Add right-click selection to tileset editor metatile layer item

This commit is contained in:
Marcus Huderle 2018-10-06 15:49:26 -05:00
parent bbfecba1ba
commit 888270f3ef
10 changed files with 125 additions and 23 deletions

View file

@ -5,11 +5,12 @@
class Tile class Tile
{ {
public: public:
Tile(); Tile() {}
Tile(int tile, bool xflip, bool yflip, int palette);
public: public:
int tile; int tile;
int xflip; bool xflip;
int yflip; bool yflip;
int palette; int palette;
}; };

View file

@ -2,13 +2,14 @@
#define METATILELAYERSITEM_H #define METATILELAYERSITEM_H
#include "tileset.h" #include "tileset.h"
#include "selectablepixmapitem.h"
#include <QGraphicsPixmapItem> #include <QGraphicsPixmapItem>
#include <QGraphicsSceneMouseEvent> #include <QGraphicsSceneMouseEvent>
class MetatileLayersItem : public QObject, public QGraphicsPixmapItem { class MetatileLayersItem: public SelectablePixmapItem {
Q_OBJECT Q_OBJECT
public: public:
MetatileLayersItem(Metatile *metatile, Tileset *primaryTileset, Tileset *secondaryTileset) { MetatileLayersItem(Metatile *metatile, Tileset *primaryTileset, Tileset *secondaryTileset): SelectablePixmapItem(16, 16, 2, 2) {
this->metatile = metatile; this->metatile = metatile;
this->primaryTileset = primaryTileset; this->primaryTileset = primaryTileset;
this->secondaryTileset = secondaryTileset; this->secondaryTileset = secondaryTileset;
@ -22,8 +23,11 @@ private:
Tileset *secondaryTileset; Tileset *secondaryTileset;
signals: signals:
void tileChanged(int, int); void tileChanged(int, int);
void selectedTilesChanged(QPoint, int, int);
protected: protected:
void mousePressEvent(QGraphicsSceneMouseEvent*); void mousePressEvent(QGraphicsSceneMouseEvent*);
void mouseMoveEvent(QGraphicsSceneMouseEvent*);
void mouseReleaseEvent(QGraphicsSceneMouseEvent*);
}; };
#endif // METATILELAYERSITEM_H #endif // METATILELAYERSITEM_H

View file

@ -30,6 +30,7 @@ private slots:
void onHoveredTileCleared(); void onHoveredTileCleared();
void onSelectedTilesChanged(); void onSelectedTilesChanged();
void onMetatileLayerTileChanged(int, int); void onMetatileLayerTileChanged(int, int);
void onMetatileLayerSelectionChanged(QPoint, int, int);
void onPaletteEditorClosed(); void onPaletteEditorClosed();
void onPaletteEditorChangedPaletteColor(); void onPaletteEditorChangedPaletteColor();
void onPaletteEditorChangedPalette(int); void onPaletteEditorChangedPalette(int);

View file

@ -16,12 +16,14 @@ public:
this->yFlip = false; this->yFlip = false;
setAcceptHoverEvents(true); setAcceptHoverEvents(true);
} }
QPoint getSelectionDimensions();
void draw(); void draw();
void select(uint16_t metatileId); void select(uint16_t metatileId);
void setTilesets(Tileset*, Tileset*); void setTilesets(Tileset*, Tileset*);
void setPaletteId(int); void setPaletteId(int);
void setTileFlips(bool, bool); void setTileFlips(bool, bool);
QList<uint16_t> getSelectedTiles(); QList<Tile> getSelectedTiles();
void setExternalSelection(int, int, QList<Tile>);
protected: protected:
void mousePressEvent(QGraphicsSceneMouseEvent*); void mousePressEvent(QGraphicsSceneMouseEvent*);
@ -31,6 +33,11 @@ protected:
void hoverLeaveEvent(QGraphicsSceneHoverEvent*); void hoverLeaveEvent(QGraphicsSceneHoverEvent*);
private: private:
bool externalSelection;
int externalSelectionWidth;
int externalSelectionHeight;
QList<Tile> externalSelectedTiles;
Tileset *primaryTileset; Tileset *primaryTileset;
Tileset *secondaryTileset; Tileset *secondaryTileset;
QList<uint16_t> selectedTiles; QList<uint16_t> selectedTiles;

