22#include <QXmlStreamWriter>
24#include "SceneModel.h"
26#include "aeongames/Node.hpp"
31 QAbstractItemModel (
parent ) {}
37 if ( ( orientation == Qt::Horizontal ) && ( role == Qt::DisplayRole ) )
42 return QString (
"Node" );
54 if ( row <
static_cast<int> ( mScene.GetChildrenCount() ) )
56 return createIndex ( row, column, &
const_cast<SceneModel*
> (
this )->mScene[row] );
64 return createIndex ( row, column, node->
GetChild ( row ) );
72 if (
index.isValid() )
74 Node* node =
reinterpret_cast<Node*
> (
index.internalPointer() );
76 if ( node_parent !=
nullptr )
78 return createIndex (
static_cast<int> ( node->
GetIndex() ), 0, node_parent );
86 if (
index.isValid() )
88 return static_cast<int> (
reinterpret_cast<Node*
> (
index.internalPointer() )->GetChildrenCount() );
90 return static_cast<int> ( mScene.GetChildrenCount() );
100 if (
index.isValid() )
104 return ( mScene.GetChildrenCount() > 0 );
109 if ( ( role == Qt::DisplayRole ) || ( role == Qt::EditRole ) )
111 if (
index.isValid() )
113 switch (
index.column() )
116 return QString (
reinterpret_cast<Node*
> (
index.internalPointer() )->
GetName().c_str() );
121 else if ( role == Qt::DecorationRole )
123 if ( mScene.GetCamera() !=
reinterpret_cast<Node *
> (
index.internalPointer() ) )
125 return QIcon (
":/icons/icon_node" );
127 return QIcon (
":/icons/icon_camera" );
129 else if ( role == Qt::UserRole )
131 return QVariant::fromValue (
index.internalPointer() );
138 if (
index.isValid() )
140 return QAbstractItemModel::flags (
index ) | Qt::ItemIsEditable | Qt::ItemIsDragEnabled | Qt::ItemIsDropEnabled;
142 return QAbstractItemModel::flags (
index ) | Qt::ItemIsDropEnabled;
147 Node* node =
reinterpret_cast<Node*
> (
index.internalPointer() );
148 if ( role == Qt::EditRole )
150 node->
SetName ( value.toString().toUtf8().constData() );
157 bool SceneModel::moveRows (
const QModelIndex & sourceParent,
int sourceRow,
int count,
const QModelIndex & destinationParent,
int destinationRow )
159 if ( sourceParent.isValid() && destinationParent.isValid() )
162 Node* source =
reinterpret_cast<Node*
> ( sourceParent.internalPointer() );
163 Node* destination =
reinterpret_cast<Node*
> ( destinationParent.internalPointer() );
164 if ( beginMoveRows ( sourceParent, sourceRow, ( sourceRow + count ) - 1, destinationParent, destinationRow ) )
166 for (
int i = 0; i < count; ++i )
177 else if ( sourceParent.isValid() )
180 Node* source =
reinterpret_cast<Node*
> ( sourceParent.internalPointer() );
181 if ( beginMoveRows ( sourceParent, sourceRow, ( sourceRow + count ) - 1, destinationParent, destinationRow ) )
183 for (
int i = 0; i < count; ++i )
185 mScene.Insert ( destinationRow + i, source->
RemoveByIndex ( sourceRow ) );
194 else if ( destinationParent.isValid() )
197 Node* destination =
reinterpret_cast<Node*
> ( destinationParent.internalPointer() );
198 if ( beginMoveRows ( sourceParent, sourceRow, ( sourceRow + count ) - 1, destinationParent, destinationRow ) )
200 for (
int i = 0; i < count; ++i )
202 destination->
Insert ( destinationRow + i, mScene.RemoveByIndex ( sourceRow ) );
214 if ( beginMoveRows ( sourceParent, sourceRow, ( sourceRow + count ) - 1, destinationParent, destinationRow ) )
216 for (
int i = 0; i < count; ++i )
218 mScene.Insert ( destinationRow + i, mScene.RemoveByIndex ( sourceRow ) );
232 return Qt::MoveAction;
237 QString format (
"application/x-aeon-engine-node" );
239 if ( !
data || ( action != Qt::MoveAction ) )
244 if ( !
data->hasFormat ( format ) )
252 QByteArray byteArray =
data->data ( format );
253 QDataStream dataStream ( &byteArray, QIODevice::ReadOnly );
256 for (
int i = 0; i < count; ++i )
259 dataStream.readRawData (
reinterpret_cast<char*
> ( &pointer ),
sizeof (
void* ) );
260 QModelIndex model_index = createIndex (
static_cast<int> ( pointer->
GetIndex() ), column, pointer );
261 moveRow ( this->parent ( model_index ),
static_cast<int> ( pointer->
GetIndex() ),
parent, row );
268 QMimeData*
data =
nullptr;
269 if ( !indexes.isEmpty() )
271 QByteArray byteArray;
272 byteArray.reserve ( ( indexes.count() + 1 ) *sizeof (
void* ) );
273 QDataStream dataStream ( &byteArray, QIODevice::WriteOnly );
274 dataStream << indexes.count();
275 for (
auto i = indexes.cbegin(); i != indexes.cend(); ++i )
277 void* pointer = ( *i ).internalPointer();
278 dataStream.writeRawData (
reinterpret_cast<char*
> ( &pointer ),
sizeof (
void* ) );
281 data =
new QMimeData();
282 data->setData ( types[0], byteArray );
290 types <<
"application/x-aeon-engine-node";
296 beginInsertRows (
parent, row, row );
299 reinterpret_cast<Node*
> (
parent.internalPointer() )->
Insert (
static_cast<size_t> ( row ), ( ( aNode ) ? std::move ( aNode ) : std::make_unique<Node>() ) );
303 mScene.Insert (
static_cast<size_t> ( row ), ( ( aNode ) ? std::move ( aNode ) : std::make_unique<Node>() ) );
310 beginRemoveRows (
parent, row, row );
317 mScene.RemoveByIndex (
static_cast<size_t> ( row ) );
325 if (
index.isValid() )
327 mScene.SetCamera (
reinterpret_cast<Node*
> (
index.internalPointer() ) );
331 mScene.SetCamera (
nullptr );
338 return mScene.Serialize ( aAsBinary );
344 mScene.Deserialize ( aSerializedScene );
Header for the Scene class.
Scene graph node representing an entity in the game world.
DLL size_t GetIndex() const
Get this node's index within its parent's child list.
DLL Node * GetChild(size_t aIndex) const
Get a child node by index.
DLL void SetName(const std::string &aName)
Set the name of this node.
DLL const std::string & GetName() const
Get the name of this node.
DLL NodeParent GetParent() const
Get this node's parent.
DLL Node * Insert(size_t aIndex, std::unique_ptr< Node > aNode)
Insert a child node at a specific index.
DLL std::unique_ptr< Node > RemoveByIndex(size_t aIndex)
Remove a child node by index.
DLL size_t GetChildrenCount() const
Get the number of direct child nodes.
Scene class. Scene is the container for all elements in a game level, takes care of collision,...
QMimeData * mimeData(const QModelIndexList &indexes) const override
Return serialized MIME data for the given model indexes.
bool dropMimeData(const QMimeData *data, Qt::DropAction action, int row, int column, const QModelIndex &parent) override
Handle data supplied by a drag-and-drop operation.
QModelIndex index(int row, int column, const QModelIndex &parent=QModelIndex()) const override
Return the index of the item at the given row and column under parent.
int rowCount(const QModelIndex &index=QModelIndex()) const override
Return the number of rows under the given parent.
QVariant headerData(int section, Qt::Orientation orientation, int role=Qt::DisplayRole) const override
Return the header data for the given section, orientation, and role.
const Scene & GetScene() const
Get a const reference to the underlying scene.
std::string Serialize(bool aAsBinary=true) const
Serialize the scene to a string.
bool setData(const QModelIndex &index, const QVariant &value, int role) override
Set the data for the given index and role.
void Deserialize(const std::string &aSerializedScene)
Deserialize a scene from a string.
QModelIndex parent(const QModelIndex &index) const override
Return the parent of the given model index.
int columnCount(const QModelIndex &index=QModelIndex()) const override
Return the number of columns for children of the given parent.
void InsertNode(int row, const QModelIndex &parent=QModelIndex(), std::unique_ptr< Node > aNode={})
Insert a node into the scene tree.
bool hasChildren(const QModelIndex &index=QModelIndex()) const override
Return whether the given parent index has any children.
Qt::ItemFlags flags(const QModelIndex &index) const override
Return the item flags for the given model index.
SceneModel(QObject *parent=nullptr)
Construct the scene model.
bool moveRows(const QModelIndex &sourceParent, int sourceRow, int count, const QModelIndex &destinationParent, int destinationRow) override
Move rows from one parent to another.
QVariant data(const QModelIndex &index, int role=Qt::DisplayRole) const override
Return the data for the given index and role.
void SetCameraNode(const QModelIndex &index=QModelIndex())
Set the camera to the node at the given index.
Qt::DropActions supportedDropActions() const override
Return the drop actions supported by this model.
void RemoveNode(int row, const QModelIndex &parent=QModelIndex())
Remove a node from the scene tree.
virtual ~SceneModel()
Destructor.
QStringList mimeTypes() const override
Return the list of MIME types that can be used to describe model indexes.
<- This is here just for the literals
Node * GetNodePtr(const NodeParent &aNodeParent)
Extract the Node pointer from a NodeParent variant.