From 5fe53cb65045b5882f24cd7f5aa20be100101358 Mon Sep 17 00:00:00 2001 From: JC Luna Date: Sat, 28 Mar 2026 19:48:09 -0500 Subject: [PATCH 01/18] Different hand drawing depending on where the nominal value is --- src/Widgets/Dial/AttitudeDial.cpp | 39 +++++++++++++++++++++++++++---- src/Widgets/Dial/AttitudeDial.h | 12 ++++++++++ 2 files changed, 47 insertions(+), 4 deletions(-) diff --git a/src/Widgets/Dial/AttitudeDial.cpp b/src/Widgets/Dial/AttitudeDial.cpp index 98a5d32..d1a52ff 100644 --- a/src/Widgets/Dial/AttitudeDial.cpp +++ b/src/Widgets/Dial/AttitudeDial.cpp @@ -16,6 +16,7 @@ AttitudeDial::AttitudeDial(QWidget* parent) : QWidget(parent) { NumericDisplay->setFrameStyle(QFrame::Panel | QFrame::Raised); NumericDisplay->setFont(NumericDisplayFont); NumericDisplay->setStyleSheet(" QLabel { color: white; background-color: black; border-radius: 3% } "); + SetRangeType(RangeTypeMode); update(); } // AttitudeDial ctor @@ -67,6 +68,39 @@ void AttitudeDial::SetNumericDisplayState(bool enabled) { update(); } // void AttitudeDial::UpdateNumericDisplay() +QPoint AttitudeDial::HandEndingLowestNominal() const { + double ang = (CurrentAngle - Range[0]) * 3.14 / 180.0; + int linex = Radius*std::sin(ang); + int liney = -Radius*std::cos(ang); + + return Origin + QPoint{ linex, liney }; +} + +QPoint AttitudeDial::HandEndingCenteredNominal() const { + double rangeCtr = (Range[1] - Range[0]) / 2.0; + double ang = (CurrentAngle - rangeCtr) * 3.14 / 180.0; + int linex = Radius*std::sin(ang); + int liney = -Radius*std::cos(ang); + + return Origin + QPoint{ linex, liney }; +} + +void AttitudeDial::SetRangeType(RangeType newRangeType) { + RangeTypeMode = newRangeType; + + switch (RangeTypeMode) { + case RangeType::LowestNominal: + RangeHandlerFunction = std::bind(&AttitudeDial::HandEndingLowestNominal, this); + break; + case RangeType::CenteredNominal: + default: + RangeHandlerFunction = std::bind(&AttitudeDial::HandEndingCenteredNominal, this); + break; + } + + update(); +} + void AttitudeDial::PaintCircularBacking(QPainter* painter) { QBrush fillBrush = painter->brush(); fillBrush.setStyle(Qt::SolidPattern); @@ -111,10 +145,7 @@ void AttitudeDial::PaintTicks(QPainter* painter) { } // void AttitudeDial::PaintTicks() void AttitudeDial::PaintHand(QPainter* painter) { - double ang = CurrentAngle * 3.14 / 180.0; - int linex = Radius*std::sin(ang); - int liney = -Radius*std::cos(ang); - QPoint end = Origin + QPoint{ linex, liney }; + QPoint end = (RangeHandlerFunction) ? RangeHandlerFunction(this) : Origin + QPoint{ 0, (int)Radius }; QPen pen = painter->pen(); pen.setColor(Palette.Hand); diff --git a/src/Widgets/Dial/AttitudeDial.h b/src/Widgets/Dial/AttitudeDial.h index 3033ab2..7da53cb 100644 --- a/src/Widgets/Dial/AttitudeDial.h +++ b/src/Widgets/Dial/AttitudeDial.h @@ -1,5 +1,6 @@ #pragma once +#include #include #include @@ -27,6 +28,12 @@ class AttitudeDial : public QWidget { AttitudeDialPalette GetPalette() const; const AttitudeDialPalette& GetPaletteView() const; + enum class RangeType : uint8_t { + CenteredNominal, + LowestNominal + }; + void SetRangeType(RangeType newRangeType); + virtual void paintEvent(QPaintEvent* event) override; private: @@ -37,6 +44,11 @@ class AttitudeDial : public QWidget { void UpdateRadius(); AttitudeDialPalette Palette; + std::array Range = { -180, 180 }; + RangeType RangeTypeMode = RangeType::CenteredNominal; + QPoint HandEndingLowestNominal() const; + QPoint HandEndingCenteredNominal() const; + std::function RangeHandlerFunction = nullptr; QFont NumericDisplayFont; QLabel* NumericDisplay; From 74a9e0e87a3eab34a96e70d798df34ae849a0356 Mon Sep 17 00:00:00 2001 From: JC Luna Date: Sat, 28 Mar 2026 22:03:21 -0500 Subject: [PATCH 02/18] Anti excessive members --- src/Plotting/Plot2D.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Plotting/Plot2D.cpp b/src/Plotting/Plot2D.cpp index ba62f59..3ab6be4 100644 --- a/src/Plotting/Plot2D.cpp +++ b/src/Plotting/Plot2D.cpp @@ -19,8 +19,8 @@ void EmbeddablePlot2D::AddPoints(uint8_t idx, std::vector& oldTime = Series[idx].Times; std::vector& oldQty = Series[idx].Quantities; - oldTime.resize(oldTime.size() + times.size()); - oldQty.resize(oldQty.size() + quantities.size()); + oldTime.reserve(oldTime.size() + times.size()); + oldQty.reserve(oldQty.size() + quantities.size()); for (double time : times) { oldTime.push_back(time); From f4404e3725fd215b3ee404f2d19019808743d5c9 Mon Sep 17 00:00:00 2001 From: JC Luna Date: Sat, 28 Mar 2026 22:11:47 -0500 Subject: [PATCH 03/18] Fix hand drawing for nominal value at center of range --- src/Widgets/Dial/AttitudeDial.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Widgets/Dial/AttitudeDial.cpp b/src/Widgets/Dial/AttitudeDial.cpp index 51730eb..7e50b88 100644 --- a/src/Widgets/Dial/AttitudeDial.cpp +++ b/src/Widgets/Dial/AttitudeDial.cpp @@ -79,8 +79,8 @@ QPoint AttitudeDial::HandEndingLowestNominal() const { QPoint AttitudeDial::HandEndingCenteredNominal() const { double rangeCtr = (Range[1] - Range[0]) / 2.0; double ang = (CurrentAngle - rangeCtr) * 3.14 / 180.0; - int linex = Radius*std::sin(ang); - int liney = -Radius*std::cos(ang); + int linex = -Radius*std::sin(ang); + int liney = Radius*std::cos(ang); return Origin + QPoint{ linex, liney }; } From f8607d17cb0998a53d3ee674c98aedf6fbbc58fc Mon Sep 17 00:00:00 2001 From: JC Luna Date: Sat, 28 Mar 2026 23:46:44 -0500 Subject: [PATCH 04/18] simple finite diff --- src/Util/FiniteDiff.hpp | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) create mode 100644 src/Util/FiniteDiff.hpp diff --git a/src/Util/FiniteDiff.hpp b/src/Util/FiniteDiff.hpp new file mode 100644 index 0000000..0703d9c --- /dev/null +++ b/src/Util/FiniteDiff.hpp @@ -0,0 +1,18 @@ +#pragma once + +#include +#include + +namespace VSCL::Util { + +template +static constexpr T CenterFiniteDifference(std::array ts, std::array vals) { + static_assert(std::is_floating_point()); + + constexpr double h = (ts[2] - ts[0]) / 2.0; + constexpr double fwd = (vals[2] - vals[1]) / 2.0; + constexpr double bkd = (vals[1] - vals[0]) / 2.0; + + return (fwd - bkd) / h; +} +} // namespace VSCL::Util From 19e5f299a7649d1833da12dd47030e94185285e2 Mon Sep 17 00:00:00 2001 From: JC Luna Date: Sun, 29 Mar 2026 13:20:01 -0500 Subject: [PATCH 05/18] Rate label --- cmake/cpp.cmake | 3 ++- src/Util/FiniteDiff.hpp | 12 ++++------- src/Widgets/Displays/RateLabel.cpp | 34 ++++++++++++++++++++++++++++++ src/Widgets/Displays/RateLabel.hpp | 27 ++++++++++++++++++++++++ 4 files changed, 67 insertions(+), 9 deletions(-) create mode 100644 src/Widgets/Displays/RateLabel.cpp create mode 100644 src/Widgets/Displays/RateLabel.hpp diff --git a/cmake/cpp.cmake b/cmake/cpp.cmake index 2d11b35..2677044 100644 --- a/cmake/cpp.cmake +++ b/cmake/cpp.cmake @@ -21,7 +21,8 @@ set(WIDGET_SOURCES "${WINDOWING_SRC_DIR}/NumericTestWidget.cpp" "${WIDGETS_SRC_DIR}/Displays/QuantitiesRatesDisplay.cpp" "${WIDGETS_SRC_DIR}/Displays/QuantitiesRatesRow.cpp" - "${WIDGETS_SRC_DIR}/Dial/AttitudeDial.cpp") + "${WIDGETS_SRC_DIR}/Dial/AttitudeDial.cpp" + "${WIDGETS_SRC_DIR}/Displays/RateLabel.hpp") set(PLOTTING_SOURCES "${PLOTTING_SRC_DIR}/Plot2D.cpp" diff --git a/src/Util/FiniteDiff.hpp b/src/Util/FiniteDiff.hpp index 0703d9c..4eac491 100644 --- a/src/Util/FiniteDiff.hpp +++ b/src/Util/FiniteDiff.hpp @@ -1,17 +1,13 @@ #pragma once #include -#include namespace VSCL::Util { -template -static constexpr T CenterFiniteDifference(std::array ts, std::array vals) { - static_assert(std::is_floating_point()); - - constexpr double h = (ts[2] - ts[0]) / 2.0; - constexpr double fwd = (vals[2] - vals[1]) / 2.0; - constexpr double bkd = (vals[1] - vals[0]) / 2.0; +static constexpr double CenterFiniteDifference(const std::array& ts, const std::array& qtys) { + double h = (ts[2] - ts[0]) / 2.0; + double fwd = (qtys[2] - qtys[1]) / 2.0; + double bkd = (qtys[1] - qtys[0]) / 2.0; return (fwd - bkd) / h; } diff --git a/src/Widgets/Displays/RateLabel.cpp b/src/Widgets/Displays/RateLabel.cpp new file mode 100644 index 0000000..04bf89f --- /dev/null +++ b/src/Widgets/Displays/RateLabel.cpp @@ -0,0 +1,34 @@ +#include +#include + +#include "RateLabel.hpp" +#include "Util/FiniteDiff.hpp" + +namespace VSCL { + +RateLabel::RateLabel(QWidget* parent) : QLabel(parent) { + SetTextFrom(0.0); + setScaledContents(true); +} + +void RateLabel::SetTextFrom(double num) { + setText(QString::number(num) + QuantityUnitString + TimeUnitString); +} + +void RateLabel::SetRateFromArray(const std::vector& ts, const std::vector& qtys) { + size_t tsz = ts.size(); + size_t qsz = qtys.size(); + + if (tsz < 3) { return; }; + if (qsz < 3) { return; }; + + const std::array tst = { ts[tsz - 1], ts[tsz - 2], ts[tsz - 3] }; + const std::array qst = { qtys[qsz - 1], qtys[qsz - 2], qtys[qsz - 3] }; + Rate = Util::CenterFiniteDifference(tst, qst); +} + +void RateLabel::DisplayRateFromArray(const std::vector& ts, const std::vector& qtys) { + SetRateFromArray(ts, qtys); + SetTextFrom(Rate); +} +} // namespace VSCL diff --git a/src/Widgets/Displays/RateLabel.hpp b/src/Widgets/Displays/RateLabel.hpp new file mode 100644 index 0000000..6c2afdf --- /dev/null +++ b/src/Widgets/Displays/RateLabel.hpp @@ -0,0 +1,27 @@ +#pragma once + +#include + +namespace VSCL { + +/* + * A label that automatically computes and displays a finite difference on an attached array. + */ +class RateLabel : public QLabel { + + Q_OBJECT; + +public: + RateLabel(QWidget* parent); + + void SetTextFrom(double num); + void SetRateFromArray(const std::vector& ts, const std::vector& qtys); + void DisplayRateFromArray(const std::vector& ts, const std::vector& qtys); + +private: + double Rate = 0.0; + QString QuantityUnitString = ""; + QString TimeUnitString = "/s"; + +}; // class RateLabel +} // namespace VSCL From 8694a372077d4538542c4528b36e881e2c73bf49 Mon Sep 17 00:00:00 2001 From: JC Luna Date: Sun, 29 Mar 2026 13:24:32 -0500 Subject: [PATCH 06/18] Rm the dial numeric dispaly --- src/Widgets/Dial/AttitudeDial.cpp | 41 ----------------------------- src/Widgets/Dial/AttitudeDial.hpp | 9 ------- src/Widgets/Displays/RateLabel.cpp | 1 - src/Windowing/WidgetsRecreation.cpp | 6 ++--- 4 files changed, 3 insertions(+), 54 deletions(-) diff --git a/src/Widgets/Dial/AttitudeDial.cpp b/src/Widgets/Dial/AttitudeDial.cpp index 7e50b88..82ec016 100644 --- a/src/Widgets/Dial/AttitudeDial.cpp +++ b/src/Widgets/Dial/AttitudeDial.cpp @@ -9,22 +9,10 @@ namespace VSCL { AttitudeDial::AttitudeDial(QWidget* parent) : QWidget(parent) { - NumericDisplayFont = QFont(); - NumericDisplay = new QLabel(this); - NumericDisplay->setBuddy(this); - NumericDisplay->setAlignment(Qt::AlignCenter); - NumericDisplay->setFrameStyle(QFrame::Panel | QFrame::Raised); - NumericDisplay->setFont(NumericDisplayFont); - NumericDisplay->setStyleSheet(" QLabel { color: white; background-color: black; border-radius: 3% } "); SetRangeType(RangeTypeMode); - update(); } // AttitudeDial ctor -AttitudeDial::AttitudeDial(QWidget* parent, bool showNumericDisplay) : AttitudeDial(parent) { - SetNumericDisplayState(showNumericDisplay); -} - void AttitudeDial::SetDialAngle(double value) { CurrentAngle = value; update(); @@ -44,30 +32,6 @@ void AttitudeDial::UpdateOrigin() { Origin = { curSize.width() / 2, curSize.height() / 2 }; } -void AttitudeDial::UpdateNumericDisplay() { - NumericDisplay->setText(QString::number(CurrentAngle) + "°"); - - int w = int(0.2*Radius); - int h = int(0.1*Radius); - - NumericDisplay->setFixedSize(w, h); - NumericDisplay->move(Origin - QPoint{ w / 2 , h / 2 }); -} // void AttitudeDial::UpdateNumericDisplay() - -void AttitudeDial::UpdateNumericFont() { - int pts = Radius / 20; - pts = (pts < 1) ? 1 : pts; - - NumericDisplayFont.setPointSize(pts); - NumericDisplay->setFont(NumericDisplayFont); -} // void AttitudeDial::UpdateNumericDisplay() - -void AttitudeDial::SetNumericDisplayState(bool enabled) { - NumericDisplayEnabled = enabled; - NumericDisplay->setVisible(enabled); - update(); -} // void AttitudeDial::UpdateNumericDisplay() - QPoint AttitudeDial::HandEndingLowestNominal() const { double ang = (CurrentAngle - Range[0]) * 3.14 / 180.0; int linex = Radius*std::sin(ang); @@ -178,10 +142,5 @@ void AttitudeDial::paintEvent(QPaintEvent* event) { PaintTicks(&painter); PaintHand(&painter); PaintCap(&painter); - - if (NumericDisplayEnabled) { - UpdateNumericDisplay(); - UpdateNumericFont(); - } } } // namespace VSCL diff --git a/src/Widgets/Dial/AttitudeDial.hpp b/src/Widgets/Dial/AttitudeDial.hpp index 7da53cb..63a2081 100644 --- a/src/Widgets/Dial/AttitudeDial.hpp +++ b/src/Widgets/Dial/AttitudeDial.hpp @@ -19,11 +19,8 @@ class AttitudeDial : public QWidget { public: AttitudeDial(QWidget* parent); - AttitudeDial(QWidget* parent, bool enabled); void SetDialAngle(double value); - void SetNumericDisplayState(bool enabled); - void SetPalette(AttitudeDialPalette& newPalette); AttitudeDialPalette GetPalette() const; const AttitudeDialPalette& GetPaletteView() const; @@ -50,12 +47,6 @@ class AttitudeDial : public QWidget { QPoint HandEndingCenteredNominal() const; std::function RangeHandlerFunction = nullptr; - QFont NumericDisplayFont; - QLabel* NumericDisplay; - bool NumericDisplayEnabled = true; - void UpdateNumericFont(); - void UpdateNumericDisplay(); - void PaintCircularBacking(QPainter* painter); void PaintTicks(QPainter* painter); void PaintHand(QPainter* painter); diff --git a/src/Widgets/Displays/RateLabel.cpp b/src/Widgets/Displays/RateLabel.cpp index 04bf89f..aa97a98 100644 --- a/src/Widgets/Displays/RateLabel.cpp +++ b/src/Widgets/Displays/RateLabel.cpp @@ -5,7 +5,6 @@ #include "Util/FiniteDiff.hpp" namespace VSCL { - RateLabel::RateLabel(QWidget* parent) : QLabel(parent) { SetTextFrom(0.0); setScaledContents(true); diff --git a/src/Windowing/WidgetsRecreation.cpp b/src/Windowing/WidgetsRecreation.cpp index 4a8ef19..aa90f35 100644 --- a/src/Windowing/WidgetsRecreation.cpp +++ b/src/Windowing/WidgetsRecreation.cpp @@ -122,13 +122,13 @@ void Widgets::SetupAttitudeDials() { dialsPolicy.setVerticalPolicy(QSizePolicy::MinimumExpanding); AttitudeDialRow->setSizePolicy(dialsPolicy); - RollDial = new AttitudeDial(AttitudeDialRow, false); + RollDial = new AttitudeDial(AttitudeDialRow); AttitudeDialOrganizer->addWidget(RollDial); - PitchDial = new AttitudeDial(AttitudeDialRow, false); + PitchDial = new AttitudeDial(AttitudeDialRow); AttitudeDialOrganizer->addWidget(PitchDial); - YawDial = new AttitudeDial(AttitudeDialRow, false); + YawDial = new AttitudeDial(AttitudeDialRow); AttitudeDialOrganizer->addWidget(YawDial); Dials = { RollDial, PitchDial, YawDial }; From b9599fe02876388865effa137f86fa7d26ee5b9f Mon Sep 17 00:00:00 2001 From: JC Luna Date: Sun, 29 Mar 2026 13:49:49 -0500 Subject: [PATCH 07/18] Less ticks, all at 45 deg intervals --- src/Widgets/Dial/AttitudeDial.cpp | 24 +++++++++++++----------- src/Widgets/Dial/AttitudeDial.hpp | 21 +++++++++------------ 2 files changed, 22 insertions(+), 23 deletions(-) diff --git a/src/Widgets/Dial/AttitudeDial.cpp b/src/Widgets/Dial/AttitudeDial.cpp index 82ec016..a70557e 100644 --- a/src/Widgets/Dial/AttitudeDial.cpp +++ b/src/Widgets/Dial/AttitudeDial.cpp @@ -76,33 +76,35 @@ void AttitudeDial::PaintCircularBacking(QPainter* painter) { } // void AttitudeDial::PaintCircularBacking() void AttitudeDial::PaintTicks(QPainter* painter) { - for (int i = 0; i < 12; i++) { - QPoint st, ed; + for (int i = 0; i < 8; i++) { QColor tickcolor; - const double ci = Radius*Cos30Degs[i]; - const double si = Radius*Sin30Degs[i]; - double ticker[2] = { 0.0, 1.0 }; + std::array ticker = { 0.0, 1.0 }; + std::array cossin; switch (i) { case 0: - case 3: - case 6: - case 9: // major + case 1: + case 2: + case 3: // major ticker[0] = 0.85; tickcolor = Palette.MajorTick; + cossin = MajorTicks[i]; break; default: // minor ticker[0] = 0.95; tickcolor = Palette.MinorTick; + cossin = MinorTicks[i - 4]; break; } - st = Origin + ticker[0] * QPoint{ int(ci), int(si) }; - ed = Origin + ticker[1] * QPoint{ int(ci), int(si) }; - + qDebug() << cossin; + double ci = Radius * cossin[0]; + double si = Radius * cossin[1]; QPen pen = painter->pen(); pen.setColor(tickcolor); + QPoint st = Origin + ticker[0] * QPoint{ int(ci), int(si) }; + QPoint ed = Origin + ticker[1] * QPoint{ int(ci), int(si) }; painter->setPen(pen); painter->drawLine(st, ed); } diff --git a/src/Widgets/Dial/AttitudeDial.hpp b/src/Widgets/Dial/AttitudeDial.hpp index 63a2081..4d81b13 100644 --- a/src/Widgets/Dial/AttitudeDial.hpp +++ b/src/Widgets/Dial/AttitudeDial.hpp @@ -7,10 +7,10 @@ namespace VSCL { struct AttitudeDialPalette { QColor Primary = QColorConstants::White; - QColor Hand = QColorConstants::Black; + QColor Hand = QColorConstants::Red; QColor Cap = QColorConstants::Black; QColor MajorTick = QColorConstants::DarkGray; - QColor MinorTick = QColorConstants::DarkGray; + QColor MinorTick = QColorConstants::LightGray; }; class AttitudeDial : public QWidget { @@ -52,16 +52,13 @@ class AttitudeDial : public QWidget { void PaintHand(QPainter* painter); void PaintCap(QPainter* painter); - static constexpr std::array Cos30Degs = { - 1.0, 0.8660254037844387, 0.5, 0.0, - -0.5, -0.8660254037844387, -1.0, -0.8660254037844387, - -0.5, 0.0, 0.5, 0.8660254037844387 - }; - static constexpr std::array Sin30Degs = { - 0.0, 0.5, 0.8660254037844387, 1.0, - 0.8660254037844387, 0.5, 0.0, -0.5, - -0.8660254037844387, -1.0, -0.8660254037844387, -0.5 - }; + static constexpr std::array, 4> MajorTicks = {{ + { 1.0, 0.0 }, { 0.0, 1.0 }, { -1.0, 0.0 }, { 0.0, -1.0 } + }}; + static constexpr std::array, 4> MinorTicks = {{ + { 0.7071067811865475, 0.7071067811865475 }, { 0.7071067811865475, -0.7071067811865475 }, + { -0.7071067811865475, -0.7071067811865475 }, { -0.7071067811865475, 0.7071067811865475 } + }}; }; // class AttitudeDial } // namespace VSCL From 0b640b47b0559e4fd564363ba1026c73496971c1 Mon Sep 17 00:00:00 2001 From: JC Luna Date: Sun, 29 Mar 2026 14:17:47 -0500 Subject: [PATCH 08/18] Shorter dial sources names --- cmake/cpp.cmake | 18 ++++++++++++++---- .../Dial/{AttitudeDial.cpp => Attitude.cpp} | 7 +------ .../Dial/{AttitudeDial.hpp => Attitude.hpp} | 0 src/Widgets/Dial/Composite.cpp | 5 +++++ src/Widgets/Dial/Composite.hpp | 5 +++++ src/Windowing/DevWindow.cpp | 2 +- src/Windowing/WidgetsRecreation.hpp | 2 +- 7 files changed, 27 insertions(+), 12 deletions(-) rename src/Widgets/Dial/{AttitudeDial.cpp => Attitude.cpp} (97%) rename src/Widgets/Dial/{AttitudeDial.hpp => Attitude.hpp} (100%) create mode 100644 src/Widgets/Dial/Composite.cpp create mode 100644 src/Widgets/Dial/Composite.hpp diff --git a/cmake/cpp.cmake b/cmake/cpp.cmake index 2677044..bd0d9e6 100644 --- a/cmake/cpp.cmake +++ b/cmake/cpp.cmake @@ -1,6 +1,6 @@ # # This file is for: -# - Encapsulating some platform differences +# - Encapsulating some platform and compiler differences # - Source declaration # - Qt6 dependency declaration # @@ -16,14 +16,24 @@ set(APP_SOURCES set(OTHER_APP_SOURCES "${CMAKE_SOURCE_DIR}/src/App/Recreation.cpp") -set(WIDGET_SOURCES +set(WINDOWING_SOURCES "${WINDOWING_SRC_DIR}/DevWindow.cpp" - "${WINDOWING_SRC_DIR}/NumericTestWidget.cpp" + "${WINDOWING_SRC_DIR}/NumericTestWidget.cpp") + +set(DIAL_SOURCES + "${WIDGETS_SRC_DIR}/Dial/Attitude.cpp" + "${WIDGETS_SRC_DIR}/Dial/Composite.cpp") + +set(DISPLAYER_SOURCES "${WIDGETS_SRC_DIR}/Displays/QuantitiesRatesDisplay.cpp" "${WIDGETS_SRC_DIR}/Displays/QuantitiesRatesRow.cpp" - "${WIDGETS_SRC_DIR}/Dial/AttitudeDial.cpp" "${WIDGETS_SRC_DIR}/Displays/RateLabel.hpp") +set(WIDGET_SOURCES + ${WINDOWING_SOURCES} + ${DIAL_SOURCES} + ${DISPLAYER_SOURCES}) + set(PLOTTING_SOURCES "${PLOTTING_SRC_DIR}/Plot2D.cpp" "${PLOTTING_SRC_DIR}/Container.cpp") diff --git a/src/Widgets/Dial/AttitudeDial.cpp b/src/Widgets/Dial/Attitude.cpp similarity index 97% rename from src/Widgets/Dial/AttitudeDial.cpp rename to src/Widgets/Dial/Attitude.cpp index a70557e..022f309 100644 --- a/src/Widgets/Dial/AttitudeDial.cpp +++ b/src/Widgets/Dial/Attitude.cpp @@ -1,10 +1,6 @@ #include #include - -#include -#include - -#include "AttitudeDial.hpp" +#include "Attitude.hpp" namespace VSCL { @@ -97,7 +93,6 @@ void AttitudeDial::PaintTicks(QPainter* painter) { break; } - qDebug() << cossin; double ci = Radius * cossin[0]; double si = Radius * cossin[1]; QPen pen = painter->pen(); diff --git a/src/Widgets/Dial/AttitudeDial.hpp b/src/Widgets/Dial/Attitude.hpp similarity index 100% rename from src/Widgets/Dial/AttitudeDial.hpp rename to src/Widgets/Dial/Attitude.hpp diff --git a/src/Widgets/Dial/Composite.cpp b/src/Widgets/Dial/Composite.cpp new file mode 100644 index 0000000..6b76a0c --- /dev/null +++ b/src/Widgets/Dial/Composite.cpp @@ -0,0 +1,5 @@ +#include "Composite.hpp" + +namespace VSCL { + +} // namespace VSCL diff --git a/src/Widgets/Dial/Composite.hpp b/src/Widgets/Dial/Composite.hpp new file mode 100644 index 0000000..bfb57b3 --- /dev/null +++ b/src/Widgets/Dial/Composite.hpp @@ -0,0 +1,5 @@ +#pragma once + +namespace VSCL { + +} // namespace VSCL diff --git a/src/Windowing/DevWindow.cpp b/src/Windowing/DevWindow.cpp index 5f10c8b..ba95777 100644 --- a/src/Windowing/DevWindow.cpp +++ b/src/Windowing/DevWindow.cpp @@ -3,7 +3,7 @@ #include #include "DevWindow.hpp" -#include "Dial/AttitudeDial.hpp" +#include "Dial/Attitude.hpp" namespace VSCL { DevWindow::DevWindow() { diff --git a/src/Windowing/WidgetsRecreation.hpp b/src/Windowing/WidgetsRecreation.hpp index 29c2683..a3a40e6 100644 --- a/src/Windowing/WidgetsRecreation.hpp +++ b/src/Windowing/WidgetsRecreation.hpp @@ -3,7 +3,7 @@ #include #include -#include "Widgets/Dial/AttitudeDial.hpp" +#include "Widgets/Dial/Attitude.hpp" #include "Widgets/Displays/QuantitiesRatesDisplay.hpp" #include "Widgets/Displays/QuantitiesRatesRow.hpp" #include "Plotting/Container.hpp" From 9fca5377c605ad0de21d9302e4147c72cd08148b Mon Sep 17 00:00:00 2001 From: JC Luna Date: Sun, 29 Mar 2026 14:53:37 -0500 Subject: [PATCH 09/18] Composite dial combining multiple widgets --- cmake/cpp.cmake | 2 +- src/Widgets/Dial/Composite.cpp | 28 ++++++++++++++++++++++++++++ src/Widgets/Dial/Composite.hpp | 29 +++++++++++++++++++++++++++++ src/Windowing/WidgetsRecreation.cpp | 6 +++--- src/Windowing/WidgetsRecreation.hpp | 10 +++++----- 5 files changed, 66 insertions(+), 9 deletions(-) diff --git a/cmake/cpp.cmake b/cmake/cpp.cmake index bd0d9e6..8a3e41b 100644 --- a/cmake/cpp.cmake +++ b/cmake/cpp.cmake @@ -27,7 +27,7 @@ set(DIAL_SOURCES set(DISPLAYER_SOURCES "${WIDGETS_SRC_DIR}/Displays/QuantitiesRatesDisplay.cpp" "${WIDGETS_SRC_DIR}/Displays/QuantitiesRatesRow.cpp" - "${WIDGETS_SRC_DIR}/Displays/RateLabel.hpp") + "${WIDGETS_SRC_DIR}/Displays/RateLabel.cpp") set(WIDGET_SOURCES ${WINDOWING_SOURCES} diff --git a/src/Widgets/Dial/Composite.cpp b/src/Widgets/Dial/Composite.cpp index 6b76a0c..cf8592b 100644 --- a/src/Widgets/Dial/Composite.cpp +++ b/src/Widgets/Dial/Composite.cpp @@ -2,4 +2,32 @@ namespace VSCL { +CompositeDial::CompositeDial(QWidget* parent) : QWidget(parent) { + DialNameLabel = new class QLabel(this); + Dial = new class AttitudeDial(this); + RateLabel = new class RateLabel(this); + + DialNameLabel->setText("Dial"); + + Organizer = new class QGridLayout(this); + setLayout(Organizer); + + Organizer->addWidget(DialNameLabel, 0, 0); + Organizer->addWidget(Dial, 1, 0); + Organizer->addWidget(RateLabel, 1, 0); +} + +CompositeDial::CompositeDial(const QString& title, QWidget* parent) + : CompositeDial(parent) { + DialNameLabel->setText(title); +} + +// Wrap accessors and settors around child widgets {{{ +void CompositeDial::SetDialTitle(const QString& title) { DialNameLabel->setText(title); } +void CompositeDial::SetDialAngle(double value) { Dial->SetDialAngle(value); } +void CompositeDial::DisplayRateFromArray( + const std::vector& ts, const std::vector& qtys) { + RateLabel->DisplayRateFromArray(ts, qtys); } +// }}} } // namespace VSCL +// vim: foldmethod=marker diff --git a/src/Widgets/Dial/Composite.hpp b/src/Widgets/Dial/Composite.hpp index bfb57b3..1d9d879 100644 --- a/src/Widgets/Dial/Composite.hpp +++ b/src/Widgets/Dial/Composite.hpp @@ -1,5 +1,34 @@ #pragma once +#include +#include + +#include "Dial/Attitude.hpp" +#include "Displays/RateLabel.hpp" + namespace VSCL { +/* + * Composite dial combines multiple elements together: + * Base dial, title, and rate display + */ +class CompositeDial : public QWidget { + + Q_OBJECT; + +public: + CompositeDial(QWidget* parent); + CompositeDial(const QString& title, QWidget* parent); + + void SetDialTitle(const QString& title); + void SetDialAngle(double value); + void DisplayRateFromArray(const std::vector& ts, const std::vector& qtys); + +private: + QGridLayout* Organizer; + QLabel* DialNameLabel; + AttitudeDial* Dial; + RateLabel* RateLabel; + +}; // class CompositeDial } // namespace VSCL diff --git a/src/Windowing/WidgetsRecreation.cpp b/src/Windowing/WidgetsRecreation.cpp index aa90f35..63d7f17 100644 --- a/src/Windowing/WidgetsRecreation.cpp +++ b/src/Windowing/WidgetsRecreation.cpp @@ -122,13 +122,13 @@ void Widgets::SetupAttitudeDials() { dialsPolicy.setVerticalPolicy(QSizePolicy::MinimumExpanding); AttitudeDialRow->setSizePolicy(dialsPolicy); - RollDial = new AttitudeDial(AttitudeDialRow); + RollDial = new CompositeDial(AttitudeDialRow); AttitudeDialOrganizer->addWidget(RollDial); - PitchDial = new AttitudeDial(AttitudeDialRow); + PitchDial = new CompositeDial(AttitudeDialRow); AttitudeDialOrganizer->addWidget(PitchDial); - YawDial = new AttitudeDial(AttitudeDialRow); + YawDial = new CompositeDial(AttitudeDialRow); AttitudeDialOrganizer->addWidget(YawDial); Dials = { RollDial, PitchDial, YawDial }; diff --git a/src/Windowing/WidgetsRecreation.hpp b/src/Windowing/WidgetsRecreation.hpp index a3a40e6..49d2768 100644 --- a/src/Windowing/WidgetsRecreation.hpp +++ b/src/Windowing/WidgetsRecreation.hpp @@ -3,7 +3,7 @@ #include #include -#include "Widgets/Dial/Attitude.hpp" +#include "Widgets/Dial/Composite.hpp" #include "Widgets/Displays/QuantitiesRatesDisplay.hpp" #include "Widgets/Displays/QuantitiesRatesRow.hpp" #include "Plotting/Container.hpp" @@ -35,10 +35,10 @@ class Widgets : public QMainWindow { QFrame* AttitudeDialRow; QHBoxLayout* AttitudeDialOrganizer; - AttitudeDial* RollDial; - AttitudeDial* PitchDial; - AttitudeDial* YawDial; - std::array Dials; + CompositeDial* RollDial; + CompositeDial* PitchDial; + CompositeDial* YawDial; + std::array Dials; void SetupAttitudeDials(); Plot::EmbeddablePlot2D* Plot; From 79ef34aeb3bf1587c0fbf9bdbb387b906b19062a Mon Sep 17 00:00:00 2001 From: JC Luna Date: Sun, 29 Mar 2026 15:00:38 -0500 Subject: [PATCH 10/18] rate label member rename --- src/Widgets/Dial/Composite.cpp | 12 ++++++------ src/Widgets/Dial/Composite.hpp | 2 +- src/Windowing/WidgetsRecreation.cpp | 6 +++--- 3 files changed, 10 insertions(+), 10 deletions(-) diff --git a/src/Widgets/Dial/Composite.cpp b/src/Widgets/Dial/Composite.cpp index cf8592b..0488b4c 100644 --- a/src/Widgets/Dial/Composite.cpp +++ b/src/Widgets/Dial/Composite.cpp @@ -3,18 +3,18 @@ namespace VSCL { CompositeDial::CompositeDial(QWidget* parent) : QWidget(parent) { - DialNameLabel = new class QLabel(this); - Dial = new class AttitudeDial(this); - RateLabel = new class RateLabel(this); + DialNameLabel = new QLabel(this); + Dial = new AttitudeDial(this); + NumericRateLabel = new RateLabel(this); DialNameLabel->setText("Dial"); - Organizer = new class QGridLayout(this); + Organizer = new QGridLayout(this); setLayout(Organizer); Organizer->addWidget(DialNameLabel, 0, 0); Organizer->addWidget(Dial, 1, 0); - Organizer->addWidget(RateLabel, 1, 0); + Organizer->addWidget(NumericRateLabel, 1, 0); } CompositeDial::CompositeDial(const QString& title, QWidget* parent) @@ -27,7 +27,7 @@ void CompositeDial::SetDialTitle(const QString& title) { DialNameLabel->setText( void CompositeDial::SetDialAngle(double value) { Dial->SetDialAngle(value); } void CompositeDial::DisplayRateFromArray( const std::vector& ts, const std::vector& qtys) { - RateLabel->DisplayRateFromArray(ts, qtys); } + NumericRateLabel->DisplayRateFromArray(ts, qtys); } // }}} } // namespace VSCL // vim: foldmethod=marker diff --git a/src/Widgets/Dial/Composite.hpp b/src/Widgets/Dial/Composite.hpp index 1d9d879..fc2094c 100644 --- a/src/Widgets/Dial/Composite.hpp +++ b/src/Widgets/Dial/Composite.hpp @@ -28,7 +28,7 @@ class CompositeDial : public QWidget { QGridLayout* Organizer; QLabel* DialNameLabel; AttitudeDial* Dial; - RateLabel* RateLabel; + RateLabel* NumericRateLabel; }; // class CompositeDial } // namespace VSCL diff --git a/src/Windowing/WidgetsRecreation.cpp b/src/Windowing/WidgetsRecreation.cpp index 63d7f17..71eccd4 100644 --- a/src/Windowing/WidgetsRecreation.cpp +++ b/src/Windowing/WidgetsRecreation.cpp @@ -122,13 +122,13 @@ void Widgets::SetupAttitudeDials() { dialsPolicy.setVerticalPolicy(QSizePolicy::MinimumExpanding); AttitudeDialRow->setSizePolicy(dialsPolicy); - RollDial = new CompositeDial(AttitudeDialRow); + RollDial = new CompositeDial(tr("Roll"), AttitudeDialRow); AttitudeDialOrganizer->addWidget(RollDial); - PitchDial = new CompositeDial(AttitudeDialRow); + PitchDial = new CompositeDial(tr("Pitch"), AttitudeDialRow); AttitudeDialOrganizer->addWidget(PitchDial); - YawDial = new CompositeDial(AttitudeDialRow); + YawDial = new CompositeDial(tr("Yaw"), AttitudeDialRow); AttitudeDialOrganizer->addWidget(YawDial); Dials = { RollDial, PitchDial, YawDial }; From 36df484c9c153175388f00bac46c40777e124a01 Mon Sep 17 00:00:00 2001 From: JC Luna Date: Sun, 29 Mar 2026 16:56:16 -0500 Subject: [PATCH 11/18] Rate label above dial --- src/Widgets/Dial/Composite.cpp | 40 +++++++++++++++++++++++------ src/Widgets/Dial/Composite.hpp | 4 ++- src/Windowing/WidgetsRecreation.cpp | 6 ++--- 3 files changed, 38 insertions(+), 12 deletions(-) diff --git a/src/Widgets/Dial/Composite.cpp b/src/Widgets/Dial/Composite.cpp index 0488b4c..d6036e6 100644 --- a/src/Widgets/Dial/Composite.cpp +++ b/src/Widgets/Dial/Composite.cpp @@ -3,18 +3,42 @@ namespace VSCL { CompositeDial::CompositeDial(QWidget* parent) : QWidget(parent) { + // Child widget setup goes top -> bottom level + + MajorOrganizer = new QGridLayout(this); + this->setLayout(MajorOrganizer); + DialNameLabel = new QLabel(this); - Dial = new AttitudeDial(this); - NumericRateLabel = new RateLabel(this); + DialRateDuo = new QWidget(this); DialNameLabel->setText("Dial"); + DialNameLabel->setScaledContents(true); + + MajorOrganizer->addWidget(DialNameLabel, 0, 0, 1, 1); + MajorOrganizer->addWidget(DialRateDuo, 1, 0, 5, 1); + + DuoOrganizer = new QGridLayout(DialRateDuo); + DialRateDuo->setLayout(DuoOrganizer); + + Dial = new AttitudeDial(DialRateDuo); + NumericRateLabel = new RateLabel(DialRateDuo); + + DuoOrganizer->addWidget(Dial, 0, 0); + DuoOrganizer->addWidget(NumericRateLabel, 0, 0); + + QSizePolicy expandPolicy(QSizePolicy::MinimumExpanding, QSizePolicy::MinimumExpanding); + this->setSizePolicy(expandPolicy); + DialRateDuo->setSizePolicy(expandPolicy); + Dial->setSizePolicy(expandPolicy); + DialNameLabel->setSizePolicy(expandPolicy); - Organizer = new QGridLayout(this); - setLayout(Organizer); + MajorOrganizer->setAlignment(Qt::AlignHCenter); + MajorOrganizer->setAlignment(DialNameLabel, Qt::AlignHCenter | Qt::AlignTop); + //MajorOrganizer->setAlignment(DialRateDuo, Qt::AlignHCenter); - Organizer->addWidget(DialNameLabel, 0, 0); - Organizer->addWidget(Dial, 1, 0); - Organizer->addWidget(NumericRateLabel, 1, 0); + //DuoOrganizer->setAlignment(Qt::AlignHCenter); + //DuoOrganizer->setAlignment(Dial,Qt::AlignHCenter); + DuoOrganizer->setAlignment(NumericRateLabel, Qt::AlignHCenter); } CompositeDial::CompositeDial(const QString& title, QWidget* parent) @@ -22,7 +46,7 @@ CompositeDial::CompositeDial(const QString& title, QWidget* parent) DialNameLabel->setText(title); } -// Wrap accessors and settors around child widgets {{{ +// Wrap accessors and settors of child widgets {{{ void CompositeDial::SetDialTitle(const QString& title) { DialNameLabel->setText(title); } void CompositeDial::SetDialAngle(double value) { Dial->SetDialAngle(value); } void CompositeDial::DisplayRateFromArray( diff --git a/src/Widgets/Dial/Composite.hpp b/src/Widgets/Dial/Composite.hpp index fc2094c..36b6588 100644 --- a/src/Widgets/Dial/Composite.hpp +++ b/src/Widgets/Dial/Composite.hpp @@ -25,8 +25,10 @@ class CompositeDial : public QWidget { void DisplayRateFromArray(const std::vector& ts, const std::vector& qtys); private: - QGridLayout* Organizer; + QGridLayout* MajorOrganizer; + QGridLayout* DuoOrganizer; QLabel* DialNameLabel; + QWidget* DialRateDuo; AttitudeDial* Dial; RateLabel* NumericRateLabel; diff --git a/src/Windowing/WidgetsRecreation.cpp b/src/Windowing/WidgetsRecreation.cpp index 71eccd4..9c7958a 100644 --- a/src/Windowing/WidgetsRecreation.cpp +++ b/src/Windowing/WidgetsRecreation.cpp @@ -122,13 +122,13 @@ void Widgets::SetupAttitudeDials() { dialsPolicy.setVerticalPolicy(QSizePolicy::MinimumExpanding); AttitudeDialRow->setSizePolicy(dialsPolicy); - RollDial = new CompositeDial(tr("Roll"), AttitudeDialRow); + RollDial = new CompositeDial(QString("Roll"), AttitudeDialRow); AttitudeDialOrganizer->addWidget(RollDial); - PitchDial = new CompositeDial(tr("Pitch"), AttitudeDialRow); + PitchDial = new CompositeDial(QString("Pitch"), AttitudeDialRow); AttitudeDialOrganizer->addWidget(PitchDial); - YawDial = new CompositeDial(tr("Yaw"), AttitudeDialRow); + YawDial = new CompositeDial(QString("Yaw"), AttitudeDialRow); AttitudeDialOrganizer->addWidget(YawDial); Dials = { RollDial, PitchDial, YawDial }; From 6fa30cd4b337d02361953f22cbfb333a47ff30cf Mon Sep 17 00:00:00 2001 From: JC Luna Date: Sun, 29 Mar 2026 17:26:08 -0500 Subject: [PATCH 12/18] Rate label styling --- src/Util/Sizing.hpp | 15 ++++++++++++--- src/Widgets/Dial/Composite.cpp | 6 +----- src/Widgets/Displays/RateLabel.cpp | 18 +++++++++++++++++- src/Widgets/Displays/RateLabel.hpp | 5 +++++ style/RateLabel.qss | 0 5 files changed, 35 insertions(+), 9 deletions(-) create mode 100644 style/RateLabel.qss diff --git a/src/Util/Sizing.hpp b/src/Util/Sizing.hpp index 0e415c7..bc8f56f 100644 --- a/src/Util/Sizing.hpp +++ b/src/Util/Sizing.hpp @@ -4,12 +4,21 @@ namespace VSCL::Util { -constexpr int MinimumWidth = 720; -constexpr int MinimumHeight = 480; +static constexpr int MinimumWidth = 720; +static constexpr int MinimumHeight = 480; struct FontAdjustment { - int PointSizeAtMinimum; + /* + * The point size at the window's minimum resolution. + */ + unsigned int PointSizeAtMinimum = 12; + + /* + * When true, adjust to the width of the window. + * When false, adjust to the height of the window. + */ bool AdjustToWidth = false; + const int AdjustPointSize(QWidget* win) const { return PointSizeAtMinimum + ((AdjustToWidth) ? diff --git a/src/Widgets/Dial/Composite.cpp b/src/Widgets/Dial/Composite.cpp index d6036e6..afd2ef5 100644 --- a/src/Widgets/Dial/Composite.cpp +++ b/src/Widgets/Dial/Composite.cpp @@ -30,15 +30,11 @@ CompositeDial::CompositeDial(QWidget* parent) : QWidget(parent) { this->setSizePolicy(expandPolicy); DialRateDuo->setSizePolicy(expandPolicy); Dial->setSizePolicy(expandPolicy); - DialNameLabel->setSizePolicy(expandPolicy); MajorOrganizer->setAlignment(Qt::AlignHCenter); MajorOrganizer->setAlignment(DialNameLabel, Qt::AlignHCenter | Qt::AlignTop); - //MajorOrganizer->setAlignment(DialRateDuo, Qt::AlignHCenter); - //DuoOrganizer->setAlignment(Qt::AlignHCenter); - //DuoOrganizer->setAlignment(Dial,Qt::AlignHCenter); - DuoOrganizer->setAlignment(NumericRateLabel, Qt::AlignHCenter); + DuoOrganizer->setAlignment(NumericRateLabel, Qt::AlignHCenter | Qt::AlignVCenter); } CompositeDial::CompositeDial(const QString& title, QWidget* parent) diff --git a/src/Widgets/Displays/RateLabel.cpp b/src/Widgets/Displays/RateLabel.cpp index aa97a98..0b6e286 100644 --- a/src/Widgets/Displays/RateLabel.cpp +++ b/src/Widgets/Displays/RateLabel.cpp @@ -7,7 +7,23 @@ namespace VSCL { RateLabel::RateLabel(QWidget* parent) : QLabel(parent) { SetTextFrom(0.0); - setScaledContents(true); + setFrameStyle(QFrame::StyledPanel | QFrame::Plain); + setStyleSheet("background-color: white;" + "color: black;" + "font: bold;" + "margin: 2%;" + "border-style: outset;" + "border-color: black;" + "border-width: 1%;" + "border-radius: 5%;" + "padding: 1%;"); + + Font.setPointSize(FontAdjustment.PointSizeAtMinimum); + setFont(Font); +} + +void RateLabel::resizeEvent(QResizeEvent* event) { + Font.setPointSize(FontAdjustment.AdjustPointSize(window())); } void RateLabel::SetTextFrom(double num) { diff --git a/src/Widgets/Displays/RateLabel.hpp b/src/Widgets/Displays/RateLabel.hpp index 6c2afdf..13fcbd0 100644 --- a/src/Widgets/Displays/RateLabel.hpp +++ b/src/Widgets/Displays/RateLabel.hpp @@ -1,6 +1,7 @@ #pragma once #include +#include "Util/Sizing.hpp" namespace VSCL { @@ -13,6 +14,7 @@ class RateLabel : public QLabel { public: RateLabel(QWidget* parent); + virtual void resizeEvent(QResizeEvent* event) override; void SetTextFrom(double num); void SetRateFromArray(const std::vector& ts, const std::vector& qtys); @@ -23,5 +25,8 @@ class RateLabel : public QLabel { QString QuantityUnitString = ""; QString TimeUnitString = "/s"; + Util::FontAdjustment FontAdjustment{ 10, true }; + QFont Font{}; + }; // class RateLabel } // namespace VSCL diff --git a/style/RateLabel.qss b/style/RateLabel.qss new file mode 100644 index 0000000..e69de29 From 8054d24b06f0fa907b9c056cd340c3fd2a1a1338 Mon Sep 17 00:00:00 2001 From: JC Luna Date: Sun, 29 Mar 2026 23:32:33 -0500 Subject: [PATCH 13/18] Call super class resize events --- src/Widgets/Dial/Composite.cpp | 4 ++++ src/Widgets/Dial/Composite.hpp | 12 +++++++++--- src/Widgets/Displays/QuantitiesRatesRow.cpp | 1 + src/Widgets/Displays/RateLabel.cpp | 1 + src/Windowing/WidgetsRecreation.cpp | 2 ++ 5 files changed, 17 insertions(+), 3 deletions(-) diff --git a/src/Widgets/Dial/Composite.cpp b/src/Widgets/Dial/Composite.cpp index afd2ef5..78b0cd1 100644 --- a/src/Widgets/Dial/Composite.cpp +++ b/src/Widgets/Dial/Composite.cpp @@ -42,6 +42,10 @@ CompositeDial::CompositeDial(const QString& title, QWidget* parent) DialNameLabel->setText(title); } +void CompositeDial::resizeEvent(QResizeEvent* event) { + QWidget::resizeEvent(event); +} + // Wrap accessors and settors of child widgets {{{ void CompositeDial::SetDialTitle(const QString& title) { DialNameLabel->setText(title); } void CompositeDial::SetDialAngle(double value) { Dial->SetDialAngle(value); } diff --git a/src/Widgets/Dial/Composite.hpp b/src/Widgets/Dial/Composite.hpp index 36b6588..442cdea 100644 --- a/src/Widgets/Dial/Composite.hpp +++ b/src/Widgets/Dial/Composite.hpp @@ -5,12 +5,13 @@ #include "Dial/Attitude.hpp" #include "Displays/RateLabel.hpp" +#include "Util/Sizing.hpp" namespace VSCL { /* - * Composite dial combines multiple elements together: - * Base dial, title, and rate display + * @brief The composite dial combines multiple elements together: + * A base dial, title, and rate display. */ class CompositeDial : public QWidget { @@ -19,6 +20,7 @@ class CompositeDial : public QWidget { public: CompositeDial(QWidget* parent); CompositeDial(const QString& title, QWidget* parent); + virtual void resizeEvent(QResizeEvent* event) override; void SetDialTitle(const QString& title); void SetDialAngle(double value); @@ -26,11 +28,15 @@ class CompositeDial : public QWidget { private: QGridLayout* MajorOrganizer; - QGridLayout* DuoOrganizer; QLabel* DialNameLabel; + Util::FontAdjustment TitleAdjustment{ .PointSizeAtMinimum = 20, .AdjustToWidth = false }; + + QGridLayout* DuoOrganizer; QWidget* DialRateDuo; AttitudeDial* Dial; RateLabel* NumericRateLabel; + double RateLimitHz = 1.0; + }; // class CompositeDial } // namespace VSCL diff --git a/src/Widgets/Displays/QuantitiesRatesRow.cpp b/src/Widgets/Displays/QuantitiesRatesRow.cpp index eb4800c..1b5525e 100644 --- a/src/Widgets/Displays/QuantitiesRatesRow.cpp +++ b/src/Widgets/Displays/QuantitiesRatesRow.cpp @@ -23,6 +23,7 @@ QtyRateRow::QtyRateRow(const QString& title, QtyRateDisplay* parent) : QGroupBox } void QtyRateRow::resizeEvent(QResizeEvent* event) { + QGroupBox::resizeEvent(event); AdjustFontSize(); } diff --git a/src/Widgets/Displays/RateLabel.cpp b/src/Widgets/Displays/RateLabel.cpp index 0b6e286..daa4238 100644 --- a/src/Widgets/Displays/RateLabel.cpp +++ b/src/Widgets/Displays/RateLabel.cpp @@ -23,6 +23,7 @@ RateLabel::RateLabel(QWidget* parent) : QLabel(parent) { } void RateLabel::resizeEvent(QResizeEvent* event) { + QLabel::resizeEvent(event); Font.setPointSize(FontAdjustment.AdjustPointSize(window())); } diff --git a/src/Windowing/WidgetsRecreation.cpp b/src/Windowing/WidgetsRecreation.cpp index 9c7958a..7c34af3 100644 --- a/src/Windowing/WidgetsRecreation.cpp +++ b/src/Windowing/WidgetsRecreation.cpp @@ -60,6 +60,8 @@ Widgets::Widgets() { } // void Widgets::Widgets() void Widgets::resizeEvent(QResizeEvent* event) { + QMainWindow::resizeEvent(event); + SetGridColumnsMinimums(); SetGridRowsMinimums(); SetAllButtonTextSize(); From 6457cce9aab41b5db0fee72cce7b916787199760 Mon Sep 17 00:00:00 2001 From: JC Luna Date: Sun, 29 Mar 2026 23:38:18 -0500 Subject: [PATCH 14/18] Autosize the title --- src/Widgets/Dial/Composite.cpp | 7 +++++++ src/Widgets/Dial/Composite.hpp | 3 ++- src/Widgets/Displays/RateLabel.cpp | 1 + src/Widgets/Displays/RateLabel.hpp | 2 +- 4 files changed, 11 insertions(+), 2 deletions(-) diff --git a/src/Widgets/Dial/Composite.cpp b/src/Widgets/Dial/Composite.cpp index 78b0cd1..68f98c2 100644 --- a/src/Widgets/Dial/Composite.cpp +++ b/src/Widgets/Dial/Composite.cpp @@ -13,6 +13,7 @@ CompositeDial::CompositeDial(QWidget* parent) : QWidget(parent) { DialNameLabel->setText("Dial"); DialNameLabel->setScaledContents(true); + DialNameLabel->setFont(DialNameFont); MajorOrganizer->addWidget(DialNameLabel, 0, 0, 1, 1); MajorOrganizer->addWidget(DialRateDuo, 1, 0, 5, 1); @@ -31,6 +32,9 @@ CompositeDial::CompositeDial(QWidget* parent) : QWidget(parent) { DialRateDuo->setSizePolicy(expandPolicy); Dial->setSizePolicy(expandPolicy); + QSizePolicy vertConstrain(QSizePolicy::Preferred, QSizePolicy::Minimum); + DialNameLabel->setSizePolicy(vertConstrain); + MajorOrganizer->setAlignment(Qt::AlignHCenter); MajorOrganizer->setAlignment(DialNameLabel, Qt::AlignHCenter | Qt::AlignTop); @@ -44,6 +48,9 @@ CompositeDial::CompositeDial(const QString& title, QWidget* parent) void CompositeDial::resizeEvent(QResizeEvent* event) { QWidget::resizeEvent(event); + + DialNameFont.setPointSize(TitleAdjustment.AdjustPointSize(window())); + DialNameLabel->setFont(DialNameFont); } // Wrap accessors and settors of child widgets {{{ diff --git a/src/Widgets/Dial/Composite.hpp b/src/Widgets/Dial/Composite.hpp index 442cdea..2ea802b 100644 --- a/src/Widgets/Dial/Composite.hpp +++ b/src/Widgets/Dial/Composite.hpp @@ -29,7 +29,8 @@ class CompositeDial : public QWidget { private: QGridLayout* MajorOrganizer; QLabel* DialNameLabel; - Util::FontAdjustment TitleAdjustment{ .PointSizeAtMinimum = 20, .AdjustToWidth = false }; + QFont DialNameFont{ }; + Util::FontAdjustment TitleAdjustment{ .PointSizeAtMinimum = 16, .AdjustToWidth = false }; QGridLayout* DuoOrganizer; QWidget* DialRateDuo; diff --git a/src/Widgets/Displays/RateLabel.cpp b/src/Widgets/Displays/RateLabel.cpp index daa4238..fb5b0e8 100644 --- a/src/Widgets/Displays/RateLabel.cpp +++ b/src/Widgets/Displays/RateLabel.cpp @@ -25,6 +25,7 @@ RateLabel::RateLabel(QWidget* parent) : QLabel(parent) { void RateLabel::resizeEvent(QResizeEvent* event) { QLabel::resizeEvent(event); Font.setPointSize(FontAdjustment.AdjustPointSize(window())); + setFont(Font); } void RateLabel::SetTextFrom(double num) { diff --git a/src/Widgets/Displays/RateLabel.hpp b/src/Widgets/Displays/RateLabel.hpp index 13fcbd0..a322978 100644 --- a/src/Widgets/Displays/RateLabel.hpp +++ b/src/Widgets/Displays/RateLabel.hpp @@ -25,7 +25,7 @@ class RateLabel : public QLabel { QString QuantityUnitString = ""; QString TimeUnitString = "/s"; - Util::FontAdjustment FontAdjustment{ 10, true }; + Util::FontAdjustment FontAdjustment{ 10, false }; QFont Font{}; }; // class RateLabel From 2972b847ded8050ecb985cf1381bfef91eee21cd Mon Sep 17 00:00:00 2001 From: JC Luna Date: Sun, 29 Mar 2026 23:39:32 -0500 Subject: [PATCH 15/18] No designated struct initializeres --- src/Widgets/Dial/Composite.hpp | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/Widgets/Dial/Composite.hpp b/src/Widgets/Dial/Composite.hpp index 2ea802b..ffb41d7 100644 --- a/src/Widgets/Dial/Composite.hpp +++ b/src/Widgets/Dial/Composite.hpp @@ -30,14 +30,12 @@ class CompositeDial : public QWidget { QGridLayout* MajorOrganizer; QLabel* DialNameLabel; QFont DialNameFont{ }; - Util::FontAdjustment TitleAdjustment{ .PointSizeAtMinimum = 16, .AdjustToWidth = false }; + Util::FontAdjustment TitleAdjustment{ 16, false }; QGridLayout* DuoOrganizer; QWidget* DialRateDuo; AttitudeDial* Dial; RateLabel* NumericRateLabel; - double RateLimitHz = 1.0; - }; // class CompositeDial } // namespace VSCL From 782ecd7c43bfd2156d677561720cc7438e5818f5 Mon Sep 17 00:00:00 2001 From: JC Luna Date: Mon, 30 Mar 2026 09:10:06 -0500 Subject: [PATCH 16/18] Reorg order of ops inside the Composite ctor --- src/Widgets/Dial/Composite.cpp | 21 ++++++++++----------- src/Windowing/WidgetsRecreation.cpp | 2 +- 2 files changed, 11 insertions(+), 12 deletions(-) diff --git a/src/Widgets/Dial/Composite.cpp b/src/Widgets/Dial/Composite.cpp index 68f98c2..5e2760d 100644 --- a/src/Widgets/Dial/Composite.cpp +++ b/src/Widgets/Dial/Composite.cpp @@ -3,10 +3,15 @@ namespace VSCL { CompositeDial::CompositeDial(QWidget* parent) : QWidget(parent) { - // Child widget setup goes top -> bottom level - + // Widget setup goes top -> bottom level + + // Top-level MajorOrganizer = new QGridLayout(this); this->setLayout(MajorOrganizer); + this->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::MinimumExpanding); + + MajorOrganizer->setAlignment(Qt::AlignHCenter); + MajorOrganizer->setAlignment(DialNameLabel, Qt::AlignHCenter | Qt::AlignTop); DialNameLabel = new QLabel(this); DialRateDuo = new QWidget(this); @@ -14,10 +19,12 @@ CompositeDial::CompositeDial(QWidget* parent) : QWidget(parent) { DialNameLabel->setText("Dial"); DialNameLabel->setScaledContents(true); DialNameLabel->setFont(DialNameFont); + DialNameLabel->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Minimum); MajorOrganizer->addWidget(DialNameLabel, 0, 0, 1, 1); MajorOrganizer->addWidget(DialRateDuo, 1, 0, 5, 1); + // Bottom-level DuoOrganizer = new QGridLayout(DialRateDuo); DialRateDuo->setLayout(DuoOrganizer); @@ -28,17 +35,9 @@ CompositeDial::CompositeDial(QWidget* parent) : QWidget(parent) { DuoOrganizer->addWidget(NumericRateLabel, 0, 0); QSizePolicy expandPolicy(QSizePolicy::MinimumExpanding, QSizePolicy::MinimumExpanding); - this->setSizePolicy(expandPolicy); + DuoOrganizer->setAlignment(NumericRateLabel, Qt::AlignHCenter | Qt::AlignVCenter); DialRateDuo->setSizePolicy(expandPolicy); Dial->setSizePolicy(expandPolicy); - - QSizePolicy vertConstrain(QSizePolicy::Preferred, QSizePolicy::Minimum); - DialNameLabel->setSizePolicy(vertConstrain); - - MajorOrganizer->setAlignment(Qt::AlignHCenter); - MajorOrganizer->setAlignment(DialNameLabel, Qt::AlignHCenter | Qt::AlignTop); - - DuoOrganizer->setAlignment(NumericRateLabel, Qt::AlignHCenter | Qt::AlignVCenter); } CompositeDial::CompositeDial(const QString& title, QWidget* parent) diff --git a/src/Windowing/WidgetsRecreation.cpp b/src/Windowing/WidgetsRecreation.cpp index 7c34af3..dc14e31 100644 --- a/src/Windowing/WidgetsRecreation.cpp +++ b/src/Windowing/WidgetsRecreation.cpp @@ -54,7 +54,7 @@ Widgets::Widgets() { ButtonFont = QFont(); SetAllButtonTextSize(); - SetRoll(2); + SetRoll(-32); SetPitch(5); SetYaw(100); } // void Widgets::Widgets() From 40ff0a82ea5ed1c0faa61f5fac92cafa2875a564 Mon Sep 17 00:00:00 2001 From: JC Luna Date: Mon, 30 Mar 2026 09:28:23 -0500 Subject: [PATCH 17/18] Silence int signedness warning, will never be UB when pt size is always positive or zero --- src/Widgets/Displays/QuantitiesRatesRow.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Widgets/Displays/QuantitiesRatesRow.cpp b/src/Widgets/Displays/QuantitiesRatesRow.cpp index 1b5525e..db9b14e 100644 --- a/src/Widgets/Displays/QuantitiesRatesRow.cpp +++ b/src/Widgets/Displays/QuantitiesRatesRow.cpp @@ -28,7 +28,7 @@ void QtyRateRow::resizeEvent(QResizeEvent* event) { } void QtyRateRow::AdjustFontSize() { - int tpt = TitleFontAdjustment.AdjustPointSize(window()); + unsigned int tpt = static_cast(TitleFontAdjustment.AdjustPointSize(window())); if (tpt <= TitleFontAdjustment.PointSizeAtMinimum) { setTitle(tr("")); TitleFont.setPointSize(1); From 8d4ea6924deabfbf8abe1625fa087d1032700144 Mon Sep 17 00:00:00 2001 From: JC Luna Date: Mon, 30 Mar 2026 15:39:28 -0500 Subject: [PATCH 18/18] Final cleanup post-review Some warnings, silenced, also a fix to a bad use of sed --- src/Plotting/Backend/CoreQChart.cpp | 4 ++-- src/Plotting/Plot2D.cpp | 4 ++-- src/Windowing/WidgetsRecreation.cpp | 4 ++-- style/RateLabel.qss | 0 4 files changed, 6 insertions(+), 6 deletions(-) delete mode 100644 style/RateLabel.qss diff --git a/src/Plotting/Backend/CoreQChart.cpp b/src/Plotting/Backend/CoreQChart.cpp index 9ed336c..33c7326 100644 --- a/src/Plotting/Backend/CoreQChart.cpp +++ b/src/Plotting/Backend/CoreQChart.cpp @@ -123,10 +123,10 @@ void PlotQChart::Plot() { QList pts; const SeriesInfo& sinfo = sinfos[idx]; - unsigned int n = sinfo.Times.size(); + std::size_t n = sinfo.Times.size(); if (n == 0) { continue; } - for (unsigned int i = 0; i < n; i++) { + for (unsigned int i = 0; static_cast(i) < n; i++) { pts.append({ sinfo.Times[i], sinfo.Quantities[i] }); } diff --git a/src/Plotting/Plot2D.cpp b/src/Plotting/Plot2D.cpp index 3ab6be4..6480ed5 100644 --- a/src/Plotting/Plot2D.cpp +++ b/src/Plotting/Plot2D.cpp @@ -4,7 +4,7 @@ namespace VSCL::Plot { -void EmbeddablePlot2D::AddPoint(double time, double quantity, bool update) { AddPoint(0, time, quantity); } +void EmbeddablePlot2D::AddPoint(double time, double quantity, bool update) { AddPoint(0, time, quantity, update); } void EmbeddablePlot2D::AddPoint(uint8_t idx, double time, double quantity, bool update) { std::vector& oldTime = Series[idx].Times; std::vector& oldQty = Series[idx].Quantities; @@ -34,7 +34,7 @@ void EmbeddablePlot2D::AddPoints(uint8_t idx, } void EmbeddablePlot2D::AddPoints( const std::vector& times, const std::vector& quantities, bool update) { - AddPoints(0, times, quantities); } + AddPoints(0, times, quantities, update); } void EmbeddablePlot2D::SetAxis(const Axis axis, const AxisInfo& info) { switch (axis) { diff --git a/src/Windowing/WidgetsRecreation.cpp b/src/Windowing/WidgetsRecreation.cpp index dc14e31..ac01013 100644 --- a/src/Windowing/WidgetsRecreation.cpp +++ b/src/Windowing/WidgetsRecreation.cpp @@ -248,7 +248,7 @@ void Widgets::SetupTimeHistoryPlotQChart() { rollInfo.Color = Plot::StandardColor.at("Red"); Plot::SeriesInfo pitchInfo; - pitchInfo.Name = "Pit.hpp"; + pitchInfo.Name = "Pitch"; pitchInfo.Color = Plot::StandardColor.at("Green"); Plot::SeriesInfo yawInfo; @@ -269,7 +269,7 @@ void Widgets::SetupAttQtysRatesDisplay() { RollQtyRate = new QtyRateRow(tr("Roll"), AttQtysRates); RollQtyRate->SetQuantityUnits("°"); RollQtyRate->SetRateUnits("°/s"); - PitchQtyRate = new QtyRateRow(tr("Pit.hpp"), AttQtysRates); + PitchQtyRate = new QtyRateRow(tr("Pitch"), AttQtysRates); PitchQtyRate->SetQuantityUnits("°"); PitchQtyRate->SetRateUnits("°/s"); YawQtyRate = new QtyRateRow(tr("Yaw"), AttQtysRates); diff --git a/style/RateLabel.qss b/style/RateLabel.qss deleted file mode 100644 index e69de29..0000000