Load and display prefabs in UI

This commit is contained in:
Marcus Huderle
2022-09-05 20:51:31 -05:00
parent a943b6b260
commit 3046a4d3ae
11 changed files with 316 additions and 3 deletions

View File

@@ -503,6 +503,8 @@ void ProjectConfig::parseConfigKeyValue(QString key, QString value) {
this->customScripts.append(script);
}
}
} else if (key == "prefabs_filepath") {
this->prefabFilepath = value;
} else {
logWarn(QString("Invalid config key found in config file %1: '%2'").arg(this->getConfigFilepath()).arg(key));
}
@@ -540,6 +542,7 @@ QMap<QString, QString> ProjectConfig::getKeyValueMap() {
map.insert("create_map_text_file", QString::number(this->createMapTextFile));
map.insert("enable_triple_layer_metatiles", QString::number(this->enableTripleLayerMetatiles));
map.insert("custom_scripts", this->customScripts.join(","));
map.insert("prefabs_filepath", this->prefabFilepath);
return map;
}
@@ -732,6 +735,15 @@ QList<QString> ProjectConfig::getCustomScripts() {
return this->customScripts;
}
void ProjectConfig::setPrefabFilepath(QString filepath) {
this->prefabFilepath = filepath;
this->save();
}
QString ProjectConfig::getPrefabFilepath() {
return this->prefabFilepath;
}
ShortcutsConfig shortcutsConfig;
QString ShortcutsConfig::getConfigFilepath() {

View File

@@ -16,6 +16,7 @@
#include "flowlayout.h"
#include "shortcut.h"
#include "mapparser.h"
#include "prefab.h"
#include <QFileDialog>
#include <QClipboard>
@@ -552,6 +553,12 @@ bool MainWindow::openProject(QString dir) {
}
if (success) {
prefab.initPrefabUI(
ui->scrollAreaWidgetContents_Prefabs,
ui->label_prefabHelp,
editor->ui->comboBox_PrimaryTileset->currentText(),
editor->ui->comboBox_SecondaryTileset->currentText(),
editor->map);
for (auto action : this->registeredActions) {
this->ui->menuTools->removeAction(action);
}

View File

@@ -2,8 +2,7 @@
#include "imageproviders.h"
#include <QPainter>
void CurrentSelectedMetatilesPixmapItem::draw() {
MetatileSelection selection = metatileSelector->getMetatileSelection();
QPixmap drawMetatileSelection(MetatileSelection selection, Map *map) {
int width = selection.dimensions.x() * 16;
int height = selection.dimensions.y() * 16;
QImage image(width, height, QImage::Format_RGBA8888);
@@ -27,5 +26,10 @@ void CurrentSelectedMetatilesPixmapItem::draw() {
}
painter.end();
setPixmap(QPixmap::fromImage(image));
return QPixmap::fromImage(image);
}
void CurrentSelectedMetatilesPixmapItem::draw() {
MetatileSelection selection = metatileSelector->getMetatileSelection();
setPixmap(drawMetatileSelection(selection, this->map));
}

116
src/ui/prefab.cpp Normal file
View File

@@ -0,0 +1,116 @@
#include "prefab.h"
#include "prefabframe.h"
#include "ui_prefabframe.h"
#include "parseutil.h"
#include "currentselectedmetatilespixmapitem.h"
#include <QJsonDocument>
#include <QJsonObject>
#include <QJsonArray>
#include <QGraphicsPixmapItem>
#include <QWidget>
#include <QDir>
#include <QSpacerItem>
void Prefab::loadPrefabs() {
this->items.clear();
QString filepath = projectConfig.getPrefabFilepath();
if (filepath.isEmpty()) return;
ParseUtil parser;
QJsonDocument prefabDoc;
if (!QFile::exists(filepath) || !parser.tryParseJsonFile(&prefabDoc, filepath)) {
QString relativePath = QDir::cleanPath(projectConfig.getProjectDir() + QDir::separator() + filepath);
if (!parser.tryParseJsonFile(&prefabDoc, relativePath)) {
logError(QString("Failed to prefab data from %1").arg(filepath));
return;
}
}
QJsonArray prefabs = prefabDoc.array();
if (prefabs.size() == 0) {
logWarn(QString("Prefabs array is empty or missing in %1.").arg(filepath));
return;
}
for (int i = 0; i < prefabs.size(); i++) {
QJsonObject prefabObj = prefabs[i].toObject();
if (prefabObj.isEmpty())
continue;
int width = prefabObj["width"].toInt();
int height = prefabObj["height"].toInt();
if (width <= 0 || height <= 0)
continue;
QString name = prefabObj["name"].toString();
QString primaryTileset = prefabObj["primary_tileset"].toString();
QString secondaryTileset = prefabObj["secondary_tileset"].toString();
MetatileSelection selection;
selection.dimensions = QPoint(width, height);
selection.hasCollision = true;
for (int j = 0; j < width * height; j++) {
selection.metatileItems.append(MetatileSelectionItem{false, 0});
selection.collisionItems.append(CollisionSelectionItem{false, 0, 0});
}
QJsonArray metatiles = prefabObj["metatiles"].toArray();
for (int j = 0; j < metatiles.size(); j++) {
QJsonObject metatileObj = metatiles[j].toObject();
int x = metatileObj["x"].toInt();
int y = metatileObj["y"].toInt();
if (x < 0 || x >= width || y < 0 || y >= height)
continue;
int index = y * width + x;
selection.metatileItems[index].enabled = true;
selection.metatileItems[index].metatileId = metatileObj["metatile_id"].toInt();
selection.collisionItems[index].enabled = true;
selection.collisionItems[index].collision = metatileObj["collision"].toInt();
selection.collisionItems[index].elevation = metatileObj["elevation"].toInt();
}
this->items.append(PrefabItem{name, primaryTileset, secondaryTileset, selection});
}
}
QList<PrefabItem> Prefab::getPrefabsForTilesets(QString primaryTileset, QString secondaryTileset) {
QList<PrefabItem> filteredPrefabs;
for (auto item : this->items) {
if ((item.primaryTileset.isEmpty() || item.primaryTileset == primaryTileset) &&
(item.secondaryTileset.isEmpty() || item.secondaryTileset == secondaryTileset)) {
filteredPrefabs.append(item);
}
}
return filteredPrefabs;
}
void Prefab::initPrefabUI(QWidget *prefabWidget, QLabel *emptyPrefabLabel, QString primaryTileset, QString secondaryTileset, Map *map) {
this->loadPrefabs();
QList<PrefabItem> prefabs = this->getPrefabsForTilesets(primaryTileset, secondaryTileset);
if (prefabs.isEmpty()) {
emptyPrefabLabel->setVisible(true);
return;
}
emptyPrefabLabel->setVisible(false);
for (auto item : this->items) {
PrefabFrame *frame = new PrefabFrame();
frame->ui->label_Name->setText(item.name);
auto scene = new QGraphicsScene;
scene->addPixmap(drawMetatileSelection(item.selection, map));
scene->setSceneRect(scene->itemsBoundingRect());
frame->ui->graphicsView_Prefab->setScene(scene);
frame->ui->graphicsView_Prefab->setFixedSize(scene->itemsBoundingRect().width() + 2,
scene->itemsBoundingRect().height() + 2);
prefabWidget->layout()->addWidget(frame);
}
auto spacer = new QSpacerItem(0, 0, QSizePolicy::Ignored, QSizePolicy::Expanding);
prefabWidget->layout()->addItem(spacer);
}
Prefab prefab;

15
src/ui/prefabframe.cpp Normal file
View File

@@ -0,0 +1,15 @@
#include "prefabframe.h"
#include "ui_prefabframe.h"
PrefabFrame::PrefabFrame(QWidget *parent) :
QFrame(parent),
ui(new Ui::PrefabFrame)
{
ui->setupUi(this);
}
PrefabFrame::~PrefabFrame()
{
delete ui;
}