mirror of
				https://github.com/ciphervance/supercell-wx.git
				synced 2025-10-31 00:40:06 +00:00 
			
		
		
		
	Added a basic location marker manager.
This commit is contained in:
		
							parent
							
								
									84233868d6
								
							
						
					
					
						commit
						19415cd0a1
					
				
					 16 changed files with 806 additions and 44 deletions
				
			
		|  | @ -31,6 +31,7 @@ | |||
| #include <scwx/qt/ui/level2_settings_widget.hpp> | ||||
| #include <scwx/qt/ui/level3_products_widget.hpp> | ||||
| #include <scwx/qt/ui/placefile_dialog.hpp> | ||||
| #include <scwx/qt/ui/marker_dialog.hpp> | ||||
| #include <scwx/qt/ui/radar_site_dialog.hpp> | ||||
| #include <scwx/qt/ui/settings_dialog.hpp> | ||||
| #include <scwx/qt/ui/update_dialog.hpp> | ||||
|  | @ -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(); | ||||
|  |  | |||
|  | @ -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(); | ||||
|  |  | |||
|  | @ -39,7 +39,7 @@ | |||
|      <x>0</x> | ||||
|      <y>0</y> | ||||
|      <width>1024</width> | ||||
|      <height>33</height> | ||||
|      <height>22</height> | ||||
|     </rect> | ||||
|    </property> | ||||
|    <widget class="QMenu" name="menuFile"> | ||||
|  | @ -104,6 +104,7 @@ | |||
|     </property> | ||||
|     <addaction name="actionPlacefileManager"/> | ||||
|     <addaction name="actionLayerManager"/> | ||||
|     <addaction name="actionMarkerManager"/> | ||||
|    </widget> | ||||
|    <addaction name="menuFile"/> | ||||
|    <addaction name="menuView"/> | ||||
|  | @ -152,8 +153,8 @@ | |||
|          <rect> | ||||
|           <x>0</x> | ||||
|           <y>0</y> | ||||
|           <width>190</width> | ||||
|           <height>686</height> | ||||
|           <width>205</width> | ||||
|           <height>701</height> | ||||
|          </rect> | ||||
|         </property> | ||||
|         <layout class="QVBoxLayout" name="verticalLayout_6"> | ||||
|  | @ -487,6 +488,15 @@ | |||
|     <string>&GPS Info</string> | ||||
|    </property> | ||||
|   </action> | ||||
|   <action name="actionMarkerManager"> | ||||
|    <property name="icon"> | ||||
|     <iconset resource="../../../../scwx-qt.qrc"> | ||||
|      <normaloff>:/res/icons/font-awesome-6/house-solid.svg</normaloff>:/res/icons/font-awesome-6/house-solid.svg</iconset> | ||||
|    </property> | ||||
|    <property name="text"> | ||||
|     <string>Location &Marker Manager</string> | ||||
|    </property> | ||||
|   </action> | ||||
|  </widget> | ||||
|  <resources> | ||||
|   <include location="../../../../scwx-qt.qrc"/> | ||||
|  |  | |||
|  | @ -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<MarkerRecord>& 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<MarkerRecord>, | ||||
|  | @ -124,7 +124,7 @@ void MarkerManager::Impl::ReadMarkerSettings() | |||
|             MarkerRecord record = | ||||
|                boost::json::value_to<MarkerRecord>(markerEntry); | ||||
| 
 | ||||
