From dcba9ececd6d6b5a3e0573150eb0629d921220b2 Mon Sep 17 00:00:00 2001 From: GriffinR Date: Fri, 3 Nov 2023 02:40:03 -0400 Subject: [PATCH] Update custom scripts editor --- forms/customscriptseditor.ui | 34 +++++++++++--- forms/customscriptslistitem.ui | 24 +++++----- include/ui/customscriptseditor.h | 8 ++-- resources/icons/edit_document.ico | Bin 1675 -> 0 bytes resources/icons/file_add.ico | Bin 0 -> 1272 bytes resources/icons/file_edit.ico | Bin 0 -> 1292 bytes resources/icons/file_put.ico | Bin 0 -> 1037 bytes resources/images.qrc | 4 +- resources/text.qrc | 1 + resources/text/script_template.js | 71 ++++++++++++++++++++++++++++++ src/ui/customscriptseditor.cpp | 69 +++++++++++++++++++++++------ 11 files changed, 174 insertions(+), 37 deletions(-) delete mode 100755 resources/icons/edit_document.ico create mode 100755 resources/icons/file_add.ico create mode 100755 resources/icons/file_edit.ico create mode 100755 resources/icons/file_put.ico create mode 100644 resources/text/script_template.js diff --git a/forms/customscriptseditor.ui b/forms/customscriptseditor.ui index 8166ed8d..2469339d 100644 --- a/forms/customscriptseditor.ui +++ b/forms/customscriptseditor.ui @@ -6,7 +6,7 @@ 0 0 - 374 + 535 355 @@ -49,20 +49,40 @@ - + + + Create a new Porymap script file with a default template + - Add New Script... + Create New Script... - :/icons/add.ico:/icons/add.ico + :/icons/file_add.ico:/icons/file_add.ico - + + + Add an existing script file to the list below + - Reload Scripts + Load Script... + + + + :/icons/file_put.ico:/icons/file_put.ico + + + + + + + Refresh all loaded scripts to account for any recent edits + + + Refresh Scripts @@ -128,7 +148,7 @@ false - QAbstractItemView::NoDragDrop + QAbstractItemView::DragOnly Qt::IgnoreAction diff --git a/forms/customscriptslistitem.ui b/forms/customscriptslistitem.ui index 7c7e8794..3a34e954 100644 --- a/forms/customscriptslistitem.ui +++ b/forms/customscriptslistitem.ui @@ -6,7 +6,7 @@ 0 0 - 129 + 151 34 @@ -24,16 +24,12 @@ 4 - + - Choose a new filepath for this script + If unchecked this script will be ignored - ... - - - - :/icons/folder.ico:/icons/folder.ico + @@ -51,12 +47,16 @@ - + - If unchecked this script will be ignored + Choose a new filepath for this script - + ... + + + + :/icons/folder.ico:/icons/folder.ico @@ -70,7 +70,7 @@ - :/icons/edit_document.ico:/icons/edit_document.ico + :/icons/file_edit.ico:/icons/file_edit.ico diff --git a/include/ui/customscriptseditor.h b/include/ui/customscriptseditor.h index d54a7cc3..27238c4e 100644 --- a/include/ui/customscriptseditor.h +++ b/include/ui/customscriptseditor.h @@ -31,10 +31,11 @@ private: Ui::CustomScriptsEditor *ui; bool hasUnsavedChanges = false; - QString importDir; + QString fileDialogDir; const QString baseDir; void displayScript(const QString &filepath, bool enabled); + void displayNewScript(QString filepath); QString chooseScript(QString dir); void removeScript(QListWidgetItem * item); void replaceScript(QListWidgetItem * item); @@ -52,8 +53,9 @@ private: private slots: void dialogButtonClicked(QAbstractButton *button); - void addNewScript(); - void reloadScripts(); + void createNewScript(); + void loadScript(); + void refreshScripts(); void removeSelectedScripts(); void openSelectedScripts(); }; diff --git a/resources/icons/edit_document.ico b/resources/icons/edit_document.ico deleted file mode 100755 index cd4bb026137a915d7478de409c616f9952501e85..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1675 zcmV;626Xv}P)6i>#fJ}@g}2A>p=fkB!F{b7BR_vF zispS>fu5v*D}Cn7e{JIZ`}c9Gyu9R%Idf*yqiKWhD?H?Nxt(}fpNvLNGn(8jh`v*U z=e~I}N~HzSj0Nnzb^8uELW<0OdUr_5U>qzg#Jst4F?rIY^rGUDyRXkmAIx2|r?AwU zHsUGt?Gumu1A8$|ei1D#Ug&-=e?3m-i)^>cvMfYVlrD+AUYsTM4u=!{`}fEAaTAjY z%1&PU>Eje{OmrN2#rMXIx|>Ms`#6f4%FyqRT8!E8?il`_8fp!<-rle)jjy+eH#V7K zVq;P7Xhu>(Ukol^l$y4D0n(C_vAy6NRDUzBU%w7BN=91lk_oi@9!awtzF~L7=5v&; zA+C2E&SfRx`DOEgq)ec46P6hZQFreFWIY<&H*MzNw>V`u3Bx=fN6Z0xed?3LQCNBc zPn=nd3E7K)flGj@4Zw|K~=EaI63C%H!yNhMyWFfBic(Y83i zJo?w*F%?|N8bFpWYy+<&aM{A{pHuM8&d$LF@k1X}MT4fsLQ|qhaaHuudOT+B=t;lv zIl1-RWtpNt)uBYkqjvQmOjy3K&Fyt%A{XUeN!niWirNd@Z=?JmNNr6l?hn7=Ng!&fp6W^8F&W;7%UuL z!SHI1gjmW^uWXfY^nC_D^P;Gz09USFCb>f3F(^55oWKVKzz2qc`;k+Xhz0qzVo%HP zK9a}@-xn7%-sQ-Bc5d<0aiAn;?N?r`w8_SeGnc)=_m50EakFcRv}DQWPYvs@KX5RK_yYtS{C z*L1jUUqtFlt6|(Nhtc98%Y6bo^FS?~87WB~ltL0z#0pH?q9H~nU@ew<4O73AaCS8V z5g&hEEyb`D$_2k41AFibs_Xtj-laq=C2+~0NFh%s!2;D)1=RMn)k4K8hAEpQoc@&h z4b-m+U*Noen?Y8D66mxcvnsSV6j@04H7`;ow zq`>zgd7|kbmyz@)8A8%0q72gYFV}|Ph1Bsd1vLJR7W&EjA2)t8X(sV^_T%3I3;>il V-yZDPnl}Id002ovPDHLkV1k)VA`Jil diff --git a/resources/icons/file_add.ico b/resources/icons/file_add.ico new file mode 100755 index 0000000000000000000000000000000000000000..d33fc2bd253bb5a67ffbe23a7562423a59dae3ff GIT binary patch literal 1272 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 Hu0mjfOi0~! literal 0 HcmV?d00001 diff --git a/resources/images.qrc b/resources/images.qrc index 2399cbe9..8afb0df4 100644 --- a/resources/images.qrc +++ b/resources/images.qrc @@ -4,8 +4,10 @@ icons/collapse_all.ico icons/cursor.ico icons/delete.ico - icons/edit_document.ico icons/expand_all.ico + icons/file_add.ico + icons/file_edit.ico + icons/file_put.ico icons/fill_color_cursor.ico icons/fill_color.ico icons/folder_closed_map.ico diff --git a/resources/text.qrc b/resources/text.qrc index 8567f8b5..b1c47e58 100644 --- a/resources/text.qrc +++ b/resources/text.qrc @@ -6,6 +6,7 @@ text/prefabs_default_emerald.json text/prefabs_default_firered.json text/prefabs_default_ruby.json + text/script_template.js ../CHANGELOG.md diff --git a/resources/text/script_template.js b/resources/text/script_template.js new file mode 100644 index 00000000..fdd1949f --- /dev/null +++ b/resources/text/script_template.js @@ -0,0 +1,71 @@ +// Called when Porymap successfully opens a project. +export function onProjectOpened(projectPath) { + +} + +// Called when Porymap closes a project. For example, this is called when opening a different project. +export function onProjectClosed(projectPath) { + +} + +// Called when a map is opened. +export function onMapOpened(mapName) { + +} + +// Called when a block is changed on the map. For example, this is called when a user paints a new tile or changes the collision property of a block. +export function onBlockChanged(x, y, prevBlock, newBlock) { + +} + +// Called when a border metatile is changed. +export function onBorderMetatileChanged(x, y, prevMetatileId, newMetatileId) { + +} + +// Called when the mouse enters a new map block. +export function onBlockHoverChanged(x, y) { + +} + +// Called when the mouse exits the map. +export function onBlockHoverCleared() { + +} + +// Called when the dimensions of the map are changed. +export function onMapResized(oldWidth, oldHeight, newWidth, newHeight) { + +} + +// Called when the dimensions of the border are changed. +export function onBorderResized(oldWidth, oldHeight, newWidth, newHeight) { + +} + +// Called when the map is updated by use of the Map Shift tool. +export function onMapShifted(xDelta, yDelta) { + +} + +// Called when the currently loaded tileset is changed by switching to a new one or by saving changes to it in the Tileset Editor. +export function onTilesetUpdated(tilesetName) { + +} + +// Called when the selected tab in the main tab bar is changed. +// Tabs are indexed from left to right, starting at 0 (0: Map, 1: Events, 2: Header, 3: Connections, 4: Wild Pokemon). +export function onMainTabChanged(oldTab, newTab) { + +} + +// Called when the selected tab in the map view tab bar is changed. +// Tabs are indexed from left to right, starting at 0 (0: Metatiles, 1: Collision, 2: Prefabs). +export function onMapViewTabChanged(oldTab, newTab) { + +} + +// Called when the visibility of the border and connecting maps is toggled on or off. +export function onBorderVisibilityToggled(visible) { + +} diff --git a/src/ui/customscriptseditor.cpp b/src/ui/customscriptseditor.cpp index 6daeb0eb..accc9c89 100644 --- a/src/ui/customscriptseditor.cpp +++ b/src/ui/customscriptseditor.cpp @@ -23,10 +23,11 @@ CustomScriptsEditor::CustomScriptsEditor(QWidget *parent) : for (int i = 0; i < paths.length(); i++) this->displayScript(paths.at(i), enabled.at(i)); - this->importDir = userConfig.getProjectDir(); + this->fileDialogDir = userConfig.getProjectDir(); - connect(ui->button_AddNewScript, &QAbstractButton::clicked, this, &CustomScriptsEditor::addNewScript); - connect(ui->button_ReloadScripts, &QAbstractButton::clicked, this, &CustomScriptsEditor::reloadScripts); + connect(ui->button_CreateNewScript, &QAbstractButton::clicked, this, &CustomScriptsEditor::createNewScript); + connect(ui->button_LoadScript, &QAbstractButton::clicked, this, &CustomScriptsEditor::loadScript); + connect(ui->button_RefreshScripts, &QAbstractButton::clicked, this, &CustomScriptsEditor::refreshScripts); connect(ui->buttonBox, &QDialogButtonBox::clicked, this, &CustomScriptsEditor::dialogButtonClicked); this->initShortcuts(); @@ -48,13 +49,17 @@ void CustomScriptsEditor::initShortcuts() { shortcut_open->setObjectName("shortcut_open"); shortcut_open->setWhatsThis("Open Selected Scripts"); - auto *shortcut_addNew = new Shortcut(QKeySequence(), this, SLOT(addNewScript())); - shortcut_addNew->setObjectName("shortcut_addNew"); - shortcut_addNew->setWhatsThis("Add New Script..."); + auto *shortcut_createNew = new Shortcut(QKeySequence(), this, SLOT(createNewScript())); + shortcut_createNew->setObjectName("shortcut_createNew"); + shortcut_createNew->setWhatsThis("Create New Script..."); - auto *shortcut_reload = new Shortcut(QKeySequence(), this, SLOT(reloadScripts())); - shortcut_reload->setObjectName("shortcut_reload"); - shortcut_reload->setWhatsThis("Reload Scripts"); + auto *shortcut_load = new Shortcut(QKeySequence(), this, SLOT(loadScript())); + shortcut_load->setObjectName("shortcut_load"); + shortcut_load->setWhatsThis("Load Script..."); + + auto *shortcut_refresh = new Shortcut(QKeySequence(), this, SLOT(refreshScripts())); + shortcut_refresh->setObjectName("shortcut_refresh"); + shortcut_refresh->setWhatsThis("Refresh Scripts"); shortcutsConfig.load(); shortcutsConfig.setDefaultShortcuts(shortcutableObjects()); @@ -145,13 +150,49 @@ QString CustomScriptsEditor::chooseScript(QString dir) { return QFileDialog::getOpenFileName(this, "Choose Custom Script File", dir, "JavaScript Files (*.js)"); } -void CustomScriptsEditor::addNewScript() { - QString filepath = this->chooseScript(this->importDir); +void CustomScriptsEditor::createNewScript() { + QString filepath = QFileDialog::getSaveFileName(this, "Create New Script File", this->fileDialogDir + "/new_script.js", "JavaScript Files (*.js)"); if (filepath.isEmpty()) return; - this->importDir = filepath; + this->fileDialogDir = filepath; + + QFile scriptFile(filepath); + if (!scriptFile.open(QIODevice::WriteOnly)) { + logError(QString("Error: Could not open %1 for writing").arg(filepath)); + QMessageBox messageBox(this); + messageBox.setText("Failed to create new script file!"); + messageBox.setInformativeText(QString("Could not open \"%1\" for writing").arg(filepath)); + messageBox.setIcon(QMessageBox::Warning); + messageBox.exec(); + return; + } + ParseUtil parser; + scriptFile.write(parser.readTextFile(":/text/script_template.js").toUtf8()); + scriptFile.close(); + // TODO: When this dialog closes, focus returns to the editor window + this->displayNewScript(filepath); +} + +void CustomScriptsEditor::loadScript() { + QString filepath = this->chooseScript(this->fileDialogDir); + if (filepath.isEmpty()) + return; + this->fileDialogDir = filepath; + this->displayNewScript(filepath); +} + +void CustomScriptsEditor::displayNewScript(QString filepath) { if (filepath.startsWith(this->baseDir)) filepath.remove(0, this->baseDir.length()); + + // Verify new script path is not already in list + for (int i = 0; i < ui->list->count(); i++) { + if (filepath == this->getScriptFilepath(ui->list->item(i), false)) { + QMessageBox::information(this, "", QString("The script '%1' is already loaded").arg(filepath)); + return; + } + } + this->displayScript(filepath, true); this->markEdited(); } @@ -192,7 +233,7 @@ void CustomScriptsEditor::openSelectedScripts() { this->openScript(item); } -void CustomScriptsEditor::reloadScripts() { +void CustomScriptsEditor::refreshScripts() { if (this->hasUnsavedChanges) { if (this->prompt("Scripts have been modified, save changes and reload the script engine?", QMessageBox::Yes) == QMessageBox::No) return; @@ -218,7 +259,7 @@ void CustomScriptsEditor::save() { userConfig.setCustomScripts(paths, enabledStates); this->hasUnsavedChanges = false; - this->reloadScripts(); + this->refreshScripts(); } int CustomScriptsEditor::prompt(const QString &text, QMessageBox::StandardButton defaultButton) {