diff --git a/forms/preferenceeditor.ui b/forms/preferenceeditor.ui index a7009e6e..1133b497 100644 --- a/forms/preferenceeditor.ui +++ b/forms/preferenceeditor.ui @@ -57,6 +57,35 @@ + + + + Event Selection Mode + + + + + + If enabled, an event can be selected by clicking directly on the opaque pixels of its sprite. This may be preferable when events are overlapping. + + + Select by clicking on sprite + + + + + + + If enabled, an event can be selected by clicking anywhere within its sprite dimensions. This may be preferable for events with small or mostly transparent sprites. + + + Select by clicking within bounding rectangle + + + + + + diff --git a/include/config.h b/include/config.h index 502ee1ec..d07b566a 100644 --- a/include/config.h +++ b/include/config.h @@ -11,6 +11,7 @@ #include #include #include +#include #include "events.h" @@ -83,6 +84,7 @@ public: this->lastUpdateCheckTime = QDateTime(); this->lastUpdateCheckVersion = porymapVersion; this->rateLimitTimes.clear(); + this->eventSelectionShapeMode = QGraphicsPixmapItem::MaskShape; } void addRecentProject(QString project); void setRecentProjects(QStringList projects); @@ -136,6 +138,7 @@ public: QDateTime lastUpdateCheckTime; QVersionNumber lastUpdateCheckVersion; QMap rateLimitTimes; + QGraphicsPixmapItem::ShapeMode eventSelectionShapeMode; QByteArray wildMonChartGeometry; QByteArray newMapDialogGeometry; QByteArray newLayoutDialogGeometry; diff --git a/include/editor.h b/include/editor.h index 3e2249f2..5de799db 100644 --- a/include/editor.h +++ b/include/editor.h @@ -116,6 +116,8 @@ public: DraggablePixmapItem *addNewEvent(Event::Type type); void updateSelectedEvents(); void duplicateSelectedEvents(); + void redrawAllEvents(); + void redrawEvents(const QList &events); void redrawEventPixmapItem(DraggablePixmapItem *item); QList getEventPixmapItems(); diff --git a/src/config.cpp b/src/config.cpp index 2356f7a9..744a6394 100644 --- a/src/config.cpp +++ b/src/config.cpp @@ -417,6 +417,14 @@ void PorymapConfig::parseConfigKeyValue(QString key, QString value) { if (match.hasMatch()) { this->rateLimitTimes.insert(match.captured("url"), QDateTime::fromString(value).toLocalTime()); } + } else if (key == "event_selection_shape_mode") { + if (value == "mask") { + this->eventSelectionShapeMode = QGraphicsPixmapItem::MaskShape; + } else if (value == "bounding_rect") { + this->eventSelectionShapeMode = QGraphicsPixmapItem::BoundingRectShape; + } else { + logWarn(QString("Invalid config value for %1: '%2'. Must be 'mask' or 'bounding_rect'.").arg(key).arg(value)); + } } else { logWarn(QString("Invalid config key found in config file %1: '%2'").arg(this->getConfigFilepath()).arg(key)); } @@ -484,6 +492,7 @@ QMap PorymapConfig::getKeyValueMap() { if (!time.isNull() && time > QDateTime::currentDateTime()) map.insert("rate_limit_time/" + i.key().toString(), time.toUTC().toString()); } + map.insert("event_selection_shape_mode", (this->eventSelectionShapeMode == QGraphicsPixmapItem::MaskShape) ? "mask" : "bounding_rect"); return map; } diff --git a/src/editor.cpp b/src/editor.cpp index 6b560ced..2824dd6c 100644 --- a/src/editor.cpp +++ b/src/editor.cpp @@ -1986,6 +1986,16 @@ Tileset* Editor::getCurrentMapPrimaryTileset() return project->getTileset(tilesetLabel); } +void Editor::redrawAllEvents() { + if (this->map) redrawEvents(this->map->getEvents()); +} + +void Editor::redrawEvents(const QList &events) { + for (const auto &event : events) { + redrawEventPixmapItem(event->getPixmapItem()); + } +} + QList Editor::getEventPixmapItems() { QList list; for (QGraphicsItem *child : events_group->childItems()) { @@ -2000,7 +2010,7 @@ void Editor::redrawEventPixmapItem(DraggablePixmapItem *item) { item->setOpacity(opacity); project->setEventPixmap(item->event, true); item->setPixmap(item->event->getPixmap()); - item->setShapeMode(QGraphicsPixmapItem::BoundingRectShape); + item->setShapeMode(porymapConfig.eventSelectionShapeMode); if (selected_events && selected_events->contains(item)) { QImage image = item->pixmap().toImage(); QPainter painter(&image); diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp index c57cdd00..1c204771 100644 --- a/src/mainwindow.cpp +++ b/src/mainwindow.cpp @@ -2754,6 +2754,9 @@ void MainWindow::togglePreferenceSpecificUi() { if (this->updatePromoter) this->updatePromoter->updatePreferences(); + + // Redraw all events to use updated porymapConfig.eventSelectionShapeMode + this->editor->redrawAllEvents(); } void MainWindow::openProjectSettingsEditor(int tab) { diff --git a/src/ui/preferenceeditor.cpp b/src/ui/preferenceeditor.cpp index a51b614d..77a1cbb5 100644 --- a/src/ui/preferenceeditor.cpp +++ b/src/ui/preferenceeditor.cpp @@ -45,6 +45,11 @@ void PreferenceEditor::initFields() { void PreferenceEditor::updateFields() { themeSelector->setCurrentText(porymapConfig.theme); + if (porymapConfig.eventSelectionShapeMode == QGraphicsPixmapItem::MaskShape) { + ui->radioButton_OnSprite->setChecked(true); + } else if (porymapConfig.eventSelectionShapeMode == QGraphicsPixmapItem::BoundingRectShape) { + ui->radioButton_WithinRect->setChecked(true); + } ui->lineEdit_TextEditorOpenFolder->setText(porymapConfig.textEditorOpenFolder); ui->lineEdit_TextEditorGotoLine->setText(porymapConfig.textEditorGotoLine); ui->checkBox_MonitorProjectFiles->setChecked(porymapConfig.monitorFiles); @@ -58,7 +63,7 @@ void PreferenceEditor::saveFields() { porymapConfig.theme = theme; emit themeChanged(theme); } - + porymapConfig.eventSelectionShapeMode = ui->radioButton_OnSprite->isChecked() ? QGraphicsPixmapItem::MaskShape : QGraphicsPixmapItem::BoundingRectShape; porymapConfig.textEditorOpenFolder = ui->lineEdit_TextEditorOpenFolder->text(); porymapConfig.textEditorGotoLine = ui->lineEdit_TextEditorGotoLine->text(); porymapConfig.monitorFiles = ui->checkBox_MonitorProjectFiles->isChecked();