diff --git a/QtGameMaker.pro b/QtGameMaker.pro index d0e57ec..c09b8ec 100644 --- a/QtGameMaker.pro +++ b/QtGameMaker.pro @@ -11,6 +11,7 @@ DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 HEADERS += \ codeeditorwidget.h \ constantsmodel.h \ + dialogs/addeventdialog.h \ dialogs/codeeditordialog.h \ dialogs/createspritedialog.h \ dialogs/fontpropertiesdialog.h \ @@ -54,6 +55,7 @@ HEADERS += \ SOURCES += main.cpp \ codeeditorwidget.cpp \ constantsmodel.cpp \ + dialogs/addeventdialog.cpp \ dialogs/codeeditordialog.cpp \ dialogs/createspritedialog.cpp \ dialogs/fontpropertiesdialog.cpp \ @@ -94,6 +96,7 @@ SOURCES += main.cpp \ triggersmodel.cpp FORMS += \ + dialogs/addeventdialog.ui \ dialogs/codeeditordialog.ui \ dialogs/createspritedialog.ui \ dialogs/fontpropertiesdialog.ui \ diff --git a/dialogs/addeventdialog.cpp b/dialogs/addeventdialog.cpp new file mode 100644 index 0000000..b0c51b3 --- /dev/null +++ b/dialogs/addeventdialog.cpp @@ -0,0 +1,48 @@ +#include "addeventdialog.h" +#include "ui_addeventdialog.h" + +#include + +AddEventDialog::AddEventDialog(QWidget *parent) : + QDialog{parent}, + m_ui{std::make_unique()} +{ + m_ui->setupUi(this); + +#ifdef Q_OS_LINUX + setWindowFlags((windowFlags() & ~Qt::Dialog) | Qt::Window); +#endif + setWindowFlag(Qt::WindowCloseButtonHint); + + if (auto button = m_ui->buttonBox->button(QDialogButtonBox::Ok)) + button->setIcon(QIcon{":/qtgameengine/icons/ok.png"}); + if (auto button = m_ui->buttonBox->button(QDialogButtonBox::Cancel)) + button->setIcon(QIcon{":/qtgameengine/icons/delete.png"}); + + connect(m_ui->pushButtonCreate, &QAbstractButton::clicked, + this, [this](){ m_eventType = Object::EventType::Create; accept(); }); + connect(m_ui->pushButtonStep, &QAbstractButton::clicked, + this, [this](){ m_eventType = Object::EventType::Step; accept(); }); + connect(m_ui->pushButtonDestroy, &QAbstractButton::clicked, + this, [this](){ m_eventType = Object::EventType::Destroy; accept(); }); +} + +AddEventDialog::~AddEventDialog() = default; + +void AddEventDialog::accept() +{ + if (!m_eventType) + { + QMessageBox::warning(this, tr("No Event selected!"), tr("No Event selected!")); + return; + } + + QDialog::accept(); +} + +void AddEventDialog::reject() +{ + m_eventType = std::nullopt; + + QDialog::reject(); +} diff --git a/dialogs/addeventdialog.h b/dialogs/addeventdialog.h new file mode 100644 index 0000000..3b88fd6 --- /dev/null +++ b/dialogs/addeventdialog.h @@ -0,0 +1,28 @@ +#pragma once + +#include + +#include + +#include "projectcontainer.h" + +namespace Ui { class AddEventDialog; } + +class AddEventDialog : public QDialog +{ + Q_OBJECT + +public: + explicit AddEventDialog(QWidget *parent = nullptr); + ~AddEventDialog(); + + Object::EventType eventType() const { return *m_eventType; } + + void accept() override; + void reject() override; + +private: + const std::unique_ptr m_ui; + + std::optional m_eventType; +}; diff --git a/dialogs/addeventdialog.ui b/dialogs/addeventdialog.ui new file mode 100644 index 0000000..aa5b6f4 --- /dev/null +++ b/dialogs/addeventdialog.ui @@ -0,0 +1,166 @@ + + + AddEventDialog + + + + 0 + 0 + 265 + 220 + + + + Choose the Event to Add + + + + + + + + Dra&w + + + + + + + &Mouse + + + + + + + Ke&y Release + + + + + + + &Alarm + + + + + + + &Step + + + + :/qtgameengine/icons/event-step.png:/qtgameengine/icons/event-step.png + + + + + + + C&reate + + + + :/qtgameengine/icons/event-create.png:/qtgameengine/icons/event-create.png + + + + + + + O&ther + + + + + + + C&ollision + + + + + + + &Destroy + + + + :/qtgameengine/icons/event-destroy.png:/qtgameengine/icons/event-destroy.png + + + + + + + Key &Press + + + + + + + &Keyboard + + + + + + + &Trigger + + + + + + + + + QDialogButtonBox::Cancel + + + true + + + + + + + + + + + buttonBox + accepted() + AddEventDialog + accept() + + + 132 + 196 + + + 132 + 108 + + + + + buttonBox + rejected() + AddEventDialog + reject() + + + 132 + 196 + + + 132 + 108 + + + + + diff --git a/dialogs/backgroundpropertiesdialog.ui b/dialogs/backgroundpropertiesdialog.ui index 0aa5732..74f7a03 100644 --- a/dialogs/backgroundpropertiesdialog.ui +++ b/dialogs/backgroundpropertiesdialog.ui @@ -25,7 +25,7 @@ - Name: + &Name: lineEditName diff --git a/dialogs/fontpropertiesdialog.ui b/dialogs/fontpropertiesdialog.ui index c767f61..e6be99c 100644 --- a/dialogs/fontpropertiesdialog.ui +++ b/dialogs/fontpropertiesdialog.ui @@ -23,7 +23,7 @@ - Name: + &Name: lineEditName diff --git a/dialogs/objectpropertiesdialog.cpp b/dialogs/objectpropertiesdialog.cpp index 63ea67e..a02ed97 100644 --- a/dialogs/objectpropertiesdialog.cpp +++ b/dialogs/objectpropertiesdialog.cpp @@ -7,17 +7,18 @@ #include -#include "projectcontainer.h" #include "projecttreemodel.h" #include "objecteventsmodel.h" #include "objectactionsmodel.h" +#include "addeventdialog.h" ObjectPropertiesDialog::ObjectPropertiesDialog(Object &object, ProjectTreeModel &projectModel, QWidget *parent) : QDialog{parent}, m_ui{std::make_unique()}, m_object{object}, m_projectModel{projectModel}, - m_eventsModel{std::make_unique()}, + m_events{m_object.events}, + m_eventsModel{std::make_unique(m_events)}, m_actionsModel{std::make_unique()}, m_spritesMenu{new QMenu{m_ui->toolButtonSprite}}, m_spriteName{object.spriteName} @@ -106,6 +107,7 @@ void ObjectPropertiesDialog::accept() m_object.solid = m_ui->checkBoxSolid->isChecked(); m_object.depth = m_ui->spinBoxDepth->value(); m_object.persistent = m_ui->checkBoxPersistent->isChecked(); + m_object.events = std::move(m_events); QDialog::accept(); } @@ -157,7 +159,17 @@ void ObjectPropertiesDialog::showInformation() void ObjectPropertiesDialog::addEvent() { - QMessageBox::warning(this, tr("Not yet implemented"), tr("Not yet implemented")); + AddEventDialog dialog{this}; + if (dialog.exec() == QDialog::Accepted) + { + if (!m_events.contains(dialog.eventType())) + { + m_eventsModel->beginResetModel(); + m_events[dialog.eventType()]; + m_eventsModel->endResetModel(); + m_unsavedChanges = true; + } + } } void ObjectPropertiesDialog::deleteEvent() diff --git a/dialogs/objectpropertiesdialog.h b/dialogs/objectpropertiesdialog.h index 0404614..22dfde4 100644 --- a/dialogs/objectpropertiesdialog.h +++ b/dialogs/objectpropertiesdialog.h @@ -3,14 +3,15 @@ #include #include +#include + +#include "projectcontainer.h" class QMenu; namespace Ui { class ObjectPropertiesDialog; } -struct Object; class ProjectTreeModel; class ObjectEventsModel; class ObjectActionsModel; -class Sprite; class ObjectPropertiesDialog : public QDialog { @@ -48,6 +49,8 @@ private: Object &m_object; ProjectTreeModel &m_projectModel; + std::map m_events; + const std::unique_ptr m_eventsModel; const std::unique_ptr m_actionsModel; diff --git a/dialogs/objectpropertiesdialog.ui b/dialogs/objectpropertiesdialog.ui index 8fc8052..20a6258 100644 --- a/dialogs/objectpropertiesdialog.ui +++ b/dialogs/objectpropertiesdialog.ui @@ -25,7 +25,7 @@ - Name: + &Name: lineEditName diff --git a/dialogs/pathpropertiesdialog.ui b/dialogs/pathpropertiesdialog.ui index 71da15e..ec4acd4 100644 --- a/dialogs/pathpropertiesdialog.ui +++ b/dialogs/pathpropertiesdialog.ui @@ -114,18 +114,18 @@ 10 - - + + - Name: + &Name: lineEditName - + The name of the path @@ -189,7 +189,7 @@ - X: + &X: spinBoxX @@ -209,7 +209,7 @@ - Y: + &Y: spinBoxY @@ -229,7 +229,7 @@ - sp: + s&p: spinBoxSp @@ -269,7 +269,7 @@ Add the point to the path - Add + &Add @@ -279,7 +279,7 @@ Insert the point before the current one - Insert + &Insert @@ -289,7 +289,7 @@ Delete the point from the path - Delete + &Delete @@ -329,14 +329,14 @@ - Straight lines + &Straight lines - Smooth curves + S&mooth curves @@ -348,7 +348,7 @@ - Precision: + P&recision: spinBoxPrecision diff --git a/dialogs/scriptpropertiesdialog.cpp b/dialogs/scriptpropertiesdialog.cpp index 908bd84..041313f 100644 --- a/dialogs/scriptpropertiesdialog.cpp +++ b/dialogs/scriptpropertiesdialog.cpp @@ -16,7 +16,7 @@ ScriptPropertiesDialog::ScriptPropertiesDialog(Script &script, ProjectTreeModel m_lineEditName{new QLineEdit{this}} { { - auto label = new QLabel{tr("Name:"), this}; + auto label = new QLabel{tr("&Name:"), this}; label->setBuddy(m_lineEditName); addToolbarWidget(label); } diff --git a/dialogs/soundpropertiesdialog.ui b/dialogs/soundpropertiesdialog.ui index dd47047..847ba71 100644 --- a/dialogs/soundpropertiesdialog.ui +++ b/dialogs/soundpropertiesdialog.ui @@ -23,7 +23,7 @@ - Name: + &Name: lineEditName diff --git a/dialogs/spritepropertiesdialog.ui b/dialogs/spritepropertiesdialog.ui index cdbf7e0..4f8308f 100644 --- a/dialogs/spritepropertiesdialog.ui +++ b/dialogs/spritepropertiesdialog.ui @@ -25,7 +25,7 @@ - Name: + &Name: lineEditName @@ -153,7 +153,7 @@ - X: + &X: Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter @@ -173,7 +173,7 @@ - Y: + &Y: Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter diff --git a/dialogs/timelinepropertiesdialog.ui b/dialogs/timelinepropertiesdialog.ui index c601bd9..b42bce0 100644 --- a/dialogs/timelinepropertiesdialog.ui +++ b/dialogs/timelinepropertiesdialog.ui @@ -23,7 +23,7 @@ - Name: + &Name: lineEditName diff --git a/icons/event-create.png b/icons/event-create.png new file mode 100644 index 0000000..bf82634 Binary files /dev/null and b/icons/event-create.png differ diff --git a/icons/event-destroy.png b/icons/event-destroy.png new file mode 100644 index 0000000..7f3298c Binary files /dev/null and b/icons/event-destroy.png differ diff --git a/icons/event-step.png b/icons/event-step.png new file mode 100644 index 0000000..216db22 Binary files /dev/null and b/icons/event-step.png differ diff --git a/objecteventsmodel.cpp b/objecteventsmodel.cpp index 9e2883a..a683562 100644 --- a/objecteventsmodel.cpp +++ b/objecteventsmodel.cpp @@ -1,19 +1,58 @@ #include "objecteventsmodel.h" -ObjectEventsModel::ObjectEventsModel(QObject *parent) : - QAbstractListModel{parent} +#include +#include + +#include "futurecpp.h" + +ObjectEventsModel::ObjectEventsModel(std::map &events, QObject *parent) : + QAbstractListModel{parent}, + m_events{events} { } int ObjectEventsModel::rowCount(const QModelIndex &parent) const { Q_UNUSED(parent) - return 0; + return m_events.size(); } QVariant ObjectEventsModel::data(const QModelIndex &index, int role) const { Q_UNUSED(index) - Q_UNUSED(role) + + if (index.row() < 0 || index.row() >= m_events.size()) + { + qWarning() << "row out of bounds" << index.row(); + return {}; + } + + const auto &pair = *std::next(std::cbegin(m_events), index.row()); + + switch (role) + { + case Qt::DisplayRole: + case Qt::EditRole: + switch (pair.first) + { + case Object::EventType::Create: return tr("Create"); + case Object::EventType::Step: return tr("Step"); + case Object::EventType::Destroy: return tr("Destroy"); + default: + qWarning() << "unknown event type" << std::to_underlying(pair.first); + return QString::number(std::to_underlying(pair.first)); + } + case Qt::DecorationRole: + switch (pair.first) + { + case Object::EventType::Create: return QIcon{":/qtgameengine/icons/event-create.png"}; + case Object::EventType::Step: return QIcon{":/qtgameengine/icons/event-step.png"}; + case Object::EventType::Destroy: return QIcon{":/qtgameengine/icons/event-destroy.png"}; + default: + qWarning() << "unknown event type" << std::to_underlying(pair.first); + return {}; + } + } + return {}; } diff --git a/objecteventsmodel.h b/objecteventsmodel.h index 1b44325..55cc1e4 100644 --- a/objecteventsmodel.h +++ b/objecteventsmodel.h @@ -2,13 +2,23 @@ #include +#include + +#include "projectcontainer.h" + class ObjectEventsModel : public QAbstractListModel { Q_OBJECT public: - explicit ObjectEventsModel(QObject *parent = nullptr); + explicit ObjectEventsModel(std::map &events, QObject *parent = nullptr); int rowCount(const QModelIndex &parent) const override; QVariant data(const QModelIndex &index, int role) const override; + + using QAbstractListModel::beginResetModel; + using QAbstractListModel::endResetModel; + +private: + std::map &m_events; }; diff --git a/projectcontainer.cpp b/projectcontainer.cpp index f75ed9a..1eb12aa 100644 --- a/projectcontainer.cpp +++ b/projectcontainer.cpp @@ -73,135 +73,164 @@ QDataStream &operator>>(QDataStream &ds, std::vector &list) return ds; } +template +QDataStream &operator<<(QDataStream &ds, const std::map &map) +{ + { + int entries = map.size(); + ds << entries; + } + for (auto iter = std::cbegin(map); iter != std::cend(map); iter++) + ds << iter->first << iter->second; + return ds; +} + +template +QDataStream &operator>>(QDataStream &ds, std::map &map) +{ + int entries; + ds >> entries; + + for (int i = 0; i < entries; i++) + { + Tkey key; + Tvalue value; + ds >> key + >> value; + map[std::move(key)] = std::move(value); + } + return ds; +} + QDataStream &operator<<(QDataStream &ds, const Sprite &sprite) { - ds << sprite.name; - ds << sprite.pixmaps; - ds << sprite.origin.x; - ds << sprite.origin.y; - ds << sprite.preciseCollisionChecking; - ds << sprite.separateCollisionMasks; + ds << sprite.name + << sprite.pixmaps + << sprite.origin.x + << sprite.origin.y + << sprite.preciseCollisionChecking + << sprite.separateCollisionMasks; return ds; } QDataStream &operator>>(QDataStream &ds, Sprite &sprite) { - ds >> sprite.name; - ds >> sprite.pixmaps; - ds >> sprite.origin.x; - ds >> sprite.origin.y; - ds >> sprite.preciseCollisionChecking; - ds >> sprite.separateCollisionMasks; + ds >> sprite.name + >> sprite.pixmaps + >> sprite.origin.x + >> sprite.origin.y + >> sprite.preciseCollisionChecking + >> sprite.separateCollisionMasks; return ds; } QDataStream &operator<<(QDataStream &ds, const Sound &sound) { - ds << sound.name; - ds << sound.type; - ds << sound.path; - ds << sound.effects.chorus; - ds << sound.effects.flanger; - ds << sound.effects.gargle; - ds << sound.effects.echo; - ds << sound.effects.reverb; - ds << sound.volume; - ds << sound.pan; - ds << sound.preload; + ds << sound.name + << sound.type + << sound.path + << sound.effects.chorus + << sound.effects.flanger + << sound.effects.gargle + << sound.effects.echo + << sound.effects.reverb + << sound.volume + << sound.pan + << sound.preload; return ds; } QDataStream &operator>>(QDataStream &ds, Sound &sound) { - ds >> sound.name; - ds >> sound.type; - ds >> sound.path; - ds >> sound.effects.chorus; - ds >> sound.effects.flanger; - ds >> sound.effects.gargle; - ds >> sound.effects.echo; - ds >> sound.effects.reverb; - ds >> sound.volume; - ds >> sound.pan; - ds >> sound.preload; + ds >> sound.name + >> sound.type + >> sound.path + >> sound.effects.chorus + >> sound.effects.flanger + >> sound.effects.gargle + >> sound.effects.echo + >> sound.effects.reverb + >> sound.volume + >> sound.pan + >> sound.preload; return ds; } QDataStream &operator<<(QDataStream &ds, const Background &background) { - ds << background.name; - ds << background.pixmap; - ds << background.tileset; + ds << background.name + << background.pixmap + << background.tileset; return ds; } QDataStream &operator>>(QDataStream &ds, Background &background) { - ds >> background.name; - ds >> background.pixmap; - ds >> background.tileset; + ds >> background.name + >> background.pixmap + >> background.tileset; return ds; } QDataStream &operator<<(QDataStream &ds, const Path::Point &point) { - ds << point.point; - ds << point.sp; + ds << point.point + << point.sp; return ds; } QDataStream &operator>>(QDataStream &ds, Path::Point &point) { - ds >> point.point; - ds >> point.sp; + ds >> point.point + >> point.sp; return ds; } QDataStream &operator<<(QDataStream &ds, const Path &path) { - ds << path.name; - ds << path.points; - ds << path.type; - ds << path.closed; - ds << path.precision; + ds << path.name + << path.points + << path.type + << path.closed + << path.precision; return ds; } QDataStream &operator>>(QDataStream &ds, Path &path) { - ds >> path.name; - ds >> path.points; - ds >> path.type; - ds >> path.closed; - ds >> path.precision; + ds >> path.name + >> path.points + >> path.type + >> path.closed + >> path.precision; return ds; } QDataStream &operator<<(QDataStream &ds, const Script &script) { - ds << script.name; - ds << script.script; + ds << script.name + << script.script; return ds; } QDataStream &operator>>(QDataStream &ds, Script &script) { - ds >> script.name; - ds >> script.script; + ds >> script.name + >> script.script; return ds; } QDataStream &operator<<(QDataStream &ds, const Font &font) { - ds << font.name; - ds << font.font; + ds << font.name + << font.font; return ds; } QDataStream &operator>>(QDataStream &ds, Font &font) { - ds >> font.name; - ds >> font.font; + ds >> font.name + >> font.font; return ds; } @@ -219,23 +248,25 @@ QDataStream &operator>>(QDataStream &ds, TimeLine &timeLine) QDataStream &operator<<(QDataStream &ds, const Object &object) { - ds << object.name; - ds << object.spriteName; - ds << object.visible; - ds << object.solid; - ds << object.depth; - ds << object.persistent; + ds << object.name + << object.spriteName + << object.visible + << object.solid + << object.depth + << object.persistent + << object.events; return ds; } QDataStream &operator>>(QDataStream &ds, Object &object) { - ds >> object.name; - ds >> object.spriteName; - ds >> object.visible; - ds >> object.solid; - ds >> object.depth; - ds >> object.persistent; + ds >> object.name + >> object.spriteName + >> object.visible + >> object.solid + >> object.depth + >> object.persistent + >> object.events; return ds; } @@ -253,29 +284,29 @@ QDataStream &operator>>(QDataStream &ds, Room &room) QDataStream &operator<<(QDataStream &ds, const ProjectContainer &project) { - ds << project.sprites; - ds << project.sounds; - ds << project.backgrounds; - ds << project.paths; - ds << project.scripts; - ds << project.fonts; - ds << project.timeLines; - ds << project.objects; - ds << project.rooms; + ds << project.sprites + << project.sounds + << project.backgrounds + << project.paths + << project.scripts + << project.fonts + << project.timeLines + << project.objects + << project.rooms; return ds; } QDataStream &operator>>(QDataStream &ds, ProjectContainer &project) { - ds >> project.sprites; - ds >> project.sounds; - ds >> project.backgrounds; - ds >> project.paths; - ds >> project.scripts; - ds >> project.fonts; - ds >> project.timeLines; - ds >> project.objects; - ds >> project.rooms; + ds >> project.sprites + >> project.sounds + >> project.backgrounds + >> project.paths + >> project.scripts + >> project.fonts + >> project.timeLines + >> project.objects + >> project.rooms; return ds; } diff --git a/projectcontainer.h b/projectcontainer.h index 13dcd62..d5df0e7 100644 --- a/projectcontainer.h +++ b/projectcontainer.h @@ -84,12 +84,19 @@ struct TimeLine struct Object { + enum class EventType { + Create, + Step, + Destroy + }; + QString name; QString spriteName; bool visible{true}; bool solid{}; int depth{}; bool persistent{}; + std::map events; }; struct Room diff --git a/resources.qrc b/resources.qrc index a9bb71d..ae337a1 100644 --- a/resources.qrc +++ b/resources.qrc @@ -76,5 +76,8 @@ icons/info.png icons/merge.png icons/sort.png + icons/event-create.png + icons/event-destroy.png + icons/event-step.png