Fix some issues with map connections after layout split

This commit is contained in:
GriffinR 2025-01-29 13:48:03 -05:00
parent de78a1172d
commit 5a6d5ea929
8 changed files with 57 additions and 100 deletions

View File

@ -91,7 +91,7 @@ public:
void removeConnection(MapConnection *);
void addConnection(MapConnection *);
void loadConnection(MapConnection *);
QRect getConnectionRect(const QString &direction, Layout *fromLayout = nullptr);
QRect getConnectionRect(const QString &direction, Layout *fromLayout = nullptr) const;
QPixmap renderConnection(const QString &direction, Layout *fromLayout = nullptr);
QUndoStack* editHistory() const { return m_editHistory; }

View File

@ -135,7 +135,7 @@ public:
QList<QGraphicsPixmapItem*> borderItems;
QGraphicsItemGroup *mapGrid = nullptr;
MapRuler *map_ruler = nullptr;
QPointer<MapRuler> map_ruler = nullptr;
MovableRect *playerViewRect = nullptr;
CursorTileRect *cursorMapTileRect = nullptr;
@ -221,10 +221,7 @@ private:
void clearMapGrid();
void clearWildMonTables();
void updateBorderVisibility();
void disconnectMapConnection(MapConnection *connection);
QPoint getConnectionOrigin(MapConnection *connection);
void removeConnectionPixmap(MapConnection *connection);
void updateConnectionPixmap(ConnectionPixmapItem *connectionItem);
void displayConnection(MapConnection *connection);
void displayDivingConnection(MapConnection *connection);
void setDivingMapName(QString mapName, QString direction);

View File

