diff --git a/.clang-tidy b/.clang-tidy new file mode 100644 index 0000000..e2e7d60 --- /dev/null +++ b/.clang-tidy @@ -0,0 +1,20 @@ +Checks: "readability-identifier-naming" +HeaderFileExtensions: ["hpp"] +ImplementationFileExtensions: ["cpp"] +HeaderFilterRegex: "(src)" +ExcludeHeaderFilterRegex: "(_deps)" +CheckOptions: + readability-identifier-naming.ClassCase: CamelCase + readability-identifier-naming.StructCase: CamelCase + readability-identifier-naming.FunctionCase: CamelCase + readability-identifier-naming.MethodCase: CamelCase + readability-identifier-naming.MemberCase: CamelCase + readability-identifier-naming.EnumCase: CamelCase + readability-identifier-naming.ScopedEnumCase: CamelCase + + readability-identifier-naming.ParameterCase: lower_case + readability-identifier-naming.MacroDefinitionCase: UPPER_CASE + readability-identifier-naming.GlobalConstantCase: UPPER_CASE + readability-identifier-naming.GlobalConstantPointerCase: UPPER_CASE + readability-identifier-naming.EnumConstantCase: UPPER_CASE + readability-identifier-naming.ScopedEnumConstantCase: UPPER_CASE diff --git a/.clangd b/.clangd index 22a3ff1..fabb9e2 100644 --- a/.clangd +++ b/.clangd @@ -1,4 +1,4 @@ CompileFlags: - Add: [-xc++, -Wall] + Add: [-xc++, -Wall, -std=c++20] Remove: [-mno-direct-extern-access, -fmodules-ts, -fmodule-mapper*, -fdeps-format*] CompilationDatabase: build diff --git a/cmake/cpp.cmake b/cmake/cpp.cmake index 10b2c07..364fd90 100644 --- a/cmake/cpp.cmake +++ b/cmake/cpp.cmake @@ -29,7 +29,8 @@ set(DISPLAYER_SOURCES "${WIDGETS_SRC_DIR}/Displays/QuantitiesRatesDisplay.cpp" "${WIDGETS_SRC_DIR}/Displays/QuantitiesRatesRow.cpp" "${WIDGETS_SRC_DIR}/Displays/RateLabel.cpp" - "${WIDGETS_SRC_DIR}/Displays/MultiPlotContainer.cpp") + "${WIDGETS_SRC_DIR}/Displays/MultiPlotContainer.cpp" + "${WIDGETS_SRC_DIR}/Displays/StatusCollector.cpp") set(WIDGET_SOURCES ${WINDOWING_SOURCES} diff --git a/src/Plotting/Appearance.hpp b/src/Plotting/Appearance.hpp index 678e0dd..39d652e 100644 --- a/src/Plotting/Appearance.hpp +++ b/src/Plotting/Appearance.hpp @@ -10,15 +10,15 @@ namespace VSCL::Plot { // Normalized in RGB space. typedef std::array ColorRGB; -static const std::map StandardColor = { +static const std::map STANDARD_COLOR = { { "Red", ColorRGB{ 1.0, 0.0, 0.0 } }, { "Green", ColorRGB{ 0.0, 1.0, 0.0 } }, { "Blue", ColorRGB{ 0.0, 0.0, 1.0 } }, }; enum class LineStyle : uint8_t { - Solid = 1, - Dashed = 2, - Dotted = 3, + SOLID = 1, + DASHED = 2, + DOTTED = 3, }; } // namespace VSCL::Plot diff --git a/src/Plotting/Axes.hpp b/src/Plotting/Axes.hpp index d9dea03..1b83364 100644 --- a/src/Plotting/Axes.hpp +++ b/src/Plotting/Axes.hpp @@ -7,20 +7,20 @@ namespace VSCL::Plot { enum class Axis : std::uint8_t { - Time = 0, - Quantity = 1, + TIME = 0, + QUANTITY = 1, }; enum class AxisScaling : std::uint8_t { - Linear = 0, - Log10 = 1, - Ln = 2, - Inverted = 3 + LINEAR = 0, + LOG10 = 1, + LN = 2, + INVERTED = 3 }; struct AxisInfo { Axis InfoOf; - AxisScaling Scaling = AxisScaling::Linear; + AxisScaling Scaling = AxisScaling::LINEAR; std::array Range = { 0.0, 1.0 }; double MajorSpacing = 1; diff --git a/src/Plotting/Backend/CoreQChart.cpp b/src/Plotting/Backend/CoreQChart.cpp index 736fac8..a861d73 100644 --- a/src/Plotting/Backend/CoreQChart.cpp +++ b/src/Plotting/Backend/CoreQChart.cpp @@ -20,7 +20,7 @@ PlotQChart::PlotQChart(QWidget* parent) LogTimeAxisQt->setLinePenColor(QColorConstants::Black); LogTimeAxisQt->setLabelFormat("%g"); LogTimeAxisQt->setGridLineVisible(false); - SetAxis(Axis::Time, GetAxisInfoView(Axis::Time)); + SetAxis(Axis::TIME, GetAxisInfoView(Axis::TIME)); PlotChart->addAxis(QuantityAxisQt, Qt::AlignLeft); QuantityAxisQt->setLinePenColor(QColorConstants::Black); @@ -30,7 +30,7 @@ PlotQChart::PlotQChart(QWidget* parent) LogQuantityAxisQt->setLinePenColor(QColorConstants::Black); LogQuantityAxisQt->setLabelFormat("%g"); LogQuantityAxisQt->setGridLineVisible(false); - SetAxis(Axis::Quantity, GetAxisInfoView(Axis::Quantity)); + SetAxis(Axis::QUANTITY, GetAxisInfoView(Axis::QUANTITY)); PlotChart->legend()->setVisible(false); PlotChart->setTheme(QChart::ChartThemeLight); @@ -55,11 +55,11 @@ void PlotQChart::SetAxis(const Axis axis, const AxisInfo& info) { double lobd = ax.Range[0]; switch (axis) { - case Axis::Time: + case Axis::TIME: axlinqt = TimeAxisQt; axlogqt = LogTimeAxisQt; break; - case Axis::Quantity: + case Axis::QUANTITY: default: axlinqt = QuantityAxisQt; axlogqt = LogQuantityAxisQt; @@ -69,7 +69,7 @@ void PlotQChart::SetAxis(const Axis axis, const AxisInfo& info) { if (!axlinqt || !axlogqt) { return; }; switch (ax.Scaling) { - case AxisScaling::Log10: + case AxisScaling::LOG10: axlinqt->setVisible(false); axlogqt->setVisible(); @@ -79,7 +79,7 @@ void PlotQChart::SetAxis(const Axis axis, const AxisInfo& info) { axqt = axlogqt; break; - case AxisScaling::Ln: + case AxisScaling::LN: axlinqt->setVisible(false); axlogqt->setVisible(); @@ -89,7 +89,7 @@ void PlotQChart::SetAxis(const Axis axis, const AxisInfo& info) { axqt = axlogqt; break; - case AxisScaling::Linear: + case AxisScaling::LINEAR: default: axlogqt->setVisible(false); axlinqt->setVisible(); @@ -135,13 +135,13 @@ void PlotQChart::Plot() { serie->setColor(QColor::fromRgbF(color[0], color[1], color[2], 1.0)); switch (sinfo.Style) { - case LineStyle::Dashed: + case LineStyle::DASHED: std::cerr << "Dashed lines not implemented for Qt Charts.\n"; break; - case LineStyle::Dotted: + case LineStyle::DOTTED: std::cerr << "Dotted lines not implemented for Qt Charts.\n"; break; - case LineStyle::Solid: + case LineStyle::SOLID: default: break; } @@ -160,8 +160,8 @@ void PlotQChart::AddSeries() { AddSeries({ }); } -void PlotQChart::AddSeries(const SeriesInfo& newInfo) { - EmbeddablePlot2D::AddSeries(newInfo); +void PlotQChart::AddSeries(const SeriesInfo& new_info) { + EmbeddablePlot2D::AddSeries(new_info); QLineSeries* newSeries = new QLineSeries(PlotChart); PlotChart->addSeries(newSeries); diff --git a/src/Plotting/Backend/CoreQChart.hpp b/src/Plotting/Backend/CoreQChart.hpp index 9ee46c1..1eefefd 100644 --- a/src/Plotting/Backend/CoreQChart.hpp +++ b/src/Plotting/Backend/CoreQChart.hpp @@ -23,7 +23,7 @@ class QCHART_BACKEND PlotQChart : virtual public EmbeddablePlot2D { virtual void EraseAllData() override; virtual void AddSeries() override; - virtual void AddSeries(const SeriesInfo& newInfo) override; + virtual void AddSeries(const SeriesInfo& new_info) override; private: QChart* PlotChart; diff --git a/src/Plotting/Plot2D.cpp b/src/Plotting/Plot2D.cpp index 7364a3b..e92770b 100644 --- a/src/Plotting/Plot2D.cpp +++ b/src/Plotting/Plot2D.cpp @@ -12,11 +12,11 @@ void EmbeddablePlot2D::AddPoint(uint8_t idx, double time, double quantity, bool oldTime.push_back(time); oldQty.push_back(quantity); - Plot::AxisInfo axInfo = this->GetAxisInfoView(Plot::Axis::Time); + Plot::AxisInfo axInfo = this->GetAxisInfoView(Plot::Axis::TIME); double maxTime = oldTime.back(); double minTime = std::max(0.0, maxTime - 10.0); axInfo.Range = { minTime, minTime + 10.0 }; - SetAxis(Plot::Axis::Time, axInfo); + SetAxis(Plot::Axis::TIME, axInfo); if (update) Plot(); } @@ -45,10 +45,10 @@ void EmbeddablePlot2D::AddPoints( void EmbeddablePlot2D::SetAxis(const Axis axis, const AxisInfo& info) { switch (axis) { - case Axis::Time: + case Axis::TIME: TimeAxis = info; break; - case Axis::Quantity: + case Axis::QUANTITY: QuantityAxis = info; break; } @@ -71,10 +71,10 @@ void EmbeddablePlot2D::EraseAllData() { const AxisInfo& EmbeddablePlot2D::GetAxisInfoView(Axis axis) const { switch (axis) { - case Axis::Time: + case Axis::TIME: return TimeAxis; break; - case Axis::Quantity: + case Axis::QUANTITY: default: return QuantityAxis; break; @@ -89,7 +89,7 @@ void EmbeddablePlot2D::AddSeries(std::string& name) { Series.push_back(serie); Plot(); } -void EmbeddablePlot2D::AddSeries(const SeriesInfo& newInfo) { Series.push_back(newInfo); Plot(); }; +void EmbeddablePlot2D::AddSeries(const SeriesInfo& new_info) { Series.push_back(new_info); Plot(); }; SeriesInfo EmbeddablePlot2D::GetSeriesByName(std::string& name) { for (const SeriesInfo& serie : Series) { @@ -113,10 +113,10 @@ const SeriesInfo& EmbeddablePlot2D::GetSeriesViewByName(std::string& name) const return Series[0]; } -void EmbeddablePlot2D::SetSeries(std::string& name, SeriesInfo& newInfo) { +void EmbeddablePlot2D::SetSeries(std::string& name, SeriesInfo& new_info) { for (SeriesInfo& serie : Series) { if (serie.Name == name) { - serie = newInfo; + serie = new_info; return; } } @@ -124,7 +124,7 @@ void EmbeddablePlot2D::SetSeries(std::string& name, SeriesInfo& newInfo) { std::cout << "Warning: Series of name " << name << " not found. Doing nothing.\n"; } -void EmbeddablePlot2D::SetSeries(uint8_t idx, SeriesInfo& newInfo) { Series[idx] = newInfo; } +void EmbeddablePlot2D::SetSeries(uint8_t idx, SeriesInfo& new_info) { Series[idx] = new_info; } void EmbeddablePlot2D::RemoveSeries(uint8_t idx) { Series.erase(Series.begin() + idx); } void EmbeddablePlot2D::RemoveSeries(std::string& name) { diff --git a/src/Plotting/Plot2D.hpp b/src/Plotting/Plot2D.hpp index 9ce5a39..5fc1757 100644 --- a/src/Plotting/Plot2D.hpp +++ b/src/Plotting/Plot2D.hpp @@ -49,13 +49,13 @@ class PLOT_API EmbeddablePlot2D : virtual public QWidget { // Add a named series. void AddSeries(std::string& name); // Add a series using the following info. - virtual void AddSeries(const SeriesInfo& newInfo); + virtual void AddSeries(const SeriesInfo& new_info); SeriesInfo GetSeriesByName(std::string& name); const SeriesInfo& GetSeriesViewByName(std::string& name) const; - void SetSeries(std::string& name, SeriesInfo& newInfo); - void SetSeries(uint8_t idx, SeriesInfo& newInfo); + void SetSeries(std::string& name, SeriesInfo& new_info); + void SetSeries(uint8_t idx, SeriesInfo& new_info); // Remove the series at the given index. void RemoveSeries(uint8_t idx); @@ -78,12 +78,12 @@ class PLOT_API EmbeddablePlot2D : virtual public QWidget { virtual void SetColor(ColorRGB& color); bool GetDrawGridState() { return DrawGrid; }; - void SetDrawGridState(bool newState) { DrawGrid = newState; }; + void SetDrawGridState(bool new_state) { DrawGrid = new_state; }; private: std::string Title; - AxisInfo TimeAxis = { Axis::Time }; - AxisInfo QuantityAxis = { Axis::Quantity }; + AxisInfo TimeAxis = { .InfoOf = Axis::TIME }; + AxisInfo QuantityAxis = { .InfoOf = Axis::QUANTITY }; std::vector Series; bool DrawGrid = false; diff --git a/src/Plotting/Series.hpp b/src/Plotting/Series.hpp index 5e8c83e..d04d98e 100644 --- a/src/Plotting/Series.hpp +++ b/src/Plotting/Series.hpp @@ -14,6 +14,6 @@ struct SeriesInfo { ColorRGB Color = {1.0, 0.0, 0.0}; double Alpha = 1.0; - LineStyle Style = LineStyle::Solid; + LineStyle Style = LineStyle::SOLID; }; } // namespace VSCL::Plot diff --git a/src/Util/Filesystem/UserPaths.cpp b/src/Util/Filesystem/UserPaths.cpp index dd02dcd..386ac57 100644 --- a/src/Util/Filesystem/UserPaths.cpp +++ b/src/Util/Filesystem/UserPaths.cpp @@ -43,7 +43,7 @@ bool MakeStandardAppPaths() { if (!fs::exists(app_dir)) { fs::create_directories(app_dir); } bool all_success = true; - std::for_each(StandardPaths.begin(), StandardPaths.end(), + std::for_each(STANDARD_PATHS.begin(), STANDARD_PATHS.end(), [&](const fs::path& subdir) { fs::path full_path = app_dir / subdir; diff --git a/src/Util/Filesystem/UserPaths.hpp b/src/Util/Filesystem/UserPaths.hpp index 619425a..0768bd2 100644 --- a/src/Util/Filesystem/UserPaths.hpp +++ b/src/Util/Filesystem/UserPaths.hpp @@ -9,15 +9,15 @@ namespace VSCL::FS { enum class UserPath : uint8_t { - Data, Config, Script + DATA, CONFIG, SCRIPT }; -static constexpr std::array StandardPaths = { +static constexpr std::array STANDARD_PATHS = { "data", "config", "script" }; static constexpr std::string_view GetStandardPath(const std::string_view& path) { - return *std::ranges::find(StandardPaths, path); + return *std::ranges::find(STANDARD_PATHS, path); } std::filesystem::path GetUserAppData(); diff --git a/src/Util/Sizing.hpp b/src/Util/Sizing.hpp index 31f621d..1765b21 100644 --- a/src/Util/Sizing.hpp +++ b/src/Util/Sizing.hpp @@ -6,8 +6,8 @@ namespace VSCL::Util { -static constexpr uint32_t MinimumWidth = 720; -static constexpr uint32_t MinimumHeight = 480; +static constexpr uint32_t MINIMUM_WIDTH = 720; +static constexpr uint32_t MINIMUM_HEIGHT = 480; struct FontAdjustment { /* @@ -21,12 +21,12 @@ struct FontAdjustment { */ bool AdjustToWidth = false; - static const uint32_t AdjustPxSize(uint32_t pxAtMin, QWidget* win, bool adjustToWidth=false) { - uint32_t dim = adjustToWidth ? win->width() : win->height(); - uint32_t adj = adjustToWidth ? MinimumWidth : MinimumHeight; + static const uint32_t AdjustPxSize(uint32_t px_at_min, QWidget* win, bool adjust_to_width=false) { + uint32_t dim = adjust_to_width ? win->width() : win->height(); + uint32_t adj = adjust_to_width ? MINIMUM_WIDTH : MINIMUM_HEIGHT; float delta = (float)(dim - adj) / (float)adj; - return pxAtMin * (uint32_t)std::ceil(1 + delta); + return px_at_min * (uint32_t)std::ceil(1 + delta); } const uint32_t AdjustPxSize(QWidget* win) const { diff --git a/src/Widgets/Dial/Attitude.cpp b/src/Widgets/Dial/Attitude.cpp index 0225c90..d80b57a 100644 --- a/src/Widgets/Dial/Attitude.cpp +++ b/src/Widgets/Dial/Attitude.cpp @@ -46,14 +46,14 @@ QPoint AttitudeDial::HandEndingCenteredNominal() const { return Origin + QPoint{ linex, liney }; } -void AttitudeDial::SetRangeType(RangeType newRangeType) { - RangeTypeMode = newRangeType; +void AttitudeDial::SetRangeType(RangeType new_range_type) { + RangeTypeMode = new_range_type; switch (RangeTypeMode) { - case RangeType::LowestNominal: + case RangeType::LOWEST_NOMINAL: RangeHandlerFunction = std::bind(&AttitudeDial::HandEndingLowestNominal, this); break; - case RangeType::CenteredNominal: + case RangeType::CENTERED_NOMINAL: default: RangeHandlerFunction = std::bind(&AttitudeDial::HandEndingCenteredNominal, this); break; @@ -85,12 +85,12 @@ void AttitudeDial::PaintTicks(QPainter* painter) { case 3: // major ticker[0] = 0.85; tickcolor = Palette.MajorTick; - cossin = MajorTicks[i]; + cossin = MAJOR_TICKS[i]; break; default: // minor ticker[0] = 0.95; tickcolor = Palette.MinorTick; - cossin = MinorTicks[i - 4]; + cossin = MINOR_TICKS[i - 4]; break; } @@ -127,7 +127,7 @@ void AttitudeDial::PaintCap(QPainter* painter) { painter->drawEllipse(Origin, r, r); } // AttitudeDial::PaintCap() -void AttitudeDial::SetPalette(AttitudeDialPalette& newPalette) { Palette = newPalette; } +void AttitudeDial::SetPalette(AttitudeDialPalette& new_palette) { Palette = new_palette; } AttitudeDialPalette AttitudeDial::GetPalette() const { return Palette; } const AttitudeDialPalette& AttitudeDial::GetPaletteView() const { return Palette; } diff --git a/src/Widgets/Dial/Attitude.hpp b/src/Widgets/Dial/Attitude.hpp index 4d81b13..21afc01 100644 --- a/src/Widgets/Dial/Attitude.hpp +++ b/src/Widgets/Dial/Attitude.hpp @@ -21,15 +21,15 @@ class AttitudeDial : public QWidget { AttitudeDial(QWidget* parent); void SetDialAngle(double value); - void SetPalette(AttitudeDialPalette& newPalette); + void SetPalette(AttitudeDialPalette& new_palette); AttitudeDialPalette GetPalette() const; const AttitudeDialPalette& GetPaletteView() const; enum class RangeType : uint8_t { - CenteredNominal, - LowestNominal + CENTERED_NOMINAL, + LOWEST_NOMINAL }; - void SetRangeType(RangeType newRangeType); + void SetRangeType(RangeType new_range_type); virtual void paintEvent(QPaintEvent* event) override; @@ -42,7 +42,7 @@ class AttitudeDial : public QWidget { AttitudeDialPalette Palette; std::array Range = { -180, 180 }; - RangeType RangeTypeMode = RangeType::CenteredNominal; + RangeType RangeTypeMode = RangeType::CENTERED_NOMINAL; QPoint HandEndingLowestNominal() const; QPoint HandEndingCenteredNominal() const; std::function RangeHandlerFunction = nullptr; @@ -52,11 +52,11 @@ class AttitudeDial : public QWidget { void PaintHand(QPainter* painter); void PaintCap(QPainter* painter); - static constexpr std::array, 4> MajorTicks = {{ + static constexpr std::array, 4> MAJOR_TICKS = {{ { 1.0, 0.0 }, { 0.0, 1.0 }, { -1.0, 0.0 }, { 0.0, -1.0 } }}; - static constexpr std::array, 4> MinorTicks = {{ + static constexpr std::array, 4> MINOR_TICKS = {{ { 0.7071067811865475, 0.7071067811865475 }, { 0.7071067811865475, -0.7071067811865475 }, { -0.7071067811865475, -0.7071067811865475 }, { -0.7071067811865475, 0.7071067811865475 } }}; diff --git a/src/Widgets/Dial/Composite.cpp b/src/Widgets/Dial/Composite.cpp index a3f1e3b..64a38de 100644 --- a/src/Widgets/Dial/Composite.cpp +++ b/src/Widgets/Dial/Composite.cpp @@ -15,9 +15,9 @@ CompositeDial::CompositeDial(QWidget* parent) this->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::MinimumExpanding); this->setLayout(MajorOrganizer); MajorOrganizer->setAlignment(Qt::AlignHCenter); - MajorOrganizer->setAlignment(DialNameLabel, Qt::AlignHCenter | Qt::AlignTop); - MajorOrganizer->addWidget(DialNameLabel, 0, 0, 1, 1); - MajorOrganizer->addWidget(DialRateDuo, 1, 0, 5, 1); + // MajorOrganizer->setAlignment(DialNameLabel, Qt::AlignCenter); + MajorOrganizer->addWidget(DialNameLabel, 0, 0); + MajorOrganizer->addWidget(DialRateDuo, 0, 1); // Set dial-rate combo layout DialRateDuo->setLayout(DuoOrganizer); @@ -30,7 +30,7 @@ CompositeDial::CompositeDial(QWidget* parent) DialNameLabel->setScaledContents(true); DialNameLabel->setFont(DialNameFont); DialNameLabel->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Minimum); - DialNameLabel->setAlignment(Qt::AlignHCenter | Qt::AlignTop); + DialNameLabel->setAlignment(Qt::AlignHCenter | Qt::AlignVCenter); // Set how the dial-rate combo resizes QSizePolicy expandPolicy(QSizePolicy::MinimumExpanding, QSizePolicy::MinimumExpanding); diff --git a/src/Widgets/Dial/Composite.hpp b/src/Widgets/Dial/Composite.hpp index f3ccf1d..e2bc809 100644 --- a/src/Widgets/Dial/Composite.hpp +++ b/src/Widgets/Dial/Composite.hpp @@ -30,7 +30,10 @@ class CompositeDial : public QWidget { QGridLayout* MajorOrganizer; QLabel* DialNameLabel; QFont DialNameFont{ }; - Util::FontAdjustment TitleAdjustment{ 16, false }; + Util::FontAdjustment TitleAdjustment{ + .PxSizeAtMinimum=16, + .AdjustToWidth=false + }; QWidget* DialRateDuo; QGridLayout* DuoOrganizer; diff --git a/src/Widgets/Displays/QuantitiesRatesDisplay.cpp b/src/Widgets/Displays/QuantitiesRatesDisplay.cpp index 888ebcb..10ac802 100644 --- a/src/Widgets/Displays/QuantitiesRatesDisplay.cpp +++ b/src/Widgets/Displays/QuantitiesRatesDisplay.cpp @@ -11,6 +11,6 @@ QtyRateDisplay::QtyRateDisplay(const QString& title, QWidget* parent) }; const QList& QtyRateDisplay::GetRowsView() const { return Rows; } -void QtyRateDisplay::AddRow(QtyRateRow* newRow) { Rows.append(newRow); Organizer->addWidget(newRow); } +void QtyRateDisplay::AddRow(QtyRateRow* new_row) { Rows.append(new_row); Organizer->addWidget(new_row); } } // namespace VSCL diff --git a/src/Widgets/Displays/QuantitiesRatesDisplay.hpp b/src/Widgets/Displays/QuantitiesRatesDisplay.hpp index 95fd802..20f7164 100644 --- a/src/Widgets/Displays/QuantitiesRatesDisplay.hpp +++ b/src/Widgets/Displays/QuantitiesRatesDisplay.hpp @@ -17,7 +17,7 @@ class QtyRateDisplay : public QGroupBox { const QList& GetRowsView() const; protected: - void AddRow(QtyRateRow* newRow); + void AddRow(QtyRateRow* new_row); private: QList Rows; diff --git a/src/Widgets/Displays/QuantitiesRatesRow.cpp b/src/Widgets/Displays/QuantitiesRatesRow.cpp index 564f99f..bfdb72c 100644 --- a/src/Widgets/Displays/QuantitiesRatesRow.cpp +++ b/src/Widgets/Displays/QuantitiesRatesRow.cpp @@ -28,8 +28,8 @@ void QtyRateRow::resizeEvent(QResizeEvent* event) { } void QtyRateRow::AdjustFontSize() { - uint32_t tpt = static_cast(TitleFontAdjustment.AdjustPxSize(window())); - if (tpt <= TitleFontAdjustment.PxSizeAtMinimum) { + uint32_t tpt = static_cast(TITLE_FONT_ADJUSTMENT.AdjustPxSize(window())); + if (tpt <= TITLE_FONT_ADJUSTMENT.PxSizeAtMinimum) { setTitle(tr("")); TitleFont.setPixelSize(1); } @@ -40,17 +40,17 @@ void QtyRateRow::AdjustFontSize() { setFont(TitleFont); - LabelFont.setPixelSize(NumericFontAdjustment.AdjustPxSize(window())); + LabelFont.setPixelSize(NUMERIC_FONT_ADJUSTMENT.AdjustPxSize(window())); QuantityLabel->setFont(LabelFont); RateLabel->setFont(LabelFont); } -void QtyRateRow::SetQuantity(double newQuantity) { - Quantity = newQuantity; +void QtyRateRow::SetQuantity(double new_quantity) { + Quantity = new_quantity; QuantityLabel->setText(QString::number(Quantity) + QuantityUnits); } -void QtyRateRow::SetRate(double newRate) { - Rate = newRate; +void QtyRateRow::SetRate(double new_rate) { + Rate = new_rate; RateLabel->setText(QString::number(Rate) + RateUnits); } diff --git a/src/Widgets/Displays/QuantitiesRatesRow.hpp b/src/Widgets/Displays/QuantitiesRatesRow.hpp index 8010a04..ea5f607 100644 --- a/src/Widgets/Displays/QuantitiesRatesRow.hpp +++ b/src/Widgets/Displays/QuantitiesRatesRow.hpp @@ -16,8 +16,8 @@ class QtyRateRow : public QGroupBox { QtyRateRow(const QString& title, QtyRateDisplay* parent); virtual void resizeEvent(QResizeEvent* event); - void SetQuantity(double newQuantity); - void SetRate(double newRate); + void SetQuantity(double new_quantity); + void SetRate(double new_rate); void SetQuantityUnits(const QString& units); void SetRateUnits(const QString& units); @@ -39,8 +39,15 @@ class QtyRateRow : public QGroupBox { QLabel* RateLabel; void AdjustFontSize(); - static constexpr Util::FontAdjustment TitleFontAdjustment { 8, false }; - static constexpr Util::FontAdjustment NumericFontAdjustment { 8, false }; + static constexpr Util::FontAdjustment TITLE_FONT_ADJUSTMENT { + .PxSizeAtMinimum = 8, + .AdjustToWidth = false + }; + + static constexpr Util::FontAdjustment NUMERIC_FONT_ADJUSTMENT { + .PxSizeAtMinimum = 8, + .AdjustToWidth = false + }; }; // class QtyRateDisplay } // namespace VSCL diff --git a/src/Widgets/Displays/RateLabel.hpp b/src/Widgets/Displays/RateLabel.hpp index a322978..c943618 100644 --- a/src/Widgets/Displays/RateLabel.hpp +++ b/src/Widgets/Displays/RateLabel.hpp @@ -25,7 +25,10 @@ class RateLabel : public QLabel { QString QuantityUnitString = ""; QString TimeUnitString = "/s"; - Util::FontAdjustment FontAdjustment{ 10, false }; + Util::FontAdjustment FontAdjustment{ + .PxSizeAtMinimum=10, + .AdjustToWidth=false + }; QFont Font{}; }; // class RateLabel diff --git a/src/Widgets/Displays/StatusCollector.cpp b/src/Widgets/Displays/StatusCollector.cpp new file mode 100644 index 0000000..2a4041e --- /dev/null +++ b/src/Widgets/Displays/StatusCollector.cpp @@ -0,0 +1,48 @@ +#include "StatusCollector.hpp" + +#include + +namespace VSCL{ +QString BuildStatusStyleSheet(const QString& object_name, Status status) { + const std::string& color = STATUS_COLOR_MAP.at(status); + return QString( + " QGroupBox#%1 {" + " border: 2px solid %2;" + " border-radius: 5px;" + " margin-top: 20px;" + "}" + " QGroupBox#statusColumn::title {" + " subcontrol-origin: margin;" + " subcontrol-position: top left;" + " padding: 0 0px;" + "}" + ).arg(object_name).arg(QString::fromStdString(color)); +} + +void SetGroupBoxStatus(QGroupBox *box, Status status) { + const QString objectName = box->objectName(); + const QString sheet = BuildStatusStyleSheet(objectName, status); + + box->setStyleSheet(sheet); + + box->style()->unpolish(box); + box->style()->polish(box); + box->update(); +} + +QString BuildButtonStyleSheet(Status status) { + const std::string& color = STATUS_COLOR_MAP.at(status); + return QString(" QPushButton { background-color: %1; color: black; }") + .arg(QString::fromStdString(color)); +} + +void SetButtonStatus(QPushButton* button, Status status) { + const QString sheet = BuildButtonStyleSheet(status); + button->setStyleSheet(sheet); + + button->style()->unpolish(button); + button->style()->polish(button); + button->update(); +} + +} // namespace VSCL diff --git a/src/Widgets/Displays/StatusCollector.hpp b/src/Widgets/Displays/StatusCollector.hpp new file mode 100644 index 0000000..b3a64d5 --- /dev/null +++ b/src/Widgets/Displays/StatusCollector.hpp @@ -0,0 +1,33 @@ +#pragma once +#include +#include +#include +#include +#include + +namespace VSCL { +enum class Status { + ARMED, // Red + DISARMED, // White + STANDBY, // White # true/false of Standby + ACTIVE, // Yellow + OPENED, // Green + CLOSED // Grey +}; + +static const std::map STATUS_COLOR_MAP = { + {Status::ARMED, "red"}, + {Status::DISARMED, "#fbfbfb"}, + {Status::STANDBY, "#fbfbfb"}, + {Status::ACTIVE, "yellow"}, + {Status::OPENED, "green"}, + {Status::CLOSED, "gray"} +}; + +QString BuildStatusStyleSheet(const QString& object_name, Status status); +void SetGroupBoxStatus(QGroupBox* box, Status status); + +QString BuildButtonStyleSheet(Status status); +void SetButtonStatus(QPushButton* button, Status status); + +} // namespace VSCL diff --git a/src/Windowing/DevWindow.cpp b/src/Windowing/DevWindow.cpp index 669ec7a..097786c 100644 --- a/src/Windowing/DevWindow.cpp +++ b/src/Windowing/DevWindow.cpp @@ -13,7 +13,7 @@ DevWindow::DevWindow() { AttitudeDial* dial = new AttitudeDial(this); - NumericDisplaysTest = new NumericTestWidget(this, dial, [dial](int newValue) { dial->SetDialAngle(newValue); }); + NumericDisplaysTest = new NumericTestWidget(this, dial, [dial](int new_value) { dial->SetDialAngle(new_value); }); setCentralWidget(Stacker); Stacker->addWidget(MainQuick); @@ -40,13 +40,13 @@ void DevWindow::SetQMLFromPath(const QUrl& path) { void DevWindow::SwapSetting() { switch (CurrentSetting) { - case DevWindow::NumericTesting: + case DevWindow::NUMERIC_TESTING: Stacker->setCurrentIndex(1); - CurrentSetting = DevWindow::QMLView; + CurrentSetting = DevWindow::QML_VIEW; break; - case DevWindow::QMLView: + case DevWindow::QML_VIEW: Stacker->setCurrentIndex(0); - CurrentSetting = DevWindow::NumericTesting; + CurrentSetting = DevWindow::NUMERIC_TESTING; break; } } diff --git a/src/Windowing/DevWindow.hpp b/src/Windowing/DevWindow.hpp index 71eafcc..a232cca 100644 --- a/src/Windowing/DevWindow.hpp +++ b/src/Windowing/DevWindow.hpp @@ -22,8 +22,8 @@ class DevWindow : public QMainWindow { DevWindow(); enum Setting { - QMLView, - NumericTesting + QML_VIEW, + NUMERIC_TESTING }; void SetQMLFromPath(const QUrl& path); @@ -38,7 +38,7 @@ private slots: void About(); private: - Setting CurrentSetting = Setting::NumericTesting; + Setting CurrentSetting = Setting::NUMERIC_TESTING; QStackedWidget* Stacker; /* diff --git a/src/Windowing/NumericTestWidget.cpp b/src/Windowing/NumericTestWidget.cpp index aa2d810..e9a2899 100644 --- a/src/Windowing/NumericTestWidget.cpp +++ b/src/Windowing/NumericTestWidget.cpp @@ -5,11 +5,11 @@ namespace VSCL { NumericTestWidget::NumericTestWidget( - QWidget* parent, QWidget* whatToTest, + QWidget* parent, QWidget* what_to_test, std::function method) : QWidget(parent) , TesterSpinbox(new QDoubleSpinBox(this)) - , WidgetBeingTested(whatToTest) { + , WidgetBeingTested(what_to_test) { QGridLayout* grid = new QGridLayout(this); grid->setContentsMargins(25, 25, 25, 25); diff --git a/src/Windowing/NumericTestWidget.hpp b/src/Windowing/NumericTestWidget.hpp index bf72f81..6c8da67 100644 --- a/src/Windowing/NumericTestWidget.hpp +++ b/src/Windowing/NumericTestWidget.hpp @@ -9,7 +9,7 @@ class NumericTestWidget : public QWidget { Q_OBJECT; public: - NumericTestWidget(QWidget* parent, QWidget* whatToTest, + NumericTestWidget(QWidget* parent, QWidget* what_to_test, std::function method); virtual void setVisible(bool visible) override; diff --git a/src/Windowing/WidgetsRecreation.cpp b/src/Windowing/WidgetsRecreation.cpp index 2010607..7b71200 100644 --- a/src/Windowing/WidgetsRecreation.cpp +++ b/src/Windowing/WidgetsRecreation.cpp @@ -4,9 +4,10 @@ #include "WidgetsRecreation.hpp" #include "Plotting/Backend/CoreQChart.hpp" +#include "Widgets/Displays/StatusCollector.hpp" // stupid temp thing {{{ -static void stupid_make_data(VSCL::Plot::EmbeddablePlot2D* plot) { +static void StupidMakeData(VSCL::Plot::EmbeddablePlot2D* plot) { double ph1, ph2, ph3; std::srand(std::chrono::system_clock::now().time_since_epoch().count() + 1); @@ -37,15 +38,13 @@ Widgets::Widgets() { // Geometry and window characteristics setWindowTitle(tr("VSCL Gyroscopic Test Rig")); - setMinimumSize(Util::MinimumWidth, Util::MinimumHeight); - resize(Util::MinimumWidth, Util::MinimumHeight); + setMinimumSize(Util::MINIMUM_WIDTH, Util::MINIMUM_HEIGHT); + resize(Util::MINIMUM_WIDTH, Util::MINIMUM_HEIGHT); // Set up the static layout SetupCentralWidget(); SetupAttitudeDials(); - // SetupTimeHistoryPlotQChart(); // <- old plot SetupMultiPlot(); // <-new multiplot - SetupAttQtysRatesDisplay(); SetupButtons(); SetupStatusColumn(); SetGridColumnsMinimums(); @@ -68,17 +67,17 @@ void Widgets::resizeEvent(QResizeEvent* event) { void Widgets::SetRoll(double roll) { RollDial->SetDialAngle(roll); - RollQtyRate->SetQuantity(roll); + // RollQtyRate->SetQuantity(roll); } void Widgets::SetPitch(double pitch) { PitchDial->SetDialAngle(pitch); - PitchQtyRate->SetQuantity(pitch); + // PitchQtyRate->SetQuantity(pitch); } void Widgets::SetYaw(double yaw) { YawDial->SetDialAngle(yaw); - YawQtyRate->SetQuantity(yaw); + // YawQtyRate->SetQuantity(yaw); } void Widgets::SetRollRate(double roll) { @@ -93,7 +92,6 @@ void Widgets::SetYawRate(double yaw) { YawQtyRate->SetRate(yaw); } - // Layout and Widgets Setup {{{ void Widgets::SetupCentralWidget() { MajorContainer = new QWidget(this); @@ -112,9 +110,9 @@ void Widgets::SetupCentralWidget() { void Widgets::SetupAttitudeDials() { AttitudeDialRow = new QFrame(MajorContainer); - MajorLayout->addWidget(AttitudeDialRow, 0, 0); + MajorLayout->addWidget(AttitudeDialRow, 0, 1); - AttitudeDialOrganizer = new QHBoxLayout(AttitudeDialRow); + AttitudeDialOrganizer = new QVBoxLayout(AttitudeDialRow); AttitudeDialOrganizer->setContentsMargins(20, 20, 20, 20); AttitudeDialRow->setLayout(AttitudeDialOrganizer); @@ -138,58 +136,60 @@ void Widgets::SetupAttitudeDials() { void Widgets::SetGridColumnsMinimums() { if (!MajorLayout) { return; }; const QRect& dims = centralWidget()->geometry(); - MajorLayout->setColumnMinimumWidth(0, 2 * dims.width() / 3); - MajorLayout->setColumnMinimumWidth(1, dims.width() / 3); + MajorLayout->setColumnMinimumWidth(0, 4 * dims.width() / 5); + MajorLayout->setColumnMinimumWidth(1, 1 * dims.width() / 5); } // void Widgets::SetGridColumnsMinimums() void Widgets::SetGridRowsMinimums() { if (!MajorLayout) { return; } const QRect& dims = centralWidget()->geometry(); - MajorLayout->setRowMinimumHeight(0, dims.height() / 3); - MajorLayout->setRowMinimumHeight(1, 2 * dims.height() / 3); + MajorLayout->setRowMinimumHeight(0, 4 * dims.height() / 5); + MajorLayout->setRowMinimumHeight(1, 1 * dims.height() / 5); } // void Widgets::SetGridRowsMinimums() // Buttons {{{ void Widgets::SetupButtons() { - LoadTestRoutineButton = new QPushButton(this); - LoadTestRoutineButton->setText(tr("Load Test Routine")); - - ArmedButton = new QPushButton(this); - ArmedButton->setText(tr("Disarmed")); - ArmedButton->setStyleSheet(" QPushButton { background-color: Yellow; color: Black; } } "); - connect(ArmedButton, &QPushButton::clicked, this, &Widgets::OnArmedButtonPressed); + StandbyIndicator = new QPushButton(this); + StandbyIndicator->setText(tr("Standby")); + SetButtonStatus(StandbyIndicator, Status::STANDBY); - QuantityCalculatorButton = new QPushButton(this); - QuantityCalculatorButton->setText(tr("Calculate Quantity")); + ArmedIndicator = new QPushButton(this); + ArmedIndicator->setText(tr("Disarmed")); + SetButtonStatus(ArmedIndicator, Status::DISARMED); + // testing below + // connect(ArmedIndicator, &QPushButton::clicked, this, &Widgets::OnArmedButtonPressed); - LogOpenButton = new QPushButton(this); - LogOpenButton->setText(tr("Open Log")); + InitiateButton = new QPushButton(this); + InitiateButton->setText(tr("Initiate")); AbortButton = new QPushButton(this); AbortButton->setText(tr("Abort")); - AbortButton->setStyleSheet(" QPushButton { background-color: red } "); + AbortButton->setStyleSheet("color: red"); + + AbortFont.setBold(true); } // void Widgets::SetupButtons() void Widgets::SetupStatusColumn() { StatusColumn = new QGroupBox(tr("Operate"), this); - MajorLayout->addWidget(StatusColumn, 1, 1); + StatusColumn->setObjectName("statusColumn"); + + SetGroupBoxStatus(StatusColumn, Status::DISARMED); + + MajorLayout->addWidget(StatusColumn, 1, 0, 1, 2); QSizePolicy vhexpanding; vhexpanding.setVerticalPolicy(QSizePolicy::MinimumExpanding); vhexpanding.setHorizontalPolicy(QSizePolicy::MinimumExpanding); - StatusColumnOrganizer = new QVBoxLayout(StatusColumn); - LoadTestRoutineButton->setSizePolicy(vhexpanding); - StatusColumnOrganizer->addWidget(LoadTestRoutineButton); - - ArmedButton->setSizePolicy(vhexpanding); - StatusColumnOrganizer->addWidget(ArmedButton); + StatusColumnOrganizer = new QHBoxLayout(StatusColumn); + StandbyIndicator->setSizePolicy(vhexpanding); + StatusColumnOrganizer->addWidget(StandbyIndicator); - QuantityCalculatorButton->setSizePolicy(vhexpanding); - StatusColumnOrganizer->addWidget(QuantityCalculatorButton); + ArmedIndicator->setSizePolicy(vhexpanding); + StatusColumnOrganizer->addWidget(ArmedIndicator); - LogOpenButton->setSizePolicy(vhexpanding); - StatusColumnOrganizer->addWidget(LogOpenButton); + InitiateButton->setSizePolicy(vhexpanding); + StatusColumnOrganizer->addWidget(InitiateButton); AbortButton->setSizePolicy(vhexpanding); StatusColumnOrganizer->addWidget(AbortButton); @@ -199,18 +199,19 @@ void Widgets::SetupStatusColumn() { void Widgets::SetAllButtonTextSize() { ButtonFont.setPixelSize(ButtonFontAdjustment.AdjustPxSize(window())); - LoadTestRoutineButton->setFont(ButtonFont); - ArmedButton->setFont(ButtonFont); - QuantityCalculatorButton->setFont(ButtonFont); - LogOpenButton->setFont(ButtonFont); - AbortButton->setFont(ButtonFont); + StandbyIndicator->setFont(ButtonFont); + ArmedIndicator->setFont(ButtonFont); + InitiateButton->setFont(ButtonFont); StatusColumn->setFont(ButtonFont); + + AbortFont.setPixelSize(AbortFontAdjustment.AdjustPxSize(window())); + AbortButton->setFont(AbortFont); } // void Widgets::SetAllButtonTextSize() // }}} void Widgets::SetupMultiPlot() { Plots = new MultiPlotContainer(this, 3); - MajorLayout->addWidget(Plots, 1, 0); + MajorLayout->addWidget(Plots, 0, 0); QList allPlots = Plots->GetPlots(); Plot::AxisInfo axInfo; @@ -223,7 +224,7 @@ void Widgets::SetupMultiPlot() { std::array RPY = {"Roll", "Pitch", "Yaw"}; auto angle = RPY.begin(); - auto color = Plot::StandardColor.begin(); + auto color = Plot::STANDARD_COLOR.begin(); for (Plot::EmbeddablePlot2D* p : allPlots) { std::string name = *angle; @@ -235,8 +236,8 @@ void Widgets::SetupMultiPlot() { p->AddSeries(info); justWtv.Title = name; - p->SetAxis(Plot::Axis::Quantity, justWtv); - p->SetAxis(Plot::Axis::Time, axInfo); + p->SetAxis(Plot::Axis::QUANTITY, justWtv); + p->SetAxis(Plot::Axis::TIME, axInfo); angle++; color++; @@ -251,30 +252,30 @@ void Widgets::SetupTimeHistoryPlotQChart() { axInfo.Range = { 0, 10 }; axInfo.MajorSpacing = 1; axInfo.MinorSpacing = 0.5; - Plot->SetAxis(Plot::Axis::Time, axInfo); + Plot->SetAxis(Plot::Axis::TIME, axInfo); Plot::SeriesInfo rollInfo; rollInfo.Name = "Roll"; - rollInfo.Color = Plot::StandardColor.at("Red"); + rollInfo.Color = Plot::STANDARD_COLOR.at("Red"); Plot::SeriesInfo pitchInfo; pitchInfo.Name = "Pitch"; - pitchInfo.Color = Plot::StandardColor.at("Green"); + pitchInfo.Color = Plot::STANDARD_COLOR.at("Green"); Plot::SeriesInfo yawInfo; yawInfo.Name = "Yaw"; - yawInfo.Color = Plot::StandardColor.at("Blue"); + yawInfo.Color = Plot::STANDARD_COLOR.at("Blue"); Plot->AddSeries(rollInfo); Plot->AddSeries(pitchInfo); Plot->AddSeries(yawInfo); - stupid_make_data(Plot); + StupidMakeData(Plot); } // void Widgets::SetupTimeHistoryPlotQChart() void Widgets::SetupAttQtysRatesDisplay() { AttQtysRates = new QtyRateDisplay(tr(""), this); - MajorLayout->addWidget(AttQtysRates, 0, 1); + MajorLayout->addWidget(AttQtysRates, 1, 0); RollQtyRate = new QtyRateRow(tr("Roll"), AttQtysRates); RollQtyRate->SetQuantityUnits("°"); @@ -319,16 +320,18 @@ void Widgets::CreateActions() { } // void Widgets::CreateActions() void Widgets::OnArmedButtonPressed() { - bArmedButtonActive = !bArmedButtonActive; + ArmedButtonActive = !ArmedButtonActive; - if (bArmedButtonActive) { - // Active state - green color - ArmedButton->setText(tr("Armed")); - ArmedButton->setStyleSheet(" QPushButton { background-color: red; color: white; } } "); + if (ArmedButtonActive) { + // Armed state - Red + ArmedIndicator->setText(tr("Armed")); + SetButtonStatus(ArmedIndicator, Status::ARMED); + SetGroupBoxStatus(StatusColumn, Status::ARMED); } else { - // Inactive state - default color - ArmedButton->setText(tr("Disarmed")); - ArmedButton->setStyleSheet(" QPushButton { background-color: Yellow; color: Black; } } "); + // Disarmed state - Yellow + ArmedIndicator->setText(tr("Disarmed")); + SetButtonStatus(ArmedIndicator, Status::DISARMED); + SetGroupBoxStatus(StatusColumn, Status::DISARMED); } } // void Widgets::OnArmedButtonPressed() // }}} diff --git a/src/Windowing/WidgetsRecreation.hpp b/src/Windowing/WidgetsRecreation.hpp index 3da5513..bde32bd 100644 --- a/src/Windowing/WidgetsRecreation.hpp +++ b/src/Windowing/WidgetsRecreation.hpp @@ -26,6 +26,9 @@ class Widgets : public QMainWindow { private: QFont ButtonFont{ }; + Util::FontAdjustment ButtonFontAdjustment{ .PxSizeAtMinimum=12 }; + QFont AbortFont{ }; + Util::FontAdjustment AbortFontAdjustment{ .PxSizeAtMinimum=12 }; QWidget* MajorContainer; QGridLayout* MajorLayout; @@ -34,7 +37,7 @@ class Widgets : public QMainWindow { void SetGridRowsMinimums(); QFrame* AttitudeDialRow; - QHBoxLayout* AttitudeDialOrganizer; + QVBoxLayout* AttitudeDialOrganizer; CompositeDial* RollDial; CompositeDial* PitchDial; @@ -56,17 +59,18 @@ class Widgets : public QMainWindow { // im not entirely sure of this part QGroupBox* StatusColumn; - QVBoxLayout* StatusColumnOrganizer; - QPushButton* LoadTestRoutineButton; - QPushButton* ArmedButton; - QPushButton* QuantityCalculatorButton; + QHBoxLayout* StatusColumnOrganizer; + QPushButton* StandbyIndicator; + QPushButton* ArmedIndicator; + QPushButton* InitiateButton; QPushButton* LogOpenButton; QPushButton* AbortButton; - bool bArmedButtonActive = false; // Track armed button state - Util::FontAdjustment ButtonFontAdjustment{ 12 }; + bool ArmedButtonActive = false; // Track armed button state + void SetupButtons(); void SetupStatusColumn(); void SetAllButtonTextSize(); + private slots: void About(); void OnArmedButtonPressed(); diff --git a/test/fs.cpp b/test/fs.cpp index 02d593e..4fad6ac 100644 --- a/test/fs.cpp +++ b/test/fs.cpp @@ -12,7 +12,7 @@ static constexpr std::string_view CONFIG_PATH_NAME = VSCL::FS::GetStandardPath("config"); static void CoutManyNames(void) { - std::ranges::for_each(VSCL::FS::StandardPaths, [](const std::string_view& str){ + std::ranges::for_each(VSCL::FS::STANDARD_PATHS, [](const std::string_view& str){ std::cout << str << "\n"; }); } @@ -32,7 +32,7 @@ int main(void) { CoutManyNames(); std::cout << "Checking for path existences: \n"; - std::for_each(VSCL::FS::StandardPaths.begin(), VSCL::FS::StandardPaths.end(), + std::for_each(VSCL::FS::STANDARD_PATHS.begin(), VSCL::FS::STANDARD_PATHS.end(), [&](const std::string_view& apppath){ std::filesystem::path subdir = whereapp / apppath; std::cout << (subdir) << " exists? ";