Implement Esc key, confirmation on new action, and del key shortcut on actions
This commit is contained in:
1 parent
f6fc000287
commit
516d030c3c
13 files changed
+103
-82
No files matched your search
@@ -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 \
|
||||
|
||||
@@ -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{};
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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();
|
||||
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -23,7 +23,6 @@ public:
|
||||
|
||||
protected:
|
||||
bool event(QEvent *event) override;
|
||||
void keyPressEvent(QKeyEvent *event) override;
|
||||
void exposeEvent(QExposeEvent *event) override;
|
||||
|
||||
private:
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
@@ -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;
|
||||
|
||||
Reference in new issue
Block a user