Commit 0dbb002d authored by Don Gagne's avatar Don Gagne

Custom tool widgets discontinued

Will be replaced by Qml + FactSystem tool widget support
parent 21e80f46
<?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" columnstretch="100,100,50">
<property name="leftMargin">
<number>6</number>
</property>
<property name="topMargin">
<number>3</number>
</property>
<property name="rightMargin">
<number>6</number>
</property>
<property name="bottomMargin">
<number>3</number>
</property>
<item row="1" column="0" colspan="2">
<widget class="QLabel" name="nameLabel">
<property name="minimumSize">
<size>
<width>50</width>
<height>0</height>
</size>
</property>
<property name="text">
<string>Description</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</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="placeholderText">
<string>Button name</string>
</property>
</widget>
</item>
<item row="0" column="0" colspan="2">
<widget class="QLineEdit" name="editNameLabel">
<property name="placeholderText">
<string>Description</string>
</property>
</widget>
</item>
<item row="1" column="2">
<widget class="QPushButton" name="actionButton">
<property name="minimumSize">
<size>
<width>30</width>
<height>0</height>
</size>
</property>
<property name="text">
<string>Button name</string>
</property>
</widget>
</item>
</layout>
</widget>
<resources/>
<connections>
<connection>
<sender>editNameLabel</sender>
<signal>textChanged(QString)</signal>
<receiver>nameLabel</receiver>
<slot>setText(QString)</slot>
<hints>
<hint type="sourcelabel">
<x>114</x>
<y>22</y>
</hint>
<hint type="destinationlabel">
<x>114</x>
<y>55</y>
</hint>
</hints>
</connection>
</connections>
</ui>
#include <QDockWidget>
#include <QDebug>
#include "QGCCommandButton.h"
#include "ui_QGCCommandButton.h"
#include "MAVLinkProtocol.h"
#include "UASManager.h"
QGCCommandButton::QGCCommandButton(QWidget *parent) :
QGCToolWidgetItem("Command Button", parent),
ui(new Ui::QGCCommandButton),
uas(NULL)
{
ui->setupUi(this);
responsecount = 0;
responsenum = 0;
connect(ui->commandButton, SIGNAL(clicked()), this, SLOT(sendCommand()));
connect(ui->editFinishButton, SIGNAL(clicked()), this, SLOT(endEditMode()));
connect(ui->editButtonName, SIGNAL(textChanged(QString)), this, SLOT(setCommandButtonName(QString)));
connect(ui->editCommandComboBox, SIGNAL(currentIndexChanged(QString)), ui->nameLabel, SLOT(setText(QString)));
// Hide all edit items
ui->editCommandComboBox->hide();
ui->editFinishButton->hide();
ui->editNameLabel->hide();
ui->editButtonName->hide();
ui->editConfirmationCheckBox->hide();
ui->editComponentSpinBox->hide();
ui->editParamsVisibleCheckBox->hide();
ui->editParam1SpinBox->hide();
ui->editParam2SpinBox->hide();
ui->editParam3SpinBox->hide();
ui->editParam4SpinBox->hide();
ui->editLine1->hide();
ui->editLine2->hide();
// Add commands to combo box
ui->editCommandComboBox->addItem("CUSTOM 0", 0);
ui->editCommandComboBox->addItem("CUSTOM 1", 1);
ui->editCommandComboBox->addItem("CUSTOM 2", 2);
ui->editCommandComboBox->addItem("CUSTOM 3", 3);
ui->editCommandComboBox->addItem("CUSTOM 4", 4);
ui->editCommandComboBox->addItem("CUSTOM 5", 5);
ui->editCommandComboBox->addItem("CUSTOM 6", 6);
ui->editCommandComboBox->addItem("CUSTOM 7", 7);
ui->editCommandComboBox->addItem("CUSTOM 8", 8);
ui->editCommandComboBox->addItem("CUSTOM 9", 9);
ui->editCommandComboBox->addItem("CUSTOM 10", 10);
ui->editCommandComboBox->addItem("CUSTOM 11", 11);
ui->editCommandComboBox->addItem("CUSTOM 12", 12);
ui->editCommandComboBox->addItem("CUSTOM 13", 13);
ui->editCommandComboBox->addItem("CUSTOM 14", 14);
ui->editCommandComboBox->addItem("CUSTOM 15", 15);
ui->editCommandComboBox->addItem("NAV_WAYPOINT", MAV_CMD_NAV_WAYPOINT);
ui->editCommandComboBox->addItem("MAV_CMD_NAV_LOITER_UNLIM", MAV_CMD_NAV_LOITER_UNLIM);
ui->editCommandComboBox->addItem("MAV_CMD_NAV_LOITER_TURNS", MAV_CMD_NAV_LOITER_TURNS);
ui->editCommandComboBox->addItem("MAV_CMD_NAV_LOITER_TIME", MAV_CMD_NAV_LOITER_TIME);
ui->editCommandComboBox->addItem("MAV_CMD_NAV_RETURN_TO_LAUNCH", MAV_CMD_NAV_RETURN_TO_LAUNCH);
ui->editCommandComboBox->addItem("MAV_CMD_NAV_LAND", MAV_CMD_NAV_LAND);
ui->editCommandComboBox->addItem("MAV_CMD_NAV_TAKEOFF", MAV_CMD_NAV_TAKEOFF);
ui->editCommandComboBox->addItem("MAV_CMD_NAV_ROI", MAV_CMD_NAV_ROI);
ui->editCommandComboBox->addItem("MAV_CMD_NAV_PATHPLANNING", MAV_CMD_NAV_PATHPLANNING);
ui->editCommandComboBox->addItem("MAV_CMD_NAV_SPLINE_WAYPOINT", MAV_CMD_NAV_SPLINE_WAYPOINT);
ui->editCommandComboBox->addItem("MAV_CMD_NAV_GUIDED_ENABLE", MAV_CMD_NAV_GUIDED_ENABLE);
ui->editCommandComboBox->addItem("MAV_CMD_CONDITION_DELAY", MAV_CMD_CONDITION_DELAY);
ui->editCommandComboBox->addItem("MAV_CMD_CONDITION_CHANGE_ALT", MAV_CMD_CONDITION_CHANGE_ALT);
ui->editCommandComboBox->addItem("MAV_CMD_CONDITION_DISTANCE", MAV_CMD_CONDITION_DISTANCE);
ui->editCommandComboBox->addItem("MAV_CMD_CONDITION_YAW", MAV_CMD_CONDITION_YAW);
ui->editCommandComboBox->addItem("MAV_CMD_CONDITION_LAST", MAV_CMD_CONDITION_LAST);
ui->editCommandComboBox->addItem("MAV_CMD_DO_SET_MODE", MAV_CMD_DO_SET_MODE);
ui->editCommandComboBox->addItem("MAV_CMD_DO_JUMP", MAV_CMD_DO_JUMP);
ui->editCommandComboBox->addItem("MAV_CMD_DO_CHANGE_SPEED", MAV_CMD_DO_CHANGE_SPEED);
ui->editCommandComboBox->addItem("MAV_CMD_DO_SET_HOME", MAV_CMD_DO_SET_HOME);
ui->editCommandComboBox->addItem("MAV_CMD_DO_SET_PARAMETER", MAV_CMD_DO_SET_PARAMETER);
ui->editCommandComboBox->addItem("MAV_CMD_DO_SET_RELAY", MAV_CMD_DO_SET_RELAY);
ui->editCommandComboBox->addItem("MAV_CMD_DO_REPEAT_RELAY", MAV_CMD_DO_REPEAT_RELAY);
ui->editCommandComboBox->addItem("MAV_CMD_DO_SET_SERVO", MAV_CMD_DO_SET_SERVO);
ui->editCommandComboBox->addItem("MAV_CMD_DO_REPEAT_SERVO", MAV_CMD_DO_REPEAT_SERVO);
ui->editCommandComboBox->addItem("MAV_CMD_DO_FLIGHTTERMINATION", MAV_CMD_DO_FLIGHTTERMINATION);
ui->editCommandComboBox->addItem("MAV_CMD_DO_LAND_START", MAV_CMD_DO_LAND_START);
ui->editCommandComboBox->addItem("MAV_CMD_DO_RALLY_LAND", MAV_CMD_DO_RALLY_LAND);
ui->editCommandComboBox->addItem("MAV_CMD_DO_GO_AROUND", MAV_CMD_DO_GO_AROUND);
ui->editCommandComboBox->addItem("MAV_CMD_DO_CONTROL_VIDEO", MAV_CMD_DO_CONTROL_VIDEO);
ui->editCommandComboBox->addItem("MAV_CMD_DO_SET_ROI", MAV_CMD_DO_SET_ROI);
ui->editCommandComboBox->addItem("MAV_CMD_DO_DIGICAM_CONFIGURE", MAV_CMD_DO_DIGICAM_CONFIGURE);
ui->editCommandComboBox->addItem("MAV_CMD_DO_DIGICAM_CONTROL", MAV_CMD_DO_DIGICAM_CONTROL);
ui->editCommandComboBox->addItem("MAV_CMD_DO_MOUNT_CONFIGURE", MAV_CMD_DO_MOUNT_CONFIGURE);
ui->editCommandComboBox->addItem("MAV_CMD_DO_MOUNT_CONTROL", MAV_CMD_DO_MOUNT_CONTROL);
ui->editCommandComboBox->addItem("MAV_CMD_DO_SET_CAM_TRIGG_DIST", MAV_CMD_DO_SET_CAM_TRIGG_DIST);
ui->editCommandComboBox->addItem("MAV_CMD_DO_FENCE_ENABLE", MAV_CMD_DO_FENCE_ENABLE);
ui->editCommandComboBox->addItem("MAV_CMD_DO_PARACHUTE", MAV_CMD_DO_PARACHUTE);
ui->editCommandComboBox->addItem("MAV_CMD_DO_INVERTED_FLIGHT", MAV_CMD_DO_INVERTED_FLIGHT);
ui->editCommandComboBox->addItem("MAV_CMD_DO_MOUNT_CONTROL_QUAT", MAV_CMD_DO_MOUNT_CONTROL_QUAT);
ui->editCommandComboBox->addItem("MAV_CMD_DO_GUIDED_MASTER", MAV_CMD_DO_GUIDED_MASTER);
ui->editCommandComboBox->addItem("MAV_CMD_DO_GUIDED_LIMITS", MAV_CMD_DO_GUIDED_LIMITS);
ui->editCommandComboBox->addItem("MAV_CMD_PREFLIGHT_CALIBRATION", MAV_CMD_PREFLIGHT_CALIBRATION);
ui->editCommandComboBox->addItem("MAV_CMD_PREFLIGHT_SET_SENSOR_OFFSETS", MAV_CMD_PREFLIGHT_SET_SENSOR_OFFSETS);
ui->editCommandComboBox->addItem("MAV_CMD_PREFLIGHT_STORAGE", MAV_CMD_PREFLIGHT_STORAGE);
ui->editCommandComboBox->addItem("MAV_CMD_PREFLIGHT_REBOOT_SHUTDOWN", MAV_CMD_PREFLIGHT_REBOOT_SHUTDOWN);
ui->editCommandComboBox->addItem("MAV_CMD_OVERRIDE_GOTO", MAV_CMD_OVERRIDE_GOTO);
ui->editCommandComboBox->addItem("MAV_CMD_MISSION_START", MAV_CMD_MISSION_START);
ui->editCommandComboBox->addItem("MAV_CMD_COMPONENT_ARM_DISARM", MAV_CMD_COMPONENT_ARM_DISARM);
ui->editCommandComboBox->addItem("MAV_CMD_START_RX_PAIR", MAV_CMD_START_RX_PAIR);
ui->editCommandComboBox->addItem("MAV_CMD_IMAGE_START_CAPTURE", MAV_CMD_IMAGE_START_CAPTURE);
ui->editCommandComboBox->addItem("MAV_CMD_IMAGE_STOP_CAPTURE", MAV_CMD_IMAGE_STOP_CAPTURE);
ui->editCommandComboBox->addItem("MAV_CMD_VIDEO_START_CAPTURE", MAV_CMD_VIDEO_START_CAPTURE);
ui->editCommandComboBox->addItem("MAV_CMD_VIDEO_STOP_CAPTURE", MAV_CMD_VIDEO_STOP_CAPTURE);
ui->editCommandComboBox->addItem("MAV_CMD_PANORAMA_CREATE", MAV_CMD_PANORAMA_CREATE);
ui->editCommandComboBox->addItem("MAV_CMD_PAYLOAD_PREPARE_DEPLOY", MAV_CMD_PAYLOAD_PREPARE_DEPLOY);
ui->editCommandComboBox->addItem("MAV_CMD_PAYLOAD_CONTROL_DEPLOY", MAV_CMD_PAYLOAD_CONTROL_DEPLOY);
ui->editCommandComboBox->setEditable(true);
init();
}
QGCCommandButton::~QGCCommandButton()
{
delete ui;
}
void QGCCommandButton::sendCommand()
{
if (QGCToolWidgetItem::uas)
{
if (responsenum != 0)
{
if (responsecount == 0)
{
//We're finished. Reset.
qDebug() << "Finished sequence";
QGCToolWidgetItem::uas->executeCommandAck(responsenum-responsecount,true);
responsecount = responsenum;
return;
}
if (responsecount < responsenum)
{
qDebug() << responsecount << responsenum;
QGCToolWidgetItem::uas->executeCommandAck(responsenum-responsecount,true);
responsecount--;
return;
}
else
{
qDebug() << "No sequence yet, sending command";
responsecount--;
}
}
// Check if command text is a number
bool ok;
int index = 0;
index = ui->editCommandComboBox->currentText().toInt(&ok);
if (!ok)
{
// Command was not a number, assume it was one of the text items
index = ui->editCommandComboBox->itemData(ui->editCommandComboBox->currentIndex()).toInt(&ok);
if (ok)
{
// Text item found, proceed
MAV_CMD command = static_cast<MAV_CMD>(index);
int confirm = (ui->editConfirmationCheckBox->isChecked()) ? 1 : 0;
float param1 = ui->editParam1SpinBox->value();
float param2 = ui->editParam2SpinBox->value();
float param3 = ui->editParam3SpinBox->value();
float param4 = ui->editParam4SpinBox->value();
float param5 = ui->editParam5SpinBox->value();
float param6 = ui->editParam6SpinBox->value();
float param7 = ui->editParam7SpinBox->value();
int component = ui->editComponentSpinBox->value();
if (showlabelname != "")
{
emit showLabel(showlabelname,index);
}
QGCToolWidgetItem::uas->executeCommand(command, confirm, param1, param2, param3, param4, param5, param6, param7, component);
//qDebug() << __FILE__ << __LINE__ << "SENDING COMMAND" << index;
}
}
}
else
{
qDebug() << __FILE__ << __LINE__ << "NO UAS SET, DOING NOTHING";
}
}
void QGCCommandButton::setCommandButtonName(QString text)
{
ui->commandButton->setText(text);
}
void QGCCommandButton::setEditMode(bool editMode)
{
// Hide elements
ui->commandButton->setVisible(!editMode);
ui->nameLabel->setVisible(!editMode);
ui->editCommandComboBox->blockSignals(!editMode);
ui->editCommandComboBox->setVisible(editMode);
ui->editFinishButton->setVisible(editMode);
ui->editNameLabel->setVisible(editMode);
ui->editButtonName->setVisible(editMode);
ui->editConfirmationCheckBox->setVisible(editMode);
ui->editComponentSpinBox->setVisible(editMode);
ui->editParamsVisibleCheckBox->setVisible(editMode);
bool showParams = editMode || ui->editParamsVisibleCheckBox->isChecked();
ui->editParam1SpinBox->setVisible(showParams);
ui->editParam2SpinBox->setVisible(showParams);
ui->editParam3SpinBox->setVisible(showParams);
ui->editParam4SpinBox->setVisible(showParams);
ui->editParam5SpinBox->setVisible(showParams);
ui->editParam6SpinBox->setVisible(showParams);
ui->editParam7SpinBox->setVisible(showParams);
ui->editLine1->setVisible(editMode);
ui->editLine2->setVisible(editMode);
QGCToolWidgetItem::setEditMode(editMode);
}
void QGCCommandButton::writeSettings(QSettings& settings)
{
//qDebug() << "COMMAND BUTTON WRITING SETTINGS";
settings.setValue("TYPE", "COMMANDBUTTON");
settings.setValue("QGC_COMMAND_BUTTON_DESCRIPTION", ui->nameLabel->text());
settings.setValue("QGC_COMMAND_BUTTON_BUTTONTEXT", ui->commandButton->text());
settings.setValue("QGC_COMMAND_BUTTON_COMMANDID", ui->editCommandComboBox->itemData(ui->editCommandComboBox->currentIndex()).toInt());
settings.setValue("QGC_COMMAND_BUTTON_PARAMS_VISIBLE", ui->editParamsVisibleCheckBox->isChecked());
settings.setValue("QGC_COMMAND_BUTTON_PARAM1", ui->editParam1SpinBox->value());
settings.setValue("QGC_COMMAND_BUTTON_PARAM2", ui->editParam2SpinBox->value());
settings.setValue("QGC_COMMAND_BUTTON_PARAM3", ui->editParam3SpinBox->value());
settings.setValue("QGC_COMMAND_BUTTON_PARAM4", ui->editParam4SpinBox->value());
settings.setValue("QGC_COMMAND_BUTTON_PARAM5", ui->editParam5SpinBox->value());
settings.setValue("QGC_COMMAND_BUTTON_PARAM6", ui->editParam6SpinBox->value());
settings.setValue("QGC_COMMAND_BUTTON_PARAM7", ui->editParam7SpinBox->value());
settings.sync();
}
void QGCCommandButton::readSettings(const QString& pre,const QVariantMap& settings)
{
ui->editButtonName->setText(settings.value(pre + "QGC_COMMAND_BUTTON_BUTTONTEXT", "UNKNOWN").toString());
ui->editCommandComboBox->setCurrentIndex(settings.value(pre + "QGC_COMMAND_BUTTON_COMMANDID", 0).toInt());
ui->commandButton->setText(settings.value(pre + "QGC_COMMAND_BUTTON_BUTTONTEXT", "UNKNOWN").toString());
int commandId = settings.value(pre + "QGC_COMMAND_BUTTON_COMMANDID", 0).toInt();
ui->editParam1SpinBox->setValue(settings.value(pre + "QGC_COMMAND_BUTTON_PARAM1", 0.0).toDouble());
ui->editParam2SpinBox->setValue(settings.value(pre + "QGC_COMMAND_BUTTON_PARAM2", 0.0).toDouble());
ui->editParam3SpinBox->setValue(settings.value(pre + "QGC_COMMAND_BUTTON_PARAM3", 0.0).toDouble());
ui->editParam4SpinBox->setValue(settings.value(pre + "QGC_COMMAND_BUTTON_PARAM4", 0.0).toDouble());
ui->editParam5SpinBox->setValue(settings.value(pre + "QGC_COMMAND_BUTTON_PARAM5", 0.0).toDouble());
ui->editParam6SpinBox->setValue(settings.value(pre + "QGC_COMMAND_BUTTON_PARAM6", 0.0).toDouble());
ui->editParam7SpinBox->setValue(settings.value(pre + "QGC_COMMAND_BUTTON_PARAM7", 0.0).toDouble());
ui->editCommandComboBox->setCurrentIndex(0);
// Find combobox entry for this data
for (int i = 0; i < ui->editCommandComboBox->count(); ++i)
{
if (commandId == ui->editCommandComboBox->itemData(i).toInt())
{
ui->editCommandComboBox->setCurrentIndex(i);
}
}
ui->editParamsVisibleCheckBox->setChecked(settings.value(pre + "QGC_COMMAND_BUTTON_PARAMS_VISIBLE").toBool());
if (ui->editParamsVisibleCheckBox->isChecked())
{
ui->editParam1SpinBox->show();
ui->editParam2SpinBox->show();
ui->editParam3SpinBox->show();
ui->editParam4SpinBox->show();
ui->editParam5SpinBox->show();
ui->editParam6SpinBox->show();
ui->editParam7SpinBox->show();
}
else
{
ui->editParam1SpinBox->hide();
ui->editParam2SpinBox->hide();
ui->editParam3SpinBox->hide();
ui->editParam4SpinBox->hide();
ui->editParam5SpinBox->hide();
ui->editParam6SpinBox->hide();
ui->editParam7SpinBox->hide();
}
ui->editNameLabel->setText(settings.value(pre + "QGC_COMMAND_BUTTON_DESCRIPTION", "ERROR LOADING BUTTON").toString());
ui->nameLabel->setText(settings.value(pre + "QGC_COMMAND_BUTTON_DESCRIPTION", "ERROR LOADING BUTTON").toString());
responsenum = settings.value(pre + "QGC_COMMAND_BUTTON_RESPONSE",0).toInt();
responsecount = responsenum;
}
void QGCCommandButton::readSettings(const QSettings& settings)
{
ui->editButtonName->setText(settings.value("QGC_COMMAND_BUTTON_BUTTONTEXT", "UNKNOWN").toString());
ui->editCommandComboBox->setCurrentIndex(settings.value("QGC_COMMAND_BUTTON_COMMANDID", 0).toInt());
ui->commandButton->setText(settings.value("QGC_COMMAND_BUTTON_BUTTONTEXT", "UNKNOWN").toString());
int commandId = settings.value("QGC_COMMAND_BUTTON_COMMANDID", 0).toInt();
ui->editParam1SpinBox->setValue(settings.value("QGC_COMMAND_BUTTON_PARAM1", 0.0).toDouble());
ui->editParam2SpinBox->setValue(settings.value("QGC_COMMAND_BUTTON_PARAM2", 0.0).toDouble());
ui->editParam3SpinBox->setValue(settings.value("QGC_COMMAND_BUTTON_PARAM3", 0.0).toDouble());
ui->editParam4SpinBox->setValue(settings.value("QGC_COMMAND_BUTTON_PARAM4", 0.0).toDouble());
ui->editParam5SpinBox->setValue(settings.value("QGC_COMMAND_BUTTON_PARAM5", 0.0).toDouble());
ui->editParam6SpinBox->setValue(settings.value("QGC_COMMAND_BUTTON_PARAM6", 0.0).toDouble());
ui->editParam7SpinBox->setValue(settings.value("QGC_COMMAND_BUTTON_PARAM7", 0.0).toDouble());
showlabelname = settings.value("QGC_COMMAND_BUTTON_LABEL","").toString();
ui->editCommandComboBox->setCurrentIndex(0);
// Find combobox entry for this data
for (int i = 0; i < ui->editCommandComboBox->count(); ++i)
{
if (commandId == ui->editCommandComboBox->itemData(i).toInt())
{
ui->editCommandComboBox->setCurrentIndex(i);
}
}
ui->editParamsVisibleCheckBox->setChecked(settings.value("QGC_COMMAND_BUTTON_PARAMS_VISIBLE").toBool());
if (ui->editParamsVisibleCheckBox->isChecked())
{
ui->editParam1SpinBox->show();
ui->editParam2SpinBox->show();
ui->editParam3SpinBox->show();
ui->editParam4SpinBox->show();
ui->editParam5SpinBox->show();
ui->editParam6SpinBox->show();
ui->editParam7SpinBox->show();
}
else
{
ui->editParam1SpinBox->hide();
ui->editParam2SpinBox->hide();
ui->editParam3SpinBox->hide();
ui->editParam4SpinBox->hide();
ui->editParam5SpinBox->hide();
ui->editParam6SpinBox->hide();
ui->editParam7SpinBox->hide();
}
ui->editNameLabel->setText(settings.value("QGC_COMMAND_BUTTON_DESCRIPTION", "ERROR LOADING BUTTON").toString());
ui->nameLabel->setText(settings.value("QGC_COMMAND_BUTTON_DESCRIPTION", "ERROR LOADING BUTTON").toString());
responsenum = settings.value("QGC_COMMAND_BUTTON_RESPONSE",0).toInt();
responsecount = responsenum;
}
#ifndef QGCCOMMANDBUTTON_H
#define QGCCOMMANDBUTTON_H
#include "QGCToolWidgetItem.h"
namespace Ui
{
class QGCCommandButton;
}
class UASInterface;
class QGCCommandButton : public QGCToolWidgetItem
{
Q_OBJECT
public:
explicit QGCCommandButton(QWidget *parent = 0);
~QGCCommandButton();
virtual void setEditMode(bool editMode);
public slots:
void sendCommand();
void setCommandButtonName(QString text);
void writeSettings(QSettings& settings);
void readSettings(const QSettings& settings);
void readSettings(const QString& pre,const QVariantMap& settings);
signals:
void showLabel(QString name, int num);
private:
int responsenum;
int responsecount;
QString showlabelname;
Ui::QGCCommandButton *ui;
UASInterface* uas;
};
#endif // QGCCOMMANDBUTTON_H
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>QGCCommandButton</class>
<widget class="QWidget" name="QGCCommandButton">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>1235</width>
<height>430</height>
</rect>
</property>
<property name="windowTitle">
<string>Form</string>
</property>
<layout class="QGridLayout" name="gridLayout" columnstretch="100,0,0,0">
<property name="leftMargin">
<number>6</number>
</property>
<property name="topMargin">
<number>3</number>
</property>
<property name="rightMargin">
<number>6</number>
</property>
<property name="bottomMargin">
<number>3</number>
</property>
<item row="7" column="0" colspan="3">
<widget class="QComboBox" name="editCommandComboBox">
<property name="editable">
<bool>true</bool>
</property>
</widget>
</item>
<item row="7" column="3">
<widget class="QPushButton" name="editFinishButton">
<property name="text">
<string>Done</string>
</property>
</widget>
</item>
<item row="2" column="3">
<widget class="QLineEdit" name="editButtonName">
<property name="text">
<string>&lt;Button Label&gt;</string>
</property>
</widget>
</item>
<item row="2" column="0" colspan="3">
<widget class="QLineEdit" name="editNameLabel">
<property name="placeholderText">
<string>Button Description</string>
</property>
</widget>
</item>
<item row="4" column="3">
<widget class="QPushButton" name="commandButton">
<property name="minimumSize">
<size>
<width>60</width>
<height>0</height>
</size>
</property>
<property name="text">
<string>Unnamed</string>
</property>
</widget>
</item>
<item row="6" column="0">
<widget class="QSpinBox" name="editComponentSpinBox">
<property name="prefix">
<string>Component ID: </string>
</property>
<property name="minimum">
<number>0</number>
</property>
<property name="maximum">
<number>255</number>
</property>
</widget>
</item>
<item row="6" column="2" colspan="2">
<widget class="QCheckBox" name="editConfirmationCheckBox">
<property name="toolTip">
<string>Set the confirm flag for this button. Some commands require that first one command is sent without confirm flag and then a second, equal command with confirm flag. This ensures safety.</string>
</property>
<property name="text">
<string>Set CONFIRM flag</string>
</property>
</widget>
</item>
<item row="3" column="0" colspan="4">
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<widget class="QDoubleSpinBox" name="editParam1SpinBox">
<property name="toolTip">
<string>PARAM1 Value as defined in MAV_CMD list</string>
</property>
<property name="statusTip">
<string>PARAM1 Value as defined in MAV_CMD list</string>
</property>
<property name="prefix">
<string>P1 </string>
</property>
<property name="minimum">
<double>-2147483647.000000000000000</double>
</property>
<property name="maximum">
<double>2147483647.000000000000000</double>
</property>
</widget>
</item>
<item>
<widget class="QDoubleSpinBox" name="editParam2SpinBox">
<property name="toolTip">
<string>PARAM2 Value as defined in MAV_CMD list</string>
</property>
<property name="statusTip">
<string>PARAM2 Value as defined in MAV_CMD list</string>
</property>
<property name="prefix">
<string>P2: </string>
</property>
<property name="minimum">
<double>-2147483647.000000000000000</double>
</property>
<property name="value">
<double>0.000000000000000</double>
</property>
</widget>
</item>
<item>
<widget class="QDoubleSpinBox" name="editParam3SpinBox">
<property name="toolTip">
<string>PARAM3 Value as defined in MAV_CMD list</string>
</property>
<property name="statusTip">
<string>PARAM3 Value as defined in MAV_CMD list</string>
</property>
<property name="prefix">
<string>P3: </string>
</property>
<property name="minimum">
<double>-2147483647.000000000000000</double>
</property>
<property name="maximum">
<double>2147483647.000000000000000</double>
</property>
</widget>
</item>
<item>
<widget class="QDoubleSpinBox" name="editParam4SpinBox">
<property name="toolTip">
<string>PARAM4 Value as defined in MAV_CMD list</string>
</property>
<property name="statusTip">
<string>PARAM4 Value as defined in MAV_CMD list</string>
</property>
<property name="prefix">
<string>P4: </string>
</property>
<property name="minimum">
<double>-2147483647.000000000000000</double>
</property>
<property name="maximum">
<double>2147483647.000000000000000</double>
</property>
</widget>
</item>
<item>
<widget class="QDoubleSpinBox" name="editParam5SpinBox">
<property name="prefix">
<string>P5: </string>
</property>
<property name="decimals">
<number>7</number>
</property>
<property name="minimum">
<double>-2147483647.000000000000000</double>
</property>
<property name="maximum">
<double>2147483647.000000000000000</double>
</property>
</widget>
</item>
<item>
<widget class="QDoubleSpinBox" name="editParam6SpinBox">
<property name="prefix">
<string>P6: </string>
</property>
<property name="decimals">
<number>7</number>
</property>
<property name="minimum">
<double>-2147483647.000000000000000</double>
</property>
<property name="maximum">
<double>2147483647.000000000000000</double>
</property>
</widget>
</item>
<item>
<widget class="QDoubleSpinBox" name="editParam7SpinBox">
<property name="prefix">
<string>P7: </string>
</property>
<property name="minimum">
<double>-2147483647.000000000000000</double>
</property>
<property name="maximum">
<double>2147483647.000000000000000</double>
</property>
</widget>
</item>
</layout>
</item>
<item row="4" column="0" colspan="3">
<widget class="QLabel" name="nameLabel">
<property name="minimumSize">
<size>
<width>50</width>
<height>0</height>
</size>
</property>
<property name="text">
<string>Description</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
</widget>
</item>
<item row="6" column="1">
<widget class="QCheckBox" name="editParamsVisibleCheckBox">
<property name="text">
<string>Keep parameters visible</string>
</property>
</widget>
</item>
<item row="1" column="0" colspan="4">
<widget class="Line" name="editLine1">
<property name="minimumSize">
<size>
<width>0</width>
<height>0</height>
</size>
</property>
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
</widget>
</item>
<item row="8" column="0" colspan="4">
<widget class="Line" name="editLine2">
<property name="minimumSize">
<size>
<width>0</width>
<height>0</height>
</size>
</property>
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
</widget>
</item>
</layout>
</widget>
<resources/>
<connections>
<connection>
<sender>editNameLabel</sender>
<signal>textChanged(QString)</signal>
<receiver>nameLabel</receiver>
<slot>setText(QString)</slot>
<hints>
<hint type="sourcelabel">
<x>114</x>
<y>22</y>
</hint>
<hint type="destinationlabel">
<x>114</x>
<y>55</y>
</hint>
</hints>
</connection>
</connections>
</ui>
#include <QMenu>
#include <QContextMenuEvent>
#include <QSettings>
#include <QTimer>
#include <QToolTip>
#include <QDebug>
#include "QGCParamSlider.h"
#include "ui_QGCParamSlider.h"
#include "UASInterface.h"
#include "UASManager.h"
QGCParamSlider::QGCParamSlider(QWidget *parent) :
QGCToolWidgetItem("Slider", parent),
parameterName(""),
parameterValue(0.0f),
parameterScalingFactor(0.0),
parameterMin(0.0f),
parameterMax(0.0f),
componentId(0),
ui(new Ui::QGCParamSlider)
{
valueModLock = false;
visibleEnabled = true;
valueModLockParam = false;
ui->setupUi(this);
ui->intValueSpinBox->hide();
ui->valueSlider->setEnabled(false);
ui->doubleValueSpinBox->setEnabled(false);
uas = NULL;
scaledInt = ui->valueSlider->maximum() - ui->valueSlider->minimum();
ui->editInfoCheckBox->hide();
ui->editDoneButton->hide();
ui->editNameLabel->hide();
ui->editRefreshParamsButton->hide();
ui->editSelectParamComboBox->hide();
ui->editSelectComponentComboBox->hide();
ui->editStatusLabel->hide();
ui->editMinSpinBox->hide();
ui->editMaxSpinBox->hide();
ui->editLine1->hide();
ui->editLine2->hide();
ui->infoLabel->hide();
connect(ui->editDoneButton, SIGNAL(clicked()), this, SLOT(endEditMode()));
// Sending actions
connect(ui->writeButton, SIGNAL(clicked()),
this, SLOT(setParamPending()));
connect(ui->editSelectComponentComboBox, SIGNAL(currentIndexChanged(int)),
this, SLOT(selectComponent(int)));
connect(ui->editSelectParamComboBox, SIGNAL(currentIndexChanged(int)),
this, SLOT(selectParameter(int)));
connect(ui->valueSlider, SIGNAL(valueChanged(int)),
this, SLOT(setSliderValue(int)));
connect(ui->doubleValueSpinBox, SIGNAL(valueChanged(double)),
this, SLOT(setParamValue(double)));
connect(ui->intValueSpinBox, SIGNAL(valueChanged(int)),
this, SLOT(setParamValue(int)));
connect(ui->editNameLabel, SIGNAL(textChanged(QString)),
ui->nameLabel, SLOT(setText(QString)));
connect(ui->readButton, SIGNAL(clicked()), this, SLOT(requestParameter()));
connect(ui->editRefreshParamsButton, SIGNAL(clicked()),
this, SLOT(refreshParamList()));
connect(ui->editInfoCheckBox, SIGNAL(clicked(bool)),
this, SLOT(showInfo(bool)));
// connect to self
connect(ui->infoLabel, SIGNAL(released()),
this, SLOT(showTooltip()));
init();
requestParameter();
}
QGCParamSlider::~QGCParamSlider()
{
delete ui;
}
void QGCParamSlider::showTooltip()
{
QWidget* sender = dynamic_cast<QWidget*>(QObject::sender());
if (sender)
{
QPoint point = mapToGlobal(ui->infoLabel->pos());
QToolTip::showText(point, sender->toolTip());
}
}
void QGCParamSlider::refreshParamList()
{
ui->editSelectParamComboBox->setEnabled(true);
ui->editSelectComponentComboBox->setEnabled(true);
if (uas) {
uas->getParamManager()->requestParameterList();
ui->editStatusLabel->setText(tr("Parameter list updating.."));
}
}
void QGCParamSlider::setActiveUAS(UASInterface* activeUas)
{
if (uas != activeUas) {
if (uas) {
disconnect(uas, SIGNAL(parameterChanged(int,int,int,int,QString,QVariant)),
this, SLOT(setParameterValue(int,int,int,int,QString,QVariant)));
}
if (activeUas) {
connect(activeUas, SIGNAL(parameterChanged(int,int,int,int,QString,QVariant)),
this, SLOT(setParameterValue(int,int,int,int,QString,QVariant)), Qt::UniqueConnection);
}
uas = activeUas;
}
if (uas && !parameterName.isEmpty()) {
QString text = uas->getParamManager()->dataModel()->getParamDescription(parameterName);
if (!text.isEmpty()) {
ui->infoLabel->setToolTip(text);
ui->infoLabel->show();
}
// Force-uncheck and hide label if no description is available
if (ui->editInfoCheckBox->isChecked()) {
showInfo((text.length() > 0));
}
}
}
void QGCParamSlider::requestParameter()
{
if (uas && !parameterName.isEmpty()) {
uas->getParamManager()->requestParameterUpdate(componentId, parameterName);
}
}
void QGCParamSlider::showInfo(bool enable)
{
ui->editInfoCheckBox->setChecked(enable);
ui->infoLabel->setVisible(enable);
}
void QGCParamSlider::setParamValue(double value)
{
parameterValue = (float)value;
//disconnect(ui->valueSlider,SIGNAL(valueChanged(int)));
if (!valueModLock && !valueModLockParam)
{
valueModLock = true;
ui->valueSlider->setValue(floatToScaledInt(value));
}
else
{
valueModLock = false;
}
//connect(ui->valueSlider, SIGNAL(valueChanged(int)), this, SLOT(setSliderValue(int)));
}
void QGCParamSlider::setParamValue(int value)
{
parameterValue = value;
// disconnect(ui->valueSlider,SIGNAL(valueChanged(int)));
if (!valueModLock && !valueModLockParam)
{
valueModLock = true;
ui->valueSlider->setValue(floatToScaledInt(value));
}
else
{
valueModLock = false;
}
//connect(ui->valueSlider, SIGNAL(valueChanged(int)), this, SLOT(setSliderValue(int)));
}
void QGCParamSlider::selectComponent(int componentIndex)
{
this->componentId = ui->editSelectComponentComboBox->itemData(componentIndex).toInt();
}
void QGCParamSlider::selectParameter(int paramIndex)
{
// Set name
parameterName = ui->editSelectParamComboBox->itemText(paramIndex);
if (parameterName.isEmpty()) {
return;
}
// Update min and max values if available
if (uas) {
UASParameterDataModel* dataModel = uas->getParamManager()->dataModel();
if (dataModel) {
// Minimum
if (dataModel->isParamMinKnown(parameterName)) {
parameterMin = dataModel->getParamMin(parameterName);
ui->editMinSpinBox->setValue(parameterMin);
}
// Maximum
if (dataModel->isParamMaxKnown(parameterName)) {
parameterMax = dataModel->getParamMax(parameterName);
ui->editMaxSpinBox->setValue(parameterMax);
}
}
}
}
void QGCParamSlider::setEditMode(bool editMode)
{
if(!editMode) {
// Store component id
selectComponent(ui->editSelectComponentComboBox->currentIndex());
// Store parameter name and id
selectParameter(ui->editSelectParamComboBox->currentIndex());
// Min/max
parameterMin = ui->editMinSpinBox->value();
parameterMax = ui->editMaxSpinBox->value();
requestParameter();
switch ((int)parameterValue.type())
{
case QVariant::Char:
case QVariant::Int:
case QVariant::UInt:
ui->intValueSpinBox->show();
break;
case QMetaType::Float:
ui->doubleValueSpinBox->show();
break;
default:
qCritical() << "ERROR: NO VALID PARAM TYPE";
return;
}
} else {
ui->doubleValueSpinBox->hide();
ui->intValueSpinBox->hide();
}
ui->valueSlider->setVisible(!editMode);
ui->nameLabel->setVisible(!editMode);
ui->writeButton->setVisible(!editMode);
ui->readButton->setVisible(!editMode);
ui->editInfoCheckBox->setVisible(editMode);
ui->editDoneButton->setVisible(editMode);
ui->editNameLabel->setVisible(editMode);
ui->editRefreshParamsButton->setVisible(editMode);
ui->editSelectParamComboBox->setVisible(editMode);
ui->editSelectComponentComboBox->setVisible(editMode);
ui->editStatusLabel->setVisible(editMode);
ui->editMinSpinBox->setVisible(editMode);
ui->editMaxSpinBox->setVisible(editMode);
ui->writeButton->setVisible(!editMode);
ui->readButton->setVisible(!editMode);
ui->editLine1->setVisible(editMode);
ui->editLine2->setVisible(editMode);
QGCToolWidgetItem::setEditMode(editMode);
}
void QGCParamSlider::setParamPending()
{
if (uas) {
uas->getParamManager()->setPendingParam(componentId, parameterName, parameterValue);
uas->getParamManager()->sendPendingParameters(true, true);
}
else {
qDebug() << __FILE__ << __LINE__ << "NO UAS SET, DOING NOTHING";
}
}
void QGCParamSlider::setSliderValue(int sliderValue)
{
if (!valueModLock && !valueModLockParam)
{
valueModLock = true;
switch ((int)parameterValue.type())
{
case QVariant::Char:
parameterValue = QVariant(QChar((unsigned char)scaledIntToFloat(sliderValue)));
ui->intValueSpinBox->setValue(parameterValue.toInt());
break;
case QVariant::Int:
parameterValue = (int)scaledIntToFloat(sliderValue);
ui->intValueSpinBox->setValue(parameterValue.toInt());
break;
case QVariant::UInt:
parameterValue = (unsigned int)scaledIntToFloat(sliderValue);
ui->intValueSpinBox->setValue(parameterValue.toUInt());
break;
case QMetaType::Float:
parameterValue = scaledIntToFloat(sliderValue);
ui->doubleValueSpinBox->setValue(parameterValue.toFloat());
break;
default:
qCritical() << "ERROR: NO VALID PARAM TYPE";
valueModLock = false;
return;
}
}
else
{
valueModLock = false;
}
}
/**
* @brief uas Unmanned system sending the parameter
* @brief component UAS component sending the parameter
* @brief parameterName Key/name of the parameter
* @brief value Value of the parameter
*/
void QGCParamSlider::setParameterValue(int uasId, int compId, int paramCount, int paramIndex, QString paramName, QVariant value)
{
Q_UNUSED(paramCount);
if (uasId != this->uas->getUASID()) {
return;
}
if (ui->nameLabel->text() == "Name") {
ui->nameLabel->setText(paramName);
}
// Check if this component and parameter are part of the list
bool found = false;
for (int i = 0; i< ui->editSelectComponentComboBox->count(); ++i) {
if (compId == ui->editSelectComponentComboBox->itemData(i).toInt()) {
found = true;
}
}
if (!found) {
ui->editSelectComponentComboBox->addItem(tr("Component #%1").arg(compId), compId);
}
// Parameter checking
found = false;
for (int i = 0; i < ui->editSelectParamComboBox->count(); ++i) {
if (paramName == ui->editSelectParamComboBox->itemText(i)) {
found = true;
}
}
if (!found) {
ui->editSelectParamComboBox->addItem(paramName, paramIndex);
}
if (visibleParam != "") {
if (paramName == visibleParam) {
if (visibleVal == value.toInt()) {
uas->getParamManager()->requestParameterUpdate(compId,paramName);
visibleEnabled = true;
this->show();
}
else {
//Disable the component here.
ui->valueSlider->setEnabled(false);
ui->intValueSpinBox->setEnabled(false);
ui->doubleValueSpinBox->setEnabled(false);
visibleEnabled = false;
this->hide();
}
}
}
Q_UNUSED(uas);
if (compId == this->componentId && paramName == this->parameterName) {
if (!visibleEnabled) {
return;
}
parameterValue = value;
ui->valueSlider->setEnabled(true);
valueModLockParam = true;
switch ((int)value.type())
{
case QVariant::Char:
ui->intValueSpinBox->show();
ui->intValueSpinBox->setEnabled(true);
ui->doubleValueSpinBox->hide();
ui->intValueSpinBox->setValue(value.toUInt());
ui->intValueSpinBox->setRange(0, UINT8_MAX);
if (parameterMax == 0 && parameterMin == 0)
{
ui->editMaxSpinBox->setValue(UINT8_MAX);
ui->editMinSpinBox->setValue(0);
}
ui->valueSlider->setValue(floatToScaledInt(value.toUInt()));
break;
case QVariant::Int:
ui->intValueSpinBox->show();
ui->intValueSpinBox->setEnabled(true);
ui->doubleValueSpinBox->hide();
ui->intValueSpinBox->setValue(value.toInt());
ui->intValueSpinBox->setRange(INT32_MIN, INT32_MAX);
if (parameterMax == 0 && parameterMin == 0)
{
ui->editMaxSpinBox->setValue(INT32_MAX);
ui->editMinSpinBox->setValue(INT32_MIN);
}
ui->valueSlider->setValue(floatToScaledInt(value.toInt()));
break;
case QVariant::UInt:
ui->intValueSpinBox->show();
ui->intValueSpinBox->setEnabled(true);
ui->doubleValueSpinBox->hide();
ui->intValueSpinBox->setValue(value.toUInt());
ui->intValueSpinBox->setRange(0, UINT32_MAX);
if (parameterMax == 0 && parameterMin == 0)
{
ui->editMaxSpinBox->setValue(UINT32_MAX);
ui->editMinSpinBox->setValue(0);
}
ui->valueSlider->setValue(floatToScaledInt(value.toUInt()));
break;
case QMetaType::Float:
ui->doubleValueSpinBox->setValue(value.toFloat());
ui->doubleValueSpinBox->show();
ui->doubleValueSpinBox->setEnabled(true);
ui->intValueSpinBox->hide();
if (parameterMax == 0 && parameterMin == 0)
{
ui->editMaxSpinBox->setValue(10000);
ui->editMinSpinBox->setValue(0);
}
ui->valueSlider->setValue(floatToScaledInt(value.toFloat()));
break;
default:
qCritical() << "ERROR: NO VALID PARAM TYPE";
valueModLockParam = false;
return;
}
valueModLockParam = false;
parameterMax = ui->editMaxSpinBox->value();
parameterMin = ui->editMinSpinBox->value();
}
if (paramIndex == paramCount - 1) {
ui->editStatusLabel->setText(tr("Complete parameter list received."));
}
}
void QGCParamSlider::changeEvent(QEvent *e)
{
QWidget::changeEvent(e);
switch (e->type()) {
case QEvent::LanguageChange:
ui->retranslateUi(this);
break;
default:
break;
}
}
float QGCParamSlider::scaledIntToFloat(int sliderValue)
{
float result = (((double)sliderValue)/(double)scaledInt)*(ui->editMaxSpinBox->value() - ui->editMinSpinBox->value());
//qDebug() << "INT TO FLOAT: CONVERTED" << sliderValue << "TO" << result;
return result;
}
int QGCParamSlider::floatToScaledInt(float value)
{
int result = ((value - ui->editMinSpinBox->value())/(ui->editMaxSpinBox->value() - ui->editMinSpinBox->value()))*scaledInt;
//qDebug() << "FLOAT TO INT: CONVERTED" << value << "TO" << result << "SCALEDINT" << scaledInt;
return result;
}
void QGCParamSlider::writeSettings(QSettings& settings)
{
settings.setValue("TYPE", "SLIDER");
settings.setValue("QGC_PARAM_SLIDER_DESCRIPTION", ui->nameLabel->text());
//settings.setValue("QGC_PARAM_SLIDER_BUTTONTEXT", ui->actionButton->text());
settings.setValue("QGC_PARAM_SLIDER_PARAMID", parameterName);
settings.setValue("QGC_PARAM_SLIDER_COMPONENTID", componentId);
settings.setValue("QGC_PARAM_SLIDER_MIN", ui->editMinSpinBox->value());
settings.setValue("QGC_PARAM_SLIDER_MAX", ui->editMaxSpinBox->value());
settings.setValue("QGC_PARAM_SLIDER_DISPLAY_INFO", ui->editInfoCheckBox->isChecked());
settings.sync();
}
void QGCParamSlider::readSettings(const QString& pre,const QVariantMap& settings)
{
parameterName = settings.value(pre + "QGC_PARAM_SLIDER_PARAMID").toString();
componentId = settings.value(pre + "QGC_PARAM_SLIDER_COMPONENTID").toInt();
ui->nameLabel->setText(settings.value(pre + "QGC_PARAM_SLIDER_DESCRIPTION").toString());
ui->editNameLabel->setText(settings.value(pre + "QGC_PARAM_SLIDER_DESCRIPTION").toString());
//settings.setValue("QGC_PARAM_SLIDER_BUTTONTEXT", ui->actionButton->text());
ui->editSelectParamComboBox->addItem(settings.value(pre + "QGC_PARAM_SLIDER_PARAMID").toString());
ui->editSelectParamComboBox->setCurrentIndex(ui->editSelectParamComboBox->count()-1);
ui->editSelectComponentComboBox->addItem(tr("Component #%1").arg(settings.value(pre + "QGC_PARAM_SLIDER_COMPONENTID").toInt()), settings.value(pre + "QGC_PARAM_SLIDER_COMPONENTID").toInt());
ui->editMinSpinBox->setValue(settings.value(pre + "QGC_PARAM_SLIDER_MIN").toFloat());
ui->editMaxSpinBox->setValue(settings.value(pre + "QGC_PARAM_SLIDER_MAX").toFloat());
visibleParam = settings.value(pre+"QGC_PARAM_SLIDER_VISIBLE_PARAM","").toString();
visibleVal = settings.value(pre+"QGC_PARAM_SLIDER_VISIBLE_VAL",0).toInt();
parameterMax = ui->editMaxSpinBox->value();
parameterMin = ui->editMinSpinBox->value();
//ui->valueSlider->setMaximum(parameterMax);
//ui->valueSlider->setMinimum(parameterMin);
showInfo(settings.value(pre + "QGC_PARAM_SLIDER_DISPLAY_INFO", true).toBool());
ui->editSelectParamComboBox->setEnabled(true);
ui->editSelectComponentComboBox->setEnabled(true);
setActiveUAS(UASManager::instance()->getActiveUAS());
}
void QGCParamSlider::readSettings(const QSettings& settings)
{
QVariantMap map;
foreach (QString key,settings.allKeys())
{
map[key] = settings.value(key);
}
readSettings("",map);
return;
parameterName = settings.value("QGC_PARAM_SLIDER_PARAMID").toString();
componentId = settings.value("QGC_PARAM_SLIDER_COMPONENTID").toInt();
ui->nameLabel->setText(settings.value("QGC_PARAM_SLIDER_DESCRIPTION").toString());
ui->editNameLabel->setText(settings.value("QGC_PARAM_SLIDER_DESCRIPTION").toString());
//settings.setValue("QGC_PARAM_SLIDER_BUTTONTEXT", ui->actionButton->text());
ui->editSelectParamComboBox->addItem(settings.value("QGC_PARAM_SLIDER_PARAMID").toString());
ui->editSelectParamComboBox->setCurrentIndex(ui->editSelectParamComboBox->count()-1);
ui->editSelectComponentComboBox->addItem(tr("Component #%1").arg(settings.value("QGC_PARAM_SLIDER_COMPONENTID").toInt()), settings.value("QGC_PARAM_SLIDER_COMPONENTID").toInt());
ui->editMinSpinBox->setValue(settings.value("QGC_PARAM_SLIDER_MIN").toFloat());
ui->editMaxSpinBox->setValue(settings.value("QGC_PARAM_SLIDER_MAX").toFloat());
visibleParam = settings.value("QGC_PARAM_SLIDER_VISIBLE_PARAM","").toString();
//QGC_TOOL_WIDGET_ITEMS\1\QGC_PARAM_SLIDER_VISIBLE_PARAM=RC5_FUNCTION
visibleVal = settings.value("QGC_PARAM_SLIDER_VISIBLE_VAL",0).toInt();
parameterMax = ui->editMaxSpinBox->value();
parameterMin = ui->editMinSpinBox->value();
showInfo(settings.value("QGC_PARAM_SLIDER_DISPLAY_INFO", true).toBool());
ui->editSelectParamComboBox->setEnabled(true);
ui->editSelectComponentComboBox->setEnabled(true);
setActiveUAS(UASManager::instance()->getActiveUAS());
}
#ifndef QGCPARAMSLIDER_H
#define QGCPARAMSLIDER_H
#include <QWidget>
#include <QAction>
#ifndef __android__
#include <QtDesigner/QDesignerExportWidget>
#endif
#include "QGCToolWidgetItem.h"
namespace Ui
{
class QGCParamSlider;
}
class QGCParamSlider : public QGCToolWidgetItem
{
Q_OBJECT
public:
explicit QGCParamSlider(QWidget *parent = 0);
~QGCParamSlider();
virtual void setEditMode(bool editMode);
public slots:
/** @brief Queue parameter for sending to the MAV (add to pending list)*/
void setParamPending();
/** @brief Set the slider value as parameter value */
void setSliderValue(int sliderValue);
/** @brief Update the UI with the new parameter value */
void setParameterValue(int uas, int componentId, int paramCount, int paramIndex, QString parameterName, const QVariant value);
void writeSettings(QSettings& settings);
void readSettings(const QSettings& settings);
void readSettings(const QString& pre,const QVariantMap& settings);
void refreshParamList();
void setActiveUAS(UASInterface *uas);
void selectComponent(int componentIndex);
void selectParameter(int paramIndex);
/** @brief Set a double parameter value */
void setParamValue(double value);
/** @brief Set an integer parameter value */
void setParamValue(int value);
/** @brief Show descriptive text next to slider */
void showInfo(bool enable);
/** @brief Show tool tip of calling element */
void showTooltip();
protected slots:
/** @brief Request the parameter of this widget from the MAV */
void requestParameter();
protected:
bool visibleEnabled;
QString visibleParam;
int visibleVal;
//The below variables, and usage in QGCParamSlider.cc are a bit of a hack, since disconnect() does not seem to take effect
//immediatly (perhaps it is put into the event loop?) - MLC
bool valueModLock; ///< Used to keep the slider/spinboxes from updating each other during user input
bool valueModLockParam; ///< Used to keep the slider/spinboxes from udpating each other when a new parametervalue comes in
QString parameterName; ///< Key/Name of the parameter
QVariant parameterValue; ///< Value of the parameter
double parameterScalingFactor; ///< Factor to scale the parameter between slider and true value
float parameterMin;
float parameterMax;
int componentId; ///< ID of the MAV component to address
double scaledInt;
void changeEvent(QEvent *e);
/** @brief Convert scaled int to float */
float scaledIntToFloat(int sliderValue);
int floatToScaledInt(float value);
private:
Ui::QGCParamSlider *ui;
};
#endif // QGCPARAMSLIDER_H
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>QGCParamSlider</class>
<widget class="QWidget" name="QGCParamSlider">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>789</width>
<height>244</height>
</rect>
</property>
<property name="windowTitle">
<string>Form</string>
</property>
<layout class="QGridLayout" name="gridLayout" columnstretch="10,0,0,0,0,0,0,0,0,0,0">
<property name="leftMargin">
<number>6</number>
</property>
<property name="topMargin">
<number>3</number>
</property>
<property name="rightMargin">
<number>6</number>
</property>
<property name="bottomMargin">
<number>3</number>
</property>
<property name="horizontalSpacing">
<number>6</number>
</property>
<property name="verticalSpacing">
<number>12</number>
</property>
<item row="2" column="6">
<widget class="QSpinBox" name="intValueSpinBox">
<property name="minimum">
<number>-999999999</number>
</property>
<property name="maximum">
<number>999999999</number>
</property>
</widget>
</item>
<item row="3" column="6" colspan="3">
<widget class="QComboBox" name="editSelectParamComboBox">
<property name="enabled">
<bool>false</bool>
</property>
<property name="toolTip">
<string>Select parameter</string>
</property>
<property name="statusTip">
<string>Select parameter</string>
</property>
</widget>
</item>
<item row="0" column="0" colspan="11">
<widget class="Line" name="editLine1">
<property name="minimumSize">
<size>
<width>0</width>
<height>0</height>
</size>
</property>
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
</widget>
</item>
<item row="2" column="7" colspan="2">
<widget class="QSlider" name="valueSlider">
<property name="minimumSize">
<size>
<width>60</width>
<height>0</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>250</width>
<height>16777215</height>
</size>
</property>
<property name="maximum">
<number>1000000</number>
</property>
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
</widget>
</item>
<item row="4" column="10">
<widget class="QPushButton" name="editDoneButton">
<property name="text">
<string>Done</string>
</property>
</widget>
</item>
<item row="6" column="0" colspan="11">
<widget class="Line" name="editLine2">
<property name="minimumSize">
<size>
<width>0</width>
<height>0</height>
</size>
</property>
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
</widget>
</item>
<item row="3" column="9">
<widget class="QCheckBox" name="editInfoCheckBox">
<property name="text">
<string>Show Info</string>
</property>
<property name="checked">
<bool>true</bool>
</property>
</widget>
</item>
<item row="2" column="0">
<spacer name="horizontalSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>0</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item row="3" column="10">
<widget class="QPushButton" name="editRefreshParamsButton">
<property name="enabled">
<bool>true</bool>
</property>
<property name="text">
<string>Refresh</string>
</property>
</widget>
</item>
<item row="2" column="10">
<widget class="QPushButton" name="readButton">
<property name="minimumSize">
<size>
<width>0</width>
<height>0</height>
</size>
</property>
<property name="toolTip">
<string>Read the current parameter value on the system</string>
</property>
<property name="statusTip">
<string>Read the current parameter value on the system</string>
</property>
<property name="text">
<string>Get</string>
</property>
</widget>
</item>
<item row="3" column="1" colspan="5">
<widget class="QComboBox" name="editSelectComponentComboBox">
<property name="enabled">
<bool>false</bool>
</property>
<property name="toolTip">
<string>Select component</string>
</property>
<property name="statusTip">
<string>Select component</string>
</property>
</widget>
</item>
<item row="1" column="1" colspan="7">
<widget class="QLineEdit" name="editNameLabel">
<property name="placeholderText">
<string>Parameter Name / Label</string>
</property>
</widget>
</item>
<item row="4" column="1" colspan="8">
<widget class="QLabel" name="editStatusLabel">
<property name="text">
<string>Please click first on refresh to update selection menus..</string>
</property>
</widget>
</item>
<item row="2" column="9">
<widget class="QPushButton" name="writeButton">
<property name="minimumSize">
<size>
<width>0</width>
<height>0</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>16777215</width>
<height>16777215</height>
</size>
</property>
<property name="toolTip">
<string>Transmit the current slider value to the system</string>
</property>
<property name="statusTip">
<string>Transmit the current slider value to the system</string>
</property>
<property name="text">
<string>Set</string>
</property>
</widget>
</item>
<item row="2" column="4">
<widget class="QDoubleSpinBox" name="doubleValueSpinBox">
<property name="minimum">
<double>-999999999.000000000000000</double>
</property>
<property name="maximum">
<double>999999999.000000000000000</double>
</property>
</widget>
</item>
<item row="1" column="8">
<widget class="QDoubleSpinBox" name="editMinSpinBox">
<property name="prefix">
<string>MIN: </string>
</property>
<property name="minimum">
<double>-999999999.000000000000000</double>
</property>
<property name="maximum">
<double>999999999.000000000000000</double>
</property>
</widget>
</item>
<item row="1" column="9" colspan="2">
<widget class="QDoubleSpinBox" name="editMaxSpinBox">
<property name="prefix">
<string>MAX: </string>
</property>
<property name="minimum">
<double>-999999999.000000000000000</double>
</property>
<property name="maximum">
<double>999999999.000000000000000</double>
</property>
</widget>
</item>
<item row="2" column="2">
<widget class="QLabel" name="nameLabel">
<property name="minimumSize">
<size>
<width>60</width>
<height>0</height>
</size>
</property>
<property name="text">
<string>Name</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
</widget>
</item>
<item row="2" column="3">
<widget class="QToolButton" name="infoLabel">
<property name="text">
<string>?</string>
</property>
</widget>
</item>
<item row="5" column="0" colspan="11">
<spacer name="verticalSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
</size>
</property>
</spacer>
</item>
</layout>
</widget>
<resources/>
<connections/>
</ui>
#include "QGCParamSliderPlugin.h"
#include "QGCParamSlider.h"
#include <QtPlugin>
QGCParamSliderPlugin::QGCParamSliderPlugin(QObject *parent) :
QObject(parent)
{
initialized = false;
}
void QGCParamSliderPlugin::initialize(QDesignerFormEditorInterface * /* core */)
{
if (initialized)
return;
initialized = true;
}
bool QGCParamSliderPlugin::isInitialized() const
{
return initialized;
}
QWidget *QGCParamSliderPlugin::createWidget(QWidget *parent)
{
return new QGCParamSlider(parent);
}
QString QGCParamSliderPlugin::name() const
{
return "QGCParamSlider";
}
QString QGCParamSliderPlugin::group() const
{
return "QGroundControl";
}
QIcon QGCParamSliderPlugin::icon() const
{
return QIcon();
}
QString QGCParamSliderPlugin::toolTip() const
{
return "";
}
QString QGCParamSliderPlugin::whatsThis() const
{
return "";
}
bool QGCParamSliderPlugin::isContainer() const
{
return false;
}
QString QGCParamSliderPlugin::domXml() const
{
return "<ui language=\"c++\">\n"
" <widget class=\"QGCParamSlider\" name=\"paramSlider\">\n"
" <property name=\"geometry\">\n"
" <rect>\n"
" <x>0</x>\n"
" <y>0</y>\n"
" <width>150</width>\n"
" <height>16</height>\n"
" </rect>\n"
" </property>\n"
" </widget>\n"
"</ui>";
}
QString QGCParamSliderPlugin::includeFile() const
{
return "QGCParamSlider.h";
}
Q_EXPORT_PLUGIN2(qgcparamsliderplugin, QGCParamSliderPlugin)
#include "QGCRadioChannelDisplay.h"
#include <QPainter>
#define DIMMEST_COLOR QColor::fromRgb(0,100,0)
#define MIDBRIGHT_COLOR QColor::fromRgb(0,180,0)
#define BRIGHTEST_COLOR QColor::fromRgb(64,255,0)
QGCRadioChannelDisplay::QGCRadioChannelDisplay(QWidget *parent) : QWidget(parent)
{
m_showMinMax = false;
m_min = 0;
m_max = 1;
m_value = 1500;
m_orientation = Qt::Vertical;
m_name = "Yaw";
m_fillBrush = QBrush(Qt::green, Qt::SolidPattern);
}
void QGCRadioChannelDisplay::setName(QString name)
{
m_name = name;
update();
}
void QGCRadioChannelDisplay::setOrientation(Qt::Orientation orient)
{
m_orientation = orient;
update();
}
void QGCRadioChannelDisplay::paintEvent(QPaintEvent *event)
{
Q_UNUSED(event);
//Values range from 0-3000.
//1500 is the middle, static servo value.
QPainter painter(this);
int fontHeight = painter.fontMetrics().height();
int twiceFontHeight = fontHeight * 2;
painter.setBrush(Qt::Dense4Pattern);
painter.setPen(QColor::fromRgb(128,128,64));
int curVal = m_value;
if (curVal > m_max) {
curVal = m_max;
}
if (curVal < m_min) {
curVal = m_min;
}
if (m_orientation == Qt::Vertical)
{
QLinearGradient gradientBrush(0, 0, this->width(), this->height());
gradientBrush.setColorAt(1.0,DIMMEST_COLOR);
gradientBrush.setColorAt(0.5,MIDBRIGHT_COLOR);
gradientBrush.setColorAt(0.0, BRIGHTEST_COLOR);
//draw border
painter.drawRect(0,0,width()-1,(height()-1) - twiceFontHeight);
painter.setPen(QColor::fromRgb(50,255,50));
painter.setBrush(Qt::SolidPattern);
//draw the text value of the widget, and its label
painter.setPen(QColor::fromRgb(255,255,255));
painter.drawText((width()/2.0) - (painter.fontMetrics().width(m_name)/2.0),((height()-3) - (fontHeight*1)),m_name);
if (isEnabled()) {
QString valStr = QString::number(m_value);
painter.drawText((width()/2.0) - (painter.fontMetrics().width(valStr)/2.0),((height()-3) - (fontHeight * 0)),valStr);
painter.setPen(QColor::fromRgb(128,128,64));
painter.setBrush(gradientBrush);
if (!m_showMinMax) {
//draw just the value
int newval = (height()-2-twiceFontHeight) * ((float)(curVal - m_min) / ((m_max-m_min)+1));
int yVal = (height()-2-twiceFontHeight) - newval;
painter.drawRect(1,yVal,width()-3,((height()-2) - yVal - twiceFontHeight));
}
else {
//draw the value
int newval = (height()-2-twiceFontHeight) * ((float)(curVal / 3001.0));
int yVal = (height()-2-twiceFontHeight) - newval;
painter.drawRect(1,yVal,width()-3,((height()-2) - yVal - twiceFontHeight));
//draw min max indicator bars
painter.setPen(QColor::fromRgb(255,0,0));
painter.setBrush(Qt::NoBrush);
int yMax = (height()-3 - twiceFontHeight) - (((height()-3-twiceFontHeight) * ((float)m_max / 3000.0)));
int yMin = (height()-3 - twiceFontHeight) - (((height()-3-twiceFontHeight) * ((float)m_min / 3000.0)));
painter.drawRect(2,yMax,width()-3,yMin - yMax);
//draw min and max labels
QString minstr = QString::number(m_min);
painter.drawText((width() / 2.0) - (painter.fontMetrics().width("min")/2.0),yMin,"min");
painter.drawText((width() / 2.0) - (painter.fontMetrics().width(minstr)/2.0),yMin + fontHeight,minstr);
QString maxstr = QString::number(m_max);
painter.drawText((width() / 2.0) - (painter.fontMetrics().width("max")/2.0),yMax,"max");
painter.drawText((width() / 2.0) - (painter.fontMetrics().width(maxstr)/2.0),yMax + fontHeight,maxstr);
}
}
}
else //horizontal orientation
{
QLinearGradient hGradientBrush(0, 0, this->width(), this->height());
hGradientBrush.setColorAt(0.0,DIMMEST_COLOR);
hGradientBrush.setColorAt(0.5,MIDBRIGHT_COLOR);
hGradientBrush.setColorAt(1.0, BRIGHTEST_COLOR);
//draw the value
painter.drawRect(0,0,width()-1,(height()-1) - twiceFontHeight);
painter.setPen(QColor::fromRgb(50,255,50));
painter.setBrush(hGradientBrush);
//draw the value string
painter.setPen(QColor::fromRgb(255,255,255));
painter.drawText((width()/2.0) - (painter.fontMetrics().width(m_name)/2.0),((height()-3) - (fontHeight*1)),m_name);
if (isEnabled()) {
QString valstr = QString::number(m_value);
painter.drawText((width()/2.0) - (painter.fontMetrics().width(valstr)/2.0),((height()-3) - (fontHeight * 0)),valstr);
painter.setPen(QColor::fromRgb(0,128,0));
painter.setBrush(hGradientBrush);
if (!m_showMinMax) {
//draw just the value
painter.drawRect(1,1,(width()-3) * ((float)(curVal-m_min) / (m_max-m_min)),(height()-3) - twiceFontHeight);
}
else {
//draw the value
painter.drawRect(1,1,(width()-3) * ((float)curVal / 3000.0),(height()-3) - twiceFontHeight);
//draw the min and max bars
painter.setBrush(Qt::NoBrush);
painter.setPen(QColor::fromRgb(255,0,0));
painter.drawRect(width() * ((float)m_min / 3000.0),2,((width()-1) * ((float)m_max / 3000.0)) - (width() * ((float)m_min / 3000.0)),(height()-5) - twiceFontHeight);
//draw the min and max strings
QString minstr = QString::number(m_min);
painter.drawText((width() * ((float)m_min / 3000.0)) - (painter.fontMetrics().width("min")/2.0),((height()-3) - (painter.fontMetrics().height()*1)),"min");
painter.drawText((width() * ((float)m_min / 3000.0)) - (painter.fontMetrics().width(minstr)/2.0),((height()-3) - (painter.fontMetrics().height() * 0)),minstr);
QString maxstr = QString::number(m_max);
painter.drawText((width() * ((float)m_max / 3000.0)) - (painter.fontMetrics().width("max")/2.0),((height()-3) - (painter.fontMetrics().height()*1)),"max");
painter.drawText((width() * ((float)m_max / 3000.0)) - (painter.fontMetrics().width(maxstr)/2.0),((height()-3) - (painter.fontMetrics().height() * 0)),maxstr);
}
}
}
}
void QGCRadioChannelDisplay::setValue(int value)
{
if (value < 0)
{
m_value = 0;
}
else if (value > 3000)
{
m_value = 3000;
}
else
{
m_value = value;
}
update();
}
void QGCRadioChannelDisplay::showMinMax(bool show)
{
m_showMinMax = show;
update();
}
void QGCRadioChannelDisplay::hideMinMax()
{
m_showMinMax = false;
update();
}
void QGCRadioChannelDisplay::setValueAndRange(int val, int min, int max)
{
setValue(val);
setMinMax(min,max);
}
void QGCRadioChannelDisplay::setMinMax(int min, int max)
{
setMin(min);
setMax(max);
}
void QGCRadioChannelDisplay::setMin(int value)
{
m_min = value;
if (m_min == m_max)
{
m_min--;
}
update();
}
void QGCRadioChannelDisplay::setMax(int value)
{
m_max = value;
if (m_min == m_max)
{
m_max++;
}
update();
}
#ifndef QGCRADIOCHANNELDISPLAY_H
#define QGCRADIOCHANNELDISPLAY_H
#include <QWidget>
class QGCRadioChannelDisplay : public QWidget
{
Q_OBJECT
public:
explicit QGCRadioChannelDisplay(QWidget *parent = 0);
void setOrientation(Qt::Orientation orient);
void setValue(int value);
void showMinMax(bool show = true);
void hideMinMax();
bool isMinMaxShown() { return m_showMinMax; }
void setValueAndRange(int val, int min, int max);
void setMinMax(int min, int max);
void setMin(int value);
void setMax(int value);
void setName(QString name);
int value() { return m_value; }
int min() { return m_min; }
int max() { return m_max; }
protected:
void paintEvent(QPaintEvent *event);
private:
Qt::Orientation m_orientation;
int m_value;
int m_min;
int m_max;
bool m_showMinMax;
QString m_name;
QBrush m_fillBrush;
signals:
public slots:
};
#endif // QGCRADIOCHANNELDISPLAY_H
#include <QDockWidget>
#include "QGCTextLabel.h"
#include "ui_QGCTextLabel.h"
#include "MAVLinkProtocol.h"
#include "UASManager.h"
QGCTextLabel::QGCTextLabel(QWidget *parent) :
QGCToolWidgetItem("Text Label", parent),
ui(new Ui::QGCTextLabel)
{
uas = 0;
enabledNum = -1;
ui->setupUi(this);
connect(ui->editFinishButton, SIGNAL(clicked()), this, SLOT(endEditMode()));
connect(ui->isMavCommand, SIGNAL(toggled(bool)), this, SLOT(update_isMavCommand()));
// Hide all edit items
ui->editFinishButton->hide();
ui->editNameLabel->hide();
ui->editLine1->hide();
ui->editLine2->hide();
ui->isMavCommand->hide();
ui->textLabel->setText(QString());
init();
}
QGCTextLabel::~QGCTextLabel()
{
delete ui;
}
void QGCTextLabel::setEditMode(bool editMode)
{
if(!editMode)
update_isMavCommand();
ui->editFinishButton->setVisible(editMode);
ui->editNameLabel->setVisible(editMode);
ui->editLine1->setVisible(editMode);
ui->editLine2->setVisible(editMode);
ui->isMavCommand->setVisible(editMode);
QGCToolWidgetItem::setEditMode(editMode);
}
void QGCTextLabel::writeSettings(QSettings& settings)
{
settings.setValue("TYPE", "TEXT");
settings.setValue("QGC_TEXT_TEXT", ui->editNameLabel->text());
settings.setValue("QGC_TEXT_SOURCE", ui->isMavCommand->isChecked()?"MAV":"NONE");
settings.sync();
}
void QGCTextLabel::readSettings(const QString& pre,const QVariantMap& settings)
{
ui->editNameLabel->setText(settings.value(pre + "QGC_TEXT_TEXT","").toString());
ui->isMavCommand->setChecked(settings.value(pre + "QGC_TEXT_SOURCE", "NONE").toString() == "MAV");
update_isMavCommand();
}
void QGCTextLabel::textMessageReceived(int uasid, int component, int severity, QString message)
{
Q_UNUSED(uasid);
Q_UNUSED(component);
Q_UNUSED(severity);
if (enabledNum != -1)
{
//SUCCESS: Executed CMD: 241
if (message.contains("SUCCESS"))
{
if (message.trimmed().endsWith(QString::number(enabledNum)))
{
enabledNum = -1;
ui->textLabel->setText(ui->textLabel->text() + " Complete");
}
}
else
{
ui->textLabel->setText(message);
}
}
}
void QGCTextLabel::readSettings(const QSettings& settings)
{
ui->editNameLabel->setText(settings.value("QGC_TEXT_TEXT","").toString()); //Place this before setting isMavCommand
ui->isMavCommand->setChecked(settings.value("QGC_TEXT_SOURCE", "NONE").toString() == "MAV");
update_isMavCommand();
}
void QGCTextLabel::enableText(int num)
{
enabledNum = num;
}
void QGCTextLabel::setActiveUAS(UASInterface *uas)
{
if(this->uas)
this->uas->disconnect(this);
this->uas = uas;
update_isMavCommand(); //Might need to update the signal connections
}
void QGCTextLabel::update_isMavCommand()
{
ui->textLabel->setText("");
if (!ui->isMavCommand->isChecked())
{
ui->nameLabel->setText(ui->editNameLabel->text());
if(this->uas)
disconnect(uas,SIGNAL(textMessageReceived(int,int,int,QString)),this,SLOT(textMessageReceived(int,int,int,QString)));
if(ui->nameLabel->text().isEmpty())
ui->nameLabel->setText(tr("Text Label")); //Show something, so that we don't end up with just an empty label
}
else
{
//MAV command text
ui->nameLabel->setText(ui->editNameLabel->text());
if(this->uas)
connect(uas,SIGNAL(textMessageReceived(int,int,int,QString)),this,SLOT(textMessageReceived(int,int,int,QString)));
}
}
#ifndef QGCTEXTLABEL_H
#define QGCTEXTLABEL_H
#include "QGCToolWidgetItem.h"
namespace Ui
{
class QGCTextLabel;
}
class UASInterface;
class QGCTextLabel : public QGCToolWidgetItem
{
Q_OBJECT
public:
explicit QGCTextLabel(QWidget *parent = 0);
~QGCTextLabel();
void setActiveUAS(UASInterface *uas);
void enableText(int num);
virtual void setEditMode(bool editMode);
public slots:
void writeSettings(QSettings& settings);
void readSettings(const QSettings& settings);
void readSettings(const QString& pre,const QVariantMap& settings);
void textMessageReceived(int uasid, int componentId, int severity, QString message);
private slots:
void update_isMavCommand();
private:
int enabledNum;
Ui::QGCTextLabel *ui;
};
#endif // QGCTEXTLABEL_H
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>QGCTextLabel</class>
<widget class="QWidget" name="QGCTextLabel">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>554</width>
<height>107</height>
</rect>
</property>
<property name="windowTitle">
<string>Form</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<widget class="Line" name="editLine1">
<property name="minimumSize">
<size>
<width>0</width>
<height>0</height>
</size>
</property>
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
</widget>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<widget class="QLineEdit" name="editNameLabel">
<property name="text">
<string/>
</property>
<property name="placeholderText">
<string>Label Description</string>
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="isMavCommand">
<property name="toolTip">
<string>This is only for advanced use, and allows a label to display the results of a Command Button.</string>
</property>
<property name="text">
<string>Mav Command</string>
</property>
</widget>
</item>
</layout>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_2">
<item>
<widget class="QLabel" name="nameLabel">
<property name="minimumSize">
<size>
<width>50</width>
<height>0</height>
</size>
</property>
<property name="text">
<string>Text Label</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="textLabel">
<property name="text">
<string>mav result</string>
</property>
</widget>
</item>
</layout>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_3">
<item>
<spacer name="horizontalSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QPushButton" name="editFinishButton">
<property name="text">
<string>Done</string>
</property>
</widget>
</item>
</layout>
</item>
<item>
<widget class="Line" name="editLine2">
<property name="minimumSize">
<size>
<width>0</width>
<height>0</height>
</size>
</property>
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
</widget>
</item>
</layout>
</widget>
<resources/>
<connections>
<connection>
<sender>editNameLabel</sender>
<signal>textChanged(QString)</signal>
<receiver>nameLabel</receiver>
<slot>setText(QString)</slot>
<hints>
<hint type="sourcelabel">
<x>280</x>
<y>32</y>
</hint>
<hint type="destinationlabel">
<x>114</x>
<y>55</y>
</hint>
</hints>
</connection>
<connection>
<sender>editNameLabel</sender>
<signal>returnPressed()</signal>
<receiver>editFinishButton</receiver>
<slot>animateClick()</slot>
<hints>
<hint type="sourcelabel">
<x>136</x>
<y>20</y>
</hint>
<hint type="destinationlabel">
<x>498</x>
<y>86</y>
</hint>
</hints>
</connection>
</connections>
</ui>
#include "QGCToolWidget.h"
#include "ui_QGCToolWidget.h"
#include <QMenu>
#include <QList>
#include <QInputDialog>
#include <QDockWidget>
#include <QContextMenuEvent>
#include <QSettings>
#include <QStandardPaths>
#include "QGCParamSlider.h"
#include "QGCToolWidgetComboBox.h"
#include "QGCTextLabel.h"
#include "QGCXYPlot.h"
#include "QGCCommandButton.h"
#include "UASManager.h"
#include "QGCFileDialog.h"
QGCToolWidget::QGCToolWidget(const QString& objectName, const QString& title, QWidget *parent, QSettings* settings) :
QWidget(parent),
mav(NULL),
mainMenuAction(NULL),
widgetTitle(title),
ui(new Ui::QGCToolWidget)
{
isFromMetaData = false;
ui->setupUi(this);
if (settings) loadSettings(*settings);
createActions();
toolLayout = ui->toolLayout;
toolLayout->setAlignment(Qt::AlignTop);
toolLayout->setSpacing(8);
this->setTitle(widgetTitle);
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*)));
if(!objectName.isEmpty()) {
instances()->insert(objectName, this);
setObjectName(objectName);
} //Otherwise we must call loadSettings() immediately to set the object name
}
QGCToolWidget::~QGCToolWidget()
{
if (mainMenuAction) mainMenuAction->deleteLater();
if (QGCToolWidget::instances()) QGCToolWidget::instances()->remove(objectName());
delete ui;
}
void QGCToolWidget::setParent(QWidget *parent)
{
QWidget::setParent(parent);
setTitle(getTitle()); //Update titles
}
/**
* @param parent Object later holding these widgets, usually the main window
* @return List of all widgets
*/
QList<QGCToolWidget*> QGCToolWidget::createWidgetsFromSettings(QWidget* parent, QString settingsFile)
{
// Load widgets from application settings
QSettings* settings;
// Or load them from a settings file
if (!settingsFile.isEmpty())
{
settings = new QSettings(settingsFile, QSettings::IniFormat);
//qDebug() << "LOADING SETTINGS FROM" << settingsFile;
}
else
{
settings = new QSettings();
//qDebug() << "LOADING SETTINGS FROM DEFAULT" << settings->fileName();
}
QList<QGCToolWidget*> newWidgets;
settings->beginGroup("Custom_Tool_Widgets");
int size = settings->beginReadArray("QGC_TOOL_WIDGET_NAMES");
for (int i = 0; i < size; i++)
{
settings->setArrayIndex(i);
QString name = settings->value("TITLE", "").toString();
QString objname = settings->value("OBJECT_NAME", "").toString();
if (!instances()->contains(objname) && !objname.isEmpty())
{
//qDebug() << "CREATED WIDGET:" << name;
QGCToolWidget* tool = new QGCToolWidget(objname, name, parent, settings);
newWidgets.append(tool);
}
else if (name.length() == 0)
{
// Silently catch empty widget name - sanity check
// to survive broken settings (e.g. from user manipulation)
}
else
{
//qDebug() << "WIDGET" << name << "DID ALREADY EXIST, REJECTING";
}
}
settings->endArray();
//qDebug() << "NEW WIDGETS: " << newWidgets.size();
// Load individual widget items
for (int i = 0; i < newWidgets.size(); i++)
{
newWidgets.at(i)->loadSettings(*settings);
}
settings->endGroup();
settings->sync();
delete settings;
return instances()->values();
}
void QGCToolWidget::showLabel(QString name,int num)
{
for (int i=0;i<toolItemList.size();i++)
{
if (toolItemList[i]->objectName() == name)
{
QGCTextLabel *label = qobject_cast<QGCTextLabel*>(toolItemList[i]);
if (label)
{
label->enableText(num);
}
}
}
}
/**
* @param singleinstance If this is set to true, the widget settings will only be loaded if not another widget with the same title exists
*/
bool QGCToolWidget::loadSettings(const QString& settings, bool singleinstance)
{
QSettings set(settings, QSettings::IniFormat);
QStringList groups = set.childGroups();
if (groups.length() > 0)
{
QString objectName = groups.first();
setObjectName(objectName);
if (singleinstance && QGCToolWidget::instances()->contains(objectName)) return false;
instances()->insert(objectName, this);
// Do not use setTitle() here,
// interferes with loading settings
widgetTitle = objectName;
//qDebug() << "WIDGET TITLE LOADED: " << widgetName;
loadSettings(set);
return true;
}
else
{
return false;
}
}
void QGCToolWidget::setSettings(QVariantMap& settings)
{
isFromMetaData = true;
settingsMap = settings;
QString widgetName = getTitle();
int size = settingsMap["count"].toInt();
for (int j = 0; j < size; j++)
{
QString type = settings.value(widgetName + "\\" + QString::number(j) + "\\" + "TYPE", "UNKNOWN").toString();
if (type == "SLIDER")
{
QString checkparam = settingsMap.value(widgetName + "\\" + QString::number(j) + "\\" + "QGC_PARAM_SLIDER_PARAMID").toString();
paramList.append(checkparam);
}
else if (type == "COMBO")
{
QString checkparam = settingsMap.value(widgetName + "\\" + QString::number(j) + "\\" + "QGC_PARAM_COMBOBOX_PARAMID").toString();
paramList.append(checkparam);
}
}
}
QList<QString> QGCToolWidget::getParamList()
{
return paramList;
}
void QGCToolWidget::setParameterValue(int uas, int component, QString parameterName, const QVariant value)
{
Q_UNUSED(uas);
Q_UNUSED(component);
Q_UNUSED(value);
QString widgetName = getTitle();
int size = settingsMap["count"].toInt();
if (paramToItemMap.contains(parameterName))
{
//If we already have an item for this parameter, updates are handled internally.
return;
}
for (int j = 0; j < size; j++)
{
QString type = settingsMap.value(widgetName + "\\" + QString::number(j) + "\\" + "TYPE", "UNKNOWN").toString();
QGCToolWidgetItem* item = NULL;
if (type == "COMMANDBUTTON")
{
//This shouldn't happen, but I'm not sure... so lets test for it.
continue;
}
else if (type == "SLIDER")
{
QString checkparam = settingsMap.value(widgetName + "\\" + QString::number(j) + "\\" + "QGC_PARAM_SLIDER_PARAMID").toString();
if (checkparam == parameterName)
{
item = new QGCParamSlider(this);
paramToItemMap[parameterName] = item;
addToolWidget(item);
item->readSettings(widgetName + "\\" + QString::number(j) + "\\",settingsMap);
return;
}
}
else if (type == "COMBO")
{
QString checkparam = settingsMap.value(widgetName + "\\" + QString::number(j) + "\\" + "QGC_PARAM_COMBOBOX_PARAMID").toString();
if (checkparam == parameterName)
{
item = new QGCToolWidgetComboBox(this);
addToolWidget(item);
item->readSettings(widgetName + "\\" + QString::number(j) + "\\",settingsMap);
paramToItemMap[parameterName] = item;
return;
}
}
}
}
void QGCToolWidget::loadSettings(QVariantMap& settings)
{
QString widgetName = getTitle();
//settings.beginGroup(widgetName);
qDebug() << "LOADING FOR" << widgetName;
//int size = settings.beginReadArray("QGC_TOOL_WIDGET_ITEMS");
int size = settings["count"].toInt();
qDebug() << "CHILDREN SIZE:" << size;
for (int j = 0; j < size; j++)
{
QApplication::processEvents();
//settings.setArrayIndex(j);
QString type = settings.value(widgetName + "\\" + QString::number(j) + "\\" + "TYPE", "UNKNOWN").toString();
if (type != "UNKNOWN")
{
QGCToolWidgetItem* item = NULL;
if (type == "COMMANDBUTTON")
{
item = new QGCCommandButton(this);
//qDebug() << "CREATED COMMANDBUTTON";
}
else if (type == "TEXT")
{
item = new QGCTextLabel(this);
item->setActiveUAS(mav);
}
else if (type == "SLIDER")
{
item = new QGCParamSlider(this);
//qDebug() << "CREATED PARAM SLIDER";
}
else if (type == "COMBO")
{
item = new QGCToolWidgetComboBox(this);
//qDebug() << "CREATED COMBOBOX";
}
else if (type == "XYPLOT")
{
item = new QGCXYPlot(this);
//qDebug() << "CREATED XYPlot";
}
if (item)
{
// Configure and add to layout
addToolWidget(item);
item->readSettings(widgetName + "\\" + QString::number(j) + "\\",settings);
//qDebug() << "Created tool widget";
}
}
else
{
qDebug() << "UNKNOWN TOOL WIDGET TYPE" << type;
}
}
//settings.endArray();
//settings.endGroup();
}
void QGCToolWidget::loadSettings(QSettings& settings)
{
QString widgetName = getTitle();
settings.beginGroup(widgetName);
//qDebug() << "LOADING FOR" << widgetName;
int size = settings.beginReadArray("QGC_TOOL_WIDGET_ITEMS");
//qDebug() << "CHILDREN SIZE:" << size;
for (int j = 0; j < size; j++)
{
settings.setArrayIndex(j);
QString type = settings.value("TYPE", "UNKNOWN").toString();
if (type != "UNKNOWN")
{
QGCToolWidgetItem* item = NULL;
if (type == "COMMANDBUTTON")
{
QGCCommandButton *button = new QGCCommandButton(this);
connect(button,SIGNAL(showLabel(QString,int)),this,SLOT(showLabel(QString,int)));
item = button;
item->setActiveUAS(mav);
//qDebug() << "CREATED COMMANDBUTTON";
}
else if (type == "SLIDER")
{
item = new QGCParamSlider(this);
item->setActiveUAS(mav);
//qDebug() << "CREATED PARAM SLIDER";
}
else if (type == "COMBO")
{
item = new QGCToolWidgetComboBox(this);
item->setActiveUAS(mav);
qDebug() << "CREATED PARAM COMBOBOX";
}
else if (type == "TEXT")
{
item = new QGCTextLabel(this);
item->setObjectName(settings.value("QGC_TEXT_ID").toString());
item->setActiveUAS(mav);
}
else if (type == "XYPLOT")
{
item = new QGCXYPlot(this);
item->setActiveUAS(mav);
}
if (item)
{
// Configure and add to layout
addToolWidget(item);
item->readSettings(settings);
//qDebug() << "Created tool widget";
}
}
else
{
//qDebug() << "UNKNOWN TOOL WIDGET TYPE";
}
}
settings.endArray();
settings.endGroup();
}
void QGCToolWidget::storeWidgetsToSettings(QSettings &settings) //static
{
settings.beginGroup("Custom_Tool_Widgets");
int preArraySize = settings.beginReadArray("QGC_TOOL_WIDGET_NAMES");
settings.endArray();
settings.beginWriteArray("QGC_TOOL_WIDGET_NAMES");
int num = 0;
for (int i = 0; i < qMax(preArraySize, instances()->size()); ++i)
{
if (i < instances()->size())
{
// Updating value
if (!instances()->values().at(i)->fromMetaData())
{
settings.setArrayIndex(num++);
settings.setValue("TITLE", instances()->values().at(i)->getTitle());
settings.setValue("OBJECT_NAME", instances()->values().at(i)->objectName());
qDebug() << "WRITING TITLE" << instances()->values().at(i)->getTitle() << "object:" << instances()->values().at(i)->objectName();
}
}
else
{
// Deleting old value
settings.remove("TITLE");
}
}
settings.endArray();
// Store individual widget items
for (int i = 0; i < instances()->size(); ++i)
{
instances()->values().at(i)->storeSettings(settings);
}
settings.endGroup();
settings.sync();
}
void QGCToolWidget::storeSettings(QSettings& settings)
{
/* This function should be called from storeWidgetsToSettings() which sets up the group etc */
Q_ASSERT(settings.group() == "Custom_Tool_Widgets");
if (isFromMetaData)
{
//Refuse to store if this is loaded from metadata or dynamically generated.
return;
}
//qDebug() << "WRITING WIDGET" << widgetTitle << "TO SETTINGS";
settings.beginGroup(widgetTitle);
settings.beginWriteArray("QGC_TOOL_WIDGET_ITEMS");
int k = 0; // QGCToolItem counter
foreach(QGCToolWidgetItem *item, toolItemList) {
// Only count actual tool widget item children
settings.setArrayIndex(k++);
// Store the ToolWidgetItem
item->writeSettings(settings);
}
//qDebug() << "WROTE" << k << "SUB-WIDGETS TO SETTINGS";
settings.endArray();
settings.endGroup();
}
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(addCommandAction);
menu.addAction(addLabelAction);
menu.addAction(addPlotAction);
menu.addSeparator();
menu.addAction(setTitleAction);
menu.addAction(exportAction);
menu.addAction(importAction);
menu.addAction(deleteAction);
menu.exec(event->globalPos());
}
void QGCToolWidget::hideEvent(QHideEvent* event)
{
// Store settings
QWidget::hideEvent(event);
}
/**
* The widgets current view and the applied dock widget area.
* Both values are only stored internally and allow an external
* widget to configure it accordingly
*/
void QGCToolWidget::setViewVisibilityAndDockWidgetArea(int view, bool visible, Qt::DockWidgetArea area)
{
viewVisible.insert(view, visible);
dockWidgetArea.insert(view, area);
}
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()));
addCommandAction = new QAction(tr("New MAV &Command Button"), this);
addCommandAction->setStatusTip(tr("Add a new action button to the tool"));
connect(addCommandAction, SIGNAL(triggered()), this, SLOT(addCommand()));
addLabelAction = new QAction(tr("New &Text Label"), this);
addLabelAction->setStatusTip(tr("Add a new label to the tool"));
connect(addLabelAction, SIGNAL(triggered()), this, SLOT(addLabel()));
addPlotAction = new QAction(tr("New &XY Plot"), this);
addPlotAction->setStatusTip(tr("Add a XY Plot to the tool"));
connect(addPlotAction, SIGNAL(triggered()), this, SLOT(addPlot()));
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()));
deleteAction = new QAction(tr("Delete this widget"), this);
deleteAction->setStatusTip(tr("Delete this widget permanently"));
connect(deleteAction, SIGNAL(triggered()), this, SLOT(deleteWidget()));
exportAction = new QAction(tr("Export this widget"), this);
exportAction->setStatusTip(tr("Export this widget to be reused by others"));
connect(exportAction, SIGNAL(triggered()), this, SLOT(exportWidget()));
importAction = new QAction(tr("Import widget"), this);
importAction->setStatusTip(tr("Import this widget from a file (current content will be removed)"));
connect(importAction, SIGNAL(triggered()), this, SLOT(importWidget()));
}
QMap<QString, QGCToolWidget*>* QGCToolWidget::instances()
{
static QMap<QString, QGCToolWidget*>* instances;
if (!instances) instances = new QMap<QString, QGCToolWidget*>();
return instances;
}
void QGCToolWidget::addParam(int uas,int component,QString paramname,QVariant value)
{
isFromMetaData = true;
QGCParamSlider* slider = new QGCParamSlider(this);
addToolWidget(slider);
slider->setActiveUAS(mav);
slider->setParameterValue(uas,component,0,-1,paramname,value);
}
void QGCToolWidget::addParam()
{
addToolWidgetAndEdit(new QGCParamSlider(this));
}
void QGCToolWidget::addCommand()
{
addToolWidgetAndEdit(new QGCCommandButton(this));
}
void QGCToolWidget::addLabel()
{
addToolWidgetAndEdit(new QGCTextLabel(this));
}
void QGCToolWidget::addPlot()
{
addToolWidgetAndEdit(new QGCXYPlot(this));
}
void QGCToolWidget::addToolWidgetAndEdit(QGCToolWidgetItem* widget)
{
addToolWidget(widget);
widget->startEditMode();
}
void QGCToolWidget::addToolWidget(QGCToolWidgetItem* widget)
{
if (ui->hintLabel)
{
ui->hintLabel->deleteLater();
ui->hintLabel = NULL;
}
connect(widget, SIGNAL(editingFinished()), this, SLOT(storeWidgetsToSettings()));
connect(widget, SIGNAL(destroyed()), this, SLOT(widgetRemoved()));
toolLayout->addWidget(widget);
toolItemList.append(widget);
}
void QGCToolWidget::widgetRemoved()
{
// Do not dynamic cast or de-reference QObject, since object is either in destructor or may have already
// been destroyed.
QGCToolWidgetItem *widget = static_cast<QGCToolWidgetItem *>(QObject::sender());
toolItemList.removeAll(widget);
storeWidgetsToSettings();
}
void QGCToolWidget::exportWidget()
{
//-- Get file to save
QString fileName = QGCFileDialog::getSaveFileName(
this, tr("Save Widget File"),
QStandardPaths::writableLocation(QStandardPaths::DesktopLocation),
tr("QGroundControl Widget Files (*.qgw)"),
"qgw",
true);
//-- Save it if we have it
if (!fileName.isEmpty()) {
QSettings settings(fileName, QSettings::IniFormat);
storeSettings(settings);
}
}
void QGCToolWidget::importWidget()
{
QString fileName = QGCFileDialog::getOpenFileName(
this, tr("Load Widget File"), QStandardPaths::writableLocation(QStandardPaths::DesktopLocation),
tr("QGroundControl Widgets (*.qgw);;All Files (*)"));
if (!fileName.isEmpty()) {
// TODO There is no error checking. If the load fails, there is nothing telling the user what happened.
loadSettings(fileName);
}
}
QString QGCToolWidget::getTitle() const
{
return widgetTitle;
}
void QGCToolWidget::setTitle()
{
QDockWidget* parent = dynamic_cast<QDockWidget*>(this->parentWidget());
if (parent)
{
bool ok;
QString text = QInputDialog::getText(this, tr("Enter Widget Title"),
tr("Widget title:"), QLineEdit::Normal,
parent->windowTitle(), &ok);
if (ok && !text.isEmpty())
{
setTitle(text);
}
}
}
void QGCToolWidget::setTitle(const QString& title)
{
// Sets title and calls setWindowTitle on QWidget
widgetTitle = title;
QWidget::setWindowTitle(title);
QDockWidget* dock = dynamic_cast<QDockWidget*>(this->parentWidget());
if (dock)
dock->setWindowTitle(widgetTitle);
emit titleChanged(title);
if (mainMenuAction) mainMenuAction->setText(title);
//Do not save the settings here, because this function might be
//called while loading, and thus saving here could end up clobbering
//all of the other widgets
}
void QGCToolWidget::setMainMenuAction(QAction* action)
{
this->mainMenuAction = action;
}
void QGCToolWidget::deleteWidget()
{
// Remove from settings
// Hide
this->hide();
instances()->remove(objectName());
QSettings settings;
settings.beginGroup("QGC_MAINWINDOW");
settings.remove(QString("TOOL_PARENT_") + objectName());
settings.endGroup();
storeWidgetsToSettings();
// Delete
this->deleteLater();
}
#ifndef QGCTOOLWIDGET_H
#define QGCTOOLWIDGET_H
#include <QWidget>
#include <QAction>
#include <QMap>
#include <QVBoxLayout>
#include "QGCToolWidgetItem.h"
#include "UAS.h"
namespace Ui
{
class QGCToolWidget;
}
class QGCToolWidget : public QWidget
{
Q_OBJECT
public:
explicit QGCToolWidget(const QString& objectName, const QString& title, QWidget *parent = 0, QSettings* settings = 0);
~QGCToolWidget();
/** @brief Factory method to instantiate all tool widgets */
static QList<QGCToolWidget*> createWidgetsFromSettings(QWidget* parent, QString settingsFile=QString());
/** @Give the tool widget a reference to its action in the main menu */
void setMainMenuAction(QAction* action);
/** @brief All instances of this class */
static QMap<QString, QGCToolWidget*>* instances();
/** @brief Get title of widget */
QString getTitle() const;
int isVisible(int view) const { return viewVisible.value(view, false); }
Qt::DockWidgetArea getDockWidgetArea(int view) { return dockWidgetArea.value(view, Qt::BottomDockWidgetArea); }
void setParent(QWidget *parent);
/** @brief Store all widgets of this type to QSettings */
static void storeWidgetsToSettings(QSettings &settingsFile);
public slots:
void addUAS(UASInterface* uas);
/** @brief Delete this widget */
void deleteWidget();
/** @brief Export this widget to a file */
void exportWidget();
/** @brief Import settings for this widget from a file */
void importWidget();
/** @brief Store all widgets of this type to QSettings */
void storeWidgetsToSettings() { QSettings settings; QGCToolWidget::storeWidgetsToSettings(settings); }
void showLabel(QString name,int num);
public:
void loadSettings(QVariantMap& settings);
/** @brief Load this widget from a QSettings object */
void loadSettings(QSettings& settings);
/** @brief Load this widget from a settings file */
bool loadSettings(const QString& settings, bool singleinstance=false);
/** @brief Store the view id and dock widget area */
void setViewVisibilityAndDockWidgetArea(int view, bool visible, Qt::DockWidgetArea area);
void setSettings(QVariantMap& settings);
QList<QString> getParamList();
void setParameterValue(int uas, int component, QString parameterName, const QVariant value);
bool fromMetaData() const { return isFromMetaData; }
signals:
void titleChanged(const QString &title);
protected:
bool isFromMetaData;
QMap<QString,QGCToolWidgetItem*> paramToItemMap;
QList<QGCToolWidgetItem*> toolItemList;
QList<QString> paramList;
QVariantMap settingsMap;
QAction* addParamAction;
QAction* addCommandAction;
QAction* addPlotAction;
QAction* addLabelAction;
QAction* setTitleAction;
QAction* deleteAction;
QAction* exportAction;
QAction* importAction;
QVBoxLayout* toolLayout;
UAS* mav;
QAction* mainMenuAction; ///< Main menu action
QMap<int, Qt::DockWidgetArea> dockWidgetArea; ///< Dock widget area desired by this widget
QMap<int, bool> viewVisible; ///< Visibility in one view
QString widgetTitle;
void contextMenuEvent(QContextMenuEvent* event);
void createActions();
/** @brief Add an existing tool widget */
void addToolWidget(QGCToolWidgetItem* widget);
/** @brief Add an existing tool widget and set it to edit mode */
void addToolWidgetAndEdit(QGCToolWidgetItem* widget);
void hideEvent(QHideEvent* event);
public slots:
void setTitle(const QString &title);
void addParam(int uas,int component,QString paramname,QVariant value);
protected slots:
void addParam();
void addCommand();
void addPlot();
void addLabel();
void setTitle();
void widgetRemoved();
private:
/** Do not use this from outside the class to set the object name,
* because we cannot track changes to the object name, and the
* QObject::setObjectName() function is not virtual. Instead only
* pass in the object name to the constructor, or use the , then
* never change it again. */
void setObjectName(const QString &name) { QWidget::setObjectName(name); }
/** Helper for storeWidgetsToSettings() */
void storeSettings(QSettings& settings);
Ui::QGCToolWidget *ui;
};
#endif // QGCTOOLWIDGET_H
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<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>
<layout class="QVBoxLayout" name="toolLayout">
<property name="spacing">
<number>0</number>
</property>
<property name="leftMargin">
<number>6</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>6</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item>
<widget class="QLabel" name="hintLabel">
<property name="text">
<string>Right-click into the widget to customize</string>
</property>
</widget>
</item>
</layout>
</widget>
<resources/>
<connections/>
</ui>
#include <QMenu>
#include <QContextMenuEvent>
#include <QSettings>
#include <QTimer>
#include <QToolTip>
#include <QDebug>
#include "QGCToolWidgetComboBox.h"
#include "ui_QGCToolWidgetComboBox.h"
#include "UASInterface.h"
#include "UASManager.h"
QGCToolWidgetComboBox::QGCToolWidgetComboBox(QWidget *parent) :
QGCToolWidgetItem("Combo", parent),
parameterName(""),
parameterValue(0.0f),
parameterScalingFactor(0.0),
parameterMin(0.0f),
parameterMax(0.0f),
componentId(0),
ui(new Ui::QGCToolWidgetComboBox)
{
ui->setupUi(this);
uas = NULL;
ui->editInfoCheckBox->hide();
ui->editDoneButton->hide();
ui->editNameLabel->hide();
ui->editRefreshParamsButton->hide();
ui->editSelectParamComboBox->hide();
ui->editSelectComponentComboBox->hide();
ui->editStatusLabel->hide();
ui->editLine1->hide();
ui->editLine2->hide();
ui->editAddItemButton->hide();
ui->editRemoveItemButton->hide();
ui->editItemValueSpinBox->hide();
ui->editItemNameLabel->hide();
ui->itemValueLabel->hide();
ui->itemNameLabel->hide();
ui->infoLabel->hide();
ui->editOptionComboBox->setEnabled(false);
isDisabled = true;
connect(ui->editDoneButton, SIGNAL(clicked()), this, SLOT(endEditMode()));
connect(ui->editOptionComboBox,SIGNAL(currentIndexChanged(QString)),this,SLOT(comboBoxIndexChanged(QString)));
connect(ui->editAddItemButton,SIGNAL(clicked()),this,SLOT(addButtonClicked()));
connect(ui->editRemoveItemButton,SIGNAL(clicked()),this,SLOT(delButtonClicked()));
// Sending actions
connect(ui->writeButton, SIGNAL(clicked()), this, SLOT(setParamPending()));
connect(ui->editSelectComponentComboBox, SIGNAL(currentIndexChanged(int)), this, SLOT(selectComponent(int)));
connect(ui->editSelectParamComboBox, SIGNAL(currentIndexChanged(int)), this, SLOT(selectParameter(int)));
//connect(ui->valueSlider, SIGNAL(valueChanged(int)), this, SLOT(setSliderValue(int)));
//connect(ui->doubleValueSpinBox, SIGNAL(valueChanged(double)), this, SLOT(setParamValue(double)));
//connect(ui->intValueSpinBox, SIGNAL(valueChanged(int)), this, SLOT(setParamValue(int)));
connect(ui->editNameLabel, SIGNAL(textChanged(QString)), ui->nameLabel, SLOT(setText(QString)));
connect(ui->readButton, SIGNAL(clicked()), this, SLOT(requestParameter()));
connect(ui->editRefreshParamsButton, SIGNAL(clicked()), this, SLOT(refreshParameter()));
connect(ui->editInfoCheckBox, SIGNAL(clicked(bool)), this, SLOT(showInfo(bool)));
// connect to self
connect(ui->infoLabel, SIGNAL(released()), this, SLOT(showTooltip()));
init();
}
QGCToolWidgetComboBox::~QGCToolWidgetComboBox()
{
delete ui;
}
void QGCToolWidgetComboBox::showTooltip()
{
QWidget* sender = dynamic_cast<QWidget*>(QObject::sender());
if (sender)
{
QPoint point = mapToGlobal(ui->infoLabel->pos());
QToolTip::showText(point, sender->toolTip());
}
}
void QGCToolWidgetComboBox::refreshParameter()
{
ui->editSelectParamComboBox->setEnabled(true);
ui->editSelectComponentComboBox->setEnabled(true);
if (uas && !parameterName.isEmpty()) {
uas->getParamManager()->requestParameterUpdate(componentId,parameterName);
ui->editStatusLabel->setText(tr("Requesting refresh..."));
}
}
void QGCToolWidgetComboBox::setActiveUAS(UASInterface* activeUas)
{
if (activeUas)
{
if (uas)
{
disconnect(uas, SIGNAL(parameterChanged(int,int,int,int,QString,QVariant)), this, SLOT(setParameterValue(int,int,int,int,QString,QVariant)));
}
// Connect buttons and signals
connect(activeUas, SIGNAL(parameterChanged(int,int,int,int,QString,QVariant)), this, SLOT(setParameterValue(int,int,int,int,QString,QVariant)), Qt::UniqueConnection);
uas = activeUas;
paramMgr = uas->getParamManager();
// Update current param value
//requestParameter();
// Set param info
QString text = paramMgr->dataModel()->getParamDescription(parameterName);
if (!text.isEmpty()) {
ui->infoLabel->setToolTip(text);
ui->infoLabel->show();
}
// Force-uncheck and hide label if no description is available
if (ui->editInfoCheckBox->isChecked()) {
showInfo((text.length() > 0));
}
}
}
void QGCToolWidgetComboBox::requestParameter()
{
if (!parameterName.isEmpty() && uas)
{
paramMgr->requestParameterUpdate(this->componentId, this->parameterName);
}
}
void QGCToolWidgetComboBox::showInfo(bool enable)
{
ui->editInfoCheckBox->setChecked(enable);
ui->infoLabel->setVisible(enable);
}
void QGCToolWidgetComboBox::selectComponent(int componentIndex)
{
this->componentId = ui->editSelectComponentComboBox->itemData(componentIndex).toInt();
}
void QGCToolWidgetComboBox::selectParameter(int paramIndex)
{
// Set name
parameterName = ui->editSelectParamComboBox->itemText(paramIndex);
// Update min and max values if available
if (uas) {
UASParameterDataModel* dataModel = paramMgr->dataModel();
if (dataModel) {
// Minimum
if (dataModel->isParamMinKnown(parameterName)) {
parameterMin = dataModel->getParamMin(parameterName);
}
// Maximum
if (dataModel->isParamMaxKnown(parameterName)) {
parameterMax = dataModel->getParamMax(parameterName);
}
// Description
QString text = dataModel->getParamDescription(parameterName);
//ui->infoLabel->setText(text);
showInfo(!(text.length() > 0));
}
}
}
void QGCToolWidgetComboBox::setEditMode(bool editMode)
{
if(!editMode) {
// Store component id
selectComponent(ui->editSelectComponentComboBox->currentIndex());
// Store parameter name and id
selectParameter(ui->editSelectParamComboBox->currentIndex());
}
ui->nameLabel->setVisible(!editMode);
ui->writeButton->setVisible(!editMode);
ui->readButton->setVisible(!editMode);
ui->editInfoCheckBox->setVisible(editMode);
ui->editDoneButton->setVisible(editMode);
ui->editNameLabel->setVisible(editMode);
ui->editRefreshParamsButton->setVisible(editMode);
ui->editSelectParamComboBox->setVisible(editMode);
ui->editSelectComponentComboBox->setVisible(editMode);
ui->editStatusLabel->setVisible(editMode);
ui->writeButton->setVisible(!editMode);
ui->readButton->setVisible(!editMode);
ui->editLine1->setVisible(editMode);
ui->editLine2->setVisible(editMode);
ui->editAddItemButton->setVisible(editMode);
ui->editRemoveItemButton->setVisible(editMode);
ui->editItemValueSpinBox->setVisible(editMode);
ui->editItemNameLabel->setVisible(editMode);
ui->itemValueLabel->setVisible(editMode);
ui->itemNameLabel->setVisible(editMode);
if (isDisabled)
{
ui->editOptionComboBox->setEnabled(editMode);
}
QGCToolWidgetItem::setEditMode(editMode);
}
void QGCToolWidgetComboBox::setParamPending()
{
if (uas) {
uas->getParamManager()->setPendingParam(componentId, parameterName, parameterValue);
}
else {
qWarning() << __FILE__ << __LINE__ << "NO UAS SET, DOING NOTHING";
}
}
/**
* @brief uas Unmanned system sending the parameter
* @brief component UAS component sending the parameter
* @brief parameterName Key/name of the parameter
* @brief value Value of the parameter
*/
void QGCToolWidgetComboBox::setParameterValue(int uas, int component, int paramCount, int paramIndex, QString parameterName, QVariant value)
{
Q_UNUSED(paramCount);
// Check if this component and parameter are part of the list
bool found = false;
for (int i = 0; i< ui->editSelectComponentComboBox->count(); ++i)
{
if (component == ui->editSelectComponentComboBox->itemData(i).toInt())
{
found = true;
}
}
if (!found)
{
ui->editSelectComponentComboBox->addItem(tr("Component #%1").arg(component), component);
}
// Parameter checking
found = false;
for (int i = 0; i < ui->editSelectParamComboBox->count(); ++i)
{
if (parameterName == ui->editSelectParamComboBox->itemText(i))
{
found = true;
}
}
if (!found)
{
ui->editSelectParamComboBox->addItem(parameterName, paramIndex);
}
Q_UNUSED(uas);
//comboBoxTextToValMap[ui->editItemNameLabel->text()] = ui->editItemValueSpinBox->value();
if (visibleParam != "")
{
if (parameterName == visibleParam)
{
if (visibleVal == value.toInt())
{
this->uas->requestParameter(this->componentId,this->parameterName);
visibleEnabled = true;
this->show();
}
else
{
//Disable the component here.
//ui->valueSlider->setEnabled(false);
//ui->intValueSpinBox->setEnabled(false);
//ui->doubleValueSpinBox->setEnabled(false);
visibleEnabled = false;
this->hide();
}
}
}
if (component == this->componentId && parameterName == this->parameterName)
{
if (!visibleEnabled)
{
return;
}
ui->editOptionComboBox->setEnabled(true);
isDisabled = false;
for (int i=0;i<ui->editOptionComboBox->count();i++)
{
if (comboBoxTextToValMap[ui->editOptionComboBox->itemText(i)] == value.toInt())
{
ui->editOptionComboBox->setCurrentIndex(i);
break;
}
}
}
if (paramIndex == paramCount - 1)
{
ui->editStatusLabel->setText(tr("Complete parameter list received."));
}
}
void QGCToolWidgetComboBox::changeEvent(QEvent *e)
{
QWidget::changeEvent(e);
switch (e->type()) {
case QEvent::LanguageChange:
ui->retranslateUi(this);
break;
default:
break;
}
}
void QGCToolWidgetComboBox::writeSettings(QSettings& settings)
{
settings.setValue("TYPE", "COMBOBOX");
settings.setValue("QGC_PARAM_COMBOBOX_DESCRIPTION", ui->nameLabel->text());
//settings.setValue("QGC_PARAM_COMBOBOX_BUTTONTEXT", ui->actionButton->text());
settings.setValue("QGC_PARAM_COMBOBOX_PARAMID", parameterName);
settings.setValue("QGC_PARAM_COMBOBOX_COMPONENTID", componentId);
settings.setValue("QGC_PARAM_COMBOBOX_DISPLAY_INFO", ui->editInfoCheckBox->isChecked());
settings.setValue("QGC_PARAM_COMBOBOX_COUNT", ui->editOptionComboBox->count());
for (int i=0;i<ui->editOptionComboBox->count();i++)
{
settings.setValue("QGC_PARAM_COMBOBOX_ITEM_" + QString::number(i) + "_TEXT",ui->editOptionComboBox->itemText(i));
settings.setValue("QGC_PARAM_COMBOBOX_ITEM_" + QString::number(i) + "_VAL",comboBoxTextToValMap[ui->editOptionComboBox->itemText(i)]);
}
settings.sync();
}
void QGCToolWidgetComboBox::readSettings(const QString& pre,const QVariantMap& settings)
{
parameterName = settings.value(pre + "QGC_PARAM_COMBOBOX_PARAMID").toString();
componentId = settings.value(pre + "QGC_PARAM_COMBOBOX_COMPONENTID").toInt();
ui->nameLabel->setText(settings.value(pre + "QGC_PARAM_COMBOBOX_DESCRIPTION").toString());
ui->editNameLabel->setText(settings.value(pre + "QGC_PARAM_COMBOBOX_DESCRIPTION").toString());
//settings.setValue("QGC_PARAM_SLIDER_BUTTONTEXT", ui->actionButton->text());
ui->editSelectParamComboBox->addItem(settings.value(pre + "QGC_PARAM_COMBOBOX_PARAMID").toString());
ui->editSelectParamComboBox->setCurrentIndex(ui->editSelectParamComboBox->count()-1);
ui->editSelectComponentComboBox->addItem(tr("Component #%1").arg(settings.value(pre + "QGC_PARAM_COMBOBOX_COMPONENTID").toInt()), settings.value(pre + "QGC_PARAM_COMBOBOX_COMPONENTID").toInt());
showInfo(settings.value(pre + "QGC_PARAM_COMBOBOX_DISPLAY_INFO", true).toBool());
ui->editSelectParamComboBox->setEnabled(true);
ui->editSelectComponentComboBox->setEnabled(true);
visibleParam = settings.value(pre+"QGC_PARAM_COMBOBOX_VISIBLE_PARAM","").toString();
visibleVal = settings.value(pre+"QGC_PARAM_COMBOBOX_VISIBLE_VAL",0).toInt();
QString type = settings.value(pre + "QGC_PARAM_COMBOBOX_TYPE","PARAM").toString();
int num = settings.value(pre + "QGC_PARAM_COMBOBOX_COUNT").toInt();
for (int i=0;i<num;i++)
{
QString pixmapfn = settings.value(pre + "QGC_PARAM_COMBOBOX_ITEM_" + QString::number(i) + "_IMG","").toString();
if (pixmapfn != "")
{
comboBoxIndexToPixmap[i] = QPixmap(pixmapfn);
}
ui->editOptionComboBox->addItem(settings.value(pre + "QGC_PARAM_COMBOBOX_ITEM_" + QString::number(i) + "_TEXT").toString());
//qDebug() << "Adding val:" << settings.value(pre + "QGC_PARAM_COMBOBOX_ITEM_" + QString::number(i) + "_TEXT").toString() << settings.value(pre + "QGC_PARAM_COMBOBOX_ITEM_" + QString::number(i) + "_VAL").toInt();
comboBoxTextToValMap[settings.value(pre + "QGC_PARAM_COMBOBOX_ITEM_" + QString::number(i) + "_TEXT").toString()] = settings.value(pre + "QGC_PARAM_COMBOBOX_ITEM_" + QString::number(i) + "_VAL").toInt();
if (type == "INDIVIDUAL")
{
comboBoxTextToParamMap[settings.value(pre + "QGC_PARAM_COMBOBOX_ITEM_" + QString::number(i) + "_TEXT").toString()] = settings.value(pre + "QGC_PARAM_COMBOBOX_ITEM_" + QString::number(i) + "_PARAM").toString();
ui->editOptionComboBox->setEnabled(true);
}
}
setActiveUAS(UASManager::instance()->getActiveUAS());
// Get param value after settings have been loaded
// requestParameter();
}
void QGCToolWidgetComboBox::readSettings(const QSettings& settings)
{
QVariantMap map;
foreach (QString key,settings.allKeys())
{
map[key] = settings.value(key);
}
readSettings("",map);
//parameterName = settings.value("QGC_PARAM_COMBOBOX_PARAMID").toString();
//component = settings.value("QGC_PARAM_COMBOBOX_COMPONENTID").toInt();
//ui->nameLabel->setText(settings.value("QGC_PARAM_COMBOBOX_DESCRIPTION").toString());
//ui->editNameLabel->setText(settings.value("QGC_PARAM_COMBOBOX_DESCRIPTION").toString());
//ui->editSelectParamComboBox->addItem(settings.value("QGC_PARAM_COMBOBOX_PARAMID").toString());
//ui->editSelectParamComboBox->setCurrentIndex(ui->editSelectParamComboBox->count()-1);
//ui->editSelectComponentComboBox->addItem(tr("Component #%1").arg(settings.value("QGC_PARAM_COMBOBOX_COMPONENTID").toInt()), settings.value("QGC_PARAM_COMBOBOX_COMPONENTID").toInt());
//showInfo(settings.value("QGC_PARAM_COMBOBOX_DISPLAY_INFO", true).toBool());
//ui->editSelectParamComboBox->setEnabled(true);
//ui->editSelectComponentComboBox->setEnabled(true);
/*int num = settings.value("QGC_PARAM_COMBOBOX_COUNT").toInt();
for (int i=0;i<num;i++)
{
QString pixmapfn = settings.value("QGC_PARAM_COMBOBOX_ITEM_" + QString::number(i) + "_IMG","").toString();
if (pixmapfn != "")
{
comboBoxIndexToPixmap[i] = QPixmap(pixmapfn);
}
ui->editOptionComboBox->addItem(settings.value("QGC_PARAM_COMBOBOX_ITEM_" + QString::number(i) + "_TEXT").toString());
qDebug() << "Adding val:" << settings.value("QGC_PARAM_COMBOBOX_ITEM_" + QString::number(i)).toString() << settings.value("QGC_PARAM_COMBOBOX_ITEM_" + QString::number(i) + "_VAL").toInt();
comboBoxTextToValMap[settings.value("QGC_PARAM_COMBOBOX_ITEM_" + QString::number(i) + "_TEXT").toString()] = settings.value("QGC_PARAM_COMBOBOX_ITEM_" + QString::number(i) + "_VAL").toInt();
}*/
//setActiveUAS(UASManager::instance()->getActiveUAS());*/
// Get param value after settings have been loaded
//requestParameter();
}
void QGCToolWidgetComboBox::addButtonClicked()
{
ui->editOptionComboBox->addItem(ui->editItemNameLabel->text());
comboBoxTextToValMap[ui->editItemNameLabel->text()] = ui->editItemValueSpinBox->value();
}
void QGCToolWidgetComboBox::delButtonClicked()
{
int index = ui->editOptionComboBox->currentIndex();
comboBoxTextToValMap.remove(ui->editOptionComboBox->currentText());
ui->editOptionComboBox->removeItem(index);
}
void QGCToolWidgetComboBox::comboBoxIndexChanged(QString val)
{
ui->imageLabel->setPixmap(comboBoxIndexToPixmap[ui->editOptionComboBox->currentIndex()]);
if (comboBoxTextToParamMap.contains(ui->editOptionComboBox->currentText()))
{
parameterName = comboBoxTextToParamMap.value(ui->editOptionComboBox->currentText());
}
switch (static_cast<int>(parameterValue.type()))
{
case QVariant::Char:
parameterValue = QVariant(QChar((unsigned char)comboBoxTextToValMap[val]));
break;
case QVariant::Int:
parameterValue = (int)comboBoxTextToValMap[val];
break;
case QVariant::UInt:
parameterValue = (unsigned int)comboBoxTextToValMap[val];
break;
case QMetaType::Float:
parameterValue =(float)comboBoxTextToValMap[val];
break;
default:
qCritical() << "ERROR: NO VALID PARAM TYPE";
return;
}
}
#ifndef QGCToolWidgetComboBox_H
#define QGCToolWidgetComboBox_H
#include <QWidget>
#include <QAction>
#ifndef __android__
#include <QtDesigner/QDesignerExportWidget>
#endif
#include "QGCToolWidgetItem.h"
class QGCUASParamManagerInterface;
namespace Ui
{
class QGCToolWidgetComboBox;
}
class QGCToolWidgetComboBox : public QGCToolWidgetItem
{
Q_OBJECT
public:
explicit QGCToolWidgetComboBox(QWidget *parent = 0);
~QGCToolWidgetComboBox();
virtual void setEditMode(bool editMode);
public slots:
/** @brief Queue parameter for sending to the MAV (add to pending list)*/
void setParamPending();
/** @brief Update the UI with the new parameter value */
void setParameterValue(int uas, int componentId, int paramCount, int paramIndex, QString parameterName, const QVariant value);
void writeSettings(QSettings& settings);
void readSettings(const QString& pre,const QVariantMap& settings);
void readSettings(const QSettings& settings);
/** @brief request that the parameter for this widget be refreshed */
void refreshParameter();
void setActiveUAS(UASInterface *uas);
void selectComponent(int componentIndex);
void selectParameter(int paramIndex);
/** @brief Show descriptive text next to slider */
void showInfo(bool enable);
/** @brief Show tool tip of calling element */
void showTooltip();
protected slots:
/** @brief Request the parameter of this widget from the MAV */
void requestParameter();
/** @brief Button click to add a new item to the combobox */
void addButtonClicked();
/** @brief Button click to remove the currently selected item from the combobox */
void delButtonClicked();
/** @brief Updates current parameter based on new combobox value */
void comboBoxIndexChanged(QString val);
protected:
QGCUASParamManagerInterface *paramMgr; ///< Access to parameter manager
bool visibleEnabled;
QString visibleParam;
int visibleVal;
QMap<QString,QString> comboBoxTextToParamMap;
QMap<int,QPixmap> comboBoxIndexToPixmap;
QMap<QString,int> comboBoxTextToValMap; ///< Comboboxtext/parameter value map
QString parameterName; ///< Key/Name of the parameter
QVariant parameterValue; ///< Value of the parameter
double parameterScalingFactor; ///< Factor to scale the parameter between slider and true value
float parameterMin;
bool isDisabled;
float parameterMax;
int componentId; ///< ID of the MAV component to address
//double scaledInt;
void changeEvent(QEvent *e);
private:
Ui::QGCToolWidgetComboBox *ui;
};
#endif // QGCToolWidgetComboBox_H
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>QGCToolWidgetComboBox</class>
<widget class="QWidget" name="QGCToolWidgetComboBox">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>789</width>
<height>244</height>
</rect>
</property>
<property name="windowTitle">
<string>Form</string>
</property>
<property name="layoutDirection">
<enum>Qt::LeftToRight</enum>
</property>
<layout class="QGridLayout" name="gridLayout" columnstretch="10,0,0,0,0,0,0,0,0,0,0,0">
<property name="leftMargin">
<number>6</number>
</property>
<property name="topMargin">
<number>3</number>
</property>
<property name="rightMargin">
<number>6</number>
</property>
<property name="bottomMargin">
<number>3</number>
</property>
<property name="horizontalSpacing">
<number>6</number>
</property>
<property name="verticalSpacing">
<number>12</number>
</property>
<item row="4" column="7">
<widget class="QLabel" name="nameLabel">
<property name="minimumSize">
<size>
<width>60</width>
<height>0</height>
</size>
</property>
<property name="text">
<string>Name</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
</widget>
</item>
<item row="4" column="8">
<widget class="QToolButton" name="infoLabel">
<property name="layoutDirection">
<enum>Qt::LeftToRight</enum>
</property>
<property name="text">
<string>?</string>
</property>
<property name="popupMode">
<enum>QToolButton::DelayedPopup</enum>
</property>
<property name="toolButtonStyle">
<enum>Qt::ToolButtonIconOnly</enum>
</property>
<property name="autoRaise">
<bool>false</bool>
</property>
<property name="arrowType">
<enum>Qt::NoArrow</enum>
</property>
</widget>
</item>
<item row="1" column="9">
<widget class="QLineEdit" name="editNameLabel">
<property name="placeholderText">
<string>Parameter Name</string>
</property>
</widget>
</item>
<item row="7" column="9">
<widget class="QLineEdit" name="editItemNameLabel"/>
</item>
<item row="7" column="7">
<widget class="QSpinBox" name="editItemValueSpinBox"/>
</item>
<item row="4" column="9">
<widget class="QComboBox" name="editOptionComboBox"/>
</item>
<item row="7" column="8">
<widget class="QLabel" name="itemNameLabel">
<property name="text">
<string>Name</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
</widget>
</item>
<item row="8" column="8">
<widget class="QComboBox" name="editSelectComponentComboBox">
<property name="enabled">
<bool>false</bool>
</property>
<property name="toolTip">
<string>Select component</string>
</property>
<property name="statusTip">
<string>Select component</string>
</property>
</widget>
</item>
<item row="7" column="10">
<widget class="QPushButton" name="editAddItemButton">
<property name="text">
<string>Add Item</string>
</property>
</widget>
</item>
<item row="7" column="11">
<widget class="QPushButton" name="editRemoveItemButton">
<property name="text">
<string>Delete Item</string>
</property>
</widget>
</item>
<item row="7" column="6">
<widget class="QLabel" name="itemValueLabel">
<property name="text">
<string>Value</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
</widget>
</item>
<item row="8" column="9">
<widget class="QComboBox" name="editSelectParamComboBox">
<property name="enabled">
<bool>false</bool>
</property>
<property name="toolTip">
<string>Select parameter</string>
</property>
<property name="statusTip">
<string>Select parameter</string>
</property>
</widget>
</item>
<item row="0" column="0" colspan="12">
<widget class="Line" name="editLine1">
<property name="minimumSize">
<size>
<width>0</width>
<height>0</height>
</size>
</property>
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
</widget>
</item>
<item row="4" column="11">
<widget class="QPushButton" name="readButton">
<property name="minimumSize">
<size>
<width>0</width>
<height>0</height>
</size>
</property>
<property name="toolTip">
<string>Read the current parameter value on the system</string>
</property>
<property name="statusTip">
<string>Read the current parameter value on the system</string>
</property>
<property name="text">
<string>Get</string>
</property>
</widget>
</item>
<item row="11" column="11">
<widget class="QPushButton" name="editDoneButton">
<property name="text">
<string>Done</string>
</property>
</widget>
</item>
<item row="4" column="10">
<widget class="QPushButton" name="writeButton">
<property name="minimumSize">
<size>
<width>0</width>
<height>0</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>16777215</width>
<height>16777215</height>
</size>
</property>
<property name="toolTip">
<string>Transmit the current slider value to the system</string>
</property>
<property name="statusTip">
<string>Transmit the current slider value to the system</string>
</property>
<property name="text">
<string>Set</string>
</property>
</widget>
</item>
<item row="8" column="10">
<widget class="QCheckBox" name="editInfoCheckBox">
<property name="text">
<string>Show Info</string>
</property>
<property name="checked">
<bool>true</bool>
</property>
</widget>
</item>
<item row="13" column="0" colspan="12">
<widget class="Line" name="editLine2">
<property name="minimumSize">
<size>
<width>0</width>
<height>0</height>
</size>
</property>
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
</widget>
</item>
<item row="12" column="2" colspan="10">
<spacer name="verticalSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
</size>
</property>
</spacer>
</item>
<item row="4" column="0" colspan="3">
<spacer name="horizontalSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>0</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item row="11" column="3" colspan="7">
<widget class="QLabel" name="editStatusLabel">
<property name="text">
<string>Please click first on refresh to update selection menus..</string>
</property>
</widget>
</item>
<item row="8" column="11">
<widget class="QPushButton" name="editRefreshParamsButton">
<property name="enabled">
<bool>true</bool>
</property>
<property name="text">
<string>Refresh</string>
</property>
</widget>
</item>
<item row="3" column="0" colspan="12">
<widget class="QLabel" name="imageLabel">
<property name="maximumSize">
<size>
<width>16777215</width>
<height>150</height>
</size>
</property>
<property name="text">
<string/>
</property>
<property name="scaledContents">
<bool>true</bool>
</property>
</widget>
</item>
</layout>
</widget>
<resources/>
<connections/>
</ui>
#include "QGCToolWidgetItem.h"
#include <QMenu>
#include <QContextMenuEvent>
#include "QGCToolWidget.h"
#include "UASManager.h"
#include <QDockWidget>
QGCToolWidgetItem::QGCToolWidgetItem(const QString& name, QWidget *parent) :
QWidget(parent),
uas(NULL),
isInEditMode(false),
qgcToolWidgetItemName(name),
_component(-1)
{
startEditAction = new QAction(tr("Edit %1").arg(qgcToolWidgetItemName), this);
stopEditAction = new QAction(tr("Finish Editing %1").arg(qgcToolWidgetItemName), this);
deleteAction = new QAction(tr("Delete %1").arg(qgcToolWidgetItemName), this);
}
void QGCToolWidgetItem::init()
{
connect(startEditAction, SIGNAL(triggered()), this, SLOT(startEditMode()));
connect(stopEditAction, SIGNAL(triggered()), this, SLOT(endEditMode()));
connect(deleteAction, SIGNAL(triggered()), this, SLOT(deleteLater()));
connect(UASManager::instance(), SIGNAL(activeUASSet(UASInterface*)),
this, SLOT(setActiveUAS(UASInterface*)));
// Set first UAS if it exists
setActiveUAS(UASManager::instance()->getActiveUAS());
}
QGCToolWidgetItem::~QGCToolWidgetItem()
{
delete startEditAction;
delete stopEditAction;
delete deleteAction;
}
void QGCToolWidgetItem::contextMenuEvent (QContextMenuEvent* event)
{
QMenu menu(this);
if (!isInEditMode) {
menu.addAction(startEditAction);
menu.addAction(deleteAction);
} else {
menu.addAction(stopEditAction);
}
menu.exec(event->globalPos());
}
void QGCToolWidgetItem::setActiveUAS(UASInterface *uas)
{
this->uas = uas;
}
void QGCToolWidgetItem::setEditMode(bool editMode)
{
isInEditMode = editMode;
// Attempt to undock the dock widget
QWidget* p = this;
QDockWidget* dock;
do {
p = p->parentWidget();
dock = dynamic_cast<QDockWidget*>(p);
if (dock)
{
dock->setFloating(editMode);
break;
}
} while (p && !dock);
emit editingFinished();
}
#ifndef QGCTOOLWIDGETITEM_H
#define QGCTOOLWIDGETITEM_H
#include <QWidget>
#include <QAction>
#include <QSettings>
#include "UASInterface.h"
class QGCToolWidgetItem : public QWidget
{
Q_OBJECT
public:
QGCToolWidgetItem(const QString& name, QWidget *parent = 0);
~QGCToolWidgetItem();
int componentId() {
return _component;
}
virtual void setEditMode(bool editMode);
bool isEditMode() const { return isInEditMode; }
public slots:
void startEditMode() { setEditMode(true); }
void endEditMode() { setEditMode(false); }
virtual void setComponent(int comp) {
_component = comp;
}
virtual void writeSettings(QSettings& settings) = 0;
virtual void readSettings(const QSettings& settings) = 0;
virtual void readSettings(const QString& pre,const QVariantMap& settings) = 0;
virtual void setActiveUAS(UASInterface *uas);
signals:
void editingFinished();
protected:
void contextMenuEvent (QContextMenuEvent* event);
void init();
UASInterface* uas;
private:
QAction* startEditAction;
QAction* stopEditAction;
QAction* deleteAction;
bool isInEditMode;
QString qgcToolWidgetItemName;
int _component; ///< The MAV component (the process or device ID)
};
#endif // QGCTOOLWIDGETITEM_H
#include <QDockWidget>
#include "QGCXYPlot.h"
#include "ui_QGCXYPlot.h"
#include "MAVLinkProtocol.h"
#include "UASManager.h"
#include "IncrementalPlot.h"
#include "QGCApplication.h"
#include <float.h>
#include <qwt_plot.h>
#include <qwt_plot_layout.h>
#include <qwt_scale_engine.h>
class XYPlotCurve : public QwtPlotItem
{
public:
XYPlotCurve() {
m_maxStorePoints = 10000;
m_maxShowPoints = 15;
setItemAttribute(QwtPlotItem::AutoScale);
minMaxSet = false;
m_color = Qt::white;
m_smoothPoints = 1;
m_startIndex = -1; //Disable
}
void setMaxDataStorePoints(int max) { m_maxStorePoints = max; itemChanged(); }
void setMaxDataShowPoints(int max) { m_maxShowPoints = max; itemChanged(); }
void setSmoothPoints(int smoothPoints) { m_smoothPoints = smoothPoints; itemChanged(); }
int maxDataStorePoints() const { return m_maxStorePoints; }
int maxDataShowPoints() const { return m_maxShowPoints; }
int smoothPoints() const { return m_smoothPoints; }
/** Append data, returning the number of removed items */
int appendData(const QPointF &data) {
m_data.append(data);
int removed = 0;
while (m_data.size() > m_maxShowPoints) {
++removed;
m_data.removeFirst();
}
if (!minMaxSet) {
xmin = xmax = data.x();
ymin = ymax = data.y();
minMaxSet = true;
previousTime =xmin;
} else if (m_autoScale) {
if (m_autoScaleTime) {
xmin += removed * (data.x() - previousTime);
previousTime = data.x();
} else {
xmin = qMin(qreal(xmin), data.x());
}
xmax = qMax(qreal(xmax), data.x());
ymin = qMin(qreal(ymin), data.y());
ymax = qMax(qreal(ymax), data.y());
}
itemChanged();
return removed;
}
void clear() {
minMaxSet = false;
m_data.clear();
itemChanged();
}
void setColor(const QColor &color) {
m_color = color;
}
void setTimeSerie(bool state) {
clear();
m_autoScaleTime = state;
}
void unsetMinMax() {
if(m_autoScale)
return;
m_autoScale = true;
//Recalculate the automatic scale
if(m_data.isEmpty())
minMaxSet = false;
else {
minMaxSet = true;
previousTime = xmax = xmin = m_data.at(0).x();
ymax = ymin = m_data.at(0).y();
for(int i = 1; i < m_data.size(); i++) {
xmin = qMin(qreal(xmin), m_data.at(i).x());
xmax = qMax(qreal(xmax), m_data.at(i).x());
ymin = qMin(qreal(ymin), m_data.at(i).y());
ymax = qMax(qreal(ymax), m_data.at(i).y());
}
}
}
void setMinMax(double xmin, double xmax, double ymin, double ymax )
{
this->xmin = xmin;
this->xmax = xmax;
this->ymin = ymin;
this->ymax = ymax;
m_autoScale = false;
minMaxSet = true;
itemChanged();
}
void setStartIndex(int time) { /** Set to -1 to just use latest */
m_startIndex = time;
itemChanged();
}
int dataSize() const { return m_data.size(); }
double xMin() const { return xmin; }
double xMax() const { return xmax; }
double yMin() const { return ymin; }
double yMax() const { return ymax; }
virtual QRectF boundingRect() const {
if(!minMaxSet)
return QRectF(1,1,-2,-2);
return QRectF(xmin,ymin,xmax-xmin,ymax-ymin);
}
/* From QwtPlotItem. Draw the complete series */
virtual void draw (QPainter *p, const QwtScaleMap &xMap, const QwtScaleMap &yMap, const QRectF &canvasRect) const
{
Q_UNUSED(canvasRect);
QPointF lastPoint;
if(m_data.isEmpty())
return;
QPointF smoothTotal(0,0);
int smoothCount = 0;
int start;
int count;
if(m_startIndex >= 0) {
int end = qMin(m_startIndex, m_data.size()-1);
start = qBound(0, end - m_maxShowPoints, m_data.size()-1);
count = end - start;
} else {
start = qMax(0,m_data.size() - m_maxShowPoints);
count = qMin(m_data.size()-start, m_maxShowPoints);
}
for(int i = qMax(0,start - m_smoothPoints); i < start; ++i) {
smoothTotal += m_data.at(i);
++smoothCount;
}
for(int i = 0; i < count; ++i) {
QPointF point = m_data.at(i+start);
if(m_smoothPoints > 1) {
smoothTotal += point;
if(smoothCount >= m_smoothPoints) {
Q_ASSERT(i + start - m_smoothPoints >= 0);
smoothTotal -= m_data.at(i + start - m_smoothPoints);
} else
++smoothCount;
point = smoothTotal/smoothCount;
}
QPointF paintCoord = QPointF(xMap.transform(point.x()), yMap.transform(point.y()));
m_color.setAlpha((m_maxShowPoints - count + i)*255/m_maxShowPoints);
p->setPen(m_color);
if(i != 0)
p->drawLine(lastPoint, paintCoord);
if(i == count-1) {
//Draw marker for first point
const int marker_radius = 2;
QRectF marker = QRectF(paintCoord.x()-marker_radius, paintCoord.y()-marker_radius, marker_radius*2+1,marker_radius*2+1);
p->fillRect(marker,QBrush(m_color));
}
lastPoint = paintCoord;
}
}
private:
QList< QPointF > m_data;
int m_maxStorePoints;
int m_maxShowPoints;
int m_smoothPoints; /** Number of points to average across */
mutable QColor m_color;
double previousTime;
double xmin;
double xmax;
double ymin;
double ymax;
bool minMaxSet;
bool m_autoScale;
bool m_autoScaleTime;
int m_startIndex;
};
QGCXYPlot::QGCXYPlot(QWidget *parent) :
QGCToolWidgetItem("XY Plot", parent),
ui(new Ui::QGCXYPlot),
plot(0),
xycurve(0),
x(0),
x_timestamp_us(0),
x_valid(false),
y(0),
y_timestamp_us(0),
y_valid(false),
max_timestamp_diff_us(10000) /* Default to 10ms tolerance between x and y values */
{
uas = 0;
ui->setupUi(this);
plot = new QwtPlot();
ui->xyPlotLayout->addWidget(plot);
connect(ui->editFinishButton, SIGNAL(clicked()), this, SLOT(endEditMode()));
connect(MainWindow::instance(), SIGNAL(valueChanged(int,QString,QString,QVariant,quint64)),
this, SLOT(appendData(int,QString,QString,QVariant,quint64)));
connect(ui->editXParam, SIGNAL(editTextChanged(QString)), this, SLOT(clearPlot()));
connect(ui->editYParam, SIGNAL(editTextChanged(QString)), this, SLOT(clearPlot()));
plot->plotLayout()->setAlignCanvasToScales(true);
QwtLinearScaleEngine* yScaleEngine = new QwtLinearScaleEngine();
plot->setAxisScaleEngine(QwtPlot::yLeft, yScaleEngine);
plot->setAxisAutoScale(QwtPlot::xBottom);
plot->setAxisAutoScale(QwtPlot::yLeft);
plot->setAutoReplot();
xycurve = new XYPlotCurve();
xycurve->attach(plot);
styleChanged(qgcApp()->styleIsDark());
connect(qgcApp(), &QGCApplication::styleChanged, this, &QGCXYPlot::styleChanged);
connect(ui->minX, SIGNAL(valueChanged(double)),this, SLOT(updateMinMaxSettings()));
connect(ui->maxX, SIGNAL(valueChanged(double)),this, SLOT(updateMinMaxSettings()));
connect(ui->minY, SIGNAL(valueChanged(double)),this, SLOT(updateMinMaxSettings()));
connect(ui->maxY, SIGNAL(valueChanged(double)),this, SLOT(updateMinMaxSettings()));
connect(ui->automaticAxisRange, SIGNAL(toggled(bool)),this, SLOT(updateMinMaxSettings()));
connect(ui->timeAxisRange, SIGNAL(toggled(bool)),this, SLOT(setTimeAxis()));
connect(ui->maxDataShowSpinBox, SIGNAL(valueChanged(int)),this, SLOT(updateMinMaxSettings()));
connect(ui->maxDataStoreSpinBox, SIGNAL(valueChanged(int)),this, SLOT(updateMinMaxSettings()));
connect(ui->smoothSpinBox, SIGNAL(valueChanged(int)),this, SLOT(updateMinMaxSettings()));
setEditMode(false);
}
QGCXYPlot::~QGCXYPlot()
{
delete ui;
}
void QGCXYPlot::clearPlot()
{
xycurve->clear();
plot->detachItems();
ui->timeScrollBar->setMaximum(xycurve->dataSize());
ui->timeScrollBar->setValue(ui->timeScrollBar->maximum());
}
void QGCXYPlot::setEditMode(bool editMode)
{
ui->lblXParam->setVisible(editMode);
ui->lblYParam->setVisible(editMode);
ui->editXParam->setVisible(editMode);
ui->editYParam->setVisible(editMode);
ui->editFinishButton->setVisible(editMode);
ui->editLine1->setVisible(editMode);
ui->editLine2->setVisible(editMode);
ui->lblMaxDataStore->setVisible(editMode);
ui->lblMaxDataShow->setVisible(editMode);
ui->lblMaxX->setVisible(editMode);
ui->lblMaxY->setVisible(editMode);
ui->lblMinX->setVisible(editMode);
ui->lblMinY->setVisible(editMode);
ui->maxX->setVisible(editMode);
ui->maxY->setVisible(editMode);
ui->minX->setVisible(editMode);
ui->minY->setVisible(editMode);
ui->maxDataShowSpinBox->setVisible(editMode);
ui->maxDataStoreSpinBox->setVisible(editMode);
ui->automaticAxisRange->setVisible(editMode);
ui->timeAxisRange->setVisible(editMode);
ui->lblSmooth->setVisible(editMode);
ui->smoothSpinBox->setVisible(editMode);
if(!editMode) {
plot->setAxisTitle(QwtPlot::xBottom, ui->editXParam->currentText());
plot->setAxisTitle(QwtPlot::yLeft, ui->editYParam->currentText());
}
QGCToolWidgetItem::setEditMode(editMode);
updateMinMaxSettings(); //Do this after calling the parent
}
void QGCXYPlot::writeSettings(QSettings& settings)
{
settings.setValue("TYPE", "XYPLOT");
settings.setValue("QGC_XYPLOT_X", ui->editXParam->currentText());
settings.setValue("QGC_XYPLOT_Y", ui->editYParam->currentText());
settings.setValue("QGC_XYPLOT_MINX", ui->minX->value());
settings.setValue("QGC_XYPLOT_MAXX", ui->maxX->value());
settings.setValue("QGC_XYPLOT_MINY", ui->minY->value());
settings.setValue("QGC_XYPLOT_MAXY", ui->maxY->value());
settings.setValue("QGC_XYPLOT_MAXDATA_STORE", ui->maxDataStoreSpinBox->value());
settings.setValue("QGC_XYPLOT_MAXDATA_SHOW", ui->maxDataShowSpinBox->value());
settings.setValue("QGC_XYPLOT_AUTO", ui->automaticAxisRange->isChecked());
settings.setValue("QGC_XYPLOT_SMOOTH", ui->smoothSpinBox->value());
settings.setValue("QGC_XYPLOT_TIME", ui->timeAxisRange->isChecked());
settings.sync();
}
void QGCXYPlot::readSettings(const QString& pre,const QVariantMap& settings)
{
ui->editXParam->setEditText(settings.value(pre + "QGC_XYPLOT_X", "").toString());
ui->editYParam->setEditText(settings.value(pre + "QGC_XYPLOT_Y", "").toString());
ui->automaticAxisRange->setChecked(settings.value(pre + "QGC_XYPLOT_AUTO", true).toBool());
ui->minX->setValue(settings.value(pre + "QGC_XYPLOT_MINX", 0).toDouble());
ui->maxX->setValue(settings.value(pre + "QGC_XYPLOT_MAXX", 0).toDouble());
ui->minY->setValue(settings.value(pre + "QGC_XYPLOT_MINY", 0).toDouble());
ui->maxY->setValue(settings.value(pre + "QGC_XYPLOT_MAXY", 0).toDouble());
ui->maxDataStoreSpinBox->setValue(settings.value(pre + "QGC_XYPLOT_MAXDATA_STORE", 10000).toInt());
ui->maxDataShowSpinBox->setValue(settings.value(pre + "QGC_XYPLOT_MAXDATA_SHOW", 15).toInt());
ui->smoothSpinBox->setValue(settings.value(pre + "QGC_XYPLOT_SMOOTH", 1).toInt());
ui->timeAxisRange->setChecked(settings.value(pre + "QGC_XYPLOT_TIME", true).toBool());
plot->setAxisTitle(QwtPlot::xBottom, ui->editXParam->currentText());
plot->setAxisTitle(QwtPlot::yLeft, ui->editYParam->currentText());
updateMinMaxSettings();
}
void QGCXYPlot::readSettings(const QSettings& settings)
{
ui->editXParam->setEditText(settings.value("QGC_XYPLOT_X", "").toString());
ui->editYParam->setEditText(settings.value("QGC_XYPLOT_Y", "").toString());
ui->automaticAxisRange->setChecked(settings.value("QGC_XYPLOT_AUTO", true).toBool());
ui->minX->setValue(settings.value("QGC_XYPLOT_MINX", 0).toDouble());
ui->maxX->setValue(settings.value("QGC_XYPLOT_MAXX", 0).toDouble());
ui->minY->setValue(settings.value("QGC_XYPLOT_MINY", 0).toDouble());
ui->maxY->setValue(settings.value("QGC_XYPLOT_MAXY", 0).toDouble());
ui->maxDataStoreSpinBox->setValue(settings.value("QGC_XYPLOT_MAXDATA_STORE", 10000).toInt());
ui->maxDataShowSpinBox->setValue(settings.value("QGC_XYPLOT_MAXDATA_SHOW", 15).toInt());
ui->smoothSpinBox->setValue(settings.value("QGC_XYPLOT_SMOOTH", 1).toInt());
ui->timeAxisRange->setChecked(settings.value("QGC_XYPLOT_TIME", true).toBool());
plot->setAxisTitle(QwtPlot::xBottom, ui->editXParam->currentText());
plot->setAxisTitle(QwtPlot::yLeft, ui->editYParam->currentText());
updateMinMaxSettings();
}
void QGCXYPlot::appendData(int uasId, const QString& curve, const QString& unit, const QVariant& variant, quint64 usec)
{
Q_UNUSED(uasId);
Q_UNUSED(unit);
if(isEditMode()) {
//When in edit mode, add all the items to the combo box
if(ui->editXParam->findText(curve) == -1) {
ui->editXParam->blockSignals(true);
ui->editYParam->blockSignals(true);
QString oldX = ui->editXParam->currentText();
QString oldY = ui->editYParam->currentText();
ui->editXParam->addItem(curve); //Annoyingly this can wipe out the current text
ui->editYParam->addItem(curve);
ui->editXParam->setEditText(oldX);
ui->editYParam->setEditText(oldY);
ui->editXParam->blockSignals(false);
ui->editYParam->blockSignals(false);
}
}
if(ui->stopStartButton->isChecked())
return;
bool ok;
if(curve == ui->editXParam->currentText()) {
x = variant.toDouble(&ok);
if(!ok)
return;
x_timestamp_us = usec;
x_valid = true;
} else if(curve == ui->editYParam->currentText()) {
y = variant.toDouble(&ok);
if(!ok)
return;
y_timestamp_us = usec;
y_valid = true;
} else
return;
if(x_valid && y_valid) {
quint64 difference;
if (y_timestamp_us < x_timestamp_us) {
difference = x_timestamp_us - y_timestamp_us;
} else {
difference = y_timestamp_us - x_timestamp_us;
}
if (difference <= max_timestamp_diff_us) {
int removed = xycurve->appendData( QPointF(x,y) );
x_valid = false;
y_valid = false;
bool atMaximum = (ui->timeScrollBar->value() == ui->timeScrollBar->maximum());
if(ui->timeScrollBar->maximum() != xycurve->dataSize()) {
ui->timeScrollBar->setMaximum(xycurve->dataSize());
if(atMaximum)
ui->timeScrollBar->setValue(ui->timeScrollBar->maximum());
} else if(!atMaximum) { //Move the scrollbar to keep current value selected
int value = qMax(ui->timeScrollBar->minimum(), ui->timeScrollBar->value() - removed);
ui->timeScrollBar->setValue(value);
xycurve->setStartIndex(value);
}
}
}
}
void QGCXYPlot::styleChanged(bool styleIsDark)
{
xycurve->setColor(styleIsDark ? Qt::white : Qt::black);
}
void QGCXYPlot::updateMinMaxSettings()
{
bool automatic = ui->automaticAxisRange->isChecked();
ui->minX->setEnabled(!automatic);
ui->maxX->setEnabled(!automatic);
ui->minY->setEnabled(!automatic);
ui->maxY->setEnabled(!automatic);
if(automatic) {
xycurve->unsetMinMax();
} else {
xycurve->setMinMax(ui->minX->value(), ui->maxX->value(), ui->minY->value(), ui->maxY->value());
}
xycurve->setMaxDataStorePoints(ui->maxDataStoreSpinBox->value());
xycurve->setMaxDataShowPoints(ui->maxDataShowSpinBox->value());
xycurve->setSmoothPoints(ui->smoothSpinBox->value());
}
void QGCXYPlot::setTimeAxis()
{
xycurve->setTimeSerie(ui->timeAxisRange->isChecked());
}
void QGCXYPlot::on_maxDataShowSpinBox_valueChanged(int value)
{
ui->maxDataStoreSpinBox->setMinimum(value);
if(ui->maxDataStoreSpinBox->value() < value)
ui->maxDataStoreSpinBox->setValue(value);
}
void QGCXYPlot::on_stopStartButton_toggled(bool checked)
{
if(!checked)
clearPlot();
}
void QGCXYPlot::on_timeScrollBar_valueChanged(int value)
{
if(value == ui->timeScrollBar->maximum())
xycurve->setStartIndex(-1);
else
xycurve->setStartIndex(value);
}
#ifndef QGCXYPLOT_H
#define QGCXYPLOT_H
#include "QGCToolWidgetItem.h"
namespace Ui
{
class QGCXYPlot;
}
class UASInterface;
class QwtPlot;
class XYPlotCurve;
class QGCXYPlot : public QGCToolWidgetItem
{
Q_OBJECT
public:
explicit QGCXYPlot(QWidget *parent = 0);
~QGCXYPlot();
virtual void setEditMode(bool editMode);
public slots:
void writeSettings(QSettings& settings);
void readSettings(const QSettings& settings);
void readSettings(const QString& pre,const QVariantMap& settings);
void appendData(int uasId, const QString& curve, const QString& unit, const QVariant& variant, quint64 usec);
void clearPlot();
void styleChanged(bool styleIsDark);
void updateMinMaxSettings();
private slots:
void on_maxDataShowSpinBox_valueChanged(int value);
void on_stopStartButton_toggled(bool checked);
void setTimeAxis();
void on_timeScrollBar_valueChanged(int value);
private:
Ui::QGCXYPlot *ui;
QwtPlot *plot;
XYPlotCurve* xycurve;
bool autoScaleTime;
double x; /**< Last unused value for the x-coordinate */
quint64 x_timestamp_us; /**< Timestamp that we last recieved a value for x */
bool x_valid; /**< Whether we have recieved an x value but so far no corresponding y value */
double y; /**< Last unused value for the x-coordinate */
quint64 y_timestamp_us; /**< Timestamp that we last recieved a value for x */
bool y_valid; /**< Whether we have recieved an x value but so far no corresponding y value */
quint64 max_timestamp_diff_us; /**< Only combine x and y to a data point if the timestamp for both doesn't differ by more than this */
};
#endif // QGCXYPLOT_H
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>QGCXYPlot</class>
<widget class="QWidget" name="QGCXYPlot">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>771</width>
<height>365</height>
</rect>
</property>
<property name="windowTitle">
<string>Form</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout_2">
<property name="spacing">
<number>0</number>
</property>
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item>
<widget class="Line" name="editLine1">
<property name="minimumSize">
<size>
<width>0</width>
<height>0</height>
</size>
</property>
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
</widget>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_5">
<property name="spacing">
<number>0</number>
</property>
<item>
<spacer name="horizontalSpacer_2">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<layout class="QVBoxLayout" name="verticalLayout">
<property name="spacing">
<number>0</number>
</property>
<item>
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<widget class="QLabel" name="lblXParam">
<property name="minimumSize">
<size>
<width>50</width>
<height>0</height>
</size>
</property>
<property name="text">
<string>X Parameter:</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
<property name="buddy">
<cstring>editXParam</cstring>
</property>
</widget>
</item>
<item>
<widget class="QComboBox" name="editXParam">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="editable">
<bool>true</bool>
</property>
<property name="insertPolicy">
<enum>QComboBox::InsertAlphabetically</enum>
</property>
<property name="sizeAdjustPolicy">
<enum>QComboBox::AdjustToContents</enum>
</property>
<property name="minimumContentsLength">
<number>10</number>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="lblYParam">
<property name="minimumSize">
<size>
<width>50</width>
<height>0</height>
</size>
</property>
<property name="text">
<string>Y Parameter:</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
<property name="buddy">
<cstring>editYParam</cstring>
</property>
</widget>
</item>
<item>
<widget class="QComboBox" name="editYParam">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="editable">
<bool>true</bool>
</property>
<property name="insertPolicy">
<enum>QComboBox::InsertAlphabetically</enum>
</property>
<property name="sizeAdjustPolicy">
<enum>QComboBox::AdjustToContents</enum>
</property>
<property name="minimumContentsLength">
<number>10</number>
</property>
</widget>
</item>
</layout>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_3">
<item>
<widget class="QLabel" name="lblMaxDataShow">
<property name="text">
<string>Number of data points to &amp;show:</string>
</property>
<property name="buddy">
<cstring>maxDataShowSpinBox</cstring>
</property>
</widget>
</item>
<item>
<widget class="QSpinBox" name="maxDataShowSpinBox">
<property name="minimum">
<number>2</number>
</property>
<property name="maximum">
<number>999</number>
</property>
<property name="value">
<number>15</number>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="lblMaxDataStore">
<property name="text">
<string>To s&amp;tore:</string>
</property>
<property name="buddy">
<cstring>maxDataStoreSpinBox</cstring>
</property>
</widget>
</item>
<item>
<widget class="QSpinBox" name="maxDataStoreSpinBox">
<property name="minimum">
<number>10</number>
</property>
<property name="maximum">
<number>999999999</number>
</property>
<property name="value">
<number>15</number>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="lblSmooth">
<property name="toolTip">
<string>Number of points to average, to provide a smoothing effect of the plotted values</string>
</property>
<property name="text">
<string>S&amp;mooth:</string>
</property>
<property name="buddy">
<cstring>smoothSpinBox</cstring>
</property>
</widget>
</item>
<item>
<widget class="QSpinBox" name="smoothSpinBox">
<property name="toolTip">
<string>Number of points to average, to provide a smoothing effect of the plotted values</string>
</property>
<property name="minimum">
<number>1</number>
</property>
<property name="maximum">
<number>99999</number>
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="automaticAxisRange">
<property name="text">
<string>Automatic Axis Range</string>
</property>
<property name="checked">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="timeAxisRange">
<property name="text">
<string>Time Series</string>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer_4">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
</layout>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_4">
<item>
<widget class="QLabel" name="lblMinX">
<property name="text">
<string>&amp;Min X:</string>
</property>
<property name="buddy">
<cstring>minX</cstring>
</property>
</widget>
</item>
<item>
<widget class="QDoubleSpinBox" name="minX">
<property name="minimum">
<double>-999999999.000000000000000</double>
</property>
<property name="maximum">
<double>999999999.000000000000000</double>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="lblMaxX">
<property name="text">
<string>&amp;Max X:</string>
</property>
<property name="buddy">
<cstring>maxX</cstring>
</property>
</widget>
</item>
<item>
<widget class="QDoubleSpinBox" name="maxX">
<property name="minimum">
<double>-999999999.000000000000000</double>
</property>
<property name="maximum">
<double>999999999.000000000000000</double>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="lblMinY">
<property name="text">
<string>Min &amp;Y:</string>
</property>
<property name="buddy">
<cstring>minY</cstring>
</property>
</widget>
</item>
<item>
<widget class="QDoubleSpinBox" name="minY">
<property name="minimum">
<double>-999999999.000000000000000</double>
</property>
<property name="maximum">
<double>999999999.000000000000000</double>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="lblMaxY">
<property name="text">
<string>Ma&amp;x Y:</string>
</property>
<property name="buddy">
<cstring>maxY</cstring>
</property>
</widget>
</item>
<item>
<widget class="QDoubleSpinBox" name="maxY">
<property name="minimum">
<double>-999999999.000000000000000</double>
</property>
<property name="maximum">
<double>999999999.000000000000000</double>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</item>
<item>
<spacer name="horizontalSpacer_3">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
</layout>
</item>
<item>
<layout class="QHBoxLayout" name="xyPlotLayout">
<property name="spacing">
<number>0</number>
</property>
</layout>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_6">
<property name="spacing">
<number>6</number>
</property>
<item>
<widget class="QScrollBar" name="timeScrollBar">
<property name="sizePolicy">
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimum">
<number>2</number>
</property>
<property name="tracking">
<bool>true</bool>
</property>
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="stopStartButton">
<property name="icon">
<iconset resource="../../../qgroundcontrol.qrc">
<normaloff>:/res/Stop</normaloff>
<normalon>:/res/Start</normalon>:/res/Stop</iconset>
</property>
<property name="iconSize">
<size>
<width>16</width>
<height>16</height>
</size>
</property>
<property name="checkable">
<bool>true</bool>
</property>
<property name="checked">
<bool>false</bool>
</property>
<property name="flat">
<bool>false</bool>
</property>
</widget>
</item>
</layout>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_2">
<item>
<spacer name="horizontalSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QPushButton" name="editFinishButton">
<property name="text">
<string>Done</string>
</property>
<property name="autoDefault">
<bool>false</bool>
</property>
<property name="default">
<bool>true</bool>
</property>
</widget>
</item>
</layout>
</item>
<item>
<widget class="Line" name="editLine2">
<property name="minimumSize">
<size>
<width>0</width>
<height>0</height>
</size>
</property>
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
</widget>
</item>
</layout>
</widget>
<tabstops>
<tabstop>editXParam</tabstop>
<tabstop>editYParam</tabstop>
<tabstop>maxDataShowSpinBox</tabstop>
<tabstop>maxDataStoreSpinBox</tabstop>
<tabstop>smoothSpinBox</tabstop>
<tabstop>automaticAxisRange</tabstop>
<tabstop>minX</tabstop>
<tabstop>maxX</tabstop>
<tabstop>minY</tabstop>
<tabstop>maxY</tabstop>
<tabstop>editFinishButton</tabstop>
</tabstops>
<resources>
<include location="../../../qgroundcontrol.qrc"/>
</resources>
<connections/>
</ui>
/*=====================================================================
QGroundControl Open Source Ground Control Station
(c) 2009, 2014 QGROUNDCONTROL PROJECT <http://www.qgroundcontrol.org>
This file is part of the QGROUNDCONTROL project
QGROUNDCONTROL is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
QGROUNDCONTROL is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with QGROUNDCONTROL. If not, see <http://www.gnu.org/licenses/>.
======================================================================*/
/// @file
/// @author Don Gagne <don@thegagnes.com>
#include "RCChannelWidget.h"
#include <QPainter>
#define DIMMEST_COLOR QColor::fromRgb(0,100,0)
#define MIDBRIGHT_COLOR QColor::fromRgb(0,180,0)
#define BRIGHTEST_COLOR QColor::fromRgb(64,255,0)
RCChannelWidget::RCChannelWidget(QWidget *parent) :
QGroupBox(parent),
_value(_centerValue),
_min(_centerValue),
_max(_centerValue),
_trim(_centerValue),
_minValid(false),
_maxValid(false),
_showMinMax(false),
_showTrim(false)
{
}
/// @brief Draws the control
void RCChannelWidget::paintEvent(QPaintEvent *event)
{
// Let the group box draw the outer border
QGroupBox::paintEvent(event);
// Now we draw the innner contents
QPainter painter(this);
int fontHeight = painter.fontMetrics().height();
int rowHeigth = fontHeight + 2;
painter.setBrush(Qt::Dense4Pattern);
painter.setPen(QColor::fromRgb(128,128,64));
int curVal = _value;
if (curVal > _maxRange) {
curVal = _maxRange;
}
if (curVal < _minRange) {
curVal = _minRange;
}
if (isEnabled()) {
QLinearGradient hGradientBrush(0, 0, this->width(), this->height());
hGradientBrush.setColorAt(0.0,DIMMEST_COLOR);
hGradientBrush.setColorAt(0.5,MIDBRIGHT_COLOR);
hGradientBrush.setColorAt(1.0, BRIGHTEST_COLOR);
// Calculate how much horizontal space we need to show a min/max value. We must be able to display four numeric
// digits for the rc value, plus we add another digit for spacing.
int minMaxDisplayWidth = painter.fontMetrics().width("00000");
// Draw the value axis line with center and end point tick marks. We need to leave enough space on the left and the right
// for the Min/Max value displays.
QRect rcValueAxis(minMaxDisplayWidth, rowHeigth * 2, width() - (minMaxDisplayWidth * 2), rowHeigth);
int yLine = rcValueAxis.y() + rcValueAxis.height() / 2;
painter.drawLine(rcValueAxis.left(), yLine, rcValueAxis.right(), yLine);
painter.drawLine(rcValueAxis.left(), rcValueAxis.top(), rcValueAxis.left(), rcValueAxis.bottom());
painter.drawLine(rcValueAxis.right(), rcValueAxis.top(), rcValueAxis.right(), rcValueAxis.bottom());
painter.drawLine(rcValueAxis.left() + rcValueAxis.width() / 2, rcValueAxis.top(), rcValueAxis.left() + rcValueAxis.width() / 2, rcValueAxis.bottom());
painter.setPen(QColor::fromRgb(50,255,50));
painter.setBrush(hGradientBrush);
if (_showMinMax) {
QString text;
// Draw the Min numeric value display to the left
painter.drawText(0, rowHeigth, minMaxDisplayWidth, fontHeight, Qt::AlignHCenter | Qt::AlignBottom, "Min");
if (_minValid) {
text = QString::number(_min);
} else {
text = "----";
}
painter.drawText(0, rowHeigth * 2, minMaxDisplayWidth, fontHeight, Qt::AlignHCenter | Qt::AlignBottom, text);
// Draw the Max numeric value display to the right
painter.drawText(width() - minMaxDisplayWidth, rowHeigth, minMaxDisplayWidth, fontHeight, Qt::AlignHCenter | Qt::AlignBottom, "Max");
if (_maxValid) {
text = QString::number(_max);
} else {
text = QString::number(_max);
}
painter.drawText(width() - minMaxDisplayWidth, rowHeigth * 2, minMaxDisplayWidth, fontHeight, Qt::AlignHCenter | Qt::AlignBottom, text);
// Draw the Min/Max tick marks on the axis
int xTick;
if (_minValid) {
int xTick = rcValueAxis.left() + (rcValueAxis.width() * ((float)(_min-_minRange) / (_maxRange-_minRange)));
painter.drawLine(xTick, rcValueAxis.top(), xTick, rcValueAxis.bottom());
}
if (_maxValid) {
xTick = rcValueAxis.left() + (rcValueAxis.width() * ((float)(_max-_minRange) / (_maxRange-_minRange)));
painter.drawLine(xTick, rcValueAxis.top(), xTick, rcValueAxis.bottom());
}
}
if (_showTrim) {
// Draw the Trim value pointer
_drawValuePointer(&painter,
rcValueAxis.left() + (rcValueAxis.width() * ((float)(_trim-_minRange) / (_maxRange-_minRange))), // x position for tip of triangle
(rowHeigth * 2) + (rowHeigth / 2) - 1, // y position for tip of triangle
rowHeigth / 2, // heigth of triangle
false); // draw upside down
// Draw the Trim value label
QString trimStr = tr("Trim %1").arg(QString::number(_trim));
int trimTextWidth = painter.fontMetrics().width(trimStr);
painter.drawText(rcValueAxis.left() + (rcValueAxis.width() * ((float)(_trim-_minRange) / (_maxRange-_minRange))) - (trimTextWidth / 2),
rowHeigth,
trimTextWidth,
fontHeight,
Qt::AlignLeft | Qt::AlignBottom,
trimStr);
}
// Draw the RC value pointer
_drawValuePointer(&painter,
rcValueAxis.left() + (rcValueAxis.width() * ((float)(curVal-_minRange) / (_maxRange-_minRange))), // x position for tip of triangle
(rowHeigth * 2) + (rowHeigth / 2) + 1, // y position for tip of triangle
rowHeigth / 2, // heigth of triangle
true); // draw right side up
// Draw the control value
QString valueStr = QString::number(_value);
int valueTextWidth = painter.fontMetrics().width(valueStr);
painter.drawText(rcValueAxis.left() + (rcValueAxis.width() * ((float)(_value-_minRange) / (_maxRange-_minRange))) - (valueTextWidth / 2),
rowHeigth * 3,
valueTextWidth,
fontHeight,
Qt::AlignLeft | Qt::AlignBottom,
valueStr);
painter.setPen(QColor::fromRgb(0,128,0));
painter.setBrush(hGradientBrush);
} else {
painter.setPen(QColor(Qt::gray));
painter.drawText(0, 0, width(), height(), Qt::AlignHCenter | Qt::AlignVCenter, tr("not available"));
}
}
void RCChannelWidget::setValue(int value)
{
_value = value;
update();
}
void RCChannelWidget::showMinMax(bool show)
{
_showMinMax = show;
update();
}
void RCChannelWidget::showTrim(bool show)
{
_showTrim = show;
update();
}
void RCChannelWidget::setValueAndMinMax(int val, int min, int max)
{
setValue(val);
setMinMax(min,max);
}
void RCChannelWidget::setMinMax(int min, int max)
{
_min = min;
_max = max;
update();
}
void RCChannelWidget::setTrim(int value)
{
_trim = value;
update();
}
/// @brief Draw rc value pointer triangle.
/// @param painter Draw using this painter
/// @param x X position for tip of triangle
/// @param y Y position for tip of triangle
/// @param heigth Height of triangle
/// @param rightSideUp true: draw triangle right side up, false: draw triangle upside down
void RCChannelWidget::_drawValuePointer(QPainter* painter, int xTip, int yTip, int height, bool rightSideUp)
{
QPointF trianglePoints[3];
// Topmost tip of triangle points to value
trianglePoints[0].setX(xTip);
trianglePoints[0].setY(yTip);
int yBottom;
if (rightSideUp) {
yBottom = yTip + height;
} else {
yBottom = yTip - height;
}
// Right bottom tip of triangle
trianglePoints[1].setX(xTip + (height * 0.75));
trianglePoints[1].setY(yBottom);
// Left bottom tip of triangle
trianglePoints[2].setX(xTip - (height * 0.75));
trianglePoints[2].setY(yBottom);
painter->drawPolygon (trianglePoints, 3);
}
/// @brief Set whether the Min range value is valid or not.
void RCChannelWidget::setMinValid(bool valid)
{
_minValid = valid;
update();
}
/// @brief Set whether the Max range value is valid or not.
void RCChannelWidget::setMaxValid(bool valid)
{
_maxValid = valid;
update();
}
/*=====================================================================
QGroundControl Open Source Ground Control Station
(c) 2009, 2014 QGROUNDCONTROL PROJECT <http://www.qgroundcontrol.org>
This file is part of the QGROUNDCONTROL project
QGROUNDCONTROL is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
QGROUNDCONTROL is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with QGROUNDCONTROL. If not, see <http://www.gnu.org/licenses/>.
======================================================================*/
/// @file
/// @author Don Gagne <don@thegagnes.com>
#ifndef RCChannelWidget_H
#define RCChannelWidget_H
#include <QGroupBox>
/// @brief RC Channel Widget - UI Widget based on QGroupBox which displays the current calibration settings
/// for an RC channel.
class RCChannelWidget : public QGroupBox
{
Q_OBJECT
public:
explicit RCChannelWidget(QWidget *parent = 0);
/// @brief Set the current RC value to display
void setValue(int value);
/// @brief Set the current RC Value, Minimum RC Value and Maximum RC Value
void setValueAndMinMax(int val, int min, int max);
void setMinMax(int min, int max);
/// @brief Set whether the Min range value is valid or not.
void setMinValid(bool valid);
/// @brief Set whether the Max range value is valid or not.
void setMaxValid(bool valid);
/// @brief Sets the Trim value for the channel
void setTrim(int value);
int value(void) { return _value; } ///< Returns the current RC Value set in the control
int min(void) { return _min; } ///< Returns the min value set in the control
int max(void) { return _max; } ///< Returns the max values set in the control
int trim(void) { return _trim; } ///< Returns the trim value set in the control
void showMinMax(bool show);
bool isMinMaxShown() { return _showMinMax; }
bool isMinValid(void) { return _minValid; }
bool isMaxValid(void) { return _maxValid; }
void showTrim(bool show);
bool isTrimShown() { return _showTrim; }
protected:
virtual void paintEvent(QPaintEvent *event);
private:
void _drawValuePointer(QPainter* painter, int xTip, int yTip, int height, bool rightSideUp);
int _value; ///< Current RC value
int _min; ///< Min RC value
int _max; ///< Max RC value
int _trim; ///< RC Value for Trim position
bool _minValid; ///< true: minimum value is valid
bool _maxValid; ///< true: maximum value is valid
bool _showMinMax; ///< true: show min max values on display
bool _showTrim; ///< true: show trim value on display
static const int _centerValue = 1500; ///< RC Value which is at center
static const int _maxDeltaRange = 700; ///< Delta around center value which is the max range for widget
static const int _minRange = _centerValue - _maxDeltaRange; ///< Smallest value widget can display
static const int _maxRange = _centerValue + _maxDeltaRange; ///< Largest value widget can display
};
#endif
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