From 19415cd0a16dad50ce30f713b904bca504a0f63b Mon Sep 17 00:00:00 2001 From: AdenKoperczak Date: Sat, 5 Oct 2024 13:09:55 -0400 Subject: [PATCH] Added a basic location marker manager. --- scwx-qt/scwx-qt.cmake | 8 + scwx-qt/source/scwx/qt/main/main_window.cpp | 11 + scwx-qt/source/scwx/qt/main/main_window.hpp | 1 + scwx-qt/source/scwx/qt/main/main_window.ui | 16 +- .../source/scwx/qt/manager/marker_manager.cpp | 53 ++-- .../source/scwx/qt/manager/marker_manager.hpp | 16 +- scwx-qt/source/scwx/qt/map/marker_layer.cpp | 32 ++- scwx-qt/source/scwx/qt/model/marker_model.cpp | 258 ++++++++++++++++++ scwx-qt/source/scwx/qt/model/marker_model.hpp | 51 ++++ scwx-qt/source/scwx/qt/types/marker_types.hpp | 8 +- scwx-qt/source/scwx/qt/ui/marker_dialog.cpp | 45 +++ scwx-qt/source/scwx/qt/ui/marker_dialog.hpp | 35 +++ scwx-qt/source/scwx/qt/ui/marker_dialog.ui | 88 ++++++ .../scwx/qt/ui/marker_settings_widget.cpp | 105 +++++++ .../scwx/qt/ui/marker_settings_widget.hpp | 35 +++ .../scwx/qt/ui/marker_settings_widget.ui | 88 ++++++ 16 files changed, 806 insertions(+), 44 deletions(-) create mode 100644 scwx-qt/source/scwx/qt/model/marker_model.cpp create mode 100644 scwx-qt/source/scwx/qt/model/marker_model.hpp create mode 100644 scwx-qt/source/scwx/qt/ui/marker_dialog.cpp create mode 100644 scwx-qt/source/scwx/qt/ui/marker_dialog.hpp create mode 100644 scwx-qt/source/scwx/qt/ui/marker_dialog.ui create mode 100644 scwx-qt/source/scwx/qt/ui/marker_settings_widget.cpp create mode 100644 scwx-qt/source/scwx/qt/ui/marker_settings_widget.hpp create mode 100644 scwx-qt/source/scwx/qt/ui/marker_settings_widget.ui diff --git a/scwx-qt/scwx-qt.cmake b/scwx-qt/scwx-qt.cmake index 6edb022d..71700cec 100644 --- a/scwx-qt/scwx-qt.cmake +++ b/scwx-qt/scwx-qt.cmake @@ -158,6 +158,7 @@ set(HDR_MODEL source/scwx/qt/model/alert_model.hpp source/scwx/qt/model/imgui_context_model.hpp source/scwx/qt/model/layer_model.hpp source/scwx/qt/model/placefile_model.hpp + source/scwx/qt/model/marker_model.hpp source/scwx/qt/model/radar_site_model.hpp source/scwx/qt/model/tree_item.hpp source/scwx/qt/model/tree_model.hpp) @@ -166,6 +167,7 @@ set(SRC_MODEL source/scwx/qt/model/alert_model.cpp source/scwx/qt/model/imgui_context_model.cpp source/scwx/qt/model/layer_model.cpp source/scwx/qt/model/placefile_model.cpp + source/scwx/qt/model/marker_model.cpp source/scwx/qt/model/radar_site_model.cpp source/scwx/qt/model/tree_item.cpp source/scwx/qt/model/tree_model.cpp) @@ -265,6 +267,8 @@ set(HDR_UI source/scwx/qt/ui/about_dialog.hpp source/scwx/qt/ui/open_url_dialog.hpp source/scwx/qt/ui/placefile_dialog.hpp source/scwx/qt/ui/placefile_settings_widget.hpp + source/scwx/qt/ui/marker_dialog.hpp + source/scwx/qt/ui/marker_settings_widget.hpp source/scwx/qt/ui/progress_dialog.hpp source/scwx/qt/ui/radar_site_dialog.hpp source/scwx/qt/ui/serial_port_dialog.hpp @@ -293,6 +297,8 @@ set(SRC_UI source/scwx/qt/ui/about_dialog.cpp source/scwx/qt/ui/open_url_dialog.cpp source/scwx/qt/ui/placefile_dialog.cpp source/scwx/qt/ui/placefile_settings_widget.cpp + source/scwx/qt/ui/marker_dialog.cpp + source/scwx/qt/ui/marker_settings_widget.cpp source/scwx/qt/ui/progress_dialog.cpp source/scwx/qt/ui/radar_site_dialog.cpp source/scwx/qt/ui/settings_dialog.cpp @@ -312,6 +318,8 @@ set(UI_UI source/scwx/qt/ui/about_dialog.ui source/scwx/qt/ui/open_url_dialog.ui source/scwx/qt/ui/placefile_dialog.ui source/scwx/qt/ui/placefile_settings_widget.ui + source/scwx/qt/ui/marker_dialog.ui + source/scwx/qt/ui/marker_settings_widget.ui source/scwx/qt/ui/progress_dialog.ui source/scwx/qt/ui/radar_site_dialog.ui source/scwx/qt/ui/settings_dialog.ui diff --git a/scwx-qt/source/scwx/qt/main/main_window.cpp b/scwx-qt/source/scwx/qt/main/main_window.cpp index 836d6784..ac5f73e1 100644 --- a/scwx-qt/source/scwx/qt/main/main_window.cpp +++ b/scwx-qt/source/scwx/qt/main/main_window.cpp @@ -31,6 +31,7 @@ #include #include #include +#include #include #include #include @@ -87,6 +88,7 @@ public: imGuiDebugDialog_ {nullptr}, layerDialog_ {nullptr}, placefileDialog_ {nullptr}, + markerDialog_ {nullptr}, radarSiteDialog_ {nullptr}, settingsDialog_ {nullptr}, updateDialog_ {nullptr}, @@ -205,6 +207,7 @@ public: ui::ImGuiDebugDialog* imGuiDebugDialog_; ui::LayerDialog* layerDialog_; ui::PlacefileDialog* placefileDialog_; + ui::MarkerDialog* markerDialog_; ui::RadarSiteDialog* radarSiteDialog_; ui::SettingsDialog* settingsDialog_; ui::UpdateDialog* updateDialog_; @@ -306,6 +309,9 @@ MainWindow::MainWindow(QWidget* parent) : // Placefile Manager Dialog p->placefileDialog_ = new ui::PlacefileDialog(this); + // Marker Manager Dialog + p->markerDialog_ = new ui::MarkerDialog(this); + // Layer Dialog p->layerDialog_ = new ui::LayerDialog(this); @@ -613,6 +619,11 @@ void MainWindow::on_actionPlacefileManager_triggered() p->placefileDialog_->show(); } +void MainWindow::on_actionMarkerManager_triggered() +{ + p->markerDialog_->show(); +} + void MainWindow::on_actionLayerManager_triggered() { p->layerDialog_->show(); diff --git a/scwx-qt/source/scwx/qt/main/main_window.hpp b/scwx-qt/source/scwx/qt/main/main_window.hpp index c6ea3a5f..6a4fb5b4 100644 --- a/scwx-qt/source/scwx/qt/main/main_window.hpp +++ b/scwx-qt/source/scwx/qt/main/main_window.hpp @@ -44,6 +44,7 @@ private slots: void on_actionRadarRange_triggered(bool checked); void on_actionRadarSites_triggered(bool checked); void on_actionPlacefileManager_triggered(); + void on_actionMarkerManager_triggered(); void on_actionLayerManager_triggered(); void on_actionImGuiDebug_triggered(); void on_actionDumpLayerList_triggered(); diff --git a/scwx-qt/source/scwx/qt/main/main_window.ui b/scwx-qt/source/scwx/qt/main/main_window.ui index 9fab1adf..c5e877c9 100644 --- a/scwx-qt/source/scwx/qt/main/main_window.ui +++ b/scwx-qt/source/scwx/qt/main/main_window.ui @@ -39,7 +39,7 @@ 0 0 1024 - 33 + 22 @@ -104,6 +104,7 @@ + @@ -152,8 +153,8 @@ 0 0 - 190 - 686 + 205 + 701 @@ -487,6 +488,15 @@ &GPS Info + + + + :/res/icons/font-awesome-6/house-solid.svg:/res/icons/font-awesome-6/house-solid.svg + + + Location &Marker Manager + + diff --git a/scwx-qt/source/scwx/qt/manager/marker_manager.cpp b/scwx-qt/source/scwx/qt/manager/marker_manager.cpp index f99b2ded..15dc0509 100644 --- a/scwx-qt/source/scwx/qt/manager/marker_manager.cpp +++ b/scwx-qt/source/scwx/qt/manager/marker_manager.cpp @@ -56,7 +56,7 @@ public: { } - types::MarkerInfo toMarkerInfo() + const types::MarkerInfo& toMarkerInfo() { return markerInfo_; } @@ -67,9 +67,9 @@ public: boost::json::value& jv, const std::shared_ptr& record) { - jv = {{kNameName_, record->markerInfo_.name_}, - {kLatitudeName_, record->markerInfo_.latitude_}, - {kLongitudeName_, record->markerInfo_.longitude_}}; + jv = {{kNameName_, record->markerInfo_.name}, + {kLatitudeName_, record->markerInfo_.latitude}, + {kLongitudeName_, record->markerInfo_.longitude}}; } friend MarkerRecord tag_invoke(boost::json::value_to_tag, @@ -124,7 +124,7 @@ void MarkerManager::Impl::ReadMarkerSettings() MarkerRecord record = boost::json::value_to(markerEntry); - if (!record.markerInfo_.name_.empty()) + if (!record.markerInfo_.name.empty()) { markerRecords_.emplace_back( std::make_shared(record.markerInfo_)); @@ -138,6 +138,8 @@ void MarkerManager::Impl::ReadMarkerSettings() logger_->debug("{} location marker entries", markerRecords_.size()); } + + Q_EMIT self_->MarkersUpdated(); } void MarkerManager::Impl::WriteMarkerSettings() @@ -153,7 +155,7 @@ MarkerManager::Impl::GetMarkerByName(const std::string& name) { for (auto& markerRecord : markerRecords_) { - if (markerRecord->markerInfo_.name_ == name) + if (markerRecord->markerInfo_.name == name) { return markerRecord; } @@ -190,38 +192,44 @@ size_t MarkerManager::marker_count() } // TODO deal with out of range/not found -types::MarkerInfo MarkerManager::get_marker(size_t index) +const types::MarkerInfo& MarkerManager::get_marker(size_t index) { std::shared_ptr markerRecord = p->markerRecords_[index]; return markerRecord->toMarkerInfo(); } -types::MarkerInfo MarkerManager::get_marker(const std::string& name) -{ - std::shared_ptr markerRecord = - p->GetMarkerByName(name); - return markerRecord->toMarkerInfo(); -} - void MarkerManager::set_marker(size_t index, const types::MarkerInfo& marker) { std::shared_ptr markerRecord = p->markerRecords_[index]; markerRecord->markerInfo_ = marker; -} - -void MarkerManager::set_marker(const std::string& name, - const types::MarkerInfo& marker) -{ - std::shared_ptr markerRecord = - p->GetMarkerByName(name); - markerRecord->markerInfo_ = marker; + Q_EMIT MarkersUpdated(); } void MarkerManager::add_marker(const types::MarkerInfo& marker) { p->markerRecords_.emplace_back(std::make_shared(marker)); + Q_EMIT MarkerAdded(); + Q_EMIT MarkersUpdated(); +} + +void MarkerManager::remove_marker(size_t index) +{ + if (index >= p->markerRecords_.size()) + { + return; + } + + for (size_t i = index; i < p->markerRecords_.size() - 1; i++) + { + p->markerRecords_[i] = p->markerRecords_[i + 1]; + } + + p->markerRecords_.pop_back(); + + Q_EMIT MarkerRemoved(index); + Q_EMIT MarkersUpdated(); } void MarkerManager::move_marker(size_t from, size_t to) @@ -250,6 +258,7 @@ void MarkerManager::move_marker(size_t from, size_t to) } p->markerRecords_[to] = markerRecord; } + Q_EMIT MarkersUpdated(); } std::shared_ptr MarkerManager::Instance() diff --git a/scwx-qt/source/scwx/qt/manager/marker_manager.hpp b/scwx-qt/source/scwx/qt/manager/marker_manager.hpp index 4fa5639c..e21accbf 100644 --- a/scwx-qt/source/scwx/qt/manager/marker_manager.hpp +++ b/scwx-qt/source/scwx/qt/manager/marker_manager.hpp @@ -2,8 +2,6 @@ #include -#include - #include namespace scwx @@ -21,16 +19,20 @@ public: explicit MarkerManager(); ~MarkerManager(); - size_t marker_count(); - types::MarkerInfo get_marker(size_t index); - types::MarkerInfo get_marker(const std::string& name); - void set_marker(size_t index, const types::MarkerInfo& marker); - void set_marker(const std::string& name, const types::MarkerInfo& marker); + size_t marker_count(); + const types::MarkerInfo& get_marker(size_t index); + void set_marker(size_t index, const types::MarkerInfo& marker); void add_marker(const types::MarkerInfo& marker); + void remove_marker(size_t index); void move_marker(size_t from, size_t to); static std::shared_ptr Instance(); +signals: + void MarkersUpdated(); + void MarkerAdded(); + void MarkerRemoved(size_t index); + 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 7b3ffb1b..1a09a0c6 100644 --- a/scwx-qt/source/scwx/qt/map/marker_layer.cpp +++ b/scwx-qt/source/scwx/qt/map/marker_layer.cpp @@ -18,39 +18,56 @@ static const auto logger_ = scwx::util::Logger::Create(logPrefix_); class MarkerLayer::Impl { public: - explicit Impl(std::shared_ptr context) : - geoIcons_ {std::make_shared(context)} + explicit Impl(MarkerLayer* self, std::shared_ptr context) : + self_ {self}, geoIcons_ {std::make_shared(context)} { + ConnectSignals(); } ~Impl() {} void ReloadMarkers(); + void ConnectSignals(); + MarkerLayer* self_; const std::string& markerIconName_ { types::GetTextureName(types::ImageTexture::Cursor17)}; std::shared_ptr geoIcons_; }; +void MarkerLayer::Impl::ConnectSignals() +{ + auto markerManager = manager::MarkerManager::Instance(); + + QObject::connect(markerManager.get(), + &manager::MarkerManager::MarkersUpdated, + self_, + [this]() + { + this->ReloadMarkers(); + }); +} + void MarkerLayer::Impl::ReloadMarkers() { + logger_->debug("ReloadMarkers()"); auto markerManager = manager::MarkerManager::Instance(); geoIcons_->StartIcons(); for (size_t i = 0; i < markerManager->marker_count(); i++) { - types::MarkerInfo marker = markerManager->get_marker(i); + const types::MarkerInfo& marker = markerManager->get_marker(i); std::shared_ptr icon = geoIcons_->AddIcon(); geoIcons_->SetIconTexture(icon, markerIconName_, 0); - geoIcons_->SetIconLocation(icon, marker.latitude_, marker.longitude_); + geoIcons_->SetIconLocation(icon, marker.latitude, marker.longitude); } geoIcons_->FinishIcons(); } MarkerLayer::MarkerLayer(const std::shared_ptr& context) : - DrawLayer(context), p(std::make_unique(context)) + DrawLayer(context), p(std::make_unique(this, context)) { AddDrawItem(p->geoIcons_); } @@ -65,6 +82,8 @@ void MarkerLayer::Initialize() p->geoIcons_->StartIconSheets(); p->geoIcons_->AddIconSheet(p->markerIconName_); p->geoIcons_->FinishIconSheets(); + + p->ReloadMarkers(); } void MarkerLayer::Render(const QMapLibre::CustomLayerRenderParameters& params) @@ -72,9 +91,6 @@ void MarkerLayer::Render(const QMapLibre::CustomLayerRenderParameters& params) // auto markerManager = manager::MarkerManager::Instance(); gl::OpenGLFunctions& gl = context()->gl(); - // TODO. do not redo this every time - p->ReloadMarkers(); - DrawLayer::Render(params); SCWX_GL_CHECK_ERROR(); diff --git a/scwx-qt/source/scwx/qt/model/marker_model.cpp b/scwx-qt/source/scwx/qt/model/marker_model.cpp new file mode 100644 index 00000000..3061c764 --- /dev/null +++ b/scwx-qt/source/scwx/qt/model/marker_model.cpp @@ -0,0 +1,258 @@ +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +namespace scwx +{ +namespace qt +{ +namespace model +{ + +static const std::string logPrefix_ = "scwx::qt::model::marker_model"; +static const auto logger_ = scwx::util::Logger::Create(logPrefix_); + +static constexpr int kFirstColumn = + static_cast(MarkerModel::Column::Name); +static constexpr int kLastColumn = + static_cast(MarkerModel::Column::Longitude); +static constexpr int kNumColumns = kLastColumn - kFirstColumn + 1; + +class MarkerModel::Impl +{ +public: + explicit Impl() {} + ~Impl() = default; + std::shared_ptr markerManager_ { + manager::MarkerManager::Instance()}; +}; + +MarkerModel::MarkerModel(QObject* parent) : + QAbstractTableModel(parent), p(std::make_unique()) +{ + connect(p->markerManager_.get(), + &manager::MarkerManager::MarkerAdded, + this, + &MarkerModel::HandleMarkerAdded); +} + +MarkerModel::~MarkerModel() = default; + +int MarkerModel::rowCount(const QModelIndex& parent) const +{ + return parent.isValid() ? + 0 : + static_cast(p->markerManager_->marker_count()); +} + +int MarkerModel::columnCount(const QModelIndex& parent) const +{ + return parent.isValid() ? 0 : kNumColumns; +} + +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 = 6; + + if (!index.isValid() || index.row() < 0 || + static_cast(index.row()) >= + p->markerManager_->marker_count()) + { + return QVariant(); + } + + const types::MarkerInfo markerInfo = + p->markerManager_->get_marker(index.row()); + + switch(index.column()) + { + case static_cast(Column::Name): + if (role == Qt::ItemDataRole::DisplayRole || + role == Qt::ItemDataRole::ToolTipRole || + role == Qt::ItemDataRole::EditRole) + { + return QString::fromStdString(markerInfo.name); + } + break; + + case static_cast(Column::Latitude): + if (role == Qt::ItemDataRole::DisplayRole || + role == Qt::ItemDataRole::ToolTipRole || + role == Qt::ItemDataRole::EditRole) + { + return QString::number( + markerInfo.latitude, COORDINATE_FORMAT, COORDINATE_PRECISION); + } + break; + + case static_cast(Column::Longitude): + if (role == Qt::ItemDataRole::DisplayRole || + role == Qt::ItemDataRole::ToolTipRole || + role == Qt::ItemDataRole::EditRole) + { + return QString::number( + markerInfo.longitude, COORDINATE_FORMAT, COORDINATE_PRECISION); + } + break; + + default: + break; + } + + return QVariant(); +} + +QVariant MarkerModel::headerData(int section, + Qt::Orientation orientation, + int role) const +{ + if (role == Qt::ItemDataRole::DisplayRole) + { + if (orientation == Qt::Horizontal) + { + switch (section) + { + case static_cast(Column::Name): + return tr("Name"); + + case static_cast(Column::Latitude): + return tr("Latitude"); + + case static_cast(Column::Longitude): + return tr("Longitude"); + + default: + break; + } + } + } + + return QVariant(); +} + +bool MarkerModel::setData(const QModelIndex& index, + const QVariant& value, + int role) +{ + if (!index.isValid() || index.row() < 0 || + static_cast(index.row()) >= + p->markerManager_->marker_count()) + { + return false; + } + + types::MarkerInfo markerInfo = p->markerManager_->get_marker(index.row()); + 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(index.row(), 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()) + { + markerInfo.latitude = 0; + p->markerManager_->set_marker(index.row(), markerInfo); + result = true; + } + else if (ok) + { + markerInfo.latitude = latitude; + p->markerManager_->set_marker(index.row(), 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()) + { + markerInfo.longitude = 0; + p->markerManager_->set_marker(index.row(), markerInfo); + result = true; + } + else if (ok) + { + markerInfo.longitude = longitude; + p->markerManager_->set_marker(index.row(), markerInfo); + result = true; + } + } + break; + + default: + break; + } + + if (result) + { + Q_EMIT dataChanged(index, index); + } + + return result; +} + +void MarkerModel::HandleMarkerAdded() +{ + QModelIndex topLeft = createIndex(0, kFirstColumn); + QModelIndex bottomRight = + createIndex(p->markerManager_->marker_count() - 1, kLastColumn); + + logger_->debug("marker_count: {}", p->markerManager_->marker_count()); + + const int newIndex = static_cast(p->markerManager_->marker_count() - 1); + beginInsertRows(QModelIndex(), newIndex, newIndex); + endInsertRows(); + + Q_EMIT dataChanged(topLeft, bottomRight); +} + +} // namespace model +} // namespace qt +} // namespace scwx diff --git a/scwx-qt/source/scwx/qt/model/marker_model.hpp b/scwx-qt/source/scwx/qt/model/marker_model.hpp new file mode 100644 index 00000000..a3d23546 --- /dev/null +++ b/scwx-qt/source/scwx/qt/model/marker_model.hpp @@ -0,0 +1,51 @@ +#pragma once + +#include + +namespace scwx +{ +namespace qt +{ +namespace model +{ + +class MarkerModel : public QAbstractTableModel +{ +public: + enum class Column : int + { + Name = 0, + Latitude = 1, + Longitude = 2 + }; + + explicit MarkerModel(QObject* parent = nullptr); + ~MarkerModel(); + + int rowCount(const QModelIndex& parent = QModelIndex()) const override; + int columnCount(const QModelIndex& parent = QModelIndex()) const override; + + Qt::ItemFlags flags(const QModelIndex& index) const override; + + QVariant data(const QModelIndex& index, + int role = Qt::DisplayRole) const override; + QVariant headerData(int section, + Qt::Orientation orientation, + int role = Qt::DisplayRole) const override; + + bool setData(const QModelIndex& index, + const QVariant& value, + int role = Qt::EditRole) override; + + +public slots: + void HandleMarkerAdded(); + +private: + class Impl; + std::unique_ptr p; +}; + +} // namespace model +} // 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 1fd02111..ffa94b3d 100644 --- a/scwx-qt/source/scwx/qt/types/marker_types.hpp +++ b/scwx-qt/source/scwx/qt/types/marker_types.hpp @@ -12,13 +12,13 @@ namespace types struct MarkerInfo { MarkerInfo(std::string name, double latitude, double longitude) : - name_ {name}, latitude_ {latitude}, longitude_ {longitude} + name {name}, latitude {latitude}, longitude {longitude} { } - std::string name_; - double latitude_; - double longitude_; + std::string name; + double latitude; + double longitude; }; } // namespace types diff --git a/scwx-qt/source/scwx/qt/ui/marker_dialog.cpp b/scwx-qt/source/scwx/qt/ui/marker_dialog.cpp new file mode 100644 index 00000000..3db33a06 --- /dev/null +++ b/scwx-qt/source/scwx/qt/ui/marker_dialog.cpp @@ -0,0 +1,45 @@ +#include "marker_dialog.hpp" +#include "ui_marker_dialog.h" + +#include +#include + +namespace scwx +{ +namespace qt +{ +namespace ui +{ + +static const std::string logPrefix_ = "scwx::qt::ui::marker_dialog"; +static const auto logger_ = scwx::util::Logger::Create(logPrefix_); + +class MarkerDialogImpl +{ +public: + explicit MarkerDialogImpl() {} + ~MarkerDialogImpl() = default; + + MarkerSettingsWidget* markerSettingsWidget_ {nullptr}; +}; + +MarkerDialog::MarkerDialog(QWidget* parent) : + QDialog(parent), + p {std::make_unique()}, + ui(new Ui::MarkerDialog) +{ + ui->setupUi(this); + + p->markerSettingsWidget_ = new MarkerSettingsWidget(this); + p->markerSettingsWidget_->layout()->setContentsMargins(0, 0, 0, 0); + ui->contentsFrame->layout()->addWidget(p->markerSettingsWidget_); +} + +MarkerDialog::~MarkerDialog() +{ + delete ui; +} + +} // namespace ui +} // namespace qt +} // namespace scwx diff --git a/scwx-qt/source/scwx/qt/ui/marker_dialog.hpp b/scwx-qt/source/scwx/qt/ui/marker_dialog.hpp new file mode 100644 index 00000000..4a9503e9 --- /dev/null +++ b/scwx-qt/source/scwx/qt/ui/marker_dialog.hpp @@ -0,0 +1,35 @@ +#pragma once + +#include + +namespace Ui +{ +class MarkerDialog; +} + +namespace scwx +{ +namespace qt +{ +namespace ui +{ + +class MarkerDialogImpl; + +class MarkerDialog : public QDialog +{ + Q_OBJECT + +public: + explicit MarkerDialog(QWidget* parent = nullptr); + ~MarkerDialog(); + +private: + friend class MarkerDialogImpl; + std::unique_ptr p; + Ui::MarkerDialog* ui; +}; + +} // namespace ui +} // namespace qt +} // namespace scwx diff --git a/scwx-qt/source/scwx/qt/ui/marker_dialog.ui b/scwx-qt/source/scwx/qt/ui/marker_dialog.ui new file mode 100644 index 00000000..641775a5 --- /dev/null +++ b/scwx-qt/source/scwx/qt/ui/marker_dialog.ui @@ -0,0 +1,88 @@ + + + MarkerDialog + + + + 0 + 0 + 700 + 600 + + + + Marker Manager + + + + + + QFrame::StyledPanel + + + QFrame::Raised + + + + 0 + + + 0 + + + 0 + + + 0 + + + + + + + + Qt::Horizontal + + + QDialogButtonBox::Close + + + + + + + + + buttonBox + accepted() + MarkerDialog + accept() + + + 248 + 254 + + + 157 + 274 + + + + + buttonBox + rejected() + MarkerDialog + 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 new file mode 100644 index 00000000..8fc1fe6a --- /dev/null +++ b/scwx-qt/source/scwx/qt/ui/marker_settings_widget.cpp @@ -0,0 +1,105 @@ +#include "marker_settings_widget.hpp" +#include "ui_marker_settings_widget.h" + +#include +#include +#include +#include +#include + +#include + +namespace scwx +{ +namespace qt +{ +namespace ui +{ + +static const std::string logPrefix_ = "scwx::qt::ui::marker_settings_widget"; +static const auto logger_ = scwx::util::Logger::Create(logPrefix_); + +class MarkerSettingsWidgetImpl +{ +public: + explicit MarkerSettingsWidgetImpl(MarkerSettingsWidget* self) : + self_ {self}, + markerModel_ {new model::MarkerModel(self_)} + { + } + + void ConnectSignals(); + + MarkerSettingsWidget* self_; + model::MarkerModel* markerModel_; + std::shared_ptr markerManager_ { + manager::MarkerManager::Instance()}; +}; + + +MarkerSettingsWidget::MarkerSettingsWidget(QWidget* parent) : + QFrame(parent), + p {std::make_unique(this)}, + ui(new Ui::MarkerSettingsWidget) +{ + ui->setupUi(this); + + ui->removeButton->setEnabled(false); + + ui->markerView->setModel(p->markerModel_); + + p->ConnectSignals(); +} + +MarkerSettingsWidget::~MarkerSettingsWidget() +{ + delete ui; +} + +void MarkerSettingsWidgetImpl::ConnectSignals() +{ + QObject::connect(self_->ui->addButton, + &QPushButton::clicked, + self_, + [this]() + { + markerManager_->add_marker(types::MarkerInfo("", 0, 0)); + }); + QObject::connect(self_->ui->removeButton, + &QPushButton::clicked, + self_, + [this]() + { + auto selectionModel = + self_->ui->markerView->selectionModel(); + QModelIndex selected = + selectionModel + ->selectedRows(static_cast( + model::MarkerModel::Column::Name)) + .first(); + + markerManager_->remove_marker(selected.row()); + }); + QObject::connect( + self_->ui->markerView->selectionModel(), + &QItemSelectionModel::selectionChanged, + self_, + [this](const QItemSelection& selected, const QItemSelection& deselected) + { + if (selected.size() == 0 && deselected.size() == 0) + { + // Items which stay selected but change their index are not + // included in selected and deselected. Thus, this signal might + // be emitted with both selected and deselected empty, if only + // the indices of selected items change. + return; + } + + bool itemSelected = selected.size() > 0; + self_->ui->removeButton->setEnabled(itemSelected); + }); +} + +} // namespace ui +} // namespace qt +} // namespace scwx diff --git a/scwx-qt/source/scwx/qt/ui/marker_settings_widget.hpp b/scwx-qt/source/scwx/qt/ui/marker_settings_widget.hpp new file mode 100644 index 00000000..b784c418 --- /dev/null +++ b/scwx-qt/source/scwx/qt/ui/marker_settings_widget.hpp @@ -0,0 +1,35 @@ +#pragma once + +#include + +namespace Ui +{ +class MarkerSettingsWidget; +} + +namespace scwx +{ +namespace qt +{ +namespace ui +{ + +class MarkerSettingsWidgetImpl; + +class MarkerSettingsWidget : public QFrame +{ + Q_OBJECT + +public: + explicit MarkerSettingsWidget(QWidget* parent = nullptr); + ~MarkerSettingsWidget(); + +private: + friend class MarkerSettingsWidgetImpl; + std::unique_ptr p; + Ui::MarkerSettingsWidget* ui; +}; + +} // namespace ui +} // namespace qt +} // namespace scwx diff --git a/scwx-qt/source/scwx/qt/ui/marker_settings_widget.ui b/scwx-qt/source/scwx/qt/ui/marker_settings_widget.ui new file mode 100644 index 00000000..12315d24 --- /dev/null +++ b/scwx-qt/source/scwx/qt/ui/marker_settings_widget.ui @@ -0,0 +1,88 @@ + + + MarkerSettingsWidget + + + + 0 + 0 + 400 + 300 + + + + Frame + + + + + + true + + + 0 + + + true + + + + + + + QFrame::Shape::StyledPanel + + + QFrame::Shadow::Raised + + + + 0 + + + 0 + + + 0 + + + 0 + + + + + Qt::Orientation::Horizontal + + + + 40 + 20 + + + + + + + + &Add + + + + + + + false + + + R&emove + + + + + + + + + + +