Implemented sorting and context menus on the instance views

This commit is contained in:
parax0 2016-01-23 04:00:26 -07:00
parent 38942988d5
commit cae8caaabb
17 changed files with 421 additions and 255 deletions

View File

@ -195,7 +195,7 @@ void CTemplateWriter::SaveScriptTemplate(CScriptTemplate *pTemp, const TString&
// Write object name
XMLElement *pName = ScriptXML.NewElement("name");
pName->SetText(*pTemp->TemplateName());
pName->SetText(*pTemp->Name());
pRoot->LinkEndChild(pName);
// Write properties

View File

@ -33,7 +33,7 @@ EGame CScriptTemplate::Game()
return mpMaster->GetGame();
}
TString CScriptTemplate::TemplateName() const
TString CScriptTemplate::Name() const
{
return mTemplateName;
}
@ -95,7 +95,7 @@ EVolumeShape CScriptTemplate::VolumeShape(CScriptObject *pObj)
{
if (pObj->Template() != this)
{
Log::Error(pObj->Template()->TemplateName() + " instance somehow called VolumeShape() on " + TemplateName() + " template");
Log::Error(pObj->Template()->Name() + " instance somehow called VolumeShape() on " + Name() + " template");
return eInvalidShape;
}
@ -112,7 +112,7 @@ float CScriptTemplate::VolumeScale(CScriptObject *pObj)
{
if (pObj->Template() != this)
{
Log::Error(pObj->Template()->TemplateName() + " instance somehow called VolumeScale() on " + TemplateName() + " template");
Log::Error(pObj->Template()->Name() + " instance somehow called VolumeScale() on " + Name() + " template");
return -1;
}
@ -169,7 +169,7 @@ s32 CScriptTemplate::CheckVolumeConditions(CScriptObject *pObj, bool LogErrors)
}
if (LogErrors)
Log::Error(pObj->Template()->TemplateName() + " instance " + TString::HexString(pObj->InstanceID(), true, true, 8) + " has unexpected volume shape value of " + TString::HexString((u32) v, true, true));
Log::Error(pObj->Template()->Name() + " instance " + TString::HexString(pObj->InstanceID(), true, true, 8) + " has unexpected volume shape value of " + TString::HexString((u32) v, true, true));
}
return -1;

View File

@ -92,7 +92,7 @@ public:
CMasterTemplate* MasterTemplate();
EGame Game();
TString TemplateName() const;
TString Name() const;
u32 NumPropertySets() const;
ERotationType RotationType() const;
EScaleType ScaleType() const;

View File

