diff --git a/include/core/map.h b/include/core/map.h index 39aa8fef..f9ab2319 100644 --- a/include/core/map.h +++ b/include/core/map.h @@ -107,6 +107,7 @@ public: bool hasUnsavedChanges(); bool isWithinBounds(int x, int y); bool isWithinBorderBounds(int x, int y); + void openScript(QString label); MapPixmapItem *mapItem = nullptr; void setMapItem(MapPixmapItem *item) { mapItem = item; } @@ -127,6 +128,7 @@ signals: void mapChanged(Map *map); void mapDimensionsChanged(const QSize &size); void mapNeedsRedrawing(); + void openScriptRequested(QString label); }; #endif // MAP_H diff --git a/include/editor.h b/include/editor.h index 811848a2..7a2488df 100644 --- a/include/editor.h +++ b/include/editor.h @@ -97,7 +97,6 @@ public: void selectMapEvent(DraggablePixmapItem *object); void selectMapEvent(DraggablePixmapItem *object, bool toggle); DraggablePixmapItem *addNewEvent(Event::Type type); - void deleteEvent(Event *); void updateSelectedEvents(); void duplicateSelectedEvents(); void redrawObject(DraggablePixmapItem *item); @@ -105,6 +104,8 @@ public: void updateCursorRectPos(int x, int y); void setCursorRectVisible(bool visible); + bool eventLimitReached(Map *, Event::Type); + QGraphicsScene *scene = nullptr; QGraphicsPixmapItem *current_view = nullptr; MapPixmapItem *map_item = nullptr; diff --git a/include/mainwindow.h b/include/mainwindow.h index 9b2de654..89e1feac 100644 --- a/include/mainwindow.h +++ b/include/mainwindow.h @@ -325,8 +325,6 @@ private: DraggablePixmapItem *selectedBG; DraggablePixmapItem *selectedHealspot; - QVector openScriptButtons; - bool isProgrammaticEventTabChange; bool projectHasUnsavedChanges; bool projectOpenFailure = false; diff --git a/include/ui/eventframes.h b/include/ui/eventframes.h index 872f07c8..48c10120 100644 --- a/include/ui/eventframes.h +++ b/include/ui/eventframes.h @@ -76,6 +76,7 @@ public: NoScrollSpinBox *spinner_radius_x; NoScrollSpinBox *spinner_radius_y; NoScrollComboBox *combo_script; + QToolButton *button_script; NoScrollComboBox *combo_flag; NoScrollComboBox *combo_trainer_type; NoScrollComboBox *combo_radius_treeid; diff --git a/src/core/map.cpp b/src/core/map.cpp index 65facef3..2e1a2df0 100644 --- a/src/core/map.cpp +++ b/src/core/map.cpp @@ -340,6 +340,10 @@ void Map::setBorderDimensions(int newWidth, int newHeight, bool setNewBlockdata, emit mapChanged(this); } +void Map::openScript(QString label) { + emit openScriptRequested(label); +} + bool Map::getBlock(int x, int y, Block *out) { if (isWithinBounds(x, y)) { int i = y * getWidth() + x; diff --git a/src/editor.cpp b/src/editor.cpp index 24b55bc0..f1eb980a 100644 --- a/src/editor.cpp +++ b/src/editor.cpp @@ -1092,6 +1092,12 @@ bool Editor::setMap(QString map_name) { return false; } + // disconnect previous map's signals so they are not firing + // multiple times if set again in the future + if (map) { + map->disconnect(this); + } + if (project) { Map *loadedMap = project->loadMap(map_name); if (!loadedMap) { @@ -1108,6 +1114,7 @@ bool Editor::setMap(QString map_name) { } map_ruler->setMapDimensions(QSize(map->getWidth(), map->getHeight())); connect(map, &Map::mapDimensionsChanged, map_ruler, &MapRuler::setMapDimensions); + connect(map, &Map::openScriptRequested, this, &Editor::openScript); updateSelectedEvents(); } @@ -2130,19 +2137,6 @@ bool Editor::eventLimitReached(Event::Type event_type) { return false; } -void Editor::deleteEvent(Event *event) { - Map *map = event->getMap(); - if (map) { - map->removeEvent(event); - if (event->getPixmapItem()) { - events_group->removeFromGroup(event->getPixmapItem()); - delete event->getPixmapItem(); - } - } - //selected_events->removeAll(event); - //updateSelectedObjects(); -} - void Editor::openMapScripts() const { const QString scriptPath = project->getMapScriptsFilePath(map->name); openInTextEditor(scriptPath); diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp index 99a8239c..65836ef3 100644 --- a/src/mainwindow.cpp +++ b/src/mainwindow.cpp @@ -1632,14 +1632,14 @@ void MainWindow::paste() { Event *pasteEvent = nullptr; Event::Type type = Event::eventTypeFromString(event["event_type"].toString()); - if (editor->eventLimitReached(type)) { - logWarn(QString("Skipping paste, the map limit for events of type '%1' has been reached.").arg(event["event_type"].toString())); - continue; + + if (this->editor->eventLimitReached(type)) { + logWarn(QString("Cannot paste event, the limit for type '%1' has been reached.").arg(event["event_type"].toString())); + break; } switch (type) { case Event::Type::Object: - // TODO: check event limit? pasteEvent = new ObjectEvent(); pasteEvent->loadFromJson(event["event"].toObject(), this->editor->project); break; @@ -1936,7 +1936,6 @@ void MainWindow::updateObjects() { updateSelectedObjects(); } -// Should probably just pass layout and let the editor work it out void MainWindow::updateSelectedObjects() { // TODO: make events and/or frames list static? don't want to clear and // re-add children frames if they are already there in a multi-select @@ -1960,60 +1959,67 @@ void MainWindow::updateSelectedObjects() { QScrollArea *scrollTarget = ui->scrollArea_Multiple; QWidget *target = ui->scrollAreaWidgetContents_Multiple; - isProgrammaticEventTabChange = true; + this->isProgrammaticEventTabChange = true; if (events.length() == 1) { + // single selected event case Event *current = events[0]->event; - Event::Group event_group_type = current->getEventGroup(); - int event_offs = Event::getIndexOffset(event_group_type); + Event::Group eventGroup = current->getEventGroup(); + int event_offs = Event::getIndexOffset(eventGroup); - // TODO: use switch - // TODO: don't need to set min/max every time, just when changing number of events in the group - if (event_group_type == Event::Group::Object) { + switch (eventGroup) { + case Event::Group::Object: { scrollTarget = ui->scrollArea_Objects; target = ui->scrollAreaWidgetContents_Objects; ui->tabWidget_EventType->setCurrentWidget(ui->tab_Objects); this->ui->spinner_ObjectID->setValue(current->getEventIndex() + event_offs); this->ui->spinner_ObjectID->setMinimum(event_offs); - this->ui->spinner_ObjectID->setMaximum(current->getMap()->events.value(event_group_type).length() + event_offs - 1); - + this->ui->spinner_ObjectID->setMaximum(current->getMap()->events.value(eventGroup).length() + event_offs - 1); + break; } - else if (event_group_type == Event::Group::Warp) { + case Event::Group::Warp: { scrollTarget = ui->scrollArea_Warps; target = ui->scrollAreaWidgetContents_Warps; ui->tabWidget_EventType->setCurrentWidget(ui->tab_Warps); this->ui->spinner_WarpID->setValue(current->getEventIndex() + event_offs); this->ui->spinner_WarpID->setMinimum(event_offs); - this->ui->spinner_WarpID->setMaximum(current->getMap()->events.value(event_group_type).length() + event_offs - 1); + this->ui->spinner_WarpID->setMaximum(current->getMap()->events.value(eventGroup).length() + event_offs - 1); + break; } - else if (event_group_type == Event::Group::Coord) { + case Event::Group::Coord: { scrollTarget = ui->scrollArea_Triggers; target = ui->scrollAreaWidgetContents_Triggers; ui->tabWidget_EventType->setCurrentWidget(ui->tab_Triggers); this->ui->spinner_TriggerID->setValue(current->getEventIndex() + event_offs); this->ui->spinner_TriggerID->setMinimum(event_offs); - this->ui->spinner_TriggerID->setMaximum(current->getMap()->events.value(event_group_type).length() + event_offs - 1); + this->ui->spinner_TriggerID->setMaximum(current->getMap()->events.value(eventGroup).length() + event_offs - 1); + break; } - else if (event_group_type == Event::Group::Bg) { + case Event::Group::Bg: { scrollTarget = ui->scrollArea_BGs; target = ui->scrollAreaWidgetContents_BGs; ui->tabWidget_EventType->setCurrentWidget(ui->tab_BGs); this->ui->spinner_BgID->setValue(current->getEventIndex() + event_offs); this->ui->spinner_BgID->setMinimum(event_offs); - this->ui->spinner_BgID->setMaximum(current->getMap()->events.value(event_group_type).length() + event_offs - 1); + this->ui->spinner_BgID->setMaximum(current->getMap()->events.value(eventGroup).length() + event_offs - 1); + break; } - else if (event_group_type == Event::Group::Heal) { + case Event::Group::Heal: { scrollTarget = ui->scrollArea_Healspots; target = ui->scrollAreaWidgetContents_Healspots; ui->tabWidget_EventType->setCurrentWidget(ui->tab_Healspots); this->ui->spinner_HealID->setValue(current->getEventIndex() + event_offs); this->ui->spinner_HealID->setMinimum(event_offs); - this->ui->spinner_HealID->setMaximum(current->getMap()->events.value(event_group_type).length() + event_offs - 1); + this->ui->spinner_HealID->setMaximum(current->getMap()->events.value(eventGroup).length() + event_offs - 1); + break; + } + default: + break; } ui->tabWidget_EventType->removeTab(ui->tabWidget_EventType->indexOf(ui->tab_Multiple)); } @@ -2022,7 +2028,7 @@ void MainWindow::updateSelectedObjects() { ui->tabWidget_EventType->setCurrentWidget(ui->tab_Multiple); } - isProgrammaticEventTabChange = false; + this->isProgrammaticEventTabChange = false; QList frames; for (DraggablePixmapItem *item : events) { @@ -2030,28 +2036,20 @@ void MainWindow::updateSelectedObjects() { EventFrame *eventFrame = event->createEventFrame(); eventFrame->populate(this->editor->project); eventFrame->initialize(); - eventFrame->setParent(nullptr); - // TODO: hide eventFrame->connectSignals(); - // connect(item, &DraggablePixmapItem::spriteChanged, frame->ui->label_spritePixmap, &QLabel::setPixmap); frames.append(eventFrame); } if (target->layout() && target->children().length()) { for (QFrame *frame : target->findChildren()) { - frame->hide(); + if (!frames.contains(frame)) + frame->hide(); } - delete target->layout(); } - // TODO: clear every layout instead? - // TODO: layout not clearing? - // eg: scrolling through objets to clone object you - // can see previous obj frame below clone frame - // possibly can just set enabled (false) which can hide frame + // TODO: necessary? keep layout just remove widgets? if (!events.empty()) { - QVBoxLayout *layout = new QVBoxLayout; target->setLayout(layout); scrollTarget->setWidgetResizable(true); @@ -2104,25 +2102,26 @@ void MainWindow::eventTabChanged(int index) { Event::Group group = getEventGroupFromTabWidget(ui->tabWidget_EventType->widget(index)); DraggablePixmapItem *selectedEvent = nullptr; - // TODO: use switch - if (group == Event::Group::Object) { + switch (group) { + case Event::Group::Object: selectedEvent = selectedObject; ui->newEventToolButton->setDefaultAction(ui->newEventToolButton->newObjectAction); - } - else if (group == Event::Group::Warp) { + break; + case Event::Group::Warp: selectedEvent = selectedWarp; ui->newEventToolButton->setDefaultAction(ui->newEventToolButton->newWarpAction); - } - else if (group == Event::Group::Coord) { + break; + case Event::Group::Coord: selectedEvent = selectedTrigger; ui->newEventToolButton->setDefaultAction(ui->newEventToolButton->newTriggerAction); - } - else if (group == Event::Group::Bg) { + break; + case Event::Group::Bg: selectedEvent = selectedBG; ui->newEventToolButton->setDefaultAction(ui->newEventToolButton->newSignAction); - } - else if (group == Event::Group::Heal) { + break; + case Event::Group::Heal: selectedEvent = selectedHealspot; + break; } if (!isProgrammaticEventTabChange) { @@ -2712,7 +2711,7 @@ void MainWindow::on_actionAbout_Porymap_triggered() void MainWindow::on_actionOpen_Log_File_triggered() { const QString logPath = getLogPath(); const int lineCount = ParseUtil::textFileLineCount(logPath); - editor->openInTextEditor(logPath, lineCount); + this->editor->openInTextEditor(logPath, lineCount); } void MainWindow::on_actionOpen_Config_Folder_triggered() { @@ -2741,14 +2740,6 @@ void MainWindow::on_actionEdit_Preferences_triggered() { } void MainWindow::togglePreferenceSpecificUi() { - if (porymapConfig.getTextEditorGotoLine().isEmpty()) { - for (auto *button : openScriptButtons) - button->hide(); - } else { - for (auto *button : openScriptButtons) - button->show(); - } - if (porymapConfig.getTextEditorOpenFolder().isEmpty()) ui->actionOpen_Project_in_Text_Editor->setEnabled(false); else diff --git a/src/ui/eventframes.cpp b/src/ui/eventframes.cpp index c1854fbf..30df4c4d 100644 --- a/src/ui/eventframes.cpp +++ b/src/ui/eventframes.cpp @@ -77,19 +77,7 @@ void EventFrame::setup() { l_layout_xyz->addLayout(l_layout_z); - // id / index spinner - // this->spinner_id = new NoScrollSpinBox(this); - - // QHBoxLayout *l_layout_id = new QHBoxLayout(); - - // this->label_id = new QLabel("id"); - // l_layout_id->addWidget(this->spinner_id); - // l_layout_id->addWidget(this->label_id); - // l_layout_id->addItem(createSpacerH()); - QVBoxLayout *l_vbox_1 = new QVBoxLayout(); - // l_vbox_1->addLayout(l_layout_id); - l_vbox_1->addItem(createSpacerV()); l_vbox_1->addLayout(l_layout_xyz); @@ -112,12 +100,6 @@ void EventFrame::setup() { this->layout_contents->setContentsMargins(0, 0, 0, 0); this->layout_main->addLayout(this->layout_contents); - - - /// - /// connect slots to event modifiers -- actually different function - /// - //this->connectSignals(); } // TODO: add / delete buttons? @@ -131,7 +113,7 @@ void EventFrame::initCustomAttributesTable() { // ie, mark connections dirty and need redo void EventFrame::connectSignals() { this->spinner_x->disconnect(); - connect(this->spinner_x, QOverload::of(&QSpinBox::valueChanged), [this](int value){ + connect(this->spinner_x, QOverload::of(&QSpinBox::valueChanged), [this](int value) { int delta = value - event->getX(); if (delta) this->event->getMap()->editHistory.push(new EventMove(QList() << this->event, delta, 0, this->spinner_x->getActionId())); }); @@ -139,7 +121,7 @@ void EventFrame::connectSignals() { connect(this->event->getPixmapItem(), &DraggablePixmapItem::xChanged, this->spinner_x, &NoScrollSpinBox::setValue); this->spinner_y->disconnect(); - connect(this->spinner_y, QOverload::of(&QSpinBox::valueChanged), [this](int value){ + connect(this->spinner_y, QOverload::of(&QSpinBox::valueChanged), [this](int value) { int delta = value - event->getY(); if (delta) this->event->getMap()->editHistory.push(new EventMove(QList() << this->event, 0, delta, this->spinner_y->getActionId())); }); @@ -147,15 +129,13 @@ void EventFrame::connectSignals() { // TODO?? this->spinner_z->disconnect(); - connect(this->spinner_z, QOverload::of(&QSpinBox::valueChanged), [this](int value){ - int delta = value - event->getZ(); - //if (delta) this->event->getMap()->editHistory.push(new EventMove(QList() << this->event, delta, 0, this->spinner_z->getActionId())); + connect(this->spinner_z, QOverload::of(&QSpinBox::valueChanged), [this](int value) { + this->event->setZ(value); }); } void EventFrame::initialize() { // this->initialized = true; - // move to before add values to combos? will spinners need to be set agane? // TODO: does this signal blocker block spinner signals? const QSignalBlocker blocker(this); @@ -167,12 +147,9 @@ void EventFrame::initialize() { } void EventFrame::populate(Project *project) { - // if (this->populated) return; const QSignalBlocker blocker(this); - // spinBox_index->setValue(editor->project->getMap(map_name)->events.value(event_group_type).indexOf(item->event) + event_offs); - this->populated = true; } @@ -184,17 +161,10 @@ void EventFrame::setActive(bool active) { -/// -/// -/// - -//* -// TODO: spinbox limits, autocompleters +// TODO: spinbox limits void ObjectFrame::setup() { EventFrame::setup(); - //this->label_id->setText("object id"); - // sprite combo QFormLayout *l_form_sprite = new QFormLayout(); this->combo_sprite = new NoScrollComboBox(this); @@ -228,7 +198,19 @@ void ObjectFrame::setup() { QFormLayout *l_form_script = new QFormLayout(); this->combo_script = new NoScrollComboBox(this); this->combo_script->setToolTip("The script which is executed with this event."); - l_form_script->addRow("Script", this->combo_script); + + // Add button next to combo which opens combo's current script. + this->button_script = new QToolButton(this); + this->button_script->setToolTip("Go to this script definition in text editor."); + this->button_script->setFixedSize(this->combo_script->height(), this->combo_script->height()); + this->button_script->setIcon(QFileIconProvider().icon(QFileIconProvider::File)); + + QHBoxLayout *l_hbox_scr = new QHBoxLayout(); + l_hbox_scr->setSpacing(3); + l_hbox_scr->addWidget(this->combo_script); + l_hbox_scr->addWidget(this->button_script); + + l_form_script->addRow("Script", l_hbox_scr); this->layout_contents->addLayout(l_form_script); // event flag @@ -255,16 +237,9 @@ void ObjectFrame::setup() { l_form_radius_treeid->addRow("Sight Radius / Berry Tree ID", this->combo_radius_treeid); this->layout_contents->addLayout(l_form_radius_treeid); - // in connection - // QFormLayout *l_form_connection = new QFormLayout(); - // this->check_in_connection = new QCheckBox(this); - // l_form_connection->addRow("In Connection", this->check_in_connection); - // this->layout_contents->addLayout(l_form_connection); - // custom attributes EventFrame::initCustomAttributesTable(); } -//*/ void ObjectFrame::connectSignals() { EventFrame::connectSignals(); @@ -297,12 +272,16 @@ void ObjectFrame::connectSignals() { // script // add local event script labels to combo? or - // TODO: openScriptButton this->combo_script->disconnect(); connect(this->combo_script, &QComboBox::currentTextChanged, [this](const QString &text) { this->object->setScript(text); }); + this->button_script->disconnect(); + connect(this->button_script, &QToolButton::clicked, [this]() { + this->object->getMap()->openScript(this->combo_script->currentText()); + }); + // flag this->combo_flag->disconnect(); connect(this->combo_flag, &QComboBox::currentTextChanged, [this](const QString &text) { @@ -348,6 +327,8 @@ void ObjectFrame::initialize() { // script this->combo_script->setCurrentText(this->object->getScript()); + if (porymapConfig.getTextEditorGotoLine().isEmpty()) + this->button_script->hide(); // flag index = this->combo_flag->findText(this->object->getFlag()); @@ -467,20 +448,6 @@ void CloneObjectFrame::populate(Project *project) { - - - - - - - - - - - - - - void WarpFrame::setup() { EventFrame::setup(); @@ -547,11 +514,6 @@ void WarpFrame::populate(Project *project) { - - - - - void TriggerFrame::setup() { EventFrame::setup(); @@ -570,7 +532,7 @@ void TriggerFrame::setup() { l_form_var->addRow("Var", this->combo_var); this->layout_contents->addLayout(l_form_var); - // var value spinner + // var value combo QFormLayout *l_form_var_val = new QFormLayout(); this->combo_var_value = new NoScrollComboBox(this); this->combo_var_value->setToolTip("The variable's value which triggers the script."); @@ -584,10 +546,27 @@ void TriggerFrame::setup() { void TriggerFrame::connectSignals() { EventFrame::connectSignals(); - // + // label + this->combo_script->disconnect(); + connect(this->combo_script, &QComboBox::currentTextChanged, [this](const QString &text) { + this->trigger->setScriptLabel(text); + }); + + // var + this->combo_var->disconnect(); + connect(this->combo_var, &QComboBox::currentTextChanged, [this](const QString &text) { + this->trigger->setScriptVar(text); + }); + + // value + this->combo_var_value->disconnect(); + connect(this->combo_var_value, &QComboBox::currentTextChanged, [this](const QString &text) { + this->trigger->setScriptVarValue(text); + }); } void TriggerFrame::initialize() { + // TODO: make us of this or delete it //if (this->populated) return; const QSignalBlocker blocker(this); EventFrame::initialize(); @@ -630,10 +609,6 @@ void TriggerFrame::populate(Project *project) { - - - - void WeatherTriggerFrame::setup() { EventFrame::setup(); @@ -684,16 +659,6 @@ void WeatherTriggerFrame::populate(Project *project) { - - - - - - - - - - void SignFrame::setup() { EventFrame::setup(); @@ -771,21 +736,6 @@ void SignFrame::populate(Project *project) { - - - - - - - - - - - - - - - void HiddenItemFrame::setup() { EventFrame::setup(); @@ -897,19 +847,6 @@ void HiddenItemFrame::populate(Project *project) { - - - - - - - - - - - - - void SecretBaseFrame::setup() { EventFrame::setup(); @@ -962,34 +899,9 @@ void SecretBaseFrame::populate(Project *project) { - - - - - - - - - - - - - - - - - - - - - - - void HealLocationFrame::setup() { EventFrame::setup(); - //this->label_id->setText("heal location id"); - // item combo QFormLayout *l_form_respawn_map = new QFormLayout(); this->combo_respawn_map = new NoScrollComboBox(this);