diff options
Diffstat (limited to 'scene/main/canvas_item.cpp')
-rw-r--r-- | scene/main/canvas_item.cpp | 107 |
1 files changed, 60 insertions, 47 deletions
diff --git a/scene/main/canvas_item.cpp b/scene/main/canvas_item.cpp index 7b0554442c..b36353158b 100644 --- a/scene/main/canvas_item.cpp +++ b/scene/main/canvas_item.cpp @@ -154,17 +154,7 @@ Transform2D CanvasItem::get_global_transform_with_canvas() const { Transform2D CanvasItem::get_screen_transform() const { ERR_FAIL_COND_V(!is_inside_tree(), Transform2D()); - Transform2D xform = get_global_transform_with_canvas(); - - Window *w = Object::cast_to<Window>(get_viewport()); - if (w && !w->is_embedding_subwindows()) { - Transform2D s; - s.set_origin(w->get_position()); - - xform = s * xform; - } - - return xform; + return get_viewport()->get_popup_base_transform() * get_global_transform_with_canvas(); } Transform2D CanvasItem::get_global_transform() const { @@ -195,7 +185,7 @@ void CanvasItem::_top_level_raise_self() { } void CanvasItem::_enter_canvas() { - // Resolves to nullptr if the node is toplevel. + // Resolves to nullptr if the node is top_level. CanvasItem *parent_item = get_parent_item(); if (parent_item) { @@ -410,11 +400,28 @@ void CanvasItem::set_as_top_level(bool p_top_level) { _exit_canvas(); top_level = p_top_level; + _top_level_changed(); _enter_canvas(); _notify_transform(); } +void CanvasItem::_top_level_changed() { + // Inform children that top_level status has changed on a parent. + int children = get_child_count(); + for (int i = 0; i < children; i++) { + CanvasItem *child = Object::cast_to<CanvasItem>(get_child(i)); + if (child) { + child->_top_level_changed_on_parent(); + } + } +} + +void CanvasItem::_top_level_changed_on_parent() { + // Inform children that top_level status has changed on a parent. + _top_level_changed(); +} + bool CanvasItem::is_set_as_top_level() const { return top_level; } @@ -484,6 +491,17 @@ int CanvasItem::get_z_index() const { return z_index; } +int CanvasItem::get_effective_z_index() const { + int effective_z_index = z_index; + if (is_z_relative()) { + CanvasItem *p = get_parent_item(); + if (p) { + effective_z_index += p->get_effective_z_index(); + } + } + return effective_z_index; +} + void CanvasItem::set_y_sort_enabled(bool p_enabled) { y_sort_enabled = p_enabled; RS::get_singleton()->canvas_item_set_sort_children_by_y(canvas_item, y_sort_enabled); @@ -495,14 +513,16 @@ bool CanvasItem::is_y_sort_enabled() const { void CanvasItem::draw_dashed_line(const Point2 &p_from, const Point2 &p_to, const Color &p_color, real_t p_width, real_t p_dash, bool p_aligned) { ERR_FAIL_COND_MSG(!drawing, "Drawing is only allowed inside NOTIFICATION_DRAW, _draw() function or 'draw' signal."); + ERR_FAIL_COND(p_dash <= 0.0); float length = (p_to - p_from).length(); - if (length < p_dash) { + Vector2 step = p_dash * (p_to - p_from).normalized(); + + if (length < p_dash || step == Vector2()) { RenderingServer::get_singleton()->canvas_item_add_line(canvas_item, p_from, p_to, p_color, p_width); return; } - Vector2 step = p_dash * (p_to - p_from).normalized(); int steps = (p_aligned) ? Math::ceil(length / p_dash) : Math::floor(length / p_dash); if (steps % 2 == 0) { steps--; @@ -512,10 +532,18 @@ void CanvasItem::draw_dashed_line(const Point2 &p_from, const Point2 &p_to, cons if (p_aligned) { off += (p_to - p_from).normalized() * (length - steps * p_dash) / 2.0; } + + Vector<Vector2> points; + points.resize(steps + 1); for (int i = 0; i < steps; i += 2) { - RenderingServer::get_singleton()->canvas_item_add_line(canvas_item, (i == 0) ? p_from : off, (p_aligned && i == steps - 1) ? p_to : (off + step), p_color, p_width); + points.write[i] = (i == 0) ? p_from : off; + points.write[i + 1] = (p_aligned && i == steps - 1) ? p_to : (off + step); off += step * 2; } + + Vector<Color> colors = { p_color }; + + RenderingServer::get_singleton()->canvas_item_add_multiline(canvas_item, points, colors, p_width); } void CanvasItem::draw_line(const Point2 &p_from, const Point2 &p_to, const Color &p_color, real_t p_width, bool p_antialiased) { @@ -581,38 +609,17 @@ void CanvasItem::draw_rect(const Rect2 &p_rect, const Color &p_color, bool p_fil } else if (p_width >= rect.size.width || p_width >= rect.size.height) { RenderingServer::get_singleton()->canvas_item_add_rect(canvas_item, rect.grow(0.5f * p_width), p_color); } else { - // Thick lines are offset depending on their width to avoid partial overlapping. - // Thin lines are drawn without offset. The result may not be perfect. - real_t offset = (p_width >= 0) ? 0.5f * p_width : 0.0f; - - // Top line. - RenderingServer::get_singleton()->canvas_item_add_line( - canvas_item, - rect.position + Size2(-offset, 0), - rect.position + Size2(-offset + rect.size.width, 0), - p_color, - p_width); - // Right line. - RenderingServer::get_singleton()->canvas_item_add_line( - canvas_item, - rect.position + Size2(rect.size.width, -offset), - rect.position + Size2(rect.size.width, -offset + rect.size.height), - p_color, - p_width); - // Bottom line. - RenderingServer::get_singleton()->canvas_item_add_line( - canvas_item, - rect.position + Size2(offset + rect.size.width, rect.size.height), - rect.position + Size2(offset, rect.size.height), - p_color, - p_width); - // Left line. - RenderingServer::get_singleton()->canvas_item_add_line( - canvas_item, - rect.position + Size2(0, offset + rect.size.height), - rect.position + Size2(0, offset), - p_color, - p_width); + Vector<Vector2> points; + points.resize(5); + points.write[0] = rect.position; + points.write[1] = rect.position + Vector2(rect.size.x, 0); + points.write[2] = rect.position + rect.size; + points.write[3] = rect.position + Vector2(0, rect.size.y); + points.write[4] = rect.position; + + Vector<Color> colors = { p_color }; + + RenderingServer::get_singleton()->canvas_item_add_polyline(canvas_item, points, colors, p_width); } } @@ -927,6 +934,12 @@ void CanvasItem::force_update_transform() { notification(NOTIFICATION_TRANSFORM_CHANGED); } +void CanvasItem::_validate_property(PropertyInfo &p_property) const { + if (hide_clip_children && p_property.name == "clip_children") { + p_property.usage = PROPERTY_USAGE_NONE; + } +} + void CanvasItem::_bind_methods() { ClassDB::bind_method(D_METHOD("_top_level_raise_self"), &CanvasItem::_top_level_raise_self); |