Changeset View
Changeset View
Standalone View
Standalone View
kstyle/widgets/toolbutton.cpp
- This file was added.
1 | #include "breezestyle.h" | ||||
---|---|---|---|---|---|
2 | #include <QToolButton> | ||||
3 | | ||||
4 | namespace Breeze | ||||
5 | { | ||||
6 | //____________________________________________________________________ | ||||
7 | QColor Helper::toolButtonColor(const QPalette &palette, bool mouseOver, bool hasFocus, bool sunken, qreal opacity, AnimationMode mode) const | ||||
8 | { | ||||
9 | QColor outline; | ||||
10 | const QColor hoverColor(this->hoverColor(palette)); | ||||
11 | const QColor focusColor(this->focusColor(palette)); | ||||
12 | const QColor sunkenColor = alphaColor(palette.color(QPalette::WindowText), 0.2); | ||||
13 | | ||||
14 | // hover takes precedence over focus | ||||
15 | if (mode == AnimationHover) { | ||||
16 | if (hasFocus) | ||||
17 | outline = KColorUtils::mix(focusColor, hoverColor, opacity); | ||||
18 | else if (sunken) | ||||
19 | outline = sunkenColor; | ||||
20 | else | ||||
21 | outline = alphaColor(hoverColor, opacity); | ||||
22 | | ||||
23 | } else if (mouseOver) { | ||||
24 | outline = hoverColor; | ||||
25 | | ||||
26 | } else if (mode == AnimationFocus) { | ||||
27 | if (sunken) | ||||
28 | outline = KColorUtils::mix(sunkenColor, focusColor, opacity); | ||||
29 | else | ||||
30 | outline = alphaColor(focusColor, opacity); | ||||
31 | | ||||
32 | } else if (hasFocus) { | ||||
33 | outline = focusColor; | ||||
34 | | ||||
35 | } else if (sunken) { | ||||
36 | outline = sunkenColor; | ||||
37 | } | ||||
38 | | ||||
39 | return outline; | ||||
40 | } | ||||
41 | | ||||
42 | //______________________________________________________________________________ | ||||
43 | void Helper::renderToolButtonFrame(QPainter *painter, const QRect &rect, const QColor &color, bool sunken) const | ||||
44 | { | ||||
45 | // do nothing for invalid color | ||||
46 | if (!color.isValid()) | ||||
47 | return; | ||||
48 | | ||||
49 | // setup painter | ||||
50 | painter->setRenderHints(QPainter::Antialiasing); | ||||
51 | | ||||
52 | const QRectF baseRect(rect); | ||||
53 | | ||||
54 | if (sunken) { | ||||
55 | const qreal radius(frameRadius()); | ||||
56 | | ||||
57 | painter->setPen(Qt::NoPen); | ||||
58 | painter->setBrush(color); | ||||
59 | | ||||
60 | const QRectF contentRect(baseRect.adjusted(1, 1, -1, -1)); | ||||
61 | painter->drawRoundedRect(contentRect, radius, radius); | ||||
62 | | ||||
63 | } else { | ||||
64 | const qreal radius(frameRadius(-0.5)); | ||||
65 | | ||||
66 | painter->setPen(color); | ||||
67 | painter->setBrush(Qt::NoBrush); | ||||
68 | const QRectF outlineRect(baseRect.adjusted(1.5, 1.5, -1.5, -1.5)); | ||||
69 | painter->drawRoundedRect(outlineRect, radius, radius); | ||||
70 | } | ||||
71 | } | ||||
72 | | ||||
73 | //___________________________________________________________________________________________________________________ | ||||
74 | QRect Style::toolButtonSubControlRect(const QStyleOptionComplex *option, SubControl subControl, const QWidget *widget) const | ||||
75 | { | ||||
76 | // cast option and check | ||||
77 | const auto toolButtonOption = qstyleoption_cast<const QStyleOptionToolButton *>(option); | ||||
78 | if (!toolButtonOption) | ||||
79 | return ParentStyleClass::subControlRect(CC_ToolButton, option, subControl, widget); | ||||
80 | | ||||
81 | const bool hasPopupMenu(toolButtonOption->features & QStyleOptionToolButton::MenuButtonPopup); | ||||
82 | const bool hasInlineIndicator(toolButtonOption->features & QStyleOptionToolButton::HasMenu && toolButtonOption->features & QStyleOptionToolButton::PopupDelay && !hasPopupMenu); | ||||
83 | | ||||
84 | // store rect | ||||
85 | const auto &rect(option->rect); | ||||
86 | const int menuButtonWidth(Metrics::MenuButton_IndicatorWidth); | ||||
87 | switch (subControl) { | ||||
88 | case SC_ToolButtonMenu: { | ||||
89 | // check features | ||||
90 | if (!(hasPopupMenu || hasInlineIndicator)) | ||||
91 | return QRect(); | ||||
92 | | ||||
93 | // check features | ||||
94 | auto menuRect(rect); | ||||
95 | menuRect.setLeft(rect.right() - menuButtonWidth + 1); | ||||
96 | if (hasInlineIndicator) { | ||||
97 | menuRect.setTop(menuRect.bottom() - menuButtonWidth + 1); | ||||
98 | } | ||||
99 | | ||||
100 | return visualRect(option, menuRect); | ||||
101 | } | ||||
102 | | ||||
103 | case SC_ToolButton: { | ||||
104 | if (hasPopupMenu) { | ||||
105 | auto contentsRect(rect); | ||||
106 | contentsRect.setRight(rect.right() - menuButtonWidth); | ||||
107 | return visualRect(option, contentsRect); | ||||
108 | | ||||
109 | } else | ||||
110 | return rect; | ||||
111 | } | ||||
112 | | ||||
113 | default: | ||||
114 | return QRect(); | ||||
115 | } | ||||
116 | } | ||||
117 | | ||||
118 | //______________________________________________________________ | ||||
119 | QSize Style::toolButtonSizeFromContents(const QStyleOption *option, const QSize &contentsSize, const QWidget *) const | ||||
120 | { | ||||
121 | // cast option and check | ||||
122 | const auto toolButtonOption = qstyleoption_cast<const QStyleOptionToolButton *>(option); | ||||
123 | if (!toolButtonOption) | ||||
124 | return contentsSize; | ||||
125 | | ||||
126 | // copy size | ||||
127 | QSize size = contentsSize; | ||||
128 | | ||||
129 | // get relevant state flags | ||||
130 | const State &state(option->state); | ||||
131 | const bool autoRaise(state & State_AutoRaise); | ||||
132 | const bool hasPopupMenu(toolButtonOption->features & QStyleOptionToolButton::MenuButtonPopup); | ||||
133 | const bool hasInlineIndicator(toolButtonOption->features & QStyleOptionToolButton::HasMenu && toolButtonOption->features & QStyleOptionToolButton::PopupDelay && !hasPopupMenu); | ||||
134 | | ||||
135 | const int marginWidth(autoRaise ? Metrics::ToolButton_MarginWidth : Metrics::Button_MarginWidth + Metrics::Frame_FrameWidth); | ||||
136 | | ||||
137 | if (hasInlineIndicator) | ||||
138 | size.rwidth() += Metrics::ToolButton_InlineIndicatorWidth; | ||||
139 | size = expandSize(size, marginWidth); | ||||
140 | | ||||
141 | return size; | ||||
142 | } | ||||
143 | | ||||
144 | //______________________________________________________________ | ||||
145 | bool Style::drawPanelButtonToolPrimitive(const QStyleOption *option, QPainter *painter, const QWidget *widget) const | ||||
146 | { | ||||
147 | // copy palette and rect | ||||
148 | const auto &palette(option->palette); | ||||
149 | auto rect(option->rect); | ||||
150 | | ||||
151 | // store relevant flags | ||||
152 | const State &state(option->state); | ||||
153 | const bool autoRaise(state & State_AutoRaise); | ||||
154 | const bool enabled(state & State_Enabled); | ||||
155 | const bool sunken(state & (State_On | State_Sunken)); | ||||
156 | const bool mouseOver(enabled && (option->state & State_MouseOver)); | ||||
157 | const bool hasFocus(enabled && (option->state & (State_HasFocus | State_Sunken))); | ||||
158 | | ||||
159 | /* | ||||
160 | * get animation state | ||||
161 | * no need to update, this was already done in drawToolButtonComplexControl | ||||
162 | */ | ||||
163 | const AnimationMode mode(_animations->widgetStateEngine().buttonAnimationMode(widget)); | ||||
164 | const qreal opacity(_animations->widgetStateEngine().buttonOpacity(widget)); | ||||
165 | | ||||
166 | if (!autoRaise) { | ||||
167 | // need to check widget for popup mode, because option is not set properly | ||||
168 | const auto toolButton(qobject_cast<const QToolButton *>(widget)); | ||||
169 | const bool hasPopupMenu(toolButton && toolButton->popupMode() == QToolButton::MenuButtonPopup); | ||||
170 | | ||||
171 | // render as push button | ||||
172 | const auto shadow(_helper->shadowColor(palette)); | ||||
173 | const auto outline(_helper->buttonOutlineColor(palette, mouseOver, hasFocus, opacity, mode)); | ||||
174 | const auto background(_helper->buttonBackgroundColor(palette, mouseOver, hasFocus, sunken, opacity, mode)); | ||||
175 | | ||||
176 | // adjust frame in case of menu | ||||
177 | if (hasPopupMenu) { | ||||
178 | painter->setClipRect(rect); | ||||
179 | rect.adjust(0, 0, Metrics::Frame_FrameRadius + 2, 0); | ||||
180 | rect = visualRect(option, rect); | ||||
181 | } | ||||
182 | | ||||
183 | // render | ||||
184 | _helper->renderButtonFrame(painter, rect, background, outline, shadow, hasFocus, sunken); | ||||
185 | | ||||
186 | } else { | ||||
187 | const auto color(_helper->toolButtonColor(palette, mouseOver, hasFocus, sunken, opacity, mode)); | ||||
188 | _helper->renderToolButtonFrame(painter, rect, color, sunken); | ||||
189 | } | ||||
190 | | ||||
191 | return true; | ||||
192 | } | ||||
193 | | ||||
194 | //___________________________________________________________________________________ | ||||
195 | bool Style::drawIndicatorArrowPrimitive(ArrowOrientation orientation, const QStyleOption *option, QPainter *painter, const QWidget *widget) const | ||||
196 | { | ||||
197 | // store rect and palette | ||||
198 | const auto &rect(option->rect); | ||||
199 | const auto &palette(option->palette); | ||||
200 | | ||||
201 | // store state | ||||
202 | const State &state(option->state); | ||||
203 | const bool enabled(state & State_Enabled); | ||||
204 | bool mouseOver(enabled && (state & State_MouseOver)); | ||||
205 | bool hasFocus(enabled && (state & State_HasFocus)); | ||||
206 | | ||||
207 | // detect special buttons | ||||
208 | const bool inTabBar(widget && qobject_cast<const QTabBar *>(widget->parentWidget())); | ||||
209 | const bool inToolButton(qstyleoption_cast<const QStyleOptionToolButton *>(option)); | ||||
210 | | ||||
211 | // color | ||||
212 | QColor color; | ||||
213 | if (inTabBar) { | ||||
214 | // for tabbar arrows one uses animations to get the arrow color | ||||
215 | /* | ||||
216 | * get animation state | ||||
217 | * there is no need to update the engine since this was already done when rendering the frame | ||||
218 | */ | ||||
219 | const AnimationMode mode(_animations->widgetStateEngine().buttonAnimationMode(widget)); | ||||
220 | const qreal opacity(_animations->widgetStateEngine().buttonOpacity(widget)); | ||||
221 | color = _helper->arrowColor(palette, mouseOver, hasFocus, opacity, mode); | ||||
222 | | ||||
223 | } else if (mouseOver && !inToolButton) { | ||||
224 | color = _helper->hoverColor(palette); | ||||
225 | | ||||
226 | } else if (inToolButton) { | ||||
227 | const bool flat(state & State_AutoRaise); | ||||
228 | | ||||
229 | // cast option | ||||
230 | const QStyleOptionToolButton *toolButtonOption(static_cast<const QStyleOptionToolButton *>(option)); | ||||
231 | const bool hasMenu((toolButtonOption->subControls & SC_ToolButtonMenu) || (toolButtonOption->features & QStyleOptionToolButton::HasMenu && toolButtonOption->features & QStyleOptionToolButton::PopupDelay)); | ||||
232 | const bool sunken(state & (State_On | State_Sunken)); | ||||
233 | if (flat && hasMenu) { | ||||
234 | if (sunken && !mouseOver) | ||||
235 | color = palette.color(QPalette::HighlightedText); | ||||
236 | else { | ||||
237 | // for menu arrows in flat toolbutton one uses animations to get the arrow color | ||||
238 | // handle arrow over animation | ||||
239 | const bool arrowHover(mouseOver && (toolButtonOption->activeSubControls & SC_ToolButtonMenu)); | ||||
240 | _animations->toolButtonEngine().updateState(widget, AnimationHover, arrowHover); | ||||
241 | | ||||
242 | const bool animated(_animations->toolButtonEngine().isAnimated(widget, AnimationHover)); | ||||
243 | const qreal opacity(_animations->toolButtonEngine().opacity(widget, AnimationHover)); | ||||
244 | | ||||
245 | color = _helper->arrowColor(palette, arrowHover, false, opacity, animated ? AnimationHover : AnimationNone); | ||||
246 | } | ||||
247 | | ||||
248 | } else if (flat) { | ||||
249 | if (sunken && hasFocus && !mouseOver) | ||||
250 | color = palette.color(QPalette::HighlightedText); | ||||
251 | else | ||||
252 | color = _helper->arrowColor(palette, QPalette::WindowText); | ||||
253 | | ||||
254 | } else if (hasFocus && !mouseOver) { | ||||
255 | color = palette.color(QPalette::HighlightedText); | ||||
256 | | ||||
257 | } else { | ||||
258 | color = _helper->arrowColor(palette, QPalette::ButtonText); | ||||
259 | } | ||||
260 | | ||||
261 | } else | ||||
262 | color = _helper->arrowColor(palette, QPalette::WindowText); | ||||
263 | | ||||
264 | // render | ||||
265 | _helper->renderArrow(painter, rect, color, orientation); | ||||
266 | | ||||
267 | return true; | ||||
268 | } | ||||
269 | | ||||
270 | //___________________________________________________________________________________ | ||||
271 | bool Style::drawIndicatorButtonDropDownPrimitive(const QStyleOption *option, QPainter *painter, const QWidget *widget) const | ||||
272 | { | ||||
273 | // cast option and check | ||||
274 | const auto toolButtonOption(qstyleoption_cast<const QStyleOptionToolButton *>(option)); | ||||
275 | if (!toolButtonOption) | ||||
276 | return true; | ||||
277 | | ||||
278 | // store state | ||||
279 | const State &state(option->state); | ||||
280 | const bool autoRaise(state & State_AutoRaise); | ||||
281 | | ||||
282 | // do nothing for autoraise buttons | ||||
283 | if (autoRaise || !(toolButtonOption->subControls & SC_ToolButtonMenu)) | ||||
284 | return true; | ||||
285 | | ||||
286 | // store palette and rect | ||||
287 | const auto &palette(option->palette); | ||||
288 | const auto &rect(option->rect); | ||||
289 | | ||||
290 | // store state | ||||
291 | const bool enabled(state & State_Enabled); | ||||
292 | const bool hasFocus(enabled && (state & (State_HasFocus | State_Sunken))); | ||||
293 | const bool mouseOver(enabled && (state & State_MouseOver)); | ||||
294 | const bool sunken(enabled && (state & State_Sunken)); | ||||
295 | | ||||
296 | // update animation state | ||||
297 | // mouse over takes precedence over focus | ||||
298 | _animations->widgetStateEngine().updateState(widget, AnimationHover, mouseOver); | ||||
299 | _animations->widgetStateEngine().updateState(widget, AnimationFocus, hasFocus && !mouseOver); | ||||
300 | | ||||
301 | const AnimationMode mode(_animations->widgetStateEngine().buttonAnimationMode(widget)); | ||||
302 | const qreal opacity(_animations->widgetStateEngine().buttonOpacity(widget)); | ||||
303 | | ||||
304 | // render as push button | ||||
305 | const auto shadow(_helper->shadowColor(palette)); | ||||
306 | const auto outline(_helper->buttonOutlineColor(palette, mouseOver, hasFocus, opacity, mode)); | ||||
307 | const auto background(_helper->buttonBackgroundColor(palette, mouseOver, hasFocus, false, opacity, mode)); | ||||
308 | | ||||
309 | auto frameRect(rect); | ||||
310 | painter->setClipRect(rect); | ||||
311 | frameRect.adjust(-Metrics::Frame_FrameRadius - 1, 0, 0, 0); | ||||
312 | frameRect = visualRect(option, frameRect); | ||||
313 | | ||||
314 | // render | ||||
315 | _helper->renderButtonFrame(painter, frameRect, background, outline, shadow, hasFocus, sunken); | ||||
316 | | ||||
317 | // also render separator | ||||
318 | auto separatorRect(rect.adjusted(0, 2, -2, -2)); | ||||
319 | separatorRect.setWidth(1); | ||||
320 | separatorRect = visualRect(option, separatorRect); | ||||
321 | if (sunken) | ||||
322 | separatorRect.translate(1, 1); | ||||
323 | _helper->renderSeparator(painter, separatorRect, outline, true); | ||||
324 | | ||||
325 | return true; | ||||
326 | } | ||||
327 | | ||||
328 | //___________________________________________________________________________________ | ||||
329 | bool Style::drawToolButtonLabelControl(const QStyleOption *option, QPainter *painter, const QWidget *widget) const | ||||
330 | { | ||||
331 | // cast option and check | ||||
332 | const auto toolButtonOption(qstyleoption_cast<const QStyleOptionToolButton *>(option)); | ||||
333 | | ||||
334 | // copy rect and palette | ||||
335 | const auto &rect = option->rect; | ||||
336 | const auto &palette = option->palette; | ||||
337 | | ||||
338 | // state | ||||
339 | const State &state(option->state); | ||||
340 | const bool enabled(state & State_Enabled); | ||||
341 | const bool sunken(state & (State_On | State_Sunken)); | ||||
342 | const bool mouseOver(enabled && (option->state & State_MouseOver)); | ||||
343 | const bool flat(state & State_AutoRaise); | ||||
344 | | ||||
345 | // focus flag is set to match the background color in either renderButtonFrame or renderToolButtonFrame | ||||
346 | bool hasFocus(false); | ||||
347 | if (flat) | ||||
348 | hasFocus = enabled && !mouseOver && (option->state & State_HasFocus); | ||||
349 | else | ||||
350 | hasFocus = enabled && !mouseOver && (option->state & (State_HasFocus | State_Sunken)); | ||||
351 | | ||||
352 | const bool hasArrow(toolButtonOption->features & QStyleOptionToolButton::Arrow); | ||||
353 | const bool hasIcon(!(hasArrow || toolButtonOption->icon.isNull())); | ||||
354 | const bool hasText(!toolButtonOption->text.isEmpty()); | ||||
355 | | ||||
356 | // contents | ||||
357 | auto contentsRect(rect); | ||||
358 | if (sunken && !flat) | ||||
359 | contentsRect.translate(1, 1); | ||||
360 | | ||||
361 | // icon size | ||||
362 | const QSize iconSize(toolButtonOption->iconSize); | ||||
363 | | ||||
364 | // text size | ||||
365 | int textFlags(_mnemonics->textFlags()); | ||||
366 | const QSize textSize(option->fontMetrics.size(textFlags, toolButtonOption->text)); | ||||
367 | | ||||
368 | // adjust text and icon rect based on options | ||||
369 | QRect iconRect; | ||||
370 | QRect textRect; | ||||
371 | | ||||
372 | if (hasText && (!(hasArrow || hasIcon) || toolButtonOption->toolButtonStyle == Qt::ToolButtonTextOnly)) { | ||||
373 | // text only | ||||
374 | textRect = contentsRect; | ||||
375 | textFlags |= Qt::AlignCenter; | ||||
376 | | ||||
377 | } else if ((hasArrow || hasIcon) && (!hasText || toolButtonOption->toolButtonStyle == Qt::ToolButtonIconOnly)) { | ||||
378 | // icon only | ||||
379 | iconRect = contentsRect; | ||||
380 | | ||||
381 | } else if (toolButtonOption->toolButtonStyle == Qt::ToolButtonTextUnderIcon) { | ||||
382 | const int contentsHeight(iconSize.height() + textSize.height() + Metrics::ToolButton_ItemSpacing); | ||||
383 | iconRect = QRect(QPoint(contentsRect.left() + (contentsRect.width() - iconSize.width()) / 2, contentsRect.top() + (contentsRect.height() - contentsHeight) / 2), iconSize); | ||||
384 | textRect = QRect(QPoint(contentsRect.left() + (contentsRect.width() - textSize.width()) / 2, iconRect.bottom() + Metrics::ToolButton_ItemSpacing + 1), textSize); | ||||
385 | textFlags |= Qt::AlignCenter; | ||||
386 | | ||||
387 | } else { | ||||
388 | const bool leftAlign(widget && widget->property(PropertyNames::toolButtonAlignment).toInt() == Qt::AlignLeft); | ||||
389 | if (leftAlign) { | ||||
390 | const int marginWidth(Metrics::Button_MarginWidth + Metrics::Frame_FrameWidth + 1); | ||||
391 | iconRect = QRect(QPoint(contentsRect.left() + marginWidth, contentsRect.top() + (contentsRect.height() - iconSize.height()) / 2), iconSize); | ||||
392 | } else { | ||||
393 | const int contentsWidth(iconSize.width() + textSize.width() + Metrics::ToolButton_ItemSpacing); | ||||
394 | iconRect = QRect(QPoint(contentsRect.left() + (contentsRect.width() - contentsWidth) / 2, contentsRect.top() + (contentsRect.height() - iconSize.height()) / 2), iconSize); | ||||
395 | } | ||||
396 | | ||||
397 | textRect = QRect(QPoint(iconRect.right() + Metrics::ToolButton_ItemSpacing + 1, contentsRect.top() + (contentsRect.height() - textSize.height()) / 2), textSize); | ||||
398 | | ||||
399 | // handle right to left layouts | ||||
400 | iconRect = visualRect(option, iconRect); | ||||
401 | textRect = visualRect(option, textRect); | ||||
402 | | ||||
403 | textFlags |= Qt::AlignLeft | Qt::AlignVCenter; | ||||
404 | } | ||||
405 | | ||||
406 | // make sure there is enough room for icon | ||||
407 | if (iconRect.isValid()) | ||||
408 | iconRect = centerRect(iconRect, iconSize); | ||||
409 | | ||||
410 | // render arrow or icon | ||||
411 | if (hasArrow && iconRect.isValid()) { | ||||
412 | QStyleOptionToolButton copy(*toolButtonOption); | ||||
413 | copy.rect = iconRect; | ||||
414 | switch (toolButtonOption->arrowType) { | ||||
415 | case Qt::LeftArrow: | ||||
416 | drawPrimitive(PE_IndicatorArrowLeft, ©, painter, widget); | ||||
417 | break; | ||||
418 | case Qt::RightArrow: | ||||
419 | drawPrimitive(PE_IndicatorArrowRight, ©, painter, widget); | ||||
420 | break; | ||||
421 | case Qt::UpArrow: | ||||
422 | drawPrimitive(PE_IndicatorArrowUp, ©, painter, widget); | ||||
423 | break; | ||||
424 | case Qt::DownArrow: | ||||
425 | drawPrimitive(PE_IndicatorArrowDown, ©, painter, widget); | ||||
426 | break; | ||||
427 | default: | ||||
428 | break; | ||||
429 | } | ||||
430 | | ||||
431 | } else if (hasIcon && iconRect.isValid()) { | ||||
432 | // icon state and mode | ||||
433 | const QIcon::State iconState(sunken ? QIcon::On : QIcon::Off); | ||||
434 | QIcon::Mode iconMode; | ||||
435 | if (!enabled) | ||||
436 | iconMode = QIcon::Disabled; | ||||
437 | else if ((!flat && hasFocus) || (flat && (state & State_Sunken) && !mouseOver)) | ||||
438 | iconMode = QIcon::Selected; | ||||
439 | else if (mouseOver && flat) | ||||
440 | iconMode = QIcon::Active; | ||||
441 | else | ||||
442 | iconMode = QIcon::Normal; | ||||
443 | | ||||
444 | const QPixmap pixmap = toolButtonOption->icon.pixmap(iconSize, iconMode, iconState); | ||||
445 | drawItemPixmap(painter, iconRect, Qt::AlignCenter, pixmap); | ||||
446 | } | ||||
447 | | ||||
448 | // render text | ||||
449 | if (hasText && textRect.isValid()) { | ||||
450 | QPalette::ColorRole textRole(QPalette::ButtonText); | ||||
451 | if (flat) | ||||
452 | textRole = (((hasFocus && sunken) || (state & State_Sunken)) && !mouseOver) ? QPalette::HighlightedText : QPalette::WindowText; | ||||
453 | else if (hasFocus && !mouseOver) | ||||
454 | textRole = QPalette::HighlightedText; | ||||
455 | | ||||
456 | painter->setFont(toolButtonOption->font); | ||||
457 | drawItemText(painter, textRect, textFlags, palette, enabled, toolButtonOption->text, textRole); | ||||
458 | } | ||||
459 | | ||||
460 | return true; | ||||
461 | } | ||||
462 | | ||||
463 | //______________________________________________________________ | ||||
464 | bool Style::drawToolButtonComplexControl(const QStyleOptionComplex *option, QPainter *painter, const QWidget *widget) const | ||||
465 | { | ||||
466 | // cast option and check | ||||
467 | const auto toolButtonOption(qstyleoption_cast<const QStyleOptionToolButton *>(option)); | ||||
468 | if (!toolButtonOption) | ||||
469 | return true; | ||||
470 | | ||||
471 | // need to alter palette for focused buttons | ||||
472 | const State &state(option->state); | ||||
473 | const bool enabled(state & State_Enabled); | ||||
474 | const bool mouseOver(enabled && (option->state & State_MouseOver)); | ||||
475 | const bool hasFocus(enabled && (option->state & State_HasFocus)); | ||||
476 | const bool sunken(state & (State_On | State_Sunken)); | ||||
477 | const bool flat(state & State_AutoRaise); | ||||
478 | | ||||
479 | // update animation state | ||||
480 | // mouse over takes precedence over focus | ||||
481 | _animations->widgetStateEngine().updateState(widget, AnimationHover, mouseOver); | ||||
482 | _animations->widgetStateEngine().updateState(widget, AnimationFocus, hasFocus && !mouseOver); | ||||
483 | | ||||
484 | // detect buttons in tabbar, for which special rendering is needed | ||||
485 | const bool inTabBar(widget && qobject_cast<const QTabBar *>(widget->parentWidget())); | ||||
486 | const bool isMenuTitle(this->isMenuTitle(widget)); | ||||
487 | if (isMenuTitle) { | ||||
488 | // copy option to adjust state, and set font as not-bold | ||||
489 | QStyleOptionToolButton copy(*toolButtonOption); | ||||
490 | copy.font.setBold(false); | ||||
491 | copy.state = State_Enabled; | ||||
492 | | ||||
493 | // render | ||||
494 | renderMenuTitle(©, painter, widget); | ||||
495 | return true; | ||||
496 | } | ||||
497 | | ||||
498 | // copy option and alter palette | ||||
499 | QStyleOptionToolButton copy(*toolButtonOption); | ||||
500 | | ||||
501 | const bool hasPopupMenu(toolButtonOption->features & QStyleOptionToolButton::MenuButtonPopup); | ||||
502 | const bool hasInlineIndicator(toolButtonOption->features & QStyleOptionToolButton::HasMenu && toolButtonOption->features & QStyleOptionToolButton::PopupDelay && !hasPopupMenu); | ||||
503 | | ||||
504 | const auto buttonRect(subControlRect(CC_ToolButton, option, SC_ToolButton, widget)); | ||||
505 | const auto menuRect(subControlRect(CC_ToolButton, option, SC_ToolButtonMenu, widget)); | ||||
506 | | ||||
507 | // frame | ||||
508 | if (toolButtonOption->subControls & SC_ToolButton) { | ||||
509 | if (!flat) | ||||
510 | copy.rect = buttonRect; | ||||
511 | if (inTabBar) | ||||
512 | drawTabBarPanelButtonToolPrimitive(©, painter, widget); | ||||
513 | else | ||||
514 | drawPrimitive(PE_PanelButtonTool, ©, painter, widget); | ||||
515 | } | ||||
516 | | ||||
517 | // arrow | ||||
518 | if (hasPopupMenu) { | ||||
519 | copy.rect = menuRect; | ||||
520 | if (!flat) | ||||
521 | drawPrimitive(PE_IndicatorButtonDropDown, ©, painter, widget); | ||||
522 | | ||||
523 | if (sunken && !flat) | ||||
524 | copy.rect.translate(1, 1); | ||||
525 | drawPrimitive(PE_IndicatorArrowDown, ©, painter, widget); | ||||
526 | | ||||
527 | } else if (hasInlineIndicator) { | ||||
528 | copy.rect = menuRect; | ||||
529 | | ||||
530 | if (sunken && !flat) | ||||
531 | copy.rect.translate(1, 1); | ||||
532 | drawPrimitive(PE_IndicatorArrowDown, ©, painter, widget); | ||||
533 | } | ||||
534 | | ||||
535 | // contents | ||||
536 | { | ||||
537 | // restore state | ||||
538 | copy.state = state; | ||||
539 | | ||||
540 | // define contents rect | ||||
541 | auto contentsRect(buttonRect); | ||||
542 | | ||||
543 | // detect dock widget title button | ||||
544 | // for dockwidget title buttons, do not take out margins, so that icon do not get scaled down | ||||
545 | const bool isDockWidgetTitleButton(widget && widget->inherits("QDockWidgetTitleButton")); | ||||
546 | if (isDockWidgetTitleButton) { | ||||
547 | // cast to abstract button | ||||
548 | // adjust state to have correct icon rendered | ||||
549 | const auto button(qobject_cast<const QAbstractButton *>(widget)); | ||||
550 | if (button->isChecked() || button->isDown()) | ||||
551 | copy.state |= State_On; | ||||
552 | | ||||
553 | } else if (!inTabBar && hasInlineIndicator) { | ||||
554 | const int marginWidth(flat ? Metrics::ToolButton_MarginWidth : Metrics::Button_MarginWidth + Metrics::Frame_FrameWidth); | ||||
555 | contentsRect = insideMargin(contentsRect, marginWidth, 0); | ||||
556 | contentsRect.setRight(contentsRect.right() - Metrics::ToolButton_InlineIndicatorWidth); | ||||
557 | contentsRect = visualRect(option, contentsRect); | ||||
558 | } | ||||
559 | | ||||
560 | copy.rect = contentsRect; | ||||
561 | | ||||
562 | // render | ||||
563 | drawControl(CE_ToolButtonLabel, ©, painter, widget); | ||||
564 | } | ||||
565 | | ||||
566 | return true; | ||||
567 | } | ||||
568 | | ||||
569 | } |