Enable multi-tile selections in tileset editor

This commit is contained in:
Marcus Huderle 2018-10-02 19:01:27 -05:00
parent 3ca284d5f3
commit da13b8ea5e
7 changed files with 96 additions and 50 deletions

View file

@ -186,8 +186,8 @@
</property> </property>
<property name="maximumSize"> <property name="maximumSize">
<size> <size>
<width>32</width> <width>64</width>
<height>32</height> <height>64</height>
</size> </size>
</property> </property>
<property name="verticalScrollBarPolicy"> <property name="verticalScrollBarPolicy">
@ -215,7 +215,7 @@
<x>0</x> <x>0</x>
<y>0</y> <y>0</y>
<width>309</width> <width>309</width>
<height>415</height> <height>409</height>
</rect> </rect>
</property> </property>
<layout class="QGridLayout" name="gridLayout_2"> <layout class="QGridLayout" name="gridLayout_2">

View file

@ -21,7 +21,7 @@ private:
Tileset *primaryTileset; Tileset *primaryTileset;
Tileset *secondaryTileset; Tileset *secondaryTileset;
signals: signals:
void tileChanged(int); void tileChanged(int, int);
protected: protected:
void mousePressEvent(QGraphicsSceneMouseEvent*); void mousePressEvent(QGraphicsSceneMouseEvent*);
}; };

View file

@ -26,8 +26,8 @@ private slots:
void onSelectedMetatileChanged(uint16_t); void onSelectedMetatileChanged(uint16_t);
void onHoveredTileChanged(uint16_t); void onHoveredTileChanged(uint16_t);
void onHoveredTileCleared(); void onHoveredTileCleared();
void onSelectedTileChanged(uint16_t); void onSelectedTilesChanged();
void onMetatileLayerTileChanged(int); void onMetatileLayerTileChanged(int, int);
void on_spinBox_paletteSelector_valueChanged(int arg1); void on_spinBox_paletteSelector_valueChanged(int arg1);
@ -50,7 +50,7 @@ private:
void initTileSelector(); void initTileSelector();
void initSelectedTileItem(); void initSelectedTileItem();
void initMetatileLayersItem(); void initMetatileLayersItem();
void drawSelectedTile(); void drawSelectedTiles();
void importTilesetTiles(Tileset*, bool); void importTilesetTiles(Tileset*, bool);
void refresh(); void refresh();
Ui::TilesetEditor *ui; Ui::TilesetEditor *ui;

View file

@ -7,7 +7,7 @@
class TilesetEditorTileSelector: public SelectablePixmapItem { class TilesetEditorTileSelector: public SelectablePixmapItem {
Q_OBJECT Q_OBJECT
public: public:
TilesetEditorTileSelector(Tileset *primaryTileset, Tileset *secondaryTileset): SelectablePixmapItem(16, 16, 1, 1) { TilesetEditorTileSelector(Tileset *primaryTileset, Tileset *secondaryTileset): SelectablePixmapItem(16, 16, 2, 2) {
this->primaryTileset = primaryTileset; this->primaryTileset = primaryTileset;
this->secondaryTileset = secondaryTileset; this->secondaryTileset = secondaryTileset;
this->numTilesWide = 16; this->numTilesWide = 16;
@ -18,7 +18,8 @@ public:
void select(uint16_t metatileId); void select(uint16_t metatileId);
void setTilesets(Tileset*, Tileset*); void setTilesets(Tileset*, Tileset*);
void setPaletteId(int); void setPaletteId(int);
uint16_t getSelectedTile(); void setTileFlips(bool, bool);
QList<uint16_t> getSelectedTiles();
protected: protected:
void mousePressEvent(QGraphicsSceneMouseEvent*); void mousePressEvent(QGraphicsSceneMouseEvent*);
@ -30,10 +31,12 @@ protected:
private: private:
Tileset *primaryTileset; Tileset *primaryTileset;
Tileset *secondaryTileset; Tileset *secondaryTileset;
uint16_t selectedTile; QList<uint16_t> selectedTiles;
int numTilesWide; int numTilesWide;
int paletteId; int paletteId;
void updateSelectedTile(); bool xFlip;
bool yFlip;
void updateSelectedTiles();
uint16_t getTileId(int x, int y); uint16_t getTileId(int x, int y);
QPoint getTileCoords(uint16_t); QPoint getTileCoords(uint16_t);
QList<QRgb> getCurPaletteTable(); QList<QRgb> getCurPaletteTable();
@ -41,7 +44,7 @@ private:
signals: signals:
void hoveredTileChanged(uint16_t); void hoveredTileChanged(uint16_t);
void hoveredTileCleared(); void hoveredTileCleared();
void selectedTileChanged(uint16_t); void selectedTilesChanged();
}; };
#endif // TILESETEDITORTILESELECTOR_H #endif // TILESETEDITORTILESELECTOR_H

View file

@ -41,6 +41,5 @@ void MetatileLayersItem::mousePressEvent(QGraphicsSceneMouseEvent *event) {
QPointF pos = event->pos(); QPointF pos = event->pos();
int x = static_cast<int>(pos.x()) / 16; int x = static_cast<int>(pos.x()) / 16;
int y = static_cast<int>(pos.y()) / 16; int y = static_cast<int>(pos.y()) / 16;
int tileIndex = (x / 2 * 4) + (y * 2) + (x % 2); emit this->tileChanged(x, y);
emit this->tileChanged(tileIndex);
} }

View file

@ -58,12 +58,13 @@ void TilesetEditor::refresh() {
this->tileSelector->setTilesets(this->primaryTileset, this->secondaryTileset); this->tileSelector->setTilesets(this->primaryTileset, this->secondaryTileset);
this->metatileLayersItem->setTilesets(this->primaryTileset, this->secondaryTileset); this->metatileLayersItem->setTilesets(this->primaryTileset, this->secondaryTileset);
this->metatileSelector->select(this->metatileSelector->getSelectedMetatile()); this->metatileSelector->select(this->metatileSelector->getSelectedMetatile());
this->drawSelectedTile(); this->drawSelectedTiles();
this->ui->graphicsView_Tiles->setSceneRect(0, 0, this->tileSelector->pixmap().width() + 2, this->tileSelector->pixmap().height() + 2); this->ui->graphicsView_Tiles->setSceneRect(0, 0, this->tileSelector->pixmap().width() + 2, this->tileSelector->pixmap().height() + 2);
this->ui->graphicsView_Tiles->setFixedSize(this->tileSelector->pixmap().width() + 2, this->tileSelector->pixmap().height() + 2); this->ui->graphicsView_Tiles->setFixedSize(this->tileSelector->pixmap().width() + 2, this->tileSelector->pixmap().height() + 2);
this->ui->graphicsView_Metatiles->setSceneRect(0, 0, this->metatileSelector->pixmap().width() + 2, this->metatileSelector->pixmap().height() + 2); this->ui->graphicsView_Metatiles->setSceneRect(0, 0, this->metatileSelector->pixmap().width() + 2, this->metatileSelector->pixmap().height() + 2);
this->ui->graphicsView_Metatiles->setFixedSize(this->metatileSelector->pixmap().width() + 2, this->metatileSelector->pixmap().height() + 2); this->ui->graphicsView_Metatiles->setFixedSize(this->metatileSelector->pixmap().width() + 2, this->metatileSelector->pixmap().height() + 2);
this->ui->graphicsView_selectedTile->setFixedSize(this->selectedTilePixmapItem->pixmap().width(), this->selectedTilePixmapItem->pixmap().height());
} }
void TilesetEditor::initMetatileSelector() void TilesetEditor::initMetatileSelector()
@ -91,8 +92,8 @@ void TilesetEditor::initTileSelector()
this, SLOT(onHoveredTileChanged(uint16_t))); this, SLOT(onHoveredTileChanged(uint16_t)));
connect(this->tileSelector, SIGNAL(hoveredTileCleared()), connect(this->tileSelector, SIGNAL(hoveredTileCleared()),
this, SLOT(onHoveredTileCleared())); this, SLOT(onHoveredTileCleared()));
connect(this->tileSelector, SIGNAL(selectedTileChanged(uint16_t)), connect(this->tileSelector, SIGNAL(selectedTilesChanged()),
this, SLOT(onSelectedTileChanged(uint16_t))); this, SLOT(onSelectedTilesChanged()));
this->tilesScene = new QGraphicsScene; this->tilesScene = new QGraphicsScene;
this->tilesScene->addItem(this->tileSelector); this->tilesScene->addItem(this->tileSelector);
@ -105,27 +106,42 @@ void TilesetEditor::initTileSelector()
void TilesetEditor::initSelectedTileItem() { void TilesetEditor::initSelectedTileItem() {
this->selectedTileScene = new QGraphicsScene; this->selectedTileScene = new QGraphicsScene;
this->drawSelectedTile(); 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(), this->selectedTilePixmapItem->pixmap().height());
} }
void TilesetEditor::drawSelectedTile() { void TilesetEditor::drawSelectedTiles() {
if (!this->selectedTileScene) { if (!this->selectedTileScene) {
return; return;
} }
this->selectedTileScene->clear(); this->selectedTileScene->clear();
QImage tileImage = getColoredTileImage(this->tileSelector->getSelectedTile(), this->primaryTileset, this->secondaryTileset, this->paletteId) QList<uint16_t> tiles = this->tileSelector->getSelectedTiles();
.mirrored(this->tileXFlip, this->tileYFlip); QPoint dimensions = this->tileSelector->getSelectionDimensions();
this->selectedTilePixmapItem = new QGraphicsPixmapItem(QPixmap::fromImage(tileImage).scaled(32, 32)); QImage selectionImage(32 * dimensions.x(), 32 * dimensions.y(), QImage::Format_RGBA8888);
QPainter painter(&selectionImage);
int tileIndex = 0;
for (int j = 0; j < dimensions.y(); j++) {
for (int i = 0; i < dimensions.x(); i++) {
QImage tileImage = getColoredTileImage(tiles.at(tileIndex), this->primaryTileset, this->secondaryTileset, this->paletteId)
.mirrored(this->tileXFlip, this->tileYFlip)
.scaled(32, 32);
tileIndex++;
painter.drawImage(i * 32, j * 32, tileImage);
}
}
this->selectedTilePixmapItem = new QGraphicsPixmapItem(QPixmap::fromImage(selectionImage));
this->selectedTileScene->addItem(this->selectedTilePixmapItem); this->selectedTileScene->addItem(this->selectedTilePixmapItem);
this->ui->graphicsView_selectedTile->setFixedSize(this->selectedTilePixmapItem->pixmap().width(), this->selectedTilePixmapItem->pixmap().height());
} }
void TilesetEditor::initMetatileLayersItem() { void TilesetEditor::initMetatileLayersItem() {
Metatile *metatile = Tileset::getMetatile(this->metatileSelector->getSelectedMetatile(), this->primaryTileset, this->secondaryTileset); Metatile *metatile = Tileset::getMetatile(this->metatileSelector->getSelectedMetatile(), this->primaryTileset, this->secondaryTileset);
this->metatileLayersItem = new MetatileLayersItem(metatile, this->primaryTileset, this->secondaryTileset); this->metatileLayersItem = new MetatileLayersItem(metatile, this->primaryTileset, this->secondaryTileset);
connect(this->metatileLayersItem, SIGNAL(tileChanged(int)), connect(this->metatileLayersItem, SIGNAL(tileChanged(int, int)),
this, SLOT(onMetatileLayerTileChanged(int))); this, SLOT(onMetatileLayerTileChanged(int, int)));
this->metatileLayersScene = new QGraphicsScene; this->metatileLayersScene = new QGraphicsScene;
this->metatileLayersScene->addItem(this->metatileLayersItem); this->metatileLayersScene->addItem(this->metatileLayersItem);
@ -160,17 +176,30 @@ void TilesetEditor::onHoveredTileCleared() {
this->ui->statusbar->clearMessage(); this->ui->statusbar->clearMessage();
} }
void TilesetEditor::onSelectedTileChanged(uint16_t) { void TilesetEditor::onSelectedTilesChanged() {
this->drawSelectedTile(); this->drawSelectedTiles();
} }
void TilesetEditor::onMetatileLayerTileChanged(int tileIndex) { void TilesetEditor::onMetatileLayerTileChanged(int x, int y) {
Tile tile = this->metatile->tiles->at(tileIndex); int maxTileIndex = x < 2 ? 3 : 7;
tile.tile = this->tileSelector->getSelectedTile(); QPoint dimensions = this->tileSelector->getSelectionDimensions();
tile.xflip = this->tileXFlip; QList<uint16_t> tiles = this->tileSelector->getSelectedTiles();
tile.yflip = this->tileYFlip; int selectedTileIndex = 0;
tile.palette = this->paletteId; for (int j = 0; j < dimensions.y(); j++) {
(*this->metatile->tiles)[tileIndex] = tile; for (int i = 0; i < dimensions.x(); i++) {
int tileIndex = ((x + i) / 2 * 4) + ((y + j) * 2) + ((x + i) % 2);
if (tileIndex <= maxTileIndex) {
Tile tile = this->metatile->tiles->at(tileIndex);
tile.tile = tiles.at(selectedTileIndex);
tile.xflip = this->tileXFlip;
tile.yflip = this->tileYFlip;
tile.palette = this->paletteId;
(*this->metatile->tiles)[tileIndex] = tile;
}
selectedTileIndex++;
}
}
this->metatileSelector->draw(); this->metatileSelector->draw();
this->metatileLayersItem->draw(); this->metatileLayersItem->draw();
} }
@ -179,19 +208,21 @@ void TilesetEditor::on_spinBox_paletteSelector_valueChanged(int paletteId)
{ {
this->paletteId = paletteId; this->paletteId = paletteId;
this->tileSelector->setPaletteId(paletteId); this->tileSelector->setPaletteId(paletteId);
this->drawSelectedTile(); this->drawSelectedTiles();
} }
void TilesetEditor::on_checkBox_xFlip_stateChanged(int checked) void TilesetEditor::on_checkBox_xFlip_stateChanged(int checked)
{ {
this->tileXFlip = checked; this->tileXFlip = checked;
this->drawSelectedTile(); this->tileSelector->setTileFlips(this->tileXFlip, this->tileYFlip);
this->drawSelectedTiles();
} }
void TilesetEditor::on_checkBox_yFlip_stateChanged(int checked) void TilesetEditor::on_checkBox_yFlip_stateChanged(int checked)
{ {
this->tileYFlip = checked; this->tileYFlip = checked;
this->drawSelectedTile(); this->tileSelector->setTileFlips(this->tileXFlip, this->tileYFlip);
this->drawSelectedTiles();
} }
void TilesetEditor::on_comboBox_metatileBehaviors_currentIndexChanged(const QString &metatileBehavior) void TilesetEditor::on_comboBox_metatileBehaviors_currentIndexChanged(const QString &metatileBehavior)

View file

@ -35,7 +35,7 @@ void TilesetEditorTileSelector::draw() {
int y = tile / this->numTilesWide; int y = tile / this->numTilesWide;
int x = tile % this->numTilesWide; int x = tile % this->numTilesWide;
QPoint origin = QPoint(x * 16, y * 16); QPoint origin = QPoint(x * 16, y * 16);
painter.drawImage(origin, tileImage); painter.drawImage(origin, tileImage.mirrored(this->xFlip, this->yFlip));
} }
painter.end(); painter.end();
@ -46,8 +46,8 @@ void TilesetEditorTileSelector::draw() {
void TilesetEditorTileSelector::select(uint16_t tile) { void TilesetEditorTileSelector::select(uint16_t tile) {
QPoint coords = this->getTileCoords(tile); QPoint coords = this->getTileCoords(tile);
SelectablePixmapItem::select(coords.x(), coords.y(), 0, 0); SelectablePixmapItem::select(coords.x(), coords.y(), 0, 0);
this->selectedTile = tile; this->updateSelectedTiles();
emit selectedTileChanged(tile); emit selectedTilesChanged();
} }
void TilesetEditorTileSelector::setTilesets(Tileset *primaryTileset, Tileset *secondaryTileset) { void TilesetEditorTileSelector::setTilesets(Tileset *primaryTileset, Tileset *secondaryTileset) {
@ -61,13 +61,26 @@ void TilesetEditorTileSelector::setPaletteId(int paletteId) {
this->draw(); this->draw();
} }
void TilesetEditorTileSelector::updateSelectedTile() { void TilesetEditorTileSelector::setTileFlips(bool xFlip, bool yFlip) {
QPoint origin = this->getSelectionStart(); this->xFlip = xFlip;
this->selectedTile = this->getTileId(origin.x(), origin.y()); this->yFlip = yFlip;
this->draw();
} }
uint16_t TilesetEditorTileSelector::getSelectedTile() { void TilesetEditorTileSelector::updateSelectedTiles() {
return this->selectedTile; this->selectedTiles.clear();
QPoint origin = this->getSelectionStart();
QPoint dimensions = this->getSelectionDimensions();
for (int j = 0; j < dimensions.y(); j++) {
for (int i = 0; i < dimensions.x(); i++) {
uint16_t metatileId = this->getTileId(origin.x() + i, origin.y() + j);
this->selectedTiles.append(metatileId);
}
}
}
QList<uint16_t> TilesetEditorTileSelector::getSelectedTiles() {
return this->selectedTiles;
} }
uint16_t TilesetEditorTileSelector::getTileId(int x, int y) { uint16_t TilesetEditorTileSelector::getTileId(int x, int y) {
@ -76,24 +89,24 @@ uint16_t TilesetEditorTileSelector::getTileId(int x, int y) {
void TilesetEditorTileSelector::mousePressEvent(QGraphicsSceneMouseEvent *event) { void TilesetEditorTileSelector::mousePressEvent(QGraphicsSceneMouseEvent *event) {
SelectablePixmapItem::mousePressEvent(event); SelectablePixmapItem::mousePressEvent(event);
this->updateSelectedTile(); this->updateSelectedTiles();
emit selectedTileChanged(this->selectedTile); emit selectedTilesChanged();
} }
void TilesetEditorTileSelector::mouseMoveEvent(QGraphicsSceneMouseEvent *event) { void TilesetEditorTileSelector::mouseMoveEvent(QGraphicsSceneMouseEvent *event) {
SelectablePixmapItem::mouseMoveEvent(event); SelectablePixmapItem::mouseMoveEvent(event);
this->updateSelectedTile(); this->updateSelectedTiles();
QPoint pos = this->getCellPos(event->pos()); 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 selectedTileChanged(tile); emit selectedTilesChanged();
} }
void TilesetEditorTileSelector::mouseReleaseEvent(QGraphicsSceneMouseEvent *event) { void TilesetEditorTileSelector::mouseReleaseEvent(QGraphicsSceneMouseEvent *event) {
SelectablePixmapItem::mouseReleaseEvent(event); SelectablePixmapItem::mouseReleaseEvent(event);
this->updateSelectedTile(); this->updateSelectedTiles();
emit selectedTileChanged(this->selectedTile); emit selectedTilesChanged();
} }
void TilesetEditorTileSelector::hoverMoveEvent(QGraphicsSceneHoverEvent *event) { void TilesetEditorTileSelector::hoverMoveEvent(QGraphicsSceneHoverEvent *event) {