From 80b35d6ade5e56284206071685dcd9816690880c Mon Sep 17 00:00:00 2001 From: GriffinR Date: Fri, 15 May 2026 22:23:32 -0400 Subject: [PATCH] Disallow empty prefabs --- CHANGELOG.md | 1 + include/ui/metatileselector.h | 12 ++++++++++++ include/ui/prefabcreationdialog.h | 2 ++ src/ui/prefab.cpp | 1 + src/ui/prefabcreationdialog.cpp | 11 +++++++++++ 5 files changed, 27 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 72fc8028..0135ff6c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -22,6 +22,7 @@ and this project somewhat adheres to [Semantic Versioning](https://semver.org/sp - Fix not being able to minimize/maximize some windows. - Fix some menu items under `Tools` not being disabled when their corresponding button is disabled. - Fix the map list search bar stealing keyboard focus whenever a map layout was opened. +- Disallow creating prefabs with no metatiles. ## [6.3.1] - 2026-04-12 ### Added diff --git a/include/ui/metatileselector.h b/include/ui/metatileselector.h index fc927e26..b8b9dd9d 100644 --- a/include/ui/metatileselector.h +++ b/include/ui/metatileselector.h @@ -34,6 +34,18 @@ struct MetatileSelection bool hasCollision; QList metatileItems; QList collisionItems; + + bool isEmpty() const { + for (const auto& metatileItem : metatileItems) { + if (metatileItem.enabled) return false; + } + if (hasCollision) { + for (const auto& collisionItem : collisionItems) { + if (collisionItem.enabled) return false; + } + } + return true; + }; }; class MetatileSelector: public SelectablePixmapItem { diff --git a/include/ui/prefabcreationdialog.h b/include/ui/prefabcreationdialog.h index 0821f751..ff96b2f2 100644 --- a/include/ui/prefabcreationdialog.h +++ b/include/ui/prefabcreationdialog.h @@ -24,6 +24,8 @@ private: Layout *layout = nullptr; Ui::PrefabCreationDialog *ui; MetatileSelection selection; + + void validate(); }; #endif // PREFABCREATIONDIALOG_H diff --git a/src/ui/prefab.cpp b/src/ui/prefab.cpp index fcbf889e..77e70dd4 100644 --- a/src/ui/prefab.cpp +++ b/src/ui/prefab.cpp @@ -82,6 +82,7 @@ void Prefab::loadPrefabs() { selection.metatileItems[index].enabled = true; selection.collisionItems[index].enabled = true; } + if (selection.isEmpty()) continue; this->items.append(PrefabItem{QUuid::createUuid(), name, primaryTileset, secondaryTileset, selection}); } diff --git a/src/ui/prefabcreationdialog.cpp b/src/ui/prefabcreationdialog.cpp index 34b11127..15e4d849 100644 --- a/src/ui/prefabcreationdialog.cpp +++ b/src/ui/prefabcreationdialog.cpp @@ -5,6 +5,7 @@ #include "prefab.h" #include +#include PrefabCreationDialog::PrefabCreationDialog(QWidget *parent, MetatileSelector *metatileSelector, Layout *layout) : QDialog(parent), @@ -36,9 +37,12 @@ PrefabCreationDialog::PrefabCreationDialog(QWidget *parent, MetatileSelector *me this->selection.collisionItems[index].enabled = toggledState; } pixmapItem->setPixmap(drawMetatileSelection(this->selection, layout)); + validate(); }); connect(this, &PrefabCreationDialog::accepted, this, &PrefabCreationDialog::savePrefab); + + validate(); } PrefabCreationDialog::~PrefabCreationDialog() @@ -46,6 +50,13 @@ PrefabCreationDialog::~PrefabCreationDialog() delete ui; } +void PrefabCreationDialog::validate() { + bool valid = !this->selection.isEmpty(); + + QPushButton* okButton = ui->buttonBox->button(QDialogButtonBox::Ok); + if (okButton) okButton->setEnabled(valid); +} + void PrefabCreationDialog::savePrefab() { prefab.addPrefab(this->selection, this->layout, this->ui->lineEdit_PrefabName->text()); }