#include "WModifyTab.h" #include "ui_WModifyTab.h" #include "CLinkDialog.h" #include "CSelectInstanceDialog.h" #include "CWorldEditor.h" #include "Editor/Undo/UndoCommands.h" #include #include #include WModifyTab::WModifyTab(CWorldEditor *pEditor, QWidget *pParent) : QWidget(pParent) , ui(new Ui::WModifyTab) , mIsPicking(false) { ui->setupUi(this); mpWorldEditor = pEditor; ui->PropertyView->SetEditor(mpWorldEditor); int PropViewWidth = ui->PropertyView->width(); ui->PropertyView->header()->resizeSection(0, PropViewWidth * 0.3); ui->PropertyView->header()->resizeSection(1, PropViewWidth * 0.3); ui->PropertyView->header()->setSectionResizeMode(1, QHeaderView::Fixed); mpInLinkModel = new CLinkModel(this); mpInLinkModel->SetConnectionType(ELinkType::Incoming); mpOutLinkModel = new CLinkModel(this); mpOutLinkModel->SetConnectionType(ELinkType::Outgoing); mpAddFromViewportAction = new QAction("Choose from viewport", this); mpAddFromListAction = new QAction("Choose from list", this); mpAddLinkMenu = new QMenu(this); mpAddLinkMenu->addAction(mpAddFromViewportAction); mpAddLinkMenu->addAction(mpAddFromListAction); ui->AddOutgoingConnectionToolButton->setMenu(mpAddLinkMenu); ui->AddIncomingConnectionToolButton->setMenu(mpAddLinkMenu); ui->InLinksTableView->setModel(mpInLinkModel); ui->OutLinksTableView->setModel(mpOutLinkModel); connect(ui->InLinksTableView, SIGNAL(doubleClicked(QModelIndex)), this, SLOT(OnLinkTableDoubleClick(QModelIndex))); connect(ui->OutLinksTableView, SIGNAL(doubleClicked(QModelIndex)), this, SLOT(OnLinkTableDoubleClick(QModelIndex))); connect(ui->InLinksTableView->selectionModel(), SIGNAL(selectionChanged(QItemSelection,QItemSelection)), this, SLOT(OnLinksSelectionModified())); connect(ui->OutLinksTableView->selectionModel(), SIGNAL(selectionChanged(QItemSelection,QItemSelection)), this, SLOT(OnLinksSelectionModified())); connect(ui->AddOutgoingConnectionToolButton, SIGNAL(triggered(QAction*)), this, SLOT(OnAddLinkActionClicked(QAction*))); connect(ui->AddIncomingConnectionToolButton, SIGNAL(triggered(QAction*)), this, SLOT(OnAddLinkActionClicked(QAction*))); connect(ui->DeleteOutgoingConnectionButton, SIGNAL(clicked()), this, SLOT(OnDeleteLinksClicked())); connect(ui->DeleteIncomingConnectionButton, SIGNAL(clicked()), this, SLOT(OnDeleteLinksClicked())); connect(ui->EditOutgoingConnectionButton, SIGNAL(clicked()), this, SLOT(OnEditLinkClicked())); connect(ui->EditIncomingConnectionButton, SIGNAL(clicked()), this, SLOT(OnEditLinkClicked())); connect(mpWorldEditor, SIGNAL(MapChanged(CWorld*,CGameArea*)), this, SLOT(OnMapChanged())); connect(mpWorldEditor, SIGNAL(SelectionTransformed()), this, SLOT(OnWorldSelectionTransformed())); connect(mpWorldEditor, SIGNAL(InstanceLinksModified(const QList&)), this, SLOT(OnInstanceLinksModified(const QList&))); connect(mpWorldEditor->Selection(), SIGNAL(Modified()), this, SLOT(GenerateUI())); ClearUI(); } WModifyTab::~WModifyTab() { delete ui; } void WModifyTab::ClearUI() { ui->ObjectsTabWidget->hide(); ui->PropertyView->SetInstance(nullptr); mpSelectedNode = nullptr; } // ************ PUBLIC SLOTS ************ void WModifyTab::GenerateUI() { if (mIsPicking) mpWorldEditor->ExitPickMode(); if (mpWorldEditor->Selection()->Size() == 1) { if (mpSelectedNode != mpWorldEditor->Selection()->Front()) { mpSelectedNode = mpWorldEditor->Selection()->Front(); if (mpSelectedNode->NodeType() == ENodeType::Script) { CScriptNode *pScriptNode = static_cast(mpSelectedNode); CScriptObject *pObj = pScriptNode->Instance(); // Set up UI ui->ObjectsTabWidget->show(); ui->PropertyView->SetInstance(pObj); mpInLinkModel->SetObject(pObj); mpOutLinkModel->SetObject(pObj); } // disabled this for now! implemented it as a quick test, it's cool it works, // but it's buggy & not ready for deployment #if 0 else { CStructRef Properties = mpSelectedNode->GetProperties(); ui->PropertyView->SetProperties(Properties); if (Properties.IsValid()) ui->ObjectsTabWidget->show(); } #endif ui->InLinksTableView->clearSelection(); ui->OutLinksTableView->clearSelection(); ui->InLinksTableView->horizontalHeader()->setSectionResizeMode(0, QHeaderView::Stretch); ui->OutLinksTableView->horizontalHeader()->setSectionResizeMode(0, QHeaderView::Stretch); } } else ClearUI(); } void WModifyTab::OnInstanceLinksModified(const QList& rkInstances) { if (mpSelectedNode && mpSelectedNode->NodeType() == ENodeType::Script) { CScriptObject *pInstance = static_cast(mpSelectedNode)->Instance(); if (pInstance && rkInstances.contains(pInstance)) { mpInLinkModel->layoutChanged(); mpOutLinkModel->layoutChanged(); ui->InLinksTableView->clearSelection(); ui->OutLinksTableView->clearSelection(); } } } void WModifyTab::OnWorldSelectionTransformed() { ui->PropertyView->UpdateEditorProperties(QModelIndex()); } void WModifyTab::OnMapChanged() { ClearUI(); } void WModifyTab::OnLinksSelectionModified() { if (sender() == ui->InLinksTableView->selectionModel()) { uint32 NumSelectedRows = ui->InLinksTableView->selectionModel()->selectedRows().size(); ui->EditIncomingConnectionButton->setEnabled(NumSelectedRows == 1); ui->DeleteIncomingConnectionButton->setEnabled(NumSelectedRows > 0); } else { uint32 NumSelectedRows = ui->OutLinksTableView->selectionModel()->selectedRows().size(); ui->EditOutgoingConnectionButton->setEnabled(NumSelectedRows == 1); ui->DeleteOutgoingConnectionButton->setEnabled(NumSelectedRows > 0); } } void WModifyTab::OnAddLinkActionClicked(QAction *pAction) { if (mpSelectedNode && mpSelectedNode->NodeType() == ENodeType::Script) { mAddLinkType = (sender() == ui->AddOutgoingConnectionToolButton ? ELinkType::Outgoing : ELinkType::Incoming); if (pAction == mpAddFromViewportAction) { mpWorldEditor->EnterPickMode(ENodeType::Script, true, false, false); connect(mpWorldEditor, SIGNAL(PickModeClick(SRayIntersection,QMouseEvent*)), this, SLOT(OnPickModeClick(SRayIntersection))); connect(mpWorldEditor, SIGNAL(PickModeExited()), this, SLOT(OnPickModeExit())); mIsPicking = true; } else if (pAction == mpAddFromListAction) { if (mIsPicking) mpWorldEditor->ExitPickMode(); CSelectInstanceDialog Dialog(mpWorldEditor, this); Dialog.exec(); CScriptObject *pTarget = Dialog.SelectedInstance(); if (pTarget) { CLinkDialog *pLinkDialog = mpWorldEditor->LinkDialog(); CScriptObject *pSelected = static_cast(mpSelectedNode)->Instance(); CScriptObject *pSender = (mAddLinkType == ELinkType::Outgoing ? pSelected : pTarget); CScriptObject *pReceiver = (mAddLinkType == ELinkType::Outgoing ? pTarget : pSelected); pLinkDialog->NewLink(pSender, pReceiver); pLinkDialog->show(); } } } } void WModifyTab::OnPickModeClick(const SRayIntersection& rkIntersect) { mpWorldEditor->ExitPickMode(); CScriptObject *pTarget = static_cast(rkIntersect.pNode)->Instance(); if (pTarget) { CLinkDialog *pDialog = mpWorldEditor->LinkDialog(); CScriptObject *pSelected = static_cast(mpSelectedNode)->Instance(); CScriptObject *pSender = (mAddLinkType == ELinkType::Outgoing ? pSelected : pTarget); CScriptObject *pReceiver = (mAddLinkType == ELinkType::Outgoing ? pTarget : pSelected); pDialog->NewLink(pSender, pReceiver); pDialog->show(); } } void WModifyTab::OnPickModeExit() { disconnect(mpWorldEditor, SIGNAL(PickModeClick(SRayIntersection,QMouseEvent*)), this, 0); disconnect(mpWorldEditor, SIGNAL(PickModeExited()), this, 0); mIsPicking = false; } void WModifyTab::OnDeleteLinksClicked() { if (mpSelectedNode && mpSelectedNode->NodeType() == ENodeType::Script) { ELinkType Type = (sender() == ui->DeleteOutgoingConnectionButton ? ELinkType::Outgoing : ELinkType::Incoming); QModelIndexList SelectedIndices = (Type == ELinkType::Outgoing ? ui->OutLinksTableView->selectionModel()->selectedRows() : ui->InLinksTableView->selectionModel()->selectedRows()); if (!SelectedIndices.isEmpty()) { QVector Indices; for (int iIdx = 0; iIdx < SelectedIndices.size(); iIdx++) Indices << SelectedIndices[iIdx].row(); CScriptObject *pInst = static_cast(mpSelectedNode)->Instance(); CDeleteLinksCommand *pCmd = new CDeleteLinksCommand(mpWorldEditor, pInst, Type, Indices); mpWorldEditor->UndoStack().push(pCmd); } } } void WModifyTab::OnEditLinkClicked() { if (mpSelectedNode && mpSelectedNode->NodeType() == ENodeType::Script) { ELinkType Type = (sender() == ui->EditOutgoingConnectionButton ? ELinkType::Outgoing : ELinkType::Incoming); QModelIndexList SelectedIndices = (Type == ELinkType::Outgoing ? ui->OutLinksTableView->selectionModel()->selectedRows() : ui->InLinksTableView->selectionModel()->selectedRows()); if (SelectedIndices.size() == 1) { CScriptObject *pInst = static_cast(mpSelectedNode)->Instance(); CLinkDialog *pDialog = mpWorldEditor->LinkDialog(); pDialog->EditLink(pInst->Link(Type, SelectedIndices.front().row())); pDialog->show(); } } } // ************ PRIVATE SLOTS ************ void WModifyTab::OnLinkTableDoubleClick(QModelIndex Index) { if (Index.column() == 0) { // The link table will only be visible if the selected node is a script node CScriptNode *pNode = static_cast(mpSelectedNode); uint32 InstanceID; if (sender() == ui->InLinksTableView) InstanceID = pNode->Instance()->Link(ELinkType::Incoming, Index.row())->SenderID(); else if (sender() == ui->OutLinksTableView) InstanceID = pNode->Instance()->Link(ELinkType::Outgoing, Index.row())->ReceiverID(); CScriptNode *pLinkedNode = pNode->Scene()->NodeForInstanceID(InstanceID); if (pLinkedNode) mpWorldEditor->ClearAndSelectNode(pLinkedNode); ui->InLinksTableView->clearSelection(); ui->OutLinksTableView->clearSelection(); } }