mirror of
https://github.com/huderlem/porymap.git
synced 2026-04-25 23:37:52 -05:00
Allow vertical layout for layer view
This commit is contained in:
parent
a88730ee3f
commit
f6f07ca5fc
|
|
@ -158,7 +158,7 @@
|
||||||
<property name="minimumSize">
|
<property name="minimumSize">
|
||||||
<size>
|
<size>
|
||||||
<width>0</width>
|
<width>0</width>
|
||||||
<height>166</height>
|
<height>190</height>
|
||||||
</size>
|
</size>
|
||||||
</property>
|
</property>
|
||||||
<property name="frameShape">
|
<property name="frameShape">
|
||||||
|
|
@ -194,7 +194,7 @@
|
||||||
<property name="checkable">
|
<property name="checkable">
|
||||||
<bool>false</bool>
|
<bool>false</bool>
|
||||||
</property>
|
</property>
|
||||||
<layout class="QGridLayout" name="gridLayout_3">
|
<layout class="QGridLayout" name="gridLayout_MetatileProperties">
|
||||||
<item row="15" column="0" colspan="4">
|
<item row="15" column="0" colspan="4">
|
||||||
<widget class="QLineEdit" name="lineEdit_metatileLabel">
|
<widget class="QLineEdit" name="lineEdit_metatileLabel">
|
||||||
<property name="clearButtonEnabled">
|
<property name="clearButtonEnabled">
|
||||||
|
|
@ -451,12 +451,6 @@
|
||||||
</item>
|
</item>
|
||||||
<item row="4" column="0" colspan="2">
|
<item row="4" column="0" colspan="2">
|
||||||
<widget class="QFrame" name="frame_SelectedTile">
|
<widget class="QFrame" name="frame_SelectedTile">
|
||||||
<property name="sizePolicy">
|
|
||||||
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
|
|
||||||
<horstretch>0</horstretch>
|
|
||||||
<verstretch>0</verstretch>
|
|
||||||
</sizepolicy>
|
|
||||||
</property>
|
|
||||||
<property name="minimumSize">
|
<property name="minimumSize">
|
||||||
<size>
|
<size>
|
||||||
<width>98</width>
|
<width>98</width>
|
||||||
|
|
@ -497,16 +491,22 @@
|
||||||
</item>
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<widget class="QGraphicsView" name="graphicsView_selectedTile">
|
<widget class="QGraphicsView" name="graphicsView_selectedTile">
|
||||||
|
<property name="sizePolicy">
|
||||||
|
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
|
||||||
|
<horstretch>0</horstretch>
|
||||||
|
<verstretch>0</verstretch>
|
||||||
|
</sizepolicy>
|
||||||
|
</property>
|
||||||
<property name="minimumSize">
|
<property name="minimumSize">
|
||||||
<size>
|
<size>
|
||||||
<width>18</width>
|
<width>98</width>
|
||||||
<height>18</height>
|
<height>98</height>
|
||||||
</size>
|
</size>
|
||||||
</property>
|
</property>
|
||||||
<property name="maximumSize">
|
<property name="maximumSize">
|
||||||
<size>
|
<size>
|
||||||
<width>98</width>
|
<width>98</width>
|
||||||
<height>34</height>
|
<height>98</height>
|
||||||
</size>
|
</size>
|
||||||
</property>
|
</property>
|
||||||
<property name="frameShape">
|
<property name="frameShape">
|
||||||
|
|
@ -520,22 +520,22 @@
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
|
<item>
|
||||||
|
<spacer name="verticalSpacer_3">
|
||||||
|
<property name="orientation">
|
||||||
|
<enum>Qt::Orientation::Vertical</enum>
|
||||||
|
</property>
|
||||||
|
<property name="sizeHint" stdset="0">
|
||||||
|
<size>
|
||||||
|
<width>20</width>
|
||||||
|
<height>1</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
</spacer>
|
||||||
|
</item>
|
||||||
</layout>
|
</layout>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="6" column="0" colspan="2">
|
|
||||||
<spacer name="verticalSpacer_6">
|
|
||||||
<property name="orientation">
|
|
||||||
<enum>Qt::Orientation::Vertical</enum>
|
|
||||||
</property>
|
|
||||||
<property name="sizeHint" stdset="0">
|
|
||||||
<size>
|
|
||||||
<width>20</width>
|
|
||||||
<height>10</height>
|
|
||||||
</size>
|
|
||||||
</property>
|
|
||||||
</spacer>
|
|
||||||
</item>
|
|
||||||
</layout>
|
</layout>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
|
|
@ -686,6 +686,14 @@
|
||||||
<property name="title">
|
<property name="title">
|
||||||
<string>View</string>
|
<string>View</string>
|
||||||
</property>
|
</property>
|
||||||
|
<widget class="QMenu" name="menuLayer_Arrangement">
|
||||||
|
<property name="title">
|
||||||
|
<string>Layer Arrangement</string>
|
||||||
|
</property>
|
||||||
|
<addaction name="actionLayer_Arrangement_Horizontal"/>
|
||||||
|
<addaction name="actionLayer_Arrangement_Vertical"/>
|
||||||
|
</widget>
|
||||||
|
<addaction name="menuLayer_Arrangement"/>
|
||||||
<addaction name="actionLayer_Grid"/>
|
<addaction name="actionLayer_Grid"/>
|
||||||
<addaction name="actionMetatile_Grid"/>
|
<addaction name="actionMetatile_Grid"/>
|
||||||
<addaction name="actionShow_Tileset_Divider"/>
|
<addaction name="actionShow_Tileset_Divider"/>
|
||||||
|
|
@ -863,6 +871,22 @@
|
||||||
<string>Secondary...</string>
|
<string>Secondary...</string>
|
||||||
</property>
|
</property>
|
||||||
</action>
|
</action>
|
||||||
|
<action name="actionLayer_Arrangement_Horizontal">
|
||||||
|
<property name="checkable">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>Horizontal</string>
|
||||||
|
</property>
|
||||||
|
</action>
|
||||||
|
<action name="actionLayer_Arrangement_Vertical">
|
||||||
|
<property name="checkable">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>Vertical</string>
|
||||||
|
</property>
|
||||||
|
</action>
|
||||||
</widget>
|
</widget>
|
||||||
<customwidgets>
|
<customwidgets>
|
||||||
<customwidget>
|
<customwidget>
|
||||||
|
|
|
||||||
|
|
@ -108,6 +108,7 @@ public:
|
||||||
int metatilesZoom;
|
int metatilesZoom;
|
||||||
int tilesetEditorMetatilesZoom;
|
int tilesetEditorMetatilesZoom;
|
||||||
int tilesetEditorTilesZoom;
|
int tilesetEditorTilesZoom;
|
||||||
|
Qt::Orientation tilesetEditorLayerOrientation;
|
||||||
bool showPlayerView;
|
bool showPlayerView;
|
||||||
bool showCursorTile;
|
bool showCursorTile;
|
||||||
bool showBorder;
|
bool showBorder;
|
||||||
|
|
|
||||||
|
|
@ -9,28 +9,40 @@
|
||||||
class MetatileLayersItem: public SelectablePixmapItem {
|
class MetatileLayersItem: public SelectablePixmapItem {
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
public:
|
public:
|
||||||
MetatileLayersItem(Metatile *metatile, Tileset *primaryTileset, Tileset *secondaryTileset);
|
MetatileLayersItem(Metatile *metatile,
|
||||||
|
Tileset *primaryTileset,
|
||||||
|
Tileset *secondaryTileset,
|
||||||
|
Qt::Orientation orientation = Qt::Horizontal);
|
||||||
void draw();
|
void draw();
|
||||||
void setTilesets(Tileset*, Tileset*);
|
void setTilesets(Tileset*, Tileset*);
|
||||||
void setMetatile(Metatile*);
|
void setMetatile(Metatile*);
|
||||||
void clearLastModifiedCoords();
|
void clearLastModifiedCoords();
|
||||||
void clearLastHoveredCoords();
|
void clearLastHoveredCoords();
|
||||||
|
|
||||||
|
QPoint tileIndexToPos(int index) const { return this->tilePositions.value(index); }
|
||||||
|
int posToTileIndex(const QPoint &pos) const { return this->tilePositions.indexOf(pos); }
|
||||||
|
int posToTileIndex(int x, int y) const { return posToTileIndex(QPoint(x, y)); }
|
||||||
|
|
||||||
|
void setOrientation(Qt::Orientation orientation);
|
||||||
|
|
||||||
bool showGrid;
|
bool showGrid;
|
||||||
private:
|
private:
|
||||||
Metatile* metatile;
|
Metatile* metatile;
|
||||||
Tileset *primaryTileset;
|
Tileset *primaryTileset;
|
||||||
Tileset *secondaryTileset;
|
Tileset *secondaryTileset;
|
||||||
|
Qt::Orientation orientation;
|
||||||
QPoint prevChangedPos;
|
QPoint prevChangedPos;
|
||||||
QPoint prevHoveredPos;
|
QPoint prevHoveredPos;
|
||||||
|
|
||||||
|
QList<QPoint> tilePositions;
|
||||||
|
|
||||||
QPoint getBoundedPos(const QPointF &);
|
QPoint getBoundedPos(const QPointF &);
|
||||||
void requestTileChange(const QPoint &pos);
|
|
||||||
void requestPaletteChange(const QPoint &pos);
|
|
||||||
void updateSelection();
|
void updateSelection();
|
||||||
|
void hover(const QPoint &pos);
|
||||||
signals:
|
signals:
|
||||||
void tileChanged(const QPoint &pos);
|
void tileChanged(const QPoint &pos);
|
||||||
void paletteChanged(const QPoint &pos);
|
void paletteChanged(const QPoint &pos);
|
||||||
void selectedTilesChanged(QPoint, int, int);
|
void selectedTilesChanged(const QPoint &pos, const QSize &dimensions);
|
||||||
void hoveredTileChanged(const Tile &tile);
|
void hoveredTileChanged(const Tile &tile);
|
||||||
void hoveredTileCleared();
|
void hoveredTileCleared();
|
||||||
protected:
|
protected:
|
||||||
|
|
|
||||||
|
|
@ -19,9 +19,13 @@ public:
|
||||||
selectionOffsetX(0),
|
selectionOffsetX(0),
|
||||||
selectionOffsetY(0)
|
selectionOffsetY(0)
|
||||||
{}
|
{}
|
||||||
virtual QSize getSelectionDimensions() const;
|
virtual QSize getSelectionDimensions() const { return QSize(abs(this->selectionOffsetX) + 1, abs(this->selectionOffsetY) + 1); }
|
||||||
virtual void draw() = 0;
|
virtual void draw() = 0;
|
||||||
|
|
||||||
|
virtual void setMaxSelectionSize(const QSize &size) { setMaxSelectionSize(size.width(), size.height()); }
|
||||||
|
virtual void setMaxSelectionSize(int width, int height);
|
||||||
|
QSize maxSelectionSize() { return QSize(this->maxSelectionWidth, this->maxSelectionHeight); }
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
int cellWidth;
|
int cellWidth;
|
||||||
int cellHeight;
|
int cellHeight;
|
||||||
|
|
@ -33,17 +37,22 @@ protected:
|
||||||
int selectionOffsetY;
|
int selectionOffsetY;
|
||||||
|
|
||||||
QPoint getSelectionStart();
|
QPoint getSelectionStart();
|
||||||
void select(int x, int y, int width = 0, int height = 0);
|
void select(const QPoint &pos, const QSize &size = QSize(1,1));
|
||||||
void select(const QPoint &pos, const QSize &size = QSize(0,0)) { select(pos.x(), pos.y(), size.width(), size.height()); }
|
void select(int x, int y, int width = 1, int height = 1) { select(QPoint(x, y), QSize(width, height)); }
|
||||||
void updateSelection(int, int);
|
void updateSelection(const QPoint &pos);
|
||||||
QPoint getCellPos(QPointF);
|
QPoint getCellPos(QPointF);
|
||||||
virtual void mousePressEvent(QGraphicsSceneMouseEvent*) override;
|
virtual void mousePressEvent(QGraphicsSceneMouseEvent*) override;
|
||||||
virtual void mouseMoveEvent(QGraphicsSceneMouseEvent*) override;
|
virtual void mouseMoveEvent(QGraphicsSceneMouseEvent*) override;
|
||||||
virtual void mouseReleaseEvent(QGraphicsSceneMouseEvent*) override;
|
virtual void mouseReleaseEvent(QGraphicsSceneMouseEvent*) override;
|
||||||
virtual void drawSelection();
|
virtual void drawSelection();
|
||||||
|
virtual int cellsWide() const { return this->cellWidth ? (pixmap().width() / this->cellWidth) : 0; }
|
||||||
|
virtual int cellsTall() const { return this->cellHeight ? (pixmap().height() / this->cellHeight) : 0; }
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void selectionChanged(int, int, int, int);
|
void selectionChanged(const QPoint&, const QSize&);
|
||||||
|
|
||||||
|
private:
|
||||||
|
QPoint prevCellPos = QPoint(-1,-1);
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // SELECTABLEPIXMAPITEM_H
|
#endif // SELECTABLEPIXMAPITEM_H
|
||||||
|
|
|
||||||
|
|
@ -69,7 +69,7 @@ private slots:
|
||||||
void onHoveredTileChanged(const Tile&);
|
void onHoveredTileChanged(const Tile&);
|
||||||
void onHoveredTileChanged(uint16_t);
|
void onHoveredTileChanged(uint16_t);
|
||||||
void onHoveredTileCleared();
|
void onHoveredTileCleared();
|
||||||
void onMetatileLayerSelectionChanged(QPoint, int, int);
|
void onMetatileLayerSelectionChanged(const QPoint&, const QSize&);
|
||||||
void onPaletteEditorChangedPaletteColor();
|
void onPaletteEditorChangedPaletteColor();
|
||||||
|
|
||||||
void on_actionChange_Metatiles_Count_triggered();
|
void on_actionChange_Metatiles_Count_triggered();
|
||||||
|
|
@ -138,6 +138,7 @@ private:
|
||||||
void refreshTileFlips();
|
void refreshTileFlips();
|
||||||
void refreshPaletteId();
|
void refreshPaletteId();
|
||||||
void paintSelectedLayerTiles(const QPoint &pos, bool paletteOnly = false);
|
void paintSelectedLayerTiles(const QPoint &pos, bool paletteOnly = false);
|
||||||
|
void setMetatileLayerOrientation(Qt::Orientation orientation);
|
||||||
|
|
||||||
Ui::TilesetEditor *ui;
|
Ui::TilesetEditor *ui;
|
||||||
History<MetatileHistoryItem*> metatileHistory;
|
History<MetatileHistoryItem*> metatileHistory;
|
||||||
|
|
|
||||||
|
|
@ -7,8 +7,8 @@
|
||||||
class TilesetEditorTileSelector: public SelectablePixmapItem {
|
class TilesetEditorTileSelector: public SelectablePixmapItem {
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
public:
|
public:
|
||||||
TilesetEditorTileSelector(Tileset *primaryTileset, Tileset *secondaryTileset, int numLayers)
|
TilesetEditorTileSelector(Tileset *primaryTileset, Tileset *secondaryTileset)
|
||||||
: SelectablePixmapItem(16, 16, numLayers * Metatile::tileWidth(), Metatile::tileHeight()) {
|
: SelectablePixmapItem(16, 16, Metatile::tileWidth(), Metatile::tileWidth()) {
|
||||||
this->primaryTileset = primaryTileset;
|
this->primaryTileset = primaryTileset;
|
||||||
this->secondaryTileset = secondaryTileset;
|
this->secondaryTileset = secondaryTileset;
|
||||||
this->numTilesWide = 16;
|
this->numTilesWide = 16;
|
||||||
|
|
@ -19,6 +19,7 @@ public:
|
||||||
setAcceptHoverEvents(true);
|
setAcceptHoverEvents(true);
|
||||||
}
|
}
|
||||||
QSize getSelectionDimensions() const override;
|
QSize getSelectionDimensions() const override;
|
||||||
|
void setMaxSelectionSize(int width, int height) override;
|
||||||
void draw() override;
|
void draw() override;
|
||||||
void select(uint16_t metatileId);
|
void select(uint16_t metatileId);
|
||||||
void highlight(uint16_t metatileId);
|
void highlight(uint16_t metatileId);
|
||||||
|
|
@ -31,6 +32,7 @@ public:
|
||||||
QImage buildPrimaryTilesIndexedImage();
|
QImage buildPrimaryTilesIndexedImage();
|
||||||
QImage buildSecondaryTilesIndexedImage();
|
QImage buildSecondaryTilesIndexedImage();
|
||||||
|
|
||||||
|
|
||||||
QVector<uint16_t> usedTiles;
|
QVector<uint16_t> usedTiles;
|
||||||
bool showUnused = false;
|
bool showUnused = false;
|
||||||
bool showDivider = false;
|
bool showDivider = false;
|
||||||
|
|
@ -49,6 +51,7 @@ private:
|
||||||
int externalSelectionHeight;
|
int externalSelectionHeight;
|
||||||
QList<Tile> externalSelectedTiles;
|
QList<Tile> externalSelectedTiles;
|
||||||
QList<int> externalSelectedPos;
|
QList<int> externalSelectedPos;
|
||||||
|
QPoint prevCellPos = QPoint(-1,-1);
|
||||||
|
|
||||||
Tileset *primaryTileset;
|
Tileset *primaryTileset;
|
||||||
Tileset *secondaryTileset;
|
Tileset *secondaryTileset;
|
||||||
|
|
|
||||||
|
|
@ -338,6 +338,7 @@ void PorymapConfig::reset() {
|
||||||
this->metatilesZoom = 30;
|
this->metatilesZoom = 30;
|
||||||
this->tilesetEditorMetatilesZoom = 30;
|
this->tilesetEditorMetatilesZoom = 30;
|
||||||
this->tilesetEditorTilesZoom = 30;
|
this->tilesetEditorTilesZoom = 30;
|
||||||
|
this->tilesetEditorLayerOrientation = Qt::Horizontal;
|
||||||
this->showPlayerView = false;
|
this->showPlayerView = false;
|
||||||
this->showCursorTile = true;
|
this->showCursorTile = true;
|
||||||
this->showBorder = true;
|
this->showBorder = true;
|
||||||
|
|
@ -454,6 +455,9 @@ void PorymapConfig::parseConfigKeyValue(QString key, QString value) {
|
||||||
this->tilesetEditorMetatilesZoom = getConfigInteger(key, value, 10, 100, 30);
|
this->tilesetEditorMetatilesZoom = getConfigInteger(key, value, 10, 100, 30);
|
||||||
} else if (key == "tileset_editor_tiles_zoom") {
|
} else if (key == "tileset_editor_tiles_zoom") {
|
||||||
this->tilesetEditorTilesZoom = getConfigInteger(key, value, 10, 100, 30);
|
this->tilesetEditorTilesZoom = getConfigInteger(key, value, 10, 100, 30);
|
||||||
|
} else if (key == "tileset_editor_layer_orientation") {
|
||||||
|
// Being explicit here to avoid casting out-of-range values.
|
||||||
|
this->tilesetEditorLayerOrientation = (getConfigInteger(key, value) == static_cast<int>(Qt::Horizontal)) ? Qt::Horizontal : Qt::Vertical;
|
||||||
} else if (key == "show_player_view") {
|
} else if (key == "show_player_view") {
|
||||||
this->showPlayerView = getConfigBool(key, value);
|
this->showPlayerView = getConfigBool(key, value);
|
||||||
} else if (key == "show_cursor_tile") {
|
} else if (key == "show_cursor_tile") {
|
||||||
|
|
@ -604,6 +608,7 @@ QMap<QString, QString> PorymapConfig::getKeyValueMap() {
|
||||||
map.insert("metatiles_zoom", QString::number(this->metatilesZoom));
|
map.insert("metatiles_zoom", QString::number(this->metatilesZoom));
|
||||||
map.insert("tileset_editor_metatiles_zoom", QString::number(this->tilesetEditorMetatilesZoom));
|
map.insert("tileset_editor_metatiles_zoom", QString::number(this->tilesetEditorMetatilesZoom));
|
||||||
map.insert("tileset_editor_tiles_zoom", QString::number(this->tilesetEditorTilesZoom));
|
map.insert("tileset_editor_tiles_zoom", QString::number(this->tilesetEditorTilesZoom));
|
||||||
|
map.insert("tileset_editor_layer_orientation", QString::number(this->tilesetEditorLayerOrientation));
|
||||||
map.insert("show_player_view", this->showPlayerView ? "1" : "0");
|
map.insert("show_player_view", this->showPlayerView ? "1" : "0");
|
||||||
map.insert("show_cursor_tile", this->showCursorTile ? "1" : "0");
|
map.insert("show_cursor_tile", this->showCursorTile ? "1" : "0");
|
||||||
map.insert("show_border", this->showBorder ? "1" : "0");
|
map.insert("show_border", this->showBorder ? "1" : "0");
|
||||||
|
|
|
||||||
|
|
@ -1773,8 +1773,8 @@ void Editor::displayMovementPermissionSelector() {
|
||||||
this, &Editor::onHoveredMovementPermissionChanged);
|
this, &Editor::onHoveredMovementPermissionChanged);
|
||||||
connect(movement_permissions_selector_item, &MovementPermissionsSelector::hoveredMovementPermissionCleared,
|
connect(movement_permissions_selector_item, &MovementPermissionsSelector::hoveredMovementPermissionCleared,
|
||||||
this, &Editor::onHoveredMovementPermissionCleared);
|
this, &Editor::onHoveredMovementPermissionCleared);
|
||||||
connect(movement_permissions_selector_item, &SelectablePixmapItem::selectionChanged, [this](int x, int y, int, int) {
|
connect(movement_permissions_selector_item, &SelectablePixmapItem::selectionChanged, [this](const QPoint &pos, const QSize&) {
|
||||||
this->setCollisionTabSpinBoxes(x, y);
|
this->setCollisionTabSpinBoxes(pos.x(), pos.y());
|
||||||
});
|
});
|
||||||
movement_permissions_selector_item->select(projectConfig.defaultCollision, projectConfig.defaultElevation);
|
movement_permissions_selector_item->select(projectConfig.defaultCollision, projectConfig.defaultElevation);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1187,6 +1187,18 @@ bool Project::loadLayoutTilesets(Layout *layout) {
|
||||||
logError(QString("Failed to load %1: missing secondary tileset label.").arg(layout->name));
|
logError(QString("Failed to load %1: missing secondary tileset label.").arg(layout->name));
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
if (!this->primaryTilesetLabels.contains(layout->tileset_primary_label)) {
|
||||||
|
logError(QString("Failed to load %1: unknown primary tileset label '%2'.")
|
||||||
|
.arg(layout->name)
|
||||||
|
.arg(layout->tileset_primary_label));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (!this->secondaryTilesetLabels.contains(layout->tileset_secondary_label)) {
|
||||||
|
logError(QString("Failed to load %1: unknown secondary tileset label '%2'.")
|
||||||
|
.arg(layout->name)
|
||||||
|
.arg(layout->tileset_secondary_label));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
layout->tileset_primary = getTileset(layout->tileset_primary_label);
|
layout->tileset_primary = getTileset(layout->tileset_primary_label);
|
||||||
layout->tileset_secondary = getTileset(layout->tileset_secondary_label);
|
layout->tileset_secondary = getTileset(layout->tileset_secondary_label);
|
||||||
|
|
@ -1194,6 +1206,11 @@ bool Project::loadLayoutTilesets(Layout *layout) {
|
||||||
}
|
}
|
||||||
|
|
||||||
Tileset* Project::getTileset(const QString &label, bool forceLoad) {
|
Tileset* Project::getTileset(const QString &label, bool forceLoad) {
|
||||||
|
if (!this->tilesetLabelsOrdered.contains(label)) {
|
||||||
|
logError(QString("Unknown tileset name '%1'.").arg(label));
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
Tileset *tileset = nullptr;
|
Tileset *tileset = nullptr;
|
||||||
|
|
||||||
auto it = this->tilesetCache.constFind(label);
|
auto it = this->tilesetCache.constFind(label);
|
||||||
|
|
|
||||||
|
|
@ -3,8 +3,8 @@
|
||||||
#include "imageproviders.h"
|
#include "imageproviders.h"
|
||||||
#include <QPainter>
|
#include <QPainter>
|
||||||
|
|
||||||
MetatileLayersItem::MetatileLayersItem(Metatile *metatile, Tileset *primaryTileset, Tileset *secondaryTileset)
|
MetatileLayersItem::MetatileLayersItem(Metatile *metatile, Tileset *primaryTileset, Tileset *secondaryTileset, Qt::Orientation orientation)
|
||||||
: SelectablePixmapItem(16, 16, Metatile::tileWidth() * projectConfig.getNumLayersInMetatile(), Metatile::tileHeight()),
|
: SelectablePixmapItem(16, 16, Metatile::tileWidth(), Metatile::tileHeight()),
|
||||||
metatile(metatile),
|
metatile(metatile),
|
||||||
primaryTileset(primaryTileset),
|
primaryTileset(primaryTileset),
|
||||||
secondaryTileset(secondaryTileset)
|
secondaryTileset(secondaryTileset)
|
||||||
|
|
@ -12,28 +12,51 @@ MetatileLayersItem::MetatileLayersItem(Metatile *metatile, Tileset *primaryTiles
|
||||||
clearLastModifiedCoords();
|
clearLastModifiedCoords();
|
||||||
clearLastHoveredCoords();
|
clearLastHoveredCoords();
|
||||||
setAcceptHoverEvents(true);
|
setAcceptHoverEvents(true);
|
||||||
|
setOrientation(orientation);
|
||||||
}
|
}
|
||||||
|
|
||||||
static const QList<QPoint> tilePositions = {
|
void MetatileLayersItem::setOrientation(Qt::Orientation orientation) {
|
||||||
QPoint(0, 0),
|
this->orientation = orientation;
|
||||||
QPoint(1, 0),
|
int maxWidth = Metatile::tileWidth();
|
||||||
QPoint(0, 1),
|
int maxHeight = Metatile::tileHeight();
|
||||||
QPoint(1, 1),
|
|
||||||
QPoint(2, 0),
|
// Generate a table of tile positions that allows us to map between
|
||||||
QPoint(3, 0),
|
// the index of a tile in the metatile and its position in this layer view.
|
||||||
QPoint(2, 1),
|
this->tilePositions.clear();
|
||||||
QPoint(3, 1),
|
if (this->orientation == Qt::Horizontal) {
|
||||||
QPoint(4, 0),
|
// Tiles are laid out horizontally, with the bottom layer on the left:
|
||||||
QPoint(5, 0),
|
// 0 1 4 5 8 9
|
||||||
QPoint(4, 1),
|
// 2 3 6 7 10 11
|
||||||
QPoint(5, 1),
|
for (int layer = 0; layer < projectConfig.getNumLayersInMetatile(); layer++)
|
||||||
};
|
for (int y = 0; y < Metatile::tileHeight(); y++)
|
||||||
|
for (int x = 0; x < Metatile::tileWidth(); x++) {
|
||||||
|
this->tilePositions.append(QPoint(x + layer * Metatile::tileWidth(), y));
|
||||||
|
}
|
||||||
|
maxWidth *= projectConfig.getNumLayersInMetatile();
|
||||||
|
} else if (this->orientation == Qt::Vertical) {
|
||||||
|
// Tiles are laid out vertically, with the bottom layer on the bottom:
|
||||||
|
// 8 9
|
||||||
|
// 10 11
|
||||||
|
// 4 5
|
||||||
|
// 6 7
|
||||||
|
// 0 1
|
||||||
|
// 2 3
|
||||||
|
for (int layer = projectConfig.getNumLayersInMetatile() - 1; layer >= 0; layer--)
|
||||||
|
for (int y = 0; y < Metatile::tileHeight(); y++)
|
||||||
|
for (int x = 0; x < Metatile::tileWidth(); x++) {
|
||||||
|
this->tilePositions.append(QPoint(x, y + layer * Metatile::tileHeight()));
|
||||||
|
}
|
||||||
|
maxHeight *= projectConfig.getNumLayersInMetatile();
|
||||||
|
}
|
||||||
|
setMaxSelectionSize(maxWidth, maxHeight);
|
||||||
|
update();
|
||||||
|
if (!this->pixmap().isNull()) {
|
||||||
|
draw();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void MetatileLayersItem::draw() {
|
void MetatileLayersItem::draw() {
|
||||||
const int numLayers = projectConfig.getNumLayersInMetatile();
|
QPixmap pixmap(this->cellWidth * this->maxSelectionWidth, this->cellHeight * this->maxSelectionHeight);
|
||||||
const int layerWidth = this->cellWidth * Metatile::tileWidth();
|
|
||||||
const int layerHeight = this->cellHeight * Metatile::tileHeight();
|
|
||||||
QPixmap pixmap(numLayers * layerWidth, layerHeight);
|
|
||||||
QPainter painter(&pixmap);
|
QPainter painter(&pixmap);
|
||||||
|
|
||||||
// Draw tile images
|
// Draw tile images
|
||||||
|
|
@ -47,15 +70,22 @@ void MetatileLayersItem::draw() {
|
||||||
true
|
true
|
||||||
).scaled(this->cellWidth, this->cellHeight);
|
).scaled(this->cellWidth, this->cellHeight);
|
||||||
tile.flip(&tileImage);
|
tile.flip(&tileImage);
|
||||||
QPoint pos = tilePositions.at(i);
|
QPoint pos = tileIndexToPos(i);
|
||||||
painter.drawImage(pos.x() * this->cellWidth, pos.y() * this->cellHeight, tileImage);
|
painter.drawImage(pos.x() * this->cellWidth, pos.y() * this->cellHeight, tileImage);
|
||||||
}
|
}
|
||||||
if (this->showGrid) {
|
if (this->showGrid) {
|
||||||
// Draw grid
|
// Draw grid
|
||||||
painter.setPen(Qt::white);
|
painter.setPen(Qt::white);
|
||||||
for (int i = 1; i < numLayers; i++) {
|
const int layerWidth = this->cellWidth * Metatile::tileWidth();
|
||||||
int x = i * layerWidth;
|
const int layerHeight = this->cellHeight * Metatile::tileHeight();
|
||||||
painter.drawLine(x, 0, x, layerHeight);
|
for (int i = 1; i < projectConfig.getNumLayersInMetatile(); i++) {
|
||||||
|
if (this->orientation == Qt::Vertical) {
|
||||||
|
int y = i * layerHeight;
|
||||||
|
painter.drawLine(0, y, layerWidth, y);
|
||||||
|
} else if (this->orientation == Qt::Horizontal) {
|
||||||
|
int x = i * layerWidth;
|
||||||
|
painter.drawLine(x, 0, x, layerHeight);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -76,51 +106,41 @@ void MetatileLayersItem::setTilesets(Tileset *primaryTileset, Tileset *secondary
|
||||||
this->clearLastHoveredCoords();
|
this->clearLastHoveredCoords();
|
||||||
}
|
}
|
||||||
|
|
||||||
// We request our current selection to be painted,
|
|
||||||
// this class doesn't handle changing the metatile data.
|
|
||||||
void MetatileLayersItem::requestTileChange(const QPoint &pos) {
|
|
||||||
this->prevChangedPos = pos;
|
|
||||||
this->clearLastHoveredCoords();
|
|
||||||
emit this->tileChanged(pos);
|
|
||||||
}
|
|
||||||
void MetatileLayersItem::requestPaletteChange(const QPoint &pos) {
|
|
||||||
this->prevChangedPos = pos;
|
|
||||||
this->clearLastHoveredCoords();
|
|
||||||
emit this->paletteChanged(pos);
|
|
||||||
}
|
|
||||||
|
|
||||||
void MetatileLayersItem::updateSelection() {
|
void MetatileLayersItem::updateSelection() {
|
||||||
QPoint selectionOrigin = this->getSelectionStart();
|
drawSelection();
|
||||||
QSize dimensions = this->getSelectionDimensions();
|
emit selectedTilesChanged(getSelectionStart(), getSelectionDimensions());
|
||||||
emit this->selectedTilesChanged(selectionOrigin, dimensions.width(), dimensions.height());
|
|
||||||
this->drawSelection();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void MetatileLayersItem::mousePressEvent(QGraphicsSceneMouseEvent *event) {
|
void MetatileLayersItem::mousePressEvent(QGraphicsSceneMouseEvent *event) {
|
||||||
|
const QPoint pos = this->getBoundedPos(event->pos());
|
||||||
|
hover(pos);
|
||||||
|
|
||||||
if (event->buttons() & Qt::RightButton) {
|
if (event->buttons() & Qt::RightButton) {
|
||||||
SelectablePixmapItem::mousePressEvent(event);
|
SelectablePixmapItem::mousePressEvent(event);
|
||||||
updateSelection();
|
updateSelection();
|
||||||
} else if (event->modifiers() & Qt::ControlModifier) {
|
} else if (event->modifiers() & Qt::ControlModifier) {
|
||||||
requestPaletteChange(getBoundedPos(event->pos()));
|
emit paletteChanged(pos);
|
||||||
} else {
|
} else {
|
||||||
requestTileChange(getBoundedPos(event->pos()));
|
emit tileChanged(pos);
|
||||||
}
|
}
|
||||||
|
this->prevChangedPos = pos;
|
||||||
}
|
}
|
||||||
|
|
||||||
void MetatileLayersItem::mouseMoveEvent(QGraphicsSceneMouseEvent *event) {
|
void MetatileLayersItem::mouseMoveEvent(QGraphicsSceneMouseEvent *event) {
|
||||||
|
const QPoint pos = this->getBoundedPos(event->pos());
|
||||||
|
if (this->prevChangedPos == pos)
|
||||||
|
return;
|
||||||
|
hover(pos);
|
||||||
|
|
||||||
if (event->buttons() & Qt::RightButton) {
|
if (event->buttons() & Qt::RightButton) {
|
||||||
SelectablePixmapItem::mouseMoveEvent(event);
|
SelectablePixmapItem::mouseMoveEvent(event);
|
||||||
updateSelection();
|
updateSelection();
|
||||||
|
} else if (event->modifiers() & Qt::ControlModifier) {
|
||||||
|
emit paletteChanged(pos);
|
||||||
} else {
|
} else {
|
||||||
const QPoint pos = this->getBoundedPos(event->pos());
|
emit tileChanged(pos);
|
||||||
if (this->prevChangedPos != pos) {
|
|
||||||
if (event->modifiers() & Qt::ControlModifier) {
|
|
||||||
requestPaletteChange(pos);
|
|
||||||
} else {
|
|
||||||
requestTileChange(pos);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
this->prevChangedPos = pos;
|
||||||
}
|
}
|
||||||
|
|
||||||
void MetatileLayersItem::mouseReleaseEvent(QGraphicsSceneMouseEvent *event) {
|
void MetatileLayersItem::mouseReleaseEvent(QGraphicsSceneMouseEvent *event) {
|
||||||
|
|
@ -130,16 +150,19 @@ void MetatileLayersItem::mouseReleaseEvent(QGraphicsSceneMouseEvent *event) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Clear selection rectangle
|
// Clear selection rectangle
|
||||||
this->draw();
|
draw();
|
||||||
}
|
}
|
||||||
|
|
||||||
void MetatileLayersItem::hoverMoveEvent(QGraphicsSceneHoverEvent * event) {
|
void MetatileLayersItem::hoverMoveEvent(QGraphicsSceneHoverEvent * event) {
|
||||||
const QPoint pos = this->getBoundedPos(event->pos());
|
hover(getBoundedPos(event->pos()));
|
||||||
|
}
|
||||||
|
|
||||||
|
void MetatileLayersItem::hover(const QPoint &pos) {
|
||||||
if (pos == this->prevHoveredPos)
|
if (pos == this->prevHoveredPos)
|
||||||
return;
|
return;
|
||||||
this->prevHoveredPos = pos;
|
this->prevHoveredPos = pos;
|
||||||
|
|
||||||
int tileIndex = tilePositions.indexOf(pos);
|
int tileIndex = posToTileIndex(pos);
|
||||||
if (tileIndex < 0 || tileIndex >= this->metatile->tiles.length())
|
if (tileIndex < 0 || tileIndex >= this->metatile->tiles.length())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,11 +1,6 @@
|
||||||
#include "selectablepixmapitem.h"
|
#include "selectablepixmapitem.h"
|
||||||
#include <QPainter>
|
#include <QPainter>
|
||||||
|
|
||||||
QSize SelectablePixmapItem::getSelectionDimensions() const
|
|
||||||
{
|
|
||||||
return QSize(abs(this->selectionOffsetX) + 1, abs(this->selectionOffsetY) + 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
QPoint SelectablePixmapItem::getSelectionStart()
|
QPoint SelectablePixmapItem::getSelectionStart()
|
||||||
{
|
{
|
||||||
int x = this->selectionInitialX;
|
int x = this->selectionInitialX;
|
||||||
|
|
@ -15,47 +10,62 @@ QPoint SelectablePixmapItem::getSelectionStart()
|
||||||
return QPoint(x, y);
|
return QPoint(x, y);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SelectablePixmapItem::select(int x, int y, int width, int height)
|
void SelectablePixmapItem::select(const QPoint &pos, const QSize &size)
|
||||||
{
|
{
|
||||||
this->selectionInitialX = x;
|
this->selectionInitialX = pos.x();
|
||||||
this->selectionInitialY = y;
|
this->selectionInitialY = pos.y();
|
||||||
this->selectionOffsetX = qBound(0, width, this->maxSelectionWidth);
|
this->selectionOffsetX = qBound(0, size.width(), this->maxSelectionWidth - 1);
|
||||||
this->selectionOffsetY = qBound(0, height, this->maxSelectionHeight);
|
this->selectionOffsetY = qBound(0, size.height(), this->maxSelectionHeight - 1);
|
||||||
this->draw();
|
draw();
|
||||||
emit this->selectionChanged(x, y, width, height);
|
emit selectionChanged(pos, getSelectionDimensions());
|
||||||
}
|
}
|
||||||
|
|
||||||
void SelectablePixmapItem::mousePressEvent(QGraphicsSceneMouseEvent *event)
|
void SelectablePixmapItem::mousePressEvent(QGraphicsSceneMouseEvent *event)
|
||||||
{
|
{
|
||||||
QPoint pos = this->getCellPos(event->pos());
|
QPoint pos = getCellPos(event->pos());
|
||||||
this->selectionInitialX = pos.x();
|
this->selectionInitialX = pos.x();
|
||||||
this->selectionInitialY = pos.y();
|
this->selectionInitialY = pos.y();
|
||||||
this->selectionOffsetX = 0;
|
this->selectionOffsetX = 0;
|
||||||
this->selectionOffsetY = 0;
|
this->selectionOffsetY = 0;
|
||||||
this->updateSelection(pos.x(), pos.y());
|
this->prevCellPos = pos;
|
||||||
|
updateSelection(pos);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SelectablePixmapItem::mouseMoveEvent(QGraphicsSceneMouseEvent *event)
|
void SelectablePixmapItem::mouseMoveEvent(QGraphicsSceneMouseEvent *event)
|
||||||
{
|
{
|
||||||
QPoint pos = this->getCellPos(event->pos());
|
QPoint pos = getCellPos(event->pos());
|
||||||
this->updateSelection(pos.x(), pos.y());
|
if (pos == this->prevCellPos)
|
||||||
|
return;
|
||||||
|
this->prevCellPos = pos;
|
||||||
|
updateSelection(pos);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SelectablePixmapItem::mouseReleaseEvent(QGraphicsSceneMouseEvent *event)
|
void SelectablePixmapItem::mouseReleaseEvent(QGraphicsSceneMouseEvent *event)
|
||||||
{
|
{
|
||||||
QPoint pos = this->getCellPos(event->pos());
|
updateSelection(getCellPos(event->pos()));
|
||||||
this->updateSelection(pos.x(), pos.y());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void SelectablePixmapItem::updateSelection(int x, int y)
|
void SelectablePixmapItem::setMaxSelectionSize(int width, int height) {
|
||||||
{
|
this->maxSelectionWidth = qMax(width, 1);
|
||||||
|
this->maxSelectionHeight = qMax(height, 1);
|
||||||
|
|
||||||
|
// Update the selection if we shrank below the current selection size.
|
||||||
|
QSize size = getSelectionDimensions();
|
||||||
|
if (size.width() > this->maxSelectionWidth || size.height() > this->maxSelectionHeight) {
|
||||||
|
QPoint origin = getSelectionStart();
|
||||||
|
this->selectionInitialX = origin.x();
|
||||||
|
this->selectionInitialY = origin.y();
|
||||||
|
this->selectionOffsetX = qMin(size.width(), this->maxSelectionWidth) - 1;
|
||||||
|
this->selectionOffsetY = qMin(size.height(), this->maxSelectionHeight) - 1;
|
||||||
|
draw();
|
||||||
|
emit selectionChanged(getSelectionStart(), getSelectionDimensions());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void SelectablePixmapItem::updateSelection(const QPoint &pos) {
|
||||||
// Snap to a valid position inside the selection area.
|
// Snap to a valid position inside the selection area.
|
||||||
int width = pixmap().width() / this->cellWidth;
|
int x = qBound(0, pos.x(), cellsWide() - 1);
|
||||||
int height = pixmap().height() / this->cellHeight;
|
int y = qBound(0, pos.y(), cellsTall() - 1);
|
||||||
if (x < 0) x = 0;
|
|
||||||
if (x >= width) x = width - 1;
|
|
||||||
if (y < 0) y = 0;
|
|
||||||
if (y >= height) y = height - 1;
|
|
||||||
|
|
||||||
this->selectionOffsetX = x - this->selectionInitialX;
|
this->selectionOffsetX = x - this->selectionInitialX;
|
||||||
this->selectionOffsetY = y - this->selectionInitialY;
|
this->selectionOffsetY = y - this->selectionInitialY;
|
||||||
|
|
@ -76,22 +86,20 @@ void SelectablePixmapItem::updateSelection(int x, int y)
|
||||||
this->selectionOffsetY = -this->maxSelectionHeight + 1;
|
this->selectionOffsetY = -this->maxSelectionHeight + 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
this->draw();
|
draw();
|
||||||
emit this->selectionChanged(x, y, width, height);
|
emit selectionChanged(QPoint(x, y), getSelectionDimensions());
|
||||||
}
|
}
|
||||||
|
|
||||||
QPoint SelectablePixmapItem::getCellPos(QPointF pos)
|
QPoint SelectablePixmapItem::getCellPos(QPointF pos) {
|
||||||
{
|
if (this->cellWidth == 0 || this->cellHeight == 0 || pixmap().isNull())
|
||||||
if (pos.x() < 0) pos.setX(0);
|
return QPoint(0,0);
|
||||||
if (pos.y() < 0) pos.setY(0);
|
|
||||||
if (pos.x() >= this->pixmap().width()) pos.setX(this->pixmap().width() - 1);
|
int x = qBound(0, static_cast<int>(pos.x()), pixmap().width() - 1);
|
||||||
if (pos.y() >= this->pixmap().height()) pos.setY(this->pixmap().height() - 1);
|
int y = qBound(0, static_cast<int>(pos.y()), pixmap().height() - 1);
|
||||||
return QPoint(static_cast<int>(pos.x()) / this->cellWidth,
|
return QPoint(x / this->cellWidth, y / this->cellHeight);
|
||||||
static_cast<int>(pos.y()) / this->cellHeight);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void SelectablePixmapItem::drawSelection()
|
void SelectablePixmapItem::drawSelection() {
|
||||||
{
|
|
||||||
QPoint origin = this->getSelectionStart();
|
QPoint origin = this->getSelectionStart();
|
||||||
QSize dimensions = this->getSelectionDimensions();
|
QSize dimensions = this->getSelectionDimensions();
|
||||||
QRect selectionRect(origin.x() * this->cellWidth, origin.y() * this->cellHeight, dimensions.width() * this->cellWidth, dimensions.height() * this->cellHeight);
|
QRect selectionRect(origin.x() * this->cellWidth, origin.y() * this->cellHeight, dimensions.width() * this->cellWidth, dimensions.height() * this->cellHeight);
|
||||||
|
|
|
||||||
|
|
@ -62,12 +62,16 @@ TilesetEditor::TilesetEditor(Project *project, Layout *layout, QWidget *parent)
|
||||||
|
|
||||||
connect(ui->spinBox_paletteSelector, QOverload<int>::of(&QSpinBox::valueChanged), this, &TilesetEditor::refreshPaletteId);
|
connect(ui->spinBox_paletteSelector, QOverload<int>::of(&QSpinBox::valueChanged), this, &TilesetEditor::refreshPaletteId);
|
||||||
|
|
||||||
|
connect(ui->actionLayer_Arrangement_Horizontal, &QAction::triggered, [this] { setMetatileLayerOrientation(Qt::Horizontal); });
|
||||||
|
connect(ui->actionLayer_Arrangement_Vertical, &QAction::triggered, [this] { setMetatileLayerOrientation(Qt::Vertical); });
|
||||||
|
|
||||||
initAttributesUi();
|
initAttributesUi();
|
||||||
initMetatileSelector();
|
initMetatileSelector();
|
||||||
initMetatileLayersItem();
|
initMetatileLayersItem();
|
||||||
initTileSelector();
|
initTileSelector();
|
||||||
initSelectedTileItem();
|
initSelectedTileItem();
|
||||||
initShortcuts();
|
initShortcuts();
|
||||||
|
setMetatileLayerOrientation(porymapConfig.tilesetEditorLayerOrientation);
|
||||||
this->metatileSelector->select(0);
|
this->metatileSelector->select(0);
|
||||||
restoreWindowState();
|
restoreWindowState();
|
||||||
}
|
}
|
||||||
|
|
@ -234,6 +238,53 @@ void TilesetEditor::initMetatileSelector()
|
||||||
this->ui->horizontalSlider_MetatilesZoom->setValue(porymapConfig.tilesetEditorMetatilesZoom);
|
this->ui->horizontalSlider_MetatilesZoom->setValue(porymapConfig.tilesetEditorMetatilesZoom);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void TilesetEditor::setMetatileLayerOrientation(Qt::Orientation orientation) {
|
||||||
|
// Sync settings
|
||||||
|
bool horizontal = (orientation == Qt::Horizontal);
|
||||||
|
porymapConfig.tilesetEditorLayerOrientation = orientation;
|
||||||
|
const QSignalBlocker b_Horizontal(ui->actionLayer_Arrangement_Horizontal);
|
||||||
|
const QSignalBlocker b_Vertical(ui->actionLayer_Arrangement_Vertical);
|
||||||
|
ui->actionLayer_Arrangement_Horizontal->setChecked(horizontal);
|
||||||
|
ui->actionLayer_Arrangement_Vertical->setChecked(!horizontal);
|
||||||
|
|
||||||
|
this->metatileLayersItem->setOrientation(orientation);
|
||||||
|
|
||||||
|
int numTilesWide = Metatile::tileWidth();
|
||||||
|
int numTilesTall = Metatile::tileHeight();
|
||||||
|
int numLayers = projectConfig.getNumLayersInMetatile();
|
||||||
|
if (horizontal) {
|
||||||
|
numTilesWide *= numLayers;
|
||||||
|
} else {
|
||||||
|
numTilesTall *= numLayers;
|
||||||
|
}
|
||||||
|
this->tileSelector->setMaxSelectionSize(numTilesWide, numTilesTall);
|
||||||
|
|
||||||
|
const int scale = 2;
|
||||||
|
int w = Tile::pixelWidth() * numTilesWide * scale + 2;
|
||||||
|
int h = Tile::pixelHeight() * numTilesTall * scale + 2;
|
||||||
|
ui->graphicsView_selectedTile->setFixedSize(w, h);
|
||||||
|
ui->graphicsView_metatileLayers->setFixedSize(w, h);
|
||||||
|
|
||||||
|
// If the layers are laid out vertically then the orientation is obvious, no need to label them.
|
||||||
|
ui->label_BottomTop->setVisible(horizontal);
|
||||||
|
|
||||||
|
// Let the graphics view take over the label's vertical space (or conversely, give the space back).
|
||||||
|
// (This is a bit of a process, apparently there's no quick way to set a widget's row / row span once they're added to the layout
|
||||||
|
int row, col, rowSpan, colSpan;
|
||||||
|
int index = ui->gridLayout_MetatileProperties->indexOf(ui->label_BottomTop);
|
||||||
|
ui->gridLayout_MetatileProperties->getItemPosition(index, &row, &col, &rowSpan, &colSpan);
|
||||||
|
|
||||||
|
// TODO: Rearrange the rest of the metatile properties panel. The vertical triple-layer metatiles layout esp. looks terrible.
|
||||||
|
ui->gridLayout_MetatileProperties->removeWidget(ui->graphicsView_metatileLayers);
|
||||||
|
if (horizontal) {
|
||||||
|
// Give space from graphics view back to label
|
||||||
|
ui->gridLayout_MetatileProperties->addWidget(ui->graphicsView_metatileLayers, row + 1, col, rowSpan, colSpan);
|
||||||
|
} else {
|
||||||
|
// Take space from label and give it to graphics view
|
||||||
|
ui->gridLayout_MetatileProperties->addWidget(ui->graphicsView_metatileLayers, row, col, rowSpan + 1, colSpan);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void TilesetEditor::initMetatileLayersItem() {
|
void TilesetEditor::initMetatileLayersItem() {
|
||||||
Metatile *metatile = Tileset::getMetatile(this->getSelectedMetatileId(), this->primaryTileset, this->secondaryTileset);
|
Metatile *metatile = Tileset::getMetatile(this->getSelectedMetatileId(), this->primaryTileset, this->secondaryTileset);
|
||||||
this->metatileLayersItem = new MetatileLayersItem(metatile, this->primaryTileset, this->secondaryTileset);
|
this->metatileLayersItem = new MetatileLayersItem(metatile, this->primaryTileset, this->secondaryTileset);
|
||||||
|
|
@ -252,9 +303,8 @@ void TilesetEditor::initMetatileLayersItem() {
|
||||||
this->ui->graphicsView_metatileLayers->setScene(this->metatileLayersScene);
|
this->ui->graphicsView_metatileLayers->setScene(this->metatileLayersScene);
|
||||||
}
|
}
|
||||||
|
|
||||||
void TilesetEditor::initTileSelector()
|
void TilesetEditor::initTileSelector() {
|
||||||
{
|
this->tileSelector = new TilesetEditorTileSelector(this->primaryTileset, this->secondaryTileset);
|
||||||
this->tileSelector = new TilesetEditorTileSelector(this->primaryTileset, this->secondaryTileset, projectConfig.getNumLayersInMetatile());
|
|
||||||
connect(this->tileSelector, &TilesetEditorTileSelector::hoveredTileChanged, [this](uint16_t tileId) {
|
connect(this->tileSelector, &TilesetEditorTileSelector::hoveredTileChanged, [this](uint16_t tileId) {
|
||||||
onHoveredTileChanged(tileId);
|
onHoveredTileChanged(tileId);
|
||||||
});
|
});
|
||||||
|
|
@ -277,7 +327,6 @@ void TilesetEditor::initSelectedTileItem() {
|
||||||
this->selectedTileScene = new QGraphicsScene;
|
this->selectedTileScene = new QGraphicsScene;
|
||||||
this->drawSelectedTiles();
|
this->drawSelectedTiles();
|
||||||
this->ui->graphicsView_selectedTile->setScene(this->selectedTileScene);
|
this->ui->graphicsView_selectedTile->setScene(this->selectedTileScene);
|
||||||
this->ui->graphicsView_selectedTile->setFixedSize(this->selectedTilePixmapItem->pixmap().width() + 2, this->selectedTilePixmapItem->pixmap().height() + 2);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void TilesetEditor::initShortcuts() {
|
void TilesetEditor::initShortcuts() {
|
||||||
|
|
@ -392,13 +441,12 @@ void TilesetEditor::drawSelectedTiles() {
|
||||||
QImage selectionImage(imgTileWidth * dimensions.width(), imgTileHeight * dimensions.height(), QImage::Format_RGBA8888);
|
QImage selectionImage(imgTileWidth * dimensions.width(), imgTileHeight * dimensions.height(), QImage::Format_RGBA8888);
|
||||||
QPainter painter(&selectionImage);
|
QPainter painter(&selectionImage);
|
||||||
int tileIndex = 0;
|
int tileIndex = 0;
|
||||||
for (int j = 0; j < dimensions.height(); j++) {
|
for (int y = 0; y < dimensions.height(); y++) {
|
||||||
for (int i = 0; i < dimensions.width(); i++) {
|
for (int x = 0; x < dimensions.width(); x++) {
|
||||||
auto tile = tiles.at(tileIndex);
|
auto tile = tiles.at(tileIndex++);
|
||||||
QImage tileImage = getPalettedTileImage(tile.tileId, this->primaryTileset, this->secondaryTileset, tile.palette, true).scaled(imgTileWidth, imgTileHeight);
|
QImage tileImage = getPalettedTileImage(tile.tileId, this->primaryTileset, this->secondaryTileset, tile.palette, true).scaled(imgTileWidth, imgTileHeight);
|
||||||
tile.flip(&tileImage);
|
tile.flip(&tileImage);
|
||||||
tileIndex++;
|
painter.drawImage(x * imgTileWidth, y * imgTileHeight, tileImage);
|
||||||
painter.drawImage(i * imgTileWidth, j * imgTileHeight, tileImage);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -407,7 +455,6 @@ void TilesetEditor::drawSelectedTiles() {
|
||||||
|
|
||||||
QSize size(this->selectedTilePixmapItem->pixmap().width(), this->selectedTilePixmapItem->pixmap().height());
|
QSize size(this->selectedTilePixmapItem->pixmap().width(), this->selectedTilePixmapItem->pixmap().height());
|
||||||
this->ui->graphicsView_selectedTile->setSceneRect(0, 0, size.width(), size.height());
|
this->ui->graphicsView_selectedTile->setSceneRect(0, 0, size.width(), size.height());
|
||||||
this->ui->graphicsView_selectedTile->setFixedSize(size.width() + 2, size.height() + 2);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void TilesetEditor::onHoveredMetatileChanged(uint16_t metatileId) {
|
void TilesetEditor::onHoveredMetatileChanged(uint16_t metatileId) {
|
||||||
|
|
@ -436,7 +483,6 @@ void TilesetEditor::onSelectedMetatileChanged(uint16_t metatileId) {
|
||||||
|
|
||||||
this->metatileLayersItem->setMetatile(metatile);
|
this->metatileLayersItem->setMetatile(metatile);
|
||||||
this->metatileLayersItem->draw();
|
this->metatileLayersItem->draw();
|
||||||
this->ui->graphicsView_metatileLayers->setFixedSize(this->metatileLayersItem->pixmap().width() + 2, this->metatileLayersItem->pixmap().height() + 2);
|
|
||||||
|
|
||||||
MetatileLabelPair labels = Tileset::getMetatileLabelPair(metatileId, this->primaryTileset, this->secondaryTileset);
|
MetatileLabelPair labels = Tileset::getMetatileLabelPair(metatileId, this->primaryTileset, this->secondaryTileset);
|
||||||
this->ui->lineEdit_metatileLabel->setText(labels.owned);
|
this->ui->lineEdit_metatileLabel->setText(labels.owned);
|
||||||
|
|
@ -467,33 +513,18 @@ void TilesetEditor::onHoveredTileCleared() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void TilesetEditor::paintSelectedLayerTiles(const QPoint &pos, bool paletteOnly) {
|
void TilesetEditor::paintSelectedLayerTiles(const QPoint &pos, bool paletteOnly) {
|
||||||
static const QList<QPoint> tileCoords = QList<QPoint>{
|
|
||||||
QPoint(0, 0),
|
|
||||||
QPoint(1, 0),
|
|
||||||
QPoint(0, 1),
|
|
||||||
QPoint(1, 1),
|
|
||||||
QPoint(2, 0),
|
|
||||||
QPoint(3, 0),
|
|
||||||
QPoint(2, 1),
|
|
||||||
QPoint(3, 1),
|
|
||||||
QPoint(4, 0),
|
|
||||||
QPoint(5, 0),
|
|
||||||
QPoint(4, 1),
|
|
||||||
QPoint(5, 1),
|
|
||||||
};
|
|
||||||
bool changed = false;
|
bool changed = false;
|
||||||
Metatile *prevMetatile = new Metatile(*this->metatile);
|
Metatile *prevMetatile = new Metatile(*this->metatile);
|
||||||
QSize dimensions = this->tileSelector->getSelectionDimensions();
|
QSize dimensions = this->tileSelector->getSelectionDimensions();
|
||||||
QList<Tile> tiles = this->tileSelector->getSelectedTiles();
|
QList<Tile> tiles = this->tileSelector->getSelectedTiles();
|
||||||
int selectedTileIndex = 0;
|
int srcTileIndex = 0;
|
||||||
int maxTileIndex = projectConfig.getNumTilesInMetatile();
|
int maxTileIndex = projectConfig.getNumTilesInMetatile();
|
||||||
for (int j = 0; j < dimensions.height(); j++) {
|
for (int y = 0; y < dimensions.height(); y++) {
|
||||||
for (int i = 0; i < dimensions.width(); i++) {
|
for (int x = 0; x < dimensions.width(); x++) {
|
||||||
int tileIndex = ((pos.x() + i) / 2 * 4) + ((pos.y() + j) * 2) + ((pos.x() + i) % 2);
|
int destTileIndex = this->metatileLayersItem->posToTileIndex(pos.x() + x, pos.y() + y);
|
||||||
QPoint tilePos = tileCoords.at(tileIndex);
|
if (destTileIndex < maxTileIndex) {
|
||||||
if (tileIndex < maxTileIndex && tilePos.x() >= pos.x() && tilePos.y() >= pos.y()){
|
Tile &destTile = this->metatile->tiles[destTileIndex];
|
||||||
Tile &destTile = this->metatile->tiles[tileIndex];
|
const Tile srcTile = tiles.at(srcTileIndex++);
|
||||||
const Tile srcTile = tiles.at(selectedTileIndex);
|
|
||||||
if (paletteOnly) {
|
if (paletteOnly) {
|
||||||
if (srcTile.palette == destTile.palette)
|
if (srcTile.palette == destTile.palette)
|
||||||
continue; // Ignore no-ops for edit history
|
continue; // Ignore no-ops for edit history
|
||||||
|
|
@ -511,7 +542,6 @@ void TilesetEditor::paintSelectedLayerTiles(const QPoint &pos, bool paletteOnly)
|
||||||
}
|
}
|
||||||
changed = true;
|
changed = true;
|
||||||
}
|
}
|
||||||
selectedTileIndex++;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!changed) {
|
if (!changed) {
|
||||||
|
|
@ -525,26 +555,24 @@ void TilesetEditor::paintSelectedLayerTiles(const QPoint &pos, bool paletteOnly)
|
||||||
this->commitMetatileChange(prevMetatile);
|
this->commitMetatileChange(prevMetatile);
|
||||||
}
|
}
|
||||||
|
|
||||||
void TilesetEditor::onMetatileLayerSelectionChanged(QPoint selectionOrigin, int width, int height) {
|
void TilesetEditor::onMetatileLayerSelectionChanged(const QPoint &selectionOrigin, const QSize &size) {
|
||||||
QList<Tile> tiles;
|
QList<Tile> tiles;
|
||||||
QList<int> tileIdxs;
|
QList<int> tileIdxs;
|
||||||
int x = selectionOrigin.x();
|
|
||||||
int y = selectionOrigin.y();
|
|
||||||
int maxTileIndex = projectConfig.getNumTilesInMetatile();
|
int maxTileIndex = projectConfig.getNumTilesInMetatile();
|
||||||
for (int j = 0; j < height; j++) {
|
for (int j = 0; j < size.height(); j++) {
|
||||||
for (int i = 0; i < width; i++) {
|
for (int i = 0; i < size.width(); i++) {
|
||||||
int tileIndex = ((x + i) / 2 * 4) + ((y + j) * 2) + ((x + i) % 2);
|
int tileIndex = this->metatileLayersItem->posToTileIndex(selectionOrigin.x() + i, selectionOrigin.y() + j);
|
||||||
if (tileIndex < maxTileIndex) {
|
if (tileIndex < maxTileIndex) {
|
||||||
tiles.append(this->metatile->tiles.at(tileIndex));
|
tiles.append(this->metatile->tiles.value(tileIndex));
|
||||||
tileIdxs.append(tileIndex);
|
tileIdxs.append(tileIndex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
this->tileSelector->setExternalSelection(width, height, tiles, tileIdxs);
|
this->tileSelector->setExternalSelection(size.width(), size.height(), tiles, tileIdxs);
|
||||||
if (width == 1 && height == 1) {
|
if (size == QSize(1,1)) {
|
||||||
setPaletteId(tiles[0].palette);
|
setPaletteId(tiles[0].palette);
|
||||||
this->tileSelector->highlight(static_cast<uint16_t>(tiles[0].tileId));
|
this->tileSelector->highlight(tiles[0].tileId);
|
||||||
this->redrawTileSelector();
|
this->redrawTileSelector();
|
||||||
}
|
}
|
||||||
this->metatileLayersItem->clearLastModifiedCoords();
|
this->metatileLayersItem->clearLastModifiedCoords();
|
||||||
|
|
|
||||||
|
|
@ -12,6 +12,11 @@ QSize TilesetEditorTileSelector::getSelectionDimensions() const {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void TilesetEditorTileSelector::setMaxSelectionSize(int width, int height) {
|
||||||
|
SelectablePixmapItem::setMaxSelectionSize(width, height);
|
||||||
|
updateSelectedTiles();
|
||||||
|
}
|
||||||
|
|
||||||
void TilesetEditorTileSelector::updateBasePixmap() {
|
void TilesetEditorTileSelector::updateBasePixmap() {
|
||||||
if (!this->primaryTileset || !this->secondaryTileset || this->numTilesWide == 0) {
|
if (!this->primaryTileset || !this->secondaryTileset || this->numTilesWide == 0) {
|
||||||
this->basePixmap = QPixmap();
|
this->basePixmap = QPixmap();
|
||||||
|
|
@ -134,7 +139,7 @@ QList<Tile> TilesetEditorTileSelector::buildSelectedTiles(int width, int height,
|
||||||
// If we've completed a layer row, or its the last tile of an incompletely
|
// If we've completed a layer row, or its the last tile of an incompletely
|
||||||
// selected layer, then append the layer row to the full row
|
// selected layer, then append the layer row to the full row
|
||||||
// If not an external selection, treat the whole row as 1 "layer"
|
// If not an external selection, treat the whole row as 1 "layer"
|
||||||
if (i == width - 1 || (this->externalSelection && (this->externalSelectedPos.at(index) % 4) & 1)) {
|
if (i == width - 1 || (this->externalSelection && (this->externalSelectedPos.at(index) % Metatile::tilesPerLayer()) & 1)) {
|
||||||
row.append(layerRow);
|
row.append(layerRow);
|
||||||
layerRow.clear();
|
layerRow.clear();
|
||||||
}
|
}
|
||||||
|
|
@ -170,16 +175,20 @@ uint16_t TilesetEditorTileSelector::getTileId(int x, int y) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void TilesetEditorTileSelector::mousePressEvent(QGraphicsSceneMouseEvent *event) {
|
void TilesetEditorTileSelector::mousePressEvent(QGraphicsSceneMouseEvent *event) {
|
||||||
|
this->prevCellPos = getCellPos(event->pos());
|
||||||
SelectablePixmapItem::mousePressEvent(event);
|
SelectablePixmapItem::mousePressEvent(event);
|
||||||
this->updateSelectedTiles();
|
this->updateSelectedTiles();
|
||||||
emit selectedTilesChanged();
|
emit selectedTilesChanged();
|
||||||
}
|
}
|
||||||
|
|
||||||
void TilesetEditorTileSelector::mouseMoveEvent(QGraphicsSceneMouseEvent *event) {
|
void TilesetEditorTileSelector::mouseMoveEvent(QGraphicsSceneMouseEvent *event) {
|
||||||
|
QPoint pos = getCellPos(event->pos());
|
||||||
|
if (this->prevCellPos == pos)
|
||||||
|
return;
|
||||||
|
this->prevCellPos = pos;
|
||||||
|
|
||||||
SelectablePixmapItem::mouseMoveEvent(event);
|
SelectablePixmapItem::mouseMoveEvent(event);
|
||||||
this->updateSelectedTiles();
|
this->updateSelectedTiles();
|
||||||
|
|
||||||
QPoint pos = this->getCellPos(event->pos());
|
|
||||||
uint16_t tile = this->getTileId(pos.x(), pos.y());
|
uint16_t tile = this->getTileId(pos.x(), pos.y());
|
||||||
emit hoveredTileChanged(tile);
|
emit hoveredTileChanged(tile);
|
||||||
emit selectedTilesChanged();
|
emit selectedTilesChanged();
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user