Commit 19dc3af7 authored by Don Gagne's avatar Don Gagne

New rc calibration channel widget

Left QGCRadioChannelDisplay alone so that I didn’t need to modify all
the other APM board code which uses this control. Also new control only
support horizontal orientation, with no plans to add vertical.
parent 6836a23a
/*=====================================================================
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),
_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) {
// Draw the Min numeric value display to the left
painter.drawText(0, rowHeigth, minMaxDisplayWidth, fontHeight, Qt::AlignHCenter | Qt::AlignBottom, "Min");
painter.drawText(0, rowHeigth * 2, minMaxDisplayWidth, fontHeight, Qt::AlignHCenter | Qt::AlignBottom, QString::number(_min));
// Draw the Max numeric value display to the right
painter.drawText(width() - minMaxDisplayWidth, rowHeigth, minMaxDisplayWidth, fontHeight, Qt::AlignHCenter | Qt::AlignBottom, "Max");
painter.drawText(width() - minMaxDisplayWidth, rowHeigth * 2, minMaxDisplayWidth, fontHeight, Qt::AlignHCenter | Qt::AlignBottom, QString::number(_max));
// Draw the Min/Max tick marks on the axis
int xTick = rcValueAxis.left() + (rcValueAxis.width() * ((float)(_min-_minRange) / (_maxRange-_minRange)));
painter.drawLine(xTick, rcValueAxis.top(), xTick, rcValueAxis.bottom());
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);
}
/*=====================================================================
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 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; }
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 _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