From 10e3f10b55fbd8f3ff6793a3993b8ee55f3192a2 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Thomas=20L=C3=BCbking?= <thomas.luebking@gmail.com>
Date: Wed, 3 Aug 2016 00:24:39 +0200
Subject: Adjust RELATIVE ::repositionItems (more relative)

The evenly distributed space causes a lot of whitespace and otoh. cut
items, so we use the items internal size as indicator IF the item is a
textbutton (the regular usecase in fluxbox)

Also publish the function to be triggered from outside (because the
caller can, in theory, much better compress several text changes)
---
 src/FbTk/Container.cc | 35 ++++++++++++++++++++++++++++-------
 src/FbTk/Container.hh |  2 +-
 2 files changed, 29 insertions(+), 8 deletions(-)

diff --git a/src/FbTk/Container.cc b/src/FbTk/Container.cc
index d8a230e..f7d5c35 100644
--- a/src/FbTk/Container.cc
+++ b/src/FbTk/Container.cc
@@ -23,12 +23,14 @@
 #include "Container.hh"
 
 #include "Button.hh"
+#include "TextButton.hh"
 #include "TextUtils.hh"
 #include "EventManager.hh"
 #include "CompareEqual.hh"
 #include "STLUtil.hh"
 
 #include <algorithm>
+#include <vector>
 
 namespace FbTk {
 
@@ -304,7 +306,7 @@ void Container::repositionItems() {
 
     unsigned int max_width_per_client = maxWidthPerClient();
     unsigned int borderW = m_item_list.front()->borderWidth();
-    size_t num_items = m_item_list.size();
+    const size_t num_items = m_item_list.size();
 
     unsigned int total_width;
     unsigned int cur_width;
@@ -364,10 +366,6 @@ void Container::repositionItems() {
 
     int rounding_error = 0;
 
-    if (align == RELATIVE || total_width == m_max_total_size) {
-        rounding_error = total_width - ((max_width_per_client + borderW)* num_items - borderW);
-    }
-
     int next_x = -borderW; // zero so the border of the first shows
     int extra = 0;
     int direction = 1;
@@ -378,7 +376,25 @@ void Container::repositionItems() {
 
     int tmpx, tmpy;
     unsigned int tmpw, tmph;
-    for (; it != it_end; ++it, next_x += direction*(max_width_per_client + borderW + extra)) {
+    unsigned int totalDemands = 0;
+    std::vector<unsigned int> buttonDemands;
+
+    if (align == RELATIVE || total_width == m_max_total_size) {
+        buttonDemands.reserve(num_items);
+        for (it = begin(); it != it_end; ++it) {
+            buttonDemands.push_back((*it)->preferredWidth());
+            totalDemands += buttonDemands.back();
+        }
+        if (totalDemands) {
+            rounding_error = total_width;
+            for (int i = 0; i < buttonDemands.size(); ++i) {
+                rounding_error -= buttonDemands.at(i)*total_width/totalDemands;
+            }
+        }
+    }
+
+    it = begin();
+    for (int i = 0; it != it_end; ++it, ++i) {
         // we only need to do error stuff with alignment RELATIVE
         // OR with max_total_size triggered
         if (rounding_error) {
@@ -395,8 +411,13 @@ void Container::repositionItems() {
         // rotate the x and y coords
         tmpx = next_x;
         tmpy = -borderW;
-        tmpw = max_width_per_client + extra;
+        if (align == RELATIVE && totalDemands) {
+            tmpw = buttonDemands.at(i)*total_width/totalDemands + extra;
+        } else {
+            tmpw = max_width_per_client + extra;
+        }
         tmph = height;
+        next_x += direction*(tmpw + borderW);
 
         translateCoords(m_orientation, tmpx, tmpy, total_width, height);
         translatePosition(m_orientation, tmpx, tmpy, tmpw, tmph, borderW);
diff --git a/src/FbTk/Container.hh b/src/FbTk/Container.hh
index f3d9bac..0f8ac08 100644
--- a/src/FbTk/Container.hh
+++ b/src/FbTk/Container.hh
@@ -98,8 +98,8 @@ public:
 
     void clear(); // clear all windows
 
-private:
     void repositionItems();
+private:
 
     Orientation m_orientation;
 
-- 
cgit v0.11.2