From 10ce47938b3de5f6a556b72acfbf4aef41c6a491 Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Fri, 21 Mar 2014 11:22:43 +0100 Subject: [PATCH] update preview on reference/referenceable changes --- apps/opencs/view/render/previewwidget.cpp | 134 ++++++++++++++++++---- apps/opencs/view/render/previewwidget.hpp | 30 +++-- apps/opencs/view/render/scenewidget.cpp | 5 + apps/opencs/view/render/scenewidget.hpp | 2 + 4 files changed, 139 insertions(+), 32 deletions(-) diff --git a/apps/opencs/view/render/previewwidget.cpp b/apps/opencs/view/render/previewwidget.cpp index 43d45f4cb..9b64cf6f4 100644 --- a/apps/opencs/view/render/previewwidget.cpp +++ b/apps/opencs/view/render/previewwidget.cpp @@ -4,36 +4,55 @@ #include #include "../../model/world/data.hpp" +#include "../../model/world/idtable.hpp" -void CSVRender::PreviewWidget::setup (const std::string& id) +void CSVRender::PreviewWidget::setup() { setNavigation (&mOrbit); - int column = mData.getReferenceables().findColumnIndex (CSMWorld::Columns::ColumnId_Model); - - int row = mData.getReferenceables().getIndex (id); - - QVariant value = mData.getReferenceables().getData (row, column); - - if (!value.isValid()) - return; - - std::string model = value.toString().toUtf8().constData(); - - if (model.empty()) - return; - mNode = getSceneManager()->getRootSceneNode()->createChildSceneNode(); mNode->setPosition (Ogre::Vector3 (0, 0, 0)); - mObject = NifOgre::Loader::createObjects (mNode, "Meshes\\" + model); + setModel(); + + QAbstractItemModel *referenceables = + mData.getTableModel (CSMWorld::UniversalId::Type_Referenceables); + + connect (referenceables, SIGNAL (dataChanged (const QModelIndex&, const QModelIndex&)), + this, SLOT (ReferenceableDataChanged (const QModelIndex&, const QModelIndex&))); + connect (referenceables, SIGNAL (rowsAboutToBeRemoved (const QModelIndex&, int, int)), + this, SLOT (ReferenceableAboutToBeRemoved (const QModelIndex&, int, int))); } -void CSVRender::PreviewWidget::adjust (const std::string& id) +void CSVRender::PreviewWidget::setModel() { if (mNode) { - int row = mData.getReferences().getIndex (id); + mObject.setNull(); + + int column = mData.getReferenceables().findColumnIndex (CSMWorld::Columns::ColumnId_Model); + + int row = mData.getReferenceables().getIndex (mReferenceableId); + + 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() +{ + if (mNode) + { + int row = mData.getReferences().getIndex (mReferenceId); float scale = mData.getReferences().getData (row, mData.getReferences(). findColumnIndex (CSMWorld::Columns::ColumnId_Scale)).toFloat(); @@ -56,17 +75,82 @@ void CSVRender::PreviewWidget::adjust (const std::string& id) } } -CSVRender::PreviewWidget::PreviewWidget (const CSMWorld::Data& data, +CSVRender::PreviewWidget::PreviewWidget (CSMWorld::Data& data, const std::string& referenceableId, QWidget *parent) -: SceneWidget (parent), mData (data), mNode (0) +: SceneWidget (parent), mData (data), mNode (0), mReferenceableId (referenceableId) { - setup (referenceableId); + setup(); } -CSVRender::PreviewWidget::PreviewWidget (const CSMWorld::Data& data, +CSVRender::PreviewWidget::PreviewWidget (CSMWorld::Data& data, const std::string& referenceableId, const std::string& referenceId, QWidget *parent) -: SceneWidget (parent), mData (data) +: SceneWidget (parent), mData (data), mReferenceableId (referenceableId), + mReferenceId (referenceId) { - setup (referenceableId); - adjust (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) +{ + CSMWorld::IdTable& referenceables = dynamic_cast ( + *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(); + } +} + +void CSVRender::PreviewWidget::ReferenceableAboutToBeRemoved (const QModelIndex& parent, int start, + int end) +{ + +} + +void CSVRender::PreviewWidget::ReferenceDataChanged (const QModelIndex& topLeft, + const QModelIndex& bottomRight) +{ + CSMWorld::IdTable& references = dynamic_cast ( + *mData.getTableModel (CSMWorld::UniversalId::Type_References)); + + int columnIndex = references.findColumnIndex (CSMWorld::Columns::ColumnId_ReferenceableId); + + QModelIndex index = references.getModelIndex (mReferenceId, columnIndex); + + 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()) + { + mReferenceableId = references.data (index).toString().toUtf8().constData(); + setModel(); + } + + flagAsModified(); + } +} + +void CSVRender::PreviewWidget::ReferenceAboutToBeRemoved (const QModelIndex& parent, int start, + int end) +{ + } diff --git a/apps/opencs/view/render/previewwidget.hpp b/apps/opencs/view/render/previewwidget.hpp index b3abd5587..2b6517e71 100644 --- a/apps/opencs/view/render/previewwidget.hpp +++ b/apps/opencs/view/render/previewwidget.hpp @@ -7,6 +7,8 @@ #include "navigationorbit.hpp" +class QModelIndex; + namespace CSMWorld { class Data; @@ -18,28 +20,42 @@ namespace CSVRender { Q_OBJECT - const CSMWorld::Data& mData; + CSMWorld::Data& mData; CSVRender::NavigationOrbit mOrbit; NifOgre::ObjectScenePtr mObject; Ogre::SceneNode *mNode; + std::string mReferenceId; + std::string mReferenceableId; - void setup (const std::string& id); - ///< \param id ID of the referenceable to be viewed + void setup(); - void adjust (const std::string& id); - ///< \param id ID of the reference to be viewed + void setModel(); + + void adjust(); + ///< Adjust referenceable preview according to the reference public: - PreviewWidget (const CSMWorld::Data& data, const std::string& referenceableId, + PreviewWidget (CSMWorld::Data& data, const std::string& referenceableId, QWidget *parent = 0); - PreviewWidget (const CSMWorld::Data& data, const std::string& referenceableId, + PreviewWidget (CSMWorld::Data& data, const std::string& referenceableId, const std::string& referenceId, QWidget *parent = 0); signals: void closeRequest(); + + private slots: + + void ReferenceableDataChanged (const QModelIndex& topLeft, + const QModelIndex& bottomRight); + + void ReferenceableAboutToBeRemoved (const QModelIndex& parent, int start, int end); + + void ReferenceDataChanged (const QModelIndex& topLeft, const QModelIndex& bottomRight); + + void ReferenceAboutToBeRemoved (const QModelIndex& parent, int start, int end); }; } diff --git a/apps/opencs/view/render/scenewidget.cpp b/apps/opencs/view/render/scenewidget.cpp index 5eec702d3..6b2ca85b5 100644 --- a/apps/opencs/view/render/scenewidget.cpp +++ b/apps/opencs/view/render/scenewidget.cpp @@ -118,6 +118,11 @@ namespace CSVRender return mSceneMgr; } + void SceneWidget::flagAsModified() + { + mUpdate = true; + } + void SceneWidget::paintEvent(QPaintEvent* e) { if (!mWindow) diff --git a/apps/opencs/view/render/scenewidget.hpp b/apps/opencs/view/render/scenewidget.hpp index 05b06b287..375c877d2 100644 --- a/apps/opencs/view/render/scenewidget.hpp +++ b/apps/opencs/view/render/scenewidget.hpp @@ -36,6 +36,8 @@ namespace CSVRender Ogre::SceneManager *getSceneManager(); + void flagAsModified(); + private: void paintEvent(QPaintEvent* e); void resizeEvent(QResizeEvent* e);