Support custom fields for all event types

This commit is contained in:
Marcus Huderle 2019-02-03 12:26:27 -06:00 committed by huderlem
parent a894bea71b
commit c4ad0971d0
7 changed files with 262 additions and 15 deletions

View file

@ -23,6 +23,7 @@ class Event
{
public:
Event();
Event(QJsonObject, QString);
public:
int x() {
return getInt("x");
@ -75,8 +76,12 @@ public:
void setPixmapFromSpritesheet(QImage, int, int);
int getPixelX();
int getPixelY();
QMap<QString, bool> getExpectedFields();
void readCustomValues(QJsonObject values);
void addCustomValuesTo(QJsonObject *obj);
QMap<QString, QString> values;
QMap<QString, QString> customValues;
QPixmap pixmap;
int spriteWidth;
int spriteHeight;

View file

@ -0,0 +1,22 @@
#ifndef CUSTOMATTRIBUTESTABLE_H
#define CUSTOMATTRIBUTESTABLE_H
#include "event.h"
#include <QObject>
#include <QFrame>
#include <QTableWidget>
class CustomAttributesTable : public QFrame
{
public:
explicit CustomAttributesTable(Event *event, QWidget *parent = nullptr);
~CustomAttributesTable();
private:
Event *event;
QTableWidget *table;
void resizeVertically();
QMap<QString, QString> getTableFields();
};
#endif // CUSTOMATTRIBUTESTABLE_H

View file

@ -34,6 +34,7 @@ SOURCES += src/core/block.cpp \
src/ui/connectionpixmapitem.cpp \
src/ui/currentselectedmetatilespixmapitem.cpp \
src/ui/cursortilerect.cpp \
src/ui/customattributestable.cpp \
src/ui/eventpropertiesframe.cpp \
src/ui/filterchildrenproxymodel.cpp \
src/ui/graphicsview.cpp \
@ -83,6 +84,7 @@ HEADERS += include/core/block.h \
include/ui/connectionpixmapitem.h \
include/ui/currentselectedmetatilespixmapitem.h \
include/ui/cursortilerect.h \
include/ui/customattributestable.h \
include/ui/eventpropertiesframe.h \
include/ui/filterchildrenproxymodel.h \
include/ui/graphicsview.h \

View file

@ -17,6 +17,13 @@ Event::Event()
this->usingSprite = false;
}
Event::Event(QJsonObject obj, QString type)
{
Event();
this->put("event_type", type);
this->readCustomValues(obj);
}
Event* Event::createNewEvent(QString event_type, QString map_name)
{
Event *event = new Event;
@ -139,6 +146,100 @@ int Event::getPixelY()
return (this->y() * 16) - qMax(0, this->spriteHeight - 16);
}
QMap<QString, bool> Event::getExpectedFields()
{
QString type = this->get("event_type");
if (type == EventType::Object) {
return QMap<QString, bool> {
{"graphics_id", true},
{"x", true},
{"y", true},
{"elevation", true},
{"movement_type", true},
{"movement_range_x", true},
{"movement_range_y", true},
{"trainer_type", true},
{"trainer_sight_or_berry_tree_id", true},
{"script", true},
{"flag", true},
};
} else if (type == EventType::Warp) {
return QMap<QString, bool> {
{"x", true},
{"y", true},
{"elevation", true},
{"dest_map", true},
{"dest_warp_id", true},
};
} else if (type == EventType::Trigger) {
return QMap<QString, bool> {
{"type", true},
{"x", true},
{"y", true},
{"elevation", true},
{"var", true},
{"var_value", true},
{"script", true},
};
} else if (type == EventType::WeatherTrigger) {
return QMap<QString, bool> {
{"type", true},
{"x", true},
{"y", true},
{"elevation", true},
{"weather", true},
};
} else if (type == EventType::Sign) {
return QMap<QString, bool> {
{"type", true},
{"x", true},
{"y", true},
{"elevation", true},
{"player_facing_dir", true},
{"script", true},
};
} else if (type == EventType::HiddenItem) {
return QMap<QString, bool> {
{"type", true},
{"x", true},
{"y", true},
{"elevation", true},
{"item", true},
{"flag", true},
};
} else if (type == EventType::SecretBase) {
return QMap<QString, bool> {
{"type", true},
{"x", true},
{"y", true},
{"elevation", true},
{"secret_base_id", true},
};
} else {
return QMap<QString, bool>();
}
};
void Event::readCustomValues(QJsonObject values)
{
this->customValues.clear();
QMap<QString, bool> expectedValues = this->getExpectedFields();
for (QString key : values.keys()) {
if (!expectedValues.contains(key)) {
this->customValues[key] = values[key].toString();
}
}
}
void Event::addCustomValuesTo(QJsonObject *obj)
{
for (QString key : this->customValues.keys()) {
if (!obj->contains(key)) {
(*obj)[key] = this->customValues[key];
}
}
}
QJsonObject Event::buildObjectEventJSON()
{
QJsonObject eventObj;
@ -153,6 +254,7 @@ QJsonObject Event::buildObjectEventJSON()
eventObj["trainer_sight_or_berry_tree_id"] = this->get("sight_radius_tree_id");
eventObj["script"] = this->get("script_label");
eventObj["flag"] = this->get("event_flag");
this->addCustomValuesTo(&eventObj);
return eventObj;
}
@ -165,6 +267,7 @@ QJsonObject Event::buildWarpEventJSON(QMap<QString, QString> *mapNamesToMapConst
warpObj["elevation"] = this->getInt("elevation");
warpObj["dest_map"] = mapNamesToMapConstants->value(this->get("destination_map_name"));
warpObj["dest_warp_id"] = this->getInt("destination_warp");
this->addCustomValuesTo(&warpObj);
return warpObj;
}
@ -179,6 +282,7 @@ QJsonObject Event::buildTriggerEventJSON()
triggerObj["var"] = this->get("script_var");
triggerObj["var_value"] = this->get("script_var_value");
triggerObj["script"] = this->get("script_label");
this->addCustomValuesTo(&triggerObj);
return triggerObj;
}
@ -191,6 +295,7 @@ QJsonObject Event::buildWeatherTriggerEventJSON()
weatherObj["y"] = this->getU16("y");
weatherObj["elevation"] = this->getInt("elevation");
weatherObj["weather"] = this->get("weather");
this->addCustomValuesTo(&weatherObj);
return weatherObj;
}
@ -204,6 +309,7 @@ QJsonObject Event::buildSignEventJSON()
signObj["elevation"] = this->getInt("elevation");
signObj["player_facing_dir"] = this->get("player_facing_direction");
signObj["script"] = this->get("script_label");
this->addCustomValuesTo(&signObj);
return signObj;
}
@ -217,6 +323,7 @@ QJsonObject Event::buildHiddenItemEventJSON()
hiddenItemObj["elevation"] = this->getInt("elevation");
hiddenItemObj["item"] = this->get("item");
hiddenItemObj["flag"] = this->get("flag");
this->addCustomValuesTo(&hiddenItemObj);
return hiddenItemObj;
}
@ -229,6 +336,7 @@ QJsonObject Event::buildSecretBaseEventJSON()
secretBaseObj["y"] = this->getU16("y");
secretBaseObj["elevation"] = this->getInt("elevation");
secretBaseObj["secret_base_id"] = this->get("secret_base_id");
this->addCustomValuesTo(&secretBaseObj);
return secretBaseObj;
}

