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.
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>
56 #include <QAbstractScrollArea>
57 #include <QAbstractItemView>
59 #include <QtDBus/QtDBus>
62 #include <KGlobalSettings>
63 #include <KConfigGroup>
64 #include <KColorUtils>
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() :
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",
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
)) {
211 _menuHighlightMode
= MM_STRONG
;
214 _menuHighlightMode
= MM_SUBTLE
;
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()
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());
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())
257 animationTimer
->stop();
261 OxygenStyle::~OxygenStyle()
264 void OxygenStyle::drawComplexControl(ComplexControl control
,const QStyleOptionComplex
*option
, QPainter
*painter
, const QWidget
*widget
) const
270 if (const QStyleOptionGroupBox
*groupBox
= qstyleoption_cast
<const QStyleOptionGroupBox
*>(option
))
272 bool isFlat
= groupBox
->features
& QStyleOptionFrameV2::Flat
;
276 QFont font
= painter
->font();
278 painter
->setFont(font
);
287 return KStyle::drawComplexControl(control
,option
,painter
,widget
);
290 void OxygenStyle::drawControl(ControlElement element
, const QStyleOption
*option
, QPainter
*p
, const QWidget
*widget
) const
296 if (const QStyleOptionRubberBand
*rbOpt
= qstyleoption_cast
<const QStyleOptionRubberBand
*>(option
))
299 QColor color
= rbOpt
->palette
.color(QPalette::Highlight
);
302 color
= KColorUtils::mix(color
, rbOpt
->palette
.color(QPalette::Active
, QPalette::WindowText
));
304 p
->setClipRegion(rbOpt
->rect
);
305 p
->drawRect(rbOpt
->rect
.adjusted(0,0,-1,-1));
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
));
334 case PushButton::Panel
:
336 if ((flags
& State_On
) || (flags
& State_Sunken
))
338 if (flags
& State_HasFocus
)
340 if (enabled
&& (flags
& State_MouseOver
))
343 renderSlab(p
, r
, pal
.color(QPalette::Button
), opts
);
347 case PushButton::DefaultButtonFrame
:
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
);
367 if (v2
&& v2
->position
== QStyleOptionToolBoxV2::Beginning
)
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
);
378 int y
= r
.height()*15/100;
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));
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);
399 p
->setRenderHint(QPainter::Antialiasing
, false);
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);
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);
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);
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);
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
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());
440 p
->setClipRect(rect
.adjusted(-32,0,32,0));
441 tiles1
->render(rect
, p
, TileSet::Left
| TileSet::Vertical
| TileSet::Right
);
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());
454 p
->setClipRect(rect
.adjusted(-32,0,32,0));
455 tiles1
->render(rect
, p
, TileSet::Left
| TileSet::Vertical
| TileSet::Right
);
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...
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
);
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
);
491 case MenuBar::EmptyArea
:
503 case MenuBarItem::Panel
:
505 bool active
= flags
& State_Selected
;
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
);
514 color
= KColorUtils::mix(color
, KColorUtils::tint(color
, pal
.color(QPalette::Highlight
), 0.6));
517 if (_menuHighlightMode
== MM_STRONG
)
518 color
= KColorUtils::tint(color
, _viewHoverBrush
.brush(pal
).color());
520 color
= KColorUtils::mix(color
, KColorUtils::tint(color
, _viewHoverBrush
.brush(pal
).color()));
524 color
= _helper
.calcMidColor(color
);
527 _helper
.holeFlat(color
, 0.0)->render(r
.adjusted(2,2,-2,-2), p
, TileSet::Full
);
535 KStyle::TextOption
* textOpts
= extractOption
<KStyle::TextOption
*>(kOpt
);
538 if (_menuHighlightMode
== MM_STRONG
&& flags
& State_Sunken
)
539 p
->setPen(pal
.color(QPalette::HighlightedText
));
541 p
->setPen(pal
.color(QPalette::WindowText
));
542 drawItemText(p
, r
, Qt::AlignVCenter
| Qt::TextShowMnemonic
| textOpts
->hAlign
, pal
, flags
& State_Enabled
,
558 _helper
.drawFloatFrame(p
, r
, pal
.window().color());
562 case Menu::Background
:
564 // we paint in the eventFilter instead so we can paint in the border too
570 // TODO: See Keramik...
588 case MenuItem::Separator
:
590 QColor color
= pal
.color(QPalette::Window
);
591 QColor light
= _helper
.calcLightColor(color
);
592 QColor dark
= _helper
.calcDarkColor(color
);
594 p
->setRenderHint(QPainter::Antialiasing
);
596 QLinearGradient
lg(r
.x(),0,r
.right(),0);
597 lg
.setColorAt(0.5, dark
);
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
);
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));
618 case MenuItem::ItemIndicator
:
621 QPixmap
pm(r
.size());
622 pm
.fill(Qt::transparent
);
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));
632 color
= _helper
.calcMidColor(color
);
633 pp
.setRenderHint(QPainter::Antialiasing
);
634 pp
.setPen(Qt::NoPen
);
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
);
649 p
->drawPixmap(r
, pm
);
652 drawKStylePrimitive(WT_Generic
, Generic::FocusIndicator
, opt
, r
, pal
, flags
, p
, widget
, kOpt
);
660 KStyle::TextOption
* textOpts
= extractOption
<KStyle::TextOption
*>(kOpt
);
663 if (_menuHighlightMode
== MM_STRONG
&& flags
& State_Selected
)
664 p
->setPen(pal
.color(QPalette::HighlightedText
));
666 p
->setPen(pal
.color(QPalette::WindowText
));
667 drawItemText(p
, r
, Qt::AlignVCenter
| Qt::TextShowMnemonic
| textOpts
->hAlign
, pal
, flags
& State_Enabled
,
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
683 case MenuItem::CheckColumn
:
689 case MenuItem::CheckOn
:
691 renderCheckBox(p
, r
.adjusted(2,-2,2,2), pal
, enabled
, false, mouseOver
, CheckBox::CheckOn
, true);
695 case MenuItem::CheckOff
:
697 renderCheckBox(p
, r
.adjusted(2,-2,2,2), pal
, enabled
, false, mouseOver
, CheckBox::CheckOff
, true);
701 case MenuItem::RadioOn
:
703 renderRadioButton(p
, r
, pal
, enabled
, mouseOver
, RadioButton::RadioOn
, true);
707 case MenuItem::RadioOff
:
709 renderRadioButton(p
, r
, pal
, enabled
, mouseOver
, RadioButton::RadioOff
, true);
713 case MenuItem::CheckIcon
:
728 const QStyleOptionDockWidget
* dwOpt
= ::qstyleoption_cast
<const QStyleOptionDockWidget
*>(opt
);
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());
745 r
.setRight(btnr
.x());
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();
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
);
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
));
777 drawItemText(p
, r
, (reverseLayout
? Qt::AlignRight
: Qt::AlignLeft
) | Qt::AlignVCenter
778 | Qt::TextShowMnemonic
, dwOpt
->palette
, dwOpt
->state
& State_Enabled
, title
,
779 QPalette::WindowText
);
785 // Don't do anything here as it interferes with custom titlewidgets
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
797 case DockWidget::SeparatorHandle
:
798 if (flags
&State_Horizontal
)
799 drawKStylePrimitive(WT_Splitter
, Splitter::HandleVert
, opt
, r
, pal
, flags
, p
, widget
);
801 drawKStylePrimitive(WT_Splitter
, Splitter::HandleHor
, opt
, r
, pal
, flags
, p
, widget
);
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
);
840 case RadioButton::RadioOn
:
841 case RadioButton::RadioOff
:
843 renderRadioButton(p
, r
, pal
, enabled
, mouseOver
, 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
);
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
);
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
);
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
);
875 case ScrollBar::GrooveAreaVertTop
:
877 renderHole(p
, pal
.color(QPalette::Window
), r
.adjusted(0,2,0,12),
878 false, false, TileSet::Left
| TileSet::Right
);
882 case ScrollBar::GrooveAreaVertBottom
:
884 renderHole(p
, pal
.color(QPalette::Window
), r
.adjusted(0,-10,0,0), false, false,
885 TileSet::Left
| TileSet::Right
);
889 case ScrollBar::GrooveAreaHorLeft
:
891 renderHole(p
, pal
.color(QPalette::Window
), r
.adjusted(2,0,12,0), false, false,
892 TileSet::Top
| TileSet::Bottom
);
896 case ScrollBar::GrooveAreaHorRight
:
898 renderHole(p
, pal
.color(QPalette::Window
), r
.adjusted(-10,0,0,0), false, false,
899 TileSet::Top
| TileSet::Bottom
);
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);
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
);
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);
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
);
964 const QStyleOptionTabV2
* tabOpt
= qstyleoption_cast
<const QStyleOptionTabV2
*>(opt
);
968 case TabBar::NorthTab
:
969 case TabBar::SouthTab
:
970 case TabBar::WestTab
:
971 case TabBar::EastTab
:
975 renderTab(p
, r
, pal
, mouseOver
, flags
&State_Selected
, tabOpt
, reverseLayout
);
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
);
987 img
= img
.transformed(QMatrix().rotate(primitive
== TabBar::WestText
? -90 : 90));
988 p
->drawImage(r
.x(), r
.y(), img
);
991 case TabBar::IndicatorTear
:
993 const QStyleOptionTab
* option
= qstyleoption_cast
<const QStyleOptionTab
*>(opt
);
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);
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
);
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);
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);
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);
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);
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);
1047 flag
= TileSet::Right
;
1048 rect
= QRect(r
.x(), r
.y()-7, 7, 4+14);
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);
1064 gr
= QRect(r
.x(), 0, r
.x()+r
.width(), 0);
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);
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())
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())
1100 fr
.setLeft(tabOpt
->tabBarRect
.right());
1101 fr
.adjust(-7,0,7,-1);
1102 renderSlab(p
, fr
, pal
.color(QPalette::Window
), NoFill
, TileSet::Top
);
1106 case QTabBar::RoundedSouth
:
1107 case QTabBar::TriangularSouth
:
1109 if (r
.left() < tabOpt
->tabBarRect
.left())
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())
1119 fr
.setLeft(tabOpt
->tabBarRect
.right());
1120 fr
.adjust(-6,0,7,-1);
1121 renderSlab(p
, fr
, pal
.color(QPalette::Window
), NoFill
, TileSet::Bottom
);
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
);
1156 // Left and right widgets are placed right and left when in reverse mode
1159 renderSlab(p
, QRect(0, r
.y(), r
.width() - w
- lw
+7, 7),
1160 pal
.color(QPalette::Window
), NoFill
, TileSet::Left
| TileSet::Top
);
1162 renderSlab(p
, QRect(0, r
.y(), r
.width(), 7), pal
.color(QPalette::Window
), NoFill
,
1163 TileSet::Left
| TileSet::Top
| TileSet::Right
);
1166 renderSlab(p
, QRect(r
.right() - lw
-7, r
.y(), lw
+7, 7),
1167 pal
.color(QPalette::Window
), NoFill
, TileSet::Top
| TileSet::Right
);
1172 renderSlab(p
, QRect(0, r
.y(), lw
+7, 7), pal
.color(QPalette::Window
), NoFill
,
1173 TileSet::Left
| TileSet::Top
);
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
);
1179 renderSlab(p
, QRect(0, r
.y(), r
.width(), 7), pal
.color(QPalette::Window
), NoFill
,
1180 TileSet::Left
| TileSet::Top
| TileSet::Right
);
1185 case QTabBar::RoundedSouth
:
1186 case QTabBar::TriangularSouth
:
1187 renderSlab(p
, r
, pal
.color(QPalette::Window
), NoFill
,
1188 TileSet::Left
| TileSet::Top
| TileSet::Right
);
1191 // Left and right widgets are placed right and left when in reverse mode
1194 renderSlab(p
, QRect(0, r
.bottom()-7, r
.width() - w
- lw
+ 7, 7),
1195 pal
.color(QPalette::Window
), NoFill
, TileSet::Left
| TileSet::Bottom
);
1197 renderSlab(p
, QRect(0, r
.bottom()-7, r
.width(), 7), pal
.color(QPalette::Window
),
1198 NoFill
, TileSet::Left
| TileSet::Bottom
| TileSet::Right
);
1201 renderSlab(p
, QRect(r
.right() - lw
-7, r
.bottom()-7, lw
+7, 7),
1202 pal
.color(QPalette::Window
), NoFill
, TileSet::Bottom
| TileSet::Right
);
1207 renderSlab(p
, QRect(0, r
.bottom()-7, lw
+7, 7),
1208 pal
.color(QPalette::Window
), NoFill
, TileSet::Left
| TileSet::Bottom
);
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
);
1214 renderSlab(p
, QRect(0, r
.bottom()-7, r
.width(), 7), pal
.color(QPalette::Window
),
1215 NoFill
, TileSet::Left
| TileSet::Bottom
| TileSet::Right
);
1220 case QTabBar::RoundedWest
:
1221 case QTabBar::TriangularWest
:
1222 renderSlab(p
, r
, pal
.color(QPalette::Window
), NoFill
,
1223 TileSet::Top
| TileSet::Right
| TileSet::Bottom
);
1227 // Left and right widgets are placed right and left when in reverse mode
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
);
1232 renderSlab(p
, QRect(r
.x(), r
.y(), r
.width(), 7), pal
.color(QPalette::Window
), NoFill
,
1233 TileSet::Left
| TileSet::Top
| TileSet::Right
);
1236 renderSlab(p
, QRect(r
.x(), r
.y() , 7, lh
+7),
1237 pal
.color(QPalette::Window
), NoFill
, TileSet::Top
| TileSet::Left
);
1242 renderSlab(p
, QRect(r
.x(), r
.y(), 7, lh
+7), pal
.color(QPalette::Window
), NoFill
,
1243 TileSet::Left
| TileSet::Top
);
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
);
1249 renderSlab(p
, QRect(r
.x(), r
.y(), 7, r
.height()), pal
.color(QPalette::Window
), NoFill
,
1250 TileSet::Top
| TileSet::Left
| TileSet::Bottom
);
1255 case QTabBar::RoundedEast
:
1256 case QTabBar::TriangularEast
:
1258 renderSlab(p
, r
, pal
.color(QPalette::Window
), NoFill
,
1259 TileSet::Top
| TileSet::Left
| TileSet::Bottom
);
1262 // Left and right widgets are placed right and left when in reverse mode
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
);
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
);
1271 renderSlab(p
, QRect(r
.x()+r
.width()-7, r
.y() , 7, lh
+7),
1272 pal
.color(QPalette::Window
), NoFill
, TileSet::Top
| TileSet::Right
);
1277 renderSlab(p
, QRect(r
.width()-7, r
.y(), 7, lh
+7), pal
.color(QPalette::Window
), NoFill
,
1278 TileSet::Top
| TileSet::Right
);
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
);
1284 renderSlab(p
, QRect(r
.x(), r
.y(), 7, r
.height()), pal
.color(QPalette::Window
), NoFill
,
1285 TileSet::Top
| TileSet::Right
| TileSet::Bottom
);
1302 case Generic::Frame
:
1307 case Window::TitlePanel
:
1308 p
->fillRect(r
, QColor(Qt::green
) );
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
);
1337 case Splitter::HandleHor
:
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
);
1351 case Splitter::HandleVert
:
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
);
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
);
1386 case Slider::GrooveHor
:
1387 case Slider::GrooveVert
:
1390 bool horizontal
= primitive
== Slider::GrooveHor
;
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
);
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
);
1412 bool hasFocus
= flags
& State_HasFocus
;
1414 const QColor inputColor
= enabled
?pal
.color(QPalette::Base
):pal
.color(QPalette::Window
);
1418 case Generic::Frame
:
1420 QRect fr
= r
.adjusted(2,2,-2,-2);
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
);
1429 _helper
.fillHole(*p
, r
);
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
);
1440 renderHole(p
, inputColor
, fr
, hasFocus
, mouseOver
);
1444 case SpinBox::EditField
:
1445 case SpinBox::ButtonArea
:
1446 case SpinBox::UpButton
:
1447 case SpinBox::DownButton
:
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
);
1473 case Generic::Frame
:
1475 // TODO: pressed state
1477 renderSlab(p
, r
, pal
.color(QPalette::Button
), opts
);
1479 QRect fr
= r
.adjusted(2,2,-2,-2);
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
);
1489 _helper
.fillHole(*p
, r
.adjusted(0,0,0,-1));
1494 #ifdef HOLE_COLOR_OUTSIDE
1495 if (hasFocus
&& enabled
)
1497 renderHole(p
, pal
.color(QPalette::Window
), fr
, true, mouseOver
);
1501 renderHole(p
, pal
.color(QPalette::Window
), fr
, false, mouseOver
);
1504 if (hasFocus
&& enabled
)
1506 renderHole(p
, inputColor
, fr
, true, mouseOver
);
1510 renderHole(p
, inputColor
, fr
, false, mouseOver
);
1518 case ComboBox::EditField
:
1524 case ComboBox::Button
:
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
);
1556 p
->drawLine(r
.bottomLeft(),r
.bottomRight());
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
);
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
)
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
);
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
);
1596 drawKStylePrimitive(WT_Generic
, Generic::ArrowDown
, opt
, QRect(r
.x()+1,r
.y()+1,r
.width(),r
.height()), pal
, flags
, p
, widget
);
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
);
1619 const QColor inputColor
= enabled
?pal
.color(QPalette::Base
):pal
.color(QPalette::Window
);
1621 if (hasFocus
&& !isReadOnly
&& isEnabled
)
1623 renderHole(p
, inputColor
, r
.adjusted(2,2,-2,-3), true, mouseOver
);
1627 renderHole(p
, inputColor
, r
.adjusted(2,2,-2,-3), false, mouseOver
);
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
);
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
);
1650 _helper
.fillHole(*p
, r
.adjusted(0,0,-0,-1));
1652 drawPrimitive(PE_FrameLineEdit
, panel
, p
, widget
);
1658 p
->fillRect(r
.adjusted(2,2,-2,-1), inputColor
);
1671 case Generic::Frame
:
1673 QColor color
= pal
.color(QPalette::Window
);
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
);
1697 case GroupBox::FlatFrame
:
1710 case ToolBar::HandleHor
:
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
));
1719 renderDot(p
, QPoint(center
-2, j
), pal
.color(QPalette::Background
));
1725 case ToolBar::HandleVert
:
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
));
1734 renderDot(p
, QPoint(j
, center
-2), pal
.color(QPalette::Background
));
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 );
1751 int center
= r
.top()+r
.height()/2;
1752 p
->drawLine( r
.x()+3, center
-1, r
.right()-3, center
-1 );
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
))
1774 if (flags
& State_HasFocus
)
1776 if (enabled
&& (flags
& State_MouseOver
))
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
);
1785 renderSlab(p
, r
, pal
.color(QPalette::Button
), opts
);
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
)
1800 tile
= _helper
.slitFocused(_viewHoverBrush
.brush(QPalette::Active
).color());
1802 tile
= _helper
.slitFocused(_viewFocusBrush
.brush(QPalette::Active
).color());
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
1819 if (primitive
>= Generic::ArrowUp
&& primitive
<= Generic::ArrowLeft
) {
1822 switch (primitive
) {
1823 case Generic::ArrowUp
: {
1825 a
<< QPointF( -3,2.5) << QPointF(0.5, -1.5) << QPointF(4,2.5);
1828 case Generic::ArrowDown
: {
1830 a
<< QPointF( -3,-2.5) << QPointF(0.5, 1.5) << QPointF(4,-2.5);
1833 case Generic::ArrowLeft
: {
1835 a
<< QPointF(2.5,-3) << QPointF(-1.5, 0.5) << QPointF(2.5,4);
1838 case Generic::ArrowRight
: {
1840 a
<< QPointF(-2.5,-3) << QPointF(1.5, 0.5) << QPointF(-2.5,4);
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
);
1853 p
->setRenderHint(QPainter::Antialiasing
, false);
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
);
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());
1881 pen
.setStyle(Qt::DotLine
);
1882 p
->setPen(pal
.color(QPalette::Base
));
1883 p
->drawRect(r
.adjusted(0,0,-1,-1));
1885 p
->drawRect(r
.adjusted(0,0,-1,-1));
1887 // we don't want the stippled focus indicator in oxygen
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
) {
1907 widget
->installEventFilter(this);
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
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))
2053 if (!(opts
& NoFill
))
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
);
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
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
2079 tile
= _helper
.slab(color
, 0.0);
2080 tile
->render(r
, p
, tiles
);
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))
2092 // for holes, focus takes precedence over hover (other way around for buttons)
2094 tile
= _helper
.holeFocused(base
, _viewFocusBrush
.brush(QPalette::Active
).color(), 0.0); // FIXME need state
2096 tile
= _helper
.holeFocused(base
, _viewHoverBrush
.brush(QPalette::Active
).color(), 0.0); // FIXME need state
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
,
2109 int s
= qMin(rect
.width(), rect
.height());
2110 QRect r
= centerRect(rect
, s
, s
);
2113 if (hasFocus
) opts
|= Focus
;
2114 if (mouseOver
) opts
|= Hover
;
2118 QColor color
= pal
.color(QPalette::Window
);
2119 _helper
.holeFlat(color
, 0.0)->render(r
, p
, TileSet::Full
);
2123 renderSlab(p
, r
, pal
.color(QPalette::Button
), opts
);
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
;
2138 dashes
<< 1.0 << 2.0;
2142 dashes
<< 0.4 << 2.0;
2144 pen
.setDashPattern(dashes
);
2147 p
->setRenderHint(QPainter::Antialiasing
);
2150 p
->drawLine(QPointF(x
+9, y
), QPointF(x
+3,y
+7));
2151 p
->drawLine(QPointF(x
, y
+4), QPointF(x
+3,y
+7));
2155 p
->drawLine(QPointF(x
+8, y
), QPointF(x
+1,y
+7));
2156 p
->drawLine(QPointF(x
+8, y
+7), QPointF(x
+1,y
));
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
2173 QRect
r2(r
.x() + (r
.width()-21)/2, r
.y() + (r
.height()-21)/2, 21, 21);
2180 QPixmap slabPixmap
= _helper
.roundSlabFocused(pal
.color(QPalette::Button
),_viewHoverBrush
.brush(QPalette::Active
).color(), 0.0);
2182 p
->drawPixmap(x
, y
, slabPixmap
);
2186 QPixmap slabPixmap
= _helper
.roundSlab(pal
.color(QPalette::Button
), 0.0);
2188 p
->drawPixmap(x
, y
, slabPixmap
);
2191 // draw the radio mark
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
;
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
));
2207 case RadioButton::RadioOff
:
2214 // StateTristate, shouldn't happen...
2219 void OxygenStyle::renderDot(QPainter
*p
, const QPointF
&point
, const QColor
&baseColor
) const
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
,
2232 const QPalette
&pal
,
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
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));
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));
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));
2308 renderSlab(p
, Rc
.adjusted(0,-7,0,0), pal
.color(QPalette::Window
), NoFill
, TileSet::Bottom
| TileSet::Left
| TileSet::Right
);
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
);
2317 TileSet
*tile
= _helper
.slabInverted(pal
.color(QPalette::Window
), 0.0);
2319 tile
->render(QRect(Rb
.left()-5, Rb
.top()-1,12,13), p
, TileSet::Right
| TileSet::Top
);
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
);
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);
2331 tile
->render(QRect(Rb
.right()-6, Rb
.top()-1,12,13), p
, TileSet::Left
| TileSet::Top
);
2333 tile
->render(QRect(Rb
.right()-6, Rb
.top()-5,12,12), p
, TileSet::Left
| TileSet::Bottom
);
2338 p
->setPen(darkColor
);
2340 if (!southAlignment
) {
2341 r
.adjusted(0,4,0,0).getRect(&x
, &y
, &w
, &h
);
2343 p
->drawArc(QRectF(x
+2.5, y
+0.5, 9.5, 9.5),90*16, 90*16);
2345 p
->drawLine(QPointF(x
+2.5, y
+6.3), QPointF(x
+2.5, y
+h
-2));
2347 p
->drawLine(QPointF(x
+2.5, y
+6.3), QPointF(x
+2.5, y
+h
-6));
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);
2356 p
->drawLine(QPointF(x
+w
-2.5, y
+6.3), QPointF(x
+w
-2.5, y
+h
+0.5));
2358 p
->drawLine(QPointF(x
+w
-2.5, y
+6.3), QPointF(x
+w
-2.5, y
+h
-6.3));
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
);
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
);
2373 p
->drawArc(QRectF(x
+2.5, y
+h
+0.2-9.5, 9.5, 9.5),180*16, 90*16);
2375 p
->drawLine(QPointF(x
+2.5, y
+1.5), QPointF(x
+2.5, y
+h
+3-9.5));
2377 p
->drawLine(QPointF(x
+2.5, y
+2+1.5), QPointF(x
+2.5, y
+h
+3-9.5));
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));
2388 p
->drawLine(QPointF(x
+w
-2.5, y
+2+1.5), QPointF(x
+w
-2.5, y
+h
-6.3));
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
);
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);
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);
2417 Ractual
.adjust(-7,0,0,0);
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);
2433 Ractual
.adjust(0,0,7,0);
2436 renderSlab(p
, Ractual
, pal
.color(QPalette::Window
), NoFill
| Hover
, posFlag
);
2438 renderSlab(p
, Ractual
, pal
.color(QPalette::Window
), NoFill
, posFlag
);
2441 // TODO mouseover effects
2444 // westAlignment and eastAlignment
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() );
2453 r
.getRect(&x
, &y
, &w
, &h
);
2455 // parts of the adjacent tabs
2456 if(!isSingle
&& ((!reverseLayout
&& !isFirst
) || (reverseLayout
&& !isFirst
))) {
2457 p
->setPen(darkColor
);
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));
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
);
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));
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));
2480 renderSlab(p
, Rc
.adjusted(-7,0,0,0), pal
.color(QPalette::Window
), NoFill
, TileSet::Top
| TileSet::Right
| TileSet::Bottom
);
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
);
2489 TileSet
*tile
= _helper
.slabInverted(pal
.color(QPalette::Window
), 0.0);
2491 tile
->render(QRect(Rb
.left(), Rb
.top()-6,12,13), p
, TileSet::Left
| TileSet::Bottom
);
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);
2499 tile
->render(QRect(Rb
.right()-6, Rb
.bottom()-6,12,13), p
, TileSet::Left
| TileSet::Top
);
2501 tile
->render(QRect(Rb
.right()-5-6, Rb
.bottom()-6,12,12), p
, TileSet::Right
| TileSet::Top
);
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);
2515 p
->drawLine(QPointF(x
-3+9.5, y
+1.5), QPointF(x
+w
+1.5, y
+1.5));
2517 p
->drawLine(QPointF(x
-3+9.5, y
+1.5), QPointF(x
+w
-1, y
+1.5));
2519 p
->drawLine(QPointF(x
, y
-3+9.5), QPointF(x
, y
+h
-1));
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);
2527 p
->drawLine(QPointF(x
+9.5, y
+h
-1), QPointF(x
+w
, y
+h
-1));
2529 p
->drawLine(QPointF(x
-4+9.5, y
+h
-1), QPointF(x
+w
-1, y
+h
-1));
2531 p
->drawLine(QPointF(x
, y
), QPointF(x
, y
+h
+3-9.5));
2532 p
->fillRect(x
, y
, w
, h
, midColor
);
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);
2548 p
->drawLine(QPointF(x
-1.5, y
+1.5), QPointF(x
+w
+3-9.5, y
+1.5));
2550 p
->drawLine(QPointF(x
, y
+1.5), QPointF(x
+w
+3-9.5, y
+1.5));
2552 p
->drawLine(QPointF(x
+w
-1, y
-3+9.5), QPointF(x
+w
-1, y
+h
-1));
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));
2562 p
->drawLine(QPointF(x
+0.5, y
+h
-1), QPointF(x
+w
+4-9.5, y
+h
-1));
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
);
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
2581 posFlag
|= TileSet::Top
;
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);
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);
2596 Ractual
.adjust(0,0,0,7);
2599 renderSlab(p
, Ractual
, pal
.color(QPalette::Window
), NoFill
| Hover
, posFlag
);
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
2613 case SH_Menu_SubMenuPopupDelay
:
2614 return 96; // Motif-like delay...
2616 case SH_ScrollView_FrameOnlyAroundContents
:
2619 case SH_ItemView_ShowDecorationSelected
:
2622 case SH_RubberBand_Mask
:
2624 const QStyleOptionRubberBand
*opt
= qstyleoption_cast
<const QStyleOptionRubberBand
*>(option
);
2627 if (QStyleHintReturnMask
*mask
= qstyleoption_cast
<QStyleHintReturnMask
*>(returnData
))
2628 mask
->region
= option
->rect
;
2632 return KStyle::styleHint(hint
, option
, widget
, returnData
);
2636 int OxygenStyle::pixelMetric(PixelMetric m
, const QStyleOption
*opt
, const QWidget
*widget
) const
2639 case PM_DefaultTopLevelMargin
:
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
))
2651 if (qobject_cast
<const QFrame
*>(widget
) || qobject_cast
<const QComboBox
*>(widget
))
2655 return KStyle::pixelMetric(m
,opt
,widget
);
2660 QSize
OxygenStyle::sizeFromContents(ContentsType type
, const QStyleOption
* option
, const QSize
& contentsSize
, const QWidget
* widget
) const
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
);
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
;
2695 const QStyleOptionGroupBox
*gbOpt
= qstyleoption_cast
<const QStyleOptionGroupBox
*>(option
);
2699 bool isFlat
= gbOpt
->features
& QStyleOptionFrameV2::Flat
;
2703 case SC_GroupBoxFrame
:
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
2716 int leftMarginExtension
= 16;
2717 r
= visualRect(option
->direction
,r
,r
.adjusted(leftMarginExtension
,0,0,0));
2722 case SC_GroupBoxCheckBox
:
2723 case SC_GroupBoxLabel
:
2725 QFont font
= widget
->font();
2726 // calculate text width assuming bold text in flat group boxes
2730 QFontMetrics fontMetrics
= QFontMetrics(font
);
2731 int h
= fontMetrics
.height();
2732 int tw
= fontMetrics
.size(Qt::TextShowMnemonic
, gbOpt
->text
+ QLatin1String(" ")).width();
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
2746 r
= QRect(0,r
.y(),tw
,r
.height());
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
);
2761 return KStyle::subControlRect(control
, option
, subControl
, widget
);
2764 QRect
OxygenStyle::subElementRect(SubElement sr
, const QStyleOption
*opt
, const QWidget
*widget
) const
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
);
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
);
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()));
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()));
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
);
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
);
2831 case QTabBar::RoundedWest
:
2832 case QTabBar::TriangularWest
:
2833 r
= QRect(QPoint(paneRect
.x() - twf
->leftCornerWidgetSize
.width(), paneRect
.y()), twf
->leftCornerWidgetSize
);
2835 case QTabBar::RoundedEast
:
2836 case QTabBar::TriangularEast
:
2837 r
= QRect(QPoint(paneRect
.x() + paneRect
.width(), paneRect
.y()), twf
->leftCornerWidgetSize
);
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
);
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
);
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
);
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
);
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());
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);
2896 r
= visualRect(opt
->direction
, opt
->rect
, r
);
2900 return KStyle::subElementRect(sr
, opt
, widget
);
2905 bool OxygenStyle::eventFilter(QObject
*obj
, QEvent
*ev
)
2907 if (KStyle::eventFilter(obj
, ev
) )
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()) {
2923 case QEvent::Resize
: {
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
)
2939 if (QMenu
*m
= qobject_cast
<QMenu
*>(obj
))
2941 switch(ev
->type()) {
2943 case QEvent::Resize
: {
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
)
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
));
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,
2984 // TODO - draw our light effects over an arbitrary fill?
2985 if (brush
.style() == Qt::SolidPattern
&&
2986 !widget
->testAttribute(Qt::WA_NoSystemBackground
)) {
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
)
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
)
3009 if (ev
->type() == QEvent::Paint
)
3014 _helper
.drawFloatFrame(&p
, dw
->rect(), dw
->palette().color(QPalette::Window
));
3020 dw
->rect().getRect(&x
, &y
, &w
, &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));
3036 if (QToolBox
*tb
= qobject_cast
<QToolBox
*>(obj
))
3038 if (ev
->type() == QEvent::Paint
)
3040 QRect r
= tb
->rect();
3041 StyleOptions opts
= NoFill
;
3044 p
.setClipRegion(((QPaintEvent
*)ev
)->region());
3045 renderSlab(&p
, r
, tb
->palette().color(QPalette::Button
), opts
);
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)
3060 buttonColor
= option
->palette
.button().color();
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
);
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;