diff options
165 files changed, 5917 insertions, 4634 deletions
diff --git a/core/io/resource_importer.cpp b/core/io/resource_importer.cpp index e167611d4a..9b6440e2a2 100644 --- a/core/io/resource_importer.cpp +++ b/core/io/resource_importer.cpp @@ -464,7 +464,11 @@ void ResourceImporter::_bind_methods() { BIND_ENUM_CONSTANT(IMPORT_ORDER_SCENE); } -void ResourceFormatImporter::add_importer(const Ref<ResourceImporter> &p_importer) { +void ResourceFormatImporter::add_importer(const Ref<ResourceImporter> &p_importer, bool p_first_priority) { ERR_FAIL_COND(p_importer.is_null()); - importers.insert(0, p_importer); + if (p_first_priority) { + importers.insert(0, p_importer); + } else { + importers.push_back(p_importer); + } } diff --git a/core/io/resource_importer.h b/core/io/resource_importer.h index f242f29ccd..2fffc16ad8 100644 --- a/core/io/resource_importer.h +++ b/core/io/resource_importer.h @@ -80,7 +80,7 @@ public: String get_internal_resource_path(const String &p_path) const; void get_internal_resource_path_list(const String &p_path, List<String> *r_paths); - void add_importer(const Ref<ResourceImporter> &p_importer); + void add_importer(const Ref<ResourceImporter> &p_importer, bool p_first_priority = false); void remove_importer(const Ref<ResourceImporter> &p_importer) { importers.erase(p_importer); } Ref<ResourceImporter> get_importer_by_name(const String &p_name) const; diff --git a/doc/classes/EditorPlugin.xml b/doc/classes/EditorPlugin.xml index cc1243898f..b9267bc577 100644 --- a/doc/classes/EditorPlugin.xml +++ b/doc/classes/EditorPlugin.xml @@ -379,8 +379,10 @@ <method name="add_import_plugin"> <return type="void" /> <argument index="0" name="importer" type="EditorImportPlugin" /> + <argument index="1" name="first_priority" type="bool" default="false" /> <description> Registers a new [EditorImportPlugin]. Import plugins are used to import custom and unsupported assets as a custom [Resource] type. + If [code]first_priority[/code] is [code]true[/code], the new import plugin is inserted first in the list and takes precedence over pre-existing plugins. [b]Note:[/b] If you want to import custom 3D asset formats use [method add_scene_format_importer_plugin] instead. See [method add_inspector_plugin] for an example of how to register a plugin. </description> @@ -408,15 +410,19 @@ <method name="add_scene_format_importer_plugin"> <return type="void" /> <argument index="0" name="scene_format_importer" type="EditorSceneFormatImporter" /> + <argument index="1" name="first_priority" type="bool" default="false" /> <description> Registers a new [EditorSceneFormatImporter]. Scene importers are used to import custom 3D asset formats as scenes. + If [code]first_priority[/code] is [code]true[/code], the new import plugin is inserted first in the list and takes precedence over pre-existing plugins. </description> </method> <method name="add_scene_post_import_plugin"> <return type="void" /> <argument index="0" name="scene_import_plugin" type="EditorScenePostImportPlugin" /> + <argument index="1" name="first_priority" type="bool" default="false" /> <description> Add a [EditorScenePostImportPlugin]. These plugins allow customizing the import process of 3D assets by adding new options to the import dialogs. + If [code]first_priority[/code] is [code]true[/code], the new import plugin is inserted first in the list and takes precedence over pre-existing plugins. </description> </method> <method name="add_spatial_gizmo_plugin"> diff --git a/doc/classes/JavaScript.xml b/doc/classes/JavaScript.xml index aeaf8ac1f5..4ea60ad867 100644 --- a/doc/classes/JavaScript.xml +++ b/doc/classes/JavaScript.xml @@ -53,5 +53,27 @@ Returns an interface to a JavaScript object that can be used by scripts. The [code]interface[/code] must be a valid property of the JavaScript [code]window[/code]. The callback must accept a single [Array] argument, which will contain the JavaScript [code]arguments[/code]. See [JavaScriptObject] for usage. </description> </method> + <method name="pwa_needs_update" qualifiers="const"> + <return type="bool" /> + <description> + Returns [code]true[/code] if a new version of the progressive web app is waiting to be activated. + [b]Note:[/b] Only relevant when exported as a Progressive Web App. + </description> + </method> + <method name="pwa_update"> + <return type="int" enum="Error" /> + <description> + Performs the live update of the progressive web app. Forcing the new version to be installed and the page to be reloaded. + [b]Note:[/b] Your application will be [b]reloaded in all browser tabs[/b]. + [b]Note:[/b] Only relevant when exported as a Progressive Web App and [method pwa_needs_update] returns [code]true[/code]. + </description> + </method> </methods> + <signals> + <signal name="pwa_update_available"> + <description> + Emitted when an update for this progressive web app has been detected but is waiting to be activated because a previous version is active. See [method pwa_update] to force the update to take place immediately. + </description> + </signal> + </signals> </class> diff --git a/doc/classes/VisualShaderNodeParticleRandomness.xml b/doc/classes/VisualShaderNodeParticleRandomness.xml index 2dec41105c..880208b136 100644 --- a/doc/classes/VisualShaderNodeParticleRandomness.xml +++ b/doc/classes/VisualShaderNodeParticleRandomness.xml @@ -8,14 +8,20 @@ </tutorials> <members> <member name="op_type" type="int" setter="set_op_type" getter="get_op_type" enum="VisualShaderNodeParticleRandomness.OpType" default="0"> + A type of operands and returned value. </member> </members> <constants> <constant name="OP_TYPE_SCALAR" value="0" enum="OpType"> + A floating-point scalar. </constant> - <constant name="OP_TYPE_VECTOR" value="1" enum="OpType"> + <constant name="OP_TYPE_VECTOR_2D" value="1" enum="OpType"> + A 2D vector type. </constant> - <constant name="OP_TYPE_MAX" value="2" enum="OpType"> + <constant name="OP_TYPE_VECTOR_3D" value="2" enum="OpType"> + A 3D vector type. + </constant> + <constant name="OP_TYPE_MAX" value="3" enum="OpType"> Represents the size of the [enum OpType] enum. </constant> </constants> diff --git a/editor/animation_track_editor.cpp b/editor/animation_track_editor.cpp index 2f33619a52..dab928794f 100644 --- a/editor/animation_track_editor.cpp +++ b/editor/animation_track_editor.cpp @@ -4368,7 +4368,7 @@ void AnimationTrackEditor::_update_tracks() { g->set_timeline(timeline); groups.push_back(g); VBoxContainer *vb = memnew(VBoxContainer); - vb->add_theme_constant_override("separation", 0); + vb->add_theme_constant_override(SNAME("separation"), 0); vb->add_child(g); track_vbox->add_child(vb); group_sort[base_path] = vb; @@ -4519,7 +4519,7 @@ void AnimationTrackEditor::_notification(int p_what) { view_group->set_icon(get_theme_icon(view_group->is_pressed() ? SNAME("AnimationTrackList") : SNAME("AnimationTrackGroup"), SNAME("EditorIcons"))); selected_filter->set_icon(get_theme_icon(SNAME("AnimationFilter"), SNAME("EditorIcons"))); imported_anim_warning->set_icon(get_theme_icon(SNAME("NodeWarning"), SNAME("EditorIcons"))); - main_panel->add_theme_style_override("panel", get_theme_stylebox(SNAME("bg"), SNAME("Tree"))); + main_panel->add_theme_style_override(SNAME("panel"), get_theme_stylebox(SNAME("bg"), SNAME("Tree"))); edit->get_popup()->set_item_icon(edit->get_popup()->get_item_index(EDIT_APPLY_RESET), get_theme_icon(SNAME("Reload"), SNAME("EditorIcons"))); } @@ -6085,7 +6085,7 @@ AnimationTrackEditor::AnimationTrackEditor() { timeline_scroll->add_child(timeline_vbox); timeline_vbox->set_v_size_flags(SIZE_EXPAND_FILL); timeline_vbox->set_h_size_flags(SIZE_EXPAND_FILL); - timeline_vbox->add_theme_constant_override("separation", 0); + timeline_vbox->add_theme_constant_override(SNAME("separation"), 0); info_message = memnew(Label); info_message->set_text(TTR("Select an AnimationPlayer node to create and edit animations.")); @@ -6140,7 +6140,7 @@ AnimationTrackEditor::AnimationTrackEditor() { scroll->add_child(track_vbox); track_vbox->set_h_size_flags(SIZE_EXPAND_FILL); scroll->set_horizontal_scroll_mode(ScrollContainer::SCROLL_MODE_DISABLED); - track_vbox->add_theme_constant_override("separation", 0); + track_vbox->add_theme_constant_override(SNAME("separation"), 0); HBoxContainer *bottom_hb = memnew(HBoxContainer); add_child(bottom_hb); diff --git a/editor/code_editor.cpp b/editor/code_editor.cpp index 2627baaea8..daca1e9587 100644 --- a/editor/code_editor.cpp +++ b/editor/code_editor.cpp @@ -105,7 +105,7 @@ void FindReplaceBar::_notification(int p_what) { hide_button->set_pressed_texture(get_theme_icon(SNAME("Close"), SNAME("EditorIcons"))); hide_button->set_custom_minimum_size(hide_button->get_normal_texture()->get_size()); } else if (p_what == NOTIFICATION_THEME_CHANGED) { - matches_label->add_theme_color_override("font_color", results_count > 0 ? get_theme_color(SNAME("font_color"), SNAME("Label")) : get_theme_color(SNAME("error_color"), SNAME("Editor"))); + matches_label->add_theme_color_override(SNAME("font_color"), results_count > 0 ? get_theme_color(SNAME("font_color"), SNAME("Label")) : get_theme_color(SNAME("error_color"), SNAME("Editor"))); } else if (p_what == NOTIFICATION_PREDELETE) { if (base_text_editor) { base_text_editor->remove_find_replace_bar(); @@ -301,7 +301,7 @@ void FindReplaceBar::_replace_all() { } text_editor->set_v_scroll(vsval); - matches_label->add_theme_color_override("font_color", rc > 0 ? get_theme_color(SNAME("font_color"), SNAME("Label")) : get_theme_color(SNAME("error_color"), SNAME("Editor"))); + matches_label->add_theme_color_override(SNAME("font_color"), rc > 0 ? get_theme_color(SNAME("font_color"), SNAME("Label")) : get_theme_color(SNAME("error_color"), SNAME("Editor"))); matches_label->set_text(vformat(TTR("%d replaced."), rc)); text_editor->call_deferred(SNAME("connect"), "text_changed", callable_mp(this, &FindReplaceBar::_editor_text_changed)); @@ -365,7 +365,7 @@ void FindReplaceBar::_update_matches_label() { } else { matches_label->show(); - matches_label->add_theme_color_override("font_color", results_count > 0 ? get_theme_color(SNAME("font_color"), SNAME("Label")) : get_theme_color(SNAME("error_color"), SNAME("Editor"))); + matches_label->add_theme_color_override(SNAME("font_color"), results_count > 0 ? get_theme_color(SNAME("font_color"), SNAME("Label")) : get_theme_color(SNAME("error_color"), SNAME("Editor"))); matches_label->set_text(vformat(results_count == 1 ? TTR("%d match.") : TTR("%d matches."), results_count)); } } @@ -818,7 +818,7 @@ void CodeTextEditor::_zoom_changed() { void CodeTextEditor::_reset_zoom() { EditorSettings::get_singleton()->set("interface/editor/code_font_size", 14); - text_editor->add_theme_font_size_override("font_size", 14 * EDSCALE); + text_editor->add_theme_font_size_override(SNAME("font_size"), 14 * EDSCALE); } void CodeTextEditor::_line_col_changed() { @@ -936,7 +936,7 @@ bool CodeTextEditor::_add_font_size(int p_delta) { if (new_size != old_size) { EditorSettings::get_singleton()->set("interface/editor/code_font_size", new_size / EDSCALE); - text_editor->add_theme_font_size_override("font_size", new_size); + text_editor->add_theme_font_size_override(SNAME("font_size"), new_size); } return true; @@ -1567,14 +1567,14 @@ void CodeTextEditor::_update_text_editor_theme() { Ref<Font> status_bar_font = get_theme_font(SNAME("status_source"), SNAME("EditorFonts")); int status_bar_font_size = get_theme_font_size(SNAME("status_source_size"), SNAME("EditorFonts")); - error->add_theme_font_override("font", status_bar_font); - error->add_theme_font_size_override("font_size", status_bar_font_size); + error->add_theme_font_override(SNAME("font"), status_bar_font); + error->add_theme_font_size_override(SNAME("font_size"), status_bar_font_size); int count = status_bar->get_child_count(); for (int i = 0; i < count; i++) { Control *n = Object::cast_to<Control>(status_bar->get_child(i)); if (n) { - n->add_theme_font_override("font", status_bar_font); - n->add_theme_font_size_override("font_size", status_bar_font_size); + n->add_theme_font_override(SNAME("font"), status_bar_font); + n->add_theme_font_size_override(SNAME("font_size"), status_bar_font_size); } } error->end_bulk_theme_override(); @@ -1666,17 +1666,17 @@ void CodeTextEditor::_notification(int p_what) { case NOTIFICATION_ENTER_TREE: case NOTIFICATION_THEME_CHANGED: { error_button->set_icon(get_theme_icon(SNAME("StatusError"), SNAME("EditorIcons"))); - error_button->add_theme_color_override("font_color", get_theme_color(SNAME("error_color"), SNAME("Editor"))); - error_button->add_theme_font_override("font", get_theme_font(SNAME("status_source"), SNAME("EditorFonts"))); - error_button->add_theme_font_size_override("font_size", get_theme_font_size(SNAME("status_source_size"), SNAME("EditorFonts"))); + error_button->add_theme_color_override(SNAME("font_color"), get_theme_color(SNAME("error_color"), SNAME("Editor"))); + error_button->add_theme_font_override(SNAME("font"), get_theme_font(SNAME("status_source"), SNAME("EditorFonts"))); + error_button->add_theme_font_size_override(SNAME("font_size"), get_theme_font_size(SNAME("status_source_size"), SNAME("EditorFonts"))); warning_button->set_icon(get_theme_icon(SNAME("NodeWarning"), SNAME("EditorIcons"))); - warning_button->add_theme_color_override("font_color", get_theme_color(SNAME("warning_color"), SNAME("Editor"))); - warning_button->add_theme_font_override("font", get_theme_font(SNAME("status_source"), SNAME("EditorFonts"))); - warning_button->add_theme_font_size_override("font_size", get_theme_font_size(SNAME("status_source_size"), SNAME("EditorFonts"))); + warning_button->add_theme_color_override(SNAME("font_color"), get_theme_color(SNAME("warning_color"), SNAME("Editor"))); + warning_button->add_theme_font_override(SNAME("font"), get_theme_font(SNAME("status_source"), SNAME("EditorFonts"))); + warning_button->add_theme_font_size_override(SNAME("font_size"), get_theme_font_size(SNAME("status_source_size"), SNAME("EditorFonts"))); - line_and_col_txt->add_theme_font_override("font", get_theme_font(SNAME("status_source"), SNAME("EditorFonts"))); - line_and_col_txt->add_theme_font_size_override("font_size", get_theme_font_size(SNAME("status_source_size"), SNAME("EditorFonts"))); + line_and_col_txt->add_theme_font_override(SNAME("font"), get_theme_font(SNAME("status_source"), SNAME("EditorFonts"))); + line_and_col_txt->add_theme_font_size_override(SNAME("font_size"), get_theme_font_size(SNAME("status_source_size"), SNAME("EditorFonts"))); if (p_what == NOTIFICATION_ENTER_TREE) { break; @@ -1935,5 +1935,5 @@ CodeTextEditor::CodeTextEditor() { font_resize_timer->connect("timeout", callable_mp(this, &CodeTextEditor::_font_resize_timeout)); EditorSettings::get_singleton()->connect("settings_changed", callable_mp(this, &CodeTextEditor::_on_settings_change)); - add_theme_constant_override("separation", 4 * EDSCALE); + add_theme_constant_override(SNAME("separation"), 4 * EDSCALE); } diff --git a/editor/connections_dialog.cpp b/editor/connections_dialog.cpp index 8efcd60210..146eb59623 100644 --- a/editor/connections_dialog.cpp +++ b/editor/connections_dialog.cpp @@ -381,7 +381,7 @@ void ConnectDialog::init(ConnectionData p_cd, bool p_edit) { void ConnectDialog::popup_dialog(const String &p_for_signal) { from_signal->set_text(p_for_signal); - error_label->add_theme_color_override("font_color", error_label->get_theme_color(SNAME("error_color"), SNAME("Editor"))); + error_label->add_theme_color_override(SNAME("font_color"), error_label->get_theme_color(SNAME("error_color"), SNAME("Editor"))); if (!advanced->is_pressed()) { error_label->set_visible(!_find_first_script(get_tree()->get_edited_scene_root(), get_tree()->get_edited_scene_root())); } @@ -1200,7 +1200,7 @@ ConnectionsDock::ConnectionsDock(EditorNode *p_editor) { tree->connect("item_activated", callable_mp(this, &ConnectionsDock::_tree_item_activated)); tree->connect("item_rmb_selected", callable_mp(this, &ConnectionsDock::_rmb_pressed)); - add_theme_constant_override("separation", 3 * EDSCALE); + add_theme_constant_override(SNAME("separation"), 3 * EDSCALE); EDITOR_DEF("interface/editors/default_signal_callback_name", "_on_{node_name}_{signal_name}"); } diff --git a/editor/create_dialog.cpp b/editor/create_dialog.cpp index e8fd97fa1a..119e81c150 100644 --- a/editor/create_dialog.cpp +++ b/editor/create_dialog.cpp @@ -743,7 +743,7 @@ CreateDialog::CreateDialog() { favorites->set_allow_reselect(true); favorites->connect("cell_selected", callable_mp(this, &CreateDialog::_favorite_selected)); favorites->connect("item_activated", callable_mp(this, &CreateDialog::_favorite_activated)); - favorites->add_theme_constant_override("draw_guides", 1); + favorites->add_theme_constant_override(SNAME("draw_guides"), 1); #ifndef _MSC_VER #warning cannot forward drag data to a non control, must be fixed #endif @@ -760,7 +760,7 @@ CreateDialog::CreateDialog() { recent->set_allow_reselect(true); recent->connect("item_selected", callable_mp(this, &CreateDialog::_history_selected)); recent->connect("item_activated", callable_mp(this, &CreateDialog::_history_activated)); - recent->add_theme_constant_override("draw_guides", 1); + recent->add_theme_constant_override(SNAME("draw_guides"), 1); VBoxContainer *vbc = memnew(VBoxContainer); vbc->set_custom_minimum_size(Size2(300, 0) * EDSCALE); diff --git a/editor/debugger/editor_debugger_node.cpp b/editor/debugger/editor_debugger_node.cpp index 4b6a11f388..6d9ad9398c 100644 --- a/editor/debugger/editor_debugger_node.cpp +++ b/editor/debugger/editor_debugger_node.cpp @@ -55,8 +55,8 @@ EditorDebuggerNode::EditorDebuggerNode() { singleton = this; } - add_theme_constant_override("margin_left", -EditorNode::get_singleton()->get_gui_base()->get_theme_stylebox(SNAME("BottomPanelDebuggerOverride"), SNAME("EditorStyles"))->get_margin(SIDE_LEFT)); - add_theme_constant_override("margin_right", -EditorNode::get_singleton()->get_gui_base()->get_theme_stylebox(SNAME("BottomPanelDebuggerOverride"), SNAME("EditorStyles"))->get_margin(SIDE_RIGHT)); + add_theme_constant_override(SNAME("margin_left"), -EditorNode::get_singleton()->get_gui_base()->get_theme_stylebox(SNAME("BottomPanelDebuggerOverride"), SNAME("EditorStyles"))->get_margin(SIDE_LEFT)); + add_theme_constant_override(SNAME("margin_right"), -EditorNode::get_singleton()->get_gui_base()->get_theme_stylebox(SNAME("BottomPanelDebuggerOverride"), SNAME("EditorStyles"))->get_margin(SIDE_RIGHT)); tabs = memnew(TabContainer); tabs->set_tab_alignment(TabContainer::ALIGNMENT_LEFT); @@ -66,7 +66,7 @@ EditorDebuggerNode::EditorDebuggerNode() { Ref<StyleBoxEmpty> empty; empty.instantiate(); - tabs->add_theme_style_override("panel", empty); + tabs->add_theme_style_override(SNAME("panel"), empty); auto_switch_remote_scene_tree = EDITOR_DEF("debugger/auto_switch_to_remote_scene_tree", false); _add_debugger(); @@ -113,7 +113,7 @@ ScriptEditorDebugger *EditorDebuggerNode::_add_debugger() { if (tabs->get_tab_count() > 1) { node->clear_style(); tabs->set_tabs_visible(true); - tabs->add_theme_style_override("panel", EditorNode::get_singleton()->get_gui_base()->get_theme_stylebox(SNAME("DebuggerPanel"), SNAME("EditorStyles"))); + tabs->add_theme_style_override(SNAME("panel"), EditorNode::get_singleton()->get_gui_base()->get_theme_stylebox(SNAME("DebuggerPanel"), SNAME("EditorStyles"))); } if (!debugger_plugins.is_empty()) { @@ -233,10 +233,10 @@ void EditorDebuggerNode::_notification(int p_what) { switch (p_what) { case EditorSettings::NOTIFICATION_EDITOR_SETTINGS_CHANGED: { if (tabs->get_tab_count() > 1) { - add_theme_constant_override("margin_left", -EditorNode::get_singleton()->get_gui_base()->get_theme_stylebox(SNAME("BottomPanelDebuggerOverride"), SNAME("EditorStyles"))->get_margin(SIDE_LEFT)); - add_theme_constant_override("margin_right", -EditorNode::get_singleton()->get_gui_base()->get_theme_stylebox(SNAME("BottomPanelDebuggerOverride"), SNAME("EditorStyles"))->get_margin(SIDE_RIGHT)); + add_theme_constant_override(SNAME("margin_left"), -EditorNode::get_singleton()->get_gui_base()->get_theme_stylebox(SNAME("BottomPanelDebuggerOverride"), SNAME("EditorStyles"))->get_margin(SIDE_LEFT)); + add_theme_constant_override(SNAME("margin_right"), -EditorNode::get_singleton()->get_gui_base()->get_theme_stylebox(SNAME("BottomPanelDebuggerOverride"), SNAME("EditorStyles"))->get_margin(SIDE_RIGHT)); - tabs->add_theme_style_override("panel", EditorNode::get_singleton()->get_gui_base()->get_theme_stylebox(SNAME("DebuggerPanel"), SNAME("EditorStyles"))); + tabs->add_theme_style_override(SNAME("panel"), EditorNode::get_singleton()->get_gui_base()->get_theme_stylebox(SNAME("DebuggerPanel"), SNAME("EditorStyles"))); } } break; case NOTIFICATION_READY: { @@ -271,20 +271,20 @@ void EditorDebuggerNode::_notification(int p_what) { if (error_count == 0 && warning_count == 0) { debugger_button->set_text(TTR("Debugger")); - debugger_button->remove_theme_color_override("font_color"); + debugger_button->remove_theme_color_override(SNAME("font_color")); debugger_button->set_icon(Ref<Texture2D>()); } else { debugger_button->set_text(TTR("Debugger") + " (" + itos(error_count + warning_count) + ")"); if (error_count >= 1 && warning_count >= 1) { debugger_button->set_icon(get_theme_icon(SNAME("ErrorWarning"), SNAME("EditorIcons"))); // Use error color to represent the highest level of severity reported. - debugger_button->add_theme_color_override("font_color", get_theme_color(SNAME("error_color"), SNAME("Editor"))); + debugger_button->add_theme_color_override(SNAME("font_color"), get_theme_color(SNAME("error_color"), SNAME("Editor"))); } else if (error_count >= 1) { debugger_button->set_icon(get_theme_icon(SNAME("Error"), SNAME("EditorIcons"))); - debugger_button->add_theme_color_override("font_color", get_theme_color(SNAME("error_color"), SNAME("Editor"))); + debugger_button->add_theme_color_override(SNAME("font_color"), get_theme_color(SNAME("error_color"), SNAME("Editor"))); } else { debugger_button->set_icon(get_theme_icon(SNAME("Warning"), SNAME("EditorIcons"))); - debugger_button->add_theme_color_override("font_color", get_theme_color(SNAME("warning_color"), SNAME("Editor"))); + debugger_button->add_theme_color_override(SNAME("font_color"), get_theme_color(SNAME("warning_color"), SNAME("Editor"))); } } last_error_count = error_count; diff --git a/editor/debugger/editor_network_profiler.cpp b/editor/debugger/editor_network_profiler.cpp index 698e950f57..c04ec465e5 100644 --- a/editor/debugger/editor_network_profiler.cpp +++ b/editor/debugger/editor_network_profiler.cpp @@ -46,8 +46,8 @@ void EditorNetworkProfiler::_notification(int p_what) { outgoing_bandwidth_text->set_right_icon(get_theme_icon(SNAME("ArrowUp"), SNAME("EditorIcons"))); // This needs to be done here to set the faded color when the profiler is first opened - incoming_bandwidth_text->add_theme_color_override("font_uneditable_color", get_theme_color(SNAME("font_color"), SNAME("Editor")) * Color(1, 1, 1, 0.5)); - outgoing_bandwidth_text->add_theme_color_override("font_uneditable_color", get_theme_color(SNAME("font_color"), SNAME("Editor")) * Color(1, 1, 1, 0.5)); + incoming_bandwidth_text->add_theme_color_override(SNAME("font_uneditable_color"), get_theme_color(SNAME("font_color"), SNAME("Editor")) * Color(1, 1, 1, 0.5)); + outgoing_bandwidth_text->add_theme_color_override(SNAME("font_uneditable_color"), get_theme_color(SNAME("font_color"), SNAME("Editor")) * Color(1, 1, 1, 0.5)); } } @@ -126,7 +126,7 @@ bool EditorNetworkProfiler::is_profiling() { EditorNetworkProfiler::EditorNetworkProfiler() { HBoxContainer *hb = memnew(HBoxContainer); - hb->add_theme_constant_override("separation", 8 * EDSCALE); + hb->add_theme_constant_override(SNAME("separation"), 8 * EDSCALE); add_child(hb); activate = memnew(Button); diff --git a/editor/debugger/editor_profiler.cpp b/editor/debugger/editor_profiler.cpp index da1d6a54f2..0a10bc95cc 100644 --- a/editor/debugger/editor_profiler.cpp +++ b/editor/debugger/editor_profiler.cpp @@ -618,7 +618,7 @@ EditorProfiler::EditorProfiler() { hb->add_child(cursor_metric_edit); cursor_metric_edit->connect("value_changed", callable_mp(this, &EditorProfiler::_cursor_metric_changed)); - hb->add_theme_constant_override("separation", 8 * EDSCALE); + hb->add_theme_constant_override(SNAME("separation"), 8 * EDSCALE); h_split = memnew(HSplitContainer); add_child(h_split); diff --git a/editor/debugger/editor_visual_profiler.cpp b/editor/debugger/editor_visual_profiler.cpp index 3cb5d3513d..5f61edcf8c 100644 --- a/editor/debugger/editor_visual_profiler.cpp +++ b/editor/debugger/editor_visual_profiler.cpp @@ -758,7 +758,7 @@ EditorVisualProfiler::EditorVisualProfiler() { hb->add_child(cursor_metric_edit); cursor_metric_edit->connect("value_changed", callable_mp(this, &EditorVisualProfiler::_cursor_metric_changed)); - hb->add_theme_constant_override("separation", 8 * EDSCALE); + hb->add_theme_constant_override(SNAME("separation"), 8 * EDSCALE); h_split = memnew(HSplitContainer); add_child(h_split); diff --git a/editor/debugger/script_editor_debugger.cpp b/editor/debugger/script_editor_debugger.cpp index 6aedfa6ccb..d0be846f76 100644 --- a/editor/debugger/script_editor_debugger.cpp +++ b/editor/debugger/script_editor_debugger.cpp @@ -147,7 +147,7 @@ void ScriptEditorDebugger::update_tabs() { } void ScriptEditorDebugger::clear_style() { - tabs->remove_theme_style_override("panel"); + tabs->remove_theme_style_override(SNAME("panel")); } void ScriptEditorDebugger::save_node(ObjectID p_id, const String &p_file) { @@ -762,13 +762,13 @@ void ScriptEditorDebugger::_parse_message(const String &p_msg, const Array &p_da void ScriptEditorDebugger::_set_reason_text(const String &p_reason, MessageType p_type) { switch (p_type) { case MESSAGE_ERROR: - reason->add_theme_color_override("font_color", get_theme_color(SNAME("error_color"), SNAME("Editor"))); + reason->add_theme_color_override(SNAME("font_color"), get_theme_color(SNAME("error_color"), SNAME("Editor"))); break; case MESSAGE_WARNING: - reason->add_theme_color_override("font_color", get_theme_color(SNAME("warning_color"), SNAME("Editor"))); + reason->add_theme_color_override(SNAME("font_color"), get_theme_color(SNAME("warning_color"), SNAME("Editor"))); break; default: - reason->add_theme_color_override("font_color", get_theme_color(SNAME("success_color"), SNAME("Editor"))); + reason->add_theme_color_override(SNAME("font_color"), get_theme_color(SNAME("success_color"), SNAME("Editor"))); } reason->set_text(p_reason); reason->set_tooltip(p_reason.word_wrap(80)); @@ -793,7 +793,7 @@ void ScriptEditorDebugger::_notification(int p_what) { vmem_export->set_icon(get_theme_icon(SNAME("Save"), SNAME("EditorIcons"))); search->set_right_icon(get_theme_icon(SNAME("Search"), SNAME("EditorIcons"))); - reason->add_theme_color_override("font_color", get_theme_color(SNAME("error_color"), SNAME("Editor"))); + reason->add_theme_color_override(SNAME("font_color"), get_theme_color(SNAME("error_color"), SNAME("Editor"))); } break; case NOTIFICATION_PROCESS: { @@ -855,8 +855,8 @@ void ScriptEditorDebugger::_notification(int p_what) { }; } break; case EditorSettings::NOTIFICATION_EDITOR_SETTINGS_CHANGED: { - if (tabs->has_theme_stylebox_override("panel")) { - tabs->add_theme_style_override("panel", editor->get_gui_base()->get_theme_stylebox(SNAME("DebuggerPanel"), SNAME("EditorStyles"))); + if (tabs->has_theme_stylebox_override(SNAME("panel"))) { + tabs->add_theme_style_override(SNAME("panel"), editor->get_gui_base()->get_theme_stylebox(SNAME("DebuggerPanel"), SNAME("EditorStyles"))); } copy->set_icon(get_theme_icon(SNAME("ActionCopy"), SNAME("EditorIcons"))); @@ -1665,7 +1665,7 @@ ScriptEditorDebugger::ScriptEditorDebugger(EditorNode *p_editor) { tabs = memnew(TabContainer); tabs->set_tab_alignment(TabContainer::ALIGNMENT_LEFT); - tabs->add_theme_style_override("panel", editor->get_gui_base()->get_theme_stylebox(SNAME("DebuggerPanel"), SNAME("EditorStyles"))); + tabs->add_theme_style_override(SNAME("panel"), editor->get_gui_base()->get_theme_stylebox(SNAME("DebuggerPanel"), SNAME("EditorStyles"))); tabs->connect("tab_changed", callable_mp(this, &ScriptEditorDebugger::_tab_changed)); add_child(tabs); diff --git a/editor/editor_about.cpp b/editor/editor_about.cpp index 54377971c6..267fe875ca 100644 --- a/editor/editor_about.cpp +++ b/editor/editor_about.cpp @@ -43,12 +43,12 @@ static const String META_TEXT_TO_COPY = "text_to_copy"; void EditorAbout::_theme_changed() { const Ref<Font> font = get_theme_font(SNAME("source"), SNAME("EditorFonts")); const int font_size = get_theme_font_size(SNAME("source_size"), SNAME("EditorFonts")); - _tpl_text->add_theme_font_override("normal_font", font); - _tpl_text->add_theme_font_size_override("normal_font_size", font_size); - _tpl_text->add_theme_constant_override("line_separation", 6 * EDSCALE); - _license_text->add_theme_font_override("normal_font", font); - _license_text->add_theme_font_size_override("normal_font_size", font_size); - _license_text->add_theme_constant_override("line_separation", 6 * EDSCALE); + _tpl_text->add_theme_font_override(SNAME("normal_font"), font); + _tpl_text->add_theme_font_size_override(SNAME("normal_font_size"), font_size); + _tpl_text->add_theme_constant_override(SNAME("line_separation"), 6 * EDSCALE); + _license_text->add_theme_font_override(SNAME("normal_font"), font); + _license_text->add_theme_font_size_override(SNAME("normal_font_size"), font_size); + _license_text->add_theme_constant_override(SNAME("line_separation"), 6 * EDSCALE); _logo->set_texture(get_theme_icon(SNAME("Logo"), SNAME("EditorIcons"))); } @@ -101,7 +101,7 @@ ScrollContainer *EditorAbout::_populate_list(const String &p_name, const List<St il->set_same_column_width(true); il->set_auto_height(true); il->set_mouse_filter(Control::MOUSE_FILTER_IGNORE); - il->add_theme_constant_override("hseparation", 16 * EDSCALE); + il->add_theme_constant_override(SNAME("hseparation"), 16 * EDSCALE); while (*names_ptr) { il->add_item(String::utf8(*names_ptr++), nullptr, false); } @@ -126,7 +126,7 @@ EditorAbout::EditorAbout() { HBoxContainer *hbc = memnew(HBoxContainer); hbc->set_h_size_flags(Control::SIZE_EXPAND_FILL); hbc->set_alignment(BoxContainer::ALIGNMENT_CENTER); - hbc->add_theme_constant_override("separation", 30 * EDSCALE); + hbc->add_theme_constant_override(SNAME("separation"), 30 * EDSCALE); add_child(vbc); vbc->add_child(hbc); diff --git a/editor/editor_audio_buses.cpp b/editor/editor_audio_buses.cpp index 5e4e375db4..9434a4e67b 100644 --- a/editor/editor_audio_buses.cpp +++ b/editor/editor_audio_buses.cpp @@ -79,17 +79,17 @@ void EditorAudioBus::_notification(int p_what) { Color bypass_color = EditorSettings::get_singleton()->is_dark_theme() ? Color(0.13, 0.8, 1.0) : Color(0.44, 0.87, 1.0); solo->set_icon(get_theme_icon(SNAME("AudioBusSolo"), SNAME("EditorIcons"))); - solo->add_theme_color_override("icon_pressed_color", solo_color); + solo->add_theme_color_override(SNAME("icon_pressed_color"), solo_color); mute->set_icon(get_theme_icon(SNAME("AudioBusMute"), SNAME("EditorIcons"))); - mute->add_theme_color_override("icon_pressed_color", mute_color); + mute->add_theme_color_override(SNAME("icon_pressed_color"), mute_color); bypass->set_icon(get_theme_icon(SNAME("AudioBusBypass"), SNAME("EditorIcons"))); - bypass->add_theme_color_override("icon_pressed_color", bypass_color); + bypass->add_theme_color_override(SNAME("icon_pressed_color"), bypass_color); bus_options->set_icon(get_theme_icon(SNAME("GuiTabMenuHl"), SNAME("EditorIcons"))); - audio_value_preview_label->add_theme_color_override("font_color", get_theme_color(SNAME("font_color"), SNAME("TooltipLabel"))); - audio_value_preview_label->add_theme_color_override("font_shadow_color", get_theme_color(SNAME("font_shadow_color"), SNAME("TooltipLabel"))); - audio_value_preview_box->add_theme_style_override("panel", get_theme_stylebox(SNAME("panel"), SNAME("TooltipPanel"))); + audio_value_preview_label->add_theme_color_override(SNAME("font_color"), get_theme_color(SNAME("font_color"), SNAME("TooltipLabel"))); + audio_value_preview_label->add_theme_color_override(SNAME("font_shadow_color"), get_theme_color(SNAME("font_shadow_color"), SNAME("TooltipLabel"))); + audio_value_preview_box->add_theme_style_override(SNAME("panel"), get_theme_stylebox(SNAME("panel"), SNAME("TooltipPanel"))); } break; case NOTIFICATION_READY: { @@ -574,7 +574,7 @@ Variant EditorAudioBus::get_drag_data(const Point2 &p_point) { Panel *p = memnew(Panel); c->add_child(p); p->set_modulate(Color(1, 1, 1, 0.7)); - p->add_theme_style_override("panel", get_theme_stylebox(SNAME("focus"), SNAME("Button"))); + p->add_theme_style_override(SNAME("panel"), get_theme_stylebox(SNAME("focus"), SNAME("Button"))); p->set_size(get_size()); p->set_position(-p_point); set_drag_preview(c); @@ -804,10 +804,10 @@ EditorAudioBus::EditorAudioBus(EditorAudioBuses *p_buses, bool p_is_master) { Ref<StyleBoxEmpty> sbempty = memnew(StyleBoxEmpty); for (int i = 0; i < hbc->get_child_count(); i++) { Control *child = Object::cast_to<Control>(hbc->get_child(i)); - child->add_theme_style_override("normal", sbempty); - child->add_theme_style_override("hover", sbempty); - child->add_theme_style_override("focus", sbempty); - child->add_theme_style_override("pressed", sbempty); + child->add_theme_style_override(SNAME("normal"), sbempty); + child->add_theme_style_override(SNAME("hover"), sbempty); + child->add_theme_style_override(SNAME("focus"), sbempty); + child->add_theme_style_override(SNAME("pressed"), sbempty); } HSeparator *separator = memnew(HSeparator); @@ -1013,7 +1013,7 @@ void EditorAudioBuses::_notification(int p_what) { switch (p_what) { case NOTIFICATION_ENTER_TREE: case NOTIFICATION_THEME_CHANGED: { - bus_scroll->add_theme_style_override("bg", get_theme_stylebox(SNAME("bg"), SNAME("Tree"))); + bus_scroll->add_theme_style_override(SNAME("bg"), get_theme_stylebox(SNAME("bg"), SNAME("Tree"))); } break; case NOTIFICATION_READY: { _update_buses(); diff --git a/editor/editor_autoload_settings.cpp b/editor/editor_autoload_settings.cpp index d74a6e12b2..d27d0c8b53 100644 --- a/editor/editor_autoload_settings.cpp +++ b/editor/editor_autoload_settings.cpp @@ -839,7 +839,7 @@ EditorAutoloadSettings::EditorAutoloadSettings() { error_message = memnew(Label); error_message->hide(); error_message->set_horizontal_alignment(HORIZONTAL_ALIGNMENT_RIGHT); - error_message->add_theme_color_override("font_color", EditorNode::get_singleton()->get_gui_base()->get_theme_color(SNAME("error_color"), SNAME("Editor"))); + error_message->add_theme_color_override(SNAME("font_color"), EditorNode::get_singleton()->get_gui_base()->get_theme_color(SNAME("error_color"), SNAME("Editor"))); add_child(error_message); Label *l = memnew(Label); diff --git a/editor/editor_feature_profile.cpp b/editor/editor_feature_profile.cpp index 1d73bdfa6e..1ab532eb32 100644 --- a/editor/editor_feature_profile.cpp +++ b/editor/editor_feature_profile.cpp @@ -592,7 +592,15 @@ void EditorFeatureProfileManager::_class_list_item_selected() { List<PropertyInfo> props; ClassDB::get_property_list(class_name, &props, true); - if (props.size() > 0) { + bool has_editor_props = false; + for (const PropertyInfo &E : props) { + if (E.usage & PROPERTY_USAGE_EDITOR) { + has_editor_props = true; + break; + } + } + + if (has_editor_props) { TreeItem *properties = property_list->create_item(root); properties->set_text(0, TTR("Class Properties:")); @@ -947,7 +955,7 @@ EditorFeatureProfileManager::EditorFeatureProfileManager() { // Add some spacing above the help label. Ref<StyleBoxEmpty> sb = memnew(StyleBoxEmpty); sb->set_default_margin(SIDE_TOP, 20 * EDSCALE); - no_profile_selected_help->add_theme_style_override("normal", sb); + no_profile_selected_help->add_theme_style_override(SNAME("normal"), sb); no_profile_selected_help->set_horizontal_alignment(HORIZONTAL_ALIGNMENT_CENTER); no_profile_selected_help->set_v_size_flags(Control::SIZE_EXPAND_FILL); h_split->add_child(no_profile_selected_help); diff --git a/editor/editor_fonts.cpp b/editor/editor_fonts.cpp index 0c9a7b2972..db87801fbb 100644 --- a/editor/editor_fonts.cpp +++ b/editor/editor_fonts.cpp @@ -279,67 +279,67 @@ void editor_register_fonts(Ref<Theme> p_theme) { p_theme->set_default_font(df); // Default theme font p_theme->set_default_font_size(default_font_size); - p_theme->set_font_size("main_size", "EditorFonts", default_font_size); - p_theme->set_font("main", "EditorFonts", df); + p_theme->set_font_size(SNAME("main_size"), SNAME("EditorFonts"), default_font_size); + p_theme->set_font(SNAME("main"), SNAME("EditorFonts"), df); // Bold font MAKE_BOLD_FONT(df_bold, String()); - p_theme->set_font_size("bold_size", "EditorFonts", default_font_size); - p_theme->set_font("bold", "EditorFonts", df_bold); + p_theme->set_font_size(SNAME("bold_size"), SNAME("EditorFonts"), default_font_size); + p_theme->set_font(SNAME("bold"), SNAME("EditorFonts"), df_bold); // Title font - p_theme->set_font_size("title_size", "EditorFonts", default_font_size + 1 * EDSCALE); - p_theme->set_font("title", "EditorFonts", df_bold); + p_theme->set_font_size(SNAME("title_size"), SNAME("EditorFonts"), default_font_size + 1 * EDSCALE); + p_theme->set_font(SNAME("title"), SNAME("EditorFonts"), df_bold); - p_theme->set_font_size("main_button_font_size", "EditorFonts", default_font_size + 1 * EDSCALE); - p_theme->set_font("main_button_font", "EditorFonts", df_bold); + p_theme->set_font_size(SNAME("main_button_font_size"), SNAME("EditorFonts"), default_font_size + 1 * EDSCALE); + p_theme->set_font(SNAME("main_button_font"), SNAME("EditorFonts"), df_bold); - p_theme->set_font("font", "Label", df); + p_theme->set_font(SNAME("font"), SNAME("Label"), df); - p_theme->set_type_variation("HeaderSmall", "Label"); - p_theme->set_font("font", "HeaderSmall", df_bold); - p_theme->set_font_size("font_size", "HeaderSmall", default_font_size); + p_theme->set_type_variation(SNAME("HeaderSmall"), SNAME("Label")); + p_theme->set_font(SNAME("font"), SNAME("HeaderSmall"), df_bold); + p_theme->set_font_size(SNAME("font_size"), SNAME("HeaderSmall"), default_font_size); - p_theme->set_type_variation("HeaderMedium", "Label"); - p_theme->set_font("font", "HeaderMedium", df_bold); - p_theme->set_font_size("font_size", "HeaderMedium", default_font_size + 1 * EDSCALE); + p_theme->set_type_variation(SNAME("HeaderMedium"), SNAME("Label")); + p_theme->set_font(SNAME("font"), SNAME("HeaderMedium"), df_bold); + p_theme->set_font_size(SNAME("font_size"), SNAME("HeaderMedium"), default_font_size + 1 * EDSCALE); - p_theme->set_type_variation("HeaderLarge", "Label"); - p_theme->set_font("font", "HeaderLarge", df_bold); - p_theme->set_font_size("font_size", "HeaderLarge", default_font_size + 3 * EDSCALE); + p_theme->set_type_variation(SNAME("HeaderLarge"), SNAME("Label")); + p_theme->set_font(SNAME("font"), SNAME("HeaderLarge"), df_bold); + p_theme->set_font_size(SNAME("font_size"), SNAME("HeaderLarge"), default_font_size + 3 * EDSCALE); // Documentation fonts String code_font_custom_variations = EditorSettings::get_singleton()->get("interface/editor/code_font_custom_variations"); MAKE_SOURCE_FONT(df_code, code_font_custom_variations); - p_theme->set_font_size("doc_size", "EditorFonts", int(EDITOR_GET("text_editor/help/help_font_size")) * EDSCALE); - p_theme->set_font("doc", "EditorFonts", df); - p_theme->set_font_size("doc_bold_size", "EditorFonts", int(EDITOR_GET("text_editor/help/help_font_size")) * EDSCALE); - p_theme->set_font("doc_bold", "EditorFonts", df_bold); - p_theme->set_font_size("doc_title_size", "EditorFonts", int(EDITOR_GET("text_editor/help/help_title_font_size")) * EDSCALE); - p_theme->set_font("doc_title", "EditorFonts", df_bold); - p_theme->set_font_size("doc_source_size", "EditorFonts", int(EDITOR_GET("text_editor/help/help_source_font_size")) * EDSCALE); - p_theme->set_font("doc_source", "EditorFonts", df_code); - p_theme->set_font_size("doc_keyboard_size", "EditorFonts", (int(EDITOR_GET("text_editor/help/help_source_font_size")) - 1) * EDSCALE); - p_theme->set_font("doc_keyboard", "EditorFonts", df_code); + p_theme->set_font_size(SNAME("doc_size"), SNAME("EditorFonts"), int(EDITOR_GET("text_editor/help/help_font_size")) * EDSCALE); + p_theme->set_font(SNAME("doc"), SNAME("EditorFonts"), df); + p_theme->set_font_size(SNAME("doc_bold_size"), SNAME("EditorFonts"), int(EDITOR_GET("text_editor/help/help_font_size")) * EDSCALE); + p_theme->set_font(SNAME("doc_bold"), SNAME("EditorFonts"), df_bold); + p_theme->set_font_size(SNAME("doc_title_size"), SNAME("EditorFonts"), int(EDITOR_GET("text_editor/help/help_title_font_size")) * EDSCALE); + p_theme->set_font(SNAME("doc_title"), SNAME("EditorFonts"), df_bold); + p_theme->set_font_size(SNAME("doc_source_size"), SNAME("EditorFonts"), int(EDITOR_GET("text_editor/help/help_source_font_size")) * EDSCALE); + p_theme->set_font(SNAME("doc_source"), SNAME("EditorFonts"), df_code); + p_theme->set_font_size(SNAME("doc_keyboard_size"), SNAME("EditorFonts"), (int(EDITOR_GET("text_editor/help/help_source_font_size")) - 1) * EDSCALE); + p_theme->set_font(SNAME("doc_keyboard"), SNAME("EditorFonts"), df_code); // Ruler font - p_theme->set_font_size("rulers_size", "EditorFonts", 8 * EDSCALE); - p_theme->set_font("rulers", "EditorFonts", df); + p_theme->set_font_size(SNAME("rulers_size"), SNAME("EditorFonts"), 8 * EDSCALE); + p_theme->set_font(SNAME("rulers"), SNAME("EditorFonts"), df); // Rotation widget font - p_theme->set_font_size("rotation_control_size", "EditorFonts", 14 * EDSCALE); - p_theme->set_font("rotation_control", "EditorFonts", df); + p_theme->set_font_size(SNAME("rotation_control_size"), SNAME("EditorFonts"), 14 * EDSCALE); + p_theme->set_font(SNAME("rotation_control"), SNAME("EditorFonts"), df); // Code font - p_theme->set_font_size("source_size", "EditorFonts", int(EDITOR_GET("interface/editor/code_font_size")) * EDSCALE); - p_theme->set_font("source", "EditorFonts", df_code); + p_theme->set_font_size(SNAME("source_size"), SNAME("EditorFonts"), int(EDITOR_GET("interface/editor/code_font_size")) * EDSCALE); + p_theme->set_font(SNAME("source"), SNAME("EditorFonts"), df_code); - p_theme->set_font_size("expression_size", "EditorFonts", (int(EDITOR_GET("interface/editor/code_font_size")) - 1) * EDSCALE); - p_theme->set_font("expression", "EditorFonts", df_code); + p_theme->set_font_size(SNAME("expression_size"), SNAME("EditorFonts"), (int(EDITOR_GET("interface/editor/code_font_size")) - 1) * EDSCALE); + p_theme->set_font(SNAME("expression"), SNAME("EditorFonts"), df_code); - p_theme->set_font_size("output_source_size", "EditorFonts", int(EDITOR_GET("run/output/font_size")) * EDSCALE); - p_theme->set_font("output_source", "EditorFonts", df_code); + p_theme->set_font_size(SNAME("output_source_size"), SNAME("EditorFonts"), int(EDITOR_GET("run/output/font_size")) * EDSCALE); + p_theme->set_font(SNAME("output_source"), SNAME("EditorFonts"), df_code); - p_theme->set_font_size("status_source_size", "EditorFonts", default_font_size); - p_theme->set_font("status_source", "EditorFonts", df_code); + p_theme->set_font_size(SNAME("status_source_size"), SNAME("EditorFonts"), default_font_size); + p_theme->set_font(SNAME("status_source"), SNAME("EditorFonts"), df_code); } diff --git a/editor/editor_help.cpp b/editor/editor_help.cpp index e80e9c43b0..dd5eeac4e5 100644 --- a/editor/editor_help.cpp +++ b/editor/editor_help.cpp @@ -54,10 +54,10 @@ void EditorHelp::_update_theme() { qualifier_color = get_theme_color(SNAME("qualifier_color"), SNAME("EditorHelp")); type_color = get_theme_color(SNAME("type_color"), SNAME("EditorHelp")); - class_desc->add_theme_color_override("selection_color", get_theme_color(SNAME("selection_color"), SNAME("EditorHelp"))); - class_desc->add_theme_constant_override("line_separation", get_theme_constant(SNAME("line_separation"), SNAME("EditorHelp"))); - class_desc->add_theme_constant_override("table_hseparation", get_theme_constant(SNAME("table_hseparation"), SNAME("EditorHelp"))); - class_desc->add_theme_constant_override("table_vseparation", get_theme_constant(SNAME("table_vseparation"), SNAME("EditorHelp"))); + class_desc->add_theme_color_override(SNAME("selection_color"), get_theme_color(SNAME("selection_color"), SNAME("EditorHelp"))); + class_desc->add_theme_constant_override(SNAME("line_separation"), get_theme_constant(SNAME("line_separation"), SNAME("EditorHelp"))); + class_desc->add_theme_constant_override(SNAME("table_hseparation"), get_theme_constant(SNAME("table_hseparation"), SNAME("EditorHelp"))); + class_desc->add_theme_constant_override(SNAME("table_vseparation"), get_theme_constant(SNAME("table_vseparation"), SNAME("EditorHelp"))); doc_font = get_theme_font(SNAME("doc"), SNAME("EditorFonts")); doc_bold_font = get_theme_font(SNAME("doc_bold"), SNAME("EditorFonts")); @@ -176,7 +176,7 @@ void EditorHelp::_class_desc_resized(bool p_force_update_theme) { Ref<StyleBox> class_desc_stylebox = EditorNode::get_singleton()->get_theme_base()->get_theme_stylebox(SNAME("normal"), SNAME("RichTextLabel"))->duplicate(); class_desc_stylebox->set_default_margin(SIDE_LEFT, display_margin); class_desc_stylebox->set_default_margin(SIDE_RIGHT, display_margin); - class_desc->add_theme_style_override("normal", class_desc_stylebox); + class_desc->add_theme_style_override(SNAME("normal"), class_desc_stylebox); } } @@ -1872,7 +1872,7 @@ EditorHelp::EditorHelp() { class_desc = memnew(RichTextLabel); add_child(class_desc); class_desc->set_v_size_flags(SIZE_EXPAND_FILL); - class_desc->add_theme_color_override("selection_color", get_theme_color(SNAME("accent_color"), SNAME("Editor")) * Color(1, 1, 1, 0.4)); + class_desc->add_theme_color_override(SNAME("selection_color"), get_theme_color(SNAME("accent_color"), SNAME("Editor")) * Color(1, 1, 1, 0.4)); class_desc->connect("meta_clicked", callable_mp(this, &EditorHelp::_class_desc_select)); class_desc->connect("gui_input", callable_mp(this, &EditorHelp::_class_desc_input)); @@ -1951,7 +1951,7 @@ void EditorHelpBit::_notification(int p_what) { switch (p_what) { case NOTIFICATION_ENTER_TREE: case NOTIFICATION_THEME_CHANGED: { - rich_text->add_theme_color_override("selection_color", get_theme_color(SNAME("selection_color"), SNAME("EditorHelp"))); + rich_text->add_theme_color_override(SNAME("selection_color"), get_theme_color(SNAME("selection_color"), SNAME("EditorHelp"))); rich_text->clear(); _add_text_to_rt(text, rich_text); rich_text->reset_size(); // Force recalculating size after parsing bbcode. @@ -2039,7 +2039,7 @@ void FindBar::_notification(int p_what) { hide_button->set_hover_texture(get_theme_icon(SNAME("Close"), SNAME("EditorIcons"))); hide_button->set_pressed_texture(get_theme_icon(SNAME("Close"), SNAME("EditorIcons"))); hide_button->set_custom_minimum_size(hide_button->get_normal_texture()->get_size()); - matches_label->add_theme_color_override("font_color", results_count > 0 ? get_theme_color(SNAME("font_color"), SNAME("Label")) : get_theme_color(SNAME("error_color"), SNAME("Editor"))); + matches_label->add_theme_color_override(SNAME("font_color"), results_count > 0 ? get_theme_color(SNAME("font_color"), SNAME("Label")) : get_theme_color(SNAME("error_color"), SNAME("Editor"))); } break; case NOTIFICATION_VISIBILITY_CHANGED: { set_process_unhandled_input(is_visible_in_tree()); @@ -2110,7 +2110,7 @@ void FindBar::_update_matches_label() { } else { matches_label->show(); - matches_label->add_theme_color_override("font_color", results_count > 0 ? get_theme_color(SNAME("font_color"), SNAME("Label")) : get_theme_color(SNAME("error_color"), SNAME("Editor"))); + matches_label->add_theme_color_override(SNAME("font_color"), results_count > 0 ? get_theme_color(SNAME("font_color"), SNAME("Label")) : get_theme_color(SNAME("error_color"), SNAME("Editor"))); matches_label->set_text(vformat(results_count == 1 ? TTR("%d match.") : TTR("%d matches."), results_count)); } } diff --git a/editor/editor_help_search.cpp b/editor/editor_help_search.cpp index 36d3ac9e66..550e6ee72b 100644 --- a/editor/editor_help_search.cpp +++ b/editor/editor_help_search.cpp @@ -38,7 +38,7 @@ void EditorHelpSearch::_update_icons() { search_box->set_right_icon(results_tree->get_theme_icon(SNAME("Search"), SNAME("EditorIcons"))); search_box->set_clear_button_enabled(true); - search_box->add_theme_icon_override("right_icon", results_tree->get_theme_icon(SNAME("Search"), SNAME("EditorIcons"))); + search_box->add_theme_icon_override(SNAME("right_icon"), results_tree->get_theme_icon(SNAME("Search"), SNAME("EditorIcons"))); case_sensitive_button->set_icon(results_tree->get_theme_icon(SNAME("MatchCase"), SNAME("EditorIcons"))); hierarchy_button->set_icon(results_tree->get_theme_icon(SNAME("ClassList"), SNAME("EditorIcons"))); diff --git a/editor/editor_inspector.cpp b/editor/editor_inspector.cpp index 29d1752578..d898c84a02 100644 --- a/editor/editor_inspector.cpp +++ b/editor/editor_inspector.cpp @@ -1890,10 +1890,10 @@ void EditorInspectorArray::_setup() { ae.margin->set_mouse_filter(MOUSE_FILTER_PASS); if (is_inside_tree()) { Size2 min_size = get_theme_stylebox(SNAME("Focus"), SNAME("EditorStyles"))->get_minimum_size(); - ae.margin->add_theme_constant_override("margin_left", min_size.x / 2); - ae.margin->add_theme_constant_override("margin_top", min_size.y / 2); - ae.margin->add_theme_constant_override("margin_right", min_size.x / 2); - ae.margin->add_theme_constant_override("margin_bottom", min_size.y / 2); + ae.margin->add_theme_constant_override(SNAME("margin_left"), min_size.x / 2); + ae.margin->add_theme_constant_override(SNAME("margin_top"), min_size.y / 2); + ae.margin->add_theme_constant_override(SNAME("margin_right"), min_size.x / 2); + ae.margin->add_theme_constant_override(SNAME("margin_bottom"), min_size.y / 2); } ae.panel->add_child(ae.margin); @@ -1989,10 +1989,10 @@ void EditorInspectorArray::_notification(int p_what) { ae.move_texture_rect->set_texture(get_theme_icon(SNAME("TripleBar"), SNAME("EditorIcons"))); Size2 min_size = get_theme_stylebox(SNAME("Focus"), SNAME("EditorStyles"))->get_minimum_size(); - ae.margin->add_theme_constant_override("margin_left", min_size.x / 2); - ae.margin->add_theme_constant_override("margin_top", min_size.y / 2); - ae.margin->add_theme_constant_override("margin_right", min_size.x / 2); - ae.margin->add_theme_constant_override("margin_bottom", min_size.y / 2); + ae.margin->add_theme_constant_override(SNAME("margin_left"), min_size.x / 2); + ae.margin->add_theme_constant_override(SNAME("margin_top"), min_size.y / 2); + ae.margin->add_theme_constant_override(SNAME("margin_right"), min_size.x / 2); + ae.margin->add_theme_constant_override(SNAME("margin_bottom"), min_size.y / 2); } add_button->set_icon(get_theme_icon(SNAME("Add"), SNAME("EditorIcons"))); @@ -2083,7 +2083,7 @@ EditorInspectorArray::EditorInspectorArray() { add_child(rmb_popup); elements_vbox = memnew(VBoxContainer); - elements_vbox->add_theme_constant_override("separation", 0); + elements_vbox->add_theme_constant_override(SNAME("separation"), 0); vbox->add_child(elements_vbox); add_button = memnew(Button); @@ -2109,7 +2109,7 @@ EditorInspectorArray::EditorInspectorArray() { page_line_edit = memnew(LineEdit); page_line_edit->connect("text_submitted", callable_mp(this, &EditorInspectorArray::_page_line_edit_text_submitted)); - page_line_edit->add_theme_constant_override("minimum_character_width", 2); + page_line_edit->add_theme_constant_override(SNAME("minimum_character_width"), 2); hbox_pagination->add_child(page_line_edit); page_count_label = memnew(Label); @@ -3020,9 +3020,9 @@ void EditorInspector::_update_inspector_bg() { n = n->get_parent(); } count_subinspectors = MIN(15, count_subinspectors); - add_theme_style_override("bg", get_theme_stylebox("sub_inspector_bg" + itos(count_subinspectors), "Editor")); + add_theme_style_override(SNAME("bg"), get_theme_stylebox("sub_inspector_bg" + itos(count_subinspectors), SNAME("Editor"))); } else { - add_theme_style_override("bg", get_theme_stylebox(SNAME("bg"), SNAME("Tree"))); + add_theme_style_override(SNAME("bg"), get_theme_stylebox(SNAME("bg"), SNAME("Tree"))); } } void EditorInspector::set_sub_inspector(bool p_enable) { @@ -3551,7 +3551,7 @@ EditorInspector::EditorInspector() { undo_redo = nullptr; main_vbox = memnew(VBoxContainer); main_vbox->set_h_size_flags(SIZE_EXPAND_FILL); - main_vbox->add_theme_constant_override("separation", 0); + main_vbox->add_theme_constant_override(SNAME("separation"), 0); add_child(main_vbox); set_horizontal_scroll_mode(SCROLL_MODE_DISABLED); diff --git a/editor/editor_log.cpp b/editor/editor_log.cpp index db4de3bed0..e6aa38e7c4 100644 --- a/editor/editor_log.cpp +++ b/editor/editor_log.cpp @@ -64,15 +64,15 @@ void EditorLog::_error_handler(void *p_self, const char *p_func, const char *p_f void EditorLog::_update_theme() { Ref<Font> normal_font = get_theme_font(SNAME("output_source"), SNAME("EditorFonts")); if (normal_font.is_valid()) { - log->add_theme_font_override("normal_font", normal_font); + log->add_theme_font_override(SNAME("normal_font"), normal_font); } - log->add_theme_font_size_override("normal_font_size", get_theme_font_size(SNAME("output_source_size"), SNAME("EditorFonts"))); - log->add_theme_color_override("selection_color", get_theme_color(SNAME("accent_color"), SNAME("Editor")) * Color(1, 1, 1, 0.4)); + log->add_theme_font_size_override(SNAME("normal_font_size"), get_theme_font_size(SNAME("output_source_size"), SNAME("EditorFonts"))); + log->add_theme_color_override(SNAME("selection_color"), get_theme_color(SNAME("accent_color"), SNAME("Editor")) * Color(1, 1, 1, 0.4)); Ref<Font> bold_font = get_theme_font(SNAME("bold"), SNAME("EditorFonts")); if (bold_font.is_valid()) { - log->add_theme_font_override("bold_font", bold_font); + log->add_theme_font_override(SNAME("bold_font"), bold_font); } type_filter_map[MSG_TYPE_STD]->toggle_button->set_icon(get_theme_icon(SNAME("Popup"), SNAME("EditorIcons"))); diff --git a/editor/editor_log.h b/editor/editor_log.h index 69a6a0b449..abfc78fdcd 100644 --- a/editor/editor_log.h +++ b/editor/editor_log.h @@ -85,7 +85,7 @@ private: toggle_button->set_text(itos(message_count)); toggle_button->set_tooltip(TTR(p_tooltip)); // Don't tint the icon even when in "pressed" state. - toggle_button->add_theme_color_override("icon_color_pressed", Color(1, 1, 1, 1)); + toggle_button->add_theme_color_override(SNAME("icon_color_pressed"), Color(1, 1, 1, 1)); toggle_button->set_focus_mode(FOCUS_NONE); // When toggled call the callback and pass the MessageType this button is for. toggle_button->connect("toggled", p_toggled_callback, varray(type)); diff --git a/editor/editor_node.cpp b/editor/editor_node.cpp index bf7e463559..b98b7fd3dc 100644 --- a/editor/editor_node.cpp +++ b/editor/editor_node.cpp @@ -692,17 +692,17 @@ void EditorNode::_notification(int p_what) { theme_base->set_theme(theme); gui_base->set_theme(theme); - gui_base->add_theme_style_override("panel", gui_base->get_theme_stylebox(SNAME("Background"), SNAME("EditorStyles"))); - scene_root_parent->add_theme_style_override("panel", gui_base->get_theme_stylebox(SNAME("Content"), SNAME("EditorStyles"))); - bottom_panel->add_theme_style_override("panel", gui_base->get_theme_stylebox(SNAME("panel"), SNAME("TabContainer"))); - scene_tabs->add_theme_style_override("tab_selected", gui_base->get_theme_stylebox(SNAME("SceneTabFG"), SNAME("EditorStyles"))); - scene_tabs->add_theme_style_override("tab_unselected", gui_base->get_theme_stylebox(SNAME("SceneTabBG"), SNAME("EditorStyles"))); - - file_menu->add_theme_style_override("hover", gui_base->get_theme_stylebox(SNAME("MenuHover"), SNAME("EditorStyles"))); - project_menu->add_theme_style_override("hover", gui_base->get_theme_stylebox(SNAME("MenuHover"), SNAME("EditorStyles"))); - debug_menu->add_theme_style_override("hover", gui_base->get_theme_stylebox(SNAME("MenuHover"), SNAME("EditorStyles"))); - settings_menu->add_theme_style_override("hover", gui_base->get_theme_stylebox(SNAME("MenuHover"), SNAME("EditorStyles"))); - help_menu->add_theme_style_override("hover", gui_base->get_theme_stylebox(SNAME("MenuHover"), SNAME("EditorStyles"))); + gui_base->add_theme_style_override(SNAME("panel"), gui_base->get_theme_stylebox(SNAME("Background"), SNAME("EditorStyles"))); + scene_root_parent->add_theme_style_override(SNAME("panel"), gui_base->get_theme_stylebox(SNAME("Content"), SNAME("EditorStyles"))); + bottom_panel->add_theme_style_override(SNAME("panel"), gui_base->get_theme_stylebox(SNAME("panel"), SNAME("TabContainer"))); + scene_tabs->add_theme_style_override(SNAME("tab_selected"), gui_base->get_theme_stylebox(SNAME("SceneTabFG"), SNAME("EditorStyles"))); + scene_tabs->add_theme_style_override(SNAME("tab_unselected"), gui_base->get_theme_stylebox(SNAME("SceneTabBG"), SNAME("EditorStyles"))); + + file_menu->add_theme_style_override(SNAME("hover"), gui_base->get_theme_stylebox(SNAME("MenuHover"), SNAME("EditorStyles"))); + project_menu->add_theme_style_override(SNAME("hover"), gui_base->get_theme_stylebox(SNAME("MenuHover"), SNAME("EditorStyles"))); + debug_menu->add_theme_style_override(SNAME("hover"), gui_base->get_theme_stylebox(SNAME("MenuHover"), SNAME("EditorStyles"))); + settings_menu->add_theme_style_override(SNAME("hover"), gui_base->get_theme_stylebox(SNAME("MenuHover"), SNAME("EditorStyles"))); + help_menu->add_theme_style_override(SNAME("hover"), gui_base->get_theme_stylebox(SNAME("MenuHover"), SNAME("EditorStyles"))); if (EDITOR_GET("interface/scene_tabs/resize_if_many_tabs")) { scene_tabs->set_min_width(int(EDITOR_GET("interface/scene_tabs/minimum_width")) * EDSCALE); @@ -715,7 +715,7 @@ void EditorNode::_notification(int p_what) { // debugger area if (EditorDebuggerNode::get_singleton()->is_visible()) { - bottom_panel->add_theme_style_override("panel", gui_base->get_theme_stylebox(SNAME("BottomPanelDebuggerOverride"), SNAME("EditorStyles"))); + bottom_panel->add_theme_style_override(SNAME("panel"), gui_base->get_theme_stylebox(SNAME("BottomPanelDebuggerOverride"), SNAME("EditorStyles"))); } // update_icons @@ -766,8 +766,8 @@ void EditorNode::_notification(int p_what) { p->set_item_icon(p->get_item_index(HELP_SUPPORT_GODOT_DEVELOPMENT), gui_base->get_theme_icon(SNAME("Heart"), SNAME("EditorIcons"))); for (int i = 0; i < main_editor_buttons.size(); i++) { - main_editor_buttons.write[i]->add_theme_font_override("font", gui_base->get_theme_font(SNAME("main_button_font"), SNAME("EditorFonts"))); - main_editor_buttons.write[i]->add_theme_font_size_override("font_size", gui_base->get_theme_font_size(SNAME("main_button_font_size"), SNAME("EditorFonts"))); + main_editor_buttons.write[i]->add_theme_font_override(SNAME("font"), gui_base->get_theme_font(SNAME("main_button_font"), SNAME("EditorFonts"))); + main_editor_buttons.write[i]->add_theme_font_size_override(SNAME("font_size"), gui_base->get_theme_font_size(SNAME("main_button_font_size"), SNAME("EditorFonts"))); } Set<String> updated_textfile_extensions; @@ -3184,8 +3184,8 @@ void EditorNode::add_editor_plugin(EditorPlugin *p_editor, bool p_config_changed tb->set_icon(singleton->gui_base->get_theme_icon(p_editor->get_name(), SNAME("EditorIcons"))); } - tb->add_theme_font_override("font", singleton->gui_base->get_theme_font(SNAME("main_button_font"), SNAME("EditorFonts"))); - tb->add_theme_font_size_override("font_size", singleton->gui_base->get_theme_font_size(SNAME("main_button_font_size"), SNAME("EditorFonts"))); + tb->add_theme_font_override(SNAME("font"), singleton->gui_base->get_theme_font(SNAME("main_button_font"), SNAME("EditorFonts"))); + tb->add_theme_font_size_override(SNAME("font_size"), singleton->gui_base->get_theme_font_size(SNAME("main_button_font_size"), SNAME("EditorFonts"))); singleton->main_editor_buttons.push_back(tb); singleton->main_editor_button_vb->add_child(tb); @@ -4251,10 +4251,10 @@ void EditorNode::_dock_make_float() { window->add_child(p); MarginContainer *margin = memnew(MarginContainer); margin->set_anchors_and_offsets_preset(Control::PRESET_WIDE); - margin->add_theme_constant_override("margin_right", borders.width); - margin->add_theme_constant_override("margin_top", borders.height); - margin->add_theme_constant_override("margin_left", borders.width); - margin->add_theme_constant_override("margin_bottom", borders.height); + margin->add_theme_constant_override(SNAME("margin_right"), borders.width); + margin->add_theme_constant_override(SNAME("margin_top"), borders.height); + margin->add_theme_constant_override(SNAME("margin_left"), borders.width); + margin->add_theme_constant_override(SNAME("margin_bottom"), borders.height); window->add_child(margin); dock->set_anchors_and_offsets_preset(Control::PRESET_WIDE); margin->add_child(dock); @@ -5199,9 +5199,9 @@ void EditorNode::_bottom_panel_switch(bool p_enable, int p_idx) { bottom_panel_items[i].control->set_visible(i == p_idx); } if (EditorDebuggerNode::get_singleton() == bottom_panel_items[p_idx].control) { // this is the debug panel which uses tabs, so the top section should be smaller - bottom_panel->add_theme_style_override("panel", gui_base->get_theme_stylebox(SNAME("BottomPanelDebuggerOverride"), SNAME("EditorStyles"))); + bottom_panel->add_theme_style_override(SNAME("panel"), gui_base->get_theme_stylebox(SNAME("BottomPanelDebuggerOverride"), SNAME("EditorStyles"))); } else { - bottom_panel->add_theme_style_override("panel", gui_base->get_theme_stylebox(SNAME("panel"), SNAME("TabContainer"))); + bottom_panel->add_theme_style_override(SNAME("panel"), gui_base->get_theme_stylebox(SNAME("panel"), SNAME("TabContainer"))); } center_split->set_dragger_visibility(SplitContainer::DRAGGER_VISIBLE); center_split->set_collapsed(false); @@ -5211,7 +5211,7 @@ void EditorNode::_bottom_panel_switch(bool p_enable, int p_idx) { bottom_panel_raise->show(); } else { - bottom_panel->add_theme_style_override("panel", gui_base->get_theme_stylebox(SNAME("panel"), SNAME("TabContainer"))); + bottom_panel->add_theme_style_override(SNAME("panel"), gui_base->get_theme_stylebox(SNAME("panel"), SNAME("TabContainer"))); bottom_panel_items[p_idx].button->set_pressed(false); bottom_panel_items[p_idx].control->set_visible(false); center_split->set_dragger_visibility(SplitContainer::DRAGGER_HIDDEN); @@ -5602,9 +5602,9 @@ void EditorNode::_bottom_panel_raise_toggled(bool p_pressed) { void EditorNode::_update_rendering_driver_color() { if (rendering_driver->get_text() == "opengl3") { - rendering_driver->add_theme_color_override("font_color", Color::hex(0x5586a4ff)); + rendering_driver->add_theme_color_override(SNAME("font_color"), Color::hex(0x5586a4ff)); } else if (rendering_driver->get_text() == "vulkan") { - rendering_driver->add_theme_color_override("font_color", theme_base->get_theme_color(SNAME("vulkan_color"), SNAME("Editor"))); + rendering_driver->add_theme_color_override(SNAME("font_color"), theme_base->get_theme_color(SNAME("vulkan_color"), SNAME("Editor"))); } } @@ -6053,7 +6053,7 @@ EditorNode::EditorNode() { theme_base->set_theme(theme); gui_base->set_theme(theme); - gui_base->add_theme_style_override("panel", gui_base->get_theme_stylebox(SNAME("Background"), SNAME("EditorStyles"))); + gui_base->add_theme_style_override(SNAME("panel"), gui_base->get_theme_stylebox(SNAME("Background"), SNAME("EditorStyles"))); resource_preview = memnew(EditorResourcePreview); add_child(resource_preview); @@ -6068,7 +6068,7 @@ EditorNode::EditorNode() { main_vbox = memnew(VBoxContainer); gui_base->add_child(main_vbox); main_vbox->set_anchors_and_offsets_preset(Control::PRESET_WIDE, Control::PRESET_MODE_MINSIZE, 8); - main_vbox->add_theme_constant_override("separation", 8 * EDSCALE); + main_vbox->add_theme_constant_override(SNAME("separation"), 8 * EDSCALE); menu_hb = memnew(HBoxContainer); main_vbox->add_child(menu_hb); @@ -6219,7 +6219,7 @@ EditorNode::EditorNode() { VBoxContainer *srt = memnew(VBoxContainer); srt->set_v_size_flags(Control::SIZE_EXPAND_FILL); top_split->add_child(srt); - srt->add_theme_constant_override("separation", 0); + srt->add_theme_constant_override(SNAME("separation"), 0); tab_preview_panel = memnew(Panel); tab_preview_panel->set_size(Size2(100, 100) * EDSCALE); @@ -6237,8 +6237,8 @@ EditorNode::EditorNode() { srt->add_child(tabbar_container); scene_tabs = memnew(TabBar); - scene_tabs->add_theme_style_override("tab_selected", gui_base->get_theme_stylebox(SNAME("SceneTabFG"), SNAME("EditorStyles"))); - scene_tabs->add_theme_style_override("tab_unselected", gui_base->get_theme_stylebox(SNAME("SceneTabBG"), SNAME("EditorStyles"))); + scene_tabs->add_theme_style_override(SNAME("tab_selected"), gui_base->get_theme_stylebox(SNAME("SceneTabFG"), SNAME("EditorStyles"))); + scene_tabs->add_theme_style_override(SNAME("tab_unselected"), gui_base->get_theme_stylebox(SNAME("SceneTabBG"), SNAME("EditorStyles"))); scene_tabs->set_select_with_rmb(true); scene_tabs->add_tab("unsaved"); scene_tabs->set_tab_alignment(TabBar::ALIGNMENT_LEFT); @@ -6264,7 +6264,7 @@ EditorNode::EditorNode() { scene_tab_add->set_flat(true); scene_tab_add->set_tooltip(TTR("Add a new scene.")); scene_tab_add->set_icon(gui_base->get_theme_icon(SNAME("Add"), SNAME("EditorIcons"))); - scene_tab_add->add_theme_color_override("icon_normal_color", Color(0.6f, 0.6f, 0.6f, 0.8f)); + scene_tab_add->add_theme_color_override(SNAME("icon_normal_color"), Color(0.6f, 0.6f, 0.6f, 0.8f)); scene_tabs->add_child(scene_tab_add); scene_tab_add->connect("pressed", callable_mp(this, &EditorNode::_menu_option), make_binds(FILE_NEW_SCENE)); @@ -6286,7 +6286,7 @@ EditorNode::EditorNode() { scene_root_parent = memnew(PanelContainer); scene_root_parent->set_custom_minimum_size(Size2(0, 80) * EDSCALE); - scene_root_parent->add_theme_style_override("panel", gui_base->get_theme_stylebox(SNAME("Content"), SNAME("EditorStyles"))); + scene_root_parent->add_theme_style_override(SNAME("panel"), gui_base->get_theme_stylebox(SNAME("Content"), SNAME("EditorStyles"))); scene_root_parent->set_draw_behind_parent(true); srt->add_child(scene_root_parent); scene_root_parent->set_v_size_flags(Control::SIZE_EXPAND_FILL); @@ -6300,7 +6300,7 @@ EditorNode::EditorNode() { main_control = memnew(VBoxContainer); main_control->set_v_size_flags(Control::SIZE_EXPAND_FILL); - main_control->add_theme_constant_override("separation", 0); + main_control->add_theme_constant_override(SNAME("separation"), 0); scene_root_parent->add_child(main_control); HBoxContainer *left_menu_hb = memnew(HBoxContainer); @@ -6310,7 +6310,7 @@ EditorNode::EditorNode() { file_menu->set_flat(false); file_menu->set_switch_on_hover(true); file_menu->set_text(TTR("Scene")); - file_menu->add_theme_style_override("hover", gui_base->get_theme_stylebox(SNAME("MenuHover"), SNAME("EditorStyles"))); + file_menu->add_theme_style_override(SNAME("hover"), gui_base->get_theme_stylebox(SNAME("MenuHover"), SNAME("EditorStyles"))); left_menu_hb->add_child(file_menu); prev_scene = memnew(Button); @@ -6426,7 +6426,7 @@ EditorNode::EditorNode() { project_menu->set_switch_on_hover(true); project_menu->set_tooltip(TTR("Miscellaneous project or scene-wide tools.")); project_menu->set_text(TTR("Project")); - project_menu->add_theme_style_override("hover", gui_base->get_theme_stylebox(SNAME("MenuHover"), SNAME("EditorStyles"))); + project_menu->add_theme_style_override(SNAME("hover"), gui_base->get_theme_stylebox(SNAME("MenuHover"), SNAME("EditorStyles"))); left_menu_hb->add_child(project_menu); p = project_menu->get_popup(); @@ -6476,7 +6476,7 @@ EditorNode::EditorNode() { debug_menu->set_flat(false); debug_menu->set_switch_on_hover(true); debug_menu->set_text(TTR("Debug")); - debug_menu->add_theme_style_override("hover", gui_base->get_theme_stylebox(SNAME("MenuHover"), SNAME("EditorStyles"))); + debug_menu->add_theme_style_override(SNAME("hover"), gui_base->get_theme_stylebox(SNAME("MenuHover"), SNAME("EditorStyles"))); left_menu_hb->add_child(debug_menu); menu_hb->add_spacer(); @@ -6485,7 +6485,7 @@ EditorNode::EditorNode() { settings_menu->set_flat(false); settings_menu->set_switch_on_hover(true); settings_menu->set_text(TTR("Editor")); - settings_menu->add_theme_style_override("hover", gui_base->get_theme_stylebox(SNAME("MenuHover"), SNAME("EditorStyles"))); + settings_menu->add_theme_style_override(SNAME("hover"), gui_base->get_theme_stylebox(SNAME("MenuHover"), SNAME("EditorStyles"))); left_menu_hb->add_child(settings_menu); p = settings_menu->get_popup(); @@ -6533,7 +6533,7 @@ EditorNode::EditorNode() { help_menu->set_flat(false); help_menu->set_switch_on_hover(true); help_menu->set_text(TTR("Help")); - help_menu->add_theme_style_override("hover", gui_base->get_theme_stylebox(SNAME("MenuHover"), SNAME("EditorStyles"))); + help_menu->add_theme_style_override(SNAME("hover"), gui_base->get_theme_stylebox(SNAME("MenuHover"), SNAME("EditorStyles"))); left_menu_hb->add_child(help_menu); p = help_menu->get_popup(); @@ -6637,8 +6637,8 @@ EditorNode::EditorNode() { rendering_driver->set_flat(true); rendering_driver->set_focus_mode(Control::FOCUS_NONE); rendering_driver->connect("item_selected", callable_mp(this, &EditorNode::_rendering_driver_selected)); - rendering_driver->add_theme_font_override("font", gui_base->get_theme_font(SNAME("bold"), SNAME("EditorFonts"))); - rendering_driver->add_theme_font_size_override("font_size", gui_base->get_theme_font_size(SNAME("bold_size"), SNAME("EditorFonts"))); + rendering_driver->add_theme_font_override(SNAME("font"), gui_base->get_theme_font(SNAME("bold"), SNAME("EditorFonts"))); + rendering_driver->add_theme_font_size_override(SNAME("font_size"), gui_base->get_theme_font_size(SNAME("bold_size"), SNAME("EditorFonts"))); right_menu_hb->add_child(rendering_driver); @@ -6761,7 +6761,7 @@ EditorNode::EditorNode() { // Bottom panels bottom_panel = memnew(PanelContainer); - bottom_panel->add_theme_style_override("panel", gui_base->get_theme_stylebox(SNAME("panel"), SNAME("TabContainer"))); + bottom_panel->add_theme_style_override(SNAME("panel"), gui_base->get_theme_stylebox(SNAME("panel"), SNAME("TabContainer"))); center_split->add_child(bottom_panel); center_split->set_dragger_visibility(SplitContainer::DRAGGER_HIDDEN); @@ -6969,6 +6969,7 @@ EditorNode::EditorNode() { // more visually meaningful to have this later raise_bottom_panel_item(AnimationPlayerEditor::get_singleton()); + add_editor_plugin(memnew(ReplicationEditorPlugin(this))); add_editor_plugin(VersionControlEditorPlugin::get_singleton()); add_editor_plugin(memnew(ShaderEditorPlugin(this))); @@ -7022,7 +7023,6 @@ EditorNode::EditorNode() { add_editor_plugin(memnew(InputEventEditorPlugin(this))); add_editor_plugin(memnew(SubViewportPreviewEditorPlugin(this))); add_editor_plugin(memnew(TextControlEditorPlugin(this))); - add_editor_plugin(memnew(ReplicationEditorPlugin(this))); for (int i = 0; i < EditorPlugins::get_plugin_count(); i++) { add_editor_plugin(EditorPlugins::create(i, this)); diff --git a/editor/editor_path.cpp b/editor/editor_path.cpp index 3dee06fb3e..e9ffb08cec 100644 --- a/editor/editor_path.cpp +++ b/editor/editor_path.cpp @@ -181,7 +181,7 @@ void EditorPath::_notification(int p_what) { update_path(); sub_objects_icon->set_texture(get_theme_icon(SNAME("select_arrow"), SNAME("Tree"))); - current_object_label->add_theme_font_override("font", get_theme_font(SNAME("main"), SNAME("EditorFonts"))); + current_object_label->add_theme_font_override(SNAME("font"), get_theme_font(SNAME("main"), SNAME("EditorFonts"))); } break; case NOTIFICATION_READY: { @@ -198,8 +198,8 @@ EditorPath::EditorPath(EditorHistory *p_history) { MarginContainer *main_mc = memnew(MarginContainer); main_mc->set_anchors_and_offsets_preset(PRESET_WIDE); - main_mc->add_theme_constant_override("margin_left", 4 * EDSCALE); - main_mc->add_theme_constant_override("margin_right", 6 * EDSCALE); + main_mc->add_theme_constant_override(SNAME("margin_left"), 4 * EDSCALE); + main_mc->add_theme_constant_override(SNAME("margin_right"), 6 * EDSCALE); add_child(main_mc); HBoxContainer *main_hb = memnew(HBoxContainer); diff --git a/editor/editor_plugin.cpp b/editor/editor_plugin.cpp index a1c031aa1b..fe44486d0d 100644 --- a/editor/editor_plugin.cpp +++ b/editor/editor_plugin.cpp @@ -717,9 +717,9 @@ void EditorPlugin::remove_translation_parser_plugin(const Ref<EditorTranslationP EditorTranslationParser::get_singleton()->remove_parser(p_parser, EditorTranslationParser::CUSTOM); } -void EditorPlugin::add_import_plugin(const Ref<EditorImportPlugin> &p_importer) { +void EditorPlugin::add_import_plugin(const Ref<EditorImportPlugin> &p_importer, bool p_first_priority) { ERR_FAIL_COND(!p_importer.is_valid()); - ResourceFormatImporter::get_singleton()->add_importer(p_importer); + ResourceFormatImporter::get_singleton()->add_importer(p_importer, p_first_priority); EditorFileSystem::get_singleton()->call_deferred(SNAME("scan")); } @@ -759,9 +759,9 @@ void EditorPlugin::remove_inspector_plugin(const Ref<EditorInspectorPlugin> &p_p EditorInspector::remove_inspector_plugin(p_plugin); } -void EditorPlugin::add_scene_format_importer_plugin(const Ref<EditorSceneFormatImporter> &p_importer) { +void EditorPlugin::add_scene_format_importer_plugin(const Ref<EditorSceneFormatImporter> &p_importer, bool p_first_priority) { ERR_FAIL_COND(!p_importer.is_valid()); - ResourceImporterScene::get_singleton()->add_importer(p_importer); + ResourceImporterScene::get_singleton()->add_importer(p_importer, p_first_priority); } void EditorPlugin::remove_scene_format_importer_plugin(const Ref<EditorSceneFormatImporter> &p_importer) { @@ -769,9 +769,10 @@ void EditorPlugin::remove_scene_format_importer_plugin(const Ref<EditorSceneForm ResourceImporterScene::get_singleton()->remove_importer(p_importer); } -void EditorPlugin::add_scene_post_import_plugin(const Ref<EditorScenePostImportPlugin> &p_plugin) { - ResourceImporterScene::get_singleton()->add_post_importer_plugin(p_plugin); +void EditorPlugin::add_scene_post_import_plugin(const Ref<EditorScenePostImportPlugin> &p_plugin, bool p_first_priority) { + ResourceImporterScene::get_singleton()->add_post_importer_plugin(p_plugin, p_first_priority); } + void EditorPlugin::remove_scene_post_import_plugin(const Ref<EditorScenePostImportPlugin> &p_plugin) { ResourceImporterScene::get_singleton()->remove_post_importer_plugin(p_plugin); } @@ -881,11 +882,11 @@ void EditorPlugin::_bind_methods() { ClassDB::bind_method(D_METHOD("queue_save_layout"), &EditorPlugin::queue_save_layout); ClassDB::bind_method(D_METHOD("add_translation_parser_plugin", "parser"), &EditorPlugin::add_translation_parser_plugin); ClassDB::bind_method(D_METHOD("remove_translation_parser_plugin", "parser"), &EditorPlugin::remove_translation_parser_plugin); - ClassDB::bind_method(D_METHOD("add_import_plugin", "importer"), &EditorPlugin::add_import_plugin); + ClassDB::bind_method(D_METHOD("add_import_plugin", "importer", "first_priority"), &EditorPlugin::add_import_plugin, DEFVAL(false)); ClassDB::bind_method(D_METHOD("remove_import_plugin", "importer"), &EditorPlugin::remove_import_plugin); - ClassDB::bind_method(D_METHOD("add_scene_format_importer_plugin", "scene_format_importer"), &EditorPlugin::add_scene_format_importer_plugin); + ClassDB::bind_method(D_METHOD("add_scene_format_importer_plugin", "scene_format_importer", "first_priority"), &EditorPlugin::add_scene_format_importer_plugin, DEFVAL(false)); ClassDB::bind_method(D_METHOD("remove_scene_format_importer_plugin", "scene_format_importer"), &EditorPlugin::remove_scene_format_importer_plugin); - ClassDB::bind_method(D_METHOD("add_scene_post_import_plugin", "scene_import_plugin"), &EditorPlugin::add_scene_post_import_plugin); + ClassDB::bind_method(D_METHOD("add_scene_post_import_plugin", "scene_import_plugin", "first_priority"), &EditorPlugin::add_scene_post_import_plugin, DEFVAL(false)); ClassDB::bind_method(D_METHOD("remove_scene_post_import_plugin", "scene_import_plugin"), &EditorPlugin::remove_scene_post_import_plugin); ClassDB::bind_method(D_METHOD("add_export_plugin", "plugin"), &EditorPlugin::add_export_plugin); ClassDB::bind_method(D_METHOD("remove_export_plugin", "plugin"), &EditorPlugin::remove_export_plugin); diff --git a/editor/editor_plugin.h b/editor/editor_plugin.h index 06517190f6..f23c5f40f6 100644 --- a/editor/editor_plugin.h +++ b/editor/editor_plugin.h @@ -278,7 +278,7 @@ public: void add_translation_parser_plugin(const Ref<EditorTranslationParserPlugin> &p_parser); void remove_translation_parser_plugin(const Ref<EditorTranslationParserPlugin> &p_parser); - void add_import_plugin(const Ref<EditorImportPlugin> &p_importer); + void add_import_plugin(const Ref<EditorImportPlugin> &p_importer, bool p_first_priority = false); void remove_import_plugin(const Ref<EditorImportPlugin> &p_importer); void add_export_plugin(const Ref<EditorExportPlugin> &p_exporter); @@ -290,10 +290,10 @@ public: void add_inspector_plugin(const Ref<EditorInspectorPlugin> &p_plugin); void remove_inspector_plugin(const Ref<EditorInspectorPlugin> &p_plugin); - void add_scene_format_importer_plugin(const Ref<EditorSceneFormatImporter> &p_importer); + void add_scene_format_importer_plugin(const Ref<EditorSceneFormatImporter> &p_importer, bool p_first_priority = false); void remove_scene_format_importer_plugin(const Ref<EditorSceneFormatImporter> &p_importer); - void add_scene_post_import_plugin(const Ref<EditorScenePostImportPlugin> &p_importer); + void add_scene_post_import_plugin(const Ref<EditorScenePostImportPlugin> &p_importer, bool p_first_priority = false); void remove_scene_post_import_plugin(const Ref<EditorScenePostImportPlugin> &p_importer); void add_autoload_singleton(const String &p_name, const String &p_path); diff --git a/editor/editor_properties.cpp b/editor/editor_properties.cpp index ef1ceebabf..80da8363ad 100644 --- a/editor/editor_properties.cpp +++ b/editor/editor_properties.cpp @@ -3087,18 +3087,18 @@ void EditorPropertyResource::_update_property_bg() { } count_subinspectors = MIN(15, count_subinspectors); - add_theme_color_override("property_color", get_theme_color(SNAME("sub_inspector_property_color"), SNAME("Editor"))); - add_theme_style_override("bg_selected", get_theme_stylebox("sub_inspector_property_bg_selected" + itos(count_subinspectors), SNAME("Editor"))); - add_theme_style_override("bg", get_theme_stylebox("sub_inspector_property_bg" + itos(count_subinspectors), SNAME("Editor"))); + add_theme_color_override(SNAME("property_color"), get_theme_color(SNAME("sub_inspector_property_color"), SNAME("Editor"))); + add_theme_style_override(SNAME("bg_selected"), get_theme_stylebox("sub_inspector_property_bg_selected" + itos(count_subinspectors), SNAME("Editor"))); + add_theme_style_override(SNAME("bg"), get_theme_stylebox("sub_inspector_property_bg" + itos(count_subinspectors), SNAME("Editor"))); - add_theme_constant_override("font_offset", get_theme_constant(SNAME("sub_inspector_font_offset"), SNAME("Editor"))); - add_theme_constant_override("vseparation", 0); + add_theme_constant_override(SNAME("font_offset"), get_theme_constant(SNAME("sub_inspector_font_offset"), SNAME("Editor"))); + add_theme_constant_override(SNAME("vseparation"), 0); } else { - add_theme_color_override("property_color", get_theme_color(SNAME("property_color"), SNAME("EditorProperty"))); - add_theme_style_override("bg_selected", get_theme_stylebox(SNAME("bg_selected"), SNAME("EditorProperty"))); - add_theme_style_override("bg", get_theme_stylebox(SNAME("bg"), SNAME("EditorProperty"))); - add_theme_constant_override("vseparation", get_theme_constant(SNAME("vseparation"), SNAME("EditorProperty"))); - add_theme_constant_override("font_offset", get_theme_constant(SNAME("font_offset"), SNAME("EditorProperty"))); + add_theme_color_override(SNAME("property_color"), get_theme_color(SNAME("property_color"), SNAME("EditorProperty"))); + add_theme_style_override(SNAME("bg_selected"), get_theme_stylebox(SNAME("bg_selected"), SNAME("EditorProperty"))); + add_theme_style_override(SNAME("bg"), get_theme_stylebox(SNAME("bg"), SNAME("EditorProperty"))); + add_theme_constant_override(SNAME("vseparation"), get_theme_constant(SNAME("vseparation"), SNAME("EditorProperty"))); + add_theme_constant_override(SNAME("font_offset"), get_theme_constant(SNAME("font_offset"), SNAME("EditorProperty"))); } updating_theme = false; diff --git a/editor/editor_properties_array_dict.cpp b/editor/editor_properties_array_dict.cpp index cfed86d1ae..a96b7d3730 100644 --- a/editor/editor_properties_array_dict.cpp +++ b/editor/editor_properties_array_dict.cpp @@ -1082,7 +1082,7 @@ void EditorPropertyDictionary::update_property() { } flat->set_bg_color(get_theme_color(SNAME("prop_subsection"), SNAME("Editor"))); - pc->add_theme_style_override("panel", flat); + pc->add_theme_style_override(SNAME("panel"), flat); add_vbox = memnew(VBoxContainer); pc->add_child(add_vbox); } diff --git a/editor/editor_sectioned_inspector.cpp b/editor/editor_sectioned_inspector.cpp index 1bab56ac4a..012f10a1bd 100644 --- a/editor/editor_sectioned_inspector.cpp +++ b/editor/editor_sectioned_inspector.cpp @@ -302,7 +302,7 @@ SectionedInspector::SectionedInspector() : sections(memnew(Tree)), filter(memnew(SectionedInspectorFilter)), inspector(memnew(EditorInspector)) { - add_theme_constant_override("autohide", 1); // Fixes the dragger always showing up + add_theme_constant_override(SNAME("autohide"), 1); // Fixes the dragger always showing up VBoxContainer *left_vb = memnew(VBoxContainer); left_vb->set_custom_minimum_size(Size2(190, 0) * EDSCALE); diff --git a/editor/editor_settings_dialog.cpp b/editor/editor_settings_dialog.cpp index 1cb95226ec..22425ae37d 100644 --- a/editor/editor_settings_dialog.cpp +++ b/editor/editor_settings_dialog.cpp @@ -182,9 +182,9 @@ void EditorSettingsDialog::_update_icons() { shortcut_search_box->set_clear_button_enabled(true); restart_close_button->set_icon(shortcuts->get_theme_icon(SNAME("Close"), SNAME("EditorIcons"))); - restart_container->add_theme_style_override("panel", shortcuts->get_theme_stylebox(SNAME("bg"), SNAME("Tree"))); + restart_container->add_theme_style_override(SNAME("panel"), shortcuts->get_theme_stylebox(SNAME("bg"), SNAME("Tree"))); restart_icon->set_texture(shortcuts->get_theme_icon(SNAME("StatusWarning"), SNAME("EditorIcons"))); - restart_label->add_theme_color_override("font_color", shortcuts->get_theme_color(SNAME("warning_color"), SNAME("Editor"))); + restart_label->add_theme_color_override(SNAME("font_color"), shortcuts->get_theme_color(SNAME("warning_color"), SNAME("Editor"))); } void EditorSettingsDialog::_event_config_confirmed() { @@ -272,15 +272,15 @@ void EditorSettingsDialog::_create_shortcut_treeitem(TreeItem *p_parent, const S shortcut_item->set_text(1, sc_text); if (sc_text == "None") { // Fade out unassigned shortcut labels for easier visual grepping. - shortcut_item->set_custom_color(1, shortcuts->get_theme_color("font_color", "Label") * Color(1, 1, 1, 0.5)); + shortcut_item->set_custom_color(1, shortcuts->get_theme_color(SNAME("font_color"), SNAME("Label")) * Color(1, 1, 1, 0.5)); } if (p_allow_revert) { - shortcut_item->add_button(1, shortcuts->get_theme_icon("Reload", "EditorIcons"), SHORTCUT_REVERT); + shortcut_item->add_button(1, shortcuts->get_theme_icon(SNAME("Reload"), SNAME("EditorIcons")), SHORTCUT_REVERT); } - shortcut_item->add_button(1, shortcuts->get_theme_icon("Add", "EditorIcons"), SHORTCUT_ADD); - shortcut_item->add_button(1, shortcuts->get_theme_icon("Close", "EditorIcons"), SHORTCUT_ERASE); + shortcut_item->add_button(1, shortcuts->get_theme_icon(SNAME("Add"), SNAME("EditorIcons")), SHORTCUT_ADD); + shortcut_item->add_button(1, shortcuts->get_theme_icon(SNAME("Close"), SNAME("EditorIcons")), SHORTCUT_ERASE); shortcut_item->set_meta("is_action", p_is_action); shortcut_item->set_meta("type", "shortcut"); @@ -299,11 +299,11 @@ void EditorSettingsDialog::_create_shortcut_treeitem(TreeItem *p_parent, const S event_item->set_text(0, shortcut_item->get_child_count() == 1 ? "Primary" : ""); event_item->set_text(1, ie->as_text()); - event_item->add_button(1, shortcuts->get_theme_icon("Edit", "EditorIcons"), SHORTCUT_EDIT); - event_item->add_button(1, shortcuts->get_theme_icon("Close", "EditorIcons"), SHORTCUT_ERASE); + event_item->add_button(1, shortcuts->get_theme_icon(SNAME("Edit"), SNAME("EditorIcons")), SHORTCUT_EDIT); + event_item->add_button(1, shortcuts->get_theme_icon(SNAME("Close"), SNAME("EditorIcons")), SHORTCUT_ERASE); - event_item->set_custom_bg_color(0, shortcuts->get_theme_color("dark_color_3", "Editor")); - event_item->set_custom_bg_color(1, shortcuts->get_theme_color("dark_color_3", "Editor")); + event_item->set_custom_bg_color(0, shortcuts->get_theme_color(SNAME("dark_color_3"), SNAME("Editor"))); + event_item->set_custom_bg_color(1, shortcuts->get_theme_color(SNAME("dark_color_3"), SNAME("Editor"))); event_item->set_meta("is_action", p_is_action); event_item->set_meta("type", "event"); diff --git a/editor/editor_spin_slider.cpp b/editor/editor_spin_slider.cpp index cd28a65c7b..881cd7a8a5 100644 --- a/editor/editor_spin_slider.cpp +++ b/editor/editor_spin_slider.cpp @@ -268,7 +268,7 @@ void EditorSpinSlider::_update_value_input_stylebox() { stylebox->set_default_margin(SIDE_RIGHT, 0); } - value_input->add_theme_style_override("normal", stylebox); + value_input->add_theme_style_override(SNAME("normal"), stylebox); } void EditorSpinSlider::_draw_spin_slider() { diff --git a/editor/editor_themes.cpp b/editor/editor_themes.cpp index 2a5fefda20..ad5012edbf 100644 --- a/editor/editor_themes.cpp +++ b/editor/editor_themes.cpp @@ -446,28 +446,28 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) { float prev_icon_saturation = theme->has_color(SNAME("icon_saturation"), SNAME("Editor")) ? theme->get_color(SNAME("icon_saturation"), SNAME("Editor")).r : 1.0; - theme->set_color("icon_saturation", "Editor", Color(icon_saturation, icon_saturation, icon_saturation)); // can't save single float in theme, so using color - theme->set_color("accent_color", "Editor", accent_color); - theme->set_color("highlight_color", "Editor", highlight_color); - theme->set_color("disabled_highlight_color", "Editor", disabled_highlight_color); - theme->set_color("base_color", "Editor", base_color); - theme->set_color("dark_color_1", "Editor", dark_color_1); - theme->set_color("dark_color_2", "Editor", dark_color_2); - theme->set_color("dark_color_3", "Editor", dark_color_3); - theme->set_color("contrast_color_1", "Editor", contrast_color_1); - theme->set_color("contrast_color_2", "Editor", contrast_color_2); - theme->set_color("box_selection_fill_color", "Editor", accent_color * Color(1, 1, 1, 0.3)); - theme->set_color("box_selection_stroke_color", "Editor", accent_color * Color(1, 1, 1, 0.8)); - - theme->set_color("axis_x_color", "Editor", Color(0.96, 0.20, 0.32)); - theme->set_color("axis_y_color", "Editor", Color(0.53, 0.84, 0.01)); - theme->set_color("axis_z_color", "Editor", Color(0.16, 0.55, 0.96)); - - theme->set_color("font_color", "Editor", font_color); - theme->set_color("highlighted_font_color", "Editor", font_hover_color); - theme->set_color("disabled_font_color", "Editor", font_disabled_color); - - theme->set_color("mono_color", "Editor", mono_color); + theme->set_color(SNAME("icon_saturation"), SNAME("Editor"), Color(icon_saturation, icon_saturation, icon_saturation)); // can't save single float in theme, so using color + theme->set_color(SNAME("accent_color"), SNAME("Editor"), accent_color); + theme->set_color(SNAME("highlight_color"), SNAME("Editor"), highlight_color); + theme->set_color(SNAME("disabled_highlight_color"), SNAME("Editor"), disabled_highlight_color); + theme->set_color(SNAME("base_color"), SNAME("Editor"), base_color); + theme->set_color(SNAME("dark_color_1"), SNAME("Editor"), dark_color_1); + theme->set_color(SNAME("dark_color_2"), SNAME("Editor"), dark_color_2); + theme->set_color(SNAME("dark_color_3"), SNAME("Editor"), dark_color_3); + theme->set_color(SNAME("contrast_color_1"), SNAME("Editor"), contrast_color_1); + theme->set_color(SNAME("contrast_color_2"), SNAME("Editor"), contrast_color_2); + theme->set_color(SNAME("box_selection_fill_color"), SNAME("Editor"), accent_color * Color(1, 1, 1, 0.3)); + theme->set_color(SNAME("box_selection_stroke_color"), SNAME("Editor"), accent_color * Color(1, 1, 1, 0.8)); + + theme->set_color(SNAME("axis_x_color"), SNAME("Editor"), Color(0.96, 0.20, 0.32)); + theme->set_color(SNAME("axis_y_color"), SNAME("Editor"), Color(0.53, 0.84, 0.01)); + theme->set_color(SNAME("axis_z_color"), SNAME("Editor"), Color(0.16, 0.55, 0.96)); + + theme->set_color(SNAME("font_color"), SNAME("Editor"), font_color); + theme->set_color(SNAME("highlighted_font_color"), SNAME("Editor"), font_hover_color); + theme->set_color(SNAME("disabled_font_color"), SNAME("Editor"), font_disabled_color); + + theme->set_color(SNAME("mono_color"), SNAME("Editor"), mono_color); Color success_color = Color(0.45, 0.95, 0.5); Color warning_color = Color(1, 0.87, 0.4); @@ -483,21 +483,21 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) { error_color = error_color.lerp(mono_color, 0.25); } - theme->set_color("success_color", "Editor", success_color); - theme->set_color("warning_color", "Editor", warning_color); - theme->set_color("error_color", "Editor", error_color); - theme->set_color("property_color", "Editor", property_color); - theme->set_color("readonly_color", "Editor", readonly_color); + theme->set_color(SNAME("success_color"), SNAME("Editor"), success_color); + theme->set_color(SNAME("warning_color"), SNAME("Editor"), warning_color); + theme->set_color(SNAME("error_color"), SNAME("Editor"), error_color); + theme->set_color(SNAME("property_color"), SNAME("Editor"), property_color); + theme->set_color(SNAME("readonly_color"), SNAME("Editor"), readonly_color); if (!dark_theme) { - theme->set_color("vulkan_color", "Editor", Color::hex(0xad1128ff)); + theme->set_color(SNAME("vulkan_color"), SNAME("Editor"), Color::hex(0xad1128ff)); } else { - theme->set_color("vulkan_color", "Editor", Color(1.0, 0.0, 0.0)); + theme->set_color(SNAME("vulkan_color"), SNAME("Editor"), Color(1.0, 0.0, 0.0)); } const int thumb_size = EDITOR_GET("filesystem/file_dialog/thumbnail_size"); - theme->set_constant("scale", "Editor", EDSCALE); - theme->set_constant("thumb_size", "Editor", thumb_size); - theme->set_constant("dark_theme", "Editor", dark_theme); + theme->set_constant(SNAME("scale"), SNAME("Editor"), EDSCALE); + theme->set_constant(SNAME("thumb_size"), SNAME("Editor"), thumb_size); + theme->set_constant(SNAME("dark_theme"), SNAME("Editor"), dark_theme); // Register icons + font @@ -632,113 +632,113 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) { // Editor background Color background_color_opaque = background_color; background_color_opaque.a = 1.0; - theme->set_stylebox("Background", "EditorStyles", make_flat_stylebox(background_color_opaque, default_margin_size, default_margin_size, default_margin_size, default_margin_size)); + theme->set_stylebox(SNAME("Background"), SNAME("EditorStyles"), make_flat_stylebox(background_color_opaque, default_margin_size, default_margin_size, default_margin_size, default_margin_size)); // Focus - theme->set_stylebox("Focus", "EditorStyles", style_widget_focus); + theme->set_stylebox(SNAME("Focus"), SNAME("EditorStyles"), style_widget_focus); // Use a less opaque color to be less distracting for the 2D and 3D editor viewports. Ref<StyleBoxFlat> style_widget_focus_viewport = style_widget_focus->duplicate(); style_widget_focus_viewport->set_border_color(accent_color * Color(1, 1, 1, 0.5)); - theme->set_stylebox("FocusViewport", "EditorStyles", style_widget_focus_viewport); + theme->set_stylebox(SNAME("FocusViewport"), SNAME("EditorStyles"), style_widget_focus_viewport); // Menu Ref<StyleBoxFlat> style_menu = style_widget->duplicate(); style_menu->set_draw_center(false); style_menu->set_border_width_all(0); - theme->set_stylebox("panel", "PanelContainer", style_menu); - theme->set_stylebox("MenuPanel", "EditorStyles", style_menu); + theme->set_stylebox(SNAME("panel"), SNAME("PanelContainer"), style_menu); + theme->set_stylebox(SNAME("MenuPanel"), SNAME("EditorStyles"), style_menu); // CanvasItem Editor Ref<StyleBoxFlat> style_canvas_editor_info = make_flat_stylebox(Color(0.0, 0.0, 0.0, 0.2)); style_canvas_editor_info->set_expand_margin_size_all(4 * EDSCALE); - theme->set_stylebox("CanvasItemInfoOverlay", "EditorStyles", style_canvas_editor_info); + theme->set_stylebox(SNAME("CanvasItemInfoOverlay"), SNAME("EditorStyles"), style_canvas_editor_info); // Script Editor - theme->set_stylebox("ScriptEditorPanel", "EditorStyles", make_empty_stylebox(default_margin_size, 0, default_margin_size, default_margin_size)); - theme->set_stylebox("ScriptEditor", "EditorStyles", make_empty_stylebox(0, 0, 0, 0)); + theme->set_stylebox(SNAME("ScriptEditorPanel"), SNAME("EditorStyles"), make_empty_stylebox(default_margin_size, 0, default_margin_size, default_margin_size)); + theme->set_stylebox(SNAME("ScriptEditor"), SNAME("EditorStyles"), make_empty_stylebox(0, 0, 0, 0)); // Play button group - theme->set_stylebox("PlayButtonPanel", "EditorStyles", style_empty); + theme->set_stylebox(SNAME("PlayButtonPanel"), SNAME("EditorStyles"), style_empty); - theme->set_stylebox("normal", "MenuButton", style_menu); - theme->set_stylebox("hover", "MenuButton", style_widget_hover); - theme->set_stylebox("pressed", "MenuButton", style_menu); - theme->set_stylebox("focus", "MenuButton", style_menu); - theme->set_stylebox("disabled", "MenuButton", style_menu); + theme->set_stylebox(SNAME("normal"), SNAME("MenuButton"), style_menu); + theme->set_stylebox(SNAME("hover"), SNAME("MenuButton"), style_widget_hover); + theme->set_stylebox(SNAME("pressed"), SNAME("MenuButton"), style_menu); + theme->set_stylebox(SNAME("focus"), SNAME("MenuButton"), style_menu); + theme->set_stylebox(SNAME("disabled"), SNAME("MenuButton"), style_menu); - theme->set_color("font_color", "MenuButton", font_color); - theme->set_color("font_hover_color", "MenuButton", font_hover_color); - theme->set_color("font_focus_color", "MenuButton", font_focus_color); + theme->set_color(SNAME("font_color"), SNAME("MenuButton"), font_color); + theme->set_color(SNAME("font_hover_color"), SNAME("MenuButton"), font_hover_color); + theme->set_color(SNAME("font_focus_color"), SNAME("MenuButton"), font_focus_color); - theme->set_stylebox("MenuHover", "EditorStyles", style_widget_hover); + theme->set_stylebox(SNAME("MenuHover"), SNAME("EditorStyles"), style_widget_hover); // Buttons - theme->set_stylebox("normal", "Button", style_widget); - theme->set_stylebox("hover", "Button", style_widget_hover); - theme->set_stylebox("pressed", "Button", style_widget_pressed); - theme->set_stylebox("focus", "Button", style_widget_focus); - theme->set_stylebox("disabled", "Button", style_widget_disabled); - - theme->set_color("font_color", "Button", font_color); - theme->set_color("font_hover_color", "Button", font_hover_color); - theme->set_color("font_focus_color", "Button", font_focus_color); - theme->set_color("font_pressed_color", "Button", accent_color); - theme->set_color("font_disabled_color", "Button", font_disabled_color); - theme->set_color("icon_hover_color", "Button", icon_hover_color); - theme->set_color("icon_focus_color", "Button", icon_focus_color); - theme->set_color("icon_pressed_color", "Button", icon_pressed_color); + theme->set_stylebox(SNAME("normal"), SNAME("Button"), style_widget); + theme->set_stylebox(SNAME("hover"), SNAME("Button"), style_widget_hover); + theme->set_stylebox(SNAME("pressed"), SNAME("Button"), style_widget_pressed); + theme->set_stylebox(SNAME("focus"), SNAME("Button"), style_widget_focus); + theme->set_stylebox(SNAME("disabled"), SNAME("Button"), style_widget_disabled); + + theme->set_color(SNAME("font_color"), SNAME("Button"), font_color); + theme->set_color(SNAME("font_hover_color"), SNAME("Button"), font_hover_color); + theme->set_color(SNAME("font_focus_color"), SNAME("Button"), font_focus_color); + theme->set_color(SNAME("font_pressed_color"), SNAME("Button"), accent_color); + theme->set_color(SNAME("font_disabled_color"), SNAME("Button"), font_disabled_color); + theme->set_color(SNAME("icon_hover_color"), SNAME("Button"), icon_hover_color); + theme->set_color(SNAME("icon_focus_color"), SNAME("Button"), icon_focus_color); + theme->set_color(SNAME("icon_pressed_color"), SNAME("Button"), icon_pressed_color); // OptionButton - theme->set_stylebox("focus", "OptionButton", style_widget_focus); - - theme->set_stylebox("normal", "OptionButton", style_widget); - theme->set_stylebox("hover", "OptionButton", style_widget_hover); - theme->set_stylebox("pressed", "OptionButton", style_widget_pressed); - theme->set_stylebox("disabled", "OptionButton", style_widget_disabled); - - theme->set_stylebox("normal_mirrored", "OptionButton", style_widget); - theme->set_stylebox("hover_mirrored", "OptionButton", style_widget_hover); - theme->set_stylebox("pressed_mirrored", "OptionButton", style_widget_pressed); - theme->set_stylebox("disabled_mirrored", "OptionButton", style_widget_disabled); - - theme->set_color("font_color", "OptionButton", font_color); - theme->set_color("font_hover_color", "OptionButton", font_hover_color); - theme->set_color("font_focus_color", "OptionButton", font_focus_color); - theme->set_color("font_pressed_color", "OptionButton", accent_color); - theme->set_color("font_disabled_color", "OptionButton", font_disabled_color); - theme->set_color("icon_hover_color", "OptionButton", icon_hover_color); - theme->set_color("icon_focus_color", "OptionButton", icon_focus_color); - theme->set_icon("arrow", "OptionButton", theme->get_icon(SNAME("GuiOptionArrow"), SNAME("EditorIcons"))); - theme->set_constant("arrow_margin", "OptionButton", widget_default_margin.x - 2 * EDSCALE); - theme->set_constant("modulate_arrow", "OptionButton", true); - theme->set_constant("hseparation", "OptionButton", 4 * EDSCALE); + theme->set_stylebox(SNAME("focus"), SNAME("OptionButton"), style_widget_focus); + + theme->set_stylebox(SNAME("normal"), SNAME("OptionButton"), style_widget); + theme->set_stylebox(SNAME("hover"), SNAME("OptionButton"), style_widget_hover); + theme->set_stylebox(SNAME("pressed"), SNAME("OptionButton"), style_widget_pressed); + theme->set_stylebox(SNAME("disabled"), SNAME("OptionButton"), style_widget_disabled); + + theme->set_stylebox(SNAME("normal_mirrored"), SNAME("OptionButton"), style_widget); + theme->set_stylebox(SNAME("hover_mirrored"), SNAME("OptionButton"), style_widget_hover); + theme->set_stylebox(SNAME("pressed_mirrored"), SNAME("OptionButton"), style_widget_pressed); + theme->set_stylebox(SNAME("disabled_mirrored"), SNAME("OptionButton"), style_widget_disabled); + + theme->set_color(SNAME("font_color"), SNAME("OptionButton"), font_color); + theme->set_color(SNAME("font_hover_color"), SNAME("OptionButton"), font_hover_color); + theme->set_color(SNAME("font_focus_color"), SNAME("OptionButton"), font_focus_color); + theme->set_color(SNAME("font_pressed_color"), SNAME("OptionButton"), accent_color); + theme->set_color(SNAME("font_disabled_color"), SNAME("OptionButton"), font_disabled_color); + theme->set_color(SNAME("icon_hover_color"), SNAME("OptionButton"), icon_hover_color); + theme->set_color(SNAME("icon_focus_color"), SNAME("OptionButton"), icon_focus_color); + theme->set_icon(SNAME("arrow"), SNAME("OptionButton"), theme->get_icon(SNAME("GuiOptionArrow"), SNAME("EditorIcons"))); + theme->set_constant(SNAME("arrow_margin"), SNAME("OptionButton"), widget_default_margin.x - 2 * EDSCALE); + theme->set_constant(SNAME("modulate_arrow"), SNAME("OptionButton"), true); + theme->set_constant(SNAME("hseparation"), SNAME("OptionButton"), 4 * EDSCALE); // CheckButton - theme->set_stylebox("normal", "CheckButton", style_menu); - theme->set_stylebox("pressed", "CheckButton", style_menu); - theme->set_stylebox("disabled", "CheckButton", style_menu); - theme->set_stylebox("hover", "CheckButton", style_menu); - - theme->set_icon("on", "CheckButton", theme->get_icon(SNAME("GuiToggleOn"), SNAME("EditorIcons"))); - theme->set_icon("on_disabled", "CheckButton", theme->get_icon(SNAME("GuiToggleOnDisabled"), SNAME("EditorIcons"))); - theme->set_icon("off", "CheckButton", theme->get_icon(SNAME("GuiToggleOff"), SNAME("EditorIcons"))); - theme->set_icon("off_disabled", "CheckButton", theme->get_icon(SNAME("GuiToggleOffDisabled"), SNAME("EditorIcons"))); - - theme->set_icon("on_mirrored", "CheckButton", theme->get_icon(SNAME("GuiToggleOnMirrored"), SNAME("EditorIcons"))); - theme->set_icon("on_disabled_mirrored", "CheckButton", theme->get_icon(SNAME("GuiToggleOnDisabledMirrored"), SNAME("EditorIcons"))); - theme->set_icon("off_mirrored", "CheckButton", theme->get_icon(SNAME("GuiToggleOffMirrored"), SNAME("EditorIcons"))); - theme->set_icon("off_disabled_mirrored", "CheckButton", theme->get_icon(SNAME("GuiToggleOffDisabledMirrored"), SNAME("EditorIcons"))); - - theme->set_color("font_color", "CheckButton", font_color); - theme->set_color("font_hover_color", "CheckButton", font_hover_color); - theme->set_color("font_focus_color", "CheckButton", font_focus_color); - theme->set_color("font_pressed_color", "CheckButton", accent_color); - theme->set_color("font_disabled_color", "CheckButton", font_disabled_color); - theme->set_color("icon_hover_color", "CheckButton", icon_hover_color); - theme->set_color("icon_focus_color", "CheckButton", icon_focus_color); - - theme->set_constant("hseparation", "CheckButton", 8 * EDSCALE); - theme->set_constant("check_vadjust", "CheckButton", 0 * EDSCALE); + theme->set_stylebox(SNAME("normal"), SNAME("CheckButton"), style_menu); + theme->set_stylebox(SNAME("pressed"), SNAME("CheckButton"), style_menu); + theme->set_stylebox(SNAME("disabled"), SNAME("CheckButton"), style_menu); + theme->set_stylebox(SNAME("hover"), SNAME("CheckButton"), style_menu); + + theme->set_icon(SNAME("on"), SNAME("CheckButton"), theme->get_icon(SNAME("GuiToggleOn"), SNAME("EditorIcons"))); + theme->set_icon(SNAME("on_disabled"), SNAME("CheckButton"), theme->get_icon(SNAME("GuiToggleOnDisabled"), SNAME("EditorIcons"))); + theme->set_icon(SNAME("off"), SNAME("CheckButton"), theme->get_icon(SNAME("GuiToggleOff"), SNAME("EditorIcons"))); + theme->set_icon(SNAME("off_disabled"), SNAME("CheckButton"), theme->get_icon(SNAME("GuiToggleOffDisabled"), SNAME("EditorIcons"))); + + theme->set_icon(SNAME("on_mirrored"), SNAME("CheckButton"), theme->get_icon(SNAME("GuiToggleOnMirrored"), SNAME("EditorIcons"))); + theme->set_icon(SNAME("on_disabled_mirrored"), SNAME("CheckButton"), theme->get_icon(SNAME("GuiToggleOnDisabledMirrored"), SNAME("EditorIcons"))); + theme->set_icon(SNAME("off_mirrored"), SNAME("CheckButton"), theme->get_icon(SNAME("GuiToggleOffMirrored"), SNAME("EditorIcons"))); + theme->set_icon(SNAME("off_disabled_mirrored"), SNAME("CheckButton"), theme->get_icon(SNAME("GuiToggleOffDisabledMirrored"), SNAME("EditorIcons"))); + + theme->set_color(SNAME("font_color"), SNAME("CheckButton"), font_color); + theme->set_color(SNAME("font_hover_color"), SNAME("CheckButton"), font_hover_color); + theme->set_color(SNAME("font_focus_color"), SNAME("CheckButton"), font_focus_color); + theme->set_color(SNAME("font_pressed_color"), SNAME("CheckButton"), accent_color); + theme->set_color(SNAME("font_disabled_color"), SNAME("CheckButton"), font_disabled_color); + theme->set_color(SNAME("icon_hover_color"), SNAME("CheckButton"), icon_hover_color); + theme->set_color(SNAME("icon_focus_color"), SNAME("CheckButton"), icon_focus_color); + + theme->set_constant(SNAME("hseparation"), SNAME("CheckButton"), 8 * EDSCALE); + theme->set_constant(SNAME("check_vadjust"), SNAME("CheckButton"), 0 * EDSCALE); // Checkbox Ref<StyleBoxFlat> sb_checkbox = style_menu->duplicate(); @@ -747,32 +747,32 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) { sb_checkbox->set_default_margin(SIDE_TOP, default_margin_size * EDSCALE); sb_checkbox->set_default_margin(SIDE_BOTTOM, default_margin_size * EDSCALE); - theme->set_stylebox("normal", "CheckBox", sb_checkbox); - theme->set_stylebox("pressed", "CheckBox", sb_checkbox); - theme->set_stylebox("disabled", "CheckBox", sb_checkbox); - theme->set_stylebox("hover", "CheckBox", sb_checkbox); - theme->set_icon("checked", "CheckBox", theme->get_icon(SNAME("GuiChecked"), SNAME("EditorIcons"))); - theme->set_icon("unchecked", "CheckBox", theme->get_icon(SNAME("GuiUnchecked"), SNAME("EditorIcons"))); - theme->set_icon("radio_checked", "CheckBox", theme->get_icon(SNAME("GuiRadioChecked"), SNAME("EditorIcons"))); - theme->set_icon("radio_unchecked", "CheckBox", theme->get_icon(SNAME("GuiRadioUnchecked"), SNAME("EditorIcons"))); - theme->set_icon("checked_disabled", "CheckBox", theme->get_icon(SNAME("GuiCheckedDisabled"), SNAME("EditorIcons"))); - theme->set_icon("unchecked_disabled", "CheckBox", theme->get_icon(SNAME("GuiUncheckedDisabled"), SNAME("EditorIcons"))); - theme->set_icon("radio_checked_disabled", "CheckBox", theme->get_icon(SNAME("GuiRadioCheckedDisabled"), SNAME("EditorIcons"))); - theme->set_icon("radio_unchecked_disabled", "CheckBox", theme->get_icon(SNAME("GuiRadioUncheckedDisabled"), SNAME("EditorIcons"))); - - theme->set_color("font_color", "CheckBox", font_color); - theme->set_color("font_hover_color", "CheckBox", font_hover_color); - theme->set_color("font_focus_color", "CheckBox", font_focus_color); - theme->set_color("font_pressed_color", "CheckBox", accent_color); - theme->set_color("font_disabled_color", "CheckBox", font_disabled_color); - theme->set_color("icon_hover_color", "CheckBox", icon_hover_color); - theme->set_color("icon_focus_color", "CheckBox", icon_focus_color); - - theme->set_constant("hseparation", "CheckBox", 8 * EDSCALE); - theme->set_constant("check_vadjust", "CheckBox", 0 * EDSCALE); + theme->set_stylebox(SNAME("normal"), SNAME("CheckBox"), sb_checkbox); + theme->set_stylebox(SNAME("pressed"), SNAME("CheckBox"), sb_checkbox); + theme->set_stylebox(SNAME("disabled"), SNAME("CheckBox"), sb_checkbox); + theme->set_stylebox(SNAME("hover"), SNAME("CheckBox"), sb_checkbox); + theme->set_icon(SNAME("checked"), SNAME("CheckBox"), theme->get_icon(SNAME("GuiChecked"), SNAME("EditorIcons"))); + theme->set_icon(SNAME("unchecked"), SNAME("CheckBox"), theme->get_icon(SNAME("GuiUnchecked"), SNAME("EditorIcons"))); + theme->set_icon(SNAME("radio_checked"), SNAME("CheckBox"), theme->get_icon(SNAME("GuiRadioChecked"), SNAME("EditorIcons"))); + theme->set_icon(SNAME("radio_unchecked"), SNAME("CheckBox"), theme->get_icon(SNAME("GuiRadioUnchecked"), SNAME("EditorIcons"))); + theme->set_icon(SNAME("checked_disabled"), SNAME("CheckBox"), theme->get_icon(SNAME("GuiCheckedDisabled"), SNAME("EditorIcons"))); + theme->set_icon(SNAME("unchecked_disabled"), SNAME("CheckBox"), theme->get_icon(SNAME("GuiUncheckedDisabled"), SNAME("EditorIcons"))); + theme->set_icon(SNAME("radio_checked_disabled"), SNAME("CheckBox"), theme->get_icon(SNAME("GuiRadioCheckedDisabled"), SNAME("EditorIcons"))); + theme->set_icon(SNAME("radio_unchecked_disabled"), SNAME("CheckBox"), theme->get_icon(SNAME("GuiRadioUncheckedDisabled"), SNAME("EditorIcons"))); + + theme->set_color(SNAME("font_color"), SNAME("CheckBox"), font_color); + theme->set_color(SNAME("font_hover_color"), SNAME("CheckBox"), font_hover_color); + theme->set_color(SNAME("font_focus_color"), SNAME("CheckBox"), font_focus_color); + theme->set_color(SNAME("font_pressed_color"), SNAME("CheckBox"), accent_color); + theme->set_color(SNAME("font_disabled_color"), SNAME("CheckBox"), font_disabled_color); + theme->set_color(SNAME("icon_hover_color"), SNAME("CheckBox"), icon_hover_color); + theme->set_color(SNAME("icon_focus_color"), SNAME("CheckBox"), icon_focus_color); + + theme->set_constant(SNAME("hseparation"), SNAME("CheckBox"), 8 * EDSCALE); + theme->set_constant(SNAME("check_vadjust"), SNAME("CheckBox"), 0 * EDSCALE); // PopupDialog - theme->set_stylebox("panel", "PopupDialog", style_popup); + theme->set_stylebox(SNAME("panel"), SNAME("PopupDialog"), style_popup); // PopupMenu const int popup_menu_margin_size = default_margin_size * 1.5 * EDSCALE; @@ -787,39 +787,39 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) { // Always display a border for PopupMenus so they can be distinguished from their background. style_popup_menu->set_border_width_all(1 * EDSCALE); style_popup_menu->set_border_color(dark_color_2); - theme->set_stylebox("panel", "PopupMenu", style_popup_menu); + theme->set_stylebox(SNAME("panel"), SNAME("PopupMenu"), style_popup_menu); Ref<StyleBoxFlat> style_menu_hover = style_widget_hover->duplicate(); // Don't use rounded corners for hover highlights since the StyleBox touches the PopupMenu's edges. style_menu_hover->set_corner_radius_all(0); - theme->set_stylebox("hover", "PopupMenu", style_menu_hover); - - theme->set_stylebox("separator", "PopupMenu", style_popup_separator); - theme->set_stylebox("labeled_separator_left", "PopupMenu", style_popup_labeled_separator_left); - theme->set_stylebox("labeled_separator_right", "PopupMenu", style_popup_labeled_separator_right); - - theme->set_color("font_color", "PopupMenu", font_color); - theme->set_color("font_hover_color", "PopupMenu", font_hover_color); - theme->set_color("font_accelerator_color", "PopupMenu", font_disabled_color); - theme->set_color("font_disabled_color", "PopupMenu", font_disabled_color); - theme->set_color("font_separator_color", "PopupMenu", font_disabled_color); - theme->set_icon("checked", "PopupMenu", theme->get_icon(SNAME("GuiChecked"), SNAME("EditorIcons"))); - theme->set_icon("unchecked", "PopupMenu", theme->get_icon(SNAME("GuiUnchecked"), SNAME("EditorIcons"))); - theme->set_icon("radio_checked", "PopupMenu", theme->get_icon(SNAME("GuiRadioChecked"), SNAME("EditorIcons"))); - theme->set_icon("radio_unchecked", "PopupMenu", theme->get_icon(SNAME("GuiRadioUnchecked"), SNAME("EditorIcons"))); - theme->set_icon("checked_disabled", "PopupMenu", theme->get_icon(SNAME("GuiCheckedDisabled"), SNAME("EditorIcons"))); - theme->set_icon("unchecked_disabled", "PopupMenu", theme->get_icon(SNAME("GuiUncheckedDisabled"), SNAME("EditorIcons"))); - theme->set_icon("radio_checked_disabled", "PopupMenu", theme->get_icon(SNAME("GuiRadioCheckedDisabled"), SNAME("EditorIcons"))); - theme->set_icon("radio_unchecked_disabled", "PopupMenu", theme->get_icon(SNAME("GuiRadioUncheckedDisabled"), SNAME("EditorIcons"))); - theme->set_icon("submenu", "PopupMenu", theme->get_icon(SNAME("ArrowRight"), SNAME("EditorIcons"))); - theme->set_icon("submenu_mirrored", "PopupMenu", theme->get_icon(SNAME("ArrowLeft"), SNAME("EditorIcons"))); - theme->set_icon("visibility_hidden", "PopupMenu", theme->get_icon(SNAME("GuiVisibilityHidden"), SNAME("EditorIcons"))); - theme->set_icon("visibility_visible", "PopupMenu", theme->get_icon(SNAME("GuiVisibilityVisible"), SNAME("EditorIcons"))); - theme->set_icon("visibility_xray", "PopupMenu", theme->get_icon(SNAME("GuiVisibilityXray"), SNAME("EditorIcons"))); - - theme->set_constant("vseparation", "PopupMenu", (extra_spacing + default_margin_size + 1) * EDSCALE); - theme->set_constant("item_start_padding", "PopupMenu", popup_menu_margin_size * EDSCALE); - theme->set_constant("item_end_padding", "PopupMenu", popup_menu_margin_size * EDSCALE); + theme->set_stylebox(SNAME("hover"), SNAME("PopupMenu"), style_menu_hover); + + theme->set_stylebox(SNAME("separator"), SNAME("PopupMenu"), style_popup_separator); + theme->set_stylebox(SNAME("labeled_separator_left"), SNAME("PopupMenu"), style_popup_labeled_separator_left); + theme->set_stylebox(SNAME("labeled_separator_right"), SNAME("PopupMenu"), style_popup_labeled_separator_right); + + theme->set_color(SNAME("font_color"), SNAME("PopupMenu"), font_color); + theme->set_color(SNAME("font_hover_color"), SNAME("PopupMenu"), font_hover_color); + theme->set_color(SNAME("font_accelerator_color"), SNAME("PopupMenu"), font_disabled_color); + theme->set_color(SNAME("font_disabled_color"), SNAME("PopupMenu"), font_disabled_color); + theme->set_color(SNAME("font_separator_color"), SNAME("PopupMenu"), font_disabled_color); + theme->set_icon(SNAME("checked"), SNAME("PopupMenu"), theme->get_icon(SNAME("GuiChecked"), SNAME("EditorIcons"))); + theme->set_icon(SNAME("unchecked"), SNAME("PopupMenu"), theme->get_icon(SNAME("GuiUnchecked"), SNAME("EditorIcons"))); + theme->set_icon(SNAME("radio_checked"), SNAME("PopupMenu"), theme->get_icon(SNAME("GuiRadioChecked"), SNAME("EditorIcons"))); + theme->set_icon(SNAME("radio_unchecked"), SNAME("PopupMenu"), theme->get_icon(SNAME("GuiRadioUnchecked"), SNAME("EditorIcons"))); + theme->set_icon(SNAME("checked_disabled"), SNAME("PopupMenu"), theme->get_icon(SNAME("GuiCheckedDisabled"), SNAME("EditorIcons"))); + theme->set_icon(SNAME("unchecked_disabled"), SNAME("PopupMenu"), theme->get_icon(SNAME("GuiUncheckedDisabled"), SNAME("EditorIcons"))); + theme->set_icon(SNAME("radio_checked_disabled"), SNAME("PopupMenu"), theme->get_icon(SNAME("GuiRadioCheckedDisabled"), SNAME("EditorIcons"))); + theme->set_icon(SNAME("radio_unchecked_disabled"), SNAME("PopupMenu"), theme->get_icon(SNAME("GuiRadioUncheckedDisabled"), SNAME("EditorIcons"))); + theme->set_icon(SNAME("submenu"), SNAME("PopupMenu"), theme->get_icon(SNAME("ArrowRight"), SNAME("EditorIcons"))); + theme->set_icon(SNAME("submenu_mirrored"), SNAME("PopupMenu"), theme->get_icon(SNAME("ArrowLeft"), SNAME("EditorIcons"))); + theme->set_icon(SNAME("visibility_hidden"), SNAME("PopupMenu"), theme->get_icon(SNAME("GuiVisibilityHidden"), SNAME("EditorIcons"))); + theme->set_icon(SNAME("visibility_visible"), SNAME("PopupMenu"), theme->get_icon(SNAME("GuiVisibilityVisible"), SNAME("EditorIcons"))); + theme->set_icon(SNAME("visibility_xray"), SNAME("PopupMenu"), theme->get_icon(SNAME("GuiVisibilityXray"), SNAME("EditorIcons"))); + + theme->set_constant(SNAME("vseparation"), SNAME("PopupMenu"), (extra_spacing + default_margin_size + 1) * EDSCALE); + theme->set_constant(SNAME("item_start_padding"), SNAME("PopupMenu"), popup_menu_margin_size * EDSCALE); + theme->set_constant(SNAME("item_end_padding"), SNAME("PopupMenu"), popup_menu_margin_size * EDSCALE); for (int i = 0; i < 16; i++) { Color si_base_color = accent_color; @@ -843,7 +843,7 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) { sub_inspector_bg->set_border_color(si_base_color * Color(0.7, 0.7, 0.7, 0.8)); sub_inspector_bg->set_draw_center(true); - theme->set_stylebox("sub_inspector_bg" + itos(i), "Editor", sub_inspector_bg); + theme->set_stylebox("sub_inspector_bg" + itos(i), SNAME("Editor"), sub_inspector_bg); Ref<StyleBoxFlat> bg_color; bg_color.instantiate(); @@ -855,99 +855,99 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) { bg_color_selected->set_border_width_all(0); bg_color_selected->set_bg_color(si_base_color * Color(0.8, 0.8, 0.8, 0.8)); - theme->set_stylebox("sub_inspector_property_bg" + itos(i), "Editor", bg_color); - theme->set_stylebox("sub_inspector_property_bg_selected" + itos(i), "Editor", bg_color_selected); + theme->set_stylebox("sub_inspector_property_bg" + itos(i), SNAME("Editor"), bg_color); + theme->set_stylebox("sub_inspector_property_bg_selected" + itos(i), SNAME("Editor"), bg_color_selected); } - theme->set_color("sub_inspector_property_color", "Editor", dark_theme ? Color(1, 1, 1, 1) : Color(0, 0, 0, 1)); - theme->set_constant("sub_inspector_font_offset", "Editor", 4 * EDSCALE); + theme->set_color(SNAME("sub_inspector_property_color"), SNAME("Editor"), dark_theme ? Color(1, 1, 1, 1) : Color(0, 0, 0, 1)); + theme->set_constant(SNAME("sub_inspector_font_offset"), SNAME("Editor"), 4 * EDSCALE); Ref<StyleBoxFlat> style_property_bg = style_default->duplicate(); style_property_bg->set_bg_color(highlight_color); style_property_bg->set_border_width_all(0); - theme->set_constant("font_offset", "EditorProperty", 8 * EDSCALE); - theme->set_stylebox("bg_selected", "EditorProperty", style_property_bg); - theme->set_stylebox("bg", "EditorProperty", Ref<StyleBoxEmpty>(memnew(StyleBoxEmpty))); - theme->set_constant("vseparation", "EditorProperty", (extra_spacing + default_margin_size) * EDSCALE); - theme->set_color("warning_color", "EditorProperty", warning_color); - theme->set_color("property_color", "EditorProperty", property_color); - theme->set_color("readonly_color", "EditorProperty", readonly_color); - theme->set_color("readonly_warning_color", "EditorProperty", readonly_warning_color); + theme->set_constant(SNAME("font_offset"), SNAME("EditorProperty"), 8 * EDSCALE); + theme->set_stylebox(SNAME("bg_selected"), SNAME("EditorProperty"), style_property_bg); + theme->set_stylebox(SNAME("bg"), SNAME("EditorProperty"), Ref<StyleBoxEmpty>(memnew(StyleBoxEmpty))); + theme->set_constant(SNAME("vseparation"), SNAME("EditorProperty"), (extra_spacing + default_margin_size) * EDSCALE); + theme->set_color(SNAME("warning_color"), SNAME("EditorProperty"), warning_color); + theme->set_color(SNAME("property_color"), SNAME("EditorProperty"), property_color); + theme->set_color(SNAME("readonly_color"), SNAME("EditorProperty"), readonly_color); + theme->set_color(SNAME("readonly_warning_color"), SNAME("EditorProperty"), readonly_warning_color); Color inspector_section_color = font_color.lerp(Color(0.5, 0.5, 0.5), 0.35); - theme->set_color("font_color", "EditorInspectorSection", inspector_section_color); + theme->set_color(SNAME("font_color"), SNAME("EditorInspectorSection"), inspector_section_color); - theme->set_constant("inspector_margin", "Editor", 12 * EDSCALE); + theme->set_constant(SNAME("inspector_margin"), SNAME("Editor"), 12 * EDSCALE); // Tree & ItemList background Ref<StyleBoxFlat> style_tree_bg = style_default->duplicate(); // Make Trees easier to distinguish from other controls by using a darker background color. style_tree_bg->set_bg_color(dark_color_1.lerp(dark_color_2, 0.5)); style_tree_bg->set_border_color(dark_color_3); - theme->set_stylebox("bg", "Tree", style_tree_bg); + theme->set_stylebox(SNAME("bg"), SNAME("Tree"), style_tree_bg); // Tree - theme->set_icon("checked", "Tree", theme->get_icon(SNAME("GuiChecked"), SNAME("EditorIcons"))); - theme->set_icon("indeterminate", "Tree", theme->get_icon(SNAME("GuiIndeterminate"), SNAME("EditorIcons"))); - theme->set_icon("unchecked", "Tree", theme->get_icon(SNAME("GuiUnchecked"), SNAME("EditorIcons"))); - theme->set_icon("arrow", "Tree", theme->get_icon(SNAME("GuiTreeArrowDown"), SNAME("EditorIcons"))); - theme->set_icon("arrow_collapsed", "Tree", theme->get_icon(SNAME("GuiTreeArrowRight"), SNAME("EditorIcons"))); - theme->set_icon("arrow_collapsed_mirrored", "Tree", theme->get_icon(SNAME("GuiTreeArrowLeft"), SNAME("EditorIcons"))); - theme->set_icon("updown", "Tree", theme->get_icon(SNAME("GuiTreeUpdown"), SNAME("EditorIcons"))); - theme->set_icon("select_arrow", "Tree", theme->get_icon(SNAME("GuiDropdown"), SNAME("EditorIcons"))); - theme->set_stylebox("bg_focus", "Tree", style_widget_focus); - theme->set_stylebox("custom_button", "Tree", make_empty_stylebox()); - theme->set_stylebox("custom_button_pressed", "Tree", make_empty_stylebox()); - theme->set_stylebox("custom_button_hover", "Tree", style_widget); - theme->set_color("custom_button_font_highlight", "Tree", font_hover_color); - theme->set_color("font_color", "Tree", font_color); - theme->set_color("font_selected_color", "Tree", mono_color); - theme->set_color("title_button_color", "Tree", font_color); - theme->set_color("drop_position_color", "Tree", accent_color); - theme->set_constant("vseparation", "Tree", widget_default_margin.y - EDSCALE); - theme->set_constant("hseparation", "Tree", 6 * EDSCALE); - theme->set_constant("guide_width", "Tree", border_width); - theme->set_constant("item_margin", "Tree", 3 * default_margin_size * EDSCALE); - theme->set_constant("button_margin", "Tree", default_margin_size * EDSCALE); - theme->set_constant("scroll_border", "Tree", 40 * EDSCALE); - theme->set_constant("scroll_speed", "Tree", 12); + theme->set_icon(SNAME("checked"), SNAME("Tree"), theme->get_icon(SNAME("GuiChecked"), SNAME("EditorIcons"))); + theme->set_icon(SNAME("indeterminate"), SNAME("Tree"), theme->get_icon(SNAME("GuiIndeterminate"), SNAME("EditorIcons"))); + theme->set_icon(SNAME("unchecked"), SNAME("Tree"), theme->get_icon(SNAME("GuiUnchecked"), SNAME("EditorIcons"))); + theme->set_icon(SNAME("arrow"), SNAME("Tree"), theme->get_icon(SNAME("GuiTreeArrowDown"), SNAME("EditorIcons"))); + theme->set_icon(SNAME("arrow_collapsed"), SNAME("Tree"), theme->get_icon(SNAME("GuiTreeArrowRight"), SNAME("EditorIcons"))); + theme->set_icon(SNAME("arrow_collapsed_mirrored"), SNAME("Tree"), theme->get_icon(SNAME("GuiTreeArrowLeft"), SNAME("EditorIcons"))); + theme->set_icon(SNAME("updown"), SNAME("Tree"), theme->get_icon(SNAME("GuiTreeUpdown"), SNAME("EditorIcons"))); + theme->set_icon(SNAME("select_arrow"), SNAME("Tree"), theme->get_icon(SNAME("GuiDropdown"), SNAME("EditorIcons"))); + theme->set_stylebox(SNAME("bg_focus"), SNAME("Tree"), style_widget_focus); + theme->set_stylebox(SNAME("custom_button"), SNAME("Tree"), make_empty_stylebox()); + theme->set_stylebox(SNAME("custom_button_pressed"), SNAME("Tree"), make_empty_stylebox()); + theme->set_stylebox(SNAME("custom_button_hover"), SNAME("Tree"), style_widget); + theme->set_color(SNAME("custom_button_font_highlight"), SNAME("Tree"), font_hover_color); + theme->set_color(SNAME("font_color"), SNAME("Tree"), font_color); + theme->set_color(SNAME("font_selected_color"), SNAME("Tree"), mono_color); + theme->set_color(SNAME("title_button_color"), SNAME("Tree"), font_color); + theme->set_color(SNAME("drop_position_color"), SNAME("Tree"), accent_color); + theme->set_constant(SNAME("vseparation"), SNAME("Tree"), widget_default_margin.y - EDSCALE); + theme->set_constant(SNAME("hseparation"), SNAME("Tree"), 6 * EDSCALE); + theme->set_constant(SNAME("guide_width"), SNAME("Tree"), border_width); + theme->set_constant(SNAME("item_margin"), SNAME("Tree"), 3 * default_margin_size * EDSCALE); + theme->set_constant(SNAME("button_margin"), SNAME("Tree"), default_margin_size * EDSCALE); + theme->set_constant(SNAME("scroll_border"), SNAME("Tree"), 40 * EDSCALE); + theme->set_constant(SNAME("scroll_speed"), SNAME("Tree"), 12); const Color guide_color = mono_color * Color(1, 1, 1, 0.05); Color relationship_line_color = mono_color * Color(1, 1, 1, relationship_line_opacity); - theme->set_constant("draw_guides", "Tree", relationship_line_opacity < 0.01); - theme->set_color("guide_color", "Tree", guide_color); + theme->set_constant(SNAME("draw_guides"), SNAME("Tree"), relationship_line_opacity < 0.01); + theme->set_color(SNAME("guide_color"), SNAME("Tree"), guide_color); int relationship_line_width = 1; Color parent_line_color = mono_color * Color(1, 1, 1, CLAMP(relationship_line_opacity + 0.45, 0.0, 1.0)); Color children_line_color = mono_color * Color(1, 1, 1, CLAMP(relationship_line_opacity + 0.25, 0.0, 1.0)); - theme->set_constant("draw_relationship_lines", "Tree", relationship_line_opacity >= 0.01); - theme->set_constant("relationship_line_width", "Tree", relationship_line_width); - theme->set_constant("parent_hl_line_width", "Tree", relationship_line_width * 2); - theme->set_constant("children_hl_line_width", "Tree", relationship_line_width); - theme->set_constant("parent_hl_line_margin", "Tree", relationship_line_width * 3); - theme->set_color("relationship_line_color", "Tree", relationship_line_color); - theme->set_color("parent_hl_line_color", "Tree", parent_line_color); - theme->set_color("children_hl_line_color", "Tree", children_line_color); + theme->set_constant(SNAME("draw_relationship_lines"), SNAME("Tree"), relationship_line_opacity >= 0.01); + theme->set_constant(SNAME("relationship_line_width"), SNAME("Tree"), relationship_line_width); + theme->set_constant(SNAME("parent_hl_line_width"), SNAME("Tree"), relationship_line_width * 2); + theme->set_constant(SNAME("children_hl_line_width"), SNAME("Tree"), relationship_line_width); + theme->set_constant(SNAME("parent_hl_line_margin"), SNAME("Tree"), relationship_line_width * 3); + theme->set_color(SNAME("relationship_line_color"), SNAME("Tree"), relationship_line_color); + theme->set_color(SNAME("parent_hl_line_color"), SNAME("Tree"), parent_line_color); + theme->set_color(SNAME("children_hl_line_color"), SNAME("Tree"), children_line_color); Ref<StyleBoxFlat> style_tree_btn = style_default->duplicate(); style_tree_btn->set_bg_color(highlight_color); style_tree_btn->set_border_width_all(0); - theme->set_stylebox("button_pressed", "Tree", style_tree_btn); + theme->set_stylebox(SNAME("button_pressed"), SNAME("Tree"), style_tree_btn); Ref<StyleBoxFlat> style_tree_hover = style_default->duplicate(); style_tree_hover->set_bg_color(highlight_color * Color(1, 1, 1, 0.4)); style_tree_hover->set_border_width_all(0); - theme->set_stylebox("hover", "Tree", style_tree_hover); + theme->set_stylebox(SNAME("hover"), SNAME("Tree"), style_tree_hover); Ref<StyleBoxFlat> style_tree_focus = style_default->duplicate(); style_tree_focus->set_bg_color(highlight_color); style_tree_focus->set_border_width_all(0); - theme->set_stylebox("selected_focus", "Tree", style_tree_focus); + theme->set_stylebox(SNAME("selected_focus"), SNAME("Tree"), style_tree_focus); Ref<StyleBoxFlat> style_tree_selected = style_tree_focus->duplicate(); - theme->set_stylebox("selected", "Tree", style_tree_selected); + theme->set_stylebox(SNAME("selected"), SNAME("Tree"), style_tree_selected); Ref<StyleBoxFlat> style_tree_cursor = style_default->duplicate(); style_tree_cursor->set_draw_center(false); @@ -957,25 +957,25 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) { Ref<StyleBoxFlat> style_tree_title = style_default->duplicate(); style_tree_title->set_bg_color(dark_color_3); style_tree_title->set_border_width_all(0); - theme->set_stylebox("cursor", "Tree", style_tree_cursor); - theme->set_stylebox("cursor_unfocused", "Tree", style_tree_cursor); - theme->set_stylebox("title_button_normal", "Tree", style_tree_title); - theme->set_stylebox("title_button_hover", "Tree", style_tree_title); - theme->set_stylebox("title_button_pressed", "Tree", style_tree_title); + theme->set_stylebox(SNAME("cursor"), SNAME("Tree"), style_tree_cursor); + theme->set_stylebox(SNAME("cursor_unfocused"), SNAME("Tree"), style_tree_cursor); + theme->set_stylebox(SNAME("title_button_normal"), SNAME("Tree"), style_tree_title); + theme->set_stylebox(SNAME("title_button_hover"), SNAME("Tree"), style_tree_title); + theme->set_stylebox(SNAME("title_button_pressed"), SNAME("Tree"), style_tree_title); Color prop_category_color = dark_color_1.lerp(mono_color, 0.12); Color prop_section_color = dark_color_1.lerp(mono_color, 0.09); Color prop_subsection_color = dark_color_1.lerp(mono_color, 0.06); - theme->set_color("prop_category", "Editor", prop_category_color); - theme->set_color("prop_section", "Editor", prop_section_color); - theme->set_color("prop_subsection", "Editor", prop_subsection_color); - theme->set_color("drop_position_color", "Tree", accent_color); + theme->set_color(SNAME("prop_category"), SNAME("Editor"), prop_category_color); + theme->set_color(SNAME("prop_section"), SNAME("Editor"), prop_section_color); + theme->set_color(SNAME("prop_subsection"), SNAME("Editor"), prop_subsection_color); + theme->set_color(SNAME("drop_position_color"), SNAME("Tree"), accent_color); Ref<StyleBoxFlat> category_bg = style_default->duplicate(); // Make Trees easier to distinguish from other controls by using a darker background color. category_bg->set_bg_color(prop_category_color); category_bg->set_border_color(prop_category_color); - theme->set_stylebox("prop_category_style", "Editor", category_bg); + theme->set_stylebox(SNAME("prop_category_style"), SNAME("Editor"), category_bg); // ItemList Ref<StyleBoxFlat> style_itemlist_bg = style_default->duplicate(); @@ -987,47 +987,47 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) { style_itemlist_cursor->set_draw_center(false); style_itemlist_cursor->set_border_width_all(border_width); style_itemlist_cursor->set_border_color(highlight_color); - theme->set_stylebox("cursor", "ItemList", style_itemlist_cursor); - theme->set_stylebox("cursor_unfocused", "ItemList", style_itemlist_cursor); - theme->set_stylebox("selected_focus", "ItemList", style_tree_focus); - theme->set_stylebox("selected", "ItemList", style_tree_selected); - theme->set_stylebox("bg_focus", "ItemList", style_widget_focus); - theme->set_stylebox("bg", "ItemList", style_itemlist_bg); - theme->set_color("font_color", "ItemList", font_color); - theme->set_color("font_selected_color", "ItemList", mono_color); - theme->set_color("guide_color", "ItemList", guide_color); - theme->set_constant("vseparation", "ItemList", widget_default_margin.y - EDSCALE); - theme->set_constant("hseparation", "ItemList", 6 * EDSCALE); - theme->set_constant("icon_margin", "ItemList", 6 * EDSCALE); - theme->set_constant("line_separation", "ItemList", 3 * EDSCALE); + theme->set_stylebox(SNAME("cursor"), SNAME("ItemList"), style_itemlist_cursor); + theme->set_stylebox(SNAME("cursor_unfocused"), SNAME("ItemList"), style_itemlist_cursor); + theme->set_stylebox(SNAME("selected_focus"), SNAME("ItemList"), style_tree_focus); + theme->set_stylebox(SNAME("selected"), SNAME("ItemList"), style_tree_selected); + theme->set_stylebox(SNAME("bg_focus"), SNAME("ItemList"), style_widget_focus); + theme->set_stylebox(SNAME("bg"), SNAME("ItemList"), style_itemlist_bg); + theme->set_color(SNAME("font_color"), SNAME("ItemList"), font_color); + theme->set_color(SNAME("font_selected_color"), SNAME("ItemList"), mono_color); + theme->set_color(SNAME("guide_color"), SNAME("ItemList"), guide_color); + theme->set_constant(SNAME("vseparation"), SNAME("ItemList"), widget_default_margin.y - EDSCALE); + theme->set_constant(SNAME("hseparation"), SNAME("ItemList"), 6 * EDSCALE); + theme->set_constant(SNAME("icon_margin"), SNAME("ItemList"), 6 * EDSCALE); + theme->set_constant(SNAME("line_separation"), SNAME("ItemList"), 3 * EDSCALE); // TabBar & TabContainer - theme->set_stylebox("tab_selected", "TabContainer", style_tab_selected); - theme->set_stylebox("tab_unselected", "TabContainer", style_tab_unselected); - theme->set_stylebox("tab_disabled", "TabContainer", style_tab_disabled); - theme->set_stylebox("tab_selected", "TabBar", style_tab_selected); - theme->set_stylebox("tab_unselected", "TabBar", style_tab_unselected); - theme->set_stylebox("tab_disabled", "TabBar", style_tab_disabled); - theme->set_color("font_selected_color", "TabContainer", font_color); - theme->set_color("font_unselected_color", "TabContainer", font_disabled_color); - theme->set_color("font_selected_color", "TabBar", font_color); - theme->set_color("font_unselected_color", "TabBar", font_disabled_color); - theme->set_icon("menu", "TabContainer", theme->get_icon(SNAME("GuiTabMenu"), SNAME("EditorIcons"))); - theme->set_icon("menu_highlight", "TabContainer", theme->get_icon(SNAME("GuiTabMenuHl"), SNAME("EditorIcons"))); - theme->set_stylebox("SceneTabFG", "EditorStyles", style_tab_selected); - theme->set_stylebox("SceneTabBG", "EditorStyles", style_tab_unselected); - theme->set_icon("close", "TabBar", theme->get_icon(SNAME("GuiClose"), SNAME("EditorIcons"))); - theme->set_stylebox("button_pressed", "TabBar", style_menu); - theme->set_stylebox("button_highlight", "TabBar", style_menu); - theme->set_icon("increment", "TabContainer", theme->get_icon(SNAME("GuiScrollArrowRight"), SNAME("EditorIcons"))); - theme->set_icon("decrement", "TabContainer", theme->get_icon(SNAME("GuiScrollArrowLeft"), SNAME("EditorIcons"))); - theme->set_icon("increment", "TabBar", theme->get_icon(SNAME("GuiScrollArrowRight"), SNAME("EditorIcons"))); - theme->set_icon("decrement", "TabBar", theme->get_icon(SNAME("GuiScrollArrowLeft"), SNAME("EditorIcons"))); - theme->set_icon("increment_highlight", "TabBar", theme->get_icon(SNAME("GuiScrollArrowRightHl"), SNAME("EditorIcons"))); - theme->set_icon("decrement_highlight", "TabBar", theme->get_icon(SNAME("GuiScrollArrowLeftHl"), SNAME("EditorIcons"))); - theme->set_icon("increment_highlight", "TabContainer", theme->get_icon(SNAME("GuiScrollArrowRightHl"), SNAME("EditorIcons"))); - theme->set_icon("decrement_highlight", "TabContainer", theme->get_icon(SNAME("GuiScrollArrowLeftHl"), SNAME("EditorIcons"))); - theme->set_constant("hseparation", "TabBar", 4 * EDSCALE); + theme->set_stylebox(SNAME("tab_selected"), SNAME("TabContainer"), style_tab_selected); + theme->set_stylebox(SNAME("tab_unselected"), SNAME("TabContainer"), style_tab_unselected); + theme->set_stylebox(SNAME("tab_disabled"), SNAME("TabContainer"), style_tab_disabled); + theme->set_stylebox(SNAME("tab_selected"), SNAME("TabBar"), style_tab_selected); + theme->set_stylebox(SNAME("tab_unselected"), SNAME("TabBar"), style_tab_unselected); + theme->set_stylebox(SNAME("tab_disabled"), SNAME("TabBar"), style_tab_disabled); + theme->set_color(SNAME("font_selected_color"), SNAME("TabContainer"), font_color); + theme->set_color(SNAME("font_unselected_color"), SNAME("TabContainer"), font_disabled_color); + theme->set_color(SNAME("font_selected_color"), SNAME("TabBar"), font_color); + theme->set_color(SNAME("font_unselected_color"), SNAME("TabBar"), font_disabled_color); + theme->set_icon(SNAME("menu"), SNAME("TabContainer"), theme->get_icon(SNAME("GuiTabMenu"), SNAME("EditorIcons"))); + theme->set_icon(SNAME("menu_highlight"), SNAME("TabContainer"), theme->get_icon(SNAME("GuiTabMenuHl"), SNAME("EditorIcons"))); + theme->set_stylebox(SNAME("SceneTabFG"), SNAME("EditorStyles"), style_tab_selected); + theme->set_stylebox(SNAME("SceneTabBG"), SNAME("EditorStyles"), style_tab_unselected); + theme->set_icon(SNAME("close"), SNAME("TabBar"), theme->get_icon(SNAME("GuiClose"), SNAME("EditorIcons"))); + theme->set_stylebox(SNAME("button_pressed"), SNAME("TabBar"), style_menu); + theme->set_stylebox(SNAME("button_highlight"), SNAME("TabBar"), style_menu); + theme->set_icon(SNAME("increment"), SNAME("TabContainer"), theme->get_icon(SNAME("GuiScrollArrowRight"), SNAME("EditorIcons"))); + theme->set_icon(SNAME("decrement"), SNAME("TabContainer"), theme->get_icon(SNAME("GuiScrollArrowLeft"), SNAME("EditorIcons"))); + theme->set_icon(SNAME("increment"), SNAME("TabBar"), theme->get_icon(SNAME("GuiScrollArrowRight"), SNAME("EditorIcons"))); + theme->set_icon(SNAME("decrement"), SNAME("TabBar"), theme->get_icon(SNAME("GuiScrollArrowLeft"), SNAME("EditorIcons"))); + theme->set_icon(SNAME("increment_highlight"), SNAME("TabBar"), theme->get_icon(SNAME("GuiScrollArrowRightHl"), SNAME("EditorIcons"))); + theme->set_icon(SNAME("decrement_highlight"), SNAME("TabBar"), theme->get_icon(SNAME("GuiScrollArrowLeftHl"), SNAME("EditorIcons"))); + theme->set_icon(SNAME("increment_highlight"), SNAME("TabContainer"), theme->get_icon(SNAME("GuiScrollArrowRightHl"), SNAME("EditorIcons"))); + theme->set_icon(SNAME("decrement_highlight"), SNAME("TabContainer"), theme->get_icon(SNAME("GuiScrollArrowLeftHl"), SNAME("EditorIcons"))); + theme->set_constant(SNAME("hseparation"), SNAME("TabBar"), 4 * EDSCALE); // Content of each tab Ref<StyleBoxFlat> style_content_panel = style_default->duplicate(); @@ -1041,16 +1041,16 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) { // Display border to visually split the body of the container from its possible backgrounds. style_content_panel->set_border_width(Side::SIDE_TOP, Math::round(2 * EDSCALE)); style_content_panel->set_border_color(dark_color_2); - theme->set_stylebox("panel", "TabContainer", style_content_panel); + theme->set_stylebox(SNAME("panel"), SNAME("TabContainer"), style_content_panel); // These styleboxes can be used on tabs against the base color background (e.g. nested tabs). Ref<StyleBoxFlat> style_tab_selected_odd = style_tab_selected->duplicate(); style_tab_selected_odd->set_bg_color(disabled_bg_color); - theme->set_stylebox("tab_selected_odd", "TabContainer", style_tab_selected_odd); + theme->set_stylebox(SNAME("tab_selected_odd"), SNAME("TabContainer"), style_tab_selected_odd); Ref<StyleBoxFlat> style_content_panel_odd = style_content_panel->duplicate(); style_content_panel_odd->set_bg_color(disabled_bg_color); - theme->set_stylebox("panel_odd", "TabContainer", style_content_panel_odd); + theme->set_stylebox(SNAME("panel_odd"), SNAME("TabContainer"), style_content_panel_odd); // This stylebox is used in 3d and 2d viewports (no borders). Ref<StyleBoxFlat> style_content_panel_vp = style_content_panel->duplicate(); @@ -1058,31 +1058,31 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) { 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); - theme->set_stylebox("Content", "EditorStyles", style_content_panel_vp); + theme->set_stylebox(SNAME("Content"), SNAME("EditorStyles"), style_content_panel_vp); // This stylebox is used by preview tabs in the Theme Editor. Ref<StyleBoxFlat> style_theme_preview_tab = style_tab_selected_odd->duplicate(); style_theme_preview_tab->set_expand_margin_size(SIDE_BOTTOM, 5 * EDSCALE); - theme->set_stylebox("ThemeEditorPreviewFG", "EditorStyles", style_theme_preview_tab); + theme->set_stylebox(SNAME("ThemeEditorPreviewFG"), SNAME("EditorStyles"), style_theme_preview_tab); Ref<StyleBoxFlat> style_theme_preview_bg_tab = style_tab_unselected->duplicate(); style_theme_preview_bg_tab->set_expand_margin_size(SIDE_BOTTOM, 2 * EDSCALE); - theme->set_stylebox("ThemeEditorPreviewBG", "EditorStyles", style_theme_preview_bg_tab); + theme->set_stylebox(SNAME("ThemeEditorPreviewBG"), SNAME("EditorStyles"), style_theme_preview_bg_tab); // Separators - theme->set_stylebox("separator", "HSeparator", make_line_stylebox(separator_color, MAX(Math::round(EDSCALE), border_width))); - theme->set_stylebox("separator", "VSeparator", make_line_stylebox(separator_color, MAX(Math::round(EDSCALE), border_width), 0, 0, true)); + theme->set_stylebox(SNAME("separator"), SNAME("HSeparator"), make_line_stylebox(separator_color, MAX(Math::round(EDSCALE), border_width))); + theme->set_stylebox(SNAME("separator"), SNAME("VSeparator"), make_line_stylebox(separator_color, MAX(Math::round(EDSCALE), border_width), 0, 0, true)); // Debugger Ref<StyleBoxFlat> style_panel_debugger = style_content_panel->duplicate(); style_panel_debugger->set_border_width(SIDE_BOTTOM, 0); - theme->set_stylebox("DebuggerPanel", "EditorStyles", style_panel_debugger); + theme->set_stylebox(SNAME("DebuggerPanel"), SNAME("EditorStyles"), style_panel_debugger); Ref<StyleBoxFlat> style_panel_invisible_top = style_content_panel->duplicate(); int stylebox_offset = theme->get_font(SNAME("tab_selected"), SNAME("TabContainer"))->get_height(theme->get_font_size(SNAME("tab_selected"), SNAME("TabContainer"))) + theme->get_stylebox(SNAME("tab_selected"), SNAME("TabContainer"))->get_minimum_size().height + theme->get_stylebox(SNAME("panel"), SNAME("TabContainer"))->get_default_margin(SIDE_TOP); style_panel_invisible_top->set_expand_margin_size(SIDE_TOP, -stylebox_offset); style_panel_invisible_top->set_default_margin(SIDE_TOP, 0); - theme->set_stylebox("BottomPanelDebuggerOverride", "EditorStyles", style_panel_invisible_top); + theme->set_stylebox(SNAME("BottomPanelDebuggerOverride"), SNAME("EditorStyles"), style_panel_invisible_top); // LineEdit @@ -1102,74 +1102,74 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) { style_line_edit_disabled->set_border_color(disabled_color); style_line_edit_disabled->set_bg_color(disabled_bg_color); - theme->set_stylebox("normal", "LineEdit", style_line_edit); - theme->set_stylebox("focus", "LineEdit", style_widget_focus); - theme->set_stylebox("read_only", "LineEdit", style_line_edit_disabled); - theme->set_icon("clear", "LineEdit", theme->get_icon(SNAME("GuiClose"), SNAME("EditorIcons"))); - theme->set_color("read_only", "LineEdit", font_disabled_color); - theme->set_color("font_color", "LineEdit", font_color); - theme->set_color("font_selected_color", "LineEdit", mono_color); - theme->set_color("font_uneditable_color", "LineEdit", font_readonly_color); - theme->set_color("font_placeholder_color", "LineEdit", font_placeholder_color); - theme->set_color("caret_color", "LineEdit", font_color); - theme->set_color("selection_color", "LineEdit", selection_color); - theme->set_color("clear_button_color", "LineEdit", font_color); - theme->set_color("clear_button_color_pressed", "LineEdit", accent_color); + theme->set_stylebox(SNAME("normal"), SNAME("LineEdit"), style_line_edit); + theme->set_stylebox(SNAME("focus"), SNAME("LineEdit"), style_widget_focus); + theme->set_stylebox(SNAME("read_only"), SNAME("LineEdit"), style_line_edit_disabled); + theme->set_icon(SNAME("clear"), SNAME("LineEdit"), theme->get_icon(SNAME("GuiClose"), SNAME("EditorIcons"))); + theme->set_color(SNAME("read_only"), SNAME("LineEdit"), font_disabled_color); + theme->set_color(SNAME("font_color"), SNAME("LineEdit"), font_color); + theme->set_color(SNAME("font_selected_color"), SNAME("LineEdit"), mono_color); + theme->set_color(SNAME("font_uneditable_color"), SNAME("LineEdit"), font_readonly_color); + theme->set_color(SNAME("font_placeholder_color"), SNAME("LineEdit"), font_placeholder_color); + theme->set_color(SNAME("caret_color"), SNAME("LineEdit"), font_color); + theme->set_color(SNAME("selection_color"), SNAME("LineEdit"), selection_color); + theme->set_color(SNAME("clear_button_color"), SNAME("LineEdit"), font_color); + theme->set_color(SNAME("clear_button_color_pressed"), SNAME("LineEdit"), accent_color); // TextEdit - theme->set_stylebox("normal", "TextEdit", style_line_edit); - theme->set_stylebox("focus", "TextEdit", style_widget_focus); - theme->set_stylebox("read_only", "TextEdit", style_line_edit_disabled); - theme->set_constant("side_margin", "TabContainer", 0); - theme->set_icon("tab", "TextEdit", theme->get_icon(SNAME("GuiTab"), SNAME("EditorIcons"))); - theme->set_icon("space", "TextEdit", theme->get_icon(SNAME("GuiSpace"), SNAME("EditorIcons"))); - theme->set_color("font_color", "TextEdit", font_color); - theme->set_color("font_readonly_color", "TextEdit", font_readonly_color); - theme->set_color("font_placeholder_color", "TextEdit", font_placeholder_color); - theme->set_color("caret_color", "TextEdit", font_color); - theme->set_color("selection_color", "TextEdit", selection_color); - theme->set_constant("line_spacing", "TextEdit", 4 * EDSCALE); + theme->set_stylebox(SNAME("normal"), SNAME("TextEdit"), style_line_edit); + theme->set_stylebox(SNAME("focus"), SNAME("TextEdit"), style_widget_focus); + theme->set_stylebox(SNAME("read_only"), SNAME("TextEdit"), style_line_edit_disabled); + theme->set_constant(SNAME("side_margin"), SNAME("TabContainer"), 0); + theme->set_icon(SNAME("tab"), SNAME("TextEdit"), theme->get_icon(SNAME("GuiTab"), SNAME("EditorIcons"))); + theme->set_icon(SNAME("space"), SNAME("TextEdit"), theme->get_icon(SNAME("GuiSpace"), SNAME("EditorIcons"))); + theme->set_color(SNAME("font_color"), SNAME("TextEdit"), font_color); + theme->set_color(SNAME("font_readonly_color"), SNAME("TextEdit"), font_readonly_color); + theme->set_color(SNAME("font_placeholder_color"), SNAME("TextEdit"), font_placeholder_color); + theme->set_color(SNAME("caret_color"), SNAME("TextEdit"), font_color); + theme->set_color(SNAME("selection_color"), SNAME("TextEdit"), selection_color); + theme->set_constant(SNAME("line_spacing"), SNAME("TextEdit"), 4 * EDSCALE); // CodeEdit - theme->set_font("font", "CodeEdit", theme->get_font(SNAME("source"), SNAME("EditorFonts"))); - theme->set_font_size("font_size", "CodeEdit", theme->get_font_size(SNAME("source_size"), SNAME("EditorFonts"))); - theme->set_stylebox("normal", "CodeEdit", style_widget); - theme->set_stylebox("focus", "CodeEdit", style_widget_hover); - theme->set_stylebox("read_only", "CodeEdit", style_widget_disabled); - theme->set_icon("tab", "CodeEdit", theme->get_icon(SNAME("GuiTab"), SNAME("EditorIcons"))); - theme->set_icon("space", "CodeEdit", theme->get_icon(SNAME("GuiSpace"), SNAME("EditorIcons"))); - theme->set_icon("folded", "CodeEdit", theme->get_icon(SNAME("GuiTreeArrowRight"), SNAME("EditorIcons"))); - theme->set_icon("can_fold", "CodeEdit", theme->get_icon(SNAME("GuiTreeArrowDown"), SNAME("EditorIcons"))); - theme->set_icon("executing_line", "CodeEdit", theme->get_icon(SNAME("MainPlay"), SNAME("EditorIcons"))); - theme->set_icon("breakpoint", "CodeEdit", theme->get_icon(SNAME("Breakpoint"), SNAME("EditorIcons"))); - theme->set_constant("line_spacing", "CodeEdit", EDITOR_DEF("text_editor/appearance/whitespace/line_spacing", 6)); + theme->set_font(SNAME("font"), SNAME("CodeEdit"), theme->get_font(SNAME("source"), SNAME("EditorFonts"))); + theme->set_font_size(SNAME("font_size"), SNAME("CodeEdit"), theme->get_font_size(SNAME("source_size"), SNAME("EditorFonts"))); + theme->set_stylebox(SNAME("normal"), SNAME("CodeEdit"), style_widget); + theme->set_stylebox(SNAME("focus"), SNAME("CodeEdit"), style_widget_hover); + theme->set_stylebox(SNAME("read_only"), SNAME("CodeEdit"), style_widget_disabled); + theme->set_icon(SNAME("tab"), SNAME("CodeEdit"), theme->get_icon(SNAME("GuiTab"), SNAME("EditorIcons"))); + theme->set_icon(SNAME("space"), SNAME("CodeEdit"), theme->get_icon(SNAME("GuiSpace"), SNAME("EditorIcons"))); + theme->set_icon(SNAME("folded"), SNAME("CodeEdit"), theme->get_icon(SNAME("GuiTreeArrowRight"), SNAME("EditorIcons"))); + theme->set_icon(SNAME("can_fold"), SNAME("CodeEdit"), theme->get_icon(SNAME("GuiTreeArrowDown"), SNAME("EditorIcons"))); + theme->set_icon(SNAME("executing_line"), SNAME("CodeEdit"), theme->get_icon(SNAME("MainPlay"), SNAME("EditorIcons"))); + theme->set_icon(SNAME("breakpoint"), SNAME("CodeEdit"), theme->get_icon(SNAME("Breakpoint"), SNAME("EditorIcons"))); + theme->set_constant(SNAME("line_spacing"), SNAME("CodeEdit"), EDITOR_DEF("text_editor/appearance/whitespace/line_spacing", 6)); // H/VSplitContainer - theme->set_stylebox("bg", "VSplitContainer", make_stylebox(theme->get_icon(SNAME("GuiVsplitBg"), SNAME("EditorIcons")), 1, 1, 1, 1)); - theme->set_stylebox("bg", "HSplitContainer", make_stylebox(theme->get_icon(SNAME("GuiHsplitBg"), SNAME("EditorIcons")), 1, 1, 1, 1)); + theme->set_stylebox(SNAME("bg"), SNAME("VSplitContainer"), make_stylebox(theme->get_icon(SNAME("GuiVsplitBg"), SNAME("EditorIcons")), 1, 1, 1, 1)); + theme->set_stylebox(SNAME("bg"), SNAME("HSplitContainer"), make_stylebox(theme->get_icon(SNAME("GuiHsplitBg"), SNAME("EditorIcons")), 1, 1, 1, 1)); - theme->set_icon("grabber", "VSplitContainer", theme->get_icon(SNAME("GuiVsplitter"), SNAME("EditorIcons"))); - theme->set_icon("grabber", "HSplitContainer", theme->get_icon(SNAME("GuiHsplitter"), SNAME("EditorIcons"))); + theme->set_icon(SNAME("grabber"), SNAME("VSplitContainer"), theme->get_icon(SNAME("GuiVsplitter"), SNAME("EditorIcons"))); + theme->set_icon(SNAME("grabber"), SNAME("HSplitContainer"), theme->get_icon(SNAME("GuiHsplitter"), SNAME("EditorIcons"))); - theme->set_constant("separation", "HSplitContainer", default_margin_size * 2 * EDSCALE); - theme->set_constant("separation", "VSplitContainer", default_margin_size * 2 * EDSCALE); + theme->set_constant(SNAME("separation"), SNAME("HSplitContainer"), default_margin_size * 2 * EDSCALE); + theme->set_constant(SNAME("separation"), SNAME("VSplitContainer"), default_margin_size * 2 * EDSCALE); // Containers - theme->set_constant("separation", "BoxContainer", default_margin_size * EDSCALE); - theme->set_constant("separation", "HBoxContainer", default_margin_size * EDSCALE); - theme->set_constant("separation", "VBoxContainer", default_margin_size * EDSCALE); - theme->set_constant("margin_left", "MarginContainer", 0); - theme->set_constant("margin_top", "MarginContainer", 0); - theme->set_constant("margin_right", "MarginContainer", 0); - theme->set_constant("margin_bottom", "MarginContainer", 0); - theme->set_constant("hseparation", "GridContainer", default_margin_size * EDSCALE); - theme->set_constant("vseparation", "GridContainer", default_margin_size * EDSCALE); - theme->set_constant("hseparation", "FlowContainer", default_margin_size * EDSCALE); - theme->set_constant("vseparation", "FlowContainer", default_margin_size * EDSCALE); - theme->set_constant("hseparation", "HFlowContainer", default_margin_size * EDSCALE); - theme->set_constant("vseparation", "HFlowContainer", default_margin_size * EDSCALE); - theme->set_constant("hseparation", "VFlowContainer", default_margin_size * EDSCALE); - theme->set_constant("vseparation", "VFlowContainer", default_margin_size * EDSCALE); + theme->set_constant(SNAME("separation"), SNAME("BoxContainer"), default_margin_size * EDSCALE); + theme->set_constant(SNAME("separation"), SNAME("HBoxContainer"), default_margin_size * EDSCALE); + theme->set_constant(SNAME("separation"), SNAME("VBoxContainer"), default_margin_size * EDSCALE); + theme->set_constant(SNAME("margin_left"), SNAME("MarginContainer"), 0); + theme->set_constant(SNAME("margin_top"), SNAME("MarginContainer"), 0); + theme->set_constant(SNAME("margin_right"), SNAME("MarginContainer"), 0); + theme->set_constant(SNAME("margin_bottom"), SNAME("MarginContainer"), 0); + theme->set_constant(SNAME("hseparation"), SNAME("GridContainer"), default_margin_size * EDSCALE); + theme->set_constant(SNAME("vseparation"), SNAME("GridContainer"), default_margin_size * EDSCALE); + theme->set_constant(SNAME("hseparation"), SNAME("FlowContainer"), default_margin_size * EDSCALE); + theme->set_constant(SNAME("vseparation"), SNAME("FlowContainer"), default_margin_size * EDSCALE); + theme->set_constant(SNAME("hseparation"), SNAME("HFlowContainer"), default_margin_size * EDSCALE); + theme->set_constant(SNAME("vseparation"), SNAME("HFlowContainer"), default_margin_size * EDSCALE); + theme->set_constant(SNAME("hseparation"), SNAME("VFlowContainer"), default_margin_size * EDSCALE); + theme->set_constant(SNAME("vseparation"), SNAME("VFlowContainer"), default_margin_size * EDSCALE); // Window @@ -1184,119 +1184,119 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) { style_window->set_border_color(base_color); style_window->set_border_width(SIDE_TOP, 24 * EDSCALE); style_window->set_expand_margin_size(SIDE_TOP, 24 * EDSCALE); - theme->set_stylebox("embedded_border", "Window", style_window); - - theme->set_color("title_color", "Window", font_color); - theme->set_icon("close", "Window", theme->get_icon(SNAME("GuiClose"), SNAME("EditorIcons"))); - theme->set_icon("close_pressed", "Window", theme->get_icon(SNAME("GuiClose"), SNAME("EditorIcons"))); - theme->set_constant("close_h_ofs", "Window", 22 * EDSCALE); - theme->set_constant("close_v_ofs", "Window", 20 * EDSCALE); - theme->set_constant("title_height", "Window", 24 * EDSCALE); - theme->set_constant("resize_margin", "Window", 4 * EDSCALE); - theme->set_font("title_font", "Window", theme->get_font(SNAME("title"), SNAME("EditorFonts"))); - theme->set_font_size("title_font_size", "Window", theme->get_font_size(SNAME("title_size"), SNAME("EditorFonts"))); + theme->set_stylebox(SNAME("embedded_border"), SNAME("Window"), style_window); + + theme->set_color(SNAME("title_color"), SNAME("Window"), font_color); + theme->set_icon(SNAME("close"), SNAME("Window"), theme->get_icon(SNAME("GuiClose"), SNAME("EditorIcons"))); + theme->set_icon(SNAME("close_pressed"), SNAME("Window"), theme->get_icon(SNAME("GuiClose"), SNAME("EditorIcons"))); + theme->set_constant(SNAME("close_h_ofs"), SNAME("Window"), 22 * EDSCALE); + theme->set_constant(SNAME("close_v_ofs"), SNAME("Window"), 20 * EDSCALE); + theme->set_constant(SNAME("title_height"), SNAME("Window"), 24 * EDSCALE); + theme->set_constant(SNAME("resize_margin"), SNAME("Window"), 4 * EDSCALE); + theme->set_font(SNAME("title_font"), SNAME("Window"), theme->get_font(SNAME("title"), SNAME("EditorFonts"))); + theme->set_font_size(SNAME("title_font_size"), SNAME("Window"), theme->get_font_size(SNAME("title_size"), SNAME("EditorFonts"))); // Complex window (currently only Editor Settings and Project Settings) Ref<StyleBoxFlat> style_complex_window = style_window->duplicate(); style_complex_window->set_bg_color(dark_color_2); style_complex_window->set_border_color(dark_color_2); - theme->set_stylebox("panel", "EditorSettingsDialog", style_complex_window); - theme->set_stylebox("panel", "ProjectSettingsEditor", style_complex_window); - theme->set_stylebox("panel", "EditorAbout", style_complex_window); + theme->set_stylebox(SNAME("panel"), SNAME("EditorSettingsDialog"), style_complex_window); + theme->set_stylebox(SNAME("panel"), SNAME("ProjectSettingsEditor"), style_complex_window); + theme->set_stylebox(SNAME("panel"), SNAME("EditorAbout"), style_complex_window); // AcceptDialog - theme->set_stylebox("panel", "AcceptDialog", style_window_title); + theme->set_stylebox(SNAME("panel"), SNAME("AcceptDialog"), style_window_title); // HScrollBar Ref<Texture2D> empty_icon = memnew(ImageTexture); - theme->set_stylebox("scroll", "HScrollBar", make_stylebox(theme->get_icon(SNAME("GuiScrollBg"), SNAME("EditorIcons")), 5, 5, 5, 5, 0, 0, 0, 0)); - theme->set_stylebox("scroll_focus", "HScrollBar", make_stylebox(theme->get_icon(SNAME("GuiScrollBg"), SNAME("EditorIcons")), 5, 5, 5, 5, 0, 0, 0, 0)); - theme->set_stylebox("grabber", "HScrollBar", make_stylebox(theme->get_icon(SNAME("GuiScrollGrabber"), SNAME("EditorIcons")), 6, 6, 6, 6, 2, 2, 2, 2)); - theme->set_stylebox("grabber_highlight", "HScrollBar", make_stylebox(theme->get_icon(SNAME("GuiScrollGrabberHl"), SNAME("EditorIcons")), 5, 5, 5, 5, 2, 2, 2, 2)); - theme->set_stylebox("grabber_pressed", "HScrollBar", make_stylebox(theme->get_icon(SNAME("GuiScrollGrabberPressed"), SNAME("EditorIcons")), 6, 6, 6, 6, 2, 2, 2, 2)); + theme->set_stylebox(SNAME("scroll"), SNAME("HScrollBar"), make_stylebox(theme->get_icon(SNAME("GuiScrollBg"), SNAME("EditorIcons")), 5, 5, 5, 5, 0, 0, 0, 0)); + theme->set_stylebox(SNAME("scroll_focus"), SNAME("HScrollBar"), make_stylebox(theme->get_icon(SNAME("GuiScrollBg"), SNAME("EditorIcons")), 5, 5, 5, 5, 0, 0, 0, 0)); + theme->set_stylebox(SNAME("grabber"), SNAME("HScrollBar"), make_stylebox(theme->get_icon(SNAME("GuiScrollGrabber"), SNAME("EditorIcons")), 6, 6, 6, 6, 2, 2, 2, 2)); + theme->set_stylebox(SNAME("grabber_highlight"), SNAME("HScrollBar"), make_stylebox(theme->get_icon(SNAME("GuiScrollGrabberHl"), SNAME("EditorIcons")), 5, 5, 5, 5, 2, 2, 2, 2)); + theme->set_stylebox(SNAME("grabber_pressed"), SNAME("HScrollBar"), make_stylebox(theme->get_icon(SNAME("GuiScrollGrabberPressed"), SNAME("EditorIcons")), 6, 6, 6, 6, 2, 2, 2, 2)); - theme->set_icon("increment", "HScrollBar", empty_icon); - theme->set_icon("increment_highlight", "HScrollBar", empty_icon); - theme->set_icon("increment_pressed", "HScrollBar", empty_icon); - theme->set_icon("decrement", "HScrollBar", empty_icon); - theme->set_icon("decrement_highlight", "HScrollBar", empty_icon); - theme->set_icon("decrement_pressed", "HScrollBar", empty_icon); + theme->set_icon(SNAME("increment"), SNAME("HScrollBar"), empty_icon); + theme->set_icon(SNAME("increment_highlight"), SNAME("HScrollBar"), empty_icon); + theme->set_icon(SNAME("increment_pressed"), SNAME("HScrollBar"), empty_icon); + theme->set_icon(SNAME("decrement"), SNAME("HScrollBar"), empty_icon); + theme->set_icon(SNAME("decrement_highlight"), SNAME("HScrollBar"), empty_icon); + theme->set_icon(SNAME("decrement_pressed"), SNAME("HScrollBar"), empty_icon); // VScrollBar - theme->set_stylebox("scroll", "VScrollBar", make_stylebox(theme->get_icon(SNAME("GuiScrollBg"), SNAME("EditorIcons")), 5, 5, 5, 5, 0, 0, 0, 0)); - theme->set_stylebox("scroll_focus", "VScrollBar", make_stylebox(theme->get_icon(SNAME("GuiScrollBg"), SNAME("EditorIcons")), 5, 5, 5, 5, 0, 0, 0, 0)); - theme->set_stylebox("grabber", "VScrollBar", make_stylebox(theme->get_icon(SNAME("GuiScrollGrabber"), SNAME("EditorIcons")), 6, 6, 6, 6, 2, 2, 2, 2)); - theme->set_stylebox("grabber_highlight", "VScrollBar", make_stylebox(theme->get_icon(SNAME("GuiScrollGrabberHl"), SNAME("EditorIcons")), 5, 5, 5, 5, 2, 2, 2, 2)); - theme->set_stylebox("grabber_pressed", "VScrollBar", make_stylebox(theme->get_icon(SNAME("GuiScrollGrabberPressed"), SNAME("EditorIcons")), 6, 6, 6, 6, 2, 2, 2, 2)); - - theme->set_icon("increment", "VScrollBar", empty_icon); - theme->set_icon("increment_highlight", "VScrollBar", empty_icon); - theme->set_icon("increment_pressed", "VScrollBar", empty_icon); - theme->set_icon("decrement", "VScrollBar", empty_icon); - theme->set_icon("decrement_highlight", "VScrollBar", empty_icon); - theme->set_icon("decrement_pressed", "VScrollBar", empty_icon); + theme->set_stylebox(SNAME("scroll"), SNAME("VScrollBar"), make_stylebox(theme->get_icon(SNAME("GuiScrollBg"), SNAME("EditorIcons")), 5, 5, 5, 5, 0, 0, 0, 0)); + theme->set_stylebox(SNAME("scroll_focus"), SNAME("VScrollBar"), make_stylebox(theme->get_icon(SNAME("GuiScrollBg"), SNAME("EditorIcons")), 5, 5, 5, 5, 0, 0, 0, 0)); + theme->set_stylebox(SNAME("grabber"), SNAME("VScrollBar"), make_stylebox(theme->get_icon(SNAME("GuiScrollGrabber"), SNAME("EditorIcons")), 6, 6, 6, 6, 2, 2, 2, 2)); + theme->set_stylebox(SNAME("grabber_highlight"), SNAME("VScrollBar"), make_stylebox(theme->get_icon(SNAME("GuiScrollGrabberHl"), SNAME("EditorIcons")), 5, 5, 5, 5, 2, 2, 2, 2)); + theme->set_stylebox(SNAME("grabber_pressed"), SNAME("VScrollBar"), make_stylebox(theme->get_icon(SNAME("GuiScrollGrabberPressed"), SNAME("EditorIcons")), 6, 6, 6, 6, 2, 2, 2, 2)); + + theme->set_icon(SNAME("increment"), SNAME("VScrollBar"), empty_icon); + theme->set_icon(SNAME("increment_highlight"), SNAME("VScrollBar"), empty_icon); + theme->set_icon(SNAME("increment_pressed"), SNAME("VScrollBar"), empty_icon); + theme->set_icon(SNAME("decrement"), SNAME("VScrollBar"), empty_icon); + theme->set_icon(SNAME("decrement_highlight"), SNAME("VScrollBar"), empty_icon); + theme->set_icon(SNAME("decrement_pressed"), SNAME("VScrollBar"), empty_icon); // HSlider - theme->set_icon("grabber_highlight", "HSlider", theme->get_icon(SNAME("GuiSliderGrabberHl"), SNAME("EditorIcons"))); - theme->set_icon("grabber", "HSlider", theme->get_icon(SNAME("GuiSliderGrabber"), SNAME("EditorIcons"))); - theme->set_stylebox("slider", "HSlider", make_flat_stylebox(dark_color_3, 0, default_margin_size / 2, 0, default_margin_size / 2, corner_width)); - theme->set_stylebox("grabber_area", "HSlider", make_flat_stylebox(contrast_color_1, 0, default_margin_size / 2, 0, default_margin_size / 2, corner_width)); - theme->set_stylebox("grabber_area_highlight", "HSlider", make_flat_stylebox(contrast_color_1, 0, default_margin_size / 2, 0, default_margin_size / 2)); + theme->set_icon(SNAME("grabber_highlight"), SNAME("HSlider"), theme->get_icon(SNAME("GuiSliderGrabberHl"), SNAME("EditorIcons"))); + theme->set_icon(SNAME("grabber"), SNAME("HSlider"), theme->get_icon(SNAME("GuiSliderGrabber"), SNAME("EditorIcons"))); + theme->set_stylebox(SNAME("slider"), SNAME("HSlider"), make_flat_stylebox(dark_color_3, 0, default_margin_size / 2, 0, default_margin_size / 2, corner_width)); + theme->set_stylebox(SNAME("grabber_area"), SNAME("HSlider"), make_flat_stylebox(contrast_color_1, 0, default_margin_size / 2, 0, default_margin_size / 2, corner_width)); + theme->set_stylebox(SNAME("grabber_area_highlight"), SNAME("HSlider"), make_flat_stylebox(contrast_color_1, 0, default_margin_size / 2, 0, default_margin_size / 2)); // VSlider - theme->set_icon("grabber", "VSlider", theme->get_icon(SNAME("GuiSliderGrabber"), SNAME("EditorIcons"))); - theme->set_icon("grabber_highlight", "VSlider", theme->get_icon(SNAME("GuiSliderGrabberHl"), SNAME("EditorIcons"))); - theme->set_stylebox("slider", "VSlider", make_flat_stylebox(dark_color_3, default_margin_size / 2, 0, default_margin_size / 2, 0, corner_width)); - theme->set_stylebox("grabber_area", "VSlider", make_flat_stylebox(contrast_color_1, default_margin_size / 2, 0, default_margin_size / 2, 0, corner_width)); - theme->set_stylebox("grabber_area_highlight", "VSlider", make_flat_stylebox(contrast_color_1, default_margin_size / 2, 0, default_margin_size / 2, 0)); + theme->set_icon(SNAME("grabber"), SNAME("VSlider"), theme->get_icon(SNAME("GuiSliderGrabber"), SNAME("EditorIcons"))); + theme->set_icon(SNAME("grabber_highlight"), SNAME("VSlider"), theme->get_icon(SNAME("GuiSliderGrabberHl"), SNAME("EditorIcons"))); + theme->set_stylebox(SNAME("slider"), SNAME("VSlider"), make_flat_stylebox(dark_color_3, default_margin_size / 2, 0, default_margin_size / 2, 0, corner_width)); + theme->set_stylebox(SNAME("grabber_area"), SNAME("VSlider"), make_flat_stylebox(contrast_color_1, default_margin_size / 2, 0, default_margin_size / 2, 0, corner_width)); + theme->set_stylebox(SNAME("grabber_area_highlight"), SNAME("VSlider"), make_flat_stylebox(contrast_color_1, default_margin_size / 2, 0, default_margin_size / 2, 0)); // RichTextLabel - theme->set_color("default_color", "RichTextLabel", font_color); - theme->set_color("font_shadow_color", "RichTextLabel", Color(0, 0, 0, 0)); - theme->set_constant("shadow_offset_x", "RichTextLabel", 1 * EDSCALE); - theme->set_constant("shadow_offset_y", "RichTextLabel", 1 * EDSCALE); - theme->set_constant("shadow_outline_size", "RichTextLabel", 1 * EDSCALE); - theme->set_stylebox("focus", "RichTextLabel", make_empty_stylebox()); - theme->set_stylebox("normal", "RichTextLabel", style_tree_bg); + theme->set_color(SNAME("default_color"), SNAME("RichTextLabel"), font_color); + theme->set_color(SNAME("font_shadow_color"), SNAME("RichTextLabel"), Color(0, 0, 0, 0)); + theme->set_constant(SNAME("shadow_offset_x"), SNAME("RichTextLabel"), 1 * EDSCALE); + theme->set_constant(SNAME("shadow_offset_y"), SNAME("RichTextLabel"), 1 * EDSCALE); + theme->set_constant(SNAME("shadow_outline_size"), SNAME("RichTextLabel"), 1 * EDSCALE); + theme->set_stylebox(SNAME("focus"), SNAME("RichTextLabel"), make_empty_stylebox()); + theme->set_stylebox(SNAME("normal"), SNAME("RichTextLabel"), style_tree_bg); // Editor help. - theme->set_color("title_color", "EditorHelp", accent_color); - theme->set_color("headline_color", "EditorHelp", mono_color); - theme->set_color("text_color", "EditorHelp", font_color); - theme->set_color("comment_color", "EditorHelp", font_color * Color(1, 1, 1, 0.6)); - theme->set_color("symbol_color", "EditorHelp", font_color * Color(1, 1, 1, 0.6)); - theme->set_color("value_color", "EditorHelp", font_color * Color(1, 1, 1, 0.6)); - theme->set_color("qualifier_color", "EditorHelp", font_color * Color(1, 1, 1, 0.8)); - theme->set_color("type_color", "EditorHelp", accent_color.lerp(font_color, 0.5)); - theme->set_color("selection_color", "EditorHelp", accent_color * Color(1, 1, 1, 0.4)); - theme->set_color("link_color", "EditorHelp", accent_color.lerp(mono_color, 0.8)); - theme->set_color("code_color", "EditorHelp", accent_color.lerp(mono_color, 0.6)); - theme->set_color("kbd_color", "EditorHelp", accent_color.lerp(property_color, 0.6)); - theme->set_constant("line_separation", "EditorHelp", Math::round(6 * EDSCALE)); - theme->set_constant("table_hseparation", "EditorHelp", 16 * EDSCALE); - theme->set_constant("table_vseparation", "EditorHelp", 6 * EDSCALE); + theme->set_color(SNAME("title_color"), SNAME("EditorHelp"), accent_color); + theme->set_color(SNAME("headline_color"), SNAME("EditorHelp"), mono_color); + theme->set_color(SNAME("text_color"), SNAME("EditorHelp"), font_color); + theme->set_color(SNAME("comment_color"), SNAME("EditorHelp"), font_color * Color(1, 1, 1, 0.6)); + theme->set_color(SNAME("symbol_color"), SNAME("EditorHelp"), font_color * Color(1, 1, 1, 0.6)); + theme->set_color(SNAME("value_color"), SNAME("EditorHelp"), font_color * Color(1, 1, 1, 0.6)); + theme->set_color(SNAME("qualifier_color"), SNAME("EditorHelp"), font_color * Color(1, 1, 1, 0.8)); + theme->set_color(SNAME("type_color"), SNAME("EditorHelp"), accent_color.lerp(font_color, 0.5)); + theme->set_color(SNAME("selection_color"), SNAME("EditorHelp"), accent_color * Color(1, 1, 1, 0.4)); + theme->set_color(SNAME("link_color"), SNAME("EditorHelp"), accent_color.lerp(mono_color, 0.8)); + theme->set_color(SNAME("code_color"), SNAME("EditorHelp"), accent_color.lerp(mono_color, 0.6)); + theme->set_color(SNAME("kbd_color"), SNAME("EditorHelp"), accent_color.lerp(property_color, 0.6)); + theme->set_constant(SNAME("line_separation"), SNAME("EditorHelp"), Math::round(6 * EDSCALE)); + theme->set_constant(SNAME("table_hseparation"), SNAME("EditorHelp"), 16 * EDSCALE); + theme->set_constant(SNAME("table_vseparation"), SNAME("EditorHelp"), 6 * EDSCALE); // Panel - theme->set_stylebox("panel", "Panel", make_flat_stylebox(dark_color_1, 6, 4, 6, 4, corner_width)); - theme->set_stylebox("panel_fg", "Panel", style_default); + theme->set_stylebox(SNAME("panel"), SNAME("Panel"), make_flat_stylebox(dark_color_1, 6, 4, 6, 4, corner_width)); + theme->set_stylebox(SNAME("panel_fg"), SNAME("Panel"), style_default); // Label - theme->set_stylebox("normal", "Label", style_empty); - theme->set_color("font_color", "Label", font_color); - theme->set_color("font_shadow_color", "Label", Color(0, 0, 0, 0)); - theme->set_constant("shadow_offset_x", "Label", 1 * EDSCALE); - theme->set_constant("shadow_offset_y", "Label", 1 * EDSCALE); - theme->set_constant("shadow_outline_size", "Label", 1 * EDSCALE); - theme->set_constant("line_spacing", "Label", 3 * EDSCALE); + theme->set_stylebox(SNAME("normal"), SNAME("Label"), style_empty); + theme->set_color(SNAME("font_color"), SNAME("Label"), font_color); + theme->set_color(SNAME("font_shadow_color"), SNAME("Label"), Color(0, 0, 0, 0)); + theme->set_constant(SNAME("shadow_offset_x"), SNAME("Label"), 1 * EDSCALE); + theme->set_constant(SNAME("shadow_offset_y"), SNAME("Label"), 1 * EDSCALE); + theme->set_constant(SNAME("shadow_outline_size"), SNAME("Label"), 1 * EDSCALE); + theme->set_constant(SNAME("line_spacing"), SNAME("Label"), 3 * EDSCALE); // LinkButton - theme->set_stylebox("focus", "LinkButton", style_empty); - theme->set_color("font_color", "LinkButton", font_color); - theme->set_color("font_hover_color", "LinkButton", font_hover_color); - theme->set_color("font_focus_color", "LinkButton", font_focus_color); - theme->set_color("font_pressed_color", "LinkButton", accent_color); - theme->set_color("font_disabled_color", "LinkButton", font_disabled_color); + theme->set_stylebox(SNAME("focus"), SNAME("LinkButton"), style_empty); + theme->set_color(SNAME("font_color"), SNAME("LinkButton"), font_color); + theme->set_color(SNAME("font_hover_color"), SNAME("LinkButton"), font_hover_color); + theme->set_color(SNAME("font_focus_color"), SNAME("LinkButton"), font_focus_color); + theme->set_color(SNAME("font_pressed_color"), SNAME("LinkButton"), accent_color); + theme->set_color(SNAME("font_disabled_color"), SNAME("LinkButton"), font_disabled_color); // TooltipPanel Ref<StyleBoxFlat> style_tooltip = style_popup->duplicate(); @@ -1307,48 +1307,48 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) { style_tooltip->set_default_margin(SIDE_BOTTOM, 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); - theme->set_color("font_color_shadow", "TooltipLabel", Color(0, 0, 0, 0)); - theme->set_stylebox("panel", "TooltipPanel", style_tooltip); + theme->set_color(SNAME("font_color"), SNAME("TooltipLabel"), font_hover_color); + theme->set_color(SNAME("font_color_shadow"), SNAME("TooltipLabel"), Color(0, 0, 0, 0)); + theme->set_stylebox(SNAME("panel"), SNAME("TooltipPanel"), style_tooltip); // PopupPanel - theme->set_stylebox("panel", "PopupPanel", style_popup); + theme->set_stylebox(SNAME("panel"), SNAME("PopupPanel"), style_popup); // SpinBox - theme->set_icon("updown", "SpinBox", theme->get_icon(SNAME("GuiSpinboxUpdown"), SNAME("EditorIcons"))); - theme->set_icon("updown_disabled", "SpinBox", theme->get_icon(SNAME("GuiSpinboxUpdownDisabled"), SNAME("EditorIcons"))); + theme->set_icon(SNAME("updown"), SNAME("SpinBox"), theme->get_icon(SNAME("GuiSpinboxUpdown"), SNAME("EditorIcons"))); + theme->set_icon(SNAME("updown_disabled"), SNAME("SpinBox"), theme->get_icon(SNAME("GuiSpinboxUpdownDisabled"), SNAME("EditorIcons"))); // ProgressBar - theme->set_stylebox("bg", "ProgressBar", make_stylebox(theme->get_icon(SNAME("GuiProgressBar"), SNAME("EditorIcons")), 4, 4, 4, 4, 0, 0, 0, 0)); - theme->set_stylebox("fg", "ProgressBar", make_stylebox(theme->get_icon(SNAME("GuiProgressFill"), SNAME("EditorIcons")), 6, 6, 6, 6, 2, 1, 2, 1)); - theme->set_color("font_color", "ProgressBar", font_color); + theme->set_stylebox(SNAME("bg"), SNAME("ProgressBar"), make_stylebox(theme->get_icon(SNAME("GuiProgressBar"), SNAME("EditorIcons")), 4, 4, 4, 4, 0, 0, 0, 0)); + theme->set_stylebox(SNAME("fg"), SNAME("ProgressBar"), make_stylebox(theme->get_icon(SNAME("GuiProgressFill"), SNAME("EditorIcons")), 6, 6, 6, 6, 2, 1, 2, 1)); + theme->set_color(SNAME("font_color"), SNAME("ProgressBar"), font_color); // GraphEdit - theme->set_stylebox("bg", "GraphEdit", style_tree_bg); + theme->set_stylebox(SNAME("bg"), "GraphEdit", style_tree_bg); if (dark_theme) { - theme->set_color("grid_major", "GraphEdit", Color(1.0, 1.0, 1.0, 0.15)); - theme->set_color("grid_minor", "GraphEdit", Color(1.0, 1.0, 1.0, 0.07)); + theme->set_color(SNAME("grid_major"), SNAME("GraphEdit"), Color(1.0, 1.0, 1.0, 0.15)); + theme->set_color(SNAME("grid_minor"), SNAME("GraphEdit"), Color(1.0, 1.0, 1.0, 0.07)); } else { - theme->set_color("grid_major", "GraphEdit", Color(0.0, 0.0, 0.0, 0.15)); - theme->set_color("grid_minor", "GraphEdit", Color(0.0, 0.0, 0.0, 0.07)); + theme->set_color(SNAME("grid_major"), SNAME("GraphEdit"), Color(0.0, 0.0, 0.0, 0.15)); + theme->set_color(SNAME("grid_minor"), SNAME("GraphEdit"), Color(0.0, 0.0, 0.0, 0.07)); } - theme->set_color("selection_fill", "GraphEdit", theme->get_color(SNAME("box_selection_fill_color"), SNAME("Editor"))); - theme->set_color("selection_stroke", "GraphEdit", theme->get_color(SNAME("box_selection_stroke_color"), SNAME("Editor"))); - theme->set_color("activity", "GraphEdit", accent_color); - theme->set_icon("minus", "GraphEdit", theme->get_icon(SNAME("ZoomLess"), SNAME("EditorIcons"))); - theme->set_icon("more", "GraphEdit", theme->get_icon(SNAME("ZoomMore"), SNAME("EditorIcons"))); - theme->set_icon("reset", "GraphEdit", theme->get_icon(SNAME("ZoomReset"), SNAME("EditorIcons"))); - theme->set_icon("snap", "GraphEdit", theme->get_icon(SNAME("SnapGrid"), SNAME("EditorIcons"))); - theme->set_icon("minimap", "GraphEdit", theme->get_icon(SNAME("GridMinimap"), SNAME("EditorIcons"))); - theme->set_icon("layout", "GraphEdit", theme->get_icon(SNAME("GridLayout"), SNAME("EditorIcons"))); - theme->set_constant("bezier_len_pos", "GraphEdit", 80 * EDSCALE); - theme->set_constant("bezier_len_neg", "GraphEdit", 160 * EDSCALE); + theme->set_color(SNAME("selection_fill"), SNAME("GraphEdit"), theme->get_color(SNAME("box_selection_fill_color"), SNAME("Editor"))); + theme->set_color(SNAME("selection_stroke"), SNAME("GraphEdit"), theme->get_color(SNAME("box_selection_stroke_color"), SNAME("Editor"))); + theme->set_color(SNAME("activity"), SNAME("GraphEdit"), accent_color); + theme->set_icon(SNAME("minus"), SNAME("GraphEdit"), theme->get_icon(SNAME("ZoomLess"), SNAME("EditorIcons"))); + theme->set_icon(SNAME("more"), SNAME("GraphEdit"), theme->get_icon(SNAME("ZoomMore"), SNAME("EditorIcons"))); + theme->set_icon(SNAME("reset"), SNAME("GraphEdit"), theme->get_icon(SNAME("ZoomReset"), SNAME("EditorIcons"))); + theme->set_icon(SNAME("snap"), SNAME("GraphEdit"), theme->get_icon(SNAME("SnapGrid"), SNAME("EditorIcons"))); + theme->set_icon(SNAME("minimap"), SNAME("GraphEdit"), theme->get_icon(SNAME("GridMinimap"), SNAME("EditorIcons"))); + theme->set_icon(SNAME("layout"), SNAME("GraphEdit"), theme->get_icon(SNAME("GridLayout"), SNAME("EditorIcons"))); + theme->set_constant(SNAME("bezier_len_pos"), SNAME("GraphEdit"), 80 * EDSCALE); + theme->set_constant(SNAME("bezier_len_neg"), SNAME("GraphEdit"), 160 * EDSCALE); // GraphEditMinimap Ref<StyleBoxFlat> style_minimap_bg = make_flat_stylebox(dark_color_1, 0, 0, 0, 0); style_minimap_bg->set_border_color(dark_color_3); style_minimap_bg->set_border_width_all(1); - theme->set_stylebox("bg", "GraphEditMinimap", style_minimap_bg); + theme->set_stylebox(SNAME("bg"), SNAME("GraphEditMinimap"), style_minimap_bg); Ref<StyleBoxFlat> style_minimap_camera; Ref<StyleBoxFlat> style_minimap_node; @@ -1363,8 +1363,8 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) { } style_minimap_camera->set_border_width_all(1); style_minimap_node->set_corner_radius_all(1); - theme->set_stylebox("camera", "GraphEditMinimap", style_minimap_camera); - theme->set_stylebox("node", "GraphEditMinimap", style_minimap_node); + theme->set_stylebox(SNAME("camera"), SNAME("GraphEditMinimap"), style_minimap_camera); + theme->set_stylebox(SNAME("node"), SNAME("GraphEditMinimap"), style_minimap_node); Ref<Texture2D> minimap_resizer_icon = theme->get_icon(SNAME("GuiResizer"), SNAME("EditorIcons")); Color minimap_resizer_color; @@ -1373,8 +1373,8 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) { } else { minimap_resizer_color = Color(0, 0, 0, 0.65); } - theme->set_icon("resizer", "GraphEditMinimap", flip_icon(minimap_resizer_icon, true, true)); - theme->set_color("resizer_color", "GraphEditMinimap", minimap_resizer_color); + theme->set_icon(SNAME("resizer"), SNAME("GraphEditMinimap"), flip_icon(minimap_resizer_icon, true, true)); + theme->set_color(SNAME("resizer_color"), SNAME("GraphEditMinimap"), minimap_resizer_color); // GraphNode const int gn_margin_side = 28; @@ -1413,93 +1413,93 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) { graphsbcomment->set_border_width(SIDE_TOP, 24 * EDSCALE); graphsbcommentselected->set_border_width(SIDE_TOP, 24 * EDSCALE); - theme->set_stylebox("frame", "GraphNode", graphsb); - theme->set_stylebox("selectedframe", "GraphNode", graphsbselected); - theme->set_stylebox("comment", "GraphNode", graphsbcomment); - theme->set_stylebox("commentfocus", "GraphNode", graphsbcommentselected); - theme->set_stylebox("breakpoint", "GraphNode", graphsbbreakpoint); - theme->set_stylebox("position", "GraphNode", graphsbposition); - theme->set_stylebox("state_machine_frame", "GraphNode", smgraphsb); - theme->set_stylebox("state_machine_selectedframe", "GraphNode", smgraphsbselected); + theme->set_stylebox(SNAME("frame"), SNAME("GraphNode"), graphsb); + theme->set_stylebox(SNAME("selectedframe"), SNAME("GraphNode"), graphsbselected); + theme->set_stylebox(SNAME("comment"), SNAME("GraphNode"), graphsbcomment); + theme->set_stylebox(SNAME("commentfocus"), SNAME("GraphNode"), graphsbcommentselected); + theme->set_stylebox(SNAME("breakpoint"), SNAME("GraphNode"), graphsbbreakpoint); + theme->set_stylebox(SNAME("position"), SNAME("GraphNode"), graphsbposition); + theme->set_stylebox(SNAME("state_machine_frame"), SNAME("GraphNode"), smgraphsb); + theme->set_stylebox(SNAME("state_machine_selectedframe"), SNAME("GraphNode"), smgraphsbselected); Color default_node_color = dark_color_1.inverted(); - theme->set_color("title_color", "GraphNode", default_node_color); + theme->set_color(SNAME("title_color"), SNAME("GraphNode"), default_node_color); default_node_color.a = 0.7; - theme->set_color("close_color", "GraphNode", default_node_color); - theme->set_color("resizer_color", "GraphNode", default_node_color); + theme->set_color(SNAME("close_color"), SNAME("GraphNode"), default_node_color); + theme->set_color(SNAME("resizer_color"), SNAME("GraphNode"), default_node_color); - theme->set_constant("port_offset", "GraphNode", 14 * EDSCALE); - theme->set_constant("title_h_offset", "GraphNode", -16 * EDSCALE); - theme->set_constant("title_offset", "GraphNode", 20 * EDSCALE); - theme->set_constant("close_h_offset", "GraphNode", 20 * EDSCALE); - theme->set_constant("close_offset", "GraphNode", 20 * EDSCALE); - theme->set_constant("separation", "GraphNode", 1 * EDSCALE); + theme->set_constant(SNAME("port_offset"), SNAME("GraphNode"), 14 * EDSCALE); + theme->set_constant(SNAME("title_h_offset"), SNAME("GraphNode"), -16 * EDSCALE); + theme->set_constant(SNAME("title_offset"), SNAME("GraphNode"), 20 * EDSCALE); + theme->set_constant(SNAME("close_h_offset"), SNAME("GraphNode"), 20 * EDSCALE); + theme->set_constant(SNAME("close_offset"), SNAME("GraphNode"), 20 * EDSCALE); + theme->set_constant(SNAME("separation"), SNAME("GraphNode"), 1 * EDSCALE); - theme->set_icon("close", "GraphNode", theme->get_icon(SNAME("GuiCloseCustomizable"), SNAME("EditorIcons"))); - theme->set_icon("resizer", "GraphNode", theme->get_icon(SNAME("GuiResizer"), SNAME("EditorIcons"))); - theme->set_icon("port", "GraphNode", theme->get_icon(SNAME("GuiGraphNodePort"), SNAME("EditorIcons"))); + theme->set_icon(SNAME("close"), SNAME("GraphNode"), theme->get_icon(SNAME("GuiCloseCustomizable"), SNAME("EditorIcons"))); + theme->set_icon(SNAME("resizer"), SNAME("GraphNode"), theme->get_icon(SNAME("GuiResizer"), SNAME("EditorIcons"))); + theme->set_icon(SNAME("port"), SNAME("GraphNode"), theme->get_icon(SNAME("GuiGraphNodePort"), SNAME("EditorIcons"))); // GridContainer - theme->set_constant("vseparation", "GridContainer", Math::round(widget_default_margin.y - 2 * EDSCALE)); + theme->set_constant(SNAME("vseparation"), SNAME("GridContainer"), Math::round(widget_default_margin.y - 2 * EDSCALE)); // FileDialog - theme->set_icon("folder", "FileDialog", theme->get_icon(SNAME("Folder"), SNAME("EditorIcons"))); - theme->set_icon("parent_folder", "FileDialog", theme->get_icon(SNAME("ArrowUp"), SNAME("EditorIcons"))); - theme->set_icon("back_folder", "FileDialog", theme->get_icon(SNAME("Back"), SNAME("EditorIcons"))); - theme->set_icon("forward_folder", "FileDialog", theme->get_icon(SNAME("Forward"), SNAME("EditorIcons"))); - theme->set_icon("reload", "FileDialog", theme->get_icon(SNAME("Reload"), SNAME("EditorIcons"))); - theme->set_icon("toggle_hidden", "FileDialog", theme->get_icon(SNAME("GuiVisibilityVisible"), SNAME("EditorIcons"))); + theme->set_icon(SNAME("folder"), SNAME("FileDialog"), theme->get_icon(SNAME("Folder"), SNAME("EditorIcons"))); + theme->set_icon(SNAME("parent_folder"), SNAME("FileDialog"), theme->get_icon(SNAME("ArrowUp"), SNAME("EditorIcons"))); + theme->set_icon(SNAME("back_folder"), SNAME("FileDialog"), theme->get_icon(SNAME("Back"), SNAME("EditorIcons"))); + theme->set_icon(SNAME("forward_folder"), SNAME("FileDialog"), theme->get_icon(SNAME("Forward"), SNAME("EditorIcons"))); + theme->set_icon(SNAME("reload"), SNAME("FileDialog"), theme->get_icon(SNAME("Reload"), SNAME("EditorIcons"))); + theme->set_icon(SNAME("toggle_hidden"), SNAME("FileDialog"), theme->get_icon(SNAME("GuiVisibilityVisible"), SNAME("EditorIcons"))); // Use a different color for folder icons to make them easier to distinguish from files. // On a light theme, the icon will be dark, so we need to lighten it before blending it with the accent color. - theme->set_color("folder_icon_modulate", "FileDialog", (dark_theme ? Color(1, 1, 1) : Color(4.25, 4.25, 4.25)).lerp(accent_color, 0.7)); - theme->set_color("files_disabled", "FileDialog", font_disabled_color); + theme->set_color(SNAME("folder_icon_modulate"), SNAME("FileDialog"), (dark_theme ? Color(1, 1, 1) : Color(4.25, 4.25, 4.25)).lerp(accent_color, 0.7)); + theme->set_color(SNAME("files_disabled"), SNAME("FileDialog"), font_disabled_color); // ColorPicker - theme->set_constant("margin", "ColorPicker", popup_margin_size); - theme->set_constant("sv_width", "ColorPicker", 256 * EDSCALE); - theme->set_constant("sv_height", "ColorPicker", 256 * EDSCALE); - theme->set_constant("h_width", "ColorPicker", 30 * EDSCALE); - theme->set_constant("label_width", "ColorPicker", 10 * EDSCALE); - theme->set_icon("screen_picker", "ColorPicker", theme->get_icon(SNAME("ColorPick"), SNAME("EditorIcons"))); - theme->set_icon("add_preset", "ColorPicker", theme->get_icon(SNAME("Add"), SNAME("EditorIcons"))); - theme->set_icon("sample_bg", "ColorPicker", theme->get_icon(SNAME("GuiMiniCheckerboard"), SNAME("EditorIcons"))); - theme->set_icon("overbright_indicator", "ColorPicker", theme->get_icon(SNAME("OverbrightIndicator"), SNAME("EditorIcons"))); - theme->set_icon("bar_arrow", "ColorPicker", theme->get_icon(SNAME("ColorPickerBarArrow"), SNAME("EditorIcons"))); - theme->set_icon("picker_cursor", "ColorPicker", theme->get_icon(SNAME("PickerCursor"), SNAME("EditorIcons"))); + theme->set_constant(SNAME("margin"), SNAME("ColorPicker"), popup_margin_size); + theme->set_constant(SNAME("sv_width"), SNAME("ColorPicker"), 256 * EDSCALE); + theme->set_constant(SNAME("sv_height"), SNAME("ColorPicker"), 256 * EDSCALE); + theme->set_constant(SNAME("h_width"), SNAME("ColorPicker"), 30 * EDSCALE); + theme->set_constant(SNAME("label_width"), SNAME("ColorPicker"), 10 * EDSCALE); + theme->set_icon(SNAME("screen_picker"), SNAME("ColorPicker"), theme->get_icon(SNAME("ColorPick"), SNAME("EditorIcons"))); + theme->set_icon(SNAME("add_preset"), SNAME("ColorPicker"), theme->get_icon(SNAME("Add"), SNAME("EditorIcons"))); + theme->set_icon(SNAME("sample_bg"), SNAME("ColorPicker"), theme->get_icon(SNAME("GuiMiniCheckerboard"), SNAME("EditorIcons"))); + theme->set_icon(SNAME("overbright_indicator"), SNAME("ColorPicker"), theme->get_icon(SNAME("OverbrightIndicator"), SNAME("EditorIcons"))); + theme->set_icon(SNAME("bar_arrow"), SNAME("ColorPicker"), theme->get_icon(SNAME("ColorPickerBarArrow"), SNAME("EditorIcons"))); + theme->set_icon(SNAME("picker_cursor"), SNAME("ColorPicker"), theme->get_icon(SNAME("PickerCursor"), SNAME("EditorIcons"))); // ColorPickerButton - theme->set_icon("bg", "ColorPickerButton", theme->get_icon(SNAME("GuiMiniCheckerboard"), SNAME("EditorIcons"))); + theme->set_icon(SNAME("bg"), SNAME("ColorPickerButton"), theme->get_icon(SNAME("GuiMiniCheckerboard"), SNAME("EditorIcons"))); // ColorPresetButton Ref<StyleBoxFlat> preset_sb = make_flat_stylebox(Color(1, 1, 1), 2, 2, 2, 2, 2); preset_sb->set_anti_aliased(false); - theme->set_stylebox("preset_fg", "ColorPresetButton", preset_sb); - theme->set_icon("preset_bg", "ColorPresetButton", theme->get_icon(SNAME("GuiMiniCheckerboard"), SNAME("EditorIcons"))); - theme->set_icon("overbright_indicator", "ColorPresetButton", theme->get_icon(SNAME("OverbrightIndicator"), SNAME("EditorIcons"))); + theme->set_stylebox(SNAME("preset_fg"), SNAME("ColorPresetButton"), preset_sb); + theme->set_icon(SNAME("preset_bg"), SNAME("ColorPresetButton"), theme->get_icon(SNAME("GuiMiniCheckerboard"), SNAME("EditorIcons"))); + theme->set_icon(SNAME("overbright_indicator"), SNAME("ColorPresetButton"), theme->get_icon(SNAME("OverbrightIndicator"), SNAME("EditorIcons"))); // Information on 3D viewport Ref<StyleBoxFlat> style_info_3d_viewport = style_default->duplicate(); style_info_3d_viewport->set_bg_color(style_info_3d_viewport->get_bg_color() * Color(1, 1, 1, 0.5)); style_info_3d_viewport->set_border_width_all(0); - theme->set_stylebox("Information3dViewport", "EditorStyles", style_info_3d_viewport); + theme->set_stylebox(SNAME("Information3dViewport"), SNAME("EditorStyles"), style_info_3d_viewport); // Asset Library. - theme->set_stylebox("panel", "AssetLib", style_content_panel); - theme->set_color("status_color", "AssetLib", Color(0.5, 0.5, 0.5)); - theme->set_icon("dismiss", "AssetLib", theme->get_icon(SNAME("Close"), SNAME("EditorIcons"))); + theme->set_stylebox(SNAME("panel"), SNAME("AssetLib"), style_content_panel); + theme->set_color(SNAME("status_color"), SNAME("AssetLib"), Color(0.5, 0.5, 0.5)); + theme->set_icon(SNAME("dismiss"), SNAME("AssetLib"), theme->get_icon(SNAME("Close"), SNAME("EditorIcons"))); // Theme editor. - theme->set_color("preview_picker_overlay_color", "ThemeEditor", Color(0.1, 0.1, 0.1, 0.25)); + theme->set_color(SNAME("preview_picker_overlay_color"), SNAME("ThemeEditor"), Color(0.1, 0.1, 0.1, 0.25)); Color theme_preview_picker_bg_color = accent_color; theme_preview_picker_bg_color.a = 0.2; Ref<StyleBoxFlat> theme_preview_picker_sb = make_flat_stylebox(theme_preview_picker_bg_color, 0, 0, 0, 0); theme_preview_picker_sb->set_border_color(accent_color); theme_preview_picker_sb->set_border_width_all(1.0 * EDSCALE); - theme->set_stylebox("preview_picker_overlay", "ThemeEditor", theme_preview_picker_sb); + theme->set_stylebox(SNAME("preview_picker_overlay"), SNAME("ThemeEditor"), theme_preview_picker_sb); Color theme_preview_picker_label_bg_color = accent_color; theme_preview_picker_label_bg_color.set_v(0.5); Ref<StyleBoxFlat> theme_preview_picker_label_sb = make_flat_stylebox(theme_preview_picker_label_bg_color, 4.0, 1.0, 4.0, 3.0); - theme->set_stylebox("preview_picker_label", "ThemeEditor", theme_preview_picker_label_sb); + theme->set_stylebox(SNAME("preview_picker_label"), SNAME("ThemeEditor"), theme_preview_picker_label_sb); // adaptive script theme constants // for comments and elements with lower relevance @@ -1593,27 +1593,27 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) { } // Now theme is loaded, apply it to CodeEdit. - theme->set_color("background_color", "CodeEdit", EDITOR_GET("text_editor/theme/highlighting/background_color")); - theme->set_color("completion_background_color", "CodeEdit", EDITOR_GET("text_editor/theme/highlighting/completion_background_color")); - theme->set_color("completion_selected_color", "CodeEdit", EDITOR_GET("text_editor/theme/highlighting/completion_selected_color")); - theme->set_color("completion_existing_color", "CodeEdit", EDITOR_GET("text_editor/theme/highlighting/completion_existing_color")); - theme->set_color("completion_scroll_color", "CodeEdit", EDITOR_GET("text_editor/theme/highlighting/completion_scroll_color")); - theme->set_color("completion_font_color", "CodeEdit", EDITOR_GET("text_editor/theme/highlighting/completion_font_color")); - theme->set_color("font_color", "CodeEdit", EDITOR_GET("text_editor/theme/highlighting/text_color")); - theme->set_color("line_number_color", "CodeEdit", EDITOR_GET("text_editor/theme/highlighting/line_number_color")); - theme->set_color("caret_color", "CodeEdit", EDITOR_GET("text_editor/theme/highlighting/caret_color")); - theme->set_color("font_selected_color", "CodeEdit", EDITOR_GET("text_editor/theme/highlighting/text_selected_color")); - theme->set_color("selection_color", "CodeEdit", EDITOR_GET("text_editor/theme/highlighting/selection_color")); - theme->set_color("brace_mismatch_color", "CodeEdit", EDITOR_GET("text_editor/theme/highlighting/brace_mismatch_color")); - theme->set_color("current_line_color", "CodeEdit", EDITOR_GET("text_editor/theme/highlighting/current_line_color")); - theme->set_color("line_length_guideline_color", "CodeEdit", EDITOR_GET("text_editor/theme/highlighting/line_length_guideline_color")); - theme->set_color("word_highlighted_color", "CodeEdit", EDITOR_GET("text_editor/theme/highlighting/word_highlighted_color")); - theme->set_color("bookmark_color", "CodeEdit", EDITOR_GET("text_editor/theme/highlighting/bookmark_color")); - theme->set_color("breakpoint_color", "CodeEdit", EDITOR_GET("text_editor/theme/highlighting/breakpoint_color")); - theme->set_color("executing_line_color", "CodeEdit", EDITOR_GET("text_editor/theme/highlighting/executing_line_color")); - theme->set_color("code_folding_color", "CodeEdit", EDITOR_GET("text_editor/theme/highlighting/code_folding_color")); - theme->set_color("search_result_color", "CodeEdit", EDITOR_GET("text_editor/theme/highlighting/search_result_color")); - theme->set_color("search_result_border_color", "CodeEdit", EDITOR_GET("text_editor/theme/highlighting/search_result_border_color")); + theme->set_color(SNAME("background_color"), SNAME("CodeEdit"), EDITOR_GET("text_editor/theme/highlighting/background_color")); + theme->set_color(SNAME("completion_background_color"), SNAME("CodeEdit"), EDITOR_GET("text_editor/theme/highlighting/completion_background_color")); + theme->set_color(SNAME("completion_selected_color"), SNAME("CodeEdit"), EDITOR_GET("text_editor/theme/highlighting/completion_selected_color")); + theme->set_color(SNAME("completion_existing_color"), SNAME("CodeEdit"), EDITOR_GET("text_editor/theme/highlighting/completion_existing_color")); + theme->set_color(SNAME("completion_scroll_color"), SNAME("CodeEdit"), EDITOR_GET("text_editor/theme/highlighting/completion_scroll_color")); + theme->set_color(SNAME("completion_font_color"), SNAME("CodeEdit"), EDITOR_GET("text_editor/theme/highlighting/completion_font_color")); + theme->set_color(SNAME("font_color"), SNAME("CodeEdit"), EDITOR_GET("text_editor/theme/highlighting/text_color")); + theme->set_color(SNAME("line_number_color"), SNAME("CodeEdit"), EDITOR_GET("text_editor/theme/highlighting/line_number_color")); + theme->set_color(SNAME("caret_color"), SNAME("CodeEdit"), EDITOR_GET("text_editor/theme/highlighting/caret_color")); + theme->set_color(SNAME("font_selected_color"), SNAME("CodeEdit"), EDITOR_GET("text_editor/theme/highlighting/text_selected_color")); + theme->set_color(SNAME("selection_color"), SNAME("CodeEdit"), EDITOR_GET("text_editor/theme/highlighting/selection_color")); + theme->set_color(SNAME("brace_mismatch_color"), SNAME("CodeEdit"), EDITOR_GET("text_editor/theme/highlighting/brace_mismatch_color")); + theme->set_color(SNAME("current_line_color"), SNAME("CodeEdit"), EDITOR_GET("text_editor/theme/highlighting/current_line_color")); + theme->set_color(SNAME("line_length_guideline_color"), SNAME("CodeEdit"), EDITOR_GET("text_editor/theme/highlighting/line_length_guideline_color")); + theme->set_color(SNAME("word_highlighted_color"), SNAME("CodeEdit"), EDITOR_GET("text_editor/theme/highlighting/word_highlighted_color")); + theme->set_color(SNAME("bookmark_color"), SNAME("CodeEdit"), EDITOR_GET("text_editor/theme/highlighting/bookmark_color")); + theme->set_color(SNAME("breakpoint_color"), SNAME("CodeEdit"), EDITOR_GET("text_editor/theme/highlighting/breakpoint_color")); + theme->set_color(SNAME("executing_line_color"), SNAME("CodeEdit"), EDITOR_GET("text_editor/theme/highlighting/executing_line_color")); + theme->set_color(SNAME("code_folding_color"), SNAME("CodeEdit"), EDITOR_GET("text_editor/theme/highlighting/code_folding_color")); + theme->set_color(SNAME("search_result_color"), SNAME("CodeEdit"), EDITOR_GET("text_editor/theme/highlighting/search_result_color")); + theme->set_color(SNAME("search_result_border_color"), SNAME("CodeEdit"), EDITOR_GET("text_editor/theme/highlighting/search_result_border_color")); return theme; } diff --git a/editor/editor_toaster.cpp b/editor/editor_toaster.cpp index 6c9e4ab0fc..f326c9fc37 100644 --- a/editor/editor_toaster.cpp +++ b/editor/editor_toaster.cpp @@ -113,22 +113,22 @@ void EditorToaster::_notification(int p_what) { disable_notifications_button->set_icon(get_theme_icon(SNAME("NotificationDisabled"), SNAME("EditorIcons"))); // Styleboxes background. - info_panel_style_background->set_bg_color(get_theme_color("base_color", "Editor")); + info_panel_style_background->set_bg_color(get_theme_color(SNAME("base_color"), SNAME("Editor"))); - warning_panel_style_background->set_bg_color(get_theme_color("base_color", "Editor")); - warning_panel_style_background->set_border_color(get_theme_color("warning_color", "Editor")); + warning_panel_style_background->set_bg_color(get_theme_color(SNAME("base_color"), SNAME("Editor"))); + warning_panel_style_background->set_border_color(get_theme_color(SNAME("warning_color"), SNAME("Editor"))); - error_panel_style_background->set_bg_color(get_theme_color("base_color", "Editor")); - error_panel_style_background->set_border_color(get_theme_color("error_color", "Editor")); + error_panel_style_background->set_bg_color(get_theme_color(SNAME("base_color"), SNAME("Editor"))); + error_panel_style_background->set_border_color(get_theme_color(SNAME("error_color"), SNAME("Editor"))); // Styleboxes progress. - info_panel_style_progress->set_bg_color(get_theme_color("base_color", "Editor").lightened(0.03)); + info_panel_style_progress->set_bg_color(get_theme_color(SNAME("base_color"), SNAME("Editor")).lightened(0.03)); - warning_panel_style_progress->set_bg_color(get_theme_color("base_color", "Editor").lightened(0.03)); - warning_panel_style_progress->set_border_color(get_theme_color("warning_color", "Editor")); + warning_panel_style_progress->set_bg_color(get_theme_color(SNAME("base_color"), SNAME("Editor")).lightened(0.03)); + warning_panel_style_progress->set_border_color(get_theme_color(SNAME("warning_color"), SNAME("Editor"))); - error_panel_style_progress->set_bg_color(get_theme_color("base_color", "Editor").lightened(0.03)); - error_panel_style_progress->set_border_color(get_theme_color("error_color", "Editor")); + error_panel_style_progress->set_bg_color(get_theme_color(SNAME("base_color"), SNAME("Editor")).lightened(0.03)); + error_panel_style_progress->set_border_color(get_theme_color(SNAME("error_color"), SNAME("Editor"))); main_button->update(); disable_notifications_button->update(); @@ -256,13 +256,13 @@ void EditorToaster::_draw_button() { real_t button_radius = main_button->get_size().x / 8; switch (highest_severity) { case SEVERITY_INFO: - color = get_theme_color("accent_color", "Editor"); + color = get_theme_color(SNAME("accent_color"), SNAME("Editor")); break; case SEVERITY_WARNING: - color = get_theme_color("warning_color", "Editor"); + color = get_theme_color(SNAME("warning_color"), SNAME("Editor")); break; case SEVERITY_ERROR: - color = get_theme_color("error_color", "Editor"); + color = get_theme_color(SNAME("error_color"), SNAME("Editor")); break; default: break; @@ -333,13 +333,13 @@ Control *EditorToaster::popup(Control *p_control, Severity p_severity, double p_ panel->set_tooltip(p_tooltip); switch (p_severity) { case SEVERITY_INFO: - panel->add_theme_style_override("panel", info_panel_style_background); + panel->add_theme_style_override(SNAME("panel"), info_panel_style_background); break; case SEVERITY_WARNING: - panel->add_theme_style_override("panel", warning_panel_style_background); + panel->add_theme_style_override(SNAME("panel"), warning_panel_style_background); break; case SEVERITY_ERROR: - panel->add_theme_style_override("panel", error_panel_style_background); + panel->add_theme_style_override(SNAME("panel"), error_panel_style_background); break; default: break; @@ -360,7 +360,7 @@ Control *EditorToaster::popup(Control *p_control, Severity p_severity, double p_ if (p_time > 0.0) { Button *close_button = memnew(Button); close_button->set_flat(true); - close_button->set_icon(get_theme_icon("Close", "EditorIcons")); + close_button->set_icon(get_theme_icon(SNAME("Close"), SNAME("EditorIcons"))); close_button->connect("pressed", callable_bind(callable_mp(this, &EditorToaster::close), panel)); close_button->connect("theme_changed", callable_bind(callable_mp(this, &EditorToaster::_close_button_theme_changed), close_button)); hbox_container->add_child(close_button); @@ -442,7 +442,7 @@ void EditorToaster::close(Control *p_control) { void EditorToaster::_close_button_theme_changed(Control *p_close_button) { Button *close_button = Object::cast_to<Button>(p_close_button); if (close_button) { - close_button->set_icon(get_theme_icon("Close", "EditorIcons")); + close_button->set_icon(get_theme_icon(SNAME("Close"), SNAME("EditorIcons"))); } } @@ -508,7 +508,7 @@ EditorToaster::EditorToaster() { // Disable notification button. disable_notifications_panel = memnew(PanelContainer); disable_notifications_panel->set_as_top_level(true); - disable_notifications_panel->add_theme_style_override("panel", info_panel_style_background); + disable_notifications_panel->add_theme_style_override(SNAME("panel"), info_panel_style_background); add_child(disable_notifications_panel); disable_notifications_button = memnew(Button); diff --git a/editor/editor_zoom_widget.cpp b/editor/editor_zoom_widget.cpp index abfa383297..8d258ba2e1 100644 --- a/editor/editor_zoom_widget.cpp +++ b/editor/editor_zoom_widget.cpp @@ -176,9 +176,9 @@ EditorZoomWidget::EditorZoomWidget() { zoom_reset = memnew(Button); zoom_reset->set_flat(true); add_child(zoom_reset); - zoom_reset->add_theme_constant_override("outline_size", 1); - zoom_reset->add_theme_color_override("font_outline_color", Color(0, 0, 0)); - zoom_reset->add_theme_color_override("font_color", Color(1, 1, 1)); + zoom_reset->add_theme_constant_override(SNAME("outline_size"), 1); + zoom_reset->add_theme_color_override(SNAME("font_outline_color"), Color(0, 0, 0)); + zoom_reset->add_theme_color_override(SNAME("font_color"), Color(1, 1, 1)); zoom_reset->connect("pressed", callable_mp(this, &EditorZoomWidget::_button_zoom_reset)); zoom_reset->set_shortcut(ED_SHORTCUT("canvas_item_editor/zoom_reset", TTR("Zoom Reset"), KeyModifierMask::CMD | Key::KEY_0)); zoom_reset->set_shortcut_context(this); @@ -197,5 +197,5 @@ EditorZoomWidget::EditorZoomWidget() { _update_zoom_label(); - add_theme_constant_override("separation", Math::round(-8 * EDSCALE)); + add_theme_constant_override(SNAME("separation"), Math::round(-8 * EDSCALE)); } diff --git a/editor/export_template_manager.cpp b/editor/export_template_manager.cpp index 8c34609e9c..9519224c12 100644 --- a/editor/export_template_manager.cpp +++ b/editor/export_template_manager.cpp @@ -357,9 +357,9 @@ void ExportTemplateManager::_set_current_progress_status(const String &p_status, download_progress_label->set_text(p_status); if (p_error) { - download_progress_label->add_theme_color_override("font_color", get_theme_color(SNAME("error_color"), SNAME("Editor"))); + download_progress_label->add_theme_color_override(SNAME("font_color"), get_theme_color(SNAME("error_color"), SNAME("Editor"))); } else { - download_progress_label->add_theme_color_override("font_color", get_theme_color(SNAME("font_color"), SNAME("Label"))); + download_progress_label->add_theme_color_override(SNAME("font_color"), get_theme_color(SNAME("font_color"), SNAME("Label"))); } } @@ -744,9 +744,9 @@ void ExportTemplateManager::_notification(int p_what) { switch (p_what) { case NOTIFICATION_ENTER_TREE: case NOTIFICATION_THEME_CHANGED: { - current_value->add_theme_font_override("font", get_theme_font(SNAME("main"), SNAME("EditorFonts"))); - current_missing_label->add_theme_color_override("font_color", get_theme_color(SNAME("error_color"), SNAME("Editor"))); - current_installed_label->add_theme_color_override("font_color", get_theme_color(SNAME("disabled_font_color"), SNAME("Editor"))); + current_value->add_theme_font_override(SNAME("font"), get_theme_font(SNAME("main"), SNAME("EditorFonts"))); + current_missing_label->add_theme_color_override(SNAME("font_color"), get_theme_color(SNAME("error_color"), SNAME("Editor"))); + current_installed_label->add_theme_color_override(SNAME("font_color"), get_theme_color(SNAME("disabled_font_color"), SNAME("Editor"))); mirror_options_button->set_icon(get_theme_icon(SNAME("GuiTabMenuHl"), SNAME("EditorIcons"))); } break; diff --git a/editor/filesystem_dock.cpp b/editor/filesystem_dock.cpp index a038da4c18..324aed5d02 100644 --- a/editor/filesystem_dock.cpp +++ b/editor/filesystem_dock.cpp @@ -2834,7 +2834,7 @@ FileSystemDock::FileSystemDock(EditorNode *p_editor) { add_child(top_vbc); HBoxContainer *toolbar_hbc = memnew(HBoxContainer); - toolbar_hbc->add_theme_constant_override("separation", 0); + toolbar_hbc->add_theme_constant_override(SNAME("separation"), 0); top_vbc->add_child(toolbar_hbc); button_hist_prev = memnew(Button); @@ -2873,7 +2873,7 @@ FileSystemDock::FileSystemDock(EditorNode *p_editor) { toolbar_hbc->add_child(button_toggle_display_mode); toolbar2_hbc = memnew(HBoxContainer); - toolbar2_hbc->add_theme_constant_override("separation", 0); + toolbar2_hbc->add_theme_constant_override(SNAME("separation"), 0); top_vbc->add_child(toolbar2_hbc); tree_search_box = memnew(LineEdit); diff --git a/editor/find_in_files.cpp b/editor/find_in_files.cpp index dd72def6ad..e2e5f89e23 100644 --- a/editor/find_in_files.cpp +++ b/editor/find_in_files.cpp @@ -567,8 +567,8 @@ FindInFilesPanel::FindInFilesPanel() { hbc->add_child(find_label); _search_text_label = memnew(Label); - _search_text_label->add_theme_font_override("font", EditorNode::get_singleton()->get_gui_base()->get_theme_font(SNAME("source"), SNAME("EditorFonts"))); - _search_text_label->add_theme_font_size_override("font_size", EditorNode::get_singleton()->get_gui_base()->get_theme_font_size(SNAME("source_size"), SNAME("EditorFonts"))); + _search_text_label->add_theme_font_override(SNAME("font"), EditorNode::get_singleton()->get_gui_base()->get_theme_font(SNAME("source"), SNAME("EditorFonts"))); + _search_text_label->add_theme_font_size_override(SNAME("font_size"), EditorNode::get_singleton()->get_gui_base()->get_theme_font_size(SNAME("source_size"), SNAME("EditorFonts"))); hbc->add_child(_search_text_label); _progress_bar = memnew(ProgressBar); @@ -596,8 +596,8 @@ FindInFilesPanel::FindInFilesPanel() { } _results_display = memnew(Tree); - _results_display->add_theme_font_override("font", EditorNode::get_singleton()->get_gui_base()->get_theme_font(SNAME("source"), SNAME("EditorFonts"))); - _results_display->add_theme_font_size_override("font_size", EditorNode::get_singleton()->get_gui_base()->get_theme_font_size(SNAME("source_size"), SNAME("EditorFonts"))); + _results_display->add_theme_font_override(SNAME("font"), EditorNode::get_singleton()->get_gui_base()->get_theme_font(SNAME("source"), SNAME("EditorFonts"))); + _results_display->add_theme_font_size_override(SNAME("font_size"), EditorNode::get_singleton()->get_gui_base()->get_theme_font_size(SNAME("source_size"), SNAME("EditorFonts"))); _results_display->set_v_size_flags(SIZE_EXPAND_FILL); _results_display->connect("item_selected", callable_mp(this, &FindInFilesPanel::_on_result_selected)); _results_display->connect("item_edited", callable_mp(this, &FindInFilesPanel::_on_item_edited)); @@ -689,8 +689,8 @@ void FindInFilesPanel::_notification(int p_what) { if (p_what == NOTIFICATION_PROCESS) { _progress_bar->set_as_ratio(_finder->get_progress()); } else if (p_what == NOTIFICATION_THEME_CHANGED) { - _search_text_label->add_theme_font_override("font", get_theme_font(SNAME("source"), SNAME("EditorFonts"))); - _results_display->add_theme_font_override("font", get_theme_font(SNAME("source"), SNAME("EditorFonts"))); + _search_text_label->add_theme_font_override(SNAME("font"), get_theme_font(SNAME("source"), SNAME("EditorFonts"))); + _results_display->add_theme_font_override(SNAME("font"), get_theme_font(SNAME("source"), SNAME("EditorFonts"))); } } diff --git a/editor/groups_editor.cpp b/editor/groups_editor.cpp index 1644bb9dbe..4753035686 100644 --- a/editor/groups_editor.cpp +++ b/editor/groups_editor.cpp @@ -448,7 +448,7 @@ GroupDialog::GroupDialog() { groups->set_allow_reselect(true); groups->set_allow_rmb_select(true); groups->set_v_size_flags(Control::SIZE_EXPAND_FILL); - groups->add_theme_constant_override("draw_guides", 1); + groups->add_theme_constant_override(SNAME("draw_guides"), 1); groups->connect("item_selected", callable_mp(this, &GroupDialog::_group_selected)); groups->connect("button_pressed", callable_mp(this, &GroupDialog::_modify_group_pressed)); groups->connect("item_edited", callable_mp(this, &GroupDialog::_group_renamed)); @@ -484,10 +484,10 @@ GroupDialog::GroupDialog() { nodes_to_add->set_hide_folding(true); nodes_to_add->set_select_mode(Tree::SELECT_MULTI); nodes_to_add->set_v_size_flags(Control::SIZE_EXPAND_FILL); - nodes_to_add->add_theme_constant_override("draw_guides", 1); + nodes_to_add->add_theme_constant_override(SNAME("draw_guides"), 1); HBoxContainer *add_filter_hbc = memnew(HBoxContainer); - add_filter_hbc->add_theme_constant_override("separate", 0); + add_filter_hbc->add_theme_constant_override(SNAME("separate"), 0); vbc_add->add_child(add_filter_hbc); add_filter = memnew(LineEdit); @@ -534,10 +534,10 @@ GroupDialog::GroupDialog() { nodes_to_remove->set_hide_root(true); nodes_to_remove->set_hide_folding(true); nodes_to_remove->set_select_mode(Tree::SELECT_MULTI); - nodes_to_remove->add_theme_constant_override("draw_guides", 1); + nodes_to_remove->add_theme_constant_override(SNAME("draw_guides"), 1); HBoxContainer *remove_filter_hbc = memnew(HBoxContainer); - remove_filter_hbc->add_theme_constant_override("separate", 0); + remove_filter_hbc->add_theme_constant_override(SNAME("separate"), 0); vbc_remove->add_child(remove_filter_hbc); remove_filter = memnew(LineEdit); @@ -733,8 +733,8 @@ GroupsEditor::GroupsEditor() { tree->set_v_size_flags(Control::SIZE_EXPAND_FILL); vbc->add_child(tree); tree->connect("button_pressed", callable_mp(this, &GroupsEditor::_modify_group)); - tree->add_theme_constant_override("draw_guides", 1); - add_theme_constant_override("separation", 3 * EDSCALE); + tree->add_theme_constant_override(SNAME("draw_guides"), 1); + add_theme_constant_override(SNAME("separation"), 3 * EDSCALE); _group_name_changed(""); } diff --git a/editor/import/dynamicfont_import_settings.cpp b/editor/import/dynamicfont_import_settings.cpp index 81b98c1d45..6f4966dd33 100644 --- a/editor/import/dynamicfont_import_settings.cpp +++ b/editor/import/dynamicfont_import_settings.cpp @@ -481,7 +481,7 @@ void DynamicFontImportSettings::_main_prop_changed(const String &p_edited_proper font_preview->get_data(0)->set_oversampling(import_settings_data->get("oversampling")); } } - font_preview_label->add_theme_font_override("font", font_preview); + font_preview_label->add_theme_font_override(SNAME("font"), font_preview); font_preview_label->update(); } @@ -495,7 +495,7 @@ void DynamicFontImportSettings::_variation_add() { vars_item->set_text(0, TTR("New configuration")); vars_item->set_editable(0, true); - vars_item->add_button(1, vars_list->get_theme_icon("Remove", "EditorIcons"), BUTTON_REMOVE_VAR, false, TTR("Remove Variation")); + vars_item->add_button(1, vars_list->get_theme_icon(SNAME("Remove"), SNAME("EditorIcons")), BUTTON_REMOVE_VAR, false, TTR("Remove Variation")); vars_item->set_button_color(1, 0, Color(1, 1, 1, 0.75)); Ref<DynamicFontImportSettingsData> import_variation_data; @@ -643,8 +643,8 @@ void DynamicFontImportSettings::_glyph_selected() { TreeItem *item = glyph_table->get_selected(); ERR_FAIL_NULL(item); - Color scol = glyph_table->get_theme_color("box_selection_fill_color", "Editor"); - Color fcol = glyph_table->get_theme_color("font_selected_color", "Editor"); + Color scol = glyph_table->get_theme_color(SNAME("box_selection_fill_color"), SNAME("Editor")); + Color fcol = glyph_table->get_theme_color(SNAME("font_selected_color"), SNAME("Editor")); scol.a = 1.f; int32_t c = item->get_metadata(glyph_table->get_selected_column()); @@ -705,8 +705,8 @@ void DynamicFontImportSettings::_edit_range(int32_t p_start, int32_t p_end) { TreeItem *root = glyph_table->create_item(); ERR_FAIL_NULL(root); - Color scol = glyph_table->get_theme_color("box_selection_fill_color", "Editor"); - Color fcol = glyph_table->get_theme_color("font_selected_color", "Editor"); + Color scol = glyph_table->get_theme_color(SNAME("box_selection_fill_color"), SNAME("Editor")); + Color fcol = glyph_table->get_theme_color(SNAME("font_selected_color"), SNAME("Editor")); scol.a = 1.f; TreeItem *item = nullptr; @@ -719,12 +719,12 @@ void DynamicFontImportSettings::_edit_range(int32_t p_start, int32_t p_end) { item->set_text(0, _pad_zeros(String::num_int64(c, 16))); item->set_text_alignment(0, HORIZONTAL_ALIGNMENT_LEFT); item->set_selectable(0, false); - item->set_custom_bg_color(0, glyph_table->get_theme_color("dark_color_3", "Editor")); + item->set_custom_bg_color(0, glyph_table->get_theme_color(SNAME("dark_color_3"), SNAME("Editor"))); } if (font_main->has_char(c)) { item->set_text(col + 1, String::chr(c)); item->set_custom_color(col + 1, Color(1, 1, 1)); - if (selected_chars.has(c) || (font_main->get_data(0).is_valid() && selected_glyphs.has(font_main->get_data(0)->get_glyph_index(get_theme_font_size("font_size") * 2, c)))) { + if (selected_chars.has(c) || (font_main->get_data(0).is_valid() && selected_glyphs.has(font_main->get_data(0)->get_glyph_index(get_theme_font_size(SNAME("font_size")) * 2, c)))) { item->set_custom_color(col + 1, fcol); item->set_custom_bg_color(col + 1, scol); } else { @@ -732,13 +732,13 @@ void DynamicFontImportSettings::_edit_range(int32_t p_start, int32_t p_end) { item->clear_custom_bg_color(col + 1); } } else { - item->set_custom_bg_color(col + 1, glyph_table->get_theme_color("dark_color_2", "Editor")); + item->set_custom_bg_color(col + 1, glyph_table->get_theme_color(SNAME("dark_color_2"), SNAME("Editor"))); } item->set_metadata(col + 1, c); item->set_text_alignment(col + 1, HORIZONTAL_ALIGNMENT_CENTER); item->set_selectable(col + 1, true); item->set_custom_font(col + 1, font_main); - item->set_custom_font_size(col + 1, get_theme_font_size("font_size") * 2); + item->set_custom_font_size(col + 1, get_theme_font_size(SNAME("font_size")) * 2); col++; if (col == 16) { @@ -752,8 +752,8 @@ bool DynamicFontImportSettings::_char_update(int32_t p_char) { if (selected_chars.has(p_char)) { selected_chars.erase(p_char); return false; - } else if (font_main->get_data(0).is_valid() && selected_glyphs.has(font_main->get_data(0)->get_glyph_index(get_theme_font_size("font_size") * 2, p_char))) { - selected_glyphs.erase(font_main->get_data(0)->get_glyph_index(get_theme_font_size("font_size") * 2, p_char)); + } else if (font_main->get_data(0).is_valid() && selected_glyphs.has(font_main->get_data(0)->get_glyph_index(get_theme_font_size(SNAME("font_size")) * 2, p_char))) { + selected_glyphs.erase(font_main->get_data(0)->get_glyph_index(get_theme_font_size(SNAME("font_size")) * 2, p_char)); return false; } else { selected_chars.insert(p_char); @@ -767,7 +767,7 @@ void DynamicFontImportSettings::_range_update(int32_t p_start, int32_t p_end) { for (int32_t i = p_start; i <= p_end; i++) { if (font_main->has_char(i)) { if (font_main->get_data(0).is_valid()) { - all_selected = all_selected && (selected_chars.has(i) || (font_main->get_data(0).is_valid() && selected_glyphs.has(font_main->get_data(0)->get_glyph_index(get_theme_font_size("font_size") * 2, i)))); + all_selected = all_selected && (selected_chars.has(i) || (font_main->get_data(0).is_valid() && selected_glyphs.has(font_main->get_data(0)->get_glyph_index(get_theme_font_size(SNAME("font_size")) * 2, i)))); } else { all_selected = all_selected && selected_chars.has(i); } @@ -780,7 +780,7 @@ void DynamicFontImportSettings::_range_update(int32_t p_start, int32_t p_end) { } else { selected_chars.erase(i); if (font_main->get_data(0).is_valid()) { - selected_glyphs.erase(font_main->get_data(0)->get_glyph_index(get_theme_font_size("font_size") * 2, i)); + selected_glyphs.erase(font_main->get_data(0)->get_glyph_index(get_theme_font_size(SNAME("font_size")) * 2, i)); } } } @@ -809,7 +809,7 @@ void DynamicFontImportSettings::_lang_add_item(const String &p_locale) { lang_item->set_checked(0, false); lang_item->set_text(1, p_locale); lang_item->set_editable(1, true); - lang_item->add_button(2, lang_list->get_theme_icon("Remove", "EditorIcons"), BUTTON_REMOVE_VAR, false, TTR("Remove")); + lang_item->add_button(2, lang_list->get_theme_icon(SNAME("Remove"), SNAME("EditorIcons")), BUTTON_REMOVE_VAR, false, TTR("Remove")); lang_item->set_button_color(2, 0, Color(1, 1, 1, 0.75)); } @@ -841,7 +841,7 @@ void DynamicFontImportSettings::_ot_add_item(int p_option) { ot_item->set_editable(0, false); ot_item->set_text(1, "1"); ot_item->set_editable(1, true); - ot_item->add_button(2, ot_list->get_theme_icon("Remove", "EditorIcons"), BUTTON_REMOVE_VAR, false, TTR("Remove")); + ot_item->add_button(2, ot_list->get_theme_icon(SNAME("Remove"), SNAME("EditorIcons")), BUTTON_REMOVE_VAR, false, TTR("Remove")); ot_item->set_button_color(2, 0, Color(1, 1, 1, 0.75)); } @@ -868,7 +868,7 @@ void DynamicFontImportSettings::_script_add_item(int p_option) { script_item->set_checked(0, false); script_item->set_text(1, script_codes[p_option]); script_item->set_editable(1, true); - script_item->add_button(2, lang_list->get_theme_icon("Remove", "EditorIcons"), BUTTON_REMOVE_VAR, false, TTR("Remove")); + script_item->add_button(2, lang_list->get_theme_icon(SNAME("Remove"), SNAME("EditorIcons")), BUTTON_REMOVE_VAR, false, TTR("Remove")); script_item->set_button_color(2, 0, Color(1, 1, 1, 0.75)); } @@ -895,10 +895,10 @@ void DynamicFontImportSettings::_notification(int p_what) { if (p_what == NOTIFICATION_READY) { connect("confirmed", callable_mp(this, &DynamicFontImportSettings::_re_import)); } else if (p_what == NOTIFICATION_ENTER_TREE || p_what == NOTIFICATION_THEME_CHANGED) { - add_lang->set_icon(add_var->get_theme_icon("Add", "EditorIcons")); - add_script->set_icon(add_var->get_theme_icon("Add", "EditorIcons")); - add_var->set_icon(add_var->get_theme_icon("Add", "EditorIcons")); - add_ot->set_icon(add_var->get_theme_icon("Add", "EditorIcons")); + add_lang->set_icon(add_var->get_theme_icon(SNAME("Add"), SNAME("EditorIcons"))); + add_script->set_icon(add_var->get_theme_icon(SNAME("Add"), SNAME("EditorIcons"))); + add_var->set_icon(add_var->get_theme_icon(SNAME("Add"), SNAME("EditorIcons"))); + add_ot->set_icon(add_var->get_theme_icon(SNAME("Add"), SNAME("EditorIcons"))); } } @@ -1036,14 +1036,14 @@ void DynamicFontImportSettings::open_settings(const String &p_path) { font_main.instantiate(); font_main->add_data(dfont_main); - text_edit->add_theme_font_override("font", font_main); + text_edit->add_theme_font_override(SNAME("font"), font_main); base_path = p_path; inspector_vars->edit(nullptr); inspector_general->edit(nullptr); - int gww = get_theme_font("font")->get_string_size("00000", get_theme_font_size("font_size")).x + 50; + int gww = get_theme_font(SNAME("font"))->get_string_size("00000", get_theme_font_size(SNAME("font_size"))).x + 50; glyph_table->set_column_custom_minimum_width(0, gww); glyph_table->clear(); @@ -1146,7 +1146,7 @@ void DynamicFontImportSettings::open_settings(const String &p_path) { vars_item->set_text(0, TTR("Configuration") + " " + itos(i)); vars_item->set_editable(0, true); - vars_item->add_button(1, vars_list->get_theme_icon("Remove", "EditorIcons"), BUTTON_REMOVE_VAR, false, TTR("Remove Variation")); + vars_item->add_button(1, vars_list->get_theme_icon(SNAME("Remove"), SNAME("EditorIcons")), BUTTON_REMOVE_VAR, false, TTR("Remove Variation")); vars_item->set_button_color(1, 0, Color(1, 1, 1, 0.75)); Ref<DynamicFontImportSettingsData> import_variation_data_custom; @@ -1184,7 +1184,7 @@ void DynamicFontImportSettings::open_settings(const String &p_path) { lang_item->set_checked(0, true); lang_item->set_text(1, _langs[i]); lang_item->set_editable(1, true); - lang_item->add_button(2, lang_list->get_theme_icon("Remove", "EditorIcons"), BUTTON_REMOVE_VAR, false, TTR("Remove")); + lang_item->add_button(2, lang_list->get_theme_icon(SNAME("Remove"), SNAME("EditorIcons")), BUTTON_REMOVE_VAR, false, TTR("Remove")); } } else if (key == "support_overrides/language_disabled") { PackedStringArray _langs = config->get_value("params", key); @@ -1197,7 +1197,7 @@ void DynamicFontImportSettings::open_settings(const String &p_path) { lang_item->set_checked(0, false); lang_item->set_text(1, _langs[i]); lang_item->set_editable(1, true); - lang_item->add_button(2, lang_list->get_theme_icon("Remove", "EditorIcons"), BUTTON_REMOVE_VAR, false, TTR("Remove")); + lang_item->add_button(2, lang_list->get_theme_icon(SNAME("Remove"), SNAME("EditorIcons")), BUTTON_REMOVE_VAR, false, TTR("Remove")); } } else if (key == "support_overrides/script_enabled") { PackedStringArray _scripts = config->get_value("params", key); @@ -1210,7 +1210,7 @@ void DynamicFontImportSettings::open_settings(const String &p_path) { script_item->set_checked(0, true); script_item->set_text(1, _scripts[i]); script_item->set_editable(1, true); - script_item->add_button(2, lang_list->get_theme_icon("Remove", "EditorIcons"), BUTTON_REMOVE_VAR, false, TTR("Remove")); + script_item->add_button(2, lang_list->get_theme_icon(SNAME("Remove"), SNAME("EditorIcons")), BUTTON_REMOVE_VAR, false, TTR("Remove")); } } else if (key == "support_overrides/script_disabled") { PackedStringArray _scripts = config->get_value("params", key); @@ -1223,7 +1223,7 @@ void DynamicFontImportSettings::open_settings(const String &p_path) { script_item->set_checked(0, false); script_item->set_text(1, _scripts[i]); script_item->set_editable(1, true); - script_item->add_button(2, lang_list->get_theme_icon("Remove", "EditorIcons"), BUTTON_REMOVE_VAR, false, TTR("Remove")); + script_item->add_button(2, lang_list->get_theme_icon(SNAME("Remove"), SNAME("EditorIcons")), BUTTON_REMOVE_VAR, false, TTR("Remove")); } } else if (key == "opentype_feature_overrides") { Dictionary features = config->get_value("params", key); @@ -1239,7 +1239,7 @@ void DynamicFontImportSettings::open_settings(const String &p_path) { ot_item->set_editable(0, false); ot_item->set_text(1, itos(value)); ot_item->set_editable(1, true); - ot_item->add_button(2, ot_list->get_theme_icon("Remove", "EditorIcons"), BUTTON_REMOVE_VAR, false, TTR("Remove")); + ot_item->add_button(2, ot_list->get_theme_icon(SNAME("Remove"), SNAME("EditorIcons")), BUTTON_REMOVE_VAR, false, TTR("Remove")); ot_item->set_button_color(2, 0, Color(1, 1, 1, 0.75)); } } else { @@ -1263,7 +1263,7 @@ void DynamicFontImportSettings::open_settings(const String &p_path) { font_preview->get_data(0)->set_hinting((TextServer::Hinting)import_settings_data->get("hinting").operator int()); font_preview->get_data(0)->set_oversampling(import_settings_data->get("oversampling")); } - font_preview_label->add_theme_font_override("font", font_preview); + font_preview_label->add_theme_font_override(SNAME("font"), font_preview); font_preview_label->update(); menu_ot->clear(); @@ -1356,7 +1356,7 @@ DynamicFontImportSettings::DynamicFontImportSettings() { menu_ot->add_child(menu_ot_cu); menu_ot_cu->connect("id_pressed", callable_mp(this, &DynamicFontImportSettings::_ot_add_item)); - Color warn_color = (EditorNode::get_singleton()) ? EditorNode::get_singleton()->get_gui_base()->get_theme_color("warning_color", "Editor") : Color(1, 1, 0); + Color warn_color = (EditorNode::get_singleton()) ? EditorNode::get_singleton()->get_gui_base()->get_theme_color(SNAME("warning_color"), SNAME("Editor")) : Color(1, 1, 0); // Root layout @@ -1372,7 +1372,7 @@ DynamicFontImportSettings::DynamicFontImportSettings() { label_warn->set_horizontal_alignment(HORIZONTAL_ALIGNMENT_CENTER); label_warn->set_text(""); root_vb->add_child(label_warn); - label_warn->add_theme_color_override("font_color", warn_color); + label_warn->add_theme_color_override(SNAME("font_color"), warn_color); label_warn->hide(); // Page 1 layout: Rendering Options @@ -1392,7 +1392,7 @@ DynamicFontImportSettings::DynamicFontImportSettings() { page1_vb->add_child(page1_hb); font_preview_label = memnew(Label); - font_preview_label->add_theme_font_size_override("font_size", 200 * EDSCALE); + font_preview_label->add_theme_font_size_override(SNAME("font_size"), 200 * EDSCALE); font_preview_label->set_horizontal_alignment(HORIZONTAL_ALIGNMENT_CENTER); font_preview_label->set_vertical_alignment(VERTICAL_ALIGNMENT_CENTER); font_preview_label->set_autowrap_mode(Label::AUTOWRAP_ARBITRARY); @@ -1438,7 +1438,7 @@ DynamicFontImportSettings::DynamicFontImportSettings() { add_var = memnew(Button); page2_hb_vars->add_child(add_var); add_var->set_tooltip(TTR("Add configuration")); - add_var->set_icon(add_var->get_theme_icon("Add", "EditorIcons")); + add_var->set_icon(add_var->get_theme_icon(SNAME("Add"), SNAME("EditorIcons"))); add_var->connect("pressed", callable_mp(this, &DynamicFontImportSettings::_variation_add)); vars_list = memnew(Tree); @@ -1545,9 +1545,9 @@ DynamicFontImportSettings::DynamicFontImportSettings() { for (int i = 0; i < 16; i++) { glyph_table->set_column_title(i + 1, String::num_int64(i, 16)); } - glyph_table->add_theme_style_override("selected", glyph_table->get_theme_stylebox("bg")); - glyph_table->add_theme_style_override("selected_focus", glyph_table->get_theme_stylebox("bg")); - glyph_table->add_theme_constant_override("hseparation", 0); + glyph_table->add_theme_style_override(SNAME("selected"), glyph_table->get_theme_stylebox(SNAME("bg"))); + glyph_table->add_theme_style_override(SNAME("selected_focus"), glyph_table->get_theme_stylebox(SNAME("bg"))); + glyph_table->add_theme_constant_override(SNAME("hseparation"), 0); glyph_table->set_h_size_flags(Control::SIZE_EXPAND_FILL); glyph_table->set_v_size_flags(Control::SIZE_EXPAND_FILL); @@ -1590,7 +1590,7 @@ DynamicFontImportSettings::DynamicFontImportSettings() { add_lang = memnew(Button); hb_lang->add_child(add_lang); add_lang->set_tooltip(TTR("Add language override")); - add_lang->set_icon(add_var->get_theme_icon("Add", "EditorIcons")); + add_lang->set_icon(add_var->get_theme_icon(SNAME("Add"), SNAME("EditorIcons"))); add_lang->connect("pressed", callable_mp(this, &DynamicFontImportSettings::_lang_add)); lang_list = memnew(Tree); @@ -1618,7 +1618,7 @@ DynamicFontImportSettings::DynamicFontImportSettings() { add_script = memnew(Button); hb_script->add_child(add_script); add_script->set_tooltip(TTR("Add script override")); - add_script->set_icon(add_var->get_theme_icon("Add", "EditorIcons")); + add_script->set_icon(add_var->get_theme_icon(SNAME("Add"), SNAME("EditorIcons"))); add_script->connect("pressed", callable_mp(this, &DynamicFontImportSettings::_script_add)); script_list = memnew(Tree); @@ -1646,7 +1646,7 @@ DynamicFontImportSettings::DynamicFontImportSettings() { add_ot = memnew(Button); hb_ot->add_child(add_ot); add_ot->set_tooltip(TTR("Add feature override")); - add_ot->set_icon(add_var->get_theme_icon("Add", "EditorIcons")); + add_ot->set_icon(add_var->get_theme_icon(SNAME("Add"), SNAME("EditorIcons"))); add_ot->connect("pressed", callable_mp(this, &DynamicFontImportSettings::_ot_add)); ot_list = memnew(Tree); diff --git a/editor/import/resource_importer_scene.cpp b/editor/import/resource_importer_scene.cpp index 5d356604f4..22a11e11cb 100644 --- a/editor/import/resource_importer_scene.cpp +++ b/editor/import/resource_importer_scene.cpp @@ -2088,18 +2088,26 @@ ResourceImporterScene::ResourceImporterScene() { singleton = this; } -void ResourceImporterScene::add_importer(Ref<EditorSceneFormatImporter> p_importer) { +void ResourceImporterScene::add_importer(Ref<EditorSceneFormatImporter> p_importer, bool p_first_priority) { ERR_FAIL_COND(p_importer.is_null()); - importers.insert(0, p_importer); + if (p_first_priority) { + importers.insert(0, p_importer); + } else { + importers.push_back(p_importer); + } } void ResourceImporterScene::remove_post_importer_plugin(const Ref<EditorScenePostImportPlugin> &p_plugin) { post_importer_plugins.erase(p_plugin); } -void ResourceImporterScene::add_post_importer_plugin(const Ref<EditorScenePostImportPlugin> &p_plugin) { +void ResourceImporterScene::add_post_importer_plugin(const Ref<EditorScenePostImportPlugin> &p_plugin, bool p_first_priority) { ERR_FAIL_COND(p_plugin.is_null()); - post_importer_plugins.insert(0, p_plugin); + if (p_first_priority) { + post_importer_plugins.insert(0, p_plugin); + } else { + post_importer_plugins.push_back(p_plugin); + } } void ResourceImporterScene::remove_importer(Ref<EditorSceneFormatImporter> p_importer) { diff --git a/editor/import/resource_importer_scene.h b/editor/import/resource_importer_scene.h index a3aeac4022..04fcc4268b 100644 --- a/editor/import/resource_importer_scene.h +++ b/editor/import/resource_importer_scene.h @@ -224,12 +224,12 @@ class ResourceImporterScene : public ResourceImporter { public: static ResourceImporterScene *get_singleton() { return singleton; } - void add_post_importer_plugin(const Ref<EditorScenePostImportPlugin> &p_plugin); + void add_post_importer_plugin(const Ref<EditorScenePostImportPlugin> &p_plugin, bool p_first_priority = false); void remove_post_importer_plugin(const Ref<EditorScenePostImportPlugin> &p_plugin); const Vector<Ref<EditorSceneFormatImporter>> &get_importers() const { return importers; } - void add_importer(Ref<EditorSceneFormatImporter> p_importer); + void add_importer(Ref<EditorSceneFormatImporter> p_importer, bool p_first_priority = false); void remove_importer(Ref<EditorSceneFormatImporter> p_importer); virtual String get_importer_name() const override; diff --git a/editor/import_dock.cpp b/editor/import_dock.cpp index f809747410..b76d31ec1f 100644 --- a/editor/import_dock.cpp +++ b/editor/import_dock.cpp @@ -561,12 +561,12 @@ void ImportDock::_reimport() { void ImportDock::_notification(int p_what) { switch (p_what) { case EditorSettings::NOTIFICATION_EDITOR_SETTINGS_CHANGED: { - imported->add_theme_style_override("normal", get_theme_stylebox(SNAME("normal"), SNAME("LineEdit"))); + imported->add_theme_style_override(SNAME("normal"), get_theme_stylebox(SNAME("normal"), SNAME("LineEdit"))); } break; case NOTIFICATION_ENTER_TREE: { import_opts->edit(params); - label_warning->add_theme_color_override("font_color", get_theme_color(SNAME("warning_color"), SNAME("Editor"))); + label_warning->add_theme_color_override(SNAME("font_color"), get_theme_color(SNAME("warning_color"), SNAME("Editor"))); } break; } } @@ -579,12 +579,12 @@ void ImportDock::_set_dirty(bool p_dirty) { if (p_dirty) { // Add a dirty marker to notify the user that they should reimport the selected resource to see changes. import->set_text(TTR("Reimport") + " (*)"); - import->add_theme_color_override("font_color", get_theme_color(SNAME("warning_color"), SNAME("Editor"))); + import->add_theme_color_override(SNAME("font_color"), get_theme_color(SNAME("warning_color"), SNAME("Editor"))); import->set_tooltip(TTR("You have pending changes that haven't been applied yet. Click Reimport to apply changes made to the import options.\nSelecting another resource in the FileSystem dock without clicking Reimport first will discard changes made in the Import dock.")); } else { // Remove the dirty marker on the Reimport button. import->set_text(TTR("Reimport")); - import->remove_theme_color_override("font_color"); + import->remove_theme_color_override(SNAME("font_color")); import->set_tooltip(""); } } @@ -617,7 +617,7 @@ ImportDock::ImportDock() { content->hide(); imported = memnew(Label); - imported->add_theme_style_override("normal", EditorNode::get_singleton()->get_gui_base()->get_theme_stylebox(SNAME("normal"), SNAME("LineEdit"))); + imported->add_theme_style_override(SNAME("normal"), EditorNode::get_singleton()->get_gui_base()->get_theme_stylebox(SNAME("normal"), SNAME("LineEdit"))); imported->set_clip_text(true); content->add_child(imported); HBoxContainer *hb = memnew(HBoxContainer); diff --git a/editor/inspector_dock.cpp b/editor/inspector_dock.cpp index e36c86fb10..95e50d90b9 100644 --- a/editor/inspector_dock.cpp +++ b/editor/inspector_dock.cpp @@ -422,7 +422,7 @@ void InspectorDock::_notification(int p_what) { object_menu->set_icon(get_theme_icon(SNAME("Tools"), SNAME("EditorIcons"))); search->set_right_icon(get_theme_icon(SNAME("Search"), SNAME("EditorIcons"))); warning->set_icon(get_theme_icon(SNAME("NodeWarning"), SNAME("EditorIcons"))); - warning->add_theme_color_override("font_color", get_theme_color(SNAME("warning_color"), SNAME("Editor"))); + warning->add_theme_color_override(SNAME("font_color"), get_theme_color(SNAME("warning_color"), SNAME("Editor"))); } break; } } diff --git a/editor/plugins/animation_blend_space_1d_editor.cpp b/editor/plugins/animation_blend_space_1d_editor.cpp index 3dcb769faf..9a350437a1 100644 --- a/editor/plugins/animation_blend_space_1d_editor.cpp +++ b/editor/plugins/animation_blend_space_1d_editor.cpp @@ -530,9 +530,9 @@ void AnimationNodeBlendSpace1DEditor::_open_editor() { void AnimationNodeBlendSpace1DEditor::_notification(int p_what) { if (p_what == NOTIFICATION_ENTER_TREE || p_what == NOTIFICATION_THEME_CHANGED) { - error_panel->add_theme_style_override("panel", get_theme_stylebox(SNAME("bg"), SNAME("Tree"))); - error_label->add_theme_color_override("font_color", get_theme_color(SNAME("error_color"), SNAME("Editor"))); - panel->add_theme_style_override("panel", get_theme_stylebox(SNAME("bg"), SNAME("Tree"))); + error_panel->add_theme_style_override(SNAME("panel"), get_theme_stylebox(SNAME("bg"), SNAME("Tree"))); + error_label->add_theme_color_override(SNAME("font_color"), get_theme_color(SNAME("error_color"), SNAME("Editor"))); + panel->add_theme_style_override(SNAME("panel"), get_theme_stylebox(SNAME("bg"), SNAME("Tree"))); tool_blend->set_icon(get_theme_icon(SNAME("EditPivot"), SNAME("EditorIcons"))); tool_select->set_icon(get_theme_icon(SNAME("ToolSelect"), SNAME("EditorIcons"))); tool_create->set_icon(get_theme_icon(SNAME("EditKey"), SNAME("EditorIcons"))); diff --git a/editor/plugins/animation_blend_space_2d_editor.cpp b/editor/plugins/animation_blend_space_2d_editor.cpp index f9df8db419..15d522d8e7 100644 --- a/editor/plugins/animation_blend_space_2d_editor.cpp +++ b/editor/plugins/animation_blend_space_2d_editor.cpp @@ -730,9 +730,9 @@ void AnimationNodeBlendSpace2DEditor::_edit_point_pos(double) { void AnimationNodeBlendSpace2DEditor::_notification(int p_what) { if (p_what == NOTIFICATION_ENTER_TREE || p_what == NOTIFICATION_THEME_CHANGED) { - error_panel->add_theme_style_override("panel", get_theme_stylebox(SNAME("bg"), SNAME("Tree"))); - error_label->add_theme_color_override("font_color", get_theme_color(SNAME("error_color"), SNAME("Editor"))); - panel->add_theme_style_override("panel", get_theme_stylebox(SNAME("bg"), SNAME("Tree"))); + error_panel->add_theme_style_override(SNAME("panel"), get_theme_stylebox(SNAME("bg"), SNAME("Tree"))); + error_label->add_theme_color_override(SNAME("font_color"), get_theme_color(SNAME("error_color"), SNAME("Editor"))); + panel->add_theme_style_override(SNAME("panel"), get_theme_stylebox(SNAME("bg"), SNAME("Tree"))); tool_blend->set_icon(get_theme_icon(SNAME("EditPivot"), SNAME("EditorIcons"))); tool_select->set_icon(get_theme_icon(SNAME("ToolSelect"), SNAME("EditorIcons"))); tool_create->set_icon(get_theme_icon(SNAME("EditKey"), SNAME("EditorIcons"))); diff --git a/editor/plugins/animation_blend_tree_editor_plugin.cpp b/editor/plugins/animation_blend_tree_editor_plugin.cpp index b000ff8eee..216405110b 100644 --- a/editor/plugins/animation_blend_tree_editor_plugin.cpp +++ b/editor/plugins/animation_blend_tree_editor_plugin.cpp @@ -243,10 +243,10 @@ void AnimationNodeBlendTreeEditor::_update_graph() { mono_color.a = 0.85; c = mono_color; - node->add_theme_color_override("title_color", c); + node->add_theme_color_override(SNAME("title_color"), c); c.a = 0.7; - node->add_theme_color_override("close_color", c); - node->add_theme_color_override("resizer_color", c); + node->add_theme_color_override(SNAME("close_color"), c); + node->add_theme_color_override(SNAME("resizer_color"), c); } List<AnimationNodeBlendTree::NodeConnection> connections; @@ -739,8 +739,8 @@ void AnimationNodeBlendTreeEditor::_notification(int p_what) { } if (p_what == NOTIFICATION_ENTER_TREE || p_what == NOTIFICATION_THEME_CHANGED) { - error_panel->add_theme_style_override("panel", get_theme_stylebox(SNAME("bg"), SNAME("Tree"))); - error_label->add_theme_color_override("font_color", get_theme_color(SNAME("error_color"), SNAME("Editor"))); + error_panel->add_theme_style_override(SNAME("panel"), get_theme_stylebox(SNAME("bg"), SNAME("Tree"))); + error_label->add_theme_color_override(SNAME("font_color"), get_theme_color(SNAME("error_color"), SNAME("Editor"))); if (p_what == NOTIFICATION_THEME_CHANGED && is_visible_in_tree()) { _update_graph(); diff --git a/editor/plugins/animation_player_editor_plugin.cpp b/editor/plugins/animation_player_editor_plugin.cpp index 320c47e820..2a1843fbf2 100644 --- a/editor/plugins/animation_player_editor_plugin.cpp +++ b/editor/plugins/animation_player_editor_plugin.cpp @@ -101,10 +101,10 @@ void AnimationPlayerEditor::_notification(int p_what) { get_tree()->connect("node_removed", callable_mp(this, &AnimationPlayerEditor::_node_removed)); - add_theme_style_override("panel", editor->get_gui_base()->get_theme_stylebox(SNAME("panel"), SNAME("Panel"))); + add_theme_style_override(SNAME("panel"), editor->get_gui_base()->get_theme_stylebox(SNAME("panel"), SNAME("Panel"))); } break; case EditorSettings::NOTIFICATION_EDITOR_SETTINGS_CHANGED: { - add_theme_style_override("panel", editor->get_gui_base()->get_theme_stylebox(SNAME("panel"), SNAME("Panel"))); + add_theme_style_override(SNAME("panel"), editor->get_gui_base()->get_theme_stylebox(SNAME("panel"), SNAME("Panel"))); } break; case NOTIFICATION_TRANSLATION_CHANGED: case NOTIFICATION_LAYOUT_DIRECTION_CHANGED: @@ -137,8 +137,8 @@ void AnimationPlayerEditor::_notification(int p_what) { pin->set_icon(get_theme_icon(SNAME("Pin"), SNAME("EditorIcons"))); - tool_anim->add_theme_style_override("normal", get_theme_stylebox(SNAME("normal"), SNAME("Button"))); - track_editor->get_edit_menu()->add_theme_style_override("normal", get_theme_stylebox(SNAME("normal"), SNAME("Button"))); + tool_anim->add_theme_style_override(SNAME("normal"), get_theme_stylebox(SNAME("normal"), SNAME("Button"))); + track_editor->get_edit_menu()->add_theme_style_override(SNAME("normal"), get_theme_stylebox(SNAME("normal"), SNAME("Button"))); #define ITEM_ICON(m_item, m_icon) tool_anim->get_popup()->set_item_icon(tool_anim->get_popup()->get_item_index(m_item), get_theme_icon(SNAME(m_icon), SNAME("EditorIcons"))) diff --git a/editor/plugins/animation_state_machine_editor.cpp b/editor/plugins/animation_state_machine_editor.cpp index f750c92fb3..55cbe640b3 100644 --- a/editor/plugins/animation_state_machine_editor.cpp +++ b/editor/plugins/animation_state_machine_editor.cpp @@ -883,9 +883,9 @@ void AnimationNodeStateMachineEditor::_update_graph() { void AnimationNodeStateMachineEditor::_notification(int p_what) { if (p_what == NOTIFICATION_ENTER_TREE || p_what == NOTIFICATION_THEME_CHANGED || p_what == NOTIFICATION_LAYOUT_DIRECTION_CHANGED || p_what == NOTIFICATION_TRANSLATION_CHANGED) { - error_panel->add_theme_style_override("panel", get_theme_stylebox(SNAME("bg"), SNAME("Tree"))); - error_label->add_theme_color_override("font_color", get_theme_color(SNAME("error_color"), SNAME("Editor"))); - panel->add_theme_style_override("panel", get_theme_stylebox(SNAME("bg"), SNAME("Tree"))); + error_panel->add_theme_style_override(SNAME("panel"), get_theme_stylebox(SNAME("bg"), SNAME("Tree"))); + error_label->add_theme_color_override(SNAME("font_color"), get_theme_color(SNAME("error_color"), SNAME("Editor"))); + panel->add_theme_style_override(SNAME("panel"), get_theme_stylebox(SNAME("bg"), SNAME("Tree"))); tool_select->set_icon(get_theme_icon(SNAME("ToolSelect"), SNAME("EditorIcons"))); tool_create->set_icon(get_theme_icon(SNAME("ToolAddNode"), SNAME("EditorIcons"))); diff --git a/editor/plugins/asset_library_editor_plugin.cpp b/editor/plugins/asset_library_editor_plugin.cpp index 7199f69f0b..d11bcb5f1f 100644 --- a/editor/plugins/asset_library_editor_plugin.cpp +++ b/editor/plugins/asset_library_editor_plugin.cpp @@ -68,9 +68,9 @@ void EditorAssetLibraryItem::set_image(int p_type, int p_index, const Ref<Textur void EditorAssetLibraryItem::_notification(int p_what) { if (p_what == NOTIFICATION_ENTER_TREE) { icon->set_normal_texture(get_theme_icon(SNAME("ProjectIconLoading"), SNAME("EditorIcons"))); - category->add_theme_color_override("font_color", Color(0.5, 0.5, 0.5)); - author->add_theme_color_override("font_color", Color(0.5, 0.5, 0.5)); - price->add_theme_color_override("font_color", Color(0.5, 0.5, 0.5)); + category->add_theme_color_override(SNAME("font_color"), Color(0.5, 0.5, 0.5)); + author->add_theme_color_override(SNAME("font_color"), Color(0.5, 0.5, 0.5)); + price->add_theme_color_override(SNAME("font_color"), Color(0.5, 0.5, 0.5)); } } @@ -100,11 +100,11 @@ EditorAssetLibraryItem::EditorAssetLibraryItem() { border->set_default_margin(SIDE_RIGHT, 5 * EDSCALE); border->set_default_margin(SIDE_BOTTOM, 5 * EDSCALE); border->set_default_margin(SIDE_TOP, 5 * EDSCALE); - add_theme_style_override("panel", border); + add_theme_style_override(SNAME("panel"), border); HBoxContainer *hb = memnew(HBoxContainer); // Add some spacing to visually separate the icon from the asset details. - hb->add_theme_constant_override("separation", 15 * EDSCALE); + hb->add_theme_constant_override(SNAME("separation"), 15 * EDSCALE); add_child(hb); icon = memnew(TextureButton); @@ -195,7 +195,7 @@ void EditorAssetLibraryItemDescription::_notification(int p_what) { switch (p_what) { case NOTIFICATION_ENTER_TREE: case NOTIFICATION_THEME_CHANGED: { - previews_bg->add_theme_style_override("panel", previews->get_theme_stylebox(SNAME("normal"), SNAME("TextEdit"))); + previews_bg->add_theme_style_override(SNAME("panel"), previews->get_theme_stylebox(SNAME("normal"), SNAME("TextEdit"))); } break; } } @@ -269,7 +269,7 @@ EditorAssetLibraryItemDescription::EditorAssetLibraryItemDescription() { add_child(hbox); VBoxContainer *desc_vbox = memnew(VBoxContainer); hbox->add_child(desc_vbox); - hbox->add_theme_constant_override("separation", 15 * EDSCALE); + hbox->add_theme_constant_override(SNAME("separation"), 15 * EDSCALE); item = memnew(EditorAssetLibraryItem); @@ -280,11 +280,11 @@ EditorAssetLibraryItemDescription::EditorAssetLibraryItemDescription() { desc_vbox->add_child(description); description->set_v_size_flags(Control::SIZE_EXPAND_FILL); description->connect("meta_clicked", callable_mp(this, &EditorAssetLibraryItemDescription::_link_click)); - description->add_theme_constant_override("line_separation", Math::round(5 * EDSCALE)); + description->add_theme_constant_override(SNAME("line_separation"), Math::round(5 * EDSCALE)); VBoxContainer *previews_vbox = memnew(VBoxContainer); hbox->add_child(previews_vbox); - previews_vbox->add_theme_constant_override("separation", 15 * EDSCALE); + previews_vbox->add_theme_constant_override(SNAME("separation"), 15 * EDSCALE); previews_vbox->set_v_size_flags(Control::SIZE_EXPAND_FILL); preview = memnew(TextureRect); @@ -400,8 +400,8 @@ void EditorAssetLibraryItemDownload::_notification(int p_what) { switch (p_what) { case NOTIFICATION_ENTER_TREE: case NOTIFICATION_THEME_CHANGED: { - panel->add_theme_style_override("panel", get_theme_stylebox(SNAME("panel"), SNAME("AssetLib"))); - status->add_theme_color_override("font_color", get_theme_color(SNAME("status_color"), SNAME("AssetLib"))); + panel->add_theme_style_override(SNAME("panel"), get_theme_stylebox(SNAME("panel"), SNAME("AssetLib"))); + status->add_theme_color_override(SNAME("font_color"), get_theme_color(SNAME("status_color"), SNAME("AssetLib"))); dismiss_button->set_normal_texture(get_theme_icon(SNAME("dismiss"), SNAME("AssetLib"))); } break; case NOTIFICATION_PROCESS: { @@ -578,9 +578,9 @@ void EditorAssetLibrary::_notification(int p_what) { case NOTIFICATION_THEME_CHANGED: { error_tr->set_texture(get_theme_icon(SNAME("Error"), SNAME("EditorIcons"))); filter->set_right_icon(get_theme_icon(SNAME("Search"), SNAME("EditorIcons"))); - library_scroll_bg->add_theme_style_override("panel", get_theme_stylebox(SNAME("bg"), SNAME("Tree"))); - downloads_scroll->add_theme_style_override("bg", get_theme_stylebox(SNAME("bg"), SNAME("Tree"))); - error_label->add_theme_color_override("color", get_theme_color(SNAME("error_color"), SNAME("Editor"))); + library_scroll_bg->add_theme_style_override(SNAME("panel"), get_theme_stylebox(SNAME("bg"), SNAME("Tree"))); + downloads_scroll->add_theme_style_override(SNAME("bg"), get_theme_stylebox(SNAME("bg"), SNAME("Tree"))); + error_label->add_theme_color_override(SNAME("color"), get_theme_color(SNAME("error_color"), SNAME("Editor"))); } break; case NOTIFICATION_VISIBILITY_CHANGED: { if (is_visible()) { @@ -984,7 +984,7 @@ HBoxContainer *EditorAssetLibrary::_make_pages(int p_page, int p_page_count, int } hbc->add_spacer(); - hbc->add_theme_constant_override("separation", 5 * EDSCALE); + hbc->add_theme_constant_override(SNAME("separation"), 5 * EDSCALE); Button *first = memnew(Button); first->set_text(TTR("First")); @@ -1191,8 +1191,8 @@ void EditorAssetLibrary::_http_request_completed(int p_status, int p_code, const asset_items = memnew(GridContainer); asset_items->set_columns(2); - asset_items->add_theme_constant_override("hseparation", 10 * EDSCALE); - asset_items->add_theme_constant_override("vseparation", 10 * EDSCALE); + asset_items->add_theme_constant_override(SNAME("hseparation"), 10 * EDSCALE); + asset_items->add_theme_constant_override(SNAME("vseparation"), 10 * EDSCALE); library_vb->add_child(asset_items); @@ -1374,7 +1374,7 @@ EditorAssetLibrary::EditorAssetLibrary(bool p_templates_only) { HBoxContainer *search_hb = memnew(HBoxContainer); library_main->add_child(search_hb); - library_main->add_theme_constant_override("separation", 10 * EDSCALE); + library_main->add_theme_constant_override(SNAME("separation"), 10 * EDSCALE); filter = memnew(LineEdit); if (templates_only) { @@ -1482,7 +1482,7 @@ EditorAssetLibrary::EditorAssetLibrary(bool p_templates_only) { PanelContainer *library_vb_border = memnew(PanelContainer); library_scroll->add_child(library_vb_border); - library_vb_border->add_theme_style_override("panel", border2); + library_vb_border->add_theme_style_override(SNAME("panel"), border2); library_vb_border->set_h_size_flags(Control::SIZE_EXPAND_FILL); library_vb = memnew(VBoxContainer); @@ -1504,8 +1504,8 @@ EditorAssetLibrary::EditorAssetLibrary(bool p_templates_only) { asset_items = memnew(GridContainer); asset_items->set_columns(2); - asset_items->add_theme_constant_override("hseparation", 10 * EDSCALE); - asset_items->add_theme_constant_override("vseparation", 10 * EDSCALE); + asset_items->add_theme_constant_override(SNAME("hseparation"), 10 * EDSCALE); + asset_items->add_theme_constant_override(SNAME("vseparation"), 10 * EDSCALE); library_vb->add_child(asset_items); @@ -1519,7 +1519,7 @@ EditorAssetLibrary::EditorAssetLibrary(bool p_templates_only) { last_queue_id = 0; - library_vb->add_theme_constant_override("separation", 20 * EDSCALE); + library_vb->add_theme_constant_override(SNAME("separation"), 20 * EDSCALE); error_hb = memnew(HBoxContainer); library_main->add_child(error_hb); diff --git a/editor/plugins/audio_stream_editor_plugin.cpp b/editor/plugins/audio_stream_editor_plugin.cpp index 086d5474ba..e20e6dc9ea 100644 --- a/editor/plugins/audio_stream_editor_plugin.cpp +++ b/editor/plugins/audio_stream_editor_plugin.cpp @@ -224,7 +224,7 @@ AudioStreamEditor::AudioStreamEditor() { _preview->add_child(_indicator); HBoxContainer *hbox = memnew(HBoxContainer); - hbox->add_theme_constant_override("separation", 0); + hbox->add_theme_constant_override(SNAME("separation"), 0); vbox->add_child(hbox); _play_button = memnew(Button); @@ -243,14 +243,14 @@ AudioStreamEditor::AudioStreamEditor() { _current_label = memnew(Label); _current_label->set_horizontal_alignment(HORIZONTAL_ALIGNMENT_RIGHT); _current_label->set_h_size_flags(SIZE_EXPAND_FILL); - _current_label->add_theme_font_override("font", EditorNode::get_singleton()->get_gui_base()->get_theme_font(SNAME("status_source"), SNAME("EditorFonts"))); - _current_label->add_theme_font_size_override("font_size", EditorNode::get_singleton()->get_gui_base()->get_theme_font_size(SNAME("status_source_size"), SNAME("EditorFonts"))); + _current_label->add_theme_font_override(SNAME("font"), EditorNode::get_singleton()->get_gui_base()->get_theme_font(SNAME("status_source"), SNAME("EditorFonts"))); + _current_label->add_theme_font_size_override(SNAME("font_size"), EditorNode::get_singleton()->get_gui_base()->get_theme_font_size(SNAME("status_source_size"), SNAME("EditorFonts"))); _current_label->set_modulate(Color(1, 1, 1, 0.5)); hbox->add_child(_current_label); _duration_label = memnew(Label); - _duration_label->add_theme_font_override("font", EditorNode::get_singleton()->get_gui_base()->get_theme_font(SNAME("status_source"), SNAME("EditorFonts"))); - _duration_label->add_theme_font_size_override("font_size", EditorNode::get_singleton()->get_gui_base()->get_theme_font_size(SNAME("status_source_size"), SNAME("EditorFonts"))); + _duration_label->add_theme_font_override(SNAME("font"), EditorNode::get_singleton()->get_gui_base()->get_theme_font(SNAME("status_source"), SNAME("EditorFonts"))); + _duration_label->add_theme_font_size_override(SNAME("font_size"), EditorNode::get_singleton()->get_gui_base()->get_theme_font_size(SNAME("status_source_size"), SNAME("EditorFonts"))); hbox->add_child(_duration_label); } diff --git a/editor/plugins/canvas_item_editor_plugin.cpp b/editor/plugins/canvas_item_editor_plugin.cpp index 8d2e6a13b4..4a7c8d7d01 100644 --- a/editor/plugins/canvas_item_editor_plugin.cpp +++ b/editor/plugins/canvas_item_editor_plugin.cpp @@ -3847,7 +3847,7 @@ void CanvasItemEditor::_notification(int p_what) { // the icon will be dark, so we need to lighten it before blending it // with the red color. const Color key_auto_color = EditorSettings::get_singleton()->is_dark_theme() ? Color(1, 1, 1) : Color(4.25, 4.25, 4.25); - key_auto_insert_button->add_theme_color_override("icon_pressed_color", key_auto_color.lerp(Color(1, 0, 0), 0.55)); + key_auto_insert_button->add_theme_color_override(SNAME("icon_pressed_color"), key_auto_color.lerp(Color(1, 0, 0), 0.55)); animation_menu->set_icon(get_theme_icon(SNAME("GuiTabMenuHl"), SNAME("EditorIcons"))); _update_context_menu_stylebox(); @@ -3967,7 +3967,7 @@ void CanvasItemEditor::_update_context_menu_stylebox() { context_menu_stylebox->set_border_color(accent_color); context_menu_stylebox->set_border_width(SIDE_BOTTOM, Math::round(2 * EDSCALE)); context_menu_stylebox->set_default_margin(SIDE_BOTTOM, 0); - context_menu_container->add_theme_style_override("panel", context_menu_stylebox); + context_menu_container->add_theme_style_override(SNAME("panel"), context_menu_stylebox); } void CanvasItemEditor::_update_scrollbars() { @@ -6073,7 +6073,7 @@ void CanvasItemEditorViewport::_notification(int p_what) { check->set_icon(get_theme_icon(check->get_text(), SNAME("EditorIcons"))); } - label->add_theme_color_override("font_color", get_theme_color(SNAME("warning_color"), SNAME("Editor"))); + label->add_theme_color_override(SNAME("font_color"), get_theme_color(SNAME("warning_color"), SNAME("Editor"))); } switch (p_what) { @@ -6141,16 +6141,16 @@ CanvasItemEditorViewport::CanvasItemEditorViewport(EditorNode *p_node, CanvasIte } label = memnew(Label); - label->add_theme_color_override("font_shadow_color", Color(0, 0, 0, 1)); - label->add_theme_constant_override("shadow_outline_size", 1 * EDSCALE); + label->add_theme_color_override(SNAME("font_shadow_color"), Color(0, 0, 0, 1)); + label->add_theme_constant_override(SNAME("shadow_outline_size"), 1 * EDSCALE); label->hide(); canvas_item_editor->get_controls_container()->add_child(label); label_desc = memnew(Label); - label_desc->add_theme_color_override("font_color", Color(0.6f, 0.6f, 0.6f, 1)); - label_desc->add_theme_color_override("font_shadow_color", Color(0.2f, 0.2f, 0.2f, 1)); - label_desc->add_theme_constant_override("shadow_outline_size", 1 * EDSCALE); - label_desc->add_theme_constant_override("line_spacing", 0); + label_desc->add_theme_color_override(SNAME("font_color"), Color(0.6f, 0.6f, 0.6f, 1)); + label_desc->add_theme_color_override(SNAME("font_shadow_color"), Color(0.2f, 0.2f, 0.2f, 1)); + label_desc->add_theme_constant_override(SNAME("shadow_outline_size"), 1 * EDSCALE); + label_desc->add_theme_constant_override(SNAME("line_spacing"), 0); label_desc->hide(); canvas_item_editor->get_controls_container()->add_child(label_desc); diff --git a/editor/plugins/debugger_editor_plugin.cpp b/editor/plugins/debugger_editor_plugin.cpp index 6e43130a92..3042132a4d 100644 --- a/editor/plugins/debugger_editor_plugin.cpp +++ b/editor/plugins/debugger_editor_plugin.cpp @@ -54,7 +54,7 @@ DebuggerEditorPlugin::DebuggerEditorPlugin(EditorNode *p_editor, MenuButton *p_d EditorDebuggerNode *debugger = memnew(EditorDebuggerNode); Button *db = EditorNode::get_singleton()->add_bottom_panel_item(TTR("Debugger"), debugger); // Add separation for the warning/error icon that is displayed later. - db->add_theme_constant_override("hseparation", 6 * EDSCALE); + db->add_theme_constant_override(SNAME("hseparation"), 6 * EDSCALE); debugger->set_tool_button(db); // Main editor debug menu. diff --git a/editor/plugins/input_event_editor_plugin.cpp b/editor/plugins/input_event_editor_plugin.cpp index b0ee88479a..e8497c620e 100644 --- a/editor/plugins/input_event_editor_plugin.cpp +++ b/editor/plugins/input_event_editor_plugin.cpp @@ -76,10 +76,10 @@ void InputEventConfigContainer::set_event(const Ref<InputEvent> &p_event) { InputEventConfigContainer::InputEventConfigContainer() { MarginContainer *mc = memnew(MarginContainer); - mc->add_theme_constant_override("margin_left", 10); - mc->add_theme_constant_override("margin_right", 10); - mc->add_theme_constant_override("margin_top", 10); - mc->add_theme_constant_override("margin_bottom", 10); + mc->add_theme_constant_override(SNAME("margin_left"), 10); + mc->add_theme_constant_override(SNAME("margin_right"), 10); + mc->add_theme_constant_override(SNAME("margin_top"), 10); + mc->add_theme_constant_override(SNAME("margin_bottom"), 10); add_child(mc); HBoxContainer *hb = memnew(HBoxContainer); diff --git a/editor/plugins/node_3d_editor_plugin.cpp b/editor/plugins/node_3d_editor_plugin.cpp index 0c0188e8d1..b069cbc0bf 100644 --- a/editor/plugins/node_3d_editor_plugin.cpp +++ b/editor/plugins/node_3d_editor_plugin.cpp @@ -2946,28 +2946,28 @@ void Node3DEditorViewport::_notification(int p_what) { view_menu->set_icon(get_theme_icon(SNAME("GuiTabMenuHl"), SNAME("EditorIcons"))); preview_camera->set_icon(get_theme_icon(SNAME("Camera3D"), SNAME("EditorIcons"))); - view_menu->add_theme_style_override("normal", editor->get_gui_base()->get_theme_stylebox(SNAME("Information3dViewport"), SNAME("EditorStyles"))); - view_menu->add_theme_style_override("hover", editor->get_gui_base()->get_theme_stylebox(SNAME("Information3dViewport"), SNAME("EditorStyles"))); - view_menu->add_theme_style_override("pressed", editor->get_gui_base()->get_theme_stylebox(SNAME("Information3dViewport"), SNAME("EditorStyles"))); - view_menu->add_theme_style_override("focus", editor->get_gui_base()->get_theme_stylebox(SNAME("Information3dViewport"), SNAME("EditorStyles"))); - view_menu->add_theme_style_override("disabled", editor->get_gui_base()->get_theme_stylebox(SNAME("Information3dViewport"), SNAME("EditorStyles"))); - - preview_camera->add_theme_style_override("normal", editor->get_gui_base()->get_theme_stylebox(SNAME("Information3dViewport"), SNAME("EditorStyles"))); - preview_camera->add_theme_style_override("hover", editor->get_gui_base()->get_theme_stylebox(SNAME("Information3dViewport"), SNAME("EditorStyles"))); - preview_camera->add_theme_style_override("pressed", editor->get_gui_base()->get_theme_stylebox(SNAME("Information3dViewport"), SNAME("EditorStyles"))); - preview_camera->add_theme_style_override("focus", editor->get_gui_base()->get_theme_stylebox(SNAME("Information3dViewport"), SNAME("EditorStyles"))); - preview_camera->add_theme_style_override("disabled", editor->get_gui_base()->get_theme_stylebox(SNAME("Information3dViewport"), SNAME("EditorStyles"))); + view_menu->add_theme_style_override(SNAME("normal"), editor->get_gui_base()->get_theme_stylebox(SNAME("Information3dViewport"), SNAME("EditorStyles"))); + view_menu->add_theme_style_override(SNAME("hover"), editor->get_gui_base()->get_theme_stylebox(SNAME("Information3dViewport"), SNAME("EditorStyles"))); + view_menu->add_theme_style_override(SNAME("pressed"), editor->get_gui_base()->get_theme_stylebox(SNAME("Information3dViewport"), SNAME("EditorStyles"))); + view_menu->add_theme_style_override(SNAME("focus"), editor->get_gui_base()->get_theme_stylebox(SNAME("Information3dViewport"), SNAME("EditorStyles"))); + view_menu->add_theme_style_override(SNAME("disabled"), editor->get_gui_base()->get_theme_stylebox(SNAME("Information3dViewport"), SNAME("EditorStyles"))); + + preview_camera->add_theme_style_override(SNAME("normal"), editor->get_gui_base()->get_theme_stylebox(SNAME("Information3dViewport"), SNAME("EditorStyles"))); + preview_camera->add_theme_style_override(SNAME("hover"), editor->get_gui_base()->get_theme_stylebox(SNAME("Information3dViewport"), SNAME("EditorStyles"))); + preview_camera->add_theme_style_override(SNAME("pressed"), editor->get_gui_base()->get_theme_stylebox(SNAME("Information3dViewport"), SNAME("EditorStyles"))); + preview_camera->add_theme_style_override(SNAME("focus"), editor->get_gui_base()->get_theme_stylebox(SNAME("Information3dViewport"), SNAME("EditorStyles"))); + preview_camera->add_theme_style_override(SNAME("disabled"), editor->get_gui_base()->get_theme_stylebox(SNAME("Information3dViewport"), SNAME("EditorStyles"))); frame_time_gradient->set_color(0, get_theme_color(SNAME("success_color"), SNAME("Editor"))); frame_time_gradient->set_color(1, get_theme_color(SNAME("warning_color"), SNAME("Editor"))); frame_time_gradient->set_color(2, get_theme_color(SNAME("error_color"), SNAME("Editor"))); - info_label->add_theme_style_override("normal", editor->get_gui_base()->get_theme_stylebox(SNAME("Information3dViewport"), SNAME("EditorStyles"))); - cpu_time_label->add_theme_style_override("normal", editor->get_gui_base()->get_theme_stylebox(SNAME("Information3dViewport"), SNAME("EditorStyles"))); - gpu_time_label->add_theme_style_override("normal", editor->get_gui_base()->get_theme_stylebox(SNAME("Information3dViewport"), SNAME("EditorStyles"))); - fps_label->add_theme_style_override("normal", editor->get_gui_base()->get_theme_stylebox(SNAME("Information3dViewport"), SNAME("EditorStyles"))); - cinema_label->add_theme_style_override("normal", editor->get_gui_base()->get_theme_stylebox(SNAME("Information3dViewport"), SNAME("EditorStyles"))); - locked_label->add_theme_style_override("normal", editor->get_gui_base()->get_theme_stylebox(SNAME("Information3dViewport"), SNAME("EditorStyles"))); + info_label->add_theme_style_override(SNAME("normal"), editor->get_gui_base()->get_theme_stylebox(SNAME("Information3dViewport"), SNAME("EditorStyles"))); + cpu_time_label->add_theme_style_override(SNAME("normal"), editor->get_gui_base()->get_theme_stylebox(SNAME("Information3dViewport"), SNAME("EditorStyles"))); + gpu_time_label->add_theme_style_override(SNAME("normal"), editor->get_gui_base()->get_theme_stylebox(SNAME("Information3dViewport"), SNAME("EditorStyles"))); + fps_label->add_theme_style_override(SNAME("normal"), editor->get_gui_base()->get_theme_stylebox(SNAME("Information3dViewport"), SNAME("EditorStyles"))); + cinema_label->add_theme_style_override(SNAME("normal"), editor->get_gui_base()->get_theme_stylebox(SNAME("Information3dViewport"), SNAME("EditorStyles"))); + locked_label->add_theme_style_override(SNAME("normal"), editor->get_gui_base()->get_theme_stylebox(SNAME("Information3dViewport"), SNAME("EditorStyles"))); } } @@ -4512,7 +4512,7 @@ Node3DEditorViewport::Node3DEditorViewport(Node3DEditor *p_spatial_editor, Edito zoom_limit_label->set_offset(Side::SIDE_TOP, -28 * EDSCALE); zoom_limit_label->set_text(TTR("To zoom further, change the camera's clipping planes (View -> Settings...)")); zoom_limit_label->set_name("ZoomLimitMessageLabel"); - zoom_limit_label->add_theme_color_override("font_color", Color(1, 1, 1, 1)); + zoom_limit_label->add_theme_color_override(SNAME("font_color"), Color(1, 1, 1, 1)); zoom_limit_label->hide(); surface->add_child(zoom_limit_label); @@ -4526,7 +4526,7 @@ Node3DEditorViewport::Node3DEditorViewport(Node3DEditor *p_spatial_editor, Edito // Make sure frame time labels don't touch the viewport's edge. top_right_vbox->set_custom_minimum_size(Size2(100, 0) * EDSCALE); // Prevent visible spacing between frame time labels. - top_right_vbox->add_theme_constant_override("separation", 0); + top_right_vbox->add_theme_constant_override(SNAME("separation"), 0); rotation_control = memnew(ViewportRotationControl); rotation_control->set_custom_minimum_size(Size2(80, 80) * EDSCALE); @@ -6190,7 +6190,7 @@ void Node3DEditor::_update_context_menu_stylebox() { context_menu_stylebox->set_border_color(accent_color); context_menu_stylebox->set_border_width(SIDE_BOTTOM, Math::round(2 * EDSCALE)); context_menu_stylebox->set_default_margin(SIDE_BOTTOM, 0); - context_menu_container->add_theme_style_override("panel", context_menu_stylebox); + context_menu_container->add_theme_style_override(SNAME("panel"), context_menu_stylebox); } void Node3DEditor::_update_gizmos_menu() { @@ -6777,8 +6777,8 @@ void Node3DEditor::_update_theme() { environ_button->set_icon(get_theme_icon(SNAME("WorldEnvironment"), SNAME("EditorIcons"))); sun_environ_settings->set_icon(get_theme_icon(SNAME("GuiTabMenuHl"), SNAME("EditorIcons"))); - sun_title->add_theme_font_override("font", get_theme_font(SNAME("title_font"), SNAME("Window"))); - environ_title->add_theme_font_override("font", get_theme_font(SNAME("title_font"), SNAME("Window"))); + sun_title->add_theme_font_override(SNAME("font"), get_theme_font(SNAME("title_font"), SNAME("Window"))); + environ_title->add_theme_font_override(SNAME("font"), get_theme_font(SNAME("title_font"), SNAME("Window"))); } void Node3DEditor::_notification(int p_what) { @@ -6815,8 +6815,8 @@ void Node3DEditor::_notification(int p_what) { _update_theme(); _update_gizmos_menu_theme(); _update_context_menu_stylebox(); - sun_title->add_theme_font_override("font", get_theme_font(SNAME("title_font"), SNAME("Window"))); - environ_title->add_theme_font_override("font", get_theme_font(SNAME("title_font"), SNAME("Window"))); + sun_title->add_theme_font_override(SNAME("font"), get_theme_font(SNAME("title_font"), SNAME("Window"))); + environ_title->add_theme_font_override(SNAME("font"), get_theme_font(SNAME("title_font"), SNAME("Window"))); } break; case EditorSettings::NOTIFICATION_EDITOR_SETTINGS_CHANGED: { // Update grid color by rebuilding grid. @@ -7806,7 +7806,7 @@ void fragment() { sun_angle_azimuth->connect("value_changed", callable_mp(this, &Node3DEditor::_sun_direction_angle_set).unbind(1)); sun_angle_azimuth_vbox->add_child(sun_angle_azimuth); sun_angle_hbox->add_child(sun_angle_azimuth_vbox); - sun_angle_hbox->add_theme_constant_override("separation", 10); + sun_angle_hbox->add_theme_constant_override(SNAME("separation"), 10); sun_vb->add_child(sun_angle_hbox); sun_color = memnew(ColorPickerButton); diff --git a/editor/plugins/polygon_2d_editor_plugin.cpp b/editor/plugins/polygon_2d_editor_plugin.cpp index b116f8ff6d..6a7a98ff89 100644 --- a/editor/plugins/polygon_2d_editor_plugin.cpp +++ b/editor/plugins/polygon_2d_editor_plugin.cpp @@ -92,8 +92,8 @@ void Polygon2DEditor::_notification(int p_what) { [[fallthrough]]; } case NOTIFICATION_THEME_CHANGED: { - uv_edit_draw->add_theme_style_override("panel", get_theme_stylebox(SNAME("bg"), SNAME("Tree"))); - bone_scroll->add_theme_style_override("bg", get_theme_stylebox(SNAME("bg"), SNAME("Tree"))); + uv_edit_draw->add_theme_style_override(SNAME("panel"), get_theme_stylebox(SNAME("bg"), SNAME("Tree"))); + bone_scroll->add_theme_style_override(SNAME("bg"), get_theme_stylebox(SNAME("bg"), SNAME("Tree"))); } break; case NOTIFICATION_VISIBILITY_CHANGED: { if (!is_visible()) { diff --git a/editor/plugins/replication_editor_plugin.cpp b/editor/plugins/replication_editor_plugin.cpp index 93f4a853f3..467db13246 100644 --- a/editor/plugins/replication_editor_plugin.cpp +++ b/editor/plugins/replication_editor_plugin.cpp @@ -95,7 +95,7 @@ void ReplicationEditor::_bind_methods() { void ReplicationEditor::_notification(int p_what) { if (p_what == NOTIFICATION_ENTER_TREE || p_what == EditorSettings::NOTIFICATION_EDITOR_SETTINGS_CHANGED) { - add_theme_style_override("panel", editor->get_gui_base()->get_theme_stylebox(SNAME("panel"), SNAME("Panel"))); + add_theme_style_override(SNAME("panel"), editor->get_gui_base()->get_theme_stylebox(SNAME("panel"), SNAME("Panel"))); } else if (p_what == NOTIFICATION_VISIBILITY_CHANGED) { update_keying(); } @@ -257,10 +257,10 @@ void ReplicationEditor::edit(MultiplayerSynchronizer *p_sync) { } Ref<Texture2D> ReplicationEditor::_get_class_icon(const Node *p_node) { - if (!p_node || !has_theme_icon(p_node->get_class(), "EditorIcons")) { - return get_theme_icon("ImportFail", "EditorIcons"); + if (!p_node || !has_theme_icon(p_node->get_class(), SNAME("EditorIcons"))) { + return get_theme_icon(SNAME("ImportFail"), SNAME("EditorIcons")); } - return get_theme_icon(p_node->get_class(), "EditorIcons"); + return get_theme_icon(p_node->get_class(), SNAME("EditorIcons")); } void ReplicationEditor::_add_property(const NodePath &p_property, bool p_spawn, bool p_sync) { @@ -285,7 +285,7 @@ void ReplicationEditor::_add_property(const NodePath &p_property, bool p_spawn, icon = _get_class_icon(node); } item->set_icon(0, icon); - item->add_button(3, get_theme_icon("Remove", "EditorIcons")); + item->add_button(3, get_theme_icon(SNAME("Remove"), SNAME("EditorIcons"))); item->set_text_alignment(1, HORIZONTAL_ALIGNMENT_CENTER); item->set_cell_mode(1, TreeItem::CELL_MODE_CHECK); item->set_checked(1, p_spawn); diff --git a/editor/plugins/resource_preloader_editor_plugin.cpp b/editor/plugins/resource_preloader_editor_plugin.cpp index 786217a5c2..271d035986 100644 --- a/editor/plugins/resource_preloader_editor_plugin.cpp +++ b/editor/plugins/resource_preloader_editor_plugin.cpp @@ -341,7 +341,7 @@ void ResourcePreloaderEditor::_bind_methods() { } ResourcePreloaderEditor::ResourcePreloaderEditor() { - //add_style_override("panel", EditorNode::get_singleton()->get_gui_base()->get_stylebox("panel","Panel")); + //add_style_override(SNAME("panel"), EditorNode::get_singleton()->get_gui_base()->get_stylebox("panel","Panel")); VBoxContainer *vbc = memnew(VBoxContainer); add_child(vbc); diff --git a/editor/plugins/script_editor_plugin.cpp b/editor/plugins/script_editor_plugin.cpp index 26227fa5bb..b20f9650ac 100644 --- a/editor/plugins/script_editor_plugin.cpp +++ b/editor/plugins/script_editor_plugin.cpp @@ -381,7 +381,7 @@ ScriptEditorQuickOpen::ScriptEditorQuickOpen() { search_options->connect("item_activated", callable_mp(this, &ScriptEditorQuickOpen::_confirmed)); search_options->set_hide_root(true); search_options->set_hide_folding(true); - search_options->add_theme_constant_override("draw_guides", 1); + search_options->add_theme_constant_override(SNAME("draw_guides"), 1); } ///////////////////////////////// @@ -1630,7 +1630,7 @@ void ScriptEditor::_notification(int p_what) { filter_scripts->set_right_icon(get_theme_icon(SNAME("Search"), SNAME("EditorIcons"))); filter_methods->set_right_icon(get_theme_icon(SNAME("Search"), SNAME("EditorIcons"))); - filename->add_theme_style_override("normal", editor->get_gui_base()->get_theme_stylebox(SNAME("normal"), SNAME("LineEdit"))); + filename->add_theme_style_override(SNAME("normal"), editor->get_gui_base()->get_theme_stylebox(SNAME("normal"), SNAME("LineEdit"))); recent_scripts->set_as_minsize(); @@ -3693,7 +3693,7 @@ ScriptEditor::ScriptEditor(EditorNode *p_editor) { filename = memnew(Label); filename->set_clip_text(true); filename->set_h_size_flags(SIZE_EXPAND_FILL); - filename->add_theme_style_override("normal", EditorNode::get_singleton()->get_gui_base()->get_theme_stylebox(SNAME("normal"), SNAME("LineEdit"))); + filename->add_theme_style_override(SNAME("normal"), EditorNode::get_singleton()->get_gui_base()->get_theme_stylebox(SNAME("normal"), SNAME("LineEdit"))); buttons_hbox->add_child(filename); members_overview_alphabeta_sort_button = memnew(Button); @@ -3948,8 +3948,8 @@ ScriptEditor::ScriptEditor(EditorNode *p_editor) { ScriptServer::edit_request_func = _open_script_request; - add_theme_style_override("panel", editor->get_gui_base()->get_theme_stylebox(SNAME("ScriptEditorPanel"), SNAME("EditorStyles"))); - tab_container->add_theme_style_override("panel", editor->get_gui_base()->get_theme_stylebox(SNAME("ScriptEditor"), SNAME("EditorStyles"))); + add_theme_style_override(SNAME("panel"), editor->get_gui_base()->get_theme_stylebox(SNAME("ScriptEditorPanel"), SNAME("EditorStyles"))); + tab_container->add_theme_style_override(SNAME("panel"), editor->get_gui_base()->get_theme_stylebox(SNAME("ScriptEditor"), SNAME("EditorStyles"))); } ScriptEditor::~ScriptEditor() { diff --git a/editor/plugins/script_text_editor.cpp b/editor/plugins/script_text_editor.cpp index 7b4ebbc6d8..a818caabbe 100644 --- a/editor/plugins/script_text_editor.cpp +++ b/editor/plugins/script_text_editor.cpp @@ -1848,7 +1848,7 @@ void ScriptTextEditor::_enable_code_editor() { ScriptTextEditor::ScriptTextEditor() { code_editor = memnew(CodeTextEditor); - code_editor->add_theme_constant_override("separation", 2); + code_editor->add_theme_constant_override(SNAME("separation"), 2); code_editor->set_anchors_and_offsets_preset(Control::PRESET_WIDE); code_editor->set_code_complete_func(_code_complete_scripts, this); code_editor->set_v_size_flags(SIZE_EXPAND_FILL); diff --git a/editor/plugins/shader_editor_plugin.cpp b/editor/plugins/shader_editor_plugin.cpp index 4bbeb33406..9aff507bdd 100644 --- a/editor/plugins/shader_editor_plugin.cpp +++ b/editor/plugins/shader_editor_plugin.cpp @@ -189,8 +189,8 @@ void ShaderTextEditor::_load_theme_settings() { if (warnings_panel) { // Warnings panel - warnings_panel->add_theme_font_override("normal_font", EditorNode::get_singleton()->get_gui_base()->get_theme_font(SNAME("main"), SNAME("EditorFonts"))); - warnings_panel->add_theme_font_size_override("normal_font_size", EditorNode::get_singleton()->get_gui_base()->get_theme_font_size(SNAME("main_size"), SNAME("EditorFonts"))); + warnings_panel->add_theme_font_override(SNAME("normal_font"), EditorNode::get_singleton()->get_gui_base()->get_theme_font(SNAME("main"), SNAME("EditorFonts"))); + warnings_panel->add_theme_font_size_override(SNAME("normal_font_size"), EditorNode::get_singleton()->get_gui_base()->get_theme_font_size(SNAME("main_size"), SNAME("EditorFonts"))); } } @@ -443,7 +443,7 @@ void ShaderEditor::_notification(int p_what) { void ShaderEditor::_editor_settings_changed() { shader_editor->update_editor_settings(); - shader_editor->get_text_editor()->add_theme_constant_override("line_spacing", EditorSettings::get_singleton()->get("text_editor/appearance/whitespace/line_spacing")); + shader_editor->get_text_editor()->add_theme_constant_override(SNAME("line_spacing"), EditorSettings::get_singleton()->get("text_editor/appearance/whitespace/line_spacing")); shader_editor->get_text_editor()->set_draw_breakpoints_gutter(false); shader_editor->get_text_editor()->set_draw_executing_lines_gutter(false); } @@ -701,7 +701,7 @@ ShaderEditor::ShaderEditor(EditorNode *p_node) { shader_editor = memnew(ShaderTextEditor); shader_editor->set_v_size_flags(SIZE_EXPAND_FILL); - shader_editor->add_theme_constant_override("separation", 0); + shader_editor->add_theme_constant_override(SNAME("separation"), 0); shader_editor->set_anchors_and_offsets_preset(Control::PRESET_WIDE); shader_editor->connect("show_warnings_panel", callable_mp(this, &ShaderEditor::_show_warnings_panel)); @@ -789,7 +789,7 @@ ShaderEditor::ShaderEditor(EditorNode *p_node) { hbc->add_child(edit_menu); hbc->add_child(goto_menu); hbc->add_child(help_menu); - hbc->add_theme_style_override("panel", p_node->get_gui_base()->get_theme_stylebox(SNAME("ScriptEditorPanel"), SNAME("EditorStyles"))); + hbc->add_theme_style_override(SNAME("panel"), p_node->get_gui_base()->get_theme_stylebox(SNAME("ScriptEditorPanel"), SNAME("EditorStyles"))); VSplitContainer *editor_box = memnew(VSplitContainer); main_container->add_child(editor_box); diff --git a/editor/plugins/skeleton_3d_editor_plugin.cpp b/editor/plugins/skeleton_3d_editor_plugin.cpp index ac77f51812..9e2ded3ec9 100644 --- a/editor/plugins/skeleton_3d_editor_plugin.cpp +++ b/editor/plugins/skeleton_3d_editor_plugin.cpp @@ -602,7 +602,7 @@ void Skeleton3DEditor::update_editors() { void Skeleton3DEditor::create_editors() { set_h_size_flags(SIZE_EXPAND_FILL); - add_theme_constant_override("separation", 0); + add_theme_constant_override(SNAME("separation"), 0); set_focus_mode(FOCUS_ALL); diff --git a/editor/plugins/sprite_frames_editor_plugin.cpp b/editor/plugins/sprite_frames_editor_plugin.cpp index 014fa0e7a5..e504756440 100644 --- a/editor/plugins/sprite_frames_editor_plugin.cpp +++ b/editor/plugins/sprite_frames_editor_plugin.cpp @@ -285,7 +285,7 @@ void SpriteFramesEditor::_sheet_spin_changed(double) { } void SpriteFramesEditor::_prepare_sprite_sheet(const String &p_file) { - Ref<Resource> texture = ResourceLoader::load(p_file); + Ref<Texture2D> texture = ResourceLoader::load(p_file); if (!texture.is_valid()) { EditorNode::get_singleton()->show_warning(TTR("Unable to load images")); ERR_FAIL_COND(!texture.is_valid()); @@ -328,10 +328,10 @@ void SpriteFramesEditor::_notification(int p_what) { [[fallthrough]]; } case NOTIFICATION_THEME_CHANGED: { - split_sheet_scroll->add_theme_style_override("bg", get_theme_stylebox(SNAME("bg"), SNAME("Tree"))); + split_sheet_scroll->add_theme_style_override(SNAME("bg"), get_theme_stylebox(SNAME("bg"), SNAME("Tree"))); } break; case NOTIFICATION_READY: { - add_theme_constant_override("autohide", 1); // Fixes the dragger always showing up. + add_theme_constant_override(SNAME("autohide"), 1); // Fixes the dragger always showing up. } break; } } @@ -1247,8 +1247,8 @@ SpriteFramesEditor::SpriteFramesEditor() { split_sheet_panel->add_child(split_sheet_zoom_margin); split_sheet_zoom_margin->set_h_size_flags(0); split_sheet_zoom_margin->set_v_size_flags(0); - split_sheet_zoom_margin->add_theme_constant_override("margin_top", 5); - split_sheet_zoom_margin->add_theme_constant_override("margin_left", 5); + split_sheet_zoom_margin->add_theme_constant_override(SNAME("margin_top"), 5); + split_sheet_zoom_margin->add_theme_constant_override(SNAME("margin_left"), 5); HBoxContainer *split_sheet_zoom_hb = memnew(HBoxContainer); split_sheet_zoom_margin->add_child(split_sheet_zoom_hb); diff --git a/editor/plugins/style_box_editor_plugin.cpp b/editor/plugins/style_box_editor_plugin.cpp index 5d38352b22..8ec5ffc0a3 100644 --- a/editor/plugins/style_box_editor_plugin.cpp +++ b/editor/plugins/style_box_editor_plugin.cpp @@ -50,7 +50,7 @@ void StyleBoxPreview::edit(const Ref<StyleBox> &p_stylebox) { } stylebox = p_stylebox; if (p_stylebox.is_valid()) { - preview->add_theme_style_override("panel", stylebox); + preview->add_theme_style_override(SNAME("panel"), stylebox); stylebox->connect("changed", callable_mp(this, &StyleBoxPreview::_sb_changed)); } _sb_changed(); diff --git a/editor/plugins/text_control_editor_plugin.cpp b/editor/plugins/text_control_editor_plugin.cpp index 87eff9c3e9..59796179a6 100644 --- a/editor/plugins/text_control_editor_plugin.cpp +++ b/editor/plugins/text_control_editor_plugin.cpp @@ -220,9 +220,9 @@ void TextControlEditor::_update_control() { } int current_font_size = edited_control->get_theme_font_size(edited_font_size); - int current_outline_size = edited_control->get_theme_constant("outline_size"); + int current_outline_size = edited_control->get_theme_constant(SNAME("outline_size")); Color current_font_color = edited_control->get_theme_color(edited_color); - Color current_outline_color = edited_control->get_theme_color("font_outline_color"); + Color current_outline_color = edited_control->get_theme_color(SNAME("font_outline_color")); if (i > 0) { same_font_size = same_font_size && (font_size == current_font_size); same_outline_size = same_outline_size && (outline_size == current_outline_size); @@ -392,8 +392,8 @@ void TextControlEditor::_outline_size_selected(double p_size) { Control *edited_control = edited_controls[i]; ur->add_do_method(edited_control, "add_theme_constant_override", "outline_size", p_size); - if (edited_control->has_theme_constant_override("outline_size")) { - ur->add_undo_method(edited_control, "add_theme_constant_override", "outline_size", edited_control->get_theme_constant("outline_size")); + if (edited_control->has_theme_constant_override(SNAME("outline_size"))) { + ur->add_undo_method(edited_control, "add_theme_constant_override", "outline_size", edited_control->get_theme_constant(SNAME("outline_size"))); } else { ur->add_undo_method(edited_control, "remove_theme_constant_override", "outline_size"); } @@ -451,8 +451,8 @@ void TextControlEditor::_outline_color_changed(const Color &p_color) { Control *edited_control = edited_controls[i]; ur->add_do_method(edited_control, "add_theme_color_override", "font_outline_color", p_color); - if (edited_control->has_theme_color_override("font_outline_color")) { - ur->add_undo_method(edited_control, "add_theme_color_override", "font_outline_color", edited_control->get_theme_color("font_outline_color")); + if (edited_control->has_theme_color_override(SNAME("font_outline_color"))) { + ur->add_undo_method(edited_control, "add_theme_color_override", "font_outline_color", edited_control->get_theme_color(SNAME("font_outline_color"))); } else { ur->add_undo_method(edited_control, "remove_theme_color_override", "font_outline_color"); } @@ -510,13 +510,13 @@ void TextControlEditor::_clear_formatting() { } ur->add_do_method(edited_control, "remove_theme_color_override", "font_outline_color"); - if (edited_control->has_theme_color_override("font_outline_color")) { - ur->add_undo_method(edited_control, "add_theme_color_override", "font_outline_color", edited_control->get_theme_color("font_outline_color")); + if (edited_control->has_theme_color_override(SNAME("font_outline_color"))) { + ur->add_undo_method(edited_control, "add_theme_color_override", "font_outline_color", edited_control->get_theme_color(SNAME("font_outline_color"))); } ur->add_do_method(edited_control, "remove_theme_constant_override", "outline_size"); - if (edited_control->has_theme_constant_override("outline_size")) { - ur->add_undo_method(edited_control, "add_theme_constant_override", "outline_size", edited_control->get_theme_constant("outline_size")); + if (edited_control->has_theme_constant_override(SNAME("outline_size"))) { + ur->add_undo_method(edited_control, "add_theme_constant_override", "outline_size", edited_control->get_theme_constant(SNAME("outline_size"))); } ur->add_do_method(edited_control, "end_bulk_theme_override"); @@ -600,7 +600,7 @@ TextControlEditor::TextControlEditor() { font_size_list = memnew(SpinBox); font_size_list->set_tooltip(TTR("Font Size")); - font_size_list->get_line_edit()->add_theme_constant_override("minimum_character_width", 2); + font_size_list->get_line_edit()->add_theme_constant_override(SNAME("minimum_character_width"), 2); font_size_list->set_min(6); font_size_list->set_step(1); font_size_list->set_max(96); @@ -619,7 +619,7 @@ TextControlEditor::TextControlEditor() { outline_size_list = memnew(SpinBox); outline_size_list->set_tooltip(TTR("Outline Size")); - outline_size_list->get_line_edit()->add_theme_constant_override("minimum_character_width", 2); + outline_size_list->get_line_edit()->add_theme_constant_override(SNAME("minimum_character_width"), 2); outline_size_list->set_min(0); outline_size_list->set_step(1); outline_size_list->set_max(96); diff --git a/editor/plugins/text_editor.cpp b/editor/plugins/text_editor.cpp index 940f269803..54cfff66c5 100644 --- a/editor/plugins/text_editor.cpp +++ b/editor/plugins/text_editor.cpp @@ -521,7 +521,7 @@ void TextEditor::update_toggle_scripts_button() { TextEditor::TextEditor() { code_editor = memnew(CodeTextEditor); add_child(code_editor); - code_editor->add_theme_constant_override("separation", 0); + code_editor->add_theme_constant_override(SNAME("separation"), 0); code_editor->connect("load_theme_settings", callable_mp(this, &TextEditor::_load_theme_settings)); code_editor->connect("validate_script", callable_mp(this, &TextEditor::_validate_script)); code_editor->set_anchors_and_offsets_preset(Control::PRESET_WIDE); diff --git a/editor/plugins/texture_3d_editor_plugin.cpp b/editor/plugins/texture_3d_editor_plugin.cpp index 6080f9df87..6792d8b329 100644 --- a/editor/plugins/texture_3d_editor_plugin.cpp +++ b/editor/plugins/texture_3d_editor_plugin.cpp @@ -171,11 +171,11 @@ Texture3DEditor::Texture3DEditor() { info->set_anchor(SIDE_TOP, 1); info->set_h_grow_direction(GROW_DIRECTION_BEGIN); info->set_v_grow_direction(GROW_DIRECTION_BEGIN); - info->add_theme_color_override("font_color", Color(1, 1, 1, 1)); - info->add_theme_color_override("font_shadow_color", Color(0, 0, 0, 0.5)); - info->add_theme_constant_override("shadow_outline_size", 1); - info->add_theme_constant_override("shadow_offset_x", 2); - info->add_theme_constant_override("shadow_offset_y", 2); + info->add_theme_color_override(SNAME("font_color"), Color(1, 1, 1, 1)); + info->add_theme_color_override(SNAME("font_shadow_color"), Color(0, 0, 0, 0.5)); + info->add_theme_constant_override(SNAME("shadow_outline_size"), 1); + info->add_theme_constant_override(SNAME("shadow_offset_x"), 2); + info->add_theme_constant_override(SNAME("shadow_offset_y"), 2); setting = false; layer->connect("value_changed", Callable(this, "_layer_changed")); diff --git a/editor/plugins/texture_editor_plugin.cpp b/editor/plugins/texture_editor_plugin.cpp index 84b33f0986..85b5cde066 100644 --- a/editor/plugins/texture_editor_plugin.cpp +++ b/editor/plugins/texture_editor_plugin.cpp @@ -50,7 +50,7 @@ void TexturePreview::_notification(int p_what) { if (metadata_label) { Ref<Font> metadata_label_font = get_theme_font(SNAME("expression"), SNAME("EditorFonts")); - metadata_label->add_theme_font_override("font", metadata_label_font); + metadata_label->add_theme_font_override(SNAME("font"), metadata_label_font); } checkerboard->set_texture(get_theme_icon(SNAME("Checkerboard"), SNAME("EditorIcons"))); @@ -94,14 +94,14 @@ TexturePreview::TexturePreview(Ref<Texture2D> p_texture, bool p_show_metadata) { p_texture->connect("changed", callable_mp(this, &TexturePreview::_update_metadata_label_text)); // It's okay that these colors are static since the grid color is static too. - metadata_label->add_theme_color_override("font_color", Color::named("white")); - metadata_label->add_theme_color_override("font_color_shadow", Color::named("black")); + metadata_label->add_theme_color_override(SNAME("font_color"), Color::named("white")); + metadata_label->add_theme_color_override(SNAME("font_color_shadow"), Color::named("black")); - metadata_label->add_theme_font_size_override("font_size", 16 * EDSCALE); - metadata_label->add_theme_color_override("font_outline_color", Color::named("black")); - metadata_label->add_theme_constant_override("outline_size", 2 * EDSCALE); + metadata_label->add_theme_font_size_override(SNAME("font_size"), 16 * EDSCALE); + metadata_label->add_theme_color_override(SNAME("font_outline_color"), Color::named("black")); + metadata_label->add_theme_constant_override(SNAME("outline_size"), 2 * EDSCALE); - metadata_label->add_theme_constant_override("shadow_outline_size", 1); + metadata_label->add_theme_constant_override(SNAME("shadow_outline_size"), 1); metadata_label->set_h_size_flags(Control::SIZE_SHRINK_END); metadata_label->set_v_size_flags(Control::SIZE_SHRINK_END); diff --git a/editor/plugins/texture_layered_editor_plugin.cpp b/editor/plugins/texture_layered_editor_plugin.cpp index a8c37d37fe..83bc51b8d1 100644 --- a/editor/plugins/texture_layered_editor_plugin.cpp +++ b/editor/plugins/texture_layered_editor_plugin.cpp @@ -247,11 +247,11 @@ TextureLayeredEditor::TextureLayeredEditor() { info->set_anchor(SIDE_TOP, 1); info->set_h_grow_direction(GROW_DIRECTION_BEGIN); info->set_v_grow_direction(GROW_DIRECTION_BEGIN); - info->add_theme_color_override("font_color", Color(1, 1, 1, 1)); - info->add_theme_color_override("font_shadow_color", Color(0, 0, 0, 0.5)); - info->add_theme_constant_override("shadow_outline_size", 1); - info->add_theme_constant_override("shadow_offset_x", 2); - info->add_theme_constant_override("shadow_offset_y", 2); + info->add_theme_color_override(SNAME("font_color"), Color(1, 1, 1, 1)); + info->add_theme_color_override(SNAME("font_shadow_color"), Color(0, 0, 0, 0.5)); + info->add_theme_constant_override(SNAME("shadow_outline_size"), 1); + info->add_theme_constant_override(SNAME("shadow_offset_x"), 2); + info->add_theme_constant_override(SNAME("shadow_offset_y"), 2); setting = false; layer->connect("value_changed", Callable(this, "_layer_changed")); diff --git a/editor/plugins/texture_region_editor_plugin.cpp b/editor/plugins/texture_region_editor_plugin.cpp index 662c0126ec..dc567586d6 100644 --- a/editor/plugins/texture_region_editor_plugin.cpp +++ b/editor/plugins/texture_region_editor_plugin.cpp @@ -808,7 +808,7 @@ void TextureRegionEditor::_notification(int p_what) { switch (p_what) { case NOTIFICATION_ENTER_TREE: case NOTIFICATION_THEME_CHANGED: { - edit_draw->add_theme_style_override("panel", get_theme_stylebox(SNAME("bg"), SNAME("Tree"))); + edit_draw->add_theme_style_override(SNAME("panel"), get_theme_stylebox(SNAME("bg"), SNAME("Tree"))); } break; case NOTIFICATION_READY: { zoom_out->set_icon(get_theme_icon(SNAME("ZoomLess"), SNAME("EditorIcons"))); diff --git a/editor/plugins/theme_editor_plugin.cpp b/editor/plugins/theme_editor_plugin.cpp index aaa09237cf..bfe605ea2d 100644 --- a/editor/plugins/theme_editor_plugin.cpp +++ b/editor/plugins/theme_editor_plugin.cpp @@ -830,7 +830,7 @@ void ThemeItemImportTree::_notification(int p_what) { case NOTIFICATION_ENTER_TREE: case NOTIFICATION_THEME_CHANGED: { select_icons_warning_icon->set_texture(get_theme_icon(SNAME("StatusWarning"), SNAME("EditorIcons"))); - select_icons_warning->add_theme_color_override("font_color", get_theme_color(SNAME("disabled_font_color"), SNAME("Editor"))); + select_icons_warning->add_theme_color_override(SNAME("font_color"), get_theme_color(SNAME("disabled_font_color"), SNAME("Editor"))); // Bottom panel buttons. import_collapse_types_button->set_icon(get_theme_icon(SNAME("CollapseTree"), SNAME("EditorIcons"))); @@ -1824,8 +1824,8 @@ void ThemeItemEditorDialog::_notification(int p_what) { import_another_theme_button->set_icon(get_theme_icon(SNAME("Folder"), SNAME("EditorIcons"))); - tc->add_theme_style_override("tab_selected", get_theme_stylebox(SNAME("tab_selected_odd"), SNAME("TabContainer"))); - tc->add_theme_style_override("panel", get_theme_stylebox(SNAME("panel_odd"), SNAME("TabContainer"))); + tc->add_theme_style_override(SNAME("tab_selected"), get_theme_stylebox(SNAME("tab_selected_odd"), SNAME("TabContainer"))); + tc->add_theme_style_override(SNAME("panel"), get_theme_stylebox(SNAME("panel_odd"), SNAME("TabContainer"))); } break; } } @@ -2389,7 +2389,7 @@ HBoxContainer *ThemeTypeEditor::_create_property_control(Theme::DataType p_data_ item_rename_cancel_button->connect("pressed", callable_mp(this, &ThemeTypeEditor::_item_rename_canceled), varray(p_data_type, p_item_name, item_name_container)); item_rename_cancel_button->hide(); } else { - item_name->add_theme_color_override("font_color", get_theme_color(SNAME("disabled_font_color"), SNAME("Editor"))); + item_name->add_theme_color_override(SNAME("font_color"), get_theme_color(SNAME("disabled_font_color"), SNAME("Editor"))); Button *item_override_button = memnew(Button); item_override_button->set_icon(get_theme_icon(SNAME("Add"), SNAME("EditorIcons"))); @@ -3251,8 +3251,8 @@ void ThemeTypeEditor::_notification(int p_what) { data_type_tabs->set_tab_icon(5, get_theme_icon(SNAME("StyleBoxFlat"), SNAME("EditorIcons"))); data_type_tabs->set_tab_icon(6, get_theme_icon(SNAME("Tools"), SNAME("EditorIcons"))); - data_type_tabs->add_theme_style_override("tab_selected", get_theme_stylebox(SNAME("tab_selected_odd"), SNAME("TabContainer"))); - data_type_tabs->add_theme_style_override("panel", get_theme_stylebox(SNAME("panel_odd"), SNAME("TabContainer"))); + data_type_tabs->add_theme_style_override(SNAME("tab_selected"), get_theme_stylebox(SNAME("tab_selected_odd"), SNAME("TabContainer"))); + data_type_tabs->add_theme_style_override(SNAME("panel"), get_theme_stylebox(SNAME("panel_odd"), SNAME("TabContainer"))); type_variation_button->set_icon(get_theme_icon(SNAME("Add"), SNAME("EditorIcons"))); } break; @@ -3532,9 +3532,9 @@ void ThemeEditor::_notification(int p_what) { switch (p_what) { case NOTIFICATION_ENTER_TREE: case NOTIFICATION_THEME_CHANGED: { - preview_tabs->add_theme_style_override("tab_selected", get_theme_stylebox(SNAME("ThemeEditorPreviewFG"), SNAME("EditorStyles"))); - preview_tabs->add_theme_style_override("tab_unselected", get_theme_stylebox(SNAME("ThemeEditorPreviewBG"), SNAME("EditorStyles"))); - preview_tabs_content->add_theme_style_override("panel", get_theme_stylebox(SNAME("panel_odd"), SNAME("TabContainer"))); + preview_tabs->add_theme_style_override(SNAME("tab_selected"), get_theme_stylebox(SNAME("ThemeEditorPreviewFG"), SNAME("EditorStyles"))); + preview_tabs->add_theme_style_override(SNAME("tab_unselected"), get_theme_stylebox(SNAME("ThemeEditorPreviewBG"), SNAME("EditorStyles"))); + preview_tabs_content->add_theme_style_override(SNAME("panel"), get_theme_stylebox(SNAME("panel_odd"), SNAME("TabContainer"))); add_preview_button->set_icon(get_theme_icon(SNAME("Add"), SNAME("EditorIcons"))); } break; @@ -3586,7 +3586,7 @@ ThemeEditor::ThemeEditor() { VBoxContainer *preview_tabs_vb = memnew(VBoxContainer); preview_tabs_vb->set_h_size_flags(SIZE_EXPAND_FILL); preview_tabs_vb->set_custom_minimum_size(Size2(520, 0) * EDSCALE); - preview_tabs_vb->add_theme_constant_override("separation", 2 * EDSCALE); + preview_tabs_vb->add_theme_constant_override(SNAME("separation"), 2 * EDSCALE); main_hs->add_child(preview_tabs_vb); HBoxContainer *preview_tabbar_hb = memnew(HBoxContainer); preview_tabs_vb->add_child(preview_tabbar_hb); diff --git a/editor/plugins/theme_editor_preview.cpp b/editor/plugins/theme_editor_preview.cpp index c4ef6e086d..a1f98df2aa 100644 --- a/editor/plugins/theme_editor_preview.cpp +++ b/editor/plugins/theme_editor_preview.cpp @@ -247,10 +247,10 @@ ThemeEditorPreview::ThemeEditorPreview() { preview_content = memnew(MarginContainer); preview_root->add_child(preview_content); - preview_content->add_theme_constant_override("margin_right", 4 * EDSCALE); - preview_content->add_theme_constant_override("margin_top", 4 * EDSCALE); - preview_content->add_theme_constant_override("margin_left", 4 * EDSCALE); - preview_content->add_theme_constant_override("margin_bottom", 4 * EDSCALE); + preview_content->add_theme_constant_override(SNAME("margin_right"), 4 * EDSCALE); + preview_content->add_theme_constant_override(SNAME("margin_top"), 4 * EDSCALE); + preview_content->add_theme_constant_override(SNAME("margin_left"), 4 * EDSCALE); + preview_content->add_theme_constant_override(SNAME("margin_bottom"), 4 * EDSCALE); preview_overlay = memnew(MarginContainer); preview_overlay->set_mouse_filter(MOUSE_FILTER_IGNORE); @@ -269,20 +269,20 @@ DefaultThemeEditorPreview::DefaultThemeEditorPreview() { preview_content->add_child(main_panel); MarginContainer *main_mc = memnew(MarginContainer); - main_mc->add_theme_constant_override("margin_right", 4 * EDSCALE); - main_mc->add_theme_constant_override("margin_top", 4 * EDSCALE); - main_mc->add_theme_constant_override("margin_left", 4 * EDSCALE); - main_mc->add_theme_constant_override("margin_bottom", 4 * EDSCALE); + main_mc->add_theme_constant_override(SNAME("margin_right"), 4 * EDSCALE); + main_mc->add_theme_constant_override(SNAME("margin_top"), 4 * EDSCALE); + main_mc->add_theme_constant_override(SNAME("margin_left"), 4 * EDSCALE); + main_mc->add_theme_constant_override(SNAME("margin_bottom"), 4 * EDSCALE); preview_content->add_child(main_mc); HBoxContainer *main_hb = memnew(HBoxContainer); main_mc->add_child(main_hb); - main_hb->add_theme_constant_override("separation", 20 * EDSCALE); + main_hb->add_theme_constant_override(SNAME("separation"), 20 * EDSCALE); VBoxContainer *first_vb = memnew(VBoxContainer); main_hb->add_child(first_vb); first_vb->set_h_size_flags(SIZE_EXPAND_FILL); - first_vb->add_theme_constant_override("separation", 10 * EDSCALE); + first_vb->add_theme_constant_override(SNAME("separation"), 10 * EDSCALE); first_vb->add_child(memnew(Label("Label"))); @@ -343,7 +343,7 @@ DefaultThemeEditorPreview::DefaultThemeEditorPreview() { VBoxContainer *second_vb = memnew(VBoxContainer); second_vb->set_h_size_flags(SIZE_EXPAND_FILL); main_hb->add_child(second_vb); - second_vb->add_theme_constant_override("separation", 10 * EDSCALE); + second_vb->add_theme_constant_override(SNAME("separation"), 10 * EDSCALE); LineEdit *le = memnew(LineEdit); le->set_text("LineEdit"); second_vb->add_child(le); @@ -383,7 +383,7 @@ DefaultThemeEditorPreview::DefaultThemeEditorPreview() { VBoxContainer *third_vb = memnew(VBoxContainer); third_vb->set_h_size_flags(SIZE_EXPAND_FILL); - third_vb->add_theme_constant_override("separation", 10 * EDSCALE); + third_vb->add_theme_constant_override(SNAME("separation"), 10 * EDSCALE); main_hb->add_child(third_vb); TabContainer *tc = memnew(TabContainer); diff --git a/editor/plugins/tiles/tile_atlas_view.cpp b/editor/plugins/tiles/tile_atlas_view.cpp index 35496795e0..ebece8ef40 100644 --- a/editor/plugins/tiles/tile_atlas_view.cpp +++ b/editor/plugins/tiles/tile_atlas_view.cpp @@ -585,7 +585,7 @@ TileAtlasView::TileAtlasView() { hbox = memnew(HBoxContainer); hbox->set_mouse_filter(Control::MOUSE_FILTER_IGNORE); - hbox->add_theme_constant_override("separation", 10); + hbox->add_theme_constant_override(SNAME("separation"), 10); hbox->hide(); margin_container->add_child(hbox); diff --git a/editor/plugins/tiles/tile_map_editor.cpp b/editor/plugins/tiles/tile_map_editor.cpp index 6e3724ead9..621cdae927 100644 --- a/editor/plugins/tiles/tile_map_editor.cpp +++ b/editor/plugins/tiles/tile_map_editor.cpp @@ -2095,7 +2095,7 @@ TileMapEditorTilesPlugin::TileMapEditorTilesPlugin() { scatter_spinbox->set_max(1000); scatter_spinbox->set_step(0.001); scatter_spinbox->set_tooltip(TTR("Defines the probability of painting nothing instead of a randomly selected tile.")); - scatter_spinbox->get_line_edit()->add_theme_constant_override("minimum_character_width", 4); + scatter_spinbox->get_line_edit()->add_theme_constant_override(SNAME("minimum_character_width"), 4); scatter_spinbox->connect("value_changed", callable_mp(this, &TileMapEditorTilesPlugin::_on_scattering_spinbox_changed)); tools_settings->add_child(scatter_spinbox); diff --git a/editor/plugins/tiles/tile_set_atlas_source_editor.cpp b/editor/plugins/tiles/tile_set_atlas_source_editor.cpp index 1bd1cd0219..7e05001b57 100644 --- a/editor/plugins/tiles/tile_set_atlas_source_editor.cpp +++ b/editor/plugins/tiles/tile_set_atlas_source_editor.cpp @@ -609,8 +609,8 @@ void TileSetAtlasSourceEditor::_update_tile_data_editors() { } // Theming. - tile_data_editors_tree->add_theme_constant_override("vseparation", 1); - tile_data_editors_tree->add_theme_constant_override("hseparation", 3); + tile_data_editors_tree->add_theme_constant_override(SNAME("vseparation"), 1); + tile_data_editors_tree->add_theme_constant_override(SNAME("hseparation"), 3); Color group_color = get_theme_color(SNAME("prop_category"), SNAME("Editor")); @@ -908,10 +908,10 @@ void TileSetAtlasSourceEditor::_update_atlas_view() { alternative_tiles_control->add_child(button); button->set_flat(true); button->set_icon(get_theme_icon(SNAME("Add"), SNAME("EditorIcons"))); - button->add_theme_style_override("normal", memnew(StyleBoxEmpty)); - button->add_theme_style_override("hover", memnew(StyleBoxEmpty)); - button->add_theme_style_override("focus", memnew(StyleBoxEmpty)); - button->add_theme_style_override("pressed", memnew(StyleBoxEmpty)); + button->add_theme_style_override(SNAME("normal"), memnew(StyleBoxEmpty)); + button->add_theme_style_override(SNAME("hover"), memnew(StyleBoxEmpty)); + button->add_theme_style_override(SNAME("focus"), memnew(StyleBoxEmpty)); + button->add_theme_style_override(SNAME("pressed"), memnew(StyleBoxEmpty)); button->connect("pressed", callable_mp(tile_set_atlas_source, &TileSetAtlasSource::create_alternative_tile), varray(tile_id, TileSetSource::INVALID_TILE_ALTERNATIVE)); button->set_rect(Rect2(Vector2(pos.x, pos.y + (y_increment - texture_region_base_size.y) / 2.0), Vector2(texture_region_base_size_min, texture_region_base_size_min))); button->set_expand_icon(true); diff --git a/editor/plugins/visual_shader_editor_plugin.cpp b/editor/plugins/visual_shader_editor_plugin.cpp index d1797e7400..ac316427da 100644 --- a/editor/plugins/visual_shader_editor_plugin.cpp +++ b/editor/plugins/visual_shader_editor_plugin.cpp @@ -679,7 +679,7 @@ void VisualShaderGraphPlugin::add_node(VisualShader::Type p_type, int p_id) { } else { hb = memnew(HBoxContainer); } - hb->add_theme_constant_override("separation", 7 * EDSCALE); + hb->add_theme_constant_override(SNAME("separation"), 7 * EDSCALE); Variant default_value; @@ -732,14 +732,14 @@ void VisualShaderGraphPlugin::add_node(VisualShader::Type p_type, int p_id) { } else { Label *label = memnew(Label); label->set_text(name_left); - label->add_theme_style_override("normal", label_style); //more compact + label->add_theme_style_override(SNAME("normal"), label_style); //more compact hb->add_child(label); if (vsnode->is_input_port_default(i, mode) && !port_left_used) { Label *hint_label = memnew(Label); hint_label->set_text(TTR("[default]")); - hint_label->add_theme_color_override("font_color", editor->get_theme_color(SNAME("font_readonly_color"), SNAME("TextEdit"))); - hint_label->add_theme_style_override("normal", label_style); + hint_label->add_theme_color_override(SNAME("font_color"), editor->get_theme_color(SNAME("font_readonly_color"), SNAME("TextEdit"))); + hint_label->add_theme_style_override(SNAME("normal"), label_style); hb->add_child(hint_label); } } @@ -779,7 +779,7 @@ void VisualShaderGraphPlugin::add_node(VisualShader::Type p_type, int p_id) { } else { Label *label = memnew(Label); label->set_text(name_right); - label->add_theme_style_override("normal", label_style); //more compact + label->add_theme_style_override(SNAME("normal"), label_style); //more compact hb->add_child(label); } } @@ -896,7 +896,7 @@ void VisualShaderGraphPlugin::add_node(VisualShader::Type p_type, int p_id) { String error = vsnode->get_warning(mode, p_type); if (!error.is_empty()) { Label *error_label = memnew(Label); - error_label->add_theme_color_override("font_color", editor->get_theme_color(SNAME("error_color"), SNAME("Editor"))); + error_label->add_theme_color_override(SNAME("font_color"), editor->get_theme_color(SNAME("error_color"), SNAME("Editor"))); error_label->set_text(error); node->add_child(error_label); } @@ -920,7 +920,7 @@ void VisualShaderGraphPlugin::add_node(VisualShader::Type p_type, int p_id) { Color members_color = EDITOR_GET("text_editor/theme/highlighting/member_variable_color"); expression_box->set_syntax_highlighter(expression_syntax_highlighter); - expression_box->add_theme_color_override("background_color", background_color); + expression_box->add_theme_color_override(SNAME("background_color"), background_color); for (const String &E : editor->keyword_list) { if (ShaderLanguage::is_control_flow_keyword(E)) { @@ -930,9 +930,9 @@ void VisualShaderGraphPlugin::add_node(VisualShader::Type p_type, int p_id) { } } - expression_box->add_theme_font_override("font", editor->get_theme_font(SNAME("expression"), SNAME("EditorFonts"))); - expression_box->add_theme_font_size_override("font_size", editor->get_theme_font_size(SNAME("expression_size"), SNAME("EditorFonts"))); - expression_box->add_theme_color_override("font_color", text_color); + expression_box->add_theme_font_override(SNAME("font"), editor->get_theme_font(SNAME("expression"), SNAME("EditorFonts"))); + expression_box->add_theme_font_size_override(SNAME("font_size"), editor->get_theme_font_size(SNAME("expression_size"), SNAME("EditorFonts"))); + expression_box->add_theme_color_override(SNAME("font_color"), text_color); expression_syntax_highlighter->set_number_color(number_color); expression_syntax_highlighter->set_symbol_color(symbol_color); expression_syntax_highlighter->set_function_color(function_color); @@ -1512,10 +1512,10 @@ void VisualShaderEditor::_update_created_node(GraphNode *node) { const Color mono_color = ((c.r + c.g + c.b) / 3) < 0.7 ? Color(1.0, 1.0, 1.0, 0.85) : Color(0.0, 0.0, 0.0, 0.85); c = mono_color; - node->add_theme_color_override("title_color", c); + node->add_theme_color_override(SNAME("title_color"), c); c.a = 0.7; - node->add_theme_color_override("close_color", c); - node->add_theme_color_override("resizer_color", c); + node->add_theme_color_override(SNAME("close_color"), c); + node->add_theme_color_override(SNAME("resizer_color"), c); } void VisualShaderEditor::_update_uniforms(bool p_update_refs) { @@ -3421,7 +3421,7 @@ void VisualShaderEditor::_notification(int p_what) { Color number_color = EDITOR_GET("text_editor/theme/highlighting/number_color"); Color members_color = EDITOR_GET("text_editor/theme/highlighting/member_variable_color"); - preview_text->add_theme_color_override("background_color", background_color); + preview_text->add_theme_color_override(SNAME("background_color"), background_color); for (const String &E : keyword_list) { if (ShaderLanguage::is_control_flow_keyword(E)) { @@ -3431,9 +3431,9 @@ void VisualShaderEditor::_notification(int p_what) { } } - preview_text->add_theme_font_override("font", get_theme_font(SNAME("expression"), SNAME("EditorFonts"))); - preview_text->add_theme_font_size_override("font_size", get_theme_font_size(SNAME("expression_size"), SNAME("EditorFonts"))); - preview_text->add_theme_color_override("font_color", text_color); + preview_text->add_theme_font_override(SNAME("font"), get_theme_font(SNAME("expression"), SNAME("EditorFonts"))); + preview_text->add_theme_font_size_override(SNAME("font_size"), get_theme_font_size(SNAME("expression_size"), SNAME("EditorFonts"))); + preview_text->add_theme_color_override(SNAME("font_color"), text_color); syntax_highlighter->set_number_color(number_color); syntax_highlighter->set_symbol_color(symbol_color); syntax_highlighter->set_function_color(function_color); @@ -3446,10 +3446,10 @@ void VisualShaderEditor::_notification(int p_what) { preview_text->add_comment_delimiter("/*", "*/", false); preview_text->add_comment_delimiter("//", "", true); - error_panel->add_theme_style_override("panel", get_theme_stylebox(SNAME("panel"), SNAME("Panel"))); - error_label->add_theme_font_override("font", get_theme_font(SNAME("status_source"), SNAME("EditorFonts"))); - error_label->add_theme_font_size_override("font_size", get_theme_font_size(SNAME("status_source_size"), SNAME("EditorFonts"))); - error_label->add_theme_color_override("font_color", get_theme_color(SNAME("error_color"), SNAME("Editor"))); + error_panel->add_theme_style_override(SNAME("panel"), get_theme_stylebox(SNAME("panel"), SNAME("Panel"))); + error_label->add_theme_font_override(SNAME("font"), get_theme_font(SNAME("status_source"), SNAME("EditorFonts"))); + error_label->add_theme_font_size_override(SNAME("font_size"), get_theme_font_size(SNAME("status_source_size"), SNAME("EditorFonts"))); + error_label->add_theme_color_override(SNAME("font_color"), get_theme_color(SNAME("error_color"), SNAME("Editor"))); } tools->set_icon(EditorNode::get_singleton()->get_gui_base()->get_theme_icon(SNAME("Tools"), SNAME("EditorIcons"))); @@ -4301,7 +4301,7 @@ VisualShaderEditor::VisualShaderEditor() { preview_vbox = memnew(VBoxContainer); preview_window->add_child(preview_vbox); - preview_vbox->add_theme_constant_override("separation", 0); + preview_vbox->add_theme_constant_override(SNAME("separation"), 0); preview_text = memnew(CodeEdit); syntax_highlighter.instantiate(); @@ -4783,11 +4783,11 @@ VisualShaderEditor::VisualShaderEditor() { // SDF { - add_options.push_back(AddOption("ScreenUVToSDF", "SDF", "", "VisualShaderNodeScreenUVToSDF", TTR("Converts screen UV to a SDF."), {}, VisualShaderNode::PORT_TYPE_VECTOR_3D, TYPE_FLAGS_FRAGMENT | TYPE_FLAGS_LIGHT, Shader::MODE_CANVAS_ITEM)); + add_options.push_back(AddOption("ScreenUVToSDF", "SDF", "", "VisualShaderNodeScreenUVToSDF", TTR("Converts screen UV to a SDF."), {}, VisualShaderNode::PORT_TYPE_VECTOR_2D, TYPE_FLAGS_FRAGMENT | TYPE_FLAGS_LIGHT, Shader::MODE_CANVAS_ITEM)); add_options.push_back(AddOption("SDFRaymarch", "SDF", "", "VisualShaderNodeSDFRaymarch", TTR("Casts a ray against the screen SDF and returns the distance travelled."), {}, -1, TYPE_FLAGS_FRAGMENT | TYPE_FLAGS_LIGHT, Shader::MODE_CANVAS_ITEM)); - add_options.push_back(AddOption("SDFToScreenUV", "SDF", "", "VisualShaderNodeSDFToScreenUV", TTR("Converts a SDF to screen UV."), {}, VisualShaderNode::PORT_TYPE_VECTOR_3D, TYPE_FLAGS_FRAGMENT | TYPE_FLAGS_LIGHT, Shader::MODE_CANVAS_ITEM)); + add_options.push_back(AddOption("SDFToScreenUV", "SDF", "", "VisualShaderNodeSDFToScreenUV", TTR("Converts a SDF to screen UV."), {}, VisualShaderNode::PORT_TYPE_VECTOR_2D, TYPE_FLAGS_FRAGMENT | TYPE_FLAGS_LIGHT, Shader::MODE_CANVAS_ITEM)); add_options.push_back(AddOption("TextureSDF", "SDF", "", "VisualShaderNodeTextureSDF", TTR("Performs a SDF texture lookup."), {}, VisualShaderNode::PORT_TYPE_SCALAR, TYPE_FLAGS_FRAGMENT | TYPE_FLAGS_LIGHT, Shader::MODE_CANVAS_ITEM)); - add_options.push_back(AddOption("TextureSDFNormal", "SDF", "", "VisualShaderNodeTextureSDFNormal", TTR("Performs a SDF normal texture lookup."), {}, VisualShaderNode::PORT_TYPE_VECTOR_3D, TYPE_FLAGS_FRAGMENT | TYPE_FLAGS_LIGHT, Shader::MODE_CANVAS_ITEM)); + add_options.push_back(AddOption("TextureSDFNormal", "SDF", "", "VisualShaderNodeTextureSDFNormal", TTR("Performs a SDF normal texture lookup."), {}, VisualShaderNode::PORT_TYPE_VECTOR_2D, TYPE_FLAGS_FRAGMENT | TYPE_FLAGS_LIGHT, Shader::MODE_CANVAS_ITEM)); } // TEXTURES @@ -4971,8 +4971,8 @@ VisualShaderEditor::VisualShaderEditor() { add_options.push_back(AddOption("Subtract", "Vector", "Operators", "VisualShaderNodeVectorOp", TTR("Subtracts 3D vector from 3D vector."), { VisualShaderNodeVectorOp::OP_SUB, VisualShaderNodeVectorOp::OP_TYPE_VECTOR_3D }, VisualShaderNode::PORT_TYPE_VECTOR_3D)); add_options.push_back(AddOption("Vector2Constant", "Vector", "Variables", "VisualShaderNodeVec2Constant", TTR("2D vector constant."), {}, VisualShaderNode::PORT_TYPE_VECTOR_2D)); - add_options.push_back(AddOption("Vector3Constant", "Vector", "Variables", "VisualShaderNodeVec3Constant", TTR("3D vector constant."), {}, VisualShaderNode::PORT_TYPE_VECTOR_3D)); add_options.push_back(AddOption("Vector2Uniform", "Vector", "Variables", "VisualShaderNodeVec2Uniform", TTR("2D vector uniform."), {}, VisualShaderNode::PORT_TYPE_VECTOR_2D)); + add_options.push_back(AddOption("Vector3Constant", "Vector", "Variables", "VisualShaderNodeVec3Constant", TTR("3D vector constant."), {}, VisualShaderNode::PORT_TYPE_VECTOR_3D)); add_options.push_back(AddOption("Vector3Uniform", "Vector", "Variables", "VisualShaderNodeVec3Uniform", TTR("3D vector uniform."), {}, VisualShaderNode::PORT_TYPE_VECTOR_3D)); // SPECIAL diff --git a/editor/project_export.cpp b/editor/project_export.cpp index f39a494df8..5e2334f5e3 100644 --- a/editor/project_export.cpp +++ b/editor/project_export.cpp @@ -1158,7 +1158,7 @@ ProjectExportDialog::ProjectExportDialog() { script_key->connect("text_changed", callable_mp(this, &ProjectExportDialog::_script_encryption_key_changed)); script_key_error = memnew(Label); script_key_error->set_text(String::utf8("• ") + TTR("Invalid Encryption Key (must be 64 hexadecimal characters long)")); - script_key_error->add_theme_color_override("font_color", EditorNode::get_singleton()->get_gui_base()->get_theme_color(SNAME("error_color"), SNAME("Editor"))); + script_key_error->add_theme_color_override(SNAME("font_color"), EditorNode::get_singleton()->get_gui_base()->get_theme_color(SNAME("error_color"), SNAME("Editor"))); sec_vb->add_margin_child(TTR("Encryption Key (256-bits as hexadecimal):"), script_key); sec_vb->add_child(script_key_error); sections->add_child(sec_vb); @@ -1227,12 +1227,12 @@ ProjectExportDialog::ProjectExportDialog() { export_error = memnew(Label); main_vb->add_child(export_error); export_error->hide(); - export_error->add_theme_color_override("font_color", EditorNode::get_singleton()->get_gui_base()->get_theme_color(SNAME("error_color"), SNAME("Editor"))); + export_error->add_theme_color_override(SNAME("font_color"), EditorNode::get_singleton()->get_gui_base()->get_theme_color(SNAME("error_color"), SNAME("Editor"))); export_warning = memnew(Label); main_vb->add_child(export_warning); export_warning->hide(); - export_warning->add_theme_color_override("font_color", EditorNode::get_singleton()->get_gui_base()->get_theme_color(SNAME("warning_color"), SNAME("Editor"))); + export_warning->add_theme_color_override(SNAME("font_color"), EditorNode::get_singleton()->get_gui_base()->get_theme_color(SNAME("warning_color"), SNAME("Editor"))); export_templates_error = memnew(HBoxContainer); main_vb->add_child(export_templates_error); @@ -1240,7 +1240,7 @@ ProjectExportDialog::ProjectExportDialog() { Label *export_error2 = memnew(Label); export_templates_error->add_child(export_error2); - export_error2->add_theme_color_override("font_color", EditorNode::get_singleton()->get_gui_base()->get_theme_color(SNAME("error_color"), SNAME("Editor"))); + export_error2->add_theme_color_override(SNAME("font_color"), EditorNode::get_singleton()->get_gui_base()->get_theme_color(SNAME("error_color"), SNAME("Editor"))); export_error2->set_text(String::utf8("• ") + TTR("Export templates for this platform are missing:") + " "); error_dialog = memnew(AcceptDialog); diff --git a/editor/project_manager.cpp b/editor/project_manager.cpp index cfb42c0741..528347b779 100644 --- a/editor/project_manager.cpp +++ b/editor/project_manager.cpp @@ -117,13 +117,13 @@ private: switch (p_type) { case MESSAGE_ERROR: { - msg->add_theme_color_override("font_color", msg->get_theme_color(SNAME("error_color"), SNAME("Editor"))); + msg->add_theme_color_override(SNAME("font_color"), msg->get_theme_color(SNAME("error_color"), SNAME("Editor"))); msg->set_modulate(Color(1, 1, 1, 1)); new_icon = msg->get_theme_icon(SNAME("StatusError"), SNAME("EditorIcons")); } break; case MESSAGE_WARNING: { - msg->add_theme_color_override("font_color", msg->get_theme_color(SNAME("warning_color"), SNAME("Editor"))); + msg->add_theme_color_override(SNAME("font_color"), msg->get_theme_color(SNAME("warning_color"), SNAME("Editor"))); msg->set_modulate(Color(1, 1, 1, 1)); new_icon = msg->get_theme_icon(SNAME("StatusWarning"), SNAME("EditorIcons")); @@ -1349,7 +1349,7 @@ void ProjectList::create_project_item_control(int p_index) { ProjectListItemControl *hb = memnew(ProjectListItemControl); hb->connect("draw", callable_mp(this, &ProjectList::_panel_draw), varray(hb)); hb->connect("gui_input", callable_mp(this, &ProjectList::_panel_input), varray(hb)); - hb->add_theme_constant_override("separation", 10 * EDSCALE); + hb->add_theme_constant_override(SNAME("separation"), 10 * EDSCALE); hb->set_tooltip(item.description); VBoxContainer *favorite_box = memnew(VBoxContainer); @@ -1394,9 +1394,9 @@ void ProjectList::create_project_item_control(int p_index) { Label *title = memnew(Label(!item.missing ? item.project_name : TTR("Missing Project"))); title->set_h_size_flags(Control::SIZE_EXPAND_FILL); - title->add_theme_font_override("font", get_theme_font(SNAME("title"), SNAME("EditorFonts"))); - title->add_theme_font_size_override("font_size", get_theme_font_size(SNAME("title_size"), SNAME("EditorFonts"))); - title->add_theme_color_override("font_color", font_color); + title->add_theme_font_override(SNAME("font"), get_theme_font(SNAME("title"), SNAME("EditorFonts"))); + title->add_theme_font_size_override(SNAME("font_size"), get_theme_font_size(SNAME("title_size"), SNAME("EditorFonts"))); + title->add_theme_color_override(SNAME("font_color"), font_color); title->set_clip_text(true); title_hb->add_child(title); @@ -1405,8 +1405,8 @@ void ProjectList::create_project_item_control(int p_index) { if (length > 0) { Label *unsupported_label = memnew(Label(unsupported_features_str)); unsupported_label->set_custom_minimum_size(Size2(length * 15, 10) * EDSCALE); - unsupported_label->add_theme_font_override("font", get_theme_font(SNAME("title"), SNAME("EditorFonts"))); - unsupported_label->add_theme_color_override("font_color", get_theme_color(SNAME("warning_color"), SNAME("Editor"))); + unsupported_label->add_theme_font_override(SNAME("font"), get_theme_font(SNAME("title"), SNAME("EditorFonts"))); + unsupported_label->add_theme_color_override(SNAME("font_color"), get_theme_color(SNAME("warning_color"), SNAME("Editor"))); unsupported_label->set_clip_text(true); unsupported_label->set_horizontal_alignment(HORIZONTAL_ALIGNMENT_RIGHT); title_hb->add_child(unsupported_label); @@ -1443,7 +1443,7 @@ void ProjectList::create_project_item_control(int p_index) { path_hb->add_child(fpath); fpath->set_h_size_flags(Control::SIZE_EXPAND_FILL); fpath->set_modulate(Color(1, 1, 1, 0.5)); - fpath->add_theme_color_override("font_color", font_color); + fpath->add_theme_color_override(SNAME("font_color"), font_color); fpath->set_clip_text(true); } @@ -2524,7 +2524,7 @@ ProjectManager::ProjectManager() { Panel *panel = memnew(Panel); add_child(panel); panel->set_anchors_and_offsets_preset(Control::PRESET_WIDE); - panel->add_theme_style_override("panel", get_theme_stylebox(SNAME("Background"), SNAME("EditorStyles"))); + panel->add_theme_style_override(SNAME("panel"), get_theme_stylebox(SNAME("Background"), SNAME("EditorStyles"))); VBoxContainer *vb = memnew(VBoxContainer); panel->add_child(vb); @@ -2562,7 +2562,7 @@ ProjectManager::ProjectManager() { hb->add_child(search_box); loading_label = memnew(Label(TTR("Loading, please wait..."))); - loading_label->add_theme_font_override("font", get_theme_font(SNAME("bold"), SNAME("EditorFonts"))); + loading_label->add_theme_font_override(SNAME("font"), get_theme_font(SNAME("bold"), SNAME("EditorFonts"))); loading_label->set_h_size_flags(Control::SIZE_EXPAND_FILL); hb->add_child(loading_label); // Hide the label but make it still take up space. This prevents reflows when showing the label. @@ -2588,7 +2588,7 @@ ProjectManager::ProjectManager() { } PanelContainer *pc = memnew(PanelContainer); - pc->add_theme_style_override("panel", get_theme_stylebox(SNAME("bg"), SNAME("Tree"))); + pc->add_theme_style_override(SNAME("panel"), get_theme_stylebox(SNAME("bg"), SNAME("Tree"))); pc->set_v_size_flags(Control::SIZE_EXPAND_FILL); search_tree_vb->add_child(pc); diff --git a/editor/project_settings_editor.cpp b/editor/project_settings_editor.cpp index c0ff1d72ee..2a72764469 100644 --- a/editor/project_settings_editor.cpp +++ b/editor/project_settings_editor.cpp @@ -509,9 +509,9 @@ void ProjectSettingsEditor::_update_action_map_editor() { void ProjectSettingsEditor::_update_theme() { search_box->set_right_icon(get_theme_icon(SNAME("Search"), SNAME("EditorIcons"))); restart_close_button->set_icon(get_theme_icon(SNAME("Close"), SNAME("EditorIcons"))); - restart_container->add_theme_style_override("panel", get_theme_stylebox(SNAME("bg"), SNAME("Tree"))); + restart_container->add_theme_style_override(SNAME("panel"), get_theme_stylebox(SNAME("bg"), SNAME("Tree"))); restart_icon->set_texture(get_theme_icon(SNAME("StatusWarning"), SNAME("EditorIcons"))); - restart_label->add_theme_color_override("font_color", get_theme_color(SNAME("warning_color"), SNAME("Editor"))); + restart_label->add_theme_color_override(SNAME("font_color"), get_theme_color(SNAME("warning_color"), SNAME("Editor"))); type_box->clear(); for (int i = 0; i < Variant::VARIANT_MAX; i++) { diff --git a/editor/quick_open.cpp b/editor/quick_open.cpp index 2a8ca67fe6..c3fb61da86 100644 --- a/editor/quick_open.cpp +++ b/editor/quick_open.cpp @@ -261,7 +261,7 @@ EditorQuickOpen::EditorQuickOpen() { search_options->create_item(); search_options->set_hide_root(true); search_options->set_hide_folding(true); - search_options->add_theme_constant_override("draw_guides", 1); + search_options->add_theme_constant_override(SNAME("draw_guides"), 1); vbc->add_margin_child(TTR("Matches:"), search_options, true); get_ok_button()->set_text(TTR("Open")); diff --git a/editor/rename_dialog.cpp b/editor/rename_dialog.cpp index c6a4c0d86a..835551c4af 100644 --- a/editor/rename_dialog.cpp +++ b/editor/rename_dialog.cpp @@ -391,9 +391,9 @@ void RenameDialog::_update_preview(String new_text) { // New name is identical to the old one. Don't color it as much to avoid distracting the user. const Color accent_color = EditorNode::get_singleton()->get_gui_base()->get_theme_color(SNAME("accent_color"), SNAME("Editor")); const Color text_color = EditorNode::get_singleton()->get_gui_base()->get_theme_color(SNAME("default_color"), SNAME("RichTextLabel")); - lbl_preview->add_theme_color_override("font_color", accent_color.lerp(text_color, 0.5)); + lbl_preview->add_theme_color_override(SNAME("font_color"), accent_color.lerp(text_color, 0.5)); } else { - lbl_preview->add_theme_color_override("font_color", EditorNode::get_singleton()->get_gui_base()->get_theme_color(SNAME("success_color"), SNAME("Editor"))); + lbl_preview->add_theme_color_override(SNAME("font_color"), EditorNode::get_singleton()->get_gui_base()->get_theme_color(SNAME("success_color"), SNAME("Editor"))); } } @@ -479,7 +479,7 @@ void RenameDialog::_error_handler(void *p_self, const char *p_func, const char * self->has_errors = true; self->lbl_preview_title->set_text(TTR("Regular Expression Error:")); - self->lbl_preview->add_theme_color_override("font_color", EditorNode::get_singleton()->get_gui_base()->get_theme_color(SNAME("error_color"), SNAME("Editor"))); + self->lbl_preview->add_theme_color_override(SNAME("font_color"), EditorNode::get_singleton()->get_gui_base()->get_theme_color(SNAME("error_color"), SNAME("Editor"))); self->lbl_preview->set_text(vformat(TTR("At character %s"), err_str)); } diff --git a/editor/scene_tree_dock.cpp b/editor/scene_tree_dock.cpp index 9b18d3a491..3c2194ccb3 100644 --- a/editor/scene_tree_dock.cpp +++ b/editor/scene_tree_dock.cpp @@ -3301,7 +3301,7 @@ SceneTreeDock::SceneTreeDock(EditorNode *p_editor, Node *p_scene_root, EditorSel VBoxContainer *vbc = this; HBoxContainer *filter_hbc = memnew(HBoxContainer); - filter_hbc->add_theme_constant_override("separate", 0); + filter_hbc->add_theme_constant_override(SNAME("separate"), 0); ED_SHORTCUT("scene_tree/rename", TTR("Rename"), Key::F2); ED_SHORTCUT_OVERRIDE("scene_tree/rename", "macos", Key::ENTER); @@ -3349,7 +3349,7 @@ SceneTreeDock::SceneTreeDock(EditorNode *p_editor, Node *p_scene_root, EditorSel filter->set_h_size_flags(SIZE_EXPAND_FILL); filter->set_placeholder(TTR("Filter nodes")); filter_hbc->add_child(filter); - filter->add_theme_constant_override("minimum_character_width", 0); + filter->add_theme_constant_override(SNAME("minimum_character_width"), 0); filter->connect("text_changed", callable_mp(this, &SceneTreeDock::_filter_changed)); button_create_script = memnew(Button); diff --git a/editor/scene_tree_editor.cpp b/editor/scene_tree_editor.cpp index e9aed53b4e..ddf7d8c465 100644 --- a/editor/scene_tree_editor.cpp +++ b/editor/scene_tree_editor.cpp @@ -1219,7 +1219,7 @@ SceneTreeEditor::SceneTreeEditor(bool p_label, bool p_can_rename, bool p_can_ope tree->set_begin(Point2(0, p_label ? 18 : 0)); tree->set_end(Point2(0, 0)); tree->set_allow_reselect(true); - tree->add_theme_constant_override("button_margin", 0); + tree->add_theme_constant_override(SNAME("button_margin"), 0); add_child(tree); @@ -1324,7 +1324,7 @@ SceneTreeDialog::SceneTreeDialog() { filter->set_h_size_flags(Control::SIZE_EXPAND_FILL); filter->set_placeholder(TTR("Filter nodes")); filter->set_clear_button_enabled(true); - filter->add_theme_constant_override("minimum_character_width", 0); + filter->add_theme_constant_override(SNAME("minimum_character_width"), 0); filter->connect("text_changed", callable_mp(this, &SceneTreeDialog::_filter_changed)); vbc->add_child(filter); diff --git a/editor/script_create_dialog.cpp b/editor/script_create_dialog.cpp index b42d4a1d6d..1fa85f8df6 100644 --- a/editor/script_create_dialog.cpp +++ b/editor/script_create_dialog.cpp @@ -70,7 +70,7 @@ void ScriptCreateDialog::_notification(int p_what) { path_button->set_icon(get_theme_icon(SNAME("Folder"), SNAME("EditorIcons"))); parent_browse_button->set_icon(get_theme_icon(SNAME("Folder"), SNAME("EditorIcons"))); parent_search_button->set_icon(get_theme_icon(SNAME("ClassList"), SNAME("EditorIcons"))); - status_panel->add_theme_style_override("panel", get_theme_stylebox(SNAME("bg"), SNAME("Tree"))); + status_panel->add_theme_style_override(SNAME("panel"), get_theme_stylebox(SNAME("bg"), SNAME("Tree"))); } break; } } @@ -291,7 +291,7 @@ void ScriptCreateDialog::_template_changed(int p_template) { template_info += " - " + sinfo.description; } template_info_label->set_text(template_info); - template_info_label->add_theme_color_override("font_color", get_theme_color(SNAME("success_color"), SNAME("Editor"))); + template_info_label->add_theme_color_override(SNAME("font_color"), get_theme_color(SNAME("success_color"), SNAME("Editor"))); } void ScriptCreateDialog::ok_pressed() { @@ -522,18 +522,18 @@ void ScriptCreateDialog::_path_submitted(const String &p_path) { void ScriptCreateDialog::_msg_script_valid(bool valid, const String &p_msg) { error_label->set_text(String::utf8("• ") + p_msg); if (valid) { - error_label->add_theme_color_override("font_color", get_theme_color(SNAME("success_color"), SNAME("Editor"))); + error_label->add_theme_color_override(SNAME("font_color"), get_theme_color(SNAME("success_color"), SNAME("Editor"))); } else { - error_label->add_theme_color_override("font_color", get_theme_color(SNAME("error_color"), SNAME("Editor"))); + error_label->add_theme_color_override(SNAME("font_color"), get_theme_color(SNAME("error_color"), SNAME("Editor"))); } } void ScriptCreateDialog::_msg_path_valid(bool valid, const String &p_msg) { path_error_label->set_text(String::utf8("• ") + p_msg); if (valid) { - path_error_label->add_theme_color_override("font_color", get_theme_color(SNAME("success_color"), SNAME("Editor"))); + path_error_label->add_theme_color_override(SNAME("font_color"), get_theme_color(SNAME("success_color"), SNAME("Editor"))); } else { - path_error_label->add_theme_color_override("font_color", get_theme_color(SNAME("error_color"), SNAME("Editor"))); + path_error_label->add_theme_color_override(SNAME("font_color"), get_theme_color(SNAME("error_color"), SNAME("Editor"))); } } @@ -658,7 +658,7 @@ void ScriptCreateDialog::_update_dialog() { class_name->set_placeholder(TTR("Allowed: a-z, A-Z, 0-9, _ and .")); Color placeholder_color = class_name->get_theme_color(SNAME("font_placeholder_color")); placeholder_color.a = 0.3; - class_name->add_theme_color_override("font_placeholder_color", placeholder_color); + class_name->add_theme_color_override(SNAME("font_placeholder_color"), placeholder_color); } else { class_name->set_editable(false); } @@ -667,7 +667,7 @@ void ScriptCreateDialog::_update_dialog() { class_name->set_placeholder(TTR("N/A")); Color placeholder_color = class_name->get_theme_color(SNAME("font_placeholder_color")); placeholder_color.a = 1; - class_name->add_theme_color_override("font_placeholder_color", placeholder_color); + class_name->add_theme_color_override(SNAME("font_placeholder_color"), placeholder_color); class_name->set_text(""); } @@ -911,7 +911,7 @@ ScriptCreateDialog::ScriptCreateDialog() { script_name_warning_label->set_text( TTR("Warning: Having the script name be the same as a built-in type is usually not desired.")); vb->add_child(script_name_warning_label); - script_name_warning_label->add_theme_color_override("font_color", Color(1, 0.85, 0.4)); + script_name_warning_label->add_theme_color_override(SNAME("font_color"), Color(1, 0.85, 0.4)); script_name_warning_label->set_autowrap_mode(Label::AUTOWRAP_WORD_SMART); script_name_warning_label->hide(); diff --git a/editor/shader_create_dialog.cpp b/editor/shader_create_dialog.cpp index 95c4c5ff0d..a34cbed2dc 100644 --- a/editor/shader_create_dialog.cpp +++ b/editor/shader_create_dialog.cpp @@ -72,7 +72,7 @@ void ShaderCreateDialog::_update_theme() { } path_button->set_icon(get_theme_icon(SNAME("Folder"), SNAME("EditorIcons"))); - status_panel->add_theme_style_override("panel", get_theme_stylebox(SNAME("bg"), SNAME("Tree"))); + status_panel->add_theme_style_override(SNAME("panel"), get_theme_stylebox(SNAME("bg"), SNAME("Tree"))); } void ShaderCreateDialog::_update_language_info() { @@ -419,18 +419,18 @@ String ShaderCreateDialog::_validate_path(const String &p_path) { void ShaderCreateDialog::_msg_script_valid(bool valid, const String &p_msg) { error_label->set_text("- " + p_msg); if (valid) { - error_label->add_theme_color_override("font_color", gc->get_theme_color(SNAME("success_color"), SNAME("Editor"))); + error_label->add_theme_color_override(SNAME("font_color"), gc->get_theme_color(SNAME("success_color"), SNAME("Editor"))); } else { - error_label->add_theme_color_override("font_color", gc->get_theme_color(SNAME("error_color"), SNAME("Editor"))); + error_label->add_theme_color_override(SNAME("font_color"), gc->get_theme_color(SNAME("error_color"), SNAME("Editor"))); } } void ShaderCreateDialog::_msg_path_valid(bool valid, const String &p_msg) { path_error_label->set_text("- " + p_msg); if (valid) { - path_error_label->add_theme_color_override("font_color", gc->get_theme_color(SNAME("success_color"), SNAME("Editor"))); + path_error_label->add_theme_color_override(SNAME("font_color"), gc->get_theme_color(SNAME("success_color"), SNAME("Editor"))); } else { - path_error_label->add_theme_color_override("font_color", gc->get_theme_color(SNAME("error_color"), SNAME("Editor"))); + path_error_label->add_theme_color_override(SNAME("font_color"), gc->get_theme_color(SNAME("error_color"), SNAME("Editor"))); } } diff --git a/misc/dist/html/editor.html b/misc/dist/html/editor.html index a681a2a1c3..9e03f50c37 100644 --- a/misc/dist/html/editor.html +++ b/misc/dist/html/editor.html @@ -265,6 +265,7 @@ <button id="btn-close-editor" class="btn close-btn" disabled="disabled" onclick="closeEditor()">×</button> <button id="btn-tab-game" class="btn tab-btn" disabled="disabled" onclick="showTab('game')">Game</button> <button id="btn-close-game" class="btn close-btn" disabled="disabled" onclick="closeGame()">×</button> + <button id="btn-tab-update" class="btn tab-btn" style="display: none;">Update</button> </div> <div id="tabs"> <div id="tab-loader"> @@ -324,10 +325,39 @@ <div id="status-notice" class="godot" style="display: none;"></div> </div> </div> - <script> + <script>//<![CDATA[ window.addEventListener("load", () => { + function notifyUpdate(sw) { + const btn = document.getElementById("btn-tab-update"); + btn.onclick = function () { + if (!window.confirm("Are you sure you want to update?\nClicking \"OK\" will reload all active instances!")) { + return; + } + sw.postMessage("update"); + btn.innerHTML = "Updating..."; + btn.disabled = true; + }; + btn.style.display = ""; + } if ("serviceWorker" in navigator) { - navigator.serviceWorker.register("service.worker.js"); + navigator.serviceWorker.register("service.worker.js").then(function (reg) { + if (reg.waiting) { + notifyUpdate(reg.waiting); + } + reg.addEventListener("updatefound", function () { + const update = reg.installing; + update.addEventListener("statechange", function () { + if (update.state === "installed") { + // It's a new install, claim and perform aggressive caching. + if (!reg.active) { + update.postMessage("claim"); + } else { + notifyUpdate(update); + } + } + }); + }); + }); } if (localStorage.getItem("welcomeModalDismissed") !== 'true') { @@ -342,7 +372,7 @@ localStorage.setItem("welcomeModalDismissed", 'true'); } } - </script> + //]]></script> <script src="godot.tools.js"></script> <script>//<![CDATA[ diff --git a/misc/dist/html/service-worker.js b/misc/dist/html/service-worker.js index 063e40a6cb..310574f21d 100644 --- a/misc/dist/html/service-worker.js +++ b/misc/dist/html/service-worker.js @@ -4,7 +4,8 @@ // Incrementing CACHE_VERSION will kick off the install event and force // previously cached resources to be updated from the network. const CACHE_VERSION = "@GODOT_VERSION@"; -const CACHE_NAME = "@GODOT_NAME@-cache"; +const CACHE_PREFIX = "@GODOT_NAME@-sw-cache-"; +const CACHE_NAME = CACHE_PREFIX + CACHE_VERSION; const OFFLINE_URL = "@GODOT_OFFLINE_PAGE@"; // Files that will be cached on load. const CACHED_FILES = @GODOT_CACHE@; @@ -13,26 +14,35 @@ const CACHABLE_FILES = @GODOT_OPT_CACHE@; const FULL_CACHE = CACHED_FILES.concat(CACHABLE_FILES); self.addEventListener("install", (event) => { - event.waitUntil(async function () { - const cache = await caches.open(CACHE_NAME); - // Clear old cache (including optionals). - await Promise.all(FULL_CACHE.map(path => cache.delete(path))); - // Insert new one. - const done = await cache.addAll(CACHED_FILES); - return done; - }()); + event.waitUntil(caches.open(CACHE_NAME).then(cache => cache.addAll(CACHED_FILES))); }); self.addEventListener("activate", (event) => { - event.waitUntil(async function () { - if ("navigationPreload" in self.registration) { - await self.registration.navigationPreload.enable(); - } - }()); - // Tell the active service worker to take control of the page immediately. - self.clients.claim(); + event.waitUntil(caches.keys().then( + function (keys) { + // Remove old caches. + return Promise.all(keys.filter(key => key.startsWith(CACHE_PREFIX) && key != CACHE_NAME).map(key => caches.delete(key))); + }).then(function() { + // Enable navigation preload if available. + return ("navigationPreload" in self.registration) ? self.registration.navigationPreload.enable() : Promise.resolve(); + }) + ); }); +async function fetchAndCache(event, cache, isCachable) { + // Use the preloaded response, if it's there + let response = await event.preloadResponse; + if (!response) { + // Or, go over network. + response = await self.fetch(event.request); + } + if (isCachable) { + // And update the cache + cache.put(event.request, response.clone()); + } + return response; +} + self.addEventListener("fetch", (event) => { const isNavigate = event.request.mode === "navigate"; const url = event.request.url || ""; @@ -42,32 +52,54 @@ self.addEventListener("fetch", (event) => { const isCachable = FULL_CACHE.some(v => v === local) || (base === referrer && base.endsWith(CACHED_FILES[0])); if (isNavigate || isCachable) { event.respondWith(async function () { - try { - // Use the preloaded response, if it's there - let request = event.request.clone(); - let response = await event.preloadResponse; - if (!response) { - // Or, go over network. - response = await fetch(event.request); - } - if (isCachable) { - // Update the cache - const cache = await caches.open(CACHE_NAME); - cache.put(request, response.clone()); - } - return response; - } catch (error) { - const cache = await caches.open(CACHE_NAME); - if (event.request.mode === "navigate") { - // Check if we have full cache. - const cached = await Promise.all(FULL_CACHE.map(name => cache.match(name))); - const missing = cached.some(v => v === undefined); - const cachedResponse = missing ? await caches.match(OFFLINE_URL) : await caches.match(CACHED_FILES[0]); - return cachedResponse; + // Try to use cache first + const cache = await caches.open(CACHE_NAME); + if (event.request.mode === "navigate") { + // Check if we have full cache during HTML page request. + const fullCache = await Promise.all(FULL_CACHE.map(name => cache.match(name))); + const missing = fullCache.some(v => v === undefined); + if (missing) { + try { + // Try network if some cached file is missing (so we can display offline page in case). + return await fetchAndCache(event, cache, isCachable); + } catch (e) { + // And return the hopefully always cached offline page in case of network failure. + console.error("Network error: ", e); + return await caches.match(OFFLINE_URL); + } } - const cachedResponse = await caches.match(event.request); - return cachedResponse; + } + const cached = await cache.match(event.request); + if (cached) { + return cached; + } else { + // Try network if don't have it in cache. + return await fetchAndCache(event, cache, isCachable); } }()); } }); + +self.addEventListener("message", (event) => { + // No cross origin + if (event.origin != self.origin) { + return; + } + const id = event.source.id || ""; + const msg = event.data || ""; + // Ensure it's one of our clients. + self.clients.get(id).then(function (client) { + if (!client) { + return; // Not a valid client. + } + if (msg === "claim") { + self.skipWaiting().then(() => self.clients.claim()); + } else if (msg === "clear") { + caches.delete(CACHE_NAME); + } else if (msg === "update") { + self.skipWaiting().then(() => self.clients.claim()).then(() => self.clients.matchAll()).then(all => all.forEach(c => c.navigate(c.url))); + } else { + onClientMessage(event); + } + }); +}); diff --git a/modules/camera/camera_osx.h b/modules/camera/camera_osx.h index 9d67235839..b0db844599 100644 --- a/modules/camera/camera_osx.h +++ b/modules/camera/camera_osx.h @@ -39,7 +39,6 @@ class CameraOSX : public CameraServer { public: CameraOSX(); - ~CameraOSX(); void update_feeds(); }; diff --git a/modules/camera/camera_osx.mm b/modules/camera/camera_osx.mm index 391006bfc2..d199c31b2f 100644 --- a/modules/camera/camera_osx.mm +++ b/modules/camera/camera_osx.mm @@ -114,18 +114,12 @@ if (output) { [self removeOutput:output]; [output setSampleBufferDelegate:nil queue:nullptr]; - [output release]; output = nullptr; } [self commitConfiguration]; } -- (void)dealloc { - // bye bye - [super dealloc]; -} - - (void)captureOutput:(AVCaptureOutput *)captureOutput didOutputSampleBuffer:(CMSampleBufferRef)sampleBuffer fromConnection:(AVCaptureConnection *)connection { // This gets called every time our camera has a new image for us to process. // May need to investigate in a way to throttle this if we get more images then we're rendering frames.. @@ -208,7 +202,6 @@ public: AVCaptureDevice *get_device() const; CameraFeedOSX(); - ~CameraFeedOSX(); void set_device(AVCaptureDevice *p_device); @@ -227,7 +220,6 @@ CameraFeedOSX::CameraFeedOSX() { void CameraFeedOSX::set_device(AVCaptureDevice *p_device) { device = p_device; - [device retain]; // get some info NSString *device_name = p_device.localizedName; @@ -240,18 +232,6 @@ void CameraFeedOSX::set_device(AVCaptureDevice *p_device) { }; }; -CameraFeedOSX::~CameraFeedOSX() { - if (capture_session != nullptr) { - [capture_session release]; - capture_session = nullptr; - }; - - if (device != nullptr) { - [device release]; - device = nullptr; - }; -}; - bool CameraFeedOSX::activate_feed() { if (capture_session) { // Already recording! @@ -282,7 +262,6 @@ void CameraFeedOSX::deactivate_feed() { // end camera capture if we have one if (capture_session) { [capture_session cleanup]; - [capture_session release]; capture_session = nullptr; }; }; @@ -317,8 +296,6 @@ void CameraFeedOSX::deactivate_feed() { // remove notifications [[NSNotificationCenter defaultCenter] removeObserver:self name:AVCaptureDeviceWasConnectedNotification object:nil]; [[NSNotificationCenter defaultCenter] removeObserver:self name:AVCaptureDeviceWasDisconnectedNotification object:nil]; - - [super dealloc]; } @end @@ -376,7 +353,3 @@ CameraOSX::CameraOSX() { // should only have one of these.... device_notifications = [[MyDeviceNotifications alloc] initForServer:this]; }; - -CameraOSX::~CameraOSX() { - [device_notifications release]; -}; diff --git a/modules/gdscript/editor_templates/CharacterBody2D/basic_movement.gd b/modules/gdscript/editor_templates/CharacterBody2D/basic_movement.gd index 0824d894c5..edaccae018 100644 --- a/modules/gdscript/editor_templates/CharacterBody2D/basic_movement.gd +++ b/modules/gdscript/editor_templates/CharacterBody2D/basic_movement.gd @@ -3,7 +3,7 @@ extends _BASE_ const SPEED: float = 300.0 -const JUMP_FORCE: float = -400.0 +const JUMP_VELOCITY: float = -400.0 # Get the gravity from the project settings to be synced with RigidDynamicBody nodes. var gravity: int = ProjectSettings.get_setting("physics/2d/default_gravity") @@ -16,7 +16,7 @@ func _physics_process(delta: float) -> void: # Handle Jump. if Input.is_action_just_pressed("ui_accept") and is_on_floor(): - motion_velocity.y = JUMP_FORCE + motion_velocity.y = JUMP_VELOCITY # Get the input direction and handle the movement/deceleration. # As good practice, you should replace UI actions with custom gameplay actions. diff --git a/modules/gdscript/editor_templates/CharacterBody3D/basic_movement.gd b/modules/gdscript/editor_templates/CharacterBody3D/basic_movement.gd index ce6d67ae84..e191e5451a 100644 --- a/modules/gdscript/editor_templates/CharacterBody3D/basic_movement.gd +++ b/modules/gdscript/editor_templates/CharacterBody3D/basic_movement.gd @@ -3,7 +3,7 @@ extends _BASE_ const SPEED: float = 5.0 -const JUMP_FORCE: float = 4.5 +const JUMP_VELOCITY: float = 4.5 # Get the gravity from the project settings to be synced with RigidDynamicBody nodes. var gravity: float = ProjectSettings.get_setting("physics/3d/default_gravity") @@ -16,7 +16,7 @@ func _physics_process(delta: float) -> void: # Handle Jump. if Input.is_action_just_pressed("ui_accept") and is_on_floor(): - motion_velocity.y = JUMP_FORCE + motion_velocity.y = JUMP_VELOCITY # Get the input direction and handle the movement/deceleration. # As good practice, you should replace UI actions with custom gameplay actions. diff --git a/modules/gdscript/editor_templates/VisualShaderNodeCustom/basic.gd b/modules/gdscript/editor_templates/VisualShaderNodeCustom/basic.gd index 27383b878d..d71f2592fe 100644 --- a/modules/gdscript/editor_templates/VisualShaderNodeCustom/basic.gd +++ b/modules/gdscript/editor_templates/VisualShaderNodeCustom/basic.gd @@ -34,8 +34,5 @@ func _get_output_port_name(port: int) -> String: func _get_output_port_type(port: int) -> int: return PORT_TYPE_SCALAR -func _get_global_code(mode: Shader.Mode) -> String: - return "" - func _get_code(input_vars: Array[String], output_vars: Array[String], mode: Shader.Mode, type: VisualShader.Type) -> String: return output_vars[0] + " = 0.0;" diff --git a/modules/gridmap/grid_map_editor_plugin.cpp b/modules/gridmap/grid_map_editor_plugin.cpp index 84510fc71e..3275851b20 100644 --- a/modules/gridmap/grid_map_editor_plugin.cpp +++ b/modules/gridmap/grid_map_editor_plugin.cpp @@ -1181,7 +1181,7 @@ GridMapEditor::GridMapEditor(EditorNode *p_editor) { floor->set_min(-32767); floor->set_max(32767); floor->set_step(1); - floor->get_line_edit()->add_theme_constant_override("minimum_character_width", 16); + floor->get_line_edit()->add_theme_constant_override(SNAME("minimum_character_width"), 16); spatial_editor_hb->add_child(floor); floor->connect("value_changed", callable_mp(this, &GridMapEditor::_floor_changed)); diff --git a/modules/mono/csharp_script.cpp b/modules/mono/csharp_script.cpp index 26436e3ec0..085ab9a467 100644 --- a/modules/mono/csharp_script.cpp +++ b/modules/mono/csharp_script.cpp @@ -3245,6 +3245,8 @@ ScriptInstance *CSharpScript::instance_create(Object *p_this) { CRASH_COND(!valid); #endif + GD_MONO_SCOPE_THREAD_ATTACH; + if (native) { StringName native_name = NATIVE_GDMONOCLASS_NAME(native); if (!ClassDB::is_parent_class(p_this->get_class_name(), native_name)) { @@ -3257,8 +3259,6 @@ ScriptInstance *CSharpScript::instance_create(Object *p_this) { } } - GD_MONO_SCOPE_THREAD_ATTACH; - Callable::CallError unchecked_error; return _create_instance(nullptr, 0, p_this, Object::cast_to<RefCounted>(p_this) != nullptr, unchecked_error); } diff --git a/modules/mono/editor_templates/CharacterBody2D/basic_movement.cs b/modules/mono/editor_templates/CharacterBody2D/basic_movement.cs index 6e9547ce9b..b0ded3133f 100644 --- a/modules/mono/editor_templates/CharacterBody2D/basic_movement.cs +++ b/modules/mono/editor_templates/CharacterBody2D/basic_movement.cs @@ -6,7 +6,7 @@ using System; public partial class _CLASS_ : _BASE_ { public const float Speed = 300.0f; - public const float JumpForce = -400.0f; + public const float JumpVelocity = -400.0f; // Get the gravity from the project settings to be synced with RigidDynamicBody nodes. public float gravity = (float)ProjectSettings.GetSetting("physics/2d/default_gravity"); @@ -21,7 +21,7 @@ public partial class _CLASS_ : _BASE_ // Handle Jump. if (Input.IsActionJustPressed("ui_accept") && IsOnFloor()) - motionVelocity.y = JumpForce; + motionVelocity.y = JumpVelocity; // Get the input direction and handle the movement/deceleration. // As good practice, you should replace UI actions with custom gameplay actions. diff --git a/modules/mono/editor_templates/CharacterBody3D/basic_movement.cs b/modules/mono/editor_templates/CharacterBody3D/basic_movement.cs index 13be4bbcb1..d8c2f67ac8 100644 --- a/modules/mono/editor_templates/CharacterBody3D/basic_movement.cs +++ b/modules/mono/editor_templates/CharacterBody3D/basic_movement.cs @@ -6,7 +6,7 @@ using System; public partial class _CLASS_ : _BASE_ { public const float Speed = 5.0f; - public const float JumpForce = 4.5f; + public const float JumpVelocity = 4.5f; // Get the gravity from the project settings to be synced with RigidDynamicBody nodes. public float gravity = (float)ProjectSettings.GetSetting("physics/3d/default_gravity"); @@ -21,7 +21,7 @@ public partial class _CLASS_ : _BASE_ // Handle Jump. if (Input.IsActionJustPressed("ui_accept") && IsOnFloor()) - motionVelocity.y = JumpForce; + motionVelocity.y = JumpVelocity; // Get the input direction and handle the movement/deceleration. // As good practice, you should replace UI actions with custom gameplay actions. diff --git a/modules/mono/editor_templates/VisualShaderNodeCustom/basic.cs b/modules/mono/editor_templates/VisualShaderNodeCustom/basic.cs index 00fdc9968e..a1b93e7daa 100644 --- a/modules/mono/editor_templates/VisualShaderNodeCustom/basic.cs +++ b/modules/mono/editor_templates/VisualShaderNodeCustom/basic.cs @@ -55,11 +55,6 @@ public partial class VisualShaderNode_CLASS_ : _BASE_ return 0; } - public override string _GetGlobalCode(Shader.Mode mode) - { - return ""; - } - public override string _GetCode(Godot.Collections.Array inputVars, Godot.Collections.Array outputVars, Shader.Mode mode, VisualShader.Type type) { return ""; diff --git a/modules/visual_script/editor/visual_script_editor.cpp b/modules/visual_script/editor/visual_script_editor.cpp index 1a7d473bd4..6e3b173fce 100644 --- a/modules/visual_script/editor/visual_script_editor.cpp +++ b/modules/visual_script/editor/visual_script_editor.cpp @@ -713,7 +713,7 @@ void VisualScriptEditor::_update_graph(int p_only_id) { LineEdit *line_edit = memnew(LineEdit); line_edit->set_text(node->get_text()); line_edit->set_expand_to_text_length_enabled(true); - line_edit->add_theme_font_override("font", get_theme_font(SNAME("source"), SNAME("EditorFonts"))); + line_edit->add_theme_font_override(SNAME("font"), get_theme_font(SNAME("source"), SNAME("EditorFonts"))); gnode->add_child(line_edit); line_edit->connect("text_changed", callable_mp(this, &VisualScriptEditor::_expression_text_changed), varray(E)); } else { @@ -743,11 +743,11 @@ void VisualScriptEditor::_update_graph(int p_only_id) { Color c = sbf->get_border_color(); c = ((c.r + c.g + c.b) / 3) < 0.7 ? Color(1.0, 1.0, 1.0, 0.85) : Color(0.0, 0.0, 0.0, 0.85); Color ic = c; - gnode->add_theme_color_override("title_color", c); + gnode->add_theme_color_override(SNAME("title_color"), c); c.a = 1; - gnode->add_theme_color_override("close_color", c); - gnode->add_theme_color_override("resizer_color", ic); - gnode->add_theme_style_override("frame", sbf); + gnode->add_theme_color_override(SNAME("close_color"), c); + gnode->add_theme_color_override(SNAME("resizer_color"), ic); + gnode->add_theme_style_override(SNAME("frame"), sbf); } const Color mono_color = get_theme_color(SNAME("mono_color"), SNAME("Editor")); @@ -2661,7 +2661,7 @@ Ref<Texture2D> VisualScriptEditor::get_theme_icon() { icon_name += "Internal"; } - if (Control::has_theme_icon(icon_name, "EditorIcons")) { + if (Control::has_theme_icon(icon_name, SNAME("EditorIcons"))) { return Control::get_theme_icon(icon_name, SNAME("EditorIcons")); } @@ -3931,13 +3931,13 @@ void VisualScriptEditor::_notification(int p_what) { update_toggle_scripts_button(); - edit_variable_edit->add_theme_style_override("bg", get_theme_stylebox(SNAME("bg"), SNAME("Tree"))); - edit_signal_edit->add_theme_style_override("bg", get_theme_stylebox(SNAME("bg"), SNAME("Tree"))); - func_input_scroll->add_theme_style_override("bg", get_theme_stylebox(SNAME("bg"), SNAME("Tree"))); + edit_variable_edit->add_theme_style_override(SNAME("bg"), get_theme_stylebox(SNAME("bg"), SNAME("Tree"))); + edit_signal_edit->add_theme_style_override(SNAME("bg"), get_theme_stylebox(SNAME("bg"), SNAME("Tree"))); + func_input_scroll->add_theme_style_override(SNAME("bg"), get_theme_stylebox(SNAME("bg"), SNAME("Tree"))); Ref<Theme> tm = EditorNode::get_singleton()->get_theme_base()->get_theme(); - bool dark_theme = tm->get_constant("dark_theme", "Editor"); + bool dark_theme = tm->get_constant(SNAME("dark_theme"), SNAME("Editor")); if (dark_theme) { node_colors["flow_control"] = Color(0.96, 0.96, 0.96); diff --git a/modules/visual_script/editor/visual_script_property_selector.cpp b/modules/visual_script/editor/visual_script_property_selector.cpp index 4072dcebe5..8913b88d1a 100644 --- a/modules/visual_script/editor/visual_script_property_selector.cpp +++ b/modules/visual_script/editor/visual_script_property_selector.cpp @@ -46,7 +46,7 @@ void VisualScriptPropertySelector::_update_icons() { search_box->set_right_icon(results_tree->get_theme_icon(SNAME("Search"), SNAME("EditorIcons"))); search_box->set_clear_button_enabled(true); - search_box->add_theme_icon_override("right_icon", results_tree->get_theme_icon(SNAME("Search"), SNAME("EditorIcons"))); + search_box->add_theme_icon_override(SNAME("right_icon"), results_tree->get_theme_icon(SNAME("Search"), SNAME("EditorIcons"))); search_visual_script_nodes->set_icon(results_tree->get_theme_icon(SNAME("VisualScript"), SNAME("EditorIcons"))); search_classes->set_icon(results_tree->get_theme_icon(SNAME("Object"), SNAME("EditorIcons"))); @@ -1114,14 +1114,14 @@ TreeItem *VisualScriptPropertySelector::SearchRunner::_create_class_item(TreeIte String details = p_doc->name; if (p_doc->category.begins_with("VisualScriptCustomNode/")) { Vector<String> path = p_doc->name.split("/"); - icon = ui_service->get_theme_icon("VisualScript", "EditorIcons"); + icon = ui_service->get_theme_icon(SNAME("VisualScript"), SNAME("EditorIcons")); text_0 = path[path.size() - 1]; text_1 = "VisualScriptCustomNode"; what = "VisualScriptCustomNode"; details = "CustomNode"; } else if (p_doc->category.begins_with("VisualScriptNode/")) { Vector<String> path = p_doc->name.split("/"); - icon = ui_service->get_theme_icon("VisualScript", "EditorIcons"); + icon = ui_service->get_theme_icon(SNAME("VisualScript"), SNAME("EditorIcons")); text_0 = path[path.size() - 1]; if (p_doc->category.begins_with("VisualScriptNode/deconstruct")) { text_0 = "deconstruct " + text_0; @@ -1142,11 +1142,11 @@ TreeItem *VisualScriptPropertySelector::SearchRunner::_create_class_item(TreeIte } else { if (p_doc->name.is_quoted()) { text_0 = p_doc->name.unquote().get_file(); - if (ui_service->has_theme_icon(p_doc->inherits, "EditorIcons")) { - icon = ui_service->get_theme_icon(p_doc->inherits, "EditorIcons"); + if (ui_service->has_theme_icon(p_doc->inherits, SNAME("EditorIcons"))) { + icon = ui_service->get_theme_icon(p_doc->inherits, SNAME("EditorIcons")); } - } else if (ui_service->has_theme_icon(p_doc->name, "EditorIcons")) { - icon = ui_service->get_theme_icon(p_doc->name, "EditorIcons"); + } else if (ui_service->has_theme_icon(p_doc->name, SNAME("EditorIcons"))) { + icon = ui_service->get_theme_icon(p_doc->name, SNAME("EditorIcons")); } else if (ClassDB::class_exists(p_doc->name) && ClassDB::is_parent_class(p_doc->name, "Object")) { icon = ui_service->get_theme_icon(SNAME("Object"), SNAME("EditorIcons")); } diff --git a/platform/javascript/api/api.cpp b/platform/javascript/api/api.cpp index 0c4accccc3..4190b24b8e 100644 --- a/platform/javascript/api/api.cpp +++ b/platform/javascript/api/api.cpp @@ -71,6 +71,9 @@ void JavaScript::_bind_methods() { ClassDB::bind_vararg_method(METHOD_FLAGS_DEFAULT, "create_object", &JavaScript::_create_object_bind, mi); } ClassDB::bind_method(D_METHOD("download_buffer", "buffer", "name", "mime"), &JavaScript::download_buffer, DEFVAL("application/octet-stream")); + ClassDB::bind_method(D_METHOD("pwa_needs_update"), &JavaScript::pwa_needs_update); + ClassDB::bind_method(D_METHOD("pwa_update"), &JavaScript::pwa_update); + ADD_SIGNAL(MethodInfo("pwa_update_available")); } #if !defined(JAVASCRIPT_ENABLED) || !defined(JAVASCRIPT_EVAL_ENABLED) @@ -102,6 +105,12 @@ Variant JavaScript::_create_object_bind(const Variant **p_args, int p_argcount, } #endif #if !defined(JAVASCRIPT_ENABLED) +bool JavaScript::pwa_needs_update() const { + return false; +} +Error JavaScript::pwa_update() { + return ERR_UNAVAILABLE; +} void JavaScript::download_buffer(Vector<uint8_t> p_arr, const String &p_name, const String &p_mime) { } #endif diff --git a/platform/javascript/api/javascript_singleton.h b/platform/javascript/api/javascript_singleton.h index 63f1aec624..e93b0a18a1 100644 --- a/platform/javascript/api/javascript_singleton.h +++ b/platform/javascript/api/javascript_singleton.h @@ -59,6 +59,8 @@ public: Ref<JavaScriptObject> create_callback(const Callable &p_callable); Variant _create_object_bind(const Variant **p_args, int p_argcount, Callable::CallError &r_error); void download_buffer(Vector<uint8_t> p_arr, const String &p_name, const String &p_mime = "application/octet-stream"); + bool pwa_needs_update() const; + Error pwa_update(); static JavaScript *get_singleton(); JavaScript(); diff --git a/platform/javascript/export/export_plugin.cpp b/platform/javascript/export/export_plugin.cpp index 92826630b4..d4c198d631 100644 --- a/platform/javascript/export/export_plugin.cpp +++ b/platform/javascript/export/export_plugin.cpp @@ -139,8 +139,7 @@ void EditorExportPlatformJavaScript::_fix_html(Vector<uint8_t> &p_html, const Re } if (p_preset->get("progressive_web_app/enabled")) { head_include += "<link rel='manifest' href='" + p_name + ".manifest.json'>\n"; - head_include += "<script type='application/javascript'>window.addEventListener('load', () => {if ('serviceWorker' in navigator) {navigator.serviceWorker.register('" + - p_name + ".service.worker.js');}});</script>\n"; + config["serviceWorker"] = p_name + ".service.worker.js"; } // Replaces HTML string @@ -188,35 +187,46 @@ Error EditorExportPlatformJavaScript::_add_manifest_icon(const String &p_path, c } Error EditorExportPlatformJavaScript::_build_pwa(const Ref<EditorExportPreset> &p_preset, const String p_path, const Vector<SharedObject> &p_shared_objects) { + String proj_name = ProjectSettings::get_singleton()->get_setting("application/config/name"); + if (proj_name.is_empty()) { + proj_name = "Godot Game"; + } + // Service worker const String dir = p_path.get_base_dir(); const String name = p_path.get_file().get_basename(); const ExportMode mode = (ExportMode)(int)p_preset->get("variant/export_type"); Map<String, String> replaces; - replaces["@GODOT_VERSION@"] = "1"; - replaces["@GODOT_NAME@"] = name; + replaces["@GODOT_VERSION@"] = String::num_int64(OS::get_singleton()->get_unix_time()) + "|" + String::num_int64(OS::get_singleton()->get_ticks_usec()); + replaces["@GODOT_NAME@"] = proj_name.substr(0, 16); replaces["@GODOT_OFFLINE_PAGE@"] = name + ".offline.html"; - Array files; - replaces["@GODOT_OPT_CACHE@"] = Variant(files).to_json_string(); - files.push_back(name + ".html"); - files.push_back(name + ".js"); - files.push_back(name + ".wasm"); - files.push_back(name + ".pck"); - files.push_back(name + ".offline.html"); + + // Files cached during worker install. + Array cache_files; + cache_files.push_back(name + ".html"); + cache_files.push_back(name + ".js"); + cache_files.push_back(name + ".offline.html"); if (p_preset->get("html/export_icon")) { - files.push_back(name + ".icon.png"); - files.push_back(name + ".apple-touch-icon.png"); + cache_files.push_back(name + ".icon.png"); + cache_files.push_back(name + ".apple-touch-icon.png"); } if (mode == EXPORT_MODE_THREADS) { - files.push_back(name + ".worker.js"); - files.push_back(name + ".audio.worklet.js"); - } else if (mode == EXPORT_MODE_GDNATIVE) { - files.push_back(name + ".side.wasm"); + cache_files.push_back(name + ".worker.js"); + cache_files.push_back(name + ".audio.worklet.js"); + } + replaces["@GODOT_CACHE@"] = Variant(cache_files).to_json_string(); + + // Heavy files that are cached on demand. + Array opt_cache_files; + opt_cache_files.push_back(name + ".wasm"); + opt_cache_files.push_back(name + ".pck"); + if (mode == EXPORT_MODE_GDNATIVE) { + opt_cache_files.push_back(name + ".side.wasm"); for (int i = 0; i < p_shared_objects.size(); i++) { - files.push_back(p_shared_objects[i].path.get_file()); + opt_cache_files.push_back(p_shared_objects[i].path.get_file()); } } - replaces["@GODOT_CACHE@"] = Variant(files).to_json_string(); + replaces["@GODOT_OPT_CACHE@"] = Variant(opt_cache_files).to_json_string(); const String sw_path = dir.plus_file(name + ".service.worker.js"); Vector<uint8_t> sw; @@ -256,10 +266,6 @@ Error EditorExportPlatformJavaScript::_build_pwa(const Ref<EditorExportPreset> & const int orientation = CLAMP(int(p_preset->get("progressive_web_app/orientation")), 0, 3); Dictionary manifest; - String proj_name = ProjectSettings::get_singleton()->get_setting("application/config/name"); - if (proj_name.is_empty()) { - proj_name = "Godot Game"; - } manifest["name"] = proj_name; manifest["start_url"] = "./" + name + ".html"; manifest["display"] = String::utf8(modes[display]); diff --git a/platform/javascript/godot_js.h b/platform/javascript/godot_js.h index 15de8b5dc7..2cb5c3025c 100644 --- a/platform/javascript/godot_js.h +++ b/platform/javascript/godot_js.h @@ -49,6 +49,8 @@ extern void godot_js_os_fs_sync(void (*p_callback)()); extern int godot_js_os_execute(const char *p_json); extern void godot_js_os_shell_open(const char *p_uri); extern int godot_js_os_hw_concurrency_get(); +extern int godot_js_pwa_cb(void (*p_callback)()); +extern int godot_js_pwa_update(); // Input extern void godot_js_input_mouse_button_cb(int (*p_callback)(int p_pressed, int p_button, double p_x, double p_y, int p_modifiers)); diff --git a/platform/javascript/javascript_singleton.cpp b/platform/javascript/javascript_singleton.cpp index b10e8007c0..77858bff01 100644 --- a/platform/javascript/javascript_singleton.cpp +++ b/platform/javascript/javascript_singleton.cpp @@ -30,6 +30,7 @@ #include "api/javascript_singleton.h" #include "emscripten.h" +#include "os_javascript.h" extern "C" { extern void godot_js_os_download_buffer(const uint8_t *p_buf, int p_buf_size, const char *p_name, const char *p_mime); @@ -355,3 +356,10 @@ Variant JavaScript::eval(const String &p_code, bool p_use_global_exec_context) { void JavaScript::download_buffer(Vector<uint8_t> p_arr, const String &p_name, const String &p_mime) { godot_js_os_download_buffer(p_arr.ptr(), p_arr.size(), p_name.utf8().get_data(), p_mime.utf8().get_data()); } + +bool JavaScript::pwa_needs_update() const { + return OS_JavaScript::get_singleton()->pwa_needs_update(); +} +Error JavaScript::pwa_update() { + return OS_JavaScript::get_singleton()->pwa_update(); +} diff --git a/platform/javascript/js/engine/config.js b/platform/javascript/js/engine/config.js index a6f9c4614c..2e5e1ed0d1 100644 --- a/platform/javascript/js/engine/config.js +++ b/platform/javascript/js/engine/config.js @@ -107,6 +107,13 @@ const InternalConfig = function (initConfig) { // eslint-disable-line no-unused- */ experimentalVK: false, /** + * The progressive web app service worker to install. + * @memberof EngineConfig + * @default + * @type {string} + */ + serviceWorker: '', + /** * @ignore * @type {Array.<string>} */ @@ -249,6 +256,7 @@ const InternalConfig = function (initConfig) { // eslint-disable-line no-unused- this.persistentDrops = parse('persistentDrops', this.persistentDrops); this.experimentalVK = parse('experimentalVK', this.experimentalVK); this.focusCanvas = parse('focusCanvas', this.focusCanvas); + this.serviceWorker = parse('serviceWorker', this.serviceWorker); this.gdnativeLibs = parse('gdnativeLibs', this.gdnativeLibs); this.fileSizes = parse('fileSizes', this.fileSizes); this.args = parse('args', this.args); diff --git a/platform/javascript/js/engine/engine.js b/platform/javascript/js/engine/engine.js index 17a8df9e29..d2ba595083 100644 --- a/platform/javascript/js/engine/engine.js +++ b/platform/javascript/js/engine/engine.js @@ -189,6 +189,9 @@ const Engine = (function () { preloader.preloadedFiles.length = 0; // Clear memory me.rtenv['callMain'](me.config.args); initPromise = null; + if (me.config.serviceWorker && 'serviceWorker' in navigator) { + navigator.serviceWorker.register(me.config.serviceWorker); + } resolve(); }); }); diff --git a/platform/javascript/js/libs/library_godot_os.js b/platform/javascript/js/libs/library_godot_os.js index 662d215443..12d06a8d51 100644 --- a/platform/javascript/js/libs/library_godot_os.js +++ b/platform/javascript/js/libs/library_godot_os.js @@ -368,3 +368,58 @@ const GodotEventListeners = { }, }; mergeInto(LibraryManager.library, GodotEventListeners); + +const GodotPWA = { + + $GodotPWA__deps: ['$GodotRuntime', '$GodotEventListeners'], + $GodotPWA: { + hasUpdate: false, + + updateState: function (cb, reg) { + if (!reg) { + return; + } + if (!reg.active) { + return; + } + if (reg.waiting) { + GodotPWA.hasUpdate = true; + cb(); + } + GodotEventListeners.add(reg, 'updatefound', function () { + const installing = reg.installing; + GodotEventListeners.add(installing, 'statechange', function () { + if (installing.state === 'installed') { + GodotPWA.hasUpdate = true; + cb(); + } + }); + }); + }, + }, + + godot_js_pwa_cb__sig: 'vi', + godot_js_pwa_cb: function (p_update_cb) { + if ('serviceWorker' in navigator) { + const cb = GodotRuntime.get_func(p_update_cb); + navigator.serviceWorker.getRegistration().then(GodotPWA.updateState.bind(null, cb)); + } + }, + + godot_js_pwa_update__sig: 'i', + godot_js_pwa_update: function () { + if ('serviceWorker' in navigator && GodotPWA.hasUpdate) { + navigator.serviceWorker.getRegistration().then(function (reg) { + if (!reg || !reg.waiting) { + return; + } + reg.waiting.postMessage('update'); + }); + return 0; + } + return 1; + }, +}; + +autoAddDeps(GodotPWA, '$GodotPWA'); +mergeInto(LibraryManager.library, GodotPWA); diff --git a/platform/javascript/os_javascript.cpp b/platform/javascript/os_javascript.cpp index 39eea13ca1..de5ca44f9d 100644 --- a/platform/javascript/os_javascript.cpp +++ b/platform/javascript/os_javascript.cpp @@ -45,6 +45,7 @@ #include <emscripten.h> #include <stdlib.h> +#include "api/javascript_singleton.h" #include "godot_js.h" void OS_JavaScript::alert(const String &p_alert, const String &p_title) { @@ -203,6 +204,19 @@ void OS_JavaScript::file_access_close_callback(const String &p_file, int p_flags } } +void OS_JavaScript::update_pwa_state_callback() { + if (OS_JavaScript::get_singleton()) { + OS_JavaScript::get_singleton()->pwa_is_waiting = true; + } + if (JavaScript::get_singleton()) { + JavaScript::get_singleton()->emit_signal("pwa_update_available"); + } +} + +Error OS_JavaScript::pwa_update() { + return godot_js_pwa_update() ? FAILED : OK; +} + bool OS_JavaScript::is_userfs_persistent() const { return idb_available; } @@ -226,6 +240,8 @@ OS_JavaScript::OS_JavaScript() { godot_js_config_locale_get(locale_ptr, 16); setenv("LANG", locale_ptr, true); + godot_js_pwa_cb(&OS_JavaScript::update_pwa_state_callback); + if (AudioDriverJavaScript::is_available()) { #ifdef NO_THREADS audio_drivers.push_back(memnew(AudioDriverScriptProcessor)); diff --git a/platform/javascript/os_javascript.h b/platform/javascript/os_javascript.h index 3404fe9dcf..9e272f9aa1 100644 --- a/platform/javascript/os_javascript.h +++ b/platform/javascript/os_javascript.h @@ -45,11 +45,13 @@ class OS_JavaScript : public OS_Unix { bool idb_is_syncing = false; bool idb_available = false; bool idb_needs_sync = false; + bool pwa_is_waiting = false; static void main_loop_callback(); static void file_access_close_callback(const String &p_file, int p_flags); static void fs_sync_callback(); + static void update_pwa_state_callback(); protected: void initialize() override; @@ -65,6 +67,9 @@ public: // Override return type to make writing static callbacks less tedious. static OS_JavaScript *get_singleton(); + bool pwa_needs_update() const { return pwa_is_waiting; } + Error pwa_update(); + void initialize_joypads() override; MainLoop *get_main_loop() const override; diff --git a/platform/osx/SCsub b/platform/osx/SCsub index 8ba106d1c2..d72a75af04 100644 --- a/platform/osx/SCsub +++ b/platform/osx/SCsub @@ -6,14 +6,21 @@ from platform_methods import run_in_subprocess import platform_osx_builders files = [ - "crash_handler_osx.mm", "os_osx.mm", + "godot_application.mm", + "godot_application_delegate.mm", + "crash_handler_osx.mm", + "osx_terminal_logger.mm", "display_server_osx.mm", + "godot_content_view.mm", + "godot_window_delegate.mm", + "godot_window.mm", + "key_mapping_osx.mm", "godot_main_osx.mm", "dir_access_osx.mm", "joypad_osx.cpp", "vulkan_context_osx.mm", - "gl_manager_osx.mm", + "gl_manager_osx_legacy.mm", ] prog = env.add_program("#bin/godot", files) diff --git a/platform/osx/detect.py b/platform/osx/detect.py index c67791b340..e7fe37d4b5 100644 --- a/platform/osx/detect.py +++ b/platform/osx/detect.py @@ -78,14 +78,16 @@ def configure(env): env["osxcross"] = True if env["arch"] == "arm64": - print("Building for macOS 10.15+, platform arm64.") - env.Append(CCFLAGS=["-arch", "arm64", "-mmacosx-version-min=10.15"]) - env.Append(LINKFLAGS=["-arch", "arm64", "-mmacosx-version-min=10.15"]) + print("Building for macOS 11.00+, platform arm64.") + env.Append(CCFLAGS=["-arch", "arm64", "-mmacosx-version-min=11.00"]) + env.Append(LINKFLAGS=["-arch", "arm64", "-mmacosx-version-min=11.00"]) else: print("Building for macOS 10.12+, platform x86_64.") env.Append(CCFLAGS=["-arch", "x86_64", "-mmacosx-version-min=10.12"]) env.Append(LINKFLAGS=["-arch", "x86_64", "-mmacosx-version-min=10.12"]) + env.Append(CCFLAGS=["-fobjc-arc"]) + if not "osxcross" in env: # regular native build if env["macports_clang"] != "no": mpprefix = os.environ.get("MACPORTS_PREFIX", "/opt/local") @@ -188,6 +190,8 @@ def configure(env): env.Append(CCFLAGS=["-Wno-deprecated-declarations"]) # Disable deprecation warnings env.Append(LINKFLAGS=["-framework", "OpenGL"]) + env.Append(LINKFLAGS=["-rpath", "@executable_path/../Frameworks", "-rpath", "@executable_path"]) + if env["vulkan"]: env.Append(CPPDEFINES=["VULKAN_ENABLED"]) env.Append(LINKFLAGS=["-framework", "Metal", "-framework", "QuartzCore", "-framework", "IOSurface"]) diff --git a/platform/osx/display_server_osx.h b/platform/osx/display_server_osx.h index 4fc733fe2c..eaf03d298e 100644 --- a/platform/osx/display_server_osx.h +++ b/platform/osx/display_server_osx.h @@ -37,13 +37,13 @@ #include "servers/display_server.h" #if defined(GLES3_ENABLED) -#include "gl_manager_osx.h" -#endif +#include "gl_manager_osx_legacy.h" +#endif // GLES3_ENABLED #if defined(VULKAN_ENABLED) #include "drivers/vulkan/rendering_device_vulkan.h" #include "platform/osx/vulkan_context_osx.h" -#endif +#endif // VULKAN_ENABLED #include <AppKit/AppKit.h> #include <AppKit/NSCursor.h> @@ -59,27 +59,8 @@ class DisplayServerOSX : public DisplayServer { _THREAD_SAFE_CLASS_ public: - void _send_event(NSEvent *p_event); - NSMenu *_get_dock_menu() const; - void _menu_callback(id p_sender); - -#if defined(GLES3_ENABLED) - GLManager_OSX *gl_manager = nullptr; -#endif -#if defined(VULKAN_ENABLED) - VulkanContextOSX *context_vulkan = nullptr; - RenderingDeviceVulkan *rendering_device_vulkan = nullptr; -#endif - - const NSMenu *_get_menu_root(const String &p_menu_root) const; - NSMenu *_get_menu_root(const String &p_menu_root); - - NSMenu *apple_menu = nullptr; - NSMenu *dock_menu = nullptr; - Map<String, NSMenu *> submenu; - struct KeyEvent { - WindowID window_id; + WindowID window_id = INVALID_WINDOW_ID; unsigned int osx_state = false; bool pressed = false; bool echo = false; @@ -89,20 +70,6 @@ public: uint32_t unicode = 0; }; - struct WarpEvent { - NSTimeInterval timestamp; - NSPoint delta; - }; - - List<WarpEvent> warp_events; - NSTimeInterval last_warp = 0; - bool ignore_warp = false; - - float display_max_scale = 1.f; - - Vector<KeyEvent> key_event_buffer; - int key_event_pos; - struct WindowData { id window_delegate; id window_object; @@ -116,8 +83,6 @@ public: Size2i max_size; Size2i size; - bool mouse_down_control = false; - bool im_active = false; Size2i im_position; @@ -140,49 +105,102 @@ public: bool no_focus = false; }; +private: +#if defined(GLES3_ENABLED) + GLManager_OSX *gl_manager = nullptr; +#endif +#if defined(VULKAN_ENABLED) + VulkanContextOSX *context_vulkan = nullptr; + RenderingDeviceVulkan *rendering_device_vulkan = nullptr; +#endif + String rendering_driver; + + NSMenu *apple_menu = nullptr; + NSMenu *dock_menu = nullptr; + Map<String, NSMenu *> submenu; + + struct WarpEvent { + NSTimeInterval timestamp; + NSPoint delta; + }; + List<WarpEvent> warp_events; + NSTimeInterval last_warp = 0; + bool ignore_warp = false; + + Vector<KeyEvent> key_event_buffer; + int key_event_pos = 0; + Point2i im_selection; String im_text; - Map<WindowID, WindowData> windows; + CGEventSourceRef event_source; + MouseMode mouse_mode = MOUSE_MODE_VISIBLE; + MouseButton last_button_state = MouseButton::NONE; - WindowID last_focused_window = INVALID_WINDOW_ID; + bool drop_events = false; + bool in_dispatch_input_event = false; + + struct LayoutInfo { + String name; + String code; + }; + Vector<LayoutInfo> kbd_layouts; + int current_layout = 0; + bool keyboard_layout_dirty = true; + WindowID last_focused_window = INVALID_WINDOW_ID; WindowID window_id_counter = MAIN_WINDOW_ID; + float display_max_scale = 1.f; + Point2i origin; + bool displays_arrangement_dirty = true; - WindowID _create_window(WindowMode p_mode, VSyncMode p_vsync_mode, const Rect2i &p_rect); - void _update_window(WindowData p_wd); - void _send_window_event(const WindowData &wd, WindowEvent p_event); - static void _dispatch_input_events(const Ref<InputEvent> &p_event); - void _dispatch_input_event(const Ref<InputEvent> &p_event); - WindowID _find_window_id(id p_window); + CursorShape cursor_shape = CURSOR_ARROW; + NSCursor *cursors[CURSOR_MAX]; + Map<CursorShape, Vector<Variant>> cursors_cache; + + Map<WindowID, WindowData> windows; + + const NSMenu *_get_menu_root(const String &p_menu_root) const; + NSMenu *_get_menu_root(const String &p_menu_root); + WindowID _create_window(WindowMode p_mode, VSyncMode p_vsync_mode, const Rect2i &p_rect); + void _update_window_style(WindowData p_wd); void _set_window_per_pixel_transparency_enabled(bool p_enabled, WindowID p_window); + void _update_displays_arrangement(); Point2i _get_screens_origin() const; Point2i _get_native_screen_position(int p_screen) const; + static void _displays_arrangement_changed(CGDirectDisplayID display_id, CGDisplayChangeSummaryFlags flags, void *user_info); + static void _dispatch_input_events(const Ref<InputEvent> &p_event); + void _dispatch_input_event(const Ref<InputEvent> &p_event); void _push_input(const Ref<InputEvent> &p_event); void _process_key_events(); - void _release_pressed_events(); + void _update_keyboard_layouts(); + static void _keyboard_layout_changed(CFNotificationCenterRef center, void *observer, CFStringRef name, const void *object, CFDictionaryRef user_info); - String rendering_driver; + static NSCursor *_cursor_from_selector(SEL p_selector, SEL p_fallback = nil); - id autoreleasePool; - CGEventSourceRef eventSource; +public: + NSMenu *get_dock_menu() const; + void menu_callback(id p_sender); - CursorShape cursor_shape; - NSCursor *cursors[CURSOR_MAX]; - Map<CursorShape, Vector<Variant>> cursors_cache; + bool has_window(WindowID p_window) const; + WindowData &get_window(WindowID p_window); - MouseMode mouse_mode; - Point2i last_mouse_pos; - MouseButton last_button_state = MouseButton::NONE; + void send_event(NSEvent *p_event); + void send_window_event(const WindowData &p_wd, WindowEvent p_event); + void release_pressed_events(); + void get_key_modifier_state(unsigned int p_osx_state, Ref<InputEventWithModifiers> r_state) const; + void update_mouse_pos(WindowData &p_wd, NSPoint p_location_in_window); + void push_to_key_event_buffer(const KeyEvent &p_event); + void update_im_text(const Point2i &p_selection, const String &p_text); + void set_last_focused_window(WindowID p_window); - bool window_focused; - bool drop_events; - bool in_dispatch_input_event = false; + void window_update(WindowID p_window); + void window_destroy(WindowID p_window); + void window_resize(WindowID p_window, int p_width, int p_height); -public: virtual bool has_feature(Feature p_feature) const override; virtual String get_name() const override; @@ -216,8 +234,10 @@ public: virtual void mouse_set_mode(MouseMode p_mode) override; virtual MouseMode mouse_get_mode() const override; + bool update_mouse_wrap(WindowData &p_wd, NSPoint &r_delta, NSPoint &r_mpos, NSTimeInterval p_timestamp); virtual void mouse_warp_to_position(const Point2i &p_to) override; virtual Point2i mouse_get_position() const override; + void mouse_set_button_state(MouseButton p_state); virtual MouseButton mouse_get_button_state() const override; virtual void clipboard_set(const String &p_text) override; @@ -297,6 +317,7 @@ public: virtual Point2i ime_get_selection() const override; virtual String ime_get_text() const override; + void cursor_update_shape(); virtual void cursor_set_shape(CursorShape p_shape) override; virtual CursorShape cursor_get_shape() const override; virtual void cursor_set_custom_image(const RES &p_cursor, CursorShape p_shape = CURSOR_ARROW, const Vector2 &p_hotspot = Vector2()) override; diff --git a/platform/osx/display_server_osx.mm b/platform/osx/display_server_osx.mm index 000be79852..ba10d7593f 100644 --- a/platform/osx/display_server_osx.mm +++ b/platform/osx/display_server_osx.mm @@ -30,6 +30,11 @@ #include "display_server_osx.h" +#include "godot_content_view.h" +#include "godot_menu_item.h" +#include "godot_window.h" +#include "godot_window_delegate.h" +#include "key_mapping_osx.h" #include "os_osx.h" #include "core/io/marshalls.h" @@ -47,217 +52,121 @@ #if defined(GLES3_ENABLED) #include "drivers/gles3/rasterizer_gles3.h" - -#import <AppKit/NSOpenGLView.h> #endif #if defined(VULKAN_ENABLED) #include "servers/rendering/renderer_rd/renderer_compositor_rd.h" - -#include <QuartzCore/CAMetalLayer.h> -#endif - -#ifndef NSAppKitVersionNumber10_14 -#define NSAppKitVersionNumber10_14 1671 #endif -#define DS_OSX ((DisplayServerOSX *)(DisplayServerOSX::get_singleton())) - -static bool ignore_momentum_scroll = false; - -static void _get_key_modifier_state(unsigned int p_osx_state, Ref<InputEventWithModifiers> r_state) { - r_state->set_shift_pressed((p_osx_state & NSEventModifierFlagShift)); - r_state->set_ctrl_pressed((p_osx_state & NSEventModifierFlagControl)); - r_state->set_alt_pressed((p_osx_state & NSEventModifierFlagOption)); - r_state->set_meta_pressed((p_osx_state & NSEventModifierFlagCommand)); -} - -static Vector2i _get_mouse_pos(DisplayServerOSX::WindowData &p_wd, NSPoint p_locationInWindow) { - const NSRect contentRect = [p_wd.window_view frame]; - const float scale = DS_OSX->screen_get_max_scale(); - p_wd.mouse_pos.x = p_locationInWindow.x * scale; - p_wd.mouse_pos.y = (contentRect.size.height - p_locationInWindow.y) * scale; - DS_OSX->last_mouse_pos = p_wd.mouse_pos; - Input::get_singleton()->set_mouse_position(p_wd.mouse_pos); - return p_wd.mouse_pos; -} - -static void _push_to_key_event_buffer(const DisplayServerOSX::KeyEvent &p_event) { - Vector<DisplayServerOSX::KeyEvent> &buffer = DS_OSX->key_event_buffer; - if (DS_OSX->key_event_pos >= buffer.size()) { - buffer.resize(1 + DS_OSX->key_event_pos); - } - buffer.write[DS_OSX->key_event_pos++] = p_event; -} - -static NSCursor *_cursorFromSelector(SEL selector, SEL fallback = nil) { - if ([NSCursor respondsToSelector:selector]) { - id object = [NSCursor performSelector:selector]; - if ([object isKindOfClass:[NSCursor class]]) { - return object; +const NSMenu *DisplayServerOSX::_get_menu_root(const String &p_menu_root) const { + const NSMenu *menu = nullptr; + if (p_menu_root == "") { + // Main menu. + menu = [NSApp mainMenu]; + } else if (p_menu_root.to_lower() == "_dock") { + // macOS dock menu. + menu = dock_menu; + } else { + // Submenu. + if (submenu.has(p_menu_root)) { + menu = submenu[p_menu_root]; } } - if (fallback) { - // Fallback should be a reasonable default, no need to check. - return [NSCursor performSelector:fallback]; - } - return [NSCursor arrowCursor]; -} - -/*************************************************************************/ -/* GlobalMenuItem */ -/*************************************************************************/ - -@interface GlobalMenuItem : NSObject { -@public - Callable callback; - Variant meta; - bool checkable; -} - -@end - -@implementation GlobalMenuItem -@end - -/*************************************************************************/ -/* GodotWindowDelegate */ -/*************************************************************************/ - -@interface GodotWindowDelegate : NSObject { - DisplayServerOSX::WindowID window_id; -} - -- (void)windowWillClose:(NSNotification *)notification; -- (void)setWindowID:(DisplayServerOSX::WindowID)wid; - -@end - -@implementation GodotWindowDelegate - -- (void)setWindowID:(DisplayServerOSX::WindowID)wid { - window_id = wid; -} - -- (BOOL)windowShouldClose:(id)sender { - if (!DS_OSX || !DS_OSX->windows.has(window_id)) { - return YES; + if (menu == apple_menu) { + // Do not allow to change Apple menu. + return nullptr; } - DS_OSX->_send_window_event(DS_OSX->windows[window_id], DisplayServerOSX::WINDOW_EVENT_CLOSE_REQUEST); - return NO; + return menu; } -- (void)windowWillClose:(NSNotification *)notification { - if (!DS_OSX || !DS_OSX->windows.has(window_id)) { - return; - } - DisplayServerOSX::WindowData &wd = DS_OSX->windows[window_id]; - - while (wd.transient_children.size()) { - DS_OSX->window_set_transient(wd.transient_children.front()->get(), DisplayServerOSX::INVALID_WINDOW_ID); - } - - if (wd.transient_parent != DisplayServerOSX::INVALID_WINDOW_ID) { - DS_OSX->window_set_transient(window_id, DisplayServerOSX::INVALID_WINDOW_ID); - } - -#if defined(GLES3_ENABLED) - if (DS_OSX->gl_manager) { - DS_OSX->gl_manager->window_destroy(window_id); - } -#endif -#ifdef VULKAN_ENABLED - if (DS_OSX->context_vulkan) { - DS_OSX->context_vulkan->window_destroy(window_id); +NSMenu *DisplayServerOSX::_get_menu_root(const String &p_menu_root) { + NSMenu *menu = nullptr; + if (p_menu_root == "") { + // Main menu. + menu = [NSApp mainMenu]; + } else if (p_menu_root.to_lower() == "_dock") { + // macOS dock menu. + menu = dock_menu; + } else { + // Submenu. + if (!submenu.has(p_menu_root)) { + NSMenu *n_menu = [[NSMenu alloc] initWithTitle:[NSString stringWithUTF8String:p_menu_root.utf8().get_data()]]; + submenu[p_menu_root] = n_menu; + } + menu = submenu[p_menu_root]; } -#endif - - DS_OSX->windows.erase(window_id); -} - -- (void)windowDidEnterFullScreen:(NSNotification *)notification { - if (!DS_OSX || !DS_OSX->windows.has(window_id)) { - return; + if (menu == apple_menu) { + // Do not allow to change Apple menu. + return nullptr; } - DisplayServerOSX::WindowData &wd = DS_OSX->windows[window_id]; - - wd.fullscreen = true; - - [wd.window_object setContentMinSize:NSMakeSize(0, 0)]; - [wd.window_object setContentMaxSize:NSMakeSize(FLT_MAX, FLT_MAX)]; - // Force window resize event. - [self windowDidResize:notification]; + return menu; } -- (void)windowDidExitFullScreen:(NSNotification *)notification { - if (!DS_OSX || !DS_OSX->windows.has(window_id)) { - return; - } - DisplayServerOSX::WindowData &wd = DS_OSX->windows[window_id]; - - wd.fullscreen = false; - - const float scale = DS_OSX->screen_get_max_scale(); - if (wd.min_size != Size2i()) { - Size2i size = wd.min_size / scale; - [wd.window_object setContentMinSize:NSMakeSize(size.x, size.y)]; - } - if (wd.max_size != Size2i()) { - Size2i size = wd.max_size / scale; - [wd.window_object setContentMaxSize:NSMakeSize(size.x, size.y)]; - } - - if (wd.resize_disabled) { - [wd.window_object setStyleMask:[wd.window_object styleMask] & ~NSWindowStyleMaskResizable]; - } - - if (wd.on_top) { - [wd.window_object setLevel:NSFloatingWindowLevel]; - } - // Force window resize event. - [self windowDidResize:notification]; -} +DisplayServerOSX::WindowID DisplayServerOSX::_create_window(WindowMode p_mode, VSyncMode p_vsync_mode, const Rect2i &p_rect) { + WindowID id; + const float scale = screen_get_max_scale(); + { + WindowData wd; -- (void)windowDidChangeBackingProperties:(NSNotification *)notification { - if (!DisplayServerOSX::get_singleton()) { - return; - } + wd.window_delegate = [[GodotWindowDelegate alloc] init]; + ERR_FAIL_COND_V_MSG(wd.window_delegate == nil, INVALID_WINDOW_ID, "Can't create a window delegate"); + [wd.window_delegate setWindowID:window_id_counter]; - ERR_FAIL_COND(!DS_OSX->windows.has(window_id)); - DisplayServerOSX::WindowData &wd = DS_OSX->windows[window_id]; + Point2i position = p_rect.position; + // OS X native y-coordinate relative to _get_screens_origin() is negative, + // Godot passes a positive value. + position.y *= -1; + position += _get_screens_origin(); - CGFloat newBackingScaleFactor = [wd.window_object backingScaleFactor]; - CGFloat oldBackingScaleFactor = [[[notification userInfo] objectForKey:@"NSBackingPropertyOldScaleFactorKey"] doubleValue]; + // initWithContentRect uses bottom-left corner of the window’s frame as origin. + wd.window_object = [[GodotWindow alloc] + initWithContentRect:NSMakeRect(position.x / scale, (position.y - p_rect.size.height) / scale, p_rect.size.width / scale, p_rect.size.height / scale) + styleMask:NSWindowStyleMaskTitled | NSWindowStyleMaskClosable | NSWindowStyleMaskMiniaturizable | NSWindowStyleMaskResizable + backing:NSBackingStoreBuffered + defer:NO]; + ERR_FAIL_COND_V_MSG(wd.window_object == nil, INVALID_WINDOW_ID, "Can't create a window"); - if (newBackingScaleFactor != oldBackingScaleFactor) { - //Set new display scale and window size - const float scale = DS_OSX->screen_get_max_scale(); - const NSRect contentRect = [wd.window_view frame]; + wd.window_view = [[GodotContentView alloc] init]; + ERR_FAIL_COND_V_MSG(wd.window_view == nil, INVALID_WINDOW_ID, "Can't create a window view"); + [wd.window_view setWindowID:window_id_counter]; + [wd.window_view setWantsLayer:TRUE]; - wd.size.width = contentRect.size.width * scale; - wd.size.height = contentRect.size.height * scale; + [wd.window_object setCollectionBehavior:NSWindowCollectionBehaviorFullScreenPrimary]; + [wd.window_object setContentView:wd.window_view]; + [wd.window_object setDelegate:wd.window_delegate]; + [wd.window_object setAcceptsMouseMovedEvents:YES]; + [wd.window_object setRestorable:NO]; + [wd.window_object setColorSpace:[NSColorSpace sRGBColorSpace]]; - DS_OSX->_send_window_event(wd, DisplayServerOSX::WINDOW_EVENT_DPI_CHANGE); + if ([wd.window_object respondsToSelector:@selector(setTabbingMode:)]) { + [wd.window_object setTabbingMode:NSWindowTabbingModeDisallowed]; + } CALayer *layer = [wd.window_view layer]; if (layer) { layer.contentsScale = scale; } - //Force window resize event - [self windowDidResize:notification]; +#if defined(VULKAN_ENABLED) + if (context_vulkan) { + Error err = context_vulkan->window_create(window_id_counter, p_vsync_mode, wd.window_view, p_rect.size.width, p_rect.size.height); + ERR_FAIL_COND_V_MSG(err != OK, INVALID_WINDOW_ID, "Can't create a Vulkan context"); + } +#endif +#if defined(GLES3_ENABLED) + if (gl_manager) { + Error err = gl_manager->window_create(window_id_counter, wd.window_view, p_rect.size.width, p_rect.size.height); + ERR_FAIL_COND_V_MSG(err != OK, INVALID_WINDOW_ID, "Can't create an OpenGL context"); + } +#endif + id = window_id_counter++; + windows[id] = wd; } -} -- (void)windowDidResize:(NSNotification *)notification { - if (!DS_OSX || !DS_OSX->windows.has(window_id)) { - return; - } - DisplayServerOSX::WindowData &wd = DS_OSX->windows[window_id]; + WindowData &wd = windows[id]; + window_set_mode(p_mode, id); const NSRect contentRect = [wd.window_view frame]; - - const float scale = DS_OSX->screen_get_max_scale(); wd.size.width = contentRect.size.width * scale; wd.size.height = contentRect.size.height * scale; @@ -267,1204 +176,448 @@ static NSCursor *_cursorFromSelector(SEL selector, SEL fallback = nil) { } #if defined(GLES3_ENABLED) - if (DS_OSX->gl_manager) { - DS_OSX->gl_manager->window_resize(window_id, wd.size.width, wd.size.height); + if (gl_manager) { + gl_manager->window_resize(id, wd.size.width, wd.size.height); } #endif #if defined(VULKAN_ENABLED) - if (DS_OSX->context_vulkan) { - DS_OSX->context_vulkan->window_resize(window_id, wd.size.width, wd.size.height); + if (context_vulkan) { + context_vulkan->window_resize(id, wd.size.width, wd.size.height); } #endif - if (!wd.rect_changed_callback.is_null()) { - Variant size = Rect2i(DS_OSX->window_get_position(window_id), DS_OSX->window_get_size(window_id)); - Variant *sizep = &size; - Variant ret; - Callable::CallError ce; - wd.rect_changed_callback.call((const Variant **)&sizep, 1, ret, ce); - } + return id; } -- (void)windowDidMove:(NSNotification *)notification { - if (!DS_OSX || !DS_OSX->windows.has(window_id)) { - return; - } - DisplayServerOSX::WindowData &wd = DS_OSX->windows[window_id]; - - DS_OSX->_release_pressed_events(); +void DisplayServerOSX::_update_window_style(WindowData p_wd) { + bool borderless_full = false; - if (!wd.rect_changed_callback.is_null()) { - Variant size = Rect2i(DS_OSX->window_get_position(window_id), DS_OSX->window_get_size(window_id)); - Variant *sizep = &size; - Variant ret; - Callable::CallError ce; - wd.rect_changed_callback.call((const Variant **)&sizep, 1, ret, ce); - } -} + if (p_wd.borderless) { + NSRect frameRect = [p_wd.window_object frame]; + NSRect screenRect = [[p_wd.window_object screen] frame]; -- (void)windowDidBecomeKey:(NSNotification *)notification { - if (!DS_OSX || !DS_OSX->windows.has(window_id)) { - return; + // Check if our window covers up the screen. + if (frameRect.origin.x <= screenRect.origin.x && frameRect.origin.y <= frameRect.origin.y && + frameRect.size.width >= screenRect.size.width && frameRect.size.height >= screenRect.size.height) { + borderless_full = true; + } } - DisplayServerOSX::WindowData &wd = DS_OSX->windows[window_id]; - if (DS_OSX->mouse_mode == DisplayServer::MOUSE_MODE_CAPTURED) { - const NSRect contentRect = [wd.window_view frame]; - NSRect pointInWindowRect = NSMakeRect(contentRect.size.width / 2, contentRect.size.height / 2, 0, 0); - NSPoint pointOnScreen = [[wd.window_view window] convertRectToScreen:pointInWindowRect].origin; - CGPoint lMouseWarpPos = { pointOnScreen.x, CGDisplayBounds(CGMainDisplayID()).size.height - pointOnScreen.y }; - CGWarpMouseCursorPosition(lMouseWarpPos); + if (borderless_full) { + // If the window covers up the screen set the level to above the main menu and hide on deactivate. + [p_wd.window_object setLevel:NSMainMenuWindowLevel + 1]; + [p_wd.window_object setHidesOnDeactivate:YES]; } else { - _ALLOW_DISCARD_ _get_mouse_pos(wd, [wd.window_object mouseLocationOutsideOfEventStream]); - Input::get_singleton()->set_mouse_position(wd.mouse_pos); - } - - DS_OSX->window_focused = true; - DS_OSX->last_focused_window = window_id; - DS_OSX->_send_window_event(wd, DisplayServerOSX::WINDOW_EVENT_FOCUS_IN); -} - -- (void)windowDidResignKey:(NSNotification *)notification { - if (!DS_OSX || !DS_OSX->windows.has(window_id)) { - return; + // Reset these when our window is not a borderless window that covers up the screen. + if (p_wd.on_top && !p_wd.fullscreen) { + [p_wd.window_object setLevel:NSFloatingWindowLevel]; + } else { + [p_wd.window_object setLevel:NSNormalWindowLevel]; + } + [p_wd.window_object setHidesOnDeactivate:NO]; } - DisplayServerOSX::WindowData &wd = DS_OSX->windows[window_id]; - - DS_OSX->window_focused = false; - - DS_OSX->_release_pressed_events(); - DS_OSX->_send_window_event(wd, DisplayServerOSX::WINDOW_EVENT_FOCUS_OUT); } -- (void)windowDidMiniaturize:(NSNotification *)notification { - if (!DS_OSX || !DS_OSX->windows.has(window_id)) { - return; - } - DisplayServerOSX::WindowData &wd = DS_OSX->windows[window_id]; - - DS_OSX->window_focused = false; - - DS_OSX->_release_pressed_events(); - DS_OSX->_send_window_event(wd, DisplayServerOSX::WINDOW_EVENT_FOCUS_OUT); -} +void DisplayServerOSX::_set_window_per_pixel_transparency_enabled(bool p_enabled, WindowID p_window) { + ERR_FAIL_COND(!windows.has(p_window)); + WindowData &wd = windows[p_window]; -- (void)windowDidDeminiaturize:(NSNotification *)notification { - if (!DS_OSX || !DS_OSX->windows.has(window_id)) { + if (!OS::get_singleton()->is_layered_allowed()) { return; } - DisplayServerOSX::WindowData &wd = DS_OSX->windows[window_id]; - - DS_OSX->window_focused = true; - DS_OSX->last_focused_window = window_id; - DS_OSX->_send_window_event(wd, DisplayServerOSX::WINDOW_EVENT_FOCUS_IN); -} - -@end - -/*************************************************************************/ -/* GodotContentView */ -/*************************************************************************/ - + if (wd.layered_window != p_enabled) { + if (p_enabled) { + [wd.window_object setBackgroundColor:[NSColor clearColor]]; + [wd.window_object setOpaque:NO]; + [wd.window_object setHasShadow:NO]; + CALayer *layer = [wd.window_view layer]; + if (layer) { + [layer setBackgroundColor:[NSColor clearColor].CGColor]; + [layer setOpaque:NO]; + } #if defined(GLES3_ENABLED) -@interface GodotContentView : NSOpenGLView <NSTextInputClient> { -#else -@interface GodotContentView : NSView <NSTextInputClient> { -#endif - - DisplayServerOSX::WindowID window_id; - NSTrackingArea *trackingArea; - NSMutableAttributedString *markedText; - bool imeInputEventInProgress; -} - -- (void)cancelComposition; -- (CALayer *)makeBackingLayer; -- (BOOL)wantsUpdateLayer; -- (void)updateLayer; -- (void)setWindowID:(DisplayServerOSX::WindowID)wid; - -@end - -@implementation GodotContentView - -- (void)setWindowID:(DisplayServerOSX::WindowID)wid { - window_id = wid; -} - -+ (void)initialize { - if (self == [GodotContentView class]) { - // nothing left to do here at the moment.. - } -} - -- (CALayer *)makeBackingLayer { -#if defined(VULKAN_ENABLED) - if (DS_OSX->context_vulkan) { - CALayer *layer = [[CAMetalLayer class] layer]; - return layer; - } + if (gl_manager) { + gl_manager->window_set_per_pixel_transparency_enabled(p_window, true); + } #endif - return [super makeBackingLayer]; -} - -- (void)updateLayer { + wd.layered_window = true; + } else { + [wd.window_object setBackgroundColor:[NSColor colorWithCalibratedWhite:1 alpha:1]]; + [wd.window_object setOpaque:YES]; + [wd.window_object setHasShadow:YES]; + CALayer *layer = [wd.window_view layer]; + if (layer) { + [layer setBackgroundColor:[NSColor colorWithCalibratedWhite:1 alpha:1].CGColor]; + [layer setOpaque:YES]; + } #if defined(GLES3_ENABLED) - if (DS_OSX->gl_manager) { - DS_OSX->gl_manager->window_update(window_id); - } + if (gl_manager) { + gl_manager->window_set_per_pixel_transparency_enabled(p_window, false); + } #endif -#if defined(VULKAN_ENABLED) - if (DS_OSX->context_vulkan) { - [super updateLayer]; + wd.layered_window = false; + } + NSRect frameRect = [wd.window_object frame]; + [wd.window_object setFrame:NSMakeRect(frameRect.origin.x, frameRect.origin.y, frameRect.size.width + 1, frameRect.size.height) display:YES]; + [wd.window_object setFrame:frameRect display:YES]; } -#endif -} - -- (BOOL)wantsUpdateLayer { - return YES; } -- (id)init { - self = [super init]; - trackingArea = nil; - imeInputEventInProgress = false; - [self updateTrackingAreas]; -#if MAC_OS_X_VERSION_MIN_REQUIRED >= 101400 - [self registerForDraggedTypes:[NSArray arrayWithObject:NSPasteboardTypeFileURL]]; -#else - [self registerForDraggedTypes:[NSArray arrayWithObject:NSFilenamesPboardType]]; -#endif - markedText = [[NSMutableAttributedString alloc] init]; - return self; -} +void DisplayServerOSX::_update_displays_arrangement() { + origin = Point2i(); -- (void)dealloc { - [trackingArea release]; - [markedText release]; - [super dealloc]; + for (int i = 0; i < get_screen_count(); i++) { + Point2i position = _get_native_screen_position(i); + if (position.x < origin.x) { + origin.x = position.x; + } + if (position.y > origin.y) { + origin.y = position.y; + } + } + displays_arrangement_dirty = false; } -static const NSRange kEmptyRange = { NSNotFound, 0 }; - -- (BOOL)hasMarkedText { - return (markedText.length > 0); -} +Point2i DisplayServerOSX::_get_screens_origin() const { + // Returns the native top-left screen coordinate of the smallest rectangle + // that encompasses all screens. Needed in get_screen_position(), + // window_get_position, and window_set_position() + // to convert between OS X native screen coordinates and the ones expected by Godot. -- (NSRange)markedRange { - return NSMakeRange(0, markedText.length); -} + if (displays_arrangement_dirty) { + const_cast<DisplayServerOSX *>(this)->_update_displays_arrangement(); + } -- (NSRange)selectedRange { - return kEmptyRange; + return origin; } -- (void)setMarkedText:(id)aString selectedRange:(NSRange)selectedRange replacementRange:(NSRange)replacementRange { - if ([aString isKindOfClass:[NSAttributedString class]]) { - [markedText initWithAttributedString:aString]; - } else { - [markedText initWithString:aString]; - } - if (markedText.length == 0) { - [self unmarkText]; - return; +Point2i DisplayServerOSX::_get_native_screen_position(int p_screen) const { + NSArray *screenArray = [NSScreen screens]; + if ((NSUInteger)p_screen < [screenArray count]) { + NSRect nsrect = [[screenArray objectAtIndex:p_screen] frame]; + // Return the top-left corner of the screen, for OS X the y starts at the bottom. + return Point2i(nsrect.origin.x, nsrect.origin.y + nsrect.size.height) * screen_get_max_scale(); } - ERR_FAIL_COND(!DS_OSX->windows.has(window_id)); - DisplayServerOSX::WindowData &wd = DS_OSX->windows[window_id]; - - if (wd.im_active) { - imeInputEventInProgress = true; - DS_OSX->im_text.parse_utf8([[markedText mutableString] UTF8String]); - DS_OSX->im_selection = Point2i(selectedRange.location, selectedRange.length); + return Point2i(); +} - OS_OSX::get_singleton()->get_main_loop()->notification(MainLoop::NOTIFICATION_OS_IME_UPDATE); +void DisplayServerOSX::_displays_arrangement_changed(CGDirectDisplayID display_id, CGDisplayChangeSummaryFlags flags, void *user_info) { + DisplayServerOSX *ds = (DisplayServerOSX *)DisplayServer::get_singleton(); + if (ds) { + ds->displays_arrangement_dirty = true; } } -- (void)doCommandBySelector:(SEL)aSelector { - if ([self respondsToSelector:aSelector]) { - [self performSelector:aSelector]; - } +void DisplayServerOSX::_dispatch_input_events(const Ref<InputEvent> &p_event) { + ((DisplayServerOSX *)(get_singleton()))->_dispatch_input_event(p_event); } -- (void)unmarkText { - imeInputEventInProgress = false; - [[markedText mutableString] setString:@""]; +void DisplayServerOSX::_dispatch_input_event(const Ref<InputEvent> &p_event) { + _THREAD_SAFE_METHOD_ + if (!in_dispatch_input_event) { + in_dispatch_input_event = true; - ERR_FAIL_COND(!DS_OSX->windows.has(window_id)); - DisplayServerOSX::WindowData &wd = DS_OSX->windows[window_id]; + Variant ev = p_event; + Variant *evp = &ev; + Variant ret; + Callable::CallError ce; - if (wd.im_active) { - DS_OSX->im_text = String(); - DS_OSX->im_selection = Point2i(); + Ref<InputEventFromWindow> event_from_window = p_event; + if (event_from_window.is_valid() && event_from_window->get_window_id() != INVALID_WINDOW_ID) { + // Send to a window. + if (windows.has(event_from_window->get_window_id())) { + Callable callable = windows[event_from_window->get_window_id()].input_event_callback; + if (callable.is_null()) { + return; + } + callable.call((const Variant **)&evp, 1, ret, ce); + } + } else { + // Send to all windows. + for (Map<WindowID, WindowData>::Element *E = windows.front(); E; E = E->next()) { + Callable callable = E->get().input_event_callback; + if (callable.is_null()) { + continue; + } + callable.call((const Variant **)&evp, 1, ret, ce); + } + } - OS_OSX::get_singleton()->get_main_loop()->notification(MainLoop::NOTIFICATION_OS_IME_UPDATE); + in_dispatch_input_event = false; } } -- (NSArray *)validAttributesForMarkedText { - return [NSArray array]; -} - -- (NSAttributedString *)attributedSubstringForProposedRange:(NSRange)aRange actualRange:(NSRangePointer)actualRange { - return nil; -} - -- (NSUInteger)characterIndexForPoint:(NSPoint)aPoint { - return 0; -} - -- (NSRect)firstRectForCharacterRange:(NSRange)aRange actualRange:(NSRangePointer)actualRange { - ERR_FAIL_COND_V(!DS_OSX->windows.has(window_id), NSMakeRect(0, 0, 0, 0)); - DisplayServerOSX::WindowData &wd = DS_OSX->windows[window_id]; - - const NSRect contentRect = [wd.window_view frame]; - const float scale = DS_OSX->screen_get_max_scale(); - NSRect pointInWindowRect = NSMakeRect(wd.im_position.x / scale, contentRect.size.height - (wd.im_position.y / scale) - 1, 0, 0); - NSPoint pointOnScreen = [wd.window_object convertRectToScreen:pointInWindowRect].origin; - - return NSMakeRect(pointOnScreen.x, pointOnScreen.y, 0, 0); +void DisplayServerOSX::_push_input(const Ref<InputEvent> &p_event) { + Ref<InputEvent> ev = p_event; + Input::get_singleton()->parse_input_event(ev); } -- (void)cancelComposition { - [self unmarkText]; - NSTextInputContext *currentInputContext = [NSTextInputContext currentInputContext]; - [currentInputContext discardMarkedText]; -} +void DisplayServerOSX::_process_key_events() { + Ref<InputEventKey> k; + for (int i = 0; i < key_event_pos; i++) { + const KeyEvent &ke = key_event_buffer[i]; + if (ke.raw) { + // Non IME input - no composite characters, pass events as is. + k.instantiate(); -- (void)insertText:(id)aString { - [self insertText:aString replacementRange:NSMakeRange(0, 0)]; -} + k->set_window_id(ke.window_id); + get_key_modifier_state(ke.osx_state, k); + k->set_pressed(ke.pressed); + k->set_echo(ke.echo); + k->set_keycode(ke.keycode); + k->set_physical_keycode((Key)ke.physical_keycode); + k->set_unicode(ke.unicode); -- (void)insertText:(id)aString replacementRange:(NSRange)replacementRange { - NSEvent *event = [NSApp currentEvent]; + _push_input(k); + } else { + // IME input. + if ((i == 0 && ke.keycode == Key::NONE) || (i > 0 && key_event_buffer[i - 1].keycode == Key::NONE)) { + k.instantiate(); - NSString *characters; - if ([aString isKindOfClass:[NSAttributedString class]]) { - characters = [aString string]; - } else { - characters = (NSString *)aString; - } + k->set_window_id(ke.window_id); + get_key_modifier_state(ke.osx_state, k); + k->set_pressed(ke.pressed); + k->set_echo(ke.echo); + k->set_keycode(Key::NONE); + k->set_physical_keycode(Key::NONE); + k->set_unicode(ke.unicode); - NSCharacterSet *ctrlChars = [NSCharacterSet controlCharacterSet]; - NSCharacterSet *wsnlChars = [NSCharacterSet whitespaceAndNewlineCharacterSet]; - if ([characters rangeOfCharacterFromSet:ctrlChars].length && [characters rangeOfCharacterFromSet:wsnlChars].length == 0) { - NSTextInputContext *currentInputContext = [NSTextInputContext currentInputContext]; - [currentInputContext discardMarkedText]; - [self cancelComposition]; - return; - } + _push_input(k); + } + if (ke.keycode != Key::NONE) { + k.instantiate(); - Char16String text; - text.resize([characters length] + 1); - [characters getCharacters:(unichar *)text.ptrw() range:NSMakeRange(0, [characters length])]; + k->set_window_id(ke.window_id); + get_key_modifier_state(ke.osx_state, k); + k->set_pressed(ke.pressed); + k->set_echo(ke.echo); + k->set_keycode(ke.keycode); + k->set_physical_keycode((Key)ke.physical_keycode); - String u32text; - u32text.parse_utf16(text.ptr(), text.length()); + if (i + 1 < key_event_pos && key_event_buffer[i + 1].keycode == Key::NONE) { + k->set_unicode(key_event_buffer[i + 1].unicode); + } - for (int i = 0; i < u32text.length(); i++) { - const char32_t codepoint = u32text[i]; - if ((codepoint & 0xFF00) == 0xF700) { - continue; + _push_input(k); + } } - - DisplayServerOSX::KeyEvent ke; - - ke.window_id = window_id; - ke.osx_state = [event modifierFlags]; - ke.pressed = true; - ke.echo = false; - ke.raw = false; // IME input event - ke.keycode = Key::NONE; - ke.physical_keycode = Key::NONE; - ke.unicode = codepoint; - - _push_to_key_event_buffer(ke); } - [self cancelComposition]; -} -- (NSDragOperation)draggingEntered:(id<NSDraggingInfo>)sender { - return NSDragOperationCopy; + key_event_pos = 0; } -- (NSDragOperation)draggingUpdated:(id<NSDraggingInfo>)sender { - return NSDragOperationCopy; -} +void DisplayServerOSX::_update_keyboard_layouts() { + kbd_layouts.clear(); + current_layout = 0; -- (BOOL)performDragOperation:(id<NSDraggingInfo>)sender { - ERR_FAIL_COND_V(!DS_OSX->windows.has(window_id), NO); - DisplayServerOSX::WindowData &wd = DS_OSX->windows[window_id]; + TISInputSourceRef cur_source = TISCopyCurrentKeyboardInputSource(); + NSString *cur_name = (__bridge NSString *)TISGetInputSourceProperty(cur_source, kTISPropertyLocalizedName); + CFRelease(cur_source); - if (!wd.drop_files_callback.is_null()) { - Vector<String> files; - NSPasteboard *pboard = [sender draggingPasteboard]; + // Enum IME layouts. + NSDictionary *filter_ime = @{ (NSString *)kTISPropertyInputSourceType : (NSString *)kTISTypeKeyboardInputMode }; + NSArray *list_ime = (__bridge NSArray *)TISCreateInputSourceList((__bridge CFDictionaryRef)filter_ime, false); + for (NSUInteger i = 0; i < [list_ime count]; i++) { + LayoutInfo ly; + NSString *name = (__bridge NSString *)TISGetInputSourceProperty((__bridge TISInputSourceRef)[list_ime objectAtIndex:i], kTISPropertyLocalizedName); + ly.name.parse_utf8([name UTF8String]); -#if MAC_OS_X_VERSION_MIN_REQUIRED >= 101400 - NSArray *items = pboard.pasteboardItems; - for (NSPasteboardItem *item in items) { - NSString *path = [item stringForType:NSPasteboardTypeFileURL]; - NSString *ns = [NSURL URLWithString:path].path; - char *utfs = strdup([ns UTF8String]); - String ret; - ret.parse_utf8(utfs); - free(utfs); - files.push_back(ret); - } -#else - NSArray *filenames = [pboard propertyListForType:NSFilenamesPboardType]; - for (NSString *ns in filenames) { - char *utfs = strdup([ns UTF8String]); - String ret; - ret.parse_utf8(utfs); - free(utfs); - files.push_back(ret); - } -#endif + NSArray *langs = (__bridge NSArray *)TISGetInputSourceProperty((__bridge TISInputSourceRef)[list_ime objectAtIndex:i], kTISPropertyInputSourceLanguages); + ly.code.parse_utf8([(NSString *)[langs objectAtIndex:0] UTF8String]); + kbd_layouts.push_back(ly); - Variant v = files; - Variant *vp = &v; - Variant ret; - Callable::CallError ce; - wd.drop_files_callback.call((const Variant **)&vp, 1, ret, ce); + if ([name isEqualToString:cur_name]) { + current_layout = kbd_layouts.size() - 1; + } } - return NO; -} + // Enum plain keyboard layouts. + NSDictionary *filter_kbd = @{ (NSString *)kTISPropertyInputSourceType : (NSString *)kTISTypeKeyboardLayout }; + NSArray *list_kbd = (__bridge NSArray *)TISCreateInputSourceList((__bridge CFDictionaryRef)filter_kbd, false); + for (NSUInteger i = 0; i < [list_kbd count]; i++) { + LayoutInfo ly; + NSString *name = (__bridge NSString *)TISGetInputSourceProperty((__bridge TISInputSourceRef)[list_kbd objectAtIndex:i], kTISPropertyLocalizedName); + ly.name.parse_utf8([name UTF8String]); -- (BOOL)isOpaque { - return YES; -} + NSArray *langs = (__bridge NSArray *)TISGetInputSourceProperty((__bridge TISInputSourceRef)[list_kbd objectAtIndex:i], kTISPropertyInputSourceLanguages); + ly.code.parse_utf8([(NSString *)[langs objectAtIndex:0] UTF8String]); + kbd_layouts.push_back(ly); -- (BOOL)canBecomeKeyView { - if (DS_OSX->windows.has(window_id)) { - DisplayServerOSX::WindowData &wd = DS_OSX->windows[window_id]; - if (wd.no_focus) { - return NO; + if ([name isEqualToString:cur_name]) { + current_layout = kbd_layouts.size() - 1; } } - return YES; -} - -- (BOOL)acceptsFirstResponder { - return YES; -} -- (void)cursorUpdate:(NSEvent *)event { - DisplayServer::CursorShape p_shape = DS_OSX->cursor_shape; - DS_OSX->cursor_shape = DisplayServer::CURSOR_MAX; - DS_OSX->cursor_set_shape(p_shape); + keyboard_layout_dirty = false; } -static void _mouseDownEvent(DisplayServer::WindowID window_id, NSEvent *event, MouseButton index, MouseButton mask, bool pressed) { - ERR_FAIL_COND(!DS_OSX->windows.has(window_id)); - DisplayServerOSX::WindowData &wd = DS_OSX->windows[window_id]; - - if (pressed) { - DS_OSX->last_button_state |= mask; - } else { - DS_OSX->last_button_state &= (MouseButton)~mask; - } - - Ref<InputEventMouseButton> mb; - mb.instantiate(); - mb->set_window_id(window_id); - const Vector2 pos = _get_mouse_pos(wd, [event locationInWindow]); - _get_key_modifier_state([event modifierFlags], mb); - mb->set_button_index(index); - mb->set_pressed(pressed); - mb->set_position(pos); - mb->set_global_position(pos); - mb->set_button_mask(DS_OSX->last_button_state); - if (index == MouseButton::LEFT && pressed) { - mb->set_double_click([event clickCount] == 2); +void DisplayServerOSX::_keyboard_layout_changed(CFNotificationCenterRef center, void *observer, CFStringRef name, const void *object, CFDictionaryRef user_info) { + DisplayServerOSX *ds = (DisplayServerOSX *)DisplayServer::get_singleton(); + if (ds) { + ds->keyboard_layout_dirty = true; } - - Input::get_singleton()->parse_input_event(mb); } -- (void)mouseDown:(NSEvent *)event { - ERR_FAIL_COND(!DS_OSX->windows.has(window_id)); - DisplayServerOSX::WindowData &wd = DS_OSX->windows[window_id]; - - if (([event modifierFlags] & NSEventModifierFlagControl)) { - wd.mouse_down_control = true; - _mouseDownEvent(window_id, event, MouseButton::RIGHT, MouseButton::MASK_RIGHT, true); - } else { - wd.mouse_down_control = false; - _mouseDownEvent(window_id, event, MouseButton::LEFT, MouseButton::MASK_LEFT, true); +NSCursor *DisplayServerOSX::_cursor_from_selector(SEL p_selector, SEL p_fallback) { + if ([NSCursor respondsToSelector:p_selector]) { + id object = [NSCursor performSelector:p_selector]; + if ([object isKindOfClass:[NSCursor class]]) { + return object; + } } -} - -- (void)mouseDragged:(NSEvent *)event { - [self mouseMoved:event]; -} - -- (void)mouseUp:(NSEvent *)event { - ERR_FAIL_COND(!DS_OSX->windows.has(window_id)); - DisplayServerOSX::WindowData &wd = DS_OSX->windows[window_id]; - - if (wd.mouse_down_control) { - _mouseDownEvent(window_id, event, MouseButton::RIGHT, MouseButton::MASK_RIGHT, false); - } else { - _mouseDownEvent(window_id, event, MouseButton::LEFT, MouseButton::MASK_LEFT, false); + if (p_fallback) { + // Fallback should be a reasonable default, no need to check. + return [NSCursor performSelector:p_fallback]; } + return [NSCursor arrowCursor]; } -- (void)mouseMoved:(NSEvent *)event { - ERR_FAIL_COND(!DS_OSX->windows.has(window_id)); - DisplayServerOSX::WindowData &wd = DS_OSX->windows[window_id]; - - NSPoint delta = NSMakePoint([event deltaX], [event deltaY]); - NSPoint mpos = [event locationInWindow]; +NSMenu *DisplayServerOSX::get_dock_menu() const { + return dock_menu; +} - if (DS_OSX->ignore_warp) { - // Discard late events, before warp - if (([event timestamp]) < DS_OSX->last_warp) { - return; - } - DS_OSX->ignore_warp = false; +void DisplayServerOSX::menu_callback(id p_sender) { + if (![p_sender representedObject]) { return; } - if (DS_OSX->mouse_mode == DisplayServer::MOUSE_MODE_CONFINED || DS_OSX->mouse_mode == DisplayServer::MOUSE_MODE_CONFINED_HIDDEN) { - // Discard late events - if (([event timestamp]) < DS_OSX->last_warp) { - return; - } + GodotMenuItem *value = [p_sender representedObject]; - // Warp affects next event delta, subtract previous warp deltas - List<DisplayServerOSX::WarpEvent>::Element *F = DS_OSX->warp_events.front(); - while (F) { - if (F->get().timestamp < [event timestamp]) { - List<DisplayServerOSX::WarpEvent>::Element *E = F; - delta.x -= E->get().delta.x; - delta.y -= E->get().delta.y; - F = F->next(); - DS_OSX->warp_events.erase(E); + if (value) { + if (value->checkable) { + if ([p_sender state] == NSControlStateValueOff) { + [p_sender setState:NSControlStateValueOn]; } else { - F = F->next(); + [p_sender setState:NSControlStateValueOff]; } } - // Confine mouse position to the window, and update delta - NSRect frame = [wd.window_object frame]; - NSPoint conf_pos = mpos; - conf_pos.x = CLAMP(conf_pos.x + delta.x, 0.f, frame.size.width); - conf_pos.y = CLAMP(conf_pos.y - delta.y, 0.f, frame.size.height); - delta.x = conf_pos.x - mpos.x; - delta.y = mpos.y - conf_pos.y; - mpos = conf_pos; - - // Move mouse cursor - NSRect pointInWindowRect = NSMakeRect(conf_pos.x, conf_pos.y, 0, 0); - conf_pos = [[wd.window_view window] convertRectToScreen:pointInWindowRect].origin; - conf_pos.y = CGDisplayBounds(CGMainDisplayID()).size.height - conf_pos.y; - CGWarpMouseCursorPosition(conf_pos); - - // Save warp data - DS_OSX->last_warp = [[NSProcessInfo processInfo] systemUptime]; - DisplayServerOSX::WarpEvent ev; - ev.timestamp = DS_OSX->last_warp; - ev.delta = delta; - DS_OSX->warp_events.push_back(ev); - } - - Ref<InputEventMouseMotion> mm; - mm.instantiate(); - - mm->set_window_id(window_id); - mm->set_button_mask(DS_OSX->last_button_state); - const Vector2i pos = _get_mouse_pos(wd, mpos); - mm->set_position(pos); - mm->set_pressure([event pressure]); - if ([event subtype] == NSEventSubtypeTabletPoint) { - const NSPoint p = [event tilt]; - mm->set_tilt(Vector2(p.x, p.y)); + if (value->callback != Callable()) { + Variant tag = value->meta; + Variant *tagp = &tag; + Variant ret; + Callable::CallError ce; + value->callback.call((const Variant **)&tagp, 1, ret, ce); + } } - mm->set_global_position(pos); - mm->set_velocity(Input::get_singleton()->get_last_mouse_velocity()); - const Vector2i relativeMotion = Vector2i(delta.x, delta.y) * DS_OSX->screen_get_max_scale(); - mm->set_relative(relativeMotion); - _get_key_modifier_state([event modifierFlags], mm); - - Input::get_singleton()->parse_input_event(mm); -} - -- (void)rightMouseDown:(NSEvent *)event { - _mouseDownEvent(window_id, event, MouseButton::RIGHT, MouseButton::MASK_RIGHT, true); -} - -- (void)rightMouseDragged:(NSEvent *)event { - [self mouseMoved:event]; -} - -- (void)rightMouseUp:(NSEvent *)event { - _mouseDownEvent(window_id, event, MouseButton::RIGHT, MouseButton::MASK_RIGHT, false); } -- (void)otherMouseDown:(NSEvent *)event { - if ((int)[event buttonNumber] == 2) { - _mouseDownEvent(window_id, event, MouseButton::MIDDLE, MouseButton::MASK_MIDDLE, true); - } else if ((int)[event buttonNumber] == 3) { - _mouseDownEvent(window_id, event, MouseButton::MB_XBUTTON1, MouseButton::MASK_XBUTTON1, true); - } else if ((int)[event buttonNumber] == 4) { - _mouseDownEvent(window_id, event, MouseButton::MB_XBUTTON2, MouseButton::MASK_XBUTTON2, true); - } else { - return; - } +bool DisplayServerOSX::has_window(WindowID p_window) const { + return windows.has(p_window); } -- (void)otherMouseDragged:(NSEvent *)event { - [self mouseMoved:event]; +DisplayServerOSX::WindowData &DisplayServerOSX::get_window(WindowID p_window) { + return windows[p_window]; } -- (void)otherMouseUp:(NSEvent *)event { - if ((int)[event buttonNumber] == 2) { - _mouseDownEvent(window_id, event, MouseButton::MIDDLE, MouseButton::MASK_MIDDLE, false); - } else if ((int)[event buttonNumber] == 3) { - _mouseDownEvent(window_id, event, MouseButton::MB_XBUTTON1, MouseButton::MASK_XBUTTON1, false); - } else if ((int)[event buttonNumber] == 4) { - _mouseDownEvent(window_id, event, MouseButton::MB_XBUTTON2, MouseButton::MASK_XBUTTON2, false); - } else { - return; - } -} +void DisplayServerOSX::send_event(NSEvent *p_event) { + // Special case handling of command-period, which is traditionally a special + // shortcut in macOS and doesn't arrive at our regular keyDown handler. + if ([p_event type] == NSEventTypeKeyDown) { + if (([p_event modifierFlags] & NSEventModifierFlagCommand) && [p_event keyCode] == 0x2f) { + Ref<InputEventKey> k; + k.instantiate(); -- (void)mouseExited:(NSEvent *)event { - ERR_FAIL_COND(!DS_OSX->windows.has(window_id)); - DisplayServerOSX::WindowData &wd = DS_OSX->windows[window_id]; + get_key_modifier_state([p_event modifierFlags], k); + k->set_window_id(DisplayServerOSX::INVALID_WINDOW_ID); + k->set_pressed(true); + k->set_keycode(Key::PERIOD); + k->set_physical_keycode(Key::PERIOD); + k->set_echo([p_event isARepeat]); - if (DS_OSX->mouse_mode != DisplayServer::MOUSE_MODE_CAPTURED) { - DS_OSX->_send_window_event(wd, DisplayServerOSX::WINDOW_EVENT_MOUSE_EXIT); + Input::get_singleton()->parse_input_event(k); + } } } -- (void)mouseEntered:(NSEvent *)event { - ERR_FAIL_COND(!DS_OSX->windows.has(window_id)); - DisplayServerOSX::WindowData &wd = DS_OSX->windows[window_id]; +void DisplayServerOSX::send_window_event(const WindowData &wd, WindowEvent p_event) { + _THREAD_SAFE_METHOD_ - if (DS_OSX->mouse_mode != DisplayServer::MOUSE_MODE_CAPTURED) { - DS_OSX->_send_window_event(wd, DisplayServerOSX::WINDOW_EVENT_MOUSE_ENTER); + if (!wd.event_callback.is_null()) { + Variant event = int(p_event); + Variant *eventp = &event; + Variant ret; + Callable::CallError ce; + wd.event_callback.call((const Variant **)&eventp, 1, ret, ce); } - - DisplayServer::CursorShape p_shape = DS_OSX->cursor_shape; - DS_OSX->cursor_shape = DisplayServer::CURSOR_MAX; - DS_OSX->cursor_set_shape(p_shape); -} - -- (void)magnifyWithEvent:(NSEvent *)event { - ERR_FAIL_COND(!DS_OSX->windows.has(window_id)); - DisplayServerOSX::WindowData &wd = DS_OSX->windows[window_id]; - - Ref<InputEventMagnifyGesture> ev; - ev.instantiate(); - ev->set_window_id(window_id); - _get_key_modifier_state([event modifierFlags], ev); - ev->set_position(_get_mouse_pos(wd, [event locationInWindow])); - ev->set_factor([event magnification] + 1.0); - - Input::get_singleton()->parse_input_event(ev); } -- (void)viewDidChangeBackingProperties { - // nothing left to do here -} - -- (void)updateTrackingAreas { - if (trackingArea != nil) { - [self removeTrackingArea:trackingArea]; - [trackingArea release]; - } - - NSTrackingAreaOptions options = NSTrackingMouseEnteredAndExited | NSTrackingActiveInKeyWindow | NSTrackingCursorUpdate | NSTrackingInVisibleRect; - trackingArea = [[NSTrackingArea alloc] initWithRect:[self bounds] options:options owner:self userInfo:nil]; - - [self addTrackingArea:trackingArea]; - [super updateTrackingAreas]; -} - -static bool isNumpadKey(unsigned int key) { - static const unsigned int table[] = { - 0x41, /* kVK_ANSI_KeypadDecimal */ - 0x43, /* kVK_ANSI_KeypadMultiply */ - 0x45, /* kVK_ANSI_KeypadPlus */ - 0x47, /* kVK_ANSI_KeypadClear */ - 0x4b, /* kVK_ANSI_KeypadDivide */ - 0x4c, /* kVK_ANSI_KeypadEnter */ - 0x4e, /* kVK_ANSI_KeypadMinus */ - 0x51, /* kVK_ANSI_KeypadEquals */ - 0x52, /* kVK_ANSI_Keypad0 */ - 0x53, /* kVK_ANSI_Keypad1 */ - 0x54, /* kVK_ANSI_Keypad2 */ - 0x55, /* kVK_ANSI_Keypad3 */ - 0x56, /* kVK_ANSI_Keypad4 */ - 0x57, /* kVK_ANSI_Keypad5 */ - 0x58, /* kVK_ANSI_Keypad6 */ - 0x59, /* kVK_ANSI_Keypad7 */ - 0x5b, /* kVK_ANSI_Keypad8 */ - 0x5c, /* kVK_ANSI_Keypad9 */ - 0x5f, /* kVK_JIS_KeypadComma */ - 0x00 - }; - for (int i = 0; table[i] != 0; i++) { - if (key == table[i]) { - return true; - } +void DisplayServerOSX::release_pressed_events() { + _THREAD_SAFE_METHOD_ + if (Input::get_singleton()) { + Input::get_singleton()->release_pressed_events(); } - return false; } -// Keyboard symbol translation table -static const Key _osx_to_godot_table[128] = { - /* 00 */ Key::A, - /* 01 */ Key::S, - /* 02 */ Key::D, - /* 03 */ Key::F, - /* 04 */ Key::H, - /* 05 */ Key::G, - /* 06 */ Key::Z, - /* 07 */ Key::X, - /* 08 */ Key::C, - /* 09 */ Key::V, - /* 0a */ Key::SECTION, /* ISO Section */ - /* 0b */ Key::B, - /* 0c */ Key::Q, - /* 0d */ Key::W, - /* 0e */ Key::E, - /* 0f */ Key::R, - /* 10 */ Key::Y, - /* 11 */ Key::T, - /* 12 */ Key::KEY_1, - /* 13 */ Key::KEY_2, - /* 14 */ Key::KEY_3, - /* 15 */ Key::KEY_4, - /* 16 */ Key::KEY_6, - /* 17 */ Key::KEY_5, - /* 18 */ Key::EQUAL, - /* 19 */ Key::KEY_9, - /* 1a */ Key::KEY_7, - /* 1b */ Key::MINUS, - /* 1c */ Key::KEY_8, - /* 1d */ Key::KEY_0, - /* 1e */ Key::BRACERIGHT, - /* 1f */ Key::O, - /* 20 */ Key::U, - /* 21 */ Key::BRACELEFT, - /* 22 */ Key::I, - /* 23 */ Key::P, - /* 24 */ Key::ENTER, - /* 25 */ Key::L, - /* 26 */ Key::J, - /* 27 */ Key::APOSTROPHE, - /* 28 */ Key::K, - /* 29 */ Key::SEMICOLON, - /* 2a */ Key::BACKSLASH, - /* 2b */ Key::COMMA, - /* 2c */ Key::SLASH, - /* 2d */ Key::N, - /* 2e */ Key::M, - /* 2f */ Key::PERIOD, - /* 30 */ Key::TAB, - /* 31 */ Key::SPACE, - /* 32 */ Key::QUOTELEFT, - /* 33 */ Key::BACKSPACE, - /* 34 */ Key::UNKNOWN, - /* 35 */ Key::ESCAPE, - /* 36 */ Key::META, - /* 37 */ Key::META, - /* 38 */ Key::SHIFT, - /* 39 */ Key::CAPSLOCK, - /* 3a */ Key::ALT, - /* 3b */ Key::CTRL, - /* 3c */ Key::SHIFT, - /* 3d */ Key::ALT, - /* 3e */ Key::CTRL, - /* 3f */ Key::UNKNOWN, /* Function */ - /* 40 */ Key::UNKNOWN, /* F17 */ - /* 41 */ Key::KP_PERIOD, - /* 42 */ Key::UNKNOWN, - /* 43 */ Key::KP_MULTIPLY, - /* 44 */ Key::UNKNOWN, - /* 45 */ Key::KP_ADD, - /* 46 */ Key::UNKNOWN, - /* 47 */ Key::NUMLOCK, /* Really KeypadClear... */ - /* 48 */ Key::VOLUMEUP, /* VolumeUp */ - /* 49 */ Key::VOLUMEDOWN, /* VolumeDown */ - /* 4a */ Key::VOLUMEMUTE, /* Mute */ - /* 4b */ Key::KP_DIVIDE, - /* 4c */ Key::KP_ENTER, - /* 4d */ Key::UNKNOWN, - /* 4e */ Key::KP_SUBTRACT, - /* 4f */ Key::UNKNOWN, /* F18 */ - /* 50 */ Key::UNKNOWN, /* F19 */ - /* 51 */ Key::EQUAL, /* KeypadEqual */ - /* 52 */ Key::KP_0, - /* 53 */ Key::KP_1, - /* 54 */ Key::KP_2, - /* 55 */ Key::KP_3, - /* 56 */ Key::KP_4, - /* 57 */ Key::KP_5, - /* 58 */ Key::KP_6, - /* 59 */ Key::KP_7, - /* 5a */ Key::UNKNOWN, /* F20 */ - /* 5b */ Key::KP_8, - /* 5c */ Key::KP_9, - /* 5d */ Key::YEN, /* JIS Yen */ - /* 5e */ Key::UNDERSCORE, /* JIS Underscore */ - /* 5f */ Key::COMMA, /* JIS KeypadComma */ - /* 60 */ Key::F5, - /* 61 */ Key::F6, - /* 62 */ Key::F7, - /* 63 */ Key::F3, - /* 64 */ Key::F8, - /* 65 */ Key::F9, - /* 66 */ Key::UNKNOWN, /* JIS Eisu */ - /* 67 */ Key::F11, - /* 68 */ Key::UNKNOWN, /* JIS Kana */ - /* 69 */ Key::F13, - /* 6a */ Key::F16, - /* 6b */ Key::F14, - /* 6c */ Key::UNKNOWN, - /* 6d */ Key::F10, - /* 6e */ Key::MENU, - /* 6f */ Key::F12, - /* 70 */ Key::UNKNOWN, - /* 71 */ Key::F15, - /* 72 */ Key::INSERT, /* Really Help... */ - /* 73 */ Key::HOME, - /* 74 */ Key::PAGEUP, - /* 75 */ Key::KEY_DELETE, - /* 76 */ Key::F4, - /* 77 */ Key::END, - /* 78 */ Key::F2, - /* 79 */ Key::PAGEDOWN, - /* 7a */ Key::F1, - /* 7b */ Key::LEFT, - /* 7c */ Key::RIGHT, - /* 7d */ Key::DOWN, - /* 7e */ Key::UP, - /* 7f */ Key::UNKNOWN, -}; - -// Translates a OS X keycode to a Godot keycode -static Key translateKey(unsigned int key) { - if (key >= 128) { - return Key::UNKNOWN; - } - - return _osx_to_godot_table[key]; -} - -// Translates a Godot keycode back to a OSX keycode -static unsigned int unmapKey(Key key) { - for (int i = 0; i <= 126; i++) { - if (_osx_to_godot_table[i] == key) { - return i; - } - } - return 127; -} - -struct _KeyCodeMap { - UniChar kchar; - Key kcode; -}; - -static const _KeyCodeMap _keycodes[55] = { - { '`', Key::QUOTELEFT }, - { '~', Key::ASCIITILDE }, - { '0', Key::KEY_0 }, - { '1', Key::KEY_1 }, - { '2', Key::KEY_2 }, - { '3', Key::KEY_3 }, - { '4', Key::KEY_4 }, - { '5', Key::KEY_5 }, - { '6', Key::KEY_6 }, - { '7', Key::KEY_7 }, - { '8', Key::KEY_8 }, - { '9', Key::KEY_9 }, - { '-', Key::MINUS }, - { '_', Key::UNDERSCORE }, - { '=', Key::EQUAL }, - { '+', Key::PLUS }, - { 'q', Key::Q }, - { 'w', Key::W }, - { 'e', Key::E }, - { 'r', Key::R }, - { 't', Key::T }, - { 'y', Key::Y }, - { 'u', Key::U }, - { 'i', Key::I }, - { 'o', Key::O }, - { 'p', Key::P }, - { '[', Key::BRACELEFT }, - { ']', Key::BRACERIGHT }, - { '{', Key::BRACELEFT }, - { '}', Key::BRACERIGHT }, - { 'a', Key::A }, - { 's', Key::S }, - { 'd', Key::D }, - { 'f', Key::F }, - { 'g', Key::G }, - { 'h', Key::H }, - { 'j', Key::J }, - { 'k', Key::K }, - { 'l', Key::L }, - { ';', Key::SEMICOLON }, - { ':', Key::COLON }, - { '\'', Key::APOSTROPHE }, - { '\"', Key::QUOTEDBL }, - { '\\', Key::BACKSLASH }, - { '#', Key::NUMBERSIGN }, - { 'z', Key::Z }, - { 'x', Key::X }, - { 'c', Key::C }, - { 'v', Key::V }, - { 'b', Key::B }, - { 'n', Key::N }, - { 'm', Key::M }, - { ',', Key::COMMA }, - { '.', Key::PERIOD }, - { '/', Key::SLASH } -}; - -static Key remapKey(unsigned int key, unsigned int state) { - if (isNumpadKey(key)) { - return translateKey(key); - } - - TISInputSourceRef currentKeyboard = TISCopyCurrentKeyboardInputSource(); - if (!currentKeyboard) { - return translateKey(key); - } - - CFDataRef layoutData = (CFDataRef)TISGetInputSourceProperty(currentKeyboard, kTISPropertyUnicodeKeyLayoutData); - if (!layoutData) { - return translateKey(key); - } - - const UCKeyboardLayout *keyboardLayout = (const UCKeyboardLayout *)CFDataGetBytePtr(layoutData); - - UInt32 keysDown = 0; - UniChar chars[4]; - UniCharCount realLength; - - OSStatus err = UCKeyTranslate(keyboardLayout, - key, - kUCKeyActionDisplay, - (state >> 8) & 0xFF, - LMGetKbdType(), - kUCKeyTranslateNoDeadKeysBit, - &keysDown, - sizeof(chars) / sizeof(chars[0]), - &realLength, - chars); - - if (err != noErr) { - return translateKey(key); - } - - for (unsigned int i = 0; i < 55; i++) { - if (_keycodes[i].kchar == chars[0]) { - return _keycodes[i].kcode; - } - } - return translateKey(key); -} - -- (void)keyDown:(NSEvent *)event { - ERR_FAIL_COND(!DS_OSX->windows.has(window_id)); - DisplayServerOSX::WindowData &wd = DS_OSX->windows[window_id]; - - ignore_momentum_scroll = true; - - // Ignore all input if IME input is in progress - if (!imeInputEventInProgress) { - NSString *characters = [event characters]; - NSUInteger length = [characters length]; - - if (!wd.im_active && length > 0 && keycode_has_unicode(remapKey([event keyCode], [event modifierFlags]))) { - // Fallback unicode character handler used if IME is not active - Char16String text; - text.resize([characters length] + 1); - [characters getCharacters:(unichar *)text.ptrw() range:NSMakeRange(0, [characters length])]; - - String u32text; - u32text.parse_utf16(text.ptr(), text.length()); - - for (int i = 0; i < u32text.length(); i++) { - const char32_t codepoint = u32text[i]; - - DisplayServerOSX::KeyEvent ke; - - ke.window_id = window_id; - ke.osx_state = [event modifierFlags]; - ke.pressed = true; - ke.echo = [event isARepeat]; - ke.keycode = remapKey([event keyCode], [event modifierFlags]); - ke.physical_keycode = translateKey([event keyCode]); - ke.raw = true; - ke.unicode = codepoint; - - _push_to_key_event_buffer(ke); - } - } else { - DisplayServerOSX::KeyEvent ke; - - ke.window_id = window_id; - ke.osx_state = [event modifierFlags]; - ke.pressed = true; - ke.echo = [event isARepeat]; - ke.keycode = remapKey([event keyCode], [event modifierFlags]); - ke.physical_keycode = translateKey([event keyCode]); - ke.raw = false; - ke.unicode = 0; - - _push_to_key_event_buffer(ke); - } - } - - // Pass events to IME handler - if (wd.im_active) { - [self interpretKeyEvents:[NSArray arrayWithObject:event]]; - } +void DisplayServerOSX::get_key_modifier_state(unsigned int p_osx_state, Ref<InputEventWithModifiers> r_state) const { + r_state->set_shift_pressed((p_osx_state & NSEventModifierFlagShift)); + r_state->set_ctrl_pressed((p_osx_state & NSEventModifierFlagControl)); + r_state->set_alt_pressed((p_osx_state & NSEventModifierFlagOption)); + r_state->set_meta_pressed((p_osx_state & NSEventModifierFlagCommand)); } -- (void)flagsChanged:(NSEvent *)event { - ignore_momentum_scroll = true; - - // Ignore all input if IME input is in progress - if (!imeInputEventInProgress) { - DisplayServerOSX::KeyEvent ke; - - ke.window_id = window_id; - ke.echo = false; - ke.raw = true; - - int key = [event keyCode]; - int mod = [event modifierFlags]; - - if (key == 0x36 || key == 0x37) { - if (mod & NSEventModifierFlagCommand) { - mod &= ~NSEventModifierFlagCommand; - ke.pressed = true; - } else { - ke.pressed = false; - } - } else if (key == 0x38 || key == 0x3c) { - if (mod & NSEventModifierFlagShift) { - mod &= ~NSEventModifierFlagShift; - ke.pressed = true; - } else { - ke.pressed = false; - } - } else if (key == 0x3a || key == 0x3d) { - if (mod & NSEventModifierFlagOption) { - mod &= ~NSEventModifierFlagOption; - ke.pressed = true; - } else { - ke.pressed = false; - } - } else if (key == 0x3b || key == 0x3e) { - if (mod & NSEventModifierFlagControl) { - mod &= ~NSEventModifierFlagControl; - ke.pressed = true; - } else { - ke.pressed = false; - } - } else { - return; - } - - ke.osx_state = mod; - ke.keycode = remapKey(key, mod); - ke.physical_keycode = translateKey(key); - ke.unicode = 0; - - _push_to_key_event_buffer(ke); - } +void DisplayServerOSX::update_mouse_pos(DisplayServerOSX::WindowData &p_wd, NSPoint p_location_in_window) { + const NSRect content_rect = [p_wd.window_view frame]; + const float scale = screen_get_max_scale(); + p_wd.mouse_pos.x = p_location_in_window.x * scale; + p_wd.mouse_pos.y = (content_rect.size.height - p_location_in_window.y) * scale; + Input::get_singleton()->set_mouse_position(p_wd.mouse_pos); } -- (void)keyUp:(NSEvent *)event { - ERR_FAIL_COND(!DS_OSX->windows.has(window_id)); - DisplayServerOSX::WindowData &wd = DS_OSX->windows[window_id]; - - // Ignore all input if IME input is in progress - if (!imeInputEventInProgress) { - NSString *characters = [event characters]; - NSUInteger length = [characters length]; - - // Fallback unicode character handler used if IME is not active - if (!wd.im_active && length > 0 && keycode_has_unicode(remapKey([event keyCode], [event modifierFlags]))) { - Char16String text; - text.resize([characters length] + 1); - [characters getCharacters:(unichar *)text.ptrw() range:NSMakeRange(0, [characters length])]; - - String u32text; - u32text.parse_utf16(text.ptr(), text.length()); - - for (int i = 0; i < u32text.length(); i++) { - const char32_t codepoint = u32text[i]; - DisplayServerOSX::KeyEvent ke; - - ke.window_id = window_id; - ke.osx_state = [event modifierFlags]; - ke.pressed = false; - ke.echo = [event isARepeat]; - ke.keycode = remapKey([event keyCode], [event modifierFlags]); - ke.physical_keycode = translateKey([event keyCode]); - ke.raw = true; - ke.unicode = codepoint; - - _push_to_key_event_buffer(ke); - } - } else { - DisplayServerOSX::KeyEvent ke; - - ke.window_id = window_id; - ke.osx_state = [event modifierFlags]; - ke.pressed = false; - ke.echo = [event isARepeat]; - ke.keycode = remapKey([event keyCode], [event modifierFlags]); - ke.physical_keycode = translateKey([event keyCode]); - ke.raw = true; - ke.unicode = 0; - - _push_to_key_event_buffer(ke); - } +void DisplayServerOSX::push_to_key_event_buffer(const DisplayServerOSX::KeyEvent &p_event) { + if (key_event_pos >= key_event_buffer.size()) { + key_event_buffer.resize(1 + key_event_pos); } + key_event_buffer.write[key_event_pos++] = p_event; } -inline void sendScrollEvent(DisplayServer::WindowID window_id, MouseButton button, double factor, int modifierFlags) { - ERR_FAIL_COND(!DS_OSX->windows.has(window_id)); - DisplayServerOSX::WindowData &wd = DS_OSX->windows[window_id]; - - MouseButton mask = mouse_button_to_mask(button); - - Ref<InputEventMouseButton> sc; - sc.instantiate(); - - sc->set_window_id(window_id); - _get_key_modifier_state(modifierFlags, sc); - sc->set_button_index(button); - sc->set_factor(factor); - sc->set_pressed(true); - sc->set_position(wd.mouse_pos); - sc->set_global_position(wd.mouse_pos); - DS_OSX->last_button_state |= (MouseButton)mask; - sc->set_button_mask(DS_OSX->last_button_state); +void DisplayServerOSX::update_im_text(const Point2i &p_selection, const String &p_text) { + im_selection = p_selection; + im_text = p_text; - Input::get_singleton()->parse_input_event(sc); - - sc.instantiate(); - sc->set_window_id(window_id); - sc->set_button_index(button); - sc->set_factor(factor); - sc->set_pressed(false); - sc->set_position(wd.mouse_pos); - sc->set_global_position(wd.mouse_pos); - DS_OSX->last_button_state &= (MouseButton)~mask; - sc->set_button_mask(DS_OSX->last_button_state); - - Input::get_singleton()->parse_input_event(sc); + OS::get_singleton()->get_main_loop()->notification(MainLoop::NOTIFICATION_OS_IME_UPDATE); } -inline void sendPanEvent(DisplayServer::WindowID window_id, double dx, double dy, int modifierFlags) { - ERR_FAIL_COND(!DS_OSX->windows.has(window_id)); - DisplayServerOSX::WindowData &wd = DS_OSX->windows[window_id]; - - Ref<InputEventPanGesture> pg; - pg.instantiate(); - - pg->set_window_id(window_id); - _get_key_modifier_state(modifierFlags, pg); - pg->set_position(wd.mouse_pos); - pg->set_delta(Vector2(-dx, -dy)); - - Input::get_singleton()->parse_input_event(pg); +void DisplayServerOSX::set_last_focused_window(WindowID p_window) { + last_focused_window = p_window; } -- (void)scrollWheel:(NSEvent *)event { - ERR_FAIL_COND(!DS_OSX->windows.has(window_id)); - DisplayServerOSX::WindowData &wd = DS_OSX->windows[window_id]; - - double deltaX, deltaY; - - _ALLOW_DISCARD_ _get_mouse_pos(wd, [event locationInWindow]); - - deltaX = [event scrollingDeltaX]; - deltaY = [event scrollingDeltaY]; - - if ([event hasPreciseScrollingDeltas]) { - deltaX *= 0.03; - deltaY *= 0.03; +void DisplayServerOSX::window_update(WindowID p_window) { +#if defined(GLES3_ENABLED) + if (gl_manager) { + gl_manager->window_update(p_window); } +#endif +} - if ([event momentumPhase] != NSEventPhaseNone) { - if (ignore_momentum_scroll) { - return; - } - } else { - ignore_momentum_scroll = false; +void DisplayServerOSX::window_destroy(WindowID p_window) { +#if defined(GLES3_ENABLED) + if (gl_manager) { + gl_manager->window_destroy(p_window); } - - if ([event phase] != NSEventPhaseNone || [event momentumPhase] != NSEventPhaseNone) { - sendPanEvent(window_id, deltaX, deltaY, [event modifierFlags]); - } else { - if (fabs(deltaX)) { - sendScrollEvent(window_id, 0 > deltaX ? MouseButton::WHEEL_RIGHT : MouseButton::WHEEL_LEFT, fabs(deltaX * 0.3), [event modifierFlags]); - } - if (fabs(deltaY)) { - sendScrollEvent(window_id, 0 < deltaY ? MouseButton::WHEEL_UP : MouseButton::WHEEL_DOWN, fabs(deltaY * 0.3), [event modifierFlags]); - } +#endif +#ifdef VULKAN_ENABLED + if (context_vulkan) { + context_vulkan->window_destroy(p_window); } +#endif + windows.erase(p_window); } -@end - -/*************************************************************************/ -/* GodotWindow */ -/*************************************************************************/ - -@interface GodotWindow : NSWindow { -} - -@end - -@implementation GodotWindow - -- (BOOL)canBecomeKeyWindow { - // Required for NSBorderlessWindowMask windows - for (Map<DisplayServer::WindowID, DisplayServerOSX::WindowData>::Element *E = DS_OSX->windows.front(); E; E = E->next()) { - if (E->get().window_object == self) { - if (E->get().no_focus) { - return NO; - } - } +void DisplayServerOSX::window_resize(WindowID p_window, int p_width, int p_height) { +#if defined(GLES3_ENABLED) + if (gl_manager) { + gl_manager->window_resize(p_window, p_width, p_height); } - return YES; -} - -- (BOOL)canBecomeMainWindow { - // Required for NSBorderlessWindowMask windows - for (Map<DisplayServer::WindowID, DisplayServerOSX::WindowData>::Element *E = DS_OSX->windows.front(); E; E = E->next()) { - if (E->get().window_object == self) { - if (E->get().no_focus) { - return NO; - } - } +#endif +#if defined(VULKAN_ENABLED) + if (context_vulkan) { + context_vulkan->window_resize(p_window, p_width, p_height); } - return YES; +#endif } -@end - -/*************************************************************************/ -/* DisplayServerOSX */ -/*************************************************************************/ - bool DisplayServerOSX::has_feature(Feature p_feature) const { switch (p_feature) { case FEATURE_GLOBAL_MENU: @@ -1494,57 +647,13 @@ String DisplayServerOSX::get_name() const { return "OSX"; } -const NSMenu *DisplayServerOSX::_get_menu_root(const String &p_menu_root) const { - const NSMenu *menu = nullptr; - if (p_menu_root == "") { - // Main menu.x - menu = [NSApp mainMenu]; - } else if (p_menu_root.to_lower() == "_dock") { - // macOS dock menu. - menu = dock_menu; - } else { - // Submenu. - if (submenu.has(p_menu_root)) { - menu = submenu[p_menu_root]; - } - } - if (menu == apple_menu) { - // Do not allow to change Apple menu. - return nullptr; - } - return menu; -} - -NSMenu *DisplayServerOSX::_get_menu_root(const String &p_menu_root) { - NSMenu *menu = nullptr; - if (p_menu_root == "") { - // Main menu. - menu = [NSApp mainMenu]; - } else if (p_menu_root.to_lower() == "_dock") { - // macOS dock menu. - menu = dock_menu; - } else { - // Submenu. - if (!submenu.has(p_menu_root)) { - NSMenu *n_menu = [[NSMenu alloc] initWithTitle:[NSString stringWithUTF8String:p_menu_root.utf8().get_data()]]; - submenu[p_menu_root] = n_menu; - } - menu = submenu[p_menu_root]; - } - if (menu == apple_menu) { - // Do not allow to change Apple menu. - return nullptr; - } - return menu; -} - void DisplayServerOSX::global_menu_add_item(const String &p_menu_root, const String &p_label, const Callable &p_callback, const Variant &p_tag) { _THREAD_SAFE_METHOD_ NSMenu *menu = _get_menu_root(p_menu_root); if (menu) { NSMenuItem *menu_item = [menu addItemWithTitle:[NSString stringWithUTF8String:p_label.utf8().get_data()] action:@selector(globalMenuCallback:) keyEquivalent:@""]; - GlobalMenuItem *obj = [[[GlobalMenuItem alloc] init] autorelease]; + GodotMenuItem *obj = [[GodotMenuItem alloc] init]; obj->callback = p_callback; obj->meta = p_tag; obj->checkable = false; @@ -1558,7 +667,7 @@ void DisplayServerOSX::global_menu_add_check_item(const String &p_menu_root, con NSMenu *menu = _get_menu_root(p_menu_root); if (menu) { NSMenuItem *menu_item = [menu addItemWithTitle:[NSString stringWithUTF8String:p_label.utf8().get_data()] action:@selector(globalMenuCallback:) keyEquivalent:@""]; - GlobalMenuItem *obj = [[[GlobalMenuItem alloc] init] autorelease]; + GodotMenuItem *obj = [[GodotMenuItem alloc] init]; obj->callback = p_callback; obj->meta = p_tag; obj->checkable = true; @@ -1614,7 +723,7 @@ bool DisplayServerOSX::global_menu_is_item_checkable(const String &p_menu_root, if (menu) { const NSMenuItem *menu_item = [menu itemAtIndex:p_idx]; if (menu_item) { - GlobalMenuItem *obj = [menu_item representedObject]; + GodotMenuItem *obj = [menu_item representedObject]; if (obj) { return obj->checkable; } @@ -1630,7 +739,7 @@ Callable DisplayServerOSX::global_menu_get_item_callback(const String &p_menu_ro if (menu) { const NSMenuItem *menu_item = [menu itemAtIndex:p_idx]; if (menu_item) { - GlobalMenuItem *obj = [menu_item representedObject]; + GodotMenuItem *obj = [menu_item representedObject]; if (obj) { return obj->callback; } @@ -1646,7 +755,7 @@ Variant DisplayServerOSX::global_menu_get_item_tag(const String &p_menu_root, in if (menu) { const NSMenuItem *menu_item = [menu itemAtIndex:p_idx]; if (menu_item) { - GlobalMenuItem *obj = [menu_item representedObject]; + GodotMenuItem *obj = [menu_item representedObject]; if (obj) { return obj->meta; } @@ -1662,10 +771,8 @@ String DisplayServerOSX::global_menu_get_item_text(const String &p_menu_root, in if (menu) { const NSMenuItem *menu_item = [menu itemAtIndex:p_idx]; if (menu_item) { - char *utfs = strdup([[menu_item title] UTF8String]); String ret; - ret.parse_utf8(utfs); - free(utfs); + ret.parse_utf8([[menu_item title] UTF8String]); return ret; } } @@ -1720,7 +827,7 @@ void DisplayServerOSX::global_menu_set_item_checkable(const String &p_menu_root, } NSMenuItem *menu_item = [menu itemAtIndex:p_idx]; if (menu_item) { - GlobalMenuItem *obj = [menu_item representedObject]; + GodotMenuItem *obj = [menu_item representedObject]; obj->checkable = p_checkable; } } @@ -1736,7 +843,7 @@ void DisplayServerOSX::global_menu_set_item_callback(const String &p_menu_root, } NSMenuItem *menu_item = [menu itemAtIndex:p_idx]; if (menu_item) { - GlobalMenuItem *obj = [menu_item representedObject]; + GodotMenuItem *obj = [menu_item representedObject]; obj->callback = p_callback; } } @@ -1752,7 +859,7 @@ void DisplayServerOSX::global_menu_set_item_tag(const String &p_menu_root, int p } NSMenuItem *menu_item = [menu itemAtIndex:p_idx]; if (menu_item) { - GlobalMenuItem *obj = [menu_item representedObject]; + GodotMenuItem *obj = [menu_item representedObject]; obj->meta = p_tag; } } @@ -1869,7 +976,6 @@ Error DisplayServerOSX::dialog_show(String p_title, String p_description, Vector p_callback.call((const Variant **)&buttonp, 1, ret, ce); } - [window release]; return OK; } @@ -1891,10 +997,8 @@ Error DisplayServerOSX::dialog_input_text(String p_title, String p_description, [window runModal]; - char *utfs = strdup([[input stringValue] UTF8String]); String ret; - ret.parse_utf8(utfs); - free(utfs); + ret.parse_utf8([[input stringValue] UTF8String]); if (!p_callback.is_null()) { Variant text = ret; @@ -1904,7 +1008,6 @@ Error DisplayServerOSX::dialog_input_text(String p_title, String p_description, p_callback.call((const Variant **)&textp, 1, ret, ce); } - [window release]; return OK; } @@ -1959,9 +1062,7 @@ void DisplayServerOSX::mouse_set_mode(MouseMode p_mode) { mouse_mode = p_mode; if (mouse_mode == MOUSE_MODE_VISIBLE || mouse_mode == MOUSE_MODE_CONFINED) { - CursorShape p_shape = cursor_shape; - cursor_shape = DisplayServer::CURSOR_MAX; - cursor_set_shape(p_shape); + cursor_update_shape(); } } @@ -1969,25 +1070,82 @@ DisplayServer::MouseMode DisplayServerOSX::mouse_get_mode() const { return mouse_mode; } +bool DisplayServerOSX::update_mouse_wrap(WindowData &p_wd, NSPoint &r_delta, NSPoint &r_mpos, NSTimeInterval p_timestamp) { + _THREAD_SAFE_METHOD_ + + if (ignore_warp) { + // Discard late events, before warp. + if (p_timestamp < last_warp) { + return true; + } + ignore_warp = false; + return true; + } + + if (mouse_mode == DisplayServer::MOUSE_MODE_CONFINED || mouse_mode == DisplayServer::MOUSE_MODE_CONFINED_HIDDEN) { + // Discard late events. + if (p_timestamp < last_warp) { + return true; + } + + // Warp affects next event delta, subtract previous warp deltas. + List<WarpEvent>::Element *F = warp_events.front(); + while (F) { + if (F->get().timestamp < p_timestamp) { + List<DisplayServerOSX::WarpEvent>::Element *E = F; + r_delta.x -= E->get().delta.x; + r_delta.y -= E->get().delta.y; + F = F->next(); + warp_events.erase(E); + } else { + F = F->next(); + } + } + + // Confine mouse position to the window, and update delta. + NSRect frame = [p_wd.window_object frame]; + NSPoint conf_pos = r_mpos; + conf_pos.x = CLAMP(conf_pos.x + r_delta.x, 0.f, frame.size.width); + conf_pos.y = CLAMP(conf_pos.y - r_delta.y, 0.f, frame.size.height); + r_delta.x = conf_pos.x - r_mpos.x; + r_delta.y = r_mpos.y - conf_pos.y; + r_mpos = conf_pos; + + // Move mouse cursor. + NSRect point_in_window_rect = NSMakeRect(conf_pos.x, conf_pos.y, 0, 0); + conf_pos = [[p_wd.window_view window] convertRectToScreen:point_in_window_rect].origin; + conf_pos.y = CGDisplayBounds(CGMainDisplayID()).size.height - conf_pos.y; + CGWarpMouseCursorPosition(conf_pos); + + // Save warp data. + last_warp = [[NSProcessInfo processInfo] systemUptime]; + + DisplayServerOSX::WarpEvent ev; + ev.timestamp = last_warp; + ev.delta = r_delta; + warp_events.push_back(ev); + } + + return false; +} + void DisplayServerOSX::mouse_warp_to_position(const Point2i &p_to) { _THREAD_SAFE_METHOD_ - if (mouse_mode == MOUSE_MODE_CAPTURED) { - last_mouse_pos = p_to; - } else { + if (mouse_mode != MOUSE_MODE_CAPTURED) { WindowID window_id = windows.has(last_focused_window) ? last_focused_window : MAIN_WINDOW_ID; WindowData &wd = windows[window_id]; - //local point in window coords + // Local point in window coords. const NSRect contentRect = [wd.window_view frame]; const float scale = screen_get_max_scale(); NSRect pointInWindowRect = NSMakeRect(p_to.x / scale, contentRect.size.height - (p_to.y / scale - 1), 0, 0); NSPoint pointOnScreen = [[wd.window_view window] convertRectToScreen:pointInWindowRect].origin; - //point in scren coords + // Point in scren coords. CGPoint lMouseWarpPos = { pointOnScreen.x, CGDisplayBounds(CGMainDisplayID()).size.height - pointOnScreen.y }; - //do the warping + // Do the warping. CGEventSourceRef lEventRef = CGEventSourceCreate(kCGEventSourceStateCombinedSessionState); CGEventSourceSetLocalEventsSuppressionInterval(lEventRef, 0.0); CGAssociateMouseAndMouseCursorPosition(false); @@ -2013,6 +1171,10 @@ Point2i DisplayServerOSX::mouse_get_position() const { return Vector2i(); } +void DisplayServerOSX::mouse_set_button_state(MouseButton p_state) { + last_button_state = p_state; +} + MouseButton DisplayServerOSX::mouse_get_button_state() const { return last_button_state; } @@ -2044,11 +1206,8 @@ String DisplayServerOSX::clipboard_get() const { NSArray *objectsToPaste = [pasteboard readObjectsForClasses:classArray options:options]; NSString *string = [objectsToPaste objectAtIndex:0]; - char *utfs = strdup([string UTF8String]); String ret; - ret.parse_utf8(utfs); - free(utfs); - + ret.parse_utf8([string UTF8String]); return ret; } @@ -2059,48 +1218,6 @@ int DisplayServerOSX::get_screen_count() const { return [screenArray count]; } -// Returns the native top-left screen coordinate of the smallest rectangle -// that encompasses all screens. Needed in get_screen_position(), -// window_get_position, and window_set_position() -// to convert between OS X native screen coordinates and the ones expected by Godot - -static bool displays_arrangement_dirty = true; -static void displays_arrangement_changed(CGDirectDisplayID display_id, CGDisplayChangeSummaryFlags flags, void *user_info) { - displays_arrangement_dirty = true; -} - -Point2i DisplayServerOSX::_get_screens_origin() const { - static Point2i origin; - - if (displays_arrangement_dirty) { - origin = Point2i(); - - for (int i = 0; i < get_screen_count(); i++) { - Point2i position = _get_native_screen_position(i); - if (position.x < origin.x) { - origin.x = position.x; - } - if (position.y > origin.y) { - origin.y = position.y; - } - } - displays_arrangement_dirty = false; - } - - return origin; -} - -Point2i DisplayServerOSX::_get_native_screen_position(int p_screen) const { - NSArray *screenArray = [NSScreen screens]; - if ((NSUInteger)p_screen < [screenArray count]) { - NSRect nsrect = [[screenArray objectAtIndex:p_screen] frame]; - // Return the top-left corner of the screen, for OS X the y starts at the bottom - return Point2i(nsrect.origin.x, nsrect.origin.y + nsrect.size.height) * screen_get_max_scale(); - } - - return Point2i(); -} - Point2i DisplayServerOSX::screen_get_position(int p_screen) const { _THREAD_SAFE_METHOD_ @@ -2110,7 +1227,7 @@ Point2i DisplayServerOSX::screen_get_position(int p_screen) const { Point2i position = _get_native_screen_position(p_screen) - _get_screens_origin(); // OS X native y-coordinate relative to _get_screens_origin() is negative, - // Godot expects a positive value + // Godot expects a positive value. position.y *= -1; return position; } @@ -2124,7 +1241,7 @@ Size2i DisplayServerOSX::screen_get_size(int p_screen) const { NSArray *screenArray = [NSScreen screens]; if ((NSUInteger)p_screen < [screenArray count]) { - // Note: Use frame to get the whole screen size + // Note: Use frame to get the whole screen size. NSRect nsrect = [[screenArray objectAtIndex:p_screen] frame]; return Size2i(nsrect.size.width, nsrect.size.height) * screen_get_max_scale(); } @@ -2254,56 +1371,6 @@ void DisplayServerOSX::show_window(WindowID p_id) { } } -void DisplayServerOSX::_send_window_event(const WindowData &wd, WindowEvent p_event) { - _THREAD_SAFE_METHOD_ - - if (!wd.event_callback.is_null()) { - Variant event = int(p_event); - Variant *eventp = &event; - Variant ret; - Callable::CallError ce; - wd.event_callback.call((const Variant **)&eventp, 1, ret, ce); - } -} - -DisplayServerOSX::WindowID DisplayServerOSX::_find_window_id(id p_window) { - for (Map<WindowID, WindowData>::Element *E = windows.front(); E; E = E->next()) { - if (E->get().window_object == p_window) { - return E->key(); - } - } - return INVALID_WINDOW_ID; -} - -void DisplayServerOSX::_update_window(WindowData p_wd) { - bool borderless_full = false; - - if (p_wd.borderless) { - NSRect frameRect = [p_wd.window_object frame]; - NSRect screenRect = [[p_wd.window_object screen] frame]; - - // Check if our window covers up the screen - if (frameRect.origin.x <= screenRect.origin.x && frameRect.origin.y <= frameRect.origin.y && - frameRect.size.width >= screenRect.size.width && frameRect.size.height >= screenRect.size.height) { - borderless_full = true; - } - } - - if (borderless_full) { - // If the window covers up the screen set the level to above the main menu and hide on deactivate - [p_wd.window_object setLevel:NSMainMenuWindowLevel + 1]; - [p_wd.window_object setHidesOnDeactivate:YES]; - } else { - // Reset these when our window is not a borderless window that covers up the screen - if (p_wd.on_top && !p_wd.fullscreen) { - [p_wd.window_object setLevel:NSFloatingWindowLevel]; - } else { - [p_wd.window_object setLevel:NSNormalWindowLevel]; - } - [p_wd.window_object setHidesOnDeactivate:NO]; - } -} - void DisplayServerOSX::delete_sub_window(WindowID p_id) { _THREAD_SAFE_METHOD_ @@ -2316,24 +1383,6 @@ void DisplayServerOSX::delete_sub_window(WindowID p_id) { [wd.window_object close]; } -void DisplayServerOSX::window_set_title(const String &p_title, WindowID p_window) { - _THREAD_SAFE_METHOD_ - - ERR_FAIL_COND(!windows.has(p_window)); - WindowData &wd = windows[p_window]; - - [wd.window_object setTitle:[NSString stringWithUTF8String:p_title.utf8().get_data()]]; -} - -void DisplayServerOSX::window_set_mouse_passthrough(const Vector<Vector2> &p_region, WindowID p_window) { - _THREAD_SAFE_METHOD_ - - ERR_FAIL_COND(!windows.has(p_window)); - WindowData &wd = windows[p_window]; - - wd.mpath = p_region; -} - void DisplayServerOSX::window_set_rect_changed_callback(const Callable &p_callable, WindowID p_window) { _THREAD_SAFE_METHOD_ @@ -2372,6 +1421,24 @@ void DisplayServerOSX::window_set_drop_files_callback(const Callable &p_callable wd.drop_files_callback = p_callable; } +void DisplayServerOSX::window_set_title(const String &p_title, WindowID p_window) { + _THREAD_SAFE_METHOD_ + + ERR_FAIL_COND(!windows.has(p_window)); + WindowData &wd = windows[p_window]; + + [wd.window_object setTitle:[NSString stringWithUTF8String:p_title.utf8().get_data()]]; +} + +void DisplayServerOSX::window_set_mouse_passthrough(const Vector<Vector2> &p_region, WindowID p_window) { + _THREAD_SAFE_METHOD_ + + ERR_FAIL_COND(!windows.has(p_window)); + WindowData &wd = windows[p_window]; + + wd.mpath = p_region; +} + int DisplayServerOSX::window_get_current_screen(WindowID p_window) const { _THREAD_SAFE_METHOD_ ERR_FAIL_COND_V(!windows.has(p_window), -1); @@ -2403,39 +1470,6 @@ void DisplayServerOSX::window_set_current_screen(int p_screen, WindowID p_window } } -void DisplayServerOSX::window_set_transient(WindowID p_window, WindowID p_parent) { - _THREAD_SAFE_METHOD_ - ERR_FAIL_COND(p_window == p_parent); - - ERR_FAIL_COND(!windows.has(p_window)); - WindowData &wd_window = windows[p_window]; - - ERR_FAIL_COND(wd_window.transient_parent == p_parent); - - ERR_FAIL_COND_MSG(wd_window.on_top, "Windows with the 'on top' can't become transient."); - if (p_parent == INVALID_WINDOW_ID) { - //remove transient - ERR_FAIL_COND(wd_window.transient_parent == INVALID_WINDOW_ID); - ERR_FAIL_COND(!windows.has(wd_window.transient_parent)); - - WindowData &wd_parent = windows[wd_window.transient_parent]; - - wd_window.transient_parent = INVALID_WINDOW_ID; - wd_parent.transient_children.erase(p_window); - - [wd_window.window_object setCollectionBehavior:NSWindowCollectionBehaviorFullScreenPrimary]; - } else { - ERR_FAIL_COND(!windows.has(p_parent)); - ERR_FAIL_COND_MSG(wd_window.transient_parent != INVALID_WINDOW_ID, "Window already has a transient parent"); - WindowData &wd_parent = windows[p_parent]; - - wd_window.transient_parent = p_parent; - wd_parent.transient_children.insert(p_window); - - [wd_window.window_object setCollectionBehavior:NSWindowCollectionBehaviorFullScreenAuxiliary]; - } -} - Point2i DisplayServerOSX::window_get_position(WindowID p_window) const { _THREAD_SAFE_METHOD_ @@ -2447,14 +1481,14 @@ Point2i DisplayServerOSX::window_get_position(WindowID p_window) const { const NSRect nsrect = [wd.window_object convertRectToScreen:contentRect]; Point2i pos; - // Return the position of the top-left corner, for OS X the y starts at the bottom + // Return the position of the top-left corner, for OS X the y starts at the bottom. const float scale = screen_get_max_scale(); pos.x = nsrect.origin.x; pos.y = (nsrect.origin.y + nsrect.size.height); pos *= scale; pos -= _get_screens_origin(); // OS X native y-coordinate relative to _get_screens_origin() is negative, - // Godot expects a positive value + // Godot expects a positive value. pos.y *= -1; return pos; } @@ -2467,7 +1501,7 @@ void DisplayServerOSX::window_set_position(const Point2i &p_position, WindowID p Point2i position = p_position; // OS X native y-coordinate relative to _get_screens_origin() is negative, - // Godot passes a positive value + // Godot passes a positive value. position.y *= -1; position += _get_screens_origin(); position /= screen_get_max_scale(); @@ -2483,8 +1517,41 @@ void DisplayServerOSX::window_set_position(const Point2i &p_position, WindowID p [wd.window_object setFrameTopLeftPoint:NSMakePoint(position.x - offset.x, position.y - offset.y)]; - _update_window(wd); - _ALLOW_DISCARD_ _get_mouse_pos(wd, [wd.window_object mouseLocationOutsideOfEventStream]); + _update_window_style(wd); + update_mouse_pos(wd, [wd.window_object mouseLocationOutsideOfEventStream]); +} + +void DisplayServerOSX::window_set_transient(WindowID p_window, WindowID p_parent) { + _THREAD_SAFE_METHOD_ + ERR_FAIL_COND(p_window == p_parent); + + ERR_FAIL_COND(!windows.has(p_window)); + WindowData &wd_window = windows[p_window]; + + ERR_FAIL_COND(wd_window.transient_parent == p_parent); + + ERR_FAIL_COND_MSG(wd_window.on_top, "Windows with the 'on top' can't become transient."); + if (p_parent == INVALID_WINDOW_ID) { + // Remove transient. + ERR_FAIL_COND(wd_window.transient_parent == INVALID_WINDOW_ID); + ERR_FAIL_COND(!windows.has(wd_window.transient_parent)); + + WindowData &wd_parent = windows[wd_window.transient_parent]; + + wd_window.transient_parent = INVALID_WINDOW_ID; + wd_parent.transient_children.erase(p_window); + + [wd_window.window_object setCollectionBehavior:NSWindowCollectionBehaviorFullScreenPrimary]; + } else { + ERR_FAIL_COND(!windows.has(p_parent)); + ERR_FAIL_COND_MSG(wd_window.transient_parent != INVALID_WINDOW_ID, "Window already has a transient parent"); + WindowData &wd_parent = windows[p_parent]; + + wd_window.transient_parent = p_parent; + wd_parent.transient_children.insert(p_window); + + [wd_window.window_object setCollectionBehavior:NSWindowCollectionBehaviorFullScreenAuxiliary]; + } } void DisplayServerOSX::window_set_max_size(const Size2i p_size, WindowID p_window) { @@ -2565,7 +1632,7 @@ void DisplayServerOSX::window_set_size(const Size2i p_size, WindowID p_window) { [wd.window_object setFrame:new_frame display:YES]; - _update_window(wd); + _update_window_style(wd); } Size2i DisplayServerOSX::window_get_size(WindowID p_window) const { @@ -2585,73 +1652,6 @@ Size2i DisplayServerOSX::window_get_real_size(WindowID p_window) const { return Size2i(frame.size.width, frame.size.height) * screen_get_max_scale(); } -bool DisplayServerOSX::window_is_maximize_allowed(WindowID p_window) const { - return true; -} - -void DisplayServerOSX::_set_window_per_pixel_transparency_enabled(bool p_enabled, WindowID p_window) { - ERR_FAIL_COND(!windows.has(p_window)); - WindowData &wd = windows[p_window]; - - if (!OS_OSX::get_singleton()->is_layered_allowed()) { - return; - } - if (wd.layered_window != p_enabled) { - if (p_enabled) { - [wd.window_object setBackgroundColor:[NSColor clearColor]]; - [wd.window_object setOpaque:NO]; - [wd.window_object setHasShadow:NO]; - CALayer *layer = [wd.window_view layer]; - if (layer) { - [layer setOpaque:NO]; - } -#if defined(VULKAN_ENABLED) - if (context_vulkan) { - //TODO - implement transparency for Vulkan - } -#endif -#if defined(GLES3_ENABLED) - if (gl_manager) { - //TODO - reimplement OpenGLES - } -#endif - wd.layered_window = true; - } else { - [wd.window_object setBackgroundColor:[NSColor colorWithCalibratedWhite:1 alpha:1]]; - [wd.window_object setOpaque:YES]; - [wd.window_object setHasShadow:YES]; - CALayer *layer = [wd.window_view layer]; - if (layer) { - [layer setOpaque:YES]; - } -#if defined(VULKAN_ENABLED) - if (context_vulkan) { - //TODO - implement transparency for Vulkan - } -#endif -#if defined(GLES3_ENABLED) - if (gl_manager) { - //TODO - reimplement OpenGLES - } -#endif - wd.layered_window = false; - } -#if defined(GLES3_ENABLED) - if (gl_manager) { - //TODO - reimplement OpenGLES - } -#endif -#if defined(VULKAN_ENABLED) - if (context_vulkan) { - //TODO - implement transparency for Vulkan - } -#endif - NSRect frameRect = [wd.window_object frame]; - [wd.window_object setFrame:NSMakeRect(frameRect.origin.x, frameRect.origin.y, frameRect.size.width + 1, frameRect.size.height) display:YES]; - [wd.window_object setFrame:frameRect display:YES]; - } -} - void DisplayServerOSX::window_set_mode(WindowMode p_mode, WindowID p_window) { _THREAD_SAFE_METHOD_ @@ -2660,12 +1660,12 @@ void DisplayServerOSX::window_set_mode(WindowMode p_mode, WindowID p_window) { WindowMode old_mode = window_get_mode(p_window); if (old_mode == p_mode) { - return; // do nothing + return; // Do nothing. } switch (old_mode) { case WINDOW_MODE_WINDOWED: { - //do nothing + // Do nothing. } break; case WINDOW_MODE_MINIMIZED: { [wd.window_object deminiaturize:nil]; @@ -2673,10 +1673,8 @@ void DisplayServerOSX::window_set_mode(WindowMode p_mode, WindowID p_window) { case WINDOW_MODE_EXCLUSIVE_FULLSCREEN: case WINDOW_MODE_FULLSCREEN: { [wd.window_object setLevel:NSNormalWindowLevel]; - if (wd.layered_window) { - _set_window_per_pixel_transparency_enabled(true, p_window); - } - if (wd.resize_disabled) { //restore resize disabled + _set_window_per_pixel_transparency_enabled(true, p_window); + if (wd.resize_disabled) { // Restore resize disabled. [wd.window_object setStyleMask:[wd.window_object styleMask] & ~NSWindowStyleMaskResizable]; } if (wd.min_size != Size2i()) { @@ -2699,17 +1697,17 @@ void DisplayServerOSX::window_set_mode(WindowMode p_mode, WindowID p_window) { switch (p_mode) { case WINDOW_MODE_WINDOWED: { - //do nothing + // Do nothing. } break; case WINDOW_MODE_MINIMIZED: { [wd.window_object performMiniaturize:nil]; } break; case WINDOW_MODE_EXCLUSIVE_FULLSCREEN: case WINDOW_MODE_FULLSCREEN: { - if (wd.layered_window) - _set_window_per_pixel_transparency_enabled(false, p_window); - if (wd.resize_disabled) //fullscreen window should be resizable to work + _set_window_per_pixel_transparency_enabled(false, p_window); + if (wd.resize_disabled) { // Fullscreen window should be resizable to work. [wd.window_object setStyleMask:[wd.window_object styleMask] | NSWindowStyleMaskResizable]; + } [wd.window_object setContentMinSize:NSMakeSize(0, 0)]; [wd.window_object setContentMaxSize:NSMakeSize(FLT_MAX, FLT_MAX)]; [wd.window_object toggleFullScreen:nil]; @@ -2729,7 +1727,7 @@ DisplayServer::WindowMode DisplayServerOSX::window_get_mode(WindowID p_window) c ERR_FAIL_COND_V(!windows.has(p_window), WINDOW_MODE_WINDOWED); const WindowData &wd = windows[p_window]; - if (wd.fullscreen) { //if fullscreen, it's not in another mode + if (wd.fullscreen) { // If fullscreen, it's not in another mode. return WINDOW_MODE_FULLSCREEN; } if ([wd.window_object isZoomed] && !wd.resize_disabled) { @@ -2741,10 +1739,14 @@ DisplayServer::WindowMode DisplayServerOSX::window_get_mode(WindowID p_window) c } } - // all other discarded, return windowed. + // All other discarded, return windowed. return WINDOW_MODE_WINDOWED; } +bool DisplayServerOSX::window_is_maximize_allowed(WindowID p_window) const { + return true; +} + void DisplayServerOSX::window_set_flag(WindowFlags p_flag, bool p_enabled, WindowID p_window) { _THREAD_SAFE_METHOD_ @@ -2754,7 +1756,7 @@ void DisplayServerOSX::window_set_flag(WindowFlags p_flag, bool p_enabled, Windo switch (p_flag) { case WINDOW_FLAG_RESIZE_DISABLED: { wd.resize_disabled = p_enabled; - if (wd.fullscreen) { //fullscreen window should be resizable, style will be applied on exiting fs + if (wd.fullscreen) { // Fullscreen window should be resizable, style will be applied on exiting fullscreen. return; } if (p_enabled) { @@ -2764,7 +1766,7 @@ void DisplayServerOSX::window_set_flag(WindowFlags p_flag, bool p_enabled, Windo } } break; case WINDOW_FLAG_BORDERLESS: { - // OrderOut prevents a lose focus bug with the window + // OrderOut prevents a lose focus bug with the window. if ([wd.window_object isVisible]) { [wd.window_object orderOut:nil]; } @@ -2772,15 +1774,14 @@ void DisplayServerOSX::window_set_flag(WindowFlags p_flag, bool p_enabled, Windo if (p_enabled) { [wd.window_object setStyleMask:NSWindowStyleMaskBorderless]; } else { - if (wd.layered_window) - _set_window_per_pixel_transparency_enabled(false, p_window); + _set_window_per_pixel_transparency_enabled(false, p_window); [wd.window_object setStyleMask:NSWindowStyleMaskTitled | NSWindowStyleMaskClosable | NSWindowStyleMaskMiniaturizable | (wd.resize_disabled ? 0 : NSWindowStyleMaskResizable)]; - // Force update of the window styles + // Force update of the window styles. NSRect frameRect = [wd.window_object frame]; [wd.window_object setFrame:NSMakeRect(frameRect.origin.x, frameRect.origin.y, frameRect.size.width + 1, frameRect.size.height) display:NO]; [wd.window_object setFrame:frameRect display:NO]; } - _update_window(wd); + _update_window_style(wd); if ([wd.window_object isVisible]) { if (wd.no_focus) { [wd.window_object orderFront:nil]; @@ -2801,9 +1802,8 @@ void DisplayServerOSX::window_set_flag(WindowFlags p_flag, bool p_enabled, Windo } } break; case WINDOW_FLAG_TRANSPARENT: { - wd.layered_window = p_enabled; if (p_enabled) { - [wd.window_object setStyleMask:NSWindowStyleMaskBorderless]; // force borderless + [wd.window_object setStyleMask:NSWindowStyleMaskBorderless]; // Force borderless. } else if (!wd.borderless) { [wd.window_object setStyleMask:NSWindowStyleMaskTitled | NSWindowStyleMaskClosable | NSWindowStyleMaskMiniaturizable | (wd.resize_disabled ? 0 : NSWindowStyleMaskResizable)]; } @@ -2906,28 +1906,103 @@ void DisplayServerOSX::window_set_ime_position(const Point2i &p_pos, WindowID p_ wd.im_position = p_pos; } -bool DisplayServerOSX::get_swap_cancel_ok() { - return false; +DisplayServer::WindowID DisplayServerOSX::get_window_at_screen_position(const Point2i &p_position) const { + Point2i position = p_position; + position.y *= -1; + position += _get_screens_origin(); + position /= screen_get_max_scale(); + + NSInteger wnum = [NSWindow windowNumberAtPoint:NSMakePoint(position.x, position.y) belowWindowWithWindowNumber:0 /*topmost*/]; + for (Map<WindowID, WindowData>::Element *E = windows.front(); E; E = E->next()) { + if ([E->get().window_object windowNumber] == wnum) { + return E->key(); + } + } + return INVALID_WINDOW_ID; } -void DisplayServerOSX::cursor_set_shape(CursorShape p_shape) { +int64_t DisplayServerOSX::window_get_native_handle(HandleType p_handle_type, WindowID p_window) const { + ERR_FAIL_COND_V(!windows.has(p_window), 0); + switch (p_handle_type) { + case DISPLAY_HANDLE: { + return 0; // Not supported. + } + case WINDOW_HANDLE: { + return (int64_t)windows[p_window].window_object; + } + case WINDOW_VIEW: { + return (int64_t)windows[p_window].window_view; + } + default: { + return 0; + } + } +} + +void DisplayServerOSX::window_attach_instance_id(ObjectID p_instance, WindowID p_window) { _THREAD_SAFE_METHOD_ - ERR_FAIL_INDEX(p_shape, CURSOR_MAX); + ERR_FAIL_COND(!windows.has(p_window)); + windows[p_window].instance_id = p_instance; +} - if (cursor_shape == p_shape) { - return; +ObjectID DisplayServerOSX::window_get_attached_instance_id(WindowID p_window) const { + _THREAD_SAFE_METHOD_ + + ERR_FAIL_COND_V(!windows.has(p_window), ObjectID()); + return windows[p_window].instance_id; +} + +void DisplayServerOSX::gl_window_make_current(DisplayServer::WindowID p_window_id) { +#if defined(GLES3_ENABLED) + gl_manager->window_make_current(p_window_id); +#endif +} + +void DisplayServerOSX::window_set_vsync_mode(DisplayServer::VSyncMode p_vsync_mode, WindowID p_window) { + _THREAD_SAFE_METHOD_ +#if defined(GLES3_ENABLED) + if (gl_manager) { + gl_manager->set_use_vsync(p_vsync_mode); } +#endif +#if defined(VULKAN_ENABLED) + if (context_vulkan) { + context_vulkan->set_vsync_mode(p_window, p_vsync_mode); + } +#endif +} - if (mouse_mode != MOUSE_MODE_VISIBLE && mouse_mode != MOUSE_MODE_CONFINED) { - cursor_shape = p_shape; - return; +DisplayServer::VSyncMode DisplayServerOSX::window_get_vsync_mode(WindowID p_window) const { + _THREAD_SAFE_METHOD_ +#if defined(GLES3_ENABLED) + if (gl_manager) { + return (gl_manager->is_using_vsync() ? DisplayServer::VSyncMode::VSYNC_ENABLED : DisplayServer::VSyncMode::VSYNC_DISABLED); + } +#endif +#if defined(VULKAN_ENABLED) + if (context_vulkan) { + return context_vulkan->get_vsync_mode(p_window); } +#endif + return DisplayServer::VSYNC_ENABLED; +} + +Point2i DisplayServerOSX::ime_get_selection() const { + return im_selection; +} + +String DisplayServerOSX::ime_get_text() const { + return im_text; +} - if (cursors[p_shape] != nullptr) { - [cursors[p_shape] set]; +void DisplayServerOSX::cursor_update_shape() { + _THREAD_SAFE_METHOD_ + + if (cursors[cursor_shape] != nullptr) { + [cursors[cursor_shape] set]; } else { - switch (p_shape) { + switch (cursor_shape) { case CURSOR_ARROW: [[NSCursor arrowCursor] set]; break; @@ -2956,16 +2031,16 @@ void DisplayServerOSX::cursor_set_shape(CursorShape p_shape) { [[NSCursor operationNotAllowedCursor] set]; break; case CURSOR_VSIZE: - [_cursorFromSelector(@selector(_windowResizeNorthSouthCursor), @selector(resizeUpDownCursor)) set]; + [_cursor_from_selector(@selector(_windowResizeNorthSouthCursor), @selector(resizeUpDownCursor)) set]; break; case CURSOR_HSIZE: - [_cursorFromSelector(@selector(_windowResizeEastWestCursor), @selector(resizeLeftRightCursor)) set]; + [_cursor_from_selector(@selector(_windowResizeEastWestCursor), @selector(resizeLeftRightCursor)) set]; break; case CURSOR_BDIAGSIZE: - [_cursorFromSelector(@selector(_windowResizeNorthEastSouthWestCursor)) set]; + [_cursor_from_selector(@selector(_windowResizeNorthEastSouthWestCursor)) set]; break; case CURSOR_FDIAGSIZE: - [_cursorFromSelector(@selector(_windowResizeNorthWestSouthEastCursor)) set]; + [_cursor_from_selector(@selector(_windowResizeNorthWestSouthEastCursor)) set]; break; case CURSOR_MOVE: [[NSCursor arrowCursor] set]; @@ -2977,14 +2052,30 @@ void DisplayServerOSX::cursor_set_shape(CursorShape p_shape) { [[NSCursor resizeLeftRightCursor] set]; break; case CURSOR_HELP: - [_cursorFromSelector(@selector(_helpCursor)) set]; + [_cursor_from_selector(@selector(_helpCursor)) set]; break; default: { } } } +} + +void DisplayServerOSX::cursor_set_shape(CursorShape p_shape) { + _THREAD_SAFE_METHOD_ + + ERR_FAIL_INDEX(p_shape, CURSOR_MAX); + + if (cursor_shape == p_shape) { + return; + } cursor_shape = p_shape; + + if (mouse_mode != MOUSE_MODE_VISIBLE && mouse_mode != MOUSE_MODE_CONFINED) { + return; + } + + cursor_update_shape(); } DisplayServerOSX::CursorShape DisplayServerOSX::cursor_get_shape() const { @@ -3079,7 +2170,6 @@ void DisplayServerOSX::cursor_set_custom_image(const RES &p_cursor, CursorShape NSCursor *cursor = [[NSCursor alloc] initWithImage:nsimage hotSpot:NSMakePoint(p_hotspot.x, p_hotspot.y)]; - [cursors[p_shape] release]; cursors[p_shape] = cursor; Vector<Variant> params; @@ -3092,94 +2182,32 @@ void DisplayServerOSX::cursor_set_custom_image(const RES &p_cursor, CursorShape [cursor set]; } } - - [imgrep release]; - [nsimage release]; } else { - // Reset to default system cursor + // Reset to default system cursor. if (cursors[p_shape] != nullptr) { - [cursors[p_shape] release]; cursors[p_shape] = nullptr; } - CursorShape c = cursor_shape; - cursor_shape = CURSOR_MAX; - cursor_set_shape(c); + cursor_update_shape(); cursors_cache.erase(p_shape); } } -struct LayoutInfo { - String name; - String code; -}; - -static Vector<LayoutInfo> kbd_layouts; -static int current_layout = 0; -static bool keyboard_layout_dirty = true; -static void keyboard_layout_changed(CFNotificationCenterRef center, void *observer, CFStringRef name, const void *object, CFDictionaryRef user_info) { - kbd_layouts.clear(); - current_layout = 0; - keyboard_layout_dirty = true; -} - -void _update_keyboard_layouts() { - @autoreleasepool { - TISInputSourceRef cur_source = TISCopyCurrentKeyboardInputSource(); - NSString *cur_name = (NSString *)TISGetInputSourceProperty(cur_source, kTISPropertyLocalizedName); - CFRelease(cur_source); - - // Enum IME layouts - NSDictionary *filter_ime = @{ (NSString *)kTISPropertyInputSourceType : (NSString *)kTISTypeKeyboardInputMode }; - NSArray *list_ime = (NSArray *)TISCreateInputSourceList((CFDictionaryRef)filter_ime, false); - for (NSUInteger i = 0; i < [list_ime count]; i++) { - LayoutInfo ly; - NSString *name = (NSString *)TISGetInputSourceProperty((TISInputSourceRef)[list_ime objectAtIndex:i], kTISPropertyLocalizedName); - ly.name.parse_utf8([name UTF8String]); - - NSArray *langs = (NSArray *)TISGetInputSourceProperty((TISInputSourceRef)[list_ime objectAtIndex:i], kTISPropertyInputSourceLanguages); - ly.code.parse_utf8([(NSString *)[langs objectAtIndex:0] UTF8String]); - kbd_layouts.push_back(ly); - - if ([name isEqualToString:cur_name]) { - current_layout = kbd_layouts.size() - 1; - } - } - [list_ime release]; - - // Enum plain keyboard layouts - NSDictionary *filter_kbd = @{ (NSString *)kTISPropertyInputSourceType : (NSString *)kTISTypeKeyboardLayout }; - NSArray *list_kbd = (NSArray *)TISCreateInputSourceList((CFDictionaryRef)filter_kbd, false); - for (NSUInteger i = 0; i < [list_kbd count]; i++) { - LayoutInfo ly; - NSString *name = (NSString *)TISGetInputSourceProperty((TISInputSourceRef)[list_kbd objectAtIndex:i], kTISPropertyLocalizedName); - ly.name.parse_utf8([name UTF8String]); - - NSArray *langs = (NSArray *)TISGetInputSourceProperty((TISInputSourceRef)[list_kbd objectAtIndex:i], kTISPropertyInputSourceLanguages); - ly.code.parse_utf8([(NSString *)[langs objectAtIndex:0] UTF8String]); - kbd_layouts.push_back(ly); - - if ([name isEqualToString:cur_name]) { - current_layout = kbd_layouts.size() - 1; - } - } - [list_kbd release]; - } - - keyboard_layout_dirty = false; +bool DisplayServerOSX::get_swap_cancel_ok() { + return false; } int DisplayServerOSX::keyboard_get_layout_count() const { if (keyboard_layout_dirty) { - _update_keyboard_layouts(); + const_cast<DisplayServerOSX *>(this)->_update_keyboard_layouts(); } return kbd_layouts.size(); } void DisplayServerOSX::keyboard_set_current_layout(int p_index) { if (keyboard_layout_dirty) { - _update_keyboard_layouts(); + const_cast<DisplayServerOSX *>(this)->_update_keyboard_layouts(); } ERR_FAIL_INDEX(p_index, kbd_layouts.size()); @@ -3187,31 +2215,29 @@ void DisplayServerOSX::keyboard_set_current_layout(int p_index) { NSString *cur_name = [NSString stringWithUTF8String:kbd_layouts[p_index].name.utf8().get_data()]; NSDictionary *filter_kbd = @{ (NSString *)kTISPropertyInputSourceType : (NSString *)kTISTypeKeyboardLayout }; - NSArray *list_kbd = (NSArray *)TISCreateInputSourceList((CFDictionaryRef)filter_kbd, false); + NSArray *list_kbd = (__bridge NSArray *)TISCreateInputSourceList((__bridge CFDictionaryRef)filter_kbd, false); for (NSUInteger i = 0; i < [list_kbd count]; i++) { - NSString *name = (NSString *)TISGetInputSourceProperty((TISInputSourceRef)[list_kbd objectAtIndex:i], kTISPropertyLocalizedName); + NSString *name = (__bridge NSString *)TISGetInputSourceProperty((__bridge TISInputSourceRef)[list_kbd objectAtIndex:i], kTISPropertyLocalizedName); if ([name isEqualToString:cur_name]) { - TISSelectInputSource((TISInputSourceRef)[list_kbd objectAtIndex:i]); + TISSelectInputSource((__bridge TISInputSourceRef)[list_kbd objectAtIndex:i]); break; } } - [list_kbd release]; NSDictionary *filter_ime = @{ (NSString *)kTISPropertyInputSourceType : (NSString *)kTISTypeKeyboardInputMode }; - NSArray *list_ime = (NSArray *)TISCreateInputSourceList((CFDictionaryRef)filter_ime, false); + NSArray *list_ime = (__bridge NSArray *)TISCreateInputSourceList((__bridge CFDictionaryRef)filter_ime, false); for (NSUInteger i = 0; i < [list_ime count]; i++) { - NSString *name = (NSString *)TISGetInputSourceProperty((TISInputSourceRef)[list_ime objectAtIndex:i], kTISPropertyLocalizedName); + NSString *name = (__bridge NSString *)TISGetInputSourceProperty((__bridge TISInputSourceRef)[list_ime objectAtIndex:i], kTISPropertyLocalizedName); if ([name isEqualToString:cur_name]) { - TISSelectInputSource((TISInputSourceRef)[list_ime objectAtIndex:i]); + TISSelectInputSource((__bridge TISInputSourceRef)[list_ime objectAtIndex:i]); break; } } - [list_ime release]; } int DisplayServerOSX::keyboard_get_current_layout() const { if (keyboard_layout_dirty) { - _update_keyboard_layouts(); + const_cast<DisplayServerOSX *>(this)->_update_keyboard_layouts(); } return current_layout; @@ -3219,7 +2245,7 @@ int DisplayServerOSX::keyboard_get_current_layout() const { String DisplayServerOSX::keyboard_get_layout_language(int p_index) const { if (keyboard_layout_dirty) { - _update_keyboard_layouts(); + const_cast<DisplayServerOSX *>(this)->_update_keyboard_layouts(); } ERR_FAIL_INDEX_V(p_index, kbd_layouts.size(), ""); @@ -3228,7 +2254,7 @@ String DisplayServerOSX::keyboard_get_layout_language(int p_index) const { String DisplayServerOSX::keyboard_get_layout_name(int p_index) const { if (keyboard_layout_dirty) { - _update_keyboard_layouts(); + const_cast<DisplayServerOSX *>(this)->_update_keyboard_layouts(); } ERR_FAIL_INDEX_V(p_index, kbd_layouts.size(), ""); @@ -3242,124 +2268,8 @@ Key DisplayServerOSX::keyboard_get_keycode_from_physical(Key p_keycode) const { Key modifiers = p_keycode & KeyModifierMask::MODIFIER_MASK; Key keycode_no_mod = p_keycode & KeyModifierMask::CODE_MASK; - unsigned int osx_keycode = unmapKey((Key)keycode_no_mod); - return (Key)(remapKey(osx_keycode, 0) | modifiers); -} - -void DisplayServerOSX::_push_input(const Ref<InputEvent> &p_event) { - Ref<InputEvent> ev = p_event; - Input::get_singleton()->parse_input_event(ev); -} - -void DisplayServerOSX::_release_pressed_events() { - _THREAD_SAFE_METHOD_ - if (Input::get_singleton()) { - Input::get_singleton()->release_pressed_events(); - } -} - -NSMenu *DisplayServerOSX::_get_dock_menu() const { - return dock_menu; -} - -void DisplayServerOSX::_menu_callback(id p_sender) { - if (![p_sender representedObject]) { - return; - } - - GlobalMenuItem *value = [p_sender representedObject]; - - if (value) { - if (value->checkable) { - if ([p_sender state] == NSControlStateValueOff) { - [p_sender setState:NSControlStateValueOn]; - } else { - [p_sender setState:NSControlStateValueOff]; - } - } - - if (value->callback != Callable()) { - Variant tag = value->meta; - Variant *tagp = &tag; - Variant ret; - Callable::CallError ce; - value->callback.call((const Variant **)&tagp, 1, ret, ce); - } - } -} - -void DisplayServerOSX::_send_event(NSEvent *p_event) { - // special case handling of command-period, which is traditionally a special - // shortcut in macOS and doesn't arrive at our regular keyDown handler. - if ([p_event type] == NSEventTypeKeyDown) { - if (([p_event modifierFlags] & NSEventModifierFlagCommand) && [p_event keyCode] == 0x2f) { - Ref<InputEventKey> k; - k.instantiate(); - - _get_key_modifier_state([p_event modifierFlags], k); - k->set_window_id(DisplayServerOSX::INVALID_WINDOW_ID); - k->set_pressed(true); - k->set_keycode(Key::PERIOD); - k->set_physical_keycode(Key::PERIOD); - k->set_echo([p_event isARepeat]); - - Input::get_singleton()->parse_input_event(k); - } - } -} - -void DisplayServerOSX::_process_key_events() { - Ref<InputEventKey> k; - for (int i = 0; i < key_event_pos; i++) { - const KeyEvent &ke = key_event_buffer[i]; - if (ke.raw) { - // Non IME input - no composite characters, pass events as is - k.instantiate(); - - k->set_window_id(ke.window_id); - _get_key_modifier_state(ke.osx_state, k); - k->set_pressed(ke.pressed); - k->set_echo(ke.echo); - k->set_keycode(ke.keycode); - k->set_physical_keycode((Key)ke.physical_keycode); - k->set_unicode(ke.unicode); - - _push_input(k); - } else { - // IME input - if ((i == 0 && ke.keycode == Key::NONE) || (i > 0 && key_event_buffer[i - 1].keycode == Key::NONE)) { - k.instantiate(); - - k->set_window_id(ke.window_id); - _get_key_modifier_state(ke.osx_state, k); - k->set_pressed(ke.pressed); - k->set_echo(ke.echo); - k->set_keycode(Key::NONE); - k->set_physical_keycode(Key::NONE); - k->set_unicode(ke.unicode); - - _push_input(k); - } - if (ke.keycode != Key::NONE) { - k.instantiate(); - - k->set_window_id(ke.window_id); - _get_key_modifier_state(ke.osx_state, k); - k->set_pressed(ke.pressed); - k->set_echo(ke.echo); - k->set_keycode(ke.keycode); - k->set_physical_keycode((Key)ke.physical_keycode); - - if (i + 1 < key_event_pos && key_event_buffer[i + 1].keycode == Key::NONE) { - k->set_unicode(key_event_buffer[i + 1].unicode); - } - - _push_input(k); - } - } - } - - key_event_pos = 0; + unsigned int osx_keycode = KeyMappingOSX::unmap_key((Key)keycode_no_mod); + return (Key)(KeyMappingOSX::remap_key(osx_keycode, 0) | modifiers); } void DisplayServerOSX::process_events() { @@ -3387,8 +2297,8 @@ void DisplayServerOSX::process_events() { for (Map<WindowID, WindowData>::Element *E = windows.front(); E; E = E->next()) { WindowData &wd = E->get(); if (wd.mpath.size() > 0) { - const Vector2 mpos = _get_mouse_pos(wd, [wd.window_object mouseLocationOutsideOfEventStream]); - if (Geometry2D::is_point_in_polygon(mpos, wd.mpath)) { + update_mouse_pos(wd, [wd.window_object mouseLocationOutsideOfEventStream]); + if (Geometry2D::is_point_in_polygon(wd.mouse_pos, wd.mpath)) { if ([wd.window_object ignoresMouseEvents]) { [wd.window_object setIgnoresMouseEvents:NO]; } @@ -3403,9 +2313,6 @@ void DisplayServerOSX::process_events() { } } } - - [autoreleasePool drain]; - autoreleasePool = [[NSAutoreleasePool alloc] init]; } void DisplayServerOSX::force_process_and_drop_events() { @@ -3416,6 +2323,18 @@ void DisplayServerOSX::force_process_and_drop_events() { drop_events = false; } +void DisplayServerOSX::release_rendering_thread() { +} + +void DisplayServerOSX::make_rendering_thread() { +} + +void DisplayServerOSX::swap_buffers() { +#if defined(GLES3_ENABLED) + gl_manager->swap_buffers(); +#endif +} + void DisplayServerOSX::set_native_icon(const String &p_filename) { _THREAD_SAFE_METHOD_ @@ -3428,10 +2347,10 @@ void DisplayServerOSX::set_native_icon(const String &p_filename) { f->get_buffer((uint8_t *)&data.write[0], len); memdelete(f); - NSData *icon_data = [[[NSData alloc] initWithBytes:&data.write[0] length:len] autorelease]; + NSData *icon_data = [[NSData alloc] initWithBytes:&data.write[0] length:len]; ERR_FAIL_COND_MSG(!icon_data, "Error reading icon data."); - NSImage *icon = [[[NSImage alloc] initWithData:icon_data] autorelease]; + NSImage *icon = [[NSImage alloc] initWithData:icon_data]; ERR_FAIL_COND_MSG(!icon, "Error loading icon."); [NSApp setApplicationIconImage:icon]; @@ -3474,112 +2393,6 @@ void DisplayServerOSX::set_icon(const Ref<Image> &p_icon) { [nsimg addRepresentation:imgrep]; [NSApp setApplicationIconImage:nsimg]; - - [imgrep release]; - [nsimg release]; -} - -void DisplayServerOSX::window_set_vsync_mode(DisplayServer::VSyncMode p_vsync_mode, WindowID p_window) { - _THREAD_SAFE_METHOD_ -#if defined(GLES3_ENABLED) - if (gl_manager) { - gl_manager->swap_buffers(); - } -#endif -#if defined(VULKAN_ENABLED) - if (context_vulkan) { - context_vulkan->set_vsync_mode(p_window, p_vsync_mode); - } -#endif -} - -DisplayServer::VSyncMode DisplayServerOSX::window_get_vsync_mode(WindowID p_window) const { - _THREAD_SAFE_METHOD_ -#if defined(GLES3_ENABLED) - if (gl_manager) { - return (gl_manager->is_using_vsync() ? DisplayServer::VSyncMode::VSYNC_ENABLED : DisplayServer::VSyncMode::VSYNC_DISABLED); - } -#endif -#if defined(VULKAN_ENABLED) - if (context_vulkan) { - return context_vulkan->get_vsync_mode(p_window); - } -#endif - return DisplayServer::VSYNC_ENABLED; -} - -Vector<String> DisplayServerOSX::get_rendering_drivers_func() { - Vector<String> drivers; - -#if defined(VULKAN_ENABLED) - drivers.push_back("vulkan"); -#endif -#if defined(GLES3_ENABLED) - drivers.push_back("opengl3"); -#endif - - return drivers; -} - -void DisplayServerOSX::gl_window_make_current(DisplayServer::WindowID p_window_id) { -#if defined(GLES3_ENABLED) - gl_manager->window_make_current(p_window_id); -#endif -} - -Point2i DisplayServerOSX::ime_get_selection() const { - return im_selection; -} - -String DisplayServerOSX::ime_get_text() const { - return im_text; -} - -DisplayServer::WindowID DisplayServerOSX::get_window_at_screen_position(const Point2i &p_position) const { - Point2i position = p_position; - position.y *= -1; - position += _get_screens_origin(); - position /= screen_get_max_scale(); - - NSInteger wnum = [NSWindow windowNumberAtPoint:NSMakePoint(position.x, position.y) belowWindowWithWindowNumber:0 /*topmost*/]; - for (Map<WindowID, WindowData>::Element *E = windows.front(); E; E = E->next()) { - if ([E->get().window_object windowNumber] == wnum) { - return E->key(); - } - } - return INVALID_WINDOW_ID; -} - -int64_t DisplayServerOSX::window_get_native_handle(HandleType p_handle_type, WindowID p_window) const { - ERR_FAIL_COND_V(!windows.has(p_window), 0); - switch (p_handle_type) { - case DISPLAY_HANDLE: { - return 0; // Not supported. - } - case WINDOW_HANDLE: { - return (int64_t)windows[p_window].window_object; - } - case WINDOW_VIEW: { - return (int64_t)windows[p_window].window_view; - } - default: { - return 0; - } - } -} - -void DisplayServerOSX::window_attach_instance_id(ObjectID p_instance, WindowID p_window) { - _THREAD_SAFE_METHOD_ - - ERR_FAIL_COND(!windows.has(p_window)); - windows[p_window].instance_id = p_instance; -} - -ObjectID DisplayServerOSX::window_get_attached_instance_id(WindowID p_window) const { - _THREAD_SAFE_METHOD_ - - ERR_FAIL_COND_V(!windows.has(p_window), ObjectID()); - return windows[p_window].instance_id; } DisplayServer *DisplayServerOSX::create_func(const String &p_rendering_driver, WindowMode p_mode, VSyncMode p_vsync_mode, uint32_t p_flags, const Vector2i &p_resolution, Error &r_error) { @@ -3590,179 +2403,48 @@ DisplayServer *DisplayServerOSX::create_func(const String &p_rendering_driver, W return ds; } -DisplayServerOSX::WindowID DisplayServerOSX::_create_window(WindowMode p_mode, VSyncMode p_vsync_mode, const Rect2i &p_rect) { - WindowID id; - const float scale = screen_get_max_scale(); - { - WindowData wd; - - wd.window_delegate = [[GodotWindowDelegate alloc] init]; - ERR_FAIL_COND_V_MSG(wd.window_delegate == nil, INVALID_WINDOW_ID, "Can't create a window delegate"); - [wd.window_delegate setWindowID:window_id_counter]; - - Point2i position = p_rect.position; - // OS X native y-coordinate relative to _get_screens_origin() is negative, - // Godot passes a positive value - position.y *= -1; - position += _get_screens_origin(); - - // initWithContentRect uses bottom-left corner of the window’s frame as origin. - wd.window_object = [[GodotWindow alloc] - initWithContentRect:NSMakeRect(position.x / scale, (position.y - p_rect.size.height) / scale, p_rect.size.width / scale, p_rect.size.height / scale) - styleMask:NSWindowStyleMaskTitled | NSWindowStyleMaskClosable | NSWindowStyleMaskMiniaturizable | NSWindowStyleMaskResizable - backing:NSBackingStoreBuffered - defer:NO]; - ERR_FAIL_COND_V_MSG(wd.window_object == nil, INVALID_WINDOW_ID, "Can't create a window"); - - wd.window_view = [[GodotContentView alloc] init]; - ERR_FAIL_COND_V_MSG(wd.window_view == nil, INVALID_WINDOW_ID, "Can't create a window view"); - [wd.window_view setWindowID:window_id_counter]; - [wd.window_view setWantsLayer:TRUE]; - - [wd.window_object setCollectionBehavior:NSWindowCollectionBehaviorFullScreenPrimary]; - [wd.window_object setContentView:wd.window_view]; - [wd.window_object setDelegate:wd.window_delegate]; - [wd.window_object setAcceptsMouseMovedEvents:YES]; - [wd.window_object setRestorable:NO]; - [wd.window_object setColorSpace:[NSColorSpace sRGBColorSpace]]; - - if ([wd.window_object respondsToSelector:@selector(setTabbingMode:)]) { - [wd.window_object setTabbingMode:NSWindowTabbingModeDisallowed]; - } - - CALayer *layer = [wd.window_view layer]; - if (layer) { - layer.contentsScale = scale; - } +Vector<String> DisplayServerOSX::get_rendering_drivers_func() { + Vector<String> drivers; #if defined(VULKAN_ENABLED) - if (context_vulkan) { - Error err = context_vulkan->window_create(window_id_counter, p_vsync_mode, wd.window_view, p_rect.size.width, p_rect.size.height); - ERR_FAIL_COND_V_MSG(err != OK, INVALID_WINDOW_ID, "Can't create a Vulkan context"); - } -#endif -#if defined(GLES3_ENABLED) - if (gl_manager) { - Error err = gl_manager->window_create(window_id_counter, wd.window_view, p_rect.size.width, p_rect.size.height); - ERR_FAIL_COND_V_MSG(err != OK, INVALID_WINDOW_ID, "Can't create an OpenGL context"); - } + drivers.push_back("vulkan"); #endif - id = window_id_counter++; - windows[id] = wd; - } - - WindowData &wd = windows[id]; - window_set_mode(p_mode, id); - - const NSRect contentRect = [wd.window_view frame]; - wd.size.width = contentRect.size.width * scale; - wd.size.height = contentRect.size.height * scale; - - CALayer *layer = [wd.window_view layer]; - if (layer) { - layer.contentsScale = scale; - } - #if defined(GLES3_ENABLED) - if (gl_manager) { - gl_manager->window_resize(id, wd.size.width, wd.size.height); - } -#endif -#if defined(VULKAN_ENABLED) - if (context_vulkan) { - context_vulkan->window_resize(id, wd.size.width, wd.size.height); - } + drivers.push_back("opengl3"); #endif - return id; -} - -void DisplayServerOSX::_dispatch_input_events(const Ref<InputEvent> &p_event) { - ((DisplayServerOSX *)(get_singleton()))->_dispatch_input_event(p_event); -} - -void DisplayServerOSX::_dispatch_input_event(const Ref<InputEvent> &p_event) { - _THREAD_SAFE_METHOD_ - if (!in_dispatch_input_event) { - in_dispatch_input_event = true; - - Variant ev = p_event; - Variant *evp = &ev; - Variant ret; - Callable::CallError ce; - - Ref<InputEventFromWindow> event_from_window = p_event; - if (event_from_window.is_valid() && event_from_window->get_window_id() != INVALID_WINDOW_ID) { - //send to a window - if (windows.has(event_from_window->get_window_id())) { - Callable callable = windows[event_from_window->get_window_id()].input_event_callback; - if (callable.is_null()) { - return; - } - callable.call((const Variant **)&evp, 1, ret, ce); - } - } else { - //send to all windows - for (Map<WindowID, WindowData>::Element *E = windows.front(); E; E = E->next()) { - Callable callable = E->get().input_event_callback; - if (callable.is_null()) { - continue; - } - callable.call((const Variant **)&evp, 1, ret, ce); - } - } - - in_dispatch_input_event = false; - } -} - -void DisplayServerOSX::release_rendering_thread() { -} - -void DisplayServerOSX::make_rendering_thread() { + return drivers; } -void DisplayServerOSX::swap_buffers() { -#if defined(GLES3_ENABLED) - gl_manager->swap_buffers(); -#endif +void DisplayServerOSX::register_osx_driver() { + register_create_function("osx", create_func, get_rendering_drivers_func); } DisplayServerOSX::DisplayServerOSX(const String &p_rendering_driver, WindowMode p_mode, VSyncMode p_vsync_mode, uint32_t p_flags, const Vector2i &p_resolution, Error &r_error) { Input::get_singleton()->set_event_dispatch_function(_dispatch_input_events); r_error = OK; - drop_events = false; memset(cursors, 0, sizeof(cursors)); - cursor_shape = CURSOR_ARROW; - - key_event_pos = 0; - mouse_mode = MOUSE_MODE_VISIBLE; - autoreleasePool = [[NSAutoreleasePool alloc] init]; + event_source = CGEventSourceCreate(kCGEventSourceStateHIDSystemState); + ERR_FAIL_COND(!event_source); - eventSource = CGEventSourceCreate(kCGEventSourceStateHIDSystemState); - ERR_FAIL_COND(!eventSource); - - CGEventSourceSetLocalEventsSuppressionInterval(eventSource, 0.0); - - keyboard_layout_dirty = true; - displays_arrangement_dirty = true; + CGEventSourceSetLocalEventsSuppressionInterval(event_source, 0.0); int screen_count = get_screen_count(); for (int i = 0; i < screen_count; i++) { display_max_scale = fmax(display_max_scale, screen_get_scale(i)); } - // Register to be notified on keyboard layout changes + // Register to be notified on keyboard layout changes. CFNotificationCenterAddObserver(CFNotificationCenterGetDistributedCenter(), - nullptr, keyboard_layout_changed, + nullptr, _keyboard_layout_changed, kTISNotifySelectedKeyboardInputSourceChanged, nullptr, CFNotificationSuspensionBehaviorDeliverImmediately); - // Register to be notified on displays arrangement changes - CGDisplayRegisterReconfigurationCallback(displays_arrangement_changed, nullptr); + // Register to be notified on displays arrangement changes. + CGDisplayRegisterReconfigurationCallback(_displays_arrangement_changed, nullptr); NSMenuItem *menu_item; NSString *title; @@ -3772,11 +2454,11 @@ DisplayServerOSX::DisplayServerOSX(const String &p_rendering_driver, WindowMode nsappname = [[NSProcessInfo processInfo] processName]; } - // Setup Dock menu + // Setup Dock menu. dock_menu = [[NSMenu alloc] initWithTitle:@"_dock"]; - // Setup Apple menu - apple_menu = [[[NSMenu alloc] initWithTitle:@""] autorelease]; + // Setup Apple menu. + apple_menu = [[NSMenu alloc] initWithTitle:@""]; title = [NSString stringWithFormat:NSLocalizedString(@"About %@", nil), nsappname]; [apple_menu addItemWithTitle:title action:@selector(showAbout:) keyEquivalent:@""]; @@ -3786,7 +2468,6 @@ DisplayServerOSX::DisplayServerOSX(const String &p_rendering_driver, WindowMode menu_item = [apple_menu addItemWithTitle:NSLocalizedString(@"Services", nil) action:nil keyEquivalent:@""]; [apple_menu setSubmenu:services forItem:menu_item]; [NSApp setServicesMenu:services]; - [services release]; [apple_menu addItem:[NSMenuItem separatorItem]]; @@ -3803,7 +2484,7 @@ DisplayServerOSX::DisplayServerOSX(const String &p_rendering_driver, WindowMode title = [NSString stringWithFormat:NSLocalizedString(@"Quit %@", nil), nsappname]; [apple_menu addItemWithTitle:title action:@selector(terminate:) keyEquivalent:@"q"]; - // Add items to the menu bar + // Add items to the menu bar. NSMenu *main_menu = [NSApp mainMenu]; menu_item = [main_menu addItemWithTitle:@"" action:nil keyEquivalent:@""]; [main_menu setSubmenu:apple_menu forItem:menu_item]; @@ -3865,15 +2546,7 @@ DisplayServerOSX::DisplayServerOSX(const String &p_rendering_driver, WindowMode } DisplayServerOSX::~DisplayServerOSX() { - if (dock_menu) { - [dock_menu release]; - } - - for (Map<String, NSMenu *>::Element *E = submenu.front(); E; E = E->next()) { - [E->get() release]; - } - - //destroy all windows + // Destroy all windows. for (Map<WindowID, WindowData>::Element *E = windows.front(); E;) { Map<WindowID, WindowData>::Element *F = E; E = E->next(); @@ -3881,7 +2554,7 @@ DisplayServerOSX::~DisplayServerOSX() { [F->get().window_object close]; } - //destroy drivers + // Destroy drivers. #if defined(GLES3_ENABLED) if (gl_manager) { memdelete(gl_manager); @@ -3902,11 +2575,7 @@ DisplayServerOSX::~DisplayServerOSX() { #endif CFNotificationCenterRemoveObserver(CFNotificationCenterGetDistributedCenter(), nullptr, kTISNotifySelectedKeyboardInputSourceChanged, nullptr); - CGDisplayRemoveReconfigurationCallback(displays_arrangement_changed, nullptr); + CGDisplayRemoveReconfigurationCallback(_displays_arrangement_changed, nullptr); cursors_cache.clear(); } - -void DisplayServerOSX::register_osx_driver() { - register_create_function("osx", create_func, get_rendering_drivers_func); -} diff --git a/platform/osx/gl_manager_osx.h b/platform/osx/gl_manager_osx_legacy.h index 0229b672a2..b5a1b9dd98 100644 --- a/platform/osx/gl_manager_osx.h +++ b/platform/osx/gl_manager_osx_legacy.h @@ -1,5 +1,5 @@ /*************************************************************************/ -/* gl_manager_osx.h */ +/* gl_manager_osx_legacy.h */ /*************************************************************************/ /* This file is part of: */ /* GODOT ENGINE */ @@ -28,8 +28,8 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#ifndef GL_MANAGER_OSX_H -#define GL_MANAGER_OSX_H +#ifndef GL_MANAGER_OSX_LEGACY_H +#define GL_MANAGER_OSX_LEGACY_H #if defined(OSX_ENABLED) && defined(GLES3_ENABLED) @@ -50,29 +50,21 @@ public: private: struct GLWindow { - GLWindow() { in_use = false; } - bool in_use; + int width = 0; + int height = 0; - DisplayServer::WindowID window_id; - int width; - int height; - - id window_view; - NSOpenGLContext *context; + id window_view = nullptr; + NSOpenGLContext *context = nullptr; }; - LocalVector<GLWindow> _windows; - - NSOpenGLContext *_shared_context = nullptr; - GLWindow *_current_window; + Map<DisplayServer::WindowID, GLWindow> windows; - Error _create_context(GLWindow &win); - void _internal_set_current_window(GLWindow *p_win); + NSOpenGLContext *shared_context = nullptr; + DisplayServer::WindowID current_window = DisplayServer::INVALID_WINDOW_ID; - GLWindow &get_window(unsigned int id) { return _windows[id]; } - const GLWindow &get_window(unsigned int id) const { return _windows[id]; } + Error create_context(GLWindow &win); - bool use_vsync; + bool use_vsync = false; ContextType context_type; public: @@ -80,7 +72,6 @@ public: void window_destroy(DisplayServer::WindowID p_window_id); void window_resize(DisplayServer::WindowID p_window_id, int p_width, int p_height); - // get directly from the cached GLWindow int window_get_width(DisplayServer::WindowID p_window_id = 0); int window_get_height(DisplayServer::WindowID p_window_id = 0); @@ -91,6 +82,7 @@ public: void window_make_current(DisplayServer::WindowID p_window_id); void window_update(DisplayServer::WindowID p_window_id); + void window_set_per_pixel_transparency_enabled(DisplayServer::WindowID p_window_id, bool p_enabled); Error initialize(); @@ -101,6 +93,5 @@ public: ~GLManager_OSX(); }; -#endif // defined(OSX_ENABLED) && defined(GLES3_ENABLED) - -#endif // GL_MANAGER_OSX_H +#endif // OSX_ENABLED && GLES3_ENABLED +#endif // GL_MANAGER_OSX_LEGACY_H diff --git a/platform/osx/gl_manager_osx.mm b/platform/osx/gl_manager_osx_legacy.mm index 3e70de8523..fbe64e32a3 100644 --- a/platform/osx/gl_manager_osx.mm +++ b/platform/osx/gl_manager_osx_legacy.mm @@ -1,5 +1,5 @@ /*************************************************************************/ -/* gl_manager_osx.mm */ +/* gl_manager_osx_legacy.mm */ /*************************************************************************/ /* This file is part of: */ /* GODOT ENGINE */ @@ -28,7 +28,7 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#include "gl_manager_osx.h" +#include "gl_manager_osx_legacy.h" #ifdef OSX_ENABLED #ifdef GLES3_ENABLED @@ -36,7 +36,7 @@ #include <stdio.h> #include <stdlib.h> -Error GLManager_OSX::_create_context(GLWindow &win) { +Error GLManager_OSX::create_context(GLWindow &win) { NSOpenGLPixelFormatAttribute attributes[] = { NSOpenGLPFADoubleBuffer, NSOpenGLPFAClosestPolicy, @@ -50,10 +50,10 @@ Error GLManager_OSX::_create_context(GLWindow &win) { NSOpenGLPixelFormat *pixel_format = [[NSOpenGLPixelFormat alloc] initWithAttributes:attributes]; ERR_FAIL_COND_V(pixel_format == nil, ERR_CANT_CREATE); - win.context = [[NSOpenGLContext alloc] initWithFormat:pixel_format shareContext:_shared_context]; + win.context = [[NSOpenGLContext alloc] initWithFormat:pixel_format shareContext:shared_context]; ERR_FAIL_COND_V(win.context == nil, ERR_CANT_CREATE); - if (_shared_context == nullptr) { - _shared_context = win.context; + if (shared_context == nullptr) { + shared_context = win.context; } [win.context setView:win.window_view]; @@ -63,40 +63,27 @@ Error GLManager_OSX::_create_context(GLWindow &win) { } Error GLManager_OSX::window_create(DisplayServer::WindowID p_window_id, id p_view, int p_width, int p_height) { - if (p_window_id >= (int)_windows.size()) { - _windows.resize(p_window_id + 1); - } - - GLWindow &win = _windows[p_window_id]; - win.in_use = true; - win.window_id = p_window_id; + GLWindow win; win.width = p_width; win.height = p_height; win.window_view = p_view; - if (_create_context(win) != OK) { - _windows.remove_at(_windows.size() - 1); + if (create_context(win) != OK) { return FAILED; } - window_make_current(_windows.size() - 1); + windows[p_window_id] = win; + window_make_current(p_window_id); return OK; } -void GLManager_OSX::_internal_set_current_window(GLWindow *p_win) { - _current_window = p_win; -} - void GLManager_OSX::window_resize(DisplayServer::WindowID p_window_id, int p_width, int p_height) { - if (p_window_id == -1) { + if (!windows.has(p_window_id)) { return; } - GLWindow &win = _windows[p_window_id]; - if (!win.in_use) { - return; - } + GLWindow &win = windows[p_window_id]; win.width = p_width; win.height = p_height; @@ -116,24 +103,37 @@ void GLManager_OSX::window_resize(DisplayServer::WindowID p_window_id, int p_wid } int GLManager_OSX::window_get_width(DisplayServer::WindowID p_window_id) { - return get_window(p_window_id).width; + if (!windows.has(p_window_id)) { + return 0; + } + + GLWindow &win = windows[p_window_id]; + return win.width; } int GLManager_OSX::window_get_height(DisplayServer::WindowID p_window_id) { - return get_window(p_window_id).height; + if (!windows.has(p_window_id)) { + return 0; + } + + GLWindow &win = windows[p_window_id]; + return win.height; } void GLManager_OSX::window_destroy(DisplayServer::WindowID p_window_id) { - GLWindow &win = get_window(p_window_id); - win.in_use = false; + if (!windows.has(p_window_id)) { + return; + } - if (_current_window == &win) { - _current_window = nullptr; + if (current_window == p_window_id) { + current_window = DisplayServer::INVALID_WINDOW_ID; } + + windows.erase(p_window_id); } void GLManager_OSX::release_current() { - if (!_current_window) { + if (current_window == DisplayServer::INVALID_WINDOW_ID) { return; } @@ -141,63 +141,59 @@ void GLManager_OSX::release_current() { } void GLManager_OSX::window_make_current(DisplayServer::WindowID p_window_id) { - if (p_window_id == -1) { - return; - } - - GLWindow &win = _windows[p_window_id]; - if (!win.in_use) { + if (current_window == p_window_id) { return; } - - if (&win == _current_window) { + if (!windows.has(p_window_id)) { return; } + GLWindow &win = windows[p_window_id]; [win.context makeCurrentContext]; - _internal_set_current_window(&win); + current_window = p_window_id; } void GLManager_OSX::make_current() { - if (!_current_window) { + if (current_window == DisplayServer::INVALID_WINDOW_ID) { return; } - if (!_current_window->in_use) { - WARN_PRINT("current window not in use!"); + if (!windows.has(current_window)) { return; } - [_current_window->context makeCurrentContext]; + + GLWindow &win = windows[current_window]; + [win.context makeCurrentContext]; } void GLManager_OSX::swap_buffers() { - // NO NEED TO CALL SWAP BUFFERS for each window... - // see https://www.khronos.org/registry/OpenGL-Refpages/gl2.1/xhtml/glXSwapBuffers.xml - - if (!_current_window) { - return; - } - if (!_current_window->in_use) { - WARN_PRINT("current window not in use!"); - return; + for (Map<DisplayServer::WindowID, GLWindow>::Element *E = windows.front(); E; E = E->next()) { + [E->get().context flushBuffer]; } - [_current_window->context flushBuffer]; } void GLManager_OSX::window_update(DisplayServer::WindowID p_window_id) { - if (p_window_id == -1) { + if (!windows.has(p_window_id)) { return; } - GLWindow &win = _windows[p_window_id]; - if (!win.in_use) { - return; - } + GLWindow &win = windows[p_window_id]; + [win.context update]; +} - if (&win == _current_window) { +void GLManager_OSX::window_set_per_pixel_transparency_enabled(DisplayServer::WindowID p_window_id, bool p_enabled) { + if (!windows.has(p_window_id)) { return; } + GLWindow &win = windows[p_window_id]; + if (p_enabled) { + GLint opacity = 0; + [win.context setValues:&opacity forParameter:NSOpenGLContextParameterSurfaceOpacity]; + } else { + GLint opacity = 1; + [win.context setValues:&opacity forParameter:NSOpenGLContextParameterSurfaceOpacity]; + } [win.context update]; } @@ -207,6 +203,7 @@ Error GLManager_OSX::initialize() { void GLManager_OSX::set_use_vsync(bool p_use) { use_vsync = p_use; + CGLContextObj ctx = CGLGetCurrentContext(); if (ctx) { GLint swapInterval = p_use ? 1 : 0; @@ -221,8 +218,6 @@ bool GLManager_OSX::is_using_vsync() const { GLManager_OSX::GLManager_OSX(ContextType p_context_type) { context_type = p_context_type; - use_vsync = false; - _current_window = nullptr; } GLManager_OSX::~GLManager_OSX() { diff --git a/platform/osx/godot_application.h b/platform/osx/godot_application.h new file mode 100644 index 0000000000..8d48a659f3 --- /dev/null +++ b/platform/osx/godot_application.h @@ -0,0 +1,42 @@ +/*************************************************************************/ +/* godot_application.h */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/*************************************************************************/ + +#ifndef GODOT_APPLICATION_H +#define GODOT_APPLICATION_H + +#include "core/os/os.h" + +#import <AppKit/AppKit.h> +#import <Foundation/Foundation.h> + +@interface GodotApplication : NSApplication +@end + +#endif // GODOT_APPLICATION_H diff --git a/platform/osx/godot_application.mm b/platform/osx/godot_application.mm new file mode 100644 index 0000000000..00a58700e8 --- /dev/null +++ b/platform/osx/godot_application.mm @@ -0,0 +1,53 @@ +/*************************************************************************/ +/* godot_application.mm */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/*************************************************************************/ + +#include "godot_application.h" + +#include "display_server_osx.h" + +@implementation GodotApplication + +- (void)sendEvent:(NSEvent *)event { + DisplayServerOSX *ds = (DisplayServerOSX *)DisplayServer::get_singleton(); + if (ds) { + ds->send_event(event); + } + + // From http://cocoadev.com/index.pl?GameKeyboardHandlingAlmost + // This works around an AppKit bug, where key up events while holding + // down the command key don't get sent to the key window. + if ([event type] == NSEventTypeKeyUp && ([event modifierFlags] & NSEventModifierFlagCommand)) { + [[self keyWindow] sendEvent:event]; + } else { + [super sendEvent:event]; + } +} + +@end diff --git a/platform/osx/godot_application_delegate.h b/platform/osx/godot_application_delegate.h new file mode 100644 index 0000000000..8eec762d8f --- /dev/null +++ b/platform/osx/godot_application_delegate.h @@ -0,0 +1,45 @@ +/*************************************************************************/ +/* godot_application_delegate.h */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/*************************************************************************/ + +#ifndef GODOT_APPLICATION_DELEGATE_H +#define GODOT_APPLICATION_DELEGATE_H + +#include "core/os/os.h" + +#import <AppKit/AppKit.h> +#import <Foundation/Foundation.h> + +@interface GodotApplicationDelegate : NSObject +- (void)forceUnbundledWindowActivationHackStep1; +- (void)forceUnbundledWindowActivationHackStep2; +- (void)forceUnbundledWindowActivationHackStep3; +@end + +#endif // GODOT_APPLICATION_DELEGATE_H diff --git a/platform/osx/godot_application_delegate.mm b/platform/osx/godot_application_delegate.mm new file mode 100644 index 0000000000..be284ba543 --- /dev/null +++ b/platform/osx/godot_application_delegate.mm @@ -0,0 +1,132 @@ +/*************************************************************************/ +/* godot_application_delegate.mm */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/*************************************************************************/ + +#include "godot_application_delegate.h" + +#include "display_server_osx.h" +#include "os_osx.h" + +@implementation GodotApplicationDelegate + +- (void)forceUnbundledWindowActivationHackStep1 { + // Step 1: Switch focus to macOS SystemUIServer process. + // Required to perform step 2, TransformProcessType will fail if app is already the in focus. + for (NSRunningApplication *app in [NSRunningApplication runningApplicationsWithBundleIdentifier:@"com.apple.systemuiserver"]) { + [app activateWithOptions:NSApplicationActivateIgnoringOtherApps]; + break; + } + [self performSelector:@selector(forceUnbundledWindowActivationHackStep2) + withObject:nil + afterDelay:0.02]; +} + +- (void)forceUnbundledWindowActivationHackStep2 { + // Step 2: Register app as foreground process. + ProcessSerialNumber psn = { 0, kCurrentProcess }; + (void)TransformProcessType(&psn, kProcessTransformToForegroundApplication); + [self performSelector:@selector(forceUnbundledWindowActivationHackStep3) withObject:nil afterDelay:0.02]; +} + +- (void)forceUnbundledWindowActivationHackStep3 { + // Step 3: Switch focus back to app window. + [[NSRunningApplication currentApplication] activateWithOptions:NSApplicationActivateIgnoringOtherApps]; +} + +- (void)applicationDidFinishLaunching:(NSNotification *)notice { + NSString *nsappname = [[[NSBundle mainBundle] infoDictionary] objectForKey:@"CFBundleName"]; + if (nsappname == nil || isatty(STDOUT_FILENO) || isatty(STDIN_FILENO) || isatty(STDERR_FILENO)) { + // If the executable is started from terminal or is not bundled, macOS WindowServer won't register and activate app window correctly (menu and title bar are grayed out and input ignored). + [self performSelector:@selector(forceUnbundledWindowActivationHackStep1) withObject:nil afterDelay:0.02]; + } +} + +- (void)applicationDidResignActive:(NSNotification *)notification { + if (OS::get_singleton()->get_main_loop()) { + OS::get_singleton()->get_main_loop()->notification(MainLoop::NOTIFICATION_APPLICATION_FOCUS_OUT); + } +} + +- (void)applicationDidBecomeActive:(NSNotification *)notification { + if (OS::get_singleton()->get_main_loop()) { + OS::get_singleton()->get_main_loop()->notification(MainLoop::NOTIFICATION_APPLICATION_FOCUS_IN); + } +} + +- (void)globalMenuCallback:(id)sender { + DisplayServerOSX *ds = (DisplayServerOSX *)DisplayServer::get_singleton(); + if (ds) { + return ds->menu_callback(sender); + } +} + +- (NSMenu *)applicationDockMenu:(NSApplication *)sender { + DisplayServerOSX *ds = (DisplayServerOSX *)DisplayServer::get_singleton(); + if (ds) { + return ds->get_dock_menu(); + } else { + return nullptr; + } +} + +- (BOOL)application:(NSApplication *)sender openFile:(NSString *)filename { + // Note: may be called called before main loop init! + OS_OSX *os = (OS_OSX *)OS::get_singleton(); + if (os) { + os->set_open_with_filename(String::utf8([filename UTF8String])); + } + +#ifdef TOOLS_ENABLED + // Open new instance. + if (os && os->get_main_loop()) { + List<String> args; + args.push_back(os->get_open_with_filename()); + String exec = os->get_executable_path(); + os->create_process(exec, args); + } +#endif + return YES; +} + +- (NSApplicationTerminateReply)applicationShouldTerminate:(NSApplication *)sender { + DisplayServerOSX *ds = (DisplayServerOSX *)DisplayServer::get_singleton(); + if (ds) { + ds->send_window_event(ds->get_window(DisplayServerOSX::MAIN_WINDOW_ID), DisplayServerOSX::WINDOW_EVENT_CLOSE_REQUEST); + } + return NSTerminateCancel; +} + +- (void)showAbout:(id)sender { + OS_OSX *os = (OS_OSX *)OS::get_singleton(); + if (os && os->get_main_loop()) { + os->get_main_loop()->notification(MainLoop::NOTIFICATION_WM_ABOUT); + } +} + +@end diff --git a/platform/osx/godot_content_view.h b/platform/osx/godot_content_view.h new file mode 100644 index 0000000000..7942d716dc --- /dev/null +++ b/platform/osx/godot_content_view.h @@ -0,0 +1,65 @@ +/*************************************************************************/ +/* godot_content_view.h */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/*************************************************************************/ + +#ifndef GODOT_CONTENT_VIEW_H +#define GODOT_CONTENT_VIEW_H + +#include "servers/display_server.h" + +#import <AppKit/AppKit.h> +#import <Foundation/Foundation.h> + +#if defined(GLES3_ENABLED) +#import <AppKit/NSOpenGLView.h> +#define RootView NSOpenGLView +#else +#define RootView NSView +#endif + +#import <QuartzCore/CAMetalLayer.h> + +@interface GodotContentView : RootView <NSTextInputClient> { + DisplayServer::WindowID window_id; + NSTrackingArea *tracking_area; + NSMutableAttributedString *marked_text; + bool ime_input_event_in_progress; + bool mouse_down_control; + bool ignore_momentum_scroll; +} + +- (void)processScrollEvent:(NSEvent *)event button:(MouseButton)button factor:(double)factor; +- (void)processPanEvent:(NSEvent *)event dx:(double)dx dy:(double)dy; +- (void)processMouseEvent:(NSEvent *)event index:(MouseButton)index mask:(MouseButton)mask pressed:(bool)pressed; +- (void)setWindowID:(DisplayServer::WindowID)wid; +- (void)cancelComposition; + +@end + +#endif // GODOT_CONTENT_VIEW_H diff --git a/platform/osx/godot_content_view.mm b/platform/osx/godot_content_view.mm new file mode 100644 index 0000000000..4e831e1ccc --- /dev/null +++ b/platform/osx/godot_content_view.mm @@ -0,0 +1,760 @@ +/*************************************************************************/ +/* godot_content_view.mm */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/*************************************************************************/ + +#include "godot_content_view.h" + +#include "display_server_osx.h" +#include "key_mapping_osx.h" + +@implementation GodotContentView + +- (id)init { + self = [super init]; + window_id = DisplayServer::INVALID_WINDOW_ID; + tracking_area = nil; + ime_input_event_in_progress = false; + mouse_down_control = false; + ignore_momentum_scroll = false; + [self updateTrackingAreas]; + + if (@available(macOS 10.13, *)) { + [self registerForDraggedTypes:[NSArray arrayWithObject:NSPasteboardTypeFileURL]]; +#if !defined(__aarch64__) // Do not build deprectead 10.13 code on ARM. + } else { + [self registerForDraggedTypes:[NSArray arrayWithObject:NSFilenamesPboardType]]; +#endif + } + marked_text = [[NSMutableAttributedString alloc] init]; + return self; +} + +- (void)setWindowID:(DisplayServerOSX::WindowID)wid { + window_id = wid; +} + +// MARK: Backing Layer + +- (CALayer *)makeBackingLayer { + return [[CAMetalLayer class] layer]; +} + +- (void)updateLayer { + DisplayServerOSX *ds = (DisplayServerOSX *)DisplayServer::get_singleton(); + ds->window_update(window_id); + [super updateLayer]; +} + +- (BOOL)wantsUpdateLayer { + return YES; +} + +- (BOOL)isOpaque { + return YES; +} + +// MARK: IME + +- (BOOL)hasMarkedText { + return (marked_text.length > 0); +} + +- (NSRange)markedRange { + return NSMakeRange(0, marked_text.length); +} + +- (NSRange)selectedRange { + static const NSRange kEmptyRange = { NSNotFound, 0 }; + return kEmptyRange; +} + +- (void)setMarkedText:(id)aString selectedRange:(NSRange)selectedRange replacementRange:(NSRange)replacementRange { + if ([aString isKindOfClass:[NSAttributedString class]]) { + marked_text = [[NSMutableAttributedString alloc] initWithAttributedString:aString]; + } else { + marked_text = [[NSMutableAttributedString alloc] initWithString:aString]; + } + if (marked_text.length == 0) { + [self unmarkText]; + return; + } + + DisplayServerOSX *ds = (DisplayServerOSX *)DisplayServer::get_singleton(); + if (!ds || !ds->has_window(window_id)) { + return; + } + + DisplayServerOSX::WindowData &wd = ds->get_window(window_id); + if (wd.im_active) { + ime_input_event_in_progress = true; + ds->update_im_text(Point2i(selectedRange.location, selectedRange.length), String::utf8([[marked_text mutableString] UTF8String])); + } +} + +- (void)unmarkText { + ime_input_event_in_progress = false; + [[marked_text mutableString] setString:@""]; + + DisplayServerOSX *ds = (DisplayServerOSX *)DisplayServer::get_singleton(); + if (!ds || !ds->has_window(window_id)) { + return; + } + + DisplayServerOSX::WindowData &wd = ds->get_window(window_id); + if (wd.im_active) { + ds->update_im_text(Point2i(), String()); + } +} + +- (NSArray *)validAttributesForMarkedText { + return [NSArray array]; +} + +- (NSAttributedString *)attributedSubstringForProposedRange:(NSRange)aRange actualRange:(NSRangePointer)actualRange { + return nil; +} + +- (NSUInteger)characterIndexForPoint:(NSPoint)aPoint { + return 0; +} + +- (NSRect)firstRectForCharacterRange:(NSRange)aRange actualRange:(NSRangePointer)actualRange { + DisplayServerOSX *ds = (DisplayServerOSX *)DisplayServer::get_singleton(); + if (!ds || !ds->has_window(window_id)) { + return NSMakeRect(0, 0, 0, 0); + } + + DisplayServerOSX::WindowData &wd = ds->get_window(window_id); + const NSRect content_rect = [wd.window_view frame]; + const float scale = ds->screen_get_max_scale(); + NSRect point_in_window_rect = NSMakeRect(wd.im_position.x / scale, content_rect.size.height - (wd.im_position.y / scale) - 1, 0, 0); + NSPoint point_on_screen = [wd.window_object convertRectToScreen:point_in_window_rect].origin; + + return NSMakeRect(point_on_screen.x, point_on_screen.y, 0, 0); +} + +- (void)cancelComposition { + [self unmarkText]; + [[NSTextInputContext currentInputContext] discardMarkedText]; +} + +- (void)insertText:(id)aString { + [self insertText:aString replacementRange:NSMakeRange(0, 0)]; +} + +- (void)insertText:(id)aString replacementRange:(NSRange)replacementRange { + NSEvent *event = [NSApp currentEvent]; + + NSString *characters; + if ([aString isKindOfClass:[NSAttributedString class]]) { + characters = [aString string]; + } else { + characters = (NSString *)aString; + } + + NSCharacterSet *ctrl_chars = [NSCharacterSet controlCharacterSet]; + NSCharacterSet *wsnl_chars = [NSCharacterSet whitespaceAndNewlineCharacterSet]; + if ([characters rangeOfCharacterFromSet:ctrl_chars].length && [characters rangeOfCharacterFromSet:wsnl_chars].length == 0) { + [[NSTextInputContext currentInputContext] discardMarkedText]; + [self cancelComposition]; + return; + } + + DisplayServerOSX *ds = (DisplayServerOSX *)DisplayServer::get_singleton(); + if (!ds || !ds->has_window(window_id)) { + [self cancelComposition]; + return; + } + + Char16String text; + text.resize([characters length] + 1); + [characters getCharacters:(unichar *)text.ptrw() range:NSMakeRange(0, [characters length])]; + + String u32text; + u32text.parse_utf16(text.ptr(), text.length()); + + for (int i = 0; i < u32text.length(); i++) { + const char32_t codepoint = u32text[i]; + if ((codepoint & 0xFF00) == 0xF700) { + continue; + } + + DisplayServerOSX::KeyEvent ke; + + ke.window_id = window_id; + ke.osx_state = [event modifierFlags]; + ke.pressed = true; + ke.echo = false; + ke.raw = false; // IME input event. + ke.keycode = Key::NONE; + ke.physical_keycode = Key::NONE; + ke.unicode = codepoint; + + ds->push_to_key_event_buffer(ke); + } + [self cancelComposition]; +} + +// MARK: Drag and drop + +- (NSDragOperation)draggingEntered:(id<NSDraggingInfo>)sender { + return NSDragOperationCopy; +} + +- (NSDragOperation)draggingUpdated:(id<NSDraggingInfo>)sender { + return NSDragOperationCopy; +} + +- (BOOL)performDragOperation:(id<NSDraggingInfo>)sender { + DisplayServerOSX *ds = (DisplayServerOSX *)DisplayServer::get_singleton(); + if (!ds || !ds->has_window(window_id)) { + return NO; + } + + DisplayServerOSX::WindowData &wd = ds->get_window(window_id); + if (!wd.drop_files_callback.is_null()) { + Vector<String> files; + NSPasteboard *pboard = [sender draggingPasteboard]; + + if (@available(macOS 10.13, *)) { + NSArray *items = pboard.pasteboardItems; + for (NSPasteboardItem *item in items) { + NSString *url = [item stringForType:NSPasteboardTypeFileURL]; + NSString *file = [NSURL URLWithString:url].path; + files.push_back(String::utf8([file UTF8String])); + } +#if !defined(__aarch64__) // Do not build deprectead 10.13 code on ARM. + } else { + NSArray *filenames = [pboard propertyListForType:NSFilenamesPboardType]; + for (NSString *file in filenames) { + files.push_back(String::utf8([file UTF8String])); + } +#endif + } + + Variant v = files; + Variant *vp = &v; + Variant ret; + Callable::CallError ce; + wd.drop_files_callback.call((const Variant **)&vp, 1, ret, ce); + } + + return NO; +} + +// MARK: Focus + +- (BOOL)canBecomeKeyView { + DisplayServerOSX *ds = (DisplayServerOSX *)DisplayServer::get_singleton(); + if (!ds || !ds->has_window(window_id)) { + return YES; + } + + DisplayServerOSX::WindowData &wd = ds->get_window(window_id); + return !wd.no_focus; +} + +- (BOOL)acceptsFirstResponder { + return YES; +} + +// MARK: Mouse + +- (void)cursorUpdate:(NSEvent *)event { + DisplayServerOSX *ds = (DisplayServerOSX *)DisplayServer::get_singleton(); + if (!ds) { + return; + } + + ds->cursor_update_shape(); +} + +- (void)processMouseEvent:(NSEvent *)event index:(MouseButton)index mask:(MouseButton)mask pressed:(bool)pressed { + DisplayServerOSX *ds = (DisplayServerOSX *)DisplayServer::get_singleton(); + if (!ds || !ds->has_window(window_id)) { + return; + } + + DisplayServerOSX::WindowData &wd = ds->get_window(window_id); + MouseButton last_button_state = ds->mouse_get_button_state(); + + if (pressed) { + last_button_state |= mask; + } else { + last_button_state &= (MouseButton)~mask; + } + ds->mouse_set_button_state(last_button_state); + + Ref<InputEventMouseButton> mb; + mb.instantiate(); + mb->set_window_id(window_id); + ds->update_mouse_pos(wd, [event locationInWindow]); + ds->get_key_modifier_state([event modifierFlags], mb); + mb->set_button_index(index); + mb->set_pressed(pressed); + mb->set_position(wd.mouse_pos); + mb->set_global_position(wd.mouse_pos); + mb->set_button_mask(last_button_state); + if (index == MouseButton::LEFT && pressed) { + mb->set_double_click([event clickCount] == 2); + } + + Input::get_singleton()->parse_input_event(mb); +} + +- (void)mouseDown:(NSEvent *)event { + if (([event modifierFlags] & NSEventModifierFlagControl)) { + mouse_down_control = true; + [self processMouseEvent:event index:MouseButton::RIGHT mask:MouseButton::MASK_RIGHT pressed:true]; + } else { + mouse_down_control = false; + [self processMouseEvent:event index:MouseButton::LEFT mask:MouseButton::MASK_LEFT pressed:true]; + } +} + +- (void)mouseDragged:(NSEvent *)event { + [self mouseMoved:event]; +} + +- (void)mouseUp:(NSEvent *)event { + if (mouse_down_control) { + [self processMouseEvent:event index:MouseButton::RIGHT mask:MouseButton::MASK_RIGHT pressed:false]; + } else { + [self processMouseEvent:event index:MouseButton::LEFT mask:MouseButton::MASK_LEFT pressed:false]; + } +} + +- (void)mouseMoved:(NSEvent *)event { + DisplayServerOSX *ds = (DisplayServerOSX *)DisplayServer::get_singleton(); + if (!ds || !ds->has_window(window_id)) { + return; + } + + DisplayServerOSX::WindowData &wd = ds->get_window(window_id); + + NSPoint delta = NSMakePoint([event deltaX], [event deltaY]); + NSPoint mpos = [event locationInWindow]; + + if (ds->update_mouse_wrap(wd, delta, mpos, [event timestamp])) { + return; + } + + Ref<InputEventMouseMotion> mm; + mm.instantiate(); + + mm->set_window_id(window_id); + mm->set_button_mask(ds->mouse_get_button_state()); + ds->update_mouse_pos(wd, mpos); + mm->set_position(wd.mouse_pos); + mm->set_pressure([event pressure]); + if ([event subtype] == NSEventSubtypeTabletPoint) { + const NSPoint p = [event tilt]; + mm->set_tilt(Vector2(p.x, p.y)); + } + mm->set_global_position(wd.mouse_pos); + mm->set_velocity(Input::get_singleton()->get_last_mouse_velocity()); + const Vector2i relativeMotion = Vector2i(delta.x, delta.y) * ds->screen_get_max_scale(); + mm->set_relative(relativeMotion); + ds->get_key_modifier_state([event modifierFlags], mm); + + Input::get_singleton()->parse_input_event(mm); +} + +- (void)rightMouseDown:(NSEvent *)event { + [self processMouseEvent:event index:MouseButton::RIGHT mask:MouseButton::MASK_RIGHT pressed:true]; +} + +- (void)rightMouseDragged:(NSEvent *)event { + [self mouseMoved:event]; +} + +- (void)rightMouseUp:(NSEvent *)event { + [self processMouseEvent:event index:MouseButton::RIGHT mask:MouseButton::MASK_RIGHT pressed:false]; +} + +- (void)otherMouseDown:(NSEvent *)event { + if ((int)[event buttonNumber] == 2) { + [self processMouseEvent:event index:MouseButton::MIDDLE mask:MouseButton::MASK_MIDDLE pressed:true]; + } else if ((int)[event buttonNumber] == 3) { + [self processMouseEvent:event index:MouseButton::MB_XBUTTON1 mask:MouseButton::MASK_XBUTTON1 pressed:true]; + } else if ((int)[event buttonNumber] == 4) { + [self processMouseEvent:event index:MouseButton::MB_XBUTTON2 mask:MouseButton::MASK_XBUTTON2 pressed:true]; + } else { + return; + } +} + +- (void)otherMouseDragged:(NSEvent *)event { + [self mouseMoved:event]; +} + +- (void)otherMouseUp:(NSEvent *)event { + if ((int)[event buttonNumber] == 2) { + [self processMouseEvent:event index:MouseButton::MIDDLE mask:MouseButton::MASK_MIDDLE pressed:false]; + } else if ((int)[event buttonNumber] == 3) { + [self processMouseEvent:event index:MouseButton::MB_XBUTTON1 mask:MouseButton::MASK_XBUTTON1 pressed:false]; + } else if ((int)[event buttonNumber] == 4) { + [self processMouseEvent:event index:MouseButton::MB_XBUTTON2 mask:MouseButton::MASK_XBUTTON2 pressed:false]; + } else { + return; + } +} + +- (void)mouseExited:(NSEvent *)event { + DisplayServerOSX *ds = (DisplayServerOSX *)DisplayServer::get_singleton(); + if (!ds || !ds->has_window(window_id)) { + return; + } + + DisplayServerOSX::WindowData &wd = ds->get_window(window_id); + if (ds->mouse_get_mode() != DisplayServer::MOUSE_MODE_CAPTURED) { + ds->send_window_event(wd, DisplayServerOSX::WINDOW_EVENT_MOUSE_EXIT); + } +} + +- (void)mouseEntered:(NSEvent *)event { + DisplayServerOSX *ds = (DisplayServerOSX *)DisplayServer::get_singleton(); + if (!ds || !ds->has_window(window_id)) { + return; + } + + DisplayServerOSX::WindowData &wd = ds->get_window(window_id); + if (ds->mouse_get_mode() != DisplayServer::MOUSE_MODE_CAPTURED) { + ds->send_window_event(wd, DisplayServerOSX::WINDOW_EVENT_MOUSE_ENTER); + } + + ds->cursor_update_shape(); +} + +- (void)magnifyWithEvent:(NSEvent *)event { + DisplayServerOSX *ds = (DisplayServerOSX *)DisplayServer::get_singleton(); + if (!ds || !ds->has_window(window_id)) { + return; + } + + DisplayServerOSX::WindowData &wd = ds->get_window(window_id); + + Ref<InputEventMagnifyGesture> ev; + ev.instantiate(); + ev->set_window_id(window_id); + ds->get_key_modifier_state([event modifierFlags], ev); + ds->update_mouse_pos(wd, [event locationInWindow]); + ev->set_position(wd.mouse_pos); + ev->set_factor([event magnification] + 1.0); + + Input::get_singleton()->parse_input_event(ev); +} + +- (void)updateTrackingAreas { + if (tracking_area != nil) { + [self removeTrackingArea:tracking_area]; + } + + NSTrackingAreaOptions options = NSTrackingMouseEnteredAndExited | NSTrackingActiveInKeyWindow | NSTrackingCursorUpdate | NSTrackingInVisibleRect; + tracking_area = [[NSTrackingArea alloc] initWithRect:[self bounds] options:options owner:self userInfo:nil]; + + [self addTrackingArea:tracking_area]; + [super updateTrackingAreas]; +} + +// MARK: Keyboard + +- (void)keyDown:(NSEvent *)event { + DisplayServerOSX *ds = (DisplayServerOSX *)DisplayServer::get_singleton(); + if (!ds || !ds->has_window(window_id)) { + return; + } + + DisplayServerOSX::WindowData &wd = ds->get_window(window_id); + + ignore_momentum_scroll = true; + + // Ignore all input if IME input is in progress. + if (!ime_input_event_in_progress) { + NSString *characters = [event characters]; + NSUInteger length = [characters length]; + + if (!wd.im_active && length > 0 && keycode_has_unicode(KeyMappingOSX::remap_key([event keyCode], [event modifierFlags]))) { + // Fallback unicode character handler used if IME is not active. + Char16String text; + text.resize([characters length] + 1); + [characters getCharacters:(unichar *)text.ptrw() range:NSMakeRange(0, [characters length])]; + + String u32text; + u32text.parse_utf16(text.ptr(), text.length()); + + for (int i = 0; i < u32text.length(); i++) { + const char32_t codepoint = u32text[i]; + + DisplayServerOSX::KeyEvent ke; + + ke.window_id = window_id; + ke.osx_state = [event modifierFlags]; + ke.pressed = true; + ke.echo = [event isARepeat]; + ke.keycode = KeyMappingOSX::remap_key([event keyCode], [event modifierFlags]); + ke.physical_keycode = KeyMappingOSX::translate_key([event keyCode]); + ke.raw = true; + ke.unicode = codepoint; + + ds->push_to_key_event_buffer(ke); + } + } else { + DisplayServerOSX::KeyEvent ke; + + ke.window_id = window_id; + ke.osx_state = [event modifierFlags]; + ke.pressed = true; + ke.echo = [event isARepeat]; + ke.keycode = KeyMappingOSX::remap_key([event keyCode], [event modifierFlags]); + ke.physical_keycode = KeyMappingOSX::translate_key([event keyCode]); + ke.raw = false; + ke.unicode = 0; + + ds->push_to_key_event_buffer(ke); + } + } + + // Pass events to IME handler + if (wd.im_active) { + [self interpretKeyEvents:[NSArray arrayWithObject:event]]; + } +} + +- (void)flagsChanged:(NSEvent *)event { + DisplayServerOSX *ds = (DisplayServerOSX *)DisplayServer::get_singleton(); + if (!ds || !ds->has_window(window_id)) { + return; + } + ignore_momentum_scroll = true; + + // Ignore all input if IME input is in progress + if (!ime_input_event_in_progress) { + DisplayServerOSX::KeyEvent ke; + + ke.window_id = window_id; + ke.echo = false; + ke.raw = true; + + int key = [event keyCode]; + int mod = [event modifierFlags]; + + if (key == 0x36 || key == 0x37) { + if (mod & NSEventModifierFlagCommand) { + mod &= ~NSEventModifierFlagCommand; + ke.pressed = true; + } else { + ke.pressed = false; + } + } else if (key == 0x38 || key == 0x3c) { + if (mod & NSEventModifierFlagShift) { + mod &= ~NSEventModifierFlagShift; + ke.pressed = true; + } else { + ke.pressed = false; + } + } else if (key == 0x3a || key == 0x3d) { + if (mod & NSEventModifierFlagOption) { + mod &= ~NSEventModifierFlagOption; + ke.pressed = true; + } else { + ke.pressed = false; + } + } else if (key == 0x3b || key == 0x3e) { + if (mod & NSEventModifierFlagControl) { + mod &= ~NSEventModifierFlagControl; + ke.pressed = true; + } else { + ke.pressed = false; + } + } else { + return; + } + + ke.osx_state = mod; + ke.keycode = KeyMappingOSX::remap_key(key, mod); + ke.physical_keycode = KeyMappingOSX::translate_key(key); + ke.unicode = 0; + + ds->push_to_key_event_buffer(ke); + } +} + +- (void)keyUp:(NSEvent *)event { + DisplayServerOSX *ds = (DisplayServerOSX *)DisplayServer::get_singleton(); + if (!ds || !ds->has_window(window_id)) { + return; + } + + DisplayServerOSX::WindowData &wd = ds->get_window(window_id); + + // Ignore all input if IME input is in progress. + if (!ime_input_event_in_progress) { + NSString *characters = [event characters]; + NSUInteger length = [characters length]; + + // Fallback unicode character handler used if IME is not active. + if (!wd.im_active && length > 0 && keycode_has_unicode(KeyMappingOSX::remap_key([event keyCode], [event modifierFlags]))) { + Char16String text; + text.resize([characters length] + 1); + [characters getCharacters:(unichar *)text.ptrw() range:NSMakeRange(0, [characters length])]; + + String u32text; + u32text.parse_utf16(text.ptr(), text.length()); + + for (int i = 0; i < u32text.length(); i++) { + const char32_t codepoint = u32text[i]; + DisplayServerOSX::KeyEvent ke; + + ke.window_id = window_id; + ke.osx_state = [event modifierFlags]; + ke.pressed = false; + ke.echo = [event isARepeat]; + ke.keycode = KeyMappingOSX::remap_key([event keyCode], [event modifierFlags]); + ke.physical_keycode = KeyMappingOSX::translate_key([event keyCode]); + ke.raw = true; + ke.unicode = codepoint; + + ds->push_to_key_event_buffer(ke); + } + } else { + DisplayServerOSX::KeyEvent ke; + + ke.window_id = window_id; + ke.osx_state = [event modifierFlags]; + ke.pressed = false; + ke.echo = [event isARepeat]; + ke.keycode = KeyMappingOSX::remap_key([event keyCode], [event modifierFlags]); + ke.physical_keycode = KeyMappingOSX::translate_key([event keyCode]); + ke.raw = true; + ke.unicode = 0; + + ds->push_to_key_event_buffer(ke); + } + } +} + +// MARK: Scroll and pan + +- (void)processScrollEvent:(NSEvent *)event button:(MouseButton)button factor:(double)factor { + DisplayServerOSX *ds = (DisplayServerOSX *)DisplayServer::get_singleton(); + if (!ds || !ds->has_window(window_id)) { + return; + } + + DisplayServerOSX::WindowData &wd = ds->get_window(window_id); + MouseButton mask = mouse_button_to_mask(button); + + Ref<InputEventMouseButton> sc; + sc.instantiate(); + + sc->set_window_id(window_id); + ds->get_key_modifier_state([event modifierFlags], sc); + sc->set_button_index(button); + sc->set_factor(factor); + sc->set_pressed(true); + sc->set_position(wd.mouse_pos); + sc->set_global_position(wd.mouse_pos); + MouseButton last_button_state = ds->mouse_get_button_state() | (MouseButton)mask; + sc->set_button_mask(last_button_state); + ds->mouse_set_button_state(last_button_state); + + Input::get_singleton()->parse_input_event(sc); + + sc.instantiate(); + sc->set_window_id(window_id); + sc->set_button_index(button); + sc->set_factor(factor); + sc->set_pressed(false); + sc->set_position(wd.mouse_pos); + sc->set_global_position(wd.mouse_pos); + last_button_state &= (MouseButton)~mask; + sc->set_button_mask(last_button_state); + ds->mouse_set_button_state(last_button_state); + + Input::get_singleton()->parse_input_event(sc); +} + +- (void)processPanEvent:(NSEvent *)event dx:(double)dx dy:(double)dy { + DisplayServerOSX *ds = (DisplayServerOSX *)DisplayServer::get_singleton(); + if (!ds || !ds->has_window(window_id)) { + return; + } + + DisplayServerOSX::WindowData &wd = ds->get_window(window_id); + + Ref<InputEventPanGesture> pg; + pg.instantiate(); + + pg->set_window_id(window_id); + ds->get_key_modifier_state([event modifierFlags], pg); + pg->set_position(wd.mouse_pos); + pg->set_delta(Vector2(-dx, -dy)); + + Input::get_singleton()->parse_input_event(pg); +} + +- (void)scrollWheel:(NSEvent *)event { + DisplayServerOSX *ds = (DisplayServerOSX *)DisplayServer::get_singleton(); + if (!ds || !ds->has_window(window_id)) { + return; + } + + DisplayServerOSX::WindowData &wd = ds->get_window(window_id); + ds->update_mouse_pos(wd, [event locationInWindow]); + + double delta_x = [event scrollingDeltaX]; + double delta_y = [event scrollingDeltaY]; + + if ([event hasPreciseScrollingDeltas]) { + delta_x *= 0.03; + delta_y *= 0.03; + } + + if ([event momentumPhase] != NSEventPhaseNone) { + if (ignore_momentum_scroll) { + return; + } + } else { + ignore_momentum_scroll = false; + } + + if ([event phase] != NSEventPhaseNone || [event momentumPhase] != NSEventPhaseNone) { + [self processPanEvent:event dx:delta_x dy:delta_y]; + } else { + if (fabs(delta_x)) { + [self processScrollEvent:event button:(0 > delta_x ? MouseButton::WHEEL_RIGHT : MouseButton::WHEEL_LEFT) factor:fabs(delta_x * 0.3)]; + } + if (fabs(delta_y)) { + [self processScrollEvent:event button:(0 < delta_y ? MouseButton::WHEEL_UP : MouseButton::WHEEL_DOWN) factor:fabs(delta_y * 0.3)]; + } + } +} + +@end diff --git a/platform/osx/godot_main_osx.mm b/platform/osx/godot_main_osx.mm index 64a93f7292..7fabfaa1b7 100644 --- a/platform/osx/godot_main_osx.mm +++ b/platform/osx/godot_main_osx.mm @@ -37,7 +37,7 @@ int main(int argc, char **argv) { #if defined(VULKAN_ENABLED) - // MoltenVK - enable full component swizzling support + // MoltenVK - enable full component swizzling support. setenv("MVK_CONFIG_FULL_IMAGE_VIEW_SWIZZLE", "1", 1); #endif @@ -45,13 +45,14 @@ int main(int argc, char **argv) { const char *dbg_arg = "-NSDocumentRevisionsDebugMode"; printf("arguments\n"); for (int i = 0; i < argc; i++) { - if (strcmp(dbg_arg, argv[i]) == 0) + if (strcmp(dbg_arg, argv[i]) == 0) { first_arg = i + 2; + } printf("%i: %s\n", i, argv[i]); }; #ifdef DEBUG_ENABLED - // lets report the path we made current after all that + // Lets report the path we made current after all that. char cwd[4096]; getcwd(cwd, 4096); printf("Current path: %s\n", cwd); @@ -60,23 +61,25 @@ int main(int argc, char **argv) { OS_OSX os; Error err; - // We must override main when testing is enabled + // We must override main when testing is enabled. TEST_MAIN_OVERRIDE - if (os.open_with_filename != "") { - char *argv_c = (char *)malloc(os.open_with_filename.utf8().size()); - memcpy(argv_c, os.open_with_filename.utf8().get_data(), os.open_with_filename.utf8().size()); + if (os.get_open_with_filename() != "") { + char *argv_c = (char *)malloc(os.get_open_with_filename().utf8().size()); + memcpy(argv_c, os.get_open_with_filename().utf8().get_data(), os.get_open_with_filename().utf8().size()); err = Main::setup(argv[0], 1, &argv_c); free(argv_c); } else { err = Main::setup(argv[0], argc - first_arg, &argv[first_arg]); } - if (err != OK) + if (err != OK) { return 255; + } - if (Main::start()) - os.run(); // it is actually the OS that decides how to run + if (Main::start()) { + os.run(); // It is actually the OS that decides how to run. + } Main::cleanup(); diff --git a/platform/osx/godot_menu_item.h b/platform/osx/godot_menu_item.h new file mode 100644 index 0000000000..50c4709c18 --- /dev/null +++ b/platform/osx/godot_menu_item.h @@ -0,0 +1,52 @@ +/*************************************************************************/ +/* godot_menu_item.h */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/*************************************************************************/ + +#ifndef GODOT_MENU_ITEM_H +#define GODOT_MENU_ITEM_H + +#include "servers/display_server.h" + +#import <AppKit/AppKit.h> +#import <Foundation/Foundation.h> + +@interface GodotMenuItem : NSObject { +@public + Callable callback; + Variant meta; + int id; + bool checkable; +} + +@end + +@implementation GodotMenuItem +@end + +#endif // GODOT_MENU_ITEM_H diff --git a/platform/osx/godot_window.h b/platform/osx/godot_window.h new file mode 100644 index 0000000000..16ff101142 --- /dev/null +++ b/platform/osx/godot_window.h @@ -0,0 +1,47 @@ +/*************************************************************************/ +/* godot_window.h */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/*************************************************************************/ + +#ifndef GODOT_WINDOW_H +#define GODOT_WINDOW_H + +#include "servers/display_server.h" + +#import <AppKit/AppKit.h> +#import <Foundation/Foundation.h> + +@interface GodotWindow : NSWindow { + DisplayServer::WindowID window_id; +} + +- (void)setWindowID:(DisplayServer::WindowID)wid; + +@end + +#endif //GODOT_WINDOW_H diff --git a/platform/osx/godot_window.mm b/platform/osx/godot_window.mm new file mode 100644 index 0000000000..e392cfb384 --- /dev/null +++ b/platform/osx/godot_window.mm @@ -0,0 +1,69 @@ +/*************************************************************************/ +/* godot_window.mm */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/*************************************************************************/ + +#include "godot_window.h" + +#include "display_server_osx.h" + +@implementation GodotWindow + +- (id)init { + self = [super init]; + window_id = DisplayServer::INVALID_WINDOW_ID; + return self; +} + +- (void)setWindowID:(DisplayServerOSX::WindowID)wid { + window_id = wid; +} + +- (BOOL)canBecomeKeyWindow { + // Required for NSBorderlessWindowMask windows. + DisplayServerOSX *ds = (DisplayServerOSX *)DisplayServer::get_singleton(); + if (!ds || !ds->has_window(window_id)) { + return YES; + } + + DisplayServerOSX::WindowData &wd = ds->get_window(window_id); + return !wd.no_focus; +} + +- (BOOL)canBecomeMainWindow { + // Required for NSBorderlessWindowMask windows. + DisplayServerOSX *ds = (DisplayServerOSX *)DisplayServer::get_singleton(); + if (!ds || !ds->has_window(window_id)) { + return YES; + } + + DisplayServerOSX::WindowData &wd = ds->get_window(window_id); + return !wd.no_focus; +} + +@end diff --git a/platform/osx/godot_window_delegate.h b/platform/osx/godot_window_delegate.h new file mode 100644 index 0000000000..8a1f681fcd --- /dev/null +++ b/platform/osx/godot_window_delegate.h @@ -0,0 +1,47 @@ +/*************************************************************************/ +/* godot_window_delegate.h */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/*************************************************************************/ + +#ifndef GODOT_WINDOW_DELEGATE_H +#define GODOT_WINDOW_DELEGATE_H + +#include "servers/display_server.h" + +#import <AppKit/AppKit.h> +#import <Foundation/Foundation.h> + +@interface GodotWindowDelegate : NSObject <NSWindowDelegate> { + DisplayServer::WindowID window_id; +} + +- (void)setWindowID:(DisplayServer::WindowID)wid; + +@end + +#endif //GODOT_WINDOW_DELEGATE_H diff --git a/platform/osx/godot_window_delegate.mm b/platform/osx/godot_window_delegate.mm new file mode 100644 index 0000000000..1742be987d --- /dev/null +++ b/platform/osx/godot_window_delegate.mm @@ -0,0 +1,254 @@ +/*************************************************************************/ +/* godot_window_delegate.mm */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/*************************************************************************/ + +#include "godot_window_delegate.h" + +#include "display_server_osx.h" + +@implementation GodotWindowDelegate + +- (void)setWindowID:(DisplayServer::WindowID)wid { + window_id = wid; +} + +- (BOOL)windowShouldClose:(id)sender { + DisplayServerOSX *ds = (DisplayServerOSX *)DisplayServer::get_singleton(); + if (!ds || !ds->has_window(window_id)) { + return YES; + } + + ds->send_window_event(ds->get_window(window_id), DisplayServerOSX::WINDOW_EVENT_CLOSE_REQUEST); + return NO; +} + +- (void)windowWillClose:(NSNotification *)notification { + DisplayServerOSX *ds = (DisplayServerOSX *)DisplayServer::get_singleton(); + if (!ds || !ds->has_window(window_id)) { + return; + } + + DisplayServerOSX::WindowData &wd = ds->get_window(window_id); + while (wd.transient_children.size()) { + ds->window_set_transient(wd.transient_children.front()->get(), DisplayServerOSX::INVALID_WINDOW_ID); + } + + if (wd.transient_parent != DisplayServerOSX::INVALID_WINDOW_ID) { + ds->window_set_transient(window_id, DisplayServerOSX::INVALID_WINDOW_ID); + } + + ds->window_destroy(window_id); +} + +- (void)windowDidEnterFullScreen:(NSNotification *)notification { + DisplayServerOSX *ds = (DisplayServerOSX *)DisplayServer::get_singleton(); + if (!ds || !ds->has_window(window_id)) { + return; + } + + DisplayServerOSX::WindowData &wd = ds->get_window(window_id); + wd.fullscreen = true; + // Reset window size limits. + [wd.window_object setContentMinSize:NSMakeSize(0, 0)]; + [wd.window_object setContentMaxSize:NSMakeSize(FLT_MAX, FLT_MAX)]; + + // Force window resize event. + [self windowDidResize:notification]; +} + +- (void)windowDidExitFullScreen:(NSNotification *)notification { + DisplayServerOSX *ds = (DisplayServerOSX *)DisplayServer::get_singleton(); + if (!ds || !ds->has_window(window_id)) { + return; + } + + DisplayServerOSX::WindowData &wd = ds->get_window(window_id); + wd.fullscreen = false; + + // Set window size limits. + const float scale = ds->screen_get_max_scale(); + if (wd.min_size != Size2i()) { + Size2i size = wd.min_size / scale; + [wd.window_object setContentMinSize:NSMakeSize(size.x, size.y)]; + } + if (wd.max_size != Size2i()) { + Size2i size = wd.max_size / scale; + [wd.window_object setContentMaxSize:NSMakeSize(size.x, size.y)]; + } + + // Restore resizability state. + if (wd.resize_disabled) { + [wd.window_object setStyleMask:[wd.window_object styleMask] & ~NSWindowStyleMaskResizable]; + } + + // Restore on-top state. + if (wd.on_top) { + [wd.window_object setLevel:NSFloatingWindowLevel]; + } + + // Force window resize event. + [self windowDidResize:notification]; +} + +- (void)windowDidChangeBackingProperties:(NSNotification *)notification { + DisplayServerOSX *ds = (DisplayServerOSX *)DisplayServer::get_singleton(); + if (!ds || !ds->has_window(window_id)) { + return; + } + + DisplayServerOSX::WindowData &wd = ds->get_window(window_id); + + CGFloat new_scale_factor = [wd.window_object backingScaleFactor]; + CGFloat old_scale_factor = [[[notification userInfo] objectForKey:@"NSBackingPropertyOldScaleFactorKey"] doubleValue]; + + if (new_scale_factor != old_scale_factor) { + // Set new display scale and window size. + const float scale = ds->screen_get_max_scale(); + const NSRect content_rect = [wd.window_view frame]; + + wd.size.width = content_rect.size.width * scale; + wd.size.height = content_rect.size.height * scale; + + ds->send_window_event(wd, DisplayServerOSX::WINDOW_EVENT_DPI_CHANGE); + + CALayer *layer = [wd.window_view layer]; + if (layer) { + layer.contentsScale = scale; + } + + //Force window resize event + [self windowDidResize:notification]; + } +} + +- (void)windowDidResize:(NSNotification *)notification { + DisplayServerOSX *ds = (DisplayServerOSX *)DisplayServer::get_singleton(); + if (!ds || !ds->has_window(window_id)) { + return; + } + + DisplayServerOSX::WindowData &wd = ds->get_window(window_id); + const NSRect content_rect = [wd.window_view frame]; + const float scale = ds->screen_get_max_scale(); + wd.size.width = content_rect.size.width * scale; + wd.size.height = content_rect.size.height * scale; + + CALayer *layer = [wd.window_view layer]; + if (layer) { + layer.contentsScale = scale; + } + + ds->window_resize(window_id, wd.size.width, wd.size.height); + + if (!wd.rect_changed_callback.is_null()) { + Variant size = Rect2i(ds->window_get_position(window_id), ds->window_get_size(window_id)); + Variant *sizep = &size; + Variant ret; + Callable::CallError ce; + wd.rect_changed_callback.call((const Variant **)&sizep, 1, ret, ce); + } +} + +- (void)windowDidMove:(NSNotification *)notification { + DisplayServerOSX *ds = (DisplayServerOSX *)DisplayServer::get_singleton(); + if (!ds || !ds->has_window(window_id)) { + return; + } + + DisplayServerOSX::WindowData &wd = ds->get_window(window_id); + ds->release_pressed_events(); + + if (!wd.rect_changed_callback.is_null()) { + Variant size = Rect2i(ds->window_get_position(window_id), ds->window_get_size(window_id)); + Variant *sizep = &size; + Variant ret; + Callable::CallError ce; + wd.rect_changed_callback.call((const Variant **)&sizep, 1, ret, ce); + } +} + +- (void)windowDidBecomeKey:(NSNotification *)notification { + DisplayServerOSX *ds = (DisplayServerOSX *)DisplayServer::get_singleton(); + if (!ds || !ds->has_window(window_id)) { + return; + } + + DisplayServerOSX::WindowData &wd = ds->get_window(window_id); + + if (ds->mouse_get_mode() == DisplayServer::MOUSE_MODE_CAPTURED) { + const NSRect content_rect = [wd.window_view frame]; + NSRect point_in_window_rect = NSMakeRect(content_rect.size.width / 2, content_rect.size.height / 2, 0, 0); + NSPoint point_on_screen = [[wd.window_view window] convertRectToScreen:point_in_window_rect].origin; + CGPoint mouse_warp_pos = { point_on_screen.x, CGDisplayBounds(CGMainDisplayID()).size.height - point_on_screen.y }; + CGWarpMouseCursorPosition(mouse_warp_pos); + } else { + ds->update_mouse_pos(wd, [wd.window_object mouseLocationOutsideOfEventStream]); + } + + ds->set_last_focused_window(window_id); + ds->send_window_event(wd, DisplayServerOSX::WINDOW_EVENT_FOCUS_IN); +} + +- (void)windowDidResignKey:(NSNotification *)notification { + DisplayServerOSX *ds = (DisplayServerOSX *)DisplayServer::get_singleton(); + if (!ds || !ds->has_window(window_id)) { + return; + } + + DisplayServerOSX::WindowData &wd = ds->get_window(window_id); + + ds->release_pressed_events(); + ds->send_window_event(wd, DisplayServerOSX::WINDOW_EVENT_FOCUS_OUT); +} + +- (void)windowDidMiniaturize:(NSNotification *)notification { + DisplayServerOSX *ds = (DisplayServerOSX *)DisplayServer::get_singleton(); + if (!ds || !ds->has_window(window_id)) { + return; + } + + DisplayServerOSX::WindowData &wd = ds->get_window(window_id); + + ds->release_pressed_events(); + ds->send_window_event(wd, DisplayServerOSX::WINDOW_EVENT_FOCUS_OUT); +} + +- (void)windowDidDeminiaturize:(NSNotification *)notification { + DisplayServerOSX *ds = (DisplayServerOSX *)DisplayServer::get_singleton(); + if (!ds || !ds->has_window(window_id)) { + return; + } + + DisplayServerOSX::WindowData &wd = ds->get_window(window_id); + + ds->set_last_focused_window(window_id); + ds->send_window_event(wd, DisplayServerOSX::WINDOW_EVENT_FOCUS_IN); +} + +@end diff --git a/platform/osx/joypad_osx.cpp b/platform/osx/joypad_osx.cpp index c2356f12cd..d518206f04 100644 --- a/platform/osx/joypad_osx.cpp +++ b/platform/osx/joypad_osx.cpp @@ -80,7 +80,7 @@ int joypad::get_hid_element_state(rec_element *p_element) const { if (IOHIDDeviceGetValue(device_ref, p_element->ref, &valueRef) == kIOReturnSuccess) { value = (SInt32)IOHIDValueGetIntegerValue(valueRef); - /* record min and max for auto calibration */ + // Record min and max for auto calibration. if (value < p_element->min) { p_element->min = value; } @@ -179,7 +179,7 @@ void joypad::add_hid_element(IOHIDElementRef p_element) { break; } - if (list) { /* add to list */ + if (list) { // Add to list. rec_element element; element.ref = p_element; @@ -280,7 +280,7 @@ static String _hex_str(uint8_t p_byte) { bool JoypadOSX::configure_joypad(IOHIDDeviceRef p_device_ref, joypad *p_joy) { p_joy->device_ref = p_device_ref; - /* get device name */ + // Get device name. String name; char c_name[256]; CFTypeRef refCF = IOHIDDeviceGetProperty(p_device_ref, CFSTR(kIOHIDProductKey)); @@ -319,7 +319,7 @@ bool JoypadOSX::configure_joypad(IOHIDDeviceRef p_device_ref, joypad *p_joy) { sprintf(uid, "%08x%08x%08x%08x", OSSwapHostToBigInt32(3), OSSwapHostToBigInt32(vendor), OSSwapHostToBigInt32(product_id), OSSwapHostToBigInt32(version)); input->joy_connection_changed(id, true, name, uid); } else { - //bluetooth device + // Bluetooth device. String guid = "05000000"; for (int i = 0; i < 12; i++) { if (i < name.size()) @@ -445,7 +445,7 @@ static HatMask process_hat_value(int p_min, int p_max, int p_value, bool p_offse void JoypadOSX::poll_joypads() const { while (CFRunLoopRunInMode(GODOT_JOY_LOOP_RUN_MODE, 0, TRUE) == kCFRunLoopRunHandledSource) { - /* no-op. Pending callbacks will fire. */ + // No-op. Pending callbacks will fire. } } @@ -568,7 +568,7 @@ void JoypadOSX::config_hid_manager(CFArrayRef p_matching_array) const { IOHIDManagerScheduleWithRunLoop(hid_manager, runloop, GODOT_JOY_LOOP_RUN_MODE); while (CFRunLoopRunInMode(GODOT_JOY_LOOP_RUN_MODE, 0, TRUE) == kCFRunLoopRunHandledSource) { - /* no-op. Callback fires once per existing device. */ + // No-op. Callback fires once per existing device. } } diff --git a/platform/osx/joypad_osx.h b/platform/osx/joypad_osx.h index 8ea1033a77..4ca7fb1698 100644 --- a/platform/osx/joypad_osx.h +++ b/platform/osx/joypad_osx.h @@ -66,7 +66,7 @@ struct joypad { int id = 0; bool offset_hat = false; - io_service_t ffservice = 0; /* Interface for force feedback, 0 = no ff */ + io_service_t ffservice = 0; // Interface for force feedback, 0 = no ff. FFCONSTANTFORCE ff_constant_force; FFDeviceObjectReference ff_device = nullptr; FFEffectObjectReference ff_object = nullptr; diff --git a/platform/osx/key_mapping_osx.h b/platform/osx/key_mapping_osx.h new file mode 100644 index 0000000000..252cc907bb --- /dev/null +++ b/platform/osx/key_mapping_osx.h @@ -0,0 +1,52 @@ +/*************************************************************************/ +/* key_mapping_osx.h */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/*************************************************************************/ + +#ifndef KEY_MAPPING_OSX_H +#define KEY_MAPPING_OSX_H + +#include "core/os/keyboard.h" + +class KeyMappingOSX { + KeyMappingOSX() {} + + static bool is_numpad_key(unsigned int key); + +public: + // Mappings input. + static Key translate_key(unsigned int key); + static unsigned int unmap_key(Key key); + static Key remap_key(unsigned int key, unsigned int state); + + // Mapping for menu shortcuts. + static String keycode_get_native_string(Key p_keycode); + static unsigned int keycode_get_native_mask(Key p_keycode); +}; + +#endif // KEY_MAPPING_OSX_H diff --git a/platform/osx/key_mapping_osx.mm b/platform/osx/key_mapping_osx.mm new file mode 100644 index 0000000000..fde9206824 --- /dev/null +++ b/platform/osx/key_mapping_osx.mm @@ -0,0 +1,477 @@ +/*************************************************************************/ +/* key_mapping_osx.mm */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/*************************************************************************/ + +#include "key_mapping_osx.h" + +#include <Carbon/Carbon.h> +#include <Cocoa/Cocoa.h> + +bool KeyMappingOSX::is_numpad_key(unsigned int key) { + static const unsigned int table[] = { + 0x41, /* kVK_ANSI_KeypadDecimal */ + 0x43, /* kVK_ANSI_KeypadMultiply */ + 0x45, /* kVK_ANSI_KeypadPlus */ + 0x47, /* kVK_ANSI_KeypadClear */ + 0x4b, /* kVK_ANSI_KeypadDivide */ + 0x4c, /* kVK_ANSI_KeypadEnter */ + 0x4e, /* kVK_ANSI_KeypadMinus */ + 0x51, /* kVK_ANSI_KeypadEquals */ + 0x52, /* kVK_ANSI_Keypad0 */ + 0x53, /* kVK_ANSI_Keypad1 */ + 0x54, /* kVK_ANSI_Keypad2 */ + 0x55, /* kVK_ANSI_Keypad3 */ + 0x56, /* kVK_ANSI_Keypad4 */ + 0x57, /* kVK_ANSI_Keypad5 */ + 0x58, /* kVK_ANSI_Keypad6 */ + 0x59, /* kVK_ANSI_Keypad7 */ + 0x5b, /* kVK_ANSI_Keypad8 */ + 0x5c, /* kVK_ANSI_Keypad9 */ + 0x5f, /* kVK_JIS_KeypadComma */ + 0x00 + }; + for (int i = 0; table[i] != 0; i++) { + if (key == table[i]) { + return true; + } + } + return false; +} + +// Keyboard symbol translation table. +static const Key _osx_to_godot_table[128] = { + /* 00 */ Key::A, + /* 01 */ Key::S, + /* 02 */ Key::D, + /* 03 */ Key::F, + /* 04 */ Key::H, + /* 05 */ Key::G, + /* 06 */ Key::Z, + /* 07 */ Key::X, + /* 08 */ Key::C, + /* 09 */ Key::V, + /* 0a */ Key::SECTION, /* ISO Section */ + /* 0b */ Key::B, + /* 0c */ Key::Q, + /* 0d */ Key::W, + /* 0e */ Key::E, + /* 0f */ Key::R, + /* 10 */ Key::Y, + /* 11 */ Key::T, + /* 12 */ Key::KEY_1, + /* 13 */ Key::KEY_2, + /* 14 */ Key::KEY_3, + /* 15 */ Key::KEY_4, + /* 16 */ Key::KEY_6, + /* 17 */ Key::KEY_5, + /* 18 */ Key::EQUAL, + /* 19 */ Key::KEY_9, + /* 1a */ Key::KEY_7, + /* 1b */ Key::MINUS, + /* 1c */ Key::KEY_8, + /* 1d */ Key::KEY_0, + /* 1e */ Key::BRACERIGHT, + /* 1f */ Key::O, + /* 20 */ Key::U, + /* 21 */ Key::BRACELEFT, + /* 22 */ Key::I, + /* 23 */ Key::P, + /* 24 */ Key::ENTER, + /* 25 */ Key::L, + /* 26 */ Key::J, + /* 27 */ Key::APOSTROPHE, + /* 28 */ Key::K, + /* 29 */ Key::SEMICOLON, + /* 2a */ Key::BACKSLASH, + /* 2b */ Key::COMMA, + /* 2c */ Key::SLASH, + /* 2d */ Key::N, + /* 2e */ Key::M, + /* 2f */ Key::PERIOD, + /* 30 */ Key::TAB, + /* 31 */ Key::SPACE, + /* 32 */ Key::QUOTELEFT, + /* 33 */ Key::BACKSPACE, + /* 34 */ Key::UNKNOWN, + /* 35 */ Key::ESCAPE, + /* 36 */ Key::META, + /* 37 */ Key::META, + /* 38 */ Key::SHIFT, + /* 39 */ Key::CAPSLOCK, + /* 3a */ Key::ALT, + /* 3b */ Key::CTRL, + /* 3c */ Key::SHIFT, + /* 3d */ Key::ALT, + /* 3e */ Key::CTRL, + /* 3f */ Key::UNKNOWN, /* Function */ + /* 40 */ Key::UNKNOWN, /* F17 */ + /* 41 */ Key::KP_PERIOD, + /* 42 */ Key::UNKNOWN, + /* 43 */ Key::KP_MULTIPLY, + /* 44 */ Key::UNKNOWN, + /* 45 */ Key::KP_ADD, + /* 46 */ Key::UNKNOWN, + /* 47 */ Key::NUMLOCK, /* Really KeypadClear... */ + /* 48 */ Key::VOLUMEUP, /* VolumeUp */ + /* 49 */ Key::VOLUMEDOWN, /* VolumeDown */ + /* 4a */ Key::VOLUMEMUTE, /* Mute */ + /* 4b */ Key::KP_DIVIDE, + /* 4c */ Key::KP_ENTER, + /* 4d */ Key::UNKNOWN, + /* 4e */ Key::KP_SUBTRACT, + /* 4f */ Key::UNKNOWN, /* F18 */ + /* 50 */ Key::UNKNOWN, /* F19 */ + /* 51 */ Key::EQUAL, /* KeypadEqual */ + /* 52 */ Key::KP_0, + /* 53 */ Key::KP_1, + /* 54 */ Key::KP_2, + /* 55 */ Key::KP_3, + /* 56 */ Key::KP_4, + /* 57 */ Key::KP_5, + /* 58 */ Key::KP_6, + /* 59 */ Key::KP_7, + /* 5a */ Key::UNKNOWN, /* F20 */ + /* 5b */ Key::KP_8, + /* 5c */ Key::KP_9, + /* 5d */ Key::YEN, /* JIS Yen */ + /* 5e */ Key::UNDERSCORE, /* JIS Underscore */ + /* 5f */ Key::COMMA, /* JIS KeypadComma */ + /* 60 */ Key::F5, + /* 61 */ Key::F6, + /* 62 */ Key::F7, + /* 63 */ Key::F3, + /* 64 */ Key::F8, + /* 65 */ Key::F9, + /* 66 */ Key::UNKNOWN, /* JIS Eisu */ + /* 67 */ Key::F11, + /* 68 */ Key::UNKNOWN, /* JIS Kana */ + /* 69 */ Key::F13, + /* 6a */ Key::F16, + /* 6b */ Key::F14, + /* 6c */ Key::UNKNOWN, + /* 6d */ Key::F10, + /* 6e */ Key::MENU, + /* 6f */ Key::F12, + /* 70 */ Key::UNKNOWN, + /* 71 */ Key::F15, + /* 72 */ Key::INSERT, /* Really Help... */ + /* 73 */ Key::HOME, + /* 74 */ Key::PAGEUP, + /* 75 */ Key::KEY_DELETE, + /* 76 */ Key::F4, + /* 77 */ Key::END, + /* 78 */ Key::F2, + /* 79 */ Key::PAGEDOWN, + /* 7a */ Key::F1, + /* 7b */ Key::LEFT, + /* 7c */ Key::RIGHT, + /* 7d */ Key::DOWN, + /* 7e */ Key::UP, + /* 7f */ Key::UNKNOWN, +}; + +// Translates a OS X keycode to a Godot keycode. +Key KeyMappingOSX::translate_key(unsigned int key) { + if (key >= 128) { + return Key::UNKNOWN; + } + + return _osx_to_godot_table[key]; +} + +// Translates a Godot keycode back to a OSX keycode. +unsigned int KeyMappingOSX::unmap_key(Key key) { + for (int i = 0; i <= 126; i++) { + if (_osx_to_godot_table[i] == key) { + return i; + } + } + return 127; +} + +struct _KeyCodeMap { + UniChar kchar; + Key kcode; +}; + +static const _KeyCodeMap _keycodes[55] = { + { '`', Key::QUOTELEFT }, + { '~', Key::ASCIITILDE }, + { '0', Key::KEY_0 }, + { '1', Key::KEY_1 }, + { '2', Key::KEY_2 }, + { '3', Key::KEY_3 }, + { '4', Key::KEY_4 }, + { '5', Key::KEY_5 }, + { '6', Key::KEY_6 }, + { '7', Key::KEY_7 }, + { '8', Key::KEY_8 }, + { '9', Key::KEY_9 }, + { '-', Key::MINUS }, + { '_', Key::UNDERSCORE }, + { '=', Key::EQUAL }, + { '+', Key::PLUS }, + { 'q', Key::Q }, + { 'w', Key::W }, + { 'e', Key::E }, + { 'r', Key::R }, + { 't', Key::T }, + { 'y', Key::Y }, + { 'u', Key::U }, + { 'i', Key::I }, + { 'o', Key::O }, + { 'p', Key::P }, + { '[', Key::BRACELEFT }, + { ']', Key::BRACERIGHT }, + { '{', Key::BRACELEFT }, + { '}', Key::BRACERIGHT }, + { 'a', Key::A }, + { 's', Key::S }, + { 'd', Key::D }, + { 'f', Key::F }, + { 'g', Key::G }, + { 'h', Key::H }, + { 'j', Key::J }, + { 'k', Key::K }, + { 'l', Key::L }, + { ';', Key::SEMICOLON }, + { ':', Key::COLON }, + { '\'', Key::APOSTROPHE }, + { '\"', Key::QUOTEDBL }, + { '\\', Key::BACKSLASH }, + { '#', Key::NUMBERSIGN }, + { 'z', Key::Z }, + { 'x', Key::X }, + { 'c', Key::C }, + { 'v', Key::V }, + { 'b', Key::B }, + { 'n', Key::N }, + { 'm', Key::M }, + { ',', Key::COMMA }, + { '.', Key::PERIOD }, + { '/', Key::SLASH } +}; + +// Remap key according to current keyboard layout. +Key KeyMappingOSX::remap_key(unsigned int key, unsigned int state) { + if (is_numpad_key(key)) { + return translate_key(key); + } + + TISInputSourceRef current_keyboard = TISCopyCurrentKeyboardInputSource(); + if (!current_keyboard) { + return translate_key(key); + } + + CFDataRef layout_data = (CFDataRef)TISGetInputSourceProperty(current_keyboard, kTISPropertyUnicodeKeyLayoutData); + if (!layout_data) { + return translate_key(key); + } + + const UCKeyboardLayout *keyboard_layout = (const UCKeyboardLayout *)CFDataGetBytePtr(layout_data); + + UInt32 keys_down = 0; + UniChar chars[4]; + UniCharCount real_length; + + OSStatus err = UCKeyTranslate(keyboard_layout, + key, + kUCKeyActionDisplay, + (state >> 8) & 0xFF, + LMGetKbdType(), + kUCKeyTranslateNoDeadKeysBit, + &keys_down, + sizeof(chars) / sizeof(chars[0]), + &real_length, + chars); + + if (err != noErr) { + return translate_key(key); + } + + for (unsigned int i = 0; i < 55; i++) { + if (_keycodes[i].kchar == chars[0]) { + return _keycodes[i].kcode; + } + } + return translate_key(key); +} + +struct _KeyCodeText { + Key code; + char32_t text; +}; + +static const _KeyCodeText _native_keycodes[] = { + /* clang-format off */ + {Key::ESCAPE ,0x001B}, + {Key::TAB ,0x0009}, + {Key::BACKTAB ,0x007F}, + {Key::BACKSPACE ,0x0008}, + {Key::ENTER ,0x000D}, + {Key::INSERT ,NSInsertFunctionKey}, + {Key::KEY_DELETE ,0x007F}, + {Key::PAUSE ,NSPauseFunctionKey}, + {Key::PRINT ,NSPrintScreenFunctionKey}, + {Key::SYSREQ ,NSSysReqFunctionKey}, + {Key::CLEAR ,NSClearLineFunctionKey}, + {Key::HOME ,0x2196}, + {Key::END ,0x2198}, + {Key::LEFT ,0x001C}, + {Key::UP ,0x001E}, + {Key::RIGHT ,0x001D}, + {Key::DOWN ,0x001F}, + {Key::PAGEUP ,0x21DE}, + {Key::PAGEDOWN ,0x21DF}, + {Key::NUMLOCK ,NSClearLineFunctionKey}, + {Key::SCROLLLOCK ,NSScrollLockFunctionKey}, + {Key::F1 ,NSF1FunctionKey}, + {Key::F2 ,NSF2FunctionKey}, + {Key::F3 ,NSF3FunctionKey}, + {Key::F4 ,NSF4FunctionKey}, + {Key::F5 ,NSF5FunctionKey}, + {Key::F6 ,NSF6FunctionKey}, + {Key::F7 ,NSF7FunctionKey}, + {Key::F8 ,NSF8FunctionKey}, + {Key::F9 ,NSF9FunctionKey}, + {Key::F10 ,NSF10FunctionKey}, + {Key::F11 ,NSF11FunctionKey}, + {Key::F12 ,NSF12FunctionKey}, + {Key::F13 ,NSF13FunctionKey}, + {Key::F14 ,NSF14FunctionKey}, + {Key::F15 ,NSF15FunctionKey}, + {Key::F16 ,NSF16FunctionKey}, //* ... NSF35FunctionKey */ + {Key::MENU ,NSMenuFunctionKey}, + {Key::HELP ,NSHelpFunctionKey}, + {Key::STOP ,NSStopFunctionKey}, + {Key::LAUNCH0 ,NSUserFunctionKey}, + {Key::SPACE ,0x0020}, + {Key::EXCLAM ,'!'}, + {Key::QUOTEDBL ,'\"'}, + {Key::NUMBERSIGN ,'#'}, + {Key::DOLLAR ,'$'}, + {Key::PERCENT ,'\%'}, + {Key::AMPERSAND ,'&'}, + {Key::APOSTROPHE ,'\''}, + {Key::PARENLEFT ,'('}, + {Key::PARENRIGHT ,')'}, + {Key::ASTERISK ,'*'}, + {Key::PLUS ,'+'}, + {Key::COMMA ,','}, + {Key::MINUS ,'-'}, + {Key::PERIOD ,'.'}, + {Key::SLASH ,'/'}, + {Key::KEY_0 ,'0'}, + {Key::KEY_1 ,'1'}, + {Key::KEY_2 ,'2'}, + {Key::KEY_3 ,'3'}, + {Key::KEY_4 ,'4'}, + {Key::KEY_5 ,'5'}, + {Key::KEY_6 ,'6'}, + {Key::KEY_7 ,'7'}, + {Key::KEY_8 ,'8'}, + {Key::KEY_9 ,'9'}, + {Key::COLON ,':'}, + {Key::SEMICOLON ,';'}, + {Key::LESS ,'<'}, + {Key::EQUAL ,'='}, + {Key::GREATER ,'>'}, + {Key::QUESTION ,'?'}, + {Key::AT ,'@'}, + {Key::A ,'a'}, + {Key::B ,'b'}, + {Key::C ,'c'}, + {Key::D ,'d'}, + {Key::E ,'e'}, + {Key::F ,'f'}, + {Key::G ,'g'}, + {Key::H ,'h'}, + {Key::I ,'i'}, + {Key::J ,'j'}, + {Key::K ,'k'}, + {Key::L ,'l'}, + {Key::M ,'m'}, + {Key::N ,'n'}, + {Key::O ,'o'}, + {Key::P ,'p'}, + {Key::Q ,'q'}, + {Key::R ,'r'}, + {Key::S ,'s'}, + {Key::T ,'t'}, + {Key::U ,'u'}, + {Key::V ,'v'}, + {Key::W ,'w'}, + {Key::X ,'x'}, + {Key::Y ,'y'}, + {Key::Z ,'z'}, + {Key::BRACKETLEFT ,'['}, + {Key::BACKSLASH ,'\\'}, + {Key::BRACKETRIGHT ,']'}, + {Key::ASCIICIRCUM ,'^'}, + {Key::UNDERSCORE ,'_'}, + {Key::QUOTELEFT ,'`'}, + {Key::BRACELEFT ,'{'}, + {Key::BAR ,'|'}, + {Key::BRACERIGHT ,'}'}, + {Key::ASCIITILDE ,'~'}, + {Key::NONE ,0x0000} + /* clang-format on */ +}; + +String KeyMappingOSX::keycode_get_native_string(Key p_keycode) { + const _KeyCodeText *kct = &_native_keycodes[0]; + + while (kct->text) { + if (kct->code == p_keycode) { + return String::chr(kct->text); + } + kct++; + } + return String(); +} + +unsigned int KeyMappingOSX::keycode_get_native_mask(Key p_keycode) { + unsigned int mask = 0; + if ((p_keycode & KeyModifierMask::CTRL) != Key::NONE) { + mask |= NSEventModifierFlagControl; + } + if ((p_keycode & KeyModifierMask::ALT) != Key::NONE) { + mask |= NSEventModifierFlagOption; + } + if ((p_keycode & KeyModifierMask::SHIFT) != Key::NONE) { + mask |= NSEventModifierFlagShift; + } + if ((p_keycode & KeyModifierMask::META) != Key::NONE) { + mask |= NSEventModifierFlagCommand; + } + if ((p_keycode & KeyModifierMask::KPAD) != Key::NONE) { + mask |= NSEventModifierFlagNumericPad; + } + return mask; +} diff --git a/platform/osx/os_osx.h b/platform/osx/os_osx.h index 60dec1fe3f..5bb5b3320e 100644 --- a/platform/osx/os_osx.h +++ b/platform/osx/os_osx.h @@ -40,9 +40,7 @@ #include "servers/audio_server.h" class OS_OSX : public OS_Unix { - virtual void delete_main_loop() override; - - bool force_quit; + bool force_quit = false; JoypadOSX *joypad_osx = nullptr; @@ -55,13 +53,15 @@ class OS_OSX : public OS_Unix { CrashHandler crash_handler; - MainLoop *main_loop; + CFRunLoopObserverRef pre_wait_observer; - static void pre_wait_observer_cb(CFRunLoopObserverRef p_observer, CFRunLoopActivity p_activiy, void *p_context); + MainLoop *main_loop = nullptr; -public: String open_with_filename; + static _FORCE_INLINE_ String get_framework_executable(const String &p_path); + static void pre_wait_observer_cb(CFRunLoopObserverRef p_observer, CFRunLoopActivity p_activiy, void *p_context); + protected: virtual void initialize_core() override; virtual void initialize() override; @@ -70,8 +70,12 @@ protected: virtual void initialize_joypads() override; virtual void set_main_loop(MainLoop *p_main_loop) override; + virtual void delete_main_loop() override; public: + String get_open_with_filename() const; + void set_open_with_filename(const String &p_path); + virtual String get_name() const override; virtual void alert(const String &p_alert, const String &p_title = "ALERT!") override; @@ -89,26 +93,27 @@ public: virtual String get_system_dir(SystemDir p_dir, bool p_shared_storage = true) const override; - Error shell_open(String p_uri) override; + virtual Error shell_open(String p_uri) override; - String get_locale() const override; + virtual String get_locale() const override; virtual String get_executable_path() const override; virtual Error create_process(const String &p_path, const List<String> &p_arguments, ProcessID *r_child_id = nullptr, bool p_open_console = false) override; virtual Error create_instance(const List<String> &p_arguments, ProcessID *r_child_id = nullptr) override; - virtual String get_unique_id() const override; //++ + virtual String get_unique_id() const override; virtual bool _check_internal_feature_support(const String &p_feature) override; - void run(); - virtual void disable_crash_handler() override; virtual bool is_disable_crash_handler() const override; virtual Error move_to_trash(const String &p_path) override; + void run(); + OS_OSX(); + ~OS_OSX(); }; #endif diff --git a/platform/osx/os_osx.mm b/platform/osx/os_osx.mm index 32d0e6dd94..9288e658cf 100644 --- a/platform/osx/os_osx.mm +++ b/platform/osx/os_osx.mm @@ -31,241 +31,45 @@ #include "os_osx.h" #include "core/version_generated.gen.h" +#include "main/main.h" #include "dir_access_osx.h" #include "display_server_osx.h" -#include "main/main.h" +#include "godot_application.h" +#include "godot_application_delegate.h" +#include "osx_terminal_logger.h" #include <dlfcn.h> #include <libproc.h> #include <mach-o/dyld.h> -#include <os/log.h> - -#define DS_OSX ((DisplayServerOSX *)(DisplayServerOSX::get_singleton())) - -/*************************************************************************/ -/* GodotApplication */ -/*************************************************************************/ - -@interface GodotApplication : NSApplication -@end - -@implementation GodotApplication - -- (void)sendEvent:(NSEvent *)event { - if (DS_OSX) { - DS_OSX->_send_event(event); - } - - // From http://cocoadev.com/index.pl?GameKeyboardHandlingAlmost - // This works around an AppKit bug, where key up events while holding - // down the command key don't get sent to the key window. - if ([event type] == NSEventTypeKeyUp && ([event modifierFlags] & NSEventModifierFlagCommand)) { - [[self keyWindow] sendEvent:event]; - } else { - [super sendEvent:event]; - } -} - -@end - -/*************************************************************************/ -/* GodotApplicationDelegate */ -/*************************************************************************/ - -@interface GodotApplicationDelegate : NSObject -- (void)forceUnbundledWindowActivationHackStep1; -- (void)forceUnbundledWindowActivationHackStep2; -- (void)forceUnbundledWindowActivationHackStep3; -@end - -@implementation GodotApplicationDelegate - -- (void)forceUnbundledWindowActivationHackStep1 { - // Step 1: Switch focus to macOS SystemUIServer process. - // Required to perform step 2, TransformProcessType will fail if app is already the in focus. - for (NSRunningApplication *app in [NSRunningApplication runningApplicationsWithBundleIdentifier:@"com.apple.systemuiserver"]) { - [app activateWithOptions:NSApplicationActivateIgnoringOtherApps]; - break; - } - [self performSelector:@selector(forceUnbundledWindowActivationHackStep2) - withObject:nil - afterDelay:0.02]; -} - -- (void)forceUnbundledWindowActivationHackStep2 { - // Step 2: Register app as foreground process. - ProcessSerialNumber psn = { 0, kCurrentProcess }; - (void)TransformProcessType(&psn, kProcessTransformToForegroundApplication); - [self performSelector:@selector(forceUnbundledWindowActivationHackStep3) withObject:nil afterDelay:0.02]; -} - -- (void)forceUnbundledWindowActivationHackStep3 { - // Step 3: Switch focus back to app window. - [[NSRunningApplication currentApplication] activateWithOptions:NSApplicationActivateIgnoringOtherApps]; -} - -- (void)applicationDidFinishLaunching:(NSNotification *)notice { - NSString *nsappname = [[[NSBundle mainBundle] infoDictionary] objectForKey:@"CFBundleName"]; - if (nsappname == nil || isatty(STDOUT_FILENO) || isatty(STDIN_FILENO) || isatty(STDERR_FILENO)) { - // If the executable is started from terminal or is not bundled, macOS WindowServer won't register and activate app window correctly (menu and title bar are grayed out and input ignored). - [self performSelector:@selector(forceUnbundledWindowActivationHackStep1) withObject:nil afterDelay:0.02]; - } -} - -- (void)applicationDidResignActive:(NSNotification *)notification { - if (OS::get_singleton()->get_main_loop()) { - OS::get_singleton()->get_main_loop()->notification(MainLoop::NOTIFICATION_APPLICATION_FOCUS_OUT); - } -} -- (void)applicationDidBecomeActive:(NSNotification *)notification { - if (OS::get_singleton()->get_main_loop()) { - OS::get_singleton()->get_main_loop()->notification(MainLoop::NOTIFICATION_APPLICATION_FOCUS_IN); - } -} - -- (void)globalMenuCallback:(id)sender { - if (DS_OSX) { - return DS_OSX->_menu_callback(sender); - } -} - -- (NSMenu *)applicationDockMenu:(NSApplication *)sender { - if (DS_OSX) { - return DS_OSX->_get_dock_menu(); +_FORCE_INLINE_ String OS_OSX::get_framework_executable(const String &p_path) { + // Append framework executable name, or return as is if p_path is not a framework. + DirAccessRef da = DirAccess::create(DirAccess::ACCESS_FILESYSTEM); + if (da->dir_exists(p_path) && da->file_exists(p_path.plus_file(p_path.get_file().get_basename()))) { + return p_path.plus_file(p_path.get_file().get_basename()); } else { - return nullptr; - } -} - -- (BOOL)application:(NSApplication *)sender openFile:(NSString *)filename { - // Note: may be called called before main loop init! - char *utfs = strdup([filename UTF8String]); - ((OS_OSX *)OS_OSX::get_singleton())->open_with_filename.parse_utf8(utfs); - free(utfs); - -#ifdef TOOLS_ENABLED - // Open new instance - if (OS_OSX::get_singleton()->get_main_loop()) { - List<String> args; - args.push_back(((OS_OSX *)OS_OSX::get_singleton())->open_with_filename); - String exec = OS_OSX::get_singleton()->get_executable_path(); - OS_OSX::get_singleton()->create_process(exec, args); - } -#endif - return YES; -} - -- (NSApplicationTerminateReply)applicationShouldTerminate:(NSApplication *)sender { - if (DS_OSX) { - DS_OSX->_send_window_event(DS_OSX->windows[DisplayServerOSX::MAIN_WINDOW_ID], DisplayServerOSX::WINDOW_EVENT_CLOSE_REQUEST); - } - return NSTerminateCancel; -} - -- (void)showAbout:(id)sender { - if (OS_OSX::get_singleton()->get_main_loop()) { - OS_OSX::get_singleton()->get_main_loop()->notification(MainLoop::NOTIFICATION_WM_ABOUT); + return p_path; } } -@end - -/*************************************************************************/ -/* OSXTerminalLogger */ -/*************************************************************************/ - -class OSXTerminalLogger : public StdLogger { -public: - virtual void log_error(const char *p_function, const char *p_file, int p_line, const char *p_code, const char *p_rationale, bool p_editor_notify = false, ErrorType p_type = ERR_ERROR) { - if (!should_log(true)) { - return; - } - - const char *err_details; - if (p_rationale && p_rationale[0]) - err_details = p_rationale; - else - err_details = p_code; - - switch (p_type) { - case ERR_WARNING: - os_log_info(OS_LOG_DEFAULT, - "WARNING: %{public}s\nat: %{public}s (%{public}s:%i)", - err_details, p_function, p_file, p_line); - logf_error("\E[1;33mWARNING:\E[0;93m %s\n", err_details); - logf_error("\E[0;90m at: %s (%s:%i)\E[0m\n", p_function, p_file, p_line); - break; - case ERR_SCRIPT: - os_log_error(OS_LOG_DEFAULT, - "SCRIPT ERROR: %{public}s\nat: %{public}s (%{public}s:%i)", - err_details, p_function, p_file, p_line); - logf_error("\E[1;35mSCRIPT ERROR:\E[0;95m %s\n", err_details); - logf_error("\E[0;90m at: %s (%s:%i)\E[0m\n", p_function, p_file, p_line); - break; - case ERR_SHADER: - os_log_error(OS_LOG_DEFAULT, - "SHADER ERROR: %{public}s\nat: %{public}s (%{public}s:%i)", - err_details, p_function, p_file, p_line); - logf_error("\E[1;36mSHADER ERROR:\E[0;96m %s\n", err_details); - logf_error("\E[0;90m at: %s (%s:%i)\E[0m\n", p_function, p_file, p_line); - break; - case ERR_ERROR: - default: - os_log_error(OS_LOG_DEFAULT, - "ERROR: %{public}s\nat: %{public}s (%{public}s:%i)", - err_details, p_function, p_file, p_line); - logf_error("\E[1;31mERROR:\E[0;91m %s\n", err_details); - logf_error("\E[0;90m at: %s (%s:%i)\E[0m\n", p_function, p_file, p_line); - break; - } - } -}; - -/*************************************************************************/ -/* OS_OSX */ -/*************************************************************************/ - -String OS_OSX::get_unique_id() const { - static String serial_number; - - if (serial_number.is_empty()) { - io_service_t platformExpert = IOServiceGetMatchingService(kIOMasterPortDefault, IOServiceMatching("IOPlatformExpertDevice")); - CFStringRef serialNumberAsCFString = nullptr; - if (platformExpert) { - serialNumberAsCFString = (CFStringRef)IORegistryEntryCreateCFProperty(platformExpert, CFSTR(kIOPlatformSerialNumberKey), kCFAllocatorDefault, 0); - IOObjectRelease(platformExpert); - } +void OS_OSX::pre_wait_observer_cb(CFRunLoopObserverRef p_observer, CFRunLoopActivity p_activiy, void *p_context) { + // Prevent main loop from sleeping and redraw window during resize / modal popups. - NSString *serialNumberAsNSString = nil; - if (serialNumberAsCFString) { - serialNumberAsNSString = [NSString stringWithString:(NSString *)serialNumberAsCFString]; - CFRelease(serialNumberAsCFString); + if (get_singleton()->get_main_loop()) { + Main::force_redraw(); + if (!Main::is_iterating()) { // Avoid cyclic loop. + Main::iteration(); } - - serial_number = [serialNumberAsNSString UTF8String]; } - return serial_number; + CFRunLoopWakeUp(CFRunLoopGetCurrent()); // Prevent main loop from sleeping. } -void OS_OSX::alert(const String &p_alert, const String &p_title) { - NSAlert *window = [[NSAlert alloc] init]; - NSString *ns_title = [NSString stringWithUTF8String:p_title.utf8().get_data()]; - NSString *ns_alert = [NSString stringWithUTF8String:p_alert.utf8().get_data()]; - - [window addButtonWithTitle:@"OK"]; - [window setMessageText:ns_title]; - [window setInformativeText:ns_alert]; - [window setAlertStyle:NSAlertStyleWarning]; +void OS_OSX::initialize() { + crash_handler.initialize(); - id key_window = [[NSApplication sharedApplication] keyWindow]; - [window runModal]; - [window release]; - if (key_window) { - [key_window makeKeyAndOrderFront:nil]; - } + initialize_core(); } void OS_OSX::initialize_core() { @@ -276,17 +80,6 @@ void OS_OSX::initialize_core() { DirAccess::make_default<DirAccessOSX>(DirAccess::ACCESS_FILESYSTEM); } -void OS_OSX::initialize_joypads() { - joypad_osx = memnew(JoypadOSX(Input::get_singleton())); -} - -void OS_OSX::initialize() { - crash_handler.initialize(); - - initialize_core(); - //ensure_user_data_dir(); -} - void OS_OSX::finalize() { #ifdef COREMIDI_ENABLED midi_driver.close(); @@ -299,42 +92,63 @@ void OS_OSX::finalize() { } } +void OS_OSX::initialize_joypads() { + joypad_osx = memnew(JoypadOSX(Input::get_singleton())); +} + void OS_OSX::set_main_loop(MainLoop *p_main_loop) { main_loop = p_main_loop; } void OS_OSX::delete_main_loop() { - if (!main_loop) + if (!main_loop) { return; + } + memdelete(main_loop); main_loop = nullptr; } +String OS_OSX::get_open_with_filename() const { + return open_with_filename; +} + +void OS_OSX::set_open_with_filename(const String &p_path) { + open_with_filename = p_path; +} + String OS_OSX::get_name() const { return "macOS"; } -_FORCE_INLINE_ String _get_framework_executable(const String p_path) { - // Append framework executable name, or return as is if p_path is not a framework. - DirAccessRef da = DirAccess::create(DirAccess::ACCESS_FILESYSTEM); - if (da->dir_exists(p_path) && da->file_exists(p_path.plus_file(p_path.get_file().get_basename()))) { - return p_path.plus_file(p_path.get_file().get_basename()); - } else { - return p_path; +void OS_OSX::alert(const String &p_alert, const String &p_title) { + NSAlert *window = [[NSAlert alloc] init]; + NSString *ns_title = [NSString stringWithUTF8String:p_title.utf8().get_data()]; + NSString *ns_alert = [NSString stringWithUTF8String:p_alert.utf8().get_data()]; + + [window addButtonWithTitle:@"OK"]; + [window setMessageText:ns_title]; + [window setInformativeText:ns_alert]; + [window setAlertStyle:NSAlertStyleWarning]; + + id key_window = [[NSApplication sharedApplication] keyWindow]; + [window runModal]; + if (key_window) { + [key_window makeKeyAndOrderFront:nil]; } } Error OS_OSX::open_dynamic_library(const String p_path, void *&p_library_handle, bool p_also_set_library_path) { - String path = _get_framework_executable(p_path); + String path = get_framework_executable(p_path); if (!FileAccess::exists(path)) { - // This code exists so gdnative can load .dylib files from within the executable path. - path = _get_framework_executable(get_executable_path().get_base_dir().plus_file(p_path.get_file())); + // Load .dylib or framework from within the executable path. + path = get_framework_executable(get_executable_path().get_base_dir().plus_file(p_path.get_file())); } if (!FileAccess::exists(path)) { - // This code exists so gdnative can load .dylib files from a standard macOS location. - path = _get_framework_executable(get_executable_path().get_base_dir().plus_file("../Frameworks").plus_file(p_path.get_file())); + // Load .dylib or framework from a standard macOS location. + path = get_framework_executable(get_executable_path().get_base_dir().plus_file("../Frameworks").plus_file(p_path.get_file())); } p_library_handle = dlopen(path.utf8().get_data(), RTLD_NOW); @@ -393,8 +207,8 @@ String OS_OSX::get_bundle_resource_dir() const { NSBundle *main = [NSBundle mainBundle]; if (main) { - NSString *resourcePath = [main resourcePath]; - ret.parse_utf8([resourcePath UTF8String]); + NSString *resource_path = [main resourcePath]; + ret.parse_utf8([resource_path UTF8String]); } return ret; } @@ -404,9 +218,9 @@ String OS_OSX::get_bundle_icon_path() const { NSBundle *main = [NSBundle mainBundle]; if (main) { - NSString *iconPath = [[main infoDictionary] objectForKey:@"CFBundleIconFile"]; - if (iconPath) { - ret.parse_utf8([iconPath UTF8String]); + NSString *icon_path = [[main infoDictionary] objectForKey:@"CFBundleIconFile"]; + if (icon_path) { + ret.parse_utf8([icon_path UTF8String]); } } return ret; @@ -449,9 +263,7 @@ String OS_OSX::get_system_dir(SystemDir p_dir, bool p_shared_storage) const { if (found) { NSArray *paths = NSSearchPathForDirectoriesInDomains(id, NSUserDomainMask, YES); if (paths && [paths count] >= 1) { - char *utfs = strdup([[paths firstObject] UTF8String]); - ret.parse_utf8(utfs); - free(utfs); + ret.parse_utf8([[paths firstObject] UTF8String]); } } @@ -475,12 +287,9 @@ String OS_OSX::get_locale() const { } String OS_OSX::get_executable_path() const { - int ret; - pid_t pid; char pathbuf[PROC_PIDPATHINFO_MAXSIZE]; - - pid = getpid(); - ret = proc_pidpath(pid, pathbuf, sizeof(pathbuf)); + int pid = getpid(); + pid_t ret = proc_pidpath(pid, pathbuf, sizeof(pathbuf)); if (ret <= 0) { return OS::get_executable_path(); } else { @@ -491,18 +300,6 @@ String OS_OSX::get_executable_path() const { } } -Error OS_OSX::create_instance(const List<String> &p_arguments, ProcessID *r_child_id) { - // If executable is bundled, always execute editor instances as an app bundle to ensure app window is registered and activated correctly. - NSString *nsappname = [[[NSBundle mainBundle] infoDictionary] objectForKey:@"CFBundleName"]; - if (nsappname != nil) { - String path; - path.parse_utf8([[[NSBundle mainBundle] bundlePath] UTF8String]); - return create_process(path, p_arguments, r_child_id, false); - } else { - return create_process(get_executable_path(), p_arguments, r_child_id, false); - } -} - Error OS_OSX::create_process(const String &p_path, const List<String> &p_arguments, ProcessID *r_child_id, bool p_open_console) { if (@available(macOS 10.15, *)) { // Use NSWorkspace if path is an .app bundle. @@ -532,7 +329,6 @@ Error OS_OSX::create_process(const String &p_path, const List<String> &p_argumen dispatch_semaphore_signal(lock); }]; dispatch_semaphore_wait(lock, dispatch_time(DISPATCH_TIME_NOW, 20000000000)); // 20 sec timeout, wait for app to launch. - dispatch_release(lock); if (err == OK) { if (r_child_id) { @@ -549,17 +345,66 @@ Error OS_OSX::create_process(const String &p_path, const List<String> &p_argumen } } -void OS_OSX::pre_wait_observer_cb(CFRunLoopObserverRef p_observer, CFRunLoopActivity p_activiy, void *p_context) { - // Prevent main loop from sleeping and redraw window during resize / modal popups. +Error OS_OSX::create_instance(const List<String> &p_arguments, ProcessID *r_child_id) { + // If executable is bundled, always execute editor instances as an app bundle to ensure app window is registered and activated correctly. + NSString *nsappname = [[[NSBundle mainBundle] infoDictionary] objectForKey:@"CFBundleName"]; + if (nsappname != nil) { + String path; + path.parse_utf8([[[NSBundle mainBundle] bundlePath] UTF8String]); + return create_process(path, p_arguments, r_child_id, false); + } else { + return create_process(get_executable_path(), p_arguments, r_child_id, false); + } +} - if (get_singleton()->get_main_loop()) { - Main::force_redraw(); - if (!Main::is_iterating()) { // Avoid cyclic loop. - Main::iteration(); +String OS_OSX::get_unique_id() const { + static String serial_number; + + if (serial_number.is_empty()) { + io_service_t platform_expert = IOServiceGetMatchingService(kIOMasterPortDefault, IOServiceMatching("IOPlatformExpertDevice")); + CFStringRef serial_number_cf_string = nullptr; + if (platform_expert) { + serial_number_cf_string = (CFStringRef)IORegistryEntryCreateCFProperty(platform_expert, CFSTR(kIOPlatformSerialNumberKey), kCFAllocatorDefault, 0); + IOObjectRelease(platform_expert); + } + + NSString *serial_number_ns_string = nil; + if (serial_number_cf_string) { + serial_number_ns_string = [NSString stringWithString:(__bridge NSString *)serial_number_cf_string]; + CFRelease(serial_number_cf_string); + } + + if (serial_number_ns_string) { + serial_number.parse_utf8([serial_number_ns_string UTF8String]); } } - CFRunLoopWakeUp(CFRunLoopGetCurrent()); // Prevent main loop from sleeping. + return serial_number; +} + +bool OS_OSX::_check_internal_feature_support(const String &p_feature) { + return p_feature == "pc"; +} + +void OS_OSX::disable_crash_handler() { + crash_handler.disable(); +} + +bool OS_OSX::is_disable_crash_handler() const { + return crash_handler.is_disabled(); +} + +Error OS_OSX::move_to_trash(const String &p_path) { + NSFileManager *fm = [NSFileManager defaultManager]; + NSURL *url = [NSURL fileURLWithPath:@(p_path.utf8().get_data())]; + NSError *err; + + if (![fm trashItemAtURL:url resultingItemURL:nil error:&err]) { + ERR_PRINT("trashItemAtURL error: " + String::utf8(err.localizedDescription.UTF8String)); + return FAILED; + } + + return OK; } void OS_OSX::run() { @@ -571,14 +416,11 @@ void OS_OSX::run() { main_loop->initialize(); - CFRunLoopObserverRef pre_wait_observer = CFRunLoopObserverCreate(kCFAllocatorDefault, kCFRunLoopBeforeWaiting, true, 0, &pre_wait_observer_cb, nullptr); - CFRunLoopAddObserver(CFRunLoopGetCurrent(), pre_wait_observer, kCFRunLoopCommonModes); - bool quit = false; while (!force_quit && !quit) { @try { if (DisplayServer::get_singleton()) { - DisplayServer::get_singleton()->process_events(); // get rid of pending events + DisplayServer::get_singleton()->process_events(); // Get rid of pending events. } joypad_osx->process_joypads(); @@ -590,25 +432,9 @@ void OS_OSX::run() { } }; - CFRunLoopRemoveObserver(CFRunLoopGetCurrent(), pre_wait_observer, kCFRunLoopCommonModes); - CFRelease(pre_wait_observer); - main_loop->finalize(); } -Error OS_OSX::move_to_trash(const String &p_path) { - NSFileManager *fm = [NSFileManager defaultManager]; - NSURL *url = [NSURL fileURLWithPath:@(p_path.utf8().get_data())]; - NSError *err; - - if (![fm trashItemAtURL:url resultingItemURL:nil error:&err]) { - ERR_PRINT("trashItemAtURL error: " + String::utf8(err.localizedDescription.UTF8String)); - return FAILED; - } - - return OK; -} - OS_OSX::OS_OSX() { main_loop = nullptr; force_quit = false; @@ -623,17 +449,17 @@ OS_OSX::OS_OSX() { DisplayServerOSX::register_osx_driver(); - // Implicitly create shared NSApplication instance + // Implicitly create shared NSApplication instance. [GodotApplication sharedApplication]; - // In case we are unbundled, make us a proper UI application + // In case we are unbundled, make us a proper UI application. [NSApp setActivationPolicy:NSApplicationActivationPolicyRegular]; // Menu bar setup must go between sharedApplication above and // finishLaunching below, in order to properly emulate the behavior - // of NSApplicationMain + // of NSApplicationMain. - NSMenu *main_menu = [[[NSMenu alloc] initWithTitle:@""] autorelease]; + NSMenu *main_menu = [[NSMenu alloc] initWithTitle:@""]; [NSApp setMainMenu:main_menu]; [NSApp finishLaunching]; @@ -641,7 +467,10 @@ OS_OSX::OS_OSX() { ERR_FAIL_COND(!delegate); [NSApp setDelegate:delegate]; - //process application:openFile: event + pre_wait_observer = CFRunLoopObserverCreate(kCFAllocatorDefault, kCFRunLoopBeforeWaiting, true, 0, &pre_wait_observer_cb, nullptr); + CFRunLoopAddObserver(CFRunLoopGetCurrent(), pre_wait_observer, kCFRunLoopCommonModes); + + // Process application:openFile: event. while (true) { NSEvent *event = [NSApp nextEventMatchingMask:NSEventMaskAny @@ -659,14 +488,7 @@ OS_OSX::OS_OSX() { [NSApp activateIgnoringOtherApps:YES]; } -bool OS_OSX::_check_internal_feature_support(const String &p_feature) { - return p_feature == "pc"; -} - -void OS_OSX::disable_crash_handler() { - crash_handler.disable(); -} - -bool OS_OSX::is_disable_crash_handler() const { - return crash_handler.is_disabled(); +OS_OSX::~OS_OSX() { + CFRunLoopRemoveObserver(CFRunLoopGetCurrent(), pre_wait_observer, kCFRunLoopCommonModes); + CFRelease(pre_wait_observer); } diff --git a/platform/osx/osx_terminal_logger.h b/platform/osx/osx_terminal_logger.h new file mode 100644 index 0000000000..8413509c4b --- /dev/null +++ b/platform/osx/osx_terminal_logger.h @@ -0,0 +1,44 @@ +/*************************************************************************/ +/* osx_terminal_logger.h */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/*************************************************************************/ + +#ifndef OSX_TERMINAL_LOGGER_H +#define OSX_TERMINAL_LOGGER_H + +#ifdef OSX_ENABLED + +#include "core/io/logger.h" + +class OSXTerminalLogger : public StdLogger { +public: + virtual void log_error(const char *p_function, const char *p_file, int p_line, const char *p_code, const char *p_rationale, bool p_editor_notify = false, ErrorType p_type = ERR_ERROR) override; +}; + +#endif // OSX_ENABLED +#endif // OSX_TERMINAL_LOGGER_H diff --git a/platform/osx/osx_terminal_logger.mm b/platform/osx/osx_terminal_logger.mm new file mode 100644 index 0000000000..c1dca111a7 --- /dev/null +++ b/platform/osx/osx_terminal_logger.mm @@ -0,0 +1,81 @@ +/*************************************************************************/ +/* osx_terminal_logger.mm */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/*************************************************************************/ + +#include "osx_terminal_logger.h" + +#ifdef OSX_ENABLED + +#include <os/log.h> + +void OSXTerminalLogger::log_error(const char *p_function, const char *p_file, int p_line, const char *p_code, const char *p_rationale, bool p_editor_notify, ErrorType p_type) { + if (!should_log(true)) { + return; + } + + const char *err_details; + if (p_rationale && p_rationale[0]) + err_details = p_rationale; + else + err_details = p_code; + + switch (p_type) { + case ERR_WARNING: + os_log_info(OS_LOG_DEFAULT, + "WARNING: %{public}s\nat: %{public}s (%{public}s:%i)", + err_details, p_function, p_file, p_line); + logf_error("\E[1;33mWARNING:\E[0;93m %s\n", err_details); + logf_error("\E[0;90m at: %s (%s:%i)\E[0m\n", p_function, p_file, p_line); + break; + case ERR_SCRIPT: + os_log_error(OS_LOG_DEFAULT, + "SCRIPT ERROR: %{public}s\nat: %{public}s (%{public}s:%i)", + err_details, p_function, p_file, p_line); + logf_error("\E[1;35mSCRIPT ERROR:\E[0;95m %s\n", err_details); + logf_error("\E[0;90m at: %s (%s:%i)\E[0m\n", p_function, p_file, p_line); + break; + case ERR_SHADER: + os_log_error(OS_LOG_DEFAULT, + "SHADER ERROR: %{public}s\nat: %{public}s (%{public}s:%i)", + err_details, p_function, p_file, p_line); + logf_error("\E[1;36mSHADER ERROR:\E[0;96m %s\n", err_details); + logf_error("\E[0;90m at: %s (%s:%i)\E[0m\n", p_function, p_file, p_line); + break; + case ERR_ERROR: + default: + os_log_error(OS_LOG_DEFAULT, + "ERROR: %{public}s\nat: %{public}s (%{public}s:%i)", + err_details, p_function, p_file, p_line); + logf_error("\E[1;31mERROR:\E[0;91m %s\n", err_details); + logf_error("\E[0;90m at: %s (%s:%i)\E[0m\n", p_function, p_file, p_line); + break; + } +} + +#endif // OSX_ENABLED diff --git a/platform/osx/vulkan_context_osx.mm b/platform/osx/vulkan_context_osx.mm index f32fab1eee..bdabc24c28 100644 --- a/platform/osx/vulkan_context_osx.mm +++ b/platform/osx/vulkan_context_osx.mm @@ -44,7 +44,7 @@ Error VulkanContextOSX::window_create(DisplayServer::WindowID p_window_id, Displ createInfo.sType = VK_STRUCTURE_TYPE_MACOS_SURFACE_CREATE_INFO_MVK; createInfo.pNext = nullptr; createInfo.flags = 0; - createInfo.pView = p_window; + createInfo.pView = (__bridge const void *)p_window; VkSurfaceKHR surface; VkResult err = vkCreateMacOSSurfaceMVK(get_instance(), &createInfo, nullptr, &surface); diff --git a/scene/gui/box_container.cpp b/scene/gui/box_container.cpp index 9827bd0cef..3261fc9d7b 100644 --- a/scene/gui/box_container.cpp +++ b/scene/gui/box_container.cpp @@ -353,7 +353,7 @@ MarginContainer *VBoxContainer::add_margin_child(const String &p_label, Control l->set_text(p_label); add_child(l); MarginContainer *mc = memnew(MarginContainer); - mc->add_theme_constant_override("margin_left", 0); + mc->add_theme_constant_override(SNAME("margin_left"), 0); mc->add_child(p_control, true); add_child(mc); if (p_expand) { diff --git a/scene/gui/button.cpp b/scene/gui/button.cpp index 3ed1b873af..65bfb463f0 100644 --- a/scene/gui/button.cpp +++ b/scene/gui/button.cpp @@ -127,7 +127,7 @@ void Button::_notification(int p_what) { } break; case DRAW_HOVER_PRESSED: { // Edge case for CheckButton and CheckBox. - if (has_theme_stylebox("hover_pressed")) { + if (has_theme_stylebox(SNAME("hover_pressed"))) { if (rtl && has_theme_stylebox(SNAME("hover_pressed_mirrored"))) { style = get_theme_stylebox(SNAME("hover_pressed_mirrored")); } else { diff --git a/scene/gui/color_picker.cpp b/scene/gui/color_picker.cpp index 36ea843d1e..4cc8f53837 100644 --- a/scene/gui/color_picker.cpp +++ b/scene/gui/color_picker.cpp @@ -70,7 +70,7 @@ void ColorPicker::_notification(int p_what) { w_edit->set_custom_minimum_size(Size2(get_theme_constant(SNAME("h_width")), 0)); wheel_edit->set_custom_minimum_size(Size2(get_theme_constant(SNAME("sv_width")), get_theme_constant(SNAME("sv_height")))); - wheel_margin->add_theme_constant_override("margin_bottom", 8 * get_theme_default_base_scale()); + wheel_margin->add_theme_constant_override(SNAME("margin_bottom"), 8 * get_theme_default_base_scale()); for (int i = 0; i < 4; i++) { labels[i]->set_custom_minimum_size(Size2(get_theme_constant(SNAME("label_width")), 0)); @@ -191,22 +191,22 @@ void ColorPicker::_update_controls() { if (raw_mode_enabled) { for (int i = 0; i < 3; i++) { - scroll[i]->remove_theme_icon_override("grabber"); - scroll[i]->remove_theme_icon_override("grabber_highlight"); - scroll[i]->remove_theme_style_override("slider"); - scroll[i]->remove_theme_style_override("grabber_area"); - scroll[i]->remove_theme_style_override("grabber_area_highlight"); + scroll[i]->remove_theme_icon_override(SNAME("grabber")); + scroll[i]->remove_theme_icon_override(SNAME("grabber_highlight")); + scroll[i]->remove_theme_style_override(SNAME("slider")); + scroll[i]->remove_theme_style_override(SNAME("grabber_area")); + scroll[i]->remove_theme_style_override(SNAME("grabber_area_highlight")); } } else { Ref<StyleBoxEmpty> style_box_empty(memnew(StyleBoxEmpty)); Ref<Texture2D> bar_arrow = get_theme_icon(SNAME("bar_arrow")); for (int i = 0; i < 4; i++) { - scroll[i]->add_theme_icon_override("grabber", bar_arrow); - scroll[i]->add_theme_icon_override("grabber_highlight", bar_arrow); - scroll[i]->add_theme_style_override("slider", style_box_empty); - scroll[i]->add_theme_style_override("grabber_area", style_box_empty); - scroll[i]->add_theme_style_override("grabber_area_highlight", style_box_empty); + scroll[i]->add_theme_icon_override(SNAME("grabber"), bar_arrow); + scroll[i]->add_theme_icon_override(SNAME("grabber_highlight"), bar_arrow); + scroll[i]->add_theme_style_override(SNAME("slider"), style_box_empty); + scroll[i]->add_theme_style_override(SNAME("grabber_area"), style_box_empty); + scroll[i]->add_theme_style_override(SNAME("grabber_area_highlight"), style_box_empty); } } @@ -1245,7 +1245,7 @@ ColorPicker::ColorPicker() : circle_mat.instantiate(); circle_mat->set_shader(circle_shader); - wheel_margin->add_theme_constant_override("margin_bottom", 8); + wheel_margin->add_theme_constant_override(SNAME("margin_bottom"), 8); wheel_edit->add_child(wheel_margin); wheel_margin->add_child(wheel); diff --git a/scene/gui/dialogs.cpp b/scene/gui/dialogs.cpp index 1cbe3adb3c..8a89c983c5 100644 --- a/scene/gui/dialogs.cpp +++ b/scene/gui/dialogs.cpp @@ -73,7 +73,7 @@ void AcceptDialog::_notification(int p_what) { } } break; case NOTIFICATION_THEME_CHANGED: { - bg->add_theme_style_override("panel", bg->get_theme_stylebox(SNAME("panel"), SNAME("AcceptDialog"))); + bg->add_theme_style_override(SNAME("panel"), bg->get_theme_stylebox(SNAME("panel"), SNAME("AcceptDialog"))); } break; case NOTIFICATION_EXIT_TREE: { if (parent_visible) { diff --git a/scene/gui/file_dialog.cpp b/scene/gui/file_dialog.cpp index dad84461f4..83dc676c55 100644 --- a/scene/gui/file_dialog.cpp +++ b/scene/gui/file_dialog.cpp @@ -65,30 +65,30 @@ void FileDialog::_theme_changed() { Color font_focus_color = vbox->get_theme_color(SNAME("font_focus_color"), SNAME("Button")); Color font_pressed_color = vbox->get_theme_color(SNAME("font_pressed_color"), SNAME("Button")); - dir_up->add_theme_color_override("icon_normal_color", font_color); - dir_up->add_theme_color_override("icon_hover_color", font_hover_color); - dir_up->add_theme_color_override("icon_focus_color", font_focus_color); - dir_up->add_theme_color_override("icon_pressed_color", font_pressed_color); - - dir_prev->add_theme_color_override("icon_color_normal", font_color); - dir_prev->add_theme_color_override("icon_color_hover", font_hover_color); - dir_prev->add_theme_color_override("icon_focus_color", font_focus_color); - dir_prev->add_theme_color_override("icon_color_pressed", font_pressed_color); - - dir_next->add_theme_color_override("icon_color_normal", font_color); - dir_next->add_theme_color_override("icon_color_hover", font_hover_color); - dir_next->add_theme_color_override("icon_focus_color", font_focus_color); - dir_next->add_theme_color_override("icon_color_pressed", font_pressed_color); - - refresh->add_theme_color_override("icon_normal_color", font_color); - refresh->add_theme_color_override("icon_hover_color", font_hover_color); - refresh->add_theme_color_override("icon_focus_color", font_focus_color); - refresh->add_theme_color_override("icon_pressed_color", font_pressed_color); - - show_hidden->add_theme_color_override("icon_normal_color", font_color); - show_hidden->add_theme_color_override("icon_hover_color", font_hover_color); - show_hidden->add_theme_color_override("icon_focus_color", font_focus_color); - show_hidden->add_theme_color_override("icon_pressed_color", font_pressed_color); + dir_up->add_theme_color_override(SNAME("icon_normal_color"), font_color); + dir_up->add_theme_color_override(SNAME("icon_hover_color"), font_hover_color); + dir_up->add_theme_color_override(SNAME("icon_focus_color"), font_focus_color); + dir_up->add_theme_color_override(SNAME("icon_pressed_color"), font_pressed_color); + + dir_prev->add_theme_color_override(SNAME("icon_color_normal"), font_color); + dir_prev->add_theme_color_override(SNAME("icon_color_hover"), font_hover_color); + dir_prev->add_theme_color_override(SNAME("icon_focus_color"), font_focus_color); + dir_prev->add_theme_color_override(SNAME("icon_color_pressed"), font_pressed_color); + + dir_next->add_theme_color_override(SNAME("icon_color_normal"), font_color); + dir_next->add_theme_color_override(SNAME("icon_color_hover"), font_hover_color); + dir_next->add_theme_color_override(SNAME("icon_focus_color"), font_focus_color); + dir_next->add_theme_color_override(SNAME("icon_color_pressed"), font_pressed_color); + + refresh->add_theme_color_override(SNAME("icon_normal_color"), font_color); + refresh->add_theme_color_override(SNAME("icon_hover_color"), font_hover_color); + refresh->add_theme_color_override(SNAME("icon_focus_color"), font_focus_color); + refresh->add_theme_color_override(SNAME("icon_pressed_color"), font_pressed_color); + + show_hidden->add_theme_color_override(SNAME("icon_normal_color"), font_color); + show_hidden->add_theme_color_override(SNAME("icon_hover_color"), font_hover_color); + show_hidden->add_theme_color_override(SNAME("icon_focus_color"), font_focus_color); + show_hidden->add_theme_color_override(SNAME("icon_pressed_color"), font_pressed_color); } void FileDialog::_notification(int p_what) { diff --git a/scene/gui/menu_button.cpp b/scene/gui/menu_button.cpp index a985a9d031..94fa5d81d8 100644 --- a/scene/gui/menu_button.cpp +++ b/scene/gui/menu_button.cpp @@ -136,6 +136,9 @@ int MenuButton::get_item_count() const { void MenuButton::_notification(int p_what) { switch (p_what) { + case NOTIFICATION_LAYOUT_DIRECTION_CHANGED: { + popup->set_layout_direction((Window::LayoutDirection)get_layout_direction()); + } break; case NOTIFICATION_VISIBILITY_CHANGED: { if (!is_visible_in_tree()) { popup->hide(); diff --git a/scene/gui/option_button.cpp b/scene/gui/option_button.cpp index 9984ab240a..31f3b306b7 100644 --- a/scene/gui/option_button.cpp +++ b/scene/gui/option_button.cpp @@ -92,7 +92,10 @@ void OptionButton::_notification(int p_what) { arrow->draw(ci, ofs, clr); } break; case NOTIFICATION_TRANSLATION_CHANGED: - case NOTIFICATION_LAYOUT_DIRECTION_CHANGED: + case NOTIFICATION_LAYOUT_DIRECTION_CHANGED: { + popup->set_layout_direction((Window::LayoutDirection)get_layout_direction()); + [[fallthrough]]; + } case NOTIFICATION_THEME_CHANGED: { if (has_theme_icon(SNAME("arrow"))) { if (is_layout_rtl()) { diff --git a/scene/gui/popup.cpp b/scene/gui/popup.cpp index 7c03fcbb37..416d847218 100644 --- a/scene/gui/popup.cpp +++ b/scene/gui/popup.cpp @@ -242,9 +242,9 @@ void PopupPanel::_update_child_rects() { void PopupPanel::_notification(int p_what) { if (p_what == NOTIFICATION_THEME_CHANGED) { - panel->add_theme_style_override("panel", get_theme_stylebox(SNAME("panel"), get_class_name())); + panel->add_theme_style_override(SNAME("panel"), get_theme_stylebox(SNAME("panel"), get_class_name())); } else if (p_what == NOTIFICATION_READY || p_what == NOTIFICATION_ENTER_TREE) { - panel->add_theme_style_override("panel", get_theme_stylebox(SNAME("panel"), get_class_name())); + panel->add_theme_style_override(SNAME("panel"), get_theme_stylebox(SNAME("panel"), get_class_name())); _update_child_rects(); } else if (p_what == NOTIFICATION_WM_SIZE_CHANGED) { _update_child_rects(); diff --git a/scene/gui/popup_menu.cpp b/scene/gui/popup_menu.cpp index 4798019720..ca1c8505fe 100644 --- a/scene/gui/popup_menu.cpp +++ b/scene/gui/popup_menu.cpp @@ -203,15 +203,17 @@ void PopupMenu::_activate_submenu(int p_over) { float scroll_offset = control->get_position().y; - Point2 submenu_pos; + submenu_popup->set_as_minsize(); // Shrink the popup size to its contents. Size2 submenu_size = submenu_popup->get_size(); + + Point2 submenu_pos; if (control->is_layout_rtl()) { submenu_pos = this_pos + Point2(-submenu_size.width, items[p_over]._ofs_cache + scroll_offset); } else { submenu_pos = this_pos + Point2(this_rect.size.width, items[p_over]._ofs_cache + scroll_offset); } - // Fix pos if going outside parent rect + // Fix pos if going outside parent rect. if (submenu_pos.x < get_parent_rect().position.x) { submenu_pos.x = this_pos.x + submenu_size.width; } @@ -222,7 +224,6 @@ void PopupMenu::_activate_submenu(int p_over) { submenu_popup->set_close_on_parent_focus(false); submenu_popup->set_position(submenu_pos); - submenu_popup->set_as_minsize(); // Shrink the popup size to its contents. PopupMenu *submenu_pum = Object::cast_to<PopupMenu>(submenu_popup); if (!submenu_pum) { @@ -642,8 +643,8 @@ void PopupMenu::_draw_items() { if (items[i].separator) { if (!text.is_empty()) { Vector2 text_pos = Point2(separator_ofs, item_ofs.y + Math::floor((h - items[i].text_buf->get_size().y) / 2.0)); - if (!items[i].icon.is_null()) { - text_pos.x = rtl ? text_pos.x - (icon_size.width + hseparation) : text_pos.x + icon_size.width + hseparation; + if (!rtl && !items[i].icon.is_null()) { + text_pos.x += icon_size.width + hseparation; } if (outline_size > 0 && font_outline_color.a > 0) { @@ -747,13 +748,32 @@ void PopupMenu::_notification(int p_what) { case NOTIFICATION_ENTER_TREE: { PopupMenu *pm = Object::cast_to<PopupMenu>(get_parent()); if (pm) { - // Inherit submenu's popup delay time from parent menu + // Inherit submenu's popup delay time from parent menu. float pm_delay = pm->get_submenu_popup_delay(); set_submenu_popup_delay(pm_delay); } } break; case NOTIFICATION_THEME_CHANGED: - case Control::NOTIFICATION_LAYOUT_DIRECTION_CHANGED: + case Control::NOTIFICATION_LAYOUT_DIRECTION_CHANGED: { + // Pass the layout direction to all submenus. + for (int i = 0; i < items.size(); i++) { + if (items[i].submenu.is_empty()) { + continue; + } + + Node *n = get_node(items[i].submenu); + if (!n) { + continue; + } + + PopupMenu *pm = Object::cast_to<PopupMenu>(n); + if (pm) { + pm->set_layout_direction(get_layout_direction()); + } + } + + [[fallthrough]]; + } case NOTIFICATION_TRANSLATION_CHANGED: { for (int i = 0; i < items.size(); i++) { items.write[i].xl_text = atr(items[i].text); @@ -826,10 +846,10 @@ void PopupMenu::_notification(int p_what) { // Set margin on the margin container Ref<StyleBox> panel_style = get_theme_stylebox(SNAME("panel")); - margin_container->add_theme_constant_override("margin_top", panel_style->get_margin(Side::SIDE_TOP)); - margin_container->add_theme_constant_override("margin_bottom", panel_style->get_margin(Side::SIDE_BOTTOM)); - margin_container->add_theme_constant_override("margin_left", panel_style->get_margin(Side::SIDE_LEFT)); - margin_container->add_theme_constant_override("margin_right", panel_style->get_margin(Side::SIDE_RIGHT)); + margin_container->add_theme_constant_override(SNAME("margin_top"), panel_style->get_margin(Side::SIDE_TOP)); + margin_container->add_theme_constant_override(SNAME("margin_bottom"), panel_style->get_margin(Side::SIDE_BOTTOM)); + margin_container->add_theme_constant_override(SNAME("margin_left"), panel_style->get_margin(Side::SIDE_LEFT)); + margin_container->add_theme_constant_override(SNAME("margin_right"), panel_style->get_margin(Side::SIDE_RIGHT)); } } break; } diff --git a/scene/gui/tree.cpp b/scene/gui/tree.cpp index e33ce0b017..e2c7597f7e 100644 --- a/scene/gui/tree.cpp +++ b/scene/gui/tree.cpp @@ -4941,7 +4941,7 @@ Tree::Tree() { add_child(popup_editor, false, INTERNAL_MODE_FRONT); popup_editor_vb = memnew(VBoxContainer); popup_editor->add_child(popup_editor_vb); - popup_editor_vb->add_theme_constant_override("separation", 0); + popup_editor_vb->add_theme_constant_override(SNAME("separation"), 0); popup_editor_vb->set_anchors_and_offsets_preset(PRESET_WIDE); text_editor = memnew(LineEdit); popup_editor_vb->add_child(text_editor); diff --git a/scene/main/canvas_item.cpp b/scene/main/canvas_item.cpp index a62bbb146c..b794bbbc57 100644 --- a/scene/main/canvas_item.cpp +++ b/scene/main/canvas_item.cpp @@ -56,43 +56,19 @@ Transform2D CanvasItem::_edit_get_transform() const { #endif bool CanvasItem::is_visible_in_tree() const { - if (!is_inside_tree()) { - return false; - } - - const CanvasItem *p = this; - - while (p) { - if (!p->visible) { - return false; - } - if (p->window && !p->window->is_visible()) { - return false; - } - p = p->get_parent_item(); - } - - const Node *n = get_parent(); - while (n) { - const CanvasLayer *c = Object::cast_to<CanvasLayer>(n); - if (c && !c->is_visible()) { - return false; - } - n = n->get_parent(); - } - - return true; + return visible && visible_in_tree; } -void CanvasItem::_propagate_visibility_changed(bool p_visible) { +void CanvasItem::_propagate_visibility_changed(bool p_visible, bool p_was_visible) { if (p_visible && first_draw) { //avoid propagating it twice first_draw = false; } + visible_in_tree = p_visible; notification(NOTIFICATION_VISIBILITY_CHANGED); - if (p_visible) { - update(); //todo optimize - } else { + if (visible && p_visible) { + update(); + } else if (!p_visible && (visible || p_was_visible)) { emit_signal(SceneStringNames::get_singleton()->hidden); } _block(); @@ -120,7 +96,7 @@ void CanvasItem::set_visible(bool p_visible) { return; } - _propagate_visibility_changed(p_visible); + _propagate_visibility_changed(p_visible, !p_visible); } void CanvasItem::show() { @@ -148,7 +124,7 @@ void CanvasItem::_update_callback() { RenderingServer::get_singleton()->canvas_item_clear(get_canvas_item()); //todo updating = true - only allow drawing here - if (is_visible_in_tree()) { //todo optimize this!! + if (is_visible_in_tree()) { if (first_draw) { notification(NOTIFICATION_VISIBILITY_CHANGED); first_draw = false; @@ -282,32 +258,44 @@ void CanvasItem::_notification(int p_what) { case NOTIFICATION_ENTER_TREE: { ERR_FAIL_COND(!is_inside_tree()); first_draw = true; + Node *parent = get_parent(); if (parent) { CanvasItem *ci = Object::cast_to<CanvasItem>(parent); + if (ci) { + visible_in_tree = ci->is_visible_in_tree(); C = ci->children_items.push_back(this); - } - if (!ci) { - //look for a window - Viewport *viewport = nullptr; - - while (parent) { - viewport = Object::cast_to<Viewport>(parent); - if (viewport) { - break; + } else { + CanvasLayer *cl = Object::cast_to<CanvasLayer>(parent); + + if (cl) { + visible_in_tree = cl->is_visible(); + } else { + // Look for a window. + Viewport *viewport = nullptr; + + while (parent) { + viewport = Object::cast_to<Viewport>(parent); + if (viewport) { + break; + } + parent = parent->get_parent(); } - parent = parent->get_parent(); - } - ERR_FAIL_COND(!viewport); + ERR_FAIL_COND(!viewport); - window = Object::cast_to<Window>(viewport); - if (window) { - window->connect(SceneStringNames::get_singleton()->visibility_changed, callable_mp(this, &CanvasItem::_window_visibility_changed)); + window = Object::cast_to<Window>(viewport); + if (window) { + window->connect(SceneStringNames::get_singleton()->visibility_changed, callable_mp(this, &CanvasItem::_window_visibility_changed)); + visible_in_tree = window->is_visible(); + } else { + visible_in_tree = true; + } } } } + _enter_canvas(); _update_texture_filter_changed(false); @@ -344,6 +332,7 @@ void CanvasItem::_notification(int p_what) { window->disconnect(SceneStringNames::get_singleton()->visibility_changed, callable_mp(this, &CanvasItem::_window_visibility_changed)); } global_invalid = true; + visible_in_tree = false; } break; case NOTIFICATION_DRAW: case NOTIFICATION_TRANSFORM_CHANGED: { diff --git a/scene/main/canvas_item.h b/scene/main/canvas_item.h index 08fea52c3a..a368a10ad0 100644 --- a/scene/main/canvas_item.h +++ b/scene/main/canvas_item.h @@ -87,6 +87,7 @@ private: Window *window = nullptr; bool first_draw = false; bool visible = true; + bool visible_in_tree = false; bool clip_children = false; bool pending_update = false; bool top_level = false; @@ -109,7 +110,7 @@ private: void _top_level_raise_self(); - void _propagate_visibility_changed(bool p_visible); + void _propagate_visibility_changed(bool p_visible, bool p_was_visible = false); void _update_callback(); diff --git a/scene/resources/default_theme/default_theme.cpp b/scene/resources/default_theme/default_theme.cpp index 670b141080..c77efcc6db 100644 --- a/scene/resources/default_theme/default_theme.cpp +++ b/scene/resources/default_theme/default_theme.cpp @@ -139,8 +139,8 @@ void fill_default_theme(Ref<Theme> &theme, const Ref<Font> &default_font, Ref<Te } // Panel - theme->set_stylebox("panel", "Panel", make_flat_stylebox(style_normal_color, 0, 0, 0, 0)); - theme->set_stylebox("panel_fg", "Panel", make_flat_stylebox(style_normal_color, 0, 0, 0, 0)); + theme->set_stylebox(SNAME("panel"), SNAME("Panel"), make_flat_stylebox(style_normal_color, 0, 0, 0, 0)); + theme->set_stylebox(SNAME("panel_fg"), SNAME("Panel"), make_flat_stylebox(style_normal_color, 0, 0, 0, 0)); // Button @@ -152,108 +152,108 @@ void fill_default_theme(Ref<Theme> &theme, const Ref<Font> &default_font, Ref<Te // Make the focus outline appear to be flush with the buttons it's focusing. focus->set_expand_margin_size_all(2 * scale); - theme->set_stylebox("normal", "Button", button_normal); - theme->set_stylebox("hover", "Button", button_hover); - theme->set_stylebox("pressed", "Button", button_pressed); - theme->set_stylebox("disabled", "Button", button_disabled); - theme->set_stylebox("focus", "Button", focus); - - theme->set_font("font", "Button", Ref<Font>()); - theme->set_font_size("font_size", "Button", -1); - theme->set_constant("outline_size", "Button", 0 * scale); - - theme->set_color("font_color", "Button", control_font_color); - theme->set_color("font_pressed_color", "Button", control_font_pressed_color); - theme->set_color("font_hover_color", "Button", control_font_hover_color); - theme->set_color("font_focus_color", "Button", control_font_focus_color); - theme->set_color("font_hover_pressed_color", "Button", control_font_pressed_color); - theme->set_color("font_disabled_color", "Button", control_font_disabled_color); - theme->set_color("font_outline_color", "Button", Color(1, 1, 1)); - - theme->set_color("icon_normal_color", "Button", Color(1, 1, 1, 1)); - theme->set_color("icon_pressed_color", "Button", Color(1, 1, 1, 1)); - theme->set_color("icon_hover_color", "Button", Color(1, 1, 1, 1)); - theme->set_color("icon_hover_pressed_color", "Button", Color(1, 1, 1, 1)); - theme->set_color("icon_focus_color", "Button", Color(1, 1, 1, 1)); - theme->set_color("icon_disabled_color", "Button", Color(1, 1, 1, 1)); - - theme->set_constant("hseparation", "Button", 2 * scale); + theme->set_stylebox(SNAME("normal"), SNAME("Button"), button_normal); + theme->set_stylebox(SNAME("hover"), SNAME("Button"), button_hover); + theme->set_stylebox(SNAME("pressed"), SNAME("Button"), button_pressed); + theme->set_stylebox(SNAME("disabled"), SNAME("Button"), button_disabled); + theme->set_stylebox(SNAME("focus"), SNAME("Button"), focus); + + theme->set_font(SNAME("font"), SNAME("Button"), Ref<Font>()); + theme->set_font_size(SNAME("font_size"), SNAME("Button"), -1); + theme->set_constant(SNAME("outline_size"), SNAME("Button"), 0 * scale); + + theme->set_color(SNAME("font_color"), SNAME("Button"), control_font_color); + theme->set_color(SNAME("font_pressed_color"), SNAME("Button"), control_font_pressed_color); + theme->set_color(SNAME("font_hover_color"), SNAME("Button"), control_font_hover_color); + theme->set_color(SNAME("font_focus_color"), SNAME("Button"), control_font_focus_color); + theme->set_color(SNAME("font_hover_pressed_color"), SNAME("Button"), control_font_pressed_color); + theme->set_color(SNAME("font_disabled_color"), SNAME("Button"), control_font_disabled_color); + theme->set_color(SNAME("font_outline_color"), SNAME("Button"), Color(1, 1, 1)); + + theme->set_color(SNAME("icon_normal_color"), SNAME("Button"), Color(1, 1, 1, 1)); + theme->set_color(SNAME("icon_pressed_color"), SNAME("Button"), Color(1, 1, 1, 1)); + theme->set_color(SNAME("icon_hover_color"), SNAME("Button"), Color(1, 1, 1, 1)); + theme->set_color(SNAME("icon_hover_pressed_color"), SNAME("Button"), Color(1, 1, 1, 1)); + theme->set_color(SNAME("icon_focus_color"), SNAME("Button"), Color(1, 1, 1, 1)); + theme->set_color(SNAME("icon_disabled_color"), SNAME("Button"), Color(1, 1, 1, 1)); + + theme->set_constant(SNAME("hseparation"), SNAME("Button"), 2 * scale); // LinkButton - theme->set_stylebox("focus", "LinkButton", focus); + theme->set_stylebox(SNAME("focus"), SNAME("LinkButton"), focus); - theme->set_font("font", "LinkButton", Ref<Font>()); - theme->set_font_size("font_size", "LinkButton", -1); + theme->set_font(SNAME("font"), SNAME("LinkButton"), Ref<Font>()); + theme->set_font_size(SNAME("font_size"), SNAME("LinkButton"), -1); - theme->set_color("font_color", "LinkButton", control_font_color); - theme->set_color("font_pressed_color", "LinkButton", control_font_pressed_color); - theme->set_color("font_hover_color", "LinkButton", control_font_hover_color); - theme->set_color("font_focus_color", "LinkButton", control_font_focus_color); - theme->set_color("font_outline_color", "LinkButton", Color(1, 1, 1)); + theme->set_color(SNAME("font_color"), SNAME("LinkButton"), control_font_color); + theme->set_color(SNAME("font_pressed_color"), SNAME("LinkButton"), control_font_pressed_color); + theme->set_color(SNAME("font_hover_color"), SNAME("LinkButton"), control_font_hover_color); + theme->set_color(SNAME("font_focus_color"), SNAME("LinkButton"), control_font_focus_color); + theme->set_color(SNAME("font_outline_color"), SNAME("LinkButton"), Color(1, 1, 1)); - theme->set_constant("outline_size", "LinkButton", 0); - theme->set_constant("underline_spacing", "LinkButton", 2 * scale); + theme->set_constant(SNAME("outline_size"), SNAME("LinkButton"), 0); + theme->set_constant(SNAME("underline_spacing"), SNAME("LinkButton"), 2 * scale); // OptionButton - theme->set_stylebox("focus", "OptionButton", focus); + theme->set_stylebox(SNAME("focus"), SNAME("OptionButton"), focus); Ref<StyleBox> sb_optbutton_normal = make_flat_stylebox(style_normal_color, 2 * default_margin, default_margin, 21, default_margin); Ref<StyleBox> sb_optbutton_hover = make_flat_stylebox(style_hover_color, 2 * default_margin, default_margin, 21, default_margin); Ref<StyleBox> sb_optbutton_pressed = make_flat_stylebox(style_pressed_color, 2 * default_margin, default_margin, 21, default_margin); Ref<StyleBox> sb_optbutton_disabled = make_flat_stylebox(style_disabled_color, 2 * default_margin, default_margin, 21, default_margin); - theme->set_stylebox("normal", "OptionButton", sb_optbutton_normal); - theme->set_stylebox("hover", "OptionButton", sb_optbutton_hover); - theme->set_stylebox("pressed", "OptionButton", sb_optbutton_pressed); - theme->set_stylebox("disabled", "OptionButton", sb_optbutton_disabled); + theme->set_stylebox(SNAME("normal"), SNAME("OptionButton"), sb_optbutton_normal); + theme->set_stylebox(SNAME("hover"), SNAME("OptionButton"), sb_optbutton_hover); + theme->set_stylebox(SNAME("pressed"), SNAME("OptionButton"), sb_optbutton_pressed); + theme->set_stylebox(SNAME("disabled"), SNAME("OptionButton"), sb_optbutton_disabled); Ref<StyleBox> sb_optbutton_normal_mirrored = make_flat_stylebox(style_normal_color, 21, default_margin, 2 * default_margin, default_margin); Ref<StyleBox> sb_optbutton_hover_mirrored = make_flat_stylebox(style_hover_color, 21, default_margin, 2 * default_margin, default_margin); Ref<StyleBox> sb_optbutton_pressed_mirrored = make_flat_stylebox(style_pressed_color, 21, default_margin, 2 * default_margin, default_margin); Ref<StyleBox> sb_optbutton_disabled_mirrored = make_flat_stylebox(style_disabled_color, 21, default_margin, 2 * default_margin, default_margin); - theme->set_stylebox("normal_mirrored", "OptionButton", sb_optbutton_normal_mirrored); - theme->set_stylebox("hover_mirrored", "OptionButton", sb_optbutton_hover_mirrored); - theme->set_stylebox("pressed_mirrored", "OptionButton", sb_optbutton_pressed_mirrored); - theme->set_stylebox("disabled_mirrored", "OptionButton", sb_optbutton_disabled_mirrored); + theme->set_stylebox(SNAME("normal_mirrored"), SNAME("OptionButton"), sb_optbutton_normal_mirrored); + theme->set_stylebox(SNAME("hover_mirrored"), SNAME("OptionButton"), sb_optbutton_hover_mirrored); + theme->set_stylebox(SNAME("pressed_mirrored"), SNAME("OptionButton"), sb_optbutton_pressed_mirrored); + theme->set_stylebox(SNAME("disabled_mirrored"), SNAME("OptionButton"), sb_optbutton_disabled_mirrored); - theme->set_icon("arrow", "OptionButton", icons["option_button_arrow"]); + theme->set_icon(SNAME("arrow"), SNAME("OptionButton"), icons["option_button_arrow"]); - theme->set_font("font", "OptionButton", Ref<Font>()); - theme->set_font_size("font_size", "OptionButton", -1); + theme->set_font(SNAME("font"), SNAME("OptionButton"), Ref<Font>()); + theme->set_font_size(SNAME("font_size"), SNAME("OptionButton"), -1); - theme->set_color("font_color", "OptionButton", control_font_color); - theme->set_color("font_pressed_color", "OptionButton", control_font_pressed_color); - theme->set_color("font_hover_color", "OptionButton", control_font_hover_color); - theme->set_color("font_focus_color", "OptionButton", control_font_focus_color); - theme->set_color("font_disabled_color", "OptionButton", control_font_disabled_color); - theme->set_color("font_outline_color", "OptionButton", Color(1, 1, 1)); + theme->set_color(SNAME("font_color"), SNAME("OptionButton"), control_font_color); + theme->set_color(SNAME("font_pressed_color"), SNAME("OptionButton"), control_font_pressed_color); + theme->set_color(SNAME("font_hover_color"), SNAME("OptionButton"), control_font_hover_color); + theme->set_color(SNAME("font_focus_color"), SNAME("OptionButton"), control_font_focus_color); + theme->set_color(SNAME("font_disabled_color"), SNAME("OptionButton"), control_font_disabled_color); + theme->set_color(SNAME("font_outline_color"), SNAME("OptionButton"), Color(1, 1, 1)); - theme->set_constant("hseparation", "OptionButton", 2 * scale); - theme->set_constant("arrow_margin", "OptionButton", 4 * scale); - theme->set_constant("outline_size", "OptionButton", 0); + theme->set_constant(SNAME("hseparation"), SNAME("OptionButton"), 2 * scale); + theme->set_constant(SNAME("arrow_margin"), SNAME("OptionButton"), 4 * scale); + theme->set_constant(SNAME("outline_size"), SNAME("OptionButton"), 0); // MenuButton - theme->set_stylebox("normal", "MenuButton", button_normal); - theme->set_stylebox("pressed", "MenuButton", button_pressed); - theme->set_stylebox("hover", "MenuButton", button_hover); - theme->set_stylebox("disabled", "MenuButton", button_disabled); - theme->set_stylebox("focus", "MenuButton", focus); + theme->set_stylebox(SNAME("normal"), SNAME("MenuButton"), button_normal); + theme->set_stylebox(SNAME("pressed"), SNAME("MenuButton"), button_pressed); + theme->set_stylebox(SNAME("hover"), SNAME("MenuButton"), button_hover); + theme->set_stylebox(SNAME("disabled"), SNAME("MenuButton"), button_disabled); + theme->set_stylebox(SNAME("focus"), SNAME("MenuButton"), focus); - theme->set_font("font", "MenuButton", Ref<Font>()); - theme->set_font_size("font_size", "MenuButton", -1); + theme->set_font(SNAME("font"), SNAME("MenuButton"), Ref<Font>()); + theme->set_font_size(SNAME("font_size"), SNAME("MenuButton"), -1); - theme->set_color("font_color", "MenuButton", control_font_color); - theme->set_color("font_pressed_color", "MenuButton", control_font_pressed_color); - theme->set_color("font_hover_color", "MenuButton", control_font_hover_color); - theme->set_color("font_focus_color", "MenuButton", control_font_focus_color); - theme->set_color("font_disabled_color", "MenuButton", Color(1, 1, 1, 0.3)); - theme->set_color("font_outline_color", "MenuButton", Color(1, 1, 1)); + theme->set_color(SNAME("font_color"), SNAME("MenuButton"), control_font_color); + theme->set_color(SNAME("font_pressed_color"), SNAME("MenuButton"), control_font_pressed_color); + theme->set_color(SNAME("font_hover_color"), SNAME("MenuButton"), control_font_hover_color); + theme->set_color(SNAME("font_focus_color"), SNAME("MenuButton"), control_font_focus_color); + theme->set_color(SNAME("font_disabled_color"), SNAME("MenuButton"), Color(1, 1, 1, 0.3)); + theme->set_color(SNAME("font_outline_color"), SNAME("MenuButton"), Color(1, 1, 1)); - theme->set_constant("hseparation", "MenuButton", 3 * scale); - theme->set_constant("outline_size", "MenuButton", 0); + theme->set_constant(SNAME("hseparation"), SNAME("MenuButton"), 3 * scale); + theme->set_constant(SNAME("outline_size"), SNAME("MenuButton"), 0); // CheckBox @@ -268,36 +268,36 @@ void fill_default_theme(Ref<Theme> &theme, const Ref<Font> &default_font, Ref<Te cbx_focus->set_default_margin(SIDE_TOP, 4 * scale); cbx_focus->set_default_margin(SIDE_BOTTOM, 4 * scale); - theme->set_stylebox("normal", "CheckBox", cbx_empty); - theme->set_stylebox("pressed", "CheckBox", cbx_empty); - theme->set_stylebox("disabled", "CheckBox", cbx_empty); - theme->set_stylebox("hover", "CheckBox", cbx_empty); - theme->set_stylebox("hover_pressed", "CheckBox", cbx_empty); - theme->set_stylebox("focus", "CheckBox", cbx_focus); - - theme->set_icon("checked", "CheckBox", icons["checked"]); - theme->set_icon("checked_disabled", "CheckBox", icons["checked"]); - theme->set_icon("unchecked", "CheckBox", icons["unchecked"]); - theme->set_icon("unchecked_disabled", "CheckBox", icons["unchecked"]); - theme->set_icon("radio_checked", "CheckBox", icons["radio_checked"]); - theme->set_icon("radio_checked_disabled", "CheckBox", icons["radio_checked"]); - theme->set_icon("radio_unchecked", "CheckBox", icons["radio_unchecked"]); - theme->set_icon("radio_unchecked_disabled", "CheckBox", icons["radio_unchecked"]); - - theme->set_font("font", "CheckBox", Ref<Font>()); - theme->set_font_size("font_size", "CheckBox", -1); - - theme->set_color("font_color", "CheckBox", control_font_color); - theme->set_color("font_pressed_color", "CheckBox", control_font_pressed_color); - theme->set_color("font_hover_color", "CheckBox", control_font_hover_color); - theme->set_color("font_hover_pressed_color", "CheckBox", control_font_pressed_color); - theme->set_color("font_focus_color", "CheckBox", control_font_focus_color); - theme->set_color("font_disabled_color", "CheckBox", control_font_disabled_color); - theme->set_color("font_outline_color", "CheckBox", Color(1, 1, 1)); - - theme->set_constant("hseparation", "CheckBox", 4 * scale); - theme->set_constant("check_vadjust", "CheckBox", 0 * scale); - theme->set_constant("outline_size", "CheckBox", 0); + theme->set_stylebox(SNAME("normal"), SNAME("CheckBox"), cbx_empty); + theme->set_stylebox(SNAME("pressed"), SNAME("CheckBox"), cbx_empty); + theme->set_stylebox(SNAME("disabled"), SNAME("CheckBox"), cbx_empty); + theme->set_stylebox(SNAME("hover"), SNAME("CheckBox"), cbx_empty); + theme->set_stylebox(SNAME("hover_pressed"), SNAME("CheckBox"), cbx_empty); + theme->set_stylebox(SNAME("focus"), SNAME("CheckBox"), cbx_focus); + + theme->set_icon(SNAME("checked"), SNAME("CheckBox"), icons["checked"]); + theme->set_icon(SNAME("checked_disabled"), SNAME("CheckBox"), icons["checked"]); + theme->set_icon(SNAME("unchecked"), SNAME("CheckBox"), icons["unchecked"]); + theme->set_icon(SNAME("unchecked_disabled"), SNAME("CheckBox"), icons["unchecked"]); + theme->set_icon(SNAME("radio_checked"), SNAME("CheckBox"), icons["radio_checked"]); + theme->set_icon(SNAME("radio_checked_disabled"), SNAME("CheckBox"), icons["radio_checked"]); + theme->set_icon(SNAME("radio_unchecked"), SNAME("CheckBox"), icons["radio_unchecked"]); + theme->set_icon(SNAME("radio_unchecked_disabled"), SNAME("CheckBox"), icons["radio_unchecked"]); + + theme->set_font(SNAME("font"), SNAME("CheckBox"), Ref<Font>()); + theme->set_font_size(SNAME("font_size"), SNAME("CheckBox"), -1); + + theme->set_color(SNAME("font_color"), SNAME("CheckBox"), control_font_color); + theme->set_color(SNAME("font_pressed_color"), SNAME("CheckBox"), control_font_pressed_color); + theme->set_color(SNAME("font_hover_color"), SNAME("CheckBox"), control_font_hover_color); + theme->set_color(SNAME("font_hover_pressed_color"), SNAME("CheckBox"), control_font_pressed_color); + theme->set_color(SNAME("font_focus_color"), SNAME("CheckBox"), control_font_focus_color); + theme->set_color(SNAME("font_disabled_color"), SNAME("CheckBox"), control_font_disabled_color); + theme->set_color(SNAME("font_outline_color"), SNAME("CheckBox"), Color(1, 1, 1)); + + theme->set_constant(SNAME("hseparation"), SNAME("CheckBox"), 4 * scale); + theme->set_constant(SNAME("check_vadjust"), SNAME("CheckBox"), 0 * scale); + theme->set_constant(SNAME("outline_size"), SNAME("CheckBox"), 0); // CheckButton @@ -307,62 +307,62 @@ void fill_default_theme(Ref<Theme> &theme, const Ref<Font> &default_font, Ref<Te cb_empty->set_default_margin(SIDE_TOP, 4 * scale); cb_empty->set_default_margin(SIDE_BOTTOM, 4 * scale); - theme->set_stylebox("normal", "CheckButton", cb_empty); - theme->set_stylebox("pressed", "CheckButton", cb_empty); - theme->set_stylebox("disabled", "CheckButton", cb_empty); - theme->set_stylebox("hover", "CheckButton", cb_empty); - theme->set_stylebox("hover_pressed", "CheckButton", cb_empty); - theme->set_stylebox("focus", "CheckButton", focus); - - theme->set_icon("on", "CheckButton", icons["toggle_on"]); - theme->set_icon("on_disabled", "CheckButton", icons["toggle_on_disabled"]); - theme->set_icon("off", "CheckButton", icons["toggle_off"]); - theme->set_icon("off_disabled", "CheckButton", icons["toggle_off_disabled"]); - - theme->set_icon("on_mirrored", "CheckButton", icons["toggle_on_mirrored"]); - theme->set_icon("on_disabled_mirrored", "CheckButton", icons["toggle_on_disabled_mirrored"]); - theme->set_icon("off_mirrored", "CheckButton", icons["toggle_off_mirrored"]); - theme->set_icon("off_disabled_mirrored", "CheckButton", icons["toggle_off_disabled_mirrored"]); - - theme->set_font("font", "CheckButton", Ref<Font>()); - theme->set_font_size("font_size", "CheckButton", -1); - - theme->set_color("font_color", "CheckButton", control_font_color); - theme->set_color("font_pressed_color", "CheckButton", control_font_pressed_color); - theme->set_color("font_hover_color", "CheckButton", control_font_hover_color); - theme->set_color("font_hover_pressed_color", "CheckButton", control_font_pressed_color); - theme->set_color("font_focus_color", "CheckButton", control_font_focus_color); - theme->set_color("font_disabled_color", "CheckButton", control_font_disabled_color); - theme->set_color("font_outline_color", "CheckButton", Color(1, 1, 1)); - - theme->set_constant("hseparation", "CheckButton", 4 * scale); - theme->set_constant("check_vadjust", "CheckButton", 0 * scale); - theme->set_constant("outline_size", "CheckButton", 0); + theme->set_stylebox(SNAME("normal"), SNAME("CheckButton"), cb_empty); + theme->set_stylebox(SNAME("pressed"), SNAME("CheckButton"), cb_empty); + theme->set_stylebox(SNAME("disabled"), SNAME("CheckButton"), cb_empty); + theme->set_stylebox(SNAME("hover"), SNAME("CheckButton"), cb_empty); + theme->set_stylebox(SNAME("hover_pressed"), SNAME("CheckButton"), cb_empty); + theme->set_stylebox(SNAME("focus"), SNAME("CheckButton"), focus); + + theme->set_icon(SNAME("on"), SNAME("CheckButton"), icons["toggle_on"]); + theme->set_icon(SNAME("on_disabled"), SNAME("CheckButton"), icons["toggle_on_disabled"]); + theme->set_icon(SNAME("off"), SNAME("CheckButton"), icons["toggle_off"]); + theme->set_icon(SNAME("off_disabled"), SNAME("CheckButton"), icons["toggle_off_disabled"]); + + theme->set_icon(SNAME("on_mirrored"), SNAME("CheckButton"), icons["toggle_on_mirrored"]); + theme->set_icon(SNAME("on_disabled_mirrored"), SNAME("CheckButton"), icons["toggle_on_disabled_mirrored"]); + theme->set_icon(SNAME("off_mirrored"), SNAME("CheckButton"), icons["toggle_off_mirrored"]); + theme->set_icon(SNAME("off_disabled_mirrored"), SNAME("CheckButton"), icons["toggle_off_disabled_mirrored"]); + + theme->set_font(SNAME("font"), SNAME("CheckButton"), Ref<Font>()); + theme->set_font_size(SNAME("font_size"), SNAME("CheckButton"), -1); + + theme->set_color(SNAME("font_color"), SNAME("CheckButton"), control_font_color); + theme->set_color(SNAME("font_pressed_color"), SNAME("CheckButton"), control_font_pressed_color); + theme->set_color(SNAME("font_hover_color"), SNAME("CheckButton"), control_font_hover_color); + theme->set_color(SNAME("font_hover_pressed_color"), SNAME("CheckButton"), control_font_pressed_color); + theme->set_color(SNAME("font_focus_color"), SNAME("CheckButton"), control_font_focus_color); + theme->set_color(SNAME("font_disabled_color"), SNAME("CheckButton"), control_font_disabled_color); + theme->set_color(SNAME("font_outline_color"), SNAME("CheckButton"), Color(1, 1, 1)); + + theme->set_constant(SNAME("hseparation"), SNAME("CheckButton"), 4 * scale); + theme->set_constant(SNAME("check_vadjust"), SNAME("CheckButton"), 0 * scale); + theme->set_constant(SNAME("outline_size"), SNAME("CheckButton"), 0); // Label - theme->set_stylebox("normal", "Label", memnew(StyleBoxEmpty)); - theme->set_font("font", "Label", Ref<Font>()); - theme->set_font_size("font_size", "Label", -1); + theme->set_stylebox(SNAME("normal"), SNAME("Label"), memnew(StyleBoxEmpty)); + theme->set_font(SNAME("font"), SNAME("Label"), Ref<Font>()); + theme->set_font_size(SNAME("font_size"), SNAME("Label"), -1); - theme->set_color("font_color", "Label", Color(1, 1, 1)); - theme->set_color("font_shadow_color", "Label", Color(0, 0, 0, 0)); - theme->set_color("font_outline_color", "Label", Color(1, 1, 1)); + theme->set_color(SNAME("font_color"), SNAME("Label"), Color(1, 1, 1)); + theme->set_color(SNAME("font_shadow_color"), SNAME("Label"), Color(0, 0, 0, 0)); + theme->set_color(SNAME("font_outline_color"), SNAME("Label"), Color(1, 1, 1)); - theme->set_constant("shadow_offset_x", "Label", 1 * scale); - theme->set_constant("shadow_offset_y", "Label", 1 * scale); - theme->set_constant("outline_size", "Label", 0); - theme->set_constant("shadow_outline_size", "Label", 1 * scale); - theme->set_constant("line_spacing", "Label", 3 * scale); + theme->set_constant(SNAME("shadow_offset_x"), SNAME("Label"), 1 * scale); + theme->set_constant(SNAME("shadow_offset_y"), SNAME("Label"), 1 * scale); + theme->set_constant(SNAME("outline_size"), SNAME("Label"), 0); + theme->set_constant(SNAME("shadow_outline_size"), SNAME("Label"), 1 * scale); + theme->set_constant(SNAME("line_spacing"), SNAME("Label"), 3 * scale); - theme->set_type_variation("HeaderSmall", "Label"); - theme->set_font_size("font_size", "HeaderSmall", default_font_size + 4); + theme->set_type_variation(SNAME("HeaderSmall"), SNAME("Label")); + theme->set_font_size(SNAME("font_size"), SNAME("HeaderSmall"), default_font_size + 4); - theme->set_type_variation("HeaderMedium", "Label"); - theme->set_font_size("font_size", "HeaderMedium", default_font_size + 8); + theme->set_type_variation(SNAME("HeaderMedium"), SNAME("Label")); + theme->set_font_size(SNAME("font_size"), SNAME("HeaderMedium"), default_font_size + 8); - theme->set_type_variation("HeaderLarge", "Label"); - theme->set_font_size("font_size", "HeaderLarge", default_font_size + 12); + theme->set_type_variation(SNAME("HeaderLarge"), SNAME("Label")); + theme->set_font_size(SNAME("font_size"), SNAME("HeaderLarge"), default_font_size + 12); // LineEdit @@ -370,129 +370,129 @@ void fill_default_theme(Ref<Theme> &theme, const Ref<Font> &default_font, Ref<Te // Add a line at the bottom to make LineEdits distinguishable from Buttons. style_line_edit->set_border_width(SIDE_BOTTOM, 2); style_line_edit->set_border_color(style_pressed_color); - theme->set_stylebox("normal", "LineEdit", style_line_edit); + theme->set_stylebox(SNAME("normal"), SNAME("LineEdit"), style_line_edit); - theme->set_stylebox("focus", "LineEdit", focus); + theme->set_stylebox(SNAME("focus"), SNAME("LineEdit"), focus); Ref<StyleBoxFlat> style_line_edit_read_only = make_flat_stylebox(style_disabled_color); // Add a line at the bottom to make LineEdits distinguishable from Buttons. style_line_edit_read_only->set_border_width(SIDE_BOTTOM, 2); style_line_edit_read_only->set_border_color(style_pressed_color * Color(1, 1, 1, 0.5)); - theme->set_stylebox("read_only", "LineEdit", style_line_edit_read_only); + theme->set_stylebox(SNAME("read_only"), SNAME("LineEdit"), style_line_edit_read_only); - theme->set_font("font", "LineEdit", Ref<Font>()); - theme->set_font_size("font_size", "LineEdit", -1); + theme->set_font(SNAME("font"), SNAME("LineEdit"), Ref<Font>()); + theme->set_font_size(SNAME("font_size"), SNAME("LineEdit"), -1); - theme->set_color("font_color", "LineEdit", control_font_color); - theme->set_color("font_selected_color", "LineEdit", control_font_pressed_color); - theme->set_color("font_uneditable_color", "LineEdit", control_font_disabled_color); - theme->set_color("font_placeholder_color", "LineEdit", control_font_placeholder_color); - theme->set_color("font_outline_color", "LineEdit", Color(1, 1, 1)); - theme->set_color("caret_color", "LineEdit", control_font_hover_color); - theme->set_color("selection_color", "LineEdit", control_selection_color); - theme->set_color("clear_button_color", "LineEdit", control_font_color); - theme->set_color("clear_button_color_pressed", "LineEdit", control_font_pressed_color); + theme->set_color(SNAME("font_color"), SNAME("LineEdit"), control_font_color); + theme->set_color(SNAME("font_selected_color"), SNAME("LineEdit"), control_font_pressed_color); + theme->set_color(SNAME("font_uneditable_color"), SNAME("LineEdit"), control_font_disabled_color); + theme->set_color(SNAME("font_placeholder_color"), SNAME("LineEdit"), control_font_placeholder_color); + theme->set_color(SNAME("font_outline_color"), SNAME("LineEdit"), Color(1, 1, 1)); + theme->set_color(SNAME("caret_color"), SNAME("LineEdit"), control_font_hover_color); + theme->set_color(SNAME("selection_color"), SNAME("LineEdit"), control_selection_color); + theme->set_color(SNAME("clear_button_color"), SNAME("LineEdit"), control_font_color); + theme->set_color(SNAME("clear_button_color_pressed"), SNAME("LineEdit"), control_font_pressed_color); - theme->set_constant("minimum_character_width", "LineEdit", 4); - theme->set_constant("outline_size", "LineEdit", 0); - theme->set_constant("caret_width", "LineEdit", 1); + theme->set_constant(SNAME("minimum_character_width"), SNAME("LineEdit"), 4); + theme->set_constant(SNAME("outline_size"), SNAME("LineEdit"), 0); + theme->set_constant(SNAME("caret_width"), SNAME("LineEdit"), 1); - theme->set_icon("clear", "LineEdit", icons["line_edit_clear"]); + theme->set_icon(SNAME("clear"), SNAME("LineEdit"), icons["line_edit_clear"]); // ProgressBar - theme->set_stylebox("bg", "ProgressBar", make_flat_stylebox(style_disabled_color, 2, 2, 2, 2, 6)); - theme->set_stylebox("fg", "ProgressBar", make_flat_stylebox(style_progress_color, 2, 2, 2, 2, 6)); + theme->set_stylebox(SNAME("bg"), SNAME("ProgressBar"), make_flat_stylebox(style_disabled_color, 2, 2, 2, 2, 6)); + theme->set_stylebox(SNAME("fg"), SNAME("ProgressBar"), make_flat_stylebox(style_progress_color, 2, 2, 2, 2, 6)); - theme->set_font("font", "ProgressBar", Ref<Font>()); - theme->set_font_size("font_size", "ProgressBar", -1); + theme->set_font(SNAME("font"), SNAME("ProgressBar"), Ref<Font>()); + theme->set_font_size(SNAME("font_size"), SNAME("ProgressBar"), -1); - theme->set_color("font_color", "ProgressBar", control_font_hover_color); - theme->set_color("font_shadow_color", "ProgressBar", Color(0, 0, 0)); - theme->set_color("font_outline_color", "ProgressBar", Color(1, 1, 1)); + theme->set_color(SNAME("font_color"), SNAME("ProgressBar"), control_font_hover_color); + theme->set_color(SNAME("font_shadow_color"), SNAME("ProgressBar"), Color(0, 0, 0)); + theme->set_color(SNAME("font_outline_color"), SNAME("ProgressBar"), Color(1, 1, 1)); - theme->set_constant("outline_size", "ProgressBar", 0); + theme->set_constant(SNAME("outline_size"), SNAME("ProgressBar"), 0); // TextEdit - theme->set_stylebox("normal", "TextEdit", style_line_edit); - theme->set_stylebox("focus", "TextEdit", focus); - theme->set_stylebox("read_only", "TextEdit", style_line_edit_read_only); - - theme->set_icon("tab", "TextEdit", icons["text_edit_tab"]); - theme->set_icon("space", "TextEdit", icons["text_edit_space"]); - - theme->set_font("font", "TextEdit", Ref<Font>()); - theme->set_font_size("font_size", "TextEdit", -1); - - theme->set_color("background_color", "TextEdit", Color(0, 0, 0, 0)); - theme->set_color("font_color", "TextEdit", control_font_color); - theme->set_color("font_selected_color", "TextEdit", control_font_pressed_color); - theme->set_color("font_readonly_color", "TextEdit", control_font_disabled_color); - theme->set_color("font_placeholder_color", "TextEdit", control_font_placeholder_color); - theme->set_color("font_outline_color", "TextEdit", Color(1, 1, 1)); - theme->set_color("selection_color", "TextEdit", control_selection_color); - theme->set_color("current_line_color", "TextEdit", Color(0.25, 0.25, 0.26, 0.8)); - theme->set_color("caret_color", "TextEdit", control_font_color); - theme->set_color("caret_background_color", "TextEdit", Color(0, 0, 0)); - theme->set_color("word_highlighted_color", "TextEdit", Color(0.5, 0.5, 0.5, 0.25)); - theme->set_color("search_result_color", "TextEdit", Color(0.3, 0.3, 0.3)); - theme->set_color("search_result_border_color", "TextEdit", Color(0.3, 0.3, 0.3, 0.4)); - - theme->set_constant("line_spacing", "TextEdit", 4 * scale); - theme->set_constant("outline_size", "TextEdit", 0); - theme->set_constant("caret_width", "TextEdit", 1); + theme->set_stylebox(SNAME("normal"), SNAME("TextEdit"), style_line_edit); + theme->set_stylebox(SNAME("focus"), SNAME("TextEdit"), focus); + theme->set_stylebox(SNAME("read_only"), SNAME("TextEdit"), style_line_edit_read_only); + + theme->set_icon(SNAME("tab"), SNAME("TextEdit"), icons["text_edit_tab"]); + theme->set_icon(SNAME("space"), SNAME("TextEdit"), icons["text_edit_space"]); + + theme->set_font(SNAME("font"), SNAME("TextEdit"), Ref<Font>()); + theme->set_font_size(SNAME("font_size"), SNAME("TextEdit"), -1); + + theme->set_color(SNAME("background_color"), SNAME("TextEdit"), Color(0, 0, 0, 0)); + theme->set_color(SNAME("font_color"), SNAME("TextEdit"), control_font_color); + theme->set_color(SNAME("font_selected_color"), SNAME("TextEdit"), control_font_pressed_color); + theme->set_color(SNAME("font_readonly_color"), SNAME("TextEdit"), control_font_disabled_color); + theme->set_color(SNAME("font_placeholder_color"), SNAME("TextEdit"), control_font_placeholder_color); + theme->set_color(SNAME("font_outline_color"), SNAME("TextEdit"), Color(1, 1, 1)); + theme->set_color(SNAME("selection_color"), SNAME("TextEdit"), control_selection_color); + theme->set_color(SNAME("current_line_color"), SNAME("TextEdit"), Color(0.25, 0.25, 0.26, 0.8)); + theme->set_color(SNAME("caret_color"), SNAME("TextEdit"), control_font_color); + theme->set_color(SNAME("caret_background_color"), SNAME("TextEdit"), Color(0, 0, 0)); + theme->set_color(SNAME("word_highlighted_color"), SNAME("TextEdit"), Color(0.5, 0.5, 0.5, 0.25)); + theme->set_color(SNAME("search_result_color"), SNAME("TextEdit"), Color(0.3, 0.3, 0.3)); + theme->set_color(SNAME("search_result_border_color"), SNAME("TextEdit"), Color(0.3, 0.3, 0.3, 0.4)); + + theme->set_constant(SNAME("line_spacing"), SNAME("TextEdit"), 4 * scale); + theme->set_constant(SNAME("outline_size"), SNAME("TextEdit"), 0); + theme->set_constant(SNAME("caret_width"), SNAME("TextEdit"), 1); // CodeEdit - theme->set_stylebox("normal", "CodeEdit", style_line_edit); - theme->set_stylebox("focus", "CodeEdit", focus); - theme->set_stylebox("read_only", "CodeEdit", style_line_edit_read_only); - theme->set_stylebox("completion", "CodeEdit", make_flat_stylebox(style_normal_color, 0, 0, 0, 0)); - - theme->set_icon("tab", "CodeEdit", icons["text_edit_tab"]); - theme->set_icon("space", "CodeEdit", icons["text_edit_space"]); - theme->set_icon("breakpoint", "CodeEdit", icons["breakpoint"]); - theme->set_icon("bookmark", "CodeEdit", icons["bookmark"]); - theme->set_icon("executing_line", "CodeEdit", icons["arrow_right"]); - theme->set_icon("can_fold", "CodeEdit", icons["arrow_down"]); - theme->set_icon("folded", "CodeEdit", icons["arrow_right"]); - theme->set_icon("folded_eol_icon", "CodeEdit", icons["text_edit_ellipsis"]); - - theme->set_font("font", "CodeEdit", Ref<Font>()); - theme->set_font_size("font_size", "CodeEdit", -1); - - theme->set_color("background_color", "CodeEdit", Color(0, 0, 0, 0)); - theme->set_color("completion_background_color", "CodeEdit", Color(0.17, 0.16, 0.2)); - theme->set_color("completion_selected_color", "CodeEdit", Color(0.26, 0.26, 0.27)); - theme->set_color("completion_existing_color", "CodeEdit", Color(0.87, 0.87, 0.87, 0.13)); - theme->set_color("completion_scroll_color", "CodeEdit", control_font_pressed_color); - theme->set_color("completion_font_color", "CodeEdit", Color(0.67, 0.67, 0.67)); - theme->set_color("font_color", "CodeEdit", control_font_color); - theme->set_color("font_selected_color", "CodeEdit", Color(0, 0, 0)); - theme->set_color("font_readonly_color", "CodeEdit", Color(control_font_color.r, control_font_color.g, control_font_color.b, 0.5f)); - theme->set_color("font_placeholder_color", "CodeEdit", control_font_placeholder_color); - theme->set_color("font_outline_color", "CodeEdit", Color(1, 1, 1)); - theme->set_color("selection_color", "CodeEdit", control_selection_color); - theme->set_color("bookmark_color", "CodeEdit", Color(0.5, 0.64, 1, 0.8)); - theme->set_color("breakpoint_color", "CodeEdit", Color(0.9, 0.29, 0.3)); - theme->set_color("executing_line_color", "CodeEdit", Color(0.98, 0.89, 0.27)); - theme->set_color("current_line_color", "CodeEdit", Color(0.25, 0.25, 0.26, 0.8)); - theme->set_color("code_folding_color", "CodeEdit", Color(0.8, 0.8, 0.8, 0.8)); - theme->set_color("caret_color", "CodeEdit", control_font_color); - theme->set_color("caret_background_color", "CodeEdit", Color(0, 0, 0)); - theme->set_color("brace_mismatch_color", "CodeEdit", Color(1, 0.2, 0.2)); - theme->set_color("line_number_color", "CodeEdit", Color(0.67, 0.67, 0.67, 0.4)); - theme->set_color("word_highlighted_color", "CodeEdit", Color(0.8, 0.9, 0.9, 0.15)); - theme->set_color("line_length_guideline_color", "CodeEdit", Color(0.3, 0.5, 0.8, 0.1)); - theme->set_color("search_result_color", "CodeEdit", Color(0.3, 0.3, 0.3)); - theme->set_color("search_result_border_color", "CodeEdit", Color(0.3, 0.3, 0.3, 0.4)); - - theme->set_constant("completion_lines", "CodeEdit", 7); - theme->set_constant("completion_max_width", "CodeEdit", 50); - theme->set_constant("completion_scroll_width", "CodeEdit", 3); - theme->set_constant("line_spacing", "CodeEdit", 4 * scale); - theme->set_constant("outline_size", "CodeEdit", 0); + theme->set_stylebox(SNAME("normal"), SNAME("CodeEdit"), style_line_edit); + theme->set_stylebox(SNAME("focus"), SNAME("CodeEdit"), focus); + theme->set_stylebox(SNAME("read_only"), SNAME("CodeEdit"), style_line_edit_read_only); + theme->set_stylebox(SNAME("completion"), SNAME("CodeEdit"), make_flat_stylebox(style_normal_color, 0, 0, 0, 0)); + + theme->set_icon(SNAME("tab"), SNAME("CodeEdit"), icons["text_edit_tab"]); + theme->set_icon(SNAME("space"), SNAME("CodeEdit"), icons["text_edit_space"]); + theme->set_icon(SNAME("breakpoint"), SNAME("CodeEdit"), icons["breakpoint"]); + theme->set_icon(SNAME("bookmark"), SNAME("CodeEdit"), icons["bookmark"]); + theme->set_icon(SNAME("executing_line"), SNAME("CodeEdit"), icons["arrow_right"]); + theme->set_icon(SNAME("can_fold"), SNAME("CodeEdit"), icons["arrow_down"]); + theme->set_icon(SNAME("folded"), SNAME("CodeEdit"), icons["arrow_right"]); + theme->set_icon(SNAME("folded_eol_icon"), SNAME("CodeEdit"), icons["text_edit_ellipsis"]); + + theme->set_font(SNAME("font"), SNAME("CodeEdit"), Ref<Font>()); + theme->set_font_size(SNAME("font_size"), SNAME("CodeEdit"), -1); + + theme->set_color(SNAME("background_color"), SNAME("CodeEdit"), Color(0, 0, 0, 0)); + theme->set_color(SNAME("completion_background_color"), SNAME("CodeEdit"), Color(0.17, 0.16, 0.2)); + theme->set_color(SNAME("completion_selected_color"), SNAME("CodeEdit"), Color(0.26, 0.26, 0.27)); + theme->set_color(SNAME("completion_existing_color"), SNAME("CodeEdit"), Color(0.87, 0.87, 0.87, 0.13)); + theme->set_color(SNAME("completion_scroll_color"), SNAME("CodeEdit"), control_font_pressed_color); + theme->set_color(SNAME("completion_font_color"), SNAME("CodeEdit"), Color(0.67, 0.67, 0.67)); + theme->set_color(SNAME("font_color"), SNAME("CodeEdit"), control_font_color); + theme->set_color(SNAME("font_selected_color"), SNAME("CodeEdit"), Color(0, 0, 0)); + theme->set_color(SNAME("font_readonly_color"), SNAME("CodeEdit"), Color(control_font_color.r, control_font_color.g, control_font_color.b, 0.5f)); + theme->set_color(SNAME("font_placeholder_color"), SNAME("CodeEdit"), control_font_placeholder_color); + theme->set_color(SNAME("font_outline_color"), SNAME("CodeEdit"), Color(1, 1, 1)); + theme->set_color(SNAME("selection_color"), SNAME("CodeEdit"), control_selection_color); + theme->set_color(SNAME("bookmark_color"), SNAME("CodeEdit"), Color(0.5, 0.64, 1, 0.8)); + theme->set_color(SNAME("breakpoint_color"), SNAME("CodeEdit"), Color(0.9, 0.29, 0.3)); + theme->set_color(SNAME("executing_line_color"), SNAME("CodeEdit"), Color(0.98, 0.89, 0.27)); + theme->set_color(SNAME("current_line_color"), SNAME("CodeEdit"), Color(0.25, 0.25, 0.26, 0.8)); + theme->set_color(SNAME("code_folding_color"), SNAME("CodeEdit"), Color(0.8, 0.8, 0.8, 0.8)); + theme->set_color(SNAME("caret_color"), SNAME("CodeEdit"), control_font_color); + theme->set_color(SNAME("caret_background_color"), SNAME("CodeEdit"), Color(0, 0, 0)); + theme->set_color(SNAME("brace_mismatch_color"), SNAME("CodeEdit"), Color(1, 0.2, 0.2)); + theme->set_color(SNAME("line_number_color"), SNAME("CodeEdit"), Color(0.67, 0.67, 0.67, 0.4)); + theme->set_color(SNAME("word_highlighted_color"), SNAME("CodeEdit"), Color(0.8, 0.9, 0.9, 0.15)); + theme->set_color(SNAME("line_length_guideline_color"), SNAME("CodeEdit"), Color(0.3, 0.5, 0.8, 0.1)); + theme->set_color(SNAME("search_result_color"), SNAME("CodeEdit"), Color(0.3, 0.3, 0.3)); + theme->set_color(SNAME("search_result_border_color"), SNAME("CodeEdit"), Color(0.3, 0.3, 0.3, 0.4)); + + theme->set_constant(SNAME("completion_lines"), SNAME("CodeEdit"), 7); + theme->set_constant(SNAME("completion_max_width"), SNAME("CodeEdit"), 50); + theme->set_constant(SNAME("completion_scroll_width"), SNAME("CodeEdit"), 3); + theme->set_constant(SNAME("line_spacing"), SNAME("CodeEdit"), 4 * scale); + theme->set_constant(SNAME("outline_size"), SNAME("CodeEdit"), 0); Ref<Texture2D> empty_icon = memnew(ImageTexture); @@ -503,33 +503,33 @@ void fill_default_theme(Ref<Theme> &theme, const Ref<Font> &default_font, Ref<Te // HScrollBar - theme->set_stylebox("scroll", "HScrollBar", style_scrollbar); - theme->set_stylebox("scroll_focus", "HScrollBar", focus); - theme->set_stylebox("grabber", "HScrollBar", style_scrollbar_grabber); - theme->set_stylebox("grabber_highlight", "HScrollBar", style_scrollbar_grabber_highlight); - theme->set_stylebox("grabber_pressed", "HScrollBar", style_scrollbar_grabber_pressed); + theme->set_stylebox(SNAME("scroll"), SNAME("HScrollBar"), style_scrollbar); + theme->set_stylebox(SNAME("scroll_focus"), SNAME("HScrollBar"), focus); + theme->set_stylebox(SNAME("grabber"), SNAME("HScrollBar"), style_scrollbar_grabber); + theme->set_stylebox(SNAME("grabber_highlight"), SNAME("HScrollBar"), style_scrollbar_grabber_highlight); + theme->set_stylebox(SNAME("grabber_pressed"), SNAME("HScrollBar"), style_scrollbar_grabber_pressed); - theme->set_icon("increment", "HScrollBar", empty_icon); - theme->set_icon("increment_highlight", "HScrollBar", empty_icon); - theme->set_icon("increment_pressed", "HScrollBar", empty_icon); - theme->set_icon("decrement", "HScrollBar", empty_icon); - theme->set_icon("decrement_highlight", "HScrollBar", empty_icon); - theme->set_icon("decrement_pressed", "HScrollBar", empty_icon); + theme->set_icon(SNAME("increment"), SNAME("HScrollBar"), empty_icon); + theme->set_icon(SNAME("increment_highlight"), SNAME("HScrollBar"), empty_icon); + theme->set_icon(SNAME("increment_pressed"), SNAME("HScrollBar"), empty_icon); + theme->set_icon(SNAME("decrement"), SNAME("HScrollBar"), empty_icon); + theme->set_icon(SNAME("decrement_highlight"), SNAME("HScrollBar"), empty_icon); + theme->set_icon(SNAME("decrement_pressed"), SNAME("HScrollBar"), empty_icon); // VScrollBar - theme->set_stylebox("scroll", "VScrollBar", style_scrollbar); - theme->set_stylebox("scroll_focus", "VScrollBar", focus); - theme->set_stylebox("grabber", "VScrollBar", style_scrollbar_grabber); - theme->set_stylebox("grabber_highlight", "VScrollBar", style_scrollbar_grabber_highlight); - theme->set_stylebox("grabber_pressed", "VScrollBar", style_scrollbar_grabber_pressed); + theme->set_stylebox(SNAME("scroll"), SNAME("VScrollBar"), style_scrollbar); + theme->set_stylebox(SNAME("scroll_focus"), SNAME("VScrollBar"), focus); + theme->set_stylebox(SNAME("grabber"), SNAME("VScrollBar"), style_scrollbar_grabber); + theme->set_stylebox(SNAME("grabber_highlight"), SNAME("VScrollBar"), style_scrollbar_grabber_highlight); + theme->set_stylebox(SNAME("grabber_pressed"), SNAME("VScrollBar"), style_scrollbar_grabber_pressed); - theme->set_icon("increment", "VScrollBar", empty_icon); - theme->set_icon("increment_highlight", "VScrollBar", empty_icon); - theme->set_icon("increment_pressed", "VScrollBar", empty_icon); - theme->set_icon("decrement", "VScrollBar", empty_icon); - theme->set_icon("decrement_highlight", "VScrollBar", empty_icon); - theme->set_icon("decrement_pressed", "VScrollBar", empty_icon); + theme->set_icon(SNAME("increment"), SNAME("VScrollBar"), empty_icon); + theme->set_icon(SNAME("increment_highlight"), SNAME("VScrollBar"), empty_icon); + theme->set_icon(SNAME("increment_pressed"), SNAME("VScrollBar"), empty_icon); + theme->set_icon(SNAME("decrement"), SNAME("VScrollBar"), empty_icon); + theme->set_icon(SNAME("decrement_highlight"), SNAME("VScrollBar"), empty_icon); + theme->set_icon(SNAME("decrement_pressed"), SNAME("VScrollBar"), empty_icon); const Ref<StyleBoxFlat> style_slider = make_flat_stylebox(style_normal_color, 4, 4, 4, 4, 4); const Ref<StyleBoxFlat> style_slider_grabber = make_flat_stylebox(style_progress_color, 4, 4, 4, 4, 4); @@ -537,83 +537,83 @@ void fill_default_theme(Ref<Theme> &theme, const Ref<Font> &default_font, Ref<Te // HSlider - theme->set_stylebox("slider", "HSlider", style_slider); - theme->set_stylebox("grabber_area", "HSlider", style_slider_grabber); - theme->set_stylebox("grabber_area_highlight", "HSlider", style_slider_grabber_highlight); + theme->set_stylebox(SNAME("slider"), SNAME("HSlider"), style_slider); + theme->set_stylebox(SNAME("grabber_area"), SNAME("HSlider"), style_slider_grabber); + theme->set_stylebox(SNAME("grabber_area_highlight"), SNAME("HSlider"), style_slider_grabber_highlight); - theme->set_icon("grabber", "HSlider", icons["slider_grabber"]); - theme->set_icon("grabber_highlight", "HSlider", icons["slider_grabber_hl"]); - theme->set_icon("grabber_disabled", "HSlider", icons["slider_grabber_disabled"]); - theme->set_icon("tick", "HSlider", icons["hslider_tick"]); + theme->set_icon(SNAME("grabber"), SNAME("HSlider"), icons["slider_grabber"]); + theme->set_icon(SNAME("grabber_highlight"), SNAME("HSlider"), icons["slider_grabber_hl"]); + theme->set_icon(SNAME("grabber_disabled"), SNAME("HSlider"), icons["slider_grabber_disabled"]); + theme->set_icon(SNAME("tick"), SNAME("HSlider"), icons["hslider_tick"]); // VSlider - theme->set_stylebox("slider", "VSlider", style_slider); - theme->set_stylebox("grabber_area", "VSlider", style_slider_grabber); - theme->set_stylebox("grabber_area_highlight", "VSlider", style_slider_grabber_highlight); + theme->set_stylebox(SNAME("slider"), SNAME("VSlider"), style_slider); + theme->set_stylebox(SNAME("grabber_area"), SNAME("VSlider"), style_slider_grabber); + theme->set_stylebox(SNAME("grabber_area_highlight"), SNAME("VSlider"), style_slider_grabber_highlight); - theme->set_icon("grabber", "VSlider", icons["slider_grabber"]); - theme->set_icon("grabber_highlight", "VSlider", icons["slider_grabber_hl"]); - theme->set_icon("grabber_disabled", "VSlider", icons["slider_grabber_disabled"]); - theme->set_icon("tick", "VSlider", icons["vslider_tick"]); + theme->set_icon(SNAME("grabber"), SNAME("VSlider"), icons["slider_grabber"]); + theme->set_icon(SNAME("grabber_highlight"), SNAME("VSlider"), icons["slider_grabber_hl"]); + theme->set_icon(SNAME("grabber_disabled"), SNAME("VSlider"), icons["slider_grabber_disabled"]); + theme->set_icon(SNAME("tick"), SNAME("VSlider"), icons["vslider_tick"]); // SpinBox - theme->set_icon("updown", "SpinBox", icons["updown"]); + theme->set_icon(SNAME("updown"), SNAME("SpinBox"), icons["updown"]); // ScrollContainer Ref<StyleBoxEmpty> empty; empty.instantiate(); - theme->set_stylebox("bg", "ScrollContainer", empty); + theme->set_stylebox(SNAME("bg"), SNAME("ScrollContainer"), empty); // Window - theme->set_stylebox("embedded_border", "Window", sb_expand(make_flat_stylebox(style_popup_color, 10, 28, 10, 8), 8, 32, 8, 6)); - theme->set_constant("scaleborder_size", "Window", 4 * scale); + theme->set_stylebox(SNAME("embedded_border"), SNAME("Window"), sb_expand(make_flat_stylebox(style_popup_color, 10, 28, 10, 8), 8, 32, 8, 6)); + theme->set_constant(SNAME("scaleborder_size"), SNAME("Window"), 4 * scale); - theme->set_font("title_font", "Window", Ref<Font>()); - theme->set_font_size("title_font_size", "Window", -1); - theme->set_color("title_color", "Window", control_font_color); - theme->set_color("title_outline_modulate", "Window", Color(1, 1, 1)); - theme->set_constant("title_outline_size", "Window", 0); - theme->set_constant("title_height", "Window", 36 * scale); - theme->set_constant("resize_margin", "Window", 4 * scale); + theme->set_font(SNAME("title_font"), SNAME("Window"), Ref<Font>()); + theme->set_font_size(SNAME("title_font_size"), SNAME("Window"), -1); + theme->set_color(SNAME("title_color"), SNAME("Window"), control_font_color); + theme->set_color(SNAME("title_outline_modulate"), SNAME("Window"), Color(1, 1, 1)); + theme->set_constant(SNAME("title_outline_size"), SNAME("Window"), 0); + theme->set_constant(SNAME("title_height"), SNAME("Window"), 36 * scale); + theme->set_constant(SNAME("resize_margin"), SNAME("Window"), 4 * scale); - theme->set_icon("close", "Window", icons["close"]); - theme->set_icon("close_pressed", "Window", icons["close_hl"]); - theme->set_constant("close_h_ofs", "Window", 18 * scale); - theme->set_constant("close_v_ofs", "Window", 24 * scale); + theme->set_icon(SNAME("close"), SNAME("Window"), icons["close"]); + theme->set_icon(SNAME("close_pressed"), SNAME("Window"), icons["close_hl"]); + theme->set_constant(SNAME("close_h_ofs"), SNAME("Window"), 18 * scale); + theme->set_constant(SNAME("close_v_ofs"), SNAME("Window"), 24 * scale); // Dialogs - theme->set_constant("margin", "Dialogs", 8 * scale); - theme->set_constant("button_margin", "Dialogs", 32 * scale); + theme->set_constant(SNAME("margin"), SNAME("Dialogs"), 8 * scale); + theme->set_constant(SNAME("button_margin"), SNAME("Dialogs"), 32 * scale); // AcceptDialog - theme->set_stylebox("panel", "AcceptDialog", make_flat_stylebox(style_popup_color, 0, 0, 0, 0)); + theme->set_stylebox(SNAME("panel"), SNAME("AcceptDialog"), make_flat_stylebox(style_popup_color, 0, 0, 0, 0)); // File Dialog - theme->set_icon("parent_folder", "FileDialog", icons["folder_up"]); - theme->set_icon("back_folder", "FileDialog", icons["arrow_left"]); - theme->set_icon("forward_folder", "FileDialog", icons["arrow_right"]); - theme->set_icon("reload", "FileDialog", icons["reload"]); - theme->set_icon("toggle_hidden", "FileDialog", icons["visibility_visible"]); - theme->set_icon("folder", "FileDialog", icons["folder"]); - theme->set_icon("file", "FileDialog", icons["file"]); - theme->set_color("folder_icon_modulate", "FileDialog", Color(1, 1, 1)); - theme->set_color("file_icon_modulate", "FileDialog", Color(1, 1, 1)); - theme->set_color("files_disabled", "FileDialog", Color(0, 0, 0, 0.7)); + theme->set_icon(SNAME("parent_folder"), SNAME("FileDialog"), icons["folder_up"]); + theme->set_icon(SNAME("back_folder"), SNAME("FileDialog"), icons["arrow_left"]); + theme->set_icon(SNAME("forward_folder"), SNAME("FileDialog"), icons["arrow_right"]); + theme->set_icon(SNAME("reload"), SNAME("FileDialog"), icons["reload"]); + theme->set_icon(SNAME("toggle_hidden"), SNAME("FileDialog"), icons["visibility_visible"]); + theme->set_icon(SNAME("folder"), SNAME("FileDialog"), icons["folder"]); + theme->set_icon(SNAME("file"), SNAME("FileDialog"), icons["file"]); + theme->set_color(SNAME("folder_icon_modulate"), SNAME("FileDialog"), Color(1, 1, 1)); + theme->set_color(SNAME("file_icon_modulate"), SNAME("FileDialog"), Color(1, 1, 1)); + theme->set_color(SNAME("files_disabled"), SNAME("FileDialog"), Color(0, 0, 0, 0.7)); // Popup - theme->set_stylebox("panel", "PopupPanel", make_flat_stylebox(style_normal_color)); + theme->set_stylebox(SNAME("panel"), SNAME("PopupPanel"), make_flat_stylebox(style_normal_color)); // PopupDialog - theme->set_stylebox("panel", "PopupDialog", make_flat_stylebox(style_normal_color)); + theme->set_stylebox(SNAME("panel"), SNAME("PopupDialog"), make_flat_stylebox(style_normal_color)); // PopupMenu @@ -638,35 +638,35 @@ void fill_default_theme(Ref<Theme> &theme, const Ref<Font> &default_font, Ref<Te Ref<StyleBoxFlat> style_popup_panel_disabled = style_popup_panel->duplicate(); style_popup_panel_disabled->set_bg_color(style_disabled_color); - theme->set_stylebox("panel", "PopupMenu", style_popup_panel); - theme->set_stylebox("panel_disabled", "PopupMenu", style_popup_panel_disabled); - theme->set_stylebox("hover", "PopupMenu", make_flat_stylebox(style_popup_hover_color)); - theme->set_stylebox("separator", "PopupMenu", separator_horizontal); - theme->set_stylebox("labeled_separator_left", "PopupMenu", separator_horizontal); - theme->set_stylebox("labeled_separator_right", "PopupMenu", separator_horizontal); - - theme->set_icon("checked", "PopupMenu", icons["checked"]); - theme->set_icon("unchecked", "PopupMenu", icons["unchecked"]); - theme->set_icon("radio_checked", "PopupMenu", icons["radio_checked"]); - theme->set_icon("radio_unchecked", "PopupMenu", icons["radio_unchecked"]); - theme->set_icon("submenu", "PopupMenu", icons["arrow_right"]); - theme->set_icon("submenu_mirrored", "PopupMenu", icons["arrow_left"]); - - theme->set_font("font", "PopupMenu", Ref<Font>()); - theme->set_font_size("font_size", "PopupMenu", -1); - - theme->set_color("font_color", "PopupMenu", control_font_color); - theme->set_color("font_accelerator_color", "PopupMenu", Color(0.7, 0.7, 0.7, 0.8)); - theme->set_color("font_disabled_color", "PopupMenu", Color(0.4, 0.4, 0.4, 0.8)); - theme->set_color("font_hover_color", "PopupMenu", control_font_color); - theme->set_color("font_separator_color", "PopupMenu", control_font_color); - theme->set_color("font_outline_color", "PopupMenu", Color(1, 1, 1)); - - theme->set_constant("hseparation", "PopupMenu", 4 * scale); - theme->set_constant("vseparation", "PopupMenu", 4 * scale); - theme->set_constant("outline_size", "PopupMenu", 0); - theme->set_constant("item_start_padding", "PopupMenu", 2 * scale); - theme->set_constant("item_end_padding", "PopupMenu", 2 * scale); + theme->set_stylebox(SNAME("panel"), SNAME("PopupMenu"), style_popup_panel); + theme->set_stylebox(SNAME("panel_disabled"), SNAME("PopupMenu"), style_popup_panel_disabled); + theme->set_stylebox(SNAME("hover"), SNAME("PopupMenu"), make_flat_stylebox(style_popup_hover_color)); + theme->set_stylebox(SNAME("separator"), SNAME("PopupMenu"), separator_horizontal); + theme->set_stylebox(SNAME("labeled_separator_left"), SNAME("PopupMenu"), separator_horizontal); + theme->set_stylebox(SNAME("labeled_separator_right"), SNAME("PopupMenu"), separator_horizontal); + + theme->set_icon(SNAME("checked"), SNAME("PopupMenu"), icons["checked"]); + theme->set_icon(SNAME("unchecked"), SNAME("PopupMenu"), icons["unchecked"]); + theme->set_icon(SNAME("radio_checked"), SNAME("PopupMenu"), icons["radio_checked"]); + theme->set_icon(SNAME("radio_unchecked"), SNAME("PopupMenu"), icons["radio_unchecked"]); + theme->set_icon(SNAME("submenu"), SNAME("PopupMenu"), icons["arrow_right"]); + theme->set_icon(SNAME("submenu_mirrored"), SNAME("PopupMenu"), icons["arrow_left"]); + + theme->set_font(SNAME("font"), SNAME("PopupMenu"), Ref<Font>()); + theme->set_font_size(SNAME("font_size"), SNAME("PopupMenu"), -1); + + theme->set_color(SNAME("font_color"), SNAME("PopupMenu"), control_font_color); + theme->set_color(SNAME("font_accelerator_color"), SNAME("PopupMenu"), Color(0.7, 0.7, 0.7, 0.8)); + theme->set_color(SNAME("font_disabled_color"), SNAME("PopupMenu"), Color(0.4, 0.4, 0.4, 0.8)); + theme->set_color(SNAME("font_hover_color"), SNAME("PopupMenu"), control_font_color); + theme->set_color(SNAME("font_separator_color"), SNAME("PopupMenu"), control_font_color); + theme->set_color(SNAME("font_outline_color"), SNAME("PopupMenu"), Color(1, 1, 1)); + + theme->set_constant(SNAME("hseparation"), SNAME("PopupMenu"), 4 * scale); + theme->set_constant(SNAME("vseparation"), SNAME("PopupMenu"), 4 * scale); + theme->set_constant(SNAME("outline_size"), SNAME("PopupMenu"), 0); + theme->set_constant(SNAME("item_start_padding"), SNAME("PopupMenu"), 2 * scale); + theme->set_constant(SNAME("item_end_padding"), SNAME("PopupMenu"), 2 * scale); // GraphNode Ref<StyleBoxFlat> graphnode_normal = make_flat_stylebox(style_normal_color, 18, 42, 18, 12); @@ -683,101 +683,101 @@ void fill_default_theme(Ref<Theme> &theme, const Ref<Font> &default_font, Ref<Te Ref<StyleBoxFlat> graphnode_position = make_flat_stylebox(style_pressed_color, 18, 42, 18, 12, 6, true, 4); graphnode_position->set_border_color(Color(0.98, 0.89, 0.27)); - theme->set_stylebox("frame", "GraphNode", graphnode_normal); - theme->set_stylebox("selectedframe", "GraphNode", graphnode_selected); - theme->set_stylebox("comment", "GraphNode", graphnode_comment_normal); - theme->set_stylebox("commentfocus", "GraphNode", graphnode_comment_selected); - theme->set_stylebox("breakpoint", "GraphNode", graphnode_breakpoint); - theme->set_stylebox("position", "GraphNode", graphnode_position); - - theme->set_icon("port", "GraphNode", icons["graph_port"]); - theme->set_icon("close", "GraphNode", icons["close"]); - theme->set_icon("resizer", "GraphNode", icons["resizer_se"]); - theme->set_font("title_font", "GraphNode", Ref<Font>()); - theme->set_color("title_color", "GraphNode", control_font_color); - theme->set_color("close_color", "GraphNode", control_font_color); - theme->set_color("resizer_color", "GraphNode", control_font_color); - theme->set_constant("separation", "GraphNode", 2 * scale); - theme->set_constant("title_offset", "GraphNode", 26 * scale); - theme->set_constant("close_offset", "GraphNode", 22 * scale); - theme->set_constant("port_offset", "GraphNode", 0); + theme->set_stylebox(SNAME("frame"), SNAME("GraphNode"), graphnode_normal); + theme->set_stylebox(SNAME("selectedframe"), SNAME("GraphNode"), graphnode_selected); + theme->set_stylebox(SNAME("comment"), SNAME("GraphNode"), graphnode_comment_normal); + theme->set_stylebox(SNAME("commentfocus"), SNAME("GraphNode"), graphnode_comment_selected); + theme->set_stylebox(SNAME("breakpoint"), SNAME("GraphNode"), graphnode_breakpoint); + theme->set_stylebox(SNAME("position"), SNAME("GraphNode"), graphnode_position); + + theme->set_icon(SNAME("port"), SNAME("GraphNode"), icons["graph_port"]); + theme->set_icon(SNAME("close"), SNAME("GraphNode"), icons["close"]); + theme->set_icon(SNAME("resizer"), SNAME("GraphNode"), icons["resizer_se"]); + theme->set_font(SNAME("title_font"), SNAME("GraphNode"), Ref<Font>()); + theme->set_color(SNAME("title_color"), SNAME("GraphNode"), control_font_color); + theme->set_color(SNAME("close_color"), SNAME("GraphNode"), control_font_color); + theme->set_color(SNAME("resizer_color"), SNAME("GraphNode"), control_font_color); + theme->set_constant(SNAME("separation"), SNAME("GraphNode"), 2 * scale); + theme->set_constant(SNAME("title_offset"), SNAME("GraphNode"), 26 * scale); + theme->set_constant(SNAME("close_offset"), SNAME("GraphNode"), 22 * scale); + theme->set_constant(SNAME("port_offset"), SNAME("GraphNode"), 0); // Tree - theme->set_stylebox("bg", "Tree", make_flat_stylebox(style_normal_color, 4, 4, 4, 5)); - theme->set_stylebox("bg_focus", "Tree", focus); - theme->set_stylebox("selected", "Tree", make_flat_stylebox(style_selected_color)); - theme->set_stylebox("selected_focus", "Tree", make_flat_stylebox(style_selected_color)); - theme->set_stylebox("cursor", "Tree", focus); - theme->set_stylebox("cursor_unfocused", "Tree", focus); - theme->set_stylebox("button_pressed", "Tree", button_pressed); - theme->set_stylebox("title_button_normal", "Tree", make_flat_stylebox(style_pressed_color, 4, 4, 4, 4)); - theme->set_stylebox("title_button_pressed", "Tree", make_flat_stylebox(style_hover_color, 4, 4, 4, 4)); - theme->set_stylebox("title_button_hover", "Tree", make_flat_stylebox(style_normal_color, 4, 4, 4, 4)); - theme->set_stylebox("custom_button", "Tree", button_normal); - theme->set_stylebox("custom_button_pressed", "Tree", button_pressed); - theme->set_stylebox("custom_button_hover", "Tree", button_hover); - - theme->set_icon("checked", "Tree", icons["checked"]); - theme->set_icon("unchecked", "Tree", icons["unchecked"]); - theme->set_icon("indeterminate", "Tree", icons["indeterminate"]); - theme->set_icon("updown", "Tree", icons["updown"]); - theme->set_icon("select_arrow", "Tree", icons["option_button_arrow"]); - theme->set_icon("arrow", "Tree", icons["arrow_down"]); - theme->set_icon("arrow_collapsed", "Tree", icons["arrow_right"]); - theme->set_icon("arrow_collapsed_mirrored", "Tree", icons["arrow_left"]); - - theme->set_font("title_button_font", "Tree", Ref<Font>()); - theme->set_font("font", "Tree", Ref<Font>()); - theme->set_font_size("font_size", "Tree", -1); - - theme->set_color("title_button_color", "Tree", control_font_color); - theme->set_color("font_color", "Tree", control_font_low_color); - theme->set_color("font_selected_color", "Tree", control_font_pressed_color); - theme->set_color("font_outline_color", "Tree", Color(1, 1, 1)); - theme->set_color("guide_color", "Tree", Color(0.7, 0.7, 0.7, 0.25)); - theme->set_color("drop_position_color", "Tree", Color(1, 0.3, 0.2)); - theme->set_color("relationship_line_color", "Tree", Color(0.27, 0.27, 0.27)); - theme->set_color("parent_hl_line_color", "Tree", Color(0.27, 0.27, 0.27)); - theme->set_color("children_hl_line_color", "Tree", Color(0.27, 0.27, 0.27)); - theme->set_color("custom_button_font_highlight", "Tree", control_font_hover_color); - - theme->set_constant("hseparation", "Tree", 4 * scale); - theme->set_constant("vseparation", "Tree", 4 * scale); - theme->set_constant("item_margin", "Tree", 16 * scale); - theme->set_constant("button_margin", "Tree", 4 * scale); - theme->set_constant("draw_relationship_lines", "Tree", 0); - theme->set_constant("relationship_line_width", "Tree", 1); - theme->set_constant("parent_hl_line_width", "Tree", 1); - theme->set_constant("children_hl_line_width", "Tree", 1); - theme->set_constant("parent_hl_line_margin", "Tree", 0); - theme->set_constant("draw_guides", "Tree", 1); - theme->set_constant("scroll_border", "Tree", 4); - theme->set_constant("scroll_speed", "Tree", 12); - theme->set_constant("outline_size", "Tree", 0); + theme->set_stylebox(SNAME("bg"), SNAME("Tree"), make_flat_stylebox(style_normal_color, 4, 4, 4, 5)); + theme->set_stylebox(SNAME("bg_focus"), SNAME("Tree"), focus); + theme->set_stylebox(SNAME("selected"), SNAME("Tree"), make_flat_stylebox(style_selected_color)); + theme->set_stylebox(SNAME("selected_focus"), SNAME("Tree"), make_flat_stylebox(style_selected_color)); + theme->set_stylebox(SNAME("cursor"), SNAME("Tree"), focus); + theme->set_stylebox(SNAME("cursor_unfocused"), SNAME("Tree"), focus); + theme->set_stylebox(SNAME("button_pressed"), SNAME("Tree"), button_pressed); + theme->set_stylebox(SNAME("title_button_normal"), SNAME("Tree"), make_flat_stylebox(style_pressed_color, 4, 4, 4, 4)); + theme->set_stylebox(SNAME("title_button_pressed"), SNAME("Tree"), make_flat_stylebox(style_hover_color, 4, 4, 4, 4)); + theme->set_stylebox(SNAME("title_button_hover"), SNAME("Tree"), make_flat_stylebox(style_normal_color, 4, 4, 4, 4)); + theme->set_stylebox(SNAME("custom_button"), SNAME("Tree"), button_normal); + theme->set_stylebox(SNAME("custom_button_pressed"), SNAME("Tree"), button_pressed); + theme->set_stylebox(SNAME("custom_button_hover"), SNAME("Tree"), button_hover); + + theme->set_icon(SNAME("checked"), SNAME("Tree"), icons["checked"]); + theme->set_icon(SNAME("unchecked"), SNAME("Tree"), icons["unchecked"]); + theme->set_icon(SNAME("indeterminate"), SNAME("Tree"), icons["indeterminate"]); + theme->set_icon(SNAME("updown"), SNAME("Tree"), icons["updown"]); + theme->set_icon(SNAME("select_arrow"), SNAME("Tree"), icons["option_button_arrow"]); + theme->set_icon(SNAME("arrow"), SNAME("Tree"), icons["arrow_down"]); + theme->set_icon(SNAME("arrow_collapsed"), SNAME("Tree"), icons["arrow_right"]); + theme->set_icon(SNAME("arrow_collapsed_mirrored"), SNAME("Tree"), icons["arrow_left"]); + + theme->set_font(SNAME("title_button_font"), SNAME("Tree"), Ref<Font>()); + theme->set_font(SNAME("font"), SNAME("Tree"), Ref<Font>()); + theme->set_font_size(SNAME("font_size"), SNAME("Tree"), -1); + + theme->set_color(SNAME("title_button_color"), SNAME("Tree"), control_font_color); + theme->set_color(SNAME("font_color"), SNAME("Tree"), control_font_low_color); + theme->set_color(SNAME("font_selected_color"), SNAME("Tree"), control_font_pressed_color); + theme->set_color(SNAME("font_outline_color"), SNAME("Tree"), Color(1, 1, 1)); + theme->set_color(SNAME("guide_color"), SNAME("Tree"), Color(0.7, 0.7, 0.7, 0.25)); + theme->set_color(SNAME("drop_position_color"), SNAME("Tree"), Color(1, 0.3, 0.2)); + theme->set_color(SNAME("relationship_line_color"), SNAME("Tree"), Color(0.27, 0.27, 0.27)); + theme->set_color(SNAME("parent_hl_line_color"), SNAME("Tree"), Color(0.27, 0.27, 0.27)); + theme->set_color(SNAME("children_hl_line_color"), SNAME("Tree"), Color(0.27, 0.27, 0.27)); + theme->set_color(SNAME("custom_button_font_highlight"), SNAME("Tree"), control_font_hover_color); + + theme->set_constant(SNAME("hseparation"), SNAME("Tree"), 4 * scale); + theme->set_constant(SNAME("vseparation"), SNAME("Tree"), 4 * scale); + theme->set_constant(SNAME("item_margin"), SNAME("Tree"), 16 * scale); + theme->set_constant(SNAME("button_margin"), SNAME("Tree"), 4 * scale); + theme->set_constant(SNAME("draw_relationship_lines"), SNAME("Tree"), 0); + theme->set_constant(SNAME("relationship_line_width"), SNAME("Tree"), 1); + theme->set_constant(SNAME("parent_hl_line_width"), SNAME("Tree"), 1); + theme->set_constant(SNAME("children_hl_line_width"), SNAME("Tree"), 1); + theme->set_constant(SNAME("parent_hl_line_margin"), SNAME("Tree"), 0); + theme->set_constant(SNAME("draw_guides"), SNAME("Tree"), 1); + theme->set_constant(SNAME("scroll_border"), SNAME("Tree"), 4); + theme->set_constant(SNAME("scroll_speed"), SNAME("Tree"), 12); + theme->set_constant(SNAME("outline_size"), SNAME("Tree"), 0); // ItemList - theme->set_stylebox("bg", "ItemList", make_flat_stylebox(style_normal_color)); - theme->set_stylebox("bg_focus", "ItemList", focus); - theme->set_constant("hseparation", "ItemList", 4); - theme->set_constant("vseparation", "ItemList", 2); - theme->set_constant("icon_margin", "ItemList", 4); - theme->set_constant("line_separation", "ItemList", 2 * scale); + theme->set_stylebox(SNAME("bg"), SNAME("ItemList"), make_flat_stylebox(style_normal_color)); + theme->set_stylebox(SNAME("bg_focus"), SNAME("ItemList"), focus); + theme->set_constant(SNAME("hseparation"), SNAME("ItemList"), 4); + theme->set_constant(SNAME("vseparation"), SNAME("ItemList"), 2); + theme->set_constant(SNAME("icon_margin"), SNAME("ItemList"), 4); + theme->set_constant(SNAME("line_separation"), SNAME("ItemList"), 2 * scale); - theme->set_font("font", "ItemList", Ref<Font>()); - theme->set_font_size("font_size", "ItemList", -1); + theme->set_font(SNAME("font"), SNAME("ItemList"), Ref<Font>()); + theme->set_font_size(SNAME("font_size"), SNAME("ItemList"), -1); - theme->set_color("font_color", "ItemList", control_font_lower_color); - theme->set_color("font_selected_color", "ItemList", control_font_pressed_color); - theme->set_color("font_outline_color", "ItemList", Color(1, 1, 1)); - theme->set_color("guide_color", "ItemList", Color(0, 0, 0, 0.1)); - theme->set_stylebox("selected", "ItemList", make_flat_stylebox(style_selected_color)); - theme->set_stylebox("selected_focus", "ItemList", make_flat_stylebox(style_selected_color)); - theme->set_stylebox("cursor", "ItemList", focus); - theme->set_stylebox("cursor_unfocused", "ItemList", focus); + theme->set_color(SNAME("font_color"), SNAME("ItemList"), control_font_lower_color); + theme->set_color(SNAME("font_selected_color"), SNAME("ItemList"), control_font_pressed_color); + theme->set_color(SNAME("font_outline_color"), SNAME("ItemList"), Color(1, 1, 1)); + theme->set_color(SNAME("guide_color"), SNAME("ItemList"), Color(0, 0, 0, 0.1)); + theme->set_stylebox(SNAME("selected"), SNAME("ItemList"), make_flat_stylebox(style_selected_color)); + theme->set_stylebox(SNAME("selected_focus"), SNAME("ItemList"), make_flat_stylebox(style_selected_color)); + theme->set_stylebox(SNAME("cursor"), SNAME("ItemList"), focus); + theme->set_stylebox(SNAME("cursor_unfocused"), SNAME("ItemList"), focus); - theme->set_constant("outline_size", "ItemList", 0); + theme->set_constant(SNAME("outline_size"), SNAME("ItemList"), 0); // TabContainer @@ -792,105 +792,105 @@ void fill_default_theme(Ref<Theme> &theme, const Ref<Font> &default_font, Ref<Te Ref<StyleBoxFlat> style_tab_disabled = style_tab_unselected->duplicate(); style_tab_disabled->set_bg_color(style_disabled_color); - theme->set_stylebox("tab_selected", "TabContainer", style_tab_selected); - theme->set_stylebox("tab_unselected", "TabContainer", style_tab_unselected); - theme->set_stylebox("tab_disabled", "TabContainer", style_tab_disabled); - theme->set_stylebox("panel", "TabContainer", make_flat_stylebox(style_normal_color, 0, 0, 0, 0)); + theme->set_stylebox(SNAME("tab_selected"), SNAME("TabContainer"), style_tab_selected); + theme->set_stylebox(SNAME("tab_unselected"), SNAME("TabContainer"), style_tab_unselected); + theme->set_stylebox(SNAME("tab_disabled"), SNAME("TabContainer"), style_tab_disabled); + theme->set_stylebox(SNAME("panel"), SNAME("TabContainer"), make_flat_stylebox(style_normal_color, 0, 0, 0, 0)); - theme->set_icon("increment", "TabContainer", icons["scroll_button_right"]); - theme->set_icon("increment_highlight", "TabContainer", icons["scroll_button_right_hl"]); - theme->set_icon("decrement", "TabContainer", icons["scroll_button_left"]); - theme->set_icon("decrement_highlight", "TabContainer", icons["scroll_button_left_hl"]); - theme->set_icon("menu", "TabContainer", icons["tabs_menu"]); - theme->set_icon("menu_highlight", "TabContainer", icons["tabs_menu_hl"]); + theme->set_icon(SNAME("increment"), SNAME("TabContainer"), icons["scroll_button_right"]); + theme->set_icon(SNAME("increment_highlight"), SNAME("TabContainer"), icons["scroll_button_right_hl"]); + theme->set_icon(SNAME("decrement"), SNAME("TabContainer"), icons["scroll_button_left"]); + theme->set_icon(SNAME("decrement_highlight"), SNAME("TabContainer"), icons["scroll_button_left_hl"]); + theme->set_icon(SNAME("menu"), SNAME("TabContainer"), icons["tabs_menu"]); + theme->set_icon(SNAME("menu_highlight"), SNAME("TabContainer"), icons["tabs_menu_hl"]); - theme->set_font("font", "TabContainer", Ref<Font>()); - theme->set_font_size("font_size", "TabContainer", -1); + theme->set_font(SNAME("font"), SNAME("TabContainer"), Ref<Font>()); + theme->set_font_size(SNAME("font_size"), SNAME("TabContainer"), -1); - theme->set_color("font_selected_color", "TabContainer", control_font_hover_color); - theme->set_color("font_unselected_color", "TabContainer", control_font_low_color); - theme->set_color("font_disabled_color", "TabContainer", control_font_disabled_color); - theme->set_color("font_outline_color", "TabContainer", Color(1, 1, 1)); + theme->set_color(SNAME("font_selected_color"), SNAME("TabContainer"), control_font_hover_color); + theme->set_color(SNAME("font_unselected_color"), SNAME("TabContainer"), control_font_low_color); + theme->set_color(SNAME("font_disabled_color"), SNAME("TabContainer"), control_font_disabled_color); + theme->set_color(SNAME("font_outline_color"), SNAME("TabContainer"), Color(1, 1, 1)); - theme->set_constant("side_margin", "TabContainer", 8 * scale); - theme->set_constant("icon_separation", "TabContainer", 4 * scale); - theme->set_constant("outline_size", "TabContainer", 0); + theme->set_constant(SNAME("side_margin"), SNAME("TabContainer"), 8 * scale); + theme->set_constant(SNAME("icon_separation"), SNAME("TabContainer"), 4 * scale); + theme->set_constant(SNAME("outline_size"), SNAME("TabContainer"), 0); // TabBar - theme->set_stylebox("tab_selected", "TabBar", style_tab_selected); - theme->set_stylebox("tab_unselected", "TabBar", style_tab_unselected); - theme->set_stylebox("tab_disabled", "TabBar", style_tab_disabled); - theme->set_stylebox("button_pressed", "TabBar", button_pressed); - theme->set_stylebox("button_highlight", "TabBar", button_normal); + theme->set_stylebox(SNAME("tab_selected"), SNAME("TabBar"), style_tab_selected); + theme->set_stylebox(SNAME("tab_unselected"), SNAME("TabBar"), style_tab_unselected); + theme->set_stylebox(SNAME("tab_disabled"), SNAME("TabBar"), style_tab_disabled); + theme->set_stylebox(SNAME("button_pressed"), SNAME("TabBar"), button_pressed); + theme->set_stylebox(SNAME("button_highlight"), SNAME("TabBar"), button_normal); - theme->set_icon("increment", "TabBar", icons["scroll_button_right"]); - theme->set_icon("increment_highlight", "TabBar", icons["scroll_button_right_hl"]); - theme->set_icon("decrement", "TabBar", icons["scroll_button_left"]); - theme->set_icon("decrement_highlight", "TabBar", icons["scroll_button_left_hl"]); - theme->set_icon("close", "TabBar", icons["close"]); + theme->set_icon(SNAME("increment"), SNAME("TabBar"), icons["scroll_button_right"]); + theme->set_icon(SNAME("increment_highlight"), SNAME("TabBar"), icons["scroll_button_right_hl"]); + theme->set_icon(SNAME("decrement"), SNAME("TabBar"), icons["scroll_button_left"]); + theme->set_icon(SNAME("decrement_highlight"), SNAME("TabBar"), icons["scroll_button_left_hl"]); + theme->set_icon(SNAME("close"), SNAME("TabBar"), icons["close"]); - theme->set_font("font", "TabBar", Ref<Font>()); - theme->set_font_size("font_size", "TabBar", -1); + theme->set_font(SNAME("font"), SNAME("TabBar"), Ref<Font>()); + theme->set_font_size(SNAME("font_size"), SNAME("TabBar"), -1); - theme->set_color("font_selected_color", "TabBar", control_font_hover_color); - theme->set_color("font_unselected_color", "TabBar", control_font_low_color); - theme->set_color("font_disabled_color", "TabBar", control_font_disabled_color); - theme->set_color("font_outline_color", "TabBar", Color(1, 1, 1)); + theme->set_color(SNAME("font_selected_color"), SNAME("TabBar"), control_font_hover_color); + theme->set_color(SNAME("font_unselected_color"), SNAME("TabBar"), control_font_low_color); + theme->set_color(SNAME("font_disabled_color"), SNAME("TabBar"), control_font_disabled_color); + theme->set_color(SNAME("font_outline_color"), SNAME("TabBar"), Color(1, 1, 1)); - theme->set_constant("hseparation", "TabBar", 4 * scale); - theme->set_constant("outline_size", "TabBar", 0); + theme->set_constant(SNAME("hseparation"), SNAME("TabBar"), 4 * scale); + theme->set_constant(SNAME("outline_size"), SNAME("TabBar"), 0); // Separators - theme->set_stylebox("separator", "HSeparator", separator_horizontal); - theme->set_stylebox("separator", "VSeparator", separator_vertical); + theme->set_stylebox(SNAME("separator"), SNAME("HSeparator"), separator_horizontal); + theme->set_stylebox(SNAME("separator"), SNAME("VSeparator"), separator_vertical); - theme->set_icon("close", "Icons", icons["close"]); - theme->set_font("normal", "Fonts", Ref<Font>()); - theme->set_font("large", "Fonts", Ref<Font>()); + theme->set_icon(SNAME("close"), SNAME("Icons"), icons["close"]); + theme->set_font(SNAME("normal"), SNAME("Fonts"), Ref<Font>()); + theme->set_font(SNAME("large"), SNAME("Fonts"), Ref<Font>()); - theme->set_constant("separation", "HSeparator", 4 * scale); - theme->set_constant("separation", "VSeparator", 4 * scale); + theme->set_constant(SNAME("separation"), SNAME("HSeparator"), 4 * scale); + theme->set_constant(SNAME("separation"), SNAME("VSeparator"), 4 * scale); // ColorPicker - theme->set_constant("margin", "ColorPicker", 4 * scale); - theme->set_constant("sv_width", "ColorPicker", 256 * scale); - theme->set_constant("sv_height", "ColorPicker", 256 * scale); - theme->set_constant("h_width", "ColorPicker", 30 * scale); - theme->set_constant("label_width", "ColorPicker", 10 * scale); - - theme->set_icon("screen_picker", "ColorPicker", icons["color_picker_pipette"]); - theme->set_icon("add_preset", "ColorPicker", icons["add"]); - theme->set_icon("color_hue", "ColorPicker", icons["color_picker_hue"]); - theme->set_icon("color_sample", "ColorPicker", icons["color_picker_sample"]); - theme->set_icon("sample_bg", "ColorPicker", icons["mini_checkerboard"]); - theme->set_icon("overbright_indicator", "ColorPicker", icons["color_picker_overbright"]); - theme->set_icon("bar_arrow", "ColorPicker", icons["color_picker_bar_arrow"]); - theme->set_icon("picker_cursor", "ColorPicker", icons["color_picker_cursor"]); + theme->set_constant(SNAME("margin"), SNAME("ColorPicker"), 4 * scale); + theme->set_constant(SNAME("sv_width"), SNAME("ColorPicker"), 256 * scale); + theme->set_constant(SNAME("sv_height"), SNAME("ColorPicker"), 256 * scale); + theme->set_constant(SNAME("h_width"), SNAME("ColorPicker"), 30 * scale); + theme->set_constant(SNAME("label_width"), SNAME("ColorPicker"), 10 * scale); + + theme->set_icon(SNAME("screen_picker"), SNAME("ColorPicker"), icons["color_picker_pipette"]); + theme->set_icon(SNAME("add_preset"), SNAME("ColorPicker"), icons["add"]); + theme->set_icon(SNAME("color_hue"), SNAME("ColorPicker"), icons["color_picker_hue"]); + theme->set_icon(SNAME("color_sample"), SNAME("ColorPicker"), icons["color_picker_sample"]); + theme->set_icon(SNAME("sample_bg"), SNAME("ColorPicker"), icons["mini_checkerboard"]); + theme->set_icon(SNAME("overbright_indicator"), SNAME("ColorPicker"), icons["color_picker_overbright"]); + theme->set_icon(SNAME("bar_arrow"), SNAME("ColorPicker"), icons["color_picker_bar_arrow"]); + theme->set_icon(SNAME("picker_cursor"), SNAME("ColorPicker"), icons["color_picker_cursor"]); // ColorPickerButton - theme->set_icon("bg", "ColorPickerButton", icons["mini_checkerboard"]); - theme->set_stylebox("normal", "ColorPickerButton", button_normal); - theme->set_stylebox("pressed", "ColorPickerButton", button_pressed); - theme->set_stylebox("hover", "ColorPickerButton", button_hover); - theme->set_stylebox("disabled", "ColorPickerButton", button_disabled); - theme->set_stylebox("focus", "ColorPickerButton", focus); + theme->set_icon(SNAME("bg"), SNAME("ColorPickerButton"), icons["mini_checkerboard"]); + theme->set_stylebox(SNAME("normal"), SNAME("ColorPickerButton"), button_normal); + theme->set_stylebox(SNAME("pressed"), SNAME("ColorPickerButton"), button_pressed); + theme->set_stylebox(SNAME("hover"), SNAME("ColorPickerButton"), button_hover); + theme->set_stylebox(SNAME("disabled"), SNAME("ColorPickerButton"), button_disabled); + theme->set_stylebox(SNAME("focus"), SNAME("ColorPickerButton"), focus); - theme->set_font("font", "ColorPickerButton", Ref<Font>()); - theme->set_font_size("font_size", "ColorPickerButton", -1); + theme->set_font(SNAME("font"), SNAME("ColorPickerButton"), Ref<Font>()); + theme->set_font_size(SNAME("font_size"), SNAME("ColorPickerButton"), -1); - theme->set_color("font_color", "ColorPickerButton", Color(1, 1, 1, 1)); - theme->set_color("font_pressed_color", "ColorPickerButton", Color(0.8, 0.8, 0.8, 1)); - theme->set_color("font_hover_color", "ColorPickerButton", Color(1, 1, 1, 1)); - theme->set_color("font_focus_color", "ColorPickerButton", Color(1, 1, 1, 1)); - theme->set_color("font_disabled_color", "ColorPickerButton", Color(0.9, 0.9, 0.9, 0.3)); - theme->set_color("font_outline_color", "ColorPickerButton", Color(1, 1, 1)); + theme->set_color(SNAME("font_color"), SNAME("ColorPickerButton"), Color(1, 1, 1, 1)); + theme->set_color(SNAME("font_pressed_color"), SNAME("ColorPickerButton"), Color(0.8, 0.8, 0.8, 1)); + theme->set_color(SNAME("font_hover_color"), SNAME("ColorPickerButton"), Color(1, 1, 1, 1)); + theme->set_color(SNAME("font_focus_color"), SNAME("ColorPickerButton"), Color(1, 1, 1, 1)); + theme->set_color(SNAME("font_disabled_color"), SNAME("ColorPickerButton"), Color(0.9, 0.9, 0.9, 0.3)); + theme->set_color(SNAME("font_outline_color"), SNAME("ColorPickerButton"), Color(1, 1, 1)); - theme->set_constant("hseparation", "ColorPickerButton", 2 * scale); - theme->set_constant("outline_size", "ColorPickerButton", 0); + theme->set_constant(SNAME("hseparation"), SNAME("ColorPickerButton"), 2 * scale); + theme->set_constant(SNAME("outline_size"), SNAME("ColorPickerButton"), 0); // ColorPresetButton @@ -899,118 +899,118 @@ void fill_default_theme(Ref<Theme> &theme, const Ref<Font> &default_font, Ref<Te preset_sb->set_corner_detail(2); preset_sb->set_anti_aliased(false); - theme->set_stylebox("preset_fg", "ColorPresetButton", preset_sb); - theme->set_icon("preset_bg", "ColorPresetButton", icons["mini_checkerboard"]); - theme->set_icon("overbright_indicator", "ColorPresetButton", icons["color_picker_overbright"]); + theme->set_stylebox(SNAME("preset_fg"), SNAME("ColorPresetButton"), preset_sb); + theme->set_icon(SNAME("preset_bg"), SNAME("ColorPresetButton"), icons["mini_checkerboard"]); + theme->set_icon(SNAME("overbright_indicator"), SNAME("ColorPresetButton"), icons["color_picker_overbright"]); // TooltipPanel + TooltipLabel - theme->set_stylebox("panel", "TooltipPanel", + theme->set_stylebox(SNAME("panel"), SNAME("TooltipPanel"), make_flat_stylebox(Color(0, 0, 0, 0.5), 2 * default_margin, 0.5 * default_margin, 2 * default_margin, 0.5 * default_margin)); - theme->set_font("font", "TooltipLabel", Ref<Font>()); - theme->set_font_size("font_size", "TooltipLabel", -1); + theme->set_font(SNAME("font"), SNAME("TooltipLabel"), Ref<Font>()); + theme->set_font_size(SNAME("font_size"), SNAME("TooltipLabel"), -1); - theme->set_color("font_color", "TooltipLabel", control_font_color); - theme->set_color("font_shadow_color", "TooltipLabel", Color(0, 0, 0, 0)); - theme->set_color("font_outline_color", "TooltipLabel", Color(0, 0, 0, 0)); + theme->set_color(SNAME("font_color"), SNAME("TooltipLabel"), control_font_color); + theme->set_color(SNAME("font_shadow_color"), SNAME("TooltipLabel"), Color(0, 0, 0, 0)); + theme->set_color(SNAME("font_outline_color"), SNAME("TooltipLabel"), Color(0, 0, 0, 0)); - theme->set_constant("shadow_offset_x", "TooltipLabel", 1); - theme->set_constant("shadow_offset_y", "TooltipLabel", 1); - theme->set_constant("outline_size", "TooltipLabel", 0); + theme->set_constant(SNAME("shadow_offset_x"), SNAME("TooltipLabel"), 1); + theme->set_constant(SNAME("shadow_offset_y"), SNAME("TooltipLabel"), 1); + theme->set_constant(SNAME("outline_size"), SNAME("TooltipLabel"), 0); // RichTextLabel - theme->set_stylebox("focus", "RichTextLabel", focus); - theme->set_stylebox("normal", "RichTextLabel", make_empty_stylebox(0, 0, 0, 0)); + theme->set_stylebox(SNAME("focus"), SNAME("RichTextLabel"), focus); + theme->set_stylebox(SNAME("normal"), SNAME("RichTextLabel"), make_empty_stylebox(0, 0, 0, 0)); - theme->set_font("normal_font", "RichTextLabel", Ref<Font>()); - theme->set_font("bold_font", "RichTextLabel", Ref<Font>()); - theme->set_font("italics_font", "RichTextLabel", Ref<Font>()); - theme->set_font("bold_italics_font", "RichTextLabel", Ref<Font>()); - theme->set_font("mono_font", "RichTextLabel", Ref<Font>()); + theme->set_font(SNAME("normal_font"), SNAME("RichTextLabel"), Ref<Font>()); + theme->set_font(SNAME("bold_font"), SNAME("RichTextLabel"), Ref<Font>()); + theme->set_font(SNAME("italics_font"), SNAME("RichTextLabel"), Ref<Font>()); + theme->set_font(SNAME("bold_italics_font"), SNAME("RichTextLabel"), Ref<Font>()); + theme->set_font(SNAME("mono_font"), SNAME("RichTextLabel"), Ref<Font>()); - theme->set_font_size("normal_font_size", "RichTextLabel", -1); - theme->set_font_size("bold_font_size", "RichTextLabel", -1); - theme->set_font_size("italics_font_size", "RichTextLabel", -1); - theme->set_font_size("bold_italics_font_size", "RichTextLabel", -1); - theme->set_font_size("mono_font_size", "RichTextLabel", -1); + theme->set_font_size(SNAME("normal_font_size"), SNAME("RichTextLabel"), -1); + theme->set_font_size(SNAME("bold_font_size"), SNAME("RichTextLabel"), -1); + theme->set_font_size(SNAME("italics_font_size"), SNAME("RichTextLabel"), -1); + theme->set_font_size(SNAME("bold_italics_font_size"), SNAME("RichTextLabel"), -1); + theme->set_font_size(SNAME("mono_font_size"), SNAME("RichTextLabel"), -1); - theme->set_color("default_color", "RichTextLabel", Color(1, 1, 1)); - theme->set_color("font_selected_color", "RichTextLabel", Color(0, 0, 0)); - theme->set_color("selection_color", "RichTextLabel", Color(0.1, 0.1, 1, 0.8)); + theme->set_color(SNAME("default_color"), SNAME("RichTextLabel"), Color(1, 1, 1)); + theme->set_color(SNAME("font_selected_color"), SNAME("RichTextLabel"), Color(0, 0, 0)); + theme->set_color(SNAME("selection_color"), SNAME("RichTextLabel"), Color(0.1, 0.1, 1, 0.8)); - theme->set_color("font_shadow_color", "RichTextLabel", Color(0, 0, 0, 0)); + theme->set_color(SNAME("font_shadow_color"), SNAME("RichTextLabel"), Color(0, 0, 0, 0)); - theme->set_color("font_outline_color", "RichTextLabel", Color(1, 1, 1)); + theme->set_color(SNAME("font_outline_color"), SNAME("RichTextLabel"), Color(1, 1, 1)); - theme->set_constant("shadow_offset_x", "RichTextLabel", 1 * scale); - theme->set_constant("shadow_offset_y", "RichTextLabel", 1 * scale); - theme->set_constant("shadow_outline_size", "RichTextLabel", 1 * scale); + theme->set_constant(SNAME("shadow_offset_x"), SNAME("RichTextLabel"), 1 * scale); + theme->set_constant(SNAME("shadow_offset_y"), SNAME("RichTextLabel"), 1 * scale); + theme->set_constant(SNAME("shadow_outline_size"), SNAME("RichTextLabel"), 1 * scale); - theme->set_constant("line_separation", "RichTextLabel", 0 * scale); - theme->set_constant("table_hseparation", "RichTextLabel", 3 * scale); - theme->set_constant("table_vseparation", "RichTextLabel", 3 * scale); + theme->set_constant(SNAME("line_separation"), SNAME("RichTextLabel"), 0 * scale); + theme->set_constant(SNAME("table_hseparation"), SNAME("RichTextLabel"), 3 * scale); + theme->set_constant(SNAME("table_vseparation"), SNAME("RichTextLabel"), 3 * scale); - theme->set_constant("outline_size", "RichTextLabel", 0); + theme->set_constant(SNAME("outline_size"), SNAME("RichTextLabel"), 0); - theme->set_color("table_odd_row_bg", "RichTextLabel", Color(0, 0, 0, 0)); - theme->set_color("table_even_row_bg", "RichTextLabel", Color(0, 0, 0, 0)); - theme->set_color("table_border", "RichTextLabel", Color(0, 0, 0, 0)); + theme->set_color(SNAME("table_odd_row_bg"), SNAME("RichTextLabel"), Color(0, 0, 0, 0)); + theme->set_color(SNAME("table_even_row_bg"), SNAME("RichTextLabel"), Color(0, 0, 0, 0)); + theme->set_color(SNAME("table_border"), SNAME("RichTextLabel"), Color(0, 0, 0, 0)); // Containers - theme->set_icon("grabber", "VSplitContainer", icons["vsplitter"]); - theme->set_icon("grabber", "HSplitContainer", icons["hsplitter"]); - - theme->set_constant("separation", "HBoxContainer", 4 * scale); - theme->set_constant("separation", "VBoxContainer", 4 * scale); - theme->set_constant("margin_left", "MarginContainer", 0 * scale); - theme->set_constant("margin_top", "MarginContainer", 0 * scale); - theme->set_constant("margin_right", "MarginContainer", 0 * scale); - theme->set_constant("margin_bottom", "MarginContainer", 0 * scale); - theme->set_constant("hseparation", "GridContainer", 4 * scale); - theme->set_constant("vseparation", "GridContainer", 4 * scale); - theme->set_constant("separation", "HSplitContainer", 12 * scale); - theme->set_constant("separation", "VSplitContainer", 12 * scale); - theme->set_constant("autohide", "HSplitContainer", 1 * scale); - theme->set_constant("autohide", "VSplitContainer", 1 * scale); - theme->set_constant("hseparation", "HFlowContainer", 4 * scale); - theme->set_constant("vseparation", "HFlowContainer", 4 * scale); - theme->set_constant("hseparation", "VFlowContainer", 4 * scale); - theme->set_constant("vseparation", "VFlowContainer", 4 * scale); - - theme->set_stylebox("panel", "PanelContainer", make_flat_stylebox(style_normal_color, 0, 0, 0, 0)); - - theme->set_icon("minus", "GraphEdit", icons["zoom_less"]); - theme->set_icon("reset", "GraphEdit", icons["zoom_reset"]); - theme->set_icon("more", "GraphEdit", icons["zoom_more"]); - theme->set_icon("snap", "GraphEdit", icons["grid_snap"]); - theme->set_icon("minimap", "GraphEdit", icons["grid_minimap"]); - theme->set_icon("layout", "GraphEdit", icons["grid_layout"]); - theme->set_stylebox("bg", "GraphEdit", make_flat_stylebox(style_normal_color, 4, 4, 4, 5)); - theme->set_color("grid_minor", "GraphEdit", Color(1, 1, 1, 0.05)); - theme->set_color("grid_major", "GraphEdit", Color(1, 1, 1, 0.2)); - theme->set_color("selection_fill", "GraphEdit", Color(1, 1, 1, 0.3)); - theme->set_color("selection_stroke", "GraphEdit", Color(1, 1, 1, 0.8)); - theme->set_color("activity", "GraphEdit", Color(1, 1, 1)); - theme->set_constant("bezier_len_pos", "GraphEdit", 80 * scale); - theme->set_constant("bezier_len_neg", "GraphEdit", 160 * scale); + theme->set_icon(SNAME("grabber"), SNAME("VSplitContainer"), icons["vsplitter"]); + theme->set_icon(SNAME("grabber"), SNAME("HSplitContainer"), icons["hsplitter"]); + + theme->set_constant(SNAME("separation"), SNAME("HBoxContainer"), 4 * scale); + theme->set_constant(SNAME("separation"), SNAME("VBoxContainer"), 4 * scale); + theme->set_constant(SNAME("margin_left"), SNAME("MarginContainer"), 0 * scale); + theme->set_constant(SNAME("margin_top"), SNAME("MarginContainer"), 0 * scale); + theme->set_constant(SNAME("margin_right"), SNAME("MarginContainer"), 0 * scale); + theme->set_constant(SNAME("margin_bottom"), SNAME("MarginContainer"), 0 * scale); + theme->set_constant(SNAME("hseparation"), SNAME("GridContainer"), 4 * scale); + theme->set_constant(SNAME("vseparation"), SNAME("GridContainer"), 4 * scale); + theme->set_constant(SNAME("separation"), SNAME("HSplitContainer"), 12 * scale); + theme->set_constant(SNAME("separation"), SNAME("VSplitContainer"), 12 * scale); + theme->set_constant(SNAME("autohide"), SNAME("HSplitContainer"), 1 * scale); + theme->set_constant(SNAME("autohide"), SNAME("VSplitContainer"), 1 * scale); + theme->set_constant(SNAME("hseparation"), SNAME("HFlowContainer"), 4 * scale); + theme->set_constant(SNAME("vseparation"), SNAME("HFlowContainer"), 4 * scale); + theme->set_constant(SNAME("hseparation"), SNAME("VFlowContainer"), 4 * scale); + theme->set_constant(SNAME("vseparation"), SNAME("VFlowContainer"), 4 * scale); + + theme->set_stylebox(SNAME("panel"), SNAME("PanelContainer"), make_flat_stylebox(style_normal_color, 0, 0, 0, 0)); + + theme->set_icon(SNAME("minus"), SNAME("GraphEdit"), icons["zoom_less"]); + theme->set_icon(SNAME("reset"), SNAME("GraphEdit"), icons["zoom_reset"]); + theme->set_icon(SNAME("more"), SNAME("GraphEdit"), icons["zoom_more"]); + theme->set_icon(SNAME("snap"), SNAME("GraphEdit"), icons["grid_snap"]); + theme->set_icon(SNAME("minimap"), SNAME("GraphEdit"), icons["grid_minimap"]); + theme->set_icon(SNAME("layout"), SNAME("GraphEdit"), icons["grid_layout"]); + theme->set_stylebox(SNAME("bg"), SNAME("GraphEdit"), make_flat_stylebox(style_normal_color, 4, 4, 4, 5)); + theme->set_color(SNAME("grid_minor"), SNAME("GraphEdit"), Color(1, 1, 1, 0.05)); + theme->set_color(SNAME("grid_major"), SNAME("GraphEdit"), Color(1, 1, 1, 0.2)); + theme->set_color(SNAME("selection_fill"), SNAME("GraphEdit"), Color(1, 1, 1, 0.3)); + theme->set_color(SNAME("selection_stroke"), SNAME("GraphEdit"), Color(1, 1, 1, 0.8)); + theme->set_color(SNAME("activity"), SNAME("GraphEdit"), Color(1, 1, 1)); + theme->set_constant(SNAME("bezier_len_pos"), SNAME("GraphEdit"), 80 * scale); + theme->set_constant(SNAME("bezier_len_neg"), SNAME("GraphEdit"), 160 * scale); // Visual Node Ports - theme->set_constant("port_grab_distance_horizontal", "GraphEdit", 24 * scale); - theme->set_constant("port_grab_distance_vertical", "GraphEdit", 26 * scale); + theme->set_constant(SNAME("port_grab_distance_horizontal"), SNAME("GraphEdit"), 24 * scale); + theme->set_constant(SNAME("port_grab_distance_vertical"), SNAME("GraphEdit"), 26 * scale); - theme->set_stylebox("bg", "GraphEditMinimap", make_flat_stylebox(Color(0.24, 0.24, 0.24), 0, 0, 0, 0)); + theme->set_stylebox(SNAME("bg"), SNAME("GraphEditMinimap"), make_flat_stylebox(Color(0.24, 0.24, 0.24), 0, 0, 0, 0)); Ref<StyleBoxFlat> style_minimap_camera = make_flat_stylebox(Color(0.65, 0.65, 0.65, 0.2), 0, 0, 0, 0, 0); style_minimap_camera->set_border_color(Color(0.65, 0.65, 0.65, 0.45)); style_minimap_camera->set_border_width_all(1); - theme->set_stylebox("camera", "GraphEditMinimap", style_minimap_camera); - theme->set_stylebox("node", "GraphEditMinimap", make_flat_stylebox(Color(1, 1, 1), 0, 0, 0, 0, 2)); + theme->set_stylebox(SNAME("camera"), SNAME("GraphEditMinimap"), style_minimap_camera); + theme->set_stylebox(SNAME("node"), SNAME("GraphEditMinimap"), make_flat_stylebox(Color(1, 1, 1), 0, 0, 0, 0, 2)); - theme->set_icon("resizer", "GraphEditMinimap", icons["resizer_nw"]); - theme->set_color("resizer_color", "GraphEditMinimap", Color(1, 1, 1, 0.85)); + theme->set_icon(SNAME("resizer"), SNAME("GraphEditMinimap"), icons["resizer_nw"]); + theme->set_color(SNAME("resizer_color"), SNAME("GraphEditMinimap"), Color(1, 1, 1, 0.85)); // Theme diff --git a/scene/resources/visual_shader.cpp b/scene/resources/visual_shader.cpp index 1683756a3e..dae61c8609 100644 --- a/scene/resources/visual_shader.cpp +++ b/scene/resources/visual_shader.cpp @@ -131,7 +131,7 @@ void VisualShaderNode::set_input_port_default_value(int p_port, const Variant &p } break; case Variant::VECTOR2: { Vector2 pv = p_prev_value; - value = Vector3(pv.x, pv.y, 0.0); + value = Vector3(pv.x, pv.y, pv.y); } break; case Variant::VECTOR3: { value = p_prev_value; @@ -289,7 +289,7 @@ String VisualShaderNode::generate_global(Shader::Mode p_mode, VisualShader::Type return String(); } -String VisualShaderNode::generate_global_per_node(Shader::Mode p_mode, VisualShader::Type p_type, int p_id) const { +String VisualShaderNode::generate_global_per_node(Shader::Mode p_mode, int p_id) const { return String(); } @@ -472,7 +472,7 @@ String VisualShaderNodeCustom::generate_code(Shader::Mode p_mode, VisualShader:: return code; } -String VisualShaderNodeCustom::generate_global_per_node(Shader::Mode p_mode, VisualShader::Type p_type, int p_id) const { +String VisualShaderNodeCustom::generate_global_per_node(Shader::Mode p_mode, int p_id) const { String ret; if (GDVIRTUAL_CALL(_get_global_code, p_mode, ret)) { String code = "// " + get_caption() + "\n"; @@ -1485,7 +1485,7 @@ Error VisualShader::_write_node(Type type, StringBuilder &global_code, StringBui class_name = vsnode->get_script_instance()->get_script()->get_path(); } if (!r_classes.has(class_name)) { - global_code_per_node += vsnode->generate_global_per_node(get_mode(), type, node); + global_code_per_node += vsnode->generate_global_per_node(get_mode(), node); for (int i = 0; i < TYPE_MAX; i++) { global_code_per_func[Type(i)] += vsnode->generate_global_per_func(get_mode(), Type(i), node); } @@ -2146,7 +2146,11 @@ void VisualShader::_update_shader() const { global_compute_code += " return __rand_from_seed(seed) * (to - from) + from;\n"; global_compute_code += "}\n\n"; - global_compute_code += "vec3 __randv_range(inout uint seed, vec3 from, vec3 to) {\n"; + global_compute_code += "vec2 __randv2_range(inout uint seed, vec2 from, vec2 to) {\n"; + global_compute_code += " return vec2(__randf_range(seed, from.x, to.x), __randf_range(seed, from.y, to.y));\n"; + global_compute_code += "}\n\n"; + + global_compute_code += "vec3 __randv3_range(inout uint seed, vec3 from, vec3 to) {\n"; global_compute_code += " return vec3(__randf_range(seed, from.x, to.x), __randf_range(seed, from.y, to.y), __randf_range(seed, from.z, to.z));\n"; global_compute_code += "}\n\n"; diff --git a/scene/resources/visual_shader.h b/scene/resources/visual_shader.h index e85bf696b0..d3b5365893 100644 --- a/scene/resources/visual_shader.h +++ b/scene/resources/visual_shader.h @@ -275,7 +275,7 @@ public: virtual Vector<VisualShader::DefaultTextureParam> get_default_texture_parameters(VisualShader::Type p_type, int p_id) const; virtual String generate_global(Shader::Mode p_mode, VisualShader::Type p_type, int p_id) const; - virtual String generate_global_per_node(Shader::Mode p_mode, VisualShader::Type p_type, int p_id) const; + virtual String generate_global_per_node(Shader::Mode p_mode, int p_id) const; virtual String generate_global_per_func(Shader::Mode p_mode, VisualShader::Type p_type, int p_id) const; // If no output is connected, the output var passed will be empty. If no input is connected and input is NIL, the input var passed will be empty. virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview = false) const = 0; @@ -335,7 +335,7 @@ protected: void _set_input_port_default_value(int p_port, const Variant &p_value); virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview = false) const override; - virtual String generate_global_per_node(Shader::Mode p_mode, VisualShader::Type p_type, int p_id) const override; + virtual String generate_global_per_node(Shader::Mode p_mode, int p_id) const override; static void _bind_methods(); diff --git a/scene/resources/visual_shader_nodes.cpp b/scene/resources/visual_shader_nodes.cpp index 1205ba91c4..f2479199ee 100644 --- a/scene/resources/visual_shader_nodes.cpp +++ b/scene/resources/visual_shader_nodes.cpp @@ -5694,7 +5694,7 @@ String VisualShaderNodeTextureUniformTriplanar::get_input_port_name(int p_port) return ""; } -String VisualShaderNodeTextureUniformTriplanar::generate_global_per_node(Shader::Mode p_mode, VisualShader::Type p_type, int p_id) const { +String VisualShaderNodeTextureUniformTriplanar::generate_global_per_node(Shader::Mode p_mode, int p_id) const { String code; code += "// TRIPLANAR FUNCTION GLOBAL CODE\n"; diff --git a/scene/resources/visual_shader_nodes.h b/scene/resources/visual_shader_nodes.h index 5c7a674d34..eeeb91a3ee 100644 --- a/scene/resources/visual_shader_nodes.h +++ b/scene/resources/visual_shader_nodes.h @@ -2136,7 +2136,7 @@ public: virtual bool is_input_port_default(int p_port, Shader::Mode p_mode) const override; - virtual String generate_global_per_node(Shader::Mode p_mode, VisualShader::Type p_type, int p_id) const override; + virtual String generate_global_per_node(Shader::Mode p_mode, int p_id) const override; virtual String generate_global_per_func(Shader::Mode p_mode, VisualShader::Type p_type, int p_id) const override; virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview = false) const override; diff --git a/scene/resources/visual_shader_particle_nodes.cpp b/scene/resources/visual_shader_particle_nodes.cpp index 3376d6aa0b..1885211d57 100644 --- a/scene/resources/visual_shader_particle_nodes.cpp +++ b/scene/resources/visual_shader_particle_nodes.cpp @@ -39,6 +39,9 @@ int VisualShaderNodeParticleEmitter::get_output_port_count() const { } VisualShaderNodeParticleEmitter::PortType VisualShaderNodeParticleEmitter::get_output_port_type(int p_port) const { + if (mode_2d) { + return PORT_TYPE_VECTOR_2D; + } return PORT_TYPE_VECTOR_3D; } @@ -54,6 +57,9 @@ bool VisualShaderNodeParticleEmitter::has_output_port_preview(int p_port) const } void VisualShaderNodeParticleEmitter::set_mode_2d(bool p_enabled) { + if (mode_2d == p_enabled) { + return; + } mode_2d = p_enabled; emit_changed(); } @@ -111,7 +117,7 @@ String VisualShaderNodeParticleSphereEmitter::get_input_port_name(int p_port) co return String(); } -String VisualShaderNodeParticleSphereEmitter::generate_global_per_node(Shader::Mode p_mode, VisualShader::Type p_type, int p_id) const { +String VisualShaderNodeParticleSphereEmitter::generate_global_per_node(Shader::Mode p_mode, int p_id) const { String code; code += "vec2 __get_random_point_in_circle(inout uint seed, float radius, float inner_radius) {\n"; @@ -129,7 +135,7 @@ String VisualShaderNodeParticleSphereEmitter::generate_code(Shader::Mode p_mode, String code; if (mode_2d) { - code += " " + p_output_vars[0] + " = vec3(__get_random_point_in_circle(__seed, " + (p_input_vars[0].is_empty() ? (String)get_input_port_default_value(0) : p_input_vars[0]) + ", " + (p_input_vars[1].is_empty() ? (String)get_input_port_default_value(1) : p_input_vars[1]) + "), 0.0);\n"; + code += " " + p_output_vars[0] + " = __get_random_point_in_circle(__seed, " + (p_input_vars[0].is_empty() ? (String)get_input_port_default_value(0) : p_input_vars[0]) + ", " + (p_input_vars[1].is_empty() ? (String)get_input_port_default_value(1) : p_input_vars[1]) + ");\n"; } else { code += " " + p_output_vars[0] + " = __get_random_point_in_sphere(__seed, " + (p_input_vars[0].is_empty() ? (String)get_input_port_default_value(0) : p_input_vars[0]) + ", " + (p_input_vars[1].is_empty() ? (String)get_input_port_default_value(1) : p_input_vars[1]) + ");\n"; } @@ -154,11 +160,27 @@ int VisualShaderNodeParticleBoxEmitter::get_input_port_count() const { VisualShaderNodeParticleBoxEmitter::PortType VisualShaderNodeParticleBoxEmitter::get_input_port_type(int p_port) const { if (p_port == 0) { + if (mode_2d) { + return PORT_TYPE_VECTOR_2D; + } return PORT_TYPE_VECTOR_3D; } return PORT_TYPE_SCALAR; } +void VisualShaderNodeParticleBoxEmitter::set_mode_2d(bool p_enabled) { + if (mode_2d == p_enabled) { + return; + } + if (p_enabled) { + set_input_port_default_value(0, Vector2(), get_input_port_default_value(0)); + } else { + set_input_port_default_value(0, Vector3(), get_input_port_default_value(0)); + } + mode_2d = p_enabled; + emit_changed(); +} + String VisualShaderNodeParticleBoxEmitter::get_input_port_name(int p_port) const { if (p_port == 0) { return "extents"; @@ -166,7 +188,7 @@ String VisualShaderNodeParticleBoxEmitter::get_input_port_name(int p_port) const return String(); } -String VisualShaderNodeParticleBoxEmitter::generate_global_per_node(Shader::Mode p_mode, VisualShader::Type p_type, int p_id) const { +String VisualShaderNodeParticleBoxEmitter::generate_global_per_node(Shader::Mode p_mode, int p_id) const { String code; code += "vec2 __get_random_point_in_box2d(inout uint seed, vec2 extents) {\n"; @@ -185,7 +207,7 @@ String VisualShaderNodeParticleBoxEmitter::generate_global_per_node(Shader::Mode String VisualShaderNodeParticleBoxEmitter::generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview) const { String code; if (mode_2d) { - code += " " + p_output_vars[0] + " = vec3(__get_random_point_in_box2d(__seed, " + (p_input_vars[0].is_empty() ? (String)get_input_port_default_value(0) : p_input_vars[0]) + ".xy), 0.0);\n"; + code += " " + p_output_vars[0] + " = __get_random_point_in_box2d(__seed, " + (p_input_vars[0].is_empty() ? (String)get_input_port_default_value(0) : p_input_vars[0]) + ");\n"; } else { code += " " + p_output_vars[0] + " = __get_random_point_in_box3d(__seed, " + (p_input_vars[0].is_empty() ? (String)get_input_port_default_value(0) : p_input_vars[0]) + ");\n"; } @@ -221,7 +243,7 @@ String VisualShaderNodeParticleRingEmitter::get_input_port_name(int p_port) cons return String(); } -String VisualShaderNodeParticleRingEmitter::generate_global_per_node(Shader::Mode p_mode, VisualShader::Type p_type, int p_id) const { +String VisualShaderNodeParticleRingEmitter::generate_global_per_node(Shader::Mode p_mode, int p_id) const { String code; code += "vec2 __get_random_point_on_ring2d(inout uint seed, float radius, float inner_radius) {\n"; @@ -243,7 +265,7 @@ String VisualShaderNodeParticleRingEmitter::generate_code(Shader::Mode p_mode, V String code; if (mode_2d) { - code = " " + p_output_vars[0] + " = vec3(__get_random_point_on_ring2d(__seed, " + (p_input_vars[0].is_empty() ? (String)get_input_port_default_value(0) : p_input_vars[0]) + ", " + (p_input_vars[1].is_empty() ? (String)get_input_port_default_value(1) : p_input_vars[1]) + "), 0.0);\n"; + code = " " + p_output_vars[0] + " = __get_random_point_on_ring2d(__seed, " + (p_input_vars[0].is_empty() ? (String)get_input_port_default_value(0) : p_input_vars[0]) + ", " + (p_input_vars[1].is_empty() ? (String)get_input_port_default_value(1) : p_input_vars[1]) + ");\n"; } else { code = " " + p_output_vars[0] + " = __get_random_point_on_ring3d(__seed, " + (p_input_vars[0].is_empty() ? (String)get_input_port_default_value(0) : p_input_vars[0]) + ", " + (p_input_vars[1].is_empty() ? (String)get_input_port_default_value(1) : p_input_vars[1]) + ", " + (p_input_vars[2].is_empty() ? (String)get_input_port_default_value(2) : p_input_vars[2]) + ");\n"; } @@ -269,18 +291,24 @@ int VisualShaderNodeParticleMeshEmitter::get_output_port_count() const { VisualShaderNodeParticleBoxEmitter::PortType VisualShaderNodeParticleMeshEmitter::get_output_port_type(int p_port) const { switch (p_port) { - case 0: - return PORT_TYPE_VECTOR_3D; // position - case 1: - return PORT_TYPE_VECTOR_3D; // normal - case 2: - return PORT_TYPE_VECTOR_3D; // color - case 3: - return PORT_TYPE_SCALAR; // alpha - case 4: - return PORT_TYPE_VECTOR_3D; // uv - case 5: - return PORT_TYPE_VECTOR_3D; // uv2 + case 0: // position + if (mode_2d) { + return PORT_TYPE_VECTOR_2D; + } + return PORT_TYPE_VECTOR_3D; + case 1: // normal + if (mode_2d) { + return PORT_TYPE_VECTOR_2D; + } + return PORT_TYPE_VECTOR_3D; + case 2: // color + return PORT_TYPE_VECTOR_3D; + case 3: // alpha + return PORT_TYPE_SCALAR; + case 4: // uv + return PORT_TYPE_VECTOR_2D; + case 5: // uv2 + return PORT_TYPE_VECTOR_2D; } return PORT_TYPE_SCALAR; } @@ -341,18 +369,22 @@ String VisualShaderNodeParticleMeshEmitter::generate_global(Shader::Mode p_mode, return code; } -String VisualShaderNodeParticleMeshEmitter::_generate_code(VisualShader::Type p_type, int p_id, const String *p_output_vars, int p_index, const String &p_texture_name, bool p_ignore_mode2d) const { +String VisualShaderNodeParticleMeshEmitter::_generate_code(VisualShader::Type p_type, int p_id, const String *p_output_vars, int p_index, const String &p_texture_name, PortType p_port_type) const { String code; if (is_output_port_connected(p_index)) { - if (mode_2d && !p_ignore_mode2d) { - code += " " + p_output_vars[p_index] + " = vec3("; - code += "texelFetch("; - code += make_unique_id(p_type, p_id, p_texture_name) + ", "; - code += "ivec2(__scalar_ibuff, 0), 0).xy, 0.0);\n"; - } else { - code += " " + p_output_vars[p_index] + " = texelFetch("; - code += make_unique_id(p_type, p_id, p_texture_name) + ", "; - code += "ivec2(__scalar_ibuff, 0), 0).xyz;\n"; + switch (p_port_type) { + case PORT_TYPE_VECTOR_2D: { + code += vformat(" %s = texelFetch(%s, ivec2(__scalar_ibuff, 0), 0).xy;\n", p_output_vars[p_index], make_unique_id(p_type, p_id, p_texture_name)); + } break; + case PORT_TYPE_VECTOR_3D: { + if (mode_2d) { + code += vformat(" %s = texelFetch(%s, ivec2(__scalar_ibuff, 0), 0).xy;\n", p_output_vars[p_index], make_unique_id(p_type, p_id, p_texture_name)); + } else { + code += vformat(" %s = texelFetch(%s, ivec2(__scalar_ibuff, 0), 0).xyz;\n", p_output_vars[p_index], make_unique_id(p_type, p_id, p_texture_name)); + } + } break; + default: + break; } } return code; @@ -362,27 +394,22 @@ String VisualShaderNodeParticleMeshEmitter::generate_code(Shader::Mode p_mode, V String code; code += " __scalar_ibuff = int(__rand_from_seed(__seed) * 65535.0) % " + itos(position_texture->get_width()) + ";\n"; - code += _generate_code(p_type, p_id, p_output_vars, 0, "mesh_vx"); - code += _generate_code(p_type, p_id, p_output_vars, 1, "mesh_nm"); + code += _generate_code(p_type, p_id, p_output_vars, 0, "mesh_vx", VisualShaderNode::PORT_TYPE_VECTOR_3D); + code += _generate_code(p_type, p_id, p_output_vars, 1, "mesh_nm", VisualShaderNode::PORT_TYPE_VECTOR_3D); if (is_output_port_connected(2) || is_output_port_connected(3)) { - code += " __vec4_buff = texelFetch("; - code += make_unique_id(p_type, p_id, "mesh_col") + ", "; - code += "ivec2(__scalar_ibuff, 0), 0);\n"; + code += vformat(" __vec4_buff = texelFetch(%s, ivec2(__scalar_ibuff, 0), 0);\n", make_unique_id(p_type, p_id, "mesh_col")); + if (is_output_port_connected(2)) { code += " " + p_output_vars[2] + " = __vec4_buff.rgb;\n"; - } else { - code += " " + p_output_vars[2] + " = vec3(0.0);\n"; } if (is_output_port_connected(3)) { code += " " + p_output_vars[3] + " = __vec4_buff.a;\n"; - } else { - code += " " + p_output_vars[3] + " = 0.0;\n"; } } - code += _generate_code(p_type, p_id, p_output_vars, 4, "mesh_uv", true); - code += _generate_code(p_type, p_id, p_output_vars, 5, "mesh_uv2", true); + code += _generate_code(p_type, p_id, p_output_vars, 4, "mesh_uv", VisualShaderNode::PORT_TYPE_VECTOR_2D); + code += _generate_code(p_type, p_id, p_output_vars, 5, "mesh_uv2", VisualShaderNode::PORT_TYPE_VECTOR_2D); return code; } @@ -876,10 +903,11 @@ void VisualShaderNodeParticleRandomness::_bind_methods() { ClassDB::bind_method(D_METHOD("set_op_type", "type"), &VisualShaderNodeParticleRandomness::set_op_type); ClassDB::bind_method(D_METHOD("get_op_type"), &VisualShaderNodeParticleRandomness::get_op_type); - ADD_PROPERTY(PropertyInfo(Variant::INT, "op_type", PROPERTY_HINT_ENUM, "Scalar,Vector"), "set_op_type", "get_op_type"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "op_type", PROPERTY_HINT_ENUM, "Scalar,Vector2,Vector3"), "set_op_type", "get_op_type"); BIND_ENUM_CONSTANT(OP_TYPE_SCALAR); - BIND_ENUM_CONSTANT(OP_TYPE_VECTOR); + BIND_ENUM_CONSTANT(OP_TYPE_VECTOR_2D); + BIND_ENUM_CONSTANT(OP_TYPE_VECTOR_3D); BIND_ENUM_CONSTANT(OP_TYPE_MAX); } @@ -898,8 +926,13 @@ int VisualShaderNodeParticleRandomness::get_output_port_count() const { } VisualShaderNodeParticleRandomness::PortType VisualShaderNodeParticleRandomness::get_output_port_type(int p_port) const { - if (op_type == OP_TYPE_VECTOR) { - return PORT_TYPE_VECTOR_3D; + switch (op_type) { + case OP_TYPE_VECTOR_2D: + return PORT_TYPE_VECTOR_2D; + case OP_TYPE_VECTOR_3D: + return PORT_TYPE_VECTOR_3D; + default: + break; } return PORT_TYPE_SCALAR; } @@ -913,8 +946,13 @@ int VisualShaderNodeParticleRandomness::get_input_port_count() const { } VisualShaderNodeParticleRandomness::PortType VisualShaderNodeParticleRandomness::get_input_port_type(int p_port) const { - if (op_type == OP_TYPE_VECTOR) { - return PORT_TYPE_VECTOR_3D; + switch (op_type) { + case OP_TYPE_VECTOR_2D: + return PORT_TYPE_VECTOR_2D; + case OP_TYPE_VECTOR_3D: + return PORT_TYPE_VECTOR_3D; + default: + break; } return PORT_TYPE_SCALAR; } @@ -930,10 +968,18 @@ String VisualShaderNodeParticleRandomness::get_input_port_name(int p_port) const String VisualShaderNodeParticleRandomness::generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview) const { String code; - if (op_type == OP_TYPE_SCALAR) { - code += vformat(" %s = __randf_range(__seed, %s, %s);\n", p_output_vars[0], p_input_vars[0].is_empty() ? (String)get_input_port_default_value(0) : p_input_vars[0], p_input_vars[1].is_empty() ? (String)get_input_port_default_value(1) : p_input_vars[1]); - } else if (op_type == OP_TYPE_VECTOR) { - code += vformat(" %s = __randv_range(__seed, %s, %s);\n", p_output_vars[0], p_input_vars[0].is_empty() ? (String)get_input_port_default_value(0) : p_input_vars[0], p_input_vars[1].is_empty() ? (String)get_input_port_default_value(1) : p_input_vars[1]); + switch (op_type) { + case OP_TYPE_SCALAR: { + code += vformat(" %s = __randf_range(__seed, %s, %s);\n", p_output_vars[0], p_input_vars[0].is_empty() ? (String)get_input_port_default_value(0) : p_input_vars[0], p_input_vars[1].is_empty() ? (String)get_input_port_default_value(1) : p_input_vars[1]); + } break; + case OP_TYPE_VECTOR_2D: { + code += vformat(" %s = __randv2_range(__seed, %s, %s);\n", p_output_vars[0], p_input_vars[0].is_empty() ? (String)get_input_port_default_value(0) : p_input_vars[0], p_input_vars[1].is_empty() ? (String)get_input_port_default_value(1) : p_input_vars[1]); + } break; + case OP_TYPE_VECTOR_3D: { + code += vformat(" %s = __randv3_range(__seed, %s, %s);\n", p_output_vars[0], p_input_vars[0].is_empty() ? (String)get_input_port_default_value(0) : p_input_vars[0], p_input_vars[1].is_empty() ? (String)get_input_port_default_value(1) : p_input_vars[1]); + } break; + default: + break; } return code; } @@ -943,12 +989,21 @@ void VisualShaderNodeParticleRandomness::set_op_type(OpType p_op_type) { if (op_type == p_op_type) { return; } - if (p_op_type == OP_TYPE_SCALAR) { - set_input_port_default_value(0, 0.0); - set_input_port_default_value(1, 1.0); - } else { - set_input_port_default_value(0, Vector3(-1.0, -1.0, -1.0)); - set_input_port_default_value(1, Vector3(1.0, 1.0, 1.0)); + switch (p_op_type) { + case OP_TYPE_SCALAR: { + set_input_port_default_value(0, 0.0, get_input_port_default_value(0)); + set_input_port_default_value(1, 0.0, get_input_port_default_value(1)); + } break; + case OP_TYPE_VECTOR_2D: { + set_input_port_default_value(0, Vector2(), get_input_port_default_value(0)); + set_input_port_default_value(1, Vector2(), get_input_port_default_value(1)); + } break; + case OP_TYPE_VECTOR_3D: { + set_input_port_default_value(0, Vector3(), get_input_port_default_value(0)); + set_input_port_default_value(1, Vector3(), get_input_port_default_value(1)); + } break; + default: + break; } op_type = p_op_type; emit_changed(); @@ -963,7 +1018,7 @@ bool VisualShaderNodeParticleRandomness::has_output_port_preview(int p_port) con } VisualShaderNodeParticleRandomness::VisualShaderNodeParticleRandomness() { - set_input_port_default_value(0, 0.0); + set_input_port_default_value(0, -1.0); set_input_port_default_value(1, 1.0); } diff --git a/scene/resources/visual_shader_particle_nodes.h b/scene/resources/visual_shader_particle_nodes.h index ce0d896c01..0b91cba5e0 100644 --- a/scene/resources/visual_shader_particle_nodes.h +++ b/scene/resources/visual_shader_particle_nodes.h @@ -48,7 +48,7 @@ public: virtual String get_output_port_name(int p_port) const override; virtual bool has_output_port_preview(int p_port) const override; - void set_mode_2d(bool p_enabled); + virtual void set_mode_2d(bool p_enabled); bool is_mode_2d() const; Vector<StringName> get_editable_properties() const override; @@ -68,7 +68,7 @@ public: virtual PortType get_input_port_type(int p_port) const override; virtual String get_input_port_name(int p_port) const override; - virtual String generate_global_per_node(Shader::Mode p_mode, VisualShader::Type p_type, int p_id) const override; + virtual String generate_global_per_node(Shader::Mode p_mode, int p_id) const override; virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview = false) const override; VisualShaderNodeParticleSphereEmitter(); @@ -83,8 +83,9 @@ public: virtual int get_input_port_count() const override; virtual PortType get_input_port_type(int p_port) const override; virtual String get_input_port_name(int p_port) const override; + virtual void set_mode_2d(bool p_enabled) override; - virtual String generate_global_per_node(Shader::Mode p_mode, VisualShader::Type p_type, int p_id) const override; + virtual String generate_global_per_node(Shader::Mode p_mode, int p_id) const override; virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview = false) const override; VisualShaderNodeParticleBoxEmitter(); @@ -100,7 +101,7 @@ public: virtual PortType get_input_port_type(int p_port) const override; virtual String get_input_port_name(int p_port) const override; - virtual String generate_global_per_node(Shader::Mode p_mode, VisualShader::Type p_type, int p_id) const override; + virtual String generate_global_per_node(Shader::Mode p_mode, int p_id) const override; virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview = false) const override; VisualShaderNodeParticleRingEmitter(); @@ -118,7 +119,7 @@ class VisualShaderNodeParticleMeshEmitter : public VisualShaderNodeParticleEmitt Ref<ImageTexture> uv_texture; Ref<ImageTexture> uv2_texture; - String _generate_code(VisualShader::Type p_type, int p_id, const String *p_output_vars, int p_index, const String &p_texture_name, bool p_ignore_mode2d = false) const; + String _generate_code(VisualShader::Type p_type, int p_id, const String *p_output_vars, int p_index, const String &p_texture_name, PortType p_port_type) const; void _update_texture(const Vector<Vector2> &p_array, Ref<ImageTexture> &r_texture); void _update_texture(const Vector<Vector3> &p_array, Ref<ImageTexture> &r_texture); @@ -213,7 +214,8 @@ class VisualShaderNodeParticleRandomness : public VisualShaderNode { public: enum OpType { OP_TYPE_SCALAR, - OP_TYPE_VECTOR, + OP_TYPE_VECTOR_2D, + OP_TYPE_VECTOR_3D, OP_TYPE_MAX, }; diff --git a/scene/resources/visual_shader_sdf_nodes.cpp b/scene/resources/visual_shader_sdf_nodes.cpp index 559831c3c2..cbd3ebd83b 100644 --- a/scene/resources/visual_shader_sdf_nodes.cpp +++ b/scene/resources/visual_shader_sdf_nodes.cpp @@ -41,7 +41,7 @@ int VisualShaderNodeSDFToScreenUV::get_input_port_count() const { } VisualShaderNodeSDFToScreenUV::PortType VisualShaderNodeSDFToScreenUV::get_input_port_type(int p_port) const { - return PORT_TYPE_VECTOR_3D; + return PORT_TYPE_VECTOR_2D; } String VisualShaderNodeSDFToScreenUV::get_input_port_name(int p_port) const { @@ -53,7 +53,7 @@ int VisualShaderNodeSDFToScreenUV::get_output_port_count() const { } VisualShaderNodeSDFToScreenUV::PortType VisualShaderNodeSDFToScreenUV::get_output_port_type(int p_port) const { - return PORT_TYPE_VECTOR_3D; + return PORT_TYPE_VECTOR_2D; } String VisualShaderNodeSDFToScreenUV::get_output_port_name(int p_port) const { @@ -61,7 +61,7 @@ String VisualShaderNodeSDFToScreenUV::get_output_port_name(int p_port) const { } String VisualShaderNodeSDFToScreenUV::generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview) const { - return " " + p_output_vars[0] + " = vec3(sdf_to_screen_uv(" + (p_input_vars[0].is_empty() ? "vec2(0.0)" : p_input_vars[0] + ".xy") + "), 0.0f);\n"; + return " " + p_output_vars[0] + " = sdf_to_screen_uv(" + (p_input_vars[0].is_empty() ? "vec2(0.0)" : p_input_vars[0]) + ");\n"; } VisualShaderNodeSDFToScreenUV::VisualShaderNodeSDFToScreenUV() { @@ -78,7 +78,7 @@ int VisualShaderNodeScreenUVToSDF::get_input_port_count() const { } VisualShaderNodeScreenUVToSDF::PortType VisualShaderNodeScreenUVToSDF::get_input_port_type(int p_port) const { - return PORT_TYPE_VECTOR_3D; + return PORT_TYPE_VECTOR_2D; } String VisualShaderNodeScreenUVToSDF::get_input_port_name(int p_port) const { @@ -90,7 +90,7 @@ int VisualShaderNodeScreenUVToSDF::get_output_port_count() const { } VisualShaderNodeScreenUVToSDF::PortType VisualShaderNodeScreenUVToSDF::get_output_port_type(int p_port) const { - return PORT_TYPE_VECTOR_3D; + return PORT_TYPE_VECTOR_2D; } String VisualShaderNodeScreenUVToSDF::get_output_port_name(int p_port) const { @@ -105,7 +105,7 @@ bool VisualShaderNodeScreenUVToSDF::is_input_port_default(int p_port, Shader::Mo } String VisualShaderNodeScreenUVToSDF::generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview) const { - return " " + p_output_vars[0] + " = vec3(screen_uv_to_sdf(" + (p_input_vars[0].is_empty() ? "SCREEN_UV" : p_input_vars[0] + ".xy") + "), 0.0f);\n"; + return " " + p_output_vars[0] + " = screen_uv_to_sdf(" + (p_input_vars[0].is_empty() ? "SCREEN_UV" : p_input_vars[0]) + ");\n"; } VisualShaderNodeScreenUVToSDF::VisualShaderNodeScreenUVToSDF() { @@ -122,7 +122,7 @@ int VisualShaderNodeTextureSDF::get_input_port_count() const { } VisualShaderNodeTextureSDF::PortType VisualShaderNodeTextureSDF::get_input_port_type(int p_port) const { - return PORT_TYPE_VECTOR_3D; + return PORT_TYPE_VECTOR_2D; } String VisualShaderNodeTextureSDF::get_input_port_name(int p_port) const { @@ -142,7 +142,7 @@ String VisualShaderNodeTextureSDF::get_output_port_name(int p_port) const { } String VisualShaderNodeTextureSDF::generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview) const { - return " " + p_output_vars[0] + " = texture_sdf(" + (p_input_vars[0].is_empty() ? "vec2(0.0)" : p_input_vars[0] + ".xy") + ");\n"; + return " " + p_output_vars[0] + " = texture_sdf(" + (p_input_vars[0].is_empty() ? "vec2(0.0)" : p_input_vars[0]) + ");\n"; } VisualShaderNodeTextureSDF::VisualShaderNodeTextureSDF() { @@ -159,7 +159,7 @@ int VisualShaderNodeTextureSDFNormal::get_input_port_count() const { } VisualShaderNodeTextureSDFNormal::PortType VisualShaderNodeTextureSDFNormal::get_input_port_type(int p_port) const { - return PORT_TYPE_VECTOR_3D; + return PORT_TYPE_VECTOR_2D; } String VisualShaderNodeTextureSDFNormal::get_input_port_name(int p_port) const { @@ -171,7 +171,7 @@ int VisualShaderNodeTextureSDFNormal::get_output_port_count() const { } VisualShaderNodeTextureSDFNormal::PortType VisualShaderNodeTextureSDFNormal::get_output_port_type(int p_port) const { - return PORT_TYPE_VECTOR_3D; + return PORT_TYPE_VECTOR_2D; } String VisualShaderNodeTextureSDFNormal::get_output_port_name(int p_port) const { @@ -179,7 +179,7 @@ String VisualShaderNodeTextureSDFNormal::get_output_port_name(int p_port) const } String VisualShaderNodeTextureSDFNormal::generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview) const { - return " " + p_output_vars[0] + " = vec3(texture_sdf_normal(" + (p_input_vars[0].is_empty() ? "vec2(0.0)" : p_input_vars[0] + ".xy") + "), 0.0f);\n"; + return " " + p_output_vars[0] + " = texture_sdf_normal(" + (p_input_vars[0].is_empty() ? "vec2(0.0)" : p_input_vars[0]) + ");\n"; } VisualShaderNodeTextureSDFNormal::VisualShaderNodeTextureSDFNormal() { @@ -197,7 +197,7 @@ int VisualShaderNodeSDFRaymarch::get_input_port_count() const { VisualShaderNodeSDFRaymarch::PortType VisualShaderNodeSDFRaymarch::get_input_port_type(int p_port) const { if (p_port == 0 || p_port == 1) { - return PORT_TYPE_VECTOR_3D; + return PORT_TYPE_VECTOR_2D; } return PORT_TYPE_SCALAR; } @@ -221,7 +221,7 @@ VisualShaderNodeSDFRaymarch::PortType VisualShaderNodeSDFRaymarch::get_output_po } else if (p_port == 1) { return PORT_TYPE_BOOLEAN; } else if (p_port == 2) { - return PORT_TYPE_VECTOR_3D; + return PORT_TYPE_VECTOR_2D; } return PORT_TYPE_SCALAR; } @@ -245,13 +245,13 @@ String VisualShaderNodeSDFRaymarch::generate_code(Shader::Mode p_mode, VisualSha if (p_input_vars[0].is_empty()) { code += " vec2 __from_pos = vec2(0.0f);\n"; } else { - code += " vec2 __from_pos = " + p_input_vars[0] + ".xy;\n"; + code += " vec2 __from_pos = " + p_input_vars[0] + ";\n"; } if (p_input_vars[1].is_empty()) { code += " vec2 __to_pos = vec2(0.0f);\n"; } else { - code += " vec2 __to_pos = " + p_input_vars[1] + ".xy;\n"; + code += " vec2 __to_pos = " + p_input_vars[1] + ";\n"; } code += "\n vec2 __at = __from_pos;\n"; @@ -271,7 +271,7 @@ String VisualShaderNodeSDFRaymarch::generate_code(Shader::Mode p_mode, VisualSha code += " float __dist = min(__max_dist, __accum);\n"; code += " " + p_output_vars[0] + " = __dist;\n"; code += " " + p_output_vars[1] + " = __accum < __max_dist;\n"; - code += " " + p_output_vars[2] + " = vec3(__from_pos + __dir * __dist, 0.0f);\n"; + code += " " + p_output_vars[2] + " = __from_pos + __dir * __dist;\n"; code += " }\n"; diff --git a/servers/rendering/renderer_rd/effects_rd.cpp b/servers/rendering/renderer_rd/effects_rd.cpp index 7183fd110f..02a0b6f184 100644 --- a/servers/rendering/renderer_rd/effects_rd.cpp +++ b/servers/rendering/renderer_rd/effects_rd.cpp @@ -482,12 +482,11 @@ void EffectsRD::set_color(RID p_dest_texture, const Color &p_color, const Rect2i RD::get_singleton()->compute_list_end(); } -void EffectsRD::gaussian_blur(RID p_source_rd_texture, RID p_texture, RID p_back_texture, const Rect2i &p_region, bool p_8bit_dst) { +void EffectsRD::gaussian_blur(RID p_source_rd_texture, RID p_texture, const Rect2i &p_region, bool p_8bit_dst) { ERR_FAIL_COND_MSG(prefer_raster_effects, "Can't use the compute version of the gaussian blur with the mobile renderer."); memset(©.push_constant, 0, sizeof(CopyPushConstant)); - uint32_t base_flags = 0; copy.push_constant.section[0] = p_region.position.x; copy.push_constant.section[1] = p_region.position.y; copy.push_constant.section[2] = p_region.size.width; @@ -497,23 +496,12 @@ void EffectsRD::gaussian_blur(RID p_source_rd_texture, RID p_texture, RID p_back RD::DrawListID compute_list = RD::get_singleton()->compute_list_begin(); RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, copy.pipelines[p_8bit_dst ? COPY_MODE_GAUSSIAN_COPY_8BIT : COPY_MODE_GAUSSIAN_COPY]); RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_compute_uniform_set_from_texture(p_source_rd_texture), 0); - RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_uniform_set_from_image(p_back_texture), 3); - - copy.push_constant.flags = base_flags | COPY_FLAG_HORIZONTAL; - RD::get_singleton()->compute_list_set_push_constant(compute_list, ©.push_constant, sizeof(CopyPushConstant)); - - RD::get_singleton()->compute_list_dispatch_threads(compute_list, p_region.size.width, p_region.size.height, 1); - - RD::get_singleton()->compute_list_add_barrier(compute_list); - - //VERTICAL - RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_compute_uniform_set_from_texture(p_back_texture), 0); RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_uniform_set_from_image(p_texture), 3); - copy.push_constant.flags = base_flags; RD::get_singleton()->compute_list_set_push_constant(compute_list, ©.push_constant, sizeof(CopyPushConstant)); RD::get_singleton()->compute_list_dispatch_threads(compute_list, p_region.size.width, p_region.size.height, 1); + RD::get_singleton()->compute_list_end(); } @@ -2343,8 +2331,8 @@ EffectsRD::EffectsRD(bool p_prefer_raster_effects) { Vector<String> copy_modes; copy_modes.push_back("\n#define MODE_GAUSSIAN_BLUR\n"); copy_modes.push_back("\n#define MODE_GAUSSIAN_BLUR\n#define DST_IMAGE_8BIT\n"); - copy_modes.push_back("\n#define MODE_GAUSSIAN_GLOW\n"); - copy_modes.push_back("\n#define MODE_GAUSSIAN_GLOW\n#define GLOW_USE_AUTO_EXPOSURE\n"); + copy_modes.push_back("\n#define MODE_GAUSSIAN_BLUR\n#define MODE_GLOW\n"); + copy_modes.push_back("\n#define MODE_GAUSSIAN_BLUR\n#define MODE_GLOW\n#define GLOW_USE_AUTO_EXPOSURE\n"); copy_modes.push_back("\n#define MODE_SIMPLE_COPY\n"); copy_modes.push_back("\n#define MODE_SIMPLE_COPY\n#define DST_IMAGE_8BIT\n"); copy_modes.push_back("\n#define MODE_SIMPLE_COPY_DEPTH\n"); diff --git a/servers/rendering/renderer_rd/effects_rd.h b/servers/rendering/renderer_rd/effects_rd.h index 1a080756a8..f5e5b1ace7 100644 --- a/servers/rendering/renderer_rd/effects_rd.h +++ b/servers/rendering/renderer_rd/effects_rd.h @@ -899,7 +899,7 @@ public: void copy_depth_to_rect(RID p_source_rd_texture, RID p_dest_framebuffer, const Rect2i &p_rect, bool p_flip_y = false); void copy_depth_to_rect_and_linearize(RID p_source_rd_texture, RID p_dest_texture, const Rect2i &p_rect, bool p_flip_y, float p_z_near, float p_z_far); void copy_to_atlas_fb(RID p_source_rd_texture, RID p_dest_framebuffer, const Rect2 &p_uv_rect, RD::DrawListID p_draw_list, bool p_flip_y = false, bool p_panorama = false); - void gaussian_blur(RID p_source_rd_texture, RID p_texture, RID p_back_texture, const Rect2i &p_region, bool p_8bit_dst = false); + void gaussian_blur(RID p_source_rd_texture, RID p_texture, const Rect2i &p_region, bool p_8bit_dst = false); void set_color(RID p_dest_texture, const Color &p_color, const Rect2i &p_region, bool p_8bit_dst = false); void gaussian_glow(RID p_source_rd_texture, RID p_back_texture, const Size2i &p_size, float p_strength = 1.0, bool p_high_quality = false, bool p_first_pass = false, float p_luminance_cap = 16.0, float p_exposure = 1.0, float p_bloom = 0.0, float p_hdr_bleed_threshold = 1.0, float p_hdr_bleed_scale = 1.0, RID p_auto_exposure = RID(), float p_auto_exposure_grey = 1.0); void gaussian_glow_raster(RID p_source_rd_texture, RID p_framebuffer_half, RID p_rd_texture_half, RID p_dest_framebuffer, const Vector2 &p_pixel_size, float p_strength = 1.0, bool p_high_quality = false, bool p_first_pass = false, float p_luminance_cap = 16.0, float p_exposure = 1.0, float p_bloom = 0.0, float p_hdr_bleed_threshold = 1.0, float p_hdr_bleed_scale = 1.0, RID p_auto_exposure = RID(), float p_auto_exposure_grey = 1.0); diff --git a/servers/rendering/renderer_rd/renderer_storage_rd.cpp b/servers/rendering/renderer_rd/renderer_storage_rd.cpp index 145c4f902e..f345001539 100644 --- a/servers/rendering/renderer_rd/renderer_storage_rd.cpp +++ b/servers/rendering/renderer_rd/renderer_storage_rd.cpp @@ -7516,10 +7516,6 @@ void RendererStorageRD::_clear_render_target(RenderTarget *rt) { if (rt->backbuffer.is_valid()) { RD::get_singleton()->free(rt->backbuffer); rt->backbuffer = RID(); - for (int i = 0; i < rt->backbuffer_mipmaps.size(); i++) { - //just erase copies, since the rest are erased by dependency - RD::get_singleton()->free(rt->backbuffer_mipmaps[i].mipmap_copy); - } rt->backbuffer_mipmaps.clear(); rt->backbuffer_uniform_set = RID(); //chain deleted } @@ -7636,7 +7632,9 @@ void RendererStorageRD::_create_render_target_backbuffer(RenderTarget *rt) { tf.mipmaps = mipmaps_required; rt->backbuffer = RD::get_singleton()->texture_create(tf, RD::TextureView()); + RD::get_singleton()->set_resource_name(rt->backbuffer, "Render Target Back Buffer"); rt->backbuffer_mipmap0 = RD::get_singleton()->texture_create_shared_from_slice(RD::TextureView(), rt->backbuffer, 0, 0); + RD::get_singleton()->set_resource_name(rt->backbuffer_mipmap0, "Back Buffer slice mipmap 0"); { Vector<RID> fb_tex; @@ -7651,23 +7649,10 @@ void RendererStorageRD::_create_render_target_backbuffer(RenderTarget *rt) { } //create mipmaps for (uint32_t i = 1; i < mipmaps_required; i++) { - RenderTarget::BackbufferMipmap mm; - { - mm.mipmap = RD::get_singleton()->texture_create_shared_from_slice(RD::TextureView(), rt->backbuffer, 0, i); - } - - { - Size2 mm_size = Image::get_image_mipmap_size(tf.width, tf.height, Image::FORMAT_RGBA8, i); + RID mipmap = RD::get_singleton()->texture_create_shared_from_slice(RD::TextureView(), rt->backbuffer, 0, i); + RD::get_singleton()->set_resource_name(mipmap, "Back Buffer slice mip: " + itos(i)); - RD::TextureFormat mmtf = tf; - mmtf.width = mm_size.width; - mmtf.height = mm_size.height; - mmtf.mipmaps = 1; - - mm.mipmap_copy = RD::get_singleton()->texture_create(mmtf, RD::TextureView()); - } - - rt->backbuffer_mipmaps.push_back(mm); + rt->backbuffer_mipmaps.push_back(mipmap); } } @@ -8111,7 +8096,7 @@ void RendererStorageRD::render_target_copy_to_back_buffer(RID p_render_target, c if (!p_gen_mipmaps) { return; } - + RD::get_singleton()->draw_command_begin_label("Gaussian Blur Mipmaps"); //then mipmap blur RID prev_texture = rt->color; //use color, not backbuffer, as bb has mipmaps. @@ -8121,10 +8106,11 @@ void RendererStorageRD::render_target_copy_to_back_buffer(RID p_render_target, c region.size.x = MAX(1, region.size.x >> 1); region.size.y = MAX(1, region.size.y >> 1); - const RenderTarget::BackbufferMipmap &mm = rt->backbuffer_mipmaps[i]; - effects->gaussian_blur(prev_texture, mm.mipmap, mm.mipmap_copy, region, true); - prev_texture = mm.mipmap; + RID mipmap = rt->backbuffer_mipmaps[i]; + effects->gaussian_blur(prev_texture, mipmap, region, true); + prev_texture = mipmap; } + RD::get_singleton()->draw_command_end_label(); } void RendererStorageRD::render_target_clear_back_buffer(RID p_render_target, const Rect2i &p_region, const Color &p_color) { @@ -8164,7 +8150,7 @@ void RendererStorageRD::render_target_gen_back_buffer_mipmaps(RID p_render_targe return; //nothing to do } } - + RD::get_singleton()->draw_command_begin_label("Gaussian Blur Mipmaps2"); //then mipmap blur RID prev_texture = rt->backbuffer_mipmap0; @@ -8174,10 +8160,11 @@ void RendererStorageRD::render_target_gen_back_buffer_mipmaps(RID p_render_targe region.size.x = MAX(1, region.size.x >> 1); region.size.y = MAX(1, region.size.y >> 1); - const RenderTarget::BackbufferMipmap &mm = rt->backbuffer_mipmaps[i]; - effects->gaussian_blur(prev_texture, mm.mipmap, mm.mipmap_copy, region, true); - prev_texture = mm.mipmap; + RID mipmap = rt->backbuffer_mipmaps[i]; + effects->gaussian_blur(prev_texture, mipmap, region, true); + prev_texture = mipmap; } + RD::get_singleton()->draw_command_end_label(); } RID RendererStorageRD::render_target_get_framebuffer_uniform_set(RID p_render_target) { diff --git a/servers/rendering/renderer_rd/renderer_storage_rd.h b/servers/rendering/renderer_rd/renderer_storage_rd.h index 43bbcf6520..6febb71e93 100644 --- a/servers/rendering/renderer_rd/renderer_storage_rd.h +++ b/servers/rendering/renderer_rd/renderer_storage_rd.h @@ -1169,12 +1169,7 @@ private: RID backbuffer_fb; RID backbuffer_mipmap0; - struct BackbufferMipmap { - RID mipmap; - RID mipmap_copy; - }; - - Vector<BackbufferMipmap> backbuffer_mipmaps; + Vector<RID> backbuffer_mipmaps; RID framebuffer_uniform_set; RID backbuffer_uniform_set; diff --git a/servers/rendering/renderer_rd/shaders/copy.glsl b/servers/rendering/renderer_rd/shaders/copy.glsl index d4d0ed0f56..ecf7bb9817 100644 --- a/servers/rendering/renderer_rd/shaders/copy.glsl +++ b/servers/rendering/renderer_rd/shaders/copy.glsl @@ -61,7 +61,7 @@ layout(rgba8, set = 3, binding = 0) uniform restrict writeonly image2D dest_buff layout(rgba32f, set = 3, binding = 0) uniform restrict writeonly image2D dest_buffer; #endif -#ifdef MODE_GAUSSIAN_GLOW +#ifdef MODE_GAUSSIAN_BLUR shared vec4 local_cache[256]; shared vec4 temp_cache[128]; #endif @@ -70,7 +70,7 @@ void main() { // Pixel being shaded ivec2 pos = ivec2(gl_GlobalInvocationID.xy); -#ifndef MODE_GAUSSIAN_GLOW // Glow needs the extra threads +#ifndef MODE_GAUSSIAN_BLUR // Gaussian blur needs the extra threads if (any(greaterThanEqual(pos, params.section.zw))) { //too large, do nothing return; } @@ -92,35 +92,11 @@ void main() { #ifdef MODE_GAUSSIAN_BLUR - //Simpler blur uses SIGMA2 for the gaussian kernel for a stronger effect - - if (bool(params.flags & FLAG_HORIZONTAL)) { - ivec2 base_pos = (pos + params.section.xy) << 1; - vec4 color = texelFetch(source_color, base_pos + ivec2(0, 0), 0) * 0.214607; - color += texelFetch(source_color, base_pos + ivec2(1, 0), 0) * 0.189879; - color += texelFetch(source_color, base_pos + ivec2(2, 0), 0) * 0.131514; - color += texelFetch(source_color, base_pos + ivec2(3, 0), 0) * 0.071303; - color += texelFetch(source_color, base_pos + ivec2(-1, 0), 0) * 0.189879; - color += texelFetch(source_color, base_pos + ivec2(-2, 0), 0) * 0.131514; - color += texelFetch(source_color, base_pos + ivec2(-3, 0), 0) * 0.071303; - imageStore(dest_buffer, pos + params.target, color); - } else { - ivec2 base_pos = (pos + params.section.xy); - vec4 color = texelFetch(source_color, base_pos + ivec2(0, 0), 0) * 0.38774; - color += texelFetch(source_color, base_pos + ivec2(0, 1), 0) * 0.24477; - color += texelFetch(source_color, base_pos + ivec2(0, 2), 0) * 0.06136; - color += texelFetch(source_color, base_pos + ivec2(0, -1), 0) * 0.24477; - color += texelFetch(source_color, base_pos + ivec2(0, -2), 0) * 0.06136; - imageStore(dest_buffer, pos + params.target, color); - } -#endif - -#ifdef MODE_GAUSSIAN_GLOW - // First pass copy texture into 16x16 local memory for every 8x8 thread block vec2 quad_center_uv = clamp(vec2(gl_GlobalInvocationID.xy + gl_LocalInvocationID.xy - 3.5) / params.section.zw, vec2(0.5 / params.section.zw), vec2(1.0 - 1.5 / params.section.zw)); uint dest_index = gl_LocalInvocationID.x * 2 + gl_LocalInvocationID.y * 2 * 16; +#ifdef MODE_GLOW if (bool(params.flags & FLAG_HIGH_QUALITY_GLOW)) { vec2 quad_offset_uv = clamp((vec2(gl_GlobalInvocationID.xy + gl_LocalInvocationID.xy - 3.0)) / params.section.zw, vec2(0.5 / params.section.zw), vec2(1.0 - 1.5 / params.section.zw)); @@ -128,12 +104,15 @@ void main() { local_cache[dest_index + 1] = (textureLod(source_color, quad_center_uv + vec2(1.0 / params.section.z, 0.0), 0) + textureLod(source_color, quad_offset_uv + vec2(1.0 / params.section.z, 0.0), 0)) * 0.5; local_cache[dest_index + 16] = (textureLod(source_color, quad_center_uv + vec2(0.0, 1.0 / params.section.w), 0) + textureLod(source_color, quad_offset_uv + vec2(0.0, 1.0 / params.section.w), 0)) * 0.5; local_cache[dest_index + 16 + 1] = (textureLod(source_color, quad_center_uv + vec2(1.0 / params.section.zw), 0) + textureLod(source_color, quad_offset_uv + vec2(1.0 / params.section.zw), 0)) * 0.5; - } else { + } else +#endif + { local_cache[dest_index] = textureLod(source_color, quad_center_uv, 0); local_cache[dest_index + 1] = textureLod(source_color, quad_center_uv + vec2(1.0 / params.section.z, 0.0), 0); local_cache[dest_index + 16] = textureLod(source_color, quad_center_uv + vec2(0.0, 1.0 / params.section.w), 0); local_cache[dest_index + 16 + 1] = textureLod(source_color, quad_center_uv + vec2(1.0 / params.section.zw), 0); } +#ifdef MODE_GLOW if (bool(params.flags & FLAG_GLOW_FIRST_PASS)) { // Tonemap initial samples to reduce weight of fireflies: https://graphicrants.blogspot.com/2013/12/tone-mapping.html local_cache[dest_index] /= 1.0 + dot(local_cache[dest_index].rgb, vec3(0.299, 0.587, 0.114)); @@ -141,29 +120,33 @@ void main() { local_cache[dest_index + 16] /= 1.0 + dot(local_cache[dest_index + 16].rgb, vec3(0.299, 0.587, 0.114)); local_cache[dest_index + 16 + 1] /= 1.0 + dot(local_cache[dest_index + 16 + 1].rgb, vec3(0.299, 0.587, 0.114)); } - + const float kernel[4] = { 0.174938, 0.165569, 0.140367, 0.106595 }; +#else + // Simpler blur uses SIGMA2 for the gaussian kernel for a stronger effect. + const float kernel[4] = { 0.214607, 0.189879, 0.131514, 0.071303 }; +#endif memoryBarrierShared(); barrier(); // Horizontal pass. Needs to copy into 8x16 chunk of local memory so vertical pass has full resolution uint read_index = gl_LocalInvocationID.x + gl_LocalInvocationID.y * 32 + 4; vec4 color_top = vec4(0.0); - color_top += local_cache[read_index] * 0.174938; - color_top += local_cache[read_index + 1] * 0.165569; - color_top += local_cache[read_index + 2] * 0.140367; - color_top += local_cache[read_index + 3] * 0.106595; - color_top += local_cache[read_index - 1] * 0.165569; - color_top += local_cache[read_index - 2] * 0.140367; - color_top += local_cache[read_index - 3] * 0.106595; + color_top += local_cache[read_index] * kernel[0]; + color_top += local_cache[read_index + 1] * kernel[1]; + color_top += local_cache[read_index + 2] * kernel[2]; + color_top += local_cache[read_index + 3] * kernel[3]; + color_top += local_cache[read_index - 1] * kernel[1]; + color_top += local_cache[read_index - 2] * kernel[2]; + color_top += local_cache[read_index - 3] * kernel[3]; vec4 color_bottom = vec4(0.0); - color_bottom += local_cache[read_index + 16] * 0.174938; - color_bottom += local_cache[read_index + 1 + 16] * 0.165569; - color_bottom += local_cache[read_index + 2 + 16] * 0.140367; - color_bottom += local_cache[read_index + 3 + 16] * 0.106595; - color_bottom += local_cache[read_index - 1 + 16] * 0.165569; - color_bottom += local_cache[read_index - 2 + 16] * 0.140367; - color_bottom += local_cache[read_index - 3 + 16] * 0.106595; + color_bottom += local_cache[read_index + 16] * kernel[0]; + color_bottom += local_cache[read_index + 1 + 16] * kernel[1]; + color_bottom += local_cache[read_index + 2 + 16] * kernel[2]; + color_bottom += local_cache[read_index + 3 + 16] * kernel[3]; + color_bottom += local_cache[read_index - 1 + 16] * kernel[1]; + color_bottom += local_cache[read_index - 2 + 16] * kernel[2]; + color_bottom += local_cache[read_index - 3 + 16] * kernel[3]; // rotate samples to take advantage of cache coherency uint write_index = gl_LocalInvocationID.y * 2 + gl_LocalInvocationID.x * 16; @@ -174,18 +157,24 @@ void main() { memoryBarrierShared(); barrier(); + // If destination outside of texture, can stop doing work now + if (any(greaterThanEqual(pos, params.section.zw))) { + return; + } + // Vertical pass uint index = gl_LocalInvocationID.y + gl_LocalInvocationID.x * 16 + 4; vec4 color = vec4(0.0); - color += temp_cache[index] * 0.174938; - color += temp_cache[index + 1] * 0.165569; - color += temp_cache[index + 2] * 0.140367; - color += temp_cache[index + 3] * 0.106595; - color += temp_cache[index - 1] * 0.165569; - color += temp_cache[index - 2] * 0.140367; - color += temp_cache[index - 3] * 0.106595; + color += temp_cache[index] * kernel[0]; + color += temp_cache[index + 1] * kernel[1]; + color += temp_cache[index + 2] * kernel[2]; + color += temp_cache[index + 3] * kernel[3]; + color += temp_cache[index - 1] * kernel[1]; + color += temp_cache[index - 2] * kernel[2]; + color += temp_cache[index - 3] * kernel[3]; +#ifdef MODE_GLOW if (bool(params.flags & FLAG_GLOW_FIRST_PASS)) { // Undo tonemap to restore range: https://graphicrants.blogspot.com/2013/12/tone-mapping.html color /= 1.0 - dot(color.rgb, vec3(0.299, 0.587, 0.114)); @@ -205,7 +194,7 @@ void main() { color = min(color * feedback, vec4(params.glow_luminance_cap)); } - +#endif imageStore(dest_buffer, pos + params.target, color); #endif diff --git a/tests/scene/test_animation.h b/tests/scene/test_animation.h new file mode 100644 index 0000000000..9199713fd9 --- /dev/null +++ b/tests/scene/test_animation.h @@ -0,0 +1,314 @@ +/*************************************************************************/ +/* test_animation.h */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/*************************************************************************/ + +#ifndef TEST_ANIMATION_H +#define TEST_ANIMATION_H + +#include "scene/resources/animation.h" + +#include "tests/test_macros.h" + +namespace TestAnimation { + +TEST_CASE("[Animation] Empty animation getters") { + const Ref<Animation> animation = memnew(Animation); + + CHECK(Math::is_equal_approx(animation->get_length(), real_t(1.0))); + CHECK(Math::is_equal_approx(animation->get_step(), real_t(0.1))); +} + +TEST_CASE("[Animation] Create value track") { + // This creates an animation that makes the node "Enemy" move to the right by + // 100 pixels in 0.5 seconds. + Ref<Animation> animation = memnew(Animation); + const int track_index = animation->add_track(Animation::TYPE_VALUE); + CHECK(track_index == 0); + animation->track_set_path(track_index, NodePath("Enemy:position:x")); + animation->track_insert_key(track_index, 0.0, 0); + animation->track_insert_key(track_index, 0.5, 100); + + CHECK(animation->get_track_count() == 1); + CHECK(!animation->track_is_compressed(0)); + CHECK(int(animation->track_get_key_value(0, 0)) == 0); + CHECK(int(animation->track_get_key_value(0, 1)) == 100); + + CHECK(Math::is_equal_approx(animation->value_track_interpolate(0, -0.2), 0.0)); + CHECK(Math::is_equal_approx(animation->value_track_interpolate(0, 0.0), 0.0)); + CHECK(Math::is_equal_approx(animation->value_track_interpolate(0, 0.2), 40.0)); + CHECK(Math::is_equal_approx(animation->value_track_interpolate(0, 0.4), 80.0)); + CHECK(Math::is_equal_approx(animation->value_track_interpolate(0, 0.5), 100.0)); + CHECK(Math::is_equal_approx(animation->value_track_interpolate(0, 0.6), 100.0)); + + CHECK(Math::is_equal_approx(animation->track_get_key_transition(0, 0), real_t(1.0))); + CHECK(Math::is_equal_approx(animation->track_get_key_transition(0, 1), real_t(1.0))); + + ERR_PRINT_OFF; + // Nonexistent keys. + CHECK(animation->track_get_key_value(0, 2).is_null()); + CHECK(animation->track_get_key_value(0, -1).is_null()); + CHECK(Math::is_equal_approx(animation->track_get_key_transition(0, 2), real_t(-1.0))); + // Nonexistent track (and keys). + CHECK(animation->track_get_key_value(1, 0).is_null()); + CHECK(animation->track_get_key_value(1, 1).is_null()); + CHECK(animation->track_get_key_value(1, 2).is_null()); + CHECK(animation->track_get_key_value(1, -1).is_null()); + CHECK(Math::is_equal_approx(animation->track_get_key_transition(1, 0), real_t(-1.0))); + + // This is a value track, so the methods below should return errors. + CHECK(animation->position_track_interpolate(0, 0.0, nullptr) == ERR_INVALID_PARAMETER); + CHECK(animation->rotation_track_interpolate(0, 0.0, nullptr) == ERR_INVALID_PARAMETER); + CHECK(animation->scale_track_interpolate(0, 0.0, nullptr) == ERR_INVALID_PARAMETER); + CHECK(Math::is_zero_approx(animation->bezier_track_interpolate(0, 0.0))); + CHECK(animation->blend_shape_track_interpolate(0, 0.0, nullptr) == ERR_INVALID_PARAMETER); + ERR_PRINT_ON; +} + +TEST_CASE("[Animation] Create 3D position track") { + Ref<Animation> animation = memnew(Animation); + const int track_index = animation->add_track(Animation::TYPE_POSITION_3D); + animation->track_set_path(track_index, NodePath("Enemy:position")); + animation->position_track_insert_key(track_index, 0.0, Vector3(0, 1, 2)); + animation->position_track_insert_key(track_index, 0.5, Vector3(3.5, 4, 5)); + + CHECK(animation->get_track_count() == 1); + CHECK(!animation->track_is_compressed(0)); + CHECK(Vector3(animation->track_get_key_value(0, 0)).is_equal_approx(Vector3(0, 1, 2))); + CHECK(Vector3(animation->track_get_key_value(0, 1)).is_equal_approx(Vector3(3.5, 4, 5))); + + Vector3 r_interpolation; + + CHECK(animation->position_track_interpolate(0, -0.2, &r_interpolation) == OK); + CHECK(r_interpolation.is_equal_approx(Vector3(0, 1, 2))); + + CHECK(animation->position_track_interpolate(0, 0.0, &r_interpolation) == OK); + CHECK(r_interpolation.is_equal_approx(Vector3(0, 1, 2))); + + CHECK(animation->position_track_interpolate(0, 0.2, &r_interpolation) == OK); + CHECK(r_interpolation.is_equal_approx(Vector3(1.4, 2.2, 3.2))); + + CHECK(animation->position_track_interpolate(0, 0.4, &r_interpolation) == OK); + CHECK(r_interpolation.is_equal_approx(Vector3(2.8, 3.4, 4.4))); + + CHECK(animation->position_track_interpolate(0, 0.5, &r_interpolation) == OK); + CHECK(r_interpolation.is_equal_approx(Vector3(3.5, 4, 5))); + + CHECK(animation->position_track_interpolate(0, 0.6, &r_interpolation) == OK); + CHECK(r_interpolation.is_equal_approx(Vector3(3.5, 4, 5))); + + // 3D position tracks always use linear interpolation for performance reasons. + CHECK(Math::is_equal_approx(animation->track_get_key_transition(0, 0), real_t(1.0))); + CHECK(Math::is_equal_approx(animation->track_get_key_transition(0, 1), real_t(1.0))); + + // This is a 3D position track, so the methods below should return errors. + ERR_PRINT_OFF; + CHECK(animation->value_track_interpolate(0, 0.0).is_null()); + CHECK(animation->rotation_track_interpolate(0, 0.0, nullptr) == ERR_INVALID_PARAMETER); + CHECK(animation->scale_track_interpolate(0, 0.0, nullptr) == ERR_INVALID_PARAMETER); + CHECK(Math::is_zero_approx(animation->bezier_track_interpolate(0, 0.0))); + CHECK(animation->blend_shape_track_interpolate(0, 0.0, nullptr) == ERR_INVALID_PARAMETER); + ERR_PRINT_ON; +} + +TEST_CASE("[Animation] Create 3D rotation track") { + Ref<Animation> animation = memnew(Animation); + const int track_index = animation->add_track(Animation::TYPE_ROTATION_3D); + animation->track_set_path(track_index, NodePath("Enemy:rotation")); + animation->rotation_track_insert_key(track_index, 0.0, Quaternion(Vector3(0, 1, 2))); + animation->rotation_track_insert_key(track_index, 0.5, Quaternion(Vector3(3.5, 4, 5))); + + CHECK(animation->get_track_count() == 1); + CHECK(!animation->track_is_compressed(0)); + CHECK(Quaternion(animation->track_get_key_value(0, 0)).is_equal_approx(Quaternion(Vector3(0, 1, 2)))); + CHECK(Quaternion(animation->track_get_key_value(0, 1)).is_equal_approx(Quaternion(Vector3(3.5, 4, 5)))); + + Quaternion r_interpolation; + + CHECK(animation->rotation_track_interpolate(0, -0.2, &r_interpolation) == OK); + CHECK(r_interpolation.is_equal_approx(Quaternion(0.403423, 0.259035, 0.73846, 0.47416))); + + CHECK(animation->rotation_track_interpolate(0, 0.0, &r_interpolation) == OK); + CHECK(r_interpolation.is_equal_approx(Quaternion(0.403423, 0.259035, 0.73846, 0.47416))); + + CHECK(animation->rotation_track_interpolate(0, 0.2, &r_interpolation) == OK); + CHECK(r_interpolation.is_equal_approx(Quaternion(0.336182, 0.30704, 0.751515, 0.477425))); + + CHECK(animation->rotation_track_interpolate(0, 0.4, &r_interpolation) == OK); + CHECK(r_interpolation.is_equal_approx(Quaternion(0.266585, 0.352893, 0.759303, 0.477344))); + + CHECK(animation->rotation_track_interpolate(0, 0.5, &r_interpolation) == OK); + CHECK(r_interpolation.is_equal_approx(Quaternion(0.231055, 0.374912, 0.761204, 0.476048))); + + CHECK(animation->rotation_track_interpolate(0, 0.6, &r_interpolation) == OK); + CHECK(r_interpolation.is_equal_approx(Quaternion(0.231055, 0.374912, 0.761204, 0.476048))); + + // 3D rotation tracks always use linear interpolation for performance reasons. + CHECK(Math::is_equal_approx(animation->track_get_key_transition(0, 0), real_t(1.0))); + CHECK(Math::is_equal_approx(animation->track_get_key_transition(0, 1), real_t(1.0))); + + // This is a 3D rotation track, so the methods below should return errors. + ERR_PRINT_OFF; + CHECK(animation->value_track_interpolate(0, 0.0).is_null()); + CHECK(animation->position_track_interpolate(0, 0.0, nullptr) == ERR_INVALID_PARAMETER); + CHECK(animation->scale_track_interpolate(0, 0.0, nullptr) == ERR_INVALID_PARAMETER); + CHECK(Math::is_zero_approx(animation->bezier_track_interpolate(0, 0.0))); + CHECK(animation->blend_shape_track_interpolate(0, 0.0, nullptr) == ERR_INVALID_PARAMETER); + ERR_PRINT_ON; +} + +TEST_CASE("[Animation] Create 3D scale track") { + Ref<Animation> animation = memnew(Animation); + const int track_index = animation->add_track(Animation::TYPE_SCALE_3D); + animation->track_set_path(track_index, NodePath("Enemy:scale")); + animation->scale_track_insert_key(track_index, 0.0, Vector3(0, 1, 2)); + animation->scale_track_insert_key(track_index, 0.5, Vector3(3.5, 4, 5)); + + CHECK(animation->get_track_count() == 1); + CHECK(!animation->track_is_compressed(0)); + CHECK(Vector3(animation->track_get_key_value(0, 0)).is_equal_approx(Vector3(0, 1, 2))); + CHECK(Vector3(animation->track_get_key_value(0, 1)).is_equal_approx(Vector3(3.5, 4, 5))); + + Vector3 r_interpolation; + + CHECK(animation->scale_track_interpolate(0, -0.2, &r_interpolation) == OK); + CHECK(r_interpolation.is_equal_approx(Vector3(0, 1, 2))); + + CHECK(animation->scale_track_interpolate(0, 0.0, &r_interpolation) == OK); + CHECK(r_interpolation.is_equal_approx(Vector3(0, 1, 2))); + + CHECK(animation->scale_track_interpolate(0, 0.2, &r_interpolation) == OK); + CHECK(r_interpolation.is_equal_approx(Vector3(1.4, 2.2, 3.2))); + + CHECK(animation->scale_track_interpolate(0, 0.4, &r_interpolation) == OK); + CHECK(r_interpolation.is_equal_approx(Vector3(2.8, 3.4, 4.4))); + + CHECK(animation->scale_track_interpolate(0, 0.5, &r_interpolation) == OK); + CHECK(r_interpolation.is_equal_approx(Vector3(3.5, 4, 5))); + + CHECK(animation->scale_track_interpolate(0, 0.6, &r_interpolation) == OK); + CHECK(r_interpolation.is_equal_approx(Vector3(3.5, 4, 5))); + + // 3D scale tracks always use linear interpolation for performance reasons. + CHECK(Math::is_equal_approx(animation->track_get_key_transition(0, 0), real_t(1.0))); + CHECK(Math::is_equal_approx(animation->track_get_key_transition(0, 1), real_t(1.0))); + + // This is a 3D scale track, so the methods below should return errors. + ERR_PRINT_OFF; + CHECK(animation->value_track_interpolate(0, 0.0).is_null()); + CHECK(animation->position_track_interpolate(0, 0.0, nullptr) == ERR_INVALID_PARAMETER); + CHECK(animation->rotation_track_interpolate(0, 0.0, nullptr) == ERR_INVALID_PARAMETER); + CHECK(Math::is_zero_approx(animation->bezier_track_interpolate(0, 0.0))); + CHECK(animation->blend_shape_track_interpolate(0, 0.0, nullptr) == ERR_INVALID_PARAMETER); + ERR_PRINT_ON; +} + +TEST_CASE("[Animation] Create blend shape track") { + Ref<Animation> animation = memnew(Animation); + const int track_index = animation->add_track(Animation::TYPE_BLEND_SHAPE); + animation->track_set_path(track_index, NodePath("Enemy:scale")); + // Negative values for blend shapes should work as expected. + animation->blend_shape_track_insert_key(track_index, 0.0, -1.0); + animation->blend_shape_track_insert_key(track_index, 0.5, 1.0); + + CHECK(animation->get_track_count() == 1); + CHECK(!animation->track_is_compressed(0)); + + float r_blend = 0.0f; + + CHECK(animation->blend_shape_track_get_key(0, 0, &r_blend) == OK); + CHECK(Math::is_equal_approx(r_blend, -1.0f)); + + CHECK(animation->blend_shape_track_get_key(0, 1, &r_blend) == OK); + CHECK(Math::is_equal_approx(r_blend, 1.0f)); + + CHECK(animation->blend_shape_track_interpolate(0, -0.2, &r_blend) == OK); + CHECK(Math::is_equal_approx(r_blend, -1.0f)); + + CHECK(animation->blend_shape_track_interpolate(0, 0.0, &r_blend) == OK); + CHECK(Math::is_equal_approx(r_blend, -1.0f)); + + CHECK(animation->blend_shape_track_interpolate(0, 0.2, &r_blend) == OK); + CHECK(Math::is_equal_approx(r_blend, -0.2f)); + + CHECK(animation->blend_shape_track_interpolate(0, 0.4, &r_blend) == OK); + CHECK(Math::is_equal_approx(r_blend, 0.6f)); + + CHECK(animation->blend_shape_track_interpolate(0, 0.5, &r_blend) == OK); + CHECK(Math::is_equal_approx(r_blend, 1.0f)); + + CHECK(animation->blend_shape_track_interpolate(0, 0.6, &r_blend) == OK); + CHECK(Math::is_equal_approx(r_blend, 1.0f)); + + // Blend shape tracks always use linear interpolation for performance reasons. + CHECK(Math::is_equal_approx(animation->track_get_key_transition(0, 0), real_t(1.0))); + CHECK(Math::is_equal_approx(animation->track_get_key_transition(0, 1), real_t(1.0))); + + // This is a blend shape track, so the methods below should return errors. + ERR_PRINT_OFF; + CHECK(animation->value_track_interpolate(0, 0.0).is_null()); + CHECK(animation->position_track_interpolate(0, 0.0, nullptr) == ERR_INVALID_PARAMETER); + CHECK(animation->rotation_track_interpolate(0, 0.0, nullptr) == ERR_INVALID_PARAMETER); + CHECK(animation->scale_track_interpolate(0, 0.0, nullptr) == ERR_INVALID_PARAMETER); + CHECK(Math::is_zero_approx(animation->bezier_track_interpolate(0, 0.0))); + ERR_PRINT_ON; +} + +TEST_CASE("[Animation] Create Bezier track") { + Ref<Animation> animation = memnew(Animation); + const int track_index = animation->add_track(Animation::TYPE_BEZIER); + animation->track_set_path(track_index, NodePath("Enemy:scale")); + animation->bezier_track_insert_key(track_index, 0.0, -1.0, Vector2(-1, -1), Vector2(1, 1)); + animation->bezier_track_insert_key(track_index, 0.5, 1.0, Vector2(0, 1), Vector2(1, 0.5)); + + CHECK(animation->get_track_count() == 1); + CHECK(!animation->track_is_compressed(0)); + + CHECK(Math::is_equal_approx(animation->bezier_track_get_key_value(0, 0), real_t(-1.0))); + CHECK(Math::is_equal_approx(animation->bezier_track_get_key_value(0, 1), real_t(1.0))); + + CHECK(Math::is_equal_approx(animation->bezier_track_interpolate(0, -0.2), real_t(-1.0))); + CHECK(Math::is_equal_approx(animation->bezier_track_interpolate(0, 0.0), real_t(-1.0))); + CHECK(Math::is_equal_approx(animation->bezier_track_interpolate(0, 0.2), real_t(-0.76057207584381))); + CHECK(Math::is_equal_approx(animation->bezier_track_interpolate(0, 0.4), real_t(-0.39975279569626))); + CHECK(Math::is_equal_approx(animation->bezier_track_interpolate(0, 0.5), real_t(1.0))); + CHECK(Math::is_equal_approx(animation->bezier_track_interpolate(0, 0.6), real_t(1.0))); + + // This is a bezier track, so the methods below should return errors. + ERR_PRINT_OFF; + CHECK(animation->value_track_interpolate(0, 0.0).is_null()); + CHECK(animation->position_track_interpolate(0, 0.0, nullptr) == ERR_INVALID_PARAMETER); + CHECK(animation->rotation_track_interpolate(0, 0.0, nullptr) == ERR_INVALID_PARAMETER); + CHECK(animation->scale_track_interpolate(0, 0.0, nullptr) == ERR_INVALID_PARAMETER); + CHECK(animation->blend_shape_track_interpolate(0, 0.0, nullptr) == ERR_INVALID_PARAMETER); + ERR_PRINT_ON; +} + +} // namespace TestAnimation + +#endif // TEST_ANIMATION_H diff --git a/tests/scene/test_gui.cpp b/tests/scene/test_gui.cpp index cd5624b70c..9da6063c7b 100644 --- a/tests/scene/test_gui.cpp +++ b/tests/scene/test_gui.cpp @@ -103,7 +103,7 @@ public: item->set_editable(0, true); item->set_range_config(0, 0, 20, 0.1); item->set_range(0, 2); - item->add_button(0, Theme::get_default()->get_icon("folder", "FileDialog")); + item->add_button(0, Theme::get_default()->get_icon(SNAME("folder"), SNAME("FileDialog"))); item->set_cell_mode(1, TreeItem::CELL_MODE_RANGE); item->set_editable(1, true); item->set_range_config(1, 0, 20, 0.1); diff --git a/tests/test_main.cpp b/tests/test_main.cpp index 3b51a6d805..504b83c2b0 100644 --- a/tests/test_main.cpp +++ b/tests/test_main.cpp @@ -73,6 +73,7 @@ #include "tests/core/variant/test_array.h" #include "tests/core/variant/test_dictionary.h" #include "tests/core/variant/test_variant.h" +#include "tests/scene/test_animation.h" #include "tests/scene/test_code_edit.h" #include "tests/scene/test_curve.h" #include "tests/scene/test_gradient.h" |