diff --git a/qrenderdoc/Styles/RDStyle/RDStyle.cpp b/qrenderdoc/Styles/RDStyle/RDStyle.cpp index 150393a06..40ed9ac75 100644 --- a/qrenderdoc/Styles/RDStyle/RDStyle.cpp +++ b/qrenderdoc/Styles/RDStyle/RDStyle.cpp @@ -622,6 +622,7 @@ QSize RDStyle::sizeFromContents(ContentsType type, const QStyleOption *opt, cons if(type == CT_PushButton || type == CT_ToolButton) { const QStyleOptionButton *button = qstyleoption_cast(opt); + const QStyleOptionToolButton *toolbutton = qstyleoption_cast(opt); QSize ret = size; @@ -631,6 +632,10 @@ QSize RDStyle::sizeFromContents(ContentsType type, const QStyleOption *opt, cons ret.setWidth(qMax(50, ret.width())); ret.setHeight(qMax(15, ret.height())); } + else if(type == CT_ToolButton && toolbutton) + { + ret = adjustToolButtonSize(toolbutton, size, widget); + } // add margin and border ret.setHeight(ret.height() + Constants::ButtonMargin + Constants::ButtonBorder * 2); @@ -897,17 +902,16 @@ void RDStyle::drawComplexControl(ComplexControl control, const QStyleOptionCompl const QStyleOptionToolButton *toolbutton = qstyleoption_cast(opt); QStyleOptionToolButton labelTextIcon = *toolbutton; - labelTextIcon.rect = proxy()->subControlRect(control, opt, SC_ToolButton, widget); + labelTextIcon.rect = subControlRect(control, opt, SC_ToolButton, widget); // draw the label text/icon proxy()->drawControl(CE_ToolButtonLabel, &labelTextIcon, p, widget); // draw the menu arrow, if there is one - if((toolbutton->subControls & SC_ToolButtonMenu) || - (toolbutton->features & QStyleOptionToolButton::HasMenu)) + if(shouldDrawToolButtonMenuArrow(toolbutton)) { QStyleOptionToolButton menu = *toolbutton; - menu.rect = proxy()->subControlRect(control, opt, SC_ToolButtonMenu, widget); + menu.rect = subControlRect(control, opt, SC_ToolButtonMenu, widget); proxy()->drawPrimitive(PE_IndicatorArrowDown, &menu, p, widget); } diff --git a/qrenderdoc/Styles/RDTweakedNativeStyle/RDTweakedNativeStyle.cpp b/qrenderdoc/Styles/RDTweakedNativeStyle/RDTweakedNativeStyle.cpp index 7beb815c7..da254ba6b 100644 --- a/qrenderdoc/Styles/RDTweakedNativeStyle/RDTweakedNativeStyle.cpp +++ b/qrenderdoc/Styles/RDTweakedNativeStyle/RDTweakedNativeStyle.cpp @@ -63,8 +63,7 @@ QRect RDTweakedNativeStyle::subControlRect(ComplexControl cc, const QStyleOption const QStyleOptionToolButton *toolbutton = qstyleoption_cast(opt); // return the normal rect if there's no menu - if(!(toolbutton->subControls & SC_ToolButtonMenu) && - !(toolbutton->features & QStyleOptionToolButton::MenuButtonPopup)) + if(!shouldDrawToolButtonMenuArrow(toolbutton)) { return ret; } @@ -107,12 +106,11 @@ QSize RDTweakedNativeStyle::sizeFromContents(ContentsType type, const QStyleOpti { QSize sz = size; - // Toolbuttons are always at least icon sized, for consistency. if(type == QStyle::CT_ToolButton) { const QStyleOptionToolButton *toolbutton = qstyleoption_cast(opt); if(toolbutton) - sz = sz.expandedTo(toolbutton->iconSize); + sz = adjustToolButtonSize(toolbutton, sz, widget); } // menu bar items can be sized for both the icon *and* the text @@ -185,13 +183,24 @@ void RDTweakedNativeStyle::drawComplexControl(ComplexControl control, const QSty backCol.setAlphaF(0.2); QStyleOptionToolButton menu; + bool hasMenu = false; + bool hasSeparateMenu = false; // draw the menu arrow, if there is one - if((toolbutton->subControls & SC_ToolButtonMenu) || - (toolbutton->features & QStyleOptionToolButton::MenuButtonPopup)) + if(shouldDrawToolButtonMenuArrow(toolbutton)) { menu = *toolbutton; menu.rect = subControlRect(control, opt, SC_ToolButtonMenu, widget); + hasMenu = true; + // We always draw an arrow if a menu is present (normally Qt only does it for MenuButtonPopup, + // where there is both a button with a default action and a menu triggered by a small arrow, + // and not InstantPopup where there is only a button). If the button uses MenuButtonPopup, + // we want to draw a line to distinguish the menu part of the button and the main part, + // but we don't need that line if the arrow is decorative only. + if(toolbutton->features & QStyleOptionToolButton::MenuButtonPopup) + { + hasSeparateMenu = true; + } } QStyle::State masked = opt->state & (State_On | State_MouseOver); @@ -204,7 +213,7 @@ void RDTweakedNativeStyle::drawComplexControl(ComplexControl control, const QSty QRect rect = opt->rect.adjusted(0, 0, -1, -1); p->setPen(opt->palette.color(QPalette::Shadow)); p->drawRect(rect); - if(menu.rect.isValid()) + if(hasSeparateMenu) p->drawLine(menu.rect.topLeft(), menu.rect.bottomLeft()); // when the mouse is over, make it a little stronger @@ -222,7 +231,7 @@ void RDTweakedNativeStyle::drawComplexControl(ComplexControl control, const QSty // draw the label text/icon drawControl(CE_ToolButtonLabel, &labelTextIcon, p, widget); - if(menu.rect.isValid()) + if(hasMenu) { menu.rect.adjust(2, 0, 0, 0); drawPrimitive(PE_IndicatorArrowDown, &menu, p, widget); @@ -585,3 +594,34 @@ void RDTweakedNativeStyle::drawControl(ControlElement control, const QStyleOptio QProxyStyle::drawControl(control, opt, p, widget); } + +bool RDTweakedNativeStyle::shouldDrawToolButtonMenuArrow(const QStyleOptionToolButton *toolbutton) const +{ + // Qt normally only draws the arrow for MenuButtonPopup; we want it for all tools button with + // menus (including InstantPopup). + return (toolbutton->subControls & SC_ToolButtonMenu) || + (toolbutton->features & QStyleOptionToolButton::HasMenu); +} + +QSize RDTweakedNativeStyle::adjustToolButtonSize(const QStyleOptionToolButton *toolbutton, + const QSize &size, const QWidget *widget) const +{ + QSize sz = size; + + // Toolbuttons are always at least icon sized, for consistency. + sz = sz.expandedTo(toolbutton->iconSize); + + if(shouldDrawToolButtonMenuArrow(toolbutton)) + { + // QToolButton::sizeHint automatically increases the width for MenuButtonPopup separate from + // calling sizeFromContents. But we want to draw the arrow for all tool buttons with menus, + // not just those using MenuButtonPopup. Check for MenuButtonPopup to avoid increasing the + // size twice. + if(!(toolbutton->features & QStyleOptionToolButton::MenuButtonPopup)) + { + sz.setWidth(sz.width() + proxy()->pixelMetric(PM_MenuButtonIndicator, toolbutton, widget)); + } + } + + return sz; +} diff --git a/qrenderdoc/Styles/RDTweakedNativeStyle/RDTweakedNativeStyle.h b/qrenderdoc/Styles/RDTweakedNativeStyle/RDTweakedNativeStyle.h index 2ed8d25b3..9a8db37ee 100644 --- a/qrenderdoc/Styles/RDTweakedNativeStyle/RDTweakedNativeStyle.h +++ b/qrenderdoc/Styles/RDTweakedNativeStyle/RDTweakedNativeStyle.h @@ -27,6 +27,8 @@ #include #include +class QStyleOptionToolButton; + class RDTweakedNativeStyle : public QProxyStyle { private: @@ -56,4 +58,7 @@ public: const QWidget *widget = NULL) const override; protected: + bool shouldDrawToolButtonMenuArrow(const QStyleOptionToolButton *toolbutton) const; + QSize adjustToolButtonSize(const QStyleOptionToolButton *toolbutton, const QSize &size, + const QWidget *widget) const; };