Merge pull request #696 from GriffinRichards/new-event-button

New event button refactor
This commit is contained in:
GriffinR 2025-03-06 21:21:49 -05:00 committed by GitHub
commit 89bdd03a0e
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
7 changed files with 99 additions and 167 deletions

View File

@ -66,7 +66,6 @@ public:
Trigger, WeatherTrigger,
Sign, HiddenItem, SecretBase,
HealLocation,
Generic,
None,
};
@ -168,7 +167,9 @@ public:
static QString groupToString(Event::Group group);
static QString typeToString(Event::Type type);
static Event::Type typeFromString(QString type);
static QString typeToJsonKey(Event::Type type);
static Event::Type typeFromJsonKey(QString type);
static QList<Event::Type> types();
// protected attributes
protected:

View File

@ -9,31 +9,20 @@ class NewEventToolButton : public QToolButton
Q_OBJECT
public:
explicit NewEventToolButton(QWidget *parent = nullptr);
Event::Type getSelectedEventType();
QAction *newObjectAction;
QAction *newCloneObjectAction;
QAction *newWarpAction;
QAction *newHealLocationAction;
QAction *newTriggerAction;
QAction *newWeatherTriggerAction;
QAction *newSignAction;
QAction *newHiddenItemAction;
QAction *newSecretBaseAction;
public slots:
void newObject();
void newCloneObject();
void newWarp();
void newHealLocation();
void newTrigger();
void newWeatherTrigger();
void newSign();
void newHiddenItem();
void newSecretBase();
Event::Type getSelectedEventType() const { return this->selectedEventType; }
bool selectEventType(Event::Type type);
void setEventTypeVisible(Event::Type type, bool visible);
signals:
void newEventAdded(Event::Type);
private:
QMap<Event::Type,QAction*> typeToAction;
Event::Type selectedEventType;
void init();
QMenu* menu;
void addEventType(Event::Type type);
};
#endif // NEWEVENTTOOLBUTTON_H

View File

