diff --git a/scwx-qt/scwx-qt.cmake b/scwx-qt/scwx-qt.cmake index 2a515e88..2b612997 100644 --- a/scwx-qt/scwx-qt.cmake +++ b/scwx-qt/scwx-qt.cmake @@ -162,6 +162,7 @@ set(SRC_REQUEST source/scwx/qt/request/download_request.cpp source/scwx/qt/request/nexrad_file_request.cpp) set(HDR_SETTINGS source/scwx/qt/settings/audio_settings.hpp source/scwx/qt/settings/general_settings.hpp + source/scwx/qt/settings/hotkey_settings.hpp source/scwx/qt/settings/map_settings.hpp source/scwx/qt/settings/palette_settings.hpp source/scwx/qt/settings/product_settings.hpp @@ -176,6 +177,7 @@ set(HDR_SETTINGS source/scwx/qt/settings/audio_settings.hpp source/scwx/qt/settings/ui_settings.hpp) set(SRC_SETTINGS source/scwx/qt/settings/audio_settings.cpp source/scwx/qt/settings/general_settings.cpp + source/scwx/qt/settings/hotkey_settings.cpp source/scwx/qt/settings/map_settings.cpp source/scwx/qt/settings/palette_settings.cpp source/scwx/qt/settings/product_settings.cpp @@ -191,6 +193,7 @@ set(HDR_TYPES source/scwx/qt/types/alert_types.hpp source/scwx/qt/types/event_types.hpp source/scwx/qt/types/font_types.hpp source/scwx/qt/types/github_types.hpp + source/scwx/qt/types/hotkey_types.hpp source/scwx/qt/types/icon_types.hpp source/scwx/qt/types/imgui_font.hpp source/scwx/qt/types/layer_types.hpp @@ -205,6 +208,7 @@ set(HDR_TYPES source/scwx/qt/types/alert_types.hpp source/scwx/qt/types/time_types.hpp) set(SRC_TYPES source/scwx/qt/types/alert_types.cpp source/scwx/qt/types/github_types.cpp + source/scwx/qt/types/hotkey_types.cpp source/scwx/qt/types/icon_types.cpp source/scwx/qt/types/imgui_font.cpp source/scwx/qt/types/layer_types.cpp diff --git a/scwx-qt/source/scwx/qt/manager/settings_manager.cpp b/scwx-qt/source/scwx/qt/manager/settings_manager.cpp index 8a244054..e5e806ea 100644 --- a/scwx-qt/source/scwx/qt/manager/settings_manager.cpp +++ b/scwx-qt/source/scwx/qt/manager/settings_manager.cpp @@ -2,6 +2,7 @@ #include #include #include +#include #include #include #include @@ -132,6 +133,7 @@ boost::json::value SettingsManager::Impl::ConvertSettingsToJson() settings::GeneralSettings::Instance().WriteJson(settingsJson); settings::AudioSettings::Instance().WriteJson(settingsJson); + settings::HotkeySettings::Instance().WriteJson(settingsJson); settings::MapSettings::Instance().WriteJson(settingsJson); settings::PaletteSettings::Instance().WriteJson(settingsJson); settings::ProductSettings::Instance().WriteJson(settingsJson); @@ -147,6 +149,7 @@ void SettingsManager::Impl::GenerateDefaultSettings() settings::GeneralSettings::Instance().SetDefaults(); settings::AudioSettings::Instance().SetDefaults(); + settings::HotkeySettings::Instance().SetDefaults(); settings::MapSettings::Instance().SetDefaults(); settings::PaletteSettings::Instance().SetDefaults(); settings::ProductSettings::Instance().SetDefaults(); @@ -163,6 +166,7 @@ bool SettingsManager::Impl::LoadSettings( jsonDirty |= !settings::GeneralSettings::Instance().ReadJson(settingsJson); jsonDirty |= !settings::AudioSettings::Instance().ReadJson(settingsJson); + jsonDirty |= !settings::HotkeySettings::Instance().ReadJson(settingsJson); jsonDirty |= !settings::MapSettings::Instance().ReadJson(settingsJson); jsonDirty |= !settings::PaletteSettings::Instance().ReadJson(settingsJson); jsonDirty |= !settings::ProductSettings::Instance().ReadJson(settingsJson); diff --git a/scwx-qt/source/scwx/qt/settings/hotkey_settings.cpp b/scwx-qt/source/scwx/qt/settings/hotkey_settings.cpp new file mode 100644 index 00000000..c6aece74 --- /dev/null +++ b/scwx-qt/source/scwx/qt/settings/hotkey_settings.cpp @@ -0,0 +1,117 @@ +#include + +#include + +namespace scwx +{ +namespace qt +{ +namespace settings +{ + +static const std::string logPrefix_ = "scwx::qt::settings::hotkey_settings"; + +static const std::unordered_map kDefaultHotkeys_ { + {types::Hotkey::ChangeMapStyle, QKeySequence {Qt::Key::Key_Z}}, + {types::Hotkey::CopyCursorCoordinates, + QKeySequence {QKeyCombination {Qt::KeyboardModifier::ControlModifier, + Qt::Key::Key_C}}}, + {types::Hotkey::CopyMapCoordinates, + QKeySequence {QKeyCombination {Qt::KeyboardModifier::ControlModifier | + Qt::KeyboardModifier::ShiftModifier, + Qt::Key::Key_C}}}, + {types::Hotkey::MapPanUp, QKeySequence {Qt::Key::Key_W}}, + {types::Hotkey::MapPanDown, QKeySequence {Qt::Key::Key_S}}, + {types::Hotkey::MapPanLeft, QKeySequence {Qt::Key::Key_A}}, + {types::Hotkey::MapPanRight, QKeySequence {Qt::Key::Key_D}}, + {types::Hotkey::MapRotateClockwise, QKeySequence {Qt::Key::Key_E}}, + {types::Hotkey::MapRotateCounterclockwise, QKeySequence {Qt::Key::Key_Q}}, + {types::Hotkey::MapZoomIn, QKeySequence {Qt::Key::Key_Equal}}, + {types::Hotkey::MapZoomOut, QKeySequence {Qt::Key::Key_Minus}}, + {types::Hotkey::ProductTiltDecrease, + QKeySequence {Qt::Key::Key_BracketLeft}}, + {types::Hotkey::ProductTiltIncrease, + QKeySequence {Qt::Key::Key_BracketRight}}, + {types::Hotkey::Unknown, QKeySequence {}}}; + +static bool IsHotkeyValid(const std::string& value); + +class HotkeySettings::Impl +{ +public: + explicit Impl() + { + for (const auto& hotkey : types::HotkeyIterator()) + { + const std::string& name = types::GetHotkeyShortName(hotkey); + const std::string defaultValue = + kDefaultHotkeys_.at(hotkey).toString().toStdString(); + + auto result = + hotkey_.emplace(hotkey, SettingsVariable {name}); + + SettingsVariable& settingsVariable = result.first->second; + + settingsVariable.SetDefault(defaultValue); + settingsVariable.SetValidator(&IsHotkeyValid); + + variables_.push_back(&settingsVariable); + } + + // Add an empty hotkey (not part of registered variables) for error + // handling + hotkey_.emplace(types::Hotkey::Unknown, + SettingsVariable {"?"}); + } + + ~Impl() {} + + std::unordered_map> hotkey_ {}; + std::vector variables_ {}; +}; + +HotkeySettings::HotkeySettings() : + SettingsCategory("hotkeys"), p(std::make_unique()) +{ + RegisterVariables(p->variables_); + SetDefaults(); + + p->variables_.clear(); +} +HotkeySettings::~HotkeySettings() = default; + +HotkeySettings::HotkeySettings(HotkeySettings&&) noexcept = default; +HotkeySettings& HotkeySettings::operator=(HotkeySettings&&) noexcept = default; + +SettingsVariable& +HotkeySettings::hotkey(scwx::qt::types::Hotkey hotkey) const +{ + auto hotkeyVariable = p->hotkey_.find(hotkey); + if (hotkeyVariable == p->hotkey_.cend()) + { + hotkeyVariable = p->hotkey_.find(types::Hotkey::Unknown); + } + return hotkeyVariable->second; +} + +HotkeySettings& HotkeySettings::Instance() +{ + static HotkeySettings hotkeySettings_; + return hotkeySettings_; +} + +bool operator==(const HotkeySettings& lhs, const HotkeySettings& rhs) +{ + return (lhs.p->hotkey_ == rhs.p->hotkey_); +} + +static bool IsHotkeyValid(const std::string& value) +{ + return QKeySequence {QString::fromStdString(value)} + .toString() + .toStdString() == value; +} + +} // namespace settings +} // namespace qt +} // namespace scwx diff --git a/scwx-qt/source/scwx/qt/settings/hotkey_settings.hpp b/scwx-qt/source/scwx/qt/settings/hotkey_settings.hpp new file mode 100644 index 00000000..9fa56cc4 --- /dev/null +++ b/scwx-qt/source/scwx/qt/settings/hotkey_settings.hpp @@ -0,0 +1,42 @@ +#pragma once + +#include +#include +#include + +#include +#include + +namespace scwx +{ +namespace qt +{ +namespace settings +{ + +class HotkeySettings : public SettingsCategory +{ +public: + explicit HotkeySettings(); + ~HotkeySettings(); + + HotkeySettings(const HotkeySettings&) = delete; + HotkeySettings& operator=(const HotkeySettings&) = delete; + + HotkeySettings(HotkeySettings&&) noexcept; + HotkeySettings& operator=(HotkeySettings&&) noexcept; + + SettingsVariable& hotkey(scwx::qt::types::Hotkey hotkey) const; + + static HotkeySettings& Instance(); + + friend bool operator==(const HotkeySettings& lhs, const HotkeySettings& rhs); + +private: + class Impl; + std::unique_ptr p; +}; + +} // namespace settings +} // namespace qt +} // namespace scwx diff --git a/scwx-qt/source/scwx/qt/types/hotkey_types.cpp b/scwx-qt/source/scwx/qt/types/hotkey_types.cpp new file mode 100644 index 00000000..b76c76a5 --- /dev/null +++ b/scwx-qt/source/scwx/qt/types/hotkey_types.cpp @@ -0,0 +1,62 @@ +#include +#include + +#include + +#include + +namespace scwx +{ +namespace qt +{ +namespace types +{ + +static const std::unordered_map hotkeyShortName_ { + {Hotkey::ChangeMapStyle, "change_map_style"}, + {Hotkey::CopyCursorCoordinates, "copy_cursor_coordinates"}, + {Hotkey::CopyMapCoordinates, "copy_map_coordinates"}, + {Hotkey::MapPanUp, "map_pan_up"}, + {Hotkey::MapPanDown, "map_pan_down"}, + {Hotkey::MapPanLeft, "map_pan_left"}, + {Hotkey::MapPanRight, "map_pan_right"}, + {Hotkey::MapRotateClockwise, "map_rotate_clockwise"}, + {Hotkey::MapRotateCounterclockwise, "map_rotate_counterclockwise"}, + {Hotkey::MapZoomIn, "map_zoom_in"}, + {Hotkey::MapZoomOut, "map_zoom_out"}, + {Hotkey::ProductTiltDecrease, "product_tilt_decrease"}, + {Hotkey::ProductTiltIncrease, "product_tilt_increase"}, + {Hotkey::Unknown, "?"}}; + +static const std::unordered_map hotkeyLongName_ { + {Hotkey::ChangeMapStyle, "Change Map Style"}, + {Hotkey::CopyCursorCoordinates, "Copy Cursor Coordinates"}, + {Hotkey::CopyMapCoordinates, "Copy Map Coordinates"}, + {Hotkey::MapPanUp, "Map Pan Up"}, + {Hotkey::MapPanDown, "Map Pan Down"}, + {Hotkey::MapPanLeft, "Map Pan Left"}, + {Hotkey::MapPanRight, "Map Pan Right"}, + {Hotkey::MapRotateClockwise, "Map Rotate Clockwise"}, + {Hotkey::MapRotateCounterclockwise, "Map Rotate Counterclockwise"}, + {Hotkey::MapZoomIn, "Map Zoom In"}, + {Hotkey::MapZoomOut, "Map Zoom Out"}, + {Hotkey::ProductTiltDecrease, "Product Tilt Decrease"}, + {Hotkey::ProductTiltIncrease, "Product Tilt Increase"}, + {Hotkey::Unknown, "?"}}; + +SCWX_GET_ENUM(Hotkey, GetHotkeyFromShortName, hotkeyShortName_) +SCWX_GET_ENUM(Hotkey, GetHotkeyFromLongName, hotkeyLongName_) + +const std::string& GetHotkeyShortName(Hotkey hotkey) +{ + return hotkeyShortName_.at(hotkey); +} + +const std::string& GetHotkeyLongName(Hotkey hotkey) +{ + return hotkeyLongName_.at(hotkey); +} + +} // namespace types +} // namespace qt +} // namespace scwx diff --git a/scwx-qt/source/scwx/qt/types/hotkey_types.hpp b/scwx-qt/source/scwx/qt/types/hotkey_types.hpp new file mode 100644 index 00000000..22699eb8 --- /dev/null +++ b/scwx-qt/source/scwx/qt/types/hotkey_types.hpp @@ -0,0 +1,42 @@ +#pragma once + +#include + +#include + +namespace scwx +{ +namespace qt +{ +namespace types +{ + +enum class Hotkey +{ + ChangeMapStyle, + CopyCursorCoordinates, + CopyMapCoordinates, + MapPanUp, + MapPanDown, + MapPanLeft, + MapPanRight, + MapRotateClockwise, + MapRotateCounterclockwise, + MapZoomIn, + MapZoomOut, + ProductTiltDecrease, + ProductTiltIncrease, + Unknown +}; +typedef scwx::util:: + Iterator + HotkeyIterator; + +Hotkey GetHotkeyFromShortName(const std::string& name); +Hotkey GetHotkeyFromLongName(const std::string& name); +const std::string& GetHotkeyShortName(Hotkey hotkey); +const std::string& GetHotkeyLongName(Hotkey hotkey); + +} // namespace types +} // namespace qt +} // namespace scwx diff --git a/test/data b/test/data index 2ba87405..11c06868 160000 --- a/test/data +++ b/test/data @@ -1 +1 @@ -Subproject commit 2ba8740516bbdc58c848bf71755b2f285aa47938 +Subproject commit 11c068682f636b521ff78b76ddefcb4398784b72