mirror of
https://github.com/TES3MP/openmw-tes3mp.git
synced 2025-01-16 19:49:56 +00:00
Merge branch 'move'
This commit is contained in:
commit
d5067201d0
30 changed files with 990 additions and 120 deletions
|
@ -26,7 +26,7 @@ opencs_units_noqt (model/world
|
||||||
universalid record commands columnbase columnimp scriptcontext cell refidcollection
|
universalid record commands columnbase columnimp scriptcontext cell refidcollection
|
||||||
refidadapter refiddata refidadapterimp ref collectionbase refcollection columns infocollection tablemimedata cellcoordinates cellselection resources resourcesmanager scope
|
refidadapter refiddata refidadapterimp ref collectionbase refcollection columns infocollection tablemimedata cellcoordinates cellselection resources resourcesmanager scope
|
||||||
pathgrid landtexture land nestedtablewrapper nestedcollection nestedcoladapterimp nestedinfocollection
|
pathgrid landtexture land nestedtablewrapper nestedcollection nestedcoladapterimp nestedinfocollection
|
||||||
idcompletionmanager metadata defaultgmsts infoselectwrapper
|
idcompletionmanager metadata defaultgmsts infoselectwrapper commandmacro
|
||||||
)
|
)
|
||||||
|
|
||||||
opencs_hdrs_noqt (model/world
|
opencs_hdrs_noqt (model/world
|
||||||
|
@ -85,7 +85,7 @@ opencs_units (view/widget
|
||||||
|
|
||||||
opencs_units (view/render
|
opencs_units (view/render
|
||||||
scenewidget worldspacewidget pagedworldspacewidget unpagedworldspacewidget
|
scenewidget worldspacewidget pagedworldspacewidget unpagedworldspacewidget
|
||||||
previewwidget editmode instancemode instanceselectionmode
|
previewwidget editmode instancemode instanceselectionmode instancemovemode
|
||||||
)
|
)
|
||||||
|
|
||||||
opencs_units_noqt (view/render
|
opencs_units_noqt (view/render
|
||||||
|
|
|
@ -1,5 +1,7 @@
|
||||||
#include "cellcoordinates.hpp"
|
#include "cellcoordinates.hpp"
|
||||||
|
|
||||||
|
#include <cmath>
|
||||||
|
|
||||||
#include <ostream>
|
#include <ostream>
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
|
|
||||||
|
@ -7,6 +9,9 @@ CSMWorld::CellCoordinates::CellCoordinates() : mX (0), mY (0) {}
|
||||||
|
|
||||||
CSMWorld::CellCoordinates::CellCoordinates (int x, int y) : mX (x), mY (y) {}
|
CSMWorld::CellCoordinates::CellCoordinates (int x, int y) : mX (x), mY (y) {}
|
||||||
|
|
||||||
|
CSMWorld::CellCoordinates::CellCoordinates (const std::pair<int, int>& coordinates)
|
||||||
|
: mX (coordinates.first), mY (coordinates.second) {}
|
||||||
|
|
||||||
int CSMWorld::CellCoordinates::getX() const
|
int CSMWorld::CellCoordinates::getX() const
|
||||||
{
|
{
|
||||||
return mX;
|
return mX;
|
||||||
|
@ -49,6 +54,13 @@ std::pair<CSMWorld::CellCoordinates, bool> CSMWorld::CellCoordinates::fromId (
|
||||||
return std::make_pair (CellCoordinates(), false);
|
return std::make_pair (CellCoordinates(), false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::pair<int, int> CSMWorld::CellCoordinates::coordinatesToCellIndex (float x, float y)
|
||||||
|
{
|
||||||
|
const int cellSize = 8192;
|
||||||
|
|
||||||
|
return std::make_pair (std::floor (x/cellSize), std::floor (y/cellSize));
|
||||||
|
}
|
||||||
|
|
||||||
bool CSMWorld::operator== (const CellCoordinates& left, const CellCoordinates& right)
|
bool CSMWorld::operator== (const CellCoordinates& left, const CellCoordinates& right)
|
||||||
{
|
{
|
||||||
return left.getX()==right.getX() && left.getY()==right.getY();
|
return left.getX()==right.getX() && left.getY()==right.getY();
|
||||||
|
|
|
@ -3,6 +3,7 @@
|
||||||
|
|
||||||
#include <iosfwd>
|
#include <iosfwd>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
#include <utility>
|
||||||
|
|
||||||
#include <QMetaType>
|
#include <QMetaType>
|
||||||
|
|
||||||
|
@ -19,6 +20,8 @@ namespace CSMWorld
|
||||||
|
|
||||||
CellCoordinates (int x, int y);
|
CellCoordinates (int x, int y);
|
||||||
|
|
||||||
|
CellCoordinates (const std::pair<int, int>& coordinates);
|
||||||
|
|
||||||
int getX() const;
|
int getX() const;
|
||||||
|
|
||||||
int getY() const;
|
int getY() const;
|
||||||
|
@ -34,6 +37,8 @@ namespace CSMWorld
|
||||||
///
|
///
|
||||||
/// \note The worldspace part of \a id is ignored
|
/// \note The worldspace part of \a id is ignored
|
||||||
static std::pair<CellCoordinates, bool> fromId (const std::string& id);
|
static std::pair<CellCoordinates, bool> fromId (const std::string& id);
|
||||||
|
|
||||||
|
static std::pair<int, int> coordinatesToCellIndex (float x, float y);
|
||||||
};
|
};
|
||||||
|
|
||||||
bool operator== (const CellCoordinates& left, const CellCoordinates& right);
|
bool operator== (const CellCoordinates& left, const CellCoordinates& right);
|
||||||
|
|
|
@ -11,6 +11,7 @@
|
||||||
#include "record.hpp"
|
#include "record.hpp"
|
||||||
#include "commands.hpp"
|
#include "commands.hpp"
|
||||||
#include "idtableproxymodel.hpp"
|
#include "idtableproxymodel.hpp"
|
||||||
|
#include "commandmacro.hpp"
|
||||||
|
|
||||||
std::vector<std::string> CSMWorld::CommandDispatcher::getDeletableRecords() const
|
std::vector<std::string> CSMWorld::CommandDispatcher::getDeletableRecords() const
|
||||||
{
|
{
|
||||||
|
@ -171,10 +172,9 @@ void CSMWorld::CommandDispatcher::executeModify (QAbstractItemModel *model, cons
|
||||||
|
|
||||||
if (modifyCell.get())
|
if (modifyCell.get())
|
||||||
{
|
{
|
||||||
mDocument.getUndoStack().beginMacro (modifyData->text());
|
CommandMacro macro (mDocument.getUndoStack());
|
||||||
mDocument.getUndoStack().push (modifyData.release());
|
macro.push (modifyData.release());
|
||||||
mDocument.getUndoStack().push (modifyCell.release());
|
macro.push (modifyCell.release());
|
||||||
mDocument.getUndoStack().endMacro();
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
mDocument.getUndoStack().push (modifyData.release());
|
mDocument.getUndoStack().push (modifyData.release());
|
||||||
|
@ -194,9 +194,7 @@ void CSMWorld::CommandDispatcher::executeDelete()
|
||||||
|
|
||||||
int columnIndex = model.findColumnIndex (Columns::ColumnId_Id);
|
int columnIndex = model.findColumnIndex (Columns::ColumnId_Id);
|
||||||
|
|
||||||
if (rows.size()>1)
|
CommandMacro macro (mDocument.getUndoStack(), rows.size()>1 ? "Delete multiple records" : "");
|
||||||
mDocument.getUndoStack().beginMacro (tr ("Delete multiple records"));
|
|
||||||
|
|
||||||
for (std::vector<std::string>::const_iterator iter (rows.begin()); iter!=rows.end(); ++iter)
|
for (std::vector<std::string>::const_iterator iter (rows.begin()); iter!=rows.end(); ++iter)
|
||||||
{
|
{
|
||||||
std::string id = model.data (model.getModelIndex (*iter, columnIndex)).
|
std::string id = model.data (model.getModelIndex (*iter, columnIndex)).
|
||||||
|
@ -204,7 +202,7 @@ void CSMWorld::CommandDispatcher::executeDelete()
|
||||||
|
|
||||||
if (mId.getType() == UniversalId::Type_Referenceables)
|
if (mId.getType() == UniversalId::Type_Referenceables)
|
||||||
{
|
{
|
||||||
mDocument.getUndoStack().push ( new CSMWorld::DeleteCommand (model, id,
|
macro.push (new CSMWorld::DeleteCommand (model, id,
|
||||||
static_cast<CSMWorld::UniversalId::Type>(model.data (model.index (
|
static_cast<CSMWorld::UniversalId::Type>(model.data (model.index (
|
||||||
model.getModelIndex (id, columnIndex).row(),
|
model.getModelIndex (id, columnIndex).row(),
|
||||||
model.findColumnIndex (CSMWorld::Columns::ColumnId_RecordType))).toInt())));
|
model.findColumnIndex (CSMWorld::Columns::ColumnId_RecordType))).toInt())));
|
||||||
|
@ -212,9 +210,6 @@ void CSMWorld::CommandDispatcher::executeDelete()
|
||||||
else
|
else
|
||||||
mDocument.getUndoStack().push (new CSMWorld::DeleteCommand (model, id));
|
mDocument.getUndoStack().push (new CSMWorld::DeleteCommand (model, id));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (rows.size()>1)
|
|
||||||
mDocument.getUndoStack().endMacro();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void CSMWorld::CommandDispatcher::executeRevert()
|
void CSMWorld::CommandDispatcher::executeRevert()
|
||||||
|
@ -231,25 +226,19 @@ void CSMWorld::CommandDispatcher::executeRevert()
|
||||||
|
|
||||||
int columnIndex = model.findColumnIndex (Columns::ColumnId_Id);
|
int columnIndex = model.findColumnIndex (Columns::ColumnId_Id);
|
||||||
|
|
||||||
if (rows.size()>1)
|
CommandMacro macro (mDocument.getUndoStack(), rows.size()>1 ? "Revert multiple records" : "");
|
||||||
mDocument.getUndoStack().beginMacro (tr ("Revert multiple records"));
|
|
||||||
|
|
||||||
for (std::vector<std::string>::const_iterator iter (rows.begin()); iter!=rows.end(); ++iter)
|
for (std::vector<std::string>::const_iterator iter (rows.begin()); iter!=rows.end(); ++iter)
|
||||||
{
|
{
|
||||||
std::string id = model.data (model.getModelIndex (*iter, columnIndex)).
|
std::string id = model.data (model.getModelIndex (*iter, columnIndex)).
|
||||||
toString().toUtf8().constData();
|
toString().toUtf8().constData();
|
||||||
|
|
||||||
mDocument.getUndoStack().push (new CSMWorld::RevertCommand (model, id));
|
macro.push (new CSMWorld::RevertCommand (model, id));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (rows.size()>1)
|
|
||||||
mDocument.getUndoStack().endMacro();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void CSMWorld::CommandDispatcher::executeExtendedDelete()
|
void CSMWorld::CommandDispatcher::executeExtendedDelete()
|
||||||
{
|
{
|
||||||
if (mExtendedTypes.size()>1)
|
CommandMacro macro (mDocument.getUndoStack(), mExtendedTypes.size()>1 ? tr ("Extended delete of multiple records") : "");
|
||||||
mDocument.getUndoStack().beginMacro (tr ("Extended delete of multiple records"));
|
|
||||||
|
|
||||||
for (std::vector<UniversalId>::const_iterator iter (mExtendedTypes.begin());
|
for (std::vector<UniversalId>::const_iterator iter (mExtendedTypes.begin());
|
||||||
iter!=mExtendedTypes.end(); ++iter)
|
iter!=mExtendedTypes.end(); ++iter)
|
||||||
|
@ -276,20 +265,15 @@ void CSMWorld::CommandDispatcher::executeExtendedDelete()
|
||||||
Misc::StringUtils::lowerCase (record.get().mCell)))
|
Misc::StringUtils::lowerCase (record.get().mCell)))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
mDocument.getUndoStack().push (
|
macro.push (new CSMWorld::DeleteCommand (model, record.get().mId));
|
||||||
new CSMWorld::DeleteCommand (model, record.get().mId));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mExtendedTypes.size()>1)
|
|
||||||
mDocument.getUndoStack().endMacro();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void CSMWorld::CommandDispatcher::executeExtendedRevert()
|
void CSMWorld::CommandDispatcher::executeExtendedRevert()
|
||||||
{
|
{
|
||||||
if (mExtendedTypes.size()>1)
|
CommandMacro macro (mDocument.getUndoStack(), mExtendedTypes.size()>1 ? tr ("Extended revert of multiple records") : "");
|
||||||
mDocument.getUndoStack().beginMacro (tr ("Extended revert of multiple records"));
|
|
||||||
|
|
||||||
for (std::vector<UniversalId>::const_iterator iter (mExtendedTypes.begin());
|
for (std::vector<UniversalId>::const_iterator iter (mExtendedTypes.begin());
|
||||||
iter!=mExtendedTypes.end(); ++iter)
|
iter!=mExtendedTypes.end(); ++iter)
|
||||||
|
@ -313,12 +297,8 @@ void CSMWorld::CommandDispatcher::executeExtendedRevert()
|
||||||
Misc::StringUtils::lowerCase (record.get().mCell)))
|
Misc::StringUtils::lowerCase (record.get().mCell)))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
mDocument.getUndoStack().push (
|
macro.push (new CSMWorld::RevertCommand (model, record.get().mId));
|
||||||
new CSMWorld::RevertCommand (model, record.get().mId));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mExtendedTypes.size()>1)
|
|
||||||
mDocument.getUndoStack().endMacro();
|
|
||||||
}
|
}
|
||||||
|
|
26
apps/opencs/model/world/commandmacro.cpp
Normal file
26
apps/opencs/model/world/commandmacro.cpp
Normal file
|
@ -0,0 +1,26 @@
|
||||||
|
|
||||||
|
#include "commandmacro.hpp"
|
||||||
|
|
||||||
|
#include <QUndoStack>
|
||||||
|
#include <QUndoCommand>
|
||||||
|
|
||||||
|
CSMWorld::CommandMacro::CommandMacro (QUndoStack& undoStack, const QString& description)
|
||||||
|
: mUndoStack (undoStack), mDescription (description), mStarted (false)
|
||||||
|
{}
|
||||||
|
|
||||||
|
CSMWorld::CommandMacro::~CommandMacro()
|
||||||
|
{
|
||||||
|
if (mStarted)
|
||||||
|
mUndoStack.endMacro();
|
||||||
|
}
|
||||||
|
|
||||||
|
void CSMWorld::CommandMacro::push (QUndoCommand *command)
|
||||||
|
{
|
||||||
|
if (!mStarted)
|
||||||
|
{
|
||||||
|
mUndoStack.beginMacro (mDescription.isEmpty() ? command->text() : mDescription);
|
||||||
|
mStarted = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
mUndoStack.push (command);
|
||||||
|
}
|
34
apps/opencs/model/world/commandmacro.hpp
Normal file
34
apps/opencs/model/world/commandmacro.hpp
Normal file
|
@ -0,0 +1,34 @@
|
||||||
|
#ifndef CSM_WOLRD_COMMANDMACRO_H
|
||||||
|
#define CSM_WOLRD_COMMANDMACRO_H
|
||||||
|
|
||||||
|
class QUndoStack;
|
||||||
|
class QUndoCommand;
|
||||||
|
|
||||||
|
#include <QString>
|
||||||
|
|
||||||
|
namespace CSMWorld
|
||||||
|
{
|
||||||
|
class CommandMacro
|
||||||
|
{
|
||||||
|
QUndoStack& mUndoStack;
|
||||||
|
QString mDescription;
|
||||||
|
bool mStarted;
|
||||||
|
|
||||||
|
/// not implemented
|
||||||
|
CommandMacro (const CommandMacro&);
|
||||||
|
|
||||||
|
/// not implemented
|
||||||
|
CommandMacro& operator= (const CommandMacro&);
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
/// If \a description is empty, the description of the first command is used.
|
||||||
|
CommandMacro (QUndoStack& undoStack, const QString& description = "");
|
||||||
|
|
||||||
|
~CommandMacro();
|
||||||
|
|
||||||
|
void push (QUndoCommand *command);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
|
@ -2,6 +2,10 @@
|
||||||
|
|
||||||
#include <cmath>
|
#include <cmath>
|
||||||
|
|
||||||
|
#include <sstream>
|
||||||
|
|
||||||
|
#include "cellcoordinates.hpp"
|
||||||
|
|
||||||
CSMWorld::CellRef::CellRef()
|
CSMWorld::CellRef::CellRef()
|
||||||
{
|
{
|
||||||
mRefNum.mIndex = 0;
|
mRefNum.mIndex = 0;
|
||||||
|
@ -10,8 +14,5 @@ CSMWorld::CellRef::CellRef()
|
||||||
|
|
||||||
std::pair<int, int> CSMWorld::CellRef::getCellIndex() const
|
std::pair<int, int> CSMWorld::CellRef::getCellIndex() const
|
||||||
{
|
{
|
||||||
const int cellSize = 8192;
|
return CellCoordinates::coordinatesToCellIndex (mPos.pos[0], mPos.pos[1]);
|
||||||
|
|
||||||
return std::make_pair (
|
|
||||||
std::floor (mPos.pos[0]/cellSize), std::floor (mPos.pos[1]/cellSize));
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -51,7 +51,12 @@ bool CSVRender::Cell::addObjects (int start, int end)
|
||||||
{
|
{
|
||||||
std::string id = Misc::StringUtils::lowerCase (collection.getRecord (i).get().mId);
|
std::string id = Misc::StringUtils::lowerCase (collection.getRecord (i).get().mId);
|
||||||
|
|
||||||
mObjects.insert (std::make_pair (id, new Object (mData, mCellNode, id, false)));
|
std::auto_ptr<Object> object (new Object (mData, mCellNode, id, false));
|
||||||
|
|
||||||
|
if (mSubModeElementMask & Mask_Reference)
|
||||||
|
object->setSubMode (mSubMode);
|
||||||
|
|
||||||
|
mObjects.insert (std::make_pair (id, object.release()));
|
||||||
modified = true;
|
modified = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -61,7 +66,8 @@ bool CSVRender::Cell::addObjects (int start, int end)
|
||||||
|
|
||||||
CSVRender::Cell::Cell (CSMWorld::Data& data, osg::Group* rootNode, const std::string& id,
|
CSVRender::Cell::Cell (CSMWorld::Data& data, osg::Group* rootNode, const std::string& id,
|
||||||
bool deleted)
|
bool deleted)
|
||||||
: mData (data), mId (Misc::StringUtils::lowerCase (id)), mDeleted (deleted)
|
: mData (data), mId (Misc::StringUtils::lowerCase (id)), mDeleted (deleted), mSubMode (0),
|
||||||
|
mSubModeElementMask (0)
|
||||||
{
|
{
|
||||||
std::pair<CSMWorld::CellCoordinates, bool> result = CSMWorld::CellCoordinates::fromId (id);
|
std::pair<CSMWorld::CellCoordinates, bool> result = CSMWorld::CellCoordinates::fromId (id);
|
||||||
|
|
||||||
|
@ -349,3 +355,35 @@ std::vector<osg::ref_ptr<CSVRender::TagBase> > CSVRender::Cell::getSelection (un
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::vector<osg::ref_ptr<CSVRender::TagBase> > CSVRender::Cell::getEdited (unsigned int elementMask) const
|
||||||
|
{
|
||||||
|
std::vector<osg::ref_ptr<TagBase> > result;
|
||||||
|
|
||||||
|
if (elementMask & Mask_Reference)
|
||||||
|
for (std::map<std::string, Object *>::const_iterator iter (mObjects.begin());
|
||||||
|
iter!=mObjects.end(); ++iter)
|
||||||
|
if (iter->second->isEdited())
|
||||||
|
result.push_back (iter->second->getTag());
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CSVRender::Cell::setSubMode (int subMode, unsigned int elementMask)
|
||||||
|
{
|
||||||
|
mSubMode = subMode;
|
||||||
|
mSubModeElementMask = elementMask;
|
||||||
|
|
||||||
|
if (elementMask & Mask_Reference)
|
||||||
|
for (std::map<std::string, Object *>::const_iterator iter (mObjects.begin());
|
||||||
|
iter!=mObjects.end(); ++iter)
|
||||||
|
iter->second->setSubMode (subMode);
|
||||||
|
}
|
||||||
|
|
||||||
|
void CSVRender::Cell::reset (unsigned int elementMask)
|
||||||
|
{
|
||||||
|
if (elementMask & Mask_Reference)
|
||||||
|
for (std::map<std::string, Object *>::const_iterator iter (mObjects.begin());
|
||||||
|
iter!=mObjects.end(); ++iter)
|
||||||
|
iter->second->reset();
|
||||||
|
}
|
||||||
|
|
|
@ -47,6 +47,8 @@ namespace CSVRender
|
||||||
std::auto_ptr<CellMarker> mCellMarker;
|
std::auto_ptr<CellMarker> mCellMarker;
|
||||||
std::auto_ptr<CellBorder> mCellBorder;
|
std::auto_ptr<CellBorder> mCellBorder;
|
||||||
bool mDeleted;
|
bool mDeleted;
|
||||||
|
int mSubMode;
|
||||||
|
unsigned int mSubModeElementMask;
|
||||||
|
|
||||||
/// Ignored if cell does not have an object with the given ID.
|
/// Ignored if cell does not have an object with the given ID.
|
||||||
///
|
///
|
||||||
|
@ -118,6 +120,14 @@ namespace CSVRender
|
||||||
bool isDeleted() const;
|
bool isDeleted() const;
|
||||||
|
|
||||||
std::vector<osg::ref_ptr<TagBase> > getSelection (unsigned int elementMask) const;
|
std::vector<osg::ref_ptr<TagBase> > getSelection (unsigned int elementMask) const;
|
||||||
|
|
||||||
|
std::vector<osg::ref_ptr<TagBase> > getEdited (unsigned int elementMask) const;
|
||||||
|
|
||||||
|
void setSubMode (int subMode, unsigned int elementMask);
|
||||||
|
|
||||||
|
/// Erase all overrides and restore the visual representation of the cell to its
|
||||||
|
/// true state.
|
||||||
|
void reset (unsigned int elementMask);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -70,3 +70,8 @@ void CSVRender::EditMode::dragEnterEvent (QDragEnterEvent *event) {}
|
||||||
void CSVRender::EditMode::dropEvent (QDropEvent* event) {}
|
void CSVRender::EditMode::dropEvent (QDropEvent* event) {}
|
||||||
|
|
||||||
void CSVRender::EditMode::dragMoveEvent (QDragMoveEvent *event) {}
|
void CSVRender::EditMode::dragMoveEvent (QDragMoveEvent *event) {}
|
||||||
|
|
||||||
|
int CSVRender::EditMode::getSubMode() const
|
||||||
|
{
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
|
@ -92,6 +92,9 @@ namespace CSVRender
|
||||||
|
|
||||||
/// Default-implementation: ignored
|
/// Default-implementation: ignored
|
||||||
virtual void dragMoveEvent (QDragMoveEvent *event);
|
virtual void dragMoveEvent (QDragMoveEvent *event);
|
||||||
|
|
||||||
|
/// Default: return -1
|
||||||
|
virtual int getSubMode() const;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -8,6 +8,7 @@
|
||||||
#include "../../model/world/idtable.hpp"
|
#include "../../model/world/idtable.hpp"
|
||||||
#include "../../model/world/idtree.hpp"
|
#include "../../model/world/idtree.hpp"
|
||||||
#include "../../model/world/commands.hpp"
|
#include "../../model/world/commands.hpp"
|
||||||
|
#include "../../model/world/commandmacro.hpp"
|
||||||
|
|
||||||
#include "../widget/scenetoolbar.hpp"
|
#include "../widget/scenetoolbar.hpp"
|
||||||
#include "../widget/scenetoolmode.hpp"
|
#include "../widget/scenetoolmode.hpp"
|
||||||
|
@ -18,10 +19,17 @@
|
||||||
#include "worldspacewidget.hpp"
|
#include "worldspacewidget.hpp"
|
||||||
#include "pagedworldspacewidget.hpp"
|
#include "pagedworldspacewidget.hpp"
|
||||||
#include "instanceselectionmode.hpp"
|
#include "instanceselectionmode.hpp"
|
||||||
|
#include "instancemovemode.hpp"
|
||||||
|
|
||||||
|
int CSVRender::InstanceMode::getSubModeFromId (const std::string& id) const
|
||||||
|
{
|
||||||
|
return id=="move" ? 0 : (id=="rotate" ? 1 : 2);
|
||||||
|
}
|
||||||
|
|
||||||
CSVRender::InstanceMode::InstanceMode (WorldspaceWidget *worldspaceWidget, QWidget *parent)
|
CSVRender::InstanceMode::InstanceMode (WorldspaceWidget *worldspaceWidget, QWidget *parent)
|
||||||
: EditMode (worldspaceWidget, QIcon (":placeholder"), Mask_Reference, "Instance editing",
|
: EditMode (worldspaceWidget, QIcon (":placeholder"), Mask_Reference, "Instance editing",
|
||||||
parent), mSubMode (0), mSelectionMode (0)
|
parent), mSubMode (0), mSubModeId ("move"), mSelectionMode (0), mDragMode (DragMode_None),
|
||||||
|
mDragAxis (-1), mLocked (false)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -30,12 +38,7 @@ void CSVRender::InstanceMode::activate (CSVWidget::SceneToolbar *toolbar)
|
||||||
if (!mSubMode)
|
if (!mSubMode)
|
||||||
{
|
{
|
||||||
mSubMode = new CSVWidget::SceneToolMode (toolbar, "Edit Sub-Mode");
|
mSubMode = new CSVWidget::SceneToolMode (toolbar, "Edit Sub-Mode");
|
||||||
mSubMode->addButton (":placeholder", "move",
|
mSubMode->addButton (new InstanceMoveMode (this), "move");
|
||||||
"Move selected instances"
|
|
||||||
"<ul><li>Use primary edit to move instances around freely</li>"
|
|
||||||
"<li>Use secondary edit to move instances around within the grid</li>"
|
|
||||||
"</ul>"
|
|
||||||
"<font color=Red>Not implemented yet</font color>");
|
|
||||||
mSubMode->addButton (":placeholder", "rotate",
|
mSubMode->addButton (":placeholder", "rotate",
|
||||||
"Rotate selected instances"
|
"Rotate selected instances"
|
||||||
"<ul><li>Use primary edit to rotate instances freely</li>"
|
"<ul><li>Use primary edit to rotate instances freely</li>"
|
||||||
|
@ -48,19 +51,33 @@ void CSVRender::InstanceMode::activate (CSVWidget::SceneToolbar *toolbar)
|
||||||
"<li>Use secondary edit to scale instances along the grid</li>"
|
"<li>Use secondary edit to scale instances along the grid</li>"
|
||||||
"</ul>"
|
"</ul>"
|
||||||
"<font color=Red>Not implemented yet</font color>");
|
"<font color=Red>Not implemented yet</font color>");
|
||||||
|
|
||||||
|
mSubMode->setButton (mSubModeId);
|
||||||
|
|
||||||
|
connect (mSubMode, SIGNAL (modeChanged (const std::string&)),
|
||||||
|
this, SLOT (subModeChanged (const std::string&)));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!mSelectionMode)
|
if (!mSelectionMode)
|
||||||
mSelectionMode = new InstanceSelectionMode (toolbar, getWorldspaceWidget());
|
mSelectionMode = new InstanceSelectionMode (toolbar, getWorldspaceWidget());
|
||||||
|
|
||||||
|
mDragMode = DragMode_None;
|
||||||
|
|
||||||
EditMode::activate (toolbar);
|
EditMode::activate (toolbar);
|
||||||
|
|
||||||
toolbar->addTool (mSubMode);
|
toolbar->addTool (mSubMode);
|
||||||
toolbar->addTool (mSelectionMode);
|
toolbar->addTool (mSelectionMode);
|
||||||
|
|
||||||
|
std::string subMode = mSubMode->getCurrentId();
|
||||||
|
|
||||||
|
getWorldspaceWidget().setSubMode (getSubModeFromId (subMode), Mask_Reference);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CSVRender::InstanceMode::deactivate (CSVWidget::SceneToolbar *toolbar)
|
void CSVRender::InstanceMode::deactivate (CSVWidget::SceneToolbar *toolbar)
|
||||||
{
|
{
|
||||||
|
mDragMode = DragMode_None;
|
||||||
|
getWorldspaceWidget().reset (Mask_Reference);
|
||||||
|
|
||||||
if (mSelectionMode)
|
if (mSelectionMode)
|
||||||
{
|
{
|
||||||
toolbar->removeTool (mSelectionMode);
|
toolbar->removeTool (mSelectionMode);
|
||||||
|
@ -78,6 +95,14 @@ void CSVRender::InstanceMode::deactivate (CSVWidget::SceneToolbar *toolbar)
|
||||||
EditMode::deactivate (toolbar);
|
EditMode::deactivate (toolbar);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CSVRender::InstanceMode::setEditLock (bool locked)
|
||||||
|
{
|
||||||
|
mLocked = locked;
|
||||||
|
|
||||||
|
if (mLocked)
|
||||||
|
getWorldspaceWidget().abortDrag();
|
||||||
|
}
|
||||||
|
|
||||||
void CSVRender::InstanceMode::primaryEditPressed (osg::ref_ptr<TagBase> tag)
|
void CSVRender::InstanceMode::primaryEditPressed (osg::ref_ptr<TagBase> tag)
|
||||||
{
|
{
|
||||||
if (CSMPrefs::get()["3D Scene Input"]["context-select"].isTrue())
|
if (CSMPrefs::get()["3D Scene Input"]["context-select"].isTrue())
|
||||||
|
@ -120,6 +145,173 @@ void CSVRender::InstanceMode::secondarySelectPressed (osg::ref_ptr<TagBase> tag)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool CSVRender::InstanceMode::primaryEditStartDrag (osg::ref_ptr<TagBase> tag)
|
||||||
|
{
|
||||||
|
if (mDragMode!=DragMode_None || mLocked)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (tag && CSMPrefs::get()["3D Scene Input"]["context-select"].isTrue())
|
||||||
|
{
|
||||||
|
getWorldspaceWidget().clearSelection (Mask_Reference);
|
||||||
|
if (CSVRender::ObjectTag *objectTag = dynamic_cast<CSVRender::ObjectTag *> (tag.get()))
|
||||||
|
{
|
||||||
|
CSVRender::Object* object = objectTag->mObject;
|
||||||
|
object->setSelected (true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<osg::ref_ptr<TagBase> > selection =
|
||||||
|
getWorldspaceWidget().getSelection (Mask_Reference);
|
||||||
|
|
||||||
|
if (selection.empty())
|
||||||
|
return false;
|
||||||
|
|
||||||
|
for (std::vector<osg::ref_ptr<TagBase> >::iterator iter (selection.begin());
|
||||||
|
iter!=selection.end(); ++iter)
|
||||||
|
{
|
||||||
|
if (CSVRender::ObjectTag *objectTag = dynamic_cast<CSVRender::ObjectTag *> (iter->get()))
|
||||||
|
{
|
||||||
|
objectTag->mObject->setEdited (Object::Override_Position);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// \todo check for sub-mode
|
||||||
|
|
||||||
|
if (CSVRender::ObjectMarkerTag *objectTag = dynamic_cast<CSVRender::ObjectMarkerTag *> (tag.get()))
|
||||||
|
{
|
||||||
|
mDragAxis = objectTag->mAxis;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
mDragAxis = -1;
|
||||||
|
|
||||||
|
mDragMode = DragMode_Move;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CSVRender::InstanceMode::secondaryEditStartDrag (osg::ref_ptr<TagBase> tag)
|
||||||
|
{
|
||||||
|
if (mLocked)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CSVRender::InstanceMode::drag (int diffX, int diffY, double speedFactor)
|
||||||
|
{
|
||||||
|
osg::Vec3f eye;
|
||||||
|
osg::Vec3f centre;
|
||||||
|
osg::Vec3f up;
|
||||||
|
|
||||||
|
getWorldspaceWidget().getCamera()->getViewMatrix().getLookAt (eye, centre, up);
|
||||||
|
|
||||||
|
osg::Vec3f offset;
|
||||||
|
|
||||||
|
if (diffY)
|
||||||
|
offset += up * diffY * speedFactor;
|
||||||
|
|
||||||
|
if (diffX)
|
||||||
|
offset += ((centre-eye) ^ up) * diffX * speedFactor;
|
||||||
|
|
||||||
|
switch (mDragMode)
|
||||||
|
{
|
||||||
|
case DragMode_Move:
|
||||||
|
{
|
||||||
|
if (mDragAxis!=-1)
|
||||||
|
for (int i=0; i<3; ++i)
|
||||||
|
if (i!=mDragAxis)
|
||||||
|
offset[i] = 0;
|
||||||
|
|
||||||
|
std::vector<osg::ref_ptr<TagBase> > selection =
|
||||||
|
getWorldspaceWidget().getEdited (Mask_Reference);
|
||||||
|
|
||||||
|
for (std::vector<osg::ref_ptr<TagBase> >::iterator iter (selection.begin());
|
||||||
|
iter!=selection.end(); ++iter)
|
||||||
|
{
|
||||||
|
if (CSVRender::ObjectTag *objectTag = dynamic_cast<CSVRender::ObjectTag *> (iter->get()))
|
||||||
|
{
|
||||||
|
ESM::Position position = objectTag->mObject->getPosition();
|
||||||
|
for (int i=0; i<3; ++i)
|
||||||
|
position.pos[i] += offset[i];
|
||||||
|
objectTag->mObject->setPosition (position.pos);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case DragMode_None: break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void CSVRender::InstanceMode::dragCompleted()
|
||||||
|
{
|
||||||
|
std::vector<osg::ref_ptr<TagBase> > selection =
|
||||||
|
getWorldspaceWidget().getEdited (Mask_Reference);
|
||||||
|
|
||||||
|
QUndoStack& undoStack = getWorldspaceWidget().getDocument().getUndoStack();
|
||||||
|
|
||||||
|
QString description;
|
||||||
|
|
||||||
|
switch (mDragMode)
|
||||||
|
{
|
||||||
|
case DragMode_Move: description = "Move Instances"; break;
|
||||||
|
|
||||||
|
case DragMode_None: break;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
CSMWorld::CommandMacro macro (undoStack, description);
|
||||||
|
|
||||||
|
for (std::vector<osg::ref_ptr<TagBase> >::iterator iter (selection.begin());
|
||||||
|
iter!=selection.end(); ++iter)
|
||||||
|
{
|
||||||
|
if (CSVRender::ObjectTag *objectTag = dynamic_cast<CSVRender::ObjectTag *> (iter->get()))
|
||||||
|
{
|
||||||
|
objectTag->mObject->apply (macro);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
mDragMode = DragMode_None;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CSVRender::InstanceMode::dragAborted()
|
||||||
|
{
|
||||||
|
getWorldspaceWidget().reset (Mask_Reference);
|
||||||
|
mDragMode = DragMode_None;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CSVRender::InstanceMode::dragWheel (int diff, double speedFactor)
|
||||||
|
{
|
||||||
|
if (mDragMode==DragMode_Move)
|
||||||
|
{
|
||||||
|
osg::Vec3f eye;
|
||||||
|
osg::Vec3f centre;
|
||||||
|
osg::Vec3f up;
|
||||||
|
|
||||||
|
getWorldspaceWidget().getCamera()->getViewMatrix().getLookAt (eye, centre, up);
|
||||||
|
|
||||||
|
osg::Vec3f offset = centre - eye;
|
||||||
|
offset.normalize();
|
||||||
|
offset *= diff * speedFactor;
|
||||||
|
|
||||||
|
std::vector<osg::ref_ptr<TagBase> > selection =
|
||||||
|
getWorldspaceWidget().getEdited (Mask_Reference);
|
||||||
|
|
||||||
|
for (std::vector<osg::ref_ptr<TagBase> >::iterator iter (selection.begin());
|
||||||
|
iter!=selection.end(); ++iter)
|
||||||
|
{
|
||||||
|
if (CSVRender::ObjectTag *objectTag = dynamic_cast<CSVRender::ObjectTag *> (iter->get()))
|
||||||
|
{
|
||||||
|
ESM::Position position = objectTag->mObject->getPosition();
|
||||||
|
for (int i=0; i<3; ++i)
|
||||||
|
position.pos[i] += offset[i];
|
||||||
|
objectTag->mObject->setPosition (position.pos);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void CSVRender::InstanceMode::dragEnterEvent (QDragEnterEvent *event)
|
void CSVRender::InstanceMode::dragEnterEvent (QDragEnterEvent *event)
|
||||||
{
|
{
|
||||||
if (const CSMWorld::TableMimeData* mime = dynamic_cast<const CSMWorld::TableMimeData*> (event->mimeData()))
|
if (const CSMWorld::TableMimeData* mime = dynamic_cast<const CSMWorld::TableMimeData*> (event->mimeData()))
|
||||||
|
@ -243,11 +435,10 @@ void CSVRender::InstanceMode::dropEvent (QDropEvent* event)
|
||||||
new CSMWorld::ModifyCommand (cellTable, countIndex, count+1));
|
new CSMWorld::ModifyCommand (cellTable, countIndex, count+1));
|
||||||
}
|
}
|
||||||
|
|
||||||
document.getUndoStack().beginMacro (createCommand->text());
|
CSMWorld::CommandMacro macro (document.getUndoStack());
|
||||||
document.getUndoStack().push (createCommand.release());
|
macro.push (createCommand.release());
|
||||||
if (incrementCommand.get())
|
if (incrementCommand.get())
|
||||||
document.getUndoStack().push (incrementCommand.release());
|
macro.push (incrementCommand.release());
|
||||||
document.getUndoStack().endMacro();
|
|
||||||
|
|
||||||
dropped = true;
|
dropped = true;
|
||||||
}
|
}
|
||||||
|
@ -256,3 +447,15 @@ void CSVRender::InstanceMode::dropEvent (QDropEvent* event)
|
||||||
event->accept();
|
event->accept();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int CSVRender::InstanceMode::getSubMode() const
|
||||||
|
{
|
||||||
|
return mSubMode ? getSubModeFromId (mSubMode->getCurrentId()) : 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CSVRender::InstanceMode::subModeChanged (const std::string& id)
|
||||||
|
{
|
||||||
|
mSubModeId = id;
|
||||||
|
getWorldspaceWidget().abortDrag();
|
||||||
|
getWorldspaceWidget().setSubMode (getSubModeFromId (id), Mask_Reference);
|
||||||
|
}
|
||||||
|
|
|
@ -15,8 +15,21 @@ namespace CSVRender
|
||||||
class InstanceMode : public EditMode
|
class InstanceMode : public EditMode
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
|
enum DragMode
|
||||||
|
{
|
||||||
|
DragMode_None,
|
||||||
|
DragMode_Move
|
||||||
|
};
|
||||||
|
|
||||||
CSVWidget::SceneToolMode *mSubMode;
|
CSVWidget::SceneToolMode *mSubMode;
|
||||||
|
std::string mSubModeId;
|
||||||
InstanceSelectionMode *mSelectionMode;
|
InstanceSelectionMode *mSelectionMode;
|
||||||
|
DragMode mDragMode;
|
||||||
|
int mDragAxis;
|
||||||
|
bool mLocked;
|
||||||
|
|
||||||
|
int getSubModeFromId (const std::string& id) const;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
|
@ -26,6 +39,8 @@ namespace CSVRender
|
||||||
|
|
||||||
virtual void deactivate (CSVWidget::SceneToolbar *toolbar);
|
virtual void deactivate (CSVWidget::SceneToolbar *toolbar);
|
||||||
|
|
||||||
|
virtual void setEditLock (bool locked);
|
||||||
|
|
||||||
virtual void primaryEditPressed (osg::ref_ptr<TagBase> tag);
|
virtual void primaryEditPressed (osg::ref_ptr<TagBase> tag);
|
||||||
|
|
||||||
virtual void secondaryEditPressed (osg::ref_ptr<TagBase> tag);
|
virtual void secondaryEditPressed (osg::ref_ptr<TagBase> tag);
|
||||||
|
@ -34,9 +49,29 @@ namespace CSVRender
|
||||||
|
|
||||||
virtual void secondarySelectPressed (osg::ref_ptr<TagBase> tag);
|
virtual void secondarySelectPressed (osg::ref_ptr<TagBase> tag);
|
||||||
|
|
||||||
|
virtual bool primaryEditStartDrag (osg::ref_ptr<TagBase> tag);
|
||||||
|
|
||||||
|
virtual bool secondaryEditStartDrag (osg::ref_ptr<TagBase> tag);
|
||||||
|
|
||||||
|
virtual void drag (int diffX, int diffY, double speedFactor);
|
||||||
|
|
||||||
|
virtual void dragCompleted();
|
||||||
|
|
||||||
|
/// \note dragAborted will not be called, if the drag is aborted via changing
|
||||||
|
/// editing mode
|
||||||
|
virtual void dragAborted();
|
||||||
|
|
||||||
|
virtual void dragWheel (int diff, double speedFactor);
|
||||||
|
|
||||||
virtual void dragEnterEvent (QDragEnterEvent *event);
|
virtual void dragEnterEvent (QDragEnterEvent *event);
|
||||||
|
|
||||||
virtual void dropEvent (QDropEvent* event);
|
virtual void dropEvent (QDropEvent* event);
|
||||||
|
|
||||||
|
virtual int getSubMode() const;
|
||||||
|
|
||||||
|
private slots:
|
||||||
|
|
||||||
|
void subModeChanged (const std::string& id);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
12
apps/opencs/view/render/instancemovemode.cpp
Normal file
12
apps/opencs/view/render/instancemovemode.cpp
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
|
||||||
|
#include "instancemovemode.hpp"
|
||||||
|
|
||||||
|
CSVRender::InstanceMoveMode::InstanceMoveMode (QWidget *parent)
|
||||||
|
: ModeButton (QIcon (QPixmap (":placeholder")),
|
||||||
|
"Move selected instances"
|
||||||
|
"<ul><li>Use primary edit to move instances around freely</li>"
|
||||||
|
"<li>Use secondary edit to move instances around within the grid</li>"
|
||||||
|
"</ul>"
|
||||||
|
"<font color=Red>Grid move not implemented yet</font color>",
|
||||||
|
parent)
|
||||||
|
{}
|
18
apps/opencs/view/render/instancemovemode.hpp
Normal file
18
apps/opencs/view/render/instancemovemode.hpp
Normal file
|
@ -0,0 +1,18 @@
|
||||||
|
#ifndef CSV_RENDER_INSTANCEMOVEMODE_H
|
||||||
|
#define CSV_RENDER_INSTANCEMOVEMODE_H
|
||||||
|
|
||||||
|
#include "../widget/modebutton.hpp"
|
||||||
|
|
||||||
|
namespace CSVRender
|
||||||
|
{
|
||||||
|
class InstanceMoveMode : public CSVWidget::ModeButton
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
InstanceMoveMode (QWidget *parent = 0);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
|
@ -9,12 +9,18 @@
|
||||||
#include <osg/ShapeDrawable>
|
#include <osg/ShapeDrawable>
|
||||||
#include <osg/Shape>
|
#include <osg/Shape>
|
||||||
#include <osg/Geode>
|
#include <osg/Geode>
|
||||||
|
#include <osg/Geometry>
|
||||||
|
#include <osg/PrimitiveSet>
|
||||||
|
|
||||||
#include <osgFX/Scribe>
|
#include <osgFX/Scribe>
|
||||||
|
|
||||||
#include "../../model/world/data.hpp"
|
#include "../../model/world/data.hpp"
|
||||||
#include "../../model/world/ref.hpp"
|
#include "../../model/world/ref.hpp"
|
||||||
#include "../../model/world/refidcollection.hpp"
|
#include "../../model/world/refidcollection.hpp"
|
||||||
|
#include "../../model/world/commands.hpp"
|
||||||
|
#include "../../model/world/universalid.hpp"
|
||||||
|
#include "../../model/world/commandmacro.hpp"
|
||||||
|
#include "../../model/world/cellcoordinates.hpp"
|
||||||
|
|
||||||
#include <components/resource/scenemanager.hpp>
|
#include <components/resource/scenemanager.hpp>
|
||||||
#include <components/sceneutil/lightutil.hpp>
|
#include <components/sceneutil/lightutil.hpp>
|
||||||
|
@ -50,6 +56,11 @@ QString CSVRender::ObjectTag::getToolTip (bool hideBasics) const
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
CSVRender::ObjectMarkerTag::ObjectMarkerTag (Object* object, int axis)
|
||||||
|
: ObjectTag (object), mAxis (axis)
|
||||||
|
{}
|
||||||
|
|
||||||
|
|
||||||
void CSVRender::Object::clear()
|
void CSVRender::Object::clear()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
@ -130,18 +141,20 @@ void CSVRender::Object::adjustTransform()
|
||||||
if (mReferenceId.empty())
|
if (mReferenceId.empty())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
const CSMWorld::CellRef& reference = getReference();
|
ESM::Position position = getPosition();
|
||||||
|
|
||||||
// position
|
// position
|
||||||
mBaseNode->setPosition(mForceBaseToZero ? osg::Vec3() : osg::Vec3f(reference.mPos.pos[0], reference.mPos.pos[1], reference.mPos.pos[2]));
|
mRootNode->setPosition(mForceBaseToZero ? osg::Vec3() : osg::Vec3f(position.pos[0], position.pos[1], position.pos[2]));
|
||||||
|
|
||||||
// orientation
|
// orientation
|
||||||
osg::Quat xr (-reference.mPos.rot[0], osg::Vec3f(1,0,0));
|
osg::Quat xr (-position.rot[0], osg::Vec3f(1,0,0));
|
||||||
osg::Quat yr (-reference.mPos.rot[1], osg::Vec3f(0,1,0));
|
osg::Quat yr (-position.rot[1], osg::Vec3f(0,1,0));
|
||||||
osg::Quat zr (-reference.mPos.rot[2], osg::Vec3f(0,0,1));
|
osg::Quat zr (-position.rot[2], osg::Vec3f(0,0,1));
|
||||||
mBaseNode->setAttitude(zr*yr*xr);
|
mBaseNode->setAttitude(zr*yr*xr);
|
||||||
|
|
||||||
mBaseNode->setScale(osg::Vec3(reference.mScale, reference.mScale, reference.mScale));
|
float scale = getScale();
|
||||||
|
|
||||||
|
mBaseNode->setScale(osg::Vec3(scale, scale, scale));
|
||||||
}
|
}
|
||||||
|
|
||||||
const CSMWorld::CellRef& CSVRender::Object::getReference() const
|
const CSMWorld::CellRef& CSVRender::Object::getReference() const
|
||||||
|
@ -152,10 +165,147 @@ const CSMWorld::CellRef& CSVRender::Object::getReference() const
|
||||||
return mData.getReferences().getRecord (mReferenceId).get();
|
return mData.getReferences().getRecord (mReferenceId).get();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CSVRender::Object::updateMarker()
|
||||||
|
{
|
||||||
|
for (int i=0; i<3; ++i)
|
||||||
|
{
|
||||||
|
if (mMarker[i])
|
||||||
|
{
|
||||||
|
mRootNode->removeChild (mMarker[i]);
|
||||||
|
mMarker[i] = osg::ref_ptr<osg::Node>();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mSelected)
|
||||||
|
{
|
||||||
|
if (mSubMode==0)
|
||||||
|
{
|
||||||
|
mMarker[i] = makeMarker (i);
|
||||||
|
mMarker[i]->setUserData(new ObjectMarkerTag (this, i));
|
||||||
|
|
||||||
|
mRootNode->addChild (mMarker[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
osg::ref_ptr<osg::Node> CSVRender::Object::makeMarker (int axis)
|
||||||
|
{
|
||||||
|
osg::ref_ptr<osg::Geometry> geometry (new osg::Geometry);
|
||||||
|
|
||||||
|
const float shaftWidth = 10;
|
||||||
|
const float shaftBaseLength = 50;
|
||||||
|
const float headWidth = 30;
|
||||||
|
const float headLength = 30;
|
||||||
|
|
||||||
|
float shaftLength = shaftBaseLength + mBaseNode->getBound().radius();
|
||||||
|
|
||||||
|
// shaft
|
||||||
|
osg::Vec3Array *vertices = new osg::Vec3Array;
|
||||||
|
|
||||||
|
for (int i=0; i<2; ++i)
|
||||||
|
{
|
||||||
|
float length = i ? shaftLength : 0;
|
||||||
|
|
||||||
|
vertices->push_back (getMarkerPosition (-shaftWidth/2, -shaftWidth/2, length, axis));
|
||||||
|
vertices->push_back (getMarkerPosition (-shaftWidth/2, shaftWidth/2, length, axis));
|
||||||
|
vertices->push_back (getMarkerPosition (shaftWidth/2, shaftWidth/2, length, axis));
|
||||||
|
vertices->push_back (getMarkerPosition (shaftWidth/2, -shaftWidth/2, length, axis));
|
||||||
|
}
|
||||||
|
|
||||||
|
// head backside
|
||||||
|
vertices->push_back (getMarkerPosition (-headWidth/2, -headWidth/2, shaftLength, axis));
|
||||||
|
vertices->push_back (getMarkerPosition (-headWidth/2, headWidth/2, shaftLength, axis));
|
||||||
|
vertices->push_back (getMarkerPosition (headWidth/2, headWidth/2, shaftLength, axis));
|
||||||
|
vertices->push_back (getMarkerPosition (headWidth/2, -headWidth/2, shaftLength, axis));
|
||||||
|
|
||||||
|
// head
|
||||||
|
vertices->push_back (getMarkerPosition (0, 0, shaftLength+headLength, axis));
|
||||||
|
|
||||||
|
geometry->setVertexArray (vertices);
|
||||||
|
|
||||||
|
osg::DrawElementsUShort *primitives = new osg::DrawElementsUShort (osg::PrimitiveSet::TRIANGLES, 0);
|
||||||
|
|
||||||
|
// shaft
|
||||||
|
for (int i=0; i<4; ++i)
|
||||||
|
{
|
||||||
|
int i2 = i==3 ? 0 : i+1;
|
||||||
|
primitives->push_back (i);
|
||||||
|
primitives->push_back (4+i);
|
||||||
|
primitives->push_back (i2);
|
||||||
|
|
||||||
|
primitives->push_back (4+i);
|
||||||
|
primitives->push_back (4+i2);
|
||||||
|
primitives->push_back (i2);
|
||||||
|
}
|
||||||
|
|
||||||
|
// cap
|
||||||
|
primitives->push_back (0);
|
||||||
|
primitives->push_back (1);
|
||||||
|
primitives->push_back (2);
|
||||||
|
|
||||||
|
primitives->push_back (2);
|
||||||
|
primitives->push_back (3);
|
||||||
|
primitives->push_back (0);
|
||||||
|
|
||||||
|
// head, backside
|
||||||
|
primitives->push_back (0+8);
|
||||||
|
primitives->push_back (1+8);
|
||||||
|
primitives->push_back (2+8);
|
||||||
|
|
||||||
|
primitives->push_back (2+8);
|
||||||
|
primitives->push_back (3+8);
|
||||||
|
primitives->push_back (0+8);
|
||||||
|
|
||||||
|
for (int i=0; i<4; ++i)
|
||||||
|
{
|
||||||
|
primitives->push_back (12);
|
||||||
|
primitives->push_back (8+(i==3 ? 0 : i+1));
|
||||||
|
primitives->push_back (8+i);
|
||||||
|
}
|
||||||
|
|
||||||
|
geometry->addPrimitiveSet (primitives);
|
||||||
|
|
||||||
|
osg::Vec4Array *colours = new osg::Vec4Array;
|
||||||
|
|
||||||
|
for (int i=0; i<8; ++i)
|
||||||
|
colours->push_back (osg::Vec4f (axis==0 ? 1.0f : 0.2f, axis==1 ? 1.0f : 0.2f,
|
||||||
|
axis==2 ? 1.0f : 0.2f, 1.0f));
|
||||||
|
|
||||||
|
for (int i=8; i<8+4+1; ++i)
|
||||||
|
colours->push_back (osg::Vec4f (axis==0 ? 1.0f : 0.0f, axis==1 ? 1.0f : 0.0f,
|
||||||
|
axis==2 ? 1.0f : 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);
|
||||||
|
|
||||||
|
return geode;
|
||||||
|
}
|
||||||
|
|
||||||
|
osg::Vec3f CSVRender::Object::getMarkerPosition (float x, float y, float z, int axis)
|
||||||
|
{
|
||||||
|
switch (axis)
|
||||||
|
{
|
||||||
|
case 2: return osg::Vec3f (x, y, z);
|
||||||
|
case 0: return osg::Vec3f (z, x, y);
|
||||||
|
case 1: return osg::Vec3f (y, z, x);
|
||||||
|
|
||||||
|
default:
|
||||||
|
|
||||||
|
throw std::logic_error ("invalid axis for marker geometry");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
CSVRender::Object::Object (CSMWorld::Data& data, osg::Group* parentNode,
|
CSVRender::Object::Object (CSMWorld::Data& data, osg::Group* parentNode,
|
||||||
const std::string& id, bool referenceable, bool forceBaseToZero)
|
const std::string& id, bool referenceable, bool forceBaseToZero)
|
||||||
: mData (data), mBaseNode(0), mSelected(false), mParentNode(parentNode), mResourceSystem(data.getResourceSystem().get()), mForceBaseToZero (forceBaseToZero)
|
: mData (data), mBaseNode(0), mSelected(false), mParentNode(parentNode), mResourceSystem(data.getResourceSystem().get()), mForceBaseToZero (forceBaseToZero),
|
||||||
|
mScaleOverride (1), mOverrideFlags (0), mSubMode (-1)
|
||||||
{
|
{
|
||||||
|
mRootNode = new osg::PositionAttitudeTransform;
|
||||||
|
|
||||||
mBaseNode = new osg::PositionAttitudeTransform;
|
mBaseNode = new osg::PositionAttitudeTransform;
|
||||||
mBaseNode->addCullCallback(new SceneUtil::LightListCallback);
|
mBaseNode->addCullCallback(new SceneUtil::LightListCallback);
|
||||||
|
|
||||||
|
@ -163,9 +313,11 @@ CSVRender::Object::Object (CSMWorld::Data& data, osg::Group* parentNode,
|
||||||
|
|
||||||
mBaseNode->setUserData(new ObjectTag(this));
|
mBaseNode->setUserData(new ObjectTag(this));
|
||||||
|
|
||||||
parentNode->addChild(mBaseNode);
|
mRootNode->addChild (mBaseNode);
|
||||||
|
|
||||||
mBaseNode->setNodeMask(Mask_Reference);
|
parentNode->addChild (mRootNode);
|
||||||
|
|
||||||
|
mRootNode->setNodeMask(Mask_Reference);
|
||||||
|
|
||||||
if (referenceable)
|
if (referenceable)
|
||||||
{
|
{
|
||||||
|
@ -179,14 +331,14 @@ CSVRender::Object::Object (CSMWorld::Data& data, osg::Group* parentNode,
|
||||||
|
|
||||||
adjustTransform();
|
adjustTransform();
|
||||||
update();
|
update();
|
||||||
|
updateMarker();
|
||||||
}
|
}
|
||||||
|
|
||||||
CSVRender::Object::~Object()
|
CSVRender::Object::~Object()
|
||||||
{
|
{
|
||||||
clear();
|
clear();
|
||||||
|
|
||||||
mParentNode->removeChild(mBaseNode);
|
mParentNode->removeChild (mRootNode);
|
||||||
mParentNode->removeChild(mOutline);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void CSVRender::Object::setSelected(bool selected)
|
void CSVRender::Object::setSelected(bool selected)
|
||||||
|
@ -194,15 +346,17 @@ void CSVRender::Object::setSelected(bool selected)
|
||||||
mSelected = selected;
|
mSelected = selected;
|
||||||
|
|
||||||
mOutline->removeChild(mBaseNode);
|
mOutline->removeChild(mBaseNode);
|
||||||
mParentNode->removeChild(mOutline);
|
mRootNode->removeChild(mOutline);
|
||||||
mParentNode->removeChild(mBaseNode);
|
mRootNode->removeChild(mBaseNode);
|
||||||
if (selected)
|
if (selected)
|
||||||
{
|
{
|
||||||
mOutline->addChild(mBaseNode);
|
mOutline->addChild(mBaseNode);
|
||||||
mParentNode->addChild(mOutline);
|
mRootNode->addChild(mOutline);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
mParentNode->addChild(mBaseNode);
|
mRootNode->addChild(mBaseNode);
|
||||||
|
|
||||||
|
updateMarker();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CSVRender::Object::getSelected() const
|
bool CSVRender::Object::getSelected() const
|
||||||
|
@ -221,6 +375,7 @@ bool CSVRender::Object::referenceableDataChanged (const QModelIndex& topLeft,
|
||||||
{
|
{
|
||||||
adjustTransform();
|
adjustTransform();
|
||||||
update();
|
update();
|
||||||
|
updateMarker();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -271,6 +426,7 @@ bool CSVRender::Object::referenceDataChanged (const QModelIndex& topLeft,
|
||||||
references.getData (index, columnIndex).toString().toUtf8().constData();
|
references.getData (index, columnIndex).toString().toUtf8().constData();
|
||||||
|
|
||||||
update();
|
update();
|
||||||
|
updateMarker();
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
@ -293,3 +449,148 @@ osg::ref_ptr<CSVRender::TagBase> CSVRender::Object::getTag() const
|
||||||
{
|
{
|
||||||
return static_cast<CSVRender::TagBase *> (mBaseNode->getUserData());
|
return static_cast<CSVRender::TagBase *> (mBaseNode->getUserData());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool CSVRender::Object::isEdited() const
|
||||||
|
{
|
||||||
|
return mOverrideFlags;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CSVRender::Object::setEdited (int flags)
|
||||||
|
{
|
||||||
|
bool discard = mOverrideFlags & ~flags;
|
||||||
|
int added = flags & ~mOverrideFlags;
|
||||||
|
|
||||||
|
mOverrideFlags = flags;
|
||||||
|
|
||||||
|
if (added & Override_Position)
|
||||||
|
for (int i=0; i<3; ++i)
|
||||||
|
mPositionOverride.pos[i] = getReference().mPos.pos[i];
|
||||||
|
|
||||||
|
if (added & Override_Rotation)
|
||||||
|
for (int i=0; i<3; ++i)
|
||||||
|
mPositionOverride.rot[i] = getReference().mPos.rot[i];
|
||||||
|
|
||||||
|
if (added & Override_Scale)
|
||||||
|
mScaleOverride = getReference().mScale;
|
||||||
|
|
||||||
|
if (discard)
|
||||||
|
adjustTransform();
|
||||||
|
}
|
||||||
|
|
||||||
|
ESM::Position CSVRender::Object::getPosition() const
|
||||||
|
{
|
||||||
|
ESM::Position position = getReference().mPos;
|
||||||
|
|
||||||
|
if (mOverrideFlags & Override_Position)
|
||||||
|
for (int i=0; i<3; ++i)
|
||||||
|
position.pos[i] = mPositionOverride.pos[i];
|
||||||
|
|
||||||
|
if (mOverrideFlags & Override_Rotation)
|
||||||
|
for (int i=0; i<3; ++i)
|
||||||
|
position.rot[i] = mPositionOverride.rot[i];
|
||||||
|
|
||||||
|
return position;
|
||||||
|
}
|
||||||
|
|
||||||
|
float CSVRender::Object::getScale() const
|
||||||
|
{
|
||||||
|
return mOverrideFlags & Override_Scale ? mScaleOverride : getReference().mScale;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CSVRender::Object::setPosition (const float position[3])
|
||||||
|
{
|
||||||
|
mOverrideFlags |= Override_Position;
|
||||||
|
|
||||||
|
for (int i=0; i<3; ++i)
|
||||||
|
mPositionOverride.pos[i] = position[i];
|
||||||
|
|
||||||
|
adjustTransform();
|
||||||
|
}
|
||||||
|
|
||||||
|
void CSVRender::Object::setRotation (const float rotation[3])
|
||||||
|
{
|
||||||
|
mOverrideFlags |= Override_Rotation;
|
||||||
|
|
||||||
|
for (int i=0; i<3; ++i)
|
||||||
|
mPositionOverride.rot[i] = rotation[i];
|
||||||
|
|
||||||
|
adjustTransform();
|
||||||
|
}
|
||||||
|
|
||||||
|
void CSVRender::Object::setScale (float scale)
|
||||||
|
{
|
||||||
|
mOverrideFlags |= Override_Scale;
|
||||||
|
|
||||||
|
mScaleOverride = scale;
|
||||||
|
|
||||||
|
adjustTransform();
|
||||||
|
}
|
||||||
|
|
||||||
|
void CSVRender::Object::apply (CSMWorld::CommandMacro& commands)
|
||||||
|
{
|
||||||
|
const CSMWorld::RefCollection& collection = mData.getReferences();
|
||||||
|
QAbstractItemModel *model = mData.getTableModel (CSMWorld::UniversalId::Type_References);
|
||||||
|
|
||||||
|
int recordIndex = collection.getIndex (mReferenceId);
|
||||||
|
|
||||||
|
if (mOverrideFlags & Override_Position)
|
||||||
|
{
|
||||||
|
for (int i=0; i<3; ++i)
|
||||||
|
{
|
||||||
|
int column = collection.findColumnIndex (static_cast<CSMWorld::Columns::ColumnId> (
|
||||||
|
CSMWorld::Columns::ColumnId_PositionXPos+i));
|
||||||
|
|
||||||
|
commands.push (new CSMWorld::ModifyCommand (*model,
|
||||||
|
model->index (recordIndex, column), mPositionOverride.pos[i]));
|
||||||
|
}
|
||||||
|
|
||||||
|
int column = collection.findColumnIndex (static_cast<CSMWorld::Columns::ColumnId> (
|
||||||
|
CSMWorld::Columns::ColumnId_Cell));
|
||||||
|
|
||||||
|
std::pair<int, int> cellIndex = collection.getRecord (recordIndex).get().getCellIndex();
|
||||||
|
|
||||||
|
/// \todo figure out worldspace (not important until multiple worldspaces are supported)
|
||||||
|
std::string cellId = CSMWorld::CellCoordinates (cellIndex).getId ("");
|
||||||
|
|
||||||
|
commands.push (new CSMWorld::ModifyCommand (*model,
|
||||||
|
model->index (recordIndex, column), QString::fromUtf8 (cellId.c_str())));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mOverrideFlags & Override_Rotation)
|
||||||
|
{
|
||||||
|
for (int i=0; i<3; ++i)
|
||||||
|
{
|
||||||
|
int column = collection.findColumnIndex (static_cast<CSMWorld::Columns::ColumnId> (
|
||||||
|
CSMWorld::Columns::ColumnId_PositionXRot+i));
|
||||||
|
|
||||||
|
commands.push (new CSMWorld::ModifyCommand (*model,
|
||||||
|
model->index (recordIndex, column), mPositionOverride.rot[i]));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mOverrideFlags & Override_Scale)
|
||||||
|
{
|
||||||
|
int column = collection.findColumnIndex (CSMWorld::Columns::ColumnId_Scale);
|
||||||
|
|
||||||
|
commands.push (new CSMWorld::ModifyCommand (*model,
|
||||||
|
model->index (recordIndex, column), mScaleOverride));
|
||||||
|
}
|
||||||
|
|
||||||
|
mOverrideFlags = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CSVRender::Object::setSubMode (int subMode)
|
||||||
|
{
|
||||||
|
if (subMode!=mSubMode)
|
||||||
|
{
|
||||||
|
mSubMode = subMode;
|
||||||
|
updateMarker();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void CSVRender::Object::reset()
|
||||||
|
{
|
||||||
|
mOverrideFlags = 0;
|
||||||
|
adjustTransform();
|
||||||
|
updateMarker();
|
||||||
|
}
|
||||||
|
|
|
@ -8,14 +8,19 @@
|
||||||
#include <osg/ref_ptr>
|
#include <osg/ref_ptr>
|
||||||
#include <osg/Referenced>
|
#include <osg/Referenced>
|
||||||
|
|
||||||
|
#include <components/esm/defs.hpp>
|
||||||
|
|
||||||
#include "tagbase.hpp"
|
#include "tagbase.hpp"
|
||||||
|
|
||||||
class QModelIndex;
|
class QModelIndex;
|
||||||
|
class QUndoStack;
|
||||||
|
|
||||||
namespace osg
|
namespace osg
|
||||||
{
|
{
|
||||||
class PositionAttitudeTransform;
|
class PositionAttitudeTransform;
|
||||||
class Group;
|
class Group;
|
||||||
|
class Node;
|
||||||
|
class Geode;
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace osgFX
|
namespace osgFX
|
||||||
|
@ -32,6 +37,7 @@ namespace CSMWorld
|
||||||
{
|
{
|
||||||
class Data;
|
class Data;
|
||||||
struct CellRef;
|
struct CellRef;
|
||||||
|
class CommandMacro;
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace CSVRender
|
namespace CSVRender
|
||||||
|
@ -50,18 +56,43 @@ namespace CSVRender
|
||||||
virtual QString getToolTip (bool hideBasics) const;
|
virtual QString getToolTip (bool hideBasics) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class ObjectMarkerTag : public ObjectTag
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
ObjectMarkerTag (Object* object, int axis);
|
||||||
|
|
||||||
|
int mAxis;
|
||||||
|
};
|
||||||
|
|
||||||
class Object
|
class Object
|
||||||
{
|
{
|
||||||
const CSMWorld::Data& mData;
|
public:
|
||||||
|
|
||||||
|
enum OverrideFlags
|
||||||
|
{
|
||||||
|
Override_Position = 1,
|
||||||
|
Override_Rotation = 2,
|
||||||
|
Override_Scale = 4
|
||||||
|
};
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
CSMWorld::Data& mData;
|
||||||
std::string mReferenceId;
|
std::string mReferenceId;
|
||||||
std::string mReferenceableId;
|
std::string mReferenceableId;
|
||||||
|
osg::ref_ptr<osg::PositionAttitudeTransform> mRootNode;
|
||||||
osg::ref_ptr<osg::PositionAttitudeTransform> mBaseNode;
|
osg::ref_ptr<osg::PositionAttitudeTransform> mBaseNode;
|
||||||
osg::ref_ptr<osgFX::Scribe> mOutline;
|
osg::ref_ptr<osgFX::Scribe> mOutline;
|
||||||
bool mSelected;
|
bool mSelected;
|
||||||
osg::Group* mParentNode;
|
osg::Group* mParentNode;
|
||||||
Resource::ResourceSystem* mResourceSystem;
|
Resource::ResourceSystem* mResourceSystem;
|
||||||
bool mForceBaseToZero;
|
bool mForceBaseToZero;
|
||||||
|
ESM::Position mPositionOverride;
|
||||||
|
int mScaleOverride;
|
||||||
|
int mOverrideFlags;
|
||||||
|
osg::ref_ptr<osg::Node> mMarker[3];
|
||||||
|
int mSubMode;
|
||||||
|
|
||||||
/// Not implemented
|
/// Not implemented
|
||||||
Object (const Object&);
|
Object (const Object&);
|
||||||
|
@ -82,6 +113,12 @@ namespace CSVRender
|
||||||
/// Throws an exception if *this was constructed with referenceable
|
/// Throws an exception if *this was constructed with referenceable
|
||||||
const CSMWorld::CellRef& getReference() const;
|
const CSMWorld::CellRef& getReference() const;
|
||||||
|
|
||||||
|
void updateMarker();
|
||||||
|
|
||||||
|
osg::ref_ptr<osg::Node> makeMarker (int axis);
|
||||||
|
|
||||||
|
osg::Vec3f getMarkerPosition (float x, float y, float z, int axis);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
Object (CSMWorld::Data& data, osg::Group *cellNode,
|
Object (CSMWorld::Data& data, osg::Group *cellNode,
|
||||||
|
@ -116,6 +153,33 @@ namespace CSVRender
|
||||||
std::string getReferenceableId() const;
|
std::string getReferenceableId() const;
|
||||||
|
|
||||||
osg::ref_ptr<TagBase> getTag() const;
|
osg::ref_ptr<TagBase> getTag() const;
|
||||||
|
|
||||||
|
/// Is there currently an editing operation running on this object?
|
||||||
|
bool isEdited() const;
|
||||||
|
|
||||||
|
void setEdited (int flags);
|
||||||
|
|
||||||
|
ESM::Position getPosition() const;
|
||||||
|
|
||||||
|
float getScale() const;
|
||||||
|
|
||||||
|
/// Set override position.
|
||||||
|
void setPosition (const float position[3]);
|
||||||
|
|
||||||
|
/// Set override rotation
|
||||||
|
void setRotation (const float rotation[3]);
|
||||||
|
|
||||||
|
/// Set override scale
|
||||||
|
void setScale (float scale);
|
||||||
|
|
||||||
|
/// Apply override changes via command and end edit mode
|
||||||
|
void apply (CSMWorld::CommandMacro& commands);
|
||||||
|
|
||||||
|
void setSubMode (int subMode);
|
||||||
|
|
||||||
|
/// Erase all overrides and restore the visual representation of the object to its
|
||||||
|
/// true state.
|
||||||
|
void reset();
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -309,10 +309,13 @@ void CSVRender::PagedWorldspaceWidget::addCellToScene (
|
||||||
bool deleted = index==-1 ||
|
bool deleted = index==-1 ||
|
||||||
cells.getRecord (index).mState==CSMWorld::RecordBase::State_Deleted;
|
cells.getRecord (index).mState==CSMWorld::RecordBase::State_Deleted;
|
||||||
|
|
||||||
Cell *cell = new Cell (mDocument.getData(), mRootNode, coordinates.getId (mWorldspace),
|
std::auto_ptr<Cell> cell (
|
||||||
deleted);
|
new Cell (mDocument.getData(), mRootNode, coordinates.getId (mWorldspace),
|
||||||
|
deleted));
|
||||||
|
EditMode *editMode = getEditMode();
|
||||||
|
cell->setSubMode (editMode->getSubMode(), editMode->getInteractionMask());
|
||||||
|
|
||||||
mCells.insert (std::make_pair (coordinates, cell));
|
mCells.insert (std::make_pair (coordinates, cell.release()));
|
||||||
}
|
}
|
||||||
|
|
||||||
void CSVRender::PagedWorldspaceWidget::removeCellFromScene (
|
void CSVRender::PagedWorldspaceWidget::removeCellFromScene (
|
||||||
|
@ -555,6 +558,37 @@ std::vector<osg::ref_ptr<CSVRender::TagBase> > CSVRender::PagedWorldspaceWidget:
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::vector<osg::ref_ptr<CSVRender::TagBase> > CSVRender::PagedWorldspaceWidget::getEdited (
|
||||||
|
unsigned int elementMask) const
|
||||||
|
{
|
||||||
|
std::vector<osg::ref_ptr<CSVRender::TagBase> > result;
|
||||||
|
|
||||||
|
for (std::map<CSMWorld::CellCoordinates, Cell *>::const_iterator iter = mCells.begin();
|
||||||
|
iter!=mCells.end(); ++iter)
|
||||||
|
{
|
||||||
|
std::vector<osg::ref_ptr<CSVRender::TagBase> > cellResult =
|
||||||
|
iter->second->getEdited (elementMask);
|
||||||
|
|
||||||
|
result.insert (result.end(), cellResult.begin(), cellResult.end());
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CSVRender::PagedWorldspaceWidget::setSubMode (int subMode, unsigned int elementMask)
|
||||||
|
{
|
||||||
|
for (std::map<CSMWorld::CellCoordinates, Cell *>::const_iterator iter = mCells.begin();
|
||||||
|
iter!=mCells.end(); ++iter)
|
||||||
|
iter->second->setSubMode (subMode, elementMask);
|
||||||
|
}
|
||||||
|
|
||||||
|
void CSVRender::PagedWorldspaceWidget::reset (unsigned int elementMask)
|
||||||
|
{
|
||||||
|
for (std::map<CSMWorld::CellCoordinates, Cell *>::const_iterator iter = mCells.begin();
|
||||||
|
iter!=mCells.end(); ++iter)
|
||||||
|
iter->second->reset (elementMask);
|
||||||
|
}
|
||||||
|
|
||||||
CSVWidget::SceneToolToggle *CSVRender::PagedWorldspaceWidget::makeControlVisibilitySelector (
|
CSVWidget::SceneToolToggle *CSVRender::PagedWorldspaceWidget::makeControlVisibilitySelector (
|
||||||
CSVWidget::SceneToolbar *parent)
|
CSVWidget::SceneToolbar *parent)
|
||||||
{
|
{
|
||||||
|
|
|
@ -112,6 +112,14 @@ namespace CSVRender
|
||||||
virtual std::vector<osg::ref_ptr<TagBase> > getSelection (unsigned int elementMask)
|
virtual std::vector<osg::ref_ptr<TagBase> > getSelection (unsigned int elementMask)
|
||||||
const;
|
const;
|
||||||
|
|
||||||
|
virtual std::vector<osg::ref_ptr<TagBase> > getEdited (unsigned int elementMask)
|
||||||
|
const;
|
||||||
|
|
||||||
|
virtual void setSubMode (int subMode, unsigned int elementMask);
|
||||||
|
|
||||||
|
/// Erase all overrides and restore the visual representation to its true state.
|
||||||
|
virtual void reset (unsigned int elementMask);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
virtual void addVisibilitySelectorButtons (CSVWidget::SceneToolToggle2 *tool);
|
virtual void addVisibilitySelectorButtons (CSVWidget::SceneToolToggle2 *tool);
|
||||||
|
|
|
@ -120,6 +120,12 @@ bool RenderWidget::eventFilter(QObject* obj, QEvent* event)
|
||||||
return QObject::eventFilter(obj, event);
|
return QObject::eventFilter(obj, event);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
osg::Camera *RenderWidget::getCamera()
|
||||||
|
{
|
||||||
|
return mView->getCamera();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// --------------------------------------------------
|
// --------------------------------------------------
|
||||||
|
|
||||||
CompositeViewer::CompositeViewer()
|
CompositeViewer::CompositeViewer()
|
||||||
|
|
|
@ -21,6 +21,7 @@ namespace Resource
|
||||||
namespace osg
|
namespace osg
|
||||||
{
|
{
|
||||||
class Group;
|
class Group;
|
||||||
|
class Camera;
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace CSVWidget
|
namespace CSVWidget
|
||||||
|
@ -47,6 +48,8 @@ namespace CSVRender
|
||||||
|
|
||||||
bool eventFilter(QObject *, QEvent *);
|
bool eventFilter(QObject *, QEvent *);
|
||||||
|
|
||||||
|
osg::Camera *getCamera();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
osg::ref_ptr<osgViewer::View> mView;
|
osg::ref_ptr<osgViewer::View> mView;
|
||||||
|
|
|
@ -131,6 +131,22 @@ std::vector<osg::ref_ptr<CSVRender::TagBase> > CSVRender::UnpagedWorldspaceWidge
|
||||||
return mCell->getSelection (elementMask);
|
return mCell->getSelection (elementMask);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::vector<osg::ref_ptr<CSVRender::TagBase> > CSVRender::UnpagedWorldspaceWidget::getEdited (
|
||||||
|
unsigned int elementMask) const
|
||||||
|
{
|
||||||
|
return mCell->getEdited (elementMask);
|
||||||
|
}
|
||||||
|
|
||||||
|
void CSVRender::UnpagedWorldspaceWidget::setSubMode (int subMode, unsigned int elementMask)
|
||||||
|
{
|
||||||
|
mCell->setSubMode (subMode, elementMask);
|
||||||
|
}
|
||||||
|
|
||||||
|
void CSVRender::UnpagedWorldspaceWidget::reset (unsigned int elementMask)
|
||||||
|
{
|
||||||
|
mCell->reset (elementMask);
|
||||||
|
}
|
||||||
|
|
||||||
void CSVRender::UnpagedWorldspaceWidget::referenceableDataChanged (const QModelIndex& topLeft,
|
void CSVRender::UnpagedWorldspaceWidget::referenceableDataChanged (const QModelIndex& topLeft,
|
||||||
const QModelIndex& bottomRight)
|
const QModelIndex& bottomRight)
|
||||||
{
|
{
|
||||||
|
|
|
@ -60,6 +60,14 @@ namespace CSVRender
|
||||||
virtual std::vector<osg::ref_ptr<TagBase> > getSelection (unsigned int elementMask)
|
virtual std::vector<osg::ref_ptr<TagBase> > getSelection (unsigned int elementMask)
|
||||||
const;
|
const;
|
||||||
|
|
||||||
|
virtual std::vector<osg::ref_ptr<TagBase> > getEdited (unsigned int elementMask)
|
||||||
|
const;
|
||||||
|
|
||||||
|
virtual void setSubMode (int subMode, unsigned int elementMask);
|
||||||
|
|
||||||
|
/// Erase all overrides and restore the visual representation to its true state.
|
||||||
|
virtual void reset (unsigned int elementMask);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
virtual void referenceableDataChanged (const QModelIndex& topLeft,
|
virtual void referenceableDataChanged (const QModelIndex& topLeft,
|
||||||
|
|
|
@ -364,6 +364,18 @@ osg::Vec3f CSVRender::WorldspaceWidget::getIntersectionPoint (const QPoint& loca
|
||||||
return start + direction * CSMPrefs::get()["Scene Drops"]["distance"].toInt();
|
return start + direction * CSMPrefs::get()["Scene Drops"]["distance"].toInt();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CSVRender::WorldspaceWidget::abortDrag()
|
||||||
|
{
|
||||||
|
if (mDragging)
|
||||||
|
{
|
||||||
|
EditMode& editMode = dynamic_cast<CSVRender::EditMode&> (*mEditMode->getCurrent());
|
||||||
|
|
||||||
|
editMode.dragAborted();
|
||||||
|
mDragging = false;
|
||||||
|
mDragMode.clear();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void CSVRender::WorldspaceWidget::dragEnterEvent (QDragEnterEvent* event)
|
void CSVRender::WorldspaceWidget::dragEnterEvent (QDragEnterEvent* event)
|
||||||
{
|
{
|
||||||
const CSMWorld::TableMimeData* mime = dynamic_cast<const CSMWorld::TableMimeData*> (event->mimeData());
|
const CSMWorld::TableMimeData* mime = dynamic_cast<const CSMWorld::TableMimeData*> (event->mimeData());
|
||||||
|
@ -573,6 +585,7 @@ void CSVRender::WorldspaceWidget::editModeChanged (const std::string& id)
|
||||||
{
|
{
|
||||||
dynamic_cast<CSVRender::EditMode&> (*mEditMode->getCurrent()).setEditLock (mLocked);
|
dynamic_cast<CSVRender::EditMode&> (*mEditMode->getCurrent()).setEditLock (mLocked);
|
||||||
mDragging = false;
|
mDragging = false;
|
||||||
|
mDragMode.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
void CSVRender::WorldspaceWidget::showToolTip()
|
void CSVRender::WorldspaceWidget::showToolTip()
|
||||||
|
@ -736,13 +749,7 @@ void CSVRender::WorldspaceWidget::keyPressEvent (QKeyEvent *event)
|
||||||
{
|
{
|
||||||
if(event->key() == Qt::Key_Escape)
|
if(event->key() == Qt::Key_Escape)
|
||||||
{
|
{
|
||||||
if (mDragging)
|
abortDrag();
|
||||||
{
|
|
||||||
EditMode& editMode = dynamic_cast<CSVRender::EditMode&> (*mEditMode->getCurrent());
|
|
||||||
|
|
||||||
editMode.dragAborted();
|
|
||||||
mDragging = false;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
RenderWidget::keyPressEvent(event);
|
RenderWidget::keyPressEvent(event);
|
||||||
|
@ -761,3 +768,8 @@ void CSVRender::WorldspaceWidget::handleMouseClick (osg::ref_ptr<TagBase> tag, c
|
||||||
else if (button=="s-select")
|
else if (button=="s-select")
|
||||||
editMode.secondarySelectPressed (tag);
|
editMode.secondarySelectPressed (tag);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
CSVRender::EditMode *CSVRender::WorldspaceWidget::getEditMode()
|
||||||
|
{
|
||||||
|
return dynamic_cast<CSVRender::EditMode *> (mEditMode->getCurrent());
|
||||||
|
}
|
||||||
|
|
|
@ -35,6 +35,7 @@ namespace CSVRender
|
||||||
{
|
{
|
||||||
class TagBase;
|
class TagBase;
|
||||||
class CellArrow;
|
class CellArrow;
|
||||||
|
class EditMode;
|
||||||
|
|
||||||
class WorldspaceWidget : public SceneWidget
|
class WorldspaceWidget : public SceneWidget
|
||||||
{
|
{
|
||||||
|
@ -152,6 +153,20 @@ namespace CSVRender
|
||||||
virtual std::vector<osg::ref_ptr<TagBase> > getSelection (unsigned int elementMask)
|
virtual std::vector<osg::ref_ptr<TagBase> > getSelection (unsigned int elementMask)
|
||||||
const = 0;
|
const = 0;
|
||||||
|
|
||||||
|
virtual std::vector<osg::ref_ptr<TagBase> > getEdited (unsigned int elementMask)
|
||||||
|
const = 0;
|
||||||
|
|
||||||
|
virtual void setSubMode (int subMode, unsigned int elementMask) = 0;
|
||||||
|
|
||||||
|
/// Erase all overrides and restore the visual representation to its true state.
|
||||||
|
virtual void reset (unsigned int elementMask) = 0;
|
||||||
|
|
||||||
|
/// \note Drags will be automatically aborted when the aborting is triggered
|
||||||
|
/// (either explicitly or implicitly) from within this class. This function only
|
||||||
|
/// needs to be called, when the drag abort is triggered externally (e.g. from
|
||||||
|
/// an edit mode).
|
||||||
|
void abortDrag();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
/// Visual elements in a scene
|
/// Visual elements in a scene
|
||||||
|
@ -181,6 +196,8 @@ namespace CSVRender
|
||||||
virtual void handleMouseClick (osg::ref_ptr<TagBase> tag, const std::string& button,
|
virtual void handleMouseClick (osg::ref_ptr<TagBase> tag, const std::string& button,
|
||||||
bool shift);
|
bool shift);
|
||||||
|
|
||||||
|
EditMode *getEditMode();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
void dragEnterEvent(QDragEnterEvent *event);
|
void dragEnterEvent(QDragEnterEvent *event);
|
||||||
|
|
|
@ -38,6 +38,27 @@ void CSVWidget::SceneToolMode::adjustToolTip (const ModeButton *activeMode)
|
||||||
setToolTip (toolTip);
|
setToolTip (toolTip);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CSVWidget::SceneToolMode::setButton (std::map<ModeButton *, std::string>::iterator iter)
|
||||||
|
{
|
||||||
|
for (std::map<ModeButton *, std::string>::const_iterator iter2 = mButtons.begin();
|
||||||
|
iter2!=mButtons.end(); ++iter2)
|
||||||
|
iter2->first->setChecked (iter2==iter);
|
||||||
|
|
||||||
|
setIcon (iter->first->icon());
|
||||||
|
adjustToolTip (iter->first);
|
||||||
|
|
||||||
|
if (mCurrent!=iter->first)
|
||||||
|
{
|
||||||
|
if (mCurrent)
|
||||||
|
mCurrent->deactivate (mToolbar);
|
||||||
|
|
||||||
|
mCurrent = iter->first;
|
||||||
|
mCurrent->activate (mToolbar);
|
||||||
|
}
|
||||||
|
|
||||||
|
emit modeChanged (iter->second);
|
||||||
|
}
|
||||||
|
|
||||||
CSVWidget::SceneToolMode::SceneToolMode (SceneToolbar *parent, const QString& toolTip)
|
CSVWidget::SceneToolMode::SceneToolMode (SceneToolbar *parent, const QString& toolTip)
|
||||||
: SceneTool (parent), mButtonSize (parent->getButtonSize()), mIconSize (parent->getIconSize()),
|
: SceneTool (parent), mButtonSize (parent->getButtonSize()), mIconSize (parent->getIconSize()),
|
||||||
mToolTip (toolTip), mFirst (0), mCurrent (0), mToolbar (parent)
|
mToolTip (toolTip), mFirst (0), mCurrent (0), mToolbar (parent)
|
||||||
|
@ -96,9 +117,25 @@ CSVWidget::ModeButton *CSVWidget::SceneToolMode::getCurrent()
|
||||||
return mCurrent;
|
return mCurrent;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::string CSVWidget::SceneToolMode::getCurrentId() const
|
||||||
|
{
|
||||||
|
return mButtons.find (mCurrent)->second;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CSVWidget::SceneToolMode::setButton (const std::string& id)
|
||||||
|
{
|
||||||
|
for (std::map<ModeButton *, std::string>::iterator iter = mButtons.begin();
|
||||||
|
iter!=mButtons.end(); ++iter)
|
||||||
|
if (iter->second==id)
|
||||||
|
{
|
||||||
|
setButton (iter);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void CSVWidget::SceneToolMode::selected()
|
void CSVWidget::SceneToolMode::selected()
|
||||||
{
|
{
|
||||||
std::map<ModeButton *, std::string>::const_iterator iter =
|
std::map<ModeButton *, std::string>::iterator iter =
|
||||||
mButtons.find (dynamic_cast<ModeButton *> (sender()));
|
mButtons.find (dynamic_cast<ModeButton *> (sender()));
|
||||||
|
|
||||||
if (iter!=mButtons.end())
|
if (iter!=mButtons.end())
|
||||||
|
@ -106,22 +143,6 @@ void CSVWidget::SceneToolMode::selected()
|
||||||
if (!iter->first->hasKeepOpen())
|
if (!iter->first->hasKeepOpen())
|
||||||
mPanel->hide();
|
mPanel->hide();
|
||||||
|
|
||||||
for (std::map<ModeButton *, std::string>::const_iterator iter2 = mButtons.begin();
|
setButton (iter);
|
||||||
iter2!=mButtons.end(); ++iter2)
|
|
||||||
iter2->first->setChecked (iter2==iter);
|
|
||||||
|
|
||||||
setIcon (iter->first->icon());
|
|
||||||
adjustToolTip (iter->first);
|
|
||||||
|
|
||||||
if (mCurrent!=iter->first)
|
|
||||||
{
|
|
||||||
if (mCurrent)
|
|
||||||
mCurrent->deactivate (mToolbar);
|
|
||||||
|
|
||||||
mCurrent = iter->first;
|
|
||||||
mCurrent->activate (mToolbar);
|
|
||||||
}
|
|
||||||
|
|
||||||
emit modeChanged (iter->second);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -41,6 +41,8 @@ namespace CSVWidget
|
||||||
/// items to be added, the function must return true anyway.
|
/// items to be added, the function must return true anyway.
|
||||||
virtual bool createContextMenu (QMenu *menu);
|
virtual bool createContextMenu (QMenu *menu);
|
||||||
|
|
||||||
|
void setButton (std::map<ModeButton *, std::string>::iterator iter);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
SceneToolMode (SceneToolbar *parent, const QString& toolTip);
|
SceneToolMode (SceneToolbar *parent, const QString& toolTip);
|
||||||
|
@ -56,6 +58,12 @@ namespace CSVWidget
|
||||||
/// Will return a 0-pointer only if the mode does not have any buttons yet.
|
/// Will return a 0-pointer only if the mode does not have any buttons yet.
|
||||||
ModeButton *getCurrent();
|
ModeButton *getCurrent();
|
||||||
|
|
||||||
|
/// Must not be called if there aren't any buttons yet.
|
||||||
|
std::string getCurrentId() const;
|
||||||
|
|
||||||
|
/// Manually change the current mode
|
||||||
|
void setButton (const std::string& id);
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
|
|
||||||
void modeChanged (const std::string& id);
|
void modeChanged (const std::string& id);
|
||||||
|
|
|
@ -9,6 +9,7 @@
|
||||||
#include "../../model/world/columns.hpp"
|
#include "../../model/world/columns.hpp"
|
||||||
#include "../../model/world/idtable.hpp"
|
#include "../../model/world/idtable.hpp"
|
||||||
#include "../../model/world/idcompletionmanager.hpp"
|
#include "../../model/world/idcompletionmanager.hpp"
|
||||||
|
#include "../../model/world/commandmacro.hpp"
|
||||||
|
|
||||||
#include "../widget/droplineedit.hpp"
|
#include "../widget/droplineedit.hpp"
|
||||||
|
|
||||||
|
@ -53,10 +54,9 @@ void CSVWorld::ReferenceCreator::pushCommand (std::auto_ptr<CSMWorld::CreateComm
|
||||||
std::auto_ptr<CSMWorld::ModifyCommand> increment (new CSMWorld::ModifyCommand
|
std::auto_ptr<CSMWorld::ModifyCommand> increment (new CSMWorld::ModifyCommand
|
||||||
(cellTable, countIndex, count+1));
|
(cellTable, countIndex, count+1));
|
||||||
|
|
||||||
getUndoStack().beginMacro (command->text());
|
CSMWorld::CommandMacro macro (getUndoStack(), command->text());
|
||||||
GenericCreator::pushCommand (command, id);
|
GenericCreator::pushCommand (command, id);
|
||||||
getUndoStack().push (increment.release());
|
macro.push (increment.release());
|
||||||
getUndoStack().endMacro();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int CSVWorld::ReferenceCreator::getRefNumCount() const
|
int CSVWorld::ReferenceCreator::getRefNumCount() const
|
||||||
|
|
|
@ -17,6 +17,7 @@
|
||||||
#include "../../model/world/commands.hpp"
|
#include "../../model/world/commands.hpp"
|
||||||
#include "../../model/world/columns.hpp"
|
#include "../../model/world/columns.hpp"
|
||||||
#include "../../model/world/tablemimedata.hpp"
|
#include "../../model/world/tablemimedata.hpp"
|
||||||
|
#include "../../model/world/commandmacro.hpp"
|
||||||
|
|
||||||
void CSVWorld::RegionMap::contextMenuEvent (QContextMenuEvent *event)
|
void CSVWorld::RegionMap::contextMenuEvent (QContextMenuEvent *event)
|
||||||
{
|
{
|
||||||
|
@ -159,8 +160,7 @@ void CSVWorld::RegionMap::setRegion (const std::string& regionId)
|
||||||
|
|
||||||
QString regionId2 = QString::fromUtf8 (regionId.c_str());
|
QString regionId2 = QString::fromUtf8 (regionId.c_str());
|
||||||
|
|
||||||
if (selected.size()>1)
|
CSMWorld::CommandMacro macro (mDocument.getUndoStack(), selected.size()>1 ? tr ("Set Region") : "");
|
||||||
mDocument.getUndoStack().beginMacro (tr ("Set Region"));
|
|
||||||
|
|
||||||
for (QModelIndexList::const_iterator iter (selected.begin()); iter!=selected.end(); ++iter)
|
for (QModelIndexList::const_iterator iter (selected.begin()); iter!=selected.end(); ++iter)
|
||||||
{
|
{
|
||||||
|
@ -170,12 +170,8 @@ void CSVWorld::RegionMap::setRegion (const std::string& regionId)
|
||||||
QModelIndex index = cellsModel->getModelIndex (cellId,
|
QModelIndex index = cellsModel->getModelIndex (cellId,
|
||||||
cellsModel->findColumnIndex (CSMWorld::Columns::ColumnId_Region));
|
cellsModel->findColumnIndex (CSMWorld::Columns::ColumnId_Region));
|
||||||
|
|
||||||
mDocument.getUndoStack().push (
|
macro.push (new CSMWorld::ModifyCommand (*cellsModel, index, regionId2));
|
||||||
new CSMWorld::ModifyCommand (*cellsModel, index, regionId2));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (selected.size()>1)
|
|
||||||
mDocument.getUndoStack().endMacro();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
CSVWorld::RegionMap::RegionMap (const CSMWorld::UniversalId& universalId,
|
CSVWorld::RegionMap::RegionMap (const CSMWorld::UniversalId& universalId,
|
||||||
|
@ -258,19 +254,15 @@ void CSVWorld::RegionMap::createCells()
|
||||||
CSMWorld::IdTable *cellsModel = &dynamic_cast<CSMWorld::IdTable&> (*
|
CSMWorld::IdTable *cellsModel = &dynamic_cast<CSMWorld::IdTable&> (*
|
||||||
mDocument.getData().getTableModel (CSMWorld::UniversalId::Type_Cells));
|
mDocument.getData().getTableModel (CSMWorld::UniversalId::Type_Cells));
|
||||||
|
|
||||||
if (selected.size()>1)
|
CSMWorld::CommandMacro macro (mDocument.getUndoStack(), selected.size()>1 ? tr ("Create cells"): "");
|
||||||
mDocument.getUndoStack().beginMacro (tr ("Create cells"));
|
|
||||||
|
|
||||||
for (QModelIndexList::const_iterator iter (selected.begin()); iter!=selected.end(); ++iter)
|
for (QModelIndexList::const_iterator iter (selected.begin()); iter!=selected.end(); ++iter)
|
||||||
{
|
{
|
||||||
std::string cellId = model()->data (*iter, CSMWorld::RegionMap::Role_CellId).
|
std::string cellId = model()->data (*iter, CSMWorld::RegionMap::Role_CellId).
|
||||||
toString().toUtf8().constData();
|
toString().toUtf8().constData();
|
||||||
|
|
||||||
mDocument.getUndoStack().push (new CSMWorld::CreateCommand (*cellsModel, cellId));
|
macro.push (new CSMWorld::CreateCommand (*cellsModel, cellId));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (selected.size()>1)
|
|
||||||
mDocument.getUndoStack().endMacro();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void CSVWorld::RegionMap::setRegion()
|
void CSVWorld::RegionMap::setRegion()
|
||||||
|
|
|
@ -4,6 +4,7 @@
|
||||||
|
|
||||||
#include "../../model/world/commands.hpp"
|
#include "../../model/world/commands.hpp"
|
||||||
#include "../../model/world/columns.hpp"
|
#include "../../model/world/columns.hpp"
|
||||||
|
#include "../../model/world/commandmacro.hpp"
|
||||||
|
|
||||||
void CSVWorld::VarTypeDelegate::addCommands (QAbstractItemModel *model, const QModelIndex& index, int type)
|
void CSVWorld::VarTypeDelegate::addCommands (QAbstractItemModel *model, const QModelIndex& index, int type)
|
||||||
const
|
const
|
||||||
|
@ -36,13 +37,10 @@ void CSVWorld::VarTypeDelegate::addCommands (QAbstractItemModel *model, const QM
|
||||||
default: break; // ignore the rest
|
default: break; // ignore the rest
|
||||||
}
|
}
|
||||||
|
|
||||||
getUndoStack().beginMacro (
|
CSMWorld::CommandMacro macro (getUndoStack(), "Modify " + model->headerData (index.column(), Qt::Horizontal, Qt::DisplayRole).toString());
|
||||||
"Modify " + model->headerData (index.column(), Qt::Horizontal, Qt::DisplayRole).toString());
|
|
||||||
|
|
||||||
getUndoStack().push (new CSMWorld::ModifyCommand (*model, index, type));
|
macro.push (new CSMWorld::ModifyCommand (*model, index, type));
|
||||||
getUndoStack().push (new CSMWorld::ModifyCommand (*model, next, value));
|
macro.push (new CSMWorld::ModifyCommand (*model, next, value));
|
||||||
|
|
||||||
getUndoStack().endMacro();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
CSVWorld::VarTypeDelegate::VarTypeDelegate (const std::vector<std::pair<int, QString> >& values,
|
CSVWorld::VarTypeDelegate::VarTypeDelegate (const std::vector<std::pair<int, QString> >& values,
|
||||||
|
|
Loading…
Reference in a new issue