Added room objects to store placed objects in rooms

This commit is contained in:
2022-03-11 15:45:22 +01:00
parent e5406ed0ce
commit 0cbde44138
6 changed files with 148 additions and 36 deletions

View File

@@ -19,6 +19,7 @@ RoomPropertiesDialog::RoomPropertiesDialog(Room &room, ProjectTreeModel &project
m_ui{std::make_unique<Ui::RoomPropertiesDialog>()}, m_ui{std::make_unique<Ui::RoomPropertiesDialog>()},
m_room{room}, m_room{room},
m_projectModel{projectModel}, m_projectModel{projectModel},
m_objects{m_room.objects},
m_scene{std::make_unique<RoomScene>(this)}, m_scene{std::make_unique<RoomScene>(this)},
m_creationCode{m_room.creationCode}, m_creationCode{m_room.creationCode},
m_spinBoxSnapX{new QSpinBox{this}}, m_spinBoxSnapX{new QSpinBox{this}},
@@ -31,6 +32,7 @@ RoomPropertiesDialog::RoomPropertiesDialog(Room &room, ProjectTreeModel &project
updateTitle(); updateTitle();
m_ui->roomEditWidget->setObjects(&m_objects);
m_ui->roomEditWidget->setFixedWidth(m_room.width); m_ui->roomEditWidget->setFixedWidth(m_room.width);
m_ui->roomEditWidget->setFixedHeight(m_room.height); m_ui->roomEditWidget->setFixedHeight(m_room.height);
m_ui->roomEditWidget->setSnapX(m_room.snapX); m_ui->roomEditWidget->setSnapX(m_room.snapX);
@@ -181,6 +183,8 @@ RoomPropertiesDialog::RoomPropertiesDialog(Room &room, ProjectTreeModel &project
m_ui->actionIsometricGrid, &QAction::setChecked); m_ui->actionIsometricGrid, &QAction::setChecked);
connect(m_ui->roomEditWidget, &RoomEditWidget::cursorMoved, connect(m_ui->roomEditWidget, &RoomEditWidget::cursorMoved,
this, &RoomPropertiesDialog::cursorMoved); this, &RoomPropertiesDialog::cursorMoved);
connect(m_ui->roomEditWidget, &RoomEditWidget::changed,
this, &RoomPropertiesDialog::changed);
connect(m_menuObjects, &QMenu::aboutToShow, connect(m_menuObjects, &QMenu::aboutToShow,
this, &RoomPropertiesDialog::objectsMenuAboutToShow); this, &RoomPropertiesDialog::objectsMenuAboutToShow);
@@ -219,6 +223,8 @@ void RoomPropertiesDialog::accept()
m_room.gridEnabled = m_ui->actionGridEnabled->isChecked(); m_room.gridEnabled = m_ui->actionGridEnabled->isChecked();
m_room.isometricGrid = m_ui->actionIsometricGrid->isChecked(); m_room.isometricGrid = m_ui->actionIsometricGrid->isChecked();
m_room.objects = m_objects;
QDialog::accept(); QDialog::accept();
} }

View File

@@ -4,6 +4,8 @@
#include <memory> #include <memory>
#include "projectcontainer.h"
class QSpinBox; class QSpinBox;
class QLabel; class QLabel;
class QMenu; class QMenu;
@@ -56,6 +58,8 @@ private:
Room &m_room; Room &m_room;
ProjectTreeModel &m_projectModel; ProjectTreeModel &m_projectModel;
std::vector<Room::Object> m_objects;
const std::unique_ptr<RoomScene> m_scene; const std::unique_ptr<RoomScene> m_scene;
QString m_creationCode; QString m_creationCode;

View File

