summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--core/input/input.cpp15
-rw-r--r--core/io/resource_loader.cpp2
-rw-r--r--core/string/locales.h1
-rw-r--r--core/string/translation.cpp16
-rw-r--r--doc/classes/CharacterBody2D.xml8
-rw-r--r--doc/classes/CharacterBody3D.xml4
-rw-r--r--doc/classes/TextEdit.xml6
-rw-r--r--doc/classes/TileMap.xml3
-rwxr-xr-xdoc/tools/make_rst.py2
-rw-r--r--editor/editor_help.cpp15
-rw-r--r--editor/editor_help.h1
-rw-r--r--editor/editor_settings.cpp2
-rw-r--r--platform/javascript/display_server_javascript.cpp3
-rw-r--r--platform/linuxbsd/display_server_x11.cpp1
-rw-r--r--platform/osx/display_server_osx.mm1
-rw-r--r--platform/windows/display_server_windows.cpp4
-rw-r--r--scene/2d/physics_body_2d.cpp32
-rw-r--r--scene/2d/physics_body_2d.h10
-rw-r--r--scene/2d/tile_map.cpp2
-rw-r--r--scene/3d/physics_body_3d.cpp13
-rw-r--r--scene/3d/physics_body_3d.h4
-rw-r--r--scene/gui/text_edit.cpp115
-rw-r--r--scene/gui/text_edit.h20
-rw-r--r--scene/main/http_request.cpp15
-rw-r--r--scene/main/viewport.cpp11
-rw-r--r--servers/rendering/renderer_rd/renderer_scene_render_rd.cpp22
-rw-r--r--servers/rendering/renderer_rd/renderer_scene_render_rd.h2
-rw-r--r--servers/rendering/shader_language.cpp13
28 files changed, 237 insertions, 106 deletions
diff --git a/core/input/input.cpp b/core/input/input.cpp
index 3ddb151f23..7106bd0745 100644
--- a/core/input/input.cpp
+++ b/core/input/input.cpp
@@ -518,18 +518,20 @@ void Input::_parse_input_event_impl(const Ref<InputEvent> &p_event, bool p_is_em
Ref<InputEventMouseMotion> mm = p_event;
if (mm.is_valid()) {
- Point2 pos = mm->get_global_position();
- if (mouse_pos != pos) {
- set_mouse_position(pos);
+ Point2 position = mm->get_global_position();
+ if (mouse_pos != position) {
+ set_mouse_position(position);
}
+ Vector2 relative = mm->get_relative();
+ mouse_velocity_track.update(relative);
if (event_dispatch_function && emulate_touch_from_mouse && !p_is_emulated && (mm->get_button_mask() & MouseButton::LEFT) != MouseButton::NONE) {
Ref<InputEventScreenDrag> drag_event;
drag_event.instantiate();
- drag_event->set_position(mm->get_position());
- drag_event->set_relative(mm->get_relative());
- drag_event->set_velocity(mm->get_velocity());
+ drag_event->set_position(position);
+ drag_event->set_relative(relative);
+ drag_event->set_velocity(get_last_mouse_velocity());
event_dispatch_function(drag_event);
}
@@ -710,7 +712,6 @@ void Input::set_gyroscope(const Vector3 &p_gyroscope) {
}
void Input::set_mouse_position(const Point2 &p_posf) {
- mouse_velocity_track.update(p_posf - mouse_pos);
mouse_pos = p_posf;
}
diff --git a/core/io/resource_loader.cpp b/core/io/resource_loader.cpp
index 3e1c9d2e4a..21bf566b1b 100644
--- a/core/io/resource_loader.cpp
+++ b/core/io/resource_loader.cpp
@@ -820,7 +820,7 @@ String ResourceLoader::_path_remap(const String &p_path, bool *r_translation_rem
}
String l = res_remaps[i].substr(split + 1).strip_edges();
int score = TranslationServer::get_singleton()->compare_locales(locale, l);
- if (score > best_score) {
+ if (score > 0 && score >= best_score) {
new_path = res_remaps[i].left(split);
best_score = score;
if (score == 10) {
diff --git a/core/string/locales.h b/core/string/locales.h
index 9ef6dee5ac..32d6608ec2 100644
--- a/core/string/locales.h
+++ b/core/string/locales.h
@@ -42,6 +42,7 @@ static const char *locale_renames[][2] = {
{ "in", "id" }, // Indonesian
{ "iw", "he" }, // Hebrew
{ "no", "nb" }, // Norwegian Bokmål
+ { "C", "en" }, // Locale is not set, fallback to English.
{ nullptr, nullptr }
};
diff --git a/core/string/translation.cpp b/core/string/translation.cpp
index 674098b06c..355ee238e8 100644
--- a/core/string/translation.cpp
+++ b/core/string/translation.cpp
@@ -544,7 +544,7 @@ Ref<Translation> TranslationServer::get_translation_object(const String &p_local
String l = t->get_locale();
int score = compare_locales(p_locale, l);
- if (score > best_score) {
+ if (score > 0 && score >= best_score) {
res = t;
best_score = score;
if (score == 10) {
@@ -566,8 +566,6 @@ StringName TranslationServer::translate(const StringName &p_message, const Strin
return p_message;
}
- ERR_FAIL_COND_V_MSG(locale.length() < 2, p_message, "Could not translate message as configured locale '" + locale + "' is invalid.");
-
StringName res = _get_message_from_translations(p_message, p_context, locale, false);
if (!res && fallback.length() >= 2) {
@@ -589,8 +587,6 @@ StringName TranslationServer::translate_plural(const StringName &p_message, cons
return p_message_plural;
}
- ERR_FAIL_COND_V_MSG(locale.length() < 2, p_message, "Could not translate message as configured locale '" + locale + "' is invalid.");
-
StringName res = _get_message_from_translations(p_message, p_context, locale, true, p_message_plural, p_n);
if (!res && fallback.length() >= 2) {
@@ -617,13 +613,17 @@ StringName TranslationServer::_get_message_from_translations(const StringName &p
String l = t->get_locale();
int score = compare_locales(p_locale, l);
- if (score > best_score) {
+ if (score > 0 && score >= best_score) {
StringName r;
if (!plural) {
- res = t->get_message(p_message, p_context);
+ r = t->get_message(p_message, p_context);
} else {
- res = t->get_plural_message(p_message, p_message_plural, p_n, p_context);
+ r = t->get_plural_message(p_message, p_message_plural, p_n, p_context);
+ }
+ if (!r) {
+ continue;
}
+ res = r;
best_score = score;
if (score == 10) {
break; // Exact match, skip the rest.
diff --git a/doc/classes/CharacterBody2D.xml b/doc/classes/CharacterBody2D.xml
index 28a9107db6..1c4475dd70 100644
--- a/doc/classes/CharacterBody2D.xml
+++ b/doc/classes/CharacterBody2D.xml
@@ -165,9 +165,6 @@
If [code]true[/code], the body will not slide on slopes when calling [method move_and_slide] when the body is standing still.
If [code]false[/code], the body will slide on floor's slopes when [member motion_velocity] applies a downward force.
</member>
- <member name="free_mode_min_slide_angle" type="float" setter="set_free_mode_min_slide_angle" getter="get_free_mode_min_slide_angle" default="0.261799">
- Minimum angle (in radians) where the body is allowed to slide when it encounters a slope. The default value equals 15 degrees.
- </member>
<member name="max_slides" type="int" setter="set_max_slides" getter="get_max_slides" default="4">
Maximum number of times the body can change direction before it stops when calling [method move_and_slide].
</member>
@@ -192,12 +189,15 @@
<member name="up_direction" type="Vector2" setter="set_up_direction" getter="get_up_direction" default="Vector2(0, -1)">
Direction vector used to determine what is a wall and what is a floor (or a ceiling), rather than a wall, when calling [method move_and_slide]. Defaults to [code]Vector2.UP[/code]. If set to [code]Vector2(0, 0)[/code], everything is considered a wall. This is useful for topdown games.
</member>
+ <member name="wall_min_slide_angle" type="float" setter="set_wall_min_slide_angle" getter="get_wall_min_slide_angle" default="0.261799">
+ Minimum angle (in radians) where the body is allowed to slide when it encounters a slope. The default value equals 15 degrees. This property only affects movement when [member motion_mode] is [constant MOTION_MODE_FLOATING].
+ </member>
</members>
<constants>
<constant name="MOTION_MODE_GROUNDED" value="0" enum="MotionMode">
Apply when notions of walls, ceiling and floor are relevant. In this mode the body motion will react to slopes (acceleration/slowdown). This mode is suitable for sided games like platformers.
</constant>
- <constant name="MOTION_MODE_FREE" value="1" enum="MotionMode">
+ <constant name="MOTION_MODE_FLOATING" value="1" enum="MotionMode">
Apply when there is no notion of floor or ceiling. All collisions will be reported as [code]on_wall[/code]. In this mode, when you slide, the speed will always be constant. This mode is suitable for top-down games.
</constant>
<constant name="PLATFORM_VEL_ON_LEAVE_ALWAYS" value="0" enum="MovingPlatformApplyVelocityOnLeave">
diff --git a/doc/classes/CharacterBody3D.xml b/doc/classes/CharacterBody3D.xml
index 819190fd69..a5df0fd97e 100644
--- a/doc/classes/CharacterBody3D.xml
+++ b/doc/classes/CharacterBody3D.xml
@@ -175,14 +175,14 @@
Direction vector used to determine what is a wall and what is a floor (or a ceiling), rather than a wall, when calling [method move_and_slide]. Defaults to [code]Vector3.UP[/code]. If set to [code]Vector3(0, 0, 0)[/code], everything is considered a wall. This is useful for topdown games.
</member>
<member name="wall_min_slide_angle" type="float" setter="set_wall_min_slide_angle" getter="get_wall_min_slide_angle" default="0.261799">
- Minimum angle (in radians) where the body is allowed to slide when it encounters a slope. The default value equals 15 degrees. In [code]MOTION_MODE_GROUNDED[/code], it works only when [member floor_block_on_wall] is [code]true[/code].
+ Minimum angle (in radians) where the body is allowed to slide when it encounters a slope. The default value equals 15 degrees. When [member motion_mode] is [constant MOTION_MODE_GROUNDED], it only affects movement if [member floor_block_on_wall] is [code]true[/code].
</member>
</members>
<constants>
<constant name="MOTION_MODE_GROUNDED" value="0" enum="MotionMode">
Apply when notions of walls, ceiling and floor are relevant. In this mode the body motion will react to slopes (acceleration/slowdown). This mode is suitable for grounded games like platformers.
</constant>
- <constant name="MOTION_MODE_FREE" value="1" enum="MotionMode">
+ <constant name="MOTION_MODE_FLOATING" value="1" enum="MotionMode">
Apply when there is no notion of floor or ceiling. All collisions will be reported as [code]on_wall[/code]. In this mode, when you slide, the speed will always be constant. This mode is suitable for games without ground like space games.
</constant>
<constant name="PLATFORM_VEL_ON_LEAVE_ALWAYS" value="0" enum="MovingPlatformApplyVelocityOnLeave">
diff --git a/doc/classes/TextEdit.xml b/doc/classes/TextEdit.xml
index 5f887a397f..6d602d58ee 100644
--- a/doc/classes/TextEdit.xml
+++ b/doc/classes/TextEdit.xml
@@ -992,6 +992,12 @@
<member name="override_selected_font_color" type="bool" setter="set_override_selected_font_color" getter="is_overriding_selected_font_color" default="false">
If [code]true[/code], custom [code]font_selected_color[/code] will be used for selected text.
</member>
+ <member name="placeholder_alpha" type="float" setter="set_placeholder_alpha" getter="get_placeholder_alpha" default="0.6">
+ Opacity of the [member placeholder_text]. From [code]0[/code] to [code]1[/code].
+ </member>
+ <member name="placeholder_text" type="String" setter="set_placeholder" getter="get_placeholder" default="&quot;&quot;">
+ Text shown when the [TextEdit] is empty. It is [b]not[/b] the [TextEdit]'s default value (see [member text]).
+ </member>
<member name="scroll_horizontal" type="int" setter="set_h_scroll" getter="get_h_scroll" default="0">
If there is a horizontal scrollbar, this determines the current horizontal scroll value in pixels.
</member>
diff --git a/doc/classes/TileMap.xml b/doc/classes/TileMap.xml
index e37031f3fd..07b9543823 100644
--- a/doc/classes/TileMap.xml
+++ b/doc/classes/TileMap.xml
@@ -202,7 +202,8 @@
<return type="Vector2" />
<argument index="0" name="map_position" type="Vector2i" />
<description>
- Returns the local position corresponding to the given tilemap (grid-based) coordinates.
+ Returns a local position of the center of the cell at the given tilemap (grid-based) coordinates.
+ [b]Note:[/b] This doesn't correspond to the visual position of the tile, i.e. it ignores the [member TileData.texture_offset] property of individual tiles.
</description>
</method>
<method name="move_layer">
diff --git a/doc/tools/make_rst.py b/doc/tools/make_rst.py
index 9e18866ca3..68f3b66f43 100755
--- a/doc/tools/make_rst.py
+++ b/doc/tools/make_rst.py
@@ -438,7 +438,7 @@ def main(): # type: () -> None
for path in args.path:
# Cut off trailing slashes so os.path.basename doesn't choke.
- if path.endswith(os.sep):
+ if path.endswith("/") or path.endswith("\\"):
path = path[:-1]
if os.path.basename(path) == "modules":
diff --git a/editor/editor_help.cpp b/editor/editor_help.cpp
index 311767d301..6d5e56184a 100644
--- a/editor/editor_help.cpp
+++ b/editor/editor_help.cpp
@@ -169,12 +169,15 @@ void EditorHelp::_class_desc_resized() {
Ref<Font> doc_code_font = get_theme_font(SNAME("doc_source"), SNAME("EditorFonts"));
int font_size = get_theme_font_size(SNAME("doc_source_size"), SNAME("EditorFonts"));
real_t char_width = doc_code_font->get_char_size('x', 0, font_size).width;
- const int display_margin = MAX(30 * EDSCALE, get_parent_anchorable_rect().size.width - char_width * 120 * EDSCALE) * 0.5;
-
- Ref<StyleBox> class_desc_stylebox = EditorNode::get_singleton()->get_theme_base()->get_theme_stylebox(SNAME("normal"), SNAME("RichTextLabel"))->duplicate();
- class_desc_stylebox->set_default_margin(SIDE_LEFT, display_margin);
- class_desc_stylebox->set_default_margin(SIDE_RIGHT, display_margin);
- class_desc->add_theme_style_override("normal", class_desc_stylebox);
+ const int new_display_margin = MAX(30 * EDSCALE, get_parent_anchorable_rect().size.width - char_width * 120 * EDSCALE) * 0.5;
+ if (display_margin != new_display_margin) {
+ display_margin = new_display_margin;
+
+ Ref<StyleBox> class_desc_stylebox = EditorNode::get_singleton()->get_theme_base()->get_theme_stylebox(SNAME("normal"), SNAME("RichTextLabel"))->duplicate();
+ class_desc_stylebox->set_default_margin(SIDE_LEFT, display_margin);
+ class_desc_stylebox->set_default_margin(SIDE_RIGHT, display_margin);
+ class_desc->add_theme_style_override("normal", class_desc_stylebox);
+ }
}
void EditorHelp::_add_type(const String &p_type, const String &p_enum) {
diff --git a/editor/editor_help.h b/editor/editor_help.h
index 377ae05a08..237cf4f347 100644
--- a/editor/editor_help.h
+++ b/editor/editor_help.h
@@ -156,6 +156,7 @@ class EditorHelp : public VBoxContainer {
void _class_desc_select(const String &p_select);
void _class_desc_input(const Ref<InputEvent> &p_input);
void _class_desc_resized();
+ int display_margin = 0;
Error _goto_desc(const String &p_class, int p_vscr = -1);
//void _update_history_buttons();
diff --git a/editor/editor_settings.cpp b/editor/editor_settings.cpp
index 07ebd249b3..8146f48f91 100644
--- a/editor/editor_settings.cpp
+++ b/editor/editor_settings.cpp
@@ -377,7 +377,7 @@ void EditorSettings::_load_defaults(Ref<ConfigFile> p_extra_config) {
lang_hint += locale;
int score = TranslationServer::get_singleton()->compare_locales(host_lang, locale);
- if (score > best_score) {
+ if (score > 0 && score >= best_score) {
best = locale;
best_score = score;
if (score == 10) {
diff --git a/platform/javascript/display_server_javascript.cpp b/platform/javascript/display_server_javascript.cpp
index e7564a599c..2842fc2f5e 100644
--- a/platform/javascript/display_server_javascript.cpp
+++ b/platform/javascript/display_server_javascript.cpp
@@ -137,7 +137,6 @@ int DisplayServerJavaScript::mouse_button_callback(int p_pressed, int p_button,
DisplayServerJavaScript *ds = get_singleton();
Point2 pos(p_x, p_y);
- Input::get_singleton()->set_mouse_position(pos);
Ref<InputEventMouseButton> ev;
ev.instantiate();
ev->set_position(pos);
@@ -219,7 +218,6 @@ void DisplayServerJavaScript::mouse_move_callback(double p_x, double p_y, double
}
Point2 pos(p_x, p_y);
- Input::get_singleton()->set_mouse_position(pos);
Ref<InputEventMouseMotion> ev;
ev.instantiate();
dom2godot_mod(ev, p_modifiers);
@@ -229,7 +227,6 @@ void DisplayServerJavaScript::mouse_move_callback(double p_x, double p_y, double
ev->set_global_position(pos);
ev->set_relative(Vector2(p_rel_x, p_rel_y));
- Input::get_singleton()->set_mouse_position(ev->get_position());
ev->set_velocity(Input::get_singleton()->get_last_mouse_velocity());
Input::get_singleton()->parse_input_event(ev);
diff --git a/platform/linuxbsd/display_server_x11.cpp b/platform/linuxbsd/display_server_x11.cpp
index 213553ab30..0ce627ca4f 100644
--- a/platform/linuxbsd/display_server_x11.cpp
+++ b/platform/linuxbsd/display_server_x11.cpp
@@ -3631,7 +3631,6 @@ void DisplayServerX11::process_events() {
mm->set_button_mask((MouseButton)mouse_get_button_state());
mm->set_position(pos);
mm->set_global_position(pos);
- Input::get_singleton()->set_mouse_position(pos);
mm->set_velocity(Input::get_singleton()->get_last_mouse_velocity());
mm->set_relative(rel);
diff --git a/platform/osx/display_server_osx.mm b/platform/osx/display_server_osx.mm
index 60f1eac4b1..1340aad9b2 100644
--- a/platform/osx/display_server_osx.mm
+++ b/platform/osx/display_server_osx.mm
@@ -787,7 +787,6 @@ static void _mouseDownEvent(DisplayServer::WindowID window_id, NSEvent *event, M
mm->set_relative(relativeMotion);
_get_key_modifier_state([event modifierFlags], mm);
- Input::get_singleton()->set_mouse_position(wd.mouse_pos);
Input::get_singleton()->parse_input_event(mm);
}
diff --git a/platform/windows/display_server_windows.cpp b/platform/windows/display_server_windows.cpp
index bcddae45d8..c9e2251b35 100644
--- a/platform/windows/display_server_windows.cpp
+++ b/platform/windows/display_server_windows.cpp
@@ -2072,7 +2072,6 @@ LRESULT DisplayServerWindows::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARA
mm->set_position(c);
mm->set_global_position(c);
- Input::get_singleton()->set_mouse_position(c);
mm->set_velocity(Vector2(0, 0));
if (raw->data.mouse.usFlags == MOUSE_MOVE_RELATIVE) {
@@ -2177,7 +2176,6 @@ LRESULT DisplayServerWindows::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARA
SetCursorPos(pos.x, pos.y);
}
- Input::get_singleton()->set_mouse_position(mm->get_position());
mm->set_velocity(Input::get_singleton()->get_last_mouse_velocity());
if (old_invalid) {
@@ -2319,7 +2317,6 @@ LRESULT DisplayServerWindows::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARA
SetCursorPos(pos.x, pos.y);
}
- Input::get_singleton()->set_mouse_position(mm->get_position());
mm->set_velocity(Input::get_singleton()->get_last_mouse_velocity());
if (old_invalid) {
@@ -2420,7 +2417,6 @@ LRESULT DisplayServerWindows::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARA
SetCursorPos(pos.x, pos.y);
}
- Input::get_singleton()->set_mouse_position(mm->get_position());
mm->set_velocity(Input::get_singleton()->get_last_mouse_velocity());
if (old_invalid) {
diff --git a/scene/2d/physics_body_2d.cpp b/scene/2d/physics_body_2d.cpp
index b2cc8164b6..01fa109384 100644
--- a/scene/2d/physics_body_2d.cpp
+++ b/scene/2d/physics_body_2d.cpp
@@ -1162,7 +1162,7 @@ bool CharacterBody2D::move_and_slide() {
if (motion_mode == MOTION_MODE_GROUNDED) {
_move_and_slide_grounded(delta, was_on_floor);
} else {
- _move_and_slide_free(delta);
+ _move_and_slide_floating(delta);
}
// Compute real velocity.
@@ -1350,7 +1350,7 @@ void CharacterBody2D::_move_and_slide_grounded(double p_delta, bool p_was_on_flo
}
}
-void CharacterBody2D::_move_and_slide_free(double p_delta) {
+void CharacterBody2D::_move_and_slide_floating(double p_delta) {
Vector2 motion = motion_velocity * p_delta;
platform_rid = RID();
@@ -1376,7 +1376,7 @@ void CharacterBody2D::_move_and_slide_free(double p_delta) {
break;
}
- if (free_mode_min_slide_angle != 0 && result.get_angle(-motion_velocity.normalized()) < free_mode_min_slide_angle + FLOOR_ANGLE_THRESHOLD) {
+ if (wall_min_slide_angle != 0 && result.get_angle(-motion_velocity.normalized()) < wall_min_slide_angle + FLOOR_ANGLE_THRESHOLD) {
motion = Vector2();
} else if (first_slide) {
Vector2 motion_slide_norm = result.remainder.slide(result.collision_normal).normalized();
@@ -1668,12 +1668,12 @@ void CharacterBody2D::set_floor_snap_length(real_t p_floor_snap_length) {
floor_snap_length = p_floor_snap_length;
}
-real_t CharacterBody2D::get_free_mode_min_slide_angle() const {
- return free_mode_min_slide_angle;
+real_t CharacterBody2D::get_wall_min_slide_angle() const {
+ return wall_min_slide_angle;
}
-void CharacterBody2D::set_free_mode_min_slide_angle(real_t p_radians) {
- free_mode_min_slide_angle = p_radians;
+void CharacterBody2D::set_wall_min_slide_angle(real_t p_radians) {
+ wall_min_slide_angle = p_radians;
}
const Vector2 &CharacterBody2D::get_up_direction() const {
@@ -1681,7 +1681,7 @@ const Vector2 &CharacterBody2D::get_up_direction() const {
}
void CharacterBody2D::set_up_direction(const Vector2 &p_up_direction) {
- ERR_FAIL_COND_MSG(p_up_direction == Vector2(), "up_direction can't be equal to Vector2.ZERO, consider using Free motion mode instead.");
+ ERR_FAIL_COND_MSG(p_up_direction == Vector2(), "up_direction can't be equal to Vector2.ZERO, consider using Floating motion mode instead.");
up_direction = p_up_direction.normalized();
}
@@ -1728,8 +1728,8 @@ void CharacterBody2D::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_floor_max_angle", "radians"), &CharacterBody2D::set_floor_max_angle);
ClassDB::bind_method(D_METHOD("get_floor_snap_length"), &CharacterBody2D::get_floor_snap_length);
ClassDB::bind_method(D_METHOD("set_floor_snap_length", "floor_snap_length"), &CharacterBody2D::set_floor_snap_length);
- ClassDB::bind_method(D_METHOD("get_free_mode_min_slide_angle"), &CharacterBody2D::get_free_mode_min_slide_angle);
- ClassDB::bind_method(D_METHOD("set_free_mode_min_slide_angle", "radians"), &CharacterBody2D::set_free_mode_min_slide_angle);
+ ClassDB::bind_method(D_METHOD("get_wall_min_slide_angle"), &CharacterBody2D::get_wall_min_slide_angle);
+ ClassDB::bind_method(D_METHOD("set_wall_min_slide_angle", "radians"), &CharacterBody2D::set_wall_min_slide_angle);
ClassDB::bind_method(D_METHOD("get_up_direction"), &CharacterBody2D::get_up_direction);
ClassDB::bind_method(D_METHOD("set_up_direction", "up_direction"), &CharacterBody2D::set_up_direction);
ClassDB::bind_method(D_METHOD("set_motion_mode", "mode"), &CharacterBody2D::set_motion_mode);
@@ -1754,14 +1754,12 @@ void CharacterBody2D::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_slide_collision", "slide_idx"), &CharacterBody2D::_get_slide_collision);
ClassDB::bind_method(D_METHOD("get_last_slide_collision"), &CharacterBody2D::_get_last_slide_collision);
- ADD_PROPERTY(PropertyInfo(Variant::INT, "motion_mode", PROPERTY_HINT_ENUM, "Grounded,Free", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_UPDATE_ALL_IF_MODIFIED), "set_motion_mode", "get_motion_mode");
+ ADD_PROPERTY(PropertyInfo(Variant::INT, "motion_mode", PROPERTY_HINT_ENUM, "Grounded,Floating", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_UPDATE_ALL_IF_MODIFIED), "set_motion_mode", "get_motion_mode");
ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "up_direction"), "set_up_direction", "get_up_direction");
ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "motion_velocity", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NO_EDITOR), "set_motion_velocity", "get_motion_velocity");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "slide_on_ceiling"), "set_slide_on_ceiling_enabled", "is_slide_on_ceiling_enabled");
ADD_PROPERTY(PropertyInfo(Variant::INT, "max_slides", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NO_EDITOR), "set_max_slides", "get_max_slides");
-
- ADD_GROUP("Free Mode", "free_mode_");
- ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "free_mode_min_slide_angle", PROPERTY_HINT_RANGE, "0,180,0.1,radians", PROPERTY_USAGE_DEFAULT), "set_free_mode_min_slide_angle", "get_free_mode_min_slide_angle");
+ ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "wall_min_slide_angle", PROPERTY_HINT_RANGE, "0,180,0.1,radians", PROPERTY_USAGE_DEFAULT), "set_wall_min_slide_angle", "get_wall_min_slide_angle");
ADD_GROUP("Floor", "floor_");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "floor_stop_on_slope"), "set_floor_stop_on_slope_enabled", "is_floor_stop_on_slope_enabled");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "floor_constant_speed"), "set_floor_constant_speed_enabled", "is_floor_constant_speed_enabled");
@@ -1775,7 +1773,7 @@ void CharacterBody2D::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "collision/safe_margin", PROPERTY_HINT_RANGE, "0.001,256,0.001"), "set_safe_margin", "get_safe_margin");
BIND_ENUM_CONSTANT(MOTION_MODE_GROUNDED);
- BIND_ENUM_CONSTANT(MOTION_MODE_FREE);
+ BIND_ENUM_CONSTANT(MOTION_MODE_FLOATING);
BIND_ENUM_CONSTANT(PLATFORM_VEL_ON_LEAVE_ALWAYS);
BIND_ENUM_CONSTANT(PLATFORM_VEL_ON_LEAVE_UPWARD_ONLY);
@@ -1783,12 +1781,12 @@ void CharacterBody2D::_bind_methods() {
}
void CharacterBody2D::_validate_property(PropertyInfo &property) const {
- if (motion_mode == MOTION_MODE_FREE) {
+ if (motion_mode == MOTION_MODE_FLOATING) {
if (property.name.begins_with("floor_") || property.name == "up_direction" || property.name == "slide_on_ceiling") {
property.usage = PROPERTY_USAGE_NO_EDITOR | PROPERTY_USAGE_INTERNAL;
}
} else {
- if (property.name == "free_mode_min_slide_angle") {
+ if (property.name == "wall_min_slide_angle") {
property.usage = PROPERTY_USAGE_NO_EDITOR | PROPERTY_USAGE_INTERNAL;
}
}
diff --git a/scene/2d/physics_body_2d.h b/scene/2d/physics_body_2d.h
index 649d67d759..f1cc100a58 100644
--- a/scene/2d/physics_body_2d.h
+++ b/scene/2d/physics_body_2d.h
@@ -328,7 +328,7 @@ class CharacterBody2D : public PhysicsBody2D {
public:
enum MotionMode {
MOTION_MODE_GROUNDED,
- MOTION_MODE_FREE,
+ MOTION_MODE_FLOATING,
};
enum MovingPlatformApplyVelocityOnLeave {
PLATFORM_VEL_ON_LEAVE_ALWAYS,
@@ -374,7 +374,7 @@ private:
int platform_layer = 0;
real_t floor_max_angle = Math::deg2rad((real_t)45.0);
real_t floor_snap_length = 1;
- real_t free_mode_min_slide_angle = Math::deg2rad((real_t)15.0);
+ real_t wall_min_slide_angle = Math::deg2rad((real_t)15.0);
Vector2 up_direction = Vector2(0.0, -1.0);
uint32_t moving_platform_floor_layers = UINT32_MAX;
uint32_t moving_platform_wall_layers = 0;
@@ -420,8 +420,8 @@ private:
real_t get_floor_snap_length();
void set_floor_snap_length(real_t p_floor_snap_length);
- real_t get_free_mode_min_slide_angle() const;
- void set_free_mode_min_slide_angle(real_t p_radians);
+ real_t get_wall_min_slide_angle() const;
+ void set_wall_min_slide_angle(real_t p_radians);
uint32_t get_moving_platform_floor_layers() const;
void set_moving_platform_floor_layers(const uint32_t p_exclude_layer);
@@ -435,7 +435,7 @@ private:
void set_moving_platform_apply_velocity_on_leave(MovingPlatformApplyVelocityOnLeave p_on_leave_velocity);
MovingPlatformApplyVelocityOnLeave get_moving_platform_apply_velocity_on_leave() const;
- void _move_and_slide_free(double p_delta);
+ void _move_and_slide_floating(double p_delta);
void _move_and_slide_grounded(double p_delta, bool p_was_on_floor);
Ref<KinematicCollision2D> _get_slide_collision(int p_bounce);
diff --git a/scene/2d/tile_map.cpp b/scene/2d/tile_map.cpp
index 5857b6710f..25c83b0c8f 100644
--- a/scene/2d/tile_map.cpp
+++ b/scene/2d/tile_map.cpp
@@ -2725,7 +2725,7 @@ void TileMap::_get_property_list(List<PropertyInfo> *p_list) const {
}
Vector2 TileMap::map_to_world(const Vector2i &p_pos) const {
- // SHOULD RETURN THE CENTER OF THE TILE
+ // SHOULD RETURN THE CENTER OF THE CELL
ERR_FAIL_COND_V(!tile_set.is_valid(), Vector2());
Vector2 ret = p_pos;
diff --git a/scene/3d/physics_body_3d.cpp b/scene/3d/physics_body_3d.cpp
index b3192a5bb5..1a707024c5 100644
--- a/scene/3d/physics_body_3d.cpp
+++ b/scene/3d/physics_body_3d.cpp
@@ -1233,7 +1233,7 @@ bool CharacterBody3D::move_and_slide() {
if (motion_mode == MOTION_MODE_GROUNDED) {
_move_and_slide_grounded(delta, was_on_floor);
} else {
- _move_and_slide_free(delta);
+ _move_and_slide_floating(delta);
}
// Compute real velocity.
@@ -1512,7 +1512,7 @@ void CharacterBody3D::_move_and_slide_grounded(double p_delta, bool p_was_on_flo
}
}
-void CharacterBody3D::_move_and_slide_free(double p_delta) {
+void CharacterBody3D::_move_and_slide_floating(double p_delta) {
Vector3 motion = motion_velocity * p_delta;
platform_rid = RID();
@@ -1929,7 +1929,7 @@ const Vector3 &CharacterBody3D::get_up_direction() const {
}
void CharacterBody3D::set_up_direction(const Vector3 &p_up_direction) {
- ERR_FAIL_COND_MSG(p_up_direction == Vector3(), "up_direction can't be equal to Vector3.ZERO, consider using Free motion mode instead.");
+ ERR_FAIL_COND_MSG(p_up_direction == Vector3(), "up_direction can't be equal to Vector3.ZERO, consider using Floating motion mode instead.");
up_direction = p_up_direction.normalized();
}
@@ -2000,12 +2000,11 @@ void CharacterBody3D::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_slide_collision", "slide_idx"), &CharacterBody3D::_get_slide_collision);
ClassDB::bind_method(D_METHOD("get_last_slide_collision"), &CharacterBody3D::_get_last_slide_collision);
- ADD_PROPERTY(PropertyInfo(Variant::INT, "motion_mode", PROPERTY_HINT_ENUM, "Grounded,Free", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_UPDATE_ALL_IF_MODIFIED), "set_motion_mode", "get_motion_mode");
+ ADD_PROPERTY(PropertyInfo(Variant::INT, "motion_mode", PROPERTY_HINT_ENUM, "Grounded,Floating", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_UPDATE_ALL_IF_MODIFIED), "set_motion_mode", "get_motion_mode");
ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "up_direction"), "set_up_direction", "get_up_direction");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "slide_on_ceiling"), "set_slide_on_ceiling_enabled", "is_slide_on_ceiling_enabled");
ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "motion_velocity", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NO_EDITOR), "set_motion_velocity", "get_motion_velocity");
ADD_PROPERTY(PropertyInfo(Variant::INT, "max_slides", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NO_EDITOR), "set_max_slides", "get_max_slides");
- ADD_GROUP("Free Mode", "free_mode_");
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "wall_min_slide_angle", PROPERTY_HINT_RANGE, "0,180,0.1,radians", PROPERTY_USAGE_DEFAULT), "set_wall_min_slide_angle", "get_wall_min_slide_angle");
ADD_GROUP("Floor", "floor_");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "floor_stop_on_slope"), "set_floor_stop_on_slope_enabled", "is_floor_stop_on_slope_enabled");
@@ -2020,7 +2019,7 @@ void CharacterBody3D::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "collision/safe_margin", PROPERTY_HINT_RANGE, "0.001,256,0.001"), "set_safe_margin", "get_safe_margin");
BIND_ENUM_CONSTANT(MOTION_MODE_GROUNDED);
- BIND_ENUM_CONSTANT(MOTION_MODE_FREE);
+ BIND_ENUM_CONSTANT(MOTION_MODE_FLOATING);
BIND_ENUM_CONSTANT(PLATFORM_VEL_ON_LEAVE_ALWAYS);
BIND_ENUM_CONSTANT(PLATFORM_VEL_ON_LEAVE_UPWARD_ONLY);
@@ -2028,7 +2027,7 @@ void CharacterBody3D::_bind_methods() {
}
void CharacterBody3D::_validate_property(PropertyInfo &property) const {
- if (motion_mode == MOTION_MODE_FREE) {
+ if (motion_mode == MOTION_MODE_FLOATING) {
if (property.name.begins_with("floor_") || property.name == "up_direction" || property.name == "slide_on_ceiling") {
property.usage = PROPERTY_USAGE_NO_EDITOR | PROPERTY_USAGE_INTERNAL;
}
diff --git a/scene/3d/physics_body_3d.h b/scene/3d/physics_body_3d.h
index e37b841117..65a763b21e 100644
--- a/scene/3d/physics_body_3d.h
+++ b/scene/3d/physics_body_3d.h
@@ -345,7 +345,7 @@ class CharacterBody3D : public PhysicsBody3D {
public:
enum MotionMode {
MOTION_MODE_GROUNDED,
- MOTION_MODE_FREE,
+ MOTION_MODE_FLOATING,
};
enum MovingPlatformApplyVelocityOnLeave {
PLATFORM_VEL_ON_LEAVE_ALWAYS,
@@ -468,7 +468,7 @@ private:
void set_moving_platform_apply_velocity_on_leave(MovingPlatformApplyVelocityOnLeave p_on_leave_velocity);
MovingPlatformApplyVelocityOnLeave get_moving_platform_apply_velocity_on_leave() const;
- void _move_and_slide_free(double p_delta);
+ void _move_and_slide_floating(double p_delta);
void _move_and_slide_grounded(double p_delta, bool p_was_on_floor);
Ref<KinematicCollision3D> _get_slide_collision(int p_bounce);
diff --git a/scene/gui/text_edit.cpp b/scene/gui/text_edit.cpp
index d6b449abd1..9b7a5b90d4 100644
--- a/scene/gui/text_edit.cpp
+++ b/scene/gui/text_edit.cpp
@@ -128,6 +128,10 @@ void TextEdit::Text::set_width(float p_width) {
width = p_width;
}
+float TextEdit::Text::get_width() const {
+ return width;
+}
+
int TextEdit::Text::get_line_wrap_amount(int p_line) const {
ERR_FAIL_INDEX_V(p_line, text.size(), 0);
@@ -646,6 +650,8 @@ void TextEdit::_notification(int p_what) {
}
}
+ bool draw_placeholder = text[0].length() == 0;
+
// Get the highlighted words.
String highlighted_text = get_selected_text();
@@ -656,7 +662,7 @@ void TextEdit::_notification(int p_what) {
int first_visible_line = get_first_visible_line() - 1;
int draw_amount = visible_rows + (smooth_scroll_enabled ? 1 : 0);
- draw_amount += get_line_wrap_count(first_visible_line + 1);
+ draw_amount += draw_placeholder ? placeholder_wraped_rows.size() - 1 : get_line_wrap_count(first_visible_line + 1);
// Draw minimap.
if (draw_minimap) {
@@ -841,7 +847,7 @@ void TextEdit::_notification(int p_what) {
// Draw main text.
caret.visible = false;
line_drawing_cache.clear();
- int row_height = get_line_height();
+ int row_height = draw_placeholder ? placeholder_line_height + line_spacing : get_line_height();
int line = first_visible_line;
for (int i = 0; i < draw_amount; i++) {
line++;
@@ -867,11 +873,14 @@ void TextEdit::_notification(int p_what) {
// Ensure we at least use the font color.
Color current_color = !editable ? font_readonly_color : font_color;
+ if (draw_placeholder) {
+ current_color.a *= placeholder_alpha;
+ }
- const Ref<TextParagraph> ldata = text.get_line_data(line);
+ const Ref<TextParagraph> ldata = draw_placeholder ? placeholder_data_buf : text.get_line_data(line);
- Vector<String> wrap_rows = get_line_wrapped_text(line);
- int line_wrap_amount = get_line_wrap_count(line);
+ Vector<String> wrap_rows = draw_placeholder ? placeholder_wraped_rows : get_line_wrapped_text(line);
+ int line_wrap_amount = draw_placeholder ? placeholder_wraped_rows.size() - 1 : get_line_wrap_count(line);
for (int line_wrap_index = 0; line_wrap_index <= line_wrap_amount; line_wrap_index++) {
if (line_wrap_index != 0) {
@@ -1385,7 +1394,9 @@ void TextEdit::_notification(int p_what) {
}
}
- line_drawing_cache[line] = cache_entry;
+ if (draw_placeholder) {
+ line_drawing_cache[line] = cache_entry;
+ }
}
if (has_focus()) {
@@ -2432,6 +2443,47 @@ void TextEdit::_move_caret_document_end(bool p_select) {
}
}
+void TextEdit::_update_placeholder() {
+ if (font.is_null() || font_size <= 0) {
+ return; // Not in tree?
+ }
+
+ // Placeholder is generally smaller then text docuemnts, and updates less so this should be fast enough for now.
+ placeholder_data_buf->clear();
+ placeholder_data_buf->set_width(text.get_width());
+ placeholder_data_buf->set_direction((TextServer::Direction)text_direction);
+ placeholder_data_buf->set_preserve_control(draw_control_chars);
+ placeholder_data_buf->add_string(placeholder_text, font, font_size, opentype_features, language);
+
+ placeholder_bidi_override = structured_text_parser(st_parser, st_args, placeholder_text);
+ if (placeholder_bidi_override.is_empty()) {
+ TS->shaped_text_set_bidi_override(placeholder_data_buf->get_rid(), placeholder_bidi_override);
+ }
+
+ if (get_tab_size() > 0) {
+ Vector<float> tabs;
+ tabs.push_back(font->get_char_size(' ', 0, font_size).width * get_tab_size());
+ placeholder_data_buf->tab_align(tabs);
+ }
+
+ // Update height.
+ const int wrap_amount = placeholder_data_buf->get_line_count() - 1;
+ placeholder_line_height = font->get_height(font_size);
+ for (int i = 0; i <= wrap_amount; i++) {
+ placeholder_line_height = MAX(placeholder_line_height, placeholder_data_buf->get_line_size(i).y);
+ }
+
+ // Update width.
+ placeholder_max_width = placeholder_data_buf->get_size().x;
+
+ // Update wrapped rows.
+ placeholder_wraped_rows.clear();
+ for (int i = 0; i <= wrap_amount; i++) {
+ Vector2i line_range = placeholder_data_buf->get_line_range(i);
+ placeholder_wraped_rows.push_back(placeholder_text.substr(line_range.x, line_range.y - line_range.x));
+ }
+}
+
void TextEdit::_update_caches() {
/* Internal API for CodeEdit. */
brace_mismatch_color = get_theme_color(SNAME("brace_mismatch_color"), SNAME("CodeEdit"));
@@ -2485,6 +2537,7 @@ void TextEdit::_update_caches() {
text.set_font(font);
text.set_font_size(font_size);
text.invalidate_all();
+ _update_placeholder();
/* Syntax highlighting. */
if (syntax_highlighter.is_valid()) {
@@ -2664,6 +2717,7 @@ void TextEdit::set_text_direction(Control::TextDirection p_text_direction) {
}
text.set_direction_and_language(dir, (!language.is_empty()) ? language : TranslationServer::get_singleton()->get_tool_locale());
text.invalidate_all();
+ _update_placeholder();
if (menu_dir) {
menu_dir->set_item_checked(menu_dir->get_item_index(MENU_DIR_INHERITED), text_direction == TEXT_DIRECTION_INHERITED);
@@ -2685,6 +2739,7 @@ void TextEdit::set_opentype_feature(const String &p_name, int p_value) {
opentype_features[tag] = p_value;
text.set_font_features(opentype_features);
text.invalidate_all();
+ _update_placeholder();
update();
}
}
@@ -2701,6 +2756,7 @@ void TextEdit::clear_opentype_features() {
opentype_features.clear();
text.set_font_features(opentype_features);
text.invalidate_all();
+ _update_placeholder();
update();
}
@@ -2715,6 +2771,7 @@ void TextEdit::set_language(const String &p_language) {
}
text.set_direction_and_language(dir, (!language.is_empty()) ? language : TranslationServer::get_singleton()->get_tool_locale());
text.invalidate_all();
+ _update_placeholder();
update();
}
}
@@ -2756,6 +2813,7 @@ void TextEdit::set_tab_size(const int p_size) {
}
text.set_tab_size(p_size);
text.invalidate_all_lines();
+ _update_placeholder();
update();
}
@@ -2878,6 +2936,25 @@ int TextEdit::get_line_count() const {
return text.size();
}
+void TextEdit::set_placeholder(const String &p_text) {
+ placeholder_text = p_text;
+ _update_placeholder();
+ update();
+}
+
+String TextEdit::get_placeholder() const {
+ return placeholder_text;
+}
+
+void TextEdit::set_placeholder_alpha(float p_alpha) {
+ placeholder_alpha = p_alpha;
+ update();
+}
+
+float TextEdit::get_placeholder_alpha() const {
+ return placeholder_alpha;
+}
+
void TextEdit::set_line(int p_line, const String &p_new_text) {
if (p_line < 0 || p_line >= text.size()) {
return;
@@ -4783,6 +4860,7 @@ void TextEdit::set_draw_control_chars(bool p_enabled) {
}
text.set_draw_control_chars(draw_control_chars);
text.invalidate_all();
+ _update_placeholder();
update();
}
}
@@ -4862,6 +4940,12 @@ void TextEdit::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_text"), &TextEdit::get_text);
ClassDB::bind_method(D_METHOD("get_line_count"), &TextEdit::get_line_count);
+ ClassDB::bind_method(D_METHOD("set_placeholder", "text"), &TextEdit::set_placeholder);
+ ClassDB::bind_method(D_METHOD("get_placeholder"), &TextEdit::get_placeholder);
+
+ ClassDB::bind_method(D_METHOD("set_placeholder_alpha", "alpha"), &TextEdit::set_placeholder_alpha);
+ ClassDB::bind_method(D_METHOD("get_placeholder_alpha"), &TextEdit::get_placeholder_alpha);
+
ClassDB::bind_method(D_METHOD("set_line", "line", "new_text"), &TextEdit::set_line);
ClassDB::bind_method(D_METHOD("get_line", "line"), &TextEdit::get_line);
@@ -5170,6 +5254,8 @@ void TextEdit::_bind_methods() {
/* Inspector */
ADD_PROPERTY(PropertyInfo(Variant::STRING, "text", PROPERTY_HINT_MULTILINE_TEXT), "set_text", "get_text");
+ ADD_PROPERTY(PropertyInfo(Variant::STRING, "placeholder_text", PROPERTY_HINT_MULTILINE_TEXT), "set_placeholder", "get_placeholder");
+ ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "placeholder_alpha", PROPERTY_HINT_RANGE, "0,1,0.001"), "set_placeholder_alpha", "get_placeholder_alpha");
ADD_PROPERTY(PropertyInfo(Variant::INT, "text_direction", PROPERTY_HINT_ENUM, "Auto,Left-to-Right,Right-to-Left,Inherited"), "set_text_direction", "get_text_direction");
ADD_PROPERTY(PropertyInfo(Variant::STRING, "language", PROPERTY_HINT_LOCALE_ID, ""), "set_language", "get_language");
@@ -5245,6 +5331,7 @@ bool TextEdit::_set(const StringName &p_name, const Variant &p_value) {
opentype_features.erase(tag);
text.set_font_features(opentype_features);
text.invalidate_all();
+ _update_placeholder();
update();
}
} else {
@@ -5252,6 +5339,7 @@ bool TextEdit::_set(const StringName &p_name, const Variant &p_value) {
opentype_features[tag] = value;
text.set_font_features(opentype_features);
text.invalidate_all();
+ _update_placeholder();
update();
}
}
@@ -5903,6 +5991,7 @@ void TextEdit::_update_wrap_at_column(bool p_force) {
text.set_width(-1);
}
text.invalidate_all_lines();
+ _update_placeholder();
}
_update_caret_wrap_offset();
@@ -5930,14 +6019,16 @@ void TextEdit::_update_scrollbars() {
h_scroll->set_begin(Point2(0, size.height - hmin.height));
h_scroll->set_end(Point2(size.width - vmin.width, size.height));
+ bool draw_placeholder = text[0].length() == 0;
+
int visible_rows = get_visible_line_count();
- int total_rows = get_total_visible_line_count();
+ int total_rows = draw_placeholder ? placeholder_wraped_rows.size() - 1 : get_total_visible_line_count();
if (scroll_past_end_of_file_enabled) {
total_rows += visible_rows - 1;
}
int visible_width = size.width - style_normal->get_minimum_size().width;
- int total_width = text.get_max_width() + vmin.x + gutters_width + gutter_padding;
+ int total_width = (draw_placeholder ? placeholder_max_width : text.get_max_width()) + vmin.x + gutters_width + gutter_padding;
if (draw_minimap) {
total_width += minimap_width;
@@ -6009,20 +6100,22 @@ void TextEdit::_scroll_moved(double p_to_val) {
}
if (v_scroll->is_visible_in_tree()) {
// Set line ofs and wrap ofs.
+ bool draw_placeholder = text[0].length() == 0;
+
int v_scroll_i = floor(get_v_scroll());
int sc = 0;
int n_line;
for (n_line = 0; n_line < text.size(); n_line++) {
if (!_is_line_hidden(n_line)) {
sc++;
- sc += get_line_wrap_count(n_line);
+ sc += draw_placeholder ? placeholder_wraped_rows.size() - 1 : get_line_wrap_count(n_line);
if (sc > v_scroll_i) {
break;
}
}
}
n_line = MIN(n_line, text.size() - 1);
- int line_wrap_amount = get_line_wrap_count(n_line);
+ int line_wrap_amount = (text[0].length() == 0) ? placeholder_wraped_rows.size() - 1 : get_line_wrap_count(n_line);
int wi = line_wrap_amount - (sc - v_scroll_i - 1);
wi = CLAMP(wi, 0, line_wrap_amount);
@@ -6450,6 +6543,8 @@ void TextEdit::_base_remove_text(int p_from_line, int p_from_column, int p_to_li
}
TextEdit::TextEdit() {
+ placeholder_data_buf.instantiate();
+
clear();
set_focus_mode(FOCUS_ALL);
_update_caches();
diff --git a/scene/gui/text_edit.h b/scene/gui/text_edit.h
index 0d0f4f6dba..fdaa928598 100644
--- a/scene/gui/text_edit.h
+++ b/scene/gui/text_edit.h
@@ -189,6 +189,7 @@ private:
int get_max_width() const;
void set_width(float p_width);
+ float get_width() const;
int get_line_wrap_amount(int p_line) const;
Vector<Vector2i> get_line_wrap_ranges(int p_line) const;
@@ -249,6 +250,19 @@ private:
String ime_text = "";
Point2 ime_selection;
+ // Placeholder
+ float placeholder_alpha = 0.6;
+
+ String placeholder_text = "";
+ Array placeholder_bidi_override;
+ Ref<TextParagraph> placeholder_data_buf;
+ int placeholder_line_height = -1;
+ int placeholder_max_width = -1;
+
+ Vector<String> placeholder_wraped_rows;
+
+ void _update_placeholder();
+
/* Initialise to opposite first, so we get past the early-out in set_editable. */
bool editable = false;
@@ -667,6 +681,12 @@ public:
String get_text() const;
int get_line_count() const;
+ void set_placeholder(const String &p_text);
+ String get_placeholder() const;
+
+ void set_placeholder_alpha(float p_alpha);
+ float get_placeholder_alpha() const;
+
void set_line(int p_line, const String &p_new_text);
String get_line(int p_line) const;
diff --git a/scene/main/http_request.cpp b/scene/main/http_request.cpp
index 34cc4aceb8..65d210983e 100644
--- a/scene/main/http_request.cpp
+++ b/scene/main/http_request.cpp
@@ -442,30 +442,25 @@ void HTTPRequest::_request_done(int p_status, int p_code, const PackedStringArra
is_compressed = false;
}
- const PackedByteArray *data = nullptr;
-
if (accept_gzip && is_compressed && p_data.size() > 0) {
// Decompress request body
- PackedByteArray *decompressed = memnew(PackedByteArray);
- int result = Compression::decompress_dynamic(decompressed, body_size_limit, p_data.ptr(), p_data.size(), mode);
+ PackedByteArray decompressed;
+ int result = Compression::decompress_dynamic(&decompressed, body_size_limit, p_data.ptr(), p_data.size(), mode);
if (result == OK) {
- data = decompressed;
+ emit_signal(SNAME("request_completed"), p_status, p_code, p_headers, decompressed);
+ return;
} else if (result == -5) {
WARN_PRINT("Decompressed size of HTTP response body exceeded body_size_limit");
p_status = RESULT_BODY_SIZE_LIMIT_EXCEEDED;
// Just return the raw data if we failed to decompress it
- data = &p_data;
} else {
WARN_PRINT("Failed to decompress HTTP response body");
p_status = RESULT_BODY_DECOMPRESS_FAILED;
// Just return the raw data if we failed to decompress it
- data = &p_data;
}
- } else {
- data = &p_data;
}
- emit_signal(SNAME("request_completed"), p_status, p_code, p_headers, *data);
+ emit_signal(SNAME("request_completed"), p_status, p_code, p_headers, p_data);
}
void HTTPRequest::_notification(int p_what) {
diff --git a/scene/main/viewport.cpp b/scene/main/viewport.cpp
index b94d109785..1244e0c028 100644
--- a/scene/main/viewport.cpp
+++ b/scene/main/viewport.cpp
@@ -523,6 +523,13 @@ void Viewport::_process_picking() {
_drop_physics_mouseover(true);
+#ifndef _3D_DISABLED
+ Vector2 last_pos(1e20, 1e20);
+ CollisionObject3D *last_object = nullptr;
+ ObjectID last_id;
+ PhysicsDirectSpaceState3D::RayResult result;
+#endif // _3D_DISABLED
+
PhysicsDirectSpaceState2D *ss2d = PhysicsServer2D::get_singleton()->space_get_direct_state(find_world_2d()->get_space());
if (physics_has_last_mousepos) {
@@ -690,10 +697,6 @@ void Viewport::_process_picking() {
}
#ifndef _3D_DISABLED
- Vector2 last_pos(1e20, 1e20);
- CollisionObject3D *last_object = nullptr;
- ObjectID last_id;
- PhysicsDirectSpaceState3D::RayResult result;
bool captured = false;
if (physics_object_capture.is_valid()) {
diff --git a/servers/rendering/renderer_rd/renderer_scene_render_rd.cpp b/servers/rendering/renderer_rd/renderer_scene_render_rd.cpp
index 126f40584a..deaf613836 100644
--- a/servers/rendering/renderer_rd/renderer_scene_render_rd.cpp
+++ b/servers/rendering/renderer_rd/renderer_scene_render_rd.cpp
@@ -1132,11 +1132,11 @@ bool RendererSceneRenderRD::_shadow_atlas_find_omni_shadows(ShadowAtlas *shadow_
return false;
}
-bool RendererSceneRenderRD::shadow_atlas_update_light(RID p_atlas, RID p_light_intance, float p_coverage, uint64_t p_light_version) {
+bool RendererSceneRenderRD::shadow_atlas_update_light(RID p_atlas, RID p_light_instance, float p_coverage, uint64_t p_light_version) {
ShadowAtlas *shadow_atlas = shadow_atlas_owner.get_or_null(p_atlas);
ERR_FAIL_COND_V(!shadow_atlas, false);
- LightInstance *li = light_instance_owner.get_or_null(p_light_intance);
+ LightInstance *li = light_instance_owner.get_or_null(p_light_instance);
ERR_FAIL_COND_V(!li, false);
if (shadow_atlas->size == 0 || shadow_atlas->smallest_subdiv == 0) {
@@ -1185,8 +1185,8 @@ bool RendererSceneRenderRD::shadow_atlas_update_light(RID p_atlas, RID p_light_i
bool should_realloc = false;
bool should_redraw = false;
- if (shadow_atlas->shadow_owners.has(p_light_intance)) {
- old_key = shadow_atlas->shadow_owners[p_light_intance];
+ if (shadow_atlas->shadow_owners.has(p_light_instance)) {
+ old_key = shadow_atlas->shadow_owners[p_light_instance];
old_quadrant = (old_key >> ShadowAtlas::QUADRANT_SHIFT) & 0x3;
old_shadow = old_key & ShadowAtlas::SHADOW_INDEX_MASK;
@@ -1230,7 +1230,7 @@ bool RendererSceneRenderRD::shadow_atlas_update_light(RID p_atlas, RID p_light_i
ShadowAtlas::Quadrant::Shadow *sh = &shadow_atlas->quadrants[new_quadrant].shadows.write[new_shadow];
_shadow_atlas_invalidate_shadow(sh, p_atlas, shadow_atlas, new_quadrant, new_shadow);
- sh->owner = p_light_intance;
+ sh->owner = p_light_instance;
sh->alloc_tick = tick;
sh->version = p_light_version;
@@ -1241,7 +1241,7 @@ bool RendererSceneRenderRD::shadow_atlas_update_light(RID p_atlas, RID p_light_i
ShadowAtlas::Quadrant::Shadow *extra_sh = &shadow_atlas->quadrants[new_quadrant].shadows.write[new_omni_shadow];
_shadow_atlas_invalidate_shadow(extra_sh, p_atlas, shadow_atlas, new_quadrant, new_omni_shadow);
- extra_sh->owner = p_light_intance;
+ extra_sh->owner = p_light_instance;
extra_sh->alloc_tick = tick;
extra_sh->version = p_light_version;
}
@@ -1249,7 +1249,7 @@ bool RendererSceneRenderRD::shadow_atlas_update_light(RID p_atlas, RID p_light_i
li->shadow_atlases.insert(p_atlas);
//update it in map
- shadow_atlas->shadow_owners[p_light_intance] = new_key;
+ shadow_atlas->shadow_owners[p_light_instance] = new_key;
//make it dirty, as it should redraw anyway
return true;
}
@@ -1270,10 +1270,10 @@ void RendererSceneRenderRD::_shadow_atlas_invalidate_shadow(RendererSceneRenderR
omni_shadow->owner = RID();
}
+ p_shadow_atlas->shadow_owners.erase(p_shadow->owner);
p_shadow->version = 0;
p_shadow->owner = RID();
sli->shadow_atlases.erase(p_atlas);
- p_shadow_atlas->shadow_owners.erase(p_shadow->owner);
}
}
@@ -2636,8 +2636,12 @@ void RendererSceneRenderRD::_render_buffers_debug_draw(RID p_render_buffers, RID
if (debug_draw == RS::VIEWPORT_DEBUG_DRAW_SHADOW_ATLAS) {
if (p_shadow_atlas.is_valid()) {
RID shadow_atlas_texture = shadow_atlas_get_texture(p_shadow_atlas);
- Size2 rtsize = storage->render_target_get_size(rb->render_target);
+ if (shadow_atlas_texture.is_null()) {
+ shadow_atlas_texture = storage->texture_rd_get_default(RendererStorageRD::DEFAULT_RD_TEXTURE_BLACK);
+ }
+
+ Size2 rtsize = storage->render_target_get_size(rb->render_target);
effects->copy_to_fb_rect(shadow_atlas_texture, storage->render_target_get_rd_framebuffer(rb->render_target), Rect2i(Vector2(), rtsize / 2), false, true);
}
}
diff --git a/servers/rendering/renderer_rd/renderer_scene_render_rd.h b/servers/rendering/renderer_rd/renderer_scene_render_rd.h
index 276cb8f229..592618ae05 100644
--- a/servers/rendering/renderer_rd/renderer_scene_render_rd.h
+++ b/servers/rendering/renderer_rd/renderer_scene_render_rd.h
@@ -983,7 +983,7 @@ public:
virtual RID shadow_atlas_create() override;
virtual void shadow_atlas_set_size(RID p_atlas, int p_size, bool p_16_bits = false) override;
virtual void shadow_atlas_set_quadrant_subdivision(RID p_atlas, int p_quadrant, int p_subdivision) override;
- virtual bool shadow_atlas_update_light(RID p_atlas, RID p_light_intance, float p_coverage, uint64_t p_light_version) override;
+ virtual bool shadow_atlas_update_light(RID p_atlas, RID p_light_instance, float p_coverage, uint64_t p_light_version) override;
_FORCE_INLINE_ bool shadow_atlas_owns_light_instance(RID p_atlas, RID p_light_intance) {
ShadowAtlas *atlas = shadow_atlas_owner.get_or_null(p_atlas);
ERR_FAIL_COND_V(!atlas, false);
diff --git a/servers/rendering/shader_language.cpp b/servers/rendering/shader_language.cpp
index cb1329d33c..f16f66544a 100644
--- a/servers/rendering/shader_language.cpp
+++ b/servers/rendering/shader_language.cpp
@@ -9060,6 +9060,19 @@ Error ShaderLanguage::complete(const String &p_code, const ShaderCompileInfo &p_
} break;
case COMPLETION_MAIN_FUNCTION: {
for (const KeyValue<StringName, FunctionInfo> &E : p_info.functions) {
+ if (!E.value.main_function) {
+ continue;
+ }
+ bool found = false;
+ for (int i = 0; i < shader->functions.size(); i++) {
+ if (shader->functions[i].name == E.key) {
+ found = true;
+ break;
+ }
+ }
+ if (found) {
+ continue;
+ }
ScriptCodeCompletionOption option(E.key, ScriptCodeCompletionOption::KIND_FUNCTION);
r_options->push_back(option);
}