Merge pull request #694 from GriffinRichards/metatile-selector-speed

Stop unnecessary full redraws of metatile selectors
This commit is contained in:
GriffinR 2025-03-03 14:23:25 -05:00 committed by GitHub
commit d43252506f
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
6 changed files with 97 additions and 44 deletions

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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