@@ -17,6 +17,11 @@ RoomEditWidget::RoomEditWidget(QWidget *parent) :
setFixedSize(640, 480); setFixedSize(640, 480);
} }
void RoomEditWidget::setObjects(std::vector<Room::Object> *objects)
{
m_objects = objects;
}
void RoomEditWidget::setSnapX(int snapX) void RoomEditWidget::setSnapX(int snapX)
{ {
if (m_snapX == snapX) if (m_snapX == snapX)
@@ -92,33 +97,8 @@ void RoomEditWidget::paintEvent(QPaintEvent *event)
QPainter painter{this}; QPainter painter{this};
if (m_draggedObject) paintObjects(painter);
{ paintDraggedObject(painter);
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}});
}
}
if (m_gridBrush) if (m_gridBrush)
painter.fillRect(rect(), m_gridBrush->brush); painter.fillRect(rect(), m_gridBrush->brush);
@@ -132,7 +112,7 @@ void RoomEditWidget::mousePressEvent(QMouseEvent *event)
{ {
m_draggedObject = DraggedObject { m_draggedObject = DraggedObject {
.object = *m_selectedObject, .object = *m_selectedObject,
.pos = event->pos() .pos = snapPoint(event->pos())
}; };
update(); update();
} }
@@ -144,6 +124,16 @@ void RoomEditWidget::mouseReleaseEvent(QMouseEvent *event)
if (m_draggedObject) 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; m_draggedObject = std::nullopt;
update(); update();
} }
@@ -153,17 +143,16 @@ void RoomEditWidget::mouseMoveEvent(QMouseEvent *event)
{ {
QWidget::mouseMoveEvent(event); QWidget::mouseMoveEvent(event);
emit cursorMoved(snapPoint(event->pos())); const auto snappedPos = snapPoint(event->pos());
emit cursorMoved(snappedPos);
if (m_draggedObject) if (m_draggedObject)
if (snappedPos != m_draggedObject->pos)
{ {
const auto newPos = snapPoint(event->pos()); m_draggedObject->pos = snappedPos;
if (newPos != m_draggedObject->pos)
{
m_draggedObject->pos = newPos;
update(); update();
} }
}
} }
QPoint RoomEditWidget::snapPoint(const QPoint &point) const 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(), 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}});
}
}

View File

@@ -5,6 +5,8 @@
#include <optional> #include <optional>
#include "projectcontainer.h"
struct Object; struct Object;
class ProjectTreeModel; class ProjectTreeModel;
@@ -19,6 +21,10 @@ class RoomEditWidget : public QWidget
public: public:
explicit RoomEditWidget(QWidget *parent = nullptr); explicit RoomEditWidget(QWidget *parent = nullptr);
std::vector<Room::Object> *objects() { return m_objects; }
const std::vector<Room::Object> *objects() const { return m_objects; }
void setObjects(std::vector<Room::Object> *objects);
int snapX() const { return m_snapX; } int snapX() const { return m_snapX; }
void setSnapX(int snapX); void setSnapX(int snapX);
@@ -49,6 +55,8 @@ signals:
void cursorMoved(const QPoint &point); void cursorMoved(const QPoint &point);
void changed();
protected: protected:
void paintEvent(QPaintEvent *event) override; void paintEvent(QPaintEvent *event) override;
void mousePressEvent(QMouseEvent *event) override; void mousePressEvent(QMouseEvent *event) override;
@@ -57,6 +65,10 @@ protected:
private: private:
QPoint snapPoint(const QPoint &point) const; QPoint snapPoint(const QPoint &point) const;
void paintObjects(QPainter &painter);
void paintDraggedObject(QPainter &painter);
std::vector<Room::Object> *m_objects{};
int m_snapX{16}; int m_snapX{16};
int m_snapY{16}; int m_snapY{16};

View File

@@ -322,6 +322,20 @@ QDataStream &operator>>(QDataStream &ds, Object &object)
return ds; 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) QDataStream &operator<<(QDataStream &ds, const Room &room)
{ {
ds << room.name ds << room.name
@@ -334,7 +348,8 @@ QDataStream &operator<<(QDataStream &ds, const Room &room)
<< room.snapX << room.snapX
<< room.snapY << room.snapY
<< room.gridEnabled << room.gridEnabled
<< room.isometricGrid; << room.isometricGrid
<< room.objects;
return ds; return ds;
} }
@@ -350,7 +365,8 @@ QDataStream &operator>>(QDataStream &ds, Room &room)
>> room.snapX >> room.snapX
>> room.snapY >> room.snapY
>> room.gridEnabled >> room.gridEnabled
>> room.isometricGrid; >> room.isometricGrid
>> room.objects;
return ds; return ds;
} }

View File

@@ -140,6 +140,13 @@ struct Room
int snapY{16}; int snapY{16};
bool gridEnabled{true}; bool gridEnabled{true};
bool isometricGrid{}; bool isometricGrid{};
struct Object {
QString objectName;
QPoint pos;
};
std::vector<Object> objects;
}; };
struct ProjectContainer struct ProjectContainer