mirror of
				https://github.com/ciphervance/supercell-wx.git
				synced 2025-10-31 09:50:06 +00:00 
			
		
		
		
	Additional layer model row population, properties
This commit is contained in:
		
							parent
							
								
									d82a1cc171
								
							
						
					
					
						commit
						14d6912014
					
				
					 4 changed files with 187 additions and 90 deletions
				
			
		|  | @ -1,5 +1,6 @@ | |||
| #include <scwx/qt/model/layer_model.hpp> | ||||
| #include <scwx/qt/manager/placefile_manager.hpp> | ||||
| #include <scwx/qt/types/map_types.hpp> | ||||
| #include <scwx/qt/types/qt_types.hpp> | ||||
| #include <scwx/util/logger.hpp> | ||||
| 
 | ||||
|  | @ -27,35 +28,53 @@ static constexpr int kLastColumn = | |||
|    static_cast<int>(LayerModel::Column::Description); | ||||
| static constexpr int kNumColumns = kLastColumn - kFirstColumn + 1; | ||||
| 
 | ||||
| static const std::unordered_map<LayerModel::LayerType, std::string> | ||||
|    layerTypeNames_ {{LayerModel::LayerType::Map, "Map"}, | ||||
|                     {LayerModel::LayerType::Radar, "Radar"}, | ||||
|                     {LayerModel::LayerType::Alert, "Alert"}, | ||||
|                     {LayerModel::LayerType::Placefile, "Placefile"}}; | ||||
| static constexpr std::size_t kMapCount_ = 4u; | ||||
| 
 | ||||
| typedef std::variant<std::monostate, std::string, awips::Phenomenon> | ||||
| typedef std:: | ||||
|    variant<std::monostate, types::Layer, awips::Phenomenon, std::string> | ||||
|       LayerDescription; | ||||
| typedef boost::container::devector< | ||||
|    std::pair<LayerModel::LayerType, LayerDescription>> | ||||
|    LayerVector; | ||||
| 
 | ||||
| class LayerModel::Impl | ||||
| { | ||||
| public: | ||||
|    explicit Impl() | ||||
|    struct LayerInfo | ||||
|    { | ||||
|       layers_.emplace_back(LayerType::Alert, awips::Phenomenon::Tornado); | ||||
|       layers_.emplace_back(LayerType::Alert, awips::Phenomenon::SnowSquall); | ||||
|       layers_.emplace_back(LayerType::Alert, | ||||
|                            awips::Phenomenon::SevereThunderstorm); | ||||
|       layers_.emplace_back(LayerType::Alert, awips::Phenomenon::FlashFlood); | ||||
|       layers_.emplace_back(LayerType::Alert, awips::Phenomenon::Marine); | ||||
|       layers_.emplace_back(LayerType::Map, "Map Overlay"); | ||||
|       layers_.emplace_back(LayerType::Radar, std::monostate {}); | ||||
|       layers_.emplace_back(LayerType::Map, "Map Underlay"); | ||||
|       types::LayerType             type_; | ||||
|       LayerDescription             description_; | ||||
|       bool                         movable_; | ||||
|       std::array<bool, kMapCount_> displayed_ {true, true, true, true}; | ||||
|    }; | ||||
| 
 | ||||
|    typedef boost::container::devector<LayerInfo> LayerVector; | ||||
| 
 | ||||
|    explicit Impl(LayerModel* self) : self_ {self} | ||||
|    { | ||||
|       layers_.emplace_back( | ||||
|          types::LayerType::Information, types::Layer::MapOverlay, false); | ||||
|       layers_.emplace_back( | ||||
|          types::LayerType::Information, types::Layer::ColorTable, false); | ||||
|       layers_.emplace_back( | ||||
|          types::LayerType::Alert, awips::Phenomenon::Tornado, true); | ||||
|       layers_.emplace_back( | ||||
|          types::LayerType::Alert, awips::Phenomenon::SnowSquall, true); | ||||
|       layers_.emplace_back( | ||||
|          types::LayerType::Alert, awips::Phenomenon::SevereThunderstorm, true); | ||||
|       layers_.emplace_back( | ||||
|          types::LayerType::Alert, awips::Phenomenon::FlashFlood, true); | ||||
|       layers_.emplace_back( | ||||
|          types::LayerType::Alert, awips::Phenomenon::Marine, true); | ||||
|       layers_.emplace_back( | ||||
|          types::LayerType::Map, types::Layer::MapSymbology, false); | ||||
|       layers_.emplace_back(types::LayerType::Radar, std::monostate {}, true); | ||||
|       layers_.emplace_back( | ||||
|          types::LayerType::Map, types::Layer::MapUnderlay, false); | ||||
|    } | ||||
|    ~Impl() = default; | ||||
| 
 | ||||
|    void AddPlacefile(const std::string& name); | ||||
| 
 | ||||
|    LayerModel* self_; | ||||
| 
 | ||||
|    std::shared_ptr<manager::PlacefileManager> placefileManager_ { | ||||
|       manager::PlacefileManager::Instance()}; | ||||
| 
 | ||||
|  | @ -63,7 +82,7 @@ public: | |||
| }; | ||||
| 
 | ||||
