Commit c664ad33 authored by lm's avatar lm

Working on new interactive control widget building, fixed timer bug in global position message

parent 41eb8ba6
......@@ -151,7 +151,10 @@ FORMS += src/ui/MainWindow.ui \
src/ui/SlugsPIDControl.ui \
src/ui/SlugsVideoCamControl.ui \
src/ui/SlugsPadCameraControl.ui \
src/ui/uas/QGCUnconnectedInfoWidget.ui
src/ui/uas/QGCUnconnectedInfoWidget.ui \
src/ui/designer/QGCToolWidget.ui \
src/ui/designer/QGCParamSlider.ui \
src/ui/designer/QGCActionButton.ui
INCLUDEPATH += src \
src/ui \
......@@ -166,7 +169,8 @@ INCLUDEPATH += src \
src/ui/mavlink \
src/ui/param \
src/ui/watchdog \
src/ui/map3D
src/ui/map3D \
src/ui/designer
HEADERS += src/MG.h \
src/Core.h \
......@@ -252,7 +256,11 @@ HEADERS += src/MG.h \
src/ui/SlugsPadCameraControl.h \
src/ui/QGCMainWindowAPConfigurator.h \
src/comm/MAVLinkSwarmSimulationLink.h \
src/ui/uas/QGCUnconnectedInfoWidget.h
src/ui/uas/QGCUnconnectedInfoWidget.h \
src/ui/designer/QGCToolWidget.h \
src/ui/designer/QGCParamSlider.h \
src/ui/designer/QGCActionButton.h \
src/ui/designer/QGCToolWidgetItem.h
# Google Earth is only supported on Mac OS and Windows with Visual Studio Compiler
macx|win32-msvc2008: {
......@@ -369,7 +377,11 @@ SOURCES += src/main.cc \
src/ui/SlugsPadCameraControl.cpp \
src/ui/QGCMainWindowAPConfigurator.cc \
src/comm/MAVLinkSwarmSimulationLink.cc \
src/ui/uas/QGCUnconnectedInfoWidget.cc
src/ui/uas/QGCUnconnectedInfoWidget.cc \
src/ui/designer/QGCToolWidget.cc \
src/ui/designer/QGCParamSlider.cc \
src/ui/designer/QGCActionButton.cc \
src/ui/designer/QGCToolWidgetItem.cc
macx|win32-msvc2008: {
SOURCES += src/ui/map3D/QGCGoogleEarthView.cc
......
......@@ -86,7 +86,8 @@ UAS::UAS(MAVLinkProtocol* protocol, int id) : UASInterface(),
roll(0.0),
pitch(0.0),
yaw(0.0),
statusTimeout(new QTimer(this))
statusTimeout(new QTimer(this)),
paramsOnceRequested(false)
{
color = UASInterface::getNextColor();
setBattery(LIPOLY, 3);
......@@ -356,7 +357,7 @@ void UAS::receiveMessage(LinkInterface* link, mavlink_message_t message)
{
mavlink_global_position_int_t pos;
mavlink_msg_global_position_int_decode(&message, &pos);
quint64 time = QGC::groundTimeUsecs();
quint64 time = QGC::groundTimeUsecs()/1000;
latitude = pos.lat/(double)1E7;
longitude = pos.lon/(double)1E7;
altitude = pos.alt/1000.0;
......@@ -474,7 +475,23 @@ void UAS::receiveMessage(LinkInterface* link, mavlink_message_t message)
{
mavlink_param_value_t value;
mavlink_msg_param_value_decode(&message, &value);
emit parameterChanged(uasId, message.compid, QString((char*)value.param_id), value.param_value);
QString parameterName = QString((char*)value.param_id);
int component = message.compid;
float val = value.param_value;
// Insert component if necessary
if (!parameters.contains(component))
{
parameters.insert(component, new QMap<QString, float>());
}
// Insert parameter into registry
if (parameters.value(component)->contains(parameterName)) parameters.value(component)->remove(parameterName);
parameters.value(component)->insert(parameterName, val);
// Emit change
emit parameterChanged(uasId, message.compid, parameterName, val);
}
break;
case MAVLINK_MSG_ID_DEBUG:
......@@ -820,6 +837,23 @@ quint64 UAS::getUnixTime(quint64 time)
}
}
QList<QString> UAS::getParameterNames(int component)
{
if (parameters.contains(component))
{
return parameters.value(component)->keys();
}
else
{
return QList<QString>();
}
}
QList<int> UAS::getComponentIds()
{
return parameters.keys();
}
void UAS::setMode(int mode)
{
if ((uint8_t)mode >= MAV_MODE_LOCKED && (uint8_t)mode <= MAV_MODE_RC_TRAINING)
......
......@@ -153,6 +153,8 @@ protected:
double pitch;
double yaw;
QTimer* statusTimeout; ///< Timer for various status timeouts
QMap<int, QMap<QString, float>* > parameters; ///< All parameters
bool paramsOnceRequested; ///< If the parameter list has been read at least once
/** @brief Set the current battery type */
void setBattery(BatteryType type, int cells);
......@@ -199,7 +201,7 @@ public slots:
//void requestWaypoints(); FIXME tbd
//void clearWaypointList(); FIXME tbd
void requestParameters();
/** @brief Enable the motors */
void enable_motors();
/** @brief Disable the motors */
......@@ -230,6 +232,9 @@ public slots:
/** @brief Set current mode of operation, e.g. auto or manual */
void setMode(int mode);
/** @brief Request all parameters */
void requestParameters();
/** @brief Set a system parameter */
void setParameter(int component, QString id, float value);
......@@ -238,6 +243,12 @@ public slots:
/** @brief Read parameters from permanent storage */
void readParametersFromStorage();
/** @brief Get the names of all parameters */
QList<QString> getParameterNames(int component);
/** @brief Get the ids of all components */
QList<int> getComponentIds();
void enableAllDataTransmission(int rate);
void enableRawSensorDataTransmission(int rate);
void enableExtendedSystemStatusTransmission(int rate);
......
......@@ -26,6 +26,7 @@
#include "MainWindow.h"
#include "JoystickWidget.h"
#include "GAudioOutput.h"
#include "QGCToolWidget.h"
#ifdef QGC_OSG_ENABLED
#include "Q3DWidgetFactory.h"
......@@ -107,6 +108,8 @@ MainWindow::MainWindow(QWidget *parent):
// Create actions
connectCommonActions();
// Add option for custom widgets
connect(ui.actionNewCustomWidget, SIGNAL(triggered()), this, SLOT(createCustomWidget()));
// Set dock options
setDockOptions(AnimatedDocks | AllowTabbedDocks | AllowNestedDocks);
......@@ -694,7 +697,16 @@ void MainWindow::connectCommonWidgets()
// it notifies that a waypoint global goes to do create and a map graphic too
connect(waypointsDockWidget->widget(), SIGNAL(createWaypointAtMap(QPointF)), mapWidget, SLOT(createWaypointGraphAtMap(QPointF)));
}
}
void MainWindow::createCustomWidget()
{
qDebug() << "ADDING CUSTOM WIDGET";
QGCToolWidget* tool = new QGCToolWidget(this);
QDockWidget* dock = new QDockWidget("Unnamed Tool", this);
dock->setWidget(tool);
this->addDockWidget(Qt::LeftDockWidgetArea, dock);
dock->setVisible(true);
}
void MainWindow::connectPxWidgets()
......
......@@ -140,6 +140,9 @@ public slots:
/** @brief Reload the CSS style sheet */
void reloadStylesheet();
/** @brief Add a custom tool widget */
void createCustomWidget();
void closeEvent(QCloseEvent* event);
/*
......
......@@ -38,7 +38,7 @@
<x>0</x>
<y>0</y>
<width>1000</width>
<height>22</height>
<height>25</height>
</rect>
</property>
<widget class="QMenu" name="menuMGround">
......@@ -46,6 +46,7 @@
<string>File</string>
</property>
<addaction name="actionJoystick_Settings"/>
<addaction name="actionNewCustomWidget"/>
<addaction name="actionSimulate"/>
<addaction name="separator"/>
<addaction name="actionExit"/>
......@@ -108,7 +109,6 @@
<addaction name="menuPerspectives"/>
<addaction name="menuHelp"/>
</widget>
<widget class="QStatusBar" name="statusBar"/>
<action name="actionExit">
<property name="icon">
......@@ -430,6 +430,11 @@
<string>Pilot</string>
</property>
</action>
<action name="actionNewCustomWidget">
<property name="text">
<string>New Custom Widget</string>
</property>
</action>
</widget>
<layoutdefault spacing="6" margin="11"/>
<resources>
......@@ -454,5 +459,3 @@
</connection>
</connections>
</ui>
#include "QGCActionButton.h"
#include "ui_QGCActionButton.h"
QGCActionButton::QGCActionButton(QWidget *parent) :
QGCToolWidgetItem(parent),
ui(new Ui::QGCActionButton)
{
ui->setupUi(this);
connect(ui->editFinishButton, SIGNAL(clicked()), this, SLOT(endEditMode()));
endEditMode();
}
QGCActionButton::~QGCActionButton()
{
delete ui;
}
void QGCActionButton::startEditMode()
{
ui->editActionComboBox->show();
ui->editActionsRefreshButton->show();
ui->editFinishButton->show();
isInEditMode = true;
}
void QGCActionButton::endEditMode()
{
ui->editActionComboBox->hide();
ui->editActionsRefreshButton->hide();
ui->editFinishButton->hide();
isInEditMode = false;
}
#ifndef QGCACTIONBUTTON_H
#define QGCACTIONBUTTON_H
#include "QGCToolWidgetItem.h"
namespace Ui {
class QGCActionButton;
}
class QGCActionButton : public QGCToolWidgetItem
{
Q_OBJECT
public:
explicit QGCActionButton(QWidget *parent = 0);
~QGCActionButton();
public slots:
void startEditMode();
void endEditMode();
private:
Ui::QGCActionButton *ui;
};
#endif // QGCACTIONBUTTON_H
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>QGCActionButton</class>
<widget class="QWidget" name="QGCActionButton">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>400</width>
<height>111</height>
</rect>
</property>
<property name="windowTitle">
<string>Form</string>
</property>
<layout class="QGridLayout" name="gridLayout">
<item row="1" column="0" colspan="2">
<widget class="QLabel" name="nameLabel">
<property name="text">
<string>Description</string>
</property>
</widget>
</item>
<item row="1" column="2">
<widget class="QPushButton" name="actionButton">
<property name="text">
<string>Button name</string>
</property>
</widget>
</item>
<item row="2" column="0">
<widget class="QComboBox" name="editActionComboBox"/>
</item>
<item row="2" column="1">
<widget class="QPushButton" name="editActionsRefreshButton">
<property name="text">
<string>Refresh Actions</string>
</property>
</widget>
</item>
<item row="2" column="2">
<widget class="QPushButton" name="editFinishButton">
<property name="text">
<string>Done</string>
</property>
</widget>
</item>
<item row="0" column="2">
<widget class="QLineEdit" name="editButtonName">
<property name="text">
<string>Button name</string>
</property>
</widget>
</item>
<item row="0" column="0" colspan="2">
<widget class="QLineEdit" name="editNameLabel">
<property name="text">
<string>Description</string>
</property>
</widget>
</item>
</layout>
</widget>
<resources/>
<connections>
<connection>
<sender>editButtonName</sender>
<signal>textChanged(QString)</signal>
<receiver>actionButton</receiver>
<slot>setWindowTitle(QString)</slot>
<hints>
<hint type="sourcelabel">
<x>310</x>
<y>22</y>
</hint>
<hint type="destinationlabel">
<x>310</x>
<y>55</y>
</hint>
</hints>
</connection>
<connection>
<sender>editNameLabel</sender>
<signal>textChanged(QString)</signal>
<receiver>nameLabel</receiver>
<slot>setText(QString)</slot>
<hints>
<hint type="sourcelabel">
<x>116</x>
<y>22</y>
</hint>
<hint type="destinationlabel">
<x>116</x>
<y>55</y>
</hint>
</hints>
</connection>
</connections>
</ui>
#include <QMenu>
#include <QContextMenuEvent>
#include "QGCParamSlider.h"
#include "ui_QGCParamSlider.h"
QGCParamSlider::QGCParamSlider(QWidget *parent) :
QWidget(parent),
QGCToolWidgetItem(parent),
ui(new Ui::QGCParamSlider)
{
ui->setupUi(this);
endEditMode();
connect(ui->doneButton, SIGNAL(clicked()), this, SLOT(endEditMode()));
}
QGCParamSlider::~QGCParamSlider()
......@@ -13,6 +18,36 @@ QGCParamSlider::~QGCParamSlider()
delete ui;
}
void QGCParamSlider::startEditMode()
{
ui->doneButton->show();
ui->maxLabel->show();
ui->minLabel->show();
ui->nameLineEdit->show();
ui->instructionsLabel->show();
ui->refreshParamsButton->show();
ui->selectParamComboBox->show();
ui->minSpinBox->show();
ui->maxSpinBox->show();
ui->typeComboBox->show();
isInEditMode = true;
}
void QGCParamSlider::endEditMode()
{
ui->doneButton->hide();
ui->maxLabel->hide();
ui->minLabel->hide();
ui->nameLineEdit->hide();
ui->instructionsLabel->hide();
ui->refreshParamsButton->hide();
ui->selectParamComboBox->hide();
ui->minSpinBox->hide();
ui->maxSpinBox->hide();
ui->typeComboBox->hide();
isInEditMode = false;
}
void QGCParamSlider::changeEvent(QEvent *e)
{
QWidget::changeEvent(e);
......
......@@ -2,13 +2,16 @@
#define QGCPARAMSLIDER_H
#include <QWidget>
#include <QAction>
#include <QtDesigner/QDesignerExportWidget>
#include "QGCToolWidgetItem.h"
namespace Ui {
class QGCParamSlider;
}
class QDESIGNER_WIDGET_EXPORT QGCParamSlider : public QWidget
class QDESIGNER_WIDGET_EXPORT QGCParamSlider : public QGCToolWidgetItem
{
Q_OBJECT
......@@ -16,6 +19,10 @@ public:
explicit QGCParamSlider(QWidget *parent = 0);
~QGCParamSlider();
public slots:
void startEditMode();
void endEditMode();
protected:
void changeEvent(QEvent *e);
......
......@@ -6,41 +6,124 @@
<rect>
<x>0</x>
<y>0</y>
<width>400</width>
<height>22</height>
<width>436</width>
<height>136</height>
</rect>
</property>
<property name="windowTitle">
<string>Form</string>
</property>
<layout class="QHBoxLayout" name="horizontalLayout">
<property name="spacing">
<number>8</number>
<layout class="QGridLayout" name="gridLayout">
<item row="1" column="0">
<widget class="QLineEdit" name="nameLineEdit">
<property name="text">
<string>Informal Name..</string>
</property>
</widget>
</item>
<item row="1" column="1" colspan="2">
<widget class="QComboBox" name="typeComboBox">
<item>
<property name="text">
<string>Float</string>
</property>
</item>
<item>
<property name="text">
<string>Integer</string>
</property>
<property name="margin">
<number>0</number>
</item>
<item>
<property name="text">
<string>Double</string>
</property>
</item>
<item>
<property name="text">
<string>Short</string>
</property>
</item>
<item>
<property name="text">
<string>Byte/Char</string>
</property>
</item>
</widget>
</item>
<item row="1" column="3">
<widget class="QLabel" name="minLabel">
<property name="text">
<string>Min</string>
</property>
</widget>
</item>
<item row="1" column="5">
<widget class="QLabel" name="maxLabel">
<property name="text">
<string>Max</string>
</property>
</widget>
</item>
<item row="2" column="0">
<widget class="QLabel" name="nameLabel">
<property name="text">
<string>Name</string>
</property>
</widget>
</item>
<item>
<item row="2" column="1">
<widget class="QLabel" name="valueLabel">
<property name="text">
<string>0.00</string>
</property>
</widget>
</item>
<item>
<item row="2" column="2" colspan="2">
<widget class="QDoubleSpinBox" name="minSpinBox"/>
</item>
<item row="2" column="4">
<widget class="QSlider" name="valueSlider">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
</widget>
</item>
<item row="2" column="5">
<widget class="QDoubleSpinBox" name="maxSpinBox"/>
</item>
<item row="3" column="5">
<widget class="QPushButton" name="doneButton">
<property name="text">
<string>Done</string>
</property>
</widget>
</item>
<item row="3" column="0" colspan="2">
<widget class="QComboBox" name="selectParamComboBox">
<item>
<property name="text">
<string>Select Parameter..</string>
</property>
</item>
</widget>
</item>
<item row="3" column="2" colspan="2">
<widget class="QPushButton" name="refreshParamsButton">
<property name="enabled">
<bool>true</bool>
</property>
<property name="text">
<string>Refresh</string>
</property>
</widget>
</item>
<item row="0" column="0" colspan="6">
<widget class="QLabel" name="instructionsLabel">
<property name="text">
<string>Please configure the parameter slider now:</string>
</property>
</widget>
</item>
</layout>
</widget>
<resources/>
......
#include "QGCToolWidget.h"
#include "ui_QGCToolWidget.h"
#include <QMenu>
#include <QList>
#include <QInputDialog>
#include <QDockWidget>
#include <QContextMenuEvent>
#include "QGCParamSlider.h"
#include "QGCActionButton.h"
#include "UASManager.h"
QGCToolWidget::QGCToolWidget(QWidget *parent) :
QWidget(parent),
toolLayout(new QVBoxLayout(this)),
mav(NULL),
ui(new Ui::QGCToolWidget)
{
ui->setupUi(this);
createActions();
toolLayout->setAlignment(Qt::AlignTop);
QList<UASInterface*> systems = UASManager::instance()->getUASList();
foreach (UASInterface* uas, systems)
{
UAS* newMav = dynamic_cast<UAS*>(uas);
if (newMav)
{
addUAS(uas);
}
}
connect(UASManager::instance(), SIGNAL(UASCreated(UASInterface*)), this, SLOT(addUAS(UASInterface*)));
}
QGCToolWidget::~QGCToolWidget()
{
delete ui;
}
void QGCToolWidget::addUAS(UASInterface* uas)
{
UAS* newMav = dynamic_cast<UAS*>(uas);
if (newMav)
{
// FIXME Convert to list
if (mav == NULL) mav = newMav;
}
}
void QGCToolWidget::contextMenuEvent (QContextMenuEvent* event)
{
QMenu menu(this);
menu.addAction(addParamAction);
menu.addAction(addButtonAction);
menu.addAction(setTitleAction);
menu.exec(event->globalPos());
}
void QGCToolWidget::createActions()
{
addParamAction = new QAction(tr("New &Parameter Slider"), this);
addParamAction->setStatusTip(tr("Add a parameter setting slider widget to the tool"));
connect(addParamAction, SIGNAL(triggered()), this, SLOT(addParam()));
addButtonAction = new QAction(tr("New MAV &Action Button"), this);
addButtonAction->setStatusTip(tr("Add a new action button to the tool"));
connect(addButtonAction, SIGNAL(triggered()), this, SLOT(addAction()));
setTitleAction = new QAction(tr("Set Widget Title"), this);
setTitleAction->setStatusTip(tr("Set the title caption of this tool widget"));
connect(setTitleAction, SIGNAL(triggered()), this, SLOT(setTitle()));
}
void QGCToolWidget::addParam()
{
QGCParamSlider* slider = new QGCParamSlider(this);
toolLayout->addWidget(slider);
slider->startEditMode();
}
void QGCToolWidget::addAction()
{
QGCActionButton* button = new QGCActionButton(this);
toolLayout->addWidget(button);
button->startEditMode();
}
void QGCToolWidget::setTitle()
{
QDockWidget* parent = dynamic_cast<QDockWidget*>(this->parentWidget());
if (parent)
{
bool ok;
QString text = QInputDialog::getText(this, tr("QInputDialog::getText()"),
tr("Widget title:"), QLineEdit::Normal,
parent->windowTitle(), &ok);
if (ok && !text.isEmpty())
parent->setWindowTitle(text);
}
}
#ifndef QGCTOOLWIDGET_H
#define QGCTOOLWIDGET_H
#include <QWidget>
#include <QAction>
#include <QVBoxLayout>
#include "UAS.h"
namespace Ui {
class QGCToolWidget;
}
class QGCToolWidget : public QWidget
{
Q_OBJECT
public:
explicit QGCToolWidget(QWidget *parent = 0);
~QGCToolWidget();
public slots:
void addUAS(UASInterface* uas);
protected:
QAction* addParamAction;
QAction* addButtonAction;
QAction* setTitleAction;
QVBoxLayout* toolLayout;
UAS* mav;
void contextMenuEvent(QContextMenuEvent* event);
void createActions();
protected slots:
void addParam();
void addAction();
void setTitle();
private:
Ui::QGCToolWidget *ui;
};
#endif // QGCTOOLWIDGET_H
<ui version="4.0">
<author/>
<comment/>
<exportmacro/>
<class>QGCToolWidget</class>
<widget class="QWidget" name="QGCToolWidget">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>400</width>
<height>300</height>
</rect>
</property>
<property name="windowTitle">
<string>Form</string>
</property>
</widget>
<pixmapfunction/>
<connections/>
</ui>
#include "QGCToolWidgetItem.h"
#include <QMenu>
#include <QContextMenuEvent>
QGCToolWidgetItem::QGCToolWidgetItem(QWidget *parent) :
QWidget(parent),
isInEditMode(false),
_component(-1)
{
startEditAction = new QAction("Edit Slider", this);
connect(startEditAction, SIGNAL(triggered()), this, SLOT(startEditMode()));
stopEditAction = new QAction("Finish Editing Slider", this);
connect(stopEditAction, SIGNAL(triggered()), this, SLOT(endEditMode()));
endEditMode();
}
QGCToolWidgetItem::~QGCToolWidgetItem()
{
delete startEditAction;
delete stopEditAction;
}
void QGCToolWidgetItem::contextMenuEvent (QContextMenuEvent* event)
{
QMenu menu(this);
if (!isInEditMode)
{
menu.addAction(startEditAction);
}
else
{
menu.addAction(stopEditAction);
}
menu.exec(event->globalPos());
}
#ifndef QGCTOOLWIDGETITEM_H
#define QGCTOOLWIDGETITEM_H
#include <QWidget>
#include <QAction>
class QGCToolWidgetItem : public QWidget
{
Q_OBJECT
public:
explicit QGCToolWidgetItem(QWidget *parent = 0);
~QGCToolWidgetItem();
int component() {return _component;}
public slots:
virtual void startEditMode() {}
virtual void endEditMode() {}
virtual void setComponent(int comp) {_component = comp;}
protected:
QAction* startEditAction;
QAction* stopEditAction;
bool isInEditMode;
int _component; ///< The MAV component (the process or device ID)
void contextMenuEvent (QContextMenuEvent* event);
};
#endif // QGCTOOLWIDGETITEM_H
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment