summaryrefslogtreecommitdiff
path: root/editor
diff options
context:
space:
mode:
Diffstat (limited to 'editor')
-rw-r--r--editor/action_map_editor.cpp80
-rw-r--r--editor/action_map_editor.h14
-rw-r--r--editor/animation_bezier_editor.cpp8
-rw-r--r--editor/animation_track_editor.cpp14
-rw-r--r--editor/code_editor.cpp8
-rw-r--r--editor/create_dialog.cpp14
-rw-r--r--editor/create_dialog.h2
-rw-r--r--editor/editor_audio_buses.cpp2
-rw-r--r--editor/editor_data.cpp26
-rw-r--r--editor/editor_data.h3
-rw-r--r--editor/editor_file_dialog.cpp32
-rw-r--r--editor/editor_inspector.cpp16
-rw-r--r--editor/editor_log.cpp6
-rw-r--r--editor/editor_node.cpp116
-rw-r--r--editor/editor_settings.cpp7
-rw-r--r--editor/editor_settings_dialog.cpp2
-rw-r--r--editor/editor_spin_slider.cpp2
-rw-r--r--editor/editor_themes.cpp63
-rw-r--r--editor/editor_toaster.cpp5
-rw-r--r--editor/editor_zoom_widget.cpp4
-rw-r--r--editor/export/export_template_manager.cpp6
-rw-r--r--editor/filesystem_dock.cpp6
-rw-r--r--editor/plugins/animation_library_editor.cpp16
-rw-r--r--editor/plugins/animation_player_editor_plugin.cpp83
-rw-r--r--editor/plugins/asset_library_editor_plugin.cpp18
-rw-r--r--editor/plugins/canvas_item_editor_plugin.cpp28
-rw-r--r--editor/plugins/material_editor_plugin.cpp46
-rw-r--r--editor/plugins/material_editor_plugin.h6
-rw-r--r--editor/plugins/node_3d_editor_plugin.cpp36
-rw-r--r--editor/plugins/path_2d_editor_plugin.cpp4
-rw-r--r--editor/plugins/path_3d_editor_plugin.cpp2
-rw-r--r--editor/plugins/polygon_2d_editor_plugin.cpp4
-rw-r--r--editor/plugins/script_editor_plugin.cpp28
-rw-r--r--editor/plugins/script_text_editor.cpp52
-rw-r--r--editor/plugins/skeleton_3d_editor_plugin.cpp2
-rw-r--r--editor/plugins/tiles/tile_data_editors.cpp13
-rw-r--r--editor/plugins/tiles/tile_map_editor.cpp8
-rw-r--r--editor/plugins/version_control_editor_plugin.cpp2
-rw-r--r--editor/progress_dialog.cpp4
-rw-r--r--editor/project_converter_3_to_4.cpp740
-rw-r--r--editor/project_converter_3_to_4.h2
-rw-r--r--editor/project_manager.cpp14
-rw-r--r--editor/project_settings_editor.cpp2
-rw-r--r--editor/scene_tree_dock.cpp18
-rw-r--r--editor/script_create_dialog.cpp12
45 files changed, 770 insertions, 806 deletions
diff --git a/editor/action_map_editor.cpp b/editor/action_map_editor.cpp
index 7cfedffcbf..b6348c5952 100644
--- a/editor/action_map_editor.cpp
+++ b/editor/action_map_editor.cpp
@@ -66,6 +66,14 @@ String InputEventConfigurationDialog::get_event_text(const Ref<InputEvent> &p_ev
String text = p_event->as_text();
+ Ref<InputEventKey> key = p_event;
+ if (key.is_valid() && key->is_command_or_control_autoremap()) {
+#ifdef MACOS_ENABLED
+ text = text.replace("Command", "Command/Ctrl");
+#else
+ text = text.replace("Ctrl", "Command/Ctrl");
+#endif
+ }
Ref<InputEventMouse> mouse = p_event;
Ref<InputEventJoypadMotion> jp_motion = p_event;
Ref<InputEventJoypadButton> jp_button = p_event;
@@ -108,11 +116,10 @@ void InputEventConfigurationDialog::_set_event(const Ref<InputEvent> &p_event, b
show_mods = true;
mod_checkboxes[MOD_ALT]->set_pressed(mod->is_alt_pressed());
mod_checkboxes[MOD_SHIFT]->set_pressed(mod->is_shift_pressed());
- mod_checkboxes[MOD_COMMAND]->set_pressed(mod->is_command_pressed());
mod_checkboxes[MOD_CTRL]->set_pressed(mod->is_ctrl_pressed());
mod_checkboxes[MOD_META]->set_pressed(mod->is_meta_pressed());
- store_command_checkbox->set_pressed(mod->is_storing_command());
+ autoremap_command_or_control_checkbox->set_pressed(mod->is_command_or_control_autoremap());
}
if (k.is_valid()) {
@@ -287,8 +294,6 @@ void InputEventConfigurationDialog::_listen_window_input(const Ref<InputEvent> &
Ref<InputEventWithModifiers> mod = received_event;
if (mod.is_valid()) {
- // Maintain store command option state
- mod->set_store_command(store_command_checkbox->is_pressed());
mod->set_window_id(0);
}
@@ -419,41 +424,31 @@ void InputEventConfigurationDialog::_mod_toggled(bool p_checked, int p_index) {
} else if (p_index == 1) {
ie->set_shift_pressed(p_checked);
} else if (p_index == 2) {
- ie->set_command_pressed(p_checked);
+ if (!autoremap_command_or_control_checkbox->is_pressed()) {
+ ie->set_ctrl_pressed(p_checked);
+ }
} else if (p_index == 3) {
- ie->set_ctrl_pressed(p_checked);
- } else if (p_index == 4) {
- ie->set_meta_pressed(p_checked);
+ if (!autoremap_command_or_control_checkbox->is_pressed()) {
+ ie->set_meta_pressed(p_checked);
+ }
}
_set_event(ie);
}
-void InputEventConfigurationDialog::_store_command_toggled(bool p_checked) {
+void InputEventConfigurationDialog::_autoremap_command_or_control_toggled(bool p_checked) {
Ref<InputEventWithModifiers> ie = event;
if (ie.is_valid()) {
- ie->set_store_command(p_checked);
+ ie->set_command_or_control_autoremap(p_checked);
_set_event(ie);
}
if (p_checked) {
- // If storing Command, show it's checkbox and hide Control (Win/Lin) or Meta (Mac)
-#ifdef APPLE_STYLE_KEYS
mod_checkboxes[MOD_META]->hide();
-
- mod_checkboxes[MOD_COMMAND]->show();
- mod_checkboxes[MOD_COMMAND]->set_text("Meta (Command)");
-#else
mod_checkboxes[MOD_CTRL]->hide();
-
- mod_checkboxes[MOD_COMMAND]->show();
- mod_checkboxes[MOD_COMMAND]->set_text("Control (Command)");
-#endif
} else {
- // If not, hide Command, show Control and Meta.
- mod_checkboxes[MOD_COMMAND]->hide();
- mod_checkboxes[MOD_CTRL]->show();
mod_checkboxes[MOD_META]->show();
+ mod_checkboxes[MOD_CTRL]->show();
}
}
@@ -502,10 +497,12 @@ void InputEventConfigurationDialog::_input_list_item_selected() {
// Maintain modifier state from checkboxes
k->set_alt_pressed(mod_checkboxes[MOD_ALT]->is_pressed());
k->set_shift_pressed(mod_checkboxes[MOD_SHIFT]->is_pressed());
- k->set_command_pressed(mod_checkboxes[MOD_COMMAND]->is_pressed());
- k->set_ctrl_pressed(mod_checkboxes[MOD_CTRL]->is_pressed());
- k->set_meta_pressed(mod_checkboxes[MOD_META]->is_pressed());
- k->set_store_command(store_command_checkbox->is_pressed());
+ if (autoremap_command_or_control_checkbox->is_pressed()) {
+ k->set_command_or_control_autoremap(true);
+ } else {
+ k->set_ctrl_pressed(mod_checkboxes[MOD_CTRL]->is_pressed());
+ k->set_meta_pressed(mod_checkboxes[MOD_META]->is_pressed());
+ }
_set_event(k, false);
} break;
@@ -517,10 +514,12 @@ void InputEventConfigurationDialog::_input_list_item_selected() {
// Maintain modifier state from checkboxes
mb->set_alt_pressed(mod_checkboxes[MOD_ALT]->is_pressed());
mb->set_shift_pressed(mod_checkboxes[MOD_SHIFT]->is_pressed());
- mb->set_command_pressed(mod_checkboxes[MOD_COMMAND]->is_pressed());
- mb->set_ctrl_pressed(mod_checkboxes[MOD_CTRL]->is_pressed());
- mb->set_meta_pressed(mod_checkboxes[MOD_META]->is_pressed());
- mb->set_store_command(store_command_checkbox->is_pressed());
+ if (autoremap_command_or_control_checkbox->is_pressed()) {
+ mb->set_command_or_control_autoremap(true);
+ } else {
+ mb->set_ctrl_pressed(mod_checkboxes[MOD_CTRL]->is_pressed());
+ mb->set_meta_pressed(mod_checkboxes[MOD_META]->is_pressed());
+ }
// Maintain selected device
mb->set_device(_get_current_device());
@@ -611,7 +610,7 @@ void InputEventConfigurationDialog::popup_and_configure(const Ref<InputEvent> &p
// This is especially important for WASD movement layouts.
physical_key_checkbox->set_pressed(true);
- store_command_checkbox->set_pressed(true);
+ autoremap_command_or_control_checkbox->set_pressed(false);
_set_current_device(0);
// Switch to "Listen" tab
@@ -722,21 +721,18 @@ InputEventConfigurationDialog::InputEventConfigurationDialog() {
mod_checkboxes[i] = memnew(CheckBox);
mod_checkboxes[i]->connect("toggled", callable_mp(this, &InputEventConfigurationDialog::_mod_toggled).bind(i));
mod_checkboxes[i]->set_text(name);
+ mod_checkboxes[i]->set_tooltip_text(TTR(mods_tip[i]));
mod_container->add_child(mod_checkboxes[i]);
}
mod_container->add_child(memnew(VSeparator));
- store_command_checkbox = memnew(CheckBox);
- store_command_checkbox->connect("toggled", callable_mp(this, &InputEventConfigurationDialog::_store_command_toggled));
- store_command_checkbox->set_pressed(true);
- store_command_checkbox->set_text(TTR("Store Command"));
-#ifdef APPLE_STYLE_KEYS
- store_command_checkbox->set_tooltip_text(TTR("Toggles between serializing 'command' and 'meta'. Used for compatibility with Windows/Linux style keyboard."));
-#else
- store_command_checkbox->set_tooltip_text(TTR("Toggles between serializing 'command' and 'control'. Used for compatibility with Apple Style keyboards."));
-#endif
- mod_container->add_child(store_command_checkbox);
+ autoremap_command_or_control_checkbox = memnew(CheckBox);
+ autoremap_command_or_control_checkbox->connect("toggled", callable_mp(this, &InputEventConfigurationDialog::_autoremap_command_or_control_toggled));
+ autoremap_command_or_control_checkbox->set_pressed(false);
+ autoremap_command_or_control_checkbox->set_text(TTR("Command / Control (auto)"));
+ autoremap_command_or_control_checkbox->set_tooltip_text(TTR("Automatically remaps between 'Meta' ('Command') and 'Control' depending on current platform."));
+ mod_container->add_child(autoremap_command_or_control_checkbox);
mod_container->hide();
additional_options_container->add_child(mod_container);
diff --git a/editor/action_map_editor.h b/editor/action_map_editor.h
index 1ca3c5bac0..36d21fe258 100644
--- a/editor/action_map_editor.h
+++ b/editor/action_map_editor.h
@@ -85,15 +85,21 @@ private:
enum ModCheckbox {
MOD_ALT,
MOD_SHIFT,
- MOD_COMMAND,
MOD_CTRL,
MOD_META,
MOD_MAX
};
- String mods[MOD_MAX] = { "Alt", "Shift", "Command", "Ctrl", "Metakey" };
+#if defined(MACOS_ENABLED)
+ String mods[MOD_MAX] = { "Option", "Shift", "Ctrl", "Command" };
+#elif defined(WINDOWS_ENABLED)
+ String mods[MOD_MAX] = { "Alt", "Shift", "Ctrl", "Windows" };
+#else
+ String mods[MOD_MAX] = { "Alt", "Shift", "Ctrl", "Meta" };
+#endif
+ String mods_tip[MOD_MAX] = { "Alt or Option key", "Shift key", "Control key", "Meta/Windows or Command key" };
CheckBox *mod_checkboxes[MOD_MAX];
- CheckBox *store_command_checkbox = nullptr;
+ CheckBox *autoremap_command_or_control_checkbox = nullptr;
CheckBox *physical_key_checkbox = nullptr;
@@ -107,7 +113,7 @@ private:
void _input_list_item_selected();
void _mod_toggled(bool p_checked, int p_index);
- void _store_command_toggled(bool p_checked);
+ void _autoremap_command_or_control_toggled(bool p_checked);
void _physical_keycode_toggled(bool p_checked);
void _device_selection_changed(int p_option_button_index);
diff --git a/editor/animation_bezier_editor.cpp b/editor/animation_bezier_editor.cpp
index 0183d08733..219f3fdbe1 100644
--- a/editor/animation_bezier_editor.cpp
+++ b/editor/animation_bezier_editor.cpp
@@ -1088,7 +1088,7 @@ void AnimationBezierTrackEdit::gui_input(const Ref<InputEvent> &p_event) {
//first check point
//command makes it ignore the main point, so control point editors can be force-edited
//path 2D editing in the 3D and 2D editors works the same way
- if (!mb->is_command_pressed()) {
+ if (!mb->is_command_or_control_pressed()) {
if (edit_points[i].point_rect.has_point(mb->get_position())) {
IntPair pair = IntPair(edit_points[i].track, edit_points[i].key);
if (mb->is_shift_pressed()) {
@@ -1152,7 +1152,7 @@ void AnimationBezierTrackEdit::gui_input(const Ref<InputEvent> &p_event) {
}
//insert new point
- if (mb->get_position().x >= limit && mb->get_position().x < get_size().width && mb->is_command_pressed()) {
+ if (mb->get_position().x >= limit && mb->get_position().x < get_size().width && mb->is_command_or_control_pressed()) {
Array new_point;
new_point.resize(5);
@@ -1684,8 +1684,8 @@ AnimationBezierTrackEdit::AnimationBezierTrackEdit() {
set_clip_contents(true);
ED_SHORTCUT("animation_bezier_editor/focus", TTR("Focus"), Key::F);
- ED_SHORTCUT("animation_bezier_editor/select_all_keys", TTR("Select All Keys"), KeyModifierMask::CMD | Key::A);
- ED_SHORTCUT("animation_bezier_editor/deselect_all_keys", TTR("Deselect All Keys"), KeyModifierMask::CMD | KeyModifierMask::SHIFT | Key::A);
+ ED_SHORTCUT("animation_bezier_editor/select_all_keys", TTR("Select All Keys"), KeyModifierMask::CMD_OR_CTRL | Key::A);
+ ED_SHORTCUT("animation_bezier_editor/deselect_all_keys", TTR("Deselect All Keys"), KeyModifierMask::CMD_OR_CTRL | KeyModifierMask::SHIFT | Key::A);
menu = memnew(PopupMenu);
add_child(menu);
diff --git a/editor/animation_track_editor.cpp b/editor/animation_track_editor.cpp
index e3b1288e9f..70b5501692 100644
--- a/editor/animation_track_editor.cpp
+++ b/editor/animation_track_editor.cpp
@@ -2930,7 +2930,7 @@ void AnimationTrackEdit::gui_input(const Ref<InputEvent> &p_event) {
}
if (key_idx != -1) {
- if (mb->is_command_pressed() || mb->is_shift_pressed()) {
+ if (mb->is_command_or_control_pressed() || mb->is_shift_pressed()) {
if (editor->is_key_selected(track, key_idx)) {
emit_signal(SNAME("deselect_key"), key_idx);
} else {
@@ -5468,7 +5468,7 @@ void AnimationTrackEditor::_scroll_input(const Ref<InputEvent> &p_event) {
for (int i = 0; i < track_edits.size(); i++) {
Rect2 local_rect = box_select_rect;
local_rect.position -= track_edits[i]->get_global_position();
- track_edits[i]->append_to_selection(local_rect, mb->is_command_pressed());
+ track_edits[i]->append_to_selection(local_rect, mb->is_command_or_control_pressed());
}
if (_get_track_selected() == -1 && track_edits.size() > 0) { // Minimal hack to make shortcuts work.
@@ -5494,7 +5494,7 @@ void AnimationTrackEditor::_scroll_input(const Ref<InputEvent> &p_event) {
}
if (!box_selection->is_visible_in_tree()) {
- if (!mm->is_command_pressed() && !mm->is_shift_pressed()) {
+ if (!mm->is_command_or_control_pressed() && !mm->is_shift_pressed()) {
_clear_selection(true);
}
box_selection->show();
@@ -6708,15 +6708,15 @@ AnimationTrackEditor::AnimationTrackEditor() {
edit->get_popup()->add_separator();
edit->get_popup()->add_item(TTR("Make Easing Selection"), EDIT_EASE_SELECTION);
edit->get_popup()->add_separator();
- edit->get_popup()->add_shortcut(ED_SHORTCUT("animation_editor/duplicate_selection", TTR("Duplicate Selection"), KeyModifierMask::CMD | Key::D), EDIT_DUPLICATE_SELECTION);
- edit->get_popup()->add_shortcut(ED_SHORTCUT("animation_editor/duplicate_selection_transposed", TTR("Duplicate Transposed"), KeyModifierMask::SHIFT | KeyModifierMask::CMD | Key::D), EDIT_DUPLICATE_TRANSPOSED);
+ edit->get_popup()->add_shortcut(ED_SHORTCUT("animation_editor/duplicate_selection", TTR("Duplicate Selection"), KeyModifierMask::CMD_OR_CTRL | Key::D), EDIT_DUPLICATE_SELECTION);
+ edit->get_popup()->add_shortcut(ED_SHORTCUT("animation_editor/duplicate_selection_transposed", TTR("Duplicate Transposed"), KeyModifierMask::SHIFT | KeyModifierMask::CMD_OR_CTRL | Key::D), EDIT_DUPLICATE_TRANSPOSED);
edit->get_popup()->add_shortcut(ED_SHORTCUT("animation_editor/add_reset_value", TTR("Add RESET Value(s)")));
edit->get_popup()->add_separator();
edit->get_popup()->add_shortcut(ED_SHORTCUT("animation_editor/delete_selection", TTR("Delete Selection"), Key::KEY_DELETE), EDIT_DELETE_SELECTION);
edit->get_popup()->add_separator();
- edit->get_popup()->add_shortcut(ED_SHORTCUT("animation_editor/goto_next_step", TTR("Go to Next Step"), KeyModifierMask::CMD | Key::RIGHT), EDIT_GOTO_NEXT_STEP);
- edit->get_popup()->add_shortcut(ED_SHORTCUT("animation_editor/goto_prev_step", TTR("Go to Previous Step"), KeyModifierMask::CMD | Key::LEFT), EDIT_GOTO_PREV_STEP);
+ edit->get_popup()->add_shortcut(ED_SHORTCUT("animation_editor/goto_next_step", TTR("Go to Next Step"), KeyModifierMask::CMD_OR_CTRL | Key::RIGHT), EDIT_GOTO_NEXT_STEP);
+ edit->get_popup()->add_shortcut(ED_SHORTCUT("animation_editor/goto_prev_step", TTR("Go to Previous Step"), KeyModifierMask::CMD_OR_CTRL | Key::LEFT), EDIT_GOTO_PREV_STEP);
edit->get_popup()->add_separator();
edit->get_popup()->add_shortcut(ED_SHORTCUT("animation_editor/apply_reset", TTR("Apply Reset")), EDIT_APPLY_RESET);
edit->get_popup()->add_separator();
diff --git a/editor/code_editor.cpp b/editor/code_editor.cpp
index 9aa913a892..11a6912aa5 100644
--- a/editor/code_editor.cpp
+++ b/editor/code_editor.cpp
@@ -800,7 +800,7 @@ void CodeTextEditor::_text_editor_gui_input(const Ref<InputEvent> &p_event) {
Ref<InputEventMouseButton> mb = p_event;
if (mb.is_valid()) {
- if (mb->is_pressed() && mb->is_command_pressed()) {
+ if (mb->is_pressed() && mb->is_command_or_control_pressed()) {
if (mb->get_button_index() == MouseButton::WHEEL_UP) {
_zoom_in();
} else if (mb->get_button_index() == MouseButton::WHEEL_DOWN) {
@@ -1867,10 +1867,10 @@ void CodeTextEditor::update_toggle_scripts_button() {
CodeTextEditor::CodeTextEditor() {
code_complete_func = nullptr;
- ED_SHORTCUT("script_editor/zoom_in", TTR("Zoom In"), KeyModifierMask::CMD | Key::EQUAL);
- ED_SHORTCUT("script_editor/zoom_out", TTR("Zoom Out"), KeyModifierMask::CMD | Key::MINUS);
+ ED_SHORTCUT("script_editor/zoom_in", TTR("Zoom In"), KeyModifierMask::CMD_OR_CTRL | Key::EQUAL);
+ ED_SHORTCUT("script_editor/zoom_out", TTR("Zoom Out"), KeyModifierMask::CMD_OR_CTRL | Key::MINUS);
ED_SHORTCUT_ARRAY("script_editor/reset_zoom", TTR("Reset Zoom"),
- { int32_t(KeyModifierMask::CMD | Key::KEY_0), int32_t(KeyModifierMask::CMD | Key::KP_0) });
+ { int32_t(KeyModifierMask::CMD_OR_CTRL | Key::KEY_0), int32_t(KeyModifierMask::CMD_OR_CTRL | Key::KP_0) });
text_editor = memnew(CodeEdit);
add_child(text_editor);
diff --git a/editor/create_dialog.cpp b/editor/create_dialog.cpp
index 8ccfda1145..4ac32d7317 100644
--- a/editor/create_dialog.cpp
+++ b/editor/create_dialog.cpp
@@ -38,7 +38,7 @@
#include "editor/editor_scale.h"
#include "editor/editor_settings.h"
-void CreateDialog::popup_create(bool p_dont_clear, bool p_replace_mode, const String &p_select_type, const String &p_select_name) {
+void CreateDialog::popup_create(bool p_dont_clear, bool p_replace_mode, const String &p_current_type, const String &p_current_name) {
_fill_type_list();
icon_fallback = search_options->has_theme_icon(base_type, SNAME("EditorIcons")) ? base_type : "Object";
@@ -50,18 +50,14 @@ void CreateDialog::popup_create(bool p_dont_clear, bool p_replace_mode, const St
}
if (p_replace_mode) {
- search_box->set_text(p_select_type);
+ search_box->set_text(p_current_type);
}
search_box->grab_focus();
_update_search();
if (p_replace_mode) {
- if (!p_select_name.is_empty()) {
- set_title(vformat(TTR("Convert %s from %s"), p_select_name, p_select_type));
- } else {
- set_title(vformat(TTR("Convert %s"), p_select_type));
- }
+ set_title(vformat(TTR("Change Type of \"%s\""), p_current_name));
set_ok_button_text(TTR("Change"));
} else {
set_title(vformat(TTR("Create New %s"), base_type));
@@ -665,7 +661,7 @@ void CreateDialog::_save_and_update_favorite_list() {
for (int i = 0; i < favorite_list.size(); i++) {
String l = favorite_list[i];
String name = l.get_slicec(' ', 0);
- if (!(ClassDB::class_exists(name) || ScriptServer::is_global_class(name))) {
+ if (!EditorNode::get_editor_data().is_type_recognized(name)) {
continue;
}
f->store_line(l);
@@ -692,7 +688,7 @@ void CreateDialog::_load_favorites_and_history() {
String l = f->get_line().strip_edges();
String name = l.get_slicec(' ', 0);
- if ((ClassDB::class_exists(name) || ScriptServer::is_global_class(name)) && !_is_class_disabled_by_feature_profile(name)) {
+ if (EditorNode::get_editor_data().is_type_recognized(name) && !_is_class_disabled_by_feature_profile(name)) {
recent->add_item(l, EditorNode::get_singleton()->get_class_icon(name, icon_fallback));
}
}
diff --git a/editor/create_dialog.h b/editor/create_dialog.h
index f7731d2726..f2e741624f 100644
--- a/editor/create_dialog.h
+++ b/editor/create_dialog.h
@@ -120,7 +120,7 @@ public:
void set_preferred_search_result_type(const String &p_preferred_type) { preferred_search_result_type = p_preferred_type; }
String get_preferred_search_result_type() { return preferred_search_result_type; }
- void popup_create(bool p_dont_clear, bool p_replace_mode = false, const String &p_select_type = "Node", const String &p_select_name = "");
+ void popup_create(bool p_dont_clear, bool p_replace_mode = false, const String &p_current_type = "", const String &p_current_name = "");
CreateDialog();
};
diff --git a/editor/editor_audio_buses.cpp b/editor/editor_audio_buses.cpp
index 99821d8983..09dce869c9 100644
--- a/editor/editor_audio_buses.cpp
+++ b/editor/editor_audio_buses.cpp
@@ -940,7 +940,7 @@ EditorAudioBus::EditorAudioBus(EditorAudioBuses *p_buses, bool p_is_master) {
hbc->add_child(bus_options);
bus_popup = bus_options->get_popup();
- bus_popup->add_shortcut(ED_SHORTCUT("audio_bus_editor/duplicate_selected_bus", TTR("Duplicate Bus"), KeyModifierMask::CMD | Key::D));
+ bus_popup->add_shortcut(ED_SHORTCUT("audio_bus_editor/duplicate_selected_bus", TTR("Duplicate Bus"), KeyModifierMask::CMD_OR_CTRL | Key::D));
bus_popup->add_shortcut(ED_SHORTCUT("audio_bus_editor/delete_selected_bus", TTR("Delete Bus"), Key::KEY_DELETE));
bus_popup->set_item_disabled(1, is_master);
bus_popup->add_item(TTR("Reset Volume"));
diff --git a/editor/editor_data.cpp b/editor/editor_data.cpp
index 1febec2c04..d1ea0f2814 100644
--- a/editor/editor_data.cpp
+++ b/editor/editor_data.cpp
@@ -509,6 +509,32 @@ Variant EditorData::instance_custom_type(const String &p_type, const String &p_i
return Variant();
}
+const EditorData::CustomType *EditorData::get_custom_type_by_name(const String &p_type) const {
+ for (const KeyValue<String, Vector<CustomType>> &E : custom_types) {
+ for (const CustomType &F : E.value) {
+ if (F.name == p_type) {
+ return &F;
+ }
+ }
+ }
+ return nullptr;
+}
+
+const EditorData::CustomType *EditorData::get_custom_type_by_path(const String &p_path) const {
+ for (const KeyValue<String, Vector<CustomType>> &E : custom_types) {
+ for (const CustomType &F : E.value) {
+ if (F.script->get_path() == p_path) {
+ return &F;
+ }
+ }
+ }
+ return nullptr;
+}
+
+bool EditorData::is_type_recognized(const String &p_type) const {
+ return ClassDB::class_exists(p_type) || ScriptServer::is_global_class(p_type) || get_custom_type_by_name(p_type);
+}
+
void EditorData::remove_custom_type(const String &p_type) {
for (KeyValue<String, Vector<CustomType>> &E : custom_types) {
for (int i = 0; i < E.value.size(); i++) {
diff --git a/editor/editor_data.h b/editor/editor_data.h
index 1da188c546..4f1740d4f0 100644
--- a/editor/editor_data.h
+++ b/editor/editor_data.h
@@ -184,6 +184,9 @@ public:
Variant instance_custom_type(const String &p_type, const String &p_inherits);
void remove_custom_type(const String &p_type);
const HashMap<String, Vector<CustomType>> &get_custom_types() const { return custom_types; }
+ const CustomType *get_custom_type_by_name(const String &p_name) const;
+ const CustomType *get_custom_type_by_path(const String &p_path) const;
+ bool is_type_recognized(const String &p_type) const;
void instantiate_object_properties(Object *p_object);
diff --git a/editor/editor_file_dialog.cpp b/editor/editor_file_dialog.cpp
index 36ca1619a4..9fa08a0adb 100644
--- a/editor/editor_file_dialog.cpp
+++ b/editor/editor_file_dialog.cpp
@@ -145,6 +145,8 @@ void EditorFileDialog::_notification(int p_what) {
if (!is_visible()) {
set_process_shortcut_input(false);
}
+
+ invalidate(); // For consistency with the standard FileDialog.
} break;
case NOTIFICATION_WM_WINDOW_FOCUS_IN: {
@@ -304,10 +306,6 @@ void EditorFileDialog::_post_popup() {
}
set_current_dir(current);
- if (invalidated) {
- update_file_list();
- invalidated = false;
- }
if (mode == FILE_MODE_SAVE_FILE) {
file->grab_focus();
} else {
@@ -320,19 +318,13 @@ void EditorFileDialog::_post_popup() {
file_box->set_visible(true);
}
- if (is_visible() && !get_current_file().is_empty()) {
+ if (!get_current_file().is_empty()) {
_request_single_thumbnail(get_current_dir().path_join(get_current_file()));
}
- if (is_visible()) {
- _update_recent();
-
- local_history.clear();
- local_history_pos = -1;
- _push_history();
-
- _update_favorites();
- }
+ local_history.clear();
+ local_history_pos = -1;
+ _push_history();
set_process_shortcut_input(true);
}
@@ -657,7 +649,7 @@ void EditorFileDialog::_item_list_empty_clicked(const Vector2 &p_pos, MouseButto
item_menu->reset_size();
if (can_create_dir) {
- item_menu->add_icon_item(theme_cache.folder, TTR("New Folder..."), ITEM_MENU_NEW_FOLDER, KeyModifierMask::CMD | Key::N);
+ item_menu->add_icon_item(theme_cache.folder, TTR("New Folder..."), ITEM_MENU_NEW_FOLDER, KeyModifierMask::CMD_OR_CTRL | Key::N);
}
item_menu->add_icon_item(theme_cache.reload, TTR("Refresh"), ITEM_MENU_REFRESH, Key::F5);
item_menu->add_separator();
@@ -1672,14 +1664,14 @@ EditorFileDialog::EditorFileDialog() {
ED_SHORTCUT("file_dialog/go_forward", TTR("Go Forward"), KeyModifierMask::ALT | Key::RIGHT);
ED_SHORTCUT("file_dialog/go_up", TTR("Go Up"), KeyModifierMask::ALT | Key::UP);
ED_SHORTCUT("file_dialog/refresh", TTR("Refresh"), Key::F5);
- ED_SHORTCUT("file_dialog/toggle_hidden_files", TTR("Toggle Hidden Files"), KeyModifierMask::CMD | Key::H);
+ ED_SHORTCUT("file_dialog/toggle_hidden_files", TTR("Toggle Hidden Files"), KeyModifierMask::CMD_OR_CTRL | Key::H);
ED_SHORTCUT("file_dialog/toggle_favorite", TTR("Toggle Favorite"), KeyModifierMask::ALT | Key::F);
ED_SHORTCUT("file_dialog/toggle_mode", TTR("Toggle Mode"), KeyModifierMask::ALT | Key::V);
- ED_SHORTCUT("file_dialog/create_folder", TTR("Create Folder"), KeyModifierMask::CMD | Key::N);
+ ED_SHORTCUT("file_dialog/create_folder", TTR("Create Folder"), KeyModifierMask::CMD_OR_CTRL | Key::N);
ED_SHORTCUT("file_dialog/delete", TTR("Delete"), Key::KEY_DELETE);
- ED_SHORTCUT("file_dialog/focus_path", TTR("Focus Path"), KeyModifierMask::CMD | Key::D);
- ED_SHORTCUT("file_dialog/move_favorite_up", TTR("Move Favorite Up"), KeyModifierMask::CMD | Key::UP);
- ED_SHORTCUT("file_dialog/move_favorite_down", TTR("Move Favorite Down"), KeyModifierMask::CMD | Key::DOWN);
+ ED_SHORTCUT("file_dialog/focus_path", TTR("Focus Path"), KeyModifierMask::CMD_OR_CTRL | Key::D);
+ ED_SHORTCUT("file_dialog/move_favorite_up", TTR("Move Favorite Up"), KeyModifierMask::CMD_OR_CTRL | Key::UP);
+ ED_SHORTCUT("file_dialog/move_favorite_down", TTR("Move Favorite Down"), KeyModifierMask::CMD_OR_CTRL | Key::DOWN);
HBoxContainer *pathhb = memnew(HBoxContainer);
diff --git a/editor/editor_inspector.cpp b/editor/editor_inspector.cpp
index c1a7b15121..7bbdc16c61 100644
--- a/editor/editor_inspector.cpp
+++ b/editor/editor_inspector.cpp
@@ -2743,7 +2743,7 @@ void EditorInspector::update_tree() {
doc_name = p.name;
// Set the category icon.
- if (!ClassDB::class_exists(type) && !ScriptServer::is_global_class(type) && p.hint_string.length() && FileAccess::exists(p.hint_string)) {
+ if (!EditorNode::get_editor_data().is_type_recognized(type) && p.hint_string.length() && FileAccess::exists(p.hint_string)) {
// If we have a category inside a script, search for the first script with a valid icon.
Ref<Script> script = ResourceLoader::load(p.hint_string, "Script");
StringName base_type;
@@ -2762,10 +2762,16 @@ void EditorInspector::update_tree() {
while (script.is_valid()) {
name = EditorNode::get_editor_data().script_class_get_name(script->get_path());
String icon_path = EditorNode::get_editor_data().script_class_get_icon_path(name);
- if (name != StringName() && icon_path.length()) {
+ if (name != StringName() && !icon_path.is_empty()) {
category->icon = ResourceLoader::load(icon_path, "Texture");
break;
}
+
+ const EditorData::CustomType *ctype = EditorNode::get_editor_data().get_custom_type_by_path(script->get_path());
+ if (ctype) {
+ category->icon = ctype->icon;
+ break;
+ }
script = script->get_base_script();
}
if (category->icon.is_null() && has_theme_icon(base_type, SNAME("EditorIcons"))) {
@@ -4076,7 +4082,7 @@ EditorInspector::EditorInspector() {
refresh_countdown = 0.33;
}
- ED_SHORTCUT("property_editor/copy_property", TTR("Copy Property"), KeyModifierMask::CMD | Key::C);
- ED_SHORTCUT("property_editor/paste_property", TTR("Paste Property"), KeyModifierMask::CMD | Key::V);
- ED_SHORTCUT("property_editor/copy_property_path", TTR("Copy Property Path"), KeyModifierMask::CMD | KeyModifierMask::SHIFT | Key::C);
+ ED_SHORTCUT("property_editor/copy_property", TTR("Copy Property"), KeyModifierMask::CMD_OR_CTRL | Key::C);
+ ED_SHORTCUT("property_editor/paste_property", TTR("Paste Property"), KeyModifierMask::CMD_OR_CTRL | Key::V);
+ ED_SHORTCUT("property_editor/copy_property_path", TTR("Copy Property Path"), KeyModifierMask::CMD_OR_CTRL | KeyModifierMask::SHIFT | Key::C);
}
diff --git a/editor/editor_log.cpp b/editor/editor_log.cpp
index a3d4296edb..6e6a898757 100644
--- a/editor/editor_log.cpp
+++ b/editor/editor_log.cpp
@@ -396,7 +396,7 @@ EditorLog::EditorLog() {
clear_button = memnew(Button);
clear_button->set_flat(true);
clear_button->set_focus_mode(FOCUS_NONE);
- clear_button->set_shortcut(ED_SHORTCUT("editor/clear_output", TTR("Clear Output"), KeyModifierMask::CMD | KeyModifierMask::SHIFT | Key::K));
+ clear_button->set_shortcut(ED_SHORTCUT("editor/clear_output", TTR("Clear Output"), KeyModifierMask::CMD_OR_CTRL | KeyModifierMask::SHIFT | Key::K));
clear_button->set_shortcut_context(this);
clear_button->connect("pressed", callable_mp(this, &EditorLog::_clear_request));
hb_tools->add_child(clear_button);
@@ -405,7 +405,7 @@ EditorLog::EditorLog() {
copy_button = memnew(Button);
copy_button->set_flat(true);
copy_button->set_focus_mode(FOCUS_NONE);
- copy_button->set_shortcut(ED_SHORTCUT("editor/copy_output", TTR("Copy Selection"), KeyModifierMask::CMD | Key::C));
+ copy_button->set_shortcut(ED_SHORTCUT("editor/copy_output", TTR("Copy Selection"), KeyModifierMask::CMD_OR_CTRL | Key::C));
copy_button->set_shortcut_context(this);
copy_button->connect("pressed", callable_mp(this, &EditorLog::_copy_request));
hb_tools->add_child(copy_button);
@@ -431,7 +431,7 @@ EditorLog::EditorLog() {
show_search_button->set_focus_mode(FOCUS_NONE);
show_search_button->set_toggle_mode(true);
show_search_button->set_pressed(true);
- show_search_button->set_shortcut(ED_SHORTCUT("editor/open_search", TTR("Focus Search/Filter Bar"), KeyModifierMask::CMD | Key::F));
+ show_search_button->set_shortcut(ED_SHORTCUT("editor/open_search", TTR("Focus Search/Filter Bar"), KeyModifierMask::CMD_OR_CTRL | Key::F));
show_search_button->set_shortcut_context(this);
show_search_button->connect("toggled", callable_mp(this, &EditorLog::_set_search_visible));
hb_tools2->add_child(show_search_button);
diff --git a/editor/editor_node.cpp b/editor/editor_node.cpp
index 96b229b7ee..1d2540f0fd 100644
--- a/editor/editor_node.cpp
+++ b/editor/editor_node.cpp
@@ -566,8 +566,6 @@ void EditorNode::_update_from_settings() {
SceneTree *tree = get_tree();
tree->set_debug_collisions_color(GLOBAL_GET("debug/shapes/collision/shape_color"));
tree->set_debug_collision_contact_color(GLOBAL_GET("debug/shapes/collision/contact_color"));
- tree->set_debug_navigation_color(GLOBAL_GET("debug/shapes/navigation/geometry_color"));
- tree->set_debug_navigation_disabled_color(GLOBAL_GET("debug/shapes/navigation/disabled_geometry_color"));
#ifdef DEBUG_ENABLED
NavigationServer3D::get_singleton_mut()->set_debug_navigation_edge_connection_color(GLOBAL_GET("debug/shapes/navigation/edge_connection_color"));
@@ -2657,22 +2655,36 @@ void EditorNode::_menu_option_confirm(int p_option, bool p_confirmed) {
case FILE_CLOSE_ALL_AND_RELOAD_CURRENT_PROJECT: {
if (!p_confirmed) {
tab_closing_idx = _next_unsaved_scene(false);
- _scene_tab_changed(tab_closing_idx);
+ if (tab_closing_idx == -1) {
+ tab_closing_idx = -2; // Only external resources are unsaved.
+ } else {
+ _scene_tab_changed(tab_closing_idx);
+ }
if (unsaved_cache || p_option == FILE_CLOSE_ALL_AND_QUIT || p_option == FILE_CLOSE_ALL_AND_RUN_PROJECT_MANAGER || p_option == FILE_CLOSE_ALL_AND_RELOAD_CURRENT_PROJECT) {
- Node *scene_root = editor_data.get_edited_scene_root(tab_closing_idx);
- if (scene_root) {
- String scene_filename = scene_root->get_scene_file_path();
+ if (tab_closing_idx == -2) {
if (p_option == FILE_CLOSE_ALL_AND_RELOAD_CURRENT_PROJECT) {
save_confirmation->set_ok_button_text(TTR("Save & Reload"));
- save_confirmation->set_text(vformat(TTR("Save changes to '%s' before reloading?"), !scene_filename.is_empty() ? scene_filename : "unsaved scene"));
+ save_confirmation->set_text(TTR("Save modified resources before reloading?"));
} else {
save_confirmation->set_ok_button_text(TTR("Save & Quit"));
- save_confirmation->set_text(vformat(TTR("Save changes to '%s' before closing?"), !scene_filename.is_empty() ? scene_filename : "unsaved scene"));
+ save_confirmation->set_text(TTR("Save modified resources before closing?"));
+ }
+ } else {
+ Node *scene_root = editor_data.get_edited_scene_root(tab_closing_idx);
+ if (scene_root) {
+ String scene_filename = scene_root->get_scene_file_path();
+ if (p_option == FILE_CLOSE_ALL_AND_RELOAD_CURRENT_PROJECT) {
+ save_confirmation->set_ok_button_text(TTR("Save & Reload"));
+ save_confirmation->set_text(vformat(TTR("Save changes to '%s' before reloading?"), !scene_filename.is_empty() ? scene_filename : "unsaved scene"));
+ } else {
+ save_confirmation->set_ok_button_text(TTR("Save & Quit"));
+ save_confirmation->set_text(vformat(TTR("Save changes to '%s' before closing?"), !scene_filename.is_empty() ? scene_filename : "unsaved scene"));
+ }
}
- save_confirmation->popup_centered();
- break;
}
+ save_confirmation->popup_centered();
+ break;
}
}
if (!editor_data.get_edited_scene_root(tab_closing_idx)) {
@@ -2945,7 +2957,7 @@ void EditorNode::_menu_option_confirm(int p_option, bool p_confirmed) {
case RELOAD_CURRENT_PROJECT: {
if (!p_confirmed) {
bool save_each = EDITOR_GET("interface/editor/save_each_scene_on_quit");
- if (_next_unsaved_scene(!save_each) == -1) {
+ if (_next_unsaved_scene(!save_each) == -1 && !get_undo_redo()->is_history_unsaved(EditorUndoRedoManager::GLOBAL_HISTORY)) {
_discard_changes();
break;
} else {
@@ -3256,8 +3268,12 @@ void EditorNode::_discard_changes(const String &p_str) {
for (const String &a : Main::get_forwardable_cli_arguments(Main::CLI_SCOPE_TOOL)) {
args.push_back(a);
}
- args.push_back("--path");
- args.push_back(exec.get_base_dir());
+
+ String exec_base_dir = exec.get_base_dir();
+ if (!exec_base_dir.is_empty()) {
+ args.push_back("--path");
+ args.push_back(exec_base_dir);
+ }
args.push_back("--project-manager");
Error err = OS::get_singleton()->create_instance(args);
@@ -3375,7 +3391,7 @@ void EditorNode::add_editor_plugin(EditorPlugin *p_editor, bool p_config_changed
singleton->main_editor_button_vb->add_child(tb);
singleton->editor_table.push_back(p_editor);
- singleton->distraction_free->raise();
+ singleton->distraction_free->move_to_front();
}
singleton->editor_data.add_editor_plugin(p_editor);
singleton->add_child(p_editor);
@@ -4335,16 +4351,8 @@ Ref<Texture2D> EditorNode::get_class_icon(const String &p_class, const String &p
}
}
- const HashMap<String, Vector<EditorData::CustomType>> &p_map = EditorNode::get_editor_data().get_custom_types();
- for (const KeyValue<String, Vector<EditorData::CustomType>> &E : p_map) {
- const Vector<EditorData::CustomType> &ct = E.value;
- for (int i = 0; i < ct.size(); ++i) {
- if (ct[i].name == p_class) {
- if (ct[i].icon.is_valid()) {
- return ct[i].icon;
- }
- }
- }
+ if (const EditorData::CustomType *ctype = EditorNode::get_editor_data().get_custom_type_by_name(p_class)) {
+ return ctype->icon;
}
if (gui_base->has_theme_icon(p_class, SNAME("EditorIcons"))) {
@@ -4965,7 +4973,7 @@ void EditorNode::_load_docks_from_config(Ref<ConfigFile> p_layout, const String
}
if (atidx == i) {
- node->raise();
+ node->move_to_front();
continue;
}
@@ -5390,7 +5398,7 @@ Button *EditorNode::add_bottom_panel_item(String p_text, Control *p_item) {
tb->set_toggle_mode(true);
tb->set_focus_mode(Control::FOCUS_NONE);
bottom_panel_vb->add_child(p_item);
- bottom_panel_hb->raise();
+ bottom_panel_hb->move_to_front();
bottom_panel_hb_editors->add_child(tb);
p_item->set_v_size_flags(Control::SIZE_EXPAND_FILL);
p_item->hide();
@@ -5424,7 +5432,7 @@ void EditorNode::make_bottom_panel_item_visible(Control *p_item) {
void EditorNode::raise_bottom_panel_item(Control *p_item) {
for (int i = 0; i < bottom_panel_items.size(); i++) {
if (bottom_panel_items[i].control == p_item) {
- bottom_panel_items[i].button->raise();
+ bottom_panel_items[i].button->move_to_front();
SWAP(bottom_panel_items.write[i], bottom_panel_items.write[bottom_panel_items.size() - 1]);
break;
}
@@ -6560,8 +6568,8 @@ EditorNode::EditorNode() {
distraction_free = memnew(Button);
distraction_free->set_flat(true);
- ED_SHORTCUT_AND_COMMAND("editor/distraction_free_mode", TTR("Distraction Free Mode"), KeyModifierMask::CMD | KeyModifierMask::SHIFT | Key::F11);
- ED_SHORTCUT_OVERRIDE("editor/distraction_free_mode", "macos", KeyModifierMask::CMD | KeyModifierMask::CTRL | Key::D);
+ ED_SHORTCUT_AND_COMMAND("editor/distraction_free_mode", TTR("Distraction Free Mode"), KeyModifierMask::CTRL | KeyModifierMask::SHIFT | Key::F11);
+ ED_SHORTCUT_OVERRIDE("editor/distraction_free_mode", "macos", KeyModifierMask::META | KeyModifierMask::CTRL | Key::D);
distraction_free->set_shortcut(ED_GET_SHORTCUT("editor/distraction_free_mode"));
distraction_free->set_tooltip_text(TTR("Toggle distraction-free mode."));
distraction_free->connect("pressed", callable_mp(this, &EditorNode::_toggle_distraction_free_mode));
@@ -6673,30 +6681,30 @@ EditorNode::EditorNode() {
gui_base->add_child(warning);
warning->connect("custom_action", callable_mp(this, &EditorNode::_copy_warning));
- ED_SHORTCUT("editor/next_tab", TTR("Next Scene Tab"), KeyModifierMask::CMD + Key::TAB);
- ED_SHORTCUT("editor/prev_tab", TTR("Previous Scene Tab"), KeyModifierMask::CMD + KeyModifierMask::SHIFT + Key::TAB);
- ED_SHORTCUT("editor/filter_files", TTR("Focus FileSystem Filter"), KeyModifierMask::CMD + KeyModifierMask::ALT + Key::P);
+ ED_SHORTCUT("editor/next_tab", TTR("Next Scene Tab"), KeyModifierMask::CMD_OR_CTRL + Key::TAB);
+ ED_SHORTCUT("editor/prev_tab", TTR("Previous Scene Tab"), KeyModifierMask::CMD_OR_CTRL + KeyModifierMask::SHIFT + Key::TAB);
+ ED_SHORTCUT("editor/filter_files", TTR("Focus FileSystem Filter"), KeyModifierMask::CMD_OR_CTRL + KeyModifierMask::ALT + Key::P);
command_palette = EditorCommandPalette::get_singleton();
command_palette->set_title(TTR("Command Palette"));
gui_base->add_child(command_palette);
- file_menu->add_shortcut(ED_SHORTCUT_AND_COMMAND("editor/new_scene", TTR("New Scene"), KeyModifierMask::CMD + Key::N), FILE_NEW_SCENE);
- file_menu->add_shortcut(ED_SHORTCUT_AND_COMMAND("editor/new_inherited_scene", TTR("New Inherited Scene..."), KeyModifierMask::CMD + KeyModifierMask::SHIFT + Key::N), FILE_NEW_INHERITED_SCENE);
- file_menu->add_shortcut(ED_SHORTCUT_AND_COMMAND("editor/open_scene", TTR("Open Scene..."), KeyModifierMask::CMD + Key::O), FILE_OPEN_SCENE);
- file_menu->add_shortcut(ED_SHORTCUT_AND_COMMAND("editor/reopen_closed_scene", TTR("Reopen Closed Scene"), KeyModifierMask::CMD + KeyModifierMask::SHIFT + Key::T), FILE_OPEN_PREV);
+ file_menu->add_shortcut(ED_SHORTCUT_AND_COMMAND("editor/new_scene", TTR("New Scene"), KeyModifierMask::CMD_OR_CTRL + Key::N), FILE_NEW_SCENE);
+ file_menu->add_shortcut(ED_SHORTCUT_AND_COMMAND("editor/new_inherited_scene", TTR("New Inherited Scene..."), KeyModifierMask::CMD_OR_CTRL + KeyModifierMask::SHIFT + Key::N), FILE_NEW_INHERITED_SCENE);
+ file_menu->add_shortcut(ED_SHORTCUT_AND_COMMAND("editor/open_scene", TTR("Open Scene..."), KeyModifierMask::CMD_OR_CTRL + Key::O), FILE_OPEN_SCENE);
+ file_menu->add_shortcut(ED_SHORTCUT_AND_COMMAND("editor/reopen_closed_scene", TTR("Reopen Closed Scene"), KeyModifierMask::CMD_OR_CTRL + KeyModifierMask::SHIFT + Key::T), FILE_OPEN_PREV);
file_menu->add_submenu_item(TTR("Open Recent"), "RecentScenes", FILE_OPEN_RECENT);
file_menu->add_separator();
- file_menu->add_shortcut(ED_SHORTCUT_AND_COMMAND("editor/save_scene", TTR("Save Scene"), KeyModifierMask::CMD + Key::S), FILE_SAVE_SCENE);
- file_menu->add_shortcut(ED_SHORTCUT_AND_COMMAND("editor/save_scene_as", TTR("Save Scene As..."), KeyModifierMask::CMD + KeyModifierMask::SHIFT + Key::S), FILE_SAVE_AS_SCENE);
- file_menu->add_shortcut(ED_SHORTCUT_AND_COMMAND("editor/save_all_scenes", TTR("Save All Scenes"), KeyModifierMask::CMD + KeyModifierMask::SHIFT + KeyModifierMask::ALT + Key::S), FILE_SAVE_ALL_SCENES);
+ file_menu->add_shortcut(ED_SHORTCUT_AND_COMMAND("editor/save_scene", TTR("Save Scene"), KeyModifierMask::CMD_OR_CTRL + Key::S), FILE_SAVE_SCENE);
+ file_menu->add_shortcut(ED_SHORTCUT_AND_COMMAND("editor/save_scene_as", TTR("Save Scene As..."), KeyModifierMask::CMD_OR_CTRL + KeyModifierMask::SHIFT + Key::S), FILE_SAVE_AS_SCENE);
+ file_menu->add_shortcut(ED_SHORTCUT_AND_COMMAND("editor/save_all_scenes", TTR("Save All Scenes"), KeyModifierMask::CMD_OR_CTRL + KeyModifierMask::SHIFT + KeyModifierMask::ALT + Key::S), FILE_SAVE_ALL_SCENES);
file_menu->add_separator();
file_menu->add_shortcut(ED_SHORTCUT_AND_COMMAND("editor/quick_open", TTR("Quick Open..."), KeyModifierMask::SHIFT + KeyModifierMask::ALT + Key::O), FILE_QUICK_OPEN);
- file_menu->add_shortcut(ED_SHORTCUT_AND_COMMAND("editor/quick_open_scene", TTR("Quick Open Scene..."), KeyModifierMask::CMD + KeyModifierMask::SHIFT + Key::O), FILE_QUICK_OPEN_SCENE);
- file_menu->add_shortcut(ED_SHORTCUT_AND_COMMAND("editor/quick_open_script", TTR("Quick Open Script..."), KeyModifierMask::CMD + KeyModifierMask::ALT + Key::O), FILE_QUICK_OPEN_SCRIPT);
+ file_menu->add_shortcut(ED_SHORTCUT_AND_COMMAND("editor/quick_open_scene", TTR("Quick Open Scene..."), KeyModifierMask::CMD_OR_CTRL + KeyModifierMask::SHIFT + Key::O), FILE_QUICK_OPEN_SCENE);
+ file_menu->add_shortcut(ED_SHORTCUT_AND_COMMAND("editor/quick_open_script", TTR("Quick Open Script..."), KeyModifierMask::CMD_OR_CTRL + KeyModifierMask::ALT + Key::O), FILE_QUICK_OPEN_SCRIPT);
file_menu->add_separator();
export_as_menu = memnew(PopupMenu);
@@ -6712,7 +6720,7 @@ EditorNode::EditorNode() {
file_menu->add_separator();
file_menu->add_shortcut(ED_SHORTCUT_AND_COMMAND("editor/reload_saved_scene", TTR("Reload Saved Scene")), EDIT_RELOAD_SAVED_SCENE);
- file_menu->add_shortcut(ED_SHORTCUT_AND_COMMAND("editor/close_scene", TTR("Close Scene"), KeyModifierMask::CMD + KeyModifierMask::SHIFT + Key::W), FILE_CLOSE);
+ file_menu->add_shortcut(ED_SHORTCUT_AND_COMMAND("editor/close_scene", TTR("Close Scene"), KeyModifierMask::CMD_OR_CTRL + KeyModifierMask::SHIFT + Key::W), FILE_CLOSE);
recent_scenes = memnew(PopupMenu);
recent_scenes->set_name("RecentScenes");
@@ -6722,7 +6730,7 @@ EditorNode::EditorNode() {
if (!global_menu || !OS::get_singleton()->has_feature("macos")) {
// On macOS "Quit" and "About" options are in the "app" menu.
file_menu->add_separator();
- file_menu->add_shortcut(ED_SHORTCUT_AND_COMMAND("editor/file_quit", TTR("Quit"), KeyModifierMask::CMD + Key::Q), FILE_QUIT, true);
+ file_menu->add_shortcut(ED_SHORTCUT_AND_COMMAND("editor/file_quit", TTR("Quit"), KeyModifierMask::CMD_OR_CTRL + Key::Q), FILE_QUIT, true);
}
project_menu = memnew(PopupMenu);
@@ -6763,7 +6771,7 @@ EditorNode::EditorNode() {
project_menu->add_separator();
project_menu->add_shortcut(ED_SHORTCUT("editor/reload_current_project", TTR("Reload Current Project")), RELOAD_CURRENT_PROJECT);
- ED_SHORTCUT_AND_COMMAND("editor/quit_to_project_list", TTR("Quit to Project List"), KeyModifierMask::CMD + KeyModifierMask::SHIFT + Key::Q);
+ ED_SHORTCUT_AND_COMMAND("editor/quit_to_project_list", TTR("Quit to Project List"), KeyModifierMask::CTRL + KeyModifierMask::SHIFT + Key::Q);
ED_SHORTCUT_OVERRIDE("editor/quit_to_project_list", "macos", KeyModifierMask::SHIFT + KeyModifierMask::ALT + Key::Q);
project_menu->add_shortcut(ED_GET_SHORTCUT("editor/quit_to_project_list"), RUN_PROJECT_MANAGER, true);
@@ -6789,9 +6797,9 @@ EditorNode::EditorNode() {
main_menu->add_child(settings_menu);
ED_SHORTCUT_AND_COMMAND("editor/editor_settings", TTR("Editor Settings..."));
- ED_SHORTCUT_OVERRIDE("editor/editor_settings", "macos", KeyModifierMask::CMD + Key::COMMA);
+ ED_SHORTCUT_OVERRIDE("editor/editor_settings", "macos", KeyModifierMask::META + Key::COMMA);
settings_menu->add_shortcut(ED_GET_SHORTCUT("editor/editor_settings"), SETTINGS_PREFERENCES);
- settings_menu->add_shortcut(ED_SHORTCUT("editor/command_palette", TTR("Command Palette..."), KeyModifierMask::CMD | KeyModifierMask::SHIFT | Key::P), HELP_COMMAND_PALETTE);
+ settings_menu->add_shortcut(ED_SHORTCUT("editor/command_palette", TTR("Command Palette..."), KeyModifierMask::CMD_OR_CTRL | KeyModifierMask::SHIFT | Key::P), HELP_COMMAND_PALETTE);
settings_menu->add_separator();
editor_layouts = memnew(PopupMenu);
@@ -6802,13 +6810,13 @@ EditorNode::EditorNode() {
settings_menu->add_separator();
ED_SHORTCUT_AND_COMMAND("editor/take_screenshot", TTR("Take Screenshot"), KeyModifierMask::CTRL | Key::F12);
- ED_SHORTCUT_OVERRIDE("editor/take_screenshot", "macos", KeyModifierMask::CMD | Key::F12);
+ ED_SHORTCUT_OVERRIDE("editor/take_screenshot", "macos", KeyModifierMask::META | Key::F12);
settings_menu->add_shortcut(ED_GET_SHORTCUT("editor/take_screenshot"), EDITOR_SCREENSHOT);
settings_menu->set_item_tooltip(-1, TTR("Screenshots are stored in the Editor Data/Settings Folder."));
ED_SHORTCUT_AND_COMMAND("editor/fullscreen_mode", TTR("Toggle Fullscreen"), KeyModifierMask::SHIFT | Key::F11);
- ED_SHORTCUT_OVERRIDE("editor/fullscreen_mode", "macos", KeyModifierMask::CMD | KeyModifierMask::CTRL | Key::F);
+ ED_SHORTCUT_OVERRIDE("editor/fullscreen_mode", "macos", KeyModifierMask::META | KeyModifierMask::CTRL | Key::F);
settings_menu->add_shortcut(ED_GET_SHORTCUT("editor/fullscreen_mode"), SETTINGS_TOGGLE_FULLSCREEN);
settings_menu->add_separator();
@@ -6869,7 +6877,7 @@ EditorNode::EditorNode() {
play_button->connect("pressed", callable_mp(this, &EditorNode::_menu_option).bind(RUN_PLAY));
ED_SHORTCUT_AND_COMMAND("editor/play", TTR("Play"), Key::F5);
- ED_SHORTCUT_OVERRIDE("editor/play", "macos", KeyModifierMask::CMD | Key::B);
+ ED_SHORTCUT_OVERRIDE("editor/play", "macos", KeyModifierMask::META | Key::B);
play_button->set_shortcut(ED_GET_SHORTCUT("editor/play"));
pause_button = memnew(Button);
@@ -6882,7 +6890,7 @@ EditorNode::EditorNode() {
launch_pad_hb->add_child(pause_button);
ED_SHORTCUT("editor/pause_scene", TTR("Pause Scene"), Key::F7);
- ED_SHORTCUT_OVERRIDE("editor/pause_scene", "macos", KeyModifierMask::CMD | KeyModifierMask::CTRL | Key::Y);
+ ED_SHORTCUT_OVERRIDE("editor/pause_scene", "macos", KeyModifierMask::META | KeyModifierMask::CTRL | Key::Y);
pause_button->set_shortcut(ED_GET_SHORTCUT("editor/pause_scene"));
stop_button = memnew(Button);
@@ -6895,7 +6903,7 @@ EditorNode::EditorNode() {
stop_button->set_disabled(true);
ED_SHORTCUT("editor/stop", TTR("Stop"), Key::F8);
- ED_SHORTCUT_OVERRIDE("editor/stop", "macos", KeyModifierMask::CMD | Key::PERIOD);
+ ED_SHORTCUT_OVERRIDE("editor/stop", "macos", KeyModifierMask::META | Key::PERIOD);
stop_button->set_shortcut(ED_GET_SHORTCUT("editor/stop"));
run_native = memnew(EditorRunNative);
@@ -6910,7 +6918,7 @@ EditorNode::EditorNode() {
play_scene_button->connect("pressed", callable_mp(this, &EditorNode::_menu_option).bind(RUN_PLAY_SCENE));
ED_SHORTCUT_AND_COMMAND("editor/play_scene", TTR("Play Scene"), Key::F6);
- ED_SHORTCUT_OVERRIDE("editor/play_scene", "macos", KeyModifierMask::CMD | Key::R);
+ ED_SHORTCUT_OVERRIDE("editor/play_scene", "macos", KeyModifierMask::META | Key::R);
play_scene_button->set_shortcut(ED_GET_SHORTCUT("editor/play_scene"));
play_custom_scene_button = memnew(Button);
@@ -6922,8 +6930,8 @@ EditorNode::EditorNode() {
_reset_play_buttons();
- ED_SHORTCUT_AND_COMMAND("editor/play_custom_scene", TTR("Play Custom Scene"), KeyModifierMask::CMD | KeyModifierMask::SHIFT | Key::F5);
- ED_SHORTCUT_OVERRIDE("editor/play_custom_scene", "macos", KeyModifierMask::CMD | KeyModifierMask::SHIFT | Key::R);
+ ED_SHORTCUT_AND_COMMAND("editor/play_custom_scene", TTR("Play Custom Scene"), KeyModifierMask::CTRL | KeyModifierMask::SHIFT | Key::F5);
+ ED_SHORTCUT_OVERRIDE("editor/play_custom_scene", "macos", KeyModifierMask::META | KeyModifierMask::SHIFT | Key::R);
play_custom_scene_button->set_shortcut(ED_GET_SHORTCUT("editor/play_custom_scene"));
write_movie_panel = memnew(PanelContainer);
diff --git a/editor/editor_settings.cpp b/editor/editor_settings.cpp
index 5dd0a1052a..74445e6caa 100644
--- a/editor/editor_settings.cpp
+++ b/editor/editor_settings.cpp
@@ -717,7 +717,7 @@ void EditorSettings::_load_defaults(Ref<ConfigFile> p_extra_config) {
EDITOR_SETTING(Variant::INT, PROPERTY_HINT_RANGE, "network/debug/remote_port", 6007, "1,65535,1")
// SSL
- EDITOR_SETTING_USAGE(Variant::STRING, PROPERTY_HINT_GLOBAL_FILE, "network/ssl/editor_ssl_certificates", _SYSTEM_CERTS_PATH, "*.crt,*.pem", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_RESTART_IF_CHANGED);
+ EDITOR_SETTING_USAGE(Variant::STRING, PROPERTY_HINT_GLOBAL_FILE, "network/tls/editor_tls_certificates", _SYSTEM_CERTS_PATH, "*.crt,*.pem", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_RESTART_IF_CHANGED);
// Profiler
EDITOR_SETTING(Variant::INT, PROPERTY_HINT_RANGE, "debugger/profiler_frame_history_size", 3600, "60,10000,1")
@@ -1467,9 +1467,10 @@ void ED_SHORTCUT_OVERRIDE_ARRAY(const String &p_path, const String &p_feature, c
#ifdef MACOS_ENABLED
// Use Cmd+Backspace as a general replacement for Delete shortcuts on macOS
if (keycode == Key::KEY_DELETE) {
- keycode = KeyModifierMask::CMD | Key::BACKSPACE;
+ keycode = KeyModifierMask::META | Key::BACKSPACE;
}
#endif
+
Ref<InputEventKey> ie;
if (keycode != Key::NONE) {
ie = InputEventKey::create_reference(keycode);
@@ -1500,7 +1501,7 @@ Ref<Shortcut> ED_SHORTCUT_ARRAY(const String &p_path, const String &p_name, cons
#ifdef MACOS_ENABLED
// Use Cmd+Backspace as a general replacement for Delete shortcuts on macOS
if (keycode == Key::KEY_DELETE) {
- keycode = KeyModifierMask::CMD | Key::BACKSPACE;
+ keycode = KeyModifierMask::META | Key::BACKSPACE;
}
#endif
diff --git a/editor/editor_settings_dialog.cpp b/editor/editor_settings_dialog.cpp
index 9b8d46a923..ec67cde112 100644
--- a/editor/editor_settings_dialog.cpp
+++ b/editor/editor_settings_dialog.cpp
@@ -175,7 +175,7 @@ void EditorSettingsDialog::shortcut_input(const Ref<InputEvent> &p_event) {
handled = true;
}
- if (k->get_keycode_with_modifiers() == (KeyModifierMask::CMD | Key::F)) {
+ if (k->is_match(InputEventKey::create_reference(KeyModifierMask::CMD_OR_CTRL | Key::F))) {
_focus_current_search_box();
handled = true;
}
diff --git a/editor/editor_spin_slider.cpp b/editor/editor_spin_slider.cpp
index 58020cf682..4cd046e811 100644
--- a/editor/editor_spin_slider.cpp
+++ b/editor/editor_spin_slider.cpp
@@ -121,7 +121,7 @@ void EditorSpinSlider::gui_input(const Ref<InputEvent> &p_event) {
pre_grab_value = get_max();
}
- if (mm->is_command_pressed()) {
+ if (mm->is_command_or_control_pressed()) {
// If control was just pressed, don't make the value do a huge jump in magnitude.
if (grabbing_spinner_dist_cache != 0) {
pre_grab_value += grabbing_spinner_dist_cache * get_step();
diff --git a/editor/editor_themes.cpp b/editor/editor_themes.cpp
index 5bf79635b8..9e983839f9 100644
--- a/editor/editor_themes.cpp
+++ b/editor/editor_themes.cpp
@@ -157,24 +157,15 @@ void EditorColorMap::create() {
static Ref<StyleBoxTexture> make_stylebox(Ref<Texture2D> p_texture, float p_left, float p_top, float p_right, float p_bottom, float p_margin_left = -1, float p_margin_top = -1, float p_margin_right = -1, float p_margin_bottom = -1, bool p_draw_center = true) {
Ref<StyleBoxTexture> style(memnew(StyleBoxTexture));
style->set_texture(p_texture);
- style->set_margin_size(SIDE_LEFT, p_left * EDSCALE);
- style->set_margin_size(SIDE_RIGHT, p_right * EDSCALE);
- style->set_margin_size(SIDE_BOTTOM, p_bottom * EDSCALE);
- style->set_margin_size(SIDE_TOP, p_top * EDSCALE);
- style->set_default_margin(SIDE_LEFT, p_margin_left * EDSCALE);
- style->set_default_margin(SIDE_RIGHT, p_margin_right * EDSCALE);
- style->set_default_margin(SIDE_BOTTOM, p_margin_bottom * EDSCALE);
- style->set_default_margin(SIDE_TOP, p_margin_top * EDSCALE);
+ style->set_margin_size_individual(p_left * EDSCALE, p_top * EDSCALE, p_right * EDSCALE, p_bottom * EDSCALE);
+ style->set_default_margin_individual(p_margin_left * EDSCALE, p_margin_top * EDSCALE, p_margin_right * EDSCALE, p_margin_bottom * EDSCALE);
style->set_draw_center(p_draw_center);
return style;
}
static Ref<StyleBoxEmpty> make_empty_stylebox(float p_margin_left = -1, float p_margin_top = -1, float p_margin_right = -1, float p_margin_bottom = -1) {
Ref<StyleBoxEmpty> style(memnew(StyleBoxEmpty));
- style->set_default_margin(SIDE_LEFT, p_margin_left * EDSCALE);
- style->set_default_margin(SIDE_RIGHT, p_margin_right * EDSCALE);
- style->set_default_margin(SIDE_BOTTOM, p_margin_bottom * EDSCALE);
- style->set_default_margin(SIDE_TOP, p_margin_top * EDSCALE);
+ style->set_default_margin_individual(p_margin_left * EDSCALE, p_margin_top * EDSCALE, p_margin_right * EDSCALE, p_margin_bottom * EDSCALE);
return style;
}
@@ -184,10 +175,7 @@ static Ref<StyleBoxFlat> make_flat_stylebox(Color p_color, float p_margin_left =
// Adjust level of detail based on the corners' effective sizes.
style->set_corner_detail(Math::ceil(0.8 * p_corner_width * EDSCALE));
style->set_corner_radius_all(p_corner_width * EDSCALE);
- style->set_default_margin(SIDE_LEFT, p_margin_left * EDSCALE);
- style->set_default_margin(SIDE_RIGHT, p_margin_right * EDSCALE);
- style->set_default_margin(SIDE_BOTTOM, p_margin_bottom * EDSCALE);
- style->set_default_margin(SIDE_TOP, p_margin_top * EDSCALE);
+ style->set_default_margin_individual(p_margin_left * EDSCALE, p_margin_top * EDSCALE, p_margin_right * EDSCALE, p_margin_bottom * EDSCALE);
// Work around issue about antialiased edges being blurrier (GH-35279).
style->set_anti_aliased(false);
return style;
@@ -600,10 +588,7 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) {
const Vector2 widget_default_margin = Vector2(extra_spacing + 6, extra_spacing + default_margin_size + 1) * EDSCALE;
Ref<StyleBoxFlat> style_widget = style_default->duplicate();
- style_widget->set_default_margin(SIDE_LEFT, widget_default_margin.x);
- style_widget->set_default_margin(SIDE_TOP, widget_default_margin.y);
- style_widget->set_default_margin(SIDE_RIGHT, widget_default_margin.x);
- style_widget->set_default_margin(SIDE_BOTTOM, widget_default_margin.y);
+ style_widget->set_default_margin_individual(widget_default_margin.x, widget_default_margin.y, widget_default_margin.x, widget_default_margin.y);
style_widget->set_bg_color(dark_color_1);
style_widget->set_border_color(dark_color_2);
@@ -626,10 +611,7 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) {
// Style for windows, popups, etc..
Ref<StyleBoxFlat> style_popup = style_default->duplicate();
const int popup_margin_size = default_margin_size * EDSCALE * 3;
- style_popup->set_default_margin(SIDE_LEFT, popup_margin_size);
- style_popup->set_default_margin(SIDE_TOP, popup_margin_size);
- style_popup->set_default_margin(SIDE_RIGHT, popup_margin_size);
- style_popup->set_default_margin(SIDE_BOTTOM, popup_margin_size);
+ style_popup->set_default_margin_all(popup_margin_size);
style_popup->set_border_color(contrast_color_1);
const Color shadow_color = Color(0, 0, 0, dark_theme ? 0.3 : 0.1);
style_popup->set_shadow_color(shadow_color);
@@ -922,10 +904,7 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) {
// Checkbox
Ref<StyleBoxFlat> sb_checkbox = style_menu->duplicate();
- sb_checkbox->set_default_margin(SIDE_LEFT, default_margin_size * EDSCALE);
- sb_checkbox->set_default_margin(SIDE_RIGHT, default_margin_size * EDSCALE);
- sb_checkbox->set_default_margin(SIDE_TOP, default_margin_size * EDSCALE);
- sb_checkbox->set_default_margin(SIDE_BOTTOM, default_margin_size * EDSCALE);
+ sb_checkbox->set_default_margin_all(default_margin_size * EDSCALE);
theme->set_stylebox("normal", "CheckBox", sb_checkbox);
theme->set_stylebox("pressed", "CheckBox", sb_checkbox);
@@ -965,10 +944,7 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) {
// Use 1 pixel for the sides, since if 0 is used, the highlight of hovered items is drawn
// on top of the popup border. This causes a 'gap' in the panel border when an item is highlighted,
// and it looks weird. 1px solves this.
- style_popup_menu->set_default_margin(SIDE_LEFT, EDSCALE);
- style_popup_menu->set_default_margin(SIDE_TOP, 2 * EDSCALE);
- style_popup_menu->set_default_margin(SIDE_RIGHT, EDSCALE);
- style_popup_menu->set_default_margin(SIDE_BOTTOM, 2 * EDSCALE);
+ style_popup_menu->set_default_margin_individual(EDSCALE, 2 * EDSCALE, EDSCALE, 2 * EDSCALE);
// Always display a border for PopupMenus so they can be distinguished from their background.
style_popup_menu->set_border_width_all(EDSCALE);
style_popup_menu->set_border_color(dark_color_2);
@@ -1024,10 +1000,7 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) {
sub_inspector_bg->set_bg_color(dark_color_1.lerp(si_base_color, 0.08));
sub_inspector_bg->set_border_width_all(2 * EDSCALE);
sub_inspector_bg->set_border_color(si_base_color * Color(0.7, 0.7, 0.7, 0.8));
- sub_inspector_bg->set_default_margin(SIDE_LEFT, 4 * EDSCALE);
- sub_inspector_bg->set_default_margin(SIDE_RIGHT, 4 * EDSCALE);
- sub_inspector_bg->set_default_margin(SIDE_BOTTOM, 4 * EDSCALE);
- sub_inspector_bg->set_default_margin(SIDE_TOP, 4 * EDSCALE);
+ sub_inspector_bg->set_default_margin_all(4 * EDSCALE);
sub_inspector_bg->set_corner_radius(CORNER_TOP_LEFT, 0);
sub_inspector_bg->set_corner_radius(CORNER_TOP_RIGHT, 0);
@@ -1255,10 +1228,7 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) {
style_content_panel->set_corner_radius(CORNER_TOP_LEFT, 0);
style_content_panel->set_corner_radius(CORNER_TOP_RIGHT, 0);
// Compensate for the border.
- style_content_panel->set_default_margin(SIDE_TOP, (2 + margin_size_extra) * EDSCALE);
- style_content_panel->set_default_margin(SIDE_RIGHT, margin_size_extra * EDSCALE);
- style_content_panel->set_default_margin(SIDE_BOTTOM, margin_size_extra * EDSCALE);
- style_content_panel->set_default_margin(SIDE_LEFT, margin_size_extra * EDSCALE);
+ style_content_panel->set_default_margin_individual(margin_size_extra * EDSCALE, (2 + margin_size_extra) * EDSCALE, margin_size_extra * EDSCALE, margin_size_extra * EDSCALE);
theme->set_stylebox("panel", "TabContainer", style_content_panel);
// Bottom panel.
@@ -1279,10 +1249,7 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) {
// This stylebox is used in 3d and 2d viewports (no borders).
Ref<StyleBoxFlat> style_content_panel_vp = style_content_panel->duplicate();
- style_content_panel_vp->set_default_margin(SIDE_LEFT, border_width * 2);
- style_content_panel_vp->set_default_margin(SIDE_TOP, default_margin_size * EDSCALE);
- style_content_panel_vp->set_default_margin(SIDE_RIGHT, border_width * 2);
- style_content_panel_vp->set_default_margin(SIDE_BOTTOM, border_width * 2);
+ style_content_panel_vp->set_default_margin_individual(border_width * 2, default_margin_size * EDSCALE, border_width * 2, border_width * 2);
theme->set_stylebox("Content", "EditorStyles", style_content_panel_vp);
// This stylebox is used by preview tabs in the Theme Editor.
@@ -1361,6 +1328,9 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) {
theme->set_constant("separation", "HSplitContainer", default_margin_size * 2 * EDSCALE);
theme->set_constant("separation", "VSplitContainer", default_margin_size * 2 * EDSCALE);
+ theme->set_constant("minimum_grab_thickness", "HSplitContainer", 6 * EDSCALE);
+ theme->set_constant("minimum_grab_thickness", "VSplitContainer", 6 * EDSCALE);
+
// Containers
theme->set_constant("separation", "BoxContainer", default_margin_size * EDSCALE);
theme->set_constant("separation", "HBoxContainer", default_margin_size * EDSCALE);
@@ -1519,10 +1489,7 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) {
// is only relevant for default tooltips.
Ref<StyleBoxFlat> style_tooltip = style_popup->duplicate();
style_tooltip->set_shadow_size(0);
- style_tooltip->set_default_margin(SIDE_LEFT, default_margin_size * EDSCALE * 0.5);
- style_tooltip->set_default_margin(SIDE_TOP, default_margin_size * EDSCALE * 0.5);
- style_tooltip->set_default_margin(SIDE_RIGHT, default_margin_size * EDSCALE * 0.5);
- style_tooltip->set_default_margin(SIDE_BOTTOM, default_margin_size * EDSCALE * 0.5);
+ style_tooltip->set_default_margin_all(default_margin_size * EDSCALE * 0.5);
style_tooltip->set_bg_color(dark_color_3 * Color(0.8, 0.8, 0.8, 0.9));
style_tooltip->set_border_width_all(0);
theme->set_color("font_color", "TooltipLabel", font_hover_color);
diff --git a/editor/editor_toaster.cpp b/editor/editor_toaster.cpp
index e66b782f3c..6a5242f0c6 100644
--- a/editor/editor_toaster.cpp
+++ b/editor/editor_toaster.cpp
@@ -498,10 +498,7 @@ EditorToaster::EditorToaster() {
Ref<StyleBoxFlat> boxes[] = { info_panel_style_background, warning_panel_style_background, error_panel_style_background };
for (int i = 0; i < 3; i++) {
- boxes[i]->set_default_margin(SIDE_LEFT, int(stylebox_radius * 2.5));
- boxes[i]->set_default_margin(SIDE_RIGHT, int(stylebox_radius * 2.5));
- boxes[i]->set_default_margin(SIDE_TOP, 3);
- boxes[i]->set_default_margin(SIDE_BOTTOM, 3);
+ boxes[i]->set_default_margin_individual(int(stylebox_radius * 2.5), 3, int(stylebox_radius * 2.5), 3);
}
// Theming (progress).
diff --git a/editor/editor_zoom_widget.cpp b/editor/editor_zoom_widget.cpp
index e4beea5e5f..88e99d9b30 100644
--- a/editor/editor_zoom_widget.cpp
+++ b/editor/editor_zoom_widget.cpp
@@ -167,7 +167,7 @@ EditorZoomWidget::EditorZoomWidget() {
zoom_minus->set_flat(true);
add_child(zoom_minus);
zoom_minus->connect("pressed", callable_mp(this, &EditorZoomWidget::_button_zoom_minus));
- zoom_minus->set_shortcut(ED_SHORTCUT("canvas_item_editor/zoom_minus", TTR("Zoom Out"), KeyModifierMask::CMD | Key::MINUS));
+ zoom_minus->set_shortcut(ED_SHORTCUT("canvas_item_editor/zoom_minus", TTR("Zoom Out"), KeyModifierMask::CMD_OR_CTRL | Key::MINUS));
zoom_minus->set_shortcut_context(this);
zoom_minus->set_focus_mode(FOCUS_NONE);
@@ -189,7 +189,7 @@ EditorZoomWidget::EditorZoomWidget() {
zoom_plus->set_flat(true);
add_child(zoom_plus);
zoom_plus->connect("pressed", callable_mp(this, &EditorZoomWidget::_button_zoom_plus));
- zoom_plus->set_shortcut(ED_SHORTCUT("canvas_item_editor/zoom_plus", TTR("Zoom In"), KeyModifierMask::CMD | Key::EQUAL)); // Usually direct access key for PLUS
+ zoom_plus->set_shortcut(ED_SHORTCUT("canvas_item_editor/zoom_plus", TTR("Zoom In"), KeyModifierMask::CMD_OR_CTRL | Key::EQUAL)); // Usually direct access key for PLUS
zoom_plus->set_shortcut_context(this);
zoom_plus->set_focus_mode(FOCUS_NONE);
diff --git a/editor/export/export_template_manager.cpp b/editor/export/export_template_manager.cpp
index 0ecbc9a8a3..ceb5b63293 100644
--- a/editor/export/export_template_manager.cpp
+++ b/editor/export/export_template_manager.cpp
@@ -172,7 +172,7 @@ void ExportTemplateManager::_download_template_completed(int p_status, int p_cod
case HTTPRequest::RESULT_BODY_SIZE_LIMIT_EXCEEDED:
case HTTPRequest::RESULT_CONNECTION_ERROR:
case HTTPRequest::RESULT_CHUNKED_BODY_SIZE_MISMATCH:
- case HTTPRequest::RESULT_SSL_HANDSHAKE_ERROR:
+ case HTTPRequest::RESULT_TLS_HANDSHAKE_ERROR:
case HTTPRequest::RESULT_CANT_CONNECT: {
_set_current_progress_status(TTR("Can't connect to the mirror."), true);
} break;
@@ -345,8 +345,8 @@ bool ExportTemplateManager::_humanize_http_status(HTTPRequest *p_request, String
*r_status = TTR("Connection Error");
success = false;
break;
- case HTTPClient::STATUS_SSL_HANDSHAKE_ERROR:
- *r_status = TTR("SSL Handshake Error");
+ case HTTPClient::STATUS_TLS_HANDSHAKE_ERROR:
+ *r_status = TTR("TLS Handshake Error");
success = false;
break;
}
diff --git a/editor/filesystem_dock.cpp b/editor/filesystem_dock.cpp
index ef8173eae4..19b4932d3d 100644
--- a/editor/filesystem_dock.cpp
+++ b/editor/filesystem_dock.cpp
@@ -3021,10 +3021,10 @@ FileSystemDock::FileSystemDock() {
set_name("FileSystem");
path = "res://";
- // `KeyModifierMask::CMD | Key::C` conflicts with other editor shortcuts.
- ED_SHORTCUT("filesystem_dock/copy_path", TTR("Copy Path"), KeyModifierMask::CMD | KeyModifierMask::SHIFT | Key::C);
+ // `KeyModifierMask::CMD_OR_CTRL | Key::C` conflicts with other editor shortcuts.
+ ED_SHORTCUT("filesystem_dock/copy_path", TTR("Copy Path"), KeyModifierMask::CMD_OR_CTRL | KeyModifierMask::SHIFT | Key::C);
ED_SHORTCUT("filesystem_dock/copy_uid", TTR("Copy UID"));
- ED_SHORTCUT("filesystem_dock/duplicate", TTR("Duplicate..."), KeyModifierMask::CMD | Key::D);
+ ED_SHORTCUT("filesystem_dock/duplicate", TTR("Duplicate..."), KeyModifierMask::CMD_OR_CTRL | Key::D);
ED_SHORTCUT("filesystem_dock/delete", TTR("Delete"), Key::KEY_DELETE);
ED_SHORTCUT("filesystem_dock/rename", TTR("Rename..."), Key::F2);
ED_SHORTCUT_OVERRIDE("filesystem_dock/rename", "macos", Key::ENTER);
diff --git a/editor/plugins/animation_library_editor.cpp b/editor/plugins/animation_library_editor.cpp
index 50ba1a71c0..2d20c0cca7 100644
--- a/editor/plugins/animation_library_editor.cpp
+++ b/editor/plugins/animation_library_editor.cpp
@@ -198,11 +198,17 @@ void AnimationLibraryEditor::_file_popup_selected(int p_id) {
} break;
case FILE_MENU_MAKE_LIBRARY_UNIQUE: {
StringName lib_name = file_dialog_library;
-
- Ref<AnimationLibrary> ald = al->duplicate();
-
- // TODO: should probably make all foreign animations assigned to this library
- // unique too.
+ List<StringName> animation_list;
+
+ Ref<AnimationLibrary> ald = memnew(AnimationLibrary);
+ al->get_animation_list(&animation_list);
+ for (const StringName &animation_name : animation_list) {
+ Ref<Animation> animation = al->get_animation(animation_name);
+ if (EditorNode::get_singleton()->is_resource_read_only(animation)) {
+ animation = animation->duplicate();
+ }
+ ald->add_animation(animation_name, animation);
+ }
Ref<EditorUndoRedoManager> undo_redo = EditorNode::get_singleton()->get_undo_redo();
undo_redo->create_action(vformat(TTR("Make Animation Library Unique: %s"), lib_name));
diff --git a/editor/plugins/animation_player_editor_plugin.cpp b/editor/plugins/animation_player_editor_plugin.cpp
index 5ac63ce4db..5406aada09 100644
--- a/editor/plugins/animation_player_editor_plugin.cpp
+++ b/editor/plugins/animation_player_editor_plugin.cpp
@@ -283,26 +283,7 @@ void AnimationPlayerEditor::_animation_selected(int p_which) {
Ref<Animation> anim = player->get_animation(current);
{
- bool animation_library_is_foreign = false;
- if (!anim->get_path().is_resource_file()) {
- int srpos = anim->get_path().find("::");
- if (srpos != -1) {
- String base = anim->get_path().substr(0, srpos);
- if (ResourceLoader::get_resource_type(base) == "PackedScene") {
- if (!get_tree()->get_edited_scene_root() || get_tree()->get_edited_scene_root()->get_scene_file_path() != base) {
- animation_library_is_foreign = true;
- }
- } else {
- if (FileAccess::exists(base + ".import")) {
- animation_library_is_foreign = true;
- }
- }
- }
- } else {
- if (FileAccess::exists(anim->get_path() + ".import")) {
- animation_library_is_foreign = true;
- }
- }
+ bool animation_library_is_foreign = EditorNode::get_singleton()->is_resource_read_only(anim);
track_editor->set_animation(anim, animation_library_is_foreign);
Node *root = player->get_node(player->get_root());
@@ -773,26 +754,7 @@ void AnimationPlayerEditor::_animation_edit() {
if (current != String()) {
Ref<Animation> anim = player->get_animation(current);
- bool animation_library_is_foreign = false;
- if (!anim->get_path().is_resource_file()) {
- int srpos = anim->get_path().find("::");
- if (srpos != -1) {
- String base = anim->get_path().substr(0, srpos);
- if (ResourceLoader::get_resource_type(base) == "PackedScene") {
- if (!get_tree()->get_edited_scene_root() || get_tree()->get_edited_scene_root()->get_scene_file_path() != base) {
- animation_library_is_foreign = true;
- }
- } else {
- if (FileAccess::exists(base + ".import")) {
- animation_library_is_foreign = true;
- }
- }
- }
- } else {
- if (FileAccess::exists(anim->get_path() + ".import")) {
- animation_library_is_foreign = true;
- }
- }
+ bool animation_library_is_foreign = EditorNode::get_singleton()->is_resource_read_only(anim);
track_editor->set_animation(anim, animation_library_is_foreign);
@@ -866,25 +828,7 @@ void AnimationPlayerEditor::_update_player() {
// Check if the global library is foreign since we want to disable options for adding/remove/renaming animations if it is.
Ref<AnimationLibrary> library = player->get_animation_library(K);
if (K == "") {
- if (!library->get_path().is_resource_file()) {
- int srpos = library->get_path().find("::");
- if (srpos != -1) {
- String base = library->get_path().substr(0, srpos);
- if (ResourceLoader::get_resource_type(base) == "PackedScene") {
- if (!get_tree()->get_edited_scene_root() || get_tree()->get_edited_scene_root()->get_scene_file_path() != base) {
- foreign_global_anim_lib = true;
- }
- } else {
- if (FileAccess::exists(base + ".import")) {
- foreign_global_anim_lib = true;
- }
- }
- }
- } else {
- if (FileAccess::exists(library->get_path() + ".import")) {
- foreign_global_anim_lib = true;
- }
- }
+ foreign_global_anim_lib = EditorNode::get_singleton()->is_resource_read_only(library);
}
List<StringName> animlist;
@@ -950,26 +894,7 @@ void AnimationPlayerEditor::_update_player() {
String current = animation->get_item_text(animation->get_selected());
Ref<Animation> anim = player->get_animation(current);
- bool animation_library_is_foreign = false;
- if (!anim->get_path().is_resource_file()) {
- int srpos = anim->get_path().find("::");
- if (srpos != -1) {
- String base = anim->get_path().substr(0, srpos);
- if (ResourceLoader::get_resource_type(base) == "PackedScene") {
- if (!get_tree()->get_edited_scene_root() || get_tree()->get_edited_scene_root()->get_scene_file_path() != base) {
- animation_library_is_foreign = true;
- }
- } else {
- if (FileAccess::exists(base + ".import")) {
- animation_library_is_foreign = true;
- }
- }
- }
- } else {
- if (FileAccess::exists(anim->get_path() + ".import")) {
- animation_library_is_foreign = true;
- }
- }
+ bool animation_library_is_foreign = EditorNode::get_singleton()->is_resource_read_only(anim);
track_editor->set_animation(anim, animation_library_is_foreign);
Node *root = player->get_node(player->get_root());
diff --git a/editor/plugins/asset_library_editor_plugin.cpp b/editor/plugins/asset_library_editor_plugin.cpp
index 1231ac10ab..436113093f 100644
--- a/editor/plugins/asset_library_editor_plugin.cpp
+++ b/editor/plugins/asset_library_editor_plugin.cpp
@@ -101,10 +101,7 @@ void EditorAssetLibraryItem::_bind_methods() {
EditorAssetLibraryItem::EditorAssetLibraryItem() {
Ref<StyleBoxEmpty> border;
border.instantiate();
- border->set_default_margin(SIDE_LEFT, 5 * EDSCALE);
- border->set_default_margin(SIDE_RIGHT, 5 * EDSCALE);
- border->set_default_margin(SIDE_BOTTOM, 5 * EDSCALE);
- border->set_default_margin(SIDE_TOP, 5 * EDSCALE);
+ border->set_default_margin_all(5 * EDSCALE);
add_theme_style_override("panel", border);
HBoxContainer *hb = memnew(HBoxContainer);
@@ -324,7 +321,7 @@ void EditorAssetLibraryItemDownload::_http_download_completed(int p_status, int
status->set_text(TTR("Can't connect."));
} break;
case HTTPRequest::RESULT_CANT_CONNECT:
- case HTTPRequest::RESULT_SSL_HANDSHAKE_ERROR: {
+ case HTTPRequest::RESULT_TLS_HANDSHAKE_ERROR: {
error_text = TTR("Can't connect to host:") + " " + host;
status->set_text(TTR("Can't connect."));
} break;
@@ -577,7 +574,7 @@ void EditorAssetLibrary::_notification(int p_what) {
switch (p_what) {
case NOTIFICATION_READY: {
add_theme_style_override("panel", get_theme_stylebox(SNAME("bg"), SNAME("AssetLib")));
- error_label->raise();
+ error_label->move_to_front();
} break;
case NOTIFICATION_ENTER_TREE:
@@ -651,7 +648,7 @@ void EditorAssetLibrary::shortcut_input(const Ref<InputEvent> &p_event) {
const Ref<InputEventKey> key = p_event;
if (key.is_valid() && key->is_pressed()) {
- if (key->get_keycode_with_modifiers() == (KeyModifierMask::CMD | Key::F) && is_visible_in_tree()) {
+ if (key->is_match(InputEventKey::create_reference(KeyModifierMask::CMD_OR_CTRL | Key::F))) {
filter->grab_focus();
filter->select_all();
accept_event();
@@ -1102,7 +1099,7 @@ void EditorAssetLibrary::_http_request_completed(int p_status, int p_code, const
case HTTPRequest::RESULT_CHUNKED_BODY_SIZE_MISMATCH: {
error_label->set_text(TTR("Connection error, please try again."));
} break;
- case HTTPRequest::RESULT_SSL_HANDSHAKE_ERROR:
+ case HTTPRequest::RESULT_TLS_HANDSHAKE_ERROR:
case HTTPRequest::RESULT_CANT_CONNECT: {
error_label->set_text(TTR("Can't connect to host:") + " " + host);
} break;
@@ -1510,10 +1507,7 @@ EditorAssetLibrary::EditorAssetLibrary(bool p_templates_only) {
Ref<StyleBoxEmpty> border2;
border2.instantiate();
- border2->set_default_margin(SIDE_LEFT, 15 * EDSCALE);
- border2->set_default_margin(SIDE_RIGHT, 35 * EDSCALE);
- border2->set_default_margin(SIDE_BOTTOM, 15 * EDSCALE);
- border2->set_default_margin(SIDE_TOP, 15 * EDSCALE);
+ border2->set_default_margin_individual(15 * EDSCALE, 15 * EDSCALE, 35 * EDSCALE, 15 * EDSCALE);
PanelContainer *library_vb_border = memnew(PanelContainer);
library_scroll->add_child(library_vb_border);
diff --git a/editor/plugins/canvas_item_editor_plugin.cpp b/editor/plugins/canvas_item_editor_plugin.cpp
index 9deb516ec4..070834b33b 100644
--- a/editor/plugins/canvas_item_editor_plugin.cpp
+++ b/editor/plugins/canvas_item_editor_plugin.cpp
@@ -1394,7 +1394,7 @@ bool CanvasItemEditor::_gui_input_rotate(const Ref<InputEvent> &p_event) {
// Start rotation
if (drag_type == DRAG_NONE) {
if (b.is_valid() && b->get_button_index() == MouseButton::LEFT && b->is_pressed()) {
- if ((b->is_command_pressed() && !b->is_alt_pressed() && tool == TOOL_SELECT) || tool == TOOL_ROTATE) {
+ if ((b->is_command_or_control_pressed() && !b->is_alt_pressed() && tool == TOOL_SELECT) || tool == TOOL_ROTATE) {
List<CanvasItem *> selection = _get_edited_canvas_items();
// Remove not movable nodes
@@ -3959,10 +3959,8 @@ void CanvasItemEditor::_notification(int p_what) {
case NOTIFICATION_ENTER_TREE: {
select_sb->set_texture(get_theme_icon(SNAME("EditorRect2D"), SNAME("EditorIcons")));
- for (int i = 0; i < 4; i++) {
- select_sb->set_margin_size(Side(i), 4);
- select_sb->set_default_margin(Side(i), 4);
- }
+ select_sb->set_margin_size_all(4);
+ select_sb->set_default_margin_all(4);
AnimationPlayerEditor::get_singleton()->get_track_editor()->connect("visibility_changed", callable_mp(this, &CanvasItemEditor::_keying_changed));
_keying_changed();
@@ -5045,7 +5043,7 @@ CanvasItemEditor::CanvasItemEditor() {
{ int32_t(KeyModifierMask::SHIFT | Key::KEY_1), int32_t(KeyModifierMask::SHIFT | Key::KP_1) });
ED_SHORTCUT_ARRAY("canvas_item_editor/zoom_100_percent", TTR("Zoom to 100%"),
- { int32_t(Key::KEY_1), int32_t(KeyModifierMask::CMD | Key::KEY_0), int32_t(Key::KP_1), int32_t(KeyModifierMask::CMD | Key::KP_0) });
+ { int32_t(Key::KEY_1), int32_t(KeyModifierMask::CMD_OR_CTRL | Key::KEY_0), int32_t(Key::KP_1), int32_t(KeyModifierMask::CMD_OR_CTRL | Key::KP_0) });
ED_SHORTCUT_ARRAY("canvas_item_editor/zoom_200_percent", TTR("Zoom to 200%"),
{ int32_t(Key::KEY_2), int32_t(Key::KP_2) });
@@ -5104,7 +5102,7 @@ CanvasItemEditor::CanvasItemEditor() {
select_button->set_pressed(true);
select_button->set_shortcut(ED_SHORTCUT("canvas_item_editor/select_mode", TTR("Select Mode"), Key::Q));
select_button->set_shortcut_context(this);
- select_button->set_tooltip_text(keycode_get_string((Key)KeyModifierMask::CMD) + TTR("Drag: Rotate selected node around pivot.") + "\n" + TTR("Alt+Drag: Move selected node.") + "\n" + keycode_get_string((Key)KeyModifierMask::CMD) + TTR("Alt+Drag: Scale selected node.") + "\n" + TTR("V: Set selected node's pivot position.") + "\n" + TTR("Alt+RMB: Show list of all nodes at position clicked, including locked.") + "\n" + keycode_get_string((Key)KeyModifierMask::CMD) + TTR("RMB: Add node at position clicked."));
+ select_button->set_tooltip_text(keycode_get_string((Key)KeyModifierMask::CMD_OR_CTRL) + TTR("Drag: Rotate selected node around pivot.") + "\n" + TTR("Alt+Drag: Move selected node.") + "\n" + keycode_get_string((Key)KeyModifierMask::CMD_OR_CTRL) + TTR("Alt+Drag: Scale selected node.") + "\n" + TTR("V: Set selected node's pivot position.") + "\n" + TTR("Alt+RMB: Show list of all nodes at position clicked, including locked.") + "\n" + keycode_get_string((Key)KeyModifierMask::CMD_OR_CTRL) + TTR("RMB: Add node at position clicked."));
main_menu_hbox->add_child(memnew(VSeparator));
@@ -5229,7 +5227,7 @@ CanvasItemEditor::CanvasItemEditor() {
lock_button->connect("pressed", callable_mp(this, &CanvasItemEditor::_popup_callback).bind(LOCK_SELECTED));
lock_button->set_tooltip_text(TTR("Lock selected node, preventing selection and movement."));
// Define the shortcut globally (without a context) so that it works if the Scene tree dock is currently focused.
- lock_button->set_shortcut(ED_SHORTCUT("editor/lock_selected_nodes", TTR("Lock Selected Node(s)"), KeyModifierMask::CMD | Key::L));
+ lock_button->set_shortcut(ED_SHORTCUT("editor/lock_selected_nodes", TTR("Lock Selected Node(s)"), KeyModifierMask::CMD_OR_CTRL | Key::L));
unlock_button = memnew(Button);
unlock_button->set_flat(true);
@@ -5237,7 +5235,7 @@ CanvasItemEditor::CanvasItemEditor() {
unlock_button->connect("pressed", callable_mp(this, &CanvasItemEditor::_popup_callback).bind(UNLOCK_SELECTED));
unlock_button->set_tooltip_text(TTR("Unlock selected node, allowing selection and movement."));
// Define the shortcut globally (without a context) so that it works if the Scene tree dock is currently focused.
- unlock_button->set_shortcut(ED_SHORTCUT("editor/unlock_selected_nodes", TTR("Unlock Selected Node(s)"), KeyModifierMask::CMD | KeyModifierMask::SHIFT | Key::L));
+ unlock_button->set_shortcut(ED_SHORTCUT("editor/unlock_selected_nodes", TTR("Unlock Selected Node(s)"), KeyModifierMask::CMD_OR_CTRL | KeyModifierMask::SHIFT | Key::L));
group_button = memnew(Button);
group_button->set_flat(true);
@@ -5245,7 +5243,7 @@ CanvasItemEditor::CanvasItemEditor() {
group_button->connect("pressed", callable_mp(this, &CanvasItemEditor::_popup_callback).bind(GROUP_SELECTED));
group_button->set_tooltip_text(TTR("Make selected node's children not selectable."));
// Define the shortcut globally (without a context) so that it works if the Scene tree dock is currently focused.
- group_button->set_shortcut(ED_SHORTCUT("editor/group_selected_nodes", TTR("Group Selected Node(s)"), KeyModifierMask::CMD | Key::G));
+ group_button->set_shortcut(ED_SHORTCUT("editor/group_selected_nodes", TTR("Group Selected Node(s)"), KeyModifierMask::CMD_OR_CTRL | Key::G));
ungroup_button = memnew(Button);
ungroup_button->set_flat(true);
@@ -5253,7 +5251,7 @@ CanvasItemEditor::CanvasItemEditor() {
ungroup_button->connect("pressed", callable_mp(this, &CanvasItemEditor::_popup_callback).bind(UNGROUP_SELECTED));
ungroup_button->set_tooltip_text(TTR("Make selected node's children selectable."));
// Define the shortcut globally (without a context) so that it works if the Scene tree dock is currently focused.
- ungroup_button->set_shortcut(ED_SHORTCUT("editor/ungroup_selected_nodes", TTR("Ungroup Selected Node(s)"), KeyModifierMask::CMD | KeyModifierMask::SHIFT | Key::G));
+ ungroup_button->set_shortcut(ED_SHORTCUT("editor/ungroup_selected_nodes", TTR("Ungroup Selected Node(s)"), KeyModifierMask::CMD_OR_CTRL | KeyModifierMask::SHIFT | Key::G));
main_menu_hbox->add_child(memnew(VSeparator));
@@ -5267,7 +5265,7 @@ CanvasItemEditor::CanvasItemEditor() {
p->set_hide_on_checkable_item_selection(false);
p->add_shortcut(ED_SHORTCUT("canvas_item_editor/skeleton_show_bones", TTR("Show Bones")), SKELETON_SHOW_BONES);
p->add_separator();
- p->add_shortcut(ED_SHORTCUT("canvas_item_editor/skeleton_make_bones", TTR("Make Bone2D Node(s) from Node(s)"), KeyModifierMask::CMD | KeyModifierMask::SHIFT | Key::B), SKELETON_MAKE_BONES);
+ p->add_shortcut(ED_SHORTCUT("canvas_item_editor/skeleton_make_bones", TTR("Make Bone2D Node(s) from Node(s)"), KeyModifierMask::CMD_OR_CTRL | KeyModifierMask::SHIFT | Key::B), SKELETON_MAKE_BONES);
p->connect("id_pressed", callable_mp(this, &CanvasItemEditor::_popup_callback));
main_menu_hbox->add_child(memnew(VSeparator));
@@ -5301,7 +5299,7 @@ CanvasItemEditor::CanvasItemEditor() {
grid_menu->add_radio_check_item(TTR("Show When Snapping"), GRID_VISIBILITY_SHOW_WHEN_SNAPPING);
grid_menu->add_radio_check_item(TTR("Hide"), GRID_VISIBILITY_HIDE);
grid_menu->add_separator();
- grid_menu->add_shortcut(ED_SHORTCUT("canvas_item_editor/toggle_grid", TTR("Toggle Grid"), KeyModifierMask::CMD | Key::APOSTROPHE));
+ grid_menu->add_shortcut(ED_SHORTCUT("canvas_item_editor/toggle_grid", TTR("Toggle Grid"), KeyModifierMask::CMD_OR_CTRL | Key::APOSTROPHE));
p->add_child(grid_menu);
p->add_submenu_item(TTR("Grid"), "GridMenu");
@@ -5318,7 +5316,7 @@ CanvasItemEditor::CanvasItemEditor() {
p->add_shortcut(ED_SHORTCUT("canvas_item_editor/frame_selection", TTR("Frame Selection"), KeyModifierMask::SHIFT | Key::F), VIEW_FRAME_TO_SELECTION);
p->add_shortcut(ED_SHORTCUT("canvas_item_editor/clear_guides", TTR("Clear Guides")), CLEAR_GUIDES);
p->add_separator();
- p->add_check_shortcut(ED_SHORTCUT("canvas_item_editor/preview_canvas_scale", TTR("Preview Canvas Scale"), KeyModifierMask::SHIFT | KeyModifierMask::CMD | Key::P), PREVIEW_CANVAS_SCALE);
+ p->add_check_shortcut(ED_SHORTCUT("canvas_item_editor/preview_canvas_scale", TTR("Preview Canvas Scale"), KeyModifierMask::SHIFT | KeyModifierMask::CMD_OR_CTRL | Key::P), PREVIEW_CANVAS_SCALE);
main_menu_hbox->add_child(memnew(VSeparator));
@@ -5388,7 +5386,7 @@ CanvasItemEditor::CanvasItemEditor() {
p = animation_menu->get_popup();
p->add_shortcut(ED_GET_SHORTCUT("canvas_item_editor/anim_insert_key"), ANIM_INSERT_KEY);
- p->add_shortcut(ED_SHORTCUT("canvas_item_editor/anim_insert_key_existing_tracks", TTR("Insert Key (Existing Tracks)"), KeyModifierMask::CMD + Key::INSERT), ANIM_INSERT_KEY_EXISTING);
+ p->add_shortcut(ED_SHORTCUT("canvas_item_editor/anim_insert_key_existing_tracks", TTR("Insert Key (Existing Tracks)"), KeyModifierMask::CMD_OR_CTRL + Key::INSERT), ANIM_INSERT_KEY_EXISTING);
p->add_separator();
p->add_shortcut(ED_SHORTCUT("canvas_item_editor/anim_copy_pose", TTR("Copy Pose")), ANIM_COPY_POSE);
p->add_shortcut(ED_SHORTCUT("canvas_item_editor/anim_paste_pose", TTR("Paste Pose")), ANIM_PASTE_POSE);
diff --git a/editor/plugins/material_editor_plugin.cpp b/editor/plugins/material_editor_plugin.cpp
index 76d05624d6..fe7713f175 100644
--- a/editor/plugins/material_editor_plugin.cpp
+++ b/editor/plugins/material_editor_plugin.cpp
@@ -40,6 +40,19 @@
#include "scene/resources/particle_process_material.h"
#include "scene/resources/sky_material.h"
+void MaterialEditor::gui_input(const Ref<InputEvent> &p_event) {
+ ERR_FAIL_COND(p_event.is_null());
+
+ Ref<InputEventMouseMotion> mm = p_event;
+ if (mm.is_valid() && (mm->get_button_mask() & MouseButton::MASK_LEFT) != MouseButton::NONE) {
+ rot.x -= mm->get_relative().y * 0.01;
+ rot.y -= mm->get_relative().x * 0.01;
+
+ rot.x = CLAMP(rot.x, -Math_PI / 2, Math_PI / 2);
+ _update_rotation();
+ }
+}
+
void MaterialEditor::_update_theme_item_cache() {
Control::_update_theme_item_cache();
@@ -77,6 +90,13 @@ void MaterialEditor::_notification(int p_what) {
}
}
+void MaterialEditor::_update_rotation() {
+ Transform3D t;
+ t.basis.rotate(Vector3(0, 1, 0), -rot.y);
+ t.basis.rotate(Vector3(1, 0, 0), -rot.x);
+ rotation->set_transform(t);
+}
+
void MaterialEditor::edit(Ref<Material> p_material, const Ref<Environment> &p_env) {
material = p_material;
camera->set_environment(p_env);
@@ -102,6 +122,10 @@ void MaterialEditor::edit(Ref<Material> p_material, const Ref<Environment> &p_en
} else {
hide();
}
+
+ rot.x = Math::deg_to_rad(-15.0);
+ rot.y = Math::deg_to_rad(30.0);
+ _update_rotation();
}
void MaterialEditor::_button_pressed(Node *p_button) {
@@ -130,9 +154,6 @@ void MaterialEditor::_button_pressed(Node *p_button) {
}
}
-void MaterialEditor::_bind_methods() {
-}
-
MaterialEditor::MaterialEditor() {
// canvas item
@@ -163,7 +184,7 @@ MaterialEditor::MaterialEditor() {
viewport->set_msaa_3d(Viewport::MSAA_4X);
camera = memnew(Camera3D);
- camera->set_transform(Transform3D(Basis(), Vector3(0, 0, 3)));
+ camera->set_transform(Transform3D(Basis(), Vector3(0, 0, 1.1)));
// Use low field of view so the sphere/box is fully encompassed within the preview,
// without much distortion.
camera->set_perspective(20, 0.1, 10);
@@ -183,18 +204,17 @@ MaterialEditor::MaterialEditor() {
light2->set_color(Color(0.7, 0.7, 0.7));
viewport->add_child(light2);
+ rotation = memnew(Node3D);
+ viewport->add_child(rotation);
+
sphere_instance = memnew(MeshInstance3D);
- viewport->add_child(sphere_instance);
+ rotation->add_child(sphere_instance);
box_instance = memnew(MeshInstance3D);
- viewport->add_child(box_instance);
-
- Transform3D box_xform;
- box_xform.basis.rotate(Vector3(1, 0, 0), Math::deg_to_rad(25.0));
- box_xform.basis = box_xform.basis * Basis().rotated(Vector3(0, 1, 0), Math::deg_to_rad(-25.0));
- box_xform.basis.scale(Vector3(0.7, 0.7, 0.7));
- box_xform.origin.y = 0.05;
- box_instance->set_transform(box_xform);
+ rotation->add_child(box_instance);
+
+ box_instance->set_transform(Transform3D() * 0.25);
+ sphere_instance->set_transform(Transform3D() * 0.375);
sphere_mesh.instantiate();
sphere_instance->set_mesh(sphere_mesh);
diff --git a/editor/plugins/material_editor_plugin.h b/editor/plugins/material_editor_plugin.h
index 7ce6deee65..8e64434d8b 100644
--- a/editor/plugins/material_editor_plugin.h
+++ b/editor/plugins/material_editor_plugin.h
@@ -45,11 +45,14 @@ class SubViewportContainer;
class MaterialEditor : public Control {
GDCLASS(MaterialEditor, Control);
+ Vector2 rot = Vector2();
+
HBoxContainer *layout_2d = nullptr;
ColorRect *rect_instance = nullptr;
SubViewportContainer *vc = nullptr;
SubViewport *viewport = nullptr;
+ Node3D *rotation = nullptr;
MeshInstance3D *sphere_instance = nullptr;
MeshInstance3D *box_instance = nullptr;
DirectionalLight3D *light1 = nullptr;
@@ -87,7 +90,8 @@ class MaterialEditor : public Control {
protected:
virtual void _update_theme_item_cache() override;
void _notification(int p_what);
- static void _bind_methods();
+ void gui_input(const Ref<InputEvent> &p_event) override;
+ void _update_rotation();
public:
void edit(Ref<Material> p_material, const Ref<Environment> &p_env);
diff --git a/editor/plugins/node_3d_editor_plugin.cpp b/editor/plugins/node_3d_editor_plugin.cpp
index 13fd406e87..b9f3015837 100644
--- a/editor/plugins/node_3d_editor_plugin.cpp
+++ b/editor/plugins/node_3d_editor_plugin.cpp
@@ -1586,7 +1586,7 @@ void Node3DEditorViewport::_sinput(const Ref<InputEvent> &p_event) {
clicked = ObjectID();
- if ((spatial_editor->get_tool_mode() == Node3DEditor::TOOL_MODE_SELECT && b->is_command_pressed()) || spatial_editor->get_tool_mode() == Node3DEditor::TOOL_MODE_ROTATE) {
+ if ((spatial_editor->get_tool_mode() == Node3DEditor::TOOL_MODE_SELECT && b->is_command_or_control_pressed()) || spatial_editor->get_tool_mode() == Node3DEditor::TOOL_MODE_ROTATE) {
begin_transform(TRANSFORM_ROTATE, false);
break;
}
@@ -4817,7 +4817,7 @@ Node3DEditorViewport::Node3DEditorViewport(Node3DEditor *p_spatial_editor, int p
preview_camera = memnew(CheckBox);
preview_camera->set_text(TTR("Preview"));
- preview_camera->set_shortcut(ED_SHORTCUT("spatial_editor/toggle_camera_preview", TTR("Toggle Camera Preview"), KeyModifierMask::CMD | Key::P));
+ preview_camera->set_shortcut(ED_SHORTCUT("spatial_editor/toggle_camera_preview", TTR("Toggle Camera Preview"), KeyModifierMask::CMD_OR_CTRL | Key::P));
vbox->add_child(preview_camera);
preview_camera->set_h_size_flags(0);
preview_camera->hide();
@@ -7751,7 +7751,7 @@ Node3DEditor::Node3DEditor() {
tool_button[TOOL_MODE_SELECT]->connect("pressed", callable_mp(this, &Node3DEditor::_menu_item_pressed).bind(MENU_TOOL_SELECT));
tool_button[TOOL_MODE_SELECT]->set_shortcut(ED_SHORTCUT("spatial_editor/tool_select", TTR("Select Mode"), Key::Q));
tool_button[TOOL_MODE_SELECT]->set_shortcut_context(this);
- tool_button[TOOL_MODE_SELECT]->set_tooltip_text(keycode_get_string((Key)KeyModifierMask::CMD) + TTR("Drag: Rotate selected node around pivot.") + "\n" + TTR("Alt+RMB: Show list of all nodes at position clicked, including locked."));
+ tool_button[TOOL_MODE_SELECT]->set_tooltip_text(keycode_get_string((Key)KeyModifierMask::CMD_OR_CTRL) + TTR("Drag: Rotate selected node around pivot.") + "\n" + TTR("Alt+RMB: Show list of all nodes at position clicked, including locked."));
main_menu_hbox->add_child(memnew(VSeparator));
tool_button[TOOL_MODE_MOVE] = memnew(Button);
@@ -7794,7 +7794,7 @@ Node3DEditor::Node3DEditor() {
tool_button[TOOL_LOCK_SELECTED]->connect("pressed", callable_mp(this, &Node3DEditor::_menu_item_pressed).bind(MENU_LOCK_SELECTED));
tool_button[TOOL_LOCK_SELECTED]->set_tooltip_text(TTR("Lock selected node, preventing selection and movement."));
// Define the shortcut globally (without a context) so that it works if the Scene tree dock is currently focused.
- tool_button[TOOL_LOCK_SELECTED]->set_shortcut(ED_SHORTCUT("editor/lock_selected_nodes", TTR("Lock Selected Node(s)"), KeyModifierMask::CMD | Key::L));
+ tool_button[TOOL_LOCK_SELECTED]->set_shortcut(ED_SHORTCUT("editor/lock_selected_nodes", TTR("Lock Selected Node(s)"), KeyModifierMask::CMD_OR_CTRL | Key::L));
tool_button[TOOL_UNLOCK_SELECTED] = memnew(Button);
main_menu_hbox->add_child(tool_button[TOOL_UNLOCK_SELECTED]);
@@ -7802,7 +7802,7 @@ Node3DEditor::Node3DEditor() {
tool_button[TOOL_UNLOCK_SELECTED]->connect("pressed", callable_mp(this, &Node3DEditor::_menu_item_pressed).bind(MENU_UNLOCK_SELECTED));
tool_button[TOOL_UNLOCK_SELECTED]->set_tooltip_text(TTR("Unlock selected node, allowing selection and movement."));
// Define the shortcut globally (without a context) so that it works if the Scene tree dock is currently focused.
- tool_button[TOOL_UNLOCK_SELECTED]->set_shortcut(ED_SHORTCUT("editor/unlock_selected_nodes", TTR("Unlock Selected Node(s)"), KeyModifierMask::CMD | KeyModifierMask::SHIFT | Key::L));
+ tool_button[TOOL_UNLOCK_SELECTED]->set_shortcut(ED_SHORTCUT("editor/unlock_selected_nodes", TTR("Unlock Selected Node(s)"), KeyModifierMask::CMD_OR_CTRL | KeyModifierMask::SHIFT | Key::L));
tool_button[TOOL_GROUP_SELECTED] = memnew(Button);
main_menu_hbox->add_child(tool_button[TOOL_GROUP_SELECTED]);
@@ -7810,7 +7810,7 @@ Node3DEditor::Node3DEditor() {
tool_button[TOOL_GROUP_SELECTED]->connect("pressed", callable_mp(this, &Node3DEditor::_menu_item_pressed).bind(MENU_GROUP_SELECTED));
tool_button[TOOL_GROUP_SELECTED]->set_tooltip_text(TTR("Make selected node's children not selectable."));
// Define the shortcut globally (without a context) so that it works if the Scene tree dock is currently focused.
- tool_button[TOOL_GROUP_SELECTED]->set_shortcut(ED_SHORTCUT("editor/group_selected_nodes", TTR("Group Selected Node(s)"), KeyModifierMask::CMD | Key::G));
+ tool_button[TOOL_GROUP_SELECTED]->set_shortcut(ED_SHORTCUT("editor/group_selected_nodes", TTR("Group Selected Node(s)"), KeyModifierMask::CMD_OR_CTRL | Key::G));
tool_button[TOOL_UNGROUP_SELECTED] = memnew(Button);
main_menu_hbox->add_child(tool_button[TOOL_UNGROUP_SELECTED]);
@@ -7818,7 +7818,7 @@ Node3DEditor::Node3DEditor() {
tool_button[TOOL_UNGROUP_SELECTED]->connect("pressed", callable_mp(this, &Node3DEditor::_menu_item_pressed).bind(MENU_UNGROUP_SELECTED));
tool_button[TOOL_UNGROUP_SELECTED]->set_tooltip_text(TTR("Make selected node's children selectable."));
// Define the shortcut globally (without a context) so that it works if the Scene tree dock is currently focused.
- tool_button[TOOL_UNGROUP_SELECTED]->set_shortcut(ED_SHORTCUT("editor/ungroup_selected_nodes", TTR("Ungroup Selected Node(s)"), KeyModifierMask::CMD | KeyModifierMask::SHIFT | Key::G));
+ tool_button[TOOL_UNGROUP_SELECTED]->set_shortcut(ED_SHORTCUT("editor/ungroup_selected_nodes", TTR("Ungroup Selected Node(s)"), KeyModifierMask::CMD_OR_CTRL | KeyModifierMask::SHIFT | Key::G));
main_menu_hbox->add_child(memnew(VSeparator));
@@ -7895,12 +7895,12 @@ Node3DEditor::Node3DEditor() {
ED_SHORTCUT("spatial_editor/insert_anim_key", TTR("Insert Animation Key"), Key::K);
ED_SHORTCUT("spatial_editor/focus_origin", TTR("Focus Origin"), Key::O);
ED_SHORTCUT("spatial_editor/focus_selection", TTR("Focus Selection"), Key::F);
- ED_SHORTCUT("spatial_editor/align_transform_with_view", TTR("Align Transform with View"), KeyModifierMask::ALT + KeyModifierMask::CMD + Key::M);
- ED_SHORTCUT("spatial_editor/align_rotation_with_view", TTR("Align Rotation with View"), KeyModifierMask::ALT + KeyModifierMask::CMD + Key::F);
+ ED_SHORTCUT("spatial_editor/align_transform_with_view", TTR("Align Transform with View"), KeyModifierMask::ALT + KeyModifierMask::CMD_OR_CTRL + Key::M);
+ ED_SHORTCUT("spatial_editor/align_rotation_with_view", TTR("Align Rotation with View"), KeyModifierMask::ALT + KeyModifierMask::CMD_OR_CTRL + Key::F);
ED_SHORTCUT("spatial_editor/freelook_toggle", TTR("Toggle Freelook"), KeyModifierMask::SHIFT + Key::F);
- ED_SHORTCUT("spatial_editor/decrease_fov", TTR("Decrease Field of View"), KeyModifierMask::CMD + Key::EQUAL); // Usually direct access key for `KEY_PLUS`.
- ED_SHORTCUT("spatial_editor/increase_fov", TTR("Increase Field of View"), KeyModifierMask::CMD + Key::MINUS);
- ED_SHORTCUT("spatial_editor/reset_fov", TTR("Reset Field of View to Default"), KeyModifierMask::CMD + Key::KEY_0);
+ ED_SHORTCUT("spatial_editor/decrease_fov", TTR("Decrease Field of View"), KeyModifierMask::CMD_OR_CTRL + Key::EQUAL); // Usually direct access key for `KEY_PLUS`.
+ ED_SHORTCUT("spatial_editor/increase_fov", TTR("Increase Field of View"), KeyModifierMask::CMD_OR_CTRL + Key::MINUS);
+ ED_SHORTCUT("spatial_editor/reset_fov", TTR("Reset Field of View to Default"), KeyModifierMask::CMD_OR_CTRL + Key::KEY_0);
PopupMenu *p;
@@ -7940,12 +7940,12 @@ Node3DEditor::Node3DEditor() {
accept = memnew(AcceptDialog);
EditorNode::get_singleton()->get_gui_base()->add_child(accept);
- p->add_radio_check_shortcut(ED_SHORTCUT("spatial_editor/1_viewport", TTR("1 Viewport"), KeyModifierMask::CMD + Key::KEY_1), MENU_VIEW_USE_1_VIEWPORT);
- p->add_radio_check_shortcut(ED_SHORTCUT("spatial_editor/2_viewports", TTR("2 Viewports"), KeyModifierMask::CMD + Key::KEY_2), MENU_VIEW_USE_2_VIEWPORTS);
- p->add_radio_check_shortcut(ED_SHORTCUT("spatial_editor/2_viewports_alt", TTR("2 Viewports (Alt)"), KeyModifierMask::ALT + KeyModifierMask::CMD + Key::KEY_2), MENU_VIEW_USE_2_VIEWPORTS_ALT);
- p->add_radio_check_shortcut(ED_SHORTCUT("spatial_editor/3_viewports", TTR("3 Viewports"), KeyModifierMask::CMD + Key::KEY_3), MENU_VIEW_USE_3_VIEWPORTS);
- p->add_radio_check_shortcut(ED_SHORTCUT("spatial_editor/3_viewports_alt", TTR("3 Viewports (Alt)"), KeyModifierMask::ALT + KeyModifierMask::CMD + Key::KEY_3), MENU_VIEW_USE_3_VIEWPORTS_ALT);
- p->add_radio_check_shortcut(ED_SHORTCUT("spatial_editor/4_viewports", TTR("4 Viewports"), KeyModifierMask::CMD + Key::KEY_4), MENU_VIEW_USE_4_VIEWPORTS);
+ p->add_radio_check_shortcut(ED_SHORTCUT("spatial_editor/1_viewport", TTR("1 Viewport"), KeyModifierMask::CMD_OR_CTRL + Key::KEY_1), MENU_VIEW_USE_1_VIEWPORT);
+ p->add_radio_check_shortcut(ED_SHORTCUT("spatial_editor/2_viewports", TTR("2 Viewports"), KeyModifierMask::CMD_OR_CTRL + Key::KEY_2), MENU_VIEW_USE_2_VIEWPORTS);
+ p->add_radio_check_shortcut(ED_SHORTCUT("spatial_editor/2_viewports_alt", TTR("2 Viewports (Alt)"), KeyModifierMask::ALT + KeyModifierMask::CMD_OR_CTRL + Key::KEY_2), MENU_VIEW_USE_2_VIEWPORTS_ALT);
+ p->add_radio_check_shortcut(ED_SHORTCUT("spatial_editor/3_viewports", TTR("3 Viewports"), KeyModifierMask::CMD_OR_CTRL + Key::KEY_3), MENU_VIEW_USE_3_VIEWPORTS);
+ p->add_radio_check_shortcut(ED_SHORTCUT("spatial_editor/3_viewports_alt", TTR("3 Viewports (Alt)"), KeyModifierMask::ALT + KeyModifierMask::CMD_OR_CTRL + Key::KEY_3), MENU_VIEW_USE_3_VIEWPORTS_ALT);
+ p->add_radio_check_shortcut(ED_SHORTCUT("spatial_editor/4_viewports", TTR("4 Viewports"), KeyModifierMask::CMD_OR_CTRL + Key::KEY_4), MENU_VIEW_USE_4_VIEWPORTS);
p->add_separator();
p->add_submenu_item(TTR("Gizmos"), "GizmosMenu");
diff --git a/editor/plugins/path_2d_editor_plugin.cpp b/editor/plugins/path_2d_editor_plugin.cpp
index dc6dfd81c2..c8bd4c1d05 100644
--- a/editor/plugins/path_2d_editor_plugin.cpp
+++ b/editor/plugins/path_2d_editor_plugin.cpp
@@ -150,7 +150,7 @@ bool Path2DEditor::forward_gui_input(const Ref<InputEvent> &p_event) {
}
// Check for point creation.
- if (mb->is_pressed() && mb->get_button_index() == MouseButton::LEFT && ((mb->is_command_pressed() && mode == MODE_EDIT) || mode == MODE_CREATE)) {
+ if (mb->is_pressed() && mb->get_button_index() == MouseButton::LEFT && ((mb->is_command_or_control_pressed() && mode == MODE_EDIT) || mode == MODE_CREATE)) {
Ref<Curve2D> curve = node->get_curve();
undo_redo->create_action(TTR("Add Point to Curve"));
@@ -537,7 +537,7 @@ Path2DEditor::Path2DEditor() {
curve_edit->set_flat(true);
curve_edit->set_toggle_mode(true);
curve_edit->set_focus_mode(Control::FOCUS_NONE);
- curve_edit->set_tooltip_text(TTR("Select Points") + "\n" + TTR("Shift+Drag: Select Control Points") + "\n" + keycode_get_string((Key)KeyModifierMask::CMD) + TTR("Click: Add Point") + "\n" + TTR("Left Click: Split Segment (in curve)") + "\n" + TTR("Right Click: Delete Point"));
+ curve_edit->set_tooltip_text(TTR("Select Points") + "\n" + TTR("Shift+Drag: Select Control Points") + "\n" + keycode_get_string((Key)KeyModifierMask::CMD_OR_CTRL) + TTR("Click: Add Point") + "\n" + TTR("Left Click: Split Segment (in curve)") + "\n" + TTR("Right Click: Delete Point"));
curve_edit->connect("pressed", callable_mp(this, &Path2DEditor::_mode_selected).bind(MODE_EDIT));
base_hb->add_child(curve_edit);
diff --git a/editor/plugins/path_3d_editor_plugin.cpp b/editor/plugins/path_3d_editor_plugin.cpp
index 1029b06638..adfaf11264 100644
--- a/editor/plugins/path_3d_editor_plugin.cpp
+++ b/editor/plugins/path_3d_editor_plugin.cpp
@@ -597,7 +597,7 @@ Path3DEditorPlugin::Path3DEditorPlugin() {
curve_edit->set_toggle_mode(true);
curve_edit->hide();
curve_edit->set_focus_mode(Control::FOCUS_NONE);
- curve_edit->set_tooltip_text(TTR("Select Points") + "\n" + TTR("Shift+Drag: Select Control Points") + "\n" + keycode_get_string((Key)KeyModifierMask::CMD) + TTR("Click: Add Point") + "\n" + TTR("Right Click: Delete Point"));
+ curve_edit->set_tooltip_text(TTR("Select Points") + "\n" + TTR("Shift+Drag: Select Control Points") + "\n" + keycode_get_string((Key)KeyModifierMask::CMD_OR_CTRL) + TTR("Click: Add Point") + "\n" + TTR("Right Click: Delete Point"));
Node3DEditor::get_singleton()->add_control_to_menu_panel(curve_edit);
curve_create = memnew(Button);
diff --git a/editor/plugins/polygon_2d_editor_plugin.cpp b/editor/plugins/polygon_2d_editor_plugin.cpp
index 328ad0ccbc..58a3a07c43 100644
--- a/editor/plugins/polygon_2d_editor_plugin.cpp
+++ b/editor/plugins/polygon_2d_editor_plugin.cpp
@@ -627,11 +627,11 @@ void Polygon2DEditor::_uv_input(const Ref<InputEvent> &p_input) {
}
if (uv_move_current == UV_MODE_EDIT_POINT) {
- if (mb->is_shift_pressed() && mb->is_command_pressed()) {
+ if (mb->is_shift_pressed() && mb->is_command_or_control_pressed()) {
uv_move_current = UV_MODE_SCALE;
} else if (mb->is_shift_pressed()) {
uv_move_current = UV_MODE_MOVE;
- } else if (mb->is_command_pressed()) {
+ } else if (mb->is_command_or_control_pressed()) {
uv_move_current = UV_MODE_ROTATE;
}
}
diff --git a/editor/plugins/script_editor_plugin.cpp b/editor/plugins/script_editor_plugin.cpp
index 953f72bd05..0a111aeb49 100644
--- a/editor/plugins/script_editor_plugin.cpp
+++ b/editor/plugins/script_editor_plugin.cpp
@@ -3363,15 +3363,15 @@ void ScriptEditor::_update_selected_editor_menu() {
EditorHelp *eh = Object::cast_to<EditorHelp>(tab_container->get_current_tab_control());
script_search_menu->get_popup()->clear();
if (eh) {
- script_search_menu->get_popup()->add_shortcut(ED_SHORTCUT("script_editor/find", TTR("Find..."), KeyModifierMask::CMD | Key::F), HELP_SEARCH_FIND);
+ script_search_menu->get_popup()->add_shortcut(ED_SHORTCUT("script_editor/find", TTR("Find..."), KeyModifierMask::CMD_OR_CTRL | Key::F), HELP_SEARCH_FIND);
script_search_menu->get_popup()->add_shortcut(ED_SHORTCUT("script_editor/find_next", TTR("Find Next"), Key::F3), HELP_SEARCH_FIND_NEXT);
script_search_menu->get_popup()->add_shortcut(ED_SHORTCUT("script_editor/find_previous", TTR("Find Previous"), KeyModifierMask::SHIFT | Key::F3), HELP_SEARCH_FIND_PREVIOUS);
script_search_menu->get_popup()->add_separator();
- script_search_menu->get_popup()->add_shortcut(ED_SHORTCUT("script_editor/find_in_files", TTR("Find in Files"), KeyModifierMask::CMD | KeyModifierMask::SHIFT | Key::F), SEARCH_IN_FILES);
+ script_search_menu->get_popup()->add_shortcut(ED_SHORTCUT("script_editor/find_in_files", TTR("Find in Files"), KeyModifierMask::CMD_OR_CTRL | KeyModifierMask::SHIFT | Key::F), SEARCH_IN_FILES);
script_search_menu->show();
} else {
if (tab_container->get_tab_count() == 0) {
- script_search_menu->get_popup()->add_shortcut(ED_SHORTCUT("script_editor/find_in_files", TTR("Find in Files"), KeyModifierMask::CMD | KeyModifierMask::SHIFT | Key::F), SEARCH_IN_FILES);
+ script_search_menu->get_popup()->add_shortcut(ED_SHORTCUT("script_editor/find_in_files", TTR("Find in Files"), KeyModifierMask::CMD_OR_CTRL | KeyModifierMask::SHIFT | Key::F), SEARCH_IN_FILES);
script_search_menu->show();
} else {
script_search_menu->hide();
@@ -3757,8 +3757,8 @@ ScriptEditor::ScriptEditor() {
ED_SHORTCUT("script_editor/window_move_up", TTR("Move Up"), KeyModifierMask::SHIFT | KeyModifierMask::ALT | Key::UP);
ED_SHORTCUT("script_editor/window_move_down", TTR("Move Down"), KeyModifierMask::SHIFT | KeyModifierMask::ALT | Key::DOWN);
// FIXME: These should be `Key::GREATER` and `Key::LESS` but those don't work.
- ED_SHORTCUT("script_editor/next_script", TTR("Next Script"), KeyModifierMask::CMD | KeyModifierMask::SHIFT | Key::PERIOD);
- ED_SHORTCUT("script_editor/prev_script", TTR("Previous Script"), KeyModifierMask::CMD | KeyModifierMask::SHIFT | Key::COMMA);
+ ED_SHORTCUT("script_editor/next_script", TTR("Next Script"), KeyModifierMask::CMD_OR_CTRL | KeyModifierMask::SHIFT | Key::PERIOD);
+ ED_SHORTCUT("script_editor/prev_script", TTR("Previous Script"), KeyModifierMask::CMD_OR_CTRL | KeyModifierMask::SHIFT | Key::COMMA);
set_process_input(true);
set_process_shortcut_input(true);
@@ -3768,10 +3768,10 @@ ScriptEditor::ScriptEditor() {
file_menu->set_shortcut_context(this);
menu_hb->add_child(file_menu);
- file_menu->get_popup()->add_shortcut(ED_SHORTCUT("script_editor/new", TTR("New Script..."), KeyModifierMask::CMD | Key::N), FILE_NEW);
- file_menu->get_popup()->add_shortcut(ED_SHORTCUT("script_editor/new_textfile", TTR("New Text File..."), KeyModifierMask::CMD | KeyModifierMask::SHIFT | Key::N), FILE_NEW_TEXTFILE);
+ file_menu->get_popup()->add_shortcut(ED_SHORTCUT("script_editor/new", TTR("New Script..."), KeyModifierMask::CMD_OR_CTRL | Key::N), FILE_NEW);
+ file_menu->get_popup()->add_shortcut(ED_SHORTCUT("script_editor/new_textfile", TTR("New Text File..."), KeyModifierMask::CMD_OR_CTRL | KeyModifierMask::SHIFT | Key::N), FILE_NEW_TEXTFILE);
file_menu->get_popup()->add_shortcut(ED_SHORTCUT("script_editor/open", TTR("Open...")), FILE_OPEN);
- file_menu->get_popup()->add_shortcut(ED_SHORTCUT("script_editor/reopen_closed_script", TTR("Reopen Closed Script"), KeyModifierMask::CMD | KeyModifierMask::SHIFT | Key::T), FILE_REOPEN_CLOSED);
+ file_menu->get_popup()->add_shortcut(ED_SHORTCUT("script_editor/reopen_closed_script", TTR("Reopen Closed Script"), KeyModifierMask::CMD_OR_CTRL | KeyModifierMask::SHIFT | Key::T), FILE_REOPEN_CLOSED);
file_menu->get_popup()->add_submenu_item(TTR("Open Recent"), "RecentScripts", FILE_OPEN_RECENT);
recent_scripts = memnew(PopupMenu);
@@ -3781,11 +3781,11 @@ ScriptEditor::ScriptEditor() {
_update_recent_scripts();
file_menu->get_popup()->add_separator();
- file_menu->get_popup()->add_shortcut(ED_SHORTCUT("script_editor/save", TTR("Save"), KeyModifierMask::ALT | KeyModifierMask::CMD | Key::S), FILE_SAVE);
+ file_menu->get_popup()->add_shortcut(ED_SHORTCUT("script_editor/save", TTR("Save"), KeyModifierMask::ALT | KeyModifierMask::CMD_OR_CTRL | Key::S), FILE_SAVE);
file_menu->get_popup()->add_shortcut(ED_SHORTCUT("script_editor/save_as", TTR("Save As...")), FILE_SAVE_AS);
file_menu->get_popup()->add_shortcut(ED_SHORTCUT("script_editor/save_all", TTR("Save All"), KeyModifierMask::SHIFT | KeyModifierMask::ALT | Key::S), FILE_SAVE_ALL);
file_menu->get_popup()->add_separator();
- file_menu->get_popup()->add_shortcut(ED_SHORTCUT("script_editor/reload_script_soft", TTR("Soft Reload Tool Script"), KeyModifierMask::CMD | KeyModifierMask::ALT | Key::R), FILE_TOOL_RELOAD_SOFT);
+ file_menu->get_popup()->add_shortcut(ED_SHORTCUT("script_editor/reload_script_soft", TTR("Soft Reload Tool Script"), KeyModifierMask::CMD_OR_CTRL | KeyModifierMask::ALT | Key::R), FILE_TOOL_RELOAD_SOFT);
file_menu->get_popup()->add_shortcut(ED_SHORTCUT("script_editor/copy_path", TTR("Copy Script Path")), FILE_COPY_PATH);
file_menu->get_popup()->add_shortcut(ED_SHORTCUT("script_editor/show_in_file_system", TTR("Show in FileSystem")), SHOW_IN_FILE_SYSTEM);
file_menu->get_popup()->add_separator();
@@ -3808,16 +3808,16 @@ ScriptEditor::ScriptEditor() {
theme_submenu->add_shortcut(ED_SHORTCUT("script_editor/save_theme_as", TTR("Save Theme As...")), THEME_SAVE_AS);
file_menu->get_popup()->add_separator();
- file_menu->get_popup()->add_shortcut(ED_SHORTCUT("script_editor/close_file", TTR("Close"), KeyModifierMask::CMD | Key::W), FILE_CLOSE);
+ file_menu->get_popup()->add_shortcut(ED_SHORTCUT("script_editor/close_file", TTR("Close"), KeyModifierMask::CMD_OR_CTRL | Key::W), FILE_CLOSE);
file_menu->get_popup()->add_shortcut(ED_SHORTCUT("script_editor/close_all", TTR("Close All")), CLOSE_ALL);
file_menu->get_popup()->add_shortcut(ED_SHORTCUT("script_editor/close_other_tabs", TTR("Close Other Tabs")), CLOSE_OTHER_TABS);
file_menu->get_popup()->add_shortcut(ED_SHORTCUT("script_editor/close_docs", TTR("Close Docs")), CLOSE_DOCS);
file_menu->get_popup()->add_separator();
- file_menu->get_popup()->add_shortcut(ED_SHORTCUT("script_editor/run_file", TTR("Run"), KeyModifierMask::CMD | KeyModifierMask::SHIFT | Key::X), FILE_RUN);
+ file_menu->get_popup()->add_shortcut(ED_SHORTCUT("script_editor/run_file", TTR("Run"), KeyModifierMask::CMD_OR_CTRL | KeyModifierMask::SHIFT | Key::X), FILE_RUN);
file_menu->get_popup()->add_separator();
- file_menu->get_popup()->add_shortcut(ED_SHORTCUT("script_editor/toggle_scripts_panel", TTR("Toggle Scripts Panel"), KeyModifierMask::CMD | Key::BACKSLASH), TOGGLE_SCRIPTS_PANEL);
+ file_menu->get_popup()->add_shortcut(ED_SHORTCUT("script_editor/toggle_scripts_panel", TTR("Toggle Scripts Panel"), KeyModifierMask::CMD_OR_CTRL | Key::BACKSLASH), TOGGLE_SCRIPTS_PANEL);
file_menu->get_popup()->connect("id_pressed", callable_mp(this, &ScriptEditor::_menu_option));
file_menu->get_popup()->connect("about_to_popup", callable_mp(this, &ScriptEditor::_prepare_file_menu));
@@ -4070,7 +4070,7 @@ ScriptEditorPlugin::ScriptEditorPlugin() {
EDITOR_DEF("text_editor/external/exec_flags", "{file}");
EditorSettings::get_singleton()->add_property_hint(PropertyInfo(Variant::STRING, "text_editor/external/exec_flags", PROPERTY_HINT_PLACEHOLDER_TEXT, "Call flags with placeholders: {project}, {file}, {col}, {line}."));
- ED_SHORTCUT("script_editor/reopen_closed_script", TTR("Reopen Closed Script"), KeyModifierMask::CMD | KeyModifierMask::SHIFT | Key::T);
+ ED_SHORTCUT("script_editor/reopen_closed_script", TTR("Reopen Closed Script"), KeyModifierMask::CMD_OR_CTRL | KeyModifierMask::SHIFT | Key::T);
ED_SHORTCUT("script_editor/clear_recent", TTR("Clear Recent Scripts"));
}
diff --git a/editor/plugins/script_text_editor.cpp b/editor/plugins/script_text_editor.cpp
index cc955eae76..42dcfb8b1f 100644
--- a/editor/plugins/script_text_editor.cpp
+++ b/editor/plugins/script_text_editor.cpp
@@ -2072,58 +2072,58 @@ static ScriptEditorBase *create_editor(const Ref<Resource> &p_resource) {
void ScriptTextEditor::register_editor() {
ED_SHORTCUT("script_text_editor/move_up", TTR("Move Up"), KeyModifierMask::ALT | Key::UP);
ED_SHORTCUT("script_text_editor/move_down", TTR("Move Down"), KeyModifierMask::ALT | Key::DOWN);
- ED_SHORTCUT("script_text_editor/delete_line", TTR("Delete Line"), KeyModifierMask::CMD | KeyModifierMask::SHIFT | Key::K);
+ ED_SHORTCUT("script_text_editor/delete_line", TTR("Delete Line"), KeyModifierMask::CMD_OR_CTRL | KeyModifierMask::SHIFT | Key::K);
// Leave these at zero, same can be accomplished with tab/shift-tab, including selection.
// The next/previous in history shortcut in this case makes a lot more sense.
ED_SHORTCUT("script_text_editor/indent_left", TTR("Indent Left"), Key::NONE);
ED_SHORTCUT("script_text_editor/indent_right", TTR("Indent Right"), Key::NONE);
- ED_SHORTCUT("script_text_editor/toggle_comment", TTR("Toggle Comment"), KeyModifierMask::CMD | Key::K);
+ ED_SHORTCUT("script_text_editor/toggle_comment", TTR("Toggle Comment"), KeyModifierMask::CMD_OR_CTRL | Key::K);
ED_SHORTCUT("script_text_editor/toggle_fold_line", TTR("Fold/Unfold Line"), KeyModifierMask::ALT | Key::F);
ED_SHORTCUT("script_text_editor/fold_all_lines", TTR("Fold All Lines"), Key::NONE);
ED_SHORTCUT("script_text_editor/unfold_all_lines", TTR("Unfold All Lines"), Key::NONE);
- ED_SHORTCUT("script_text_editor/duplicate_selection", TTR("Duplicate Selection"), KeyModifierMask::SHIFT | KeyModifierMask::CMD | Key::D);
- ED_SHORTCUT_OVERRIDE("script_text_editor/duplicate_selection", "macos", KeyModifierMask::SHIFT | KeyModifierMask::CMD | Key::C);
- ED_SHORTCUT("script_text_editor/evaluate_selection", TTR("Evaluate Selection"), KeyModifierMask::CMD | KeyModifierMask::SHIFT | Key::E);
- ED_SHORTCUT("script_text_editor/trim_trailing_whitespace", TTR("Trim Trailing Whitespace"), KeyModifierMask::CMD | KeyModifierMask::ALT | Key::T);
- ED_SHORTCUT("script_text_editor/convert_indent_to_spaces", TTR("Convert Indent to Spaces"), KeyModifierMask::CMD | KeyModifierMask::SHIFT | Key::Y);
- ED_SHORTCUT("script_text_editor/convert_indent_to_tabs", TTR("Convert Indent to Tabs"), KeyModifierMask::CMD | KeyModifierMask::SHIFT | Key::I);
- ED_SHORTCUT("script_text_editor/auto_indent", TTR("Auto Indent"), KeyModifierMask::CMD | Key::I);
+ ED_SHORTCUT("script_text_editor/duplicate_selection", TTR("Duplicate Selection"), KeyModifierMask::SHIFT | KeyModifierMask::CTRL | Key::D);
+ ED_SHORTCUT_OVERRIDE("script_text_editor/duplicate_selection", "macos", KeyModifierMask::SHIFT | KeyModifierMask::META | Key::C);
+ ED_SHORTCUT("script_text_editor/evaluate_selection", TTR("Evaluate Selection"), KeyModifierMask::CMD_OR_CTRL | KeyModifierMask::SHIFT | Key::E);
+ ED_SHORTCUT("script_text_editor/trim_trailing_whitespace", TTR("Trim Trailing Whitespace"), KeyModifierMask::CMD_OR_CTRL | KeyModifierMask::ALT | Key::T);
+ ED_SHORTCUT("script_text_editor/convert_indent_to_spaces", TTR("Convert Indent to Spaces"), KeyModifierMask::CMD_OR_CTRL | KeyModifierMask::SHIFT | Key::Y);
+ ED_SHORTCUT("script_text_editor/convert_indent_to_tabs", TTR("Convert Indent to Tabs"), KeyModifierMask::CMD_OR_CTRL | KeyModifierMask::SHIFT | Key::I);
+ ED_SHORTCUT("script_text_editor/auto_indent", TTR("Auto Indent"), KeyModifierMask::CMD_OR_CTRL | Key::I);
- ED_SHORTCUT_AND_COMMAND("script_text_editor/find", TTR("Find..."), KeyModifierMask::CMD | Key::F);
+ ED_SHORTCUT_AND_COMMAND("script_text_editor/find", TTR("Find..."), KeyModifierMask::CMD_OR_CTRL | Key::F);
ED_SHORTCUT("script_text_editor/find_next", TTR("Find Next"), Key::F3);
- ED_SHORTCUT_OVERRIDE("script_text_editor/find_next", "macos", KeyModifierMask::CMD | Key::G);
+ ED_SHORTCUT_OVERRIDE("script_text_editor/find_next", "macos", KeyModifierMask::META | Key::G);
ED_SHORTCUT("script_text_editor/find_previous", TTR("Find Previous"), KeyModifierMask::SHIFT | Key::F3);
- ED_SHORTCUT_OVERRIDE("script_text_editor/find_previous", "macos", KeyModifierMask::CMD | KeyModifierMask::SHIFT | Key::G);
+ ED_SHORTCUT_OVERRIDE("script_text_editor/find_previous", "macos", KeyModifierMask::META | KeyModifierMask::SHIFT | Key::G);
- ED_SHORTCUT_AND_COMMAND("script_text_editor/replace", TTR("Replace..."), KeyModifierMask::CMD | Key::R);
- ED_SHORTCUT_OVERRIDE("script_text_editor/replace", "macos", KeyModifierMask::ALT | KeyModifierMask::CMD | Key::F);
+ ED_SHORTCUT_AND_COMMAND("script_text_editor/replace", TTR("Replace..."), KeyModifierMask::CTRL | Key::R);
+ ED_SHORTCUT_OVERRIDE("script_text_editor/replace", "macos", KeyModifierMask::ALT | KeyModifierMask::META | Key::F);
- ED_SHORTCUT("script_text_editor/find_in_files", TTR("Find in Files..."), KeyModifierMask::CMD | KeyModifierMask::SHIFT | Key::F);
- ED_SHORTCUT("script_text_editor/replace_in_files", TTR("Replace in Files..."), KeyModifierMask::CMD | KeyModifierMask::SHIFT | Key::R);
+ ED_SHORTCUT("script_text_editor/find_in_files", TTR("Find in Files..."), KeyModifierMask::CMD_OR_CTRL | KeyModifierMask::SHIFT | Key::F);
+ ED_SHORTCUT("script_text_editor/replace_in_files", TTR("Replace in Files..."), KeyModifierMask::CMD_OR_CTRL | KeyModifierMask::SHIFT | Key::R);
ED_SHORTCUT("script_text_editor/contextual_help", TTR("Contextual Help"), KeyModifierMask::ALT | Key::F1);
ED_SHORTCUT_OVERRIDE("script_text_editor/contextual_help", "macos", KeyModifierMask::ALT | KeyModifierMask::SHIFT | Key::SPACE);
- ED_SHORTCUT("script_text_editor/toggle_bookmark", TTR("Toggle Bookmark"), KeyModifierMask::CMD | KeyModifierMask::ALT | Key::B);
- ED_SHORTCUT("script_text_editor/goto_next_bookmark", TTR("Go to Next Bookmark"), KeyModifierMask::CMD | Key::B);
- ED_SHORTCUT("script_text_editor/goto_previous_bookmark", TTR("Go to Previous Bookmark"), KeyModifierMask::CMD | KeyModifierMask::SHIFT | Key::B);
+ ED_SHORTCUT("script_text_editor/toggle_bookmark", TTR("Toggle Bookmark"), KeyModifierMask::CMD_OR_CTRL | KeyModifierMask::ALT | Key::B);
+ ED_SHORTCUT("script_text_editor/goto_next_bookmark", TTR("Go to Next Bookmark"), KeyModifierMask::CMD_OR_CTRL | Key::B);
+ ED_SHORTCUT("script_text_editor/goto_previous_bookmark", TTR("Go to Previous Bookmark"), KeyModifierMask::CMD_OR_CTRL | KeyModifierMask::SHIFT | Key::B);
ED_SHORTCUT("script_text_editor/remove_all_bookmarks", TTR("Remove All Bookmarks"), Key::NONE);
- ED_SHORTCUT("script_text_editor/goto_function", TTR("Go to Function..."), KeyModifierMask::ALT | KeyModifierMask::CMD | Key::F);
- ED_SHORTCUT_OVERRIDE("script_text_editor/goto_function", "macos", KeyModifierMask::CTRL | KeyModifierMask::CMD | Key::J);
+ ED_SHORTCUT("script_text_editor/goto_function", TTR("Go to Function..."), KeyModifierMask::ALT | KeyModifierMask::CTRL | Key::F);
+ ED_SHORTCUT_OVERRIDE("script_text_editor/goto_function", "macos", KeyModifierMask::CTRL | KeyModifierMask::META | Key::J);
- ED_SHORTCUT("script_text_editor/goto_line", TTR("Go to Line..."), KeyModifierMask::CMD | Key::L);
+ ED_SHORTCUT("script_text_editor/goto_line", TTR("Go to Line..."), KeyModifierMask::CMD_OR_CTRL | Key::L);
ED_SHORTCUT("script_text_editor/toggle_breakpoint", TTR("Toggle Breakpoint"), Key::F9);
- ED_SHORTCUT_OVERRIDE("script_text_editor/toggle_breakpoint", "macos", KeyModifierMask::CMD | KeyModifierMask::SHIFT | Key::B);
+ ED_SHORTCUT_OVERRIDE("script_text_editor/toggle_breakpoint", "macos", KeyModifierMask::META | KeyModifierMask::SHIFT | Key::B);
- ED_SHORTCUT("script_text_editor/remove_all_breakpoints", TTR("Remove All Breakpoints"), KeyModifierMask::CMD | KeyModifierMask::SHIFT | Key::F9);
- ED_SHORTCUT("script_text_editor/goto_next_breakpoint", TTR("Go to Next Breakpoint"), KeyModifierMask::CMD | Key::PERIOD);
- ED_SHORTCUT("script_text_editor/goto_previous_breakpoint", TTR("Go to Previous Breakpoint"), KeyModifierMask::CMD | Key::COMMA);
+ ED_SHORTCUT("script_text_editor/remove_all_breakpoints", TTR("Remove All Breakpoints"), KeyModifierMask::CMD_OR_CTRL | KeyModifierMask::SHIFT | Key::F9);
+ ED_SHORTCUT("script_text_editor/goto_next_breakpoint", TTR("Go to Next Breakpoint"), KeyModifierMask::CMD_OR_CTRL | Key::PERIOD);
+ ED_SHORTCUT("script_text_editor/goto_previous_breakpoint", TTR("Go to Previous Breakpoint"), KeyModifierMask::CMD_OR_CTRL | Key::COMMA);
ScriptEditor::register_create_script_editor_function(create_editor);
}
diff --git a/editor/plugins/skeleton_3d_editor_plugin.cpp b/editor/plugins/skeleton_3d_editor_plugin.cpp
index 37d05e5fa7..3c75ac6ca6 100644
--- a/editor/plugins/skeleton_3d_editor_plugin.cpp
+++ b/editor/plugins/skeleton_3d_editor_plugin.cpp
@@ -785,7 +785,7 @@ void Skeleton3DEditor::create_editors() {
key_insert_all_button->set_focus_mode(FOCUS_NONE);
key_insert_all_button->connect("pressed", callable_mp(this, &Skeleton3DEditor::insert_keys).bind(true));
key_insert_all_button->set_tooltip_text(TTR("Insert key of all bone poses."));
- key_insert_all_button->set_shortcut(ED_SHORTCUT("skeleton_3d_editor/insert_key_of_all_bones", TTR("Insert Key (All Bones)"), KeyModifierMask::CMD + Key::INSERT));
+ key_insert_all_button->set_shortcut(ED_SHORTCUT("skeleton_3d_editor/insert_key_of_all_bones", TTR("Insert Key (All Bones)"), KeyModifierMask::CMD_OR_CTRL + Key::INSERT));
animation_hb->add_child(key_insert_all_button);
// Bone tree.
diff --git a/editor/plugins/tiles/tile_data_editors.cpp b/editor/plugins/tiles/tile_data_editors.cpp
index 1dce41e4c7..4d54001b94 100644
--- a/editor/plugins/tiles/tile_data_editors.cpp
+++ b/editor/plugins/tiles/tile_data_editors.cpp
@@ -40,6 +40,10 @@
#include "editor/editor_scale.h"
#include "editor/editor_undo_redo_manager.h"
+#ifdef DEBUG_ENABLED
+#include "servers/navigation_server_3d.h"
+#endif // DEBUG_ENABLED
+
void TileDataEditor::_tile_set_changed_plan_update() {
_tile_set_changed_update_needed = true;
call_deferred(SNAME("_tile_set_changed_deferred_update"));
@@ -2674,7 +2678,9 @@ void TileDataNavigationEditor::_tile_set_changed() {
void TileDataNavigationEditor::_notification(int p_what) {
switch (p_what) {
case NOTIFICATION_ENTER_TREE: {
- polygon_editor->set_polygons_color(get_tree()->get_debug_navigation_color());
+#ifdef DEBUG_ENABLED
+ polygon_editor->set_polygons_color(NavigationServer3D::get_singleton()->get_debug_navigation_geometry_face_color());
+#endif // DEBUG_ENABLED
} break;
}
}
@@ -2701,7 +2707,10 @@ void TileDataNavigationEditor::draw_over_tile(CanvasItem *p_canvas_item, Transfo
return;
}
- Color color = p_canvas_item->get_tree()->get_debug_navigation_color();
+ Color color = Color(0.5, 1.0, 1.0, 1.0);
+#ifdef DEBUG_ENABLED
+ color = NavigationServer3D::get_singleton()->get_debug_navigation_geometry_face_color();
+#endif // DEBUG_ENABLED
if (p_selected) {
Color grid_color = EditorSettings::get_singleton()->get("editors/tiles_editor/grid_color");
Color selection_color = Color().from_hsv(Math::fposmod(grid_color.get_h() + 0.5, 1.0), grid_color.get_s(), grid_color.get_v(), 1.0);
diff --git a/editor/plugins/tiles/tile_map_editor.cpp b/editor/plugins/tiles/tile_map_editor.cpp
index 3f2710f858..01bef9b52b 100644
--- a/editor/plugins/tiles/tile_map_editor.cpp
+++ b/editor/plugins/tiles/tile_map_editor.cpp
@@ -1359,11 +1359,11 @@ void TileMapEditorTilesPlugin::_stop_dragging() {
for (int i = 0; i < sources_list->get_item_count(); i++) {
if (int(sources_list->get_item_metadata(i)) == picked_source) {
sources_list->set_current(i);
+ TilesEditorPlugin::get_singleton()->set_sources_lists_current(i);
break;
}
}
sources_list->ensure_current_is_visible();
- TilesEditorPlugin::get_singleton()->set_sources_lists_current(picked_source);
}
Ref<TileMapPattern> new_selection_pattern = tile_map->get_pattern(tile_map_layer, coords_array);
@@ -2020,9 +2020,9 @@ TileMapEditorTilesPlugin::TileMapEditorTilesPlugin() {
->connect("mouse_exited", callable_mp(this, &TileMapEditorTilesPlugin::_mouse_exited_viewport));
// --- Shortcuts ---
- ED_SHORTCUT("tiles_editor/cut", TTR("Cut"), KeyModifierMask::CMD | Key::X);
- ED_SHORTCUT("tiles_editor/copy", TTR("Copy"), KeyModifierMask::CMD | Key::C);
- ED_SHORTCUT("tiles_editor/paste", TTR("Paste"), KeyModifierMask::CMD | Key::V);
+ ED_SHORTCUT("tiles_editor/cut", TTR("Cut"), KeyModifierMask::CMD_OR_CTRL | Key::X);
+ ED_SHORTCUT("tiles_editor/copy", TTR("Copy"), KeyModifierMask::CMD_OR_CTRL | Key::C);
+ ED_SHORTCUT("tiles_editor/paste", TTR("Paste"), KeyModifierMask::CMD_OR_CTRL | Key::V);
ED_SHORTCUT("tiles_editor/cancel", TTR("Cancel"), Key::ESCAPE);
ED_SHORTCUT("tiles_editor/delete", TTR("Delete"), Key::KEY_DELETE);
diff --git a/editor/plugins/version_control_editor_plugin.cpp b/editor/plugins/version_control_editor_plugin.cpp
index fba760d57f..761140b2d5 100644
--- a/editor/plugins/version_control_editor_plugin.cpp
+++ b/editor/plugins/version_control_editor_plugin.cpp
@@ -1319,7 +1319,7 @@ VersionControlEditorPlugin::VersionControlEditorPlugin() {
commit_message->connect(SNAME("gui_input"), callable_mp(this, &VersionControlEditorPlugin::_commit_message_gui_input));
commit_area->add_child(commit_message);
- ED_SHORTCUT("version_control/commit", TTR("Commit"), KeyModifierMask::CMD | Key::ENTER);
+ ED_SHORTCUT("version_control/commit", TTR("Commit"), KeyModifierMask::CMD_OR_CTRL | Key::ENTER);
commit_button = memnew(Button);
commit_button->set_text(TTR("Commit Changes"));
diff --git a/editor/progress_dialog.cpp b/editor/progress_dialog.cpp
index 1c9afa8be8..4cc60c4c3c 100644
--- a/editor/progress_dialog.cpp
+++ b/editor/progress_dialog.cpp
@@ -176,7 +176,7 @@ void ProgressDialog::add_task(const String &p_task, const String &p_label, int p
} else {
cancel_hb->hide();
}
- cancel_hb->raise();
+ cancel_hb->move_to_front();
cancelled = false;
_popup();
if (p_can_cancel) {
@@ -207,7 +207,9 @@ bool ProgressDialog::task_step(const String &p_task, const String &p_state, int
DisplayServer::get_singleton()->process_events();
}
+#ifndef ANDROID_ENABLED
Main::iteration(); // this will not work on a lot of platforms, so it's only meant for the editor
+#endif
return cancelled;
}
diff --git a/editor/project_converter_3_to_4.cpp b/editor/project_converter_3_to_4.cpp
index 47c4557f14..39b30b31fb 100644
--- a/editor/project_converter_3_to_4.cpp
+++ b/editor/project_converter_3_to_4.cpp
@@ -240,6 +240,8 @@ static const char *gdscript_function_renames[][2] = {
{ "can_instance", "can_instantiate" }, // PackedScene, Script
{ "canvas_light_set_scale", "canvas_light_set_texture_scale" }, // RenderingServer
{ "center_viewport_to_cursor", "center_viewport_to_caret" }, // TextEdit
+ { "change_scene", "change_scene_to_file" }, // SceneTree
+ { "change_scene_to", "change_scene_to_packed" }, // SceneTree
{ "clip_polygons_2d", "clip_polygons" }, // Geometry2D
{ "clip_polyline_with_polygon_2d", "clip_polyline_with_polygon" }, //Geometry2D
{ "commit_handle", "_commit_handle" }, // EditorNode3DGizmo
@@ -290,7 +292,7 @@ static const char *gdscript_function_renames[][2] = {
{ "get_collision_layer_bit", "get_collision_layer_value" }, // CSGShape3D and a lot of others like GridMap
{ "get_collision_mask_bit", "get_collision_mask_value" }, // CSGShape3D and a lot of others like GridMap
{ "get_color_types", "get_color_type_list" }, // Theme
- { "get_command", "is_command_pressed" }, // InputEventWithModifiers
+ { "get_command", "is_command_or_control_pressed" }, // InputEventWithModifiers
{ "get_constant_types", "get_constant_type_list" }, // Theme
{ "get_control", "is_ctrl_pressed" }, // InputEventWithModifiers
{ "get_cull_mask_bit", "get_cull_mask_value" }, // Camera3D
@@ -478,7 +480,7 @@ static const char *gdscript_function_renames[][2] = {
{ "set_collision_layer_bit", "set_collision_layer_value" }, // CSGShape3D and a lot of others like GridMap
{ "set_collision_mask_bit", "set_collision_mask_value" }, // CSGShape3D and a lot of others like GridMap
{ "set_column_min_width", "set_column_custom_minimum_width" }, // Tree
- { "set_command", "set_command_pressed" }, // InputEventWithModifiers
+ { "set_command", "set_meta_pressed" }, // InputEventWithModifiers
{ "set_control", "set_ctrl_pressed" }, // InputEventWithModifiers
{ "set_create_options", "_set_create_options" }, // EditorResourcePicker
{ "set_cull_mask_bit", "set_cull_mask_value" }, // Camera3D
@@ -670,6 +672,8 @@ static const char *csharp_function_renames[][2] = {
{ "CanInstance", "CanInstantiate" }, // PackedScene, Script
{ "CanvasLightSetScale", "CanvasLightSetTextureScale" }, // RenderingServer
{ "CenterViewportToCursor", "CenterViewportToCaret" }, // TextEdit
+ { "ChangeScene", "ChangeSceneToFile" }, // SceneTree
+ { "ChangeSceneTo", "ChangeSceneToPacked" }, // SceneTree
{ "ClipPolygons2d", "ClipPolygons" }, // Geometry2D
{ "ClipPolylineWithPolygon2d", "ClipPolylineWithPolygon" }, //Geometry2D
{ "CommitHandle", "_CommitHandle" }, // EditorNode3DGizmo
@@ -1266,7 +1270,7 @@ static const char *project_settings_renames[][2] = {
{ "network/limits/debugger_stdout/max_errors_per_second", "network/limits/debugger/max_errors_per_second" },
{ "network/limits/debugger_stdout/max_messages_per_frame", "network/limits/debugger/max_queued_messages" },
{ "network/limits/debugger_stdout/max_warnings_per_second", "network/limits/debugger/max_warnings_per_second" },
- { "network/ssl/certificates", "network/ssl/certificate_bundle_override" },
+ { "network/ssl/certificates", "network/tls/certificate_bundle_override" },
{ "physics/2d/thread_model", "physics/2d/run_on_thread" }, // TODO not sure
{ "rendering/environment/default_clear_color", "rendering/environment/defaults/default_clear_color" },
{ "rendering/environment/default_environment", "rendering/environment/defaults/default_environment" },
@@ -1550,7 +1554,6 @@ static const char *class_renames[][2] = {
{ nullptr, nullptr },
};
-// TODO - this colors needs to be validated(not all are valid)
static const char *color_renames[][2] = {
{ "aliceblue", "ALICE_BLUE" },
{ "antiquewhite", "ANTIQUE_WHITE" },
@@ -1704,7 +1707,7 @@ static const char *color_renames[][2] = {
class ProjectConverter3To4::RegExContainer {
public:
- // Custom GDScript
+ // Custom GDScript.
RegEx reg_is_empty = RegEx("\\bempty\\(");
RegEx reg_super = RegEx("([\t ])\\.([a-zA-Z_])");
RegEx reg_json_to = RegEx("\\bto_json\\b");
@@ -1721,7 +1724,7 @@ public:
RegEx reg_os_fullscreen = RegEx("OS.window_fullscreen[= ]+([^#^\n]+)");
RegEx reg_instantiate = RegEx("\\.instance\\(([^\\)]*)\\)");
- // GDScript keywords
+ // GDScript keywords.
RegEx keyword_gdscript_tool = RegEx("^tool");
RegEx keyword_gdscript_export_single = RegEx("^export");
RegEx keyword_gdscript_export_mutli = RegEx("([\t]+)export\\b");
@@ -1735,7 +1738,7 @@ public:
RegEx keyword_gdscript_master = RegEx("^master func");
RegEx keyword_gdscript_mastersync = RegEx("^mastersync func");
- // CSharp keywords
+ // CSharp keywords.
RegEx keyword_csharp_remote = RegEx("\\[Remote(Attribute)?(\\(\\))?\\]");
RegEx keyword_csharp_remotesync = RegEx("\\[(Remote)?Sync(Attribute)?(\\(\\))?\\]");
RegEx keyword_csharp_puppet = RegEx("\\[(Puppet|Slave)(Attribute)?(\\(\\))?\\]");
@@ -1743,11 +1746,11 @@ public:
RegEx keyword_csharp_master = RegEx("\\[Master(Attribute)?(\\(\\))?\\]");
RegEx keyword_csharp_mastersync = RegEx("\\[MasterSync(Attribute)?(\\(\\))?\\]");
- // Colors
+ // Colors.
LocalVector<RegEx *> color_regexes;
LocalVector<String> color_renamed;
- // Classes
+ // Classes.
LocalVector<RegEx *> class_tscn_regexes;
LocalVector<RegEx *> class_gd_regexes;
LocalVector<RegEx *> class_shader_regexes;
@@ -1762,7 +1765,7 @@ public:
LocalVector<String> class_temp_gd_renames;
LocalVector<String> class_temp_shader_renames;
- // Common
+ // Common.
LocalVector<RegEx *> enum_regexes;
LocalVector<RegEx *> gdscript_function_regexes;
LocalVector<RegEx *> project_settings_regexes;
@@ -1775,58 +1778,58 @@ public:
LocalVector<RegEx *> csharp_signal_regexes;
RegExContainer() {
- // Common
+ // Common.
{
- // Enum
+ // Enum.
for (unsigned int current_index = 0; enum_renames[current_index][0]; current_index++) {
enum_regexes.push_back(memnew(RegEx(String("\\b") + enum_renames[current_index][0] + "\\b")));
}
- // GDScript functions
+ // GDScript functions.
for (unsigned int current_index = 0; gdscript_function_renames[current_index][0]; current_index++) {
gdscript_function_regexes.push_back(memnew(RegEx(String("\\b") + gdscript_function_renames[current_index][0] + "\\b")));
}
- // Project Settings
+ // Project Settings.
for (unsigned int current_index = 0; project_settings_renames[current_index][0]; current_index++) {
project_settings_regexes.push_back(memnew(RegEx(String("\\b") + project_settings_renames[current_index][0] + "\\b")));
}
- // GDScript properties
+ // GDScript properties.
for (unsigned int current_index = 0; gdscript_properties_renames[current_index][0]; current_index++) {
gdscript_properties_regexes.push_back(memnew(RegEx(String("\\b") + gdscript_properties_renames[current_index][0] + "\\b")));
}
- // GDScript Signals
+ // GDScript Signals.
for (unsigned int current_index = 0; gdscript_signals_renames[current_index][0]; current_index++) {
gdscript_signals_regexes.push_back(memnew(RegEx(String("\\b") + gdscript_signals_renames[current_index][0] + "\\b")));
}
- // Shaders
+ // Shaders.
for (unsigned int current_index = 0; shaders_renames[current_index][0]; current_index++) {
shaders_regexes.push_back(memnew(RegEx(String("\\b") + shaders_renames[current_index][0] + "\\b")));
}
- // Builtin types
+ // Builtin types.
for (unsigned int current_index = 0; builtin_types_renames[current_index][0]; current_index++) {
builtin_types_regexes.push_back(memnew(RegEx(String("\\b") + builtin_types_renames[current_index][0] + "\\b")));
}
- // CSharp function renames
+ // CSharp function renames.
for (unsigned int current_index = 0; csharp_function_renames[current_index][0]; current_index++) {
csharp_function_regexes.push_back(memnew(RegEx(String("\\b") + csharp_function_renames[current_index][0] + "\\b")));
}
- // CSharp properties renames
+ // CSharp properties renames.
for (unsigned int current_index = 0; csharp_properties_renames[current_index][0]; current_index++) {
csharp_properties_regexes.push_back(memnew(RegEx(String("\\b") + csharp_properties_renames[current_index][0] + "\\b")));
}
- // CSharp signals renames
+ // CSharp signals renames.
for (unsigned int current_index = 0; csharp_signals_renames[current_index][0]; current_index++) {
csharp_signal_regexes.push_back(memnew(RegEx(String("\\b") + csharp_signals_renames[current_index][0] + "\\b")));
}
}
- // Colors
+ // Colors.
{
for (unsigned int current_index = 0; color_renames[current_index][0]; current_index++) {
color_regexes.push_back(memnew(RegEx(String("\\bColor.") + color_renames[current_index][0] + "\\b")));
color_renamed.push_back(String("Color.") + color_renames[current_index][1]);
}
}
- // Classes
+ // Classes.
{
for (unsigned int current_index = 0; class_renames[current_index][0]; current_index++) {
class_tscn_regexes.push_back(memnew(RegEx(String("\\b") + class_renames[current_index][0] + ".tscn\\b")));
@@ -1884,12 +1887,12 @@ public:
}
};
-ProjectConverter3To4::ProjectConverter3To4(int maximum_file_size_kb, int maximum_line_length) {
- this->maximum_file_size = maximum_file_size_kb * 1024;
- this->maximum_line_length = maximum_line_length;
+ProjectConverter3To4::ProjectConverter3To4(int p_maximum_file_size_kb, int p_maximum_line_length) {
+ maximum_file_size = p_maximum_file_size_kb * 1024;
+ maximum_line_length = p_maximum_line_length;
}
-// Function responsible for converting project
+// Function responsible for converting project.
int ProjectConverter3To4::convert() {
print_line("Starting conversion.");
uint64_t conversion_start_time = Time::get_singleton()->get_ticks_msec();
@@ -1897,7 +1900,7 @@ int ProjectConverter3To4::convert() {
RegExContainer reg_container = RegExContainer();
int cached_maximum_line_length = maximum_line_length;
- maximum_line_length = 10000; // Use only for tests bigger value, to not break them
+ maximum_line_length = 10000; // Use only for tests bigger value, to not break them.
ERR_FAIL_COND_V_MSG(!test_array_names(), ERROR_CODE, "Cannot start converting due to problems with data in arrays.");
ERR_FAIL_COND_V_MSG(!test_conversion(reg_container), ERROR_CODE, "Cannot start converting due to problems with converting arrays.");
@@ -1905,36 +1908,36 @@ int ProjectConverter3To4::convert() {
maximum_line_length = cached_maximum_line_length;
// Checking if folder contains valid Godot 3 project.
- // Project should not be converted more than 1 times
+ // Project should not be converted more than once.
{
- String conventer_text = "; Project was converted by built-in tool to Godot 4.0";
+ String converter_text = "; Project was converted by built-in tool to Godot 4.0";
- ERR_FAIL_COND_V_MSG(!FileAccess::exists("project.godot"), ERROR_CODE, "Current directory doesn't contains any Godot 3 project");
+ ERR_FAIL_COND_V_MSG(!FileAccess::exists("project.godot"), ERROR_CODE, "Current working directory doesn't contain a \"project.godot\" file for a Godot 3 project.");
Error err = OK;
String project_godot_content = FileAccess::get_file_as_string("project.godot", &err);
- ERR_FAIL_COND_V_MSG(err != OK, ERROR_CODE, "Failed to read content of \"project.godot\" file.");
- ERR_FAIL_COND_V_MSG(project_godot_content.contains(conventer_text), ERROR_CODE, "Project already was converted with this tool.");
+ ERR_FAIL_COND_V_MSG(err != OK, ERROR_CODE, "Unable to read \"project.godot\".");
+ ERR_FAIL_COND_V_MSG(project_godot_content.contains(converter_text), ERROR_CODE, "Project was already converted with this tool.");
Ref<FileAccess> file = FileAccess::open("project.godot", FileAccess::WRITE);
- ERR_FAIL_COND_V_MSG(file.is_null(), ERROR_CODE, "Failed to open project.godot file.");
+ ERR_FAIL_COND_V_MSG(file.is_null(), ERROR_CODE, "Unable to open \"project.godot\".");
- file->store_string(conventer_text + "\n" + project_godot_content);
+ file->store_string(converter_text + "\n" + project_godot_content);
}
Vector<String> collected_files = check_for_files();
uint32_t converted_files = 0;
- // Check file by file
+ // Check file by file.
for (int i = 0; i < collected_files.size(); i++) {
String file_name = collected_files[i];
Vector<String> lines;
uint32_t ignored_lines = 0;
{
Ref<FileAccess> file = FileAccess::open(file_name, FileAccess::READ);
- ERR_CONTINUE_MSG(file.is_null(), "Failed to read content of \"" + file_name + "\".");
+ ERR_CONTINUE_MSG(file.is_null(), vformat("Unable to read content of \"%s\".", file_name));
while (!file->eof_reached()) {
String line = file->get_line();
lines.append(line);
@@ -1943,7 +1946,7 @@ int ProjectConverter3To4::convert() {
String file_content_before = collect_string_from_vector(lines);
uint64_t hash_before = file_content_before.hash();
uint64_t file_size = file_content_before.size();
- print_line("Trying to convert\t" + itos(i + 1) + "/" + itos(collected_files.size()) + " file - \"" + file_name.trim_prefix("res://") + "\" with size - " + itos(file_size / 1024) + " KB");
+ print_line(vformat("Trying to convert\t%d/%d file - \"%s\" with size - %d KB", i + 1, collected_files.size(), file_name.trim_prefix("res://"), file_size / 1024));
Vector<String> reason;
bool is_ignored = false;
@@ -1955,15 +1958,15 @@ int ProjectConverter3To4::convert() {
}
if (file_size < uint64_t(maximum_file_size)) {
- // TSCN must be the same work exactly same as .gd file because it may contains builtin script
+ // ".tscn" must work exactly the same as ".gd" files because they may contain built-in Scripts.
if (file_name.ends_with(".gd")) {
- rename_classes(lines, reg_container); // Using only specialized function
+ rename_classes(lines, reg_container); // Using only specialized function.
rename_common(enum_renames, reg_container.enum_regexes, lines);
- rename_colors(lines, reg_container); // Require to additional rename
+ rename_colors(lines, reg_container); // Require to additional rename.
rename_common(gdscript_function_renames, reg_container.gdscript_function_regexes, lines);
- rename_gdscript_functions(lines, reg_container, false); // Require to additional rename
+ rename_gdscript_functions(lines, reg_container, false); // Require to additional rename.
rename_common(project_settings_renames, reg_container.project_settings_regexes, lines);
rename_gdscript_keywords(lines, reg_container);
@@ -1974,13 +1977,13 @@ int ProjectConverter3To4::convert() {
custom_rename(lines, "\\.shader", ".gdshader");
} else if (file_name.ends_with(".tscn")) {
- rename_classes(lines, reg_container); // Using only specialized function
+ rename_classes(lines, reg_container); // Using only specialized function.
rename_common(enum_renames, reg_container.enum_regexes, lines);
- rename_colors(lines, reg_container); // Require to additional rename
+ rename_colors(lines, reg_container); // Require to do additional renames.
rename_common(gdscript_function_renames, reg_container.gdscript_function_regexes, lines);
- rename_gdscript_functions(lines, reg_container, true); // Require to additional rename
+ rename_gdscript_functions(lines, reg_container, true); // Require to do additional renames.
rename_common(project_settings_renames, reg_container.project_settings_regexes, lines);
rename_gdscript_keywords(lines, reg_container);
@@ -1990,8 +1993,8 @@ int ProjectConverter3To4::convert() {
rename_common(builtin_types_renames, reg_container.builtin_types_regexes, lines);
custom_rename(lines, "\\.shader", ".gdshader");
- } else if (file_name.ends_with(".cs")) { // TODO, C# should use different methods
- rename_classes(lines, reg_container); // Using only specialized function
+ } else if (file_name.ends_with(".cs")) { // TODO, C# should use different methods.
+ rename_classes(lines, reg_container); // Using only specialized function.
rename_common(csharp_function_renames, reg_container.csharp_function_regexes, lines);
rename_common(builtin_types_renames, reg_container.builtin_types_regexes, lines);
rename_common(csharp_properties_renames, reg_container.csharp_properties_regexes, lines);
@@ -2002,7 +2005,7 @@ int ProjectConverter3To4::convert() {
} else if (file_name.ends_with(".gdshader") || file_name.ends_with(".shader")) {
rename_common(shaders_renames, reg_container.shaders_regexes, lines);
} else if (file_name.ends_with("tres")) {
- rename_classes(lines, reg_container); // Using only specialized function
+ rename_classes(lines, reg_container); // Using only specialized function.
rename_common(shaders_renames, reg_container.shaders_regexes, lines);
rename_common(builtin_types_renames, reg_container.builtin_types_regexes, lines);
@@ -2024,41 +2027,40 @@ int ProjectConverter3To4::convert() {
}
}
} else {
- reason.append(" ERROR: File has exceeded the maximum size allowed - " + itos(maximum_file_size / 1024) + " KB");
+ reason.append(vformat(" ERROR: File has exceeded the maximum size allowed - %d KB", maximum_file_size / 1024));
is_ignored = true;
}
uint64_t end_time = Time::get_singleton()->get_ticks_msec();
if (is_ignored) {
- String end_message = " Checking file took " + itos(end_time - start_time) + " ms.";
+ String end_message = vformat(" Checking file took %d ms.", end_time - start_time);
print_line(end_message);
} else {
String file_content_after = collect_string_from_vector(lines);
uint64_t hash_after = file_content_after.hash64();
- // Don't need to save file without any changes
- // Save if this is a shader, because it was renamed
+ // Don't need to save file without any changes.
+ // Save if this is a shader, because it was renamed.
if (hash_before != hash_after || file_name.ends_with(".gdshader")) {
converted_files++;
Ref<FileAccess> file = FileAccess::open(file_name, FileAccess::WRITE);
- ERR_CONTINUE_MSG(file.is_null(), "Failed to open \"" + file_name + "\" to save data to file.");
+ ERR_CONTINUE_MSG(file.is_null(), vformat("Unable to apply changes to \"%s\", no writing access.", file_name));
file->store_string(file_content_after);
- reason.append(" File was changed, conversion took " + itos(end_time - start_time) + " ms.");
+ reason.append(vformat(" File was changed, conversion took %d ms.", end_time - start_time));
} else {
- reason.append(" File was not changed, checking took " + itos(end_time - start_time) + " ms.");
+ reason.append(vformat(" File was left unchanged, checking took %d ms.", end_time - start_time));
}
if (ignored_lines != 0) {
- reason.append(" Ignored " + itos(ignored_lines) + " lines, because their length exceeds maximum allowed characters - " + itos(maximum_line_length));
+ reason.append(vformat(" Ignored %d lines, because their length exceeds maximum allowed characters - %d.", ignored_lines, maximum_line_length));
}
}
for (int k = 0; k < reason.size(); k++) {
print_line(reason[k]);
}
}
-
- print_line("Conversion ended - all files(" + itos(collected_files.size()) + "), converted files(" + itos(converted_files) + "), not converted files(" + itos(collected_files.size() - converted_files) + ").");
+ print_line(vformat("Conversion ended - all files(%d), converted files: (%d), not converted files: (%d).", collected_files.size(), converted_files, collected_files.size() - converted_files));
uint64_t conversion_end_time = Time::get_singleton()->get_ticks_msec();
- print_line("Conversion of all files took " + itos(conversion_end_time - conversion_start_time) + " ms.");
+ print_line(vformat("Conversion of all files took %10.3f seconds.", (conversion_end_time - conversion_start_time) / 1000.0));
return 0;
};
@@ -2070,7 +2072,7 @@ int ProjectConverter3To4::validate_conversion() {
RegExContainer reg_container = RegExContainer();
int cached_maximum_line_length = maximum_line_length;
- maximum_line_length = 10000; // Use only for tests bigger value, to not break them
+ maximum_line_length = 10000; // To avoid breaking the tests, only use this for the their larger value.
ERR_FAIL_COND_V_MSG(!test_array_names(), ERROR_CODE, "Cannot start converting due to problems with data in arrays.");
ERR_FAIL_COND_V_MSG(!test_conversion(reg_container), ERROR_CODE, "Cannot start converting due to problems with converting arrays.");
@@ -2078,7 +2080,7 @@ int ProjectConverter3To4::validate_conversion() {
maximum_line_length = cached_maximum_line_length;
// Checking if folder contains valid Godot 3 project.
- // Project should not be converted more than 1 times
+ // Project should not be converted more than once.
{
String conventer_text = "; Project was converted by built-in tool to Godot 4.0";
@@ -2095,7 +2097,7 @@ int ProjectConverter3To4::validate_conversion() {
uint32_t converted_files = 0;
- // Check file by file
+ // Check file by file.
for (int i = 0; i < collected_files.size(); i++) {
String file_name = collected_files[i];
Vector<String> lines;
@@ -2103,14 +2105,14 @@ int ProjectConverter3To4::validate_conversion() {
uint64_t file_size = 0;
{
Ref<FileAccess> file = FileAccess::open(file_name, FileAccess::READ);
- ERR_CONTINUE_MSG(file.is_null(), "Failed to read content of \"" + file_name + "\".");
+ ERR_CONTINUE_MSG(file.is_null(), vformat("Unable to read content of \"%s\".", file_name));
while (!file->eof_reached()) {
String line = file->get_line();
file_size += line.size();
lines.append(line);
}
}
- print_line("Checking for conversion - " + itos(i + 1) + "/" + itos(collected_files.size()) + " file - \"" + file_name.trim_prefix("res://") + "\" with size - " + itos(file_size / 1024) + " KB");
+ print_line(vformat("Checking for conversion - %d/%d file - \"%s\" with size - %d KB"), i + 1, collected_files.size(), file_name.trim_prefix("res://"), file_size / 1024);
Vector<String> changed_elements;
Vector<String> reason;
@@ -2118,7 +2120,7 @@ int ProjectConverter3To4::validate_conversion() {
uint64_t start_time = Time::get_singleton()->get_ticks_msec();
if (file_name.ends_with(".shader")) {
- reason.append("\tFile extension will be renamed from `shader` to `gdshader`.");
+ reason.append("\tFile extension will be renamed from \"shader\" to \"gdshader\".");
}
if (file_size < uint64_t(maximum_file_size)) {
@@ -2180,7 +2182,7 @@ int ProjectConverter3To4::validate_conversion() {
} else if (file_name.ends_with(".csproj")) {
// TODO
} else {
- ERR_PRINT(file_name + " is not supported!");
+ ERR_PRINT(vformat("\"%s\", is not supported!", file_name));
continue;
}
@@ -2190,14 +2192,14 @@ int ProjectConverter3To4::validate_conversion() {
}
}
} else {
- reason.append("\tERROR: File has exceeded the maximum size allowed - " + itos(maximum_file_size / 1024) + " KB");
+ reason.append(vformat("\tERROR: File has exceeded the maximum size allowed - %d KB.", maximum_file_size / 1024));
is_ignored = true;
}
uint64_t end_time = Time::get_singleton()->get_ticks_msec();
- String end_message = " Checking file took " + itos(end_time - start_time) + " ms.";
+ String end_message = vformat(" Checking file took %10.3f ms.", (end_time - start_time) / 1000.0);
if (ignored_lines != 0) {
- end_message += " Ignored " + itos(ignored_lines) + " lines, because their length exceeds maximum allowed characters - " + itos(maximum_line_length);
+ end_message += vformat(" Ignored %d lines, because their length exceeds maximum allowed characters - %d.", ignored_lines, maximum_line_length);
}
print_line(end_message);
@@ -2214,13 +2216,13 @@ int ProjectConverter3To4::validate_conversion() {
}
}
- print_line("Checking for valid conversion ended - all files(" + itos(collected_files.size()) + "), files which would be converted(" + itos(converted_files) + "), files which would not be converted(" + itos(collected_files.size() - converted_files) + ").");
+ print_line(vformat("Checking for valid conversion ended - all files(%d), files which would be converted(%d), files which would not be converted(%d).", collected_files.size(), converted_files, collected_files.size() - converted_files));
uint64_t conversion_end_time = Time::get_singleton()->get_ticks_msec();
- print_line("Conversion of all files took " + itos(conversion_end_time - conversion_start_time) + " ms.");
+ print_line(vformat("Conversion of all files took %10.3f seconds.", (conversion_end_time - conversion_start_time) / 1000.0));
return 0;
}
-// Collect files which will be checked, it will not touch txt, mp4, wav etc. files
+// Collect files which will be checked, excluding ".txt", ".mp4", ".wav" etc. files.
Vector<String> ProjectConverter3To4::check_for_files() {
Vector<String> collected_files = Vector<String>();
@@ -2230,7 +2232,7 @@ Vector<String> ProjectConverter3To4::check_for_files() {
core_bind::Directory dir = core_bind::Directory();
while (!directories_to_check.is_empty()) {
String path = directories_to_check.get(directories_to_check.size() - 1); // Is there any pop_back function?
- directories_to_check.resize(directories_to_check.size() - 1); // Remove last element
+ directories_to_check.resize(directories_to_check.size() - 1); // Remove last element.
if (dir.open(path) == OK) {
dir.set_include_hidden(true);
dir.list_dir_begin();
@@ -2267,10 +2269,7 @@ bool ProjectConverter3To4::test_conversion_gdscript_builtin(String name, String
Vector<String> got = name.split("\n");
(this->*func)(got, reg_container, builtin_script);
String got_str = collect_string_from_vector(got);
- if (expected != got_str) {
- ERR_PRINT("Failed to convert " + what + " `" + name + "` to `" + expected + "`, got instead `" + got_str + "`");
- return false;
- }
+ ERR_FAIL_COND_V_MSG(expected != got_str, false, vformat("Failed to convert %s \"%s\" to \"%s\", got instead \"%s\"", what, name, expected, got_str));
return true;
}
@@ -2279,10 +2278,7 @@ bool ProjectConverter3To4::test_conversion_with_regex(String name, String expect
Vector<String> got = name.split("\n");
(this->*func)(got, reg_container);
String got_str = collect_string_from_vector(got);
- if (expected != got_str) {
- ERR_PRINT("Failed to convert " + what + " `" + name + "` to `" + expected + "`, got instead `" + got_str + "`");
- return false;
- }
+ ERR_FAIL_COND_V_MSG(expected != got_str, false, vformat("Failed to convert %s \"%s\" to \"%s\", got instead \"%s\"", what, name, expected, got_str));
return true;
}
@@ -2291,187 +2287,185 @@ bool ProjectConverter3To4::test_conversion_basic(String name, String expected, c
Vector<String> got = name.split("\n");
rename_common(array, regex_cache, got);
String got_str = collect_string_from_vector(got);
- if (expected != got_str) {
- ERR_PRINT("Failed to convert " + what + " `" + name + "` to `" + expected + "`, got instead `" + got_str + "`");
- return false;
- }
+ ERR_FAIL_COND_V_MSG(expected != got_str, false, vformat("Failed to convert %s \"%s\" to \"%s\", got instead \"%s\"", what, name, expected, got_str));
+
return true;
}
-// Validate if conversions are proper
+// Validate if conversions are proper.
bool ProjectConverter3To4::test_conversion(RegExContainer &reg_container) {
bool valid = true;
- valid = valid & test_conversion_basic("TYPE_REAL", "TYPE_FLOAT", enum_renames, reg_container.enum_regexes, "enum");
+ valid = valid && test_conversion_basic("TYPE_REAL", "TYPE_FLOAT", enum_renames, reg_container.enum_regexes, "enum");
- valid = valid & test_conversion_basic("can_instance", "can_instantiate", gdscript_function_renames, reg_container.gdscript_function_regexes, "gdscript function");
+ valid = valid && test_conversion_basic("can_instance", "can_instantiate", gdscript_function_renames, reg_container.gdscript_function_regexes, "gdscript function");
- valid = valid & test_conversion_basic("CanInstance", "CanInstantiate", csharp_function_renames, reg_container.csharp_function_regexes, "csharp function");
+ valid = valid && test_conversion_basic("CanInstance", "CanInstantiate", csharp_function_renames, reg_container.csharp_function_regexes, "csharp function");
- valid = valid & test_conversion_basic("translation", "position", gdscript_properties_renames, reg_container.gdscript_properties_regexes, "gdscript property");
+ valid = valid && test_conversion_basic("translation", "position", gdscript_properties_renames, reg_container.gdscript_properties_regexes, "gdscript property");
- valid = valid & test_conversion_basic("Translation", "Position", csharp_properties_renames, reg_container.csharp_properties_regexes, "csharp property");
+ valid = valid && test_conversion_basic("Translation", "Position", csharp_properties_renames, reg_container.csharp_properties_regexes, "csharp property");
- valid = valid & test_conversion_basic("NORMALMAP", "NORMAL_MAP", shaders_renames, reg_container.shaders_regexes, "shader");
+ valid = valid && test_conversion_basic("NORMALMAP", "NORMAL_MAP", shaders_renames, reg_container.shaders_regexes, "shader");
- valid = valid & test_conversion_basic("text_entered", "text_submitted", gdscript_signals_renames, reg_container.gdscript_signals_regexes, "gdscript signal");
+ valid = valid && test_conversion_basic("text_entered", "text_submitted", gdscript_signals_renames, reg_container.gdscript_signals_regexes, "gdscript signal");
- valid = valid & test_conversion_basic("TextEntered", "TextSubmitted", csharp_signals_renames, reg_container.csharp_signal_regexes, "csharp signal");
+ valid = valid && test_conversion_basic("TextEntered", "TextSubmitted", csharp_signals_renames, reg_container.csharp_signal_regexes, "csharp signal");
- valid = valid & test_conversion_basic("audio/channel_disable_threshold_db", "audio/buses/channel_disable_threshold_db", project_settings_renames, reg_container.project_settings_regexes, "project setting");
+ valid = valid && test_conversion_basic("audio/channel_disable_threshold_db", "audio/buses/channel_disable_threshold_db", project_settings_renames, reg_container.project_settings_regexes, "project setting");
- valid = valid & test_conversion_basic("Transform", "Transform3D", builtin_types_renames, reg_container.builtin_types_regexes, "builtin type");
+ valid = valid && test_conversion_basic("Transform", "Transform3D", builtin_types_renames, reg_container.builtin_types_regexes, "builtin type");
- // Custom Renames
+ // Custom Renames.
- valid = valid & test_conversion_with_regex("(Connect(A,B,C,D,E,F,G) != OK):", "(Connect(A,new Callable(B,C),D,E,F,G) != OK):", &ProjectConverter3To4::rename_csharp_functions, "custom rename csharp", reg_container);
- valid = valid & test_conversion_with_regex("(Disconnect(A,B,C) != OK):", "(Disconnect(A,new Callable(B,C)) != OK):", &ProjectConverter3To4::rename_csharp_functions, "custom rename csharp", reg_container);
- valid = valid & test_conversion_with_regex("(IsConnected(A,B,C) != OK):", "(IsConnected(A,new Callable(B,C)) != OK):", &ProjectConverter3To4::rename_csharp_functions, "custom rename", reg_container);
+ valid = valid && test_conversion_with_regex("(Connect(A,B,C,D,E,F,G) != OK):", "(Connect(A,new Callable(B,C),D,E,F,G) != OK):", &ProjectConverter3To4::rename_csharp_functions, "custom rename csharp", reg_container);
+ valid = valid && test_conversion_with_regex("(Disconnect(A,B,C) != OK):", "(Disconnect(A,new Callable(B,C)) != OK):", &ProjectConverter3To4::rename_csharp_functions, "custom rename csharp", reg_container);
+ valid = valid && test_conversion_with_regex("(IsConnected(A,B,C) != OK):", "(IsConnected(A,new Callable(B,C)) != OK):", &ProjectConverter3To4::rename_csharp_functions, "custom rename", reg_container);
- valid = valid & test_conversion_with_regex("[Remote]", "[RPC(MultiplayerAPI.RPCMode.AnyPeer)]", &ProjectConverter3To4::rename_csharp_attributes, "custom rename csharp", reg_container);
- valid = valid & test_conversion_with_regex("[RemoteSync]", "[RPC(MultiplayerAPI.RPCMode.AnyPeer, CallLocal = true)]", &ProjectConverter3To4::rename_csharp_attributes, "custom rename csharp", reg_container);
- valid = valid & test_conversion_with_regex("[Sync]", "[RPC(MultiplayerAPI.RPCMode.AnyPeer, CallLocal = true)]", &ProjectConverter3To4::rename_csharp_attributes, "custom rename csharp", reg_container);
- valid = valid & test_conversion_with_regex("[Slave]", "[RPC]", &ProjectConverter3To4::rename_csharp_attributes, "custom rename csharp", reg_container);
- valid = valid & test_conversion_with_regex("[Puppet]", "[RPC]", &ProjectConverter3To4::rename_csharp_attributes, "custom rename csharp", reg_container);
- valid = valid & test_conversion_with_regex("[PuppetSync]", "[RPC(CallLocal = true)]", &ProjectConverter3To4::rename_csharp_attributes, "custom rename csharp", reg_container);
- valid = valid & test_conversion_with_regex("[Master]", "The master and mastersync rpc behavior is not officially supported anymore. Try using another keyword or making custom logic using Multiplayer.GetRemoteSenderId()\n[RPC]", &ProjectConverter3To4::rename_csharp_attributes, "custom rename csharp", reg_container);
- valid = valid & test_conversion_with_regex("[MasterSync]", "The master and mastersync rpc behavior is not officially supported anymore. Try using another keyword or making custom logic using Multiplayer.GetRemoteSenderId()\n[RPC(CallLocal = true)]", &ProjectConverter3To4::rename_csharp_attributes, "custom rename csharp", reg_container);
-
- valid = valid & test_conversion_gdscript_builtin("OS.window_fullscreen = Settings.fullscreen", "ProjectSettings.set(\"display/window/size/fullscreen\", Settings.fullscreen)", &ProjectConverter3To4::rename_gdscript_functions, "custom rename", reg_container, false);
- valid = valid & test_conversion_gdscript_builtin("OS.window_fullscreen = Settings.fullscreen", "ProjectSettings.set(\\\"display/window/size/fullscreen\\\", Settings.fullscreen)", &ProjectConverter3To4::rename_gdscript_functions, "custom rename", reg_container, true);
- valid = valid & test_conversion_gdscript_builtin("OS.get_window_safe_area()", "DisplayServer.get_display_safe_area()", &ProjectConverter3To4::rename_gdscript_functions, "custom rename", reg_container, false);
-
- valid = valid & test_conversion_gdscript_builtin("\tvar aa = roman(r.move_and_slide( a, b, c, d, e, f )) # Roman", "\tr.set_velocity(a)\n\tr.set_up_direction(b)\n\tr.set_floor_stop_on_slope_enabled(c)\n\tr.set_max_slides(d)\n\tr.set_floor_max_angle(e)\n\t# TODOConverter40 infinite_inertia were removed in Godot 4.0 - previous value `f`\n\tr.move_and_slide()\n\tvar aa = roman(r.velocity) # Roman", &ProjectConverter3To4::rename_gdscript_functions, "custom rename", reg_container, false);
- valid = valid & test_conversion_gdscript_builtin("\tvar aa = roman(r.move_and_slide_with_snap( a, g, b, c, d, e, f )) # Roman", "\tr.set_velocity(a)\n\t# TODOConverter40 looks that snap in Godot 4.0 is float, not vector like in Godot 3 - previous value `g`\n\tr.set_up_direction(b)\n\tr.set_floor_stop_on_slope_enabled(c)\n\tr.set_max_slides(d)\n\tr.set_floor_max_angle(e)\n\t# TODOConverter40 infinite_inertia were removed in Godot 4.0 - previous value `f`\n\tr.move_and_slide()\n\tvar aa = roman(r.velocity) # Roman", &ProjectConverter3To4::rename_gdscript_functions, "custom rename", reg_container, false);
+ valid = valid && test_conversion_with_regex("[Remote]", "[RPC(MultiplayerAPI.RPCMode.AnyPeer)]", &ProjectConverter3To4::rename_csharp_attributes, "custom rename csharp", reg_container);
+ valid = valid && test_conversion_with_regex("[RemoteSync]", "[RPC(MultiplayerAPI.RPCMode.AnyPeer, CallLocal = true)]", &ProjectConverter3To4::rename_csharp_attributes, "custom rename csharp", reg_container);
+ valid = valid && test_conversion_with_regex("[Sync]", "[RPC(MultiplayerAPI.RPCMode.AnyPeer, CallLocal = true)]", &ProjectConverter3To4::rename_csharp_attributes, "custom rename csharp", reg_container);
+ valid = valid && test_conversion_with_regex("[Slave]", "[RPC]", &ProjectConverter3To4::rename_csharp_attributes, "custom rename csharp", reg_container);
+ valid = valid && test_conversion_with_regex("[Puppet]", "[RPC]", &ProjectConverter3To4::rename_csharp_attributes, "custom rename csharp", reg_container);
+ valid = valid && test_conversion_with_regex("[PuppetSync]", "[RPC(CallLocal = true)]", &ProjectConverter3To4::rename_csharp_attributes, "custom rename csharp", reg_container);
+ valid = valid && test_conversion_with_regex("[Master]", "The master and mastersync rpc behavior is not officially supported anymore. Try using another keyword or making custom logic using Multiplayer.GetRemoteSenderId()\n[RPC]", &ProjectConverter3To4::rename_csharp_attributes, "custom rename csharp", reg_container);
+ valid = valid && test_conversion_with_regex("[MasterSync]", "The master and mastersync rpc behavior is not officially supported anymore. Try using another keyword or making custom logic using Multiplayer.GetRemoteSenderId()\n[RPC(CallLocal = true)]", &ProjectConverter3To4::rename_csharp_attributes, "custom rename csharp", reg_container);
+
+ valid = valid && test_conversion_gdscript_builtin("OS.window_fullscreen = Settings.fullscreen", "ProjectSettings.set(\"display/window/size/fullscreen\", Settings.fullscreen)", &ProjectConverter3To4::rename_gdscript_functions, "custom rename", reg_container, false);
+ valid = valid && test_conversion_gdscript_builtin("OS.window_fullscreen = Settings.fullscreen", "ProjectSettings.set(\\\"display/window/size/fullscreen\\\", Settings.fullscreen)", &ProjectConverter3To4::rename_gdscript_functions, "custom rename", reg_container, true);
+ valid = valid && test_conversion_gdscript_builtin("OS.get_window_safe_area()", "DisplayServer.get_display_safe_area()", &ProjectConverter3To4::rename_gdscript_functions, "custom rename", reg_container, false);
+
+ valid = valid && test_conversion_gdscript_builtin("\tvar aa = roman(r.move_and_slide( a, b, c, d, e, f )) # Roman", "\tr.set_velocity(a)\n\tr.set_up_direction(b)\n\tr.set_floor_stop_on_slope_enabled(c)\n\tr.set_max_slides(d)\n\tr.set_floor_max_angle(e)\n\t# TODOConverter40 infinite_inertia were removed in Godot 4.0 - previous value `f`\n\tr.move_and_slide()\n\tvar aa = roman(r.velocity) # Roman", &ProjectConverter3To4::rename_gdscript_functions, "custom rename", reg_container, false);
+ valid = valid && test_conversion_gdscript_builtin("\tvar aa = roman(r.move_and_slide_with_snap( a, g, b, c, d, e, f )) # Roman", "\tr.set_velocity(a)\n\t# TODOConverter40 looks that snap in Godot 4.0 is float, not vector like in Godot 3 - previous value `g`\n\tr.set_up_direction(b)\n\tr.set_floor_stop_on_slope_enabled(c)\n\tr.set_max_slides(d)\n\tr.set_floor_max_angle(e)\n\t# TODOConverter40 infinite_inertia were removed in Godot 4.0 - previous value `f`\n\tr.move_and_slide()\n\tvar aa = roman(r.velocity) # Roman", &ProjectConverter3To4::rename_gdscript_functions, "custom rename", reg_container, false);
- valid = valid & test_conversion_gdscript_builtin("list_dir_begin( a , b )", "list_dir_begin() # TODOGODOT4 fill missing arguments https://github.com/godotengine/godot/pull/40547", &ProjectConverter3To4::rename_gdscript_functions, "custom rename", reg_container, false);
- valid = valid & test_conversion_gdscript_builtin("list_dir_begin( a )", "list_dir_begin() # TODOGODOT4 fill missing arguments https://github.com/godotengine/godot/pull/40547", &ProjectConverter3To4::rename_gdscript_functions, "custom rename", reg_container, false);
- valid = valid & test_conversion_gdscript_builtin("list_dir_begin( )", "list_dir_begin() # TODOGODOT4 fill missing arguments https://github.com/godotengine/godot/pull/40547", &ProjectConverter3To4::rename_gdscript_functions, "custom rename", reg_container, false);
+ valid = valid && test_conversion_gdscript_builtin("list_dir_begin( a , b )", "list_dir_begin() # TODOGODOT4 fill missing arguments https://github.com/godotengine/godot/pull/40547", &ProjectConverter3To4::rename_gdscript_functions, "custom rename", reg_container, false);
+ valid = valid && test_conversion_gdscript_builtin("list_dir_begin( a )", "list_dir_begin() # TODOGODOT4 fill missing arguments https://github.com/godotengine/godot/pull/40547", &ProjectConverter3To4::rename_gdscript_functions, "custom rename", reg_container, false);
+ valid = valid && test_conversion_gdscript_builtin("list_dir_begin( )", "list_dir_begin() # TODOGODOT4 fill missing arguments https://github.com/godotengine/godot/pull/40547", &ProjectConverter3To4::rename_gdscript_functions, "custom rename", reg_container, false);
- valid = valid & test_conversion_gdscript_builtin("sort_custom( a , b )", "sort_custom(Callable(a,b))", &ProjectConverter3To4::rename_gdscript_functions, "custom rename", reg_container, false);
-
- valid = valid & test_conversion_gdscript_builtin("func c(var a, var b)", "func c(a, b)", &ProjectConverter3To4::rename_gdscript_functions, "custom rename", reg_container, false);
+ valid = valid && test_conversion_gdscript_builtin("sort_custom( a , b )", "sort_custom(Callable(a,b))", &ProjectConverter3To4::rename_gdscript_functions, "custom rename", reg_container, false);
+
+ valid = valid && test_conversion_gdscript_builtin("func c(var a, var b)", "func c(a, b)", &ProjectConverter3To4::rename_gdscript_functions, "custom rename", reg_container, false);
- valid = valid & test_conversion_gdscript_builtin("draw_line(1, 2, 3, 4, 5)", "draw_line(1,2,3,4)", &ProjectConverter3To4::rename_gdscript_functions, "custom rename", reg_container, false);
+ valid = valid && test_conversion_gdscript_builtin("draw_line(1, 2, 3, 4, 5)", "draw_line(1,2,3,4)", &ProjectConverter3To4::rename_gdscript_functions, "custom rename", reg_container, false);
- valid = valid & test_conversion_gdscript_builtin("\timage.lock()", "\tfalse # image.lock() # TODOConverter40, image no longer require locking, `false` helps to not broke one line if/else, so can be freely removed", &ProjectConverter3To4::rename_gdscript_functions, "custom rename", reg_container, false);
- valid = valid & test_conversion_gdscript_builtin("\timage.unlock()", "\tfalse # image.unlock() # TODOConverter40, image no longer require locking, `false` helps to not broke one line if/else, so can be freely removed", &ProjectConverter3To4::rename_gdscript_functions, "custom rename", reg_container, false);
- valid = valid & test_conversion_gdscript_builtin("\troman.image.unlock()", "\tfalse # roman.image.unlock() # TODOConverter40, image no longer require locking, `false` helps to not broke one line if/else, so can be freely removed", &ProjectConverter3To4::rename_gdscript_functions, "custom rename", reg_container, false);
- valid = valid & test_conversion_gdscript_builtin("\tmtx.lock()", "\tmtx.lock()", &ProjectConverter3To4::rename_gdscript_functions, "custom rename", reg_container, false);
- valid = valid & test_conversion_gdscript_builtin("\tmutex.unlock()", "\tmutex.unlock()", &ProjectConverter3To4::rename_gdscript_functions, "custom rename", reg_container, false);
+ valid = valid && test_conversion_gdscript_builtin("\timage.lock()", "\tfalse # image.lock() # TODOConverter40, Image no longer requires locking, `false` helps to not break one line if/else, so it can freely be removed", &ProjectConverter3To4::rename_gdscript_functions, "custom rename", reg_container, false);
+ valid = valid && test_conversion_gdscript_builtin("\timage.unlock()", "\tfalse # image.unlock() # TODOConverter40, Image no longer requires locking, `false` helps to not break one line if/else, so it can freely be removed", &ProjectConverter3To4::rename_gdscript_functions, "custom rename", reg_container, false);
+ valid = valid && test_conversion_gdscript_builtin("\troman.image.unlock()", "\tfalse # roman.image.unlock() # TODOConverter40, Image no longer requires locking, `false` helps to not break one line if/else, so it can freely be removed", &ProjectConverter3To4::rename_gdscript_functions, "custom rename", reg_container, false);
+ valid = valid && test_conversion_gdscript_builtin("\tmtx.lock()", "\tmtx.lock()", &ProjectConverter3To4::rename_gdscript_functions, "custom rename", reg_container, false);
+ valid = valid && test_conversion_gdscript_builtin("\tmutex.unlock()", "\tmutex.unlock()", &ProjectConverter3To4::rename_gdscript_functions, "custom rename", reg_container, false);
- valid = valid & test_conversion_with_regex("extends CSGBox", "extends CSGBox3D", &ProjectConverter3To4::rename_classes, "classes", reg_container);
- valid = valid & test_conversion_with_regex("CSGBox", "CSGBox3D", &ProjectConverter3To4::rename_classes, "classes", reg_container);
- valid = valid & test_conversion_with_regex("Spatial", "Node3D", &ProjectConverter3To4::rename_classes, "classes", reg_container);
- valid = valid & test_conversion_with_regex("Spatial.tscn", "Spatial.tscn", &ProjectConverter3To4::rename_classes, "classes", reg_container);
- valid = valid & test_conversion_with_regex("Spatial.gd", "Spatial.gd", &ProjectConverter3To4::rename_classes, "classes", reg_container);
- valid = valid & test_conversion_with_regex("Spatial.shader", "Spatial.shader", &ProjectConverter3To4::rename_classes, "classes", reg_container);
- valid = valid & test_conversion_with_regex("Spatial.other", "Node3D.other", &ProjectConverter3To4::rename_classes, "classes", reg_container);
-
- valid = valid & test_conversion_with_regex("\nonready", "\n@onready", &ProjectConverter3To4::rename_gdscript_keywords, "gdscript keyword", reg_container);
- valid = valid & test_conversion_with_regex("onready", "@onready", &ProjectConverter3To4::rename_gdscript_keywords, "gdscript keyword", reg_container);
- valid = valid & test_conversion_with_regex(" onready", " onready", &ProjectConverter3To4::rename_gdscript_keywords, "gdscript keyword", reg_container);
- valid = valid & test_conversion_with_regex("\nexport", "\n@export", &ProjectConverter3To4::rename_gdscript_keywords, "gdscript keyword", reg_container);
- valid = valid & test_conversion_with_regex("\texport", "\t@export", &ProjectConverter3To4::rename_gdscript_keywords, "gdscript keyword", reg_container);
- valid = valid & test_conversion_with_regex("\texport_dialog", "\texport_dialog", &ProjectConverter3To4::rename_gdscript_keywords, "gdscript keyword", reg_container);
- valid = valid & test_conversion_with_regex("export", "@export", &ProjectConverter3To4::rename_gdscript_keywords, "gdscript keyword", reg_container);
- valid = valid & test_conversion_with_regex(" export", " export", &ProjectConverter3To4::rename_gdscript_keywords, "gdscript keyword", reg_container);
- valid = valid & test_conversion_with_regex("tool", "@tool", &ProjectConverter3To4::rename_gdscript_keywords, "gdscript keyword", reg_container);
- valid = valid & test_conversion_with_regex("\n tool", "\n tool", &ProjectConverter3To4::rename_gdscript_keywords, "gdscript keyword", reg_container);
- valid = valid & test_conversion_with_regex("\n\ntool", "\n\n@tool", &ProjectConverter3To4::rename_gdscript_keywords, "gdscript keyword", reg_container);
- valid = valid & test_conversion_with_regex("\n\nremote func", "\n\n@rpc(any_peer) func", &ProjectConverter3To4::rename_gdscript_keywords, "gdscript keyword", reg_container);
- valid = valid & test_conversion_with_regex("\n\nremotesync func", "\n\n@rpc(any_peer, call_local) func", &ProjectConverter3To4::rename_gdscript_keywords, "gdscript keyword", reg_container);
- valid = valid & test_conversion_with_regex("\n\nsync func", "\n\n@rpc(any_peer, call_local) func", &ProjectConverter3To4::rename_gdscript_keywords, "gdscript keyword", reg_container);
- valid = valid & test_conversion_with_regex("\n\nslave func", "\n\n@rpc func", &ProjectConverter3To4::rename_gdscript_keywords, "gdscript keyword", reg_container);
- valid = valid & test_conversion_with_regex("\n\npuppet func", "\n\n@rpc func", &ProjectConverter3To4::rename_gdscript_keywords, "gdscript keyword", reg_container);
- valid = valid & test_conversion_with_regex("\n\npuppetsync func", "\n\n@rpc(call_local) func", &ProjectConverter3To4::rename_gdscript_keywords, "gdscript keyword", reg_container);
- valid = valid & test_conversion_with_regex("\n\nmaster func", "\n\nThe master and mastersync rpc behavior is not officially supported anymore. Try using another keyword or making custom logic using get_multiplayer().get_remote_sender_id()\n@rpc func", &ProjectConverter3To4::rename_gdscript_keywords, "gdscript keyword", reg_container);
- valid = valid & test_conversion_with_regex("\n\nmastersync func", "\n\nThe master and mastersync rpc behavior is not officially supported anymore. Try using another keyword or making custom logic using get_multiplayer().get_remote_sender_id()\n@rpc(call_local) func", &ProjectConverter3To4::rename_gdscript_keywords, "gdscript keyword", reg_container);
-
- valid = valid & test_conversion_gdscript_builtin("var size : Vector2 = Vector2() setget set_function , get_function", "var size : Vector2 = Vector2() :\n get:\n return size # TODOConverter40 Copy here content of get_function\n set(mod_value):\n mod_value # TODOConverter40 Copy here content of set_function", &ProjectConverter3To4::rename_gdscript_functions, "custom rename", reg_container, false);
- valid = valid & test_conversion_gdscript_builtin("var size : Vector2 = Vector2() setget set_function , ", "var size : Vector2 = Vector2() :\n get:\n return size # TODOConverter40 Non existent get function \n set(mod_value):\n mod_value # TODOConverter40 Copy here content of set_function", &ProjectConverter3To4::rename_gdscript_functions, "custom rename", reg_container, false);
- valid = valid & test_conversion_gdscript_builtin("var size : Vector2 = Vector2() setget set_function", "var size : Vector2 = Vector2() :\n get:\n return size # TODOConverter40 Non existent get function \n set(mod_value):\n mod_value # TODOConverter40 Copy here content of set_function", &ProjectConverter3To4::rename_gdscript_functions, "custom rename", reg_container, false);
- valid = valid & test_conversion_gdscript_builtin("var size : Vector2 = Vector2() setget , get_function", "var size : Vector2 = Vector2() :\n get:\n return size # TODOConverter40 Copy here content of get_function \n set(mod_value):\n mod_value # TODOConverter40 Non existent set function", &ProjectConverter3To4::rename_gdscript_functions, "custom rename", reg_container, false);
-
- valid = valid & test_conversion_gdscript_builtin("get_node(@", "get_node(", &ProjectConverter3To4::rename_gdscript_functions, "custom rename", reg_container, false);
-
- valid = valid & test_conversion_gdscript_builtin("yield(this, \"timeout\")", "await this.timeout", &ProjectConverter3To4::rename_gdscript_functions, "custom rename", reg_container, false);
- valid = valid & test_conversion_gdscript_builtin("yield(this, \\\"timeout\\\")", "await this.timeout", &ProjectConverter3To4::rename_gdscript_functions, "custom rename", reg_container, true);
-
- valid = valid & test_conversion_gdscript_builtin(" Transform.xform(Vector3(a,b,c)) ", " Transform * Vector3(a,b,c) ", &ProjectConverter3To4::rename_gdscript_functions, "custom rename", reg_container, false);
- valid = valid & test_conversion_gdscript_builtin(" Transform.xform_inv(Vector3(a,b,c)) ", " Vector3(a,b,c) * Transform ", &ProjectConverter3To4::rename_gdscript_functions, "custom rename", reg_container, false);
-
- valid = valid & test_conversion_gdscript_builtin("export(float) var lifetime = 3.0", "export var lifetime: float = 3.0", &ProjectConverter3To4::rename_gdscript_functions, "custom rename", reg_container, false);
- valid = valid & test_conversion_gdscript_builtin("export(String, 'AnonymousPro', 'CourierPrime') var _font_name = 'AnonymousPro'", "export var _font_name = 'AnonymousPro' # (String, 'AnonymousPro', 'CourierPrime')", &ProjectConverter3To4::rename_gdscript_functions, "custom rename", reg_container, false); // TODO, this is only a workaround
- valid = valid & test_conversion_gdscript_builtin("export(PackedScene) var mob_scene", "export var mob_scene: PackedScene", &ProjectConverter3To4::rename_gdscript_functions, "custom rename", reg_container, false);
-
- valid = valid & test_conversion_gdscript_builtin("var d = parse_json(roman(sfs))", "var test_json_conv = JSON.new()\ntest_json_conv.parse(roman(sfs))\nvar d = test_json_conv.get_data()", &ProjectConverter3To4::rename_gdscript_functions, "custom rename", reg_container, false);
-
- valid = valid & test_conversion_gdscript_builtin("to_json( AA ) szon", "JSON.new().stringify( AA ) szon", &ProjectConverter3To4::rename_gdscript_functions, "custom rename", reg_container, false);
- valid = valid & test_conversion_gdscript_builtin("s to_json", "s JSON.new().stringify", &ProjectConverter3To4::rename_gdscript_functions, "custom rename", reg_container, false);
- valid = valid & test_conversion_gdscript_builtin("AF to_json2", "AF to_json2", &ProjectConverter3To4::rename_gdscript_functions, "custom rename", reg_container, false);
- valid = valid & test_conversion_gdscript_builtin("var rr = JSON.parse(a)", "var test_json_conv = JSON.new()\ntest_json_conv.parse(a)\nvar rr = test_json_conv.get_data()", &ProjectConverter3To4::rename_gdscript_functions, "custom rename", reg_container, false);
-
- valid = valid & test_conversion_gdscript_builtin("empty()", "is_empty()", &ProjectConverter3To4::rename_gdscript_functions, "custom rename", reg_container, false);
- valid = valid & test_conversion_gdscript_builtin(".empty", ".empty", &ProjectConverter3To4::rename_gdscript_functions, "custom rename", reg_container, false);
-
- valid = valid & test_conversion_gdscript_builtin(").roman(", ").roman(", &ProjectConverter3To4::rename_gdscript_functions, "custom rename", reg_container, false);
- valid = valid & test_conversion_gdscript_builtin("\t.roman(", "\tsuper.roman(", &ProjectConverter3To4::rename_gdscript_functions, "custom rename", reg_container, false);
- valid = valid & test_conversion_gdscript_builtin(" .roman(", " super.roman(", &ProjectConverter3To4::rename_gdscript_functions, "custom rename", reg_container, false);
- valid = valid & test_conversion_gdscript_builtin(".1", ".1", &ProjectConverter3To4::rename_gdscript_functions, "custom rename", reg_container, false);
- valid = valid & test_conversion_gdscript_builtin(" .1", " .1", &ProjectConverter3To4::rename_gdscript_functions, "custom rename", reg_container, false);
- valid = valid & test_conversion_gdscript_builtin("'.'", "'.'", &ProjectConverter3To4::rename_gdscript_functions, "custom rename", reg_container, false);
- valid = valid & test_conversion_gdscript_builtin("'.a'", "'.a'", &ProjectConverter3To4::rename_gdscript_functions, "custom rename", reg_container, false);
- valid = valid & test_conversion_gdscript_builtin("\t._input(_event)", "\tsuper._input(_event)", &ProjectConverter3To4::rename_gdscript_functions, "custom rename", reg_container, false);
-
- valid = valid & test_conversion_gdscript_builtin("(connect(A,B,C) != OK):", "(connect(A,Callable(B,C)) != OK):", &ProjectConverter3To4::rename_gdscript_functions, "custom rename", reg_container, false);
- valid = valid & test_conversion_gdscript_builtin("(connect(A,B,C,D) != OK):", "(connect(A,Callable(B,C).bind(D)) != OK):", &ProjectConverter3To4::rename_gdscript_functions, "custom rename", reg_container, false);
- valid = valid & test_conversion_gdscript_builtin("(connect(A,B,C,[D]) != OK):", "(connect(A,Callable(B,C).bind(D)) != OK):", &ProjectConverter3To4::rename_gdscript_functions, "custom rename", reg_container, false);
- valid = valid & test_conversion_gdscript_builtin("(connect(A,B,C,[D,E]) != OK):", "(connect(A,Callable(B,C).bind(D,E)) != OK):", &ProjectConverter3To4::rename_gdscript_functions, "custom rename", reg_container, false);
- valid = valid & test_conversion_gdscript_builtin("(connect(A,B,C,[D,E],F) != OK):", "(connect(A,Callable(B,C).bind(D,E),F) != OK):", &ProjectConverter3To4::rename_gdscript_functions, "custom rename", reg_container, false);
- valid = valid & test_conversion_gdscript_builtin("(connect(A,B,C,D,E) != OK):", "(connect(A,Callable(B,C).bind(D),E) != OK):", &ProjectConverter3To4::rename_gdscript_functions, "custom rename", reg_container, false);
-
- valid = valid & test_conversion_gdscript_builtin("(start(A,B) != OK):", "(start(Callable(A,B)) != OK):", &ProjectConverter3To4::rename_gdscript_functions, "custom rename", reg_container, false);
- valid = valid & test_conversion_gdscript_builtin("func start(A,B):", "func start(A,B):", &ProjectConverter3To4::rename_gdscript_functions, "custom rename", reg_container, false);
- valid = valid & test_conversion_gdscript_builtin("(start(A,B,C,D,E,F,G) != OK):", "(start(Callable(A,B).bind(C),D,E,F,G) != OK):", &ProjectConverter3To4::rename_gdscript_functions, "custom rename", reg_container, false);
- valid = valid & test_conversion_gdscript_builtin("disconnect(A,B,C) != OK):", "disconnect(A,Callable(B,C)) != OK):", &ProjectConverter3To4::rename_gdscript_functions, "custom rename", reg_container, false);
- valid = valid & test_conversion_gdscript_builtin("is_connected(A,B,C) != OK):", "is_connected(A,Callable(B,C)) != OK):", &ProjectConverter3To4::rename_gdscript_functions, "custom rename", reg_container, false);
- valid = valid & test_conversion_gdscript_builtin("is_connected(A,B,C))", "is_connected(A,Callable(B,C)))", &ProjectConverter3To4::rename_gdscript_functions, "custom rename", reg_container, false);
-
- valid = valid & test_conversion_gdscript_builtin("(tween_method(A,B,C,D,E).foo())", "(tween_method(Callable(A,B),C,D,E).foo())", &ProjectConverter3To4::rename_gdscript_functions, "custom rename", reg_container, false);
- valid = valid & test_conversion_gdscript_builtin("(tween_method(A,B,C,D,E,[F,G]).foo())", "(tween_method(Callable(A,B).bind(F,G),C,D,E).foo())", &ProjectConverter3To4::rename_gdscript_functions, "custom rename", reg_container, false);
- valid = valid & test_conversion_gdscript_builtin("(tween_callback(A,B).foo())", "(tween_callback(Callable(A,B)).foo())", &ProjectConverter3To4::rename_gdscript_functions, "custom rename", reg_container, false);
- valid = valid & test_conversion_gdscript_builtin("(tween_callback(A,B,[C,D]).foo())", "(tween_callback(Callable(A,B).bind(C,D)).foo())", &ProjectConverter3To4::rename_gdscript_functions, "custom rename", reg_container, false);
-
- valid = valid & test_conversion_gdscript_builtin("func _init(", "func _init(", &ProjectConverter3To4::rename_gdscript_functions, "custom rename", reg_container, false);
- valid = valid & test_conversion_gdscript_builtin("func _init(p_x:int)->void:", "func _init(p_x:int):", &ProjectConverter3To4::rename_gdscript_functions, "custom rename", reg_container, false);
- valid = valid & test_conversion_gdscript_builtin("q_PackedDataContainer._iter_init(variable1)", "q_PackedDataContainer._iter_init(variable1)", &ProjectConverter3To4::rename_gdscript_functions, "custom rename", reg_container, false);
-
- valid = valid & test_conversion_gdscript_builtin("assert(speed < 20, str(randi()%10))", "assert(speed < 20) #,str(randi()%10))", &ProjectConverter3To4::rename_gdscript_functions, "custom rename", reg_container, false);
- valid = valid & test_conversion_gdscript_builtin("assert(speed < 2)", "assert(speed < 2)", &ProjectConverter3To4::rename_gdscript_functions, "custom rename", reg_container, false);
- valid = valid & test_conversion_gdscript_builtin("assert(false, \"Missing type --\" + str(argument.type) + \"--, needs to be added to project\")", "assert(false) #,\"Missing type --\" + str(argument.type) + \"--, needs to be added to project\")", &ProjectConverter3To4::rename_gdscript_functions, "custom rename", reg_container, false);
-
- valid = valid & test_conversion_gdscript_builtin("create_from_image(aa, bb)", "create_from_image(aa) #,bb", &ProjectConverter3To4::rename_gdscript_functions, "custom rename", reg_container, false);
- valid = valid & test_conversion_gdscript_builtin("q_ImageTexture.create_from_image(variable1, variable2)", "q_ImageTexture.create_from_image(variable1) #,variable2", &ProjectConverter3To4::rename_gdscript_functions, "custom rename", reg_container, false);
-
- valid = valid & test_conversion_gdscript_builtin("set_cell_item(a, b, c, d ,e) # AA", "set_cell_item( Vector3(a,b,c) ,d,e) # AA", &ProjectConverter3To4::rename_gdscript_functions, "custom rename", reg_container, false);
- valid = valid & test_conversion_gdscript_builtin("set_cell_item(a, b)", "set_cell_item(a, b)", &ProjectConverter3To4::rename_gdscript_functions, "custom rename", reg_container, false);
- valid = valid & test_conversion_gdscript_builtin("get_cell_item_orientation(a, b,c)", "get_cell_item_orientation(Vector3i(a,b,c))", &ProjectConverter3To4::rename_gdscript_functions, "custom rename", reg_container, false);
- valid = valid & test_conversion_gdscript_builtin("get_cell_item(a, b,c)", "get_cell_item(Vector3i(a,b,c))", &ProjectConverter3To4::rename_gdscript_functions, "custom rename", reg_container, false);
- valid = valid & test_conversion_gdscript_builtin("map_to_world(a, b,c)", "map_to_local(Vector3i(a,b,c))", &ProjectConverter3To4::rename_gdscript_functions, "custom rename", reg_container, false);
-
- valid = valid & test_conversion_gdscript_builtin("PackedStringArray(req_godot).join('.')", "'.'.join(PackedStringArray(req_godot))", &ProjectConverter3To4::rename_gdscript_functions, "custom rename", reg_container, false);
- valid = valid & test_conversion_gdscript_builtin("=PackedStringArray(req_godot).join('.')", "='.'.join(PackedStringArray(req_godot))", &ProjectConverter3To4::rename_gdscript_functions, "custom rename", reg_container, false);
-
- valid = valid & test_conversion_gdscript_builtin("apply_force(position, impulse)", "apply_force(impulse, position)", &ProjectConverter3To4::rename_gdscript_functions, "custom rename", reg_container, false);
- valid = valid & test_conversion_gdscript_builtin("apply_impulse(position, impulse)", "apply_impulse(impulse, position)", &ProjectConverter3To4::rename_gdscript_functions, "custom rename", reg_container, false);
- valid = valid & test_conversion_gdscript_builtin("draw_rect(a,b,c,d,e).abc", "draw_rect(a,b,c,d).abc# e) TODOGODOT4 Antialiasing argument is missing", &ProjectConverter3To4::rename_gdscript_functions, "custom rename", reg_container, false);
- valid = valid & test_conversion_gdscript_builtin("get_focus_owner()", "get_viewport().gui_get_focus_owner()", &ProjectConverter3To4::rename_gdscript_functions, "custom rename", reg_container, false);
- valid = valid & test_conversion_gdscript_builtin("button.pressed = 1", "button.button_pressed = 1", &ProjectConverter3To4::rename_gdscript_functions, "custom rename", reg_container, false);
- valid = valid & test_conversion_gdscript_builtin("button.pressed=1", "button.button_pressed=1", &ProjectConverter3To4::rename_gdscript_functions, "custom rename", reg_container, false);
- valid = valid & test_conversion_gdscript_builtin("button.pressed SF", "button.pressed SF", &ProjectConverter3To4::rename_gdscript_functions, "custom rename", reg_container, false);
-
- valid = valid & test_conversion_with_regex("AAA Color.white AF", "AAA Color.WHITE AF", &ProjectConverter3To4::rename_colors, "custom rename", reg_container);
+ valid = valid && test_conversion_with_regex("extends CSGBox", "extends CSGBox3D", &ProjectConverter3To4::rename_classes, "classes", reg_container);
+ valid = valid && test_conversion_with_regex("CSGBox", "CSGBox3D", &ProjectConverter3To4::rename_classes, "classes", reg_container);
+ valid = valid && test_conversion_with_regex("Spatial", "Node3D", &ProjectConverter3To4::rename_classes, "classes", reg_container);
+ valid = valid && test_conversion_with_regex("Spatial.tscn", "Spatial.tscn", &ProjectConverter3To4::rename_classes, "classes", reg_container);
+ valid = valid && test_conversion_with_regex("Spatial.gd", "Spatial.gd", &ProjectConverter3To4::rename_classes, "classes", reg_container);
+ valid = valid && test_conversion_with_regex("Spatial.shader", "Spatial.shader", &ProjectConverter3To4::rename_classes, "classes", reg_container);
+ valid = valid && test_conversion_with_regex("Spatial.other", "Node3D.other", &ProjectConverter3To4::rename_classes, "classes", reg_container);
+
+ valid = valid && test_conversion_with_regex("\nonready", "\n@onready", &ProjectConverter3To4::rename_gdscript_keywords, "gdscript keyword", reg_container);
+ valid = valid && test_conversion_with_regex("onready", "@onready", &ProjectConverter3To4::rename_gdscript_keywords, "gdscript keyword", reg_container);
+ valid = valid && test_conversion_with_regex(" onready", " onready", &ProjectConverter3To4::rename_gdscript_keywords, "gdscript keyword", reg_container);
+ valid = valid && test_conversion_with_regex("\nexport", "\n@export", &ProjectConverter3To4::rename_gdscript_keywords, "gdscript keyword", reg_container);
+ valid = valid && test_conversion_with_regex("\texport", "\t@export", &ProjectConverter3To4::rename_gdscript_keywords, "gdscript keyword", reg_container);
+ valid = valid && test_conversion_with_regex("\texport_dialog", "\texport_dialog", &ProjectConverter3To4::rename_gdscript_keywords, "gdscript keyword", reg_container);
+ valid = valid && test_conversion_with_regex("export", "@export", &ProjectConverter3To4::rename_gdscript_keywords, "gdscript keyword", reg_container);
+ valid = valid && test_conversion_with_regex(" export", " export", &ProjectConverter3To4::rename_gdscript_keywords, "gdscript keyword", reg_container);
+ valid = valid && test_conversion_with_regex("tool", "@tool", &ProjectConverter3To4::rename_gdscript_keywords, "gdscript keyword", reg_container);
+ valid = valid && test_conversion_with_regex("\n tool", "\n tool", &ProjectConverter3To4::rename_gdscript_keywords, "gdscript keyword", reg_container);
+ valid = valid && test_conversion_with_regex("\n\ntool", "\n\n@tool", &ProjectConverter3To4::rename_gdscript_keywords, "gdscript keyword", reg_container);
+ valid = valid && test_conversion_with_regex("\n\nremote func", "\n\n@rpc(any_peer) func", &ProjectConverter3To4::rename_gdscript_keywords, "gdscript keyword", reg_container);
+ valid = valid && test_conversion_with_regex("\n\nremotesync func", "\n\n@rpc(any_peer, call_local) func", &ProjectConverter3To4::rename_gdscript_keywords, "gdscript keyword", reg_container);
+ valid = valid && test_conversion_with_regex("\n\nsync func", "\n\n@rpc(any_peer, call_local) func", &ProjectConverter3To4::rename_gdscript_keywords, "gdscript keyword", reg_container);
+ valid = valid && test_conversion_with_regex("\n\nslave func", "\n\n@rpc func", &ProjectConverter3To4::rename_gdscript_keywords, "gdscript keyword", reg_container);
+ valid = valid && test_conversion_with_regex("\n\npuppet func", "\n\n@rpc func", &ProjectConverter3To4::rename_gdscript_keywords, "gdscript keyword", reg_container);
+ valid = valid && test_conversion_with_regex("\n\npuppetsync func", "\n\n@rpc(call_local) func", &ProjectConverter3To4::rename_gdscript_keywords, "gdscript keyword", reg_container);
+ valid = valid && test_conversion_with_regex("\n\nmaster func", "\n\nThe master and mastersync rpc behavior is not officially supported anymore. Try using another keyword or making custom logic using get_multiplayer().get_remote_sender_id()\n@rpc func", &ProjectConverter3To4::rename_gdscript_keywords, "gdscript keyword", reg_container);
+ valid = valid && test_conversion_with_regex("\n\nmastersync func", "\n\nThe master and mastersync rpc behavior is not officially supported anymore. Try using another keyword or making custom logic using get_multiplayer().get_remote_sender_id()\n@rpc(call_local) func", &ProjectConverter3To4::rename_gdscript_keywords, "gdscript keyword", reg_container);
+
+ valid = valid && test_conversion_gdscript_builtin("var size : Vector2 = Vector2() setget set_function , get_function", "var size : Vector2 = Vector2() :\n get:\n return size # TODOConverter40 Copy here content of get_function\n set(mod_value):\n mod_value # TODOConverter40 Copy here content of set_function", &ProjectConverter3To4::rename_gdscript_functions, "custom rename", reg_container, false);
+ valid = valid && test_conversion_gdscript_builtin("var size : Vector2 = Vector2() setget set_function , ", "var size : Vector2 = Vector2() :\n get:\n return size # TODOConverter40 Non existent get function \n set(mod_value):\n mod_value # TODOConverter40 Copy here content of set_function", &ProjectConverter3To4::rename_gdscript_functions, "custom rename", reg_container, false);
+ valid = valid && test_conversion_gdscript_builtin("var size : Vector2 = Vector2() setget set_function", "var size : Vector2 = Vector2() :\n get:\n return size # TODOConverter40 Non existent get function \n set(mod_value):\n mod_value # TODOConverter40 Copy here content of set_function", &ProjectConverter3To4::rename_gdscript_functions, "custom rename", reg_container, false);
+ valid = valid && test_conversion_gdscript_builtin("var size : Vector2 = Vector2() setget , get_function", "var size : Vector2 = Vector2() :\n get:\n return size # TODOConverter40 Copy here content of get_function \n set(mod_value):\n mod_value # TODOConverter40 Non existent set function", &ProjectConverter3To4::rename_gdscript_functions, "custom rename", reg_container, false);
+
+ valid = valid && test_conversion_gdscript_builtin("get_node(@", "get_node(", &ProjectConverter3To4::rename_gdscript_functions, "custom rename", reg_container, false);
+
+ valid = valid && test_conversion_gdscript_builtin("yield(this, \"timeout\")", "await this.timeout", &ProjectConverter3To4::rename_gdscript_functions, "custom rename", reg_container, false);
+ valid = valid && test_conversion_gdscript_builtin("yield(this, \\\"timeout\\\")", "await this.timeout", &ProjectConverter3To4::rename_gdscript_functions, "custom rename", reg_container, true);
+
+ valid = valid && test_conversion_gdscript_builtin(" Transform.xform(Vector3(a,b,c)) ", " Transform * Vector3(a,b,c) ", &ProjectConverter3To4::rename_gdscript_functions, "custom rename", reg_container, false);
+ valid = valid && test_conversion_gdscript_builtin(" Transform.xform_inv(Vector3(a,b,c)) ", " Vector3(a,b,c) * Transform ", &ProjectConverter3To4::rename_gdscript_functions, "custom rename", reg_container, false);
+
+ valid = valid && test_conversion_gdscript_builtin("export(float) var lifetime = 3.0", "export var lifetime: float = 3.0", &ProjectConverter3To4::rename_gdscript_functions, "custom rename", reg_container, false);
+ valid = valid && test_conversion_gdscript_builtin("export(String, 'AnonymousPro', 'CourierPrime') var _font_name = 'AnonymousPro'", "export var _font_name = 'AnonymousPro' # (String, 'AnonymousPro', 'CourierPrime')", &ProjectConverter3To4::rename_gdscript_functions, "custom rename", reg_container, false); // TODO, this is only a workaround
+ valid = valid && test_conversion_gdscript_builtin("export(PackedScene) var mob_scene", "export var mob_scene: PackedScene", &ProjectConverter3To4::rename_gdscript_functions, "custom rename", reg_container, false);
+
+ valid = valid && test_conversion_gdscript_builtin("var d = parse_json(roman(sfs))", "var test_json_conv = JSON.new()\ntest_json_conv.parse(roman(sfs))\nvar d = test_json_conv.get_data()", &ProjectConverter3To4::rename_gdscript_functions, "custom rename", reg_container, false);
+
+ valid = valid && test_conversion_gdscript_builtin("to_json( AA ) szon", "JSON.new().stringify( AA ) szon", &ProjectConverter3To4::rename_gdscript_functions, "custom rename", reg_container, false);
+ valid = valid && test_conversion_gdscript_builtin("s to_json", "s JSON.new().stringify", &ProjectConverter3To4::rename_gdscript_functions, "custom rename", reg_container, false);
+ valid = valid && test_conversion_gdscript_builtin("AF to_json2", "AF to_json2", &ProjectConverter3To4::rename_gdscript_functions, "custom rename", reg_container, false);
+ valid = valid && test_conversion_gdscript_builtin("var rr = JSON.parse(a)", "var test_json_conv = JSON.new()\ntest_json_conv.parse(a)\nvar rr = test_json_conv.get_data()", &ProjectConverter3To4::rename_gdscript_functions, "custom rename", reg_container, false);
+
+ valid = valid && test_conversion_gdscript_builtin("empty()", "is_empty()", &ProjectConverter3To4::rename_gdscript_functions, "custom rename", reg_container, false);
+ valid = valid && test_conversion_gdscript_builtin(".empty", ".empty", &ProjectConverter3To4::rename_gdscript_functions, "custom rename", reg_container, false);
+
+ valid = valid && test_conversion_gdscript_builtin(").roman(", ").roman(", &ProjectConverter3To4::rename_gdscript_functions, "custom rename", reg_container, false);
+ valid = valid && test_conversion_gdscript_builtin("\t.roman(", "\tsuper.roman(", &ProjectConverter3To4::rename_gdscript_functions, "custom rename", reg_container, false);
+ valid = valid && test_conversion_gdscript_builtin(" .roman(", " super.roman(", &ProjectConverter3To4::rename_gdscript_functions, "custom rename", reg_container, false);
+ valid = valid && test_conversion_gdscript_builtin(".1", ".1", &ProjectConverter3To4::rename_gdscript_functions, "custom rename", reg_container, false);
+ valid = valid && test_conversion_gdscript_builtin(" .1", " .1", &ProjectConverter3To4::rename_gdscript_functions, "custom rename", reg_container, false);
+ valid = valid && test_conversion_gdscript_builtin("'.'", "'.'", &ProjectConverter3To4::rename_gdscript_functions, "custom rename", reg_container, false);
+ valid = valid && test_conversion_gdscript_builtin("'.a'", "'.a'", &ProjectConverter3To4::rename_gdscript_functions, "custom rename", reg_container, false);
+ valid = valid && test_conversion_gdscript_builtin("\t._input(_event)", "\tsuper._input(_event)", &ProjectConverter3To4::rename_gdscript_functions, "custom rename", reg_container, false);
+
+ valid = valid && test_conversion_gdscript_builtin("(connect(A,B,C) != OK):", "(connect(A,Callable(B,C)) != OK):", &ProjectConverter3To4::rename_gdscript_functions, "custom rename", reg_container, false);
+ valid = valid && test_conversion_gdscript_builtin("(connect(A,B,C,D) != OK):", "(connect(A,Callable(B,C).bind(D)) != OK):", &ProjectConverter3To4::rename_gdscript_functions, "custom rename", reg_container, false);
+ valid = valid && test_conversion_gdscript_builtin("(connect(A,B,C,[D]) != OK):", "(connect(A,Callable(B,C).bind(D)) != OK):", &ProjectConverter3To4::rename_gdscript_functions, "custom rename", reg_container, false);
+ valid = valid && test_conversion_gdscript_builtin("(connect(A,B,C,[D,E]) != OK):", "(connect(A,Callable(B,C).bind(D,E)) != OK):", &ProjectConverter3To4::rename_gdscript_functions, "custom rename", reg_container, false);
+ valid = valid && test_conversion_gdscript_builtin("(connect(A,B,C,[D,E],F) != OK):", "(connect(A,Callable(B,C).bind(D,E),F) != OK):", &ProjectConverter3To4::rename_gdscript_functions, "custom rename", reg_container, false);
+ valid = valid && test_conversion_gdscript_builtin("(connect(A,B,C,D,E) != OK):", "(connect(A,Callable(B,C).bind(D),E) != OK):", &ProjectConverter3To4::rename_gdscript_functions, "custom rename", reg_container, false);
+
+ valid = valid && test_conversion_gdscript_builtin("(start(A,B) != OK):", "(start(Callable(A,B)) != OK):", &ProjectConverter3To4::rename_gdscript_functions, "custom rename", reg_container, false);
+ valid = valid && test_conversion_gdscript_builtin("func start(A,B):", "func start(A,B):", &ProjectConverter3To4::rename_gdscript_functions, "custom rename", reg_container, false);
+ valid = valid && test_conversion_gdscript_builtin("(start(A,B,C,D,E,F,G) != OK):", "(start(Callable(A,B).bind(C),D,E,F,G) != OK):", &ProjectConverter3To4::rename_gdscript_functions, "custom rename", reg_container, false);
+ valid = valid && test_conversion_gdscript_builtin("disconnect(A,B,C) != OK):", "disconnect(A,Callable(B,C)) != OK):", &ProjectConverter3To4::rename_gdscript_functions, "custom rename", reg_container, false);
+ valid = valid && test_conversion_gdscript_builtin("is_connected(A,B,C) != OK):", "is_connected(A,Callable(B,C)) != OK):", &ProjectConverter3To4::rename_gdscript_functions, "custom rename", reg_container, false);
+ valid = valid && test_conversion_gdscript_builtin("is_connected(A,B,C))", "is_connected(A,Callable(B,C)))", &ProjectConverter3To4::rename_gdscript_functions, "custom rename", reg_container, false);
+
+ valid = valid && test_conversion_gdscript_builtin("(tween_method(A,B,C,D,E).foo())", "(tween_method(Callable(A,B),C,D,E).foo())", &ProjectConverter3To4::rename_gdscript_functions, "custom rename", reg_container, false);
+ valid = valid && test_conversion_gdscript_builtin("(tween_method(A,B,C,D,E,[F,G]).foo())", "(tween_method(Callable(A,B).bind(F,G),C,D,E).foo())", &ProjectConverter3To4::rename_gdscript_functions, "custom rename", reg_container, false);
+ valid = valid && test_conversion_gdscript_builtin("(tween_callback(A,B).foo())", "(tween_callback(Callable(A,B)).foo())", &ProjectConverter3To4::rename_gdscript_functions, "custom rename", reg_container, false);
+ valid = valid && test_conversion_gdscript_builtin("(tween_callback(A,B,[C,D]).foo())", "(tween_callback(Callable(A,B).bind(C,D)).foo())", &ProjectConverter3To4::rename_gdscript_functions, "custom rename", reg_container, false);
+
+ valid = valid && test_conversion_gdscript_builtin("func _init(", "func _init(", &ProjectConverter3To4::rename_gdscript_functions, "custom rename", reg_container, false);
+ valid = valid && test_conversion_gdscript_builtin("func _init(p_x:int)->void:", "func _init(p_x:int):", &ProjectConverter3To4::rename_gdscript_functions, "custom rename", reg_container, false);
+ valid = valid && test_conversion_gdscript_builtin("q_PackedDataContainer._iter_init(variable1)", "q_PackedDataContainer._iter_init(variable1)", &ProjectConverter3To4::rename_gdscript_functions, "custom rename", reg_container, false);
+
+ valid = valid && test_conversion_gdscript_builtin("assert(speed < 20, str(randi()%10))", "assert(speed < 20) #,str(randi()%10))", &ProjectConverter3To4::rename_gdscript_functions, "custom rename", reg_container, false);
+ valid = valid && test_conversion_gdscript_builtin("assert(speed < 2)", "assert(speed < 2)", &ProjectConverter3To4::rename_gdscript_functions, "custom rename", reg_container, false);
+ valid = valid && test_conversion_gdscript_builtin("assert(false, \"Missing type --\" + str(argument.type) + \"--, needs to be added to project\")", "assert(false) #,\"Missing type --\" + str(argument.type) + \"--, needs to be added to project\")", &ProjectConverter3To4::rename_gdscript_functions, "custom rename", reg_container, false);
+
+ valid = valid && test_conversion_gdscript_builtin("create_from_image(aa, bb)", "create_from_image(aa) #,bb", &ProjectConverter3To4::rename_gdscript_functions, "custom rename", reg_container, false);
+ valid = valid && test_conversion_gdscript_builtin("q_ImageTexture.create_from_image(variable1, variable2)", "q_ImageTexture.create_from_image(variable1) #,variable2", &ProjectConverter3To4::rename_gdscript_functions, "custom rename", reg_container, false);
+
+ valid = valid && test_conversion_gdscript_builtin("set_cell_item(a, b, c, d ,e) # AA", "set_cell_item( Vector3(a,b,c) ,d,e) # AA", &ProjectConverter3To4::rename_gdscript_functions, "custom rename", reg_container, false);
+ valid = valid && test_conversion_gdscript_builtin("set_cell_item(a, b)", "set_cell_item(a, b)", &ProjectConverter3To4::rename_gdscript_functions, "custom rename", reg_container, false);
+ valid = valid && test_conversion_gdscript_builtin("get_cell_item_orientation(a, b,c)", "get_cell_item_orientation(Vector3i(a,b,c))", &ProjectConverter3To4::rename_gdscript_functions, "custom rename", reg_container, false);
+ valid = valid && test_conversion_gdscript_builtin("get_cell_item(a, b,c)", "get_cell_item(Vector3i(a,b,c))", &ProjectConverter3To4::rename_gdscript_functions, "custom rename", reg_container, false);
+ valid = valid && test_conversion_gdscript_builtin("map_to_world(a, b,c)", "map_to_local(Vector3i(a,b,c))", &ProjectConverter3To4::rename_gdscript_functions, "custom rename", reg_container, false);
+
+ valid = valid && test_conversion_gdscript_builtin("PackedStringArray(req_godot).join('.')", "'.'.join(PackedStringArray(req_godot))", &ProjectConverter3To4::rename_gdscript_functions, "custom rename", reg_container, false);
+ valid = valid && test_conversion_gdscript_builtin("=PackedStringArray(req_godot).join('.')", "='.'.join(PackedStringArray(req_godot))", &ProjectConverter3To4::rename_gdscript_functions, "custom rename", reg_container, false);
+
+ valid = valid && test_conversion_gdscript_builtin("apply_force(position, impulse)", "apply_force(impulse, position)", &ProjectConverter3To4::rename_gdscript_functions, "custom rename", reg_container, false);
+ valid = valid && test_conversion_gdscript_builtin("apply_impulse(position, impulse)", "apply_impulse(impulse, position)", &ProjectConverter3To4::rename_gdscript_functions, "custom rename", reg_container, false);
+ valid = valid && test_conversion_gdscript_builtin("draw_rect(a,b,c,d,e).abc", "draw_rect(a,b,c,d).abc# e) TODOGODOT4 Antialiasing argument is missing", &ProjectConverter3To4::rename_gdscript_functions, "custom rename", reg_container, false);
+ valid = valid && test_conversion_gdscript_builtin("get_focus_owner()", "get_viewport().gui_get_focus_owner()", &ProjectConverter3To4::rename_gdscript_functions, "custom rename", reg_container, false);
+ valid = valid && test_conversion_gdscript_builtin("button.pressed = 1", "button.button_pressed = 1", &ProjectConverter3To4::rename_gdscript_functions, "custom rename", reg_container, false);
+ valid = valid && test_conversion_gdscript_builtin("button.pressed=1", "button.button_pressed=1", &ProjectConverter3To4::rename_gdscript_functions, "custom rename", reg_container, false);
+ valid = valid && test_conversion_gdscript_builtin("button.pressed SF", "button.pressed SF", &ProjectConverter3To4::rename_gdscript_functions, "custom rename", reg_container, false);
+
+ valid = valid && test_conversion_with_regex("AAA Color.white AF", "AAA Color.WHITE AF", &ProjectConverter3To4::rename_colors, "custom rename", reg_container);
// Custom rule conversion
{
@@ -2483,9 +2477,9 @@ bool ProjectConverter3To4::test_conversion(RegExContainer &reg_container) {
custom_rename(got, from, to);
String got_str = collect_string_from_vector(got);
if (got_str != expected) {
- ERR_PRINT("Failed to convert custom rename `" + name + "` to `" + expected + "`, got instead `" + got_str + "`");
+ ERR_PRINT(vformat("Failed to convert custom rename \"%s\" to \"%s\", got \"%s\", instead.", name, expected, got_str));
}
- valid = valid & (got_str == expected);
+ valid = valid && (got_str == expected);
}
// get_object_of_execution
@@ -2494,36 +2488,36 @@ bool ProjectConverter3To4::test_conversion(RegExContainer &reg_container) {
String expected = "kieliszek.";
String got = get_object_of_execution(base);
if (got != expected) {
- ERR_PRINT("Failed to get proper data from get_object_of_execution `" + base + "` should return `" + expected + "`(" + itos(expected.size()) + "), got instead `" + got + "`(" + itos(got.size()) + ")");
+ ERR_PRINT(vformat("Failed to get proper data from get_object_of_execution. \"%s\" should return \"%s\"(%d), got \"%s\"(%d), instead.", base, expected, expected.size(), got, got.size()));
}
- valid = valid & (got == expected);
+ valid = valid && (got == expected);
}
{
String base = "r.";
String expected = "r.";
String got = get_object_of_execution(base);
if (got != expected) {
- ERR_PRINT("Failed to get proper data from get_object_of_execution `" + base + "` should return `" + expected + "`(" + itos(expected.size()) + "), got instead `" + got + "`(" + itos(got.size()) + ")");
+ ERR_PRINT(vformat("Failed to get proper data from get_object_of_execution. \"%s\" should return \"%s\"(%d), got \"%s\"(%d), instead.", base, expected, expected.size(), got, got.size()));
}
- valid = valid & (got == expected);
+ valid = valid && (got == expected);
}
{
String base = "mortadela(";
String expected = "";
String got = get_object_of_execution(base);
if (got != expected) {
- ERR_PRINT("Failed to get proper data from get_object_of_execution `" + base + "` should return `" + expected + "`(" + itos(expected.size()) + "), got instead `" + got + "`(" + itos(got.size()) + ")");
+ ERR_PRINT(vformat("Failed to get proper data from get_object_of_execution. \"%s\" should return \"%s\"(%d), got \"%s\"(%d), instead.", base, expected, expected.size(), got, got.size()));
}
- valid = valid & (got == expected);
+ valid = valid && (got == expected);
}
{
String base = "var node = $world/ukraine/lviv.";
String expected = "$world/ukraine/lviv.";
String got = get_object_of_execution(base);
if (got != expected) {
- ERR_PRINT("Failed to get proper data from get_object_of_execution `" + base + "` should return `" + expected + "`(" + itos(expected.size()) + "), got instead `" + got + "`(" + itos(got.size()) + ")");
+ ERR_PRINT(vformat("Failed to get proper data from get_object_of_execution. \"%s\" should return \"%s\"(%d), got \"%s\"(%d), instead.", base, expected, expected.size(), got, got.size()));
}
- valid = valid & (got == expected);
+ valid = valid && (got == expected);
}
}
// get_starting_space
@@ -2532,9 +2526,9 @@ bool ProjectConverter3To4::test_conversion(RegExContainer &reg_container) {
String expected = "\t\t\t";
String got = get_starting_space(base);
if (got != expected) {
- ERR_PRINT("Failed to get proper data from get_starting_space `" + base + "` should return `" + expected + "`(" + itos(expected.size()) + "), got instead `" + got + "`(" + itos(got.size()) + ")");
+ ERR_PRINT(vformat("Failed to get proper data from get_object_of_execution. \"%s\" should return \"%s\"(%d), got \"%s\"(%d), instead.", base, expected, expected.size(), got, got.size()));
}
- valid = valid & (got == expected);
+ valid = valid && (got == expected);
}
// Parse Arguments
{
@@ -2546,9 +2540,9 @@ bool ProjectConverter3To4::test_conversion(RegExContainer &reg_container) {
got += part + "|||";
}
if (got != expected) {
- ERR_PRINT("Failed to get proper data from parse_arguments `" + line + "` should return `" + expected + "`(" + itos(expected.size()) + "), got instead `" + got + "`(" + itos(got.size()) + ")");
+ ERR_PRINT(vformat("Failed to get proper data from parse_arguments. \"%s\" should return \"%s\"(%d), got \"%s\"(%d), instead.", line, expected, expected.size(), got, got.size()));
}
- valid = valid & (got == expected);
+ valid = valid && (got == expected);
}
{
String line = "(a , b , c)";
@@ -2559,9 +2553,9 @@ bool ProjectConverter3To4::test_conversion(RegExContainer &reg_container) {
got += part + "|||";
}
if (got != expected) {
- ERR_PRINT("Failed to get proper data from parse_arguments `" + line + "` should return `" + expected + "`(" + itos(expected.size()) + "), got instead `" + got + "`(" + itos(got.size()) + ")");
+ ERR_PRINT(vformat("Failed to get proper data from parse_arguments. \"%s\" should return \"%s\"(%d), got \"%s\"(%d), instead.", line, expected, expected.size(), got, got.size()));
}
- valid = valid & (got == expected);
+ valid = valid && (got == expected);
}
{
String line = "(a , \"b,\" , c)";
@@ -2572,9 +2566,9 @@ bool ProjectConverter3To4::test_conversion(RegExContainer &reg_container) {
got += part + "|||";
}
if (got != expected) {
- ERR_PRINT("Failed to get proper data from parse_arguments `" + line + "` should return `" + expected + "`(" + itos(expected.size()) + "), got instead `" + got + "`(" + itos(got.size()) + ")");
+ ERR_PRINT(vformat("Failed to get proper data from parse_arguments. \"%s\" should return \"%s\"(%d), got \"%s\"(%d), instead.", line, expected, expected.size(), got, got.size()));
}
- valid = valid & (got == expected);
+ valid = valid && (got == expected);
}
{
String line = "(a , \"(,),,,,\" , c)";
@@ -2585,35 +2579,35 @@ bool ProjectConverter3To4::test_conversion(RegExContainer &reg_container) {
got += part + "|||";
}
if (got != expected) {
- ERR_PRINT("Failed to get proper data from parse_arguments `" + line + "` should return `" + expected + "`(" + itos(expected.size()) + "), got instead `" + got + "`(" + itos(got.size()) + ")");
+ ERR_PRINT(vformat("Failed to get proper data from parse_arguments. \"%s\" should return \"%s\"(%d), got \"%s\"(%d), instead.", line, expected, expected.size(), got, got.size()));
}
- valid = valid & (got == expected);
+ valid = valid && (got == expected);
}
return valid;
}
-// Validate in all arrays if names don't do cyclic renames `Node` -> `Node2D` | `Node2D` -> `2DNode`
+// Validate in all arrays if names don't do cyclic renames "Node" -> "Node2D" | "Node2D" -> "2DNode"
bool ProjectConverter3To4::test_array_names() {
bool valid = true;
Vector<String> names = Vector<String>();
- // Validate if all classes are valid
+ // Validate if all classes are valid.
{
for (unsigned int current_index = 0; class_renames[current_index][0]; current_index++) {
const String old_class = class_renames[current_index][0];
const String new_class = class_renames[current_index][1];
- // Light2D, Texture, Viewport are special classes(probably virtual ones)
+ // Light2D, Texture, Viewport are special classes(probably virtual ones).
if (ClassDB::class_exists(StringName(old_class)) && old_class != "Light2D" && old_class != "Texture" && old_class != "Viewport") {
- ERR_PRINT(String("Class `") + old_class + "` exists in Godot 4.0, so cannot be renamed to something else.");
- valid = false; // This probably should be only a warning, but not 100% sure - this would need to be added to CI
+ ERR_PRINT(vformat("Class \"%s\" exists in Godot 4.0, so it cannot be renamed to something else.", old_class));
+ valid = false; // This probably should be only a warning, but not 100% sure - this would need to be added to CI.
}
- // Callable is special class, to which normal classes may be renamed
+ // Callable is special class, to which normal classes may be renamed.
if (!ClassDB::class_exists(StringName(new_class)) && new_class != "Callable") {
- ERR_PRINT(String("Class `") + new_class + "` doesn't exists in Godot 4.0, so cannot be used in conversion.");
- valid = false; // This probably should be only a warning, but not 100% sure - this would need to be added to CI
+ ERR_PRINT(vformat("Class \"%s\" does not exist in Godot 4.0, so it cannot be used in the conversion.", old_class));
+ valid = false; // This probably should be only a warning, but not 100% sure - this would need to be added to CI.
}
}
}
@@ -2621,8 +2615,8 @@ bool ProjectConverter3To4::test_array_names() {
{
HashSet<String> all_functions;
- // List of excluded functions from builtin types and global namespace, because currently it is not possible to get list of functions from them
- // This will be available when https://github.com/godotengine/godot/pull/49053 or similar will be included into Godot
+ // List of excluded functions from builtin types and global namespace, because currently it is not possible to get list of functions from them.
+ // This will be available when https://github.com/godotengine/godot/pull/49053 or similar will be included into Godot.
static const char *builtin_types_excluded_functions[] = { "dict_to_inst", "inst_to_dict", "bytes_to_var", "bytes_to_var_with_objects", "db_to_linear", "deg_to_rad", "linear_to_db", "rad_to_deg", "randf_range", "snapped", "str_to_var", "var_to_str", "var_to_bytes", "var_to_bytes_with_objects", "move_toward", "uri_encode", "uri_decode", "remove_at", "get_rotation_quaternion", "clamp", "grow_side", "is_absolute_path", "is_valid_int", "lerp", "to_ascii_buffer", "to_utf8_buffer", "to_utf32_buffer", "snapped", "remap", nullptr };
for (int current_index = 0; builtin_types_excluded_functions[current_index]; current_index++) {
all_functions.insert(builtin_types_excluded_functions[current_index]);
@@ -2652,82 +2646,79 @@ bool ProjectConverter3To4::test_array_names() {
int current_element = 0;
while (gdscript_function_renames[current_element][0] != nullptr) {
+ String name_3_x = gdscript_function_renames[current_element][0];
+ String name_4_0 = gdscript_function_renames[current_element][1];
if (!all_functions.has(gdscript_function_renames[current_element][1])) {
- ERR_PRINT(String("Missing gdscript function in pair (") + gdscript_function_renames[current_element][0] + " - ===> " + gdscript_function_renames[current_element][1] + " <===)");
+ ERR_PRINT(vformat("Missing GDScript function in pair (%s - ===> %s <===)", name_3_x, name_4_0));
valid = false;
}
current_element++;
}
}
if (!valid) {
- ERR_PRINT("Found function which is used in converter, but cannot be found in Godot 4. Rename this element to new name or remove entire rule about it if is obsolete.");
+ ERR_PRINT("Found function which is used in the converter, but it cannot be found in Godot 4. Rename this element or remove its entry if it's obsolete.");
}
- valid = valid & test_single_array(enum_renames);
- valid = valid & test_single_array(class_renames, true);
- valid = valid & test_single_array(gdscript_function_renames, true);
- valid = valid & test_single_array(csharp_function_renames, true);
- valid = valid & test_single_array(gdscript_properties_renames, true);
- valid = valid & test_single_array(csharp_properties_renames);
- valid = valid & test_single_array(shaders_renames, true);
- valid = valid & test_single_array(gdscript_signals_renames);
- valid = valid & test_single_array(project_settings_renames);
- valid = valid & test_single_array(builtin_types_renames);
- valid = valid & test_single_array(color_renames);
+ valid = valid && test_single_array(enum_renames);
+ valid = valid && test_single_array(class_renames, true);
+ valid = valid && test_single_array(gdscript_function_renames, true);
+ valid = valid && test_single_array(csharp_function_renames, true);
+ valid = valid && test_single_array(gdscript_properties_renames, true);
+ valid = valid && test_single_array(csharp_properties_renames);
+ valid = valid && test_single_array(shaders_renames, true);
+ valid = valid && test_single_array(gdscript_signals_renames);
+ valid = valid && test_single_array(project_settings_renames);
+ valid = valid && test_single_array(builtin_types_renames);
+ valid = valid && test_single_array(color_renames);
return valid;
}
-// Validate in one array if names don't do cyclic renames `Node` -> `Node2D` | `Node2D` -> `2DNode`
-// Also checks if in name contains spaces at the end or beginning
-bool ProjectConverter3To4::test_single_array(const char *array[][2], bool ignore_second_check) {
+// Validates the array to prevent cyclic renames, such as `Node` -> `Node2D`, then `Node2D` -> `2DNode`.
+// Also checks if names contain leading or trailing spaces.
+bool ProjectConverter3To4::test_single_array(const char *p_array[][2], bool p_ignore_4_0_name) {
bool valid = true;
Vector<String> names = Vector<String>();
- for (unsigned int current_index = 0; array[current_index][0]; current_index++) {
- if (String(array[current_index][0]).begins_with(" ") || String(array[current_index][0]).ends_with(" ")) {
- {
- ERR_PRINT(String("Entry \"") + array[current_index][0] + "\" ends or stars with space.");
- valid = false;
- }
+ for (unsigned int current_index = 0; p_array[current_index][0]; current_index++) {
+ String name_3_x = p_array[current_index][0];
+ String name_4_0 = p_array[current_index][1];
+ if (name_3_x != name_3_x.strip_edges()) {
+ ERR_PRINT(vformat("Invalid Entry \"%s\" contains leading or trailing spaces.", name_3_x));
+ valid = false;
}
- if (names.has(array[current_index][0])) {
- ERR_PRINT(String("Found duplicated things, pair ( -> ") + array[current_index][0] + " , " + array[current_index][1] + ")");
+ if (names.has(name_3_x)) {
+ ERR_PRINT(vformat("Found duplicated entry, pair ( -> %s , %s)", name_3_x, name_4_0));
valid = false;
}
- names.append(array[current_index][0]);
+ names.append(name_3_x);
- if (String(array[current_index][1]).begins_with(" ") || String(array[current_index][1]).ends_with(" ")) {
- {
- ERR_PRINT(String("Entry \"") + array[current_index][1] + "\" ends or stars with space.");
- valid = false;
- }
+ if (name_4_0 != name_4_0.strip_edges()) {
+ ERR_PRINT(vformat("Invalid Entry \"%s\" contains leading or trailing spaces.", name_3_x));
+ valid = false;
}
- if (names.has(array[current_index][1])) {
- ERR_PRINT(String("Found duplicated things, pair (") + array[current_index][0] + " , ->" + array[current_index][1] + ")");
+ if (names.has(name_4_0)) {
+ ERR_PRINT(vformat("Found duplicated entry, pair ( -> %s , %s)", name_3_x, name_4_0));
valid = false;
}
- if (!ignore_second_check) {
- names.append(array[current_index][1]);
+ if (!p_ignore_4_0_name) {
+ names.append(name_4_0);
}
}
return valid;
};
-// Returns arguments from given function execution, this cannot be really done as regex
+// Returns arguments from given function execution, this cannot be really done as regex.
// `abc(d,e(f,g),h)` -> [d], [e(f,g)], [h]
Vector<String> ProjectConverter3To4::parse_arguments(const String &line) {
Vector<String> parts;
int string_size = line.length();
- int start_part = 0; // Index of beginning of start par
+ int start_part = 0; // Index of beginning of start part.
int parts_counter = 0;
char32_t previous_character = '\0';
- bool is_inside_string = false; // if true, it ignore this 3 characters ( , ) inside string
+ bool is_inside_string = false; // If true, it ignores these 3 characters ( , ) inside string.
- if (line.count("(") != line.count(")")) {
- ERR_PRINT("Converter internal bug: substring should have equal number of open and close parenthess in line - `" + line + "`");
- return parts;
- }
+ ERR_FAIL_COND_V_MSG(line.count("(") != line.count(")"), parts, vformat("Converter internal bug: substring should have equal number of open and close parentheses in line - \"%s\".", line));
for (int current_index = 0; current_index < string_size; current_index++) {
char32_t character = line.get(current_index);
@@ -2788,9 +2779,9 @@ Vector<String> ProjectConverter3To4::parse_arguments(const String &line) {
return clean_parts;
}
-// Finds latest parenthess owned by function
+// Finds latest parenthesis owned by function.
// `function(abc(a,b),DD)):` finds this parenthess `function(abc(a,b),DD => ) <= ):`
-int ProjectConverter3To4::get_end_parenthess(const String &line) const {
+int ProjectConverter3To4::get_end_parenthesis(const String &line) const {
int current_state = 0;
for (int current_index = 0; line.length() > current_index; current_index++) {
char32_t character = line.get(current_index);
@@ -2807,8 +2798,8 @@ int ProjectConverter3To4::get_end_parenthess(const String &line) const {
return -1;
}
-// Connects arguments from vector to one string
-// Needed when after processing e.g. 2 arguments, later arguments are not changed in any way
+// Merges multiple arguments into a single String.
+// Needed when after processing e.g. 2 arguments, later arguments are not changed in any way.
String ProjectConverter3To4::connect_arguments(const Vector<String> &arguments, int from, int to) const {
if (to == -1) {
to = arguments.size();
@@ -2828,7 +2819,7 @@ String ProjectConverter3To4::connect_arguments(const Vector<String> &arguments,
return value;
}
-// Return spaces or tabs which starts line e.g. `\t\tmove_this` will return `\t\t`
+// Returns the indentation (spaces and tabs) at the start of the line e.g. `\t\tmove_this` returns `\t\t`.
String ProjectConverter3To4::get_starting_space(const String &line) const {
String empty_space;
int current_character = 0;
@@ -2860,9 +2851,8 @@ String ProjectConverter3To4::get_starting_space(const String &line) const {
return empty_space;
}
-// Return object which execute specific function
-// e.g. in `var roman = kieliszek.funkcja()` to this function is passed everything before function which we want to check
-// so it is `var roman = kieliszek.` and this function return `kieliszek.`
+// Returns the object that’s executing the function in the line.
+// e.g. Passing the line "var roman = kieliszek.funkcja()" to this function returns "kieliszek".
String ProjectConverter3To4::get_object_of_execution(const String &line) const {
int end = line.size() - 1; // Last one is \0
int variable_start = end - 1;
@@ -2880,10 +2870,10 @@ String ProjectConverter3To4::get_object_of_execution(const String &line) const {
if (start == 0) {
break;
} else if (is_nodepath_sep) {
- // Freeze variable_start, try to fetch more chars since this might be node path literal
+ // Freeze variable_start, try to fetch more chars since this might be a Node path literal.
is_possibly_nodepath = true;
} else if (is_nodepath_start) {
- // Found $, this is a node path literal
+ // Found $, this is a Node path literal.
is_valid_nodepath = true;
break;
}
@@ -2893,8 +2883,8 @@ String ProjectConverter3To4::get_object_of_execution(const String &line) const {
start--;
continue;
} else {
- // Abandon all hope, this is neither a variable nor a node path literal
- variable_start++; // Found invalid character, needs to be ignored
+ // Abandon all hope, this is neither a variable nor a Node path literal.
+ variable_start++; // Found invalid character, needs to be ignored.
break;
}
}
@@ -2943,7 +2933,7 @@ void ProjectConverter3To4::rename_classes(Vector<String> &lines, const RegExCont
for (unsigned int current_index = 0; class_renames[current_index][0]; current_index++) {
if (line.contains(class_renames[current_index][0])) {
bool found_ignored_items = false;
- // Renaming Spatial.tscn to TEMP_RENAMED_CLASS.tscn
+ // Renaming Spatial.tscn to TEMP_RENAMED_CLASS.tscn.
if (line.contains(String(class_renames[current_index][0]) + ".")) {
found_ignored_items = true;
line = reg_container.class_tscn_regexes[current_index]->sub(line, "TEMP_RENAMED_CLASS.tscn", true);
@@ -2951,10 +2941,10 @@ void ProjectConverter3To4::rename_classes(Vector<String> &lines, const RegExCont
line = reg_container.class_shader_regexes[current_index]->sub(line, "TEMP_RENAMED_CLASS.shader", true);
}
- // Causal renaming Spatial -> Node3D
+ // Causal renaming Spatial -> Node3D.
line = reg_container.class_regexes[current_index]->sub(line, class_renames[current_index][1], true);
- // Restore Spatial.tscn from TEMP_RENAMED_CLASS.tscn
+ // Restore Spatial.tscn from TEMP_RENAMED_CLASS.tscn.
if (found_ignored_items) {
line = reg_container.class_temp_tscn.sub(line, reg_container.class_temp_tscn_renames[current_index], true);
line = reg_container.class_temp_gd.sub(line, reg_container.class_temp_gd_renames[current_index], true);
@@ -2977,7 +2967,7 @@ Vector<String> ProjectConverter3To4::check_for_rename_classes(Vector<String> &li
if (line.contains(class_renames[current_index][0])) {
String old_line = line;
bool found_ignored_items = false;
- // Renaming Spatial.tscn to TEMP_RENAMED_CLASS.tscn
+ // Renaming Spatial.tscn to TEMP_RENAMED_CLASS.tscn.
if (line.contains(String(class_renames[current_index][0]) + ".")) {
found_ignored_items = true;
line = reg_container.class_tscn_regexes[current_index]->sub(line, "TEMP_RENAMED_CLASS.tscn", true);
@@ -2985,13 +2975,13 @@ Vector<String> ProjectConverter3To4::check_for_rename_classes(Vector<String> &li
line = reg_container.class_shader_regexes[current_index]->sub(line, "TEMP_RENAMED_CLASS.shader", true);
}
- // Causal renaming Spatial -> Node3D
+ // Causal renaming Spatial -> Node3D.
TypedArray<RegExMatch> reg_match = reg_container.class_regexes[current_index]->search_all(line);
if (reg_match.size() > 0) {
found_renames.append(line_formatter(current_line, class_renames[current_index][0], class_renames[current_index][1], old_line));
}
- // Restore Spatial.tscn from TEMP_RENAMED_CLASS.tscn
+ // Restore Spatial.tscn from TEMP_RENAMED_CLASS.tscn.
if (found_ignored_items) {
line = reg_container.class_temp_tscn.sub(line, reg_container.class_temp_tscn_renames[current_index], true);
line = reg_container.class_temp_gd.sub(line, reg_container.class_temp_gd_renames[current_index], true);
@@ -3031,13 +3021,14 @@ Vector<String> ProjectConverter3To4::check_for_rename_gdscript_functions(Vector<
return found_renames;
}
-// TODO, this function should run only on all .gd files and also on lines in tscn files which
+// TODO, this function should run only on all ".gd" files and also on lines in ".tscn" files which are parts of built-in Scripts.
void ProjectConverter3To4::process_gdscript_line(String &line, const RegExContainer &reg_container, bool builtin) {
- // In this and other functions, reg.sub are used only after checking line with str.contains function which is sometimes few times faster with bigger line lengths
+ // In this and other functions, reg.sub() is used only after checking lines with str.contains().
+ // With longer lines, doing so can sometimes be significantly faster.
if ((line.contains(".lock") || line.contains(".unlock")) && !line.contains("mtx") && !line.contains("mutex") && !line.contains("Mutex")) {
- line = reg_container.reg_image_lock.sub(line, "false # $1.lock() # TODOConverter40, image no longer require locking, `false` helps to not broke one line if/else, so can be freely removed", true);
- line = reg_container.reg_image_unlock.sub(line, "false # $1.unlock() # TODOConverter40, image no longer require locking, `false` helps to not broke one line if/else, so can be freely removed", true);
+ line = reg_container.reg_image_lock.sub(line, "false # $1.lock() # TODOConverter40, Image no longer requires locking, `false` helps to not break one line if/else, so it can freely be removed", true);
+ line = reg_container.reg_image_unlock.sub(line, "false # $1.unlock() # TODOConverter40, Image no longer requires locking, `false` helps to not break one line if/else, so it can freely be removed", true);
}
// PackedStringArray(req_godot).join('.') -> '.'.join(PackedStringArray(req_godot)) PoolStringArray
@@ -3116,7 +3107,7 @@ void ProjectConverter3To4::process_gdscript_line(String &line, const RegExContai
// -- r.move_and_slide( a, b, c, d, e ) -> r.set_velocity(a) ... r.move_and_slide() KinematicBody
if (line.contains(("move_and_slide("))) {
int start = line.find("move_and_slide(");
- int end = get_end_parenthess(line.substr(start)) + 1;
+ int end = get_end_parenthesis(line.substr(start)) + 1;
if (end > -1) {
String base_obj = get_object_of_execution(line.substr(0, start));
String starting_space = get_starting_space(line);
@@ -3162,7 +3153,7 @@ void ProjectConverter3To4::process_gdscript_line(String &line, const RegExContai
// -- r.move_and_slide_with_snap( a, b, c, d, e ) -> r.set_velocity(a) ... r.move_and_slide() KinematicBody
if (line.contains("move_and_slide_with_snap(")) {
int start = line.find("move_and_slide_with_snap(");
- int end = get_end_parenthess(line.substr(start)) + 1;
+ int end = get_end_parenthesis(line.substr(start)) + 1;
if (end > -1) {
String base_obj = get_object_of_execution(line.substr(0, start));
String starting_space = get_starting_space(line);
@@ -3213,7 +3204,7 @@ void ProjectConverter3To4::process_gdscript_line(String &line, const RegExContai
// -- sort_custom( a , b ) -> sort_custom(Callable( a , b )) Object
if (line.contains("sort_custom(")) {
int start = line.find("sort_custom(");
- int end = get_end_parenthess(line.substr(start)) + 1;
+ int end = get_end_parenthesis(line.substr(start)) + 1;
if (end > -1) {
Vector<String> parts = parse_arguments(line.substr(start, end));
if (parts.size() == 2) {
@@ -3225,7 +3216,7 @@ void ProjectConverter3To4::process_gdscript_line(String &line, const RegExContai
// -- list_dir_begin( ) -> list_dir_begin() Object
if (line.contains("list_dir_begin(")) {
int start = line.find("list_dir_begin(");
- int end = get_end_parenthess(line.substr(start)) + 1;
+ int end = get_end_parenthesis(line.substr(start)) + 1;
if (end > -1) {
line = line.substr(0, start) + "list_dir_begin() " + line.substr(end + start) + "# TODOGODOT4 fill missing arguments https://github.com/godotengine/godot/pull/40547";
}
@@ -3234,7 +3225,7 @@ void ProjectConverter3To4::process_gdscript_line(String &line, const RegExContai
// -- draw_line(1,2,3,4,5) -> draw_line(1,2,3,4) CanvasItem
if (line.contains("draw_line(")) {
int start = line.find("draw_line(");
- int end = get_end_parenthess(line.substr(start)) + 1;
+ int end = get_end_parenthesis(line.substr(start)) + 1;
if (end > -1) {
Vector<String> parts = parse_arguments(line.substr(start, end));
if (parts.size() == 5) {
@@ -3247,7 +3238,7 @@ void ProjectConverter3To4::process_gdscript_line(String &line, const RegExContai
if (line.contains("func ") && line.contains("var ")) {
int start = line.find("func ");
start = line.substr(start).find("(") + start;
- int end = get_end_parenthess(line.substr(start)) + 1;
+ int end = get_end_parenthesis(line.substr(start)) + 1;
if (end > -1) {
Vector<String> parts = parse_arguments(line.substr(start, end));
@@ -3265,7 +3256,7 @@ void ProjectConverter3To4::process_gdscript_line(String &line, const RegExContai
// -- yield(this, \"timeout\") -> await this.timeout GDScript
if (line.contains("yield(")) {
int start = line.find("yield(");
- int end = get_end_parenthess(line.substr(start)) + 1;
+ int end = get_end_parenthesis(line.substr(start)) + 1;
if (end > -1) {
Vector<String> parts = parse_arguments(line.substr(start, end));
if (parts.size() == 2) {
@@ -3281,7 +3272,7 @@ void ProjectConverter3To4::process_gdscript_line(String &line, const RegExContai
// -- parse_json( AA ) -> TODO Object
if (line.contains("parse_json(")) {
int start = line.find("parse_json(");
- int end = get_end_parenthess(line.substr(start)) + 1;
+ int end = get_end_parenthesis(line.substr(start)) + 1;
if (end > -1) {
Vector<String> parts = parse_arguments(line.substr(start, end));
line = line.substr(0, start) + "JSON.new().stringify(" + connect_arguments(parts, 0) + ")" + line.substr(end + start);
@@ -3291,7 +3282,7 @@ void ProjectConverter3To4::process_gdscript_line(String &line, const RegExContai
// -- .xform(Vector3(a,b,c)) -> * Vector3(a,b,c) Transform
if (line.contains(".xform(")) {
int start = line.find(".xform(");
- int end = get_end_parenthess(line.substr(start)) + 1;
+ int end = get_end_parenthesis(line.substr(start)) + 1;
if (end > -1) {
Vector<String> parts = parse_arguments(line.substr(start, end));
if (parts.size() == 1) {
@@ -3303,7 +3294,7 @@ void ProjectConverter3To4::process_gdscript_line(String &line, const RegExContai
// -- .xform_inv(Vector3(a,b,c)) -> * Vector3(a,b,c) Transform
if (line.contains(".xform_inv(")) {
int start = line.find(".xform_inv(");
- int end = get_end_parenthess(line.substr(start)) + 1;
+ int end = get_end_parenthesis(line.substr(start)) + 1;
if (end > -1) {
String object_exec = get_object_of_execution(line.substr(0, start));
if (line.contains(object_exec + ".xform")) {
@@ -3321,7 +3312,7 @@ void ProjectConverter3To4::process_gdscript_line(String &line, const RegExContai
int start = line.find("connect(");
// Protection from disconnect
if (start == 0 || line.get(start - 1) != 's') {
- int end = get_end_parenthess(line.substr(start)) + 1;
+ int end = get_end_parenthesis(line.substr(start)) + 1;
if (end > -1) {
Vector<String> parts = parse_arguments(line.substr(start, end));
if (parts.size() == 3) {
@@ -3335,7 +3326,7 @@ void ProjectConverter3To4::process_gdscript_line(String &line, const RegExContai
// -- disconnect(a,b,c) -> disconnect(a,Callable(b,c)) Object
if (line.contains("disconnect(")) {
int start = line.find("disconnect(");
- int end = get_end_parenthess(line.substr(start)) + 1;
+ int end = get_end_parenthesis(line.substr(start)) + 1;
if (end > -1) {
Vector<String> parts = parse_arguments(line.substr(start, end));
if (parts.size() == 3) {
@@ -3346,7 +3337,7 @@ void ProjectConverter3To4::process_gdscript_line(String &line, const RegExContai
// -- is_connected(a,b,c) -> is_connected(a,Callable(b,c)) Object
if (line.contains("is_connected(")) {
int start = line.find("is_connected(");
- int end = get_end_parenthess(line.substr(start)) + 1;
+ int end = get_end_parenthesis(line.substr(start)) + 1;
if (end > -1) {
Vector<String> parts = parse_arguments(line.substr(start, end));
if (parts.size() == 3) {
@@ -3358,7 +3349,7 @@ void ProjectConverter3To4::process_gdscript_line(String &line, const RegExContai
// -- "(tween_method(A,B,C,D,E,[F,G]) != OK):", "(tween_method(Callable(A,B).bind(F,G),C,D,E) Object
if (line.contains("tween_method(")) {
int start = line.find("tween_method(");
- int end = get_end_parenthess(line.substr(start)) + 1;
+ int end = get_end_parenthesis(line.substr(start)) + 1;
if (end > -1) {
Vector<String> parts = parse_arguments(line.substr(start, end));
if (parts.size() == 5) {
@@ -3371,7 +3362,7 @@ void ProjectConverter3To4::process_gdscript_line(String &line, const RegExContai
// -- "(tween_callback(A,B,[C,D]) != OK):", "(connect(Callable(A,B).bind(C,D)) Object
if (line.contains("tween_callback(")) {
int start = line.find("tween_callback(");
- int end = get_end_parenthess(line.substr(start)) + 1;
+ int end = get_end_parenthesis(line.substr(start)) + 1;
if (end > -1) {
Vector<String> parts = parse_arguments(line.substr(start, end));
if (parts.size() == 2) {
@@ -3385,7 +3376,7 @@ void ProjectConverter3To4::process_gdscript_line(String &line, const RegExContai
// -- start(a,b,c,d) -> start(Callable(a,b).bind(c),d) Thread
if (line.contains("start(")) {
int start = line.find("start(");
- int end = get_end_parenthess(line.substr(start)) + 1;
+ int end = get_end_parenthesis(line.substr(start)) + 1;
// Protection from 'func start'
if (!line.begins_with("func ")) {
if (end > -1) {
@@ -3412,7 +3403,7 @@ void ProjectConverter3To4::process_gdscript_line(String &line, const RegExContai
// assert(speed < 20, str(randi()%10)) -> assert(speed < 20) #,str(randi()%10)) GDScript - GDScript bug constant message
if (line.contains("assert(")) {
int start = line.find("assert(");
- int end = get_end_parenthess(line.substr(start)) + 1;
+ int end = get_end_parenthesis(line.substr(start)) + 1;
if (end > -1) {
Vector<String> parts = parse_arguments(line.substr(start, end));
if (parts.size() == 2) {
@@ -3423,7 +3414,7 @@ void ProjectConverter3To4::process_gdscript_line(String &line, const RegExContai
// create_from_image(aa, bb) -> create_from_image(aa) #, bb ImageTexture
if (line.contains("create_from_image(")) {
int start = line.find("create_from_image(");
- int end = get_end_parenthess(line.substr(start)) + 1;
+ int end = get_end_parenthesis(line.substr(start)) + 1;
if (end > -1) {
Vector<String> parts = parse_arguments(line.substr(start, end));
if (parts.size() == 2) {
@@ -3434,7 +3425,7 @@ void ProjectConverter3To4::process_gdscript_line(String &line, const RegExContai
// set_cell_item(a, b, c, d ,e) -> set_cell_item(Vector3(a, b, c), d ,e)
if (line.contains("set_cell_item(")) {
int start = line.find("set_cell_item(");
- int end = get_end_parenthess(line.substr(start)) + 1;
+ int end = get_end_parenthesis(line.substr(start)) + 1;
if (end > -1) {
Vector<String> parts = parse_arguments(line.substr(start, end));
if (parts.size() > 2) {
@@ -3445,7 +3436,7 @@ void ProjectConverter3To4::process_gdscript_line(String &line, const RegExContai
// get_cell_item(a, b, c) -> get_cell_item(Vector3i(a, b, c))
if (line.contains("get_cell_item(")) {
int start = line.find("get_cell_item(");
- int end = get_end_parenthess(line.substr(start)) + 1;
+ int end = get_end_parenthesis(line.substr(start)) + 1;
if (end > -1) {
Vector<String> parts = parse_arguments(line.substr(start, end));
if (parts.size() == 3) {
@@ -3456,7 +3447,7 @@ void ProjectConverter3To4::process_gdscript_line(String &line, const RegExContai
// get_cell_item_orientation(a, b, c) -> get_cell_item_orientation(Vector3i(a, b, c))
if (line.contains("get_cell_item_orientation(")) {
int start = line.find("get_cell_item_orientation(");
- int end = get_end_parenthess(line.substr(start)) + 1;
+ int end = get_end_parenthesis(line.substr(start)) + 1;
if (end > -1) {
Vector<String> parts = parse_arguments(line.substr(start, end));
if (parts.size() == 3) {
@@ -3467,7 +3458,7 @@ void ProjectConverter3To4::process_gdscript_line(String &line, const RegExContai
// apply_impulse(A, B) -> apply_impulse(B, A)
if (line.contains("apply_impulse(")) {
int start = line.find("apply_impulse(");
- int end = get_end_parenthess(line.substr(start)) + 1;
+ int end = get_end_parenthesis(line.substr(start)) + 1;
if (end > -1) {
Vector<String> parts = parse_arguments(line.substr(start, end));
if (parts.size() == 2) {
@@ -3478,7 +3469,7 @@ void ProjectConverter3To4::process_gdscript_line(String &line, const RegExContai
// apply_force(A, B) -> apply_force(B, A)
if (line.contains("apply_force(")) {
int start = line.find("apply_force(");
- int end = get_end_parenthess(line.substr(start)) + 1;
+ int end = get_end_parenthesis(line.substr(start)) + 1;
if (end > -1) {
Vector<String> parts = parse_arguments(line.substr(start, end));
if (parts.size() == 2) {
@@ -3489,7 +3480,7 @@ void ProjectConverter3To4::process_gdscript_line(String &line, const RegExContai
// map_to_world(a, b, c) -> map_to_local(Vector3i(a, b, c))
if (line.contains("map_to_world(")) {
int start = line.find("map_to_world(");
- int end = get_end_parenthess(line.substr(start)) + 1;
+ int end = get_end_parenthesis(line.substr(start)) + 1;
if (end > -1) {
Vector<String> parts = parse_arguments(line.substr(start, end));
if (parts.size() == 3) {
@@ -3502,7 +3493,7 @@ void ProjectConverter3To4::process_gdscript_line(String &line, const RegExContai
// OS.get_window_safe_area() -> DisplayServer.get_display_safe_area()
if (line.contains("OS.get_window_safe_area(")) {
int start = line.find("OS.get_window_safe_area(");
- int end = get_end_parenthess(line.substr(start)) + 1;
+ int end = get_end_parenthesis(line.substr(start)) + 1;
if (end > -1) {
Vector<String> parts = parse_arguments(line.substr(start, end));
if (parts.size() == 0) {
@@ -3513,7 +3504,7 @@ void ProjectConverter3To4::process_gdscript_line(String &line, const RegExContai
// draw_rect(a,b,c,d,e) -> draw_rect(a,b,c,d)#e) TODOGODOT4 Antialiasing argument is missing
if (line.contains("draw_rect(")) {
int start = line.find("draw_rect(");
- int end = get_end_parenthess(line.substr(start)) + 1;
+ int end = get_end_parenthesis(line.substr(start)) + 1;
if (end > -1) {
Vector<String> parts = parse_arguments(line.substr(start, end));
if (parts.size() == 5) {
@@ -3566,7 +3557,7 @@ void ProjectConverter3To4::process_csharp_line(String &line, const RegExContaine
int start = line.find("Connect(");
// Protection from disconnect
if (start == 0 || line.get(start - 1) != 's') {
- int end = get_end_parenthess(line.substr(start)) + 1;
+ int end = get_end_parenthesis(line.substr(start)) + 1;
if (end > -1) {
Vector<String> parts = parse_arguments(line.substr(start, end));
if (parts.size() >= 3) {
@@ -3578,7 +3569,7 @@ void ProjectConverter3To4::process_csharp_line(String &line, const RegExContaine
// -- Disconnect(a,b,c) -> Disconnect(a,Callable(b,c)) Object
if (line.contains("Disconnect(")) {
int start = line.find("Disconnect(");
- int end = get_end_parenthess(line.substr(start)) + 1;
+ int end = get_end_parenthesis(line.substr(start)) + 1;
if (end > -1) {
Vector<String> parts = parse_arguments(line.substr(start, end));
if (parts.size() == 3) {
@@ -3589,7 +3580,7 @@ void ProjectConverter3To4::process_csharp_line(String &line, const RegExContaine
// -- IsConnected(a,b,c) -> IsConnected(a,Callable(b,c)) Object
if (line.contains("IsConnected(")) {
int start = line.find("IsConnected(");
- int end = get_end_parenthess(line.substr(start)) + 1;
+ int end = get_end_parenthesis(line.substr(start)) + 1;
if (end > -1) {
Vector<String> parts = parse_arguments(line.substr(start, end));
if (parts.size() == 3) {
@@ -3866,7 +3857,7 @@ Vector<String> ProjectConverter3To4::check_for_custom_rename(Vector<String> &lin
if (uint64_t(line.length()) <= maximum_line_length) {
TypedArray<RegExMatch> reg_match = reg.search_all(line);
if (reg_match.size() > 0) {
- found_renames.append(line_formatter(current_line, from.replace("\\.", "."), to, line)); // Without replacing it will print "\.shader" instead ".shader"
+ found_renames.append(line_formatter(current_line, from.replace("\\.", "."), to, line)); // Without replacing it will print "\.shader" instead ".shader".
}
}
current_line++;
@@ -3920,19 +3911,28 @@ String ProjectConverter3To4::line_formatter(int current_line, String from, Strin
if (line.size() > 400) {
line = line.substr(0, 397) + "...";
}
- return String("Line (") + itos(current_line) + ") " + from.replace("\r", "").replace("\n", "") + " -> " + to.replace("\r", "").replace("\n", "") + " - LINE \"\"\" " + line.replace("\r", "").replace("\n", "").strip_edges() + " \"\"\"";
+
+ from = from.strip_escapes();
+ to = to.strip_escapes();
+ line = line.replace("\r", "").replace("\n", "").strip_edges();
+
+ return vformat("Line(%d), %s -> %s - LINE \"\"\" %s \"\"\"", current_line, from, to, line);
}
// Prints only full lines e.g.:
// Line (1) - FULL LINES - """yield(get_tree().create_timer(3), 'timeout')""" =====> """ await get_tree().create_timer(3).timeout """
-String ProjectConverter3To4::simple_line_formatter(int current_line, String old_line, String line) {
+String ProjectConverter3To4::simple_line_formatter(int current_line, String old_line, String new_line) {
if (old_line.size() > 1000) {
old_line = old_line.substr(0, 997) + "...";
}
- if (line.size() > 1000) {
- line = line.substr(0, 997) + "...";
+ if (new_line.size() > 1000) {
+ new_line = new_line.substr(0, 997) + "...";
}
- return String("Line (") + itos(current_line) + ") - FULL LINES - \"\"\"" + old_line.replace("\r", "").replace("\n", "").strip_edges() + "\"\"\" =====> \"\"\" " + line.replace("\r", "").replace("\n", "").strip_edges() + " \"\"\"";
+
+ old_line = old_line.replace("\r", "").replace("\n", "").strip_edges();
+ new_line = new_line.replace("\r", "").replace("\n", "").strip_edges();
+
+ return vformat("Line (%d) - FULL LINES - \"\"\" %s \"\"\" =====> \"\"\" %s \"\"\"", current_line, old_line, new_line);
}
// Collects string from vector strings
@@ -3948,14 +3948,14 @@ String ProjectConverter3To4::collect_string_from_vector(Vector<String> &vector)
return string;
}
-#else // No regex.
+#else // No RegEx.
int ProjectConverter3To4::convert() {
- ERR_FAIL_V_MSG(ERROR_CODE, "Can't run converter for Godot 3.x projects as RegEx module is disabled.");
+ ERR_FAIL_V_MSG(ERROR_CODE, "Can't run converter for Godot 3.x projects, because RegEx module is disabled.");
}
int ProjectConverter3To4::validate_conversion() {
- ERR_FAIL_V_MSG(ERROR_CODE, "Can't validate conversion for Godot 3.x projects as RegEx module is disabled.");
+ ERR_FAIL_V_MSG(ERROR_CODE, "Can't validate conversion for Godot 3.x projects, because RegEx module is disabled.");
}
#endif // MODULE_REGEX_ENABLED
diff --git a/editor/project_converter_3_to_4.h b/editor/project_converter_3_to_4.h
index fc6d66c9a8..2cecb9da79 100644
--- a/editor/project_converter_3_to_4.h
+++ b/editor/project_converter_3_to_4.h
@@ -76,7 +76,7 @@ private:
Vector<String> check_for_files();
Vector<String> parse_arguments(const String &line);
- int get_end_parenthess(const String &line) const;
+ int get_end_parenthesis(const String &line) const;
String connect_arguments(const Vector<String> &line, int from, int to = -1) const;
String get_starting_space(const String &line) const;
String get_object_of_execution(const String &line) const;
diff --git a/editor/project_manager.cpp b/editor/project_manager.cpp
index 2b0d6f740a..544e8c9323 100644
--- a/editor/project_manager.cpp
+++ b/editor/project_manager.cpp
@@ -1993,7 +1993,7 @@ void ProjectManager::shortcut_input(const Ref<InputEvent> &p_ev) {
// This is handled by the platform implementation on macOS,
// so only define the shortcut on other platforms
#ifndef MACOS_ENABLED
- if (k->get_keycode_with_modifiers() == (KeyModifierMask::CMD | Key::Q)) {
+ if (k->get_keycode_with_modifiers() == (KeyModifierMask::META | Key::Q)) {
_dim_window();
get_tree()->quit();
}
@@ -2051,7 +2051,7 @@ void ProjectManager::shortcut_input(const Ref<InputEvent> &p_ev) {
} break;
case Key::F: {
- if (k->is_command_pressed()) {
+ if (k->is_command_or_control_pressed()) {
this->search_box->grab_focus();
} else {
keycode_handled = false;
@@ -2628,21 +2628,21 @@ ProjectManager::ProjectManager() {
create_btn = memnew(Button);
create_btn->set_text(TTR("New Project"));
create_btn->add_theme_constant_override("h_separation", btn_h_separation);
- create_btn->set_shortcut(ED_SHORTCUT("project_manager/new_project", TTR("New Project"), KeyModifierMask::CMD | Key::N));
+ create_btn->set_shortcut(ED_SHORTCUT("project_manager/new_project", TTR("New Project"), KeyModifierMask::CMD_OR_CTRL | Key::N));
create_btn->connect("pressed", callable_mp(this, &ProjectManager::_new_project));
tree_vb->add_child(create_btn);
import_btn = memnew(Button);
import_btn->set_text(TTR("Import"));
import_btn->add_theme_constant_override("h_separation", btn_h_separation);
- import_btn->set_shortcut(ED_SHORTCUT("project_manager/import_project", TTR("Import Project"), KeyModifierMask::CMD | Key::I));
+ import_btn->set_shortcut(ED_SHORTCUT("project_manager/import_project", TTR("Import Project"), KeyModifierMask::CMD_OR_CTRL | Key::I));
import_btn->connect("pressed", callable_mp(this, &ProjectManager::_import_project));
tree_vb->add_child(import_btn);
scan_btn = memnew(Button);
scan_btn->set_text(TTR("Scan"));
scan_btn->add_theme_constant_override("h_separation", btn_h_separation);
- scan_btn->set_shortcut(ED_SHORTCUT("project_manager/scan_projects", TTR("Scan Projects"), KeyModifierMask::CMD | Key::S));
+ scan_btn->set_shortcut(ED_SHORTCUT("project_manager/scan_projects", TTR("Scan Projects"), KeyModifierMask::CMD_OR_CTRL | Key::S));
scan_btn->connect("pressed", callable_mp(this, &ProjectManager::_scan_projects));
tree_vb->add_child(scan_btn);
@@ -2651,14 +2651,14 @@ ProjectManager::ProjectManager() {
open_btn = memnew(Button);
open_btn->set_text(TTR("Edit"));
open_btn->add_theme_constant_override("h_separation", btn_h_separation);
- open_btn->set_shortcut(ED_SHORTCUT("project_manager/edit_project", TTR("Edit Project"), KeyModifierMask::CMD | Key::E));
+ open_btn->set_shortcut(ED_SHORTCUT("project_manager/edit_project", TTR("Edit Project"), KeyModifierMask::CMD_OR_CTRL | Key::E));
open_btn->connect("pressed", callable_mp(this, &ProjectManager::_open_selected_projects_ask));
tree_vb->add_child(open_btn);
run_btn = memnew(Button);
run_btn->set_text(TTR("Run"));
run_btn->add_theme_constant_override("h_separation", btn_h_separation);
- run_btn->set_shortcut(ED_SHORTCUT("project_manager/run_project", TTR("Run Project"), KeyModifierMask::CMD | Key::R));
+ run_btn->set_shortcut(ED_SHORTCUT("project_manager/run_project", TTR("Run Project"), KeyModifierMask::CMD_OR_CTRL | Key::R));
run_btn->connect("pressed", callable_mp(this, &ProjectManager::_run_project));
tree_vb->add_child(run_btn);
diff --git a/editor/project_settings_editor.cpp b/editor/project_settings_editor.cpp
index 11cbc4132c..2da49f11cc 100644
--- a/editor/project_settings_editor.cpp
+++ b/editor/project_settings_editor.cpp
@@ -239,7 +239,7 @@ void ProjectSettingsEditor::shortcut_input(const Ref<InputEvent> &p_event) {
handled = true;
}
- if (k->get_keycode_with_modifiers() == (KeyModifierMask::CMD | Key::F)) {
+ if (k->is_match(InputEventKey::create_reference(KeyModifierMask::CMD_OR_CTRL | Key::F))) {
search_box->grab_focus();
search_box->select_all();
handled = true;
diff --git a/editor/scene_tree_dock.cpp b/editor/scene_tree_dock.cpp
index cde4490cd3..488a651c29 100644
--- a/editor/scene_tree_dock.cpp
+++ b/editor/scene_tree_dock.cpp
@@ -3402,24 +3402,24 @@ SceneTreeDock::SceneTreeDock(Node *p_scene_root, EditorSelection *p_editor_selec
ED_SHORTCUT("scene_tree/batch_rename", TTR("Batch Rename"), KeyModifierMask::SHIFT | Key::F2);
ED_SHORTCUT_OVERRIDE("scene_tree/batch_rename", "macos", KeyModifierMask::SHIFT | Key::ENTER);
- ED_SHORTCUT("scene_tree/add_child_node", TTR("Add Child Node"), KeyModifierMask::CMD | Key::A);
- ED_SHORTCUT("scene_tree/instance_scene", TTR("Instantiate Child Scene"), KeyModifierMask::CMD | KeyModifierMask::SHIFT | Key::A);
+ ED_SHORTCUT("scene_tree/add_child_node", TTR("Add Child Node"), KeyModifierMask::CMD_OR_CTRL | Key::A);
+ ED_SHORTCUT("scene_tree/instance_scene", TTR("Instantiate Child Scene"), KeyModifierMask::CMD_OR_CTRL | KeyModifierMask::SHIFT | Key::A);
ED_SHORTCUT("scene_tree/expand_collapse_all", TTR("Expand/Collapse Branch"));
- ED_SHORTCUT("scene_tree/cut_node", TTR("Cut"), KeyModifierMask::CMD | Key::X);
- ED_SHORTCUT("scene_tree/copy_node", TTR("Copy"), KeyModifierMask::CMD | Key::C);
- ED_SHORTCUT("scene_tree/paste_node", TTR("Paste"), KeyModifierMask::CMD | Key::V);
+ ED_SHORTCUT("scene_tree/cut_node", TTR("Cut"), KeyModifierMask::CMD_OR_CTRL | Key::X);
+ ED_SHORTCUT("scene_tree/copy_node", TTR("Copy"), KeyModifierMask::CMD_OR_CTRL | Key::C);
+ ED_SHORTCUT("scene_tree/paste_node", TTR("Paste"), KeyModifierMask::CMD_OR_CTRL | Key::V);
ED_SHORTCUT("scene_tree/change_node_type", TTR("Change Type"));
ED_SHORTCUT("scene_tree/attach_script", TTR("Attach Script"));
ED_SHORTCUT("scene_tree/extend_script", TTR("Extend Script"));
ED_SHORTCUT("scene_tree/detach_script", TTR("Detach Script"));
- ED_SHORTCUT("scene_tree/move_up", TTR("Move Up"), KeyModifierMask::CMD | Key::UP);
- ED_SHORTCUT("scene_tree/move_down", TTR("Move Down"), KeyModifierMask::CMD | Key::DOWN);
- ED_SHORTCUT("scene_tree/duplicate", TTR("Duplicate"), KeyModifierMask::CMD | Key::D);
+ ED_SHORTCUT("scene_tree/move_up", TTR("Move Up"), KeyModifierMask::CMD_OR_CTRL | Key::UP);
+ ED_SHORTCUT("scene_tree/move_down", TTR("Move Down"), KeyModifierMask::CMD_OR_CTRL | Key::DOWN);
+ ED_SHORTCUT("scene_tree/duplicate", TTR("Duplicate"), KeyModifierMask::CMD_OR_CTRL | Key::D);
ED_SHORTCUT("scene_tree/reparent", TTR("Reparent"));
ED_SHORTCUT("scene_tree/reparent_to_new_node", TTR("Reparent to New Node"));
ED_SHORTCUT("scene_tree/make_root", TTR("Make Scene Root"));
ED_SHORTCUT("scene_tree/save_branch_as_scene", TTR("Save Branch as Scene"));
- ED_SHORTCUT("scene_tree/copy_node_path", TTR("Copy Node Path"), KeyModifierMask::CMD | KeyModifierMask::SHIFT | Key::C);
+ ED_SHORTCUT("scene_tree/copy_node_path", TTR("Copy Node Path"), KeyModifierMask::CMD_OR_CTRL | KeyModifierMask::SHIFT | Key::C);
ED_SHORTCUT("scene_tree/delete_no_confirm", TTR("Delete (No Confirm)"), KeyModifierMask::SHIFT | Key::KEY_DELETE);
ED_SHORTCUT("scene_tree/delete", TTR("Delete"), Key::KEY_DELETE);
diff --git a/editor/script_create_dialog.cpp b/editor/script_create_dialog.cpp
index 16ab441324..f57dfe4827 100644
--- a/editor/script_create_dialog.cpp
+++ b/editor/script_create_dialog.cpp
@@ -202,7 +202,7 @@ bool ScriptCreateDialog::_validate_parent(const String &p_string) {
}
}
- return ClassDB::class_exists(p_string) || ScriptServer::is_global_class(p_string);
+ return EditorNode::get_editor_data().is_type_recognized(p_string);
}
bool ScriptCreateDialog::_validate_class(const String &p_string) {
@@ -372,7 +372,15 @@ void ScriptCreateDialog::_create_new() {
const ScriptLanguage::ScriptTemplate sinfo = _get_current_template();
- scr = ScriptServer::get_language(language_menu->get_selected())->make_template(sinfo.content, cname_param, parent_name->get_text());
+ String parent_class = parent_name->get_text();
+ if (!ClassDB::class_exists(parent_class) && !ScriptServer::is_global_class(parent_class)) {
+ // If base is a custom type, replace with script path instead.
+ const EditorData::CustomType *type = EditorNode::get_editor_data().get_custom_type_by_name(parent_class);
+ ERR_FAIL_NULL(type);
+ parent_class = "\"" + type->script->get_path() + "\"";
+ }
+
+ scr = ScriptServer::get_language(language_menu->get_selected())->make_template(sinfo.content, cname_param, parent_class);
if (has_named_classes) {
String cname = class_name->get_text();