| LayerModel::LayerModel(QObject* parent) : | ||||
|     QAbstractTableModel(parent), p(std::make_unique<Impl>()) | ||||
|     QAbstractTableModel(parent), p(std::make_unique<Impl>(this)) | ||||
| { | ||||
|    connect(p->placefileManager_.get(), | ||||
|            &manager::PlacefileManager::PlacefileEnabled, | ||||
|  | @ -101,13 +120,25 @@ Qt::ItemFlags LayerModel::flags(const QModelIndex& index) const | |||
| { | ||||
|    Qt::ItemFlags flags = QAbstractTableModel::flags(index); | ||||
| 
 | ||||
|    if (!index.isValid() || index.row() < 0 || | ||||
|        static_cast<std::size_t>(index.row()) >= p->layers_.size()) | ||||
|    { | ||||
|       return flags; | ||||
|    } | ||||
| 
 | ||||
|    const auto& layer = p->layers_.at(index.row()); | ||||
| 
 | ||||
|    switch (index.column()) | ||||
|    { | ||||
|    case static_cast<int>(Column::DisplayMap1): | ||||
|    case static_cast<int>(Column::DisplayMap2): | ||||
|    case static_cast<int>(Column::DisplayMap3): | ||||
|    case static_cast<int>(Column::DisplayMap4): | ||||
|       flags |= Qt::ItemFlag::ItemIsUserCheckable | Qt::ItemFlag::ItemIsEditable; | ||||
|       if (layer.type_ != types::LayerType::Map) | ||||
|       { | ||||
|          flags |= | ||||
|             Qt::ItemFlag::ItemIsUserCheckable | Qt::ItemFlag::ItemIsEditable; | ||||
|       } | ||||
|       break; | ||||
| 
 | ||||
|    default: | ||||
|  | @ -132,7 +163,6 @@ QVariant LayerModel::data(const QModelIndex& index, int role) const | |||
|    } | ||||
| 
 | ||||
|    const auto& layer = p->layers_.at(index.row()); | ||||
|    bool        enabled = true; // TODO
 | ||||
| 
 | ||||
|    switch (index.column()) | ||||
|    { | ||||
|  | @ -147,23 +177,29 @@ QVariant LayerModel::data(const QModelIndex& index, int role) const | |||
|    case static_cast<int>(Column::DisplayMap2): | ||||
|    case static_cast<int>(Column::DisplayMap3): | ||||
|    case static_cast<int>(Column::DisplayMap4): | ||||
|       // TODO
 | ||||
|       if (layer.type_ != types::LayerType::Map) | ||||
|       { | ||||
|          bool displayed = | ||||
|             layer.displayed_[index.column() - | ||||
|                              static_cast<int>(Column::DisplayMap1)]; | ||||
| 
 | ||||
|          if (role == Qt::ItemDataRole::ToolTipRole) | ||||
|          { | ||||
|          return enabled ? displayedString : hiddenString; | ||||
|             return displayed ? displayedString : hiddenString; | ||||
|          } | ||||
|          else if (role == Qt::ItemDataRole::CheckStateRole) | ||||
|          { | ||||
|          return static_cast<int>(enabled ? Qt::CheckState::Checked : | ||||
|             return static_cast<int>(displayed ? Qt::CheckState::Checked : | ||||
|                                                 Qt::CheckState::Unchecked); | ||||
|          } | ||||
|       } | ||||
|       break; | ||||
| 
 | ||||
|    case static_cast<int>(Column::Type): | ||||
|       if (role == Qt::ItemDataRole::DisplayRole || | ||||
|           role == Qt::ItemDataRole::ToolTipRole) | ||||
|       { | ||||
|          return QString::fromStdString(layerTypeNames_.at(layer.first)); | ||||
|          return QString::fromStdString(types::GetLayerTypeName(layer.type_)); | ||||
|       } | ||||
|       break; | ||||
| 
 | ||||
|  | @ -171,17 +207,13 @@ QVariant LayerModel::data(const QModelIndex& index, int role) const | |||
|       if (role == Qt::ItemDataRole::DisplayRole || | ||||
|           role == Qt::ItemDataRole::ToolTipRole) | ||||
|       { | ||||
|          if (layer.first == LayerType::Placefile) | ||||
|          if (layer.type_ == types::LayerType::Placefile) | ||||
|          { | ||||
|             return p->placefileManager_->placefile_enabled( | ||||
|                       std::get<std::string>(layer.second)) ? | ||||
|                       std::get<std::string>(layer.description_)) ? | ||||
|                       enabledString : | ||||
|                       disabledString; | ||||
|          } | ||||
|          else | ||||
|          { | ||||
|             return enabledString; | ||||
|          } | ||||
|       } | ||||
|       break; | ||||
| 
 | ||||
|  | @ -189,9 +221,10 @@ QVariant LayerModel::data(const QModelIndex& index, int role) const | |||
|       if (role == Qt::ItemDataRole::DisplayRole || | ||||
|           role == Qt::ItemDataRole::ToolTipRole) | ||||
|       { | ||||
|          if (layer.first == LayerType::Placefile) | ||||
|          if (layer.type_ == types::LayerType::Placefile) | ||||
|          { | ||||
|             std::string placefileName = std::get<std::string>(layer.second); | ||||
|             std::string placefileName = | ||||
|                std::get<std::string>(layer.description_); | ||||
|             std::string description = placefileName; | ||||
|             std::string title = | ||||
|                p->placefileManager_->placefile_title(placefileName); | ||||
|  | @ -204,15 +237,21 @@ QVariant LayerModel::data(const QModelIndex& index, int role) const | |||
|          } | ||||
|          else | ||||
|          { | ||||
|             if (std::holds_alternative<std::string>(layer.second)) | ||||
|             if (std::holds_alternative<std::string>(layer.description_)) | ||||
|             { | ||||
|                return QString::fromStdString( | ||||
|                   std::get<std::string>(layer.second)); | ||||
|                   std::get<std::string>(layer.description_)); | ||||
|             } | ||||
|             else if (std::holds_alternative<awips::Phenomenon>(layer.second)) | ||||
|             else if (std::holds_alternative<types::Layer>(layer.description_)) | ||||
|             { | ||||
|                return QString::fromStdString(types::GetLayerName( | ||||
|                   std::get<types::Layer>(layer.description_))); | ||||
|             } | ||||
|             else if (std::holds_alternative<awips::Phenomenon>( | ||||
|                         layer.description_)) | ||||
|             { | ||||
|                return QString::fromStdString(awips::GetPhenomenonText( | ||||
|                   std::get<awips::Phenomenon>(layer.second))); | ||||
|                   std::get<awips::Phenomenon>(layer.description_))); | ||||
|             } | ||||
|          } | ||||
|       } | ||||
|  | @ -321,7 +360,7 @@ bool LayerModel::setData(const QModelIndex& index, | |||
|       return false; | ||||
|    } | ||||
| 
 | ||||
|    const auto& layer  = p->layers_.at(index.row()); | ||||
|    auto& layer  = p->layers_.at(index.row()); | ||||
|    bool  result = false; | ||||
| 
 | ||||
|    switch (index.column()) | ||||
|  | @ -332,9 +371,10 @@ bool LayerModel::setData(const QModelIndex& index, | |||
|    case static_cast<int>(Column::DisplayMap4): | ||||
|       if (role == Qt::ItemDataRole::CheckStateRole) | ||||
|       { | ||||
|          // TODO
 | ||||
|          Q_UNUSED(layer); | ||||
|          Q_UNUSED(value); | ||||
|          layer.displayed_[index.column() - | ||||
|                           static_cast<int>(Column::DisplayMap1)] = | ||||
|             value.toBool(); | ||||
|          result = true; | ||||
|       } | ||||
|       break; | ||||
| 
 | ||||
|  | @ -352,12 +392,13 @@ bool LayerModel::setData(const QModelIndex& index, | |||
| 
 | ||||
| void LayerModel::HandlePlacefileRemoved(const std::string& name) | ||||
| { | ||||
|    auto it = std::find_if(p->layers_.begin(), | ||||
|    auto it = | ||||
|       std::find_if(p->layers_.begin(), | ||||
|                    p->layers_.end(), | ||||
|                    [&name](const auto& layer) | ||||
|                    { | ||||
|                              return layer.first == LayerType::Placefile && | ||||
|                                     std::get<std::string>(layer.second) == name; | ||||
|                       return layer.type_ == types::LayerType::Placefile && | ||||
|                              std::get<std::string>(layer.description_) == name; | ||||
|                    }); | ||||
| 
 | ||||
|    if (it != p->layers_.end()) | ||||
|  | @ -374,13 +415,13 @@ void LayerModel::HandlePlacefileRemoved(const std::string& name) | |||
| void LayerModel::HandlePlacefileRenamed(const std::string& oldName, | ||||
|                                         const std::string& newName) | ||||
| { | ||||
|    auto it = | ||||
|       std::find_if(p->layers_.begin(), | ||||
|    auto it = std::find_if( | ||||
|       p->layers_.begin(), | ||||
|       p->layers_.end(), | ||||
|       [&oldName](const auto& layer) | ||||
|       { | ||||
|                       return layer.first == LayerType::Placefile && | ||||
|                              std::get<std::string>(layer.second) == oldName; | ||||
|          return layer.type_ == types::LayerType::Placefile && | ||||
|                 std::get<std::string>(layer.description_) == oldName; | ||||
|       }); | ||||
| 
 | ||||
|    if (it != p->layers_.end()) | ||||
|  | @ -391,27 +432,26 @@ void LayerModel::HandlePlacefileRenamed(const std::string& oldName, | |||
|       QModelIndex bottomRight = createIndex(row, kLastColumn); | ||||
| 
 | ||||
|       // Rename placefile
 | ||||
|       it->second = newName; | ||||
|       it->description_ = newName; | ||||
| 
 | ||||
|       Q_EMIT dataChanged(topLeft, bottomRight); | ||||
|    } | ||||
|    else | ||||
|    { | ||||
|       // Placefile is new, prepend row
 | ||||
|       beginInsertRows(QModelIndex(), 0, 0); | ||||
|       p->layers_.push_front({LayerType::Placefile, newName}); | ||||
|       endInsertRows(); | ||||
|       // Placefile doesn't exist, add row
 | ||||
|       p->AddPlacefile(newName); | ||||
|    } | ||||
| } | ||||
| 
 | ||||
| void LayerModel::HandlePlacefileUpdate(const std::string& name) | ||||
| { | ||||
|    auto it = std::find_if(p->layers_.begin(), | ||||
|    auto it = | ||||
|       std::find_if(p->layers_.begin(), | ||||
|                    p->layers_.end(), | ||||
|                    [&name](const auto& layer) | ||||
|                    { | ||||
|                              return layer.first == LayerType::Placefile && | ||||
|                                     std::get<std::string>(layer.second) == name; | ||||
|                       return layer.type_ == types::LayerType::Placefile && | ||||
|                              std::get<std::string>(layer.description_) == name; | ||||
|                    }); | ||||
| 
 | ||||
|    if (it != p->layers_.end()) | ||||
|  | @ -425,13 +465,34 @@ void LayerModel::HandlePlacefileUpdate(const std::string& name) | |||
|    } | ||||
|    else | ||||
|    { | ||||
|       // Placefile is new, prepend row
 | ||||
|       beginInsertRows(QModelIndex(), 0, 0); | ||||
|       p->layers_.push_front({LayerType::Placefile, name}); | ||||
|       endInsertRows(); | ||||
|       // Placefile doesn't exist, add row
 | ||||
|       p->AddPlacefile(name); | ||||
|    } | ||||
| } | ||||
| 
 | ||||
| void LayerModel::Impl::AddPlacefile(const std::string& name) | ||||
| { | ||||
|    // Insert after color table
 | ||||
|    auto insertPosition = std::find_if( | ||||
|       layers_.begin(), | ||||
|       layers_.end(), | ||||
|       [](const Impl::LayerInfo& layerInfo) | ||||
|       { | ||||
|          return std::holds_alternative<types::Layer>(layerInfo.description_) && | ||||
|                 std::get<types::Layer>(layerInfo.description_) == | ||||
|                    types::Layer::ColorTable; | ||||
|       }); | ||||
|    if (insertPosition != layers_.end()) | ||||
|    { | ||||
|       ++insertPosition; | ||||
|    } | ||||
| 
 | ||||
|    // Placefile is new, add row
 | ||||
|    self_->beginInsertRows(QModelIndex(), 0, 0); | ||||
|    layers_.insert(insertPosition, {types::LayerType::Placefile, name}); | ||||
|    self_->endInsertRows(); | ||||
| } | ||||
| 
 | ||||
| } // namespace model
 | ||||
| } // namespace qt
 | ||||
| } // namespace scwx
 | ||||
|  |  | |||
|  | @ -17,6 +17,8 @@ namespace model | |||
| 
 | ||||
| class LayerModel : public QAbstractTableModel | ||||
| { | ||||
|    Q_DISABLE_COPY_MOVE(LayerModel) | ||||
| 
 | ||||
| public: | ||||
|    enum class Column : int | ||||
|    { | ||||
|  | @ -32,14 +34,6 @@ public: | |||
|    typedef scwx::util::Iterator<Column, Column::Order, Column::Description> | ||||
|       ColumnIterator; | ||||
| 
 | ||||
|    enum class LayerType | ||||
|    { | ||||
|       Map, | ||||
|       Radar, | ||||
|       Alert, | ||||
|       Placefile | ||||
|    }; | ||||
| 
 | ||||
|    explicit LayerModel(QObject* parent = nullptr); | ||||
|    ~LayerModel(); | ||||
| 
 | ||||
|  |  | |||
|  | @ -9,9 +9,32 @@ namespace qt | |||
| namespace types | ||||
| { | ||||
| 
 | ||||
| static const std::unordered_map<types::LayerType, std::string> layerTypeName_ { | ||||
|    {types::LayerType::Map, "Map"}, | ||||
|    {types::LayerType::Radar, "Radar"}, | ||||
|    {types::LayerType::Alert, "Alert"}, | ||||
|    {types::LayerType::Placefile, "Placefile"}, | ||||
|    {types::LayerType::Information, "Information"}}; | ||||
| 
 | ||||
| static const std::unordered_map<types::Layer, std::string> layerName_ { | ||||
|    {types::Layer::MapOverlay, "Map Overlay"}, | ||||
|    {types::Layer::ColorTable, "Color Table"}, | ||||
|    {types::Layer::MapSymbology, "Map Symbology"}, | ||||
|    {types::Layer::MapUnderlay, "Map Underlay"}}; | ||||
| 
 | ||||
| static const std::unordered_map<MapTime, std::string> mapTimeName_ { | ||||
|    {MapTime::Live, "Live"}, {MapTime::Archive, "Archive"}}; | ||||
| 
 | ||||
| std::string GetLayerTypeName(LayerType layerType) | ||||
| { | ||||
|    return layerTypeName_.at(layerType); | ||||
| } | ||||
| 
 | ||||
| std::string GetLayerName(Layer layer) | ||||
| { | ||||
|    return layerName_.at(layer); | ||||
| } | ||||
| 
 | ||||
| std::string GetMapTimeName(MapTime mapTime) | ||||
| { | ||||
|    return mapTimeName_.at(mapTime); | ||||
|  |  | |||
|  | @ -9,6 +9,23 @@ namespace qt | |||
| namespace types | ||||
| { | ||||
| 
 | ||||
| enum class LayerType | ||||
| { | ||||
|    Map, | ||||
|    Radar, | ||||
|    Alert, | ||||
|    Placefile, | ||||
|    Information | ||||
| }; | ||||
| 
 | ||||
| enum class Layer | ||||
| { | ||||
|    MapOverlay, | ||||
|    ColorTable, | ||||
|    MapSymbology, | ||||
|    MapUnderlay | ||||
| }; | ||||
| 
 | ||||
| enum class AnimationState | ||||
| { | ||||
|    Play, | ||||
|  | @ -29,6 +46,8 @@ enum class NoUpdateReason | |||
|    InvalidData | ||||
| }; | ||||
| 
 | ||||
| std::string GetLayerTypeName(LayerType layerType); | ||||
| std::string GetLayerName(Layer layer); | ||||
| std::string GetMapTimeName(MapTime mapTime); | ||||
| 
 | ||||
| } // namespace types
 | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Dan Paulat
						Dan Paulat