diff options
-rw-r--r-- | editor/gui/editor_run_bar.cpp | 6 | ||||
-rw-r--r-- | editor/gui/editor_run_bar.h | 4 | ||||
-rw-r--r-- | editor/gui/scene_tree_editor.cpp | 71 | ||||
-rw-r--r-- | modules/mono/csharp_script.cpp | 2 | ||||
-rw-r--r-- | modules/mono/editor/GodotTools/GodotTools/Build/MSBuildPanel.cs | 4 | ||||
-rw-r--r-- | modules/mono/editor/GodotTools/GodotTools/GodotSharpEditor.cs | 16 | ||||
-rw-r--r-- | modules/mono/editor/GodotTools/GodotTools/Internals/Globals.cs | 21 | ||||
-rw-r--r-- | modules/mono/editor/GodotTools/GodotTools/Internals/Internal.cs | 13 | ||||
-rw-r--r-- | modules/mono/editor/editor_internal_calls.cpp | 24 | ||||
-rw-r--r-- | modules/mono/icons/BuildCSharp.svg | 1 |
10 files changed, 112 insertions, 50 deletions
diff --git a/editor/gui/editor_run_bar.cpp b/editor/gui/editor_run_bar.cpp index c226c1a2d6..e144d1d10d 100644 --- a/editor/gui/editor_run_bar.cpp +++ b/editor/gui/editor_run_bar.cpp @@ -348,6 +348,10 @@ bool EditorRunBar::is_movie_maker_enabled() const { return write_movie_button->is_pressed(); } +HBoxContainer *EditorRunBar::get_buttons_container() { + return main_hbox; +} + void EditorRunBar::_bind_methods() { ADD_SIGNAL(MethodInfo("play_pressed")); ADD_SIGNAL(MethodInfo("stop_pressed")); @@ -359,7 +363,7 @@ EditorRunBar::EditorRunBar() { main_panel = memnew(PanelContainer); add_child(main_panel); - HBoxContainer *main_hbox = memnew(HBoxContainer); + main_hbox = memnew(HBoxContainer); main_panel->add_child(main_hbox); play_button = memnew(Button); diff --git a/editor/gui/editor_run_bar.h b/editor/gui/editor_run_bar.h index b7e7db2bd6..1cb999612a 100644 --- a/editor/gui/editor_run_bar.h +++ b/editor/gui/editor_run_bar.h @@ -39,6 +39,7 @@ class Button; class EditorRunNative; class EditorQuickOpen; class PanelContainer; +class HBoxContainer; class EditorRunBar : public MarginContainer { GDCLASS(EditorRunBar, MarginContainer); @@ -53,6 +54,7 @@ class EditorRunBar : public MarginContainer { }; PanelContainer *main_panel = nullptr; + HBoxContainer *main_hbox = nullptr; Button *play_button = nullptr; Button *pause_button = nullptr; @@ -109,6 +111,8 @@ public: Button *get_pause_button() { return pause_button; } + HBoxContainer *get_buttons_container(); + EditorRunBar(); }; diff --git a/editor/gui/scene_tree_editor.cpp b/editor/gui/scene_tree_editor.cpp index fbe167814d..f8b9313e0a 100644 --- a/editor/gui/scene_tree_editor.cpp +++ b/editor/gui/scene_tree_editor.cpp @@ -964,26 +964,55 @@ void SceneTreeEditor::_rename_node(Node *p_node, const String &p_name) { String new_name = p_name.validate_node_name(); if (new_name != p_name) { - error->set_text(TTR("Invalid node name, the following characters are not allowed:") + "\n" + String::get_invalid_node_name_characters()); - error->popup_centered(); - - if (new_name.is_empty()) { - item->set_text(0, p_node->get_name()); - return; + String text = TTR("Invalid node name, the following characters are not allowed:") + "\n" + String::get_invalid_node_name_characters(); + if (error->is_visible()) { + if (!error->get_meta("invalid_character", false)) { + error->set_text(error->get_text() + "\n\n" + text); + error->set_meta("invalid_character", true); + } + } else { + error->set_text(text); + error->set_meta("invalid_character", true); + error->set_meta("same_unique_name", false); + error->popup_centered(); } + } - item->set_text(0, new_name); + // Trim leading/trailing whitespace to prevent node names from containing accidental whitespace, which would make it more difficult to get the node via `get_node()`. + new_name = new_name.strip_edges(); + if (new_name.is_empty()) { + // If name is empty, fallback to class name. + if (GLOBAL_GET("editor/naming/node_name_casing").operator int() != NAME_CASING_PASCAL_CASE) { + new_name = Node::adjust_name_casing(p_node->get_class()); + } else { + new_name = p_node->get_class(); + } } if (new_name == p_node->get_name()) { if (item->get_text(0).is_empty()) { item->set_text(0, new_name); } + return; + } + // We previously made sure name is not the same as current name so that it won't complain about already used unique name when not changing name. + if (p_node->is_unique_name_in_owner() && get_tree()->get_edited_scene_root()->get_node_or_null("%" + new_name)) { + String text = TTR("Another node already uses this unique name in the scene."); + if (error->is_visible()) { + if (!error->get_meta("same_unique_name", false)) { + error->set_text(error->get_text() + "\n\n" + text); + error->set_meta("same_unique_name", true); + } + } else { + error->set_text(text); + error->set_meta("same_unique_name", true); + error->set_meta("invalid_character", false); + error->popup_centered(); + } + item->set_text(0, p_node->get_name()); return; } - // Trim leading/trailing whitespace to prevent node names from containing accidental whitespace, which would make it more difficult to get the node via `get_node()`. - new_name = new_name.strip_edges(); if (!is_scene_tree_dock) { p_node->set_name(new_name); @@ -999,7 +1028,7 @@ void SceneTreeEditor::_rename_node(Node *p_node, const String &p_name) { undo_redo->add_undo_method(item, "set_metadata", 0, p_node->get_path()); undo_redo->add_undo_method(item, "set_text", 0, p_node->get_name()); - p_node->set_name(p_name); + p_node->set_name(new_name); undo_redo->add_do_method(p_node, "set_name", new_name); undo_redo->add_do_method(item, "set_metadata", 0, p_node->get_path()); undo_redo->add_do_method(item, "set_text", 0, new_name); @@ -1017,28 +1046,6 @@ void SceneTreeEditor::_renamed() { ERR_FAIL_COND(!n); String new_name = which->get_text(0); - if (new_name.strip_edges().is_empty()) { - // If name is empty, fallback to class name. - if (GLOBAL_GET("editor/naming/node_name_casing").operator int() != NAME_CASING_PASCAL_CASE) { - new_name = Node::adjust_name_casing(n->get_class()); - } else { - new_name = n->get_class(); - } - } - - if (n->is_unique_name_in_owner()) { - Node *existing = get_tree()->get_edited_scene_root()->get_node_or_null("%" + new_name); - if (existing == n) { - which->set_text(0, n->get_name()); - return; - } - if (existing != nullptr) { - error->set_text(TTR("Another node already uses this unique name in the scene.")); - error->popup_centered(); - which->set_text(0, n->get_name()); - return; - } - } _rename_node(n, new_name); } diff --git a/modules/mono/csharp_script.cpp b/modules/mono/csharp_script.cpp index 1ed495943f..f592533a5a 100644 --- a/modules/mono/csharp_script.cpp +++ b/modules/mono/csharp_script.cpp @@ -1197,8 +1197,6 @@ void CSharpLanguage::_editor_init_callback() { // Add plugin to EditorNode and enable it EditorNode::add_editor_plugin(godotsharp_editor); - ED_SHORTCUT("mono/build_solution", TTR("Build Solution"), KeyModifierMask::ALT | Key::B); - ED_SHORTCUT_OVERRIDE("mono/build_solution", "macos", KeyModifierMask::META | KeyModifierMask::CTRL | Key::B); godotsharp_editor->enable_plugin(); get_singleton()->godotsharp_editor = godotsharp_editor; diff --git a/modules/mono/editor/GodotTools/GodotTools/Build/MSBuildPanel.cs b/modules/mono/editor/GodotTools/GodotTools/Build/MSBuildPanel.cs index 1bb1b3227e..cc11132a55 100644 --- a/modules/mono/editor/GodotTools/GodotTools/Build/MSBuildPanel.cs +++ b/modules/mono/editor/GodotTools/GodotTools/Build/MSBuildPanel.cs @@ -114,7 +114,7 @@ namespace GodotTools.Build var toolBarHBox = new HBoxContainer { SizeFlagsHorizontal = SizeFlags.ExpandFill }; AddChild(toolBarHBox); - _buildMenuBtn = new MenuButton { Text = "Build", Icon = GetThemeIcon("Play", "EditorIcons") }; + _buildMenuBtn = new MenuButton { Text = "Build", Icon = GetThemeIcon("BuildCSharp", "EditorIcons") }; toolBarHBox.AddChild(_buildMenuBtn); var buildMenu = _buildMenuBtn.GetPopup(); @@ -184,7 +184,7 @@ namespace GodotTools.Build if (what == NotificationThemeChanged) { if (_buildMenuBtn != null) - _buildMenuBtn.Icon = GetThemeIcon("Play", "EditorIcons"); + _buildMenuBtn.Icon = GetThemeIcon("BuildCSharp", "EditorIcons"); if (_errorsBtn != null) _errorsBtn.Icon = GetThemeIcon("StatusError", "EditorIcons"); if (_warningsBtn != null) diff --git a/modules/mono/editor/GodotTools/GodotTools/GodotSharpEditor.cs b/modules/mono/editor/GodotTools/GodotTools/GodotSharpEditor.cs index 622a155d37..cdf0a344d4 100644 --- a/modules/mono/editor/GodotTools/GodotTools/GodotSharpEditor.cs +++ b/modules/mono/editor/GodotTools/GodotTools/GodotSharpEditor.cs @@ -497,18 +497,20 @@ namespace GodotTools AddToolSubmenuItem("C#", _menuPopup); - var buildSolutionShortcut = (Shortcut)EditorShortcut("mono/build_solution"); - _toolBarBuildButton = new Button { - Text = "Build", - TooltipText = "Build Solution".TTR(), + Flat = true, + Icon = editorBaseControl.GetThemeIcon("BuildCSharp", "EditorIcons"), FocusMode = Control.FocusModeEnum.None, - Shortcut = buildSolutionShortcut, - ShortcutInTooltip = true + Shortcut = EditorDefShortcut("mono/build_solution", "Build Project".TTR(), (Key)KeyModifierMask.MaskAlt | Key.B), + ShortcutInTooltip = true, }; + EditorShortcutOverride("mono/build_solution", "macos", (Key)KeyModifierMask.MaskMeta | (Key)KeyModifierMask.MaskCtrl | Key.B); + _toolBarBuildButton.Pressed += BuildProjectPressed; - AddControlToContainer(CustomControlContainer.Toolbar, _toolBarBuildButton); + Internal.EditorPlugin_AddControlToEditorRunBar(_toolBarBuildButton); + // Move Build button so it appears to the left of the Play button. + _toolBarBuildButton.GetParent().MoveChild(_toolBarBuildButton, 0); if (File.Exists(GodotSharpDirs.ProjectCsProjPath)) { diff --git a/modules/mono/editor/GodotTools/GodotTools/Internals/Globals.cs b/modules/mono/editor/GodotTools/GodotTools/Internals/Globals.cs index 45ae7eb86b..a6718e8fd5 100644 --- a/modules/mono/editor/GodotTools/GodotTools/Internals/Globals.cs +++ b/modules/mono/editor/GodotTools/GodotTools/Internals/Globals.cs @@ -29,11 +29,26 @@ namespace GodotTools.Internals return Variant.CreateTakingOwnershipOfDisposableValue(result); } - public static Variant EditorShortcut(string setting) + public static Shortcut EditorDefShortcut(string setting, string name, Key keycode = Key.None, bool physical = false) { using godot_string settingIn = Marshaling.ConvertStringToNative(setting); - Internal.godot_icall_Globals_EditorShortcut(settingIn, out godot_variant result); - return Variant.CreateTakingOwnershipOfDisposableValue(result); + using godot_string nameIn = Marshaling.ConvertStringToNative(name); + Internal.godot_icall_Globals_EditorDefShortcut(settingIn, nameIn, keycode, physical.ToGodotBool(), out godot_variant result); + return (Shortcut)Variant.CreateTakingOwnershipOfDisposableValue(result); + } + + public static Shortcut EditorGetShortcut(string setting) + { + using godot_string settingIn = Marshaling.ConvertStringToNative(setting); + Internal.godot_icall_Globals_EditorGetShortcut(settingIn, out godot_variant result); + return (Shortcut)Variant.CreateTakingOwnershipOfDisposableValue(result); + } + + public static void EditorShortcutOverride(string setting, string feature, Key keycode = Key.None, bool physical = false) + { + using godot_string settingIn = Marshaling.ConvertStringToNative(setting); + using godot_string featureIn = Marshaling.ConvertStringToNative(feature); + Internal.godot_icall_Globals_EditorShortcutOverride(settingIn, featureIn, keycode, physical.ToGodotBool()); } [SuppressMessage("ReSharper", "InconsistentNaming")] diff --git a/modules/mono/editor/GodotTools/GodotTools/Internals/Internal.cs b/modules/mono/editor/GodotTools/GodotTools/Internals/Internal.cs index 3ea11750b7..90c443ebb8 100644 --- a/modules/mono/editor/GodotTools/GodotTools/Internals/Internal.cs +++ b/modules/mono/editor/GodotTools/GodotTools/Internals/Internal.cs @@ -54,6 +54,9 @@ namespace GodotTools.Internals public static void EditorRunStop() => godot_icall_Internal_EditorRunStop(); + public static void EditorPlugin_AddControlToEditorRunBar(Control control) => + godot_icall_Internal_EditorPlugin_AddControlToEditorRunBar(control.NativeInstance); + public static void ScriptEditorDebugger_ReloadScripts() => godot_icall_Internal_ScriptEditorDebugger_ReloadScripts(); @@ -137,6 +140,8 @@ namespace GodotTools.Internals private static partial void godot_icall_Internal_EditorRunStop(); + private static partial void godot_icall_Internal_EditorPlugin_AddControlToEditorRunBar(IntPtr p_control); + private static partial void godot_icall_Internal_ScriptEditorDebugger_ReloadScripts(); private static partial void godot_icall_Internal_CodeCompletionRequest(int kind, in godot_string scriptFile, @@ -151,7 +156,13 @@ namespace GodotTools.Internals bool restartIfChanged, out godot_variant result); public static partial void - godot_icall_Globals_EditorShortcut(in godot_string setting, out godot_variant result); + godot_icall_Globals_EditorDefShortcut(in godot_string setting, in godot_string name, Key keycode, godot_bool physical, out godot_variant result); + + public static partial void + godot_icall_Globals_EditorGetShortcut(in godot_string setting, out godot_variant result); + + public static partial void + godot_icall_Globals_EditorShortcutOverride(in godot_string setting, in godot_string feature, Key keycode, godot_bool physical); public static partial void godot_icall_Globals_TTR(in godot_string text, out godot_string dest); diff --git a/modules/mono/editor/editor_internal_calls.cpp b/modules/mono/editor/editor_internal_calls.cpp index ba6b91b704..fc99f3ceda 100644 --- a/modules/mono/editor/editor_internal_calls.cpp +++ b/modules/mono/editor/editor_internal_calls.cpp @@ -168,6 +168,10 @@ void godot_icall_Internal_EditorRunStop() { EditorRunBar::get_singleton()->stop_playing(); } +void godot_icall_Internal_EditorPlugin_AddControlToEditorRunBar(Control *p_control) { + EditorRunBar::get_singleton()->get_buttons_container()->add_child(p_control); +} + void godot_icall_Internal_ScriptEditorDebugger_ReloadScripts() { EditorDebuggerNode *ed = EditorDebuggerNode::get_singleton(); if (ed) { @@ -199,12 +203,25 @@ void godot_icall_Globals_EditorDef(const godot_string *p_setting, const godot_va memnew_placement(r_result, Variant(result)); } -void godot_icall_Globals_EditorShortcut(const godot_string *p_setting, godot_variant *r_result) { +void godot_icall_Globals_EditorDefShortcut(const godot_string *p_setting, const godot_string *p_name, Key p_keycode, bool p_physical, godot_variant *r_result) { + String setting = *reinterpret_cast<const String *>(p_setting); + String name = *reinterpret_cast<const String *>(p_name); + Ref<Shortcut> result = ED_SHORTCUT(setting, name, p_keycode, p_physical); + memnew_placement(r_result, Variant(result)); +} + +void godot_icall_Globals_EditorGetShortcut(const godot_string *p_setting, Ref<Shortcut> *r_result) { String setting = *reinterpret_cast<const String *>(p_setting); Ref<Shortcut> result = ED_GET_SHORTCUT(setting); memnew_placement(r_result, Variant(result)); } +void godot_icall_Globals_EditorShortcutOverride(const godot_string *p_setting, const godot_string *p_feature, Key p_keycode, bool p_physical) { + String setting = *reinterpret_cast<const String *>(p_setting); + String feature = *reinterpret_cast<const String *>(p_feature); + ED_SHORTCUT_OVERRIDE(setting, feature, p_keycode, p_physical); +} + void godot_icall_Globals_TTR(const godot_string *p_text, godot_string *r_dest) { String text = *reinterpret_cast<const String *>(p_text); memnew_placement(r_dest, String(TTR(text))); @@ -251,12 +268,15 @@ static const void *unmanaged_callbacks[]{ (void *)godot_icall_Internal_EditorNodeShowScriptScreen, (void *)godot_icall_Internal_EditorRunPlay, (void *)godot_icall_Internal_EditorRunStop, + (void *)godot_icall_Internal_EditorPlugin_AddControlToEditorRunBar, (void *)godot_icall_Internal_ScriptEditorDebugger_ReloadScripts, (void *)godot_icall_Internal_CodeCompletionRequest, (void *)godot_icall_Globals_EditorScale, (void *)godot_icall_Globals_GlobalDef, (void *)godot_icall_Globals_EditorDef, - (void *)godot_icall_Globals_EditorShortcut, + (void *)godot_icall_Globals_EditorDefShortcut, + (void *)godot_icall_Globals_EditorGetShortcut, + (void *)godot_icall_Globals_EditorShortcutOverride, (void *)godot_icall_Globals_TTR, (void *)godot_icall_Utils_OS_GetPlatformName, (void *)godot_icall_Utils_OS_UnixFileHasExecutableAccess, diff --git a/modules/mono/icons/BuildCSharp.svg b/modules/mono/icons/BuildCSharp.svg new file mode 100644 index 0000000000..9d0102c35d --- /dev/null +++ b/modules/mono/icons/BuildCSharp.svg @@ -0,0 +1 @@ +<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="M 9.6060193,0.78346667 C 8.6741914,0.96303367 7.6708299,1.5334576 6.9028943,1.9768256 l -2.1523438,1.244141 0.082031,0.138672 -0.3105469,-0.00781 -2.5839844,1.492188 1.9101563,3.308593 2.5820312,-1.490234 0.1425781,-0.255859 4.1875002,7.2539054 0.5,0.867187 c 0.415803,0.720194 1.331398,0.964165 2.050782,0.548829 0.719286,-0.415279 0.963839,-1.33001 0.548828,-2.048829 l -2,-3.4648424 -2.8808602,-4.990235 3.7070322,-2.101562 -0.265626,-0.439453 C 11.697382,0.83561667 10.650124,0.58226267 9.6060193,0.78346667 Z" fill="#e0e0e0"/></svg> |