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();