Implement Esc key, confirmation on new action, and del key shortcut on actions

This commit is contained in:
feedc0de committed 2026-11-14 16:43:13 +01:00
1 parent f6fc000287
commit 516d030c3c
13 files changed
+103 -82

No files matched your search

+1
View File
@@ -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 \
+3
View File
@@ -0,0 +1,3 @@
#pragma once
inline constexpr char newActionMimeType[] = "application/x-qtgamemaker-new-action";
@@ -6,6 +6,7 @@
#include <QDebug>
#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();
}
@@ -1,9 +1,13 @@
#include "actionscontainermodel.h"
#include <algorithm>
#include <QDebug>
#include <QIcon>
#include <QMimeData>
#include <QTimer>
#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();
@@ -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{};
+2
View File
@@ -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);
+48 -52
View File
@@ -5,6 +5,9 @@
#include <QMessageBox>
#include <QMenu>
#include <QKeySequence>
#include <QShortcut>
#include <type_traits>
#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<MoveFixedAction>(action))
if (editAction(*action))
emit changed();
}
bool ActionsContainerWidget::editAction(Action &action)
{
return std::visit([this](auto &value) {
using T = std::decay_t<decltype(value)>;
ActionDialogFor<T> 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<MoveFreeAction>(action))
{
MoveFreeDialog dialog{*ptr, m_projectModel, this};
if (dialog.exec() == QDialog::Accepted)
emit changed();
}
else if (auto ptr = std::get_if<MoveTowardsAction>(action))
{
MoveTowardsDialog dialog{*ptr, m_projectModel, this};
if (dialog.exec() == QDialog::Accepted)
emit changed();
}
else if (auto ptr = std::get_if<SpeedHorizontalAction>(action))
{
SpeedHorizontalDialog dialog{*ptr, m_projectModel, this};
if (dialog.exec() == QDialog::Accepted)
emit changed();
}
else if (auto ptr = std::get_if<SpeedVerticalAction>(action))
{
SpeedVerticalDialog dialog{*ptr, m_projectModel, this};
if (dialog.exec() == QDialog::Accepted)
emit changed();
}
else if (auto ptr = std::get_if<SetGravityAction>(action))
{
SetGravityDialog dialog{*ptr, m_projectModel, this};
if (dialog.exec() == QDialog::Accepted)
emit changed();
}
else if (auto ptr = std::get_if<ExecuteCodeAction>(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<T> dialog{action, m_projectModel, this};
if (dialog.exec() == QDialog::Accepted)
Action action = T{};
if (editAction(action))
m_actionsModel->appendAction(std::move(action));
}
@@ -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<typename T>
void createNewAction();
+9
View File
@@ -4,6 +4,7 @@
#include <QEventLoop>
#include <QEnterEvent>
#include <QKeyEvent>
#include <QMouseEvent>
#include <QWheelEvent>
@@ -59,6 +60,14 @@ bool GameEngine::eventFilter(QObject *watched, QEvent *event)
switch (event->type())
{
case QEvent::KeyPress:
if (static_cast<QKeyEvent *>(event)->key() == Qt::Key_Escape &&
m_project.globalGameSettings.letEscEndGame)
{
window->close();
return true;
}
break;
case QEvent::FocusIn:
if (m_mouseSource != window)
{
-9
View File
@@ -3,7 +3,6 @@
#include <array>
#include <cstddef>
#include <QKeyEvent>
#include <QMatrix4x4>
#include <QOpenGLContext>
#include <QOpenGLShaderProgram>
@@ -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);
-1
View File
@@ -23,7 +23,6 @@ public:
protected:
bool event(QEvent *event) override;
void keyPressEvent(QKeyEvent *event) override;
void exposeEvent(QExposeEvent *event) override;
private:
-15
View File
@@ -1,7 +1,5 @@
#include "vulkangamewindow.h"
#include <QKeyEvent>
#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);
}
-4
View File
@@ -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;