409 lines
15 KiB
C++
409 lines
15 KiB
C++
#include "WInstancesTab.h"
|
|
#include "ui_WInstancesTab.h"
|
|
|
|
#include "CWorldEditor.h"
|
|
#include <Core/Resource/Script/CScriptLayer.h>
|
|
#include <Core/Resource/Script/NGameList.h>
|
|
#include <Core/Scene/CScene.h>
|
|
#include <Core/Scene/CSceneIterator.h>
|
|
|
|
WInstancesTab::WInstancesTab(CWorldEditor *pEditor, QWidget *parent) :
|
|
QWidget(parent),
|
|
ui(new Ui::WInstancesTab)
|
|
{
|
|
ui->setupUi(this);
|
|
|
|
mpEditor = pEditor;
|
|
mpScene = mpEditor->Scene();
|
|
|
|
mpLayersModel = new CInstancesModel(pEditor, this);
|
|
mpLayersModel->SetModelType(CInstancesModel::EInstanceModelType::Layers);
|
|
mpTypesModel = new CInstancesModel(pEditor, this);
|
|
mpTypesModel->SetModelType(CInstancesModel::EInstanceModelType::Types);
|
|
mLayersProxyModel.setSourceModel(mpLayersModel);
|
|
mTypesProxyModel.setSourceModel(mpTypesModel);
|
|
|
|
connect(mpLayersModel, SIGNAL(modelReset()), this, SLOT(ExpandTopLevelItems()));
|
|
connect(mpTypesModel, SIGNAL(modelReset()), this, SLOT(ExpandTopLevelItems()));
|
|
|
|
int ColWidth = ui->LayersTreeView->width() * 0.29;
|
|
|
|
ui->LayersTreeView->setModel(&mLayersProxyModel);
|
|
ui->LayersTreeView->resizeColumnToContents(2);
|
|
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);
|
|
|
|
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()
|
|
{
|
|
delete ui;
|
|
}
|
|
|
|
// ************ PRIVATE SLOTS ************
|
|
void WInstancesTab::OnTreeClick(QModelIndex Index)
|
|
{
|
|
// Single click is used to process show/hide events
|
|
QModelIndex SourceIndex = (ui->TabWidget->currentIndex() == 0 ? mLayersProxyModel.mapToSource(Index) : mTypesProxyModel.mapToSource(Index));
|
|
|
|
if (SourceIndex.column() == 2)
|
|
{
|
|
// Show/Hide Instance
|
|
if (mpTypesModel->IndexType(SourceIndex) == CInstancesModel::EIndexType::Instance)
|
|
{
|
|
CScriptObject *pObj = mpTypesModel->IndexObject(SourceIndex);
|
|
|
|
if (pObj)
|
|
{
|
|
CScriptNode *pNode = mpScene->NodeForInstance(pObj);
|
|
|
|
if (pNode)
|
|
pNode->SetVisible(!pNode->IsVisible());
|
|
}
|
|
|
|
}
|
|
|
|
// Show/Hide Object Type
|
|
else if (mpTypesModel->IndexType(SourceIndex) == CInstancesModel::EIndexType::ObjectType)
|
|
{
|
|
if (sender() == ui->LayersTreeView)
|
|
{
|
|
CScriptLayer *pLayer = mpLayersModel->IndexLayer(SourceIndex);
|
|
pLayer->SetVisible(!pLayer->IsVisible());
|
|
}
|
|
|
|
else if (sender() == ui->TypesTreeView)
|
|
{
|
|
CScriptTemplate *pTmp = mpTypesModel->IndexTemplate(SourceIndex);
|
|
pTmp->SetVisible(!pTmp->IsVisible());
|
|
}
|
|
}
|
|
|
|
static_cast<QTreeView*>(sender())->update(Index);
|
|
}
|
|
}
|
|
|
|
void WInstancesTab::OnTreeDoubleClick(QModelIndex Index)
|
|
{
|
|
QModelIndex SourceIndex = (ui->TabWidget->currentIndex() == 0 ? mLayersProxyModel.mapToSource(Index) : mTypesProxyModel.mapToSource(Index));;
|
|
CInstancesModel::EIndexType IndexType = mpTypesModel->IndexType(SourceIndex);
|
|
|
|
if ((mpEditor) && (IndexType == CInstancesModel::EIndexType::Instance))
|
|
{
|
|
ENodeType NodeType = mpTypesModel->IndexNodeType(SourceIndex);
|
|
|
|
if (NodeType == ENodeType::Script)
|
|
{
|
|
CSceneNode *pSelectedNode = mpScene->NodeForInstance( static_cast<CScriptObject*>(SourceIndex.internalPointer()) );
|
|
mpEditor->ClearAndSelectNode(pSelectedNode);
|
|
}
|
|
}
|
|
}
|
|
|
|
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::EIndexType::ObjectType)
|
|
{
|
|
pObject = nullptr;
|
|
mpMenuObject = nullptr;
|
|
|
|
if (IsLayers)
|
|
mpMenuLayer = mpLayersModel->IndexLayer(mMenuIndex);
|
|
else
|
|
mpMenuTemplate = mpTypesModel->IndexTemplate(mMenuIndex);
|
|
}
|
|
|
|
else if (mMenuIndexType == CInstancesModel::EIndexType::Instance)
|
|
{
|
|
pObject = ( IsLayers ? mpLayersModel->IndexObject(mMenuIndex) : mpTypesModel->IndexObject(mMenuIndex) );
|
|
mpMenuObject = mpScene->NodeForInstance(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::EIndexType::Instance ? 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::EIndexType::Instance ? mMenuIndex.parent() : mMenuIndex);
|
|
QModelIndex TypeParent = TypeIndex.parent();
|
|
|
|
if (IsLayers)
|
|
{
|
|
CGameArea *pArea = mpEditor->ActiveArea();
|
|
|
|
for (uint32 iLyr = 0; iLyr < pArea->NumScriptLayers(); iLyr++)
|
|
{
|
|
CScriptLayer *pLayer = pArea->ScriptLayer(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->CurrentGame();
|
|
CGameTemplate *pGame = NGameList::GetGameTemplate(Game);
|
|
|
|
for (uint32 iTemp = 0; iTemp < pGame->NumScriptTemplates(); iTemp++)
|
|
{
|
|
CScriptTemplate *pTemplate = pGame->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::EIndexType::Instance ? mMenuIndex.parent() : mMenuIndex);
|
|
QModelIndex TypeParent = TypeIndex.parent();
|
|
|
|
if (IsLayers)
|
|
{
|
|
CGameArea *pArea = mpEditor->ActiveArea();
|
|
|
|
for (uint32 iLyr = 0; iLyr < pArea->NumScriptLayers(); iLyr++)
|
|
pArea->ScriptLayer(iLyr)->SetVisible(true);
|
|
|
|
mpLayersModel->dataChanged( mpLayersModel->index(0, 2, TypeParent), mpLayersModel->index(mpLayersModel->rowCount(TypeParent) - 1, 2, TypeParent) );
|
|
}
|
|
|
|
else
|
|
{
|
|
EGame Game = mpEditor->CurrentGame();
|
|
CGameTemplate *pGame = NGameList::GetGameTemplate(Game);
|
|
|
|
for (uint32 iTemp = 0; iTemp < pGame->NumScriptTemplates(); iTemp++)
|
|
pGame->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, ENodeType::Script, true); !It.DoneIterating(); ++It)
|
|
It->SetVisible(true);
|
|
|
|
// Unhide layers
|
|
QModelIndex LayersRoot = mpLayersModel->index(0, 0, mpLayersModel->index(0, 0, QModelIndex()));
|
|
|
|
if (LayersRoot.isValid())
|
|
{
|
|
CGameArea *pArea = mpEditor->ActiveArea();
|
|
|
|
for (uint32 iLyr = 0; iLyr < pArea->NumScriptLayers(); iLyr++)
|
|
pArea->ScriptLayer(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, mpTypesModel->index(0, 0, QModelIndex()));
|
|
|
|
if (TypesRoot.isValid())
|
|
{
|
|
EGame Game = mpEditor->CurrentGame();
|
|
CGameTemplate *pGame = NGameList::GetGameTemplate(Game);
|
|
|
|
for (uint32 iTemp = 0; iTemp < pGame->NumScriptTemplates(); iTemp++)
|
|
pGame->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 (uint32 iModel = 0; iModel < 2; iModel++)
|
|
{
|
|
CInstancesModel *pModel = (iModel == 0 ? mpLayersModel : mpTypesModel);
|
|
|
|
QModelIndex Base = pModel->index(0, 0);
|
|
uint32 NumRows = pModel->rowCount(Base);
|
|
|
|
for (uint32 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();
|
|
}
|
|
|
|
void WInstancesTab::ExpandTopLevelItems()
|
|
{
|
|
for (uint32 iModel = 0; iModel < 2; iModel++)
|
|
{
|
|
QAbstractItemModel *pModel = (iModel == 0 ? &mLayersProxyModel : &mTypesProxyModel);
|
|
QTreeView *pView = (iModel == 0 ? ui->LayersTreeView : ui->TypesTreeView);
|
|
QModelIndex Index = pModel->index(0,0);
|
|
|
|
while (Index.isValid())
|
|
{
|
|
pView->expand(Index);
|
|
Index = Index.sibling(Index.row() + 1, 0);
|
|
}
|
|
}
|
|
}
|