summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--doc/classes/EditorInspector.xml2
-rw-r--r--doc/classes/LineEdit.xml2
-rw-r--r--doc/classes/Mesh.xml3
-rw-r--r--editor/groups_editor.cpp2
-rw-r--r--editor/plugins/skeleton_editor_plugin.cpp9
-rw-r--r--modules/mono/glue/GodotSharp/GodotSharp/Core/Color.cs28
-rw-r--r--platform/android/os_android.cpp3
-rw-r--r--scene/3d/physics_body.cpp114
-rw-r--r--scene/3d/physics_body.h12
-rw-r--r--scene/3d/skeleton.cpp63
-rw-r--r--scene/3d/skeleton.h4
-rw-r--r--scene/gui/line_edit.cpp6
-rw-r--r--scene/gui/rich_text_label.cpp15
-rw-r--r--scene/gui/tree.cpp13
-rw-r--r--scene/gui/tree.h3
-rw-r--r--scene/resources/mesh.cpp1
-rw-r--r--thirdparty/README.md1
-rw-r--r--thirdparty/miniupnpc/miniupnpc/minissdpc.c4
-rw-r--r--thirdparty/miniupnpc/windows_fix.diff16
19 files changed, 176 insertions, 125 deletions
diff --git a/doc/classes/EditorInspector.xml b/doc/classes/EditorInspector.xml
index 7834390247..61d240c1dc 100644
--- a/doc/classes/EditorInspector.xml
+++ b/doc/classes/EditorInspector.xml
@@ -1,8 +1,10 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="EditorInspector" inherits="ScrollContainer" version="4.0">
<brief_description>
+ A tab used to edit properties of the selected node.
</brief_description>
<description>
+ The editor inspector is by default located on the right-hand side of the editor. It's used to edit the properties of the selected node. For example, you can select a node such as the Sprite2D then edit its transform through the inspector tool. The editor inspector is an essential tool in the game development workflow.
</description>
<tutorials>
</tutorials>
diff --git a/doc/classes/LineEdit.xml b/doc/classes/LineEdit.xml
index 512401d2de..f2574360cb 100644
--- a/doc/classes/LineEdit.xml
+++ b/doc/classes/LineEdit.xml
@@ -22,6 +22,8 @@
- Ctrl + N: Like the down arrow key, move the cursor to the next line
- Ctrl + D: Like the Delete key, delete the character on the right side of cursor
- Ctrl + H: Like the Backspace key, delete the character on the left side of the cursor
+ - Ctrl + A: Like the Home key, move the cursor to the beginning of the line
+ - Ctrl + E: Like the End key, move the cursor to the end of the line
- Command + Left arrow: Like the Home key, move the cursor to the beginning of the line
- Command + Right arrow: Like the End key, move the cursor to the end of the line
</description>
diff --git a/doc/classes/Mesh.xml b/doc/classes/Mesh.xml
index b2d979239c..67b6045152 100644
--- a/doc/classes/Mesh.xml
+++ b/doc/classes/Mesh.xml
@@ -161,9 +161,6 @@
<constant name="ARRAY_FORMAT_INDEX" value="256" enum="ArrayFormat">
Mesh array uses indices.
</constant>
- <constant name="ARRAY_COMPRESS_BASE" value="9" enum="ArrayFormat">
- Used internally to calculate other [code]ARRAY_COMPRESS_*[/code] enum values. Do not use.
- </constant>
<constant name="ARRAY_COMPRESS_VERTEX" value="512" enum="ArrayFormat">
Flag used to mark a compressed (half float) vertex array.
</constant>
diff --git a/editor/groups_editor.cpp b/editor/groups_editor.cpp
index 83259afb35..c76ff9d679 100644
--- a/editor/groups_editor.cpp
+++ b/editor/groups_editor.cpp
@@ -197,7 +197,7 @@ void GroupDialog::_add_group(String p_name) {
}
String name = p_name.strip_edges();
- if (name == "" || groups->search_item_text(name)) {
+ if (name.empty() || groups->get_item_with_text(name)) {
return;
}
diff --git a/editor/plugins/skeleton_editor_plugin.cpp b/editor/plugins/skeleton_editor_plugin.cpp
index 8b5fe7d2c5..9101c64eab 100644
--- a/editor/plugins/skeleton_editor_plugin.cpp
+++ b/editor/plugins/skeleton_editor_plugin.cpp
@@ -103,8 +103,10 @@ void SkeletonEditor::create_physical_skeleton() {
PhysicalBone *SkeletonEditor::create_physical_bone(int bone_id, int bone_child_id, const Vector<BoneInfo> &bones_infos) {
- real_t half_height(skeleton->get_bone_rest(bone_child_id).origin.length() * 0.5);
- real_t radius(half_height * 0.2);
+ const Transform child_rest = skeleton->get_bone_rest(bone_child_id);
+
+ const real_t half_height(child_rest.origin.length() * 0.5);
+ const real_t radius(half_height * 0.2);
CapsuleShape *bone_shape_capsule = memnew(CapsuleShape);
bone_shape_capsule->set_height((half_height - radius) * 2);
@@ -114,7 +116,8 @@ PhysicalBone *SkeletonEditor::create_physical_bone(int bone_id, int bone_child_i
bone_shape->set_shape(bone_shape_capsule);
Transform body_transform;
- body_transform.origin = Vector3(0, 0, -half_height);
+ body_transform.set_look_at(Vector3(0, 0, 0), child_rest.origin, Vector3(0, 1, 0));
+ body_transform.origin = body_transform.basis.xform(Vector3(0, 0, -half_height));
Transform joint_transform;
joint_transform.origin = Vector3(0, 0, half_height);
diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/Color.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/Color.cs
index 0462ef1125..1d1a49945f 100644
--- a/modules/mono/glue/GodotSharp/GodotSharp/Core/Color.cs
+++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/Color.cs
@@ -318,9 +318,9 @@ namespace Godot
return res;
}
- public int ToAbgr32()
+ public uint ToAbgr32()
{
- int c = (byte)Math.Round(a * 255);
+ uint c = (byte)Math.Round(a * 255);
c <<= 8;
c |= (byte)Math.Round(b * 255);
c <<= 8;
@@ -331,9 +331,9 @@ namespace Godot
return c;
}
- public long ToAbgr64()
+ public ulong ToAbgr64()
{
- long c = (ushort)Math.Round(a * 65535);
+ ulong c = (ushort)Math.Round(a * 65535);
c <<= 16;
c |= (ushort)Math.Round(b * 65535);
c <<= 16;
@@ -344,9 +344,9 @@ namespace Godot
return c;
}
- public int ToArgb32()
+ public uint ToArgb32()
{
- int c = (byte)Math.Round(a * 255);
+ uint c = (byte)Math.Round(a * 255);
c <<= 8;
c |= (byte)Math.Round(r * 255);
c <<= 8;
@@ -357,9 +357,9 @@ namespace Godot
return c;
}
- public long ToArgb64()
+ public ulong ToArgb64()
{
- long c = (ushort)Math.Round(a * 65535);
+ ulong c = (ushort)Math.Round(a * 65535);
c <<= 16;
c |= (ushort)Math.Round(r * 65535);
c <<= 16;
@@ -370,9 +370,9 @@ namespace Godot
return c;
}
- public int ToRgba32()
+ public uint ToRgba32()
{
- int c = (byte)Math.Round(r * 255);
+ uint c = (byte)Math.Round(r * 255);
c <<= 8;
c |= (byte)Math.Round(g * 255);
c <<= 8;
@@ -383,9 +383,9 @@ namespace Godot
return c;
}
- public long ToRgba64()
+ public ulong ToRgba64()
{
- long c = (ushort)Math.Round(r * 65535);
+ ulong c = (ushort)Math.Round(r * 65535);
c <<= 16;
c |= (ushort)Math.Round(g * 65535);
c <<= 16;
@@ -419,7 +419,7 @@ namespace Godot
this.a = a;
}
- public Color(int rgba)
+ public Color(uint rgba)
{
a = (rgba & 0xFF) / 255.0f;
rgba >>= 8;
@@ -430,7 +430,7 @@ namespace Godot
r = (rgba & 0xFF) / 255.0f;
}
- public Color(long rgba)
+ public Color(ulong rgba)
{
a = (rgba & 0xFFFF) / 65535.0f;
rgba >>= 16;
diff --git a/platform/android/os_android.cpp b/platform/android/os_android.cpp
index 44c5b5d6b4..e5d9bdc60c 100644
--- a/platform/android/os_android.cpp
+++ b/platform/android/os_android.cpp
@@ -507,9 +507,8 @@ void OS_Android::process_double_tap(Point2 p_pos) {
ev.instance();
ev->set_position(p_pos);
ev->set_global_position(p_pos);
- ev->set_pressed(true);
+ ev->set_pressed(false);
ev->set_doubleclick(true);
- ev->set_button_index(1);
input->parse_input_event(ev);
}
diff --git a/scene/3d/physics_body.cpp b/scene/3d/physics_body.cpp
index caeae90238..a1a221b5bb 100644
--- a/scene/3d/physics_body.cpp
+++ b/scene/3d/physics_body.cpp
@@ -1562,6 +1562,24 @@ void PhysicalBone::apply_impulse(const Vector3 &p_pos, const Vector3 &p_impulse)
PhysicsServer::get_singleton()->body_apply_impulse(get_rid(), p_pos, p_impulse);
}
+void PhysicalBone::reset_physics_simulation_state() {
+ if (simulate_physics) {
+ _start_physics_simulation();
+ } else {
+ _stop_physics_simulation();
+ }
+}
+
+void PhysicalBone::reset_to_rest_position() {
+ if (parent_skeleton) {
+ if (-1 == bone_id) {
+ set_global_transform(parent_skeleton->get_global_transform() * body_offset);
+ } else {
+ set_global_transform(parent_skeleton->get_global_transform() * parent_skeleton->get_bone_global_pose(bone_id) * body_offset);
+ }
+ }
+}
+
bool PhysicalBone::PinJointData::_set(const StringName &p_name, const Variant &p_value, RID j) {
if (JointData::_set(p_name, p_value, j)) {
return true;
@@ -2167,7 +2185,7 @@ void PhysicalBone::_notification(int p_what) {
parent_skeleton = find_skeleton_parent(get_parent());
update_bone_id();
reset_to_rest_position();
- _reset_physics_simulation_state();
+ reset_physics_simulation_state();
if (!joint.is_valid() && joint_data) {
_reload_joint();
}
@@ -2238,8 +2256,6 @@ void PhysicalBone::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_body_offset", "offset"), &PhysicalBone::set_body_offset);
ClassDB::bind_method(D_METHOD("get_body_offset"), &PhysicalBone::get_body_offset);
- ClassDB::bind_method(D_METHOD("is_static_body"), &PhysicalBone::is_static_body);
-
ClassDB::bind_method(D_METHOD("get_simulate_physics"), &PhysicalBone::get_simulate_physics);
ClassDB::bind_method(D_METHOD("is_simulating_physics"), &PhysicalBone::is_simulating_physics);
@@ -2508,26 +2524,13 @@ const Transform &PhysicalBone::get_joint_offset() const {
return joint_offset;
}
-void PhysicalBone::set_static_body(bool p_static) {
-
- static_body = p_static;
-
- set_as_toplevel(!static_body);
-
- _reset_physics_simulation_state();
-}
-
-bool PhysicalBone::is_static_body() {
- return static_body;
-}
-
void PhysicalBone::set_simulate_physics(bool p_simulate) {
if (simulate_physics == p_simulate) {
return;
}
simulate_physics = p_simulate;
- _reset_physics_simulation_state();
+ reset_physics_simulation_state();
}
bool PhysicalBone::get_simulate_physics() {
@@ -2535,7 +2538,7 @@ bool PhysicalBone::get_simulate_physics() {
}
bool PhysicalBone::is_simulating_physics() {
- return _internal_simulate_physics && !_internal_static_body;
+ return _internal_simulate_physics;
}
void PhysicalBone::set_bone_name(const String &p_name) {
@@ -2618,8 +2621,6 @@ PhysicalBone::PhysicalBone() :
#endif
joint_data(NULL),
parent_skeleton(NULL),
- static_body(false),
- _internal_static_body(false),
simulate_physics(false),
_internal_simulate_physics(false),
bone_id(-1),
@@ -2629,8 +2630,7 @@ PhysicalBone::PhysicalBone() :
friction(1),
gravity_scale(1) {
- set_static_body(static_body);
- _reset_physics_simulation_state();
+ reset_physics_simulation_state();
}
PhysicalBone::~PhysicalBone() {
@@ -2657,8 +2657,7 @@ void PhysicalBone::update_bone_id() {
parent_skeleton->bind_physical_bone_to_bone(bone_id, this);
_fix_joint_offset();
- _internal_static_body = !static_body; // Force staticness reset
- _reset_staticness_state();
+ reset_physics_simulation_state();
}
}
@@ -2680,49 +2679,6 @@ void PhysicalBone::update_offset() {
#endif
}
-void PhysicalBone::reset_to_rest_position() {
- if (parent_skeleton) {
- if (-1 == bone_id) {
- set_global_transform(parent_skeleton->get_global_transform() * body_offset);
- } else {
- set_global_transform(parent_skeleton->get_global_transform() * parent_skeleton->get_bone_global_pose(bone_id) * body_offset);
- }
- }
-}
-
-void PhysicalBone::_reset_physics_simulation_state() {
- if (simulate_physics && !static_body) {
- _start_physics_simulation();
- } else {
- _stop_physics_simulation();
- }
-
- _reset_staticness_state();
-}
-
-void PhysicalBone::_reset_staticness_state() {
-
- if (parent_skeleton && -1 != bone_id) {
- if (static_body && simulate_physics) { // With this check I'm sure the position of this body is updated only when it's necessary
-
- if (_internal_static_body) {
- return;
- }
-
- parent_skeleton->bind_child_node_to_bone(bone_id, this);
- _internal_static_body = true;
- } else {
-
- if (!_internal_static_body) {
- return;
- }
-
- parent_skeleton->unbind_child_node_from_bone(bone_id, this);
- _internal_static_body = false;
- }
- }
-}
-
void PhysicalBone::_start_physics_simulation() {
if (_internal_simulate_physics || !parent_skeleton) {
return;
@@ -2732,17 +2688,27 @@ void PhysicalBone::_start_physics_simulation() {
PhysicsServer::get_singleton()->body_set_collision_layer(get_rid(), get_collision_layer());
PhysicsServer::get_singleton()->body_set_collision_mask(get_rid(), get_collision_mask());
PhysicsServer::get_singleton()->body_set_force_integration_callback(get_rid(), this, "_direct_state_changed");
+ set_as_toplevel(true);
_internal_simulate_physics = true;
}
void PhysicalBone::_stop_physics_simulation() {
- if (!_internal_simulate_physics || !parent_skeleton) {
+ if (!parent_skeleton) {
return;
}
- PhysicsServer::get_singleton()->body_set_mode(get_rid(), PhysicsServer::BODY_MODE_STATIC);
- PhysicsServer::get_singleton()->body_set_collision_layer(get_rid(), 0);
- PhysicsServer::get_singleton()->body_set_collision_mask(get_rid(), 0);
- PhysicsServer::get_singleton()->body_set_force_integration_callback(get_rid(), NULL, "");
- parent_skeleton->set_bone_global_pose_override(bone_id, Transform(), 0.0, false);
- _internal_simulate_physics = false;
+ if (parent_skeleton->get_animate_physical_bones()) {
+ PhysicsServer::get_singleton()->body_set_mode(get_rid(), PhysicsServer::BODY_MODE_KINEMATIC);
+ PhysicsServer::get_singleton()->body_set_collision_layer(get_rid(), get_collision_layer());
+ PhysicsServer::get_singleton()->body_set_collision_mask(get_rid(), get_collision_mask());
+ } else {
+ PhysicsServer::get_singleton()->body_set_mode(get_rid(), PhysicsServer::BODY_MODE_STATIC);
+ PhysicsServer::get_singleton()->body_set_collision_layer(get_rid(), 0);
+ PhysicsServer::get_singleton()->body_set_collision_mask(get_rid(), 0);
+ }
+ if (_internal_simulate_physics) {
+ PhysicsServer::get_singleton()->body_set_force_integration_callback(get_rid(), NULL, "");
+ parent_skeleton->set_bone_global_pose_override(bone_id, Transform(), 0.0, false);
+ set_as_toplevel(false);
+ _internal_simulate_physics = false;
+ }
}
diff --git a/scene/3d/physics_body.h b/scene/3d/physics_body.h
index 05bcbe22f0..6a1e803eaf 100644
--- a/scene/3d/physics_body.h
+++ b/scene/3d/physics_body.h
@@ -562,8 +562,6 @@ private:
Skeleton *parent_skeleton;
Transform body_offset;
Transform body_offset_inverse;
- bool static_body;
- bool _internal_static_body;
bool simulate_physics;
bool _internal_simulate_physics;
int bone_id;
@@ -613,9 +611,6 @@ public:
void set_body_offset(const Transform &p_offset);
const Transform &get_body_offset() const;
- void set_static_body(bool p_static);
- bool is_static_body();
-
void set_simulate_physics(bool p_simulate);
bool get_simulate_physics();
bool is_simulating_physics();
@@ -641,16 +636,15 @@ public:
void apply_central_impulse(const Vector3 &p_impulse);
void apply_impulse(const Vector3 &p_pos, const Vector3 &p_impulse);
+ void reset_physics_simulation_state();
+ void reset_to_rest_position();
+
PhysicalBone();
~PhysicalBone();
private:
void update_bone_id();
void update_offset();
- void reset_to_rest_position();
-
- void _reset_physics_simulation_state();
- void _reset_staticness_state();
void _start_physics_simulation();
void _stop_physics_simulation();
diff --git a/scene/3d/skeleton.cpp b/scene/3d/skeleton.cpp
index 17e67c47d1..4089e0c23b 100644
--- a/scene/3d/skeleton.cpp
+++ b/scene/3d/skeleton.cpp
@@ -32,6 +32,7 @@
#include "core/message_queue.h"
+#include "core/engine.h"
#include "core/project_settings.h"
#include "scene/3d/physics_body.h"
#include "scene/resources/surface_tool.h"
@@ -332,6 +333,27 @@ void Skeleton::_notification(int p_what) {
dirty = false;
} break;
+
+#ifndef _3D_DISABLED
+ case NOTIFICATION_INTERNAL_PHYSICS_PROCESS: {
+ // This is active only if the skeleton animates the physical bones
+ // and the state of the bone is not active.
+ if (animate_physical_bones) {
+ for (int i = 0; i < bones.size(); i += 1) {
+ if (bones[i].physical_bone) {
+ if (bones[i].physical_bone->is_simulating_physics() == false) {
+ bones[i].physical_bone->reset_to_rest_position();
+ }
+ }
+ }
+ }
+ } break;
+ case NOTIFICATION_READY: {
+ if (Engine::get_singleton()->is_editor_hint()) {
+ set_physics_process_internal(true);
+ }
+ } break;
+#endif
}
}
@@ -584,6 +606,27 @@ void Skeleton::localize_rests() {
#ifndef _3D_DISABLED
+void Skeleton::set_animate_physical_bones(bool p_animate) {
+ animate_physical_bones = p_animate;
+
+ if (Engine::get_singleton()->is_editor_hint() == false) {
+ bool sim = false;
+ for (int i = 0; i < bones.size(); i += 1) {
+ if (bones[i].physical_bone) {
+ bones[i].physical_bone->reset_physics_simulation_state();
+ if (bones[i].physical_bone->is_simulating_physics()) {
+ sim = true;
+ }
+ }
+ }
+ set_physics_process_internal(sim == false && p_animate);
+ }
+}
+
+bool Skeleton::get_animate_physical_bones() const {
+ return animate_physical_bones;
+}
+
void Skeleton::bind_physical_bone_to_bone(int p_bone, PhysicalBone *p_physical_bone) {
ERR_FAIL_INDEX(p_bone, bones.size());
ERR_FAIL_COND(bones[p_bone].physical_bone);
@@ -653,12 +696,14 @@ void _pb_stop_simulation(Node *p_node) {
PhysicalBone *pb = Object::cast_to<PhysicalBone>(p_node);
if (pb) {
pb->set_simulate_physics(false);
- pb->set_static_body(false);
}
}
void Skeleton::physical_bones_stop_simulation() {
_pb_stop_simulation(this);
+ if (Engine::get_singleton()->is_editor_hint() == false && animate_physical_bones) {
+ set_physics_process_internal(true);
+ }
}
void _pb_start_simulation(const Skeleton *p_skeleton, Node *p_node, const Vector<int> &p_sim_bones) {
@@ -669,24 +714,17 @@ void _pb_start_simulation(const Skeleton *p_skeleton, Node *p_node, const Vector
PhysicalBone *pb = Object::cast_to<PhysicalBone>(p_node);
if (pb) {
- bool sim = false;
for (int i = p_sim_bones.size() - 1; 0 <= i; --i) {
if (p_sim_bones[i] == pb->get_bone_id() || p_skeleton->is_bone_parent_of(pb->get_bone_id(), p_sim_bones[i])) {
- sim = true;
+ pb->set_simulate_physics(true);
break;
}
}
-
- pb->set_simulate_physics(true);
- if (sim) {
- pb->set_static_body(false);
- } else {
- pb->set_static_body(true);
- }
}
}
void Skeleton::physical_bones_start_simulation_on(const Array &p_bones) {
+ set_physics_process_internal(false);
Vector<int> sim_bones;
if (p_bones.size() <= 0) {
@@ -836,11 +874,15 @@ void Skeleton::_bind_methods() {
#ifndef _3D_DISABLED
+ ClassDB::bind_method(D_METHOD("set_animate_physical_bones"), &Skeleton::set_animate_physical_bones);
+ ClassDB::bind_method(D_METHOD("get_animate_physical_bones"), &Skeleton::get_animate_physical_bones);
+
ClassDB::bind_method(D_METHOD("physical_bones_stop_simulation"), &Skeleton::physical_bones_stop_simulation);
ClassDB::bind_method(D_METHOD("physical_bones_start_simulation", "bones"), &Skeleton::physical_bones_start_simulation_on, DEFVAL(Array()));
ClassDB::bind_method(D_METHOD("physical_bones_add_collision_exception", "exception"), &Skeleton::physical_bones_add_collision_exception);
ClassDB::bind_method(D_METHOD("physical_bones_remove_collision_exception", "exception"), &Skeleton::physical_bones_remove_collision_exception);
+ ADD_PROPERTY(PropertyInfo(Variant::BOOL, "animate_physical_bones"), "set_animate_physical_bones", "get_animate_physical_bones");
#endif // _3D_DISABLED
BIND_CONSTANT(NOTIFICATION_UPDATE_SKELETON);
@@ -848,6 +890,7 @@ void Skeleton::_bind_methods() {
Skeleton::Skeleton() {
+ animate_physical_bones = true;
dirty = false;
process_order_dirty = true;
}
diff --git a/scene/3d/skeleton.h b/scene/3d/skeleton.h
index 056f70e22b..9599510850 100644
--- a/scene/3d/skeleton.h
+++ b/scene/3d/skeleton.h
@@ -115,6 +115,7 @@ private:
}
};
+ bool animate_physical_bones;
Vector<Bone> bones;
Vector<int> process_order;
bool process_order_dirty;
@@ -199,6 +200,9 @@ public:
#ifndef _3D_DISABLED
// Physical bone API
+ void set_animate_physical_bones(bool p_animate);
+ bool get_animate_physical_bones() const;
+
void bind_physical_bone_to_bone(int p_bone, PhysicalBone *p_physical_bone);
void unbind_physical_bone_from_bone(int p_bone);
diff --git a/scene/gui/line_edit.cpp b/scene/gui/line_edit.cpp
index 7cc47d351e..2504989d2c 100644
--- a/scene/gui/line_edit.cpp
+++ b/scene/gui/line_edit.cpp
@@ -184,6 +184,12 @@ void LineEdit::_gui_input(Ref<InputEvent> p_event) {
case KEY_H: {
remap_key = KEY_BACKSPACE;
} break;
+ case KEY_A: {
+ remap_key = KEY_HOME;
+ } break;
+ case KEY_E: {
+ remap_key = KEY_END;
+ } break;
}
if (remap_key != KEY_UNKNOWN) {
diff --git a/scene/gui/rich_text_label.cpp b/scene/gui/rich_text_label.cpp
index af5d0e2f45..b19e1d8362 100644
--- a/scene/gui/rich_text_label.cpp
+++ b/scene/gui/rich_text_label.cpp
@@ -204,6 +204,8 @@ int RichTextLabel::_process_line(ItemFrame *p_frame, const Vector2 &p_ofs, int &
int line_ascent = cfont->get_ascent();
int line_descent = cfont->get_descent();
+ int backtrack = 0; // for dynamic hidden content.
+
int nonblank_line_count = 0; //number of nonblank lines as counted during PROCESS_DRAW
Variant meta;
@@ -214,6 +216,7 @@ int RichTextLabel::_process_line(ItemFrame *p_frame, const Vector2 &p_ofs, int &
{ \
if (p_mode != PROCESS_CACHE) { \
line++; \
+ backtrack = 0; \
if (!line_is_blank) { \
nonblank_line_count++; \
} \
@@ -263,7 +266,7 @@ int RichTextLabel::_process_line(ItemFrame *p_frame, const Vector2 &p_ofs, int &
l.maximum_width = MAX(l.maximum_width, MIN(p_width, wofs + m_width)); \
l.minimum_width = MAX(l.minimum_width, m_width); \
} \
- if (wofs + m_width > p_width) { \
+ if (wofs - backtrack + m_width > p_width) { \
line_wrapped = true; \
if (p_mode == PROCESS_CACHE) { \
if (spaces > 0) \
@@ -390,6 +393,7 @@ int RichTextLabel::_process_line(ItemFrame *p_frame, const Vector2 &p_ofs, int &
int fw = 0;
lh = 0;
+
if (p_mode != PROCESS_CACHE) {
lh = line < l.height_caches.size() ? l.height_caches[line] : 1;
line_ascent = line < l.ascent_caches.size() ? l.ascent_caches[line] : 1;
@@ -432,13 +436,12 @@ int RichTextLabel::_process_line(ItemFrame *p_frame, const Vector2 &p_ofs, int &
{
- int ofs = 0;
+ int ofs = 0 - backtrack;
for (int i = 0; i < end; i++) {
int pofs = wofs + ofs;
if (p_mode == PROCESS_POINTER && r_click_char && p_click_pos.y >= p_ofs.y + y && p_click_pos.y <= p_ofs.y + y + lh) {
- //int o = (wofs+w)-p_click_pos.x;
int cw = font->get_char_size(c[i], c[i + 1]).x;
@@ -481,7 +484,10 @@ int RichTextLabel::_process_line(ItemFrame *p_frame, const Vector2 &p_ofs, int &
bool visible = visible_characters < 0 || ((p_char_count < visible_characters && YRANGE_VISIBLE(y + lh - line_descent - line_ascent, line_ascent + line_descent)) &&
faded_visibility > 0.0f);
+ const bool previously_visible = visible;
+
for (int j = 0; j < fx_stack.size(); j++) {
+
ItemFX *item_fx = fx_stack[j];
if (item_fx->type == ITEM_CUSTOMFX && custom_fx_ok) {
@@ -575,6 +581,8 @@ int RichTextLabel::_process_line(ItemFrame *p_frame, const Vector2 &p_ofs, int &
} else {
cw = drawer.draw_char(ci, p_ofs + Point2(align_ofs + pofs, y + lh - line_descent) + fx_offset, fx_char, c[i + 1], fx_color);
}
+ } else if (previously_visible) {
+ backtrack += font->get_char_size(fx_char, c[i + 1]).x;
}
p_char_count++;
@@ -648,6 +656,7 @@ int RichTextLabel::_process_line(ItemFrame *p_frame, const Vector2 &p_ofs, int &
case ITEM_NEWLINE: {
lh = 0;
+
if (p_mode != PROCESS_CACHE) {
lh = line < l.height_caches.size() ? l.height_caches[line] : 1;
line_is_blank = true;
diff --git a/scene/gui/tree.cpp b/scene/gui/tree.cpp
index 964f376dbd..790e1d5f4f 100644
--- a/scene/gui/tree.cpp
+++ b/scene/gui/tree.cpp
@@ -1121,7 +1121,7 @@ void Tree::draw_item_rect(const TreeItem::Cell &p_cell, const Rect2i &p_rect, co
}
rect.position.y += Math::floor((rect.size.y - font->get_height()) / 2.0) + font->get_ascent();
- font->draw(ci, rect.position, text, p_color, rect.size.x);
+ font->draw(ci, rect.position, text, p_color, MAX(0, rect.size.width));
}
int Tree::draw_item(const Point2i &p_pos, const Point2 &p_draw_ofs, const Size2 &p_draw_size, TreeItem *p_item) {
@@ -3630,6 +3630,17 @@ TreeItem *Tree::search_item_text(const String &p_find, int *r_col, bool p_select
return _search_item_text(from->get_next_visible(true), p_find, r_col, p_selectable);
}
+TreeItem *Tree::get_item_with_text(const String &p_find) const {
+ for (TreeItem *current = root; current; current = current->get_next_visible()) {
+ for (int i = 0; i < columns.size(); i++) {
+ if (current->get_text(i) == p_find) {
+ return current;
+ }
+ }
+ }
+ return NULL;
+}
+
void Tree::_do_incr_search(const String &p_add) {
uint64_t time = OS::get_singleton()->get_ticks_usec() / 1000; // convert to msec
diff --git a/scene/gui/tree.h b/scene/gui/tree.h
index d87de6e773..f3c88eb5ac 100644
--- a/scene/gui/tree.h
+++ b/scene/gui/tree.h
@@ -577,7 +577,10 @@ public:
Rect2 get_item_rect(TreeItem *p_item, int p_column = -1) const;
bool edit_selected();
+ // First item that starts with the text, from the current focused item down and wraps around.
TreeItem *search_item_text(const String &p_find, int *r_col = NULL, bool p_selectable = false);
+ // First item that matches the whole text, from the first item down.
+ TreeItem *get_item_with_text(const String &p_find) const;
Point2 get_scroll() const;
void scroll_to_item(TreeItem *p_item);
diff --git a/scene/resources/mesh.cpp b/scene/resources/mesh.cpp
index 0599920303..8f68cc5286 100644
--- a/scene/resources/mesh.cpp
+++ b/scene/resources/mesh.cpp
@@ -518,7 +518,6 @@ void Mesh::_bind_methods() {
BIND_ENUM_CONSTANT(ARRAY_FORMAT_WEIGHTS);
BIND_ENUM_CONSTANT(ARRAY_FORMAT_INDEX);
- BIND_ENUM_CONSTANT(ARRAY_COMPRESS_BASE);
BIND_ENUM_CONSTANT(ARRAY_COMPRESS_VERTEX);
BIND_ENUM_CONSTANT(ARRAY_COMPRESS_NORMAL);
BIND_ENUM_CONSTANT(ARRAY_COMPRESS_TANGENT);
diff --git a/thirdparty/README.md b/thirdparty/README.md
index 9b6f670972..7c3378dec3 100644
--- a/thirdparty/README.md
+++ b/thirdparty/README.md
@@ -281,6 +281,7 @@ Files extracted from upstream source:
- All `*.c` and `*.h` files from `miniupnpc` to `thirdparty/miniupnpc/miniupnpc`
- Remove `test*`, `minihttptestserver.c` and `wingenminiupnpcstrings.c`
+The patch `windows_fix.diff` is applied to `minissdpc.c` to fix an upstream issue.
The only modified file is miniupnpcstrings.h, which was created for Godot
(it is usually autogenerated by cmake).
diff --git a/thirdparty/miniupnpc/miniupnpc/minissdpc.c b/thirdparty/miniupnpc/miniupnpc/minissdpc.c
index 29f8110155..ea9af02e1f 100644
--- a/thirdparty/miniupnpc/miniupnpc/minissdpc.c
+++ b/thirdparty/miniupnpc/miniupnpc/minissdpc.c
@@ -683,11 +683,7 @@ ssdpDiscoverDevices(const char * const deviceTypes[],
#endif
} else {
struct in_addr mc_if;
-#if defined(_WIN32) && (_WIN32_WINNT >= _WIN32_WINNT_VISTA)
- InetPtonA(AF_INET, multicastif, &mc_if);
-#else
mc_if.s_addr = inet_addr(multicastif); /* ex: 192.168.x.x */
-#endif
if(mc_if.s_addr != INADDR_NONE)
{
((struct sockaddr_in *)&sockudp_r)->sin_addr.s_addr = mc_if.s_addr;
diff --git a/thirdparty/miniupnpc/windows_fix.diff b/thirdparty/miniupnpc/windows_fix.diff
new file mode 100644
index 0000000000..460b596888
--- /dev/null
+++ b/thirdparty/miniupnpc/windows_fix.diff
@@ -0,0 +1,16 @@
+diff --git a/thirdparty/miniupnpc/miniupnpc/minissdpc.c b/thirdparty/miniupnpc/miniupnpc/minissdpc.c
+index 29f8110155..ea9af02e1f 100644
+--- a/thirdparty/miniupnpc/miniupnpc/minissdpc.c
++++ b/thirdparty/miniupnpc/miniupnpc/minissdpc.c
+@@ -683,11 +683,7 @@ ssdpDiscoverDevices(const char * const deviceTypes[],
+ #endif
+ } else {
+ struct in_addr mc_if;
+-#if defined(_WIN32) && (_WIN32_WINNT >= _WIN32_WINNT_VISTA)
+- InetPtonA(AF_INET, multicastif, &mc_if);
+-#else
+ mc_if.s_addr = inet_addr(multicastif); /* ex: 192.168.x.x */
+-#endif
+ if(mc_if.s_addr != INADDR_NONE)
+ {
+ ((struct sockaddr_in *)&sockudp_r)->sin_addr.s_addr = mc_if.s_addr;