diff --git a/forms/mainwindow.ui b/forms/mainwindow.ui
index 057df05d..7c2d45ba 100644
--- a/forms/mainwindow.ui
+++ b/forms/mainwindow.ui
@@ -2882,6 +2882,7 @@
+
@@ -3236,6 +3237,17 @@
Show Dive/Emerge Map
+
+
+ true
+
+
+ false
+
+
+ Show Events in Map View
+
+
true
diff --git a/include/config.h b/include/config.h
index 6eb84470..7f263da0 100644
--- a/include/config.h
+++ b/include/config.h
@@ -81,6 +81,7 @@ public:
this->projectSettingsTab = 0;
this->warpBehaviorWarningDisabled = false;
this->eventDeleteWarningDisabled = false;
+ this->eventOverlayEnabled = false;
this->checkForUpdates = true;
this->lastUpdateCheckTime = QDateTime();
this->lastUpdateCheckVersion = porymapVersion;
@@ -136,6 +137,7 @@ public:
int projectSettingsTab;
bool warpBehaviorWarningDisabled;
bool eventDeleteWarningDisabled;
+ bool eventOverlayEnabled;
bool checkForUpdates;
QDateTime lastUpdateCheckTime;
QVersionNumber lastUpdateCheckVersion;
diff --git a/include/editor.h b/include/editor.h
index 0c11a1e8..689d2f4f 100644
--- a/include/editor.h
+++ b/include/editor.h
@@ -119,6 +119,7 @@ public:
void redrawEvents(const QList &events);
void redrawEventPixmapItem(DraggablePixmapItem *item);
QList getEventPixmapItems();
+ qreal getEventOpacity(const Event *event) const;
void updateCursorRectPos(int x, int y);
void setCursorRectVisible(bool visible);
@@ -161,21 +162,11 @@ public:
EditAction eventEditAction = EditAction::Select;
enum class EditMode { None, Disabled, Metatiles, Collision, Header, Events, Connections, Encounters };
- EditMode editMode = EditMode::None;
- void setEditMode(EditMode mode) { this->editMode = mode; }
- EditMode getEditMode() { return this->editMode; }
+ void setEditMode(EditMode editMode);
+ EditMode getEditMode() const { return this->editMode; }
bool getEditingLayout();
- void setEditorView();
-
- void setEditingMetatiles();
- void setEditingCollision();
- void setEditingHeader();
- void setEditingEvents();
- void setEditingConnections();
- void setEditingEncounters();
-
void setMapEditingButtonsEnabled(bool enabled);
int scaleIndex = 2;
@@ -211,6 +202,8 @@ private:
const QImage collisionPlaceholder = QImage(":/images/collisions_unknown.png");
QPixmap collisionSheetPixmap;
+ EditMode editMode = EditMode::None;
+
void clearMap();
void clearMetatileSelector();
void clearMovementPermissionSelector();
diff --git a/include/mainwindow.h b/include/mainwindow.h
index 2d065b37..805899a1 100644
--- a/include/mainwindow.h
+++ b/include/mainwindow.h
@@ -261,6 +261,7 @@ private slots:
void on_checkBox_MirrorConnections_stateChanged(int selected);
void on_actionDive_Emerge_Map_triggered();
+ void on_actionShow_Events_In_Map_View_triggered();
void on_groupBox_DiveMapOpacity_toggled(bool on);
void on_slider_DiveEmergeMapOpacity_valueChanged(int value);
void on_slider_DiveMapOpacity_valueChanged(int value);
diff --git a/src/config.cpp b/src/config.cpp
index a61393ab..b22972a4 100644
--- a/src/config.cpp
+++ b/src/config.cpp
@@ -394,6 +394,8 @@ void PorymapConfig::parseConfigKeyValue(QString key, QString value) {
this->warpBehaviorWarningDisabled = getConfigBool(key, value);
} else if (key == "event_delete_warning_disabled") {
this->eventDeleteWarningDisabled = getConfigBool(key, value);
+ } else if (key == "event_overlay_enabled") {
+ this->eventOverlayEnabled = getConfigBool(key, value);
} else if (key == "check_for_updates") {
this->checkForUpdates = getConfigBool(key, value);
} else if (key == "last_update_check_time") {
@@ -479,6 +481,7 @@ QMap PorymapConfig::getKeyValueMap() {
map.insert("project_settings_tab", QString::number(this->projectSettingsTab));
map.insert("warp_behavior_warning_disabled", QString::number(this->warpBehaviorWarningDisabled));
map.insert("event_delete_warning_disabled", QString::number(this->eventDeleteWarningDisabled));
+ map.insert("event_overlay_enabled", QString::number(this->eventOverlayEnabled));
map.insert("check_for_updates", QString::number(this->checkForUpdates));
map.insert("last_update_check_time", this->lastUpdateCheckTime.toUTC().toString());
map.insert("last_update_check_version", this->lastUpdateCheckVersion.toString());
diff --git a/src/editor.cpp b/src/editor.cpp
index a160f462..6a2e0c20 100644
--- a/src/editor.cpp
+++ b/src/editor.cpp
@@ -113,8 +113,12 @@ bool Editor::getEditingLayout() {
return this->editMode == EditMode::Metatiles || this->editMode == EditMode::Collision;
}
-void Editor::setEditorView() {
- // based on editMode
+void Editor::setEditMode(EditMode editMode) {
+ // At the moment we can't early return if editMode == this->editMode, because this function also takes care of refreshing the map view.
+ // The main window relies on this when switching projects (the edit mode will remain the same, but it needs a refresh).
+ auto oldEditMode = this->editMode;
+ this->editMode = editMode;
+
if (!map_item || !collision_item) return;
if (!this->layout) return;
@@ -132,70 +136,34 @@ void Editor::setEditorView() {
break;
default:
current_view = nullptr;
- return;
+ break;
}
map_item->setEditsEnabled(this->editMode != EditMode::Connections);
map_item->draw();
collision_item->draw();
- current_view->setVisible(true);
+ if (current_view) current_view->setVisible(true);
updateBorderVisibility();
QUndoStack *editStack = this->map ? this->map->editHistory() : nullptr;
- bool usesCursor = false;
- if (this->editMode == EditMode::Metatiles || this->editMode == EditMode::Collision) {
- if (this->layout) editStack = &this->layout->editHistory;
- usesCursor = true;
+ bool editingLayout = getEditingLayout();
+ if (editingLayout && this->layout) {
+ editStack = &this->layout->editHistory;
}
-
this->cursorMapTileRect->setSingleTileMode();
- this->cursorMapTileRect->setActive(usesCursor);
+ this->cursorMapTileRect->setActive(editingLayout);
this->editGroup.setActiveStack(editStack);
+ setMapEditingButtonsEnabled(editingLayout);
-
- if (this->events_group) {
- this->events_group->setVisible(this->editMode == EditMode::Events);
+ if (this->editMode == EditMode::Events || oldEditMode == EditMode::Events) {
+ // When switching to or from the Events tab the opacity of the events changes. Redraw the events to reflect that change.
+ redrawAllEvents();
+ }
+ if (this->editMode == EditMode::Events){
+ updateWarpEventWarnings();
}
- setMapEditingButtonsEnabled(this->editMode != EditMode::Events);
-}
-
-void Editor::setEditingMetatiles() {
- this->editMode = EditMode::Metatiles;
-
- setEditorView();
-}
-
-void Editor::setEditingCollision() {
- this->editMode = EditMode::Collision;
-
- setEditorView();
-}
-
-void Editor::setEditingHeader() {
- this->editMode = EditMode::Header;
-
- setEditorView();
-}
-
-void Editor::setEditingEvents() {
- this->editMode = EditMode::Events;
-
- setEditorView();
- updateWarpEventWarnings();
-}
-
-void Editor::setEditingConnections() {
- this->editMode = EditMode::Connections;
-
- setEditorView();
-}
-
-void Editor::setEditingEncounters() {
- this->editMode = EditMode::Encounters;
-
- setEditorView();
}
void Editor::setMapEditingButtonsEnabled(bool enabled) {
@@ -1486,10 +1454,6 @@ bool Editor::displayMap() {
displayMapEvents();
displayMapConnections();
maskNonVisibleConnectionTiles();
-
- if (events_group) {
- events_group->setVisible(false);
- }
return true;
}
@@ -2003,20 +1967,40 @@ QList Editor::getEventPixmapItems() {
return list;
}
+qreal Editor::getEventOpacity(const Event *event) const {
+ // There are 4 possible opacities for an event's sprite:
+ // - Off the Events tab, and the event overlay is off (0.0)
+ // - Off the Events tab, and the event overlay is on (0.5)
+ // - On the Events tab, and the event has a default sprite (0.7)
+ // - On the Events tab, and the event has a custom sprite (1.0)
+ if (this->editMode != EditMode::Events)
+ return porymapConfig.eventOverlayEnabled ? 0.5 : 0.0;
+ return event->getUsingSprite() ? 1.0 : 0.7;
+}
+
void Editor::redrawEventPixmapItem(DraggablePixmapItem *item) {
if (item && item->event && !item->event->getPixmap().isNull()) {
- qreal opacity = item->event->getUsingSprite() ? 1.0 : 0.7;
- item->setOpacity(opacity);
+ item->setOpacity(getEventOpacity(item->event));
project->setEventPixmap(item->event, true);
item->setPixmap(item->event->getPixmap());
item->setShapeMode(porymapConfig.eventSelectionShapeMode);
- if (selected_events && selected_events->contains(item)) {
- QImage image = item->pixmap().toImage();
- QPainter painter(&image);
- painter.setPen(QColor(255, 0, 255));
- painter.drawRect(0, 0, image.width() - 1, image.height() - 1);
- painter.end();
- item->setPixmap(QPixmap::fromImage(image));
+
+ if (this->editMode == EditMode::Events) {
+ if (selected_events && selected_events->contains(item)) {
+ // Draw the selection rectangle
+ QImage image = item->pixmap().toImage();
+ QPainter painter(&image);
+ painter.setPen(QColor(255, 0, 255));
+ painter.drawRect(0, 0, image.width() - 1, image.height() - 1);
+ painter.end();
+ item->setPixmap(QPixmap::fromImage(image));
+ }
+ item->setAcceptedMouseButtons(Qt::AllButtons);
+ } else {
+ // Can't interact with event pixmaps outside of event editing mode.
+ // We could do setEnabled(false), but rather than ignoring the mouse events this
+ // would reject them, which would prevent painting on the map behind the events.
+ item->setAcceptedMouseButtons(Qt::NoButton);
}
item->updatePosition();
}
diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp
index 3f359d0e..a38b3bd0 100644
--- a/src/mainwindow.cpp
+++ b/src/mainwindow.cpp
@@ -525,17 +525,11 @@ void MainWindow::loadUserSettings() {
ui->actionCursor_Tile_Outline->setChecked(porymapConfig.showCursorTile);
this->editor->settings->cursorTileRectEnabled = porymapConfig.showCursorTile;
- // Border
- ui->checkBox_ToggleBorder->setChecked(porymapConfig.showBorder);
-
// Grid
const QSignalBlocker b_Grid(ui->checkBox_ToggleGrid);
ui->actionShow_Grid->setChecked(porymapConfig.showGrid);
ui->checkBox_ToggleGrid->setChecked(porymapConfig.showGrid);
- // Mirror connections
- ui->checkBox_MirrorConnections->setChecked(porymapConfig.mirrorConnectingMaps);
-
// Collision opacity/transparency
const QSignalBlocker b_CollisionTransparency(ui->horizontalSlider_CollisionTransparency);
this->editor->collisionOpacity = static_cast(porymapConfig.collisionOpacity) / 100;
@@ -555,6 +549,10 @@ void MainWindow::loadUserSettings() {
ui->horizontalSlider_MetatileZoom->setValue(porymapConfig.metatilesZoom);
ui->horizontalSlider_CollisionZoom->setValue(porymapConfig.collisionZoom);
+ ui->checkBox_MirrorConnections->setChecked(porymapConfig.mirrorConnectingMaps);
+ ui->checkBox_ToggleBorder->setChecked(porymapConfig.showBorder);
+ ui->actionShow_Events_In_Map_View->setChecked(porymapConfig.eventOverlayEnabled);
+
setTheme(porymapConfig.theme);
setDivingMapsVisible(porymapConfig.showDiveEmergeMaps);
}
@@ -1787,14 +1785,20 @@ void MainWindow::on_mapViewTab_tabBarClicked(int index)
if (index != oldIndex)
Scripting::cb_MapViewTabChanged(oldIndex, index);
+ static const QMap tabIndexToEditMode = {
+ {MapViewTab::Metatiles, Editor::EditMode::Metatiles},
+ {MapViewTab::Collision, Editor::EditMode::Collision},
+ {MapViewTab::Prefabs, Editor::EditMode::Metatiles},
+ };
+ if (tabIndexToEditMode.contains(index)) {
+ editor->setEditMode(tabIndexToEditMode.value(index));
+ }
+
if (index == MapViewTab::Metatiles) {
- editor->setEditingMetatiles();
refreshMetatileViews();
} else if (index == MapViewTab::Collision) {
- editor->setEditingCollision();
refreshCollisionSelector();
} else if (index == MapViewTab::Prefabs) {
- editor->setEditingMetatiles();
if (projectConfig.prefabFilepath.isEmpty() && !projectConfig.prefabImportPrompted) {
// User hasn't set up prefabs and hasn't been prompted before.
// Ask if they'd like to import the default prefabs file.
@@ -1821,19 +1825,26 @@ void MainWindow::on_mainTabBar_tabBarClicked(int index)
};
ui->mainStackedWidget->setCurrentIndex(tabIndexToStackIndex.value(index));
+ static const QMap tabIndexToEditMode = {
+ // MainTab::Map itself has no edit mode, depends on mapViewTab.
+ {MainTab::Events, Editor::EditMode::Events},
+ {MainTab::Header, Editor::EditMode::Header},
+ {MainTab::Connections, Editor::EditMode::Connections},
+ {MainTab::WildPokemon, Editor::EditMode::Encounters},
+ };
+ if (tabIndexToEditMode.contains(index)) {
+ editor->setEditMode(tabIndexToEditMode.value(index));
+ }
+
if (index == MainTab::Map) {
ui->stackedWidget_MapEvents->setCurrentIndex(0);
on_mapViewTab_tabBarClicked(ui->mapViewTab->currentIndex());
clickToolButtonFromEditAction(editor->mapEditAction);
} else if (index == MainTab::Events) {
ui->stackedWidget_MapEvents->setCurrentIndex(1);
- editor->setEditingEvents();
clickToolButtonFromEditAction(editor->eventEditAction);
} else if (index == MainTab::Connections) {
- editor->setEditingConnections();
ui->graphicsView_Connections->setFocus(); // Avoid opening tab with focus on something editable
- } else if (index == MainTab::WildPokemon) {
- editor->setEditingEncounters();
}
if (!editor->map) return;
@@ -1883,6 +1894,11 @@ void MainWindow::on_actionCursor_Tile_Outline_triggered()
}
}
+void MainWindow::on_actionShow_Events_In_Map_View_triggered() {
+ porymapConfig.eventOverlayEnabled = ui->actionShow_Events_In_Map_View->isChecked();
+ this->editor->redrawAllEvents();
+}
+
void MainWindow::on_actionShow_Grid_triggered() {
this->editor->toggleGrid(ui->actionShow_Grid->isChecked());
}