From kde-commits Sat Sep 15 10:55:07 2018 From: Amish Naidu Date: Sat, 15 Sep 2018 10:55:07 +0000 To: kde-commits Subject: [kdevelop/5.3] kdevplatform/sublime: Sublime: Fix window growing larger by making tool view buttons Message-Id: X-MARC-Message: https://marc.info/?l=kde-commits&m=153700891806890 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 Co= de. IdealToolButtons: Instead of simply truncating text, they will elide text w= hile painting. IdealButtonBarWidget: Previously the layout attached to the object was bein= g 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, introduc= ed 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/s= ublime/idealbuttonbarwidget.cpp index 918d1a36a3..d76597411e 100644 --- a/kdevplatform/sublime/idealbuttonbarwidget.cpp +++ b/kdevplatform/sublime/idealbuttonbarwidget.cpp @@ -105,27 +105,29 @@ IdealButtonBarWidget::IdealButtonBarWidget(Qt::DockWi= dgetArea 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 =3D=3D Qt::BottomDockWidgetArea) { - QBoxLayout *statusLayout =3D new QBoxLayout(QBoxLayout::RightToLef= t, this); + QBoxLayout *statusLayout =3D new QBoxLayout(QBoxLayout::LeftToRigh= t, this); statusLayout->setMargin(0); = - IdealButtonBarLayout *l =3D new IdealButtonBarLayout(orientation()= ); - statusLayout->addLayout(l); + m_buttonsLayout =3D new IdealButtonBarLayout(orientation()); + statusLayout->addLayout(m_buttonsLayout); + + statusLayout->addStretch(1); = m_corner =3D new QWidget(this); QBoxLayout *cornerLayout =3D new QBoxLayout(QBoxLayout::LeftToRigh= t, m_corner); cornerLayout->setMargin(0); cornerLayout->setSpacing(0); statusLayout->addWidget(m_corner); - statusLayout->addStretch(1); } else - (void) new IdealButtonBarLayout(orientation(), this); + m_buttonsLayout =3D new IdealButtonBarLayout(orientation(), this); } = QAction* IdealButtonBarWidget::addWidget(IdealDockWidget *dock, @@ -194,7 +196,7 @@ void IdealButtonBarWidget::removeAction(QAction* widget= Action) action->button()->deleteLater(); delete action; = - if (layout()->isEmpty()) { + if (m_buttonsLayout->isEmpty()) { emit emptyChanged(); } } @@ -249,12 +251,7 @@ void IdealButtonBarWidget::addButtonToOrder(const Idea= lToolButton* button) { QString buttonId =3D id(button); if (!m_buttonsOrder.contains(buttonId)) { - if (m_area =3D=3D 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 load= OrderSettings() may leads // to situations when loaded order does not contains all existing butt= ons. Therefore we should // fix this with using addToOrder() method. - for (int i =3D 0; i < layout()->count(); ++i) { - if (auto button =3D dynamic_cast(layout()->itemA= t(i)->widget())) { + for (int i =3D 0; i < m_buttonsLayout->count(); ++i) { + if (auto button =3D dynamic_cast(m_buttonsLayout= ->itemAt(i)->widget())) { addButtonToOrder(button); - layout()->removeWidget(button); + m_buttonsLayout->removeWidget(button); } } = foreach(const QString& id, m_buttonsOrder) { if (auto b =3D 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 =3D 0; i < layout()->count(); ++i) { - if (auto button =3D dynamic_cast(layout()->itemA= t(i)->widget())) { + for (int i =3D 0; i < m_buttonsLayout->count(); ++i) { + if (auto button =3D dynamic_cast(m_buttonsLayout= ->itemAt(i)->widget())) { m_buttonsOrder +=3D id(button); } } diff --git a/kdevplatform/sublime/idealbuttonbarwidget.h b/kdevplatform/sub= lime/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/id= eallayout.cpp index 6c6efa57dc..8bc4347919 100644 --- a/kdevplatform/sublime/ideallayout.cpp +++ b/kdevplatform/sublime/ideallayout.cpp @@ -25,6 +25,8 @@ #include #include = +#include + using namespace Sublime; = IdealButtonBarLayout::IdealButtonBarLayout(Qt::Orientation orientation, QW= idget *parent) @@ -196,23 +198,47 @@ int IdealButtonBarLayout::doVerticalLayout(const QRec= t &rect, bool updateGeometr int y =3D rect.y() + t; int currentLineWidth =3D 0; = - for (QLayoutItem *item : _items) { - const QSize itemSizeHint =3D item->sizeHint(); - if (y + itemSizeHint.height() + b > rect.height()) { - int newX =3D x + currentLineWidth + buttonSpacing; - if (newX + itemSizeHint.width() + r <=3D rect.width()) - { - x +=3D currentLineWidth + buttonSpacing; - y =3D rect.y() + t; + if (_items.empty()) { + return x + currentLineWidth + r; + } + + const bool shrink =3D rect.height() < sizeHint().height(); + + const int maximumHeight =3D rect.height() / _items.size(); + int shrinkedHeight =3D -1; + + if (shrink) { + int smallItemCount =3D 0; + const int surplus =3D std::accumulate(_items.begin(), _items.end()= , 0, [maximumHeight, &smallItemCount](int acc, QLayoutItem* item) { + const int itemHeight =3D item->sizeHint().height(); + if (itemHeight <=3D maximumHeight) { + acc +=3D maximumHeight - itemHeight; + ++smallItemCount; } + return acc; + }); + + Q_ASSERT(_items.size() !=3D smallItemCount); // should be true sin= ce rect.width !=3D sizeHint.width + // evenly distribute surplus height over large items + shrinkedHeight =3D maximumHeight + surplus / (_items.size() - smal= lItemCount); + } + + for (QLayoutItem* item : _items) { + const QSize itemSizeHint =3D item->sizeHint(); + const int itemWidth =3D itemSizeHint.width(); + int itemHeight =3D itemSizeHint.height(); + + if (shrink && itemSizeHint.height() > maximumHeight) { + itemHeight =3D shrinkedHeight; } = - if (updateGeometry) - item->setGeometry(QRect(x, y, itemSizeHint.width(), itemSizeHi= nt.height())); + if (updateGeometry) { + item->setGeometry(QRect(x, y, itemWidth, itemHeight)); + } = - currentLineWidth =3D qMax(currentLineWidth, itemSizeHint.width()); + currentLineWidth =3D qMax(currentLineWidth, itemWidth); = - y +=3D itemSizeHint.height() + buttonSpacing; + y +=3D itemHeight + buttonSpacing; } = m_layoutDirty =3D updateGeometry; @@ -230,26 +256,47 @@ int IdealButtonBarLayout::doHorizontalLayout(const QR= ect &rect, bool updateGeome int y =3D rect.y() + t; int currentLineHeight =3D 0; = - for (QLayoutItem *item : _items) { - QSize itemSizeHint =3D item->sizeHint(); - if (x + itemSizeHint.width() + r > rect.width()) { - // Run out of horizontal space. Try to move button to another - // row. - int newY =3D y + currentLineHeight + buttonSpacing; - if (newY + itemSizeHint.height() + b <=3D rect.height()) - { - y =3D newY; - x =3D rect.x() + l; - currentLineHeight =3D 0; + if (_items.empty()) { + return y + currentLineHeight + b; + } + + const bool shrink =3D rect.width() < sizeHint().width(); + + const int maximumWidth =3D rect.width() / _items.size(); + int shrinkedWidth =3D -1; + + if (shrink) { + int smallItemCount =3D 0; + const int surplus =3D std::accumulate(_items.begin(), _items.end()= , 0, [maximumWidth, &smallItemCount](int acc, QLayoutItem* item) { + const int itemWidth =3D item->sizeHint().width(); + if (itemWidth <=3D maximumWidth) { + acc +=3D maximumWidth - itemWidth; + ++smallItemCount; } + return acc; + }); + + Q_ASSERT(_items.size() !=3D smallItemCount); // should be true sin= ce rect.width !=3D sizeHint.width + // evenly distribute surplus width on the large items + shrinkedWidth =3D maximumWidth + surplus / (_items.size() - smallI= temCount); + } + + for (QLayoutItem* item : _items) { + const QSize itemSizeHint =3D item->sizeHint(); + int itemWidth =3D itemSizeHint.width(); + const int itemHeight =3D itemSizeHint.height(); + + if (shrink && itemSizeHint.width() > maximumWidth) { + itemWidth =3D shrinkedWidth; } = - if (updateGeometry) - item->setGeometry(QRect(x, y, itemSizeHint.width(), itemSizeHi= nt.height())); + if (updateGeometry) { + item->setGeometry(QRect(x, y, itemWidth, itemHeight)); + } = - currentLineHeight =3D qMax(currentLineHeight, itemSizeHint.height(= )); + currentLineHeight =3D qMax(currentLineHeight, itemHeight); = - x +=3D itemSizeHint.width() + buttonSpacing; + x +=3D itemWidth + buttonSpacing; } = m_layoutDirty =3D updateGeometry; diff --git a/kdevplatform/sublime/idealtoolbutton.cpp b/kdevplatform/sublim= e/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 =3D=3D Qt::TopDockWidgetArea || _area =3D=3D Qt::BottomDockW= idgetArea) { - QToolButton::paintEvent(event); + // elide text + int iconWidth =3D 0; + if (toolButtonStyle() !=3D Qt::ToolButtonTextOnly && !option.icon.= isNull()) { + iconWidth =3D option.iconSize.width(); + } + + // subtract 4 to be consistent with the size calculated by sizeHin= t, which adds 4, + // again to be consistent with QToolButton + option.text =3D fontMetrics().elidedText(text(), Qt::ElideRight, c= ontentsRect().width() - iconWidth - 4); + painter.drawComplexControl(QStyle::CC_ToolButton, option); } else { // rotated paint - QStylePainter painter(this); - QStyleOptionToolButton option; - initStyleOption(&option); - + // elide text + int iconHeight =3D 0; + if (toolButtonStyle() !=3D Qt::ToolButtonTextOnly && !option.icon.= isNull()) { + iconHeight =3D option.iconSize.height(); + } + QString textToDraw =3D fontMetrics().elidedText(text(), Qt::ElideR= ight, contentsRect().height() - iconHeight - 4); // first draw normal frame and not text/icon option.text =3D QString(); option.icon =3D QIcon(); @@ -116,7 +133,8 @@ void IdealToolButton::paintEvent(QPaintEvent *event) } = // paint text and icon - option.text =3D text(); + option.text =3D textToDraw; + QIcon::Mode iconMode =3D (option.state & QStyle::State_MouseOver) = ? QIcon::Active : QIcon::Normal; QPixmap ic =3D icon().pixmap(option.iconSize, iconMode, QIcon::On); QTransform tf;