From aa0c9fb4cbeaba895479dc8c9bb2f188f6e5856e Mon Sep 17 00:00:00 2001 From: Sam Hellawell Date: Sat, 16 Mar 2024 07:45:52 +0000 Subject: [PATCH 1/3] Fix: cannot drag region into map, map columns are rectangular --- apps/opencs/view/world/regionmap.cpp | 18 +++++++++++++++++- apps/opencs/view/world/regionmap.hpp | 2 ++ 2 files changed, 19 insertions(+), 1 deletion(-) diff --git a/apps/opencs/view/world/regionmap.cpp b/apps/opencs/view/world/regionmap.cpp index a2847848d0..5c3aa11c8e 100644 --- a/apps/opencs/view/world/regionmap.cpp +++ b/apps/opencs/view/world/regionmap.cpp @@ -224,6 +224,10 @@ CSVWorld::RegionMap::RegionMap(const CSMWorld::UniversalId& universalId, CSMDoc: addAction(mViewInTableAction); setAcceptDrops(true); + + // Make columns square incase QSizeHint doesnt apply + for (int column = 0; column < this->model()->columnCount(); ++column) + this->setColumnWidth(column, this->rowHeight(0)); } void CSVWorld::RegionMap::selectAll() @@ -358,12 +362,24 @@ std::vector CSVWorld::RegionMap::getDraggedRecords() cons return ids; } +void CSVWorld::RegionMap::dragMoveEvent(QDragMoveEvent* event) +{ + QModelIndex index = indexAt(event->pos()); + const CSMWorld::TableMimeData* mime = dynamic_cast(event->mimeData()); + if (mime != nullptr && (mime->holdsType(CSMWorld::UniversalId::Type_Region))) + { + event->accept(); + return; + } + + event->ignore(); +} + void CSVWorld::RegionMap::dropEvent(QDropEvent* event) { QModelIndex index = indexAt(event->pos()); bool exists = QTableView::model()->data(index, Qt::BackgroundRole) != QBrush(Qt::DiagCrossPattern); - if (!index.isValid() || !exists) { return; diff --git a/apps/opencs/view/world/regionmap.hpp b/apps/opencs/view/world/regionmap.hpp index b6c5078ea3..137b47ed83 100644 --- a/apps/opencs/view/world/regionmap.hpp +++ b/apps/opencs/view/world/regionmap.hpp @@ -59,6 +59,8 @@ namespace CSVWorld void mouseMoveEvent(QMouseEvent* event) override; + void dragMoveEvent(QDragMoveEvent* event) override; + void dropEvent(QDropEvent* event) override; public: From 5fca45565c2822a109240fa1fb3bae0f90ec6741 Mon Sep 17 00:00:00 2001 From: Sam Hellawell Date: Sat, 16 Mar 2024 07:46:21 +0000 Subject: [PATCH 2/3] Feature: display different brush for land vs water --- apps/opencs/model/world/regionmap.cpp | 33 +++++++++++++++++++++------ apps/opencs/model/world/regionmap.hpp | 3 ++- 2 files changed, 28 insertions(+), 8 deletions(-) diff --git a/apps/opencs/model/world/regionmap.cpp b/apps/opencs/model/world/regionmap.cpp index 5c22aedf4d..c27846a890 100644 --- a/apps/opencs/model/world/regionmap.cpp +++ b/apps/opencs/model/world/regionmap.cpp @@ -1,7 +1,9 @@ #include "regionmap.hpp" +#include #include #include +#include #include #include @@ -21,20 +23,36 @@ #include "data.hpp" #include "universalid.hpp" +namespace CSMWorld +{ + float getLandHeight(const CSMWorld::Cell& cell, CSMWorld::Data& data) + { + const IdCollection& lands = data.getLand(); + int landIndex = lands.searchId(cell.mId); + const Land& land = lands.getRecord(landIndex).get(); + + // If any part of land is above water, returns > 0 - otherwise returns < 0 + if (land.getLandData()) + return land.getLandData()->mMaxHeight - cell.mWater; + + return 0.0f; + } +} + CSMWorld::RegionMap::CellDescription::CellDescription() : mDeleted(false) { } -CSMWorld::RegionMap::CellDescription::CellDescription(const Record& cell) +CSMWorld::RegionMap::CellDescription::CellDescription(const Record& cell, float landHeight) { const Cell& cell2 = cell.get(); if (!cell2.isExterior()) throw std::logic_error("Interior cell in region map"); + mMaxLandHeight = landHeight; mDeleted = cell.isDeleted(); - mRegion = cell2.mRegion; mName = cell2.mName; } @@ -92,7 +110,7 @@ void CSMWorld::RegionMap::buildMap() if (cell2.isExterior()) { - CellDescription description(cell); + CellDescription description(cell, getLandHeight(cell2, mData)); CellCoordinates index = getIndex(cell2); @@ -140,7 +158,7 @@ void CSMWorld::RegionMap::addCells(int start, int end) { CellCoordinates index = getIndex(cell2); - CellDescription description(cell); + CellDescription description(cell, getLandHeight(cell.get(), mData)); addCell(index, description); } @@ -335,10 +353,11 @@ QVariant CSMWorld::RegionMap::data(const QModelIndex& index, int role) const auto iter = mColours.find(cell->second.mRegion); if (iter != mColours.end()) - return QBrush(QColor(iter->second & 0xff, (iter->second >> 8) & 0xff, (iter->second >> 16) & 0xff)); + return QBrush(QColor(iter->second & 0xff, (iter->second >> 8) & 0xff, (iter->second >> 16) & 0xff), + cell->second.mMaxLandHeight > 0 ? Qt::SolidPattern : Qt::CrossPattern); - if (cell->second.mRegion.empty()) - return QBrush(Qt::Dense6Pattern); // no region + if (cell->second.mRegion.empty()) // no region + return QBrush(cell->second.mMaxLandHeight > 0 ? Qt::Dense3Pattern : Qt::Dense6Pattern); return QBrush(Qt::red, Qt::Dense6Pattern); // invalid region } diff --git a/apps/opencs/model/world/regionmap.hpp b/apps/opencs/model/world/regionmap.hpp index 3f62c7b61d..e5a4d61337 100644 --- a/apps/opencs/model/world/regionmap.hpp +++ b/apps/opencs/model/world/regionmap.hpp @@ -40,13 +40,14 @@ namespace CSMWorld private: struct CellDescription { + float mMaxLandHeight; bool mDeleted; ESM::RefId mRegion; std::string mName; CellDescription(); - CellDescription(const Record& cell); + CellDescription(const Record& cell, float landHeight); }; Data& mData; From a62da201e5516ba677ade73214bb3b161ddd4a05 Mon Sep 17 00:00:00 2001 From: Sam Hellawell Date: Sat, 16 Mar 2024 09:02:47 +0000 Subject: [PATCH 3/3] check for land index not -1, fix warning Signed-off-by: Sam Hellawell --- apps/opencs/model/world/regionmap.cpp | 4 +++- apps/opencs/view/world/regionmap.cpp | 1 - 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/apps/opencs/model/world/regionmap.cpp b/apps/opencs/model/world/regionmap.cpp index c27846a890..f555f0ea32 100644 --- a/apps/opencs/model/world/regionmap.cpp +++ b/apps/opencs/model/world/regionmap.cpp @@ -29,9 +29,11 @@ namespace CSMWorld { const IdCollection& lands = data.getLand(); int landIndex = lands.searchId(cell.mId); - const Land& land = lands.getRecord(landIndex).get(); + if (landIndex == -1) + return 0.0f; // If any part of land is above water, returns > 0 - otherwise returns < 0 + const Land& land = lands.getRecord(landIndex).get(); if (land.getLandData()) return land.getLandData()->mMaxHeight - cell.mWater; diff --git a/apps/opencs/view/world/regionmap.cpp b/apps/opencs/view/world/regionmap.cpp index 5c3aa11c8e..17d0016afc 100644 --- a/apps/opencs/view/world/regionmap.cpp +++ b/apps/opencs/view/world/regionmap.cpp @@ -364,7 +364,6 @@ std::vector CSVWorld::RegionMap::getDraggedRecords() cons void CSVWorld::RegionMap::dragMoveEvent(QDragMoveEvent* event) { - QModelIndex index = indexAt(event->pos()); const CSMWorld::TableMimeData* mime = dynamic_cast(event->mimeData()); if (mime != nullptr && (mime->holdsType(CSMWorld::UniversalId::Type_Region))) {