Changeset View
Changeset View
Standalone View
Standalone View
kstyle/widgets/tabbar.cpp
- This file was added.
1 | #include "tabbar_p.h" | ||||
---|---|---|---|---|---|
2 | | ||||
3 | namespace Breeze | ||||
4 | { | ||||
5 | //______________________________________________________________________________ | ||||
6 | void Helper::renderTabBarTab(QPainter *painter, const QRect &rect, const QColor &color, const QColor &outline, Corners corners) const | ||||
7 | { | ||||
8 | // setup painter | ||||
9 | painter->setRenderHint(QPainter::Antialiasing, true); | ||||
10 | | ||||
11 | QRectF frameRect(rect); | ||||
12 | qreal radius(frameRadius()); | ||||
13 | | ||||
14 | // pen | ||||
15 | if (outline.isValid()) { | ||||
16 | painter->setPen(outline); | ||||
17 | frameRect.adjust(0.5, 0.5, -0.5, -0.5); | ||||
18 | radius = qMax(radius - 1, qreal(0.0)); | ||||
19 | | ||||
20 | } else | ||||
21 | painter->setPen(Qt::NoPen); | ||||
22 | | ||||
23 | // brush | ||||
24 | if (color.isValid()) | ||||
25 | painter->setBrush(color); | ||||
26 | else | ||||
27 | painter->setBrush(Qt::NoBrush); | ||||
28 | | ||||
29 | // render | ||||
30 | QPainterPath path(roundedPath(frameRect, corners, radius)); | ||||
31 | painter->drawPath(path); | ||||
32 | } | ||||
33 | | ||||
34 | //______________________________________________________________________________ | ||||
35 | void Helper::renderTabWidgetFrame(QPainter *painter, const QRect &rect, const QColor &color, const QColor &outline, Corners corners) const | ||||
36 | { | ||||
37 | painter->setRenderHint(QPainter::Antialiasing); | ||||
38 | | ||||
39 | QRectF frameRect(rect.adjusted(1, 1, -1, -1)); | ||||
40 | qreal radius(frameRadius()); | ||||
41 | | ||||
42 | // set pen | ||||
43 | if (outline.isValid()) { | ||||
44 | painter->setPen(outline); | ||||
45 | frameRect.adjust(0.5, 0.5, -0.5, -0.5); | ||||
46 | radius = qMax(radius - 1, qreal(0.0)); | ||||
47 | | ||||
48 | } else | ||||
49 | painter->setPen(Qt::NoPen); | ||||
50 | | ||||
51 | // set brush | ||||
52 | if (color.isValid()) | ||||
53 | painter->setBrush(color); | ||||
54 | else | ||||
55 | painter->setBrush(Qt::NoBrush); | ||||
56 | | ||||
57 | // render | ||||
58 | QPainterPath path(roundedPath(frameRect, corners, radius)); | ||||
59 | painter->drawPath(path); | ||||
60 | } | ||||
61 | | ||||
62 | //____________________________________________________________________ | ||||
63 | QRect Style::tabBarTabLeftButtonRect(const QStyleOption *option, const QWidget *) const | ||||
64 | { | ||||
65 | // cast option and check | ||||
66 | #if BREEZE_USE_KDE4 | ||||
67 | const auto tabOption(qstyleoption_cast<const QStyleOptionTabV3 *>(option)); | ||||
68 | #else | ||||
69 | const auto tabOption(qstyleoption_cast<const QStyleOptionTab *>(option)); | ||||
70 | #endif | ||||
71 | if (!tabOption || tabOption->leftButtonSize.isEmpty()) | ||||
72 | return QRect(); | ||||
73 | | ||||
74 | const auto rect(option->rect); | ||||
75 | const QSize size(tabOption->leftButtonSize); | ||||
76 | QRect buttonRect(QPoint(0, 0), size); | ||||
77 | | ||||
78 | // vertical positioning | ||||
79 | switch (tabOption->shape) { | ||||
80 | case QTabBar::RoundedNorth: | ||||
81 | case QTabBar::TriangularNorth: | ||||
82 | | ||||
83 | case QTabBar::RoundedSouth: | ||||
84 | case QTabBar::TriangularSouth: | ||||
85 | buttonRect.moveLeft(rect.left() + Metrics::TabBar_TabMarginWidth); | ||||
86 | buttonRect.moveTop((rect.height() - buttonRect.height()) / 2); | ||||
87 | buttonRect = visualRect(option, buttonRect); | ||||
88 | break; | ||||
89 | | ||||
90 | case QTabBar::RoundedWest: | ||||
91 | case QTabBar::TriangularWest: | ||||
92 | buttonRect.moveBottom(rect.bottom() - Metrics::TabBar_TabMarginWidth); | ||||
93 | buttonRect.moveLeft((rect.width() - buttonRect.width()) / 2); | ||||
94 | break; | ||||
95 | | ||||
96 | case QTabBar::RoundedEast: | ||||
97 | case QTabBar::TriangularEast: | ||||
98 | buttonRect.moveTop(rect.top() + Metrics::TabBar_TabMarginWidth); | ||||
99 | buttonRect.moveLeft((rect.width() - buttonRect.width()) / 2); | ||||
100 | break; | ||||
101 | | ||||
102 | default: | ||||
103 | break; | ||||
104 | } | ||||
105 | | ||||
106 | return buttonRect; | ||||
107 | } | ||||
108 | | ||||
109 | //____________________________________________________________________ | ||||
110 | QRect Style::tabBarTabRightButtonRect(const QStyleOption *option, const QWidget *) const | ||||
111 | { | ||||
112 | // cast option and check | ||||
113 | #if BREEZE_USE_KDE4 | ||||
114 | const auto tabOption(qstyleoption_cast<const QStyleOptionTabV3 *>(option)); | ||||
115 | #else | ||||
116 | const auto tabOption(qstyleoption_cast<const QStyleOptionTab *>(option)); | ||||
117 | #endif | ||||
118 | if (!tabOption || tabOption->rightButtonSize.isEmpty()) | ||||
119 | return QRect(); | ||||
120 | | ||||
121 | const auto rect(option->rect); | ||||
122 | const auto size(tabOption->rightButtonSize); | ||||
123 | QRect buttonRect(QPoint(0, 0), size); | ||||
124 | | ||||
125 | // vertical positioning | ||||
126 | switch (tabOption->shape) { | ||||
127 | case QTabBar::RoundedNorth: | ||||
128 | case QTabBar::TriangularNorth: | ||||
129 | | ||||
130 | case QTabBar::RoundedSouth: | ||||
131 | case QTabBar::TriangularSouth: | ||||
132 | buttonRect.moveRight(rect.right() - Metrics::TabBar_TabMarginWidth); | ||||
133 | buttonRect.moveTop((rect.height() - buttonRect.height()) / 2); | ||||
134 | buttonRect = visualRect(option, buttonRect); | ||||
135 | break; | ||||
136 | | ||||
137 | case QTabBar::RoundedWest: | ||||
138 | case QTabBar::TriangularWest: | ||||
139 | buttonRect.moveTop(rect.top() + Metrics::TabBar_TabMarginWidth); | ||||
140 | buttonRect.moveLeft((rect.width() - buttonRect.width()) / 2); | ||||
141 | break; | ||||
142 | | ||||
143 | case QTabBar::RoundedEast: | ||||
144 | case QTabBar::TriangularEast: | ||||
145 | buttonRect.moveBottom(rect.bottom() - Metrics::TabBar_TabMarginWidth); | ||||
146 | buttonRect.moveLeft((rect.width() - buttonRect.width()) / 2); | ||||
147 | break; | ||||
148 | | ||||
149 | default: | ||||
150 | break; | ||||
151 | } | ||||
152 | | ||||
153 | return buttonRect; | ||||
154 | } | ||||
155 | | ||||
156 | //______________________________________________________________ | ||||
157 | QSize Style::tabBarTabSizeFromContents(const QStyleOption *option, const QSize &contentsSize, const QWidget *) const | ||||
158 | { | ||||
159 | const auto tabOption(qstyleoption_cast<const QStyleOptionTab *>(option)); | ||||
160 | const bool hasText(tabOption && !tabOption->text.isEmpty()); | ||||
161 | const bool hasIcon(tabOption && !tabOption->icon.isNull()); | ||||
162 | #if BREEZE_USE_KDE4 | ||||
163 | const auto tabOptionV3(qstyleoption_cast<const QStyleOptionTabV3 *>(option)); | ||||
164 | const bool hasLeftButton(tabOptionV3 && !tabOptionV3->leftButtonSize.isEmpty()); | ||||
165 | const bool hasRightButton(tabOptionV3 && !tabOptionV3->leftButtonSize.isEmpty()); | ||||
166 | #else | ||||
167 | const bool hasLeftButton(tabOption && !tabOption->leftButtonSize.isEmpty()); | ||||
168 | const bool hasRightButton(tabOption && !tabOption->leftButtonSize.isEmpty()); | ||||
169 | #endif | ||||
170 | | ||||
171 | // calculate width increment for horizontal tabs | ||||
172 | int widthIncrement = 0; | ||||
173 | if (hasIcon && !(hasText || hasLeftButton || hasRightButton)) | ||||
174 | widthIncrement -= 4; | ||||
175 | if (hasText && hasIcon) | ||||
176 | widthIncrement += Metrics::TabBar_TabItemSpacing; | ||||
177 | if (hasLeftButton && (hasText || hasIcon)) | ||||
178 | widthIncrement += Metrics::TabBar_TabItemSpacing; | ||||
179 | if (hasRightButton && (hasText || hasIcon || hasLeftButton)) | ||||
180 | widthIncrement += Metrics::TabBar_TabItemSpacing; | ||||
181 | | ||||
182 | // add margins | ||||
183 | QSize size(contentsSize); | ||||
184 | | ||||
185 | // compare to minimum size | ||||
186 | const bool verticalTabs(tabOption && isVerticalTab(tabOption)); | ||||
187 | if (verticalTabs) { | ||||
188 | size.rheight() += widthIncrement; | ||||
189 | if (hasIcon && !hasText) | ||||
190 | size = size.expandedTo(QSize(Metrics::TabBar_TabMinHeight, 0)); | ||||
191 | else | ||||
192 | size = size.expandedTo(QSize(Metrics::TabBar_TabMinHeight, Metrics::TabBar_TabMinWidth)); | ||||
193 | | ||||
194 | } else { | ||||
195 | size.rwidth() += widthIncrement; | ||||
196 | if (hasIcon && !hasText) | ||||
197 | size = size.expandedTo(QSize(0, Metrics::TabBar_TabMinHeight)); | ||||
198 | else | ||||
199 | size = size.expandedTo(QSize(Metrics::TabBar_TabMinWidth, Metrics::TabBar_TabMinHeight)); | ||||
200 | } | ||||
201 | | ||||
202 | return size; | ||||
203 | } | ||||
204 | | ||||
205 | //___________________________________________________________________________________ | ||||
206 | bool Style::drawTabBarTabLabelControl(const QStyleOption *option, QPainter *painter, const QWidget *widget) const | ||||
207 | { | ||||
208 | // call parent style method | ||||
209 | ParentStyleClass::drawControl(CE_TabBarTabLabel, option, painter, widget); | ||||
210 | | ||||
211 | // store rect and palette | ||||
212 | const auto &rect(option->rect); | ||||
213 | const auto &palette(option->palette); | ||||
214 | | ||||
215 | // check focus | ||||
216 | const State &state(option->state); | ||||
217 | const bool enabled(state & State_Enabled); | ||||
218 | const bool selected(state & State_Selected); | ||||
219 | const bool hasFocus(enabled && selected && (state & State_HasFocus)); | ||||
220 | | ||||
221 | // update mouse over animation state | ||||
222 | _animations->tabBarEngine().updateState(widget, rect.topLeft(), AnimationFocus, hasFocus); | ||||
223 | const bool animated(enabled && selected && _animations->tabBarEngine().isAnimated(widget, rect.topLeft(), AnimationFocus)); | ||||
224 | const qreal opacity(_animations->tabBarEngine().opacity(widget, rect.topLeft(), AnimationFocus)); | ||||
225 | | ||||
226 | if (!(hasFocus || animated)) | ||||
227 | return true; | ||||
228 | | ||||
229 | // code is copied from QCommonStyle, but adds focus | ||||
230 | // cast option and check | ||||
231 | const auto tabOption(qstyleoption_cast<const QStyleOptionTab *>(option)); | ||||
232 | if (!tabOption || tabOption->text.isEmpty()) | ||||
233 | return true; | ||||
234 | | ||||
235 | // tab option rect | ||||
236 | const bool verticalTabs(isVerticalTab(tabOption)); | ||||
237 | const int textFlags(Qt::AlignCenter | _mnemonics->textFlags()); | ||||
238 | | ||||
239 | // text rect | ||||
240 | auto textRect(subElementRect(SE_TabBarTabText, option, widget)); | ||||
241 | | ||||
242 | if (verticalTabs) { | ||||
243 | // properly rotate painter | ||||
244 | painter->save(); | ||||
245 | int newX, newY, newRot; | ||||
246 | if (tabOption->shape == QTabBar::RoundedEast || tabOption->shape == QTabBar::TriangularEast) { | ||||
247 | newX = rect.width() + rect.x(); | ||||
248 | newY = rect.y(); | ||||
249 | newRot = 90; | ||||
250 | | ||||
251 | } else { | ||||
252 | newX = rect.x(); | ||||
253 | newY = rect.y() + rect.height(); | ||||
254 | newRot = -90; | ||||
255 | } | ||||
256 | | ||||
257 | QTransform transform; | ||||
258 | transform.translate(newX, newY); | ||||
259 | transform.rotate(newRot); | ||||
260 | painter->setTransform(transform, true); | ||||
261 | } | ||||
262 | | ||||
263 | // adjust text rect based on font metrics | ||||
264 | textRect = option->fontMetrics.boundingRect(textRect, textFlags, tabOption->text); | ||||
265 | | ||||
266 | // focus color | ||||
267 | QColor focusColor; | ||||
268 | if (animated) | ||||
269 | focusColor = _helper->alphaColor(_helper->focusColor(palette), opacity); | ||||
270 | else if (hasFocus) | ||||
271 | focusColor = _helper->focusColor(palette); | ||||
272 | | ||||
273 | // render focus line | ||||
274 | _helper->renderFocusLine(painter, textRect, focusColor); | ||||
275 | | ||||
276 | if (verticalTabs) | ||||
277 | painter->restore(); | ||||
278 | | ||||
279 | return true; | ||||
280 | } | ||||
281 | | ||||
282 | //___________________________________________________________________________________ | ||||
283 | bool Style::drawTabBarTabShapeControl(const QStyleOption *option, QPainter *painter, const QWidget *widget) const | ||||
284 | { | ||||
285 | const auto tabOption(qstyleoption_cast<const QStyleOptionTab *>(option)); | ||||
286 | if (!tabOption) | ||||
287 | return true; | ||||
288 | | ||||
289 | // palette and state | ||||
290 | const auto &palette(option->palette); | ||||
291 | const State &state(option->state); | ||||
292 | const bool enabled(state & State_Enabled); | ||||
293 | const bool selected(state & State_Selected); | ||||
294 | const bool mouseOver(enabled && !selected && (state & State_MouseOver)); | ||||
295 | | ||||
296 | // check if tab is being dragged | ||||
297 | const bool isDragged(widget && selected && painter->device() != widget); | ||||
298 | const bool isLocked(widget && _tabBarData->isLocked(widget)); | ||||
299 | | ||||
300 | // store rect | ||||
301 | auto rect(option->rect); | ||||
302 | | ||||
303 | // update mouse over animation state | ||||
304 | _animations->tabBarEngine().updateState(widget, rect.topLeft(), AnimationHover, mouseOver); | ||||
305 | const bool animated(enabled && !selected && _animations->tabBarEngine().isAnimated(widget, rect.topLeft(), AnimationHover)); | ||||
306 | const qreal opacity(_animations->tabBarEngine().opacity(widget, rect.topLeft(), AnimationHover)); | ||||
307 | | ||||
308 | // lock state | ||||
309 | if (selected && widget && isDragged) | ||||
310 | _tabBarData->lock(widget); | ||||
311 | else if (widget && selected && _tabBarData->isLocked(widget)) | ||||
312 | _tabBarData->release(); | ||||
313 | | ||||
314 | // tab position | ||||
315 | const QStyleOptionTab::TabPosition &position = tabOption->position; | ||||
316 | const bool isSingle(position == QStyleOptionTab::OnlyOneTab); | ||||
317 | const bool isQtQuickControl(this->isQtQuickControl(option, widget)); | ||||
318 | bool isFirst(isSingle || position == QStyleOptionTab::Beginning); | ||||
319 | bool isLast(isSingle || position == QStyleOptionTab::End); | ||||
320 | bool isLeftOfSelected(!isLocked && tabOption->selectedPosition == QStyleOptionTab::NextIsSelected); | ||||
321 | bool isRightOfSelected(!isLocked && tabOption->selectedPosition == QStyleOptionTab::PreviousIsSelected); | ||||
322 | | ||||
323 | // true if widget is aligned to the frame | ||||
324 | // need to check for 'isRightOfSelected' because for some reason the isFirst flag is set when active tab is being moved | ||||
325 | isFirst &= !isRightOfSelected; | ||||
326 | isLast &= !isLeftOfSelected; | ||||
327 | | ||||
328 | // swap state based on reverse layout, so that they become layout independent | ||||
329 | const bool reverseLayout(option->direction == Qt::RightToLeft); | ||||
330 | const bool verticalTabs(isVerticalTab(tabOption)); | ||||
331 | if (reverseLayout && !verticalTabs) { | ||||
332 | qSwap(isFirst, isLast); | ||||
333 | qSwap(isLeftOfSelected, isRightOfSelected); | ||||
334 | } | ||||
335 | | ||||
336 | // overlap | ||||
337 | // for QtQuickControls, ovelap is already accounted of in the option. Unlike in the qwidget case | ||||
338 | const int overlap(isQtQuickControl ? 0 : Metrics::TabBar_TabOverlap); | ||||
339 | | ||||
340 | // adjust rect and define corners based on tabbar orientation | ||||
341 | Corners corners; | ||||
342 | switch (tabOption->shape) { | ||||
343 | case QTabBar::RoundedNorth: | ||||
344 | case QTabBar::TriangularNorth: | ||||
345 | if (selected) { | ||||
346 | corners = CornerTopLeft | CornerTopRight; | ||||
347 | rect.adjust(0, 0, 0, 1); | ||||
348 | | ||||
349 | } else { | ||||
350 | rect.adjust(0, 0, 0, -1); | ||||
351 | if (isFirst) | ||||
352 | corners |= CornerTopLeft; | ||||
353 | if (isLast) | ||||
354 | corners |= CornerTopRight; | ||||
355 | if (isRightOfSelected) | ||||
356 | rect.adjust(-Metrics::Frame_FrameRadius, 0, 0, 0); | ||||
357 | if (isLeftOfSelected) | ||||
358 | rect.adjust(0, 0, Metrics::Frame_FrameRadius, 0); | ||||
359 | else if (!isLast) | ||||
360 | rect.adjust(0, 0, overlap, 0); | ||||
361 | } | ||||
362 | break; | ||||
363 | | ||||
364 | case QTabBar::RoundedSouth: | ||||
365 | case QTabBar::TriangularSouth: | ||||
366 | if (selected) { | ||||
367 | corners = CornerBottomLeft | CornerBottomRight; | ||||
368 | rect.adjust(0, -1, 0, 0); | ||||
369 | | ||||
370 | } else { | ||||
371 | rect.adjust(0, 1, 0, 0); | ||||
372 | if (isFirst) | ||||
373 | corners |= CornerBottomLeft; | ||||
374 | if (isLast) | ||||
375 | corners |= CornerBottomRight; | ||||
376 | if (isRightOfSelected) | ||||
377 | rect.adjust(-Metrics::Frame_FrameRadius, 0, 0, 0); | ||||
378 | if (isLeftOfSelected) | ||||
379 | rect.adjust(0, 0, Metrics::Frame_FrameRadius, 0); | ||||
380 | else if (!isLast) | ||||
381 | rect.adjust(0, 0, overlap, 0); | ||||
382 | } | ||||
383 | break; | ||||
384 | | ||||
385 | case QTabBar::RoundedWest: | ||||
386 | case QTabBar::TriangularWest: | ||||
387 | if (selected) { | ||||
388 | corners = CornerTopLeft | CornerBottomLeft; | ||||
389 | rect.adjust(0, 0, 1, 0); | ||||
390 | | ||||
391 | } else { | ||||
392 | rect.adjust(0, 0, -1, 0); | ||||
393 | if (isFirst) | ||||
394 | corners |= CornerTopLeft; | ||||
395 | if (isLast) | ||||
396 | corners |= CornerBottomLeft; | ||||
397 | if (isRightOfSelected) | ||||
398 | rect.adjust(0, -Metrics::Frame_FrameRadius, 0, 0); | ||||
399 | if (isLeftOfSelected) | ||||
400 | rect.adjust(0, 0, 0, Metrics::Frame_FrameRadius); | ||||
401 | else if (!isLast) | ||||
402 | rect.adjust(0, 0, 0, overlap); | ||||
403 | } | ||||
404 | break; | ||||
405 | | ||||
406 | case QTabBar::RoundedEast: | ||||
407 | case QTabBar::TriangularEast: | ||||
408 | if (selected) { | ||||
409 | corners = CornerTopRight | CornerBottomRight; | ||||
410 | rect.adjust(-1, 0, 0, 0); | ||||
411 | | ||||
412 | } else { | ||||
413 | rect.adjust(1, 0, 0, 0); | ||||
414 | if (isFirst) | ||||
415 | corners |= CornerTopRight; | ||||
416 | if (isLast) | ||||
417 | corners |= CornerBottomRight; | ||||
418 | if (isRightOfSelected) | ||||
419 | rect.adjust(0, -Metrics::Frame_FrameRadius, 0, 0); | ||||
420 | if (isLeftOfSelected) | ||||
421 | rect.adjust(0, 0, 0, Metrics::Frame_FrameRadius); | ||||
422 | else if (!isLast) | ||||
423 | rect.adjust(0, 0, 0, overlap); | ||||
424 | } | ||||
425 | break; | ||||
426 | | ||||
427 | default: | ||||
428 | break; | ||||
429 | } | ||||
430 | | ||||
431 | // color | ||||
432 | QColor color; | ||||
433 | if (selected) { | ||||
434 | #if QT_VERSION >= 0x050000 | ||||
435 | bool documentMode = tabOption->documentMode; | ||||
436 | #else | ||||
437 | bool documentMode = false; | ||||
438 | if (const auto tabOptionV3 = qstyleoption_cast<const QStyleOptionTabV3 *>(option)) { | ||||
439 | documentMode = tabOptionV3->documentMode; | ||||
440 | } | ||||
441 | #endif | ||||
442 | | ||||
443 | // flag passed to QStyleOptionTab is unfortunately not reliable enough | ||||
444 | // also need to check on parent widget | ||||
445 | const auto tabWidget = (widget && widget->parentWidget()) ? qobject_cast<const QTabWidget *>(widget->parentWidget()) : nullptr; | ||||
446 | documentMode |= (tabWidget ? tabWidget->documentMode() : true); | ||||
447 | | ||||
448 | color = (documentMode && !isQtQuickControl && !hasAlteredBackground(widget)) ? palette.color(QPalette::Window) : _helper->frameBackgroundColor(palette); | ||||
449 | | ||||
450 | } else { | ||||
451 | const auto normal(_helper->alphaColor(palette.color(QPalette::Shadow), 0.2)); | ||||
452 | const auto hover(_helper->alphaColor(_helper->hoverColor(palette), 0.2)); | ||||
453 | if (animated) | ||||
454 | color = KColorUtils::mix(normal, hover, opacity); | ||||
455 | else if (mouseOver) | ||||
456 | color = hover; | ||||
457 | else | ||||
458 | color = normal; | ||||
459 | } | ||||
460 | | ||||
461 | // outline | ||||
462 | const auto outline(selected ? _helper->alphaColor(palette.color(QPalette::WindowText), 0.25) : QColor()); | ||||
463 | | ||||
464 | // render | ||||
465 | if (selected) { | ||||
466 | QRegion oldRegion(painter->clipRegion()); | ||||
467 | painter->setClipRect(option->rect, Qt::IntersectClip); | ||||
468 | _helper->renderTabBarTab(painter, rect, color, outline, corners); | ||||
469 | painter->setClipRegion(oldRegion); | ||||
470 | | ||||
471 | } else { | ||||
472 | _helper->renderTabBarTab(painter, rect, color, outline, corners); | ||||
473 | } | ||||
474 | | ||||
475 | return true; | ||||
476 | } | ||||
477 | | ||||
478 | //____________________________________________________________________ | ||||
479 | QRect Style::tabWidgetTabBarRect(const QStyleOption *option, const QWidget *widget) const | ||||
480 | { | ||||
481 | // cast option and check | ||||
482 | const auto tabOption = qstyleoption_cast<const QStyleOptionTabWidgetFrame *>(option); | ||||
483 | if (!tabOption) | ||||
484 | return ParentStyleClass::subElementRect(SE_TabWidgetTabBar, option, widget); | ||||
485 | | ||||
486 | // do nothing if tabbar is hidden | ||||
487 | const QSize tabBarSize(tabOption->tabBarSize); | ||||
488 | | ||||
489 | auto rect(option->rect); | ||||
490 | QRect tabBarRect(QPoint(0, 0), tabBarSize); | ||||
491 | | ||||
492 | Qt::Alignment tabBarAlignment(styleHint(SH_TabBar_Alignment, option, widget)); | ||||
493 | | ||||
494 | // horizontal positioning | ||||
495 | const bool verticalTabs(isVerticalTab(tabOption->shape)); | ||||
496 | if (verticalTabs) { | ||||
497 | tabBarRect.setHeight(qMin(tabBarRect.height(), rect.height() - 2)); | ||||
498 | if (tabBarAlignment == Qt::AlignCenter) | ||||
499 | tabBarRect.moveTop(rect.top() + (rect.height() - tabBarRect.height()) / 2); | ||||
500 | else | ||||
501 | tabBarRect.moveTop(rect.top() + 1); | ||||
502 | | ||||
503 | } else { | ||||
504 | // account for corner rects | ||||
505 | // need to re-run visualRect to remove right-to-left handling, since it is re-added on tabBarRect at the end | ||||
506 | const auto leftButtonRect(visualRect(option, subElementRect(SE_TabWidgetLeftCorner, option, widget))); | ||||
507 | const auto rightButtonRect(visualRect(option, subElementRect(SE_TabWidgetRightCorner, option, widget))); | ||||
508 | | ||||
509 | rect.setLeft(leftButtonRect.width()); | ||||
510 | rect.setRight(rightButtonRect.left() - 1); | ||||
511 | | ||||
512 | tabBarRect.setWidth(qMin(tabBarRect.width(), rect.width() - 2)); | ||||
513 | if (tabBarAlignment == Qt::AlignCenter) | ||||
514 | tabBarRect.moveLeft(rect.left() + (rect.width() - tabBarRect.width()) / 2); | ||||
515 | else | ||||
516 | tabBarRect.moveLeft(rect.left() + 1); | ||||
517 | | ||||
518 | tabBarRect = visualRect(option, tabBarRect); | ||||
519 | } | ||||
520 | | ||||
521 | // vertical positioning | ||||
522 | switch (tabOption->shape) { | ||||
523 | case QTabBar::RoundedNorth: | ||||
524 | case QTabBar::TriangularNorth: | ||||
525 | tabBarRect.moveTop(rect.top() + 1); | ||||
526 | break; | ||||
527 | | ||||
528 | case QTabBar::RoundedSouth: | ||||
529 | case QTabBar::TriangularSouth: | ||||
530 | tabBarRect.moveBottom(rect.bottom() - 1); | ||||
531 | break; | ||||
532 | | ||||
533 | case QTabBar::RoundedWest: | ||||
534 | case QTabBar::TriangularWest: | ||||
535 | tabBarRect.moveLeft(rect.left() + 1); | ||||
536 | break; | ||||
537 | | ||||
538 | case QTabBar::RoundedEast: | ||||
539 | case QTabBar::TriangularEast: | ||||
540 | tabBarRect.moveRight(rect.right() - 1); | ||||
541 | break; | ||||
542 | | ||||
543 | default: | ||||
544 | break; | ||||
545 | } | ||||
546 | | ||||
547 | return tabBarRect; | ||||
548 | } | ||||
549 | | ||||
550 | //____________________________________________________________________ | ||||
551 | QRect Style::tabWidgetTabContentsRect(const QStyleOption *option, const QWidget *widget) const | ||||
552 | { | ||||
553 | // cast option and check | ||||
554 | const auto tabOption = qstyleoption_cast<const QStyleOptionTabWidgetFrame *>(option); | ||||
555 | if (!tabOption) | ||||
556 | return option->rect; | ||||
557 | | ||||
558 | // do nothing if tabbar is hidden | ||||
559 | if (tabOption->tabBarSize.isEmpty()) | ||||
560 | return option->rect; | ||||
561 | const auto rect = tabWidgetTabPaneRect(option, widget); | ||||
562 | | ||||
563 | const bool documentMode(tabOption->lineWidth == 0); | ||||
564 | if (documentMode) { | ||||
565 | // add margin only to the relevant side | ||||
566 | switch (tabOption->shape) { | ||||
567 | case QTabBar::RoundedNorth: | ||||
568 | case QTabBar::TriangularNorth: | ||||
569 | return rect.adjusted(0, Metrics::TabWidget_MarginWidth, 0, 0); | ||||
570 | | ||||
571 | case QTabBar::RoundedSouth: | ||||
572 | case QTabBar::TriangularSouth: | ||||
573 | return rect.adjusted(0, 0, 0, -Metrics::TabWidget_MarginWidth); | ||||
574 | | ||||
575 | case QTabBar::RoundedWest: | ||||
576 | case QTabBar::TriangularWest: | ||||
577 | return rect.adjusted(Metrics::TabWidget_MarginWidth, 0, 0, 0); | ||||
578 | | ||||
579 | case QTabBar::RoundedEast: | ||||
580 | case QTabBar::TriangularEast: | ||||
581 | return rect.adjusted(0, 0, -Metrics::TabWidget_MarginWidth, 0); | ||||
582 | | ||||
583 | default: | ||||
584 | return rect; | ||||
585 | } | ||||
586 | | ||||
587 | } else | ||||
588 | return insideMargin(rect, Metrics::TabWidget_MarginWidth); | ||||
589 | } | ||||
590 | | ||||
591 | //____________________________________________________________________ | ||||
592 | QRect Style::tabWidgetTabPaneRect(const QStyleOption *option, const QWidget *) const | ||||
593 | { | ||||
594 | const auto tabOption = qstyleoption_cast<const QStyleOptionTabWidgetFrame *>(option); | ||||
595 | if (!tabOption || tabOption->tabBarSize.isEmpty()) | ||||
596 | return option->rect; | ||||
597 | | ||||
598 | const int overlap = Metrics::TabBar_BaseOverlap - 1; | ||||
599 | const QSize tabBarSize(tabOption->tabBarSize - QSize(overlap, overlap)); | ||||
600 | | ||||
601 | auto rect(option->rect); | ||||
602 | switch (tabOption->shape) { | ||||
603 | case QTabBar::RoundedNorth: | ||||
604 | case QTabBar::TriangularNorth: | ||||
605 | rect.adjust(0, tabBarSize.height(), 0, 0); | ||||
606 | break; | ||||
607 | | ||||
608 | case QTabBar::RoundedSouth: | ||||
609 | case QTabBar::TriangularSouth: | ||||
610 | rect.adjust(0, 0, 0, -tabBarSize.height()); | ||||
611 | break; | ||||
612 | | ||||
613 | case QTabBar::RoundedWest: | ||||
614 | case QTabBar::TriangularWest: | ||||
615 | rect.adjust(tabBarSize.width(), 0, 0, 0); | ||||
616 | break; | ||||
617 | | ||||
618 | case QTabBar::RoundedEast: | ||||
619 | case QTabBar::TriangularEast: | ||||
620 | rect.adjust(0, 0, -tabBarSize.width(), 0); | ||||
621 | break; | ||||
622 | | ||||
623 | default: | ||||
624 | return QRect(); | ||||
625 | } | ||||
626 | | ||||
627 | return rect; | ||||
628 | } | ||||
629 | | ||||
630 | //____________________________________________________________________ | ||||
631 | QRect Style::tabWidgetCornerRect(SubElement element, const QStyleOption *option, const QWidget *) const | ||||
632 | { | ||||
633 | // cast option and check | ||||
634 | const auto tabOption = qstyleoption_cast<const QStyleOptionTabWidgetFrame *>(option); | ||||
635 | if (!tabOption) | ||||
636 | return option->rect; | ||||
637 | | ||||
638 | // do nothing if tabbar is hidden | ||||
639 | const QSize tabBarSize(tabOption->tabBarSize); | ||||
640 | if (tabBarSize.isEmpty()) | ||||
641 | return QRect(); | ||||
642 | | ||||
643 | // do nothing for vertical tabs | ||||
644 | const bool verticalTabs(isVerticalTab(tabOption->shape)); | ||||
645 | if (verticalTabs) | ||||
646 | return QRect(); | ||||
647 | | ||||
648 | const auto rect(option->rect); | ||||
649 | QRect cornerRect; | ||||
650 | switch (element) { | ||||
651 | case SE_TabWidgetLeftCorner: | ||||
652 | cornerRect = QRect(QPoint(0, 0), tabOption->leftCornerWidgetSize); | ||||
653 | cornerRect.moveLeft(rect.left()); | ||||
654 | break; | ||||
655 | | ||||
656 | case SE_TabWidgetRightCorner: | ||||
657 | cornerRect = QRect(QPoint(0, 0), tabOption->rightCornerWidgetSize); | ||||
658 | cornerRect.moveRight(rect.right()); | ||||
659 | break; | ||||
660 | | ||||
661 | default: | ||||
662 | break; | ||||
663 | } | ||||
664 | | ||||
665 | // expend height to tabBarSize, if needed, to make sure base is properly rendered | ||||
666 | cornerRect.setHeight(qMax(cornerRect.height(), tabBarSize.height() + 1)); | ||||
667 | | ||||
668 | switch (tabOption->shape) { | ||||
669 | case QTabBar::RoundedNorth: | ||||
670 | case QTabBar::TriangularNorth: | ||||
671 | cornerRect.moveTop(rect.top()); | ||||
672 | break; | ||||
673 | | ||||
674 | case QTabBar::RoundedSouth: | ||||
675 | case QTabBar::TriangularSouth: | ||||
676 | cornerRect.moveBottom(rect.bottom()); | ||||
677 | break; | ||||
678 | | ||||
679 | default: | ||||
680 | break; | ||||
681 | } | ||||
682 | | ||||
683 | // return cornerRect; | ||||
684 | cornerRect = visualRect(option, cornerRect); | ||||
685 | return cornerRect; | ||||
686 | } | ||||
687 | | ||||
688 | //______________________________________________________________ | ||||
689 | QSize Style::tabWidgetSizeFromContents(const QStyleOption *option, const QSize &contentsSize, const QWidget *widget) const | ||||
690 | { | ||||
691 | // cast option and check | ||||
692 | const auto tabOption = qstyleoption_cast<const QStyleOptionTabWidgetFrame *>(option); | ||||
693 | if (!tabOption) | ||||
694 | return expandSize(contentsSize, Metrics::TabWidget_MarginWidth); | ||||
695 | | ||||
696 | // try find direct children of type QTabBar and QStackedWidget | ||||
697 | // this is needed in order to add TabWidget margins only if they are necessary around tabWidget content, not the tabbar | ||||
698 | if (!widget) | ||||
699 | return expandSize(contentsSize, Metrics::TabWidget_MarginWidth); | ||||
700 | QTabBar *tabBar = nullptr; | ||||
701 | QStackedWidget *stack = nullptr; | ||||
702 | auto children(widget->children()); | ||||
703 | foreach (auto child, children) { | ||||
704 | if (!tabBar) | ||||
705 | tabBar = qobject_cast<QTabBar *>(child); | ||||
706 | if (!stack) | ||||
707 | stack = qobject_cast<QStackedWidget *>(child); | ||||
708 | if (tabBar && stack) | ||||
709 | break; | ||||
710 | } | ||||
711 | | ||||
712 | if (!(tabBar && stack)) | ||||
713 | return expandSize(contentsSize, Metrics::TabWidget_MarginWidth); | ||||
714 | | ||||
715 | // tab orientation | ||||
716 | const bool verticalTabs(tabOption && isVerticalTab(tabOption->shape)); | ||||
717 | if (verticalTabs) { | ||||
718 | const int tabBarHeight = tabBar->minimumSizeHint().height(); | ||||
719 | const int stackHeight = stack->minimumSizeHint().height(); | ||||
720 | if (contentsSize.height() == tabBarHeight && tabBarHeight + 2 * (Metrics::Frame_FrameWidth - 1) >= stackHeight + 2 * Metrics::TabWidget_MarginWidth) | ||||
721 | return QSize(contentsSize.width() + 2 * Metrics::TabWidget_MarginWidth, contentsSize.height() + 2 * (Metrics::Frame_FrameWidth - 1)); | ||||
722 | else | ||||
723 | return expandSize(contentsSize, Metrics::TabWidget_MarginWidth); | ||||
724 | | ||||
725 | } else { | ||||
726 | const int tabBarWidth = tabBar->minimumSizeHint().width(); | ||||
727 | const int stackWidth = stack->minimumSizeHint().width(); | ||||
728 | if (contentsSize.width() == tabBarWidth && tabBarWidth + 2 * (Metrics::Frame_FrameWidth - 1) >= stackWidth + 2 * Metrics::TabWidget_MarginWidth) | ||||
729 | return QSize(contentsSize.width() + 2 * (Metrics::Frame_FrameWidth - 1), contentsSize.height() + 2 * Metrics::TabWidget_MarginWidth); | ||||
730 | else | ||||
731 | return expandSize(contentsSize, Metrics::TabWidget_MarginWidth); | ||||
732 | } | ||||
733 | } | ||||
734 | | ||||
735 | //___________________________________________________________________________________ | ||||
736 | bool Style::drawFrameTabWidgetPrimitive(const QStyleOption *option, QPainter *painter, const QWidget *widget) const | ||||
737 | { | ||||
738 | // cast option and check | ||||
739 | #if BREEZE_USE_KDE4 | ||||
740 | const auto tabOption(qstyleoption_cast<const QStyleOptionTabWidgetFrameV2 *>(option)); | ||||
741 | #else | ||||
742 | const auto tabOption(qstyleoption_cast<const QStyleOptionTabWidgetFrame *>(option)); | ||||
743 | #endif | ||||
744 | if (!tabOption) | ||||
745 | return true; | ||||
746 | | ||||
747 | // do nothing if tabbar is hidden | ||||
748 | const bool isQtQuickControl(this->isQtQuickControl(option, widget)); | ||||
749 | if (tabOption->tabBarSize.isEmpty() && !isQtQuickControl) | ||||
750 | return true; | ||||
751 | | ||||
752 | // adjust rect to handle overlaps | ||||
753 | auto rect(option->rect); | ||||
754 | | ||||
755 | const auto tabBarRect(tabOption->tabBarRect); | ||||
756 | const QSize tabBarSize(tabOption->tabBarSize); | ||||
757 | Corners corners = AllCorners; | ||||
758 | | ||||
759 | // adjust corners to deal with oversized tabbars | ||||
760 | switch (tabOption->shape) { | ||||
761 | case QTabBar::RoundedNorth: | ||||
762 | case QTabBar::TriangularNorth: | ||||
763 | if (isQtQuickControl) | ||||
764 | rect.adjust(-1, -1, 1, 0); | ||||
765 | if (tabBarSize.width() >= rect.width() - 2 * Metrics::Frame_FrameRadius) | ||||
766 | corners &= ~CornersTop; | ||||
767 | if (tabBarRect.left() < rect.left() + Metrics::Frame_FrameRadius) | ||||
768 | corners &= ~CornerTopLeft; | ||||
769 | if (tabBarRect.right() > rect.right() - Metrics::Frame_FrameRadius) | ||||
770 | corners &= ~CornerTopRight; | ||||
771 | break; | ||||
772 | | ||||
773 | case QTabBar::RoundedSouth: | ||||
774 | case QTabBar::TriangularSouth: | ||||
775 | if (isQtQuickControl) | ||||
776 | rect.adjust(-1, 0, 1, 1); | ||||
777 | if (tabBarSize.width() >= rect.width() - 2 * Metrics::Frame_FrameRadius) | ||||
778 | corners &= ~CornersBottom; | ||||
779 | if (tabBarRect.left() < rect.left() + Metrics::Frame_FrameRadius) | ||||
780 | corners &= ~CornerBottomLeft; | ||||
781 | if (tabBarRect.right() > rect.right() - Metrics::Frame_FrameRadius) | ||||
782 | corners &= ~CornerBottomRight; | ||||
783 | break; | ||||
784 | | ||||
785 | case QTabBar::RoundedWest: | ||||
786 | case QTabBar::TriangularWest: | ||||
787 | if (isQtQuickControl) | ||||
788 | rect.adjust(-1, 0, 0, 0); | ||||
789 | if (tabBarSize.height() >= rect.height() - 2 * Metrics::Frame_FrameRadius) | ||||
790 | corners &= ~CornersLeft; | ||||
791 | if (tabBarRect.top() < rect.top() + Metrics::Frame_FrameRadius) | ||||
792 | corners &= ~CornerTopLeft; | ||||
793 | if (tabBarRect.bottom() > rect.bottom() - Metrics::Frame_FrameRadius) | ||||
794 | corners &= ~CornerBottomLeft; | ||||
795 | break; | ||||
796 | | ||||
797 | case QTabBar::RoundedEast: | ||||
798 | case QTabBar::TriangularEast: | ||||
799 | if (isQtQuickControl) | ||||
800 | rect.adjust(0, 0, 1, 0); | ||||
801 | if (tabBarSize.height() >= rect.height() - 2 * Metrics::Frame_FrameRadius) | ||||
802 | corners &= ~CornersRight; | ||||
803 | if (tabBarRect.top() < rect.top() + Metrics::Frame_FrameRadius) | ||||
804 | corners &= ~CornerTopRight; | ||||
805 | if (tabBarRect.bottom() > rect.bottom() - Metrics::Frame_FrameRadius) | ||||
806 | corners &= ~CornerBottomRight; | ||||
807 | break; | ||||
808 | | ||||
809 | default: | ||||
810 | break; | ||||
811 | } | ||||
812 | | ||||
813 | // define colors | ||||
814 | const auto &palette(option->palette); | ||||
815 | const auto background(_helper->frameBackgroundColor(palette)); | ||||
816 | const auto outline(_helper->frameOutlineColor(palette)); | ||||
817 | _helper->renderTabWidgetFrame(painter, rect, background, outline, corners); | ||||
818 | | ||||
819 | return true; | ||||
820 | } | ||||
821 | | ||||
822 | //___________________________________________________________________________________ | ||||
823 | bool Style::drawFrameTabBarBasePrimitive(const QStyleOption *option, QPainter *painter, const QWidget *) const | ||||
824 | { | ||||
825 | // tabbar frame used either for 'separate' tabbar, or in 'document mode' | ||||
826 | | ||||
827 | // cast option and check | ||||
828 | const auto tabOption(qstyleoption_cast<const QStyleOptionTabBarBase *>(option)); | ||||
829 | if (!tabOption) | ||||
830 | return true; | ||||
831 | | ||||
832 | // get rect, orientation, palette | ||||
833 | const auto rect(option->rect); | ||||
834 | const auto outline(_helper->frameOutlineColor(option->palette)); | ||||
835 | | ||||
836 | // setup painter | ||||
837 | painter->setBrush(Qt::NoBrush); | ||||
838 | painter->setRenderHint(QPainter::Antialiasing, false); | ||||
839 | painter->setPen(QPen(outline, 1)); | ||||
840 | | ||||
841 | // render | ||||
842 | switch (tabOption->shape) { | ||||
843 | case QTabBar::RoundedNorth: | ||||
844 | case QTabBar::TriangularNorth: | ||||
845 | painter->drawLine(rect.bottomLeft() - QPoint(1, 0), rect.bottomRight() + QPoint(1, 0)); | ||||
846 | break; | ||||
847 | | ||||
848 | case QTabBar::RoundedSouth: | ||||
849 | case QTabBar::TriangularSouth: | ||||
850 | painter->drawLine(rect.topLeft() - QPoint(1, 0), rect.topRight() + QPoint(1, 0)); | ||||
851 | break; | ||||
852 | | ||||
853 | case QTabBar::RoundedWest: | ||||
854 | case QTabBar::TriangularWest: | ||||
855 | painter->drawLine(rect.topRight() - QPoint(0, 1), rect.bottomRight() + QPoint(1, 0)); | ||||
856 | break; | ||||
857 | | ||||
858 | case QTabBar::RoundedEast: | ||||
859 | case QTabBar::TriangularEast: | ||||
860 | painter->drawLine(rect.topLeft() - QPoint(0, 1), rect.bottomLeft() + QPoint(1, 0)); | ||||
861 | break; | ||||
862 | | ||||
863 | default: | ||||
864 | break; | ||||
865 | } | ||||
866 | | ||||
867 | return true; | ||||
868 | } | ||||
869 | | ||||
870 | //______________________________________________________________ | ||||
871 | bool Style::drawTabBarPanelButtonToolPrimitive(const QStyleOption *option, QPainter *painter, const QWidget *widget) const | ||||
872 | { | ||||
873 | // copy palette and rect | ||||
874 | auto rect(option->rect); | ||||
875 | | ||||
876 | // static_cast is safe here since check was already performed in calling function | ||||
877 | const QTabBar *tabBar(static_cast<QTabBar *>(widget->parentWidget())); | ||||
878 | | ||||
879 | // overlap. | ||||
880 | // subtract 1, because of the empty pixel left the tabwidget frame | ||||
881 | const int overlap(Metrics::TabBar_BaseOverlap - 1); | ||||
882 | | ||||
883 | // adjust rect based on tabbar shape | ||||
884 | switch (tabBar->shape()) { | ||||
885 | case QTabBar::RoundedNorth: | ||||
886 | case QTabBar::TriangularNorth: | ||||
887 | rect.adjust(0, 0, 0, -overlap); | ||||
888 | break; | ||||
889 | | ||||
890 | case QTabBar::RoundedSouth: | ||||
891 | case QTabBar::TriangularSouth: | ||||
892 | rect.adjust(0, overlap, 0, 0); | ||||
893 | break; | ||||
894 | | ||||
895 | case QTabBar::RoundedWest: | ||||
896 | case QTabBar::TriangularWest: | ||||
897 | rect.adjust(0, 0, -overlap, 0); | ||||
898 | break; | ||||
899 | | ||||
900 | case QTabBar::RoundedEast: | ||||
901 | case QTabBar::TriangularEast: | ||||
902 | rect.adjust(overlap, 0, 0, 0); | ||||
903 | break; | ||||
904 | | ||||
905 | default: | ||||
906 | break; | ||||
907 | } | ||||
908 | | ||||
909 | // get the relevant palette | ||||
910 | const QWidget *parent(tabBar->parentWidget()); | ||||
911 | if (qobject_cast<const QTabWidget *>(parent)) | ||||
912 | parent = parent->parentWidget(); | ||||
913 | const auto &palette(parent ? parent->palette() : QApplication::palette()); | ||||
914 | const auto color = hasAlteredBackground(parent) ? _helper->frameBackgroundColor(palette) : palette.color(QPalette::Window); | ||||
915 | | ||||
916 | // render flat background | ||||
917 | painter->setPen(Qt::NoPen); | ||||
918 | painter->setBrush(color); | ||||
919 | painter->drawRect(rect); | ||||
920 | | ||||
921 | return true; | ||||
922 | } | ||||
923 | | ||||
924 | //___________________________________________________________________________________ | ||||
925 | bool Style::drawIndicatorTabTearPrimitive(const QStyleOption *option, QPainter *painter, const QWidget *) const | ||||
926 | { | ||||
927 | // cast option and check | ||||
928 | const auto tabOption(qstyleoption_cast<const QStyleOptionTab *>(option)); | ||||
929 | if (!tabOption) | ||||
930 | return true; | ||||
931 | | ||||
932 | // store palette and rect | ||||
933 | const auto &palette(option->palette); | ||||
934 | auto rect(option->rect); | ||||
935 | | ||||
936 | const bool reverseLayout(option->direction == Qt::RightToLeft); | ||||
937 | | ||||
938 | const auto color(_helper->alphaColor(palette.color(QPalette::WindowText), 0.2)); | ||||
939 | painter->setRenderHint(QPainter::Antialiasing, false); | ||||
940 | painter->setPen(color); | ||||
941 | painter->setBrush(Qt::NoBrush); | ||||
942 | switch (tabOption->shape) { | ||||
943 | case QTabBar::TriangularNorth: | ||||
944 | case QTabBar::RoundedNorth: | ||||
945 | rect.adjust(0, 1, 0, 0); | ||||
946 | if (reverseLayout) | ||||
947 | painter->drawLine(rect.topRight(), rect.bottomRight()); | ||||
948 | else | ||||
949 | painter->drawLine(rect.topLeft(), rect.bottomLeft()); | ||||
950 | break; | ||||
951 | | ||||
952 | case QTabBar::TriangularSouth: | ||||
953 | case QTabBar::RoundedSouth: | ||||
954 | rect.adjust(0, 0, 0, -1); | ||||
955 | if (reverseLayout) | ||||
956 | painter->drawLine(rect.topRight(), rect.bottomRight()); | ||||
957 | else | ||||
958 | painter->drawLine(rect.topLeft(), rect.bottomLeft()); | ||||
959 | break; | ||||
960 | | ||||
961 | case QTabBar::TriangularWest: | ||||
962 | case QTabBar::RoundedWest: | ||||
963 | rect.adjust(1, 0, 0, 0); | ||||
964 | painter->drawLine(rect.topLeft(), rect.topRight()); | ||||
965 | break; | ||||
966 | | ||||
967 | case QTabBar::TriangularEast: | ||||
968 | case QTabBar::RoundedEast: | ||||
969 | rect.adjust(0, 0, -1, 0); | ||||
970 | painter->drawLine(rect.topLeft(), rect.topRight()); | ||||
971 | break; | ||||
972 | | ||||
973 | default: | ||||
974 | break; | ||||
975 | } | ||||
976 | | ||||
977 | return true; | ||||
978 | } | ||||
979 | | ||||
980 | //___________________________________________________________________________________ | ||||
981 | bool Style::drawIndicatorTabClosePrimitive(const QStyleOption *option, QPainter *painter, const QWidget *widget) const | ||||
982 | { | ||||
983 | // get icon and check | ||||
984 | QIcon icon(standardIcon(SP_TitleBarCloseButton, option, widget)); | ||||
985 | if (icon.isNull()) | ||||
986 | return false; | ||||
987 | | ||||
988 | // store state | ||||
989 | const State &state(option->state); | ||||
990 | const bool enabled(state & State_Enabled); | ||||
991 | const bool active(state & State_Raised); | ||||
992 | const bool sunken(state & State_Sunken); | ||||
993 | | ||||
994 | // decide icon mode and state | ||||
995 | QIcon::Mode iconMode; | ||||
996 | QIcon::State iconState; | ||||
997 | if (!enabled) { | ||||
998 | iconMode = QIcon::Disabled; | ||||
999 | iconState = QIcon::Off; | ||||
1000 | | ||||
1001 | } else { | ||||
1002 | if (active) | ||||
1003 | iconMode = QIcon::Active; | ||||
1004 | else | ||||
1005 | iconMode = QIcon::Normal; | ||||
1006 | | ||||
1007 | iconState = sunken ? QIcon::On : QIcon::Off; | ||||
1008 | } | ||||
1009 | | ||||
1010 | // icon size | ||||
1011 | const int iconWidth(pixelMetric(QStyle::PM_SmallIconSize, option, widget)); | ||||
1012 | const QSize iconSize(iconWidth, iconWidth); | ||||
1013 | | ||||
1014 | // get pixmap | ||||
1015 | const QPixmap pixmap(icon.pixmap(iconSize, iconMode, iconState)); | ||||
1016 | | ||||
1017 | // render | ||||
1018 | drawItemPixmap(painter, option->rect, Qt::AlignCenter, pixmap); | ||||
1019 | return true; | ||||
1020 | } | ||||
1021 | | ||||
1022 | } |