summaryrefslogtreecommitdiff
path: root/editor
diff options
context:
space:
mode:
Diffstat (limited to 'editor')
-rw-r--r--editor/editor_node.cpp138
-rw-r--r--editor/editor_node.h17
-rw-r--r--editor/editor_plugin.cpp13
-rw-r--r--editor/editor_settings.cpp7
-rw-r--r--editor/plugins/spatial_editor_plugin.cpp14
-rw-r--r--editor/project_manager.cpp49
-rw-r--r--editor/project_settings_editor.cpp17
-rw-r--r--editor/scene_tree_dock.cpp66
8 files changed, 242 insertions, 79 deletions
diff --git a/editor/editor_node.cpp b/editor/editor_node.cpp
index e627263909..7936cf446f 100644
--- a/editor/editor_node.cpp
+++ b/editor/editor_node.cpp
@@ -190,6 +190,8 @@ void EditorNode::_unhandled_input(const Ref<InputEvent> &p_event) {
Ref<InputEventKey> k = p_event;
if (k.is_valid() && k->is_pressed() && !k->is_echo() && !gui_base->get_viewport()->gui_has_modal_stack()) {
+ EditorPlugin *old_editor = editor_plugin_screen;
+
if (ED_IS_SHORTCUT("editor/next_tab", p_event)) {
int next_tab = editor_data.get_edited_scene() + 1;
next_tab %= editor_data.get_edited_scene_count();
@@ -225,6 +227,10 @@ void EditorNode::_unhandled_input(const Ref<InputEvent> &p_event) {
_bottom_panel_switch(false, i);
}
}
+
+ if (old_editor != editor_plugin_screen) {
+ get_tree()->set_input_as_handled();
+ }
}
}
@@ -604,6 +610,7 @@ void EditorNode::open_resource(const String &p_type) {
void EditorNode::save_resource_in_path(const Ref<Resource> &p_resource, const String &p_path) {
editor_data.apply_changes_in_editors();
+
int flg = 0;
if (EditorSettings::get_singleton()->get("filesystem/on_save/compress_binary_resources"))
flg |= ResourceSaver::FLAG_COMPRESS;
@@ -1089,7 +1096,8 @@ void EditorNode::_save_scene(String p_file, int idx) {
void EditorNode::_save_all_scenes() {
- for (int i = 0; i < editor_data.get_edited_scene_count(); i++) {
+ int i = _next_unsaved_scene(true, 0);
+ while (i != -1) {
Node *scene = editor_data.get_edited_scene_root(i);
if (scene && scene->get_filename() != "") {
if (i != editor_data.get_edited_scene())
@@ -1097,6 +1105,7 @@ void EditorNode::_save_all_scenes() {
else
_save_scene_with_preview(scene->get_filename());
} // else: ignore new scenes
+ i = _next_unsaved_scene(true, ++i);
}
_save_default_environment();
@@ -1447,7 +1456,8 @@ void EditorNode::_save_default_environment() {
if (fallback.is_valid() && fallback->get_path().is_resource_file()) {
Map<RES, bool> processed;
_find_and_save_edited_subresources(fallback.ptr(), processed, 0);
- save_resource_in_path(fallback, fallback->get_path());
+ if (fallback->get_last_modified_time() != fallback->get_import_last_modified_time())
+ save_resource_in_path(fallback, fallback->get_path());
}
}
@@ -1593,7 +1603,8 @@ void EditorNode::_edit_current() {
// special case if use of external editor is true
if (main_plugin->get_name() == "Script" && (bool(EditorSettings::get_singleton()->get("text_editor/external/use_external_editor")) || overrides_external_editor(current_obj))) {
- main_plugin->edit(current_obj);
+ if (!changing_scene)
+ main_plugin->edit(current_obj);
}
else if (main_plugin != editor_plugin_screen && (!ScriptEditor::get_singleton() || !ScriptEditor::get_singleton()->is_visible_in_tree() || ScriptEditor::get_singleton()->can_take_away_focus())) {
@@ -2116,10 +2127,6 @@ void EditorNode::_menu_option_confirm(int p_option, bool p_confirmed) {
log->add_message("REDO: " + action);
} break;
- case TOOLS_ORPHAN_RESOURCES: {
-
- orphan_resources->show();
- } break;
case EDIT_REVERT: {
@@ -2565,6 +2572,30 @@ void EditorNode::_menu_option_confirm(int p_option, bool p_confirmed) {
}
}
+void EditorNode::_tool_menu_option(int p_idx) {
+ switch (tool_menu->get_item_id(p_idx)) {
+ case TOOLS_ORPHAN_RESOURCES: {
+ orphan_resources->show();
+ } break;
+ case TOOLS_CUSTOM: {
+ if (tool_menu->get_item_submenu(p_idx) == "") {
+ Array params = tool_menu->get_item_metadata(p_idx);
+
+ Object *handler = ObjectDB::get_instance(params[0]);
+ String callback = params[1];
+ Variant *ud = &params[2];
+ Variant::CallError ce;
+
+ handler->call(callback, (const Variant **)&ud, 1, ce);
+ if (ce.error != Variant::CallError::CALL_OK) {
+ String err = Variant::get_call_error_text(handler, callback, (const Variant **)&ud, 1, ce);
+ ERR_PRINTS("Error calling function from tool menu: " + err);
+ }
+ } // else it's a submenu so don't do anything.
+ } break;
+ }
+}
+
int EditorNode::_next_unsaved_scene(bool p_valid_filename, int p_start) {
for (int i = p_start; i < editor_data.get_edited_scene_count(); i++) {
@@ -4457,6 +4488,45 @@ Variant EditorNode::drag_files_and_dirs(const Vector<String> &p_paths, Control *
return drag_data;
}
+void EditorNode::add_tool_menu_item(const String &p_name, Object *p_handler, const String &p_callback, const Variant &p_ud) {
+ ERR_FAIL_NULL(p_handler);
+ int idx = tool_menu->get_item_count();
+ tool_menu->add_item(p_name, TOOLS_CUSTOM);
+
+ Array parameters;
+ parameters.push_back(p_handler->get_instance_id());
+ parameters.push_back(p_callback);
+ parameters.push_back(p_ud);
+
+ tool_menu->set_item_metadata(idx, parameters);
+}
+
+void EditorNode::add_tool_submenu_item(const String &p_name, PopupMenu *p_submenu) {
+ ERR_FAIL_NULL(p_submenu);
+ ERR_FAIL_COND(p_submenu->get_parent() != NULL);
+
+ tool_menu->add_child(p_submenu);
+ tool_menu->add_submenu_item(p_name, p_submenu->get_name(), TOOLS_CUSTOM);
+}
+
+void EditorNode::remove_tool_menu_item(const String &p_name) {
+ for (int i = 0; i < tool_menu->get_item_count(); i++) {
+ if (tool_menu->get_item_id(i) != TOOLS_CUSTOM)
+ continue;
+
+ if (tool_menu->get_item_text(i) == p_name) {
+ if (tool_menu->get_item_submenu(i) != "") {
+ Node *n = tool_menu->get_node(tool_menu->get_item_submenu(i));
+ tool_menu->remove_child(n);
+ memdelete(n);
+ }
+ tool_menu->remove_item(i);
+ tool_menu->set_as_minsize();
+ return;
+ }
+ }
+}
+
void EditorNode::_dropped_files(const Vector<String> &p_files, int p_screen) {
String to_path = ProjectSettings::get_singleton()->globalize_path(get_filesystem_dock()->get_current_path());
@@ -4653,6 +4723,7 @@ Vector<Ref<EditorResourceConversionPlugin> > EditorNode::find_resource_conversio
void EditorNode::_bind_methods() {
ClassDB::bind_method("_menu_option", &EditorNode::_menu_option);
+ ClassDB::bind_method("_tool_menu_option", &EditorNode::_tool_menu_option);
ClassDB::bind_method("_menu_confirm_current", &EditorNode::_menu_confirm_current);
ClassDB::bind_method("_dialog_action", &EditorNode::_dialog_action);
ClassDB::bind_method("_resource_selected", &EditorNode::_resource_selected, DEFVAL(""));
@@ -4791,18 +4862,43 @@ EditorNode::EditorNode() {
FileAccess::set_backup_save(EDITOR_GET("filesystem/on_save/safe_save_on_backup_then_rename"));
{
- int dpi_mode = EditorSettings::get_singleton()->get("interface/editor/hidpi_mode");
- if (dpi_mode == 0) {
- const int screen = OS::get_singleton()->get_current_screen();
- editor_set_scale(OS::get_singleton()->get_screen_dpi(screen) >= 192 && OS::get_singleton()->get_screen_size(screen).x > 2000 ? 2.0 : 1.0);
- } else if (dpi_mode == 1) {
- editor_set_scale(0.75);
- } else if (dpi_mode == 2) {
- editor_set_scale(1.0);
- } else if (dpi_mode == 3) {
- editor_set_scale(1.5);
- } else if (dpi_mode == 4) {
- editor_set_scale(2.0);
+ int display_scale = EditorSettings::get_singleton()->get("interface/editor/display_scale");
+ float custom_display_scale = EditorSettings::get_singleton()->get("interface/editor/custom_display_scale");
+
+ switch (display_scale) {
+ case 0: {
+ // Try applying a suitable display scale automatically
+ const int screen = OS::get_singleton()->get_current_screen();
+ editor_set_scale(OS::get_singleton()->get_screen_dpi(screen) >= 192 && OS::get_singleton()->get_screen_size(screen).x > 2000 ? 2.0 : 1.0);
+ } break;
+
+ case 1: {
+ editor_set_scale(0.75);
+ } break;
+
+ case 2: {
+ editor_set_scale(1.0);
+ } break;
+
+ case 3: {
+ editor_set_scale(1.25);
+ } break;
+
+ case 4: {
+ editor_set_scale(1.5);
+ } break;
+
+ case 5: {
+ editor_set_scale(1.75);
+ } break;
+
+ case 6: {
+ editor_set_scale(2.0);
+ } break;
+
+ default: {
+ editor_set_scale(custom_display_scale);
+ } break;
}
}
@@ -5226,9 +5322,9 @@ EditorNode::EditorNode() {
p->connect("id_pressed", this, "_menu_option");
p->add_item(TTR("Export"), FILE_EXPORT_PROJECT);
- PopupMenu *tool_menu = memnew(PopupMenu);
+ tool_menu = memnew(PopupMenu);
tool_menu->set_name("Tools");
- tool_menu->connect("id_pressed", this, "_menu_option");
+ tool_menu->connect("index_pressed", this, "_tool_menu_option");
p->add_child(tool_menu);
p->add_submenu_item(TTR("Tools"), "Tools");
tool_menu->add_item(TTR("Orphan Resource Explorer"), TOOLS_ORPHAN_RESOURCES);
diff --git a/editor/editor_node.h b/editor/editor_node.h
index 9090066dea..90bebffca6 100644
--- a/editor/editor_node.h
+++ b/editor/editor_node.h
@@ -141,6 +141,7 @@ private:
EDIT_REDO,
EDIT_REVERT,
TOOLS_ORPHAN_RESOURCES,
+ TOOLS_CUSTOM,
RESOURCE_NEW,
RESOURCE_LOAD,
RESOURCE_SAVE,
@@ -426,6 +427,7 @@ private:
void _menu_option(int p_option);
void _menu_confirm_current();
void _menu_option_confirm(int p_option, bool p_confirmed);
+ void _tool_menu_option(int p_idx);
void _update_debug_options();
void _property_editor_forward();
@@ -600,21 +602,6 @@ private:
static int build_callback_count;
static EditorBuildCallback build_callbacks[MAX_BUILD_CALLBACKS];
- bool _initializing_tool_menu;
-
- struct ToolMenuItem {
- String name;
- String submenu;
- Variant ud;
- ObjectID handler;
- String callback;
- };
-
- Vector<ToolMenuItem> tool_menu_items;
-
- void _tool_menu_insert_item(const ToolMenuItem &p_item);
- void _rebuild_tool_menu() const;
-
bool _dimming;
float _dim_time;
Timer *_dim_timer;
diff --git a/editor/editor_plugin.cpp b/editor/editor_plugin.cpp
index 31d0bfa8a9..4f38c0188d 100644
--- a/editor/editor_plugin.cpp
+++ b/editor/editor_plugin.cpp
@@ -429,21 +429,18 @@ void EditorPlugin::remove_control_from_container(CustomControlContainer p_locati
}
void EditorPlugin::add_tool_menu_item(const String &p_name, Object *p_handler, const String &p_callback, const Variant &p_ud) {
-
- //EditorNode::get_singleton()->add_tool_menu_item(p_name, p_handler, p_callback, p_ud);
+ EditorNode::get_singleton()->add_tool_menu_item(p_name, p_handler, p_callback, p_ud);
}
void EditorPlugin::add_tool_submenu_item(const String &p_name, Object *p_submenu) {
-
ERR_FAIL_NULL(p_submenu);
PopupMenu *submenu = Object::cast_to<PopupMenu>(p_submenu);
ERR_FAIL_NULL(submenu);
- //EditorNode::get_singleton()->add_tool_submenu_item(p_name, submenu);
+ EditorNode::get_singleton()->add_tool_submenu_item(p_name, submenu);
}
void EditorPlugin::remove_tool_menu_item(const String &p_name) {
-
- //EditorNode::get_singleton()->remove_tool_menu_item(p_name);
+ EditorNode::get_singleton()->remove_tool_menu_item(p_name);
}
void EditorPlugin::set_input_event_forwarding_always_enabled() {
@@ -707,9 +704,9 @@ void EditorPlugin::_bind_methods() {
ClassDB::bind_method(D_METHOD("remove_control_from_docks", "control"), &EditorPlugin::remove_control_from_docks);
ClassDB::bind_method(D_METHOD("remove_control_from_bottom_panel", "control"), &EditorPlugin::remove_control_from_bottom_panel);
ClassDB::bind_method(D_METHOD("remove_control_from_container", "container", "control"), &EditorPlugin::remove_control_from_container);
- //ClassDB::bind_method(D_METHOD("add_tool_menu_item", "name", "handler", "callback", "ud"),&EditorPlugin::add_tool_menu_item,DEFVAL(Variant()));
+ ClassDB::bind_method(D_METHOD("add_tool_menu_item", "name", "handler", "callback", "ud"), &EditorPlugin::add_tool_menu_item, DEFVAL(Variant()));
ClassDB::bind_method(D_METHOD("add_tool_submenu_item", "name", "submenu"), &EditorPlugin::add_tool_submenu_item);
- //ClassDB::bind_method(D_METHOD("remove_tool_menu_item", "name"),&EditorPlugin::remove_tool_menu_item);
+ ClassDB::bind_method(D_METHOD("remove_tool_menu_item", "name"), &EditorPlugin::remove_tool_menu_item);
ClassDB::bind_method(D_METHOD("add_custom_type", "type", "base", "script", "icon"), &EditorPlugin::add_custom_type);
ClassDB::bind_method(D_METHOD("remove_custom_type", "type"), &EditorPlugin::remove_custom_type);
diff --git a/editor/editor_settings.cpp b/editor/editor_settings.cpp
index 3a75673560..85f6d99c67 100644
--- a/editor/editor_settings.cpp
+++ b/editor/editor_settings.cpp
@@ -283,8 +283,10 @@ void EditorSettings::_load_defaults(Ref<ConfigFile> p_extra_config) {
hints["interface/editor/editor_language"] = PropertyInfo(Variant::STRING, "interface/editor/editor_language", PROPERTY_HINT_ENUM, lang_hint, PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_RESTART_IF_CHANGED);
}
- _initial_set("interface/editor/hidpi_mode", 0);
- hints["interface/editor/hidpi_mode"] = PropertyInfo(Variant::INT, "interface/editor/hidpi_mode", PROPERTY_HINT_ENUM, "Auto,VeryLoDPI,LoDPI,MidDPI,HiDPI", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_RESTART_IF_CHANGED);
+ _initial_set("interface/editor/display_scale", 0);
+ hints["interface/editor/display_scale"] = PropertyInfo(Variant::INT, "interface/editor/display_scale", PROPERTY_HINT_ENUM, "Auto,75%,100%,125%,150%,175%,200%,Custom", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_RESTART_IF_CHANGED);
+ _initial_set("interface/editor/custom_display_scale", 1.0f);
+ hints["interface/editor/custom_display_scale"] = PropertyInfo(Variant::REAL, "interface/editor/custom_display_scale", PROPERTY_HINT_RANGE, "0.75,3,0.01", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_RESTART_IF_CHANGED);
_initial_set("interface/scene_tabs/show_script_button", false);
_initial_set("interface/editor/main_font_size", 14);
hints["interface/editor/main_font_size"] = PropertyInfo(Variant::INT, "interface/editor/main_font_size", PROPERTY_HINT_RANGE, "10,40,1", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_RESTART_IF_CHANGED);
@@ -407,6 +409,7 @@ void EditorSettings::_load_defaults(Ref<ConfigFile> p_extra_config) {
// navigation
_initial_set("editors/3d/navigation/navigation_scheme", 0);
+ _initial_set("editors/3d/navigation/invert_y-axis", false);
hints["editors/3d/navigation/navigation_scheme"] = PropertyInfo(Variant::INT, "editors/3d/navigation/navigation_scheme", PROPERTY_HINT_ENUM, "Godot,Maya,Modo");
_initial_set("editors/3d/navigation/zoom_style", 0);
hints["editors/3d/navigation/zoom_style"] = PropertyInfo(Variant::INT, "editors/3d/navigation/zoom_style", PROPERTY_HINT_ENUM, "Vertical, Horizontal");
diff --git a/editor/plugins/spatial_editor_plugin.cpp b/editor/plugins/spatial_editor_plugin.cpp
index 9e7bfd5787..e484140527 100644
--- a/editor/plugins/spatial_editor_plugin.cpp
+++ b/editor/plugins/spatial_editor_plugin.cpp
@@ -1907,8 +1907,13 @@ void SpatialEditorViewport::_nav_orbit(Ref<InputEventWithModifiers> p_event, con
real_t degrees_per_pixel = EditorSettings::get_singleton()->get("editors/3d/navigation_feel/orbit_sensitivity");
real_t radians_per_pixel = Math::deg2rad(degrees_per_pixel);
+ bool invert_y_axis = EditorSettings::get_singleton()->get("editors/3d/navigation/invert_y-axis");
- cursor.x_rot += p_relative.y * radians_per_pixel;
+ if (invert_y_axis) {
+ cursor.x_rot -= p_relative.y * radians_per_pixel;
+ } else {
+ cursor.x_rot += p_relative.y * radians_per_pixel;
+ }
cursor.y_rot += p_relative.x * radians_per_pixel;
if (cursor.x_rot > Math_PI / 2.0)
cursor.x_rot = Math_PI / 2.0;
@@ -1925,11 +1930,16 @@ void SpatialEditorViewport::_nav_look(Ref<InputEventWithModifiers> p_event, cons
if (!orthogonal) {
real_t degrees_per_pixel = EditorSettings::get_singleton()->get("editors/3d/navigation_feel/orbit_sensitivity");
real_t radians_per_pixel = Math::deg2rad(degrees_per_pixel);
+ bool invert_y_axis = EditorSettings::get_singleton()->get("editors/3d/navigation/invert_y-axis");
// Note: do NOT assume the camera has the "current" transform, because it is interpolated and may have "lag".
Transform prev_camera_transform = to_camera_transform(cursor);
- cursor.x_rot += p_relative.y * radians_per_pixel;
+ if (invert_y_axis) {
+ cursor.x_rot -= p_relative.y * radians_per_pixel;
+ } else {
+ cursor.x_rot += p_relative.y * radians_per_pixel;
+ }
cursor.y_rot += p_relative.x * radians_per_pixel;
if (cursor.x_rot > Math_PI / 2.0)
cursor.x_rot = Math_PI / 2.0;
diff --git a/editor/project_manager.cpp b/editor/project_manager.cpp
index 5f93e984cc..de98c89db5 100644
--- a/editor/project_manager.cpp
+++ b/editor/project_manager.cpp
@@ -1517,18 +1517,43 @@ ProjectManager::ProjectManager() {
EditorSettings::get_singleton()->set_optimize_save(false); //just write settings as they came
{
- int dpi_mode = EditorSettings::get_singleton()->get("interface/editor/hidpi_mode");
- if (dpi_mode == 0) {
- const int screen = OS::get_singleton()->get_current_screen();
- editor_set_scale(OS::get_singleton()->get_screen_dpi(screen) >= 192 && OS::get_singleton()->get_screen_size(screen).x > 2000 ? 2.0 : 1.0);
- } else if (dpi_mode == 1) {
- editor_set_scale(0.75);
- } else if (dpi_mode == 2) {
- editor_set_scale(1.0);
- } else if (dpi_mode == 3) {
- editor_set_scale(1.5);
- } else if (dpi_mode == 4) {
- editor_set_scale(2.0);
+ int display_scale = EditorSettings::get_singleton()->get("interface/editor/display_scale");
+ float custom_display_scale = EditorSettings::get_singleton()->get("interface/editor/custom_display_scale");
+
+ switch (display_scale) {
+ case 0: {
+ // Try applying a suitable display scale automatically
+ const int screen = OS::get_singleton()->get_current_screen();
+ editor_set_scale(OS::get_singleton()->get_screen_dpi(screen) >= 192 && OS::get_singleton()->get_screen_size(screen).x > 2000 ? 2.0 : 1.0);
+ } break;
+
+ case 1: {
+ editor_set_scale(0.75);
+ } break;
+
+ case 2: {
+ editor_set_scale(1.0);
+ } break;
+
+ case 3: {
+ editor_set_scale(1.25);
+ } break;
+
+ case 4: {
+ editor_set_scale(1.5);
+ } break;
+
+ case 5: {
+ editor_set_scale(1.75);
+ } break;
+
+ case 6: {
+ editor_set_scale(2.0);
+ } break;
+
+ default: {
+ editor_set_scale(custom_display_scale);
+ } break;
}
}
diff --git a/editor/project_settings_editor.cpp b/editor/project_settings_editor.cpp
index 8080a04a67..75523cd843 100644
--- a/editor/project_settings_editor.cpp
+++ b/editor/project_settings_editor.cpp
@@ -123,6 +123,15 @@ void ProjectSettingsEditor::_notification(int p_what) {
}
}
+static bool _validate_action_name(const String &p_name) {
+ const CharType *cstr = p_name.c_str();
+ for (int i = 0; cstr[i]; i++)
+ if (cstr[i] == '/' || cstr[i] == ':' || cstr[i] == '"' ||
+ cstr[i] == '=' || cstr[i] == '\\' || cstr[i] < 32)
+ return false;
+ return true;
+}
+
void ProjectSettingsEditor::_action_selected() {
TreeItem *ti = input_editor->get_selected();
@@ -145,12 +154,12 @@ void ProjectSettingsEditor::_action_edited() {
if (new_name == old_name)
return;
- if (new_name.find("/") != -1 || new_name.find(":") != -1 || new_name.find("\"") != -1 || new_name == "") {
+ if (new_name == "" || !_validate_action_name(new_name)) {
ti->set_text(0, old_name);
add_at = "input/" + old_name;
- message->set_text(TTR("Invalid action (anything goes but '/', ':' or '\"')."));
+ message->set_text(TTR("Invalid action name. it cannot be empty nor contain '/', ':', '=', '\\' or '\"'"));
message->popup_centered(Size2(300, 100) * EDSCALE);
return;
}
@@ -838,9 +847,9 @@ void ProjectSettingsEditor::_action_check(String p_action) {
action_add->set_disabled(true);
} else {
- if (p_action.find("/") != -1 || p_action.find(":") != -1 || p_action.find("\"") != -1) {
+ if (!_validate_action_name(p_action)) {
- action_add_error->set_text(TTR("Can't contain '/', ':' or '\"'"));
+ action_add_error->set_text(TTR("Invalid action name. it cannot be empty nor contain '/', ':', '=', '\\' or '\"'"));
action_add_error->show();
action_add->set_disabled(true);
return;
diff --git a/editor/scene_tree_dock.cpp b/editor/scene_tree_dock.cpp
index 002d702bac..d5ec858c37 100644
--- a/editor/scene_tree_dock.cpp
+++ b/editor/scene_tree_dock.cpp
@@ -345,17 +345,30 @@ void SceneTreeDock::_tool_selected(int p_tool, bool p_confirm_override) {
} break;
case TOOL_CLEAR_SCRIPT: {
- Node *selected = scene_tree->get_selected();
- if (!selected)
- break;
- Ref<Script> existing = selected->get_script();
- if (existing.is_valid()) {
- const RefPtr empty;
- selected->set_script(empty);
- _update_script_button();
+ List<Node *> selection = editor_selection->get_selected_node_list();
+
+ if (selection.empty())
+ return;
+
+ editor_data->get_undo_redo().create_action(TTR("Clear Script"));
+ editor_data->get_undo_redo().add_do_method(editor, "push_item", (Script *)NULL);
+
+ for (List<Node *>::Element *E = selection.front(); E; E = E->next()) {
+
+ Ref<Script> existing = E->get()->get_script();
+ if (existing.is_valid()) {
+ const RefPtr empty;
+ editor_data->get_undo_redo().add_do_method(E->get(), "set_script", empty);
+ editor_data->get_undo_redo().add_undo_method(E->get(), "set_script", existing);
+ }
}
+ editor_data->get_undo_redo().add_do_method(this, "_update_script_button");
+ editor_data->get_undo_redo().add_undo_method(this, "_update_script_button");
+
+ editor_data->get_undo_redo().commit_action();
+
} break;
case TOOL_MOVE_UP:
case TOOL_MOVE_DOWN: {
@@ -1208,12 +1221,26 @@ void SceneTreeDock::_do_reparent(Node *p_new_parent, int p_position_in_parent, V
void SceneTreeDock::_script_created(Ref<Script> p_script) {
- Node *selected = scene_tree->get_selected();
- if (!selected)
+ List<Node *> selected = editor_selection->get_selected_node_list();
+
+ if (selected.empty())
return;
- selected->set_script(p_script.get_ref_ptr());
- editor->push_item(p_script.operator->());
- _update_script_button();
+
+ editor_data->get_undo_redo().create_action(TTR("Attach Script"));
+ for (List<Node *>::Element *E = selected.front(); E; E = E->next()) {
+
+ Ref<Script> existing = E->get()->get_script();
+ editor_data->get_undo_redo().add_do_method(E->get(), "set_script", p_script.get_ref_ptr());
+ editor_data->get_undo_redo().add_undo_method(E->get(), "set_script", existing);
+ }
+
+ editor_data->get_undo_redo().add_do_method(editor, "push_item", p_script.operator->());
+ editor_data->get_undo_redo().add_undo_method(editor, "push_item", (Script *)NULL);
+
+ editor_data->get_undo_redo().add_do_method(this, "_update_script_button");
+ editor_data->get_undo_redo().add_undo_method(this, "_update_script_button");
+
+ editor_data->get_undo_redo().commit_action();
}
void SceneTreeDock::_delete_confirm() {
@@ -1669,8 +1696,12 @@ void SceneTreeDock::_script_dropped(String p_file, NodePath p_to) {
ERR_FAIL_COND(!scr.is_valid());
Node *n = get_node(p_to);
if (n) {
- n->set_script(scr.get_ref_ptr());
- _update_script_button();
+ editor_data->get_undo_redo().create_action(TTR("Attach Script"));
+ editor_data->get_undo_redo().add_do_method(n, "set_script", scr);
+ editor_data->get_undo_redo().add_undo_method(n, "set_script", n->get_script());
+ editor_data->get_undo_redo().add_do_method(this, "_update_script_button");
+ editor_data->get_undo_redo().add_undo_method(this, "_update_script_button");
+ editor_data->get_undo_redo().commit_action();
}
}
@@ -1807,6 +1838,10 @@ void SceneTreeDock::_tree_rmb(const Vector2 &p_menu_pos) {
menu->set_item_checked(menu->get_item_idx_from_text(TTR("Load As Placeholder")), placeholder);
}
}
+ } else {
+ menu->add_separator();
+ menu->add_icon_shortcut(get_icon("ScriptCreate", "EditorIcons"), ED_GET_SHORTCUT("scene_tree/attach_script"), TOOL_ATTACH_SCRIPT);
+ menu->add_icon_shortcut(get_icon("ScriptRemove", "EditorIcons"), ED_GET_SHORTCUT("scene_tree/clear_script"), TOOL_CLEAR_SCRIPT);
}
menu->add_separator();
menu->add_icon_shortcut(get_icon("Remove", "EditorIcons"), ED_SHORTCUT("scene_tree/delete", TTR("Delete Node(s)"), KEY_DELETE), TOOL_ERASE);
@@ -1925,6 +1960,7 @@ void SceneTreeDock::_bind_methods() {
ClassDB::bind_method(D_METHOD("_focus_node"), &SceneTreeDock::_focus_node);
ClassDB::bind_method(D_METHOD("_remote_tree_selected"), &SceneTreeDock::_remote_tree_selected);
ClassDB::bind_method(D_METHOD("_local_tree_selected"), &SceneTreeDock::_local_tree_selected);
+ ClassDB::bind_method(D_METHOD("_update_script_button"), &SceneTreeDock::_update_script_button);
ClassDB::bind_method(D_METHOD("instance"), &SceneTreeDock::instance);