diff options
139 files changed, 969 insertions, 835 deletions
diff --git a/core/compressed_translation.cpp b/core/compressed_translation.cpp index f102721470..d927b74897 100644 --- a/core/compressed_translation.cpp +++ b/core/compressed_translation.cpp @@ -136,6 +136,8 @@ void PHashTranslation::generate(const Ref<Translation> &p_from) { bucket_table_size += 2 + b.size() * 4; } + ERR_FAIL_COND(bucket_table_size == 0); + hash_table.resize(size); bucket_table.resize(bucket_table_size); diff --git a/core/resource.cpp b/core/resource.cpp index 87c92ca5b1..e0a40b6f3c 100644 --- a/core/resource.cpp +++ b/core/resource.cpp @@ -365,17 +365,38 @@ bool Resource::is_translation_remapped() const { //helps keep IDs same number when loading/saving scenes. -1 clears ID and it Returns -1 when no id stored void Resource::set_id_for_path(const String &p_path, int p_id) { if (p_id == -1) { - id_for_path.erase(p_path); + if (ResourceCache::path_cache_lock) { + ResourceCache::path_cache_lock->write_lock(); + } + ResourceCache::resource_path_cache[p_path].erase(get_path()); + if (ResourceCache::path_cache_lock) { + ResourceCache::path_cache_lock->write_unlock(); + } } else { - id_for_path[p_path] = p_id; + if (ResourceCache::path_cache_lock) { + ResourceCache::path_cache_lock->write_lock(); + } + ResourceCache::resource_path_cache[p_path][get_path()] = p_id; + if (ResourceCache::path_cache_lock) { + ResourceCache::path_cache_lock->write_unlock(); + } } } int Resource::get_id_for_path(const String &p_path) const { - - if (id_for_path.has(p_path)) { - return id_for_path[p_path]; + if (ResourceCache::path_cache_lock) { + ResourceCache::path_cache_lock->read_lock(); + } + if (ResourceCache::resource_path_cache[p_path].has(get_path())) { + int result = ResourceCache::resource_path_cache[p_path][get_path()]; + if (ResourceCache::path_cache_lock) { + ResourceCache::path_cache_lock->read_unlock(); + } + return result; } else { + if (ResourceCache::path_cache_lock) { + ResourceCache::path_cache_lock->read_unlock(); + } return -1; } } @@ -430,12 +451,21 @@ Resource::~Resource() { } HashMap<String, Resource *> ResourceCache::resources; +#ifdef TOOLS_ENABLED +HashMap<String, HashMap<String, int> > ResourceCache::resource_path_cache; +#endif RWLock *ResourceCache::lock = NULL; +#ifdef TOOLS_ENABLED +RWLock *ResourceCache::path_cache_lock = NULL; +#endif void ResourceCache::setup() { lock = RWLock::create(); +#ifdef TOOLS_ENABLED + path_cache_lock = RWLock::create(); +#endif } void ResourceCache::clear() { diff --git a/core/resource.h b/core/resource.h index 038b4f6278..3e1fe07137 100644 --- a/core/resource.h +++ b/core/resource.h @@ -84,9 +84,7 @@ protected: void _set_path(const String &p_path); void _take_over_path(const String &p_path); -#ifdef TOOLS_ENABLED - Map<String, int> id_for_path; -#endif + public: static Node *(*_get_local_scene_func)(); //used by editor @@ -152,6 +150,10 @@ class ResourceCache { friend class ResourceLoader; //need the lock static RWLock *lock; static HashMap<String, Resource *> resources; +#ifdef TOOLS_ENABLED + static HashMap<String, HashMap<String, int> > resource_path_cache; // each tscn has a set of resource paths and IDs + static RWLock *path_cache_lock; +#endif // TOOLS_ENABLED friend void unregister_core_types(); static void clear(); friend void register_core_types(); diff --git a/core/variant_call.cpp b/core/variant_call.cpp index 1b5ca9d3e5..40b944744b 100644 --- a/core/variant_call.cpp +++ b/core/variant_call.cpp @@ -316,6 +316,10 @@ struct _VariantCall { static void _call_String_to_ascii(Variant &r_ret, Variant &p_self, const Variant **p_args) { String *s = reinterpret_cast<String *>(p_self._data._mem); + if (s->empty()) { + r_ret = PoolByteArray(); + return; + } CharString charstr = s->ascii(); PoolByteArray retval; @@ -331,6 +335,10 @@ struct _VariantCall { static void _call_String_to_utf8(Variant &r_ret, Variant &p_self, const Variant **p_args) { String *s = reinterpret_cast<String *>(p_self._data._mem); + if (s->empty()) { + r_ret = PoolByteArray(); + return; + } CharString charstr = s->utf8(); PoolByteArray retval; @@ -545,7 +553,7 @@ struct _VariantCall { PoolByteArray *ba = reinterpret_cast<PoolByteArray *>(p_self._data._mem); String s; - if (ba->size() >= 0) { + if (ba->size() > 0) { PoolByteArray::Read r = ba->read(); CharString cs; cs.resize(ba->size() + 1); @@ -561,7 +569,7 @@ struct _VariantCall { PoolByteArray *ba = reinterpret_cast<PoolByteArray *>(p_self._data._mem); String s; - if (ba->size() >= 0) { + if (ba->size() > 0) { PoolByteArray::Read r = ba->read(); s.parse_utf8((const char *)r.ptr(), ba->size()); } @@ -572,14 +580,15 @@ struct _VariantCall { PoolByteArray *ba = reinterpret_cast<PoolByteArray *>(p_self._data._mem); PoolByteArray compressed; - Compression::Mode mode = (Compression::Mode)(int)(*p_args[0]); + if (ba->size() > 0) { + Compression::Mode mode = (Compression::Mode)(int)(*p_args[0]); - compressed.resize(Compression::get_max_compressed_buffer_size(ba->size(), mode)); - int result = Compression::compress(compressed.write().ptr(), ba->read().ptr(), ba->size(), mode); - - result = result >= 0 ? result : 0; - compressed.resize(result); + compressed.resize(Compression::get_max_compressed_buffer_size(ba->size(), mode)); + int result = Compression::compress(compressed.write().ptr(), ba->read().ptr(), ba->size(), mode); + result = result >= 0 ? result : 0; + compressed.resize(result); + } r_ret = compressed; } @@ -591,9 +600,9 @@ struct _VariantCall { int buffer_size = (int)(*p_args[0]); - if (buffer_size < 0) { + if (buffer_size <= 0) { r_ret = decompressed; - ERR_FAIL_MSG("Decompression buffer size is less than zero."); + ERR_FAIL_MSG("Decompression buffer size must be greater than zero."); } decompressed.resize(buffer_size); @@ -607,6 +616,10 @@ struct _VariantCall { static void _call_PoolByteArray_hex_encode(Variant &r_ret, Variant &p_self, const Variant **p_args) { PoolByteArray *ba = reinterpret_cast<PoolByteArray *>(p_self._data._mem); + if (ba->size() == 0) { + r_ret = String(); + return; + } PoolByteArray::Read r = ba->read(); String s = String::hex_encode_buffer(&r[0], ba->size()); r_ret = s; diff --git a/doc/classes/ConfigFile.xml b/doc/classes/ConfigFile.xml index 775ad4c922..56f54e4434 100644 --- a/doc/classes/ConfigFile.xml +++ b/doc/classes/ConfigFile.xml @@ -39,6 +39,16 @@ Deletes the specified section along with all the key-value pairs inside. </description> </method> + <method name="erase_section_key"> + <return type="void"> + </return> + <argument index="0" name="section" type="String"> + </argument> + <argument index="1" name="key" type="String"> + </argument> + <description> + </description> + </method> <method name="get_section_keys" qualifiers="const"> <return type="PoolStringArray"> </return> diff --git a/doc/classes/NavigationMesh.xml b/doc/classes/NavigationMesh.xml index f6c7a7d1b5..6528704bb5 100644 --- a/doc/classes/NavigationMesh.xml +++ b/doc/classes/NavigationMesh.xml @@ -107,6 +107,10 @@ </member> <member name="geometry/parsed_geometry_type" type="int" setter="set_parsed_geometry_type" getter="get_parsed_geometry_type" default="0"> </member> + <member name="geometry/source_geometry_mode" type="int" setter="set_source_geometry_mode" getter="get_source_geometry_mode" default="0"> + </member> + <member name="geometry/source_group_name" type="String" setter="set_source_group_name" getter="get_source_group_name"> + </member> <member name="polygon/verts_per_poly" type="float" setter="set_verts_per_poly" getter="get_verts_per_poly" default="6.0"> </member> <member name="region/merge_size" type="float" setter="set_region_merge_size" getter="get_region_merge_size" default="20.0"> diff --git a/doc/classes/PopupMenu.xml b/doc/classes/PopupMenu.xml index 50b300d216..691aec2eb1 100644 --- a/doc/classes/PopupMenu.xml +++ b/doc/classes/PopupMenu.xml @@ -156,7 +156,7 @@ </argument> <argument index="1" name="max_states" type="int"> </argument> - <argument index="2" name="default_state" type="int"> + <argument index="2" name="default_state" type="int" default="0"> </argument> <argument index="3" name="id" type="int" default="-1"> </argument> diff --git a/doc/classes/ScriptCreateDialog.xml b/doc/classes/ScriptCreateDialog.xml index 30d67d47f3..3d0fa9a0d5 100644 --- a/doc/classes/ScriptCreateDialog.xml +++ b/doc/classes/ScriptCreateDialog.xml @@ -31,9 +31,9 @@ </methods> <members> <member name="dialog_hide_on_ok" type="bool" setter="set_hide_on_ok" getter="get_hide_on_ok" override="true" default="false" /> - <member name="margin_bottom" type="float" setter="set_margin" getter="get_margin" override="true" default="76.0" /> - <member name="margin_right" type="float" setter="set_margin" getter="get_margin" override="true" default="200.0" /> - <member name="rect_size" type="Vector2" setter="_set_size" getter="get_size" override="true" default="Vector2( 200, 76 )" /> + <member name="margin_bottom" type="float" setter="set_margin" getter="get_margin" override="true" default="232.0" /> + <member name="margin_right" type="float" setter="set_margin" getter="get_margin" override="true" default="361.0" /> + <member name="rect_size" type="Vector2" setter="_set_size" getter="get_size" override="true" default="Vector2( 361, 232 )" /> <member name="window_title" type="String" setter="set_title" getter="get_title" override="true" default=""Attach Node Script"" /> </members> <signals> diff --git a/doc/classes/Skeleton2D.xml b/doc/classes/Skeleton2D.xml index 064a7266bd..886e8244a2 100644 --- a/doc/classes/Skeleton2D.xml +++ b/doc/classes/Skeleton2D.xml @@ -1,6 +1,7 @@ <?xml version="1.0" encoding="UTF-8" ?> <class name="Skeleton2D" inherits="Node2D" category="Core" version="3.2"> <brief_description> + Skeleton for 2D characters and animated objects. </brief_description> <description> </description> @@ -20,6 +21,7 @@ <return type="int"> </return> <description> + Returns the amount of bones in the skeleton. </description> </method> <method name="get_skeleton" qualifiers="const"> diff --git a/doc/classes/TreeItem.xml b/doc/classes/TreeItem.xml index a4c976591f..c77388e5f4 100644 --- a/doc/classes/TreeItem.xml +++ b/doc/classes/TreeItem.xml @@ -26,6 +26,15 @@ Adds a button with [Texture] [code]button[/code] at column [code]column[/code]. The [code]button_idx[/code] index is used to identify the button when calling other methods. If not specified, the next available index is used, which may be retrieved by calling [method get_button_count] immediately after this method. Optionally, the button can be [code]disabled[/code] and have a [code]tooltip[/code]. </description> </method> + <method name="call_recursive" qualifiers="vararg"> + <return type="Variant"> + </return> + <argument index="0" name="method" type="String"> + </argument> + <description> + Calls the [code]method[/code] on the actual TreeItem and its children recursively. Pass parameters as a comma separated list. + </description> + </method> <method name="clear_custom_bg_color"> <return type="void"> </return> @@ -594,15 +603,6 @@ Sets the given column's tooltip text. </description> </method> - <method name="call_recursive" qualifiers="vararg"> - <return type="Variant"> - </return> - <argument index="0" name="method" type="String"> - </argument> - <description> - Calls the [code]method[/code] on the actual TreeItem and its children recursively. Pass parameters as a comma separated list. - </description> - </method> </methods> <members> <member name="collapsed" type="bool" setter="set_collapsed" getter="is_collapsed"> diff --git a/doc/classes/VisualShaderNodeCubeMapUniform.xml b/doc/classes/VisualShaderNodeCubeMapUniform.xml index 453af81009..c6b3db5a9d 100644 --- a/doc/classes/VisualShaderNodeCubeMapUniform.xml +++ b/doc/classes/VisualShaderNodeCubeMapUniform.xml @@ -8,9 +8,6 @@ </tutorials> <methods> </methods> - <members> - <member name="default_input_values" type="Array" setter="_set_default_input_values" getter="_get_default_input_values" override="true" default="[ ]" /> - </members> <constants> </constants> </class> diff --git a/drivers/gles3/rasterizer_scene_gles3.cpp b/drivers/gles3/rasterizer_scene_gles3.cpp index 35f414cf09..519fdf2b3b 100644 --- a/drivers/gles3/rasterizer_scene_gles3.cpp +++ b/drivers/gles3/rasterizer_scene_gles3.cpp @@ -1093,7 +1093,7 @@ void RasterizerSceneGLES3::gi_probe_instance_set_bounds(RID p_probe, const Vecto //////////////////////////// //////////////////////////// -bool RasterizerSceneGLES3::_setup_material(RasterizerStorageGLES3::Material *p_material, bool p_alpha_pass) { +bool RasterizerSceneGLES3::_setup_material(RasterizerStorageGLES3::Material *p_material, bool p_depth_pass, bool p_alpha_pass) { /* this is handled outside if (p_material->shader->spatial.cull_mode == RasterizerStorageGLES3::Shader::Spatial::CULL_MODE_DISABLED) { @@ -1121,7 +1121,7 @@ bool RasterizerSceneGLES3::_setup_material(RasterizerStorageGLES3::Material *p_m if (state.current_depth_draw != p_material->shader->spatial.depth_draw_mode) { switch (p_material->shader->spatial.depth_draw_mode) { case RasterizerStorageGLES3::Shader::Spatial::DEPTH_DRAW_ALPHA_PREPASS: { - glDepthMask(GL_TRUE); + glDepthMask(p_depth_pass); // If some transparent objects write to depth, we need to re-copy depth texture when we need it if (p_alpha_pass && !state.used_depth_prepass) { state.prepared_depth_texture = false; @@ -2241,7 +2241,7 @@ void RasterizerSceneGLES3::_render_list(RenderList::Element **p_elements, int p_ storage->info.render.material_switch_count++; - rebind = _setup_material(material, p_alpha_pass); + rebind = _setup_material(material, use_opaque_prepass, p_alpha_pass); if (rebind) { storage->info.render.shader_rebind_count++; diff --git a/drivers/gles3/rasterizer_scene_gles3.h b/drivers/gles3/rasterizer_scene_gles3.h index 3d09adcfeb..e6d2449653 100644 --- a/drivers/gles3/rasterizer_scene_gles3.h +++ b/drivers/gles3/rasterizer_scene_gles3.h @@ -832,7 +832,7 @@ public: _FORCE_INLINE_ void _set_cull(bool p_front, bool p_disabled, bool p_reverse_cull); - _FORCE_INLINE_ bool _setup_material(RasterizerStorageGLES3::Material *p_material, bool p_alpha_pass); + _FORCE_INLINE_ bool _setup_material(RasterizerStorageGLES3::Material *p_material, bool p_depth_pass, bool p_alpha_pass); _FORCE_INLINE_ void _setup_geometry(RenderList::Element *e, const Transform &p_view_transform); _FORCE_INLINE_ void _render_geometry(RenderList::Element *e); _FORCE_INLINE_ void _setup_light(RenderList::Element *e, const Transform &p_view_transform); diff --git a/editor/connections_dialog.cpp b/editor/connections_dialog.cpp index 1e5eabc24e..f5a01dfb04 100644 --- a/editor/connections_dialog.cpp +++ b/editor/connections_dialog.cpp @@ -417,6 +417,7 @@ ConnectDialog::ConnectDialog() { dst_method = memnew(LineEdit); dst_method->set_h_size_flags(SIZE_EXPAND_FILL); + dst_method->connect("text_entered", this, "_builtin_text_entered"); dstm_hb->add_child(dst_method); advanced = memnew(CheckButton); diff --git a/editor/dependency_editor.cpp b/editor/dependency_editor.cpp index 5f8660e108..1f58eda396 100644 --- a/editor/dependency_editor.cpp +++ b/editor/dependency_editor.cpp @@ -646,7 +646,7 @@ DependencyErrorDialog::DependencyErrorDialog() { vb->add_margin_child(TTR("Load failed due to missing dependencies:"), files, true); files->set_v_size_flags(SIZE_EXPAND_FILL); - set_custom_minimum_size(Size2(500, 220)); + set_custom_minimum_size(Size2(500, 220) * EDSCALE); get_ok()->set_text(TTR("Open Anyway")); get_cancel()->set_text(TTR("Close")); diff --git a/editor/editor_inspector.cpp b/editor/editor_inspector.cpp index b29417b4c3..78e058eeaa 100644 --- a/editor/editor_inspector.cpp +++ b/editor/editor_inspector.cpp @@ -1566,11 +1566,11 @@ void EditorInspector::update_tree() { if (dot != -1) { String ov = name.right(dot); name = name.substr(0, dot); - name = name.camelcase_to_underscore().capitalize(); + name = name.capitalize(); name += ov; } else { - name = name.camelcase_to_underscore().capitalize(); + name = name.capitalize(); } } diff --git a/editor/editor_properties.cpp b/editor/editor_properties.cpp index 460f75eef0..9ec9df2ee9 100644 --- a/editor/editor_properties.cpp +++ b/editor/editor_properties.cpp @@ -2399,19 +2399,11 @@ void EditorPropertyResource::_update_menu_items() { inheritors_array.push_back(t); - int id = TYPE_BASE_ID + idx; - - if (!icon.is_valid() && has_icon(t, "EditorIcons")) { - icon = get_icon(t, "EditorIcons"); - } - - if (icon.is_valid()) { + if (!icon.is_valid()) + icon = get_icon(has_icon(t, "EditorIcons") ? t : "Object", "EditorIcons"); - menu->add_icon_item(icon, vformat(TTR("New %s"), t), id); - } else { - - menu->add_item(vformat(TTR("New %s"), t), id); - } + int id = TYPE_BASE_ID + idx; + menu->add_icon_item(icon, vformat(TTR("New %s"), t), id); idx++; } @@ -2925,7 +2917,7 @@ void EditorInspectorDefaultPlugin::parse_begin(Object *p_object) { bool EditorInspectorDefaultPlugin::parse_property(Object *p_object, Variant::Type p_type, const String &p_path, PropertyHint p_hint, const String &p_hint_text, int p_usage) { - float default_float_step = EDITOR_GET("interface/inspector/default_float_step"); + double default_float_step = EDITOR_GET("interface/inspector/default_float_step"); switch (p_type) { diff --git a/editor/editor_settings.cpp b/editor/editor_settings.cpp index 3ea59115b0..672844117d 100644 --- a/editor/editor_settings.cpp +++ b/editor/editor_settings.cpp @@ -559,8 +559,6 @@ void EditorSettings::_load_defaults(Ref<ConfigFile> p_extra_config) { hints["editors/3d/freelook/freelook_base_speed"] = PropertyInfo(Variant::REAL, "editors/3d/freelook/freelook_base_speed", PROPERTY_HINT_RANGE, "0.0, 10, 0.01"); _initial_set("editors/3d/freelook/freelook_activation_modifier", 0); hints["editors/3d/freelook/freelook_activation_modifier"] = PropertyInfo(Variant::INT, "editors/3d/freelook/freelook_activation_modifier", PROPERTY_HINT_ENUM, "None,Shift,Alt,Meta,Ctrl"); - _initial_set("editors/3d/freelook/freelook_modifier_speed_factor", 3.0); - hints["editors/3d/freelook/freelook_modifier_speed_factor"] = PropertyInfo(Variant::REAL, "editors/3d/freelook/freelook_modifier_speed_factor", PROPERTY_HINT_RANGE, "0.0, 10.0, 0.1"); _initial_set("editors/3d/freelook/freelook_speed_zoom_link", false); // 2D diff --git a/editor/import/editor_scene_importer_gltf.cpp b/editor/import/editor_scene_importer_gltf.cpp index 49091dc812..fcf0e4af6f 100644 --- a/editor/import/editor_scene_importer_gltf.cpp +++ b/editor/import/editor_scene_importer_gltf.cpp @@ -1973,7 +1973,7 @@ Error EditorSceneImporterGLTF::_reparent_to_fake_joint(GLTFState &state, GLTFSke state.nodes.push_back(fake_joint); // We better not be a joint, or we messed up in our logic - if (node->joint == true) + if (node->joint) return FAILED; fake_joint->translation = node->translation; diff --git a/editor/output_strings.cpp b/editor/output_strings.cpp deleted file mode 100644 index baabaff9a8..0000000000 --- a/editor/output_strings.cpp +++ /dev/null @@ -1,208 +0,0 @@ -/*************************************************************************/ -/* output_strings.cpp */ -/*************************************************************************/ -/* This file is part of: */ -/* GODOT ENGINE */ -/* https://godotengine.org */ -/*************************************************************************/ -/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ -/* */ -/* Permission is hereby granted, free of charge, to any person obtaining */ -/* a copy of this software and associated documentation files (the */ -/* "Software"), to deal in the Software without restriction, including */ -/* without limitation the rights to use, copy, modify, merge, publish, */ -/* distribute, sublicense, and/or sell copies of the Software, and to */ -/* permit persons to whom the Software is furnished to do so, subject to */ -/* the following conditions: */ -/* */ -/* The above copyright notice and this permission notice shall be */ -/* included in all copies or substantial portions of the Software. */ -/* */ -/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ -/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ -/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ -/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ -/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ -/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ -/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -/*************************************************************************/ - -#include "output_strings.h" - -void OutputStrings::update_scrollbars() { - - Size2 hmin = h_scroll->get_combined_minimum_size(); - Size2 vmin = v_scroll->get_combined_minimum_size(); - - v_scroll->set_anchor(MARGIN_LEFT, ANCHOR_END); - v_scroll->set_anchor(MARGIN_RIGHT, ANCHOR_END); - v_scroll->set_anchor(MARGIN_BOTTOM, ANCHOR_END); - - v_scroll->set_begin(Point2(-vmin.width, 0)); - v_scroll->set_end(Point2(0, 0)); - - h_scroll->set_anchor(MARGIN_RIGHT, ANCHOR_END); - h_scroll->set_anchor(MARGIN_TOP, ANCHOR_END); - h_scroll->set_anchor(MARGIN_BOTTOM, ANCHOR_END); - - h_scroll->set_begin(Point2(0, -hmin.y)); - h_scroll->set_end(Point2(-vmin.x, 0)); - - margin.y = hmin.y; - margin.x = vmin.x; - - Ref<StyleBox> tree_st = get_stylebox("bg", "Tree"); - int page = ((size_height - (int)margin.y - tree_st->get_margin(MARGIN_TOP)) / font_height); - v_scroll->set_page(page); -} - -void OutputStrings::_notification(int p_what) { - - switch (p_what) { - - case NOTIFICATION_DRAW: { - - if (following) { - - updating = true; - v_scroll->set_value(v_scroll->get_max() - v_scroll->get_page()); - updating = false; - } - - RID ci = get_canvas_item(); - Size2 size = get_size(); - - Ref<Font> font = get_font("font", "Tree"); - Ref<StyleBox> tree_st = get_stylebox("bg", "Tree"); - tree_st->draw(ci, Rect2(Point2(), size)); - Color color = get_color("font_color", "Tree"); - Ref<Texture> icon_error = get_icon("Error", "EditorIcons"); - Ref<Texture> icon_warning = get_icon("Warning", "EditorIcons"); - - //int lines = (size_height-(int)margin.y) / font_height; - Point2 ofs = tree_st->get_offset(); - - LineMap::Element *E = line_map.find(v_scroll->get_value()); - float h_ofs = (int)h_scroll->get_value(); - Point2 icon_ofs = Point2(0, (font_height - (int)icon_error->get_height()) / 2); - - FontDrawer drawer(font, Color(1, 1, 1)); - while (E && ofs.y < (size_height - (int)margin.y)) { - - String str = E->get().text; - Point2 line_ofs = ofs; - - switch (E->get().type) { - - case LINE_WARNING: { - icon_warning->draw(ci, line_ofs + icon_ofs); - - } break; - case LINE_ERROR: { - icon_error->draw(ci, line_ofs + icon_ofs); - } break; - case LINE_LINK: { - - } break; - default: { - } - } - - line_ofs.y += font->get_ascent(); - line_ofs.x += icon_error->get_width() + 4; - - for (int i = 0; i < str.length(); i++) { - if (line_ofs.x - h_ofs < 0) { - line_ofs.x += font->get_char_size(str[i], str[i + 1]).width; - } else if (line_ofs.x - h_ofs > size.width - margin.width) { - break; - } else { - line_ofs.x += font->draw_char(ci, Point2(line_ofs.x - h_ofs, line_ofs.y), str[i], str[i + 1], color); - } - } - - ofs.y += font_height; - E = E->next(); - } - - } break; - - case NOTIFICATION_ENTER_TREE: - case NOTIFICATION_RESIZED: { - - font_height = get_font("font", "Tree")->get_height(); - size_height = get_size().height; - update_scrollbars(); - } break; - } -} - -void OutputStrings::_hscroll_changed(float p_value) { - - if (updating) - return; - - update(); -} -void OutputStrings::_vscroll_changed(float p_value) { - - if (updating) - return; - //user changed scroll - following = (p_value + v_scroll->get_page()) >= v_scroll->get_max(); - update(); -} - -void OutputStrings::add_line(const String &p_text, const Variant &p_meta, const LineType p_type) { - - Vector<String> strings = p_text.split("\n"); - - for (int i = 0; i < strings.size(); i++) { - - if (strings[i].length() == 0) - continue; - - int last = line_map.empty() ? 0 : (line_map.back()->key() + 1); - - Line l; - l.text = strings[i]; - l.meta = p_meta; - l.type = p_type; - line_map.insert(last, l); - - updating = true; - v_scroll->set_max(last + 1); - v_scroll->set_min(line_map.front()->key()); - updating = false; - } - - while (line_map.size() > line_max_count) { - - line_map.erase(line_map.front()); - } - - update(); -} - -void OutputStrings::_bind_methods() { - - ClassDB::bind_method("_vscroll_changed", &OutputStrings::_vscroll_changed); - ClassDB::bind_method("_hscroll_changed", &OutputStrings::_hscroll_changed); -} - -OutputStrings::OutputStrings() { - - following = true; - updating = false; - line_max_count = 4096; - h_scroll = memnew(HScrollBar); - v_scroll = memnew(VScrollBar); - add_child(h_scroll); - add_child(v_scroll); - size_height = 1; - font_height = 1; - update_scrollbars(); - h_scroll->connect("value_changed", this, "_hscroll_changed"); - v_scroll->connect("value_changed", this, "_vscroll_changed"); -} diff --git a/editor/output_strings.h b/editor/output_strings.h deleted file mode 100644 index 4fd3f7d836..0000000000 --- a/editor/output_strings.h +++ /dev/null @@ -1,87 +0,0 @@ -/*************************************************************************/ -/* output_strings.h */ -/*************************************************************************/ -/* This file is part of: */ -/* GODOT ENGINE */ -/* https://godotengine.org */ -/*************************************************************************/ -/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ -/* */ -/* Permission is hereby granted, free of charge, to any person obtaining */ -/* a copy of this software and associated documentation files (the */ -/* "Software"), to deal in the Software without restriction, including */ -/* without limitation the rights to use, copy, modify, merge, publish, */ -/* distribute, sublicense, and/or sell copies of the Software, and to */ -/* permit persons to whom the Software is furnished to do so, subject to */ -/* the following conditions: */ -/* */ -/* The above copyright notice and this permission notice shall be */ -/* included in all copies or substantial portions of the Software. */ -/* */ -/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ -/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ -/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ -/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ -/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ -/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ -/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -/*************************************************************************/ - -#ifndef OUTPUT_STRINGS_H -#define OUTPUT_STRINGS_H - -#include "core/map.h" -#include "scene/gui/control.h" -#include "scene/gui/scroll_bar.h" - -class OutputStrings : public Control { - - GDCLASS(OutputStrings, Control); - -public: - enum LineType { - - LINE_NORMAL, - LINE_WARNING, - LINE_ERROR, - LINE_LINK - }; - -private: - struct Line { - - LineType type; - Variant meta; - String text; - }; - - int font_height; - int size_height; - - Size2 margin; - typedef Map<int, Line> LineMap; - Map<int, Line> line_map; - - VScrollBar *v_scroll; - HScrollBar *h_scroll; - - bool following; - int line_max_count; - bool updating; - - void _vscroll_changed(float p_value); - void _hscroll_changed(float p_value); - void update_scrollbars(); - -protected: - static void _bind_methods(); - void _notification(int p_what); - -public: - void add_line(const String &p_text, const Variant &p_meta = Variant(), const LineType p_type = LINE_NORMAL); - - OutputStrings(); -}; - -#endif // OUTPUT_STRINGS_H diff --git a/editor/plugins/canvas_item_editor_plugin.cpp b/editor/plugins/canvas_item_editor_plugin.cpp index f54411c72b..2a31d53a7e 100644 --- a/editor/plugins/canvas_item_editor_plugin.cpp +++ b/editor/plugins/canvas_item_editor_plugin.cpp @@ -284,7 +284,7 @@ Point2 CanvasItemEditor::snap_point(Point2 p_target, unsigned int p_modes, unsig snap_target[0] = SNAP_TARGET_NONE; snap_target[1] = SNAP_TARGET_NONE; - bool is_snap_active = snap_active ^ Input::get_singleton()->is_key_pressed(KEY_CONTROL); + bool is_snap_active = smart_snap_active ^ Input::get_singleton()->is_key_pressed(KEY_CONTROL); // Smart snap using the canvas position Vector2 output = p_target; @@ -384,7 +384,7 @@ Point2 CanvasItemEditor::snap_point(Point2 p_target, unsigned int p_modes, unsig } } - if (((is_snap_active && snap_grid && (p_modes & SNAP_GRID)) || (p_forced_modes & SNAP_GRID)) && fmod(rotation, (real_t)360.0) == 0.0) { + if (((grid_snap_active && (p_modes & SNAP_GRID)) || (p_forced_modes & SNAP_GRID)) && fmod(rotation, (real_t)360.0) == 0.0) { // Grid Point2 offset = grid_offset; if (snap_relative) { @@ -412,7 +412,7 @@ Point2 CanvasItemEditor::snap_point(Point2 p_target, unsigned int p_modes, unsig } float CanvasItemEditor::snap_angle(float p_target, float p_start) const { - return (((snap_active || snap_rotation) ^ Input::get_singleton()->is_key_pressed(KEY_CONTROL)) && snap_rotation_step != 0) ? Math::stepify(p_target - snap_rotation_offset, snap_rotation_step) + snap_rotation_offset : p_target; + return (((smart_snap_active || snap_rotation) ^ Input::get_singleton()->is_key_pressed(KEY_CONTROL)) && snap_rotation_step != 0) ? Math::stepify(p_target - snap_rotation_offset, snap_rotation_step) + snap_rotation_offset : p_target; } void CanvasItemEditor::_unhandled_key_input(const Ref<InputEvent> &p_ev) { @@ -427,11 +427,11 @@ void CanvasItemEditor::_unhandled_key_input(const Ref<InputEvent> &p_ev) { } if (k->is_pressed() && !k->get_control() && !k->is_echo()) { - if ((snap_grid || show_grid) && multiply_grid_step_shortcut.is_valid() && multiply_grid_step_shortcut->is_shortcut(p_ev)) { + if ((grid_snap_active || show_grid) && multiply_grid_step_shortcut.is_valid() && multiply_grid_step_shortcut->is_shortcut(p_ev)) { // Multiply the grid size grid_step_multiplier = MIN(grid_step_multiplier + 1, 12); viewport->update(); - } else if ((snap_grid || show_grid) && divide_grid_step_shortcut.is_valid() && divide_grid_step_shortcut->is_shortcut(p_ev)) { + } else if ((grid_snap_active || show_grid) && divide_grid_step_shortcut.is_valid() && divide_grid_step_shortcut->is_shortcut(p_ev)) { // Divide the grid size Point2 new_grid_step = grid_step * Math::pow(2.0, grid_step_multiplier - 1); if (new_grid_step.x >= 1.0 && new_grid_step.y >= 1.0) @@ -1197,7 +1197,7 @@ bool CanvasItemEditor::_gui_input_zoom_or_pan(const Ref<InputEvent> &p_event, bo //Pan the viewport panning = true; } - } else if (panning) { + } else { if (!k->is_pressed()) { // Stop panning the viewport (for any mouse button press) panning = false; @@ -2287,7 +2287,7 @@ bool CanvasItemEditor::_gui_input_ruler_tool(const Ref<InputEvent> &p_event) { return true; } - bool is_snap_active = snap_active ^ Input::get_singleton()->is_key_pressed(KEY_CONTROL); + bool is_snap_active = smart_snap_active ^ Input::get_singleton()->is_key_pressed(KEY_CONTROL); if (m.is_valid() && (ruler_tool_active || (is_snap_active && previous_origin != ruler_tool_origin))) { @@ -2558,11 +2558,10 @@ void CanvasItemEditor::_draw_rulers() { Color font_color = get_color("font_color", "Editor"); font_color.a = 0.8; Ref<Font> font = get_font("rulers", "EditorFonts"); - bool is_snap_active = snap_active ^ Input::get_singleton()->is_key_pressed(KEY_CONTROL); // The rule transform Transform2D ruler_transform = Transform2D(); - if (show_grid || (is_snap_active && snap_grid)) { + if (show_grid || grid_snap_active) { List<CanvasItem *> selection = _get_edited_canvas_items(); if (snap_relative && selection.size() > 0) { ruler_transform.translate(_get_encompassing_rect_from_list(selection).position); @@ -2642,7 +2641,7 @@ void CanvasItemEditor::_draw_rulers() { } void CanvasItemEditor::_draw_grid() { - if (show_grid) { + if (show_grid || grid_snap_active) { //Draw the grid Size2 s = viewport->get_size(); int last_cell = 0; @@ -2688,7 +2687,7 @@ void CanvasItemEditor::_draw_ruler_tool() { if (tool != TOOL_RULER) return; - bool is_snap_active = snap_active ^ Input::get_singleton()->is_key_pressed(KEY_CONTROL); + bool is_snap_active = smart_snap_active ^ Input::get_singleton()->is_key_pressed(KEY_CONTROL); if (ruler_tool_active) { Color ruler_primary_color = get_color("accent_color", "Editor"); @@ -3697,7 +3696,8 @@ void CanvasItemEditor::_notification(int p_what) { move_button->set_icon(get_icon("ToolMove", "EditorIcons")); scale_button->set_icon(get_icon("ToolScale", "EditorIcons")); rotate_button->set_icon(get_icon("ToolRotate", "EditorIcons")); - snap_button->set_icon(get_icon("Snap", "EditorIcons")); + smart_snap_button->set_icon(get_icon("Snap", "EditorIcons")); + grid_snap_button->set_icon(get_icon("SnapGrid", "EditorIcons")); snap_config_menu->set_icon(get_icon("GuiTabMenu", "EditorIcons")); skeleton_menu->set_icon(get_icon("Bone", "EditorIcons")); pan_button->set_icon(get_icon("ToolPan", "EditorIcons")); @@ -4101,8 +4101,13 @@ void CanvasItemEditor::_button_zoom_plus() { _zoom_on_position(zoom * Math_SQRT2, viewport_scrollable->get_size() / 2.0); } -void CanvasItemEditor::_button_toggle_snap(bool p_status) { - snap_active = p_status; +void CanvasItemEditor::_button_toggle_smart_snap(bool p_status) { + smart_snap_active = p_status; + viewport->update(); +} + +void CanvasItemEditor::_button_toggle_grid_snap(bool p_status) { + grid_snap_active = p_status; viewport->update(); } @@ -4261,11 +4266,6 @@ void CanvasItemEditor::_popup_callback(int p_op) { int idx = smartsnap_config_popup->get_item_index(SNAP_USE_GUIDES); smartsnap_config_popup->set_item_checked(idx, snap_guides); } break; - case SNAP_USE_GRID: { - snap_grid = !snap_grid; - int idx = snap_config_menu->get_popup()->get_item_index(SNAP_USE_GRID); - snap_config_menu->get_popup()->set_item_checked(idx, snap_grid); - } break; case SNAP_USE_ROTATION: { snap_rotation = !snap_rotation; int idx = snap_config_menu->get_popup()->get_item_index(SNAP_USE_ROTATION); @@ -4797,7 +4797,8 @@ void CanvasItemEditor::_bind_methods() { ClassDB::bind_method("_button_zoom_minus", &CanvasItemEditor::_button_zoom_minus); ClassDB::bind_method("_button_zoom_reset", &CanvasItemEditor::_button_zoom_reset); ClassDB::bind_method("_button_zoom_plus", &CanvasItemEditor::_button_zoom_plus); - ClassDB::bind_method("_button_toggle_snap", &CanvasItemEditor::_button_toggle_snap); + ClassDB::bind_method("_button_toggle_smart_snap", &CanvasItemEditor::_button_toggle_smart_snap); + ClassDB::bind_method("_button_toggle_grid_snap", &CanvasItemEditor::_button_toggle_grid_snap); ClassDB::bind_method("_button_toggle_anchor_mode", &CanvasItemEditor::_button_toggle_anchor_mode); ClassDB::bind_method("_update_scroll", &CanvasItemEditor::_update_scroll); ClassDB::bind_method("_update_scrollbars", &CanvasItemEditor::_update_scrollbars); @@ -4832,13 +4833,13 @@ Dictionary CanvasItemEditor::get_state() const { state["grid_step"] = grid_step; state["snap_rotation_offset"] = snap_rotation_offset; state["snap_rotation_step"] = snap_rotation_step; - state["snap_active"] = snap_active; + state["smart_snap_active"] = smart_snap_active; + state["grid_snap_active"] = grid_snap_active; state["snap_node_parent"] = snap_node_parent; state["snap_node_anchors"] = snap_node_anchors; state["snap_node_sides"] = snap_node_sides; state["snap_node_center"] = snap_node_center; state["snap_other_nodes"] = snap_other_nodes; - state["snap_grid"] = snap_grid; state["snap_guides"] = snap_guides; state["show_grid"] = show_grid; state["show_origin"] = show_origin; @@ -4886,9 +4887,14 @@ void CanvasItemEditor::set_state(const Dictionary &p_state) { snap_rotation_offset = state["snap_rotation_offset"]; } - if (state.has("snap_active")) { - snap_active = state["snap_active"]; - snap_button->set_pressed(snap_active); + if (state.has("smart_snap_active")) { + smart_snap_active = state["smart_snap_active"]; + smart_snap_button->set_pressed(smart_snap_active); + } + + if (state.has("grid_snap_active")) { + grid_snap_active = state["grid_snap_active"]; + grid_snap_button->set_pressed(grid_snap_active); } if (state.has("snap_node_parent")) { @@ -4927,12 +4933,6 @@ void CanvasItemEditor::set_state(const Dictionary &p_state) { smartsnap_config_popup->set_item_checked(idx, snap_guides); } - if (state.has("snap_grid")) { - snap_grid = state["snap_grid"]; - int idx = snap_config_menu->get_popup()->get_item_index(SNAP_USE_GRID); - snap_config_menu->get_popup()->set_item_checked(idx, snap_grid); - } - if (state.has("show_grid")) { show_grid = state["show_grid"]; int idx = view_menu->get_popup()->get_item_index(SHOW_GRID); @@ -5071,13 +5071,13 @@ CanvasItemEditor::CanvasItemEditor(EditorNode *p_editor) { grid_step_multiplier = 0; snap_rotation_offset = 0; snap_rotation_step = 15 / (180 / Math_PI); - snap_active = false; + smart_snap_active = false; + grid_snap_active = false; snap_node_parent = true; snap_node_anchors = true; snap_node_sides = true; snap_node_center = true; snap_other_nodes = true; - snap_grid = true; snap_guides = true; snap_rotation = false; snap_relative = false; @@ -5269,12 +5269,19 @@ CanvasItemEditor::CanvasItemEditor(EditorNode *p_editor) { hb->add_child(memnew(VSeparator)); - snap_button = memnew(ToolButton); - hb->add_child(snap_button); - snap_button->set_toggle_mode(true); - snap_button->connect("toggled", this, "_button_toggle_snap"); - snap_button->set_tooltip(TTR("Toggle snapping.")); - snap_button->set_shortcut(ED_SHORTCUT("canvas_item_editor/use_snap", TTR("Use Snap"), KEY_MASK_SHIFT | KEY_S)); + smart_snap_button = memnew(ToolButton); + hb->add_child(smart_snap_button); + smart_snap_button->set_toggle_mode(true); + smart_snap_button->connect("toggled", this, "_button_toggle_smart_snap"); + smart_snap_button->set_tooltip(TTR("Toggle smart snapping.")); + smart_snap_button->set_shortcut(ED_SHORTCUT("canvas_item_editor/use_smart_snap", TTR("Use Smart Snap"), KEY_MASK_SHIFT | KEY_S)); + + grid_snap_button = memnew(ToolButton); + hb->add_child(grid_snap_button); + grid_snap_button->set_toggle_mode(true); + grid_snap_button->connect("toggled", this, "_button_toggle_grid_snap"); + grid_snap_button->set_tooltip(TTR("Toggle grid snapping.")); + grid_snap_button->set_shortcut(ED_SHORTCUT("canvas_item_editor/use_grid_snap", TTR("Use Grid Snap"), KEY_MASK_SHIFT | KEY_G)); snap_config_menu = memnew(MenuButton); hb->add_child(snap_config_menu); @@ -5285,7 +5292,6 @@ CanvasItemEditor::CanvasItemEditor(EditorNode *p_editor) { PopupMenu *p = snap_config_menu->get_popup(); p->connect("id_pressed", this, "_popup_callback"); p->set_hide_on_checkable_item_selection(false); - p->add_check_shortcut(ED_SHORTCUT("canvas_item_editor/snap_grid", TTR("Snap to Grid")), SNAP_USE_GRID); p->add_check_shortcut(ED_SHORTCUT("canvas_item_editor/use_rotation_snap", TTR("Use Rotation Snap")), SNAP_USE_ROTATION); p->add_check_shortcut(ED_SHORTCUT("canvas_item_editor/snap_relative", TTR("Snap Relative")), SNAP_RELATIVE); p->add_check_shortcut(ED_SHORTCUT("canvas_item_editor/use_pixel_snap", TTR("Use Pixel Snap")), SNAP_USE_PIXEL); @@ -5357,7 +5363,7 @@ CanvasItemEditor::CanvasItemEditor(EditorNode *p_editor) { p = view_menu->get_popup(); p->set_hide_on_checkable_item_selection(false); - p->add_check_shortcut(ED_SHORTCUT("canvas_item_editor/show_grid", TTR("Show Grid"), KEY_G), SHOW_GRID); + p->add_check_shortcut(ED_SHORTCUT("canvas_item_editor/show_grid", TTR("Always Show Grid"), KEY_G), SHOW_GRID); p->add_check_shortcut(ED_SHORTCUT("canvas_item_editor/show_helpers", TTR("Show Helpers"), KEY_H), SHOW_HELPERS); p->add_check_shortcut(ED_SHORTCUT("canvas_item_editor/show_rulers", TTR("Show Rulers")), SHOW_RULERS); p->add_check_shortcut(ED_SHORTCUT("canvas_item_editor/show_guides", TTR("Show Guides"), KEY_Y), SHOW_GUIDES); diff --git a/editor/plugins/canvas_item_editor_plugin.h b/editor/plugins/canvas_item_editor_plugin.h index 6cce1ca10e..480fb89621 100644 --- a/editor/plugins/canvas_item_editor_plugin.h +++ b/editor/plugins/canvas_item_editor_plugin.h @@ -259,13 +259,14 @@ private: float snap_rotation_step; float snap_rotation_offset; - bool snap_active; + bool smart_snap_active; + bool grid_snap_active; + bool snap_node_parent; bool snap_node_anchors; bool snap_node_sides; bool snap_node_center; bool snap_other_nodes; - bool snap_grid; bool snap_guides; bool snap_rotation; bool snap_relative; @@ -347,7 +348,8 @@ private: ToolButton *ruler_button; - ToolButton *snap_button; + ToolButton *smart_snap_button; + ToolButton *grid_snap_button; MenuButton *snap_config_menu; PopupMenu *smartsnap_config_popup; @@ -529,7 +531,8 @@ private: void _button_zoom_minus(); void _button_zoom_reset(); void _button_zoom_plus(); - void _button_toggle_snap(bool p_status); + void _button_toggle_smart_snap(bool p_status); + void _button_toggle_grid_snap(bool p_status); void _button_tool_select(int p_index); HSplitContainer *palette_split; diff --git a/editor/plugins/spatial_editor_plugin.cpp b/editor/plugins/spatial_editor_plugin.cpp index 095350d0e1..1d8fd38858 100644 --- a/editor/plugins/spatial_editor_plugin.cpp +++ b/editor/plugins/spatial_editor_plugin.cpp @@ -2049,12 +2049,11 @@ void SpatialEditorViewport::_update_freelook(real_t delta) { return; } - Vector3 forward = camera->get_transform().basis.xform(Vector3(0, 0, -1)); - Vector3 right = camera->get_transform().basis.xform(Vector3(1, 0, 0)); - Vector3 up = camera->get_transform().basis.xform(Vector3(0, 1, 0)); + const Vector3 forward = camera->get_transform().basis.xform(Vector3(0, 0, -1)); + const Vector3 right = camera->get_transform().basis.xform(Vector3(1, 0, 0)); + const Vector3 up = camera->get_transform().basis.xform(Vector3(0, 1, 0)); Vector3 direction; - bool speed_modifier = false; if (is_shortcut_pressed("spatial_editor/freelook_left")) { direction -= right; @@ -2074,17 +2073,17 @@ void SpatialEditorViewport::_update_freelook(real_t delta) { if (is_shortcut_pressed("spatial_editor/freelook_down")) { direction -= up; } - if (is_shortcut_pressed("spatial_editor/freelook_speed_modifier")) { - speed_modifier = true; - } real_t speed = freelook_speed; - if (speed_modifier) { - real_t modifier_speed_factor = EditorSettings::get_singleton()->get("editors/3d/freelook/freelook_modifier_speed_factor"); - speed *= modifier_speed_factor; + + if (is_shortcut_pressed("spatial_editor/freelook_speed_modifier")) { + speed *= 3.0; + } + if (is_shortcut_pressed("spatial_editor/freelook_slow_modifier")) { + speed *= 0.333333; } - Vector3 motion = direction * speed * delta; + const Vector3 motion = direction * speed * delta; cursor.pos += motion; cursor.eye_pos += motion; } @@ -3588,6 +3587,7 @@ SpatialEditorViewport::SpatialEditorViewport(SpatialEditor *p_spatial_editor, Ed ED_SHORTCUT("spatial_editor/freelook_up", TTR("Freelook Up"), KEY_E); ED_SHORTCUT("spatial_editor/freelook_down", TTR("Freelook Down"), KEY_Q); ED_SHORTCUT("spatial_editor/freelook_speed_modifier", TTR("Freelook Speed Modifier"), KEY_SHIFT); + ED_SHORTCUT("spatial_editor/freelook_slow_modifier", TTR("Freelook Slow Modifier"), KEY_ALT); preview_camera = memnew(CheckBox); preview_camera->set_text(TTR("Preview")); diff --git a/editor/project_export.cpp b/editor/project_export.cpp index 7456396460..adcbddfb04 100644 --- a/editor/project_export.cpp +++ b/editor/project_export.cpp @@ -286,11 +286,13 @@ void ProjectExportDialog::_edit_preset(int p_index) { export_templates_error->hide(); export_button->set_disabled(true); + get_ok()->set_disabled(true); } else { export_error->hide(); export_templates_error->hide(); export_button->set_disabled(false); + get_ok()->set_disabled(false); } custom_features->set_text(current->get_custom_features()); @@ -623,6 +625,7 @@ void ProjectExportDialog::_delete_preset_confirm() { int idx = presets->get_current(); _edit_preset(-1); export_button->set_disabled(true); + get_ok()->set_disabled(true); EditorExport::get_singleton()->remove_export_preset(idx); _update_presets(); } @@ -1249,6 +1252,7 @@ ProjectExportDialog::ProjectExportDialog() { export_button->connect("pressed", this, "_export_project"); // Disable initially before we select a valid preset export_button->set_disabled(true); + get_ok()->set_disabled(true); export_all_dialog = memnew(ConfirmationDialog); add_child(export_all_dialog); diff --git a/editor/project_settings_editor.cpp b/editor/project_settings_editor.cpp index 35187214a6..803c806028 100644 --- a/editor/project_settings_editor.cpp +++ b/editor/project_settings_editor.cpp @@ -1109,6 +1109,8 @@ void ProjectSettingsEditor::drop_data_fw(const Point2 &p_point, const Variant &p TreeItem *selected = input_editor->get_selected(); TreeItem *item = input_editor->get_item_at_position(p_point); + if (!item) + return; TreeItem *target = item->get_parent() == input_editor->get_root() ? item : item->get_parent(); String selected_name = "input/" + selected->get_text(0); diff --git a/editor/spatial_editor_gizmos.cpp b/editor/spatial_editor_gizmos.cpp index 489049c543..16da2771b9 100644 --- a/editor/spatial_editor_gizmos.cpp +++ b/editor/spatial_editor_gizmos.cpp @@ -3730,6 +3730,7 @@ void CollisionShapeSpatialGizmoPlugin::redraw(EditorSpatialGizmo *p_gizmo) { Ref<ConcavePolygonShape> cs2 = s; Ref<ArrayMesh> mesh = cs2->get_debug_mesh(); p_gizmo->add_mesh(mesh, false, Ref<SkinReference>(), material); + p_gizmo->add_collision_segments(cs2->get_debug_mesh_lines()); } if (Object::cast_to<RayShape>(*s)) { diff --git a/main/main.cpp b/main/main.cpp index 42c90fc027..fe0f5a0215 100644 --- a/main/main.cpp +++ b/main/main.cpp @@ -1856,9 +1856,7 @@ bool Main::start() { // Hide console window if requested (Windows-only). bool hide_console = EditorSettings::get_singleton()->get_setting("interface/editor/hide_console_window"); OS::get_singleton()->set_console_visible(!hide_console); - } - if (project_manager || editor) { // Load SSL Certificates from Editor Settings (or builtin) Crypto::load_default_certificates(EditorSettings::get_singleton()->get_setting("network/ssl/editor_ssl_certificates").operator String()); } diff --git a/main/splash.png b/main/splash.png Binary files differindex 32960db65f..7bddd4325a 100644 --- a/main/splash.png +++ b/main/splash.png diff --git a/main/splash_editor.png b/main/splash_editor.png Binary files differindex ab10716a2e..2967d8dd3e 100644 --- a/main/splash_editor.png +++ b/main/splash_editor.png diff --git a/misc/dist/ios_xcode/godot_ios/Images.xcassets/LaunchImage.launchimage/Default-480h@2x.png b/misc/dist/ios_xcode/godot_ios/Images.xcassets/LaunchImage.launchimage/Default-480h@2x.png Binary files differindex 1299ceaee5..7c9cac3f0e 100644 --- a/misc/dist/ios_xcode/godot_ios/Images.xcassets/LaunchImage.launchimage/Default-480h@2x.png +++ b/misc/dist/ios_xcode/godot_ios/Images.xcassets/LaunchImage.launchimage/Default-480h@2x.png diff --git a/misc/dist/ios_xcode/godot_ios/Images.xcassets/LaunchImage.launchimage/Default-568h@2x.png b/misc/dist/ios_xcode/godot_ios/Images.xcassets/LaunchImage.launchimage/Default-568h@2x.png Binary files differindex 604a7ba701..0226bdf7cd 100644 --- a/misc/dist/ios_xcode/godot_ios/Images.xcassets/LaunchImage.launchimage/Default-568h@2x.png +++ b/misc/dist/ios_xcode/godot_ios/Images.xcassets/LaunchImage.launchimage/Default-568h@2x.png diff --git a/misc/dist/ios_xcode/godot_ios/Images.xcassets/LaunchImage.launchimage/Default-667h@2x.png b/misc/dist/ios_xcode/godot_ios/Images.xcassets/LaunchImage.launchimage/Default-667h@2x.png Binary files differindex bffb8c9fde..25904c186c 100644 --- a/misc/dist/ios_xcode/godot_ios/Images.xcassets/LaunchImage.launchimage/Default-667h@2x.png +++ b/misc/dist/ios_xcode/godot_ios/Images.xcassets/LaunchImage.launchimage/Default-667h@2x.png diff --git a/misc/dist/ios_xcode/godot_ios/Images.xcassets/LaunchImage.launchimage/Default-Landscape-736h@3x.png b/misc/dist/ios_xcode/godot_ios/Images.xcassets/LaunchImage.launchimage/Default-Landscape-736h@3x.png Binary files differindex 47826cd683..649df071f9 100644 --- a/misc/dist/ios_xcode/godot_ios/Images.xcassets/LaunchImage.launchimage/Default-Landscape-736h@3x.png +++ b/misc/dist/ios_xcode/godot_ios/Images.xcassets/LaunchImage.launchimage/Default-Landscape-736h@3x.png diff --git a/misc/dist/ios_xcode/godot_ios/Images.xcassets/LaunchImage.launchimage/Default-Landscape-X.png b/misc/dist/ios_xcode/godot_ios/Images.xcassets/LaunchImage.launchimage/Default-Landscape-X.png Binary files differindex 0f44a704b5..f3bd86a7de 100644 --- a/misc/dist/ios_xcode/godot_ios/Images.xcassets/LaunchImage.launchimage/Default-Landscape-X.png +++ b/misc/dist/ios_xcode/godot_ios/Images.xcassets/LaunchImage.launchimage/Default-Landscape-X.png diff --git a/misc/dist/ios_xcode/godot_ios/Images.xcassets/LaunchImage.launchimage/Default-Landscape.png b/misc/dist/ios_xcode/godot_ios/Images.xcassets/LaunchImage.launchimage/Default-Landscape.png Binary files differindex 07ab777bc2..d5692eaffa 100644 --- a/misc/dist/ios_xcode/godot_ios/Images.xcassets/LaunchImage.launchimage/Default-Landscape.png +++ b/misc/dist/ios_xcode/godot_ios/Images.xcassets/LaunchImage.launchimage/Default-Landscape.png diff --git a/misc/dist/ios_xcode/godot_ios/Images.xcassets/LaunchImage.launchimage/Default-Landscape@2x.png b/misc/dist/ios_xcode/godot_ios/Images.xcassets/LaunchImage.launchimage/Default-Landscape@2x.png Binary files differindex 774b9c5bbf..8c4fe87b9c 100644 --- a/misc/dist/ios_xcode/godot_ios/Images.xcassets/LaunchImage.launchimage/Default-Landscape@2x.png +++ b/misc/dist/ios_xcode/godot_ios/Images.xcassets/LaunchImage.launchimage/Default-Landscape@2x.png diff --git a/misc/dist/ios_xcode/godot_ios/Images.xcassets/LaunchImage.launchimage/Default-Portrait-736h@3x.png b/misc/dist/ios_xcode/godot_ios/Images.xcassets/LaunchImage.launchimage/Default-Portrait-736h@3x.png Binary files differindex fff36679c7..e755beb803 100644 --- a/misc/dist/ios_xcode/godot_ios/Images.xcassets/LaunchImage.launchimage/Default-Portrait-736h@3x.png +++ b/misc/dist/ios_xcode/godot_ios/Images.xcassets/LaunchImage.launchimage/Default-Portrait-736h@3x.png diff --git a/misc/dist/ios_xcode/godot_ios/Images.xcassets/LaunchImage.launchimage/Default-Portrait-X.png b/misc/dist/ios_xcode/godot_ios/Images.xcassets/LaunchImage.launchimage/Default-Portrait-X.png Binary files differindex 0804519faa..f676fda263 100644 --- a/misc/dist/ios_xcode/godot_ios/Images.xcassets/LaunchImage.launchimage/Default-Portrait-X.png +++ b/misc/dist/ios_xcode/godot_ios/Images.xcassets/LaunchImage.launchimage/Default-Portrait-X.png diff --git a/misc/dist/ios_xcode/godot_ios/Images.xcassets/LaunchImage.launchimage/Default-Portrait.png b/misc/dist/ios_xcode/godot_ios/Images.xcassets/LaunchImage.launchimage/Default-Portrait.png Binary files differindex 833142222c..43da4f3ed6 100644 --- a/misc/dist/ios_xcode/godot_ios/Images.xcassets/LaunchImage.launchimage/Default-Portrait.png +++ b/misc/dist/ios_xcode/godot_ios/Images.xcassets/LaunchImage.launchimage/Default-Portrait.png diff --git a/misc/dist/ios_xcode/godot_ios/Images.xcassets/LaunchImage.launchimage/Default-Portrait@2x.png b/misc/dist/ios_xcode/godot_ios/Images.xcassets/LaunchImage.launchimage/Default-Portrait@2x.png Binary files differindex 4c934c4a53..075a6790ce 100644 --- a/misc/dist/ios_xcode/godot_ios/Images.xcassets/LaunchImage.launchimage/Default-Portrait@2x.png +++ b/misc/dist/ios_xcode/godot_ios/Images.xcassets/LaunchImage.launchimage/Default-Portrait@2x.png diff --git a/modules/bullet/collision_object_bullet.h b/modules/bullet/collision_object_bullet.h index c9430bec18..04231b0814 100644 --- a/modules/bullet/collision_object_bullet.h +++ b/modules/bullet/collision_object_bullet.h @@ -167,14 +167,18 @@ public: _FORCE_INLINE_ const VSet<RID> &get_exceptions() const { return exceptions; } _FORCE_INLINE_ void set_collision_layer(uint32_t p_layer) { - collisionLayer = p_layer; - on_collision_filters_change(); + if (collisionLayer != p_layer) { + collisionLayer = p_layer; + on_collision_filters_change(); + } } _FORCE_INLINE_ uint32_t get_collision_layer() const { return collisionLayer; } _FORCE_INLINE_ void set_collision_mask(uint32_t p_mask) { - collisionMask = p_mask; - on_collision_filters_change(); + if (collisionMask != p_mask) { + collisionMask = p_mask; + on_collision_filters_change(); + } } _FORCE_INLINE_ uint32_t get_collision_mask() const { return collisionMask; } diff --git a/modules/bullet/rigid_body_bullet.cpp b/modules/bullet/rigid_body_bullet.cpp index 8d21b25b20..f29c4cb9ca 100644 --- a/modules/bullet/rigid_body_bullet.cpp +++ b/modules/bullet/rigid_body_bullet.cpp @@ -411,6 +411,8 @@ void RigidBodyBullet::on_collision_filters_change() { if (space) { space->reload_collision_filters(this); } + + set_activation_state(true); } void RigidBodyBullet::on_collision_checker_start() { @@ -471,7 +473,7 @@ void RigidBodyBullet::assert_no_constraints() { void RigidBodyBullet::set_activation_state(bool p_active) { if (p_active) { - btBody->setActivationState(ACTIVE_TAG); + btBody->activate(); } else { btBody->setActivationState(WANTS_DEACTIVATION); } diff --git a/modules/bullet/space_bullet.cpp b/modules/bullet/space_bullet.cpp index d2b16b0fd1..e74c29769f 100644 --- a/modules/bullet/space_bullet.cpp +++ b/modules/bullet/space_bullet.cpp @@ -42,6 +42,7 @@ #include "servers/physics_server.h" #include "soft_body_bullet.h" +#include <BulletCollision/BroadphaseCollision/btBroadphaseProxy.h> #include <BulletCollision/CollisionDispatch/btCollisionObject.h> #include <BulletCollision/CollisionDispatch/btGhostObject.h> #include <BulletCollision/NarrowPhaseCollision/btGjkEpaPenetrationDepthSolver.h> @@ -459,9 +460,13 @@ void SpaceBullet::remove_area(AreaBullet *p_area) { } void SpaceBullet::reload_collision_filters(AreaBullet *p_area) { - // This is necessary to change collision filter - dynamicsWorld->removeCollisionObject(p_area->get_bt_ghost()); - dynamicsWorld->addCollisionObject(p_area->get_bt_ghost(), p_area->get_collision_layer(), p_area->get_collision_mask()); + btGhostObject *ghost_object = p_area->get_bt_ghost(); + + btBroadphaseProxy *ghost_proxy = ghost_object->getBroadphaseHandle(); + ghost_proxy->m_collisionFilterGroup = p_area->get_collision_layer(); + ghost_proxy->m_collisionFilterMask = p_area->get_collision_mask(); + + dynamicsWorld->refreshBroadphaseProxy(ghost_object); } void SpaceBullet::add_rigid_body(RigidBodyBullet *p_body) { @@ -482,9 +487,13 @@ void SpaceBullet::remove_rigid_body(RigidBodyBullet *p_body) { } void SpaceBullet::reload_collision_filters(RigidBodyBullet *p_body) { - // This is necessary to change collision filter - remove_rigid_body(p_body); - add_rigid_body(p_body); + btRigidBody *rigid_body = p_body->get_bt_rigid_body(); + + btBroadphaseProxy *body_proxy = rigid_body->getBroadphaseProxy(); + body_proxy->m_collisionFilterGroup = p_body->get_collision_layer(); + body_proxy->m_collisionFilterMask = p_body->get_collision_mask(); + + dynamicsWorld->refreshBroadphaseProxy(rigid_body); } void SpaceBullet::add_soft_body(SoftBodyBullet *p_body) { diff --git a/modules/gdscript/gdscript_parser.cpp b/modules/gdscript/gdscript_parser.cpp index 21434cd150..282bb45c3f 100644 --- a/modules/gdscript/gdscript_parser.cpp +++ b/modules/gdscript/gdscript_parser.cpp @@ -2232,9 +2232,7 @@ void GDScriptParser::_parse_pattern_block(BlockNode *p_block, Vector<PatternBran break; // go back a level } - if (pending_newline != -1) { - pending_newline = -1; - } + pending_newline = -1; PatternBranchNode *branch = alloc_node<PatternBranchNode>(); branch->body = alloc_node<BlockNode>(); @@ -6111,12 +6109,18 @@ bool GDScriptParser::_is_type_compatible(const DataType &p_container, const Data break; } + // Some classes are prefixed with `_` internally + if (!ClassDB::class_exists(expr_native)) { + expr_native = "_" + expr_native; + } + switch (p_container.kind) { case DataType::NATIVE: { if (p_container.is_meta_type) { return ClassDB::is_parent_class(expr_native, GDScriptNativeClass::get_class_static()); } else { - return ClassDB::is_parent_class(expr_native, p_container.native_type); + StringName container_native = ClassDB::class_exists(p_container.native_type) ? p_container.native_type : StringName("_" + p_container.native_type); + return ClassDB::is_parent_class(expr_native, container_native); } } break; case DataType::SCRIPT: diff --git a/modules/gdscript/language_server/gdscript_extend_parser.cpp b/modules/gdscript/language_server/gdscript_extend_parser.cpp index 03d731a5f0..6b5c26ec81 100644 --- a/modules/gdscript/language_server/gdscript_extend_parser.cpp +++ b/modules/gdscript/language_server/gdscript_extend_parser.cpp @@ -298,7 +298,7 @@ void ExtendGDScriptParser::parse_function_symbol(const GDScriptParser::FunctionN const int line = LINE_NUMBER_TO_INDEX(p_func->line); r_symbol.range.start.line = line; r_symbol.range.start.character = p_func->column; - r_symbol.range.end.line = MAX(p_func->body->end_line - 2, p_func->body->line); + r_symbol.range.end.line = MAX(p_func->body->end_line - 2, r_symbol.range.start.line); r_symbol.range.end.character = lines[r_symbol.range.end.line].length(); r_symbol.selectionRange.start.line = r_symbol.range.start.line; r_symbol.documentation = parse_documentation(line); diff --git a/modules/gdscript/language_server/lsp.hpp b/modules/gdscript/language_server/lsp.hpp index cf360b5291..a048af88bb 100644 --- a/modules/gdscript/language_server/lsp.hpp +++ b/modules/gdscript/language_server/lsp.hpp @@ -496,7 +496,7 @@ struct TextDocumentSyncOptions { dict["willSave"] = willSave; dict["openClose"] = openClose; dict["change"] = change; - dict["change"] = save.to_json(); + dict["save"] = save.to_json(); return dict; } }; diff --git a/modules/mono/editor/GodotTools/GodotTools/BuildManager.cs b/modules/mono/editor/GodotTools/GodotTools/BuildManager.cs index 417032da54..ab37d89955 100644 --- a/modules/mono/editor/GodotTools/GodotTools/BuildManager.cs +++ b/modules/mono/editor/GodotTools/GodotTools/BuildManager.cs @@ -160,9 +160,16 @@ namespace GodotTools if (!File.Exists(GodotSharpDirs.ProjectSlnPath)) return true; // No solution to build - // Make sure to update the API assemblies if they happen to be missing. Just in - // case the user decided to delete them at some point after they were loaded. - Internal.UpdateApiAssembliesFromPrebuilt(); + // Make sure the API assemblies are up to date before building the project. + // We may not have had the chance to update the release API assemblies, and the debug ones + // may have been deleted by the user at some point after they were loaded by the Godot editor. + string apiAssembliesUpdateError = Internal.UpdateApiAssembliesFromPrebuilt(config == "Release" ? "Release" : "Debug"); + + if (!string.IsNullOrEmpty(apiAssembliesUpdateError)) + { + ShowBuildErrorDialog("Failed to update the Godot API assemblies"); + return false; + } var editorSettings = GodotSharpEditor.Instance.GetEditorInterface().GetEditorSettings(); var buildTool = (BuildTool) editorSettings.GetSetting("mono/builds/build_tool"); diff --git a/modules/mono/editor/GodotTools/GodotTools/GodotSharpEditor.cs b/modules/mono/editor/GodotTools/GodotTools/GodotSharpEditor.cs index 7da7cff933..12edd651df 100644 --- a/modules/mono/editor/GodotTools/GodotTools/GodotSharpEditor.cs +++ b/modules/mono/editor/GodotTools/GodotTools/GodotSharpEditor.cs @@ -34,7 +34,7 @@ namespace GodotTools private bool CreateProjectSolution() { - using (var pr = new EditorProgress("create_csharp_solution", "Generating solution...".TTR(), 2)) + using (var pr = new EditorProgress("create_csharp_solution", "Generating solution...".TTR(), 3)) { pr.Step("Generating C# project...".TTR()); @@ -73,9 +73,23 @@ namespace GodotTools return false; } - // Make sure to update the API assemblies if they happen to be missing. Just in - // case the user decided to delete them at some point after they were loaded. - Internal.UpdateApiAssembliesFromPrebuilt(); + pr.Step("Updating Godot API assemblies...".TTR()); + + string debugApiAssembliesError = Internal.UpdateApiAssembliesFromPrebuilt("Debug"); + + if (!string.IsNullOrEmpty(debugApiAssembliesError)) + { + ShowErrorDialog("Failed to update the Godot API assemblies: " + debugApiAssembliesError); + return false; + } + + string releaseApiAssembliesError = Internal.UpdateApiAssembliesFromPrebuilt("Release"); + + if (!string.IsNullOrEmpty(releaseApiAssembliesError)) + { + ShowErrorDialog("Failed to update the Godot API assemblies: " + releaseApiAssembliesError); + return false; + } pr.Step("Done".TTR()); diff --git a/modules/mono/editor/GodotTools/GodotTools/Ides/GodotIdeManager.cs b/modules/mono/editor/GodotTools/GodotTools/Ides/GodotIdeManager.cs index 9e24138143..01aa0d0ab1 100644 --- a/modules/mono/editor/GodotTools/GodotTools/Ides/GodotIdeManager.cs +++ b/modules/mono/editor/GodotTools/GodotTools/Ides/GodotIdeManager.cs @@ -40,8 +40,7 @@ namespace GodotTools.Ides protected ILogger Logger { - get => logger ?? (logger = new ConsoleLogger()); - set => logger = value; + get => logger ?? (logger = new GodotLogger()); } private void StartServer() diff --git a/modules/mono/editor/GodotTools/GodotTools/Internals/Internal.cs b/modules/mono/editor/GodotTools/GodotTools/Internals/Internal.cs index 7783576910..836c9c11e4 100644 --- a/modules/mono/editor/GodotTools/GodotTools/Internals/Internal.cs +++ b/modules/mono/editor/GodotTools/GodotTools/Internals/Internal.cs @@ -10,8 +10,8 @@ namespace GodotTools.Internals public const string CSharpLanguageType = "CSharpScript"; public const string CSharpLanguageExtension = "cs"; - public static string UpdateApiAssembliesFromPrebuilt() => - internal_UpdateApiAssembliesFromPrebuilt(); + public static string UpdateApiAssembliesFromPrebuilt(string config) => + internal_UpdateApiAssembliesFromPrebuilt(config); public static string FullTemplatesDir => internal_FullTemplatesDir(); @@ -55,7 +55,7 @@ namespace GodotTools.Internals // Internal Calls [MethodImpl(MethodImplOptions.InternalCall)] - private static extern string internal_UpdateApiAssembliesFromPrebuilt(); + private static extern string internal_UpdateApiAssembliesFromPrebuilt(string config); [MethodImpl(MethodImplOptions.InternalCall)] private static extern string internal_FullTemplatesDir(); diff --git a/modules/mono/editor/csharp_project.cpp b/modules/mono/editor/csharp_project.cpp index 0e6c58c9d7..748447005f 100644 --- a/modules/mono/editor/csharp_project.cpp +++ b/modules/mono/editor/csharp_project.cpp @@ -75,7 +75,7 @@ bool generate_api_solution(const String &p_solution_dir, const String &p_core_pr p_editor_proj_dir, p_editor_compile_items, GDMono::get_singleton()->get_tools_project_editor_assembly()); } else { - MonoDomain *temp_domain = GDMonoUtils::create_domain("GodotEngine.ApiSolutionGenerationDomain"); + MonoDomain *temp_domain = GDMonoUtils::create_domain("GodotEngine.Domain.ApiSolutionGeneration"); CRASH_COND(temp_domain == NULL); _GDMONO_SCOPE_EXIT_DOMAIN_UNLOAD_(temp_domain); diff --git a/modules/mono/editor/editor_internal_calls.cpp b/modules/mono/editor/editor_internal_calls.cpp index 5a84d9e3b8..1564d73c2a 100644 --- a/modules/mono/editor/editor_internal_calls.cpp +++ b/modules/mono/editor/editor_internal_calls.cpp @@ -230,31 +230,9 @@ uint32_t godot_icall_GodotSharpExport_GetExportedAssemblyDependencies(MonoString return GodotSharpExport::get_exported_assembly_dependencies(project_dll_name, project_dll_src_path, build_config, custom_lib_dir, dependencies); } -float godot_icall_Globals_EditorScale() { - return EDSCALE; -} - -MonoObject *godot_icall_Globals_GlobalDef(MonoString *p_setting, MonoObject *p_default_value, MonoBoolean p_restart_if_changed) { - String setting = GDMonoMarshal::mono_string_to_godot(p_setting); - Variant default_value = GDMonoMarshal::mono_object_to_variant(p_default_value); - Variant result = _GLOBAL_DEF(setting, default_value, (bool)p_restart_if_changed); - return GDMonoMarshal::variant_to_mono_object(result); -} - -MonoObject *godot_icall_Globals_EditorDef(MonoString *p_setting, MonoObject *p_default_value, MonoBoolean p_restart_if_changed) { - String setting = GDMonoMarshal::mono_string_to_godot(p_setting); - Variant default_value = GDMonoMarshal::mono_object_to_variant(p_default_value); - Variant result = _EDITOR_DEF(setting, default_value, (bool)p_restart_if_changed); - return GDMonoMarshal::variant_to_mono_object(result); -} - -MonoString *godot_icall_Globals_TTR(MonoString *p_text) { - String text = GDMonoMarshal::mono_string_to_godot(p_text); - return GDMonoMarshal::mono_string_from_godot(TTR(text)); -} - -MonoString *godot_icall_Internal_UpdateApiAssembliesFromPrebuilt() { - String error_str = GDMono::get_singleton()->update_api_assemblies_from_prebuilt(); +MonoString *godot_icall_Internal_UpdateApiAssembliesFromPrebuilt(MonoString *p_config) { + String config = GDMonoMarshal::mono_string_to_godot(p_config); + String error_str = GDMono::get_singleton()->update_api_assemblies_from_prebuilt(config); return GDMonoMarshal::mono_string_from_godot(error_str); } @@ -365,6 +343,29 @@ void godot_icall_Internal_ScriptEditorDebugger_ReloadScripts() { } } +float godot_icall_Globals_EditorScale() { + return EDSCALE; +} + +MonoObject *godot_icall_Globals_GlobalDef(MonoString *p_setting, MonoObject *p_default_value, MonoBoolean p_restart_if_changed) { + String setting = GDMonoMarshal::mono_string_to_godot(p_setting); + Variant default_value = GDMonoMarshal::mono_object_to_variant(p_default_value); + Variant result = _GLOBAL_DEF(setting, default_value, (bool)p_restart_if_changed); + return GDMonoMarshal::variant_to_mono_object(result); +} + +MonoObject *godot_icall_Globals_EditorDef(MonoString *p_setting, MonoObject *p_default_value, MonoBoolean p_restart_if_changed) { + String setting = GDMonoMarshal::mono_string_to_godot(p_setting); + Variant default_value = GDMonoMarshal::mono_object_to_variant(p_default_value); + Variant result = _EDITOR_DEF(setting, default_value, (bool)p_restart_if_changed); + return GDMonoMarshal::variant_to_mono_object(result); +} + +MonoString *godot_icall_Globals_TTR(MonoString *p_text) { + String text = GDMonoMarshal::mono_string_to_godot(p_text); + return GDMonoMarshal::mono_string_from_godot(TTR(text)); +} + MonoString *godot_icall_Utils_OS_GetPlatformName() { String os_name = OS::get_singleton()->get_name(); return GDMonoMarshal::mono_string_from_godot(os_name); diff --git a/modules/mono/editor/godotsharp_export.cpp b/modules/mono/editor/godotsharp_export.cpp index 80a7335b1d..e83152d668 100644 --- a/modules/mono/editor/godotsharp_export.cpp +++ b/modules/mono/editor/godotsharp_export.cpp @@ -32,9 +32,13 @@ #include <mono/metadata/image.h> +#include "core/os/os.h" + #include "../mono_gd/gd_mono.h" #include "../mono_gd/gd_mono_assembly.h" +namespace GodotSharpExport { + String get_assemblyref_name(MonoImage *p_image, int index) { const MonoTableInfo *table_info = mono_image_get_table_info(p_image, MONO_TABLE_ASSEMBLYREF); @@ -45,7 +49,7 @@ String get_assemblyref_name(MonoImage *p_image, int index) { return String::utf8(mono_metadata_string_heap(p_image, cols[MONO_ASSEMBLYREF_NAME])); } -Error GodotSharpExport::get_assembly_dependencies(GDMonoAssembly *p_assembly, const Vector<String> &p_search_dirs, Dictionary &r_dependencies) { +Error get_assembly_dependencies(GDMonoAssembly *p_assembly, const Vector<String> &p_search_dirs, Dictionary &r_dependencies) { MonoImage *image = p_assembly->get_image(); for (int i = 0; i < mono_image_get_table_rows(image, MONO_TABLE_ASSEMBLYREF); i++) { @@ -96,8 +100,8 @@ Error GodotSharpExport::get_assembly_dependencies(GDMonoAssembly *p_assembly, co return OK; } -Error GodotSharpExport::get_exported_assembly_dependencies(const String &p_project_dll_name, const String &p_project_dll_src_path, const String &p_build_config, const String &p_custom_lib_dir, Dictionary &r_dependencies) { - MonoDomain *export_domain = GDMonoUtils::create_domain("GodotEngine.ProjectExportDomain"); +Error get_exported_assembly_dependencies(const String &p_project_dll_name, const String &p_project_dll_src_path, const String &p_build_config, const String &p_custom_bcl_dir, Dictionary &r_dependencies) { + MonoDomain *export_domain = GDMonoUtils::create_domain("GodotEngine.Domain.ProjectExport"); ERR_FAIL_NULL_V(export_domain, FAILED); _GDMONO_SCOPE_EXIT_DOMAIN_UNLOAD_(export_domain); @@ -110,7 +114,9 @@ Error GodotSharpExport::get_exported_assembly_dependencies(const String &p_proje ERR_FAIL_COND_V_MSG(!load_success, ERR_CANT_RESOLVE, "Cannot load assembly (refonly): '" + p_project_dll_name + "'."); Vector<String> search_dirs; - GDMonoAssembly::fill_search_dirs(search_dirs, p_build_config, p_custom_lib_dir); + GDMonoAssembly::fill_search_dirs(search_dirs, p_build_config, p_custom_bcl_dir); return get_assembly_dependencies(scripts_assembly, search_dirs, r_dependencies); } + +} // namespace GodotSharpExport diff --git a/modules/mono/editor/godotsharp_export.h b/modules/mono/editor/godotsharp_export.h index 8d121a6bc3..58e46e2f2d 100644 --- a/modules/mono/editor/godotsharp_export.h +++ b/modules/mono/editor/godotsharp_export.h @@ -39,10 +39,11 @@ namespace GodotSharpExport { +Error get_assembly_dependencies(GDMonoAssembly *p_assembly, const Vector<String> &p_search_dirs, Dictionary &r_dependencies); + Error get_exported_assembly_dependencies(const String &p_project_dll_name, const String &p_project_dll_src_path, const String &p_build_config, const String &p_custom_lib_dir, Dictionary &r_dependencies); -Error get_assembly_dependencies(GDMonoAssembly *p_assembly, const Vector<String> &p_search_dirs, Dictionary &r_dependencies); } // namespace GodotSharpExport diff --git a/modules/mono/godotsharp_dirs.cpp b/modules/mono/godotsharp_dirs.cpp index 4b2525c692..5fa8aed5a9 100644 --- a/modules/mono/godotsharp_dirs.cpp +++ b/modules/mono/godotsharp_dirs.cpp @@ -43,6 +43,8 @@ #include "utils/android_utils.h" #endif +#include "mono_gd/gd_mono.h" + namespace GodotSharpDirs { String _get_expected_build_config() { @@ -59,20 +61,6 @@ String _get_expected_build_config() { #endif } -String _get_expected_api_build_config() { -#ifdef TOOLS_ENABLED - return "Debug"; -#else - -#ifdef DEBUG_ENABLED - return "Debug"; -#else - return "Release"; -#endif - -#endif -} - String _get_mono_user_dir() { #ifdef TOOLS_ENABLED if (EditorSettings::get_singleton()) { @@ -134,7 +122,7 @@ private: res_data_dir = "res://.mono"; res_metadata_dir = res_data_dir.plus_file("metadata"); res_assemblies_base_dir = res_data_dir.plus_file("assemblies"); - res_assemblies_dir = res_assemblies_base_dir.plus_file(_get_expected_api_build_config()); + res_assemblies_dir = res_assemblies_base_dir.plus_file(GDMono::get_expected_api_build_config()); res_config_dir = res_data_dir.plus_file("etc").plus_file("mono"); // TODO use paths from csproj diff --git a/modules/mono/mono_gd/gd_mono.cpp b/modules/mono/mono_gd/gd_mono.cpp index 544bfc4615..504b8d41d0 100644 --- a/modules/mono/mono_gd/gd_mono.cpp +++ b/modules/mono/mono_gd/gd_mono.cpp @@ -381,10 +381,10 @@ void GDMono::initialize_load_assemblies() { } bool GDMono::_are_api_assemblies_out_of_sync() { - bool out_of_sync = core_api_assembly && (core_api_assembly_out_of_sync || !GDMonoUtils::mono_cache.godot_api_cache_updated); + bool out_of_sync = core_api_assembly.assembly && (core_api_assembly.out_of_sync || !GDMonoUtils::mono_cache.godot_api_cache_updated); #ifdef TOOLS_ENABLED if (!out_of_sync) - out_of_sync = editor_api_assembly && editor_api_assembly_out_of_sync; + out_of_sync = editor_api_assembly.assembly && editor_api_assembly.out_of_sync; #endif return out_of_sync; } @@ -523,10 +523,10 @@ bool GDMono::load_assembly_from(const String &p_name, const String &p_path, GDMo return true; } -APIAssembly::Version APIAssembly::Version::get_from_loaded_assembly(GDMonoAssembly *p_api_assembly, APIAssembly::Type p_api_type) { - APIAssembly::Version api_assembly_version; +ApiAssemblyInfo::Version ApiAssemblyInfo::Version::get_from_loaded_assembly(GDMonoAssembly *p_api_assembly, ApiAssemblyInfo::Type p_api_type) { + ApiAssemblyInfo::Version api_assembly_version; - const char *nativecalls_name = p_api_type == APIAssembly::API_CORE ? + const char *nativecalls_name = p_api_type == ApiAssemblyInfo::API_CORE ? BINDINGS_CLASS_NATIVECALLS : BINDINGS_CLASS_NATIVECALLS_EDITOR; @@ -549,8 +549,8 @@ APIAssembly::Version APIAssembly::Version::get_from_loaded_assembly(GDMonoAssemb return api_assembly_version; } -String APIAssembly::to_string(APIAssembly::Type p_type) { - return p_type == APIAssembly::API_CORE ? "API_CORE" : "API_EDITOR"; +String ApiAssemblyInfo::to_string(ApiAssemblyInfo::Type p_type) { + return p_type == ApiAssemblyInfo::API_CORE ? "API_CORE" : "API_EDITOR"; } bool GDMono::_load_corlib_assembly() { @@ -567,16 +567,12 @@ bool GDMono::_load_corlib_assembly() { } #ifdef TOOLS_ENABLED -bool GDMono::copy_prebuilt_api_assembly(APIAssembly::Type p_api_type, const String &p_config) { - - bool &api_assembly_out_of_sync = (p_api_type == APIAssembly::API_CORE) ? - GDMono::get_singleton()->core_api_assembly_out_of_sync : - GDMono::get_singleton()->editor_api_assembly_out_of_sync; +bool GDMono::copy_prebuilt_api_assembly(ApiAssemblyInfo::Type p_api_type, const String &p_config) { String src_dir = GodotSharpDirs::get_data_editor_prebuilt_api_dir().plus_file(p_config); String dst_dir = GodotSharpDirs::get_res_assemblies_base_dir().plus_file(p_config); - String assembly_name = p_api_type == APIAssembly::API_CORE ? CORE_API_ASSEMBLY_NAME : EDITOR_API_ASSEMBLY_NAME; + String assembly_name = p_api_type == ApiAssemblyInfo::API_CORE ? CORE_API_ASSEMBLY_NAME : EDITOR_API_ASSEMBLY_NAME; // Create destination directory if needed if (!DirAccess::exists(dst_dir)) { @@ -590,35 +586,102 @@ bool GDMono::copy_prebuilt_api_assembly(APIAssembly::Type p_api_type, const Stri } } + DirAccessRef da = DirAccess::create(DirAccess::ACCESS_FILESYSTEM); + + String xml_file = assembly_name + ".xml"; + if (da->copy(src_dir.plus_file(xml_file), dst_dir.plus_file(xml_file)) != OK) + WARN_PRINTS("Failed to copy '" + xml_file + "'."); + + String pdb_file = assembly_name + ".pdb"; + if (da->copy(src_dir.plus_file(pdb_file), dst_dir.plus_file(pdb_file)) != OK) + WARN_PRINTS("Failed to copy '" + pdb_file + "'."); + String assembly_file = assembly_name + ".dll"; - String assembly_src = src_dir.plus_file(assembly_file); - String assembly_dst = dst_dir.plus_file(assembly_file); + if (da->copy(src_dir.plus_file(assembly_file), dst_dir.plus_file(assembly_file)) != OK) { + ERR_PRINTS("Failed to copy '" + assembly_file + "'."); + return false; + } + + return true; +} - if (!FileAccess::exists(assembly_dst) || api_assembly_out_of_sync) { - DirAccessRef da = DirAccess::create(DirAccess::ACCESS_FILESYSTEM); +static bool try_get_cached_api_hash_for(const String &p_api_assemblies_dir, bool &r_out_of_sync) { + String core_api_assembly_path = p_api_assemblies_dir.plus_file(CORE_API_ASSEMBLY_NAME ".dll"); + String editor_api_assembly_path = p_api_assemblies_dir.plus_file(EDITOR_API_ASSEMBLY_NAME ".dll"); - String xml_file = assembly_name + ".xml"; - if (da->copy(src_dir.plus_file(xml_file), dst_dir.plus_file(xml_file)) != OK) - WARN_PRINTS("Failed to copy '" + xml_file + "'."); + if (!FileAccess::exists(core_api_assembly_path) || !FileAccess::exists(editor_api_assembly_path)) + return false; - String pdb_file = assembly_name + ".pdb"; - if (da->copy(src_dir.plus_file(pdb_file), dst_dir.plus_file(pdb_file)) != OK) - WARN_PRINTS("Failed to copy '" + pdb_file + "'."); + String cached_api_hash_path = p_api_assemblies_dir.plus_file("api_hash_cache.cfg"); - Error err = da->copy(assembly_src, assembly_dst); + if (!FileAccess::exists(cached_api_hash_path)) + return false; - if (err != OK) { - ERR_PRINTS("Failed to copy '" + assembly_file + "'."); - return false; - } + Ref<ConfigFile> cfg; + cfg.instance(); + Error cfg_err = cfg->load(cached_api_hash_path); + ERR_FAIL_COND_V(cfg_err != OK, false); - api_assembly_out_of_sync = false; + // Checking the modified time is good enough + if (FileAccess::get_modified_time(core_api_assembly_path) != (uint64_t)cfg->get_value("core", "modified_time") || + FileAccess::get_modified_time(editor_api_assembly_path) != (uint64_t)cfg->get_value("editor", "modified_time")) { + return false; } + r_out_of_sync = GodotSharpBindings::get_bindings_version() != (uint32_t)cfg->get_value("core", "bindings_version") || + GodotSharpBindings::get_cs_glue_version() != (uint32_t)cfg->get_value("core", "cs_glue_version") || + GodotSharpBindings::get_bindings_version() != (uint32_t)cfg->get_value("editor", "bindings_version") || + GodotSharpBindings::get_cs_glue_version() != (uint32_t)cfg->get_value("editor", "cs_glue_version") || + GodotSharpBindings::get_core_api_hash() != (uint64_t)cfg->get_value("core", "api_hash") || + GodotSharpBindings::get_editor_api_hash() != (uint64_t)cfg->get_value("editor", "api_hash"); + return true; } -String GDMono::update_api_assemblies_from_prebuilt() { +static void create_cached_api_hash_for(const String &p_api_assemblies_dir) { + + String core_api_assembly_path = p_api_assemblies_dir.plus_file(CORE_API_ASSEMBLY_NAME ".dll"); + String editor_api_assembly_path = p_api_assemblies_dir.plus_file(EDITOR_API_ASSEMBLY_NAME ".dll"); + String cached_api_hash_path = p_api_assemblies_dir.plus_file("api_hash_cache.cfg"); + + Ref<ConfigFile> cfg; + cfg.instance(); + + cfg->set_value("core", "modified_time", FileAccess::get_modified_time(core_api_assembly_path)); + cfg->set_value("editor", "modified_time", FileAccess::get_modified_time(editor_api_assembly_path)); + + cfg->set_value("core", "bindings_version", GodotSharpBindings::get_bindings_version()); + cfg->set_value("core", "cs_glue_version", GodotSharpBindings::get_cs_glue_version()); + cfg->set_value("editor", "bindings_version", GodotSharpBindings::get_bindings_version()); + cfg->set_value("editor", "cs_glue_version", GodotSharpBindings::get_cs_glue_version()); + + // This assumes the prebuilt api assemblies we copied to the project are not out of sync + cfg->set_value("core", "api_hash", GodotSharpBindings::get_core_api_hash()); + cfg->set_value("editor", "api_hash", GodotSharpBindings::get_editor_api_hash()); + + Error err = cfg->save(cached_api_hash_path); + ERR_FAIL_COND(err != OK); +} + +bool GDMono::_temp_domain_load_are_assemblies_out_of_sync(const String &p_config) { + MonoDomain *temp_domain = GDMonoUtils::create_domain("GodotEngine.Domain.CheckApiAssemblies"); + ERR_FAIL_NULL_V(temp_domain, "Failed to create temporary domain to check API assemblies"); + _GDMONO_SCOPE_EXIT_DOMAIN_UNLOAD_(temp_domain); + + _GDMONO_SCOPE_DOMAIN_(temp_domain); + + GDMono::LoadedApiAssembly temp_core_api_assembly; + GDMono::LoadedApiAssembly temp_editor_api_assembly; + + if (!_try_load_api_assemblies(temp_core_api_assembly, temp_editor_api_assembly, + p_config, /* refonly: */ true, /* loaded_callback: */ NULL)) { + return temp_core_api_assembly.out_of_sync || temp_editor_api_assembly.out_of_sync; + } + + return true; // Failed to load, assume they're outdated assemblies +} + +String GDMono::update_api_assemblies_from_prebuilt(const String &p_config, const bool *p_core_api_out_of_sync, const bool *p_editor_api_out_of_sync) { #define FAIL_REASON(m_out_of_sync, m_prebuilt_exists) \ ( \ @@ -629,46 +692,55 @@ String GDMono::update_api_assemblies_from_prebuilt() { String("and the prebuilt assemblies are missing.") : \ String("and we failed to copy the prebuilt assemblies."))) - bool api_assembly_out_of_sync = core_api_assembly_out_of_sync || editor_api_assembly_out_of_sync; + String dst_assemblies_dir = GodotSharpDirs::get_res_assemblies_base_dir().plus_file(p_config); - String core_assembly_path = GodotSharpDirs::get_res_assemblies_dir().plus_file(CORE_API_ASSEMBLY_NAME ".dll"); - String editor_assembly_path = GodotSharpDirs::get_res_assemblies_dir().plus_file(EDITOR_API_ASSEMBLY_NAME ".dll"); + String core_assembly_path = dst_assemblies_dir.plus_file(CORE_API_ASSEMBLY_NAME ".dll"); + String editor_assembly_path = dst_assemblies_dir.plus_file(EDITOR_API_ASSEMBLY_NAME ".dll"); - if (!api_assembly_out_of_sync && FileAccess::exists(core_assembly_path) && FileAccess::exists(editor_assembly_path)) - return String(); // No update needed + bool api_assemblies_out_of_sync = false; + + if (p_core_api_out_of_sync && p_editor_api_out_of_sync) { + api_assemblies_out_of_sync = p_core_api_out_of_sync || p_editor_api_out_of_sync; + } else if (FileAccess::exists(core_assembly_path) && FileAccess::exists(editor_assembly_path)) { + // Determine if they're out of sync + if (!try_get_cached_api_hash_for(dst_assemblies_dir, api_assemblies_out_of_sync)) { + api_assemblies_out_of_sync = _temp_domain_load_are_assemblies_out_of_sync(p_config); + } + } - const int CONFIGS_LEN = 2; - String configs[CONFIGS_LEN] = { String("Debug"), String("Release") }; + // Note: Even if only one of the assemblies if missing or out of sync, we update both - for (int i = 0; i < CONFIGS_LEN; i++) { - String config = configs[i]; + if (!api_assemblies_out_of_sync && FileAccess::exists(core_assembly_path) && FileAccess::exists(editor_assembly_path)) + return String(); // No update needed - print_verbose("Updating '" + config + "' API assemblies"); + print_verbose("Updating '" + p_config + "' API assemblies"); - String prebuilt_api_dir = GodotSharpDirs::get_data_editor_prebuilt_api_dir().plus_file(config); - String prebuilt_core_dll_path = prebuilt_api_dir.plus_file(CORE_API_ASSEMBLY_NAME ".dll"); - String prebuilt_editor_dll_path = prebuilt_api_dir.plus_file(EDITOR_API_ASSEMBLY_NAME ".dll"); + String prebuilt_api_dir = GodotSharpDirs::get_data_editor_prebuilt_api_dir().plus_file(p_config); + String prebuilt_core_dll_path = prebuilt_api_dir.plus_file(CORE_API_ASSEMBLY_NAME ".dll"); + String prebuilt_editor_dll_path = prebuilt_api_dir.plus_file(EDITOR_API_ASSEMBLY_NAME ".dll"); - if (!FileAccess::exists(prebuilt_core_dll_path) || !FileAccess::exists(prebuilt_editor_dll_path)) { - return FAIL_REASON(api_assembly_out_of_sync, /* prebuilt_exists: */ false); - } + if (!FileAccess::exists(prebuilt_core_dll_path) || !FileAccess::exists(prebuilt_editor_dll_path)) { + return FAIL_REASON(api_assemblies_out_of_sync, /* prebuilt_exists: */ false); + } - // Copy the prebuilt Api - if (!copy_prebuilt_api_assembly(APIAssembly::API_CORE, config) || - !copy_prebuilt_api_assembly(APIAssembly::API_EDITOR, config)) { - return FAIL_REASON(api_assembly_out_of_sync, /* prebuilt_exists: */ true); - } + // Copy the prebuilt Api + if (!copy_prebuilt_api_assembly(ApiAssemblyInfo::API_CORE, p_config) || + !copy_prebuilt_api_assembly(ApiAssemblyInfo::API_EDITOR, p_config)) { + return FAIL_REASON(api_assemblies_out_of_sync, /* prebuilt_exists: */ true); } + // Cache the api hash of the assemblies we just copied + create_cached_api_hash_for(dst_assemblies_dir); + return String(); // Updated successfully #undef FAIL_REASON } #endif -bool GDMono::_load_core_api_assembly() { +bool GDMono::_load_core_api_assembly(LoadedApiAssembly &r_loaded_api_assembly, const String &p_config, bool p_refonly) { - if (core_api_assembly) + if (r_loaded_api_assembly.assembly) return true; #ifdef TOOLS_ENABLED @@ -676,101 +748,115 @@ bool GDMono::_load_core_api_assembly() { // If running the project manager, load it from the prebuilt API directory String assembly_dir = !Main::is_project_manager() ? - GodotSharpDirs::get_res_assemblies_dir() : - GodotSharpDirs::get_data_editor_prebuilt_api_dir().plus_file("Debug"); + GodotSharpDirs::get_res_assemblies_base_dir().plus_file(p_config) : + GodotSharpDirs::get_data_editor_prebuilt_api_dir().plus_file(p_config); String assembly_path = assembly_dir.plus_file(CORE_API_ASSEMBLY_NAME ".dll"); bool success = FileAccess::exists(assembly_path) && - load_assembly_from(CORE_API_ASSEMBLY_NAME, assembly_path, &core_api_assembly); + load_assembly_from(CORE_API_ASSEMBLY_NAME, assembly_path, &r_loaded_api_assembly.assembly, p_refonly); #else - bool success = load_assembly(CORE_API_ASSEMBLY_NAME, &core_api_assembly); + bool success = load_assembly(CORE_API_ASSEMBLY_NAME, &r_loaded_api_assembly.assembly, p_refonly); #endif if (success) { - APIAssembly::Version api_assembly_ver = APIAssembly::Version::get_from_loaded_assembly(core_api_assembly, APIAssembly::API_CORE); - core_api_assembly_out_of_sync = GodotSharpBindings::get_core_api_hash() != api_assembly_ver.godot_api_hash || - GodotSharpBindings::get_bindings_version() != api_assembly_ver.bindings_version || - GodotSharpBindings::get_cs_glue_version() != api_assembly_ver.cs_glue_version; - if (!core_api_assembly_out_of_sync) { - GDMonoUtils::update_godot_api_cache(); - - _install_trace_listener(); - } + ApiAssemblyInfo::Version api_assembly_ver = ApiAssemblyInfo::Version::get_from_loaded_assembly(r_loaded_api_assembly.assembly, ApiAssemblyInfo::API_CORE); + r_loaded_api_assembly.out_of_sync = GodotSharpBindings::get_core_api_hash() != api_assembly_ver.godot_api_hash || + GodotSharpBindings::get_bindings_version() != api_assembly_ver.bindings_version || + GodotSharpBindings::get_cs_glue_version() != api_assembly_ver.cs_glue_version; } else { - core_api_assembly_out_of_sync = false; + r_loaded_api_assembly.out_of_sync = false; } return success; } #ifdef TOOLS_ENABLED -bool GDMono::_load_editor_api_assembly() { +bool GDMono::_load_editor_api_assembly(LoadedApiAssembly &r_loaded_api_assembly, const String &p_config, bool p_refonly) { - if (editor_api_assembly) + if (r_loaded_api_assembly.assembly) return true; // For the editor and the editor player we want to load it from a specific path to make sure we can keep it up to date // If running the project manager, load it from the prebuilt API directory String assembly_dir = !Main::is_project_manager() ? - GodotSharpDirs::get_res_assemblies_dir() : - GodotSharpDirs::get_data_editor_prebuilt_api_dir().plus_file("Debug"); + GodotSharpDirs::get_res_assemblies_base_dir().plus_file(p_config) : + GodotSharpDirs::get_data_editor_prebuilt_api_dir().plus_file(p_config); String assembly_path = assembly_dir.plus_file(EDITOR_API_ASSEMBLY_NAME ".dll"); bool success = FileAccess::exists(assembly_path) && - load_assembly_from(EDITOR_API_ASSEMBLY_NAME, assembly_path, &editor_api_assembly); + load_assembly_from(EDITOR_API_ASSEMBLY_NAME, assembly_path, &r_loaded_api_assembly.assembly, p_refonly); if (success) { - APIAssembly::Version api_assembly_ver = APIAssembly::Version::get_from_loaded_assembly(editor_api_assembly, APIAssembly::API_EDITOR); - editor_api_assembly_out_of_sync = GodotSharpBindings::get_editor_api_hash() != api_assembly_ver.godot_api_hash || - GodotSharpBindings::get_bindings_version() != api_assembly_ver.bindings_version || - GodotSharpBindings::get_cs_glue_version() != api_assembly_ver.cs_glue_version; + ApiAssemblyInfo::Version api_assembly_ver = ApiAssemblyInfo::Version::get_from_loaded_assembly(r_loaded_api_assembly.assembly, ApiAssemblyInfo::API_EDITOR); + r_loaded_api_assembly.out_of_sync = GodotSharpBindings::get_editor_api_hash() != api_assembly_ver.godot_api_hash || + GodotSharpBindings::get_bindings_version() != api_assembly_ver.bindings_version || + GodotSharpBindings::get_cs_glue_version() != api_assembly_ver.cs_glue_version; } else { - editor_api_assembly_out_of_sync = false; + r_loaded_api_assembly.out_of_sync = false; } return success; } #endif -bool GDMono::_try_load_api_assemblies() { - - if (!_load_core_api_assembly()) { +bool GDMono::_try_load_api_assemblies(LoadedApiAssembly &r_core_api_assembly, LoadedApiAssembly &r_editor_api_assembly, + const String &p_config, bool p_refonly, CoreApiAssemblyLoadedCallback p_callback) { + if (!_load_core_api_assembly(r_core_api_assembly, p_config, p_refonly)) { if (OS::get_singleton()->is_stdout_verbose()) print_error("Mono: Failed to load Core API assembly"); return false; } #ifdef TOOLS_ENABLED - if (!_load_editor_api_assembly()) { + if (!_load_editor_api_assembly(r_editor_api_assembly, p_config, p_refonly)) { if (OS::get_singleton()->is_stdout_verbose()) print_error("Mono: Failed to load Editor API assembly"); return false; } - if (editor_api_assembly_out_of_sync) + if (r_editor_api_assembly.out_of_sync) return false; #endif // Check if the core API assembly is out of sync only after trying to load the // editor API assembly. Otherwise, if both assemblies are out of sync, we would // only update the former as we won't know the latter also needs to be updated. - if (core_api_assembly_out_of_sync || !GDMonoUtils::mono_cache.godot_api_cache_updated) + if (r_core_api_assembly.out_of_sync) + return false; + + if (p_callback) + return p_callback(); + + return true; +} + +bool GDMono::_on_core_api_assembly_loaded() { + GDMonoUtils::update_godot_api_cache(); + + if (!GDMonoUtils::mono_cache.godot_api_cache_updated) return false; + get_singleton()->_install_trace_listener(); + return true; } +bool GDMono::_try_load_api_assemblies_preset() { + return _try_load_api_assemblies(core_api_assembly, editor_api_assembly, + get_expected_api_build_config(), /* refonly: */ false, _on_core_api_assembly_loaded); +} + void GDMono::_load_api_assemblies() { - bool api_assemblies_loaded = _try_load_api_assemblies(); + bool api_assemblies_loaded = _try_load_api_assemblies_preset(); if (!api_assemblies_loaded) { #ifdef TOOLS_ENABLED - // The API assemblies are out of sync. Fine, try one more time, but this time - // update them from the prebuilt assemblies directory before trying to load them. + // The API assemblies are out of sync or some other error happened. Fine, try one more time, but + // this time update them from the prebuilt assemblies directory before trying to load them again. // Shouldn't happen. The project manager loads the prebuilt API assemblies CRASH_COND_MSG(Main::is_project_manager(), "Failed to load one of the prebuilt API assemblies."); @@ -780,7 +866,7 @@ void GDMono::_load_api_assemblies() { CRASH_COND_MSG(domain_unload_err != OK, "Mono: Failed to unload scripts domain."); // 2. Update the API assemblies - String update_error = update_api_assemblies_from_prebuilt(); + String update_error = update_api_assemblies_from_prebuilt("Debug", &core_api_assembly.out_of_sync, &editor_api_assembly.out_of_sync); CRASH_COND_MSG(!update_error.empty(), update_error); // 3. Load the scripts domain again @@ -788,7 +874,7 @@ void GDMono::_load_api_assemblies() { CRASH_COND_MSG(domain_load_err != OK, "Mono: Failed to load scripts domain."); // 4. Try loading the updated assemblies - api_assemblies_loaded = _try_load_api_assemblies(); + api_assemblies_loaded = _try_load_api_assemblies_preset(); #endif } @@ -796,14 +882,14 @@ void GDMono::_load_api_assemblies() { // welp... too bad if (_are_api_assemblies_out_of_sync()) { - if (core_api_assembly_out_of_sync) { + if (core_api_assembly.out_of_sync) { ERR_PRINT("The assembly '" CORE_API_ASSEMBLY_NAME "' is out of sync."); } else if (!GDMonoUtils::mono_cache.godot_api_cache_updated) { ERR_PRINT("The loaded assembly '" CORE_API_ASSEMBLY_NAME "' is in sync, but the cache update failed."); } #ifdef TOOLS_ENABLED - if (editor_api_assembly_out_of_sync) { + if (editor_api_assembly.out_of_sync) { ERR_PRINT("The assembly '" EDITOR_API_ASSEMBLY_NAME "' is out of sync."); } #endif @@ -852,15 +938,14 @@ void GDMono::_install_trace_listener() { #ifdef DEBUG_ENABLED // Install the trace listener now before the project assembly is loaded - typedef void (*DebuggingUtils_InstallTraceListener)(MonoObject **); + GDMonoClass *debug_utils = get_core_api_assembly()->get_class(BINDINGS_NAMESPACE, "DebuggingUtils"); + GDMonoMethod *install_func = debug_utils->get_method("InstallTraceListener"); + MonoException *exc = NULL; - GDMonoClass *debug_utils = core_api_assembly->get_class(BINDINGS_NAMESPACE, "DebuggingUtils"); - DebuggingUtils_InstallTraceListener install_func = - (DebuggingUtils_InstallTraceListener)debug_utils->get_method_thunk("InstallTraceListener"); - install_func((MonoObject **)&exc); + install_func->invoke_raw(NULL, NULL, &exc); if (exc) { - ERR_PRINT("Failed to install 'System.Diagnostics.Trace' listener."); GDMonoUtils::debug_print_unhandled_exception(exc); + ERR_PRINT("Failed to install 'System.Diagnostics.Trace' listener."); } #endif } @@ -871,7 +956,7 @@ Error GDMono::_load_scripts_domain() { print_verbose("Mono: Loading scripts domain..."); - scripts_domain = GDMonoUtils::create_domain("GodotEngine.ScriptsDomain"); + scripts_domain = GDMonoUtils::create_domain("GodotEngine.Domain.Scripts"); ERR_FAIL_NULL_V_MSG(scripts_domain, ERR_CANT_CREATE, "Mono: Could not create scripts app domain."); @@ -903,10 +988,13 @@ Error GDMono::_unload_scripts_domain() { _domain_assemblies_cleanup(mono_domain_get_id(scripts_domain)); - core_api_assembly = NULL; + core_api_assembly.assembly = NULL; +#ifdef TOOLS_ENABLED + editor_api_assembly.assembly = NULL; +#endif + project_assembly = NULL; #ifdef TOOLS_ENABLED - editor_api_assembly = NULL; tools_assembly = NULL; tools_project_editor_assembly = NULL; #endif @@ -1076,16 +1164,9 @@ GDMono::GDMono() { root_domain = NULL; scripts_domain = NULL; - core_api_assembly_out_of_sync = false; -#ifdef TOOLS_ENABLED - editor_api_assembly_out_of_sync = false; -#endif - corlib_assembly = NULL; - core_api_assembly = NULL; project_assembly = NULL; #ifdef TOOLS_ENABLED - editor_api_assembly = NULL; tools_assembly = NULL; tools_project_editor_assembly = NULL; #endif diff --git a/modules/mono/mono_gd/gd_mono.h b/modules/mono/mono_gd/gd_mono.h index 343d68bc2d..e14a0d8409 100644 --- a/modules/mono/mono_gd/gd_mono.h +++ b/modules/mono/mono_gd/gd_mono.h @@ -41,7 +41,7 @@ #include "../utils/mono_reg_utils.h" #endif -namespace APIAssembly { +namespace ApiAssemblyInfo { enum Type { API_CORE, API_EDITOR @@ -76,7 +76,7 @@ struct Version { }; String to_string(Type p_type); -} // namespace APIAssembly +} // namespace ApiAssemblyInfo class GDMono { @@ -86,44 +86,58 @@ public: POLICY_LOG_ERROR }; + struct LoadedApiAssembly { + GDMonoAssembly *assembly; + bool out_of_sync; + + LoadedApiAssembly() : + assembly(NULL), + out_of_sync(false) { + } + }; + private: bool runtime_initialized; bool finalizing_scripts_domain; + UnhandledExceptionPolicy unhandled_exception_policy; + MonoDomain *root_domain; MonoDomain *scripts_domain; - bool core_api_assembly_out_of_sync; -#ifdef TOOLS_ENABLED - bool editor_api_assembly_out_of_sync; -#endif + HashMap<uint32_t, HashMap<String, GDMonoAssembly *> > assemblies; GDMonoAssembly *corlib_assembly; - GDMonoAssembly *core_api_assembly; GDMonoAssembly *project_assembly; #ifdef TOOLS_ENABLED - GDMonoAssembly *editor_api_assembly; GDMonoAssembly *tools_assembly; GDMonoAssembly *tools_project_editor_assembly; #endif - HashMap<uint32_t, HashMap<String, GDMonoAssembly *> > assemblies; - - UnhandledExceptionPolicy unhandled_exception_policy; + LoadedApiAssembly core_api_assembly; + LoadedApiAssembly editor_api_assembly; - void _domain_assemblies_cleanup(uint32_t p_domain_id); + typedef bool (*CoreApiAssemblyLoadedCallback)(); bool _are_api_assemblies_out_of_sync(); + bool _temp_domain_load_are_assemblies_out_of_sync(const String &p_config); + + bool _load_core_api_assembly(LoadedApiAssembly &r_loaded_api_assembly, const String &p_config, bool p_refonly); +#ifdef TOOLS_ENABLED + bool _load_editor_api_assembly(LoadedApiAssembly &r_loaded_api_assembly, const String &p_config, bool p_refonly); +#endif + + static bool _on_core_api_assembly_loaded(); bool _load_corlib_assembly(); - bool _load_core_api_assembly(); #ifdef TOOLS_ENABLED - bool _load_editor_api_assembly(); bool _load_tools_assemblies(); #endif bool _load_project_assembly(); - bool _try_load_api_assemblies(); + bool _try_load_api_assemblies(LoadedApiAssembly &r_core_api_assembly, LoadedApiAssembly &r_editor_api_assembly, + const String &p_config, bool p_refonly, CoreApiAssemblyLoadedCallback p_callback); + bool _try_load_api_assemblies_preset(); void _load_api_assemblies(); void _install_trace_listener(); @@ -133,6 +147,8 @@ private: Error _load_scripts_domain(); Error _unload_scripts_domain(); + void _domain_assemblies_cleanup(uint32_t p_domain_id); + uint64_t api_core_hash; #ifdef TOOLS_ENABLED uint64_t api_editor_hash; @@ -166,9 +182,21 @@ public: #endif // TOOLS_ENABLED #endif // DEBUG_METHODS_ENABLED + _FORCE_INLINE_ static String get_expected_api_build_config() { +#ifdef TOOLS_ENABLED + return "Debug"; +#else +#ifdef DEBUG_ENABLED + return "Debug"; +#else + return "Release"; +#endif +#endif + } + #ifdef TOOLS_ENABLED - bool copy_prebuilt_api_assembly(APIAssembly::Type p_api_type, const String &p_config); - String update_api_assemblies_from_prebuilt(); + bool copy_prebuilt_api_assembly(ApiAssemblyInfo::Type p_api_type, const String &p_config); + String update_api_assemblies_from_prebuilt(const String &p_config, const bool *p_core_api_out_of_sync = NULL, const bool *p_editor_api_out_of_sync = NULL); #endif static GDMono *get_singleton() { return singleton; } @@ -188,10 +216,10 @@ public: _FORCE_INLINE_ MonoDomain *get_scripts_domain() { return scripts_domain; } _FORCE_INLINE_ GDMonoAssembly *get_corlib_assembly() const { return corlib_assembly; } - _FORCE_INLINE_ GDMonoAssembly *get_core_api_assembly() const { return core_api_assembly; } + _FORCE_INLINE_ GDMonoAssembly *get_core_api_assembly() const { return core_api_assembly.assembly; } _FORCE_INLINE_ GDMonoAssembly *get_project_assembly() const { return project_assembly; } #ifdef TOOLS_ENABLED - _FORCE_INLINE_ GDMonoAssembly *get_editor_api_assembly() const { return editor_api_assembly; } + _FORCE_INLINE_ GDMonoAssembly *get_editor_api_assembly() const { return editor_api_assembly.assembly; } _FORCE_INLINE_ GDMonoAssembly *get_tools_assembly() const { return tools_assembly; } _FORCE_INLINE_ GDMonoAssembly *get_tools_project_editor_assembly() const { return tools_project_editor_assembly; } #endif diff --git a/modules/mono/mono_gd/gd_mono_utils.cpp b/modules/mono/mono_gd/gd_mono_utils.cpp index e385f4c601..6504fbe423 100644 --- a/modules/mono/mono_gd/gd_mono_utils.cpp +++ b/modules/mono/mono_gd/gd_mono_utils.cpp @@ -550,6 +550,8 @@ MonoObject *create_managed_from(const Dictionary &p_from, GDMonoClass *p_class) } MonoDomain *create_domain(const String &p_friendly_name) { + print_verbose("Mono: Creating domain '" + p_friendly_name + "'..."); + MonoDomain *domain = mono_domain_create_appdomain((char *)p_friendly_name.utf8().get_data(), NULL); if (domain) { diff --git a/modules/recast/navigation_mesh_generator.cpp b/modules/recast/navigation_mesh_generator.cpp index c5b60f2dca..320591cf7c 100644 --- a/modules/recast/navigation_mesh_generator.cpp +++ b/modules/recast/navigation_mesh_generator.cpp @@ -131,7 +131,7 @@ void EditorNavigationMeshGenerator::_add_faces(const PoolVector3Array &p_faces, } } -void EditorNavigationMeshGenerator::_parse_geometry(Transform p_accumulated_transform, Node *p_node, Vector<float> &p_verticies, Vector<int> &p_indices, int p_generate_from, uint32_t p_collision_mask) { +void EditorNavigationMeshGenerator::_parse_geometry(Transform p_accumulated_transform, Node *p_node, Vector<float> &p_verticies, Vector<int> &p_indices, int p_generate_from, uint32_t p_collision_mask, bool p_recurse_children) { if (Object::cast_to<MeshInstance>(p_node) && p_generate_from != NavigationMesh::PARSED_GEOMETRY_STATIC_COLLIDERS) { @@ -263,8 +263,10 @@ void EditorNavigationMeshGenerator::_parse_geometry(Transform p_accumulated_tran p_accumulated_transform = p_accumulated_transform * spatial->get_transform(); } - for (int i = 0; i < p_node->get_child_count(); i++) { - _parse_geometry(p_accumulated_transform, p_node->get_child(i), p_verticies, p_indices, p_generate_from, p_collision_mask); + if (p_recurse_children) { + for (int i = 0; i < p_node->get_child_count(); i++) { + _parse_geometry(p_accumulated_transform, p_node->get_child(i), p_verticies, p_indices, p_generate_from, p_collision_mask, p_recurse_children); + } } } @@ -439,7 +441,21 @@ void EditorNavigationMeshGenerator::bake(Ref<NavigationMesh> p_nav_mesh, Node *p Vector<float> vertices; Vector<int> indices; - _parse_geometry(Object::cast_to<Spatial>(p_node)->get_transform().affine_inverse(), p_node, vertices, indices, p_nav_mesh->get_parsed_geometry_type(), p_nav_mesh->get_collision_mask()); + List<Node *> parse_nodes; + + if (p_nav_mesh->get_source_geometry_mode() == NavigationMesh::SOURCE_GEOMETRY_NAVMESH_CHILDREN) { + parse_nodes.push_back(p_node); + } else { + p_node->get_tree()->get_nodes_in_group(p_nav_mesh->get_source_group_name(), &parse_nodes); + } + + Transform navmesh_xform = Object::cast_to<Spatial>(p_node)->get_transform().affine_inverse(); + for (const List<Node *>::Element *E = parse_nodes.front(); E; E = E->next()) { + int geometry_type = p_nav_mesh->get_parsed_geometry_type(); + uint32_t collision_mask = p_nav_mesh->get_collision_mask(); + bool recurse_children = p_nav_mesh->get_source_geometry_mode() != NavigationMesh::SOURCE_GEOMETRY_GROUPS_EXPLICIT; + _parse_geometry(navmesh_xform, E->get(), vertices, indices, geometry_type, collision_mask, recurse_children); + } if (vertices.size() > 0 && indices.size() > 0) { diff --git a/modules/recast/navigation_mesh_generator.h b/modules/recast/navigation_mesh_generator.h index 30a6e3c835..f19622a4a9 100644 --- a/modules/recast/navigation_mesh_generator.h +++ b/modules/recast/navigation_mesh_generator.h @@ -47,7 +47,7 @@ protected: static void _add_vertex(const Vector3 &p_vec3, Vector<float> &p_verticies); static void _add_mesh(const Ref<Mesh> &p_mesh, const Transform &p_xform, Vector<float> &p_verticies, Vector<int> &p_indices); static void _add_faces(const PoolVector3Array &p_faces, const Transform &p_xform, Vector<float> &p_verticies, Vector<int> &p_indices); - static void _parse_geometry(Transform p_accumulated_transform, Node *p_node, Vector<float> &p_verticies, Vector<int> &p_indices, int p_generate_from, uint32_t p_collision_mask); + static void _parse_geometry(Transform p_accumulated_transform, Node *p_node, Vector<float> &p_verticies, Vector<int> &p_indices, int p_generate_from, uint32_t p_collision_mask, bool p_recurse_children); static void _convert_detail_mesh_to_native_navigation_mesh(const rcPolyMeshDetail *p_detail_mesh, Ref<NavigationMesh> p_nav_mesh); static void _build_recast_navigation_mesh(Ref<NavigationMesh> p_nav_mesh, EditorProgress *ep, diff --git a/modules/visual_script/visual_script_editor.cpp b/modules/visual_script/visual_script_editor.cpp index 093901ad07..c1a4c58620 100644 --- a/modules/visual_script/visual_script_editor.cpp +++ b/modules/visual_script/visual_script_editor.cpp @@ -1916,8 +1916,6 @@ bool VisualScriptEditor::can_drop_data_fw(const Point2 &p_point, const Variant & return false; } -#ifdef TOOLS_ENABLED - static Node *_find_script_node(Node *p_edited_scene, Node *p_current_node, const Ref<Script> &script) { if (p_edited_scene != p_current_node && p_current_node->get_owner() != p_edited_scene) @@ -1937,8 +1935,6 @@ static Node *_find_script_node(Node *p_edited_scene, Node *p_current_node, const return NULL; } -#endif - void VisualScriptEditor::drop_data_fw(const Point2 &p_point, const Variant &p_data, Control *p_from) { if (p_from != graph) { @@ -2456,12 +2452,8 @@ Ref<Texture> VisualScriptEditor::get_icon() { } bool VisualScriptEditor::is_unsaved() { -#ifdef TOOLS_ENABLED return script->is_edited() || script->are_subnodes_edited(); -#else - return false; -#endif } Variant VisualScriptEditor::get_edit_state() { diff --git a/modules/visual_script/visual_script_editor.h b/modules/visual_script/visual_script_editor.h index 5a00469eea..fbf021e7b6 100644 --- a/modules/visual_script/visual_script_editor.h +++ b/modules/visual_script/visual_script_editor.h @@ -228,7 +228,7 @@ class VisualScriptEditor : public ScriptEditorBase { void _update_node_size(int p_id); void _port_name_focus_out(const Node *p_name_box, int p_id, int p_port, bool is_input); - Vector2 _get_available_pos(bool centered = true, Vector2 pos = Vector2()) const; + Vector2 _get_available_pos(bool centered = true, Vector2 ofs = Vector2()) const; StringName _get_function_of_node(int p_id) const; void _move_nodes_with_rescan(const StringName &p_func_from, const StringName &p_func_to, int p_id); diff --git a/modules/visual_script/visual_script_property_selector.h b/modules/visual_script/visual_script_property_selector.h index 405949e8c1..3a7c8de6a2 100644 --- a/modules/visual_script/visual_script_property_selector.h +++ b/modules/visual_script/visual_script_property_selector.h @@ -45,7 +45,7 @@ class VisualScriptPropertySelector : public ConfirmationDialog { void create_visualscript_item(const String &name, TreeItem *const root, const String &search_input, const String &text); - void get_visual_node_names(const String &root_filter, const Set<String> &filter, bool &found, TreeItem *const root, LineEdit *const search_box); + void get_visual_node_names(const String &root_filter, const Set<String> &p_modifiers, bool &found, TreeItem *const root, LineEdit *const search_box); void _sbox_input(const Ref<InputEvent> &p_ie); diff --git a/modules/websocket/doc_classes/WebSocketClient.xml b/modules/websocket/doc_classes/WebSocketClient.xml index c3baf9de83..705e3485f5 100644 --- a/modules/websocket/doc_classes/WebSocketClient.xml +++ b/modules/websocket/doc_classes/WebSocketClient.xml @@ -21,10 +21,13 @@ </argument> <argument index="2" name="gd_mp_api" type="bool" default="false"> </argument> + <argument index="3" name="custom_headers" type="PoolStringArray" default="PoolStringArray( )"> + </argument> <description> Connects to the given URL requesting one of the given [code]protocols[/code] as sub-protocol. If the list empty (default), no sub-protocol will be requested. If [code]true[/code] is passed as [code]gd_mp_api[/code], the client will behave like a network peer for the [MultiplayerAPI], connections to non-Godot servers will not work, and [signal data_received] will not be emitted. If [code]false[/code] is passed instead (default), you must call [PacketPeer] functions ([code]put_packet[/code], [code]get_packet[/code], etc.) on the [WebSocketPeer] returned via [code]get_peer(1)[/code] and not on this object directly (e.g. [code]get_peer(1).put_packet(data)[/code]). + You can optionally pass a list of [code]custom_headers[/code] to be added to the handshake HTTP request (not supported in HTML5 platform). </description> </method> <method name="disconnect_from_host"> @@ -38,8 +41,25 @@ Disconnects this client from the connected host. See [method WebSocketPeer.close] for more information. </description> </method> + <method name="get_connected_host" qualifiers="const"> + <return type="String"> + </return> + <description> + Return the IP address of the currently connected host. + </description> + </method> + <method name="get_connected_port" qualifiers="const"> + <return type="int"> + </return> + <description> + Return the IP port of the currently connected host. + </description> + </method> </methods> <members> + <member name="trusted_ssl_certificate" type="X509Certificate" setter="set_trusted_ssl_certificate" getter="get_trusted_ssl_certificate"> + If specified, this [X509Certificate] will be the only one accepted when connecting to an SSL host. Any other certificate provided by the server will be regarded as invalid. + </member> <member name="verify_ssl" type="bool" setter="set_verify_ssl_enabled" getter="is_verify_ssl_enabled"> If [code]true[/code], SSL certificate verification is enabled. [b]Note:[/b] You must specify the certificates to be used in the Project Settings for it to work when exported. diff --git a/modules/websocket/doc_classes/WebSocketServer.xml b/modules/websocket/doc_classes/WebSocketServer.xml index 63318e5874..86f2dae64f 100644 --- a/modules/websocket/doc_classes/WebSocketServer.xml +++ b/modules/websocket/doc_classes/WebSocketServer.xml @@ -82,6 +82,17 @@ </description> </method> </methods> + <members> + <member name="ca_chain" type="X509Certificate" setter="set_ca_chain" getter="get_ca_chain"> + When using SSL (see [member private_key] and [member ssl_certificate]), you can set this to a valid [X509Certificate] to be provided as additional CA chain information during the SSL handshake. + </member> + <member name="private_key" type="CryptoKey" setter="set_private_key" getter="get_private_key"> + When set to a valid [CryptoKey] (along with [member ssl_certificate]) will cause the server to require SSL instead of regular TCP (i.e. the [code]wss://[/code] protocol). + </member> + <member name="ssl_certificate" type="X509Certificate" setter="set_ssl_certificate" getter="get_ssl_certificate"> + When set to a valid [X509Certificate] (along with [member private_key]) will cause the server to require SSL instead of regular TCP (i.e. the [code]wss://[/code] protocol). + </member> + </members> <signals> <signal name="client_close_request"> <argument index="0" name="id" type="int"> diff --git a/modules/websocket/emws_client.cpp b/modules/websocket/emws_client.cpp index 409cc9f699..fad766ea5d 100644 --- a/modules/websocket/emws_client.cpp +++ b/modules/websocket/emws_client.cpp @@ -64,13 +64,20 @@ EMSCRIPTEN_KEEPALIVE void _esws_on_close(void *obj, int code, char *reason, int } } -Error EMWSClient::connect_to_host(String p_host, String p_path, uint16_t p_port, bool p_ssl, PoolVector<String> p_protocols) { +Error EMWSClient::connect_to_host(String p_host, String p_path, uint16_t p_port, bool p_ssl, const PoolVector<String> p_protocols, const Vector<String> p_custom_headers) { String proto_string = p_protocols.join(","); String str = "ws://"; - if (p_ssl) + if (p_custom_headers.size()) { + WARN_PRINT_ONCE("Custom headers are not supported in in HTML5 platform."); + } + if (p_ssl) { str = "wss://"; + if (ssl_cert.is_valid()) { + WARN_PRINT_ONCE("Custom SSL certificate is not supported in HTML5 platform."); + } + } str += p_host + ":" + itos(p_port) + p_path; _is_connecting = true; @@ -193,12 +200,12 @@ void EMWSClient::disconnect_from_host(int p_code, String p_reason) { IP_Address EMWSClient::get_connected_host() const { - return IP_Address(); + ERR_FAIL_V_MSG(IP_Address(), "Not supported in HTML5 export."); }; uint16_t EMWSClient::get_connected_port() const { - return 1025; + ERR_FAIL_V_MSG(0, "Not supported in HTML5 export."); }; int EMWSClient::get_max_packet_size() const { diff --git a/modules/websocket/emws_client.h b/modules/websocket/emws_client.h index 1811d05eea..2d35f7f0f6 100644 --- a/modules/websocket/emws_client.h +++ b/modules/websocket/emws_client.h @@ -50,7 +50,7 @@ public: bool _is_connecting; Error set_buffers(int p_in_buffer, int p_in_packets, int p_out_buffer, int p_out_packets); - Error connect_to_host(String p_host, String p_path, uint16_t p_port, bool p_ssl, PoolVector<String> p_protocol = PoolVector<String>()); + Error connect_to_host(String p_host, String p_path, uint16_t p_port, bool p_ssl, const PoolVector<String> p_protocol = PoolVector<String>(), const Dictionary p_custom_headers = Dictionary()); Ref<WebSocketPeer> get_peer(int p_peer_id) const; void disconnect_from_host(int p_code = 1000, String p_reason = ""); IP_Address get_connected_host() const; diff --git a/modules/websocket/websocket_client.cpp b/modules/websocket/websocket_client.cpp index 4ff5404c61..8bbd5aa37f 100644 --- a/modules/websocket/websocket_client.cpp +++ b/modules/websocket/websocket_client.cpp @@ -40,7 +40,7 @@ WebSocketClient::WebSocketClient() { WebSocketClient::~WebSocketClient() { } -Error WebSocketClient::connect_to_url(String p_url, PoolVector<String> p_protocols, bool gd_mp_api) { +Error WebSocketClient::connect_to_url(String p_url, const Vector<String> p_protocols, bool gd_mp_api, const Vector<String> p_custom_headers) { _is_multiplayer = gd_mp_api; String host = p_url; @@ -72,7 +72,7 @@ Error WebSocketClient::connect_to_url(String p_url, PoolVector<String> p_protoco host = host.substr(0, p_len); } - return connect_to_host(host, path, port, ssl, p_protocols); + return connect_to_host(host, path, port, ssl, p_protocols, p_custom_headers); } void WebSocketClient::set_verify_ssl_enabled(bool p_verify_ssl) { @@ -85,6 +85,17 @@ bool WebSocketClient::is_verify_ssl_enabled() const { return verify_ssl; } +Ref<X509Certificate> WebSocketClient::get_trusted_ssl_certificate() const { + + return ssl_cert; +} + +void WebSocketClient::set_trusted_ssl_certificate(Ref<X509Certificate> p_cert) { + + ERR_FAIL_COND(get_connection_status() != CONNECTION_DISCONNECTED); + ssl_cert = p_cert; +} + bool WebSocketClient::is_server() const { return false; @@ -132,13 +143,20 @@ void WebSocketClient::_on_error() { } void WebSocketClient::_bind_methods() { - ClassDB::bind_method(D_METHOD("connect_to_url", "url", "protocols", "gd_mp_api"), &WebSocketClient::connect_to_url, DEFVAL(PoolVector<String>()), DEFVAL(false)); + ClassDB::bind_method(D_METHOD("connect_to_url", "url", "protocols", "gd_mp_api", "custom_headers"), &WebSocketClient::connect_to_url, DEFVAL(Vector<String>()), DEFVAL(false), DEFVAL(Vector<String>())); ClassDB::bind_method(D_METHOD("disconnect_from_host", "code", "reason"), &WebSocketClient::disconnect_from_host, DEFVAL(1000), DEFVAL("")); + ClassDB::bind_method(D_METHOD("get_connected_host"), &WebSocketClient::get_connected_host); + ClassDB::bind_method(D_METHOD("get_connected_port"), &WebSocketClient::get_connected_port); ClassDB::bind_method(D_METHOD("set_verify_ssl_enabled", "enabled"), &WebSocketClient::set_verify_ssl_enabled); ClassDB::bind_method(D_METHOD("is_verify_ssl_enabled"), &WebSocketClient::is_verify_ssl_enabled); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "verify_ssl", PROPERTY_HINT_NONE, "", 0), "set_verify_ssl_enabled", "is_verify_ssl_enabled"); + ClassDB::bind_method(D_METHOD("get_trusted_ssl_certificate"), &WebSocketClient::get_trusted_ssl_certificate); + ClassDB::bind_method(D_METHOD("set_trusted_ssl_certificate"), &WebSocketClient::set_trusted_ssl_certificate); + + ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "trusted_ssl_certificate", PROPERTY_HINT_RESOURCE_TYPE, "X509Certificate", 0), "set_trusted_ssl_certificate", "get_trusted_ssl_certificate"); + ADD_SIGNAL(MethodInfo("data_received")); ADD_SIGNAL(MethodInfo("connection_established", PropertyInfo(Variant::STRING, "protocol"))); ADD_SIGNAL(MethodInfo("server_close_request", PropertyInfo(Variant::INT, "code"), PropertyInfo(Variant::STRING, "reason"))); diff --git a/modules/websocket/websocket_client.h b/modules/websocket/websocket_client.h index 7ddb9468a5..08fd6798fe 100644 --- a/modules/websocket/websocket_client.h +++ b/modules/websocket/websocket_client.h @@ -31,6 +31,7 @@ #ifndef WEBSOCKET_CLIENT_H #define WEBSOCKET_CLIENT_H +#include "core/crypto/crypto.h" #include "core/error_list.h" #include "websocket_multiplayer_peer.h" #include "websocket_peer.h" @@ -43,17 +44,20 @@ class WebSocketClient : public WebSocketMultiplayerPeer { protected: Ref<WebSocketPeer> _peer; bool verify_ssl; + Ref<X509Certificate> ssl_cert; static void _bind_methods(); public: - Error connect_to_url(String p_url, PoolVector<String> p_protocols = PoolVector<String>(), bool gd_mp_api = false); + Error connect_to_url(String p_url, const Vector<String> p_protocols = Vector<String>(), bool gd_mp_api = false, const Vector<String> p_custom_headers = Vector<String>()); void set_verify_ssl_enabled(bool p_verify_ssl); bool is_verify_ssl_enabled() const; + Ref<X509Certificate> get_trusted_ssl_certificate() const; + void set_trusted_ssl_certificate(Ref<X509Certificate> p_cert); virtual void poll() = 0; - virtual Error connect_to_host(String p_host, String p_path, uint16_t p_port, bool p_ssl, PoolVector<String> p_protocol = PoolVector<String>()) = 0; + virtual Error connect_to_host(String p_host, String p_path, uint16_t p_port, bool p_ssl, const Vector<String> p_protocol = Vector<String>(), const Vector<String> p_custom_headers = Vector<String>()) = 0; virtual void disconnect_from_host(int p_code = 1000, String p_reason = "") = 0; virtual IP_Address get_connected_host() const = 0; virtual uint16_t get_connected_port() const = 0; diff --git a/modules/websocket/websocket_server.cpp b/modules/websocket/websocket_server.cpp index ef5f6f5c20..c7414075ed 100644 --- a/modules/websocket/websocket_server.cpp +++ b/modules/websocket/websocket_server.cpp @@ -42,19 +42,58 @@ WebSocketServer::~WebSocketServer() { void WebSocketServer::_bind_methods() { ClassDB::bind_method(D_METHOD("is_listening"), &WebSocketServer::is_listening); - ClassDB::bind_method(D_METHOD("listen", "port", "protocols", "gd_mp_api"), &WebSocketServer::listen, DEFVAL(PoolVector<String>()), DEFVAL(false)); + ClassDB::bind_method(D_METHOD("listen", "port", "protocols", "gd_mp_api"), &WebSocketServer::listen, DEFVAL(Vector<String>()), DEFVAL(false)); ClassDB::bind_method(D_METHOD("stop"), &WebSocketServer::stop); ClassDB::bind_method(D_METHOD("has_peer", "id"), &WebSocketServer::has_peer); ClassDB::bind_method(D_METHOD("get_peer_address", "id"), &WebSocketServer::get_peer_address); ClassDB::bind_method(D_METHOD("get_peer_port", "id"), &WebSocketServer::get_peer_port); ClassDB::bind_method(D_METHOD("disconnect_peer", "id", "code", "reason"), &WebSocketServer::disconnect_peer, DEFVAL(1000), DEFVAL("")); + ClassDB::bind_method(D_METHOD("get_private_key"), &WebSocketServer::get_private_key); + ClassDB::bind_method(D_METHOD("set_private_key"), &WebSocketServer::set_private_key); + ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "private_key", PROPERTY_HINT_RESOURCE_TYPE, "CryptoKey", 0), "set_private_key", "get_private_key"); + + ClassDB::bind_method(D_METHOD("get_ssl_certificate"), &WebSocketServer::get_ssl_certificate); + ClassDB::bind_method(D_METHOD("set_ssl_certificate"), &WebSocketServer::set_ssl_certificate); + ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "ssl_certificate", PROPERTY_HINT_RESOURCE_TYPE, "X509Certificate", 0), "set_ssl_certificate", "get_ssl_certificate"); + + ClassDB::bind_method(D_METHOD("get_ca_chain"), &WebSocketServer::get_ca_chain); + ClassDB::bind_method(D_METHOD("set_ca_chain"), &WebSocketServer::set_ca_chain); + ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "ca_chain", PROPERTY_HINT_RESOURCE_TYPE, "X509Certificate", 0), "set_ca_chain", "get_ca_chain"); + ADD_SIGNAL(MethodInfo("client_close_request", PropertyInfo(Variant::INT, "id"), PropertyInfo(Variant::INT, "code"), PropertyInfo(Variant::STRING, "reason"))); ADD_SIGNAL(MethodInfo("client_disconnected", PropertyInfo(Variant::INT, "id"), PropertyInfo(Variant::BOOL, "was_clean_close"))); ADD_SIGNAL(MethodInfo("client_connected", PropertyInfo(Variant::INT, "id"), PropertyInfo(Variant::STRING, "protocol"))); ADD_SIGNAL(MethodInfo("data_received", PropertyInfo(Variant::INT, "id"))); } +Ref<CryptoKey> WebSocketServer::get_private_key() const { + return private_key; +} + +void WebSocketServer::set_private_key(Ref<CryptoKey> p_key) { + ERR_FAIL_COND(is_listening()); + private_key = p_key; +} + +Ref<X509Certificate> WebSocketServer::get_ssl_certificate() const { + return ssl_cert; +} + +void WebSocketServer::set_ssl_certificate(Ref<X509Certificate> p_cert) { + ERR_FAIL_COND(is_listening()); + ssl_cert = p_cert; +} + +Ref<X509Certificate> WebSocketServer::get_ca_chain() const { + return ca_chain; +} + +void WebSocketServer::set_ca_chain(Ref<X509Certificate> p_ca_chain) { + ERR_FAIL_COND(is_listening()); + ca_chain = p_ca_chain; +} + NetworkedMultiplayerPeer::ConnectionStatus WebSocketServer::get_connection_status() const { if (is_listening()) return CONNECTION_CONNECTED; diff --git a/modules/websocket/websocket_server.h b/modules/websocket/websocket_server.h index 83c0c10419..0b39f94473 100644 --- a/modules/websocket/websocket_server.h +++ b/modules/websocket/websocket_server.h @@ -31,6 +31,7 @@ #ifndef WEBSOCKET_H #define WEBSOCKET_H +#include "core/crypto/crypto.h" #include "core/reference.h" #include "websocket_multiplayer_peer.h" #include "websocket_peer.h" @@ -43,9 +44,13 @@ class WebSocketServer : public WebSocketMultiplayerPeer { protected: static void _bind_methods(); + Ref<CryptoKey> private_key; + Ref<X509Certificate> ssl_cert; + Ref<X509Certificate> ca_chain; + public: virtual void poll() = 0; - virtual Error listen(int p_port, PoolVector<String> p_protocols = PoolVector<String>(), bool gd_mp_api = false) = 0; + virtual Error listen(int p_port, const Vector<String> p_protocols = Vector<String>(), bool gd_mp_api = false) = 0; virtual void stop() = 0; virtual bool is_listening() const = 0; virtual bool has_peer(int p_id) const = 0; @@ -62,6 +67,15 @@ public: void _on_disconnect(int32_t p_peer_id, bool p_was_clean); void _on_close_request(int32_t p_peer_id, int p_code, String p_reason); + Ref<CryptoKey> get_private_key() const; + void set_private_key(Ref<CryptoKey> p_key); + + Ref<X509Certificate> get_ssl_certificate() const; + void set_ssl_certificate(Ref<X509Certificate> p_cert); + + Ref<X509Certificate> get_ca_chain() const; + void set_ca_chain(Ref<X509Certificate> p_ca_chain); + virtual Error set_buffers(int p_in_buffer, int p_in_packets, int p_out_buffer, int p_out_packets) = 0; WebSocketServer(); diff --git a/modules/websocket/wsl_client.cpp b/modules/websocket/wsl_client.cpp index 0006a057e0..a422f65cfc 100644 --- a/modules/websocket/wsl_client.cpp +++ b/modules/websocket/wsl_client.cpp @@ -86,6 +86,7 @@ void WSLClient::_do_handshake() { WSLPeer::PeerData *data = memnew(struct WSLPeer::PeerData); data->obj = this; data->conn = _connection; + data->tcp = _tcp; data->is_server = false; data->id = 1; _peer->make_context(data, _in_buf_size, _in_pkt_size, _out_buf_size, _out_pkt_size); @@ -151,7 +152,7 @@ bool WSLClient::_verify_headers(String &r_protocol) { return true; } -Error WSLClient::connect_to_host(String p_host, String p_path, uint16_t p_port, bool p_ssl, PoolVector<String> p_protocols) { +Error WSLClient::connect_to_host(String p_host, String p_path, uint16_t p_port, bool p_ssl, const Vector<String> p_protocols, const Vector<String> p_custom_headers) { ERR_FAIL_COND_V(_connection.is_valid(), ERR_ALREADY_IN_USE); @@ -180,7 +181,8 @@ Error WSLClient::connect_to_host(String p_host, String p_path, uint16_t p_port, _connection = _tcp; _use_ssl = p_ssl; _host = p_host; - _protocols = p_protocols; + _protocols.clear(); + _protocols.append_array(p_protocols); _key = WSLPeer::generate_key(); // TODO custom extra headers (allow overriding this too?) @@ -199,6 +201,9 @@ Error WSLClient::connect_to_host(String p_host, String p_path, uint16_t p_port, } request += "\r\n"; } + for (int i = 0; i < p_custom_headers.size(); i++) { + request += p_custom_headers[i] + "\r\n"; + } request += "\r\n"; _request = request.utf8(); @@ -236,7 +241,7 @@ void WSLClient::poll() { ssl = Ref<StreamPeerSSL>(StreamPeerSSL::create()); ERR_FAIL_COND_MSG(ssl.is_null(), "SSL is not available in this build."); ssl->set_blocking_handshake_enabled(false); - if (ssl->connect_to_stream(_tcp, verify_ssl, _host) != OK) { + if (ssl->connect_to_stream(_tcp, verify_ssl, _host, ssl_cert) != OK) { disconnect_from_host(); _on_error(); return; @@ -293,7 +298,7 @@ void WSLClient::disconnect_from_host(int p_code, String p_reason) { _key = ""; _host = ""; - _protocols.resize(0); + _protocols.clear(); _use_ssl = false; _request = ""; @@ -305,12 +310,14 @@ void WSLClient::disconnect_from_host(int p_code, String p_reason) { IP_Address WSLClient::get_connected_host() const { - return IP_Address(); + ERR_FAIL_COND_V(!_peer->is_connected_to_host(), IP_Address()); + return _peer->get_connected_host(); } uint16_t WSLClient::get_connected_port() const { - return 1025; + ERR_FAIL_COND_V(!_peer->is_connected_to_host(), 0); + return _peer->get_connected_port(); } Error WSLClient::set_buffers(int p_in_buffer, int p_in_packets, int p_out_buffer, int p_out_packets) { diff --git a/modules/websocket/wsl_client.h b/modules/websocket/wsl_client.h index 57dfd635b7..870be94a87 100644 --- a/modules/websocket/wsl_client.h +++ b/modules/websocket/wsl_client.h @@ -64,7 +64,7 @@ private: String _key; String _host; - PoolVector<String> _protocols; + Vector<String> _protocols; bool _use_ssl; void _do_handshake(); @@ -72,7 +72,7 @@ private: public: Error set_buffers(int p_in_buffer, int p_in_packets, int p_out_buffer, int p_out_packets); - Error connect_to_host(String p_host, String p_path, uint16_t p_port, bool p_ssl, PoolVector<String> p_protocol = PoolVector<String>()); + Error connect_to_host(String p_host, String p_path, uint16_t p_port, bool p_ssl, const Vector<String> p_protocol = Vector<String>(), const Vector<String> p_custom_headers = Vector<String>()); int get_max_packet_size() const; Ref<WebSocketPeer> get_peer(int p_peer_id) const; void disconnect_from_host(int p_code = 1000, String p_reason = ""); diff --git a/modules/websocket/wsl_peer.cpp b/modules/websocket/wsl_peer.cpp index 74fb901232..32beccde5d 100644 --- a/modules/websocket/wsl_peer.cpp +++ b/modules/websocket/wsl_peer.cpp @@ -208,7 +208,6 @@ void WSLPeer::make_context(PeerData *p_data, unsigned int p_in_buf_size, unsigne _data = p_data; _data->peer = this; _data->valid = true; - _connection = Ref<StreamPeer>(_data->conn); if (_data->is_server) wslay_event_context_server_init(&(_data->ctx), &wsl_callbacks, _data); @@ -302,18 +301,16 @@ void WSLPeer::close(int p_code, String p_reason) { IP_Address WSLPeer::get_connected_host() const { - ERR_FAIL_COND_V(!is_connected_to_host(), IP_Address()); + ERR_FAIL_COND_V(!is_connected_to_host() || _data->tcp.is_null(), IP_Address()); - IP_Address ip; - return ip; + return _data->tcp->get_connected_host(); } uint16_t WSLPeer::get_connected_port() const { - ERR_FAIL_COND_V(!is_connected_to_host(), 0); + ERR_FAIL_COND_V(!is_connected_to_host() || _data->tcp.is_null(), 0); - uint16_t port = 0; - return port; + return _data->tcp->get_connected_port(); } void WSLPeer::invalidate() { diff --git a/modules/websocket/wsl_peer.h b/modules/websocket/wsl_peer.h index d51b304fe1..01ad250468 100644 --- a/modules/websocket/wsl_peer.h +++ b/modules/websocket/wsl_peer.h @@ -35,6 +35,7 @@ #include "core/error_list.h" #include "core/io/packet_peer.h" +#include "core/io/stream_peer_tcp.h" #include "core/ring_buffer.h" #include "packet_buffer.h" #include "websocket_peer.h" @@ -55,6 +56,7 @@ public: void *obj; void *peer; Ref<StreamPeer> conn; + Ref<StreamPeerTCP> tcp; int id; wslay_event_context_ptr ctx; @@ -77,7 +79,6 @@ private: static bool _wsl_poll(struct PeerData *p_data); static void _wsl_destroy(struct PeerData **p_data); - Ref<StreamPeer> _connection; struct PeerData *_data; uint8_t _is_string; // Our packet info is just a boolean (is_string), using uint8_t for it. diff --git a/modules/websocket/wsl_server.cpp b/modules/websocket/wsl_server.cpp index efb526eed1..993dceafb9 100644 --- a/modules/websocket/wsl_server.cpp +++ b/modules/websocket/wsl_server.cpp @@ -35,6 +35,7 @@ #include "core/project_settings.h" WSLServer::PendingPeer::PendingPeer() { + use_ssl = false; time = 0; has_request = false; response_sent = 0; @@ -42,7 +43,7 @@ WSLServer::PendingPeer::PendingPeer() { memset(req_buf, 0, sizeof(req_buf)); } -bool WSLServer::PendingPeer::_parse_request(const PoolStringArray p_protocols) { +bool WSLServer::PendingPeer::_parse_request(const Vector<String> p_protocols) { Vector<String> psa = String((char *)req_buf).split("\r\n"); int len = psa.size(); ERR_FAIL_COND_V_MSG(len < 4, false, "Not enough response headers, got: " + itos(len) + ", expected >= 4."); @@ -97,9 +98,19 @@ bool WSLServer::PendingPeer::_parse_request(const PoolStringArray p_protocols) { return true; } -Error WSLServer::PendingPeer::do_handshake(PoolStringArray p_protocols) { +Error WSLServer::PendingPeer::do_handshake(const Vector<String> p_protocols) { if (OS::get_singleton()->get_ticks_msec() - time > WSL_SERVER_TIMEOUT) return ERR_TIMEOUT; + if (use_ssl) { + Ref<StreamPeerSSL> ssl = static_cast<Ref<StreamPeerSSL> >(connection); + if (ssl.is_null()) + return FAILED; + ssl->poll(); + if (ssl->get_status() == StreamPeerSSL::STATUS_HANDSHAKING) + return ERR_BUSY; + else if (ssl->get_status() != StreamPeerSSL::STATUS_CONNECTED) + return FAILED; + } if (!has_request) { int read = 0; while (true) { @@ -143,11 +154,11 @@ Error WSLServer::PendingPeer::do_handshake(PoolStringArray p_protocols) { return OK; } -Error WSLServer::listen(int p_port, PoolVector<String> p_protocols, bool gd_mp_api) { +Error WSLServer::listen(int p_port, const Vector<String> p_protocols, bool gd_mp_api) { ERR_FAIL_COND_V(is_listening(), ERR_ALREADY_IN_USE); _is_multiplayer = gd_mp_api; - _protocols = p_protocols; + _protocols.append_array(p_protocols); _server->listen(p_port); return OK; @@ -185,6 +196,7 @@ void WSLServer::poll() { WSLPeer::PeerData *data = memnew(struct WSLPeer::PeerData); data->obj = this; data->conn = ppeer->connection; + data->tcp = ppeer->tcp; data->is_server = true; data->id = id; @@ -204,12 +216,21 @@ void WSLServer::poll() { return; while (_server->is_connection_available()) { - Ref<StreamPeer> conn = _server->take_connection(); + Ref<StreamPeerTCP> conn = _server->take_connection(); if (is_refusing_new_connections()) continue; // Conn will go out-of-scope and be closed. Ref<PendingPeer> peer = memnew(PendingPeer); - peer->connection = conn; + if (private_key.is_valid() && ssl_cert.is_valid()) { + Ref<StreamPeerSSL> ssl = Ref<StreamPeerSSL>(StreamPeerSSL::create()); + ssl->set_blocking_handshake_enabled(false); + ssl->accept_stream(conn, private_key, ssl_cert, ca_chain); + peer->connection = ssl; + peer->use_ssl = true; + } else { + peer->connection = conn; + } + peer->tcp = conn; peer->time = OS::get_singleton()->get_ticks_msec(); _pending.push_back(peer); } @@ -231,6 +252,7 @@ void WSLServer::stop() { } _pending.clear(); _peer_map.clear(); + _protocols.clear(); } bool WSLServer::has_peer(int p_id) const { diff --git a/modules/websocket/wsl_server.h b/modules/websocket/wsl_server.h index 2ceb941073..aae563355e 100644 --- a/modules/websocket/wsl_server.h +++ b/modules/websocket/wsl_server.h @@ -36,6 +36,7 @@ #include "websocket_server.h" #include "wsl_peer.h" +#include "core/io/stream_peer_ssl.h" #include "core/io/stream_peer_tcp.h" #include "core/io/tcp_server.h" @@ -49,10 +50,12 @@ private: class PendingPeer : public Reference { private: - bool _parse_request(const PoolStringArray p_protocols); + bool _parse_request(const Vector<String> p_protocols); public: + Ref<StreamPeerTCP> tcp; Ref<StreamPeer> connection; + bool use_ssl; int time; uint8_t req_buf[WSL_MAX_HEADER_SIZE]; @@ -65,7 +68,7 @@ private: PendingPeer(); - Error do_handshake(const PoolStringArray p_protocols); + Error do_handshake(const Vector<String> p_protocols); }; int _in_buf_size; @@ -75,11 +78,11 @@ private: List<Ref<PendingPeer> > _pending; Ref<TCP_Server> _server; - PoolStringArray _protocols; + Vector<String> _protocols; public: Error set_buffers(int p_in_buffer, int p_in_packets, int p_out_buffer, int p_out_packets); - Error listen(int p_port, PoolVector<String> p_protocols = PoolVector<String>(), bool gd_mp_api = false); + Error listen(int p_port, const Vector<String> p_protocols = Vector<String>(), bool gd_mp_api = false); void stop(); bool is_listening() const; int get_max_packet_size() const; diff --git a/platform/android/export/export.cpp b/platform/android/export/export.cpp index b61575e2aa..a43f195b84 100644 --- a/platform/android/export/export.cpp +++ b/platform/android/export/export.cpp @@ -766,17 +766,9 @@ class EditorExportPlatformAndroid : public EditorExportPlatform { uint32_t attr_value = decode_uint32(&p_manifest[iofs + 8]); uint32_t attr_resid = decode_uint32(&p_manifest[iofs + 16]); - String value; - if (attr_value != 0xFFFFFFFF) - value = string_table[attr_value]; - else - value = "Res #" + itos(attr_resid); + const String value = (attr_value != 0xFFFFFFFF) ? string_table[attr_value] : "Res #" + itos(attr_resid); String attrname = string_table[attr_name]; - String nspace; - if (attr_nspace != 0xFFFFFFFF) - nspace = string_table[attr_nspace]; - else - nspace = ""; + const String nspace = (attr_nspace != 0xFFFFFFFF) ? string_table[attr_nspace] : ""; //replace project information if (tname == "manifest" && attrname == "package") { @@ -828,14 +820,16 @@ class EditorExportPlatformAndroid : public EditorExportPlatform { encode_uint32(min_gles3 ? 0x00030000 : 0x00020000, &p_manifest.write[iofs + 16]); } - if (tname == "meta-data" && attrname == "name" && string_table[attr_value] == "xr_mode_metadata_name") { + // FIXME: `attr_value != 0xFFFFFFFF` below added as a stopgap measure for GH-32553, + // but the issue should be debugged further and properly addressed. + if (tname == "meta-data" && attrname == "name" && value == "xr_mode_metadata_name") { // Update the meta-data 'android:name' attribute based on the selected XR mode. if (xr_mode_index == 1 /* XRMode.OVR */) { string_table.write[attr_value] = "com.samsung.android.vr.application.mode"; } } - if (tname == "meta-data" && attrname == "value" && string_table[attr_value] == "xr_mode_metadata_value") { + if (tname == "meta-data" && attrname == "value" && value == "xr_mode_metadata_value") { // Update the meta-data 'android:value' attribute based on the selected XR mode. if (xr_mode_index == 1 /* XRMode.OVR */) { string_table.write[attr_value] = "vr_only"; diff --git a/platform/android/java/lib/res/drawable-hdpi/notify_panel_notification_icon_bg.png b/platform/android/java/lib/res/drawable-hdpi/notify_panel_notification_icon_bg.png Binary files differindex 2c246b04a4..f849d8e90d 100644 --- a/platform/android/java/lib/res/drawable-hdpi/notify_panel_notification_icon_bg.png +++ b/platform/android/java/lib/res/drawable-hdpi/notify_panel_notification_icon_bg.png diff --git a/platform/android/java/lib/res/drawable-mdpi/notify_panel_notification_icon_bg.png b/platform/android/java/lib/res/drawable-mdpi/notify_panel_notification_icon_bg.png Binary files differindex 8bcd464bed..1dfb28b33a 100644 --- a/platform/android/java/lib/res/drawable-mdpi/notify_panel_notification_icon_bg.png +++ b/platform/android/java/lib/res/drawable-mdpi/notify_panel_notification_icon_bg.png diff --git a/platform/android/java/lib/res/drawable-xxhdpi/notify_panel_notification_icon_bg.png b/platform/android/java/lib/res/drawable-xxhdpi/notify_panel_notification_icon_bg.png Binary files differindex b458ff3057..302a972049 100644 --- a/platform/android/java/lib/res/drawable-xxhdpi/notify_panel_notification_icon_bg.png +++ b/platform/android/java/lib/res/drawable-xxhdpi/notify_panel_notification_icon_bg.png diff --git a/platform/android/logo.png b/platform/android/logo.png Binary files differindex ba2a0e366a..df445f6a9c 100644 --- a/platform/android/logo.png +++ b/platform/android/logo.png diff --git a/platform/javascript/logo.png b/platform/javascript/logo.png Binary files differindex 36832d93ba..c046d87dc4 100644 --- a/platform/javascript/logo.png +++ b/platform/javascript/logo.png diff --git a/platform/osx/logo.png b/platform/osx/logo.png Binary files differindex 62086fc415..834bbf3ba6 100644 --- a/platform/osx/logo.png +++ b/platform/osx/logo.png diff --git a/platform/osx/os_osx.mm b/platform/osx/os_osx.mm index d30cb1c092..51ae264cf7 100644 --- a/platform/osx/os_osx.mm +++ b/platform/osx/os_osx.mm @@ -339,6 +339,8 @@ static CVReturn DisplayLinkCallback(CVDisplayLinkRef displayLink, const CVTimeSt CGFloat oldBackingScaleFactor = [[[notification userInfo] objectForKey:@"NSBackingPropertyOldScaleFactorKey"] doubleValue]; if (OS_OSX::singleton->is_hidpi_allowed()) { [OS_OSX::singleton->window_view setWantsBestResolutionOpenGLSurface:YES]; + } else { + [OS_OSX::singleton->window_view setWantsBestResolutionOpenGLSurface:NO]; } if (newBackingScaleFactor != oldBackingScaleFactor) { @@ -1492,6 +1494,8 @@ Error OS_OSX::initialize(const VideoMode &p_desired, int p_video_driver, int p_a [window_view setWantsBestResolutionOpenGLSurface:YES]; //if (current_videomode.resizable) [window_object setCollectionBehavior:NSWindowCollectionBehaviorFullScreenPrimary]; + } else { + [window_view setWantsBestResolutionOpenGLSurface:NO]; } //[window_object setTitle:[NSString stringWithUTF8String:"GodotEnginies"]]; diff --git a/platform/x11/os_x11.cpp b/platform/x11/os_x11.cpp index 39160ee720..694aea7462 100644 --- a/platform/x11/os_x11.cpp +++ b/platform/x11/os_x11.cpp @@ -1767,7 +1767,8 @@ void OS_X11::handle_key_event(XKeyEvent *p_event, bool p_echo) { XKeyEvent xkeyevent_no_mod = *xkeyevent; xkeyevent_no_mod.state &= ~ShiftMask; xkeyevent_no_mod.state &= ~ControlMask; - XLookupString(&xkeyevent_no_mod, str, 256, &keysym_keycode, NULL); + XLookupString(xkeyevent, str, 256, &keysym_unicode, NULL); + XLookupString(&xkeyevent_no_mod, NULL, 0, &keysym_keycode, NULL); // Meanwhile, XLookupString returns keysyms useful for unicode. @@ -1777,8 +1778,6 @@ void OS_X11::handle_key_event(XKeyEvent *p_event, bool p_echo) { xmblen = 8; } - keysym_unicode = keysym_keycode; - if (xkeyevent->type == KeyPress && xic) { Status status; diff --git a/scene/2d/joints_2d.cpp b/scene/2d/joints_2d.cpp index d8156a0afe..12fb18cedc 100644 --- a/scene/2d/joints_2d.cpp +++ b/scene/2d/joints_2d.cpp @@ -61,8 +61,6 @@ void Joint2D::_update_joint(bool p_only_free) { if (!body_a || !body_b) return; - SWAP(body_a, body_b); - joint = _configure_joint(body_a, body_b); if (!joint.is_valid()) diff --git a/scene/2d/sprite.cpp b/scene/2d/sprite.cpp index 83f92ce2bc..d2e1e494e3 100644 --- a/scene/2d/sprite.cpp +++ b/scene/2d/sprite.cpp @@ -269,8 +269,8 @@ int Sprite::get_frame() const { } void Sprite::set_frame_coords(const Vector2 &p_coord) { - ERR_FAIL_INDEX(int(p_coord.x), vframes); - ERR_FAIL_INDEX(int(p_coord.y), hframes); + ERR_FAIL_INDEX(int(p_coord.x), hframes); + ERR_FAIL_INDEX(int(p_coord.y), vframes); set_frame(int(p_coord.y) * hframes + int(p_coord.x)); } diff --git a/scene/3d/navigation_mesh.cpp b/scene/3d/navigation_mesh.cpp index f82543b789..496dc4b411 100644 --- a/scene/3d/navigation_mesh.cpp +++ b/scene/3d/navigation_mesh.cpp @@ -108,6 +108,24 @@ bool NavigationMesh::get_collision_mask_bit(int p_bit) const { return get_collision_mask() & (1 << p_bit); } +void NavigationMesh::set_source_geometry_mode(int p_geometry_mode) { + ERR_FAIL_INDEX(p_geometry_mode, SOURCE_GEOMETRY_MAX); + source_geometry_mode = static_cast<SourceGeometryMode>(p_geometry_mode); + _change_notify(); +} + +int NavigationMesh::get_source_geometry_mode() const { + return source_geometry_mode; +} + +void NavigationMesh::set_source_group_name(StringName p_group_name) { + source_group_name = p_group_name; +} + +StringName NavigationMesh::get_source_group_name() const { + return source_group_name; +} + void NavigationMesh::set_cell_size(float p_value) { cell_size = p_value; } @@ -387,6 +405,12 @@ void NavigationMesh::_bind_methods() { ClassDB::bind_method(D_METHOD("set_collision_mask_bit", "bit", "value"), &NavigationMesh::set_collision_mask_bit); ClassDB::bind_method(D_METHOD("get_collision_mask_bit", "bit"), &NavigationMesh::get_collision_mask_bit); + ClassDB::bind_method(D_METHOD("set_source_geometry_mode", "mask"), &NavigationMesh::set_source_geometry_mode); + ClassDB::bind_method(D_METHOD("get_source_geometry_mode"), &NavigationMesh::get_source_geometry_mode); + + ClassDB::bind_method(D_METHOD("set_source_group_name", "mask"), &NavigationMesh::set_source_group_name); + ClassDB::bind_method(D_METHOD("get_source_group_name"), &NavigationMesh::get_source_group_name); + ClassDB::bind_method(D_METHOD("set_cell_size", "cell_size"), &NavigationMesh::set_cell_size); ClassDB::bind_method(D_METHOD("get_cell_size"), &NavigationMesh::get_cell_size); @@ -462,6 +486,8 @@ void NavigationMesh::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::INT, "sample_partition_type/sample_partition_type", PROPERTY_HINT_ENUM, "Watershed,Monotone,Layers"), "set_sample_partition_type", "get_sample_partition_type"); ADD_PROPERTY(PropertyInfo(Variant::INT, "geometry/parsed_geometry_type", PROPERTY_HINT_ENUM, "Mesh Instances,Static Colliders,Both"), "set_parsed_geometry_type", "get_parsed_geometry_type"); ADD_PROPERTY(PropertyInfo(Variant::INT, "geometry/collision_mask", PROPERTY_HINT_LAYERS_3D_PHYSICS), "set_collision_mask", "get_collision_mask"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "geometry/source_geometry_mode", PROPERTY_HINT_ENUM, "Navmesh Children, Group With Children, Group Explicit"), "set_source_geometry_mode", "get_source_geometry_mode"); + ADD_PROPERTY(PropertyInfo(Variant::STRING, "geometry/source_group_name"), "set_source_group_name", "get_source_group_name"); ADD_PROPERTY(PropertyInfo(Variant::REAL, "cell/size", PROPERTY_HINT_RANGE, "0.1,1.0,0.01,or_greater"), "set_cell_size", "get_cell_size"); ADD_PROPERTY(PropertyInfo(Variant::REAL, "cell/height", PROPERTY_HINT_RANGE, "0.1,1.0,0.01,or_greater"), "set_cell_height", "get_cell_height"); @@ -489,6 +515,13 @@ void NavigationMesh::_validate_property(PropertyInfo &property) const { return; } } + + if (property.name == "geometry/source_group_name") { + if (source_geometry_mode == SOURCE_GEOMETRY_NAVMESH_CHILDREN) { + property.usage = 0; + return; + } + } } NavigationMesh::NavigationMesh() { @@ -509,6 +542,8 @@ NavigationMesh::NavigationMesh() { partition_type = SAMPLE_PARTITION_WATERSHED; parsed_geometry_type = PARSED_GEOMETRY_MESH_INSTANCES; collision_mask = 0xFFFFFFFF; + source_geometry_mode = SOURCE_GEOMETRY_NAVMESH_CHILDREN; + source_group_name = "navmesh"; filter_low_hanging_obstacles = false; filter_ledge_spans = false; filter_walkable_low_height_spans = false; diff --git a/scene/3d/navigation_mesh.h b/scene/3d/navigation_mesh.h index 5fbf3998ff..8467f80f0e 100644 --- a/scene/3d/navigation_mesh.h +++ b/scene/3d/navigation_mesh.h @@ -77,6 +77,13 @@ public: PARSED_GEOMETRY_MAX }; + enum SourceGeometryMode { + SOURCE_GEOMETRY_NAVMESH_CHILDREN = 0, + SOURCE_GEOMETRY_GROUPS_WITH_CHILDREN, + SOURCE_GEOMETRY_GROUPS_EXPLICIT, + SOURCE_GEOMETRY_MAX + }; + protected: float cell_size; float cell_height; @@ -96,6 +103,9 @@ protected: ParsedGeometryType parsed_geometry_type; uint32_t collision_mask; + SourceGeometryMode source_geometry_mode; + StringName source_group_name; + bool filter_low_hanging_obstacles; bool filter_ledge_spans; bool filter_walkable_low_height_spans; @@ -114,6 +124,12 @@ public: void set_collision_mask_bit(int p_bit, bool p_value); bool get_collision_mask_bit(int p_bit) const; + void set_source_geometry_mode(int p_source_mode); + int get_source_geometry_mode() const; + + void set_source_group_name(StringName p_group_name); + StringName get_source_group_name() const; + void set_cell_size(float p_value); float get_cell_size() const; diff --git a/scene/3d/sprite_3d.cpp b/scene/3d/sprite_3d.cpp index a9dacc442c..a8d2f4d415 100644 --- a/scene/3d/sprite_3d.cpp +++ b/scene/3d/sprite_3d.cpp @@ -577,9 +577,8 @@ void Sprite3D::set_frame(int p_frame) { ERR_FAIL_INDEX(p_frame, int64_t(vframes) * hframes); - if (frame != p_frame) + frame = p_frame; - frame = p_frame; _queue_update(); _change_notify("frame"); @@ -593,8 +592,8 @@ int Sprite3D::get_frame() const { } void Sprite3D::set_frame_coords(const Vector2 &p_coord) { - ERR_FAIL_INDEX(int(p_coord.x), vframes); - ERR_FAIL_INDEX(int(p_coord.y), hframes); + ERR_FAIL_INDEX(int(p_coord.x), hframes); + ERR_FAIL_INDEX(int(p_coord.y), vframes); set_frame(int(p_coord.y) * hframes + int(p_coord.x)); } diff --git a/scene/gui/file_dialog.cpp b/scene/gui/file_dialog.cpp index 24c046457b..5cb4bcc64f 100644 --- a/scene/gui/file_dialog.cpp +++ b/scene/gui/file_dialog.cpp @@ -46,14 +46,31 @@ VBoxContainer *FileDialog::get_vbox() { void FileDialog::_notification(int p_what) { - if (p_what == NOTIFICATION_ENTER_TREE) { + if (p_what == NOTIFICATION_ENTER_TREE || p_what == NOTIFICATION_THEME_CHANGED) { - dir_up->set_icon(get_icon("parent_folder")); - refresh->set_icon(get_icon("reload")); - show_hidden->set_icon(get_icon("toggle_hidden")); - } + if (p_what == NOTIFICATION_ENTER_TREE) { + dir_up->set_icon(get_icon("parent_folder")); + refresh->set_icon(get_icon("reload")); + show_hidden->set_icon(get_icon("toggle_hidden")); + } + + Color font_color = get_color("font_color", "ToolButton"); + Color font_color_hover = get_color("font_color_hover", "ToolButton"); + Color font_color_pressed = get_color("font_color_pressed", "ToolButton"); + + dir_up->add_color_override("icon_color_normal", font_color); + dir_up->add_color_override("icon_color_hover", font_color_hover); + dir_up->add_color_override("icon_color_pressed", font_color_pressed); + + refresh->add_color_override("icon_color_normal", font_color); + refresh->add_color_override("icon_color_hover", font_color_hover); + refresh->add_color_override("icon_color_pressed", font_color_pressed); + + show_hidden->add_color_override("icon_color_normal", font_color); + show_hidden->add_color_override("icon_color_hover", font_color_hover); + show_hidden->add_color_override("icon_color_pressed", font_color_pressed); - if (p_what == NOTIFICATION_POPUP_HIDE) { + } else if (p_what == NOTIFICATION_POPUP_HIDE) { set_process_unhandled_input(false); } diff --git a/scene/gui/text_edit.cpp b/scene/gui/text_edit.cpp index c0b0944e47..69d076c41b 100644 --- a/scene/gui/text_edit.cpp +++ b/scene/gui/text_edit.cpp @@ -935,7 +935,7 @@ void TextEdit::_notification(int p_what) { int minimap_line = (v_scroll->get_max() <= minimap_visible_lines) ? -1 : first_visible_line; if (minimap_line >= 0) { minimap_line -= num_lines_from_rows(first_visible_line, 0, -num_lines_before, wi); - minimap_line -= (smooth_scroll_enabled ? 1 : 0); + minimap_line -= (minimap_line > 0 && smooth_scroll_enabled ? 1 : 0); } int minimap_draw_amount = minimap_visible_lines + times_line_wraps(minimap_line + 1); @@ -2146,7 +2146,7 @@ void TextEdit::_get_minimap_mouse_row(const Point2i &p_mouse, int &r_row) const int minimap_line = (v_scroll->get_max() <= minimap_visible_lines) ? -1 : first_visible_line; if (first_visible_line > 0 && minimap_line >= 0) { minimap_line -= num_lines_from_rows(first_visible_line, 0, -num_lines_before, wi); - minimap_line -= (smooth_scroll_enabled ? 1 : 0); + minimap_line -= (minimap_line > 0 && smooth_scroll_enabled ? 1 : 0); } else { minimap_line = 0; } @@ -4071,6 +4071,7 @@ void TextEdit::_insert_text_at_cursor(const String &p_text) { int new_column, new_line; _insert_text(cursor.line, cursor.column, p_text, &new_line, &new_column); + _update_scrollbars(); cursor_set_line(new_line); cursor_set_column(new_column); @@ -5914,7 +5915,7 @@ void TextEdit::unfold_line(int p_line) { if (!is_folded(p_line) && !is_line_hidden(p_line)) return; - int fold_start = p_line; + int fold_start; for (fold_start = p_line; fold_start > 0; fold_start--) { if (is_folded(fold_start)) break; diff --git a/scene/main/scene_tree.cpp b/scene/main/scene_tree.cpp index 3ee21ce38b..830d314245 100644 --- a/scene/main/scene_tree.cpp +++ b/scene/main/scene_tree.cpp @@ -70,9 +70,8 @@ float SceneTreeTimer::get_time_left() const { } void SceneTreeTimer::set_pause_mode_process(bool p_pause_mode_process) { - if (process_pause != p_pause_mode_process) { - process_pause = p_pause_mode_process; - } + + process_pause = p_pause_mode_process; } bool SceneTreeTimer::is_pause_mode_process() { diff --git a/scene/resources/bit_map.cpp b/scene/resources/bit_map.cpp index b5354bc3e2..e6139dd707 100644 --- a/scene/resources/bit_map.cpp +++ b/scene/resources/bit_map.cpp @@ -534,7 +534,7 @@ void BitMap::grow_mask(int p_pixels, const Rect2 &p_rect) { return; } - bool bit_value = (p_pixels > 0) ? true : false; + bool bit_value = p_pixels > 0; p_pixels = Math::abs(p_pixels); Rect2i r = Rect2i(0, 0, width, height).clip(p_rect); diff --git a/scene/resources/box_shape.cpp b/scene/resources/box_shape.cpp index d819e9f776..c6fe14e55e 100644 --- a/scene/resources/box_shape.cpp +++ b/scene/resources/box_shape.cpp @@ -31,7 +31,7 @@ #include "box_shape.h" #include "servers/physics_server.h" -Vector<Vector3> BoxShape::_gen_debug_mesh_lines() { +Vector<Vector3> BoxShape::get_debug_mesh_lines() { Vector<Vector3> lines; AABB aabb; diff --git a/scene/resources/box_shape.h b/scene/resources/box_shape.h index 42d54310a8..0bce929aee 100644 --- a/scene/resources/box_shape.h +++ b/scene/resources/box_shape.h @@ -42,12 +42,13 @@ protected: static void _bind_methods(); virtual void _update_shape(); - virtual Vector<Vector3> _gen_debug_mesh_lines(); public: void set_extents(const Vector3 &p_extents); Vector3 get_extents() const; + virtual Vector<Vector3> get_debug_mesh_lines(); + BoxShape(); }; diff --git a/scene/resources/capsule_shape.cpp b/scene/resources/capsule_shape.cpp index 669b261bfe..1ec3bd7158 100644 --- a/scene/resources/capsule_shape.cpp +++ b/scene/resources/capsule_shape.cpp @@ -31,7 +31,7 @@ #include "capsule_shape.h" #include "servers/physics_server.h" -Vector<Vector3> CapsuleShape::_gen_debug_mesh_lines() { +Vector<Vector3> CapsuleShape::get_debug_mesh_lines() { float radius = get_radius(); float height = get_height(); diff --git a/scene/resources/capsule_shape.h b/scene/resources/capsule_shape.h index 6bca53f783..befbc1dcd5 100644 --- a/scene/resources/capsule_shape.h +++ b/scene/resources/capsule_shape.h @@ -44,14 +44,14 @@ protected: virtual void _update_shape(); - virtual Vector<Vector3> _gen_debug_mesh_lines(); - public: void set_radius(float p_radius); float get_radius() const; void set_height(float p_height); float get_height() const; + virtual Vector<Vector3> get_debug_mesh_lines(); + CapsuleShape(); }; diff --git a/scene/resources/concave_polygon_shape.cpp b/scene/resources/concave_polygon_shape.cpp index b4cc38c8c0..dbc07ef591 100644 --- a/scene/resources/concave_polygon_shape.cpp +++ b/scene/resources/concave_polygon_shape.cpp @@ -32,7 +32,7 @@ #include "servers/physics_server.h" -Vector<Vector3> ConcavePolygonShape::_gen_debug_mesh_lines() { +Vector<Vector3> ConcavePolygonShape::get_debug_mesh_lines() { Set<DrawEdge> edges; diff --git a/scene/resources/concave_polygon_shape.h b/scene/resources/concave_polygon_shape.h index 1b8ddfc308..57362a29be 100644 --- a/scene/resources/concave_polygon_shape.h +++ b/scene/resources/concave_polygon_shape.h @@ -61,12 +61,13 @@ protected: static void _bind_methods(); virtual void _update_shape(); - virtual Vector<Vector3> _gen_debug_mesh_lines(); public: void set_faces(const PoolVector<Vector3> &p_faces); PoolVector<Vector3> get_faces() const; + Vector<Vector3> get_debug_mesh_lines(); + ConcavePolygonShape(); }; diff --git a/scene/resources/convex_polygon_shape.cpp b/scene/resources/convex_polygon_shape.cpp index 499688a185..af459ec311 100644 --- a/scene/resources/convex_polygon_shape.cpp +++ b/scene/resources/convex_polygon_shape.cpp @@ -32,7 +32,7 @@ #include "core/math/quick_hull.h" #include "servers/physics_server.h" -Vector<Vector3> ConvexPolygonShape::_gen_debug_mesh_lines() { +Vector<Vector3> ConvexPolygonShape::get_debug_mesh_lines() { PoolVector<Vector3> points = get_points(); diff --git a/scene/resources/convex_polygon_shape.h b/scene/resources/convex_polygon_shape.h index 5c192476d3..e6daf1bef4 100644 --- a/scene/resources/convex_polygon_shape.h +++ b/scene/resources/convex_polygon_shape.h @@ -43,12 +43,12 @@ protected: virtual void _update_shape(); - virtual Vector<Vector3> _gen_debug_mesh_lines(); - public: void set_points(const PoolVector<Vector3> &p_points); PoolVector<Vector3> get_points() const; + virtual Vector<Vector3> get_debug_mesh_lines(); + ConvexPolygonShape(); }; diff --git a/scene/resources/cylinder_shape.cpp b/scene/resources/cylinder_shape.cpp index f60f7ab376..c1a0a0ac5d 100644 --- a/scene/resources/cylinder_shape.cpp +++ b/scene/resources/cylinder_shape.cpp @@ -31,7 +31,7 @@ #include "cylinder_shape.h" #include "servers/physics_server.h" -Vector<Vector3> CylinderShape::_gen_debug_mesh_lines() { +Vector<Vector3> CylinderShape::get_debug_mesh_lines() { float radius = get_radius(); float height = get_height(); diff --git a/scene/resources/cylinder_shape.h b/scene/resources/cylinder_shape.h index 58a4f5a817..411c1515ed 100644 --- a/scene/resources/cylinder_shape.h +++ b/scene/resources/cylinder_shape.h @@ -43,14 +43,14 @@ protected: static void _bind_methods(); virtual void _update_shape(); - virtual Vector<Vector3> _gen_debug_mesh_lines(); - public: void set_radius(float p_radius); float get_radius() const; void set_height(float p_height); float get_height() const; + virtual Vector<Vector3> get_debug_mesh_lines(); + CylinderShape(); }; diff --git a/scene/resources/default_theme/button_hover.png b/scene/resources/default_theme/button_hover.png Binary files differindex ef226e3caf..ff2258281e 100644 --- a/scene/resources/default_theme/button_hover.png +++ b/scene/resources/default_theme/button_hover.png diff --git a/scene/resources/default_theme/button_normal.png b/scene/resources/default_theme/button_normal.png Binary files differindex 7d0bd16221..c189b61b89 100644 --- a/scene/resources/default_theme/button_normal.png +++ b/scene/resources/default_theme/button_normal.png diff --git a/scene/resources/default_theme/color_picker_hue.png b/scene/resources/default_theme/color_picker_hue.png Binary files differindex de2cd0c2bf..7b46f03cb4 100644 --- a/scene/resources/default_theme/color_picker_hue.png +++ b/scene/resources/default_theme/color_picker_hue.png diff --git a/scene/resources/default_theme/error_icon.png b/scene/resources/default_theme/error_icon.png Binary files differindex 00680db5df..30336b91a4 100644 --- a/scene/resources/default_theme/error_icon.png +++ b/scene/resources/default_theme/error_icon.png diff --git a/scene/resources/default_theme/graph_node_selected.png b/scene/resources/default_theme/graph_node_selected.png Binary files differindex cc4eb7f753..c52d88586b 100644 --- a/scene/resources/default_theme/graph_node_selected.png +++ b/scene/resources/default_theme/graph_node_selected.png diff --git a/scene/resources/default_theme/graph_port.png b/scene/resources/default_theme/graph_port.png Binary files differindex f33ae3baf3..358934f4d8 100644 --- a/scene/resources/default_theme/graph_port.png +++ b/scene/resources/default_theme/graph_port.png diff --git a/scene/resources/default_theme/icon_visibility.png b/scene/resources/default_theme/icon_visibility.png Binary files differindex 6402571f3e..b2df8cbdb8 100644 --- a/scene/resources/default_theme/icon_visibility.png +++ b/scene/resources/default_theme/icon_visibility.png diff --git a/scene/resources/default_theme/option_button_normal.png b/scene/resources/default_theme/option_button_normal.png Binary files differindex 2dadb40338..43fc29e958 100644 --- a/scene/resources/default_theme/option_button_normal.png +++ b/scene/resources/default_theme/option_button_normal.png diff --git a/scene/resources/default_theme/scroll_grabber_hl.png b/scene/resources/default_theme/scroll_grabber_hl.png Binary files differindex 006cfa3361..21ee486e0b 100644 --- a/scene/resources/default_theme/scroll_grabber_hl.png +++ b/scene/resources/default_theme/scroll_grabber_hl.png diff --git a/scene/resources/default_theme/space.png b/scene/resources/default_theme/space.png Binary files differindex 7e458a6c45..3c66316074 100644 --- a/scene/resources/default_theme/space.png +++ b/scene/resources/default_theme/space.png diff --git a/scene/resources/default_theme/tab_container_bg.png b/scene/resources/default_theme/tab_container_bg.png Binary files differindex 7d0bd16221..c189b61b89 100644 --- a/scene/resources/default_theme/tab_container_bg.png +++ b/scene/resources/default_theme/tab_container_bg.png diff --git a/scene/resources/default_theme/tab_current.png b/scene/resources/default_theme/tab_current.png Binary files differindex 520d147217..d5641e917a 100644 --- a/scene/resources/default_theme/tab_current.png +++ b/scene/resources/default_theme/tab_current.png diff --git a/scene/resources/default_theme/tab_disabled.png b/scene/resources/default_theme/tab_disabled.png Binary files differindex 97157a58dd..a7c04effa3 100644 --- a/scene/resources/default_theme/tab_disabled.png +++ b/scene/resources/default_theme/tab_disabled.png diff --git a/scene/resources/default_theme/theme_data.h b/scene/resources/default_theme/theme_data.h index 0d57fc6b14..0a4e557451 100644 --- a/scene/resources/default_theme/theme_data.h +++ b/scene/resources/default_theme/theme_data.h @@ -19,11 +19,11 @@ static const unsigned char button_focus_png[] = { }; static const unsigned char button_hover_png[] = { - 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x10, 0x8, 0x3, 0x0, 0x0, 0x0, 0x28, 0x2d, 0xf, 0x53, 0x0, 0x0, 0x0, 0x8a, 0x50, 0x4c, 0x54, 0x45, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x42, 0x40, 0x4b, 0x5f, 0x5a, 0x6c, 0x5f, 0x5a, 0x6b, 0x56, 0x53, 0x64, 0x57, 0x53, 0x64, 0x3e, 0x3b, 0x46, 0x57, 0x53, 0x63, 0x57, 0x53, 0x63, 0x5b, 0x57, 0x68, 0x5a, 0x56, 0x67, 0x4d, 0x4a, 0x57, 0x49, 0x46, 0x52, 0x48, 0x45, 0x51, 0x5b, 0x57, 0x66, 0x59, 0x55, 0x64, 0x47, 0x44, 0x50, 0x58, 0x54, 0x64, 0x46, 0x43, 0x50, 0x56, 0x53, 0x63, 0x45, 0x42, 0x4f, 0x56, 0x53, 0x62, 0x45, 0x42, 0x4e, 0x55, 0x51, 0x62, 0x44, 0x41, 0x4e, 0x55, 0x51, 0x60, 0x44, 0x41, 0x4d, 0x43, 0x40, 0x4c, 0x47, 0x43, 0x51, 0x43, 0x3f, 0x4d, 0x42, 0x3f, 0x4c, 0x53, 0x50, 0x5f, 0x53, 0x4f, 0x5e, 0x40, 0xdc, 0xe6, 0x80, 0x0, 0x0, 0x0, 0x16, 0x74, 0x52, 0x4e, 0x53, 0x4, 0xa, 0x11, 0x19, 0x1f, 0x22, 0x24, 0x15, 0x25, 0x34, 0x3f, 0x46, 0x47, 0x48, 0x77, 0xef, 0xef, 0xef, 0xef, 0x77, 0xef, 0xed, 0x6b, 0x28, 0x52, 0x7a, 0x0, 0x0, 0x0, 0x67, 0x49, 0x44, 0x41, 0x54, 0x78, 0xda, 0x5d, 0xcf, 0x47, 0x2, 0x83, 0x30, 0x10, 0x43, 0x51, 0x69, 0x98, 0xf4, 0xe4, 0xfe, 0x87, 0x24, 0xfb, 0xf4, 0x8, 0xd1, 0xb1, 0x3f, 0xb8, 0xbd, 0xdd, 0x24, 0x38, 0x4, 0x40, 0x43, 0xc9, 0xfd, 0x24, 0x1a, 0x7a, 0x27, 0x2d, 0x7, 0xc2, 0x41, 0x2f, 0xbd, 0x69, 0x88, 0x23, 0x27, 0x38, 0x3d, 0xfd, 0x22, 0x2f, 0xd3, 0x1b, 0xc3, 0x35, 0xe9, 0x85, 0x39, 0xd, 0x10, 0x2c, 0x0, 0x25, 0x20, 0x81, 0x2d, 0xc0, 0xa0, 0x2d, 0x8, 0xa9, 0x12, 0x64, 0x0, 0x66, 0x91, 0xa5, 0x61, 0xf3, 0xbe, 0xc5, 0x18, 0xd9, 0x7e, 0x7e, 0x21, 0x45, 0x1b, 0x53, 0x77, 0x4a, 0xac, 0x87, 0x63, 0x3d, 0x7e, 0x7, 0x87, 0x7b, 0x3b, 0x5b, 0x7a, 0xd3, 0xea, 0x4, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82 + 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x10, 0x8, 0x3, 0x0, 0x0, 0x0, 0x28, 0x2d, 0xf, 0x53, 0x0, 0x0, 0x0, 0x8a, 0x50, 0x4c, 0x54, 0x45, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x42, 0x40, 0x4b, 0x5f, 0x5a, 0x6c, 0x5f, 0x5a, 0x6b, 0x56, 0x53, 0x64, 0x57, 0x53, 0x64, 0x3e, 0x3b, 0x46, 0x57, 0x53, 0x63, 0x57, 0x53, 0x63, 0x5b, 0x57, 0x68, 0x5a, 0x56, 0x67, 0x4d, 0x4a, 0x57, 0x49, 0x46, 0x52, 0x48, 0x45, 0x51, 0x5b, 0x57, 0x66, 0x59, 0x55, 0x64, 0x47, 0x44, 0x50, 0x58, 0x54, 0x64, 0x46, 0x43, 0x50, 0x56, 0x53, 0x63, 0x45, 0x42, 0x4f, 0x56, 0x53, 0x62, 0x45, 0x42, 0x4e, 0x55, 0x51, 0x62, 0x44, 0x41, 0x4e, 0x55, 0x51, 0x60, 0x44, 0x41, 0x4d, 0x43, 0x40, 0x4c, 0x47, 0x43, 0x51, 0x43, 0x3f, 0x4d, 0x42, 0x3f, 0x4c, 0x53, 0x50, 0x5f, 0x53, 0x4f, 0x5e, 0x40, 0xdc, 0xe6, 0x80, 0x0, 0x0, 0x0, 0x16, 0x74, 0x52, 0x4e, 0x53, 0x4, 0xa, 0x11, 0x19, 0x1f, 0x22, 0x24, 0x15, 0x25, 0x34, 0x3f, 0x46, 0x47, 0x48, 0x77, 0xef, 0xef, 0xef, 0xef, 0x77, 0xef, 0xed, 0x6b, 0x28, 0x52, 0x7a, 0x0, 0x0, 0x0, 0x65, 0x49, 0x44, 0x41, 0x54, 0x78, 0xda, 0x6d, 0xcf, 0xc5, 0x1, 0x84, 0x40, 0x14, 0x4, 0xd1, 0x2e, 0x5c, 0xf3, 0xf, 0x92, 0xbd, 0xaf, 0xd3, 0xb8, 0x53, 0x30, 0xf6, 0x6e, 0x1f, 0x31, 0x26, 0xc9, 0x63, 0x90, 0xcc, 0xe2, 0xb1, 0x4f, 0x34, 0x48, 0x8a, 0x86, 0xfc, 0xf6, 0x87, 0x1e, 0x82, 0x8c, 0x19, 0xf2, 0x17, 0x4, 0x50, 0xce, 0x6f, 0x8d, 0xd7, 0x88, 0x7e, 0x69, 0xc9, 0x23, 0x4, 0x1c, 0x40, 0x47, 0x50, 0x24, 0xed, 0x41, 0x3d, 0x78, 0xf, 0x56, 0xe4, 0x23, 0xb8, 0x7, 0x69, 0x11, 0xf7, 0x12, 0x12, 0x7e, 0xea, 0x60, 0xa, 0x9a, 0xef, 0x3f, 0xb0, 0x83, 0x26, 0x98, 0x7b, 0x70, 0x33, 0xdc, 0x65, 0xfc, 0xe, 0x81, 0x4e, 0x3b, 0x55, 0xea, 0xaa, 0xb0, 0xe, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82 }; static const unsigned char button_normal_png[] = { - 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x10, 0x8, 0x3, 0x0, 0x0, 0x0, 0x28, 0x2d, 0xf, 0x53, 0x0, 0x0, 0x0, 0x87, 0x50, 0x4c, 0x54, 0x45, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x3c, 0x3a, 0x44, 0x56, 0x53, 0x61, 0x56, 0x52, 0x60, 0x47, 0x44, 0x52, 0x33, 0x31, 0x39, 0x47, 0x44, 0x50, 0x47, 0x44, 0x51, 0x52, 0x50, 0x5d, 0x51, 0x4f, 0x5d, 0x46, 0x42, 0x4e, 0x42, 0x3e, 0x4a, 0x41, 0x3e, 0x49, 0x51, 0x4e, 0x5b, 0x40, 0x3e, 0x48, 0x4f, 0x4c, 0x59, 0x3f, 0x3d, 0x47, 0x4e, 0x4a, 0x58, 0x3e, 0x3b, 0x46, 0x4b, 0x49, 0x55, 0x3c, 0x3a, 0x44, 0x4a, 0x47, 0x54, 0x3b, 0x39, 0x43, 0x49, 0x46, 0x53, 0x3a, 0x38, 0x42, 0x47, 0x45, 0x50, 0x39, 0x37, 0x40, 0x47, 0x43, 0x50, 0x38, 0x35, 0x3f, 0x36, 0x34, 0x3e, 0x44, 0x42, 0x4d, 0x44, 0x41, 0x4c, 0x3f, 0x38, 0xaa, 0x5e, 0x0, 0x0, 0x0, 0x15, 0x74, 0x52, 0x4e, 0x53, 0x4, 0xa, 0x11, 0x19, 0x1f, 0x22, 0x24, 0x15, 0x25, 0x34, 0x3f, 0x46, 0x47, 0x48, 0x77, 0xef, 0xef, 0xef, 0x77, 0xef, 0xed, 0xe8, 0xff, 0x76, 0xed, 0x0, 0x0, 0x0, 0x65, 0x49, 0x44, 0x41, 0x54, 0x78, 0xda, 0x65, 0xcf, 0x45, 0x2, 0x84, 0x30, 0x14, 0x4, 0xd1, 0x2e, 0x1c, 0xee, 0x7f, 0xca, 0xd1, 0xed, 0x28, 0x8d, 0x4b, 0x92, 0x5a, 0xbe, 0xe8, 0x2f, 0xc4, 0x9c, 0x24, 0xcf, 0x15, 0x54, 0xab, 0x78, 0xee, 0x53, 0x30, 0x4a, 0x85, 0xa6, 0xfc, 0xf1, 0x87, 0x11, 0xb2, 0x9a, 0x15, 0x9a, 0x37, 0x13, 0x74, 0xce, 0xb4, 0xd4, 0x77, 0xcb, 0xe, 0xb4, 0x96, 0x99, 0x10, 0x34, 0x81, 0x42, 0x50, 0x21, 0x9d, 0x41, 0x23, 0xf8, 0xc, 0x56, 0xe1, 0x10, 0x9c, 0x40, 0x4e, 0xfe, 0x6e, 0x72, 0x96, 0x7e, 0xd7, 0xdf, 0x3f, 0xb3, 0x79, 0x90, 0xcd, 0xf1, 0xc4, 0x26, 0x1e, 0x8e, 0x78, 0xfc, 0x1, 0xf5, 0x61, 0x3f, 0x44, 0xe8, 0xf1, 0xdd, 0xba, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82 + 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x10, 0x8, 0x3, 0x0, 0x0, 0x0, 0x28, 0x2d, 0xf, 0x53, 0x0, 0x0, 0x0, 0x87, 0x50, 0x4c, 0x54, 0x45, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x3c, 0x3a, 0x44, 0x56, 0x53, 0x61, 0x56, 0x52, 0x60, 0x47, 0x44, 0x52, 0x33, 0x31, 0x39, 0x47, 0x44, 0x50, 0x47, 0x44, 0x51, 0x52, 0x50, 0x5d, 0x51, 0x4f, 0x5d, 0x46, 0x42, 0x4e, 0x42, 0x3e, 0x4a, 0x41, 0x3e, 0x49, 0x51, 0x4e, 0x5b, 0x40, 0x3e, 0x48, 0x4f, 0x4c, 0x59, 0x3f, 0x3d, 0x47, 0x4e, 0x4a, 0x58, 0x3e, 0x3b, 0x46, 0x4b, 0x49, 0x55, 0x3c, 0x3a, 0x44, 0x4a, 0x47, 0x54, 0x3b, 0x39, 0x43, 0x49, 0x46, 0x53, 0x3a, 0x38, 0x42, 0x47, 0x45, 0x50, 0x39, 0x37, 0x40, 0x47, 0x43, 0x50, 0x38, 0x35, 0x3f, 0x36, 0x34, 0x3e, 0x44, 0x42, 0x4d, 0x44, 0x41, 0x4c, 0x3f, 0x38, 0xaa, 0x5e, 0x0, 0x0, 0x0, 0x15, 0x74, 0x52, 0x4e, 0x53, 0x4, 0xa, 0x11, 0x19, 0x1f, 0x22, 0x24, 0x15, 0x25, 0x34, 0x3f, 0x46, 0x47, 0x48, 0x77, 0xef, 0xef, 0xef, 0x77, 0xef, 0xed, 0xe8, 0xff, 0x76, 0xed, 0x0, 0x0, 0x0, 0x63, 0x49, 0x44, 0x41, 0x54, 0x78, 0xda, 0x6d, 0xcf, 0x45, 0x2, 0x84, 0x30, 0x0, 0x4, 0xc1, 0x69, 0x1c, 0xfe, 0xff, 0xca, 0xd5, 0xeb, 0x2a, 0x83, 0x6b, 0xd2, 0xb7, 0x54, 0x1c, 0x31, 0x26, 0xc9, 0x63, 0x50, 0xcc, 0x32, 0x8d, 0x3f, 0xd9, 0x20, 0x5, 0x1a, 0xf2, 0xc7, 0x1f, 0x7a, 0x48, 0x4a, 0x66, 0xa8, 0xde, 0xc, 0xd0, 0x38, 0xd1, 0x54, 0xdb, 0x4c, 0x2b, 0xd0, 0x5c, 0x62, 0x8e, 0xa0, 0x1, 0x74, 0x4, 0x65, 0xd2, 0x1e, 0xd4, 0x83, 0xf7, 0x60, 0x65, 0x3e, 0x82, 0x3, 0x48, 0x49, 0xdf, 0x55, 0xca, 0xd4, 0xef, 0xfa, 0xfb, 0x27, 0x36, 0xf, 0x92, 0x31, 0x9e, 0x44, 0x3e, 0x17, 0x7c, 0xbf, 0x3, 0xef, 0x34, 0x3f, 0x3e, 0xe0, 0x24, 0x67, 0xb9, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82 }; static const unsigned char button_pressed_png[] = { @@ -47,7 +47,7 @@ static const unsigned char close_hl_png[] = { }; static const unsigned char color_picker_hue_png[] = { - 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, 0x1, 0x0, 0x8, 0x2, 0x0, 0x0, 0x0, 0xfd, 0x5c, 0x8b, 0xcf, 0x0, 0x0, 0x0, 0x59, 0x49, 0x44, 0x41, 0x54, 0x28, 0x91, 0xcd, 0xd0, 0x31, 0xa, 0x3, 0x31, 0x10, 0x43, 0xd1, 0x87, 0xc0, 0xf6, 0xfd, 0x8f, 0x1b, 0xdb, 0x30, 0x69, 0x76, 0x21, 0x65, 0xd8, 0x14, 0x71, 0xf1, 0xf9, 0x8c, 0x84, 0x9a, 0x51, 0x44, 0x13, 0xfd, 0x21, 0xe3, 0x87, 0xed, 0xf7, 0xa8, 0xcd, 0x2a, 0x99, 0x8e, 0x46, 0x2b, 0x94, 0xd0, 0x43, 0xb, 0xe3, 0x64, 0xb3, 0x2a, 0xa6, 0x93, 0xb9, 0x9f, 0x9a, 0x4e, 0x3a, 0x69, 0x97, 0xc7, 0xe5, 0x3b, 0x1b, 0xff, 0xef, 0x6d, 0xa5, 0xec, 0x30, 0xc3, 0xeb, 0xf2, 0xc, 0xeb, 0xe3, 0x5e, 0x27, 0xf4, 0x8a, 0x37, 0x75, 0x7b, 0x8a, 0xe5, 0x90, 0x9a, 0xab, 0x81, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82 + 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, 0x1, 0x0, 0x8, 0x2, 0x0, 0x0, 0x0, 0xfd, 0x5c, 0x8b, 0xcf, 0x0, 0x0, 0x0, 0x54, 0x49, 0x44, 0x41, 0x54, 0x78, 0xda, 0xcd, 0xc9, 0x1, 0x6, 0x43, 0x31, 0x10, 0x45, 0xd1, 0x63, 0xc8, 0xcf, 0xfe, 0x97, 0xdb, 0x9f, 0xf0, 0x1a, 0x15, 0xb4, 0x0, 0xa5, 0x1a, 0x1c, 0xd7, 0xcc, 0x13, 0x4a, 0x5b, 0xae, 0x2f, 0xf5, 0xdd, 0xdf, 0x92, 0xc9, 0x88, 0xba, 0x1d, 0x4d, 0xb, 0xa2, 0xb8, 0x96, 0xb6, 0xf4, 0x93, 0xcb, 0x48, 0xb9, 0x9d, 0x8c, 0x16, 0xa4, 0x2e, 0x5e, 0xda, 0x6e, 0xe7, 0xe3, 0xd7, 0xff, 0xbf, 0x9b, 0x22, 0x66, 0x71, 0x2f, 0x8f, 0xdd, 0xc5, 0x78, 0xbb, 0xc7, 0x9, 0xbb, 0xf0, 0x4, 0x75, 0x7b, 0x8a, 0xe5, 0x7c, 0x23, 0x8a, 0xd3, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82 }; static const unsigned char color_picker_sample_png[] = { @@ -59,7 +59,7 @@ static const unsigned char dropdown_png[] = { }; static const unsigned char error_icon_png[] = { - 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x10, 0x8, 0x4, 0x0, 0x0, 0x0, 0xb5, 0xfa, 0x37, 0xea, 0x0, 0x0, 0x0, 0x2, 0x62, 0x4b, 0x47, 0x44, 0x0, 0xff, 0x87, 0x8f, 0xcc, 0xbf, 0x0, 0x0, 0x0, 0x9, 0x70, 0x48, 0x59, 0x73, 0x0, 0x0, 0xb, 0x13, 0x0, 0x0, 0xb, 0x13, 0x1, 0x0, 0x9a, 0x9c, 0x18, 0x0, 0x0, 0x0, 0x7, 0x74, 0x49, 0x4d, 0x45, 0x7, 0xe2, 0xb, 0xf, 0x0, 0x22, 0x18, 0xc, 0x35, 0xef, 0x18, 0x0, 0x0, 0x0, 0xe, 0x49, 0x44, 0x41, 0x54, 0x28, 0xcf, 0x63, 0x60, 0x18, 0x5, 0xa3, 0x0, 0x1, 0x0, 0x2, 0x10, 0x0, 0x1, 0x14, 0xc2, 0xc0, 0x92, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82 + 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x10, 0x8, 0x4, 0x0, 0x0, 0x0, 0xb5, 0xfa, 0x37, 0xea, 0x0, 0x0, 0x0, 0x9, 0x70, 0x48, 0x59, 0x73, 0x0, 0x0, 0xb, 0x13, 0x0, 0x0, 0xb, 0x13, 0x1, 0x0, 0x9a, 0x9c, 0x18, 0x0, 0x0, 0x0, 0x2, 0x62, 0x4b, 0x47, 0x44, 0x0, 0xff, 0x87, 0x8f, 0xcc, 0xbf, 0x0, 0x0, 0x0, 0xe, 0x49, 0x44, 0x41, 0x54, 0x28, 0xcf, 0x63, 0x60, 0x18, 0x5, 0xa3, 0x0, 0x1, 0x0, 0x2, 0x10, 0x0, 0x1, 0x14, 0xc2, 0xc0, 0x92, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82 }; static const unsigned char focus_png[] = { @@ -99,11 +99,11 @@ static const unsigned char graph_node_position_png[] = { }; static const unsigned char graph_node_selected_png[] = { - 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x40, 0x8, 0x3, 0x0, 0x0, 0x0, 0x24, 0xa3, 0x7, 0xa4, 0x0, 0x0, 0x1, 0x5f, 0x50, 0x4c, 0x54, 0x45, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xb2, 0xb2, 0xcc, 0xae, 0xa0, 0xbb, 0x9c, 0x92, 0xa6, 0x9a, 0x91, 0xa4, 0x95, 0x8c, 0x9e, 0xaf, 0x9f, 0xaf, 0xa0, 0x94, 0xa5, 0x8e, 0x84, 0x95, 0x7f, 0x75, 0x84, 0x73, 0x6a, 0x78, 0x6d, 0x64, 0x72, 0xa2, 0xa2, 0xb9, 0x9c, 0x90, 0xa2, 0x8b, 0x81, 0x90, 0xdc, 0xda, 0xce, 0xe2, 0xe1, 0xd2, 0x9d, 0x91, 0xa9, 0x85, 0x7c, 0x8c, 0xdb, 0xd9, 0xce, 0xdb, 0xd9, 0xcd, 0xda, 0xce, 0xe0, 0xde, 0xd5, 0xe3, 0xdf, 0xd6, 0xe4, 0x97, 0x8d, 0xa0, 0x7a, 0x70, 0x7f, 0xdb, 0xd0, 0xdf, 0xdb, 0xd0, 0xe1, 0xda, 0xd0, 0xe1, 0x70, 0x67, 0x75, 0xd8, 0xcb, 0xde, 0xda, 0xcf, 0xdf, 0xdb, 0xce, 0xe1, 0xdb, 0xcf, 0xe1, 0xdb, 0xd0, 0xe0, 0xda, 0xcf, 0xe0, 0xd8, 0xcc, 0xde, 0x90, 0x87, 0x99, 0x6d, 0x67, 0x72, 0xd7, 0xcc, 0xdf, 0xda, 0xce, 0xdf, 0xd8, 0xcb, 0xdf, 0xd7, 0xca, 0xde, 0xd9, 0xcc, 0xdf, 0xd9, 0xcd, 0xdf, 0xd6, 0xc9, 0xdd, 0xd9, 0xcd, 0xde, 0xd6, 0xc8, 0xdc, 0xd5, 0xc8, 0xdc, 0xd7, 0xcb, 0xdd, 0xd7, 0xca, 0xdd, 0xd5, 0xc7, 0xdc, 0xd3, 0xc6, 0xdb, 0xd5, 0xc9, 0xdc, 0xd5, 0xc9, 0xdd, 0xd6, 0xc9, 0xdc, 0xd4, 0xc6, 0xdb, 0xd3, 0xc5, 0xdb, 0xd5, 0xc8, 0xdb, 0xd4, 0xc8, 0xdc, 0xd3, 0xc4, 0xd9, 0xd4, 0xc6, 0xda, 0xd2, 0xc3, 0xd9, 0xd3, 0xc5, 0xda, 0xd2, 0xc5, 0xd9, 0xd3, 0xc5, 0xd9, 0xd2, 0xc5, 0xda, 0xd1, 0xc2, 0xd9, 0xd2, 0xc4, 0xd8, 0xd2, 0xc4, 0xd9, 0xd0, 0xc2, 0xd9, 0xd0, 0xc1, 0xd7, 0xd0, 0xc2, 0xd7, 0xd0, 0xc2, 0xd8, 0xd1, 0xc2, 0xd7, 0xcf, 0xc1, 0xd7, 0xd0, 0xc2, 0xd6, 0xcf, 0xc1, 0xd6, 0xcf, 0xc2, 0xd7, 0xcf, 0xc0, 0xd7, 0xce, 0xbf, 0xd6, 0xce, 0xc0, 0xd5, 0xce, 0xc0, 0xd6, 0xce, 0xbf, 0xd5, 0xcd, 0xbf, 0xd5, 0xcd, 0xbe, 0xd5, 0xcd, 0xbe, 0xd4, 0xcc, 0xbd, 0xd5, 0xcc, 0xbd, 0xd4, 0xcc, 0xbc, 0xd4, 0x47, 0x40, 0x4a, 0x1d, 0x1a, 0x1f, 0x69, 0x5f, 0x6f, 0x4a, 0x42, 0x4f, 0x5e, 0x54, 0x63, 0x3b, 0x34, 0x3f, 0x5e, 0x55, 0x63, 0x63, 0x59, 0x67, 0x77, 0x6d, 0x7b, 0x6d, 0x62, 0x73, 0x7f, 0x76, 0x85, 0xdb, 0xd9, 0xcd, 0xdb, 0xd8, 0xcd, 0x6d, 0x62, 0x74, 0x8f, 0x84, 0x94, 0x7f, 0x76, 0x83, 0xdb, 0xd8, 0xcd, 0xa4, 0x95, 0xa4, 0x7e, 0x74, 0x84, 0x74, 0x6b, 0x79, 0x6f, 0x66, 0x74, 0x96, 0x8a, 0xa2, 0x91, 0x88, 0x9b, 0x0, 0x0, 0x0, 0xaa, 0xaa, 0xaa, 0xbf, 0xbf, 0xbf, 0xf0, 0xc9, 0xec, 0x71, 0x0, 0x0, 0x0, 0x75, 0x74, 0x52, 0x4e, 0x53, 0x1, 0x3, 0xa, 0x13, 0x1a, 0x1c, 0x1d, 0x10, 0x2b, 0x4d, 0x64, 0x6e, 0x72, 0xb, 0x2c, 0x6a, 0xfc, 0xff, 0x15, 0x52, 0xfd, 0xff, 0xe2, 0xe2, 0xe2, 0x1b, 0x68, 0xe2, 0xe2, 0xe2, 0x71, 0xe2, 0xe2, 0xe2, 0xe2, 0xe2, 0xe2, 0xe2, 0x1e, 0x72, 0xe2, 0xe2, 0xe2, 0xe2, 0xe2, 0xe2, 0xe2, 0xe2, 0xe2, 0xe2, 0xe2, 0xe2, 0xe2, 0xe2, 0xe2, 0xe2, 0xe2, 0xe2, 0xe2, 0xe2, 0xe2, 0xe2, 0xe2, 0xe2, 0xe2, 0xe2, 0xe2, 0xe2, 0xe2, 0xe2, 0xe2, 0xe2, 0xe2, 0xe2, 0xe2, 0xe2, 0xe2, 0xe2, 0xe2, 0xe2, 0xe2, 0xe2, 0xe2, 0xe2, 0xe2, 0xe2, 0xe2, 0xe2, 0xe2, 0xe2, 0xe2, 0xc7, 0xc7, 0xc7, 0xc7, 0xc7, 0xc7, 0xc7, 0xc7, 0x6b, 0xc7, 0x56, 0xfe, 0xff, 0xc7, 0x30, 0x74, 0xfe, 0x11, 0x57, 0x6d, 0x72, 0x16, 0x1c, 0x0, 0x3, 0x4, 0x35, 0xf5, 0x4, 0x26, 0x0, 0x0, 0x1, 0x1f, 0x49, 0x44, 0x41, 0x54, 0x78, 0xda, 0xec, 0xd0, 0x35, 0x82, 0x1c, 0x31, 0x14, 0x84, 0xe1, 0xbf, 0xa4, 0xd7, 0x32, 0x33, 0xb3, 0xf, 0x63, 0x8e, 0xcd, 0x10, 0xcd, 0x99, 0x1c, 0x3a, 0x75, 0xe8, 0xcc, 0xbe, 0x8e, 0x99, 0x79, 0xb9, 0x49, 0x6f, 0x49, 0xd3, 0xcb, 0x7b, 0x82, 0xa9, 0xac, 0x3e, 0xb1, 0xc, 0xad, 0x4, 0xf0, 0x95, 0x98, 0xd2, 0x6, 0x68, 0xec, 0x60, 0xa9, 0xac, 0x52, 0xb2, 0x6a, 0xf3, 0x92, 0x3d, 0x9a, 0xdf, 0x2f, 0x39, 0x20, 0xf7, 0xb9, 0x7d, 0x6e, 0xbf, 0xcf, 0x62, 0xea, 0xaa, 0x96, 0x24, 0x69, 0xce, 0xbe, 0xd9, 0x55, 0x4d, 0xef, 0x5b, 0xd8, 0xbb, 0x90, 0x9a, 0xa6, 0x39, 0x21, 0xf6, 0x5d, 0xb5, 0x77, 0xa9, 0x8a, 0x7, 0x35, 0xd5, 0xc0, 0x19, 0x32, 0x9f, 0xcf, 0x1b, 0x10, 0x3d, 0x9c, 0x1, 0x20, 0x2, 0x6, 0x84, 0xbf, 0x24, 0x9a, 0x44, 0x73, 0xac, 0x80, 0x4e, 0x80, 0x5c, 0x4e, 0x28, 0x60, 0x2, 0xc9, 0x3d, 0xa8, 0x40, 0x25, 0xe6, 0x0, 0xe, 0xe4, 0x2, 0x51, 0x1c, 0x2, 0x40, 0x5, 0x82, 0xa4, 0x2c, 0x3c, 0x76, 0xc3, 0x12, 0x51, 0xfb, 0x9e, 0xba, 0xdb, 0x3b, 0x6c, 0x2a, 0x45, 0xd8, 0xaf, 0x3c, 0x86, 0x3e, 0x57, 0x31, 0xc7, 0x7e, 0x98, 0x51, 0x25, 0x39, 0xca, 0x15, 0x1a, 0x3, 0x2, 0x8f, 0xc0, 0x70, 0xa, 0x20, 0x1c, 0x2f, 0x10, 0x87, 0x2f, 0x1c, 0x66, 0xec, 0xe, 0x1b, 0x33, 0x81, 0xd, 0x99, 0xc0, 0x55, 0xfd, 0x8, 0x5e, 0x4a, 0xe0, 0x82, 0x1b, 0xf3, 0x68, 0xc, 0x62, 0x7e, 0xaf, 0x4d, 0xdf, 0x79, 0x15, 0xf2, 0x30, 0xe3, 0xfa, 0x1b, 0xab, 0xc3, 0x3d, 0x59, 0xe3, 0x99, 0xa0, 0xe4, 0xf7, 0xbc, 0xb6, 0xd6, 0xa4, 0x97, 0x65, 0xc6, 0x63, 0xf7, 0xd6, 0x66, 0x62, 0x1f, 0x9f, 0xe9, 0x5, 0x30, 0x72, 0xef, 0xe2, 0x8c, 0xf9, 0xf3, 0x83, 0x23, 0xbd, 0x3e, 0xf, 0x2c, 0x6e, 0xbb, 0xf7, 0xff, 0x5, 0x5f, 0xfe, 0xb3, 0x14, 0x31, 0xf4, 0x31, 0x33, 0xfa, 0x41, 0xd3, 0xe9, 0xe7, 0x22, 0x6, 0x0, 0xb4, 0xb3, 0x74, 0xef, 0x4f, 0xde, 0x59, 0x95, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82 + 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x40, 0x8, 0x3, 0x0, 0x0, 0x0, 0x24, 0xa3, 0x7, 0xa4, 0x0, 0x0, 0x1, 0x5f, 0x50, 0x4c, 0x54, 0x45, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xb2, 0xb2, 0xcc, 0xae, 0xa0, 0xbb, 0x9c, 0x92, 0xa6, 0x9a, 0x91, 0xa4, 0x95, 0x8c, 0x9e, 0xaf, 0x9f, 0xaf, 0xa0, 0x94, 0xa5, 0x8e, 0x84, 0x95, 0x7f, 0x75, 0x84, 0x73, 0x6a, 0x78, 0x6d, 0x64, 0x72, 0xa2, 0xa2, 0xb9, 0x9c, 0x90, 0xa2, 0x8b, 0x81, 0x90, 0xdc, 0xda, 0xce, 0xe2, 0xe1, 0xd2, 0x9d, 0x91, 0xa9, 0x85, 0x7c, 0x8c, 0xdb, 0xd9, 0xce, 0xdb, 0xd9, 0xcd, 0xda, 0xce, 0xe0, 0xde, 0xd5, 0xe3, 0xdf, 0xd6, 0xe4, 0x97, 0x8d, 0xa0, 0x7a, 0x70, 0x7f, 0xdb, 0xd0, 0xdf, 0xdb, 0xd0, 0xe1, 0xda, 0xd0, 0xe1, 0x70, 0x67, 0x75, 0xd8, 0xcb, 0xde, 0xda, 0xcf, 0xdf, 0xdb, 0xce, 0xe1, 0xdb, 0xcf, 0xe1, 0xdb, 0xd0, 0xe0, 0xda, 0xcf, 0xe0, 0xd8, 0xcc, 0xde, 0x90, 0x87, 0x99, 0x6d, 0x67, 0x72, 0xd7, 0xcc, 0xdf, 0xda, 0xce, 0xdf, 0xd8, 0xcb, 0xdf, 0xd7, 0xca, 0xde, 0xd9, 0xcc, 0xdf, 0xd9, 0xcd, 0xdf, 0xd6, 0xc9, 0xdd, 0xd9, 0xcd, 0xde, 0xd6, 0xc8, 0xdc, 0xd5, 0xc8, 0xdc, 0xd7, 0xcb, 0xdd, 0xd7, 0xca, 0xdd, 0xd5, 0xc7, 0xdc, 0xd3, 0xc6, 0xdb, 0xd5, 0xc9, 0xdc, 0xd5, 0xc9, 0xdd, 0xd6, 0xc9, 0xdc, 0xd4, 0xc6, 0xdb, 0xd3, 0xc5, 0xdb, 0xd5, 0xc8, 0xdb, 0xd4, 0xc8, 0xdc, 0xd3, 0xc4, 0xd9, 0xd4, 0xc6, 0xda, 0xd2, 0xc3, 0xd9, 0xd3, 0xc5, 0xda, 0xd2, 0xc5, 0xd9, 0xd3, 0xc5, 0xd9, 0xd2, 0xc5, 0xda, 0xd1, 0xc2, 0xd9, 0xd2, 0xc4, 0xd8, 0xd2, 0xc4, 0xd9, 0xd0, 0xc2, 0xd9, 0xd0, 0xc1, 0xd7, 0xd0, 0xc2, 0xd7, 0xd0, 0xc2, 0xd8, 0xd1, 0xc2, 0xd7, 0xcf, 0xc1, 0xd7, 0xd0, 0xc2, 0xd6, 0xcf, 0xc1, 0xd6, 0xcf, 0xc2, 0xd7, 0xcf, 0xc0, 0xd7, 0xce, 0xbf, 0xd6, 0xce, 0xc0, 0xd5, 0xce, 0xc0, 0xd6, 0xce, 0xbf, 0xd5, 0xcd, 0xbf, 0xd5, 0xcd, 0xbe, 0xd5, 0xcd, 0xbe, 0xd4, 0xcc, 0xbd, 0xd5, 0xcc, 0xbd, 0xd4, 0xcc, 0xbc, 0xd4, 0x47, 0x40, 0x4a, 0x1d, 0x1a, 0x1f, 0x69, 0x5f, 0x6f, 0x4a, 0x42, 0x4f, 0x5e, 0x54, 0x63, 0x3b, 0x34, 0x3f, 0x5e, 0x55, 0x63, 0x63, 0x59, 0x67, 0x77, 0x6d, 0x7b, 0x6d, 0x62, 0x73, 0x7f, 0x76, 0x85, 0xdb, 0xd9, 0xcd, 0xdb, 0xd8, 0xcd, 0x6d, 0x62, 0x74, 0x8f, 0x84, 0x94, 0x7f, 0x76, 0x83, 0xdb, 0xd8, 0xcd, 0xa4, 0x95, 0xa4, 0x7e, 0x74, 0x84, 0x74, 0x6b, 0x79, 0x6f, 0x66, 0x74, 0x96, 0x8a, 0xa2, 0x91, 0x88, 0x9b, 0x0, 0x0, 0x0, 0xaa, 0xaa, 0xaa, 0xbf, 0xbf, 0xbf, 0xf0, 0xc9, 0xec, 0x71, 0x0, 0x0, 0x0, 0x75, 0x74, 0x52, 0x4e, 0x53, 0x1, 0x3, 0xa, 0x13, 0x1a, 0x1c, 0x1d, 0x10, 0x2b, 0x4d, 0x64, 0x6e, 0x72, 0xb, 0x2c, 0x6a, 0xfc, 0xff, 0x15, 0x52, 0xfd, 0xff, 0xe2, 0xe2, 0xe2, 0x1b, 0x68, 0xe2, 0xe2, 0xe2, 0x71, 0xe2, 0xe2, 0xe2, 0xe2, 0xe2, 0xe2, 0xe2, 0x1e, 0x72, 0xe2, 0xe2, 0xe2, 0xe2, 0xe2, 0xe2, 0xe2, 0xe2, 0xe2, 0xe2, 0xe2, 0xe2, 0xe2, 0xe2, 0xe2, 0xe2, 0xe2, 0xe2, 0xe2, 0xe2, 0xe2, 0xe2, 0xe2, 0xe2, 0xe2, 0xe2, 0xe2, 0xe2, 0xe2, 0xe2, 0xe2, 0xe2, 0xe2, 0xe2, 0xe2, 0xe2, 0xe2, 0xe2, 0xe2, 0xe2, 0xe2, 0xe2, 0xe2, 0xe2, 0xe2, 0xe2, 0xe2, 0xe2, 0xe2, 0xe2, 0xe2, 0xc7, 0xc7, 0xc7, 0xc7, 0xc7, 0xc7, 0xc7, 0xc7, 0x6b, 0xc7, 0x56, 0xfe, 0xff, 0xc7, 0x30, 0x74, 0xfe, 0x11, 0x57, 0x6d, 0x72, 0x16, 0x1c, 0x0, 0x3, 0x4, 0x35, 0xf5, 0x4, 0x26, 0x0, 0x0, 0x1, 0x16, 0x49, 0x44, 0x41, 0x54, 0x78, 0xda, 0xed, 0xcc, 0xc5, 0x61, 0x95, 0x61, 0x10, 0x85, 0xe1, 0xf7, 0x8c, 0x5c, 0xc3, 0xdd, 0x65, 0x4d, 0xea, 0xc8, 0x6, 0xdb, 0x63, 0xab, 0x74, 0x90, 0x42, 0xe8, 0x20, 0x5b, 0x3a, 0xa0, 0x12, 0xaa, 0xc0, 0x25, 0xd7, 0xe5, 0x1f, 0xec, 0xc3, 0xa5, 0x82, 0x9c, 0xdd, 0x79, 0x46, 0x84, 0xbe, 0x4, 0xa8, 0x2f, 0x91, 0x7a, 0xbf, 0xc0, 0x52, 0x47, 0x5a, 0xa5, 0x51, 0xe4, 0x6f, 0x27, 0xd1, 0xd7, 0x6c, 0x24, 0x15, 0xa0, 0xaa, 0xe9, 0xb0, 0xec, 0x75, 0x10, 0x51, 0x9, 0xbd, 0xde, 0x60, 0x44, 0xbc, 0xb6, 0xeb, 0x43, 0x86, 0xc, 0x56, 0x3d, 0x96, 0xfb, 0x99, 0xc, 0xaf, 0xfb, 0xfe, 0xd4, 0x8f, 0xf5, 0xf3, 0xc3, 0x72, 0xb3, 0x39, 0x67, 0xec, 0xbf, 0x3b, 0x12, 0x80, 0x97, 0x9d, 0x3, 0xc0, 0x81, 0x0, 0xec, 0x2d, 0x3d, 0x96, 0x3d, 0x96, 0x27, 0x1a, 0xe8, 0x14, 0xa8, 0x54, 0x58, 0x83, 0x10, 0x48, 0x55, 0xa6, 0x6, 0x29, 0xa6, 0x0, 0x87, 0xba, 0x6, 0x2e, 0x8e, 0x0, 0xa0, 0x6, 0x26, 0xa9, 0x13, 0xe5, 0x6b, 0xc0, 0x80, 0xcc, 0x8c, 0xea, 0xb2, 0xd6, 0x83, 0xef, 0x4f, 0x25, 0x87, 0x91, 0xba, 0xb6, 0x11, 0x74, 0x96, 0xde, 0xf3, 0xae, 0x6d, 0x90, 0x3d, 0x15, 0xea, 0x12, 0xd1, 0x0, 0x41, 0x39, 0xd0, 0xc0, 0x4, 0x88, 0xa2, 0x1a, 0xb8, 0x0, 0xe0, 0x3b, 0xd8, 0x7f, 0xc1, 0xf8, 0x25, 0x7, 0xf0, 0x4b, 0x3b, 0x80, 0xb8, 0xae, 0x17, 0x56, 0xad, 0x18, 0x97, 0xca, 0x98, 0xa1, 0xd6, 0x11, 0x33, 0x6c, 0x7f, 0x1b, 0xe3, 0xfb, 0xc6, 0xf6, 0xbe, 0xf7, 0xb6, 0xb6, 0x2c, 0x3b, 0xa, 0xb3, 0xbe, 0x6e, 0xe8, 0x59, 0xac, 0x42, 0x7a, 0xd2, 0x36, 0xee, 0x57, 0xad, 0x62, 0xec, 0x1b, 0x7f, 0xa4, 0x3d, 0x60, 0xa7, 0x6a, 0xed, 0x63, 0xa1, 0xc3, 0x3b, 0x7a, 0xa, 0xc0, 0xad, 0xda, 0x1b, 0x57, 0xec, 0xf2, 0xd8, 0x75, 0x17, 0x0, 0x6a, 0x7f, 0x97, 0x8f, 0x54, 0xa2, 0x67, 0xc8, 0xba, 0xb8, 0x46, 0x24, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82 }; static const unsigned char graph_port_png[] = { - 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0xa, 0x0, 0x0, 0x0, 0xa, 0x8, 0x4, 0x0, 0x0, 0x0, 0x27, 0x3b, 0x7, 0x36, 0x0, 0x0, 0x0, 0x72, 0x49, 0x44, 0x41, 0x54, 0x78, 0xda, 0x65, 0xce, 0x41, 0xa, 0x83, 0x30, 0x10, 0x85, 0xe1, 0xb9, 0x98, 0xe2, 0x9, 0x3c, 0x50, 0xe9, 0xc6, 0x83, 0x45, 0x7b, 0x8b, 0xfc, 0x7a, 0x1, 0xd7, 0x49, 0xba, 0xd, 0xd3, 0x79, 0xd0, 0x16, 0x41, 0xfe, 0x6c, 0xe6, 0x83, 0xc0, 0x33, 0x8f, 0xf2, 0xc4, 0xc6, 0x3b, 0x5a, 0x99, 0x75, 0xc7, 0xe3, 0x49, 0xc7, 0x7f, 0xe5, 0x25, 0x30, 0x4f, 0xa2, 0xd3, 0x6b, 0x74, 0x8a, 0xfb, 0x31, 0x1a, 0x2f, 0x51, 0xfb, 0x26, 0x66, 0x35, 0x1a, 0x5e, 0xff, 0x58, 0x84, 0xd5, 0xa8, 0x37, 0x2c, 0xc6, 0x76, 0xfb, 0x9e, 0x8c, 0x19, 0x17, 0x97, 0x48, 0x44, 0xdf, 0x7, 0xad, 0x5c, 0x2e, 0x93, 0x7a, 0x7e, 0x68, 0x67, 0x74, 0x8c, 0x24, 0x1a, 0x95, 0xb4, 0xf, 0xba, 0x3f, 0x56, 0x94, 0xa6, 0x72, 0xc9, 0xf9, 0xda, 0xf8, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82 + 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0xa, 0x0, 0x0, 0x0, 0xa, 0x8, 0x4, 0x0, 0x0, 0x0, 0x27, 0x3b, 0x7, 0x36, 0x0, 0x0, 0x0, 0x6e, 0x49, 0x44, 0x41, 0x54, 0x78, 0xda, 0x65, 0x8e, 0xc1, 0xd, 0xc2, 0x30, 0x10, 0x4, 0xb7, 0x31, 0x22, 0x2a, 0x48, 0x41, 0x88, 0x4f, 0xa, 0x73, 0x42, 0x17, 0x1e, 0xd2, 0x40, 0xde, 0x3e, 0xf3, 0xb5, 0x8c, 0x8f, 0x13, 0x8, 0x29, 0x3b, 0xbf, 0xd1, 0x9e, 0xf6, 0xe4, 0xc9, 0x57, 0x36, 0x5e, 0x83, 0x95, 0x59, 0x11, 0xee, 0x34, 0xfa, 0x97, 0xbc, 0x44, 0x6b, 0xa8, 0xa3, 0xdb, 0xe0, 0x70, 0xdd, 0xf6, 0x49, 0x3c, 0x5c, 0xd5, 0x20, 0xf4, 0x2a, 0x2a, 0xdd, 0x7e, 0xb2, 0xb8, 0x34, 0x61, 0x27, 0x59, 0xc4, 0x76, 0x3a, 0x4f, 0x62, 0xa6, 0xbb, 0x2e, 0x83, 0x18, 0x7a, 0x5e, 0x7c, 0x7f, 0xf9, 0x7b, 0xa9, 0xe5, 0x9b, 0x22, 0xfb, 0x44, 0xa2, 0x62, 0xa4, 0x4f, 0x4b, 0x6f, 0x69, 0x3b, 0x9a, 0x7e, 0xcd, 0xde, 0x94, 0x27, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82 }; static const unsigned char hseparator_png[] = { @@ -167,7 +167,7 @@ static const unsigned char icon_snap_grid_png[] = { }; static const unsigned char icon_visibility_png[] = { - 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x10, 0x8, 0x3, 0x0, 0x0, 0x0, 0x28, 0x2d, 0xf, 0x53, 0x0, 0x0, 0x0, 0x3, 0x73, 0x42, 0x49, 0x54, 0x8, 0x8, 0x8, 0xdb, 0xe1, 0x4f, 0xe0, 0x0, 0x0, 0x0, 0x9, 0x70, 0x48, 0x59, 0x73, 0x0, 0x0, 0xe, 0xc4, 0x0, 0x0, 0xe, 0xc4, 0x1, 0x95, 0x2b, 0xe, 0x1b, 0x0, 0x0, 0x0, 0x19, 0x74, 0x45, 0x58, 0x74, 0x53, 0x6f, 0x66, 0x74, 0x77, 0x61, 0x72, 0x65, 0x0, 0x77, 0x77, 0x77, 0x2e, 0x69, 0x6e, 0x6b, 0x73, 0x63, 0x61, 0x70, 0x65, 0x2e, 0x6f, 0x72, 0x67, 0x9b, 0xee, 0x3c, 0x1a, 0x0, 0x0, 0x0, 0x96, 0x50, 0x4c, 0x54, 0x45, 0x0, 0x0, 0x0, 0xdf, 0xdf, 0xdf, 0xe3, 0xe3, 0xe3, 0xe6, 0xe6, 0xe6, 0xd5, 0xd5, 0xd5, 0xd8, 0xd8, 0xd8, 0xdb, 0xdb, 0xdb, 0xdd, 0xdd, 0xdd, 0xe1, 0xe1, 0xe1, 0xe3, 0xe3, 0xe3, 0xe4, 0xe4, 0xe4, 0xde, 0xde, 0xde, 0xde, 0xde, 0xde, 0xe0, 0xe0, 0xe0, 0xe1, 0xe1, 0xe1, 0xde, 0xde, 0xde, 0xdf, 0xdf, 0xdf, 0xdf, 0xdf, 0xdf, 0xdf, 0xdf, 0xdf, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xdf, 0xdf, 0xdf, 0xe0, 0xe0, 0xe0, 0xde, 0xde, 0xde, 0xde, 0xde, 0xde, 0xde, 0xde, 0xde, 0xde, 0xde, 0xde, 0xdf, 0xdf, 0xdf, 0xdf, 0xdf, 0xdf, 0xdf, 0xdf, 0xdf, 0xdf, 0xdf, 0xdf, 0xe0, 0xe0, 0xe0, 0xde, 0xde, 0xde, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe1, 0xe1, 0xe1, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe1, 0xe1, 0xe1, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xb7, 0x7e, 0xd, 0xb6, 0x0, 0x0, 0x0, 0x32, 0x74, 0x52, 0x4e, 0x53, 0x0, 0x8, 0x9, 0xa, 0xc, 0xd, 0xe, 0xf, 0x11, 0x12, 0x13, 0x2e, 0x2f, 0x32, 0x33, 0x36, 0x37, 0x38, 0x48, 0x49, 0x4b, 0x50, 0x53, 0x55, 0x56, 0x6c, 0x6d, 0x6e, 0x70, 0x77, 0x79, 0x7b, 0x7c, 0xc5, 0xd7, 0xd8, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf, 0xe1, 0xe2, 0xe3, 0xf0, 0xf2, 0xf3, 0xf4, 0xfe, 0x5e, 0x62, 0x1a, 0x26, 0x0, 0x0, 0x0, 0x86, 0x49, 0x44, 0x41, 0x54, 0x18, 0x19, 0x8d, 0xc1, 0xb, 0x16, 0x42, 0x40, 0x0, 0x86, 0xd1, 0x2f, 0xa2, 0x77, 0x2a, 0x85, 0xde, 0x91, 0x5e, 0x33, 0x8a, 0x7f, 0xff, 0x9b, 0xcb, 0x99, 0x63, 0x1, 0xee, 0xa5, 0x9f, 0xc1, 0x3e, 0x6f, 0xea, 0xfc, 0xe0, 0xd1, 0x99, 0xdd, 0xe5, 0x94, 0xb, 0x9c, 0xf9, 0x57, 0x26, 0x9, 0x82, 0x5d, 0xa1, 0xdf, 0x92, 0x96, 0xf7, 0x94, 0x99, 0xd0, 0x1a, 0x1b, 0x7d, 0x7c, 0xe0, 0x2c, 0x25, 0x6c, 0x2b, 0x1b, 0x93, 0x4a, 0x17, 0xa0, 0x94, 0x2, 0xac, 0x64, 0x8, 0xa5, 0x12, 0x78, 0x48, 0x1, 0x56, 0x32, 0x8c, 0xa4, 0x7, 0x70, 0x93, 0x76, 0xc4, 0xd6, 0x6c, 0xc8, 0xa4, 0x2b, 0x30, 0xac, 0x54, 0x8c, 0x69, 0x4d, 0xad, 0xcc, 0x90, 0xd6, 0xba, 0x91, 0x49, 0xc3, 0x30, 0xb3, 0x6a, 0x22, 0x9c, 0xd5, 0x5b, 0xce, 0x2b, 0xa2, 0xe3, 0x9f, 0xf2, 0xba, 0xce, 0x8f, 0x3e, 0xbd, 0xfc, 0x1, 0xdb, 0xf3, 0x10, 0xc5, 0x78, 0x85, 0x14, 0x89, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82 + 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x10, 0x8, 0x3, 0x0, 0x0, 0x0, 0x28, 0x2d, 0xf, 0x53, 0x0, 0x0, 0x0, 0x9, 0x70, 0x48, 0x59, 0x73, 0x0, 0x0, 0xe, 0xc4, 0x0, 0x0, 0xe, 0xc4, 0x1, 0x95, 0x2b, 0xe, 0x1b, 0x0, 0x0, 0x0, 0x3, 0x73, 0x42, 0x49, 0x54, 0x8, 0x8, 0x8, 0xdb, 0xe1, 0x4f, 0xe0, 0x0, 0x0, 0x0, 0x96, 0x50, 0x4c, 0x54, 0x45, 0x0, 0x0, 0x0, 0xdf, 0xdf, 0xdf, 0xe3, 0xe3, 0xe3, 0xe6, 0xe6, 0xe6, 0xd5, 0xd5, 0xd5, 0xd8, 0xd8, 0xd8, 0xdb, 0xdb, 0xdb, 0xdd, 0xdd, 0xdd, 0xe1, 0xe1, 0xe1, 0xe3, 0xe3, 0xe3, 0xe4, 0xe4, 0xe4, 0xde, 0xde, 0xde, 0xde, 0xde, 0xde, 0xe0, 0xe0, 0xe0, 0xe1, 0xe1, 0xe1, 0xde, 0xde, 0xde, 0xdf, 0xdf, 0xdf, 0xdf, 0xdf, 0xdf, 0xdf, 0xdf, 0xdf, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xdf, 0xdf, 0xdf, 0xe0, 0xe0, 0xe0, 0xde, 0xde, 0xde, 0xde, 0xde, 0xde, 0xde, 0xde, 0xde, 0xde, 0xde, 0xde, 0xdf, 0xdf, 0xdf, 0xdf, 0xdf, 0xdf, 0xdf, 0xdf, 0xdf, 0xdf, 0xdf, 0xdf, 0xe0, 0xe0, 0xe0, 0xde, 0xde, 0xde, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe1, 0xe1, 0xe1, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe1, 0xe1, 0xe1, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xb7, 0x7e, 0xd, 0xb6, 0x0, 0x0, 0x0, 0x32, 0x74, 0x52, 0x4e, 0x53, 0x0, 0x8, 0x9, 0xa, 0xc, 0xd, 0xe, 0xf, 0x11, 0x12, 0x13, 0x2e, 0x2f, 0x32, 0x33, 0x36, 0x37, 0x38, 0x48, 0x49, 0x4b, 0x50, 0x53, 0x55, 0x56, 0x6c, 0x6d, 0x6e, 0x70, 0x77, 0x79, 0x7b, 0x7c, 0xc5, 0xd7, 0xd8, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf, 0xe1, 0xe2, 0xe3, 0xf0, 0xf2, 0xf3, 0xf4, 0xfe, 0x5e, 0x62, 0x1a, 0x26, 0x0, 0x0, 0x0, 0x83, 0x49, 0x44, 0x41, 0x54, 0x78, 0xda, 0x8d, 0xc8, 0x45, 0x42, 0x3, 0x1, 0x0, 0xc0, 0xc0, 0xd4, 0x8b, 0x43, 0x1d, 0x5f, 0x77, 0xcb, 0xff, 0x1f, 0x87, 0xd3, 0xf3, 0xe6, 0x36, 0x61, 0x5c, 0x93, 0xc7, 0x70, 0xe8, 0xc3, 0xa7, 0xe9, 0xbf, 0xaf, 0x62, 0x55, 0x4d, 0x6e, 0x7e, 0x7d, 0xdd, 0x5a, 0x1d, 0x16, 0x8b, 0x7d, 0x64, 0x77, 0xfb, 0xed, 0x69, 0x66, 0x75, 0x1, 0xb0, 0xae, 0x2c, 0x67, 0xc0, 0xab, 0x1e, 0xd8, 0x35, 0xf5, 0x96, 0xa3, 0xbe, 0x1, 0x89, 0x2e, 0xa8, 0xb5, 0x62, 0xa9, 0x9, 0x90, 0x9e, 0xc7, 0x4a, 0x53, 0x20, 0xd0, 0x3d, 0xdb, 0xba, 0xda, 0x70, 0xd2, 0x77, 0x60, 0xde, 0x18, 0xad, 0x1, 0x2e, 0x6b, 0xab, 0x39, 0xc0, 0xc3, 0x60, 0x75, 0x5c, 0x2e, 0x4f, 0xb5, 0xc3, 0x1d, 0x3f, 0xdd, 0x17, 0xaa, 0x9a, 0xff, 0x19, 0x66, 0x2f, 0x61, 0xdf, 0x87, 0xcf, 0x33, 0x46, 0xf5, 0x9, 0xdb, 0xf3, 0x10, 0xc5, 0x55, 0x93, 0xc, 0xea, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82 }; static const unsigned char icon_zoom_less_png[] = { @@ -211,7 +211,7 @@ static const unsigned char option_button_hover_png[] = { }; static const unsigned char option_button_normal_png[] = { - 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0x20, 0x0, 0x0, 0x0, 0x10, 0x8, 0x3, 0x0, 0x0, 0x0, 0x40, 0xde, 0x8d, 0x6b, 0x0, 0x0, 0x1, 0x41, 0x50, 0x4c, 0x54, 0x45, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x3c, 0x3a, 0x44, 0x56, 0x53, 0x61, 0x2b, 0x2b, 0x31, 0x2e, 0x2e, 0x34, 0x56, 0x52, 0x60, 0x2a, 0x2a, 0x30, 0x47, 0x44, 0x52, 0x22, 0x22, 0x27, 0x33, 0x31, 0x39, 0x47, 0x44, 0x50, 0x24, 0x24, 0x28, 0x24, 0x24, 0x29, 0x52, 0x50, 0x5d, 0x51, 0x4f, 0x5d, 0x5d, 0x5a, 0x6a, 0x2a, 0x2a, 0x31, 0x2a, 0x2a, 0x30, 0x2d, 0x2d, 0x34, 0x2f, 0x2f, 0x36, 0x2e, 0x2e, 0x35, 0x2c, 0x2c, 0x32, 0x46, 0x42, 0x4e, 0x42, 0x3e, 0x4a, 0x41, 0x3e, 0x49, 0x51, 0x4e, 0x5b, 0x26, 0x26, 0x2b, 0x24, 0x24, 0x28, 0x27, 0x27, 0x2d, 0x29, 0x29, 0x2f, 0x28, 0x28, 0x2e, 0x25, 0x25, 0x2b, 0x23, 0x23, 0x28, 0x40, 0x3e, 0x48, 0x50, 0x4e, 0x5a, 0x26, 0x26, 0x2c, 0x25, 0x25, 0x2a, 0x2a, 0x2a, 0x2f, 0x2b, 0x2b, 0x31, 0x22, 0x22, 0x26, 0x4f, 0x4c, 0x59, 0x3f, 0x3d, 0x47, 0x2d, 0x2d, 0x33, 0x22, 0x22, 0x27, 0x4e, 0x4a, 0x58, 0x3e, 0x3b, 0x46, 0x27, 0x27, 0x2b, 0x2e, 0x2e, 0x34, 0x2c, 0x2c, 0x31, 0x29, 0x29, 0x2e, 0x4b, 0x49, 0x55, 0x3c, 0x3a, 0x44, 0x4a, 0x47, 0x54, 0x3b, 0x39, 0x43, 0x24, 0x24, 0x2a, 0x24, 0x24, 0x29, 0x20, 0x20, 0x25, 0x49, 0x46, 0x53, 0x3a, 0x38, 0x42, 0x28, 0x28, 0x2d, 0x2b, 0x2b, 0x30, 0x29, 0x29, 0x2d, 0x20, 0x20, 0x23, 0x47, 0x45, 0x50, 0x39, 0x37, 0x40, 0x22, 0x22, 0x28, 0x27, 0x27, 0x2c, 0x1e, 0x1e, 0x22, 0x47, 0x43, 0x50, 0x38, 0x35, 0x3f, 0x46, 0x42, 0x4f, 0x21, 0x21, 0x26, 0x21, 0x21, 0x25, 0x23, 0x23, 0x27, 0x20, 0x20, 0x24, 0x1d, 0x1d, 0x21, 0x36, 0x34, 0x3e, 0x44, 0x41, 0x4e, 0x1f, 0x1f, 0x24, 0x1f, 0x1f, 0x23, 0x1e, 0x1e, 0x21, 0x44, 0x42, 0x4d, 0x44, 0x41, 0x4c, 0x4e, 0x4b, 0x58, 0x8, 0xd9, 0x10, 0xcb, 0x0, 0x0, 0x0, 0x24, 0x74, 0x52, 0x4e, 0x53, 0x0, 0x4, 0xa, 0x11, 0x19, 0x1f, 0x22, 0x24, 0x1d, 0x16, 0xd, 0x7, 0x2, 0x15, 0x25, 0x34, 0x3f, 0x46, 0x47, 0x48, 0x43, 0x3a, 0x2d, 0x1b, 0x77, 0xef, 0xe6, 0x49, 0xef, 0xe6, 0xef, 0xe7, 0x77, 0xef, 0xe4, 0x4a, 0xba, 0xea, 0xc1, 0xeb, 0x0, 0x0, 0x0, 0xe7, 0x49, 0x44, 0x41, 0x54, 0x78, 0xda, 0x6c, 0x91, 0x53, 0x62, 0x5, 0x41, 0x14, 0x44, 0xab, 0x46, 0xb1, 0x6d, 0x67, 0x3, 0x59, 0x44, 0x16, 0x9e, 0xdf, 0xe8, 0x2f, 0xb6, 0xcd, 0xe7, 0x61, 0xe3, 0x3e, 0x4e, 0xb5, 0x2e, 0x4e, 0xdb, 0xa3, 0x11, 0x80, 0xc4, 0x51, 0xc6, 0x3f, 0x5a, 0xe5, 0xb1, 0x4f, 0x8, 0xd5, 0xff, 0x15, 0xd1, 0x26, 0xba, 0x7d, 0xbd, 0xec, 0xa3, 0x75, 0x94, 0x24, 0x11, 0xbb, 0xe1, 0x2f, 0x1f, 0xe0, 0x91, 0xde, 0x8, 0xf3, 0x1, 0xe, 0x3d, 0x42, 0x1, 0xe3, 0x49, 0xf, 0x1a, 0xc0, 0xb7, 0xb5, 0x47, 0x92, 0x52, 0xb7, 0x3b, 0x79, 0xa7, 0x80, 0x21, 0xc2, 0x2a, 0xa9, 0x15, 0x8b, 0x8e, 0x1c, 0x2e, 0x64, 0x71, 0x4, 0xd0, 0x5b, 0x34, 0x80, 0xa0, 0x34, 0x29, 0xab, 0xd5, 0x7a, 0xfb, 0x5e, 0xc2, 0x51, 0xc0, 0x3, 0x83, 0x6, 0x10, 0xa2, 0xa1, 0x62, 0x1f, 0xf0, 0xae, 0x0, 0x38, 0xd, 0xe0, 0x67, 0xfe, 0xe9, 0xb, 0x72, 0x86, 0xb7, 0x5, 0x46, 0xa, 0x48, 0xfc, 0xa6, 0x15, 0x1e, 0x96, 0xc5, 0x79, 0x99, 0xbe, 0x78, 0x59, 0x2c, 0x1, 0x5e, 0x92, 0x34, 0x6d, 0xb1, 0xf9, 0xda, 0x75, 0x66, 0x6d, 0xfa, 0xf3, 0x5, 0x7f, 0x58, 0x3, 0x8d, 0x15, 0xc8, 0x85, 0xf3, 0xd, 0x6b, 0x1f, 0xdf, 0x6e, 0x8c, 0x33, 0xd4, 0xc0, 0xce, 0xd6, 0xa8, 0x0, 0xd5, 0x20, 0xbc, 0xb5, 0xf6, 0xc2, 0x68, 0xb6, 0xf4, 0x8d, 0x6, 0x9c, 0xc3, 0x6d, 0x5a, 0x60, 0xf, 0x53, 0x7d, 0x72, 0x86, 0x6a, 0xf4, 0xf1, 0xed, 0x1, 0x74, 0x5a, 0x3f, 0xab, 0x94, 0xee, 0x3f, 0x7a, 0x64, 0x11, 0x8a, 0x6e, 0x0, 0x80, 0xdd, 0x4f, 0x5c, 0xe, 0xd7, 0x26, 0x1c, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82 + 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0x20, 0x0, 0x0, 0x0, 0x10, 0x8, 0x3, 0x0, 0x0, 0x0, 0x40, 0xde, 0x8d, 0x6b, 0x0, 0x0, 0x1, 0x41, 0x50, 0x4c, 0x54, 0x45, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x3c, 0x3a, 0x44, 0x56, 0x53, 0x61, 0x2b, 0x2b, 0x31, 0x2e, 0x2e, 0x34, 0x56, 0x52, 0x60, 0x2a, 0x2a, 0x30, 0x47, 0x44, 0x52, 0x22, 0x22, 0x27, 0x33, 0x31, 0x39, 0x47, 0x44, 0x50, 0x24, 0x24, 0x28, 0x24, 0x24, 0x29, 0x52, 0x50, 0x5d, 0x51, 0x4f, 0x5d, 0x5d, 0x5a, 0x6a, 0x2a, 0x2a, 0x31, 0x2a, 0x2a, 0x30, 0x2d, 0x2d, 0x34, 0x2f, 0x2f, 0x36, 0x2e, 0x2e, 0x35, 0x2c, 0x2c, 0x32, 0x46, 0x42, 0x4e, 0x42, 0x3e, 0x4a, 0x41, 0x3e, 0x49, 0x51, 0x4e, 0x5b, 0x26, 0x26, 0x2b, 0x24, 0x24, 0x28, 0x27, 0x27, 0x2d, 0x29, 0x29, 0x2f, 0x28, 0x28, 0x2e, 0x25, 0x25, 0x2b, 0x23, 0x23, 0x28, 0x40, 0x3e, 0x48, 0x50, 0x4e, 0x5a, 0x26, 0x26, 0x2c, 0x25, 0x25, 0x2a, 0x2a, 0x2a, 0x2f, 0x2b, 0x2b, 0x31, 0x22, 0x22, 0x26, 0x4f, 0x4c, 0x59, 0x3f, 0x3d, 0x47, 0x2d, 0x2d, 0x33, 0x22, 0x22, 0x27, 0x4e, 0x4a, 0x58, 0x3e, 0x3b, 0x46, 0x27, 0x27, 0x2b, 0x2e, 0x2e, 0x34, 0x2c, 0x2c, 0x31, 0x29, 0x29, 0x2e, 0x4b, 0x49, 0x55, 0x3c, 0x3a, 0x44, 0x4a, 0x47, 0x54, 0x3b, 0x39, 0x43, 0x24, 0x24, 0x2a, 0x24, 0x24, 0x29, 0x20, 0x20, 0x25, 0x49, 0x46, 0x53, 0x3a, 0x38, 0x42, 0x28, 0x28, 0x2d, 0x2b, 0x2b, 0x30, 0x29, 0x29, 0x2d, 0x20, 0x20, 0x23, 0x47, 0x45, 0x50, 0x39, 0x37, 0x40, 0x22, 0x22, 0x28, 0x27, 0x27, 0x2c, 0x1e, 0x1e, 0x22, 0x47, 0x43, 0x50, 0x38, 0x35, 0x3f, 0x46, 0x42, 0x4f, 0x21, 0x21, 0x26, 0x21, 0x21, 0x25, 0x23, 0x23, 0x27, 0x20, 0x20, 0x24, 0x1d, 0x1d, 0x21, 0x36, 0x34, 0x3e, 0x44, 0x41, 0x4e, 0x1f, 0x1f, 0x24, 0x1f, 0x1f, 0x23, 0x1e, 0x1e, 0x21, 0x44, 0x42, 0x4d, 0x44, 0x41, 0x4c, 0x4e, 0x4b, 0x58, 0x8, 0xd9, 0x10, 0xcb, 0x0, 0x0, 0x0, 0x24, 0x74, 0x52, 0x4e, 0x53, 0x0, 0x4, 0xa, 0x11, 0x19, 0x1f, 0x22, 0x24, 0x1d, 0x16, 0xd, 0x7, 0x2, 0x15, 0x25, 0x34, 0x3f, 0x46, 0x47, 0x48, 0x43, 0x3a, 0x2d, 0x1b, 0x77, 0xef, 0xe6, 0x49, 0xef, 0xe6, 0xef, 0xe7, 0x77, 0xef, 0xe4, 0x4a, 0xba, 0xea, 0xc1, 0xeb, 0x0, 0x0, 0x0, 0xe6, 0x49, 0x44, 0x41, 0x54, 0x78, 0xda, 0x6c, 0xd1, 0x55, 0x5a, 0xc4, 0x30, 0x14, 0x5, 0xe0, 0x73, 0xea, 0x82, 0xbb, 0x3b, 0x6c, 0x80, 0x45, 0xb0, 0x70, 0x5e, 0xb1, 0x37, 0xdc, 0x75, 0xdc, 0x3d, 0x43, 0x2a, 0x5f, 0x3a, 0x7e, 0x6a, 0xc9, 0xbd, 0x7f, 0x9d, 0x2a, 0x0, 0xa4, 0x16, 0xd, 0xaa, 0x18, 0x8e, 0x41, 0x3f, 0x11, 0xd1, 0xbe, 0x52, 0xc7, 0x48, 0xa8, 0xfb, 0x5e, 0x68, 0xd4, 0x24, 0x96, 0x6a, 0xfc, 0xaf, 0x8b, 0x32, 0xbf, 0x61, 0x90, 0xc6, 0x3c, 0x27, 0x3, 0xce, 0xfe, 0x20, 0x2, 0x4b, 0xd2, 0x45, 0x1f, 0x14, 0xd5, 0x78, 0x5e, 0x36, 0x1c, 0x7d, 0xe5, 0x33, 0x2, 0xb3, 0x84, 0x8a, 0xec, 0xd4, 0xeb, 0x9a, 0x1a, 0x1b, 0x82, 0xf5, 0x79, 0x20, 0x2, 0x46, 0x1f, 0x58, 0x8d, 0x95, 0xe4, 0x6a, 0x1d, 0xcf, 0x4f, 0x89, 0x85, 0x10, 0x80, 0x56, 0x1f, 0x8, 0xf4, 0x53, 0xf7, 0x81, 0x6c, 0x4, 0xa0, 0xf5, 0x41, 0x69, 0xeb, 0xb7, 0xd0, 0x7b, 0x86, 0xcc, 0x36, 0xbb, 0x11, 0x90, 0x66, 0x1f, 0x88, 0xef, 0xbd, 0x64, 0x92, 0x5a, 0x7b, 0x4e, 0xed, 0x34, 0x42, 0x20, 0xa5, 0xd5, 0x7, 0x27, 0x69, 0xfb, 0x51, 0x8d, 0x69, 0x6e, 0xd5, 0xcc, 0xb9, 0x18, 0xf4, 0xaf, 0x40, 0x6e, 0x3f, 0x1d, 0xab, 0xf1, 0xdd, 0xc7, 0xf1, 0x12, 0x45, 0xc, 0xce, 0x4f, 0x17, 0x12, 0xd0, 0xb6, 0xc4, 0x87, 0x1a, 0x6f, 0x2f, 0x48, 0x8b, 0xef, 0x31, 0xd0, 0x6e, 0xce, 0xa8, 0xc0, 0x25, 0x56, 0x7d, 0x5, 0x52, 0xed, 0x6e, 0xae, 0x68, 0x0, 0xd4, 0x86, 0x7f, 0x56, 0x43, 0x62, 0x38, 0xc, 0x46, 0x28, 0xba, 0x1, 0x7a, 0xad, 0x4f, 0x59, 0x90, 0xab, 0xbf, 0xa4, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82 }; static const unsigned char option_button_pressed_png[] = { @@ -279,7 +279,7 @@ static const unsigned char scroll_grabber_png[] = { }; static const unsigned char scroll_grabber_hl_png[] = { - 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0xc, 0x0, 0x0, 0x0, 0xc, 0x8, 0x3, 0x0, 0x0, 0x0, 0x61, 0xab, 0xac, 0xd5, 0x0, 0x0, 0x0, 0x69, 0x50, 0x4c, 0x54, 0x45, 0x0, 0x0, 0x0, 0x97, 0xd0, 0xdf, 0x92, 0xcb, 0xdc, 0x84, 0xbb, 0xd4, 0x92, 0xca, 0xdc, 0x95, 0xd0, 0xdd, 0x83, 0xbb, 0xd3, 0x8b, 0xc8, 0xd7, 0x79, 0xb5, 0xcb, 0x78, 0xb4, 0xca, 0x73, 0xb0, 0xc7, 0x73, 0xb0, 0xc7, 0x7b, 0xc0, 0xcf, 0x79, 0xc5, 0xd1, 0x6b, 0xae, 0xc1, 0x75, 0xc6, 0xcf, 0x70, 0xbc, 0xca, 0x64, 0xa6, 0xbc, 0x71, 0xbc, 0xc9, 0x82, 0xba, 0xd4, 0x6a, 0xa2, 0xc6, 0x62, 0x9a, 0xc2, 0x61, 0x9a, 0xc1, 0x68, 0x9f, 0xc2, 0x5d, 0x92, 0xbb, 0x5c, 0x92, 0xb8, 0x58, 0x8d, 0xb6, 0x59, 0x8e, 0xb3, 0x56, 0x89, 0xb0, 0x5c, 0x91, 0xb2, 0x53, 0x84, 0xa9, 0x58, 0x8f, 0xae, 0x54, 0x83, 0xa4, 0x57, 0x8e, 0xad, 0x64, 0xa5, 0xba, 0x17, 0x3b, 0xfc, 0x67, 0x0, 0x0, 0x0, 0x13, 0x74, 0x52, 0x4e, 0x53, 0x0, 0x25, 0xad, 0xf1, 0xad, 0x27, 0xef, 0xad, 0xf1, 0xf3, 0xf1, 0xf3, 0xad, 0x28, 0xef, 0x27, 0xad, 0xf2, 0xad, 0xcd, 0x8a, 0x27, 0xfe, 0x0, 0x0, 0x0, 0x49, 0x49, 0x44, 0x41, 0x54, 0x78, 0xda, 0x75, 0xc7, 0xa5, 0x1, 0x3, 0x1, 0x0, 0x4, 0xc1, 0xdd, 0xb, 0x9a, 0x60, 0xff, 0x3d, 0x6, 0x54, 0xe0, 0x59, 0x3d, 0x8f, 0x9b, 0xb0, 0x66, 0x3, 0x98, 0xdc, 0xff, 0x35, 0x20, 0xec, 0x3c, 0x6b, 0xf5, 0xae, 0xff, 0x6c, 0xda, 0xdc, 0x36, 0x31, 0xc7, 0x6f, 0xc9, 0x16, 0x8c, 0x40, 0x1d, 0xba, 0x64, 0x21, 0x42, 0xc0, 0x97, 0xc9, 0xe6, 0x25, 0x8, 0x5c, 0xf4, 0xf6, 0x2c, 0x5f, 0x8c, 0x39, 0x4c, 0x3, 0xfe, 0x9a, 0x10, 0x43, 0x82, 0xcf, 0x27, 0x93, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82 + 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0xc, 0x0, 0x0, 0x0, 0xc, 0x8, 0x3, 0x0, 0x0, 0x0, 0x61, 0xab, 0xac, 0xd5, 0x0, 0x0, 0x0, 0x69, 0x50, 0x4c, 0x54, 0x45, 0x0, 0x0, 0x0, 0x97, 0xd0, 0xdf, 0x92, 0xcb, 0xdc, 0x84, 0xbb, 0xd4, 0x92, 0xca, 0xdc, 0x95, 0xd0, 0xdd, 0x83, 0xbb, 0xd3, 0x8b, 0xc8, 0xd7, 0x79, 0xb5, 0xcb, 0x78, 0xb4, 0xca, 0x73, 0xb0, 0xc7, 0x73, 0xb0, 0xc7, 0x7b, 0xc0, 0xcf, 0x79, 0xc5, 0xd1, 0x6b, 0xae, 0xc1, 0x75, 0xc6, 0xcf, 0x70, 0xbc, 0xca, 0x64, 0xa6, 0xbc, 0x71, 0xbc, 0xc9, 0x82, 0xba, 0xd4, 0x6a, 0xa2, 0xc6, 0x62, 0x9a, 0xc2, 0x61, 0x9a, 0xc1, 0x68, 0x9f, 0xc2, 0x5d, 0x92, 0xbb, 0x5c, 0x92, 0xb8, 0x58, 0x8d, 0xb6, 0x59, 0x8e, 0xb3, 0x56, 0x89, 0xb0, 0x5c, 0x91, 0xb2, 0x53, 0x84, 0xa9, 0x58, 0x8f, 0xae, 0x54, 0x83, 0xa4, 0x57, 0x8e, 0xad, 0x64, 0xa5, 0xba, 0x17, 0x3b, 0xfc, 0x67, 0x0, 0x0, 0x0, 0x13, 0x74, 0x52, 0x4e, 0x53, 0x0, 0x25, 0xad, 0xf1, 0xad, 0x27, 0xef, 0xad, 0xf1, 0xf3, 0xf1, 0xf3, 0xad, 0x28, 0xef, 0x27, 0xad, 0xf2, 0xad, 0xcd, 0x8a, 0x27, 0xfe, 0x0, 0x0, 0x0, 0x46, 0x49, 0x44, 0x41, 0x54, 0x78, 0xda, 0x7d, 0x8a, 0x25, 0x2, 0xc4, 0x40, 0x0, 0x3, 0x27, 0x39, 0x52, 0x57, 0xfa, 0xff, 0x1f, 0x17, 0x54, 0x19, 0x6d, 0x61, 0x4c, 0x90, 0x5b, 0x5e, 0x80, 0xec, 0x66, 0x58, 0x76, 0x3, 0x1f, 0x15, 0xd2, 0x9c, 0x97, 0x61, 0xf, 0xbf, 0x4a, 0xc0, 0x12, 0x3b, 0xde, 0xfb, 0xeb, 0x8, 0x66, 0xf, 0xbe, 0x8, 0x2, 0x83, 0x92, 0xec, 0x57, 0x12, 0x8, 0x28, 0xa5, 0x3a, 0x4e, 0x89, 0x7, 0x56, 0x51, 0x36, 0x11, 0x22, 0x4, 0xb, 0xcc, 0xf7, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82 }; static const unsigned char scroll_grabber_pressed_png[] = { @@ -295,7 +295,7 @@ static const unsigned char selection_oof_png[] = { }; static const unsigned char space_png[] = { - 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0x8, 0x0, 0x0, 0x0, 0x8, 0x8, 0x6, 0x0, 0x0, 0x0, 0xc4, 0xf, 0xbe, 0x8b, 0x0, 0x0, 0x0, 0x6, 0x62, 0x4b, 0x47, 0x44, 0x0, 0xff, 0x0, 0xff, 0x0, 0xff, 0xa0, 0xbd, 0xa7, 0x93, 0x0, 0x0, 0x0, 0x2f, 0x49, 0x44, 0x41, 0x54, 0x18, 0x95, 0x63, 0x60, 0xa0, 0x2a, 0xf8, 0xff, 0xff, 0xbf, 0xe0, 0xff, 0xff, 0xff, 0x5, 0x91, 0xc5, 0x58, 0x90, 0x24, 0x85, 0x18, 0x18, 0x18, 0x14, 0xa0, 0x6c, 0x6, 0x46, 0x46, 0xc6, 0xf7, 0xc, 0xc, 0xc, 0xc, 0x4c, 0x14, 0x5b, 0x41, 0x39, 0x0, 0x0, 0x71, 0x1a, 0x13, 0x5d, 0x87, 0xfe, 0x9e, 0x7d, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82 + 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0x8, 0x0, 0x0, 0x0, 0x8, 0x8, 0x4, 0x0, 0x0, 0x0, 0x6e, 0x6, 0x76, 0x0, 0x0, 0x0, 0x0, 0x2, 0x62, 0x4b, 0x47, 0x44, 0x0, 0xff, 0x87, 0x8f, 0xcc, 0xbf, 0x0, 0x0, 0x0, 0x1c, 0x49, 0x44, 0x41, 0x54, 0x78, 0xda, 0x63, 0x20, 0x16, 0xfc, 0x17, 0xfc, 0x2f, 0x88, 0xcc, 0x15, 0xfa, 0x6f, 0x4, 0x84, 0x82, 0x18, 0x2, 0xe8, 0x5a, 0x88, 0x4, 0x0, 0x8c, 0xa4, 0xd, 0x47, 0x8, 0xea, 0xcc, 0xbb, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82 }; static const unsigned char spinbox_updown_png[] = { @@ -319,15 +319,15 @@ static const unsigned char tab_close_png[] = { }; static const unsigned char tab_container_bg_png[] = { - 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x10, 0x8, 0x3, 0x0, 0x0, 0x0, 0x28, 0x2d, 0xf, 0x53, 0x0, 0x0, 0x0, 0x87, 0x50, 0x4c, 0x54, 0x45, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x3c, 0x3a, 0x44, 0x56, 0x53, 0x61, 0x56, 0x52, 0x60, 0x47, 0x44, 0x52, 0x33, 0x31, 0x39, 0x47, 0x44, 0x50, 0x47, 0x44, 0x51, 0x52, 0x50, 0x5d, 0x51, 0x4f, 0x5d, 0x46, 0x42, 0x4e, 0x42, 0x3e, 0x4a, 0x41, 0x3e, 0x49, 0x51, 0x4e, 0x5b, 0x40, 0x3e, 0x48, 0x4f, 0x4c, 0x59, 0x3f, 0x3d, 0x47, 0x4e, 0x4a, 0x58, 0x3e, 0x3b, 0x46, 0x4b, 0x49, 0x55, 0x3c, 0x3a, 0x44, 0x4a, 0x47, 0x54, 0x3b, 0x39, 0x43, 0x49, 0x46, 0x53, 0x3a, 0x38, 0x42, 0x47, 0x45, 0x50, 0x39, 0x37, 0x40, 0x47, 0x43, 0x50, 0x38, 0x35, 0x3f, 0x36, 0x34, 0x3e, 0x44, 0x42, 0x4d, 0x44, 0x41, 0x4c, 0x3f, 0x38, 0xaa, 0x5e, 0x0, 0x0, 0x0, 0x15, 0x74, 0x52, 0x4e, 0x53, 0x4, 0xa, 0x11, 0x19, 0x1f, 0x22, 0x24, 0x15, 0x25, 0x34, 0x3f, 0x46, 0x47, 0x48, 0x77, 0xef, 0xef, 0xef, 0x77, 0xef, 0xed, 0xe8, 0xff, 0x76, 0xed, 0x0, 0x0, 0x0, 0x65, 0x49, 0x44, 0x41, 0x54, 0x78, 0xda, 0x65, 0xcf, 0x45, 0x2, 0x84, 0x30, 0x14, 0x4, 0xd1, 0x2e, 0x1c, 0xee, 0x7f, 0xca, 0xd1, 0xed, 0x28, 0x8d, 0x4b, 0x92, 0x5a, 0xbe, 0xe8, 0x2f, 0xc4, 0x9c, 0x24, 0xcf, 0x15, 0x54, 0xab, 0x78, 0xee, 0x53, 0x30, 0x4a, 0x85, 0xa6, 0xfc, 0xf1, 0x87, 0x11, 0xb2, 0x9a, 0x15, 0x9a, 0x37, 0x13, 0x74, 0xce, 0xb4, 0xd4, 0x77, 0xcb, 0xe, 0xb4, 0x96, 0x99, 0x10, 0x34, 0x81, 0x42, 0x50, 0x21, 0x9d, 0x41, 0x23, 0xf8, 0xc, 0x56, 0xe1, 0x10, 0x9c, 0x40, 0x4e, 0xfe, 0x6e, 0x72, 0x96, 0x7e, 0xd7, 0xdf, 0x3f, 0xb3, 0x79, 0x90, 0xcd, 0xf1, 0xc4, 0x26, 0x1e, 0x8e, 0x78, 0xfc, 0x1, 0xf5, 0x61, 0x3f, 0x44, 0xe8, 0xf1, 0xdd, 0xba, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82 + 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x10, 0x8, 0x3, 0x0, 0x0, 0x0, 0x28, 0x2d, 0xf, 0x53, 0x0, 0x0, 0x0, 0x87, 0x50, 0x4c, 0x54, 0x45, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x3c, 0x3a, 0x44, 0x56, 0x53, 0x61, 0x56, 0x52, 0x60, 0x47, 0x44, 0x52, 0x33, 0x31, 0x39, 0x47, 0x44, 0x50, 0x47, 0x44, 0x51, 0x52, 0x50, 0x5d, 0x51, 0x4f, 0x5d, 0x46, 0x42, 0x4e, 0x42, 0x3e, 0x4a, 0x41, 0x3e, 0x49, 0x51, 0x4e, 0x5b, 0x40, 0x3e, 0x48, 0x4f, 0x4c, 0x59, 0x3f, 0x3d, 0x47, 0x4e, 0x4a, 0x58, 0x3e, 0x3b, 0x46, 0x4b, 0x49, 0x55, 0x3c, 0x3a, 0x44, 0x4a, 0x47, 0x54, 0x3b, 0x39, 0x43, 0x49, 0x46, 0x53, 0x3a, 0x38, 0x42, 0x47, 0x45, 0x50, 0x39, 0x37, 0x40, 0x47, 0x43, 0x50, 0x38, 0x35, 0x3f, 0x36, 0x34, 0x3e, 0x44, 0x42, 0x4d, 0x44, 0x41, 0x4c, 0x3f, 0x38, 0xaa, 0x5e, 0x0, 0x0, 0x0, 0x15, 0x74, 0x52, 0x4e, 0x53, 0x4, 0xa, 0x11, 0x19, 0x1f, 0x22, 0x24, 0x15, 0x25, 0x34, 0x3f, 0x46, 0x47, 0x48, 0x77, 0xef, 0xef, 0xef, 0x77, 0xef, 0xed, 0xe8, 0xff, 0x76, 0xed, 0x0, 0x0, 0x0, 0x63, 0x49, 0x44, 0x41, 0x54, 0x78, 0xda, 0x6d, 0xcf, 0x45, 0x2, 0x84, 0x30, 0x0, 0x4, 0xc1, 0x69, 0x1c, 0xfe, 0xff, 0xca, 0xd5, 0xeb, 0x2a, 0x83, 0x6b, 0xd2, 0xb7, 0x54, 0x1c, 0x31, 0x26, 0xc9, 0x63, 0x50, 0xcc, 0x32, 0x8d, 0x3f, 0xd9, 0x20, 0x5, 0x1a, 0xf2, 0xc7, 0x1f, 0x7a, 0x48, 0x4a, 0x66, 0xa8, 0xde, 0xc, 0xd0, 0x38, 0xd1, 0x54, 0xdb, 0x4c, 0x2b, 0xd0, 0x5c, 0x62, 0x8e, 0xa0, 0x1, 0x74, 0x4, 0x65, 0xd2, 0x1e, 0xd4, 0x83, 0xf7, 0x60, 0x65, 0x3e, 0x82, 0x3, 0x48, 0x49, 0xdf, 0x55, 0xca, 0xd4, 0xef, 0xfa, 0xfb, 0x27, 0x36, 0xf, 0x92, 0x31, 0x9e, 0x44, 0x3e, 0x17, 0x7c, 0xbf, 0x3, 0xef, 0x34, 0x3f, 0x3e, 0xe0, 0x24, 0x67, 0xb9, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82 }; static const unsigned char tab_current_png[] = { - 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x10, 0x8, 0x3, 0x0, 0x0, 0x0, 0x28, 0x2d, 0xf, 0x53, 0x0, 0x0, 0x0, 0x99, 0x50, 0x4c, 0x54, 0x45, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x3f, 0x3d, 0x48, 0x5b, 0x58, 0x66, 0x5b, 0x57, 0x65, 0x57, 0x54, 0x62, 0x55, 0x53, 0x62, 0x4a, 0x46, 0x52, 0x46, 0x41, 0x4e, 0x45, 0x41, 0x4d, 0x55, 0x52, 0x60, 0x44, 0x41, 0x4c, 0x53, 0x50, 0x5e, 0x43, 0x40, 0x4b, 0x52, 0x4e, 0x5d, 0x41, 0x3e, 0x4a, 0x4f, 0x4d, 0x5a, 0x3f, 0x3d, 0x48, 0x4e, 0x4b, 0x59, 0x3e, 0x3c, 0x47, 0x4d, 0x4a, 0x58, 0x3d, 0x3b, 0x46, 0x4b, 0x49, 0x54, 0x3c, 0x3a, 0x44, 0x4b, 0x47, 0x54, 0x3b, 0x39, 0x43, 0x3b, 0x39, 0x42, 0x3b, 0x38, 0x43, 0x3b, 0x38, 0x42, 0x3a, 0x37, 0x41, 0x39, 0x37, 0x41, 0x3a, 0x38, 0x41, 0x39, 0x36, 0x3f, 0x38, 0x36, 0x3f, 0x39, 0x36, 0x40, 0x38, 0x36, 0x40, 0x37, 0x35, 0x3e, 0x37, 0x34, 0x3e, 0x36, 0x35, 0x3d, 0xd7, 0x41, 0xa4, 0x19, 0x0, 0x0, 0x0, 0x11, 0x74, 0x52, 0x4e, 0x53, 0x4, 0xa, 0x11, 0x19, 0x1f, 0x22, 0x24, 0x15, 0x25, 0x34, 0x3f, 0x46, 0x47, 0x48, 0x77, 0xef, 0xef, 0xa3, 0x31, 0x6b, 0xc2, 0x0, 0x0, 0x0, 0x60, 0x49, 0x44, 0x41, 0x54, 0x78, 0xda, 0x55, 0xca, 0x85, 0xd, 0xc0, 0x40, 0x14, 0xc3, 0x50, 0x27, 0xf7, 0xd5, 0xfd, 0xd7, 0x2d, 0xa6, 0x4c, 0x16, 0x3f, 0xb9, 0xd0, 0x11, 0x90, 0xa3, 0x52, 0x77, 0x49, 0x8e, 0x86, 0xd2, 0x26, 0x16, 0x7b, 0x59, 0x32, 0x68, 0x3, 0x37, 0x5d, 0xe0, 0x59, 0x3b, 0x74, 0x31, 0x67, 0x4b, 0x3b, 0xf, 0x71, 0xe5, 0xe8, 0xf, 0xec, 0xc0, 0x1f, 0x28, 0xf8, 0x2, 0x14, 0xf9, 0x42, 0xa8, 0xfc, 0x21, 0x3b, 0xe4, 0x1, 0x6f, 0x0, 0x18, 0x11, 0xac, 0x99, 0xc0, 0xe, 0x25, 0x22, 0x2d, 0x76, 0xc6, 0x13, 0x1a, 0x8, 0xac, 0x78, 0xfc, 0x1c, 0x70, 0x30, 0x2b, 0xba, 0xe9, 0x31, 0x70, 0xc1, 0x7f, 0x3b, 0x77, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82 + 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x10, 0x8, 0x3, 0x0, 0x0, 0x0, 0x28, 0x2d, 0xf, 0x53, 0x0, 0x0, 0x0, 0x99, 0x50, 0x4c, 0x54, 0x45, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x3f, 0x3d, 0x48, 0x5b, 0x58, 0x66, 0x5b, 0x57, 0x65, 0x57, 0x54, 0x62, 0x55, 0x53, 0x62, 0x4a, 0x46, 0x52, 0x46, 0x41, 0x4e, 0x45, 0x41, 0x4d, 0x55, 0x52, 0x60, 0x44, 0x41, 0x4c, 0x53, 0x50, 0x5e, 0x43, 0x40, 0x4b, 0x52, 0x4e, 0x5d, 0x41, 0x3e, 0x4a, 0x4f, 0x4d, 0x5a, 0x3f, 0x3d, 0x48, 0x4e, 0x4b, 0x59, 0x3e, 0x3c, 0x47, 0x4d, 0x4a, 0x58, 0x3d, 0x3b, 0x46, 0x4b, 0x49, 0x54, 0x3c, 0x3a, 0x44, 0x4b, 0x47, 0x54, 0x3b, 0x39, 0x43, 0x3b, 0x39, 0x42, 0x3b, 0x38, 0x43, 0x3b, 0x38, 0x42, 0x3a, 0x37, 0x41, 0x39, 0x37, 0x41, 0x3a, 0x38, 0x41, 0x39, 0x36, 0x3f, 0x38, 0x36, 0x3f, 0x39, 0x36, 0x40, 0x38, 0x36, 0x40, 0x37, 0x35, 0x3e, 0x37, 0x34, 0x3e, 0x36, 0x35, 0x3d, 0xd7, 0x41, 0xa4, 0x19, 0x0, 0x0, 0x0, 0x11, 0x74, 0x52, 0x4e, 0x53, 0x4, 0xa, 0x11, 0x19, 0x1f, 0x22, 0x24, 0x15, 0x25, 0x34, 0x3f, 0x46, 0x47, 0x48, 0x77, 0xef, 0xef, 0xa3, 0x31, 0x6b, 0xc2, 0x0, 0x0, 0x0, 0x5f, 0x49, 0x44, 0x41, 0x54, 0x78, 0xda, 0x55, 0xca, 0x85, 0xd, 0xc0, 0x40, 0x14, 0xc3, 0x50, 0x27, 0xf7, 0xd5, 0xfd, 0xd7, 0x2d, 0xa6, 0x4c, 0x16, 0x3f, 0x59, 0xe8, 0x8, 0xc8, 0x91, 0xd4, 0x5d, 0x92, 0xa3, 0xa1, 0x76, 0xb1, 0xd8, 0xcb, 0x92, 0x41, 0x1b, 0xb8, 0xe9, 0x2, 0xcf, 0xd2, 0x7e, 0xc4, 0x9c, 0x2d, 0xed, 0x3c, 0xc4, 0x95, 0xa3, 0x3f, 0xb0, 0x3, 0x7f, 0xa0, 0xe0, 0xb, 0x50, 0xe4, 0xb, 0xa1, 0xf2, 0x87, 0x38, 0x31, 0x4f, 0x4e, 0xa, 0x30, 0x22, 0x58, 0x33, 0x81, 0x1d, 0x4a, 0x44, 0x5a, 0xec, 0x8c, 0x27, 0x34, 0x10, 0x58, 0xf1, 0xf8, 0x39, 0xe0, 0x60, 0x56, 0x63, 0x63, 0x30, 0x69, 0xf8, 0x3c, 0xb4, 0xd1, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82 }; static const unsigned char tab_disabled_png[] = { - 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x10, 0x8, 0x4, 0x0, 0x0, 0x0, 0xb5, 0xfa, 0x37, 0xea, 0x0, 0x0, 0x3, 0xa7, 0x7a, 0x54, 0x58, 0x74, 0x52, 0x61, 0x77, 0x20, 0x70, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x20, 0x74, 0x79, 0x70, 0x65, 0x20, 0x65, 0x78, 0x69, 0x66, 0x0, 0x0, 0x78, 0xda, 0xcd, 0x96, 0x59, 0x92, 0xe3, 0x2a, 0x10, 0x45, 0xff, 0x59, 0x45, 0x2f, 0x81, 0xcc, 0x24, 0x19, 0x96, 0x83, 0x18, 0x22, 0x7a, 0x7, 0x6f, 0xf9, 0x7d, 0xc1, 0x48, 0x1e, 0xab, 0x5c, 0x65, 0xfb, 0xe3, 0x89, 0xb0, 0x40, 0x29, 0x48, 0xae, 0xee, 0x41, 0xc8, 0xa6, 0xfd, 0xf7, 0xb7, 0x9b, 0x3f, 0x38, 0x28, 0x45, 0x6f, 0x9c, 0x86, 0xe8, 0x93, 0xf7, 0x16, 0x87, 0x4b, 0x2e, 0x71, 0x46, 0x23, 0xda, 0xd3, 0x71, 0xaa, 0xc9, 0xba, 0x79, 0x5e, 0x17, 0x76, 0x6f, 0x5c, 0xc5, 0xcd, 0x71, 0x83, 0x11, 0x12, 0xd4, 0x72, 0xba, 0xf4, 0x6d, 0xf5, 0xcf, 0x88, 0xeb, 0x79, 0x40, 0x70, 0x2b, 0xbe, 0x5d, 0xc7, 0x4d, 0x28, 0x2b, 0x4f, 0x5c, 0x89, 0xe8, 0x48, 0x3c, 0xf, 0x19, 0x33, 0x8f, 0xf6, 0xea, 0x17, 0x57, 0x22, 0xe1, 0x53, 0x9c, 0xd6, 0xb5, 0x49, 0x6b, 0x5c, 0x76, 0x17, 0x8f, 0xb3, 0x7e, 0x5c, 0x56, 0xda, 0x95, 0xfc, 0xf6, 0xda, 0x5, 0x98, 0x51, 0x15, 0xf9, 0x84, 0xd, 0x37, 0x21, 0xb1, 0x38, 0xc7, 0x31, 0x8b, 0x40, 0x81, 0x24, 0xc9, 0x32, 0xda, 0x79, 0xde, 0x19, 0x91, 0x80, 0xb6, 0x43, 0x9d, 0x45, 0x84, 0x1e, 0x7b, 0x67, 0x8e, 0xe6, 0x8d, 0x79, 0x47, 0xeb, 0xc6, 0x3b, 0x9b, 0x57, 0x5c, 0xae, 0xad, 0x30, 0xd6, 0xaf, 0xe, 0xfe, 0xc6, 0xa3, 0x15, 0x27, 0xbd, 0x89, 0xcb, 0x31, 0xd, 0xdf, 0x52, 0xdb, 0x67, 0xbe, 0xba, 0x91, 0xcb, 0x31, 0xc5, 0x9d, 0x77, 0xbd, 0xd7, 0xd8, 0x7b, 0x3b, 0x3d, 0x5d, 0x76, 0x1e, 0x4e, 0x79, 0xb3, 0x1e, 0x6a, 0x7f, 0x94, 0xd9, 0x42, 0xc7, 0xd, 0x56, 0xca, 0x1c, 0xe6, 0x51, 0x2, 0x7e, 0x8a, 0x76, 0x98, 0x25, 0xa1, 0x44, 0x3c, 0x62, 0x1, 0xb1, 0xa, 0x9a, 0x1b, 0x4a, 0x31, 0x94, 0x88, 0xe1, 0x69, 0x27, 0x47, 0x95, 0x32, 0x75, 0x6a, 0xb3, 0x2e, 0x54, 0x20, 0xd1, 0x71, 0xe3, 0x80, 0x9a, 0xb9, 0xb0, 0xcc, 0x58, 0x94, 0xc0, 0x89, 0xcb, 0x84, 0xe2, 0x46, 0xa1, 0xce, 0x1, 0x78, 0xaa, 0x91, 0x8, 0x3e, 0x5, 0xd4, 0x4, 0x61, 0x3e, 0xb4, 0xd0, 0x9c, 0x37, 0xcd, 0xf9, 0xa, 0x45, 0xcc, 0x5c, 0x9, 0x3d, 0x99, 0x90, 0x8c, 0x30, 0xe2, 0xae, 0x98, 0x47, 0xc1, 0x57, 0xca, 0x91, 0xa8, 0xf7, 0xb1, 0x74, 0x89, 0x6c, 0x3c, 0xbc, 0x82, 0x2e, 0x1e, 0x6b, 0x1a, 0x32, 0x6, 0xb9, 0x71, 0x46, 0x2f, 0x0, 0xa1, 0xbe, 0x3c, 0xd5, 0xe9, 0xef, 0x2c, 0xe6, 0x62, 0xdd, 0xd8, 0xb, 0xb0, 0x2, 0x82, 0x3a, 0x6d, 0x8e, 0x78, 0xc0, 0x6c, 0xb7, 0x53, 0x8a, 0x4d, 0xe9, 0xbc, 0xb6, 0x64, 0x72, 0x16, 0xf4, 0x53, 0xeb, 0x8c, 0x3d, 0xbd, 0x1a, 0x14, 0xea, 0x4a, 0x0, 0x8b, 0x30, 0xb7, 0x42, 0xc, 0x9, 0x8, 0x58, 0x4f, 0xa2, 0xe4, 0xc9, 0x6, 0xe6, 0x40, 0x4, 0x1f, 0x23, 0xf8, 0x64, 0x28, 0x67, 0x71, 0xbc, 0x81, 0x0, 0xa9, 0x72, 0x25, 0xd3, 0xc1, 0x46, 0xc4, 0x3, 0x4e, 0xe4, 0x31, 0x37, 0xc6, 0x4, 0x9a, 0x7d, 0x59, 0xf9, 0x14, 0xc6, 0xd6, 0x2, 0x10, 0x2a, 0x1e, 0xaf, 0x4a, 0x1c, 0x2f, 0x10, 0x60, 0x39, 0xa7, 0x58, 0x3f, 0xc1, 0x45, 0xac, 0xa1, 0xac, 0xa2, 0xce, 0xa8, 0xaa, 0xd7, 0xa0, 0x51, 0x93, 0x66, 0x2f, 0xde, 0x79, 0xf5, 0xde, 0x7, 0x3f, 0xf6, 0xa8, 0x1c, 0x24, 0xb8, 0xa0, 0xc1, 0x87, 0x10, 0x62, 0x48, 0x21, 0x47, 0x89, 0x2e, 0x6a, 0xf4, 0x31, 0xc4, 0x18, 0x53, 0xcc, 0x89, 0x93, 0x60, 0xb, 0xd3, 0xe4, 0x53, 0x30, 0x29, 0xa6, 0x94, 0x72, 0xc6, 0xa4, 0x19, 0xa9, 0x33, 0x46, 0x67, 0xf4, 0xc8, 0x79, 0xe3, 0x4d, 0x36, 0xb7, 0xe9, 0xe6, 0xb7, 0xb0, 0xc5, 0x2d, 0x6d, 0xb9, 0x60, 0xf9, 0x14, 0x57, 0xb4, 0xf8, 0x12, 0x4a, 0x2c, 0xa9, 0xe4, 0xca, 0x55, 0x2a, 0x5e, 0xff, 0xea, 0x6b, 0x30, 0x35, 0xd6, 0x54, 0x73, 0xa3, 0x86, 0xa5, 0xd4, 0x5c, 0xd3, 0xe6, 0x5b, 0x68, 0xb1, 0xa5, 0x96, 0x3b, 0xd6, 0x5a, 0x97, 0xee, 0xba, 0x76, 0xdf, 0x43, 0x8f, 0x3d, 0xf5, 0x7c, 0x50, 0x5b, 0x54, 0xaf, 0xa9, 0xd1, 0xd, 0xb9, 0xef, 0xa9, 0xd1, 0xa2, 0x36, 0x88, 0xb9, 0xd9, 0x2f, 0x9c, 0xa9, 0x21, 0x1c, 0xc2, 0x9e, 0x82, 0xc6, 0x76, 0xa2, 0x83, 0x19, 0x88, 0xb1, 0x23, 0x10, 0xf, 0x83, 0x0, 0x16, 0x34, 0xf, 0x66, 0x36, 0x92, 0x73, 0x3c, 0xc8, 0xd, 0x66, 0x36, 0x31, 0x5e, 0xa, 0x65, 0x50, 0x23, 0x1d, 0x70, 0x2a, 0xd, 0x62, 0x20, 0xe8, 0x1a, 0xb1, 0x76, 0x3a, 0xd8, 0x9d, 0xc9, 0x7d, 0xcb, 0xcd, 0xa8, 0xfb, 0x15, 0x37, 0xfe, 0x8a, 0x9c, 0x19, 0xe8, 0x3e, 0x41, 0xce, 0xc, 0x74, 0x8b, 0xdc, 0x3d, 0xb7, 0x7, 0xd4, 0x6a, 0x9e, 0x5f, 0x14, 0x99, 0x80, 0xc6, 0x5b, 0x38, 0x3c, 0xb5, 0xd2, 0xb1, 0xb1, 0xa1, 0x43, 0x8b, 0x99, 0x63, 0x1e, 0xdf, 0xa4, 0x97, 0x6b, 0xf3, 0x6e, 0x82, 0xff, 0x59, 0xa2, 0x76, 0x98, 0x52, 0xcd, 0x96, 0x67, 0xd4, 0xe2, 0x7b, 0x78, 0x6a, 0xd8, 0xd7, 0x6a, 0x83, 0x5d, 0x64, 0x45, 0x84, 0x8e, 0x89, 0x9e, 0x4a, 0xe9, 0x9a, 0xf6, 0x51, 0x92, 0x67, 0xc, 0xd4, 0xe2, 0x2e, 0xcf, 0xfd, 0x52, 0xb, 0xf9, 0x35, 0x30, 0x1d, 0x1e, 0xe1, 0x3, 0xb4, 0xf2, 0x97, 0x94, 0x9f, 0x8a, 0x71, 0x37, 0x62, 0x3e, 0x48, 0xd, 0x42, 0xcc, 0xae, 0x24, 0xb7, 0xa7, 0x4a, 0xf8, 0x50, 0xd2, 0x3e, 0x8d, 0xbf, 0xda, 0xc3, 0x12, 0xb3, 0xf9, 0xa7, 0x4a, 0xe8, 0x91, 0x27, 0x9f, 0x51, 0x74, 0x1, 0x67, 0x5b, 0xc9, 0xcd, 0xd7, 0x4a, 0x5c, 0xff, 0xce, 0x93, 0xf7, 0x14, 0x5d, 0x78, 0x52, 0x6e, 0xee, 0x99, 0x7, 0x4a, 0xea, 0xfe, 0xd6, 0x44, 0x25, 0xa7, 0xe3, 0x6f, 0xeb, 0xf, 0x6a, 0xf3, 0x93, 0x8e, 0x14, 0xf6, 0x67, 0xeb, 0xc2, 0x5f, 0x2c, 0x73, 0x73, 0x88, 0xad, 0xb2, 0x6b, 0xca, 0x73, 0xb8, 0x8e, 0xff, 0xd0, 0x3f, 0xaf, 0xcd, 0x77, 0x1d, 0xb4, 0x9f, 0x2d, 0x79, 0xe6, 0xb7, 0xe9, 0x2e, 0xbf, 0x62, 0xc9, 0x5d, 0x6d, 0x9e, 0x58, 0xa2, 0x4f, 0x76, 0x0, 0xa9, 0xec, 0xf7, 0x6d, 0xe4, 0x25, 0x4b, 0xee, 0x6a, 0xf3, 0xd8, 0x92, 0xfa, 0x74, 0x33, 0x71, 0xe9, 0x7a, 0xb9, 0x9a, 0xcf, 0x6c, 0xfd, 0xa7, 0x44, 0x17, 0xeb, 0xf5, 0xf7, 0x4a, 0x2e, 0x13, 0xbd, 0xbd, 0xad, 0xd9, 0x99, 0xe8, 0x4d, 0x25, 0x9f, 0x50, 0x74, 0x65, 0x89, 0x79, 0x57, 0xc9, 0x3b, 0x8a, 0x1e, 0xc2, 0xd9, 0x15, 0x75, 0xfc, 0x61, 0x49, 0xe6, 0x1f, 0xbf, 0x1c, 0xa8, 0x52, 0x2b, 0xb1, 0xc9, 0xd4, 0x0, 0x0, 0x0, 0x2, 0x62, 0x4b, 0x47, 0x44, 0x0, 0xff, 0x87, 0x8f, 0xcc, 0xbf, 0x0, 0x0, 0x0, 0x9, 0x70, 0x48, 0x59, 0x73, 0x0, 0x0, 0x2e, 0x23, 0x0, 0x0, 0x2e, 0x23, 0x1, 0x78, 0xa5, 0x3f, 0x76, 0x0, 0x0, 0x0, 0x7, 0x74, 0x49, 0x4d, 0x45, 0x7, 0xe3, 0x2, 0xa, 0x13, 0x29, 0x21, 0x5f, 0x36, 0xe2, 0x14, 0x0, 0x0, 0x0, 0xaf, 0x49, 0x44, 0x41, 0x54, 0x28, 0xcf, 0x7d, 0x91, 0x41, 0xa, 0xc2, 0x40, 0x10, 0x4, 0x6b, 0x92, 0x61, 0x37, 0xb0, 0x87, 0xec, 0x39, 0x3e, 0xc6, 0x3f, 0xf8, 0x9a, 0x3c, 0xc1, 0xd7, 0xf8, 0x3, 0xf, 0x3e, 0xc6, 0xab, 0x44, 0x50, 0x30, 0x26, 0x66, 0x3c, 0x2c, 0x6, 0x3, 0xd9, 0xf4, 0x69, 0xa0, 0xab, 0x9b, 0x86, 0x11, 0x14, 0x87, 0xa7, 0xc2, 0x51, 0x52, 0x90, 0x34, 0xf1, 0xe1, 0xcd, 0x8b, 0x9e, 0xb7, 0xe2, 0x8, 0x44, 0x6a, 0x2, 0x1e, 0x41, 0x0, 0xc3, 0xe8, 0x79, 0x72, 0xa7, 0x3, 0xc5, 0x13, 0xf7, 0x87, 0x5d, 0x3b, 0x46, 0x16, 0xd2, 0xee, 0x7a, 0xbc, 0x9c, 0x18, 0x95, 0x8a, 0xba, 0x69, 0x6f, 0x71, 0xc4, 0xfe, 0x6c, 0x41, 0x63, 0xd3, 0x72, 0xe6, 0xa1, 0x38, 0xc2, 0x10, 0x87, 0x65, 0x1c, 0x63, 0x60, 0x88, 0x4, 0x9c, 0x52, 0xe2, 0xa7, 0x45, 0x9a, 0x79, 0x29, 0x9e, 0x52, 0x29, 0x10, 0x63, 0x5a, 0x1, 0xc, 0x84, 0x42, 0x1, 0xc9, 0x36, 0x8, 0x68, 0x3a, 0x33, 0x0, 0x9, 0x30, 0x5b, 0x5, 0xc, 0x6c, 0x6e, 0x98, 0x36, 0x1b, 0x24, 0xdb, 0xf0, 0xdb, 0xc0, 0x2a, 0x90, 0x54, 0x6c, 0xba, 0x96, 0x0, 0xc9, 0x2, 0xc2, 0xfc, 0xe0, 0xac, 0xbe, 0xe, 0x38, 0x38, 0x83, 0xbf, 0x35, 0x30, 0x94, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82 + 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x10, 0x8, 0x4, 0x0, 0x0, 0x0, 0xb5, 0xfa, 0x37, 0xea, 0x0, 0x0, 0x0, 0x9, 0x70, 0x48, 0x59, 0x73, 0x0, 0x0, 0x2e, 0x23, 0x0, 0x0, 0x2e, 0x23, 0x1, 0x78, 0xa5, 0x3f, 0x76, 0x0, 0x0, 0x0, 0x2, 0x62, 0x4b, 0x47, 0x44, 0x0, 0xff, 0x87, 0x8f, 0xcc, 0xbf, 0x0, 0x0, 0x0, 0xa6, 0x49, 0x44, 0x41, 0x54, 0x78, 0xda, 0x7c, 0xcd, 0xc5, 0x41, 0x4, 0x41, 0x10, 0x0, 0xc0, 0xea, 0xbd, 0xc1, 0x6d, 0xde, 0x47, 0x30, 0xe4, 0x40, 0x34, 0x1b, 0x2, 0xd1, 0x10, 0x1, 0x1a, 0xc, 0x4f, 0xdc, 0x6d, 0x1b, 0x77, 0xe6, 0xea, 0xd5, 0xde, 0xa1, 0x98, 0x36, 0x63, 0xd6, 0xb4, 0x91, 0xe, 0x30, 0x78, 0x74, 0xe7, 0xc6, 0xad, 0xbb, 0x97, 0xf6, 0x82, 0x6a, 0xc5, 0x82, 0x19, 0x21, 0x90, 0xd2, 0xad, 0x4b, 0xa7, 0x4e, 0x28, 0x66, 0xd4, 0xb5, 0xf5, 0xd5, 0xfe, 0xa1, 0xfa, 0xa1, 0x9c, 0x1c, 0x6c, 0xec, 0x6f, 0x7a, 0x28, 0x66, 0xad, 0x8c, 0xfb, 0xa3, 0xfa, 0x20, 0x7d, 0x9, 0xa5, 0x8e, 0x7b, 0xdb, 0x2e, 0x5e, 0x5f, 0xdc, 0xd7, 0x7b, 0x3f, 0xa5, 0x7b, 0xf7, 0xd5, 0x82, 0xe9, 0x62, 0x64, 0x66, 0x90, 0xfe, 0x1a, 0x98, 0x31, 0x2a, 0x3a, 0x91, 0x6, 0x7f, 0x25, 0xa1, 0x2b, 0x88, 0xe6, 0x85, 0xa0, 0x40, 0x73, 0x0, 0x5, 0x99, 0xf2, 0xff, 0x17, 0xf9, 0x79, 0x61, 0x98, 0x78, 0x21, 0x9a, 0x17, 0x82, 0xf2, 0x99, 0x34, 0x74, 0x13, 0xbb, 0x49, 0x87, 0xd0, 0x12, 0x4f, 0x3, 0x29, 0x20, 0x0, 0x0, 0xe, 0x38, 0x38, 0x83, 0xd2, 0xe8, 0x36, 0x36, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82 }; static const unsigned char tab_menu_png[] = { diff --git a/scene/resources/height_map_shape.cpp b/scene/resources/height_map_shape.cpp index f763700d52..214706626d 100644 --- a/scene/resources/height_map_shape.cpp +++ b/scene/resources/height_map_shape.cpp @@ -31,7 +31,7 @@ #include "height_map_shape.h" #include "servers/physics_server.h" -Vector<Vector3> HeightMapShape::_gen_debug_mesh_lines() { +Vector<Vector3> HeightMapShape::get_debug_mesh_lines() { Vector<Vector3> points; if ((map_width != 0) && (map_depth != 0)) { diff --git a/scene/resources/height_map_shape.h b/scene/resources/height_map_shape.h index b062f4e893..4cf2a76213 100644 --- a/scene/resources/height_map_shape.h +++ b/scene/resources/height_map_shape.h @@ -46,8 +46,6 @@ protected: static void _bind_methods(); virtual void _update_shape(); - virtual Vector<Vector3> _gen_debug_mesh_lines(); - public: void set_map_width(int p_new); int get_map_width() const; @@ -56,6 +54,8 @@ public: void set_map_data(PoolRealArray p_new); PoolRealArray get_map_data() const; + virtual Vector<Vector3> get_debug_mesh_lines(); + HeightMapShape(); }; diff --git a/scene/resources/plane_shape.cpp b/scene/resources/plane_shape.cpp index 08f6ccd764..d3274ec5f8 100644 --- a/scene/resources/plane_shape.cpp +++ b/scene/resources/plane_shape.cpp @@ -32,7 +32,7 @@ #include "servers/physics_server.h" -Vector<Vector3> PlaneShape::_gen_debug_mesh_lines() { +Vector<Vector3> PlaneShape::get_debug_mesh_lines() { Plane p = get_plane(); Vector<Vector3> points; diff --git a/scene/resources/plane_shape.h b/scene/resources/plane_shape.h index 87c367cfde..f853d1966b 100644 --- a/scene/resources/plane_shape.h +++ b/scene/resources/plane_shape.h @@ -42,12 +42,12 @@ protected: static void _bind_methods(); virtual void _update_shape(); - virtual Vector<Vector3> _gen_debug_mesh_lines(); - public: void set_plane(Plane p_plane); Plane get_plane() const; + virtual Vector<Vector3> get_debug_mesh_lines(); + PlaneShape(); }; #endif // PLANE_SHAPE_H diff --git a/scene/resources/ray_shape.cpp b/scene/resources/ray_shape.cpp index 0acfffdc06..5a696aee23 100644 --- a/scene/resources/ray_shape.cpp +++ b/scene/resources/ray_shape.cpp @@ -32,7 +32,7 @@ #include "servers/physics_server.h" -Vector<Vector3> RayShape::_gen_debug_mesh_lines() { +Vector<Vector3> RayShape::get_debug_mesh_lines() { Vector<Vector3> points; points.push_back(Vector3()); diff --git a/scene/resources/ray_shape.h b/scene/resources/ray_shape.h index 89fc34051c..fee7475c69 100644 --- a/scene/resources/ray_shape.h +++ b/scene/resources/ray_shape.h @@ -41,7 +41,6 @@ class RayShape : public Shape { protected: static void _bind_methods(); virtual void _update_shape(); - virtual Vector<Vector3> _gen_debug_mesh_lines(); public: void set_length(float p_length); @@ -50,6 +49,8 @@ public: void set_slips_on_slope(bool p_active); bool get_slips_on_slope() const; + virtual Vector<Vector3> get_debug_mesh_lines(); + RayShape(); }; #endif // RAY_SHAPE_H diff --git a/scene/resources/shape.cpp b/scene/resources/shape.cpp index 6ba46f066c..3500fdb4bc 100644 --- a/scene/resources/shape.cpp +++ b/scene/resources/shape.cpp @@ -37,7 +37,7 @@ void Shape::add_vertices_to_array(PoolVector<Vector3> &array, const Transform &p_xform) { - Vector<Vector3> toadd = _gen_debug_mesh_lines(); + Vector<Vector3> toadd = get_debug_mesh_lines(); if (toadd.size()) { @@ -64,7 +64,7 @@ Ref<ArrayMesh> Shape::get_debug_mesh() { if (debug_mesh_cache.is_valid()) return debug_mesh_cache; - Vector<Vector3> lines = _gen_debug_mesh_lines(); + Vector<Vector3> lines = get_debug_mesh_lines(); debug_mesh_cache = Ref<ArrayMesh>(memnew(ArrayMesh)); diff --git a/scene/resources/shape.h b/scene/resources/shape.h index ba763eaab1..2743fd0c65 100644 --- a/scene/resources/shape.h +++ b/scene/resources/shape.h @@ -50,13 +50,13 @@ protected: _FORCE_INLINE_ RID get_shape() const { return shape; } Shape(RID p_shape); - virtual Vector<Vector3> _gen_debug_mesh_lines() = 0; // { return Vector<Vector3>(); } virtual void _update_shape(); public: virtual RID get_rid() const { return shape; } Ref<ArrayMesh> get_debug_mesh(); + virtual Vector<Vector3> get_debug_mesh_lines() = 0; // { return Vector<Vector3>(); } void add_vertices_to_array(PoolVector<Vector3> &array, const Transform &p_xform); diff --git a/scene/resources/sphere_shape.cpp b/scene/resources/sphere_shape.cpp index af89413ced..019bc9189a 100644 --- a/scene/resources/sphere_shape.cpp +++ b/scene/resources/sphere_shape.cpp @@ -31,7 +31,7 @@ #include "sphere_shape.h" #include "servers/physics_server.h" -Vector<Vector3> SphereShape::_gen_debug_mesh_lines() { +Vector<Vector3> SphereShape::get_debug_mesh_lines() { float r = get_radius(); diff --git a/scene/resources/sphere_shape.h b/scene/resources/sphere_shape.h index 682928e885..679882fe23 100644 --- a/scene/resources/sphere_shape.h +++ b/scene/resources/sphere_shape.h @@ -42,12 +42,13 @@ protected: static void _bind_methods(); virtual void _update_shape(); - virtual Vector<Vector3> _gen_debug_mesh_lines(); public: void set_radius(float p_radius); float get_radius() const; + virtual Vector<Vector3> get_debug_mesh_lines(); + SphereShape(); }; diff --git a/scene/resources/visual_shader.cpp b/scene/resources/visual_shader.cpp index cd77c8a850..bd6835f816 100644 --- a/scene/resources/visual_shader.cpp +++ b/scene/resources/visual_shader.cpp @@ -1067,16 +1067,7 @@ Error VisualShader::_write_node(Type type, StringBuilder &global_code, StringBui VisualShaderNodeUniform *uniform = (VisualShaderNodeUniform *)graph[type].nodes[from_node].node.ptr(); if (uniform) { - inputs[i] = ""; - switch (uniform->get_uniform_type()) { - case VisualShaderNodeUniform::UTYPE_CUBEMAP: - inputs[i] += "cube_"; - break; - case VisualShaderNodeUniform::UTYPE_SAMPLER2D: - inputs[i] += "s2d_"; - break; - } - inputs[i] += uniform->get_uniform_name(); + inputs[i] = uniform->get_uniform_name(); } else { inputs[i] = ""; } @@ -1981,16 +1972,7 @@ void VisualShaderNodeUniform::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::STRING, "uniform_name"), "set_uniform_name", "get_uniform_name"); } -int VisualShaderNodeUniform::get_uniform_type() const { - return (int)uniform_type; -} - -void VisualShaderNodeUniform::set_uniform_type(int p_type) { - uniform_type = (UniformType)p_type; -} - VisualShaderNodeUniform::VisualShaderNodeUniform() { - uniform_type = UTYPE_NONE; } ////////////// GroupBase diff --git a/scene/resources/visual_shader.h b/scene/resources/visual_shader.h index 016213c399..4f73316404 100644 --- a/scene/resources/visual_shader.h +++ b/scene/resources/visual_shader.h @@ -353,16 +353,8 @@ public: class VisualShaderNodeUniform : public VisualShaderNode { GDCLASS(VisualShaderNodeUniform, VisualShaderNode); -public: - enum UniformType { - UTYPE_NONE, - UTYPE_CUBEMAP, - UTYPE_SAMPLER2D, - }; - private: String uniform_name; - UniformType uniform_type; protected: static void _bind_methods(); @@ -371,9 +363,6 @@ public: void set_uniform_name(const String &p_name); String get_uniform_name() const; - int get_uniform_type() const; - void set_uniform_type(int p_type); - VisualShaderNodeUniform(); }; diff --git a/scene/resources/visual_shader_nodes.cpp b/scene/resources/visual_shader_nodes.cpp index c56d5d7213..a7df736c78 100644 --- a/scene/resources/visual_shader_nodes.cpp +++ b/scene/resources/visual_shader_nodes.cpp @@ -386,7 +386,7 @@ String VisualShaderNodeTexture::get_input_port_name(int p_port) const { case 1: return "lod"; case 2: - return "sampler"; + return "sampler2D"; default: return ""; } @@ -474,62 +474,23 @@ String VisualShaderNodeTexture::generate_code(Shader::Mode p_mode, VisualShader: if (source == SOURCE_PORT) { String id = p_input_vars[2]; - VisualShaderNodeUniform::UniformType utype = VisualShaderNodeUniform::UTYPE_NONE; - if (id.begins_with("cube_")) { - utype = VisualShaderNodeUniform::UTYPE_CUBEMAP; - id = id.substr(5); - } else if (id.begins_with("s2d_")) { - utype = VisualShaderNodeUniform::UTYPE_SAMPLER2D; - id = id.substr(4); - } - String code; if (id == String()) { code += "\tvec4 " + id + "_tex_read = vec4(0.0);\n"; } else { if (p_input_vars[0] == String()) { // Use UV by default. - switch (utype) { - case VisualShaderNodeUniform::UTYPE_CUBEMAP: - if (p_input_vars[1] == String()) { - code += "\tvec4 " + id + "_tex_read = texture( " + id + " , vec3( UV, 0.0 ) );\n"; - } else { - code += "\tvec4 " + id + "_tex_read = textureLod( " + id + " , vec3( UV, 0.0 ) , " + p_input_vars[1] + " );\n"; - } - break; - case VisualShaderNodeUniform::UTYPE_SAMPLER2D: - if (p_input_vars[1] == String()) { - code += "\tvec4 " + id + "_tex_read = texture( " + id + " , UV.xy );\n"; - } else { - code += "\tvec4 " + id + "_tex_read = textureLod( " + id + " , UV.xy , " + p_input_vars[1] + " );\n"; - } - break; - default: - break; + + if (p_input_vars[1] == String()) { + code += "\tvec4 " + id + "_tex_read = texture( " + id + " , UV.xy );\n"; + } else { + code += "\tvec4 " + id + "_tex_read = textureLod( " + id + " , UV.xy , " + p_input_vars[1] + " );\n"; } + } else if (p_input_vars[1] == String()) { //no lod - - switch (utype) { - case VisualShaderNodeUniform::UTYPE_CUBEMAP: - code += "\tvec4 " + id + "_tex_read = texture( " + id + " , " + p_input_vars[0] + " );\n"; - break; - case VisualShaderNodeUniform::UTYPE_SAMPLER2D: - code += "\tvec4 " + id + "_tex_read = texture( " + id + " , " + p_input_vars[0] + ".xy );\n"; - break; - default: - break; - } + code += "\tvec4 " + id + "_tex_read = texture( " + id + " , " + p_input_vars[0] + ".xy );\n"; } else { - switch (utype) { - case VisualShaderNodeUniform::UTYPE_CUBEMAP: - code += "\tvec4 " + id + "_tex_read = textureLod( " + id + " , " + p_input_vars[0] + " , " + p_input_vars[1] + " );\n"; - break; - case VisualShaderNodeUniform::UTYPE_SAMPLER2D: - code += "\tvec4 " + id + "_tex_read = textureLod( " + id + " , " + p_input_vars[0] + ".xy , " + p_input_vars[1] + " );\n"; - break; - default: - break; - } + code += "\tvec4 " + id + "_tex_read = textureLod( " + id + " , " + p_input_vars[0] + ".xy , " + p_input_vars[1] + " );\n"; } code += "\t" + p_output_vars[0] + " = " + id + "_tex_read.rgb;\n"; @@ -769,15 +730,33 @@ String VisualShaderNodeCubeMap::get_caption() const { } int VisualShaderNodeCubeMap::get_input_port_count() const { - return 2; + return 3; } VisualShaderNodeCubeMap::PortType VisualShaderNodeCubeMap::get_input_port_type(int p_port) const { - return p_port == 0 ? PORT_TYPE_VECTOR : PORT_TYPE_SCALAR; + switch (p_port) { + case 0: + return PORT_TYPE_VECTOR; + case 1: + return PORT_TYPE_SCALAR; + case 2: + return PORT_TYPE_SAMPLER; + default: + return PORT_TYPE_SCALAR; + } } String VisualShaderNodeCubeMap::get_input_port_name(int p_port) const { - return p_port == 0 ? "uv" : "lod"; + switch (p_port) { + case 0: + return "uv"; + case 1: + return "lod"; + case 2: + return "samplerCube"; + default: + return ""; + } } int VisualShaderNodeCubeMap::get_output_port_count() const { @@ -803,19 +782,37 @@ Vector<VisualShader::DefaultTextureParam> VisualShaderNodeCubeMap::get_default_t String VisualShaderNodeCubeMap::generate_global(Shader::Mode p_mode, VisualShader::Type p_type, int p_id) const { - String u = "uniform samplerCube " + make_unique_id(p_type, p_id, "cube"); - switch (texture_type) { - case TYPE_DATA: break; - case TYPE_COLOR: u += " : hint_albedo"; break; - case TYPE_NORMALMAP: u += " : hint_normal"; break; + if (source == SOURCE_TEXTURE) { + String u = "uniform samplerCube " + make_unique_id(p_type, p_id, "cube"); + switch (texture_type) { + case TYPE_DATA: break; + case TYPE_COLOR: u += " : hint_albedo"; break; + case TYPE_NORMALMAP: u += " : hint_normal"; break; + } + return u + ";"; } - return u + ";"; + return String(); } String VisualShaderNodeCubeMap::generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview) const { - String id = make_unique_id(p_type, p_id, "cube"); String code; + String id; + if (source == SOURCE_TEXTURE) { + id = make_unique_id(p_type, p_id, "cube"); + } else if (source == SOURCE_PORT) { + id = p_input_vars[2]; + } else { + return String(); + } + + if (id == String()) { + code += "\tvec4 " + id + "_read = vec4(0.0);\n"; + code += "\t" + p_output_vars[0] + " = " + id + "_read.rgb;\n"; + code += "\t" + p_output_vars[1] + " = " + id + "_read.a;\n"; + return code; + } + if (p_input_vars[0] == String()) { // Use UV by default. if (p_input_vars[1] == String()) { @@ -830,9 +827,9 @@ String VisualShaderNodeCubeMap::generate_code(Shader::Mode p_mode, VisualShader: } else { code += "\tvec4 " + id + "_read = textureLod( " + id + " , " + p_input_vars[0] + " , " + p_input_vars[1] + " );\n"; } - code += "\t" + p_output_vars[0] + " = " + id + "_read.rgb;\n"; code += "\t" + p_output_vars[1] + " = " + id + "_read.a;\n"; + return code; } @@ -843,6 +840,16 @@ String VisualShaderNodeCubeMap::get_input_port_default_hint(int p_port) const { return ""; } +void VisualShaderNodeCubeMap::set_source(Source p_source) { + source = p_source; + emit_changed(); + emit_signal("editor_refresh_request"); +} + +VisualShaderNodeCubeMap::Source VisualShaderNodeCubeMap::get_source() const { + return source; +} + void VisualShaderNodeCubeMap::set_cube_map(Ref<CubeMap> p_value) { cube_map = p_value; @@ -865,22 +872,32 @@ VisualShaderNodeCubeMap::TextureType VisualShaderNodeCubeMap::get_texture_type() Vector<StringName> VisualShaderNodeCubeMap::get_editable_properties() const { Vector<StringName> props; - props.push_back("cube_map"); - props.push_back("texture_type"); + props.push_back("source"); + if (source == SOURCE_TEXTURE) { + props.push_back("cube_map"); + props.push_back("texture_type"); + } return props; } void VisualShaderNodeCubeMap::_bind_methods() { + ClassDB::bind_method(D_METHOD("set_source", "value"), &VisualShaderNodeCubeMap::set_source); + ClassDB::bind_method(D_METHOD("get_source"), &VisualShaderNodeCubeMap::get_source); + ClassDB::bind_method(D_METHOD("set_cube_map", "value"), &VisualShaderNodeCubeMap::set_cube_map); ClassDB::bind_method(D_METHOD("get_cube_map"), &VisualShaderNodeCubeMap::get_cube_map); ClassDB::bind_method(D_METHOD("set_texture_type", "value"), &VisualShaderNodeCubeMap::set_texture_type); ClassDB::bind_method(D_METHOD("get_texture_type"), &VisualShaderNodeCubeMap::get_texture_type); + ADD_PROPERTY(PropertyInfo(Variant::INT, "source", PROPERTY_HINT_ENUM, "Texture,SamplerPort"), "set_source", "get_source"); ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "cube_map", PROPERTY_HINT_RESOURCE_TYPE, "CubeMap"), "set_cube_map", "get_cube_map"); ADD_PROPERTY(PropertyInfo(Variant::INT, "texture_type", PROPERTY_HINT_ENUM, "Data,Color,Normalmap"), "set_texture_type", "get_texture_type"); + BIND_ENUM_CONSTANT(SOURCE_TEXTURE); + BIND_ENUM_CONSTANT(SOURCE_PORT); + BIND_ENUM_CONSTANT(TYPE_DATA); BIND_ENUM_CONSTANT(TYPE_COLOR); BIND_ENUM_CONSTANT(TYPE_NORMALMAP); @@ -3177,7 +3194,7 @@ String VisualShaderNodeTextureUniform::get_output_port_name(int p_port) const { case 1: return "alpha"; case 2: - return "sampler"; + return "sampler2D"; default: return ""; } @@ -3284,7 +3301,6 @@ String VisualShaderNodeTextureUniform::get_input_port_default_hint(int p_port) c VisualShaderNodeTextureUniform::VisualShaderNodeTextureUniform() { texture_type = TYPE_DATA; color_default = COLOR_DEFAULT_WHITE; - set_uniform_type(VisualShaderNodeUniform::UTYPE_SAMPLER2D); } ////////////// Texture Uniform (Triplanar) @@ -3403,7 +3419,7 @@ VisualShaderNodeCubeMapUniform::PortType VisualShaderNodeCubeMapUniform::get_out } String VisualShaderNodeCubeMapUniform::get_output_port_name(int p_port) const { - return "sampler"; + return "samplerCube"; } int VisualShaderNodeCubeMapUniform::get_input_port_count() const { @@ -3450,7 +3466,6 @@ String VisualShaderNodeCubeMapUniform::generate_code(Shader::Mode p_mode, Visual } VisualShaderNodeCubeMapUniform::VisualShaderNodeCubeMapUniform() { - set_uniform_type(VisualShaderNodeUniform::UTYPE_CUBEMAP); } ////////////// If diff --git a/scene/resources/visual_shader_nodes.h b/scene/resources/visual_shader_nodes.h index 350e73408c..339e59bda9 100644 --- a/scene/resources/visual_shader_nodes.h +++ b/scene/resources/visual_shader_nodes.h @@ -259,6 +259,11 @@ class VisualShaderNodeCubeMap : public VisualShaderNode { Ref<CubeMap> cube_map; public: + enum Source { + SOURCE_TEXTURE, + SOURCE_PORT + }; + enum TextureType { TYPE_DATA, TYPE_COLOR, @@ -266,6 +271,7 @@ public: }; private: + Source source; TextureType texture_type; protected: @@ -287,6 +293,9 @@ public: virtual String generate_global(Shader::Mode p_mode, VisualShader::Type p_type, int p_id) const; virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview = false) const; //if no output is connected, the output var passed will be empty. if no input is connected and input is NIL, the input var passed will be empty + void set_source(Source p_source); + Source get_source() const; + void set_cube_map(Ref<CubeMap> p_value); Ref<CubeMap> get_cube_map() const; @@ -299,6 +308,7 @@ public: }; VARIANT_ENUM_CAST(VisualShaderNodeCubeMap::TextureType) +VARIANT_ENUM_CAST(VisualShaderNodeCubeMap::Source) /////////////////////////////////////// /// OPS diff --git a/servers/audio_server.cpp b/servers/audio_server.cpp index 2cf6a67bef..1da0146084 100644 --- a/servers/audio_server.cpp +++ b/servers/audio_server.cpp @@ -1079,6 +1079,7 @@ void AudioServer::finish() { for (int i = 0; i < AudioDriverManager::get_driver_count(); i++) { AudioDriverManager::get_driver(i)->finish(); + AudioDriverManager::get_driver(i)->clear_capture_buffer(); } for (int i = 0; i < buses.size(); i++) { diff --git a/servers/audio_server.h b/servers/audio_server.h index 72bb6faf42..da4b9daf5b 100644 --- a/servers/audio_server.h +++ b/servers/audio_server.h @@ -115,6 +115,8 @@ public: unsigned int get_capture_position() { return capture_position; } unsigned int get_capture_size() { return capture_size; } + void clear_capture_buffer() { capture_buffer.resize(0); } + #ifdef DEBUG_ENABLED uint64_t get_profiling_time() const { return prof_time; } void reset_profiling_time() { prof_time = 0; } diff --git a/servers/physics/body_sw.cpp b/servers/physics/body_sw.cpp index a3bb581cb5..7d575c57ae 100644 --- a/servers/physics/body_sw.cpp +++ b/servers/physics/body_sw.cpp @@ -794,7 +794,7 @@ BodySW::BodySW() : still_time = 0; continuous_cd = false; - can_sleep = false; + can_sleep = true; fi_callback = NULL; } diff --git a/servers/physics_2d/body_2d_sw.cpp b/servers/physics_2d/body_2d_sw.cpp index 6ba159ca0a..f9939e3843 100644 --- a/servers/physics_2d/body_2d_sw.cpp +++ b/servers/physics_2d/body_2d_sw.cpp @@ -694,7 +694,7 @@ Body2DSW::Body2DSW() : still_time = 0; continuous_cd_mode = Physics2DServer::CCD_MODE_DISABLED; - can_sleep = false; + can_sleep = true; fi_callback = NULL; } diff --git a/servers/visual/visual_server_wrap_mt.cpp b/servers/visual/visual_server_wrap_mt.cpp index 79e4d8cbba..1f0217c0ce 100644 --- a/servers/visual/visual_server_wrap_mt.cpp +++ b/servers/visual/visual_server_wrap_mt.cpp @@ -137,6 +137,7 @@ void VisualServerWrapMT::finish() { } texture_free_cached_ids(); + sky_free_cached_ids(); shader_free_cached_ids(); material_free_cached_ids(); mesh_free_cached_ids(); @@ -148,6 +149,7 @@ void VisualServerWrapMT::finish() { spot_light_free_cached_ids(); reflection_probe_free_cached_ids(); gi_probe_free_cached_ids(); + lightmap_capture_free_cached_ids(); particles_free_cached_ids(); camera_free_cached_ids(); viewport_free_cached_ids(); |