View file

@ -1,6 +1,9 @@
#include "tile.h" #include "tile.h"
Tile::Tile() Tile::Tile(int tile, bool xflip, bool yflip, int palette)
{ {
this->tile = tile;
this->xflip = xflip;
this->yflip = yflip;
this->palette = palette;
} }

View file

@ -64,7 +64,7 @@ QImage getMetatileImage(uint16_t tile, Tileset *primaryTileset, Tileset *seconda
} }
QPoint origin = QPoint(x*8, y*8); QPoint origin = QPoint(x*8, y*8);
metatile_painter.drawImage(origin, tile_image.mirrored(tile_.xflip == 1, tile_.yflip == 1)); metatile_painter.drawImage(origin, tile_image.mirrored(tile_.xflip, tile_.yflip));
} }
metatile_painter.end(); metatile_painter.end();

View file

@ -38,8 +38,42 @@ void MetatileLayersItem::setTilesets(Tileset *primaryTileset, Tileset *secondary
} }
void MetatileLayersItem::mousePressEvent(QGraphicsSceneMouseEvent *event) { void MetatileLayersItem::mousePressEvent(QGraphicsSceneMouseEvent *event) {
if (event->buttons() & Qt::RightButton) {
SelectablePixmapItem::mousePressEvent(event);
QPoint selectionOrigin = this->getSelectionStart();
QPoint dimensions = this->getSelectionDimensions();
emit this->selectedTilesChanged(selectionOrigin, dimensions.x(), dimensions.y());
this->drawSelection();
} else {
QPointF pos = event->pos();
int x = static_cast<int>(pos.x()) / 16;
int y = static_cast<int>(pos.y()) / 16;
emit this->tileChanged(x, y);
}
}
void MetatileLayersItem::mouseMoveEvent(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;
emit this->tileChanged(x, y); if (event->buttons() & Qt::RightButton) {
SelectablePixmapItem::mouseMoveEvent(event);
QPoint selectionOrigin = this->getSelectionStart();
QPoint dimensions = this->getSelectionDimensions();
emit this->selectedTilesChanged(selectionOrigin, dimensions.x(), dimensions.y());
this->drawSelection();
} else {
emit this->tileChanged(x, y);
}
}
void MetatileLayersItem::mouseReleaseEvent(QGraphicsSceneMouseEvent *event) {
if (event->buttons() & Qt::RightButton) {
SelectablePixmapItem::mouseReleaseEvent(event);
QPoint selectionOrigin = this->getSelectionStart();
QPoint dimensions = this->getSelectionDimensions();
emit this->selectedTilesChanged(selectionOrigin, dimensions.x(), dimensions.y());
}
this->draw();
} }

View file

@ -108,6 +108,7 @@ PaletteEditor::PaletteEditor(Project *project, Tileset *primaryTileset, Tileset
this->initColorSliders(); this->initColorSliders();
this->refreshColorSliders(); this->refreshColorSliders();
this->refreshColors(); this->refreshColors();
this->commitEditHistory();
} }
PaletteEditor::~PaletteEditor() PaletteEditor::~PaletteEditor()

View file

