15 changed files with 1896 additions and 3048 deletions
@ -0,0 +1,510 @@
@@ -0,0 +1,510 @@
|
||||
/*===================================================================== |
||||
|
||||
QGroundControl Open Source Ground Control Station |
||||
|
||||
(c) 2009 - 2015 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 |
||||
/// @brief Radio Calibration |
||||
/// @author Don Gagne <don@thegagnes.com> |
||||
|
||||
import QtQuick 2.2 |
||||
import QtQuick.Controls 1.2 |
||||
import QtQuick.Dialogs 1.2 |
||||
|
||||
import QGroundControl.FactSystem 1.0 |
||||
import QGroundControl.FactControls 1.0 |
||||
import QGroundControl.Palette 1.0 |
||||
import QGroundControl.Controls 1.0 |
||||
import QGroundControl.ScreenTools 1.0 |
||||
import QGroundControl.Controllers 1.0 |
||||
|
||||
QGCView { |
||||
id: rootQGCView |
||||
viewComponent: view |
||||
|
||||
Component { |
||||
id: view |
||||
|
||||
QGCViewPanel { |
||||
id: viewPanel |
||||
|
||||
QGCPalette { id: qgcPal; colorGroupEnabled: enabled } |
||||
|
||||
readonly property real labelToMonitorMargin: defaultTextWidth * 3 |
||||
|
||||
function updateChannelCount() |
||||
{ |
||||
if (controller.channelCount < controller.minChannelCount) { |
||||
showDialog(channelCountDialogComponent, "Radio Config", 50, 0) |
||||
} else { |
||||
hideDialog() |
||||
} |
||||
} |
||||
|
||||
RadioComponentController { |
||||
id: controller |
||||
factPanel: viewPanel |
||||
statusText: statusText |
||||
cancelButton: cancelButton |
||||
nextButton: nextButton |
||||
skipButton: skipButton |
||||
|
||||
onChannelCountChanged: updateChannelCount() |
||||
} |
||||
|
||||
Connections { |
||||
target: rootQGCView |
||||
|
||||
onCompleted: { |
||||
controller.start() |
||||
updateChannelCount() |
||||
} |
||||
} |
||||
|
||||
Component { |
||||
id: channelCountDialogComponent |
||||
|
||||
QGCViewMessage { |
||||
message: controller.channelCount == 0 ? "Please turn on transmitter." : controller.minChannelCount + " channels or more are needed to fly." |
||||
} |
||||
} |
||||
|
||||
Component { |
||||
id: spektrumBindDialogComponent |
||||
|
||||
QGCViewDialog { |
||||
|
||||
function accept() { |
||||
controller.spektrumBindMode(radioGroup.current.bindMode) |
||||
hideDialog() |
||||
} |
||||
|
||||
function reject() { |
||||
hideDialog() |
||||
} |
||||
|
||||
Column { |
||||
anchors.fill: parent |
||||
spacing: 5 |
||||
|
||||
QGCLabel { |
||||
width: parent.width |
||||
wrapMode: Text.WordWrap |
||||
text: "Click Ok to place your Spektrum receiver in the bind mode. Select the specific receiver type below:" |
||||
} |
||||
|
||||
ExclusiveGroup { id: radioGroup } |
||||
|
||||
QGCRadioButton { |
||||
exclusiveGroup: radioGroup |
||||
text: "DSM2 Mode" |
||||
|
||||
property int bindMode: RadioComponentController.DSM2 |
||||
} |
||||
|
||||
QGCRadioButton { |
||||
exclusiveGroup: radioGroup |
||||
text: "DSMX (7 channels or less)" |
||||
|
||||
property int bindMode: RadioComponentController.DSMX7 |
||||
} |
||||
|
||||
QGCRadioButton { |
||||
exclusiveGroup: radioGroup |
||||
checked: true |
||||
text: "DSMX (8 channels or more)" |
||||
|
||||
property int bindMode: RadioComponentController.DSMX8 |
||||
} |
||||
} |
||||
} |
||||
} // Component - spektrumBindDialogComponent |
||||
|
||||
// Live channel monitor control component |
||||
Component { |
||||
id: channelMonitorDisplayComponent |
||||
|
||||
Item { |
||||
property int rcValue: 1500 |
||||
|
||||
|
||||
property int __lastRcValue: 1500 |
||||
readonly property int __rcValueMaxJitter: 2 |
||||
property color __barColor: qgcPal.windowShade |
||||
|
||||
// Bar |
||||
Rectangle { |
||||
id: bar |
||||
anchors.verticalCenter: parent.verticalCenter |
||||
width: parent.width |
||||
height: parent.height / 2 |
||||
color: __barColor |
||||
} |
||||
|
||||
// Center point |
||||
Rectangle { |
||||
anchors.horizontalCenter: parent.horizontalCenter |
||||
width: defaultTextWidth / 2 |
||||
height: parent.height |
||||
color: qgcPal.window |
||||
} |
||||
|
||||
// Indicator |
||||
Rectangle { |
||||
anchors.verticalCenter: parent.verticalCenter |
||||
width: parent.height * 0.75 |
||||
height: width |
||||
x: ((Math.abs((rcValue - 1000) - (reversed ? 1000 : 0)) / 1000) * parent.width) - (width / 2) |
||||
radius: width / 2 |
||||
color: qgcPal.text |
||||
visible: mapped |
||||
} |
||||
|
||||
QGCLabel { |
||||
anchors.fill: parent |
||||
horizontalAlignment: Text.AlignHCenter |
||||
verticalAlignment: Text.AlignVCenter |
||||
text: "Not Mapped" |
||||
visible: !mapped |
||||
} |
||||
|
||||
ColorAnimation { |
||||
id: barAnimation |
||||
target: bar |
||||
property: "color" |
||||
from: "yellow" |
||||
to: __barColor |
||||
duration: 1500 |
||||
} |
||||
|
||||
onRcValueChanged: { |
||||
if (Math.abs(rcValue - __lastRcValue) > __rcValueMaxJitter) { |
||||
__lastRcValue = rcValue |
||||
barAnimation.restart() |
||||
} |
||||
} |
||||
|
||||
/* |
||||
// rcValue debugger |
||||
QGCLabel { |
||||
anchors.fill: parent |
||||
text: rcValue |
||||
} |
||||
*/ |
||||
} |
||||
} // Component - channelMonitorDisplayComponent |
||||
|
||||
// Main view Qml starts here |
||||
|
||||
QGCLabel { |
||||
id: header |
||||
font.pointSize: ScreenTools.largeFontPointSize |
||||
text: "RADIO CONFIG" |
||||
} |
||||
|
||||
Item { |
||||
id: spacer |
||||
anchors.top: header.bottom |
||||
width: parent.width |
||||
height: 10 |
||||
} |
||||
|
||||
// Left side column |
||||
Column { |
||||
id: leftColumn |
||||
anchors.top: spacer.bottom |
||||
anchors.left: parent.left |
||||
anchors.right: columnSpacer.left |
||||
spacing: 10 |
||||
|
||||
Row { |
||||
spacing: 10 |
||||
|
||||
QGCLabel { |
||||
anchors.baseline: bindButton.baseline |
||||
text: "Place Spektrum satellite receiver in bind mode:" |
||||
} |
||||
|
||||
QGCButton { |
||||
id: bindButton |
||||
text: "Spektrum Bind" |
||||
|
||||
onClicked: showDialog(spektrumBindDialogComponent, "Radio Config", 50, StandardButton.Ok | StandardButton.Cancel) |
||||
} |
||||
} |
||||
|
||||
// Attitude Controls |
||||
Column { |
||||
width: parent.width |
||||
spacing: 5 |
||||
|
||||
QGCLabel { text: "Attitude Controls" } |
||||
|
||||
Item { |
||||
width: parent.width |
||||
height: defaultTextHeight * 2 |
||||
|
||||
QGCLabel { |
||||
id: rollLabel |
||||
width: defaultTextWidth * 10 |
||||
text: "Roll" |
||||
} |
||||
|
||||
Loader { |
||||
id: rollLoader |
||||
anchors.left: rollLabel.right |
||||
anchors.right: parent.right |
||||
height: rootQGCView.defaultTextHeight |
||||
width: 100 |
||||
sourceComponent: channelMonitorDisplayComponent |
||||
|
||||
property real defaultTextWidth: rootQGCView.defaultTextWidth |
||||
property bool mapped: controller.rollChannelMapped |
||||
property bool reversed: controller.rollChannelReversed |
||||
} |
||||
|
||||
Connections { |
||||
target: controller |
||||
|
||||
onRollChannelRCValueChanged: rollLoader.item.rcValue = rcValue |
||||
} |
||||
} |
||||
|
||||
Item { |
||||
width: parent.width |
||||
height: defaultTextHeight * 2 |
||||
|
||||
QGCLabel { |
||||
id: pitchLabel |
||||
width: defaultTextWidth * 10 |
||||
text: "Pitch" |
||||
} |
||||
|
||||
Loader { |
||||
id: pitchLoader |
||||
anchors.left: pitchLabel.right |
||||
anchors.right: parent.right |
||||
height: rootQGCView.defaultTextHeight |
||||
width: 100 |
||||
sourceComponent: channelMonitorDisplayComponent |
||||
|
||||
property real defaultTextWidth: rootQGCView.defaultTextWidth |
||||
property bool mapped: controller.pitchChannelMapped |
||||
property bool reversed: controller.pitchChannelReversed |
||||
} |
||||
|
||||
Connections { |
||||
target: controller |
||||
|
||||
onPitchChannelRCValueChanged: pitchLoader.item.rcValue = rcValue |
||||
} |
||||
} |
||||
|
||||
Item { |
||||
width: parent.width |
||||
height: defaultTextHeight * 2 |
||||
|
||||
QGCLabel { |
||||
id: yawLabel |
||||
width: defaultTextWidth * 10 |
||||
text: "Yaw" |
||||
} |
||||
|
||||
Loader { |
||||
id: yawLoader |
||||
anchors.left: yawLabel.right |
||||
anchors.right: parent.right |
||||
height: rootQGCView.defaultTextHeight |
||||
width: 100 |
||||
sourceComponent: channelMonitorDisplayComponent |
||||
|
||||
property real defaultTextWidth: rootQGCView.defaultTextWidth |
||||
property bool mapped: controller.yawChannelMapped |
||||
property bool reversed: controller.yawChannelReversed |
||||
} |
||||
|
||||
Connections { |
||||
target: controller |
||||
|
||||
onYawChannelRCValueChanged: yawLoader.item.rcValue = rcValue |
||||
} |
||||
} |
||||
|
||||
Item { |
||||
width: parent.width |
||||
height: defaultTextHeight * 2 |
||||
|
||||
QGCLabel { |
||||
id: throttleLabel |
||||
width: defaultTextWidth * 10 |
||||
text: "Throttle" |
||||
} |
||||
|
||||
Loader { |
||||
id: throttleLoader |
||||
anchors.left: throttleLabel.right |
||||
anchors.right: parent.right |
||||
height: rootQGCView.defaultTextHeight |
||||
width: 100 |
||||
sourceComponent: channelMonitorDisplayComponent |
||||
|
||||
property real defaultTextWidth: rootQGCView.defaultTextWidth |
||||
property bool mapped: controller.throttleChannelMapped |
||||
property bool reversed: controller.throttleChannelReversed |
||||
} |
||||
|
||||
Connections { |
||||
target: controller |
||||
|
||||
onThrottleChannelRCValueChanged: throttleLoader.item.rcValue = rcValue |
||||
} |
||||
} |
||||
} // Column - Attitude Control labels |
||||
|
||||
// Command Buttons |
||||
Row { |
||||
spacing: 10 |
||||
|
||||
QGCButton { |
||||
id: skipButton |
||||
text: "Skip" |
||||
|
||||
onClicked: controller.skipButtonClicked() |
||||
} |
||||
|
||||
QGCButton { |
||||
id: cancelButton |
||||
text: "Cancel" |
||||
|
||||
onClicked: controller.cancelButtonClicked() |
||||
} |
||||
|
||||
QGCButton { |
||||
id: nextButton |
||||
primary: true |
||||
text: "Calibrate" |
||||
|
||||
onClicked: controller.nextButtonClicked() |
||||
} |
||||
} // Row - Buttons |
||||
|
||||
// Status Text |
||||
QGCLabel { |
||||
id: statusText |
||||
width: parent.width |
||||
wrapMode: Text.WordWrap |
||||
} |
||||
} // Column - Left Column |
||||
|
||||
Item { |
||||
id: columnSpacer |
||||
anchors.right: rightColumn.left |
||||
width: 20 |
||||
} |
||||
|
||||
// Right side column |
||||
Column { |
||||
id: rightColumn |
||||
anchors.top: spacer.bottom |
||||
anchors.right: parent.right |
||||
width: defaultTextWidth * 35 |
||||
spacing: 10 |
||||
|
||||
Row { |
||||
spacing: 10 |
||||
ExclusiveGroup { id: modeGroup } |
||||
|
||||
QGCRadioButton { |
||||
exclusiveGroup: modeGroup |
||||
text: "Mode 1" |
||||
checked: controller.transmitterMode == 1 |
||||
|
||||
onClicked: controller.transmitterMode = 1 |
||||
} |
||||
|
||||
QGCRadioButton { |
||||
exclusiveGroup: modeGroup |
||||
text: "Mode 2" |
||||
checked: controller.transmitterMode == 2 |
||||
|
||||
onClicked: controller.transmitterMode = 2 |
||||
} |
||||
} |
||||
|
||||
Image { |
||||
width: parent.width |
||||
height: defaultTextHeight * 15 |
||||
fillMode: Image.PreserveAspectFit |
||||
smooth: true |
||||
source: controller.imageHelp |
||||
} |
||||
|
||||
// Channel monitor |
||||
Column { |
||||
width: parent.width |
||||
spacing: 5 |
||||
|
||||
QGCLabel { text: "Channel Monitor" } |
||||
|
||||
Connections { |
||||
target: controller |
||||
|
||||
onChannelRCValueChanged: { |
||||
if (channelMonitorRepeater.itemAt(channel)) { |
||||
channelMonitorRepeater.itemAt(channel).loader.item.rcValue = rcValue |
||||
} |
||||
} |
||||
} |
||||
|
||||
Repeater { |
||||
id: channelMonitorRepeater |
||||
model: controller.channelCount |
||||
width: parent.width |
||||
|
||||
Row { |
||||
spacing: 5 |
||||
|
||||
// Need this to get to loader from Connections above |
||||
property Item loader: theLoader |
||||
|
||||
QGCLabel { |
||||
id: channelLabel |
||||
text: modelData + 1 |
||||
} |
||||
|
||||
Loader { |
||||
id: theLoader |
||||
anchors.verticalCenter: channelLabel.verticalCenter |
||||
height: rootQGCView.defaultTextHeight |
||||
width: 200 |
||||
sourceComponent: channelMonitorDisplayComponent |
||||
|
||||
property real defaultTextWidth: rootQGCView.defaultTextWidth |
||||
property bool mapped: true |
||||
readonly property bool reversed: false |
||||
} |
||||
} |
||||
} |
||||
} // Column - Channel Monitor |
||||
} // Column - Right Column |
||||
} // QGCViewPanel |
||||
} // Component - view |
||||
} |
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -1,306 +0,0 @@
@@ -1,306 +0,0 @@
|
||||
/*=====================================================================
|
||||
|
||||
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 "RCValueWidget.h" |
||||
|
||||
#include <QPainter> |
||||
#include <QDebug> |
||||
|
||||
#define DIMMEST_COLOR QColor::fromRgb(0,100,0) |
||||
#define MIDBRIGHT_COLOR QColor::fromRgb(0,180,0) |
||||
#define BRIGHTEST_COLOR QColor::fromRgb(64,255,0) |
||||
|
||||
RCValueWidget::RCValueWidget(QWidget *parent) : |
||||
QWidget(parent), |
||||
_smallMode(false), |
||||
_value(_centerValue), |
||||
_min(_centerValue), |
||||
_max(_centerValue), |
||||
_trim(_centerValue), |
||||
_minValid(false), |
||||
_maxValid(false), |
||||
_showMinMax(false), |
||||
_showTrim(false), |
||||
_fgColor(255, 255, 255) |
||||
{ |
||||
setAutoFillBackground(true); |
||||
} |
||||
|
||||
/// @brief Draws the control
|
||||
void RCValueWidget::paintEvent(QPaintEvent *event) |
||||
{ |
||||
QPainter painter(this); |
||||
painter.setRenderHints(QPainter::Antialiasing); |
||||
|
||||
Q_UNUSED(event); |
||||
|
||||
int curVal = _value; |
||||
if (curVal > _maxRange) { |
||||
curVal = _maxRange; |
||||
} |
||||
if (curVal < _minRange) { |
||||
curVal = _minRange; |
||||
} |
||||
|
||||
QPen pen(_fgColor); |
||||
pen.setWidth(1); |
||||
painter.setPen(pen); |
||||
|
||||
if (_smallMode) { |
||||
painter.drawLine(0, height() / 2, width(), height() / 2); |
||||
} else { |
||||
// The value bar itself it centered in the control
|
||||
QRect rectValueBar(0, (rect().height() - _barHeight)/2, rect().width() - 1, _barHeight); |
||||
|
||||
painter.drawRoundedRect(rectValueBar, _barHeight/2, _barHeight/2); |
||||
} |
||||
|
||||
// Draw the RC value circle
|
||||
int radius = _smallMode ? 4 : _barHeight; |
||||
int curValNormalized; |
||||
if (_reversed) { |
||||
curValNormalized = _centerValue - (curVal - _centerValue); |
||||
} else { |
||||
curValNormalized = curVal; |
||||
} |
||||
QPoint ptCenter(width() * ((float)(curValNormalized-_minRange) / (_maxRange-_minRange)), height() / 2); |
||||
QBrush brush(QColor(128, 128, 128)); |
||||
painter.setBrush(brush); |
||||
painter.drawEllipse(ptCenter, radius, radius); |
||||
|
||||
#if 0 |
||||
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")); |
||||
} |
||||
#endif |
||||
} |
||||
|
||||
void RCValueWidget::setValue(int value) |
||||
{ |
||||
_value = value; |
||||
update(); |
||||
} |
||||
|
||||
void RCValueWidget::showMinMax(bool show) |
||||
{ |
||||
_showMinMax = show; |
||||
update(); |
||||
} |
||||
|
||||
void RCValueWidget::showTrim(bool show) |
||||
{ |
||||
_showTrim = show; |
||||
update(); |
||||
} |
||||
|
||||
void RCValueWidget::setValueAndMinMax(int val, int min, int max) |
||||
{ |
||||
setValue(val); |
||||
setMinMax(min,max); |
||||
} |
||||
|
||||
void RCValueWidget::setMinMax(int min, int max) |
||||
{ |
||||
_min = min; |
||||
_max = max; |
||||
update(); |
||||
} |
||||
|
||||
void RCValueWidget::setMin(int min) |
||||
{ |
||||
_min = min; |
||||
update(); |
||||
} |
||||
|
||||
void RCValueWidget::setMax(int max) |
||||
{ |
||||
_max = max; |
||||
update(); |
||||
} |
||||
|
||||
void RCValueWidget::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 RCValueWidget::_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 RCValueWidget::setMinValid(bool valid) |
||||
{ |
||||
_minValid = valid; |
||||
update(); |
||||
} |
||||
|
||||
/// @brief Set whether the Max range value is valid or not.
|
||||
void RCValueWidget::setMaxValid(bool valid) |
||||
{ |
||||
_maxValid = valid; |
||||
update(); |
||||
} |
@ -1,111 +0,0 @@
@@ -1,111 +0,0 @@
|
||||
/*=====================================================================
|
||||
|
||||
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
|
||||
/// @brief Widget which shows current RC value on a bar with tick marks.
|
||||
/// @author Don Gagne <don@thegagnes.com>
|
||||
|
||||
#ifndef RCValueWidget_H |
||||
#define RCValueWidget_H |
||||
|
||||
#include <QWidget> |
||||
#include <QColor> |
||||
|
||||
/// @brief Widget which shows current RC value on a bar with tick marks.
|
||||
class RCValueWidget : public QWidget |
||||
{ |
||||
Q_OBJECT |
||||
|
||||
public: |
||||
explicit RCValueWidget(QWidget *parent = 0); |
||||
|
||||
/// @brief Set the widget to display small value bar.
|
||||
void setSmallMode(void) { _smallMode = true; } |
||||
|
||||
/// @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); |
||||
void setMin(int min); |
||||
void setMax(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); |
||||
|
||||
/// @brief Sets the reversed state of channel
|
||||
/// @param reversed true: channel is reversed
|
||||
void setReversed(bool reversed) { _reversed = reversed; } |
||||
|
||||
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); |
||||
|
||||
bool _smallMode; ///< true: draw small value bar, false: draw normal value bar
|
||||
|
||||
int _value; ///< Current RC value
|
||||
int _min; ///< Min RC value
|
||||
int _max; ///< Max RC value
|
||||
int _trim; ///< RC Value for Trim position
|
||||
bool _reversed; ///< true: channel is reversed
|
||||
|
||||
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 = 650; ///< 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
|
||||
|
||||
static const int _barHeight = 7; |
||||
|
||||
QColor _fgColor; |
||||
}; |
||||
|
||||
#endif |
Loading…
Reference in new issue