@ -73,19 +73,20 @@ void Event::modify() {
this->map->modify();
}
const QMap<Event::Group, QString> groupToStringMap = {
{Event::Group::Object, "Object"},
{Event::Group::Warp, "Warp"},
{Event::Group::Coord, "Trigger"},
{Event::Group::Bg, "BG"},
{Event::Group::Heal, "Heal Location"},
};
QString Event::groupToString(Event::Group group) {
static const QMap<Event::Group, QString> groupToStringMap = {
{Event::Group::Object, "Object"},
{Event::Group::Warp, "Warp"},
{Event::Group::Coord, "Trigger"},
{Event::Group::Bg, "BG"},
{Event::Group::Heal, "Heal Location"},
};
return groupToStringMap.value(group);
}
const QMap<Event::Type, QString> typeToStringMap = {
// These are the expected key names used in the map.json files.
// We re-use them for key names in the copy/paste JSON data,
const QMap<Event::Type, QString> typeToJsonKeyMap = {
{Event::Type::Object, "object"},
{Event::Type::CloneObject, "clone_object"},
{Event::Type::Warp, "warp"},
@ -97,12 +98,32 @@ const QMap<Event::Type, QString> typeToStringMap = {
{Event::Type::HealLocation, "heal_location"},
};
QString Event::typeToString(Event::Type type) {
return typeToStringMap.value(type);
QString Event::typeToJsonKey(Event::Type type) {
return typeToJsonKeyMap.value(type);
}
Event::Type Event::typeFromString(QString type) {
return typeToStringMap.key(type, Event::Type::None);
Event::Type Event::typeFromJsonKey(QString type) {
return typeToJsonKeyMap.key(type, Event::Type::None);
}
QList<Event::Type> Event::types() {
static QList<Event::Type> typeList = typeToJsonKeyMap.keys();
return typeList;
}
QString Event::typeToString(Event::Type type) {
static const QMap<Event::Type, QString> typeToStringMap = {
{Event::Type::Object, "Object"},
{Event::Type::CloneObject, "Clone Object"},
{Event::Type::Warp, "Warp"},
{Event::Type::Trigger, "Trigger"},
{Event::Type::WeatherTrigger, "Weather"},
{Event::Type::Sign, "Sign"},
{Event::Type::HiddenItem, "Hidden Item"},
{Event::Type::SecretBase, "Secret Base"},
{Event::Type::HealLocation, "Heal Location"},
};
return typeToStringMap.value(type);
}
void Event::loadPixmap(Project *project) {

View File

@ -1148,6 +1148,7 @@ void Editor::unsetMap() {
this->map->pruneEditHistory();
this->map->disconnect(this);
}
clearMapEvents();
clearMapConnections();
this->map = nullptr;

View File

@ -1109,9 +1109,9 @@ bool MainWindow::setProjectUI() {
// Wild Encounters tab
ui->mainTabBar->setTabEnabled(MainTab::WildPokemon, editor->project->wildEncountersLoaded);
ui->newEventToolButton->newWeatherTriggerAction->setVisible(projectConfig.eventWeatherTriggerEnabled);
ui->newEventToolButton->newSecretBaseAction->setVisible(projectConfig.eventSecretBaseEnabled);
ui->newEventToolButton->newCloneObjectAction->setVisible(projectConfig.eventCloneObjectEnabled);
ui->newEventToolButton->setEventTypeVisible(Event::Type::WeatherTrigger, projectConfig.eventWeatherTriggerEnabled);
ui->newEventToolButton->setEventTypeVisible(Event::Type::SecretBase, projectConfig.eventSecretBaseEnabled);
ui->newEventToolButton->setEventTypeVisible(Event::Type::CloneObject, projectConfig.eventCloneObjectEnabled);
editor->setCollisionGraphics();
ui->spinBox_SelectedElevation->setMaximum(Block::getMaxElevation());
@ -1647,7 +1647,7 @@ void MainWindow::copy() {
OrderedJson::array eventsArray;
for (const auto &event : this->editor->selectedEvents) {
OrderedJson::object eventContainer;
eventContainer["event_type"] = Event::typeToString(event->getEventType());
eventContainer["event_type"] = Event::typeToJsonKey(event->getEventType());
OrderedJson::object eventJson = event->buildEventJson(editor->project);
eventContainer["event"] = eventJson;
eventsArray.append(eventContainer);
@ -1758,7 +1758,7 @@ void MainWindow::paste() {
QJsonArray events = pasteObject["events"].toArray();
for (QJsonValue event : events) {
// paste the event to the map
Event::Type type = Event::typeFromString(event["event_type"].toString());
Event::Type type = Event::typeFromJsonKey(event["event_type"].toString());
Event *pasteEvent = Event::create(type);
if (!pasteEvent)
continue;
@ -1990,7 +1990,7 @@ void MainWindow::resetMapViewScale() {
void MainWindow::tryAddEventTab(QWidget * tab) {
auto group = getEventGroupFromTabWidget(tab);
if (editor->map->getNumEvents(group))
if (this->editor->map && this->editor->map->getNumEvents(group))
ui->tabWidget_EventType->addTab(tab, QString("%1s").arg(Event::groupToString(group)));
}
@ -2118,6 +2118,11 @@ void MainWindow::updateSelectedEvents() {
ui->tabWidget_EventType->setCurrentWidget(ui->tab_Multiple);
}
if (!events.isEmpty()) {
// Set the 'New Event' button to be the type of the most recently-selected event
ui->newEventToolButton->selectEventType(events.constLast()->getEventType());
}
this->isProgrammaticEventTabChange = false;
QList<QFrame *> frames;
@ -2177,27 +2182,6 @@ void MainWindow::eventTabChanged(int index) {
if (editor->map) {
Event::Group group = getEventGroupFromTabWidget(ui->tabWidget_EventType->widget(index));
Event *selectedEvent = this->lastSelectedEvent.value(group, nullptr);
switch (group) {
case Event::Group::Object:
ui->newEventToolButton->setDefaultAction(ui->newEventToolButton->newObjectAction);
break;
case Event::Group::Warp:
ui->newEventToolButton->setDefaultAction(ui->newEventToolButton->newWarpAction);
break;
case Event::Group::Coord:
ui->newEventToolButton->setDefaultAction(ui->newEventToolButton->newTriggerAction);
break;
case Event::Group::Bg:
ui->newEventToolButton->setDefaultAction(ui->newEventToolButton->newSignAction);
break;
case Event::Group::Heal:
ui->newEventToolButton->setDefaultAction(ui->newEventToolButton->newHealLocationAction);
break;
default:
break;
}
if (!isProgrammaticEventTabChange) {
if (!selectedEvent) selectedEvent = this->editor->map->getEvent(group, 0);
this->editor->selectMapEvent(selectedEvent);

View File

@ -207,7 +207,7 @@ bool Project::readMapJson(const QString &mapName, QJsonDocument * out) {
bool Project::loadMapEvent(Map *map, const QJsonObject &json, Event::Type defaultType) {
QString typeString = ParseUtil::jsonToQString(json["type"]);
Event::Type type = typeString.isEmpty() ? defaultType : Event::typeFromString(typeString);
Event::Type type = typeString.isEmpty() ? defaultType : Event::typeFromJsonKey(typeString);
Event* event = Event::create(type);
if (!event) {
return false;

View File

@ -8,117 +8,53 @@ NewEventToolButton::NewEventToolButton(QWidget *parent) :
{
setPopupMode(QToolButton::MenuButtonPopup);
QObject::connect(this, &NewEventToolButton::triggered, this, &NewEventToolButton::setDefaultAction);
this->init();
this->menu = new QMenu(this);
for (const auto &type : Event::types()) {
addEventType(type);
}
setMenu(this->menu);
setDefaultAction(this->menu->actions().constFirst());
}
void NewEventToolButton::init()
{
// Add a context menu to select different types of map events.
this->newObjectAction = new QAction("New Object", this);
this->newObjectAction->setIcon(QIcon(":/icons/add.ico"));
connect(this->newObjectAction, &QAction::triggered, this, &NewEventToolButton::newObject);
void NewEventToolButton::addEventType(Event::Type type) {
if (this->typeToAction.contains(type))
return;
this->newCloneObjectAction = new QAction("New Clone Object", this);
this->newCloneObjectAction->setIcon(QIcon(":/icons/add.ico"));
connect(this->newCloneObjectAction, &QAction::triggered, this, &NewEventToolButton::newCloneObject);
auto action = new QAction(QStringLiteral("New ") + Event::typeToString(type), this);
action->setIcon(QIcon(QStringLiteral(":/icons/add.ico")));
connect(action, &QAction::triggered, [this, type] {
this->selectedEventType = type;
emit newEventAdded(this->selectedEventType);
});
this->newWarpAction = new QAction("New Warp", this);
this->newWarpAction->setIcon(QIcon(":/icons/add.ico"));
connect(this->newWarpAction, &QAction::triggered, this, &NewEventToolButton::newWarp);
this->newHealLocationAction = new QAction("New Heal Location", this);
this->newHealLocationAction->setIcon(QIcon(":/icons/add.ico"));
connect(this->newHealLocationAction, &QAction::triggered, this, &NewEventToolButton::newHealLocation);
this->newTriggerAction = new QAction("New Trigger", this);
this->newTriggerAction->setIcon(QIcon(":/icons/add.ico"));
connect(this->newTriggerAction, &QAction::triggered, this, &NewEventToolButton::newTrigger);
this->newWeatherTriggerAction = new QAction("New Weather Trigger", this);
this->newWeatherTriggerAction->setIcon(QIcon(":/icons/add.ico"));
connect(this->newWeatherTriggerAction, &QAction::triggered, this, &NewEventToolButton::newWeatherTrigger);
this->newSignAction = new QAction("New Sign", this);
this->newSignAction->setIcon(QIcon(":/icons/add.ico"));
connect(this->newSignAction, &QAction::triggered, this, &NewEventToolButton::newSign);
this->newHiddenItemAction = new QAction("New Hidden Item", this);
this->newHiddenItemAction->setIcon(QIcon(":/icons/add.ico"));
connect(this->newHiddenItemAction, &QAction::triggered, this, &NewEventToolButton::newHiddenItem);
this->newSecretBaseAction = new QAction("New Secret Base", this);
this->newSecretBaseAction->setIcon(QIcon(":/icons/add.ico"));
connect(this->newSecretBaseAction, &QAction::triggered, this, &NewEventToolButton::newSecretBase);
QMenu *alignMenu = new QMenu(this);
alignMenu->addAction(this->newObjectAction);
alignMenu->addAction(this->newCloneObjectAction);
alignMenu->addAction(this->newWarpAction);
alignMenu->addAction(this->newHealLocationAction);
alignMenu->addAction(this->newTriggerAction);
alignMenu->addAction(this->newWeatherTriggerAction);
alignMenu->addAction(this->newSignAction);
alignMenu->addAction(this->newHiddenItemAction);
alignMenu->addAction(this->newSecretBaseAction);
this->setMenu(alignMenu);
this->setDefaultAction(this->newObjectAction);
this->typeToAction.insert(type, action);
this->menu->addAction(action);
}
Event::Type NewEventToolButton::getSelectedEventType()
{
return this->selectedEventType;
bool NewEventToolButton::selectEventType(Event::Type type) {
auto action = this->typeToAction.value(type);
if (!action || !action->isVisible())
return false;
this->selectedEventType = type;
setDefaultAction(action);
return true;
}
void NewEventToolButton::newObject()
{
this->selectedEventType = Event::Type::Object;
emit newEventAdded(this->selectedEventType);
}
void NewEventToolButton::setEventTypeVisible(Event::Type type, bool visible) {
auto action = this->typeToAction.value(type);
if (!action)
return;
void NewEventToolButton::newCloneObject()
{
this->selectedEventType = Event::Type::CloneObject;
emit newEventAdded(this->selectedEventType);
}
action->setVisible(visible);
void NewEventToolButton::newWarp()
{
this->selectedEventType = Event::Type::Warp;
emit newEventAdded(this->selectedEventType);
}
void NewEventToolButton::newHealLocation()
{
this->selectedEventType = Event::Type::HealLocation;
emit newEventAdded(this->selectedEventType);
}
void NewEventToolButton::newTrigger()
{
this->selectedEventType = Event::Type::Trigger;
emit newEventAdded(this->selectedEventType);
}
void NewEventToolButton::newWeatherTrigger()
{
this->selectedEventType = Event::Type::WeatherTrigger;
emit newEventAdded(this->selectedEventType);
}
void NewEventToolButton::newSign()
{
this->selectedEventType = Event::Type::Sign;
emit newEventAdded(this->selectedEventType);
}
void NewEventToolButton::newHiddenItem()
{
this->selectedEventType = Event::Type::HiddenItem;
emit newEventAdded(this->selectedEventType);
}
void NewEventToolButton::newSecretBase()
{
this->selectedEventType = Event::Type::SecretBase;
emit newEventAdded(this->selectedEventType);
// If we just hid the currently-selected type we need to pick a new type.
if (this->selectedEventType == type) {
for (const auto &newType : Event::types()) {
if (newType != type && selectEventType(newType)){
break;
}
}
}
}