11#include " coloredtoolbutton.h"
22
33#include < QApplication>
4+ #include < QBrush>
5+ #include < QLinearGradient>
6+ #include < QPainter>
7+ #include < QPalette>
48#include < QStyle>
9+ #include < QStyleOptionFocusRect>
10+ #include < QStyleOptionToolButton>
11+ #include < QStylePainter>
512
613// /
714// / \brief ColoredToolButton::ColoredToolButton
1017ColoredToolButton::ColoredToolButton (QWidget* parent)
1118 : QToolButton(parent)
1219{
13- clearColors ();
1420}
1521
1622// /
@@ -19,15 +25,40 @@ ColoredToolButton::ColoredToolButton(QWidget* parent)
1925// /
2026void ColoredToolButton::setColors (const Colors& colors)
2127{
22- setStyleSheet (coloredStyleSheet (colors));
28+ _colors = colors;
29+ _hasColors = true ;
30+ update ();
2331}
2432
2533// /
2634// / \brief ColoredToolButton::clearColors
2735// /
2836void ColoredToolButton::clearColors ()
2937{
30- setStyleSheet (defaultStyleSheet ());
38+ _hasColors = false ;
39+ update ();
40+ }
41+
42+ // /
43+ // / \brief ColoredToolButton::paintEvent
44+ // / \param event
45+ // /
46+ void ColoredToolButton::paintEvent (QPaintEvent* event)
47+ {
48+ Q_UNUSED (event)
49+
50+ QStyleOptionToolButton option;
51+ initStyleOption (&option);
52+
53+ if (!_hasColors) {
54+ QStylePainter painter (this );
55+ painter.drawComplexControl (QStyle::CC_ToolButton, option);
56+ return ;
57+ }
58+
59+ QStylePainter painter (this );
60+ option.palette = coloredPalette (option);
61+ drawColoredToolButton (&painter, option);
3162}
3263
3364// /
@@ -42,64 +73,162 @@ bool ColoredToolButton::isFusionStyle()
4273}
4374
4475// /
45- // / \brief ColoredToolButton::background
46- // / \param top
47- // / \param bottom
76+ // / \brief ColoredToolButton::buttonColor
77+ // / \param option
4878// / \return
4979// /
50- QString ColoredToolButton::background (const QString& top, const QString& bottom)
80+ QColor ColoredToolButton::buttonColor (const QStyleOptionToolButton& option) const
5181{
52- return QString (" qlineargradient(x1:0, y1:0, x2:0, y2:1, stop:0 %1, stop:1 %2)" )
53- .arg (top, bottom);
82+ if (option.state & (QStyle::State_Sunken | QStyle::State_On))
83+ return QColor (_colors.pressed );
84+
85+ if (option.state & QStyle::State_MouseOver)
86+ return QColor (_colors.hover );
87+
88+ return QColor (_colors.base );
5489}
5590
5691// /
57- // / \brief ColoredToolButton::defaultStyleSheet
92+ // / \brief ColoredToolButton::buttonBrush
93+ // / \param option
5894// / \return
5995// /
60- QString ColoredToolButton::defaultStyleSheet ()
96+ QBrush ColoredToolButton::buttonBrush ( const QStyleOptionToolButton& option) const
6197{
62- return " padding: 0px 12px;" ;
98+ QColor top;
99+ QColor bottom;
100+
101+ if (option.state & (QStyle::State_Sunken | QStyle::State_On)) {
102+ top = QColor (_colors.pressed );
103+ bottom = QColor (_colors.border );
104+ }
105+ else if (option.state & QStyle::State_MouseOver) {
106+ top = QColor (_colors.hover );
107+ bottom = QColor (_colors.pressed );
108+ }
109+ else {
110+ top = QColor (_colors.base );
111+ bottom = QColor (_colors.hover );
112+ }
113+
114+ if (!isFusionStyle ())
115+ return top;
116+
117+ QLinearGradient gradient (option.rect .topLeft (), option.rect .bottomLeft ());
118+ gradient.setColorAt (0.0 , top);
119+ gradient.setColorAt (1.0 , bottom);
120+ return gradient;
63121}
64122
65123// /
66- // / \brief ColoredToolButton::coloredStyleSheet
67- // / \param colors
124+ // / \brief ColoredToolButton::coloredPalette
125+ // / \param option
68126// / \return
69127// /
70- QString ColoredToolButton::coloredStyleSheet (const Colors& colors)
128+ QPalette ColoredToolButton::coloredPalette (const QStyleOptionToolButton& option) const
71129{
72- const QString normalBackground = isFusionStyle ()
73- ? background (colors.base , colors.hover )
74- : colors.base ;
75- const QString hoverBackground = isFusionStyle ()
76- ? background (colors.hover , colors.pressed )
77- : colors.hover ;
78- const QString pressedBackground = isFusionStyle ()
79- ? background (colors.pressed , colors.border )
80- : colors.pressed ;
81-
82- return QString (R"(
83- ColoredToolButton {
84- color: white;
85- padding: 0px 12px 0px 2px;
86- background-color: %1;
87- border: 1px solid %2;
88- border-radius: 4px;
89- }
90- ColoredToolButton:hover {
91- background-color: %3;
92- }
93- ColoredToolButton:pressed {
94- background-color: %4;
95- }
96- ColoredToolButton::menu-button {
97- width: 12px;
98- border-left: 1px solid %2;
99- }
100- ColoredToolButton::menu-arrow {
101- width: 10px;
102- height: 10px;
103- }
104- )" ).arg (normalBackground, colors.border , hoverBackground, pressedBackground);
130+ const QColor button = buttonColor (option);
131+ const QColor border (_colors.border );
132+ const QColor text (Qt::white);
133+
134+ QPalette palette = option.palette ;
135+
136+ for (const QPalette::ColorGroup group : { QPalette::Active, QPalette::Inactive, QPalette::Disabled }) {
137+ palette.setColor (group, QPalette::Button, button);
138+ palette.setColor (group, QPalette::ButtonText, text);
139+ palette.setColor (group, QPalette::WindowText, text);
140+ palette.setColor (group, QPalette::Light, QColor (_colors.hover ).lighter (115 ));
141+ palette.setColor (group, QPalette::Midlight, QColor (_colors.hover ));
142+ palette.setColor (group, QPalette::Mid, border);
143+ palette.setColor (group, QPalette::Dark, border);
144+ palette.setColor (group, QPalette::Shadow, border.darker (125 ));
145+ }
146+
147+ return palette;
148+ }
149+
150+ // /
151+ // / \brief ColoredToolButton::drawColoredToolButton
152+ // / \param painter
153+ // / \param option
154+ // /
155+ void ColoredToolButton::drawColoredToolButton (QPainter* painter, const QStyleOptionToolButton& option) const
156+ {
157+ const QRect buttonRect = style ()->subControlRect (QStyle::CC_ToolButton, &option, QStyle::SC_ToolButton, this );
158+ const QRect menuRect = style ()->subControlRect (QStyle::CC_ToolButton, &option, QStyle::SC_ToolButtonMenu, this );
159+ const QColor border (_colors.border );
160+
161+ QStyle::State buttonState = option.state & ~QStyle::State_Sunken;
162+ QStyle::State menuState = buttonState;
163+ const bool autoRaise = option.state & QStyle::State_AutoRaise;
164+
165+ if (autoRaise && (!(buttonState & QStyle::State_MouseOver) || !(buttonState & QStyle::State_Enabled)))
166+ buttonState &= ~QStyle::State_Raised;
167+
168+ if (option.state & QStyle::State_Sunken) {
169+ if (option.activeSubControls & QStyle::SC_ToolButton) {
170+ buttonState |= QStyle::State_Sunken;
171+ menuState |= QStyle::State_MouseOver | QStyle::State_Sunken;
172+ }
173+ else if (option.activeSubControls & QStyle::SC_ToolButtonMenu) {
174+ menuState |= QStyle::State_Sunken;
175+ buttonState |= QStyle::State_MouseOver;
176+ }
177+ }
178+
179+ painter->save ();
180+ painter->setRenderHint (QPainter::Antialiasing, true );
181+ painter->setPen (border);
182+ painter->setBrush (buttonBrush (option));
183+ painter->drawRoundedRect (option.rect .adjusted (0 , 0 , -1 , -1 ), 4.0 , 4.0 );
184+ painter->restore ();
185+
186+ if (option.state & QStyle::State_HasFocus) {
187+ QStyleOptionFocusRect focus;
188+ focus.QStyleOption ::operator =(option);
189+ focus.rect .adjust (3 , 3 , -3 , -3 );
190+ if (option.features & QStyleOptionToolButton::MenuButtonPopup)
191+ focus.rect .adjust (0 , 0 , -style ()->pixelMetric (QStyle::PM_MenuButtonIndicator, &option, this ), 0 );
192+ style ()->drawPrimitive (QStyle::PE_FrameFocusRect, &focus, painter, this );
193+ }
194+
195+ QStyleOptionToolButton label = option;
196+ label.state = buttonState;
197+ if (!autoRaise)
198+ label.state &= ~QStyle::State_Sunken;
199+ label.rect = buttonRect;
200+ if (option.subControls & QStyle::SC_ToolButtonMenu) {
201+ if (isRightToLeft ())
202+ label.rect .setLeft (menuRect.right () + 1 );
203+ else
204+ label.rect .setRight (menuRect.left () - 1 );
205+ }
206+ label.rect .adjust (2 , 2 , -2 , -2 );
207+ style ()->drawControl (QStyle::CE_ToolButtonLabel, &label, painter, this );
208+
209+ if (option.subControls & QStyle::SC_ToolButtonMenu) {
210+ QStyleOptionToolButton tool = option;
211+ tool.state = menuState;
212+
213+ painter->save ();
214+ painter->setPen (option.palette .dark ().color ());
215+ painter->drawLine (menuRect.left (), menuRect.top () + 3 ,
216+ menuRect.left (), menuRect.bottom () - 3 );
217+ painter->setPen (option.palette .light ().color ());
218+ painter->drawLine (menuRect.left () - 1 , menuRect.top () + 3 ,
219+ menuRect.left () - 1 , menuRect.bottom () - 3 );
220+
221+ tool.rect = menuRect.adjusted (2 , 3 , -2 , -1 );
222+ style ()->drawPrimitive (QStyle::PE_IndicatorArrowDown, &tool, painter, this );
223+ painter->restore ();
224+ }
225+ else if (option.features & QStyleOptionToolButton::HasMenu) {
226+ const int indicator = style ()->pixelMetric (QStyle::PM_MenuButtonIndicator, &option, this );
227+ QStyleOptionToolButton arrow = option;
228+ arrow.rect = QRect (option.rect .right () + 4 - indicator,
229+ option.rect .height () - indicator + 4 ,
230+ indicator - 5 ,
231+ indicator - 5 );
232+ style ()->drawPrimitive (QStyle::PE_IndicatorArrowDown, &arrow, painter, this );
233+ }
105234}
0 commit comments