Merge pull request #709 from GriffinRichards/image-exporter

Update map image exporter
This commit is contained in:
GriffinR
2025-04-07 13:04:34 -04:00
committed by GitHub
21 changed files with 889 additions and 513 deletions

View File

@@ -7,7 +7,7 @@
<x>0</x>
<y>0</y>
<width>817</width>
<height>535</height>
<height>556</height>
</rect>
</property>
<property name="windowTitle">
@@ -25,6 +25,9 @@
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="focusPolicy">
<enum>Qt::FocusPolicy::ClickFocus</enum>
</property>
<layout class="QVBoxLayout" name="verticalLayout_Options">
<item>
<layout class="QFormLayout" name="formLayout">
@@ -37,6 +40,9 @@
</item>
<item row="0" column="1">
<widget class="NoScrollComboBox" name="comboBox_MapSelection">
<property name="insertPolicy">
<enum>QComboBox::InsertPolicy::NoInsert</enum>
</property>
<property name="sizeAdjustPolicy">
<enum>QComboBox::SizeAdjustPolicy::AdjustToContents</enum>
</property>
@@ -163,7 +169,7 @@
</widget>
</item>
<item row="1" column="0">
<widget class="QCheckBox" name="checkBox_Elevation">
<widget class="QCheckBox" name="checkBox_Collision">
<property name="text">
<string>Collision</string>
</property>
@@ -188,7 +194,10 @@
</property>
<layout class="QGridLayout" name="gridLayout_7">
<item row="2" column="1">
<widget class="QSpinBox" name="spinBox_TimelapseDelay">
<widget class="NoScrollSpinBox" name="spinBox_TimelapseDelay">
<property name="focusPolicy">
<enum>Qt::FocusPolicy::StrongFocus</enum>
</property>
<property name="specialValueText">
<string/>
</property>
@@ -214,7 +223,10 @@
</widget>
</item>
<item row="3" column="1">
<widget class="QSpinBox" name="spinBox_FrameSkip">
<widget class="NoScrollSpinBox" name="spinBox_FrameSkip">
<property name="focusPolicy">
<enum>Qt::FocusPolicy::StrongFocus</enum>
</property>
<property name="suffix">
<string/>
</property>
@@ -250,9 +262,22 @@
</spacer>
</item>
<item>
<widget class="QCheckBox" name="checkBox_ActualSize">
<widget class="QCheckBox" name="checkBox_DisablePreviewUpdates">
<property name="toolTip">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;If checked, the image in the preview window will not be recreated when the settings are changed.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="text">
<string>Preview actual size</string>
<string>Disable preview updates</string>
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="checkBox_DisablePreviewScaling">
<property name="toolTip">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;If checked, the image shown in the preview window will not scale to fit into the available space. The aspect ratio of the image will never change.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="text">
<string>Disable preview scaling</string>
</property>
</widget>
</item>
@@ -263,6 +288,9 @@
<property name="text">
<string>Reset</string>
</property>
<property name="autoDefault">
<bool>false</bool>
</property>
</widget>
</item>
<item>
@@ -283,6 +311,9 @@
<property name="text">
<string>Cancel</string>
</property>
<property name="autoDefault">
<bool>false</bool>
</property>
</widget>
</item>
<item>
@@ -290,6 +321,9 @@
<property name="text">
<string>Save</string>
</property>
<property name="autoDefault">
<bool>false</bool>
</property>
</widget>
</item>
</layout>
@@ -323,16 +357,22 @@
</property>
<item row="0" column="0">
<widget class="QScrollArea" name="scrollArea_Preview">
<property name="sizeAdjustPolicy">
<enum>QAbstractScrollArea::SizeAdjustPolicy::AdjustToContents</enum>
</property>
<property name="widgetResizable">
<bool>true</bool>
</property>
<property name="alignment">
<set>Qt::AlignmentFlag::AlignCenter</set>
</property>
<widget class="QWidget" name="scrollAreaWidgetContents">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>469</width>
<height>464</height>
<height>485</height>
</rect>
</property>
<layout class="QGridLayout" name="gridLayout">
@@ -398,6 +438,11 @@
<extends>QComboBox</extends>
<header>noscrollcombobox.h</header>
</customwidget>
<customwidget>
<class>NoScrollSpinBox</class>
<extends>QSpinBox</extends>
<header>noscrollspinbox.h</header>
</customwidget>
</customwidgets>
<resources/>
<connections/>

