Nested table support for Pathgrids.
parent
bdf0d8db22
commit
05210d7f21
@ -0,0 +1,39 @@
|
||||
#ifndef CSM_WOLRD_IDADAPTER_H
|
||||
#define CSM_WOLRD_IDADAPTER_H
|
||||
|
||||
#include "record.hpp"
|
||||
|
||||
class QVariant;
|
||||
|
||||
namespace CSMWorld
|
||||
{
|
||||
class NestedTableWrapperBase;
|
||||
|
||||
template<typename ESXRecordT>
|
||||
class NestedIdAdapter
|
||||
{
|
||||
public:
|
||||
|
||||
NestedIdAdapter() {}
|
||||
|
||||
virtual ~NestedIdAdapter() {}
|
||||
|
||||
virtual void addNestedRow(Record<ESXRecordT>& record, int position) const = 0;
|
||||
|
||||
virtual void removeNestedRow(Record<ESXRecordT>& record, int rowToRemove) const = 0;
|
||||
|
||||
virtual void setNestedTable(Record<ESXRecordT>& record, const NestedTableWrapperBase& nestedTable) = 0;
|
||||
|
||||
virtual NestedTableWrapperBase* nestedTable(const Record<ESXRecordT>& record) const = 0;
|
||||
|
||||
virtual QVariant getNestedData(const Record<ESXRecordT>& record, int subRowIndex, int subColIndex) const = 0;
|
||||
|
||||
virtual void setNestedData(Record<ESXRecordT>& record, const QVariant& value, int subRowIndex, int subColIndex) const = 0;
|
||||
|
||||
virtual int getNestedColumnsCount(const Record<ESXRecordT>& record) const = 0;
|
||||
|
||||
virtual int getNestedRowsCount(const Record<ESXRecordT>& record) const = 0;
|
||||
};
|
||||
}
|
||||
|
||||
#endif // CSM_WOLRD_IDADAPTER_H
|
@ -0,0 +1,202 @@
|
||||
#ifndef CSM_WOLRD_IDADAPTERIMP_H
|
||||
#define CSM_WOLRD_IDADAPTERIMP_H
|
||||
|
||||
#include <QVariant>
|
||||
|
||||
#include <components/esm/loadpgrd.hpp>
|
||||
|
||||
#include "idadapter.hpp"
|
||||
|
||||
namespace CSMWorld
|
||||
{
|
||||
class NestedTableWrapperBase;
|
||||
|
||||
template<typename ESXRecordT>
|
||||
class PathgridPointListAdapter : public NestedIdAdapter<ESXRecordT>
|
||||
{
|
||||
public:
|
||||
PathgridPointListAdapter () {}
|
||||
|
||||
virtual void addNestedRow(Record<ESXRecordT>& record, int position) const
|
||||
{
|
||||
ESXRecordT pathgrid = record.get();
|
||||
|
||||
ESXRecordT::PointList& points = pathgrid.mPoints;
|
||||
|
||||
// blank row
|
||||
ESM::Pathgrid::Point point;
|
||||
point.mX = 0;
|
||||
point.mY = 0;
|
||||
point.mZ = 0;
|
||||
point.mAutogenerated = 0;
|
||||
point.mConnectionNum = 0;
|
||||
point.mUnknown = 0;
|
||||
|
||||
// FIXME: inserting a point should trigger re-indexing of the edges
|
||||
points.insert(points.begin()+position, point);
|
||||
pathgrid.mData.mS2 += 1; // increment the number of points
|
||||
|
||||
record.setModified (pathgrid);
|
||||
}
|
||||
|
||||
virtual void removeNestedRow(Record<ESXRecordT>& record, int rowToRemove) const
|
||||
{
|
||||
ESXRecordT pathgrid = record.get();
|
||||
|
||||
ESXRecordT::PointList& points = pathgrid.mPoints;
|
||||
|
||||
if (rowToRemove < 0 || rowToRemove >= static_cast<int> (points.size()))
|
||||
throw std::runtime_error ("index out of range");
|
||||
|
||||
// FIXME: deleting a point should trigger re-indexing of the edges
|
||||
points.erase(points.begin()+rowToRemove);
|
||||
pathgrid.mData.mS2 -= 1; // decrement the number of points
|
||||
|
||||
record.setModified (pathgrid);
|
||||
}
|
||||
|
||||
virtual void setNestedTable(Record<ESXRecordT>& record, const NestedTableWrapperBase& nestedTable)
|
||||
{
|
||||
record.get().mPoints =
|
||||
static_cast<const NestedTableWrapper<ESXRecordT::PointList> &>(nestedTable).mNestedTable;
|
||||
}
|
||||
|
||||
virtual NestedTableWrapperBase* nestedTable(const Record<ESXRecordT>& record) const
|
||||
{
|
||||
// deleted by dtor of NestedTableStoring
|
||||
return new NestedTableWrapper<ESXRecordT::PointList>(record.get().mPoints);
|
||||
}
|
||||
|
||||
virtual QVariant getNestedData(const Record<ESXRecordT>& record, int subRowIndex, int subColIndex) const
|
||||
{
|
||||
ESM::Pathgrid::Point point = record.get().mPoints[subRowIndex];
|
||||
switch (subColIndex)
|
||||
{
|
||||
case 0: return point.mX;
|
||||
case 1: return point.mY;
|
||||
case 2: return point.mZ;
|
||||
default: throw std::logic_error("Pathgrid point subcolumn index out of range");
|
||||
}
|
||||
}
|
||||
|
||||
virtual void setNestedData(Record<ESXRecordT>& record, const QVariant& value,
|
||||
int subRowIndex, int subColIndex) const
|
||||
{
|
||||
ESXRecordT pathgrid = record.get();
|
||||
ESM::Pathgrid::Point point = pathgrid.mPoints[subRowIndex];
|
||||
switch (subColIndex)
|
||||
{
|
||||
case 0: point.mX = value.toInt(); break;
|
||||
case 1: point.mY = value.toInt(); break;
|
||||
case 2: point.mZ = value.toInt(); break;
|
||||
default: throw std::logic_error("Pathgrid point subcolumn index out of range");
|
||||
}
|
||||
|
||||
pathgrid.mPoints[subRowIndex] = point;
|
||||
|
||||
record.setModified (pathgrid);
|
||||
}
|
||||
|
||||
virtual int getNestedColumnsCount(const Record<ESXRecordT>& record) const
|
||||
{
|
||||
return 3;
|
||||
}
|
||||
|
||||
virtual int getNestedRowsCount(const Record<ESXRecordT>& record) const
|
||||
{
|
||||
return static_cast<int>(record.get().mPoints.size());
|
||||
}
|
||||
};
|
||||
|
||||
template<typename ESXRecordT>
|
||||
class PathgridEdgeListAdapter : public NestedIdAdapter<ESXRecordT>
|
||||
{
|
||||
public:
|
||||
PathgridEdgeListAdapter () {}
|
||||
|
||||
// FIXME: seems to be auto-sorted in the dialog table display after insertion
|
||||
virtual void addNestedRow(Record<ESXRecordT>& record, int position) const
|
||||
{
|
||||
ESXRecordT pathgrid = record.get();
|
||||
|
||||
ESXRecordT::EdgeList& edges = pathgrid.mEdges;
|
||||
|
||||
// blank row
|
||||
ESM::Pathgrid::Edge edge;
|
||||
edge.mV0 = 0;
|
||||
edge.mV1 = 0;
|
||||
|
||||
// FIXME: inserting a blank edge does not really make sense, perhaps this should be a
|
||||
// logic_error exception
|
||||
edges.insert(edges.begin()+position, edge);
|
||||
|
||||
record.setModified (pathgrid);
|
||||
}
|
||||
|
||||
virtual void removeNestedRow(Record<ESXRecordT>& record, int rowToRemove) const
|
||||
{
|
||||
ESXRecordT pathgrid = record.get();
|
||||
|
||||
ESXRecordT::EdgeList& edges = pathgrid.mEdges;
|
||||
|
||||
if (rowToRemove < 0 || rowToRemove >= static_cast<int> (edges.size()))
|
||||
throw std::runtime_error ("index out of range");
|
||||
|
||||
edges.erase(edges.begin()+rowToRemove);
|
||||
|
||||
record.setModified (pathgrid);
|
||||
}
|
||||
|
||||
virtual void setNestedTable(Record<ESXRecordT>& record, const NestedTableWrapperBase& nestedTable)
|
||||
{
|
||||
record.get().mEdges =
|
||||
static_cast<const NestedTableWrapper<ESXRecordT::EdgeList> &>(nestedTable).mNestedTable;
|
||||
}
|
||||
|
||||
virtual NestedTableWrapperBase* nestedTable(const Record<ESXRecordT>& record) const
|
||||
{
|
||||
// deleted by dtor of NestedTableStoring
|
||||
return new NestedTableWrapper<ESXRecordT::EdgeList>(record.get().mEdges);
|
||||
}
|
||||
|
||||
virtual QVariant getNestedData(const Record<ESXRecordT>& record, int subRowIndex, int subColIndex) const
|
||||
{
|
||||
ESM::Pathgrid::Edge edge = record.get().mEdges[subRowIndex];
|
||||
switch (subColIndex)
|
||||
{
|
||||
case 0: return edge.mV0;
|
||||
case 1: return edge.mV1;
|
||||
default: throw std::logic_error("Pathgrid edge subcolumn index out of range");
|
||||
}
|
||||
}
|
||||
|
||||
virtual void setNestedData(Record<ESXRecordT>& record, const QVariant& value,
|
||||
int subRowIndex, int subColIndex) const
|
||||
{
|
||||
ESXRecordT pathgrid = record.get();
|
||||
ESM::Pathgrid::Edge edge = pathgrid.mEdges[subRowIndex];
|
||||
switch (subColIndex)
|
||||
{
|
||||
case 0: edge.mV0 = value.toInt(); break;
|
||||
case 1: edge.mV1 = value.toInt(); break;
|
||||
default: throw std::logic_error("Pathgrid edge subcolumn index out of range");
|
||||
}
|
||||
|
||||
pathgrid.mEdges[subRowIndex] = edge;
|
||||
|
||||
record.setModified (pathgrid);
|
||||
}
|
||||
|
||||
virtual int getNestedColumnsCount(const Record<ESXRecordT>& record) const
|
||||
{
|
||||
return 2;
|
||||
}
|
||||
|
||||
virtual int getNestedRowsCount(const Record<ESXRecordT>& record) const
|
||||
{
|
||||
return static_cast<int>(record.get().mEdges.size());
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
#endif // CSM_WOLRD_IDADAPTERIMP_H
|
Loading…
Reference in New Issue