diff --git a/scwx-qt/res/icons/font-awesome-6/volume-high-solid.svg b/scwx-qt/res/icons/font-awesome-6/volume-high-solid.svg
new file mode 100644
index 00000000..21b6c285
--- /dev/null
+++ b/scwx-qt/res/icons/font-awesome-6/volume-high-solid.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/scwx-qt/scwx-qt.qrc b/scwx-qt/scwx-qt.qrc
index 51cc16df..c094673a 100644
--- a/scwx-qt/scwx-qt.qrc
+++ b/scwx-qt/scwx-qt.qrc
@@ -44,6 +44,7 @@
res/icons/font-awesome-6/square-caret-right-regular.svg
res/icons/font-awesome-6/square-minus-regular.svg
res/icons/font-awesome-6/square-plus-regular.svg
+ res/icons/font-awesome-6/volume-high-solid.svg
res/palettes/wct/CC.pal
res/palettes/wct/Default16.pal
res/palettes/wct/DOD_DSD.pal
diff --git a/scwx-qt/source/scwx/qt/settings/settings_interface.cpp b/scwx-qt/source/scwx/qt/settings/settings_interface.cpp
index b7133537..a20e7dfa 100644
--- a/scwx-qt/source/scwx/qt/settings/settings_interface.cpp
+++ b/scwx-qt/source/scwx/qt/settings/settings_interface.cpp
@@ -180,6 +180,32 @@ void SettingsInterface::SetEditWidget(QWidget* widget)
// TODO: Display invalid status
});
}
+ else if constexpr (std::is_same_v)
+ {
+ // If the line is edited (not programatically changed), stage the new
+ // value
+ QObject::connect(lineEdit,
+ &QLineEdit::textEdited,
+ p->context_.get(),
+ [this](const QString& text)
+ {
+ // Convert to a double
+ bool ok;
+ double value = text.toDouble(&ok);
+ if (ok)
+ {
+ // Attempt to stage the value
+ p->stagedValid_ =
+ p->variable_->StageValue(value);
+ p->UpdateResetButton();
+ }
+ else
+ {
+ p->stagedValid_ = false;
+ p->UpdateResetButton();
+ }
+ });
+ }
else if constexpr (std::is_same_v>)
{
// If the line is edited (not programatically changed), stage the new
@@ -310,6 +336,52 @@ void SettingsInterface::SetEditWidget(QWidget* widget)
});
}
}
+ else if (QDoubleSpinBox* doubleSpinBox =
+ dynamic_cast(widget))
+ {
+ if constexpr (std::is_floating_point_v)
+ {
+ const std::optional minimum = p->variable_->GetMinimum();
+ const std::optional maximum = p->variable_->GetMaximum();
+
+ if (minimum.has_value())
+ {
+ doubleSpinBox->setMinimum(static_cast(*minimum));
+ }
+ if (maximum.has_value())
+ {
+ doubleSpinBox->setMaximum(static_cast(*maximum));
+ }
+
+ // If the spin box is edited, stage a changed value
+ QObject::connect(
+ doubleSpinBox,
+ &QDoubleSpinBox::valueChanged,
+ p->context_.get(),
+ [this](double d)
+ {
+ const T value = p->variable_->GetValue();
+ const std::optional staged = p->variable_->GetStaged();
+
+ // If there is a value staged, and the new value is the same as
+ // the current value, reset the staged value
+ if (staged.has_value() && static_cast(d) == value)
+ {
+ p->variable_->Reset();
+ p->stagedValid_ = true;
+ p->UpdateResetButton();
+ }
+ // If there is no staged value, or if the new value is different
+ // than what is staged, attempt to stage the value
+ else if (!staged.has_value() || static_cast(d) != *staged)
+ {
+ p->stagedValid_ = p->variable_->StageValue(static_cast(d));
+ p->UpdateResetButton();
+ }
+ // Otherwise, don't process an unchanged value
+ });
+ }
+ }
p->UpdateEditWidget();
}
@@ -378,6 +450,10 @@ void SettingsInterface::Impl::SetWidgetText(U* widget, const T& currentValue)
{
widget->setText(QString::number(currentValue));
}
+ else if constexpr (std::is_floating_point_v)
+ {
+ widget->setText(QString::number(currentValue));
+ }
else if constexpr (std::is_same_v)
{
if (mapFromValue_ != nullptr)
@@ -448,6 +524,14 @@ void SettingsInterface::Impl::UpdateEditWidget()
spinBox->setValue(static_cast(currentValue));
}
}
+ else if (QDoubleSpinBox* doubleSpinBox =
+ dynamic_cast(editWidget_))
+ {
+ if constexpr (std::is_floating_point_v)
+ {
+ doubleSpinBox->setValue(static_cast(currentValue));
+ }
+ }
}
template
diff --git a/scwx-qt/source/scwx/qt/ui/settings_dialog.cpp b/scwx-qt/source/scwx/qt/ui/settings_dialog.cpp
index efc267bf..296e33e0 100644
--- a/scwx-qt/source/scwx/qt/ui/settings_dialog.cpp
+++ b/scwx-qt/source/scwx/qt/ui/settings_dialog.cpp
@@ -6,12 +6,14 @@
#include
#include
#include
+#include
#include
#include
#include
#include
#include
#include
+#include
#include
#include
#include
@@ -84,6 +86,24 @@ static const std::unordered_map
{"VIL", {0u, 255u, 1.0f, 2.5f}},
{"???", {0u, 15u, 0.0f, 1.0f}}};
+#define SCWX_ENUM_MAP_FROM_VALUE(Type, Iterator, ToName) \
+ [](const std::string& text) -> std::string \
+ { \
+ for (Type enumValue : Iterator) \
+ { \
+ const std::string enumName = ToName(enumValue); \
+ \
+ if (boost::iequals(text, enumName)) \
+ { \
+ /* Return label */ \
+ return enumName; \
+ } \
+ } \
+ \
+ /* Label not found, return unknown */ \
+ return "?"; \
+ }
+
class SettingsDialogImpl
{
public:
@@ -104,6 +124,9 @@ public:
&antiAliasingEnabled_,
&updateNotificationsEnabled_,
&debugEnabled_,
+ &alertAudioLocationMethod_,
+ &alertAudioLatitude_,
+ &alertAudioLongitude_,
&hoverTextWrap_,
&tooltipMethod_,
&placefileTextDropShadowEnabled_}}
@@ -136,6 +159,7 @@ public:
void SetupGeneralTab();
void SetupPalettesColorTablesTab();
void SetupPalettesAlertsTab();
+ void SetupAudioTab();
void SetupTextTab();
void ShowColorDialog(QLineEdit* lineEdit, QFrame* frame = nullptr);
@@ -191,6 +215,13 @@ public:
settings::SettingsInterface>
inactiveAlertColors_ {};
+ settings::SettingsInterface alertAudioLocationMethod_ {};
+ settings::SettingsInterface alertAudioLatitude_ {};
+ settings::SettingsInterface alertAudioLongitude_ {};
+
+ std::unordered_map>
+ alertAudioEnabled_ {};
+
std::unordered_map>
fontFamilies_ {};
@@ -223,6 +254,9 @@ SettingsDialog::SettingsDialog(QWidget* parent) :
// Palettes > Alerts
p->SetupPalettesAlertsTab();
+ // Audio
+ p->SetupAudioTab();
+
// Text
p->SetupTextTab();
@@ -766,6 +800,70 @@ void SettingsDialogImpl::SetupPalettesAlertsTab()
}
}
+void SettingsDialogImpl::SetupAudioTab()
+{
+ settings::AudioSettings& audioSettings = settings::AudioSettings::Instance();
+
+ for (const auto& locationMethod : types::LocationMethodIterator())
+ {
+ self_->ui->alertAudioLocationMethodComboBox->addItem(
+ QString::fromStdString(types::GetLocationMethodName(locationMethod)));
+ }
+
+ alertAudioLocationMethod_.SetSettingsVariable(
+ audioSettings.alert_location_method());
+ alertAudioLocationMethod_.SetMapFromValueFunction(
+ SCWX_ENUM_MAP_FROM_VALUE(types::LocationMethod,
+ types::LocationMethodIterator(),
+ types::GetLocationMethodName));
+ alertAudioLocationMethod_.SetMapToValueFunction(
+ [](std::string text) -> std::string
+ {
+ // Convert label to lower case and return
+ boost::to_lower(text);
+ return text;
+ });
+ alertAudioLocationMethod_.SetEditWidget(
+ self_->ui->alertAudioLocationMethodComboBox);
+ alertAudioLocationMethod_.SetResetButton(
+ self_->ui->resetAlertAudioLocationMethodButton);
+
+ alertAudioLatitude_.SetSettingsVariable(audioSettings.alert_latitude());
+ alertAudioLatitude_.SetEditWidget(self_->ui->alertAudioLatitudeSpinBox);
+ alertAudioLatitude_.SetResetButton(self_->ui->resetAlertAudioLatitudeButton);
+
+ alertAudioLongitude_.SetSettingsVariable(audioSettings.alert_longitude());
+ alertAudioLongitude_.SetEditWidget(self_->ui->alertAudioLongitudeSpinBox);
+ alertAudioLongitude_.SetResetButton(
+ self_->ui->resetAlertAudioLongitudeButton);
+
+ auto alertAudioLayout =
+ static_cast(self_->ui->alertAudioGroupBox->layout());
+
+ for (const auto& phenomenon : types::GetAlertAudioPhenomena())
+ {
+ QCheckBox* alertAudioCheckbox = new QCheckBox(self_);
+ alertAudioCheckbox->setText(
+ QString::fromStdString(awips::GetPhenomenonText(phenomenon)));
+
+ static_cast(self_->ui->alertAudioGroupBox->layout())
+ ->addWidget(
+ alertAudioCheckbox, alertAudioLayout->rowCount(), 0, 1, -1);
+
+ // Create settings interface
+ auto result = alertAudioEnabled_.emplace(
+ phenomenon, settings::SettingsInterface {});
+ auto& alertAudioEnabled = result.first->second;
+
+ // Add to settings list
+ settings_.push_back(&alertAudioEnabled);
+
+ alertAudioEnabled.SetSettingsVariable(
+ audioSettings.alert_enabled(phenomenon));
+ alertAudioEnabled.SetEditWidget(alertAudioCheckbox);
+ }
+}
+
void SettingsDialogImpl::SetupTextTab()
{
settings::TextSettings& textSettings = settings::TextSettings::Instance();
diff --git a/scwx-qt/source/scwx/qt/ui/settings_dialog.ui b/scwx-qt/source/scwx/qt/ui/settings_dialog.ui
index f770135f..b7be3c87 100644
--- a/scwx-qt/source/scwx/qt/ui/settings_dialog.ui
+++ b/scwx-qt/source/scwx/qt/ui/settings_dialog.ui
@@ -77,6 +77,15 @@
:/res/icons/font-awesome-6/palette-solid.svg:/res/icons/font-awesome-6/palette-solid.svg
+ -
+
+ Audio
+
+
+
+ :/res/icons/font-awesome-6/volume-high-solid.svg:/res/icons/font-awesome-6/volume-high-solid.svg
+
+
-
Text
@@ -364,8 +373,8 @@
0
0
- 63
- 18
+ 508
+ 383
@@ -436,6 +445,128 @@
+
+
+ -
+
+
+ Alerts
+
+
+
-
+
+
+ Latitude
+
+
+
+ -
+
+
+ 6
+
+
+ -90.000000000000000
+
+
+ 90.000000000000000
+
+
+ 0.010000000000000
+
+
+
+ -
+
+
+ ...
+
+
+
+ :/res/icons/font-awesome-6/rotate-left-solid.svg:/res/icons/font-awesome-6/rotate-left-solid.svg
+
+
+
+ -
+
+
+ Longitude
+
+
+
+ -
+
+
+ ...
+
+
+
+ :/res/icons/font-awesome-6/rotate-left-solid.svg:/res/icons/font-awesome-6/rotate-left-solid.svg
+
+
+
+ -
+
+
+ ...
+
+
+
+ :/res/icons/font-awesome-6/rotate-left-solid.svg:/res/icons/font-awesome-6/rotate-left-solid.svg
+
+
+
+ -
+
+
+ Location Method
+
+
+
+ -
+
+
+ 6
+
+
+ -180.000000000000000
+
+
+ 180.000000000000000
+
+
+ 0.010000000000000
+
+
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+
+
+
+
+ -
+
+
+ Qt::Vertical
+
+
+
+ 20
+ 309
+
+
+
+
+
+
-