From efc79e8ec62f35b8d7cf03615fb022bc5f43cfcf Mon Sep 17 00:00:00 2001 From: Daniel Evans Date: Tue, 14 Apr 2015 01:06:50 +0100 Subject: [PATCH] Overhaul Model Viewer behaviour with visibility toggle --- rwviewer/ViewerWidget.cpp | 7 ++- rwviewer/ViewerWidget.hpp | 3 +- rwviewer/ViewerWindow.cpp | 11 ++++- rwviewer/ViewerWindow.hpp | 2 + rwviewer/models/DFFFramesTreeModel.cpp | 61 +++++++++++++++++++++++++- rwviewer/models/DFFFramesTreeModel.hpp | 14 ++++-- rwviewer/views/ModelViewer.cpp | 19 +++++++- rwviewer/views/ModelViewer.hpp | 10 +++++ rwviewer/views/ObjectViewer.cpp | 32 ++++++++++++-- rwviewer/views/ObjectViewer.hpp | 7 +++ rwviewer/widgets/ModelFramesWidget.cpp | 4 +- rwviewer/widgets/ModelFramesWidget.hpp | 2 +- 12 files changed, 154 insertions(+), 18 deletions(-) diff --git a/rwviewer/ViewerWidget.cpp b/rwviewer/ViewerWidget.cpp index 4fbcacbe..19f50138 100644 --- a/rwviewer/ViewerWidget.cpp +++ b/rwviewer/ViewerWidget.cpp @@ -165,7 +165,7 @@ GameWorld* ViewerWidget::world() return gworld; } -void ViewerWidget::showItem(qint16 item) +void ViewerWidget::showObject(qint16 item) { currentObjectID = item; @@ -244,6 +244,11 @@ Model* ViewerWidget::currentModel() const return activeModel; } +GameObject* ViewerWidget::currentObject() const +{ + return dummyObject; +} + void ViewerWidget::mousePressEvent(QMouseEvent* e) { dragging = true; diff --git a/rwviewer/ViewerWidget.hpp b/rwviewer/ViewerWidget.hpp index 5bb35d7e..acffdf21 100644 --- a/rwviewer/ViewerWidget.hpp +++ b/rwviewer/ViewerWidget.hpp @@ -55,12 +55,13 @@ public: virtual void paintGL(); Model *currentModel() const; + GameObject* currentObject() const; GameWorld* world(); public slots: - void showItem(qint16 item); + void showObject(qint16 item); void showModel(Model* model); void selectFrame(ModelFrame* frame); diff --git a/rwviewer/ViewerWindow.cpp b/rwviewer/ViewerWindow.cpp index ffc3b397..16bc9325 100644 --- a/rwviewer/ViewerWindow.cpp +++ b/rwviewer/ViewerWindow.cpp @@ -57,7 +57,8 @@ ViewerWindow::ViewerWindow(QWidget* parent, Qt::WindowFlags flags) viewSwitcher->addWidget(objectViewer); viewSwitcher->addWidget(modelViewer); - connect(objectViewer, SIGNAL(modelChanged(Model*)), modelViewer, SLOT(showModel(Model*))); + //connect(objectViewer, SIGNAL(modelChanged(Model*)), modelViewer, SLOT(showModel(Model*))); + connect(objectViewer, SIGNAL(showObjectModel(uint16_t)), this, SLOT(showObjectModel(uint16_t))); objectViewer->setViewerWidget( viewerWidget ); @@ -199,6 +200,14 @@ void ViewerWindow::switchWidget() } } +void ViewerWindow::showObjectModel(uint16_t object) +{ + // Switch to the model viewer + modelViewer->setViewerWidget( viewerWidget ); + viewSwitcher->setCurrentIndex( viewSwitcher->indexOf(modelViewer) ); + modelViewer->showObject(object); +} + void ViewerWindow::updateRecentGames() { QSettings settings("OpenRW", "rwviewer"); diff --git a/rwviewer/ViewerWindow.hpp b/rwviewer/ViewerWindow.hpp index 4f912a06..08548de4 100644 --- a/rwviewer/ViewerWindow.hpp +++ b/rwviewer/ViewerWindow.hpp @@ -63,6 +63,8 @@ private slots: void switchWidget(); + void showObjectModel(uint16_t object); + private: QList recentGames; diff --git a/rwviewer/models/DFFFramesTreeModel.cpp b/rwviewer/models/DFFFramesTreeModel.cpp index 50146a09..ebf08576 100644 --- a/rwviewer/models/DFFFramesTreeModel.cpp +++ b/rwviewer/models/DFFFramesTreeModel.cpp @@ -1,8 +1,9 @@ #include "DFFFramesTreeModel.hpp" #include +#include -DFFFramesTreeModel::DFFFramesTreeModel(Model *m, QObject* parent) - : QAbstractItemModel(parent), model(m) +DFFFramesTreeModel::DFFFramesTreeModel(Model *m, Skeleton* skel, QObject* parent) + : QAbstractItemModel(parent), model(m), skeleton(skel) { } @@ -63,9 +64,65 @@ QVariant DFFFramesTreeModel::data(const QModelIndex& index, int role) const return QString(f->getName().c_str()); } } + else if( role == Qt::CheckStateRole ) + { + if( index.column() == 0 ) + { + if( skeleton ) + { + return skeleton->getData(f->getIndex()).enabled ? + Qt::Checked : Qt::Unchecked; + } + } + } return QVariant(); } +bool DFFFramesTreeModel::setData(const QModelIndex& index, const QVariant& value, int role) +{ + if(! index.isValid() ) + { + return false; + } + + ModelFrame* f = static_cast(index.internalPointer()); + + if( role == Qt::CheckStateRole ) + { + if( index.column() == 0 && skeleton ) + { + if( (Qt::CheckState)value.toInt() == Qt::Checked ) + { + skeleton->setEnabled(f, true); + } + else + { + skeleton->setEnabled(f, false); + } + return true; + } + } + + return false; +} + +Qt::ItemFlags DFFFramesTreeModel::flags(const QModelIndex& index) const +{ + if(! index.isValid() ) + { + return 0; + } + + Qt::ItemFlags flags = Qt::ItemIsEnabled | Qt::ItemIsSelectable; + + if( index.column() == 0 && skeleton ) + { + flags |= Qt::ItemIsUserCheckable; + } + + return flags; +} + QVariant DFFFramesTreeModel::headerData(int section, Qt::Orientation orientation, int role) const { if(orientation == Qt::Horizontal) { diff --git a/rwviewer/models/DFFFramesTreeModel.hpp b/rwviewer/models/DFFFramesTreeModel.hpp index a0b6b66b..7eca632f 100644 --- a/rwviewer/models/DFFFramesTreeModel.hpp +++ b/rwviewer/models/DFFFramesTreeModel.hpp @@ -5,20 +5,26 @@ #include class Model; +class Skeleton; class DFFFramesTreeModel : public QAbstractItemModel { Model* model; + Skeleton* skeleton; public: - explicit DFFFramesTreeModel(Model* m, QObject* parent = 0); + explicit DFFFramesTreeModel(Model* m, Skeleton* skel, QObject* parent = 0); virtual int columnCount(const QModelIndex& parent = QModelIndex()) const; virtual int rowCount(const QModelIndex& parent = QModelIndex()) const; - - virtual QVariant data(const QModelIndex& index, int role = Qt::DisplayRole) const; - + + virtual QVariant data(const QModelIndex& index, int role = Qt::DisplayRole) const; + + virtual bool setData(const QModelIndex& index, const QVariant& value, int role); + + virtual Qt::ItemFlags flags(const QModelIndex& index) const; + virtual QModelIndex index(int row, int column, const QModelIndex& parent = QModelIndex()) const; virtual QModelIndex parent(const QModelIndex& child) const; diff --git a/rwviewer/views/ModelViewer.cpp b/rwviewer/views/ModelViewer.cpp index a8876ebd..d46d7135 100644 --- a/rwviewer/views/ModelViewer.cpp +++ b/rwviewer/views/ModelViewer.cpp @@ -1,10 +1,12 @@ #include "ModelViewer.hpp" #include #include "ViewerWidget.hpp" +#include +#include #include ModelViewer::ModelViewer(ViewerWidget* viewer, QWidget* parent, Qt::WindowFlags f) -: QWidget(parent, f), _world(nullptr), viewing(nullptr) +: QWidget(parent, f), _world(nullptr), viewing(nullptr), skeleton(nullptr) { mainSplit = new QSplitter; mainLayout = new QVBoxLayout; @@ -40,6 +42,19 @@ void ModelViewer::showData(GameWorld* world) void ModelViewer::showModel(Model* model) { viewing = model; + if( skeleton ) + { + delete skeleton; + } + skeleton = new Skeleton(); viewerWidget->showModel(model); - frames->setModel(model); + frames->setModel(model, nullptr); +} + +void ModelViewer::showObject(uint16_t object) +{ + viewerWidget->showObject(object); + viewing = viewerWidget->currentModel(); + skeleton = viewerWidget->currentObject()->skeleton; + frames->setModel(viewing, skeleton); } diff --git a/rwviewer/views/ModelViewer.hpp b/rwviewer/views/ModelViewer.hpp index df887c62..93fb04da 100644 --- a/rwviewer/views/ModelViewer.hpp +++ b/rwviewer/views/ModelViewer.hpp @@ -12,6 +12,7 @@ class ViewerWidget; class Model; +class Skeleton; class ModelFramesWidget; class ModelViewer : public QWidget @@ -20,6 +21,7 @@ class ModelViewer : public QWidget GameWorld* _world; Model* viewing; + Skeleton* skeleton; QSplitter* mainSplit; QVBoxLayout* mainLayout; @@ -39,8 +41,16 @@ public: public slots: + /** + * Display a raw model + */ void showModel(Model* model); + /** + * Display a game object's model + */ + void showObject(uint16_t object); + void showData(GameWorld* world); }; diff --git a/rwviewer/views/ObjectViewer.cpp b/rwviewer/views/ObjectViewer.cpp index eebc591a..5296129a 100644 --- a/rwviewer/views/ObjectViewer.cpp +++ b/rwviewer/views/ObjectViewer.cpp @@ -2,6 +2,7 @@ #include #include "ViewerWidget.hpp" #include +#include ObjectViewer::ObjectViewer(ViewerWidget* viewer, QWidget* parent, Qt::WindowFlags f) : QWidget(parent, f) @@ -10,6 +11,13 @@ ObjectViewer::ObjectViewer(ViewerWidget* viewer, QWidget* parent, Qt::WindowFlag objectList = new QTableView; + objectMenu = new QMenu(objectList); + objectList->setContextMenuPolicy(Qt::CustomContextMenu); + auto viewModelAction = new QAction("View Model", objectMenu); + objectMenu->addAction(viewModelAction); + connect(viewModelAction, SIGNAL(triggered()), this, SLOT(menuViewModel())); + connect(objectList, SIGNAL(customContextMenuRequested(QPoint)), this, SLOT(onCustomContextMenu(QPoint))); + mainLayout->addWidget(objectList); previewWidget = viewer; @@ -27,8 +35,6 @@ ObjectViewer::ObjectViewer(ViewerWidget* viewer, QWidget* parent, Qt::WindowFlag infoLayout->addWidget(new QLabel("Model"), 3, 0); infoLayout->addWidget(previewModel, 3, 1); - //infoLayout->addStretch(100); - mainLayout->addLayout(infoLayout); this->setLayout(mainLayout); @@ -77,8 +83,7 @@ void ObjectViewer::showItem(qint16 item) previewModel->setText(QString::fromStdString(v->modelName)); } - previewWidget->showItem(item); - modelChanged( previewWidget->currentModel() ); + previewWidget->showObject(item); } } @@ -107,3 +112,22 @@ void ObjectViewer::showItem(QModelIndex model) showItem(model.internalId()); } +void ObjectViewer::onCustomContextMenu(const QPoint& p) +{ + contextMenuIndex = objectList->indexAt(p); + if ( contextMenuIndex.isValid() ) + { + objectMenu->exec(objectList->mapToGlobal(p)); + } +} + +void ObjectViewer::menuViewModel() +{ + if( contextMenuIndex.isValid() ) + { + auto id = contextMenuIndex.internalId(); + showObjectModel(id); + } +} + + diff --git a/rwviewer/views/ObjectViewer.hpp b/rwviewer/views/ObjectViewer.hpp index b94ba46d..9446247b 100644 --- a/rwviewer/views/ObjectViewer.hpp +++ b/rwviewer/views/ObjectViewer.hpp @@ -25,6 +25,9 @@ class ObjectViewer : public QWidget QLabel* previewID; QLabel* previewModel; QLabel* previewClass; + + QMenu* objectMenu; + QModelIndex contextMenuIndex; public: ObjectViewer(ViewerWidget *viewer = 0, QWidget* parent = 0, Qt::WindowFlags f = 0); @@ -40,6 +43,8 @@ signals: void modelChanged(Model* model); + void showObjectModel(uint16_t object); + public slots: void showItem(qint16 item); @@ -50,6 +55,8 @@ private slots: void showItem(QModelIndex model); + void onCustomContextMenu(const QPoint &); + void menuViewModel(); }; #endif diff --git a/rwviewer/widgets/ModelFramesWidget.cpp b/rwviewer/widgets/ModelFramesWidget.cpp index f8b80dbc..8e92bf78 100644 --- a/rwviewer/widgets/ModelFramesWidget.cpp +++ b/rwviewer/widgets/ModelFramesWidget.cpp @@ -48,7 +48,7 @@ ModelFramesWidget::ModelFramesWidget(QWidget* parent, Qt::WindowFlags flags) setLayout(_layout); } -void ModelFramesWidget::setModel(Model *model) +void ModelFramesWidget::setModel(Model *model, Skeleton* skeleton) { if(framemodel) { delete framemodel; @@ -57,7 +57,7 @@ void ModelFramesWidget::setModel(Model *model) } gmodel = model; if(model != nullptr) { - framemodel = new DFFFramesTreeModel(model, this); + framemodel = new DFFFramesTreeModel(model, skeleton, this); tree->setModel(framemodel); tree->setDisabled(false); connect(tree->selectionModel(), SIGNAL(currentChanged(QModelIndex,QModelIndex)), diff --git a/rwviewer/widgets/ModelFramesWidget.hpp b/rwviewer/widgets/ModelFramesWidget.hpp index fe4f31dc..e1719352 100644 --- a/rwviewer/widgets/ModelFramesWidget.hpp +++ b/rwviewer/widgets/ModelFramesWidget.hpp @@ -31,7 +31,7 @@ public: public slots: - void setModel(Model *model); + void setModel(Model *model, Skeleton* skeleton); signals: