Prevent weird diving map behavior

This commit is contained in:
GriffinR
2025-04-15 12:22:51 -04:00
parent d014eef9e8
commit b1d85d32c1
9 changed files with 87 additions and 13 deletions

View File

@@ -87,6 +87,7 @@ public:
void deleteConnections();
QList<MapConnection*> getConnections() const { return m_connections; }
MapConnection* getConnection(const QString &direction) const;
void removeConnection(MapConnection *);
void addConnection(MapConnection *);
void loadConnection(MapConnection *);

View File

@@ -92,7 +92,8 @@ public:
void setConnectionsVisibility(bool visible);
void updateDivingMapsVisibility();
void renderDivingConnections();
void addConnection(MapConnection* connection);
void addNewConnection(const QString &mapName, const QString &direction);
void replaceConnection(const QString &mapName, const QString &direction);
void removeConnection(MapConnection* connection);
void addNewWildMonGroup(QWidget *window);
void deleteWildMonGroup();

View File

@@ -20,13 +20,16 @@ public:
virtual void accept() override;
signals:
void accepted(MapConnection *result);
void newConnectionedAdded(const QString &mapName, const QString &direction);
void connectionReplaced(const QString &mapName, const QString &direction);
private:
Ui::NewMapConnectionDialog *ui;
Map *m_map;
bool mapNameIsValid();
void setWarningVisible(bool visible);
bool askReplaceConnection(MapConnection *connection, const QString &newMapName);
};
#endif // NEWMAPCONNECTIONDIALOG_H

View File

@@ -288,6 +288,15 @@ void Map::removeConnection(MapConnection *connection) {
emit connectionRemoved(connection);
}
// Return the first map connection that has the given direction.
MapConnection* Map::getConnection(const QString &direction) const {
for (const auto &connection : m_connections) {
if (connection->direction() == direction)
return connection;
}
return nullptr;
}
void Map::commit(QUndoCommand *cmd) {
m_editHistory->push(cmd);
}

View File

@@ -818,19 +818,32 @@ void Editor::displayConnection(MapConnection *connection) {
}
}
void Editor::addConnection(MapConnection *connection) {
if (!connection)
void Editor::addNewConnection(const QString &mapName, const QString &direction) {
if (!this->map)
return;
MapConnection *connection = new MapConnection(mapName, direction);
// Mark this connection to be selected once its display elements have been created.
// It's possible this is a Dive/Emerge connection, but that's ok (no selection will occur).
connection_to_select = connection;
this->connection_to_select = connection;
this->map->commit(new MapConnectionAdd(this->map, connection));
}
void Editor::replaceConnection(const QString &mapName, const QString &direction) {
if (!this->map)
return;
MapConnection *connection = this->map->getConnection(direction);
if (!connection || connection->targetMapName() == mapName)
return;
this->map->commit(new MapConnectionChangeMap(connection, mapName));
}
void Editor::removeConnection(MapConnection *connection) {
if (!connection)
if (!this->map || !connection)
return;
this->map->commit(new MapConnectionRemove(this->map, connection));
}
@@ -948,7 +961,7 @@ bool Editor::setDivingMapName(const QString &mapName, const QString &direction)
}
} else if (!mapName.isEmpty()) {
// Create new connection
addConnection(new MapConnection(mapName, direction));
addNewConnection(mapName, direction);
}
return true;
}

View File

@@ -2588,7 +2588,8 @@ void MainWindow::on_pushButton_AddConnection_clicked() {
return;
auto dialog = new NewMapConnectionDialog(this, this->editor->map, this->editor->project->mapNames);
connect(dialog, &NewMapConnectionDialog::accepted, this->editor, &Editor::addConnection);
connect(dialog, &NewMapConnectionDialog::newConnectionedAdded, this->editor, &Editor::addNewConnection);
connect(dialog, &NewMapConnectionDialog::connectionReplaced, this->editor, &Editor::replaceConnection);
dialog->open();
}

View File

