Allow vertical layout for layer view

This commit is contained in:
GriffinR 2025-07-29 03:10:46 -04:00
parent a88730ee3f
commit f6f07ca5fc
13 changed files with 317 additions and 177 deletions

View File

@ -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>

View File

@ -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;

View File

@ -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:

View File

@ -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

View File

@ -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;

View File

@ -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;

View File

@ -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");

View File

@ -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);
} }

View File

@ -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);

View File

@ -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;

View File

@ -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);

View File

@ -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();

View File

@ -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();