diff options
25 files changed, 168 insertions, 68 deletions
diff --git a/core/pool_vector.h b/core/pool_vector.h index 102a620f17..338de966f6 100644 --- a/core/pool_vector.h +++ b/core/pool_vector.h @@ -411,8 +411,8 @@ public: p_to = size() + p_to; } - CRASH_BAD_INDEX(p_from, size()); - CRASH_BAD_INDEX(p_to, size()); + ERR_FAIL_INDEX_V(p_from, size(), PoolVector<T>()); + ERR_FAIL_INDEX_V(p_to, size(), PoolVector<T>()); PoolVector<T> slice; int span = 1 + p_to - p_from; @@ -511,6 +511,8 @@ const T PoolVector<T>::operator[](int p_index) const { template <class T> Error PoolVector<T>::resize(int p_size) { + ERR_FAIL_COND_V(p_size < 0, ERR_INVALID_PARAMETER); + if (alloc == NULL) { if (p_size == 0) diff --git a/doc/classes/Area.xml b/doc/classes/Area.xml index c39c570be9..d40376414f 100644 --- a/doc/classes/Area.xml +++ b/doc/classes/Area.xml @@ -56,7 +56,8 @@ <argument index="0" name="body" type="Node"> </argument> <description> - If [code]true[/code], the given body overlaps the Area. Note that the result of this test is not immediate after moving objects. For performance, list of overlaps is updated once per frame and before the physics step. Consider using signals instead. + If [code]true[/code], the given physics body overlaps the Area. Note that the result of this test is not immediate after moving objects. For performance, list of overlaps is updated once per frame and before the physics step. Consider using signals instead. + The [code]body[/code] argument can either be a [PhysicsBody] or a [GridMap] instance (while GridMaps are not physics body themselves, they register their tiles with collision shapes as a virtual physics body). </description> </method> <method name="set_collision_layer_bit"> @@ -183,14 +184,16 @@ <argument index="0" name="body" type="Node"> </argument> <description> - Emitted when a [PhysicsBody] object enters. + Emitted when a physics body enters. + The [code]body[/code] argument can either be a [PhysicsBody] or a [GridMap] instance (while GridMaps are not physics body themselves, they register their tiles with collision shapes as a virtual physics body). </description> </signal> <signal name="body_exited"> <argument index="0" name="body" type="Node"> </argument> <description> - Emitted when a [PhysicsBody] object exits. + Emitted when a physics body exits. + The [code]body[/code] argument can either be a [PhysicsBody] or a [GridMap] instance (while GridMaps are not physics body themselves, they register their tiles with collision shapes as a virtual physics body). </description> </signal> <signal name="body_shape_entered"> @@ -203,7 +206,8 @@ <argument index="3" name="area_shape" type="int"> </argument> <description> - Emitted when a [PhysicsBody] object enters, reporting which shapes overlapped. + Emitted when a physics body enters, reporting which shapes overlapped. + The [code]body[/code] argument can either be a [PhysicsBody] or a [GridMap] instance (while GridMaps are not physics body themselves, they register their tiles with collision shapes as a virtual physics body). </description> </signal> <signal name="body_shape_exited"> @@ -216,7 +220,8 @@ <argument index="3" name="area_shape" type="int"> </argument> <description> - Emitted when a [PhysicsBody] object exits, reporting which shapes were overlapping. + Emitted when a physics body exits, reporting which shapes were overlapping. + The [code]body[/code] argument can either be a [PhysicsBody] or a [GridMap] instance (while GridMaps are not physics body themselves, they register their tiles with collision shapes as a virtual physics body). </description> </signal> </signals> diff --git a/doc/classes/Area2D.xml b/doc/classes/Area2D.xml index 8d28ddc889..4771a976b5 100644 --- a/doc/classes/Area2D.xml +++ b/doc/classes/Area2D.xml @@ -56,7 +56,8 @@ <argument index="0" name="body" type="Node"> </argument> <description> - If [code]true[/code], the given body overlaps the Area2D. Note that the result of this test is not immediate after moving objects. For performance, list of overlaps is updated once per frame and before the physics step. Consider using signals instead. + If [code]true[/code], the given physics body overlaps the Area2D. Note that the result of this test is not immediate after moving objects. For performance, list of overlaps is updated once per frame and before the physics step. Consider using signals instead. + The [code]body[/code] argument can either be a [PhysicsBody2D] or a [TileMap] instance (while TileMaps are not physics body themselves, they register their tiles with collision shapes as a virtual physics body). </description> </method> <method name="set_collision_layer_bit"> @@ -168,43 +169,47 @@ </description> </signal> <signal name="body_entered"> - <argument index="0" name="body" type="PhysicsBody2D"> + <argument index="0" name="body" type="Node"> </argument> <description> - Emitted when a [PhysicsBody2D] object enters. + Emitted when a physics body enters. + The [code]body[/code] argument can either be a [PhysicsBody2D] or a [TileMap] instance (while TileMaps are not physics body themselves, they register their tiles with collision shapes as a virtual physics body). </description> </signal> <signal name="body_exited"> - <argument index="0" name="body" type="PhysicsBody2D"> + <argument index="0" name="body" type="Node"> </argument> <description> - Emitted when a [PhysicsBody2D] object exits. + Emitted when a physics body exits. + The [code]body[/code] argument can either be a [PhysicsBody2D] or a [TileMap] instance (while TileMaps are not physics body themselves, they register their tiles with collision shapes as a virtual physics body). </description> </signal> <signal name="body_shape_entered"> <argument index="0" name="body_id" type="int"> </argument> - <argument index="1" name="body" type="PhysicsBody2D"> + <argument index="1" name="body" type="Node"> </argument> <argument index="2" name="body_shape" type="int"> </argument> <argument index="3" name="area_shape" type="int"> </argument> <description> - Emitted when a [PhysicsBody2D] object enters, reporting which shapes overlapped. + Emitted when a physics body enters, reporting which shapes overlapped. + The [code]body[/code] argument can either be a [PhysicsBody2D] or a [TileMap] instance (while TileMaps are not physics body themselves, they register their tiles with collision shapes as a virtual physics body). </description> </signal> <signal name="body_shape_exited"> <argument index="0" name="body_id" type="int"> </argument> - <argument index="1" name="body" type="PhysicsBody2D"> + <argument index="1" name="body" type="Node"> </argument> <argument index="2" name="body_shape" type="int"> </argument> <argument index="3" name="area_shape" type="int"> </argument> <description> - Emitted when a [PhysicsBody2D] object exits, reporting which shapes were overlapping. + Emitted when a physics body exits, reporting which shapes were overlapping. + The [code]body[/code] argument can either be a [PhysicsBody2D] or a [TileMap] instance (while TileMaps are not physics body themselves, they register their tiles with collision shapes as a virtual physics body). </description> </signal> </signals> diff --git a/doc/classes/MarginContainer.xml b/doc/classes/MarginContainer.xml index 0993ed88ca..3ea3204e56 100644 --- a/doc/classes/MarginContainer.xml +++ b/doc/classes/MarginContainer.xml @@ -4,7 +4,15 @@ Simple margin container. </brief_description> <description> - Simple margin container. Adds a left margin to anything contained. + Adds a top, left, bottom, and right margin to all [Control] nodes that are direct children of the container. To control the [MarginContainer]'s margin, use the [code]margin_*[/code] theme properties listed below. + [b]Note:[/b] Be careful, [Control] margin values are different than the constant margin values. If you want to change the custom margin values of the [MarginContainer] by code you should use the following examples: + [codeblock] + var margin_value = 100 + set("custom_constants/margin_top", margin_value) + set("custom_constants/margin_left", margin_value) + set("custom_constants/margin_bottom", margin_value) + set("custom_constants/margin_right", margin_value) + [/codeblock] </description> <tutorials> </tutorials> @@ -14,12 +22,16 @@ </constants> <theme_items> <theme_item name="margin_bottom" type="int"> + All direct children of [MarginContainer] will have a bottom margin of [code]margin_bottom[/code] pixels. </theme_item> <theme_item name="margin_left" type="int"> + All direct children of [MarginContainer] will have a left margin of [code]margin_left[/code] pixels. </theme_item> <theme_item name="margin_right" type="int"> + All direct children of [MarginContainer] will have a right margin of [code]margin_right[/code] pixels. </theme_item> <theme_item name="margin_top" type="int"> + All direct children of [MarginContainer] will have a top margin of [code]margin_top[/code] pixels. </theme_item> </theme_items> </class> diff --git a/doc/classes/OS.xml b/doc/classes/OS.xml index 7b50021284..3292438851 100644 --- a/doc/classes/OS.xml +++ b/doc/classes/OS.xml @@ -4,7 +4,7 @@ Operating System functions. </brief_description> <description> - Operating System functions. OS Wraps the most common functionality to communicate with the host Operating System, such as: mouse grabbing, mouse cursors, clipboard, video mode, date and time, timers, environment variables, execution of binaries, command line, etc. + Operating System functions. OS Wraps the most common functionality to communicate with the host Operating System, such as: clipboard, video mode, date and time, timers, environment variables, execution of binaries, command line, etc. </description> <tutorials> </tutorials> diff --git a/doc/classes/Object.xml b/doc/classes/Object.xml index c9910360ed..548a0c18bb 100644 --- a/doc/classes/Object.xml +++ b/doc/classes/Object.xml @@ -374,6 +374,7 @@ <argument index="1" name="value" type="Variant"> </argument> <description> + Set property into the object, after the current frame's physics step. This is equivalent to calling [method set] via [method call_deferred], i.e. [code]call_deferred("set", [property, value])[/code]. </description> </method> <method name="set_indexed"> diff --git a/doc/classes/TextEdit.xml b/doc/classes/TextEdit.xml index e818d753d8..8c87a4f2e7 100644 --- a/doc/classes/TextEdit.xml +++ b/doc/classes/TextEdit.xml @@ -521,12 +521,15 @@ </constants> <theme_items> <theme_item name="background_color" type="Color"> + Sets the background [Color] of this [TextEdit]. [member syntax_highlighting] has to be enabled. </theme_item> <theme_item name="bookmark_color" type="Color"> + Sets the [Color] of the bookmark marker. [member syntax_highlighting] has to be enabled. </theme_item> <theme_item name="brace_mismatch_color" type="Color"> </theme_item> <theme_item name="breakpoint_color" type="Color"> + Sets the [Color] of the breakpoints. [member breakpoint_gutter] has to be enabled. </theme_item> <theme_item name="caret_background_color" type="Color"> </theme_item> @@ -553,6 +556,7 @@ <theme_item name="completion_selected_color" type="Color"> </theme_item> <theme_item name="current_line_color" type="Color"> + Sets the [Color] of the breakpoints. [member breakpoint_gutter] has to be enabled. </theme_item> <theme_item name="executing_line_color" type="Color"> </theme_item> @@ -563,38 +567,48 @@ <theme_item name="folded" type="Texture"> </theme_item> <theme_item name="font" type="Font"> + Sets the default [Font]. </theme_item> <theme_item name="font_color" type="Color"> + Sets the font [Color]. </theme_item> <theme_item name="font_color_selected" type="Color"> </theme_item> <theme_item name="function_color" type="Color"> </theme_item> <theme_item name="line_number_color" type="Color"> + Sets the [Color] of the line numbers. [member show_line_numbers] has to be enabled. </theme_item> <theme_item name="line_spacing" type="int"> + Sets the spacing between the lines. </theme_item> <theme_item name="mark_color" type="Color"> + Sets the [Color] of marked text. </theme_item> <theme_item name="member_variable_color" type="Color"> </theme_item> <theme_item name="normal" type="StyleBox"> + Sets the [StyleBox] of this [TextEdit]. </theme_item> <theme_item name="number_color" type="Color"> </theme_item> <theme_item name="read_only" type="StyleBox"> + Sets the [StyleBox] of this [TextEdit] when [member readonly] is enabled. </theme_item> <theme_item name="safe_line_number_color" type="Color"> </theme_item> <theme_item name="selection_color" type="Color"> + Sets the highlight [Color] of text selections. </theme_item> <theme_item name="space" type="Texture"> </theme_item> <theme_item name="symbol_color" type="Color"> </theme_item> <theme_item name="tab" type="Texture"> + Sets a custom [Texture] for tab text characters. </theme_item> <theme_item name="word_highlighted_color" type="Color"> + Sets the highlight [Color] of multiple occurrences. [member highlight_all_occurrences] has to be enabled. </theme_item> </theme_items> </class> diff --git a/editor/doc/doc_data.cpp b/editor/doc/doc_data.cpp index 7d2159d365..041f81d063 100644 --- a/editor/doc/doc_data.cpp +++ b/editor/doc/doc_data.cpp @@ -1126,6 +1126,7 @@ Error DocData::save_classes(const String &p_default_path, const Map<String, Stri const PropertyDoc &p = c.theme_properties[i]; _write_string(f, 2, "<theme_item name=\"" + p.name + "\" type=\"" + p.type + "\">"); + _write_string(f, 3, p.description.strip_edges().xml_escape()); _write_string(f, 2, "</theme_item>"); } _write_string(f, 1, "</theme_items>"); diff --git a/editor/editor_help.cpp b/editor/editor_help.cpp index 26d793cf65..4bfb967351 100644 --- a/editor/editor_help.cpp +++ b/editor/editor_help.cpp @@ -416,6 +416,7 @@ void EditorHelp::_update_doc() { class_desc->pop(); class_desc->add_newline(); + class_desc->add_newline(); class_desc->push_color(text_color); class_desc->push_font(doc_font); class_desc->push_indent(1); @@ -441,6 +442,7 @@ void EditorHelp::_update_doc() { class_desc->pop(); class_desc->pop(); + class_desc->add_newline(); class_desc->push_indent(1); class_desc->push_table(2); class_desc->set_table_column_expand(1, 1); @@ -479,14 +481,15 @@ void EditorHelp::_update_doc() { class_desc->push_color(headline_color); _add_text(cd.properties[i].name); + class_desc->pop(); + class_desc->pop(); + if (describe) { class_desc->pop(); property_descr = true; } class_desc->pop(); - class_desc->pop(); - class_desc->pop(); } class_desc->pop(); //table @@ -519,6 +522,7 @@ void EditorHelp::_update_doc() { class_desc->pop(); class_desc->pop(); + class_desc->add_newline(); class_desc->push_font(doc_code_font); class_desc->push_indent(1); class_desc->push_table(2); @@ -876,6 +880,7 @@ void EditorHelp::_update_doc() { class_desc->pop(); class_desc->add_newline(); + class_desc->add_newline(); class_desc->push_color(text_color); class_desc->push_font(doc_font); class_desc->push_indent(1); @@ -1000,6 +1005,7 @@ void EditorHelp::_update_doc() { class_desc->pop(); // table class_desc->add_newline(); + class_desc->add_newline(); class_desc->push_color(text_color); class_desc->push_font(doc_font); @@ -1042,6 +1048,8 @@ void EditorHelp::_update_doc() { class_desc->pop(); class_desc->add_newline(); + class_desc->add_newline(); + class_desc->push_color(text_color); class_desc->push_font(doc_font); class_desc->push_indent(1); diff --git a/editor/editor_layouts_dialog.cpp b/editor/editor_layouts_dialog.cpp index 01e4762196..36f7b30016 100644 --- a/editor/editor_layouts_dialog.cpp +++ b/editor/editor_layouts_dialog.cpp @@ -120,7 +120,7 @@ EditorLayoutsDialog::EditorLayoutsDialog() { layout_names->set_anchor_and_margin(MARGIN_LEFT, ANCHOR_BEGIN, 5); layout_names->set_anchor_and_margin(MARGIN_RIGHT, ANCHOR_END, -5); layout_names->set_v_size_flags(Control::SIZE_EXPAND_FILL); - layout_names->set_select_mode(ItemList::SelectMode::SELECT_MULTI); + layout_names->set_select_mode(ItemList::SELECT_MULTI); layout_names->set_allow_rmb_select(true); name = memnew(LineEdit); diff --git a/editor/editor_settings.cpp b/editor/editor_settings.cpp index 5e04bf4953..f05a75ed90 100644 --- a/editor/editor_settings.cpp +++ b/editor/editor_settings.cpp @@ -573,6 +573,7 @@ void EditorSettings::_load_defaults(Ref<ConfigFile> p_extra_config) { _initial_set("editors/2d/bone_outline_color", Color(0.35, 0.35, 0.35)); _initial_set("editors/2d/bone_outline_size", 2); _initial_set("editors/2d/viewport_border_color", Color(0.4, 0.4, 1.0, 0.4)); + _initial_set("editors/2d/constrain_editor_view", true); _initial_set("editors/2d/warped_mouse_panning", true); _initial_set("editors/2d/simple_panning", false); _initial_set("editors/2d/scroll_to_pan", false); diff --git a/editor/plugins/canvas_item_editor_plugin.cpp b/editor/plugins/canvas_item_editor_plugin.cpp index 3c24fd19b6..6560a403e5 100644 --- a/editor/plugins/canvas_item_editor_plugin.cpp +++ b/editor/plugins/canvas_item_editor_plugin.cpp @@ -3615,18 +3615,19 @@ void CanvasItemEditor::_update_scrollbars() { // Constraints the view offset and updates the scrollbars Point2 begin = canvas_item_rect.position; Point2 end = canvas_item_rect.position + canvas_item_rect.size - local_rect.size / zoom; + bool constrain_editor_view = bool(EditorSettings::get_singleton()->get("editors/2d/constrain_editor_view")); if (canvas_item_rect.size.height <= (local_rect.size.y / zoom)) { - if (ABS(begin.y - previous_update_view_offset.y) < ABS(begin.y - view_offset.y)) { + if (constrain_editor_view && ABS(begin.y - previous_update_view_offset.y) < ABS(begin.y - view_offset.y)) { view_offset.y = previous_update_view_offset.y; } v_scroll->hide(); } else { - if (view_offset.y > end.y && view_offset.y > previous_update_view_offset.y) { + if (constrain_editor_view && view_offset.y > end.y && view_offset.y > previous_update_view_offset.y) { view_offset.y = MAX(end.y, previous_update_view_offset.y); } - if (view_offset.y < begin.y && view_offset.y < previous_update_view_offset.y) { + if (constrain_editor_view && view_offset.y < begin.y && view_offset.y < previous_update_view_offset.y) { view_offset.y = MIN(begin.y, previous_update_view_offset.y); } @@ -3637,16 +3638,16 @@ void CanvasItemEditor::_update_scrollbars() { } if (canvas_item_rect.size.width <= (local_rect.size.x / zoom)) { - if (ABS(begin.x - previous_update_view_offset.x) < ABS(begin.x - view_offset.x)) { + if (constrain_editor_view && ABS(begin.x - previous_update_view_offset.x) < ABS(begin.x - view_offset.x)) { view_offset.x = previous_update_view_offset.x; } h_scroll->hide(); } else { - if (view_offset.x > end.x && view_offset.x > previous_update_view_offset.x) { + if (constrain_editor_view && view_offset.x > end.x && view_offset.x > previous_update_view_offset.x) { view_offset.x = MAX(end.x, previous_update_view_offset.x); } - if (view_offset.x < begin.x && view_offset.x < previous_update_view_offset.x) { + if (constrain_editor_view && view_offset.x < begin.x && view_offset.x < previous_update_view_offset.x) { view_offset.x = MIN(begin.x, previous_update_view_offset.x); } diff --git a/modules/bullet/collision_object_bullet.cpp b/modules/bullet/collision_object_bullet.cpp index 166d7e6158..e1800fd3eb 100644 --- a/modules/bullet/collision_object_bullet.cpp +++ b/modules/bullet/collision_object_bullet.cpp @@ -305,7 +305,7 @@ void RigidCollisionObjectBullet::set_shape_transform(int p_index, const Transfor ERR_FAIL_INDEX(p_index, get_shape_count()); shapes.write[p_index].set_transform(p_transform); - reload_shapes(); + shape_changed(p_index); } const btTransform &RigidCollisionObjectBullet::get_bt_shape_transform(int p_index) const { diff --git a/modules/gdscript/doc_classes/@GDScript.xml b/modules/gdscript/doc_classes/@GDScript.xml index b6de5dbf62..3eaee53789 100644 --- a/modules/gdscript/doc_classes/@GDScript.xml +++ b/modules/gdscript/doc_classes/@GDScript.xml @@ -1241,6 +1241,16 @@ # infinite loop between 0.0 and 0.99 f = wrapf(f + 0.1, 0.0, 1.0) [/codeblock] + [codeblock] + # infinite rotation (in radians) + angle = wrapf(angle + 0.1, 0.0, TAU) + [/codeblock] + Note: If you just want to wrap between 0.0 and [code]n[/code] (where [code]n[/code] is a positive float value) then it's better for performance to use [method fmod] method like [code]fmod(number, n)[/code]. + The usage of [code]wrapf[/code] is more flexible than using the [method fmod] approach by giving the user a simple control over the minimum value. It also fully supports negative numbers, e.g. + [codeblock] + # infinite rotation (in radians) + angle = wrapf(angle + 0.1, -PI, PI) + [/codeblock] </description> </method> <method name="wrapi"> @@ -1267,6 +1277,12 @@ # infinite loop between 0 and 9 frame = wrapi(frame + 1, 0, 10) [/codeblock] + Note: If you just want to wrap between 0 and [code]n[/code] (where [code]n[/code] is a positive integer value) then it's better for performance to use modulo operator like [code]number % n[/code]. + The usage of [code]wrapi[/code] is more flexible than using the modulo approach by giving the user a simple control over the minimum value. It also fully supports negative numbers, e.g. + [codeblock] + # result is -2 + var result = wrapi(-6, -5, -1) + [/codeblock] </description> </method> <method name="yield"> diff --git a/modules/gridmap/grid_map_editor_plugin.cpp b/modules/gridmap/grid_map_editor_plugin.cpp index 6b9a97efb4..03619aa0bd 100644 --- a/modules/gridmap/grid_map_editor_plugin.cpp +++ b/modules/gridmap/grid_map_editor_plugin.cpp @@ -279,7 +279,7 @@ void GridMapEditor::_update_cursor_transform() { cursor_transform = Transform(); cursor_transform.origin = cursor_origin; cursor_transform.basis.set_orthogonal_index(cursor_rot); - cursor_transform = node->get_transform() * cursor_transform; + cursor_transform = node->get_global_transform() * cursor_transform; if (cursor_instance.is_valid()) { VisualServer::get_singleton()->instance_set_transform(cursor_instance, cursor_transform); @@ -420,7 +420,7 @@ bool GridMapEditor::do_input_action(Camera *p_camera, const Point2 &p_point, boo } last_mouseover = Vector3(cell[0], cell[1], cell[2]); - VS::get_singleton()->instance_set_transform(grid_instance[edit_axis], Transform(Basis(), grid_ofs)); + VS::get_singleton()->instance_set_transform(grid_instance[edit_axis], node->get_global_transform() * edit_grid_xform); if (cursor_instance.is_valid()) { diff --git a/platform/iphone/export/export.cpp b/platform/iphone/export/export.cpp index 7ca83320d0..b2064472e4 100644 --- a/platform/iphone/export/export.cpp +++ b/platform/iphone/export/export.cpp @@ -125,7 +125,7 @@ class EditorExportPlatformIOS : public EditorExportPlatform { first = true; continue; } - if (!((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || (c >= '0' && c <= '9') || c == '_')) { + if (!((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || (c >= '0' && c <= '9') || c == '-')) { if (r_error) { *r_error = vformat(TTR("The character '%s' is not allowed in Identifier."), String::chr(c)); } @@ -137,7 +137,7 @@ class EditorExportPlatformIOS : public EditorExportPlatform { } return false; } - if (first && c == '_') { + if (first && c == '-') { if (r_error) { *r_error = vformat(TTR("The character '%s' cannot be the first character in a Identifier segment."), String::chr(c)); } diff --git a/scene/2d/area_2d.cpp b/scene/2d/area_2d.cpp index b322cfe8f1..b701e84a9c 100644 --- a/scene/2d/area_2d.cpp +++ b/scene/2d/area_2d.cpp @@ -657,10 +657,10 @@ void Area2D::_bind_methods() { ClassDB::bind_method(D_METHOD("_body_inout"), &Area2D::_body_inout); ClassDB::bind_method(D_METHOD("_area_inout"), &Area2D::_area_inout); - ADD_SIGNAL(MethodInfo("body_shape_entered", PropertyInfo(Variant::INT, "body_id"), PropertyInfo(Variant::OBJECT, "body", PROPERTY_HINT_RESOURCE_TYPE, "PhysicsBody2D"), PropertyInfo(Variant::INT, "body_shape"), PropertyInfo(Variant::INT, "area_shape"))); - ADD_SIGNAL(MethodInfo("body_shape_exited", PropertyInfo(Variant::INT, "body_id"), PropertyInfo(Variant::OBJECT, "body", PROPERTY_HINT_RESOURCE_TYPE, "PhysicsBody2D"), PropertyInfo(Variant::INT, "body_shape"), PropertyInfo(Variant::INT, "area_shape"))); - ADD_SIGNAL(MethodInfo("body_entered", PropertyInfo(Variant::OBJECT, "body", PROPERTY_HINT_RESOURCE_TYPE, "PhysicsBody2D"))); - ADD_SIGNAL(MethodInfo("body_exited", PropertyInfo(Variant::OBJECT, "body", PROPERTY_HINT_RESOURCE_TYPE, "PhysicsBody2D"))); + ADD_SIGNAL(MethodInfo("body_shape_entered", PropertyInfo(Variant::INT, "body_id"), PropertyInfo(Variant::OBJECT, "body", PROPERTY_HINT_RESOURCE_TYPE, "Node"), PropertyInfo(Variant::INT, "body_shape"), PropertyInfo(Variant::INT, "area_shape"))); + ADD_SIGNAL(MethodInfo("body_shape_exited", PropertyInfo(Variant::INT, "body_id"), PropertyInfo(Variant::OBJECT, "body", PROPERTY_HINT_RESOURCE_TYPE, "Node"), PropertyInfo(Variant::INT, "body_shape"), PropertyInfo(Variant::INT, "area_shape"))); + ADD_SIGNAL(MethodInfo("body_entered", PropertyInfo(Variant::OBJECT, "body", PROPERTY_HINT_RESOURCE_TYPE, "Node"))); + ADD_SIGNAL(MethodInfo("body_exited", PropertyInfo(Variant::OBJECT, "body", PROPERTY_HINT_RESOURCE_TYPE, "Node"))); ADD_SIGNAL(MethodInfo("area_shape_entered", PropertyInfo(Variant::INT, "area_id"), PropertyInfo(Variant::OBJECT, "area", PROPERTY_HINT_RESOURCE_TYPE, "Area2D"), PropertyInfo(Variant::INT, "area_shape"), PropertyInfo(Variant::INT, "self_shape"))); ADD_SIGNAL(MethodInfo("area_shape_exited", PropertyInfo(Variant::INT, "area_id"), PropertyInfo(Variant::OBJECT, "area", PROPERTY_HINT_RESOURCE_TYPE, "Area2D"), PropertyInfo(Variant::INT, "area_shape"), PropertyInfo(Variant::INT, "self_shape"))); diff --git a/scene/3d/vehicle_body.cpp b/scene/3d/vehicle_body.cpp index 32b8219ee0..55bb7eabd9 100644 --- a/scene/3d/vehicle_body.cpp +++ b/scene/3d/vehicle_body.cpp @@ -585,7 +585,7 @@ void VehicleBody::_resolve_single_bilateral(PhysicsDirectBodyState *s, const Vec if (p_rollInfluence > 0.0) { // !BAS! But seeing we apply this frame by frame, makes more sense to me to make this time based // keeping in mind our anti roll factor if it is set - contactDamping = s->get_step() / p_rollInfluence; + contactDamping = MIN(contactDamping, s->get_step() / p_rollInfluence); } #define ONLY_USE_LINEAR_MASS diff --git a/scene/gui/line_edit.cpp b/scene/gui/line_edit.cpp index da6bff8ab8..960499c876 100644 --- a/scene/gui/line_edit.cpp +++ b/scene/gui/line_edit.cpp @@ -650,6 +650,11 @@ void LineEdit::_notification(int p_what) { set_cursor_position(get_cursor_position()); } break; + case NOTIFICATION_TRANSLATION_CHANGED: { + placeholder_translated = tr(placeholder); + update_placeholder_width(); + update(); + } break; case MainLoop::NOTIFICATION_WM_FOCUS_IN: { window_has_focus = true; draw_caret = true; @@ -675,10 +680,8 @@ void LineEdit::_notification(int p_what) { RID ci = get_canvas_item(); Ref<StyleBox> style = get_stylebox("normal"); - float disabled_alpha = 1.0; // used to set the disabled input text color if (!is_editable()) { style = get_stylebox("read_only"); - disabled_alpha = .5; draw_caret = false; } @@ -724,20 +727,19 @@ void LineEdit::_notification(int p_what) { int font_ascent = font->get_ascent(); Color selection_color = get_color("selection_color"); - Color font_color = get_color("font_color"); + Color font_color = is_editable() ? get_color("font_color") : get_color("font_color_uneditable"); Color font_color_selected = get_color("font_color_selected"); Color cursor_color = get_color("cursor_color"); - const String &t = using_placeholder ? placeholder : text; + const String &t = using_placeholder ? placeholder_translated : text; // draw placeholder color if (using_placeholder) font_color.a *= placeholder_alpha; - font_color.a *= disabled_alpha; bool display_clear_icon = !using_placeholder && is_editable() && clear_button_enabled; if (right_icon.is_valid() || display_clear_icon) { Ref<Texture> r_icon = display_clear_icon ? Control::get_icon("clear") : right_icon; - Color color_icon(1, 1, 1, disabled_alpha * .9); + Color color_icon(1, 1, 1, !is_editable() ? .5 * .9 : .9); if (display_clear_icon) { if (clear_button_status.press_attempt && clear_button_status.pressing_inside) { color_icon = get_color("clear_button_color_pressed"); @@ -1148,16 +1150,9 @@ String LineEdit::get_text() const { void LineEdit::set_placeholder(String p_text) { - placeholder = tr(p_text); - if ((max_length <= 0) || (placeholder.length() <= max_length)) { - Ref<Font> font = get_font("font"); - cached_placeholder_width = 0; - if (font != NULL) { - for (int i = 0; i < placeholder.length(); i++) { - cached_placeholder_width += font->get_char_size(placeholder[i]).width; - } - } - } + placeholder = p_text; + placeholder_translated = tr(placeholder); + update_placeholder_width(); update(); } @@ -1546,6 +1541,18 @@ void LineEdit::_emit_text_change() { text_changed_dirty = false; } +void LineEdit::update_placeholder_width() { + if ((max_length <= 0) || (placeholder_translated.length() <= max_length)) { + Ref<Font> font = get_font("font"); + cached_placeholder_width = 0; + if (font != NULL) { + for (int i = 0; i < placeholder_translated.length(); i++) { + cached_placeholder_width += font->get_char_size(placeholder_translated[i]).width; + } + } + } +} + void LineEdit::_clear_redo() { _create_undo_state(); if (undo_stack_pos == NULL) { diff --git a/scene/gui/line_edit.h b/scene/gui/line_edit.h index 3b29780dc0..3002f6f637 100644 --- a/scene/gui/line_edit.h +++ b/scene/gui/line_edit.h @@ -72,6 +72,7 @@ private: String undo_text; String text; String placeholder; + String placeholder_translated; String secret_character; float placeholder_alpha; String ime_text; @@ -126,6 +127,8 @@ private: void _emit_text_change(); bool expand_to_text_length; + void update_placeholder_width(); + bool caret_blink_enabled; bool draw_caret; bool window_has_focus; diff --git a/scene/gui/rich_text_label.cpp b/scene/gui/rich_text_label.cpp index 8891f679ee..3a9a0ae21a 100644 --- a/scene/gui/rich_text_label.cpp +++ b/scene/gui/rich_text_label.cpp @@ -314,6 +314,18 @@ int RichTextLabel::_process_line(ItemFrame *p_frame, const Vector2 &p_ofs, int & align = align_it->align; } break; + case ITEM_INDENT: { + + if (it != l.from) { + ItemIndent *indent_it = static_cast<ItemIndent *>(it); + + int indent = indent_it->level * tab_size * cfont->get_char_size(' ').width; + margin += indent; + begin += indent; + wofs += indent; + } + + } break; case ITEM_TEXT: { ItemText *text = static_cast<ItemText *>(it); @@ -1301,6 +1313,23 @@ bool RichTextLabel::_find_meta(Item *p_item, Variant *r_meta, ItemMeta **r_item) return false; } +bool RichTextLabel::_find_layout_subitem(Item *from, Item *to) { + + if (from && from != to) { + if (from->type != ITEM_FONT && from->type != ITEM_COLOR && from->type != ITEM_UNDERLINE && from->type != ITEM_STRIKETHROUGH) + return true; + + for (List<Item *>::Element *E = from->subitems.front(); E; E = E->next()) { + bool layout = _find_layout_subitem(E->get(), to); + + if (layout) + return true; + } + } + + return false; +} + void RichTextLabel::_validate_line_caches(ItemFrame *p_frame) { if (p_frame->first_invalid_line == p_frame->lines.size()) @@ -1421,7 +1450,7 @@ void RichTextLabel::_add_item(Item *p_item, bool p_enter, bool p_ensure_newline) if (p_ensure_newline) { Item *from = current_frame->lines[current_frame->lines.size() - 1].from; // only create a new line for Item types that generate content/layout, ignore those that represent formatting/styling - if (from && from->type != ITEM_FONT && from->type != ITEM_COLOR && from->type != ITEM_UNDERLINE && from->type != ITEM_STRIKETHROUGH) { + if (_find_layout_subitem(from, p_item)) { _invalidate_current_line(current_frame); current_frame->lines.resize(current_frame->lines.size() + 1); } diff --git a/scene/gui/rich_text_label.h b/scene/gui/rich_text_label.h index 114c6103e2..21d099c37a 100644 --- a/scene/gui/rich_text_label.h +++ b/scene/gui/rich_text_label.h @@ -286,6 +286,7 @@ private: bool _find_underline(Item *p_item); bool _find_strikethrough(Item *p_item); bool _find_meta(Item *p_item, Variant *r_meta, ItemMeta **r_item = NULL); + bool _find_layout_subitem(Item *from, Item *to); void _update_scroll(); void _scroll_changed(double); diff --git a/scene/gui/text_edit.cpp b/scene/gui/text_edit.cpp index 4e86e4bb1e..9d457e989c 100644 --- a/scene/gui/text_edit.cpp +++ b/scene/gui/text_edit.cpp @@ -662,10 +662,8 @@ void TextEdit::_notification(int p_what) { int xmargin_end = size.width - cache.style_normal->get_margin(MARGIN_RIGHT); //let's do it easy for now: cache.style_normal->draw(ci, Rect2(Point2(), size)); - float readonly_alpha = 1.0; // used to set the input text color when in read-only mode if (readonly) { cache.style_readonly->draw(ci, Rect2(Point2(), size)); - readonly_alpha = .5; draw_caret = false; } if (has_focus()) @@ -675,8 +673,7 @@ void TextEdit::_notification(int p_what) { int visible_rows = get_visible_rows() + 1; - Color color = cache.font_color; - color.a *= readonly_alpha; + Color color = readonly ? cache.font_color_readonly : cache.font_color; if (syntax_coloring) { if (cache.background_color.a > 0.01) { @@ -871,10 +868,7 @@ void TextEdit::_notification(int p_what) { color_map = _get_line_syntax_highlighting(line); } // ensure we at least use the font color - Color current_color = cache.font_color; - if (readonly) { - current_color.a *= readonly_alpha; - } + Color current_color = readonly ? cache.font_color_readonly : cache.font_color; bool underlined = false; @@ -1061,10 +1055,7 @@ void TextEdit::_notification(int p_what) { if (syntax_coloring) { if (color_map.has(last_wrap_column + j)) { - current_color = color_map[last_wrap_column + j].color; - if (readonly) { - current_color.a *= readonly_alpha; - } + current_color = readonly ? cache.font_color_readonly : color_map[last_wrap_column + j].color; } color = current_color; } @@ -1252,8 +1243,7 @@ void TextEdit::_notification(int p_what) { if (cursor.column == last_wrap_column + j && cursor.line == line && cursor_wrap_index == line_wrap_index && block_caret && draw_caret && !insert_mode) { color = cache.caret_background_color; } else if (!syntax_coloring && block_caret) { - color = cache.font_color; - color.a *= readonly_alpha; + color = readonly ? cache.font_color_readonly : cache.font_color; } if (str[j] >= 32) { @@ -4555,6 +4545,7 @@ void TextEdit::_update_caches() { cache.safe_line_number_color = get_color("safe_line_number_color"); cache.font_color = get_color("font_color"); cache.font_color_selected = get_color("font_color_selected"); + cache.font_color_readonly = get_color("font_color_readonly"); cache.keyword_color = get_color("keyword_color"); cache.function_color = get_color("function_color"); cache.member_variable_color = get_color("member_variable_color"); diff --git a/scene/gui/text_edit.h b/scene/gui/text_edit.h index c721cf992e..30956ccb23 100644 --- a/scene/gui/text_edit.h +++ b/scene/gui/text_edit.h @@ -185,6 +185,7 @@ private: Color safe_line_number_color; Color font_color; Color font_color_selected; + Color font_color_readonly; Color keyword_color; Color number_color; Color function_color; diff --git a/scene/resources/default_theme/default_theme.cpp b/scene/resources/default_theme/default_theme.cpp index 2c5dfc375c..4e2fe1f9b2 100644 --- a/scene/resources/default_theme/default_theme.cpp +++ b/scene/resources/default_theme/default_theme.cpp @@ -398,6 +398,7 @@ void fill_default_theme(Ref<Theme> &theme, const Ref<Font> &default_font, const theme->set_color("font_color", "LineEdit", control_font_color); theme->set_color("font_color_selected", "LineEdit", Color(0, 0, 0)); + theme->set_color("font_color_uneditable", "LineEdit", Color(control_font_color.r, control_font_color.g, control_font_color.b, 0.5f)); theme->set_color("cursor_color", "LineEdit", control_font_color_hover); theme->set_color("selection_color", "LineEdit", font_color_selection); theme->set_color("clear_button_color", "LineEdit", control_font_color); @@ -439,6 +440,7 @@ void fill_default_theme(Ref<Theme> &theme, const Ref<Font> &default_font, const theme->set_color("completion_font_color", "TextEdit", Color::html("aaaaaa")); theme->set_color("font_color", "TextEdit", control_font_color); theme->set_color("font_color_selected", "TextEdit", Color(0, 0, 0)); + theme->set_color("font_color_readonly", "TextEdit", Color(control_font_color.r, control_font_color.g, control_font_color.b, 0.5f)); theme->set_color("selection_color", "TextEdit", font_color_selection); theme->set_color("mark_color", "TextEdit", Color(1.0, 0.4, 0.4, 0.4)); theme->set_color("bookmark_color", "TextEdit", Color(0.08, 0.49, 0.98)); |