diff options
Diffstat (limited to 'scene')
42 files changed, 275 insertions, 160 deletions
diff --git a/scene/2d/collision_polygon_2d.cpp b/scene/2d/collision_polygon_2d.cpp index bb144dda96..766a8a6de4 100644 --- a/scene/2d/collision_polygon_2d.cpp +++ b/scene/2d/collision_polygon_2d.cpp @@ -169,8 +169,8 @@ void CollisionPolygon2D::_notification(int p_what) { Vector<Vector2> pts; float tsize = 8; pts.push_back(line_to + (Vector2(0, tsize))); - pts.push_back(line_to + (Vector2(0.707 * tsize, 0))); - pts.push_back(line_to + (Vector2(-0.707 * tsize, 0))); + pts.push_back(line_to + (Vector2(Math_SQRT12 * tsize, 0))); + pts.push_back(line_to + (Vector2(-Math_SQRT12 * tsize, 0))); Vector<Color> cols; for (int i = 0; i < 3; i++) cols.push_back(dcol); diff --git a/scene/2d/collision_shape_2d.cpp b/scene/2d/collision_shape_2d.cpp index f79d79d039..d9c1d69b53 100644 --- a/scene/2d/collision_shape_2d.cpp +++ b/scene/2d/collision_shape_2d.cpp @@ -134,8 +134,8 @@ void CollisionShape2D::_notification(int p_what) { Vector<Vector2> pts; float tsize = 8; pts.push_back(line_to + (Vector2(0, tsize))); - pts.push_back(line_to + (Vector2(0.707 * tsize, 0))); - pts.push_back(line_to + (Vector2(-0.707 * tsize, 0))); + pts.push_back(line_to + (Vector2(Math_SQRT12 * tsize, 0))); + pts.push_back(line_to + (Vector2(-Math_SQRT12 * tsize, 0))); Vector<Color> cols; for (int i = 0; i < 3; i++) cols.push_back(draw_col); diff --git a/scene/2d/physics_body_2d.cpp b/scene/2d/physics_body_2d.cpp index a57bfd4cbe..05f8d4883f 100644 --- a/scene/2d/physics_body_2d.cpp +++ b/scene/2d/physics_body_2d.cpp @@ -1051,7 +1051,7 @@ void RigidBody2D::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::REAL, "gravity_scale", PROPERTY_HINT_RANGE, "-128,128,0.01"), "set_gravity_scale", "get_gravity_scale"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "custom_integrator"), "set_use_custom_integrator", "is_using_custom_integrator"); ADD_PROPERTY(PropertyInfo(Variant::INT, "continuous_cd", PROPERTY_HINT_ENUM, "Disabled,Cast Ray,Cast Shape"), "set_continuous_collision_detection_mode", "get_continuous_collision_detection_mode"); - ADD_PROPERTY(PropertyInfo(Variant::INT, "contacts_reported"), "set_max_contacts_reported", "get_max_contacts_reported"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "contacts_reported", PROPERTY_HINT_RANGE, "0,64,1,or_greater"), "set_max_contacts_reported", "get_max_contacts_reported"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "contact_monitor"), "set_contact_monitor", "is_contact_monitor_enabled"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "sleeping"), "set_sleeping", "is_sleeping"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "can_sleep"), "set_can_sleep", "is_able_to_sleep"); diff --git a/scene/2d/ray_cast_2d.cpp b/scene/2d/ray_cast_2d.cpp index bf8d008bb2..4f6f410bdc 100644 --- a/scene/2d/ray_cast_2d.cpp +++ b/scene/2d/ray_cast_2d.cpp @@ -180,8 +180,8 @@ void RayCast2D::_notification(int p_what) { Vector<Vector2> pts; float tsize = 8; pts.push_back(xf.xform(Vector2(tsize, 0))); - pts.push_back(xf.xform(Vector2(0, 0.707 * tsize))); - pts.push_back(xf.xform(Vector2(0, -0.707 * tsize))); + pts.push_back(xf.xform(Vector2(0, Math_SQRT12 * tsize))); + pts.push_back(xf.xform(Vector2(0, -Math_SQRT12 * tsize))); Vector<Color> cols; for (int i = 0; i < 3; i++) cols.push_back(draw_col); diff --git a/scene/2d/sprite.cpp b/scene/2d/sprite.cpp index 8cdfceea52..a595f6714b 100644 --- a/scene/2d/sprite.cpp +++ b/scene/2d/sprite.cpp @@ -315,6 +315,9 @@ bool Sprite::is_pixel_opaque(const Point2 &p_point) const { if (texture.is_null()) return false; + if (texture->get_size().width == 0 || texture->get_size().height == 0) + return false; + Rect2 src_rect, dst_rect; bool filter_clip; _get_rects(src_rect, dst_rect, filter_clip); diff --git a/scene/3d/collision_polygon.cpp b/scene/3d/collision_polygon.cpp index 37aa95fb43..a59cce5c66 100644 --- a/scene/3d/collision_polygon.cpp +++ b/scene/3d/collision_polygon.cpp @@ -44,7 +44,7 @@ void CollisionPolygon::_build_polygon() { if (polygon.size() == 0) return; - Vector<Vector<Vector2> > decomp = Geometry::decompose_polygon(polygon); + Vector<Vector<Vector2> > decomp = Geometry::decompose_polygon_in_convex(polygon); if (decomp.size() == 0) return; diff --git a/scene/3d/mesh_instance.cpp b/scene/3d/mesh_instance.cpp index 50ca466df3..493806fc78 100644 --- a/scene/3d/mesh_instance.cpp +++ b/scene/3d/mesh_instance.cpp @@ -154,10 +154,10 @@ void MeshInstance::_resolve_skeleton_path() { if (!skeleton_path.is_empty()) { Skeleton *skeleton = Object::cast_to<Skeleton>(get_node(skeleton_path)); if (skeleton) { - new_skin_reference = skeleton->register_skin(skin); - if (skin.is_null()) { + new_skin_reference = skeleton->register_skin(skin_internal); + if (skin_internal.is_null()) { //a skin was created for us - skin = new_skin_reference->get_skin(); + skin_internal = new_skin_reference->get_skin(); _change_notify(); } } @@ -173,6 +173,7 @@ void MeshInstance::_resolve_skeleton_path() { } void MeshInstance::set_skin(const Ref<Skin> &p_skin) { + skin_internal = p_skin; skin = p_skin; if (!is_inside_tree()) return; diff --git a/scene/3d/mesh_instance.h b/scene/3d/mesh_instance.h index 77ead75dd3..91617341ba 100644 --- a/scene/3d/mesh_instance.h +++ b/scene/3d/mesh_instance.h @@ -43,6 +43,7 @@ class MeshInstance : public GeometryInstance { protected: Ref<Mesh> mesh; Ref<Skin> skin; + Ref<Skin> skin_internal; Ref<SkinReference> skin_ref; NodePath skeleton_path; diff --git a/scene/3d/physics_body.cpp b/scene/3d/physics_body.cpp index 6049b6cdb4..46e7bca943 100644 --- a/scene/3d/physics_body.cpp +++ b/scene/3d/physics_body.cpp @@ -1014,7 +1014,7 @@ void RigidBody::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::REAL, "gravity_scale", PROPERTY_HINT_RANGE, "-128,128,0.01"), "set_gravity_scale", "get_gravity_scale"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "custom_integrator"), "set_use_custom_integrator", "is_using_custom_integrator"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "continuous_cd"), "set_use_continuous_collision_detection", "is_using_continuous_collision_detection"); - ADD_PROPERTY(PropertyInfo(Variant::INT, "contacts_reported"), "set_max_contacts_reported", "get_max_contacts_reported"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "contacts_reported", PROPERTY_HINT_RANGE, "0,64,1,or_greater"), "set_max_contacts_reported", "get_max_contacts_reported"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "contact_monitor"), "set_contact_monitor", "is_contact_monitor_enabled"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "sleeping"), "set_sleeping", "is_sleeping"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "can_sleep"), "set_can_sleep", "is_able_to_sleep"); @@ -1554,6 +1554,14 @@ bool PhysicalBone::JointData::_get(const StringName &p_name, Variant &r_ret) con void PhysicalBone::JointData::_get_property_list(List<PropertyInfo> *p_list) const { } +void PhysicalBone::apply_central_impulse(const Vector3 &p_impulse) { + PhysicsServer::get_singleton()->body_apply_central_impulse(get_rid(), p_impulse); +} + +void PhysicalBone::apply_impulse(const Vector3 &p_pos, const Vector3 &p_impulse) { + PhysicsServer::get_singleton()->body_apply_impulse(get_rid(), p_pos, p_impulse); +} + bool PhysicalBone::PinJointData::_set(const StringName &p_name, const Variant &p_value, RID j) { if (JointData::_set(p_name, p_value, j)) { return true; @@ -2216,6 +2224,9 @@ void PhysicalBone::_direct_state_changed(Object *p_state) { } void PhysicalBone::_bind_methods() { + ClassDB::bind_method(D_METHOD("apply_central_impulse", "impulse"), &PhysicalBone::apply_central_impulse); + ClassDB::bind_method(D_METHOD("apply_impulse", "position", "impulse"), &PhysicalBone::apply_impulse); + ClassDB::bind_method(D_METHOD("_direct_state_changed"), &PhysicalBone::_direct_state_changed); ClassDB::bind_method(D_METHOD("set_joint_type", "joint_type"), &PhysicalBone::set_joint_type); diff --git a/scene/3d/physics_body.h b/scene/3d/physics_body.h index 0967cb9cd5..b208baf235 100644 --- a/scene/3d/physics_body.h +++ b/scene/3d/physics_body.h @@ -636,6 +636,9 @@ public: void set_gravity_scale(real_t p_gravity_scale); real_t get_gravity_scale() const; + void apply_central_impulse(const Vector3 &p_impulse); + void apply_impulse(const Vector3 &p_pos, const Vector3 &p_impulse); + PhysicalBone(); ~PhysicalBone(); diff --git a/scene/3d/voxel_light_baker.cpp b/scene/3d/voxel_light_baker.cpp index 8e09930aed..3235953730 100644 --- a/scene/3d/voxel_light_baker.cpp +++ b/scene/3d/voxel_light_baker.cpp @@ -1594,10 +1594,10 @@ Vector3 VoxelLightBaker::_compute_pixel_light_at_pos(const Vector3 &p_pos, const case BAKE_QUALITY_LOW: { //default quality static const Vector3 dirs[4] = { - Vector3(0.707107, 0, 0.707107), - Vector3(0, 0.707107, 0.707107), - Vector3(-0.707107, 0, 0.707107), - Vector3(0, -0.707107, 0.707107) + Vector3(Math_SQRT12, 0, Math_SQRT12), + Vector3(0, Math_SQRT12, Math_SQRT12), + Vector3(-Math_SQRT12, 0, Math_SQRT12), + Vector3(0, -Math_SQRT12, Math_SQRT12) }; static const float weights[4] = { 0.25, 0.25, 0.25, 0.25 }; diff --git a/scene/animation/tween.cpp b/scene/animation/tween.cpp index ce3f2b3b1a..72e8ae1b26 100644 --- a/scene/animation/tween.cpp +++ b/scene/animation/tween.cpp @@ -239,14 +239,14 @@ void Tween::_bind_methods() { ClassDB::bind_method(D_METHOD("get_runtime"), &Tween::get_runtime); // Bind interpolation and follow methods - ClassDB::bind_method(D_METHOD("interpolate_property", "object", "property", "initial_val", "final_val", "duration", "trans_type", "ease_type", "delay"), &Tween::interpolate_property, DEFVAL(0)); - ClassDB::bind_method(D_METHOD("interpolate_method", "object", "method", "initial_val", "final_val", "duration", "trans_type", "ease_type", "delay"), &Tween::interpolate_method, DEFVAL(0)); + ClassDB::bind_method(D_METHOD("interpolate_property", "object", "property", "initial_val", "final_val", "duration", "trans_type", "ease_type", "delay"), &Tween::interpolate_property, DEFVAL(TRANS_LINEAR), DEFVAL(EASE_IN_OUT), DEFVAL(0)); + ClassDB::bind_method(D_METHOD("interpolate_method", "object", "method", "initial_val", "final_val", "duration", "trans_type", "ease_type", "delay"), &Tween::interpolate_method, DEFVAL(TRANS_LINEAR), DEFVAL(EASE_IN_OUT), DEFVAL(0)); ClassDB::bind_method(D_METHOD("interpolate_callback", "object", "duration", "callback", "arg1", "arg2", "arg3", "arg4", "arg5"), &Tween::interpolate_callback, DEFVAL(Variant()), DEFVAL(Variant()), DEFVAL(Variant()), DEFVAL(Variant()), DEFVAL(Variant())); ClassDB::bind_method(D_METHOD("interpolate_deferred_callback", "object", "duration", "callback", "arg1", "arg2", "arg3", "arg4", "arg5"), &Tween::interpolate_deferred_callback, DEFVAL(Variant()), DEFVAL(Variant()), DEFVAL(Variant()), DEFVAL(Variant()), DEFVAL(Variant())); - ClassDB::bind_method(D_METHOD("follow_property", "object", "property", "initial_val", "target", "target_property", "duration", "trans_type", "ease_type", "delay"), &Tween::follow_property, DEFVAL(0)); - ClassDB::bind_method(D_METHOD("follow_method", "object", "method", "initial_val", "target", "target_method", "duration", "trans_type", "ease_type", "delay"), &Tween::follow_method, DEFVAL(0)); - ClassDB::bind_method(D_METHOD("targeting_property", "object", "property", "initial", "initial_val", "final_val", "duration", "trans_type", "ease_type", "delay"), &Tween::targeting_property, DEFVAL(0)); - ClassDB::bind_method(D_METHOD("targeting_method", "object", "method", "initial", "initial_method", "final_val", "duration", "trans_type", "ease_type", "delay"), &Tween::targeting_method, DEFVAL(0)); + ClassDB::bind_method(D_METHOD("follow_property", "object", "property", "initial_val", "target", "target_property", "duration", "trans_type", "ease_type", "delay"), &Tween::follow_property, DEFVAL(TRANS_LINEAR), DEFVAL(EASE_IN_OUT), DEFVAL(0)); + ClassDB::bind_method(D_METHOD("follow_method", "object", "method", "initial_val", "target", "target_method", "duration", "trans_type", "ease_type", "delay"), &Tween::follow_method, DEFVAL(TRANS_LINEAR), DEFVAL(EASE_IN_OUT), DEFVAL(0)); + ClassDB::bind_method(D_METHOD("targeting_property", "object", "property", "initial", "initial_val", "final_val", "duration", "trans_type", "ease_type", "delay"), &Tween::targeting_property, DEFVAL(TRANS_LINEAR), DEFVAL(EASE_IN_OUT), DEFVAL(0)); + ClassDB::bind_method(D_METHOD("targeting_method", "object", "method", "initial", "initial_method", "final_val", "duration", "trans_type", "ease_type", "delay"), &Tween::targeting_method, DEFVAL(TRANS_LINEAR), DEFVAL(EASE_IN_OUT), DEFVAL(0)); // Add the Tween signals ADD_SIGNAL(MethodInfo("tween_started", PropertyInfo(Variant::OBJECT, "object"), PropertyInfo(Variant::NODE_PATH, "key"))); diff --git a/scene/animation/tween.h b/scene/animation/tween.h index 574238f5c9..f301d8d76b 100644 --- a/scene/animation/tween.h +++ b/scene/animation/tween.h @@ -101,6 +101,12 @@ private: int args; Variant arg[5]; int uid; + InterpolateData() { + active = false; + finish = false; + call_deferred = false; + uid = 0; + } }; String autoplay; @@ -173,21 +179,14 @@ public: real_t tell() const; real_t get_runtime() const; - bool interpolate_property(Object *p_object, NodePath p_property, Variant p_initial_val, Variant p_final_val, real_t p_duration, TransitionType p_trans_type, EaseType p_ease_type, real_t p_delay = 0); - - bool interpolate_method(Object *p_object, StringName p_method, Variant p_initial_val, Variant p_final_val, real_t p_duration, TransitionType p_trans_type, EaseType p_ease_type, real_t p_delay = 0); - + bool interpolate_property(Object *p_object, NodePath p_property, Variant p_initial_val, Variant p_final_val, real_t p_duration, TransitionType p_trans_type = TRANS_LINEAR, EaseType p_ease_type = EASE_IN_OUT, real_t p_delay = 0); + bool interpolate_method(Object *p_object, StringName p_method, Variant p_initial_val, Variant p_final_val, real_t p_duration, TransitionType p_trans_type = TRANS_LINEAR, EaseType p_ease_type = EASE_IN_OUT, real_t p_delay = 0); bool interpolate_callback(Object *p_object, real_t p_duration, String p_callback, VARIANT_ARG_DECLARE); - bool interpolate_deferred_callback(Object *p_object, real_t p_duration, String p_callback, VARIANT_ARG_DECLARE); - - bool follow_property(Object *p_object, NodePath p_property, Variant p_initial_val, Object *p_target, NodePath p_target_property, real_t p_duration, TransitionType p_trans_type, EaseType p_ease_type, real_t p_delay = 0); - - bool follow_method(Object *p_object, StringName p_method, Variant p_initial_val, Object *p_target, StringName p_target_method, real_t p_duration, TransitionType p_trans_type, EaseType p_ease_type, real_t p_delay = 0); - - bool targeting_property(Object *p_object, NodePath p_property, Object *p_initial, NodePath p_initial_property, Variant p_final_val, real_t p_duration, TransitionType p_trans_type, EaseType p_ease_type, real_t p_delay = 0); - - bool targeting_method(Object *p_object, StringName p_method, Object *p_initial, StringName p_initial_method, Variant p_final_val, real_t p_duration, TransitionType p_trans_type, EaseType p_ease_type, real_t p_delay = 0); + bool follow_property(Object *p_object, NodePath p_property, Variant p_initial_val, Object *p_target, NodePath p_target_property, real_t p_duration, TransitionType p_trans_type = TRANS_LINEAR, EaseType p_ease_type = EASE_IN_OUT, real_t p_delay = 0); + bool follow_method(Object *p_object, StringName p_method, Variant p_initial_val, Object *p_target, StringName p_target_method, real_t p_duration, TransitionType p_trans_type = TRANS_LINEAR, EaseType p_ease_type = EASE_IN_OUT, real_t p_delay = 0); + bool targeting_property(Object *p_object, NodePath p_property, Object *p_initial, NodePath p_initial_property, Variant p_final_val, real_t p_duration, TransitionType p_trans_type = TRANS_LINEAR, EaseType p_ease_type = EASE_IN_OUT, real_t p_delay = 0); + bool targeting_method(Object *p_object, StringName p_method, Object *p_initial, StringName p_initial_method, Variant p_final_val, real_t p_duration, TransitionType p_trans_type = TRANS_LINEAR, EaseType p_ease_type = EASE_IN_OUT, real_t p_delay = 0); Tween(); ~Tween(); diff --git a/scene/debugger/script_debugger_remote.cpp b/scene/debugger/script_debugger_remote.cpp index c3c6a088cb..1b37a7dbdb 100644 --- a/scene/debugger/script_debugger_remote.cpp +++ b/scene/debugger/script_debugger_remote.cpp @@ -1257,7 +1257,7 @@ ScriptDebuggerRemote::ScriptDebuggerRemote() : scene_tree(NULL) { packet_peer_stream->set_stream_peer(tcp_client); - packet_peer_stream->set_output_buffer_max_size(1024 * 1024 * 8); //8mb should be way more than enough + packet_peer_stream->set_output_buffer_max_size((1024 * 1024 * 8) - 4); // 8 MiB should be way more than enough, minus 4 bytes for separator. phl.printfunc = _print_handler; phl.userdata = this; diff --git a/scene/gui/button.cpp b/scene/gui/button.cpp index ca4c255855..a68462f4d4 100644 --- a/scene/gui/button.cpp +++ b/scene/gui/button.cpp @@ -190,6 +190,13 @@ void Button::_notification(int p_what) { Point2 icon_ofs = !_icon.is_null() ? Point2(icon_region.size.width + get_constant("hseparation"), 0) : Point2(); int text_clip = size.width - style->get_minimum_size().width - icon_ofs.width; + if (_internal_margin[MARGIN_LEFT] > 0) { + text_clip -= _internal_margin[MARGIN_LEFT] + get_constant("hseparation"); + } + if (_internal_margin[MARGIN_RIGHT] > 0) { + text_clip -= _internal_margin[MARGIN_RIGHT] + get_constant("hseparation"); + } + Point2 text_ofs = (size - style->get_minimum_size() - icon_ofs - font->get_string_size(xl_text) - Point2(_internal_margin[MARGIN_RIGHT] - _internal_margin[MARGIN_LEFT], 0)) / 2.0; switch (align) { diff --git a/scene/gui/control.cpp b/scene/gui/control.cpp index 8b4d5d4980..ccc658b0aa 100644 --- a/scene/gui/control.cpp +++ b/scene/gui/control.cpp @@ -2012,14 +2012,15 @@ Control *Control::find_next_valid_focus() const { if (!data.focus_next.is_empty()) { Node *n = get_node(data.focus_next); + Control *c; if (n) { - from = Object::cast_to<Control>(n); - ERR_FAIL_COND_V_MSG(!from, NULL, "Next focus node is not a control: " + n->get_name() + "."); + c = Object::cast_to<Control>(n); + ERR_FAIL_COND_V_MSG(!c, NULL, "Next focus node is not a control: " + n->get_name() + "."); } else { return NULL; } - if (from->is_visible() && from->get_focus_mode() != FOCUS_NONE) - return from; + if (c->is_visible() && c->get_focus_mode() != FOCUS_NONE) + return c; } // find next child @@ -2102,14 +2103,15 @@ Control *Control::find_prev_valid_focus() const { if (!data.focus_prev.is_empty()) { Node *n = get_node(data.focus_prev); + Control *c; if (n) { - from = Object::cast_to<Control>(n); - ERR_FAIL_COND_V_MSG(!from, NULL, "Previous focus node is not a control: " + n->get_name() + "."); + c = Object::cast_to<Control>(n); + ERR_FAIL_COND_V_MSG(!c, NULL, "Previous focus node is not a control: " + n->get_name() + "."); } else { return NULL; } - if (from->is_visible() && from->get_focus_mode() != FOCUS_NONE) - return from; + if (c->is_visible() && c->get_focus_mode() != FOCUS_NONE) + return c; } // find prev child diff --git a/scene/gui/file_dialog.cpp b/scene/gui/file_dialog.cpp index 6400061309..dd9e11508f 100644 --- a/scene/gui/file_dialog.cpp +++ b/scene/gui/file_dialog.cpp @@ -558,25 +558,25 @@ void FileDialog::update_filters() { const int max_filters = 5; for (int i = 0; i < MIN(max_filters, filters.size()); i++) { - String flt = filters[i].get_slice(";", 0); + String flt = filters[i].get_slice(";", 0).strip_edges(); if (i > 0) - all_filters += ","; + all_filters += ", "; all_filters += flt; } if (max_filters < filters.size()) all_filters += ", ..."; - filter->add_item(RTR("All Recognized") + " ( " + all_filters + " )"); + filter->add_item(RTR("All Recognized") + " (" + all_filters + ")"); } for (int i = 0; i < filters.size(); i++) { String flt = filters[i].get_slice(";", 0).strip_edges(); String desc = filters[i].get_slice(";", 1).strip_edges(); if (desc.length()) - filter->add_item(String(tr(desc)) + " ( " + flt + " )"); + filter->add_item(String(tr(desc)) + " (" + flt + ")"); else - filter->add_item("( " + flt + " )"); + filter->add_item("(" + flt + ")"); } filter->add_item(RTR("All Files (*)")); diff --git a/scene/gui/item_list.cpp b/scene/gui/item_list.cpp index 3884622942..20bbcbde80 100644 --- a/scene/gui/item_list.cpp +++ b/scene/gui/item_list.cpp @@ -973,12 +973,12 @@ void ItemList::_notification(int p_what) { float max = MAX(page, ofs.y + max_h); if (auto_height) auto_height_value = ofs.y + max_h + bg->get_minimum_size().height; + scroll_bar->set_max(max); + scroll_bar->set_page(page); if (max <= page) { scroll_bar->set_value(0); scroll_bar->hide(); } else { - scroll_bar->set_max(max); - scroll_bar->set_page(page); scroll_bar->show(); if (do_autoscroll_to_bottom) diff --git a/scene/gui/line_edit.cpp b/scene/gui/line_edit.cpp index e6a27aa63f..d96ca69c87 100644 --- a/scene/gui/line_edit.cpp +++ b/scene/gui/line_edit.cpp @@ -704,7 +704,7 @@ void LineEdit::_notification(int p_what) { } int x_ofs = 0; - bool using_placeholder = text.empty(); + bool using_placeholder = text.empty() && ime_text.empty(); int cached_text_width = using_placeholder ? cached_placeholder_width : cached_width; switch (align) { diff --git a/scene/gui/popup_menu.cpp b/scene/gui/popup_menu.cpp index 08faaf7d45..5561bce714 100644 --- a/scene/gui/popup_menu.cpp +++ b/scene/gui/popup_menu.cpp @@ -191,16 +191,20 @@ void PopupMenu::_submenu_timeout() { void PopupMenu::_scroll(float p_factor, const Point2 &p_over) { - const float global_y = get_global_position().y; - int vseparation = get_constant("vseparation"); Ref<Font> font = get_font("font"); float dy = (vseparation + font->get_height()) * 3 * p_factor * get_global_transform().get_scale().y; - if (dy > 0 && global_y < 0) - dy = MIN(dy, -global_y - 1); - else if (dy < 0 && global_y + get_size().y * get_global_transform().get_scale().y > get_viewport_rect().size.y) - dy = -MIN(-dy, global_y + get_size().y * get_global_transform().get_scale().y - get_viewport_rect().size.y - 1); + if (dy > 0) { + const float global_top = get_global_position().y; + const float limit = global_top < 0 ? -global_top : 0; + dy = MIN(dy, limit); + } else if (dy < 0) { + const float global_bottom = get_global_position().y + get_size().y * get_global_transform().get_scale().y; + const float viewport_height = get_viewport_rect().size.y; + const float limit = global_bottom > viewport_height ? global_bottom - viewport_height : 0; + dy = -MIN(-dy, limit); + } set_position(get_position() + Vector2(0, dy)); Ref<InputEventMouseMotion> ie; diff --git a/scene/gui/rich_text_effect.cpp b/scene/gui/rich_text_effect.cpp index f9e0be5b31..ab2f8d2172 100644 --- a/scene/gui/rich_text_effect.cpp +++ b/scene/gui/rich_text_effect.cpp @@ -89,8 +89,6 @@ void CharFXTransform::_bind_methods() { ClassDB::bind_method(D_METHOD("get_character"), &CharFXTransform::get_character); ClassDB::bind_method(D_METHOD("set_character", "character"), &CharFXTransform::set_character); - ClassDB::bind_method(D_METHOD("get_value_or", "key", "default_value"), &CharFXTransform::get_value_or); - ADD_PROPERTY(PropertyInfo(Variant::INT, "relative_index"), "set_relative_index", "get_relative_index"); ADD_PROPERTY(PropertyInfo(Variant::INT, "absolute_index"), "set_absolute_index", "get_absolute_index"); ADD_PROPERTY(PropertyInfo(Variant::REAL, "elapsed_time"), "set_elapsed_time", "get_elapsed_time"); @@ -101,17 +99,6 @@ void CharFXTransform::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::INT, "character"), "set_character", "get_character"); } -Variant CharFXTransform::get_value_or(String p_key, Variant p_default_value) { - if (!this->environment.has(p_key)) - return p_default_value; - - Variant r = environment[p_key]; - if (r.get_type() != p_default_value.get_type()) - return p_default_value; - - return r; -} - CharFXTransform::CharFXTransform() { relative_index = 0; absolute_index = 0; diff --git a/scene/gui/rich_text_effect.h b/scene/gui/rich_text_effect.h index 4330cebfe6..9e0065b199 100644 --- a/scene/gui/rich_text_effect.h +++ b/scene/gui/rich_text_effect.h @@ -82,8 +82,6 @@ public: void set_character(int p_char) { character = (CharType)p_char; } Dictionary get_environment() { return environment; } void set_environment(Dictionary p_environment) { environment = p_environment; } - - Variant get_value_or(String p_key, Variant p_default_value); }; #endif // RICH_TEXT_EFFECT_H diff --git a/scene/gui/rich_text_label.cpp b/scene/gui/rich_text_label.cpp index 0331046492..abca865ae0 100644 --- a/scene/gui/rich_text_label.cpp +++ b/scene/gui/rich_text_label.cpp @@ -1701,6 +1701,9 @@ bool RichTextLabel::remove_line(const int p_line) { if (!was_newline) { current_frame->lines.remove(p_line); + if (current_frame->lines.size() == 0) { + current_frame->lines.resize(1); + } } if (p_line == 0 && current->subitems.size() > 0) diff --git a/scene/gui/scroll_container.cpp b/scene/gui/scroll_container.cpp index fa23bf91dd..cb9ae875b7 100644 --- a/scene/gui/scroll_container.cpp +++ b/scene/gui/scroll_container.cpp @@ -30,6 +30,7 @@ #include "scroll_container.h" #include "core/os/os.h" +#include "scene/main/viewport.h" bool ScrollContainer::clips_input() const { @@ -232,6 +233,27 @@ void ScrollContainer::_update_scrollbar_position() { v_scroll->raise(); } +void ScrollContainer::_ensure_focused_visible(Control *p_control) { + + if (is_a_parent_of(p_control)) { + Rect2 global_rect = get_global_rect(); + Rect2 other_rect = p_control->get_global_rect(); + float right_margin = 0; + if (v_scroll->is_visible()) { + right_margin += v_scroll->get_size().x; + } + float bottom_margin = 0; + if (h_scroll->is_visible()) { + bottom_margin += h_scroll->get_size().y; + } + + float diff = MAX(MIN(other_rect.position.y, global_rect.position.y), other_rect.position.y + other_rect.size.y - global_rect.size.y + bottom_margin); + set_v_scroll(get_v_scroll() + (diff - global_rect.position.y)); + diff = MAX(MIN(other_rect.position.x, global_rect.position.x), other_rect.position.x + other_rect.size.x - global_rect.size.x + right_margin); + set_h_scroll(get_h_scroll() + (diff - global_rect.position.x)); + } +} + void ScrollContainer::_notification(int p_what) { if (p_what == NOTIFICATION_ENTER_TREE || p_what == NOTIFICATION_THEME_CHANGED) { @@ -239,6 +261,11 @@ void ScrollContainer::_notification(int p_what) { call_deferred("_update_scrollbar_position"); }; + if (p_what == NOTIFICATION_READY) { + + get_viewport()->connect("gui_focus_changed", this, "_ensure_focused_visible"); + } + if (p_what == NOTIFICATION_SORT_CHILDREN) { child_max_size = Size2(0, 0); @@ -521,6 +548,7 @@ void ScrollContainer::_bind_methods() { ClassDB::bind_method(D_METHOD("set_enable_v_scroll", "enable"), &ScrollContainer::set_enable_v_scroll); ClassDB::bind_method(D_METHOD("is_v_scroll_enabled"), &ScrollContainer::is_v_scroll_enabled); ClassDB::bind_method(D_METHOD("_update_scrollbar_position"), &ScrollContainer::_update_scrollbar_position); + ClassDB::bind_method(D_METHOD("_ensure_focused_visible"), &ScrollContainer::_ensure_focused_visible); ClassDB::bind_method(D_METHOD("set_h_scroll", "value"), &ScrollContainer::set_h_scroll); ClassDB::bind_method(D_METHOD("get_h_scroll"), &ScrollContainer::get_h_scroll); ClassDB::bind_method(D_METHOD("set_v_scroll", "value"), &ScrollContainer::set_v_scroll); diff --git a/scene/gui/scroll_container.h b/scene/gui/scroll_container.h index 2ab169f4d0..1d247f14c6 100644 --- a/scene/gui/scroll_container.h +++ b/scene/gui/scroll_container.h @@ -75,6 +75,7 @@ protected: static void _bind_methods(); void _update_scrollbar_position(); + void _ensure_focused_visible(Control *p_node); public: int get_v_scroll() const; diff --git a/scene/gui/slider.cpp b/scene/gui/slider.cpp index ba57be1686..cbb2db7788 100644 --- a/scene/gui/slider.cpp +++ b/scene/gui/slider.cpp @@ -166,7 +166,6 @@ void Slider::_notification(int p_what) { RID ci = get_canvas_item(); Size2i size = get_size(); Ref<StyleBox> style = get_stylebox("slider"); - Ref<StyleBox> focus = get_stylebox("focus"); Ref<StyleBox> grabber_area = get_stylebox("grabber_area"); Ref<Texture> grabber = get_icon(editable ? ((mouse_inside || has_focus()) ? "grabber_highlight" : "grabber") : "grabber_disabled"); Ref<Texture> tick = get_icon("tick"); @@ -178,10 +177,7 @@ void Slider::_notification(int p_what) { float areasize = size.height - grabber->get_size().height; style->draw(ci, Rect2i(Point2i(size.width / 2 - widget_width / 2, 0), Size2i(widget_width, size.height))); grabber_area->draw(ci, Rect2i(Point2i((size.width - widget_width) / 2, size.height - areasize * ratio - grabber->get_size().height / 2), Size2i(widget_width, areasize * ratio + grabber->get_size().width / 2))); - /* - if (mouse_inside||has_focus()) - focus->draw(ci,Rect2i(Point2i(),Size2i(style->get_minimum_size().width+style->get_center_size().width,size.height))); - */ + if (ticks > 1) { int grabber_offset = (grabber->get_size().height / 2 - tick->get_height() / 2); for (int i = 0; i < ticks; i++) { @@ -198,10 +194,6 @@ void Slider::_notification(int p_what) { style->draw(ci, Rect2i(Point2i(0, (size.height - widget_height) / 2), Size2i(size.width, widget_height))); grabber_area->draw(ci, Rect2i(Point2i(0, (size.height - widget_height) / 2), Size2i(areasize * ratio + grabber->get_size().width / 2, widget_height))); - /* - if (mouse_inside||has_focus()) - focus->draw(ci,Rect2i(Point2i(),Size2i(size.width,style->get_minimum_size().height+style->get_center_size().height))); - */ if (ticks > 1) { int grabber_offset = (grabber->get_size().width / 2 - tick->get_width() / 2); diff --git a/scene/gui/spin_box.cpp b/scene/gui/spin_box.cpp index bf067898e6..de25d6a63d 100644 --- a/scene/gui/spin_box.cpp +++ b/scene/gui/spin_box.cpp @@ -211,6 +211,10 @@ void SpinBox::_notification(int p_what) { _adjust_width_for_icon(get_icon("updown")); _value_changed(0); + } else if (p_what == NOTIFICATION_THEME_CHANGED) { + + call_deferred("minimum_size_changed"); + get_line_edit()->call_deferred("minimum_size_changed"); } } diff --git a/scene/gui/text_edit.cpp b/scene/gui/text_edit.cpp index 2558a930b6..9bcacd6ee3 100644 --- a/scene/gui/text_edit.cpp +++ b/scene/gui/text_edit.cpp @@ -4438,7 +4438,6 @@ int TextEdit::get_line_wrap_index_at_col(int p_line, int p_column) const { } void TextEdit::cursor_set_column(int p_col, bool p_adjust_viewport) { - if (p_col < 0) p_col = 0; @@ -5178,11 +5177,16 @@ void TextEdit::cut() { OS::get_singleton()->set_clipboard(clipboard); cursor_set_line(cursor.line); cursor_set_column(0); - _remove_text(cursor.line, 0, cursor.line, text[cursor.line].length()); - backspace_at_cursor(); + if (cursor.line == 0 && get_line_count() > 1) { + _remove_text(cursor.line, 0, cursor.line + 1, 0); + } else { + _remove_text(cursor.line, 0, cursor.line, text[cursor.line].length()); + backspace_at_cursor(); + cursor_set_line(cursor.line + 1); + } + update(); - cursor_set_line(cursor.line + 1); cut_copy_line = clipboard; } else { @@ -7141,6 +7145,7 @@ TextEdit::TextEdit() { max_chars = 0; clear(); wrap_enabled = false; + wrap_at = 0; wrap_right_offset = 10; set_focus_mode(FOCUS_ALL); syntax_highlighter = NULL; diff --git a/scene/gui/text_edit.h b/scene/gui/text_edit.h index 594366de7d..4f11e9bb50 100644 --- a/scene/gui/text_edit.h +++ b/scene/gui/text_edit.h @@ -69,6 +69,10 @@ public: int region; bool end; + ColorRegionInfo() { + region = 0; + end = false; + } }; struct Line { @@ -84,6 +88,16 @@ public: Ref<Texture> info_icon; String info; String data; + Line() { + width_cache = 0; + marked = false; + breakpoint = false; + bookmark = false; + hidden = false; + safe = false; + has_info = false; + wrap_amount_cache = 0; + } }; private: @@ -143,6 +157,14 @@ private: int last_fit_x; int line, column; ///< cursor int x_ofs, line_ofs, wrap_ofs; + Cursor() { + last_fit_x = 0; + line = 0; + column = 0; ///< cursor + x_ofs = 0; + line_ofs = 0; + wrap_ofs = 0; + } } cursor; struct Selection { @@ -167,7 +189,21 @@ private: int to_line, to_column; bool shiftclick_left; - + Selection() { + selecting_mode = MODE_NONE; + selecting_line = 0; + selecting_column = 0; + selected_word_beg = 0; + selected_word_end = 0; + selected_word_origin = 0; + selecting_text = false; + active = false; + from_line = 0; + from_column = 0; + to_line = 0; + to_column = 0; + shiftclick_left = false; + } } selection; struct Cache { @@ -219,6 +255,16 @@ private: int fold_gutter_width; int info_gutter_width; int minimap_width; + Cache() { + + row_height = 0; + line_spacing = 0; + line_number_w = 0; + breakpoint_gutter_width = 0; + fold_gutter_width = 0; + info_gutter_width = 0; + minimap_width = 0; + } } cache; Map<int, int> color_region_cache; @@ -240,6 +286,17 @@ private: uint32_t version; bool chain_forward; bool chain_backward; + TextOperation() { + type = TYPE_NONE; + from_line = 0; + from_column = 0; + to_line = 0; + to_column = 0; + prev_version = 0; + version = 0; + chain_forward = false; + chain_backward = false; + } }; String ime_text; diff --git a/scene/main/scene_tree.cpp b/scene/main/scene_tree.cpp index 3a6fff45c5..48f6a0cc95 100644 --- a/scene/main/scene_tree.cpp +++ b/scene/main/scene_tree.cpp @@ -423,7 +423,7 @@ void SceneTree::input_event(const Ref<InputEvent> &p_event) { input_handled = false; - Ref<InputEvent> ev = p_event; + const Ref<InputEvent> &ev = p_event; MainLoop::input_event(ev); diff --git a/scene/main/viewport.cpp b/scene/main/viewport.cpp index 3ad44a4a2e..a7c7322b0e 100644 --- a/scene/main/viewport.cpp +++ b/scene/main/viewport.cpp @@ -2407,12 +2407,12 @@ void Viewport::_gui_input_event(Ref<InputEvent> p_event) { Input *input = Input::get_singleton(); - if (!mods && p_event->is_action_pressed("ui_focus_next") && input->is_action_just_pressed("ui_focus_next")) { + if (p_event->is_action_pressed("ui_focus_next") && input->is_action_just_pressed("ui_focus_next")) { next = from->find_next_valid_focus(); } - if (!mods && p_event->is_action_pressed("ui_focus_prev") && input->is_action_just_pressed("ui_focus_prev")) { + if (p_event->is_action_pressed("ui_focus_prev") && input->is_action_just_pressed("ui_focus_prev")) { next = from->find_prev_valid_focus(); } @@ -2634,6 +2634,7 @@ void Viewport::_gui_control_grab_focus(Control *p_control) { return; get_tree()->call_group_flags(SceneTree::GROUP_CALL_REALTIME, "_viewports", "_gui_remove_focus"); gui.key_focus = p_control; + emit_signal("gui_focus_changed", p_control); p_control->notification(Control::NOTIFICATION_FOCUS_ENTER); p_control->update(); } @@ -3216,6 +3217,7 @@ void Viewport::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::TRANSFORM2D, "global_canvas_transform", PROPERTY_HINT_NONE, "", 0), "set_global_canvas_transform", "get_global_canvas_transform"); ADD_SIGNAL(MethodInfo("size_changed")); + ADD_SIGNAL(MethodInfo("gui_focus_changed", PropertyInfo(Variant::OBJECT, "node", PROPERTY_HINT_RESOURCE_TYPE, "Control"))); BIND_ENUM_CONSTANT(UPDATE_DISABLED); BIND_ENUM_CONSTANT(UPDATE_ONCE); diff --git a/scene/resources/default_theme/default_theme.cpp b/scene/resources/default_theme/default_theme.cpp index e82819f270..c67e5a928c 100644 --- a/scene/resources/default_theme/default_theme.cpp +++ b/scene/resources/default_theme/default_theme.cpp @@ -496,9 +496,6 @@ void fill_default_theme(Ref<Theme> &theme, const Ref<Font> &default_font, const theme->set_stylebox("slider", "HSlider", make_stylebox(hslider_bg_png, 4, 4, 4, 4)); theme->set_stylebox("grabber_area", "HSlider", make_stylebox(hslider_bg_png, 4, 4, 4, 4)); - theme->set_stylebox("grabber_highlight", "HSlider", make_stylebox(hslider_grabber_hl_png, 6, 6, 6, 6)); - theme->set_stylebox("grabber_disabled", "HSlider", make_stylebox(hslider_grabber_disabled_png, 6, 6, 6, 6)); - theme->set_stylebox("focus", "HSlider", focus); theme->set_icon("grabber", "HSlider", make_icon(hslider_grabber_png)); theme->set_icon("grabber_highlight", "HSlider", make_icon(hslider_grabber_hl_png)); @@ -509,9 +506,6 @@ void fill_default_theme(Ref<Theme> &theme, const Ref<Font> &default_font, const theme->set_stylebox("slider", "VSlider", make_stylebox(vslider_bg_png, 4, 4, 4, 4)); theme->set_stylebox("grabber_area", "VSlider", make_stylebox(vslider_bg_png, 4, 4, 4, 4)); - theme->set_stylebox("grabber_highlight", "VSlider", make_stylebox(vslider_grabber_hl_png, 6, 6, 6, 6)); - theme->set_stylebox("grabber_disabled", "VSlider", make_stylebox(vslider_grabber_disabled_png, 6, 6, 6, 6)); - theme->set_stylebox("focus", "VSlider", focus); theme->set_icon("grabber", "VSlider", make_icon(vslider_grabber_png)); theme->set_icon("grabber_highlight", "VSlider", make_icon(vslider_grabber_hl_png)); diff --git a/scene/resources/dynamic_font.cpp b/scene/resources/dynamic_font.cpp index 99a2881d58..7524571956 100644 --- a/scene/resources/dynamic_font.cpp +++ b/scene/resources/dynamic_font.cpp @@ -657,6 +657,7 @@ void DynamicFont::_reload_cache() { if (!data.is_valid()) { data_at_size.unref(); outline_data_at_size.unref(); + fallbacks.resize(0); fallback_data_at_size.resize(0); fallback_outline_data_at_size.resize(0); return; diff --git a/scene/resources/mesh.cpp b/scene/resources/mesh.cpp index 4afb07cb6f..0d94d4dbf4 100644 --- a/scene/resources/mesh.cpp +++ b/scene/resources/mesh.cpp @@ -483,6 +483,7 @@ void Mesh::_bind_methods() { ClassDB::bind_method(D_METHOD("set_lightmap_size_hint", "size"), &Mesh::set_lightmap_size_hint); ClassDB::bind_method(D_METHOD("get_lightmap_size_hint"), &Mesh::get_lightmap_size_hint); + ClassDB::bind_method(D_METHOD("get_aabb"), &Mesh::get_aabb); ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "lightmap_size_hint"), "set_lightmap_size_hint", "get_lightmap_size_hint"); diff --git a/scene/resources/packed_scene.cpp b/scene/resources/packed_scene.cpp index 7d62873bbd..5ce269fff9 100644 --- a/scene/resources/packed_scene.cpp +++ b/scene/resources/packed_scene.cpp @@ -397,6 +397,9 @@ Error SceneState::_parse_node(Node *p_owner, Node *p_node, int p_parent_idx, Map if (p_owner->get_scene_inherited_state().is_null() && (p_node == p_owner || (p_node->get_owner() == p_owner && (p_node->get_parent() == p_owner || p_node->get_parent()->get_owner() == p_owner)))) { //do not save index, because it belongs to saved scene and scene is not inherited nd.index = -1; + } else if (p_node == p_owner) { + //This (hopefully) happens if the node is a scene root, so its index is irrelevant. + nd.index = -1; } else { //part of an inherited scene, or parent is from an instanced scene nd.index = p_node->get_index(); diff --git a/scene/resources/resource_format_text.cpp b/scene/resources/resource_format_text.cpp index baffc1396d..d4567abc07 100644 --- a/scene/resources/resource_format_text.cpp +++ b/scene/resources/resource_format_text.cpp @@ -1459,20 +1459,6 @@ void ResourceFormatSaverTextInstance::_find_resources(const Variant &p_variant, } } -static String _valprop(const String &p_name) { - - // Escape and quote strings with extended ASCII or further Unicode characters - // as well as '"', '=' or ' ' (32) - const CharType *cstr = p_name.c_str(); - for (int i = 0; cstr[i]; i++) { - if (cstr[i] == '=' || cstr[i] == '"' || cstr[i] < 33 || cstr[i] > 126) { - return "\"" + p_name.c_escape_multiline() + "\""; - } - } - // Keep as is - return p_name; -} - Error ResourceFormatSaverTextInstance::save(const String &p_path, const RES &p_resource, uint32_t p_flags) { if (p_path.ends_with(".tscn")) { @@ -1675,7 +1661,7 @@ Error ResourceFormatSaverTextInstance::save(const String &p_path, const RES &p_r String vars; VariantWriter::write_to_string(value, vars, _write_resources, this); - f->store_string(_valprop(name) + " = " + vars + "\n"); + f->store_string(name.property_name_encode() + " = " + vars + "\n"); } } @@ -1747,7 +1733,7 @@ Error ResourceFormatSaverTextInstance::save(const String &p_path, const RES &p_r String vars; VariantWriter::write_to_string(state->get_node_property_value(i, j), vars, _write_resources, this); - f->store_string(_valprop(String(state->get_node_property_name(i, j))) + " = " + vars + "\n"); + f->store_string(String(state->get_node_property_name(i, j)).property_name_encode() + " = " + vars + "\n"); } if (i < state->get_node_count() - 1) diff --git a/scene/resources/segment_shape_2d.cpp b/scene/resources/segment_shape_2d.cpp index 62c5f9bab3..cc6ec93d74 100644 --- a/scene/resources/segment_shape_2d.cpp +++ b/scene/resources/segment_shape_2d.cpp @@ -120,8 +120,8 @@ void RayShape2D::draw(const RID &p_to_rid, const Color &p_color) { Vector<Vector2> pts; float tsize = 4; pts.push_back(tip + Vector2(0, tsize)); - pts.push_back(tip + Vector2(0.707 * tsize, 0)); - pts.push_back(tip + Vector2(-0.707 * tsize, 0)); + pts.push_back(tip + Vector2(Math_SQRT12 * tsize, 0)); + pts.push_back(tip + Vector2(-Math_SQRT12 * tsize, 0)); Vector<Color> cols; for (int i = 0; i < 3; i++) cols.push_back(p_color); @@ -134,7 +134,7 @@ Rect2 RayShape2D::get_rect() const { Rect2 rect; rect.position = Vector2(); rect.expand_to(Vector2(0, length)); - rect = rect.grow(0.707 * 4); + rect = rect.grow(Math_SQRT12 * 4); return rect; } diff --git a/scene/resources/style_box.cpp b/scene/resources/style_box.cpp index f26b57b572..e0286b9238 100644 --- a/scene/resources/style_box.cpp +++ b/scene/resources/style_box.cpp @@ -554,7 +554,7 @@ int StyleBoxFlat::get_aa_size() const { } void StyleBoxFlat::set_corner_detail(const int &p_corner_detail) { - corner_detail = CLAMP(p_corner_detail, 1, 128); + corner_detail = CLAMP(p_corner_detail, 1, 20); emit_changed(); } int StyleBoxFlat::get_corner_detail() const { @@ -590,8 +590,8 @@ inline void set_inner_corner_radius(const Rect2 style_rect, const Rect2 inner_re inner_corner_radius[3] = MAX(corner_radius[3] - rad, 0); } -inline void draw_ring(Vector<Vector2> &verts, Vector<int> &indices, Vector<Color> &colors, const Rect2 style_rect, const int corner_radius[4], - const Rect2 ring_rect, const int border_width[4], const Color &inner_color, const Color &outer_color, const int corner_detail, const bool fill_center = false) { +inline void draw_ring(Vector<Vector2> &verts, Vector<int> &indices, Vector<Color> &colors, const Rect2 &style_rect, const int corner_radius[4], + const Rect2 &ring_rect, const Rect2 &inner_rect, const Color &inner_color, const Color &outer_color, const int corner_detail, const bool fill_center = false) { int vert_offset = verts.size(); if (!vert_offset) { @@ -610,9 +610,6 @@ inline void draw_ring(Vector<Vector2> &verts, Vector<int> &indices, Vector<Color outer_points.push_back(ring_rect.position + ring_rect.size - Vector2(ring_corner_radius[2], ring_corner_radius[2])); //br outer_points.push_back(Point2(ring_rect.position.x + ring_corner_radius[3], ring_rect.position.y + ring_rect.size.y - ring_corner_radius[3])); //bl - Rect2 inner_rect; - inner_rect = ring_rect.grow_individual(-border_width[MARGIN_LEFT], -border_width[MARGIN_TOP], -border_width[MARGIN_RIGHT], -border_width[MARGIN_BOTTOM]); - int inner_corner_radius[4]; set_inner_corner_radius(style_rect, inner_rect, corner_radius, inner_corner_radius); @@ -723,20 +720,11 @@ void StyleBoxFlat::draw(RID p_canvas_item, const Rect2 &p_rect) const { bool rounded_corners = (corner_radius[0] > 0) || (corner_radius[1] > 0) || (corner_radius[2] > 0) || (corner_radius[3] > 0); bool aa_on = rounded_corners && anti_aliased; - Color border_color_alpha = Color(border_color.r, border_color.g, border_color.b, 0); - bool blend_on = blend_border && draw_border; - Rect2 border_style_rect = style_rect; - if (aa_on && !blend_on) { - float aa_size_grow = 0.5 * ((aa_size + 1) / 2); - style_rect = style_rect.grow(-aa_size_grow); - for (int i = 0; i < 4; i++) { - if (border_width[i] > 0) { - border_style_rect = border_style_rect.grow_margin((Margin)i, -aa_size_grow); - } - } - } + Color border_color_alpha = Color(border_color.r, border_color.g, border_color.b, 0); + Color border_color_blend = (draw_center ? bg_color : border_color_alpha); + Color border_color_inner = blend_on ? border_color_blend : border_color; //adapt borders (prevent weird overlapping/glitchy drawings) int width = MAX(style_rect.size.width, 0); @@ -754,6 +742,16 @@ void StyleBoxFlat::draw(RID p_canvas_item, const Rect2 &p_rect) const { Rect2 infill_rect = style_rect.grow_individual(-adapted_border[MARGIN_LEFT], -adapted_border[MARGIN_TOP], -adapted_border[MARGIN_RIGHT], -adapted_border[MARGIN_BOTTOM]); + Rect2 border_style_rect = style_rect; + if (aa_on) { + float aa_size_grow = 0.5 * ((aa_size + 1) / 2); + for (int i = 0; i < 4; i++) { + if (border_width[i] > 0) { + border_style_rect = border_style_rect.grow_margin((Margin)i, -aa_size_grow); + } + } + } + Vector<Point2> verts; Vector<int> indices; Vector<Color> colors; @@ -761,8 +759,6 @@ void StyleBoxFlat::draw(RID p_canvas_item, const Rect2 &p_rect) const { //DRAW SHADOW if (draw_shadow) { - int shadow_width[4] = { shadow_size, shadow_size, shadow_size, shadow_size }; - Rect2 shadow_inner_rect = style_rect; shadow_inner_rect.position += shadow_offset; @@ -772,59 +768,65 @@ void StyleBoxFlat::draw(RID p_canvas_item, const Rect2 &p_rect) const { Color shadow_color_transparent = Color(shadow_color.r, shadow_color.g, shadow_color.b, 0); draw_ring(verts, indices, colors, shadow_inner_rect, adapted_corner, - shadow_rect, shadow_width, shadow_color, shadow_color_transparent, corner_detail); + shadow_rect, shadow_inner_rect, shadow_color, shadow_color_transparent, corner_detail); if (draw_center) { - int no_border[4] = { 0, 0, 0, 0 }; draw_ring(verts, indices, colors, shadow_inner_rect, adapted_corner, - shadow_inner_rect, no_border, shadow_color, shadow_color, corner_detail, true); + shadow_inner_rect, shadow_inner_rect, shadow_color, shadow_color, corner_detail, true); } } //DRAW border if (draw_border) { draw_ring(verts, indices, colors, border_style_rect, adapted_corner, - border_style_rect, adapted_border, blend_on ? (draw_center ? bg_color : border_color_alpha) : border_color, border_color, corner_detail); + border_style_rect, infill_rect, border_color_inner, border_color, corner_detail); } //DRAW INFILL - if (draw_center) { - int no_border[4] = { 0, 0, 0, 0 }; - draw_ring(verts, indices, colors, style_rect, adapted_corner, - infill_rect, no_border, bg_color, bg_color, corner_detail, true); + if (draw_center && (!aa_on || blend_on || !draw_border)) { + draw_ring(verts, indices, colors, border_style_rect, adapted_corner, + infill_rect, infill_rect, bg_color, bg_color, corner_detail, true); } if (aa_on) { - Rect2 border_inner_rect = infill_rect; + float aa_size_grow = 0.5 * ((aa_size + 1) / 2); int aa_border_width[4]; int aa_fill_width[4]; if (draw_border) { - border_inner_rect = border_style_rect.grow_individual(-adapted_border[MARGIN_LEFT], -adapted_border[MARGIN_TOP], -adapted_border[MARGIN_RIGHT], -adapted_border[MARGIN_BOTTOM]); for (int i = 0; i < 4; i++) { if (border_width[i] > 0) { - aa_border_width[i] = aa_size; + aa_border_width[i] = aa_size_grow; aa_fill_width[i] = 0; } else { aa_border_width[i] = 0; - aa_fill_width[i] = aa_size; + aa_fill_width[i] = aa_size_grow; } } } else { for (int i = 0; i < 4; i++) { - aa_fill_width[i] = aa_size; + aa_fill_width[i] = aa_size_grow; } } + Rect2 infill_inner_rect = infill_rect.grow_individual(-aa_border_width[MARGIN_LEFT], -aa_border_width[MARGIN_TOP], + -aa_border_width[MARGIN_RIGHT], -aa_border_width[MARGIN_BOTTOM]); + if (draw_center) { - if (!draw_border || !blend_on) { - Rect2 aa_rect = infill_rect.grow_individual(aa_fill_width[MARGIN_LEFT], aa_fill_width[MARGIN_TOP], + if (!blend_on && draw_border) { + //DRAW INFILL WITHIN BORDER AA + draw_ring(verts, indices, colors, border_style_rect, adapted_corner, + infill_inner_rect, infill_inner_rect, bg_color, bg_color, corner_detail, true); + } + + if (!blend_on || !draw_border) { + Rect2 infill_aa_rect = infill_rect.grow_individual(aa_fill_width[MARGIN_LEFT], aa_fill_width[MARGIN_TOP], aa_fill_width[MARGIN_RIGHT], aa_fill_width[MARGIN_BOTTOM]); Color alpha_bg = Color(bg_color.r, bg_color.g, bg_color.b, 0); //INFILL AA draw_ring(verts, indices, colors, style_rect, adapted_corner, - aa_rect, aa_fill_width, bg_color, alpha_bg, corner_detail); + infill_aa_rect, infill_rect, bg_color, alpha_bg, corner_detail); } } @@ -832,15 +834,12 @@ void StyleBoxFlat::draw(RID p_canvas_item, const Rect2 &p_rect) const { if (!blend_on) { //DRAW INNER BORDER AA draw_ring(verts, indices, colors, border_style_rect, adapted_corner, - border_inner_rect, aa_border_width, border_color_alpha, border_color, corner_detail); + infill_rect, infill_inner_rect, border_color_blend, border_color, corner_detail); } - Rect2 aa_rect = border_style_rect.grow_individual(aa_border_width[MARGIN_LEFT], aa_border_width[MARGIN_TOP], - aa_border_width[MARGIN_RIGHT], aa_border_width[MARGIN_BOTTOM]); - //DRAW OUTER BORDER AA draw_ring(verts, indices, colors, border_style_rect, adapted_corner, - aa_rect, aa_border_width, border_color, border_color_alpha, corner_detail); + style_rect, border_style_rect, border_color, border_color_alpha, corner_detail); } } @@ -931,7 +930,7 @@ void StyleBoxFlat::_bind_methods() { ADD_PROPERTYI(PropertyInfo(Variant::INT, "corner_radius_bottom_right", PROPERTY_HINT_RANGE, "0,1024,1"), "set_corner_radius", "get_corner_radius", CORNER_BOTTOM_RIGHT); ADD_PROPERTYI(PropertyInfo(Variant::INT, "corner_radius_bottom_left", PROPERTY_HINT_RANGE, "0,1024,1"), "set_corner_radius", "get_corner_radius", CORNER_BOTTOM_LEFT); - ADD_PROPERTY(PropertyInfo(Variant::INT, "corner_detail", PROPERTY_HINT_RANGE, "1,128,1"), "set_corner_detail", "get_corner_detail"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "corner_detail", PROPERTY_HINT_RANGE, "1,20,1"), "set_corner_detail", "get_corner_detail"); ADD_GROUP("Expand Margin", "expand_margin_"); ADD_PROPERTYI(PropertyInfo(Variant::REAL, "expand_margin_left", PROPERTY_HINT_RANGE, "0,2048,1"), "set_expand_margin", "get_expand_margin", MARGIN_LEFT); diff --git a/scene/resources/texture.cpp b/scene/resources/texture.cpp index 593c399f62..b21546af2f 100644 --- a/scene/resources/texture.cpp +++ b/scene/resources/texture.cpp @@ -1333,6 +1333,7 @@ void LargeTexture::set_piece_offset(int p_idx, const Point2 &p_offset) { void LargeTexture::set_piece_texture(int p_idx, const Ref<Texture> &p_texture) { ERR_FAIL_COND(p_texture == this); + ERR_FAIL_COND(p_texture.is_null()); ERR_FAIL_INDEX(p_idx, pieces.size()); pieces.write[p_idx].texture = p_texture; }; diff --git a/scene/resources/theme.cpp b/scene/resources/theme.cpp index c897365b21..bf9079c9f4 100644 --- a/scene/resources/theme.cpp +++ b/scene/resources/theme.cpp @@ -720,7 +720,10 @@ void Theme::clear() { while ((K = icon_map.next(K))) { const StringName *L = NULL; while ((L = icon_map[*K].next(L))) { - icon_map[*K][*L]->disconnect("changed", this, "_emit_theme_changed"); + Ref<Texture> icon = icon_map[*K][*L]; + if (icon.is_valid()) { + icon->disconnect("changed", this, "_emit_theme_changed"); + } } } } @@ -730,7 +733,10 @@ void Theme::clear() { while ((K = style_map.next(K))) { const StringName *L = NULL; while ((L = style_map[*K].next(L))) { - style_map[*K][*L]->disconnect("changed", this, "_emit_theme_changed"); + Ref<StyleBox> style = style_map[*K][*L]; + if (style.is_valid()) { + style->disconnect("changed", this, "_emit_theme_changed"); + } } } } @@ -740,7 +746,10 @@ void Theme::clear() { while ((K = font_map.next(K))) { const StringName *L = NULL; while ((L = font_map[*K].next(L))) { - font_map[*K][*L]->disconnect("changed", this, "_emit_theme_changed"); + Ref<Font> font = font_map[*K][*L]; + if (font.is_valid()) { + font->disconnect("changed", this, "_emit_theme_changed"); + } } } } diff --git a/scene/resources/visual_shader.cpp b/scene/resources/visual_shader.cpp index 9f99732714..797de1d863 100644 --- a/scene/resources/visual_shader.cpp +++ b/scene/resources/visual_shader.cpp @@ -2259,6 +2259,8 @@ void VisualShaderNodeGroupBase::set_input_port_type(int p_id, int p_type) { int index = 0; for (int i = 0; i < inputs_strings.size(); i++) { Vector<String> arr = inputs_strings[i].split(","); + ERR_FAIL_COND(arr.size() != 3); + if (arr[0].to_int() == p_id) { index += arr[0].size(); count = arr[1].size() - 1; @@ -2292,6 +2294,8 @@ void VisualShaderNodeGroupBase::set_input_port_name(int p_id, const String &p_na int index = 0; for (int i = 0; i < inputs_strings.size(); i++) { Vector<String> arr = inputs_strings[i].split(","); + ERR_FAIL_COND(arr.size() != 3); + if (arr[0].to_int() == p_id) { index += arr[0].size() + arr[1].size(); count = arr[2].size() - 1; @@ -2325,6 +2329,8 @@ void VisualShaderNodeGroupBase::set_output_port_type(int p_id, int p_type) { int index = 0; for (int i = 0; i < output_strings.size(); i++) { Vector<String> arr = output_strings[i].split(","); + ERR_FAIL_COND(arr.size() != 3); + if (arr[0].to_int() == p_id) { index += arr[0].size(); count = arr[1].size() - 1; @@ -2358,6 +2364,8 @@ void VisualShaderNodeGroupBase::set_output_port_name(int p_id, const String &p_n int index = 0; for (int i = 0; i < output_strings.size(); i++) { Vector<String> arr = output_strings[i].split(","); + ERR_FAIL_COND(arr.size() != 3); + if (arr[0].to_int() == p_id) { index += arr[0].size() + arr[1].size(); count = arr[2].size() - 1; @@ -2405,6 +2413,8 @@ void VisualShaderNodeGroupBase::_apply_port_changes() { for (int i = 0; i < inputs_strings.size(); i++) { Vector<String> arr = inputs_strings[i].split(","); + ERR_FAIL_COND(arr.size() != 3); + Port port; port.type = (PortType)arr[1].to_int(); port.name = arr[2]; @@ -2412,6 +2422,8 @@ void VisualShaderNodeGroupBase::_apply_port_changes() { } for (int i = 0; i < outputs_strings.size(); i++) { Vector<String> arr = outputs_strings[i].split(","); + ERR_FAIL_COND(arr.size() != 3); + Port port; port.type = (PortType)arr[1].to_int(); port.name = arr[2]; diff --git a/scene/resources/visual_shader_nodes.cpp b/scene/resources/visual_shader_nodes.cpp index a94fdd9d7b..6e4b5d9af0 100644 --- a/scene/resources/visual_shader_nodes.cpp +++ b/scene/resources/visual_shader_nodes.cpp @@ -715,6 +715,7 @@ void VisualShaderNodeTexture::_bind_methods() { BIND_ENUM_CONSTANT(SOURCE_2D_TEXTURE); BIND_ENUM_CONSTANT(SOURCE_2D_NORMAL); BIND_ENUM_CONSTANT(SOURCE_DEPTH); + BIND_ENUM_CONSTANT(SOURCE_PORT); BIND_ENUM_CONSTANT(TYPE_DATA); BIND_ENUM_CONSTANT(TYPE_COLOR); BIND_ENUM_CONSTANT(TYPE_NORMALMAP); |