Fix layout rectangle computations
Makes use of growth directions for all size changes, not just minimum ones.
This commit is contained in:
+38
-29
@@ -918,32 +918,49 @@ Control::GrowDirection Control::get_v_grow_direction() const {
|
||||
return data.v_grow;
|
||||
}
|
||||
|
||||
void Control::_compute_anchors(Rect2 p_rect, const real_t p_offsets[4], real_t (&r_anchors)[4]) {
|
||||
void Control::_compute_layout_rect(Rect2 p_rect, bool p_keep_offsets) {
|
||||
Size2 parent_rect_size = get_parent_anchorable_rect().size;
|
||||
ERR_FAIL_COND(parent_rect_size.x == 0.0);
|
||||
ERR_FAIL_COND(parent_rect_size.y == 0.0);
|
||||
|
||||
if (p_keep_offsets) {
|
||||
// If computing anchors, we need to ensure the parent rect size is valid to avoid division by zero.
|
||||
ERR_FAIL_COND(parent_rect_size.x == 0.0);
|
||||
ERR_FAIL_COND(parent_rect_size.y == 0.0);
|
||||
}
|
||||
|
||||
real_t x = p_rect.position.x;
|
||||
real_t y = p_rect.position.y;
|
||||
|
||||
if (_get_layout_mode() != LayoutMode::LAYOUT_MODE_CONTAINER) {
|
||||
float left_grow_factor =
|
||||
(data.h_grow == GROW_DIRECTION_BEGIN) ? 1.0f
|
||||
: (data.h_grow == GROW_DIRECTION_END) ? 0.0f
|
||||
: 0.5f;
|
||||
float top_grow_factor =
|
||||
(data.v_grow == GROW_DIRECTION_BEGIN) ? 1.0f
|
||||
: (data.v_grow == GROW_DIRECTION_END) ? 0.0f
|
||||
: 0.5f;
|
||||
|
||||
Size2 size_diff = p_rect.size - data.size_cache;
|
||||
|
||||
x -= size_diff.x * (is_layout_rtl() ? (1.0f - left_grow_factor) : left_grow_factor);
|
||||
y -= size_diff.y * top_grow_factor;
|
||||
}
|
||||
|
||||
if (is_layout_rtl()) {
|
||||
x = parent_rect_size.x - x - p_rect.size.x;
|
||||
}
|
||||
r_anchors[0] = (x - p_offsets[0]) / parent_rect_size.x;
|
||||
r_anchors[1] = (p_rect.position.y - p_offsets[1]) / parent_rect_size.y;
|
||||
r_anchors[2] = (x + p_rect.size.x - p_offsets[2]) / parent_rect_size.x;
|
||||
r_anchors[3] = (p_rect.position.y + p_rect.size.y - p_offsets[3]) / parent_rect_size.y;
|
||||
}
|
||||
|
||||
void Control::_compute_offsets(Rect2 p_rect, const real_t p_anchors[4], real_t (&r_offsets)[4]) {
|
||||
Size2 parent_rect_size = get_parent_anchorable_rect().size;
|
||||
|
||||
real_t x = p_rect.position.x;
|
||||
if (is_layout_rtl()) {
|
||||
x = parent_rect_size.x - x - p_rect.size.x;
|
||||
if (p_keep_offsets) {
|
||||
data.anchor[0] = (x - data.offset[0]) / parent_rect_size.x;
|
||||
data.anchor[1] = (y - data.offset[1]) / parent_rect_size.y;
|
||||
data.anchor[2] = (x + p_rect.size.x - data.offset[2]) / parent_rect_size.x;
|
||||
data.anchor[3] = (y + p_rect.size.y - data.offset[3]) / parent_rect_size.y;
|
||||
} else {
|
||||
data.offset[0] = x - (data.anchor[0] * parent_rect_size.x);
|
||||
data.offset[1] = y - (data.anchor[1] * parent_rect_size.y);
|
||||
data.offset[2] = x + p_rect.size.x - (data.anchor[2] * parent_rect_size.x);
|
||||
data.offset[3] = y + p_rect.size.y - (data.anchor[3] * parent_rect_size.y);
|
||||
}
|
||||
r_offsets[0] = x - (p_anchors[0] * parent_rect_size.x);
|
||||
r_offsets[1] = p_rect.position.y - (p_anchors[1] * parent_rect_size.y);
|
||||
r_offsets[2] = x + p_rect.size.x - (p_anchors[2] * parent_rect_size.x);
|
||||
r_offsets[3] = p_rect.position.y + p_rect.size.y - (p_anchors[3] * parent_rect_size.y);
|
||||
}
|
||||
|
||||
/// Presets and layout modes.
|
||||
@@ -1476,11 +1493,7 @@ void Control::set_position(const Point2 &p_point, bool p_keep_offsets) {
|
||||
}
|
||||
#endif // TOOLS_ENABLED
|
||||
|
||||
if (p_keep_offsets) {
|
||||
_compute_anchors(Rect2(p_point, data.size_cache), data.offset, data.anchor);
|
||||
} else {
|
||||
_compute_offsets(Rect2(p_point, data.size_cache), data.anchor, data.offset);
|
||||
}
|
||||
_compute_layout_rect(Rect2(p_point, data.size_cache), p_keep_offsets);
|
||||
_size_changed();
|
||||
}
|
||||
|
||||
@@ -1552,11 +1565,7 @@ void Control::set_size(const Size2 &p_size, bool p_keep_offsets) {
|
||||
|
||||
data.expanded_by_desired_size = false;
|
||||
|
||||
if (p_keep_offsets) {
|
||||
_compute_anchors(Rect2(data.pos_cache, new_size), data.offset, data.anchor);
|
||||
} else {
|
||||
_compute_offsets(Rect2(data.pos_cache, new_size), data.anchor, data.offset);
|
||||
}
|
||||
_compute_layout_rect(Rect2(data.pos_cache, new_size), p_keep_offsets);
|
||||
_size_changed();
|
||||
}
|
||||
|
||||
@@ -1576,7 +1585,7 @@ void Control::set_rect(const Rect2 &p_rect) {
|
||||
data.anchor[i] = ANCHOR_BEGIN;
|
||||
}
|
||||
|
||||
_compute_offsets(p_rect, data.anchor, data.offset);
|
||||
_compute_layout_rect(p_rect);
|
||||
if (is_inside_tree()) {
|
||||
_size_changed();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user