diff --git a/scwx-qt/source/scwx/qt/settings/settings_interface.cpp b/scwx-qt/source/scwx/qt/settings/settings_interface.cpp index dd729da0..49fe7513 100644 --- a/scwx-qt/source/scwx/qt/settings/settings_interface.cpp +++ b/scwx-qt/source/scwx/qt/settings/settings_interface.cpp @@ -9,6 +9,7 @@ #include #include #include +#include #include #include #include @@ -33,6 +34,9 @@ public: ~Impl() {} + template + void SetWidgetText(U* widget, const T& currentValue); + void UpdateEditWidget(); void UpdateResetButton(); @@ -105,6 +109,11 @@ void SettingsInterface::SetEditWidget(QWidget* widget) p->editWidget_ = widget; + if (widget == nullptr) + { + return; + } + if (QLineEdit* lineEdit = dynamic_cast(widget)) { if constexpr (std::is_same_v) @@ -274,33 +283,36 @@ void SettingsInterface::SetResetButton(QAbstractButton* button) p->resetButton_ = button; - QObject::connect(p->resetButton_, - &QAbstractButton::clicked, - p->context_.get(), - [this]() - { - T defaultValue = p->variable_->GetDefault(); - - if (p->variable_->GetValue() == defaultValue) + if (p->resetButton_ != nullptr) + { + QObject::connect(p->resetButton_, + &QAbstractButton::clicked, + p->context_.get(), + [this]() { - // If the current value is default, reset the staged - // value - p->variable_->Reset(); - p->stagedValid_ = true; - p->UpdateEditWidget(); - p->UpdateResetButton(); - } - else - { - // Stage the default value - p->stagedValid_ = - p->variable_->StageValue(defaultValue); - p->UpdateEditWidget(); - p->UpdateResetButton(); - } - }); + T defaultValue = p->variable_->GetDefault(); - p->UpdateResetButton(); + if (p->variable_->GetValue() == defaultValue) + { + // If the current value is default, reset the + // staged value + p->variable_->Reset(); + p->stagedValid_ = true; + p->UpdateEditWidget(); + p->UpdateResetButton(); + } + else + { + // Stage the default value + p->stagedValid_ = + p->variable_->StageValue(defaultValue); + p->UpdateEditWidget(); + p->UpdateResetButton(); + } + }); + + p->UpdateResetButton(); + } } template @@ -317,6 +329,39 @@ void SettingsInterface::SetMapToValueFunction( p->mapToValue_ = function; } +template +template +void SettingsInterface::Impl::SetWidgetText(U* widget, const T& currentValue) +{ + if constexpr (std::is_integral_v) + { + widget->setText(QString::number(currentValue)); + } + else if constexpr (std::is_same_v) + { + if (mapFromValue_ != nullptr) + { + widget->setText(QString::fromStdString(mapFromValue_(currentValue))); + } + else + { + widget->setText(QString::fromStdString(currentValue)); + } + } + else if constexpr (std::is_same_v>) + { + if (mapFromValue_ != nullptr) + { + widget->setText(QString::fromStdString(mapFromValue_(currentValue))); + } + else + { + widget->setText(QString::fromStdString( + fmt::format("{}", fmt::join(currentValue, ", ")))); + } + } +} + template void SettingsInterface::Impl::UpdateEditWidget() { @@ -327,35 +372,11 @@ void SettingsInterface::Impl::UpdateEditWidget() if (QLineEdit* lineEdit = dynamic_cast(editWidget_)) { - if constexpr (std::is_integral_v) - { - lineEdit->setText(QString::number(currentValue)); - } - else if constexpr (std::is_same_v) - { - if (mapFromValue_ != nullptr) - { - lineEdit->setText( - QString::fromStdString(mapFromValue_(currentValue))); - } - else - { - lineEdit->setText(QString::fromStdString(currentValue)); - } - } - else if constexpr (std::is_same_v>) - { - if (mapFromValue_ != nullptr) - { - lineEdit->setText( - QString::fromStdString(mapFromValue_(currentValue))); - } - else - { - lineEdit->setText(QString::fromStdString( - fmt::format("{}", fmt::join(currentValue, ", ")))); - } - } + SetWidgetText(lineEdit, currentValue); + } + else if (QLabel* label = dynamic_cast(editWidget_)) + { + SetWidgetText(label, currentValue); } else if (QCheckBox* checkBox = dynamic_cast(editWidget_)) { diff --git a/scwx-qt/source/scwx/qt/settings/settings_variable.cpp b/scwx-qt/source/scwx/qt/settings/settings_variable.cpp index 270a2eed..1f7661c0 100644 --- a/scwx-qt/source/scwx/qt/settings/settings_variable.cpp +++ b/scwx-qt/source/scwx/qt/settings/settings_variable.cpp @@ -239,6 +239,12 @@ std::optional SettingsVariable::GetStaged() const return p->staged_; } +template +T SettingsVariable::GetStagedOrValue() const +{ + return p->staged_.value_or(GetValue()); +} + template T SettingsVariable::GetDefault() const { diff --git a/scwx-qt/source/scwx/qt/settings/settings_variable.hpp b/scwx-qt/source/scwx/qt/settings/settings_variable.hpp index c7999c0d..c05c543f 100644 --- a/scwx-qt/source/scwx/qt/settings/settings_variable.hpp +++ b/scwx-qt/source/scwx/qt/settings/settings_variable.hpp @@ -103,6 +103,14 @@ public: */ std::optional GetStaged() const; + /** + * Gets the staged value of the settings variable, if defined, otherwise the + * current value. + * + * @return Staged value or current value + */ + T GetStagedOrValue() const; + /** * Validate the value against the defined parameters of the settings * variable. diff --git a/scwx-qt/source/scwx/qt/settings/text_settings.cpp b/scwx-qt/source/scwx/qt/settings/text_settings.cpp index 980abf40..5bc9946b 100644 --- a/scwx-qt/source/scwx/qt/settings/text_settings.cpp +++ b/scwx-qt/source/scwx/qt/settings/text_settings.cpp @@ -79,6 +79,13 @@ public: void InitializeFontVariables(); + friend bool operator==(const FontData& lhs, const FontData& rhs) + { + return (lhs.fontFamily_ == rhs.fontFamily_ && + lhs.fontStyle_ == rhs.fontStyle_ && + lhs.fontPointSize_ == rhs.fontPointSize_); + } + TextSettings* self_; std::unordered_map fontData_ {}; @@ -168,7 +175,8 @@ TextSettings& TextSettings::Instance() bool operator==(const TextSettings& lhs, const TextSettings& rhs) { - return (lhs.p->hoverTextWrap_ == rhs.p->hoverTextWrap_ && + return (lhs.p->fontData_ == rhs.p->fontData_ && + lhs.p->hoverTextWrap_ == rhs.p->hoverTextWrap_ && lhs.p->tooltipMethod_ == rhs.p->tooltipMethod_); } diff --git a/scwx-qt/source/scwx/qt/ui/settings_dialog.cpp b/scwx-qt/source/scwx/qt/ui/settings_dialog.cpp index c2449e9f..c175fe7b 100644 --- a/scwx-qt/source/scwx/qt/ui/settings_dialog.cpp +++ b/scwx-qt/source/scwx/qt/ui/settings_dialog.cpp @@ -9,6 +9,7 @@ #include #include #include +#include #include #include #include @@ -119,7 +120,10 @@ public: } // Configure font dialog - fontDialog_->setOptions(QFontDialog::FontDialogOption::ScalableFonts); + fontDialog_->setOptions( + QFontDialog::FontDialogOption::DontUseNativeDialog | + QFontDialog::FontDialogOption::ScalableFonts); + fontDialog_->setWindowModality(Qt::WindowModality::WindowModal); } ~SettingsDialogImpl() = default; @@ -133,6 +137,10 @@ public: void ShowColorDialog(QLineEdit* lineEdit, QFrame* frame = nullptr); void UpdateRadarDialogLocation(const std::string& id); + QFont GetSelectedFont(); + void SelectFontCategory(types::FontCategory fontCategory); + void UpdateFontDisplayData(); + void ApplyChanges(); void DiscardChanges(); void ResetToDefault(); @@ -157,6 +165,8 @@ public: QStandardItemModel* fontCategoryModel_; + types::FontCategory selectedFontCategory_ {types::FontCategory::Unknown}; + settings::SettingsInterface defaultRadarSite_ {}; settings::SettingsInterface> fontSizes_ {}; settings::SettingsInterface gridWidth_ {}; @@ -251,18 +261,6 @@ void SettingsDialogImpl::ConnectSignals() } }); - QObject::connect(self_->ui->fontSelectButton, - &QAbstractButton::clicked, - self_, - [this]() { fontDialog_->show(); }); - - QObject::connect( - fontDialog_, - &QFontDialog::fontSelected, - self_, - [this](const QFont& font) - { logger_->debug("Selected font: {}", font.toString().toStdString()); }); - // Update the Radar Site dialog "map" location with the currently selected // radar site auto& defaultRadarSite = *defaultRadarSite_.GetSettingsVariable(); @@ -270,6 +268,66 @@ void SettingsDialogImpl::ConnectSignals() [this](const std::string& newValue) { UpdateRadarDialogLocation(newValue); }); + QObject::connect( + self_->ui->fontListView->selectionModel(), + &QItemSelectionModel::selectionChanged, + self_, + [this](const QItemSelection& selected, const QItemSelection& deselected) + { + if (selected.size() == 0 && deselected.size() == 0) + { + // Items which stay selected but change their index are not + // included in selected and deselected. Thus, this signal might + // be emitted with both selected and deselected empty, if only + // the indices of selected items change. + return; + } + + if (selected.size() > 0) + { + QModelIndex selectedIndex = selected[0].indexes()[0]; + QVariant variantData = + self_->ui->fontListView->model()->data(selectedIndex); + if (variantData.typeId() == QMetaType::QString) + { + types::FontCategory fontCategory = + types::GetFontCategory(variantData.toString().toStdString()); + SelectFontCategory(fontCategory); + UpdateFontDisplayData(); + } + } + }); + + QObject::connect(self_->ui->fontSelectButton, + &QAbstractButton::clicked, + self_, + [this]() + { + fontDialog_->setCurrentFont(GetSelectedFont()); + fontDialog_->show(); + }); + + QObject::connect(fontDialog_, + &QFontDialog::fontSelected, + self_, + [this](const QFont& font) + { + logger_->debug("Selected font: {}", + font.toString().toStdString()); + + fontFamilies_.at(selectedFontCategory_) + .GetSettingsVariable() + ->StageValue(font.family().toStdString()); + fontStyles_.at(selectedFontCategory_) + .GetSettingsVariable() + ->StageValue(font.styleName().toStdString()); + fontPointSizes_.at(selectedFontCategory_) + .GetSettingsVariable() + ->StageValue(font.pointSizeF()); + + UpdateFontDisplayData(); + }); + QObject::connect( self_->ui->buttonBox, &QDialogButtonBox::clicked, @@ -706,6 +764,8 @@ void SettingsDialogImpl::SetupTextTab() fontSize.SetSettingsVariable(textSettings.font_point_size(fontCategory)); } self_->ui->fontListView->setCurrentIndex(fontCategoryModel_->index(0, 0)); + SelectFontCategory(*types::FontCategoryIterator().begin()); + UpdateFontDisplayData(); hoverTextWrap_.SetSettingsVariable(textSettings.hover_text_wrap()); hoverTextWrap_.SetEditWidget(self_->ui->hoverTextWrapSpinBox); @@ -861,6 +921,73 @@ void SettingsDialogImpl::UpdateRadarDialogLocation(const std::string& id) } } +QFont SettingsDialogImpl::GetSelectedFont() +{ + std::string fontFamily = fontFamilies_.at(selectedFontCategory_) + .GetSettingsVariable() + ->GetStagedOrValue(); + std::string fontStyle = fontStyles_.at(selectedFontCategory_) + .GetSettingsVariable() + ->GetStagedOrValue(); + units::font_size::points fontSize { + fontPointSizes_.at(selectedFontCategory_) + .GetSettingsVariable() + ->GetStagedOrValue()}; + + QFont font(QString::fromStdString(fontFamily)); + font.setStyleName(QString::fromStdString(fontStyle)); + font.setPointSizeF(fontSize.value()); + + return font; +} + +void SettingsDialogImpl::SelectFontCategory(types::FontCategory fontCategory) +{ + if (selectedFontCategory_ != types::FontCategory::Unknown && + selectedFontCategory_ != fontCategory) + { + auto& fontFamily = fontFamilies_.at(selectedFontCategory_); + auto& fontStyle = fontStyles_.at(selectedFontCategory_); + auto& fontSize = fontPointSizes_.at(selectedFontCategory_); + + fontFamily.SetResetButton(nullptr); + fontStyle.SetResetButton(nullptr); + fontSize.SetResetButton(nullptr); + + fontFamily.SetEditWidget(nullptr); + fontStyle.SetEditWidget(nullptr); + fontSize.SetEditWidget(nullptr); + } + + if (selectedFontCategory_ != fontCategory) + { + auto& fontFamily = fontFamilies_.at(fontCategory); + auto& fontStyle = fontStyles_.at(fontCategory); + auto& fontSize = fontPointSizes_.at(fontCategory); + + fontFamily.SetResetButton(self_->ui->resetFontButton); + fontStyle.SetResetButton(self_->ui->resetFontButton); + fontSize.SetResetButton(self_->ui->resetFontButton); + + fontFamily.SetEditWidget(self_->ui->fontNameLabel); + fontStyle.SetEditWidget(self_->ui->fontStyleLabel); + fontSize.SetEditWidget(self_->ui->fontSizeLabel); + } + + selectedFontCategory_ = fontCategory; +} + +void SettingsDialogImpl::UpdateFontDisplayData() +{ + QFont font = GetSelectedFont(); + + self_->ui->fontNameLabel->setText(font.family()); + self_->ui->fontStyleLabel->setText(font.styleName()); + self_->ui->fontSizeLabel->setText(QString::number(font.pointSizeF())); + + self_->ui->fontPreviewLabel->setFont(font); +} + void SettingsDialogImpl::ApplyChanges() { logger_->info("Applying settings changes"); diff --git a/scwx-qt/source/scwx/qt/ui/settings_dialog.ui b/scwx-qt/source/scwx/qt/ui/settings_dialog.ui index e921f38a..de695341 100644 --- a/scwx-qt/source/scwx/qt/ui/settings_dialog.ui +++ b/scwx-qt/source/scwx/qt/ui/settings_dialog.ui @@ -102,7 +102,7 @@ - 0 + 2 @@ -468,36 +468,16 @@ 0 - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - Reset All Fonts - - - - - - - + Display Item: + + + @@ -538,10 +518,10 @@ - QFrame::StyledPanel + QFrame::Panel - QFrame::Raised + QFrame::Plain