PrimeWorldEditor/src/Editor/CNodeSelection.h

125 lines
3.4 KiB
C++

#ifndef CNODESELECTION_H
#define CNODESELECTION_H
#include <Core/Scene/CSceneIterator.h>
#include <Core/Scene/CSceneNode.h>
#include <Core/Scene/CScriptNode.h>
#include <QList>
#include <QObject>
class CNodeSelection : public QObject
{
Q_OBJECT
FNodeFlags mAllowedNodes{ENodeType::All};
QList<CSceneNode*> mSelectedNodes;
mutable CAABox mCachedBounds;
mutable bool mBoundsDirty = true;
public:
CNodeSelection() = default;
~CNodeSelection() override
{
for (CSceneNode *pNode : mSelectedNodes)
pNode->SetSelected(false);
}
void SelectNode(CSceneNode *pNode)
{
if (IsAllowedType(pNode->NodeType()) && !pNode->IsSelected())
{
pNode->SetSelected(true);
mSelectedNodes << pNode;
mCachedBounds.ExpandBounds(pNode->AABox());
emit Modified();
}
}
void DeselectNode(CSceneNode *pNode)
{
if (pNode->IsSelected())
{
pNode->SetSelected(false);
mSelectedNodes.removeOne(pNode);
mBoundsDirty = true;
emit Modified();
}
}
void Clear()
{
for (CSceneNode *pNode : mSelectedNodes)
pNode->SetSelected(false);
mSelectedNodes.clear();
mBoundsDirty = true;
emit Modified();
}
void ClearAndSelectNode(CSceneNode *pNode)
{
// Block signals for Clear so that Modified only emits once.
blockSignals(true);
Clear();
blockSignals(false);
SelectNode(pNode);
}
void SetSelectedNodes(const QList<CSceneNode*>& rkList)
{
blockSignals(true);
Clear();
for (CSceneNode *pNode : rkList)
SelectNode(pNode);
blockSignals(false);
mBoundsDirty = true;
emit Modified();
}
CAABox Bounds() const
{
if (mBoundsDirty)
{
mCachedBounds = CAABox::Infinite();
for (CSceneNode *pNode : mSelectedNodes)
{
mCachedBounds.ExpandBounds(pNode->AABox());
if (pNode->NodeType() == ENodeType::Script)
{
CScriptNode *pScript = static_cast<CScriptNode*>(pNode);
if (pScript->HasPreviewVolume())
mCachedBounds.ExpandBounds(pScript->PreviewVolumeAABox());
}
}
mBoundsDirty = false;
}
return mCachedBounds;
}
uint32 Size() const { return mSelectedNodes.size(); }
bool IsEmpty() const { return Size() == 0; }
CSceneNode* At(uint32 Index) const { return mSelectedNodes[Index]; }
CSceneNode* Front() const { return mSelectedNodes.front(); }
CSceneNode* Back() const { return mSelectedNodes.back(); }
CSceneNode* operator[](uint32 Index) const { return mSelectedNodes[Index]; }
void UpdateBounds() { mBoundsDirty = true; }
void SetAllowedNodeTypes(FNodeFlags Types) { mAllowedNodes = Types; }
bool IsAllowedType(ENodeType Type) const { return (mAllowedNodes & Type) != 0; }
bool IsAllowedType(CSceneNode *pNode) const { return (mAllowedNodes & pNode->NodeType()) != 0; }
QList<CSceneNode*> SelectedNodeList() const { return mSelectedNodes; }
signals:
void Modified();
};
#endif // CNODESELECTION_H