View file

@ -8,6 +8,7 @@
#include "ui_eventpropertiesframe.h"
#include "bordermetatilespixmapitem.h"
#include "currentselectedmetatilespixmapitem.h"
#include "customattributestable.h"
#include <QFileDialog>
#include <QStandardItemModel>
@ -1376,8 +1377,11 @@ void MainWindow::updateSelectedObjects() {
item->bind(combo, key);
}
frames.append(frame);
// Custom fields table.
CustomAttributesTable *customAttributes = new CustomAttributesTable(item->event, frame);
frame->layout()->addWidget(customAttributes);
frames.append(frame);
}
//int scroll = ui->scrollArea_4->verticalScrollBar()->value();

View file

@ -218,7 +218,7 @@ bool Project::loadMapData(Map* map) {
QJsonArray objectEventsArr = mapObj["object_events"].toArray();
for (int i = 0; i < objectEventsArr.size(); i++) {
QJsonObject event = objectEventsArr[i].toObject();
Event *object = new Event;
Event *object = new Event(event, EventType::Object);
object->put("map_name", map->name);
object->put("sprite", event["graphics_id"].toString());
object->put("x", QString::number(event["x"].toInt()));
@ -232,7 +232,6 @@ bool Project::loadMapData(Map* map) {
object->put("script_label", event["script"].toString());
object->put("event_flag", event["flag"].toString());
object->put("event_group_type", "object_event_group");
object->put("event_type", EventType::Object);
map->events["object_event_group"].append(object);
}
@ -240,7 +239,7 @@ bool Project::loadMapData(Map* map) {
QJsonArray warpEventsArr = mapObj["warp_events"].toArray();
for (int i = 0; i < warpEventsArr.size(); i++) {
QJsonObject event = warpEventsArr[i].toObject();
Event *warp = new Event;
Event *warp = new Event(event, EventType::Warp);
warp->put("map_name", map->name);
warp->put("x", QString::number(event["x"].toInt()));
warp->put("y", QString::number(event["y"].toInt()));
@ -252,12 +251,10 @@ bool Project::loadMapData(Map* map) {
if (mapConstantsToMapNames->contains(mapConstant)) {
warp->put("destination_map_name", mapConstantsToMapNames->value(mapConstant));
warp->put("event_group_type", "warp_event_group");
warp->put("event_type", EventType::Warp);
map->events["warp_event_group"].append(warp);
} else if (mapConstant == NONE_MAP_CONSTANT) {
warp->put("destination_map_name", NONE_MAP_NAME);
warp->put("event_group_type", "warp_event_group");
warp->put("event_type", EventType::Warp);
map->events["warp_event_group"].append(warp);
} else {
logError(QString("Destination map constant '%1' is invalid for warp").arg(mapConstant));
@ -292,7 +289,7 @@ bool Project::loadMapData(Map* map) {
QJsonObject event = coordEventsArr[i].toObject();
QString type = event["type"].toString();
if (type == "trigger") {
Event *coord = new Event;
Event *coord = new Event(event, EventType::Trigger);
coord->put("map_name", map->name);
coord->put("x", QString::number(event["x"].toInt()));
coord->put("y", QString::number(event["y"].toInt()));
@ -301,10 +298,9 @@ bool Project::loadMapData(Map* map) {
coord->put("script_var_value", QString::number(event["var_value"].toInt()));
coord->put("script_label", event["script"].toString());
coord->put("event_group_type", "coord_event_group");
coord->put("event_type", EventType::Trigger);
map->events["coord_event_group"].append(coord);
} else if (type == "weather") {
Event *coord = new Event;
Event *coord = new Event(event, EventType::WeatherTrigger);
coord->put("map_name", map->name);
coord->put("x", QString::number(event["x"].toInt()));
coord->put("y", QString::number(event["y"].toInt()));
@ -322,7 +318,7 @@ bool Project::loadMapData(Map* map) {
QJsonObject event = bgEventsArr[i].toObject();
QString type = event["type"].toString();
if (type == "sign") {
Event *bg = new Event;
Event *bg = new Event(event, EventType::Sign);
bg->put("map_name", map->name);
bg->put("x", QString::number(event["x"].toInt()));
bg->put("y", QString::number(event["y"].toInt()));
@ -330,10 +326,9 @@ bool Project::loadMapData(Map* map) {
bg->put("player_facing_direction", event["player_facing_dir"].toString());
bg->put("script_label", event["script"].toString());
bg->put("event_group_type", "bg_event_group");
bg->put("event_type", EventType::Sign);
map->events["bg_event_group"].append(bg);
} else if (type == "hidden_item") {
Event *bg = new Event;
Event *bg = new Event(event, EventType::HiddenItem);
bg->put("map_name", map->name);
bg->put("x", QString::number(event["x"].toInt()));
bg->put("y", QString::number(event["y"].toInt()));
@ -341,17 +336,15 @@ bool Project::loadMapData(Map* map) {
bg->put("item", event["item"].toString());
bg->put("flag", event["flag"].toString());
bg->put("event_group_type", "bg_event_group");
bg->put("event_type", EventType::HiddenItem);
map->events["bg_event_group"].append(bg);
} else if (type == "secret_base") {
Event *bg = new Event;
Event *bg = new Event(event, EventType::SecretBase);
bg->put("map_name", map->name);
bg->put("x", QString::number(event["x"].toInt()));
bg->put("y", QString::number(event["y"].toInt()));
bg->put("elevation", QString::number(event["elevation"].toInt()));
bg->put("secret_base_id", event["secret_base_id"].toString());
bg->put("event_group_type", "bg_event_group");
bg->put("event_type", EventType::SecretBase);
map->events["bg_event_group"].append(bg);
}
}

View file

@ -0,0 +1,113 @@
#include "customattributestable.h"
#include <QHBoxLayout>
#include <QHeaderView>
#include <QPushButton>
#include <QTableWidget>
#include <QLabel>
#include <QScrollBar>
CustomAttributesTable::CustomAttributesTable(Event *event, QWidget *parent) :
QFrame(parent)
{
this->event = event;
QVBoxLayout *layout = new QVBoxLayout(this);
QLabel *label = new QLabel("Custom Attributes");
layout->addWidget(label);
QFrame *buttonsFrame = new QFrame(this);
buttonsFrame->setLayout(new QHBoxLayout());
QPushButton *addButton = new QPushButton(this);
QPushButton *deleteButton = new QPushButton(this);
addButton->setText("Add");
deleteButton->setText("Delete");
buttonsFrame->layout()->addWidget(addButton);
buttonsFrame->layout()->addWidget(deleteButton);
buttonsFrame->layout()->addItem(new QSpacerItem(1, 1, QSizePolicy::Expanding, QSizePolicy::Fixed));
buttonsFrame->layout()->setMargin(0);
layout->addWidget(buttonsFrame);
this->table = new QTableWidget(this);
this->table->setColumnCount(2);
this->table->setHorizontalHeaderLabels(QStringList({"Key", "Value"}));
this->table->horizontalHeader()->setStretchLastSection(true);
layout->addWidget(this->table);
for (auto it = event->customValues.begin(); it != event->customValues.end(); it++) {
int rowIndex = this->table->rowCount();
this->table->insertRow(rowIndex);
this->table->setItem(rowIndex, 0, new QTableWidgetItem(it.key()));
this->table->setItem(rowIndex, 1, new QTableWidgetItem(it.value()));
}
connect(addButton, &QPushButton::clicked, [=]() {
int rowIndex = this->table->rowCount();
this->table->insertRow(rowIndex);
this->table->selectRow(rowIndex);
this->event->customValues = this->getTableFields();
this->resizeVertically();
});
connect(deleteButton, &QPushButton::clicked, [=]() {
int rowCount = this->table->rowCount();
if (rowCount > 0) {
QModelIndexList indexList = this->table->selectionModel()->selectedIndexes();
QList<QPersistentModelIndex> persistentIndexes;
for (QModelIndex index : indexList) {
QPersistentModelIndex persistentIndex(index);
persistentIndexes.append(persistentIndex);
}
for (QPersistentModelIndex index : persistentIndexes) {
this->table->removeRow(index.row());
}
if (this->table->rowCount() > 0) {
this->table->selectRow(0);
}
this->event->customValues = this->getTableFields();
this->resizeVertically();
}
});
connect(this->table, &QTableWidget::cellChanged, [=]() {
this->event->customValues = this->getTableFields();
});
this->resizeVertically();
}
CustomAttributesTable::~CustomAttributesTable()
{
}
QMap<QString, QString> CustomAttributesTable::getTableFields() {
QMap<QString, QString> fields;
for (int row = 0; row < table->rowCount(); row++) {
QString keyStr = "";
QString valueStr = "";
QTableWidgetItem *key = table->item(row, 0);
QTableWidgetItem *value = table->item(row, 1);
if (key) keyStr = key->text();
if (value) valueStr = value->text();
fields[keyStr] = valueStr;
}
return fields;
}
void CustomAttributesTable::resizeVertically() {
int horizontalHeaderHeight = this->table->horizontalHeader()->height();
int rowHeight = 0;
for (int i = 0; i < this->table->rowCount(); i++) {
rowHeight += this->table->rowHeight(0);
}
int totalHeight = horizontalHeaderHeight + rowHeight;
if (this->table->rowCount() == 0) {
totalHeight += 1;
} else {
totalHeight += 2;
}
this->table->setMinimumHeight(totalHeight);
this->table->setMaximumHeight(totalHeight);
}