diff --git a/include/ui/metatileselector.h b/include/ui/metatileselector.h index fba0993d..7bb3f131 100644 --- a/include/ui/metatileselector.h +++ b/include/ui/metatileselector.h @@ -42,8 +42,10 @@ public: this->cellPos = QPoint(-1, -1); setAcceptHoverEvents(true); } - QPoint getSelectionDimensions(); - void draw(); + + QPoint getSelectionDimensions() override; + void draw() override; + bool select(uint16_t metatile); void selectFromMap(uint16_t metatileId, uint16_t collision, uint16_t elevation); void setTilesets(Tileset*, Tileset*); @@ -53,15 +55,18 @@ public: QPoint getMetatileIdCoordsOnWidget(uint16_t); void setLayout(Layout *layout); bool isInternalSelection() const { return (!this->externalSelection && !this->prefabSelection); } + Tileset *primaryTileset; Tileset *secondaryTileset; protected: - void mousePressEvent(QGraphicsSceneMouseEvent*); - void mouseMoveEvent(QGraphicsSceneMouseEvent*); - void mouseReleaseEvent(QGraphicsSceneMouseEvent*); - void hoverMoveEvent(QGraphicsSceneHoverEvent*); - void hoverLeaveEvent(QGraphicsSceneHoverEvent*); + void mousePressEvent(QGraphicsSceneMouseEvent*) override; + void mouseMoveEvent(QGraphicsSceneMouseEvent*) override; + void mouseReleaseEvent(QGraphicsSceneMouseEvent*) override; + void hoverMoveEvent(QGraphicsSceneHoverEvent*) override; + void hoverLeaveEvent(QGraphicsSceneHoverEvent*) override; + void drawSelection() override; private: + QPixmap basePixmap; bool externalSelection; bool prefabSelection; int numMetatilesWide; @@ -72,6 +77,7 @@ private: MetatileSelection selection; QPoint cellPos; + void updateBasePixmap(); void updateSelectedMetatiles(); void updateExternalSelectedMetatiles(); uint16_t getMetatileId(int x, int y) const; diff --git a/include/ui/selectablepixmapitem.h b/include/ui/selectablepixmapitem.h index 97a47c43..2681e485 100644 --- a/include/ui/selectablepixmapitem.h +++ b/include/ui/selectablepixmapitem.h @@ -31,9 +31,9 @@ protected: void select(int, int, int, int); void updateSelection(int, int); QPoint getCellPos(QPointF); - void mousePressEvent(QGraphicsSceneMouseEvent*); - void mouseMoveEvent(QGraphicsSceneMouseEvent*); - void mouseReleaseEvent(QGraphicsSceneMouseEvent*); + virtual void mousePressEvent(QGraphicsSceneMouseEvent*) override; + virtual void mouseMoveEvent(QGraphicsSceneMouseEvent*) override; + virtual void mouseReleaseEvent(QGraphicsSceneMouseEvent*) override; virtual void drawSelection(); signals: diff --git a/include/ui/tileseteditormetatileselector.h b/include/ui/tileseteditormetatileselector.h index afc77ffe..8a3fdfa7 100644 --- a/include/ui/tileseteditormetatileselector.h +++ b/include/ui/tileseteditormetatileselector.h @@ -11,9 +11,13 @@ class TilesetEditorMetatileSelector: public SelectablePixmapItem { public: TilesetEditorMetatileSelector(Tileset *primaryTileset, Tileset *secondaryTileset, Layout *layout); Layout *layout = nullptr; - void draw(); + + void draw() override; + void drawMetatile(uint16_t metatileId); + void drawSelectedMetatile(); + bool select(uint16_t metatileId); - void setTilesets(Tileset*, Tileset*, bool draw = true); + void setTilesets(Tileset*, Tileset*); uint16_t getSelectedMetatileId(); void updateSelectedMetatile(); QPoint getMetatileIdCoordsOnWidget(uint16_t metatileId); @@ -27,18 +31,21 @@ public: bool showDivider = false; protected: - void mousePressEvent(QGraphicsSceneMouseEvent*); - void mouseMoveEvent(QGraphicsSceneMouseEvent*); - void mouseReleaseEvent(QGraphicsSceneMouseEvent*); - void hoverMoveEvent(QGraphicsSceneHoverEvent*); - void hoverLeaveEvent(QGraphicsSceneHoverEvent*); + void mousePressEvent(QGraphicsSceneMouseEvent*) override; + void mouseMoveEvent(QGraphicsSceneMouseEvent*) override; + void mouseReleaseEvent(QGraphicsSceneMouseEvent*) override; + void hoverMoveEvent(QGraphicsSceneHoverEvent*) override; + void hoverLeaveEvent(QGraphicsSceneHoverEvent*) override; private: + QImage baseImage; + QPixmap basePixmap; Tileset *primaryTileset = nullptr; Tileset *secondaryTileset = nullptr; - uint16_t selectedMetatile; + uint16_t selectedMetatileId; int numMetatilesWide; int numMetatilesHigh; + void updateBasePixmap(); uint16_t getMetatileId(int x, int y); QPoint getMetatileIdCoords(uint16_t); bool shouldAcceptEvent(QGraphicsSceneMouseEvent*); diff --git a/src/ui/metatileselector.cpp b/src/ui/metatileselector.cpp index b8bafefc..012b6609 100644 --- a/src/ui/metatileselector.cpp +++ b/src/ui/metatileselector.cpp @@ -14,11 +14,7 @@ int MetatileSelector::numPrimaryMetatilesRounded() const { return ceil((double)this->primaryTileset->numMetatiles() / this->numMetatilesWide) * this->numMetatilesWide; } -void MetatileSelector::draw() { - if (!this->primaryTileset || !this->secondaryTileset) { - this->setPixmap(QPixmap()); - } - +void MetatileSelector::updateBasePixmap() { int primaryLength = this->numPrimaryMetatilesRounded(); int length_ = primaryLength + this->secondaryTileset->numMetatiles(); int height_ = length_ / this->numMetatilesWide; @@ -39,12 +35,20 @@ void MetatileSelector::draw() { QPoint metatile_origin = QPoint(map_x * 16, map_y * 16); painter.drawImage(metatile_origin, metatile_image); } - painter.end(); - this->setPixmap(QPixmap::fromImage(image)); + this->basePixmap = QPixmap::fromImage(image); +} +void MetatileSelector::draw() { + if (this->basePixmap.isNull()) + updateBasePixmap(); + setPixmap(this->basePixmap); + drawSelection(); +} + +void MetatileSelector::drawSelection() { if (!this->prefabSelection && (!this->externalSelection || (this->externalSelectionWidth == 1 && this->externalSelectionHeight == 1))) { - this->drawSelection(); + SelectablePixmapItem::drawSelection(); } } @@ -76,7 +80,9 @@ void MetatileSelector::setTilesets(Tileset *primaryTileset, Tileset *secondaryTi this->updateExternalSelectedMetatiles(); else this->updateSelectedMetatiles(); - this->draw(); + + updateBasePixmap(); + draw(); } MetatileSelection MetatileSelector::getMetatileSelection() { diff --git a/src/ui/tileseteditor.cpp b/src/ui/tileseteditor.cpp index 9668f1cb..5d6dede9 100644 --- a/src/ui/tileseteditor.cpp +++ b/src/ui/tileseteditor.cpp @@ -475,7 +475,7 @@ void TilesetEditor::onMetatileLayerTileChanged(int x, int y) { } } - this->metatileSelector->draw(); + this->metatileSelector->drawSelectedMetatile(); this->metatileLayersItem->draw(); this->tileSelector->draw(); this->commitMetatileChange(prevMetatile); @@ -603,7 +603,7 @@ void TilesetEditor::on_comboBox_layerType_activated(int layerType) Metatile *prevMetatile = new Metatile(*this->metatile); this->metatile->setLayerType(layerType); this->commitMetatileChange(prevMetatile); - this->metatileSelector->draw(); // Changing the layer type can affect how fully transparent metatiles appear + this->metatileSelector->drawSelectedMetatile(); // Changing the layer type can affect how fully transparent metatiles appear } } @@ -860,7 +860,7 @@ bool TilesetEditor::replaceMetatile(uint16_t metatileId, const Metatile * src, Q this->metatile = dest; *this->metatile = *src; this->metatileSelector->select(metatileId); - this->metatileSelector->draw(); + this->metatileSelector->drawMetatile(metatileId); this->metatileLayersItem->draw(); this->metatileLayersItem->clearLastModifiedCoords(); this->metatileLayersItem->clearLastHoveredCoords(); diff --git a/src/ui/tileseteditormetatileselector.cpp b/src/ui/tileseteditormetatileselector.cpp index 07e50bba..4e09cf34 100644 --- a/src/ui/tileseteditormetatileselector.cpp +++ b/src/ui/tileseteditormetatileselector.cpp @@ -5,7 +5,8 @@ TilesetEditorMetatileSelector::TilesetEditorMetatileSelector(Tileset *primaryTileset, Tileset *secondaryTileset, Layout *layout) : SelectablePixmapItem(32, 32, 1, 1) { - this->setTilesets(primaryTileset, secondaryTileset, false); + this->primaryTileset = primaryTileset; + this->secondaryTileset = secondaryTileset; this->numMetatilesWide = 8; this->layout = layout; setAcceptHoverEvents(true); @@ -72,42 +73,75 @@ QImage TilesetEditorMetatileSelector::buildImage(int metatileIdStart, int numMet return image; } +void TilesetEditorMetatileSelector::drawMetatile(uint16_t metatileId) { + QPoint pos = getMetatileIdCoords(metatileId); + + QPainter painter(&this->baseImage); + QImage metatile_image = getMetatileImage( + metatileId, + this->primaryTileset, + this->secondaryTileset, + this->layout->metatileLayerOrder, + this->layout->metatileLayerOpacity, + true) + .scaled(this->cellWidth, this->cellHeight); + painter.drawImage(QPoint(pos.x() * this->cellWidth, pos.y() * this->cellHeight), metatile_image); + painter.end(); + + this->basePixmap = QPixmap::fromImage(this->baseImage); + draw(); +} + +void TilesetEditorMetatileSelector::drawSelectedMetatile() { + drawMetatile(this->selectedMetatileId); +} + +void TilesetEditorMetatileSelector::updateBasePixmap() { + this->baseImage = buildAllMetatilesImage(); + this->basePixmap = QPixmap::fromImage(this->baseImage); +} + void TilesetEditorMetatileSelector::draw() { - this->setPixmap(QPixmap::fromImage(this->buildAllMetatilesImage())); - this->drawGrid(); - this->drawDivider(); - this->drawSelection(); - this->drawFilters(); + if (this->basePixmap.isNull()) + updateBasePixmap(); + setPixmap(this->basePixmap); + + drawGrid(); + drawDivider(); + drawFilters(); + + drawSelection(); } bool TilesetEditorMetatileSelector::select(uint16_t metatileId) { if (!Tileset::metatileIsValid(metatileId, this->primaryTileset, this->secondaryTileset)) return false; QPoint coords = this->getMetatileIdCoords(metatileId); SelectablePixmapItem::select(coords.x(), coords.y(), 0, 0); - this->selectedMetatile = metatileId; + this->selectedMetatileId = metatileId; emit selectedMetatileChanged(metatileId); return true; } -void TilesetEditorMetatileSelector::setTilesets(Tileset *primaryTileset, Tileset *secondaryTileset, bool draw) { +void TilesetEditorMetatileSelector::setTilesets(Tileset *primaryTileset, Tileset *secondaryTileset) { this->primaryTileset = primaryTileset; this->secondaryTileset = secondaryTileset; - if (draw) this->draw(); + updateBasePixmap(); + draw(); } void TilesetEditorMetatileSelector::updateSelectedMetatile() { QPoint origin = this->getSelectionStart(); uint16_t metatileId = this->getMetatileId(origin.x(), origin.y()); if (Tileset::metatileIsValid(metatileId, this->primaryTileset, this->secondaryTileset)) - this->selectedMetatile = metatileId; + this->selectedMetatileId = metatileId; else - this->selectedMetatile = Project::getNumMetatilesPrimary() + this->secondaryTileset->numMetatiles() - 1; - emit selectedMetatileChanged(this->selectedMetatile); + this->selectedMetatileId = Project::getNumMetatilesPrimary() + this->secondaryTileset->numMetatiles() - 1; + emit selectedMetatileChanged(this->selectedMetatileId); } uint16_t TilesetEditorMetatileSelector::getSelectedMetatileId() { - return this->selectedMetatile; + return this->selectedMetatileId; } uint16_t TilesetEditorMetatileSelector::getMetatileId(int x, int y) { @@ -135,7 +169,7 @@ void TilesetEditorMetatileSelector::mouseMoveEvent(QGraphicsSceneMouseEvent *eve if (!shouldAcceptEvent(event)) return; SelectablePixmapItem::mouseMoveEvent(event); this->updateSelectedMetatile(); - emit hoveredMetatileChanged(this->selectedMetatile); + emit hoveredMetatileChanged(this->selectedMetatileId); } void TilesetEditorMetatileSelector::mouseReleaseEvent(QGraphicsSceneMouseEvent *event) {