diff --git a/QtGameMaker.pro b/QtGameMaker.pro index 018f224..9090134 100644 --- a/QtGameMaker.pro +++ b/QtGameMaker.pro @@ -26,6 +26,7 @@ INCLUDEPATH += \ HEADERS += \ src/closeeventfilter.h \ + src/editor/dialogs/actions/setgravitydialog.h \ src/editor/dialogs/actions/speedhorizontaldialog.h \ src/editor/dialogs/actions/movefreedialog.h \ src/editor/dialogs/actions/movetowardsdialog.h \ @@ -38,6 +39,8 @@ HEADERS += \ src/editor/roomscene.h \ src/editor/widgets/actiondragwidget.h \ src/editor/widgets/draggabletreeview.h \ + src/editor/widgets/objectparentselectorwidget.h \ + src/editor/widgets/objectselectorwidget.h \ src/editor/widgets/qlineeditwithmenu.h \ src/editor/widgets/qscrollareawithmenu.h \ src/editor/widgets/roomeditwidget.h \ @@ -94,6 +97,7 @@ HEADERS += \ SOURCES += \ src/closeeventfilter.cpp \ src/editor/dialogs/actions/executecodedialog.cpp \ + src/editor/dialogs/actions/setgravitydialog.cpp \ src/editor/dialogs/actions/speedhorizontaldialog.cpp \ src/editor/dialogs/actions/movefreedialog.cpp \ src/editor/dialogs/actions/movetowardsdialog.cpp \ @@ -105,6 +109,8 @@ SOURCES += \ src/editor/roomscene.cpp \ src/editor/widgets/actiondragwidget.cpp \ src/editor/widgets/draggabletreeview.cpp \ + src/editor/widgets/objectparentselectorwidget.cpp \ + src/editor/widgets/objectselectorwidget.cpp \ src/editor/widgets/qlineeditwithmenu.cpp \ src/editor/widgets/qscrollareawithmenu.cpp \ src/editor/widgets/roomeditwidget.cpp \ @@ -158,6 +164,7 @@ SOURCES += \ src/projectserialization.cpp FORMS += \ + src/editor/dialogs/actions/setgravitydialog.ui \ src/editor/dialogs/actions/speedhorizontaldialog.ui \ src/editor/dialogs/actions/movefreedialog.ui \ src/editor/dialogs/actions/movetowardsdialog.ui \ @@ -190,7 +197,8 @@ FORMS += \ src/editor/dialogs/triggersdialog.ui \ src/editor/dialogs/userdefinedconstantsdialog.ui \ src/editor/widgets/actionscontainerwidget.ui\ - src/editor/dialogs/actions/movefixeddialog.ui + src/editor/dialogs/actions/movefixeddialog.ui \ + src/editor/widgets/objectselectorwidget.ui RESOURCES += \ src/editor/resources_editor.qrc \ diff --git a/src/editor/dialogs/actions/executecodedialog.cpp b/src/editor/dialogs/actions/executecodedialog.cpp index 1666e72..47153ba 100644 --- a/src/editor/dialogs/actions/executecodedialog.cpp +++ b/src/editor/dialogs/actions/executecodedialog.cpp @@ -1,31 +1,54 @@ #include "executecodedialog.h" #include +#include #include #include #include "projectcontainer.h" +#include "widgets/objectselectorwidget.h" -ExecuteCodeDialog::ExecuteCodeDialog(ExecuteCodeAction &action, QWidget *parent) : +ExecuteCodeDialog::ExecuteCodeDialog(ExecuteCodeAction &action, ProjectTreeModel *projectModel, QWidget *parent) : CodeEditorDialog{tr("Execute Code"), parent}, m_action{action}, m_radioButtonSelf{new QRadioButton{tr("Self"), this}}, m_radioButtonOther{new QRadioButton{tr("Other"), this}}, - m_radioButtonObject{new QRadioButton{tr("Object"), this}} + m_radioButtonObject{new QRadioButton{tr("Object"), this}}, + m_objectSelector{new ObjectSelectorWidget{this}} { #ifdef Q_OS_LINUX setWindowFlags((windowFlags() & ~Qt::Dialog) | Qt::Window); #endif setWindowFlag(Qt::WindowCloseButtonHint); + m_objectSelector->setProjectModel(projectModel); + + m_objectSelector->setEmptySelectionText(tr("self")); + m_objectSelector->setShowClearObjectAction(false); + addToolbarWidget(new QLabel{tr("Applies to:"), this}); addToolbarWidget(m_radioButtonSelf); addToolbarWidget(m_radioButtonOther); addToolbarWidget(m_radioButtonObject); + auto action_ = addToolbarWidget(m_objectSelector); - m_radioButtonSelf->setChecked(m_action.appliesTo == ExecuteCodeAction::AppliesTo::Self); - m_radioButtonOther->setChecked(m_action.appliesTo == ExecuteCodeAction::AppliesTo::Other); - m_radioButtonObject->setChecked(m_action.appliesTo == ExecuteCodeAction::AppliesTo::Object); + connect(m_radioButtonObject, &QRadioButton::toggled, + m_objectSelector, &QWidget::setVisible); + connect(m_radioButtonObject, &QRadioButton::toggled, + action_, &QAction::setVisible); + + m_radioButtonSelf->setChecked(std::holds_alternative(m_action.appliesTo)); + m_radioButtonOther->setChecked(std::holds_alternative(m_action.appliesTo)); + { + auto ptr = std::get_if(&m_action.appliesTo); + m_radioButtonObject->setChecked(ptr != nullptr); + m_objectSelector->setVisible(ptr != nullptr); + action_->setVisible(ptr != nullptr); + if (ptr) + m_objectSelector->setObject(ptr->objectName); + else + m_objectSelector->clearObject(); + } setScript(m_action.script); @@ -46,11 +69,11 @@ void ExecuteCodeDialog::accept() } if (m_radioButtonSelf->isChecked()) - m_action.appliesTo = ExecuteCodeAction::AppliesTo::Self; + m_action.appliesTo = AppliesToSelf{}; else if (m_radioButtonOther->isChecked()) - m_action.appliesTo = ExecuteCodeAction::AppliesTo::Other; + m_action.appliesTo = AppliesToOther{}; else if (m_radioButtonObject->isChecked()) - m_action.appliesTo = ExecuteCodeAction::AppliesTo::Object; + m_action.appliesTo = AppliesToObject{ .objectName = m_objectSelector->objectName() }; else { QMessageBox::warning(this, tr("No Applies To selected!"), tr("No Applies To selected!")); diff --git a/src/editor/dialogs/actions/executecodedialog.h b/src/editor/dialogs/actions/executecodedialog.h index 61b817c..314a234 100644 --- a/src/editor/dialogs/actions/executecodedialog.h +++ b/src/editor/dialogs/actions/executecodedialog.h @@ -4,13 +4,15 @@ class QRadioButton; struct ExecuteCodeAction; +class ProjectTreeModel; +class ObjectSelectorWidget; class ExecuteCodeDialog : public CodeEditorDialog { Q_OBJECT public: - explicit ExecuteCodeDialog(ExecuteCodeAction &action, QWidget *parent = nullptr); + explicit ExecuteCodeDialog(ExecuteCodeAction &action, ProjectTreeModel *projectModel, QWidget *parent = nullptr); void accept() override; @@ -20,4 +22,6 @@ private: QRadioButton * const m_radioButtonSelf; QRadioButton * const m_radioButtonOther; QRadioButton * const m_radioButtonObject; + + ObjectSelectorWidget * const m_objectSelector; }; diff --git a/src/editor/dialogs/actions/movefixeddialog.cpp b/src/editor/dialogs/actions/movefixeddialog.cpp index 49c6e1e..6fb1c28 100644 --- a/src/editor/dialogs/actions/movefixeddialog.cpp +++ b/src/editor/dialogs/actions/movefixeddialog.cpp @@ -3,13 +3,23 @@ #include -MoveFixedDialog::MoveFixedDialog(MoveFixedAction &action, QWidget *parent) : +MoveFixedDialog::MoveFixedDialog(MoveFixedAction &action, ProjectTreeModel *projectModel, QWidget *parent) : QDialog{parent}, m_ui{std::make_unique()}, m_action{action} { m_ui->setupUi(this); + { + QSizePolicy sp_retain = m_ui->widgetObject->sizePolicy(); + sp_retain.setRetainSizeWhenHidden(true); + m_ui->widgetObject->setSizePolicy(sp_retain); + } + m_ui->widgetObject->setProjectModel(projectModel); + + m_ui->widgetObject->setEmptySelectionText(tr("self")); + m_ui->widgetObject->setShowClearObjectAction(false); + 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)) diff --git a/src/editor/dialogs/actions/movefixeddialog.h b/src/editor/dialogs/actions/movefixeddialog.h index 363c7a1..ddb55da 100644 --- a/src/editor/dialogs/actions/movefixeddialog.h +++ b/src/editor/dialogs/actions/movefixeddialog.h @@ -6,13 +6,14 @@ namespace Ui { class MoveFixedDialog; } class MoveFixedAction; +class ProjectTreeModel; class MoveFixedDialog : public QDialog { Q_OBJECT public: - explicit MoveFixedDialog(MoveFixedAction &action, QWidget *parent = nullptr); + explicit MoveFixedDialog(MoveFixedAction &action, ProjectTreeModel *projectModel, QWidget *parent = nullptr); ~MoveFixedDialog() override; private: diff --git a/src/editor/dialogs/actions/movefixeddialog.ui b/src/editor/dialogs/actions/movefixeddialog.ui index d3de655..a0e4a2a 100644 --- a/src/editor/dialogs/actions/movefixeddialog.ui +++ b/src/editor/dialogs/actions/movefixeddialog.ui @@ -50,7 +50,7 @@ - + @@ -59,12 +59,9 @@ - - - - - - ... + + + false @@ -285,6 +282,14 @@ + + + ObjectSelectorWidget + QWidget +
widgets/objectselectorwidget.h
+ 1 +
+
@@ -321,5 +326,21 @@ + + radioButtonObject + toggled(bool) + widgetObject + setVisible(bool) + + + 127 + 115 + + + 289 + 115 + + + diff --git a/src/editor/dialogs/actions/movefreedialog.cpp b/src/editor/dialogs/actions/movefreedialog.cpp index 1e252ff..cd53844 100644 --- a/src/editor/dialogs/actions/movefreedialog.cpp +++ b/src/editor/dialogs/actions/movefreedialog.cpp @@ -3,13 +3,23 @@ #include -MoveFreeDialog::MoveFreeDialog(MoveFreeAction &action, QWidget *parent) : +MoveFreeDialog::MoveFreeDialog(MoveFreeAction &action, ProjectTreeModel *projectModel, QWidget *parent) : QDialog{parent}, m_ui{std::make_unique()}, m_action{action} { m_ui->setupUi(this); + { + QSizePolicy sp_retain = m_ui->widgetObject->sizePolicy(); + sp_retain.setRetainSizeWhenHidden(true); + m_ui->widgetObject->setSizePolicy(sp_retain); + } + m_ui->widgetObject->setProjectModel(projectModel); + + m_ui->widgetObject->setEmptySelectionText(tr("self")); + m_ui->widgetObject->setShowClearObjectAction(false); + 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)) diff --git a/src/editor/dialogs/actions/movefreedialog.h b/src/editor/dialogs/actions/movefreedialog.h index 260b9d6..cc4031b 100644 --- a/src/editor/dialogs/actions/movefreedialog.h +++ b/src/editor/dialogs/actions/movefreedialog.h @@ -6,13 +6,14 @@ namespace Ui { class MoveFreeDialog; } class MoveFreeAction; +class ProjectTreeModel; class MoveFreeDialog : public QDialog { Q_OBJECT public: - explicit MoveFreeDialog(MoveFreeAction &action, QWidget *parent = nullptr); + explicit MoveFreeDialog(MoveFreeAction &action, ProjectTreeModel *projectModel, QWidget *parent = nullptr); ~MoveFreeDialog() override; private: diff --git a/src/editor/dialogs/actions/movefreedialog.ui b/src/editor/dialogs/actions/movefreedialog.ui index e8c9148..506834a 100644 --- a/src/editor/dialogs/actions/movefreedialog.ui +++ b/src/editor/dialogs/actions/movefreedialog.ui @@ -50,7 +50,7 @@ - + @@ -59,12 +59,9 @@ - - - - - - ... + + + false @@ -188,6 +185,14 @@ + + + ObjectSelectorWidget + QWidget +
widgets/objectselectorwidget.h
+ 1 +
+
@@ -224,5 +229,21 @@ + + radioButtonObject + toggled(bool) + widgetObject + setVisible(bool) + + + 127 + 115 + + + 289 + 115 + + + diff --git a/src/editor/dialogs/actions/movetowardsdialog.cpp b/src/editor/dialogs/actions/movetowardsdialog.cpp index af28db8..de48d0a 100644 --- a/src/editor/dialogs/actions/movetowardsdialog.cpp +++ b/src/editor/dialogs/actions/movetowardsdialog.cpp @@ -3,13 +3,23 @@ #include -MoveTowardsDialog::MoveTowardsDialog(MoveTowardsAction &action, QWidget *parent) : +MoveTowardsDialog::MoveTowardsDialog(MoveTowardsAction &action, ProjectTreeModel *projectModel, QWidget *parent) : QDialog{parent}, m_ui{std::make_unique()}, m_action{action} { m_ui->setupUi(this); + { + QSizePolicy sp_retain = m_ui->widgetObject->sizePolicy(); + sp_retain.setRetainSizeWhenHidden(true); + m_ui->widgetObject->setSizePolicy(sp_retain); + } + m_ui->widgetObject->setProjectModel(projectModel); + + m_ui->widgetObject->setEmptySelectionText(tr("self")); + m_ui->widgetObject->setShowClearObjectAction(false); + 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)) diff --git a/src/editor/dialogs/actions/movetowardsdialog.h b/src/editor/dialogs/actions/movetowardsdialog.h index c107b2e..c9f498f 100644 --- a/src/editor/dialogs/actions/movetowardsdialog.h +++ b/src/editor/dialogs/actions/movetowardsdialog.h @@ -6,13 +6,14 @@ namespace Ui { class MoveTowardsDialog; } class MoveTowardsAction; +class ProjectTreeModel; class MoveTowardsDialog : public QDialog { Q_OBJECT public: - explicit MoveTowardsDialog(MoveTowardsAction &action, QWidget *parent = nullptr); + explicit MoveTowardsDialog(MoveTowardsAction &action, ProjectTreeModel *projectModel, QWidget *parent = nullptr); ~MoveTowardsDialog() override; private: diff --git a/src/editor/dialogs/actions/movetowardsdialog.ui b/src/editor/dialogs/actions/movetowardsdialog.ui index 8104348..b85855d 100644 --- a/src/editor/dialogs/actions/movetowardsdialog.ui +++ b/src/editor/dialogs/actions/movetowardsdialog.ui @@ -50,7 +50,7 @@ - + @@ -59,12 +59,9 @@ - - - - - - ... + + + false @@ -201,6 +198,14 @@ + + + ObjectSelectorWidget + QWidget +
widgets/objectselectorwidget.h
+ 1 +
+
@@ -237,5 +242,21 @@ + + radioButtonObject + toggled(bool) + widgetObject + setVisible(bool) + + + 127 + 115 + + + 289 + 115 + + + diff --git a/src/editor/dialogs/actions/setgravitydialog.cpp b/src/editor/dialogs/actions/setgravitydialog.cpp new file mode 100644 index 0000000..a228b2a --- /dev/null +++ b/src/editor/dialogs/actions/setgravitydialog.cpp @@ -0,0 +1,29 @@ +#include "setgravitydialog.h" +#include "ui_setgravitydialog.h" + +#include + +SetGravityDialog::SetGravityDialog(SetGravityAction &action, ProjectTreeModel *projectModel, QWidget *parent) : + QDialog{parent}, + m_ui{std::make_unique()}, + m_action{action} +{ + m_ui->setupUi(this); + + { + QSizePolicy sp_retain = m_ui->widgetObject->sizePolicy(); + sp_retain.setRetainSizeWhenHidden(true); + m_ui->widgetObject->setSizePolicy(sp_retain); + } + m_ui->widgetObject->setProjectModel(projectModel); + + m_ui->widgetObject->setEmptySelectionText(tr("self")); + m_ui->widgetObject->setShowClearObjectAction(false); + + 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"}); +} + +SetGravityDialog::~SetGravityDialog() = default; diff --git a/src/editor/dialogs/actions/setgravitydialog.h b/src/editor/dialogs/actions/setgravitydialog.h new file mode 100644 index 0000000..4f84e08 --- /dev/null +++ b/src/editor/dialogs/actions/setgravitydialog.h @@ -0,0 +1,23 @@ +#pragma once + +#include + +#include + +namespace Ui { class SetGravityDialog; } +struct SetGravityAction; +class ProjectTreeModel; + +class SetGravityDialog : public QDialog +{ + Q_OBJECT + +public: + explicit SetGravityDialog(SetGravityAction &action, ProjectTreeModel *projectModel, QWidget *parent = nullptr); + ~SetGravityDialog() override; + +private: + const std::unique_ptr m_ui; + + SetGravityAction &m_action; +}; diff --git a/src/editor/dialogs/actions/setgravitydialog.ui b/src/editor/dialogs/actions/setgravitydialog.ui new file mode 100644 index 0000000..b368e84 --- /dev/null +++ b/src/editor/dialogs/actions/setgravitydialog.ui @@ -0,0 +1,249 @@ + + + SetGravityDialog + + + + 0 + 0 + 435 + 429 + + + + Set Gravity + + + + + + + + + + + :/qtgameengine/icons/action-set-gravity.png + + + + + + + Applies to + + + + + + Self + + + true + + + + + + + Other + + + + + + + + + Object: + + + + + + + false + + + + + + + + + + + + + + QFrame::StyledPanel + + + QFrame::Raised + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + direction: + + + spinBoxDirection + + + + + + + + + + gravity: + + + spinBoxGravity + + + + + + + + + + Relative + + + + + + + + + + + + Qt::Horizontal + + + QDialogButtonBox::Cancel|QDialogButtonBox::Ok + + + + + + + + ObjectSelectorWidget + QWidget +
widgets/objectselectorwidget.h
+ 1 +
+
+ + + + + + buttonBox + accepted() + SetGravityDialog + accept() + + + 257 + 419 + + + 157 + 274 + + + + + buttonBox + rejected() + SetGravityDialog + reject() + + + 325 + 419 + + + 286 + 274 + + + + + radioButtonObject + toggled(bool) + widgetObject + setVisible(bool) + + + 127 + 115 + + + 289 + 115 + + + + +
diff --git a/src/editor/dialogs/actions/speedhorizontaldialog.cpp b/src/editor/dialogs/actions/speedhorizontaldialog.cpp index b325b49..ea33686 100644 --- a/src/editor/dialogs/actions/speedhorizontaldialog.cpp +++ b/src/editor/dialogs/actions/speedhorizontaldialog.cpp @@ -3,13 +3,23 @@ #include -SpeedHorizontalDialog::SpeedHorizontalDialog(SpeedHorizontalAction &action, QWidget *parent) : +SpeedHorizontalDialog::SpeedHorizontalDialog(SpeedHorizontalAction &action, ProjectTreeModel *projectModel, QWidget *parent) : QDialog{parent}, m_ui{std::make_unique()}, m_action{action} { m_ui->setupUi(this); + { + QSizePolicy sp_retain = m_ui->widgetObject->sizePolicy(); + sp_retain.setRetainSizeWhenHidden(true); + m_ui->widgetObject->setSizePolicy(sp_retain); + } + m_ui->widgetObject->setProjectModel(projectModel); + + m_ui->widgetObject->setEmptySelectionText(tr("self")); + m_ui->widgetObject->setShowClearObjectAction(false); + 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)) diff --git a/src/editor/dialogs/actions/speedhorizontaldialog.h b/src/editor/dialogs/actions/speedhorizontaldialog.h index 51c96e9..49c4ca3 100644 --- a/src/editor/dialogs/actions/speedhorizontaldialog.h +++ b/src/editor/dialogs/actions/speedhorizontaldialog.h @@ -6,13 +6,14 @@ namespace Ui { class SpeedHorizontalDialog; } struct SpeedHorizontalAction; +class ProjectTreeModel; class SpeedHorizontalDialog : public QDialog { Q_OBJECT public: - explicit SpeedHorizontalDialog(SpeedHorizontalAction &action, QWidget *parent = nullptr); + explicit SpeedHorizontalDialog(SpeedHorizontalAction &action, ProjectTreeModel *projectModel, QWidget *parent = nullptr); ~SpeedHorizontalDialog() override; private: diff --git a/src/editor/dialogs/actions/speedhorizontaldialog.ui b/src/editor/dialogs/actions/speedhorizontaldialog.ui index 3a1e2cb..93af3bb 100644 --- a/src/editor/dialogs/actions/speedhorizontaldialog.ui +++ b/src/editor/dialogs/actions/speedhorizontaldialog.ui @@ -6,31 +6,183 @@ 0 0 - 400 - 300 + 435 + 429 - Dialog + Speed Horizontal - - - - 30 - 240 - 341 - 32 - - - - Qt::Horizontal - - - QDialogButtonBox::Cancel|QDialogButtonBox::Ok - - + + + + + + + + + + :/qtgameengine/icons/action-speed-horizontal.png + + + + + + + Applies to + + + + + + Self + + + true + + + + + + + Other + + + + + + + + + Object: + + + + + + + false + + + + + + + + + + + + + + QFrame::StyledPanel + + + QFrame::Raised + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + hor. speed: + + + spinBoxHorSpeed + + + + + + + + + + Relative + + + + + + + + + + + + Qt::Horizontal + + + QDialogButtonBox::Cancel|QDialogButtonBox::Ok + + + + - + + + ObjectSelectorWidget + QWidget +
widgets/objectselectorwidget.h
+ 1 +
+
+ + + buttonBox @@ -39,8 +191,8 @@ accept() - 248 - 254 + 257 + 419 157 @@ -55,8 +207,8 @@ reject() - 316 - 260 + 325 + 419 286 @@ -64,5 +216,21 @@ + + radioButtonObject + toggled(bool) + widgetObject + setVisible(bool) + + + 127 + 115 + + + 289 + 115 + + + diff --git a/src/editor/dialogs/actions/speedverticaldialog.cpp b/src/editor/dialogs/actions/speedverticaldialog.cpp index 1af4a83..22342a0 100644 --- a/src/editor/dialogs/actions/speedverticaldialog.cpp +++ b/src/editor/dialogs/actions/speedverticaldialog.cpp @@ -3,13 +3,23 @@ #include -SpeedVerticalDialog::SpeedVerticalDialog(SpeedVerticalAction &action, QWidget *parent) : +SpeedVerticalDialog::SpeedVerticalDialog(SpeedVerticalAction &action, ProjectTreeModel *projectModel, QWidget *parent) : QDialog{parent}, m_ui{std::make_unique()}, m_action{action} { m_ui->setupUi(this); + { + QSizePolicy sp_retain = m_ui->widgetObject->sizePolicy(); + sp_retain.setRetainSizeWhenHidden(true); + m_ui->widgetObject->setSizePolicy(sp_retain); + } + m_ui->widgetObject->setProjectModel(projectModel); + + m_ui->widgetObject->setEmptySelectionText(tr("self")); + m_ui->widgetObject->setShowClearObjectAction(false); + 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)) diff --git a/src/editor/dialogs/actions/speedverticaldialog.h b/src/editor/dialogs/actions/speedverticaldialog.h index 70749f9..f686936 100644 --- a/src/editor/dialogs/actions/speedverticaldialog.h +++ b/src/editor/dialogs/actions/speedverticaldialog.h @@ -6,13 +6,14 @@ namespace Ui { class SpeedVerticalDialog; } struct SpeedVerticalAction; +class ProjectTreeModel; class SpeedVerticalDialog : public QDialog { Q_OBJECT public: - explicit SpeedVerticalDialog(SpeedVerticalAction &action, QWidget *parent = nullptr); + explicit SpeedVerticalDialog(SpeedVerticalAction &action, ProjectTreeModel *projectModel, QWidget *parent = nullptr); ~SpeedVerticalDialog() override; private: diff --git a/src/editor/dialogs/actions/speedverticaldialog.ui b/src/editor/dialogs/actions/speedverticaldialog.ui index 3981708..afe76d7 100644 --- a/src/editor/dialogs/actions/speedverticaldialog.ui +++ b/src/editor/dialogs/actions/speedverticaldialog.ui @@ -6,31 +6,183 @@ 0 0 - 400 - 300 + 435 + 429 - Dialog + Speed Vertical - - - - 30 - 240 - 341 - 32 - - - - Qt::Horizontal - - - QDialogButtonBox::Cancel|QDialogButtonBox::Ok - - + + + + + + + + + + :/qtgameengine/icons/action-speed-vertical.png + + + + + + + Applies to + + + + + + Self + + + true + + + + + + + Other + + + + + + + + + Object: + + + + + + + false + + + + + + + + + + + + + + QFrame::StyledPanel + + + QFrame::Raised + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + vert. speed: + + + spinBoxVertSpeed + + + + + + + + + + Relative + + + + + + + + + + + + Qt::Horizontal + + + QDialogButtonBox::Cancel|QDialogButtonBox::Ok + + + + - + + + ObjectSelectorWidget + QWidget +
widgets/objectselectorwidget.h
+ 1 +
+
+ + + buttonBox @@ -39,8 +191,8 @@ accept() - 248 - 254 + 257 + 419 157 @@ -55,8 +207,8 @@ reject() - 316 - 260 + 325 + 419 286 @@ -64,5 +216,21 @@ + + radioButtonObject + toggled(bool) + widgetObject + setVisible(bool) + + + 127 + 115 + + + 289 + 115 + + + diff --git a/src/editor/dialogs/codeeditordialog.cpp b/src/editor/dialogs/codeeditordialog.cpp index 82b9d44..69ba018 100644 --- a/src/editor/dialogs/codeeditordialog.cpp +++ b/src/editor/dialogs/codeeditordialog.cpp @@ -115,9 +115,9 @@ void CodeEditorDialog::changed() } } -void CodeEditorDialog::addToolbarWidget(QWidget *widget) +QAction *CodeEditorDialog::addToolbarWidget(QWidget *widget) { - m_ui->toolBar->addWidget(widget); + return m_ui->toolBar->addWidget(widget); } void CodeEditorDialog::loadCode() diff --git a/src/editor/dialogs/codeeditordialog.h b/src/editor/dialogs/codeeditordialog.h index cac7a5f..a75c9b2 100644 --- a/src/editor/dialogs/codeeditordialog.h +++ b/src/editor/dialogs/codeeditordialog.h @@ -30,7 +30,7 @@ protected slots: protected: bool m_unsavedChanges{}; - void addToolbarWidget(QWidget *widget); + QAction *addToolbarWidget(QWidget *widget); private slots: void loadCode(); diff --git a/src/editor/dialogs/objectpropertiesdialog.cpp b/src/editor/dialogs/objectpropertiesdialog.cpp index f2b7ab8..e07eee2 100644 --- a/src/editor/dialogs/objectpropertiesdialog.cpp +++ b/src/editor/dialogs/objectpropertiesdialog.cpp @@ -22,10 +22,8 @@ ObjectPropertiesDialog::ObjectPropertiesDialog(Object &object, ProjectTreeModel m_collisionEvents{m_object.collisionEvents}, m_eventsModel{std::make_unique(m_events, m_collisionEvents)}, m_menuSprites{new QMenu{this}}, - m_menuParents{new QMenu{this}}, m_menuMaskSprites{new QMenu{this}}, m_spriteName{object.spriteName}, - m_parentName{object.parentName}, m_maskSpriteName{object.maskSpriteName} { m_ui->setupUi(this); @@ -37,13 +35,20 @@ ObjectPropertiesDialog::ObjectPropertiesDialog(Object &object, ProjectTreeModel if (auto button = m_ui->buttonBox->button(QDialogButtonBox::Cancel)) button->setIcon(QIcon{":/qtgameengine/icons/delete.png"}); + m_ui->widgetParent->setProjectModel(&m_projectModel); + m_ui->widgetParent->setForbiddenObjectName(m_object.name); + m_ui->actionsWidget->setProjectModel(&m_projectModel); + m_ui->lineEditName->setText(m_object.name); m_ui->lineEditSprite->setText(m_spriteName.isEmpty() ? tr("") : m_spriteName); - m_ui->lineEditParent->setText(m_parentName.isEmpty() ? tr("") : m_parentName); + m_ui->widgetParent->setEmptySelectionText(tr("")); + if (QSignalBlocker blocker{m_ui->widgetParent}; object.parentName.isEmpty()) + m_ui->widgetParent->clearObject(); + else + m_ui->widgetParent->setObject(object.parentName); m_ui->lineEditMask->setText(m_maskSpriteName.isEmpty() ? tr("") : m_maskSpriteName); updateSpritePreview(); m_ui->toolButtonSprite->setMenu(m_menuSprites); - m_ui->toolButtonParent->setMenu(m_menuParents); m_ui->toolButtonMask->setMenu(m_menuMaskSprites); m_ui->checkBoxVisible->setChecked(m_object.visible); m_ui->checkBoxSolid->setChecked(m_object.solid); @@ -51,7 +56,6 @@ ObjectPropertiesDialog::ObjectPropertiesDialog(Object &object, ProjectTreeModel m_ui->checkBoxPersistent->setChecked(m_object.persistent); m_ui->lineEditSprite->setMenu(m_menuSprites); - m_ui->lineEditParent->setMenu(m_menuParents); m_ui->lineEditMask->setMenu(m_menuMaskSprites); m_ui->listViewEvents->setModel(m_eventsModel.get()); @@ -104,11 +108,12 @@ ObjectPropertiesDialog::ObjectPropertiesDialog(Object &object, ProjectTreeModel connect(m_menuSprites, &QMenu::aboutToShow, this, &ObjectPropertiesDialog::spritesMenuAboutToShow); - connect(m_menuParents, &QMenu::aboutToShow, - this, &ObjectPropertiesDialog::parentsMenuAboutToShow); connect(m_menuMaskSprites, &QMenu::aboutToShow, this, &ObjectPropertiesDialog::maskSpritesMenuAboutToShow); + connect(m_ui->widgetParent, &ObjectSelectorWidget::changed, + this, &ObjectPropertiesDialog::changed); + connect(m_ui->listViewEvents->selectionModel(), &QItemSelectionModel::currentChanged, this, &ObjectPropertiesDialog::currentEventChanged); @@ -148,7 +153,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.parentName = m_parentName; + m_object.parentName = m_ui->widgetParent->objectName(); m_object.maskSpriteName = m_maskSpriteName; m_object.events = std::move(m_events); m_object.collisionEvents = std::move(m_collisionEvents); @@ -283,11 +288,9 @@ void ObjectPropertiesDialog::objectNameChanged(const Object &object, const QStri updateTitle(); } - if (!m_parentName.isEmpty() && m_parentName == oldName) - { - m_parentName = object.name; - m_ui->lineEditParent->setText(object.name); - } + if (QSignalBlocker blocker{m_ui->widgetParent}; + !m_ui->widgetParent->objectName().isEmpty() && m_ui->widgetParent->objectName() == oldName) + m_ui->widgetParent->setObject(object.name); } void ObjectPropertiesDialog::spriteNameChanged(const Sprite &sprite, const QString &oldName) @@ -314,11 +317,9 @@ void ObjectPropertiesDialog::spriteNameChanged(const Sprite &sprite, const QStri void ObjectPropertiesDialog::objectAboutToBeRemoved(const Object &object) { - if (!m_parentName.isEmpty() && m_parentName == object.name) - { - m_parentName.clear(); - m_ui->lineEditParent->setText(tr("")); - } + if (QSignalBlocker blocker{m_ui->widgetParent}; + !m_ui->widgetParent->objectName().isEmpty() && m_ui->widgetParent->objectName() == object.name) + m_ui->widgetParent->clearObject(); } void ObjectPropertiesDialog::spriteAboutToBeRemoved(const Sprite &sprite) @@ -365,29 +366,6 @@ void ObjectPropertiesDialog::spritesMenuAboutToShow() [&sprite,this](){ setSprite(sprite); }); } -void ObjectPropertiesDialog::parentsMenuAboutToShow() -{ - m_menuParents->clear(); - m_menuParents->addAction(tr(""), this, &ObjectPropertiesDialog::clearParent); - for (const Object &object : m_projectModel.project()->objects) - { - QIcon icon; - if (!object.spriteName.isEmpty()) - { - const auto &sprites = m_projectModel.project()->sprites; - const auto iter = std::find_if(std::cbegin(sprites), std::cend(sprites), - [&](const Sprite &sprite){ return sprite.name == object.spriteName; }); - if (iter != std::cend(sprites)) - { - if (!iter->pixmaps.empty()) - icon = iter->pixmaps.front(); - } - } - m_menuParents->addAction(icon, object.name, this, - [&object,this](){ setParent(object); }); - } -} - void ObjectPropertiesDialog::maskSpritesMenuAboutToShow() { m_menuMaskSprites->clear(); @@ -449,26 +427,6 @@ void ObjectPropertiesDialog::setSprite(const Sprite &sprite) changed(); } -void ObjectPropertiesDialog::clearParent() -{ - m_parentName.clear(); - m_ui->lineEditParent->setText(tr("")); - changed(); -} - -void ObjectPropertiesDialog::setParent(const Object &object) -{ - if (&m_object == &object) - { - QMessageBox::warning(this, tr("This will create a loop in parents."), tr("This will create a loop in parents.")); - return; - } - - m_parentName = object.name; - m_ui->lineEditParent->setText(object.name); - changed(); -} - void ObjectPropertiesDialog::clearMaskSprite() { m_maskSpriteName.clear(); diff --git a/src/editor/dialogs/objectpropertiesdialog.h b/src/editor/dialogs/objectpropertiesdialog.h index 1594646..947d95a 100644 --- a/src/editor/dialogs/objectpropertiesdialog.h +++ b/src/editor/dialogs/objectpropertiesdialog.h @@ -42,7 +42,6 @@ private slots: void spritePixmapsChanged(const Sprite &sprite); void spritesMenuAboutToShow(); - void parentsMenuAboutToShow(); void maskSpritesMenuAboutToShow(); void currentEventChanged(const QModelIndex &index); void eventsContextMenuRequested(const QPoint &pos); @@ -51,9 +50,6 @@ private slots: void clearSprite(); void setSprite(const Sprite &sprite); - void clearParent(); - void setParent(const Object &object); - void clearMaskSprite(); void setMaskSprite(const Sprite &sprite); @@ -74,11 +70,9 @@ private: const std::unique_ptr m_eventsModel; QMenu * const m_menuSprites; - QMenu * const m_menuParents; QMenu * const m_menuMaskSprites; QString m_spriteName; - QString m_parentName; QString m_maskSpriteName; bool m_unsavedChanges{}; diff --git a/src/editor/dialogs/objectpropertiesdialog.ui b/src/editor/dialogs/objectpropertiesdialog.ui index 464c0b6..6e14acd 100644 --- a/src/editor/dialogs/objectpropertiesdialog.ui +++ b/src/editor/dialogs/objectpropertiesdialog.ui @@ -204,42 +204,12 @@ Parent: - lineEditParent + widgetParent - - - - - - 0 - 0 - - - - The parent from which events and actions are - - - <no parent> - - - true - - - - - - - ... - - - QToolButton::InstantPopup - - - - + @@ -431,6 +401,12 @@ QLineEdit
widgets/qlineeditwithmenu.h
+ + ObjectParentSelectorWidget + QWidget +
widgets/objectparentselectorwidget.h
+ 1 +
diff --git a/src/editor/icons/action-set-gravity.png b/src/editor/icons/action-set-gravity.png new file mode 100644 index 0000000..3e92bbe Binary files /dev/null and b/src/editor/icons/action-set-gravity.png differ diff --git a/src/editor/models/actionscontainermodel.cpp b/src/editor/models/actionscontainermodel.cpp index 385c2d4..3d8917c 100644 --- a/src/editor/models/actionscontainermodel.cpp +++ b/src/editor/models/actionscontainermodel.cpp @@ -54,6 +54,8 @@ QVariant ActionsContainerModel::data(const QModelIndex &index, int role) const return tr("Set the horizontal speed"); else if (std::holds_alternative(action)) return tr("Set the vertical speed"); + else if (std::holds_alternative(action)) + return tr("Set the gravity"); else if (std::holds_alternative(action)) return tr("Execute a piece of code"); else @@ -72,6 +74,8 @@ QVariant ActionsContainerModel::data(const QModelIndex &index, int role) const return QIcon{":/qtgameengine/icons/action-speed-horizontal.png"}; else if (std::holds_alternative(action)) return QIcon{":/qtgameengine/icons/action-speed-vertical.png"}; + else if (std::holds_alternative(action)) + return QIcon{":/qtgameengine/icons/action-set-gravity.png"}; else if (std::holds_alternative(action)) return QIcon{":/qtgameengine/icons/action-execute-code.png"}; else diff --git a/src/editor/models/actionscontainermodel.h b/src/editor/models/actionscontainermodel.h index 19a555b..27696fe 100644 --- a/src/editor/models/actionscontainermodel.h +++ b/src/editor/models/actionscontainermodel.h @@ -28,7 +28,8 @@ public: bool removeRows(int row, int count, const QModelIndex &parent) override; bool moveRows(const QModelIndex &sourceParent, int sourceRow, int count, const QModelIndex &destinationParent, int destinationChild) override; - ActionsContainer *actionsContainer() const { return m_actionsContainer; } + ActionsContainer *actionsContainer() { return m_actionsContainer; } + const ActionsContainer *actionsContainer() const { return m_actionsContainer; } void setActionsContainer(ActionsContainer *actionsContainer); Action *getAction(const QModelIndex &index); diff --git a/src/editor/resources_editor.qrc b/src/editor/resources_editor.qrc index bbf428e..fe47c6e 100644 --- a/src/editor/resources_editor.qrc +++ b/src/editor/resources_editor.qrc @@ -5,6 +5,7 @@ icons/action-move-fixed.png icons/action-move-free.png icons/action-move-towards.png + icons/action-set-gravity.png icons/action-speed-horizontal.png icons/action-speed-vertical.png icons/add.png diff --git a/src/editor/widgets/actionscontainerwidget.cpp b/src/editor/widgets/actionscontainerwidget.cpp index 8bc77d4..9e6ba7e 100644 --- a/src/editor/widgets/actionscontainerwidget.cpp +++ b/src/editor/widgets/actionscontainerwidget.cpp @@ -12,6 +12,7 @@ #include "dialogs/actions/movetowardsdialog.h" #include "dialogs/actions/speedhorizontaldialog.h" #include "dialogs/actions/speedverticaldialog.h" +#include "dialogs/actions/setgravitydialog.h" #include "dialogs/actions/executecodedialog.h" namespace { @@ -21,6 +22,7 @@ template<> struct ActionDialogForImpl { using Dialog = MoveFreeD template<> struct ActionDialogForImpl { using Dialog = MoveTowardsDialog; }; template<> struct ActionDialogForImpl { using Dialog = SpeedHorizontalDialog; }; template<> struct ActionDialogForImpl { using Dialog = SpeedVerticalDialog; }; +template<> struct ActionDialogForImpl { using Dialog = SetGravityDialog; }; template<> struct ActionDialogForImpl { using Dialog = ExecuteCodeDialog; }; template using ActionDialogFor = ActionDialogForImpl::Dialog; } @@ -61,6 +63,8 @@ ActionsContainerWidget::ActionsContainerWidget(QWidget *parent) : this, &ActionsContainerWidget::createNewAction); connect(m_ui->toolButtonSpeedVertical, &QAbstractButton::clicked, this, &ActionsContainerWidget::createNewAction); + connect(m_ui->toolButtonSetGravity, &QAbstractButton::clicked, + this, &ActionsContainerWidget::createNewAction); connect(m_ui->toolButtonExecuteCode, &QAbstractButton::clicked, this, &ActionsContainerWidget::createNewAction); @@ -69,12 +73,18 @@ ActionsContainerWidget::ActionsContainerWidget(QWidget *parent) : m_ui->toolButtonMoveTowards->setAction(MoveTowardsAction{}); m_ui->toolButtonSpeedHorizontal->setAction(SpeedHorizontalAction{}); m_ui->toolButtonSpeedVertical->setAction(SpeedVerticalAction{}); + m_ui->toolButtonSetGravity->setAction(SetGravityAction{}); m_ui->toolButtonExecuteCode->setAction(ExecuteCodeAction{}); } ActionsContainerWidget::~ActionsContainerWidget() = default; -ActionsContainer *ActionsContainerWidget::actionsContainer() const +ActionsContainer *ActionsContainerWidget::actionsContainer() +{ + return m_actionsModel->actionsContainer(); +} + +const ActionsContainer *ActionsContainerWidget::actionsContainer() const { return m_actionsModel->actionsContainer(); } @@ -95,37 +105,43 @@ void ActionsContainerWidget::actionDoubleClicked(const QModelIndex &index) if (auto ptr = std::get_if(action)) { - MoveFixedDialog dialog{*ptr, this}; + MoveFixedDialog dialog{*ptr, m_projectModel, this}; if (dialog.exec() == QDialog::Accepted) emit changed(); } else if (auto ptr = std::get_if(action)) { - MoveFreeDialog dialog{*ptr, this}; + MoveFreeDialog dialog{*ptr, m_projectModel, this}; if (dialog.exec() == QDialog::Accepted) emit changed(); } else if (auto ptr = std::get_if(action)) { - MoveTowardsDialog dialog{*ptr, this}; + MoveTowardsDialog dialog{*ptr, m_projectModel, this}; if (dialog.exec() == QDialog::Accepted) emit changed(); } else if (auto ptr = std::get_if(action)) { - SpeedHorizontalDialog dialog{*ptr, this}; + SpeedHorizontalDialog dialog{*ptr, m_projectModel, this}; if (dialog.exec() == QDialog::Accepted) emit changed(); } else if (auto ptr = std::get_if(action)) { - SpeedVerticalDialog dialog{*ptr, this}; + 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, this}; + ExecuteCodeDialog dialog{*ptr, m_projectModel, this}; if (dialog.exec() == QDialog::Accepted) emit changed(); } @@ -205,7 +221,7 @@ void ActionsContainerWidget::createNewAction() return; T action; - ActionDialogFor dialog{action, this}; + ActionDialogFor dialog{action, m_projectModel, this}; if (dialog.exec() == QDialog::Accepted) m_actionsModel->appendAction(std::move(action)); } diff --git a/src/editor/widgets/actionscontainerwidget.h b/src/editor/widgets/actionscontainerwidget.h index 44cbeb1..a2a1b4d 100644 --- a/src/editor/widgets/actionscontainerwidget.h +++ b/src/editor/widgets/actionscontainerwidget.h @@ -8,6 +8,7 @@ namespace Ui { class ActionsContainerWidget; } class ActionsContainerModel; +class ProjectTreeModel; class ActionsContainerWidget : public QWidget { @@ -17,7 +18,12 @@ public: explicit ActionsContainerWidget(QWidget *parent = nullptr); ~ActionsContainerWidget(); - ActionsContainer *actionsContainer() const; + ProjectTreeModel *projectModel() { return m_projectModel; } + const ProjectTreeModel *projectModel() const { return m_projectModel; } + void setProjectModel(ProjectTreeModel *projectModel) { m_projectModel = projectModel; } + + ActionsContainer *actionsContainer(); + const ActionsContainer *actionsContainer() const; void setActionsContainer(ActionsContainer *actionsContainer); signals: @@ -35,4 +41,6 @@ private: const std::unique_ptr m_ui; const std::unique_ptr m_actionsModel; + + ProjectTreeModel *m_projectModel{}; }; diff --git a/src/editor/widgets/actionscontainerwidget.ui b/src/editor/widgets/actionscontainerwidget.ui index 6842209..f18ee3a 100644 --- a/src/editor/widgets/actionscontainerwidget.ui +++ b/src/editor/widgets/actionscontainerwidget.ui @@ -257,13 +257,13 @@
- + Set Gravity - :/qtgameengine/icons/action.png:/qtgameengine/icons/action.png + :/qtgameengine/icons/action-set-gravity.png:/qtgameengine/icons/action-set-gravity.png diff --git a/src/editor/widgets/objectparentselectorwidget.cpp b/src/editor/widgets/objectparentselectorwidget.cpp new file mode 100644 index 0000000..03961bd --- /dev/null +++ b/src/editor/widgets/objectparentselectorwidget.cpp @@ -0,0 +1,14 @@ +#include "objectparentselectorwidget.h" + +#include + +void ObjectParentSelectorWidget::setObject(const QString &objectName) +{ + if (!m_forbiddenObjectName.isEmpty() && m_forbiddenObjectName == objectName) + { + QMessageBox::warning(this, tr("This will create a loop in parents."), tr("This will create a loop in parents.")); + return; + } + + ObjectSelectorWidget::setObject(objectName); +} diff --git a/src/editor/widgets/objectparentselectorwidget.h b/src/editor/widgets/objectparentselectorwidget.h new file mode 100644 index 0000000..52d703f --- /dev/null +++ b/src/editor/widgets/objectparentselectorwidget.h @@ -0,0 +1,19 @@ +#pragma once + +#include "objectselectorwidget.h" + +class ObjectParentSelectorWidget : public ObjectSelectorWidget +{ + Q_OBJECT + +public: + using ObjectSelectorWidget::ObjectSelectorWidget; + + QString forbiddenObjectName() const { return m_forbiddenObjectName; }; + void setForbiddenObjectName(const QString &forbiddenObjectName) { m_forbiddenObjectName = forbiddenObjectName; } + + void setObject(const QString &objectName) override; + +private: + QString m_forbiddenObjectName; +}; diff --git a/src/editor/widgets/objectselectorwidget.cpp b/src/editor/widgets/objectselectorwidget.cpp new file mode 100644 index 0000000..9b53c54 --- /dev/null +++ b/src/editor/widgets/objectselectorwidget.cpp @@ -0,0 +1,83 @@ +#include "objectselectorwidget.h" +#include "ui_objectselectorwidget.h" + +#include +#include + +#include "models/projecttreemodel.h" +#include "projectcontainer.h" + +ObjectSelectorWidget::ObjectSelectorWidget(QWidget *parent) : + QWidget{parent}, + m_ui{std::make_unique()}, + m_menuObjects{new QMenu{this}} +{ + m_ui->setupUi(this); + + m_ui->lineEdit->setMenu(m_menuObjects); + m_ui->toolButton->setMenu(m_menuObjects); + + connect(m_menuObjects, &QMenu::aboutToShow, + this, &ObjectSelectorWidget::menuAboutToShow); +} + +ObjectSelectorWidget::~ObjectSelectorWidget() = default; + +void ObjectSelectorWidget::setObject(const QString &objectName) +{ + if (m_objectName == objectName) + return; + + m_objectName = objectName; + m_ui->lineEdit->setText(objectName); + emit changed(); +} + +void ObjectSelectorWidget::clearObject() +{ + if (m_objectName.isEmpty()) + return; + + m_objectName.clear(); + m_ui->lineEdit->setText(m_emptySelectionText); + emit changed(); +} + +void ObjectSelectorWidget::setEmptySelectionText(const QString &emptySelectionText) +{ + m_emptySelectionText = emptySelectionText; + if (m_objectName.isEmpty()) + m_ui->lineEdit->setText(m_emptySelectionText); +} + +void ObjectSelectorWidget::menuAboutToShow() +{ + if (!m_projectModel) + { + qCritical() << "no project model!"; + return; + } + + m_menuObjects->clear(); + + if (m_showClearObjectAction) + m_menuObjects->addAction(m_emptySelectionText, this, &ObjectSelectorWidget::clearObject); + + for (const Object &object : m_projectModel->project()->objects) + { + QIcon icon; + if (!object.spriteName.isEmpty()) + { + const auto &sprites = m_projectModel->project()->sprites; + const auto iter = std::find_if(std::cbegin(sprites), std::cend(sprites), + [&](const Sprite &sprite){ return sprite.name == object.spriteName; }); + if (iter != std::cend(sprites)) + { + if (!iter->pixmaps.empty()) + icon = iter->pixmaps.front(); + } + } + m_menuObjects->addAction(icon, object.name, this, + [&object,this](){ setObject(object.name); }); + } +} diff --git a/src/editor/widgets/objectselectorwidget.h b/src/editor/widgets/objectselectorwidget.h new file mode 100644 index 0000000..b1c8996 --- /dev/null +++ b/src/editor/widgets/objectselectorwidget.h @@ -0,0 +1,51 @@ +#pragma once + +#include + +#include + +namespace Ui { class ObjectSelectorWidget; } +class ProjectTreeModel; + +class ObjectSelectorWidget : public QWidget +{ + Q_OBJECT + Q_PROPERTY(QString emptySelectionText READ emptySelectionText WRITE setEmptySelectionText DESIGNABLE true FINAL) + Q_PROPERTY(bool showClearObjectAction READ showClearObjectAction WRITE setShowClearObjectAction DESIGNABLE true FINAL) + +public: + explicit ObjectSelectorWidget(QWidget *parent = nullptr); + ~ObjectSelectorWidget() override; + + ProjectTreeModel *projectModel() { return m_projectModel; } + const ProjectTreeModel *projectModel() const { return m_projectModel; } + void setProjectModel(ProjectTreeModel *projectModel) { m_projectModel = projectModel; } + + QString objectName() const { return m_objectName; } + virtual void setObject(const QString &objectName); + void clearObject(); + + QString emptySelectionText() const { return m_emptySelectionText; } + void setEmptySelectionText(const QString &emptySelectionText); + + bool showClearObjectAction() const { return m_showClearObjectAction; } + void setShowClearObjectAction(bool showClearObjectAction) { m_showClearObjectAction = showClearObjectAction; } + +signals: + void changed(); + +private slots: + void menuAboutToShow(); + +private: + const std::unique_ptr m_ui; + + ProjectTreeModel *m_projectModel{}; + + QString m_objectName; + + QString m_emptySelectionText; + bool m_showClearObjectAction; + + QMenu * const m_menuObjects; +}; diff --git a/src/editor/widgets/objectselectorwidget.ui b/src/editor/widgets/objectselectorwidget.ui new file mode 100644 index 0000000..a9d5411 --- /dev/null +++ b/src/editor/widgets/objectselectorwidget.ui @@ -0,0 +1,59 @@ + + + ObjectSelectorWidget + + + + 0 + 0 + 168 + 26 + + + + + 0 + 0 + + + + Form + + + + 0 + + + 0 + + + 0 + + + 0 + + + + + + + + ... + + + QToolButton::InstantPopup + + + + + + + + QLineEditWithMenu + QLineEdit +
widgets/qlineeditwithmenu.h
+
+
+ + +
diff --git a/src/projectcontainer.h b/src/projectcontainer.h index ba98d6a..0df972d 100644 --- a/src/projectcontainer.h +++ b/src/projectcontainer.h @@ -157,35 +157,51 @@ struct Font } range; }; -struct MoveFixedAction { +struct AppliesToSelf { }; +struct AppliesToOther { + +}; + +struct AppliesToObject { + QString objectName; +}; + +using AppliesTo = std::variant< + AppliesToSelf, + AppliesToOther, + AppliesToObject +>; + +struct MoveFixedAction { + AppliesTo appliesTo{AppliesToSelf{}}; +}; + struct MoveFreeAction { - + AppliesTo appliesTo{AppliesToSelf{}}; }; struct MoveTowardsAction { - + AppliesTo appliesTo{AppliesToSelf{}}; }; struct SpeedHorizontalAction { + AppliesTo appliesTo{AppliesToSelf{}}; +}; +struct SetGravityAction { + AppliesTo appliesTo{AppliesToSelf{}}; }; struct SpeedVerticalAction { - + AppliesTo appliesTo{AppliesToSelf{}}; }; struct ExecuteCodeAction { - enum class AppliesTo { - Self, - Other, - Object - }; - + AppliesTo appliesTo{AppliesToSelf{}}; QString script; - AppliesTo appliesTo{AppliesTo::Self}; }; using Action = std::variant< @@ -194,6 +210,7 @@ using Action = std::variant< MoveTowardsAction, SpeedHorizontalAction, SpeedVerticalAction, + SetGravityAction, ExecuteCodeAction >; diff --git a/src/projectserialization.cpp b/src/projectserialization.cpp index d241617..3e00d56 100644 --- a/src/projectserialization.cpp +++ b/src/projectserialization.cpp @@ -262,87 +262,143 @@ QDataStream &operator>>(QDataStream &ds, Font &font) return ds; } +QDataStream &operator<<(QDataStream &ds, const AppliesToSelf &action) +{ + Q_UNUSED(action); + //ds << action.; + return ds; +} + +QDataStream &operator>>(QDataStream &ds, AppliesToSelf &action) +{ + Q_UNUSED(action); + //ds >> action.; + return ds; +} + +QDataStream &operator<<(QDataStream &ds, const AppliesToOther &action) +{ + Q_UNUSED(action); + //ds << action.; + return ds; +} + +QDataStream &operator>>(QDataStream &ds, AppliesToOther &action) +{ + Q_UNUSED(action); + //ds >> action.; + return ds; +} + +QDataStream &operator<<(QDataStream &ds, const AppliesToObject &action) +{ + Q_UNUSED(action); + ds << action.objectName; + return ds; +} + +QDataStream &operator>>(QDataStream &ds, AppliesToObject &action) +{ + Q_UNUSED(action); + ds >> action.objectName; + return ds; +} + QDataStream &operator<<(QDataStream &ds, const MoveFixedAction &action) { Q_UNUSED(action); -// ds << action.; + ds << action.appliesTo; return ds; } QDataStream &operator>>(QDataStream &ds, MoveFixedAction &action) { Q_UNUSED(action); -// ds >> action.; + ds >> action.appliesTo; return ds; } QDataStream &operator<<(QDataStream &ds, const MoveFreeAction &action) { Q_UNUSED(action); -// ds << action.; + ds << action.appliesTo; return ds; } QDataStream &operator>>(QDataStream &ds, MoveFreeAction &action) { Q_UNUSED(action); -// ds >> action.; + ds >> action.appliesTo; return ds; } QDataStream &operator<<(QDataStream &ds, const MoveTowardsAction &action) { Q_UNUSED(action); -// ds << action.; + ds << action.appliesTo; return ds; } QDataStream &operator>>(QDataStream &ds, MoveTowardsAction &action) { Q_UNUSED(action); -// ds >> action.; + ds >> action.appliesTo; return ds; } QDataStream &operator<<(QDataStream &ds, const SpeedHorizontalAction &action) { Q_UNUSED(action); -// ds << action.; + ds << action.appliesTo; return ds; } QDataStream &operator>>(QDataStream &ds, SpeedHorizontalAction &action) { Q_UNUSED(action); -// ds >> action.; + ds >> action.appliesTo; return ds; } QDataStream &operator<<(QDataStream &ds, const SpeedVerticalAction &action) { Q_UNUSED(action); -// ds << action.; + ds << action.appliesTo; return ds; } QDataStream &operator>>(QDataStream &ds, SpeedVerticalAction &action) { Q_UNUSED(action); -// ds >> action.; + ds >> action.appliesTo; + return ds; +} + +QDataStream &operator<<(QDataStream &ds, const SetGravityAction &action) +{ + Q_UNUSED(action); + ds << action.appliesTo; + return ds; +} + +QDataStream &operator>>(QDataStream &ds, SetGravityAction &action) +{ + Q_UNUSED(action); + ds >> action.appliesTo; return ds; } QDataStream &operator<<(QDataStream &ds, const ExecuteCodeAction &action) { - ds << action.script; - ds << action.appliesTo; + ds << action.appliesTo + << action.script; return ds; } QDataStream &operator>>(QDataStream &ds, ExecuteCodeAction &action) { - ds >> action.script; - ds >> action.appliesTo; + ds >> action.appliesTo + >> action.script; return ds; } diff --git a/src/projectserialization.h b/src/projectserialization.h index acd1a57..08f4389 100644 --- a/src/projectserialization.h +++ b/src/projectserialization.h @@ -28,6 +28,12 @@ QDataStream &operator<<(QDataStream &ds, const Script &script); QDataStream &operator>>(QDataStream &ds, Script &script); QDataStream &operator<<(QDataStream &ds, const Font &font); QDataStream &operator>>(QDataStream &ds, Font &font); +QDataStream &operator<<(QDataStream &ds, const AppliesToSelf &action); +QDataStream &operator>>(QDataStream &ds, AppliesToSelf &action); +QDataStream &operator<<(QDataStream &ds, const AppliesToOther &action); +QDataStream &operator>>(QDataStream &ds, AppliesToOther &action); +QDataStream &operator<<(QDataStream &ds, const AppliesToObject &action); +QDataStream &operator>>(QDataStream &ds, AppliesToObject &action); QDataStream &operator<<(QDataStream &ds, const MoveFixedAction &action); QDataStream &operator>>(QDataStream &ds, MoveFixedAction &action); QDataStream &operator<<(QDataStream &ds, const MoveFreeAction &action); @@ -38,6 +44,8 @@ QDataStream &operator<<(QDataStream &ds, const SpeedHorizontalAction &action); QDataStream &operator>>(QDataStream &ds, SpeedHorizontalAction &action); QDataStream &operator<<(QDataStream &ds, const SpeedVerticalAction &action); QDataStream &operator>>(QDataStream &ds, SpeedVerticalAction &action); +QDataStream &operator<<(QDataStream &ds, const SetGravityAction &action); +QDataStream &operator>>(QDataStream &ds, SetGravityAction &action); QDataStream &operator<<(QDataStream &ds, const ExecuteCodeAction &action); QDataStream &operator>>(QDataStream &ds, ExecuteCodeAction &action); QDataStream &operator<<(QDataStream &ds, const TimeLine &timeLine);