From d0d9adfd1a3ecc5fbbf798222e9971dedc2c63a5 Mon Sep 17 00:00:00 2001 From: AdenKoperczak Date: Thu, 28 Nov 2024 12:33:14 -0500 Subject: [PATCH] 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 @@ public: 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 @@ public: 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