Make a branch to make krunner Good Enough For Aaron™.
[kdebase/uwolfer.git] / runtime / kstyles / oxygen / oxygen.cpp
blobdd7dd1d94872163625bb5a0eceb2d031c9423cbf
1 /* Oxygen widget style for KDE 4
2 Copyright (C) 2007-2008 Casper Boemann <cbr@boemann.dk>
3 Copyright (C) 2003-2005 Sandro Giessl <sandro@giessl.com>
4 Copyright (C) 2001-2002 Chris Lee <clee@kde.org>
5 Copyright (C) 2001-2002 Carsten Pfeiffer <pfeiffer@kde.org>
6 Copyright (C) 2001-2002 Karol Szwed <gallium@kde.org>
7 Copyright (c) 2002 Malte Starostik <malte@kde.org>
8 Copyright (C) 2002,2003 Maksim Orlovich <mo002j@mail.rochester.edu>
9 Copyright (C) 2001-2002 Karol Szwed <gallium@kde.org>
10 Copyright (C) 2001-2002 Fredrik Höglund <fredrik@kde.org>
11 Copyright (C) 2000 Daniel M. Duley <mosfet@kde.org>
12 Copyright (C) 2000 Dirk Mueller <mueller@kde.org>
13 Copyright (C) 2001 Martijn Klingens <klingens@kde.org>
15 This library is free software; you can redistribute it and/or
16 modify it under the terms of the GNU Library General Public
17 License version 2 as published by the Free Software Foundation.
19 This library is distributed in the hope that it will be useful,
20 but WITHOUT ANY WARRANTY; without even the implied warranty of
21 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
22 Library General Public License for more details.
24 You should have received a copy of the GNU Library General Public License
25 along with this library; see the file COPYING.LIB. If not, write to
26 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
27 Boston, MA 02110-1301, USA.
30 #include "oxygen.h"
31 #include "oxygen.moc"
33 #include <QtGui/QPainter>
34 #include <QtCore/QTimer>
35 #include <QtCore/QEvent>
36 #include <QtCore/QSettings>
37 #include <QtGui/QStyleOption>
38 #include <QtGui/QApplication>
40 #include <QtGui/QCheckBox>
41 #include <QtGui/QComboBox>
42 #include <QtGui/QMenuBar>
43 #include <QtGui/QProgressBar>
44 #include <QtGui/QPushButton>
45 #include <QtGui/QRadioButton>
46 #include <QtGui/QToolButton>
47 #include <QtGui/QToolBar>
48 #include <QtGui/QToolBox>
49 #include <QtGui/QScrollBar>
50 #include <QtGui/QGroupBox>
51 #include <QtGui/QLineEdit>
52 #include <QtGui/QDockWidget>
53 #include <QStyleOptionDockWidget>
54 #include <QPaintEvent>
55 #include <QToolBox>
56 #include <QAbstractScrollArea>
57 #include <QAbstractItemView>
59 #include <QtDBus/QtDBus>
61 #include <KGlobal>
62 #include <KGlobalSettings>
63 #include <KConfigGroup>
64 #include <KColorUtils>
65 #include <kdebug.h>
67 #include <math.h>
69 #include "helper.h"
70 #include "tileset.h"
72 // We need better holes! Bevel color and shadow color are currently based on
73 // only one color, even though they are different things; also, we don't really
74 // know what bevel color should be based on... (and shadow color for white
75 // views looks rather bad). For now at least, just using QPalette::Window
76 // everywhere seems best...
77 #define HOLE_COLOR_OUTSIDE
79 K_EXPORT_STYLE("Oxygen", OxygenStyle)
81 K_GLOBAL_STATIC_WITH_ARGS(OxygenStyleHelper, globalHelper, ("oxygen"))
83 OxygenStyle::OxygenStyle() :
84 KStyle(),
85 // kickerMode(false),
86 // kornMode(false),
87 flatMode(false),
88 _helper(*globalHelper)
90 _config = _helper.config();
92 // connect to KGlobalSettings signals so we will be notified when the
93 // system palette (in particular, the contrast) is changed
94 QDBusConnection::sessionBus().connect( QString(), "/KGlobalSettings",
95 "org.kde.KGlobalSettings",
96 "notifyChange", this,
97 SLOT(globalSettingsChange(int,int))
100 // call the slot directly; this initial call will set up things that also
101 // need to be reset when the system palette changes
102 globalSettingsChange(KGlobalSettings::PaletteChanged, 0);
104 setWidgetLayoutProp(WT_Generic, Generic::DefaultFrameWidth, 2);
106 // TODO: change this when double buttons are implemented
107 setWidgetLayoutProp(WT_ScrollBar, ScrollBar::DoubleBotButton, true);
108 setWidgetLayoutProp(WT_ScrollBar, ScrollBar::MinimumSliderHeight, 21);
109 setWidgetLayoutProp(WT_ScrollBar, ScrollBar::BarWidth, 15); // size*2+1
110 setWidgetLayoutProp(WT_ScrollBar, ScrollBar::ArrowColor,QPalette::ButtonText);
111 setWidgetLayoutProp(WT_ScrollBar, ScrollBar::ActiveArrowColor,QPalette::ButtonText);
112 setWidgetLayoutProp(WT_ScrollBar, ScrollBar::SingleButtonHeight, 14);
113 setWidgetLayoutProp(WT_ScrollBar, ScrollBar::DoubleButtonHeight, 28);
115 setWidgetLayoutProp(WT_PushButton, PushButton::DefaultIndicatorMargin, 0);
116 setWidgetLayoutProp(WT_PushButton, PushButton::ContentsMargin + Left, 16);
117 setWidgetLayoutProp(WT_PushButton, PushButton::ContentsMargin + Right, 16);
118 setWidgetLayoutProp(WT_PushButton, PushButton::ContentsMargin + Top, 1);
119 setWidgetLayoutProp(WT_PushButton, PushButton::ContentsMargin + Bot, 0);
120 setWidgetLayoutProp(WT_PushButton, PushButton::FocusMargin, 0);
121 setWidgetLayoutProp(WT_PushButton, PushButton::FocusMargin + Left, 0);
122 setWidgetLayoutProp(WT_PushButton, PushButton::FocusMargin + Right, 0);
123 setWidgetLayoutProp(WT_PushButton, PushButton::FocusMargin + Top, 0);
124 setWidgetLayoutProp(WT_PushButton, PushButton::FocusMargin + Bot, 0);
125 setWidgetLayoutProp(WT_PushButton, PushButton::PressedShiftHorizontal, 0);
126 setWidgetLayoutProp(WT_PushButton, PushButton::PressedShiftVertical, 0);
128 setWidgetLayoutProp(WT_Splitter, Splitter::Width, 6);
130 setWidgetLayoutProp(WT_CheckBox, CheckBox::Size, 23);
131 setWidgetLayoutProp(WT_CheckBox, CheckBox::BoxTextSpace, 4);
132 setWidgetLayoutProp(WT_RadioButton, RadioButton::Size, 25);
133 setWidgetLayoutProp(WT_RadioButton, RadioButton::BoxTextSpace, 4);
135 setWidgetLayoutProp(WT_DockWidget, DockWidget::TitleTextColor, QPalette::WindowText);
136 setWidgetLayoutProp(WT_DockWidget, DockWidget::FrameWidth, 0);
137 setWidgetLayoutProp(WT_DockWidget, DockWidget::TitleMargin, 2);
139 setWidgetLayoutProp(WT_Menu, Menu::FrameWidth, 5);
140 setWidgetLayoutProp(WT_Menu, Menu::Margin, 4);
142 setWidgetLayoutProp(WT_MenuBar, MenuBar::ItemSpacing, 0);
143 setWidgetLayoutProp(WT_MenuBar, MenuBar::Margin, 0);
144 setWidgetLayoutProp(WT_MenuBar, MenuBar::Margin + Left, 0);
145 setWidgetLayoutProp(WT_MenuBar, MenuBar::Margin + Right, 0);
146 setWidgetLayoutProp(WT_MenuBar, MenuBar::Margin + Top, 0);
147 setWidgetLayoutProp(WT_MenuBar, MenuBar::Margin + Bot, 2);
149 setWidgetLayoutProp(WT_MenuBarItem, MenuBarItem::Margin, 3);
150 setWidgetLayoutProp(WT_MenuBarItem, MenuBarItem::Margin+Left, 5);
151 setWidgetLayoutProp(WT_MenuBarItem, MenuBarItem::Margin+Right, 5);
153 setWidgetLayoutProp(WT_MenuItem, MenuItem::CheckAlongsideIcon, 1);
154 setWidgetLayoutProp(WT_MenuItem, MenuItem::CheckWidth, 16);
155 setWidgetLayoutProp(WT_MenuItem, MenuItem::MinHeight, 20);
157 setWidgetLayoutProp(WT_ProgressBar, ProgressBar::BusyIndicatorSize, 10);
159 setWidgetLayoutProp(WT_TabBar, TabBar::TabOverlap, 0);
160 setWidgetLayoutProp(WT_TabBar, TabBar::BaseOverlap, 7);
161 setWidgetLayoutProp(WT_TabBar, TabBar::TabContentsMargin, 6);
162 setWidgetLayoutProp(WT_TabBar, TabBar::TabFocusMargin, 0);
163 setWidgetLayoutProp(WT_TabBar, TabBar::TabContentsMargin + Left, 5);
164 setWidgetLayoutProp(WT_TabBar, TabBar::TabContentsMargin + Right, 5);
165 setWidgetLayoutProp(WT_TabBar, TabBar::TabContentsMargin + Top, 2);
166 setWidgetLayoutProp(WT_TabBar, TabBar::TabContentsMargin + Bot, 2);
167 setWidgetLayoutProp(WT_TabBar, TabBar::ScrollButtonWidth, 18);
169 setWidgetLayoutProp(WT_TabWidget, TabWidget::ContentsMargin, 6);
171 setWidgetLayoutProp(WT_Slider, Slider::HandleThickness, 25);
172 setWidgetLayoutProp(WT_Slider, Slider::HandleLength, 19);
174 setWidgetLayoutProp(WT_SpinBox, SpinBox::FrameWidth, 6);
175 setWidgetLayoutProp(WT_SpinBox, SpinBox::ContentsMargin + Left, 3);
176 setWidgetLayoutProp(WT_SpinBox, SpinBox::ContentsMargin + Top, -2);
177 setWidgetLayoutProp(WT_SpinBox, SpinBox::ContentsMargin + Bot, -1);
178 setWidgetLayoutProp(WT_SpinBox, SpinBox::ButtonWidth, 19);
179 setWidgetLayoutProp(WT_SpinBox, SpinBox::ButtonSpacing, 0);
180 setWidgetLayoutProp(WT_SpinBox, SpinBox::ButtonMargin+Left, 2);
181 setWidgetLayoutProp(WT_SpinBox, SpinBox::ButtonMargin+Right, 9);
182 setWidgetLayoutProp(WT_SpinBox, SpinBox::ButtonMargin+Top, 5);
183 setWidgetLayoutProp(WT_SpinBox, SpinBox::ButtonMargin+Bot, 4);
185 setWidgetLayoutProp(WT_ComboBox, ComboBox::FrameWidth, 6);
186 setWidgetLayoutProp(WT_ComboBox, ComboBox::ContentsMargin + Left, 3);
187 setWidgetLayoutProp(WT_ComboBox, ComboBox::ContentsMargin + Top, -1);
188 setWidgetLayoutProp(WT_ComboBox, ComboBox::ContentsMargin + Bot, -1);
189 setWidgetLayoutProp(WT_ComboBox, ComboBox::ButtonWidth, 19);
190 setWidgetLayoutProp(WT_ComboBox, ComboBox::ButtonMargin, 0);
191 setWidgetLayoutProp(WT_ComboBox, ComboBox::ButtonMargin+Left, 2);
192 setWidgetLayoutProp(WT_ComboBox, ComboBox::ButtonMargin+Right, 9);
193 setWidgetLayoutProp(WT_ComboBox, ComboBox::ButtonMargin+Top, 6);
194 setWidgetLayoutProp(WT_ComboBox, ComboBox::ButtonMargin+Bot, 3);
195 setWidgetLayoutProp(WT_ComboBox, ComboBox::FocusMargin, 0);
197 setWidgetLayoutProp(WT_ToolBar, ToolBar::FrameWidth, 0);
198 setWidgetLayoutProp(WT_ToolBar, ToolBar::ItemSpacing, 1);
199 setWidgetLayoutProp(WT_ToolBar, ToolBar::ItemMargin, 2);
201 setWidgetLayoutProp(WT_ToolButton, ToolButton::ContentsMargin, 4);
202 setWidgetLayoutProp(WT_ToolButton, ToolButton::FocusMargin, 0);
204 setWidgetLayoutProp(WT_GroupBox, GroupBox::FrameWidth, 5);
206 setWidgetLayoutProp(WT_ToolBoxTab, ToolBoxTab::Margin, 5);
208 KConfigGroup cfg(_config, "Style");
209 switch (cfg.readEntry("MenuHighlight", (int)MM_DARK)) {
210 case MM_STRONG:
211 _menuHighlightMode = MM_STRONG;
212 break;
213 case MM_SUBTLE:
214 _menuHighlightMode = MM_SUBTLE;
215 break;
216 default:
217 _menuHighlightMode = MM_DARK;
219 _checkCheck = (cfg.readEntry("CheckStyle", 0) == 0);
220 _animateProgressBar = cfg.readEntry("AnimateProgressBar", false);
221 _drawToolBarItemSeparator = cfg.readEntry("DrawToolBarItemSeparator", true);
222 _drawTriangularExpander = cfg.readEntry("DrawTriangularExpander", false);
224 if ( _animateProgressBar )
226 animationTimer = new QTimer( this );
227 connect( animationTimer, SIGNAL(timeout()), this, SLOT(updateProgressPos()) );
233 void OxygenStyle::updateProgressPos()
235 QProgressBar* pb;
236 //Update the registered progressbars.
237 QMap<QWidget*, int>::iterator iter;
238 bool visible = false;
239 for (iter = progAnimWidgets.begin(); iter != progAnimWidgets.end(); ++iter)
241 pb = dynamic_cast<QProgressBar*>(iter.key());
243 if ( !pb )
244 continue;
246 if ( iter.key() -> isEnabled() &&
247 pb->value() != pb->maximum() )
249 // update animation Offset of the current Widget
250 //iter.value() = (iter.value() + 1) % 32;
251 // dont' update right now iter.key()->update();
253 if (iter.key()->isVisible())
254 visible = true;
256 if (!visible)
257 animationTimer->stop();
261 OxygenStyle::~OxygenStyle()
264 void OxygenStyle::drawComplexControl(ComplexControl control,const QStyleOptionComplex *option, QPainter *painter, const QWidget *widget) const
266 switch (control)
268 case CC_GroupBox:
270 if (const QStyleOptionGroupBox *groupBox = qstyleoption_cast<const QStyleOptionGroupBox *>(option))
272 bool isFlat = groupBox->features & QStyleOptionFrameV2::Flat;
274 if (isFlat)
276 QFont font = painter->font();
277 font.setBold(true);
278 painter->setFont(font);
282 break;
283 default:
284 break;
287 return KStyle::drawComplexControl(control,option,painter,widget);
290 void OxygenStyle::drawControl(ControlElement element, const QStyleOption *option, QPainter *p, const QWidget *widget) const
292 switch (element)
294 case CE_RubberBand:
296 if (const QStyleOptionRubberBand *rbOpt = qstyleoption_cast<const QStyleOptionRubberBand *>(option))
298 p->save();
299 QColor color = rbOpt->palette.color(QPalette::Highlight);
300 color.setAlpha(50);
301 p->setBrush(color);
302 color = KColorUtils::mix(color, rbOpt->palette.color(QPalette::Active, QPalette::WindowText));
303 p->setPen(color);
304 p->setClipRegion(rbOpt->rect);
305 p->drawRect(rbOpt->rect.adjusted(0,0,-1,-1));
306 p->restore();
308 break;
310 default:
311 KStyle::drawControl(element, option, p, widget);
315 void OxygenStyle::drawKStylePrimitive(WidgetType widgetType, int primitive,
316 const QStyleOption* opt,
317 const QRect &r, const QPalette &pal,
318 State flags, QPainter* p,
319 const QWidget* widget,
320 KStyle::Option* kOpt) const
322 StyleOptions opts = 0;
323 const bool reverseLayout = opt->direction == Qt::RightToLeft;
325 const bool enabled = flags & State_Enabled;
326 const bool mouseOver(enabled && (flags & State_MouseOver));
328 switch (widgetType)
330 case WT_PushButton:
332 switch (primitive)
334 case PushButton::Panel:
336 if ((flags & State_On) || (flags & State_Sunken))
337 opts |= Sunken;
338 if (flags & State_HasFocus)
339 opts |= Focus;
340 if (enabled && (flags & State_MouseOver))
341 opts |= Hover;
343 renderSlab(p, r, pal.color(QPalette::Button), opts);
344 return;
347 case PushButton::DefaultButtonFrame:
349 return;
353 break;
355 case WT_ToolBoxTab:
357 switch (primitive)
359 case ToolBoxTab::Panel:
361 const QStyleOptionToolBox *option = qstyleoption_cast<const QStyleOptionToolBox *>(opt);
362 if(!(option && widget)) return;
364 const QStyleOptionToolBoxV2 *v2 = qstyleoption_cast<const QStyleOptionToolBoxV2 *>(opt);
366 p->save();
367 if (v2 && v2->position == QStyleOptionToolBoxV2::Beginning)
369 p->restore();
370 return;
373 QColor color = widget->palette().color(QPalette::Window); // option returns a wrong color
374 QColor light = _helper.calcLightColor(color);
375 QColor dark = _helper.calcDarkColor(color);
377 QPainterPath path;
378 int y = r.height()*15/100;
379 if (reverseLayout) {
380 path.moveTo(r.left()+52, r.top());
381 path.cubicTo(QPointF(r.left()+50-8, r.top()), QPointF(r.left()+50-10, r.top()+y), QPointF(r.left()+50-10, r.top()+y));
382 path.lineTo(r.left()+18+9, r.bottom()-y);
383 path.cubicTo(QPointF(r.left()+18+9, r.bottom()-y), QPointF(r.left()+19+6, r.bottom()-1-0.3), QPointF(r.left()+19, r.bottom()-1-0.3));
384 } else {
385 path.moveTo(r.right()-52, r.top());
386 path.cubicTo(QPointF(r.right()-50+8, r.top()), QPointF(r.right()-50+10, r.top()+y), QPointF(r.right()-50+10, r.top()+y));
387 path.lineTo(r.right()-18-9, r.bottom()-y);
388 path.cubicTo(QPointF(r.right()-18-9, r.bottom()-y), QPointF(r.right()-19-6, r.bottom()-1-0.3), QPointF(r.right()-19, r.bottom()-1-0.3));
391 p->setRenderHint(QPainter::Antialiasing, true);
392 p->translate(0,1);
393 p->setPen(light);
394 p->drawPath(path);
395 p->translate(0,-1);
396 p->setPen(dark);
397 p->drawPath(path);
399 p->setRenderHint(QPainter::Antialiasing, false);
400 if (reverseLayout) {
401 p->drawLine(r.left()+50-1, r.top(), r.right(), r.top());
402 p->drawLine(r.left()+20, r.bottom()-2, r.left(), r.bottom()-2);
403 p->setPen(light);
404 p->drawLine(r.left()+50, r.top()+1, r.right(), r.top()+1);
405 p->drawLine(r.left()+20, r.bottom()-1, r.left(), r.bottom()-1);
406 } else {
407 p->drawLine(r.left(), r.top(), r.right()-50+1, r.top());
408 p->drawLine(r.right()-20, r.bottom()-2, r.right(), r.bottom()-2);
409 p->setPen(light);
410 p->drawLine(r.left(), r.top()+1, r.right()-50, r.top()+1);
411 p->drawLine(r.right()-20, r.bottom()-1, r.right(), r.bottom()-1);
414 p->restore();
415 return;
419 break;
421 case WT_ProgressBar:
423 // const Q3ProgressBar *pb = dynamic_cast<const Q3ProgressBar*>(widget);
424 // int steps = pb->totalSteps();
426 QColor bg = enabled?pal.color(QPalette::Base):pal.color(QPalette::Background); // background
427 QColor fg = enabled?pal.color(QPalette::Highlight):pal.color(QPalette::Background).dark(110); // foreground
430 switch (primitive)
432 case ProgressBar::Groove:
434 QColor color = pal.color(QPalette::Button);
435 QRect rect = r.adjusted(2,0,-2,0);
437 TileSet *tiles1 = _helper.horizontalScrollBar(color, rect.height(), r.width());
439 p->save();
440 p->setClipRect(rect.adjusted(-32,0,32,0));
441 tiles1->render(rect, p, TileSet::Left | TileSet::Vertical | TileSet::Right);
442 p->restore();
443 return;
446 case ProgressBar::BusyIndicator:
448 QColor color = _viewHoverBrush.brush(pal).color();
449 QRect rect = r.adjusted(0,-2,0,2);
451 TileSet *tiles1 = _helper.horizontalScrollBar(color, rect.height(), r.width());
453 p->save();
454 p->setClipRect(rect.adjusted(-32,0,32,0));
455 tiles1->render(rect, p, TileSet::Left | TileSet::Vertical | TileSet::Right);
456 p->restore();
457 return;
460 case ProgressBar::Indicator:
462 QColor color = _viewHoverBrush.brush(pal).color();
463 QRect rect = r.adjusted(0,-2,2+r.width() / 300,2); // right pos: hackish, but necessary...
465 int animShift = 0;
466 if (_animateProgressBar) {
467 // find the animation Offset for the current Widget
468 QWidget* nonConstWidget = const_cast<QWidget*>(widget);
469 QMap<QWidget*, int>::const_iterator iter = progAnimWidgets.find(nonConstWidget);
470 if (iter != progAnimWidgets.end())
471 animShift = iter.value();
473 TileSet *tiles1 = _helper.horizontalScrollBar(color, rect.height(), r.width()-animShift);
475 p->save();
476 //p->setClipRect(rect.adjusted(-32,0,32,0));
477 /* HACK - make progress bars with a few percent progress look less broken. */
478 p->setClipRect(rect.adjusted(1,0,0,0));
479 tiles1->render(rect, p, TileSet::Left | TileSet::Vertical | TileSet::Right);
480 p->restore();
481 return;
485 break;
487 case WT_MenuBar:
489 switch (primitive)
491 case MenuBar::EmptyArea:
493 return;
497 break;
499 case WT_MenuBarItem:
501 switch (primitive)
503 case MenuBarItem::Panel:
505 bool active = flags & State_Selected;
507 if (active) {
508 QColor color = pal.color(QPalette::Window);
509 if (_menuHighlightMode != MM_DARK) {
510 if(flags & State_Sunken) {
511 if (_menuHighlightMode == MM_STRONG)
512 color = pal.color(QPalette::Highlight);
513 else
514 color = KColorUtils::mix(color, KColorUtils::tint(color, pal.color(QPalette::Highlight), 0.6));
516 else {
517 if (_menuHighlightMode == MM_STRONG)
518 color = KColorUtils::tint(color, _viewHoverBrush.brush(pal).color());
519 else
520 color = KColorUtils::mix(color, KColorUtils::tint(color, _viewHoverBrush.brush(pal).color()));
523 else {
524 color = _helper.calcMidColor(color);
527 _helper.holeFlat(color, 0.0)->render(r.adjusted(2,2,-2,-2), p, TileSet::Full);
530 return;
533 case Generic::Text:
535 KStyle::TextOption* textOpts = extractOption<KStyle::TextOption*>(kOpt);
537 QPen old = p->pen();
538 if (_menuHighlightMode == MM_STRONG && flags & State_Sunken)
539 p->setPen(pal.color(QPalette::HighlightedText));
540 else
541 p->setPen(pal.color(QPalette::WindowText));
542 drawItemText(p, r, Qt::AlignVCenter | Qt::TextShowMnemonic | textOpts->hAlign, pal, flags & State_Enabled,
543 textOpts->text);
544 p->setPen(old);
546 return;
550 break;
552 case WT_Menu:
554 switch (primitive)
556 case Generic::Frame:
558 _helper.drawFloatFrame(p, r, pal.window().color());
559 return;
562 case Menu::Background:
564 // we paint in the eventFilter instead so we can paint in the border too
565 return;
568 case Menu::TearOff:
570 // TODO: See Keramik...
572 return;
575 case Menu::Scroller:
577 // TODO
578 return;
582 break;
584 case WT_MenuItem:
586 switch (primitive)
588 case MenuItem::Separator:
590 QColor color = pal.color(QPalette::Window);
591 QColor light = _helper.calcLightColor(color);
592 QColor dark = _helper.calcDarkColor(color);
593 dark.setAlpha(120);
594 p->setRenderHint(QPainter::Antialiasing);
596 QLinearGradient lg(r.x(),0,r.right(),0);
597 lg.setColorAt(0.5, dark);
598 dark.setAlpha(0);
599 lg.setColorAt(0.0, dark);
600 lg.setColorAt(1.0, dark);
601 p->setPen(QPen(lg,1));
603 p->drawLine(QPointF(r.x(), r.y()+0.5),
604 QPointF(r.right(), r.y()+0.5));
606 lg = QLinearGradient(r.x(), 0, r.right(),0);
607 lg.setColorAt(0.5, light);
608 light.setAlpha(0);
609 lg.setColorAt(0.0, light);
610 lg.setColorAt(1.0, light);
611 p->setPen(QPen(lg,1));
613 p->drawLine(QPointF(r.x(), r.y()+1.5),
614 QPointF(r.right(), r.y()+1.5));
615 return;
618 case MenuItem::ItemIndicator:
620 if (enabled) {
621 QPixmap pm(r.size());
622 pm.fill(Qt::transparent);
623 QPainter pp(&pm);
624 QRect rr(QPoint(0,0), r.size());
626 QColor color = pal.color(QPalette::Window);
627 if (_menuHighlightMode == MM_STRONG)
628 color = pal.color(QPalette::Highlight);
629 else if (_menuHighlightMode == MM_SUBTLE)
630 color = KColorUtils::mix(color, KColorUtils::tint(color, pal.color(QPalette::Highlight), 0.6));
631 else
632 color = _helper.calcMidColor(color);
633 pp.setRenderHint(QPainter::Antialiasing);
634 pp.setPen(Qt::NoPen);
636 pp.setBrush(color);
637 _helper.fillHole(pp, rr);
639 _helper.holeFlat(color, 0.0)->render(rr.adjusted(2,2,-2,-2), &pp);
641 QRect maskr(rr.width()-40, 0, 40,rr.height());
642 QLinearGradient gradient(maskr.left(), 0, maskr.right()-4, 0);
643 gradient.setColorAt(0.0, QColor(0,0,0,255));
644 gradient.setColorAt(1.0, QColor(0,0,0,0));
645 pp.setBrush(gradient);
646 pp.setCompositionMode(QPainter::CompositionMode_DestinationIn);
647 pp.drawRect(maskr);
649 p->drawPixmap(r, pm);
651 else {
652 drawKStylePrimitive(WT_Generic, Generic::FocusIndicator, opt, r, pal, flags, p, widget, kOpt);
655 return;
658 case Generic::Text:
660 KStyle::TextOption* textOpts = extractOption<KStyle::TextOption*>(kOpt);
662 QPen old = p->pen();
663 if (_menuHighlightMode == MM_STRONG && flags & State_Selected)
664 p->setPen(pal.color(QPalette::HighlightedText));
665 else
666 p->setPen(pal.color(QPalette::WindowText));
667 drawItemText(p, r, Qt::AlignVCenter | Qt::TextShowMnemonic | textOpts->hAlign, pal, flags & State_Enabled,
668 textOpts->text);
669 p->setPen(old);
671 return;
674 case Generic::ArrowRight:
675 case Generic::ArrowLeft:
677 // always draw in window text color due to fade-out
678 extractOption<KStyle::ColorOption*>(kOpt)->color = QPalette::WindowText;
679 // fall through to lower handler
680 break;
683 case MenuItem::CheckColumn:
685 // empty
686 return;
689 case MenuItem::CheckOn:
691 renderCheckBox(p, r.adjusted(2,-2,2,2), pal, enabled, false, mouseOver, CheckBox::CheckOn, true);
692 return;
695 case MenuItem::CheckOff:
697 renderCheckBox(p, r.adjusted(2,-2,2,2), pal, enabled, false, mouseOver, CheckBox::CheckOff, true);
698 return;
701 case MenuItem::RadioOn:
703 renderRadioButton(p, r, pal, enabled, mouseOver, RadioButton::RadioOn, true);
704 return;
707 case MenuItem::RadioOff:
709 renderRadioButton(p, r, pal, enabled, mouseOver, RadioButton::RadioOff, true);
710 return;
713 case MenuItem::CheckIcon:
715 // TODO
716 return;
720 break;
722 case WT_DockWidget:
724 switch (primitive)
726 case Generic::Text:
728 const QStyleOptionDockWidget* dwOpt = ::qstyleoption_cast<const QStyleOptionDockWidget*>(opt);
729 if (!dwOpt) return;
730 const QStyleOptionDockWidgetV2 *v2 = qstyleoption_cast<const QStyleOptionDockWidgetV2*>(opt);
731 bool verticalTitleBar = v2 ? v2->verticalTitleBar : false;
733 QRect btnr = subElementRect(dwOpt->floatable ? SE_DockWidgetFloatButton : SE_DockWidgetCloseButton, opt, widget);
734 int fw = widgetLayoutProp(WT_DockWidget, DockWidget::TitleMargin, opt, widget);
735 QRect r = dwOpt->rect.adjusted(fw, fw, -fw, -fw);
736 if (verticalTitleBar)
737 r.setY(btnr.y()+btnr.height());
738 else if(reverseLayout)
740 r.setLeft(btnr.x()+btnr.width());
741 r.adjust(0,0,-4,0);
743 else
745 r.setRight(btnr.x());
746 r.adjust(4,0,0,0);
749 QString title = dwOpt->title;
750 QString tmpTitle = title;
751 if(tmpTitle.contains("&"))
753 int pos = tmpTitle.indexOf("&");
754 if(!(tmpTitle.size()-1 > pos && tmpTitle.at(pos+1) == QChar('&')))
755 tmpTitle.remove(pos, 1);
757 int tw = dwOpt->fontMetrics.width(tmpTitle);
758 int th = dwOpt->fontMetrics.height();
759 int width = verticalTitleBar ? r.height() : r.width();
760 if (width < tw)
761 title = dwOpt->fontMetrics.elidedText(title, Qt::ElideRight, width, Qt::TextShowMnemonic);
763 if (verticalTitleBar)
765 QRect br(dwOpt->fontMetrics.boundingRect(title));
766 QImage textImage(br.size(), QImage::Format_ARGB32_Premultiplied);
767 textImage.fill(0x00000000);
768 QPainter painter(&textImage);
769 drawItemText(&painter, QRect(0, 0, br.width(), br.height()), Qt::AlignLeft|Qt::AlignTop|Qt::TextShowMnemonic, dwOpt->palette, dwOpt->state & State_Enabled, title, QPalette::WindowText);
770 painter.end();
771 textImage = textImage.transformed(QMatrix().rotate(-90));
773 p->drawPixmap(r.x()+(r.width()-th)/2, r.y()+r.height()-textImage.height(), QPixmap::fromImage(textImage));
775 else
777 drawItemText(p, r, (reverseLayout ? Qt::AlignRight : Qt::AlignLeft) | Qt::AlignVCenter
778 | Qt::TextShowMnemonic, dwOpt->palette, dwOpt->state & State_Enabled, title,
779 QPalette::WindowText);
781 return;
783 case Generic::Frame:
785 // Don't do anything here as it interferes with custom titlewidgets
786 return;
789 case DockWidget::TitlePanel:
791 // The frame is draw in the eventfilter
792 // This is because when a dockwidget has a titlebarwidget, then we can not
793 // paint on the dockwidget prober here
794 return;
797 case DockWidget::SeparatorHandle:
798 if (flags&State_Horizontal)
799 drawKStylePrimitive(WT_Splitter, Splitter::HandleVert, opt, r, pal, flags, p, widget);
800 else
801 drawKStylePrimitive(WT_Splitter, Splitter::HandleHor, opt, r, pal, flags, p, widget);
802 return;
805 break;
807 case WT_StatusBar:
809 switch (primitive)
811 case Generic::Frame:
813 return;
817 break;
819 case WT_CheckBox:
821 switch(primitive)
823 case CheckBox::CheckOn:
824 case CheckBox::CheckOff:
825 case CheckBox::CheckTriState:
827 bool hasFocus = flags & State_HasFocus;
829 renderCheckBox(p, r, pal, enabled, hasFocus, mouseOver, primitive);
830 return;
834 break;
836 case WT_RadioButton:
838 switch(primitive)
840 case RadioButton::RadioOn:
841 case RadioButton::RadioOff:
843 renderRadioButton(p, r, pal, enabled, mouseOver, primitive);
844 return;
849 break;
851 case WT_ScrollBar:
853 switch (primitive)
855 case ScrollBar::DoubleButtonHor:
856 renderHole(p, pal.color(QPalette::Window), QRect(r.left()-5, 0, 5, r.height()),
857 false, false, TileSet::Top | TileSet::Bottom | TileSet::Right);
858 break;
860 case ScrollBar::DoubleButtonVert:
861 renderHole(p, pal.color(QPalette::Window), QRect(0, r.top()-5, r.width(), 5),
862 false, false, TileSet::Left | TileSet::Bottom | TileSet::Right);
863 break;
865 case ScrollBar::SingleButtonHor:
866 renderHole(p, pal.color(QPalette::Window), QRect(r.right()+3, 0, 5, r.height()),
867 false, false, TileSet::Top | TileSet::Left | TileSet::Bottom);
868 break;
870 case ScrollBar::SingleButtonVert:
871 renderHole(p, pal.color(QPalette::Window), QRect(0, r.bottom()+3, r.width(), 5),
872 false, false, TileSet::Top | TileSet::Left | TileSet::Right);
873 break;
875 case ScrollBar::GrooveAreaVertTop:
877 renderHole(p, pal.color(QPalette::Window), r.adjusted(0,2,0,12),
878 false, false, TileSet::Left | TileSet::Right);
879 return;
882 case ScrollBar::GrooveAreaVertBottom:
884 renderHole(p, pal.color(QPalette::Window), r.adjusted(0,-10,0,0), false, false,
885 TileSet::Left | TileSet::Right);
886 return;
889 case ScrollBar::GrooveAreaHorLeft:
891 renderHole(p, pal.color(QPalette::Window), r.adjusted(2,0,12,0), false, false,
892 TileSet::Top | TileSet::Bottom);
893 return;
896 case ScrollBar::GrooveAreaHorRight:
898 renderHole(p, pal.color(QPalette::Window), r.adjusted(-10,0,0,0), false, false,
899 TileSet::Top | TileSet::Bottom);
900 return;
903 case ScrollBar::SliderVert:
905 QColor color = pal.color(QPalette::Button);
906 if (mouseOver || (flags & State_Sunken)) // TODO not when disabled ((flags & State_Enabled) doesn't work?)
907 color = _viewHoverBrush.brush(pal).color();
908 QRect rect = r.adjusted(1,3,-1,0);
910 renderHole(p, pal.color(QPalette::Window), rect.adjusted(-1,-1,1,0), false, false,
911 TileSet::Left | TileSet::Right);
913 int offset = rect.top()/2; // divide by 2 to make the "lightplay" move half speed of the handle
914 int remainder = qMin(12, rect.height()/2);
916 // Draw the handle in two parts, the top, and the bottom with calculated offset
917 TileSet *tiles1 = _helper.verticalScrollBar(color, rect.width(), offset);
918 TileSet *tiles2 = _helper.verticalScrollBar(color, rect.width(), offset+rect.height()+8);
920 p->save();
921 p->setClipRect(rect.adjusted(0,0,0,-remainder-1));
922 tiles1->render(rect, p, TileSet::Top | TileSet::Horizontal);
923 p->setClipRect( QRect(rect.left(), rect.bottom()-remainder, rect.width(), remainder));
924 tiles2->render( QRect(rect.left(), rect.bottom()-32, rect.width(),32),
925 p, TileSet::Bottom | TileSet::Horizontal);
926 p->restore();
927 return;
930 case ScrollBar::SliderHor:
932 QColor color = pal.color(QPalette::Button);
933 if (mouseOver || (flags & State_Sunken)) // TODO not when disabled ((flags & State_Enabled) doesn't work?)
934 color = _viewHoverBrush.brush(pal).color();
935 QRect rect = r.adjusted(3,1,0,-1);
937 renderHole(p, pal.color(QPalette::Window), rect.adjusted(-1,-1,0,1), false, false,
938 TileSet::Top | TileSet::Bottom);
940 int offset = r.left()/2; // divide by 2 to make the "lightplay" move half speed of the handle
941 int remainder = qMin(12, rect.width()/2);
943 // Draw the handle in two parts, the top, and the bottom with calculated offset
944 TileSet *tiles1 = _helper.horizontalScrollBar(color, rect.height(), offset);
945 TileSet *tiles2 = _helper.horizontalScrollBar(color, rect.height(), offset+rect.width()+8);
947 p->save();
948 p->setClipRect(rect.adjusted(0,0,-remainder-1,0));
949 tiles1->render(rect, p, TileSet::Left | TileSet::Vertical);
950 p->setClipRect( QRect(rect.right()-remainder, rect.top(), remainder, rect.height()) );
951 tiles2->render( QRect(rect.right()-32, rect.top(), 32, rect.height()),
952 p, TileSet::Right | TileSet::Vertical);
953 p->restore();
954 return;
960 break;
962 case WT_TabBar:
964 const QStyleOptionTabV2* tabOpt = qstyleoption_cast<const QStyleOptionTabV2*>(opt);
966 switch (primitive)
968 case TabBar::NorthTab:
969 case TabBar::SouthTab:
970 case TabBar::WestTab:
971 case TabBar::EastTab:
973 if (!tabOpt) break;
975 renderTab(p, r, pal, mouseOver, flags&State_Selected, tabOpt, reverseLayout);
977 return;
979 case TabBar::WestText:
980 case TabBar::EastText:
982 QImage img(r.height(), r.width(), QImage::Format_ARGB32_Premultiplied);
983 img.fill(0x00000000);
984 QPainter painter(&img);
985 drawItemText(&painter, img.rect(), (reverseLayout ? Qt::AlignRight : Qt::AlignLeft) | Qt::AlignVCenter | Qt::TextShowMnemonic, tabOpt->palette, tabOpt->state & State_Enabled, tabOpt->text, QPalette::WindowText);
986 painter.end();
987 img = img.transformed(QMatrix().rotate(primitive == TabBar::WestText ? -90 : 90));
988 p->drawImage(r.x(), r.y(), img);
989 return;
991 case TabBar::IndicatorTear:
993 const QStyleOptionTab* option = qstyleoption_cast<const QStyleOptionTab*>(opt);
994 if(!option) return;
996 TileSet::Tiles flag;
997 QRect rect;
998 QRect br = r;
999 bool vertical = false;
1000 QPainter::CompositionMode slabCompMode = QPainter::CompositionMode_Source;
1002 switch(option->shape) {
1003 case QTabBar::RoundedNorth:
1004 case QTabBar::TriangularNorth:
1005 if(!option->cornerWidgets & QStyleOptionTab::LeftCornerWidget) {
1006 flag = reverseLayout ? TileSet::Right : TileSet::Left;
1007 rect = QRect(r.x(), r.y()+r.height()-4-7, 14+7, 4+14);
1009 else {
1010 flag = TileSet::Top;
1011 rect = QRect(r.x()-7, r.y()+r.height()-7, 14+7, 7);
1012 slabCompMode = QPainter::CompositionMode_SourceOver;
1014 rect = visualRect(option->direction, r, rect);
1015 break;
1016 case QTabBar::RoundedSouth:
1017 case QTabBar::TriangularSouth:
1018 if(!option->cornerWidgets & QStyleOptionTab::LeftCornerWidget) {
1019 flag = reverseLayout ? TileSet::Right : TileSet::Left;
1020 rect = QRect(r.x(), r.y()-7, 14+7, 2+14);
1022 else {
1023 flag = TileSet::Bottom;
1024 rect = reverseLayout ? QRect(r.x()-7+4, r.y(), 14+3, 6) : QRect(r.x()-7, r.y()-1, 14+6, 7);
1026 break;
1027 case QTabBar::RoundedWest:
1028 case QTabBar::TriangularWest:
1029 if(!option->cornerWidgets & QStyleOptionTab::LeftCornerWidget) {
1030 flag = TileSet::Top;
1031 rect = QRect(r.x()+r.width()-4-7, r.y(), 4+14, 7);
1033 else {
1034 flag = TileSet::Left;
1035 rect = QRect(r.x()+r.width()-7, r.y()-7, 7, 4+14);
1036 br.adjust(0,0,-5,0);
1038 vertical = true;
1039 break;
1040 case QTabBar::RoundedEast:
1041 case QTabBar::TriangularEast:
1042 if(!option->cornerWidgets & QStyleOptionTab::LeftCornerWidget) {
1043 flag = TileSet::Top;
1044 rect = QRect(r.x()-7, r.y(), 4+14, 7);
1046 else {
1047 flag = TileSet::Right;
1048 rect = QRect(r.x(), r.y()-7, 7, 4+14);
1049 br.adjust(5,0,0,0);
1051 vertical = true;
1052 break;
1053 default:
1054 return;
1057 QRect gr;
1058 if(!vertical && !reverseLayout)
1059 gr = QRect(0, 0, r.width(), 0);
1060 else if(!vertical && reverseLayout)
1061 if(!option->cornerWidgets & QStyleOptionTab::LeftCornerWidget)
1062 gr = QRect(r.x()-4, 0, r.x()-4+r.width(), 0);
1063 else
1064 gr = QRect(r.x(), 0, r.x()+r.width(), 0);
1065 else
1066 gr = QRect(0, 0, 0, r.height());
1069 QLinearGradient grad(gr.x(), gr.y(), gr.width(), gr.height());
1070 grad.setColorAt(0, Qt::transparent);
1071 grad.setColorAt(0.2, Qt::transparent);
1072 grad.setColorAt(1, Qt::black);
1073 p->setCompositionMode((reverseLayout && !vertical) ? QPainter::CompositionMode_DestinationOut : QPainter::CompositionMode_DestinationIn);
1074 p->fillRect(br, QBrush(grad));
1076 p->setCompositionMode(slabCompMode);
1077 renderSlab(p, rect, opt->palette.color(QPalette::Window), NoFill, flag);
1078 */ return;
1080 case TabBar::BaseFrame:
1082 const QStyleOptionTabBarBase* tabOpt = qstyleoption_cast<const QStyleOptionTabBarBase*>(opt);
1084 switch(tabOpt->shape)
1086 case QTabBar::RoundedNorth:
1087 case QTabBar::TriangularNorth:
1090 if (r.left() < tabOpt->tabBarRect.left())
1092 QRect fr = r;
1093 fr.setRight(tabOpt->tabBarRect.left());
1094 fr.adjust(-7,0,7,-1);
1095 renderSlab(p, fr, pal.color(QPalette::Window), NoFill, TileSet::Top);
1097 if (tabOpt->tabBarRect.right() < r.right())
1099 QRect fr = r;
1100 fr.setLeft(tabOpt->tabBarRect.right());
1101 fr.adjust(-7,0,7,-1);
1102 renderSlab(p, fr, pal.color(QPalette::Window), NoFill, TileSet::Top);
1104 return;
1106 case QTabBar::RoundedSouth:
1107 case QTabBar::TriangularSouth:
1109 if (r.left() < tabOpt->tabBarRect.left())
1111 QRect fr = r;
1112 fr.setRight(tabOpt->tabBarRect.left());
1113 fr.adjust(-7,0,7,-1);
1114 renderSlab(p, fr, pal.color(QPalette::Window), NoFill, TileSet::Bottom);
1116 if (tabOpt->tabBarRect.right() < r.right())
1118 QRect fr = r;
1119 fr.setLeft(tabOpt->tabBarRect.right());
1120 fr.adjust(-6,0,7,-1);
1121 renderSlab(p, fr, pal.color(QPalette::Window), NoFill, TileSet::Bottom);
1123 return;
1125 default:
1126 break;
1128 return;
1133 break;
1135 case WT_TabWidget:
1137 switch (primitive)
1139 case Generic::Frame:
1141 const QStyleOptionTabWidgetFrame* tabOpt = qstyleoption_cast<const QStyleOptionTabWidgetFrame*>(opt);
1142 // FIXME: tabOpt->tabBarSize may be bigger than the tab widget's size
1143 int w = tabOpt->tabBarSize.width();
1144 int h = tabOpt->tabBarSize.height();
1145 int lw = tabOpt->leftCornerWidgetSize.width();
1146 int lh = tabOpt->leftCornerWidgetSize.height();
1148 switch(tabOpt->shape)
1150 case QTabBar::RoundedNorth:
1151 case QTabBar::TriangularNorth:
1152 renderSlab(p, r, pal.color(QPalette::Window), NoFill,
1153 TileSet::Left | TileSet::Bottom | TileSet::Right);
1154 if(reverseLayout)
1156 // Left and right widgets are placed right and left when in reverse mode
1158 if (w+lw >0)
1159 renderSlab(p, QRect(0, r.y(), r.width() - w - lw+7, 7),
1160 pal.color(QPalette::Window), NoFill, TileSet::Left | TileSet::Top);
1161 else
1162 renderSlab(p, QRect(0, r.y(), r.width(), 7), pal.color(QPalette::Window), NoFill,
1163 TileSet::Left | TileSet::Top | TileSet::Right);
1165 if (lw > 0)
1166 renderSlab(p, QRect(r.right() - lw-7, r.y(), lw+7, 7),
1167 pal.color(QPalette::Window), NoFill, TileSet::Top | TileSet::Right);
1169 else
1171 if (lw > 0)
1172 renderSlab(p, QRect(0, r.y(), lw+7, 7), pal.color(QPalette::Window), NoFill,
1173 TileSet::Left | TileSet::Top);
1175 if (w+lw >0)
1176 renderSlab(p, QRect(w+lw-7, r.y(), r.width() - w - lw+7, 7), pal.color(QPalette::Window), NoFill,
1177 TileSet::Top | TileSet::Right);
1178 else
1179 renderSlab(p, QRect(0, r.y(), r.width(), 7), pal.color(QPalette::Window), NoFill,
1180 TileSet::Left | TileSet::Top | TileSet::Right);
1183 return;
1185 case QTabBar::RoundedSouth:
1186 case QTabBar::TriangularSouth:
1187 renderSlab(p, r, pal.color(QPalette::Window), NoFill,
1188 TileSet::Left | TileSet::Top | TileSet::Right);
1189 if(reverseLayout)
1191 // Left and right widgets are placed right and left when in reverse mode
1193 if (w+lw >0)
1194 renderSlab(p, QRect(0, r.bottom()-7, r.width() - w - lw + 7, 7),
1195 pal.color(QPalette::Window), NoFill, TileSet::Left | TileSet::Bottom);
1196 else
1197 renderSlab(p, QRect(0, r.bottom()-7, r.width(), 7), pal.color(QPalette::Window),
1198 NoFill, TileSet::Left | TileSet::Bottom | TileSet::Right);
1200 if (lw > 0)
1201 renderSlab(p, QRect(r.right() - lw-7, r.bottom()-7, lw+7, 7),
1202 pal.color(QPalette::Window), NoFill, TileSet::Bottom | TileSet::Right);
1204 else
1206 if (lw > 0)
1207 renderSlab(p, QRect(0, r.bottom()-7, lw+7, 7),
1208 pal.color(QPalette::Window), NoFill, TileSet::Left | TileSet::Bottom);
1210 if (w+lw >0)
1211 renderSlab(p, QRect(w+lw-7, r.bottom()-7, r.width() - w - lw+7, 7),
1212 pal.color(QPalette::Window), NoFill, TileSet::Bottom | TileSet::Right);
1213 else
1214 renderSlab(p, QRect(0, r.bottom()-7, r.width(), 7), pal.color(QPalette::Window),
1215 NoFill, TileSet::Left | TileSet::Bottom | TileSet::Right);
1218 return;
1220 case QTabBar::RoundedWest:
1221 case QTabBar::TriangularWest:
1222 renderSlab(p, r, pal.color(QPalette::Window), NoFill,
1223 TileSet::Top | TileSet::Right | TileSet::Bottom);
1225 if(reverseLayout)
1227 // Left and right widgets are placed right and left when in reverse mode
1228 if (h+lh >0)
1229 renderSlab(p, QRect(r.x(), h + lh - 7, 7, r.height() - h - lh+7),
1230 pal.color(QPalette::Window), NoFill, TileSet::Bottom | TileSet::Left);
1231 else
1232 renderSlab(p, QRect(r.x(), r.y(), r.width(), 7), pal.color(QPalette::Window), NoFill,
1233 TileSet::Left | TileSet::Top | TileSet::Right);
1235 if (lh > 0)
1236 renderSlab(p, QRect(r.x(), r.y() , 7, lh+7),
1237 pal.color(QPalette::Window), NoFill, TileSet::Top | TileSet::Left);
1239 else
1241 if (lh > 0)
1242 renderSlab(p, QRect(r.x(), r.y(), 7, lh+7), pal.color(QPalette::Window), NoFill,
1243 TileSet::Left | TileSet::Top);
1245 if (h+lh >0)
1246 renderSlab(p, QRect(r.x(), r.y()+h+lh-7, 7, r.height() - h - lh+7), pal.color(QPalette::Window), NoFill,
1247 TileSet::Left | TileSet::Bottom);
1248 else
1249 renderSlab(p, QRect(r.x(), r.y(), 7, r.height()), pal.color(QPalette::Window), NoFill,
1250 TileSet::Top | TileSet::Left | TileSet::Bottom);
1253 return;
1255 case QTabBar::RoundedEast:
1256 case QTabBar::TriangularEast:
1258 renderSlab(p, r, pal.color(QPalette::Window), NoFill,
1259 TileSet::Top | TileSet::Left | TileSet::Bottom);
1260 if(reverseLayout)
1262 // Left and right widgets are placed right and left when in reverse mode
1263 if (h+lh >0)
1264 renderSlab(p, QRect(r.x()+r.width()-7, h + lh - 7, 7, r.height() - h - lh+7),
1265 pal.color(QPalette::Window), NoFill, TileSet::Bottom | TileSet::Right);
1266 else
1267 renderSlab(p, QRect(r.x()+r.width()-7, r.y(), r.width(), 7), pal.color(QPalette::Window), NoFill,
1268 TileSet::Left | TileSet::Top | TileSet::Right);
1270 if (lh > 0)
1271 renderSlab(p, QRect(r.x()+r.width()-7, r.y() , 7, lh+7),
1272 pal.color(QPalette::Window), NoFill, TileSet::Top | TileSet::Right);
1274 else
1276 if (lh > 0)
1277 renderSlab(p, QRect(r.width()-7, r.y(), 7, lh+7), pal.color(QPalette::Window), NoFill,
1278 TileSet::Top | TileSet::Right);
1280 if (h+lh >0)
1281 renderSlab(p, QRect(r.width()-7, r.y()+h+lh-7, 7, r.height() - h - lh+7), pal.color(QPalette::Window), NoFill,
1282 TileSet::Bottom | TileSet::Right);
1283 else
1284 renderSlab(p, QRect(r.x(), r.y(), 7, r.height()), pal.color(QPalette::Window), NoFill,
1285 TileSet::Top | TileSet::Right | TileSet::Bottom);
1288 return;
1289 default:
1290 return;
1296 break;
1298 case WT_Window:
1300 switch (primitive)
1302 case Generic::Frame:
1304 return;
1307 case Window::TitlePanel:
1308 p->fillRect(r, QColor(Qt::green) );
1309 return;
1311 case Window::ButtonMin:
1312 case Window::ButtonMax:
1313 case Window::ButtonRestore:
1314 case Window::ButtonClose:
1315 case Window::ButtonShade:
1316 case Window::ButtonUnshade:
1317 case Window::ButtonHelp:
1319 KStyle::TitleButtonOption* tbkOpts =
1320 extractOption<KStyle::TitleButtonOption*>(kOpt);
1321 State bflags = flags;
1322 bflags &= ~State_Sunken;
1323 if (tbkOpts->active)
1324 bflags |= State_Sunken;
1325 drawKStylePrimitive(WT_ToolButton, ToolButton::Panel, opt, r, pal, bflags, p, widget);
1326 return;
1331 break;
1333 case WT_Splitter:
1335 switch (primitive)
1337 case Splitter::HandleHor:
1339 int h = r.height();
1340 QColor color = pal.color(QPalette::Background);
1342 int ngroups = qMax(1,h / 250);
1343 int center = (h - (ngroups-1) * 250) /2 + r.top();
1344 for(int k = 0; k < ngroups; k++, center += 250) {
1345 renderDot(p, QPointF(r.left()+3, center-3), color);
1346 renderDot(p, QPointF(r.left()+3, center), color);
1347 renderDot(p, QPointF(r.left()+3, center+3), color);
1349 return;
1351 case Splitter::HandleVert:
1353 int w = r.width();
1354 QColor color = pal.color(QPalette::Background);
1356 int ngroups = qMax(1, w / 250);
1357 int center = (w - (ngroups-1) * 250) /2 + r.left();
1358 for(int k = 0; k < ngroups; k++, center += 250) {
1359 renderDot(p, QPointF(center-3, r.top()+3), color);
1360 renderDot(p, QPointF(center, r.top()+3), color);
1361 renderDot(p, QPointF(center+3, r.top()+3), color);
1363 return;
1367 break;
1369 case WT_Slider:
1371 // TODO
1372 switch (primitive)
1374 case Slider::HandleHor:
1375 case Slider::HandleVert:
1377 StyleOptions opts = (flags & State_HasFocus ? Focus : StyleOption());
1378 if (const QStyleOptionSlider *slider = qstyleoption_cast<const QStyleOptionSlider *>(opt))
1379 if(slider->activeSubControls & SC_SliderHandle)
1380 if (mouseOver) opts |= Hover;
1382 renderSlab(p, r, pal.color(QPalette::Button), opts);
1383 return;
1386 case Slider::GrooveHor:
1387 case Slider::GrooveVert:
1390 bool horizontal = primitive == Slider::GrooveHor;
1392 if (horizontal) {
1393 int center = r.y()+r.height()/2;
1394 _helper.groove(pal.color(QPalette::Window), 0.0)->render(
1395 QRect(r.left()+4, center-2, r.width()-8, 5), p);
1396 } else {
1397 int center = r.x()+r.width()/2;
1398 _helper.groove(pal.color(QPalette::Window), 0.0)->render(
1399 QRect(center-2, r.top()+4, 5, r.height()-8), p);
1403 return;
1408 break;
1410 case WT_SpinBox:
1412 bool hasFocus = flags & State_HasFocus;
1414 const QColor inputColor = enabled?pal.color(QPalette::Base):pal.color(QPalette::Window);
1416 switch (primitive)
1418 case Generic::Frame:
1420 QRect fr = r.adjusted(2,2,-2,-2);
1421 p->save();
1422 p->setRenderHint(QPainter::Antialiasing);
1423 p->setPen(Qt::NoPen);
1424 p->setBrush(inputColor);
1426 #ifdef HOLE_NO_EDGE_FILL
1427 p->fillRect(fr.adjusted(3,3,-3,-3), inputColor);
1428 #else
1429 _helper.fillHole(*p, r);
1430 #endif
1432 p->restore();
1433 // TODO use widget background role?
1434 // We really need the color of the widget behind to be "right",
1435 // but the shadow needs to be colored as the inner widget; needs
1436 // changes in helper.
1437 #ifdef HOLE_COLOR_OUTSIDE
1438 renderHole(p, pal.color(QPalette::Window), fr, hasFocus, mouseOver);
1439 #else
1440 renderHole(p, inputColor, fr, hasFocus, mouseOver);
1441 #endif
1442 return;
1444 case SpinBox::EditField:
1445 case SpinBox::ButtonArea:
1446 case SpinBox::UpButton:
1447 case SpinBox::DownButton:
1449 return;
1455 break;
1457 case WT_ComboBox:
1459 bool editable = false;
1460 if (const QStyleOptionComboBox *cb = qstyleoption_cast<const QStyleOptionComboBox *>(opt) )
1461 editable = cb->editable;
1463 bool hasFocus = flags & State_HasFocus;
1464 StyleOptions opts = (flags & State_HasFocus ? Focus : StyleOption());
1465 if (mouseOver) opts |= Hover;
1467 const QColor buttonColor = enabled?pal.color(QPalette::Button):pal.color(QPalette::Window);
1468 const QColor inputColor = enabled ? pal.color(QPalette::Base) : pal.color(QPalette::Window);
1469 QRect editField = subControlRect(CC_ComboBox, qstyleoption_cast<const QStyleOptionComplex*>(opt), SC_ComboBoxEditField, widget);
1471 switch (primitive)
1473 case Generic::Frame:
1475 // TODO: pressed state
1476 if(!editable) {
1477 renderSlab(p, r, pal.color(QPalette::Button), opts);
1478 } else {
1479 QRect fr = r.adjusted(2,2,-2,-2);
1480 // input area
1481 p->save();
1482 p->setRenderHint(QPainter::Antialiasing);
1483 p->setPen(Qt::NoPen);
1484 p->setBrush(inputColor);
1486 #ifdef HOLE_NO_EDGE_FILL
1487 p->fillRect(fr.adjusted(3,3,-3,-3), inputColor);
1488 #else
1489 _helper.fillHole(*p, r.adjusted(0,0,0,-1));
1490 #endif
1492 p->restore();
1494 #ifdef HOLE_COLOR_OUTSIDE
1495 if (hasFocus && enabled)
1497 renderHole(p, pal.color(QPalette::Window), fr, true, mouseOver);
1499 else
1501 renderHole(p, pal.color(QPalette::Window), fr, false, mouseOver);
1503 #else
1504 if (hasFocus && enabled)
1506 renderHole(p, inputColor, fr, true, mouseOver);
1508 else
1510 renderHole(p, inputColor, fr, false, mouseOver);
1512 #endif
1515 return;
1518 case ComboBox::EditField:
1520 // empty
1521 return;
1524 case ComboBox::Button:
1526 return;
1531 break;
1533 case WT_Header:
1535 switch (primitive)
1537 case Header::SectionHor:
1538 case Header::SectionVert:
1540 if (const QStyleOptionHeader *header = qstyleoption_cast<const QStyleOptionHeader *>(opt)) {
1541 bool isFirst = (primitive==Header::SectionHor)&&(header->position == QStyleOptionHeader::Beginning);
1543 p->setPen(pal.color(QPalette::Text));
1545 QColor color = pal.color(QPalette::Button);
1546 p->fillRect(r, color);
1547 if(primitive == Header::SectionHor) {
1548 if(header->section != 0 || isFirst) {
1549 int center = r.center().y();
1550 renderDot(p, QPointF(r.right()-1, center-3), color);
1551 renderDot(p, QPointF(r.right()-1, center), color);
1552 renderDot(p, QPointF(r.right()-1, center+3), color);
1555 else
1556 p->drawLine(r.bottomLeft(),r.bottomRight());
1559 return;
1563 break;
1565 case WT_Tree:
1567 switch (primitive)
1569 case Tree::VerticalBranch:
1570 case Tree::HorizontalBranch:
1572 //### FIXME: set sane color.
1573 QBrush brush(Qt::Dense4Pattern);
1574 brush.setColor(pal.mid().color() );
1575 p->fillRect(r, brush);
1576 return;
1578 case Tree::ExpanderOpen:
1579 case Tree::ExpanderClosed:
1581 int radius = (r.width() - 4) / 2;
1582 int centerx = r.x() + r.width()/2;
1583 int centery = r.y() + r.height()/2;
1585 p->setPen( pal.text().color() );
1586 if(!_drawTriangularExpander)
1588 // plus or minus
1589 p->drawLine( centerx - radius, centery, centerx + radius, centery );
1590 if (primitive == Tree::ExpanderClosed) // Collapsed = On
1591 p->drawLine( centerx, centery - radius, centerx, centery + radius );
1592 } else {
1593 if(primitive == Tree::ExpanderClosed)
1594 drawKStylePrimitive(WT_Generic, Generic::ArrowRight, opt, QRect(r.x()+1,r.y()+1,r.width(),r.height()), pal, flags, p, widget);
1595 else
1596 drawKStylePrimitive(WT_Generic, Generic::ArrowDown, opt, QRect(r.x()+1,r.y()+1,r.width(),r.height()), pal, flags, p, widget);
1599 return;
1601 default:
1602 break;
1605 break;
1607 case WT_LineEdit:
1609 switch (primitive)
1611 case Generic::Frame:
1613 const bool isReadOnly = flags & State_ReadOnly;
1614 const bool isEnabled = flags & State_Enabled;
1615 const bool hasFocus = flags & State_HasFocus;
1616 #ifdef HOLE_COLOR_OUTSIDE
1617 const QColor inputColor = pal.color(QPalette::Window);
1618 #else
1619 const QColor inputColor = enabled?pal.color(QPalette::Base):pal.color(QPalette::Window);
1620 #endif
1621 if (hasFocus && !isReadOnly && isEnabled)
1623 renderHole(p, inputColor, r.adjusted(2,2,-2,-3), true, mouseOver);
1625 else
1627 renderHole(p, inputColor, r.adjusted(2,2,-2,-3), false, mouseOver);
1629 return;
1632 case LineEdit::Panel:
1634 const QColor inputColor = enabled?pal.color(QPalette::Base):pal.color(QPalette::Window);
1636 if (const QStyleOptionFrame *panel = qstyleoption_cast<const QStyleOptionFrame*>(opt))
1638 const int lineWidth(panel->lineWidth);
1640 if (lineWidth > 0)
1642 p->save();
1643 p->setRenderHint(QPainter::Antialiasing);
1644 p->setPen(Qt::NoPen);
1645 p->setBrush(inputColor);
1647 #ifdef HOLE_NO_EDGE_FILL
1648 p->fillRect(r.adjusted(5,5,-5,-5), inputColor);
1649 #else
1650 _helper.fillHole(*p, r.adjusted(0,0,-0,-1));
1651 #endif
1652 drawPrimitive(PE_FrameLineEdit, panel, p, widget);
1654 p->restore();
1656 else
1658 p->fillRect(r.adjusted(2,2,-2,-1), inputColor);
1665 break;
1667 case WT_GroupBox:
1669 switch (primitive)
1671 case Generic::Frame:
1673 QColor color = pal.color(QPalette::Window);
1675 p->save();
1676 p->setRenderHint(QPainter::Antialiasing);
1677 p->setPen(Qt::NoPen);
1679 QLinearGradient innerGradient(0, r.top()-r.height()+12, 0, r.bottom()+r.height()-19);
1680 QColor light = _helper.calcLightColor(color); //KColorUtils::shade(calcLightColor(color), shade));
1681 light.setAlphaF(0.4);
1682 innerGradient.setColorAt(0.0, light);
1683 color.setAlphaF(0.4);
1684 innerGradient.setColorAt(1.0, color);
1685 p->setBrush(innerGradient);
1686 p->setClipRect(r.adjusted(0, 0, 0, -19));
1687 _helper.fillSlab(*p, r);
1689 TileSet *slopeTileSet = _helper.slope(pal.color(QPalette::Window), 0.0);
1690 p->setClipping(false);
1691 slopeTileSet->render(r, p);
1693 p->restore();
1695 return;
1697 case GroupBox::FlatFrame:
1699 return;
1704 break;
1706 case WT_ToolBar:
1708 switch (primitive)
1710 case ToolBar::HandleHor:
1712 int counter = 1;
1714 int center = r.left()+r.width()/2;
1715 for(int j = r.top()+2; j <= r.bottom()-3; j+=3) {
1716 if(counter%2 == 0) {
1717 renderDot(p, QPoint(center+1, j), pal.color(QPalette::Background));
1718 } else {
1719 renderDot(p, QPoint(center-2, j), pal.color(QPalette::Background));
1721 counter++;
1723 return;
1725 case ToolBar::HandleVert:
1727 int counter = 1;
1729 int center = r.top()+r.height()/2;
1730 for(int j = r.left()+2; j <= r.right()-3; j+=3) {
1731 if(counter%2 == 0) {
1732 renderDot(p, QPoint(j, center+1), pal.color(QPalette::Background));
1733 } else {
1734 renderDot(p, QPoint(j, center-2), pal.color(QPalette::Background));
1736 counter++;
1739 return;
1742 case ToolBar::Separator:
1744 if(_drawToolBarItemSeparator) {
1745 // TODO leftover from plastik, probably should be redone
1746 p->setPen(_helper.calcDarkColor(pal.color(QPalette::Background)));
1747 if(flags & State_Horizontal) {
1748 int center = r.left()+r.width()/2;
1749 p->drawLine( center-1, r.top()+3, center-1, r.bottom()-3 );
1750 } else {
1751 int center = r.top()+r.height()/2;
1752 p->drawLine( r.x()+3, center-1, r.right()-3, center-1 );
1756 return;
1760 break;
1762 case WT_ToolButton:
1764 switch (primitive)
1766 case ToolButton::Panel:
1768 const QToolButton* t=dynamic_cast<const QToolButton*>(widget);
1769 if (t && t->autoRaise()==false)
1771 StyleOptions opts = 0;
1772 if ((flags & State_On) || (flags & State_Sunken))
1773 opts |= Sunken;
1774 if (flags & State_HasFocus)
1775 opts |= Focus;
1776 if (enabled && (flags & State_MouseOver))
1777 opts |= Hover;
1778 if (dynamic_cast<const QTabBar*>(t->parent()))
1780 renderWindowBackground(p, r, t->window());
1781 //renderSlab(p, r.adjusted(0,4,0,-4), pal.color(QPalette::Button), opts);
1782 renderSlab(p, QRect(r.left()-7, r.bottom()-6, r.width()+14, 2), pal.color(QPalette::Window), NoFill, TileSet::Top);
1784 else
1785 renderSlab(p, r, pal.color(QPalette::Button), opts);
1786 return;
1789 bool hasFocus = flags & State_HasFocus;
1791 if((flags & State_Sunken) || (flags & State_On) )
1793 renderHole(p, pal.color(QPalette::Window), r, hasFocus, mouseOver);
1795 else if (hasFocus || mouseOver)
1797 TileSet *tile;
1799 if(mouseOver)
1800 tile = _helper.slitFocused(_viewHoverBrush.brush(QPalette::Active).color());
1801 else
1802 tile = _helper.slitFocused(_viewFocusBrush.brush(QPalette::Active).color());
1803 tile->render(r, p);
1805 return;
1810 break;
1812 case WT_Limit: //max value for the enum, only here to silence the compiler
1813 case WT_Generic: // handled below since the primitives arevalid for all WT_ types
1814 break;
1818 // Arrows
1819 if (primitive >= Generic::ArrowUp && primitive <= Generic::ArrowLeft) {
1820 QPolygonF a;
1822 switch (primitive) {
1823 case Generic::ArrowUp: {
1824 a.clear();
1825 a << QPointF( -3,2.5) << QPointF(0.5, -1.5) << QPointF(4,2.5);
1826 break;
1828 case Generic::ArrowDown: {
1829 a.clear();
1830 a << QPointF( -3,-2.5) << QPointF(0.5, 1.5) << QPointF(4,-2.5);
1831 break;
1833 case Generic::ArrowLeft: {
1834 a.clear();
1835 a << QPointF(2.5,-3) << QPointF(-1.5, 0.5) << QPointF(2.5,4);
1836 break;
1838 case Generic::ArrowRight: {
1839 a.clear();
1840 a << QPointF(-2.5,-3) << QPointF(1.5, 0.5) << QPointF(-2.5,4);
1841 break;
1845 a.translate(int(r.x()+r.width()/2), int(r.y()+r.height()/2));
1846 KStyle::ColorOption* colorOpt = extractOption<KStyle::ColorOption*>(kOpt);
1847 QColor arrowColor = colorOpt->color.color(pal);
1849 QPen oldPen(p->pen()); // important to save the pen as combobox assumes we don't touch
1850 p->setPen(QPen(arrowColor, 2.2, Qt::SolidLine, Qt::RoundCap, Qt::RoundJoin));
1851 p->setRenderHint(QPainter::Antialiasing);
1852 p->drawPolyline(a);
1853 p->setRenderHint(QPainter::Antialiasing, false);
1854 p->setPen(oldPen);
1855 return;
1858 switch (primitive)
1860 case Generic::Frame:
1862 // WT_Generic and other fallen-through frames...
1863 // QFrame, Qt item views, etc.: sunken..
1864 bool focusHighlight = flags&State_HasFocus/* && flags&State_Enabled*/;
1865 if (flags & State_Sunken) {
1866 // TODO use widget background role? - probably not
1867 //renderHole(p, pal.color(widget->backgroundRole()), r, focusHighlight);
1868 renderHole(p, pal.color(QPalette::Window), r, focusHighlight);
1869 } else
1870 break; // do the default thing
1873 case Generic::FocusIndicator:
1875 const QAbstractItemView *aiv = qobject_cast<const QAbstractItemView*>(widget);
1876 if (aiv && opt && (opt->state & QStyle::State_Item)
1877 && (aiv->selectionMode() != QAbstractItemView::SingleSelection))
1879 QPen pen(_viewFocusBrush.brush(QPalette::Active).color());
1880 pen.setWidth(0);
1881 pen.setStyle(Qt::DotLine);
1882 p->setPen(pal.color(QPalette::Base));
1883 p->drawRect(r.adjusted(0,0,-1,-1));
1884 p->setPen(pen);
1885 p->drawRect(r.adjusted(0,0,-1,-1));
1887 // we don't want the stippled focus indicator in oxygen
1888 return;
1891 default:
1892 break;
1895 // default fallback
1896 KStyle::drawKStylePrimitive(widgetType, primitive, opt,
1897 r, pal, flags, p, widget, kOpt);
1900 void OxygenStyle::polish(QWidget* widget)
1902 if (!widget) return;
1904 switch (widget->windowFlags() & Qt::WindowType_Mask) {
1905 case Qt::Window:
1906 case Qt::Dialog:
1907 widget->installEventFilter(this);
1908 break;
1909 case Qt::Popup: // we currently don't want gradients on menus etc
1910 case Qt::Tool: // this we exclude as it is used for dragging of icons etc
1911 default:
1912 break;
1915 if( _animateProgressBar && qobject_cast<QProgressBar*>(widget) )
1917 widget->installEventFilter(this);
1918 progAnimWidgets[widget] = 0;
1919 connect(widget, SIGNAL(destroyed(QObject*)), this, SLOT(progressBarDestroyed(QObject*)));
1920 if (!animationTimer->isActive()) {
1921 animationTimer->setSingleShot( false );
1922 animationTimer->start( 50 );
1926 if (qobject_cast<QPushButton*>(widget)
1927 || qobject_cast<QComboBox*>(widget)
1928 || qobject_cast<QAbstractSpinBox*>(widget)
1929 || qobject_cast<QCheckBox*>(widget)
1930 || qobject_cast<QRadioButton*>(widget)
1931 || qobject_cast<QTabBar*>(widget)
1932 || qobject_cast<QScrollBar*>(widget)
1933 || qobject_cast<QSlider*>(widget)
1934 || qobject_cast<QToolButton*>(widget)
1936 widget->setAttribute(Qt::WA_Hover);
1939 if (qobject_cast<QMenuBar*>(widget))
1941 widget->setBackgroundRole(QPalette::NoRole);
1943 else if (widget->inherits("Q3ToolBar")
1944 || qobject_cast<QToolBar*>(widget)
1945 || qobject_cast<QToolBar *>(widget->parent()))
1947 widget->setBackgroundRole(QPalette::NoRole);
1948 widget->setContentsMargins(0,0,0,2);
1949 widget->installEventFilter(this);
1951 else if (qobject_cast<QScrollBar*>(widget) )
1953 widget->setAttribute(Qt::WA_OpaquePaintEvent, false);
1955 else if (qobject_cast<QDockWidget*>(widget))
1957 widget->setContentsMargins(2,1,2,2);
1958 widget->installEventFilter(this);
1960 else if (qobject_cast<QToolBox*>(widget))
1962 widget->setBackgroundRole(QPalette::NoRole);
1963 widget->setAutoFillBackground(false);
1964 widget->setContentsMargins(5,5,5,5);
1965 widget->installEventFilter(this);
1967 else if (widget->parentWidget() && widget->parentWidget()->parentWidget() && qobject_cast<QToolBox*>(widget->parentWidget()->parentWidget()->parentWidget()))
1969 widget->setBackgroundRole(QPalette::NoRole);
1970 widget->setAutoFillBackground(false);
1971 widget->parentWidget()->setAutoFillBackground(false);
1973 else if (qobject_cast<QMenu*>(widget))
1975 widget->installEventFilter(this);
1977 KStyle::polish(widget);
1980 void OxygenStyle::unpolish(QWidget* widget)
1982 if ( qobject_cast<QProgressBar*>(widget) )
1984 progAnimWidgets.remove(widget);
1987 if (qobject_cast<QPushButton*>(widget)
1988 || qobject_cast<QComboBox*>(widget)
1989 || qobject_cast<QAbstractSpinBox*>(widget)
1990 || qobject_cast<QCheckBox*>(widget)
1991 || qobject_cast<QRadioButton*>(widget)
1992 || qobject_cast<QScrollBar*>(widget)
1993 || qobject_cast<QSlider*>(widget)
1995 widget->setAttribute(Qt::WA_Hover, false);
1998 if (qobject_cast<QMenuBar*>(widget)
1999 || (widget && widget->inherits("Q3ToolBar"))
2000 || qobject_cast<QToolBar*>(widget)
2001 || (widget && qobject_cast<QToolBar *>(widget->parent()))
2002 || qobject_cast<QToolBox*>(widget))
2004 widget->setBackgroundRole(QPalette::Button);
2007 if (qobject_cast<QScrollBar*>(widget))
2009 widget->setAttribute(Qt::WA_OpaquePaintEvent);
2011 else if (qobject_cast<QDockWidget*>(widget))
2013 widget->setContentsMargins(0,0,0,0);
2015 else if (qobject_cast<QToolBox*>(widget))
2017 widget->setBackgroundRole(QPalette::Button);
2018 widget->setContentsMargins(0,0,0,0);
2019 widget->removeEventFilter(this);
2021 else if (qobject_cast<QMenu*>(widget))
2023 widget->setAttribute(Qt::WA_PaintOnScreen, false);
2024 widget->setAttribute(Qt::WA_NoSystemBackground, false);
2025 widget->removeEventFilter(this);
2027 KStyle::unpolish(widget);
2030 void OxygenStyle::progressBarDestroyed(QObject* obj)
2032 progAnimWidgets.remove(static_cast<QWidget*>(obj));
2033 //the timer updates will stop next time if this was the last visible one
2036 void OxygenStyle::globalSettingsChange(int type, int /*arg*/)
2038 if (type == KGlobalSettings::PaletteChanged) {
2039 _helper.reloadConfig();
2040 _viewFocusBrush = KStatefulBrush( KColorScheme::View, KColorScheme::FocusColor, _config );
2041 _viewHoverBrush = KStatefulBrush( KColorScheme::View, KColorScheme::HoverColor, _config );
2045 void OxygenStyle::renderSlab(QPainter *p, const QRect &r, const QColor &color, StyleOptions opts, TileSet::Tiles tiles) const
2047 if ((r.width() <= 0) || (r.height() <= 0))
2048 return;
2050 TileSet *tile;
2052 // fill
2053 if (!(opts & NoFill))
2055 p->save();
2056 p->setRenderHint(QPainter::Antialiasing);
2057 p->setPen(Qt::NoPen);
2059 QLinearGradient innerGradient(0, r.top() - r.height(), 0, r.bottom());
2060 innerGradient.setColorAt(0.0, _helper.calcLightColor(color)); //KColorUtils::shade(calcLightColor(color), shade));
2061 innerGradient.setColorAt(1.0, color);
2062 p->setBrush(innerGradient);
2063 _helper.fillSlab(*p, r);
2065 p->restore();
2068 // edges
2069 // for slabs, hover takes precedence over focus (other way around for holes)
2070 // but in any case if the button is sunken we don't show focus nor hover
2071 if (opts & Sunken)
2072 tile = _helper.slabSunken(color, 0.0);
2073 else if (opts & Hover)
2074 tile = _helper.slabFocused(color, _viewHoverBrush.brush(QPalette::Active).color(), 0.0); // FIXME need state
2075 else if (opts & Focus)
2076 tile = _helper.slabFocused(color, _viewFocusBrush.brush(QPalette::Active).color(), 0.0); // FIXME need state
2077 else
2079 tile = _helper.slab(color, 0.0);
2080 tile->render(r, p, tiles);
2081 return;
2083 tile->render(r, p, tiles);
2086 void OxygenStyle::renderHole(QPainter *p, const QColor &base, const QRect &r, bool focus, bool hover, TileSet::Tiles posFlags) const
2088 if((r.width() <= 0)||(r.height() <= 0))
2089 return;
2091 TileSet *tile;
2092 // for holes, focus takes precedence over hover (other way around for buttons)
2093 if (focus)
2094 tile = _helper.holeFocused(base, _viewFocusBrush.brush(QPalette::Active).color(), 0.0); // FIXME need state
2095 else if (hover)
2096 tile = _helper.holeFocused(base, _viewHoverBrush.brush(QPalette::Active).color(), 0.0); // FIXME need state
2097 else
2098 tile = _helper.hole(base, 0.0);
2099 tile->render(r, p, posFlags);
2102 // TODO take StyleOptions instead of ugly bools
2103 void OxygenStyle::renderCheckBox(QPainter *p, const QRect &rect, const QPalette &pal,
2104 bool enabled, bool hasFocus, bool mouseOver, int primitive,
2105 bool sunken) const
2107 Q_UNUSED(enabled);
2109 int s = qMin(rect.width(), rect.height());
2110 QRect r = centerRect(rect, s, s);
2112 StyleOptions opts;
2113 if (hasFocus) opts |= Focus;
2114 if (mouseOver) opts |= Hover;
2116 if(sunken)
2118 QColor color = pal.color(QPalette::Window);
2119 _helper.holeFlat(color, 0.0)->render(r, p, TileSet::Full);
2121 else
2123 renderSlab(p, r, pal.color(QPalette::Button), opts);
2126 // check mark
2127 double x = r.center().x() - 3.5, y = r.center().y() - 2.5;
2129 if (primitive != CheckBox::CheckOff)
2131 QBrush brush = _helper.decoGradient(rect.adjusted(2,2,-2,-2), pal.color(QPalette::ButtonText));
2132 QPen pen(brush, 2.2, Qt::SolidLine, Qt::RoundCap, Qt::RoundJoin);
2134 pen.setCapStyle(Qt::RoundCap);
2135 if (primitive == CheckBox::CheckTriState) {
2136 QVector<qreal> dashes;
2137 if (_checkCheck) {
2138 dashes << 1.0 << 2.0;
2139 pen.setWidthF(1.3);
2141 else {
2142 dashes << 0.4 << 2.0;
2144 pen.setDashPattern(dashes);
2147 p->setRenderHint(QPainter::Antialiasing);
2148 p->setPen(pen);
2149 if (_checkCheck) {
2150 p->drawLine(QPointF(x+9, y), QPointF(x+3,y+7));
2151 p->drawLine(QPointF(x, y+4), QPointF(x+3,y+7));
2153 else {
2154 if (sunken) {
2155 p->drawLine(QPointF(x+8, y), QPointF(x+1,y+7));
2156 p->drawLine(QPointF(x+8, y+7), QPointF(x+1,y));
2158 else {
2159 p->drawLine(QPointF(x+8, y-1), QPointF(x,y+7));
2160 p->drawLine(QPointF(x+8, y+7), QPointF(x,y-1));
2163 p->setRenderHint(QPainter::Antialiasing, false);
2167 void OxygenStyle::renderRadioButton(QPainter *p, const QRect &r, const QPalette &pal,
2168 bool enabled, bool mouseOver, int prim,
2169 bool drawButton) const
2171 Q_UNUSED(enabled);
2173 QRect r2(r.x() + (r.width()-21)/2, r.y() + (r.height()-21)/2, 21, 21);
2174 int x = r2.x();
2175 int y = r2.y();
2177 // TODO focus?
2178 if(mouseOver)
2180 QPixmap slabPixmap = _helper.roundSlabFocused(pal.color(QPalette::Button),_viewHoverBrush.brush(QPalette::Active).color(), 0.0);
2181 if(drawButton)
2182 p->drawPixmap(x, y, slabPixmap);
2184 else
2186 QPixmap slabPixmap = _helper.roundSlab(pal.color(QPalette::Button), 0.0);
2187 if(drawButton)
2188 p->drawPixmap(x, y, slabPixmap);
2191 // draw the radio mark
2192 switch (prim)
2194 case RadioButton::RadioOn:
2196 const double radius = 3.0;
2197 double dx = r2.width() * 0.5 - radius;
2198 double dy = r2.height() * 0.5 - radius;
2199 p->save();
2200 p->setRenderHints(QPainter::Antialiasing);
2201 p->setPen(Qt::NoPen);
2202 p->setBrush(_helper.decoGradient(r2.adjusted(2,2,-2,-2), pal.color(QPalette::ButtonText)));
2203 p->drawEllipse(QRectF(r2).adjusted(dx, dy, -dx, -dy));
2204 p->restore();
2205 return;
2207 case RadioButton::RadioOff:
2209 // empty
2210 return;
2213 default:
2214 // StateTristate, shouldn't happen...
2215 return;
2219 void OxygenStyle::renderDot(QPainter *p, const QPointF &point, const QColor &baseColor) const
2221 Q_UNUSED(baseColor)
2222 const qreal diameter = 1.8;
2223 p->setRenderHint(QPainter::Antialiasing);
2224 p->setPen(Qt::NoPen);
2225 p->setBrush(QColor(0, 0, 0, 66));
2226 p->drawEllipse(QRectF(point.x()-diameter/2+0.5, point.y()-diameter/2+0.5, diameter, diameter));
2227 p->setRenderHint(QPainter::Antialiasing, false);
2230 void OxygenStyle::renderTab(QPainter *p,
2231 const QRect &r,
2232 const QPalette &pal,
2233 bool mouseOver,
2234 const bool selected,
2235 const QStyleOptionTabV2 *tabOpt,
2236 const bool reverseLayout) const
2238 const QStyleOptionTab::TabPosition pos = tabOpt->position;
2239 const bool northAlignment = tabOpt->shape == QTabBar::RoundedNorth || tabOpt->shape == QTabBar::TriangularNorth;
2240 const bool southAlignment = tabOpt->shape == QTabBar::RoundedSouth || tabOpt->shape == QTabBar::TriangularSouth;
2241 const bool westAlignment = tabOpt->shape == QTabBar::RoundedWest || tabOpt->shape == QTabBar::TriangularWest;
2242 const bool eastAlignment = tabOpt->shape == QTabBar::RoundedEast || tabOpt->shape == QTabBar::TriangularEast;
2243 const bool leftCornerWidget = reverseLayout ?
2244 (tabOpt->cornerWidgets&QStyleOptionTab::RightCornerWidget) :
2245 (tabOpt->cornerWidgets&QStyleOptionTab::LeftCornerWidget);
2246 const bool rightCornerWidget = reverseLayout ?
2247 (tabOpt->cornerWidgets&QStyleOptionTab::LeftCornerWidget) :
2248 (tabOpt->cornerWidgets&QStyleOptionTab::RightCornerWidget);
2249 const bool isFirst = pos == QStyleOptionTab::Beginning || pos == QStyleOptionTab::OnlyOneTab/* (pos == First) || (pos == Single)*/;
2250 const bool isLast = pos == QStyleOptionTab::End /*(pos == Last)*/;
2251 const bool isSingle = pos == QStyleOptionTab::OnlyOneTab /*(pos == Single)*/;
2252 const bool isLeftOfSelected = reverseLayout ?
2253 (tabOpt->selectedPosition == QStyleOptionTab::PreviousIsSelected) :
2254 (tabOpt->selectedPosition == QStyleOptionTab::NextIsSelected);
2255 const bool isRightOfSelected = reverseLayout ?
2256 (tabOpt->selectedPosition == QStyleOptionTab::NextIsSelected) :
2257 (tabOpt->selectedPosition == QStyleOptionTab::PreviousIsSelected);
2258 const bool isLeftMost = (reverseLayout && !(westAlignment || eastAlignment) ?
2259 (tabOpt->position == QStyleOptionTab::End) :
2260 (tabOpt->position == QStyleOptionTab::Beginning)) ||
2261 tabOpt->position == QStyleOptionTab::OnlyOneTab;
2262 const bool isRightMost = reverseLayout && !(westAlignment || eastAlignment) ?
2263 (tabOpt->position == QStyleOptionTab::Beginning) :
2264 (tabOpt->position == QStyleOptionTab::End) ||
2265 tabOpt->position == QStyleOptionTab::OnlyOneTab;
2266 const bool isFrameAligned = reverseLayout && !(westAlignment || eastAlignment) ?
2267 (isRightMost && ! (tabOpt->cornerWidgets & QStyleOptionTab::LeftCornerWidget)) :
2268 (isLeftMost && ! (tabOpt->cornerWidgets & QStyleOptionTab::LeftCornerWidget));
2269 const QColor midColor = _helper.alphaColor(_helper.calcDarkColor(pal.color(QPalette::Window)), 0.4);
2270 const QColor darkColor = _helper.alphaColor(_helper.calcDarkColor(pal.color(QPalette::Window)), 0.6);
2272 if(northAlignment || southAlignment) {
2273 // the tab part of the tab - ie subtracted the fairing to the frame
2274 QRect Rc = southAlignment ? r.adjusted(0,6,0,0) : r.adjusted(0,0,0,-7);
2276 // the area where the fairing should appear
2277 const QRect Rb(r.x(), southAlignment?r.top():Rc.bottom()+1, r.width(), r.height()-Rc.height() );
2279 // FIXME - maybe going to redo tabs
2280 if (selected) {
2281 int x,y,w,h;
2282 r.getRect(&x, &y, &w, &h);
2283 // parts of the adjacent tabs
2284 if(!isSingle && ((!reverseLayout && !isFirst) || (reverseLayout && !isLast))) {
2285 p->setPen(darkColor);
2286 if(southAlignment) {
2287 p->fillRect(r.x(), r.y()+5, 2, r.height()-10, midColor);
2288 p->drawLine(QPointF(x, y+h-6), QPointF(x+2, y+h-6));
2290 else {
2291 p->fillRect(r.x(), r.y()+5, 2, r.height()-8, midColor);
2292 p->drawLine(QPointF(x, y+5), QPointF(x+2, y+5));
2295 if(!isSingle && ((!reverseLayout && !isLast) || (reverseLayout && !isFirst))) {
2296 p->setPen(darkColor);
2297 if(southAlignment) {
2298 p->fillRect(r.x()+r.width()-2, r.y()+5, 1, r.height()-10, midColor);
2299 p->drawLine(QPointF(x+w-3, y+h-6), QPointF(x+w-1, y+h-6));
2301 else {
2302 p->fillRect(r.x()+r.width()-2, r.y()+5, 1, r.height()-8, midColor);
2303 p->drawLine(QPointF(x+w-3, y+5), QPointF(x+w-1, y+5));
2307 if(southAlignment)
2308 renderSlab(p, Rc.adjusted(0,-7,0,0), pal.color(QPalette::Window), NoFill, TileSet::Bottom | TileSet::Left | TileSet::Right);
2309 else
2310 renderSlab(p, Rc.adjusted(0,0,0,7), pal.color(QPalette::Window), NoFill, TileSet::Top | TileSet::Left | TileSet::Right);
2312 // some "position specific" paintings...
2313 // First draw the left connection from the panel border to the tab
2314 if(isFirst && !reverseLayout && !leftCornerWidget) {
2315 renderSlab(p, Rb.adjusted(0,-7,0,7), pal.color(QPalette::Window), NoFill, TileSet::Left);
2316 } else {
2317 TileSet *tile = _helper.slabInverted(pal.color(QPalette::Window), 0.0);
2318 if(southAlignment)
2319 tile->render(QRect(Rb.left()-5, Rb.top()-1,12,13), p, TileSet::Right | TileSet::Top);
2320 else
2321 tile->render(QRect(Rb.left()-5, Rb.top()-5,12,12), p, TileSet::Right | TileSet::Bottom);
2324 // Now draw the right connection from the panel border to the tab
2325 if(isFirst && reverseLayout && !rightCornerWidget) {
2326 renderSlab(p, Rb.adjusted(0,-7,0,7), pal.color(QPalette::Window), NoFill, TileSet::Right);
2327 } else {
2328 TileSet *tile = _helper.slabInverted(pal.color(QPalette::Window), 0.0);
2329 //renderHole(p, QRect(Rb.right()-3, Rb.top(),3,5), false, false, TileSet::Left | TileSet::Bottom);
2330 if(southAlignment)
2331 tile->render(QRect(Rb.right()-6, Rb.top()-1,12,13), p, TileSet::Left | TileSet::Top);
2332 else
2333 tile->render(QRect(Rb.right()-6, Rb.top()-5,12,12), p, TileSet::Left | TileSet::Bottom);
2335 } else {
2336 // inactive tabs
2337 int x,y,w,h;
2338 p->setPen(darkColor);
2340 if (!southAlignment) {
2341 r.adjusted(0,4,0,0).getRect(&x, &y, &w, &h);
2342 if(isLeftMost) {
2343 p->drawArc(QRectF(x+2.5, y+0.5, 9.5, 9.5),90*16, 90*16);
2344 if(isFrameAligned)
2345 p->drawLine(QPointF(x+2.5, y+6.3), QPointF(x+2.5, y+h-2));
2346 else
2347 p->drawLine(QPointF(x+2.5, y+6.3), QPointF(x+2.5, y+h-6));
2348 // topline
2349 p->drawLine(QPointF(x+8.8, y+0.5), QPointF(x+w-1, y+0.5));
2350 if(!isLeftOfSelected)
2351 p->drawLine(QPointF(x+w-0.5, y+1.5), QPointF(x+w-0.5, y+h-6.3));
2352 p->fillRect(x+2, y+1, w-2, h-5, midColor);
2353 } else if(isRightMost) {
2354 p->drawArc(QRectF(x+w-9.5-2.5, y+0.5, 9.5, 9.5), 0, 90*16);
2355 if(isFrameAligned)
2356 p->drawLine(QPointF(x+w-2.5, y+6.3), QPointF(x+w-2.5, y+h+0.5));
2357 else
2358 p->drawLine(QPointF(x+w-2.5, y+6.3), QPointF(x+w-2.5, y+h-6.3));
2359 // topline
2360 p->drawLine(QPointF(x, y+0.5), QPointF(x+w-8.8, y+0.5));
2361 p->fillRect(x-1, y+1, w-1, h-5, midColor);
2362 } else {
2363 // topline
2364 p->drawLine(QPointF(x, y+0.5), QPointF(x+w-1, y+0.5));
2365 if(!isLeftOfSelected)
2366 p->drawLine(QPointF(x+w-0.5, y+1.5), QPointF(x+w-0.5, y+h-6.3));
2367 p->fillRect(x-1, y+1, w-1+2, h-5, midColor);
2370 else { // southAlignment
2371 r.adjusted(0,0,0,-6).getRect(&x, &y, &w, &h);
2372 if(isLeftMost) {
2373 p->drawArc(QRectF(x+2.5, y+h+0.2-9.5, 9.5, 9.5),180*16, 90*16);
2374 if(isFrameAligned)
2375 p->drawLine(QPointF(x+2.5, y+1.5), QPointF(x+2.5, y+h+3-9.5));
2376 else
2377 p->drawLine(QPointF(x+2.5, y+2+1.5), QPointF(x+2.5, y+h+3-9.5));
2378 // bottomline
2379 p->drawLine(QPointF(x+8.8, y+h), QPointF(x+w-1, y+h));
2380 if(!isLeftOfSelected)
2381 p->drawLine(QPointF(x+w-0.5, y+2+1.5), QPointF(x+w-0.5, y+h-1));
2382 p->fillRect(x+2, y+5, w-2, h-4, midColor);
2383 } else if(isRightMost) {
2384 p->drawArc(QRectF(x+w-9.5-2.5, y+h+0.2-9.5, 9.5, 9.5), 270*16, 90*16);
2385 if(isFrameAligned) // in reverseLayout mode
2386 p->drawLine(QPointF(x+w-2.5, y+1.5), QPointF(x+w-2.5, y+h-6.3));
2387 else
2388 p->drawLine(QPointF(x+w-2.5, y+2+1.5), QPointF(x+w-2.5, y+h-6.3));
2389 // bottomline
2390 p->drawLine(QPointF(x, y+h), QPointF(x+w-8.8, y+h));
2391 p->fillRect(x-1, y+5, w-1, h-4, midColor);
2392 } else {
2393 // bottomline
2394 p->drawLine(QPointF(x, y+h), QPointF(x+w-1, y+h));
2395 if(!isLeftOfSelected)
2396 p->drawLine(QPointF(x+w-0.5, y+2+1.5), QPointF(x+w-0.5, y+h-1));
2397 p->fillRect(x-1, y+5, w-1+2, h-4, midColor);
2404 TileSet::Tiles posFlag = southAlignment?TileSet::Bottom:TileSet::Top;
2405 QRect Ractual(Rb.left(), Rb.y(), Rb.width(), 6);
2407 if(isLeftMost) {
2408 if(isFrameAligned)
2409 posFlag |= TileSet::Left;
2410 // fix, to keep the mouseover line within the tabs (drawn) boundary
2411 if(reverseLayout || !isFrameAligned) {
2412 renderSlab(p, QRect(Ractual.left()-7, Ractual.y(), 2+14, Ractual.height()), pal.color(QPalette::Window), NoFill, posFlag);
2413 Ractual.adjust(-5,0,0,0);
2416 else
2417 Ractual.adjust(-7,0,0,0);
2419 if(isRightMost) {
2420 if(isFrameAligned)
2421 posFlag |= TileSet::Right;
2422 // fix, to keep the mouseover line within the tabs (drawn) boundary
2423 if(reverseLayout && !isFrameAligned) {
2424 renderSlab(p, QRect(Ractual.left()+Ractual.width()-2-7, Ractual.y(), 1+14, Ractual.height()), pal.color(QPalette::Window), NoFill, posFlag);
2425 Ractual.adjust(0,0,5,0);
2427 else if(!isFrameAligned) {
2428 renderSlab(p, QRect(Ractual.left()+Ractual.width()-2-7, Ractual.y(), 2+14, Ractual.height()), pal.color(QPalette::Window), NoFill, posFlag);
2429 Ractual.adjust(0,0,5,0);
2432 else
2433 Ractual.adjust(0,0,7,0);
2435 if (mouseOver)
2436 renderSlab(p, Ractual, pal.color(QPalette::Window), NoFill| Hover, posFlag);
2437 else
2438 renderSlab(p, Ractual, pal.color(QPalette::Window), NoFill, posFlag);
2441 // TODO mouseover effects
2444 // westAlignment and eastAlignment
2445 else {
2446 // the tab part of the tab - ie subtracted the fairing to the frame
2447 QRect Rc = eastAlignment ? r.adjusted(7,0,0,0) : r.adjusted(0,0,-7,0);
2448 // the area where the fairing should appear
2449 const QRect Rb(eastAlignment ? r.x() : Rc.width(), r.top(), r.width()-Rc.width(), r.height() );
2451 if (selected) {
2452 int x,y,w,h;
2453 r.getRect(&x, &y, &w, &h);
2455 // parts of the adjacent tabs
2456 if(!isSingle && ((!reverseLayout && !isFirst) || (reverseLayout && !isFirst))) {
2457 p->setPen(darkColor);
2458 if(eastAlignment) {
2459 p->fillRect(x+5, y, w-10, 2, midColor);
2460 p->drawLine(QPointF(x+w-5-1, y), QPointF(x+w-5-1, y+2));
2462 else {
2463 p->fillRect(x+5, y, w-10, 2, midColor);
2464 p->drawLine(QPointF(x+5, y), QPointF(x+5, y+2));
2467 if(!isSingle && ((!reverseLayout && !isLast) || (reverseLayout && !isLast))) {
2468 p->setPen(darkColor);
2469 if(eastAlignment) {
2470 p->fillRect(x+5, y+h-2, w-10, 2, midColor);
2471 p->drawLine(QPointF(x+w-5-1, y+h-2), QPointF(x+w-5-1, y+h-1));
2473 else {
2474 p->fillRect(x+5, y+h-2, w-10, 2, midColor);
2475 p->drawLine(QPointF(x+5, y+h-2-1), QPointF(x+5, y+h-1));
2479 if(eastAlignment)
2480 renderSlab(p, Rc.adjusted(-7,0,0,0), pal.color(QPalette::Window), NoFill, TileSet::Top | TileSet::Right | TileSet::Bottom);
2481 else
2482 renderSlab(p, Rc.adjusted(0,0,7,0), pal.color(QPalette::Window), NoFill, TileSet::Top | TileSet::Left | TileSet::Bottom);
2484 // some "position specific" paintings...
2485 // First draw the top connection from the panel border to the tab
2486 if(isFirst && !leftCornerWidget) {
2487 renderSlab(p, Rb.adjusted(-7,0,7,0), pal.color(QPalette::Window), NoFill, TileSet::Top);
2488 } else {
2489 TileSet *tile = _helper.slabInverted(pal.color(QPalette::Window), 0.0);
2490 if(eastAlignment)
2491 tile->render(QRect(Rb.left(), Rb.top()-6,12,13), p, TileSet::Left | TileSet::Bottom);
2492 else
2493 tile->render(QRect(Rb.left()-5, Rb.top()-5,12,12), p, TileSet::Right | TileSet::Bottom);
2496 // Now draw the bottom connection from the panel border to the tab
2497 TileSet *tile = _helper.slabInverted(pal.color(QPalette::Window), 0.0);
2498 if(eastAlignment)
2499 tile->render(QRect(Rb.right()-6, Rb.bottom()-6,12,13), p, TileSet::Left | TileSet::Top);
2500 else
2501 tile->render(QRect(Rb.right()-5-6, Rb.bottom()-6,12,12), p, TileSet::Right | TileSet::Top);
2504 else {
2505 // inactive tabs
2506 int x,y,w,h;
2507 p->setPen(darkColor);
2509 if (westAlignment) {
2510 Rc.adjusted(5,0,2,0).getRect(&x, &y, &w, &h);
2512 if(isLeftMost) { // at top
2513 p->drawArc(QRectF(x+0.5, y+1.5, 9.5, 9.5),90*16, 90*16);
2514 if(isFrameAligned)
2515 p->drawLine(QPointF(x-3+9.5, y+1.5), QPointF(x+w+1.5, y+1.5));
2516 else
2517 p->drawLine(QPointF(x-3+9.5, y+1.5), QPointF(x+w-1, y+1.5));
2518 // leftline
2519 p->drawLine(QPointF(x, y-3+9.5), QPointF(x, y+h-1));
2520 // separator
2521 if((!reverseLayout && !isLeftOfSelected) || (reverseLayout && !isRightOfSelected))
2522 p->drawLine(QPointF(x+1.5, y+h-1), QPointF(x+w-0.5, y+h-1));
2523 p->fillRect(x, y+2, w, h-2, midColor);
2524 } else if(isRightMost) { // at bottom
2525 p->drawArc(QRectF(x+0.5, y+h-0.5-9.5, 9.5, 9.5), 180*16, 90*16);
2526 if(isFrameAligned)
2527 p->drawLine(QPointF(x+9.5, y+h-1), QPointF(x+w, y+h-1));
2528 else
2529 p->drawLine(QPointF(x-4+9.5, y+h-1), QPointF(x+w-1, y+h-1));
2530 // leftline
2531 p->drawLine(QPointF(x, y), QPointF(x, y+h+3-9.5));
2532 p->fillRect(x, y, w, h, midColor);
2533 } else {
2534 // leftline
2535 p->drawLine(QPointF(x, y), QPointF(x, y+h-1));
2536 if((!reverseLayout && !isLeftOfSelected) || (reverseLayout && !isRightOfSelected))
2537 p->drawLine(QPointF(x+1.5, y+h-1), QPointF(x+w-0.5, y+h-1));
2538 p->fillRect(x, y, w, h, midColor);
2541 else { // eastAlignment
2543 Rc.adjusted(-2,0,-5,0).getRect(&x, &y, &w, &h);
2545 if(isLeftMost) { // at top
2546 p->drawArc(QRectF(x+w-0.5-9.5, y+1.5, 9.5, 9.5),0*16, 90*16);
2547 if(isFrameAligned)
2548 p->drawLine(QPointF(x-1.5, y+1.5), QPointF(x+w+3-9.5, y+1.5));
2549 else
2550 p->drawLine(QPointF(x, y+1.5), QPointF(x+w+3-9.5, y+1.5));
2551 // rightline
2552 p->drawLine(QPointF(x+w-1, y-3+9.5), QPointF(x+w-1, y+h-1));
2553 // separator
2554 if((!reverseLayout && !isLeftOfSelected) || (reverseLayout && !isRightOfSelected))
2555 p->drawLine(QPointF(x+0.5, y+h-1), QPointF(x+w-1.5, y+h-1));
2556 p->fillRect(x, y+2, w, h-2, midColor);
2557 } else if(isRightMost) { // at bottom
2558 p->drawArc(QRectF(x+w-9.5-0.5, y+h-0.5-9.5, 9.5, 9.5), 270*16, 90*16);
2559 if(isFrameAligned) // in reverseLayout mode
2560 p->drawLine(QPointF(x-2.5, y+h-1), QPointF(x+w+3-9.5, y+h-1));
2561 else
2562 p->drawLine(QPointF(x+0.5, y+h-1), QPointF(x+w+4-9.5, y+h-1));
2563 // rightline
2564 p->drawLine(QPointF(x+w-1, y), QPointF(x+w-1, y+h+3-9.5));
2565 p->fillRect(x, y, w, h, midColor);
2566 } else {
2567 // rightline
2568 p->drawLine(QPointF(x+w-1, y), QPointF(x+w-1, y+h-1));
2569 if((!reverseLayout && !isLeftOfSelected) || (reverseLayout && !isRightOfSelected))
2570 p->drawLine(QPointF(x+0.5, y+h-1), QPointF(x+w-1.5, y+h-1));
2571 p->fillRect(x, y, w, h, midColor);
2576 TileSet::Tiles posFlag = eastAlignment ? TileSet::Right : TileSet::Left;
2577 QRect Ractual(Rb.left(), Rb.y(), 7, Rb.height());
2579 if(isLeftMost) { // at top
2580 if(isFrameAligned)
2581 posFlag |= TileSet::Top;
2582 else {
2583 renderSlab(p, QRect(Ractual.left(), Ractual.y()-7, Ractual.width(), 2+14), pal.color(QPalette::Window), NoFill, posFlag);
2584 Ractual.adjust(0,-5,0,0);
2587 else
2588 Ractual.adjust(0,-7,0,0);
2590 if(isRightMost) { // at bottom
2591 if(isFrameAligned && !reverseLayout)
2592 posFlag |= TileSet::Top;
2593 Ractual.adjust(0,0,0,7);
2595 else
2596 Ractual.adjust(0,0,0,7);
2598 if (mouseOver)
2599 renderSlab(p, Ractual, pal.color(QPalette::Window), NoFill| Hover, posFlag);
2600 else
2601 renderSlab(p, Ractual, pal.color(QPalette::Window), NoFill, posFlag);
2603 // TODO mouseover effects
2609 int OxygenStyle::styleHint(StyleHint hint, const QStyleOption * option,
2610 const QWidget * widget, QStyleHintReturn * returnData) const
2612 switch (hint) {
2613 case SH_Menu_SubMenuPopupDelay:
2614 return 96; // Motif-like delay...
2616 case SH_ScrollView_FrameOnlyAroundContents:
2617 return true;
2619 case SH_ItemView_ShowDecorationSelected:
2620 return true;
2622 case SH_RubberBand_Mask:
2624 const QStyleOptionRubberBand *opt = qstyleoption_cast<const QStyleOptionRubberBand *>(option);
2625 if (!opt)
2626 return true;
2627 if (QStyleHintReturnMask *mask = qstyleoption_cast<QStyleHintReturnMask*>(returnData))
2628 mask->region = option->rect;
2629 return true;
2631 default:
2632 return KStyle::styleHint(hint, option, widget, returnData);
2636 int OxygenStyle::pixelMetric(PixelMetric m, const QStyleOption *opt, const QWidget *widget) const
2638 switch(m) {
2639 case PM_DefaultTopLevelMargin:
2640 return 11;
2642 case PM_DefaultChildMargin:
2643 return 4; // qcommon is 9;
2645 case PM_DefaultLayoutSpacing:
2646 return 4; // qcommon is 6
2648 case PM_DefaultFrameWidth:
2649 if (qobject_cast<const QLineEdit*>(widget))
2650 return 5;
2651 if (qobject_cast<const QFrame*>(widget) || qobject_cast<const QComboBox*>(widget))
2652 return 3;
2653 //else fall through
2654 default:
2655 return KStyle::pixelMetric(m,opt,widget);
2660 QSize OxygenStyle::sizeFromContents(ContentsType type, const QStyleOption* option, const QSize& contentsSize, const QWidget* widget) const
2662 switch(type)
2664 case CT_ToolButton:
2666 // We want to avoid super-skiny buttons, for things like "up" when icons + text
2667 // For this, we would like to make width >= height.
2668 // However, once we get here, QToolButton may have already put in the menu area
2669 // (PM_MenuButtonIndicator) into the width. So we may have to take it out, fix things
2670 // up, and add it back in. So much for class-independent rendering...
2671 QSize size = contentsSize;
2673 if (const QStyleOptionToolButton* tbOpt = qstyleoption_cast<const QStyleOptionToolButton*>(option)) {
2674 if ((!tbOpt->icon.isNull()) && (!tbOpt->text.isEmpty()) && tbOpt->toolButtonStyle == Qt::ToolButtonTextUnderIcon)
2675 size.setHeight(size.height()-9);
2677 return KStyle::sizeFromContents(type, option, size, widget);
2679 default:
2680 break;
2682 return KStyle::sizeFromContents(type, option, contentsSize, widget);
2686 QRect OxygenStyle::subControlRect(ComplexControl control, const QStyleOptionComplex* option,
2687 SubControl subControl, const QWidget* widget) const
2689 QRect r = option->rect;
2691 switch (control)
2693 case CC_GroupBox:
2695 const QStyleOptionGroupBox *gbOpt = qstyleoption_cast<const QStyleOptionGroupBox *>(option);
2696 if (!gbOpt)
2697 break;
2699 bool isFlat = gbOpt->features & QStyleOptionFrameV2::Flat;
2701 switch (subControl)
2703 case SC_GroupBoxFrame:
2704 return r;
2705 case SC_GroupBoxContents:
2707 int th = gbOpt->fontMetrics.height() + 8;
2708 QRect cr = subElementRect(SE_CheckBoxIndicator, option, widget);
2709 int fw = widgetLayoutProp(WT_GroupBox, GroupBox::FrameWidth, option, widget);
2711 r.adjust(fw,fw + qMax(th, cr.height()), -fw, -fw);
2713 // add additional indentation to flat group boxes
2714 if (isFlat)
2716 int leftMarginExtension = 16;
2717 r = visualRect(option->direction,r,r.adjusted(leftMarginExtension,0,0,0));
2720 return r;
2722 case SC_GroupBoxCheckBox:
2723 case SC_GroupBoxLabel:
2725 QFont font = widget->font();
2726 // calculate text width assuming bold text in flat group boxes
2727 if (isFlat)
2728 font.setBold(true);
2730 QFontMetrics fontMetrics = QFontMetrics(font);
2731 int h = fontMetrics.height();
2732 int tw = fontMetrics.size(Qt::TextShowMnemonic, gbOpt->text + QLatin1String(" ")).width();
2733 r.setHeight(h);
2734 r.moveTop(8);
2735 QRect cr;
2736 if(gbOpt->subControls & QStyle::SC_GroupBoxCheckBox)
2738 cr = subElementRect(SE_CheckBoxIndicator, option, widget);
2739 QRect gcr((gbOpt->rect.width() - tw -cr.width())/2 , (h-cr.height())/2+r.y(), cr.width(), cr.height());
2740 if(subControl == SC_GroupBoxCheckBox)
2741 return visualRect(option->direction, option->rect, gcr);
2744 // left align labels in flat group boxes, center align labels in framed group boxes
2745 if (isFlat)
2746 r = QRect(0,r.y(),tw,r.height());
2747 else
2748 r = QRect((gbOpt->rect.width() - tw - cr.width())/2 + cr.width(), r.y(), tw, r.height());
2750 return visualRect(option->direction, option->rect, r);
2752 default:
2753 break;
2755 break;
2757 default:
2758 break;
2761 return KStyle::subControlRect(control, option, subControl, widget);
2764 QRect OxygenStyle::subElementRect(SubElement sr, const QStyleOption *opt, const QWidget *widget) const
2766 QRect r;
2768 switch (sr) {
2769 case SE_TabWidgetTabBar: {
2770 const QStyleOptionTabWidgetFrame *twf = qstyleoption_cast<const QStyleOptionTabWidgetFrame *>(opt);
2771 if(!twf) return QRect();
2772 r = QRect(QPoint(0,0), twf->tabBarSize);
2774 switch (twf->shape) {
2775 case QTabBar::RoundedNorth:
2776 case QTabBar::TriangularNorth: {
2777 r.setWidth(qMin(r.width(), twf->rect.width()
2778 - twf->leftCornerWidgetSize.width()
2779 - twf->rightCornerWidgetSize.width()));
2780 r.moveTopLeft(QPoint(twf->leftCornerWidgetSize.width(), 0));
2781 r = visualRect(twf->direction, twf->rect, r);
2782 break;
2784 case QTabBar::RoundedSouth:
2785 case QTabBar::TriangularSouth: {
2786 r.setWidth(qMin(r.width(), twf->rect.width()
2787 - twf->leftCornerWidgetSize.width()
2788 - twf->rightCornerWidgetSize.width()));
2789 r.moveTopLeft(QPoint(twf->leftCornerWidgetSize.width(),
2790 twf->rect.height() - twf->tabBarSize.height()));
2791 r = visualRect(twf->direction, twf->rect, r);
2792 break;
2794 case QTabBar::RoundedEast:
2795 case QTabBar::TriangularEast: {
2796 r.setHeight(qMin(r.height(), twf->rect.height()
2797 - twf->leftCornerWidgetSize.height()
2798 - twf->rightCornerWidgetSize.height()));
2799 r.moveTopLeft(QPoint(twf->rect.width() - twf->tabBarSize.width(),
2800 twf->leftCornerWidgetSize.height()));
2801 break;
2803 case QTabBar::RoundedWest:
2804 case QTabBar::TriangularWest: {
2805 r.setHeight(qMin(r.height(), twf->rect.height()
2806 - twf->leftCornerWidgetSize.height()
2807 - twf->rightCornerWidgetSize.height()));
2808 r.moveTopLeft(QPoint(0, twf->leftCornerWidgetSize.height()));
2810 break;
2812 return r;
2815 case SE_TabWidgetLeftCorner: {
2816 const QStyleOptionTabWidgetFrame *twf = qstyleoption_cast<const QStyleOptionTabWidgetFrame *>(opt);
2817 if(!twf) return QRect();
2819 QRect paneRect = subElementRect(SE_TabWidgetTabPane, twf, widget);
2820 switch (twf->shape) {
2821 case QTabBar::RoundedNorth:
2822 case QTabBar::TriangularNorth:
2823 r = QRect(QPoint(paneRect.x(), paneRect.y() - twf->leftCornerWidgetSize.height()), twf->leftCornerWidgetSize);
2824 r = visualRect(twf->direction, twf->rect, r);
2825 break;
2826 case QTabBar::RoundedSouth:
2827 case QTabBar::TriangularSouth:
2828 r = QRect(QPoint(paneRect.x(), paneRect.height()), twf->leftCornerWidgetSize);
2829 r = visualRect(twf->direction, twf->rect, r);
2830 break;
2831 case QTabBar::RoundedWest:
2832 case QTabBar::TriangularWest:
2833 r = QRect(QPoint(paneRect.x() - twf->leftCornerWidgetSize.width(), paneRect.y()), twf->leftCornerWidgetSize);
2834 break;
2835 case QTabBar::RoundedEast:
2836 case QTabBar::TriangularEast:
2837 r = QRect(QPoint(paneRect.x() + paneRect.width(), paneRect.y()), twf->leftCornerWidgetSize);
2838 break;
2839 default:
2840 break;
2843 return r;
2846 case SE_TabWidgetRightCorner: {
2847 const QStyleOptionTabWidgetFrame *twf = qstyleoption_cast<const QStyleOptionTabWidgetFrame *>(opt);
2848 if(!twf) return QRect();
2850 QRect paneRect = subElementRect(SE_TabWidgetTabPane, twf, widget);
2851 switch (twf->shape) {
2852 case QTabBar::RoundedNorth:
2853 case QTabBar::TriangularNorth:
2854 r = QRect(QPoint(paneRect.width() - twf->rightCornerWidgetSize.width(), paneRect.y() - twf->rightCornerWidgetSize.height()), twf->rightCornerWidgetSize);
2855 r = visualRect(twf->direction, twf->rect, r);
2856 break;
2857 case QTabBar::RoundedSouth:
2858 case QTabBar::TriangularSouth:
2859 r = QRect(QPoint(paneRect.width() - twf->rightCornerWidgetSize.width(), paneRect.height()), twf->rightCornerWidgetSize);
2860 r = visualRect(twf->direction, twf->rect, r);
2861 break;
2862 case QTabBar::RoundedWest:
2863 case QTabBar::TriangularWest:
2864 r = QRect(QPoint(paneRect.x() - twf->rightCornerWidgetSize.width(), paneRect.y() + paneRect.height() - twf->rightCornerWidgetSize.height()), twf->rightCornerWidgetSize);
2865 break;
2866 case QTabBar::RoundedEast:
2867 case QTabBar::TriangularEast:
2868 r = QRect(QPoint(paneRect.x() + paneRect.width(), paneRect.y() + paneRect.height() - twf->rightCornerWidgetSize.height()), twf->rightCornerWidgetSize);
2869 break;
2870 default:
2871 break;
2874 return r;
2876 case SE_TabBarTearIndicator: {
2877 const QStyleOptionTab *option = qstyleoption_cast<const QStyleOptionTab *>(opt);
2878 if(!option) return QRect();
2880 switch (option->shape) {
2881 case QTabBar::RoundedNorth:
2882 case QTabBar::TriangularNorth:
2883 case QTabBar::RoundedSouth:
2884 case QTabBar::TriangularSouth:
2885 r.setRect(option->rect.left(), option->rect.top(), 8, option->rect.height());
2886 break;
2887 case QTabBar::RoundedWest:
2888 case QTabBar::TriangularWest:
2889 case QTabBar::RoundedEast:
2890 case QTabBar::TriangularEast:
2891 r.setRect(option->rect.left(), option->rect.top(), option->rect.width(), 8);
2892 break;
2893 default:
2894 break;
2896 r = visualRect(opt->direction, opt->rect, r);
2897 return r;
2899 default:
2900 return KStyle::subElementRect(sr, opt, widget);
2905 bool OxygenStyle::eventFilter(QObject *obj, QEvent *ev)
2907 if (KStyle::eventFilter(obj, ev) )
2908 return true;
2910 // Track show events for progress bars
2911 if ( _animateProgressBar && qobject_cast<QProgressBar*>(obj) )
2913 if ((ev->type() == QEvent::Show) && !animationTimer->isActive())
2915 animationTimer->start( 50 );
2919 if (QToolBar *t = qobject_cast<QToolBar*>(obj))
2921 switch(ev->type()) {
2922 case QEvent::Show:
2923 case QEvent::Resize: {
2924 int x, y, w, h;
2925 t->rect().getRect(&x, &y, &w, &h);
2926 QRegion reg(x+4, y, w-8, h);
2927 reg += QRegion(x, y+4, w, h-8);
2928 reg += QRegion(x+2, y+1, w-4, h-2);
2929 reg += QRegion(x+1, y+2, w-2, h-4);
2930 if(t->mask() != reg)
2931 t->setMask(reg);
2932 return false;
2934 default:
2935 return false;
2939 if (QMenu *m = qobject_cast<QMenu*>(obj))
2941 switch(ev->type()) {
2942 case QEvent::Show:
2943 case QEvent::Resize: {
2944 int x, y, w, h;
2945 m->rect().getRect(&x, &y, &w, &h);
2946 QRegion reg(x+4, y, w-8, h);
2947 reg += QRegion(x, y+4, w, h-8);
2948 reg += QRegion(x+2, y+1, w-4, h-2);
2949 reg += QRegion(x+1, y+2, w-2, h-4);
2950 if(m->mask() != reg)
2951 m->setMask(reg);
2952 return false;
2954 case QEvent::Paint:
2956 QPainter p(m);
2957 QPaintEvent *e = (QPaintEvent*)ev;
2958 QRect r = m->rect();
2959 QColor color = m->palette().color(QPalette::Background);
2960 int splitY = qMin(200, 3*r.height()/4);
2962 p.setClipRegion(e->region());
2964 QRect upperRect = QRect(0, 0, r.width(), splitY);
2965 QPixmap tile = _helper.verticalGradient(color, splitY);
2966 p.drawTiledPixmap(upperRect, tile);
2968 QRect lowerRect = QRect(0,splitY, r.width(), r.height() - splitY);
2969 p.fillRect(lowerRect, _helper.backgroundBottomColor(color));
2970 return false;
2972 default:
2973 return false;
2977 if (static_cast<QWidget*>(obj)->isWindow()) {
2978 if (ev->type() == QEvent::Paint)
2980 QWidget *widget = static_cast<QWidget*>(obj);
2981 QBrush brush = widget->palette().brush(widget->backgroundRole());
2982 // don't use our background if the app requested something else,
2983 // e.g. a pixmap
2984 // TODO - draw our light effects over an arbitrary fill?
2985 if (brush.style() == Qt::SolidPattern &&
2986 !widget->testAttribute(Qt::WA_NoSystemBackground)) {
2987 QPainter p(widget);
2988 QPaintEvent *e = (QPaintEvent*)ev;
2989 p.setClipRegion(e->region());
2990 renderWindowBackground(&p, e->rect(), widget);
2995 if (QDockWidget*dw = qobject_cast<QDockWidget*>(obj))
2997 if (ev->type() == QEvent::Show || ev->type() == QEvent::Resize)
2999 int x, y, w, h;
3000 dw->rect().getRect(&x, &y, &w, &h);
3001 QRegion reg(x+4, y, w-8, h);
3002 reg += QRegion(x, y+4, w, h-8);
3003 reg += QRegion(x+2, y+1, w-4, h-2);
3004 reg += QRegion(x+1, y+2, w-2, h-4);
3005 if(dw->mask() != reg)
3006 dw->setMask(reg);
3007 return false;
3009 if (ev->type() == QEvent::Paint)
3011 QPainter p(dw);
3012 if(dw->isWindow())
3014 _helper.drawFloatFrame(&p, dw->rect(), dw->palette().color(QPalette::Window));
3015 return false;
3018 int x,y,w,h;
3020 dw->rect().getRect(&x, &y, &w, &h);
3022 h--;
3023 p.setPen(QColor(0,0,0, 30));
3024 p.drawLine(QPointF(6.3, 0.5), QPointF(w-6.3, 0.5));
3025 p.drawArc(QRectF(0.5, 0.5, 9.5, 9.5),90*16, 90*16);
3026 p.drawArc(QRectF(w-9.5-0.5, 0.5, 9.5, 9.5), 0, 90*16);
3027 p.drawLine(QPointF(0.5, 6.3), QPointF(0.5, h-6.3));
3028 p.drawLine(QPointF(w-0.5, 6.3), QPointF(w-0.5, h-6.3));
3029 p.drawArc(QRectF(0.5, h-9.5-0.5, 9.5, 9.5),180*16, 90*16);
3030 p.drawArc(QRectF(w-9.5-0.5, h-9.5-0.5, 9.5, 9.5), 270*16, 90*16);
3031 p.drawLine(QPointF(6.3, h-0.5), QPointF(w-6.3, h-0.5));
3032 return false;
3036 if (QToolBox *tb = qobject_cast<QToolBox*>(obj))
3038 if (ev->type() == QEvent::Paint)
3040 QRect r = tb->rect();
3041 StyleOptions opts = NoFill;
3043 QPainter p(tb);
3044 p.setClipRegion(((QPaintEvent*)ev)->region());
3045 renderSlab(&p, r, tb->palette().color(QPalette::Button), opts);
3046 return false;
3048 return false;
3051 return false;
3054 QIcon OxygenStyle::standardIconImplementation(StandardPixmap standardIcon, const QStyleOption *option,
3055 const QWidget *widget) const
3057 // get button color (unfortunately option and widget might not be set)
3058 QColor buttonColor;
3059 if (option)
3060 buttonColor = option->palette.button().color();
3061 else if (widget)
3062 buttonColor = widget->palette().button().color();
3063 else if (qApp) // might not have a QApplication
3064 buttonColor = qApp->palette().button().color();
3065 else // KCS is always safe
3066 buttonColor = KColorScheme(QPalette::Active, KColorScheme::Button,
3067 _config).background().color();
3069 switch (standardIcon) {
3070 case SP_TitleBarNormalButton:
3072 QPixmap realpm(pixelMetric(QStyle::PM_SmallIconSize,0,0), pixelMetric(QStyle::PM_SmallIconSize,0,0));
3073 realpm.fill(QColor(0,0,0,0));
3074 QPixmap pm = _helper.windecoButton(buttonColor, 5);
3075 QPainter painter(&realpm);
3076 painter.drawPixmap(1,1,pm);
3077 painter.setRenderHints(QPainter::Antialiasing);
3078 painter.setBrush(Qt::NoBrush);
3079 QLinearGradient lg = _helper.decoGradient(QRect(3,3,11,11), QColor(0,0,0));
3080 painter.setPen(QPen(lg,1.4));
3081 QPointF points[4] = {QPointF(8.5, 6), QPointF(11, 8.5), QPointF(8.5, 11), QPointF(6, 8.5)};
3082 painter.drawPolygon(points, 4);
3084 return QIcon(realpm);
3087 case SP_TitleBarCloseButton:
3088 case SP_DockWidgetCloseButton:
3090 QPixmap realpm(pixelMetric(QStyle::PM_SmallIconSize,0,0), pixelMetric(QStyle::PM_SmallIconSize,0,0));
3091 realpm.fill(QColor(0,0,0,0));
3092 QPixmap pm = _helper.windecoButton(buttonColor,5);
3093 QPainter painter(&realpm);
3094 painter.drawPixmap(1,1,pm);
3095 painter.setRenderHints(QPainter::Antialiasing);
3096 painter.setBrush(Qt::NoBrush);
3097 QLinearGradient lg = _helper.decoGradient(QRect(3,3,11,11), QColor(0,0,0));
3098 painter.setPen(QPen(lg,1.4));
3099 painter.drawLine( QPointF(6.5,6.5), QPointF(11.0,11.0) );
3100 painter.drawLine( QPointF(11.0,6.5), QPointF(6.5,11.0) );
3102 return QIcon(realpm);
3104 default:
3105 return KStyle::standardPixmap(standardIcon, option, widget);
3109 void OxygenStyle::renderWindowBackground(QPainter *p, const QRect &clipRect, const QWidget *widget) const
3111 QRect r = widget->rect();
3112 QColor color = widget->palette().color(widget->backgroundRole());
3113 int splitY = qMin(300, 3*r.height()/4);
3115 QRect upperRect = QRect(0, 0, r.width(), splitY);
3116 QPixmap tile = _helper.verticalGradient(color, splitY);
3117 p->drawTiledPixmap(upperRect, tile);
3119 QRect lowerRect = QRect(0,splitY, r.width(), r.height() - splitY);
3120 p->fillRect(lowerRect, _helper.backgroundBottomColor(color));
3122 int radialW = qMin(600, r.width());
3123 int frameH = 32; // on first paint the frame may not have been done yet, so just fixate it
3124 QRect radialRect = QRect((r.width() - radialW) / 2, 0, radialW, 64-frameH);
3125 if (clipRect.intersects(radialRect))
3127 tile = _helper.radialGradient(color, radialW);
3128 p->drawPixmap(radialRect, tile, QRect(0, frameH, radialW, 64-frameH));
3132 // kate: indent-width 4; replace-tabs on; tab-width 4; space-indent on;