diff options
144 files changed, 990 insertions, 469 deletions
diff --git a/SConstruct b/SConstruct index e943f8dc04..f32924835d 100644 --- a/SConstruct +++ b/SConstruct @@ -189,7 +189,7 @@ Help(opts.GenerateHelpText(env_base)) # generate help # add default include paths -env_base.Append(CPPPATH=['#editor', '#']) +env_base.Prepend(CPPPATH=['#', '#editor']) # configure ENV for platform env_base.platform_exporters = platform_exporters diff --git a/core/SCsub b/core/SCsub index d5be74a64f..06efc8408d 100644 --- a/core/SCsub +++ b/core/SCsub @@ -80,9 +80,9 @@ if env['builtin_zlib']: ] thirdparty_zlib_sources = [thirdparty_zlib_dir + file for file in thirdparty_zlib_sources] - env_thirdparty.Append(CPPPATH=[thirdparty_zlib_dir]) + env_thirdparty.Prepend(CPPPATH=[thirdparty_zlib_dir]) # Needs to be available in main env too - env.Append(CPPPATH=[thirdparty_zlib_dir]) + env.Prepend(CPPPATH=[thirdparty_zlib_dir]) env_thirdparty.add_source_files(env.core_sources, thirdparty_zlib_sources) @@ -128,9 +128,9 @@ if env['builtin_zstd']: ] thirdparty_zstd_sources = [thirdparty_zstd_dir + file for file in thirdparty_zstd_sources] - env_thirdparty.Append(CPPPATH=[thirdparty_zstd_dir, thirdparty_zstd_dir + "common"]) + env_thirdparty.Prepend(CPPPATH=[thirdparty_zstd_dir, thirdparty_zstd_dir + "common"]) env_thirdparty.Append(CPPFLAGS="-DZSTD_STATIC_LINKING_ONLY") - env.Append(CPPPATH=thirdparty_zstd_dir) + env.Prepend(CPPPATH=thirdparty_zstd_dir) # Also needed in main env includes will trigger warnings env.Append(CPPFLAGS="-DZSTD_STATIC_LINKING_ONLY") diff --git a/core/math/rect2.h b/core/math/rect2.h index 901d372132..3b66617c83 100644 --- a/core/math/rect2.h +++ b/core/math/rect2.h @@ -103,7 +103,7 @@ struct Rect2 { ((p_rect.position.y + p_rect.size.y) < (position.y + size.y)); } - inline bool has_no_area() const { + _FORCE_INLINE_ bool has_no_area() const { return (size.x <= 0 || size.y <= 0); } @@ -154,8 +154,6 @@ struct Rect2 { return true; } - inline bool no_area() const { return (size.width <= 0 || size.height <= 0); } - bool operator==(const Rect2 &p_rect) const { return position == p_rect.position && size == p_rect.size; } bool operator!=(const Rect2 &p_rect) const { return position != p_rect.position || size != p_rect.size; } @@ -189,7 +187,7 @@ struct Rect2 { return g; } - inline Rect2 expand(const Vector2 &p_vector) const { + _FORCE_INLINE_ Rect2 expand(const Vector2 &p_vector) const { Rect2 r = *this; r.expand_to(p_vector); @@ -215,7 +213,7 @@ struct Rect2 { size = end - begin; } - inline Rect2 abs() const { + _FORCE_INLINE_ Rect2 abs() const { return Rect2(Point2(position.x + MIN(size.x, 0), position.y + MIN(size.y, 0)), size.abs()); } @@ -265,7 +263,7 @@ struct Rect2i { ((p_rect.position.y + p_rect.size.y) < (position.y + size.y)); } - inline bool has_no_area() const { + _FORCE_INLINE_ bool has_no_area() const { return (size.x <= 0 || size.y <= 0); } @@ -316,8 +314,6 @@ struct Rect2i { return true; } - bool no_area() { return (size.width <= 0 || size.height <= 0); } - bool operator==(const Rect2i &p_rect) const { return position == p_rect.position && size == p_rect.size; } bool operator!=(const Rect2i &p_rect) const { return position != p_rect.position || size != p_rect.size; } @@ -331,6 +327,33 @@ struct Rect2i { return g; } + inline Rect2i grow_margin(Margin p_margin, int p_amount) const { + Rect2i g = *this; + g = g.grow_individual((MARGIN_LEFT == p_margin) ? p_amount : 0, + (MARGIN_TOP == p_margin) ? p_amount : 0, + (MARGIN_RIGHT == p_margin) ? p_amount : 0, + (MARGIN_BOTTOM == p_margin) ? p_amount : 0); + return g; + } + + inline Rect2i grow_individual(int p_left, int p_top, int p_right, int p_bottom) const { + + Rect2i g = *this; + g.position.x -= p_left; + g.position.y -= p_top; + g.size.width += p_left + p_right; + g.size.height += p_top + p_bottom; + + return g; + } + + _FORCE_INLINE_ Rect2i expand(const Vector2i &p_vector) const { + + Rect2i r = *this; + r.expand_to(p_vector); + return r; + } + inline void expand_to(const Point2i &p_vector) { Point2i begin = position; diff --git a/core/os/input.cpp b/core/os/input.cpp index 63bf1db499..f04d4a1b3e 100644 --- a/core/os/input.cpp +++ b/core/os/input.cpp @@ -34,6 +34,10 @@ #include "core/os/os.h" #include "core/project_settings.h" +#ifdef TOOLS_ENABLED +#include "editor/editor_settings.h" +#endif + Input *Input::singleton = NULL; Input *Input::get_singleton() { @@ -123,6 +127,8 @@ void Input::_bind_methods() { void Input::get_argument_options(const StringName &p_function, int p_idx, List<String> *r_options) const { #ifdef TOOLS_ENABLED + const String quote_style = EDITOR_DEF("text_editor/completion/use_single_quotes", 0) ? "'" : "\""; + String pf = p_function; if (p_idx == 0 && (pf == "is_action_pressed" || pf == "action_press" || pf == "action_release" || pf == "is_action_just_pressed" || pf == "is_action_just_released" || pf == "get_action_strength")) { @@ -136,7 +142,7 @@ void Input::get_argument_options(const StringName &p_function, int p_idx, List<S continue; String name = pi.name.substr(pi.name.find("/") + 1, pi.name.length()); - r_options->push_back("\"" + name + "\""); + r_options->push_back(quote_style + name + quote_style); } } #endif diff --git a/doc/classes/AudioStreamPlayer.xml b/doc/classes/AudioStreamPlayer.xml index 07d7c875db..c6ec45f15e 100644 --- a/doc/classes/AudioStreamPlayer.xml +++ b/doc/classes/AudioStreamPlayer.xml @@ -10,15 +10,6 @@ <link>https://docs.godotengine.org/en/latest/tutorials/audio/audio_streams.html</link> </tutorials> <methods> - <method name="get_mix_time" qualifiers="const"> - <return type="float"> - </return> - <description> - Returns the actual amount of time this stream player was mixing since play() was pressed. - To know the exact position this song is mixing right now, add the value to [method AudioServer.get_time_since_last_mix]. - Also consider substracting [method AudioServer.get_output_latency] to that result. - </description> - </method> <method name="get_playback_position"> <return type="float"> </return> diff --git a/doc/classes/ColorPicker.xml b/doc/classes/ColorPicker.xml index d0a81ad8ae..a58edb5ca8 100644 --- a/doc/classes/ColorPicker.xml +++ b/doc/classes/ColorPicker.xml @@ -45,6 +45,10 @@ <member name="edit_alpha" type="bool" setter="set_edit_alpha" getter="is_editing_alpha"> If [code]true[/code], shows an alpha channel slider (transparency). </member> + <member name="presets_enabled" type="bool" setter="set_presets_enabled" getter="are_presets_enabled"> + </member> + <member name="presets_visible" type="bool" setter="set_presets_visible" getter="are_presets_visible"> + </member> <member name="raw_mode" type="bool" setter="set_raw_mode" getter="is_raw_mode"> If [code]true[/code], allows the color R, G, B component values to go beyond 1.0, which can be used for certain special operations that require it (like tinting without darkening or rendering sprites in HDR). </member> diff --git a/doc/classes/Line2D.xml b/doc/classes/Line2D.xml index 623b23807f..c55760767a 100644 --- a/doc/classes/Line2D.xml +++ b/doc/classes/Line2D.xml @@ -14,8 +14,11 @@ </return> <argument index="0" name="position" type="Vector2"> </argument> + <argument index="1" name="at_position" type="int" default="-1"> + </argument> <description> Add a point at the [code]position[/code]. Appends the point at the end of the line. + If [code]at_position[/code] is given, the point is inserted before the point number [code]at_position[/code], moving that point (and every point after) after the inserted point. If [code]at_position[/code] is not given, or is an illegal value ([code]at_position < 0[/code] or [code]at_position >= [method get_point_count][/code]), the point will be appended at the end of the point list. </description> </method> <method name="clear_points"> diff --git a/doc/classes/LineEdit.xml b/doc/classes/LineEdit.xml index 6ea097ec2f..bb180b591d 100644 --- a/doc/classes/LineEdit.xml +++ b/doc/classes/LineEdit.xml @@ -1,10 +1,19 @@ <?xml version="1.0" encoding="UTF-8" ?> <class name="LineEdit" inherits="Control" category="Core" version="3.2"> <brief_description> - Control that provides single line string editing. + Control that provides single-line string editing. </brief_description> <description> - LineEdit provides a single line string editor, used for text fields. + LineEdit provides a single-line string editor, used for text fields. It features many built-in shortcuts which will always be available: + - Ctrl + C: Copy + - Ctrl + X: Cut + - Ctrl + V or Ctrl + Y: Paste/"yank" + - Ctrl + Z: Undo + - Ctrl + Shift + Z: Redo + - Ctrl + U: Delete text from the cursor position to the beginning of the line + - Ctrl + K: Delete text from the cursor position to the end of the line + - Ctrl + A: Select all text + - Up/Down arrow: Move the cursor to the beginning/end of the line </description> <tutorials> </tutorials> diff --git a/doc/classes/Object.xml b/doc/classes/Object.xml index 4fe43814d1..9c2a65ce5b 100644 --- a/doc/classes/Object.xml +++ b/doc/classes/Object.xml @@ -327,6 +327,14 @@ <description> </description> </method> + <method name="remove_meta"> + <return type="void"> + </return> + <argument index="0" name="name" type="String"> + </argument> + <description> + </description> + </method> <method name="set"> <return type="void"> </return> diff --git a/doc/classes/Physics2DServer.xml b/doc/classes/Physics2DServer.xml index 641e1898ff..172420e4ca 100644 --- a/doc/classes/Physics2DServer.xml +++ b/doc/classes/Physics2DServer.xml @@ -18,6 +18,8 @@ </argument> <argument index="2" name="transform" type="Transform2D" default="Transform2D( 1, 0, 0, 1, 0, 0 )"> </argument> + <argument index="3" name="disabled" type="bool" default="false"> + </argument> <description> Adds a shape to the area, along with a transform matrix. Shapes are usually referenced by their index, so you should track which shape has a given index. </description> @@ -251,7 +253,7 @@ </argument> <argument index="1" name="shape_idx" type="int"> </argument> - <argument index="2" name="disable" type="bool"> + <argument index="2" name="disabled" type="bool"> </argument> <description> Disables a given shape in an area. @@ -346,6 +348,8 @@ </argument> <argument index="2" name="transform" type="Transform2D" default="Transform2D( 1, 0, 0, 1, 0, 0 )"> </argument> + <argument index="3" name="disabled" type="bool" default="false"> + </argument> <description> Adds a shape to the body, along with a transform matrix. Shapes are usually referenced by their index, so you should track which shape has a given index. </description> @@ -746,7 +750,7 @@ </argument> <argument index="1" name="shape_idx" type="int"> </argument> - <argument index="2" name="disable" type="bool"> + <argument index="2" name="disabled" type="bool"> </argument> <description> Disables shape in body if [code]disable[/code] is [code]true[/code]. diff --git a/doc/classes/PhysicsServer.xml b/doc/classes/PhysicsServer.xml index 25869a853c..78a6ed8ac0 100644 --- a/doc/classes/PhysicsServer.xml +++ b/doc/classes/PhysicsServer.xml @@ -18,6 +18,8 @@ </argument> <argument index="2" name="transform" type="Transform" default="Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0 )"> </argument> + <argument index="3" name="disabled" type="bool" default="false"> + </argument> <description> Adds a shape to the area, along with a transform matrix. Shapes are usually referenced by their index, so you should track which shape has a given index. </description> @@ -246,6 +248,18 @@ Substitutes a given area shape by another. The old shape is selected by its index, the new one by its [RID]. </description> </method> + <method name="area_set_shape_disabled"> + <return type="void"> + </return> + <argument index="0" name="area" type="RID"> + </argument> + <argument index="1" name="shape_idx" type="int"> + </argument> + <argument index="2" name="disabled" type="bool"> + </argument> + <description> + </description> + </method> <method name="area_set_shape_transform"> <return type="void"> </return> @@ -334,6 +348,8 @@ </argument> <argument index="2" name="transform" type="Transform" default="Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0 )"> </argument> + <argument index="3" name="disabled" type="bool" default="false"> + </argument> <description> Adds a shape to the body, along with a transform matrix. Shapes are usually referenced by their index, so you should track which shape has a given index. </description> @@ -750,6 +766,18 @@ Substitutes a given body shape by another. The old shape is selected by its index, the new one by its [RID]. </description> </method> + <method name="body_set_shape_disabled"> + <return type="void"> + </return> + <argument index="0" name="body" type="RID"> + </argument> + <argument index="1" name="shape_idx" type="int"> + </argument> + <argument index="2" name="disabled" type="bool"> + </argument> + <description> + </description> + </method> <method name="body_set_shape_transform"> <return type="void"> </return> diff --git a/doc/classes/ScriptEditor.xml b/doc/classes/ScriptEditor.xml index 666ab15802..28e1f75ac1 100644 --- a/doc/classes/ScriptEditor.xml +++ b/doc/classes/ScriptEditor.xml @@ -55,6 +55,15 @@ Returns an array with all [Script] objects which are currently open in editor. </description> </method> + <method name="goto_line"> + <return type="void"> + </return> + <argument index="0" name="line_number" type="int"> + </argument> + <description> + Goes to the specified line in the current script. + </description> + </method> <method name="open_script_create_dialog"> <return type="void"> </return> diff --git a/doc/classes/TextEdit.xml b/doc/classes/TextEdit.xml index fa78fbe305..0210815d75 100644 --- a/doc/classes/TextEdit.xml +++ b/doc/classes/TextEdit.xml @@ -524,8 +524,14 @@ </theme_item> <theme_item name="current_line_color" type="Color"> </theme_item> + <theme_item name="executing_line_color" type="Color"> + </theme_item> <theme_item name="focus" type="StyleBox"> </theme_item> + <theme_item name="fold" type="Texture"> + </theme_item> + <theme_item name="folded" type="Texture"> + </theme_item> <theme_item name="font" type="Font"> </theme_item> <theme_item name="font_color" type="Color"> diff --git a/drivers/gl_context/SCsub b/drivers/gl_context/SCsub index efb26a7908..ef5b57a0cc 100644 --- a/drivers/gl_context/SCsub +++ b/drivers/gl_context/SCsub @@ -10,7 +10,7 @@ if (env["platform"] in ["haiku", "osx", "windows", "x11"]): ] thirdparty_sources = [thirdparty_dir + file for file in thirdparty_sources] - env.Append(CPPPATH=[thirdparty_dir]) + env.Prepend(CPPPATH=[thirdparty_dir]) env.Append(CPPFLAGS=['-DGLAD_ENABLED']) env.Append(CPPFLAGS=['-DGLES_OVER_GL']) diff --git a/drivers/gles2/rasterizer_scene_gles2.cpp b/drivers/gles2/rasterizer_scene_gles2.cpp index 9f1425189c..99eb0665d6 100644 --- a/drivers/gles2/rasterizer_scene_gles2.cpp +++ b/drivers/gles2/rasterizer_scene_gles2.cpp @@ -2845,7 +2845,7 @@ void RasterizerSceneGLES2::render_scene(const Transform &p_cam_transform, const glBlendEquation(GL_FUNC_ADD); glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA); - render_list.sort_by_depth(true); + render_list.sort_by_reverse_depth_and_priority(true); _render_render_list(&render_list.elements[render_list.max_elements - render_list.alpha_element_count], render_list.alpha_element_count, cam_transform, p_cam_projection, p_shadow_atlas, env, env_radiance_tex, 0.0, 0.0, reverse_cull, true, false); diff --git a/drivers/gles2/rasterizer_scene_gles2.h b/drivers/gles2/rasterizer_scene_gles2.h index f23e45b52f..48672991d1 100644 --- a/drivers/gles2/rasterizer_scene_gles2.h +++ b/drivers/gles2/rasterizer_scene_gles2.h @@ -502,7 +502,8 @@ public: enum { MAX_LIGHTS = 255, MAX_REFLECTION_PROBES = 255, - DEFAULT_MAX_ELEMENTS = 65536 + DEFAULT_MAX_ELEMENTS = 65536, + SORT_KEY_PRIORITY_SHIFT = 56 }; int max_elements; @@ -598,6 +599,29 @@ public: } } + struct SortByReverseDepthAndPriority { + + _FORCE_INLINE_ bool operator()(const Element *A, const Element *B) const { + uint32_t layer_A = uint32_t(A->sort_key >> SORT_KEY_PRIORITY_SHIFT); + uint32_t layer_B = uint32_t(B->sort_key >> SORT_KEY_PRIORITY_SHIFT); + if (layer_A == layer_B) { + return A->instance->depth > B->instance->depth; + } else { + return layer_A < layer_B; + } + } + }; + + void sort_by_reverse_depth_and_priority(bool p_alpha) { //used for alpha + + SortArray<Element *, SortByReverseDepthAndPriority> sorter; + if (p_alpha) { + sorter.sort(&elements[max_elements - alpha_element_count], alpha_element_count); + } else { + sorter.sort(elements, element_count); + } + } + // element adding and stuff _FORCE_INLINE_ Element *add_element() { diff --git a/drivers/png/SCsub b/drivers/png/SCsub index 97ba1de3db..9dc80244ff 100644 --- a/drivers/png/SCsub +++ b/drivers/png/SCsub @@ -26,9 +26,9 @@ if env['builtin_libpng']: ] thirdparty_sources = [thirdparty_dir + file for file in thirdparty_sources] - env_png.Append(CPPPATH=[thirdparty_dir]) + env_png.Prepend(CPPPATH=[thirdparty_dir]) # Needed for drivers includes and in platform/javascript - env.Append(CPPPATH=[thirdparty_dir]) + env.Prepend(CPPPATH=[thirdparty_dir]) # Currently .ASM filter_neon.S does not compile on NT. import os diff --git a/editor/animation_bezier_editor.cpp b/editor/animation_bezier_editor.cpp index f6d4a2665c..e524dffd43 100644 --- a/editor/animation_bezier_editor.cpp +++ b/editor/animation_bezier_editor.cpp @@ -453,6 +453,8 @@ void AnimationBezierTrackEdit::_notification(int p_what) { ep.point_rect.size = bezier_icon->get_size(); if (selection.has(i)) { draw_texture(selected_icon, ep.point_rect.position); + draw_string(font, ep.point_rect.position + Vector2(8, -font->get_height() - 4), TTR("Time:") + " " + rtos(Math::stepify(offset, 0.001)), accent); + draw_string(font, ep.point_rect.position + Vector2(8, -8), TTR("Value:") + " " + rtos(Math::stepify(value, 0.001)), accent); } else { draw_texture(bezier_icon, ep.point_rect.position); } @@ -518,6 +520,12 @@ void AnimationBezierTrackEdit::set_animation_and_track(const Ref<Animation> &p_a animation = p_animation; track = p_track; + if (is_connected("select_key", editor, "_key_selected")) + disconnect("select_key", editor, "_key_selected"); + if (is_connected("deselect_key", editor, "_key_deselected")) + disconnect("deselect_key", editor, "_key_deselected"); + connect("select_key", editor, "_key_selected", varray(p_track), CONNECT_DEFERRED); + connect("deselect_key", editor, "_key_deselected", varray(p_track), CONNECT_DEFERRED); update(); } @@ -536,6 +544,7 @@ void AnimationBezierTrackEdit::set_timeline(AnimationTimelineEdit *p_timeline) { } void AnimationBezierTrackEdit::set_editor(AnimationTrackEditor *p_editor) { editor = p_editor; + connect("clear_selection", editor, "_clear_selection"); } void AnimationBezierTrackEdit::_play_position_draw() { @@ -578,6 +587,7 @@ String AnimationBezierTrackEdit::get_tooltip(const Point2 &p_pos) const { void AnimationBezierTrackEdit::_clear_selection() { selection.clear(); + emit_signal("clear_selection"); update(); } @@ -598,6 +608,7 @@ void AnimationBezierTrackEdit::_select_at_anim(const Ref<Animation> &p_anim, int ERR_FAIL_COND(idx < 0); selection.insert(idx); + emit_signal("select_key", idx, true); update(); } @@ -653,20 +664,22 @@ void AnimationBezierTrackEdit::_gui_input(const Ref<InputEvent> &p_event) { if (mb.is_valid() && mb->get_button_index() == BUTTON_RIGHT && mb->is_pressed()) { menu_insert_key = mb->get_position(); - Vector2 popup_pos = get_global_transform().xform(mb->get_position()); - - menu->clear(); - menu->add_icon_item(bezier_icon, TTR("Insert Key Here"), MENU_KEY_INSERT); - if (selection.size()) { - menu->add_separator(); - menu->add_icon_item(get_icon("Duplicate", "EditorIcons"), TTR("Duplicate Selected Key(s)"), MENU_KEY_DUPLICATE); - menu->add_separator(); - menu->add_icon_item(get_icon("Remove", "EditorIcons"), TTR("Delete Selected Key(s)"), MENU_KEY_DELETE); - } + if (menu_insert_key.x >= timeline->get_name_limit() && menu_insert_key.x <= get_size().width - timeline->get_buttons_width()) { + Vector2 popup_pos = get_global_transform().xform(mb->get_position()); + + menu->clear(); + menu->add_icon_item(bezier_icon, TTR("Insert Key Here"), MENU_KEY_INSERT); + if (selection.size()) { + menu->add_separator(); + menu->add_icon_item(get_icon("Duplicate", "EditorIcons"), TTR("Duplicate Selected Key(s)"), MENU_KEY_DUPLICATE); + menu->add_separator(); + menu->add_icon_item(get_icon("Remove", "EditorIcons"), TTR("Delete Selected Key(s)"), MENU_KEY_DELETE); + } - menu->set_as_minsize(); - menu->set_position(popup_pos); - menu->popup(); + menu->set_as_minsize(); + menu->set_position(popup_pos); + menu->popup(); + } } if (mb.is_valid() && mb->is_pressed() && mb->get_button_index() == BUTTON_LEFT) { @@ -678,6 +691,7 @@ void AnimationBezierTrackEdit::_gui_input(const Ref<InputEvent> &p_event) { for (Map<int, Rect2>::Element *E = subtracks.front(); E; E = E->next()) { if (E->get().has_point(mb->get_position())) { set_animation_and_track(animation, E->key()); + _clear_selection(); return; } } @@ -850,7 +864,7 @@ void AnimationBezierTrackEdit::_gui_input(const Ref<InputEvent> &p_event) { // 2- remove overlapped keys for (Set<int>::Element *E = selection.back(); E; E = E->prev()) { - float newtime = animation->track_get_key_time(track, E->get()) + moving_selection_offset.x; + float newtime = editor->snap_time(animation->track_get_key_time(track, E->get()) + moving_selection_offset.x); int idx = animation->track_find_key(track, newtime, true); if (idx == -1) @@ -872,7 +886,7 @@ void AnimationBezierTrackEdit::_gui_input(const Ref<InputEvent> &p_event) { // 3-move the keys (re insert them) for (Set<int>::Element *E = selection.back(); E; E = E->prev()) { - float newpos = animation->track_get_key_time(track, E->get()) + moving_selection_offset.x; + float newpos = editor->snap_time(animation->track_get_key_time(track, E->get()) + moving_selection_offset.x); /* if (newpos<0) continue; //no add at the beginning @@ -887,7 +901,7 @@ void AnimationBezierTrackEdit::_gui_input(const Ref<InputEvent> &p_event) { // 4-(undo) remove inserted keys for (Set<int>::Element *E = selection.back(); E; E = E->prev()) { - float newpos = animation->track_get_key_time(track, E->get()) + moving_selection_offset.x; + float newpos = editor->snap_time(animation->track_get_key_time(track, E->get()) + moving_selection_offset.x); /* if (newpos<0) continue; //no remove what no inserted @@ -924,7 +938,7 @@ void AnimationBezierTrackEdit::_gui_input(const Ref<InputEvent> &p_event) { for (Set<int>::Element *E = selection.back(); E; E = E->prev()) { float oldpos = animation->track_get_key_time(track, E->get()); - float newpos = oldpos + moving_selection_offset.x; + float newpos = editor->snap_time(oldpos + moving_selection_offset.x); undo_redo->add_do_method(this, "_select_at_anim", animation, track, newpos); undo_redo->add_undo_method(this, "_select_at_anim", animation, track, oldpos); @@ -965,7 +979,7 @@ void AnimationBezierTrackEdit::_gui_input(const Ref<InputEvent> &p_event) { } float y = (get_size().height / 2 - mm->get_position().y) * v_zoom + v_scroll; - float x = ((mm->get_position().x - timeline->get_name_limit()) / timeline->get_zoom_scale()) + timeline->get_value(); + float x = editor->snap_time(((mm->get_position().x - timeline->get_name_limit()) / timeline->get_zoom_scale()) + timeline->get_value()); moving_selection_offset = Vector2(x - animation->track_get_key_time(track, moving_selection_from_key), y - animation->bezier_track_get_key_value(track, moving_selection_from_key)); update(); @@ -1154,8 +1168,8 @@ void AnimationBezierTrackEdit::_bind_methods() { ClassDB::bind_method("_play_position_draw", &AnimationBezierTrackEdit::_play_position_draw); ClassDB::bind_method("_clear_selection", &AnimationBezierTrackEdit::_clear_selection); - ClassDB::bind_method("_clear_selection_for_anim", &AnimationBezierTrackEdit::_clear_selection); - ClassDB::bind_method("_select_at_anim", &AnimationBezierTrackEdit::_clear_selection); + ClassDB::bind_method("_clear_selection_for_anim", &AnimationBezierTrackEdit::_clear_selection_for_anim); + ClassDB::bind_method("_select_at_anim", &AnimationBezierTrackEdit::_select_at_anim); ADD_SIGNAL(MethodInfo("timeline_changed", PropertyInfo(Variant::REAL, "position"), PropertyInfo(Variant::BOOL, "drag"))); ADD_SIGNAL(MethodInfo("remove_request", PropertyInfo(Variant::INT, "track"))); diff --git a/editor/animation_track_editor.cpp b/editor/animation_track_editor.cpp index 4dff7d5b69..61244ab78c 100644 --- a/editor/animation_track_editor.cpp +++ b/editor/animation_track_editor.cpp @@ -309,8 +309,8 @@ public: setting = true; undo_redo->create_action(TTR("Anim Change Keyframe Value"), UndoRedo::MERGE_ENDS); Vector2 prev = animation->bezier_track_get_key_in_handle(track, key); - undo_redo->add_do_method(animation.ptr(), "bezier_track_set_in_handle", track, key, value); - undo_redo->add_undo_method(animation.ptr(), "bezier_track_set_in_handle", track, key, prev); + undo_redo->add_do_method(animation.ptr(), "bezier_track_set_key_in_handle", track, key, value); + undo_redo->add_undo_method(animation.ptr(), "bezier_track_set_key_in_handle", track, key, prev); undo_redo->add_do_method(this, "_update_obj", animation); undo_redo->add_undo_method(this, "_update_obj", animation); undo_redo->commit_action(); @@ -325,8 +325,8 @@ public: setting = true; undo_redo->create_action(TTR("Anim Change Keyframe Value"), UndoRedo::MERGE_ENDS); Vector2 prev = animation->bezier_track_get_key_out_handle(track, key); - undo_redo->add_do_method(animation.ptr(), "bezier_track_set_out_handle", track, key, value); - undo_redo->add_undo_method(animation.ptr(), "bezier_track_set_out_handle", track, key, prev); + undo_redo->add_do_method(animation.ptr(), "bezier_track_set_key_out_handle", track, key, value); + undo_redo->add_undo_method(animation.ptr(), "bezier_track_set_key_out_handle", track, key, prev); undo_redo->add_do_method(this, "_update_obj", animation); undo_redo->add_undo_method(this, "_update_obj", animation); undo_redo->commit_action(); @@ -1274,13 +1274,7 @@ void AnimationTrackEdit::_notification(int p_what) { } else if (animation->track_get_type(track) == Animation::TYPE_ANIMATION) { text = TTR("Anim Clips:"); } else { - Vector<StringName> sn = path.get_subnames(); - for (int i = 0; i < sn.size(); i++) { - if (i > 0) { - text += "."; - } - text += sn[i]; - } + text += path.get_concatenated_subnames(); } text_color.a *= 0.7; } else if (node) { @@ -1294,14 +1288,10 @@ void AnimationTrackEdit::_notification(int p_what) { draw_texture(icon, Point2(ofs, int(get_size().height - icon->get_height()) / 2)); icon_cache = icon; - text = node->get_name(); + text = String() + node->get_name() + ":" + path.get_concatenated_subnames(); ofs += hsep; ofs += icon->get_width(); - Vector<StringName> sn = path.get_subnames(); - for (int i = 0; i < sn.size(); i++) { - text += "."; - text += sn[i]; - } + } else { icon_cache = type_icon; @@ -3536,7 +3526,10 @@ void AnimationTrackEditor::_animation_changed() { if (key_edit && key_edit->setting) { //if editing a key, just update the edited track, makes refresh less costly if (key_edit->track < track_edits.size()) { - track_edits[key_edit->track]->update(); + if (animation->track_get_type(key_edit->track) == Animation::TYPE_BEZIER) + bezier_edit->update(); + else + track_edits[key_edit->track]->update(); } return; } diff --git a/editor/code_editor.cpp b/editor/code_editor.cpp index d655f52f5d..ec984e480a 100644 --- a/editor/code_editor.cpp +++ b/editor/code_editor.cpp @@ -1297,6 +1297,8 @@ void CodeTextEditor::_on_settings_change() { text_editor->set_callhint_settings( EDITOR_DEF("text_editor/completion/put_callhint_tooltip_below_current_line", true), EDITOR_DEF("text_editor/completion/callhint_tooltip_offset", Vector2())); + + idle->set_wait_time(EDITOR_DEF("text_editor/completion/idle_parse_delay", 2.0)); } void CodeTextEditor::_text_changed_idle_timeout() { @@ -1411,7 +1413,7 @@ CodeTextEditor::CodeTextEditor() { idle = memnew(Timer); add_child(idle); idle->set_one_shot(true); - idle->set_wait_time(EDITOR_DEF("text_editor/completion/idle_parse_delay", 2)); + idle->set_wait_time(EDITOR_DEF("text_editor/completion/idle_parse_delay", 2.0)); code_complete_timer = memnew(Timer); add_child(code_complete_timer); diff --git a/editor/create_dialog.cpp b/editor/create_dialog.cpp index 26bd651c2b..ac42f15f7f 100644 --- a/editor/create_dialog.cpp +++ b/editor/create_dialog.cpp @@ -721,6 +721,7 @@ CreateDialog::CreateDialog() { favorites->connect("cell_selected", this, "_favorite_selected"); favorites->connect("item_activated", this, "_favorite_activated"); favorites->set_drag_forwarding(this); + favorites->add_constant_override("draw_guides", 1); VBoxContainer *rec_vb = memnew(VBoxContainer); vsc->add_child(rec_vb); @@ -733,6 +734,7 @@ CreateDialog::CreateDialog() { recent->set_hide_folding(true); recent->connect("cell_selected", this, "_history_selected"); recent->connect("item_activated", this, "_history_activated"); + recent->add_constant_override("draw_guides", 1); VBoxContainer *vbc = memnew(VBoxContainer); hsc->add_child(vbc); diff --git a/editor/dependency_editor.cpp b/editor/dependency_editor.cpp index 5df2b687cc..bde73e9268 100644 --- a/editor/dependency_editor.cpp +++ b/editor/dependency_editor.cpp @@ -225,9 +225,9 @@ void DependencyEditor::edit(const String &p_path) { popup_centered_ratio(); if (EditorNode::get_singleton()->is_scene_open(p_path)) { - EditorNode::get_singleton()->show_warning(vformat(TTR("Scene '%s' is currently being edited.\nChanges will not take effect unless reloaded."), p_path.get_file())); + EditorNode::get_singleton()->show_warning(vformat(TTR("Scene '%s' is currently being edited.\nChanges will only take effect when reloaded."), p_path.get_file())); } else if (ResourceCache::has(p_path)) { - EditorNode::get_singleton()->show_warning(vformat(TTR("Resource '%s' is in use.\nChanges will take effect when reloaded."), p_path.get_file())); + EditorNode::get_singleton()->show_warning(vformat(TTR("Resource '%s' is in use.\nChanges will only take effect when reloaded."), p_path.get_file())); } } diff --git a/editor/editor_autoload_settings.cpp b/editor/editor_autoload_settings.cpp index 2f2b0d2cba..e0c90808a0 100644 --- a/editor/editor_autoload_settings.cpp +++ b/editor/editor_autoload_settings.cpp @@ -638,12 +638,12 @@ void EditorAutoloadSettings::autoload_add(const String &p_name, const String &p_ String path = p_path; if (!FileAccess::exists(path)) { - EditorNode::get_singleton()->show_warning(TTR("Invalid Path.") + "\n" + TTR("File does not exist.")); + EditorNode::get_singleton()->show_warning(TTR("Invalid path.") + "\n" + TTR("File does not exist.")); return; } if (!path.begins_with("res://")) { - EditorNode::get_singleton()->show_warning(TTR("Invalid Path.") + "\n" + TTR("Not in resource path.")); + EditorNode::get_singleton()->show_warning(TTR("Invalid path.") + "\n" + TTR("Not in resource path.")); return; } diff --git a/editor/editor_dir_dialog.cpp b/editor/editor_dir_dialog.cpp index e8cf730796..e04bca2a9e 100644 --- a/editor/editor_dir_dialog.cpp +++ b/editor/editor_dir_dialog.cpp @@ -133,7 +133,7 @@ void EditorDirDialog::_make_dir() { TreeItem *ti = tree->get_selected(); if (!ti) { - mkdirerr->set_text(TTR("Please select a base directory first")); + mkdirerr->set_text(TTR("Please select a base directory first.")); mkdirerr->popup_centered_minsize(); return; } diff --git a/editor/editor_node.cpp b/editor/editor_node.cpp index df653d6d03..8703076a57 100644 --- a/editor/editor_node.cpp +++ b/editor/editor_node.cpp @@ -1631,7 +1631,7 @@ void EditorNode::_edit_current() { editable_warning = TTR("This resource belongs to a scene that was imported, so it's not editable.\nPlease read the documentation relevant to importing scenes to better understand this workflow."); } else { if ((!get_edited_scene() || get_edited_scene()->get_filename() != base_path) && ResourceLoader::get_resource_type(base_path) == "PackedScene") { - editable_warning = TTR("This resource belongs to a scene that was instanced or inherited.\nChanges to it will not be kept when saving the current scene."); + editable_warning = TTR("This resource belongs to a scene that was instanced or inherited.\nChanges to it won't be kept when saving the current scene."); } } } else if (current_res->get_path().is_resource_file()) { @@ -1656,14 +1656,14 @@ void EditorNode::_edit_current() { if (get_edited_scene() && get_edited_scene()->get_filename() != String()) { String source_scene = get_edited_scene()->get_filename(); if (FileAccess::exists(source_scene + ".import")) { - editable_warning = TTR("This scene was imported, so changes to it will not be kept.\nInstancing it or inheriting will allow making changes to it.\nPlease read the documentation relevant to importing scenes to better understand this workflow."); + editable_warning = TTR("This scene was imported, so changes to it won't be kept.\nInstancing it or inheriting will allow making changes to it.\nPlease read the documentation relevant to importing scenes to better understand this workflow."); } } } else { if (current_obj->is_class("ScriptEditorDebuggerInspectedObject")) { - editable_warning = TTR("This is a remote object so changes to it will not be kept.\nPlease read the documentation relevant to debugging to better understand this workflow."); + editable_warning = TTR("This is a remote object, so changes to it won't be kept.\nPlease read the documentation relevant to debugging to better understand this workflow."); capitalize = false; disable_folding = true; } diff --git a/editor/editor_settings.cpp b/editor/editor_settings.cpp index bf582ca004..e80d3e1b37 100644 --- a/editor/editor_settings.cpp +++ b/editor/editor_settings.cpp @@ -407,6 +407,7 @@ void EditorSettings::_load_defaults(Ref<ConfigFile> p_extra_config) { _initial_set("text_editor/theme/color_theme", "Adaptive"); hints["text_editor/theme/color_theme"] = PropertyInfo(Variant::STRING, "text_editor/theme/color_theme", PROPERTY_HINT_ENUM, "Adaptive,Default,Custom"); _initial_set("text_editor/theme/line_spacing", 6); + hints["text_editor/theme/line_spacing"] = PropertyInfo(Variant::INT, "text_editor/theme/line_spacing", PROPERTY_HINT_RANGE, "0,50,1"); _load_default_text_editor_theme(); @@ -459,12 +460,14 @@ void EditorSettings::_load_defaults(Ref<ConfigFile> p_extra_config) { _initial_set("text_editor/cursor/right_click_moves_caret", true); // Completion - _initial_set("text_editor/completion/idle_parse_delay", 2); + _initial_set("text_editor/completion/idle_parse_delay", 2.0); + hints["text_editor/completion/idle_parse_delay"] = PropertyInfo(Variant::REAL, "text_editor/completion/idle_parse_delay", PROPERTY_HINT_RANGE, "0.1, 10, 0.01"); _initial_set("text_editor/completion/auto_brace_complete", false); _initial_set("text_editor/completion/put_callhint_tooltip_below_current_line", true); _initial_set("text_editor/completion/callhint_tooltip_offset", Vector2()); _initial_set("text_editor/completion/complete_file_paths", true); _initial_set("text_editor/completion/add_type_hints", false); + _initial_set("text_editor/completion/use_single_quotes", false); // Help _initial_set("text_editor/help/show_help_index", true); diff --git a/editor/export_template_manager.cpp b/editor/export_template_manager.cpp index aa2a03510d..ed6d6578ad 100644 --- a/editor/export_template_manager.cpp +++ b/editor/export_template_manager.cpp @@ -690,7 +690,7 @@ ExportTemplateManager::ExportTemplateManager() { remove_confirm->connect("confirmed", this, "_uninstall_template_confirm"); template_open = memnew(FileDialog); - template_open->set_title(TTR("Select template file")); + template_open->set_title(TTR("Select Template File")); template_open->add_filter("*.tpz ; Godot Export Templates"); template_open->set_access(FileDialog::ACCESS_FILESYSTEM); template_open->set_mode(FileDialog::MODE_OPEN_FILE); diff --git a/editor/filesystem_dock.cpp b/editor/filesystem_dock.cpp index aade606412..6248680a52 100644 --- a/editor/filesystem_dock.cpp +++ b/editor/filesystem_dock.cpp @@ -1208,7 +1208,7 @@ void FileSystemDock::_make_dir_confirm() { return; } else if (dir_name.find("/") != -1 || dir_name.find("\\") != -1 || dir_name.find(":") != -1 || dir_name.find("*") != -1 || dir_name.find("|") != -1 || dir_name.find(">") != -1 || dir_name.ends_with(".") || dir_name.ends_with(" ")) { - EditorNode::get_singleton()->show_warning(TTR("Provided name contains invalid characters")); + EditorNode::get_singleton()->show_warning(TTR("Provided name contains invalid characters.")); return; } diff --git a/editor/import/resource_importer_scene.cpp b/editor/import/resource_importer_scene.cpp index 8f66cce39a..1de276b940 100644 --- a/editor/import/resource_importer_scene.cpp +++ b/editor/import/resource_importer_scene.cpp @@ -1290,7 +1290,10 @@ Error ResourceImporterScene::import(const String &p_source_file, const String &p Object::cast_to<Spatial>(scene)->scale(Vector3(root_scale, root_scale, root_scale)); } - scene->set_name(p_options["nodes/root_name"]); + if (p_options["nodes/root_name"] != "Scene Root") + scene->set_name(p_options["nodes/root_name"]); + else + scene->set_name(p_save_path.get_file().get_basename()); err = OK; diff --git a/editor/plugins/animation_blend_space_2d_editor.cpp b/editor/plugins/animation_blend_space_2d_editor.cpp index 918f3a2149..5e8fb8e059 100644 --- a/editor/plugins/animation_blend_space_2d_editor.cpp +++ b/editor/plugins/animation_blend_space_2d_editor.cpp @@ -195,7 +195,7 @@ void AnimationNodeBlendSpace2DEditor::_blend_space_gui_input(const Ref<InputEven //add triangle! if (blend_space->has_triangle(making_triangle[0], making_triangle[1], making_triangle[2])) { making_triangle.clear(); - EditorNode::get_singleton()->show_warning(TTR("Triangle already exists")); + EditorNode::get_singleton()->show_warning(TTR("Triangle already exists.")); return; } diff --git a/editor/plugins/animation_blend_tree_editor_plugin.cpp b/editor/plugins/animation_blend_tree_editor_plugin.cpp index f13c2170ea..bfee76492b 100644 --- a/editor/plugins/animation_blend_tree_editor_plugin.cpp +++ b/editor/plugins/animation_blend_tree_editor_plugin.cpp @@ -949,7 +949,7 @@ AnimationNodeBlendTreeEditor::AnimationNodeBlendTreeEditor() { filter_dialog->add_child(filter_vbox); filter_enabled = memnew(CheckBox); - filter_enabled->set_text(TTR("Enable filtering")); + filter_enabled->set_text(TTR("Enable Filtering")); filter_enabled->connect("pressed", this, "_filter_toggled"); filter_vbox->add_child(filter_enabled); diff --git a/editor/plugins/canvas_item_editor_plugin.cpp b/editor/plugins/canvas_item_editor_plugin.cpp index ab5ff7dee4..88bb8e38fe 100644 --- a/editor/plugins/canvas_item_editor_plugin.cpp +++ b/editor/plugins/canvas_item_editor_plugin.cpp @@ -3433,7 +3433,7 @@ void CanvasItemEditor::_notification(int p_what) { p->add_separator(); p->add_icon_item(get_icon("ControlAlignWide", "EditorIcons"), "Full Rect", ANCHORS_AND_MARGINS_PRESET_WIDE); p->add_separator(); - p->add_submenu_item(TTR("Anchors only"), "Anchors"); + p->add_submenu_item(TTR("Anchors Only"), "Anchors"); p->set_item_icon(20, get_icon("Anchor", "EditorIcons")); anchors_popup->clear(); @@ -4811,24 +4811,24 @@ 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/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_shortcut(ED_SHORTCUT("canvas_item_editor/configure_snap", TTR("Configure Snap...")), SNAP_CONFIGURE); 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); - p->add_submenu_item(TTR("Smart snapping"), "SmartSnapping"); + p->add_submenu_item(TTR("Smart Snapping"), "SmartSnapping"); smartsnap_config_popup = memnew(PopupMenu); p->add_child(smartsnap_config_popup); smartsnap_config_popup->set_name("SmartSnapping"); smartsnap_config_popup->connect("id_pressed", this, "_popup_callback"); smartsnap_config_popup->set_hide_on_checkable_item_selection(false); - smartsnap_config_popup->add_check_shortcut(ED_SHORTCUT("canvas_item_editor/snap_node_parent", TTR("Snap to parent")), SNAP_USE_NODE_PARENT); - smartsnap_config_popup->add_check_shortcut(ED_SHORTCUT("canvas_item_editor/snap_node_anchors", TTR("Snap to node anchor")), SNAP_USE_NODE_ANCHORS); - smartsnap_config_popup->add_check_shortcut(ED_SHORTCUT("canvas_item_editor/snap_node_sides", TTR("Snap to node sides")), SNAP_USE_NODE_SIDES); - smartsnap_config_popup->add_check_shortcut(ED_SHORTCUT("canvas_item_editor/snap_node_center", TTR("Snap to node center")), SNAP_USE_NODE_CENTER); - smartsnap_config_popup->add_check_shortcut(ED_SHORTCUT("canvas_item_editor/snap_other_nodes", TTR("Snap to other nodes")), SNAP_USE_OTHER_NODES); - smartsnap_config_popup->add_check_shortcut(ED_SHORTCUT("canvas_item_editor/snap_guides", TTR("Snap to guides")), SNAP_USE_GUIDES); + smartsnap_config_popup->add_check_shortcut(ED_SHORTCUT("canvas_item_editor/snap_node_parent", TTR("Snap to Parent")), SNAP_USE_NODE_PARENT); + smartsnap_config_popup->add_check_shortcut(ED_SHORTCUT("canvas_item_editor/snap_node_anchors", TTR("Snap to Node Anchor")), SNAP_USE_NODE_ANCHORS); + smartsnap_config_popup->add_check_shortcut(ED_SHORTCUT("canvas_item_editor/snap_node_sides", TTR("Snap to Node Sides")), SNAP_USE_NODE_SIDES); + smartsnap_config_popup->add_check_shortcut(ED_SHORTCUT("canvas_item_editor/snap_node_center", TTR("Snap to Node Center")), SNAP_USE_NODE_CENTER); + smartsnap_config_popup->add_check_shortcut(ED_SHORTCUT("canvas_item_editor/snap_other_nodes", TTR("Snap to Other Nodes")), SNAP_USE_OTHER_NODES); + smartsnap_config_popup->add_check_shortcut(ED_SHORTCUT("canvas_item_editor/snap_guides", TTR("Snap to Guides")), SNAP_USE_GUIDES); hb->add_child(memnew(VSeparator)); @@ -5466,7 +5466,7 @@ CanvasItemEditorViewport::CanvasItemEditorViewport(EditorNode *p_node, CanvasIte selector = memnew(AcceptDialog); editor->get_gui_base()->add_child(selector); - selector->set_title(TTR("Change default type")); + selector->set_title(TTR("Change Default Type")); selector->connect("confirmed", this, "_on_change_type_confirmed"); selector->connect("popup_hide", this, "_on_change_type_closed"); diff --git a/editor/plugins/curve_editor_plugin.cpp b/editor/plugins/curve_editor_plugin.cpp index 2c0dd5f1db..55feb40c2c 100644 --- a/editor/plugins/curve_editor_plugin.cpp +++ b/editor/plugins/curve_editor_plugin.cpp @@ -53,11 +53,11 @@ CurveEditor::CurveEditor() { _presets_menu = memnew(PopupMenu); _presets_menu->set_name("_presets_menu"); - _presets_menu->add_item(TTR("Flat0"), PRESET_FLAT0); - _presets_menu->add_item(TTR("Flat1"), PRESET_FLAT1); + _presets_menu->add_item(TTR("Flat 0"), PRESET_FLAT0); + _presets_menu->add_item(TTR("Flat 1"), PRESET_FLAT1); _presets_menu->add_item(TTR("Linear"), PRESET_LINEAR); - _presets_menu->add_item(TTR("Ease in"), PRESET_EASE_IN); - _presets_menu->add_item(TTR("Ease out"), PRESET_EASE_OUT); + _presets_menu->add_item(TTR("Ease In"), PRESET_EASE_IN); + _presets_menu->add_item(TTR("Ease Out"), PRESET_EASE_OUT); _presets_menu->add_item(TTR("Smoothstep"), PRESET_SMOOTHSTEP); _presets_menu->connect("id_pressed", this, "_on_preset_item_selected"); _context_menu->add_child(_presets_menu); @@ -330,10 +330,10 @@ void CurveEditor::open_context_menu(Vector2 pos) { _context_menu->clear(); if (_curve_ref.is_valid()) { - _context_menu->add_item(TTR("Add point"), CONTEXT_ADD_POINT); + _context_menu->add_item(TTR("Add Point"), CONTEXT_ADD_POINT); if (_selected_point >= 0) { - _context_menu->add_item(TTR("Remove point"), CONTEXT_REMOVE_POINT); + _context_menu->add_item(TTR("Remove Point"), CONTEXT_REMOVE_POINT); if (_selected_tangent != TANGENT_NONE) { _context_menu->add_separator(); @@ -351,12 +351,12 @@ void CurveEditor::open_context_menu(Vector2 pos) { _context_menu->add_separator(); if (_selected_point > 0) { - _context_menu->add_check_item(TTR("Left linear"), CONTEXT_LEFT_LINEAR); + _context_menu->add_check_item(TTR("Left Linear"), CONTEXT_LEFT_LINEAR); _context_menu->set_item_checked(_context_menu->get_item_index(CONTEXT_LEFT_LINEAR), _curve_ref->get_point_left_mode(_selected_point) == Curve::TANGENT_LINEAR); } if (_selected_point + 1 < _curve_ref->get_point_count()) { - _context_menu->add_check_item(TTR("Right linear"), CONTEXT_RIGHT_LINEAR); + _context_menu->add_check_item(TTR("Right Linear"), CONTEXT_RIGHT_LINEAR); _context_menu->set_item_checked(_context_menu->get_item_index(CONTEXT_RIGHT_LINEAR), _curve_ref->get_point_right_mode(_selected_point) == Curve::TANGENT_LINEAR); } @@ -366,7 +366,7 @@ void CurveEditor::open_context_menu(Vector2 pos) { _context_menu->add_separator(); } - _context_menu->add_submenu_item(TTR("Load preset"), _presets_menu->get_name()); + _context_menu->add_submenu_item(TTR("Load Preset"), _presets_menu->get_name()); _context_menu->set_size(Size2(0, 0)); _context_menu->popup(); diff --git a/editor/plugins/physical_bone_plugin.cpp b/editor/plugins/physical_bone_plugin.cpp index 9ea37aceb9..96681a105f 100644 --- a/editor/plugins/physical_bone_plugin.cpp +++ b/editor/plugins/physical_bone_plugin.cpp @@ -61,7 +61,7 @@ PhysicalBoneEditor::PhysicalBoneEditor(EditorNode *p_editor) : button_transform_joint = memnew(ToolButton); spatial_editor_hb->add_child(button_transform_joint); - button_transform_joint->set_text(TTR("Move joint")); + button_transform_joint->set_text(TTR("Move Joint")); button_transform_joint->set_icon(SpatialEditor::get_singleton()->get_icon("PhysicalBone", "EditorIcons")); button_transform_joint->set_toggle_mode(true); button_transform_joint->connect("toggled", this, "_on_toggle_button_transform_joint"); diff --git a/editor/plugins/script_editor_plugin.cpp b/editor/plugins/script_editor_plugin.cpp index d84a5a1e48..0982da784f 100644 --- a/editor/plugins/script_editor_plugin.cpp +++ b/editor/plugins/script_editor_plugin.cpp @@ -2950,6 +2950,7 @@ void ScriptEditor::_bind_methods() { ClassDB::bind_method(D_METHOD("can_drop_data_fw", "point", "data", "from"), &ScriptEditor::can_drop_data_fw); ClassDB::bind_method(D_METHOD("drop_data_fw", "point", "data", "from"), &ScriptEditor::drop_data_fw); + ClassDB::bind_method(D_METHOD("goto_line", "line_number"), &ScriptEditor::_goto_script_line2); ClassDB::bind_method(D_METHOD("get_current_script"), &ScriptEditor::_get_current_script); ClassDB::bind_method(D_METHOD("get_open_scripts"), &ScriptEditor::_get_open_scripts); ClassDB::bind_method(D_METHOD("open_script_create_dialog", "base_name", "base_path"), &ScriptEditor::open_script_create_dialog); diff --git a/editor/plugins/tile_map_editor_plugin.cpp b/editor/plugins/tile_map_editor_plugin.cpp index 6b66bb6891..29a54f815d 100644 --- a/editor/plugins/tile_map_editor_plugin.cpp +++ b/editor/plugins/tile_map_editor_plugin.cpp @@ -240,22 +240,23 @@ void TileMapEditor::set_selected_tiles(Vector<int> p_tiles) { palette->ensure_current_is_visible(); } -void TileMapEditor::_create_set_cell_undo(const Vector2 &p_vec, const CellOp &p_cell_old, const CellOp &p_cell_new) { +Dictionary TileMapEditor::_create_cell_dictionary(int tile, bool flip_x, bool flip_y, bool transpose, Vector2 autotile_coord) { - Dictionary cell_old; - Dictionary cell_new; + Dictionary cell; - cell_old["id"] = p_cell_old.idx; - cell_old["flip_h"] = p_cell_old.xf; - cell_old["flip_y"] = p_cell_old.yf; - cell_old["transpose"] = p_cell_old.tr; - cell_old["auto_coord"] = p_cell_old.ac; + cell["id"] = tile; + cell["flip_h"] = flip_x; + cell["flip_y"] = flip_y; + cell["transpose"] = transpose; + cell["auto_coord"] = autotile_coord; - cell_new["id"] = p_cell_new.idx; - cell_new["flip_h"] = p_cell_new.xf; - cell_new["flip_y"] = p_cell_new.yf; - cell_new["transpose"] = p_cell_new.tr; - cell_new["auto_coord"] = p_cell_new.ac; + return cell; +} + +void TileMapEditor::_create_set_cell_undo_redo(const Vector2 &p_vec, const CellOp &p_cell_old, const CellOp &p_cell_new) { + + Dictionary cell_old = _create_cell_dictionary(p_cell_old.idx, p_cell_old.xf, p_cell_old.yf, p_cell_old.tr, p_cell_old.ac); + Dictionary cell_new = _create_cell_dictionary(p_cell_new.idx, p_cell_new.xf, p_cell_new.yf, p_cell_new.tr, p_cell_new.ac); undo_redo->add_undo_method(node, "_set_celld", p_vec, cell_old); undo_redo->add_do_method(node, "_set_celld", p_vec, cell_new); @@ -271,7 +272,7 @@ void TileMapEditor::_finish_undo() { if (undo_data.size()) { for (Map<Point2i, CellOp>::Element *E = undo_data.front(); E; E = E->next()) { - _create_set_cell_undo(E->key(), E->get(), _get_op_from_cell(E->key())); + _create_set_cell_undo_redo(E->key(), E->get(), _get_op_from_cell(E->key())); } undo_data.clear(); @@ -319,10 +320,7 @@ void TileMapEditor::_set_cell(const Point2i &p_pos, Vector<int> p_values, bool p } } - Variant v_pos_x = p_pos.x, v_pos_y = p_pos.y, v_tile = p_value, v_flip_h = p_flip_h, v_flip_v = p_flip_v, v_transpose = p_transpose, v_autotile_coord = Vector2(p_autotile_coord.x, p_autotile_coord.y); - const Variant *args[7] = { &v_pos_x, &v_pos_y, &v_tile, &v_flip_h, &v_flip_v, &v_transpose, &v_autotile_coord }; - Variant::CallError ce; - node->call("set_cell", args, 7, ce); + node->_set_celld(p_pos, _create_cell_dictionary(p_value, p_flip_h, p_flip_v, p_transpose, p_autotile_coord)); if (manual_autotile || (p_value != -1 && node->get_tileset()->tile_get_tile_mode(p_value) == TileSet::ATLAS_TILE)) { if (current != -1) { diff --git a/editor/plugins/tile_map_editor_plugin.h b/editor/plugins/tile_map_editor_plugin.h index fc6fefd992..fcdada1111 100644 --- a/editor/plugins/tile_map_editor_plugin.h +++ b/editor/plugins/tile_map_editor_plugin.h @@ -193,9 +193,10 @@ class TileMapEditor : public VBoxContainer { void _palette_selected(int index); void _palette_multi_selected(int index, bool selected); + Dictionary _create_cell_dictionary(int tile, bool flip_x, bool flip_y, bool transpose, Vector2 autotile_coord); void _start_undo(const String &p_action); void _finish_undo(); - void _create_set_cell_undo(const Vector2 &p_vec, const CellOp &p_cell_old, const CellOp &p_cell_new); + void _create_set_cell_undo_redo(const Vector2 &p_vec, const CellOp &p_cell_old, const CellOp &p_cell_new); void _set_cell(const Point2i &p_pos, Vector<int> p_values, bool p_flip_h = false, bool p_flip_v = false, bool p_transpose = false, const Point2i p_autotile_coord = Point2()); void _canvas_mouse_enter(); diff --git a/editor/project_manager.cpp b/editor/project_manager.cpp index 095ec891cd..709c2caa96 100644 --- a/editor/project_manager.cpp +++ b/editor/project_manager.cpp @@ -765,7 +765,7 @@ public: set_title(TTR("Install Project:") + " " + zip_title); get_ok()->set_text(TTR("Install & Edit")); - name_container->hide(); + name_container->show(); install_path_container->hide(); rasterizer_container->hide(); project_path->grab_focus(); @@ -798,7 +798,7 @@ public: create_dir = memnew(Button); pnhb->add_child(create_dir); - create_dir->set_text(TTR("Create folder")); + create_dir->set_text(TTR("Create Folder")); create_dir->connect("pressed", this, "_create_folder"); path_container = memnew(VBoxContainer); @@ -987,6 +987,24 @@ void ProjectManager::_update_project_buttons() { open_btn->set_disabled(empty_selection); rename_btn->set_disabled(empty_selection); run_btn->set_disabled(empty_selection); + + bool missing_projects = false; + Map<String, String> list_all_projects; + for (int i = 0; i < scroll_children->get_child_count(); i++) { + HBoxContainer *hb = Object::cast_to<HBoxContainer>(scroll_children->get_child(i)); + if (hb) { + list_all_projects.insert(hb->get_meta("name"), hb->get_meta("main_scene")); + } + } + for (Map<String, String>::Element *E = list_all_projects.front(); E; E = E->next()) { + String project_name = E->key().replace("::", "/") + "/project.godot"; + if (!FileAccess::exists(project_name)) { + missing_projects = true; + break; + } + } + + erase_missing_btn->set_visible(missing_projects); } void ProjectManager::_panel_input(const Ref<InputEvent> &p_ev, Node *p_hb) { @@ -1530,13 +1548,13 @@ void ProjectManager::_open_selected_projects_ask() { // Check if the config_version property was empty or 0 if (config_version == 0) { - ask_update_settings->set_text(vformat(TTR("The following project settings file does not specify the version of Godot through which it was created.\n\n%s\n\nIf you proceed with opening it, it will be converted to Godot's current configuration file format.\nWarning: You will not be able to open the project with previous versions of the engine anymore."), conf)); + ask_update_settings->set_text(vformat(TTR("The following project settings file does not specify the version of Godot through which it was created.\n\n%s\n\nIf you proceed with opening it, it will be converted to Godot's current configuration file format.\nWarning: You won't be able to open the project with previous versions of the engine anymore."), conf)); ask_update_settings->popup_centered_minsize(); return; } // Check if we need to convert project settings from an earlier engine version if (config_version < ProjectSettings::CONFIG_VERSION) { - ask_update_settings->set_text(vformat(TTR("The following project settings file was generated by an older engine version, and needs to be converted for this version:\n\n%s\n\nDo you want to convert it?\nWarning: You will not be able to open the project with previous versions of the engine anymore."), conf)); + ask_update_settings->set_text(vformat(TTR("The following project settings file was generated by an older engine version, and needs to be converted for this version:\n\n%s\n\nDo you want to convert it?\nWarning: You won't be able to open the project with previous versions of the engine anymore."), conf)); ask_update_settings->popup_centered_minsize(); return; } @@ -1557,7 +1575,7 @@ void ProjectManager::_run_project_confirm() { const String &selected_main = E->get(); if (selected_main == "") { - run_error_diag->set_text(TTR("Can't run project: no main scene defined.\nPlease edit the project and set the main scene in \"Project Settings\" under the \"Application\" category.")); + run_error_diag->set_text(TTR("Can't run project: no main scene defined.\nPlease edit the project and set the main scene in the Project Settings under the \"Application\" category.")); run_error_diag->popup_centered(); return; } @@ -1597,7 +1615,7 @@ void ProjectManager::_run_project() { } if (selected_list.size() > 1) { - multi_run_ask->set_text(TTR("Are you sure to run more than one project?")); + multi_run_ask->set_text(vformat(TTR("Are you sure to run %d projects at once?"), selected_list.size())); multi_run_ask->popup_centered_minsize(); } else { _run_project_confirm(); @@ -1700,15 +1718,61 @@ void ProjectManager::_erase_project_confirm() { _load_recent_projects(); } +void ProjectManager::_erase_missing_projects_confirm() { + + Map<String, String> list_all_projects; + for (int i = 0; i < scroll_children->get_child_count(); i++) { + HBoxContainer *hb = Object::cast_to<HBoxContainer>(scroll_children->get_child(i)); + if (hb) { + list_all_projects.insert(hb->get_meta("name"), hb->get_meta("main_scene")); + } + } + + if (list_all_projects.size() == 0) { + return; + } + + int deleted_projects = 0; + int remaining_projects = 0; + for (Map<String, String>::Element *E = list_all_projects.front(); E; E = E->next()) { + String project_name = E->key().replace("::", "/") + "/project.godot"; + if (!FileAccess::exists(project_name)) { + deleted_projects++; + EditorSettings::get_singleton()->erase("projects/" + E->key()); + EditorSettings::get_singleton()->erase("favorite_projects/" + E->key()); + } else { + remaining_projects++; + } + } + print_line("Deleted " + itos(deleted_projects) + " projects, remaining " + itos(remaining_projects) + " projects"); + EditorSettings::get_singleton()->save(); + selected_list.clear(); + last_clicked = ""; + _load_recent_projects(); +} + void ProjectManager::_erase_project() { if (selected_list.size() == 0) return; - erase_ask->set_text(TTR("Remove project from the list? (Folder contents will not be modified)")); + String confirm_message; + if (selected_list.size() >= 2) { + confirm_message = vformat(TTR("Remove %d projects from the list?\nThe project folders' contents won't be modified."), selected_list.size()); + } else { + confirm_message = TTR("Remove this project from the list?\nThe project folder's contents won't be modified."); + } + + erase_ask->set_text(confirm_message); erase_ask->popup_centered_minsize(); } +void ProjectManager::_erase_missing_projects() { + + erase_missing_ask->set_text(TTR("Remove all missing projects from the list? (Folders contents will not be modified)")); + erase_missing_ask->popup_centered_minsize(); +} + void ProjectManager::_language_selected(int p_id) { String lang = language_btn->get_item_metadata(p_id); @@ -1716,7 +1780,7 @@ void ProjectManager::_language_selected(int p_id) { language_btn->set_text(lang); language_btn->set_icon(get_icon("Environment", "EditorIcons")); - language_restart_ask->set_text(TTR("Language changed.\nThe UI will update next time the editor or project manager starts.")); + language_restart_ask->set_text(TTR("Language changed.\nThe interface will update after restarting the editor or project manager.")); language_restart_ask->popup_centered(); } @@ -1777,7 +1841,8 @@ void ProjectManager::_files_dropped(PoolStringArray p_files, int p_screen) { if (confirm) { multi_scan_ask->get_ok()->disconnect("pressed", this, "_scan_multiple_folders"); multi_scan_ask->get_ok()->connect("pressed", this, "_scan_multiple_folders", varray(folders)); - multi_scan_ask->set_text(vformat(TTR("You are about the scan %s folders for existing Godot projects. Do you confirm?"), folders.size())); + multi_scan_ask->set_text( + vformat(TTR("Are you sure to scan %s folders for existing Godot projects?\nThis could take a while."), folders.size())); multi_scan_ask->popup_centered_minsize(); } else { _scan_multiple_folders(folders); @@ -1804,7 +1869,9 @@ void ProjectManager::_bind_methods() { ClassDB::bind_method("_new_project", &ProjectManager::_new_project); ClassDB::bind_method("_rename_project", &ProjectManager::_rename_project); ClassDB::bind_method("_erase_project", &ProjectManager::_erase_project); + ClassDB::bind_method("_erase_missing_projects", &ProjectManager::_erase_missing_projects); ClassDB::bind_method("_erase_project_confirm", &ProjectManager::_erase_project_confirm); + ClassDB::bind_method("_erase_missing_projects_confirm", &ProjectManager::_erase_missing_projects_confirm); ClassDB::bind_method("_language_selected", &ProjectManager::_language_selected); ClassDB::bind_method("_restart_confirm", &ProjectManager::_restart_confirm); ClassDB::bind_method("_exit_dialog", &ProjectManager::_exit_dialog); @@ -2042,6 +2109,12 @@ ProjectManager::ProjectManager() { erase->connect("pressed", this, "_erase_project"); erase_btn = erase; + Button *erase_missing = memnew(Button); + erase_missing->set_text(TTR("Remove Missing")); + tree_vb->add_child(erase_missing); + erase_missing->connect("pressed", this, "_erase_missing_projects"); + erase_missing_btn = erase_missing; + tree_vb->add_spacer(); if (StreamPeerSSL::is_available()) { @@ -2105,6 +2178,11 @@ ProjectManager::ProjectManager() { language_restart_ask->get_cancel()->set_text(TTR("Continue")); gui_base->add_child(language_restart_ask); + erase_missing_ask = memnew(ConfirmationDialog); + erase_missing_ask->get_ok()->set_text(TTR("Remove All")); + erase_missing_ask->get_ok()->connect("pressed", this, "_erase_missing_projects_confirm"); + gui_base->add_child(erase_missing_ask); + erase_ask = memnew(ConfirmationDialog); erase_ask->get_ok()->set_text(TTR("Remove")); erase_ask->get_ok()->connect("pressed", this, "_erase_project_confirm"); @@ -2153,7 +2231,7 @@ ProjectManager::ProjectManager() { gui_base->add_child(dialog_error); open_templates = memnew(ConfirmationDialog); - open_templates->set_text(TTR("You don't currently have any projects.\nWould you like to explore the official example projects in the Asset Library?")); + open_templates->set_text(TTR("You currently don't have any projects.\nWould you like to explore official example projects in the Asset Library?")); open_templates->get_ok()->set_text(TTR("Open Asset Library")); open_templates->connect("confirmed", this, "_open_asset_library"); add_child(open_templates); diff --git a/editor/project_manager.h b/editor/project_manager.h index 1fdd7dbe06..382e9fc8fb 100644 --- a/editor/project_manager.h +++ b/editor/project_manager.h @@ -45,6 +45,7 @@ class ProjectManager : public Control { GDCLASS(ProjectManager, Control); Button *erase_btn; + Button *erase_missing_btn; Button *open_btn; Button *rename_btn; Button *run_btn; @@ -57,6 +58,7 @@ class ProjectManager : public Control { FileDialog *scan_dir; ConfirmationDialog *language_restart_ask; ConfirmationDialog *erase_ask; + ConfirmationDialog *erase_missing_ask; ConfirmationDialog *multi_open_ask; ConfirmationDialog *multi_run_ask; ConfirmationDialog *multi_scan_ask; @@ -89,7 +91,9 @@ class ProjectManager : public Control { void _new_project(); void _rename_project(); void _erase_project(); + void _erase_missing_projects(); void _erase_project_confirm(); + void _erase_missing_projects_confirm(); void _update_project_buttons(); void _language_selected(int p_id); void _restart_confirm(); diff --git a/editor/project_settings_editor.cpp b/editor/project_settings_editor.cpp index 2d7ad8bc04..71bddebcf5 100644 --- a/editor/project_settings_editor.cpp +++ b/editor/project_settings_editor.cpp @@ -181,7 +181,7 @@ void ProjectSettingsEditor::_action_edited() { ti->set_text(0, old_name); add_at = "input/" + old_name; - message->set_text(vformat(TTR("Action '%s' already exists!"), new_name)); + message->set_text(vformat(TTR("An action with the name '%s' already exists."), new_name)); message->popup_centered(Size2(300, 100) * EDSCALE); return; } @@ -927,7 +927,7 @@ void ProjectSettingsEditor::_action_check(String p_action) { } if (ProjectSettings::get_singleton()->has_setting("input/" + p_action)) { - action_add_error->set_text(TTR("Already existing")); + action_add_error->set_text(vformat(TTR("An action with the name '%s' already exists."), p_action)); action_add_error->show(); action_add->set_disabled(true); return; @@ -1592,6 +1592,7 @@ void ProjectSettingsEditor::_toggle_search_bar(bool p_pressed) { search_box->select_all(); } else { + search_box->clear(); search_bar->hide(); add_prop_bar->show(); } @@ -1785,7 +1786,7 @@ ProjectSettingsEditor::ProjectSettingsEditor(EditorData *p_data) { restart_icon->set_v_size_flags(SIZE_SHRINK_CENTER); restart_hb->add_child(restart_icon); restart_label = memnew(Label); - restart_label->set_text(TTR("Editor must be restarted for changes to take effect")); + restart_label->set_text(TTR("The editor must be restarted for changes to take effect.")); restart_hb->add_child(restart_label); restart_hb->add_spacer(); Button *restart_button = memnew(Button); @@ -2003,8 +2004,8 @@ ProjectSettingsEditor::ProjectSettingsEditor(EditorData *p_data) { tvb->add_child(tmc); translation_locale_filter_mode = memnew(OptionButton); - translation_locale_filter_mode->add_item(TTR("Show all locales"), SHOW_ALL_LOCALES); - translation_locale_filter_mode->add_item(TTR("Show only selected locales"), SHOW_ONLY_SELECTED_LOCALES); + translation_locale_filter_mode->add_item(TTR("Show All Locales"), SHOW_ALL_LOCALES); + translation_locale_filter_mode->add_item(TTR("Show Selected Locales Only"), SHOW_ONLY_SELECTED_LOCALES); translation_locale_filter_mode->select(0); tmc->add_margin_child(TTR("Filter mode:"), translation_locale_filter_mode); translation_locale_filter_mode->connect("item_selected", this, "_translation_filter_mode_changed"); diff --git a/editor/quick_open.cpp b/editor/quick_open.cpp index c197248c35..dc2f098333 100644 --- a/editor/quick_open.cpp +++ b/editor/quick_open.cpp @@ -255,14 +255,19 @@ void EditorQuickOpen::_confirmed() { void EditorQuickOpen::_notification(int p_what) { - if (p_what == NOTIFICATION_ENTER_TREE) { + switch (p_what) { - connect("confirmed", this, "_confirmed"); + case NOTIFICATION_ENTER_TREE: { - search_box->set_right_icon(get_icon("Search", "EditorIcons")); - search_box->set_clear_button_enabled(true); - } else if (p_what == NOTIFICATION_EXIT_TREE) { - disconnect("confirmed", this, "_confirmed"); + connect("confirmed", this, "_confirmed"); + + search_box->set_right_icon(get_icon("Search", "EditorIcons")); + search_box->set_clear_button_enabled(true); + } break; + case NOTIFICATION_EXIT_TREE: { + + disconnect("confirmed", this, "_confirmed"); + } break; } } @@ -297,6 +302,7 @@ EditorQuickOpen::EditorQuickOpen() { set_hide_on_ok(false); search_options->connect("item_activated", this, "_confirmed"); search_options->set_hide_root(true); + search_options->add_constant_override("draw_guides", 1); ei = "EditorIcons"; ot = "Object"; add_directories = false; diff --git a/editor/rename_dialog.cpp b/editor/rename_dialog.cpp index ed1eec95dc..858b14a733 100644 --- a/editor/rename_dialog.cpp +++ b/editor/rename_dialog.cpp @@ -113,7 +113,7 @@ RenameDialog::RenameDialog(SceneTreeEditor *p_scene_tree_editor, UndoRedo *p_und collapse_theme->set_icon("unchecked", "CheckBox", collapse_theme->get_icon("GuiTreeArrowRight", "EditorIcons")); CheckBox *chk_collapse_features = memnew(CheckBox); - chk_collapse_features->set_text(TTR("Advanced options")); + chk_collapse_features->set_text(TTR("Advanced Options")); chk_collapse_features->set_theme(collapse_theme); chk_collapse_features->set_focus_mode(FOCUS_NONE); vbc->add_child(chk_collapse_features); diff --git a/editor/scene_tree_dock.cpp b/editor/scene_tree_dock.cpp index 1dca542138..a41f10607b 100644 --- a/editor/scene_tree_dock.cpp +++ b/editor/scene_tree_dock.cpp @@ -2625,6 +2625,7 @@ SceneTreeDock::SceneTreeDock(EditorNode *p_editor, Node *p_scene_root, EditorSel add_child(rename_dialog); script_create_dialog = memnew(ScriptCreateDialog); + script_create_dialog->set_inheritance_base_type("Node"); add_child(script_create_dialog); script_create_dialog->connect("script_created", this, "_script_created"); diff --git a/editor/script_create_dialog.cpp b/editor/script_create_dialog.cpp index 5ab0efaee3..292cb8ddc3 100644 --- a/editor/script_create_dialog.cpp +++ b/editor/script_create_dialog.cpp @@ -34,6 +34,7 @@ #include "core/os/file_access.h" #include "core/project_settings.h" #include "core/script_language.h" +#include "editor/create_dialog.h" #include "editor/editor_node.h" #include "editor/editor_scale.h" #include "editor_file_system.h" @@ -45,11 +46,28 @@ void ScriptCreateDialog::_notification(int p_what) { case NOTIFICATION_ENTER_TREE: { path_button->set_icon(get_icon("Folder", "EditorIcons")); parent_browse_button->set_icon(get_icon("Folder", "EditorIcons")); + parent_search_button->set_icon(get_icon("ClassList", "EditorIcons")); status_panel->add_style_override("panel", get_stylebox("bg", "Tree")); } break; } } +void ScriptCreateDialog::_path_hbox_sorted() { + if (is_visible()) { + int filename_start_pos = initial_bp.find_last("/") + 1; + int filename_end_pos = initial_bp.length(); + + file_path->select(filename_start_pos, filename_end_pos); + + // First set cursor to the end of line to scroll LineEdit view + // to the right and then set the actual cursor position. + file_path->set_cursor_position(file_path->get_text().length()); + file_path->set_cursor_position(filename_start_pos); + + file_path->grab_focus(); + } +} + bool ScriptCreateDialog::_can_be_built_in() { return (supports_built_in && built_in_enabled); } @@ -77,6 +95,11 @@ void ScriptCreateDialog::config(const String &p_base_name, const String &p_base_ _path_changed(file_path->get_text()); } +void ScriptCreateDialog::set_inheritance_base_type(const String &p_base) { + + base_type = p_base; +} + bool ScriptCreateDialog::_validate(const String &p_string) { if (p_string.length() == 0) @@ -322,7 +345,7 @@ void ScriptCreateDialog::_browse_path(bool browse_parent, bool p_save) { if (p_save) { file_browse->set_mode(EditorFileDialog::MODE_SAVE_FILE); - file_browse->set_title(TTR("Open Script/Choose Location")); + file_browse->set_title(TTR("Open Script / Choose Location")); file_browse->get_ok()->set_text(TTR("Open")); } else { file_browse->set_mode(EditorFileDialog::MODE_OPEN_FILE); @@ -362,6 +385,17 @@ void ScriptCreateDialog::_file_selected(const String &p_file) { } } +void ScriptCreateDialog::_create() { + + parent_name->set_text(select_class->get_selected_type()); +} + +void ScriptCreateDialog::_browse_class_in_tree() { + + select_class->set_base_type(base_type); + select_class->popup_create(true); +} + void ScriptCreateDialog::_path_changed(const String &p_path) { is_path_valid = false; @@ -369,27 +403,27 @@ void ScriptCreateDialog::_path_changed(const String &p_path) { String p = p_path.strip_edges(); if (p == "") { - _msg_path_valid(false, TTR("Path is empty")); + _msg_path_valid(false, TTR("Path is empty.")); _update_dialog(); return; } if (p.get_file().get_basename() == "") { - _msg_path_valid(false, TTR("Filename is empty")); + _msg_path_valid(false, TTR("Filename is empty.")); _update_dialog(); return; } p = ProjectSettings::get_singleton()->localize_path(p); if (!p.begins_with("res://")) { - _msg_path_valid(false, TTR("Path is not local")); + _msg_path_valid(false, TTR("Path is not local.")); _update_dialog(); return; } DirAccess *d = DirAccess::create(DirAccess::ACCESS_RESOURCES); if (d->change_dir(p.get_base_dir()) != OK) { - _msg_path_valid(false, TTR("Invalid base path")); + _msg_path_valid(false, TTR("Invalid base path.")); memdelete(d); _update_dialog(); return; @@ -402,11 +436,11 @@ void ScriptCreateDialog::_path_changed(const String &p_path) { if (f->dir_exists(p)) { is_new_script_created = false; is_path_valid = false; - _msg_path_valid(false, TTR("Directory of the same name exists")); + _msg_path_valid(false, TTR("A directory with the same name exists.")); } else if (f->file_exists(p)) { is_new_script_created = false; is_path_valid = true; - _msg_path_valid(true, TTR("File exists, will be reused")); + _msg_path_valid(true, TTR("File exists, it will be reused.")); } memdelete(f); _update_dialog(); @@ -438,13 +472,13 @@ void ScriptCreateDialog::_path_changed(const String &p_path) { } if (!found) { - _msg_path_valid(false, TTR("Invalid extension")); + _msg_path_valid(false, TTR("Invalid extension.")); _update_dialog(); return; } if (!match) { - _msg_path_valid(false, TTR("Wrong extension chosen")); + _msg_path_valid(false, TTR("Wrong extension chosen.")); _update_dialog(); return; } @@ -496,20 +530,20 @@ void ScriptCreateDialog::_update_dialog() { get_ok()->set_disabled(true); if (!is_built_in) { if (!is_path_valid) { - _msg_script_valid(false, TTR("Invalid Path")); + _msg_script_valid(false, TTR("Invalid path.")); script_ok = false; } } if (has_named_classes && (is_new_script_created && !is_class_name_valid)) { - _msg_script_valid(false, TTR("Invalid class name")); + _msg_script_valid(false, TTR("Invalid class name.")); script_ok = false; } if (!is_parent_name_valid) { - _msg_script_valid(false, TTR("Invalid inherited parent name or path")); + _msg_script_valid(false, TTR("Invalid inherited parent name or path.")); script_ok = false; } if (script_ok) { - _msg_script_valid(true, TTR("Script valid")); + _msg_script_valid(true, TTR("Script is valid.")); get_ok()->set_disabled(false); } @@ -562,7 +596,7 @@ void ScriptCreateDialog::_update_dialog() { parent_name->set_editable(true); parent_browse_button->set_disabled(false); internal->set_disabled(!_can_be_built_in()); - _msg_path_valid(true, TTR("Built-in script (into scene file)")); + _msg_path_valid(true, TTR("Built-in script (into scene file).")); } else if (is_new_script_created) { // New Script Created get_ok()->set_text(TTR("Create")); @@ -570,7 +604,7 @@ void ScriptCreateDialog::_update_dialog() { parent_browse_button->set_disabled(false); internal->set_disabled(!_can_be_built_in()); if (is_path_valid) { - _msg_path_valid(true, TTR("Create new script file")); + _msg_path_valid(true, TTR("Will create a new script file.")); } } else { // Script Loaded @@ -579,13 +613,14 @@ void ScriptCreateDialog::_update_dialog() { parent_browse_button->set_disabled(true); internal->set_disabled(!_can_be_built_in()); if (is_path_valid) { - _msg_path_valid(true, TTR("Load existing script file")); + _msg_path_valid(true, TTR("Will load an existing script file.")); } } } void ScriptCreateDialog::_bind_methods() { + ClassDB::bind_method("_path_hbox_sorted", &ScriptCreateDialog::_path_hbox_sorted); ClassDB::bind_method("_class_name_changed", &ScriptCreateDialog::_class_name_changed); ClassDB::bind_method("_parent_name_changed", &ScriptCreateDialog::_parent_name_changed); ClassDB::bind_method("_lang_changed", &ScriptCreateDialog::_lang_changed); @@ -595,6 +630,8 @@ void ScriptCreateDialog::_bind_methods() { ClassDB::bind_method("_path_changed", &ScriptCreateDialog::_path_changed); ClassDB::bind_method("_path_entered", &ScriptCreateDialog::_path_entered); ClassDB::bind_method("_template_changed", &ScriptCreateDialog::_template_changed); + ClassDB::bind_method("_create", &ScriptCreateDialog::_create); + ClassDB::bind_method("_browse_class_in_tree", &ScriptCreateDialog::_browse_class_in_tree); ClassDB::bind_method(D_METHOD("config", "inherits", "path", "built_in_enabled"), &ScriptCreateDialog::config, DEFVAL(true)); @@ -707,12 +744,18 @@ ScriptCreateDialog::ScriptCreateDialog() { /* Inherits */ + base_type = "Object"; + hb = memnew(HBoxContainer); hb->set_h_size_flags(SIZE_EXPAND_FILL); parent_name = memnew(LineEdit); parent_name->connect("text_changed", this, "_parent_name_changed"); parent_name->set_h_size_flags(SIZE_EXPAND_FILL); hb->add_child(parent_name); + parent_search_button = memnew(Button); + parent_search_button->set_flat(true); + parent_search_button->connect("pressed", this, "_browse_class_in_tree"); + hb->add_child(parent_search_button); parent_browse_button = memnew(Button); parent_browse_button->set_flat(true); parent_browse_button->connect("pressed", this, "_browse_path", varray(true, false)); @@ -760,6 +803,7 @@ ScriptCreateDialog::ScriptCreateDialog() { /* Path */ hb = memnew(HBoxContainer); + hb->connect("sort_children", this, "_path_hbox_sorted"); file_path = memnew(LineEdit); file_path->connect("text_changed", this, "_path_changed"); file_path->connect("text_entered", this, "_path_entered"); @@ -777,6 +821,10 @@ ScriptCreateDialog::ScriptCreateDialog() { /* Dialog Setup */ + select_class = memnew(CreateDialog); + select_class->connect("create", this, "_create"); + add_child(select_class); + file_browse = memnew(EditorFileDialog); file_browse->connect("file_selected", this, "_file_selected"); file_browse->set_mode(EditorFileDialog::MODE_OPEN_FILE); diff --git a/editor/script_create_dialog.h b/editor/script_create_dialog.h index 15e838d69f..f5c335c00a 100644 --- a/editor/script_create_dialog.h +++ b/editor/script_create_dialog.h @@ -40,6 +40,8 @@ #include "scene/gui/option_button.h" #include "scene/gui/panel_container.h" +class CreateDialog; + class ScriptCreateDialog : public ConfirmationDialog { GDCLASS(ScriptCreateDialog, ConfirmationDialog); @@ -49,6 +51,7 @@ class ScriptCreateDialog : public ConfirmationDialog { PanelContainer *status_panel; LineEdit *parent_name; Button *parent_browse_button; + Button *parent_search_button; OptionButton *language_menu; OptionButton *template_menu; LineEdit *file_path; @@ -57,6 +60,7 @@ class ScriptCreateDialog : public ConfirmationDialog { CheckButton *internal; VBoxContainer *path_vb; AcceptDialog *alert; + CreateDialog *select_class; bool path_valid; bool create_new; bool is_browsing_parent; @@ -74,7 +78,9 @@ class ScriptCreateDialog : public ConfirmationDialog { bool re_check_path; String script_template; Vector<String> template_list; + String base_type; + void _path_hbox_sorted(); bool _can_be_built_in(); void _path_changed(const String &p_path = String()); void _path_entered(const String &p_path = String()); @@ -86,6 +92,8 @@ class ScriptCreateDialog : public ConfirmationDialog { void _template_changed(int p_template = 0); void _browse_path(bool browse_parent, bool p_save); void _file_selected(const String &p_file); + void _create(); + void _browse_class_in_tree(); virtual void ok_pressed(); void _create_new(); void _load_exist(); @@ -99,6 +107,7 @@ protected: public: void config(const String &p_base_name, const String &p_base_path, bool p_built_in_enabled = true); + void set_inheritance_base_type(const String &p_base); ScriptCreateDialog(); }; diff --git a/editor/settings_config_dialog.cpp b/editor/settings_config_dialog.cpp index d6756b2bb3..68a1117364 100644 --- a/editor/settings_config_dialog.cpp +++ b/editor/settings_config_dialog.cpp @@ -449,7 +449,7 @@ EditorSettingsDialog::EditorSettingsDialog() { restart_icon->set_v_size_flags(SIZE_SHRINK_CENTER); restart_hb->add_child(restart_icon); restart_label = memnew(Label); - restart_label->set_text(TTR("Editor must be restarted for changes to take effect")); + restart_label->set_text(TTR("The editor must be restarted for changes to take effect.")); restart_hb->add_child(restart_label); restart_hb->add_spacer(); Button *restart_button = memnew(Button); diff --git a/modules/assimp/SCsub b/modules/assimp/SCsub index 61a357809a..0da7e432e2 100644 --- a/modules/assimp/SCsub +++ b/modules/assimp/SCsub @@ -4,19 +4,19 @@ Import('env') Import('env_modules') env_assimp = env_modules.Clone() -env_assimp.Append(CPPPATH=['#thirdparty/assimp']) -env_assimp.Append(CPPPATH=['#thirdparty/assimp/include']) -env_assimp.Append(CPPPATH=['#thirdparty/assimp/code/Importer/IFC']) -env_assimp.Append(CPPPATH=['#thirdparty/misc']) -env_assimp.Append(CPPPATH=['#thirdparty/assimp/code']) -env_assimp.Append(CPPPATH=['#thirdparty/assimp/contrib/irrXML/']) -env_assimp.Append(CPPPATH=['#thirdparty/assimp/contrib/unzip/']) -env_assimp.Append(CPPPATH=['#thirdparty/assimp/code/Importer/STEPParser']) -env_assimp.Append(CPPPATH=['#thirdparty/assimp/']) -env_assimp.Append(CPPPATH=['#thirdparty/zlib/']) -env_assimp.Append(CPPPATH=['#thirdparty/assimp/contrib/openddlparser/include']) -env_assimp.Append(CPPPATH=['#thirdparty/assimp/contrib/rapidjson/include']) -env_assimp.Append(CPPPATH=['.']) +env_assimp.Prepend(CPPPATH=['#thirdparty/assimp']) +env_assimp.Prepend(CPPPATH=['#thirdparty/assimp/include']) +env_assimp.Prepend(CPPPATH=['#thirdparty/assimp/code/Importer/IFC']) +env_assimp.Prepend(CPPPATH=['#thirdparty/misc']) +env_assimp.Prepend(CPPPATH=['#thirdparty/assimp/code']) +env_assimp.Prepend(CPPPATH=['#thirdparty/assimp/contrib/irrXML/']) +env_assimp.Prepend(CPPPATH=['#thirdparty/assimp/contrib/unzip/']) +env_assimp.Prepend(CPPPATH=['#thirdparty/assimp/code/Importer/STEPParser']) +env_assimp.Prepend(CPPPATH=['#thirdparty/assimp/']) +env_assimp.Prepend(CPPPATH=['#thirdparty/zlib/']) +env_assimp.Prepend(CPPPATH=['#thirdparty/assimp/contrib/openddlparser/include']) +env_assimp.Prepend(CPPPATH=['#thirdparty/assimp/contrib/rapidjson/include']) +env_assimp.Prepend(CPPPATH=['.']) #env_assimp.Append(CPPFLAGS=['-DASSIMP_DOUBLE_PRECISION']) # TODO default to what godot is compiled with for future double support env_assimp.Append(CPPFLAGS=['-DASSIMP_BUILD_BOOST_WORKAROUND']) env_assimp.Append(CPPFLAGS=['-DOPENDDLPARSER_BUILD']) diff --git a/modules/bullet/SCsub b/modules/bullet/SCsub index e7c2fff54c..16d694c238 100644 --- a/modules/bullet/SCsub +++ b/modules/bullet/SCsub @@ -186,7 +186,7 @@ if env['builtin_bullet']: thirdparty_sources = [thirdparty_dir + file for file in bullet2_src] - env_bullet.Append(CPPPATH=[thirdparty_dir]) + env_bullet.Prepend(CPPPATH=[thirdparty_dir]) # if env['target'] == "debug" or env['target'] == "release_debug": # env_bullet.Append(CPPFLAGS=['-DBT_DEBUG']) diff --git a/modules/bullet/bullet_physics_server.cpp b/modules/bullet/bullet_physics_server.cpp index 44ea061f51..b21bdee052 100644 --- a/modules/bullet/bullet_physics_server.cpp +++ b/modules/bullet/bullet_physics_server.cpp @@ -279,14 +279,14 @@ PhysicsServer::AreaSpaceOverrideMode BulletPhysicsServer::area_get_space_overrid return area->get_spOv_mode(); } -void BulletPhysicsServer::area_add_shape(RID p_area, RID p_shape, const Transform &p_transform) { +void BulletPhysicsServer::area_add_shape(RID p_area, RID p_shape, const Transform &p_transform, bool p_disabled) { AreaBullet *area = area_owner.get(p_area); ERR_FAIL_COND(!area); ShapeBullet *shape = shape_owner.get(p_shape); ERR_FAIL_COND(!shape); - area->add_shape(shape, p_transform); + area->add_shape(shape, p_transform, p_disabled); } void BulletPhysicsServer::area_set_shape(RID p_area, int p_shape_idx, RID p_shape) { @@ -498,7 +498,7 @@ PhysicsServer::BodyMode BulletPhysicsServer::body_get_mode(RID p_body) const { return body->get_mode(); } -void BulletPhysicsServer::body_add_shape(RID p_body, RID p_shape, const Transform &p_transform) { +void BulletPhysicsServer::body_add_shape(RID p_body, RID p_shape, const Transform &p_transform, bool p_disabled) { RigidBodyBullet *body = rigid_body_owner.get(p_body); ERR_FAIL_COND(!body); @@ -506,7 +506,7 @@ void BulletPhysicsServer::body_add_shape(RID p_body, RID p_shape, const Transfor ShapeBullet *shape = shape_owner.get(p_shape); ERR_FAIL_COND(!shape); - body->add_shape(shape, p_transform); + body->add_shape(shape, p_transform, p_disabled); } void BulletPhysicsServer::body_set_shape(RID p_body, int p_shape_idx, RID p_shape) { diff --git a/modules/bullet/bullet_physics_server.h b/modules/bullet/bullet_physics_server.h index 1b74cbf3fc..5bcb0d244b 100644 --- a/modules/bullet/bullet_physics_server.h +++ b/modules/bullet/bullet_physics_server.h @@ -133,7 +133,7 @@ public: virtual void area_set_space_override_mode(RID p_area, AreaSpaceOverrideMode p_mode); virtual AreaSpaceOverrideMode area_get_space_override_mode(RID p_area) const; - virtual void area_add_shape(RID p_area, RID p_shape, const Transform &p_transform = Transform()); + virtual void area_add_shape(RID p_area, RID p_shape, const Transform &p_transform = Transform(), bool p_disabled = false); virtual void area_set_shape(RID p_area, int p_shape_idx, RID p_shape); virtual void area_set_shape_transform(RID p_area, int p_shape_idx, const Transform &p_transform); virtual int area_get_shape_count(RID p_area) const; @@ -174,7 +174,7 @@ public: virtual void body_set_mode(RID p_body, BodyMode p_mode); virtual BodyMode body_get_mode(RID p_body) const; - virtual void body_add_shape(RID p_body, RID p_shape, const Transform &p_transform = Transform()); + virtual void body_add_shape(RID p_body, RID p_shape, const Transform &p_transform = Transform(), bool p_disabled = false); // Not supported, Please remove and add new shape virtual void body_set_shape(RID p_body, int p_shape_idx, RID p_shape); virtual void body_set_shape_transform(RID p_body, int p_shape_idx, const Transform &p_transform); diff --git a/modules/bullet/collision_object_bullet.cpp b/modules/bullet/collision_object_bullet.cpp index ef5f21fc21..3a90bdc6ae 100644 --- a/modules/bullet/collision_object_bullet.cpp +++ b/modules/bullet/collision_object_bullet.cpp @@ -216,8 +216,8 @@ RigidCollisionObjectBullet::~RigidCollisionObjectBullet() { } } -void RigidCollisionObjectBullet::add_shape(ShapeBullet *p_shape, const Transform &p_transform) { - shapes.push_back(ShapeWrapper(p_shape, p_transform, true)); +void RigidCollisionObjectBullet::add_shape(ShapeBullet *p_shape, const Transform &p_transform, bool p_disabled) { + shapes.push_back(ShapeWrapper(p_shape, p_transform, !p_disabled)); p_shape->add_owner(this); reload_shapes(); } @@ -299,6 +299,8 @@ Transform RigidCollisionObjectBullet::get_shape_transform(int p_index) const { } void RigidCollisionObjectBullet::set_shape_disabled(int p_index, bool p_disabled) { + if (shapes[p_index].active != p_disabled) + return; shapes.write[p_index].active = !p_disabled; shape_changed(p_index); } diff --git a/modules/bullet/collision_object_bullet.h b/modules/bullet/collision_object_bullet.h index 2d4e5c4f1a..e65bc52caf 100644 --- a/modules/bullet/collision_object_bullet.h +++ b/modules/bullet/collision_object_bullet.h @@ -224,7 +224,7 @@ public: _FORCE_INLINE_ btCollisionShape *get_main_shape() const { return mainShape; } - void add_shape(ShapeBullet *p_shape, const Transform &p_transform = Transform()); + void add_shape(ShapeBullet *p_shape, const Transform &p_transform = Transform(), bool p_disabled = false); void set_shape(int p_index, ShapeBullet *p_shape); int get_shape_count() const; diff --git a/modules/cvtt/SCsub b/modules/cvtt/SCsub index fcc69d8371..142af0c800 100644 --- a/modules/cvtt/SCsub +++ b/modules/cvtt/SCsub @@ -14,7 +14,7 @@ if env['builtin_squish']: thirdparty_sources = [thirdparty_dir + file for file in thirdparty_sources] - env_cvtt.Append(CPPPATH=[thirdparty_dir]) + env_cvtt.Prepend(CPPPATH=[thirdparty_dir]) env_thirdparty = env_cvtt.Clone() env_thirdparty.disable_warnings() diff --git a/modules/enet/SCsub b/modules/enet/SCsub index a57a4b29ea..78d8d43414 100644 --- a/modules/enet/SCsub +++ b/modules/enet/SCsub @@ -21,7 +21,7 @@ if env['builtin_enet']: ] thirdparty_sources = [thirdparty_dir + file for file in thirdparty_sources] - env_enet.Append(CPPPATH=[thirdparty_dir]) + env_enet.Prepend(CPPPATH=[thirdparty_dir]) env_enet.Append(CPPFLAGS=["-DGODOT_ENET"]) env_thirdparty = env_enet.Clone() diff --git a/modules/etc/SCsub b/modules/etc/SCsub index eb2738053b..532b97b006 100644 --- a/modules/etc/SCsub +++ b/modules/etc/SCsub @@ -27,7 +27,7 @@ thirdparty_sources = [ ] thirdparty_sources = [thirdparty_dir + file for file in thirdparty_sources] -env_etc.Append(CPPPATH=[thirdparty_dir]) +env_etc.Prepend(CPPPATH=[thirdparty_dir]) # upstream uses c++11 if not env.msvc: diff --git a/modules/freetype/SCsub b/modules/freetype/SCsub index f2cd9f9a60..0c8b223a9e 100644 --- a/modules/freetype/SCsub +++ b/modules/freetype/SCsub @@ -68,9 +68,9 @@ if env['builtin_freetype']: sfnt = env_freetype.Object(sfnt, CPPFLAGS=['-U__OPTIMIZE__']) thirdparty_sources += [sfnt] - env_freetype.Append(CPPPATH=[thirdparty_dir + "/include"]) + env_freetype.Prepend(CPPPATH=[thirdparty_dir + "/include"]) # Also needed in main env for scene/ - env.Append(CPPPATH=[thirdparty_dir + "/include"]) + env.Prepend(CPPPATH=[thirdparty_dir + "/include"]) env_freetype.Append(CPPFLAGS=['-DFT2_BUILD_LIBRARY', '-DFT_CONFIG_OPTION_USE_PNG']) if (env['target'] != 'release'): @@ -78,7 +78,7 @@ if env['builtin_freetype']: # Also requires libpng headers if env['builtin_libpng']: - env_freetype.Append(CPPPATH=["#thirdparty/libpng"]) + env_freetype.Prepend(CPPPATH=["#thirdparty/libpng"]) env_thirdparty = env_freetype.Clone() env_thirdparty.disable_warnings() diff --git a/modules/gdnative/SCsub b/modules/gdnative/SCsub index 235f0b97bb..0cdd585558 100644 --- a/modules/gdnative/SCsub +++ b/modules/gdnative/SCsub @@ -12,7 +12,7 @@ env_gdnative.add_source_files(env.modules_sources, "nativescript/*.cpp") env_gdnative.add_source_files(env.modules_sources, "gdnative_library_singleton_editor.cpp") env_gdnative.add_source_files(env.modules_sources, "gdnative_library_editor_plugin.cpp") -env_gdnative.Append(CPPPATH=['#modules/gdnative/include/']) +env_gdnative.Prepend(CPPPATH=['#modules/gdnative/include/']) Export('env_gdnative') @@ -36,7 +36,7 @@ if ARGUMENTS.get('gdnative_wrapper', False): gensource, = env_gdnative.CommandNoCache('gdnative_wrapper_code.gen.cpp', 'gdnative_api.json', run_in_subprocess(gdnative_builders.build_gdnative_wrapper_code)) gd_wrapper_env = env.Clone() - gd_wrapper_env.Append(CPPPATH=['#modules/gdnative/include/']) + gd_wrapper_env.Prepend(CPPPATH=['#modules/gdnative/include/']) if gd_wrapper_env['use_lto']: if not env.msvc: diff --git a/modules/gdnative/arvr/arvr_interface_gdnative.cpp b/modules/gdnative/arvr/arvr_interface_gdnative.cpp index 8c602e0cba..c3f8688adb 100644 --- a/modules/gdnative/arvr/arvr_interface_gdnative.cpp +++ b/modules/gdnative/arvr/arvr_interface_gdnative.cpp @@ -222,6 +222,15 @@ void ARVRInterfaceGDNative::process() { interface->process(data); } +void ARVRInterfaceGDNative::notification(int p_what) { + ERR_FAIL_COND(interface == NULL); + + // this is only available in interfaces that implement 1.1 or later + if ((interface->version.major > 1) || ((interface->version.major == 1) && (interface->version.minor > 0))) { + interface->notification(data, p_what); + } +} + ///////////////////////////////////////////////////////////////////////////////////// // some helper callbacks diff --git a/modules/gdnative/arvr/arvr_interface_gdnative.h b/modules/gdnative/arvr/arvr_interface_gdnative.h index 3f966ece51..86396b067a 100644 --- a/modules/gdnative/arvr/arvr_interface_gdnative.h +++ b/modules/gdnative/arvr/arvr_interface_gdnative.h @@ -82,6 +82,7 @@ public: virtual void commit_for_eye(ARVRInterface::Eyes p_eye, RID p_render_target, const Rect2 &p_screen_rect); virtual void process(); + virtual void notification(int p_what); }; #endif // ARVR_INTERFACE_GDNATIVE_H diff --git a/modules/gdnative/include/arvr/godot_arvr.h b/modules/gdnative/include/arvr/godot_arvr.h index 321b471d0e..657090fa70 100644 --- a/modules/gdnative/include/arvr/godot_arvr.h +++ b/modules/gdnative/include/arvr/godot_arvr.h @@ -63,6 +63,7 @@ typedef struct { void (*process)(void *); // only in 1.1 onwards godot_int (*get_external_texture_for_eye)(void *, godot_int); + void (*notification)(void *, godot_int); } godot_arvr_interface_gdnative; void GDAPI godot_arvr_register_interface(const godot_arvr_interface_gdnative *p_interface); diff --git a/modules/gdnative/nativescript/api_generator.cpp b/modules/gdnative/nativescript/api_generator.cpp index 4577c7327a..e0cf990f83 100644 --- a/modules/gdnative/nativescript/api_generator.cpp +++ b/modules/gdnative/nativescript/api_generator.cpp @@ -139,6 +139,34 @@ static String get_type_name(const PropertyInfo &info) { } /* + * Some comparison helper functions we need + */ + +struct MethodInfoComparator { + StringName::AlphCompare compare; + bool operator()(const MethodInfo &p_a, const MethodInfo &p_b) const { + + return compare(p_a.name, p_b.name); + } +}; + +struct PropertyInfoComparator { + StringName::AlphCompare compare; + bool operator()(const PropertyInfo &p_a, const PropertyInfo &p_b) const { + + return compare(p_a.name, p_b.name); + } +}; + +struct ConstantAPIComparator { + NoCaseComparator compare; + bool operator()(const ConstantAPI &p_a, const ConstantAPI &p_b) const { + + return compare(p_a.constant_name, p_b.constant_name); + } +}; + +/* * Reads the entire Godot API to a list */ List<ClassAPI> generate_c_api_classes() { @@ -147,6 +175,7 @@ List<ClassAPI> generate_c_api_classes() { List<StringName> classes; ClassDB::get_class_list(&classes); + classes.sort_custom<StringName::AlphCompare>(); // Register global constants as a fake GlobalConstants singleton class { @@ -162,6 +191,7 @@ List<ClassAPI> generate_c_api_classes() { constant_api.constant_value = GlobalConstants::get_global_constant_value(i); global_constants_api.constants.push_back(constant_api); } + global_constants_api.constants.sort_custom<ConstantAPIComparator>(); api.push_back(global_constants_api); } @@ -193,6 +223,7 @@ List<ClassAPI> generate_c_api_classes() { { List<String> constant; ClassDB::get_integer_constant_list(class_name, &constant, true); + constant.sort_custom<NoCaseComparator>(); for (List<String>::Element *c = constant.front(); c != NULL; c = c->next()) { ConstantAPI constant_api; constant_api.constant_name = c->get(); @@ -206,6 +237,7 @@ List<ClassAPI> generate_c_api_classes() { { List<MethodInfo> signals_; ClassDB::get_signal_list(class_name, &signals_, true); + signals_.sort_custom<MethodInfoComparator>(); for (int i = 0; i < signals_.size(); i++) { SignalAPI signal; @@ -245,6 +277,7 @@ List<ClassAPI> generate_c_api_classes() { { List<PropertyInfo> properties; ClassDB::get_property_list(class_name, &properties, true); + properties.sort_custom<PropertyInfoComparator>(); for (List<PropertyInfo>::Element *p = properties.front(); p != NULL; p = p->next()) { PropertyAPI property_api; @@ -272,6 +305,7 @@ List<ClassAPI> generate_c_api_classes() { { List<MethodInfo> methods; ClassDB::get_method_list(class_name, &methods, true); + methods.sort_custom<MethodInfoComparator>(); for (List<MethodInfo>::Element *m = methods.front(); m != NULL; m = m->next()) { MethodAPI method_api; diff --git a/modules/gdnative/videodecoder/SCsub b/modules/gdnative/videodecoder/SCsub index 8d9c1ff50e..04cc8ed604 100644 --- a/modules/gdnative/videodecoder/SCsub +++ b/modules/gdnative/videodecoder/SCsub @@ -5,5 +5,5 @@ Import('env_modules') env_vsdecoder_gdnative = env_modules.Clone() -env_vsdecoder_gdnative.Append(CPPPATH=['#modules/gdnative/include/']) +env_vsdecoder_gdnative.Prepend(CPPPATH=['#modules/gdnative/include/']) env_vsdecoder_gdnative.add_source_files(env.modules_sources, '*.cpp') diff --git a/modules/gdscript/gdscript_editor.cpp b/modules/gdscript/gdscript_editor.cpp index ab34184bfb..69bf114c8e 100644 --- a/modules/gdscript/gdscript_editor.cpp +++ b/modules/gdscript/gdscript_editor.cpp @@ -511,8 +511,10 @@ struct GDScriptCompletionIdentifier { static void _get_directory_contents(EditorFileSystemDirectory *p_dir, Set<String> &r_list) { + const String quote_style = EDITOR_DEF("text_editor/completion/use_single_quotes", false) ? "'" : "\""; + for (int i = 0; i < p_dir->get_file_count(); i++) { - r_list.insert("\"" + p_dir->get_file_path(i) + "\""); + r_list.insert(quote_style + p_dir->get_file_path(i) + quote_style); } for (int i = 0; i < p_dir->get_subdir_count(); i++) { @@ -2178,6 +2180,8 @@ static void _find_call_arguments(const GDScriptCompletionContext &p_context, con GDScriptParser::DataType base_type = p_base.type; bool _static = false; + const String quote_style = EDITOR_DEF("text_editor/completion/use_single_quotes", false) ? "'" : "\""; + while (base_type.has_type) { switch (base_type.kind) { case GDScriptParser::DataType::CLASS: { @@ -2198,7 +2202,7 @@ static void _find_call_arguments(const GDScriptCompletionContext &p_context, con if ((p_method == "connect" || p_method == "emit_signal") && p_argidx == 0) { for (int i = 0; i < base_type.class_type->_signals.size(); i++) { - r_result.insert("\"" + base_type.class_type->_signals[i].name.operator String() + "\""); + r_result.insert(quote_style + base_type.class_type->_signals[i].name.operator String() + quote_style); } } @@ -2211,7 +2215,7 @@ static void _find_call_arguments(const GDScriptCompletionContext &p_context, con List<MethodInfo> signals; gds->get_script_signal_list(&signals); for (List<MethodInfo>::Element *E = signals.front(); E; E = E->next()) { - r_result.insert("\"" + E->get().name + "\""); + r_result.insert(quote_style + E->get().name + quote_style); } } Ref<GDScript> base_script = gds->get_base_script(); @@ -2270,7 +2274,7 @@ static void _find_call_arguments(const GDScriptCompletionContext &p_context, con List<MethodInfo> signals; ClassDB::get_signal_list(class_name, &signals); for (List<MethodInfo>::Element *E = signals.front(); E; E = E->next()) { - r_result.insert("\"" + E->get().name + "\""); + r_result.insert(quote_style + E->get().name + quote_style); } } @@ -2285,7 +2289,7 @@ static void _find_call_arguments(const GDScriptCompletionContext &p_context, con continue; } String name = s.get_slice("/", 1); - r_result.insert("\"/root/" + name + "\""); + r_result.insert(quote_style + "/root/" + name + quote_style); } } @@ -2299,7 +2303,7 @@ static void _find_call_arguments(const GDScriptCompletionContext &p_context, con continue; } String name = s.get_slice("/", 1); - r_result.insert("\"" + name + "\""); + r_result.insert(quote_style + name + quote_style); } } @@ -2334,6 +2338,8 @@ static void _find_call_arguments(const GDScriptCompletionContext &p_context, con static void _find_call_arguments(GDScriptCompletionContext &p_context, const GDScriptParser::Node *p_node, int p_argidx, Set<String> &r_result, bool &r_forced, String &r_arghint) { + const String quote_style = EDITOR_DEF("text_editor/completion/use_single_quotes", false) ? "'" : "\""; + if (!p_node || p_node->type != GDScriptParser::Node::TYPE_OPERATOR) { return; } @@ -2451,7 +2457,7 @@ static void _find_call_arguments(GDScriptCompletionContext &p_context, const GDS Set<String> methods; _find_identifiers_in_base(p_context, connect_base, true, methods); for (Set<String>::Element *E = methods.front(); E; E = E->next()) { - r_result.insert("\"" + E->get().replace("(", "").replace(")", "") + "\""); + r_result.insert(quote_style + E->get().replace("(", "").replace(")", "") + quote_style); } } @@ -2460,6 +2466,8 @@ static void _find_call_arguments(GDScriptCompletionContext &p_context, const GDS Error GDScriptLanguage::complete_code(const String &p_code, const String &p_base_path, Object *p_owner, List<String> *r_options, bool &r_forced, String &r_call_hint) { + const String quote_style = EDITOR_DEF("text_editor/completion/use_single_quotes", false) ? "'" : "\""; + GDScriptParser parser; parser.parse(p_code, p_base_path, false, "", true); @@ -2526,7 +2534,7 @@ Error GDScriptLanguage::complete_code(const String &p_code, const String &p_base continue; } String name = s.get_slice("/", 1); - options.insert("\"/root/" + name + "\""); + options.insert(quote_style + "/root/" + name + quote_style); } } } break; @@ -2666,7 +2674,7 @@ Error GDScriptLanguage::complete_code(const String &p_code, const String &p_base switch (base_type.kind) { case GDScriptParser::DataType::CLASS: { for (int i = 0; i < base_type.class_type->_signals.size(); i++) { - options.insert("\"" + base_type.class_type->_signals[i].name.operator String() + "\""); + options.insert(quote_style + base_type.class_type->_signals[i].name.operator String() + quote_style); } base_type = base_type.class_type->base_type; } break; @@ -2677,7 +2685,7 @@ Error GDScriptLanguage::complete_code(const String &p_code, const String &p_base List<MethodInfo> signals; scr->get_script_signal_list(&signals); for (List<MethodInfo>::Element *E = signals.front(); E; E = E->next()) { - options.insert("\"" + E->get().name + "\""); + options.insert(quote_style + E->get().name + quote_style); } Ref<Script> base_script = scr->get_base_script(); if (base_script.is_valid()) { @@ -2704,7 +2712,7 @@ Error GDScriptLanguage::complete_code(const String &p_code, const String &p_base List<MethodInfo> signals; ClassDB::get_signal_list(class_name, &signals); for (List<MethodInfo>::Element *E = signals.front(); E; E = E->next()) { - options.insert("\"" + E->get().name + "\""); + options.insert(quote_style + E->get().name + quote_style); } } break; default: { @@ -2890,7 +2898,7 @@ Error GDScriptLanguage::complete_code(const String &p_code, const String &p_base String GDScriptLanguage::_get_indentation() const { #ifdef TOOLS_ENABLED if (Engine::get_singleton()->is_editor_hint()) { - bool use_space_indentation = EDITOR_DEF("text_editor/indent/type", 0); + bool use_space_indentation = EDITOR_DEF("text_editor/indent/type", false); if (use_space_indentation) { int indent_size = EDITOR_DEF("text_editor/indent/size", 4); diff --git a/modules/jpg/SCsub b/modules/jpg/SCsub index d5f87905eb..96e8e704dd 100644 --- a/modules/jpg/SCsub +++ b/modules/jpg/SCsub @@ -13,7 +13,7 @@ thirdparty_sources = [ ] thirdparty_sources = [thirdparty_dir + file for file in thirdparty_sources] -env_jpg.Append(CPPPATH=[thirdparty_dir]) +env_jpg.Prepend(CPPPATH=[thirdparty_dir]) env_thirdparty = env_jpg.Clone() env_thirdparty.disable_warnings() diff --git a/modules/mobile_vr/mobile_vr_interface.cpp b/modules/mobile_vr/mobile_vr_interface.cpp index dc7ed03548..fe107d3683 100644 --- a/modules/mobile_vr/mobile_vr_interface.cpp +++ b/modules/mobile_vr/mobile_vr_interface.cpp @@ -440,6 +440,12 @@ void MobileVRInterface::process() { }; }; +void MobileVRInterface::notification(int p_what){ + _THREAD_SAFE_METHOD_ + + // nothing to do here, I guess we could pauze our sensors... +} + MobileVRInterface::MobileVRInterface() { initialized = false; diff --git a/modules/mobile_vr/mobile_vr_interface.h b/modules/mobile_vr/mobile_vr_interface.h index e595daf16e..7fa51eecb7 100644 --- a/modules/mobile_vr/mobile_vr_interface.h +++ b/modules/mobile_vr/mobile_vr_interface.h @@ -142,6 +142,7 @@ public: virtual void commit_for_eye(ARVRInterface::Eyes p_eye, RID p_render_target, const Rect2 &p_screen_rect); virtual void process(); + virtual void notification(int p_what); MobileVRInterface(); ~MobileVRInterface(); diff --git a/modules/mono/build_scripts/mono_configure.py b/modules/mono/build_scripts/mono_configure.py index 160580e116..4cfa2a5b93 100644 --- a/modules/mono/build_scripts/mono_configure.py +++ b/modules/mono/build_scripts/mono_configure.py @@ -70,7 +70,7 @@ def configure(env, env_mono): mono_lib_path = os.path.join(mono_root, 'lib') env.Append(LIBPATH=mono_lib_path) - env_mono.Append(CPPPATH=os.path.join(mono_root, 'include', 'mono-2.0')) + env_mono.Prepend(CPPPATH=os.path.join(mono_root, 'include', 'mono-2.0')) if mono_static: lib_suffix = Environment()['LIBSUFFIX'] @@ -153,7 +153,7 @@ def configure(env, env_mono): mono_lib_path = os.path.join(mono_root, 'lib') env.Append(LIBPATH=mono_lib_path) - env_mono.Append(CPPPATH=os.path.join(mono_root, 'include', 'mono-2.0')) + env_mono.Prepend(CPPPATH=os.path.join(mono_root, 'include', 'mono-2.0')) mono_lib = find_file_in_dir(mono_lib_path, mono_lib_names, prefix='lib', extension='.a') diff --git a/modules/mono/csharp_script.cpp b/modules/mono/csharp_script.cpp index 27e579935f..ef09e76d11 100644 --- a/modules/mono/csharp_script.cpp +++ b/modules/mono/csharp_script.cpp @@ -2285,8 +2285,9 @@ bool CSharpScript::_get_member_export(GDMonoClass *p_class, IMonoClassMember *p_ hint = PROPERTY_HINT_RESOURCE_TYPE; hint_string = NATIVE_GDMONOCLASS_NAME(field_native_class); } else if (variant_type == Variant::ARRAY && export_info.array.element_type != Variant::NIL) { + String elem_type_str = itos(export_info.array.element_type); hint = PROPERTY_HINT_TYPE_STRING; - hint_string = itos(export_info.array.element_type) + ":"; + hint_string = elem_type_str + "/" + elem_type_str + ":" + export_info.array.element_native_name; } else if (variant_type == Variant::DICTIONARY && export_info.dictionary.key_type != Variant::NIL && export_info.dictionary.value_type != Variant::NIL) { // TODO: There is no hint for this yet } else { diff --git a/modules/mono/mono_gd/gd_mono_marshal.cpp b/modules/mono/mono_gd/gd_mono_marshal.cpp index de4f3650bd..d586b73cf9 100644 --- a/modules/mono/mono_gd/gd_mono_marshal.cpp +++ b/modules/mono/mono_gd/gd_mono_marshal.cpp @@ -184,8 +184,13 @@ Variant::Type managed_to_variant_type(const ManagedType &p_type, ExportInfo *r_e reftype, &key_reftype, &value_reftype, &exc); UNLIKELY_UNHANDLED_EXCEPTION(exc); - r_export_info->dictionary.key_type = managed_to_variant_type(ManagedType::from_reftype(key_reftype)); - r_export_info->dictionary.value_type = managed_to_variant_type(ManagedType::from_reftype(value_reftype)); + ManagedType key_type = ManagedType::from_reftype(key_reftype); + ManagedType value_type = ManagedType::from_reftype(value_reftype); + + r_export_info->dictionary.key_type = managed_to_variant_type(key_type); + r_export_info->dictionary.key_native_name = NATIVE_GDMONOCLASS_NAME(key_type.type_class); + r_export_info->dictionary.value_type = managed_to_variant_type(value_type); + r_export_info->dictionary.value_native_name = NATIVE_GDMONOCLASS_NAME(value_type.type_class); } return Variant::DICTIONARY; @@ -205,7 +210,10 @@ Variant::Type managed_to_variant_type(const ManagedType &p_type, ExportInfo *r_e reftype, &elem_reftype, &exc); UNLIKELY_UNHANDLED_EXCEPTION(exc); - r_export_info->array.element_type = managed_to_variant_type(ManagedType::from_reftype(elem_reftype)); + ManagedType elem_type = ManagedType::from_reftype(elem_reftype); + + r_export_info->array.element_type = managed_to_variant_type(elem_type); + r_export_info->array.element_native_name = NATIVE_GDMONOCLASS_NAME(elem_type.type_class); } return Variant::ARRAY; diff --git a/modules/mono/mono_gd/gd_mono_marshal.h b/modules/mono/mono_gd/gd_mono_marshal.h index 4a73f9e3e6..8d3fd4b349 100644 --- a/modules/mono/mono_gd/gd_mono_marshal.h +++ b/modules/mono/mono_gd/gd_mono_marshal.h @@ -61,13 +61,16 @@ T unbox(MonoObject *p_obj) { struct ExportInfo { struct ArrayInfo { Variant::Type element_type; + String element_native_name; ArrayInfo() : element_type(Variant::NIL) {} } array; struct DictionaryInfo { Variant::Type key_type; + String key_native_name; Variant::Type value_type; + String value_native_name; DictionaryInfo() : key_type(Variant::NIL), diff --git a/modules/ogg/SCsub b/modules/ogg/SCsub index 765a9fc11a..6a72a519fe 100644 --- a/modules/ogg/SCsub +++ b/modules/ogg/SCsub @@ -14,7 +14,7 @@ if env['builtin_libogg']: ] thirdparty_sources = [thirdparty_dir + file for file in thirdparty_sources] - env_ogg.Append(CPPPATH=[thirdparty_dir]) + env_ogg.Prepend(CPPPATH=[thirdparty_dir]) env_thirdparty = env_ogg.Clone() env_thirdparty.disable_warnings() diff --git a/modules/opensimplex/SCsub b/modules/opensimplex/SCsub index 4235f6a0b9..311d33b047 100644 --- a/modules/opensimplex/SCsub +++ b/modules/opensimplex/SCsub @@ -12,7 +12,7 @@ thirdparty_sources = [ ] thirdparty_sources = [thirdparty_dir + file for file in thirdparty_sources] -env_opensimplex.Append(CPPPATH=[thirdparty_dir]) +env_opensimplex.Prepend(CPPPATH=[thirdparty_dir]) env_thirdparty = env_opensimplex.Clone() env_thirdparty.disable_warnings() diff --git a/modules/opus/SCsub b/modules/opus/SCsub index a1325734e2..f3c981dd45 100644 --- a/modules/opus/SCsub +++ b/modules/opus/SCsub @@ -206,7 +206,7 @@ if env['builtin_opus']: # also requires libogg if env['builtin_libogg']: - env_opus.Append(CPPPATH=["#thirdparty/libogg"]) + env_opus.Prepend(CPPPATH=["#thirdparty/libogg"]) env_opus.Append(CPPFLAGS=["-DHAVE_CONFIG_H"]) @@ -218,7 +218,7 @@ if env['builtin_opus']: "silk/fixed", "silk/float", ] - env_opus.Append(CPPPATH=[thirdparty_dir + "/" + dir for dir in thirdparty_include_paths]) + env_opus.Prepend(CPPPATH=[thirdparty_dir + "/" + dir for dir in thirdparty_include_paths]) if env["platform"] == "android": if ("android_arch" in env and env["android_arch"] in ["armv6", "armv7"]): diff --git a/modules/pvr/SCsub b/modules/pvr/SCsub index 2e4a792a36..18da38fbbd 100644 --- a/modules/pvr/SCsub +++ b/modules/pvr/SCsub @@ -17,7 +17,7 @@ thirdparty_sources = [ ] thirdparty_sources = [thirdparty_dir + file for file in thirdparty_sources] -env_pvr.Append(CPPPATH=[thirdparty_dir]) +env_pvr.Prepend(CPPPATH=[thirdparty_dir]) env_thirdparty = env_pvr.Clone() env_thirdparty.disable_warnings() diff --git a/modules/recast/SCsub b/modules/recast/SCsub index 4a06653968..94d9968164 100644 --- a/modules/recast/SCsub +++ b/modules/recast/SCsub @@ -23,7 +23,7 @@ if env['builtin_recast']: ] thirdparty_sources = [thirdparty_dir + file for file in thirdparty_sources] - env_recast.Append(CPPPATH=[thirdparty_dir + "/Include"]) + env_recast.Prepend(CPPPATH=[thirdparty_dir + "/Include"]) env_thirdparty = env_recast.Clone() env_thirdparty.disable_warnings() diff --git a/modules/regex/SCsub b/modules/regex/SCsub index 99c25add45..65f354ffa7 100644 --- a/modules/regex/SCsub +++ b/modules/regex/SCsub @@ -46,7 +46,7 @@ if env['builtin_pcre2']: thirdparty_sources = [thirdparty_dir + file for file in thirdparty_sources] - env_regex.Append(CPPPATH=[thirdparty_dir]) + env_regex.Prepend(CPPPATH=[thirdparty_dir]) env_regex.Append(CPPFLAGS=thirdparty_flags) def pcre2_builtin(width): diff --git a/modules/squish/SCsub b/modules/squish/SCsub index 3be85a1efa..15320bcd0c 100644 --- a/modules/squish/SCsub +++ b/modules/squish/SCsub @@ -22,7 +22,7 @@ if env['builtin_squish']: thirdparty_sources = [thirdparty_dir + file for file in thirdparty_sources] - env_squish.Append(CPPPATH=[thirdparty_dir]) + env_squish.Prepend(CPPPATH=[thirdparty_dir]) env_thirdparty = env_squish.Clone() env_thirdparty.disable_warnings() diff --git a/modules/svg/SCsub b/modules/svg/SCsub index 66d9b3bf75..90bfe22abb 100644 --- a/modules/svg/SCsub +++ b/modules/svg/SCsub @@ -12,10 +12,10 @@ thirdparty_sources = [ ] thirdparty_sources = [thirdparty_dir + file for file in thirdparty_sources] -env_svg.Append(CPPPATH=[thirdparty_dir]) +env_svg.Prepend(CPPPATH=[thirdparty_dir]) # FIXME: Needed in editor/editor_themes.cpp for now, but ideally there # shouldn't be a dependency on modules/ and its own 3rd party deps. -env.Append(CPPPATH=[thirdparty_dir]) +env.Prepend(CPPPATH=[thirdparty_dir]) env.Append(CPPFLAGS=["-DSVG_ENABLED"]) env_thirdparty = env_svg.Clone() diff --git a/modules/theora/SCsub b/modules/theora/SCsub index f98db2359c..785eca4c41 100644 --- a/modules/theora/SCsub +++ b/modules/theora/SCsub @@ -70,13 +70,13 @@ if env['builtin_libtheora']: thirdparty_sources = [thirdparty_dir + file for file in thirdparty_sources] - env_theora.Append(CPPPATH=[thirdparty_dir]) + env_theora.Prepend(CPPPATH=[thirdparty_dir]) # also requires libogg and libvorbis if env['builtin_libogg']: - env_theora.Append(CPPPATH=["#thirdparty/libogg"]) + env_theora.Prepend(CPPPATH=["#thirdparty/libogg"]) if env['builtin_libvorbis']: - env_theora.Append(CPPPATH=["#thirdparty/libvorbis"]) + env_theora.Prepend(CPPPATH=["#thirdparty/libvorbis"]) env_thirdparty = env_theora.Clone() env_thirdparty.disable_warnings() diff --git a/modules/theora/video_stream_theora.cpp b/modules/theora/video_stream_theora.cpp index 8db0799b47..ae542713ea 100644 --- a/modules/theora/video_stream_theora.cpp +++ b/modules/theora/video_stream_theora.cpp @@ -94,15 +94,15 @@ void VideoStreamPlaybackTheora::video_write(void) { if (px_fmt == TH_PF_444) { - yuv444_2_rgb8888((uint8_t *)dst, (uint8_t *)yuv[0].data, (uint8_t *)yuv[1].data, (uint8_t *)yuv[2].data, size.x, size.y, yuv[0].stride, yuv[1].stride, size.x << 2, 0); + yuv444_2_rgb8888((uint8_t *)dst, (uint8_t *)yuv[0].data, (uint8_t *)yuv[1].data, (uint8_t *)yuv[2].data, size.x, size.y, yuv[0].stride, yuv[1].stride, size.x << 2); } else if (px_fmt == TH_PF_422) { - yuv422_2_rgb8888((uint8_t *)dst, (uint8_t *)yuv[0].data, (uint8_t *)yuv[1].data, (uint8_t *)yuv[2].data, size.x, size.y, yuv[0].stride, yuv[1].stride, size.x << 2, 0); + yuv422_2_rgb8888((uint8_t *)dst, (uint8_t *)yuv[0].data, (uint8_t *)yuv[1].data, (uint8_t *)yuv[2].data, size.x, size.y, yuv[0].stride, yuv[1].stride, size.x << 2); } else if (px_fmt == TH_PF_420) { - yuv420_2_rgb8888((uint8_t *)dst, (uint8_t *)yuv[0].data, (uint8_t *)yuv[2].data, (uint8_t *)yuv[1].data, size.x, size.y, yuv[0].stride, yuv[1].stride, size.x << 2, 0); + yuv420_2_rgb8888((uint8_t *)dst, (uint8_t *)yuv[0].data, (uint8_t *)yuv[1].data, (uint8_t *)yuv[2].data, size.x, size.y, yuv[0].stride, yuv[1].stride, size.x << 2); }; format = Image::FORMAT_RGBA8; diff --git a/modules/tinyexr/SCsub b/modules/tinyexr/SCsub index 3e7bda2bca..97f9797b58 100644 --- a/modules/tinyexr/SCsub +++ b/modules/tinyexr/SCsub @@ -13,7 +13,7 @@ thirdparty_sources = [ ] thirdparty_sources = [thirdparty_dir + file for file in thirdparty_sources] -env_tinyexr.Append(CPPPATH=[thirdparty_dir]) +env_tinyexr.Prepend(CPPPATH=[thirdparty_dir]) env_thirdparty = env_tinyexr.Clone() env_thirdparty.disable_warnings() diff --git a/modules/upnp/SCsub b/modules/upnp/SCsub index 2b15f7aee2..6d669ab73b 100644 --- a/modules/upnp/SCsub +++ b/modules/upnp/SCsub @@ -25,7 +25,7 @@ if env['builtin_miniupnpc']: ] thirdparty_sources = [thirdparty_dir + file for file in thirdparty_sources] - env_upnp.Append(CPPPATH=[thirdparty_dir]) + env_upnp.Prepend(CPPPATH=[thirdparty_dir]) env_upnp.Append(CPPFLAGS=["-DMINIUPNP_STATICLIB"]) env_thirdparty = env_upnp.Clone() diff --git a/modules/vhacd/SCsub b/modules/vhacd/SCsub index fdd3ddc1e6..161aed2eb9 100644 --- a/modules/vhacd/SCsub +++ b/modules/vhacd/SCsub @@ -24,7 +24,7 @@ thirdparty_sources = [ thirdparty_sources = [thirdparty_dir + file for file in thirdparty_sources] -env_vhacd.Append(CPPPATH=[thirdparty_dir+"/inc"]) +env_vhacd.Prepend(CPPPATH=[thirdparty_dir + "/inc"]) env_vhacd.Append(CPPFLAGS=["-DGODOT_ENET"]) # upstream uses c++11 diff --git a/modules/visual_script/visual_script_editor.cpp b/modules/visual_script/visual_script_editor.cpp index b50c99932d..28c9a11cb8 100644 --- a/modules/visual_script/visual_script_editor.cpp +++ b/modules/visual_script/visual_script_editor.cpp @@ -3574,7 +3574,7 @@ VisualScriptEditor::VisualScriptEditor() { graph->connect("scroll_offset_changed", this, "_graph_ofs_changed"); select_func_text = memnew(Label); - select_func_text->set_text(TTR("Select or create a function to edit graph")); + select_func_text->set_text(TTR("Select or create a function to edit its graph.")); select_func_text->set_align(Label::ALIGN_CENTER); select_func_text->set_valign(Label::VALIGN_CENTER); select_func_text->set_h_size_flags(SIZE_EXPAND_FILL); diff --git a/modules/vorbis/SCsub b/modules/vorbis/SCsub index 19587563ab..3824fdd789 100644 --- a/modules/vorbis/SCsub +++ b/modules/vorbis/SCsub @@ -40,11 +40,11 @@ if env['builtin_libvorbis']: thirdparty_sources = [thirdparty_dir + file for file in thirdparty_sources] - env_vorbis.Append(CPPPATH=[thirdparty_dir]) + env_vorbis.Prepend(CPPPATH=[thirdparty_dir]) # also requires libogg if env['builtin_libogg']: - env_vorbis.Append(CPPPATH=["#thirdparty/libogg"]) + env_vorbis.Prepend(CPPPATH=["#thirdparty/libogg"]) env_thirdparty = env_vorbis.Clone() env_thirdparty.disable_warnings() diff --git a/modules/webm/SCsub b/modules/webm/SCsub index dcc9a45044..e57437229f 100644 --- a/modules/webm/SCsub +++ b/modules/webm/SCsub @@ -15,7 +15,7 @@ thirdparty_sources = [ ] thirdparty_sources = [thirdparty_dir + file for file in thirdparty_sources] -env_webm.Append(CPPPATH=[thirdparty_dir, thirdparty_dir + "libwebm/"]) +env_webm.Prepend(CPPPATH=[thirdparty_dir, thirdparty_dir + "libwebm/"]) # upstream uses c++11 if (not env_webm.msvc): @@ -23,14 +23,14 @@ if (not env_webm.msvc): # also requires libogg, libvorbis and libopus if env['builtin_libogg']: - env_webm.Append(CPPPATH=["#thirdparty/libogg"]) + env_webm.Prepend(CPPPATH=["#thirdparty/libogg"]) if env['builtin_libvorbis']: - env_webm.Append(CPPPATH=["#thirdparty/libvorbis"]) + env_webm.Prepend(CPPPATH=["#thirdparty/libvorbis"]) if env['builtin_opus']: - env_webm.Append(CPPPATH=["#thirdparty/opus"]) + env_webm.Prepend(CPPPATH=["#thirdparty/opus"]) if env['builtin_libvpx']: - env_webm.Append(CPPPATH=["#thirdparty/libvpx"]) + env_webm.Prepend(CPPPATH=["#thirdparty/libvpx"]) SConscript("libvpx/SCsub") env_thirdparty = env_webm.Clone() diff --git a/modules/webm/libvpx/SCsub b/modules/webm/libvpx/SCsub index 5bf4ea3464..a6be1380a6 100644 --- a/modules/webm/libvpx/SCsub +++ b/modules/webm/libvpx/SCsub @@ -256,7 +256,7 @@ libvpx_sources_arm_neon_gas_apple = [libvpx_dir + file for file in libvpx_source env_libvpx = env_modules.Clone() env_libvpx.disable_warnings() -env_libvpx.Append(CPPPATH=[libvpx_dir]) +env_libvpx.Prepend(CPPPATH=[libvpx_dir]) webm_multithread = env["platform"] != 'javascript' @@ -380,7 +380,7 @@ if webm_cpu_x86: elif webm_cpu_arm: env_libvpx.add_source_files(env.modules_sources, libvpx_sources_arm) if env["platform"] == 'android': - env_libvpx.Append(CPPPATH=[libvpx_dir + "third_party/android"]) + env_libvpx.Prepend(CPPPATH=[libvpx_dir + "third_party/android"]) env_libvpx.add_source_files(env.modules_sources, [libvpx_dir + "third_party/android/cpu-features.c"]) env_libvpx_neon = env_libvpx.Clone() diff --git a/modules/webm/video_stream_webm.cpp b/modules/webm/video_stream_webm.cpp index f2497eeec1..6485c95360 100644 --- a/modules/webm/video_stream_webm.cpp +++ b/modules/webm/video_stream_webm.cpp @@ -32,6 +32,7 @@ #include "OpusVorbisDecoder.hpp" #include "VPXDecoder.hpp" +#include <vpx/vpx_image.h> #include "mkvparser/mkvparser.h" @@ -314,19 +315,37 @@ void VideoStreamPlaybackWebm::update(float p_delta) { PoolVector<uint8_t>::Write w = frame_data.write(); bool converted = false; - if (image.chromaShiftW == 1 && image.chromaShiftH == 1) { + if (image.chromaShiftW == 0 && image.chromaShiftH == 0 && image.cs == VPX_CS_SRGB) { + + uint8_t *wp = w.ptr(); + unsigned char *rRow = image.planes[2]; + unsigned char *gRow = image.planes[0]; + unsigned char *bRow = image.planes[1]; + for (int i = 0; i < image.h; i++) { + for (int j = 0; j < image.w; j++) { + *wp++ = rRow[j]; + *wp++ = gRow[j]; + *wp++ = bRow[j]; + *wp++ = 255; + } + rRow += image.linesize[2]; + gRow += image.linesize[0]; + bRow += image.linesize[1]; + } + converted = true; + } else if (image.chromaShiftW == 1 && image.chromaShiftH == 1) { - yuv420_2_rgb8888(w.ptr(), image.planes[0], image.planes[2], image.planes[1], image.w, image.h, image.linesize[0], image.linesize[1], image.w << 2, 0); + yuv420_2_rgb8888(w.ptr(), image.planes[0], image.planes[1], image.planes[2], image.w, image.h, image.linesize[0], image.linesize[1], image.w << 2); // libyuv::I420ToARGB(image.planes[0], image.linesize[0], image.planes[2], image.linesize[2], image.planes[1], image.linesize[1], w.ptr(), image.w << 2, image.w, image.h); converted = true; } else if (image.chromaShiftW == 1 && image.chromaShiftH == 0) { - yuv422_2_rgb8888(w.ptr(), image.planes[0], image.planes[2], image.planes[1], image.w, image.h, image.linesize[0], image.linesize[1], image.w << 2, 0); + yuv422_2_rgb8888(w.ptr(), image.planes[0], image.planes[1], image.planes[2], image.w, image.h, image.linesize[0], image.linesize[1], image.w << 2); // libyuv::I422ToARGB(image.planes[0], image.linesize[0], image.planes[2], image.linesize[2], image.planes[1], image.linesize[1], w.ptr(), image.w << 2, image.w, image.h); converted = true; } else if (image.chromaShiftW == 0 && image.chromaShiftH == 0) { - yuv444_2_rgb8888(w.ptr(), image.planes[0], image.planes[2], image.planes[1], image.w, image.h, image.linesize[0], image.linesize[1], image.w << 2, 0); + yuv444_2_rgb8888(w.ptr(), image.planes[0], image.planes[1], image.planes[2], image.w, image.h, image.linesize[0], image.linesize[1], image.w << 2); // libyuv::I444ToARGB(image.planes[0], image.linesize[0], image.planes[2], image.linesize[2], image.planes[1], image.linesize[1], w.ptr(), image.w << 2, image.w, image.h); converted = true; } else if (image.chromaShiftW == 2 && image.chromaShiftH == 0) { diff --git a/modules/webp/SCsub b/modules/webp/SCsub index fa3896c457..666628bb44 100644 --- a/modules/webp/SCsub +++ b/modules/webp/SCsub @@ -126,7 +126,7 @@ if env['builtin_libwebp']: ] thirdparty_sources = [thirdparty_dir + "src/" + file for file in thirdparty_sources] - env_webp.Append(CPPPATH=[thirdparty_dir, thirdparty_dir + "src/"]) + env_webp.Prepend(CPPPATH=[thirdparty_dir, thirdparty_dir + "src/"]) env_thirdparty = env_webp.Clone() env_thirdparty.disable_warnings() diff --git a/modules/webrtc/SCsub b/modules/webrtc/SCsub index 446bd530c2..868553b879 100644 --- a/modules/webrtc/SCsub +++ b/modules/webrtc/SCsub @@ -10,7 +10,6 @@ use_gdnative = env_webrtc["module_gdnative_enabled"] if use_gdnative: # GDNative is retained in Javascript for export compatibility env_webrtc.Append(CPPDEFINES=['WEBRTC_GDNATIVE_ENABLED']) - gdnative_includes = ["#modules/gdnative/include/"] - env_webrtc.Append(CPPPATH=gdnative_includes) + env_webrtc.Prepend(CPPPATH=["#modules/gdnative/include/"]) env_webrtc.add_source_files(env.modules_sources, "*.cpp") diff --git a/modules/websocket/SCsub b/modules/websocket/SCsub index 12b4969cf7..2d2de81220 100644 --- a/modules/websocket/SCsub +++ b/modules/websocket/SCsub @@ -75,7 +75,7 @@ if env['builtin_libwebsockets'] and not env["platform"] == "javascript": # alrea else: # Unix socket thirdparty_sources += Glob(thirdparty_dir + "lib/plat/unix/*.c") - env_lws.Append(CPPPATH=[thirdparty_dir + 'include/']) + env_lws.Prepend(CPPPATH=[thirdparty_dir + 'include/']) if env['builtin_mbedtls']: mbedtls_includes = "#thirdparty/mbedtls/include" @@ -85,14 +85,14 @@ if env['builtin_libwebsockets'] and not env["platform"] == "javascript": # alrea env_lws.Prepend(CPPPATH=wrapper_includes) if env["platform"] == "windows" or env["platform"] == "uwp": - env_lws.Append(CPPPATH=[helper_dir]) + env_lws.Prepend(CPPPATH=[helper_dir]) if env["platform"] == "uwp": env_lws.Append(CPPFLAGS=["/DLWS_MINGW_SUPPORT"]) env_thirdparty = env_lws.Clone() env_thirdparty.disable_warnings() - env_thirdparty.Append(CPPPATH=[thirdparty_dir + 'lib/']) + env_thirdparty.Prepend(CPPPATH=[thirdparty_dir + 'lib/']) env_thirdparty.add_source_files(env.modules_sources, thirdparty_sources) env_lws.add_source_files(env.modules_sources, "*.cpp") diff --git a/modules/xatlas_unwrap/SCsub b/modules/xatlas_unwrap/SCsub index 7a40945f27..50e3cb1551 100644 --- a/modules/xatlas_unwrap/SCsub +++ b/modules/xatlas_unwrap/SCsub @@ -13,7 +13,7 @@ if env['builtin_xatlas']: ] thirdparty_sources = [thirdparty_dir + file for file in thirdparty_sources] - env_xatlas_unwrap.Append(CPPPATH=[thirdparty_dir]) + env_xatlas_unwrap.Prepend(CPPPATH=[thirdparty_dir]) # upstream uses c++11 if (not env.msvc): diff --git a/platform/android/detect.py b/platform/android/detect.py index 6c67067db7..8d35617d20 100644 --- a/platform/android/detect.py +++ b/platform/android/detect.py @@ -299,7 +299,7 @@ def configure(env): env.Append(LIBPATH=[env["ANDROID_NDK_ROOT"] + '/toolchains/' + target_subpath + '/prebuilt/' + host_subpath + '/' + abi_subpath + '/lib']) - env.Append(CPPPATH=['#platform/android']) + env.Prepend(CPPPATH=['#platform/android']) env.Append(CPPFLAGS=['-DANDROID_ENABLED', '-DUNIX_ENABLED', '-DNO_FCNTL']) env.Append(LIBS=['OpenSLES', 'EGL', 'GLESv3', 'android', 'log', 'z', 'dl']) diff --git a/platform/haiku/detect.py b/platform/haiku/detect.py index 874b1ab1fb..f33c77a407 100644 --- a/platform/haiku/detect.py +++ b/platform/haiku/detect.py @@ -137,7 +137,7 @@ def configure(env): if not env['builtin_miniupnpc']: # No pkgconfig file so far, hardcode default paths. - env.Append(CPPPATH=["/system/develop/headers/x86/miniupnpc"]) + env.Prepend(CPPPATH=["/system/develop/headers/x86/miniupnpc"]) env.Append(LIBS=["miniupnpc"]) # On Linux wchar_t should be 32-bits @@ -147,7 +147,7 @@ def configure(env): ## Flags - env.Append(CPPPATH=['#platform/haiku']) + env.Prepend(CPPPATH=['#platform/haiku']) env.Append(CPPFLAGS=['-DUNIX_ENABLED', '-DOPENGL_ENABLED', '-DGLES_ENABLED']) env.Append(CPPFLAGS=['-DMEDIA_KIT_ENABLED']) # env.Append(CPPFLAGS=['-DFREETYPE_ENABLED']) diff --git a/platform/iphone/detect.py b/platform/iphone/detect.py index d56e28a4af..3ed0a4ade7 100644 --- a/platform/iphone/detect.py +++ b/platform/iphone/detect.py @@ -165,12 +165,12 @@ def configure(env): if env['icloud']: env.Append(CPPFLAGS=['-DICLOUD_ENABLED']) - env.Append(CPPPATH=['$IPHONESDK/usr/include', - '$IPHONESDK/System/Library/Frameworks/OpenGLES.framework/Headers', - '$IPHONESDK/System/Library/Frameworks/AudioUnit.framework/Headers', - ]) + env.Prepend(CPPPATH=['$IPHONESDK/usr/include', + '$IPHONESDK/System/Library/Frameworks/OpenGLES.framework/Headers', + '$IPHONESDK/System/Library/Frameworks/AudioUnit.framework/Headers', + ]) env['ENV']['CODESIGN_ALLOCATE'] = '/Developer/Platforms/iPhoneOS.platform/Developer/usr/bin/codesign_allocate' - env.Append(CPPPATH=['#platform/iphone']) + env.Prepend(CPPPATH=['#platform/iphone']) env.Append(CPPFLAGS=['-DIPHONE_ENABLED', '-DUNIX_ENABLED', '-DGLES_ENABLED', '-DCOREAUDIO_ENABLED']) diff --git a/platform/javascript/detect.py b/platform/javascript/detect.py index c7acbde3f7..145ce8d83d 100644 --- a/platform/javascript/detect.py +++ b/platform/javascript/detect.py @@ -103,7 +103,7 @@ def configure(env): ## Compile flags - env.Append(CPPPATH=['#platform/javascript']) + env.Prepend(CPPPATH=['#platform/javascript']) env.Append(CPPDEFINES=['JAVASCRIPT_ENABLED', 'UNIX_ENABLED']) # No multi-threading (SharedArrayBuffer) available yet, diff --git a/platform/osx/detect.py b/platform/osx/detect.py index 8024897195..4c88f91d13 100644 --- a/platform/osx/detect.py +++ b/platform/osx/detect.py @@ -126,7 +126,7 @@ def configure(env): ## Flags - env.Append(CPPPATH=['#platform/osx']) + env.Prepend(CPPPATH=['#platform/osx']) env.Append(CPPFLAGS=['-DOSX_ENABLED', '-DUNIX_ENABLED', '-DGLES_ENABLED', '-DAPPLE_STYLE_KEYS', '-DCOREAUDIO_ENABLED', '-DCOREMIDI_ENABLED']) env.Append(LINKFLAGS=['-framework', 'Cocoa', '-framework', 'Carbon', '-framework', 'OpenGL', '-framework', 'AGL', '-framework', 'AudioUnit', '-framework', 'CoreAudio', '-framework', 'CoreMIDI', '-lz', '-framework', 'IOKit', '-framework', 'ForceFeedback', '-framework', 'CoreVideo']) env.Append(LIBS=['pthread']) diff --git a/platform/server/detect.py b/platform/server/detect.py index 5306a2bf69..08c2eb6aaf 100644 --- a/platform/server/detect.py +++ b/platform/server/detect.py @@ -201,7 +201,7 @@ def configure(env): if not env['builtin_miniupnpc']: # No pkgconfig file so far, hardcode default paths. - env.Append(CPPPATH=["/usr/include/miniupnpc"]) + env.Prepend(CPPPATH=["/usr/include/miniupnpc"]) env.Append(LIBS=["miniupnpc"]) # On Linux wchar_t should be 32-bits @@ -215,7 +215,7 @@ def configure(env): if not env['builtin_zlib']: env.ParseConfig('pkg-config zlib --cflags --libs') - env.Append(CPPPATH=['#platform/server']) + env.Prepend(CPPPATH=['#platform/server']) env.Append(CPPFLAGS=['-DSERVER_ENABLED', '-DUNIX_ENABLED']) if (platform.system() == "Darwin"): diff --git a/platform/uwp/detect.py b/platform/uwp/detect.py index 17f8242466..00f419f4f0 100644 --- a/platform/uwp/detect.py +++ b/platform/uwp/detect.py @@ -77,7 +77,7 @@ def configure(env): # ANGLE angle_root = os.getenv("ANGLE_SRC_PATH") - env.Append(CPPPATH=[angle_root + '/include']) + env.Prepend(CPPPATH=[angle_root + '/include']) jobs = str(env.GetOption("num_jobs")) angle_build_cmd = "msbuild.exe " + angle_root + "/winrt/10/src/angle.sln /nologo /v:m /m:" + jobs + " /p:Configuration=Release /p:Platform=" @@ -137,7 +137,7 @@ def configure(env): ## Compile flags - env.Append(CPPPATH=['#platform/uwp', '#drivers/windows']) + env.Prepend(CPPPATH=['#platform/uwp', '#drivers/windows']) env.Append(CPPFLAGS=['/DUWP_ENABLED', '/DWINDOWS_ENABLED', '/DTYPED_METHOD_BIND']) env.Append(CPPFLAGS=['/DGLES_ENABLED', '/DGL_GLEXT_PROTOTYPES', '/DEGL_EGLEXT_PROTOTYPES', '/DANGLE_ENABLED']) winver = "0x0602" # Windows 8 is the minimum target for UWP build diff --git a/platform/windows/detect.py b/platform/windows/detect.py index 5c38eebf04..4b4b507499 100644 --- a/platform/windows/detect.py +++ b/platform/windows/detect.py @@ -201,7 +201,7 @@ def configure_msvc(env, manual_msvc_config): env.AppendUnique(CXXFLAGS=['/TP']) # assume all sources are C++ if manual_msvc_config: # should be automatic if SCons found it if os.getenv("WindowsSdkDir") is not None: - env.Append(CPPPATH=[os.getenv("WindowsSdkDir") + "/Include"]) + env.Prepend(CPPPATH=[os.getenv("WindowsSdkDir") + "/Include"]) else: print("Missing environment variable: WindowsSdkDir") @@ -239,7 +239,7 @@ def configure_msvc(env, manual_msvc_config): env.AppendUnique(LINKFLAGS=['/LTCG']) if manual_msvc_config: - env.Append(CPPPATH=[p for p in os.getenv("INCLUDE").split(";")]) + env.Prepend(CPPPATH=[p for p in os.getenv("INCLUDE").split(";")]) env.Append(LIBPATH=[p for p in os.getenv("LIB").split(";")]) # Incremental linking fix @@ -342,7 +342,7 @@ def configure_mingw(env): def configure(env): # At this point the env has been set up with basic tools/compilers. - env.Append(CPPPATH=['#platform/windows']) + env.Prepend(CPPPATH=['#platform/windows']) print("Configuring for Windows: target=%s, bits=%s" % (env['target'], env['bits'])) diff --git a/platform/x11/detect.py b/platform/x11/detect.py index f8ae5e9acb..933ee6b72e 100644 --- a/platform/x11/detect.py +++ b/platform/x11/detect.py @@ -275,7 +275,7 @@ def configure(env): if not env['builtin_miniupnpc']: # No pkgconfig file so far, hardcode default paths. - env.Append(CPPPATH=["/usr/include/miniupnpc"]) + env.Prepend(CPPPATH=["/usr/include/miniupnpc"]) env.Append(LIBS=["miniupnpc"]) # On Linux wchar_t should be 32-bits @@ -316,7 +316,7 @@ def configure(env): if not env['builtin_zlib']: env.ParseConfig('pkg-config zlib --cflags --libs') - env.Append(CPPPATH=['#platform/x11']) + env.Prepend(CPPPATH=['#platform/x11']) env.Append(CPPFLAGS=['-DX11_ENABLED', '-DUNIX_ENABLED', '-DOPENGL_ENABLED', '-DGLES_ENABLED']) env.Append(LIBS=['GL', 'pthread']) diff --git a/platform/x11/os_x11.cpp b/platform/x11/os_x11.cpp index 8d857de239..267ac08a72 100644 --- a/platform/x11/os_x11.cpp +++ b/platform/x11/os_x11.cpp @@ -1176,15 +1176,28 @@ Point2 OS_X11::get_window_position() const { int x, y; Window child; XTranslateCoordinates(x11_display, x11_window, DefaultRootWindow(x11_display), 0, 0, &x, &y, &child); - - int screen = get_current_screen(); - Point2i screen_position = get_screen_position(screen); - - return Point2i(x - screen_position.x, y - screen_position.y); + return Point2i(x, y); } void OS_X11::set_window_position(const Point2 &p_position) { - XMoveWindow(x11_display, x11_window, p_position.x, p_position.y); + int x = 0; + int y = 0; + if (get_borderless_window() == false) { + //exclude window decorations + XSync(x11_display, False); + Atom prop = XInternAtom(x11_display, "_NET_FRAME_EXTENTS", True); + Atom type; + int format; + unsigned long len; + unsigned long remaining; + unsigned char *data = NULL; + if (XGetWindowProperty(x11_display, x11_window, prop, 0, 4, False, AnyPropertyType, &type, &format, &len, &remaining, &data) == Success) { + long *extents = (long *)data; + x = extents[0]; + y = extents[2]; + } + } + XMoveWindow(x11_display, x11_window, p_position.x - x, p_position.y - y); update_real_mouse_position(); } diff --git a/scene/2d/collision_object_2d.cpp b/scene/2d/collision_object_2d.cpp index f43d97eb2a..375375285d 100644 --- a/scene/2d/collision_object_2d.cpp +++ b/scene/2d/collision_object_2d.cpp @@ -251,9 +251,9 @@ void CollisionObject2D::shape_owner_add_shape(uint32_t p_owner, const Ref<Shape2 s.index = total_subshapes; s.shape = p_shape; if (area) { - Physics2DServer::get_singleton()->area_add_shape(rid, p_shape->get_rid(), sd.xform); + Physics2DServer::get_singleton()->area_add_shape(rid, p_shape->get_rid(), sd.xform, sd.disabled); } else { - Physics2DServer::get_singleton()->body_add_shape(rid, p_shape->get_rid(), sd.xform); + Physics2DServer::get_singleton()->body_add_shape(rid, p_shape->get_rid(), sd.xform, sd.disabled); } sd.shapes.push_back(s); diff --git a/scene/2d/line_2d.cpp b/scene/2d/line_2d.cpp index 73692e0535..ba06b3ebff 100644 --- a/scene/2d/line_2d.cpp +++ b/scene/2d/line_2d.cpp @@ -120,8 +120,12 @@ void Line2D::clear_points() { } } -void Line2D::add_point(Vector2 pos) { - _points.append(pos); +void Line2D::add_point(Vector2 pos, int atpos) { + if (atpos < 0 || _points.size() < atpos) { + _points.append(pos); + } else { + _points.insert(atpos, pos); + } update(); } @@ -318,7 +322,7 @@ void Line2D::_bind_methods() { ClassDB::bind_method(D_METHOD("get_point_count"), &Line2D::get_point_count); - ClassDB::bind_method(D_METHOD("add_point", "position"), &Line2D::add_point); + ClassDB::bind_method(D_METHOD("add_point", "position", "at_position"), &Line2D::add_point, DEFVAL(-1)); ClassDB::bind_method(D_METHOD("remove_point", "i"), &Line2D::remove_point); ClassDB::bind_method(D_METHOD("clear_points"), &Line2D::clear_points); diff --git a/scene/2d/line_2d.h b/scene/2d/line_2d.h index 32befab2d3..8a6f7b2dc5 100644 --- a/scene/2d/line_2d.h +++ b/scene/2d/line_2d.h @@ -72,7 +72,7 @@ public: void clear_points(); - void add_point(Vector2 pos); + void add_point(Vector2 pos, int atpos = -1); void remove_point(int i); void set_width(float width); diff --git a/scene/2d/tile_map.cpp b/scene/2d/tile_map.cpp index 885c9ea8bc..b321bcf3ce 100644 --- a/scene/2d/tile_map.cpp +++ b/scene/2d/tile_map.cpp @@ -749,7 +749,10 @@ void TileMap::set_cellv(const Vector2 &p_pos, int p_tile, bool p_flip_x, bool p_ void TileMap::_set_celld(const Vector2 &p_pos, const Dictionary &p_data) { - set_cell(p_pos.x, p_pos.y, p_data["id"], p_data["flip_h"], p_data["flip_y"], p_data["transpose"], p_data["auto_coord"]); + Variant v_pos_x = p_pos.x, v_pos_y = p_pos.y, v_tile = p_data["id"], v_flip_h = p_data["flip_h"], v_flip_v = p_data["flip_y"], v_transpose = p_data["transpose"], v_autotile_coord = p_data["auto_coord"]; + const Variant *args[7] = { &v_pos_x, &v_pos_y, &v_tile, &v_flip_h, &v_flip_v, &v_transpose, &v_autotile_coord }; + Variant::CallError ce; + call("set_cell", args, 7, ce); } void TileMap::set_cell(int p_x, int p_y, int p_tile, bool p_flip_x, bool p_flip_y, bool p_transpose, Vector2 p_autotile_coord) { diff --git a/scene/3d/arvr_nodes.cpp b/scene/3d/arvr_nodes.cpp index e5346c4c53..52fa96ee4a 100644 --- a/scene/3d/arvr_nodes.cpp +++ b/scene/3d/arvr_nodes.cpp @@ -379,11 +379,11 @@ String ARVRController::get_configuration_warning() const { // must be child node of ARVROrigin! ARVROrigin *origin = Object::cast_to<ARVROrigin>(get_parent()); if (origin == NULL) { - return TTR("ARVRController must have an ARVROrigin node as its parent"); + return TTR("ARVRController must have an ARVROrigin node as its parent."); }; if (controller_id == 0) { - return TTR("The controller id must not be 0 or this controller will not be bound to an actual controller"); + return TTR("The controller ID must not be 0 or this controller won't be bound to an actual controller."); }; return String(); @@ -506,11 +506,11 @@ String ARVRAnchor::get_configuration_warning() const { // must be child node of ARVROrigin! ARVROrigin *origin = Object::cast_to<ARVROrigin>(get_parent()); if (origin == NULL) { - return TTR("ARVRAnchor must have an ARVROrigin node as its parent"); + return TTR("ARVRAnchor must have an ARVROrigin node as its parent."); }; if (anchor_id == 0) { - return TTR("The anchor id must not be 0 or this anchor will not be bound to an actual anchor"); + return TTR("The anchor ID must not be 0 or this anchor won't be bound to an actual anchor."); }; return String(); @@ -545,7 +545,7 @@ String ARVROrigin::get_configuration_warning() const { return String(); if (tracked_camera == NULL) - return TTR("ARVROrigin requires an ARVRCamera child node"); + return TTR("ARVROrigin requires an ARVRCamera child node."); return String(); }; @@ -583,6 +583,10 @@ void ARVROrigin::set_world_scale(float p_world_scale) { }; void ARVROrigin::_notification(int p_what) { + // get our ARVRServer + ARVRServer *arvr_server = ARVRServer::get_singleton(); + ERR_FAIL_NULL(arvr_server); + switch (p_what) { case NOTIFICATION_ENTER_TREE: { set_process_internal(true); @@ -591,10 +595,6 @@ void ARVROrigin::_notification(int p_what) { set_process_internal(false); }; break; case NOTIFICATION_INTERNAL_PROCESS: { - // get our ARVRServer - ARVRServer *arvr_server = ARVRServer::get_singleton(); - ERR_FAIL_NULL(arvr_server); - // set our world origin to our node transform arvr_server->set_world_origin(get_global_transform()); @@ -611,6 +611,14 @@ void ARVROrigin::_notification(int p_what) { default: break; }; + + // send our notification to all active ARVR interfaces, they may need to react to it also + for (int i = 0; i < arvr_server->get_interface_count(); i++) { + Ref<ARVRInterface> interface = arvr_server->get_interface(i); + if (interface.is_valid() && interface->is_initialized()) { + interface->notification(p_what); + } + } }; ARVROrigin::ARVROrigin() { diff --git a/scene/3d/collision_object.cpp b/scene/3d/collision_object.cpp index f542b021be..fc46cf5bdb 100644 --- a/scene/3d/collision_object.cpp +++ b/scene/3d/collision_object.cpp @@ -259,9 +259,9 @@ void CollisionObject::shape_owner_add_shape(uint32_t p_owner, const Ref<Shape> & s.index = total_subshapes; s.shape = p_shape; if (area) { - PhysicsServer::get_singleton()->area_add_shape(rid, p_shape->get_rid(), sd.xform); + PhysicsServer::get_singleton()->area_add_shape(rid, p_shape->get_rid(), sd.xform, sd.disabled); } else { - PhysicsServer::get_singleton()->body_add_shape(rid, p_shape->get_rid(), sd.xform); + PhysicsServer::get_singleton()->body_add_shape(rid, p_shape->get_rid(), sd.xform, sd.disabled); } sd.shapes.push_back(s); diff --git a/scene/3d/soft_body.cpp b/scene/3d/soft_body.cpp index d6a0595519..909d4fda34 100644 --- a/scene/3d/soft_body.cpp +++ b/scene/3d/soft_body.cpp @@ -405,7 +405,7 @@ String SoftBody::get_configuration_warning() const { if (!warning.empty()) warning += "\n\n"; - warning += TTR("This body will be ignored until you set a mesh"); + warning += TTR("This body will be ignored until you set a mesh."); } Transform t = get_transform(); diff --git a/scene/3d/spatial.cpp b/scene/3d/spatial.cpp index 395f7b9b35..05fd984f93 100644 --- a/scene/3d/spatial.cpp +++ b/scene/3d/spatial.cpp @@ -676,8 +676,7 @@ void Spatial::set_identity() { void Spatial::look_at(const Vector3 &p_target, const Vector3 &p_up) { - Transform lookat; - lookat.origin = get_global_transform().origin; + Transform lookat(get_global_transform()); if (lookat.origin == p_target) { ERR_EXPLAIN("Node origin and target are in the same position, look_at() failed"); ERR_FAIL(); @@ -687,7 +686,10 @@ void Spatial::look_at(const Vector3 &p_target, const Vector3 &p_up) { ERR_EXPLAIN("Up vector and direction between node origin and target are aligned, look_at() failed"); ERR_FAIL(); } + Vector3 original_scale(lookat.basis.get_scale()); lookat = lookat.looking_at(p_target, p_up); + // as basis was normalized, we just need to apply original scale back + lookat.basis.scale(original_scale); set_global_transform(lookat); } diff --git a/scene/animation/animation_player.cpp b/scene/animation/animation_player.cpp index 016db15b73..ead3516116 100644 --- a/scene/animation/animation_player.cpp +++ b/scene/animation/animation_player.cpp @@ -34,7 +34,10 @@ #include "core/message_queue.h" #include "scene/scene_string_names.h" #include "servers/audio/audio_stream.h" + #ifdef TOOLS_ENABLED +#include "editor/editor_settings.h" + void AnimatedValuesBackup::update_skeletons() { for (int i = 0; i < entries.size(); i++) { @@ -1510,13 +1513,19 @@ NodePath AnimationPlayer::get_root() const { void AnimationPlayer::get_argument_options(const StringName &p_function, int p_idx, List<String> *r_options) const { +#ifdef TOOLS_ENABLED + const String quote_style = EDITOR_DEF("text_editor/completion/use_single_quotes", 0) ? "'" : "\""; +#else + const String quote_style = "\""; +#endif + String pf = p_function; if (p_function == "play" || p_function == "play_backwards" || p_function == "remove_animation" || p_function == "has_animation" || p_function == "queue") { List<StringName> al; get_animation_list(&al); for (List<StringName>::Element *E = al.front(); E; E = E->next()) { - r_options->push_back("\"" + String(E->get()) + "\""); + r_options->push_back(quote_style + String(E->get()) + quote_style); } } Node::get_argument_options(p_function, p_idx, r_options); diff --git a/scene/gui/base_button.cpp b/scene/gui/base_button.cpp index d68cdd5f8d..f808d6c234 100644 --- a/scene/gui/base_button.cpp +++ b/scene/gui/base_button.cpp @@ -282,10 +282,7 @@ void BaseButton::_notification(int p_what) { if (p_what == NOTIFICATION_ENTER_TREE) { } - if (p_what == NOTIFICATION_EXIT_TREE) { - } - - if (p_what == NOTIFICATION_VISIBILITY_CHANGED && !is_visible_in_tree()) { + if (p_what == NOTIFICATION_EXIT_TREE || (p_what == NOTIFICATION_VISIBILITY_CHANGED && !is_visible_in_tree())) { if (!toggle_mode) { status.pressed = false; diff --git a/scene/gui/color_picker.cpp b/scene/gui/color_picker.cpp index d8b2cfb5b9..bca3471091 100644 --- a/scene/gui/color_picker.cpp +++ b/scene/gui/color_picker.cpp @@ -38,8 +38,6 @@ #include "editor_scale.h" #include "editor_settings.h" #endif - -#include "scene/gui/separator.h" #include "scene/main/viewport.h" void ColorPicker::_notification(int p_what) { @@ -469,7 +467,7 @@ void ColorPicker::_preset_input(const Ref<InputEvent> &p_event) { set_pick_color(presets[index]); _update_color(); emit_signal("color_changed", color); - } else if (bev->is_pressed() && bev->get_button_index() == BUTTON_RIGHT) { + } else if (bev->is_pressed() && bev->get_button_index() == BUTTON_RIGHT && presets_enabled) { int index = bev->get_position().x / (preset->get_size().x / presets.size()); Color clicked_preset = presets[index]; erase_preset(clicked_preset); @@ -565,6 +563,31 @@ void ColorPicker::_html_focus_exit() { _focus_exit(); } +void ColorPicker::set_presets_enabled(bool p_enabled) { + presets_enabled = p_enabled; + if (!p_enabled) { + bt_add_preset->set_disabled(true); + bt_add_preset->set_focus_mode(FOCUS_NONE); + } else { + bt_add_preset->set_disabled(false); + bt_add_preset->set_focus_mode(FOCUS_ALL); + } +} + +bool ColorPicker::are_presets_enabled() const { + return presets_enabled; +} + +void ColorPicker::set_presets_visible(bool p_visible) { + presets_visible = p_visible; + preset_separator->set_visible(p_visible); + preset_container->set_visible(p_visible); +} + +bool ColorPicker::are_presets_visible() const { + return presets_visible; +} + void ColorPicker::_bind_methods() { ClassDB::bind_method(D_METHOD("set_pick_color", "color"), &ColorPicker::set_pick_color); @@ -575,6 +598,10 @@ void ColorPicker::_bind_methods() { ClassDB::bind_method(D_METHOD("is_deferred_mode"), &ColorPicker::is_deferred_mode); ClassDB::bind_method(D_METHOD("set_edit_alpha", "show"), &ColorPicker::set_edit_alpha); ClassDB::bind_method(D_METHOD("is_editing_alpha"), &ColorPicker::is_editing_alpha); + ClassDB::bind_method(D_METHOD("set_presets_enabled", "enabled"), &ColorPicker::set_presets_enabled); + ClassDB::bind_method(D_METHOD("are_presets_enabled"), &ColorPicker::are_presets_enabled); + ClassDB::bind_method(D_METHOD("set_presets_visible", "visible"), &ColorPicker::set_presets_visible); + ClassDB::bind_method(D_METHOD("are_presets_visible"), &ColorPicker::are_presets_visible); ClassDB::bind_method(D_METHOD("add_preset", "color"), &ColorPicker::add_preset); ClassDB::bind_method(D_METHOD("erase_preset", "color"), &ColorPicker::erase_preset); ClassDB::bind_method(D_METHOD("get_presets"), &ColorPicker::get_presets); @@ -598,6 +625,8 @@ void ColorPicker::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::BOOL, "edit_alpha"), "set_edit_alpha", "is_editing_alpha"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "raw_mode"), "set_raw_mode", "is_raw_mode"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "deferred_mode"), "set_deferred_mode", "is_deferred_mode"); + ADD_PROPERTY(PropertyInfo(Variant::BOOL, "presets_enabled"), "set_presets_enabled", "are_presets_enabled"); + ADD_PROPERTY(PropertyInfo(Variant::BOOL, "presets_visible"), "set_presets_visible", "are_presets_visible"); ADD_SIGNAL(MethodInfo("color_changed", PropertyInfo(Variant::COLOR, "color"))); ADD_SIGNAL(MethodInfo("preset_added", PropertyInfo(Variant::COLOR, "color"))); @@ -613,6 +642,8 @@ ColorPicker::ColorPicker() : raw_mode_enabled = false; deferred_mode_enabled = false; changing_color = false; + presets_enabled = true; + presets_visible = true; screen = NULL; HBoxContainer *hb_smpl = memnew(HBoxContainer); @@ -725,18 +756,19 @@ ColorPicker::ColorPicker() : set_pick_color(Color(1, 1, 1)); - add_child(memnew(HSeparator)); + preset_separator = memnew(HSeparator); + add_child(preset_separator); - HBoxContainer *bbc = memnew(HBoxContainer); - add_child(bbc); + preset_container = memnew(HBoxContainer); + add_child(preset_container); preset = memnew(TextureRect); - bbc->add_child(preset); + preset_container->add_child(preset); preset->connect("gui_input", this, "_preset_input"); preset->connect("draw", this, "_update_presets"); bt_add_preset = memnew(Button); - bbc->add_child(bt_add_preset); + preset_container->add_child(bt_add_preset); bt_add_preset->set_tooltip(TTR("Add current color as a preset.")); bt_add_preset->connect("pressed", this, "_add_preset_pressed"); } diff --git a/scene/gui/color_picker.h b/scene/gui/color_picker.h index b78844839a..b5ddf2d0c2 100644 --- a/scene/gui/color_picker.h +++ b/scene/gui/color_picker.h @@ -37,6 +37,7 @@ #include "scene/gui/label.h" #include "scene/gui/line_edit.h" #include "scene/gui/popup.h" +#include "scene/gui/separator.h" #include "scene/gui/slider.h" #include "scene/gui/spin_box.h" #include "scene/gui/texture_rect.h" @@ -52,6 +53,8 @@ private: Control *w_edit; TextureRect *sample; TextureRect *preset; + HBoxContainer *preset_container; + HSeparator *preset_separator; Button *bt_add_preset; List<Color> presets; ToolButton *btn_pick; @@ -70,6 +73,8 @@ private: bool deferred_mode_enabled; bool updating; bool changing_color; + bool presets_enabled; + bool presets_visible; float h, s, v; Color last_hsv; @@ -114,6 +119,12 @@ public: void set_deferred_mode(bool p_enabled); bool is_deferred_mode() const; + void set_presets_enabled(bool p_enabled); + bool are_presets_enabled() const; + + void set_presets_visible(bool p_visible); + bool are_presets_visible() const; + void set_focus_on_line_edit(); ColorPicker(); diff --git a/scene/gui/control.cpp b/scene/gui/control.cpp index c7cd2bb6d8..a38f97a90c 100644 --- a/scene/gui/control.cpp +++ b/scene/gui/control.cpp @@ -2634,6 +2634,12 @@ bool Control::is_visibility_clip_disabled() const { void Control::get_argument_options(const StringName &p_function, int p_idx, List<String> *r_options) const { +#ifdef TOOLS_ENABLED + const String quote_style = EDITOR_DEF("text_editor/completion/use_single_quotes", 0) ? "'" : "\""; +#else + const String quote_style = "\""; +#endif + Node::get_argument_options(p_function, p_idx, r_options); if (p_idx == 0) { @@ -2651,7 +2657,7 @@ void Control::get_argument_options(const StringName &p_function, int p_idx, List sn.sort_custom<StringName::AlphCompare>(); for (List<StringName>::Element *E = sn.front(); E; E = E->next()) { - r_options->push_back("\"" + E->get() + "\""); + r_options->push_back(quote_style + E->get() + quote_style); } } } diff --git a/scene/gui/item_list.cpp b/scene/gui/item_list.cpp index 026374ded1..f5e979e9e6 100644 --- a/scene/gui/item_list.cpp +++ b/scene/gui/item_list.cpp @@ -369,6 +369,7 @@ void ItemList::clear() { update(); shape_changed = true; defer_select_single = -1; + scroll_bar->set_value(0); } void ItemList::set_fixed_column_width(int p_size) { diff --git a/scene/gui/popup_menu.cpp b/scene/gui/popup_menu.cpp index 7c6b003dc3..8825891807 100644 --- a/scene/gui/popup_menu.cpp +++ b/scene/gui/popup_menu.cpp @@ -54,9 +54,11 @@ Size2 PopupMenu::get_minimum_size() const { Ref<Font> font = get_font("font"); float max_w = 0; + float icon_w = 0; int font_h = font->get_height(); - int check_w = MAX(get_icon("checked")->get_width(), get_icon("radio_checked")->get_width()); + int check_w = MAX(get_icon("checked")->get_width(), get_icon("radio_checked")->get_width()) + hseparation; int accel_max_w = 0; + bool has_check = false; for (int i = 0; i < items.size(); i++) { @@ -65,8 +67,7 @@ Size2 PopupMenu::get_minimum_size() const { Size2 icon_size = items[i].icon->get_size(); size.height = MAX(icon_size.height, font_h); - size.width += icon_size.width; - size.width += hseparation; + icon_w = MAX(icon_size.width + hseparation, icon_w); } else { size.height = font_h; @@ -74,10 +75,8 @@ Size2 PopupMenu::get_minimum_size() const { size.width += items[i].h_ofs; - if (items[i].checkable_type) { - - size.width += check_w + hseparation; - } + if (items[i].checkable_type) + has_check = true; String text = items[i].shortcut.is_valid() ? String(tr(items[i].shortcut->get_name())) : items[i].xl_text; size.width += font->get_string_size(text).width; @@ -91,13 +90,14 @@ Size2 PopupMenu::get_minimum_size() const { accel_max_w = MAX(accel_w, accel_max_w); } - if (items[i].submenu != "") { - + if (items[i].submenu != "") size.width += get_icon("submenu")->get_width(); - } + + if (has_check) + size.width += check_w; + max_w = MAX(max_w, size.width + icon_w); minsize.height += size.height; - max_w = MAX(max_w, size.width); } minsize.width += max_w + accel_max_w; @@ -147,10 +147,10 @@ int PopupMenu::_get_mouse_over(const Point2 &p_over) const { void PopupMenu::_activate_submenu(int over) { Node *n = get_node(items[over].submenu); - ERR_EXPLAIN("item subnode does not exist: " + items[over].submenu); + ERR_EXPLAIN("Item subnode does not exist: " + items[over].submenu); ERR_FAIL_COND(!n); Popup *pm = Object::cast_to<Popup>(n); - ERR_EXPLAIN("item subnode is not a Popup: " + items[over].submenu); + ERR_EXPLAIN("Item subnode is not a Popup: " + items[over].submenu); ERR_FAIL_COND(!pm); if (pm->is_visible_in_tree()) return; //already visible! @@ -443,15 +443,31 @@ void PopupMenu::_notification(int p_what) { Color font_color_hover = get_color("font_color_hover"); float font_h = font->get_height(); + // Add the check and the wider icon to the offset of all items. + float icon_ofs = 0.0; + bool has_check = false; + for (int i = 0; i < items.size(); i++) { + + if (!items[i].icon.is_null()) + icon_ofs = MAX(items[i].icon->get_size().height, icon_ofs); + + if (items[i].checkable_type) + has_check = true; + } + if (icon_ofs > 0.0) + icon_ofs += hseparation; + + float check_ofs = 0.0; + if (has_check) + check_ofs = MAX(get_icon("checked")->get_width(), get_icon("radio_checked")->get_width()) + hseparation; + for (int i = 0; i < items.size(); i++) { if (i > 0) ofs.y += vseparation; Point2 item_ofs = ofs; - float h; Size2 icon_size; - - Color icon_color(1, 1, 1, items[i].disabled ? 0.5 : 1); + float h; if (!items[i].icon.is_null()) { @@ -489,16 +505,15 @@ void PopupMenu::_notification(int p_what) { } } + Color icon_color(1, 1, 1, items[i].disabled ? 0.5 : 1); + if (items[i].checkable_type) { Texture *icon = (items[i].checked ? check[items[i].checkable_type - 1] : uncheck[items[i].checkable_type - 1]).ptr(); icon->draw(ci, item_ofs + Point2(0, Math::floor((h - icon->get_height()) / 2.0)), icon_color); - item_ofs.x += icon->get_width() + hseparation; } if (!items[i].icon.is_null()) { - items[i].icon->draw(ci, item_ofs + Point2(0, Math::floor((h - icon_size.height) / 2.0)), icon_color); - item_ofs.x += items[i].icon->get_width(); - item_ofs.x += hseparation; + items[i].icon->draw(ci, item_ofs + Size2(check_ofs, 0) + Point2(0, Math::floor((h - icon_size.height) / 2.0)), icon_color); } if (items[i].submenu != "") { @@ -514,6 +529,7 @@ void PopupMenu::_notification(int p_what) { } } else { + item_ofs.x += icon_ofs + check_ofs; font->draw(ci, item_ofs + Point2(0, Math::floor((h - font_h) / 2.0)), text, items[i].disabled ? font_color_disabled : (i == mouse_over ? font_color_hover : font_color)); } diff --git a/scene/gui/text_edit.cpp b/scene/gui/text_edit.cpp index e44e340ecf..3eb4e6d75a 100644 --- a/scene/gui/text_edit.cpp +++ b/scene/gui/text_edit.cpp @@ -825,6 +825,9 @@ void TextEdit::_notification(int p_what) { // get the highlighted words String highlighted_text = get_selection_text(); + // check if highlighted words contains only whitespaces (tabs or spaces) + bool only_whitespaces_highlighted = highlighted_text.strip_edges() == String(); + String line_num_padding = line_numbers_zero_padded ? "0" : " "; int cursor_wrap_index = get_cursor_wrap_index(); @@ -1123,7 +1126,7 @@ void TextEdit::_notification(int p_what) { VisualServer::get_singleton()->canvas_item_add_rect(ci, Rect2(Point2i(char_ofs + char_margin + char_w + ofs_x - 1, ofs_y), Size2i(1, get_row_height())), border_color); } - if (highlight_all_occurrences) { + if (highlight_all_occurrences && !only_whitespaces_highlighted) { if (highlighted_text_col != -1) { // if we are at the end check for new word on same line @@ -5783,19 +5786,29 @@ void TextEdit::_confirm_completion() { cursor_set_column(cursor.column - completion_base.length(), false); insert_text_at_cursor(completion_current); - // When inserted into the middle of an existing string, don't add an unnecessary quote + // When inserted into the middle of an existing string/method, don't add an unnecessary quote/bracket. String line = text[cursor.line]; CharType next_char = line[cursor.column]; CharType last_completion_char = completion_current[completion_current.length() - 1]; - if ((last_completion_char == '"' || last_completion_char == '\'') && - last_completion_char == next_char) { + if ((last_completion_char == '"' || last_completion_char == '\'') && last_completion_char == next_char) { _base_remove_text(cursor.line, cursor.column, cursor.line, cursor.column + 1); } - if (last_completion_char == '(' && auto_brace_completion_enabled) { - insert_text_at_cursor(")"); - cursor.column--; + if (last_completion_char == '(') { + + if (next_char == last_completion_char) { + _base_remove_text(cursor.line, cursor.column - 1, cursor.line, cursor.column); + } else if (auto_brace_completion_enabled) { + insert_text_at_cursor(")"); + cursor.column--; + } + } else if (last_completion_char == ')' && next_char == '(') { + + _base_remove_text(cursor.line, cursor.column - 2, cursor.line, cursor.column); + if (line[cursor.column + 1] != ')') { + cursor.column--; + } } end_complex_operation(); @@ -5839,6 +5852,7 @@ void TextEdit::_update_completion_candidates() { bool inquote = false; int first_quote = -1; + int restore_quotes = -1; int c = cofs - 1; while (c >= 0) { @@ -5846,6 +5860,11 @@ void TextEdit::_update_completion_candidates() { inquote = !inquote; if (first_quote == -1) first_quote = c; + restore_quotes = 0; + } else if (restore_quotes == 0 && l[c] == '$') { + restore_quotes = 1; + } else if (restore_quotes == 0 && !_is_whitespace(l[c])) { + restore_quotes = -1; } c--; } @@ -5913,6 +5932,11 @@ void TextEdit::_update_completion_candidates() { completion_strings.write[i] = completion_strings[i].unquote().quote("'"); } + if (inquote && restore_quotes == 1 && !completion_strings[i].is_quoted()) { + String quote = single_quote ? "'" : "\""; + completion_strings.write[i] = completion_strings[i].quote(quote); + } + if (completion_strings[i].begins_with(s)) { completion_options.push_back(completion_strings[i]); } else if (completion_strings[i].to_lower().begins_with(s.to_lower())) { @@ -5990,7 +6014,6 @@ void TextEdit::code_complete(const Vector<String> &p_strings, bool p_forced) { completion_current = ""; completion_index = 0; _update_completion_candidates(); - // } String TextEdit::get_word_at_pos(const Vector2 &p_pos) const { diff --git a/scene/gui/texture_button.cpp b/scene/gui/texture_button.cpp index 795b25cce0..b5f949aeb7 100644 --- a/scene/gui/texture_button.cpp +++ b/scene/gui/texture_button.cpp @@ -64,7 +64,7 @@ bool TextureButton::has_point(const Point2 &p_point) const { Rect2 rect = Rect2(); Size2 mask_size = click_mask->get_size(); - if (_position_rect.no_area()) { + if (_position_rect.has_no_area()) { rect.size = mask_size; } else if (_tile) { // if the stretch mode is tile we offset the point to keep it inside the mask size diff --git a/scene/gui/texture_rect.cpp b/scene/gui/texture_rect.cpp index 2195de9694..423794d8ba 100644 --- a/scene/gui/texture_rect.cpp +++ b/scene/gui/texture_rect.cpp @@ -96,7 +96,7 @@ void TextureRect::_notification(int p_what) { size.width *= hflip ? -1.0f : 1.0f; size.height *= vflip ? -1.0f : 1.0f; - if (region.no_area()) { + if (region.has_no_area()) { draw_texture_rect(texture, Rect2(offset, size), tile); } else { draw_texture_rect_region(texture, Rect2(offset, size), region); diff --git a/scene/main/node.cpp b/scene/main/node.cpp index 0465ffe442..e80de68e3b 100644 --- a/scene/main/node.cpp +++ b/scene/main/node.cpp @@ -39,6 +39,10 @@ #include "scene/scene_string_names.h" #include "viewport.h" +#ifdef TOOLS_ENABLED +#include "editor/editor_settings.h" +#endif + VARIANT_ENUM_CAST(Node::PauseMode); int Node::orphan_node_count = 0; @@ -2637,10 +2641,16 @@ NodePath Node::get_import_path() const { static void _add_nodes_to_options(const Node *p_base, const Node *p_node, List<String> *r_options) { +#ifdef TOOLS_ENABLED + const String quote_style = EDITOR_DEF("text_editor/completion/use_single_quotes", 0) ? "'" : "\""; +#else + const String quote_style = "\""; +#endif + if (p_node != p_base && !p_node->get_owner()) return; String n = p_base->get_path_to(p_node); - r_options->push_back("\"" + n + "\""); + r_options->push_back(quote_style + n + quote_style); for (int i = 0; i < p_node->get_child_count(); i++) { _add_nodes_to_options(p_base, p_node->get_child(i), r_options); } diff --git a/scene/main/scene_tree.cpp b/scene/main/scene_tree.cpp index 125e0a2882..b81364e2f0 100644 --- a/scene/main/scene_tree.cpp +++ b/scene/main/scene_tree.cpp @@ -369,8 +369,7 @@ void SceneTree::set_group_flags(uint32_t p_call_flags, const StringName &p_group } void SceneTree::call_group(const StringName &p_group, const StringName &p_function, VARIANT_ARG_DECLARE) { - - call_group_flags(0, p_group, VARIANT_ARG_PASS); + call_group_flags(0, p_group, p_function, VARIANT_ARG_PASS); } void SceneTree::notify_group(const StringName &p_group, int p_notification) { diff --git a/scene/resources/material.cpp b/scene/resources/material.cpp index 536eb11a27..766c7bbd9f 100644 --- a/scene/resources/material.cpp +++ b/scene/resources/material.cpp @@ -30,6 +30,10 @@ #include "material.h" +#ifdef TOOLS_ENABLED +#include "editor/editor_settings.h" +#endif + #include "scene/scene_string_names.h" void Material::set_next_pass(const Ref<Material> &p_pass) { @@ -236,6 +240,12 @@ void ShaderMaterial::_bind_methods() { void ShaderMaterial::get_argument_options(const StringName &p_function, int p_idx, List<String> *r_options) const { +#ifdef TOOLS_ENABLED + const String quote_style = EDITOR_DEF("text_editor/completion/use_single_quotes", 0) ? "'" : "\""; +#else + const String quote_style = "\""; +#endif + String f = p_function.operator String(); if ((f == "get_shader_param" || f == "set_shader_param") && p_idx == 0) { @@ -243,7 +253,7 @@ void ShaderMaterial::get_argument_options(const StringName &p_function, int p_id List<PropertyInfo> pl; shader->get_param_list(&pl); for (List<PropertyInfo>::Element *E = pl.front(); E; E = E->next()) { - r_options->push_back("\"" + E->get().name.replace_first("shader_param/", "") + "\""); + r_options->push_back(quote_style + E->get().name.replace_first("shader_param/", "") + quote_style); } } } diff --git a/scene/resources/tile_set.cpp b/scene/resources/tile_set.cpp index 21b2893502..5b5968c10f 100644 --- a/scene/resources/tile_set.cpp +++ b/scene/resources/tile_set.cpp @@ -600,6 +600,8 @@ Vector2 TileSet::autotile_get_subtile_for_bitmask(int p_id, uint16_t p_bitmask, } List<Vector2> coords; + List<uint32_t> priorities; + uint32_t priority_sum = 0; uint32_t mask; uint16_t mask_; uint16_t mask_ignore; @@ -613,16 +615,34 @@ Vector2 TileSet::autotile_get_subtile_for_bitmask(int p_id, uint16_t p_bitmask, mask_ignore = mask >> 16; if (((mask_ & (~mask_ignore)) == (p_bitmask & (~mask_ignore))) && (((~mask_) | mask_ignore) == ((~p_bitmask) | mask_ignore))) { - for (int i = 0; i < autotile_get_subtile_priority(p_id, E->key()); i++) { - coords.push_back(E->key()); - } + uint32_t priority = autotile_get_subtile_priority(p_id, E->key()); + priority_sum += priority; + priorities.push_back(priority); + coords.push_back(E->key()); } } if (coords.size() == 0) { return autotile_get_icon_coordinate(p_id); } else { - return coords[Math::rand() % coords.size()]; + uint32_t picked_value = Math::rand() % priority_sum; + uint32_t upper_bound; + uint32_t lower_bound = 0; + Vector2 result = coords.front()->get(); + List<Vector2>::Element *coords_E = coords.front(); + List<uint32_t>::Element *priorities_E = priorities.front(); + while (priorities_E) { + upper_bound = lower_bound + priorities_E->get(); + if (lower_bound <= picked_value && picked_value < upper_bound) { + result = coords_E->get(); + break; + } + lower_bound = upper_bound; + priorities_E = priorities_E->next(); + coords_E = coords_E->next(); + } + + return result; } } diff --git a/servers/arvr/arvr_interface.h b/servers/arvr/arvr_interface.h index 8459a82388..9ea59a3961 100644 --- a/servers/arvr/arvr_interface.h +++ b/servers/arvr/arvr_interface.h @@ -112,6 +112,7 @@ public: virtual void commit_for_eye(ARVRInterface::Eyes p_eye, RID p_render_target, const Rect2 &p_screen_rect) = 0; /* output the left or right eye */ virtual void process() = 0; + virtual void notification(int p_what) = 0; ARVRInterface(); ~ARVRInterface(); diff --git a/servers/physics/collision_object_sw.cpp b/servers/physics/collision_object_sw.cpp index 085ad4f9ea..b1c21290ab 100644 --- a/servers/physics/collision_object_sw.cpp +++ b/servers/physics/collision_object_sw.cpp @@ -32,13 +32,14 @@ #include "servers/physics/physics_server_sw.h" #include "space_sw.h" -void CollisionObjectSW::add_shape(ShapeSW *p_shape, const Transform &p_transform) { +void CollisionObjectSW::add_shape(ShapeSW *p_shape, const Transform &p_transform, bool p_disabled) { Shape s; s.shape = p_shape; s.xform = p_transform; s.xform_inv = s.xform.affine_inverse(); s.bpid = 0; //needs update + s.disabled = p_disabled; shapes.push_back(s); p_shape->add_owner(this); diff --git a/servers/physics/collision_object_sw.h b/servers/physics/collision_object_sw.h index 5c14d5aaf9..c2c3fe0e5a 100644 --- a/servers/physics/collision_object_sw.h +++ b/servers/physics/collision_object_sw.h @@ -118,7 +118,7 @@ public: void _shape_changed(); _FORCE_INLINE_ Type get_type() const { return type; } - void add_shape(ShapeSW *p_shape, const Transform &p_transform = Transform()); + void add_shape(ShapeSW *p_shape, const Transform &p_transform = Transform(), bool p_disabled = false); void set_shape(int p_index, ShapeSW *p_shape); void set_shape_transform(int p_index, const Transform &p_transform); _FORCE_INLINE_ int get_shape_count() const { return shapes.size(); } diff --git a/servers/physics/physics_server_sw.cpp b/servers/physics/physics_server_sw.cpp index 36d18e8901..66170f5a2e 100644 --- a/servers/physics/physics_server_sw.cpp +++ b/servers/physics/physics_server_sw.cpp @@ -283,7 +283,7 @@ PhysicsServer::AreaSpaceOverrideMode PhysicsServerSW::area_get_space_override_mo return area->get_space_override_mode(); } -void PhysicsServerSW::area_add_shape(RID p_area, RID p_shape, const Transform &p_transform) { +void PhysicsServerSW::area_add_shape(RID p_area, RID p_shape, const Transform &p_transform, bool p_disabled) { AreaSW *area = area_owner.get(p_area); ERR_FAIL_COND(!area); @@ -291,7 +291,7 @@ void PhysicsServerSW::area_add_shape(RID p_area, RID p_shape, const Transform &p ShapeSW *shape = shape_owner.get(p_shape); ERR_FAIL_COND(!shape); - area->add_shape(shape, p_transform); + area->add_shape(shape, p_transform, p_disabled); } void PhysicsServerSW::area_set_shape(RID p_area, int p_shape_idx, RID p_shape) { @@ -540,7 +540,7 @@ PhysicsServer::BodyMode PhysicsServerSW::body_get_mode(RID p_body) const { return body->get_mode(); }; -void PhysicsServerSW::body_add_shape(RID p_body, RID p_shape, const Transform &p_transform) { +void PhysicsServerSW::body_add_shape(RID p_body, RID p_shape, const Transform &p_transform, bool p_disabled) { BodySW *body = body_owner.get(p_body); ERR_FAIL_COND(!body); @@ -548,7 +548,7 @@ void PhysicsServerSW::body_add_shape(RID p_body, RID p_shape, const Transform &p ShapeSW *shape = shape_owner.get(p_shape); ERR_FAIL_COND(!shape); - body->add_shape(shape, p_transform); + body->add_shape(shape, p_transform, p_disabled); } void PhysicsServerSW::body_set_shape(RID p_body, int p_shape_idx, RID p_shape) { diff --git a/servers/physics/physics_server_sw.h b/servers/physics/physics_server_sw.h index 5d0ba3628e..dc1cbca94d 100644 --- a/servers/physics/physics_server_sw.h +++ b/servers/physics/physics_server_sw.h @@ -119,7 +119,7 @@ public: virtual void area_set_space(RID p_area, RID p_space); virtual RID area_get_space(RID p_area) const; - virtual void area_add_shape(RID p_area, RID p_shape, const Transform &p_transform = Transform()); + virtual void area_add_shape(RID p_area, RID p_shape, const Transform &p_transform = Transform(), bool p_disabled = false); virtual void area_set_shape(RID p_area, int p_shape_idx, RID p_shape); virtual void area_set_shape_transform(RID p_area, int p_shape_idx, const Transform &p_transform); @@ -163,7 +163,7 @@ public: virtual void body_set_mode(RID p_body, BodyMode p_mode); virtual BodyMode body_get_mode(RID p_body) const; - virtual void body_add_shape(RID p_body, RID p_shape, const Transform &p_transform = Transform()); + virtual void body_add_shape(RID p_body, RID p_shape, const Transform &p_transform = Transform(), bool p_disabled = false); virtual void body_set_shape(RID p_body, int p_shape_idx, RID p_shape); virtual void body_set_shape_transform(RID p_body, int p_shape_idx, const Transform &p_transform); diff --git a/servers/physics_2d/collision_object_2d_sw.cpp b/servers/physics_2d/collision_object_2d_sw.cpp index 4ec92497e7..445a2e0613 100644 --- a/servers/physics_2d/collision_object_2d_sw.cpp +++ b/servers/physics_2d/collision_object_2d_sw.cpp @@ -31,14 +31,14 @@ #include "collision_object_2d_sw.h" #include "space_2d_sw.h" -void CollisionObject2DSW::add_shape(Shape2DSW *p_shape, const Transform2D &p_transform) { +void CollisionObject2DSW::add_shape(Shape2DSW *p_shape, const Transform2D &p_transform, bool p_disabled) { Shape s; s.shape = p_shape; s.xform = p_transform; s.xform_inv = s.xform.affine_inverse(); s.bpid = 0; //needs update - s.disabled = false; + s.disabled = p_disabled; s.one_way_collision = false; s.one_way_collision_margin = 0; shapes.push_back(s); diff --git a/servers/physics_2d/collision_object_2d_sw.h b/servers/physics_2d/collision_object_2d_sw.h index d5e815ff45..fa18e61262 100644 --- a/servers/physics_2d/collision_object_2d_sw.h +++ b/servers/physics_2d/collision_object_2d_sw.h @@ -111,7 +111,7 @@ public: void _shape_changed(); _FORCE_INLINE_ Type get_type() const { return type; } - void add_shape(Shape2DSW *p_shape, const Transform2D &p_transform = Transform2D()); + void add_shape(Shape2DSW *p_shape, const Transform2D &p_transform = Transform2D(), bool p_disabled = false); void set_shape(int p_index, Shape2DSW *p_shape); void set_shape_transform(int p_index, const Transform2D &p_transform); void set_shape_metadata(int p_index, const Variant &p_metadata); diff --git a/servers/physics_2d/physics_2d_server_sw.cpp b/servers/physics_2d/physics_2d_server_sw.cpp index 283d20876d..1d02227052 100644 --- a/servers/physics_2d/physics_2d_server_sw.cpp +++ b/servers/physics_2d/physics_2d_server_sw.cpp @@ -378,7 +378,7 @@ Physics2DServer::AreaSpaceOverrideMode Physics2DServerSW::area_get_space_overrid return area->get_space_override_mode(); } -void Physics2DServerSW::area_add_shape(RID p_area, RID p_shape, const Transform2D &p_transform) { +void Physics2DServerSW::area_add_shape(RID p_area, RID p_shape, const Transform2D &p_transform, bool p_disabled) { Area2DSW *area = area_owner.get(p_area); ERR_FAIL_COND(!area); @@ -386,7 +386,7 @@ void Physics2DServerSW::area_add_shape(RID p_area, RID p_shape, const Transform2 Shape2DSW *shape = shape_owner.get(p_shape); ERR_FAIL_COND(!shape); - area->add_shape(shape, p_transform); + area->add_shape(shape, p_transform, p_disabled); } void Physics2DServerSW::area_set_shape(RID p_area, int p_shape_idx, RID p_shape) { @@ -643,7 +643,7 @@ Physics2DServer::BodyMode Physics2DServerSW::body_get_mode(RID p_body) const { return body->get_mode(); }; -void Physics2DServerSW::body_add_shape(RID p_body, RID p_shape, const Transform2D &p_transform) { +void Physics2DServerSW::body_add_shape(RID p_body, RID p_shape, const Transform2D &p_transform, bool p_disabled) { Body2DSW *body = body_owner.get(p_body); ERR_FAIL_COND(!body); @@ -651,7 +651,7 @@ void Physics2DServerSW::body_add_shape(RID p_body, RID p_shape, const Transform2 Shape2DSW *shape = shape_owner.get(p_shape); ERR_FAIL_COND(!shape); - body->add_shape(shape, p_transform); + body->add_shape(shape, p_transform, p_disabled); } void Physics2DServerSW::body_set_shape(RID p_body, int p_shape_idx, RID p_shape) { diff --git a/servers/physics_2d/physics_2d_server_sw.h b/servers/physics_2d/physics_2d_server_sw.h index 4beec41442..6fda74b877 100644 --- a/servers/physics_2d/physics_2d_server_sw.h +++ b/servers/physics_2d/physics_2d_server_sw.h @@ -131,7 +131,7 @@ public: virtual void area_set_space(RID p_area, RID p_space); virtual RID area_get_space(RID p_area) const; - virtual void area_add_shape(RID p_area, RID p_shape, const Transform2D &p_transform = Transform2D()); + virtual void area_add_shape(RID p_area, RID p_shape, const Transform2D &p_transform = Transform2D(), bool p_disabled = false); virtual void area_set_shape(RID p_area, int p_shape_idx, RID p_shape); virtual void area_set_shape_transform(RID p_area, int p_shape_idx, const Transform2D &p_transform); @@ -175,7 +175,7 @@ public: virtual void body_set_mode(RID p_body, BodyMode p_mode); virtual BodyMode body_get_mode(RID p_body) const; - virtual void body_add_shape(RID p_body, RID p_shape, const Transform2D &p_transform = Transform2D()); + virtual void body_add_shape(RID p_body, RID p_shape, const Transform2D &p_transform = Transform2D(), bool p_disabled = false); virtual void body_set_shape(RID p_body, int p_shape_idx, RID p_shape); virtual void body_set_shape_transform(RID p_body, int p_shape_idx, const Transform2D &p_transform); virtual void body_set_shape_metadata(RID p_body, int p_shape_idx, const Variant &p_metadata); diff --git a/servers/physics_2d/physics_2d_server_wrap_mt.h b/servers/physics_2d/physics_2d_server_wrap_mt.h index 5b9a102a1b..b61e1faad2 100644 --- a/servers/physics_2d/physics_2d_server_wrap_mt.h +++ b/servers/physics_2d/physics_2d_server_wrap_mt.h @@ -140,7 +140,7 @@ public: FUNC2(area_set_space_override_mode, RID, AreaSpaceOverrideMode); FUNC1RC(AreaSpaceOverrideMode, area_get_space_override_mode, RID); - FUNC3(area_add_shape, RID, RID, const Transform2D &); + FUNC4(area_add_shape, RID, RID, const Transform2D &, bool); FUNC3(area_set_shape, RID, int, RID); FUNC3(area_set_shape_transform, RID, int, const Transform2D &); FUNC3(area_set_shape_disabled, RID, int, bool); @@ -183,7 +183,7 @@ public: FUNC2(body_set_mode, RID, BodyMode); FUNC1RC(BodyMode, body_get_mode, RID); - FUNC3(body_add_shape, RID, RID, const Transform2D &); + FUNC4(body_add_shape, RID, RID, const Transform2D &, bool); FUNC3(body_set_shape, RID, int, RID); FUNC3(body_set_shape_transform, RID, int, const Transform2D &); FUNC3(body_set_shape_metadata, RID, int, const Variant &); diff --git a/servers/physics_2d_server.cpp b/servers/physics_2d_server.cpp index 3a05791f17..dadadf68fd 100644 --- a/servers/physics_2d_server.cpp +++ b/servers/physics_2d_server.cpp @@ -567,10 +567,10 @@ void Physics2DServer::_bind_methods() { ClassDB::bind_method(D_METHOD("area_set_space_override_mode", "area", "mode"), &Physics2DServer::area_set_space_override_mode); ClassDB::bind_method(D_METHOD("area_get_space_override_mode", "area"), &Physics2DServer::area_get_space_override_mode); - ClassDB::bind_method(D_METHOD("area_add_shape", "area", "shape", "transform"), &Physics2DServer::area_add_shape, DEFVAL(Transform2D())); + ClassDB::bind_method(D_METHOD("area_add_shape", "area", "shape", "transform", "disabled"), &Physics2DServer::area_add_shape, DEFVAL(Transform2D()), DEFVAL(false)); ClassDB::bind_method(D_METHOD("area_set_shape", "area", "shape_idx", "shape"), &Physics2DServer::area_set_shape); ClassDB::bind_method(D_METHOD("area_set_shape_transform", "area", "shape_idx", "transform"), &Physics2DServer::area_set_shape_transform); - ClassDB::bind_method(D_METHOD("area_set_shape_disabled", "area", "shape_idx", "disable"), &Physics2DServer::area_set_shape_disabled); + ClassDB::bind_method(D_METHOD("area_set_shape_disabled", "area", "shape_idx", "disabled"), &Physics2DServer::area_set_shape_disabled); ClassDB::bind_method(D_METHOD("area_get_shape_count", "area"), &Physics2DServer::area_get_shape_count); ClassDB::bind_method(D_METHOD("area_get_shape", "area", "shape_idx"), &Physics2DServer::area_get_shape); @@ -606,7 +606,7 @@ void Physics2DServer::_bind_methods() { ClassDB::bind_method(D_METHOD("body_set_mode", "body", "mode"), &Physics2DServer::body_set_mode); ClassDB::bind_method(D_METHOD("body_get_mode", "body"), &Physics2DServer::body_get_mode); - ClassDB::bind_method(D_METHOD("body_add_shape", "body", "shape", "transform"), &Physics2DServer::body_add_shape, DEFVAL(Transform2D())); + ClassDB::bind_method(D_METHOD("body_add_shape", "body", "shape", "transform", "disabled"), &Physics2DServer::body_add_shape, DEFVAL(Transform2D()), DEFVAL(false)); ClassDB::bind_method(D_METHOD("body_set_shape", "body", "shape_idx", "shape"), &Physics2DServer::body_set_shape); ClassDB::bind_method(D_METHOD("body_set_shape_transform", "body", "shape_idx", "transform"), &Physics2DServer::body_set_shape_transform); ClassDB::bind_method(D_METHOD("body_set_shape_metadata", "body", "shape_idx", "metadata"), &Physics2DServer::body_set_shape_metadata); @@ -619,7 +619,7 @@ void Physics2DServer::_bind_methods() { ClassDB::bind_method(D_METHOD("body_remove_shape", "body", "shape_idx"), &Physics2DServer::body_remove_shape); ClassDB::bind_method(D_METHOD("body_clear_shapes", "body"), &Physics2DServer::body_clear_shapes); - ClassDB::bind_method(D_METHOD("body_set_shape_disabled", "body", "shape_idx", "disable"), &Physics2DServer::body_set_shape_disabled); + ClassDB::bind_method(D_METHOD("body_set_shape_disabled", "body", "shape_idx", "disabled"), &Physics2DServer::body_set_shape_disabled); ClassDB::bind_method(D_METHOD("body_set_shape_as_one_way_collision", "body", "shape_idx", "enable", "margin"), &Physics2DServer::body_set_shape_as_one_way_collision); ClassDB::bind_method(D_METHOD("body_attach_object_instance_id", "body", "id"), &Physics2DServer::body_attach_object_instance_id); diff --git a/servers/physics_2d_server.h b/servers/physics_2d_server.h index 0ba8a6605d..a9b95fbdf8 100644 --- a/servers/physics_2d_server.h +++ b/servers/physics_2d_server.h @@ -335,7 +335,7 @@ public: virtual void area_set_space_override_mode(RID p_area, AreaSpaceOverrideMode p_mode) = 0; virtual AreaSpaceOverrideMode area_get_space_override_mode(RID p_area) const = 0; - virtual void area_add_shape(RID p_area, RID p_shape, const Transform2D &p_transform = Transform2D()) = 0; + virtual void area_add_shape(RID p_area, RID p_shape, const Transform2D &p_transform = Transform2D(), bool p_disabled = false) = 0; virtual void area_set_shape(RID p_area, int p_shape_idx, RID p_shape) = 0; virtual void area_set_shape_transform(RID p_area, int p_shape_idx, const Transform2D &p_transform) = 0; @@ -388,7 +388,7 @@ public: virtual void body_set_mode(RID p_body, BodyMode p_mode) = 0; virtual BodyMode body_get_mode(RID p_body) const = 0; - virtual void body_add_shape(RID p_body, RID p_shape, const Transform2D &p_transform = Transform2D()) = 0; + virtual void body_add_shape(RID p_body, RID p_shape, const Transform2D &p_transform = Transform2D(), bool p_disabled = false) = 0; virtual void body_set_shape(RID p_body, int p_shape_idx, RID p_shape) = 0; virtual void body_set_shape_transform(RID p_body, int p_shape_idx, const Transform2D &p_transform) = 0; virtual void body_set_shape_metadata(RID p_body, int p_shape_idx, const Variant &p_metadata) = 0; diff --git a/servers/physics_server.cpp b/servers/physics_server.cpp index 0629af663e..fe8c644f0b 100644 --- a/servers/physics_server.cpp +++ b/servers/physics_server.cpp @@ -427,9 +427,10 @@ void PhysicsServer::_bind_methods() { ClassDB::bind_method(D_METHOD("area_set_space_override_mode", "area", "mode"), &PhysicsServer::area_set_space_override_mode); ClassDB::bind_method(D_METHOD("area_get_space_override_mode", "area"), &PhysicsServer::area_get_space_override_mode); - ClassDB::bind_method(D_METHOD("area_add_shape", "area", "shape", "transform"), &PhysicsServer::area_add_shape, DEFVAL(Transform())); + ClassDB::bind_method(D_METHOD("area_add_shape", "area", "shape", "transform", "disabled"), &PhysicsServer::area_add_shape, DEFVAL(Transform()), DEFVAL(false)); ClassDB::bind_method(D_METHOD("area_set_shape", "area", "shape_idx", "shape"), &PhysicsServer::area_set_shape); ClassDB::bind_method(D_METHOD("area_set_shape_transform", "area", "shape_idx", "transform"), &PhysicsServer::area_set_shape_transform); + ClassDB::bind_method(D_METHOD("area_set_shape_disabled", "area", "shape_idx", "disabled"), &PhysicsServer::area_set_shape_disabled); ClassDB::bind_method(D_METHOD("area_get_shape_count", "area"), &PhysicsServer::area_get_shape_count); ClassDB::bind_method(D_METHOD("area_get_shape", "area", "shape_idx"), &PhysicsServer::area_get_shape); @@ -471,9 +472,10 @@ void PhysicsServer::_bind_methods() { ClassDB::bind_method(D_METHOD("body_set_collision_mask", "body", "mask"), &PhysicsServer::body_set_collision_mask); ClassDB::bind_method(D_METHOD("body_get_collision_mask", "body"), &PhysicsServer::body_get_collision_mask); - ClassDB::bind_method(D_METHOD("body_add_shape", "body", "shape", "transform"), &PhysicsServer::body_add_shape, DEFVAL(Transform())); + ClassDB::bind_method(D_METHOD("body_add_shape", "body", "shape", "transform", "disabled"), &PhysicsServer::body_add_shape, DEFVAL(Transform()), DEFVAL(false)); ClassDB::bind_method(D_METHOD("body_set_shape", "body", "shape_idx", "shape"), &PhysicsServer::body_set_shape); ClassDB::bind_method(D_METHOD("body_set_shape_transform", "body", "shape_idx", "transform"), &PhysicsServer::body_set_shape_transform); + ClassDB::bind_method(D_METHOD("body_set_shape_disabled", "body", "shape_idx", "disabled"), &PhysicsServer::body_set_shape_disabled); ClassDB::bind_method(D_METHOD("body_get_shape_count", "body"), &PhysicsServer::body_get_shape_count); ClassDB::bind_method(D_METHOD("body_get_shape", "body", "shape_idx"), &PhysicsServer::body_get_shape); diff --git a/servers/physics_server.h b/servers/physics_server.h index 9895ef2455..bc196c11fb 100644 --- a/servers/physics_server.h +++ b/servers/physics_server.h @@ -320,7 +320,7 @@ public: virtual void area_set_space_override_mode(RID p_area, AreaSpaceOverrideMode p_mode) = 0; virtual AreaSpaceOverrideMode area_get_space_override_mode(RID p_area) const = 0; - virtual void area_add_shape(RID p_area, RID p_shape, const Transform &p_transform = Transform()) = 0; + virtual void area_add_shape(RID p_area, RID p_shape, const Transform &p_transform = Transform(), bool p_disabled = false) = 0; virtual void area_set_shape(RID p_area, int p_shape_idx, RID p_shape) = 0; virtual void area_set_shape_transform(RID p_area, int p_shape_idx, const Transform &p_transform) = 0; @@ -372,7 +372,7 @@ public: virtual void body_set_mode(RID p_body, BodyMode p_mode) = 0; virtual BodyMode body_get_mode(RID p_body) const = 0; - virtual void body_add_shape(RID p_body, RID p_shape, const Transform &p_transform = Transform()) = 0; + virtual void body_add_shape(RID p_body, RID p_shape, const Transform &p_transform = Transform(), bool p_disabled = false) = 0; virtual void body_set_shape(RID p_body, int p_shape_idx, RID p_shape) = 0; virtual void body_set_shape_transform(RID p_body, int p_shape_idx, const Transform &p_transform) = 0; diff --git a/thirdparty/README.md b/thirdparty/README.md index e2c2334c0f..b4a9b83331 100644 --- a/thirdparty/README.md +++ b/thirdparty/README.md @@ -185,18 +185,21 @@ Files extracted from upstream source: ## libsimplewebm - Upstream: https://github.com/zaps166/libsimplewebm -- Version: git (05cfdc2, 2016) -- License: MIT, BSD-3-Clause +- Version: git (fe57fd3, 2019) +- License: MIT (main), BSD-3-Clause (libwebm) + +This contains libwebm, but the version in use is updated from the one used by libsimplewebm, +and may have *unmarked* alterations from that. Files extracted from upstream source: -TODO. +- all the .cpp, .hpp files in the main folder except `example.cpp` +- LICENSE Important: Some files have Godot-made changes. They are marked with `// -- GODOT start --` and `// -- GODOT end --` comments. - ## libtheora - Upstream: https://www.theora.org diff --git a/thirdparty/libsimplewebm/OpusVorbisDecoder.cpp b/thirdparty/libsimplewebm/OpusVorbisDecoder.cpp index c9e71eb733..b5824b17be 100644 --- a/thirdparty/libsimplewebm/OpusVorbisDecoder.cpp +++ b/thirdparty/libsimplewebm/OpusVorbisDecoder.cpp @@ -122,6 +122,7 @@ bool OpusVorbisDecoder::getPCMS16(WebMFrame &frame, short *buffer, int &numOutSa return false; } +// -- GODOT begin -- bool OpusVorbisDecoder::getPCMF(WebMFrame &frame, float *buffer, int &numOutSamples) { if (m_vorbis) { m_vorbis->op.packet = frame.buffer; @@ -158,6 +159,7 @@ bool OpusVorbisDecoder::getPCMF(WebMFrame &frame, float *buffer, int &numOutSamp } return false; } +// -- GODOT end -- bool OpusVorbisDecoder::openVorbis(const WebMDemuxer &demuxer) { diff --git a/thirdparty/libsimplewebm/OpusVorbisDecoder.hpp b/thirdparty/libsimplewebm/OpusVorbisDecoder.hpp index b7619d6a25..f285b3fbd6 100644 --- a/thirdparty/libsimplewebm/OpusVorbisDecoder.hpp +++ b/thirdparty/libsimplewebm/OpusVorbisDecoder.hpp @@ -44,8 +44,10 @@ public: { return m_numSamples; } - bool getPCMF(WebMFrame &frame, float *buffer, int &numOutSamples); bool getPCMS16(WebMFrame &frame, short *buffer, int &numOutSamples); +// -- GODOT begin -- + bool getPCMF(WebMFrame &frame, float *buffer, int &numOutSamples); +// -- GODOT end -- private: bool openVorbis(const WebMDemuxer &demuxer); diff --git a/thirdparty/libsimplewebm/VPXDecoder.cpp b/thirdparty/libsimplewebm/VPXDecoder.cpp index 3f77b8f5cd..e2606f83ba 100644 --- a/thirdparty/libsimplewebm/VPXDecoder.cpp +++ b/thirdparty/libsimplewebm/VPXDecoder.cpp @@ -33,7 +33,8 @@ VPXDecoder::VPXDecoder(const WebMDemuxer &demuxer, unsigned threads) : m_ctx(NULL), m_iter(NULL), - m_delay(0) + m_delay(0), + m_last_space(VPX_CS_UNKNOWN) { if (threads > 8) threads = 8; @@ -86,6 +87,11 @@ VPXDecoder::IMAGE_ERROR VPXDecoder::getImage(Image &image) IMAGE_ERROR err = NO_FRAME; if (vpx_image_t *img = vpx_codec_get_frame(m_ctx, &m_iter)) { + // It seems to be a common problem that UNKNOWN comes up a lot, yet FFMPEG is somehow getting accurate colour-space information. + // After checking FFMPEG code, *they're* getting colour-space information, so I'm assuming something like this is going on. + // It appears to work, at least. + if (img->cs != VPX_CS_UNKNOWN) + m_last_space = img->cs; if ((img->fmt & VPX_IMG_FMT_PLANAR) && !(img->fmt & (VPX_IMG_FMT_HAS_ALPHA | VPX_IMG_FMT_HIGHBITDEPTH))) { if (img->stride[0] && img->stride[1] && img->stride[2]) @@ -95,6 +101,7 @@ VPXDecoder::IMAGE_ERROR VPXDecoder::getImage(Image &image) image.w = img->d_w; image.h = img->d_h; + image.cs = m_last_space; image.chromaShiftW = img->x_chroma_shift; image.chromaShiftH = img->y_chroma_shift; @@ -119,7 +126,9 @@ VPXDecoder::IMAGE_ERROR VPXDecoder::getImage(Image &image) /**/ +// -- GODOT begin -- #if 0 +// -- GODOT end -- static inline int ceilRshift(int val, int shift) { @@ -139,4 +148,7 @@ int VPXDecoder::Image::getHeight(int plane) const return ceilRshift(h, chromaShiftH); } +// -- GODOT begin -- #endif +// -- GODOT end -- + diff --git a/thirdparty/libsimplewebm/VPXDecoder.hpp b/thirdparty/libsimplewebm/VPXDecoder.hpp index 6108395871..5071b069cb 100644 --- a/thirdparty/libsimplewebm/VPXDecoder.hpp +++ b/thirdparty/libsimplewebm/VPXDecoder.hpp @@ -37,12 +37,17 @@ public: class Image { public: +// -- GODOT begin -- #if 0 +// -- GODOT end -- int getWidth(int plane) const; int getHeight(int plane) const; +// -- GODOT begin -- #endif +// -- GODOT end -- int w, h; + int cs; int chromaShiftW, chromaShiftH; unsigned char *planes[3]; int linesize[3]; @@ -75,6 +80,7 @@ private: vpx_codec_ctx *m_ctx; const void *m_iter; int m_delay; + int m_last_space; }; #endif // VPXDECODER_HPP diff --git a/thirdparty/misc/yuv2rgb.h b/thirdparty/misc/yuv2rgb.h index 3ec8388246..d8f7fd6de2 100644 --- a/thirdparty/misc/yuv2rgb.h +++ b/thirdparty/misc/yuv2rgb.h @@ -24,6 +24,14 @@ does not infringe any patents that apply in your area before you ship it. */ +/* + * Please note that this version has been modified for various reasons: + * 1. Using the Godot core typedefs + * 2. At some point or another the code relied on the byte order of a uint32_t, this has been fixed + * 3. Output has been reordered to struct { uint8_t r, g, b, a; } precisely in accordance with the function names + * 4. Removing unused 'dither' parameter + */ + #ifndef YUV2RGB_H #define YUV2RGB_H @@ -803,6 +811,8 @@ static const uint32_t tables[256*3] = { 0xE6365800U }; +/* -- Common -- */ + #define FLAGS 0x40080100 #define READUV(U,V) (tables[256 + (U)] + tables[512 + (V)]) #define READY(Y) tables[Y] @@ -820,12 +830,14 @@ do { \ #define STORE(Y,DSTPTR) \ do { \ - *(DSTPTR)++ = (Y); \ - *(DSTPTR)++ = (Y)>>22; \ *(DSTPTR)++ = (Y)>>11; \ - *(DSTPTR)++ = 255; \ + *(DSTPTR)++ = (Y)>>22; \ + *(DSTPTR)++ = (Y); \ + *(DSTPTR)++ = 255; \ } while (0 == 1) +/* -- End Common -- */ + static void yuv422_2_rgb8888(uint8_t *dst_ptr, const uint8_t *y_ptr, const uint8_t *u_ptr, @@ -834,8 +846,7 @@ static void yuv422_2_rgb8888(uint8_t *dst_ptr, int32_t height, int32_t y_span, int32_t uv_span, - int32_t dst_span, - int32_t dither) + int32_t dst_span) { height -= 1; while (height > 0) @@ -909,35 +920,7 @@ static void yuv422_2_rgb8888(uint8_t *dst_ptr, } } - -#undef FLAGS -#undef READUV -#undef READY -#undef FIXUP -#undef STORE - - -#define FLAGS 0x40080100 -#define READUV(U,V) (tables[256 + (U)] + tables[512 + (V)]) -#define READY(Y) tables[Y] -#define FIXUP(Y) \ -do { \ - int tmp = (Y) & FLAGS; \ - if (tmp != 0) \ - { \ - tmp -= tmp>>8; \ - (Y) |= tmp; \ - tmp = FLAGS & ~(Y>>1); \ - (Y) += tmp>>8; \ - } \ -} while (0 == 1) - -#define STORE(Y,DSTPTR) \ -do { \ - (DSTPTR) = 0xFF000000 | (Y & 0xFF) | (0xFF00 & (Y>>14)) | (0xFF0000 & (Y<<5));\ -} while (0 == 1) - -static void yuv420_2_rgb8888(uint8_t *dst_ptr_, +static void yuv420_2_rgb8888(uint8_t *dst_ptr, const uint8_t *y_ptr, const uint8_t *u_ptr, const uint8_t *v_ptr, @@ -945,12 +928,9 @@ static void yuv420_2_rgb8888(uint8_t *dst_ptr_, int32_t height, int32_t y_span, int32_t uv_span, - int32_t dst_span, - int32_t dither) + int32_t dst_span) { - uint32_t *dst_ptr = (uint32_t *)(void *)dst_ptr_; - dst_span >>= 2; - + /* The 'dst_ptr as uint32_t' thing is not endianness-aware, so that's been removed. */ height -= 1; while (height > 0) { @@ -960,36 +940,38 @@ static void yuv420_2_rgb8888(uint8_t *dst_ptr_, { /* Do 2 column pairs */ uint32_t uv, y0, y1; + uint8_t * dst_ptr_1span = dst_ptr + dst_span; uv = READUV(*u_ptr++,*v_ptr++); y1 = uv + READY(y_ptr[y_span]); y0 = uv + READY(*y_ptr++); FIXUP(y1); FIXUP(y0); - STORE(y1, dst_ptr[dst_span]); - STORE(y0, *dst_ptr++); + STORE(y1, dst_ptr_1span); + STORE(y0, dst_ptr); y1 = uv + READY(y_ptr[y_span]); y0 = uv + READY(*y_ptr++); FIXUP(y1); FIXUP(y0); - STORE(y1, dst_ptr[dst_span]); - STORE(y0, *dst_ptr++); + STORE(y1, dst_ptr_1span); + STORE(y0, dst_ptr); height += (2<<16); } if ((height>>16) == 0) { /* Trailing column pair */ uint32_t uv, y0, y1; + uint8_t * dst_ptr_1span = dst_ptr + dst_span; uv = READUV(*u_ptr,*v_ptr); y1 = uv + READY(y_ptr[y_span]); y0 = uv + READY(*y_ptr++); FIXUP(y1); FIXUP(y0); - STORE(y0, dst_ptr[dst_span]); - STORE(y1, *dst_ptr++); + STORE(y0, dst_ptr_1span); + STORE(y1, dst_ptr); } - dst_ptr += dst_span*2-width; + dst_ptr += (dst_span * 2) - (width * 4); y_ptr += y_span*2-width; u_ptr += uv_span-(width>>1); v_ptr += uv_span-(width>>1); @@ -1011,8 +993,8 @@ static void yuv420_2_rgb8888(uint8_t *dst_ptr_, y0 = uv + READY(*y_ptr++); FIXUP(y1); FIXUP(y0); - STORE(y1, *dst_ptr++); - STORE(y0, *dst_ptr++); + STORE(y1, dst_ptr); + STORE(y0, dst_ptr); height += (2<<16); } if ((height>>16) == 0) @@ -1023,42 +1005,11 @@ static void yuv420_2_rgb8888(uint8_t *dst_ptr_, uv = READUV(*u_ptr++,*v_ptr++); y0 = uv + READY(*y_ptr++); FIXUP(y0); - STORE(y0, *dst_ptr++); + STORE(y0, dst_ptr); } } } - - -#undef FLAGS -#undef READUV -#undef READY -#undef FIXUP -#undef STORE - -#define FLAGS 0x40080100 -#define READUV(U,V) (tables[256 + (U)] + tables[512 + (V)]) -#define READY(Y) tables[Y] -#define FIXUP(Y) \ -do { \ - int tmp = (Y) & FLAGS; \ - if (tmp != 0) \ - { \ - tmp -= tmp>>8; \ - (Y) |= tmp; \ - tmp = FLAGS & ~(Y>>1); \ - (Y) += tmp>>8; \ - } \ -} while (0 == 1) - -#define STORE(Y,DSTPTR) \ -do { \ - *(DSTPTR)++ = (Y); \ - *(DSTPTR)++ = (Y)>>22; \ - *(DSTPTR)++ = (Y)>>11; \ - *(DSTPTR)++ = 255; \ -} while (0 == 1) - static void yuv444_2_rgb8888(uint8_t *dst_ptr, const uint8_t *y_ptr, const uint8_t *u_ptr, @@ -1067,8 +1018,7 @@ static void yuv444_2_rgb8888(uint8_t *dst_ptr, int32_t height, int32_t y_span, int32_t uv_span, - int32_t dst_span, - int32_t dither) + int32_t dst_span) { height -= 1; while (height > 0) @@ -1143,4 +1093,11 @@ static void yuv444_2_rgb8888(uint8_t *dst_ptr, height -= 1; } } + +#undef FLAGS +#undef READUV +#undef READY +#undef FIXUP +#undef STORE + #endif // YUV2RGB_H |