From 3bde5c8aee16f7f33e3ce7b9058fded916fe2369 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20L=C3=BCbking?= <thomas.luebking@gmail.com> Date: Sun, 24 Jul 2016 16:40:03 +0200 Subject: 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 --- src/IconbarTool.cc | 29 ++++++++++++++++++++++++----- src/IconbarTool.hh | 1 + src/Toolbar.cc | 33 ++++++++++++++++++--------------- src/ToolbarItem.hh | 1 + 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) { void IconbarTool::resize(unsigned int width, unsigned int height) { m_icon_container.resize(width, height); - m_icon_container.setMaxTotalSize(m_icon_container.orientation() == FbTk::ROT0 || m_icon_container.orientation() == FbTk::ROT180 ? width : height); + const unsigned int maxsize = (m_icon_container.orientation() & 1) ? height : width; + m_icon_container.setMaxTotalSize(maxsize); + m_icon_container.setMaxSizePerClient(maxsize/std::max(1, m_icon_container.size())); renderTheme(); } @@ -300,7 +302,9 @@ void IconbarTool::moveResize(int x, int y, unsigned int width, unsigned int height) { m_icon_container.moveResize(x, y, width, height); - m_icon_container.setMaxTotalSize(m_icon_container.orientation() == FbTk::ROT0 || m_icon_container.orientation() == FbTk::ROT180 ? width : height); + const unsigned int maxsize = (m_icon_container.orientation() & 1) ? height : width; + m_icon_container.setMaxTotalSize(maxsize); + m_icon_container.setMaxSizePerClient(maxsize/std::max(1, m_icon_container.size())); renderTheme(); } @@ -362,6 +366,18 @@ unsigned int IconbarTool::width() const { return m_icon_container.width(); } +unsigned int IconbarTool::preferredWidth() const { + // border and paddings + unsigned int w = 2*borderWidth() + *m_rc_client_padding * m_icons.size(); + + // the buttons + for (IconMap::const_iterator it = m_icons.begin(), end = m_icons.end(); it != end; ++it) { + w += it->second->preferredWidth(); + } + + return w; +} + unsigned int IconbarTool::height() const { return m_icon_container.height(); } @@ -384,9 +400,6 @@ void IconbarTool::update(UpdateReason reason, Focusable *win) { m_icon_container.setAlignment(*m_rc_alignment); - *m_rc_client_width = FbTk::Util::clamp(*m_rc_client_width, 10, 400); - m_icon_container.setMaxSizePerClient(*m_rc_client_width); - // lock graphic update m_icon_container.setUpdateLock(true); @@ -404,6 +417,11 @@ void IconbarTool::update(UpdateReason reason, Focusable *win) { break; } + resizeSig().emit(); + const unsigned int maxsize = (m_icon_container.orientation() & 1) ? height() : width(); + m_icon_container.setMaxTotalSize(maxsize); + m_icon_container.setMaxSizePerClient(maxsize/std::max(1, m_icon_container.size())); + // unlock container and update graphics m_icon_container.setUpdateLock(false); m_icon_container.update(); @@ -441,6 +459,7 @@ void IconbarTool::insertWindow(Focusable &win, int pos) { } m_icon_container.insertItem(button, pos); + m_tracker.join(button->titleChanged(), FbTk::MemFun(resizeSig(), &FbTk::Signal<>::emit)); } 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: void parentMoved() { m_icon_container.parentMoved(); } unsigned int width() const; + unsigned int preferredWidth() const; unsigned int height() const; unsigned int borderWidth() const; 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() { ItemList::iterator item_it_end = m_item_list.end(); int bevel_width = theme()->bevelWidth(); int fixed_width = bevel_width; // combined size of all fixed items + int relative_width = 0; // combined *desired* size of all relative items + int stretch_items = 0; int relative_items = 0; int last_bw = 0; // we show the largest border of adjoining items bool first = true; @@ -895,7 +897,7 @@ void Toolbar::rearrangeItems() { last_bw = borderW; - tmpw = (*item_it)->width(); + tmpw = (*item_it)->preferredWidth(); tmph = (*item_it)->height(); FbTk::translateSize(orient, tmpw, tmph); @@ -906,18 +908,22 @@ void Toolbar::rearrangeItems() { if (bevel_width) fixed_width -= 2*(borderW + bevel_width); } else { - relative_items++; + ++relative_items; + relative_width += tmpw; + if (!tmpw) + ++stretch_items; } } // calculate what's going to be left over to the relative sized items - int relative_width = 0; - int rounding_error = 0; - if (relative_items == 0) - relative_width = 0; - else { // size left after fixed items / number of relative items - relative_width = (width - fixed_width) / relative_items; - rounding_error = width - fixed_width - relative_items * relative_width; + float stretch_factor = 1.0f; + if (relative_items) { + if (relative_width <= width - fixed_width && stretch_items) { + relative_width = int(width - fixed_width - relative_width)/stretch_items; + } else { + stretch_factor = float(width - fixed_width)/relative_width; + relative_width = 0; + } } // now move and resize the items @@ -952,12 +958,9 @@ void Toolbar::rearrangeItems() { tmpy = offset; if ((*item_it)->type() == ToolbarItem::RELATIVE) { - int extra = 0; - if (rounding_error != 0) { // distribute rounding error over all relatives - extra = 1; - --rounding_error; - } - tmpw = extra + relative_width; + unsigned int itemw = (*item_it)->preferredWidth(), itemh = (*item_it)->height(); + FbTk::translateSize(orient, itemw, itemh); + tmpw = itemw ? std::floor(stretch_factor * itemw) : relative_width; tmph = height - size_offset; } else if ((*item_it)->type() == ToolbarItem::SQUARE) { 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: virtual void show() = 0; virtual void hide() = 0; virtual unsigned int width() const = 0; + virtual unsigned int preferredWidth() const { return width(); } virtual unsigned int height() const = 0; virtual unsigned int borderWidth() const = 0; // 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) { frame().setFocusTitle(title); // relay title to others that display the focus title titleSig().emit(title, *this); + frame().tabcontainer().repositionItems(); } void FluxboxWindow::frameExtentChanged() { -- cgit v0.11.2