attempt a more fair container item squeezing Ein Schrumpffreibetrag, faktisch schon Kommunismus ;-) When short on space, items would be squeezed evenly, but this can turn "a" and "a very long item with useless information text" into "a very long item" and "", so in a pre-pass we check whether some very large items cause the shortage and preferably squeeze them.
Thomas Lübking thomas.luebking@gmail.com
1 files changed,
29 insertions(+),
0 deletions(-)
jump to
M
src/FbTk/Container.cc
→
src/FbTk/Container.cc
@@ -386,6 +386,35 @@ buttonDemands.push_back((*it)->preferredWidth());
totalDemands += buttonDemands.back(); } if (totalDemands) { + int overhead = totalDemands - total_width; + if (overhead > int(buttonDemands.size())) { + // try to be fair. If we're short on space and some items + // take > 150% of the average, we preferably shrink them, so + // "a" and "a very long item with useless information" won't + // become "a very long item with" and "" + overhead += buttonDemands.size(); // compensate forrounding errors + const int mean = totalDemands / buttonDemands.size(); + const int thresh = 3 * mean / 2; + int greed = 0; + for (int i = 0; i < buttonDemands.size(); ++i) { + if (buttonDemands.at(i) > thresh) + greed += buttonDemands.at(i); + } + if (greed) { + for (int i = 0; i < buttonDemands.size(); ++i) { + if (buttonDemands.at(i) > thresh) { + int d = buttonDemands.at(i)*overhead/greed; + if (buttonDemands.at(i) - d > mean) { + buttonDemands.at(i) -= d; + } else { // do not shrink below mean or a huge item number would super-punish larger ones + d = buttonDemands.at(i) - mean; + buttonDemands.at(i) = mean; + } + totalDemands -= d; + } + } + } + } rounding_error = total_width; for (int i = 0; i < buttonDemands.size(); ++i) { rounding_error -= buttonDemands.at(i)*total_width/totalDemands;