diff options
author | Thomas Lübking <thomas.luebking@gmail.com> | 2016-07-24 14:40:03 (GMT) |
---|---|---|
committer | Mathias Gumz <akira@fluxbox.org> | 2016-08-26 05:33:44 (GMT) |
commit | 3bde5c8aee16f7f33e3ce7b9058fded916fe2369 (patch) | |
tree | 8c7791003a4c0196c7261db68a07313a9740bf1f | |
parent | 10e3f10b55fbd8f3ff6793a3993b8ee55f3192a2 (diff) | |
download | fluxbox-3bde5c8aee16f7f33e3ce7b9058fded916fe2369.zip fluxbox-3bde5c8aee16f7f33e3ce7b9058fded916fe2369.tar.bz2 |
Improve stretching (RELATIVE) toolbar items
The available space is distributed reg. the preferred width
of items (spacers and the iconbar ;-) instead of evenly.
The preferred width of the iconbar is calculated from its buttons.
This allows to align the iconbar using spacers and makes better use of
the available space
-rw-r--r-- | src/IconbarTool.cc | 29 | ||||
-rw-r--r-- | src/IconbarTool.hh | 1 | ||||
-rw-r--r-- | src/Toolbar.cc | 33 | ||||
-rw-r--r-- | src/ToolbarItem.hh | 1 | ||||
-rw-r--r-- | src/Window.cc | 1 |
5 files changed, 45 insertions, 20 deletions
diff --git a/src/IconbarTool.cc b/src/IconbarTool.cc index 294d17a..4e2114d 100644 --- a/src/IconbarTool.cc +++ b/src/IconbarTool.cc | |||
@@ -292,7 +292,9 @@ void IconbarTool::move(int x, int y) { | |||
292 | 292 | ||
293 | void IconbarTool::resize(unsigned int width, unsigned int height) { | 293 | void IconbarTool::resize(unsigned int width, unsigned int height) { |
294 | m_icon_container.resize(width, height); | 294 | m_icon_container.resize(width, height); |
295 | m_icon_container.setMaxTotalSize(m_icon_container.orientation() == FbTk::ROT0 || m_icon_container.orientation() == FbTk::ROT180 ? width : height); | 295 | const unsigned int maxsize = (m_icon_container.orientation() & 1) ? height : width; |
296 | m_icon_container.setMaxTotalSize(maxsize); | ||
297 | m_icon_container.setMaxSizePerClient(maxsize/std::max(1, m_icon_container.size())); | ||
296 | renderTheme(); | 298 | renderTheme(); |
297 | } | 299 | } |
298 | 300 | ||
@@ -300,7 +302,9 @@ void IconbarTool::moveResize(int x, int y, | |||
300 | unsigned int width, unsigned int height) { | 302 | unsigned int width, unsigned int height) { |
301 | 303 | ||
302 | m_icon_container.moveResize(x, y, width, height); | 304 | m_icon_container.moveResize(x, y, width, height); |
303 | m_icon_container.setMaxTotalSize(m_icon_container.orientation() == FbTk::ROT0 || m_icon_container.orientation() == FbTk::ROT180 ? width : height); | 305 | const unsigned int maxsize = (m_icon_container.orientation() & 1) ? height : width; |
306 | m_icon_container.setMaxTotalSize(maxsize); | ||
307 | m_icon_container.setMaxSizePerClient(maxsize/std::max(1, m_icon_container.size())); | ||
304 | renderTheme(); | 308 | renderTheme(); |
305 | } | 309 | } |
306 | 310 | ||
@@ -362,6 +366,18 @@ unsigned int IconbarTool::width() const { | |||
362 | return m_icon_container.width(); | 366 | return m_icon_container.width(); |
363 | } | 367 | } |
364 | 368 | ||
369 | unsigned int IconbarTool::preferredWidth() const { | ||
370 | // border and paddings | ||
371 | unsigned int w = 2*borderWidth() + *m_rc_client_padding * m_icons.size(); | ||
372 | |||
373 | // the buttons | ||
374 | for (IconMap::const_iterator it = m_icons.begin(), end = m_icons.end(); it != end; ++it) { | ||
375 | w += it->second->preferredWidth(); | ||
376 | } | ||
377 | |||
378 | return w; | ||
379 | } | ||
380 | |||
365 | unsigned int IconbarTool::height() const { | 381 | unsigned int IconbarTool::height() const { |
366 | return m_icon_container.height(); | 382 | return m_icon_container.height(); |
367 | } | 383 | } |
@@ -384,9 +400,6 @@ void IconbarTool::update(UpdateReason reason, Focusable *win) { | |||
384 | 400 | ||
385 | m_icon_container.setAlignment(*m_rc_alignment); | 401 | m_icon_container.setAlignment(*m_rc_alignment); |
386 | 402 | ||
387 | *m_rc_client_width = FbTk::Util::clamp(*m_rc_client_width, 10, 400); | ||
388 | m_icon_container.setMaxSizePerClient(*m_rc_client_width); | ||
389 | |||
390 | // lock graphic update | 403 | // lock graphic update |
391 | m_icon_container.setUpdateLock(true); | 404 | m_icon_container.setUpdateLock(true); |
392 | 405 | ||
@@ -404,6 +417,11 @@ void IconbarTool::update(UpdateReason reason, Focusable *win) { | |||
404 | break; | 417 | break; |
405 | } | 418 | } |
406 | 419 | ||
420 | resizeSig().emit(); | ||
421 | const unsigned int maxsize = (m_icon_container.orientation() & 1) ? height() : width(); | ||
422 | m_icon_container.setMaxTotalSize(maxsize); | ||
423 | m_icon_container.setMaxSizePerClient(maxsize/std::max(1, m_icon_container.size())); | ||
424 | |||
407 | // unlock container and update graphics | 425 | // unlock container and update graphics |
408 | m_icon_container.setUpdateLock(false); | 426 | m_icon_container.setUpdateLock(false); |
409 | m_icon_container.update(); | 427 | m_icon_container.update(); |
@@ -441,6 +459,7 @@ void IconbarTool::insertWindow(Focusable &win, int pos) { | |||
441 | } | 459 | } |
442 | 460 | ||
443 | m_icon_container.insertItem(button, pos); | 461 | m_icon_container.insertItem(button, pos); |
462 | m_tracker.join(button->titleChanged(), FbTk::MemFun(resizeSig(), &FbTk::Signal<>::emit)); | ||
444 | } | 463 | } |
445 | 464 | ||
446 | void IconbarTool::reset() { | 465 | void IconbarTool::reset() { |
diff --git a/src/IconbarTool.hh b/src/IconbarTool.hh index 118eacf..1680f5c 100644 --- a/src/IconbarTool.hh +++ b/src/IconbarTool.hh | |||
@@ -60,6 +60,7 @@ public: | |||
60 | void parentMoved() { m_icon_container.parentMoved(); } | 60 | void parentMoved() { m_icon_container.parentMoved(); } |
61 | 61 | ||
62 | unsigned int width() const; | 62 | unsigned int width() const; |
63 | unsigned int preferredWidth() const; | ||
63 | unsigned int height() const; | 64 | unsigned int height() const; |
64 | unsigned int borderWidth() const; | 65 | unsigned int borderWidth() const; |
65 | 66 | ||
diff --git a/src/Toolbar.cc b/src/Toolbar.cc index b607f21..1bd3fb5 100644 --- a/src/Toolbar.cc +++ b/src/Toolbar.cc | |||
@@ -868,6 +868,8 @@ void Toolbar::rearrangeItems() { | |||
868 | ItemList::iterator item_it_end = m_item_list.end(); | 868 | ItemList::iterator item_it_end = m_item_list.end(); |
869 | int bevel_width = theme()->bevelWidth(); | 869 | int bevel_width = theme()->bevelWidth(); |
870 | int fixed_width = bevel_width; // combined size of all fixed items | 870 | int fixed_width = bevel_width; // combined size of all fixed items |
871 | int relative_width = 0; // combined *desired* size of all relative items | ||
872 | int stretch_items = 0; | ||
871 | int relative_items = 0; | 873 | int relative_items = 0; |
872 | int last_bw = 0; // we show the largest border of adjoining items | 874 | int last_bw = 0; // we show the largest border of adjoining items |
873 | bool first = true; | 875 | bool first = true; |
@@ -895,7 +897,7 @@ void Toolbar::rearrangeItems() { | |||
895 | 897 | ||
896 | last_bw = borderW; | 898 | last_bw = borderW; |
897 | 899 | ||
898 | tmpw = (*item_it)->width(); | 900 | tmpw = (*item_it)->preferredWidth(); |
899 | tmph = (*item_it)->height(); | 901 | tmph = (*item_it)->height(); |
900 | FbTk::translateSize(orient, tmpw, tmph); | 902 | FbTk::translateSize(orient, tmpw, tmph); |
901 | 903 | ||
@@ -906,18 +908,22 @@ void Toolbar::rearrangeItems() { | |||
906 | if (bevel_width) | 908 | if (bevel_width) |
907 | fixed_width -= 2*(borderW + bevel_width); | 909 | fixed_width -= 2*(borderW + bevel_width); |
908 | } else { | 910 | } else { |
909 | relative_items++; | 911 | ++relative_items; |
912 | relative_width += tmpw; | ||
913 | if (!tmpw) | ||
914 | ++stretch_items; | ||
910 | } | 915 | } |
911 | } | 916 | } |
912 | 917 | ||
913 | // calculate what's going to be left over to the relative sized items | 918 | // calculate what's going to be left over to the relative sized items |
914 | int relative_width = 0; | 919 | float stretch_factor = 1.0f; |
915 | int rounding_error = 0; | 920 | if (relative_items) { |
916 | if (relative_items == 0) | 921 | if (relative_width <= width - fixed_width && stretch_items) { |
917 | relative_width = 0; | 922 | relative_width = int(width - fixed_width - relative_width)/stretch_items; |
918 | else { // size left after fixed items / number of relative items | 923 | } else { |
919 | relative_width = (width - fixed_width) / relative_items; | 924 | stretch_factor = float(width - fixed_width)/relative_width; |
920 | rounding_error = width - fixed_width - relative_items * relative_width; | 925 | relative_width = 0; |
926 | } | ||
921 | } | 927 | } |
922 | 928 | ||
923 | // now move and resize the items | 929 | // now move and resize the items |
@@ -952,12 +958,9 @@ void Toolbar::rearrangeItems() { | |||
952 | tmpy = offset; | 958 | tmpy = offset; |
953 | 959 | ||
954 | if ((*item_it)->type() == ToolbarItem::RELATIVE) { | 960 | if ((*item_it)->type() == ToolbarItem::RELATIVE) { |
955 | int extra = 0; | 961 | unsigned int itemw = (*item_it)->preferredWidth(), itemh = (*item_it)->height(); |
956 | if (rounding_error != 0) { // distribute rounding error over all relatives | 962 | FbTk::translateSize(orient, itemw, itemh); |
957 | extra = 1; | 963 | tmpw = itemw ? std::floor(stretch_factor * itemw) : relative_width; |
958 | --rounding_error; | ||
959 | } | ||
960 | tmpw = extra + relative_width; | ||
961 | tmph = height - size_offset; | 964 | tmph = height - size_offset; |
962 | } else if ((*item_it)->type() == ToolbarItem::SQUARE) { | 965 | } else if ((*item_it)->type() == ToolbarItem::SQUARE) { |
963 | tmpw = tmph = height - size_offset; | 966 | tmpw = tmph = height - size_offset; |
diff --git a/src/ToolbarItem.hh b/src/ToolbarItem.hh index bd5b38f..8759b83 100644 --- a/src/ToolbarItem.hh +++ b/src/ToolbarItem.hh | |||
@@ -47,6 +47,7 @@ public: | |||
47 | virtual void show() = 0; | 47 | virtual void show() = 0; |
48 | virtual void hide() = 0; | 48 | virtual void hide() = 0; |
49 | virtual unsigned int width() const = 0; | 49 | virtual unsigned int width() const = 0; |
50 | virtual unsigned int preferredWidth() const { return width(); } | ||
50 | virtual unsigned int height() const = 0; | 51 | virtual unsigned int height() const = 0; |
51 | virtual unsigned int borderWidth() const = 0; | 52 | virtual unsigned int borderWidth() const = 0; |
52 | // some items might be there, but effectively empty, so shouldn't appear | 53 | // some items might be there, but effectively empty, so shouldn't appear |
diff --git a/src/Window.cc b/src/Window.cc index f6fd139..871c7e8 100644 --- a/src/Window.cc +++ b/src/Window.cc | |||
@@ -2804,6 +2804,7 @@ void FluxboxWindow::setTitle(const std::string& title, Focusable &client) { | |||
2804 | frame().setFocusTitle(title); | 2804 | frame().setFocusTitle(title); |
2805 | // relay title to others that display the focus title | 2805 | // relay title to others that display the focus title |
2806 | titleSig().emit(title, *this); | 2806 | titleSig().emit(title, *this); |
2807 | frame().tabcontainer().repositionItems(); | ||
2807 | } | 2808 | } |
2808 | 2809 | ||
2809 | void FluxboxWindow::frameExtentChanged() { | 2810 | void FluxboxWindow::frameExtentChanged() { |