From c73698619df5397702d35569a1f3432e9be8a130 Mon Sep 17 00:00:00 2001 From: AdenKoperczak Date: Thu, 28 Nov 2024 10:35:55 -0500 Subject: [PATCH 01/31] Use name as hover text for marker --- scwx-qt/source/scwx/qt/map/marker_layer.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/scwx-qt/source/scwx/qt/map/marker_layer.cpp b/scwx-qt/source/scwx/qt/map/marker_layer.cpp index 0480a63e..4e1a2dd0 100644 --- a/scwx-qt/source/scwx/qt/map/marker_layer.cpp +++ b/scwx-qt/source/scwx/qt/map/marker_layer.cpp @@ -61,6 +61,7 @@ void MarkerLayer::Impl::ReloadMarkers() std::shared_ptr icon = geoIcons_->AddIcon(); geoIcons_->SetIconTexture(icon, markerIconName_, 0); geoIcons_->SetIconLocation(icon, marker.latitude, marker.longitude); + geoIcons_->SetIconHoverText(icon, marker.name); }); geoIcons_->FinishIcons(); From daa5bd24dc7082d7d952e1f62ef6e60f30e37f0f Mon Sep 17 00:00:00 2001 From: AdenKoperczak Date: Thu, 28 Nov 2024 10:49:27 -0500 Subject: [PATCH 02/31] Add q_color_modulate for modulating the color of QIcons --- scwx-qt/scwx-qt.cmake | 2 + .../source/scwx/qt/util/q_color_modulate.cpp | 56 +++++++++++++++++++ .../source/scwx/qt/util/q_color_modulate.hpp | 22 ++++++++ 3 files changed, 80 insertions(+) create mode 100644 scwx-qt/source/scwx/qt/util/q_color_modulate.cpp create mode 100644 scwx-qt/source/scwx/qt/util/q_color_modulate.hpp diff --git a/scwx-qt/scwx-qt.cmake b/scwx-qt/scwx-qt.cmake index 1c654b0e..54703605 100644 --- a/scwx-qt/scwx-qt.cmake +++ b/scwx-qt/scwx-qt.cmake @@ -357,6 +357,7 @@ set(HDR_UTIL source/scwx/qt/util/color.hpp source/scwx/qt/util/network.hpp source/scwx/qt/util/streams.hpp source/scwx/qt/util/texture_atlas.hpp + source/scwx/qt/util/q_color_modulate.hpp source/scwx/qt/util/q_file_buffer.hpp source/scwx/qt/util/q_file_input_stream.hpp source/scwx/qt/util/time.hpp @@ -369,6 +370,7 @@ set(SRC_UTIL source/scwx/qt/util/color.cpp source/scwx/qt/util/maplibre.cpp source/scwx/qt/util/network.cpp source/scwx/qt/util/texture_atlas.cpp + source/scwx/qt/util/q_color_modulate.cpp source/scwx/qt/util/q_file_buffer.cpp source/scwx/qt/util/q_file_input_stream.cpp source/scwx/qt/util/time.cpp diff --git a/scwx-qt/source/scwx/qt/util/q_color_modulate.cpp b/scwx-qt/source/scwx/qt/util/q_color_modulate.cpp new file mode 100644 index 00000000..567fc62d --- /dev/null +++ b/scwx-qt/source/scwx/qt/util/q_color_modulate.cpp @@ -0,0 +1,56 @@ +#include + +#include +#include +#include +#include +#include + +namespace scwx +{ +namespace qt +{ +namespace util +{ + +void modulateColors_(QImage& image, const QColor& color) +{ + for (int y = 0; y < image.height(); ++y) + { + QRgb* line = reinterpret_cast(image.scanLine(y)); + for (int x = 0; x < image.width(); ++x) + { + QRgb& rgb = line[x]; + int red = qRed(rgb) * color.redF(); + int green = qGreen(rgb) * color.greenF(); + int blue = qBlue(rgb) * color.blueF(); + int alpha = qAlpha(rgb) * color.alphaF(); + + rgb = qRgba(red, green, blue, alpha); + } + } +} + +QImage modulateColors(const QImage& image, const QColor& color) +{ + QImage copy = image.copy(); + modulateColors_(copy, color); + return copy; +} + +QPixmap modulateColors(const QPixmap& pixmap, const QColor& color) +{ + QImage image = pixmap.toImage(); + modulateColors_(image, color); + return QPixmap::fromImage(image); +} + +QIcon modulateColors(const QIcon& icon, const QSize& size, const QColor& color) +{ + QPixmap pixmap = modulateColors(icon.pixmap(size), color); + return QIcon(pixmap); +} + +} // namespace util +} // namespace qt +} // namespace scwx diff --git a/scwx-qt/source/scwx/qt/util/q_color_modulate.hpp b/scwx-qt/source/scwx/qt/util/q_color_modulate.hpp new file mode 100644 index 00000000..c54b852f --- /dev/null +++ b/scwx-qt/source/scwx/qt/util/q_color_modulate.hpp @@ -0,0 +1,22 @@ +#pragma once + +#include +#include +#include +#include +#include + +namespace scwx +{ +namespace qt +{ +namespace util +{ + +QImage modulateColors(const QImage& image, const QColor& color); +QPixmap modulateColors(const QPixmap& pixmap, const QColor& color); +QIcon modulateColors(const QIcon& icon, const QSize& size, const QColor& color); + +} // namespace util +} // namespace qt +} // namespace scwx From 1dce1b2b35972f53195cbf0480b9b65c42f430b9 Mon Sep 17 00:00:00 2001 From: AdenKoperczak Date: Thu, 28 Nov 2024 11:07:37 -0500 Subject: [PATCH 03/31] Added new icons for location markers. All icons are white, so they can be color modulated to the correct color. --- .../icons/font-awesome-6/briefcase-solid.svg | 1 + .../font-awesome-6/building-columns-solid.svg | 1 + .../icons/font-awesome-6/caravan-solid.svg | 1 + .../font-awesome-6/house-solid-white.svg | 1 + .../location-crosshairs-solid.svg | 1 + .../res/icons/font-awesome-6/location-pin.svg | 4 +++ .../icons/font-awesome-6/star-solid-white.svg | 1 + .../res/icons/font-awesome-6/tent-solid.svg | 1 + .../res/textures/images/location-marker.svg | 2 +- scwx-qt/scwx-qt.qrc | 8 ++++++ .../source/scwx/qt/types/texture_types.cpp | 27 +++++++++++++++++++ .../source/scwx/qt/types/texture_types.hpp | 9 +++++++ 12 files changed, 56 insertions(+), 1 deletion(-) create mode 100644 scwx-qt/res/icons/font-awesome-6/briefcase-solid.svg create mode 100644 scwx-qt/res/icons/font-awesome-6/building-columns-solid.svg create mode 100644 scwx-qt/res/icons/font-awesome-6/caravan-solid.svg create mode 100644 scwx-qt/res/icons/font-awesome-6/house-solid-white.svg create mode 100644 scwx-qt/res/icons/font-awesome-6/location-crosshairs-solid.svg create mode 100644 scwx-qt/res/icons/font-awesome-6/location-pin.svg create mode 100644 scwx-qt/res/icons/font-awesome-6/star-solid-white.svg create mode 100644 scwx-qt/res/icons/font-awesome-6/tent-solid.svg diff --git a/scwx-qt/res/icons/font-awesome-6/briefcase-solid.svg b/scwx-qt/res/icons/font-awesome-6/briefcase-solid.svg new file mode 100644 index 00000000..b16bc330 --- /dev/null +++ b/scwx-qt/res/icons/font-awesome-6/briefcase-solid.svg @@ -0,0 +1 @@ + diff --git a/scwx-qt/res/icons/font-awesome-6/building-columns-solid.svg b/scwx-qt/res/icons/font-awesome-6/building-columns-solid.svg new file mode 100644 index 00000000..cf0df19a --- /dev/null +++ b/scwx-qt/res/icons/font-awesome-6/building-columns-solid.svg @@ -0,0 +1 @@ + diff --git a/scwx-qt/res/icons/font-awesome-6/caravan-solid.svg b/scwx-qt/res/icons/font-awesome-6/caravan-solid.svg new file mode 100644 index 00000000..c341214f --- /dev/null +++ b/scwx-qt/res/icons/font-awesome-6/caravan-solid.svg @@ -0,0 +1 @@ + diff --git a/scwx-qt/res/icons/font-awesome-6/house-solid-white.svg b/scwx-qt/res/icons/font-awesome-6/house-solid-white.svg new file mode 100644 index 00000000..59f65e1e --- /dev/null +++ b/scwx-qt/res/icons/font-awesome-6/house-solid-white.svg @@ -0,0 +1 @@ + diff --git a/scwx-qt/res/icons/font-awesome-6/location-crosshairs-solid.svg b/scwx-qt/res/icons/font-awesome-6/location-crosshairs-solid.svg new file mode 100644 index 00000000..5bb1ea5c --- /dev/null +++ b/scwx-qt/res/icons/font-awesome-6/location-crosshairs-solid.svg @@ -0,0 +1 @@ + diff --git a/scwx-qt/res/icons/font-awesome-6/location-pin.svg b/scwx-qt/res/icons/font-awesome-6/location-pin.svg new file mode 100644 index 00000000..4b6182cd --- /dev/null +++ b/scwx-qt/res/icons/font-awesome-6/location-pin.svg @@ -0,0 +1,4 @@ + + + + diff --git a/scwx-qt/res/icons/font-awesome-6/star-solid-white.svg b/scwx-qt/res/icons/font-awesome-6/star-solid-white.svg new file mode 100644 index 00000000..41bcd103 --- /dev/null +++ b/scwx-qt/res/icons/font-awesome-6/star-solid-white.svg @@ -0,0 +1 @@ + diff --git a/scwx-qt/res/icons/font-awesome-6/tent-solid.svg b/scwx-qt/res/icons/font-awesome-6/tent-solid.svg new file mode 100644 index 00000000..9f159d60 --- /dev/null +++ b/scwx-qt/res/icons/font-awesome-6/tent-solid.svg @@ -0,0 +1 @@ + diff --git a/scwx-qt/res/textures/images/location-marker.svg b/scwx-qt/res/textures/images/location-marker.svg index 8ebb064f..3eef9d9e 100644 --- a/scwx-qt/res/textures/images/location-marker.svg +++ b/scwx-qt/res/textures/images/location-marker.svg @@ -6,6 +6,6 @@ + stroke="#ffffff" stroke-width="20" fill="none"/> diff --git a/scwx-qt/scwx-qt.qrc b/scwx-qt/scwx-qt.qrc index cca0f62c..ee3fcc8e 100644 --- a/scwx-qt/scwx-qt.qrc +++ b/scwx-qt/scwx-qt.qrc @@ -32,6 +32,9 @@ res/icons/font-awesome-6/angles-up-solid.svg res/icons/font-awesome-6/backward-step-solid.svg res/icons/font-awesome-6/book-solid.svg + res/icons/font-awesome-6/briefcase-solid.svg + res/icons/font-awesome-6/building-solid.svg + res/icons/font-awesome-6/caravan-solid.svg res/icons/font-awesome-6/copy-regular.svg res/icons/font-awesome-6/discord.svg res/icons/font-awesome-6/earth-americas-solid.svg @@ -40,8 +43,11 @@ res/icons/font-awesome-6/gears-solid.svg res/icons/font-awesome-6/github.svg res/icons/font-awesome-6/house-solid.svg + res/icons/font-awesome-6/house-solid-white.svg res/icons/font-awesome-6/keyboard-regular.svg res/icons/font-awesome-6/layer-group-solid.svg + res/icons/font-awesome-6/location-crosshairs-solid.svg + res/icons/font-awesome-6/location-pin.svg res/icons/font-awesome-6/palette-solid.svg res/icons/font-awesome-6/pause-solid.svg res/icons/font-awesome-6/play-solid.svg @@ -53,7 +59,9 @@ res/icons/font-awesome-6/square-minus-regular.svg res/icons/font-awesome-6/square-plus-regular.svg res/icons/font-awesome-6/star-solid.svg + res/icons/font-awesome-6/star-solid-white.svg res/icons/font-awesome-6/stop-solid.svg + res/icons/font-awesome-6/tent-solid.svg res/icons/font-awesome-6/volume-high-solid.svg res/palettes/wct/CC.pal res/palettes/wct/Default16.pal diff --git a/scwx-qt/source/scwx/qt/types/texture_types.cpp b/scwx-qt/source/scwx/qt/types/texture_types.cpp index 7f0c7a24..336a26d8 100644 --- a/scwx-qt/source/scwx/qt/types/texture_types.cpp +++ b/scwx-qt/source/scwx/qt/types/texture_types.cpp @@ -25,8 +25,35 @@ static const std::unordered_map imageTextureInfo_ { {ImageTexture::Cursor17, {"images/cursor-17", ":/res/textures/images/cursor-17.png"}}, {ImageTexture::Dot3, {"images/dot-3", ":/res/textures/images/dot-3.png"}}, + {ImageTexture::LocationBriefcase, + {"images/location-briefcase", + ":/res/icons/font-awesome-6/briefcase-solid.svg"}}, + {ImageTexture::LocationBuildingColumns, + {"images/location-building-columns", + ":/res/icons/font-awesome-6/building-columns-solid.svg"}}, + {ImageTexture::LocationBuilding, + {"images/location-building", + ":/res/icons/font-awesome-6/building-solid.svg"}}, + {ImageTexture::LocationCaravan, + {"images/location-caravan", + ":/res/icons/font-awesome-6/caravan-solid.svg"}}, + {ImageTexture::LocationCrosshair, + {"images/location-crosshair", + ":/res/icons/font-awesome-6/location-crosshairs-solid.svg"}}, + {ImageTexture::LocationHouse, + {"images/location-house", + ":/res/icons/font-awesome-6/house-solid-white.svg"}}, {ImageTexture::LocationMarker, {"images/location-marker", ":/res/textures/images/location-marker.svg"}}, + {ImageTexture::LocationPin, + {"images/location-pin", + ":/res/icons/font-awesome-6/location-pin.svg"}}, + {ImageTexture::LocationStar, + {"images/location-star", + ":/res/icons/font-awesome-6/star-solid-white.svg"}}, + {ImageTexture::LocationTent, + {"images/location-tent", + ":/res/icons/font-awesome-6/tent-solid.svg"}}, {ImageTexture::MapboxLogo, {"images/mapbox-logo", ":/res/textures/images/mapbox-logo.svg"}}, {ImageTexture::MapTilerLogo, diff --git a/scwx-qt/source/scwx/qt/types/texture_types.hpp b/scwx-qt/source/scwx/qt/types/texture_types.hpp index 307a7638..d5eabc4a 100644 --- a/scwx-qt/source/scwx/qt/types/texture_types.hpp +++ b/scwx-qt/source/scwx/qt/types/texture_types.hpp @@ -18,7 +18,16 @@ enum class ImageTexture Crosshairs24, Cursor17, Dot3, + LocationBriefcase, + LocationBuildingColumns, + LocationBuilding, + LocationCaravan, + LocationCrosshair, + LocationHouse, LocationMarker, + LocationPin, + LocationStar, + LocationTent, MapboxLogo, MapTilerLogo }; From 875fb8a8c97c733a2b3d4c75e7efd4793b5f5f72 Mon Sep 17 00:00:00 2001 From: AdenKoperczak Date: Thu, 28 Nov 2024 11:14:32 -0500 Subject: [PATCH 04/31] Added building-solid.svg icon (missed in last commit) --- scwx-qt/res/icons/font-awesome-6/building-solid.svg | 1 + 1 file changed, 1 insertion(+) create mode 100644 scwx-qt/res/icons/font-awesome-6/building-solid.svg diff --git a/scwx-qt/res/icons/font-awesome-6/building-solid.svg b/scwx-qt/res/icons/font-awesome-6/building-solid.svg new file mode 100644 index 00000000..6f6d3f24 --- /dev/null +++ b/scwx-qt/res/icons/font-awesome-6/building-solid.svg @@ -0,0 +1 @@ + From 7ed89fdd5d4c5ea3a80902fa42299f311019acb7 Mon Sep 17 00:00:00 2001 From: AdenKoperczak Date: Thu, 28 Nov 2024 11:17:31 -0500 Subject: [PATCH 05/31] added marker_types code for dealing with new marker icons --- scwx-qt/scwx-qt.cmake | 3 +- scwx-qt/source/scwx/qt/types/marker_types.cpp | 34 +++++++++++++++++++ scwx-qt/source/scwx/qt/types/marker_types.hpp | 25 ++++++++++++++ 3 files changed, 61 insertions(+), 1 deletion(-) create mode 100644 scwx-qt/source/scwx/qt/types/marker_types.cpp diff --git a/scwx-qt/scwx-qt.cmake b/scwx-qt/scwx-qt.cmake index 54703605..7aca4dff 100644 --- a/scwx-qt/scwx-qt.cmake +++ b/scwx-qt/scwx-qt.cmake @@ -222,8 +222,8 @@ set(HDR_TYPES source/scwx/qt/types/alert_types.hpp source/scwx/qt/types/layer_types.hpp source/scwx/qt/types/location_types.hpp source/scwx/qt/types/map_types.hpp - source/scwx/qt/types/media_types.hpp source/scwx/qt/types/marker_types.hpp + source/scwx/qt/types/media_types.hpp source/scwx/qt/types/qt_types.hpp source/scwx/qt/types/radar_product_record.hpp source/scwx/qt/types/text_event_key.hpp @@ -239,6 +239,7 @@ set(SRC_TYPES source/scwx/qt/types/alert_types.cpp source/scwx/qt/types/layer_types.cpp source/scwx/qt/types/location_types.cpp source/scwx/qt/types/map_types.cpp + source/scwx/qt/types/marker_types.cpp source/scwx/qt/types/media_types.cpp source/scwx/qt/types/qt_types.cpp source/scwx/qt/types/radar_product_record.cpp diff --git a/scwx-qt/source/scwx/qt/types/marker_types.cpp b/scwx-qt/source/scwx/qt/types/marker_types.cpp new file mode 100644 index 00000000..ce63490a --- /dev/null +++ b/scwx-qt/source/scwx/qt/types/marker_types.cpp @@ -0,0 +1,34 @@ +#include + +namespace scwx +{ +namespace qt +{ +namespace types +{ + +const std::vector& getMarkerIcons() +{ + static std::vector markerIcons = {}; + if (markerIcons.size() == 0) + { + markerIcons = { + MarkerIconInfo(types::ImageTexture::LocationMarker, -1, -1), + MarkerIconInfo(types::ImageTexture::LocationPin, 6, 16), + MarkerIconInfo(types::ImageTexture::LocationCrosshair, -1, -1), + MarkerIconInfo(types::ImageTexture::LocationStar, -1, -1), + MarkerIconInfo(types::ImageTexture::LocationBriefcase, -1, -1), + MarkerIconInfo(types::ImageTexture::LocationBuildingColumns, -1, -1), + MarkerIconInfo(types::ImageTexture::LocationBuilding, -1, -1), + MarkerIconInfo(types::ImageTexture::LocationCaravan, -1, -1), + MarkerIconInfo(types::ImageTexture::LocationHouse, -1, -1), + MarkerIconInfo(types::ImageTexture::LocationTent, -1, -1), + }; + } + + return markerIcons; +} + +} // namespace types +} // namespace qt +} // namespace scwx diff --git a/scwx-qt/source/scwx/qt/types/marker_types.hpp b/scwx-qt/source/scwx/qt/types/marker_types.hpp index e3d28e26..80f7430f 100644 --- a/scwx-qt/source/scwx/qt/types/marker_types.hpp +++ b/scwx-qt/source/scwx/qt/types/marker_types.hpp @@ -1,8 +1,12 @@ #pragma once +#include + #include #include +#include + namespace scwx { namespace qt @@ -24,6 +28,27 @@ struct MarkerInfo double longitude; }; +struct MarkerIconInfo { + explicit MarkerIconInfo(types::ImageTexture texture, + std::int32_t hotX, + std::int32_t hotY) : + name{types::GetTextureName(texture)}, + path{types::GetTexturePath(texture)}, + hotX{hotX}, + hotY{hotY}, + qIcon{QIcon(QString::fromStdString(path))} + { + } + + std::string name; + std::string path; + std::int32_t hotX; + std::int32_t hotY; + QIcon qIcon; +}; + +const std::vector& getMarkerIcons(); + } // namespace types } // namespace qt } // namespace scwx From 6da34fc151d29e17c9859ec65bfbffebb05ecd13 Mon Sep 17 00:00:00 2001 From: AdenKoperczak Date: Thu, 28 Nov 2024 11:50:58 -0500 Subject: [PATCH 06/31] Added location marker icon support to marker_types and marker_manager --- .../source/scwx/qt/manager/marker_manager.cpp | 49 ++++++++++++++++--- scwx-qt/source/scwx/qt/types/marker_types.hpp | 23 ++++++--- .../scwx/qt/ui/marker_settings_widget.cpp | 9 +++- 3 files changed, 67 insertions(+), 14 deletions(-) diff --git a/scwx-qt/source/scwx/qt/manager/marker_manager.cpp b/scwx-qt/source/scwx/qt/manager/marker_manager.cpp index 99208a10..2fece570 100644 --- a/scwx-qt/source/scwx/qt/manager/marker_manager.cpp +++ b/scwx-qt/source/scwx/qt/manager/marker_manager.cpp @@ -1,5 +1,6 @@ #include #include +#include #include #include #include @@ -27,6 +28,12 @@ static const auto logger_ = scwx::util::Logger::Create(logPrefix_); static const std::string kNameName_ = "name"; static const std::string kLatitudeName_ = "latitude"; static const std::string kLongitudeName_ = "longitude"; +static const std::string kIconName_ = "icon"; +static const std::string kIconColorName_ = "icon-color"; + +static const std::string defaultIconName = types::getMarkerIcons()[0].name; +static const boost::gil::rgba8_pixel_t defaultIconColor = + util::color::ToRgba8PixelT("#ffff0000"); class MarkerManager::Impl { @@ -59,10 +66,7 @@ class MarkerManager::Impl class MarkerManager::Impl::MarkerRecord { public: - MarkerRecord(const std::string& name, double latitude, double longitude) : - markerInfo_ {types::MarkerInfo(name, latitude, longitude)} - { - } + MarkerRecord(const types::MarkerInfo& info) : markerInfo_ {info} { @@ -81,16 +85,47 @@ class MarkerManager::Impl::MarkerRecord { jv = {{kNameName_, record->markerInfo_.name}, {kLatitudeName_, record->markerInfo_.latitude}, - {kLongitudeName_, record->markerInfo_.longitude}}; + {kLongitudeName_, record->markerInfo_.longitude}, + {kIconName_, record->markerInfo_.iconName}, + {kIconColorName_, util::color::ToArgbString(record->markerInfo_.iconColor)}}; } + friend MarkerRecord tag_invoke(boost::json::value_to_tag, const boost::json::value& jv) { - return MarkerRecord( + + const boost::json::object& jo = jv.as_object(); + + std::string iconName = defaultIconName; + boost::gil::rgba8_pixel_t iconColor = defaultIconColor; + + if (jo.contains(kIconName_) && jo.at(kIconName_).is_string()) + { + iconName = boost::json::value_to(jv.at(kIconName_)); + } + + if (jo.contains(kIconColorName_) && jo.at(kIconName_).is_string()) + { + try { + iconColor = util::color::ToRgba8PixelT( + boost::json::value_to(jv.at(kIconColorName_))); + } + catch (const std::exception& ex) + { + logger_->warn( + "Could not parse color value in location-markers.json with the " + "following exception: {}", + ex.what()); + } + } + + return MarkerRecord(types::MarkerInfo( boost::json::value_to(jv.at(kNameName_)), boost::json::value_to(jv.at(kLatitudeName_)), - boost::json::value_to(jv.at(kLongitudeName_))); + boost::json::value_to(jv.at(kLongitudeName_)), + iconName, + iconColor)); } }; diff --git a/scwx-qt/source/scwx/qt/types/marker_types.hpp b/scwx-qt/source/scwx/qt/types/marker_types.hpp index 80f7430f..2d1aa987 100644 --- a/scwx-qt/source/scwx/qt/types/marker_types.hpp +++ b/scwx-qt/source/scwx/qt/types/marker_types.hpp @@ -5,6 +5,7 @@ #include #include +#include #include namespace scwx @@ -17,15 +18,25 @@ typedef std::uint64_t MarkerId; struct MarkerInfo { - MarkerInfo(const std::string& name, double latitude, double longitude) : - name {name}, latitude {latitude}, longitude {longitude} + MarkerInfo(const std::string& name, + double latitude, + double longitude, + const std::string iconName, + boost::gil::rgba8_pixel_t iconColor) : + name {name}, + latitude {latitude}, + longitude {longitude}, + iconName {iconName}, + iconColor {iconColor} { } - MarkerId id; - std::string name; - double latitude; - double longitude; + MarkerId id; + std::string name; + double latitude; + double longitude; + std::string iconName; + boost::gil::rgba8_pixel_t iconColor; }; struct MarkerIconInfo { diff --git a/scwx-qt/source/scwx/qt/ui/marker_settings_widget.cpp b/scwx-qt/source/scwx/qt/ui/marker_settings_widget.cpp index 0c2bc614..6a1e04f3 100644 --- a/scwx-qt/source/scwx/qt/ui/marker_settings_widget.cpp +++ b/scwx-qt/source/scwx/qt/ui/marker_settings_widget.cpp @@ -7,6 +7,8 @@ #include #include +#include + #include namespace scwx @@ -63,7 +65,12 @@ void MarkerSettingsWidgetImpl::ConnectSignals() self_, [this]() { - markerManager_->add_marker(types::MarkerInfo("", 0, 0)); + markerManager_->add_marker(types::MarkerInfo( + "", + 0, + 0, + types::getMarkerIcons()[0].name, + util::color::ToRgba8PixelT("#ffff0000"))); }); QObject::connect( self_->ui->removeButton, From 1a32748b8e0db88e52572a5f3c0975e9075c05fe Mon Sep 17 00:00:00 2001 From: AdenKoperczak Date: Thu, 28 Nov 2024 12:00:36 -0500 Subject: [PATCH 07/31] Add location marker icon and color rendering on the map. --- scwx-qt/source/scwx/qt/manager/marker_manager.cpp | 6 +++--- scwx-qt/source/scwx/qt/map/marker_layer.cpp | 14 ++++++++------ 2 files changed, 11 insertions(+), 9 deletions(-) diff --git a/scwx-qt/source/scwx/qt/manager/marker_manager.cpp b/scwx-qt/source/scwx/qt/manager/marker_manager.cpp index 2fece570..30cb0d4b 100644 --- a/scwx-qt/source/scwx/qt/manager/marker_manager.cpp +++ b/scwx-qt/source/scwx/qt/manager/marker_manager.cpp @@ -31,9 +31,6 @@ static const std::string kLongitudeName_ = "longitude"; static const std::string kIconName_ = "icon"; static const std::string kIconColorName_ = "icon-color"; -static const std::string defaultIconName = types::getMarkerIcons()[0].name; -static const boost::gil::rgba8_pixel_t defaultIconColor = - util::color::ToRgba8PixelT("#ffff0000"); class MarkerManager::Impl { @@ -94,6 +91,9 @@ class MarkerManager::Impl::MarkerRecord friend MarkerRecord tag_invoke(boost::json::value_to_tag, const boost::json::value& jv) { + static const std::string defaultIconName = types::getMarkerIcons()[0].name; + static const boost::gil::rgba8_pixel_t defaultIconColor = + util::color::ToRgba8PixelT("#ffff0000"); const boost::json::object& jo = jv.as_object(); diff --git a/scwx-qt/source/scwx/qt/map/marker_layer.cpp b/scwx-qt/source/scwx/qt/map/marker_layer.cpp index 4e1a2dd0..311a347b 100644 --- a/scwx-qt/source/scwx/qt/map/marker_layer.cpp +++ b/scwx-qt/source/scwx/qt/map/marker_layer.cpp @@ -2,7 +2,6 @@ #include #include #include -#include #include namespace scwx @@ -29,8 +28,6 @@ class MarkerLayer::Impl void ConnectSignals(); MarkerLayer* self_; - const std::string& markerIconName_ { - types::GetTextureName(types::ImageTexture::LocationMarker)}; std::shared_ptr geoIcons_; }; @@ -59,9 +56,10 @@ void MarkerLayer::Impl::ReloadMarkers() [this](const types::MarkerInfo& marker) { std::shared_ptr icon = geoIcons_->AddIcon(); - geoIcons_->SetIconTexture(icon, markerIconName_, 0); + geoIcons_->SetIconTexture(icon, marker.iconName, 0); geoIcons_->SetIconLocation(icon, marker.latitude, marker.longitude); geoIcons_->SetIconHoverText(icon, marker.name); + geoIcons_->SetIconModulate(icon, marker.iconColor); }); geoIcons_->FinishIcons(); @@ -82,7 +80,11 @@ void MarkerLayer::Initialize() DrawLayer::Initialize(); p->geoIcons_->StartIconSheets(); - p->geoIcons_->AddIconSheet(p->markerIconName_); + for (auto& markerIcon : types::getMarkerIcons()) + { + p->geoIcons_->AddIconSheet( + markerIcon.name, 0, 0, markerIcon.hotX, markerIcon.hotY); + } p->geoIcons_->FinishIconSheets(); p->ReloadMarkers(); @@ -90,8 +92,8 @@ void MarkerLayer::Initialize() void MarkerLayer::Render(const QMapLibre::CustomLayerRenderParameters& params) { - // auto markerManager = manager::MarkerManager::Instance(); gl::OpenGLFunctions& gl = context()->gl(); + context()->set_render_parameters(params); DrawLayer::Render(params); From d0d9adfd1a3ecc5fbbf798222e9971dedc2c63a5 Mon Sep 17 00:00:00 2001 From: AdenKoperczak Date: Thu, 28 Nov 2024 12:33:14 -0500 Subject: [PATCH 08/31] Switch to using new edit_marker_dialog for marker adding and editting --- scwx-qt/scwx-qt.cmake | 3 + .../source/scwx/qt/manager/marker_manager.cpp | 3 +- .../source/scwx/qt/manager/marker_manager.hpp | 2 +- scwx-qt/source/scwx/qt/model/marker_model.cpp | 101 +------ .../source/scwx/qt/ui/edit_marker_dialog.cpp | 249 ++++++++++++++++++ .../source/scwx/qt/ui/edit_marker_dialog.hpp | 41 +++ .../source/scwx/qt/ui/edit_marker_dialog.ui | 188 +++++++++++++ .../scwx/qt/ui/marker_settings_widget.cpp | 37 ++- 8 files changed, 514 insertions(+), 110 deletions(-) create mode 100644 scwx-qt/source/scwx/qt/ui/edit_marker_dialog.cpp create mode 100644 scwx-qt/source/scwx/qt/ui/edit_marker_dialog.hpp create mode 100644 scwx-qt/source/scwx/qt/ui/edit_marker_dialog.ui diff --git a/scwx-qt/scwx-qt.cmake b/scwx-qt/scwx-qt.cmake index 7aca4dff..b8630306 100644 --- a/scwx-qt/scwx-qt.cmake +++ b/scwx-qt/scwx-qt.cmake @@ -256,6 +256,7 @@ set(HDR_UI source/scwx/qt/ui/about_dialog.hpp source/scwx/qt/ui/county_dialog.hpp source/scwx/qt/ui/download_dialog.hpp source/scwx/qt/ui/edit_line_dialog.hpp + source/scwx/qt/ui/edit_marker_dialog.hpp source/scwx/qt/ui/flow_layout.hpp source/scwx/qt/ui/gps_info_dialog.hpp source/scwx/qt/ui/hotkey_edit.hpp @@ -286,6 +287,7 @@ set(SRC_UI source/scwx/qt/ui/about_dialog.cpp source/scwx/qt/ui/county_dialog.cpp source/scwx/qt/ui/download_dialog.cpp source/scwx/qt/ui/edit_line_dialog.cpp + source/scwx/qt/ui/edit_marker_dialog.cpp source/scwx/qt/ui/flow_layout.cpp source/scwx/qt/ui/gps_info_dialog.cpp source/scwx/qt/ui/hotkey_edit.cpp @@ -315,6 +317,7 @@ set(UI_UI source/scwx/qt/ui/about_dialog.ui source/scwx/qt/ui/collapsible_group.ui source/scwx/qt/ui/county_dialog.ui source/scwx/qt/ui/edit_line_dialog.ui + source/scwx/qt/ui/edit_marker_dialog.ui source/scwx/qt/ui/gps_info_dialog.ui source/scwx/qt/ui/imgui_debug_dialog.ui source/scwx/qt/ui/layer_dialog.ui diff --git a/scwx-qt/source/scwx/qt/manager/marker_manager.cpp b/scwx-qt/source/scwx/qt/manager/marker_manager.cpp index 30cb0d4b..fbfe2a2d 100644 --- a/scwx-qt/source/scwx/qt/manager/marker_manager.cpp +++ b/scwx-qt/source/scwx/qt/manager/marker_manager.cpp @@ -313,7 +313,7 @@ void MarkerManager::set_marker(types::MarkerId id, const types::MarkerInfo& mark Q_EMIT MarkersUpdated(); } -void MarkerManager::add_marker(const types::MarkerInfo& marker) +types::MarkerId MarkerManager::add_marker(const types::MarkerInfo& marker) { types::MarkerId id; { @@ -326,6 +326,7 @@ void MarkerManager::add_marker(const types::MarkerInfo& marker) } Q_EMIT MarkerAdded(id); Q_EMIT MarkersUpdated(); + return id; } void MarkerManager::remove_marker(types::MarkerId id) diff --git a/scwx-qt/source/scwx/qt/manager/marker_manager.hpp b/scwx-qt/source/scwx/qt/manager/marker_manager.hpp index 37ec1c31..17ccb8e6 100644 --- a/scwx-qt/source/scwx/qt/manager/marker_manager.hpp +++ b/scwx-qt/source/scwx/qt/manager/marker_manager.hpp @@ -25,7 +25,7 @@ class MarkerManager : public QObject std::optional get_marker(types::MarkerId id); std::optional get_index(types::MarkerId id); void set_marker(types::MarkerId id, const types::MarkerInfo& marker); - void add_marker(const types::MarkerInfo& marker); + types::MarkerId add_marker(const types::MarkerInfo& marker); void remove_marker(types::MarkerId id); void move_marker(size_t from, size_t to); diff --git a/scwx-qt/source/scwx/qt/model/marker_model.cpp b/scwx-qt/source/scwx/qt/model/marker_model.cpp index e550312e..c035900a 100644 --- a/scwx-qt/source/scwx/qt/model/marker_model.cpp +++ b/scwx-qt/source/scwx/qt/model/marker_model.cpp @@ -78,26 +78,11 @@ Qt::ItemFlags MarkerModel::flags(const QModelIndex& index) const { Qt::ItemFlags flags = QAbstractTableModel::flags(index); - switch (index.column()) - { - case static_cast(Column::Name): - case static_cast(Column::Latitude): - case static_cast(Column::Longitude): - flags |= Qt::ItemFlag::ItemIsEditable; - break; - default: - break; - } - return flags; } QVariant MarkerModel::data(const QModelIndex& index, int role) const { - - static const char COORDINATE_FORMAT = 'g'; - static const int COORDINATE_PRECISION = 10; - if (!index.isValid() || index.row() < 0 || static_cast(index.row()) >= p->markerIds_.size()) { @@ -118,8 +103,7 @@ QVariant MarkerModel::data(const QModelIndex& index, int role) const { case static_cast(Column::Name): if (role == Qt::ItemDataRole::DisplayRole || - role == Qt::ItemDataRole::ToolTipRole || - role == Qt::ItemDataRole::EditRole) + role == Qt::ItemDataRole::ToolTipRole) { return QString::fromStdString(markerInfo->name); } @@ -132,11 +116,6 @@ QVariant MarkerModel::data(const QModelIndex& index, int role) const return QString::fromStdString( common::GetLatitudeString(markerInfo->latitude)); } - else if (role == Qt::ItemDataRole::EditRole) - { - return QString::number( - markerInfo->latitude, COORDINATE_FORMAT, COORDINATE_PRECISION); - } break; case static_cast(Column::Longitude): @@ -146,11 +125,6 @@ QVariant MarkerModel::data(const QModelIndex& index, int role) const return QString::fromStdString( common::GetLongitudeString(markerInfo->longitude)); } - else if (role == Qt::ItemDataRole::EditRole) - { - return QString::number( - markerInfo->longitude, COORDINATE_FORMAT, COORDINATE_PRECISION); - } break; break; @@ -199,78 +173,9 @@ QVariant MarkerModel::headerData(int section, return QVariant(); } -bool MarkerModel::setData(const QModelIndex& index, - const QVariant& value, - int role) +bool MarkerModel::setData(const QModelIndex&, const QVariant&, int) { - - if (!index.isValid() || index.row() < 0 || - static_cast(index.row()) >= p->markerIds_.size()) - { - return false; - } - - types::MarkerId id = p->markerIds_[index.row()]; - std::optional markerInfo = - p->markerManager_->get_marker(id); - if (!markerInfo) - { - return false; - } - bool result = false; - - switch(index.column()) - { - case static_cast(Column::Name): - if (role == Qt::ItemDataRole::EditRole) - { - QString str = value.toString(); - markerInfo->name = str.toStdString(); - p->markerManager_->set_marker(id, *markerInfo); - result = true; - } - break; - - case static_cast(Column::Latitude): - if (role == Qt::ItemDataRole::EditRole) - { - QString str = value.toString(); - bool ok; - double latitude = str.toDouble(&ok); - if (!str.isEmpty() && ok && -90 <= latitude && latitude <= 90) - { - markerInfo->latitude = latitude; - p->markerManager_->set_marker(id, *markerInfo); - result = true; - } - } - break; - - case static_cast(Column::Longitude): - if (role == Qt::ItemDataRole::EditRole) - { - QString str = value.toString(); - bool ok; - double longitude = str.toDouble(&ok); - if (!str.isEmpty() && ok && -180 <= longitude && longitude <= 180) - { - markerInfo->longitude = longitude; - p->markerManager_->set_marker(id, *markerInfo); - result = true; - } - } - break; - - default: - break; - } - - if (result) - { - Q_EMIT dataChanged(index, index); - } - - return result; + return false; } void MarkerModel::HandleMarkersInitialized(size_t count) diff --git a/scwx-qt/source/scwx/qt/ui/edit_marker_dialog.cpp b/scwx-qt/source/scwx/qt/ui/edit_marker_dialog.cpp new file mode 100644 index 00000000..d84b3c0c --- /dev/null +++ b/scwx-qt/source/scwx/qt/ui/edit_marker_dialog.cpp @@ -0,0 +1,249 @@ +#include "edit_marker_dialog.hpp" +#include "ui_edit_marker_dialog.h" + +#include +#include +#include +#include +#include + +#include +#include + +#include +#include +#include +#include +#include +#include + +namespace scwx +{ +namespace qt +{ +namespace ui +{ + +static const std::string logPrefix_ = "scwx::qt::ui::edit_marker_dialog"; +static const auto logger_ = scwx::util::Logger::Create(logPrefix_); + +class EditMarkerDialog::Impl +{ +public: + explicit Impl(EditMarkerDialog* self) : + self_{self} + { + } + + void show_color_dialog(); + void set_icon_color(const std::string& color); + + void connect_signals(); + + void handle_accepted(); + void handle_rejected(); + + EditMarkerDialog* self_; + QPushButton* deleteButton_; + QIcon get_colored_icon(size_t index, const std::string& color); + + std::shared_ptr markerManager_ = + manager::MarkerManager::Instance(); + const std::vector* icons_; + types::MarkerId editId_; + bool adding_; +}; + +QIcon EditMarkerDialog::Impl::get_colored_icon(size_t index, + const std::string& color) +{ + if (index >= icons_->size()) + { + return QIcon(); + } + + return util::modulateColors((*icons_)[index].qIcon, + self_->ui->iconComboBox->iconSize(), + QColor(QString::fromStdString(color))); +} + +EditMarkerDialog::EditMarkerDialog(QWidget* parent) : + QDialog(parent), + p {std::make_unique(this)}, + ui(new Ui::EditMarkerDialog) +{ + ui->setupUi(this); + + p->icons_ = &types::getMarkerIcons(); + for (auto& markerIcon : (*p->icons_)) + { + ui->iconComboBox->addItem(markerIcon.qIcon, + QString(""), + QString::fromStdString(markerIcon.name)); + } + p->deleteButton_ = + ui->buttonBox->addButton("Delete", QDialogButtonBox::DestructiveRole); + p->connect_signals(); +} + +EditMarkerDialog::~EditMarkerDialog() +{ + delete ui; +} + +void EditMarkerDialog::setup() +{ + setup(0, 0); +} + +void EditMarkerDialog::setup(double latitude, double longitude) +{ + ui->iconComboBox->setCurrentIndex(0); + // By default use foreground color as marker color, mainly so the icons + // are vissable in the dropdown menu. + QColor color = QWidget::palette().color(QWidget::foregroundRole()); + p->editId_ = p->markerManager_->add_marker(types::MarkerInfo( + "", + latitude, + longitude, + ui->iconComboBox->currentData().toString().toStdString(), + boost::gil::rgba8_pixel_t {static_cast(color.red()), + static_cast(color.green()), + static_cast(color.blue()), + static_cast(color.alpha())})); + + setup(p->editId_); + p->adding_ = true; +} + +void EditMarkerDialog::setup(types::MarkerId id) +{ + std::optional marker = + p->markerManager_->get_marker(id); + if (!marker) + { + return; + } + + p->editId_ = id; + p->adding_ = false; + + int iconIndex = + ui->iconComboBox->findData(QString::fromStdString(marker->iconName)); + if (iconIndex < 0 || marker->iconName == "") + { + iconIndex = 0; + } + + std::string iconColorStr = util::color::ToArgbString(marker->iconColor); + + ui->nameLineEdit->setText(QString::fromStdString(marker->name)); + ui->iconComboBox->setCurrentIndex(iconIndex); + ui->latitudeDoubleSpinBox->setValue(marker->latitude); + ui->longitudeDoubleSpinBox->setValue(marker->longitude); + ui->iconColorLineEdit->setText(QString::fromStdString(iconColorStr)); + + p->set_icon_color(iconColorStr); +} + +types::MarkerInfo EditMarkerDialog::get_marker_info() const +{ + QString colorName = ui->iconColorLineEdit->text(); + boost::gil::rgba8_pixel_t color = + util::color::ToRgba8PixelT(colorName.toStdString()); + + return types::MarkerInfo( + ui->nameLineEdit->text().toStdString(), + ui->latitudeDoubleSpinBox->value(), + ui->longitudeDoubleSpinBox->value(), + ui->iconComboBox->currentData().toString().toStdString(), + color); +} + +void EditMarkerDialog::Impl::show_color_dialog() +{ + + QColorDialog* dialog = new QColorDialog(self_); + + dialog->setAttribute(Qt::WA_DeleteOnClose); + dialog->setOption(QColorDialog::ColorDialogOption::ShowAlphaChannel); + + QColor initialColor(self_->ui->iconColorLineEdit->text()); + if (initialColor.isValid()) + { + dialog->setCurrentColor(initialColor); + } + + QObject::connect(dialog, + &QColorDialog::colorSelected, + self_, + [this](const QColor& qColor) + { + QString colorName = + qColor.name(QColor::NameFormat::HexArgb); + self_->ui->iconColorLineEdit->setText(colorName); + }); + dialog->open(); +} + +void EditMarkerDialog::Impl::connect_signals() +{ + connect(self_, + &EditMarkerDialog::accepted, + self_, + [this]() { handle_accepted(); }); + + connect(self_, + &EditMarkerDialog::rejected, + self_, + [this]() { handle_rejected(); }); + + connect(deleteButton_, + &QPushButton::clicked, + self_, + [this]() + { + markerManager_->remove_marker(editId_); + self_->done(0); + }); + + connect(self_->ui->iconColorLineEdit, + &QLineEdit::textEdited, + self_, + [=, this](const QString& text) + { set_icon_color(text.toStdString()); }); + + connect(self_->ui->iconColorButton, + &QAbstractButton::clicked, + self_, + [=, this]() { self_->p->show_color_dialog(); }); +} + +void EditMarkerDialog::Impl::set_icon_color(const std::string& color) +{ + self_->ui->iconColorFrame->setStyleSheet( + QString::fromStdString(fmt::format("background-color: {}", color))); + + for (size_t i = 0; i < icons_->size(); i++) + { + self_->ui->iconComboBox->setItemIcon(static_cast(i), + get_colored_icon(i, color)); + } +} + +void EditMarkerDialog::Impl::handle_accepted() +{ + markerManager_->set_marker(editId_, self_->get_marker_info()); +} + +void EditMarkerDialog::Impl::handle_rejected() +{ + if (adding_) + { + markerManager_->remove_marker(editId_); + } +} + +} // namespace ui +} // namespace qt +} // namespace scwx diff --git a/scwx-qt/source/scwx/qt/ui/edit_marker_dialog.hpp b/scwx-qt/source/scwx/qt/ui/edit_marker_dialog.hpp new file mode 100644 index 00000000..eb66e889 --- /dev/null +++ b/scwx-qt/source/scwx/qt/ui/edit_marker_dialog.hpp @@ -0,0 +1,41 @@ +#pragma once +#include + +#include + +namespace Ui +{ +class EditMarkerDialog; +} + +namespace scwx +{ +namespace qt +{ +namespace ui +{ +class EditMarkerDialog : public QDialog +{ + Q_OBJECT + Q_DISABLE_COPY_MOVE(EditMarkerDialog) + +public: + explicit EditMarkerDialog(QWidget* parent = nullptr); + ~EditMarkerDialog(); + + void setup(); + void setup(double latitude, double longitude); + void setup(types::MarkerId id); + + types::MarkerInfo get_marker_info() const; + +private: + class Impl; + std::unique_ptr p; + Ui::EditMarkerDialog* ui; +}; + + +} // namespace ui +} // namespace qt +} // namespace scwx diff --git a/scwx-qt/source/scwx/qt/ui/edit_marker_dialog.ui b/scwx-qt/source/scwx/qt/ui/edit_marker_dialog.ui new file mode 100644 index 00000000..d6b6dc87 --- /dev/null +++ b/scwx-qt/source/scwx/qt/ui/edit_marker_dialog.ui @@ -0,0 +1,188 @@ + + + EditMarkerDialog + + + + 0 + 0 + 400 + 211 + + + + Edit Location Marker + + + + + + Icon + + + + + + + Qt::Orientation::Horizontal + + + QDialogButtonBox::StandardButton::Cancel|QDialogButtonBox::StandardButton::Ok + + + + + + + true + + + + + + + Latitude + + + + + + + 4 + + + -180.000000000000000 + + + 180.000000000000000 + + + + + + + + + + Name + + + + + + + 4 + + + -90.000000000000000 + + + 90.000000000000000 + + + + + + + Longitude + + + + + + + Qt::Orientation::Vertical + + + + 20 + 40 + + + + + + + + Icon Color + + + + + + + + + + 24 + 24 + + + + QFrame::Shape::Box + + + QFrame::Shadow::Plain + + + + + + + #ffffffff + + + + + + + ... + + + + :/res/icons/font-awesome-6/palette-solid.svg:/res/icons/font-awesome-6/palette-solid.svg + + + + + + + + + + + + + buttonBox + accepted() + EditMarkerDialog + accept() + + + 248 + 254 + + + 157 + 274 + + + + + buttonBox + rejected() + EditMarkerDialog + reject() + + + 316 + 260 + + + 286 + 274 + + + + + diff --git a/scwx-qt/source/scwx/qt/ui/marker_settings_widget.cpp b/scwx-qt/source/scwx/qt/ui/marker_settings_widget.cpp index 6a1e04f3..ba6cf88b 100644 --- a/scwx-qt/source/scwx/qt/ui/marker_settings_widget.cpp +++ b/scwx-qt/source/scwx/qt/ui/marker_settings_widget.cpp @@ -4,11 +4,9 @@ #include #include #include -#include +#include #include -#include - #include namespace scwx @@ -36,6 +34,7 @@ class MarkerSettingsWidgetImpl model::MarkerModel* markerModel_; std::shared_ptr markerManager_ { manager::MarkerManager::Instance()}; + std::shared_ptr editMarkerDialog_ {nullptr}; }; @@ -47,9 +46,10 @@ MarkerSettingsWidget::MarkerSettingsWidget(QWidget* parent) : ui->setupUi(this); ui->removeButton->setEnabled(false); - ui->markerView->setModel(p->markerModel_); + p->editMarkerDialog_ = std::make_shared(this); + p->ConnectSignals(); } @@ -65,12 +65,8 @@ void MarkerSettingsWidgetImpl::ConnectSignals() self_, [this]() { - markerManager_->add_marker(types::MarkerInfo( - "", - 0, - 0, - types::getMarkerIcons()[0].name, - util::color::ToRgba8PixelT("#ffff0000"))); + editMarkerDialog_->setup(); + editMarkerDialog_->show(); }); QObject::connect( self_->ui->removeButton, @@ -109,6 +105,27 @@ void MarkerSettingsWidgetImpl::ConnectSignals() bool itemSelected = selected.size() > 0; self_->ui->removeButton->setEnabled(itemSelected); }); + QObject::connect(self_->ui->markerView, + &QAbstractItemView::doubleClicked, + self_, + [this](const QModelIndex& index) + { + int row = index.row(); + if (row < 0) + { + return; + } + + std::optional id = + markerModel_->getId(row); + if (!id) + { + return; + } + + editMarkerDialog_->setup(*id); + editMarkerDialog_->show(); + }); } } // namespace ui From cfed61c6ffa79a63e18313bd86dfb1cea2f2b6be Mon Sep 17 00:00:00 2001 From: AdenKoperczak Date: Thu, 28 Nov 2024 12:46:26 -0500 Subject: [PATCH 09/31] Added Icon column to location marker manager dialog --- scwx-qt/source/scwx/qt/model/marker_model.cpp | 22 ++++++++++++++++++- scwx-qt/source/scwx/qt/model/marker_model.hpp | 3 ++- 2 files changed, 23 insertions(+), 2 deletions(-) diff --git a/scwx-qt/source/scwx/qt/model/marker_model.cpp b/scwx-qt/source/scwx/qt/model/marker_model.cpp index c035900a..0fc22ab0 100644 --- a/scwx-qt/source/scwx/qt/model/marker_model.cpp +++ b/scwx-qt/source/scwx/qt/model/marker_model.cpp @@ -3,6 +3,7 @@ #include #include #include +#include #include #include @@ -38,7 +39,6 @@ class MarkerModel::Impl MarkerModel::MarkerModel(QObject* parent) : QAbstractTableModel(parent), p(std::make_unique()) { - connect(p->markerManager_.get(), &manager::MarkerManager::MarkersInitialized, this, @@ -127,6 +127,23 @@ QVariant MarkerModel::data(const QModelIndex& index, int role) const } break; break; + case static_cast(Column::Icon): + if (role == Qt::ItemDataRole::DecorationRole) + { + for (auto& icon : types::getMarkerIcons()) + { + if (icon.name == markerInfo->iconName) + { + return util::modulateColors(icon.qIcon, + QSize(30, 30), + QColor(markerInfo->iconColor[0], + markerInfo->iconColor[1], + markerInfo->iconColor[2], + markerInfo->iconColor[3])); + } + } + } + break; default: break; @@ -164,6 +181,9 @@ QVariant MarkerModel::headerData(int section, case static_cast(Column::Longitude): return tr("Longitude"); + case static_cast(Column::Icon): + return tr("Icon"); + default: break; } diff --git a/scwx-qt/source/scwx/qt/model/marker_model.hpp b/scwx-qt/source/scwx/qt/model/marker_model.hpp index 4fc6c95c..91c8854f 100644 --- a/scwx-qt/source/scwx/qt/model/marker_model.hpp +++ b/scwx-qt/source/scwx/qt/model/marker_model.hpp @@ -17,7 +17,8 @@ class MarkerModel : public QAbstractTableModel { Latitude = 0, Longitude = 1, - Name = 2, + Icon = 2, + Name = 3, }; explicit MarkerModel(QObject* parent = nullptr); From fc8d65d4d1e6831023669867fd63a13fc431a7c6 Mon Sep 17 00:00:00 2001 From: AdenKoperczak Date: Thu, 28 Nov 2024 13:09:34 -0500 Subject: [PATCH 10/31] Add right click to edit location marker --- scwx-qt/source/scwx/qt/gl/draw/geo_icons.cpp | 23 +++++++++--- scwx-qt/source/scwx/qt/gl/draw/geo_icons.hpp | 10 ++++++ scwx-qt/source/scwx/qt/map/marker_layer.cpp | 38 ++++++++++++++++++-- 3 files changed, 65 insertions(+), 6 deletions(-) diff --git a/scwx-qt/source/scwx/qt/gl/draw/geo_icons.cpp b/scwx-qt/source/scwx/qt/gl/draw/geo_icons.cpp index 9e2a8d17..71501930 100644 --- a/scwx-qt/source/scwx/qt/gl/draw/geo_icons.cpp +++ b/scwx-qt/source/scwx/qt/gl/draw/geo_icons.cpp @@ -38,7 +38,7 @@ static constexpr std::size_t kIntegersPerVertex_ = 4; static constexpr std::size_t kIntegerBufferLength_ = kNumTriangles * kVerticesPerTriangle * kIntegersPerVertex_; -struct GeoIconDrawItem +struct GeoIconDrawItem : types::EventHandler { units::length::nautical_miles threshold_ {}; std::chrono::sys_time startTime_ {}; @@ -691,7 +691,7 @@ void GeoIcons::Impl::UpdateSingleBuffer( hoverIcons.end(), [&di](auto& entry) { return entry.di_ == di; }); - if (di->visible_ && !di->hoverText_.empty()) + if (di->visible_ && (!di->hoverText_.empty() || di->event_ != nullptr)) { const units::angle::radians radians = angle; @@ -903,7 +903,7 @@ bool GeoIcons::RunMousePicking( const QPointF& mouseGlobalPos, const glm::vec2& mouseCoords, const common::Coordinate& /* mouseGeoCoords */, - std::shared_ptr& /* eventHandler */) + std::shared_ptr& eventHandler ) { std::unique_lock lock {p->iconMutex_}; @@ -993,12 +993,27 @@ bool GeoIcons::RunMousePicking( if (it != p->currentHoverIcons_.crend()) { itemPicked = true; - util::tooltip::Show(it->di_->hoverText_, mouseGlobalPos); + if (!it->di_->hoverText_.empty()) + { + // Show tooltip + util::tooltip::Show(it->di_->hoverText_, mouseGlobalPos); + } + if (it->di_->event_ != nullptr) + { + eventHandler = it->di_; + } } return itemPicked; } +void GeoIcons::RegisterEventHandler( + const std::shared_ptr& di, + const std::function& eventHandler) +{ + di->event_ = eventHandler; +} + } // namespace draw } // namespace gl } // namespace qt diff --git a/scwx-qt/source/scwx/qt/gl/draw/geo_icons.hpp b/scwx-qt/source/scwx/qt/gl/draw/geo_icons.hpp index 4d819681..073fc118 100644 --- a/scwx-qt/source/scwx/qt/gl/draw/geo_icons.hpp +++ b/scwx-qt/source/scwx/qt/gl/draw/geo_icons.hpp @@ -183,6 +183,16 @@ class GeoIcons : public DrawItem */ void FinishIcons(); + /** + * Registers an event handler for an icon. + * + * @param [in] di Icon draw item + * @param [in] eventHandler Event handler function + */ + static void + RegisterEventHandler(const std::shared_ptr& di, + const std::function& eventHandler); + private: class Impl; diff --git a/scwx-qt/source/scwx/qt/map/marker_layer.cpp b/scwx-qt/source/scwx/qt/map/marker_layer.cpp index 311a347b..e552c749 100644 --- a/scwx-qt/source/scwx/qt/map/marker_layer.cpp +++ b/scwx-qt/source/scwx/qt/map/marker_layer.cpp @@ -1,8 +1,14 @@ #include #include #include -#include #include +#include +#include + +#include +#include + +#include namespace scwx { @@ -18,7 +24,9 @@ class MarkerLayer::Impl { public: explicit Impl(MarkerLayer* self, std::shared_ptr context) : - self_ {self}, geoIcons_ {std::make_shared(context)} + self_ {self}, + geoIcons_ {std::make_shared(context)}, + editMarkerDialog_ {std::make_shared()} { ConnectSignals(); } @@ -30,6 +38,7 @@ class MarkerLayer::Impl MarkerLayer* self_; std::shared_ptr geoIcons_; + std::shared_ptr editMarkerDialog_; }; void MarkerLayer::Impl::ConnectSignals() @@ -55,11 +64,36 @@ void MarkerLayer::Impl::ReloadMarkers() markerManager->for_each( [this](const types::MarkerInfo& marker) { + // must use local ID, instead of reference to marker in event handler + // callback. + types::MarkerId id = marker.id; + std::shared_ptr icon = geoIcons_->AddIcon(); geoIcons_->SetIconTexture(icon, marker.iconName, 0); geoIcons_->SetIconLocation(icon, marker.latitude, marker.longitude); geoIcons_->SetIconHoverText(icon, marker.name); geoIcons_->SetIconModulate(icon, marker.iconColor); + geoIcons_->RegisterEventHandler( + icon, + [this, id](QEvent* ev) + { + switch (ev->type()) + { + case QEvent::Type::MouseButtonPress: + { + QMouseEvent* mouseEvent = reinterpret_cast(ev); + if (mouseEvent->buttons() == Qt::MouseButton::RightButton) + { + editMarkerDialog_->setup(id); + editMarkerDialog_->show(); + } + } + break; + + default: + break; + } + }); }); geoIcons_->FinishIcons(); From 05515c59b89f9b4c9218a1a87b174019922132d6 Mon Sep 17 00:00:00 2001 From: AdenKoperczak Date: Thu, 28 Nov 2024 13:27:03 -0500 Subject: [PATCH 11/31] Added hotkey for adding new location markers --- scwx-qt/source/scwx/qt/map/map_widget.cpp | 21 ++++++++++++++++--- .../scwx/qt/settings/hotkey_settings.cpp | 1 + scwx-qt/source/scwx/qt/types/hotkey_types.cpp | 2 ++ scwx-qt/source/scwx/qt/types/hotkey_types.hpp | 3 ++- 4 files changed, 23 insertions(+), 4 deletions(-) diff --git a/scwx-qt/source/scwx/qt/map/map_widget.cpp b/scwx-qt/source/scwx/qt/map/map_widget.cpp index ab7b0cf6..9c68a68a 100644 --- a/scwx-qt/source/scwx/qt/map/map_widget.cpp +++ b/scwx-qt/source/scwx/qt/map/map_widget.cpp @@ -9,10 +9,10 @@ #include #include #include +#include #include #include #include -#include #include #include #include @@ -21,6 +21,7 @@ #include #include #include +#include #include #include #include @@ -79,6 +80,7 @@ class MapWidgetImpl : public QObject map_(), layerList_ {}, imGuiRendererInitialized_ {false}, + editMarkerDialog_ {nullptr}, radarProductManager_ {nullptr}, radarProductLayer_ {nullptr}, overlayLayer_ {nullptr}, @@ -127,8 +129,6 @@ class MapWidgetImpl : public QObject ImGui_ImplQt_Init(); InitializeCustomStyles(); - - ConnectSignals(); } ~MapWidgetImpl() @@ -219,6 +219,8 @@ class MapWidgetImpl : public QObject std::shared_ptr layerModel_ { model::LayerModel::Instance()}; + std::shared_ptr editMarkerDialog_; + std::shared_ptr hotkeyManager_ { manager::HotkeyManager::Instance()}; std::shared_ptr placefileManager_ { @@ -283,6 +285,9 @@ MapWidget::MapWidget(std::size_t id, const QMapLibre::Settings& settings) : setFocusPolicy(Qt::StrongFocus); ImGui_ImplQt_RegisterWidget(this); + + p->editMarkerDialog_ = std::make_shared(this); + p->ConnectSignals(); } MapWidget::~MapWidget() @@ -429,6 +434,16 @@ void MapWidgetImpl::HandleHotkeyPressed(types::Hotkey hotkey, bool isAutoRepeat) switch (hotkey) { + case types::Hotkey::AddLocationMarker: + if (hasMouse_) + { + auto coordinate = map_->coordinateForPixel(lastPos_); + + editMarkerDialog_->setup(coordinate.first, coordinate.second); + editMarkerDialog_->show(); + } + break; + case types::Hotkey::ChangeMapStyle: if (context_->settings().isActive_) { diff --git a/scwx-qt/source/scwx/qt/settings/hotkey_settings.cpp b/scwx-qt/source/scwx/qt/settings/hotkey_settings.cpp index 0edaf840..e9c6b007 100644 --- a/scwx-qt/source/scwx/qt/settings/hotkey_settings.cpp +++ b/scwx-qt/source/scwx/qt/settings/hotkey_settings.cpp @@ -12,6 +12,7 @@ namespace settings static const std::string logPrefix_ = "scwx::qt::settings::hotkey_settings"; static const std::unordered_map kDefaultHotkeys_ { + {types::Hotkey::AddLocationMarker, QKeySequence {Qt::Key::Key_M}}, {types::Hotkey::ChangeMapStyle, QKeySequence {Qt::Key::Key_Z}}, {types::Hotkey::CopyCursorCoordinates, QKeySequence {QKeyCombination {Qt::KeyboardModifier::ControlModifier, diff --git a/scwx-qt/source/scwx/qt/types/hotkey_types.cpp b/scwx-qt/source/scwx/qt/types/hotkey_types.cpp index 8a4d0ee5..72c77f63 100644 --- a/scwx-qt/source/scwx/qt/types/hotkey_types.cpp +++ b/scwx-qt/source/scwx/qt/types/hotkey_types.cpp @@ -13,6 +13,7 @@ namespace types { static const std::unordered_map hotkeyShortName_ { + {Hotkey::AddLocationMarker, "add_location_marker"}, {Hotkey::ChangeMapStyle, "change_map_style"}, {Hotkey::CopyCursorCoordinates, "copy_cursor_coordinates"}, {Hotkey::CopyMapCoordinates, "copy_map_coordinates"}, @@ -52,6 +53,7 @@ static const std::unordered_map hotkeyShortName_ { {Hotkey::Unknown, "?"}}; static const std::unordered_map hotkeyLongName_ { + {Hotkey::AddLocationMarker, "Add Location Marker"}, {Hotkey::ChangeMapStyle, "Change Map Style"}, {Hotkey::CopyCursorCoordinates, "Copy Cursor Coordinates"}, {Hotkey::CopyMapCoordinates, "Copy Map Coordinates"}, diff --git a/scwx-qt/source/scwx/qt/types/hotkey_types.hpp b/scwx-qt/source/scwx/qt/types/hotkey_types.hpp index c2118a4f..2107a009 100644 --- a/scwx-qt/source/scwx/qt/types/hotkey_types.hpp +++ b/scwx-qt/source/scwx/qt/types/hotkey_types.hpp @@ -13,6 +13,7 @@ namespace types enum class Hotkey { + AddLocationMarker, ChangeMapStyle, CopyCursorCoordinates, CopyMapCoordinates, @@ -52,7 +53,7 @@ enum class Hotkey Unknown }; typedef scwx::util:: - Iterator + Iterator HotkeyIterator; Hotkey GetHotkeyFromShortName(const std::string& name); From 1a5503a6f659a229b97546cb6b144917dc66bfac Mon Sep 17 00:00:00 2001 From: AdenKoperczak Date: Thu, 28 Nov 2024 13:45:21 -0500 Subject: [PATCH 12/31] Fix issue where set_marker removed id from record --- scwx-qt/source/scwx/qt/manager/marker_manager.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/scwx-qt/source/scwx/qt/manager/marker_manager.cpp b/scwx-qt/source/scwx/qt/manager/marker_manager.cpp index fbfe2a2d..e4f69598 100644 --- a/scwx-qt/source/scwx/qt/manager/marker_manager.cpp +++ b/scwx-qt/source/scwx/qt/manager/marker_manager.cpp @@ -291,7 +291,8 @@ std::optional MarkerManager::get_index(types::MarkerId id) return p->idToIndex_[id]; } -void MarkerManager::set_marker(types::MarkerId id, const types::MarkerInfo& marker) +void MarkerManager::set_marker(types::MarkerId id, + const types::MarkerInfo& marker) { { std::unique_lock lock(p->markerRecordLock_); @@ -308,6 +309,7 @@ void MarkerManager::set_marker(types::MarkerId id, const types::MarkerInfo& mark std::shared_ptr& markerRecord = p->markerRecords_[index]; markerRecord->markerInfo_ = marker; + markerRecord->markerInfo_.id = id; } Q_EMIT MarkerChanged(id); Q_EMIT MarkersUpdated(); From 7b72cb4c7188aaad3449c85e771823abc6861411 Mon Sep 17 00:00:00 2001 From: AdenKoperczak Date: Thu, 28 Nov 2024 13:54:03 -0500 Subject: [PATCH 13/31] Add building-columns-solid.svg to qrc (missed in earlier commit) --- scwx-qt/scwx-qt.qrc | 1 + 1 file changed, 1 insertion(+) diff --git a/scwx-qt/scwx-qt.qrc b/scwx-qt/scwx-qt.qrc index ee3fcc8e..e7d8315a 100644 --- a/scwx-qt/scwx-qt.qrc +++ b/scwx-qt/scwx-qt.qrc @@ -33,6 +33,7 @@ res/icons/font-awesome-6/backward-step-solid.svg res/icons/font-awesome-6/book-solid.svg res/icons/font-awesome-6/briefcase-solid.svg + res/icons/font-awesome-6/building-columns-solid.svg res/icons/font-awesome-6/building-solid.svg res/icons/font-awesome-6/caravan-solid.svg res/icons/font-awesome-6/copy-regular.svg From 3685599693f3f5a1eb2ed049d776f23dbe5e67ec Mon Sep 17 00:00:00 2001 From: AdenKoperczak Date: Thu, 28 Nov 2024 21:01:08 -0500 Subject: [PATCH 14/31] Set icon color properly from dialog in editMarkerDialog --- scwx-qt/source/scwx/qt/ui/edit_marker_dialog.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/scwx-qt/source/scwx/qt/ui/edit_marker_dialog.cpp b/scwx-qt/source/scwx/qt/ui/edit_marker_dialog.cpp index d84b3c0c..93d4c1e0 100644 --- a/scwx-qt/source/scwx/qt/ui/edit_marker_dialog.cpp +++ b/scwx-qt/source/scwx/qt/ui/edit_marker_dialog.cpp @@ -182,6 +182,7 @@ void EditMarkerDialog::Impl::show_color_dialog() QString colorName = qColor.name(QColor::NameFormat::HexArgb); self_->ui->iconColorLineEdit->setText(colorName); + set_icon_color(colorName.toStdString()); }); dialog->open(); } From 5bb4a7f95a4d36e220bc90e6a475e3ac8967d2d2 Mon Sep 17 00:00:00 2001 From: AdenKoperczak Date: Mon, 9 Dec 2024 13:47:01 -0500 Subject: [PATCH 15/31] Add custom marker icons, and rework how marker icons are handled. --- scwx-qt/scwx-qt.cmake | 1 - .../source/scwx/qt/manager/marker_manager.cpp | 118 +++++++++-- .../source/scwx/qt/manager/marker_manager.hpp | 9 + scwx-qt/source/scwx/qt/map/marker_layer.cpp | 56 ++++-- scwx-qt/source/scwx/qt/model/marker_model.cpp | 23 ++- scwx-qt/source/scwx/qt/types/marker_types.cpp | 34 ---- scwx-qt/source/scwx/qt/types/marker_types.hpp | 33 +++- .../source/scwx/qt/ui/edit_marker_dialog.cpp | 110 ++++++++--- .../source/scwx/qt/ui/edit_marker_dialog.hpp | 2 +- .../source/scwx/qt/ui/edit_marker_dialog.ui | 184 ++++++++++-------- 10 files changed, 367 insertions(+), 203 deletions(-) delete mode 100644 scwx-qt/source/scwx/qt/types/marker_types.cpp diff --git a/scwx-qt/scwx-qt.cmake b/scwx-qt/scwx-qt.cmake index b8630306..706ac038 100644 --- a/scwx-qt/scwx-qt.cmake +++ b/scwx-qt/scwx-qt.cmake @@ -239,7 +239,6 @@ set(SRC_TYPES source/scwx/qt/types/alert_types.cpp source/scwx/qt/types/layer_types.cpp source/scwx/qt/types/location_types.cpp source/scwx/qt/types/map_types.cpp - source/scwx/qt/types/marker_types.cpp source/scwx/qt/types/media_types.cpp source/scwx/qt/types/qt_types.cpp source/scwx/qt/types/radar_product_record.cpp diff --git a/scwx-qt/source/scwx/qt/manager/marker_manager.cpp b/scwx-qt/source/scwx/qt/manager/marker_manager.cpp index e4f69598..75eb16fa 100644 --- a/scwx-qt/source/scwx/qt/manager/marker_manager.cpp +++ b/scwx-qt/source/scwx/qt/manager/marker_manager.cpp @@ -2,13 +2,16 @@ #include #include #include +#include #include +#include #include #include #include #include #include +#include #include #include @@ -25,12 +28,13 @@ namespace manager static const std::string logPrefix_ = "scwx::qt::manager::marker_manager"; static const auto logger_ = scwx::util::Logger::Create(logPrefix_); -static const std::string kNameName_ = "name"; -static const std::string kLatitudeName_ = "latitude"; -static const std::string kLongitudeName_ = "longitude"; -static const std::string kIconName_ = "icon"; -static const std::string kIconColorName_ = "icon-color"; +static const std::string kNameName_ = "name"; +static const std::string kLatitudeName_ = "latitude"; +static const std::string kLongitudeName_ = "longitude"; +static const std::string kIconName_ = "icon"; +static const std::string kIconColorName_ = "icon-color"; +static const std::string defaultIconName = "images/location-marker"; class MarkerManager::Impl { @@ -40,15 +44,16 @@ class MarkerManager::Impl explicit Impl(MarkerManager* self) : self_ {self} {} ~Impl() { threadPool_.join(); } - std::string markerSettingsPath_ {""}; - std::vector> markerRecords_ {}; + std::string markerSettingsPath_ {""}; + std::vector> markerRecords_ {}; std::unordered_map idToIndex_ {}; - + std::unordered_map markerIcons_ {}; MarkerManager* self_; boost::asio::thread_pool threadPool_ {1u}; std::shared_mutex markerRecordLock_ {}; + std::shared_mutex markerIconsLock_ {}; void InitializeMarkerSettings(); void ReadMarkerSettings(); @@ -57,7 +62,7 @@ class MarkerManager::Impl void InitalizeIds(); types::MarkerId NewId(); - types::MarkerId lastId_; + types::MarkerId lastId_ {0}; }; class MarkerManager::Impl::MarkerRecord @@ -84,14 +89,14 @@ class MarkerManager::Impl::MarkerRecord {kLatitudeName_, record->markerInfo_.latitude}, {kLongitudeName_, record->markerInfo_.longitude}, {kIconName_, record->markerInfo_.iconName}, - {kIconColorName_, util::color::ToArgbString(record->markerInfo_.iconColor)}}; + {kIconColorName_, + util::color::ToArgbString(record->markerInfo_.iconColor)}}; } friend MarkerRecord tag_invoke(boost::json::value_to_tag, const boost::json::value& jv) { - static const std::string defaultIconName = types::getMarkerIcons()[0].name; static const boost::gil::rgba8_pixel_t defaultIconColor = util::color::ToRgba8PixelT("#ffff0000"); @@ -120,12 +125,12 @@ class MarkerManager::Impl::MarkerRecord } } - return MarkerRecord(types::MarkerInfo( + return {types::MarkerInfo( boost::json::value_to(jv.at(kNameName_)), boost::json::value_to(jv.at(kLatitudeName_)), boost::json::value_to(jv.at(kLongitudeName_)), iconName, - iconColor)); + iconColor)}; } }; @@ -176,14 +181,14 @@ void MarkerManager::Impl::ReadMarkerSettings() { // For each marker entry auto& markerArray = markerJson.as_array(); + //std::vector fileNames {}; markerRecords_.reserve(markerArray.size()); idToIndex_.reserve(markerArray.size()); for (auto& markerEntry : markerArray) { try { - MarkerRecord record = - boost::json::value_to(markerEntry); + auto record = boost::json::value_to(markerEntry); if (!record.markerInfo_.name.empty()) { @@ -193,6 +198,8 @@ void MarkerManager::Impl::ReadMarkerSettings() markerRecords_.emplace_back( std::make_shared(record.markerInfo_)); idToIndex_.emplace(id, index); + + self_->add_icon(record.markerInfo_.iconName, true); } } catch (const std::exception& ex) @@ -201,10 +208,14 @@ void MarkerManager::Impl::ReadMarkerSettings() } } + util::TextureAtlas& textureAtlas = util::TextureAtlas::Instance(); + textureAtlas.BuildAtlas(2048, 2048); // TODO should code be moved to ResourceManager (probrably) + logger_->debug("{} location marker entries", markerRecords_.size()); } } + Q_EMIT self_->MarkersUpdated(); } @@ -233,17 +244,41 @@ MarkerManager::Impl::GetMarkerByName(const std::string& name) MarkerManager::MarkerManager() : p(std::make_unique(this)) { + const std::vector defaultMarkerIcons_ { + types::MarkerIconInfo(types::ImageTexture::LocationMarker, -1, -1), + types::MarkerIconInfo(types::ImageTexture::LocationPin, 6, 16), + types::MarkerIconInfo(types::ImageTexture::LocationCrosshair, -1, -1), + types::MarkerIconInfo(types::ImageTexture::LocationStar, -1, -1), + types::MarkerIconInfo(types::ImageTexture::LocationBriefcase, -1, -1), + types::MarkerIconInfo( + types::ImageTexture::LocationBuildingColumns, -1, -1), + types::MarkerIconInfo(types::ImageTexture::LocationBuilding, -1, -1), + types::MarkerIconInfo(types::ImageTexture::LocationCaravan, -1, -1), + types::MarkerIconInfo(types::ImageTexture::LocationHouse, -1, -1), + types::MarkerIconInfo(types::ImageTexture::LocationTent, -1, -1), + }; + p->InitializeMarkerSettings(); boost::asio::post(p->threadPool_, - [this]() + [this, defaultMarkerIcons_]() { try { // Read Marker settings on startup main::Application::WaitForInitialization(); + { + std::unique_lock lock(p->markerIconsLock_); + p->markerIcons_.reserve( + defaultMarkerIcons_.size()); + for (auto& icon : defaultMarkerIcons_) + { + p->markerIcons_.emplace(icon.name, icon); + } + } p->ReadMarkerSettings(); + Q_EMIT IconsReady(); Q_EMIT MarkersInitialized(p->markerRecords_.size()); } catch (const std::exception& ex) @@ -310,6 +345,8 @@ void MarkerManager::set_marker(types::MarkerId id, p->markerRecords_[index]; markerRecord->markerInfo_ = marker; markerRecord->markerInfo_.id = id; + + add_icon(marker.iconName); } Q_EMIT MarkerChanged(id); Q_EMIT MarkersUpdated(); @@ -325,6 +362,8 @@ types::MarkerId MarkerManager::add_marker(const types::MarkerInfo& marker) p->idToIndex_.emplace(id, index); p->markerRecords_.emplace_back(std::make_shared(marker)); p->markerRecords_[index]->markerInfo_.id = id; + + add_icon(marker.iconName); } Q_EMIT MarkerAdded(id); Q_EMIT MarkersUpdated(); @@ -403,6 +442,48 @@ void MarkerManager::for_each(std::function func) } } +void MarkerManager::add_icon(const std::string& name, bool startup) +{ + { + std::unique_lock lock(p->markerIconsLock_); + if (p->markerIcons_.contains(name)) + { + return; + } + std::shared_ptr image = + ResourceManager::LoadImageResource(name); + + auto icon = types::MarkerIconInfo(name, -1, -1, image); + p->markerIcons_.emplace(name, icon); + } + + if (!startup) + { + util::TextureAtlas& textureAtlas = util::TextureAtlas::Instance(); + textureAtlas.BuildAtlas(2048, 2048); // TODO should code be moved to ResourceManager (probrably) + Q_EMIT IconAdded(name); + } +} + +std::optional +MarkerManager::get_icon(const std::string& name) +{ + std::shared_lock lock(p->markerIconsLock_); + if (p->markerIcons_.contains(name)) + { + return p->markerIcons_.at(name); + } + + return {}; +} + +const std::unordered_map +MarkerManager::get_icons() +{ + std::shared_lock lock(p->markerIconsLock_); + return p->markerIcons_; +} + // Only use for testing void MarkerManager::set_marker_settings_path(const std::string& path) { @@ -429,6 +510,11 @@ std::shared_ptr MarkerManager::Instance() return markerManager; } +const std::string& MarkerManager::getDefaultIconName() +{ + return defaultIconName; +} + } // namespace manager } // namespace qt } // namespace scwx diff --git a/scwx-qt/source/scwx/qt/manager/marker_manager.hpp b/scwx-qt/source/scwx/qt/manager/marker_manager.hpp index 17ccb8e6..9e897660 100644 --- a/scwx-qt/source/scwx/qt/manager/marker_manager.hpp +++ b/scwx-qt/source/scwx/qt/manager/marker_manager.hpp @@ -29,12 +29,17 @@ class MarkerManager : public QObject void remove_marker(types::MarkerId id); void move_marker(size_t from, size_t to); + void add_icon(const std::string& name, bool startup = false); + std::optional get_icon(const std::string& name); + const std::unordered_map get_icons(); + void for_each(std::function func); // Only use for testing void set_marker_settings_path(const std::string& path); static std::shared_ptr Instance(); + static const std::string& getDefaultIconName(); signals: void MarkersInitialized(size_t count); @@ -43,6 +48,10 @@ class MarkerManager : public QObject void MarkerAdded(types::MarkerId id); void MarkerRemoved(types::MarkerId id); + void IconsReady(); + void IconAdded(std::string name); + + private: class Impl; std::unique_ptr p; diff --git a/scwx-qt/source/scwx/qt/map/marker_layer.cpp b/scwx-qt/source/scwx/qt/map/marker_layer.cpp index e552c749..0bad94f6 100644 --- a/scwx-qt/source/scwx/qt/map/marker_layer.cpp +++ b/scwx-qt/source/scwx/qt/map/marker_layer.cpp @@ -30,11 +30,16 @@ class MarkerLayer::Impl { ConnectSignals(); } - ~Impl() {} + ~Impl() = default; void ReloadMarkers(); void ConnectSignals(); + std::shared_ptr markerManager_ { + manager::MarkerManager::Instance()}; + + void set_icon_sheets(); + MarkerLayer* self_; std::shared_ptr geoIcons_; @@ -43,25 +48,26 @@ class MarkerLayer::Impl void MarkerLayer::Impl::ConnectSignals() { - auto markerManager = manager::MarkerManager::Instance(); - - QObject::connect(markerManager.get(), - &manager::MarkerManager::MarkersUpdated, - self_, - [this]() - { - this->ReloadMarkers(); - }); + QObject::connect(markerManager_.get(), + &manager::MarkerManager::MarkersUpdated, + self_, + [this]() { ReloadMarkers(); }); + QObject::connect(markerManager_.get(), + &manager::MarkerManager::IconsReady, + self_, + [this]() { set_icon_sheets(); }); + QObject::connect(markerManager_.get(), + &manager::MarkerManager::IconAdded, + self_, + [this]() { set_icon_sheets(); }); } void MarkerLayer::Impl::ReloadMarkers() { logger_->debug("ReloadMarkers()"); - auto markerManager = manager::MarkerManager::Instance(); geoIcons_->StartIcons(); - - markerManager->for_each( + markerManager_->for_each( [this](const types::MarkerInfo& marker) { // must use local ID, instead of reference to marker in event handler @@ -69,6 +75,7 @@ void MarkerLayer::Impl::ReloadMarkers() types::MarkerId id = marker.id; std::shared_ptr icon = geoIcons_->AddIcon(); + geoIcons_->SetIconTexture(icon, marker.iconName, 0); geoIcons_->SetIconLocation(icon, marker.latitude, marker.longitude); geoIcons_->SetIconHoverText(icon, marker.name); @@ -81,7 +88,7 @@ void MarkerLayer::Impl::ReloadMarkers() { case QEvent::Type::MouseButtonPress: { - QMouseEvent* mouseEvent = reinterpret_cast(ev); + auto* mouseEvent = reinterpret_cast(ev); if (mouseEvent->buttons() == Qt::MouseButton::RightButton) { editMarkerDialog_->setup(id); @@ -113,15 +120,22 @@ void MarkerLayer::Initialize() logger_->debug("Initialize()"); DrawLayer::Initialize(); - p->geoIcons_->StartIconSheets(); - for (auto& markerIcon : types::getMarkerIcons()) + p->set_icon_sheets(); + p->ReloadMarkers(); +} + +void MarkerLayer::Impl::set_icon_sheets() +{ + geoIcons_->StartIconSheets(); + for (auto& markerIcon : markerManager_->get_icons()) { - p->geoIcons_->AddIconSheet( - markerIcon.name, 0, 0, markerIcon.hotX, markerIcon.hotY); + geoIcons_->AddIconSheet(markerIcon.second.name, + 0, + 0, + markerIcon.second.hotX, + markerIcon.second.hotY); } - p->geoIcons_->FinishIconSheets(); - - p->ReloadMarkers(); + geoIcons_->FinishIconSheets(); } void MarkerLayer::Render(const QMapLibre::CustomLayerRenderParameters& params) diff --git a/scwx-qt/source/scwx/qt/model/marker_model.cpp b/scwx-qt/source/scwx/qt/model/marker_model.cpp index 0fc22ab0..7c012921 100644 --- a/scwx-qt/source/scwx/qt/model/marker_model.cpp +++ b/scwx-qt/source/scwx/qt/model/marker_model.cpp @@ -19,6 +19,7 @@ namespace model static const std::string logPrefix_ = "scwx::qt::model::marker_model"; static const auto logger_ = scwx::util::Logger::Create(logPrefix_); +static const int iconSize_ = 30; static constexpr int kFirstColumn = static_cast(MarkerModel::Column::Latitude); @@ -130,17 +131,19 @@ QVariant MarkerModel::data(const QModelIndex& index, int role) const case static_cast(Column::Icon): if (role == Qt::ItemDataRole::DecorationRole) { - for (auto& icon : types::getMarkerIcons()) + std::optional icon = + p->markerManager_->get_icon(markerInfo->iconName); + if (icon) { + return util::modulateColors(icon->qIcon, + QSize(iconSize_, iconSize_), + QColor(markerInfo->iconColor[0], + markerInfo->iconColor[1], + markerInfo->iconColor[2], + markerInfo->iconColor[3])); + } + else { - if (icon.name == markerInfo->iconName) - { - return util::modulateColors(icon.qIcon, - QSize(30, 30), - QColor(markerInfo->iconColor[0], - markerInfo->iconColor[1], - markerInfo->iconColor[2], - markerInfo->iconColor[3])); - } + return {}; } } break; diff --git a/scwx-qt/source/scwx/qt/types/marker_types.cpp b/scwx-qt/source/scwx/qt/types/marker_types.cpp deleted file mode 100644 index ce63490a..00000000 --- a/scwx-qt/source/scwx/qt/types/marker_types.cpp +++ /dev/null @@ -1,34 +0,0 @@ -#include - -namespace scwx -{ -namespace qt -{ -namespace types -{ - -const std::vector& getMarkerIcons() -{ - static std::vector markerIcons = {}; - if (markerIcons.size() == 0) - { - markerIcons = { - MarkerIconInfo(types::ImageTexture::LocationMarker, -1, -1), - MarkerIconInfo(types::ImageTexture::LocationPin, 6, 16), - MarkerIconInfo(types::ImageTexture::LocationCrosshair, -1, -1), - MarkerIconInfo(types::ImageTexture::LocationStar, -1, -1), - MarkerIconInfo(types::ImageTexture::LocationBriefcase, -1, -1), - MarkerIconInfo(types::ImageTexture::LocationBuildingColumns, -1, -1), - MarkerIconInfo(types::ImageTexture::LocationBuilding, -1, -1), - MarkerIconInfo(types::ImageTexture::LocationCaravan, -1, -1), - MarkerIconInfo(types::ImageTexture::LocationHouse, -1, -1), - MarkerIconInfo(types::ImageTexture::LocationTent, -1, -1), - }; - } - - return markerIcons; -} - -} // namespace types -} // namespace qt -} // namespace scwx diff --git a/scwx-qt/source/scwx/qt/types/marker_types.hpp b/scwx-qt/source/scwx/qt/types/marker_types.hpp index 2d1aa987..1848adfa 100644 --- a/scwx-qt/source/scwx/qt/types/marker_types.hpp +++ b/scwx-qt/source/scwx/qt/types/marker_types.hpp @@ -14,15 +14,15 @@ namespace qt { namespace types { -typedef std::uint64_t MarkerId; +using MarkerId = std::uint64_t; struct MarkerInfo { - MarkerInfo(const std::string& name, - double latitude, - double longitude, - const std::string iconName, - boost::gil::rgba8_pixel_t iconColor) : + MarkerInfo(const std::string& name, + double latitude, + double longitude, + const std::string& iconName, + const boost::gil::rgba8_pixel_t& iconColor) : name {name}, latitude {latitude}, longitude {longitude}, @@ -31,7 +31,7 @@ struct MarkerInfo { } - MarkerId id; + MarkerId id{0}; std::string name; double latitude; double longitude; @@ -47,7 +47,21 @@ struct MarkerIconInfo { path{types::GetTexturePath(texture)}, hotX{hotX}, hotY{hotY}, - qIcon{QIcon(QString::fromStdString(path))} + qIcon{QIcon(QString::fromStdString(path))}, + image{} + { + } + + explicit MarkerIconInfo(const std::string& path, + std::int32_t hotX, + std::int32_t hotY, + std::shared_ptr image) : + name{path}, + path{path}, + hotX{hotX}, + hotY{hotY}, + qIcon{QIcon(QString::fromStdString(path))}, + image{image} { } @@ -56,10 +70,9 @@ struct MarkerIconInfo { std::int32_t hotX; std::int32_t hotY; QIcon qIcon; + std::optional> image; }; -const std::vector& getMarkerIcons(); - } // namespace types } // namespace qt } // namespace scwx diff --git a/scwx-qt/source/scwx/qt/ui/edit_marker_dialog.cpp b/scwx-qt/source/scwx/qt/ui/edit_marker_dialog.cpp index 93d4c1e0..f182735c 100644 --- a/scwx-qt/source/scwx/qt/ui/edit_marker_dialog.cpp +++ b/scwx-qt/source/scwx/qt/ui/edit_marker_dialog.cpp @@ -8,7 +8,6 @@ #include #include -#include #include #include @@ -16,6 +15,7 @@ #include #include #include +#include namespace scwx { @@ -36,6 +36,8 @@ class EditMarkerDialog::Impl } void show_color_dialog(); + void show_icon_file_dialog(); + void set_icon_color(const std::string& color); void connect_signals(); @@ -45,24 +47,20 @@ class EditMarkerDialog::Impl EditMarkerDialog* self_; QPushButton* deleteButton_; - QIcon get_colored_icon(size_t index, const std::string& color); + QIcon get_colored_icon(const types::MarkerIconInfo& marker, + const std::string& color); std::shared_ptr markerManager_ = manager::MarkerManager::Instance(); - const std::vector* icons_; types::MarkerId editId_; bool adding_; + std::string setIconOnAdded_{""}; }; -QIcon EditMarkerDialog::Impl::get_colored_icon(size_t index, - const std::string& color) +QIcon EditMarkerDialog::Impl::get_colored_icon( + const types::MarkerIconInfo& marker, const std::string& color) { - if (index >= icons_->size()) - { - return QIcon(); - } - - return util::modulateColors((*icons_)[index].qIcon, + return util::modulateColors(marker.qIcon, self_->ui->iconComboBox->iconSize(), QColor(QString::fromStdString(color))); } @@ -74,12 +72,11 @@ EditMarkerDialog::EditMarkerDialog(QWidget* parent) : { ui->setupUi(this); - p->icons_ = &types::getMarkerIcons(); - for (auto& markerIcon : (*p->icons_)) + for (auto& markerIcon : p->markerManager_->get_icons()) { - ui->iconComboBox->addItem(markerIcon.qIcon, + ui->iconComboBox->addItem(markerIcon.second.qIcon, QString(""), - QString::fromStdString(markerIcon.name)); + QString::fromStdString(markerIcon.second.name)); } p->deleteButton_ = ui->buttonBox->addButton("Delete", QDialogButtonBox::DestructiveRole); @@ -98,7 +95,6 @@ void EditMarkerDialog::setup() void EditMarkerDialog::setup(double latitude, double longitude) { - ui->iconComboBox->setCurrentIndex(0); // By default use foreground color as marker color, mainly so the icons // are vissable in the dropdown menu. QColor color = QWidget::palette().color(QWidget::foregroundRole()); @@ -106,7 +102,7 @@ void EditMarkerDialog::setup(double latitude, double longitude) "", latitude, longitude, - ui->iconComboBox->currentData().toString().toStdString(), + manager::MarkerManager::getDefaultIconName(), boost::gil::rgba8_pixel_t {static_cast(color.red()), static_cast(color.green()), static_cast(color.blue()), @@ -128,6 +124,9 @@ void EditMarkerDialog::setup(types::MarkerId id) p->editId_ = id; p->adding_ = false; + std::string iconColorStr = util::color::ToArgbString(marker->iconColor); + p->set_icon_color(iconColorStr); + int iconIndex = ui->iconComboBox->findData(QString::fromStdString(marker->iconName)); if (iconIndex < 0 || marker->iconName == "") @@ -135,15 +134,11 @@ void EditMarkerDialog::setup(types::MarkerId id) iconIndex = 0; } - std::string iconColorStr = util::color::ToArgbString(marker->iconColor); - ui->nameLineEdit->setText(QString::fromStdString(marker->name)); ui->iconComboBox->setCurrentIndex(iconIndex); ui->latitudeDoubleSpinBox->setValue(marker->latitude); ui->longitudeDoubleSpinBox->setValue(marker->longitude); ui->iconColorLineEdit->setText(QString::fromStdString(iconColorStr)); - - p->set_icon_color(iconColorStr); } types::MarkerInfo EditMarkerDialog::get_marker_info() const @@ -163,7 +158,7 @@ types::MarkerInfo EditMarkerDialog::get_marker_info() const void EditMarkerDialog::Impl::show_color_dialog() { - QColorDialog* dialog = new QColorDialog(self_); + auto* dialog = new QColorDialog(self_); dialog->setAttribute(Qt::WA_DeleteOnClose); dialog->setOption(QColorDialog::ColorDialogOption::ShowAlphaChannel); @@ -187,6 +182,28 @@ void EditMarkerDialog::Impl::show_color_dialog() dialog->open(); } +void EditMarkerDialog::Impl::show_icon_file_dialog() +{ + + auto* dialog = new QFileDialog(self_); + + dialog->setFileMode(QFileDialog::ExistingFile); + dialog->setNameFilters({"Icon (*.png *.svg)", "All (*)"}); + dialog->setAttribute(Qt::WA_DeleteOnClose); + + QObject::connect(dialog, + &QFileDialog::fileSelected, + self_, + [this](const QString& file) + { + std::string path = + QDir::toNativeSeparators(file).toStdString(); + setIconOnAdded_ = path; + markerManager_->add_icon(path); + }); + dialog->open(); +} + void EditMarkerDialog::Impl::connect_signals() { connect(self_, @@ -217,7 +234,33 @@ void EditMarkerDialog::Impl::connect_signals() connect(self_->ui->iconColorButton, &QAbstractButton::clicked, self_, - [=, this]() { self_->p->show_color_dialog(); }); + [=, this]() { show_color_dialog(); }); + + connect(self_->ui->iconFileOpenButton, + &QPushButton::clicked, + self_, + [this]() { show_icon_file_dialog(); }); + + connect(markerManager_.get(), + &manager::MarkerManager::IconAdded, + self_, + [this]() + { + std::string color = + self_->ui->iconColorLineEdit->text().toStdString(); + set_icon_color(color); + + if (setIconOnAdded_ != "") + { + int i = self_->ui->iconComboBox->findData( + QString::fromStdString(setIconOnAdded_)); + if (i >= 0) + { + self_->ui->iconComboBox->setCurrentIndex(i); + setIconOnAdded_ = ""; + } + } + }); } void EditMarkerDialog::Impl::set_icon_color(const std::string& color) @@ -225,10 +268,25 @@ void EditMarkerDialog::Impl::set_icon_color(const std::string& color) self_->ui->iconColorFrame->setStyleSheet( QString::fromStdString(fmt::format("background-color: {}", color))); - for (size_t i = 0; i < icons_->size(); i++) + auto* iconComboBox = self_->ui->iconComboBox; + + + QVariant data = self_->ui->iconComboBox->currentData(); + self_->ui->iconComboBox->clear(); + for (auto& markerIcon : markerManager_->get_icons()) { - self_->ui->iconComboBox->setItemIcon(static_cast(i), - get_colored_icon(i, color)); + int i = + iconComboBox->findData(QString::fromStdString(markerIcon.second.name)); + QIcon icon = get_colored_icon(markerIcon.second, color); + if (i < 0) + { + iconComboBox->addItem( + icon, QString(""), QString::fromStdString(markerIcon.second.name)); + } + else + { + self_->ui->iconComboBox->setItemIcon(i, icon); + } } } diff --git a/scwx-qt/source/scwx/qt/ui/edit_marker_dialog.hpp b/scwx-qt/source/scwx/qt/ui/edit_marker_dialog.hpp index eb66e889..5dac04ea 100644 --- a/scwx-qt/source/scwx/qt/ui/edit_marker_dialog.hpp +++ b/scwx-qt/source/scwx/qt/ui/edit_marker_dialog.hpp @@ -21,7 +21,7 @@ class EditMarkerDialog : public QDialog public: explicit EditMarkerDialog(QWidget* parent = nullptr); - ~EditMarkerDialog(); + ~EditMarkerDialog() override; void setup(); void setup(double latitude, double longitude); diff --git a/scwx-qt/source/scwx/qt/ui/edit_marker_dialog.ui b/scwx-qt/source/scwx/qt/ui/edit_marker_dialog.ui index d6b6dc87..f6d9c28d 100644 --- a/scwx-qt/source/scwx/qt/ui/edit_marker_dialog.ui +++ b/scwx-qt/source/scwx/qt/ui/edit_marker_dialog.ui @@ -7,88 +7,14 @@ 0 0 400 - 211 + 249 Edit Location Marker - - - - Icon - - - - - - - Qt::Orientation::Horizontal - - - QDialogButtonBox::StandardButton::Cancel|QDialogButtonBox::StandardButton::Ok - - - - - - - true - - - - - - - Latitude - - - - - - - 4 - - - -180.000000000000000 - - - 180.000000000000000 - - - - - - - - - - Name - - - - - - - 4 - - - -90.000000000000000 - - - 90.000000000000000 - - - - - - - Longitude - - - - + Qt::Orientation::Vertical @@ -101,14 +27,7 @@ - - - - Icon Color - - - - + @@ -146,6 +65,103 @@ + + + + 4 + + + -90.000000000000000 + + + 90.000000000000000 + + + + + + + Name + + + + + + + Icon + + + + + + + Qt::Orientation::Horizontal + + + QDialogButtonBox::StandardButton::Cancel|QDialogButtonBox::StandardButton::Ok + + + + + + + Longitude + + + + + + + Icon Color + + + + + + + Latitude + + + + + + + Add Custom Icon + + + ... + + + + + + + 4 + + + -180.000000000000000 + + + 180.000000000000000 + + + + + + + + + + + 0 + 0 + + + + true + + + From 4432bcb93c4f72d8a47731f197249dc98576886a Mon Sep 17 00:00:00 2001 From: AdenKoperczak Date: Mon, 9 Dec 2024 14:12:18 -0500 Subject: [PATCH 16/31] Fixed existing tests in location_marker_part2 --- test/data | 2 +- .../scwx/qt/model/marker_model.test.cpp | 29 ++++++++++--------- 2 files changed, 17 insertions(+), 14 deletions(-) diff --git a/test/data b/test/data index 4b4d9c54..42783ea4 160000 --- a/test/data +++ b/test/data @@ -1 +1 @@ -Subproject commit 4b4d9c54b8218aa2297dbd457e3747091570f0d2 +Subproject commit 42783ea4f3b118b2b0f3266efb53f9b4384f069b diff --git a/test/source/scwx/qt/model/marker_model.test.cpp b/test/source/scwx/qt/model/marker_model.test.cpp index 700ffc6e..8846c9cd 100644 --- a/test/source/scwx/qt/model/marker_model.test.cpp +++ b/test/source/scwx/qt/model/marker_model.test.cpp @@ -1,6 +1,7 @@ #include #include #include +#include #include #include @@ -30,6 +31,9 @@ static std::mutex initializedMutex {}; static std::condition_variable initializedCond {}; static bool initialized; +static const boost::gil::rgba8_pixel_t defaultIconColor = + util::color::ToRgba8PixelT("#ffff0000"); + void CompareFiles(const std::string& file1, const std::string& file2) { std::ifstream ifs1 {file1}; @@ -49,8 +53,7 @@ void CopyFile(const std::string& from, const std::string& to) CompareFiles(from, to); } -typedef void TestFunction(std::shared_ptr manager, - MarkerModel& model); +using TestFunction = void (std::shared_ptr, MarkerModel &); void RunTest(const std::string& filename, TestFunction testFunction) { @@ -65,7 +68,7 @@ void RunTest(const std::string& filename, TestFunction testFunction) initialized = false; QObject::connect(manager.get(), &manager::MarkerManager::MarkersInitialized, - [](size_t count) + []() { std::unique_lock lock(initializedMutex); initialized = true; @@ -119,7 +122,7 @@ TEST(MarkerModelTest, AddRemove) RunTest(ONE_MARKERS_FILE, [](std::shared_ptr manager, MarkerModel&) - { manager->add_marker(types::MarkerInfo("Null", 0, 0)); }); + { manager->add_marker(types::MarkerInfo("Null", 0, 0, "images/location-marker", defaultIconColor)); }); RunTest( EMPTY_MARKERS_FILE, [](std::shared_ptr manager, MarkerModel& model) @@ -143,11 +146,11 @@ TEST(MarkerModelTest, AddFive) RunTest(FIVE_MARKERS_FILE, [](std::shared_ptr manager, MarkerModel&) { - manager->add_marker(types::MarkerInfo("Null", 0, 0)); - manager->add_marker(types::MarkerInfo("North", 90, 0)); - manager->add_marker(types::MarkerInfo("South", -90, 0)); - manager->add_marker(types::MarkerInfo("East", 0, 90)); - manager->add_marker(types::MarkerInfo("West", 0, -90)); + manager->add_marker(types::MarkerInfo("Null", 0, 0, "images/location-marker", defaultIconColor)); + manager->add_marker(types::MarkerInfo("North", 90, 0, "images/location-marker", defaultIconColor)); + manager->add_marker(types::MarkerInfo("South", -90, 0, "images/location-marker", defaultIconColor)); + manager->add_marker(types::MarkerInfo("East", 0, 90, "images/location-marker", defaultIconColor)); + manager->add_marker(types::MarkerInfo("West", 0, -90, "images/location-marker", defaultIconColor)); }); std::filesystem::remove(TEMP_MARKERS_FILE); @@ -161,10 +164,10 @@ TEST(MarkerModelTest, AddFour) RunTest(FIVE_MARKERS_FILE, [](std::shared_ptr manager, MarkerModel&) { - manager->add_marker(types::MarkerInfo("North", 90, 0)); - manager->add_marker(types::MarkerInfo("South", -90, 0)); - manager->add_marker(types::MarkerInfo("East", 0, 90)); - manager->add_marker(types::MarkerInfo("West", 0, -90)); + manager->add_marker(types::MarkerInfo("North", 90, 0, "images/location-marker", defaultIconColor)); + manager->add_marker(types::MarkerInfo("South", -90, 0, "images/location-marker", defaultIconColor)); + manager->add_marker(types::MarkerInfo("East", 0, 90, "images/location-marker", defaultIconColor)); + manager->add_marker(types::MarkerInfo("West", 0, -90, "images/location-marker", defaultIconColor)); }); std::filesystem::remove(TEMP_MARKERS_FILE); From 5d8f3786de20c8344f3c498b071cdd146ac501a7 Mon Sep 17 00:00:00 2001 From: AdenKoperczak Date: Mon, 9 Dec 2024 15:12:53 -0500 Subject: [PATCH 17/31] Remove unneeded data variable --- scwx-qt/source/scwx/qt/ui/edit_marker_dialog.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/scwx-qt/source/scwx/qt/ui/edit_marker_dialog.cpp b/scwx-qt/source/scwx/qt/ui/edit_marker_dialog.cpp index f182735c..70625be4 100644 --- a/scwx-qt/source/scwx/qt/ui/edit_marker_dialog.cpp +++ b/scwx-qt/source/scwx/qt/ui/edit_marker_dialog.cpp @@ -271,7 +271,6 @@ void EditMarkerDialog::Impl::set_icon_color(const std::string& color) auto* iconComboBox = self_->ui->iconComboBox; - QVariant data = self_->ui->iconComboBox->currentData(); self_->ui->iconComboBox->clear(); for (auto& markerIcon : markerManager_->get_icons()) { From d8233a2c4107fb35e654b3aa019970f5d709c545 Mon Sep 17 00:00:00 2001 From: AdenKoperczak Date: Mon, 9 Dec 2024 16:24:52 -0500 Subject: [PATCH 18/31] enable having markers without names --- .../source/scwx/qt/manager/marker_manager.cpp | 19 ++++++++----------- 1 file changed, 8 insertions(+), 11 deletions(-) diff --git a/scwx-qt/source/scwx/qt/manager/marker_manager.cpp b/scwx-qt/source/scwx/qt/manager/marker_manager.cpp index 75eb16fa..b4396b2f 100644 --- a/scwx-qt/source/scwx/qt/manager/marker_manager.cpp +++ b/scwx-qt/source/scwx/qt/manager/marker_manager.cpp @@ -190,17 +190,14 @@ void MarkerManager::Impl::ReadMarkerSettings() { auto record = boost::json::value_to(markerEntry); - if (!record.markerInfo_.name.empty()) - { - types::MarkerId id = NewId(); - size_t index = markerRecords_.size(); - record.markerInfo_.id = id; - markerRecords_.emplace_back( - std::make_shared(record.markerInfo_)); - idToIndex_.emplace(id, index); - - self_->add_icon(record.markerInfo_.iconName, true); - } + types::MarkerId id = NewId(); + size_t index = markerRecords_.size(); + record.markerInfo_.id = id; + markerRecords_.emplace_back( + std::make_shared(record.markerInfo_)); + idToIndex_.emplace(id, index); + + self_->add_icon(record.markerInfo_.iconName, true); } catch (const std::exception& ex) { From 89ef2566478584e3d13753a58f0f7e7985f43d01 Mon Sep 17 00:00:00 2001 From: AdenKoperczak Date: Mon, 9 Dec 2024 17:44:46 -0500 Subject: [PATCH 19/31] Modify lat/lon dialog to make them somewhat nicer to work with --- scwx-qt/source/scwx/qt/ui/edit_marker_dialog.ui | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/scwx-qt/source/scwx/qt/ui/edit_marker_dialog.ui b/scwx-qt/source/scwx/qt/ui/edit_marker_dialog.ui index f6d9c28d..3bfad9a6 100644 --- a/scwx-qt/source/scwx/qt/ui/edit_marker_dialog.ui +++ b/scwx-qt/source/scwx/qt/ui/edit_marker_dialog.ui @@ -67,8 +67,11 @@ + + QAbstractSpinBox::CorrectionMode::CorrectToNearestValue + - 4 + 5 -90.000000000000000 @@ -135,8 +138,11 @@ + + QAbstractSpinBox::CorrectionMode::CorrectToNearestValue + - 4 + 5 -180.000000000000000 From 3629dd36f2f01cbc88d9e13fcd97353cdc6dc76e Mon Sep 17 00:00:00 2001 From: AdenKoperczak Date: Mon, 9 Dec 2024 17:46:09 -0500 Subject: [PATCH 20/31] Add part1 to part2 location marker conversion test --- .../scwx/qt/model/marker_model.test.cpp | 35 +++++++++++++------ 1 file changed, 25 insertions(+), 10 deletions(-) diff --git a/test/source/scwx/qt/model/marker_model.test.cpp b/test/source/scwx/qt/model/marker_model.test.cpp index 8846c9cd..f152ddec 100644 --- a/test/source/scwx/qt/model/marker_model.test.cpp +++ b/test/source/scwx/qt/model/marker_model.test.cpp @@ -26,6 +26,8 @@ static const std::string ONE_MARKERS_FILE = std::string(SCWX_TEST_DATA_DIR) + "/json/markers/markers-one.json"; static const std::string FIVE_MARKERS_FILE = std::string(SCWX_TEST_DATA_DIR) + "/json/markers/markers-five.json"; +static const std::string PART1_MARKER_FILE = + std::string(SCWX_TEST_DATA_DIR) + "/json/markers/markers-part1.json"; static std::mutex initializedMutex {}; static std::condition_variable initializedCond {}; @@ -33,6 +35,8 @@ static bool initialized; static const boost::gil::rgba8_pixel_t defaultIconColor = util::color::ToRgba8PixelT("#ffff0000"); +static const std::string defaultIconName = "images/location-marker"; + void CompareFiles(const std::string& file1, const std::string& file2) { @@ -122,7 +126,7 @@ TEST(MarkerModelTest, AddRemove) RunTest(ONE_MARKERS_FILE, [](std::shared_ptr manager, MarkerModel&) - { manager->add_marker(types::MarkerInfo("Null", 0, 0, "images/location-marker", defaultIconColor)); }); + { manager->add_marker(types::MarkerInfo("Null", 0, 0, defaultIconName, defaultIconColor)); }); RunTest( EMPTY_MARKERS_FILE, [](std::shared_ptr manager, MarkerModel& model) @@ -146,11 +150,11 @@ TEST(MarkerModelTest, AddFive) RunTest(FIVE_MARKERS_FILE, [](std::shared_ptr manager, MarkerModel&) { - manager->add_marker(types::MarkerInfo("Null", 0, 0, "images/location-marker", defaultIconColor)); - manager->add_marker(types::MarkerInfo("North", 90, 0, "images/location-marker", defaultIconColor)); - manager->add_marker(types::MarkerInfo("South", -90, 0, "images/location-marker", defaultIconColor)); - manager->add_marker(types::MarkerInfo("East", 0, 90, "images/location-marker", defaultIconColor)); - manager->add_marker(types::MarkerInfo("West", 0, -90, "images/location-marker", defaultIconColor)); + manager->add_marker(types::MarkerInfo("Null", 0, 0, defaultIconName, defaultIconColor)); + manager->add_marker(types::MarkerInfo("North", 90, 0, defaultIconName, defaultIconColor)); + manager->add_marker(types::MarkerInfo("South", -90, 0, defaultIconName, defaultIconColor)); + manager->add_marker(types::MarkerInfo("East", 0, 90, defaultIconName, defaultIconColor)); + manager->add_marker(types::MarkerInfo("West", 0, -90, defaultIconName, defaultIconColor)); }); std::filesystem::remove(TEMP_MARKERS_FILE); @@ -164,10 +168,10 @@ TEST(MarkerModelTest, AddFour) RunTest(FIVE_MARKERS_FILE, [](std::shared_ptr manager, MarkerModel&) { - manager->add_marker(types::MarkerInfo("North", 90, 0, "images/location-marker", defaultIconColor)); - manager->add_marker(types::MarkerInfo("South", -90, 0, "images/location-marker", defaultIconColor)); - manager->add_marker(types::MarkerInfo("East", 0, 90, "images/location-marker", defaultIconColor)); - manager->add_marker(types::MarkerInfo("West", 0, -90, "images/location-marker", defaultIconColor)); + manager->add_marker(types::MarkerInfo("North", 90, 0, defaultIconName, defaultIconColor)); + manager->add_marker(types::MarkerInfo("South", -90, 0, defaultIconName, defaultIconColor)); + manager->add_marker(types::MarkerInfo("East", 0, 90, defaultIconName, defaultIconColor)); + manager->add_marker(types::MarkerInfo("West", 0, -90, defaultIconName, defaultIconColor)); }); std::filesystem::remove(TEMP_MARKERS_FILE); @@ -238,6 +242,17 @@ TEST(MarkerModelTest, RemoveFour) EXPECT_EQ(std::filesystem::exists(TEMP_MARKERS_FILE), false); } +TEST(MarkerModelTest, UpdateFromPart1) +{ + CopyFile(PART1_MARKER_FILE, TEMP_MARKERS_FILE); + + RunTest(ONE_MARKERS_FILE, + [](std::shared_ptr, MarkerModel&) {}); + + std::filesystem::remove(TEMP_MARKERS_FILE); + EXPECT_EQ(std::filesystem::exists(TEMP_MARKERS_FILE), false); +} + } // namespace model } // namespace qt } // namespace scwx From e62ef3a7f3b676ca001e4d37e9e595ab658775d2 Mon Sep 17 00:00:00 2001 From: AdenKoperczak Date: Tue, 10 Dec 2024 10:14:42 -0500 Subject: [PATCH 21/31] modified comments from TODO to question. Still needs checking --- scwx-qt/source/scwx/qt/manager/marker_manager.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/scwx-qt/source/scwx/qt/manager/marker_manager.cpp b/scwx-qt/source/scwx/qt/manager/marker_manager.cpp index b4396b2f..5678106f 100644 --- a/scwx-qt/source/scwx/qt/manager/marker_manager.cpp +++ b/scwx-qt/source/scwx/qt/manager/marker_manager.cpp @@ -206,7 +206,7 @@ void MarkerManager::Impl::ReadMarkerSettings() } util::TextureAtlas& textureAtlas = util::TextureAtlas::Instance(); - textureAtlas.BuildAtlas(2048, 2048); // TODO should code be moved to ResourceManager (probrably) + textureAtlas.BuildAtlas(2048, 2048); // Should this code be moved to ResourceManager? logger_->debug("{} location marker entries", markerRecords_.size()); } @@ -457,7 +457,7 @@ void MarkerManager::add_icon(const std::string& name, bool startup) if (!startup) { util::TextureAtlas& textureAtlas = util::TextureAtlas::Instance(); - textureAtlas.BuildAtlas(2048, 2048); // TODO should code be moved to ResourceManager (probrably) + textureAtlas.BuildAtlas(2048, 2048); // Should this code be moved to ResourceManager? Q_EMIT IconAdded(name); } } From cac89129af36676159ebc4c1888a732472b18147 Mon Sep 17 00:00:00 2001 From: AdenKoperczak Date: Sat, 14 Dec 2024 10:16:18 -0500 Subject: [PATCH 22/31] Location markers part2 clang-format fixes --- scwx-qt/source/scwx/qt/gl/draw/geo_icons.cpp | 2 +- .../source/scwx/qt/manager/marker_manager.cpp | 25 +++++------ .../source/scwx/qt/manager/marker_manager.hpp | 9 ++-- scwx-qt/source/scwx/qt/model/marker_model.cpp | 3 +- scwx-qt/source/scwx/qt/types/marker_types.hpp | 45 ++++++++++--------- .../source/scwx/qt/types/texture_types.cpp | 6 +-- .../source/scwx/qt/ui/edit_marker_dialog.cpp | 25 +++++------ .../source/scwx/qt/ui/edit_marker_dialog.hpp | 3 +- .../scwx/qt/model/marker_model.test.cpp | 37 +++++++++------ 9 files changed, 79 insertions(+), 76 deletions(-) diff --git a/scwx-qt/source/scwx/qt/gl/draw/geo_icons.cpp b/scwx-qt/source/scwx/qt/gl/draw/geo_icons.cpp index 71501930..743b0df9 100644 --- a/scwx-qt/source/scwx/qt/gl/draw/geo_icons.cpp +++ b/scwx-qt/source/scwx/qt/gl/draw/geo_icons.cpp @@ -903,7 +903,7 @@ bool GeoIcons::RunMousePicking( const QPointF& mouseGlobalPos, const glm::vec2& mouseCoords, const common::Coordinate& /* mouseGeoCoords */, - std::shared_ptr& eventHandler ) + std::shared_ptr& eventHandler) { std::unique_lock lock {p->iconMutex_}; diff --git a/scwx-qt/source/scwx/qt/manager/marker_manager.cpp b/scwx-qt/source/scwx/qt/manager/marker_manager.cpp index 5678106f..21cb90cd 100644 --- a/scwx-qt/source/scwx/qt/manager/marker_manager.cpp +++ b/scwx-qt/source/scwx/qt/manager/marker_manager.cpp @@ -28,11 +28,11 @@ namespace manager static const std::string logPrefix_ = "scwx::qt::manager::marker_manager"; static const auto logger_ = scwx::util::Logger::Create(logPrefix_); -static const std::string kNameName_ = "name"; -static const std::string kLatitudeName_ = "latitude"; -static const std::string kLongitudeName_ = "longitude"; -static const std::string kIconName_ = "icon"; -static const std::string kIconColorName_ = "icon-color"; +static const std::string kNameName_ = "name"; +static const std::string kLatitudeName_ = "latitude"; +static const std::string kLongitudeName_ = "longitude"; +static const std::string kIconName_ = "icon"; +static const std::string kIconColorName_ = "icon-color"; static const std::string defaultIconName = "images/location-marker"; @@ -68,7 +68,6 @@ class MarkerManager::Impl class MarkerManager::Impl::MarkerRecord { public: - MarkerRecord(const types::MarkerInfo& info) : markerInfo_ {info} { @@ -93,7 +92,6 @@ class MarkerManager::Impl::MarkerRecord util::color::ToArgbString(record->markerInfo_.iconColor)}}; } - friend MarkerRecord tag_invoke(boost::json::value_to_tag, const boost::json::value& jv) { @@ -102,7 +100,7 @@ class MarkerManager::Impl::MarkerRecord const boost::json::object& jo = jv.as_object(); - std::string iconName = defaultIconName; + std::string iconName = defaultIconName; boost::gil::rgba8_pixel_t iconColor = defaultIconColor; if (jo.contains(kIconName_) && jo.at(kIconName_).is_string()) @@ -112,7 +110,8 @@ class MarkerManager::Impl::MarkerRecord if (jo.contains(kIconColorName_) && jo.at(kIconName_).is_string()) { - try { + try + { iconColor = util::color::ToRgba8PixelT( boost::json::value_to(jv.at(kIconColorName_))); } @@ -181,7 +180,6 @@ void MarkerManager::Impl::ReadMarkerSettings() { // For each marker entry auto& markerArray = markerJson.as_array(); - //std::vector fileNames {}; markerRecords_.reserve(markerArray.size()); idToIndex_.reserve(markerArray.size()); for (auto& markerEntry : markerArray) @@ -206,13 +204,13 @@ void MarkerManager::Impl::ReadMarkerSettings() } util::TextureAtlas& textureAtlas = util::TextureAtlas::Instance(); - textureAtlas.BuildAtlas(2048, 2048); // Should this code be moved to ResourceManager? + textureAtlas.BuildAtlas( + 2048, 2048); // Should this code be moved to ResourceManager? logger_->debug("{} location marker entries", markerRecords_.size()); } } - Q_EMIT self_->MarkersUpdated(); } @@ -457,7 +455,8 @@ void MarkerManager::add_icon(const std::string& name, bool startup) if (!startup) { util::TextureAtlas& textureAtlas = util::TextureAtlas::Instance(); - textureAtlas.BuildAtlas(2048, 2048); // Should this code be moved to ResourceManager? + textureAtlas.BuildAtlas( + 2048, 2048); // Should this code be moved to ResourceManager? Q_EMIT IconAdded(name); } } diff --git a/scwx-qt/source/scwx/qt/manager/marker_manager.hpp b/scwx-qt/source/scwx/qt/manager/marker_manager.hpp index 9e897660..7004e117 100644 --- a/scwx-qt/source/scwx/qt/manager/marker_manager.hpp +++ b/scwx-qt/source/scwx/qt/manager/marker_manager.hpp @@ -23,11 +23,11 @@ class MarkerManager : public QObject size_t marker_count(); std::optional get_marker(types::MarkerId id); - std::optional get_index(types::MarkerId id); + std::optional get_index(types::MarkerId id); void set_marker(types::MarkerId id, const types::MarkerInfo& marker); types::MarkerId add_marker(const types::MarkerInfo& marker); - void remove_marker(types::MarkerId id); - void move_marker(size_t from, size_t to); + void remove_marker(types::MarkerId id); + void move_marker(size_t from, size_t to); void add_icon(const std::string& name, bool startup = false); std::optional get_icon(const std::string& name); @@ -39,7 +39,7 @@ class MarkerManager : public QObject void set_marker_settings_path(const std::string& path); static std::shared_ptr Instance(); - static const std::string& getDefaultIconName(); + static const std::string& getDefaultIconName(); signals: void MarkersInitialized(size_t count); @@ -51,7 +51,6 @@ class MarkerManager : public QObject void IconsReady(); void IconAdded(std::string name); - private: class Impl; std::unique_ptr p; diff --git a/scwx-qt/source/scwx/qt/model/marker_model.cpp b/scwx-qt/source/scwx/qt/model/marker_model.cpp index 7c012921..32294de0 100644 --- a/scwx-qt/source/scwx/qt/model/marker_model.cpp +++ b/scwx-qt/source/scwx/qt/model/marker_model.cpp @@ -133,7 +133,8 @@ QVariant MarkerModel::data(const QModelIndex& index, int role) const { std::optional icon = p->markerManager_->get_icon(markerInfo->iconName); - if (icon) { + if (icon) + { return util::modulateColors(icon->qIcon, QSize(iconSize_, iconSize_), QColor(markerInfo->iconColor[0], diff --git a/scwx-qt/source/scwx/qt/types/marker_types.hpp b/scwx-qt/source/scwx/qt/types/marker_types.hpp index 1848adfa..09f9a06b 100644 --- a/scwx-qt/source/scwx/qt/types/marker_types.hpp +++ b/scwx-qt/source/scwx/qt/types/marker_types.hpp @@ -31,7 +31,7 @@ struct MarkerInfo { } - MarkerId id{0}; + MarkerId id {0}; std::string name; double latitude; double longitude; @@ -39,37 +39,38 @@ struct MarkerInfo boost::gil::rgba8_pixel_t iconColor; }; -struct MarkerIconInfo { +struct MarkerIconInfo +{ explicit MarkerIconInfo(types::ImageTexture texture, std::int32_t hotX, std::int32_t hotY) : - name{types::GetTextureName(texture)}, - path{types::GetTexturePath(texture)}, - hotX{hotX}, - hotY{hotY}, - qIcon{QIcon(QString::fromStdString(path))}, - image{} + name {types::GetTextureName(texture)}, + path {types::GetTexturePath(texture)}, + hotX {hotX}, + hotY {hotY}, + qIcon {QIcon(QString::fromStdString(path))}, + image {} { } - explicit MarkerIconInfo(const std::string& path, - std::int32_t hotX, - std::int32_t hotY, + explicit MarkerIconInfo(const std::string& path, + std::int32_t hotX, + std::int32_t hotY, std::shared_ptr image) : - name{path}, - path{path}, - hotX{hotX}, - hotY{hotY}, - qIcon{QIcon(QString::fromStdString(path))}, - image{image} + name {path}, + path {path}, + hotX {hotX}, + hotY {hotY}, + qIcon {QIcon(QString::fromStdString(path))}, + image {image} { } - std::string name; - std::string path; - std::int32_t hotX; - std::int32_t hotY; - QIcon qIcon; + std::string name; + std::string path; + std::int32_t hotX; + std::int32_t hotY; + QIcon qIcon; std::optional> image; }; diff --git a/scwx-qt/source/scwx/qt/types/texture_types.cpp b/scwx-qt/source/scwx/qt/types/texture_types.cpp index 336a26d8..18efd9b9 100644 --- a/scwx-qt/source/scwx/qt/types/texture_types.cpp +++ b/scwx-qt/source/scwx/qt/types/texture_types.cpp @@ -46,14 +46,12 @@ static const std::unordered_map imageTextureInfo_ { {ImageTexture::LocationMarker, {"images/location-marker", ":/res/textures/images/location-marker.svg"}}, {ImageTexture::LocationPin, - {"images/location-pin", - ":/res/icons/font-awesome-6/location-pin.svg"}}, + {"images/location-pin", ":/res/icons/font-awesome-6/location-pin.svg"}}, {ImageTexture::LocationStar, {"images/location-star", ":/res/icons/font-awesome-6/star-solid-white.svg"}}, {ImageTexture::LocationTent, - {"images/location-tent", - ":/res/icons/font-awesome-6/tent-solid.svg"}}, + {"images/location-tent", ":/res/icons/font-awesome-6/tent-solid.svg"}}, {ImageTexture::MapboxLogo, {"images/mapbox-logo", ":/res/textures/images/mapbox-logo.svg"}}, {ImageTexture::MapTilerLogo, diff --git a/scwx-qt/source/scwx/qt/ui/edit_marker_dialog.cpp b/scwx-qt/source/scwx/qt/ui/edit_marker_dialog.cpp index 70625be4..b3c34e96 100644 --- a/scwx-qt/source/scwx/qt/ui/edit_marker_dialog.cpp +++ b/scwx-qt/source/scwx/qt/ui/edit_marker_dialog.cpp @@ -30,10 +30,7 @@ static const auto logger_ = scwx::util::Logger::Create(logPrefix_); class EditMarkerDialog::Impl { public: - explicit Impl(EditMarkerDialog* self) : - self_{self} - { - } + explicit Impl(EditMarkerDialog* self) : self_ {self} {} void show_color_dialog(); void show_icon_file_dialog(); @@ -46,15 +43,15 @@ class EditMarkerDialog::Impl void handle_rejected(); EditMarkerDialog* self_; - QPushButton* deleteButton_; + QPushButton* deleteButton_; QIcon get_colored_icon(const types::MarkerIconInfo& marker, const std::string& color); std::shared_ptr markerManager_ = manager::MarkerManager::Instance(); types::MarkerId editId_; - bool adding_; - std::string setIconOnAdded_{""}; + bool adding_; + std::string setIconOnAdded_ {""}; }; QIcon EditMarkerDialog::Impl::get_colored_icon( @@ -66,9 +63,9 @@ QIcon EditMarkerDialog::Impl::get_colored_icon( } EditMarkerDialog::EditMarkerDialog(QWidget* parent) : - QDialog(parent), - p {std::make_unique(this)}, - ui(new Ui::EditMarkerDialog) + QDialog(parent), + p {std::make_unique(this)}, + ui(new Ui::EditMarkerDialog) { ui->setupUi(this); @@ -98,7 +95,7 @@ void EditMarkerDialog::setup(double latitude, double longitude) // By default use foreground color as marker color, mainly so the icons // are vissable in the dropdown menu. QColor color = QWidget::palette().color(QWidget::foregroundRole()); - p->editId_ = p->markerManager_->add_marker(types::MarkerInfo( + p->editId_ = p->markerManager_->add_marker(types::MarkerInfo( "", latitude, longitude, @@ -114,8 +111,7 @@ void EditMarkerDialog::setup(double latitude, double longitude) void EditMarkerDialog::setup(types::MarkerId id) { - std::optional marker = - p->markerManager_->get_marker(id); + std::optional marker = p->markerManager_->get_marker(id); if (!marker) { return; @@ -143,7 +139,7 @@ void EditMarkerDialog::setup(types::MarkerId id) types::MarkerInfo EditMarkerDialog::get_marker_info() const { - QString colorName = ui->iconColorLineEdit->text(); + QString colorName = ui->iconColorLineEdit->text(); boost::gil::rgba8_pixel_t color = util::color::ToRgba8PixelT(colorName.toStdString()); @@ -270,7 +266,6 @@ void EditMarkerDialog::Impl::set_icon_color(const std::string& color) auto* iconComboBox = self_->ui->iconComboBox; - self_->ui->iconComboBox->clear(); for (auto& markerIcon : markerManager_->get_icons()) { diff --git a/scwx-qt/source/scwx/qt/ui/edit_marker_dialog.hpp b/scwx-qt/source/scwx/qt/ui/edit_marker_dialog.hpp index 5dac04ea..4008b990 100644 --- a/scwx-qt/source/scwx/qt/ui/edit_marker_dialog.hpp +++ b/scwx-qt/source/scwx/qt/ui/edit_marker_dialog.hpp @@ -32,10 +32,9 @@ class EditMarkerDialog : public QDialog private: class Impl; std::unique_ptr p; - Ui::EditMarkerDialog* ui; + Ui::EditMarkerDialog* ui; }; - } // namespace ui } // namespace qt } // namespace scwx diff --git a/test/source/scwx/qt/model/marker_model.test.cpp b/test/source/scwx/qt/model/marker_model.test.cpp index f152ddec..74ad28a9 100644 --- a/test/source/scwx/qt/model/marker_model.test.cpp +++ b/test/source/scwx/qt/model/marker_model.test.cpp @@ -10,7 +10,6 @@ #include #include - namespace scwx { namespace qt @@ -37,7 +36,6 @@ static const boost::gil::rgba8_pixel_t defaultIconColor = util::color::ToRgba8PixelT("#ffff0000"); static const std::string defaultIconName = "images/location-marker"; - void CompareFiles(const std::string& file1, const std::string& file2) { std::ifstream ifs1 {file1}; @@ -57,7 +55,8 @@ void CopyFile(const std::string& from, const std::string& to) CompareFiles(from, to); } -using TestFunction = void (std::shared_ptr, MarkerModel &); +using TestFunction = void(std::shared_ptr, + MarkerModel&); void RunTest(const std::string& filename, TestFunction testFunction) { @@ -126,7 +125,10 @@ TEST(MarkerModelTest, AddRemove) RunTest(ONE_MARKERS_FILE, [](std::shared_ptr manager, MarkerModel&) - { manager->add_marker(types::MarkerInfo("Null", 0, 0, defaultIconName, defaultIconColor)); }); + { + manager->add_marker(types::MarkerInfo( + "Null", 0, 0, defaultIconName, defaultIconColor)); + }); RunTest( EMPTY_MARKERS_FILE, [](std::shared_ptr manager, MarkerModel& model) @@ -150,11 +152,16 @@ TEST(MarkerModelTest, AddFive) RunTest(FIVE_MARKERS_FILE, [](std::shared_ptr manager, MarkerModel&) { - manager->add_marker(types::MarkerInfo("Null", 0, 0, defaultIconName, defaultIconColor)); - manager->add_marker(types::MarkerInfo("North", 90, 0, defaultIconName, defaultIconColor)); - manager->add_marker(types::MarkerInfo("South", -90, 0, defaultIconName, defaultIconColor)); - manager->add_marker(types::MarkerInfo("East", 0, 90, defaultIconName, defaultIconColor)); - manager->add_marker(types::MarkerInfo("West", 0, -90, defaultIconName, defaultIconColor)); + manager->add_marker(types::MarkerInfo( + "Null", 0, 0, defaultIconName, defaultIconColor)); + manager->add_marker(types::MarkerInfo( + "North", 90, 0, defaultIconName, defaultIconColor)); + manager->add_marker(types::MarkerInfo( + "South", -90, 0, defaultIconName, defaultIconColor)); + manager->add_marker(types::MarkerInfo( + "East", 0, 90, defaultIconName, defaultIconColor)); + manager->add_marker(types::MarkerInfo( + "West", 0, -90, defaultIconName, defaultIconColor)); }); std::filesystem::remove(TEMP_MARKERS_FILE); @@ -168,10 +175,14 @@ TEST(MarkerModelTest, AddFour) RunTest(FIVE_MARKERS_FILE, [](std::shared_ptr manager, MarkerModel&) { - manager->add_marker(types::MarkerInfo("North", 90, 0, defaultIconName, defaultIconColor)); - manager->add_marker(types::MarkerInfo("South", -90, 0, defaultIconName, defaultIconColor)); - manager->add_marker(types::MarkerInfo("East", 0, 90, defaultIconName, defaultIconColor)); - manager->add_marker(types::MarkerInfo("West", 0, -90, defaultIconName, defaultIconColor)); + manager->add_marker(types::MarkerInfo( + "North", 90, 0, defaultIconName, defaultIconColor)); + manager->add_marker(types::MarkerInfo( + "South", -90, 0, defaultIconName, defaultIconColor)); + manager->add_marker(types::MarkerInfo( + "East", 0, 90, defaultIconName, defaultIconColor)); + manager->add_marker(types::MarkerInfo( + "West", 0, -90, defaultIconName, defaultIconColor)); }); std::filesystem::remove(TEMP_MARKERS_FILE); From 7ab12e7b4bc9ed14dc0a38a0cf1f4ad00b121888 Mon Sep 17 00:00:00 2001 From: AdenKoperczak Date: Sat, 14 Dec 2024 11:17:30 -0500 Subject: [PATCH 23/31] location markers part2 initial clang-tidy changes --- .../source/scwx/qt/manager/marker_manager.cpp | 40 ++++++++--------- scwx-qt/source/scwx/qt/map/marker_layer.cpp | 5 ++- .../source/scwx/qt/ui/edit_marker_dialog.cpp | 44 ++++++++++--------- .../source/scwx/qt/ui/edit_marker_dialog.hpp | 2 +- .../scwx/qt/ui/marker_settings_widget.cpp | 4 +- .../source/scwx/qt/util/q_color_modulate.cpp | 23 +++++++--- 6 files changed, 66 insertions(+), 52 deletions(-) diff --git a/scwx-qt/source/scwx/qt/manager/marker_manager.cpp b/scwx-qt/source/scwx/qt/manager/marker_manager.cpp index 21cb90cd..cf25cbcb 100644 --- a/scwx-qt/source/scwx/qt/manager/marker_manager.cpp +++ b/scwx-qt/source/scwx/qt/manager/marker_manager.cpp @@ -168,7 +168,7 @@ void MarkerManager::Impl::ReadMarkerSettings() boost::json::value markerJson = nullptr; { - std::unique_lock lock(markerRecordLock_); + const std::unique_lock lock(markerRecordLock_); // Determine if marker settings exists if (std::filesystem::exists(markerSettingsPath_)) @@ -188,9 +188,9 @@ void MarkerManager::Impl::ReadMarkerSettings() { auto record = boost::json::value_to(markerEntry); - types::MarkerId id = NewId(); - size_t index = markerRecords_.size(); - record.markerInfo_.id = id; + const types::MarkerId id = NewId(); + const size_t index = markerRecords_.size(); + record.markerInfo_.id = id; markerRecords_.emplace_back( std::make_shared(record.markerInfo_)); idToIndex_.emplace(id, index); @@ -218,7 +218,7 @@ void MarkerManager::Impl::WriteMarkerSettings() { logger_->info("Saving location marker settings"); - std::shared_lock lock(markerRecordLock_); + const std::shared_lock lock(markerRecordLock_); auto markerJson = boost::json::value_from(markerRecords_); util::json::WriteJsonFile(markerSettingsPath_, markerJson); } @@ -263,7 +263,7 @@ MarkerManager::MarkerManager() : p(std::make_unique(this)) // Read Marker settings on startup main::Application::WaitForInitialization(); { - std::unique_lock lock(p->markerIconsLock_); + const std::unique_lock lock(p->markerIconsLock_); p->markerIcons_.reserve( defaultMarkerIcons_.size()); for (auto& icon : defaultMarkerIcons_) @@ -295,7 +295,7 @@ size_t MarkerManager::marker_count() std::optional MarkerManager::get_marker(types::MarkerId id) { - std::shared_lock lock(p->markerRecordLock_); + const std::shared_lock lock(p->markerRecordLock_); if (!p->idToIndex_.contains(id)) { return {}; @@ -313,7 +313,7 @@ std::optional MarkerManager::get_marker(types::MarkerId id) std::optional MarkerManager::get_index(types::MarkerId id) { - std::shared_lock lock(p->markerRecordLock_); + const std::shared_lock lock(p->markerRecordLock_); if (!p->idToIndex_.contains(id)) { return {}; @@ -325,7 +325,7 @@ void MarkerManager::set_marker(types::MarkerId id, const types::MarkerInfo& marker) { { - std::unique_lock lock(p->markerRecordLock_); + const std::unique_lock lock(p->markerRecordLock_); if (!p->idToIndex_.contains(id)) { return; @@ -336,9 +336,9 @@ void MarkerManager::set_marker(types::MarkerId id, logger_->warn("id in idToIndex_ but out of range!"); return; } - std::shared_ptr& markerRecord = + const std::shared_ptr& markerRecord = p->markerRecords_[index]; - markerRecord->markerInfo_ = marker; + markerRecord->markerInfo_ = marker; markerRecord->markerInfo_.id = id; add_icon(marker.iconName); @@ -351,7 +351,7 @@ types::MarkerId MarkerManager::add_marker(const types::MarkerInfo& marker) { types::MarkerId id; { - std::unique_lock lock(p->markerRecordLock_); + const std::unique_lock lock(p->markerRecordLock_); id = p->NewId(); size_t index = p->markerRecords_.size(); p->idToIndex_.emplace(id, index); @@ -368,7 +368,7 @@ types::MarkerId MarkerManager::add_marker(const types::MarkerInfo& marker) void MarkerManager::remove_marker(types::MarkerId id) { { - std::unique_lock lock(p->markerRecordLock_); + const std::unique_lock lock(p->markerRecordLock_); if (!p->idToIndex_.contains(id)) { return; @@ -399,7 +399,7 @@ void MarkerManager::remove_marker(types::MarkerId id) void MarkerManager::move_marker(size_t from, size_t to) { { - std::unique_lock lock(p->markerRecordLock_); + const std::unique_lock lock(p->markerRecordLock_); if (from >= p->markerRecords_.size() || to >= p->markerRecords_.size()) { return; @@ -430,7 +430,7 @@ void MarkerManager::move_marker(size_t from, size_t to) void MarkerManager::for_each(std::function func) { - std::shared_lock lock(p->markerRecordLock_); + const std::shared_lock lock(p->markerRecordLock_); for (auto marker : p->markerRecords_) { func(marker->markerInfo_); @@ -440,12 +440,12 @@ void MarkerManager::for_each(std::function func) void MarkerManager::add_icon(const std::string& name, bool startup) { { - std::unique_lock lock(p->markerIconsLock_); + const std::unique_lock lock(p->markerIconsLock_); if (p->markerIcons_.contains(name)) { return; } - std::shared_ptr image = + const std::shared_ptr image = ResourceManager::LoadImageResource(name); auto icon = types::MarkerIconInfo(name, -1, -1, image); @@ -464,7 +464,7 @@ void MarkerManager::add_icon(const std::string& name, bool startup) std::optional MarkerManager::get_icon(const std::string& name) { - std::shared_lock lock(p->markerIconsLock_); + const std::shared_lock lock(p->markerIconsLock_); if (p->markerIcons_.contains(name)) { return p->markerIcons_.at(name); @@ -476,7 +476,7 @@ MarkerManager::get_icon(const std::string& name) const std::unordered_map MarkerManager::get_icons() { - std::shared_lock lock(p->markerIconsLock_); + const std::shared_lock lock(p->markerIconsLock_); return p->markerIcons_; } @@ -492,7 +492,7 @@ std::shared_ptr MarkerManager::Instance() static std::weak_ptr markerManagerReference_ {}; static std::mutex instanceMutex_ {}; - std::unique_lock lock(instanceMutex_); + const std::unique_lock lock(instanceMutex_); std::shared_ptr markerManager = markerManagerReference_.lock(); diff --git a/scwx-qt/source/scwx/qt/map/marker_layer.cpp b/scwx-qt/source/scwx/qt/map/marker_layer.cpp index 0bad94f6..a0ac668f 100644 --- a/scwx-qt/source/scwx/qt/map/marker_layer.cpp +++ b/scwx-qt/source/scwx/qt/map/marker_layer.cpp @@ -72,9 +72,10 @@ void MarkerLayer::Impl::ReloadMarkers() { // must use local ID, instead of reference to marker in event handler // callback. - types::MarkerId id = marker.id; + const types::MarkerId id = marker.id; - std::shared_ptr icon = geoIcons_->AddIcon(); + const std::shared_ptr icon = + geoIcons_->AddIcon(); geoIcons_->SetIconTexture(icon, marker.iconName, 0); geoIcons_->SetIconLocation(icon, marker.latitude, marker.longitude); diff --git a/scwx-qt/source/scwx/qt/ui/edit_marker_dialog.cpp b/scwx-qt/source/scwx/qt/ui/edit_marker_dialog.cpp index b3c34e96..47bfb07f 100644 --- a/scwx-qt/source/scwx/qt/ui/edit_marker_dialog.cpp +++ b/scwx-qt/source/scwx/qt/ui/edit_marker_dialog.cpp @@ -30,7 +30,12 @@ static const auto logger_ = scwx::util::Logger::Create(logPrefix_); class EditMarkerDialog::Impl { public: - explicit Impl(EditMarkerDialog* self) : self_ {self} {} + explicit Impl(EditMarkerDialog* self) : + self_ {self}, + deleteButton_ {self_->ui->buttonBox->addButton( + "Delete", QDialogButtonBox::DestructiveRole)} + { + } void show_color_dialog(); void show_icon_file_dialog(); @@ -49,8 +54,8 @@ class EditMarkerDialog::Impl std::shared_ptr markerManager_ = manager::MarkerManager::Instance(); - types::MarkerId editId_; - bool adding_; + types::MarkerId editId_ {0}; + bool adding_ {false}; std::string setIconOnAdded_ {""}; }; @@ -75,8 +80,6 @@ EditMarkerDialog::EditMarkerDialog(QWidget* parent) : QString(""), QString::fromStdString(markerIcon.second.name)); } - p->deleteButton_ = - ui->buttonBox->addButton("Delete", QDialogButtonBox::DestructiveRole); p->connect_signals(); } @@ -94,8 +97,8 @@ void EditMarkerDialog::setup(double latitude, double longitude) { // By default use foreground color as marker color, mainly so the icons // are vissable in the dropdown menu. - QColor color = QWidget::palette().color(QWidget::foregroundRole()); - p->editId_ = p->markerManager_->add_marker(types::MarkerInfo( + const QColor color = QWidget::palette().color(QWidget::foregroundRole()); + p->editId_ = p->markerManager_->add_marker(types::MarkerInfo( "", latitude, longitude, @@ -120,7 +123,8 @@ void EditMarkerDialog::setup(types::MarkerId id) p->editId_ = id; p->adding_ = false; - std::string iconColorStr = util::color::ToArgbString(marker->iconColor); + const std::string iconColorStr = + util::color::ToArgbString(marker->iconColor); p->set_icon_color(iconColorStr); int iconIndex = @@ -139,8 +143,8 @@ void EditMarkerDialog::setup(types::MarkerId id) types::MarkerInfo EditMarkerDialog::get_marker_info() const { - QString colorName = ui->iconColorLineEdit->text(); - boost::gil::rgba8_pixel_t color = + const QString colorName = ui->iconColorLineEdit->text(); + const boost::gil::rgba8_pixel_t color = util::color::ToRgba8PixelT(colorName.toStdString()); return types::MarkerInfo( @@ -159,7 +163,7 @@ void EditMarkerDialog::Impl::show_color_dialog() dialog->setAttribute(Qt::WA_DeleteOnClose); dialog->setOption(QColorDialog::ColorDialogOption::ShowAlphaChannel); - QColor initialColor(self_->ui->iconColorLineEdit->text()); + const QColor initialColor(self_->ui->iconColorLineEdit->text()); if (initialColor.isValid()) { dialog->setCurrentColor(initialColor); @@ -170,7 +174,7 @@ void EditMarkerDialog::Impl::show_color_dialog() self_, [this](const QColor& qColor) { - QString colorName = + const QString colorName = qColor.name(QColor::NameFormat::HexArgb); self_->ui->iconColorLineEdit->setText(colorName); set_icon_color(colorName.toStdString()); @@ -180,7 +184,6 @@ void EditMarkerDialog::Impl::show_color_dialog() void EditMarkerDialog::Impl::show_icon_file_dialog() { - auto* dialog = new QFileDialog(self_); dialog->setFileMode(QFileDialog::ExistingFile); @@ -192,7 +195,7 @@ void EditMarkerDialog::Impl::show_icon_file_dialog() self_, [this](const QString& file) { - std::string path = + const std::string path = QDir::toNativeSeparators(file).toStdString(); setIconOnAdded_ = path; markerManager_->add_icon(path); @@ -224,13 +227,12 @@ void EditMarkerDialog::Impl::connect_signals() connect(self_->ui->iconColorLineEdit, &QLineEdit::textEdited, self_, - [=, this](const QString& text) - { set_icon_color(text.toStdString()); }); + [this](const QString& text) { set_icon_color(text.toStdString()); }); connect(self_->ui->iconColorButton, &QAbstractButton::clicked, self_, - [=, this]() { show_color_dialog(); }); + [this]() { show_color_dialog(); }); connect(self_->ui->iconFileOpenButton, &QPushButton::clicked, @@ -242,13 +244,13 @@ void EditMarkerDialog::Impl::connect_signals() self_, [this]() { - std::string color = + const std::string color = self_->ui->iconColorLineEdit->text().toStdString(); set_icon_color(color); if (setIconOnAdded_ != "") { - int i = self_->ui->iconComboBox->findData( + const int i = self_->ui->iconComboBox->findData( QString::fromStdString(setIconOnAdded_)); if (i >= 0) { @@ -269,9 +271,9 @@ void EditMarkerDialog::Impl::set_icon_color(const std::string& color) self_->ui->iconComboBox->clear(); for (auto& markerIcon : markerManager_->get_icons()) { - int i = + const int i = iconComboBox->findData(QString::fromStdString(markerIcon.second.name)); - QIcon icon = get_colored_icon(markerIcon.second, color); + const QIcon icon = get_colored_icon(markerIcon.second, color); if (i < 0) { iconComboBox->addItem( diff --git a/scwx-qt/source/scwx/qt/ui/edit_marker_dialog.hpp b/scwx-qt/source/scwx/qt/ui/edit_marker_dialog.hpp index 4008b990..6c6f6e6c 100644 --- a/scwx-qt/source/scwx/qt/ui/edit_marker_dialog.hpp +++ b/scwx-qt/source/scwx/qt/ui/edit_marker_dialog.hpp @@ -27,7 +27,7 @@ class EditMarkerDialog : public QDialog void setup(double latitude, double longitude); void setup(types::MarkerId id); - types::MarkerInfo get_marker_info() const; + [[nodiscard]] types::MarkerInfo get_marker_info() const; private: class Impl; diff --git a/scwx-qt/source/scwx/qt/ui/marker_settings_widget.cpp b/scwx-qt/source/scwx/qt/ui/marker_settings_widget.cpp index ba6cf88b..cc98302d 100644 --- a/scwx-qt/source/scwx/qt/ui/marker_settings_widget.cpp +++ b/scwx-qt/source/scwx/qt/ui/marker_settings_widget.cpp @@ -102,7 +102,7 @@ void MarkerSettingsWidgetImpl::ConnectSignals() return; } - bool itemSelected = selected.size() > 0; + const bool itemSelected = selected.size() > 0; self_->ui->removeButton->setEnabled(itemSelected); }); QObject::connect(self_->ui->markerView, @@ -110,7 +110,7 @@ void MarkerSettingsWidgetImpl::ConnectSignals() self_, [this](const QModelIndex& index) { - int row = index.row(); + const int row = index.row(); if (row < 0) { return; diff --git a/scwx-qt/source/scwx/qt/util/q_color_modulate.cpp b/scwx-qt/source/scwx/qt/util/q_color_modulate.cpp index 567fc62d..007ceb47 100644 --- a/scwx-qt/source/scwx/qt/util/q_color_modulate.cpp +++ b/scwx-qt/source/scwx/qt/util/q_color_modulate.cpp @@ -20,11 +20,22 @@ void modulateColors_(QImage& image, const QColor& color) QRgb* line = reinterpret_cast(image.scanLine(y)); for (int x = 0; x < image.width(); ++x) { - QRgb& rgb = line[x]; - int red = qRed(rgb) * color.redF(); - int green = qGreen(rgb) * color.greenF(); - int blue = qBlue(rgb) * color.blueF(); - int alpha = qAlpha(rgb) * color.alphaF(); + QRgb& rgb = line[x]; + /* clang-format off + * NOLINTBEGIN(cppcoreguidelines-narrowing-conversions, bugprone-narrowing-conversions) + * qRed/qGreen/qBlue/qAlpha return values 0-255, handlable by float + * redF/greenF/blueF/alphaF are all 0-1, so output is 0-255 + * Rounding is fine for this. + * clang-format on + */ + const int red = qRed(rgb) * color.redF(); + const int green = qGreen(rgb) * color.greenF(); + const int blue = qBlue(rgb) * color.blueF(); + const int alpha = qAlpha(rgb) * color.alphaF(); + /* clang-format off + * NOLINTEND(cppcoreguidelines-narrowing-conversions, bugprone-narrowing-conversions) + * clang-format on + */ rgb = qRgba(red, green, blue, alpha); } @@ -47,7 +58,7 @@ QPixmap modulateColors(const QPixmap& pixmap, const QColor& color) QIcon modulateColors(const QIcon& icon, const QSize& size, const QColor& color) { - QPixmap pixmap = modulateColors(icon.pixmap(size), color); + const QPixmap pixmap = modulateColors(icon.pixmap(size), color); return QIcon(pixmap); } From d9d8f8de8aecbee193f0153925ea2f412f137e07 Mon Sep 17 00:00:00 2001 From: AdenKoperczak Date: Sat, 14 Dec 2024 11:32:09 -0500 Subject: [PATCH 24/31] Fix preemptive initialization because of clang-tidy changes --- scwx-qt/source/scwx/qt/ui/edit_marker_dialog.cpp | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/scwx-qt/source/scwx/qt/ui/edit_marker_dialog.cpp b/scwx-qt/source/scwx/qt/ui/edit_marker_dialog.cpp index 47bfb07f..ef7966d1 100644 --- a/scwx-qt/source/scwx/qt/ui/edit_marker_dialog.cpp +++ b/scwx-qt/source/scwx/qt/ui/edit_marker_dialog.cpp @@ -30,12 +30,7 @@ static const auto logger_ = scwx::util::Logger::Create(logPrefix_); class EditMarkerDialog::Impl { public: - explicit Impl(EditMarkerDialog* self) : - self_ {self}, - deleteButton_ {self_->ui->buttonBox->addButton( - "Delete", QDialogButtonBox::DestructiveRole)} - { - } + explicit Impl(EditMarkerDialog* self) : self_ {self} {} void show_color_dialog(); void show_icon_file_dialog(); @@ -48,7 +43,7 @@ class EditMarkerDialog::Impl void handle_rejected(); EditMarkerDialog* self_; - QPushButton* deleteButton_; + QPushButton* deleteButton_ {nullptr}; QIcon get_colored_icon(const types::MarkerIconInfo& marker, const std::string& color); @@ -80,6 +75,8 @@ EditMarkerDialog::EditMarkerDialog(QWidget* parent) : QString(""), QString::fromStdString(markerIcon.second.name)); } + p->deleteButton_ = + ui->buttonBox->addButton("Delete", QDialogButtonBox::DestructiveRole); p->connect_signals(); } From 9a5d24544e4e32a34210ddc0b54fe19d93296f19 Mon Sep 17 00:00:00 2001 From: AdenKoperczak Date: Sat, 14 Dec 2024 12:17:44 -0500 Subject: [PATCH 25/31] Revert to selected icon when recoloring all the icons --- scwx-qt/source/scwx/qt/ui/edit_marker_dialog.cpp | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/scwx-qt/source/scwx/qt/ui/edit_marker_dialog.cpp b/scwx-qt/source/scwx/qt/ui/edit_marker_dialog.cpp index ef7966d1..882bbe68 100644 --- a/scwx-qt/source/scwx/qt/ui/edit_marker_dialog.cpp +++ b/scwx-qt/source/scwx/qt/ui/edit_marker_dialog.cpp @@ -265,6 +265,8 @@ void EditMarkerDialog::Impl::set_icon_color(const std::string& color) auto* iconComboBox = self_->ui->iconComboBox; + const QVariant currentIcon = iconComboBox->currentData(); + self_->ui->iconComboBox->clear(); for (auto& markerIcon : markerManager_->get_icons()) { @@ -281,6 +283,15 @@ void EditMarkerDialog::Impl::set_icon_color(const std::string& color) self_->ui->iconComboBox->setItemIcon(i, icon); } } + + const int i = + iconComboBox->findData(currentIcon); + if (i < 0) + { + return; + } + + iconComboBox->setCurrentIndex(i); } void EditMarkerDialog::Impl::handle_accepted() From 23a99f081aa3b52279b0423a932cf6dc1b656bf2 Mon Sep 17 00:00:00 2001 From: AdenKoperczak Date: Sat, 14 Dec 2024 12:20:47 -0500 Subject: [PATCH 26/31] Fix formatting on most for clang-format for location_markers_part2 --- scwx-qt/source/scwx/qt/ui/edit_marker_dialog.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/scwx-qt/source/scwx/qt/ui/edit_marker_dialog.cpp b/scwx-qt/source/scwx/qt/ui/edit_marker_dialog.cpp index 882bbe68..e186a4df 100644 --- a/scwx-qt/source/scwx/qt/ui/edit_marker_dialog.cpp +++ b/scwx-qt/source/scwx/qt/ui/edit_marker_dialog.cpp @@ -284,8 +284,7 @@ void EditMarkerDialog::Impl::set_icon_color(const std::string& color) } } - const int i = - iconComboBox->findData(currentIcon); + const int i = iconComboBox->findData(currentIcon); if (i < 0) { return; From 91b4d6c2c2ec539d2708b2335391b1cb1146a70b Mon Sep 17 00:00:00 2001 From: AdenKoperczak Date: Fri, 27 Dec 2024 10:32:07 -0500 Subject: [PATCH 27/31] added new test data from other pull requests --- test/data | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/data b/test/data index 42783ea4..0d085b1d 160000 --- a/test/data +++ b/test/data @@ -1 +1 @@ -Subproject commit 42783ea4f3b118b2b0f3266efb53f9b4384f069b +Subproject commit 0d085b1df59045e14ca996982b4907b1a0da4fdb From dc284974b35957dafada7c838d1c00836081b7f7 Mon Sep 17 00:00:00 2001 From: AdenKoperczak Date: Sat, 11 Jan 2025 10:32:21 -0500 Subject: [PATCH 28/31] First pass fixes from discussions. Mostly linter fixes --- .clang-tidy | 2 ++ .../source/scwx/qt/manager/marker_manager.cpp | 17 +++++----- .../scwx/qt/manager/resource_manager.cpp | 14 +++++++-- .../scwx/qt/manager/resource_manager.hpp | 1 + scwx-qt/source/scwx/qt/map/map_widget.cpp | 7 +++-- scwx-qt/source/scwx/qt/map/marker_layer.cpp | 14 ++++++++- scwx-qt/source/scwx/qt/model/marker_model.cpp | 15 ++++++++- scwx-qt/source/scwx/qt/types/marker_types.hpp | 29 +++++++++-------- .../source/scwx/qt/ui/edit_marker_dialog.cpp | 31 ++++++++++--------- .../source/scwx/qt/ui/edit_marker_dialog.hpp | 10 ++---- .../source/scwx/qt/ui/edit_marker_dialog.ui | 2 +- .../scwx/qt/ui/marker_settings_widget.cpp | 16 +++++++--- .../source/scwx/qt/util/q_color_modulate.cpp | 13 +++----- .../source/scwx/qt/util/q_color_modulate.hpp | 10 ++---- 14 files changed, 107 insertions(+), 74 deletions(-) diff --git a/.clang-tidy b/.clang-tidy index 602e3d0c..3c98e81d 100644 --- a/.clang-tidy +++ b/.clang-tidy @@ -10,4 +10,6 @@ Checks: - '-misc-include-cleaner' - '-misc-non-private-member-variables-in-classes' - '-modernize-use-trailing-return-type' + - '-bugprone-easily-swappable-parameters' + - '-modernize-return-braced-init-list' FormatStyle: 'file' diff --git a/scwx-qt/source/scwx/qt/manager/marker_manager.cpp b/scwx-qt/source/scwx/qt/manager/marker_manager.cpp index cf25cbcb..a9214d03 100644 --- a/scwx-qt/source/scwx/qt/manager/marker_manager.cpp +++ b/scwx-qt/source/scwx/qt/manager/marker_manager.cpp @@ -203,9 +203,7 @@ void MarkerManager::Impl::ReadMarkerSettings() } } - util::TextureAtlas& textureAtlas = util::TextureAtlas::Instance(); - textureAtlas.BuildAtlas( - 2048, 2048); // Should this code be moved to ResourceManager? + ResourceManager::BuildAtlas(); logger_->debug("{} location marker entries", markerRecords_.size()); } @@ -239,7 +237,7 @@ MarkerManager::Impl::GetMarkerByName(const std::string& name) MarkerManager::MarkerManager() : p(std::make_unique(this)) { - const std::vector defaultMarkerIcons_ { + static const std::vector defaultMarkerIcons_ { types::MarkerIconInfo(types::ImageTexture::LocationMarker, -1, -1), types::MarkerIconInfo(types::ImageTexture::LocationPin, 6, 16), types::MarkerIconInfo(types::ImageTexture::LocationCrosshair, -1, -1), @@ -256,7 +254,7 @@ MarkerManager::MarkerManager() : p(std::make_unique(this)) p->InitializeMarkerSettings(); boost::asio::post(p->threadPool_, - [this, defaultMarkerIcons_]() + [this]() { try { @@ -454,9 +452,7 @@ void MarkerManager::add_icon(const std::string& name, bool startup) if (!startup) { - util::TextureAtlas& textureAtlas = util::TextureAtlas::Instance(); - textureAtlas.BuildAtlas( - 2048, 2048); // Should this code be moved to ResourceManager? + ResourceManager::BuildAtlas(); Q_EMIT IconAdded(name); } } @@ -465,9 +461,10 @@ std::optional MarkerManager::get_icon(const std::string& name) { const std::shared_lock lock(p->markerIconsLock_); - if (p->markerIcons_.contains(name)) + auto it = p->markerIcons_.find(name); + if (it != p->markerIcons_.end()) { - return p->markerIcons_.at(name); + return it->second; } return {}; diff --git a/scwx-qt/source/scwx/qt/manager/resource_manager.cpp b/scwx-qt/source/scwx/qt/manager/resource_manager.cpp index 443d771b..5299d6ff 100644 --- a/scwx-qt/source/scwx/qt/manager/resource_manager.cpp +++ b/scwx-qt/source/scwx/qt/manager/resource_manager.cpp @@ -22,6 +22,9 @@ namespace ResourceManager static const std::string logPrefix_ = "scwx::qt::manager::resource_manager"; static const auto logger_ = scwx::util::Logger::Create(logPrefix_); +static const size_t atlasWidth = 2048; +static const size_t atlasHeight = 2048; + static void LoadFonts(); static void LoadTextures(); @@ -68,8 +71,7 @@ LoadImageResources(const std::vector& urlStrings) if (!images.empty()) { - util::TextureAtlas& textureAtlas = util::TextureAtlas::Instance(); - textureAtlas.BuildAtlas(2048, 2048); + BuildAtlas(); } return images; @@ -103,7 +105,13 @@ static void LoadTextures() GetTexturePath(lineTexture)); } - textureAtlas.BuildAtlas(2048, 2048); + BuildAtlas(); +} + +void BuildAtlas() +{ + util::TextureAtlas& textureAtlas = util::TextureAtlas::Instance(); + textureAtlas.BuildAtlas(atlasWidth, atlasHeight); } } // namespace ResourceManager diff --git a/scwx-qt/source/scwx/qt/manager/resource_manager.hpp b/scwx-qt/source/scwx/qt/manager/resource_manager.hpp index 00658891..ec7cf65e 100644 --- a/scwx-qt/source/scwx/qt/manager/resource_manager.hpp +++ b/scwx-qt/source/scwx/qt/manager/resource_manager.hpp @@ -22,6 +22,7 @@ std::shared_ptr LoadImageResource(const std::string& urlString); std::vector> LoadImageResources(const std::vector& urlStrings); +void BuildAtlas(); } // namespace ResourceManager } // namespace manager diff --git a/scwx-qt/source/scwx/qt/map/map_widget.cpp b/scwx-qt/source/scwx/qt/map/map_widget.cpp index 9c68a68a..c5c07b56 100644 --- a/scwx-qt/source/scwx/qt/map/map_widget.cpp +++ b/scwx-qt/source/scwx/qt/map/map_widget.cpp @@ -219,7 +219,7 @@ class MapWidgetImpl : public QObject std::shared_ptr layerModel_ { model::LayerModel::Instance()}; - std::shared_ptr editMarkerDialog_; + ui::EditMarkerDialog* editMarkerDialog_; std::shared_ptr hotkeyManager_ { manager::HotkeyManager::Instance()}; @@ -286,7 +286,10 @@ MapWidget::MapWidget(std::size_t id, const QMapLibre::Settings& settings) : ImGui_ImplQt_RegisterWidget(this); - p->editMarkerDialog_ = std::make_shared(this); + // Qt parent deals with memory management + // NOLINTNEXTLINE(cppcoreguidelines-owning-memory) + p->editMarkerDialog_ = new ui::EditMarkerDialog(this); + p->ConnectSignals(); } diff --git a/scwx-qt/source/scwx/qt/map/marker_layer.cpp b/scwx-qt/source/scwx/qt/map/marker_layer.cpp index a0ac668f..ba7f3e27 100644 --- a/scwx-qt/source/scwx/qt/map/marker_layer.cpp +++ b/scwx-qt/source/scwx/qt/map/marker_layer.cpp @@ -77,9 +77,21 @@ void MarkerLayer::Impl::ReloadMarkers() const std::shared_ptr icon = geoIcons_->AddIcon(); + const std::string latitudeString = + common::GetLatitudeString(marker.latitude); + const std::string longitudeString = + common::GetLongitudeString(marker.longitude); + + const std::string hoverText = + marker.name != "" ? + fmt::format( + "{}\n{}, {}", marker.name, latitudeString, longitudeString) : + fmt::format("{}, {}", latitudeString, longitudeString); + + geoIcons_->SetIconTexture(icon, marker.iconName, 0); geoIcons_->SetIconLocation(icon, marker.latitude, marker.longitude); - geoIcons_->SetIconHoverText(icon, marker.name); + geoIcons_->SetIconHoverText(icon, hoverText); geoIcons_->SetIconModulate(icon, marker.iconColor); geoIcons_->RegisterEventHandler( icon, diff --git a/scwx-qt/source/scwx/qt/model/marker_model.cpp b/scwx-qt/source/scwx/qt/model/marker_model.cpp index 32294de0..77fb7ab7 100644 --- a/scwx-qt/source/scwx/qt/model/marker_model.cpp +++ b/scwx-qt/source/scwx/qt/model/marker_model.cpp @@ -129,7 +129,20 @@ QVariant MarkerModel::data(const QModelIndex& index, int role) const break; break; case static_cast(Column::Icon): - if (role == Qt::ItemDataRole::DecorationRole) + if (role == Qt::ItemDataRole::DisplayRole) + { + std::optional icon = + p->markerManager_->get_icon(markerInfo->iconName); + if (icon) + { + return QString::fromStdString(icon->shortName); + } + else + { + return {}; + } + } + else if (role == Qt::ItemDataRole::DecorationRole) { std::optional icon = p->markerManager_->get_icon(markerInfo->iconName); diff --git a/scwx-qt/source/scwx/qt/types/marker_types.hpp b/scwx-qt/source/scwx/qt/types/marker_types.hpp index 09f9a06b..f8b1c710 100644 --- a/scwx-qt/source/scwx/qt/types/marker_types.hpp +++ b/scwx-qt/source/scwx/qt/types/marker_types.hpp @@ -2,31 +2,29 @@ #include -#include #include +#include +#include #include +#include #include -namespace scwx -{ -namespace qt -{ -namespace types +namespace scwx::qt::types { using MarkerId = std::uint64_t; struct MarkerInfo { - MarkerInfo(const std::string& name, + MarkerInfo(std::string name, double latitude, double longitude, - const std::string& iconName, + std::string iconName, const boost::gil::rgba8_pixel_t& iconColor) : - name {name}, + name {std::move(name)}, latitude {latitude}, longitude {longitude}, - iconName {iconName}, + iconName {std::move(iconName)}, iconColor {iconColor} { } @@ -41,6 +39,7 @@ struct MarkerInfo struct MarkerIconInfo { + // Initializer for default icons (which use a texture) explicit MarkerIconInfo(types::ImageTexture texture, std::int32_t hotX, std::int32_t hotY) : @@ -51,14 +50,19 @@ struct MarkerIconInfo qIcon {QIcon(QString::fromStdString(path))}, image {} { + auto qName = QString::fromStdString(name); + QStringList parts = qName.split("location-"); + shortName = parts.last().toStdString(); } + // Initializer for custom icons (which use a file path) explicit MarkerIconInfo(const std::string& path, std::int32_t hotX, std::int32_t hotY, std::shared_ptr image) : name {path}, path {path}, + shortName {QFileInfo(path.c_str()).fileName().toStdString()}, hotX {hotX}, hotY {hotY}, qIcon {QIcon(QString::fromStdString(path))}, @@ -68,12 +72,11 @@ struct MarkerIconInfo std::string name; std::string path; + std::string shortName; std::int32_t hotX; std::int32_t hotY; QIcon qIcon; std::optional> image; }; -} // namespace types -} // namespace qt -} // namespace scwx +} // namespace scwx::qt::types diff --git a/scwx-qt/source/scwx/qt/ui/edit_marker_dialog.cpp b/scwx-qt/source/scwx/qt/ui/edit_marker_dialog.cpp index e186a4df..a6aaa4d4 100644 --- a/scwx-qt/source/scwx/qt/ui/edit_marker_dialog.cpp +++ b/scwx-qt/source/scwx/qt/ui/edit_marker_dialog.cpp @@ -17,11 +17,7 @@ #include #include -namespace scwx -{ -namespace qt -{ -namespace ui +namespace scwx::qt::ui { static const std::string logPrefix_ = "scwx::qt::ui::edit_marker_dialog"; @@ -71,9 +67,10 @@ EditMarkerDialog::EditMarkerDialog(QWidget* parent) : for (auto& markerIcon : p->markerManager_->get_icons()) { - ui->iconComboBox->addItem(markerIcon.second.qIcon, - QString(""), - QString::fromStdString(markerIcon.second.name)); + ui->iconComboBox->addItem( + markerIcon.second.qIcon, + QString::fromStdString(markerIcon.second.shortName), + QString::fromStdString(markerIcon.second.name)); } p->deleteButton_ = ui->buttonBox->addButton("Delete", QDialogButtonBox::DestructiveRole); @@ -154,7 +151,8 @@ types::MarkerInfo EditMarkerDialog::get_marker_info() const void EditMarkerDialog::Impl::show_color_dialog() { - + // WA_DeleteOnClose manages memory + // NOLINTNEXTLINE(cppcoreguidelines-owning-memory) auto* dialog = new QColorDialog(self_); dialog->setAttribute(Qt::WA_DeleteOnClose); @@ -184,7 +182,7 @@ void EditMarkerDialog::Impl::show_icon_file_dialog() auto* dialog = new QFileDialog(self_); dialog->setFileMode(QFileDialog::ExistingFile); - dialog->setNameFilters({"Icon (*.png *.svg)", "All (*)"}); + dialog->setNameFilters({"Icon (*.png *.svg)", "All Files (*)"}); dialog->setAttribute(Qt::WA_DeleteOnClose); QObject::connect(dialog, @@ -256,6 +254,11 @@ void EditMarkerDialog::Impl::connect_signals() } } }); + + connect(self_->ui->buttonBox->button(QDialogButtonBox::Apply), + &QAbstractButton::clicked, + self_, + [this]() { handle_accepted(); }); } void EditMarkerDialog::Impl::set_icon_color(const std::string& color) @@ -276,7 +279,9 @@ void EditMarkerDialog::Impl::set_icon_color(const std::string& color) if (i < 0) { iconComboBox->addItem( - icon, QString(""), QString::fromStdString(markerIcon.second.name)); + icon, + QString::fromStdString(markerIcon.second.shortName), + QString::fromStdString(markerIcon.second.name)); } else { @@ -306,6 +311,4 @@ void EditMarkerDialog::Impl::handle_rejected() } } -} // namespace ui -} // namespace qt -} // namespace scwx +} // namespace scwx::qt::ui diff --git a/scwx-qt/source/scwx/qt/ui/edit_marker_dialog.hpp b/scwx-qt/source/scwx/qt/ui/edit_marker_dialog.hpp index 6c6f6e6c..c20ebe27 100644 --- a/scwx-qt/source/scwx/qt/ui/edit_marker_dialog.hpp +++ b/scwx-qt/source/scwx/qt/ui/edit_marker_dialog.hpp @@ -8,11 +8,7 @@ namespace Ui class EditMarkerDialog; } -namespace scwx -{ -namespace qt -{ -namespace ui +namespace scwx::qt::ui { class EditMarkerDialog : public QDialog { @@ -35,6 +31,4 @@ class EditMarkerDialog : public QDialog Ui::EditMarkerDialog* ui; }; -} // namespace ui -} // namespace qt -} // namespace scwx +} // namespace scwx::qt::ui diff --git a/scwx-qt/source/scwx/qt/ui/edit_marker_dialog.ui b/scwx-qt/source/scwx/qt/ui/edit_marker_dialog.ui index 3bfad9a6..d3d47500 100644 --- a/scwx-qt/source/scwx/qt/ui/edit_marker_dialog.ui +++ b/scwx-qt/source/scwx/qt/ui/edit_marker_dialog.ui @@ -101,7 +101,7 @@ Qt::Orientation::Horizontal - QDialogButtonBox::StandardButton::Cancel|QDialogButtonBox::StandardButton::Ok + QDialogButtonBox::StandardButton::Apply|QDialogButtonBox::StandardButton::Cancel|QDialogButtonBox::StandardButton::Ok diff --git a/scwx-qt/source/scwx/qt/ui/marker_settings_widget.cpp b/scwx-qt/source/scwx/qt/ui/marker_settings_widget.cpp index cc98302d..b3ba8440 100644 --- a/scwx-qt/source/scwx/qt/ui/marker_settings_widget.cpp +++ b/scwx-qt/source/scwx/qt/ui/marker_settings_widget.cpp @@ -23,15 +23,21 @@ class MarkerSettingsWidgetImpl { public: explicit MarkerSettingsWidgetImpl(MarkerSettingsWidget* self) : - self_ {self}, - markerModel_ {new model::MarkerModel(self_)} + self_ {self}, + markerModel_ {new model::MarkerModel(self_)}, + proxyModel_ {new QSortFilterProxyModel(self_)} { + proxyModel_->setSourceModel(markerModel_); + proxyModel_->setSortRole(Qt::DisplayRole); // TODO types::SortRole + proxyModel_->setFilterCaseSensitivity(Qt::CaseInsensitive); + proxyModel_->setFilterKeyColumn(-1); } void ConnectSignals(); - MarkerSettingsWidget* self_; - model::MarkerModel* markerModel_; + MarkerSettingsWidget* self_; + model::MarkerModel* markerModel_; + QSortFilterProxyModel* proxyModel_; std::shared_ptr markerManager_ { manager::MarkerManager::Instance()}; std::shared_ptr editMarkerDialog_ {nullptr}; @@ -46,7 +52,7 @@ MarkerSettingsWidget::MarkerSettingsWidget(QWidget* parent) : ui->setupUi(this); ui->removeButton->setEnabled(false); - ui->markerView->setModel(p->markerModel_); + ui->markerView->setModel(p->proxyModel_); p->editMarkerDialog_ = std::make_shared(this); diff --git a/scwx-qt/source/scwx/qt/util/q_color_modulate.cpp b/scwx-qt/source/scwx/qt/util/q_color_modulate.cpp index 007ceb47..c205ce88 100644 --- a/scwx-qt/source/scwx/qt/util/q_color_modulate.cpp +++ b/scwx-qt/source/scwx/qt/util/q_color_modulate.cpp @@ -6,11 +6,7 @@ #include #include -namespace scwx -{ -namespace qt -{ -namespace util +namespace scwx::qt::util { void modulateColors_(QImage& image, const QColor& color) @@ -20,6 +16,9 @@ void modulateColors_(QImage& image, const QColor& color) QRgb* line = reinterpret_cast(image.scanLine(y)); for (int x = 0; x < image.width(); ++x) { + // This is pulled from Qt Documentation + // https://doc.qt.io/qt-6/qimage.html#scanLine + // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic) QRgb& rgb = line[x]; /* clang-format off * NOLINTBEGIN(cppcoreguidelines-narrowing-conversions, bugprone-narrowing-conversions) @@ -62,6 +61,4 @@ QIcon modulateColors(const QIcon& icon, const QSize& size, const QColor& color) return QIcon(pixmap); } -} // namespace util -} // namespace qt -} // namespace scwx +} // namespace scwx::qt::util diff --git a/scwx-qt/source/scwx/qt/util/q_color_modulate.hpp b/scwx-qt/source/scwx/qt/util/q_color_modulate.hpp index c54b852f..35326293 100644 --- a/scwx-qt/source/scwx/qt/util/q_color_modulate.hpp +++ b/scwx-qt/source/scwx/qt/util/q_color_modulate.hpp @@ -6,17 +6,11 @@ #include #include -namespace scwx -{ -namespace qt -{ -namespace util +namespace scwx::qt::util { QImage modulateColors(const QImage& image, const QColor& color); QPixmap modulateColors(const QPixmap& pixmap, const QColor& color); QIcon modulateColors(const QIcon& icon, const QSize& size, const QColor& color); -} // namespace util -} // namespace qt -} // namespace scwx +} // namespace scwx::qt::util From 2fd94c6575b226ba20036c80c99e3ddc9453b2dd Mon Sep 17 00:00:00 2001 From: AdenKoperczak Date: Sat, 11 Jan 2025 10:33:40 -0500 Subject: [PATCH 29/31] Gracefully fallback when icon cannot be loaded --- scwx-qt/source/scwx/qt/manager/marker_manager.cpp | 13 +++++++++++-- scwx-qt/source/scwx/qt/map/marker_layer.cpp | 10 +++++++++- 2 files changed, 20 insertions(+), 3 deletions(-) diff --git a/scwx-qt/source/scwx/qt/manager/marker_manager.cpp b/scwx-qt/source/scwx/qt/manager/marker_manager.cpp index a9214d03..798f94b2 100644 --- a/scwx-qt/source/scwx/qt/manager/marker_manager.cpp +++ b/scwx-qt/source/scwx/qt/manager/marker_manager.cpp @@ -446,8 +446,17 @@ void MarkerManager::add_icon(const std::string& name, bool startup) const std::shared_ptr image = ResourceManager::LoadImageResource(name); - auto icon = types::MarkerIconInfo(name, -1, -1, image); - p->markerIcons_.emplace(name, icon); + if (image) + { + auto icon = types::MarkerIconInfo(name, -1, -1, image); + p->markerIcons_.emplace(name, icon); + } + else + { + // defaultIconName should always be in markerIcons, so at is fine + auto icon = p->markerIcons_.at(defaultIconName); + p->markerIcons_.emplace(name, icon); + } } if (!startup) diff --git a/scwx-qt/source/scwx/qt/map/marker_layer.cpp b/scwx-qt/source/scwx/qt/map/marker_layer.cpp index ba7f3e27..906ef7c1 100644 --- a/scwx-qt/source/scwx/qt/map/marker_layer.cpp +++ b/scwx-qt/source/scwx/qt/map/marker_layer.cpp @@ -88,8 +88,16 @@ void MarkerLayer::Impl::ReloadMarkers() "{}\n{}, {}", marker.name, latitudeString, longitudeString) : fmt::format("{}, {}", latitudeString, longitudeString); + auto iconInfo = markerManager_->get_icon(marker.iconName); + if (iconInfo) + { + geoIcons_->SetIconTexture(icon, iconInfo->name, 0); + } + else + { + geoIcons_->SetIconTexture(icon, marker.iconName, 0); + } - geoIcons_->SetIconTexture(icon, marker.iconName, 0); geoIcons_->SetIconLocation(icon, marker.latitude, marker.longitude); geoIcons_->SetIconHoverText(icon, hoverText); geoIcons_->SetIconModulate(icon, marker.iconColor); From 7edafe8d7874da549f0c2eeb1743b0b9dfc736dd Mon Sep 17 00:00:00 2001 From: AdenKoperczak Date: Sat, 11 Jan 2025 10:46:04 -0500 Subject: [PATCH 30/31] Location Markers Part2 clang-format/tidy suggestions --- scwx-qt/source/scwx/qt/manager/marker_manager.cpp | 2 +- scwx-qt/source/scwx/qt/manager/resource_manager.cpp | 4 ++-- scwx-qt/source/scwx/qt/map/map_widget.cpp | 2 +- scwx-qt/source/scwx/qt/types/marker_types.hpp | 4 ++-- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/scwx-qt/source/scwx/qt/manager/marker_manager.cpp b/scwx-qt/source/scwx/qt/manager/marker_manager.cpp index 798f94b2..fd7bee13 100644 --- a/scwx-qt/source/scwx/qt/manager/marker_manager.cpp +++ b/scwx-qt/source/scwx/qt/manager/marker_manager.cpp @@ -470,7 +470,7 @@ std::optional MarkerManager::get_icon(const std::string& name) { const std::shared_lock lock(p->markerIconsLock_); - auto it = p->markerIcons_.find(name); + auto it = p->markerIcons_.find(name); if (it != p->markerIcons_.end()) { return it->second; diff --git a/scwx-qt/source/scwx/qt/manager/resource_manager.cpp b/scwx-qt/source/scwx/qt/manager/resource_manager.cpp index 5299d6ff..c6c40a26 100644 --- a/scwx-qt/source/scwx/qt/manager/resource_manager.cpp +++ b/scwx-qt/source/scwx/qt/manager/resource_manager.cpp @@ -110,8 +110,8 @@ static void LoadTextures() void BuildAtlas() { - util::TextureAtlas& textureAtlas = util::TextureAtlas::Instance(); - textureAtlas.BuildAtlas(atlasWidth, atlasHeight); + util::TextureAtlas& textureAtlas = util::TextureAtlas::Instance(); + textureAtlas.BuildAtlas(atlasWidth, atlasHeight); } } // namespace ResourceManager diff --git a/scwx-qt/source/scwx/qt/map/map_widget.cpp b/scwx-qt/source/scwx/qt/map/map_widget.cpp index c5c07b56..0e9846dd 100644 --- a/scwx-qt/source/scwx/qt/map/map_widget.cpp +++ b/scwx-qt/source/scwx/qt/map/map_widget.cpp @@ -219,7 +219,7 @@ class MapWidgetImpl : public QObject std::shared_ptr layerModel_ { model::LayerModel::Instance()}; - ui::EditMarkerDialog* editMarkerDialog_; + ui::EditMarkerDialog* editMarkerDialog_ {nullptr}; std::shared_ptr hotkeyManager_ { manager::HotkeyManager::Instance()}; diff --git a/scwx-qt/source/scwx/qt/types/marker_types.hpp b/scwx-qt/source/scwx/qt/types/marker_types.hpp index f8b1c710..661aa207 100644 --- a/scwx-qt/source/scwx/qt/types/marker_types.hpp +++ b/scwx-qt/source/scwx/qt/types/marker_types.hpp @@ -50,9 +50,9 @@ struct MarkerIconInfo qIcon {QIcon(QString::fromStdString(path))}, image {} { - auto qName = QString::fromStdString(name); + auto qName = QString::fromStdString(name); QStringList parts = qName.split("location-"); - shortName = parts.last().toStdString(); + shortName = parts.last().toStdString(); } // Initializer for custom icons (which use a file path) From 736fd43b46365bc4798eb72fee73dc444cb034aa Mon Sep 17 00:00:00 2001 From: AdenKoperczak Date: Sat, 11 Jan 2025 10:58:30 -0500 Subject: [PATCH 31/31] Location Markers Part 2 linter suggestions (post rebase) --- scwx-qt/source/scwx/qt/map/map_widget.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/scwx-qt/source/scwx/qt/map/map_widget.cpp b/scwx-qt/source/scwx/qt/map/map_widget.cpp index 0e9846dd..e363e3dc 100644 --- a/scwx-qt/source/scwx/qt/map/map_widget.cpp +++ b/scwx-qt/source/scwx/qt/map/map_widget.cpp @@ -80,7 +80,6 @@ class MapWidgetImpl : public QObject map_(), layerList_ {}, imGuiRendererInitialized_ {false}, - editMarkerDialog_ {nullptr}, radarProductManager_ {nullptr}, radarProductLayer_ {nullptr}, overlayLayer_ {nullptr},