PrimeWorldEditor/src/Editor/WorldEditor/WInstancesTab.cpp

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);
}
}
}