View File

@@ -47,6 +47,13 @@ enum CommandId {
#define IDMask_EventType_Trigger (1 << 11)
#define IDMask_EventType_Heal (1 << 12)
#define IDMask_ConnectionDirection_Up (1 << 8)
#define IDMask_ConnectionDirection_Down (1 << 9)
#define IDMask_ConnectionDirection_Left (1 << 10)
#define IDMask_ConnectionDirection_Right (1 << 11)
#define IDMask_ConnectionDirection_Dive (1 << 12)
#define IDMask_ConnectionDirection_Emerge (1 << 13)
/// Implements a command to commit metatile paint actions
/// onto the map using the pencil tool.
class PaintMetatile : public QUndoCommand {
@@ -400,7 +407,7 @@ public:
void redo() override;
bool mergeWith(const QUndoCommand *command) override;
int id() const override { return CommandId::ID_MapConnectionMove; }
int id() const override;
private:
MapConnection *connection;
@@ -421,7 +428,7 @@ public:
void undo() override;
void redo() override;
int id() const override { return CommandId::ID_MapConnectionChangeDirection; }
int id() const override;
private:
QPointer<MapConnection> connection;
@@ -443,7 +450,7 @@ public:
void undo() override;
void redo() override;
int id() const override { return CommandId::ID_MapConnectionChangeMap; }
int id() const override;
private:
QPointer<MapConnection> connection;
@@ -465,7 +472,7 @@ public:
void undo() override;
void redo() override;
int id() const override { return CommandId::ID_MapConnectionAdd; }
int id() const override;
private:
Map *map = nullptr;
@@ -485,7 +492,7 @@ public:
void undo() override;
void redo() override;
int id() const override { return CommandId::ID_MapConnectionRemove; }
int id() const override;
private:
Map *map = nullptr;

View File

@@ -170,6 +170,7 @@ public:
static QString typeToJsonKey(Event::Type type);
static Event::Type typeFromJsonKey(QString type);
static QList<Event::Type> types();
static QList<Event::Group> groups();
// protected attributes
protected:
@@ -616,6 +617,10 @@ private:
};
inline uint qHash(const Event::Group &key, uint seed = 0) {
return qHash(static_cast<int>(key), seed);
}
///
/// Keeps track of scripts

View File

@@ -86,7 +86,7 @@ public:
bool hasEvent(Event *) const;
void deleteConnections();
QList<MapConnection*> getConnections() const;
QList<MapConnection*> getConnections() const { return m_connections; }
void removeConnection(MapConnection *);
void addConnection(MapConnection *);
void loadConnection(MapConnection *);

View File

@@ -26,13 +26,19 @@ public:
QString direction() const { return m_direction; }
void setDirection(const QString &direction, bool mirror = true);
bool isCardinal() const { return isCardinal(m_direction); }
bool isHorizontal() const { return isHorizontal(m_direction); }
bool isVertical() const { return isVertical(m_direction); }
bool isDiving() const { return isDiving(m_direction); }
int offset() const { return m_offset; }
void setOffset(int offset, bool mirror = true);
MapConnection* findMirror();
MapConnection* createMirror();
QPixmap getPixmap();
QPixmap render() const;
QPoint relativePos(bool clipped = false) const;
static QPointer<Project> project;
static const QMap<QString, QString> oppositeDirections;

View File

@@ -94,9 +94,12 @@ public:
int getHeight() const { return height; }
int getBorderWidth() const { return border_width; }
int getBorderHeight() const { return border_height; }
int getBorderDrawWidth() const;
int getBorderDrawHeight() const;
bool isWithinBounds(int x, int y);
bool isWithinBorderBounds(int x, int y);
bool isWithinBounds(int x, int y) const;
bool isWithinBounds(const QRect &rect) const;
bool isWithinBorderBounds(int x, int y) const;
bool getBlock(int x, int y, Block *out);
void setBlock(int x, int y, Block block, bool enableScriptCallback = false);
@@ -139,6 +142,8 @@ private:
void setNewDimensionsBlockdata(int newWidth, int newHeight);
void setNewBorderDimensionsBlockdata(int newWidth, int newHeight);
static int getBorderDrawDistance(int dimension, qreal minimum);
signals:
void dimensionsChanged(const QSize &size);
void needsRedrawing();

View File

@@ -175,8 +175,6 @@ public:
void eventsView_onMousePress(QMouseEvent *event);
int getBorderDrawDistance(int dimension);
bool selectingEvent = false;
void deleteSelectedEvents();

View File

@@ -301,6 +301,10 @@ public:
Ui::MainWindow *ui;
QPointer<Editor> editor = nullptr;
signals:
void mapOpened(Map*);
void layoutOpened(Layout*);
private:
QLabel *label_MapRulerStatus = nullptr;
QPointer<TilesetEditor> tilesetEditor = nullptr;

View File

@@ -1,10 +1,9 @@
#ifndef MAPIMAGEEXPORTER_H
#define MAPIMAGEEXPORTER_H
#include "map.h"
#include "editor.h"
#include "project.h"
#include <QDialog>
class QGifImage;
namespace Ui {
class MapImageExporter;
@@ -17,21 +16,17 @@ enum ImageExporterMode {
};
struct ImageExporterSettings {
bool showObjects = false;
bool showWarps = false;
bool showBGs = false;
bool showTriggers = false;
bool showHealLocations = false;
bool showUpConnections = false;
bool showDownConnections = false;
bool showLeftConnections = false;
bool showRightConnections = false;
QSet<Event::Group> showEvents;
QSet<QString> showConnections;
bool showGrid = false;
bool showBorder = false;
bool showCollision = false;
bool previewActualSize = false;
bool disablePreviewScaling = false;
bool disablePreviewUpdates = false;
int timelapseSkipAmount = 1;
int timelapseDelayMs = 200;
// Not exposed as a setting in the UI atm (our color input widget has no alpha channel).
QColor fillColor = Qt::transparent;
};
class MapImageExporter : public QDialog
@@ -39,32 +34,58 @@ class MapImageExporter : public QDialog
Q_OBJECT
public:
explicit MapImageExporter(QWidget *parent, Editor *editor, ImageExporterMode mode);
explicit MapImageExporter(QWidget *parent, Project *project, Map *map, ImageExporterMode mode = ImageExporterMode::Normal)
: MapImageExporter(parent, project, map, map->layout(), mode) {};
explicit MapImageExporter(QWidget *parent, Project *project, Layout *layout, ImageExporterMode mode = ImageExporterMode::Normal)
: MapImageExporter(parent, project, nullptr, layout, mode) {};
~MapImageExporter();
ImageExporterMode mode() const { return m_mode; }
void setMap(Map *map);
void setLayout(Layout *layout);
private:
explicit MapImageExporter(QWidget *parent, Project *project, Map *map, Layout *layout, ImageExporterMode mode);
Ui::MapImageExporter *ui;
Layout *m_layout = nullptr;
Project *m_project = nullptr;
Map *m_map = nullptr;
Editor *m_editor = nullptr;
Layout *m_layout = nullptr;
QGraphicsScene *m_scene = nullptr;
QPixmap m_preview;
QGifImage *m_timelapseGifImage = nullptr;
QBuffer *m_timelapseBuffer = nullptr;
QMovie *m_timelapseMovie = nullptr;
QGraphicsPixmapItem *m_preview = nullptr;
ImageExporterSettings m_settings;
ImageExporterMode m_mode = ImageExporterMode::Normal;
ImageExporterMode m_originalMode;
void updatePreview();
void setModeSpecificUi();
void setSelectionText(const QString &text);
void updateMapSelection();
void resetSettings();
QString getTitle(ImageExporterMode mode);
QString getDescription(ImageExporterMode mode);
void updatePreview(bool forceUpdate = false);
void scalePreview();
void updateShowBorderState();
bool eventsEnabled();
void setEventGroupEnabled(Event::Group group, bool enable);
bool connectionsEnabled();
void setConnectionDirectionEnabled(const QString &dir, bool enable);
void saveImage();
QPixmap getStitchedImage(QProgressDialog *progress, bool includeBorder);
QGifImage* createTimelapseGifImage(QProgressDialog *progress);
QPixmap getStitchedImage(QProgressDialog *progress);
QPixmap getFormattedMapPixmap();
QPixmap getFormattedMapPixmap(Map *map, bool ignoreBorder = false);
QPixmap getFormattedLayoutPixmap(Layout *layout, bool ignoreBorder = false, bool ignoreGrid = false);
void paintGrid(QPixmap *pixmap, bool ignoreBorder = false);
bool historyItemAppliesToFrame(const QUndoCommand *command);
void paintBorder(QPainter *painter, Layout *layout);
void paintCollision(QPainter *painter, Layout *layout);
void paintConnections(QPainter *painter, const Map *map);
void paintEvents(QPainter *painter, const Map *map);
void paintGrid(QPainter *painter, const Layout *layout = nullptr);
QMargins getMargins(const Map *map);
QPixmap getExpandedPixmap(const QPixmap &pixmap, const QSize &targetSize, const QColor &fillColor);
bool currentHistoryAppliesToFrame(QUndoStack *historyStack);
protected:
virtual void showEvent(QShowEvent *) override;
@@ -84,15 +105,16 @@ private slots:
void on_checkBox_ConnectionRight_stateChanged(int state);
void on_checkBox_AllConnections_stateChanged(int state);
void on_checkBox_Elevation_stateChanged(int state);
void on_checkBox_Collision_stateChanged(int state);
void on_checkBox_Grid_stateChanged(int state);
void on_checkBox_Border_stateChanged(int state);
void on_pushButton_Reset_pressed();
void on_spinBox_TimelapseDelay_valueChanged(int delayMs);
void on_spinBox_FrameSkip_valueChanged(int skip);
void on_spinBox_TimelapseDelay_editingFinished();
void on_spinBox_FrameSkip_editingFinished();
void on_checkBox_ActualSize_stateChanged(int state);
void on_checkBox_DisablePreviewScaling_stateChanged(int state);
void on_checkBox_DisablePreviewUpdates_stateChanged(int state);
};
#endif // MAPIMAGEEXPORTER_H

View File

@@ -5,7 +5,7 @@
#include <QDebug>
int getEventTypeMask(QList<Event *> events) {
int getEventTypeMask(const QList<Event *> &events) {
int eventTypeMask = 0;
for (auto event : events) {
Event::Group groupType = event->getEventGroup();
@@ -24,6 +24,26 @@ int getEventTypeMask(QList<Event *> events) {
return eventTypeMask;
}
int getConnectionDirectionMask(const QList<QString> &directions) {
int mask = 0;
for (auto direction : directions) {
if (direction == "up") {
mask |= IDMask_ConnectionDirection_Up;
} else if (direction == "down") {
mask |= IDMask_ConnectionDirection_Down;
} else if (direction == "left") {
mask |= IDMask_ConnectionDirection_Left;
} else if (direction == "right") {
mask |= IDMask_ConnectionDirection_Right;
} else if (direction == "dive") {
mask |= IDMask_ConnectionDirection_Dive;
} else if (direction == "emerge") {
mask |= IDMask_ConnectionDirection_Emerge;
}
}
return mask;
}
void renderBlocks(Layout *layout, bool ignoreCache = false) {
layout->layoutItem->draw(ignoreCache);
layout->collisionItem->draw(ignoreCache);
@@ -587,6 +607,10 @@ bool MapConnectionMove::mergeWith(const QUndoCommand *command) {
return true;
}
int MapConnectionMove::id() const {
return CommandId::ID_MapConnectionMove | getConnectionDirectionMask({this->connection->direction()});
}
/******************************************************************************
************************************************************************
******************************************************************************/
@@ -629,6 +653,10 @@ void MapConnectionChangeDirection::undo() {
QUndoCommand::undo();
}
int MapConnectionChangeDirection::id() const {
return CommandId::ID_MapConnectionChangeDirection | getConnectionDirectionMask({this->oldDirection, this->newDirection});
}
/******************************************************************************
************************************************************************
******************************************************************************/
@@ -664,6 +692,10 @@ void MapConnectionChangeMap::undo() {
QUndoCommand::undo();
}
int MapConnectionChangeMap::id() const {
return CommandId::ID_MapConnectionChangeMap | getConnectionDirectionMask({this->connection->direction()});
}
/******************************************************************************
************************************************************************
******************************************************************************/
@@ -708,6 +740,10 @@ void MapConnectionAdd::undo() {
QUndoCommand::undo();
}
int MapConnectionAdd::id() const {
return CommandId::ID_MapConnectionAdd | getConnectionDirectionMask({this->connection->direction()});
}
/******************************************************************************
************************************************************************
******************************************************************************/
@@ -745,3 +781,7 @@ void MapConnectionRemove::undo() {
QUndoCommand::undo();
}
int MapConnectionRemove::id() const {
return CommandId::ID_MapConnectionRemove | getConnectionDirectionMask({this->connection->direction()});
}

View File

@@ -73,17 +73,23 @@ void Event::modify() {
this->map->modify();
}
const QMap<Event::Group, QString> groupToStringMap = {
{Event::Group::Object, "Object"},
{Event::Group::Warp, "Warp"},
{Event::Group::Coord, "Trigger"},
{Event::Group::Bg, "BG"},
{Event::Group::Heal, "Heal Location"},
};
QString Event::groupToString(Event::Group group) {
static const QMap<Event::Group, QString> groupToStringMap = {
{Event::Group::Object, "Object"},
{Event::Group::Warp, "Warp"},
{Event::Group::Coord, "Trigger"},
{Event::Group::Bg, "BG"},
{Event::Group::Heal, "Heal Location"},
};
return groupToStringMap.value(group);
}
QList<Event::Group> Event::groups() {
static QList<Event::Group> groupList = groupToStringMap.keys();
return groupList;
}
// These are the expected key names used in the map.json files.
// We re-use them for key names in the copy/paste JSON data,
const QMap<Event::Type, QString> typeToJsonKeyMap = {

View File

@@ -232,10 +232,6 @@ void Map::deleteConnections() {
m_connections.clear();
}
QList<MapConnection*> Map::getConnections() const {
return m_connections;
}
void Map::addConnection(MapConnection *connection) {
if (!connection || m_connections.contains(connection))
return;
@@ -243,7 +239,7 @@ void Map::addConnection(MapConnection *connection) {
// Maps should only have one Dive/Emerge connection at a time.
// (Users can technically have more by editing their data manually, but we will only display one at a time)
// Any additional connections being added (this can happen via mirroring) are tracked for deleting but otherwise ignored.
if (MapConnection::isDiving(connection->direction())) {
if (connection->isDiving()) {
for (const auto &i : m_connections) {
if (i->direction() == connection->direction()) {
trackConnection(connection);

View File

@@ -60,7 +60,7 @@ Map* MapConnection::targetMap() const {
return getMap(m_targetMapName);
}
QPixmap MapConnection::getPixmap() {
QPixmap MapConnection::render() const {
auto map = targetMap();
if (!map)
return QPixmap();
@@ -68,6 +68,28 @@ QPixmap MapConnection::getPixmap() {
return map->renderConnection(m_direction, m_parentMap ? m_parentMap->layout() : nullptr);
}
// Get the position of the target map relative to its parent map.
// For right/down connections this is offset by the dimensions of the parent map.
// For left/up connections this is offset by the dimensions of the target map.
// If 'clipped' is true, only the rendered dimensions of the target map will be used, rather than its full dimensions.
QPoint MapConnection::relativePos(bool clipped) const {
int x = 0, y = 0;
if (m_direction == "right") {
if (m_parentMap) x = m_parentMap->getWidth();
y = m_offset;
} else if (m_direction == "down") {
x = m_offset;
if (m_parentMap) y = m_parentMap->getHeight();
} else if (m_direction == "left") {
if (targetMap()) x = !clipped ? -targetMap()->getWidth() : -targetMap()->getConnectionRect(m_direction).width();
y = m_offset;
} else if (m_direction == "up") {
x = m_offset;
if (targetMap()) y = !clipped ? -targetMap()->getHeight() : -targetMap()->getConnectionRect(m_direction).height();
}
return QPoint(x, y);
}
void MapConnection::setParentMap(Map* map, bool mirror) {
if (map == m_parentMap)
return;

View File

@@ -50,14 +50,37 @@ Layout::Settings Layout::settings() const {
return settings;
}
bool Layout::isWithinBounds(int x, int y) {
bool Layout::isWithinBounds(int x, int y) const {
return (x >= 0 && x < this->getWidth() && y >= 0 && y < this->getHeight());
}
bool Layout::isWithinBorderBounds(int x, int y) {
bool Layout::isWithinBounds(const QRect &rect) const {
return rect.left() >= 0 && rect.right() < this->getWidth() && rect.top() >= 0 && rect.bottom() < this->getHeight();
}
bool Layout::isWithinBorderBounds(int x, int y) const {
return (x >= 0 && x < this->getBorderWidth() && y >= 0 && y < this->getBorderHeight());
}
int Layout::getBorderDrawWidth() const {
return getBorderDrawDistance(border_width, BORDER_DISTANCE);
}
int Layout::getBorderDrawHeight() const {
return getBorderDrawDistance(border_height, BORDER_DISTANCE);
}
// We need to draw sufficient border blocks to fill the area that gets loaded around the player in-game (BORDER_DISTANCE).
// Note that this is not the same as the player's view distance.
// The result will be some multiple of the input dimension, because we only draw the border in increments of its full width/height.
int Layout::getBorderDrawDistance(int dimension, qreal minimum) {
if (dimension >= minimum)
return dimension;
// Get first multiple of dimension >= the minimum
return dimension * qCeil(minimum / qMax(dimension, 1));
}
bool Layout::getBlock(int x, int y, Block *out) {
if (isWithinBounds(x, y)) {
int i = y * getWidth() + x;

View File

@@ -761,7 +761,7 @@ void Editor::displayConnection(MapConnection *connection) {
if (!connection)
return;
if (MapConnection::isDiving(connection->direction())) {
if (connection->isDiving()) {
displayDivingConnection(connection);
return;
}
@@ -826,7 +826,7 @@ void Editor::removeConnectionPixmap(MapConnection *connection) {
if (!connection)
return;
if (MapConnection::isDiving(connection->direction())) {
if (connection->isDiving()) {
removeDivingMapPixmap(connection);
return;
}
@@ -1795,8 +1795,8 @@ void Editor::displayMapBorder() {
int borderWidth = this->layout->getBorderWidth();
int borderHeight = this->layout->getBorderHeight();
int borderHorzDist = getBorderDrawDistance(borderWidth);
int borderVertDist = getBorderDrawDistance(borderHeight);
int borderHorzDist = this->layout->getBorderDrawWidth();
int borderVertDist = this->layout->getBorderDrawHeight();
QPixmap pixmap = this->layout->renderBorder();
for (int y = -borderVertDist; y < this->layout->getHeight() + borderVertDist; y += borderHeight)
for (int x = -borderHorzDist; x < this->layout->getWidth() + borderHorzDist; x += borderWidth) {
@@ -1821,17 +1821,6 @@ void Editor::updateMapConnections() {
item->render(true);
}
int Editor::getBorderDrawDistance(int dimension) {
// Draw sufficient border blocks to fill the player's view (BORDER_DISTANCE)
if (dimension >= BORDER_DISTANCE) {
return dimension;
} else if (dimension) {
return dimension * (BORDER_DISTANCE / dimension + (BORDER_DISTANCE % dimension ? 1 : 0));
} else {
return BORDER_DISTANCE;
}
}
void Editor::toggleGrid(bool checked) {
if (porymapConfig.showGrid == checked)
return;

View File

@@ -960,6 +960,9 @@ bool MainWindow::setMap(QString map_name) {
Scripting::cb_MapOpened(map_name);
prefab.updatePrefabUi(editor->layout);
updateTilesetEditor();
emit mapOpened(editor->map);
return true;
}
@@ -1013,6 +1016,8 @@ bool MainWindow::setLayout(QString layoutId) {
userConfig.recentMapOrLayout = layoutId;
emit layoutOpened(editor->layout);
return true;
}
@@ -2555,12 +2560,23 @@ void MainWindow::on_actionImport_Map_from_Advance_Map_1_92_triggered() {
void MainWindow::showExportMapImageWindow(ImageExporterMode mode) {
if (!editor->project) return;
// If the user is requesting this window again we assume it's for a new
// window (the map/mode may have changed), so delete the old window.
if (this->mapImageExporter)
// If the user is requesting this window again with a different mode
// then we'll recreate the window with the new mode.
if (this->mapImageExporter && this->mapImageExporter->mode() != mode)
delete this->mapImageExporter;
this->mapImageExporter = new MapImageExporter(this, this->editor, mode);
if (!this->mapImageExporter) {
// Open new image export window
if (this->editor->map){
this->mapImageExporter = new MapImageExporter(this, this->editor->project, this->editor->map, mode);
} else if (this->editor->layout) {
this->mapImageExporter = new MapImageExporter(this, this->editor->project, this->editor->layout, mode);
}
if (this->mapImageExporter) {
connect(this, &MainWindow::mapOpened, this->mapImageExporter, &MapImageExporter::setMap);
connect(this, &MainWindow::layoutOpened, this->mapImageExporter, &MapImageExporter::setLayout);
}
}
openSubWindow(this->mapImageExporter);
}

View File

@@ -5,7 +5,7 @@
#include <math.h>
ConnectionPixmapItem::ConnectionPixmapItem(MapConnection* connection)
: QGraphicsPixmapItem(connection->getPixmap()),
: QGraphicsPixmapItem(connection->render()),
connection(connection)
{
this->setEditable(true);
@@ -28,7 +28,7 @@ void ConnectionPixmapItem::refresh() {
// Render additional visual effects on top of the base map image.
void ConnectionPixmapItem::render(bool ignoreCache) {
if (ignoreCache)
this->basePixmap = this->connection->getPixmap();
this->basePixmap = this->connection->render();
QPixmap pixmap = this->basePixmap.copy(0, 0, this->basePixmap.width(), this->basePixmap.height());
this->setZValue(-1);
@@ -63,10 +63,10 @@ QVariant ConnectionPixmapItem::itemChange(GraphicsItemChange change, const QVari
int newOffset = this->connection->offset();
// Restrict movement to the metatile grid and perpendicular to the connection direction.
if (MapConnection::isVertical(this->connection->direction())) {
if (this->connection->isVertical()) {
x = (round(newPos.x() / this->mWidth) * this->mWidth) - this->originX;
newOffset = x / this->mWidth;
} else if (MapConnection::isHorizontal(this->connection->direction())) {
} else if (this->connection->isHorizontal()) {
y = (round(newPos.y() / this->mHeight) * this->mHeight) - this->originY;
newOffset = y / this->mHeight;
}
@@ -87,9 +87,9 @@ void ConnectionPixmapItem::updatePos() {
qreal x = this->originX;
qreal y = this->originY;
if (MapConnection::isVertical(this->connection->direction())) {
if (this->connection->isVertical()) {
x += this->connection->offset() * this->mWidth;
} else if (MapConnection::isHorizontal(this->connection->direction())) {
} else if (this->connection->isHorizontal()) {
y += this->connection->offset() * this->mHeight;
}
@@ -98,22 +98,13 @@ void ConnectionPixmapItem::updatePos() {
}
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();
if (this->connection->isVertical()) {
this->originX = 0;
this->originY = this->connection->relativePos(true).y() * this->mHeight;
} else if (this->connection->isHorizontal()) {
this->originX = this->connection->relativePos(true).x() * this->mWidth;
this->originY = 0;
}
this->originX = x * this->mWidth;
this->originY = y * this->mHeight;
updatePos();
}

View File

@@ -25,7 +25,7 @@ QPixmap DivingMapPixmapItem::getBasePixmap(MapConnection* connection) {
return QPixmap(); // Save some rendering time if it won't be displayed
if (connection->targetMapName() == connection->parentMapName())
return QPixmap(); // If the map is connected to itself then rendering is pointless.
return connection->getPixmap();
return connection->render();
}
void DivingMapPixmapItem::updatePixmap() {

File diff suppressed because it is too large Load Diff

View File

@@ -356,6 +356,15 @@ QVector<QRgb> QGifImage::globalColorTable() const
return d->globalColorTable;
}
/*!
Return canvas size.
*/
QSize QGifImage::getCanvasSize() const
{
Q_D(const QGifImage);
return d->getCanvasSize();
}
/*!
Return background color of the gif canvas. It only makes sense when
global color table is not empty.

View File

@@ -52,6 +52,8 @@ public:
int loopCount() const;
void setLoopCount(int loop);
QSize getCanvasSize() const;
int frameCount() const;
QImage frame(int index) const;