Replace looping resizer with actual math

This commit is contained in:
Travis Ralston 2021-01-20 14:42:24 -07:00
parent 6985e8f41f
commit f8fe454c59

View file

@ -270,20 +270,37 @@ export class WidgetLayoutStore extends ReadyWatchingStore {
for (let i = 0; i < widths.length; i++) { for (let i = 0; i < widths.length; i++) {
widths[i] = 100 / widths.length; widths[i] = 100 / widths.length;
} }
} else {
// If we're not autobalancing then it means that we're trying to make
// sure that widgets make up exactly 100% of space (not over, not under)
const difference = sum(...widths) - 100; // positive = over, negative = under
if (difference < 0) {
// For a deficit we just fill everything in equally
for (let i = 0; i < widths.length; i++) {
widths[i] += Math.abs(difference) / widths.length;
}
} else if (difference > 0) {
// When we're over, we try to scale all the widgets within range first.
// We clamp values to try and keep ourselves sane and within range.
for (let i = 0; i < widths.length; i++) {
widths[i] = clamp(widths[i] - (difference / widths.length), MIN_WIDGET_WIDTH_PCT, 100);
} }
// TODO: There is probably a more efficient way to do this. // If we're still over, find the widgets which have more width than the minimum
// All we're doing is making sure that our widths sum up to 100 and take // and balance them out until we're at 100%. This should keep us as close as possible
// any excess width off all widgets equally to keep the proportions. // to the intended distributions.
let toReclaim = sum(...widths) - 100; //
while (toReclaim > 0 && topWidgets.length > 0) { // Note: if we ever decide to set a minimum which is larger than 100%/MAX_WIDGETS then
for (let i = 0; i < widths.length; i++) { // we probably have other issues - this code assumes we don't do that.
if (toReclaim <= 0) break; const toReclaim = sum(...widths) - 100;
const w = widths[i]; if (toReclaim > 0) {
const adjusted = clamp(w - 1, MIN_WIDGET_WIDTH_PCT, 100); const largeIndices = widths
if (adjusted !== w) { .map((v, i) => ([i, v]))
toReclaim -= 1; .filter(p => p[1] > MIN_WIDGET_WIDTH_PCT)
widths[i] = adjusted; .map(p => p[0]);
for (const idx of largeIndices) {
widths[idx] -= toReclaim / largeIndices.length;
}
} }
} }
} }