diff --git a/kdevplatform/sublime/ideallayout.cpp b/kdevplatform/sublime/ideallayout.cpp --- a/kdevplatform/sublime/ideallayout.cpp +++ b/kdevplatform/sublime/ideallayout.cpp @@ -22,6 +22,8 @@ #include "ideallayout.h" +#include + #include #include @@ -72,19 +74,37 @@ QSize IdealButtonBarLayout::minimumSize() const { - // The code below appears to be completely wrong -- - // it will return the maximum size of a single button, not any - // estimate as to how much space is necessary to draw all buttons - // in a minimally acceptable way. if (m_minSizeDirty) { - if (orientation() == Qt::Vertical) { - const int width = doVerticalLayout(QRect(0, 0, 0, _height), false); - return QSize(width, 0); - } + const int buttonSpacing = this->buttonSpacing(); - m_min = QSize(0, 0); + bool first = true; + int orientationSize = 0; + int crossSize = 0; for (QLayoutItem* item : _items) { - m_min = m_min.expandedTo(item->minimumSize()); + const QSize itemMinSize = item->minimumSize(); + + int orientationSizeHere; + int crossSizeHere; + if (orientation() == Qt::Vertical) { + orientationSizeHere = itemMinSize.height(); + crossSizeHere = itemMinSize.width(); + } else { + orientationSizeHere = itemMinSize.width(); + crossSizeHere = itemMinSize.height(); + } + + if (first) { + crossSize = crossSizeHere; + first = false; + } else { + orientationSize += buttonSpacing; + } + orientationSize += orientationSizeHere; + } + if (orientation() == Qt::Vertical) { + m_min = QSize(crossSize, orientationSize); + } else { + m_min = QSize(orientationSize, crossSize); } m_minSizeDirty = false; @@ -202,9 +222,10 @@ return x + currentLineWidth + r; } - const bool shrink = rect.height() < sizeHint().height(); + bool shrink = rect.height() < sizeHint().height(); - const int maximumHeight = rect.height() / _items.size(); + // space left per button after removing available space for buttonSpacing + const int maximumHeight = (rect.height() - buttonSpacing * (_items.size() - 1)) / _items.size(); int shrinkedHeight = -1; if (shrink) { @@ -218,9 +239,14 @@ 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); + // Sanity check to prevent against a divide-by-zero due to some latent miscalculations + if (_items.size() != smallItemCount) { + // evenly distribute surplus height over large items + shrinkedHeight = maximumHeight + surplus / (_items.size() - smallItemCount); + } else { + qCDebug(SUBLIME) << "Expected at least one large item, none found, possible erraneous shrink predicate or sizeHint"; + shrink = false; + } } for (QLayoutItem* item : _items) { @@ -260,9 +286,10 @@ return y + currentLineHeight + b; } - const bool shrink = rect.width() < sizeHint().width(); + bool shrink = rect.width() < sizeHint().width(); - const int maximumWidth = rect.width() / _items.size(); + // space left per button after removing available space for buttonSpacing + const int maximumWidth = (rect.width() - buttonSpacing * (_items.size() - 1)) / _items.size(); int shrinkedWidth = -1; if (shrink) { @@ -276,9 +303,14 @@ 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); + // Sanity check to prevent against a divide-by-zero due to some latent miscalculations + if (_items.size() != smallItemCount) { + // evenly distribute surplus width on the large items + shrinkedWidth = maximumWidth + surplus / (_items.size() - smallItemCount); + } else { + qCDebug(SUBLIME) << "Expected at least one large item, none found, possible erraneous shrink predicate or sizeHint"; + shrink = false; + } } for (QLayoutItem* item : _items) { diff --git a/kdevplatform/sublime/idealtoolbutton.h b/kdevplatform/sublime/idealtoolbutton.h --- a/kdevplatform/sublime/idealtoolbutton.h +++ b/kdevplatform/sublime/idealtoolbutton.h @@ -36,6 +36,8 @@ QSize sizeHint() const override; + QSize minimumSizeHint() const override; + protected: void paintEvent(QPaintEvent *event) override; diff --git a/kdevplatform/sublime/idealtoolbutton.cpp b/kdevplatform/sublime/idealtoolbutton.cpp --- a/kdevplatform/sublime/idealtoolbutton.cpp +++ b/kdevplatform/sublime/idealtoolbutton.cpp @@ -35,6 +35,14 @@ setToolButtonStyle(Qt::ToolButtonTextBesideIcon); setContextMenuPolicy(Qt::CustomContextMenu); + + QSizePolicy sizePolicy = this->sizePolicy(); + if (orientation() == Qt::Horizontal) { + sizePolicy.setHorizontalPolicy(QSizePolicy::Preferred); + } else { + sizePolicy.setVerticalPolicy(QSizePolicy::Preferred); + } + setSizePolicy(sizePolicy); } Qt::Orientation IdealToolButton::orientation() const @@ -86,6 +94,37 @@ } } +QSize IdealToolButton::minimumSizeHint() const +{ + QStyleOptionToolButton opt; + initStyleOption(&opt); + + // if style has icons, minimumSize is the size of the icon + if (toolButtonStyle() != Qt::ToolButtonTextOnly && !opt.icon.isNull()) { + int iconWidth = 0; + int iconHeight = 0; + if (_area == Qt::TopDockWidgetArea || _area == Qt::BottomDockWidgetArea) { + iconWidth = opt.iconSize.width(); + iconHeight = opt.iconSize.height(); + } else { + iconWidth = opt.iconSize.height(); + iconHeight = opt.iconSize.width(); + } + + return {iconWidth + 1, iconHeight + 1}; + } else { + // if no icon, set an arbitrary minimum size + QFontMetrics fm = fontMetrics(); + const QSize minimumSize = fm.size(Qt::TextShowMnemonic, opt.text.left(4)); + if (_area == Qt::TopDockWidgetArea || _area == Qt::BottomDockWidgetArea) { + return minimumSize; + } else { + return {minimumSize.height(), minimumSize.width()}; + } + } +} + + void IdealToolButton::paintEvent(QPaintEvent *event) { Q_UNUSED(event);