@ -10,22 +10,20 @@
class ConnectionPixmapItem : public QObject, public QGraphicsPixmapItem {
Q_OBJECT
public:
ConnectionPixmapItem(MapConnection* connection, int originX, int originY);
ConnectionPixmapItem(MapConnection* connection, QPoint origin);
ConnectionPixmapItem(MapConnection* connection);
const QPointer<MapConnection> connection;
void setOrigin(int x, int y);
void setOrigin(QPoint pos);
void setEditable(bool editable);
bool getEditable();
void setSelected(bool selected);
void updatePos();
void render(bool ignoreCache = false);
signals:
void positionChanged(qreal x, qreal y);
private:
QPixmap basePixmap;
qreal originX;
@ -36,6 +34,10 @@ private:
static const int mWidth = 16;
static const int mHeight = 16;
void updatePos();
void updateOrigin();
void refresh();
protected:
virtual QVariant itemChange(GraphicsItemChange change, const QVariant &value) override;
virtual void mousePressEvent(QGraphicsSceneMouseEvent*) override;

View File

@ -23,7 +23,6 @@ public:
explicit ConnectionsListItem(QWidget *parent, MapConnection *connection, const QStringList &mapNames);
~ConnectionsListItem();
void updateUI();
void setSelected(bool selected);
private:
@ -33,6 +32,8 @@ private:
bool isSelected = false;
unsigned actionId = 0;
void updateUI();
protected:
virtual void mousePressEvent(QMouseEvent*) override;
virtual void focusInEvent(QFocusEvent*) override;

View File

@ -90,7 +90,7 @@ int Map::getBorderHeight() const {
// Get the portion of the map that can be rendered when rendered as a map connection.
// Cardinal connections render the nearest segment of their map and within the bounds of the border draw distance,
// Dive/Emerge connections are rendered normally within the bounds of their parent map.
QRect Map::getConnectionRect(const QString &direction, Layout * fromLayout) {
QRect Map::getConnectionRect(const QString &direction, Layout * fromLayout) const {
int x = 0, y = 0;
int w = getWidth(), h = getHeight();

View File

@ -779,14 +779,6 @@ void Editor::updateEncounterFields(EncounterFields newFields) {
project->wildMonFields = newFields;
}
void Editor::disconnectMapConnection(MapConnection *connection) {
// Disconnect MapConnection's signals used by the display.
// It'd be nice if we could just 'connection->disconnect(this)' but that doesn't account for lambda functions.
QObject::disconnect(connection, &MapConnection::targetMapNameChanged, nullptr, nullptr);
QObject::disconnect(connection, &MapConnection::directionChanged, nullptr, nullptr);
QObject::disconnect(connection, &MapConnection::offsetChanged, nullptr, nullptr);
}
void Editor::displayConnection(MapConnection *connection) {
if (!connection)
return;
@ -797,13 +789,13 @@ void Editor::displayConnection(MapConnection *connection) {
}
// Create connection image
ConnectionPixmapItem *pixmapItem = new ConnectionPixmapItem(connection, getConnectionOrigin(connection));
pixmapItem->render();
auto pixmapItem = new ConnectionPixmapItem(connection);
scene->addItem(pixmapItem);
maskNonVisibleConnectionTiles();
connect(pixmapItem, &ConnectionPixmapItem::positionChanged, this, &Editor::maskNonVisibleConnectionTiles);
// Create item for the list panel
ConnectionsListItem *listItem = new ConnectionsListItem(ui->scrollAreaContents_ConnectionsList, pixmapItem->connection, project->mapNames);
auto listItem = new ConnectionsListItem(ui->scrollAreaContents_ConnectionsList, pixmapItem->connection, project->mapNames);
ui->layout_ConnectionsList->insertWidget(ui->layout_ConnectionsList->count() - 1, listItem); // Insert above the vertical spacer
// Double clicking the pixmap or clicking the list item's map button opens the connected map
@ -822,25 +814,6 @@ void Editor::displayConnection(MapConnection *connection) {
setSelectedConnectionItem(pixmapItem);
});
// Sync edits to 'offset' between the list UI and the pixmap
connect(connection, &MapConnection::offsetChanged, [=](int, int) {
listItem->updateUI();
pixmapItem->updatePos();
maskNonVisibleConnectionTiles();
});
// Sync edits to 'direction' between the list UI and the pixmap
connect(connection, &MapConnection::directionChanged, [=](QString, QString) {
listItem->updateUI();
updateConnectionPixmap(pixmapItem);
});
// Sync edits to 'map' between the list UI and the pixmap
connect(connection, &MapConnection::targetMapNameChanged, [=](QString, QString) {
listItem->updateUI();
updateConnectionPixmap(pixmapItem);
});
// When the pixmap is deleted, remove its associated list item
connect(pixmapItem, &ConnectionPixmapItem::destroyed, listItem, &ConnectionsListItem::deleteLater);
@ -875,8 +848,6 @@ void Editor::removeConnectionPixmap(MapConnection *connection) {
if (!connection)
return;
disconnectMapConnection(connection);
if (MapConnection::isDiving(connection->direction())) {
removeDivingMapPixmap(connection);
return;
@ -1011,39 +982,6 @@ void Editor::updateDivingMapsVisibility() {
}
}
// Get the 'origin' point for the connection's pixmap, i.e. where it should be positioned in the editor when connection->offset() == 0.
// This differs depending on the connection's direction and the dimensions of its target map or parent map.
QPoint Editor::getConnectionOrigin(MapConnection *connection) {
if (!connection)
return QPoint(0, 0);
Map *parentMap = connection->parentMap();
Map *targetMap = connection->targetMap();
const QString direction = connection->direction();
int x = 0, y = 0;
if (direction == "right") {
if (parentMap) x = parentMap->getWidth();
} else if (direction == "down") {
if (parentMap) y = parentMap->getHeight();
} else if (direction == "left") {
if (targetMap) x = -targetMap->getConnectionRect(direction).width();
} else if (direction == "up") {
if (targetMap) y = -targetMap->getConnectionRect(direction).height();
}
return QPoint(x * 16, y * 16);
}
void Editor::updateConnectionPixmap(ConnectionPixmapItem *pixmapItem) {
if (!pixmapItem)
return;
pixmapItem->setOrigin(getConnectionOrigin(pixmapItem->connection));
pixmapItem->render(true); // Full render to reflect map changes
maskNonVisibleConnectionTiles();
}
void Editor::setSelectedConnectionItem(ConnectionPixmapItem *pixmapItem) {
if (!pixmapItem || pixmapItem == selected_connection_item)
return;
@ -1245,8 +1183,6 @@ void Editor::unsetMap() {
if (this->map) {
this->map->pruneEditHistory();
this->map->disconnect(this);
for (const auto &connection : this->map->getConnections())
disconnectMapConnection(connection);
}
clearMapConnections();
@ -1546,7 +1482,10 @@ void Editor::clearMap() {
map = nullptr;
// These are normally preserved between map displays, we only delete them now.
delete scene;
if (scene) {
scene->removeItem(this->map_ruler);
delete scene;
}
delete metatile_selector_item;
delete movement_permissions_selector_item;
}
@ -1575,9 +1514,10 @@ bool Editor::displayLayout() {
scene->installEventFilter(filter);
connect(filter, &MapSceneEventFilter::wheelZoom, this, &Editor::onWheelZoom);
scene->installEventFilter(this->map_ruler);
this->map_ruler->setZValue(1000);
scene->addItem(this->map_ruler);
}
clearConnectionMask();
displayMetatileSelector();
displayMapMetatiles();
displayMovementPermissionSelector();
@ -1586,9 +1526,7 @@ bool Editor::displayLayout() {
displayCurrentMetatilesSelection();
displayMapBorder();
displayMapGrid();
this->map_ruler->setZValue(1000);
scene->addItem(this->map_ruler);
maskNonVisibleConnectionTiles();
if (map_item) {
map_item->setVisible(false);
@ -1638,7 +1576,6 @@ void Editor::clearMapMetatiles() {
if (map_item && scene) {
scene->removeItem(map_item);
delete map_item;
scene->removeItem(this->map_ruler);
}
}

View File

@ -4,19 +4,25 @@
#include <math.h>
ConnectionPixmapItem::ConnectionPixmapItem(MapConnection* connection, int x, int y)
ConnectionPixmapItem::ConnectionPixmapItem(MapConnection* connection)
: QGraphicsPixmapItem(connection->getPixmap()),
connection(connection)
{
this->setEditable(true);
setFlag(ItemIsFocusable, true);
this->basePixmap = pixmap();
this->setOrigin(x, y);
refresh();
// If the connection changes externally we want to update the pixmap to reflect the change.
connect(connection, &MapConnection::offsetChanged, this, &ConnectionPixmapItem::updatePos);
connect(connection, &MapConnection::directionChanged, this, &ConnectionPixmapItem::refresh);
connect(connection, &MapConnection::targetMapNameChanged, this, &ConnectionPixmapItem::refresh);
}
ConnectionPixmapItem::ConnectionPixmapItem(MapConnection* connection, QPoint pos)
: ConnectionPixmapItem(connection, pos.x(), pos.y())
{}
void ConnectionPixmapItem::refresh() {
updateOrigin();
render(true);
}
// Render additional visual effects on top of the base map image.
void ConnectionPixmapItem::render(bool ignoreCache) {
@ -77,8 +83,6 @@ QVariant ConnectionPixmapItem::itemChange(GraphicsItemChange change, const QVari
// If connection->offset changed externally we call this to correct our position.
void ConnectionPixmapItem::updatePos() {
const QSignalBlocker blocker(this);
qreal x = this->originX;
qreal y = this->originY;
@ -89,17 +93,28 @@ void ConnectionPixmapItem::updatePos() {
}
this->setPos(x, y);
emit positionChanged(x, y);
}
// Set the pixmap's external origin point, i.e. the pixmap's position when connection->offset == 0
void ConnectionPixmapItem::setOrigin(int x, int y) {
this->originX = x;
this->originY = y;
void ConnectionPixmapItem::updateOrigin() {
const Map *parentMap = connection->parentMap();
const Map *targetMap = connection->targetMap();
const QString direction = connection->direction();
int x = 0, y = 0;
if (direction == "right") {
if (parentMap) x = parentMap->getWidth();
} else if (direction == "down") {
if (parentMap) y = parentMap->getHeight();
} else if (direction == "left") {
if (targetMap) x = -targetMap->getConnectionRect(direction).width();
} else if (direction == "up") {
if (targetMap) y = -targetMap->getConnectionRect(direction).height();
}
this->originX = x * this->mWidth;
this->originY = y * this->mHeight;
updatePos();
}
void ConnectionPixmapItem::setOrigin(QPoint pos) {
this->setOrigin(pos.x(), pos.y());
}
void ConnectionPixmapItem::setEditable(bool editable) {
setFlag(ItemIsMovable, editable);

View File

@ -38,6 +38,11 @@ ConnectionsListItem::ConnectionsListItem(QWidget *parent, MapConnection * connec
// Distinguish between move actions for the edit history
connect(ui->spinBox_Offset, &QSpinBox::editingFinished, [this] { this->actionId++; });
// If the connection changes externally we want to update to reflect the change.
connect(connection, &MapConnection::offsetChanged, this, &ConnectionsListItem::updateUI);
connect(connection, &MapConnection::directionChanged, this, &ConnectionsListItem::updateUI);
connect(connection, &MapConnection::targetMapNameChanged, this, &ConnectionsListItem::updateUI);
this->connection = connection;
this->map = connection->parentMap();
this->updateUI();