diff options
69 files changed, 509 insertions, 544 deletions
diff --git a/core/input_map.cpp b/core/input_map.cpp index 51e3f311a9..b88d99470a 100644 --- a/core/input_map.cpp +++ b/core/input_map.cpp @@ -199,6 +199,10 @@ bool InputMap::event_get_action_status(const Ref<InputEvent> &p_event, const Str Ref<InputEventAction> input_event_action = p_event; if (input_event_action.is_valid()) { + if (p_pressed != NULL) + *p_pressed = input_event_action->is_pressed(); + if (p_strength != NULL) + *p_strength = (*p_pressed) ? 1.0f : 0.0f; return input_event_action->get_action() == p_action; } diff --git a/core/io/multiplayer_api.cpp b/core/io/multiplayer_api.cpp index 1179b1bfd6..5503b8d59c 100644 --- a/core/io/multiplayer_api.cpp +++ b/core/io/multiplayer_api.cpp @@ -45,8 +45,7 @@ _FORCE_INLINE_ bool _should_call_local(MultiplayerAPI::RPCMode mode, bool is_mas } break; case MultiplayerAPI::RPC_MODE_REMOTESYNC: case MultiplayerAPI::RPC_MODE_MASTERSYNC: - case MultiplayerAPI::RPC_MODE_SLAVESYNC: - case MultiplayerAPI::RPC_MODE_SYNC: { + case MultiplayerAPI::RPC_MODE_PUPPETSYNC: { //call it, sync always results in call return true; } break; @@ -55,7 +54,7 @@ _FORCE_INLINE_ bool _should_call_local(MultiplayerAPI::RPCMode mode, bool is_mas r_skip_rpc = true; //no other master so.. return is_master; } break; - case MultiplayerAPI::RPC_MODE_SLAVE: { + case MultiplayerAPI::RPC_MODE_PUPPET: { return !is_master; } break; } @@ -68,19 +67,16 @@ _FORCE_INLINE_ bool _can_call_mode(Node *p_node, MultiplayerAPI::RPCMode mode, i case MultiplayerAPI::RPC_MODE_DISABLED: { return false; } break; - case MultiplayerAPI::RPC_MODE_REMOTE: { - return true; - } break; - case MultiplayerAPI::RPC_MODE_REMOTESYNC: - case MultiplayerAPI::RPC_MODE_SYNC: { + case MultiplayerAPI::RPC_MODE_REMOTE: + case MultiplayerAPI::RPC_MODE_REMOTESYNC: { return true; } break; case MultiplayerAPI::RPC_MODE_MASTERSYNC: case MultiplayerAPI::RPC_MODE_MASTER: { return p_node->is_network_master(); } break; - case MultiplayerAPI::RPC_MODE_SLAVESYNC: - case MultiplayerAPI::RPC_MODE_SLAVE: { + case MultiplayerAPI::RPC_MODE_PUPPETSYNC: + case MultiplayerAPI::RPC_MODE_PUPPET: { return !p_node->is_network_master() && p_remote_id == p_node->get_network_master(); } break; } @@ -804,12 +800,13 @@ void MultiplayerAPI::_bind_methods() { BIND_ENUM_CONSTANT(RPC_MODE_DISABLED); BIND_ENUM_CONSTANT(RPC_MODE_REMOTE); - BIND_ENUM_CONSTANT(RPC_MODE_SYNC); BIND_ENUM_CONSTANT(RPC_MODE_MASTER); - BIND_ENUM_CONSTANT(RPC_MODE_SLAVE); + BIND_ENUM_CONSTANT(RPC_MODE_PUPPET); + BIND_ENUM_CONSTANT(RPC_MODE_SLAVE); // deprecated BIND_ENUM_CONSTANT(RPC_MODE_REMOTESYNC); + BIND_ENUM_CONSTANT(RPC_MODE_SYNC); // deprecated BIND_ENUM_CONSTANT(RPC_MODE_MASTERSYNC); - BIND_ENUM_CONSTANT(RPC_MODE_SLAVESYNC); + BIND_ENUM_CONSTANT(RPC_MODE_PUPPETSYNC); } MultiplayerAPI::MultiplayerAPI() { diff --git a/core/io/multiplayer_api.h b/core/io/multiplayer_api.h index e47b1830e8..c86e76e91a 100644 --- a/core/io/multiplayer_api.h +++ b/core/io/multiplayer_api.h @@ -91,12 +91,13 @@ public: RPC_MODE_DISABLED, // No rpc for this method, calls to this will be blocked (default) RPC_MODE_REMOTE, // Using rpc() on it will call method / set property in all remote peers - RPC_MODE_SYNC, // Using rpc() on it will call method / set property in all remote peers and locally RPC_MODE_MASTER, // Using rpc() on it will call method on wherever the master is, be it local or remote - RPC_MODE_SLAVE, // Using rpc() on it will call method for all slaves - RPC_MODE_REMOTESYNC, // Same as RPC_MODE_SYNC, compatibility + RPC_MODE_PUPPET, // Using rpc() on it will call method for all puppets + RPC_MODE_SLAVE = RPC_MODE_PUPPET, // Deprecated, same as puppet + RPC_MODE_REMOTESYNC, // Using rpc() on it will call method / set property in all remote peers and locally + RPC_MODE_SYNC = RPC_MODE_REMOTESYNC, // Deprecated. Same as RPC_MODE_REMOTESYNC RPC_MODE_MASTERSYNC, // Using rpc() on it will call method / set property in the master peer and locally - RPC_MODE_SLAVESYNC, // Using rpc() on it will call method / set property in all slave peers and locally + RPC_MODE_PUPPETSYNC, // Using rpc() on it will call method / set property in all puppets peers and locally }; void poll(); diff --git a/core/os/input_event.cpp b/core/os/input_event.cpp index cc359ef2ac..5bbdd7efb2 100644 --- a/core/os/input_event.cpp +++ b/core/os/input_event.cpp @@ -962,6 +962,22 @@ bool InputEventAction::is_action(const StringName &p_action) const { return action == p_action; } +bool InputEventAction::action_match(const Ref<InputEvent> &p_event, bool *p_pressed, float *p_strength, float p_deadzone) const { + + Ref<InputEventAction> act = p_event; + if (act.is_null()) + return false; + + bool match = action == act->action; + if (match) { + if (p_pressed != NULL) + *p_pressed = act->pressed; + if (p_strength != NULL) + *p_strength = (*p_pressed) ? 1.0f : 0.0f; + } + return match; +} + String InputEventAction::as_text() const { return "InputEventAction : action=" + action + ", pressed=(" + (pressed ? "true" : "false"); diff --git a/core/os/input_event.h b/core/os/input_event.h index cb61e61e7c..789d19c5b2 100644 --- a/core/os/input_event.h +++ b/core/os/input_event.h @@ -481,6 +481,8 @@ public: virtual bool is_action(const StringName &p_action) const; + virtual bool action_match(const Ref<InputEvent> &p_event, bool *p_pressed, float *p_strength, float p_deadzone) const; + virtual bool shortcut_match(const Ref<InputEvent> &p_event) const; virtual bool is_action_type() const { return true; } virtual String as_text() const; diff --git a/doc/classes/Input.xml b/doc/classes/Input.xml index a0bb585583..d9929b3d31 100644 --- a/doc/classes/Input.xml +++ b/doc/classes/Input.xml @@ -293,7 +293,7 @@ <argument index="2" name="hotspot" type="Vector2" default="Vector2( 0, 0 )"> </argument> <description> - Set a custom mouse cursor image, which is only visible inside the game window. The hotspot can also be specified. Passing [code]null[/code] to the image parameter resets to the system cursor. See enum [code]CURSOR_*[/code] for the list of shapes. + Sets a custom mouse cursor image, which is only visible inside the game window. The hotspot can also be specified. Passing [code]null[/code] to the image parameter resets to the system cursor. See enum [code]CURSOR_*[/code] for the list of shapes. [code]image[/code]'s size must be lower than 256x256. [code]hotspot[/code] must be within [code]image[/code]'s size. </description> @@ -304,6 +304,8 @@ <argument index="0" name="shape" type="int" enum="Input.CursorShape" default="0"> </argument> <description> + Sets the default cursor shape to be used in the viewport instead of [code]CURSOR_ARROW[/code]. + Note that if you want to change the default cursor shape for [Control]'s nodes, use [member Control.mouse_default_cursor_shape] instead. </description> </method> <method name="set_mouse_mode"> diff --git a/doc/classes/MultiplayerAPI.xml b/doc/classes/MultiplayerAPI.xml index 10e7f1b172..d8d7d9acfc 100644 --- a/doc/classes/MultiplayerAPI.xml +++ b/doc/classes/MultiplayerAPI.xml @@ -90,7 +90,7 @@ </methods> <members> <member name="network_peer" type="NetworkedMultiplayerPeer" setter="set_network_peer" getter="get_network_peer"> - The peer object to handle the RPC system (effectively enabling networking when set). Depending on the peer itself, the MultiplayerAPI will become a network server (check with [method is_network_server]) and will set root node's network mode to master (see NETWORK_MODE_* constants in [Node]), or it will become a regular peer with root node set to slave. All child nodes are set to inherit the network mode by default. Handling of networking-related events (connection, disconnection, new clients) is done by connecting to MultiplayerAPI's signals. + The peer object to handle the RPC system (effectively enabling networking when set). Depending on the peer itself, the MultiplayerAPI will become a network server (check with [method is_network_server]) and will set root node's network mode to master (see NETWORK_MODE_* constants in [Node]), or it will become a regular peer with root node set to puppet. All child nodes are set to inherit the network mode by default. Handling of networking-related events (connection, disconnection, new clients) is done by connecting to MultiplayerAPI's signals. </member> <member name="refuse_new_network_connections" type="bool" setter="set_refuse_new_network_connections" getter="is_refusing_new_network_connections"> If [code]true[/code] the MultiplayerAPI's [member network_peer] refuses new incoming connections. @@ -141,25 +141,28 @@ Used with [method Node.rpc_config] or [method Node.rset_config] to disable a method or property for all RPC calls, making it unavailable. Default for all methods. </constant> <constant name="RPC_MODE_REMOTE" value="1" enum="RPCMode"> - Used with [method Node.rpc_config] or [method Node.rset_config] to set a method to be called or a property to be changed only on the remote end, not locally. Analogous to the [code]remote[/code] keyword. Calls and property changes are accepted from all remote peers, no matter if they are node's master or slaves. + Used with [method Node.rpc_config] or [method Node.rset_config] to set a method to be called or a property to be changed only on the remote end, not locally. Analogous to the [code]remote[/code] keyword. Calls and property changes are accepted from all remote peers, no matter if they are node's master or puppets. </constant> - <constant name="RPC_MODE_SYNC" value="2" enum="RPCMode"> - Behave like [code]RPC_MODE_REMOTE[/code] but also make the call or property change locally. Analogous to the [code]sync[/code] keyword. + <constant name="RPC_MODE_MASTER" value="2" enum="RPCMode"> + Used with [method Node.rpc_config] or [method Node.rset_config] to set a method to be called or a property to be changed only on the network master for this node. Analogous to the [code]master[/code] keyword. Only accepts calls or property changes from the node's network puppets, see [method Node.set_network_master]. </constant> - <constant name="RPC_MODE_MASTER" value="3" enum="RPCMode"> - Used with [method Node.rpc_config] or [method Node.rset_config] to set a method to be called or a property to be changed only on the network master for this node. Analogous to the [code]master[/code] keyword. Only accepts calls or property changes from the node's network slaves, see [method Node.set_network_master]. + <constant name="RPC_MODE_PUPPET" value="3" enum="RPCMode"> + Used with [method Node.rpc_config] or [method Node.rset_config] to set a method to be called or a property to be changed only on puppets for this node. Analogous to the [code]puppet[/code] keyword. Only accepts calls or property changes from the node's network master, see [method Node.set_network_master]. </constant> - <constant name="RPC_MODE_SLAVE" value="4" enum="RPCMode"> - Used with [method Node.rpc_config] or [method Node.rset_config] to set a method to be called or a property to be changed only on slaves for this node. Analogous to the [code]slave[/code] keyword. Only accepts calls or property changes from the node's network master, see [method Node.set_network_master]. + <constant name="RPC_MODE_SLAVE" value="3" enum="RPCMode"> + Deprecated. Use [code]RPC_MODE_PUPPET[/code] instead. Analogous to the [code]slave[/code] keyword. </constant> - <constant name="RPC_MODE_REMOTESYNC" value="5" enum="RPCMode"> - Behave like [code]RPC_MODE_REMOTE[/code] but also make the call or property change locally. Same as [code]RPC_MODE_SYNC[/code] which is only kept for compatibility. Analogous to the [code]remotesync[/code] keyword. + <constant name="RPC_MODE_REMOTESYNC" value="4" enum="RPCMode"> + Behave like [code]RPC_MODE_REMOTE[/code] but also make the call or property change locally. Analogous to the [code]remotesync[/code] keyword. </constant> - <constant name="RPC_MODE_MASTERSYNC" value="6" enum="RPCMode"> + <constant name="RPC_MODE_SYNC" value="4" enum="RPCMode"> + Deprecated. Use [code]RPC_MODE_REMOTESYNC[/code] instead. Analogous to the [code]sync[/code] keyword. + </constant> + <constant name="RPC_MODE_MASTERSYNC" value="5" enum="RPCMode"> Behave like [code]RPC_MODE_MASTER[/code] but also make the call or property change locally. Analogous to the [code]mastersync[/code] keyword. </constant> - <constant name="RPC_MODE_SLAVESYNC" value="7" enum="RPCMode"> - Behave like [code]RPC_MODE_SLAVE[/code] but also make the call or property change locally. Analogous to the [code]slavesync[/code] keyword. + <constant name="RPC_MODE_PUPPETSYNC" value="6" enum="RPCMode"> + Behave like [code]RPC_MODE_PUPPET[/code] but also make the call or property change locally. Analogous to the [code]puppetsync[/code] keyword. </constant> </constants> </class> diff --git a/doc/classes/Node.xml b/doc/classes/Node.xml index d8b8f1fb43..d00652d40c 100644 --- a/doc/classes/Node.xml +++ b/doc/classes/Node.xml @@ -582,7 +582,7 @@ <argument index="1" name="mode" type="int" enum="MultiplayerAPI.RPCMode"> </argument> <description> - Changes the RPC mode for the given [code]method[/code] to the given [code]mode[/code]. See [enum MultiplayerAPI.RPCMode]. An alternative is annotating methods and properties with the corresponding keywords ([code]remote[/code], [code]sync[/code], [code]master[/code], [code]slave[/code]). By default, methods are not exposed to networking (and RPCs). Also see [method rset] and [method rset_config] for properties. + Changes the RPC mode for the given [code]method[/code] to the given [code]mode[/code]. See [enum MultiplayerAPI.RPCMode]. An alternative is annotating methods and properties with the corresponding keywords ([code]remote[/code], [code]master[/code], [code]puppet[/code], [code]remotesync[/code], [code]mastersync[/code], [code]puppetsync[/code]). By default, methods are not exposed to networking (and RPCs). Also see [method rset] and [method rset_config] for properties. </description> </method> <method name="rpc_id" qualifiers="vararg"> @@ -635,7 +635,7 @@ <argument index="1" name="mode" type="int" enum="MultiplayerAPI.RPCMode"> </argument> <description> - Changes the RPC mode for the given [code]property[/code] to the given [code]mode[/code]. See [enum MultiplayerAPI.RPCMode]. An alternative is annotating methods and properties with the corresponding keywords ([code]remote[/code], [code]sync[/code], [code]master[/code], [code]slave[/code]). By default, properties are not exposed to networking (and RPCs). Also see [method rpc] and [method rpc_config] for methods. + Changes the RPC mode for the given [code]property[/code] to the given [code]mode[/code]. See [enum MultiplayerAPI.RPCMode]. An alternative is annotating methods and properties with the corresponding keywords ([code]remote[/code], [code]master[/code], [code]puppet[/code], [code]remotesync[/code], [code]mastersync[/code], [code]puppetsync[/code]). By default, properties are not exposed to networking (and RPCs). Also see [method rpc] and [method rpc_config] for methods. </description> </method> <method name="rset_id"> @@ -692,7 +692,7 @@ <argument index="1" name="recursive" type="bool" default="true"> </argument> <description> - Sets the node's network master to the peer with the given peer ID. The network master is the peer that has authority over the node on the network. Useful in conjunction with the [code]master[/code] and [code]slave[/code] keywords. Inherited from the parent node by default, which ultimately defaults to peer ID 1 (the server). If [code]recursive[/code], the given peer is recursively set as the master for all children of this node. + Sets the node's network master to the peer with the given peer ID. The network master is the peer that has authority over the node on the network. Useful in conjunction with the [code]master[/code] and [code]puppet[/code] keywords. Inherited from the parent node by default, which ultimately defaults to peer ID 1 (the server). If [code]recursive[/code], the given peer is recursively set as the master for all children of this node. </description> </method> <method name="set_physics_process"> diff --git a/doc/classes/ProjectSettings.xml b/doc/classes/ProjectSettings.xml index b0d1cf8619..548d60fe35 100644 --- a/doc/classes/ProjectSettings.xml +++ b/doc/classes/ProjectSettings.xml @@ -157,6 +157,8 @@ </method> </methods> <members> + <member name="application/boot_splash/bg_color" type="Color" setter="" getter=""> + </member> <member name="application/boot_splash/fullsize" type="bool" setter="" getter=""> Scale the boot splash image to the full window length when engine starts (will leave it as default pixel size otherwise). </member> @@ -226,6 +228,8 @@ </member> <member name="debug/gdscript/warnings/constant_used_as_function" type="bool" setter="" getter=""> </member> + <member name="debug/gdscript/warnings/deprecated_keyword" type="bool" setter="" getter=""> + </member> <member name="debug/gdscript/warnings/enable" type="bool" setter="" getter=""> </member> <member name="debug/gdscript/warnings/function_conflicts_constant" type="bool" setter="" getter=""> diff --git a/doc/classes/SceneTree.xml b/doc/classes/SceneTree.xml index a447294fea..1985845552 100644 --- a/doc/classes/SceneTree.xml +++ b/doc/classes/SceneTree.xml @@ -274,7 +274,7 @@ When [code]false[/code] you need to manually call [method MultiplayerAPI.poll] for processing network packets and delivering RPCs/RSETs. This allows to run RPCs/RSETs in a different loop (e.g. physics, thread, specific time step) and for manual [Mutex] protection when accessing the [MultiplayerAPI] from threads. </member> <member name="network_peer" type="NetworkedMultiplayerPeer" setter="set_network_peer" getter="get_network_peer"> - The peer object to handle the RPC system (effectively enabling networking when set). Depending on the peer itself, the SceneTree will become a network server (check with [method is_network_server()]) and will set root node's network mode to master (see NETWORK_MODE_* constants in [Node]), or it will become a regular peer with root node set to slave. All child nodes are set to inherit the network mode by default. Handling of networking-related events (connection, disconnection, new clients) is done by connecting to SceneTree's signals. + The peer object to handle the RPC system (effectively enabling networking when set). Depending on the peer itself, the SceneTree will become a network server (check with [method is_network_server()]) and will set root node's network mode to master (see NETWORK_MODE_* constants in [Node]), or it will become a regular peer with root node set to puppet. All child nodes are set to inherit the network mode by default. Handling of networking-related events (connection, disconnection, new clients) is done by connecting to SceneTree's signals. </member> <member name="paused" type="bool" setter="set_pause" getter="is_paused"> If [code]true[/code] the SceneTree is paused. diff --git a/doc/classes/ShaderMaterial.xml b/doc/classes/ShaderMaterial.xml index 5abba9fba9..7491d22479 100644 --- a/doc/classes/ShaderMaterial.xml +++ b/doc/classes/ShaderMaterial.xml @@ -20,6 +20,22 @@ Returns the current value set for this material of a uniform in the shader. </description> </method> + <method name="property_can_revert"> + <return type="bool"> + </return> + <argument index="0" name="name" type="String"> + </argument> + <description> + </description> + </method> + <method name="property_get_revert"> + <return type="Variant"> + </return> + <argument index="0" name="name" type="String"> + </argument> + <description> + </description> + </method> <method name="set_shader_param"> <return type="void"> </return> diff --git a/doc/classes/Viewport.xml b/doc/classes/Viewport.xml index 2f5710da51..9cd501630e 100644 --- a/doc/classes/Viewport.xml +++ b/doc/classes/Viewport.xml @@ -46,6 +46,13 @@ Returns the total transform of the viewport. </description> </method> + <method name="get_modal_stack_top" qualifiers="const"> + <return type="Control"> + </return> + <description> + Returns the topmost modal in the stack. + </description> + </method> <method name="get_mouse_position" qualifiers="const"> <return type="Vector2"> </return> diff --git a/doc/classes/VisualServer.xml b/doc/classes/VisualServer.xml index afada05bf7..58b3d33cdb 100644 --- a/doc/classes/VisualServer.xml +++ b/doc/classes/VisualServer.xml @@ -2185,6 +2185,16 @@ Returns the value of a certain material's parameter. </description> </method> + <method name="material_get_param_default" qualifiers="const"> + <return type="Variant"> + </return> + <argument index="0" name="material" type="RID"> + </argument> + <argument index="1" name="parameter" type="String"> + </argument> + <description> + </description> + </method> <method name="material_get_shader" qualifiers="const"> <return type="RID"> </return> diff --git a/editor/animation_bezier_editor.cpp b/editor/animation_bezier_editor.cpp index 04977dbb47..f0dc3ce305 100644 --- a/editor/animation_bezier_editor.cpp +++ b/editor/animation_bezier_editor.cpp @@ -30,6 +30,8 @@ #include "animation_bezier_editor.h" +#include "editor/editor_node.h" + float AnimationBezierTrackEdit::_bezier_h_to_pixel(float p_h) { float h = p_h; h = (h - v_scroll) / v_zoom; @@ -288,12 +290,7 @@ void AnimationBezierTrackEdit::_notification(int p_what) { int h = font->get_height(); if (node) { - Ref<Texture> icon; - if (has_icon(node->get_class(), "EditorIcons")) { - icon = get_icon(node->get_class(), "EditorIcons"); - } else { - icon = get_icon("Node", "EditorIcons"); - } + Ref<Texture> icon = EditorNode::get_singleton()->get_object_icon(node, "Node"); h = MAX(h, icon->get_height()); diff --git a/editor/create_dialog.cpp b/editor/create_dialog.cpp index 8bef94d8a8..ff34618b04 100644 --- a/editor/create_dialog.cpp +++ b/editor/create_dialog.cpp @@ -60,7 +60,7 @@ void CreateDialog::popup_create(bool p_dont_clear, bool p_replace_mode) { TreeItem *ti = recent->create_item(root); ti->set_text(0, l); - ti->set_icon(0, _get_editor_icon(l)); + ti->set_icon(0, EditorNode::get_singleton()->get_class_icon(l, base_type)); } } @@ -151,41 +151,6 @@ void CreateDialog::_sbox_input(const Ref<InputEvent> &p_ie) { } } -Ref<Texture> CreateDialog::_get_editor_icon(const String &p_type) const { - - if (has_icon(p_type, "EditorIcons")) { - return get_icon(p_type, "EditorIcons"); - } - - if (ScriptServer::is_global_class(p_type)) { - String icon_path = EditorNode::get_editor_data().script_class_get_icon_path(p_type); - RES icon; - if (FileAccess::exists(icon_path)) { - icon = ResourceLoader::load(icon_path); - } - if (!icon.is_valid()) { - icon = get_icon(ScriptServer::get_global_class_base(p_type), "EditorIcons"); - } - return icon; - } - - const Map<String, Vector<EditorData::CustomType> > &p_map = EditorNode::get_editor_data().get_custom_types(); - for (const Map<String, Vector<EditorData::CustomType> >::Element *E = p_map.front(); E; E = E->next()) { - const Vector<EditorData::CustomType> &ct = E->value(); - for (int i = 0; i < ct.size(); ++i) { - if (ct[i].name == p_type) { - if (ct[i].icon.is_valid()) { - return ct[i].icon; - } else { - return get_icon("Object", "EditorIcons"); - } - } - } - } - - return get_icon("Object", "EditorIcons"); -} - void CreateDialog::add_type(const String &p_type, HashMap<String, TreeItem *> &p_types, TreeItem *p_root, TreeItem **to_select) { if (p_types.has(p_type)) @@ -246,7 +211,10 @@ void CreateDialog::add_type(const String &p_type, HashMap<String, TreeItem *> &p to_select_type = to_select_type.split(" ")[0]; bool current_item_is_preferred; if (cpp_type) { - current_item_is_preferred = ClassDB::is_parent_class(p_type, preferred_search_result_type) && !ClassDB::is_parent_class(to_select_type, preferred_search_result_type) && search_box->get_text() != to_select_type; + String cpp_to_select_type = to_select_type; + if (ScriptServer::is_global_class(to_select_type)) + cpp_to_select_type = ScriptServer::get_global_class_base(to_select_type); + current_item_is_preferred = ClassDB::is_parent_class(p_type, preferred_search_result_type) && !ClassDB::is_parent_class(cpp_to_select_type, preferred_search_result_type); } else { current_item_is_preferred = ed.script_class_is_parent(p_type, preferred_search_result_type) && !ed.script_class_is_parent(to_select_type, preferred_search_result_type) && search_box->get_text() != to_select_type; } @@ -274,7 +242,7 @@ void CreateDialog::add_type(const String &p_type, HashMap<String, TreeItem *> &p const String &description = EditorHelp::get_doc_data()->class_list[p_type].brief_description; item->set_tooltip(0, description); - item->set_icon(0, _get_editor_icon(p_type)); + item->set_icon(0, EditorNode::get_singleton()->get_class_icon(p_type, base_type)); p_types[p_type] = item; } @@ -578,7 +546,7 @@ void CreateDialog::_update_favorite_list() { continue; TreeItem *ti = favorites->create_item(root); ti->set_text(0, l); - ti->set_icon(0, _get_editor_icon(l)); + ti->set_icon(0, EditorNode::get_singleton()->get_class_icon(l, base_type)); } emit_signal("favorites_updated"); } diff --git a/editor/dependency_editor.cpp b/editor/dependency_editor.cpp index 9f04d40763..037543f45c 100644 --- a/editor/dependency_editor.cpp +++ b/editor/dependency_editor.cpp @@ -198,12 +198,7 @@ void DependencyEditor::_update_list() { } String name = path.get_file(); - Ref<Texture> icon; - if (has_icon(type, "EditorIcons")) { - icon = get_icon(type, "EditorIcons"); - } else { - icon = get_icon("Object", "EditorIcons"); - } + Ref<Texture> icon = EditorNode::get_singleton()->get_class_icon(type); item->set_text(0, name); item->set_icon(0, icon); item->set_metadata(0, type); @@ -346,13 +341,7 @@ void DependencyEditorOwners::_fill_owners(EditorFileSystemDirectory *efsd) { if (!found) continue; - Ref<Texture> icon; - String type = efsd->get_file_type(i); - if (!has_icon(type, "EditorIcons")) { - icon = get_icon("Object", "EditorIcons"); - } else { - icon = get_icon(type, "EditorIcons"); - } + Ref<Texture> icon = EditorNode::get_singleton()->get_class_icon(efsd->get_file_type(i)); owners->add_item(efsd->get_file_path(i), icon); } @@ -460,7 +449,7 @@ void DependencyRemoveDialog::_build_removed_dependency_tree(const Vector<Removed } //List this file under this dependency - Ref<Texture> icon = has_icon(rd.file_type, "EditorIcons") ? get_icon(rd.file_type, "EditorIcons") : get_icon("Object", "EditorIcons"); + Ref<Texture> icon = EditorNode::get_singleton()->get_class_icon(rd.file_type); TreeItem *file_item = owners->create_item(tree_items[rd.dependency]); file_item->set_text(0, rd.file); file_item->set_icon(0, icon); @@ -579,12 +568,7 @@ void DependencyErrorDialog::show(const String &p_for_file, const Vector<String> if (report[i].get_slice_count("::") > 0) type = report[i].get_slice("::", 1); - Ref<Texture> icon; - if (!has_icon(type, "EditorIcons")) { - icon = get_icon("Object", "EditorIcons"); - } else { - icon = get_icon(type, "EditorIcons"); - } + Ref<Texture> icon = EditorNode::get_singleton()->get_class_icon(type); TreeItem *ti = files->create_item(root); ti->set_text(0, dep); @@ -687,12 +671,7 @@ bool OrphanResourcesDialog::_fill_owners(EditorFileSystemDirectory *efsd, HashMa String type = efsd->get_file_type(i); - Ref<Texture> icon; - if (has_icon(type, "EditorIcons")) { - icon = get_icon(type, "EditorIcons"); - } else { - icon = get_icon("Object", "EditorIcons"); - } + Ref<Texture> icon = EditorNode::get_singleton()->get_class_icon(type); ti->set_icon(0, icon); int ds = efsd->get_file_deps(i).size(); ti->set_text(1, itos(ds)); diff --git a/editor/editor_audio_buses.cpp b/editor/editor_audio_buses.cpp index 96110b61ab..6cd81626c7 100644 --- a/editor/editor_audio_buses.cpp +++ b/editor/editor_audio_buses.cpp @@ -765,10 +765,7 @@ EditorAudioBus::EditorAudioBus(EditorAudioBuses *p_buses, bool p_is_master) { if (!ClassDB::can_instance(E->get())) continue; - Ref<Texture> icon; - if (has_icon(E->get(), "EditorIcons")) { - icon = get_icon(E->get(), "EditorIcons"); - } + Ref<Texture> icon = EditorNode::get_singleton()->get_class_icon(E->get()); String name = E->get().operator String().replace("AudioEffect", ""); effect_options->add_item(name); effect_options->set_item_metadata(effect_options->get_item_count() - 1, E->get()); diff --git a/editor/editor_data.cpp b/editor/editor_data.cpp index 6187c6b318..9420452da1 100644 --- a/editor/editor_data.cpp +++ b/editor/editor_data.cpp @@ -869,7 +869,7 @@ bool EditorData::script_class_is_parent(const String &p_class, const String &p_i return true; } -StringName EditorData::script_class_get_base(const String &p_class) { +StringName EditorData::script_class_get_base(const String &p_class) const { if (!ScriptServer::is_global_class(p_class)) return StringName(); @@ -895,24 +895,48 @@ Object *EditorData::script_class_instance(const String &p_class) { RES script = ResourceLoader::load(ScriptServer::get_global_class_path(p_class)); if (script.is_valid()) obj->set_script(script.get_ref_ptr()); - - RES icon = ResourceLoader::load(script_class_get_icon_path(p_class)); - if (icon.is_valid()) - obj->set_meta("_editor_icon", icon); - return obj; } } return NULL; } +void EditorData::script_class_set_icon_path(const String &p_class, const String &p_icon_path) { + _script_class_icon_paths[p_class] = p_icon_path; +} + +String EditorData::script_class_get_icon_path(const String &p_class) const { + if (!ScriptServer::is_global_class(p_class)) + return String(); + + String current = p_class; + String ret = _script_class_icon_paths[current]; + while (ret.empty()) { + current = script_class_get_base(current); + if (!ScriptServer::is_global_class(current)) + return String(); + ret = _script_class_icon_paths.has(current) ? _script_class_icon_paths[current] : String(); + } + + return ret; +} + +StringName EditorData::script_class_get_name(const String &p_path) const { + return _script_class_file_to_path.has(p_path) ? _script_class_file_to_path[p_path] : StringName(); +} + +void EditorData::script_class_set_name(const String &p_path, const StringName &p_class) { + _script_class_file_to_path[p_path] = p_class; +} + void EditorData::script_class_save_icon_paths() { List<StringName> keys; _script_class_icon_paths.get_key_list(&keys); Dictionary d; for (List<StringName>::Element *E = keys.front(); E; E = E->next()) { - d[E->get()] = _script_class_icon_paths[E->get()]; + if (ScriptServer::is_global_class(E->get())) + d[E->get()] = _script_class_icon_paths[E->get()]; } ProjectSettings::get_singleton()->set("_global_script_class_icons", d); @@ -927,8 +951,11 @@ void EditorData::script_class_load_icon_paths() { d.get_key_list(&keys); for (List<Variant>::Element *E = keys.front(); E; E = E->next()) { - String key = E->get().operator String(); - _script_class_icon_paths[key] = d[key]; + String name = E->get().operator String(); + _script_class_icon_paths[name] = d[name]; + + String path = ScriptServer::get_global_class_path(name); + script_class_set_name(path, name); } } diff --git a/editor/editor_data.h b/editor/editor_data.h index 9f5d3e2a15..87a76ee5ba 100644 --- a/editor/editor_data.h +++ b/editor/editor_data.h @@ -147,6 +147,7 @@ private: bool _find_updated_instances(Node *p_root, Node *p_node, Set<String> &checked_paths); HashMap<StringName, String> _script_class_icon_paths; + HashMap<String, StringName> _script_class_file_to_path; public: EditorPlugin *get_editor(Object *p_object); @@ -214,10 +215,14 @@ public: void notify_resource_saved(const Ref<Resource> &p_resource); bool script_class_is_parent(const String &p_class, const String &p_inherits); - StringName script_class_get_base(const String &p_class); + StringName script_class_get_base(const String &p_class) const; Object *script_class_instance(const String &p_class); - String script_class_get_icon_path(const String &p_class) const { return _script_class_icon_paths.has(p_class) ? _script_class_icon_paths[p_class] : String(); } - void script_class_set_icon_path(const String &p_class, const String &p_icon_path) { _script_class_icon_paths[p_class] = p_icon_path; } + + StringName script_class_get_name(const String &p_path) const; + void script_class_set_name(const String &p_path, const StringName &p_class); + + String script_class_get_icon_path(const String &p_class) const; + void script_class_set_icon_path(const String &p_class, const String &p_icon_path); void script_class_clear_icon_paths() { _script_class_icon_paths.clear(); } void script_class_save_icon_paths(); void script_class_load_icon_paths(); diff --git a/editor/editor_file_system.cpp b/editor/editor_file_system.cpp index 3d034989ed..56358cf5b7 100644 --- a/editor/editor_file_system.cpp +++ b/editor/editor_file_system.cpp @@ -1358,6 +1358,7 @@ void EditorFileSystem::_scan_script_classes(EditorFileSystemDirectory *p_dir) { } ScriptServer::add_global_class(files[i]->script_class_name, files[i]->script_class_extends, lang, p_dir->get_file_path(i)); EditorNode::get_editor_data().script_class_set_icon_path(files[i]->script_class_name, files[i]->script_class_icon_path); + EditorNode::get_editor_data().script_class_set_name(files[i]->file, files[i]->script_class_name); } for (int i = 0; i < p_dir->get_subdir_count(); i++) { _scan_script_classes(p_dir->get_subdir(i)); diff --git a/editor/editor_help.cpp b/editor/editor_help.cpp index 5b9e7b29a9..728c4affbd 100644 --- a/editor/editor_help.cpp +++ b/editor/editor_help.cpp @@ -88,10 +88,8 @@ void EditorHelpSearch::IncrementalSearch::phase1(Map<String, DocData::ClassDoc>: TreeItem *item = search_options->create_item(root); item->set_metadata(0, "class_name:" + E->key()); item->set_text(0, E->key() + " (Class)"); - if (search->has_icon(E->key(), "EditorIcons")) - item->set_icon(0, search->get_icon(E->key(), "EditorIcons")); - else - item->set_icon(0, def_icon); + Ref<Texture> icon = EditorNode::get_singleton()->get_class_icon(E->key(), "Node"); + item->set_icon(0, icon); } } @@ -99,11 +97,7 @@ void EditorHelpSearch::IncrementalSearch::phase2(Map<String, DocData::ClassDoc>: DocData::ClassDoc &c = E->get(); - Ref<Texture> cicon; - if (search->has_icon(E->key(), "EditorIcons")) - cicon = search->get_icon(E->key(), "EditorIcons"); - else - cicon = def_icon; + Ref<Texture> cicon = EditorNode::get_singleton()->get_class_icon(E->key(), "Node"); for (int i = 0; i < c.methods.size(); i++) { if ((term.begins_with(".") && c.methods[i].name.begins_with(term.right(1))) || (term.ends_with("(") && c.methods[i].name.ends_with(term.left(term.length() - 1).strip_edges())) || (term.begins_with(".") && term.ends_with("(") && c.methods[i].name == term.substr(1, term.length() - 2).strip_edges()) || c.methods[i].name.findn(term) != -1) { @@ -343,10 +337,8 @@ void EditorHelpIndex::add_type(const String &p_type, HashMap<String, TreeItem *> item->set_tooltip(0, EditorHelp::get_doc_data()->class_list[p_type].brief_description); item->set_text(0, p_type); - if (has_icon(p_type, "EditorIcons")) { - - item->set_icon(0, get_icon(p_type, "EditorIcons")); - } + Ref<Texture> icon = EditorNode::get_singleton()->get_class_icon(p_type); + item->set_icon(0, icon); p_types[p_type] = item; } diff --git a/editor/editor_inspector.cpp b/editor/editor_inspector.cpp index b64570f312..36c3102840 100644 --- a/editor/editor_inspector.cpp +++ b/editor/editor_inspector.cpp @@ -1423,10 +1423,7 @@ void EditorInspector::update_tree() { category_vbox = NULL; //reset String type = p.name; - if (has_icon(type, "EditorIcons")) - category->icon = get_icon(type, "EditorIcons"); - else - category->icon = get_icon("Object", "EditorIcons"); + category->icon = EditorNode::get_singleton()->get_class_icon(type, "Object"); category->label = type; category->bg_color = get_color("prop_category", "Editor"); diff --git a/editor/editor_node.cpp b/editor/editor_node.cpp index b652a25b6b..d8e6f711ff 100644 --- a/editor/editor_node.cpp +++ b/editor/editor_node.cpp @@ -141,12 +141,7 @@ void EditorNode::_update_scene_tabs() { String type = editor_data.get_scene_type(i); Ref<Texture> icon; if (type != String()) { - - if (!gui_base->has_icon(type, "EditorIcons")) { - type = "Node"; - } - - icon = gui_base->get_icon(type, "EditorIcons"); + icon = get_class_icon(type, "Node"); } int current = editor_data.get_edited_scene(); @@ -3126,6 +3121,86 @@ void EditorNode::stop_child_process() { _menu_option_confirm(RUN_STOP, false); } +Ref<Texture> EditorNode::get_object_icon(const Object *p_object, const String &p_fallback) const { + ERR_FAIL_COND_V(!p_object || !gui_base, NULL); + + Ref<Script> script = p_object->get_script(); + if (script.is_null() && p_object->is_class("Script")) { + script = p_object; + } + + StringName name; + String icon_path; + if (script.is_valid()) { + name = EditorNode::get_editor_data().script_class_get_name(script->get_path()); + icon_path = EditorNode::get_editor_data().script_class_get_icon_path(name); + name = script->get_instance_base_type(); + } + + if (gui_base->has_icon(p_object->get_class(), "EditorIcons")) + return gui_base->get_icon(p_object->get_class(), "EditorIcons"); + + if (icon_path.length()) + return ResourceLoader::load(icon_path); + + if (p_object->has_meta("_editor_icon")) + return p_object->get_meta("_editor_icon"); + + if (name != StringName()) { + const Map<String, Vector<EditorData::CustomType> > &p_map = EditorNode::get_editor_data().get_custom_types(); + for (const Map<String, Vector<EditorData::CustomType> >::Element *E = p_map.front(); E; E = E->next()) { + const Vector<EditorData::CustomType> &ct = E->value(); + for (int i = 0; i < ct.size(); ++i) { + if (ct[i].name == name && ct[i].icon.is_valid()) { + return ct[i].icon; + } + } + } + } + + if (p_fallback.length()) + return gui_base->get_icon(p_fallback, "EditorIcons"); + + return NULL; +} + +Ref<Texture> EditorNode::get_class_icon(const String &p_class, const String &p_fallback) const { + ERR_FAIL_COND_V(p_class.empty(), NULL); + + if (gui_base->has_icon(p_class, "EditorIcons")) { + return gui_base->get_icon(p_class, "EditorIcons"); + } + + if (ScriptServer::is_global_class(p_class)) { + String icon_path = EditorNode::get_editor_data().script_class_get_icon_path(p_class); + RES icon; + if (FileAccess::exists(icon_path)) { + icon = ResourceLoader::load(icon_path); + } + if (!icon.is_valid()) { + icon = gui_base->get_icon(ScriptServer::get_global_class_base(p_class), "EditorIcons"); + } + return icon; + } + + const Map<String, Vector<EditorData::CustomType> > &p_map = EditorNode::get_editor_data().get_custom_types(); + for (const Map<String, Vector<EditorData::CustomType> >::Element *E = p_map.front(); E; E = E->next()) { + const Vector<EditorData::CustomType> &ct = E->value(); + for (int i = 0; i < ct.size(); ++i) { + if (ct[i].name == p_class) { + if (ct[i].icon.is_valid()) { + return ct[i].icon; + } + } + } + } + + if (p_fallback.length()) + return gui_base->get_icon(p_fallback, "EditorIcons"); + + return NULL; +} + void EditorNode::progress_add_task(const String &p_task, const String &p_label, int p_steps, bool p_can_cancel) { singleton->progress_dialog->add_task(p_task, p_label, p_steps, p_can_cancel); diff --git a/editor/editor_node.h b/editor/editor_node.h index 5a17ab6ca0..7409c64a64 100644 --- a/editor/editor_node.h +++ b/editor/editor_node.h @@ -706,6 +706,8 @@ public: void stop_child_process(); Ref<Theme> get_editor_theme() const { return theme; } + Ref<Texture> get_object_icon(const Object *p_object, const String &p_fallback = "Object") const; + Ref<Texture> get_class_icon(const String &p_class, const String &p_fallback = "Object") const; void show_accept(const String &p_text, const String &p_title); void show_warning(const String &p_text, const String &p_title = "Warning!"); diff --git a/editor/editor_path.cpp b/editor/editor_path.cpp index 9506a0e951..0eff1fd7dd 100644 --- a/editor/editor_path.cpp +++ b/editor/editor_path.cpp @@ -54,12 +54,7 @@ void EditorPath::_add_children_to_popup(Object *p_obj, int p_depth) { if (!obj) continue; - Ref<Texture> icon; - - if (has_icon(obj->get_class(), "EditorIcons")) - icon = get_icon(obj->get_class(), "EditorIcons"); - else - icon = get_icon("Object", "EditorIcons"); + Ref<Texture> icon = EditorNode::get_singleton()->get_object_icon(obj); int index = popup->get_item_count(); popup->add_icon_item(icon, E->get().name.capitalize(), objects.size()); @@ -122,12 +117,7 @@ void EditorPath::_notification(int p_what) { String type = obj->get_class(); - Ref<Texture> icon; - - if (has_icon(obj->get_class(), "EditorIcons")) - icon = get_icon(obj->get_class(), "EditorIcons"); - else - icon = get_icon("Object", "EditorIcons"); + Ref<Texture> icon = EditorNode::get_singleton()->get_object_icon(obj); icon->draw(ci, Point2i(ofs, (size.height - icon->get_height()) / 2)); diff --git a/editor/editor_plugin_settings.cpp b/editor/editor_plugin_settings.cpp index ef0b61e882..30027c0c34 100644 --- a/editor/editor_plugin_settings.cpp +++ b/editor/editor_plugin_settings.cpp @@ -117,7 +117,7 @@ void EditorPluginSettings::update_plugins() { TreeItem *item = plugin_list->create_item(root); item->set_text(0, name); - item->set_tooltip(0, "Name: " + name + "\nPath: " + path + "\nMain Script: " + script); + item->set_tooltip(0, "Name: " + name + "\nPath: " + path + "\nMain Script: " + script + "\nDescription: " + description); item->set_metadata(0, d); item->set_text(1, version); item->set_metadata(1, script); diff --git a/editor/editor_properties.cpp b/editor/editor_properties.cpp index f932aa9927..3439133809 100644 --- a/editor/editor_properties.cpp +++ b/editor/editor_properties.cpp @@ -846,18 +846,11 @@ void EditorPropertyObjectID::update_property() { if (type == "") type = "Object"; - String icon_type = type; - if (has_icon(icon_type, "EditorIcons")) { - type = icon_type; - } else { - type = "Object"; - } - ObjectID id = get_edited_object()->get(get_edited_property()); if (id != 0) { edit->set_text(type + " ID: " + itos(id)); edit->set_disabled(false); - edit->set_icon(get_icon(icon_type, "EditorIcons")); + edit->set_icon(EditorNode::get_singleton()->get_class_icon(type)); } else { edit->set_text(TTR("[Empty]")); edit->set_disabled(true); @@ -1858,14 +1851,7 @@ void EditorPropertyNodePath::update_property() { ERR_FAIL_COND(!target_node); assign->set_text(target_node->get_name()); - - Ref<Texture> icon; - if (has_icon(target_node->get_class(), "EditorIcons")) - icon = get_icon(target_node->get_class(), "EditorIcons"); - else - icon = get_icon("Node", "EditorIcons"); - - assign->set_icon(icon); + assign->set_icon(EditorNode::get_singleton()->get_object_icon(target_node, "Node")); } void EditorPropertyNodePath::setup(const NodePath &p_base_hint, Vector<StringName> p_valid_types) { @@ -2363,13 +2349,7 @@ void EditorPropertyResource::update_property() { assign->set_text(TTR("[empty]")); } else { - Ref<Texture> icon; - if (has_icon(res->get_class(), "EditorIcons")) - icon = get_icon(res->get_class(), "EditorIcons"); - else - icon = get_icon("Node", "EditorIcons"); - - assign->set_icon(icon); + assign->set_icon(EditorNode::get_singleton()->get_object_icon(res.operator->(), "Node")); if (res->get_name() != String()) { assign->set_text(res->get_name()); diff --git a/editor/editor_sub_scene.cpp b/editor/editor_sub_scene.cpp index 056ee59860..7036a0ddaa 100644 --- a/editor/editor_sub_scene.cpp +++ b/editor/editor_sub_scene.cpp @@ -30,6 +30,7 @@ #include "editor_sub_scene.h" +#include "editor/editor_node.h" #include "scene/gui/margin_container.h" #include "scene/resources/packed_scene.h" @@ -84,9 +85,7 @@ void EditorSubScene::_fill_tree(Node *p_node, TreeItem *p_parent) { it->set_text(0, p_node->get_name()); it->set_editable(0, false); it->set_selectable(0, true); - if (has_icon(p_node->get_class(), "EditorIcons")) { - it->set_icon(0, get_icon(p_node->get_class(), "EditorIcons")); - } + it->set_icon(0, EditorNode::get_singleton()->get_object_icon(p_node, "Node")); for (int i = 0; i < p_node->get_child_count(); i++) { diff --git a/editor/groups_editor.cpp b/editor/groups_editor.cpp index 0efd14e932..cb9703342f 100644 --- a/editor/groups_editor.cpp +++ b/editor/groups_editor.cpp @@ -90,12 +90,7 @@ void GroupDialog::_load_nodes(Node *p_current) { node->set_metadata(0, path); node->set_tooltip(0, path); - Ref<Texture> icon; - if (p_current->has_meta("_editor_icon")) { - icon = p_current->get_meta("_editor_icon"); - } else { - icon = get_icon((has_icon(p_current->get_class(), "EditorIcons") ? p_current->get_class() : String("Object")), "EditorIcons"); - } + Ref<Texture> icon = EditorNode::get_singleton()->get_object_icon(p_current, "Node"); node->set_icon(0, icon); if (!_can_edit(p_current, selected_group)) { diff --git a/editor/inspector_dock.cpp b/editor/inspector_dock.cpp index 7aad973a96..5ab764fb15 100644 --- a/editor/inspector_dock.cpp +++ b/editor/inspector_dock.cpp @@ -231,11 +231,10 @@ void InspectorDock::_prepare_history() { already.insert(id); - Ref<Texture> icon = get_icon("Object", "EditorIcons"); - if (has_icon(obj->get_class(), "EditorIcons")) - icon = get_icon(obj->get_class(), "EditorIcons"); - else + Ref<Texture> icon = EditorNode::get_singleton()->get_object_icon(obj, ""); + if (icon.is_null()) { icon = base_icon; + } String text; if (Object::cast_to<Resource>(obj)) { diff --git a/editor/plugins/animation_blend_tree_editor_plugin.cpp b/editor/plugins/animation_blend_tree_editor_plugin.cpp index abf703cfd4..19d5243776 100644 --- a/editor/plugins/animation_blend_tree_editor_plugin.cpp +++ b/editor/plugins/animation_blend_tree_editor_plugin.cpp @@ -542,11 +542,7 @@ bool AnimationNodeBlendTreeEditor::_update_filters(const Ref<AnimationNode> &ano if (base->has_node(accum)) { Node *node = base->get_node(accum); - if (has_icon(node->get_class(), "EditorIcons")) { - ti->set_icon(0, get_icon(node->get_class(), "EditorIcons")); - } else { - ti->set_icon(0, get_icon("Node", "EditorIcons")); - } + ti->set_icon(0, EditorNode::get_singleton()->get_object_icon(node, "Node")); } } else { diff --git a/editor/plugins/canvas_item_editor_plugin.cpp b/editor/plugins/canvas_item_editor_plugin.cpp index eae3775e6b..34159964a5 100644 --- a/editor/plugins/canvas_item_editor_plugin.cpp +++ b/editor/plugins/canvas_item_editor_plugin.cpp @@ -1905,11 +1905,7 @@ bool CanvasItemEditor::_gui_input_select(const Ref<InputEvent> &p_event) { for (int i = 0; i < selection_results.size(); i++) { CanvasItem *item = selection_results[i].item; - Ref<Texture> icon; - if (item->has_meta("_editor_icon")) - icon = item->get_meta("_editor_icon"); - else - icon = get_icon(has_icon(item->get_class(), "EditorIcons") ? item->get_class() : String("Object"), "EditorIcons"); + Ref<Texture> icon = EditorNode::get_singleton()->get_object_icon(item, "Node"); String node_path = "/" + root_name + "/" + root_path.rel_path_to(item->get_path()); selection_menu->add_item(item->get_name()); @@ -2046,10 +2042,7 @@ bool CanvasItemEditor::_gui_input_hover(const Ref<InputEvent> &p_event) { _HoverResult hover_result; hover_result.position = canvas_item->get_global_transform_with_canvas().get_origin(); - if (has_icon(canvas_item->get_class(), "EditorIcons")) - hover_result.icon = get_icon(canvas_item->get_class(), "EditorIcons"); - else - hover_result.icon = get_icon("Object", "EditorIcons"); + hover_result.icon = EditorNode::get_singleton()->get_object_icon(canvas_item); hover_result.name = canvas_item->get_name(); hovering_results_tmp.push_back(hover_result); @@ -4397,7 +4390,7 @@ CanvasItemEditor::CanvasItemEditor(EditorNode *p_editor) { zoom_plus = memnew(ToolButton); zoom_hb->add_child(zoom_plus); zoom_plus->connect("pressed", this, "_button_zoom_plus"); - zoom_plus->set_shortcut(ED_SHORTCUT("canvas_item_editor/zoom_plus", TTR("Zoom in"), KEY_MASK_CMD | KEY_PLUS)); + zoom_plus->set_shortcut(ED_SHORTCUT("canvas_item_editor/zoom_plus", TTR("Zoom in"), KEY_MASK_CMD | KEY_EQUAL)); // Usually direct access key for PLUS zoom_plus->set_focus_mode(FOCUS_NONE); updating_scroll = false; diff --git a/editor/plugins/item_list_editor_plugin.cpp b/editor/plugins/item_list_editor_plugin.cpp index 7b5de9c009..186e66f980 100644 --- a/editor/plugins/item_list_editor_plugin.cpp +++ b/editor/plugins/item_list_editor_plugin.cpp @@ -317,10 +317,7 @@ void ItemListEditor::edit(Node *p_item_list) { item_plugins[i]->set_object(p_item_list); property_editor->edit(item_plugins[i]); - if (has_icon(item_list->get_class(), "EditorIcons")) - toolbar_button->set_icon(get_icon(item_list->get_class(), "EditorIcons")); - else - toolbar_button->set_icon(Ref<Texture>()); + toolbar_button->set_icon(EditorNode::get_singleton()->get_object_icon(item_list, "")); selected_idx = i; return; diff --git a/editor/plugins/resource_preloader_editor_plugin.cpp b/editor/plugins/resource_preloader_editor_plugin.cpp index da6aa48f9c..dd327d0a2c 100644 --- a/editor/plugins/resource_preloader_editor_plugin.cpp +++ b/editor/plugins/resource_preloader_editor_plugin.cpp @@ -238,8 +238,7 @@ void ResourcePreloaderEditor::_update_library() { ti->set_text(2, type); ti->set_selectable(2, false); - if (has_icon(type, "EditorIcons")) - ti->set_icon(2, get_icon(type, "EditorIcons")); + ti->set_icon(2, EditorNode::get_singleton()->get_class_icon(type, "")); } //player->add_resource("default",resource); diff --git a/editor/plugins/root_motion_editor_plugin.cpp b/editor/plugins/root_motion_editor_plugin.cpp index 1961f3786c..b3adf19a64 100644 --- a/editor/plugins/root_motion_editor_plugin.cpp +++ b/editor/plugins/root_motion_editor_plugin.cpp @@ -109,11 +109,7 @@ void EditorPropertyRootMotion::_node_assign() { if (base->has_node(accum)) { Node *node = base->get_node(accum); - if (has_icon(node->get_class(), "EditorIcons")) { - ti->set_icon(0, get_icon(node->get_class(), "EditorIcons")); - } else { - ti->set_icon(0, get_icon("Node", "EditorIcons")); - } + ti->set_icon(0, EditorNode::get_singleton()->get_object_icon(node, "Node")); } } else { @@ -235,14 +231,7 @@ void EditorPropertyRootMotion::update_property() { ERR_FAIL_COND(!target_node); assign->set_text(target_node->get_name()); - - Ref<Texture> icon; - if (has_icon(target_node->get_class(), "EditorIcons")) - icon = get_icon(target_node->get_class(), "EditorIcons"); - else - icon = get_icon("Node", "EditorIcons"); - - assign->set_icon(icon); + assign->set_icon(EditorNode::get_singleton()->get_object_icon(target_node, "Node")); } void EditorPropertyRootMotion::setup(const NodePath &p_base_hint) { diff --git a/editor/plugins/spatial_editor_plugin.cpp b/editor/plugins/spatial_editor_plugin.cpp index e86424ee51..c2554acd49 100644 --- a/editor/plugins/spatial_editor_plugin.cpp +++ b/editor/plugins/spatial_editor_plugin.cpp @@ -847,11 +847,7 @@ void SpatialEditorViewport::_list_select(Ref<InputEventMouseButton> b) { Spatial *spat = selection_results[i].item; - Ref<Texture> icon; - if (spat->has_meta("_editor_icon")) - icon = spat->get_meta("_editor_icon"); - else - icon = get_icon(has_icon(spat->get_class(), "EditorIcons") ? spat->get_class() : String("Object"), "EditorIcons"); + Ref<Texture> icon = EditorNode::get_singleton()->get_object_icon(spat, "Node"); String node_path = "/" + root_name + "/" + root_path.rel_path_to(spat->get_path()); diff --git a/editor/plugins/text_editor.cpp b/editor/plugins/text_editor.cpp index 5d379fb8b3..3bf4140591 100644 --- a/editor/plugins/text_editor.cpp +++ b/editor/plugins/text_editor.cpp @@ -30,6 +30,8 @@ #include "text_editor.h" +#include "editor_node.h" + void TextEditor::add_syntax_highlighter(SyntaxHighlighter *p_highlighter) { highlighters[p_highlighter->get_name()] = p_highlighter; highlighter_menu->add_radio_check_item(p_highlighter->get_name()); @@ -158,10 +160,7 @@ String TextEditor::get_name() { Ref<Texture> TextEditor::get_icon() { - if (get_parent_control() && get_parent_control()->has_icon(text_file->get_class(), "EditorIcons")) { - return get_parent_control()->get_icon(text_file->get_class(), "EditorIcons"); - } - return Ref<Texture>(); + return EditorNode::get_singleton()->get_object_icon(text_file.operator->(), ""); } RES TextEditor::get_edited_resource() const { diff --git a/editor/project_export.cpp b/editor/project_export.cpp index aba89a87ee..fa6dce1771 100644 --- a/editor/project_export.cpp +++ b/editor/project_export.cpp @@ -655,16 +655,9 @@ bool ProjectExportDialog::_fill_tree(EditorFileSystemDirectory *p_dir, TreeItem file->set_cell_mode(0, TreeItem::CELL_MODE_CHECK); file->set_text(0, p_dir->get_file(i)); - Ref<Texture> tex; - if (has_icon(type, editor_icons)) { - tex = get_icon(type, editor_icons); - } else { - tex = get_icon("Object", editor_icons); - } - String path = p_dir->get_file_path(i); - file->set_icon(0, tex); + file->set_icon(0, EditorNode::get_singleton()->get_class_icon(type)); file->set_editable(0, true); file->set_checked(0, current->has_export_file(path)); file->set_metadata(0, path); diff --git a/editor/project_settings_editor.cpp b/editor/project_settings_editor.cpp index 1baf606e7b..7a68646f40 100644 --- a/editor/project_settings_editor.cpp +++ b/editor/project_settings_editor.cpp @@ -1840,9 +1840,9 @@ ProjectSettingsEditor::ProjectSettingsEditor(EditorData *p_data) { input_editor->set_column_title(0, TTR("Action")); input_editor->set_column_title(1, TTR("Deadzone")); input_editor->set_column_expand(1, false); - input_editor->set_column_min_width(1, 80); + input_editor->set_column_min_width(1, 80 * EDSCALE); input_editor->set_column_expand(2, false); - input_editor->set_column_min_width(2, 50); + input_editor->set_column_min_width(2, 50 * EDSCALE); input_editor->connect("item_edited", this, "_action_edited"); input_editor->connect("item_activated", this, "_action_activated"); input_editor->connect("cell_selected", this, "_action_selected"); diff --git a/editor/property_editor.cpp b/editor/property_editor.cpp index 1c2eedfc9c..508db2e03f 100644 --- a/editor/property_editor.cpp +++ b/editor/property_editor.cpp @@ -34,6 +34,7 @@ #include "core/io/image_loader.h" #include "core/io/marshalls.h" #include "core/io/resource_loader.h" +#include "core/math/expression.h" #include "core/os/input.h" #include "core/os/keyboard.h" #include "core/pair.h" @@ -1531,21 +1532,24 @@ void CustomPropertyEditor::_modified(String p_string) { updating = true; switch (type) { case Variant::INT: { - - if (evaluator) - v = evaluator->eval(value_editor[0]->get_text()); - else + String text = value_editor[0]->get_text(); + Ref<Expression> expr; + expr.instance(); + Error err = expr->parse(text); + if (err != OK) { v = value_editor[0]->get_text().to_int(); + return; + } else { + v = expr->execute(Array(), NULL, false); + } emit_signal("variant_changed"); } break; case Variant::REAL: { if (hint != PROPERTY_HINT_EXP_EASING) { - if (evaluator) - v = evaluator->eval(value_editor[0]->get_text()); - else - v = value_editor[0]->get_text().to_double(); + String text = value_editor[0]->get_text(); + v = _parse_real_expression(text); emit_signal("variant_changed"); } @@ -1558,13 +1562,8 @@ void CustomPropertyEditor::_modified(String p_string) { case Variant::VECTOR2: { Vector2 vec; - if (evaluator) { - vec.x = evaluator->eval(value_editor[0]->get_text()); - vec.y = evaluator->eval(value_editor[1]->get_text()); - } else { - vec.x = value_editor[0]->get_text().to_double(); - vec.y = value_editor[1]->get_text().to_double(); - } + vec.x = _parse_real_expression(value_editor[0]->get_text()); + vec.y = _parse_real_expression(value_editor[1]->get_text()); v = vec; _emit_changed_whole_or_field(); @@ -1572,17 +1571,11 @@ void CustomPropertyEditor::_modified(String p_string) { case Variant::RECT2: { Rect2 r2; - if (evaluator) { - r2.position.x = evaluator->eval(value_editor[0]->get_text()); - r2.position.y = evaluator->eval(value_editor[1]->get_text()); - r2.size.x = evaluator->eval(value_editor[2]->get_text()); - r2.size.y = evaluator->eval(value_editor[3]->get_text()); - } else { - r2.position.x = value_editor[0]->get_text().to_double(); - r2.position.y = value_editor[1]->get_text().to_double(); - r2.size.x = value_editor[2]->get_text().to_double(); - r2.size.y = value_editor[3]->get_text().to_double(); - } + + r2.position.x = _parse_real_expression(value_editor[0]->get_text()); + r2.position.y = _parse_real_expression(value_editor[1]->get_text()); + r2.size.x = _parse_real_expression(value_editor[2]->get_text()); + r2.size.y = _parse_real_expression(value_editor[3]->get_text()); v = r2; _emit_changed_whole_or_field(); @@ -1591,15 +1584,9 @@ void CustomPropertyEditor::_modified(String p_string) { case Variant::VECTOR3: { Vector3 vec; - if (evaluator) { - vec.x = evaluator->eval(value_editor[0]->get_text()); - vec.y = evaluator->eval(value_editor[1]->get_text()); - vec.z = evaluator->eval(value_editor[2]->get_text()); - } else { - vec.x = value_editor[0]->get_text().to_double(); - vec.y = value_editor[1]->get_text().to_double(); - vec.z = value_editor[2]->get_text().to_double(); - } + vec.x = _parse_real_expression(value_editor[0]->get_text()); + vec.y = _parse_real_expression(value_editor[1]->get_text()); + vec.z = _parse_real_expression(value_editor[2]->get_text()); v = vec; _emit_changed_whole_or_field(); @@ -1607,17 +1594,10 @@ void CustomPropertyEditor::_modified(String p_string) { case Variant::PLANE: { Plane pl; - if (evaluator) { - pl.normal.x = evaluator->eval(value_editor[0]->get_text()); - pl.normal.y = evaluator->eval(value_editor[1]->get_text()); - pl.normal.z = evaluator->eval(value_editor[2]->get_text()); - pl.d = evaluator->eval(value_editor[3]->get_text()); - } else { - pl.normal.x = value_editor[0]->get_text().to_double(); - pl.normal.y = value_editor[1]->get_text().to_double(); - pl.normal.z = value_editor[2]->get_text().to_double(); - pl.d = value_editor[3]->get_text().to_double(); - } + pl.normal.x = _parse_real_expression(value_editor[0]->get_text()); + pl.normal.y = _parse_real_expression(value_editor[1]->get_text()); + pl.normal.z = _parse_real_expression(value_editor[2]->get_text()); + pl.d = _parse_real_expression(value_editor[3]->get_text()); v = pl; _emit_changed_whole_or_field(); @@ -1625,17 +1605,10 @@ void CustomPropertyEditor::_modified(String p_string) { case Variant::QUAT: { Quat q; - if (evaluator) { - q.x = evaluator->eval(value_editor[0]->get_text()); - q.y = evaluator->eval(value_editor[1]->get_text()); - q.z = evaluator->eval(value_editor[2]->get_text()); - q.w = evaluator->eval(value_editor[3]->get_text()); - } else { - q.x = value_editor[0]->get_text().to_double(); - q.y = value_editor[1]->get_text().to_double(); - q.z = value_editor[2]->get_text().to_double(); - q.w = value_editor[3]->get_text().to_double(); - } + q.x = _parse_real_expression(value_editor[0]->get_text()); + q.y = _parse_real_expression(value_editor[1]->get_text()); + q.z = _parse_real_expression(value_editor[2]->get_text()); + q.w = _parse_real_expression(value_editor[3]->get_text()); v = q; _emit_changed_whole_or_field(); @@ -1645,21 +1618,12 @@ void CustomPropertyEditor::_modified(String p_string) { Vector3 pos; Vector3 size; - if (evaluator) { - pos.x = evaluator->eval(value_editor[0]->get_text()); - pos.y = evaluator->eval(value_editor[1]->get_text()); - pos.z = evaluator->eval(value_editor[2]->get_text()); - size.x = evaluator->eval(value_editor[3]->get_text()); - size.y = evaluator->eval(value_editor[4]->get_text()); - size.z = evaluator->eval(value_editor[5]->get_text()); - } else { - pos.x = value_editor[0]->get_text().to_double(); - pos.y = value_editor[1]->get_text().to_double(); - pos.z = value_editor[2]->get_text().to_double(); - size.x = value_editor[3]->get_text().to_double(); - size.y = value_editor[4]->get_text().to_double(); - size.z = value_editor[5]->get_text().to_double(); - } + pos.x = _parse_real_expression(value_editor[0]->get_text()); + pos.y = _parse_real_expression(value_editor[1]->get_text()); + pos.z = _parse_real_expression(value_editor[2]->get_text()); + size.x = _parse_real_expression(value_editor[3]->get_text()); + size.y = _parse_real_expression(value_editor[4]->get_text()); + size.z = _parse_real_expression(value_editor[5]->get_text()); v = AABB(pos, size); _emit_changed_whole_or_field(); @@ -1668,11 +1632,7 @@ void CustomPropertyEditor::_modified(String p_string) { Transform2D m; for (int i = 0; i < 6; i++) { - if (evaluator) { - m.elements[i / 2][i % 2] = evaluator->eval(value_editor[i]->get_text()); - } else { - m.elements[i / 2][i % 2] = value_editor[i]->get_text().to_double(); - } + m.elements[i / 2][i % 2] = _parse_real_expression(value_editor[i]->get_text()); } v = m; @@ -1683,12 +1643,7 @@ void CustomPropertyEditor::_modified(String p_string) { Basis m; for (int i = 0; i < 9; i++) { - - if (evaluator) { - m.elements[i / 3][i % 3] = evaluator->eval(value_editor[i]->get_text()); - } else { - m.elements[i / 3][i % 3] = value_editor[i]->get_text().to_double(); - } + m.elements[i / 3][i % 3] = _parse_real_expression(value_editor[i]->get_text()); } v = m; @@ -1699,25 +1654,14 @@ void CustomPropertyEditor::_modified(String p_string) { Basis basis; for (int i = 0; i < 9; i++) { - - if (evaluator) { - basis.elements[i / 3][i % 3] = evaluator->eval(value_editor[(i / 3) * 4 + i % 3]->get_text()); - } else { - basis.elements[i / 3][i % 3] = value_editor[(i / 3) * 4 + i % 3]->get_text().to_double(); - } + basis.elements[i / 3][i % 3] = _parse_real_expression(value_editor[(i / 3) * 4 + i % 3]->get_text()); } Vector3 origin; - if (evaluator) { - origin.x = evaluator->eval(value_editor[3]->get_text()); - origin.y = evaluator->eval(value_editor[7]->get_text()); - origin.z = evaluator->eval(value_editor[11]->get_text()); - } else { - origin.x = value_editor[3]->get_text().to_double(); - origin.y = value_editor[7]->get_text().to_double(); - origin.z = value_editor[11]->get_text().to_double(); - } + origin.x = _parse_real_expression(value_editor[3]->get_text()); + origin.y = _parse_real_expression(value_editor[7]->get_text()); + origin.z = _parse_real_expression(value_editor[11]->get_text()); v = Transform(basis, origin); _emit_changed_whole_or_field(); @@ -1759,6 +1703,19 @@ void CustomPropertyEditor::_modified(String p_string) { updating = false; } +real_t CustomPropertyEditor::_parse_real_expression(String text) { + Ref<Expression> expr; + expr.instance(); + Error err = expr->parse(text); + real_t out; + if (err != OK) { + out = value_editor[0]->get_text().to_double(); + } else { + out = expr->execute(Array(), NULL, false); + } + return out; +} + void CustomPropertyEditor::_emit_changed_whole_or_field() { if (!Input::get_singleton()->is_key_pressed(KEY_SHIFT)) { diff --git a/editor/property_editor.h b/editor/property_editor.h index 7d7ab912ea..ee3a56d857 100644 --- a/editor/property_editor.h +++ b/editor/property_editor.h @@ -135,6 +135,9 @@ class CustomPropertyEditor : public Popup { void _text_edit_changed(); void _file_selected(String p_file); void _modified(String p_string); + + real_t _parse_real_expression(String text); + void _range_modified(double p_value); void _focus_enter(); void _focus_exit(); diff --git a/editor/property_selector.cpp b/editor/property_selector.cpp index c9eba33f35..9042bdc7c1 100644 --- a/editor/property_selector.cpp +++ b/editor/property_selector.cpp @@ -31,6 +31,7 @@ #include "property_selector.h" #include "core/os/keyboard.h" +#include "editor/editor_node.h" #include "editor_scale.h" void PropertySelector::_text_changed(const String &p_newtext) { @@ -161,10 +162,8 @@ void PropertySelector::_update_search() { Ref<Texture> icon; if (E->get().name == "Script Variables") { icon = get_icon("Script", "EditorIcons"); - } else if (has_icon(E->get().name, "EditorIcons")) { - icon = get_icon(E->get().name, "EditorIcons"); } else { - icon = get_icon("Object", "EditorIcons"); + icon = EditorNode::get_singleton()->get_class_icon(E->get().name); } category->set_icon(0, icon); continue; @@ -241,10 +240,8 @@ void PropertySelector::_update_search() { if (E->get().name == "*Script Methods") { icon = get_icon("Script", "EditorIcons"); script_methods = true; - } else if (has_icon(rep, "EditorIcons")) { - icon = get_icon(rep, "EditorIcons"); } else { - icon = get_icon("Object", "EditorIcons"); + icon = EditorNode::get_singleton()->get_class_icon(rep); } category->set_icon(0, icon); diff --git a/editor/scene_tree_dock.cpp b/editor/scene_tree_dock.cpp index 9461f39aeb..af6b998b28 100644 --- a/editor/scene_tree_dock.cpp +++ b/editor/scene_tree_dock.cpp @@ -399,11 +399,6 @@ void SceneTreeDock::_tool_selected(int p_tool, bool p_confirm_override) { const RefPtr empty; editor_data->get_undo_redo().add_do_method(E->get(), "set_script", empty); editor_data->get_undo_redo().add_undo_method(E->get(), "set_script", existing); - - if (E->get()->has_meta("_editor_icon")) { - editor_data->get_undo_redo().add_do_method(E->get(), "set_meta", "_editor_icon", get_icon(E->get()->get_class(), "EditorIcons")); - editor_data->get_undo_redo().add_undo_method(E->get(), "set_meta", "_editor_icon", E->get()->get_meta("_editor_icon")); - } } } @@ -1501,19 +1496,6 @@ void SceneTreeDock::_script_created(Ref<Script> p_script) { Ref<Script> existing = E->get()->get_script(); editor_data->get_undo_redo().add_do_method(E->get(), "set_script", p_script.get_ref_ptr()); editor_data->get_undo_redo().add_undo_method(E->get(), "set_script", existing); - - String icon_path; - String name = p_script->get_language()->get_global_class_name(p_script->get_path(), NULL, &icon_path); - if (ScriptServer::is_global_class(name)) { - RES icon = ResourceLoader::load(icon_path); - editor_data->get_undo_redo().add_do_method(E->get(), "set_meta", "_editor_icon", icon); - String existing_name = existing.is_valid() ? existing->get_language()->get_global_class_name(existing->get_path()) : String(); - if (existing.is_null() || !ScriptServer::is_global_class(existing_name)) { - editor_data->get_undo_redo().add_undo_method(E->get(), "set_meta", "_editor_icon", get_icon(E->get()->get_class(), "EditorIcons")); - } else { - editor_data->get_undo_redo().add_undo_method(E->get(), "set_meta", "_editor_icon", editor_data->script_class_get_icon_path(existing_name)); - } - } } editor_data->get_undo_redo().commit_action(); @@ -2029,12 +2011,7 @@ void SceneTreeDock::_add_children_to_popup(Object *p_obj, int p_depth) { if (!obj) continue; - Ref<Texture> icon; - - if (has_icon(obj->get_class(), "EditorIcons")) - icon = get_icon(obj->get_class(), "EditorIcons"); - else - icon = get_icon("Object", "EditorIcons"); + Ref<Texture> icon = EditorNode::get_singleton()->get_object_icon(obj); if (menu->get_item_count() == 0) { menu->add_submenu_item(TTR("Sub-Resources"), "Sub-Resources"); @@ -2264,7 +2241,7 @@ void SceneTreeDock::_update_create_root_dialog() { String name = l.get_slicec(' ', 0); if (ScriptServer::is_global_class(name)) name = ScriptServer::get_global_class_base(name); - button->set_icon(get_icon(name, "EditorIcons")); + button->set_icon(EditorNode::get_singleton()->get_class_icon(name)); button->connect("pressed", this, "_favorite_root_selected", make_binds(l)); } } diff --git a/editor/scene_tree_editor.cpp b/editor/scene_tree_editor.cpp index a45773003a..07670bb420 100644 --- a/editor/scene_tree_editor.cpp +++ b/editor/scene_tree_editor.cpp @@ -186,11 +186,7 @@ bool SceneTreeEditor::_add_nodes(Node *p_node, TreeItem *p_parent) { item->set_collapsed(true); } - Ref<Texture> icon; - if (p_node->has_meta("_editor_icon")) - icon = p_node->get_meta("_editor_icon"); - else - icon = get_icon((has_icon(p_node->get_class(), "EditorIcons") ? p_node->get_class() : String("Object")), "EditorIcons"); + Ref<Texture> icon = EditorNode::get_singleton()->get_object_icon(p_node, "Node"); item->set_icon(0, icon); item->set_metadata(0, p_node->get_path()); diff --git a/editor/script_editor_debugger.cpp b/editor/script_editor_debugger.cpp index b451092709..a28a111025 100644 --- a/editor/script_editor_debugger.cpp +++ b/editor/script_editor_debugger.cpp @@ -428,8 +428,9 @@ void ScriptEditorDebugger::_parse_message(const String &p_msg, const Array &p_da ObjectID id = ObjectID(p_data[i + 3]); it->set_text(0, p_data[i + 1]); - if (has_icon(p_data[i + 2], "EditorIcons")) - it->set_icon(0, get_icon(p_data[i + 2], "EditorIcons")); + Ref<Texture> icon = EditorNode::get_singleton()->get_class_icon(p_data[i + 2], ""); + if (icon.is_valid()) + it->set_icon(0, icon); it->set_metadata(0, id); if (id == inspected_object_id) { diff --git a/main/main.cpp b/main/main.cpp index 34aca032da..90d4db2948 100644 --- a/main/main.cpp +++ b/main/main.cpp @@ -1096,30 +1096,24 @@ Error Main::setup2(Thread::ID p_main_tid_override) { ERR_PRINTS("Non-existing or invalid boot splash at: " + boot_logo_path + ". Loading default splash."); } + Color boot_bg_color = GLOBAL_DEF("application/boot_splash/bg_color", boot_splash_bg_color); if (boot_logo.is_valid()) { OS::get_singleton()->_msec_splash = OS::get_singleton()->get_ticks_msec(); - Color boot_bg = GLOBAL_DEF("application/boot_splash/bg_color", clear); - VisualServer::get_singleton()->set_boot_image(boot_logo, boot_bg, boot_logo_scale); -#ifndef TOOLS_ENABLED -//no tools, so free the boot logo (no longer needed) -//ProjectSettings::get_singleton()->set("application/boot_logo",Image()); -#endif + VisualServer::get_singleton()->set_boot_image(boot_logo, boot_bg_color, boot_logo_scale); } else { #ifndef NO_DEFAULT_BOOT_LOGO - MAIN_PRINT("Main: Create bootsplash"); #if defined(TOOLS_ENABLED) && !defined(NO_EDITOR_SPLASH) - Ref<Image> splash = (editor || project_manager) ? memnew(Image(boot_splash_editor_png)) : memnew(Image(boot_splash_png)); #else Ref<Image> splash = memnew(Image(boot_splash_png)); #endif MAIN_PRINT("Main: ClearColor"); - VisualServer::get_singleton()->set_default_clear_color(boot_splash_bg_color); + VisualServer::get_singleton()->set_default_clear_color(boot_bg_color); MAIN_PRINT("Main: Image"); - VisualServer::get_singleton()->set_boot_image(splash, boot_splash_bg_color, false); + VisualServer::get_singleton()->set_boot_image(splash, boot_bg_color, false); #endif } diff --git a/methods.py b/methods.py index 1bc10954ba..00c477635e 100644 --- a/methods.py +++ b/methods.py @@ -578,6 +578,9 @@ def generate_vs_project(env, num_jobs): release_targets = ['bin\\godot.windows.opt.32.exe'] + ['bin\\godot.windows.opt.64.exe'] release_debug_targets = ['bin\\godot.windows.opt.tools.32.exe'] + ['bin\\godot.windows.opt.tools.64.exe'] targets = debug_targets + release_targets + release_debug_targets + if not env.get('MSVS'): + env['MSVS']['PROJECTSUFFIX'] = '.vcxproj' + env['MSVS']['SOLUTIONSUFFIX'] = '.sln' env.MSVSProject( target=['#godot' + env['MSVSPROJECTSUFFIX']], incs=env.vs_incs, diff --git a/modules/gdnative/include/nativescript/godot_nativescript.h b/modules/gdnative/include/nativescript/godot_nativescript.h index d6a729be47..ba044117e2 100644 --- a/modules/gdnative/include/nativescript/godot_nativescript.h +++ b/modules/gdnative/include/nativescript/godot_nativescript.h @@ -40,12 +40,13 @@ extern "C" { typedef enum { GODOT_METHOD_RPC_MODE_DISABLED, GODOT_METHOD_RPC_MODE_REMOTE, - GODOT_METHOD_RPC_MODE_SYNC, GODOT_METHOD_RPC_MODE_MASTER, - GODOT_METHOD_RPC_MODE_SLAVE, + GODOT_METHOD_RPC_MODE_PUPPET, + GODOT_METHOD_RPC_MODE_SLAVE = GODOT_METHOD_RPC_MODE_PUPPET, GODOT_METHOD_RPC_MODE_REMOTESYNC, + GODOT_METHOD_RPC_MODE_SYNC = GODOT_METHOD_RPC_MODE_REMOTESYNC, GODOT_METHOD_RPC_MODE_MASTERSYNC, - GODOT_METHOD_RPC_MODE_SLAVESYNC, + GODOT_METHOD_RPC_MODE_PUPPETSYNC, } godot_method_rpc_mode; typedef enum { diff --git a/modules/gdnative/nativescript/nativescript.cpp b/modules/gdnative/nativescript/nativescript.cpp index ea968fb0b1..641e4021d8 100644 --- a/modules/gdnative/nativescript/nativescript.cpp +++ b/modules/gdnative/nativescript/nativescript.cpp @@ -810,18 +810,16 @@ MultiplayerAPI::RPCMode NativeScriptInstance::get_rpc_mode(const StringName &p_m return MultiplayerAPI::RPC_MODE_DISABLED; case GODOT_METHOD_RPC_MODE_REMOTE: return MultiplayerAPI::RPC_MODE_REMOTE; - case GODOT_METHOD_RPC_MODE_SYNC: - return MultiplayerAPI::RPC_MODE_SYNC; case GODOT_METHOD_RPC_MODE_MASTER: return MultiplayerAPI::RPC_MODE_MASTER; - case GODOT_METHOD_RPC_MODE_SLAVE: - return MultiplayerAPI::RPC_MODE_SLAVE; + case GODOT_METHOD_RPC_MODE_PUPPET: + return MultiplayerAPI::RPC_MODE_PUPPET; case GODOT_METHOD_RPC_MODE_REMOTESYNC: return MultiplayerAPI::RPC_MODE_REMOTESYNC; case GODOT_METHOD_RPC_MODE_MASTERSYNC: return MultiplayerAPI::RPC_MODE_MASTERSYNC; - case GODOT_METHOD_RPC_MODE_SLAVESYNC: - return MultiplayerAPI::RPC_MODE_SLAVESYNC; + case GODOT_METHOD_RPC_MODE_PUPPETSYNC: + return MultiplayerAPI::RPC_MODE_PUPPETSYNC; default: return MultiplayerAPI::RPC_MODE_DISABLED; } @@ -846,12 +844,16 @@ MultiplayerAPI::RPCMode NativeScriptInstance::get_rset_mode(const StringName &p_ return MultiplayerAPI::RPC_MODE_DISABLED; case GODOT_METHOD_RPC_MODE_REMOTE: return MultiplayerAPI::RPC_MODE_REMOTE; - case GODOT_METHOD_RPC_MODE_SYNC: - return MultiplayerAPI::RPC_MODE_SYNC; case GODOT_METHOD_RPC_MODE_MASTER: return MultiplayerAPI::RPC_MODE_MASTER; - case GODOT_METHOD_RPC_MODE_SLAVE: - return MultiplayerAPI::RPC_MODE_SLAVE; + case GODOT_METHOD_RPC_MODE_PUPPET: + return MultiplayerAPI::RPC_MODE_PUPPET; + case GODOT_METHOD_RPC_MODE_REMOTESYNC: + return MultiplayerAPI::RPC_MODE_REMOTESYNC; + case GODOT_METHOD_RPC_MODE_MASTERSYNC: + return MultiplayerAPI::RPC_MODE_MASTERSYNC; + case GODOT_METHOD_RPC_MODE_PUPPETSYNC: + return MultiplayerAPI::RPC_MODE_PUPPETSYNC; default: return MultiplayerAPI::RPC_MODE_DISABLED; } diff --git a/modules/gdscript/gdscript.cpp b/modules/gdscript/gdscript.cpp index 4d5d8cedde..d12c1f555c 100644 --- a/modules/gdscript/gdscript.cpp +++ b/modules/gdscript/gdscript.cpp @@ -1779,10 +1779,11 @@ void GDScriptLanguage::get_reserved_words(List<String> *p_words) const { "remote", "sync", "master", + "puppet", "slave", "remotesync", "mastersync", - "slavesync", + "puppetsync", 0 }; @@ -1979,6 +1980,10 @@ String GDScriptWarning::get_message() const { CHECK_SYMBOLS(4); return "The argument '" + symbols[0] + "' of the function '" + symbols[1] + "' requires a the subtype '" + symbols[2] + "' but the supertype '" + symbols[3] + "' was provided"; } break; + case DEPRECATED_KEYWORD: { + CHECK_SYMBOLS(2); + return "The '" + symbols[0] + "' keyword is deprecated and will be removed in a future release, please replace its uses by '" + symbols[1] + "'."; + } break; } ERR_EXPLAIN("Invalid GDScript warning code: " + get_name_from_code(code)); ERR_FAIL_V(String()); @@ -2018,6 +2023,7 @@ String GDScriptWarning::get_name_from_code(Code p_code) { "UNSAFE_METHOD_ACCESS", "UNSAFE_CAST", "UNSAFE_CALL_ARGUMENT", + "DEPRECATED_KEYWORD", NULL }; diff --git a/modules/gdscript/gdscript.h b/modules/gdscript/gdscript.h index 739d18569f..d795500265 100644 --- a/modules/gdscript/gdscript.h +++ b/modules/gdscript/gdscript.h @@ -289,6 +289,7 @@ struct GDScriptWarning { UNSAFE_METHOD_ACCESS, // Function not found in the detected type (but can be in subtypes) UNSAFE_CAST, // Cast used in an unknown type UNSAFE_CALL_ARGUMENT, // Function call argument is of a supertype of the require argument + DEPRECATED_KEYWORD, // The keyword is deprecated and should be replaced WARNING_MAX, } code; Vector<String> symbols; diff --git a/modules/gdscript/gdscript_editor.cpp b/modules/gdscript/gdscript_editor.cpp index affb73a048..32a7668760 100644 --- a/modules/gdscript/gdscript_editor.cpp +++ b/modules/gdscript/gdscript_editor.cpp @@ -2109,8 +2109,8 @@ static void _find_identifiers(const GDScriptCompletionContext &p_context, bool p "and", "in", "not", "or", "false", "PI", "TAU", "INF", "NAN", "self", "true", "as", "assert", "breakpoint", "class", "extends", "is", "func", "preload", "setget", "signal", "tool", "yield", "const", "enum", "export", "onready", "static", "var", "break", "continue", "if", "elif", - "else", "for", "pass", "return", "match", "while", "remote", "sync", "master", "slave", - "remotesync", "mastersync", "slavesync", + "else", "for", "pass", "return", "match", "while", "remote", "sync", "master", "puppet", "slave", + "remotesync", "mastersync", "puppetsync", 0 }; diff --git a/modules/gdscript/gdscript_parser.cpp b/modules/gdscript/gdscript_parser.cpp index 7243690f94..89e102a858 100644 --- a/modules/gdscript/gdscript_parser.cpp +++ b/modules/gdscript/gdscript_parser.cpp @@ -4382,10 +4382,10 @@ void GDScriptParser::_parse_class(ClassNode *p_class) { tokenizer->advance(); } - if (tokenizer->get_token() != GDScriptTokenizer::TK_PR_VAR && tokenizer->get_token() != GDScriptTokenizer::TK_PR_ONREADY && tokenizer->get_token() != GDScriptTokenizer::TK_PR_REMOTE && tokenizer->get_token() != GDScriptTokenizer::TK_PR_MASTER && tokenizer->get_token() != GDScriptTokenizer::TK_PR_SLAVE && tokenizer->get_token() != GDScriptTokenizer::TK_PR_SYNC && tokenizer->get_token() != GDScriptTokenizer::TK_PR_REMOTESYNC && tokenizer->get_token() != GDScriptTokenizer::TK_PR_MASTERSYNC && tokenizer->get_token() != GDScriptTokenizer::TK_PR_SLAVESYNC) { + if (tokenizer->get_token() != GDScriptTokenizer::TK_PR_VAR && tokenizer->get_token() != GDScriptTokenizer::TK_PR_ONREADY && tokenizer->get_token() != GDScriptTokenizer::TK_PR_REMOTE && tokenizer->get_token() != GDScriptTokenizer::TK_PR_MASTER && tokenizer->get_token() != GDScriptTokenizer::TK_PR_PUPPET && tokenizer->get_token() != GDScriptTokenizer::TK_PR_SYNC && tokenizer->get_token() != GDScriptTokenizer::TK_PR_REMOTESYNC && tokenizer->get_token() != GDScriptTokenizer::TK_PR_MASTERSYNC && tokenizer->get_token() != GDScriptTokenizer::TK_PR_PUPPETSYNC && tokenizer->get_token() != GDScriptTokenizer::TK_PR_SLAVE) { current_export = PropertyInfo(); - _set_error("Expected 'var', 'onready', 'remote', 'master', 'slave', 'sync', 'remotesync', 'mastersync', 'slavesync'."); + _set_error("Expected 'var', 'onready', 'remote', 'master', 'puppet', 'sync', 'remotesync', 'mastersync', 'puppetsync'."); return; } @@ -4442,7 +4442,9 @@ void GDScriptParser::_parse_class(ClassNode *p_class) { rpc_mode = MultiplayerAPI::RPC_MODE_MASTER; continue; } break; - case GDScriptTokenizer::TK_PR_SLAVE: { + case GDScriptTokenizer::TK_PR_SLAVE: + _add_warning(GDScriptWarning::DEPRECATED_KEYWORD, tokenizer->get_token_line(), "slave", "puppet"); + case GDScriptTokenizer::TK_PR_PUPPET: { //may be fallthrough from export, ignore if so tokenizer->advance(); @@ -4459,7 +4461,7 @@ void GDScriptParser::_parse_class(ClassNode *p_class) { } } - rpc_mode = MultiplayerAPI::RPC_MODE_SLAVE; + rpc_mode = MultiplayerAPI::RPC_MODE_PUPPET; continue; } break; case GDScriptTokenizer::TK_PR_REMOTESYNC: @@ -4475,7 +4477,7 @@ void GDScriptParser::_parse_class(ClassNode *p_class) { return; } - rpc_mode = MultiplayerAPI::RPC_MODE_SYNC; + rpc_mode = MultiplayerAPI::RPC_MODE_REMOTESYNC; continue; } break; case GDScriptTokenizer::TK_PR_MASTERSYNC: { @@ -4493,7 +4495,7 @@ void GDScriptParser::_parse_class(ClassNode *p_class) { rpc_mode = MultiplayerAPI::RPC_MODE_MASTERSYNC; continue; } break; - case GDScriptTokenizer::TK_PR_SLAVESYNC: { + case GDScriptTokenizer::TK_PR_PUPPETSYNC: { //may be fallthrough from export, ignore if so tokenizer->advance(); @@ -4505,7 +4507,7 @@ void GDScriptParser::_parse_class(ClassNode *p_class) { return; } - rpc_mode = MultiplayerAPI::RPC_MODE_SLAVESYNC; + rpc_mode = MultiplayerAPI::RPC_MODE_PUPPETSYNC; continue; } break; case GDScriptTokenizer::TK_PR_VAR: { diff --git a/modules/gdscript/gdscript_tokenizer.cpp b/modules/gdscript/gdscript_tokenizer.cpp index 941f5dbecc..77e1b7290e 100644 --- a/modules/gdscript/gdscript_tokenizer.cpp +++ b/modules/gdscript/gdscript_tokenizer.cpp @@ -112,10 +112,11 @@ const char *GDScriptTokenizer::token_names[TK_MAX] = { "rpc", "sync", "master", + "puppet", "slave", "remotesync", "mastersync", - "slavesync", + "puppetsync", "'['", "']'", "'{'", @@ -210,10 +211,11 @@ static const _kws _keyword_list[] = { { GDScriptTokenizer::TK_PR_REMOTE, "remote" }, { GDScriptTokenizer::TK_PR_MASTER, "master" }, { GDScriptTokenizer::TK_PR_SLAVE, "slave" }, + { GDScriptTokenizer::TK_PR_PUPPET, "puppet" }, { GDScriptTokenizer::TK_PR_SYNC, "sync" }, { GDScriptTokenizer::TK_PR_REMOTESYNC, "remotesync" }, { GDScriptTokenizer::TK_PR_MASTERSYNC, "mastersync" }, - { GDScriptTokenizer::TK_PR_SLAVESYNC, "slavesync" }, + { GDScriptTokenizer::TK_PR_PUPPETSYNC, "puppetsync" }, { GDScriptTokenizer::TK_PR_CONST, "const" }, { GDScriptTokenizer::TK_PR_ENUM, "enum" }, //controlflow @@ -258,11 +260,11 @@ bool GDScriptTokenizer::is_token_literal(int p_offset, bool variable_safe) const case TK_PR_SIGNAL: case TK_PR_REMOTE: case TK_PR_MASTER: - case TK_PR_SLAVE: + case TK_PR_PUPPET: case TK_PR_SYNC: case TK_PR_REMOTESYNC: case TK_PR_MASTERSYNC: - case TK_PR_SLAVESYNC: + case TK_PR_PUPPETSYNC: return true; // Literal for non-variables only: diff --git a/modules/gdscript/gdscript_tokenizer.h b/modules/gdscript/gdscript_tokenizer.h index 01b1ac5bf2..cc894fb101 100644 --- a/modules/gdscript/gdscript_tokenizer.h +++ b/modules/gdscript/gdscript_tokenizer.h @@ -119,9 +119,10 @@ public: TK_PR_SYNC, TK_PR_MASTER, TK_PR_SLAVE, + TK_PR_PUPPET, TK_PR_REMOTESYNC, TK_PR_MASTERSYNC, - TK_PR_SLAVESYNC, + TK_PR_PUPPETSYNC, TK_BRACKET_OPEN, TK_BRACKET_CLOSE, TK_CURLY_BRACKET_OPEN, diff --git a/modules/mono/csharp_script.cpp b/modules/mono/csharp_script.cpp index b9209fce92..c013c232d4 100644 --- a/modules/mono/csharp_script.cpp +++ b/modules/mono/csharp_script.cpp @@ -1541,18 +1541,20 @@ MultiplayerAPI::RPCMode CSharpInstance::_member_get_rpc_mode(GDMonoClassMember * if (p_member->has_attribute(CACHED_CLASS(RemoteAttribute))) return MultiplayerAPI::RPC_MODE_REMOTE; - if (p_member->has_attribute(CACHED_CLASS(SyncAttribute))) - return MultiplayerAPI::RPC_MODE_SYNC; if (p_member->has_attribute(CACHED_CLASS(MasterAttribute))) return MultiplayerAPI::RPC_MODE_MASTER; + if (p_member->has_attribute(CACHED_CLASS(PuppetAttribute))) + return MultiplayerAPI::RPC_MODE_PUPPET; if (p_member->has_attribute(CACHED_CLASS(SlaveAttribute))) - return MultiplayerAPI::RPC_MODE_SLAVE; + return MultiplayerAPI::RPC_MODE_PUPPET; if (p_member->has_attribute(CACHED_CLASS(RemoteSyncAttribute))) return MultiplayerAPI::RPC_MODE_REMOTESYNC; + if (p_member->has_attribute(CACHED_CLASS(SyncAttribute))) + return MultiplayerAPI::RPC_MODE_REMOTESYNC; if (p_member->has_attribute(CACHED_CLASS(MasterSyncAttribute))) return MultiplayerAPI::RPC_MODE_MASTERSYNC; - if (p_member->has_attribute(CACHED_CLASS(SlaveSyncAttribute))) - return MultiplayerAPI::RPC_MODE_SLAVESYNC; + if (p_member->has_attribute(CACHED_CLASS(PuppetSyncAttribute))) + return MultiplayerAPI::RPC_MODE_PUPPETSYNC; return MultiplayerAPI::RPC_MODE_DISABLED; } diff --git a/modules/mono/glue/Managed/Files/Attributes/RPCAttributes.cs b/modules/mono/glue/Managed/Files/Attributes/RPCAttributes.cs index 6bf9560bfa..2398e10135 100644 --- a/modules/mono/glue/Managed/Files/Attributes/RPCAttributes.cs +++ b/modules/mono/glue/Managed/Files/Attributes/RPCAttributes.cs @@ -12,6 +12,9 @@ namespace Godot public class MasterAttribute : Attribute {} [AttributeUsage(AttributeTargets.Method | AttributeTargets.Field)] + public class PuppetAttribute : Attribute {} + + [AttributeUsage(AttributeTargets.Method | AttributeTargets.Field)] public class SlaveAttribute : Attribute {} [AttributeUsage(AttributeTargets.Method | AttributeTargets.Field)] @@ -21,5 +24,5 @@ namespace Godot public class MasterSyncAttribute : Attribute {} [AttributeUsage(AttributeTargets.Method | AttributeTargets.Field)] - public class SlaveSyncAttribute : Attribute {} + public class PuppetSyncAttribute : Attribute {} } diff --git a/modules/mono/mono_gd/gd_mono_utils.cpp b/modules/mono/mono_gd/gd_mono_utils.cpp index 8fbaca0992..b97a24b09c 100644 --- a/modules/mono/mono_gd/gd_mono_utils.cpp +++ b/modules/mono/mono_gd/gd_mono_utils.cpp @@ -126,10 +126,11 @@ void MonoCache::clear_members() { class_RemoteAttribute = NULL; class_SyncAttribute = NULL; class_MasterAttribute = NULL; + class_PuppetAttribute = NULL; class_SlaveAttribute = NULL; class_RemoteSyncAttribute = NULL; class_MasterSyncAttribute = NULL; - class_SlaveSyncAttribute = NULL; + class_PuppetSyncAttribute = NULL; class_GodotMethodAttribute = NULL; field_GodotMethodAttribute_methodName = NULL; @@ -225,10 +226,11 @@ void update_godot_api_cache() { CACHE_CLASS_AND_CHECK(RemoteAttribute, GODOT_API_CLASS(RemoteAttribute)); CACHE_CLASS_AND_CHECK(SyncAttribute, GODOT_API_CLASS(SyncAttribute)); CACHE_CLASS_AND_CHECK(MasterAttribute, GODOT_API_CLASS(MasterAttribute)); + CACHE_CLASS_AND_CHECK(PuppetAttribute, GODOT_API_CLASS(PuppetAttribute)); CACHE_CLASS_AND_CHECK(SlaveAttribute, GODOT_API_CLASS(SlaveAttribute)); CACHE_CLASS_AND_CHECK(RemoteSyncAttribute, GODOT_API_CLASS(RemoteSyncAttribute)); CACHE_CLASS_AND_CHECK(MasterSyncAttribute, GODOT_API_CLASS(MasterSyncAttribute)); - CACHE_CLASS_AND_CHECK(SlaveSyncAttribute, GODOT_API_CLASS(SlaveSyncAttribute)); + CACHE_CLASS_AND_CHECK(PuppetSyncAttribute, GODOT_API_CLASS(PuppetSyncAttribute)); CACHE_CLASS_AND_CHECK(GodotMethodAttribute, GODOT_API_CLASS(GodotMethodAttribute)); CACHE_FIELD_AND_CHECK(GodotMethodAttribute, methodName, CACHED_CLASS(GodotMethodAttribute)->get_field("methodName")); diff --git a/modules/mono/mono_gd/gd_mono_utils.h b/modules/mono/mono_gd/gd_mono_utils.h index 96ff3e8116..ec3a57eb46 100644 --- a/modules/mono/mono_gd/gd_mono_utils.h +++ b/modules/mono/mono_gd/gd_mono_utils.h @@ -131,8 +131,9 @@ struct MonoCache { GDMonoClass *class_SyncAttribute; GDMonoClass *class_RemoteSyncAttribute; GDMonoClass *class_MasterSyncAttribute; - GDMonoClass *class_SlaveSyncAttribute; + GDMonoClass *class_PuppetSyncAttribute; GDMonoClass *class_MasterAttribute; + GDMonoClass *class_PuppetAttribute; GDMonoClass *class_SlaveAttribute; GDMonoClass *class_GodotMethodAttribute; GDMonoField *field_GodotMethodAttribute_methodName; diff --git a/modules/opensimplex/doc_classes/SimplexNoise.xml b/modules/opensimplex/doc_classes/SimplexNoise.xml index 2dd2318681..a5a01d88a7 100644 --- a/modules/opensimplex/doc_classes/SimplexNoise.xml +++ b/modules/opensimplex/doc_classes/SimplexNoise.xml @@ -22,7 +22,6 @@ print(noise.get_noise_3d(0.5,3.0,15.0)) print(noise.get_noise_3d(0.5,1.9,4.7,0.0)) [/codeblock] - </description> <tutorials> </tutorials> diff --git a/modules/visual_script/visual_script_nodes.cpp b/modules/visual_script/visual_script_nodes.cpp index 99f242e974..5c880f48d1 100644 --- a/modules/visual_script/visual_script_nodes.cpp +++ b/modules/visual_script/visual_script_nodes.cpp @@ -167,7 +167,7 @@ void VisualScriptFunction::_get_property_list(List<PropertyInfo> *p_list) const p_list->push_back(PropertyInfo(Variant::INT, "stack/size", PROPERTY_HINT_RANGE, "1,100000")); } p_list->push_back(PropertyInfo(Variant::BOOL, "stack/stackless")); - p_list->push_back(PropertyInfo(Variant::INT, "rpc/mode", PROPERTY_HINT_ENUM, "Disabled,Remote,Sync,Master,Slave")); + p_list->push_back(PropertyInfo(Variant::INT, "rpc/mode", PROPERTY_HINT_ENUM, "Disabled,Remote,Master,Puppet,Remote Sync,Master Sync,Puppet Sync")); } int VisualScriptFunction::get_output_sequence_port_count() const { diff --git a/modules/visual_script/visual_script_property_selector.cpp b/modules/visual_script/visual_script_property_selector.cpp index 39997d14c4..9942d5baa6 100644 --- a/modules/visual_script/visual_script_property_selector.cpp +++ b/modules/visual_script/visual_script_property_selector.cpp @@ -31,6 +31,7 @@ #include "visual_script_property_selector.h" #include "core/os/keyboard.h" +#include "editor/editor_node.h" #include "editor_scale.h" #include "modules/visual_script/visual_script.h" #include "modules/visual_script/visual_script_builtin_funcs.h" @@ -176,10 +177,8 @@ void VisualScriptPropertySelector::_update_search() { Ref<Texture> icon; if (E->get().name == "Script Variables") { icon = get_icon("Script", "EditorIcons"); - } else if (has_icon(E->get().name, "EditorIcons")) { - icon = get_icon(E->get().name, "EditorIcons"); } else { - icon = get_icon("Object", "EditorIcons"); + icon = EditorNode::get_singleton()->get_class_icon(E->get().name); } category->set_icon(0, icon); continue; @@ -289,10 +288,8 @@ void VisualScriptPropertySelector::_update_search() { if (E->get().name == "*Script Methods") { icon = get_icon("Script", "EditorIcons"); script_methods = true; - } else if (has_icon(rep, "EditorIcons")) { - icon = get_icon(rep, "EditorIcons"); } else { - icon = get_icon("Object", "EditorIcons"); + icon = EditorNode::get_singleton()->get_class_icon(rep); } category->set_icon(0, icon); diff --git a/platform/osx/os_osx.mm b/platform/osx/os_osx.mm index c0de4e3f2a..b98113baeb 100644 --- a/platform/osx/os_osx.mm +++ b/platform/osx/os_osx.mm @@ -1662,7 +1662,7 @@ void OS_OSX::set_custom_mouse_cursor(const RES &p_cursor, CursorShape p_shape, c [cursors[p_shape] release]; cursors[p_shape] = cursor; - if (p_shape == CURSOR_ARROW) { + if (p_shape == cursor_shape) { [cursor set]; } @@ -1671,8 +1671,10 @@ void OS_OSX::set_custom_mouse_cursor(const RES &p_cursor, CursorShape p_shape, c } else { // Reset to default system cursor cursors[p_shape] = NULL; + + CursorShape c = cursor_shape; cursor_shape = CURSOR_MAX; - set_cursor_shape(p_shape); + set_cursor_shape(c); } } diff --git a/platform/windows/os_windows.cpp b/platform/windows/os_windows.cpp index 67fc1c7496..f63aebbbd3 100644 --- a/platform/windows/os_windows.cpp +++ b/platform/windows/os_windows.cpp @@ -2311,7 +2311,7 @@ void OS_Windows::set_custom_mouse_cursor(const RES &p_cursor, CursorShape p_shap cursors[p_shape] = CreateIconIndirect(&iconinfo); - if (p_shape == CURSOR_ARROW) { + if (p_shape == cursor_shape) { SetCursor(cursors[p_shape]); } @@ -2328,8 +2328,10 @@ void OS_Windows::set_custom_mouse_cursor(const RES &p_cursor, CursorShape p_shap } else { // Reset to default system cursor cursors[p_shape] = NULL; + + CursorShape c = cursor_shape; cursor_shape = CURSOR_MAX; - set_cursor_shape(p_shape); + set_cursor_shape(c); } } diff --git a/platform/x11/os_x11.cpp b/platform/x11/os_x11.cpp index b80a20ce40..24dfe541f9 100644 --- a/platform/x11/os_x11.cpp +++ b/platform/x11/os_x11.cpp @@ -2606,7 +2606,7 @@ void OS_X11::set_custom_mouse_cursor(const RES &p_cursor, CursorShape p_shape, c // Save it for a further usage cursors[p_shape] = XcursorImageLoadCursor(x11_display, cursor_image); - if (p_shape == CURSOR_ARROW) { + if (p_shape == current_cursor) { XDefineCursor(x11_display, x11_window, cursors[p_shape]); } @@ -2618,8 +2618,9 @@ void OS_X11::set_custom_mouse_cursor(const RES &p_cursor, CursorShape p_shape, c cursors[p_shape] = XcursorImageLoadCursor(x11_display, img[p_shape]); } + CursorShape c = current_cursor; current_cursor = CURSOR_MAX; - set_cursor_shape(p_shape); + set_cursor_shape(c); } } diff --git a/scene/gui/rich_text_label.cpp b/scene/gui/rich_text_label.cpp index 1e281471a6..fa5019a6f7 100644 --- a/scene/gui/rich_text_label.cpp +++ b/scene/gui/rich_text_label.cpp @@ -29,12 +29,13 @@ /*************************************************************************/ #include "rich_text_label.h" + #include "core/os/keyboard.h" #include "core/os/os.h" #include "scene/scene_string_names.h" #ifdef TOOLS_ENABLED -#include "editor/editor_node.h" +#include "editor/editor_scale.h" #endif RichTextLabel::Item *RichTextLabel::_get_next_item(Item *p_item, bool p_free) { @@ -2295,7 +2296,7 @@ RichTextLabel::RichTextLabel() { vscroll = memnew(VScrollBar); add_child(vscroll); - vscroll->set_drag_slave(String("..")); + vscroll->set_drag_node(String("..")); vscroll->set_step(1); vscroll->set_anchor_and_margin(MARGIN_TOP, ANCHOR_BEGIN, 0); vscroll->set_anchor_and_margin(MARGIN_BOTTOM, ANCHOR_END, 0); diff --git a/scene/gui/scroll_bar.cpp b/scene/gui/scroll_bar.cpp index df27fb0e6b..07380f45cc 100644 --- a/scene/gui/scroll_bar.cpp +++ b/scene/gui/scroll_bar.cpp @@ -300,24 +300,24 @@ void ScrollBar::_notification(int p_what) { if (p_what == NOTIFICATION_ENTER_TREE) { - if (has_node(drag_slave_path)) { - Node *n = get_node(drag_slave_path); - drag_slave = Object::cast_to<Control>(n); + if (has_node(drag_node_path)) { + Node *n = get_node(drag_node_path); + drag_node = Object::cast_to<Control>(n); } - if (drag_slave) { - drag_slave->connect("gui_input", this, "_drag_slave_input"); - drag_slave->connect("tree_exiting", this, "_drag_slave_exit", varray(), CONNECT_ONESHOT); + if (drag_node) { + drag_node->connect("gui_input", this, "_drag_node_input"); + drag_node->connect("tree_exiting", this, "_drag_node_exit", varray(), CONNECT_ONESHOT); } } if (p_what == NOTIFICATION_EXIT_TREE) { - if (drag_slave) { - drag_slave->disconnect("gui_input", this, "_drag_slave_input"); - drag_slave->disconnect("tree_exiting", this, "_drag_slave_exit"); + if (drag_node) { + drag_node->disconnect("gui_input", this, "_drag_node_input"); + drag_node->disconnect("tree_exiting", this, "_drag_node_exit"); } - drag_slave = NULL; + drag_node = NULL; } if (p_what == NOTIFICATION_INTERNAL_PHYSICS_PROCESS) { @@ -337,12 +337,13 @@ void ScrollBar::_notification(int p_what) { scrolling = false; set_physics_process_internal(false); } - } else if (drag_slave_touching) { - if (drag_slave_touching_deaccel) { + } else if (drag_node_touching) { + + if (drag_node_touching_deaccel) { Vector2 pos = Vector2(orientation == HORIZONTAL ? get_value() : 0, orientation == VERTICAL ? get_value() : 0); - pos += drag_slave_speed * get_physics_process_delta_time(); + pos += drag_node_speed * get_physics_process_delta_time(); bool turnoff = false; @@ -360,15 +361,15 @@ void ScrollBar::_notification(int p_what) { set_value(pos.x); - float sgn_x = drag_slave_speed.x < 0 ? -1 : 1; - float val_x = Math::abs(drag_slave_speed.x); + float sgn_x = drag_node_speed.x < 0 ? -1 : 1; + float val_x = Math::abs(drag_node_speed.x); val_x -= 1000 * get_physics_process_delta_time(); if (val_x < 0) { turnoff = true; } - drag_slave_speed.x = sgn_x * val_x; + drag_node_speed.x = sgn_x * val_x; } else { @@ -384,29 +385,29 @@ void ScrollBar::_notification(int p_what) { set_value(pos.y); - float sgn_y = drag_slave_speed.y < 0 ? -1 : 1; - float val_y = Math::abs(drag_slave_speed.y); + float sgn_y = drag_node_speed.y < 0 ? -1 : 1; + float val_y = Math::abs(drag_node_speed.y); val_y -= 1000 * get_physics_process_delta_time(); if (val_y < 0) { turnoff = true; } - drag_slave_speed.y = sgn_y * val_y; + drag_node_speed.y = sgn_y * val_y; } if (turnoff) { set_physics_process_internal(false); - drag_slave_touching = false; - drag_slave_touching_deaccel = false; + drag_node_touching = false; + drag_node_touching_deaccel = false; } } else { if (time_since_motion == 0 || time_since_motion > 0.1) { - Vector2 diff = drag_slave_accum - last_drag_slave_accum; - last_drag_slave_accum = drag_slave_accum; - drag_slave_speed = diff / get_physics_process_delta_time(); + Vector2 diff = drag_node_accum - last_drag_node_accum; + last_drag_node_accum = drag_node_accum; + drag_node_speed = diff / get_physics_process_delta_time(); } time_since_motion += get_physics_process_delta_time(); @@ -544,15 +545,15 @@ float ScrollBar::get_custom_step() const { return custom_step; } -void ScrollBar::_drag_slave_exit() { +void ScrollBar::_drag_node_exit() { - if (drag_slave) { - drag_slave->disconnect("gui_input", this, "_drag_slave_input"); + if (drag_node) { + drag_node->disconnect("gui_input", this, "_drag_node_input"); } - drag_slave = NULL; + drag_node = NULL; } -void ScrollBar::_drag_slave_input(const Ref<InputEvent> &p_input) { +void ScrollBar::_drag_node_input(const Ref<InputEvent> &p_input) { Ref<InputEventMouseButton> mb = p_input; @@ -563,43 +564,30 @@ void ScrollBar::_drag_slave_input(const Ref<InputEvent> &p_input) { if (mb->is_pressed()) { - if (drag_slave_touching) { - set_physics_process_internal(false); - drag_slave_touching_deaccel = false; - drag_slave_touching = false; - drag_slave_speed = Vector2(); - drag_slave_accum = Vector2(); - last_drag_slave_accum = Vector2(); - drag_slave_from = Vector2(); - } + drag_node_speed = Vector2(); + drag_node_accum = Vector2(); + last_drag_node_accum = Vector2(); + drag_node_from = Vector2(orientation == HORIZONTAL ? get_value() : 0, orientation == VERTICAL ? get_value() : 0); - if (true) { - drag_slave_speed = Vector2(); - drag_slave_accum = Vector2(); - last_drag_slave_accum = Vector2(); - //drag_slave_from=Vector2(h_scroll->get_val(),v_scroll->get_val()); - drag_slave_from = Vector2(orientation == HORIZONTAL ? get_value() : 0, orientation == VERTICAL ? get_value() : 0); + drag_node_touching = OS::get_singleton()->has_touchscreen_ui_hint(); + drag_node_touching_deaccel = false; + time_since_motion = 0; - drag_slave_touching = OS::get_singleton()->has_touchscreen_ui_hint(); - drag_slave_touching_deaccel = false; + if (drag_node_touching) { + set_physics_process_internal(true); time_since_motion = 0; - if (drag_slave_touching) { - set_physics_process_internal(true); - time_since_motion = 0; - } } } else { - if (drag_slave_touching) { + if (drag_node_touching) { - if (drag_slave_speed == Vector2()) { - drag_slave_touching_deaccel = false; - drag_slave_touching = false; + if (drag_node_speed == Vector2()) { + drag_node_touching_deaccel = false; + drag_node_touching = false; set_physics_process_internal(false); } else { - - drag_slave_touching_deaccel = true; + drag_node_touching_deaccel = true; } } } @@ -609,60 +597,54 @@ void ScrollBar::_drag_slave_input(const Ref<InputEvent> &p_input) { if (mm.is_valid()) { - if (drag_slave_touching && !drag_slave_touching_deaccel) { + if (drag_node_touching && !drag_node_touching_deaccel) { Vector2 motion = Vector2(mm->get_relative().x, mm->get_relative().y); - drag_slave_accum -= motion; - Vector2 diff = drag_slave_from + drag_slave_accum; + drag_node_accum -= motion; + Vector2 diff = drag_node_from + drag_node_accum; if (orientation == HORIZONTAL) set_value(diff.x); - /* - else - drag_slave_accum.x=0; - */ + if (orientation == VERTICAL) set_value(diff.y); - /* - else - drag_slave_accum.y=0; - */ + time_since_motion = 0; } } } -void ScrollBar::set_drag_slave(const NodePath &p_path) { +void ScrollBar::set_drag_node(const NodePath &p_path) { if (is_inside_tree()) { - if (drag_slave) { - drag_slave->disconnect("gui_input", this, "_drag_slave_input"); - drag_slave->disconnect("tree_exiting", this, "_drag_slave_exit"); + if (drag_node) { + drag_node->disconnect("gui_input", this, "_drag_node_input"); + drag_node->disconnect("tree_exiting", this, "_drag_node_exit"); } } - drag_slave = NULL; - drag_slave_path = p_path; + drag_node = NULL; + drag_node_path = p_path; if (is_inside_tree()) { if (has_node(p_path)) { Node *n = get_node(p_path); - drag_slave = Object::cast_to<Control>(n); + drag_node = Object::cast_to<Control>(n); } - if (drag_slave) { - drag_slave->connect("gui_input", this, "_drag_slave_input"); - drag_slave->connect("tree_exiting", this, "_drag_slave_exit", varray(), CONNECT_ONESHOT); + if (drag_node) { + drag_node->connect("gui_input", this, "_drag_node_input"); + drag_node->connect("tree_exiting", this, "_drag_node_exit", varray(), CONNECT_ONESHOT); } } } -NodePath ScrollBar::get_drag_slave() const { +NodePath ScrollBar::get_drag_node() const { - return drag_slave_path; + return drag_node_path; } void ScrollBar::set_smooth_scroll_enabled(bool p_enable) { @@ -678,8 +660,8 @@ void ScrollBar::_bind_methods() { ClassDB::bind_method(D_METHOD("_gui_input"), &ScrollBar::_gui_input); ClassDB::bind_method(D_METHOD("set_custom_step", "step"), &ScrollBar::set_custom_step); ClassDB::bind_method(D_METHOD("get_custom_step"), &ScrollBar::get_custom_step); - ClassDB::bind_method(D_METHOD("_drag_slave_input"), &ScrollBar::_drag_slave_input); - ClassDB::bind_method(D_METHOD("_drag_slave_exit"), &ScrollBar::_drag_slave_exit); + ClassDB::bind_method(D_METHOD("_drag_node_input"), &ScrollBar::_drag_node_input); + ClassDB::bind_method(D_METHOD("_drag_node_exit"), &ScrollBar::_drag_node_exit); ADD_SIGNAL(MethodInfo("scrolling")); @@ -691,13 +673,13 @@ ScrollBar::ScrollBar(Orientation p_orientation) { orientation = p_orientation; highlight = HIGHLIGHT_NONE; custom_step = -1; - drag_slave = NULL; + drag_node = NULL; drag.active = false; - drag_slave_speed = Vector2(); - drag_slave_touching = false; - drag_slave_touching_deaccel = false; + drag_node_speed = Vector2(); + drag_node_touching = false; + drag_node_touching_deaccel = false; scrolling = false; target_scroll = 0; diff --git a/scene/gui/scroll_bar.h b/scene/gui/scroll_bar.h index 15e037f8bb..cde4120cdb 100644 --- a/scene/gui/scroll_bar.h +++ b/scene/gui/scroll_bar.h @@ -36,6 +36,7 @@ /** @author Juan Linietsky <reduzio@gmail.com> */ + class ScrollBar : public Range { GDCLASS(ScrollBar, Range); @@ -71,25 +72,25 @@ class ScrollBar : public Range { static void set_can_focus_by_default(bool p_can_focus); - Node *drag_slave; - NodePath drag_slave_path; + Node *drag_node; + NodePath drag_node_path; - Vector2 drag_slave_speed; - Vector2 drag_slave_accum; - Vector2 drag_slave_from; - Vector2 last_drag_slave_accum; - float last_drag_slave_time; + Vector2 drag_node_speed; + Vector2 drag_node_accum; + Vector2 drag_node_from; + Vector2 last_drag_node_accum; + float last_drag_node_time; float time_since_motion; - bool drag_slave_touching; - bool drag_slave_touching_deaccel; + bool drag_node_touching; + bool drag_node_touching_deaccel; bool click_handled; bool scrolling; double target_scroll; bool smooth_scroll_enabled; - void _drag_slave_exit(); - void _drag_slave_input(const Ref<InputEvent> &p_input); + void _drag_node_exit(); + void _drag_node_input(const Ref<InputEvent> &p_input); void _gui_input(Ref<InputEvent> p_event); @@ -102,8 +103,8 @@ public: void set_custom_step(float p_custom_step); float get_custom_step() const; - void set_drag_slave(const NodePath &p_path); - NodePath get_drag_slave() const; + void set_drag_node(const NodePath &p_path); + NodePath get_drag_node() const; void set_smooth_scroll_enabled(bool p_enable); bool is_smooth_scroll_enabled() const; diff --git a/scene/main/viewport.cpp b/scene/main/viewport.cpp index dfd9dfa52e..487ca2b009 100644 --- a/scene/main/viewport.cpp +++ b/scene/main/viewport.cpp @@ -2789,6 +2789,8 @@ void Viewport::_bind_methods() { ClassDB::bind_method(D_METHOD("gui_get_drag_data"), &Viewport::gui_get_drag_data); ClassDB::bind_method(D_METHOD("gui_is_dragging"), &Viewport::gui_is_dragging); + ClassDB::bind_method(D_METHOD("get_modal_stack_top"), &Viewport::get_modal_stack_top); + ClassDB::bind_method(D_METHOD("set_disable_input", "disable"), &Viewport::set_disable_input); ClassDB::bind_method(D_METHOD("is_input_disabled"), &Viewport::is_input_disabled); |