Additional layer model work, including alert, radar and map layers

This commit is contained in:
Dan Paulat 2023-10-12 21:43:53 -05:00
parent f0822205a4
commit d82a1cc171
4 changed files with 167 additions and 74 deletions

View file

@ -10,6 +10,7 @@
#include <QFontMetrics> #include <QFontMetrics>
#include <QStyle> #include <QStyle>
#include <QStyleOption> #include <QStyleOption>
#include <boost/container/devector.hpp>
namespace scwx namespace scwx
{ {
@ -32,21 +33,37 @@ static const std::unordered_map<LayerModel::LayerType, std::string>
{LayerModel::LayerType::Alert, "Alert"}, {LayerModel::LayerType::Alert, "Alert"},
{LayerModel::LayerType::Placefile, "Placefile"}}; {LayerModel::LayerType::Placefile, "Placefile"}};
class LayerModelImpl typedef std::variant<std::monostate, std::string, awips::Phenomenon>
LayerDescription;
typedef boost::container::devector<
std::pair<LayerModel::LayerType, LayerDescription>>
LayerVector;
class LayerModel::Impl
{ {
public: public:
explicit LayerModelImpl() {} explicit Impl()
~LayerModelImpl() = default; {
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");
}
~Impl() = default;
std::shared_ptr<manager::PlacefileManager> placefileManager_ { std::shared_ptr<manager::PlacefileManager> placefileManager_ {
manager::PlacefileManager::Instance()}; manager::PlacefileManager::Instance()};
std::vector<std::pair<LayerModel::LayerType, std::variant<std::string>>> LayerVector layers_ {};
layers_ {};
}; };
LayerModel::LayerModel(QObject* parent) : LayerModel::LayerModel(QObject* parent) :
QAbstractTableModel(parent), p(std::make_unique<LayerModelImpl>()) QAbstractTableModel(parent), p(std::make_unique<Impl>())
{ {
connect(p->placefileManager_.get(), connect(p->placefileManager_.get(),
&manager::PlacefileManager::PlacefileEnabled, &manager::PlacefileManager::PlacefileEnabled,
@ -86,10 +103,10 @@ Qt::ItemFlags LayerModel::flags(const QModelIndex& index) const
switch (index.column()) switch (index.column())
{ {
case static_cast<int>(Column::EnabledMap1): case static_cast<int>(Column::DisplayMap1):
case static_cast<int>(Column::EnabledMap2): case static_cast<int>(Column::DisplayMap2):
case static_cast<int>(Column::EnabledMap3): case static_cast<int>(Column::DisplayMap3):
case static_cast<int>(Column::EnabledMap4): case static_cast<int>(Column::DisplayMap4):
flags |= Qt::ItemFlag::ItemIsUserCheckable | Qt::ItemFlag::ItemIsEditable; flags |= Qt::ItemFlag::ItemIsUserCheckable | Qt::ItemFlag::ItemIsEditable;
break; break;
@ -105,6 +122,9 @@ QVariant LayerModel::data(const QModelIndex& index, int role) const
static const QString enabledString = QObject::tr("Enabled"); static const QString enabledString = QObject::tr("Enabled");
static const QString disabledString = QObject::tr("Disabled"); static const QString disabledString = QObject::tr("Disabled");
static const QString displayedString = QObject::tr("Displayed");
static const QString hiddenString = QObject::tr("Hidden");
if (!index.isValid() || index.row() < 0 || if (!index.isValid() || index.row() < 0 ||
static_cast<std::size_t>(index.row()) >= p->layers_.size()) static_cast<std::size_t>(index.row()) >= p->layers_.size())
{ {
@ -119,18 +139,18 @@ QVariant LayerModel::data(const QModelIndex& index, int role) const
case static_cast<int>(Column::Order): case static_cast<int>(Column::Order):
if (role == Qt::ItemDataRole::DisplayRole) if (role == Qt::ItemDataRole::DisplayRole)
{ {
return index.row(); return index.row() + 1;
} }
break; break;
case static_cast<int>(Column::EnabledMap1): case static_cast<int>(Column::DisplayMap1):
case static_cast<int>(Column::EnabledMap2): case static_cast<int>(Column::DisplayMap2):
case static_cast<int>(Column::EnabledMap3): case static_cast<int>(Column::DisplayMap3):
case static_cast<int>(Column::EnabledMap4): case static_cast<int>(Column::DisplayMap4):
// TODO // TODO
if (role == Qt::ItemDataRole::ToolTipRole) if (role == Qt::ItemDataRole::ToolTipRole)
{ {
return enabled ? enabledString : disabledString; return enabled ? displayedString : hiddenString;
} }
else if (role == Qt::ItemDataRole::CheckStateRole) else if (role == Qt::ItemDataRole::CheckStateRole)
{ {
@ -147,6 +167,24 @@ QVariant LayerModel::data(const QModelIndex& index, int role) const
} }
break; break;
case static_cast<int>(Column::Enabled):
if (role == Qt::ItemDataRole::DisplayRole ||
role == Qt::ItemDataRole::ToolTipRole)
{
if (layer.first == LayerType::Placefile)
{
return p->placefileManager_->placefile_enabled(
std::get<std::string>(layer.second)) ?
enabledString :
disabledString;
}
else
{
return enabledString;
}
}
break;
case static_cast<int>(Column::Description): case static_cast<int>(Column::Description):
if (role == Qt::ItemDataRole::DisplayRole || if (role == Qt::ItemDataRole::DisplayRole ||
role == Qt::ItemDataRole::ToolTipRole) role == Qt::ItemDataRole::ToolTipRole)
@ -171,6 +209,11 @@ QVariant LayerModel::data(const QModelIndex& index, int role) const
return QString::fromStdString( return QString::fromStdString(
std::get<std::string>(layer.second)); std::get<std::string>(layer.second));
} }
else if (std::holds_alternative<awips::Phenomenon>(layer.second))
{
return QString::fromStdString(awips::GetPhenomenonText(
std::get<awips::Phenomenon>(layer.second)));
}
} }
} }
break; break;
@ -191,21 +234,24 @@ LayerModel::headerData(int section, Qt::Orientation orientation, int role) const
{ {
switch (section) switch (section)
{ {
case static_cast<int>(Column::EnabledMap1): case static_cast<int>(Column::DisplayMap1):
return tr("1"); return tr("1");
case static_cast<int>(Column::EnabledMap2): case static_cast<int>(Column::DisplayMap2):
return tr("2"); return tr("2");
case static_cast<int>(Column::EnabledMap3): case static_cast<int>(Column::DisplayMap3):
return tr("3"); return tr("3");
case static_cast<int>(Column::EnabledMap4): case static_cast<int>(Column::DisplayMap4):
return tr("4"); return tr("4");
case static_cast<int>(Column::Type): case static_cast<int>(Column::Type):
return tr("Type"); return tr("Type");
case static_cast<int>(Column::Enabled):
return tr("Enabled");
case static_cast<int>(Column::Description): case static_cast<int>(Column::Description):
return tr("Description"); return tr("Description");
@ -221,17 +267,17 @@ LayerModel::headerData(int section, Qt::Orientation orientation, int role) const
case static_cast<int>(Column::Order): case static_cast<int>(Column::Order):
return tr("Order"); return tr("Order");
case static_cast<int>(Column::EnabledMap1): case static_cast<int>(Column::DisplayMap1):
return tr("Enabled on Map 1"); return tr("Display on Map 1");
case static_cast<int>(Column::EnabledMap2): case static_cast<int>(Column::DisplayMap2):
return tr("Enabled on Map 2"); return tr("Display on Map 2");
case static_cast<int>(Column::EnabledMap3): case static_cast<int>(Column::DisplayMap3):
return tr("Enabled on Map 3"); return tr("Display on Map 3");
case static_cast<int>(Column::EnabledMap4): case static_cast<int>(Column::DisplayMap4):
return tr("Enabled on Map 4"); return tr("Display on Map 4");
default: default:
break; break;
@ -241,10 +287,10 @@ LayerModel::headerData(int section, Qt::Orientation orientation, int role) const
{ {
switch (section) switch (section)
{ {
case static_cast<int>(Column::EnabledMap1): case static_cast<int>(Column::DisplayMap1):
case static_cast<int>(Column::EnabledMap2): case static_cast<int>(Column::DisplayMap2):
case static_cast<int>(Column::EnabledMap3): case static_cast<int>(Column::DisplayMap3):
case static_cast<int>(Column::EnabledMap4): case static_cast<int>(Column::DisplayMap4):
{ {
static const QCheckBox checkBox {}; static const QCheckBox checkBox {};
QStyleOptionButton option {}; QStyleOptionButton option {};
@ -280,10 +326,10 @@ bool LayerModel::setData(const QModelIndex& index,
switch (index.column()) switch (index.column())
{ {
case static_cast<int>(Column::EnabledMap1): case static_cast<int>(Column::DisplayMap1):
case static_cast<int>(Column::EnabledMap2): case static_cast<int>(Column::DisplayMap2):
case static_cast<int>(Column::EnabledMap3): case static_cast<int>(Column::DisplayMap3):
case static_cast<int>(Column::EnabledMap4): case static_cast<int>(Column::DisplayMap4):
if (role == Qt::ItemDataRole::CheckStateRole) if (role == Qt::ItemDataRole::CheckStateRole)
{ {
// TODO // TODO
@ -351,10 +397,9 @@ void LayerModel::HandlePlacefileRenamed(const std::string& oldName,
} }
else else
{ {
// Placefile is new, append row // Placefile is new, prepend row
const int newIndex = static_cast<int>(p->layers_.size()); beginInsertRows(QModelIndex(), 0, 0);
beginInsertRows(QModelIndex(), newIndex, newIndex); p->layers_.push_front({LayerType::Placefile, newName});
p->layers_.push_back({LayerType::Placefile, newName});
endInsertRows(); endInsertRows();
} }
} }
@ -380,10 +425,9 @@ void LayerModel::HandlePlacefileUpdate(const std::string& name)
} }
else else
{ {
// Placefile is new, append row // Placefile is new, prepend row
const int newIndex = static_cast<int>(p->layers_.size()); beginInsertRows(QModelIndex(), 0, 0);
beginInsertRows(QModelIndex(), newIndex, newIndex); p->layers_.push_front({LayerType::Placefile, name});
p->layers_.push_back({LayerType::Placefile, name});
endInsertRows(); endInsertRows();
} }
} }

View file

@ -2,6 +2,7 @@
#include <scwx/qt/types/text_event_key.hpp> #include <scwx/qt/types/text_event_key.hpp>
#include <scwx/common/geographic.hpp> #include <scwx/common/geographic.hpp>
#include <scwx/util/iterator.hpp>
#include <memory> #include <memory>
@ -14,21 +15,22 @@ namespace qt
namespace model namespace model
{ {
class LayerModelImpl;
class LayerModel : public QAbstractTableModel class LayerModel : public QAbstractTableModel
{ {
public: public:
enum class Column : int enum class Column : int
{ {
Order = 0, Order = 0,
EnabledMap1 = 1, DisplayMap1 = 1,
EnabledMap2 = 2, DisplayMap2 = 2,
EnabledMap3 = 3, DisplayMap3 = 3,
EnabledMap4 = 4, DisplayMap4 = 4,
Type = 5, Type = 5,
Description = 6 Enabled = 6,
Description = 7
}; };
typedef scwx::util::Iterator<Column, Column::Order, Column::Description>
ColumnIterator;
enum class LayerType enum class LayerType
{ {
@ -63,8 +65,8 @@ public slots:
void HandlePlacefileUpdate(const std::string& name); void HandlePlacefileUpdate(const std::string& name);
private: private:
friend class LayerModelImpl; class Impl;
std::unique_ptr<LayerModelImpl> p; std::unique_ptr<Impl> p;
}; };
} // namespace model } // namespace model

View file

@ -39,19 +39,16 @@ LayerDialog::LayerDialog(QWidget* parent) :
layerViewHeader->setMinimumSectionSize(10); layerViewHeader->setMinimumSectionSize(10);
// Enabled columns have a fixed size (checkbox) // Give small columns a fixed size
for (auto column : model::LayerModel::ColumnIterator())
{
if (column != model::LayerModel::Column::Description)
{
layerViewHeader->setSectionResizeMode( layerViewHeader->setSectionResizeMode(
static_cast<int>(model::LayerModel::Column::EnabledMap1), static_cast<int>(column),
QHeaderView::ResizeMode::ResizeToContents);
layerViewHeader->setSectionResizeMode(
static_cast<int>(model::LayerModel::Column::EnabledMap2),
QHeaderView::ResizeMode::ResizeToContents);
layerViewHeader->setSectionResizeMode(
static_cast<int>(model::LayerModel::Column::EnabledMap3),
QHeaderView::ResizeMode::ResizeToContents);
layerViewHeader->setSectionResizeMode(
static_cast<int>(model::LayerModel::Column::EnabledMap4),
QHeaderView::ResizeMode::ResizeToContents); QHeaderView::ResizeMode::ResizeToContents);
}
}
} }
LayerDialog::~LayerDialog() LayerDialog::~LayerDialog()

View file

@ -6,8 +6,8 @@
<rect> <rect>
<x>0</x> <x>0</x>
<y>0</y> <y>0</y>
<width>400</width> <width>700</width>
<height>300</height> <height>600</height>
</rect> </rect>
</property> </property>
<property name="windowTitle"> <property name="windowTitle">
@ -43,6 +43,9 @@
<property name="selectionMode"> <property name="selectionMode">
<enum>QAbstractItemView::ContiguousSelection</enum> <enum>QAbstractItemView::ContiguousSelection</enum>
</property> </property>
<property name="indentation">
<number>0</number>
</property>
</widget> </widget>
</item> </item>
<item> <item>
@ -131,7 +134,7 @@
<property name="sizeHint" stdset="0"> <property name="sizeHint" stdset="0">
<size> <size>
<width>20</width> <width>20</width>
<height>60</height> <height>209</height>
</size> </size>
</property> </property>
</spacer> </spacer>
@ -142,6 +145,50 @@
</layout> </layout>
</widget> </widget>
</item> </item>
<item>
<widget class="QFrame" name="frame_3">
<property name="frameShape">
<enum>QFrame::StyledPanel</enum>
</property>
<property name="frameShadow">
<enum>QFrame::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>
<widget class="QLineEdit" name="lineEdit">
<property name="placeholderText">
<string>Filter</string>
</property>
<property name="clearButtonEnabled">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item> <item>
<widget class="QDialogButtonBox" name="buttonBox"> <widget class="QDialogButtonBox" name="buttonBox">
<property name="orientation"> <property name="orientation">
@ -154,6 +201,9 @@
</item> </item>
</layout> </layout>
</widget> </widget>
</item>
</layout>
</widget>
<resources> <resources>
<include location="../../../../scwx-qt.qrc"/> <include location="../../../../scwx-qt.qrc"/>
</resources> </resources>