diff --git a/QtGameMaker.pro b/QtGameMaker.pro index 6f80973..7aea98a 100644 --- a/QtGameMaker.pro +++ b/QtGameMaker.pro @@ -26,6 +26,7 @@ INCLUDEPATH += \ HEADERS += \ src/closeeventfilter.h \ + src/editor/actionmimetypes.h \ src/editor/dialogs/actions/actiondialogutils.h \ src/editor/dialogs/actions/setgravitydialog.h \ src/editor/dialogs/actions/speedhorizontaldialog.h \ diff --git a/src/editor/actionmimetypes.h b/src/editor/actionmimetypes.h new file mode 100644 index 0000000..18f07a3 --- /dev/null +++ b/src/editor/actionmimetypes.h @@ -0,0 +1,3 @@ +#pragma once + +inline constexpr char newActionMimeType[] = "application/x-qtgamemaker-new-action"; diff --git a/src/editor/dialogs/globalgamesettingsdialog.cpp b/src/editor/dialogs/globalgamesettingsdialog.cpp index af3d539..b08b430 100644 --- a/src/editor/dialogs/globalgamesettingsdialog.cpp +++ b/src/editor/dialogs/globalgamesettingsdialog.cpp @@ -6,6 +6,7 @@ #include #include "editorguiutils.h" +#include "projectcontainer.h" GlobalGameSettingsDialog::GlobalGameSettingsDialog(GlobalGameSettings &globalGameSettings, QWidget *parent) : QDialog{parent}, @@ -13,6 +14,7 @@ GlobalGameSettingsDialog::GlobalGameSettingsDialog(GlobalGameSettings &globalGam m_globalGameSettings{globalGameSettings} { m_ui->setupUi(this); + m_ui->checkBoxEscEndGame->setChecked(m_globalGameSettings.letEscEndGame); #ifdef Q_OS_LINUX setWindowFlags((windowFlags() & ~Qt::Dialog) | Qt::Window); @@ -31,6 +33,9 @@ GlobalGameSettingsDialog::GlobalGameSettingsDialog(GlobalGameSettings &globalGam improveButtonBox(m_ui->buttonBox); + connect(m_ui->checkBoxEscEndGame, &QCheckBox::toggled, + this, &GlobalGameSettingsDialog::changed); + connect(m_ui->checkBoxFullscreen, &QCheckBox::toggled, this, &GlobalGameSettingsDialog::changed); connect(m_ui->radioButtonFixedScale, &QCheckBox::toggled, @@ -68,7 +73,7 @@ void GlobalGameSettingsDialog::accept() return; } - // TODO + m_globalGameSettings.letEscEndGame = m_ui->checkBoxEscEndGame->isChecked(); QDialog::accept(); } diff --git a/src/editor/models/actionscontainermodel.cpp b/src/editor/models/actionscontainermodel.cpp index 384bfad..0255de4 100644 --- a/src/editor/models/actionscontainermodel.cpp +++ b/src/editor/models/actionscontainermodel.cpp @@ -1,9 +1,13 @@ #include "actionscontainermodel.h" +#include + #include #include #include +#include +#include "actionmimetypes.h" #include "projectserialization.h" #include "stdserialization.h" @@ -211,6 +215,17 @@ bool ActionsContainerModel::dropMimeData(const QMimeData *data, Qt::DropAction a return false; } + if (data->hasFormat(newActionMimeType)) + { + if (actions.size() != 1 || action != Qt::CopyAction) + return false; + Action freshAction = std::move(actions.front()); + QTimer::singleShot(0, this, [this, freshAction = std::move(freshAction), row]() mutable { + emit newActionDropped(std::move(freshAction), row); + }); + return true; + } + beginInsertRows({}, row, row + actions.size() - 1); auto iter = std::next(std::begin(*m_actionsContainer), row); for (auto &action : actions) @@ -223,6 +238,20 @@ bool ActionsContainerModel::dropMimeData(const QMimeData *data, Qt::DropAction a return true; } +void ActionsContainerModel::insertAction(int row, Action action) +{ + if (!m_actionsContainer) + { + emit actionsContainerMissing(); + return; + } + row = std::clamp(row, 0, int(m_actionsContainer->size())); + beginInsertRows({}, row, row); + m_actionsContainer->insert(std::next(m_actionsContainer->begin(), row), std::move(action)); + endInsertRows(); + emit changed(); +} + bool ActionsContainerModel::removeRows(int row, int count, const QModelIndex &parent) { qDebug() << row << count << parent.isValid(); diff --git a/src/editor/models/actionscontainermodel.h b/src/editor/models/actionscontainermodel.h index 27696fe..954124f 100644 --- a/src/editor/models/actionscontainermodel.h +++ b/src/editor/models/actionscontainermodel.h @@ -39,10 +39,12 @@ public: void appendAction(Action &&action); void appendAction(const Action &action); + void insertAction(int row, Action action); signals: void changed(); void actionsContainerMissing(); + void newActionDropped(Action action, int row); private: ActionsContainer *m_actionsContainer{}; diff --git a/src/editor/widgets/actiondragwidget.cpp b/src/editor/widgets/actiondragwidget.cpp index 2a3e4ec..7689199 100644 --- a/src/editor/widgets/actiondragwidget.cpp +++ b/src/editor/widgets/actiondragwidget.cpp @@ -9,6 +9,7 @@ #include "projectserialization.h" #include "stdserialization.h" +#include "actionmimetypes.h" void ActionDragWidget::mousePressEvent(QMouseEvent *event) { @@ -37,6 +38,7 @@ void ActionDragWidget::mouseMoveEvent(QMouseEvent *event) QDataStream stream(&encoded, QIODevice::WriteOnly); stream << m_action; mimeData->setData("custom", encoded); + mimeData->setData(newActionMimeType, {}); drag->setMimeData(mimeData); Qt::DropAction dropAction = drag->exec(Qt::CopyAction); diff --git a/src/editor/widgets/actionscontainerwidget.cpp b/src/editor/widgets/actionscontainerwidget.cpp index 9e6ba7e..4bcffff 100644 --- a/src/editor/widgets/actionscontainerwidget.cpp +++ b/src/editor/widgets/actionscontainerwidget.cpp @@ -5,6 +5,9 @@ #include #include #include +#include + +#include #include "models/actionscontainermodel.h" #include "dialogs/actions/movefixeddialog.h" @@ -42,12 +45,21 @@ ActionsContainerWidget::ActionsContainerWidget(QWidget *parent) : connect(m_actionsModel.get(), &ActionsContainerModel::actionsContainerMissing, this, &ActionsContainerWidget::actionsContainerMissing); + connect(m_actionsModel.get(), &ActionsContainerModel::newActionDropped, + this, &ActionsContainerWidget::newActionDropped); + connect(m_ui->listViewActions, &QListView::customContextMenuRequested, this, &ActionsContainerWidget::actionsContextMenuRequested); connect(m_ui->listViewActions, &QListView::doubleClicked, this, &ActionsContainerWidget::actionDoubleClicked); + auto *deleteShortcut = new QShortcut{QKeySequence::Delete, m_ui->listViewActions}; + deleteShortcut->setContext(Qt::WidgetWithChildrenShortcut); + connect(deleteShortcut, &QShortcut::activated, this, [this]() { + deleteAction(m_ui->listViewActions->currentIndex()); + }); + connect(m_actionsModel.get(), &QAbstractItemModel::modelAboutToBeReset, m_ui->listViewActions, [listView=m_ui->listViewActions](){ listView->setCurrentIndex(QModelIndex{}); @@ -103,75 +115,61 @@ void ActionsContainerWidget::actionDoubleClicked(const QModelIndex &index) if (!action) return; - if (auto ptr = std::get_if(action)) + if (editAction(*action)) + emit changed(); +} + +bool ActionsContainerWidget::editAction(Action &action) +{ + return std::visit([this](auto &value) { + using T = std::decay_t; + ActionDialogFor dialog{value, m_projectModel, this}; + return dialog.exec() == QDialog::Accepted; + }, action); +} + +void ActionsContainerWidget::newActionDropped(Action action, int row) +{ + if (!m_actionsModel->actionsContainer()) { - MoveFixedDialog dialog{*ptr, m_projectModel, this}; - if (dialog.exec() == QDialog::Accepted) - emit changed(); + actionsContainerMissing(); + return; } - else if (auto ptr = std::get_if(action)) - { - MoveFreeDialog dialog{*ptr, m_projectModel, this}; - if (dialog.exec() == QDialog::Accepted) - emit changed(); - } - else if (auto ptr = std::get_if(action)) - { - MoveTowardsDialog dialog{*ptr, m_projectModel, this}; - if (dialog.exec() == QDialog::Accepted) - emit changed(); - } - else if (auto ptr = std::get_if(action)) - { - SpeedHorizontalDialog dialog{*ptr, m_projectModel, this}; - if (dialog.exec() == QDialog::Accepted) - emit changed(); - } - else if (auto ptr = std::get_if(action)) - { - SpeedVerticalDialog dialog{*ptr, m_projectModel, this}; - if (dialog.exec() == QDialog::Accepted) - emit changed(); - } - else if (auto ptr = std::get_if(action)) - { - SetGravityDialog dialog{*ptr, m_projectModel, this}; - if (dialog.exec() == QDialog::Accepted) - emit changed(); - } - else if (auto ptr = std::get_if(action)) - { - ExecuteCodeDialog dialog{*ptr, m_projectModel, this}; - if (dialog.exec() == QDialog::Accepted) - emit changed(); - } - else - QMessageBox::information(this, tr("Not implemented!"), tr("Not implemented!")); + if (editAction(action)) + m_actionsModel->insertAction(row, std::move(action)); +} + +void ActionsContainerWidget::deleteAction(const QModelIndex &index) +{ + if (!index.isValid() || !m_actionsModel->actionsContainer()) + return; + if (!m_actionsModel->removeRow(index.row())) + QMessageBox::warning(this, tr("Could not remove action!"), tr("Could not remove action!")); } void ActionsContainerWidget::actionsContextMenuRequested(const QPoint &pos) { const auto index = m_ui->listViewActions->indexAt(pos); - auto action = index.isValid() ? m_actionsModel->getAction(index) : nullptr; + auto *selectedAction = index.isValid() ? m_actionsModel->getAction(index) : nullptr; QMenu menu{this}; if (auto action = menu.addAction(tr("&Edit Values"), this, [this,index](){ actionDoubleClicked(index); })) - action->setEnabled(action); + action->setEnabled(selectedAction != nullptr); menu.addSeparator(); if (auto action = menu.addAction(tr("C&ut"), this, [this](){ QMessageBox::information(this, tr("Not implemented!"), tr("Not implemented!")); })) { - action->setEnabled(action); + action->setEnabled(selectedAction != nullptr); action->setShortcut(QKeySequence::Cut); } if (auto action = menu.addAction(tr("&Copy"), this, [this](){ QMessageBox::information(this, tr("Not implemented!"), tr("Not implemented!")); })) { - action->setEnabled(action); + action->setEnabled(selectedAction != nullptr); action->setShortcut(QKeySequence::Copy); } if (auto action = menu.addAction(tr("&Paste"), this, [this](){ @@ -183,11 +181,10 @@ void ActionsContainerWidget::actionsContextMenuRequested(const QPoint &pos) } menu.addSeparator(); if (auto action = menu.addAction(tr("&Delete"), this, [this,index](){ - if (!m_actionsModel->removeRow(index.row())) - QMessageBox::warning(this, tr("Could not remove action!"), tr("Could not remove action!")); + deleteAction(index); })) { - action->setEnabled(action); + action->setEnabled(selectedAction != nullptr); action->setShortcut(QKeySequence::Delete); } menu.addSeparator(); @@ -220,8 +217,7 @@ void ActionsContainerWidget::createNewAction() if (!m_actionsModel->actionsContainer()) return; - T action; - ActionDialogFor dialog{action, m_projectModel, this}; - if (dialog.exec() == QDialog::Accepted) + Action action = T{}; + if (editAction(action)) m_actionsModel->appendAction(std::move(action)); } diff --git a/src/editor/widgets/actionscontainerwidget.h b/src/editor/widgets/actionscontainerwidget.h index a2a1b4d..9934501 100644 --- a/src/editor/widgets/actionscontainerwidget.h +++ b/src/editor/widgets/actionscontainerwidget.h @@ -31,10 +31,13 @@ signals: private slots: void actionDoubleClicked(const QModelIndex &index); + void newActionDropped(Action action, int row); void actionsContextMenuRequested(const QPoint &pos); void actionsContainerMissing(); private: + bool editAction(Action &action); + void deleteAction(const QModelIndex &index); template void createNewAction(); diff --git a/src/engine/gameengine.cpp b/src/engine/gameengine.cpp index 778db73..5b8af9a 100644 --- a/src/engine/gameengine.cpp +++ b/src/engine/gameengine.cpp @@ -4,6 +4,7 @@ #include #include +#include #include #include @@ -59,6 +60,14 @@ bool GameEngine::eventFilter(QObject *watched, QEvent *event) switch (event->type()) { + case QEvent::KeyPress: + if (static_cast(event)->key() == Qt::Key_Escape && + m_project.globalGameSettings.letEscEndGame) + { + window->close(); + return true; + } + break; case QEvent::FocusIn: if (m_mouseSource != window) { diff --git a/src/engine/glgamewindow.cpp b/src/engine/glgamewindow.cpp index 866d5c9..685f89e 100644 --- a/src/engine/glgamewindow.cpp +++ b/src/engine/glgamewindow.cpp @@ -3,7 +3,6 @@ #include #include -#include #include #include #include @@ -217,14 +216,6 @@ bool GlGameWindow::event(QEvent *event) return QWindow::event(event); } -void GlGameWindow::keyPressEvent(QKeyEvent *event) -{ - if (event->key() == Qt::Key_Escape && m_project.globalGameSettings.letEscEndGame) - close(); - else - QWindow::keyPressEvent(event); -} - void GlGameWindow::exposeEvent(QExposeEvent *event) { QWindow::exposeEvent(event); diff --git a/src/engine/glgamewindow.h b/src/engine/glgamewindow.h index eb84635..c8d791a 100644 --- a/src/engine/glgamewindow.h +++ b/src/engine/glgamewindow.h @@ -23,7 +23,6 @@ public: protected: bool event(QEvent *event) override; - void keyPressEvent(QKeyEvent *event) override; void exposeEvent(QExposeEvent *event) override; private: diff --git a/src/engine/vulkangamewindow.cpp b/src/engine/vulkangamewindow.cpp index 71e2710..c6a483d 100644 --- a/src/engine/vulkangamewindow.cpp +++ b/src/engine/vulkangamewindow.cpp @@ -1,7 +1,5 @@ #include "vulkangamewindow.h" -#include - #include "projectcontainer.h" #include "gamescene.h" #include "vulkangamerenderer.h" @@ -28,16 +26,3 @@ QVulkanWindowRenderer *VulkanGameWindow::createRenderer() { return new VulkanGameRenderer{m_scene, this}; } - -void VulkanGameWindow::keyPressEvent(QKeyEvent *event) -{ - QVulkanWindow::keyPressEvent(event); - - if (event->key() == Qt::Key_Escape && m_project.globalGameSettings.letEscEndGame) - close(); -} - -void VulkanGameWindow::keyReleaseEvent(QKeyEvent *event) -{ - QVulkanWindow::keyReleaseEvent(event); -} diff --git a/src/engine/vulkangamewindow.h b/src/engine/vulkangamewindow.h index bd0117c..03df1cd 100644 --- a/src/engine/vulkangamewindow.h +++ b/src/engine/vulkangamewindow.h @@ -13,10 +13,6 @@ public: QVulkanWindowRenderer *createRenderer() override; -protected: - void keyPressEvent(QKeyEvent *event) override; - void keyReleaseEvent(QKeyEvent *event) override; - private: const ProjectContainer &m_project; const GameScene &m_scene;