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 \
|
Resource/Model/EVertexAttribute.h \
|
||||||
Render/FRenderOptions.h \
|
Render/FRenderOptions.h \
|
||||||
Scene/FShowFlags.h \
|
Scene/FShowFlags.h \
|
||||||
Scene/CScene.h
|
Scene/CScene.h \
|
||||||
|
Scene/CSceneIterator.h
|
||||||
|
|
||||||
# Source Files
|
# Source Files
|
||||||
SOURCES += \
|
SOURCES += \
|
||||||
|
@ -265,4 +266,5 @@ SOURCES += \
|
||||||
Resource/Script/IPropertyTemplate.cpp \
|
Resource/Script/IPropertyTemplate.cpp \
|
||||||
Resource/Script/IProperty.cpp \
|
Resource/Script/IProperty.cpp \
|
||||||
Scene/FShowFlags.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;
|
if (pModel == nullptr) return nullptr;
|
||||||
|
|
||||||
CModelNode *pNode = new CModelNode(this, mpSceneRootNode, pModel);
|
CModelNode *pNode = new CModelNode(this, mpSceneRootNode, pModel);
|
||||||
mNodes[eShowObjects].push_back(pNode);
|
mNodes[eModelNode].push_back(pNode);
|
||||||
mNumNodes++;
|
mNumNodes++;
|
||||||
return pNode;
|
return pNode;
|
||||||
}
|
}
|
||||||
|
@ -41,7 +41,7 @@ CStaticNode* CScene::CreateStaticNode(CStaticModel *pModel)
|
||||||
if (pModel == nullptr) return nullptr;
|
if (pModel == nullptr) return nullptr;
|
||||||
|
|
||||||
CStaticNode *pNode = new CStaticNode(this, mpAreaRootNode, pModel);
|
CStaticNode *pNode = new CStaticNode(this, mpAreaRootNode, pModel);
|
||||||
mNodes[eShowWorld].push_back(pNode);
|
mNodes[eStaticNode].push_back(pNode);
|
||||||
mNumNodes++;
|
mNumNodes++;
|
||||||
return pNode;
|
return pNode;
|
||||||
}
|
}
|
||||||
|
@ -51,7 +51,7 @@ CCollisionNode* CScene::CreateCollisionNode(CCollisionMeshGroup *pMesh)
|
||||||
if (pMesh == nullptr) return nullptr;
|
if (pMesh == nullptr) return nullptr;
|
||||||
|
|
||||||
CCollisionNode *pNode = new CCollisionNode(this, mpAreaRootNode, pMesh);
|
CCollisionNode *pNode = new CCollisionNode(this, mpAreaRootNode, pMesh);
|
||||||
mNodes[eShowWorldCollision].push_back(pNode);
|
mNodes[eCollisionNode].push_back(pNode);
|
||||||
mNumNodes++;
|
mNumNodes++;
|
||||||
return pNode;
|
return pNode;
|
||||||
}
|
}
|
||||||
|
@ -61,7 +61,7 @@ CScriptNode* CScene::CreateScriptNode(CScriptObject *pObj)
|
||||||
if (pObj == nullptr) return nullptr;
|
if (pObj == nullptr) return nullptr;
|
||||||
|
|
||||||
CScriptNode *pNode = new CScriptNode(this, mpAreaRootNode, pObj);
|
CScriptNode *pNode = new CScriptNode(this, mpAreaRootNode, pObj);
|
||||||
mNodes[eShowObjects].push_back(pNode);
|
mNodes[eScriptNode].push_back(pNode);
|
||||||
mNumNodes++;
|
mNumNodes++;
|
||||||
return pNode;
|
return pNode;
|
||||||
}
|
}
|
||||||
|
@ -71,7 +71,7 @@ CLightNode* CScene::CreateLightNode(CLight *pLight)
|
||||||
if (pLight == nullptr) return nullptr;
|
if (pLight == nullptr) return nullptr;
|
||||||
|
|
||||||
CLightNode *pNode = new CLightNode(this, mpAreaRootNode, pLight);
|
CLightNode *pNode = new CLightNode(this, mpAreaRootNode, pLight);
|
||||||
mNodes[eShowLights].push_back(pNode);
|
mNodes[eLightNode].push_back(pNode);
|
||||||
mNumNodes++;
|
mNumNodes++;
|
||||||
return pNode;
|
return pNode;
|
||||||
}
|
}
|
||||||
|
@ -115,7 +115,7 @@ void CScene::SetActiveArea(CGameArea *pArea)
|
||||||
{
|
{
|
||||||
CScriptLayer *pLayer = mpArea->GetScriptLayer(iLyr);
|
CScriptLayer *pLayer = mpArea->GetScriptLayer(iLyr);
|
||||||
u32 NumObjects = pLayer->GetNumObjects();
|
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++)
|
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
|
// Override show flags in game mode
|
||||||
FShowFlags ShowFlags = (ViewInfo.GameMode ? gkGameModeShowFlags : ViewInfo.ShowFlags);
|
FShowFlags ShowFlags = (ViewInfo.GameMode ? gkGameModeShowFlags : ViewInfo.ShowFlags);
|
||||||
|
FNodeFlags NodeFlags = NodeFlagsForShowFlags(ShowFlags);
|
||||||
|
|
||||||
for (auto it = mNodes.begin(); it != mNodes.end(); it++)
|
for (auto it = mNodes.begin(); it != mNodes.end(); it++)
|
||||||
{
|
{
|
||||||
if (ShowFlags & it->first)
|
if (NodeFlags & it->first)
|
||||||
{
|
{
|
||||||
std::vector<CSceneNode*>& rNodeVec = it->second;
|
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)
|
SRayIntersection CScene::SceneRayCast(const CRay& Ray, const SViewInfo& ViewInfo)
|
||||||
{
|
{
|
||||||
FShowFlags ShowFlags = (ViewInfo.GameMode ? gkGameModeShowFlags : ViewInfo.ShowFlags);
|
FShowFlags ShowFlags = (ViewInfo.GameMode ? gkGameModeShowFlags : ViewInfo.ShowFlags);
|
||||||
|
FNodeFlags NodeFlags = NodeFlagsForShowFlags(ShowFlags);
|
||||||
CRayCollisionTester Tester(Ray);
|
CRayCollisionTester Tester(Ray);
|
||||||
|
|
||||||
for (auto it = mNodes.begin(); it != mNodes.end(); it++)
|
for (auto it = mNodes.begin(); it != mNodes.end(); it++)
|
||||||
{
|
{
|
||||||
if (ShowFlags & it->first)
|
if (NodeFlags & it->first)
|
||||||
{
|
{
|
||||||
std::vector<CSceneNode*>& rNodeVec = it->second;
|
std::vector<CSceneNode*>& rNodeVec = it->second;
|
||||||
|
|
||||||
|
@ -252,7 +254,7 @@ CScriptNode* CScene::NodeForObject(CScriptObject *pObj)
|
||||||
CLightNode* CScene::NodeForLight(CLight *pLight)
|
CLightNode* CScene::NodeForLight(CLight *pLight)
|
||||||
{
|
{
|
||||||
// Slow. Is there a better way to do this?
|
// 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++)
|
for (auto it = rLights.begin(); it != rLights.end(); it++)
|
||||||
{
|
{
|
||||||
|
@ -291,3 +293,24 @@ CGameArea* CScene::GetActiveArea()
|
||||||
{
|
{
|
||||||
return mpArea;
|
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
|
class CScene
|
||||||
{
|
{
|
||||||
|
friend class CSceneIterator;
|
||||||
|
|
||||||
bool mSplitTerrain;
|
bool mSplitTerrain;
|
||||||
|
|
||||||
u32 mNumNodes;
|
u32 mNumNodes;
|
||||||
CRootNode *mpSceneRootNode;
|
CRootNode *mpSceneRootNode;
|
||||||
std::unordered_map<EShowFlag, std::vector<CSceneNode*>> mNodes;
|
std::unordered_map<ENodeType, std::vector<CSceneNode*>> mNodes;
|
||||||
|
|
||||||
TResPtr<CGameArea> mpArea;
|
TResPtr<CGameArea> mpArea;
|
||||||
TResPtr<CWorld> mpWorld;
|
TResPtr<CWorld> mpWorld;
|
||||||
|
@ -60,6 +62,10 @@ public:
|
||||||
// Setters/Getters
|
// Setters/Getters
|
||||||
CModel* GetActiveSkybox();
|
CModel* GetActiveSkybox();
|
||||||
CGameArea* GetActiveArea();
|
CGameArea* GetActiveArea();
|
||||||
|
|
||||||
|
// Static
|
||||||
|
static FShowFlags ShowFlagsForNodeFlags(FNodeFlags NodeFlags);
|
||||||
|
static FNodeFlags NodeFlagsForShowFlags(FShowFlags ShowFlags);
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // CSCENE_H
|
#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
|
#ifndef ENODETYPE_H
|
||||||
#define ENODETYPE_H
|
#define ENODETYPE_H
|
||||||
|
|
||||||
|
#include <Common/Flags.h>
|
||||||
|
|
||||||
enum ENodeType
|
enum ENodeType
|
||||||
{
|
{
|
||||||
eRootNode,
|
eRootNode = 0x0,
|
||||||
eModelNode,
|
eModelNode = 0x1,
|
||||||
eStaticNode,
|
eStaticNode = 0x2,
|
||||||
eCollisionNode,
|
eCollisionNode = 0x4,
|
||||||
eScriptNode,
|
eScriptNode = 0x8,
|
||||||
eScriptExtraNode,
|
eScriptExtraNode = 0x10,
|
||||||
eLightNode
|
eLightNode = 0x20,
|
||||||
|
eAllNodeTypes = 0x3F
|
||||||
};
|
};
|
||||||
|
|
||||||
|
DECLARE_FLAGS(ENodeType, FNodeFlags)
|
||||||
|
|
||||||
#endif // ENODETYPE_H
|
#endif // ENODETYPE_H
|
||||||
|
|
||||||
|
|
|
@ -45,6 +45,11 @@ void CSceneViewport::SetShowFlag(EShowFlag Flag, bool Visible)
|
||||||
mViewInfo.ShowFlags &= ~Flag;
|
mViewInfo.ShowFlags &= ~Flag;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
FShowFlags CSceneViewport::ShowFlags() const
|
||||||
|
{
|
||||||
|
return mViewInfo.ShowFlags;
|
||||||
|
}
|
||||||
|
|
||||||
CRenderer* CSceneViewport::Renderer()
|
CRenderer* CSceneViewport::Renderer()
|
||||||
{
|
{
|
||||||
return mpRenderer;
|
return mpRenderer;
|
||||||
|
|
|
@ -32,6 +32,7 @@ public:
|
||||||
~CSceneViewport();
|
~CSceneViewport();
|
||||||
void SetScene(INodeEditor *pEditor, CScene *pScene);
|
void SetScene(INodeEditor *pEditor, CScene *pScene);
|
||||||
void SetShowFlag(EShowFlag Flag, bool Visible);
|
void SetShowFlag(EShowFlag Flag, bool Visible);
|
||||||
|
FShowFlags ShowFlags() const;
|
||||||
CRenderer* Renderer();
|
CRenderer* Renderer();
|
||||||
CSceneNode* HoverNode();
|
CSceneNode* HoverNode();
|
||||||
CVector3f HoverPoint();
|
CVector3f HoverPoint();
|
||||||
|
|
|
@ -125,7 +125,9 @@ HEADERS += \
|
||||||
INodeEditor.h \
|
INodeEditor.h \
|
||||||
TestDialog.h \
|
TestDialog.h \
|
||||||
UICommon.h \
|
UICommon.h \
|
||||||
CErrorLogDialog.h
|
CErrorLogDialog.h \
|
||||||
|
Undo/CSelectAllCommand.h \
|
||||||
|
Undo/CInvertSelectionCommand.h
|
||||||
|
|
||||||
# Source Files
|
# Source Files
|
||||||
SOURCES += \
|
SOURCES += \
|
||||||
|
@ -171,7 +173,9 @@ SOURCES += \
|
||||||
main.cpp \
|
main.cpp \
|
||||||
TestDialog.cpp \
|
TestDialog.cpp \
|
||||||
UICommon.cpp \
|
UICommon.cpp \
|
||||||
CErrorLogDialog.cpp
|
CErrorLogDialog.cpp \
|
||||||
|
Undo/CSelectAllCommand.cpp \
|
||||||
|
Undo/CInvertSelectionCommand.cpp
|
||||||
|
|
||||||
# UI Files
|
# UI Files
|
||||||
FORMS += \
|
FORMS += \
|
||||||
|
|
|
@ -2,12 +2,13 @@
|
||||||
#include "Editor/Undo/UndoCommands.h"
|
#include "Editor/Undo/UndoCommands.h"
|
||||||
|
|
||||||
INodeEditor::INodeEditor(QWidget *pParent)
|
INodeEditor::INodeEditor(QWidget *pParent)
|
||||||
: QMainWindow(pParent),
|
: QMainWindow(pParent)
|
||||||
mShowGizmo(false),
|
, mSelectionLocked(false)
|
||||||
mGizmoHovering(false),
|
, mShowGizmo(false)
|
||||||
mGizmoTransforming(false),
|
, mGizmoHovering(false)
|
||||||
mTranslateSpace(eWorldTransform),
|
, mGizmoTransforming(false)
|
||||||
mRotateSpace(eWorldTransform)
|
, mTranslateSpace(eWorldTransform)
|
||||||
|
, mRotateSpace(eWorldTransform)
|
||||||
{
|
{
|
||||||
// Create undo actions
|
// Create undo actions
|
||||||
QAction *pUndoAction = mUndoStack.createUndoAction(this);
|
QAction *pUndoAction = mUndoStack.createUndoAction(this);
|
||||||
|
@ -133,39 +134,68 @@ void INodeEditor::ExpandSelectionBounds(CSceneNode *pNode)
|
||||||
|
|
||||||
void INodeEditor::SelectNode(CSceneNode *pNode)
|
void INodeEditor::SelectNode(CSceneNode *pNode)
|
||||||
{
|
{
|
||||||
if (!pNode->IsSelected())
|
if (!mSelectionLocked)
|
||||||
mUndoStack.push(new CSelectNodeCommand(this, pNode, mSelection));
|
{
|
||||||
|
if (!pNode->IsSelected())
|
||||||
|
mUndoStack.push(new CSelectNodeCommand(this, pNode, mSelection));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void INodeEditor::DeselectNode(CSceneNode *pNode)
|
void INodeEditor::DeselectNode(CSceneNode *pNode)
|
||||||
{
|
{
|
||||||
if (pNode->IsSelected())
|
if (!mSelectionLocked)
|
||||||
mUndoStack.push(new CDeselectNodeCommand(this, pNode, mSelection));
|
{
|
||||||
|
if (pNode->IsSelected())
|
||||||
|
mUndoStack.push(new CDeselectNodeCommand(this, pNode, mSelection));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void INodeEditor::ClearSelection()
|
void INodeEditor::ClearSelection()
|
||||||
{
|
{
|
||||||
if (!mSelection.empty())
|
if (!mSelectionLocked)
|
||||||
mUndoStack.push(new CClearSelectionCommand(this, mSelection));
|
{
|
||||||
|
if (!mSelection.empty())
|
||||||
|
mUndoStack.push(new CClearSelectionCommand(this, mSelection));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void INodeEditor::ClearAndSelectNode(CSceneNode *pNode)
|
void INodeEditor::ClearAndSelectNode(CSceneNode *pNode)
|
||||||
{
|
{
|
||||||
if (mSelection.empty())
|
if (!mSelectionLocked)
|
||||||
mUndoStack.push(new CSelectNodeCommand(this, pNode, mSelection));
|
|
||||||
|
|
||||||
else if ((mSelection.size() == 1) && (mSelection.front() == pNode))
|
|
||||||
return;
|
|
||||||
|
|
||||||
else
|
|
||||||
{
|
{
|
||||||
mUndoStack.beginMacro("Select");
|
if (mSelection.empty())
|
||||||
mUndoStack.push(new CClearSelectionCommand(this, mSelection));
|
mUndoStack.push(new CSelectNodeCommand(this, pNode, mSelection));
|
||||||
mUndoStack.push(new CSelectNodeCommand(this, pNode, mSelection));
|
|
||||||
mUndoStack.endMacro();
|
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 ************
|
// ************ PUBLIC SLOTS ************
|
||||||
void INodeEditor::OnGizmoMoved()
|
void INodeEditor::OnGizmoMoved()
|
||||||
{
|
{
|
||||||
|
|
|
@ -25,6 +25,7 @@ protected:
|
||||||
CScene mScene;
|
CScene mScene;
|
||||||
QList<CSceneNode*> mSelection;
|
QList<CSceneNode*> mSelection;
|
||||||
CAABox mSelectionBounds;
|
CAABox mSelectionBounds;
|
||||||
|
bool mSelectionLocked;
|
||||||
|
|
||||||
// Gizmo
|
// Gizmo
|
||||||
CGizmo mGizmo;
|
CGizmo mGizmo;
|
||||||
|
@ -56,6 +57,9 @@ public:
|
||||||
void DeselectNode(CSceneNode *pNode);
|
void DeselectNode(CSceneNode *pNode);
|
||||||
void ClearSelection();
|
void ClearSelection();
|
||||||
void ClearAndSelectNode(CSceneNode *pNode);
|
void ClearAndSelectNode(CSceneNode *pNode);
|
||||||
|
void SelectAll(FNodeFlags NodeFlags);
|
||||||
|
void InvertSelection(FNodeFlags NodeFlags);
|
||||||
|
void SetSelectionLocked(bool Locked);
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void SelectionModified();
|
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 "CSelectNodeCommand.h"
|
||||||
#include "CDeselectNodeCommand.h"
|
#include "CDeselectNodeCommand.h"
|
||||||
#include "CClearSelectionCommand.h"
|
#include "CClearSelectionCommand.h"
|
||||||
|
#include "CSelectAllCommand.h"
|
||||||
|
#include "CInvertSelectionCommand.h"
|
||||||
#include "EUndoCommand.h"
|
#include "EUndoCommand.h"
|
||||||
|
|
||||||
#endif // UNDOCOMMANDS
|
#endif // UNDOCOMMANDS
|
||||||
|
|
|
@ -11,6 +11,7 @@
|
||||||
#include "Editor/UICommon.h"
|
#include "Editor/UICommon.h"
|
||||||
|
|
||||||
#include <Core/Render/CDrawUtil.h>
|
#include <Core/Render/CDrawUtil.h>
|
||||||
|
#include <Core/Scene/CSceneIterator.h>
|
||||||
#include <Core/Log.h>
|
#include <Core/Log.h>
|
||||||
|
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
@ -57,7 +58,8 @@ CWorldEditor::CWorldEditor(QWidget *parent) :
|
||||||
mpTransformCombo->setMinimumWidth(75);
|
mpTransformCombo->setMinimumWidth(75);
|
||||||
ui->MainToolBar->addActions(mGizmoActions);
|
ui->MainToolBar->addActions(mGizmoActions);
|
||||||
ui->MainToolBar->addWidget(mpTransformCombo);
|
ui->MainToolBar->addWidget(mpTransformCombo);
|
||||||
ui->menuEdit->addActions(mUndoActions);
|
ui->menuEdit->insertActions(ui->ActionSelectAll, mUndoActions);
|
||||||
|
ui->menuEdit->insertSeparator(ui->ActionSelectAll);
|
||||||
|
|
||||||
// Initialize offscreen actions
|
// Initialize offscreen actions
|
||||||
addAction(ui->ActionIncrementGizmo);
|
addAction(ui->ActionIncrementGizmo);
|
||||||
|
@ -471,3 +473,17 @@ void CWorldEditor::on_ActionGameMode_triggered()
|
||||||
{
|
{
|
||||||
ui->MainViewport->SetGameMode(ui->ActionGameMode->isChecked());
|
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_ActionDecrementGizmo_triggered();
|
||||||
void on_ActionDrawObjectCollision_triggered();
|
void on_ActionDrawObjectCollision_triggered();
|
||||||
void on_ActionGameMode_triggered();
|
void on_ActionGameMode_triggered();
|
||||||
|
void on_ActionSelectAll_triggered();
|
||||||
|
void on_ActionInvertSelection_triggered();
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // CWORLDEDITOR_H
|
#endif // CWORLDEDITOR_H
|
||||||
|
|
|
@ -245,6 +245,8 @@
|
||||||
<property name="title">
|
<property name="title">
|
||||||
<string>Edit</string>
|
<string>Edit</string>
|
||||||
</property>
|
</property>
|
||||||
|
<addaction name="ActionSelectAll"/>
|
||||||
|
<addaction name="ActionInvertSelection"/>
|
||||||
</widget>
|
</widget>
|
||||||
<widget class="QMenu" name="menuView">
|
<widget class="QMenu" name="menuView">
|
||||||
<property name="title">
|
<property name="title">
|
||||||
|
@ -740,6 +742,22 @@
|
||||||
<string>G</string>
|
<string>G</string>
|
||||||
</property>
|
</property>
|
||||||
</action>
|
</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>
|
</widget>
|
||||||
<customwidgets>
|
<customwidgets>
|
||||||
<customwidget>
|
<customwidget>
|
||||||
|
|
|
@ -2,9 +2,6 @@
|
||||||
#include "CDarkStyle.h"
|
#include "CDarkStyle.h"
|
||||||
#include <Core/Resource/Factory/CTemplateLoader.h>
|
#include <Core/Resource/Factory/CTemplateLoader.h>
|
||||||
|
|
||||||
// temp
|
|
||||||
#include <Core/Resource/Cooker/CTemplateWriter.h>
|
|
||||||
|
|
||||||
#include <QApplication>
|
#include <QApplication>
|
||||||
#include <QStyleFactory>
|
#include <QStyleFactory>
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue