Allow running EditorScripts from the FileSystemDock

Apply suggestions from code review

Co-Authored-By: Tomasz Chabora <kobewi4e@gmail.com>
This commit is contained in:
Ryan
2025-05-13 02:07:26 -04:00
parent db66343528
commit e3db0d62a8
5 changed files with 57 additions and 30 deletions

View File

@ -96,6 +96,7 @@
#include "editor/editor_property_name_processor.h" #include "editor/editor_property_name_processor.h"
#include "editor/editor_resource_picker.h" #include "editor/editor_resource_picker.h"
#include "editor/editor_resource_preview.h" #include "editor/editor_resource_preview.h"
#include "editor/editor_script.h"
#include "editor/editor_settings.h" #include "editor/editor_settings.h"
#include "editor/editor_settings_dialog.h" #include "editor/editor_settings_dialog.h"
#include "editor/editor_translation_parser.h" #include "editor/editor_translation_parser.h"
@ -5742,6 +5743,41 @@ bool EditorNode::validate_custom_directory() {
return true; return true;
} }
void EditorNode::run_editor_script(const Ref<Script> &p_script) {
Error err = p_script->reload(true); // Always hard reload the script before running.
if (err != OK || !p_script->is_valid()) {
EditorToaster::get_singleton()->popup_str(TTR("Cannot run the script because it contains errors, check the output log."), EditorToaster::SEVERITY_WARNING);
return;
}
// Perform additional checks on the script to evaluate if it's runnable.
bool is_runnable = true;
if (!ClassDB::is_parent_class(p_script->get_instance_base_type(), "EditorScript")) {
is_runnable = false;
EditorToaster::get_singleton()->popup_str(TTR("Cannot run the script because it doesn't extend EditorScript."), EditorToaster::SEVERITY_WARNING);
}
if (!p_script->is_tool()) {
is_runnable = false;
if (p_script->get_class() == "GDScript") {
EditorToaster::get_singleton()->popup_str(TTR("Cannot run the script because it's not a tool script (add the @tool annotation at the top)."), EditorToaster::SEVERITY_WARNING);
} else if (p_script->get_class() == "CSharpScript") {
EditorToaster::get_singleton()->popup_str(TTR("Cannot run the script because it's not a tool script (add the [Tool] attribute above the class definition)."), EditorToaster::SEVERITY_WARNING);
} else {
EditorToaster::get_singleton()->popup_str(TTR("Cannot run the script because it's not a tool script."), EditorToaster::SEVERITY_WARNING);
}
}
if (!is_runnable) {
return;
}
Ref<EditorScript> es = memnew(EditorScript);
es->set_script(p_script);
es->run();
}
void EditorNode::_immediate_dialog_confirmed() { void EditorNode::_immediate_dialog_confirmed() {
immediate_dialog_confirmed = true; immediate_dialog_confirmed = true;
} }

View File

@ -990,6 +990,7 @@ public:
bool ensure_main_scene(bool p_from_native); bool ensure_main_scene(bool p_from_native);
bool validate_custom_directory(); bool validate_custom_directory();
void run_editor_script(const Ref<Script> &p_script);
}; };
class EditorPluginList : public Object { class EditorPluginList : public Object {

View File

@ -2588,6 +2588,14 @@ void FileSystemDock::_file_option(int p_option, const Vector<String> &p_selected
String dir = ProjectSettings::get_singleton()->globalize_path(fpath); String dir = ProjectSettings::get_singleton()->globalize_path(fpath);
ScriptEditor::get_singleton()->open_text_file_create_dialog(dir); ScriptEditor::get_singleton()->open_text_file_create_dialog(dir);
} break; } break;
case FILE_MENU_RUN_SCRIPT: {
if (p_selected.size() == 1) {
const String &fpath = p_selected[0];
Ref<Script> scr = ResourceLoader::load(fpath);
ERR_FAIL_COND(scr.is_null());
EditorNode::get_singleton()->run_editor_script(scr);
}
} break;
case EXTRA_FOCUS_PATH: { case EXTRA_FOCUS_PATH: {
focus_on_filter(); focus_on_filter();
@ -3273,6 +3281,16 @@ void FileSystemDock::_file_and_folders_fill_popup(PopupMenu *p_popup, const Vect
p_popup->add_separator(); p_popup->add_separator();
} else if (filenames.size() == 1) { } else if (filenames.size() == 1) {
p_popup->add_icon_item(get_editor_theme_icon(SNAME("Load")), TTRC("Open"), FILE_MENU_OPEN); p_popup->add_icon_item(get_editor_theme_icon(SNAME("Load")), TTRC("Open"), FILE_MENU_OPEN);
String type = EditorFileSystem::get_singleton()->get_file_type(filenames[0]);
if (ClassDB::is_parent_class(type, "Script")) {
Ref<Script> scr = ResourceLoader::load(filenames[0]);
if (scr.is_valid()) {
if (ClassDB::is_parent_class(scr->get_instance_base_type(), "EditorScript")) {
p_popup->add_icon_item(get_editor_theme_icon(SNAME("MainPlay")), TTRC("Run"), FILE_MENU_RUN_SCRIPT);
}
}
}
p_popup->add_separator(); p_popup->add_separator();
} }

View File

@ -129,6 +129,7 @@ private:
FILE_MENU_NEW_FOLDER, FILE_MENU_NEW_FOLDER,
FILE_MENU_NEW_SCRIPT, FILE_MENU_NEW_SCRIPT,
FILE_MENU_NEW_SCENE, FILE_MENU_NEW_SCENE,
FILE_MENU_RUN_SCRIPT,
FILE_MENU_MAX, FILE_MENU_MAX,
// Extra shortcuts that don't exist in the menu. // Extra shortcuts that don't exist in the menu.
EXTRA_FOCUS_PATH, EXTRA_FOCUS_PATH,

View File

@ -1491,36 +1491,7 @@ void ScriptEditor::_menu_option(int p_option) {
current->apply_code(); current->apply_code();
Error err = scr->reload(true); // Always hard reload the script before running. EditorNode::get_singleton()->run_editor_script(scr);
if (err != OK || !scr->is_valid()) {
EditorToaster::get_singleton()->popup_str(TTR("Cannot run the script because it contains errors, check the output log."), EditorToaster::SEVERITY_WARNING);
return;
}
// Perform additional checks on the script to evaluate if it's runnable.
bool is_runnable = true;
if (!ClassDB::is_parent_class(scr->get_instance_base_type(), "EditorScript")) {
is_runnable = false;
EditorToaster::get_singleton()->popup_str(TTR("Cannot run the script because it doesn't extend EditorScript."), EditorToaster::SEVERITY_WARNING);
}
if (!scr->is_tool()) {
is_runnable = false;
if (scr->get_class() == "GDScript") {
EditorToaster::get_singleton()->popup_str(TTR("Cannot run the script because it's not a tool script (add the @tool annotation at the top)."), EditorToaster::SEVERITY_WARNING);
} else {
EditorToaster::get_singleton()->popup_str(TTR("Cannot run the script because it's not a tool script."), EditorToaster::SEVERITY_WARNING);
}
}
if (!is_runnable) {
return;
}
Ref<EditorScript> es = memnew(EditorScript);
es->set_script(scr);
es->run();
} break; } break;
case FILE_MENU_CLOSE: { case FILE_MENU_CLOSE: {