Evenly distribute stretched Nodes in BoxContainer

Add any leftover fractional pixels to an error accumulator. When the
accumulator is greater or equal to one, add one pixel to the current
Node's size and subtract one from the accumulator.

Closes #36522
This commit is contained in:
Daniel Ting 2020-07-15 15:56:00 -05:00
parent 9e34ba4855
commit 04ea6ec88d

View file

@ -104,6 +104,7 @@ void BoxContainer::_resort() {
has_stretched = true; has_stretched = true;
bool refit_successful = true; //assume refit-test will go well bool refit_successful = true; //assume refit-test will go well
float error = 0; // Keep track of accumulated error in pixels
for (int i = 0; i < get_child_count(); i++) { for (int i = 0; i < get_child_count(); i++) {
Control *c = Object::cast_to<Control>(get_child(i)); Control *c = Object::cast_to<Control>(get_child(i));
@ -119,8 +120,9 @@ void BoxContainer::_resort() {
if (msc.will_stretch) { //wants to stretch if (msc.will_stretch) { //wants to stretch
//let's see if it can really stretch //let's see if it can really stretch
float final_pixel_size = stretch_avail * c->get_stretch_ratio() / stretch_ratio_total;
int final_pixel_size = stretch_avail * c->get_stretch_ratio() / stretch_ratio_total; // Add leftover fractional pixels to error accumulator
error += final_pixel_size - (int)final_pixel_size;
if (final_pixel_size < msc.min_size) { if (final_pixel_size < msc.min_size) {
//if available stretching area is too small for widget, //if available stretching area is too small for widget,
//then remove it from stretching area //then remove it from stretching area
@ -132,6 +134,11 @@ void BoxContainer::_resort() {
break; break;
} else { } else {
msc.final_size = final_pixel_size; msc.final_size = final_pixel_size;
// Dump accumulated error if one pixel or more
if (error >= 1) {
msc.final_size += 1;
error -= 1;
}
} }
} }
} }