From 38d04bcd254542a5d752a5c8a2070ebf17c438ae Mon Sep 17 00:00:00 2001 From: parax0 Date: Sat, 9 Jan 2016 09:39:43 -0700 Subject: [PATCH] Added CSceneIterator and implemented support for Select All/Invert Selection --- src/Core/Core.pro | 6 +- src/Core/Scene/CScene.cpp | 41 ++++++++--- src/Core/Scene/CScene.h | 8 ++- src/Core/Scene/CSceneIterator.cpp | 72 +++++++++++++++++++ src/Core/Scene/CSceneIterator.h | 66 ++++++++++++++++++ src/Core/Scene/ENodeType.h | 19 ++++-- src/Editor/CSceneViewport.cpp | 5 ++ src/Editor/CSceneViewport.h | 1 + src/Editor/Editor.pro | 8 ++- src/Editor/INodeEditor.cpp | 76 ++++++++++++++------- src/Editor/INodeEditor.h | 4 ++ src/Editor/Undo/CInvertSelectionCommand.cpp | 56 +++++++++++++++ src/Editor/Undo/CInvertSelectionCommand.h | 23 +++++++ src/Editor/Undo/CSelectAllCommand.cpp | 56 +++++++++++++++ src/Editor/Undo/CSelectAllCommand.h | 23 +++++++ src/Editor/Undo/UndoCommands.h | 2 + src/Editor/WorldEditor/CWorldEditor.cpp | 18 ++++- src/Editor/WorldEditor/CWorldEditor.h | 2 + src/Editor/WorldEditor/CWorldEditor.ui | 18 +++++ src/Editor/main.cpp | 3 - 20 files changed, 459 insertions(+), 48 deletions(-) create mode 100644 src/Core/Scene/CSceneIterator.cpp create mode 100644 src/Core/Scene/CSceneIterator.h create mode 100644 src/Editor/Undo/CInvertSelectionCommand.cpp create mode 100644 src/Editor/Undo/CInvertSelectionCommand.h create mode 100644 src/Editor/Undo/CSelectAllCommand.cpp create mode 100644 src/Editor/Undo/CSelectAllCommand.h diff --git a/src/Core/Core.pro b/src/Core/Core.pro index 732380b2..b785a66b 100644 --- a/src/Core/Core.pro +++ b/src/Core/Core.pro @@ -180,7 +180,8 @@ HEADERS += \ Resource/Model/EVertexAttribute.h \ Render/FRenderOptions.h \ Scene/FShowFlags.h \ - Scene/CScene.h + Scene/CScene.h \ + Scene/CSceneIterator.h # Source Files SOURCES += \ @@ -265,4 +266,5 @@ SOURCES += \ Resource/Script/IPropertyTemplate.cpp \ Resource/Script/IProperty.cpp \ Scene/FShowFlags.cpp \ - Scene/CScene.cpp + Scene/CScene.cpp \ + Scene/CSceneIterator.cpp diff --git a/src/Core/Scene/CScene.cpp b/src/Core/Scene/CScene.cpp index 1f860a38..21e3592b 100644 --- a/src/Core/Scene/CScene.cpp +++ b/src/Core/Scene/CScene.cpp @@ -31,7 +31,7 @@ CModelNode* CScene::CreateModelNode(CModel *pModel) if (pModel == nullptr) return nullptr; CModelNode *pNode = new CModelNode(this, mpSceneRootNode, pModel); - mNodes[eShowObjects].push_back(pNode); + mNodes[eModelNode].push_back(pNode); mNumNodes++; return pNode; } @@ -41,7 +41,7 @@ CStaticNode* CScene::CreateStaticNode(CStaticModel *pModel) if (pModel == nullptr) return nullptr; CStaticNode *pNode = new CStaticNode(this, mpAreaRootNode, pModel); - mNodes[eShowWorld].push_back(pNode); + mNodes[eStaticNode].push_back(pNode); mNumNodes++; return pNode; } @@ -51,7 +51,7 @@ CCollisionNode* CScene::CreateCollisionNode(CCollisionMeshGroup *pMesh) if (pMesh == nullptr) return nullptr; CCollisionNode *pNode = new CCollisionNode(this, mpAreaRootNode, pMesh); - mNodes[eShowWorldCollision].push_back(pNode); + mNodes[eCollisionNode].push_back(pNode); mNumNodes++; return pNode; } @@ -61,7 +61,7 @@ CScriptNode* CScene::CreateScriptNode(CScriptObject *pObj) if (pObj == nullptr) return nullptr; CScriptNode *pNode = new CScriptNode(this, mpAreaRootNode, pObj); - mNodes[eShowObjects].push_back(pNode); + mNodes[eScriptNode].push_back(pNode); mNumNodes++; return pNode; } @@ -71,7 +71,7 @@ CLightNode* CScene::CreateLightNode(CLight *pLight) if (pLight == nullptr) return nullptr; CLightNode *pNode = new CLightNode(this, mpAreaRootNode, pLight); - mNodes[eShowLights].push_back(pNode); + mNodes[eLightNode].push_back(pNode); mNumNodes++; return pNode; } @@ -115,7 +115,7 @@ void CScene::SetActiveArea(CGameArea *pArea) { CScriptLayer *pLayer = mpArea->GetScriptLayer(iLyr); u32 NumObjects = pLayer->GetNumObjects(); - mNodes[eShowObjects].reserve(mNodes[eShowObjects].size() + NumObjects); + mNodes[eScriptNode].reserve(mNodes[eScriptNode].size() + NumObjects); for (u32 iObj = 0; iObj < NumObjects; iObj++) { @@ -202,10 +202,11 @@ void CScene::AddSceneToRenderer(CRenderer *pRenderer, const SViewInfo& ViewInfo) { // Override show flags in game mode FShowFlags ShowFlags = (ViewInfo.GameMode ? gkGameModeShowFlags : ViewInfo.ShowFlags); + FNodeFlags NodeFlags = NodeFlagsForShowFlags(ShowFlags); for (auto it = mNodes.begin(); it != mNodes.end(); it++) { - if (ShowFlags & it->first) + if (NodeFlags & it->first) { std::vector& rNodeVec = it->second; @@ -219,11 +220,12 @@ void CScene::AddSceneToRenderer(CRenderer *pRenderer, const SViewInfo& ViewInfo) SRayIntersection CScene::SceneRayCast(const CRay& Ray, const SViewInfo& ViewInfo) { FShowFlags ShowFlags = (ViewInfo.GameMode ? gkGameModeShowFlags : ViewInfo.ShowFlags); + FNodeFlags NodeFlags = NodeFlagsForShowFlags(ShowFlags); CRayCollisionTester Tester(Ray); for (auto it = mNodes.begin(); it != mNodes.end(); it++) { - if (ShowFlags & it->first) + if (NodeFlags & it->first) { std::vector& rNodeVec = it->second; @@ -252,7 +254,7 @@ CScriptNode* CScene::NodeForObject(CScriptObject *pObj) CLightNode* CScene::NodeForLight(CLight *pLight) { // Slow. Is there a better way to do this? - std::vector& rLights = mNodes[eShowLights]; + std::vector& rLights = mNodes[eLightNode]; for (auto it = rLights.begin(); it != rLights.end(); it++) { @@ -291,3 +293,24 @@ CGameArea* CScene::GetActiveArea() { return mpArea; } + +// ************ STATIC ************ +FShowFlags CScene::ShowFlagsForNodeFlags(FNodeFlags NodeFlags) +{ + FShowFlags Out; + if (NodeFlags & eStaticNode) Out |= eShowWorld; + if (NodeFlags & eScriptNode) Out |= eShowObjects; + if (NodeFlags & eCollisionNode) Out |= eShowWorldCollision; + if (NodeFlags & eLightNode) Out |= eShowLights; + return Out; +} + +FNodeFlags CScene::NodeFlagsForShowFlags(FShowFlags ShowFlags) +{ + FNodeFlags Out = eRootNode | eModelNode; + if (ShowFlags & eShowWorld) Out |= eStaticNode; + if (ShowFlags & eShowWorldCollision) Out |= eCollisionNode; + if (ShowFlags & eShowObjects) Out |= eScriptNode | eScriptExtraNode; + if (ShowFlags & eShowLights) Out |= eLightNode; + return Out; +} diff --git a/src/Core/Scene/CScene.h b/src/Core/Scene/CScene.h index 6ef698bc..04fde572 100644 --- a/src/Core/Scene/CScene.h +++ b/src/Core/Scene/CScene.h @@ -22,11 +22,13 @@ class CScene { + friend class CSceneIterator; + bool mSplitTerrain; u32 mNumNodes; CRootNode *mpSceneRootNode; - std::unordered_map> mNodes; + std::unordered_map> mNodes; TResPtr mpArea; TResPtr mpWorld; @@ -60,6 +62,10 @@ public: // Setters/Getters CModel* GetActiveSkybox(); CGameArea* GetActiveArea(); + + // Static + static FShowFlags ShowFlagsForNodeFlags(FNodeFlags NodeFlags); + static FNodeFlags NodeFlagsForShowFlags(FShowFlags ShowFlags); }; #endif // CSCENE_H diff --git a/src/Core/Scene/CSceneIterator.cpp b/src/Core/Scene/CSceneIterator.cpp new file mode 100644 index 00000000..de05a19d --- /dev/null +++ b/src/Core/Scene/CSceneIterator.cpp @@ -0,0 +1,72 @@ +#include "CSceneIterator.h" +#include "CScene.h" + +CSceneIterator::CSceneIterator(CScene *pScene, FNodeFlags AllowedNodeTypes /*= eAllNodeTypes*/, bool AllowHiddenNodes /*= false*/) + : mpScene(pScene) + , mAllowHiddenNodes(AllowHiddenNodes) + , mNodeFlags(AllowedNodeTypes) + , mpCurNode(nullptr) +{ + mMapIterator = mpScene->mNodes.begin(); + + while (mMapIterator != mpScene->mNodes.end()) + { + if (mMapIterator->first & AllowedNodeTypes) + break; + + mMapIterator++; + } + + if (mMapIterator != mpScene->mNodes.end()) + { + mVectorIterator = (mMapIterator->second).begin(); + Next(); // Find first node + } +} + +// ************ PROTECTED ************ +void CSceneIterator::InternalFindNext() +{ + // This function does most of the heavy lifting. We continue from where we left off last time this function was called. + while (mMapIterator != mpScene->mNodes.end()) + { + // Iterate over each node in the vector. + std::vector& rVector = mMapIterator->second; + bool FoundNext = false; + + while (mVectorIterator != rVector.end()) + { + CSceneNode *pNode = *mVectorIterator; + + // Check node visibility + if (mAllowHiddenNodes || pNode->IsVisible()) + { + mpCurNode = pNode; + FoundNext = true; + } + + mVectorIterator++; + if (FoundNext) return; + } + + // We've reached the end of this node vector, so advance the map iterator + while (true) + { + mMapIterator++; + + if (mMapIterator == mpScene->mNodes.end()) + { + break; + } + + if (mNodeFlags & mMapIterator->first) + { + mVectorIterator = mMapIterator->second.begin(); + break; + } + } + } + + // If we're down here, then it seems we're done iterating the scene. + mpCurNode = nullptr; +} diff --git a/src/Core/Scene/CSceneIterator.h b/src/Core/Scene/CSceneIterator.h new file mode 100644 index 00000000..6c7e7f67 --- /dev/null +++ b/src/Core/Scene/CSceneIterator.h @@ -0,0 +1,66 @@ +#ifndef CSCENEITERATOR_H +#define CSCENEITERATOR_H + +#include "ENodeType.h" +#include + +class CScene; +class CSceneNode; + +class CSceneIterator +{ + CScene *mpScene; + bool mAllowHiddenNodes; + FNodeFlags mNodeFlags; + + CSceneNode *mpCurNode; + std::unordered_map>::iterator mMapIterator; + std::vector::iterator mVectorIterator; + +public: + CSceneIterator(CScene *pScene, FNodeFlags AllowedNodeTypes = eAllNodeTypes, bool AllowHiddenNodes = false); + + inline CSceneNode* Next() + { + InternalFindNext(); + return mpCurNode; + } + + inline bool DoneIterating() const + { + return (mpCurNode == nullptr); + } + + inline CSceneNode* GetNode() const + { + return mpCurNode; + } + + inline CSceneNode* operator*() const + { + return mpCurNode; + } + + inline CSceneNode* operator->() const + { + return mpCurNode; + } + + inline CSceneIterator& operator++() + { + Next(); + return *this; + } + + inline CSceneIterator operator++(int) + { + CSceneIterator Copy = *this; + Next(); + return Copy; + } + +protected: + void InternalFindNext(); +}; + +#endif // CSCENEITERATOR_H diff --git a/src/Core/Scene/ENodeType.h b/src/Core/Scene/ENodeType.h index b97d6f93..2e686725 100644 --- a/src/Core/Scene/ENodeType.h +++ b/src/Core/Scene/ENodeType.h @@ -1,16 +1,21 @@ #ifndef ENODETYPE_H #define ENODETYPE_H +#include + enum ENodeType { - eRootNode, - eModelNode, - eStaticNode, - eCollisionNode, - eScriptNode, - eScriptExtraNode, - eLightNode + eRootNode = 0x0, + eModelNode = 0x1, + eStaticNode = 0x2, + eCollisionNode = 0x4, + eScriptNode = 0x8, + eScriptExtraNode = 0x10, + eLightNode = 0x20, + eAllNodeTypes = 0x3F }; +DECLARE_FLAGS(ENodeType, FNodeFlags) + #endif // ENODETYPE_H diff --git a/src/Editor/CSceneViewport.cpp b/src/Editor/CSceneViewport.cpp index e7ca4e2d..7a89b559 100644 --- a/src/Editor/CSceneViewport.cpp +++ b/src/Editor/CSceneViewport.cpp @@ -45,6 +45,11 @@ void CSceneViewport::SetShowFlag(EShowFlag Flag, bool Visible) mViewInfo.ShowFlags &= ~Flag; } +FShowFlags CSceneViewport::ShowFlags() const +{ + return mViewInfo.ShowFlags; +} + CRenderer* CSceneViewport::Renderer() { return mpRenderer; diff --git a/src/Editor/CSceneViewport.h b/src/Editor/CSceneViewport.h index ef0748bb..14ac2ba5 100644 --- a/src/Editor/CSceneViewport.h +++ b/src/Editor/CSceneViewport.h @@ -32,6 +32,7 @@ public: ~CSceneViewport(); void SetScene(INodeEditor *pEditor, CScene *pScene); void SetShowFlag(EShowFlag Flag, bool Visible); + FShowFlags ShowFlags() const; CRenderer* Renderer(); CSceneNode* HoverNode(); CVector3f HoverPoint(); diff --git a/src/Editor/Editor.pro b/src/Editor/Editor.pro index cbbbc819..a2628686 100644 --- a/src/Editor/Editor.pro +++ b/src/Editor/Editor.pro @@ -125,7 +125,9 @@ HEADERS += \ INodeEditor.h \ TestDialog.h \ UICommon.h \ - CErrorLogDialog.h + CErrorLogDialog.h \ + Undo/CSelectAllCommand.h \ + Undo/CInvertSelectionCommand.h # Source Files SOURCES += \ @@ -171,7 +173,9 @@ SOURCES += \ main.cpp \ TestDialog.cpp \ UICommon.cpp \ - CErrorLogDialog.cpp + CErrorLogDialog.cpp \ + Undo/CSelectAllCommand.cpp \ + Undo/CInvertSelectionCommand.cpp # UI Files FORMS += \ diff --git a/src/Editor/INodeEditor.cpp b/src/Editor/INodeEditor.cpp index 5b2fd44d..d8a26f96 100644 --- a/src/Editor/INodeEditor.cpp +++ b/src/Editor/INodeEditor.cpp @@ -2,12 +2,13 @@ #include "Editor/Undo/UndoCommands.h" INodeEditor::INodeEditor(QWidget *pParent) - : QMainWindow(pParent), - mShowGizmo(false), - mGizmoHovering(false), - mGizmoTransforming(false), - mTranslateSpace(eWorldTransform), - mRotateSpace(eWorldTransform) + : QMainWindow(pParent) + , mSelectionLocked(false) + , mShowGizmo(false) + , mGizmoHovering(false) + , mGizmoTransforming(false) + , mTranslateSpace(eWorldTransform) + , mRotateSpace(eWorldTransform) { // Create undo actions QAction *pUndoAction = mUndoStack.createUndoAction(this); @@ -133,39 +134,68 @@ void INodeEditor::ExpandSelectionBounds(CSceneNode *pNode) void INodeEditor::SelectNode(CSceneNode *pNode) { - if (!pNode->IsSelected()) - mUndoStack.push(new CSelectNodeCommand(this, pNode, mSelection)); + if (!mSelectionLocked) + { + if (!pNode->IsSelected()) + mUndoStack.push(new CSelectNodeCommand(this, pNode, mSelection)); + } } void INodeEditor::DeselectNode(CSceneNode *pNode) { - if (pNode->IsSelected()) - mUndoStack.push(new CDeselectNodeCommand(this, pNode, mSelection)); + if (!mSelectionLocked) + { + if (pNode->IsSelected()) + mUndoStack.push(new CDeselectNodeCommand(this, pNode, mSelection)); + } } void INodeEditor::ClearSelection() { - if (!mSelection.empty()) - mUndoStack.push(new CClearSelectionCommand(this, mSelection)); + if (!mSelectionLocked) + { + if (!mSelection.empty()) + mUndoStack.push(new CClearSelectionCommand(this, mSelection)); + } } void INodeEditor::ClearAndSelectNode(CSceneNode *pNode) { - if (mSelection.empty()) - mUndoStack.push(new CSelectNodeCommand(this, pNode, mSelection)); - - else if ((mSelection.size() == 1) && (mSelection.front() == pNode)) - return; - - else + if (!mSelectionLocked) { - mUndoStack.beginMacro("Select"); - mUndoStack.push(new CClearSelectionCommand(this, mSelection)); - mUndoStack.push(new CSelectNodeCommand(this, pNode, mSelection)); - mUndoStack.endMacro(); + if (mSelection.empty()) + mUndoStack.push(new CSelectNodeCommand(this, pNode, mSelection)); + + else if ((mSelection.size() == 1) && (mSelection.front() == pNode)) + return; + + else + { + mUndoStack.beginMacro("Select"); + mUndoStack.push(new CClearSelectionCommand(this, mSelection)); + mUndoStack.push(new CSelectNodeCommand(this, pNode, mSelection)); + mUndoStack.endMacro(); + } } } +void INodeEditor::SelectAll(FNodeFlags NodeFlags) +{ + if (!mSelectionLocked) + mUndoStack.push(new CSelectAllCommand(this, mSelection, &mScene, NodeFlags)); +} + +void INodeEditor::InvertSelection(FNodeFlags NodeFlags) +{ + if (!mSelectionLocked) + mUndoStack.push(new CInvertSelectionCommand(this, mSelection, &mScene, NodeFlags)); +} + +void INodeEditor::SetSelectionLocked(bool Locked) +{ + mSelectionLocked = Locked; +} + // ************ PUBLIC SLOTS ************ void INodeEditor::OnGizmoMoved() { diff --git a/src/Editor/INodeEditor.h b/src/Editor/INodeEditor.h index 6dbc0f3d..d7c06cd8 100644 --- a/src/Editor/INodeEditor.h +++ b/src/Editor/INodeEditor.h @@ -25,6 +25,7 @@ protected: CScene mScene; QList mSelection; CAABox mSelectionBounds; + bool mSelectionLocked; // Gizmo CGizmo mGizmo; @@ -56,6 +57,9 @@ public: void DeselectNode(CSceneNode *pNode); void ClearSelection(); void ClearAndSelectNode(CSceneNode *pNode); + void SelectAll(FNodeFlags NodeFlags); + void InvertSelection(FNodeFlags NodeFlags); + void SetSelectionLocked(bool Locked); signals: void SelectionModified(); diff --git a/src/Editor/Undo/CInvertSelectionCommand.cpp b/src/Editor/Undo/CInvertSelectionCommand.cpp new file mode 100644 index 00000000..5880d796 --- /dev/null +++ b/src/Editor/Undo/CInvertSelectionCommand.cpp @@ -0,0 +1,56 @@ +#include "CInvertSelectionCommand.h" +#include + +CInvertSelectionCommand::CInvertSelectionCommand(INodeEditor *pEditor, QList& rSelection, CScene *pScene, FNodeFlags NodeFlags) + : QUndoCommand("Invert Selection") + , mpEditor(pEditor) + , mOldSelection(rSelection) + , mpSelection(&rSelection) +{ + CSceneIterator it(pScene, NodeFlags); + + while (!it.DoneIterating()) + { + if (!it->IsSelected()) + mNewSelection.append(*it); + ++it; + } +} + +CInvertSelectionCommand::~CInvertSelectionCommand() +{ +} + +void CInvertSelectionCommand::undo() +{ + *mpSelection = mOldSelection; + + // Deselect all nodes in new selection + foreach (CSceneNode *pNode, mNewSelection) + pNode->SetSelected(false); + + // Select all nodes in the old selection + foreach (CSceneNode *pNode, mOldSelection) + pNode->SetSelected(true); + + // Update editor + mpEditor->RecalculateSelectionBounds(); + mpEditor->SelectionModified(); +} + +void CInvertSelectionCommand::redo() +{ + *mpSelection = mNewSelection; + + // Deselect all nodes in the old selection + foreach (CSceneNode *pNode, mOldSelection) + pNode->SetSelected(false); + + // Select all nodes in the new selection + foreach (CSceneNode *pNode, mNewSelection) + pNode->SetSelected(true); + + // Update editor + mpEditor->RecalculateSelectionBounds(); + mpEditor->SelectionModified(); +} diff --git a/src/Editor/Undo/CInvertSelectionCommand.h b/src/Editor/Undo/CInvertSelectionCommand.h new file mode 100644 index 00000000..20d303c9 --- /dev/null +++ b/src/Editor/Undo/CInvertSelectionCommand.h @@ -0,0 +1,23 @@ +#ifndef CINVERTSELECTIONCOMMAND_H +#define CINVERTSELECTIONCOMMAND_H + +#include "Editor/INodeEditor.h" +#include + +#include + +class CInvertSelectionCommand : public QUndoCommand +{ + INodeEditor *mpEditor; + QList mOldSelection; + QList mNewSelection; + QList *mpSelection; + +public: + CInvertSelectionCommand(INodeEditor *pEditor, QList& rSelection, CScene *pScene, FNodeFlags NodeFlags); + ~CInvertSelectionCommand(); + void undo(); + void redo(); +}; + +#endif // CINVERTSELECTIONCOMMAND_H diff --git a/src/Editor/Undo/CSelectAllCommand.cpp b/src/Editor/Undo/CSelectAllCommand.cpp new file mode 100644 index 00000000..70479e77 --- /dev/null +++ b/src/Editor/Undo/CSelectAllCommand.cpp @@ -0,0 +1,56 @@ +#include "CSelectAllCommand.h" +#include + +CSelectAllCommand::CSelectAllCommand(INodeEditor *pEditor, QList &rSelection, CScene *pScene, FNodeFlags NodeFlags) + : QUndoCommand("Select All") + , mpEditor(pEditor) + , mOldSelection(rSelection) + , mpSelection(&rSelection) +{ + CSceneIterator it(pScene, NodeFlags); + + while (!it.DoneIterating()) + { + mNewSelection.append(*it); + ++it; + } +} + +CSelectAllCommand::~CSelectAllCommand() +{ +} + + +void CSelectAllCommand::undo() +{ + *mpSelection = mOldSelection; + + // Deselect all nodes in new selection + foreach (CSceneNode *pNode, mNewSelection) + pNode->SetSelected(false); + + // Select all nodes in the old selection + foreach (CSceneNode *pNode, mOldSelection) + pNode->SetSelected(true); + + // Update editor + mpEditor->RecalculateSelectionBounds(); + mpEditor->SelectionModified(); +} + +void CSelectAllCommand::redo() +{ + *mpSelection = mNewSelection; + + // Deselect all nodes in the old selection + foreach (CSceneNode *pNode, mOldSelection) + pNode->SetSelected(false); + + // Select all nodes in the new selection + foreach (CSceneNode *pNode, mNewSelection) + pNode->SetSelected(true); + + // Update editor + mpEditor->RecalculateSelectionBounds(); + mpEditor->SelectionModified(); +} diff --git a/src/Editor/Undo/CSelectAllCommand.h b/src/Editor/Undo/CSelectAllCommand.h new file mode 100644 index 00000000..9127aa80 --- /dev/null +++ b/src/Editor/Undo/CSelectAllCommand.h @@ -0,0 +1,23 @@ +#ifndef CSELECTALLCOMMAND_H +#define CSELECTALLCOMMAND_H + +#include "Editor/INodeEditor.h" +#include + +#include + +class CSelectAllCommand : public QUndoCommand +{ + INodeEditor *mpEditor; + QList mOldSelection; + QList mNewSelection; + QList *mpSelection; + +public: + CSelectAllCommand(INodeEditor *pEditor, QList& rSelection, CScene *pScene, FNodeFlags NodeFlags); + ~CSelectAllCommand(); + void undo(); + void redo(); +}; + +#endif // CSELECTALLCOMMAND_H diff --git a/src/Editor/Undo/UndoCommands.h b/src/Editor/Undo/UndoCommands.h index ca190147..ee84d186 100644 --- a/src/Editor/Undo/UndoCommands.h +++ b/src/Editor/Undo/UndoCommands.h @@ -7,6 +7,8 @@ #include "CSelectNodeCommand.h" #include "CDeselectNodeCommand.h" #include "CClearSelectionCommand.h" +#include "CSelectAllCommand.h" +#include "CInvertSelectionCommand.h" #include "EUndoCommand.h" #endif // UNDOCOMMANDS diff --git a/src/Editor/WorldEditor/CWorldEditor.cpp b/src/Editor/WorldEditor/CWorldEditor.cpp index e7b424db..9808c15c 100644 --- a/src/Editor/WorldEditor/CWorldEditor.cpp +++ b/src/Editor/WorldEditor/CWorldEditor.cpp @@ -11,6 +11,7 @@ #include "Editor/UICommon.h" #include +#include #include #include @@ -57,7 +58,8 @@ CWorldEditor::CWorldEditor(QWidget *parent) : mpTransformCombo->setMinimumWidth(75); ui->MainToolBar->addActions(mGizmoActions); ui->MainToolBar->addWidget(mpTransformCombo); - ui->menuEdit->addActions(mUndoActions); + ui->menuEdit->insertActions(ui->ActionSelectAll, mUndoActions); + ui->menuEdit->insertSeparator(ui->ActionSelectAll); // Initialize offscreen actions addAction(ui->ActionIncrementGizmo); @@ -471,3 +473,17 @@ void CWorldEditor::on_ActionGameMode_triggered() { ui->MainViewport->SetGameMode(ui->ActionGameMode->isChecked()); } + +void CWorldEditor::on_ActionSelectAll_triggered() +{ + FNodeFlags NodeFlags = CScene::NodeFlagsForShowFlags(ui->MainViewport->ShowFlags()); + NodeFlags &= ~(eStaticNode | eCollisionNode); + SelectAll(NodeFlags); +} + +void CWorldEditor::on_ActionInvertSelection_triggered() +{ + FNodeFlags NodeFlags = CScene::NodeFlagsForShowFlags(ui->MainViewport->ShowFlags()); + NodeFlags &= ~(eStaticNode | eCollisionNode); + InvertSelection(NodeFlags); +} diff --git a/src/Editor/WorldEditor/CWorldEditor.h b/src/Editor/WorldEditor/CWorldEditor.h index 1d33ac8c..be79c110 100644 --- a/src/Editor/WorldEditor/CWorldEditor.h +++ b/src/Editor/WorldEditor/CWorldEditor.h @@ -77,6 +77,8 @@ private slots: void on_ActionDecrementGizmo_triggered(); void on_ActionDrawObjectCollision_triggered(); void on_ActionGameMode_triggered(); + void on_ActionSelectAll_triggered(); + void on_ActionInvertSelection_triggered(); }; #endif // CWORLDEDITOR_H diff --git a/src/Editor/WorldEditor/CWorldEditor.ui b/src/Editor/WorldEditor/CWorldEditor.ui index 9aff7622..ec72e51b 100644 --- a/src/Editor/WorldEditor/CWorldEditor.ui +++ b/src/Editor/WorldEditor/CWorldEditor.ui @@ -245,6 +245,8 @@ Edit + + @@ -740,6 +742,22 @@ G + + + Select All + + + Ctrl+A + + + + + Invert Selection + + + Ctrl+I + + diff --git a/src/Editor/main.cpp b/src/Editor/main.cpp index 31cdeabf..3ea787ff 100644 --- a/src/Editor/main.cpp +++ b/src/Editor/main.cpp @@ -2,9 +2,6 @@ #include "CDarkStyle.h" #include -// temp -#include - #include #include