Performance & bug clean up
This commit is contained in:
parent
1e09d08c9c
commit
96b5fb1617
15 changed files with 214 additions and 256 deletions
|
@ -1715,7 +1715,7 @@
|
|||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>100</width>
|
||||
<height>16</height>
|
||||
<height>30</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="sizePolicy">
|
||||
|
@ -1809,7 +1809,7 @@
|
|||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>100</width>
|
||||
<height>16</height>
|
||||
<height>30</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="sizePolicy">
|
||||
|
@ -1903,7 +1903,7 @@
|
|||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>100</width>
|
||||
<height>16</height>
|
||||
<height>30</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="sizePolicy">
|
||||
|
@ -2003,7 +2003,7 @@
|
|||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>100</width>
|
||||
<height>16</height>
|
||||
<height>30</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="sizePolicy">
|
||||
|
@ -2097,7 +2097,7 @@
|
|||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>100</width>
|
||||
<height>16</height>
|
||||
<height>30</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="sizePolicy">
|
||||
|
@ -2596,6 +2596,9 @@
|
|||
<property name="editable">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="clearButtonEnabled" stdset="0">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="4">
|
||||
|
@ -2667,6 +2670,9 @@
|
|||
<property name="editable">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="clearButtonEnabled" stdset="0">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
|
@ -2757,8 +2763,8 @@
|
|||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>365</width>
|
||||
<height>658</height>
|
||||
<width>100</width>
|
||||
<height>30</height>
|
||||
</rect>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="layout_ConnectionsList">
|
||||
|
|
|
@ -98,7 +98,7 @@ public:
|
|||
QStringList getScriptLabels(Event::Group group = Event::Group::None);
|
||||
void removeEvent(Event *);
|
||||
void addEvent(Event *);
|
||||
QPixmap renderConnection(MapConnection, MapLayout *);
|
||||
QPixmap renderConnection(const MapConnection&, MapLayout *);
|
||||
QPixmap renderBorder(bool ignoreCache = false);
|
||||
void setDimensions(int newWidth, int newHeight, bool setNewBlockdata = true, bool enableScriptCallback = false);
|
||||
void setBorderDimensions(int newWidth, int newHeight, bool setNewBlockdata = true, bool enableScriptCallback = false);
|
||||
|
|
|
@ -12,6 +12,12 @@ public:
|
|||
QString direction;
|
||||
int offset;
|
||||
QString map_name;
|
||||
|
||||
static const QStringList cardinalDirections;
|
||||
static bool isCardinal(const QString &direction);
|
||||
static bool isHorizontal(const QString &direction);
|
||||
static bool isVertical(const QString &direction);
|
||||
static MapConnection mirror(const MapConnection &source, const QString &mapName);
|
||||
};
|
||||
|
||||
struct MapConnectionMirror {
|
||||
|
|
|
@ -168,14 +168,13 @@ private:
|
|||
QPixmap collisionSheetPixmap;
|
||||
|
||||
void updateBorderVisibility();
|
||||
QPoint calculateConnectionPosition(const MapConnection *connection, const QPixmap &pixmap);
|
||||
QPoint calculateConnectionPosition(const MapConnection &connection, const QPixmap &pixmap);
|
||||
QPixmap getConnectionPixmap(const MapConnection &connection);
|
||||
void updateConnectionItem(ConnectionPixmapItem* connectionItem);
|
||||
void updateConnectionItemPos(ConnectionPixmapItem* connectionItem);
|
||||
void createConnectionItem(MapConnection* connection);
|
||||
void populateConnectionsList();
|
||||
void addConnectionToList(ConnectionPixmapItem* connection);
|
||||
void updateDiveEmergeMap(QString mapName, QString direction);
|
||||
bool shouldMirrorConnection(const MapConnection &source);
|
||||
MapConnectionMirror getMirroredConnection(const MapConnection&);
|
||||
void addMirroredConnection(const MapConnection&);
|
||||
void removeMirroredConnection(const MapConnection&);
|
||||
|
@ -197,7 +196,7 @@ private slots:
|
|||
void setConnectionOffset(MapConnection *connection, int offset);
|
||||
void setConnectionMap(MapConnection *connection, const QString &mapName);
|
||||
void setConnectionDirection(MapConnection *connection, const QString &direction);
|
||||
void onConnectionItemSelected(ConnectionPixmapItem* connectionItem);
|
||||
void setSelectedConnection(ConnectionPixmapItem* connectionItem);
|
||||
void onHoveredMovementPermissionChanged(uint16_t, uint16_t);
|
||||
void onHoveredMovementPermissionCleared();
|
||||
void onHoveredMetatileSelectionChanged(uint16_t);
|
||||
|
|
|
@ -28,13 +28,14 @@ public:
|
|||
int initialOffset;
|
||||
int baseMapWidth;
|
||||
int baseMapHeight;
|
||||
void render(qreal opacity = 1);
|
||||
|
||||
void setEditable(bool editable);
|
||||
bool getEditable();
|
||||
void updateHighlight(bool selected);
|
||||
void setSelected(bool selected);
|
||||
void render();
|
||||
|
||||
private:
|
||||
bool highlighted = false;
|
||||
bool selected = false;
|
||||
|
||||
protected:
|
||||
QVariant itemChange(GraphicsItemChange change, const QVariant &value);
|
||||
|
@ -42,10 +43,9 @@ protected:
|
|||
void mouseDoubleClickEvent(QGraphicsSceneMouseEvent*);
|
||||
|
||||
signals:
|
||||
void connectionItemSelected(ConnectionPixmapItem* connectionItem);
|
||||
void connectionItemDoubleClicked(ConnectionPixmapItem* connectionItem);
|
||||
void connectionMoved(MapConnection *, int newOffset);
|
||||
void highlightChanged(bool highlighted);
|
||||
void selectionChanged(bool selected);
|
||||
};
|
||||
|
||||
#endif // CONNECTIONPIXMAPITEM_H
|
||||
|
|
|
@ -13,6 +13,7 @@ public:
|
|||
void setTextItem(const QString &text);
|
||||
void setNumberItem(int value);
|
||||
void setHexItem(uint32_t value);
|
||||
void setClearButtonEnabled(bool enabled);
|
||||
|
||||
private:
|
||||
void setItem(int index, const QString &text);
|
||||
|
|
|
@ -24,6 +24,7 @@ SOURCES += src/core/block.cpp \
|
|||
src/core/heallocation.cpp \
|
||||
src/core/imageexport.cpp \
|
||||
src/core/map.cpp \
|
||||
src/core/mapconnection.cpp \
|
||||
src/core/maplayout.cpp \
|
||||
src/core/mapparser.cpp \
|
||||
src/core/metatile.cpp \
|
||||
|
|
|
@ -217,34 +217,21 @@ QPixmap Map::renderBorder(bool ignoreCache) {
|
|||
return layout->border_pixmap;
|
||||
}
|
||||
|
||||
QPixmap Map::renderConnection(MapConnection connection, MapLayout * fromLayout) {
|
||||
int x, y, w, h;
|
||||
QPixmap Map::renderConnection(const MapConnection &connection, MapLayout * fromLayout) {
|
||||
if (!MapConnection::isCardinal(connection.direction))
|
||||
return QPixmap();
|
||||
|
||||
int x = 0, y = 0, w = getWidth(), h = getHeight();
|
||||
if (connection.direction == "up") {
|
||||
x = 0;
|
||||
y = getHeight() - BORDER_DISTANCE;
|
||||
w = getWidth();
|
||||
h = BORDER_DISTANCE;
|
||||
} else if (connection.direction == "down") {
|
||||
x = 0;
|
||||
y = 0;
|
||||
w = getWidth();
|
||||
h = BORDER_DISTANCE;
|
||||
} else if (connection.direction == "left") {
|
||||
x = getWidth() - BORDER_DISTANCE;
|
||||
y = 0;
|
||||
w = BORDER_DISTANCE;
|
||||
h = getHeight();
|
||||
} else if (connection.direction == "right") {
|
||||
x = 0;
|
||||
y = 0;
|
||||
w = BORDER_DISTANCE;
|
||||
h = getHeight();
|
||||
} else {
|
||||
// this should not happen
|
||||
x = 0;
|
||||
y = 0;
|
||||
w = getWidth();
|
||||
h = getHeight();
|
||||
}
|
||||
|
||||
render(true, fromLayout, QRect(x, y, w, h));
|
||||
|
|
|
@ -1,43 +1,35 @@
|
|||
#include "mapconnection.h"
|
||||
#include "map.h"
|
||||
|
||||
void MapConnection::setDirection(const QString & direction) {
|
||||
if (direction == m_direction)
|
||||
return;
|
||||
auto before = m_direction;
|
||||
m_direction = direction;
|
||||
emit directionChanged(before, m_direction);
|
||||
}
|
||||
const QStringList MapConnection::cardinalDirections = {
|
||||
"up", "down", "left", "right"
|
||||
};
|
||||
|
||||
void MapConnection::setOffset(int offset) {
|
||||
if (offset == m_offset)
|
||||
return;
|
||||
auto before = m_offset;
|
||||
m_offset = offset;
|
||||
emit offsetChanged(before, m_offset);
|
||||
}
|
||||
|
||||
void MapConnection::setMapName(const QString &mapName) {
|
||||
if (mapName == m_mapName)
|
||||
return;
|
||||
auto before = m_mapName;
|
||||
m_mapName = mapName;
|
||||
emit mapNameChanged(before, m_mapName);
|
||||
}
|
||||
/*
|
||||
static QString MapConnection::oppositeDirection(const QString &direction) {
|
||||
MapConnection MapConnection::mirror(const MapConnection &source, const QString &mapName) {
|
||||
static const QMap<QString, QString> oppositeDirections = {
|
||||
{"up", "down"}, {"down", "up"},
|
||||
{"right", "left"}, {"left", "right"},
|
||||
{"dive", "emerge"}, {"emerge", "dive"}
|
||||
};
|
||||
return oppositeDirections.value(direction);
|
||||
|
||||
// TODO: Allowing editing unknown directions is a can of worms.
|
||||
// Specifically a self-connection with an empty direction and an offset of 0 can be identified as its own mirror
|
||||
MapConnection mirror;
|
||||
mirror.direction = oppositeDirections.value(source.direction/*, source.direction*/);
|
||||
mirror.map_name = mapName;
|
||||
mirror.offset = -source.offset;
|
||||
|
||||
return mirror;
|
||||
}
|
||||
|
||||
static MapConnection* MapConnection::getMirror(const MapConnection*, const Map*) {
|
||||
|
||||
bool MapConnection::isHorizontal(const QString &direction) {
|
||||
return direction == "left" || direction == "right";
|
||||
}
|
||||
|
||||
static MapConnection* MapConnection::newMirror(const MapConnection*) {
|
||||
bool MapConnection::isVertical(const QString &direction) {
|
||||
return direction == "up" || direction == "down";
|
||||
}
|
||||
|
||||
}*/
|
||||
bool MapConnection::isCardinal(const QString &direction) {
|
||||
return cardinalDirections.contains(direction);
|
||||
}
|
||||
|
|
250
src/editor.cpp
250
src/editor.cpp
|
@ -89,7 +89,6 @@ void Editor::setEditingMap() {
|
|||
current_view = map_item;
|
||||
if (map_item) {
|
||||
map_item->paintingMode = MapPixmapItem::PaintMode::Metatiles;
|
||||
displayMapConnections();
|
||||
map_item->draw();
|
||||
map_item->setVisible(true);
|
||||
}
|
||||
|
@ -109,7 +108,6 @@ void Editor::setEditingMap() {
|
|||
void Editor::setEditingCollision() {
|
||||
current_view = collision_item;
|
||||
if (collision_item) {
|
||||
displayMapConnections();
|
||||
collision_item->draw();
|
||||
collision_item->setVisible(true);
|
||||
}
|
||||
|
@ -135,7 +133,6 @@ void Editor::setEditingObjects() {
|
|||
}
|
||||
if (map_item) {
|
||||
map_item->paintingMode = MapPixmapItem::PaintMode::EventObjects;
|
||||
displayMapConnections();
|
||||
map_item->draw();
|
||||
map_item->setVisible(true);
|
||||
}
|
||||
|
@ -172,8 +169,6 @@ void Editor::setEditingConnections() {
|
|||
map_item->paintingMode = MapPixmapItem::PaintMode::Disabled;
|
||||
map_item->draw();
|
||||
map_item->setVisible(true);
|
||||
populateConnectionsList();
|
||||
maskNonVisibleConnectionTiles();
|
||||
}
|
||||
if (collision_item) {
|
||||
collision_item->setVisible(false);
|
||||
|
@ -722,58 +717,15 @@ void Editor::updateEncounterFields(EncounterFields newFields) {
|
|||
project->wildMonFields = newFields;
|
||||
}
|
||||
|
||||
void Editor::populateConnectionsList() {
|
||||
const QSignalBlocker blocker1(ui->comboBox_DiveMap);
|
||||
const QSignalBlocker blocker2(ui->comboBox_EmergeMap);
|
||||
|
||||
// TODO: We should probably just be doing this once, and updating the items when new maps are created.
|
||||
ui->comboBox_DiveMap->clear();
|
||||
ui->comboBox_EmergeMap->clear();
|
||||
ui->comboBox_DiveMap->addItems(project->mapNames);
|
||||
ui->comboBox_EmergeMap->addItems(project->mapNames);
|
||||
ui->comboBox_DiveMap->setCurrentText("");
|
||||
ui->comboBox_EmergeMap->setCurrentText("");
|
||||
ui->comboBox_DiveMap->lineEdit()->setClearButtonEnabled(true);
|
||||
ui->comboBox_EmergeMap->lineEdit()->setClearButtonEnabled(true);
|
||||
|
||||
for (MapConnection* connection : map->connections) {
|
||||
if (connection->direction == "dive") {
|
||||
ui->comboBox_DiveMap->setCurrentText(connection->map_name);
|
||||
} else if (connection->direction == "emerge") {
|
||||
ui->comboBox_EmergeMap->setCurrentText(connection->map_name);
|
||||
}
|
||||
}
|
||||
|
||||
// Clear any existing connections in list
|
||||
for (auto listItem : ui->scrollAreaContents_ConnectionsList->findChildren<ConnectionsListItem*>())
|
||||
listItem->deleteLater();
|
||||
|
||||
for (auto item :connection_items)
|
||||
addConnectionToList(item);
|
||||
}
|
||||
|
||||
// TODO: When connecting a map to itself the new mirror is shaded incorrectly
|
||||
// TODO: Set default focus to the selected connection, right now it defaults to the dive combo box
|
||||
|
||||
void Editor::addConnectionToList(ConnectionPixmapItem * connectionItem) {
|
||||
ConnectionsListItem *listItem = new ConnectionsListItem(ui->scrollAreaContents_ConnectionsList, connectionItem->connection, project->mapNames);
|
||||
ui->layout_ConnectionsList->insertWidget(ui->layout_ConnectionsList->count() - 1, listItem); // Insert above the vertical spacer
|
||||
|
||||
// Sync the selection highlight between the list UI and the graphical map connection
|
||||
connect(connectionItem, &ConnectionPixmapItem::highlightChanged, listItem, &ConnectionsListItem::setSelected);
|
||||
connect(connectionItem, &ConnectionPixmapItem::selectionChanged, listItem, &ConnectionsListItem::setSelected);
|
||||
connect(listItem, &ConnectionsListItem::selected, [this, connectionItem] {
|
||||
// When the list item is selected, select the pixmap too
|
||||
if (connectionItem == selected_connection_item) {
|
||||
// Already selected, no change
|
||||
return;
|
||||
}
|
||||
// Deselect old connection and select new connection
|
||||
if (selected_connection_item) selected_connection_item->updateHighlight(false);
|
||||
selected_connection_item = connectionItem;
|
||||
selected_connection_item->updateHighlight(true);
|
||||
setSelectedConnection(connectionItem);
|
||||
});
|
||||
if (connectionItem == selected_connection_item)
|
||||
listItem->setSelected(true);
|
||||
|
||||
// Sync edits to 'offset' between the list UI and the graphical map connection
|
||||
connect(connectionItem, &ConnectionPixmapItem::connectionMoved, [this, listItem](MapConnection* connection, int offset) {
|
||||
|
@ -787,9 +739,10 @@ void Editor::addConnectionToList(ConnectionPixmapItem * connectionItem) {
|
|||
|
||||
// Sync edits to 'direction' or 'map' between the list UI and the graphical map connection.
|
||||
// These are 1-way because the direction and map cannot be edited graphically, only via the list UI.
|
||||
connect(listItem, &ConnectionsListItem::editedDirection, [this, connectionItem](MapConnection* connection, QString direction) {
|
||||
connect(listItem, &ConnectionsListItem::editedDirection, [this, connectionItem, listItem](MapConnection* connection, QString direction) {
|
||||
setConnectionDirection(connection, direction);
|
||||
updateConnectionItem(connectionItem); // TODO: Simplify?
|
||||
updateConnectionItem(connectionItem); // TODO: Simplify
|
||||
listItem->updateUI(); // Changing direction may have changed our offset too
|
||||
});
|
||||
connect(listItem, &ConnectionsListItem::editedMapName, [this, connectionItem](MapConnection* connection, QString mapName) {
|
||||
setConnectionMap(connection, mapName);
|
||||
|
@ -813,13 +766,13 @@ void Editor::addConnectionToList(ConnectionPixmapItem * connectionItem) {
|
|||
|
||||
void Editor::addNewConnection() {
|
||||
// Find direction with least number of connections.
|
||||
QMap<QString, int> directionCounts = QMap<QString, int>({{"up", 0}, {"right", 0}, {"down", 0}, {"left", 0}});
|
||||
QMap<QString, int> directionCounts;
|
||||
for (MapConnection* connection : map->connections) {
|
||||
directionCounts[connection->direction]++;
|
||||
}
|
||||
QString minDirection = "up";
|
||||
int minCount = INT_MAX;
|
||||
for (QString direction : directionCounts.keys()) {
|
||||
for (QString direction : MapConnection::cardinalDirections) {
|
||||
if (directionCounts[direction] < minCount) {
|
||||
minDirection = direction;
|
||||
minCount = directionCounts[direction];
|
||||
|
@ -827,7 +780,6 @@ void Editor::addNewConnection() {
|
|||
}
|
||||
|
||||
// Prefer not to connect the map to itself (we have to if it's the only map).
|
||||
// TODO: Is this more or less sensible than a connection with no map name
|
||||
QString defaultMapName = project->mapNames.first();
|
||||
if (defaultMapName == map->name && project->mapNames.length() > 1) {
|
||||
defaultMapName = project->mapNames.at(1);
|
||||
|
@ -838,11 +790,14 @@ void Editor::addNewConnection() {
|
|||
newConnection->offset = 0;
|
||||
newConnection->map_name = defaultMapName;
|
||||
addConnection(map, newConnection);
|
||||
onConnectionItemSelected(connection_items.last());
|
||||
setSelectedConnection(connection_items.last());
|
||||
addMirroredConnection(*newConnection);
|
||||
}
|
||||
|
||||
void Editor::addConnection(Map* map, MapConnection * connection) {
|
||||
if (!map || !connection)
|
||||
return;
|
||||
|
||||
map->connections.append(connection);
|
||||
if (map == this->map) {
|
||||
// Adding a connection to the current map, we need to display it visually.
|
||||
|
@ -857,7 +812,6 @@ void Editor::addConnection(Map* map, MapConnection * connection) {
|
|||
ui->comboBox_EmergeMap->setCurrentText(connection->map_name);
|
||||
} else {
|
||||
createConnectionItem(connection);
|
||||
addConnectionToList(connection_items.last());
|
||||
}
|
||||
}
|
||||
emit editedMapData(map);
|
||||
|
@ -885,7 +839,7 @@ void Editor::removeConnectionItem(ConnectionPixmapItem* connectionItem, bool rem
|
|||
if (connectionItem == selected_connection_item) {
|
||||
selected_connection_item = nullptr;
|
||||
if (!connection_items.isEmpty())
|
||||
onConnectionItemSelected(connection_items.first());
|
||||
setSelectedConnection(connection_items.first());
|
||||
}
|
||||
delete connectionItem;
|
||||
}
|
||||
|
@ -902,22 +856,9 @@ void Editor::removeSelectedConnection() {
|
|||
removeConnectionItem(selected_connection_item);
|
||||
}
|
||||
|
||||
static const QMap<QString, QString> oppositeDirections = {
|
||||
{"up", "down"}, {"down", "up"},
|
||||
{"right", "left"}, {"left", "right"},
|
||||
{"dive", "emerge"}, {"emerge", "dive"}
|
||||
};
|
||||
|
||||
bool Editor::shouldMirrorConnection(const MapConnection &source) {
|
||||
// The current map's connections are not mirrored if the user has disabled this setting,
|
||||
// unless it's a connection to itself (which is mirrored by definition).
|
||||
// TODO: Confirm in-game representation of the above fact is accurate.
|
||||
return ui->checkBox_MirrorConnections->isChecked() || (map && map->name == source.map_name);
|
||||
}
|
||||
|
||||
MapConnectionMirror Editor::getMirroredConnection(const MapConnection &source) {
|
||||
MapConnectionMirror mirror;
|
||||
if (!map || !shouldMirrorConnection(source))
|
||||
if (!map || !ui->checkBox_MirrorConnections->isChecked())
|
||||
return mirror;
|
||||
|
||||
// Note: It's possible (and ok) for mirror.map == this->map
|
||||
|
@ -925,12 +866,10 @@ MapConnectionMirror Editor::getMirroredConnection(const MapConnection &source) {
|
|||
if (!mirror.map)
|
||||
return mirror;
|
||||
|
||||
MapConnection target;
|
||||
target.direction = oppositeDirections.value(source.direction);
|
||||
target.map_name = map->name;
|
||||
target.offset = -source.offset;
|
||||
|
||||
// Find the matching connection in the connected map.
|
||||
// Note: There is no strict source -> mirror pairing, i.e. we are not guaranteed
|
||||
// to always get the same MapConnection if there are multiple identical copies.
|
||||
MapConnection target = MapConnection::mirror(source, map->name);
|
||||
for (auto connection : mirror.map->connections) {
|
||||
if (*connection == target) {
|
||||
mirror.connection = connection;
|
||||
|
@ -946,10 +885,7 @@ void Editor::addMirroredConnection(const MapConnection &source) {
|
|||
return;
|
||||
|
||||
mirror.connection = new MapConnection;
|
||||
mirror.connection->direction = oppositeDirections.value(source.direction);
|
||||
mirror.connection->map_name = map->name;
|
||||
mirror.connection->offset = -source.offset;
|
||||
|
||||
*mirror.connection = MapConnection::mirror(source, map->name);
|
||||
addConnection(mirror.map, mirror.connection);
|
||||
}
|
||||
|
||||
|
@ -993,7 +929,7 @@ void Editor::updateDiveEmergeMap(QString mapName, QString direction) {
|
|||
return;
|
||||
}
|
||||
|
||||
// TODO: How does the game handle having multiple Dive/Emerge maps. Should we support this?
|
||||
// Only the first Dive/Emerge map (if present) is considered, as in-game.
|
||||
MapConnection* connection = nullptr;
|
||||
for (MapConnection* conn : map->connections) {
|
||||
if (conn->direction == direction) {
|
||||
|
@ -1002,14 +938,18 @@ void Editor::updateDiveEmergeMap(QString mapName, QString direction) {
|
|||
}
|
||||
}
|
||||
|
||||
// We (lazily) always update the connection by deleting the old one and creating a new one.
|
||||
// Unlike the displayed connections which can be updated rapidly by click+drag, this isn't
|
||||
// really an issue for Dive/Emerge maps.
|
||||
// Dive/Emerge maps aren't represented visually (aside from their combo boxes),
|
||||
// so we have less to do here than a normal connection.
|
||||
if (connection) {
|
||||
removeMirroredConnection(*connection);
|
||||
removeConnection(map, connection);
|
||||
}
|
||||
if (!mapName.isEmpty() && mapName != DYNAMIC_MAP_NAME) {
|
||||
// Update existing connection
|
||||
if (mapName.isEmpty()) {
|
||||
removeMirroredConnection(*connection);
|
||||
removeConnection(map, connection);
|
||||
} else {
|
||||
setConnectionMap(connection, mapName);
|
||||
}
|
||||
} else if (!mapName.isEmpty()) {
|
||||
// Create new connection
|
||||
connection = new MapConnection;
|
||||
connection->direction = direction;
|
||||
connection->offset = 0;
|
||||
|
@ -1019,25 +959,36 @@ void Editor::updateDiveEmergeMap(QString mapName, QString direction) {
|
|||
}
|
||||
}
|
||||
|
||||
QPoint Editor::calculateConnectionPosition(const MapConnection *connection, const QPixmap &pixmap) {
|
||||
QPoint Editor::calculateConnectionPosition(const MapConnection &connection, const QPixmap &pixmap) {
|
||||
int x = 0, y = 0;
|
||||
const int mWidth = 16, mHeight = 16;
|
||||
if (connection->direction == "up") {
|
||||
x = connection->offset * mWidth;
|
||||
if (connection.direction == "up") {
|
||||
x = connection.offset * mWidth;
|
||||
y = -pixmap.height();
|
||||
} else if (connection->direction == "down") {
|
||||
x = connection->offset * mWidth;
|
||||
} else if (connection.direction == "down") {
|
||||
x = connection.offset * mWidth;
|
||||
y = map->getHeight() * mHeight;
|
||||
} else if (connection->direction == "left") {
|
||||
} else if (connection.direction == "left") {
|
||||
x = -pixmap.width();
|
||||
y = connection->offset * mHeight;
|
||||
} else if (connection->direction == "right") {
|
||||
y = connection.offset * mHeight;
|
||||
} else if (connection.direction == "right") {
|
||||
x = map->getWidth() * mWidth;
|
||||
y = connection->offset * mHeight;
|
||||
y = connection.offset * mHeight;
|
||||
}
|
||||
return QPoint(x, y);
|
||||
}
|
||||
|
||||
QPixmap Editor::getConnectionPixmap(const MapConnection &connection) {
|
||||
Map *connectedMap = project->getMap(connection.map_name);
|
||||
|
||||
// connectedMap will be null for MAP_DYNAMIC and any map that fails to load.
|
||||
// The connection will be editable from the list, but no image will be displayed on the map.
|
||||
if (!connectedMap)
|
||||
return QPixmap();
|
||||
|
||||
return connectedMap->renderConnection(connection, map->layout);
|
||||
}
|
||||
|
||||
void Editor::updateConnectionItem(ConnectionPixmapItem* connectionItem) {
|
||||
if (!connectionItem || !connectionItem->connection)
|
||||
return;
|
||||
|
@ -1046,29 +997,22 @@ void Editor::updateConnectionItem(ConnectionPixmapItem* connectionItem) {
|
|||
if (mapName.isEmpty())
|
||||
return;
|
||||
|
||||
// TODO: What happens if a connection is saved with an empty name
|
||||
if (mapName == DYNAMIC_MAP_NAME || !project->mapNames.contains(mapName)) {
|
||||
if (!project->mapNames.contains(mapName)) {
|
||||
logError(QString("Invalid map name '%1' specified for connection.").arg(mapName));
|
||||
return;
|
||||
}
|
||||
|
||||
Map *connectedMap = project->getMap(mapName);
|
||||
if (!connectedMap)
|
||||
return;
|
||||
|
||||
QPixmap pixmap = connectedMap->renderConnection(*connectionItem->connection, map->layout);
|
||||
connectionItem->initialOffset = connectionItem->connection->offset;
|
||||
connectionItem->basePixmap = pixmap;
|
||||
QPoint pos = calculateConnectionPosition(connectionItem->connection, pixmap);
|
||||
connectionItem->basePixmap = getConnectionPixmap(*connectionItem->connection);
|
||||
QPoint pos = calculateConnectionPosition(*connectionItem->connection, connectionItem->basePixmap);
|
||||
|
||||
connectionItem->blockSignals(true);
|
||||
connectionItem->setPixmap(pixmap);
|
||||
connectionItem->updateHighlight(connectionItem == selected_connection_item);
|
||||
connectionItem->setPixmap(connectionItem->basePixmap);
|
||||
connectionItem->initialX = pos.x();
|
||||
connectionItem->initialY = pos.y();
|
||||
connectionItem->setX(pos.x());
|
||||
connectionItem->setY(pos.y());
|
||||
connectionItem->setZValue(-1);
|
||||
connectionItem->render();
|
||||
connectionItem->blockSignals(false);
|
||||
|
||||
maskNonVisibleConnectionTiles();
|
||||
|
@ -1080,9 +1024,9 @@ void Editor::updateConnectionItemPos(ConnectionPixmapItem* connectionItem) {
|
|||
|
||||
MapConnection *connection = connectionItem->connection;
|
||||
connectionItem->blockSignals(true);
|
||||
if (connection->direction == "up" || connection->direction == "down") {
|
||||
if (MapConnection::isVertical(connection->direction)) {
|
||||
connectionItem->setX(connectionItem->initialX + (connection->offset - connectionItem->initialOffset) * 16);
|
||||
} else if (connection->direction == "left" || connection->direction == "right") {
|
||||
} else if (MapConnection::isHorizontal(connection->direction)) {
|
||||
connectionItem->setY(connectionItem->initialY + (connection->offset - connectionItem->initialOffset) * 16);
|
||||
}
|
||||
connectionItem->blockSignals(false);
|
||||
|
@ -1115,7 +1059,6 @@ void Editor::setConnectionOffset(MapConnection *connection, int offset) {
|
|||
}
|
||||
}
|
||||
}
|
||||
// TODO: If there's no mirror but there should be we're not creating one
|
||||
|
||||
connection->offset = offset;
|
||||
emit editedMapData(map);
|
||||
|
@ -1141,19 +1084,26 @@ void Editor::setConnectionDirection(MapConnection *connection, const QString &di
|
|||
|
||||
// TODO: Lazy
|
||||
removeMirroredConnection(*connection);
|
||||
|
||||
if (MapConnection::isHorizontal(connection->direction) != MapConnection::isHorizontal(direction)
|
||||
|| MapConnection::isVertical(connection->direction) != MapConnection::isVertical(direction)) {
|
||||
// If the direction has changed between vertical/horizontal then the old offset may not make sense, so we reset it
|
||||
setConnectionOffset(connection, 0);
|
||||
}
|
||||
connection->direction = direction;
|
||||
|
||||
addMirroredConnection(*connection);
|
||||
|
||||
emit editedMapData(map);
|
||||
}
|
||||
|
||||
void Editor::onConnectionItemSelected(ConnectionPixmapItem* connectionItem) {
|
||||
if (!connectionItem)
|
||||
void Editor::setSelectedConnection(ConnectionPixmapItem* connectionItem) {
|
||||
if (!connectionItem || connectionItem == selected_connection_item)
|
||||
return;
|
||||
|
||||
if (selected_connection_item) selected_connection_item->setSelected(false);
|
||||
selected_connection_item = connectionItem;
|
||||
for (ConnectionPixmapItem* item : connection_items)
|
||||
item->updateHighlight(item == selected_connection_item);
|
||||
selected_connection_item->setSelected(true);
|
||||
}
|
||||
|
||||
// TODO: Inaccurate if there are multiple connections from the same map
|
||||
|
@ -1161,7 +1111,7 @@ void Editor::setSelectedConnectionFromMap(QString mapName) {
|
|||
// Search for the first connection that connects to the given map map.
|
||||
for (ConnectionPixmapItem* item : connection_items) {
|
||||
if (item->connection->map_name == mapName) {
|
||||
onConnectionItemSelected(item);
|
||||
setSelectedConnection(item);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -1606,6 +1556,7 @@ bool Editor::displayMap() {
|
|||
displayMapBorder();
|
||||
displayMapGrid();
|
||||
displayWildMonTables();
|
||||
maskNonVisibleConnectionTiles();
|
||||
|
||||
this->map_ruler->setZValue(1000);
|
||||
scene->addItem(this->map_ruler);
|
||||
|
@ -1795,41 +1746,56 @@ void Editor::displayMapConnections() {
|
|||
selected_connection_item = nullptr;
|
||||
connection_items.clear();
|
||||
|
||||
const QSignalBlocker blocker1(ui->comboBox_DiveMap);
|
||||
const QSignalBlocker blocker2(ui->comboBox_EmergeMap);
|
||||
ui->comboBox_DiveMap->clear();
|
||||
ui->comboBox_EmergeMap->clear();
|
||||
ui->comboBox_DiveMap->addItems(project->mapNames);
|
||||
ui->comboBox_EmergeMap->addItems(project->mapNames);
|
||||
ui->comboBox_DiveMap->setCurrentText("");
|
||||
ui->comboBox_EmergeMap->setCurrentText("");
|
||||
|
||||
// Note: We only support editing 1 Dive and Emerge connection per map.
|
||||
// In a vanilla game only the first Dive/Emerge connection is considered, so allowing
|
||||
// users to have multiple is likely to lead to confusion. In case users have changed
|
||||
// this we won't delete extra diving connections, but we'll only display the first one.
|
||||
for (MapConnection *connection : map->connections) {
|
||||
if (connection->direction == "dive" || connection->direction == "emerge") {
|
||||
continue;
|
||||
if (connection->direction == "dive") {
|
||||
if (ui->comboBox_DiveMap->currentText().isEmpty())
|
||||
ui->comboBox_DiveMap->setCurrentText(connection->map_name);
|
||||
} else if (connection->direction == "emerge") {
|
||||
if (ui->comboBox_EmergeMap->currentText().isEmpty())
|
||||
ui->comboBox_EmergeMap->setCurrentText(connection->map_name);
|
||||
} else {
|
||||
// We allow any unknown direction names here. They'll be editable from the list menu.
|
||||
createConnectionItem(connection);
|
||||
}
|
||||
createConnectionItem(connection);
|
||||
}
|
||||
|
||||
if (!connection_items.empty()) {
|
||||
onConnectionItemSelected(connection_items.first());
|
||||
}
|
||||
|
||||
maskNonVisibleConnectionTiles();
|
||||
if (!connection_items.empty())
|
||||
setSelectedConnection(connection_items.first());
|
||||
}
|
||||
|
||||
void Editor::createConnectionItem(MapConnection* connection) {
|
||||
Map *connected_map = project->getMap(connection->map_name);
|
||||
if (!connected_map) {
|
||||
if (!connection)
|
||||
return;
|
||||
}
|
||||
|
||||
QPixmap pixmap = connected_map->renderConnection(*connection, map->layout);
|
||||
QPoint pos = calculateConnectionPosition(connection, pixmap);
|
||||
|
||||
QPixmap pixmap = getConnectionPixmap(*connection);
|
||||
QPoint pos = calculateConnectionPosition(*connection, pixmap);
|
||||
ConnectionPixmapItem *item = new ConnectionPixmapItem(pixmap, connection, pos.x(), pos.y(), map->getWidth(), map->getHeight());
|
||||
item->setX(pos.x());
|
||||
item->setY(pos.y());
|
||||
item->setZValue(-1);
|
||||
item->render();
|
||||
scene->addItem(item);
|
||||
|
||||
connect(item, &ConnectionPixmapItem::connectionItemSelected, this, &Editor::onConnectionItemSelected);
|
||||
connect(item, &ConnectionPixmapItem::selectionChanged, [this, item](bool selected) {
|
||||
if (selected) setSelectedConnection(item);
|
||||
});
|
||||
connect(item, &ConnectionPixmapItem::connectionItemDoubleClicked, [this, item] {
|
||||
emit this->connectionItemDoubleClicked(item->connection->map_name, map->name);
|
||||
});
|
||||
|
||||
connection_items.append(item);
|
||||
addConnectionToList(item);
|
||||
}
|
||||
|
||||
// Hides connected map tiles that cannot be seen from the current map (beyond BORDER_DISTANCE).
|
||||
|
@ -1891,14 +1857,12 @@ void Editor::updateMapBorder() {
|
|||
}
|
||||
|
||||
void Editor::updateMapConnections() {
|
||||
for (int i = 0; i < connection_items.size(); i++) {
|
||||
Map *connected_map = project->getMap(connection_items[i]->connection->map_name);
|
||||
if (!connected_map)
|
||||
for (auto item : connection_items) {
|
||||
if (!item->connection)
|
||||
continue;
|
||||
|
||||
QPixmap pixmap = connected_map->renderConnection(*(connection_items[i]->connection), map->layout);
|
||||
connection_items[i]->basePixmap = pixmap;
|
||||
connection_items[i]->setPixmap(pixmap);
|
||||
QPixmap pixmap = getConnectionPixmap(*item->connection);
|
||||
item->basePixmap = pixmap;
|
||||
item->setPixmap(pixmap);
|
||||
}
|
||||
|
||||
maskNonVisibleConnectionTiles();
|
||||
|
@ -1992,7 +1956,7 @@ void Editor::updateBorderVisibility() {
|
|||
item->setVisible(visible);
|
||||
item->setEditable(editingConnections);
|
||||
item->setEnabled(visible);
|
||||
item->updateHighlight(item == selected_connection_item);
|
||||
item->render();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -736,6 +736,13 @@ void MainWindow::on_action_Reload_Project_triggered() {
|
|||
// setMap, but with a visible error message in case of failure.
|
||||
// Use when the user is specifically requesting a map to open.
|
||||
bool MainWindow::userSetMap(QString map_name, bool scrollTreeView) {
|
||||
if (map_name == DYNAMIC_MAP_NAME) {
|
||||
QMessageBox msgBox(this);
|
||||
QString errorMsg = QString("The map '%1' can't be opened, it's a placeholder to indicate the specified map will be set programmatically.").arg(map_name);
|
||||
msgBox.critical(nullptr, "Error Opening Map", errorMsg);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!setMap(map_name, scrollTreeView)) {
|
||||
QMessageBox msgBox(this);
|
||||
QString errorMsg = QString("There was an error opening map %1. Please see %2 for full error details.\n\n%3")
|
||||
|
@ -750,7 +757,7 @@ bool MainWindow::userSetMap(QString map_name, bool scrollTreeView) {
|
|||
|
||||
bool MainWindow::setMap(QString map_name, bool scrollTreeView) {
|
||||
logInfo(QString("Setting map to '%1'").arg(map_name));
|
||||
if (map_name.isEmpty()) {
|
||||
if (map_name.isEmpty() || map_name == DYNAMIC_MAP_NAME) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -828,10 +835,6 @@ void MainWindow::refreshMapScene()
|
|||
}
|
||||
|
||||
void MainWindow::openWarpMap(QString map_name, int event_id, Event::Group event_group) {
|
||||
// Can't warp to dynamic maps
|
||||
if (map_name == DYNAMIC_MAP_NAME)
|
||||
return;
|
||||
|
||||
// Ensure valid destination map name.
|
||||
if (!editor->project->mapNames.contains(map_name)) {
|
||||
logError(QString("Invalid map name '%1'").arg(map_name));
|
||||
|
@ -1846,6 +1849,8 @@ void MainWindow::on_mainTabBar_tabBarClicked(int index)
|
|||
clickToolButtonFromEditMode(editor->obj_edit_mode);
|
||||
} else if (index == MainTab::Connections) {
|
||||
editor->setEditingConnections();
|
||||
// Stop the Dive/Emerge combo boxes from getting the initial focus
|
||||
ui->graphicsView_Map->setFocus();
|
||||
}
|
||||
if (index != MainTab::WildPokemon) {
|
||||
if (editor->project && editor->project->wildEncountersLoaded)
|
||||
|
@ -2577,13 +2582,13 @@ void MainWindow::on_pushButton_ConfigureEncountersJSON_clicked() {
|
|||
|
||||
void MainWindow::on_button_OpenDiveMap_clicked() {
|
||||
const QString mapName = ui->comboBox_DiveMap->currentText();
|
||||
if (mapName != DYNAMIC_MAP_NAME && editor->project->mapNames.contains(mapName))
|
||||
if (editor->project->mapNames.contains(mapName))
|
||||
userSetMap(mapName, true);
|
||||
}
|
||||
|
||||
void MainWindow::on_button_OpenEmergeMap_clicked() {
|
||||
const QString mapName = ui->comboBox_EmergeMap->currentText();
|
||||
if (mapName != DYNAMIC_MAP_NAME && editor->project->mapNames.contains(mapName))
|
||||
if (editor->project->mapNames.contains(mapName))
|
||||
userSetMap(mapName, true);
|
||||
}
|
||||
|
||||
|
|
|
@ -117,6 +117,9 @@ void Project::clearTilesetCache() {
|
|||
}
|
||||
|
||||
Map* Project::loadMap(QString map_name) {
|
||||
if (map_name == DYNAMIC_MAP_NAME)
|
||||
return nullptr;
|
||||
|
||||
Map *map;
|
||||
if (mapCache.contains(map_name)) {
|
||||
map = mapCache.value(map_name);
|
||||
|
|
|
@ -2,15 +2,28 @@
|
|||
|
||||
#include <math.h>
|
||||
|
||||
void ConnectionPixmapItem::render(qreal opacity) {
|
||||
QPixmap newPixmap = this->basePixmap.copy(0, 0, this->basePixmap.width(), this->basePixmap.height());
|
||||
if (opacity < 1) {
|
||||
QPainter painter(&newPixmap);
|
||||
int alpha = static_cast<int>(255 * (1 - opacity));
|
||||
painter.fillRect(0, 0, newPixmap.width(), newPixmap.height(), QColor(0, 0, 0, alpha));
|
||||
painter.end();
|
||||
void ConnectionPixmapItem::render() {
|
||||
QPixmap pixmap = this->basePixmap.copy(0, 0, this->basePixmap.width(), this->basePixmap.height());
|
||||
this->setZValue(-1);
|
||||
|
||||
// When editing is inactive the current selection is ignored, all connections should appear normal.
|
||||
if (this->getEditable()) {
|
||||
if (this->selected) {
|
||||
// Draw highlight
|
||||
QPainter painter(&pixmap);
|
||||
painter.setPen(QColor(255, 0, 255));
|
||||
painter.drawRect(0, 0, pixmap.width() - 1, pixmap.height() - 1);
|
||||
painter.end();
|
||||
} else {
|
||||
// Darken the image
|
||||
this->setZValue(-2);
|
||||
QPainter painter(&pixmap);
|
||||
int alpha = static_cast<int>(255 * 0.25);
|
||||
painter.fillRect(0, 0, pixmap.width(), pixmap.height(), QColor(0, 0, 0, alpha));
|
||||
painter.end();
|
||||
}
|
||||
}
|
||||
this->setPixmap(newPixmap);
|
||||
this->setPixmap(pixmap);
|
||||
}
|
||||
|
||||
QVariant ConnectionPixmapItem::itemChange(GraphicsItemChange change, const QVariant &value)
|
||||
|
@ -20,7 +33,7 @@ QVariant ConnectionPixmapItem::itemChange(GraphicsItemChange change, const QVari
|
|||
|
||||
qreal x, y;
|
||||
int newOffset = this->initialOffset;
|
||||
if (this->connection->direction == "up" || this->connection->direction == "down") {
|
||||
if (MapConnection::isVertical(this->connection->direction)) {
|
||||
x = round(newPos.x() / 16) * 16;
|
||||
newOffset += (x - initialX) / 16;
|
||||
x = newOffset * 16;
|
||||
|
@ -29,7 +42,7 @@ QVariant ConnectionPixmapItem::itemChange(GraphicsItemChange change, const QVari
|
|||
x = this->initialX;
|
||||
}
|
||||
|
||||
if (this->connection->direction == "right" || this->connection->direction == "left") {
|
||||
if (MapConnection::isHorizontal(this->connection->direction)) {
|
||||
y = round(newPos.y() / 16) * 16;
|
||||
newOffset += (y - this->initialY) / 16;
|
||||
y = newOffset * 16;
|
||||
|
@ -56,41 +69,18 @@ bool ConnectionPixmapItem::getEditable() {
|
|||
return (this->flags() & ItemIsMovable) != 0;
|
||||
}
|
||||
|
||||
// TODO: Consider whether it still makes sense to highlight the "current" connection (given you can edit them at any point now)
|
||||
void ConnectionPixmapItem::updateHighlight(bool selected) {
|
||||
const int normalZ = -1;
|
||||
const qreal normalOpacity = 1.0;
|
||||
|
||||
// When editing is inactive the current selection is ignored, all connections should appear normal.
|
||||
if (!this->getEditable()) {
|
||||
this->setZValue(normalZ);
|
||||
this->render(normalOpacity);
|
||||
void ConnectionPixmapItem::setSelected(bool selected) {
|
||||
if (this->selected == selected)
|
||||
return;
|
||||
}
|
||||
|
||||
this->setZValue(selected ? normalZ : -2);
|
||||
this->render(selected ? normalOpacity : 0.75);
|
||||
|
||||
if (selected) {
|
||||
// Draw highlight
|
||||
QPixmap pixmap = this->pixmap();
|
||||
QPainter painter(&pixmap);
|
||||
painter.setPen(QColor(255, 0, 255));
|
||||
painter.drawRect(0, 0, pixmap.width() - 1, pixmap.height() - 1);
|
||||
painter.end();
|
||||
this->setPixmap(pixmap);
|
||||
}
|
||||
|
||||
// Let the list UI know if the selection highlight changes so it can update accordingly
|
||||
if (this->highlighted != selected)
|
||||
emit highlightChanged(selected);
|
||||
this->highlighted = selected;
|
||||
this->selected = selected;
|
||||
this->render();
|
||||
emit selectionChanged(selected);
|
||||
}
|
||||
|
||||
void ConnectionPixmapItem::mousePressEvent(QGraphicsSceneMouseEvent *) {
|
||||
if (!this->getEditable())
|
||||
return;
|
||||
emit connectionItemSelected(this);
|
||||
this->setSelected(true);
|
||||
}
|
||||
|
||||
void ConnectionPixmapItem::mouseDoubleClickEvent(QGraphicsSceneMouseEvent *) {
|
||||
|
|
|
@ -1,8 +1,6 @@
|
|||
#include "connectionslistitem.h"
|
||||
#include "ui_connectionslistitem.h"
|
||||
|
||||
static const QStringList directions = {"up", "down", "left", "right"};
|
||||
|
||||
ConnectionsListItem::ConnectionsListItem(QWidget *parent, MapConnection * connection, const QStringList &mapNames) :
|
||||
QFrame(parent),
|
||||
ui(new Ui::ConnectionsListItem)
|
||||
|
@ -15,7 +13,7 @@ ConnectionsListItem::ConnectionsListItem(QWidget *parent, MapConnection * connec
|
|||
|
||||
ui->comboBox_Direction->setEditable(false);
|
||||
ui->comboBox_Direction->setMinimumContentsLength(0);
|
||||
ui->comboBox_Direction->addItems(directions);
|
||||
ui->comboBox_Direction->addItems(MapConnection::cardinalDirections);
|
||||
|
||||
ui->comboBox_Map->setMinimumContentsLength(6);
|
||||
ui->comboBox_Map->addItems(mapNames);
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
#include "noscrollcombobox.h"
|
||||
|
||||
#include <QCompleter>
|
||||
#include <QLineEdit>
|
||||
|
||||
NoScrollComboBox::NoScrollComboBox(QWidget *parent)
|
||||
: QComboBox(parent)
|
||||
|
@ -61,3 +62,8 @@ void NoScrollComboBox::setHexItem(uint32_t value)
|
|||
{
|
||||
this->setItem(this->findData(value), "0x" + QString::number(value, 16).toUpper());
|
||||
}
|
||||
|
||||
void NoScrollComboBox::setClearButtonEnabled(bool enabled) {
|
||||
if (this->lineEdit())
|
||||
this->lineEdit()->setClearButtonEnabled(enabled);
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue