From 6159724b04e72809ca55c350d21251716cb37ab8 Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Mon, 8 Jul 2013 16:53:08 +0200 Subject: [PATCH] build region map from records (only initial build; updates not implemented yet) --- apps/opencs/model/world/data.cpp | 15 ++- apps/opencs/model/world/regionmap.cpp | 127 ++++++++++++++++++++++++-- apps/opencs/model/world/regionmap.hpp | 24 ++++- 3 files changed, 154 insertions(+), 12 deletions(-) diff --git a/apps/opencs/model/world/data.cpp b/apps/opencs/model/world/data.cpp index 4a38604b1..d54b3ac16 100644 --- a/apps/opencs/model/world/data.cpp +++ b/apps/opencs/model/world/data.cpp @@ -162,8 +162,6 @@ CSMWorld::Data::Data() : mRefs (mCells) addModel (new IdTable (&mReferenceables), UniversalId::Type_Referenceables, UniversalId::Type_Referenceable); addModel (new IdTable (&mRefs), UniversalId::Type_References, UniversalId::Type_Reference); - - addModel (new RegionMap, UniversalId::Type_RegionMap, UniversalId::Type_None); } CSMWorld::Data::~Data() @@ -307,7 +305,20 @@ QAbstractItemModel *CSMWorld::Data::getTableModel (const UniversalId& id) std::map::iterator iter = mModelIndex.find (id.getType()); if (iter==mModelIndex.end()) + { + // try creating missing (secondary) tables on the fly + // + // Note: We create these tables here so we don't have to deal with them during load/initial + // construction of the ESX data where no update signals are available. + if (id.getType()==UniversalId::Type_RegionMap) + { + RegionMap *table = 0; + addModel (table = new RegionMap (*this), UniversalId::Type_RegionMap, + UniversalId::Type_None); + return table; + } throw std::logic_error ("No table model available for " + id.toString()); + } return iter->second; } diff --git a/apps/opencs/model/world/regionmap.cpp b/apps/opencs/model/world/regionmap.cpp index 8fbed9c5a..01ec979d2 100644 --- a/apps/opencs/model/world/regionmap.cpp +++ b/apps/opencs/model/world/regionmap.cpp @@ -3,21 +3,95 @@ #include +#include "data.hpp" +#include "universalid.hpp" + std::pair CSMWorld::RegionMap::getIndex (const QModelIndex& index) const { return std::make_pair (index.column()+mMin.first, index.row()+mMin.second); } -CSMWorld::RegionMap::RegionMap() +void CSMWorld::RegionMap::buildRegions (Data& data) { - // setting up some placeholder regions - mMap.insert (std::make_pair (std::make_pair (0, 0), "a")); - mMap.insert (std::make_pair (std::make_pair (1, 1), "b")); - mMap.insert (std::make_pair (std::make_pair (1, 0), "a")); - mMin = std::make_pair (0, 0); - mMax = std::make_pair (2, 2); - mColours.insert (std::make_pair ("a", 0xff0000ff)); - mColours.insert (std::make_pair ("b", 0x00ff00ff)); + const IdCollection& regions = data.getRegions(); + + int size = regions.getSize(); + + for (int i=0; i& region = regions.getRecord (i); + + if (!region.isDeleted()) + mColours.insert (std::make_pair (region.get().mId, region.get().mMapColor)); + } +} + +void CSMWorld::RegionMap::buildMap (Data& data) +{ + const IdCollection& cells = data.getCells(); + + int size = cells.getSize(); + + mMin = mMax = std::make_pair (0, 0); + + for (int i=0; i& cell = cells.getRecord (i); + + if (!cell.isDeleted()) + { + const Cell& cell2 = cell.get(); + + if (cell2.isExterior()) + { + std::pair index (cell2.mData.mX, cell2.mData.mY); + + if (mMap.empty()) + { + mMin = index; + mMax = std::make_pair (mMin.first+1, mMin.second+1); + } + else + { + if (index.first=mMax.first) + mMax.first = index.first + 1; + + if (index.second=mMax.second) + mMax.second = index.second + 1; + } + + mMap.insert (std::make_pair (index, cell2.mRegion)); + } + } + } +} + +CSMWorld::RegionMap::RegionMap (Data& data) +{ + buildRegions (data); + buildMap (data); + + QAbstractItemModel *regions = data.getTableModel (UniversalId (UniversalId::Type_Regions)); + + connect (regions, SIGNAL (rowsAboutToBeRemoved (const QModelIndex&, int, int)), + this, SLOT (regionsAboutToBeRemoved (const QModelIndex&, int, int))); + connect (regions, SIGNAL (rowsInserted (const QModelIndex&, int, int)), + this, SLOT (regionsInserted (const QModelIndex&, int, int))); + connect (regions, SIGNAL (dataChanged (const QModelIndex&, const QModelIndex&)), + this, SLOT (regionsChanged (const QModelIndex&, const QModelIndex&))); + + QAbstractItemModel *cells = data.getTableModel (UniversalId (UniversalId::Type_Cells)); + + connect (cells, SIGNAL (rowsAboutToBeRemoved (const QModelIndex&, int, int)), + this, SLOT (regionsAboutToBeRemoved (const QModelIndex&, int, int))); + connect (cells, SIGNAL (rowsInserted (const QModelIndex&, int, int)), + this, SLOT (regionsInserted (const QModelIndex&, int, int))); + connect (cells, SIGNAL (dataChanged (const QModelIndex&, const QModelIndex&)), + this, SLOT (regionsChanged (const QModelIndex&, const QModelIndex&))); } int CSMWorld::RegionMap::rowCount (const QModelIndex& parent) const @@ -70,4 +144,39 @@ Qt::ItemFlags CSMWorld::RegionMap::flags (const QModelIndex& index) const return Qt::ItemIsSelectable | Qt::ItemIsEnabled; return 0; +} + +void CSMWorld::RegionMap::regionsAboutToBeRemoved (const QModelIndex& parent, int start, int end) +{ + + +} + +void CSMWorld::RegionMap::regionsInserted (const QModelIndex& parent, int start, int end) +{ + + +} + +void CSMWorld::RegionMap::regionsChanged (const QModelIndex& topLeft, const QModelIndex& bottomRight) +{ + + +} + +void CSMWorld::RegionMap::cellsAboutToBeRemoved (const QModelIndex& parent, int start, int end) +{ + + +} + +void CSMWorld::RegionMap::cellsInserted (const QModelIndex& parent, int start, int end) +{ + + +} + +void CSMWorld::RegionMap::cellsChanged (const QModelIndex& topLeft, const QModelIndex& bottomRight) +{ +; } \ No newline at end of file diff --git a/apps/opencs/model/world/regionmap.hpp b/apps/opencs/model/world/regionmap.hpp index 78792fad1..a61875c78 100644 --- a/apps/opencs/model/world/regionmap.hpp +++ b/apps/opencs/model/world/regionmap.hpp @@ -8,11 +8,15 @@ namespace CSMWorld { + class Data; + /// \brief Model for the region map /// /// This class does not holds any record data (other than for the purpose of buffering). class RegionMap : public QAbstractTableModel { + Q_OBJECT + std::map, std::string> mMap; ///< cell index, region std::pair mMin; ///< inclusive std::pair mMax; ///< exclusive @@ -21,9 +25,13 @@ namespace CSMWorld std::pair getIndex (const QModelIndex& index) const; ///< Translates a Qt model index into a cell index (which can contain negative components) + void buildRegions (Data& data); + + void buildMap (Data& data); + public: - RegionMap(); + RegionMap (Data& data); virtual int rowCount (const QModelIndex& parent = QModelIndex()) const; @@ -32,6 +40,20 @@ namespace CSMWorld virtual QVariant data (const QModelIndex& index, int role = Qt::DisplayRole) const; virtual Qt::ItemFlags flags (const QModelIndex& index) const; + + private slots: + + void regionsAboutToBeRemoved (const QModelIndex& parent, int start, int end); + + void regionsInserted (const QModelIndex& parent, int start, int end); + + void regionsChanged (const QModelIndex& topLeft, const QModelIndex& bottomRight); + + void cellsAboutToBeRemoved (const QModelIndex& parent, int start, int end); + + void cellsInserted (const QModelIndex& parent, int start, int end); + + void cellsChanged (const QModelIndex& topLeft, const QModelIndex& bottomRight); }; }