@@ -143,6 +143,8 @@ void ConnectionPixmapItem::mouseDoubleClickEvent(QGraphicsSceneMouseEvent *) {
emit connectionItemDoubleClicked(this->connection);
}
// TODO: Rather than listening for this here and on the list item, listen for it on the connections graphics view,
// and delete whichever map connections are currently selected. This should fix our weird focus requirements in here.
void ConnectionPixmapItem::keyPressEvent(QKeyEvent* event) {
if (event->key() == Qt::Key_Delete || event->key() == Qt::Key_Backspace) {
emit deleteRequested(this->connection);

View File

@@ -100,7 +100,17 @@ void ConnectionsListItem::mousePressEvent(QMouseEvent *) {
void ConnectionsListItem::commitDirection() {
const QString direction = ui->comboBox_Direction->currentText();
if (this->map && this->connection && this->connection->direction() != direction) {
if (!this->connection || this->connection->direction() == direction)
return;
if (MapConnection::isDiving(direction)) {
// Diving maps are displayed separately, no support right now for replacing a list item with a diving map.
// For now just restore the original direction.
ui->comboBox_Direction->setCurrentText(this->connection->direction());
return;
}
if (this->map) {
this->map->commit(new MapConnectionChangeDirection(this->connection, direction));
}
}

View File

@@ -1,9 +1,11 @@
#include "newmapconnectiondialog.h"
#include "ui_newmapconnectiondialog.h"
#include "message.h"
NewMapConnectionDialog::NewMapConnectionDialog(QWidget *parent, Map* map, const QStringList &mapNames) :
QDialog(parent),
ui(new Ui::NewMapConnectionDialog)
ui(new Ui::NewMapConnectionDialog),
m_map(map)
{
ui->setupUi(this);
setAttribute(Qt::WA_DeleteOnClose);
@@ -15,7 +17,7 @@ NewMapConnectionDialog::NewMapConnectionDialog(QWidget *parent, Map* map, const
// Choose default direction
QMap<QString, int> directionCounts;
for (auto connection : map->getConnections()) {
for (auto connection : m_map->getConnections()) {
directionCounts[connection->direction()]++;
}
QString defaultDirection;
@@ -32,7 +34,7 @@ NewMapConnectionDialog::NewMapConnectionDialog(QWidget *parent, Map* map, const
QString defaultMapName;
if (mapNames.isEmpty()) {
defaultMapName = QString();
} else if (mapNames.first() == map->name() && mapNames.length() > 1) {
} else if (mapNames.first() == m_map->name() && mapNames.length() > 1) {
// Prefer not to connect the map to itself
defaultMapName = mapNames.at(1);
} else {
@@ -61,11 +63,43 @@ void NewMapConnectionDialog::setWarningVisible(bool visible) {
adjustSize();
}
bool NewMapConnectionDialog::askReplaceConnection(MapConnection *connection, const QString &newMapName) {
QString message = QString("%1 already has a %2 connection to '%3'. Replace it with a %2 connection to '%4'?")
.arg(m_map->name())
.arg(connection->direction())
.arg(connection->targetMapName())
.arg(newMapName);
return QuestionMessage::show(message, this) == QMessageBox::Yes;
}
void NewMapConnectionDialog::accept() {
if (!mapNameIsValid()) {
setWarningVisible(true);
return;
}
emit accepted(new MapConnection(ui->comboBox_Map->currentText(), ui->comboBox_Direction->currentText()));
const QString direction = ui->comboBox_Direction->currentText();
const QString targetMapName = ui->comboBox_Map->currentText();
// This is a very niche use case. Normally the user should add Dive/Emerge map connections using the line edits at the top of
// the Connections tab, but because we allow custom direction names in this dialog's Direction drop-down, a user could type
// in "dive" or "emerge" and we have to decide what to do. If there's no existing Dive/Emerge map we can just add it normally
// as if they had typed in the regular line edits. If there's already an existing connection we need to replace it.
if (MapConnection::isDiving(direction)) {
MapConnection *connection = m_map->getConnection(direction);
if (connection) {
if (connection->targetMapName() != targetMapName) {
if (!askReplaceConnection(connection, targetMapName))
return; // Canceled
emit connectionReplaced(targetMapName, direction);
}
// Replaced the diving connection (or no-op, if adding a diving connection with the same map name)
QDialog::accept();
return;
}
// Adding a new diving connection that doesn't exist yet, proceed normally.
}
emit newConnectionedAdded(targetMapName, direction);
QDialog::accept();
}