mirror of
https://github.com/OpenMW/openmw.git
synced 2025-01-20 12:53:52 +00:00
Merge branch 'objects'
This commit is contained in:
commit
099c406226
7 changed files with 382 additions and 160 deletions
|
@ -70,7 +70,7 @@ opencs_units (view/render
|
||||||
|
|
||||||
opencs_units_noqt (view/render
|
opencs_units_noqt (view/render
|
||||||
navigation navigation1st navigationfree navigationorbit lighting lightingday lightingnight
|
navigation navigation1st navigationfree navigationorbit lighting lightingday lightingnight
|
||||||
lightingbright
|
lightingbright object
|
||||||
)
|
)
|
||||||
|
|
||||||
opencs_units_noqt (view/world
|
opencs_units_noqt (view/world
|
||||||
|
|
217
apps/opencs/view/render/object.cpp
Normal file
217
apps/opencs/view/render/object.cpp
Normal file
|
@ -0,0 +1,217 @@
|
||||||
|
|
||||||
|
#include "object.hpp"
|
||||||
|
|
||||||
|
#include <OgreSceneManager.h>
|
||||||
|
#include <OgreSceneNode.h>
|
||||||
|
#include <OgreEntity.h>
|
||||||
|
|
||||||
|
#include "../../model/world/data.hpp"
|
||||||
|
#include "../../model/world/ref.hpp"
|
||||||
|
#include "../../model/world/refidcollection.hpp"
|
||||||
|
|
||||||
|
void CSVRender::Object::clearSceneNode (Ogre::SceneNode *node)
|
||||||
|
{
|
||||||
|
for (Ogre::SceneNode::ObjectIterator iter = node->getAttachedObjectIterator();
|
||||||
|
iter.hasMoreElements(); )
|
||||||
|
{
|
||||||
|
Ogre::MovableObject* object = dynamic_cast<Ogre::MovableObject*> (iter.getNext());
|
||||||
|
node->getCreator()->destroyMovableObject (object);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (Ogre::SceneNode::ChildNodeIterator iter = node->getChildIterator();
|
||||||
|
iter.hasMoreElements(); )
|
||||||
|
{
|
||||||
|
Ogre::SceneNode* childNode = dynamic_cast<Ogre::SceneNode*> (iter.getNext());
|
||||||
|
clearSceneNode (childNode);
|
||||||
|
node->getCreator()->destroySceneNode (childNode);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void CSVRender::Object::clear()
|
||||||
|
{
|
||||||
|
mObject.setNull();
|
||||||
|
|
||||||
|
clearSceneNode (mBase);
|
||||||
|
}
|
||||||
|
|
||||||
|
void CSVRender::Object::update()
|
||||||
|
{
|
||||||
|
clear();
|
||||||
|
|
||||||
|
std::string model;
|
||||||
|
int error = 0; // 1 referemceanöe does not exist, 2 referenceable does not specify a mesh
|
||||||
|
|
||||||
|
const CSMWorld::RefIdCollection& referenceables = mData.getReferenceables();
|
||||||
|
|
||||||
|
int index = referenceables.searchId (mReferenceableId);
|
||||||
|
|
||||||
|
if (index==-1)
|
||||||
|
error = 1;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// xxx check for Deleted state (error 1)
|
||||||
|
|
||||||
|
model = referenceables.getData (index,
|
||||||
|
referenceables.findColumnIndex (CSMWorld::Columns::ColumnId_Model)).
|
||||||
|
toString().toUtf8().constData();
|
||||||
|
|
||||||
|
if (model.empty())
|
||||||
|
error = 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (error)
|
||||||
|
{
|
||||||
|
Ogre::Entity* entity = mBase->getCreator()->createEntity (Ogre::SceneManager::PT_CUBE);
|
||||||
|
entity->setMaterialName("BaseWhite"); /// \todo adjust material according to error
|
||||||
|
|
||||||
|
mBase->attachObject (entity);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
mObject = NifOgre::Loader::createObjects (mBase, "Meshes\\" + model);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void CSVRender::Object::adjust()
|
||||||
|
{
|
||||||
|
if (mReferenceId.empty())
|
||||||
|
return;
|
||||||
|
|
||||||
|
const CSMWorld::CellRef& reference = getReference();
|
||||||
|
|
||||||
|
// position
|
||||||
|
if (!mForceBaseToZero)
|
||||||
|
{
|
||||||
|
Ogre::Vector3 (reference.mPos.pos[0], reference.mPos.pos[1], reference.mPos.pos[2]);
|
||||||
|
|
||||||
|
mBase->setPosition (Ogre::Vector3 (
|
||||||
|
reference.mPos.pos[0], reference.mPos.pos[1], reference.mPos.pos[2]));
|
||||||
|
}
|
||||||
|
|
||||||
|
// orientation
|
||||||
|
Ogre::Quaternion xr (Ogre::Radian (-reference.mPos.pos[0]), Ogre::Vector3::UNIT_X);
|
||||||
|
|
||||||
|
Ogre::Quaternion yr (Ogre::Radian (-reference.mPos.pos[1]), Ogre::Vector3::UNIT_Y);
|
||||||
|
|
||||||
|
Ogre::Quaternion zr (Ogre::Radian (-reference.mPos.pos[2]), Ogre::Vector3::UNIT_Z);
|
||||||
|
|
||||||
|
mBase->setOrientation (xr*yr*zr);
|
||||||
|
|
||||||
|
// scale
|
||||||
|
mBase->setScale (reference.mScale, reference.mScale, reference.mScale);
|
||||||
|
}
|
||||||
|
|
||||||
|
const CSMWorld::CellRef& CSVRender::Object::getReference() const
|
||||||
|
{
|
||||||
|
if (mReferenceId.empty())
|
||||||
|
throw std::logic_error ("object does not represent a reference");
|
||||||
|
|
||||||
|
return mData.getReferences().getRecord (mReferenceId).get();
|
||||||
|
}
|
||||||
|
|
||||||
|
CSVRender::Object::Object (const CSMWorld::Data& data, Ogre::SceneNode *cellNode,
|
||||||
|
const std::string& id, bool referenceable, bool forceBaseToZero)
|
||||||
|
: mData (data), mBase (0), mForceBaseToZero (forceBaseToZero)
|
||||||
|
{
|
||||||
|
mBase = cellNode->createChildSceneNode();
|
||||||
|
|
||||||
|
if (referenceable)
|
||||||
|
{
|
||||||
|
mReferenceableId = id;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
mReferenceId = id;
|
||||||
|
mReferenceableId = getReference().mRefID;
|
||||||
|
}
|
||||||
|
|
||||||
|
update();
|
||||||
|
adjust();
|
||||||
|
}
|
||||||
|
|
||||||
|
CSVRender::Object::~Object()
|
||||||
|
{
|
||||||
|
clear();
|
||||||
|
|
||||||
|
if (mBase)
|
||||||
|
mBase->getCreator()->destroySceneNode (mBase);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CSVRender::Object::referenceableDataChanged (const QModelIndex& topLeft,
|
||||||
|
const QModelIndex& bottomRight)
|
||||||
|
{
|
||||||
|
const CSMWorld::RefIdCollection& referenceables = mData.getReferenceables();
|
||||||
|
|
||||||
|
int index = referenceables.searchId (mReferenceableId);
|
||||||
|
|
||||||
|
if (index!=-1 && index>=topLeft.row() && index<=bottomRight.row())
|
||||||
|
{
|
||||||
|
update();
|
||||||
|
adjust();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CSVRender::Object::referenceableAboutToBeRemoved (const QModelIndex& parent, int start,
|
||||||
|
int end)
|
||||||
|
{
|
||||||
|
const CSMWorld::RefIdCollection& referenceables = mData.getReferenceables();
|
||||||
|
|
||||||
|
int index = referenceables.searchId (mReferenceableId);
|
||||||
|
|
||||||
|
if (index!=-1 && index>=start && index<=end)
|
||||||
|
{
|
||||||
|
// Deletion of referenceable-type objects is handled outside of Object.
|
||||||
|
if (!mReferenceId.empty())
|
||||||
|
{
|
||||||
|
update();
|
||||||
|
adjust();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CSVRender::Object::referenceDataChanged (const QModelIndex& topLeft,
|
||||||
|
const QModelIndex& bottomRight)
|
||||||
|
{
|
||||||
|
if (mReferenceId.empty())
|
||||||
|
return false;
|
||||||
|
|
||||||
|
const CSMWorld::RefCollection& references = mData.getReferences();
|
||||||
|
|
||||||
|
int index = references.searchId (mReferenceId);
|
||||||
|
|
||||||
|
if (index!=-1 && index>=topLeft.row() && index<=bottomRight.row())
|
||||||
|
{
|
||||||
|
int columnIndex =
|
||||||
|
references.findColumnIndex (CSMWorld::Columns::ColumnId_ReferenceableId);
|
||||||
|
|
||||||
|
if (columnIndex>=topLeft.column() && columnIndex<=bottomRight.row())
|
||||||
|
{
|
||||||
|
mReferenceableId =
|
||||||
|
references.getData (index, columnIndex).toString().toUtf8().constData();
|
||||||
|
|
||||||
|
update();
|
||||||
|
}
|
||||||
|
|
||||||
|
adjust();
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string CSVRender::Object::getReferenceId() const
|
||||||
|
{
|
||||||
|
return mReferenceId;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string CSVRender::Object::getReferenceableId() const
|
||||||
|
{
|
||||||
|
return mReferenceableId;
|
||||||
|
}
|
80
apps/opencs/view/render/object.hpp
Normal file
80
apps/opencs/view/render/object.hpp
Normal file
|
@ -0,0 +1,80 @@
|
||||||
|
#ifndef OPENCS_VIEW_OBJECT_H
|
||||||
|
#define OPENCS_VIEW_OBJECT_H
|
||||||
|
|
||||||
|
#include <components/nifogre/ogrenifloader.hpp>
|
||||||
|
|
||||||
|
class QModelIndex;
|
||||||
|
|
||||||
|
namespace Ogre
|
||||||
|
{
|
||||||
|
class SceneNode;
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace CSMWorld
|
||||||
|
{
|
||||||
|
class Data;
|
||||||
|
class CellRef;
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace CSVRender
|
||||||
|
{
|
||||||
|
class Object
|
||||||
|
{
|
||||||
|
const CSMWorld::Data& mData;
|
||||||
|
std::string mReferenceId;
|
||||||
|
std::string mReferenceableId;
|
||||||
|
Ogre::SceneNode *mBase;
|
||||||
|
NifOgre::ObjectScenePtr mObject;
|
||||||
|
bool mForceBaseToZero;
|
||||||
|
|
||||||
|
/// Not implemented
|
||||||
|
Object (const Object&);
|
||||||
|
|
||||||
|
/// Not implemented
|
||||||
|
Object& operator= (const Object&);
|
||||||
|
|
||||||
|
/// Destroy all scene nodes and movable objects attached to node.
|
||||||
|
static void clearSceneNode (Ogre::SceneNode *node);
|
||||||
|
|
||||||
|
/// Remove object from node (includes deleting)
|
||||||
|
void clear();
|
||||||
|
|
||||||
|
/// Update model
|
||||||
|
void update();
|
||||||
|
|
||||||
|
/// Adjust position, orientation and scale
|
||||||
|
void adjust();
|
||||||
|
|
||||||
|
/// Throws an exception if *this was constructed with referenceable
|
||||||
|
const CSMWorld::CellRef& getReference() const;
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
Object (const CSMWorld::Data& data, Ogre::SceneNode *cellNode,
|
||||||
|
const std::string& id, bool referenceable, bool forceBaseToZero = false);
|
||||||
|
/// \param forceBaseToZero If this is a reference ignore the coordinates and place
|
||||||
|
/// it at 0, 0, 0 instead.
|
||||||
|
|
||||||
|
~Object();
|
||||||
|
|
||||||
|
/// \return Did this call result in a modification of the visual representation of
|
||||||
|
/// this object?
|
||||||
|
bool referenceableDataChanged (const QModelIndex& topLeft,
|
||||||
|
const QModelIndex& bottomRight);
|
||||||
|
|
||||||
|
/// \return Did this call result in a modification of the visual representation of
|
||||||
|
/// this object?
|
||||||
|
bool referenceableAboutToBeRemoved (const QModelIndex& parent, int start, int end);
|
||||||
|
|
||||||
|
/// \return Did this call result in a modification of the visual representation of
|
||||||
|
/// this object?
|
||||||
|
bool referenceDataChanged (const QModelIndex& topLeft, const QModelIndex& bottomRight);
|
||||||
|
|
||||||
|
/// Returns an empty string if this is a refereceable-type object.
|
||||||
|
std::string getReferenceId() const;
|
||||||
|
|
||||||
|
std::string getReferenceableId() const;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
|
@ -7,194 +7,119 @@
|
||||||
#include "../../model/world/data.hpp"
|
#include "../../model/world/data.hpp"
|
||||||
#include "../../model/world/idtable.hpp"
|
#include "../../model/world/idtable.hpp"
|
||||||
|
|
||||||
void CSVRender::PreviewWidget::setup()
|
CSVRender::PreviewWidget::PreviewWidget (CSMWorld::Data& data,
|
||||||
|
const std::string& id, bool referenceable, QWidget *parent)
|
||||||
|
: SceneWidget (parent), mData (data),
|
||||||
|
mObject (data, getSceneManager()->getRootSceneNode(), id, referenceable, true)
|
||||||
{
|
{
|
||||||
setNavigation (&mOrbit);
|
setNavigation (&mOrbit);
|
||||||
|
|
||||||
mNode = getSceneManager()->getRootSceneNode()->createChildSceneNode();
|
|
||||||
mNode->setPosition (Ogre::Vector3 (0, 0, 0));
|
|
||||||
|
|
||||||
setModel();
|
|
||||||
|
|
||||||
QAbstractItemModel *referenceables =
|
QAbstractItemModel *referenceables =
|
||||||
mData.getTableModel (CSMWorld::UniversalId::Type_Referenceables);
|
mData.getTableModel (CSMWorld::UniversalId::Type_Referenceables);
|
||||||
|
|
||||||
connect (referenceables, SIGNAL (dataChanged (const QModelIndex&, const QModelIndex&)),
|
connect (referenceables, SIGNAL (dataChanged (const QModelIndex&, const QModelIndex&)),
|
||||||
this, SLOT (ReferenceableDataChanged (const QModelIndex&, const QModelIndex&)));
|
this, SLOT (referenceableDataChanged (const QModelIndex&, const QModelIndex&)));
|
||||||
connect (referenceables, SIGNAL (rowsAboutToBeRemoved (const QModelIndex&, int, int)),
|
connect (referenceables, SIGNAL (rowsAboutToBeRemoved (const QModelIndex&, int, int)),
|
||||||
this, SLOT (ReferenceableAboutToBeRemoved (const QModelIndex&, int, int)));
|
this, SLOT (referenceableAboutToBeRemoved (const QModelIndex&, int, int)));
|
||||||
}
|
|
||||||
|
|
||||||
void CSVRender::PreviewWidget::setModel()
|
if (!referenceable)
|
||||||
{
|
|
||||||
if (mNode)
|
|
||||||
{
|
{
|
||||||
mObject.setNull();
|
QAbstractItemModel *references =
|
||||||
|
mData.getTableModel (CSMWorld::UniversalId::Type_References);
|
||||||
|
|
||||||
if (mReferenceableId.empty())
|
connect (references, SIGNAL (dataChanged (const QModelIndex&, const QModelIndex&)),
|
||||||
return;
|
this, SLOT (referenceDataChanged (const QModelIndex&, const QModelIndex&)));
|
||||||
|
connect (references, SIGNAL (rowsAboutToBeRemoved (const QModelIndex&, int, int)),
|
||||||
int column =
|
this, SLOT (referenceAboutToBeRemoved (const QModelIndex&, int, int)));
|
||||||
mData.getReferenceables().findColumnIndex (CSMWorld::Columns::ColumnId_Model);
|
|
||||||
|
|
||||||
int row = mData.getReferenceables().searchId (mReferenceableId);
|
|
||||||
|
|
||||||
if (row==-1)
|
|
||||||
return;
|
|
||||||
|
|
||||||
QVariant value = mData.getReferenceables().getData (row, column);
|
|
||||||
|
|
||||||
if (!value.isValid())
|
|
||||||
return;
|
|
||||||
|
|
||||||
std::string model = value.toString().toUtf8().constData();
|
|
||||||
|
|
||||||
if (model.empty())
|
|
||||||
return;
|
|
||||||
|
|
||||||
mObject = NifOgre::Loader::createObjects (mNode, "Meshes\\" + model);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void CSVRender::PreviewWidget::adjust()
|
void CSVRender::PreviewWidget::referenceableDataChanged (const QModelIndex& topLeft,
|
||||||
{
|
|
||||||
if (mNode)
|
|
||||||
{
|
|
||||||
int row = mData.getReferences().getIndex (mReferenceId);
|
|
||||||
|
|
||||||
float scale = mData.getReferences().getData (row, mData.getReferences().
|
|
||||||
findColumnIndex (CSMWorld::Columns::ColumnId_Scale)).toFloat();
|
|
||||||
float rotX = mData.getReferences().getData (row, mData.getReferences().
|
|
||||||
findColumnIndex (CSMWorld::Columns::ColumnId_PositionXRot)).toFloat();
|
|
||||||
float rotY = mData.getReferences().getData (row, mData.getReferences().
|
|
||||||
findColumnIndex (CSMWorld::Columns::ColumnId_PositionYRot)).toFloat();
|
|
||||||
float rotZ = mData.getReferences().getData (row, mData.getReferences().
|
|
||||||
findColumnIndex (CSMWorld::Columns::ColumnId_PositionZRot)).toFloat();
|
|
||||||
|
|
||||||
mNode->setScale (scale, scale, scale);
|
|
||||||
|
|
||||||
Ogre::Quaternion xr (Ogre::Radian(-rotX), Ogre::Vector3::UNIT_X);
|
|
||||||
|
|
||||||
Ogre::Quaternion yr (Ogre::Radian(-rotY), Ogre::Vector3::UNIT_Y);
|
|
||||||
|
|
||||||
Ogre::Quaternion zr (Ogre::Radian(-rotZ), Ogre::Vector3::UNIT_Z);
|
|
||||||
|
|
||||||
mNode->setOrientation (xr*yr*zr);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
CSVRender::PreviewWidget::PreviewWidget (CSMWorld::Data& data,
|
|
||||||
const std::string& referenceableId, QWidget *parent)
|
|
||||||
: SceneWidget (parent), mData (data), mNode (0), mReferenceableId (referenceableId)
|
|
||||||
{
|
|
||||||
setup();
|
|
||||||
}
|
|
||||||
|
|
||||||
CSVRender::PreviewWidget::PreviewWidget (CSMWorld::Data& data,
|
|
||||||
const std::string& referenceableId, const std::string& referenceId, QWidget *parent)
|
|
||||||
: SceneWidget (parent), mData (data), mReferenceableId (referenceableId),
|
|
||||||
mReferenceId (referenceId)
|
|
||||||
{
|
|
||||||
setup();
|
|
||||||
|
|
||||||
adjust();
|
|
||||||
|
|
||||||
QAbstractItemModel *references =
|
|
||||||
mData.getTableModel (CSMWorld::UniversalId::Type_References);
|
|
||||||
|
|
||||||
connect (references, SIGNAL (dataChanged (const QModelIndex&, const QModelIndex&)),
|
|
||||||
this, SLOT (ReferenceDataChanged (const QModelIndex&, const QModelIndex&)));
|
|
||||||
connect (references, SIGNAL (rowsAboutToBeRemoved (const QModelIndex&, int, int)),
|
|
||||||
this, SLOT (ReferenceAboutToBeRemoved (const QModelIndex&, int, int)));
|
|
||||||
}
|
|
||||||
|
|
||||||
void CSVRender::PreviewWidget::ReferenceableDataChanged (const QModelIndex& topLeft,
|
|
||||||
const QModelIndex& bottomRight)
|
const QModelIndex& bottomRight)
|
||||||
{
|
{
|
||||||
if (mReferenceableId.empty())
|
if (mObject.referenceableDataChanged (topLeft, bottomRight))
|
||||||
return;
|
|
||||||
|
|
||||||
CSMWorld::IdTable& referenceables = dynamic_cast<CSMWorld::IdTable&> (
|
|
||||||
*mData.getTableModel (CSMWorld::UniversalId::Type_Referenceables));
|
|
||||||
|
|
||||||
QModelIndex index = referenceables.getModelIndex (mReferenceableId, 0);
|
|
||||||
|
|
||||||
if (index.row()>=topLeft.row() && index.row()<=bottomRight.row())
|
|
||||||
{
|
|
||||||
/// \todo possible optimisation; check columns and only update if relevant columns have
|
|
||||||
/// changed
|
|
||||||
setModel();
|
|
||||||
flagAsModified();
|
flagAsModified();
|
||||||
|
|
||||||
|
if (mObject.getReferenceId().empty())
|
||||||
|
{
|
||||||
|
CSMWorld::IdTable& referenceables = dynamic_cast<CSMWorld::IdTable&> (
|
||||||
|
*mData.getTableModel (CSMWorld::UniversalId::Type_Referenceables));
|
||||||
|
|
||||||
|
QModelIndex index = referenceables.getModelIndex (mObject.getReferenceableId(),
|
||||||
|
referenceables.findColumnIndex (CSMWorld::Columns::ColumnId_Modification));
|
||||||
|
|
||||||
|
if (referenceables.data (index).toInt()==CSMWorld::RecordBase::State_Deleted)
|
||||||
|
emit closeRequest();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void CSVRender::PreviewWidget::ReferenceableAboutToBeRemoved (const QModelIndex& parent, int start,
|
void CSVRender::PreviewWidget::referenceableAboutToBeRemoved (const QModelIndex& parent, int start,
|
||||||
int end)
|
int end)
|
||||||
{
|
{
|
||||||
if (mReferenceableId.empty())
|
if (mObject.referenceableAboutToBeRemoved (parent, start, end))
|
||||||
|
flagAsModified();
|
||||||
|
|
||||||
|
if (mObject.getReferenceableId().empty())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
CSMWorld::IdTable& referenceables = dynamic_cast<CSMWorld::IdTable&> (
|
CSMWorld::IdTable& referenceables = dynamic_cast<CSMWorld::IdTable&> (
|
||||||
*mData.getTableModel (CSMWorld::UniversalId::Type_Referenceables));
|
*mData.getTableModel (CSMWorld::UniversalId::Type_Referenceables));
|
||||||
|
|
||||||
QModelIndex index = referenceables.getModelIndex (mReferenceableId, 0);
|
QModelIndex index = referenceables.getModelIndex (mObject.getReferenceableId(), 0);
|
||||||
|
|
||||||
if (index.row()>=start && index.row()<=end)
|
if (index.row()>=start && index.row()<=end)
|
||||||
{
|
{
|
||||||
if (mReferenceId.empty())
|
if (mObject.getReferenceId().empty())
|
||||||
{
|
{
|
||||||
// this is a preview for a referenceble
|
// this is a preview for a referenceble
|
||||||
emit closeRequest();
|
emit closeRequest();
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
|
||||||
// this is a preview for a reference
|
|
||||||
mObject.setNull();
|
|
||||||
flagAsModified();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void CSVRender::PreviewWidget::ReferenceDataChanged (const QModelIndex& topLeft,
|
void CSVRender::PreviewWidget::referenceDataChanged (const QModelIndex& topLeft,
|
||||||
const QModelIndex& bottomRight)
|
const QModelIndex& bottomRight)
|
||||||
{
|
{
|
||||||
if (mReferenceId.empty())
|
if (mObject.referenceDataChanged (topLeft, bottomRight))
|
||||||
|
flagAsModified();
|
||||||
|
|
||||||
|
if (mObject.getReferenceId().empty())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
CSMWorld::IdTable& references = dynamic_cast<CSMWorld::IdTable&> (
|
CSMWorld::IdTable& references = dynamic_cast<CSMWorld::IdTable&> (
|
||||||
*mData.getTableModel (CSMWorld::UniversalId::Type_References));
|
*mData.getTableModel (CSMWorld::UniversalId::Type_References));
|
||||||
|
|
||||||
|
// check for deleted state
|
||||||
|
{
|
||||||
|
QModelIndex index = references.getModelIndex (mObject.getReferenceId(),
|
||||||
|
references.findColumnIndex (CSMWorld::Columns::ColumnId_Modification));
|
||||||
|
|
||||||
|
if (references.data (index).toInt()==CSMWorld::RecordBase::State_Deleted)
|
||||||
|
{
|
||||||
|
emit closeRequest();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
int columnIndex = references.findColumnIndex (CSMWorld::Columns::ColumnId_ReferenceableId);
|
int columnIndex = references.findColumnIndex (CSMWorld::Columns::ColumnId_ReferenceableId);
|
||||||
|
|
||||||
QModelIndex index = references.getModelIndex (mReferenceId, columnIndex);
|
QModelIndex index = references.getModelIndex (mObject.getReferenceId(), columnIndex);
|
||||||
|
|
||||||
if (index.row()>=topLeft.row() && index.row()<=bottomRight.row())
|
if (index.row()>=topLeft.row() && index.row()<=bottomRight.row())
|
||||||
{
|
|
||||||
/// \todo possible optimisation; check columns and only update if relevant columns have
|
|
||||||
/// changed
|
|
||||||
adjust();
|
|
||||||
|
|
||||||
if (index.column()>=topLeft.column() && index.column()<=bottomRight.row())
|
if (index.column()>=topLeft.column() && index.column()<=bottomRight.row())
|
||||||
{
|
emit referenceableIdChanged (mObject.getReferenceableId());
|
||||||
mReferenceableId = references.data (index).toString().toUtf8().constData();
|
|
||||||
emit referenceableIdChanged (mReferenceableId);
|
|
||||||
setModel();
|
|
||||||
}
|
|
||||||
|
|
||||||
flagAsModified();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void CSVRender::PreviewWidget::ReferenceAboutToBeRemoved (const QModelIndex& parent, int start,
|
void CSVRender::PreviewWidget::referenceAboutToBeRemoved (const QModelIndex& parent, int start,
|
||||||
int end)
|
int end)
|
||||||
{
|
{
|
||||||
if (mReferenceId.empty())
|
if (mObject.getReferenceId().empty())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
CSMWorld::IdTable& references = dynamic_cast<CSMWorld::IdTable&> (
|
CSMWorld::IdTable& references = dynamic_cast<CSMWorld::IdTable&> (
|
||||||
*mData.getTableModel (CSMWorld::UniversalId::Type_References));
|
*mData.getTableModel (CSMWorld::UniversalId::Type_References));
|
||||||
|
|
||||||
QModelIndex index = references.getModelIndex (mReferenceId, 0);
|
QModelIndex index = references.getModelIndex (mObject.getReferenceId(), 0);
|
||||||
|
|
||||||
if (index.row()>=start && index.row()<=end)
|
if (index.row()>=start && index.row()<=end)
|
||||||
emit closeRequest();
|
emit closeRequest();
|
||||||
|
|
|
@ -1,11 +1,10 @@
|
||||||
#ifndef OPENCS_VIEW_PREVIEWWIDGET_H
|
#ifndef OPENCS_VIEW_PREVIEWWIDGET_H
|
||||||
#define OPENCS_VIEW_PREVIEWWIDGET_H
|
#define OPENCS_VIEW_PREVIEWWIDGET_H
|
||||||
|
|
||||||
#include <components/nifogre/ogrenifloader.hpp>
|
|
||||||
|
|
||||||
#include "scenewidget.hpp"
|
#include "scenewidget.hpp"
|
||||||
|
|
||||||
#include "navigationorbit.hpp"
|
#include "navigationorbit.hpp"
|
||||||
|
#include "object.hpp"
|
||||||
|
|
||||||
class QModelIndex;
|
class QModelIndex;
|
||||||
|
|
||||||
|
@ -22,26 +21,13 @@ namespace CSVRender
|
||||||
|
|
||||||
CSMWorld::Data& mData;
|
CSMWorld::Data& mData;
|
||||||
CSVRender::NavigationOrbit mOrbit;
|
CSVRender::NavigationOrbit mOrbit;
|
||||||
NifOgre::ObjectScenePtr mObject;
|
Object mObject;
|
||||||
Ogre::SceneNode *mNode;
|
|
||||||
std::string mReferenceId;
|
|
||||||
std::string mReferenceableId;
|
|
||||||
|
|
||||||
void setup();
|
|
||||||
|
|
||||||
void setModel();
|
|
||||||
|
|
||||||
void adjust();
|
|
||||||
///< Adjust referenceable preview according to the reference
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
PreviewWidget (CSMWorld::Data& data, const std::string& referenceableId,
|
PreviewWidget (CSMWorld::Data& data, const std::string& id, bool referenceable,
|
||||||
QWidget *parent = 0);
|
QWidget *parent = 0);
|
||||||
|
|
||||||
PreviewWidget (CSMWorld::Data& data, const std::string& referenceableId,
|
|
||||||
const std::string& referenceId, QWidget *parent = 0);
|
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
|
|
||||||
void closeRequest();
|
void closeRequest();
|
||||||
|
@ -50,14 +36,14 @@ namespace CSVRender
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
|
|
||||||
void ReferenceableDataChanged (const QModelIndex& topLeft,
|
void referenceableDataChanged (const QModelIndex& topLeft,
|
||||||
const QModelIndex& bottomRight);
|
const QModelIndex& bottomRight);
|
||||||
|
|
||||||
void ReferenceableAboutToBeRemoved (const QModelIndex& parent, int start, int end);
|
void referenceableAboutToBeRemoved (const QModelIndex& parent, int start, int end);
|
||||||
|
|
||||||
void ReferenceDataChanged (const QModelIndex& topLeft, const QModelIndex& bottomRight);
|
void referenceDataChanged (const QModelIndex& topLeft, const QModelIndex& bottomRight);
|
||||||
|
|
||||||
void ReferenceAboutToBeRemoved (const QModelIndex& parent, int start, int end);
|
void referenceAboutToBeRemoved (const QModelIndex& parent, int start, int end);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -23,10 +23,10 @@ CSVWorld::PreviewSubView::PreviewSubView (const CSMWorld::UniversalId& id, CSMDo
|
||||||
referenceableIdChanged (referenceableId);
|
referenceableIdChanged (referenceableId);
|
||||||
|
|
||||||
mScene =
|
mScene =
|
||||||
new CSVRender::PreviewWidget (document.getData(), referenceableId, id.getId(), this);
|
new CSVRender::PreviewWidget (document.getData(), id.getId(), false, this);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
mScene = new CSVRender::PreviewWidget (document.getData(), id.getId(), this);
|
mScene = new CSVRender::PreviewWidget (document.getData(), id.getId(), true, this);
|
||||||
|
|
||||||
SceneToolbar *toolbar = new SceneToolbar (48+6, this);
|
SceneToolbar *toolbar = new SceneToolbar (48+6, this);
|
||||||
|
|
||||||
|
|
|
@ -115,12 +115,12 @@ void CSVWorld::Table::contextMenuEvent (QContextMenuEvent *event)
|
||||||
|
|
||||||
if (selectedRows.size()==1)
|
if (selectedRows.size()==1)
|
||||||
{
|
{
|
||||||
|
int row = selectedRows.begin()->row();
|
||||||
|
|
||||||
|
row = mProxyModel->mapToSource (mProxyModel->index (row, 0)).row();
|
||||||
|
|
||||||
if (mModel->getFeatures() & CSMWorld::IdTable::Feature_View)
|
if (mModel->getFeatures() & CSMWorld::IdTable::Feature_View)
|
||||||
{
|
{
|
||||||
int row = selectedRows.begin()->row();
|
|
||||||
|
|
||||||
row = mProxyModel->mapToSource (mProxyModel->index (row, 0)).row();
|
|
||||||
|
|
||||||
CSMWorld::UniversalId id = mModel->view (row).first;
|
CSMWorld::UniversalId id = mModel->view (row).first;
|
||||||
|
|
||||||
int index = mDocument.getData().getCells().searchId (id.getId());
|
int index = mDocument.getData().getCells().searchId (id.getId());
|
||||||
|
@ -132,7 +132,16 @@ void CSVWorld::Table::contextMenuEvent (QContextMenuEvent *event)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mModel->getFeatures() & CSMWorld::IdTable::Feature_Preview)
|
if (mModel->getFeatures() & CSMWorld::IdTable::Feature_Preview)
|
||||||
menu.addAction (mPreviewAction);
|
{
|
||||||
|
QModelIndex index = mModel->index (row,
|
||||||
|
mModel->findColumnIndex (CSMWorld::Columns::ColumnId_Modification));
|
||||||
|
|
||||||
|
CSMWorld::RecordBase::State state = static_cast<CSMWorld::RecordBase::State> (
|
||||||
|
mModel->data (index).toInt());
|
||||||
|
|
||||||
|
if (state!=CSMWorld::RecordBase::State_Deleted)
|
||||||
|
menu.addAction (mPreviewAction);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
menu.exec (event->globalPos());
|
menu.exec (event->globalPos());
|
||||||
|
@ -377,7 +386,12 @@ void CSVWorld::Table::previewRecord()
|
||||||
{
|
{
|
||||||
std::string id = getUniversalId (selectedRows.begin()->row()).getId();
|
std::string id = getUniversalId (selectedRows.begin()->row()).getId();
|
||||||
|
|
||||||
emit editRequest (CSMWorld::UniversalId (CSMWorld::UniversalId::Type_Preview, id) , "");
|
QModelIndex index = mModel->getModelIndex (id,
|
||||||
|
mModel->findColumnIndex (CSMWorld::Columns::ColumnId_Modification));
|
||||||
|
|
||||||
|
if (mModel->data (index)!=CSMWorld::RecordBase::State_Deleted)
|
||||||
|
emit editRequest (CSMWorld::UniversalId (CSMWorld::UniversalId::Type_Preview, id),
|
||||||
|
"");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue