mirror of
https://github.com/OpenMW/openmw.git
synced 2025-01-21 09:23:53 +00:00
Merge branch 'marker'
This commit is contained in:
commit
6c65081643
11 changed files with 567 additions and 49 deletions
|
@ -90,7 +90,7 @@ opencs_units (view/render
|
|||
|
||||
opencs_units_noqt (view/render
|
||||
lighting lightingday lightingnight
|
||||
lightingbright object cell terrainstorage tagbase
|
||||
lightingbright object cell terrainstorage tagbase cellarrow
|
||||
)
|
||||
|
||||
opencs_hdrs_noqt (view/render
|
||||
|
|
|
@ -32,6 +32,23 @@ std::string CSMWorld::CellCoordinates::getId (const std::string& worldspace) con
|
|||
return stream.str();
|
||||
}
|
||||
|
||||
std::pair<CSMWorld::CellCoordinates, bool> CSMWorld::CellCoordinates::fromId (
|
||||
const std::string& id)
|
||||
{
|
||||
// no worldspace for now, needs to be changed for 1.1
|
||||
if (!id.empty() && id[0]=='#')
|
||||
{
|
||||
int x, y;
|
||||
char ignore;
|
||||
|
||||
std::istringstream stream (id);
|
||||
if (stream >> ignore >> x >> y)
|
||||
return std::make_pair (CellCoordinates (x, y), true);
|
||||
}
|
||||
|
||||
return std::make_pair (CellCoordinates(), false);
|
||||
}
|
||||
|
||||
bool CSMWorld::operator== (const CellCoordinates& left, const CellCoordinates& right)
|
||||
{
|
||||
return left.getX()==right.getX() && left.getY()==right.getY();
|
||||
|
|
|
@ -28,6 +28,12 @@ namespace CSMWorld
|
|||
|
||||
std::string getId (const std::string& worldspace) const;
|
||||
///< Return the ID for the cell at these coordinates.
|
||||
|
||||
/// \return first: CellCoordinates (or 0, 0 if cell does not have coordinates),
|
||||
/// second: is cell paged?
|
||||
///
|
||||
/// \note The worldspace part of \a id is ignored
|
||||
static std::pair<CellCoordinates, bool> fromId (const std::string& id);
|
||||
};
|
||||
|
||||
bool operator== (const CellCoordinates& left, const CellCoordinates& right);
|
||||
|
|
|
@ -9,6 +9,7 @@
|
|||
#include "../../model/world/columns.hpp"
|
||||
#include "../../model/world/data.hpp"
|
||||
#include "../../model/world/refcollection.hpp"
|
||||
#include "../../model/world/cellcoordinates.hpp"
|
||||
|
||||
#include "elements.hpp"
|
||||
#include "terrainstorage.hpp"
|
||||
|
@ -50,33 +51,39 @@ bool CSVRender::Cell::addObjects (int start, int end)
|
|||
return modified;
|
||||
}
|
||||
|
||||
CSVRender::Cell::Cell (CSMWorld::Data& data, osg::Group* rootNode, const std::string& id)
|
||||
: mData (data), mId (Misc::StringUtils::lowerCase (id)), mX(0), mY(0)
|
||||
CSVRender::Cell::Cell (CSMWorld::Data& data, osg::Group* rootNode, const std::string& id,
|
||||
bool deleted)
|
||||
: mData (data), mId (Misc::StringUtils::lowerCase (id)), mDeleted (deleted)
|
||||
{
|
||||
std::pair<CSMWorld::CellCoordinates, bool> result = CSMWorld::CellCoordinates::fromId (id);
|
||||
|
||||
if (result.second)
|
||||
mCoordinates = result.first;
|
||||
|
||||
mCellNode = new osg::Group;
|
||||
rootNode->addChild(mCellNode);
|
||||
|
||||
CSMWorld::IdTable& references = dynamic_cast<CSMWorld::IdTable&> (
|
||||
*mData.getTableModel (CSMWorld::UniversalId::Type_References));
|
||||
|
||||
int rows = references.rowCount();
|
||||
|
||||
addObjects (0, rows-1);
|
||||
|
||||
const CSMWorld::IdCollection<CSMWorld::Land>& land = mData.getLand();
|
||||
int landIndex = land.searchId(mId);
|
||||
if (landIndex != -1)
|
||||
if (!mDeleted)
|
||||
{
|
||||
const ESM::Land& esmLand = land.getRecord(mId).get();
|
||||
CSMWorld::IdTable& references = dynamic_cast<CSMWorld::IdTable&> (
|
||||
*mData.getTableModel (CSMWorld::UniversalId::Type_References));
|
||||
|
||||
if (esmLand.getLandData (ESM::Land::DATA_VHGT))
|
||||
int rows = references.rowCount();
|
||||
|
||||
addObjects (0, rows-1);
|
||||
|
||||
const CSMWorld::IdCollection<CSMWorld::Land>& land = mData.getLand();
|
||||
int landIndex = land.searchId(mId);
|
||||
if (landIndex != -1)
|
||||
{
|
||||
mTerrain.reset(new Terrain::TerrainGrid(mCellNode, data.getResourceSystem().get(), NULL, new TerrainStorage(mData), Element_Terrain<<1));
|
||||
mTerrain->loadCell(esmLand.mX,
|
||||
esmLand.mY);
|
||||
const ESM::Land& esmLand = land.getRecord(mId).get();
|
||||
|
||||
mX = esmLand.mX;
|
||||
mY = esmLand.mY;
|
||||
if (esmLand.getLandData (ESM::Land::DATA_VHGT))
|
||||
{
|
||||
mTerrain.reset(new Terrain::TerrainGrid(mCellNode, data.getResourceSystem().get(), NULL, new TerrainStorage(mData), Element_Terrain<<1));
|
||||
mTerrain->loadCell(esmLand.mX,
|
||||
esmLand.mY);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -122,6 +129,9 @@ bool CSVRender::Cell::referenceableAboutToBeRemoved (const QModelIndex& parent,
|
|||
bool CSVRender::Cell::referenceDataChanged (const QModelIndex& topLeft,
|
||||
const QModelIndex& bottomRight)
|
||||
{
|
||||
if (mDeleted)
|
||||
return false;
|
||||
|
||||
CSMWorld::IdTable& references = dynamic_cast<CSMWorld::IdTable&> (
|
||||
*mData.getTableModel (CSMWorld::UniversalId::Type_References));
|
||||
|
||||
|
@ -189,6 +199,9 @@ bool CSVRender::Cell::referenceAboutToBeRemoved (const QModelIndex& parent, int
|
|||
if (parent.isValid())
|
||||
return false;
|
||||
|
||||
if (mDeleted)
|
||||
return false;
|
||||
|
||||
CSMWorld::IdTable& references = dynamic_cast<CSMWorld::IdTable&> (
|
||||
*mData.getTableModel (CSMWorld::UniversalId::Type_References));
|
||||
|
||||
|
@ -209,6 +222,9 @@ bool CSVRender::Cell::referenceAdded (const QModelIndex& parent, int start, int
|
|||
if (parent.isValid())
|
||||
return false;
|
||||
|
||||
if (mDeleted)
|
||||
return false;
|
||||
|
||||
return addObjects (start, end);
|
||||
}
|
||||
|
||||
|
@ -232,3 +248,31 @@ void CSVRender::Cell::setSelection (int elementMask, Selection mode)
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CSVRender::Cell::setCellArrows (int mask)
|
||||
{
|
||||
for (int i=0; i<4; ++i)
|
||||
{
|
||||
CellArrow::Direction direction = static_cast<CellArrow::Direction> (1<<i);
|
||||
|
||||
bool enable = mask & direction;
|
||||
|
||||
if (enable!=(mCellArrows[i].get()!=0))
|
||||
{
|
||||
if (enable)
|
||||
mCellArrows[i].reset (new CellArrow (mCellNode, direction, mCoordinates));
|
||||
else
|
||||
mCellArrows[i].reset (0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
CSMWorld::CellCoordinates CSVRender::Cell::getCoordinates() const
|
||||
{
|
||||
return mCoordinates;
|
||||
}
|
||||
|
||||
bool CSVRender::Cell::isDeleted() const
|
||||
{
|
||||
return mDeleted;
|
||||
}
|
||||
|
|
|
@ -14,6 +14,7 @@
|
|||
#endif
|
||||
|
||||
#include "object.hpp"
|
||||
#include "cellarrow.hpp"
|
||||
|
||||
class QModelIndex;
|
||||
|
||||
|
@ -25,6 +26,7 @@ namespace osg
|
|||
namespace CSMWorld
|
||||
{
|
||||
class Data;
|
||||
class CellCoordinates;
|
||||
}
|
||||
|
||||
namespace CSVRender
|
||||
|
@ -36,8 +38,9 @@ namespace CSVRender
|
|||
osg::ref_ptr<osg::Group> mCellNode;
|
||||
std::map<std::string, Object *> mObjects;
|
||||
std::auto_ptr<Terrain::TerrainGrid> mTerrain;
|
||||
int mX;
|
||||
int mY;
|
||||
CSMWorld::CellCoordinates mCoordinates;
|
||||
std::auto_ptr<CellArrow> mCellArrows[4];
|
||||
bool mDeleted;
|
||||
|
||||
/// Ignored if cell does not have an object with the given ID.
|
||||
///
|
||||
|
@ -60,7 +63,10 @@ namespace CSVRender
|
|||
|
||||
public:
|
||||
|
||||
Cell (CSMWorld::Data& data, osg::Group* rootNode, const std::string& id);
|
||||
/// \note Deleted covers both cells that are deleted and cells that don't exist in
|
||||
/// the first place.
|
||||
Cell (CSMWorld::Data& data, osg::Group* rootNode, const std::string& id,
|
||||
bool deleted = false);
|
||||
|
||||
~Cell();
|
||||
|
||||
|
@ -86,6 +92,13 @@ namespace CSVRender
|
|||
bool referenceAdded (const QModelIndex& parent, int start, int end);
|
||||
|
||||
void setSelection (int elementMask, Selection mode);
|
||||
|
||||
void setCellArrows (int mask);
|
||||
|
||||
/// Returns 0, 0 in case of an unpaged cell.
|
||||
CSMWorld::CellCoordinates getCoordinates() const;
|
||||
|
||||
bool isDeleted() const;
|
||||
};
|
||||
}
|
||||
|
||||
|
|
161
apps/opencs/view/render/cellarrow.cpp
Normal file
161
apps/opencs/view/render/cellarrow.cpp
Normal file
|
@ -0,0 +1,161 @@
|
|||
|
||||
#include "cellarrow.hpp"
|
||||
|
||||
#include <osg/Group>
|
||||
#include <osg/PositionAttitudeTransform>
|
||||
#include <osg/Geode>
|
||||
#include <osg/Geometry>
|
||||
#include <osg/PrimitiveSet>
|
||||
|
||||
#include "elements.hpp"
|
||||
|
||||
CSVRender::CellArrowTag::CellArrowTag (CellArrow *arrow)
|
||||
: TagBase (Element_CellArrow), mArrow (arrow)
|
||||
{}
|
||||
|
||||
CSVRender::CellArrow *CSVRender::CellArrowTag::getCellArrow() const
|
||||
{
|
||||
return mArrow;
|
||||
}
|
||||
|
||||
|
||||
void CSVRender::CellArrow::adjustTransform()
|
||||
{
|
||||
// position
|
||||
const int cellSize = 8192;
|
||||
const int offset = cellSize / 2 + 800;
|
||||
|
||||
int x = mCoordinates.getX()*cellSize + cellSize/2;
|
||||
int y = mCoordinates.getY()*cellSize + cellSize/2;
|
||||
|
||||
float xr = 0;
|
||||
float yr = 0;
|
||||
float zr = 0;
|
||||
|
||||
float angle = osg::DegreesToRadians (90.0f);
|
||||
|
||||
switch (mDirection)
|
||||
{
|
||||
case Direction_North: y += offset; xr = -angle; zr = angle; break;
|
||||
case Direction_West: x -= offset; yr = -angle; break;
|
||||
case Direction_South: y -= offset; xr = angle; zr = angle; break;
|
||||
case Direction_East: x += offset; yr = angle; break;
|
||||
};
|
||||
|
||||
mBaseNode->setPosition (osg::Vec3f (x, y, 0));
|
||||
|
||||
// orientation
|
||||
osg::Quat xr2 (xr, osg::Vec3f (1,0,0));
|
||||
osg::Quat yr2 (yr, osg::Vec3f (0,1,0));
|
||||
osg::Quat zr2 (zr, osg::Vec3f (0,0,1));
|
||||
mBaseNode->setAttitude (zr2*yr2*xr2);
|
||||
}
|
||||
|
||||
void CSVRender::CellArrow::buildShape()
|
||||
{
|
||||
osg::ref_ptr<osg::Geometry> geometry (new osg::Geometry);
|
||||
|
||||
const int arrowWidth = 4000;
|
||||
const int arrowLength = 1500;
|
||||
const int arrowHeight = 500;
|
||||
|
||||
osg::Vec3Array *vertices = new osg::Vec3Array;
|
||||
for (int i2=0; i2<2; ++i2)
|
||||
for (int i=0; i<2; ++i)
|
||||
{
|
||||
float height = i ? -arrowHeight/2 : arrowHeight/2;
|
||||
vertices->push_back (osg::Vec3f (height, -arrowWidth/2, 0));
|
||||
vertices->push_back (osg::Vec3f (height, arrowWidth/2, 0));
|
||||
vertices->push_back (osg::Vec3f (height, 0, arrowLength));
|
||||
}
|
||||
|
||||
geometry->setVertexArray (vertices);
|
||||
|
||||
osg::DrawElementsUShort *primitives = new osg::DrawElementsUShort (osg::PrimitiveSet::TRIANGLES, 0);
|
||||
|
||||
// top
|
||||
primitives->push_back (0);
|
||||
primitives->push_back (1);
|
||||
primitives->push_back (2);
|
||||
|
||||
// bottom
|
||||
primitives->push_back (5);
|
||||
primitives->push_back (4);
|
||||
primitives->push_back (3);
|
||||
|
||||
// back
|
||||
primitives->push_back (3+6);
|
||||
primitives->push_back (4+6);
|
||||
primitives->push_back (1+6);
|
||||
|
||||
primitives->push_back (3+6);
|
||||
primitives->push_back (1+6);
|
||||
primitives->push_back (0+6);
|
||||
|
||||
// sides
|
||||
primitives->push_back (0+6);
|
||||
primitives->push_back (2+6);
|
||||
primitives->push_back (5+6);
|
||||
|
||||
primitives->push_back (0+6);
|
||||
primitives->push_back (5+6);
|
||||
primitives->push_back (3+6);
|
||||
|
||||
primitives->push_back (4+6);
|
||||
primitives->push_back (5+6);
|
||||
primitives->push_back (2+6);
|
||||
|
||||
primitives->push_back (4+6);
|
||||
primitives->push_back (2+6);
|
||||
primitives->push_back (1+6);
|
||||
|
||||
geometry->addPrimitiveSet (primitives);
|
||||
|
||||
osg::Vec4Array *colours = new osg::Vec4Array;
|
||||
|
||||
for (int i=0; i<6; ++i)
|
||||
colours->push_back (osg::Vec4f (1.0f, 0.0f, 0.0f, 1.0f));
|
||||
for (int i=0; i<6; ++i)
|
||||
colours->push_back (osg::Vec4f (0.8f, (i==2 || i==5) ? 0.6f : 0.4f, 0.0f, 1.0f));
|
||||
|
||||
geometry->setColorArray (colours, osg::Array::BIND_PER_VERTEX);
|
||||
|
||||
geometry->getOrCreateStateSet()->setMode (GL_LIGHTING, osg::StateAttribute::OFF);
|
||||
|
||||
osg::ref_ptr<osg::Geode> geode (new osg::Geode);
|
||||
geode->addDrawable (geometry);
|
||||
|
||||
mBaseNode->addChild (geode);
|
||||
}
|
||||
|
||||
CSVRender::CellArrow::CellArrow (osg::Group *cellNode, Direction direction,
|
||||
const CSMWorld::CellCoordinates& coordinates)
|
||||
: mDirection (direction), mParentNode (cellNode), mCoordinates (coordinates)
|
||||
{
|
||||
mBaseNode = new osg::PositionAttitudeTransform;
|
||||
|
||||
mBaseNode->setUserData (new CellArrowTag (this));
|
||||
|
||||
mParentNode->addChild (mBaseNode);
|
||||
|
||||
// 0x1 reserved for separating cull and update visitors
|
||||
mBaseNode->setNodeMask (Element_CellArrow<<1);
|
||||
|
||||
adjustTransform();
|
||||
buildShape();
|
||||
}
|
||||
|
||||
CSVRender::CellArrow::~CellArrow()
|
||||
{
|
||||
mParentNode->removeChild (mBaseNode);
|
||||
}
|
||||
|
||||
CSMWorld::CellCoordinates CSVRender::CellArrow::getCoordinates() const
|
||||
{
|
||||
return mCoordinates;
|
||||
}
|
||||
|
||||
CSVRender::CellArrow::Direction CSVRender::CellArrow::getDirection() const
|
||||
{
|
||||
return mDirection;
|
||||
}
|
72
apps/opencs/view/render/cellarrow.hpp
Normal file
72
apps/opencs/view/render/cellarrow.hpp
Normal file
|
@ -0,0 +1,72 @@
|
|||
#ifndef OPENCS_VIEW_CELLARROW_H
|
||||
#define OPENCS_VIEW_CELLARROW_H
|
||||
|
||||
#include "tagbase.hpp"
|
||||
|
||||
#include <osg/ref_ptr>
|
||||
|
||||
#include "../../model/world/cellcoordinates.hpp"
|
||||
|
||||
namespace osg
|
||||
{
|
||||
class PositionAttitudeTransform;
|
||||
class Group;
|
||||
}
|
||||
|
||||
namespace CSVRender
|
||||
{
|
||||
class CellArrow;
|
||||
|
||||
class CellArrowTag : public TagBase
|
||||
{
|
||||
CellArrow *mArrow;
|
||||
|
||||
public:
|
||||
|
||||
CellArrowTag (CellArrow *arrow);
|
||||
|
||||
CellArrow *getCellArrow() const;
|
||||
};
|
||||
|
||||
|
||||
class CellArrow
|
||||
{
|
||||
public:
|
||||
|
||||
enum Direction
|
||||
{
|
||||
Direction_North = 1,
|
||||
Direction_West = 2,
|
||||
Direction_South = 4,
|
||||
Direction_East = 8
|
||||
};
|
||||
|
||||
private:
|
||||
|
||||
// not implemented
|
||||
CellArrow (const CellArrow&);
|
||||
CellArrow& operator= (const CellArrow&);
|
||||
|
||||
Direction mDirection;
|
||||
osg::Group* mParentNode;
|
||||
osg::ref_ptr<osg::PositionAttitudeTransform> mBaseNode;
|
||||
CSMWorld::CellCoordinates mCoordinates;
|
||||
|
||||
void adjustTransform();
|
||||
|
||||
void buildShape();
|
||||
|
||||
public:
|
||||
|
||||
CellArrow (osg::Group *cellNode, Direction direction,
|
||||
const CSMWorld::CellCoordinates& coordinates);
|
||||
|
||||
~CellArrow();
|
||||
|
||||
CSMWorld::CellCoordinates getCoordinates() const;
|
||||
|
||||
Direction getDirection() const;
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
|
@ -1,8 +1,10 @@
|
|||
#include "pagedworldspacewidget.hpp"
|
||||
|
||||
#include <memory>
|
||||
#include <sstream>
|
||||
|
||||
#include <QMouseEvent>
|
||||
#include <QApplication>
|
||||
|
||||
#include <osgGA/TrackballManipulator>
|
||||
|
||||
|
@ -21,20 +23,19 @@
|
|||
bool CSVRender::PagedWorldspaceWidget::adjustCells()
|
||||
{
|
||||
bool modified = false;
|
||||
bool wasEmpty = mCells.empty();
|
||||
|
||||
const CSMWorld::IdCollection<CSMWorld::Cell>& cells = mDocument.getData().getCells();
|
||||
|
||||
{
|
||||
// remove (or name/region modified)
|
||||
// remove/update
|
||||
std::map<CSMWorld::CellCoordinates, Cell *>::iterator iter (mCells.begin());
|
||||
|
||||
while (iter!=mCells.end())
|
||||
{
|
||||
int index = cells.searchId (iter->first.getId (mWorldspace));
|
||||
|
||||
if (!mSelection.has (iter->first) || index==-1 ||
|
||||
cells.getRecord (index).mState==CSMWorld::RecordBase::State_Deleted)
|
||||
if (!mSelection.has (iter->first))
|
||||
{
|
||||
// remove
|
||||
delete iter->second;
|
||||
mCells.erase (iter++);
|
||||
|
||||
|
@ -42,12 +43,33 @@ bool CSVRender::PagedWorldspaceWidget::adjustCells()
|
|||
}
|
||||
else
|
||||
{
|
||||
// check if name or region field has changed
|
||||
// FIXME: config setting
|
||||
//std::string name = cells.getRecord(index).get().mName;
|
||||
//std::string region = cells.getRecord(index).get().mRegion;
|
||||
// update
|
||||
int index = cells.searchId (iter->first.getId (mWorldspace));
|
||||
|
||||
// cell marker update goes here
|
||||
bool deleted = index==-1 ||
|
||||
cells.getRecord (index).mState==CSMWorld::RecordBase::State_Deleted;
|
||||
|
||||
if (deleted!=iter->second->isDeleted())
|
||||
{
|
||||
modified = true;
|
||||
|
||||
std::auto_ptr<Cell> cell (new Cell (mDocument.getData(), mRootNode,
|
||||
iter->first.getId (mWorldspace), deleted));
|
||||
|
||||
delete iter->second;
|
||||
iter->second = cell.release();
|
||||
}
|
||||
else if (!deleted)
|
||||
{
|
||||
// delete state has not changed -> just update
|
||||
|
||||
// TODO check if name or region field has changed (cell marker)
|
||||
// FIXME: config setting
|
||||
//std::string name = cells.getRecord(index).get().mName;
|
||||
//std::string region = cells.getRecord(index).get().mRegion;
|
||||
|
||||
modified = true;
|
||||
}
|
||||
|
||||
++iter;
|
||||
}
|
||||
|
@ -58,20 +80,43 @@ bool CSVRender::PagedWorldspaceWidget::adjustCells()
|
|||
for (CSMWorld::CellSelection::Iterator iter (mSelection.begin()); iter!=mSelection.end();
|
||||
++iter)
|
||||
{
|
||||
int index = cells.searchId (iter->getId (mWorldspace));
|
||||
|
||||
if (index > 0 && cells.getRecord (index).mState!=CSMWorld::RecordBase::State_Deleted &&
|
||||
mCells.find (*iter)==mCells.end())
|
||||
if (mCells.find (*iter)==mCells.end())
|
||||
{
|
||||
Cell *cell = new Cell (mDocument.getData(), mRootNode,
|
||||
iter->getId (mWorldspace));
|
||||
mCells.insert (std::make_pair (*iter, cell));
|
||||
|
||||
addCellToScene (*iter);
|
||||
modified = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (modified)
|
||||
{
|
||||
for (std::map<CSMWorld::CellCoordinates, Cell *>::const_iterator iter (mCells.begin());
|
||||
iter!=mCells.end(); ++iter)
|
||||
{
|
||||
int mask = 0;
|
||||
|
||||
for (int i=CellArrow::Direction_North; i<=CellArrow::Direction_East; i *= 2)
|
||||
{
|
||||
CSMWorld::CellCoordinates coordinates (iter->second->getCoordinates());
|
||||
|
||||
switch (i)
|
||||
{
|
||||
case CellArrow::Direction_North: coordinates = coordinates.move (0, 1); break;
|
||||
case CellArrow::Direction_West: coordinates = coordinates.move (-1, 0); break;
|
||||
case CellArrow::Direction_South: coordinates = coordinates.move (0, -1); break;
|
||||
case CellArrow::Direction_East: coordinates = coordinates.move (1, 0); break;
|
||||
}
|
||||
|
||||
if (!mSelection.has (coordinates))
|
||||
mask |= i;
|
||||
}
|
||||
|
||||
iter->second->setCellArrows (mask);
|
||||
}
|
||||
}
|
||||
|
||||
/// \todo do not overwrite manipulator object
|
||||
/// \todo move code to useViewHint function
|
||||
if (modified && wasEmpty)
|
||||
mView->setCameraManipulator(new osgGA::TrackballManipulator);
|
||||
|
||||
return modified;
|
||||
|
@ -105,6 +150,76 @@ void CSVRender::PagedWorldspaceWidget::addEditModeSelectorButtons (
|
|||
"terrain-move");
|
||||
}
|
||||
|
||||
void CSVRender::PagedWorldspaceWidget::handleMouseClick (osg::ref_ptr<TagBase> tag, const std::string& button)
|
||||
{
|
||||
if (tag && tag->getElement()==Element_CellArrow)
|
||||
{
|
||||
if (button=="p-edit" || button=="s-edit")
|
||||
{
|
||||
if (CellArrowTag *cellArrowTag =
|
||||
dynamic_cast<CSVRender::CellArrowTag *> (tag.get()))
|
||||
{
|
||||
CellArrow *arrow = cellArrowTag->getCellArrow();
|
||||
|
||||
CSMWorld::CellCoordinates coordinates = arrow->getCoordinates();
|
||||
|
||||
CellArrow::Direction direction = arrow->getDirection();
|
||||
|
||||
int x = 0;
|
||||
int y = 0;
|
||||
|
||||
switch (direction)
|
||||
{
|
||||
case CellArrow::Direction_North: y = 1; break;
|
||||
case CellArrow::Direction_West: x = -1; break;
|
||||
case CellArrow::Direction_South: y = -1; break;
|
||||
case CellArrow::Direction_East: x = 1; break;
|
||||
}
|
||||
|
||||
bool modified = false;
|
||||
|
||||
if (QApplication::keyboardModifiers() & Qt::ShiftModifier)
|
||||
{
|
||||
if (button=="p-edit")
|
||||
addCellSelection (x, y);
|
||||
else
|
||||
moveCellSelection (x, y);
|
||||
|
||||
modified = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
CSMWorld::CellCoordinates newCoordinates = coordinates.move (x, y);
|
||||
|
||||
if (mCells.find (newCoordinates)==mCells.end())
|
||||
{
|
||||
addCellToScene (newCoordinates);
|
||||
mSelection.add (newCoordinates);
|
||||
modified = true;
|
||||
}
|
||||
|
||||
if (button=="s-edit")
|
||||
{
|
||||
if (mCells.find (coordinates)!=mCells.end())
|
||||
{
|
||||
removeCellFromScene (coordinates);
|
||||
mSelection.remove (coordinates);
|
||||
modified = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (modified)
|
||||
adjustCells();
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
WorldspaceWidget::handleMouseClick (tag, button);
|
||||
}
|
||||
|
||||
void CSVRender::PagedWorldspaceWidget::referenceableDataChanged (const QModelIndex& topLeft,
|
||||
const QModelIndex& bottomRight)
|
||||
{
|
||||
|
@ -184,6 +299,72 @@ std::string CSVRender::PagedWorldspaceWidget::getStartupInstruction()
|
|||
return stream.str();
|
||||
}
|
||||
|
||||
void CSVRender::PagedWorldspaceWidget::addCellToScene (
|
||||
const CSMWorld::CellCoordinates& coordinates)
|
||||
{
|
||||
const CSMWorld::IdCollection<CSMWorld::Cell>& cells = mDocument.getData().getCells();
|
||||
|
||||
int index = cells.searchId (coordinates.getId (mWorldspace));
|
||||
|
||||
bool deleted = index==-1 ||
|
||||
cells.getRecord (index).mState==CSMWorld::RecordBase::State_Deleted;
|
||||
|
||||
Cell *cell = new Cell (mDocument.getData(), mRootNode, coordinates.getId (mWorldspace),
|
||||
deleted);
|
||||
|
||||
mCells.insert (std::make_pair (coordinates, cell));
|
||||
}
|
||||
|
||||
void CSVRender::PagedWorldspaceWidget::removeCellFromScene (
|
||||
const CSMWorld::CellCoordinates& coordinates)
|
||||
{
|
||||
std::map<CSMWorld::CellCoordinates, Cell *>::iterator iter = mCells.find (coordinates);
|
||||
|
||||
if (iter!=mCells.end())
|
||||
{
|
||||
delete iter->second;
|
||||
mCells.erase (iter);
|
||||
}
|
||||
}
|
||||
|
||||
void CSVRender::PagedWorldspaceWidget::addCellSelection (int x, int y)
|
||||
{
|
||||
CSMWorld::CellSelection newSelection = mSelection;
|
||||
newSelection.move (x, y);
|
||||
|
||||
for (CSMWorld::CellSelection::Iterator iter (newSelection.begin()); iter!=newSelection.end();
|
||||
++iter)
|
||||
{
|
||||
if (mCells.find (*iter)==mCells.end())
|
||||
{
|
||||
addCellToScene (*iter);
|
||||
mSelection.add (*iter);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CSVRender::PagedWorldspaceWidget::moveCellSelection (int x, int y)
|
||||
{
|
||||
CSMWorld::CellSelection newSelection = mSelection;
|
||||
newSelection.move (x, y);
|
||||
|
||||
for (CSMWorld::CellSelection::Iterator iter (mSelection.begin()); iter!=mSelection.end();
|
||||
++iter)
|
||||
{
|
||||
if (!newSelection.has (*iter))
|
||||
removeCellFromScene (*iter);
|
||||
}
|
||||
|
||||
for (CSMWorld::CellSelection::Iterator iter (newSelection.begin()); iter!=newSelection.end();
|
||||
++iter)
|
||||
{
|
||||
if (!mSelection.has (*iter))
|
||||
addCellToScene (*iter);
|
||||
}
|
||||
|
||||
mSelection = newSelection;
|
||||
}
|
||||
|
||||
CSVRender::PagedWorldspaceWidget::PagedWorldspaceWidget (QWidget* parent, CSMDoc::Document& document)
|
||||
: WorldspaceWidget (document, parent), mDocument (document), mWorldspace ("std::default"),
|
||||
mControlElements(NULL), mDisplayCellCoord(true)
|
||||
|
|
|
@ -53,6 +53,20 @@ namespace CSVRender
|
|||
|
||||
virtual std::string getStartupInstruction();
|
||||
|
||||
/// \note Does not update the view or any cell marker
|
||||
void addCellToScene (const CSMWorld::CellCoordinates& coordinates);
|
||||
|
||||
/// \note Does not update the view or any cell marker
|
||||
///
|
||||
/// \note Calling this function for a cell that is not in the selection is a no-op.
|
||||
void removeCellFromScene (const CSMWorld::CellCoordinates& coordinates);
|
||||
|
||||
/// \note Does not update the view or any cell marker
|
||||
void addCellSelection (int x, int y);
|
||||
|
||||
/// \note Does not update the view or any cell marker
|
||||
void moveCellSelection (int x, int y);
|
||||
|
||||
public:
|
||||
|
||||
PagedWorldspaceWidget (QWidget *parent, CSMDoc::Document& document);
|
||||
|
@ -88,6 +102,8 @@ namespace CSVRender
|
|||
|
||||
virtual void addEditModeSelectorButtons (CSVWidget::SceneToolMode *tool);
|
||||
|
||||
virtual void handleMouseClick (osg::ref_ptr<TagBase> tag, const std::string& button);
|
||||
|
||||
signals:
|
||||
|
||||
void cellSelectionChanged (const CSMWorld::CellSelection& selection);
|
||||
|
|
|
@ -574,14 +574,7 @@ void CSVRender::WorldspaceWidget::mousePressEvent (QMouseEvent *event)
|
|||
{
|
||||
osg::ref_ptr<TagBase> tag = mousePick (event);
|
||||
|
||||
EditMode& editMode = dynamic_cast<CSVRender::EditMode&> (*mEditMode->getCurrent());
|
||||
|
||||
if (button=="p-edit")
|
||||
editMode.primaryEditPressed (tag);
|
||||
else if (button=="s-edit")
|
||||
editMode.secondaryEditPressed (tag);
|
||||
else if (button=="select")
|
||||
editMode.selectPressed (tag);
|
||||
handleMouseClick (tag, button);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -650,3 +643,15 @@ void CSVRender::WorldspaceWidget::keyPressEvent (QKeyEvent *event)
|
|||
else
|
||||
RenderWidget::keyPressEvent(event);
|
||||
}
|
||||
|
||||
void CSVRender::WorldspaceWidget::handleMouseClick (osg::ref_ptr<TagBase> tag, const std::string& button)
|
||||
{
|
||||
EditMode& editMode = dynamic_cast<CSVRender::EditMode&> (*mEditMode->getCurrent());
|
||||
|
||||
if (button=="p-edit")
|
||||
editMode.primaryEditPressed (tag);
|
||||
else if (button=="s-edit")
|
||||
editMode.secondaryEditPressed (tag);
|
||||
else if (button=="select")
|
||||
editMode.selectPressed (tag);
|
||||
}
|
||||
|
|
|
@ -27,6 +27,7 @@ namespace CSVWidget
|
|||
namespace CSVRender
|
||||
{
|
||||
class TagBase;
|
||||
class CellArrow;
|
||||
|
||||
class WorldspaceWidget : public SceneWidget
|
||||
{
|
||||
|
@ -132,6 +133,8 @@ namespace CSVRender
|
|||
virtual void wheelEvent (QWheelEvent *event);
|
||||
virtual void keyPressEvent (QKeyEvent *event);
|
||||
|
||||
virtual void handleMouseClick (osg::ref_ptr<TagBase> tag, const std::string& button);
|
||||
|
||||
private:
|
||||
|
||||
void dragEnterEvent(QDragEnterEvent *event);
|
||||
|
|
Loading…
Reference in a new issue