|             if (!record.markerInfo_.name_.empty()) | ||||
|             if (!record.markerInfo_.name.empty()) | ||||
|             { | ||||
|                markerRecords_.emplace_back( | ||||
|                   std::make_shared<MarkerRecord>(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<MarkerManager::Impl::MarkerRecord> markerRecord = | ||||
|       p->markerRecords_[index]; | ||||
|    return markerRecord->toMarkerInfo(); | ||||
| } | ||||
| 
 | ||||
| types::MarkerInfo MarkerManager::get_marker(const std::string& name) | ||||
| { | ||||
|    std::shared_ptr<MarkerManager::Impl::MarkerRecord> markerRecord = | ||||
|       p->GetMarkerByName(name); | ||||
|    return markerRecord->toMarkerInfo(); | ||||
| } | ||||
| 
 | ||||
| void MarkerManager::set_marker(size_t index, const types::MarkerInfo& marker) | ||||
| { | ||||
|    std::shared_ptr<MarkerManager::Impl::MarkerRecord> markerRecord = | ||||
|       p->markerRecords_[index]; | ||||
|    markerRecord->markerInfo_ = marker; | ||||
| } | ||||
| 
 | ||||
| void MarkerManager::set_marker(const std::string&       name, | ||||
|                                const types::MarkerInfo& marker) | ||||
| { | ||||
|    std::shared_ptr<MarkerManager::Impl::MarkerRecord> 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<Impl::MarkerRecord>(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> MarkerManager::Instance() | ||||
|  |  | |||
|  | @ -2,8 +2,6 @@ | |||
| 
 | ||||
| #include <scwx/qt/types/marker_types.hpp> | ||||
| 
 | ||||
| #include <string> | ||||
| 
 | ||||
| #include <QObject> | ||||
| 
 | ||||
| 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<MarkerManager> Instance(); | ||||
| 
 | ||||
| signals: | ||||
|    void MarkersUpdated(); | ||||
|    void MarkerAdded(); | ||||
|    void MarkerRemoved(size_t index); | ||||
| 
 | ||||
| private: | ||||
|    class Impl; | ||||
|    std::unique_ptr<Impl> p; | ||||
|  |  | |||
|  | @ -18,39 +18,56 @@ static const auto        logger_    = scwx::util::Logger::Create(logPrefix_); | |||
| class MarkerLayer::Impl | ||||
| { | ||||
| public: | ||||
|    explicit Impl(std::shared_ptr<MapContext> context) : | ||||
|        geoIcons_ {std::make_shared<gl::draw::GeoIcons>(context)} | ||||
|    explicit Impl(MarkerLayer* self, std::shared_ptr<MapContext> context) : | ||||
|        self_ {self}, geoIcons_ {std::make_shared<gl::draw::GeoIcons>(context)} | ||||
|    { | ||||
|       ConnectSignals(); | ||||
|    } | ||||
|    ~Impl() {} | ||||
| 
 | ||||
|    void ReloadMarkers(); | ||||
|    void ConnectSignals(); | ||||
| 
 | ||||
|    MarkerLayer* self_; | ||||
|    const std::string& markerIconName_ { | ||||
|       types::GetTextureName(types::ImageTexture::Cursor17)}; | ||||
| 
 | ||||
|    std::shared_ptr<gl::draw::GeoIcons> 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<gl::draw::GeoIconDrawItem> 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<MapContext>& context) : | ||||
|     DrawLayer(context), p(std::make_unique<MarkerLayer::Impl>(context)) | ||||
|     DrawLayer(context), p(std::make_unique<MarkerLayer::Impl>(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(); | ||||
|  |  | |||
							
								
								
									
										258
									
								
								scwx-qt/source/scwx/qt/model/marker_model.cpp
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										258
									
								
								scwx-qt/source/scwx/qt/model/marker_model.cpp
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,258 @@ | |||
| #include <scwx/qt/model/marker_model.hpp> | ||||
| #include <scwx/qt/manager/marker_manager.hpp> | ||||
| #include <scwx/qt/types/marker_types.hpp> | ||||
| #include <scwx/qt/types/qt_types.hpp> | ||||
| #include <scwx/util/logger.hpp> | ||||
| 
 | ||||
| #include <QApplication> | ||||
| #include <QCheckBox> | ||||
| #include <QFontMetrics> | ||||
| #include <QStyle> | ||||
| #include <QStyleOption> | ||||
| 
 | ||||
| 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<int>(MarkerModel::Column::Name); | ||||
| static constexpr int kLastColumn = | ||||
|    static_cast<int>(MarkerModel::Column::Longitude); | ||||
| static constexpr int kNumColumns = kLastColumn - kFirstColumn + 1; | ||||
| 
 | ||||
| class MarkerModel::Impl | ||||
| { | ||||
| public: | ||||
|    explicit Impl() {} | ||||
|    ~Impl() = default; | ||||
|    std::shared_ptr<manager::MarkerManager> markerManager_ { | ||||
|       manager::MarkerManager::Instance()}; | ||||
| }; | ||||
| 
 | ||||
| MarkerModel::MarkerModel(QObject* parent) : | ||||
|    QAbstractTableModel(parent), p(std::make_unique<Impl>()) | ||||
| { | ||||
|    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<int>(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<int>(Column::Name): | ||||
|    case static_cast<int>(Column::Latitude): | ||||
|    case static_cast<int>(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<std::size_t>(index.row()) >= | ||||
|           p->markerManager_->marker_count()) | ||||
|    { | ||||
|       return QVariant(); | ||||
|    } | ||||
| 
 | ||||
|    const types::MarkerInfo markerInfo = | ||||
|       p->markerManager_->get_marker(index.row()); | ||||
| 
 | ||||
|    switch(index.column()) | ||||
|    { | ||||
|    case static_cast<int>(Column::Name): | ||||
|       if (role == Qt::ItemDataRole::DisplayRole || | ||||
|           role == Qt::ItemDataRole::ToolTipRole || | ||||
|           role == Qt::ItemDataRole::EditRole) | ||||
|       { | ||||
|          return QString::fromStdString(markerInfo.name); | ||||
|       } | ||||
|       break; | ||||
| 
 | ||||
|    case static_cast<int>(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<int>(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<int>(Column::Name): | ||||
|                return tr("Name"); | ||||
| 
 | ||||
|             case static_cast<int>(Column::Latitude): | ||||
|                return tr("Latitude"); | ||||
| 
 | ||||
|             case static_cast<int>(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<std::size_t>(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<int>(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<int>(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<int>(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<int>(p->markerManager_->marker_count() - 1); | ||||
|    beginInsertRows(QModelIndex(), newIndex, newIndex); | ||||
|    endInsertRows(); | ||||
| 
 | ||||
|    Q_EMIT dataChanged(topLeft, bottomRight); | ||||
| } | ||||
| 
 | ||||
| } // namespace model
 | ||||
| } // namespace qt
 | ||||
| } // namespace scwx
 | ||||
							
								
								
									
										51
									
								
								scwx-qt/source/scwx/qt/model/marker_model.hpp
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										51
									
								
								scwx-qt/source/scwx/qt/model/marker_model.hpp
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,51 @@ | |||
| #pragma once | ||||
| 
 | ||||
| #include <QAbstractTableModel> | ||||
| 
 | ||||
| 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<Impl> p; | ||||
| }; | ||||
| 
 | ||||
| } // namespace model
 | ||||
| } // namespace qt
 | ||||
| } // namespace scwx
 | ||||
|  | @ -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
 | ||||
|  |  | |||
							
								
								
									
										45
									
								
								scwx-qt/source/scwx/qt/ui/marker_dialog.cpp
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										45
									
								
								scwx-qt/source/scwx/qt/ui/marker_dialog.cpp
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,45 @@ | |||
| #include "marker_dialog.hpp" | ||||
| #include "ui_marker_dialog.h" | ||||
| 
 | ||||
| #include <scwx/qt/ui/marker_settings_widget.hpp> | ||||
| #include <scwx/util/logger.hpp> | ||||
| 
 | ||||
| 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<MarkerDialogImpl>()}, | ||||
|     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
 | ||||
							
								
								
									
										35
									
								
								scwx-qt/source/scwx/qt/ui/marker_dialog.hpp
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										35
									
								
								scwx-qt/source/scwx/qt/ui/marker_dialog.hpp
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,35 @@ | |||
| #pragma once | ||||
| 
 | ||||
| #include <QDialog> | ||||
| 
 | ||||
| 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<MarkerDialogImpl> p; | ||||
|    Ui::MarkerDialog*                 ui; | ||||
| }; | ||||
| 
 | ||||
| } // namespace ui
 | ||||
| } // namespace qt
 | ||||
| } // namespace scwx
 | ||||
							
								
								
									
										88
									
								
								scwx-qt/source/scwx/qt/ui/marker_dialog.ui
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										88
									
								
								scwx-qt/source/scwx/qt/ui/marker_dialog.ui
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,88 @@ | |||
| <?xml version="1.0" encoding="UTF-8"?> | ||||
| <ui version="4.0"> | ||||
|  <class>MarkerDialog</class> | ||||
|  <widget class="QDialog" name="MarkerDialog"> | ||||
|   <property name="geometry"> | ||||
|    <rect> | ||||
|     <x>0</x> | ||||
|     <y>0</y> | ||||
|     <width>700</width> | ||||
|     <height>600</height> | ||||
|    </rect> | ||||
|   </property> | ||||
|   <property name="windowTitle"> | ||||
|    <string>Marker Manager</string> | ||||
|   </property> | ||||
|   <layout class="QVBoxLayout" name="verticalLayout"> | ||||
|    <item> | ||||
|     <widget class="QFrame" name="contentsFrame"> | ||||
|      <property name="frameShape"> | ||||
|       <enum>QFrame::StyledPanel</enum> | ||||
|      </property> | ||||
|      <property name="frameShadow"> | ||||
|       <enum>QFrame::Raised</enum> | ||||
|      </property> | ||||
|      <layout class="QVBoxLayout" name="verticalLayout_2"> | ||||
|       <property name="leftMargin"> | ||||
|        <number>0</number> | ||||
|       </property> | ||||
|       <property name="topMargin"> | ||||
|        <number>0</number> | ||||
|       </property> | ||||
|       <property name="rightMargin"> | ||||
|        <number>0</number> | ||||
|       </property> | ||||
|       <property name="bottomMargin"> | ||||
|        <number>0</number> | ||||
|       </property> | ||||
|      </layout> | ||||
|     </widget> | ||||
|    </item> | ||||
|    <item> | ||||
|     <widget class="QDialogButtonBox" name="buttonBox"> | ||||
|      <property name="orientation"> | ||||
|       <enum>Qt::Horizontal</enum> | ||||
|      </property> | ||||
|      <property name="standardButtons"> | ||||
|       <set>QDialogButtonBox::Close</set> | ||||
|      </property> | ||||
|     </widget> | ||||
|    </item> | ||||
|   </layout> | ||||
|  </widget> | ||||
|  <resources/> | ||||
|  <connections> | ||||
|   <connection> | ||||
|    <sender>buttonBox</sender> | ||||
|    <signal>accepted()</signal> | ||||
|    <receiver>MarkerDialog</receiver> | ||||
|    <slot>accept()</slot> | ||||
|    <hints> | ||||
|     <hint type="sourcelabel"> | ||||
|      <x>248</x> | ||||
|      <y>254</y> | ||||
|     </hint> | ||||
|     <hint type="destinationlabel"> | ||||
|      <x>157</x> | ||||
|      <y>274</y> | ||||
|     </hint> | ||||
|    </hints> | ||||
|   </connection> | ||||
|   <connection> | ||||
|    <sender>buttonBox</sender> | ||||
|    <signal>rejected()</signal> | ||||
|    <receiver>MarkerDialog</receiver> | ||||
|    <slot>reject()</slot> | ||||
|    <hints> | ||||
|     <hint type="sourcelabel"> | ||||
|      <x>316</x> | ||||
|      <y>260</y> | ||||
|     </hint> | ||||
|     <hint type="destinationlabel"> | ||||
|      <x>286</x> | ||||
|      <y>274</y> | ||||
|     </hint> | ||||
|    </hints> | ||||
|   </connection> | ||||
|  </connections> | ||||
| </ui> | ||||
							
								
								
									
										105
									
								
								scwx-qt/source/scwx/qt/ui/marker_settings_widget.cpp
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										105
									
								
								scwx-qt/source/scwx/qt/ui/marker_settings_widget.cpp
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,105 @@ | |||
| #include "marker_settings_widget.hpp" | ||||
| #include "ui_marker_settings_widget.h" | ||||
| 
 | ||||
| #include <scwx/qt/manager/marker_manager.hpp> | ||||
| #include <scwx/qt/model/marker_model.hpp> | ||||
| #include <scwx/qt/types/qt_types.hpp> | ||||
| #include <scwx/qt/ui/open_url_dialog.hpp> | ||||
| #include <scwx/util/logger.hpp> | ||||
| 
 | ||||
| #include <QSortFilterProxyModel> | ||||
| 
 | ||||
| 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<manager::MarkerManager> markerManager_ { | ||||
|       manager::MarkerManager::Instance()}; | ||||
| }; | ||||
| 
 | ||||
| 
 | ||||
| MarkerSettingsWidget::MarkerSettingsWidget(QWidget* parent) : | ||||
|     QFrame(parent), | ||||
|     p {std::make_unique<MarkerSettingsWidgetImpl>(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<int>( | ||||
|                                 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
 | ||||
							
								
								
									
										35
									
								
								scwx-qt/source/scwx/qt/ui/marker_settings_widget.hpp
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										35
									
								
								scwx-qt/source/scwx/qt/ui/marker_settings_widget.hpp
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,35 @@ | |||
| #pragma once | ||||
| 
 | ||||
| #include <QFrame> | ||||
| 
 | ||||
| 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<MarkerSettingsWidgetImpl> p; | ||||
|    Ui::MarkerSettingsWidget*                 ui; | ||||
| }; | ||||
| 
 | ||||
| } // namespace ui
 | ||||
| } // namespace qt
 | ||||
| } // namespace scwx
 | ||||
							
								
								
									
										88
									
								
								scwx-qt/source/scwx/qt/ui/marker_settings_widget.ui
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										88
									
								
								scwx-qt/source/scwx/qt/ui/marker_settings_widget.ui
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,88 @@ | |||
| <?xml version="1.0" encoding="UTF-8"?> | ||||
| <ui version="4.0"> | ||||
|  <class>MarkerSettingsWidget</class> | ||||
|  <widget class="QFrame" name="MarkerSettingsWidget"> | ||||
|   <property name="geometry"> | ||||
|    <rect> | ||||
|     <x>0</x> | ||||
|     <y>0</y> | ||||
|     <width>400</width> | ||||
|     <height>300</height> | ||||
|    </rect> | ||||
|   </property> | ||||
|   <property name="windowTitle"> | ||||
|    <string>Frame</string> | ||||
|   </property> | ||||
|   <layout class="QVBoxLayout" name="verticalLayout"> | ||||
|    <item> | ||||
|     <widget class="QTreeView" name="markerView"> | ||||
|      <property name="alternatingRowColors"> | ||||
|       <bool>true</bool> | ||||
|      </property> | ||||
|      <property name="indentation"> | ||||
|       <number>0</number> | ||||
|      </property> | ||||
|      <property name="sortingEnabled"> | ||||
|       <bool>true</bool> | ||||
|      </property> | ||||
|     </widget> | ||||
|    </item> | ||||
|    <item> | ||||
|     <widget class="QFrame" name="buttonFrame"> | ||||
|      <property name="frameShape"> | ||||
|       <enum>QFrame::Shape::StyledPanel</enum> | ||||
|      </property> | ||||
|      <property name="frameShadow"> | ||||
|       <enum>QFrame::Shadow::Raised</enum> | ||||
|      </property> | ||||
|      <layout class="QHBoxLayout" name="horizontalLayout_2"> | ||||
|       <property name="leftMargin"> | ||||
|        <number>0</number> | ||||
|       </property> | ||||
|       <property name="topMargin"> | ||||
|        <number>0</number> | ||||
|       </property> | ||||
|       <property name="rightMargin"> | ||||
|        <number>0</number> | ||||
|       </property> | ||||
|       <property name="bottomMargin"> | ||||
|        <number>0</number> | ||||
|       </property> | ||||
|       <item> | ||||
|        <spacer name="horizontalSpacer"> | ||||
|         <property name="orientation"> | ||||
|          <enum>Qt::Orientation::Horizontal</enum> | ||||
|         </property> | ||||
|         <property name="sizeHint" stdset="0"> | ||||
|          <size> | ||||
|           <width>40</width> | ||||
|           <height>20</height> | ||||
|          </size> | ||||
|         </property> | ||||
|        </spacer> | ||||
|       </item> | ||||
|       <item> | ||||
|        <widget class="QPushButton" name="addButton"> | ||||
|         <property name="text"> | ||||
|          <string>&Add</string> | ||||
|         </property> | ||||
|        </widget> | ||||
|       </item> | ||||
|       <item> | ||||
|        <widget class="QPushButton" name="removeButton"> | ||||
|         <property name="enabled"> | ||||
|          <bool>false</bool> | ||||
|         </property> | ||||
|         <property name="text"> | ||||
|          <string>R&emove</string> | ||||
|         </property> | ||||
|        </widget> | ||||
|       </item> | ||||
|      </layout> | ||||
|     </widget> | ||||
|    </item> | ||||
|   </layout> | ||||
|  </widget> | ||||
|  <resources/> | ||||
|  <connections/> | ||||
| </ui> | ||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 AdenKoperczak
						AdenKoperczak