sdrangel/sdrgui/gui/coursedeviationindicator.cpp

183 wiersze
5.3 KiB
C++

///////////////////////////////////////////////////////////////////////////////////
// Copyright (C) 2023 Jon Beniston, M7RCE <jon@beniston.com> //
// //
// This program 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 as version 3 of the License, or //
// (at your option) any later version. //
// //
// This program 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 V3 for more details. //
// //
// You should have received a copy of the GNU General Public License //
// along with this program. If not, see <http://www.gnu.org/licenses/>. //
///////////////////////////////////////////////////////////////////////////////////
#include <cmath>
#include <QPainter>
#include "coursedeviationindicator.h"
CourseDeviationIndicator::CourseDeviationIndicator(QWidget *parent) :
QWidget(parent),
m_localizerDDM(0.0f),
m_glideSlopeDDM(0.0f)
{
}
void CourseDeviationIndicator::setMode(Mode mode)
{
m_mode = mode;
update();
}
void CourseDeviationIndicator::setLocalizerDDM(float ddm)
{
m_localizerDDM = ddm;
update();
}
void CourseDeviationIndicator::setGlideSlopeDDM(float ddm)
{
m_glideSlopeDDM = ddm;
update();
}
void CourseDeviationIndicator::paintEvent(QPaintEvent *event)
{
(void) event;
QPainter painter(this);
QRect r = rect();
int midW = r.width() / 2;
int midH = r.height() / 2;
int spacing;
// A320 like CDI
// Black background
int bgw, bgh;
if (m_mode == LOC)
{
bgw = r.width();
bgh = 20;
painter.fillRect(0, midH - bgh, bgw, bgh*2, QColor(0, 0, 0));
}
else
{
bgw = 20;
bgh = r.height();
painter.fillRect(midW - bgw, 0, bgw*2, bgh, QColor(0, 0, 0));
}
const int dots = 5;
// Circles
painter.setPen(QColor(255, 255, 255));
const int radius = 4;
int x, y;
if (m_mode == LOC)
{
spacing = r.width() / 5;
x = spacing / 2;
y = midH;
}
else
{
spacing = r.height() / 5;
x = midW;
y = spacing / 2;
}
for (int i = 0; i < dots; i++)
{
if (i != 2) {
painter.drawEllipse(QPointF(x, y), radius, radius);
}
if (m_mode == LOC) {
x += spacing;
} else {
y += spacing;
}
}
// Diamond (index) - only draw half of symbol if out of range
// Shouldn't draw the symbol if signal not vaiid
// Typically, LOC full scale deflection 0.155 DDM (Which is ~2.5deg, so 1 deg per dot, but can be 3 degrees. A320 is 0.8 deg per dot)
// For GS, full deflection is 0.0875 DDM (0.7deg, so 0.14 deg per dot)
painter.setPen(QColor(255, 150, 250));
float dev;
if (m_mode == LOC) {
dev = m_localizerDDM / 0.155;
} else {
dev = m_glideSlopeDDM / 0.0875;
}
dev = std::min(dev, 1.0f);
dev = std::max(dev, -1.0f);
if (m_mode == LOC)
{
x = midW + dev * r.width() / 2; // Positive DDM means we're to left of course line
y = midH;
}
else
{
x = midW;
y = midH + dev * r.height() / 2; // Positive DDM means we're above glide path
}
int dw = 10;
int dh = 8;
painter.drawLine(x, y + dh, x - dw, y);
painter.drawLine(x - dw, y, x, y - dh);
painter.drawLine(x + dw, y, x, y - dh);
painter.drawLine(x, y + dh, x + dw, y);
// Centre line
painter.setPen(QColor(255, 255, 70));
if (m_mode == LOC)
{
int lh = 14;
painter.drawLine(midW, midH + lh, midW, midH - lh);
painter.drawLine(midW-1, midH + lh, midW-1, midH - lh);
painter.drawLine(midW+1, midH + lh, midW+1, midH - lh);
}
else
{
int lw = 14;
painter.drawLine(midW + lw, midH, midW - lw, midH);
painter.drawLine(midW + lw, midH - 1, midW - lw, midH - 1);
painter.drawLine(midW + lw, midH + 1, midW - lw, midH + 1);
}
if (m_mode == LOC)
{
// Indicate localizer capture
if (std::abs(m_localizerDDM) < 0.175) // See 3.1.3.7.4
{
QFontMetrics fm(painter.font());
QString text = "LOC";
int tw = fm.horizontalAdvance(text);
int th = fm.descent();
painter.setPen(QColor(0, 255, 0));
painter.drawText(midW - tw/2, midH - bgh - th, text);
}
}
else
{
// Indicate glideslope capture
if (std::abs(m_glideSlopeDDM) < 0.175) // Can't see a spec for this
{
QFontMetrics fm(painter.font());
QString text = "G/S";
int th = fm.ascent() / 2;
painter.setPen(QColor(0, 255, 0));
painter.drawText(midW + bgw + 2, midH + th, text);
}
}
}