diff --git a/QtGameMaker.pro b/QtGameMaker.pro index 8123270..9e84c8d 100644 --- a/QtGameMaker.pro +++ b/QtGameMaker.pro @@ -14,6 +14,10 @@ QMAKE_CXXFLAGS += \ -Wpedantic \ -Werror +!greaterThan(QT_MAJOR_VERSION, 5) { + QMAKE_CXXFLAGS += -Wno-deprecated-enum-enum-conversion +} + DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 INCLUDEPATH += \ @@ -23,6 +27,8 @@ INCLUDEPATH += \ HEADERS += \ src/closeeventfilter.h \ src/editor/dialogs/genericcodeeditordialog.h \ + src/editor/widgets/qlineeditwithmenu.h \ + src/editor/widgets/qscrollareawithmenu.h \ src/editor/widgets/roomeditwidget.h \ src/futurecpp.h \ src/projectcontainer.h \ @@ -72,6 +78,8 @@ HEADERS += \ SOURCES += \ src/closeeventfilter.cpp \ src/editor/dialogs/genericcodeeditordialog.cpp \ + src/editor/widgets/qlineeditwithmenu.cpp \ + src/editor/widgets/qscrollareawithmenu.cpp \ src/editor/widgets/roomeditwidget.cpp \ src/main.cpp \ src/projectcontainer.cpp \ diff --git a/src/editor/dialogs/editspritedialog.cpp b/src/editor/dialogs/editspritedialog.cpp index 06307e6..a94a2b8 100644 --- a/src/editor/dialogs/editspritedialog.cpp +++ b/src/editor/dialogs/editspritedialog.cpp @@ -2,6 +2,7 @@ #include "ui_editspritedialog.h" #include +#include #include "projectcontainer.h" #include "models/spritesmodel.h" diff --git a/src/editor/dialogs/globalgamesettingsdialog.cpp b/src/editor/dialogs/globalgamesettingsdialog.cpp index db5ab1e..de5ee14 100644 --- a/src/editor/dialogs/globalgamesettingsdialog.cpp +++ b/src/editor/dialogs/globalgamesettingsdialog.cpp @@ -3,6 +3,7 @@ #include #include +#include GlobalGameSettingsDialog::GlobalGameSettingsDialog(QWidget *parent) : QDialog{parent}, diff --git a/src/editor/dialogs/imageeditordialog.cpp b/src/editor/dialogs/imageeditordialog.cpp index c5bda6f..dfb1bb9 100644 --- a/src/editor/dialogs/imageeditordialog.cpp +++ b/src/editor/dialogs/imageeditordialog.cpp @@ -2,6 +2,7 @@ #include "ui_imageeditordialog.h" #include +#include ImageEditorDialog::ImageEditorDialog(const QPixmap &pixmap, const QString &title, QWidget *parent) : QDialog{parent}, diff --git a/src/editor/dialogs/imageeditordialog.ui b/src/editor/dialogs/imageeditordialog.ui index 513f8ce..f52a6f6 100644 --- a/src/editor/dialogs/imageeditordialog.ui +++ b/src/editor/dialogs/imageeditordialog.ui @@ -137,36 +137,38 @@ - - - - - - + + + + + + + + + + true + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop + + + + + 0 + 0 + 470 + 375 + + + - - - - - 0 - 0 - 0 - 0 - - - - - - - - - - - - - + + + + + diff --git a/src/editor/dialogs/objectpropertiesdialog.cpp b/src/editor/dialogs/objectpropertiesdialog.cpp index 947f736..9258639 100644 --- a/src/editor/dialogs/objectpropertiesdialog.cpp +++ b/src/editor/dialogs/objectpropertiesdialog.cpp @@ -33,13 +33,14 @@ ObjectPropertiesDialog::ObjectPropertiesDialog(Object &object, ProjectTreeModel m_ui->lineEditName->setText(m_object.name); m_ui->lineEditSprite->setText(m_spriteName.isEmpty() ? tr("") : m_spriteName); updateSpritePreview(); - m_menuSprites->setParent(m_ui->toolButtonSprite); m_ui->toolButtonSprite->setMenu(m_menuSprites); m_ui->checkBoxVisible->setChecked(m_object.visible); m_ui->checkBoxSolid->setChecked(m_object.solid); m_ui->spinBoxDepth->setValue(m_object.depth); m_ui->checkBoxPersistent->setChecked(m_object.persistent); + m_ui->lineEditSprite->setMenu(m_menuSprites); + m_ui->listViewEvents->setModel(m_eventsModel.get()); connect(&m_projectModel, &ProjectTreeModel::objectNameChanged, @@ -53,6 +54,8 @@ ObjectPropertiesDialog::ObjectPropertiesDialog(Object &object, ProjectTreeModel connect(m_eventsModel.get(), &QAbstractItemModel::modelReset, this, &ObjectPropertiesDialog::changed); + connect(m_eventsModel.get(), &QAbstractItemModel::rowsInserted, + this, &ObjectPropertiesDialog::rowsInserted); connect(m_eventsModel.get(), &QAbstractItemModel::rowsInserted, this, &ObjectPropertiesDialog::changed); connect(m_eventsModel.get(), &QAbstractItemModel::dataChanged, @@ -116,7 +119,12 @@ void ObjectPropertiesDialog::accept() } } - m_object.spriteName = m_spriteName; + if (!m_projectModel.setObjectSpriteName(m_object, std::move(m_spriteName))) + { + QMessageBox::critical(this, tr("Setting Object Sprite failed!"), tr("Setting Object Sprite failed!")); + return; + } + m_object.visible = m_ui->checkBoxVisible->isChecked(); m_object.solid = m_ui->checkBoxSolid->isChecked(); m_object.depth = m_ui->spinBoxDepth->value(); @@ -328,6 +336,11 @@ void ObjectPropertiesDialog::eventsContextMenuRequested(const QPoint &pos) menu.exec(m_ui->listViewEvents->viewport()->mapToGlobal(pos)); } +void ObjectPropertiesDialog::rowsInserted(const QModelIndex &parent, int first) +{ + m_ui->listViewEvents->setCurrentIndex(m_eventsModel->index(first, 0, parent)); +} + void ObjectPropertiesDialog::clearSprite() { m_spriteName.clear(); diff --git a/src/editor/dialogs/objectpropertiesdialog.h b/src/editor/dialogs/objectpropertiesdialog.h index bdf4c46..031a377 100644 --- a/src/editor/dialogs/objectpropertiesdialog.h +++ b/src/editor/dialogs/objectpropertiesdialog.h @@ -42,6 +42,7 @@ private slots: void spritesMenuAboutToShow(); void currentEventChanged(const QModelIndex &index); void eventsContextMenuRequested(const QPoint &pos); + void rowsInserted(const QModelIndex &parent, int first); void clearSprite(); void setSprite(const Sprite &sprite); diff --git a/src/editor/dialogs/objectpropertiesdialog.ui b/src/editor/dialogs/objectpropertiesdialog.ui index 4e391f1..7f20d83 100644 --- a/src/editor/dialogs/objectpropertiesdialog.ui +++ b/src/editor/dialogs/objectpropertiesdialog.ui @@ -77,7 +77,7 @@ - + The sprite used to represent the object @@ -414,6 +414,11 @@
widgets/actionscontainerwidget.h
1 + + QLineEditWithMenu + QLineEdit +
widgets/qlineeditwithmenu.h
+
diff --git a/src/editor/dialogs/roompropertiesdialog.cpp b/src/editor/dialogs/roompropertiesdialog.cpp index 5e79760..3e01f7a 100644 --- a/src/editor/dialogs/roompropertiesdialog.cpp +++ b/src/editor/dialogs/roompropertiesdialog.cpp @@ -4,6 +4,7 @@ #include #include #include +#include #include #include @@ -19,6 +20,7 @@ RoomPropertiesDialog::RoomPropertiesDialog(Room &room, ProjectTreeModel &project m_creationCode{m_room.creationCode}, m_spinBoxSnapX{new QSpinBox{this}}, m_spinBoxSnapY{new QSpinBox{this}}, + m_menuObjects{new QMenu{this}}, m_labelX{new QLabel{tr("x: %0").arg(0)}}, m_labelY{new QLabel{tr("y: %0").arg(0)}} { @@ -71,7 +73,13 @@ RoomPropertiesDialog::RoomPropertiesDialog(Room &room, ProjectTreeModel &project m_ui->toolBar->addWidget(toolButton); } - m_ui->scrollArea->setBackgroundRole(QPalette::Dark); + m_ui->toolButtonObject->setMenu(m_menuObjects); + + m_ui->lineEditObject->setMenu(m_menuObjects); + + m_ui->scrollAreaObject->setMenu(m_menuObjects); + + m_ui->scrollAreaRoom->setBackgroundRole(QPalette::Dark); m_labelX->setFrameStyle(QFrame::Sunken); m_ui->statusbar->addWidget(m_labelX, 1); @@ -93,6 +101,14 @@ RoomPropertiesDialog::RoomPropertiesDialog(Room &room, ProjectTreeModel &project connect(&m_projectModel, &ProjectTreeModel::roomNameChanged, this, &RoomPropertiesDialog::roomNameChanged); + connect(&m_projectModel, &ProjectTreeModel::spritePixmapsChanged, + this, &RoomPropertiesDialog::spritePixmapsChanged); + connect(&m_projectModel, &ProjectTreeModel::objectNameChanged, + this, &RoomPropertiesDialog::objectNameChanged); + connect(&m_projectModel, &ProjectTreeModel::objectAboutToBeRemoved, + this, &RoomPropertiesDialog::objectAboutToBeRemoved); + connect(&m_projectModel, &ProjectTreeModel::objectSpriteNameChanged, + this, &RoomPropertiesDialog::objectSpriteNameChanged); connect(m_ui->actionUndo, &QAction::triggered, this, &RoomPropertiesDialog::undo); @@ -158,6 +174,12 @@ RoomPropertiesDialog::RoomPropertiesDialog(Room &room, ProjectTreeModel &project m_ui->actionIsometricGrid, &QAction::setChecked); connect(m_ui->roomEditWidget, &RoomEditWidget::cursorMoved, this, &RoomPropertiesDialog::cursorMoved); + + connect(m_menuObjects, &QMenu::aboutToShow, + this, &RoomPropertiesDialog::objectsMenuAboutToShow); + + if (!m_projectModel.project()->objects.empty()) + setObject(m_projectModel.project()->objects.back()); } RoomPropertiesDialog::~RoomPropertiesDialog() = default; @@ -291,12 +313,111 @@ void RoomPropertiesDialog::roomNameChanged(const Room &room) updateTitle(); } +void RoomPropertiesDialog::spritePixmapsChanged(const Sprite &sprite) +{ + if (!m_selectedObject) + return; + + if (m_selectedObject->spriteName.isEmpty()) + return; + + if (m_selectedObject->spriteName != sprite.name) + return; + + QPixmap pixmap; + if (!sprite.pixmaps.empty() && !sprite.pixmaps.front().isNull()) + pixmap = sprite.pixmaps.front(); + m_ui->labelObjectPreview->setPixmap(std::move(pixmap)); +} + +void RoomPropertiesDialog::objectNameChanged(const Object &object) +{ + if (!m_selectedObject) + return; + + if (&object != m_selectedObject) + return; + + m_ui->lineEditObject->setText(object.name); +} + +void RoomPropertiesDialog::objectAboutToBeRemoved(const Object &object) +{ + if (!m_selectedObject) + return; + + if (&object != m_selectedObject) + return; + + m_selectedObject = nullptr; + m_ui->lineEditObject->clear(); + m_ui->labelObjectPreview->setPixmap({}); +} + +void RoomPropertiesDialog::objectSpriteNameChanged(const Object &object) +{ + if (!m_selectedObject) + return; + + if (&object != m_selectedObject) + return; + + QPixmap pixmap; + if (!object.spriteName.isEmpty()) + { + const auto iter = std::find_if(std::cbegin(m_projectModel.project()->sprites), std::cend(m_projectModel.project()->sprites), + [&object](const auto &sprite){ return object.spriteName == sprite.name; }); + if (iter == std::cend(m_projectModel.project()->sprites)) + qWarning() << "invalid sprite" << object.spriteName; + else if (!iter->pixmaps.empty() && !iter->pixmaps.front().isNull()) + pixmap = iter->pixmaps.front(); + } + m_ui->labelObjectPreview->setPixmap(std::move(pixmap)); +} + +void RoomPropertiesDialog::objectsMenuAboutToShow() +{ + m_menuObjects->clear(); + for (const auto &object : m_projectModel.project()->objects) + { + QIcon icon; + if (!object.spriteName.isEmpty()) + { + const auto iter = std::find_if(std::cbegin(m_projectModel.project()->sprites), std::cend(m_projectModel.project()->sprites), + [&object](const auto &sprite){ return object.spriteName == sprite.name; }); + if (iter == std::cend(m_projectModel.project()->sprites)) + qWarning() << "invalid sprite" << object.spriteName; + else if (!iter->pixmaps.empty() && !iter->pixmaps.front().isNull()) + icon = iter->pixmaps.front(); + } + m_menuObjects->addAction(icon, object.name, this, + [&object,this](){ setObject(object); }); + } +} + void RoomPropertiesDialog::cursorMoved(const QPoint &point) { m_labelX->setText(tr("X: %0").arg(point.x())); m_labelY->setText(tr("Y: %0").arg(point.y())); } +void RoomPropertiesDialog::setObject(const Object &object) +{ + m_selectedObject = &object; + QPixmap pixmap; + if (!object.spriteName.isEmpty()) + { + const auto iter = std::find_if(std::cbegin(m_projectModel.project()->sprites), std::cend(m_projectModel.project()->sprites), + [&object](const auto &sprite){ return object.spriteName == sprite.name; }); + if (iter == std::cend(m_projectModel.project()->sprites)) + qWarning() << "invalid sprite" << object.spriteName; + else if (!iter->pixmaps.empty() && !iter->pixmaps.front().isNull()) + pixmap = iter->pixmaps.front(); + } + m_ui->labelObjectPreview->setPixmap(std::move(pixmap)); + m_ui->lineEditObject->setText(object.name); +} + void RoomPropertiesDialog::updateTitle() { setWindowTitle(tr("Room Properties: %0%1") diff --git a/src/editor/dialogs/roompropertiesdialog.h b/src/editor/dialogs/roompropertiesdialog.h index 48e4e76..8c452ef 100644 --- a/src/editor/dialogs/roompropertiesdialog.h +++ b/src/editor/dialogs/roompropertiesdialog.h @@ -6,8 +6,11 @@ class QSpinBox; class QLabel; +class QMenu; namespace Ui { class RoomPropertiesDialog; } struct Room; +struct Sprite; +struct Object; class ProjectTreeModel; class RoomPropertiesDialog : public QDialog @@ -34,10 +37,17 @@ private slots: void changed(); void roomNameChanged(const Room &room); + void spritePixmapsChanged(const Sprite &sprite); + void objectNameChanged(const Object &object); + void objectAboutToBeRemoved(const Object &object); + void objectSpriteNameChanged(const Object &object); + + void objectsMenuAboutToShow(); void cursorMoved(const QPoint &point); private: + void setObject(const Object &object); void updateTitle(); const std::unique_ptr m_ui; @@ -52,6 +62,10 @@ private: QSpinBox * const m_spinBoxSnapX; QSpinBox * const m_spinBoxSnapY; + QMenu * const m_menuObjects; + QLabel * const m_labelX; QLabel * const m_labelY; + + const Object *m_selectedObject{}; }; diff --git a/src/editor/dialogs/roompropertiesdialog.ui b/src/editor/dialogs/roompropertiesdialog.ui index 8cd6f35..a9788c7 100644 --- a/src/editor/dialogs/roompropertiesdialog.ui +++ b/src/editor/dialogs/roompropertiesdialog.ui @@ -105,19 +105,99 @@ &Objects - + - 10 + 0 - 10 + 0 - 10 + 0 - 10 + 0 + + + + true + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop + + + + + 0 + 0 + 222 + 331 + + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop + + + + + + + + QFrame::StyledPanel + + + QFrame::Raised + + + + + + Object to add with left mouse: + + + + + + + + + true + + + + + + + ... + + + QToolButton::InstantPopup + + + + + + + + + Left mouse button = add<br/> + &lt;Alt&gt; = no snap<br/> + &lt;Shift&gt; = multiple<br/> + &lt;Ctrl&gt; = move<br/>Right mouse button = delete<br/> + &lt;Shift&gt; = delete all<br/> + &lt;Ctrl&gt; = popup menu + + + + + + + Delete underlaying + + + true + + + + + +
@@ -302,7 +382,10 @@ - + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop + @@ -512,6 +595,17 @@
widgets/roomeditwidget.h
1 + + QLineEditWithMenu + QLineEdit +
widgets/qlineeditwithmenu.h
+
+ + QScrollAreaWithMenu + QScrollArea +
widgets/qscrollareawithmenu.h
+ 1 +
diff --git a/src/editor/mainwindow.cpp b/src/editor/mainwindow.cpp index f42142c..880ff04 100644 --- a/src/editor/mainwindow.cpp +++ b/src/editor/mainwindow.cpp @@ -740,7 +740,13 @@ void MainWindow::setupStylesMenu() return QString{}; } - return style->name(); + return style-> +#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0) + name +#else + objectName +#endif + (); }(); if (name.isEmpty()) @@ -754,11 +760,16 @@ void MainWindow::setupStylesMenu() return; } QApplication::setStyle(style); - qDebug() << style->name(); }); m_actionGroupStyles->addAction(action); action->setCheckable(true); - action->setChecked(currentStyle && currentStyle->name() == name); + action->setChecked(currentStyle && currentStyle-> +#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0) + name +#else + objectName +#endif + () == name); } } diff --git a/src/editor/models/objecteventsmodel.cpp b/src/editor/models/objecteventsmodel.cpp index 014d6ca..3e26084 100644 --- a/src/editor/models/objecteventsmodel.cpp +++ b/src/editor/models/objecteventsmodel.cpp @@ -92,9 +92,32 @@ bool ObjectEventsModel::addEvent(Object::EventType eventType) return false; } - beginResetModel(); - m_events[eventType]; - endResetModel(); + // temporary copy to find row before inserting, as its needed for beginInsertRows() + auto tempevents = m_events; + + const auto &tempInsertResult = tempevents.insert(std::make_pair(eventType, ActionsContainer{})); + if (!tempInsertResult.second) + { + qWarning() << "temp inserting failed!"; + return false; + } + + const auto tempNewRow = std::distance(std::begin(tempevents), tempInsertResult.first); + + + beginInsertRows({}, tempNewRow, tempNewRow); + + const auto &insertResult = m_events.insert(std::make_pair(eventType, ActionsContainer{})); + if (!insertResult.second) + { + qWarning() << "inserting failed!"; + return false; + } + + const auto newRow = std::distance(std::begin(m_events), insertResult.first); + Q_ASSERT(tempNewRow == newRow); + + endInsertRows(); return true; } @@ -108,11 +131,46 @@ bool ObjectEventsModel::changeEvent(Object::EventType eventType, Object::EventTy return false; } - beginResetModel(); - auto value = std::move(iter->second); + if (eventType == newEventType) + { + qWarning() << "same event again"; + return true; + } + + auto container = std::move(iter->second); + + const auto oldRow = std::distance(std::begin(m_events), iter); + + beginRemoveRows({}, oldRow, oldRow); m_events.erase(iter); - m_events[newEventType] = std::move(value); - endResetModel(); + endRemoveRows(); + + // temporary copy to find row before inserting, as its needed for beginInsertRows() + auto tempevents = m_events; + + const auto &tempInsertResult = tempevents.insert(std::make_pair(newEventType, ActionsContainer{})); + if (!tempInsertResult.second) + { + qWarning() << "temp inserting failed!"; + return false; + } + + const auto tempNewRow = std::distance(std::begin(tempevents), tempInsertResult.first); + + + beginInsertRows({}, tempNewRow, tempNewRow); + + const auto &insertResult = m_events.insert(std::make_pair(newEventType, std::move(container))); + if (!insertResult.second) + { + qWarning() << "inserting failed!"; + return false; + } + + const auto newRow = std::distance(std::begin(m_events), insertResult.first); + Q_ASSERT(tempNewRow == newRow); + + endInsertRows(); return true; } @@ -126,9 +184,11 @@ bool ObjectEventsModel::removeEvent(Object::EventType eventType) return false; } - beginResetModel(); + const auto row = std::distance(std::begin(m_events), iter); + + beginRemoveRows({}, row, row); m_events.erase(iter); - endResetModel(); + endRemoveRows(); return true; } diff --git a/src/editor/models/pathpointsmodel.h b/src/editor/models/pathpointsmodel.h index 9d136f6..94fc0a6 100644 --- a/src/editor/models/pathpointsmodel.h +++ b/src/editor/models/pathpointsmodel.h @@ -3,6 +3,7 @@ #include #include +#include #include "projectcontainer.h" diff --git a/src/editor/models/projecttreemodel.cpp b/src/editor/models/projecttreemodel.cpp index bb1cdcf..ff7eda9 100644 --- a/src/editor/models/projecttreemodel.cpp +++ b/src/editor/models/projecttreemodel.cpp @@ -660,6 +660,37 @@ bool ProjectTreeModel::setBackgroundPixmap(const Background &background, QPixmap return true; } +bool ProjectTreeModel::setObjectSpriteName(const Object &object, QString &&spriteName) +{ + if (!m_project) + { + qWarning() << "unexpected null project"; + return false; + } + + auto &container = m_project->objects; + const auto iter = std::find_if(std::begin(container), std::end(container), + [&object](const auto &otherEntry){ return &object == &otherEntry; }); + if (iter == std::cend(container)) + { + qWarning() << "object not from this project!"; + return false; + } + + if (iter->spriteName == spriteName) + return true; + + auto oldSpriteName = std::move(iter->spriteName); + iter->spriteName = std::move(spriteName); + + const auto index = this->index(std::distance(std::begin(container), iter), 0, rootFor()); + emit dataChanged(index, index, { Qt::DecorationRole }); + + emit objectSpriteNameChanged(object, std::move(oldSpriteName)); + + return true; +} + template QVariant ProjectTreeModel::dataFor(const QModelIndex &index, int role) const { diff --git a/src/editor/models/projecttreemodel.h b/src/editor/models/projecttreemodel.h index aeff49e..56c0f6a 100644 --- a/src/editor/models/projecttreemodel.h +++ b/src/editor/models/projecttreemodel.h @@ -73,6 +73,8 @@ public: bool setBackgroundPixmap(const Background &background, QPixmap &&pixmap); + bool setObjectSpriteName(const Object &object, QString &&spriteName); + signals: void errorOccured(const QString &message); @@ -82,9 +84,9 @@ signals: void pathCreated(const Path &path); void scriptCreated(const Script &script); void fontCreated(const Font &font); - void timeLineCreated(const TimeLine &font); - void objectCreated(const Object &font); - void roomCreated(const Room &font); + void timeLineCreated(const TimeLine &timeLine); + void objectCreated(const Object &object); + void roomCreated(const Room &room); void spriteAboutToBeRemoved(const Sprite &sprite); void soundAboutToBeRemoved(const Sound &sound); @@ -92,9 +94,9 @@ signals: void pathAboutToBeRemoved(const Path &path); void scriptAboutToBeRemoved(const Script &script); void fontAboutToBeRemoved(const Font &font); - void timeLineAboutToBeRemoved(const TimeLine &font); - void objectAboutToBeRemoved(const Object &font); - void roomAboutToBeRemoved(const Room &font); + void timeLineAboutToBeRemoved(const TimeLine &timeLine); + void objectAboutToBeRemoved(const Object &object); + void roomAboutToBeRemoved(const Room &room); void spriteNameChanged(const Sprite &sprite, const QString &oldName); void soundNameChanged(const Sound &sound, const QString &oldName); @@ -102,9 +104,9 @@ signals: void pathNameChanged(const Path &path, const QString &oldName); void scriptNameChanged(const Script &script, const QString &oldName); void fontNameChanged(const Font &font, const QString &oldName); - void timeLineNameChanged(const TimeLine &font, const QString &oldName); - void objectNameChanged(const Object &font, const QString &oldName); - void roomNameChanged(const Room &font, const QString &oldName); + void timeLineNameChanged(const TimeLine &timeLine, const QString &oldName); + void objectNameChanged(const Object &object, const QString &oldName); + void roomNameChanged(const Room &room, const QString &oldName); void spritePixmapsChanged(const Sprite &sprite); diff --git a/src/editor/widgets/qlineeditwithmenu.cpp b/src/editor/widgets/qlineeditwithmenu.cpp new file mode 100644 index 0000000..b660d94 --- /dev/null +++ b/src/editor/widgets/qlineeditwithmenu.cpp @@ -0,0 +1,14 @@ +#include "qlineeditwithmenu.h" + +#include +#include + +void QLineEditWithMenu::mousePressEvent(QMouseEvent *event) +{ + QLineEdit::mousePressEvent(event); + + if (!m_menu) + return; + + m_menu->exec(mapToGlobal(event->pos())); +} diff --git a/src/editor/widgets/qlineeditwithmenu.h b/src/editor/widgets/qlineeditwithmenu.h new file mode 100644 index 0000000..bb018c9 --- /dev/null +++ b/src/editor/widgets/qlineeditwithmenu.h @@ -0,0 +1,23 @@ +#pragma once + +#include + +class QMenu; + +class QLineEditWithMenu : public QLineEdit +{ + Q_OBJECT + +public: + using QLineEdit::QLineEdit; + + QMenu *menu() { return m_menu; } + const QMenu *menu() const { return m_menu; } + void setMenu(QMenu *menu) { m_menu = menu; } + +protected: + void mousePressEvent(QMouseEvent *event) override; + +private: + QMenu *m_menu{}; +}; diff --git a/src/editor/widgets/qscrollareawithmenu.cpp b/src/editor/widgets/qscrollareawithmenu.cpp new file mode 100644 index 0000000..34fd141 --- /dev/null +++ b/src/editor/widgets/qscrollareawithmenu.cpp @@ -0,0 +1,14 @@ +#include "qscrollareawithmenu.h" + +#include +#include + +void QScrollAreaWithMenu::mousePressEvent(QMouseEvent *event) +{ + QScrollArea::mousePressEvent(event); + + if (!m_menu) + return; + + m_menu->exec(mapToGlobal(event->pos())); +} diff --git a/src/editor/widgets/qscrollareawithmenu.h b/src/editor/widgets/qscrollareawithmenu.h new file mode 100644 index 0000000..bff6d69 --- /dev/null +++ b/src/editor/widgets/qscrollareawithmenu.h @@ -0,0 +1,23 @@ +#pragma once + +#include + +class QMenu; + +class QScrollAreaWithMenu : public QScrollArea +{ + Q_OBJECT + +public: + using QScrollArea::QScrollArea; + + QMenu *menu() { return m_menu; } + const QMenu *menu() const { return m_menu; } + void setMenu(QMenu *menu) { m_menu = menu; } + +protected: + void mousePressEvent(QMouseEvent *event) override; + +private: + QMenu *m_menu{}; +};