mirror of
https://github.com/huderlem/porymap.git
synced 2026-08-23 17:16:17 -05:00
Merge pull request #709 from GriffinRichards/image-exporter
Update map image exporter
This commit is contained in:
@@ -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><html><head/><body><p>If checked, the image in the preview window will not be recreated when the settings are changed.</p></body></html></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><html><head/><body><p>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.</p></body></html></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/>
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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 *);
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -175,8 +175,6 @@ public:
|
||||
|
||||
void eventsView_onMousePress(QMouseEvent *event);
|
||||
|
||||
int getBorderDrawDistance(int dimension);
|
||||
|
||||
bool selectingEvent = false;
|
||||
|
||||
void deleteSelectedEvents();
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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()});
|
||||
}
|
||||
|
||||
@@ -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 = {
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
|
||||
@@ -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
9
src/vendor/QtGifImage/gifimage/qgifimage.cpp
vendored
9
src/vendor/QtGifImage/gifimage/qgifimage.cpp
vendored
@@ -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.
|
||||
|
||||
2
src/vendor/QtGifImage/gifimage/qgifimage.h
vendored
2
src/vendor/QtGifImage/gifimage/qgifimage.h
vendored
@@ -52,6 +52,8 @@ public:
|
||||
int loopCount() const;
|
||||
void setLoopCount(int loop);
|
||||
|
||||
QSize getCanvasSize() const;
|
||||
|
||||
int frameCount() const;
|
||||
QImage frame(int index) const;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user