From 0cbde441380dc2b28677838fd187ce7575944e66 Mon Sep 17 00:00:00 2001 From: 0xFEEDC0DE64 Date: Fri, 11 Mar 2022 15:45:22 +0100 Subject: [PATCH] Added room objects to store placed objects in rooms --- src/editor/dialogs/roompropertiesdialog.cpp | 6 + src/editor/dialogs/roompropertiesdialog.h | 4 + src/editor/widgets/roomeditwidget.cpp | 135 +++++++++++++++----- src/editor/widgets/roomeditwidget.h | 12 ++ src/projectcontainer.cpp | 20 ++- src/projectcontainer.h | 7 + 6 files changed, 148 insertions(+), 36 deletions(-) diff --git a/src/editor/dialogs/roompropertiesdialog.cpp b/src/editor/dialogs/roompropertiesdialog.cpp index 1f60383..1bc89bd 100644 --- a/src/editor/dialogs/roompropertiesdialog.cpp +++ b/src/editor/dialogs/roompropertiesdialog.cpp @@ -19,6 +19,7 @@ RoomPropertiesDialog::RoomPropertiesDialog(Room &room, ProjectTreeModel &project m_ui{std::make_unique()}, m_room{room}, m_projectModel{projectModel}, + m_objects{m_room.objects}, m_scene{std::make_unique(this)}, m_creationCode{m_room.creationCode}, m_spinBoxSnapX{new QSpinBox{this}}, @@ -31,6 +32,7 @@ RoomPropertiesDialog::RoomPropertiesDialog(Room &room, ProjectTreeModel &project updateTitle(); + m_ui->roomEditWidget->setObjects(&m_objects); m_ui->roomEditWidget->setFixedWidth(m_room.width); m_ui->roomEditWidget->setFixedHeight(m_room.height); m_ui->roomEditWidget->setSnapX(m_room.snapX); @@ -181,6 +183,8 @@ RoomPropertiesDialog::RoomPropertiesDialog(Room &room, ProjectTreeModel &project m_ui->actionIsometricGrid, &QAction::setChecked); connect(m_ui->roomEditWidget, &RoomEditWidget::cursorMoved, this, &RoomPropertiesDialog::cursorMoved); + connect(m_ui->roomEditWidget, &RoomEditWidget::changed, + this, &RoomPropertiesDialog::changed); connect(m_menuObjects, &QMenu::aboutToShow, this, &RoomPropertiesDialog::objectsMenuAboutToShow); @@ -219,6 +223,8 @@ void RoomPropertiesDialog::accept() m_room.gridEnabled = m_ui->actionGridEnabled->isChecked(); m_room.isometricGrid = m_ui->actionIsometricGrid->isChecked(); + m_room.objects = m_objects; + QDialog::accept(); } diff --git a/src/editor/dialogs/roompropertiesdialog.h b/src/editor/dialogs/roompropertiesdialog.h index 3957548..ddb02b1 100644 --- a/src/editor/dialogs/roompropertiesdialog.h +++ b/src/editor/dialogs/roompropertiesdialog.h @@ -4,6 +4,8 @@ #include +#include "projectcontainer.h" + class QSpinBox; class QLabel; class QMenu; @@ -56,6 +58,8 @@ private: Room &m_room; ProjectTreeModel &m_projectModel; + std::vector m_objects; + const std::unique_ptr m_scene; QString m_creationCode; diff --git a/src/editor/widgets/roomeditwidget.cpp b/src/editor/widgets/roomeditwidget.cpp index 2bbdd2f..554c1bc 100644 --- a/src/editor/widgets/roomeditwidget.cpp +++ b/src/editor/widgets/roomeditwidget.cpp @@ -17,6 +17,11 @@ RoomEditWidget::RoomEditWidget(QWidget *parent) : setFixedSize(640, 480); } +void RoomEditWidget::setObjects(std::vector *objects) +{ + m_objects = objects; +} + void RoomEditWidget::setSnapX(int snapX) { if (m_snapX == snapX) @@ -92,33 +97,8 @@ void RoomEditWidget::paintEvent(QPaintEvent *event) QPainter painter{this}; - if (m_draggedObject) - { - if (m_projectTreeModel) - { - QPixmap pixmap; - const auto &object = m_draggedObject->object.get(); - if (!object.spriteName.isEmpty()) - { - const auto iter = std::find_if(std::cbegin(m_projectTreeModel->project()->sprites), std::cend(m_projectTreeModel->project()->sprites), - [&object](const auto &sprite){ return object.spriteName == sprite.name; }); - if (iter == std::cend(m_projectTreeModel->project()->sprites)) - qWarning() << "invalid sprite" << object.spriteName; - else if (!iter->pixmaps.empty() && !iter->pixmaps.front().isNull()) - pixmap = iter->pixmaps.front(); - } - - if (pixmap.isNull()) - goto noPixmap; - - painter.drawPixmap(m_draggedObject->pos, std::move(pixmap)); - } - else - { -noPixmap: - painter.drawRect(QRect{m_draggedObject->pos, QSize{64, 64}}); - } - } + paintObjects(painter); + paintDraggedObject(painter); if (m_gridBrush) painter.fillRect(rect(), m_gridBrush->brush); @@ -132,7 +112,7 @@ void RoomEditWidget::mousePressEvent(QMouseEvent *event) { m_draggedObject = DraggedObject { .object = *m_selectedObject, - .pos = event->pos() + .pos = snapPoint(event->pos()) }; update(); } @@ -144,6 +124,16 @@ void RoomEditWidget::mouseReleaseEvent(QMouseEvent *event) if (m_draggedObject) { + if (m_objects) + { + m_objects->emplace_back(Room::Object{ + .objectName = m_draggedObject->object.get().name, + .pos = snapPoint(event->pos()) + }); + + emit changed(); + } + m_draggedObject = std::nullopt; update(); } @@ -153,17 +143,16 @@ void RoomEditWidget::mouseMoveEvent(QMouseEvent *event) { QWidget::mouseMoveEvent(event); - emit cursorMoved(snapPoint(event->pos())); + const auto snappedPos = snapPoint(event->pos()); + + emit cursorMoved(snappedPos); if (m_draggedObject) - { - const auto newPos = snapPoint(event->pos()); - if (newPos != m_draggedObject->pos) + if (snappedPos != m_draggedObject->pos) { - m_draggedObject->pos = newPos; + m_draggedObject->pos = snappedPos; update(); } - } } QPoint RoomEditWidget::snapPoint(const QPoint &point) const @@ -173,3 +162,81 @@ QPoint RoomEditWidget::snapPoint(const QPoint &point) const m_snapY > 1 ? ((point.y() + (m_snapY / 2)) / m_snapY * m_snapY) : point.y(), }; } + +void RoomEditWidget::paintObjects(QPainter &painter) +{ + if (!m_objects) + return; + + for (const Room::Object &object : *m_objects) + { + if (m_projectTreeModel) + { + const auto iter = std::find_if(std::cbegin(m_projectTreeModel->project()->objects), std::cend(m_projectTreeModel->project()->objects), + [&object](const auto &obj){ return object.objectName == obj.name; }); + if (iter == std::cend(m_projectTreeModel->project()->objects)) + { + qWarning() << "invalid object" << object.objectName; + goto noPixmap; + } + + if (iter->spriteName.isEmpty()) + goto noPixmap; + + { + const auto iter2 = std::find_if(std::cbegin(m_projectTreeModel->project()->sprites), std::cend(m_projectTreeModel->project()->sprites), + [&object=*iter](const auto &sprite){ return object.spriteName == sprite.name; }); + + if (iter2 == std::cend(m_projectTreeModel->project()->sprites)) + { + qWarning() << "invalid sprite" << iter->spriteName; + goto noPixmap; + } + + if (iter2->pixmaps.empty() || iter2->pixmaps.front().isNull()) + goto noPixmap; + + painter.drawPixmap(object.pos, iter2->pixmaps.front()); + } + } + else + { +noPixmap: + painter.drawRect(QRect{object.pos, QSize{64, 64}}); + } + } +} + +void RoomEditWidget::paintDraggedObject(QPainter &painter) +{ + if (!m_draggedObject) + return; + + if (m_projectTreeModel) + { + const auto &object = m_draggedObject->object.get(); + + if (object.spriteName.isEmpty()) + goto noPixmap; + + { + const auto iter = std::find_if(std::cbegin(m_projectTreeModel->project()->sprites), std::cend(m_projectTreeModel->project()->sprites), + [&object](const auto &sprite){ return object.spriteName == sprite.name; }); + if (iter == std::cend(m_projectTreeModel->project()->sprites)) + { + qWarning() << "invalid sprite" << object.spriteName; + goto noPixmap; + } + + if (iter->pixmaps.empty() || iter->pixmaps.front().isNull()) + goto noPixmap; + + painter.drawPixmap(m_draggedObject->pos, iter->pixmaps.front()); + } + } + else + { +noPixmap: + painter.drawRect(QRect{m_draggedObject->pos, QSize{64, 64}}); + } +} diff --git a/src/editor/widgets/roomeditwidget.h b/src/editor/widgets/roomeditwidget.h index 6550166..71a0f40 100644 --- a/src/editor/widgets/roomeditwidget.h +++ b/src/editor/widgets/roomeditwidget.h @@ -5,6 +5,8 @@ #include +#include "projectcontainer.h" + struct Object; class ProjectTreeModel; @@ -19,6 +21,10 @@ class RoomEditWidget : public QWidget public: explicit RoomEditWidget(QWidget *parent = nullptr); + std::vector *objects() { return m_objects; } + const std::vector *objects() const { return m_objects; } + void setObjects(std::vector *objects); + int snapX() const { return m_snapX; } void setSnapX(int snapX); @@ -49,6 +55,8 @@ signals: void cursorMoved(const QPoint &point); + void changed(); + protected: void paintEvent(QPaintEvent *event) override; void mousePressEvent(QMouseEvent *event) override; @@ -57,6 +65,10 @@ protected: private: QPoint snapPoint(const QPoint &point) const; + void paintObjects(QPainter &painter); + void paintDraggedObject(QPainter &painter); + + std::vector *m_objects{}; int m_snapX{16}; int m_snapY{16}; diff --git a/src/projectcontainer.cpp b/src/projectcontainer.cpp index 7d36b88..d2f14a5 100644 --- a/src/projectcontainer.cpp +++ b/src/projectcontainer.cpp @@ -322,6 +322,20 @@ QDataStream &operator>>(QDataStream &ds, Object &object) return ds; } +QDataStream &operator<<(QDataStream &ds, const Room::Object &object) +{ + ds << object.objectName + << object.pos; + return ds; +} + +QDataStream &operator>>(QDataStream &ds, Room::Object &object) +{ + ds >> object.objectName + >> object.pos; + return ds; +} + QDataStream &operator<<(QDataStream &ds, const Room &room) { ds << room.name @@ -334,7 +348,8 @@ QDataStream &operator<<(QDataStream &ds, const Room &room) << room.snapX << room.snapY << room.gridEnabled - << room.isometricGrid; + << room.isometricGrid + << room.objects; return ds; } @@ -350,7 +365,8 @@ QDataStream &operator>>(QDataStream &ds, Room &room) >> room.snapX >> room.snapY >> room.gridEnabled - >> room.isometricGrid; + >> room.isometricGrid + >> room.objects; return ds; } diff --git a/src/projectcontainer.h b/src/projectcontainer.h index 26d664b..15052c7 100644 --- a/src/projectcontainer.h +++ b/src/projectcontainer.h @@ -140,6 +140,13 @@ struct Room int snapY{16}; bool gridEnabled{true}; bool isometricGrid{}; + + struct Object { + QString objectName; + QPoint pos; + }; + + std::vector objects; }; struct ProjectContainer