@ -33,7 +33,7 @@ CScriptNode::CScriptNode(CScene *pScene, CSceneNode *pParent, CScriptObject *pOb
mScale = mpInstance->Scale();
MarkTransformChanged();
SetName("[" + pTemp->TemplateName() + "] " + mpInstance->InstanceName());
SetName("[" + pTemp->Name() + "] " + mpInstance->InstanceName());
// Determine display assets
mpActiveModel = mpInstance->GetDisplayModel();

View File

@ -189,7 +189,7 @@ void CDamageableTriggerExtra::AddToRenderer(CRenderer *pRenderer, const SViewInf
if (ViewInfo.GameMode && !mpInstance->IsActive())
return;
if ((ViewInfo.ShowFlags & eShowObjectGeometry) == 0)
if (!ViewInfo.GameMode && ((ViewInfo.ShowFlags & eShowObjectGeometry) == 0))
return;
if (mRenderSide != eNoRender)

View File

@ -311,7 +311,7 @@ void CSceneViewport::ContextMenu(QContextMenuEvent* pEvent)
{
CScriptNode *pScript = static_cast<CScriptNode*>(mpHoverNode);
NodeName = pScript->Object()->InstanceName();
mpHideHoverTypeAction->setText( QString("Hide all %1 objects").arg(TO_QSTRING(pScript->Template()->TemplateName())) );
mpHideHoverTypeAction->setText( QString("Hide all %1 objects").arg(TO_QSTRING(pScript->Template()->Name())) );
mpHideHoverLayerAction->setText( QString("Hide layer %1").arg(TO_QSTRING(pScript->Object()->Layer()->Name())) );
}

View File

@ -108,9 +108,7 @@ HEADERS += \
WorldEditor/CAboutDialog.h \
WorldEditor/CLayerEditor.h \
WorldEditor/CLayerModel.h \
WorldEditor/CLayersInstanceModel.h \
WorldEditor/CLinkModel.h \
WorldEditor/CTypesInstanceModel.h \
WorldEditor/CWorldEditor.h \
WorldEditor/WCreateTab.h \
WorldEditor/WInstancesTab.h \
@ -133,7 +131,9 @@ HEADERS += \
PropertyEdit/CPropertyModel.h \
PropertyEdit/CPropertyDelegate.h \
PropertyEdit/CPropertyView.h \
PropertyEdit/CPropertyRelay.h
PropertyEdit/CPropertyRelay.h \
WorldEditor/CInstancesProxyModel.h \
WorldEditor/CInstancesModel.h
# Source Files
SOURCES += \
@ -161,9 +161,7 @@ SOURCES += \
WorldEditor/CAboutDialog.cpp \
WorldEditor/CLayerEditor.cpp \
WorldEditor/CLayerModel.cpp \
WorldEditor/CLayersInstanceModel.cpp \
WorldEditor/CLinkModel.cpp \
WorldEditor/CTypesInstanceModel.cpp \
WorldEditor/CWorldEditor.cpp \
WorldEditor/WCreateTab.cpp \
WorldEditor/WInstancesTab.cpp \
@ -185,7 +183,8 @@ SOURCES += \
WorldEditor/CPoiMapModel.cpp \
PropertyEdit/CPropertyModel.cpp \
PropertyEdit/CPropertyDelegate.cpp \
PropertyEdit/CPropertyView.cpp
PropertyEdit/CPropertyView.cpp \
WorldEditor/CInstancesModel.cpp
# UI Files
FORMS += \

View File

@ -1,4 +1,4 @@
#include "CTypesInstanceModel.h"
#include "CInstancesModel.h"
#include "Editor/UICommon.h"
#include <Core/Resource/Script/CScriptLayer.h>
#include <Core/Scene/CScriptNode.h>
@ -25,10 +25,10 @@
bool SortTemplatesAlphabetical(CScriptTemplate *pA, CScriptTemplate *pB)
{
return (pA->TemplateName() < pB->TemplateName());
return (pA->Name() < pB->Name());
}
CTypesInstanceModel::CTypesInstanceModel(QObject *pParent) : QAbstractItemModel(pParent)
CInstancesModel::CInstancesModel(QObject *pParent) : QAbstractItemModel(pParent)
{
mpEditor = nullptr;
mpScene = nullptr;
@ -38,11 +38,11 @@ CTypesInstanceModel::CTypesInstanceModel(QObject *pParent) : QAbstractItemModel(
mBaseItems << "Script";
}
CTypesInstanceModel::~CTypesInstanceModel()
CInstancesModel::~CInstancesModel()
{
}
QVariant CTypesInstanceModel::headerData(int section, Qt::Orientation orientation, int role) const
QVariant CInstancesModel::headerData(int section, Qt::Orientation orientation, int role) const
{
if ((orientation == Qt::Horizontal) && (role == Qt::DisplayRole))
{
@ -56,7 +56,7 @@ QVariant CTypesInstanceModel::headerData(int section, Qt::Orientation orientatio
return QVariant::Invalid;
}
QModelIndex CTypesInstanceModel::index(int row, int column, const QModelIndex &parent) const
QModelIndex CInstancesModel::index(int row, int column, const QModelIndex &parent) const
{
if (!hasIndex(row, column, parent))
return QModelIndex();
@ -112,7 +112,7 @@ QModelIndex CTypesInstanceModel::index(int row, int column, const QModelIndex &p
return QModelIndex();
}
QModelIndex CTypesInstanceModel::parent(const QModelIndex &child) const
QModelIndex CInstancesModel::parent(const QModelIndex &child) const
{
EIndexType type = IndexType(child);
@ -158,7 +158,7 @@ QModelIndex CTypesInstanceModel::parent(const QModelIndex &child) const
return QModelIndex();
}
int CTypesInstanceModel::rowCount(const QModelIndex &parent) const
int CInstancesModel::rowCount(const QModelIndex &parent) const
{
EIndexType type = IndexType(parent);
@ -194,12 +194,12 @@ int CTypesInstanceModel::rowCount(const QModelIndex &parent) const
return 0;
}
int CTypesInstanceModel::columnCount(const QModelIndex& /*parent*/) const
int CInstancesModel::columnCount(const QModelIndex& /*parent*/) const
{
return 3;
}
QVariant CTypesInstanceModel::data(const QModelIndex &index, int role) const
QVariant CInstancesModel::data(const QModelIndex &index, int role) const
{
EIndexType type = IndexType(index);
@ -223,7 +223,7 @@ QVariant CTypesInstanceModel::data(const QModelIndex &index, int role) const
if (mModelType == eLayers)
return TO_QSTRING(mpEditor->ActiveArea()->GetScriptLayer(index.row())->Name());
else
return TO_QSTRING(mTemplateList[index.row()]->TemplateName());
return TO_QSTRING(mTemplateList[index.row()]->Name());
}
// todo: show/hide button in column 2
else
@ -242,7 +242,7 @@ QVariant CTypesInstanceModel::data(const QModelIndex &index, int role) const
else if (index.column() == 1)
{
if (mModelType == eLayers)
return TO_QSTRING(pObj->Template()->TemplateName());
return TO_QSTRING(pObj->Template()->Name());
else if (mModelType == eTypes)
return TO_QSTRING(pObj->Layer()->Name());
}
@ -308,31 +308,31 @@ QVariant CTypesInstanceModel::data(const QModelIndex &index, int role) const
return QVariant::Invalid;
}
void CTypesInstanceModel::SetEditor(CWorldEditor *pEditor)
void CInstancesModel::SetEditor(CWorldEditor *pEditor)
{
mpEditor = pEditor;
mpScene = (pEditor ? pEditor->Scene() : nullptr);
}
void CTypesInstanceModel::SetMaster(CMasterTemplate *pMaster)
void CInstancesModel::SetMaster(CMasterTemplate *pMaster)
{
mpCurrentMaster = pMaster;
GenerateList();
}
void CTypesInstanceModel::SetArea(CGameArea *pArea)
void CInstancesModel::SetArea(CGameArea *pArea)
{
beginResetModel();
mpArea = pArea;
endResetModel();
}
void CTypesInstanceModel::SetModelType(EInstanceModelType type)
void CInstancesModel::SetModelType(EInstanceModelType type)
{
mModelType = type;
}
void CTypesInstanceModel::NodeCreated(CSceneNode *pNode)
void CInstancesModel::NodeCreated(CSceneNode *pNode)
{
if (mModelType == eTypes)
{
@ -352,7 +352,7 @@ void CTypesInstanceModel::NodeCreated(CSceneNode *pNode)
}
}
void CTypesInstanceModel::NodeDeleted(CSceneNode *pNode)
void CInstancesModel::NodeDeleted(CSceneNode *pNode)
{
if (mModelType = eTypes)
{
@ -378,7 +378,7 @@ void CTypesInstanceModel::NodeDeleted(CSceneNode *pNode)
}
}
CScriptLayer* CTypesInstanceModel::IndexLayer(const QModelIndex& index) const
CScriptLayer* CInstancesModel::IndexLayer(const QModelIndex& index) const
{
if ((mModelType != eLayers) || (IndexNodeType(index) != eScriptType) || (IndexType(index) != eObjectTypeIndex))
return nullptr;
@ -387,7 +387,7 @@ CScriptLayer* CTypesInstanceModel::IndexLayer(const QModelIndex& index) const
return mpArea->GetScriptLayer(RowIndex);
}
CScriptTemplate* CTypesInstanceModel::IndexTemplate(const QModelIndex& index) const
CScriptTemplate* CInstancesModel::IndexTemplate(const QModelIndex& index) const
{
if ((mModelType != eTypes) || (IndexNodeType(index) != eScriptType) || (IndexType(index) != eObjectTypeIndex))
return nullptr;
@ -396,7 +396,7 @@ CScriptTemplate* CTypesInstanceModel::IndexTemplate(const QModelIndex& index) co
return mTemplateList[RowIndex];
}
CScriptObject* CTypesInstanceModel::IndexObject(const QModelIndex& index) const
CScriptObject* CInstancesModel::IndexObject(const QModelIndex& index) const
{
if ((IndexNodeType(index) != eScriptType) || (IndexType(index) != eInstanceIndex))
return nullptr;
@ -405,7 +405,7 @@ CScriptObject* CTypesInstanceModel::IndexObject(const QModelIndex& index) const
}
// ************ STATIC ************
CTypesInstanceModel::EIndexType CTypesInstanceModel::IndexType(const QModelIndex& index)
CInstancesModel::EIndexType CInstancesModel::IndexType(const QModelIndex& index)
{
if (!index.isValid()) return eRootIndex;
else if (index.internalId() == 0) return eNodeTypeIndex;
@ -413,7 +413,7 @@ CTypesInstanceModel::EIndexType CTypesInstanceModel::IndexType(const QModelIndex
else return eInstanceIndex;
}
CTypesInstanceModel::ENodeType CTypesInstanceModel::IndexNodeType(const QModelIndex& index)
CInstancesModel::ENodeType CInstancesModel::IndexNodeType(const QModelIndex& index)
{
EIndexType type = IndexType(index);
@ -428,7 +428,7 @@ CTypesInstanceModel::ENodeType CTypesInstanceModel::IndexNodeType(const QModelIn
}
// ************ PRIVATE ************
void CTypesInstanceModel::GenerateList()
void CInstancesModel::GenerateList()
{
beginResetModel();

View File

@ -9,7 +9,7 @@
#include <QAbstractItemModel>
#include <QList>
class CTypesInstanceModel : public QAbstractItemModel
class CInstancesModel : public QAbstractItemModel
{
Q_OBJECT
@ -38,8 +38,8 @@ private:
QStringList mBaseItems;
public:
explicit CTypesInstanceModel(QObject *pParent = 0);
~CTypesInstanceModel();
explicit CInstancesModel(QObject *pParent = 0);
~CInstancesModel();
QVariant headerData(int section, Qt::Orientation orientation, int role) const;
QModelIndex index(int row, int column, const QModelIndex &parent = QModelIndex()) const;
QModelIndex parent(const QModelIndex &child) const;

View File

@ -0,0 +1,35 @@
#ifndef CINSTANCESPROXYMODEL_H
#define CINSTANCESPROXYMODEL_H
#include <QSortFilterProxyModel>
class CInstancesProxyModel : public QSortFilterProxyModel
{
public:
CInstancesProxyModel(QObject *pParent = 0)
: QSortFilterProxyModel(pParent)
{
setSortCaseSensitivity(Qt::CaseInsensitive);
}
virtual bool lessThan(const QModelIndex& rkLeft, const QModelIndex& rkRight) const
{
// Don't sort from the top two levels and don't sort the Show column
if (rkLeft.parent() == QModelIndex() || rkLeft.parent().parent() == QModelIndex() || rkLeft.column() == 2)
{
if (sortOrder() == Qt::AscendingOrder)
return rkLeft.row() < rkRight.row();
else
return rkLeft.row() > rkRight.row();
}
else
{
QString Left = sourceModel()->data(rkLeft).toString();
QString Right = sourceModel()->data(rkRight).toString();
return Left < Right;
}
}
};
#endif // CINSTANCESPROXYMODEL_H

View File

@ -1,119 +0,0 @@
#include "CLayersInstanceModel.h"
/* The tree has 3 levels:
* 1. Node Type (Script Object, Light) - represented with ID of 0
* 2. Layer - represented with flags
* 3. Instance - represented with pointer to instance (0x1 bit is guaranteed to be clear)
*
* Flags for Layer tree items:
* AAAAAAAAAAAAAAAAAAAAAAAAAAABBBBC
* A: Row index
* B: Node type row index
* C: Item type (ObjType, Instance)
*/
#define LAYERS_ROW_INDEX_MASK 0xFFFFFFE0
#define LAYERS_NODE_TYPE_MASK 0x0000001E
#define LAYERS_ITEM_TYPE_MASK 0x00000001
#define LAYERS_ROW_INDEX_SHIFT 5
#define LAYERS_NODE_TYPE_SHIFT 1
#define LAYERS_ITEM_TYPE_SHIFT 0
CLayersInstanceModel::CLayersInstanceModel(QObject *pParent) : QAbstractItemModel(pParent)
{
}
CLayersInstanceModel::~CLayersInstanceModel()
{
}
QVariant CLayersInstanceModel::headerData(int section, Qt::Orientation orientation, int role) const
{
if ((orientation == Qt::Horizontal) && (role == Qt::DisplayRole))
{
switch (section)
{
case 0: return "Name";
case 1: return "Type";
case 2: return "Show";
}
}
return QVariant::Invalid;
}
QModelIndex CLayersInstanceModel::index(int /*row*/, int /*column*/, const QModelIndex& /*parent*/) const
{
return QModelIndex();
}
QModelIndex CLayersInstanceModel::parent(const QModelIndex& /*child*/) const
{
return QModelIndex();
}
int CLayersInstanceModel::rowCount(const QModelIndex& /*parent*/) const
{
return 0;
}
int CLayersInstanceModel::columnCount(const QModelIndex& /*parent*/) const
{
return 3;
}
QVariant CLayersInstanceModel::data(const QModelIndex& /*index*/, int /*role*/) const
{
return QVariant::Invalid;
}
void CLayersInstanceModel::SetEditor(CWorldEditor *pEditor)
{
mpEditor = pEditor;
mpScene = (pEditor ? pEditor->Scene() : nullptr);
mpArea = (pEditor ? pEditor->ActiveArea() : nullptr);
}
void CLayersInstanceModel::NodeCreated(CSceneNode* /*pNode*/)
{
emit layoutChanged();
}
void CLayersInstanceModel::NodeDeleted(CSceneNode* /*pNode*/)
{
emit layoutChanged();
}
CScriptLayer* CLayersInstanceModel::IndexLayer(const QModelIndex& /*index*/) const
{
return nullptr;
}
CScriptObject* CLayersInstanceModel::IndexObject(const QModelIndex& /*index*/) const
{
return nullptr;
}
// ************ STATIC ************
CLayersInstanceModel::EIndexType CLayersInstanceModel::IndexType(const QModelIndex& index)
{
if (!index.isValid()) return eRootIndex;
else if (index.internalId() == 0) return eNodeTypeIndex;
else if (((index.internalId() & LAYERS_ITEM_TYPE_MASK) >> LAYERS_ITEM_TYPE_SHIFT) == 1) return eLayerIndex;
else return eInstanceIndex;
}
CLayersInstanceModel::ENodeType CLayersInstanceModel::IndexNodeType(const QModelIndex& index)
{
EIndexType type = IndexType(index);
switch (type)
{
case eRootIndex: return eInvalidType;
case eNodeTypeIndex: return (ENodeType) index.row();
case eLayerIndex: return (ENodeType) index.parent().row();
case eInstanceIndex: return (ENodeType) index.parent().parent().row();
default: return eInvalidType;
}
}

View File

@ -1,49 +0,0 @@
#ifndef CLAYERSINSTANCEMODEL_H
#define CLAYERSINSTANCEMODEL_H
#include "CWorldEditor.h"
#include <Core/Resource/Script/CScriptLayer.h>
#include <QAbstractItemModel>
// Only supports script layers atm - maybe light layers later...?
class CLayersInstanceModel : public QAbstractItemModel
{
Q_OBJECT
public:
enum EIndexType {
eRootIndex, eNodeTypeIndex, eLayerIndex, eInstanceIndex
};
enum ENodeType {
eScriptType = 0x0,
eLightType = 0x1,
eInvalidType = 0xFF
};
private:
CWorldEditor *mpEditor;
CScene *mpScene;
TResPtr<CGameArea> mpArea;
public:
explicit CLayersInstanceModel(QObject *pParent = 0);
~CLayersInstanceModel();
QVariant headerData(int section, Qt::Orientation orientation, int role) const;
QModelIndex index(int row, int column, const QModelIndex &parent) const;
QModelIndex parent(const QModelIndex &child) const;
int rowCount(const QModelIndex &parent) const;
int columnCount(const QModelIndex &parent) const;
QVariant data(const QModelIndex &index, int role) const;
void SetEditor(CWorldEditor *pEditor);
void NodeCreated(CSceneNode *pNode);
void NodeDeleted(CSceneNode *pNode);
CScriptLayer* IndexLayer(const QModelIndex& index) const;
CScriptObject* IndexObject(const QModelIndex& index) const;
// Static
static EIndexType IndexType(const QModelIndex& index);
static ENodeType IndexNodeType(const QModelIndex& index);
};
#endif // CLAYERSINSTANCEMODEL_H

View File

@ -55,7 +55,7 @@ QVariant CLinkModel::data(const QModelIndex &index, int role) const
CScriptObject *pTargetObj = mpObject->Area()->GetInstanceByID(link.ObjectID);
if (pTargetObj) {
QString ObjType = QString("[%1] ").arg(UICommon::ToQString(pTargetObj->Template()->TemplateName()));
QString ObjType = QString("[%1] ").arg(UICommon::ToQString(pTargetObj->Template()->Name()));
return ObjType + UICommon::ToQString(pTargetObj->InstanceName());
}
else {

View File

@ -4,6 +4,7 @@
#include "CWorldEditor.h"
#include <Core/Resource/Script/CScriptLayer.h>
#include <Core/Scene/CScene.h>
#include <Core/Scene/CSceneIterator.h>
WInstancesTab::WInstancesTab(QWidget *parent) :
QWidget(parent),
@ -12,34 +13,59 @@ WInstancesTab::WInstancesTab(QWidget *parent) :
ui->setupUi(this);
mpEditor = nullptr;
mpLayersModel = new CTypesInstanceModel(this);
mpLayersModel->SetModelType(CTypesInstanceModel::eLayers);
mpTypesModel = new CTypesInstanceModel(this);
mpTypesModel->SetModelType(CTypesInstanceModel::eTypes);
ui->LayersTreeView->setModel(mpLayersModel);
ui->LayersTreeView->header()->setSectionResizeMode(2, QHeaderView::Fixed);
mpLayersModel = new CInstancesModel(this);
mpLayersModel->SetModelType(CInstancesModel::eLayers);
mpTypesModel = new CInstancesModel(this);
mpTypesModel->SetModelType(CInstancesModel::eTypes);
mLayersProxyModel.setSourceModel(mpLayersModel);
mTypesProxyModel.setSourceModel(mpTypesModel);
int ColWidth = ui->LayersTreeView->width() * 0.29;
ui->LayersTreeView->setModel(&mLayersProxyModel);
ui->LayersTreeView->resizeColumnToContents(2);
ui->TypesTreeView->setModel(mpTypesModel);
ui->TypesTreeView->header()->setSectionResizeMode(2, QHeaderView::Fixed);
ui->LayersTreeView->header()->setSectionResizeMode(2, QHeaderView::Fixed);
ui->LayersTreeView->header()->resizeSection(0, ColWidth);
ui->LayersTreeView->header()->resizeSection(1, ColWidth);
ui->LayersTreeView->header()->setSortIndicator(0, Qt::AscendingOrder);
ui->TypesTreeView->setModel(&mTypesProxyModel);
ui->TypesTreeView->resizeColumnToContents(2);
ui->TypesTreeView->header()->setSectionResizeMode(2, QHeaderView::Fixed);
ui->TypesTreeView->header()->resizeSection(0, ColWidth);
ui->TypesTreeView->header()->resizeSection(1, ColWidth);
ui->TypesTreeView->header()->setSortIndicator(0, Qt::AscendingOrder);
// Create context menu
mpTreeContextMenu = new QMenu(this);
mpHideInstance = new QAction("Hide instance", this);
mpHideType = new QAction("", this);
mpHideAllExceptType = new QAction("", this);
mpTreeContextMenu->addAction(mpHideInstance);
mpTreeContextMenu->addAction(mpHideType);
mpTreeContextMenu->addAction(mpHideAllExceptType);
// Configure signals/slots
connect(ui->LayersTreeView, SIGNAL(clicked(QModelIndex)), this, SLOT(OnTreeClick(QModelIndex)));
connect(ui->LayersTreeView, SIGNAL(doubleClicked(QModelIndex)), this, SLOT(OnTreeDoubleClick(QModelIndex)));
connect(ui->LayersTreeView, SIGNAL(customContextMenuRequested(QPoint)), this, SLOT(OnTreeContextMenu(QPoint)));
connect(ui->TypesTreeView, SIGNAL(clicked(QModelIndex)), this, SLOT(OnTreeClick(QModelIndex)));
connect(ui->TypesTreeView, SIGNAL(doubleClicked(QModelIndex)), this, SLOT(OnTreeDoubleClick(QModelIndex)));
connect(ui->TypesTreeView, SIGNAL(customContextMenuRequested(QPoint)), this, SLOT(OnTreeContextMenu(QPoint)));
// Create context menu
mpHideInstance = new QAction("Hide instance", this);
mpHideType = new QAction("HideType", this);
mpHideAllTypes = new QAction("Hide all types", this);
mpHideAllExceptType = new QAction("HideAllButType", this);
mpSeparator = new QAction(this);
mpSeparator->setSeparator(true);
mpUnhideAllTypes = new QAction("UnhideAllTypes", this);
mpUnhideAll = new QAction("Unhide all", this);
QList<QAction*> ActionList;
ActionList << mpHideInstance << mpHideType << mpHideAllTypes << mpHideAllExceptType << mpSeparator
<< mpUnhideAllTypes << mpUnhideAll;
mpTreeContextMenu = new QMenu(this);
mpTreeContextMenu->addActions(ActionList);
connect(mpHideInstance, SIGNAL(triggered()), this, SLOT(OnHideInstanceAction()));
connect(mpHideType, SIGNAL(triggered()), this, SLOT(OnHideTypeAction()));
connect(mpHideAllTypes, SIGNAL(triggered()), this, SLOT(OnHideAllTypesAction()));
connect(mpHideAllExceptType, SIGNAL(triggered()), this, SLOT(OnHideAllExceptTypeAction()));
connect(mpUnhideAllTypes, SIGNAL(triggered()), this, SLOT(OnUnhideAllTypes()));
connect(mpUnhideAll, SIGNAL(triggered()), this, SLOT(OnUnhideAll()));
}
WInstancesTab::~WInstancesTab()
@ -71,51 +97,57 @@ void WInstancesTab::SetArea(CGameArea *pArea)
void WInstancesTab::OnTreeClick(QModelIndex Index)
{
// Single click is used to process show/hide events
if (Index.column() == 2)
QModelIndex SourceIndex = (ui->TabWidget->currentIndex() == 0 ? mLayersProxyModel.mapToSource(Index) : mTypesProxyModel.mapToSource(Index));
if (SourceIndex.column() == 2)
{
// Show/Hide Instance
if (mpTypesModel->IndexType(Index) == CTypesInstanceModel::eInstanceIndex)
if (mpTypesModel->IndexType(SourceIndex) == CInstancesModel::eInstanceIndex)
{
CScriptObject *pObj = mpTypesModel->IndexObject(Index);
CScriptNode *pNode = mpScene->NodeForObject(pObj);
pNode->SetVisible(!pNode->IsVisible());
CScriptObject *pObj = mpTypesModel->IndexObject(SourceIndex);
if (pObj)
{
CScriptNode *pNode = mpScene->NodeForObject(pObj);
if (pNode)
pNode->SetVisible(!pNode->IsVisible());
}
}
// Show/Hide Object Type
else if (mpTypesModel->IndexType(Index) == CTypesInstanceModel::eObjectTypeIndex)
else if (mpTypesModel->IndexType(SourceIndex) == CInstancesModel::eObjectTypeIndex)
{
if (sender() == ui->LayersTreeView)
{
CScriptLayer *pLayer = mpLayersModel->IndexLayer(Index);
CScriptLayer *pLayer = mpLayersModel->IndexLayer(SourceIndex);
pLayer->SetVisible(!pLayer->IsVisible());
}
else if (sender() == ui->TypesTreeView)
{
CScriptTemplate *pTmp = mpTypesModel->IndexTemplate(Index);
CScriptTemplate *pTmp = mpTypesModel->IndexTemplate(SourceIndex);
pTmp->SetVisible(!pTmp->IsVisible());
}
}
if (sender() == ui->LayersTreeView)
ui->LayersTreeView->update(Index);
else if (sender() == ui->TypesTreeView)
ui->TypesTreeView->update(Index);
static_cast<QTreeView*>(sender())->update(Index);
}
}
void WInstancesTab::OnTreeDoubleClick(QModelIndex Index)
{
CTypesInstanceModel::EIndexType IndexType = mpTypesModel->IndexType(Index);
QModelIndex SourceIndex = (ui->TabWidget->currentIndex() == 0 ? mLayersProxyModel.mapToSource(Index) : mTypesProxyModel.mapToSource(Index));;
CInstancesModel::EIndexType IndexType = mpTypesModel->IndexType(SourceIndex);
if ((mpEditor) && (IndexType == CTypesInstanceModel::eInstanceIndex))
if ((mpEditor) && (IndexType == CInstancesModel::eInstanceIndex))
{
CTypesInstanceModel::ENodeType NodeType = mpTypesModel->IndexNodeType(Index);
CInstancesModel::ENodeType NodeType = mpTypesModel->IndexNodeType(SourceIndex);
CSceneNode *pSelectedNode = nullptr;
if (NodeType == CTypesInstanceModel::eScriptType)
pSelectedNode = mpScene->NodeForObject( static_cast<CScriptObject*>(Index.internalPointer()) );
if (NodeType == CInstancesModel::eScriptType)
pSelectedNode = mpScene->NodeForObject( static_cast<CScriptObject*>(SourceIndex.internalPointer()) );
if (pSelectedNode)
{
@ -125,24 +157,263 @@ void WInstancesTab::OnTreeDoubleClick(QModelIndex Index)
}
}
void WInstancesTab::OnTreeContextMenu(QPoint Pos)
{
bool IsLayers = (sender() == ui->LayersTreeView);
QModelIndex Index = (IsLayers ? ui->LayersTreeView->indexAt(Pos) : ui->TypesTreeView->indexAt(Pos));
mMenuIndex = (IsLayers ? mLayersProxyModel.mapToSource(Index) : mTypesProxyModel.mapToSource(Index));
// Determine type
mMenuIndexType = (IsLayers ? mpLayersModel->IndexType(mMenuIndex) : mpTypesModel->IndexType(mMenuIndex));
CScriptObject *pObject = nullptr;
mpMenuObject = nullptr;
mpMenuLayer = nullptr;
mpMenuTemplate = nullptr;
if (mMenuIndexType == CInstancesModel::eObjectTypeIndex)
{
pObject = nullptr;
mpMenuObject = nullptr;
if (IsLayers)
mpMenuLayer = mpLayersModel->IndexLayer(mMenuIndex);
else
mpMenuTemplate = mpTypesModel->IndexTemplate(mMenuIndex);
}
else if (mMenuIndexType == CInstancesModel::eInstanceIndex)
{
pObject = ( IsLayers ? mpLayersModel->IndexObject(mMenuIndex) : mpTypesModel->IndexObject(mMenuIndex) );
mpMenuObject = mpScene->NodeForObject(pObject);
if (IsLayers)
mpMenuLayer = pObject->Layer();
else
mpMenuTemplate = pObject->Template();
}
// Set visibility and text
if (pObject)
{
QString Hide = mpMenuObject->MarkedVisible() ? "Hide" : "Unhide";
mpHideInstance->setText(QString("%1 instance").arg(Hide));
mpHideInstance->setVisible(true);
}
else
{
mpHideInstance->setVisible(false);
}
if (mpMenuLayer)
{
QString Hide = mpMenuLayer->IsVisible() ? "Hide" : "Unhide";
mpHideType->setText(QString("%1 layer %2").arg(Hide).arg(TO_QSTRING(mpMenuLayer->Name())));
mpHideType->setVisible(true);
mpHideAllExceptType->setText(QString("Hide all layers but %1").arg(TO_QSTRING(mpMenuLayer->Name())));
mpHideAllExceptType->setVisible(true);
}
else if (mpMenuTemplate)
{
QString Hide = mpMenuTemplate->IsVisible() ? "Hide" : "Unhide";
mpHideType->setText(QString("%1 all %2 objects").arg(Hide).arg(TO_QSTRING(mpMenuTemplate->Name())));
mpHideType->setVisible(true);
mpHideAllExceptType->setText(QString("Hide all types but %1").arg(TO_QSTRING(mpMenuTemplate->Name())));
mpHideAllExceptType->setVisible(true);
}
else
{
mpHideType->setVisible(false);
mpHideAllExceptType->setVisible(false);
}
mpHideAllTypes->setText(QString("Hide all %1").arg(IsLayers ? "layers" : "types"));
mpUnhideAllTypes->setText(QString("Unhide all %1").arg(IsLayers ? "layers" : "types"));
QPoint GlobalPos = static_cast<QTreeView*>(sender())->viewport()->mapToGlobal(Pos);
mpTreeContextMenu->exec(GlobalPos);
}
void WInstancesTab::OnHideInstanceAction()
{
bool IsLayers = (ui->TabWidget->currentIndex() == 0);
mpMenuObject->SetVisible(mpMenuObject->MarkedVisible() ? false : true);
if (IsLayers)
mpLayersModel->dataChanged(mMenuIndex, mMenuIndex);
else
mpTypesModel->dataChanged(mMenuIndex, mMenuIndex);
}
void WInstancesTab::OnHideTypeAction()
{
bool IsLayers = (ui->TabWidget->currentIndex() == 0);
QModelIndex TypeIndex = (mMenuIndexType == CInstancesModel::eInstanceIndex ? mMenuIndex.parent() : mMenuIndex);
if (IsLayers)
{
mpMenuLayer->SetVisible(mpMenuLayer->IsVisible() ? false : true);
mpLayersModel->dataChanged(TypeIndex, TypeIndex);
}
else
{
mpMenuTemplate->SetVisible(mpMenuTemplate->IsVisible() ? false : true);
mpTypesModel->dataChanged(TypeIndex, TypeIndex);
}
}
void WInstancesTab::OnHideAllTypesAction()
{
bool IsLayers = (ui->TabWidget->currentIndex() == 0);
CInstancesModel *pModel = (IsLayers ? mpLayersModel : mpTypesModel);
QModelIndex BaseIndex = pModel->index(0, 0);
for (int iIdx = 0; iIdx < pModel->rowCount(BaseIndex); iIdx++)
{
QModelIndex Index = pModel->index(iIdx, 0, BaseIndex);
if (IsLayers)
{
CScriptLayer *pLayer = pModel->IndexLayer(Index);
pLayer->SetVisible(false);
}
else
{
CScriptTemplate *pTemplate = pModel->IndexTemplate(Index);
pTemplate->SetVisible(false);
}
}
pModel->dataChanged(pModel->index(0, 2, BaseIndex), pModel->index(pModel->rowCount(BaseIndex) - 1, 2, BaseIndex));
}
void WInstancesTab::OnHideAllExceptTypeAction()
{
bool IsLayers = (ui->TabWidget->currentIndex() == 0);
QModelIndex TypeIndex = (mMenuIndexType == CInstancesModel::eInstanceIndex ? mMenuIndex.parent() : mMenuIndex);
QModelIndex TypeParent = TypeIndex.parent();
if (IsLayers)
{
CGameArea *pArea = mpEditor->ActiveArea();
for (u32 iLyr = 0; iLyr < pArea->GetScriptLayerCount(); iLyr++)
{
CScriptLayer *pLayer = pArea->GetScriptLayer(iLyr);
pLayer->SetVisible( pLayer == mpMenuLayer ? true : false );
}
mpLayersModel->dataChanged( mpLayersModel->index(0, 2, TypeParent), mpLayersModel->index(mpLayersModel->rowCount(TypeParent) - 1, 2, TypeParent) );
}
else
{
EGame Game = mpEditor->ActiveArea()->Version();
CMasterTemplate *pMaster = CMasterTemplate::GetMasterForGame(Game);
for (u32 iTemp = 0; iTemp < pMaster->NumScriptTemplates(); iTemp++)
{
CScriptTemplate *pTemplate = pMaster->TemplateByIndex(iTemp);
pTemplate->SetVisible( pTemplate == mpMenuTemplate ? true : false );
}
mpTypesModel->dataChanged( mpTypesModel->index(0, 2, TypeParent), mpTypesModel->index(mpTypesModel->rowCount(TypeParent) - 1, 2, TypeParent) );
}
}
void WInstancesTab::OnUnhideAllTypes()
{
bool IsLayers = (ui->TabWidget->currentIndex() == 0);
QModelIndex TypeIndex = (mMenuIndexType == CInstancesModel::eInstanceIndex ? mMenuIndex.parent() : mMenuIndex);
QModelIndex TypeParent = TypeIndex.parent();
if (IsLayers)
{
CGameArea *pArea = mpEditor->ActiveArea();
for (u32 iLyr = 0; iLyr < pArea->GetScriptLayerCount(); iLyr++)
pArea->GetScriptLayer(iLyr)->SetVisible(true);
mpLayersModel->dataChanged( mpLayersModel->index(0, 2, TypeParent), mpLayersModel->index(mpLayersModel->rowCount(TypeParent) - 1, 2, TypeParent) );
}
else
{
EGame Game = mpEditor->ActiveArea()->Version();
CMasterTemplate *pMaster = CMasterTemplate::GetMasterForGame(Game);
for (u32 iTemp = 0; iTemp < pMaster->NumScriptTemplates(); iTemp++)
pMaster->TemplateByIndex(iTemp)->SetVisible(true);
mpTypesModel->dataChanged( mpTypesModel->index(0, 2, TypeParent), mpTypesModel->index(mpTypesModel->rowCount(TypeParent) - 1, 2, TypeParent) );
}
}
void WInstancesTab::OnUnhideAll()
{
// Unhide instances
for (CSceneIterator It(mpScene, eScriptNode, true); !It.DoneIterating(); ++It)
It->SetVisible(true);
// Unhide layers
QModelIndex LayersRoot = mpLayersModel->index(0, 0, QModelIndex()).child(0, 0);
if (LayersRoot.isValid())
{
CGameArea *pArea = mpEditor->ActiveArea();
for (u32 iLyr = 0; iLyr < pArea->GetScriptLayerCount(); iLyr++)
pArea->GetScriptLayer(iLyr)->SetVisible(true);
mpLayersModel->dataChanged( mpLayersModel->index(0, 2, LayersRoot), mpLayersModel->index(mpLayersModel->rowCount(LayersRoot) - 1, 2, LayersRoot) );
}
// Unhide types
QModelIndex TypesRoot = mpTypesModel->index(0, 0, QModelIndex()).child(0, 0);
if (TypesRoot.isValid())
{
EGame Game = mpEditor->ActiveArea()->Version();
CMasterTemplate *pMaster = CMasterTemplate::GetMasterForGame(Game);
for (u32 iTemp = 0; iTemp < pMaster->NumScriptTemplates(); iTemp++)
pMaster->TemplateByIndex(iTemp)->SetVisible(true);
mpTypesModel->dataChanged( mpTypesModel->index(0, 2, TypesRoot), mpTypesModel->index(mpTypesModel->rowCount(TypesRoot) - 1, 2, TypesRoot) );
}
// Emit data changed on all instances
for (u32 iModel = 0; iModel < 2; iModel++)
{
CInstancesModel *pModel = (iModel == 0 ? mpLayersModel : mpTypesModel);
QModelIndex Base = pModel->index(0, 0);
u32 NumRows = pModel->rowCount(Base);
for (u32 iRow = 0; iRow < NumRows; iRow++)
{
QModelIndex RowIndex = pModel->index(iRow, 2, Base);
pModel->dataChanged( pModel->index(0, 2, RowIndex), pModel->index(pModel->rowCount(RowIndex) - 1, 2, RowIndex) );
}
}
OnUnhideAllTypes();
}
// ************ PRIVATE ************
void WInstancesTab::ExpandTopLevelItems()
{
for (u32 iModel = 0; iModel < 2; iModel++)
{
QAbstractItemModel *pModel = (iModel == 0 ? mpLayersModel : mpTypesModel);
QAbstractItemModel *pModel = (iModel == 0 ? &mLayersProxyModel : &mTypesProxyModel);
QTreeView *pView = (iModel == 0 ? ui->LayersTreeView : ui->TypesTreeView);
QModelIndex Index = pModel->index(0,0);

View File

@ -1,7 +1,8 @@
#ifndef WINSTANCESTAB_H
#define WINSTANCESTAB_H
#include "CTypesInstanceModel.h"
#include "CInstancesProxyModel.h"
#include "CInstancesModel.h"
#include <QWidget>
#include <QAction>
@ -20,14 +21,26 @@ class WInstancesTab : public QWidget
CWorldEditor *mpEditor;
CScene *mpScene;
CTypesInstanceModel *mpLayersModel;
CTypesInstanceModel *mpTypesModel;
CInstancesModel *mpLayersModel;
CInstancesModel *mpTypesModel;
CInstancesProxyModel mLayersProxyModel;
CInstancesProxyModel mTypesProxyModel;
// Tree right-click context menu
QMenu *mpTreeContextMenu;
QAction *mpHideInstance;
QAction *mpHideType;
QAction *mpHideAllTypes;
QAction *mpHideAllExceptType;
QAction *mpSeparator;
QAction *mpUnhideAllTypes;
QAction *mpUnhideAll;
QModelIndex mMenuIndex;
CScriptNode *mpMenuObject;
CScriptLayer *mpMenuLayer;
CScriptTemplate *mpMenuTemplate;
CInstancesModel::EIndexType mMenuIndexType;
public:
explicit WInstancesTab(QWidget *parent = 0);
@ -39,14 +52,19 @@ public:
private slots:
void OnTreeClick(QModelIndex Index);
void OnTreeDoubleClick(QModelIndex Index);
void OnTreeContextMenu(QPoint Pos);
void OnHideInstanceAction();
void OnHideTypeAction();
void OnHideAllTypesAction();
void OnHideAllExceptTypeAction();
void OnUnhideAllTypes();
void OnUnhideAll();
void ExpandTopLevelItems();
private:
Ui::WInstancesTab *ui;
void ExpandTopLevelItems();
};
#endif // WINSTANCESTAB_H

View File

@ -29,7 +29,7 @@
<item>
<widget class="QTabWidget" name="TabWidget">
<property name="currentIndex">
<number>1</number>
<number>0</number>
</property>
<widget class="QWidget" name="ShowLayersTab">
<attribute name="title">
@ -50,6 +50,9 @@
</property>
<item>
<widget class="QTreeView" name="LayersTreeView">
<property name="contextMenuPolicy">
<enum>Qt::CustomContextMenu</enum>
</property>
<property name="frameShape">
<enum>QFrame::NoFrame</enum>
</property>
@ -59,6 +62,9 @@
<property name="indentation">
<number>13</number>
</property>
<property name="sortingEnabled">
<bool>true</bool>
</property>
</widget>
</item>
</layout>
@ -82,6 +88,9 @@
</property>
<item>
<widget class="QTreeView" name="TypesTreeView">
<property name="contextMenuPolicy">
<enum>Qt::CustomContextMenu</enum>
</property>
<property name="styleSheet">
<string notr="true"/>
</property>
@ -97,6 +106,9 @@
<property name="indentation">
<number>13</number>
</property>
<property name="sortingEnabled">
<bool>true</bool>
</property>
</widget>
</item>
</layout>

View File

@ -84,7 +84,6 @@
<assets>
<billboard source="file">script/common/Effect.txtr</billboard>
</assets>
<preview_scale>0.5</preview_scale>
<rotation_type>enabled</rotation_type>
<scale_type>enabled</scale_type>
</editor>