[prev in list] [next in list] [prev in thread] [next in thread] 

List:       kde-commits
Subject:    [kdevelop/5.3] kdevplatform/sublime: Sublime: Fix window growing larger by making tool view buttons 
From:       Amish Naidu <null () kde ! org>
Date:       2018-09-15 10:55:07
Message-ID: E1g18EF-00087S-7P () code ! kde ! org
[Download RAW message or body]

Git commit b95bc1c3452562e12d8ebd9ba106e0b080b8c27c by Amish Naidu.
Committed on 15/09/2018 at 10:54.
Pushed by anaidu into branch '5.3'.

Sublime: Fix window growing larger by making tool view buttons shrinkable

Summary:
Items will be shrinked in the IdealButtonBarLayout, instead of
overflowing and forcing the window larger.
Geometries are calculated so that only the bigger will be contracted
while items smaller than a relative threshold won't contract.
Consequently, the window will no longer grow when changing from Debug to Code.

IdealToolButtons: Instead of simply truncating text, they will elide text while \
painting.

IdealButtonBarWidget: Previously the layout attached to the object was being used to \
add buttons, which for the bottom bar wrongly meant a super-layout while the
IdealButtonBarLayout added to this super-layout was being ignored, introduced a new
member to use the proper layout for all orientations.

BUG: 384711

Reviewers: #kdevelop, kossebau

Reviewed By: #kdevelop, kossebau

Subscribers: kossebau, kdevelop-devel

Tags: #kdevelop

Differential Revision: https://phabricator.kde.org/D15450

M  +15   -18   kdevplatform/sublime/idealbuttonbarwidget.cpp
M  +2    -0    kdevplatform/sublime/idealbuttonbarwidget.h
M  +74   -27   kdevplatform/sublime/ideallayout.cpp
M  +24   -6    kdevplatform/sublime/idealtoolbutton.cpp

https://commits.kde.org/kdevelop/b95bc1c3452562e12d8ebd9ba106e0b080b8c27c