@ -125,15 +125,15 @@ void TilesetEditor::drawSelectedTiles() {
} }
this->selectedTileScene->clear(); this->selectedTileScene->clear();
QList<uint16_t> tiles = this->tileSelector->getSelectedTiles(); QList<Tile> tiles = this->tileSelector->getSelectedTiles();
QPoint dimensions = this->tileSelector->getSelectionDimensions(); QPoint dimensions = this->tileSelector->getSelectionDimensions();
QImage selectionImage(16 * dimensions.x(), 16 * dimensions.y(), QImage::Format_RGBA8888); QImage selectionImage(16 * dimensions.x(), 16 * dimensions.y(), QImage::Format_RGBA8888);
QPainter painter(&selectionImage); QPainter painter(&selectionImage);
int tileIndex = 0; int tileIndex = 0;
for (int j = 0; j < dimensions.y(); j++) { for (int j = 0; j < dimensions.y(); j++) {
for (int i = 0; i < dimensions.x(); i++) { for (int i = 0; i < dimensions.x(); i++) {
QImage tileImage = getColoredTileImage(tiles.at(tileIndex), this->primaryTileset, this->secondaryTileset, this->paletteId) QImage tileImage = getColoredTileImage(tiles.at(tileIndex).tile, this->primaryTileset, this->secondaryTileset, tiles.at(tileIndex).palette)
.mirrored(this->tileXFlip, this->tileYFlip) .mirrored(tiles.at(tileIndex).xflip, tiles.at(tileIndex).yflip)
.scaled(16, 16); .scaled(16, 16);
tileIndex++; tileIndex++;
painter.drawImage(i * 16, j * 16, tileImage); painter.drawImage(i * 16, j * 16, tileImage);
@ -150,6 +150,8 @@ void TilesetEditor::initMetatileLayersItem() {
this->metatileLayersItem = new MetatileLayersItem(metatile, this->primaryTileset, this->secondaryTileset); this->metatileLayersItem = new MetatileLayersItem(metatile, this->primaryTileset, this->secondaryTileset);
connect(this->metatileLayersItem, SIGNAL(tileChanged(int, int)), connect(this->metatileLayersItem, SIGNAL(tileChanged(int, int)),
this, SLOT(onMetatileLayerTileChanged(int, int))); this, SLOT(onMetatileLayerTileChanged(int, int)));
connect(this->metatileLayersItem, SIGNAL(selectedTilesChanged(QPoint, int, int)),
this, SLOT(onMetatileLayerSelectionChanged(QPoint, int, int)));
this->metatileLayersScene = new QGraphicsScene; this->metatileLayersScene = new QGraphicsScene;
this->metatileLayersScene->addItem(this->metatileLayersItem); this->metatileLayersScene->addItem(this->metatileLayersItem);
@ -191,17 +193,17 @@ void TilesetEditor::onSelectedTilesChanged() {
void TilesetEditor::onMetatileLayerTileChanged(int x, int y) { void TilesetEditor::onMetatileLayerTileChanged(int x, int y) {
int maxTileIndex = x < 2 ? 3 : 7; int maxTileIndex = x < 2 ? 3 : 7;
QPoint dimensions = this->tileSelector->getSelectionDimensions(); QPoint dimensions = this->tileSelector->getSelectionDimensions();
QList<uint16_t> tiles = this->tileSelector->getSelectedTiles(); QList<Tile> tiles = this->tileSelector->getSelectedTiles();
int selectedTileIndex = 0; int selectedTileIndex = 0;
for (int j = 0; j < dimensions.y(); j++) { for (int j = 0; j < dimensions.y(); j++) {
for (int i = 0; i < dimensions.x(); i++) { for (int i = 0; i < dimensions.x(); i++) {
int tileIndex = ((x + i) / 2 * 4) + ((y + j) * 2) + ((x + i) % 2); int tileIndex = ((x + i) / 2 * 4) + ((y + j) * 2) + ((x + i) % 2);
if (tileIndex <= maxTileIndex) { if (tileIndex <= maxTileIndex) {
Tile tile = this->metatile->tiles->at(tileIndex); Tile tile = this->metatile->tiles->at(tileIndex);
tile.tile = tiles.at(selectedTileIndex); tile.tile = tiles.at(selectedTileIndex).tile;
tile.xflip = this->tileXFlip; tile.xflip = tiles.at(selectedTileIndex).xflip;
tile.yflip = this->tileYFlip; tile.yflip = tiles.at(selectedTileIndex).yflip;
tile.palette = this->paletteId; tile.palette = tiles.at(selectedTileIndex).palette;
(*this->metatile->tiles)[tileIndex] = tile; (*this->metatile->tiles)[tileIndex] = tile;
} }
selectedTileIndex++; selectedTileIndex++;
@ -213,6 +215,21 @@ void TilesetEditor::onMetatileLayerTileChanged(int x, int y) {
this->hasUnsavedChanges = true; this->hasUnsavedChanges = true;
} }
void TilesetEditor::onMetatileLayerSelectionChanged(QPoint selectionOrigin, int width, int height) {
QList<Tile> tiles;
int x = selectionOrigin.x();
int y = selectionOrigin.y();
for (int j = 0; j < height; j++) {
for (int i = 0; i < width; i++) {
int tileIndex = ((x + i) / 2 * 4) + ((y + j) * 2) + ((x + i) % 2);
if (tileIndex < 8) {
tiles.append(this->metatile->tiles->at(tileIndex));
}
}
}
this->tileSelector->setExternalSelection(width, height, tiles);
}
void TilesetEditor::on_spinBox_paletteSelector_valueChanged(int paletteId) void TilesetEditor::on_spinBox_paletteSelector_valueChanged(int paletteId)
{ {
this->ui->spinBox_paletteSelector->blockSignals(true); this->ui->spinBox_paletteSelector->blockSignals(true);
@ -391,8 +408,8 @@ void TilesetEditor::on_actionChange_Metatiles_Count_triggered()
Tile tile; Tile tile;
tile.palette = 0; tile.palette = 0;
tile.tile = 0; tile.tile = 0;
tile.xflip = 0; tile.xflip = false;
tile.yflip = 0; tile.yflip = false;
Metatile *metatile = new Metatile; Metatile *metatile = new Metatile;
metatile->behavior = 0; metatile->behavior = 0;
metatile->layerType = 0; metatile->layerType = 0;

View file

@ -3,6 +3,14 @@
#include "project.h" #include "project.h"
#include <QPainter> #include <QPainter>
QPoint TilesetEditorTileSelector::getSelectionDimensions() {
if (this->externalSelection) {
return QPoint(this->externalSelectionWidth, this->externalSelectionHeight);
} else {
return SelectablePixmapItem::getSelectionDimensions();
}
}
void TilesetEditorTileSelector::draw() { void TilesetEditorTileSelector::draw() {
if (!this->primaryTileset || !this->primaryTileset->tiles if (!this->primaryTileset || !this->primaryTileset->tiles
|| !this->secondaryTileset || !this->secondaryTileset->tiles) { || !this->secondaryTileset || !this->secondaryTileset->tiles) {
@ -40,10 +48,14 @@ void TilesetEditorTileSelector::draw() {
painter.end(); painter.end();
this->setPixmap(QPixmap::fromImage(image)); this->setPixmap(QPixmap::fromImage(image));
this->drawSelection();
if (!this->externalSelection) {
this->drawSelection();
}
} }
void TilesetEditorTileSelector::select(uint16_t tile) { void TilesetEditorTileSelector::select(uint16_t tile) {
this->externalSelection = false;
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->updateSelectedTiles(); this->updateSelectedTiles();
@ -68,6 +80,7 @@ void TilesetEditorTileSelector::setTileFlips(bool xFlip, bool yFlip) {
} }
void TilesetEditorTileSelector::updateSelectedTiles() { void TilesetEditorTileSelector::updateSelectedTiles() {
this->externalSelection = false;
this->selectedTiles.clear(); this->selectedTiles.clear();
QPoint origin = this->getSelectionStart(); QPoint origin = this->getSelectionStart();
QPoint dimensions = this->getSelectionDimensions(); QPoint dimensions = this->getSelectionDimensions();
@ -79,8 +92,29 @@ void TilesetEditorTileSelector::updateSelectedTiles() {
} }
} }
QList<uint16_t> TilesetEditorTileSelector::getSelectedTiles() { QList<Tile> TilesetEditorTileSelector::getSelectedTiles() {
return this->selectedTiles; if (this->externalSelection) {
return this->externalSelectedTiles;
} else {
QList<Tile> tiles;
for (uint16_t tile : this->selectedTiles) {
tiles.append(Tile(tile, this->xFlip, this->yFlip, this->paletteId));
}
return tiles;
}
}
void TilesetEditorTileSelector::setExternalSelection(int width, int height, QList<Tile> tiles) {
this->externalSelection = true;
this->externalSelectionWidth = width;
this->externalSelectionHeight = height;
this->externalSelectedTiles.clear();
for (int i = 0; i < tiles.length(); i++) {
this->externalSelectedTiles.append(tiles.at(i));
}
this->draw();
emit selectedTilesChanged();
} }
uint16_t TilesetEditorTileSelector::getTileId(int x, int y) { uint16_t TilesetEditorTileSelector::getTileId(int x, int y) {