Added CSceneIterator and implemented support for Select All/Invert Selection
This commit is contained in:
parent
7eeb90b925
commit
38d04bcd25
|
@ -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
|
||||
|
|
|
@ -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<CSceneNode*>& 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<CSceneNode*>& 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<CSceneNode*>& rLights = mNodes[eShowLights];
|
||||
std::vector<CSceneNode*>& 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;
|
||||
}
|
||||
|
|
|
@ -22,11 +22,13 @@
|
|||
|
||||
class CScene
|
||||
{
|
||||
friend class CSceneIterator;
|
||||
|
||||
bool mSplitTerrain;
|
||||
|
||||
u32 mNumNodes;
|
||||
CRootNode *mpSceneRootNode;
|
||||
std::unordered_map<EShowFlag, std::vector<CSceneNode*>> mNodes;
|
||||
std::unordered_map<ENodeType, std::vector<CSceneNode*>> mNodes;
|
||||
|
||||
TResPtr<CGameArea> mpArea;
|
||||
TResPtr<CWorld> 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
|
||||
|
|
|
@ -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<CSceneNode*>& 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;
|
||||
}
|
|
@ -0,0 +1,66 @@
|
|||
#ifndef CSCENEITERATOR_H
|
||||
#define CSCENEITERATOR_H
|
||||
|
||||
#include "ENodeType.h"
|
||||
#include <unordered_map>
|
||||
|
||||
class CScene;
|
||||
class CSceneNode;
|
||||
|
||||
class CSceneIterator
|
||||
{
|
||||
CScene *mpScene;
|
||||
bool mAllowHiddenNodes;
|
||||
FNodeFlags mNodeFlags;
|
||||
|
||||
CSceneNode *mpCurNode;
|
||||
std::unordered_map<ENodeType, std::vector<CSceneNode*>>::iterator mMapIterator;
|
||||
std::vector<CSceneNode*>::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
|
|
@ -1,16 +1,21 @@
|
|||
#ifndef ENODETYPE_H
|
||||
#define ENODETYPE_H
|
||||
|
||||
#include <Common/Flags.h>
|
||||
|
||||
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
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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 += \
|
||||
|
|
|
@ -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()
|
||||
{
|
||||
|
|
|
@ -25,6 +25,7 @@ protected:
|
|||
CScene mScene;
|
||||
QList<CSceneNode*> 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();
|
||||
|
|
|
@ -0,0 +1,56 @@
|
|||
#include "CInvertSelectionCommand.h"
|
||||
#include <Core/Scene/CSceneIterator.h>
|
||||
|
||||
CInvertSelectionCommand::CInvertSelectionCommand(INodeEditor *pEditor, QList<CSceneNode*>& 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();
|
||||
}
|
|
@ -0,0 +1,23 @@
|
|||
#ifndef CINVERTSELECTIONCOMMAND_H
|
||||
#define CINVERTSELECTIONCOMMAND_H
|
||||
|
||||
#include "Editor/INodeEditor.h"
|
||||
#include <Core/Scene/CSceneNode.h>
|
||||
|
||||
#include <QUndoCommand>
|
||||
|
||||
class CInvertSelectionCommand : public QUndoCommand
|
||||
{
|
||||
INodeEditor *mpEditor;
|
||||
QList<CSceneNode*> mOldSelection;
|
||||
QList<CSceneNode*> mNewSelection;
|
||||
QList<CSceneNode*> *mpSelection;
|
||||
|
||||
public:
|
||||
CInvertSelectionCommand(INodeEditor *pEditor, QList<CSceneNode*>& rSelection, CScene *pScene, FNodeFlags NodeFlags);
|
||||
~CInvertSelectionCommand();
|
||||
void undo();
|
||||
void redo();
|
||||
};
|
||||
|
||||
#endif // CINVERTSELECTIONCOMMAND_H
|
|
@ -0,0 +1,56 @@
|
|||
#include "CSelectAllCommand.h"
|
||||
#include <Core/Scene/CSceneIterator.h>
|
||||
|
||||
CSelectAllCommand::CSelectAllCommand(INodeEditor *pEditor, QList<CSceneNode *> &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();
|
||||
}
|
|
@ -0,0 +1,23 @@
|
|||
#ifndef CSELECTALLCOMMAND_H
|
||||
#define CSELECTALLCOMMAND_H
|
||||
|
||||
#include "Editor/INodeEditor.h"
|
||||
#include <Core/Scene/CSceneNode.h>
|
||||
|
||||
#include <QUndoCommand>
|
||||
|
||||
class CSelectAllCommand : public QUndoCommand
|
||||
{
|
||||
INodeEditor *mpEditor;
|
||||
QList<CSceneNode*> mOldSelection;
|
||||
QList<CSceneNode*> mNewSelection;
|
||||
QList<CSceneNode*> *mpSelection;
|
||||
|
||||
public:
|
||||
CSelectAllCommand(INodeEditor *pEditor, QList<CSceneNode*>& rSelection, CScene *pScene, FNodeFlags NodeFlags);
|
||||
~CSelectAllCommand();
|
||||
void undo();
|
||||
void redo();
|
||||
};
|
||||
|
||||
#endif // CSELECTALLCOMMAND_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
|
||||
|
|
|
@ -11,6 +11,7 @@
|
|||
#include "Editor/UICommon.h"
|
||||
|
||||
#include <Core/Render/CDrawUtil.h>
|
||||
#include <Core/Scene/CSceneIterator.h>
|
||||
#include <Core/Log.h>
|
||||
|
||||
#include <iostream>
|
||||
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -245,6 +245,8 @@
|
|||
<property name="title">
|
||||
<string>Edit</string>
|
||||
</property>
|
||||
<addaction name="ActionSelectAll"/>
|
||||
<addaction name="ActionInvertSelection"/>
|
||||
</widget>
|
||||
<widget class="QMenu" name="menuView">
|
||||
<property name="title">
|
||||
|
@ -740,6 +742,22 @@
|
|||
<string>G</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="ActionSelectAll">
|
||||
<property name="text">
|
||||
<string>Select All</string>
|
||||
</property>
|
||||
<property name="shortcut">
|
||||
<string>Ctrl+A</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="ActionInvertSelection">
|
||||
<property name="text">
|
||||
<string>Invert Selection</string>
|
||||
</property>
|
||||
<property name="shortcut">
|
||||
<string>Ctrl+I</string>
|
||||
</property>
|
||||
</action>
|
||||
</widget>
|
||||
<customwidgets>
|
||||
<customwidget>
|
||||
|
|
|
@ -2,9 +2,6 @@
|
|||
#include "CDarkStyle.h"
|
||||
#include <Core/Resource/Factory/CTemplateLoader.h>
|
||||
|
||||
// temp
|
||||
#include <Core/Resource/Cooker/CTemplateWriter.h>
|
||||
|
||||
#include <QApplication>
|
||||
#include <QStyleFactory>
|
||||
|
||||
|
|
Loading…
Reference in New Issue