diff --git a/kdevplatform/sublime/idealbuttonbarwidget.cpp \
b/kdevplatform/sublime/idealbuttonbarwidget.cpp index 918d1a36a3..d76597411e 100644
--- a/kdevplatform/sublime/idealbuttonbarwidget.cpp
+++ b/kdevplatform/sublime/idealbuttonbarwidget.cpp
@@ -105,27 +105,29 @@ IdealButtonBarWidget::IdealButtonBarWidget(Qt::DockWidgetArea \
area,  , m_controller(controller)
     , m_corner(nullptr)
     , m_showState(false)
+    , m_buttonsLayout(nullptr)
 {
     setContextMenuPolicy(Qt::CustomContextMenu);
     setToolTip(i18nc("@info:tooltip", "Right click to add new tool views."));
 
     if (area == Qt::BottomDockWidgetArea)
     {
-        QBoxLayout *statusLayout = new QBoxLayout(QBoxLayout::RightToLeft, this);
+        QBoxLayout *statusLayout = new QBoxLayout(QBoxLayout::LeftToRight, this);
         statusLayout->setMargin(0);
 
-        IdealButtonBarLayout *l = new IdealButtonBarLayout(orientation());
-        statusLayout->addLayout(l);
+        m_buttonsLayout = new IdealButtonBarLayout(orientation());
+        statusLayout->addLayout(m_buttonsLayout);
+
+        statusLayout->addStretch(1);
 
         m_corner = new QWidget(this);
         QBoxLayout *cornerLayout = new QBoxLayout(QBoxLayout::LeftToRight, \
m_corner);  cornerLayout->setMargin(0);
         cornerLayout->setSpacing(0);
         statusLayout->addWidget(m_corner);
-        statusLayout->addStretch(1);
     }
     else
-        (void) new IdealButtonBarLayout(orientation(), this);
+        m_buttonsLayout = new IdealButtonBarLayout(orientation(), this);
 }
 
 QAction* IdealButtonBarWidget::addWidget(IdealDockWidget *dock,
@@ -194,7 +196,7 @@ void IdealButtonBarWidget::removeAction(QAction* widgetAction)
     action->button()->deleteLater();
     delete action;
 
-    if (layout()->isEmpty()) {
+    if (m_buttonsLayout->isEmpty()) {
         emit emptyChanged();
     }
 }
@@ -249,12 +251,7 @@ void IdealButtonBarWidget::addButtonToOrder(const \
IdealToolButton* button)  {
     QString buttonId = id(button);
     if (!m_buttonsOrder.contains(buttonId)) {
-        if (m_area == Qt::BottomDockWidgetArea) {
-            m_buttonsOrder.push_front(buttonId);
-        }
-        else {
-            m_buttonsOrder.push_back(buttonId);
-        }
+        m_buttonsOrder.push_back(buttonId);
     }
 }
 
@@ -281,16 +278,16 @@ void IdealButtonBarWidget::applyOrderToLayout()
     // If widget already have some buttons in the layout then calling \
                loadOrderSettings() may leads
     // to situations when loaded order does not contains all existing buttons. \
Therefore we should  // fix this with using addToOrder() method.
-    for (int i = 0; i < layout()->count(); ++i) {
-        if (auto button = \
dynamic_cast<IdealToolButton*>(layout()->itemAt(i)->widget())) { +    for (int i = 0; \
i < m_buttonsLayout->count(); ++i) { +        if (auto button = \
dynamic_cast<IdealToolButton*>(m_buttonsLayout->itemAt(i)->widget())) {  \
                addButtonToOrder(button);
-            layout()->removeWidget(button);
+            m_buttonsLayout->removeWidget(button);
         }
     }
 
     foreach(const QString& id, m_buttonsOrder) {
         if (auto b = button(id)) {
-            layout()->addWidget(b);
+            m_buttonsLayout->addWidget(b);
         }
     }
 }
@@ -298,8 +295,8 @@ void IdealButtonBarWidget::applyOrderToLayout()
 void IdealButtonBarWidget::takeOrderFromLayout()
 {
     m_buttonsOrder.clear();
-    for (int i = 0; i < layout()->count(); ++i) {
-        if (auto button = \
dynamic_cast<IdealToolButton*>(layout()->itemAt(i)->widget())) { +    for (int i = 0; \
i < m_buttonsLayout->count(); ++i) { +        if (auto button = \
dynamic_cast<IdealToolButton*>(m_buttonsLayout->itemAt(i)->widget())) {  \
m_buttonsOrder += id(button);  }
     }
diff --git a/kdevplatform/sublime/idealbuttonbarwidget.h \
b/kdevplatform/sublime/idealbuttonbarwidget.h index db0f927191..011466557f 100644
--- a/kdevplatform/sublime/idealbuttonbarwidget.h
+++ b/kdevplatform/sublime/idealbuttonbarwidget.h
@@ -37,6 +37,7 @@ namespace Sublime
 class MainWindow;
 class IdealController;
 class IdealDockWidget;
+class IdealButtonBarLayout;
 class View;
 class Area;
 
@@ -93,6 +94,7 @@ private:
     QWidget* m_corner;
     bool m_showState;
     QStringList m_buttonsOrder;
+    IdealButtonBarLayout* m_buttonsLayout;
 };
 
 }
diff --git a/kdevplatform/sublime/ideallayout.cpp \
b/kdevplatform/sublime/ideallayout.cpp index 6c6efa57dc..8bc4347919 100644
--- a/kdevplatform/sublime/ideallayout.cpp
+++ b/kdevplatform/sublime/ideallayout.cpp
@@ -25,6 +25,8 @@
 #include <QStyle>
 #include <QWidget>
 
+#include <numeric>
+
 using namespace Sublime;
 
 IdealButtonBarLayout::IdealButtonBarLayout(Qt::Orientation orientation, QWidget \
*parent) @@ -196,23 +198,47 @@ int IdealButtonBarLayout::doVerticalLayout(const QRect \
&rect, bool updateGeometr  int y = rect.y() + t;
     int currentLineWidth = 0;
 
-    for (QLayoutItem *item : _items) {
-        const QSize itemSizeHint = item->sizeHint();
-        if (y + itemSizeHint.height() + b > rect.height()) {
-            int newX = x + currentLineWidth + buttonSpacing;
-            if (newX + itemSizeHint.width() + r <= rect.width())
-            {
-                x += currentLineWidth + buttonSpacing;
-                y = rect.y() + t;
+    if (_items.empty()) {
+        return x + currentLineWidth + r;
+    }
+
+    const bool shrink = rect.height() < sizeHint().height();
+
+    const int maximumHeight = rect.height() / _items.size();
+    int shrinkedHeight = -1;
+
+    if (shrink) {
+        int smallItemCount = 0;
+        const int surplus = std::accumulate(_items.begin(), _items.end(), 0, \
[maximumHeight, &smallItemCount](int acc, QLayoutItem* item) { +            const int \
itemHeight = item->sizeHint().height(); +            if (itemHeight <= maximumHeight) \
{ +                acc += maximumHeight - itemHeight;
+                ++smallItemCount;
             }
+            return acc;
+        });
+
+        Q_ASSERT(_items.size() != smallItemCount); // should be true since \
rect.width != sizeHint.width +        // evenly distribute surplus height over large \
items +        shrinkedHeight = maximumHeight + surplus / (_items.size() - \
smallItemCount); +    }
+
+    for (QLayoutItem* item : _items) {
+        const QSize itemSizeHint = item->sizeHint();
+        const int itemWidth  = itemSizeHint.width();
+        int itemHeight = itemSizeHint.height();
+
+        if (shrink && itemSizeHint.height() > maximumHeight) {
+            itemHeight = shrinkedHeight;
         }
 
-        if (updateGeometry)
-            item->setGeometry(QRect(x, y, itemSizeHint.width(), \
itemSizeHint.height())); +        if (updateGeometry) {
+            item->setGeometry(QRect(x, y, itemWidth, itemHeight));
+        }
 
-        currentLineWidth = qMax(currentLineWidth, itemSizeHint.width());
+        currentLineWidth = qMax(currentLineWidth, itemWidth);
 
-        y += itemSizeHint.height() + buttonSpacing;
+        y += itemHeight + buttonSpacing;
     }
 
     m_layoutDirty = updateGeometry;
@@ -230,26 +256,47 @@ int IdealButtonBarLayout::doHorizontalLayout(const QRect &rect, \
bool updateGeome  int y = rect.y() + t;
     int currentLineHeight = 0;
 
-    for (QLayoutItem *item : _items) {
-        QSize itemSizeHint = item->sizeHint();
-        if (x + itemSizeHint.width() + r > rect.width()) {
-            // Run out of horizontal space. Try to move button to another
-            // row.
-            int newY = y + currentLineHeight + buttonSpacing;
-            if (newY + itemSizeHint.height() + b <= rect.height())
-            {
-                y = newY;
-                x = rect.x() + l;
-                currentLineHeight = 0;
+    if (_items.empty()) {
+        return y + currentLineHeight + b;
+    }
+
+    const bool shrink = rect.width() < sizeHint().width();
+
+    const int maximumWidth = rect.width() / _items.size();
+    int shrinkedWidth = -1;
+
+    if (shrink) {
+        int smallItemCount = 0;
+        const int surplus = std::accumulate(_items.begin(), _items.end(), 0, \
[maximumWidth, &smallItemCount](int acc, QLayoutItem* item) { +            const int \
itemWidth = item->sizeHint().width(); +            if (itemWidth <= maximumWidth) {
+                acc += maximumWidth - itemWidth;
+                ++smallItemCount;
             }
+            return acc;
+        });
+
+        Q_ASSERT(_items.size() != smallItemCount); // should be true since \
rect.width != sizeHint.width +        // evenly distribute surplus width on the large \
items +        shrinkedWidth = maximumWidth + surplus / (_items.size() - \
smallItemCount); +    }
+
+    for (QLayoutItem* item : _items) {
+        const QSize itemSizeHint = item->sizeHint();
+        int itemWidth  = itemSizeHint.width();
+        const int itemHeight = itemSizeHint.height();
+
+        if (shrink && itemSizeHint.width() > maximumWidth) {
+            itemWidth = shrinkedWidth;
         }
 
-        if (updateGeometry)
-            item->setGeometry(QRect(x, y, itemSizeHint.width(), \
itemSizeHint.height())); +        if (updateGeometry) {
+            item->setGeometry(QRect(x, y, itemWidth, itemHeight));
+        }
 
-        currentLineHeight = qMax(currentLineHeight, itemSizeHint.height());
+        currentLineHeight = qMax(currentLineHeight, itemHeight);
 
-        x += itemSizeHint.width() + buttonSpacing;
+        x += itemWidth + buttonSpacing;
     }
 
     m_layoutDirty = updateGeometry;
diff --git a/kdevplatform/sublime/idealtoolbutton.cpp \
b/kdevplatform/sublime/idealtoolbutton.cpp index 42daad8665..01dbfefe24 100644
--- a/kdevplatform/sublime/idealtoolbutton.cpp
+++ b/kdevplatform/sublime/idealtoolbutton.cpp
@@ -88,14 +88,31 @@ QSize IdealToolButton::sizeHint() const
 
 void IdealToolButton::paintEvent(QPaintEvent *event)
 {
+    Q_UNUSED(event);
+
+    QStylePainter painter(this);
+    QStyleOptionToolButton option;
+    initStyleOption(&option);
+
     if (_area == Qt::TopDockWidgetArea || _area == Qt::BottomDockWidgetArea) {
-        QToolButton::paintEvent(event);
+        // elide text
+        int iconWidth = 0;
+        if (toolButtonStyle() != Qt::ToolButtonTextOnly && !option.icon.isNull()) {
+            iconWidth = option.iconSize.width();
+        }
+
+        // subtract 4 to be consistent with the size calculated by sizeHint, which \
adds 4, +        // again to be consistent with QToolButton
+        option.text = fontMetrics().elidedText(text(), Qt::ElideRight, \
contentsRect().width() - iconWidth - 4); +        \
painter.drawComplexControl(QStyle::CC_ToolButton, option);  } else {
         // rotated paint
-        QStylePainter painter(this);
-        QStyleOptionToolButton option;
-        initStyleOption(&option);
-
+        // elide text
+        int iconHeight = 0;
+        if (toolButtonStyle() != Qt::ToolButtonTextOnly && !option.icon.isNull()) {
+            iconHeight = option.iconSize.height();
+        }
+        QString textToDraw = fontMetrics().elidedText(text(), Qt::ElideRight, \
contentsRect().height() - iconHeight - 4);  // first draw normal frame and not \
text/icon  option.text = QString();
         option.icon = QIcon();
@@ -116,7 +133,8 @@ void IdealToolButton::paintEvent(QPaintEvent *event)
         }
 
         // paint text and icon
-        option.text = text();
+        option.text = textToDraw;
+
         QIcon::Mode iconMode = (option.state & QStyle::State_MouseOver) ? \
QIcon::Active : QIcon::Normal;  QPixmap ic = icon().pixmap(option.iconSize, iconMode, \
QIcon::On);  QTransform tf;


[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic