Make a branch to make krunner Good Enough For Aaron™.
[kdebase/uwolfer.git] / runtime / kstyles / light / lightstyle-v3.cpp
blob6a95aaa1581379f5b2d01f0c019412ca1133efa6
1 /*
2 Copyright (c) 2000-2001 Trolltech AS (info@trolltech.com)
4 Permission is hereby granted, free of charge, to any person obtaining a
5 copy of this software and associated documentation files (the "Software"),
6 to deal in the Software without restriction, including without limitation
7 the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 and/or sell copies of the Software, and to permit persons to whom the
9 Software is furnished to do so, subject to the following conditions:
11 The above copyright notice and this permission notice shall be included in
12 all copies or substantial portions of the Software.
14 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17 THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
19 FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
20 DEALINGS IN THE SOFTWARE.
23 #include "lightstyle-v3.h"
25 #include "QtGui/QMenuBar"
26 #include "QtGui/QApplication"
27 #include "QtGui/QCheckBox"
28 #include "QtGui/QPainter"
29 #include "QtGui/QColorGroup"
30 #include "QtGui/QPushButton"
31 #include "QtGui/qdrawutil.h"
32 #include "QtGui/QProgressBar"
33 #include "QtGui/QScrollBar"
34 #include "QtGui/QTabBar"
35 #include "QtCore/QPointer"
36 #include "QtGui/QLayout"
37 #include "QtGui/QLineEdit"
38 #include "QtGui/QImage"
39 #include "QtGui/QComboBox"
40 #include "QtGui/QSlider"
41 #include "QtGui/QStyleFactory"
42 #include <Qt3Support/Q3PointArray>
45 // The Light Style, 3rd revision
47 LightStyleV3::LightStyleV3()
48 : KStyle(AllowMenuTransparency)
50 basestyle = QStyleFactory::create( "Windows" );
51 if ( ! basestyle )
52 basestyle = QStyleFactory::create( QStyleFactory::keys().first() );
53 if ( ! basestyle )
54 qFatal( "LightStyle: could not find a basestyle!" );
57 LightStyleV3::~LightStyleV3()
59 delete basestyle;
62 void LightStyleV3::polishPopupMenu( QMenu * menu)
64 KStyle::polishPopupMenu(menu);
65 // empty to satisy pure virtual requirements
69 A LightBevel looks like this:
71 EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE
72 ESSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSE
73 ESBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBSE
74 ESBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBSE
75 ESBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBSE
76 ESBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBSE
77 ESBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBSE
78 ESBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBSE
79 ESBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBSE
80 ESBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBSE
81 ESBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBSE
82 ESBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBSE
83 ESBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBSE
84 ESBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBSE
85 ESBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBSE
86 ESBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBSE
87 ESBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBSE
88 ESBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBSE
89 ESBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBSE
90 ESBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBSE
91 ESBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBSE
92 ESBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBSE
93 ESBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBSE
94 ESSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSE
95 EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE
97 where:
98 E is the sunken etching ( optional, not drawn by default )
99 S is the border (optional, drawn by default )
100 B is the bevel (draw with the line width, minus the width of
101 the etching and border )
102 F is the fill ( optional, not drawn by default )
104 static void drawLightEtch( QPainter *p,
105 const QRect &rect,
106 const QColor &color,
107 bool sunken )
109 Q3PointArray pts( 4 );
111 pts.setPoint( 0, rect.left(), rect.bottom() - 1);
112 pts.setPoint( 1, rect.left(), rect.top() );
113 pts.setPoint( 2, rect.left() + 1, rect.top() );
114 pts.setPoint( 3, rect.right(), rect.top() );
115 p->setPen( sunken ? color.dark( 115 ) : color.light( 115 ) );
116 p->drawLineSegments( pts );
118 pts.setPoint( 0, rect.left(), rect.bottom() );
119 pts.setPoint( 1, rect.right(), rect.bottom() );
120 pts.setPoint( 2, rect.right(), rect.bottom() - 1 );
121 pts.setPoint( 3, rect.right(), rect.top() + 1 );
122 p->setPen( sunken ? color.light( 115 ) : color.dark( 115 ) );
123 p->drawLineSegments( pts );
126 static void drawLightBevel( QPainter *p,
127 const QRect &rect,
128 const QColorGroup &cg,
129 QStyle::State flags,
130 int linewidth,
131 bool etch = false, // light sunken bevel around border
132 bool border = true, // rectangle around bevel
133 const QBrush *fill = 0 ) // contents fill
135 QRect br = rect;
136 bool bevel = ( flags & ( QStyle::State_Down | QStyle::State_On |
137 QStyle::State_Sunken | QStyle::State_Raised ) );
138 bool sunken = (flags & (QStyle::State_Down | QStyle::State_On |
139 QStyle::State_Sunken));
141 if ( etch && linewidth > 0 ) {
142 drawLightEtch( p, br, cg.background(), true );
143 linewidth--;
144 br.adjust( 1, 1, -1, -1 );
147 if ( ! br.isValid() )
148 return;
149 if ( border && linewidth > 0 ) {
150 p->setPen( cg.dark() );
151 p->drawRect( br );
152 linewidth--;
153 br.adjust( 1, 1, -1, -1 );
156 if ( ! br.isValid() )
157 return;
158 if ( bevel && linewidth > 0 ) {
159 // draw a bevel
160 int x, y, w, h;
161 br.getRect( &x, &y, &w, &h );
163 // copied form qDrawShadePanel - just changed the highlight colors...
164 Q3PointArray a( 4*linewidth );
165 if ( sunken )
166 p->setPen( border ? cg.mid() : cg.dark() );
167 else
168 p->setPen( cg.light() );
169 int x1, y1, x2, y2;
170 int i;
171 int n = 0;
172 x1 = x;
173 y1 = y2 = y;
174 x2 = x+w-2;
175 for ( i=0; i<linewidth; i++ ) { // top shadow
176 a.setPoint( n++, x1, y1++ );
177 a.setPoint( n++, x2--, y2++ );
179 x2 = x1;
180 y1 = y+h-2;
181 for ( i=0; i<linewidth; i++ ) { // left shadow
182 a.setPoint( n++, x1++, y1 );
183 a.setPoint( n++, x2++, y2-- );
185 p->drawLineSegments( a );
186 n = 0;
187 if ( sunken )
188 p->setPen( cg.light() );
189 else
190 p->setPen( border ? cg.mid() : cg.dark() );
191 x1 = x;
192 y1 = y2 = y+h-1;
193 x2 = x+w-1;
194 for ( i=0; i<linewidth; i++ ) { // bottom shadow
195 a.setPoint( n++, x1++, y1-- );
196 a.setPoint( n++, x2, y2-- );
198 x1 = x2;
199 y1 = y;
200 y2 = y+h-linewidth-1;
201 for ( i=0; i<linewidth; i++ ) { // right shadow
202 a.setPoint( n++, x1--, y1++ );
203 a.setPoint( n++, x2--, y2 );
205 p->drawLineSegments( a );
207 br.adjust( linewidth, linewidth, -linewidth, -linewidth );
210 // fill
211 if ( fill )
212 p->fillRect( br, *fill );
215 void LightStyleV3::drawPrimitive( PrimitiveElement pe,
216 QPainter *p,
217 const QRect &r,
218 const QColorGroup &cg,
219 SFlags flags,
220 const QStyleOption &data ) const
222 QRect br = r;
223 const QBrush *fill = 0;
225 switch (pe) {
226 case PE_HeaderSection:
227 // don't draw any headers sunken
228 flags = ((flags | Style_Sunken) ^ Style_Sunken) | Style_Raised;
230 p->setPen( cg.background() );
231 // hard border at the bottom/right of the header
232 if ( flags & Style_Horizontal ) {
233 p->drawLine( br.bottomLeft(), br.bottomRight() );
234 br.adjust( 0, 0, 0, -1 );
235 } else {
236 p->drawLine( br.topRight(), br.bottomRight() );
237 br.adjust( 0, 0, -1, 0 );
240 // draw the header ( just an etching )
241 if ( ! br.isValid() )
242 break;
243 drawLightEtch( p, br, ( ( flags & Style_Down ) ?
244 cg.midlight() : cg.button() ),
245 ( flags & Style_Down ) );
246 br.adjust( 1, 1, -1, -1 );
248 // fill the header
249 if ( ! br.isValid() )
250 break;
251 p->fillRect( br, cg.brush( ( flags & Style_Down ) ?
252 QPalette::Midlight : QPalette::Button ) );
254 // the taskbuttons in kicker seem to allow the style to set the pencolor
255 // here, which will be used to draw the text for focused window buttons...
256 // how utterly silly
257 p->setPen( cg.buttonText() );
258 break;
260 case PE_ButtonCommand:
262 QRect br = r;
264 if (flags & QStyle::State_Enabled) {
265 if (flags & (QStyle::State_Down |
266 QStyle::State_On |
267 QStyle::State_Sunken))
268 fill = &cg.brush(QPalette::Midlight);
269 else
270 fill = &cg.brush(QPalette::Button);
271 } else
272 fill = &cg.brush(QPalette::Background);
274 bool etch = true;
275 if ( flags & Style_ButtonDefault ) {
276 etch = false;
277 br.adjust( 1, 1, -1, -1 );
279 drawLightBevel( p, br, cg, flags,
280 pixelMetric( PM_DefaultFrameWidth ) + ( etch ? 1 : 0 ),
281 etch, true, fill );
282 break;
285 case PE_ButtonBevel:
286 case PE_ButtonTool:
287 if (flags & QStyle::State_Enabled) {
288 if (flags & (QStyle::State_Down |
289 QStyle::State_On |
290 QStyle::State_Sunken))
291 fill = &cg.brush(QPalette::Midlight);
292 else
293 fill = &cg.brush(QPalette::Button);
294 } else
295 fill = &cg.brush(QPalette::Background);
296 drawLightBevel( p, r, cg, flags, pixelMetric( PM_DefaultFrameWidth ),
297 false, true, fill );
298 break;
300 case PE_ButtonDropDown:
302 QBrush thefill;
303 bool sunken =
304 (flags & (QStyle::State_Down | QStyle::State_On | QStyle::State_Sunken));
306 if (flags & QStyle::State_Enabled) {
307 if (sunken)
308 thefill = cg.brush(QPalette::Midlight);
309 else
310 thefill = cg.brush(QPalette::Button);
311 } else
312 thefill = cg.brush(QPalette::Background);
314 p->setPen( cg.dark() );
315 p->drawLine(r.topLeft(), r.topRight());
316 p->drawLine(r.topRight(), r.bottomRight());
317 p->drawLine(r.bottomRight(), r.bottomLeft());
319 if (flags & (QStyle::State_Down | QStyle::State_On |
320 QStyle::State_Sunken | QStyle::State_Raised)) {
321 // button bevel
322 if (sunken)
323 p->setPen(cg.mid());
324 else
325 p->setPen(cg.light());
327 p->drawLine(r.x(), r.y() + 2,
328 r.x(), r.y() + r.height() - 3); // left
329 p->drawLine(r.x(), r.y() + 1,
330 r.x() + r.width() - 2, r.y() + 1); // top
332 if (sunken)
333 p->setPen(cg.light());
334 else
335 p->setPen(cg.mid());
337 p->drawLine(r.x() + r.width() - 2, r.y() + 2,
338 r.x() + r.width() - 2, r.y() + r.height() - 3); // right
339 p->drawLine(r.x() + 1, r.y() + r.height() - 2,
340 r.x() + r.width() - 2, r.y() + r.height() - 2); // bottom
343 p->fillRect(r.x() + 1, r.y() + 2, r.width() - 3, r.height() - 4, thefill);
344 break;
347 case PE_ButtonDefault:
348 p->setPen( cg.shadow() );
349 p->drawRect( r );
350 break;
352 case PE_Indicator:
353 const QBrush *fill;
354 if (! (flags & Style_Enabled))
355 fill = &cg.brush(QPalette::Background);
356 else if (flags & Style_Down)
357 fill = &cg.brush(QPalette::Mid);
358 else
359 fill = &cg.brush(QPalette::Base);
360 drawLightBevel( p, r, cg, flags | Style_Sunken, 2, true, true, fill );
362 p->setPen(cg.text());
363 if (flags & Style_NoChange) {
364 p->drawLine(r.x() + 3, r.y() + r.height() / 2,
365 r.x() + r.width() - 4, r.y() + r.height() / 2);
366 p->drawLine(r.x() + 3, r.y() + 1 + r.height() / 2,
367 r.x() + r.width() - 4, r.y() + 1 + r.height() / 2);
368 p->drawLine(r.x() + 3, r.y() - 1 + r.height() / 2,
369 r.x() + r.width() - 4, r.y() - 1 + r.height() / 2);
370 } else if (flags & Style_On) {
371 p->drawLine(r.x() + 4, r.y() + 3,
372 r.x() + r.width() - 4, r.y() + r.height() - 5);
373 p->drawLine(r.x() + 3, r.y() + 3,
374 r.x() + r.width() - 4, r.y() + r.height() - 4);
375 p->drawLine(r.x() + 3, r.y() + 4,
376 r.x() + r.width() - 5, r.y() + r.height() - 4);
377 p->drawLine(r.x() + 3, r.y() + r.height() - 5,
378 r.x() + r.width() - 5, r.y() + 3);
379 p->drawLine(r.x() + 3, r.y() + r.height() - 4,
380 r.x() + r.width() - 4, r.y() + 3);
381 p->drawLine(r.x() + 4, r.y() + r.height() - 4,
382 r.x() + r.width() - 4, r.y() + 4);
385 break;
387 case PE_ExclusiveIndicator:
389 QRect br = r, // bevel rect
390 lr = r, // outline rect
391 cr = r, // contents rect
392 ir = r; // indicator rect
393 lr.adjust( 1, 1, -1, -1 );
394 cr.adjust( 2, 2, -2, -2 );
395 ir.adjust( 3, 3, -3, -3 );
397 p->fillRect( r, cg.brush( QPalette::Background ) );
399 p->setPen( flags & Style_Down ? cg.mid() :
400 ( flags & Style_Enabled ? cg.base() : cg.background() ) );
401 p->setBrush( flags & Style_Down ? cg.mid() :
402 ( flags & Style_Enabled ? cg.base() : cg.background() ) );
403 p->drawEllipse( lr );
405 p->setPen( cg.background().dark( 115 ) );
406 p->drawArc( br, 45*16, 180*16 );
407 p->setPen( cg.background().light( 115 ) );
408 p->drawArc( br, 235*16, 180*16 );
410 p->setPen( cg.dark() );
411 p->drawArc( lr, 0, 16*360 );
413 if ( flags & Style_On ) {
414 p->setPen( flags & Style_Down ? cg.mid() :
415 ( flags & Style_Enabled ? cg.base() : cg.background() ) );
416 p->setBrush( cg.text() );
417 p->drawEllipse( ir );
420 break;
423 case PE_DockWindowHandle:
425 QString title;
426 bool drawTitle = false;
427 if ( p && p->device()->devType() == QInternal::Widget ) {
428 QWidget *w = (QWidget *) p->device();
429 QWidget *p = w->parentWidget();
430 if (p->inherits("QDockWindow") && ! p->inherits("QToolBar")) {
431 drawTitle = true;
432 title = p->caption();
436 flags |= Style_Raised;
437 if (flags & Style_Horizontal) {
438 if (drawTitle) {
439 QPixmap pm(r.height(), r.width());
440 QPainter p2(&pm);
441 p2.fillRect(0, 0, pm.width(), pm.height(),
442 cg.brush(QPalette::Highlight));
443 p2.setPen(cg.highlightedText());
444 p2.drawText(0, 0, pm.width(), pm.height(), Qt::AlignCenter, title);
445 p2.end();
447 QMatrix m;
448 m.rotate(270.0);
449 pm = pm.xForm(m);
450 p->drawPixmap(r.x(), r.y(), pm);
451 } else {
452 for ( int i = r.left() - 1; i < r.right(); i += 3 ) {
453 p->setPen( cg.midlight() );
454 p->drawLine( i, r.top(), i, r.bottom() );
455 p->setPen( cg.background() );
456 p->drawLine( i + 1, r.top(), i + 1, r.bottom() );
457 p->setPen( cg.mid() );
458 p->drawLine( i + 2, r.top(), i + 2, r.bottom() );
461 } else {
462 if (drawTitle) {
463 p->fillRect(r, cg.brush(QPalette::Highlight));
464 p->setPen(cg.highlightedText());
465 p->drawText(r, Qt::AlignCenter, title);
466 } else {
467 for ( int i = r.top() - 1; i < r.bottom(); i += 3 ) {
468 p->setPen( cg.midlight() );
469 p->drawLine( r.left(), i, r.right(), i );
470 p->setPen( cg.background() );
471 p->drawLine( r.left(), i + 1, r.right(), i + 1);
472 p->setPen( cg.mid() );
473 p->drawLine( r.left(), i + 2, r.right(), i + 2 );
478 break;
481 case PE_DockWindowSeparator:
483 if (flags & Style_Horizontal) {
484 int hw = r.width() / 2;
485 p->setPen( cg.mid() );
486 p->drawLine( hw, r.top() + 6, hw, r.bottom() - 6 );
487 p->setPen( cg.light() );
488 p->drawLine( hw + 1, r.top() + 6, hw + 1, r.bottom() - 6 );
489 } else {
490 int hh = r.height() / 2;
491 p->setPen( cg.mid() );
492 p->drawLine( r.left() + 6, hh, r.right() - 6, hh );
493 p->setPen( cg.light() );
494 p->drawLine( r.left() + 6, hh + 1, r.right() - 6, hh + 1 );
496 break;
499 case PE_Splitter:
500 if (flags & Style_Horizontal)
501 flags &= ~Style_Horizontal;
502 else
503 flags |= Style_Horizontal;
504 // fall through intended
506 case PE_DockWindowResizeHandle:
508 QRect br = r;
510 p->setPen( cg.shadow() );
511 p->drawRect( br );
513 br.adjust( 1, 1, -1, -1 );
515 if ( ! br.isValid() )
516 break;
517 p->setPen( cg.light() );
518 p->drawLine( br.left(), br.top(), br.right() - 1, br.top() );
519 p->drawLine( br.left(), br.top() + 1, br.left(), br.bottom() );
520 p->setPen( cg.mid() );
521 p->drawLine( br.bottomLeft(), br.bottomRight() );
522 p->drawLine( br.right(), br.top(), br.right(), br.bottom() - 1 );
524 br.adjust( 1, 1, -1, -1 );
526 if ( ! br.isValid() )
527 break;
528 p->fillRect( br, cg.brush( QPalette::Button ) );
529 break;
532 case PE_PanelPopup:
533 drawLightBevel( p, r, cg, flags,
534 ( data.isDefault() ? pixelMetric(PM_DefaultFrameWidth) :
535 data.lineWidth() ), false, true );
536 break;
538 case PE_Panel:
539 case PE_PanelLineEdit:
540 case PE_PanelTabWidget:
541 case PE_WindowFrame:
543 QRect br = r;
545 int cover = 0;
546 int reallw = ( data.isDefault() ?
547 pixelMetric( PM_DefaultFrameWidth ) : data.lineWidth() );
548 cover = reallw - 1;
550 if ( ! ( flags & Style_Sunken ) )
551 flags |= Style_Raised;
552 drawLightBevel( p, br, cg, flags, 1, false, false );
553 br.adjust( 1, 1, -1, -1 );
555 while ( cover-- > 0 ) {
556 Q3PointArray pts( 8 );
557 pts.setPoint( 0, br.left(), br.bottom() - 1);
558 pts.setPoint( 1, br.left(), br.top() );
559 pts.setPoint( 2, br.left() + 1, br.top() );
560 pts.setPoint( 3, br.right(), br.top() );
561 pts.setPoint( 4, br.left(), br.bottom() );
562 pts.setPoint( 5, br.right(), br.bottom() );
563 pts.setPoint( 6, br.right(), br.bottom() - 1 );
564 pts.setPoint( 7, br.right(), br.top() + 1 );
565 p->setPen( cg.background() );
566 p->drawLineSegments( pts );
568 br.adjust( 1, 1, -1, -1 );
570 break;
573 case PE_PanelDockWindow:
574 drawLightBevel( p, r, cg, flags, ( data.isDefault() ?
575 pixelMetric(PM_DefaultFrameWidth) :
576 data.lineWidth() ), false, false,
577 &cg.brush( QPalette::Button ) );
578 break;
580 case PE_PanelMenuBar:
581 drawLightBevel( p, r, cg, flags, ( data.isDefault() ?
582 pixelMetric(PM_MenuBarFrameWidth) :
583 data.lineWidth() ), false, false,
584 &cg.brush( QPalette::Button ) );
585 break;
587 case PE_ScrollBarSubLine:
589 QRect br = r;
590 PrimitiveElement pe;
592 p->setPen( cg.background() );
593 if (flags & Style_Horizontal) {
594 pe = PE_ArrowLeft;
595 p->drawLine( br.topLeft(), br.topRight() );
596 br.adjust( 0, 1, 0, 0 );
597 } else {
598 pe = PE_ArrowUp;
599 p->drawLine( br.topLeft(), br.bottomLeft() );
600 br.adjust( 1, 0, 0, 0 );
603 if ( ! br.isValid() )
604 break;
605 drawLightEtch( p, br, cg.button(), false );
606 br.adjust( 1, 1, -1, -1 );
608 if ( ! br.isValid() )
609 break;
610 p->fillRect( br, cg.brush( ( flags & Style_Down ) ?
611 QPalette::Midlight :
612 QPalette::Button ) );
613 br.adjust( 2, 2, -2, -2 );
615 if ( ! br.isValid() )
616 break;
617 drawPrimitive( pe, p, br, cg, flags );
618 break;
621 case PE_ScrollBarAddLine:
623 QRect br = r;
624 PrimitiveElement pe;
626 p->setPen( cg.background() );
627 if (flags & Style_Horizontal) {
628 pe = PE_ArrowRight;
629 p->drawLine( br.topLeft(), br.topRight() );
630 br.adjust( 0, 1, 0, 0 );
631 } else {
632 pe = PE_ArrowDown;
633 p->drawLine( br.topLeft(), br.bottomLeft() );
634 br.adjust( 1, 0, 0, 0 );
637 if ( ! br.isValid() )
638 break;
639 drawLightEtch( p, br, cg.button(), false );
640 br.adjust( 1, 1, -1, -1 );
642 if ( ! br.isValid() )
643 break;
644 p->fillRect( br, cg.brush( ( flags & Style_Down ) ?
645 QPalette::Midlight :
646 QPalette::Button ) );
647 br.adjust( 2, 2, -2, -2 );
649 if ( ! br.isValid() )
650 break;
651 drawPrimitive( pe, p, br, cg, flags );
652 break;
655 case PE_ScrollBarSubPage:
657 QRect br = r;
659 p->setPen( cg.background() );
660 if (flags & Style_Horizontal) {
661 p->drawLine( br.topLeft(), br.topRight() );
662 br.adjust( 0, 1, 0, 0 );
663 } else {
664 p->drawLine( br.topLeft(), br.bottomLeft() );
665 br.adjust( 1, 0, 0, 0 );
668 if ( ! br.isValid() )
669 break;
670 drawLightEtch( p, br, cg.button(), false );
671 br.adjust( 1, 1, -1, -1 );
673 if ( ! br.isValid() )
674 break;
675 p->fillRect( br, cg.brush( ( flags & Style_Down ) ?
676 QPalette::Midlight :
677 QPalette::Button ) );
678 break;
681 case PE_ScrollBarAddPage:
683 QRect br = r;
685 p->setPen( cg.background() );
686 if (flags & Style_Horizontal) {
687 p->drawLine( br.topLeft(), br.topRight() );
688 br.adjust( 0, 1, 0, 0 );
689 } else {
690 p->drawLine( br.topLeft(), br.bottomLeft() );
691 br.adjust( 1, 0, 0, 0 );
694 if ( ! br.isValid() )
695 break;
696 drawLightEtch( p, br, cg.button(), false );
697 br.adjust( 1, 1, -1, -1 );
699 if ( ! br.isValid() )
700 break;
701 p->fillRect( br, cg.brush( ( flags & Style_Down ) ?
702 QPalette::Midlight :
703 QPalette::Button ) );
704 break;
707 case PE_ScrollBarSlider:
709 QRect br = r;
711 p->setPen( cg.background() );
712 if (flags & Style_Horizontal) {
713 p->drawLine( br.topLeft(), br.topRight() );
714 br.adjust( 0, 1, 0, 0 );
715 } else {
716 p->drawLine( br.topLeft(), br.bottomLeft() );
717 br.adjust( 1, 0, 0, 0 );
720 if ( ! br.isValid() )
721 break;
722 p->setPen( cg.highlight().light() );
723 p->drawLine( br.topLeft(), br.topRight() );
724 p->drawLine( br.left(), br.top() + 1, br.left(), br.bottom() - 1 );
726 p->setPen( cg.highlight().dark() );
727 p->drawLine( br.left(), br.bottom(), br.right() - 1, br.bottom() );
728 p->drawLine( br.topRight(), br.bottomRight() );
729 br.adjust( 1, 1, -1, -1 );
731 p->fillRect( br, cg.brush( QPalette::Highlight ) );
732 break;
735 case PE_FocusRect:
736 p->setBrush( Qt::NoBrush );
737 if ( flags & Style_FocusAtBorder )
738 p->setPen( cg.shadow() );
739 else
740 p->setPen( cg.dark() );
741 p->drawRect( r );
742 break;
744 case PE_ProgressBarChunk:
745 p->fillRect(r.x(), r.y() + 2, r.width(), r.height() - 4, cg.highlight());
746 break;
748 default:
749 if (pe == PE_HeaderArrow) {
750 if (flags & Style_Down)
751 pe = PE_ArrowDown;
752 else
753 pe = PE_ArrowUp;
756 if (pe >= PE_ArrowUp && pe <= PE_ArrowLeft) {
757 Q3PointArray a;
759 switch ( pe ) {
760 case PE_ArrowUp:
761 a.setPoints( 7, -4,1, 2,1, -3,0, 1,0, -2,-1, 0,-1, -1,-2 );
762 break;
764 case PE_ArrowDown:
765 a.setPoints( 7, -4,-2, 2,-2, -3,-1, 1,-1, -2,0, 0,0, -1,1 );
766 break;
768 case PE_ArrowRight:
769 a.setPoints( 7, -2,-3, -2,3, -1,-2, -1,2, 0,-1, 0,1, 1,0 );
770 break;
772 case PE_ArrowLeft:
773 a.setPoints( 7, 0,-3, 0,3, -1,-2, -1,2, -2,-1, -2,1, -3,0 );
774 break;
776 default:
777 break;
780 if (a.isNull())
781 return;
783 p->save();
784 if ( flags & Style_Enabled ) {
785 a.translate( r.x() + r.width() / 2, r.y() + r.height() / 2 );
786 p->setPen( cg.buttonText() );
787 p->drawLineSegments( a, 0, 3 ); // draw arrow
788 p->drawPoint( a[6] );
789 } else {
790 a.translate( r.x() + r.width() / 2 + 1, r.y() + r.height() / 2 + 1 );
791 p->setPen( cg.light() );
792 p->drawLineSegments( a, 0, 3 ); // draw arrow
793 p->drawPoint( a[6] );
794 a.translate( -1, -1 );
795 p->setPen( cg.mid() );
796 p->drawLineSegments( a, 0, 3 ); // draw arrow
797 p->drawPoint( a[6] );
799 p->restore();
800 } else
801 QCommonStyle::drawPrimitive(pe, p, r, cg, flags, data);
802 break;
806 void LightStyleV3::drawControl( ControlElement control,
807 QPainter *p,
808 const QWidget *widget,
809 const QRect &r,
810 const QColorGroup &cg,
811 SFlags flags,
812 const QStyleOption &data ) const
814 switch (control) {
815 case CE_TabBarTab:
817 const QTabBar *tb = (const QTabBar *) widget;
818 QRect br = r;
820 if ( tb->shape() == QTabBar::RoundedNorth ) {
821 if ( ! ( flags & Style_Selected ) ) {
822 p->setPen( cg.background() );
823 p->drawLine( br.left(), br.bottom(),
824 br.right(), br.bottom() );
825 p->setPen( cg.light() );
826 p->drawLine( br.left(), br.bottom() - 1,
827 br.right(), br.bottom() - 1);
828 br.adjust( 0, 2, -1, -2 );
829 if ( br.left() == 0 )
830 p->drawPoint( br.left(), br.bottom() + 2 );
831 } else {
832 p->setPen( cg.background() );
833 p->drawLine( br.bottomLeft(), br.bottomRight() );
834 if ( br.left() == 0 ) {
835 p->setPen( cg.light() );
836 p->drawPoint( br.bottomLeft() );
838 br.adjust( 0, 0, 0, -1 );
841 p->setPen( cg.light() );
842 p->drawLine( br.bottomLeft(), br.topLeft() );
843 p->drawLine( br.topLeft(), br.topRight() );
844 p->setPen( cg.dark() );
845 p->drawLine( br.right(), br.top() + 1, br.right(), br.bottom() );
847 if ( flags & Style_Selected )
849 p->fillRect( br.right() - 3, br.top() + 1, 3, br.height() - 1, cg.brush(QPalette::Highlight));
850 br.adjust( 1, 1, -4, 0 );
852 else
853 br.adjust( 1, 1, -1, 0 );
854 p->fillRect( br, cg.background() );
855 } else if ( tb->shape() == QTabBar:: RoundedSouth ) {
856 if ( ! ( flags & Style_Selected ) ) {
857 p->setPen( cg.background() );
858 p->drawLine( br.left(), br.top(),
859 br.right(), br.top() );
860 p->setPen( cg.dark() );
861 p->drawLine( br.left(), br.top() + 1,
862 br.right(), br.top() + 1);
863 br.adjust( 0, 2, -1, -2 );
864 if ( br.left() == 0 ) {
865 p->setPen( cg.light() );
866 p->drawPoint( br.left(), br.top() - 2 );
868 } else {
869 p->setPen( cg.background() );
870 p->drawLine( br.topLeft(), br.topRight() );
871 if ( br.left() == 0 ) {
872 p->setPen( cg.light() );
873 p->drawPoint( br.topLeft() );
875 br.adjust( 0, 1, 0, 0 );
878 p->setPen( cg.light() );
879 p->drawLine( br.topLeft(), br.bottomLeft() );
880 p->setPen( cg.dark() );
881 p->drawLine( br.bottomLeft(), br.bottomRight() );
882 p->drawLine( br.right(), br.top(), br.right(), br.bottom() - 1 );
883 br.adjust( 1, 0, -1, -1 );
885 if ( flags & Style_Selected )
887 p->fillRect( br.right() - 2, br.top(), 3, br.height(), cg.brush(QPalette::Highlight));
888 br.adjust( 1, 0, -3, -1 );
890 else
891 br.adjust( 1, 0, -1, -1 );
893 p->fillRect( br, cg.background() );
894 } else
895 QCommonStyle::drawControl( control, p, widget, r, cg, flags, data );
896 break;
899 case CE_PopupMenuItem:
901 if (! widget || data.isDefault())
902 break;
904 const QMenu *popupmenu = (const QMenu *) widget;
905 QMenuItem *mi = data.menuItem();
906 int tab = data.tabWidth();
907 int maxpmw = data.maxIconWidth();
909 if ( mi && mi->isSeparator() ) {
910 if ( widget->erasePixmap() && !widget->erasePixmap()->isNull() )
911 p->drawPixmap( r.topLeft(), *widget->erasePixmap(), r );
912 else
913 p->fillRect(r, cg.brush(QPalette::Button));
914 p->setPen( cg.mid() );
915 p->drawLine(r.left() + 12, r.top() + 1,
916 r.right() - 12, r.top() + 1);
917 p->setPen( cg.light() );
918 p->drawLine(r.left() + 12, r.top() + 2,
919 r.right() - 12, r.top() + 2);
920 break;
923 if (flags & Style_Active)
924 qDrawShadePanel(p, r, cg, true, 1,
925 &cg.brush(QPalette::Midlight));
926 else if ( widget->erasePixmap() && !widget->erasePixmap()->isNull() )
927 p->drawPixmap( r.topLeft(), *widget->erasePixmap(), r );
928 else
929 p->fillRect(r, cg.brush(QPalette::Button));
931 if ( !mi )
932 break;
934 maxpmw = qMax(maxpmw, 16);
936 QRect cr, ir, tr, sr;
937 // check column
938 cr.setRect(r.left(), r.top(), maxpmw, r.height());
939 // submenu indicator column
940 sr.setCoords(r.right() - maxpmw, r.top(), r.right(), r.bottom());
941 // tab/accelerator column
942 tr.setCoords(sr.left() - tab - 4, r.top(), sr.left(), r.bottom());
943 // item column
944 ir.setCoords(cr.right() + 4, r.top(), tr.right() - 4, r.bottom());
946 bool reverse = QApplication::isRightToLeft();
947 if ( reverse ) {
948 cr = visualRect( cr, r );
949 sr = visualRect( sr, r );
950 tr = visualRect( tr, r );
951 ir = visualRect( ir, r );
954 if (mi->isChecked() &&
955 ! (flags & Style_Active) &
956 (flags & Style_Enabled))
957 qDrawShadePanel(p, cr, cg, true, 1, &cg.brush(QPalette::Midlight));
959 if (mi->iconSet()) {
960 QIcon::Mode mode =
961 (flags & Style_Enabled) ? QIcon::Normal : QIcon::Disabled;
962 if ((flags & Style_Active) && (flags & Style_Enabled))
963 mode = QIcon::Active;
964 QPixmap pixmap;
965 if (popupmenu->isCheckable() && mi->isChecked())
966 pixmap =
967 mi->iconSet()->pixmap( QIcon::Small, mode, QIcon::On );
968 else
969 pixmap =
970 mi->iconSet()->pixmap( QIcon::Small, mode );
971 QRect pmr(QPoint(0, 0), pixmap.size());
972 pmr.moveCenter(cr.center());
973 p->setPen(cg.text());
974 p->drawPixmap(pmr.topLeft(), pixmap);
975 } else if (popupmenu->isCheckable() && mi->isChecked())
976 drawPrimitive(PE_CheckMark, p, cr, cg,
977 (flags & Style_Enabled) | Style_On);
979 QColor textcolor;
980 QColor embosscolor;
981 if (flags & Style_Active) {
982 if (! (flags & Style_Enabled))
983 textcolor = cg.midlight().dark();
984 else
985 textcolor = cg.buttonText();
986 embosscolor = cg.midlight().light();
987 } else if (! (flags & Style_Enabled)) {
988 textcolor = cg.text();
989 embosscolor = cg.light();
990 } else
991 textcolor = embosscolor = cg.buttonText();
992 p->setPen(textcolor);
994 if (mi->custom()) {
995 p->save();
996 if (! (flags & Style_Enabled)) {
997 p->setPen(cg.light());
998 mi->custom()->paint(p, cg, flags & Style_Active,
999 flags & Style_Enabled,
1000 ir.x() + 1, ir.y() + 1,
1001 ir.width() - 1, ir.height() - 1);
1002 p->setPen(textcolor);
1004 mi->custom()->paint(p, cg, flags & Style_Active,
1005 flags & Style_Enabled,
1006 ir.x(), ir.y(),
1007 ir.width(), ir.height());
1008 p->restore();
1011 QString text = mi->text();
1012 if (! text.isNull()) {
1013 int t = text.find('\t');
1015 // draw accelerator/tab-text
1016 if (t >= 0) {
1017 int alignFlag = Qt::AlignVCenter | Qt::TextShowMnemonic | Qt::TextDontClip | Qt::TextSingleLine;
1018 alignFlag |= ( reverse ? Qt::AlignLeft : Qt::AlignRight );
1019 if (! (flags & Style_Enabled)) {
1020 p->setPen(embosscolor);
1021 tr.translate(1, 1);
1022 p->drawText(tr, alignFlag, text.mid(t + 1));
1023 tr.translate(-1, -1);
1024 p->setPen(textcolor);
1027 p->drawText(tr, alignFlag, text.mid(t + 1));
1030 int alignFlag = Qt::AlignVCenter | Qt::TextShowMnemonic | Qt::TextDontClip | Qt::TextSingleLine;
1031 alignFlag |= ( reverse ? Qt::AlignRight : Qt::AlignLeft );
1033 if (! (flags & Style_Enabled)) {
1034 p->setPen(embosscolor);
1035 ir.translate(1, 1);
1036 p->drawText(ir, alignFlag, text, t);
1037 ir.translate(-1, -1);
1038 p->setPen(textcolor);
1041 p->drawText(ir, alignFlag, text, t);
1042 } else if (mi->pixmap()) {
1043 QPixmap pixmap = *mi->pixmap();
1044 if (pixmap.depth() == 1)
1045 p->setBackgroundMode(Qt::OpaqueMode);
1046 p->drawPixmap(ir.x(), ir.y() + (ir.height() - pixmap.height()) / 2, pixmap);
1047 if (pixmap.depth() == 1)
1048 p->setBackgroundMode(Qt::TransparentMode);
1051 if (mi->popup())
1052 drawPrimitive( (QApplication::isRightToLeft() ? PE_ArrowLeft : PE_ArrowRight),
1053 p, sr, cg, flags);
1054 break;
1057 case CE_MenuBarEmptyArea:
1059 p->fillRect(r, cg.brush(QPalette::Button));
1060 break;
1063 case CE_MenuBarItem:
1065 if ( flags & Style_Active )
1066 qDrawShadePanel(p, r, cg, true, 1, &cg.brush(QPalette::Midlight));
1067 else
1068 p->fillRect( r, cg.brush( QPalette::Button ) );
1070 if (data.isDefault())
1071 break;
1073 QMenuItem *mi = data.menuItem();
1074 drawItem(p, r, Qt::AlignCenter | Qt::TextShowMnemonic | Qt::TextDontClip | Qt::TextSingleLine, cg,
1075 flags & Style_Enabled, mi->pixmap(), mi->text(), -1,
1076 &cg.buttonText());
1077 break;
1080 case CE_ProgressBarGroove:
1081 drawLightBevel( p, r, cg, Style_Sunken, pixelMetric( PM_DefaultFrameWidth ),
1082 true, true, &cg.brush( QPalette::Background ) );
1083 break;
1085 default:
1086 QCommonStyle::drawControl(control, p, widget, r, cg, flags, data);
1087 break;
1091 void LightStyleV3::drawControlMask( ControlElement control,
1092 QPainter *p,
1093 const QWidget *widget,
1094 const QRect &r,
1095 const QStyleOption &data ) const
1097 switch (control) {
1098 case CE_PushButton:
1099 p->fillRect(r, Qt::color1);
1100 break;
1102 default:
1103 QCommonStyle::drawControlMask(control, p, widget, r, data);
1104 break;
1108 QRect LightStyleV3::subRect(SubRect subrect, const QWidget *widget) const
1110 QRect rect;
1112 switch (subrect) {
1113 case SR_PushButtonFocusRect:
1115 rect = QCommonStyle::subRect( SR_PushButtonContents, widget );
1116 int bm = pixelMetric( PM_ButtonMargin, widget ), hbm = bm / 2;
1117 rect.adjust( hbm, hbm, -hbm, -hbm );
1118 break;
1121 case SR_ComboBoxFocusRect:
1123 rect = QCommonStyle::subRect( SR_ComboBoxFocusRect, widget );
1124 rect.adjust( -1, -1, 1, 1 );
1125 break;
1128 case SR_CheckBoxFocusRect:
1130 const QCheckBox* cb = static_cast<const QCheckBox*>(widget);
1132 //Only checkbox, no label
1133 if (cb->text().isEmpty() && (cb->pixmap() == 0) )
1135 QRect bounding = cb->rect();
1136 QRect checkbox(bounding.x(), bounding.y() + (bounding.height() - 13)/2,
1137 13, 13);
1139 return checkbox;
1141 //Fallthrough intentional
1145 default:
1146 rect = QCommonStyle::subRect(subrect, widget);
1147 break;
1150 return rect;
1153 void LightStyleV3::drawComplexControl( ComplexControl control,
1154 QPainter* p,
1155 const QWidget* widget,
1156 const QRect& r,
1157 const QColorGroup& cg,
1158 SFlags flags,
1159 SCFlags controls,
1160 SCFlags active,
1161 const QStyleOption &data ) const
1163 switch (control) {
1164 case CC_ComboBox:
1166 const QComboBox *combobox = (const QComboBox *) widget;
1167 QRect frame, arrow, field;
1168 frame =
1169 QStyle::visualRect(querySubControlMetrics(CC_ComboBox, widget,
1170 SC_ComboBoxFrame, data),
1171 widget);
1172 arrow =
1173 QStyle::visualRect(querySubControlMetrics(CC_ComboBox, widget,
1174 SC_ComboBoxArrow, data),
1175 widget);
1176 field =
1177 QStyle::visualRect(querySubControlMetrics(CC_ComboBox, widget,
1178 SC_ComboBoxEditField, data),
1179 widget);
1181 if ((controls & SC_ComboBoxFrame) && frame.isValid())
1182 drawPrimitive( PE_Panel, p, frame, cg, flags | Style_Sunken );
1184 if ((controls & SC_ComboBoxArrow) && arrow.isValid()) {
1185 drawLightEtch( p, arrow, cg.button(), ( active == SC_ComboBoxArrow ) );
1186 arrow.adjust( 1, 1, -1, -1 );
1187 p->fillRect( arrow, cg.brush( QPalette::Button ) );
1188 arrow.adjust(3, 1, -1, -1);
1189 drawPrimitive(PE_ArrowDown, p, arrow, cg, flags);
1192 if ((controls & SC_ComboBoxEditField) && field.isValid()) {
1193 if (flags & Style_HasFocus) {
1194 if (! combobox->editable()) {
1195 QRect fr =
1196 QStyle::visualRect( subRect( SR_ComboBoxFocusRect, widget ),
1197 widget );
1198 p->fillRect( fr, cg.brush( QPalette::Highlight ) );
1199 drawPrimitive( PE_FocusRect, p, fr, cg,
1200 flags | Style_FocusAtBorder,
1201 QStyleOption(cg.highlight()));
1204 p->setPen(cg.highlightedText());
1205 } else {
1206 p->fillRect( field, ( ( flags & Style_Enabled ) ?
1207 cg.brush( QPalette::Base ) :
1208 cg.brush( QPalette::Background ) ) );
1209 p->setPen( cg.text() );
1213 break;
1216 case CC_SpinWidget:
1218 const Q3SpinWidget *spinwidget = (const Q3SpinWidget *) widget;
1219 QRect frame, up, down;
1221 frame = querySubControlMetrics(CC_SpinWidget, widget,
1222 SC_SpinWidgetFrame, data);
1223 up = spinwidget->upRect();
1224 down = spinwidget->downRect();
1226 if ((controls & SC_SpinWidgetFrame) && frame.isValid())
1227 drawPrimitive( PE_Panel, p, frame, cg, flags | Style_Sunken );
1229 if ((controls & SC_SpinWidgetUp) && up.isValid()) {
1230 PrimitiveElement pe = PE_SpinWidgetUp;
1231 if ( spinwidget->buttonSymbols() == Q3SpinWidget::PlusMinus )
1232 pe = PE_SpinWidgetPlus;
1234 p->setPen( cg.background() );
1235 p->drawLine( up.topLeft(), up.bottomLeft() );
1237 up.adjust( 1, 0, 0, 0 );
1238 p->fillRect( up, cg.brush( QPalette::Button ) );
1239 drawLightEtch( p, up, cg.button(), ( active == SC_SpinWidgetUp ) );
1241 up.addCoords( 1, 0, 0, 0 );
1242 drawPrimitive(pe, p, up, cg, flags |
1243 ((active == SC_SpinWidgetUp) ?
1244 Style_On | Style_Sunken : Style_Raised));
1247 if ((controls & SC_SpinWidgetDown) && down.isValid()) {
1248 PrimitiveElement pe = PE_SpinWidgetDown;
1249 if ( spinwidget->buttonSymbols() == Q3SpinWidget::PlusMinus )
1250 pe = PE_SpinWidgetMinus;
1252 p->setPen( cg.background() );
1253 p->drawLine( down.topLeft(), down.bottomLeft() );
1255 down.adjust( 1, 0, 0, 0 );
1256 p->fillRect( down, cg.brush( QPalette::Button ) );
1257 drawLightEtch( p, down, cg.button(), ( active == SC_SpinWidgetDown ) );
1259 down.adjust( 1, 0, 0, 0 );
1260 drawPrimitive(pe, p, down, cg, flags |
1261 ((active == SC_SpinWidgetDown) ?
1262 Style_On | Style_Sunken : Style_Raised));
1265 break;
1268 case CC_ScrollBar:
1270 const QScrollBar *scrollbar = (const QScrollBar *) widget;
1271 QRect addline, subline, subline2, addpage, subpage, slider, first, last;
1272 bool maxedOut = (scrollbar->minValue() == scrollbar->maxValue());
1274 subline = querySubControlMetrics(control, widget, SC_ScrollBarSubLine, data);
1275 addline = querySubControlMetrics(control, widget, SC_ScrollBarAddLine, data);
1276 subpage = querySubControlMetrics(control, widget, SC_ScrollBarSubPage, data);
1277 addpage = querySubControlMetrics(control, widget, SC_ScrollBarAddPage, data);
1278 slider = querySubControlMetrics(control, widget, SC_ScrollBarSlider, data);
1279 first = querySubControlMetrics(control, widget, SC_ScrollBarFirst, data);
1280 last = querySubControlMetrics(control, widget, SC_ScrollBarLast, data);
1282 subline2 = addline;
1283 if (scrollbar->orientation() == Qt::Horizontal)
1284 subline2.translate(-addline.width(), 0);
1285 else
1286 subline2.translate(0, -addline.height());
1288 if ((controls & SC_ScrollBarSubLine) && subline.isValid()) {
1289 drawPrimitive(PE_ScrollBarSubLine, p, subline, cg,
1290 Style_Enabled | ((active == SC_ScrollBarSubLine) ?
1291 Style_Down : Style_Default) |
1292 ((scrollbar->orientation() == Qt::Horizontal) ?
1293 Style_Horizontal : 0));
1295 if (subline2.isValid())
1296 drawPrimitive(PE_ScrollBarSubLine, p, subline2, cg,
1297 Style_Enabled | ((active == SC_ScrollBarSubLine) ?
1298 Style_Down : Style_Default) |
1299 ((scrollbar->orientation() == Qt::Horizontal) ?
1300 Style_Horizontal : 0));
1302 if ((controls & SC_ScrollBarAddLine) && addline.isValid())
1303 drawPrimitive(PE_ScrollBarAddLine, p, addline, cg,
1304 Style_Enabled | ((active == SC_ScrollBarAddLine) ?
1305 Style_Down : Style_Default) |
1306 ((scrollbar->orientation() == Qt::Horizontal) ?
1307 Style_Horizontal : 0));
1308 if ((controls & SC_ScrollBarSubPage) && subpage.isValid())
1309 drawPrimitive(PE_ScrollBarSubPage, p, subpage, cg,
1310 Style_Enabled | ((active == SC_ScrollBarSubPage) ?
1311 Style_Down : Style_Default) |
1312 ((scrollbar->orientation() == Qt::Horizontal) ?
1313 Style_Horizontal : 0));
1314 if ((controls & SC_ScrollBarAddPage) && addpage.isValid())
1315 drawPrimitive(PE_ScrollBarAddPage, p, addpage, cg,
1316 ((maxedOut) ? Style_Default : Style_Enabled) |
1317 ((active == SC_ScrollBarAddPage) ?
1318 Style_Down : Style_Default) |
1319 ((scrollbar->orientation() == Qt::Horizontal) ?
1320 Style_Horizontal : 0));
1321 if ((controls & SC_ScrollBarFirst) && first.isValid())
1322 drawPrimitive(PE_ScrollBarFirst, p, first, cg,
1323 Style_Enabled | ((active == SC_ScrollBarFirst) ?
1324 Style_Down : Style_Default) |
1325 ((scrollbar->orientation() == Qt::Horizontal) ?
1326 Style_Horizontal : 0));
1327 if ((controls & SC_ScrollBarLast) && last.isValid())
1328 drawPrimitive(PE_ScrollBarLast, p, last, cg,
1329 Style_Enabled | ((active == SC_ScrollBarLast) ?
1330 Style_Down : Style_Default) |
1331 ((scrollbar->orientation() == Qt::Horizontal) ?
1332 Style_Horizontal : 0));
1333 if ((controls & SC_ScrollBarSlider) && slider.isValid()) {
1334 drawPrimitive(PE_ScrollBarSlider, p, slider, cg,
1335 Style_Enabled | ((active == SC_ScrollBarSlider) ?
1336 Style_Down : Style_Default) |
1337 ((scrollbar->orientation() == Qt::Horizontal) ?
1338 Style_Horizontal : 0));
1340 // ### perhaps this should not be able to accept focus if maxedOut?
1341 if (scrollbar->hasFocus()) {
1342 QRect fr(slider.x() + 2, slider.y() + 2,
1343 slider.width() - 5, slider.height() - 5);
1344 drawPrimitive(PE_FocusRect, p, fr, cg, Style_Default);
1348 break;
1351 case CC_Slider:
1353 const QSlider *slider = (const QSlider *) widget;
1354 QRect groove = querySubControlMetrics(CC_Slider, widget, SC_SliderGroove,
1355 data),
1356 handle = querySubControlMetrics(CC_Slider, widget, SC_SliderHandle,
1357 data);
1359 if ((controls & SC_SliderGroove) && groove.isValid()) {
1360 QColor grooveColor = cg.midlight();
1361 if (!(flags & Style_Enabled))
1362 grooveColor = cg.background();
1365 QBrush brush(grooveColor);
1366 drawLightBevel( p, groove, cg,
1367 ( ( flags | Style_Raised ) ^ Style_Raised ) |
1368 ( ( flags & Style_Enabled ) ? Style_Sunken :
1369 Style_Default ), 2, true, true,
1370 &brush );
1371 groove.adjust( 2, 2, -2, -2 );
1372 drawLightEtch( p, groove, grooveColor, false );
1374 if (flags & Style_HasFocus) {
1375 groove.adjust( -2, -2, 2, 2 );
1376 drawPrimitive( PE_FocusRect, p, groove, cg, flags );
1380 if ((controls & SC_SliderHandle) && handle.isValid()) {
1381 QColor sliderColor = cg.highlight();
1382 if (!(flags & Style_Enabled))
1383 sliderColor = cg.button();
1385 p->setPen( sliderColor.light() );
1387 p->drawLine( handle.topLeft(), handle.topRight() );
1388 p->drawLine( handle.left(), handle.top() + 1,
1389 handle.left(), handle.bottom() - 1 );
1390 p->setPen( sliderColor.dark() );
1391 p->drawLine( handle.left(), handle.bottom(),
1392 handle.right() - 1, handle.bottom() );
1393 p->drawLine( handle.topRight(), handle.bottomRight() );
1394 handle.adjust( 1, 1, -1, -1 );
1395 p->fillRect( handle, sliderColor );
1396 p->setPen( cg.midlight() );
1398 if ( slider->orientation() == Qt::Horizontal )
1399 p->drawLine( handle.left() + handle.width() / 2,
1400 handle.top() + 1,
1401 handle.left() + handle.width() / 2,
1402 handle.bottom() - 1 );
1403 else
1404 p->drawLine( handle.left() + 1,
1405 handle.top() + handle.height() / 2,
1406 handle.right() - 1,
1407 handle.top() + handle.height() / 2 );
1410 if (controls & SC_SliderTickmarks)
1411 QCommonStyle::drawComplexControl(control, p, widget, r, cg, flags,
1412 SC_SliderTickmarks, active, data );
1413 break;
1416 case CC_ListView:
1417 // use the base style for CC_ListView
1418 basestyle->drawComplexControl(control, p, widget, r, cg, flags,
1419 controls, active, data);
1420 break;
1422 default:
1423 QCommonStyle::drawComplexControl(control, p, widget, r, cg, flags,
1424 controls, active, data);
1425 break;
1429 QRect LightStyleV3::querySubControlMetrics( ComplexControl control,
1430 const QWidget *widget,
1431 SubControl sc,
1432 const QStyleOption &data ) const
1434 QRect ret;
1436 switch (control) {
1437 case CC_ComboBox:
1439 int fw = pixelMetric( PM_DefaultFrameWidth, widget );
1440 int sb = pixelMetric( PM_ScrollBarExtent ); // width of the arrow
1442 switch ( sc ) {
1443 case SC_ComboBoxFrame:
1444 ret = widget->rect();
1445 break;
1446 case SC_ComboBoxArrow:
1447 ret.setRect( widget->width() - fw - sb, fw,
1448 sb, widget->height() - fw*2 );
1449 break;
1450 case SC_ComboBoxEditField:
1451 ret.setRect( fw, fw, widget->width() - fw*2 - sb - 1,
1452 widget->height() - fw*2 );
1453 break;
1454 default:
1455 break;
1458 break;
1461 case CC_ScrollBar:
1463 const QScrollBar *scrollbar = (const QScrollBar *) widget;
1464 int sliderstart = scrollbar->sliderStart();
1465 int sbextent = pixelMetric(PM_ScrollBarExtent, widget);
1466 int maxlen = ((scrollbar->orientation() == Qt::Horizontal) ?
1467 scrollbar->width() : scrollbar->height()) - (sbextent * 3);
1468 int sliderlen;
1470 // calculate slider length
1471 if (scrollbar->maxValue() != scrollbar->minValue()) {
1472 uint range = scrollbar->maxValue() - scrollbar->minValue();
1473 sliderlen = (scrollbar->pageStep() * maxlen) /
1474 (range + scrollbar->pageStep());
1476 int slidermin = pixelMetric( PM_ScrollBarSliderMin, widget );
1477 if ( sliderlen < slidermin || range > INT_MAX / 2 )
1478 sliderlen = slidermin;
1479 if ( sliderlen > maxlen )
1480 sliderlen = maxlen;
1481 } else
1482 sliderlen = maxlen;
1484 switch (sc) {
1485 case SC_ScrollBarSubLine:
1486 // top/left button
1487 ret.setRect(0, 0, sbextent, sbextent);
1488 break;
1490 case SC_ScrollBarAddLine:
1491 // bottom/right button
1492 if (scrollbar->orientation() == Qt::Horizontal)
1493 ret.setRect(scrollbar->width() - sbextent, 0, sbextent, sbextent);
1494 else
1495 ret.setRect(0, scrollbar->height() - sbextent, sbextent, sbextent);
1496 break;
1498 case SC_ScrollBarSubPage:
1499 // between top/left button and slider
1500 if (scrollbar->orientation() == Qt::Horizontal)
1501 ret.setRect(sbextent, 0, sliderstart - sbextent, sbextent);
1502 else
1503 ret.setRect(0, sbextent, sbextent, sliderstart - sbextent);
1504 break;
1506 case SC_ScrollBarAddPage:
1507 // between bottom/right button and slider
1508 if (scrollbar->orientation() == Qt::Horizontal)
1509 ret.setRect(sliderstart + sliderlen, 0, maxlen - sliderstart -
1510 sliderlen + sbextent, sbextent);
1511 else
1512 ret.setRect(0, sliderstart + sliderlen, sbextent, maxlen -
1513 sliderstart - sliderlen + sbextent);
1514 break;
1516 case SC_ScrollBarGroove:
1517 if (scrollbar->orientation() == Qt::Horizontal)
1518 ret.setRect(sbextent, 0, maxlen, sbextent );
1519 else
1520 ret.setRect(0, sbextent, sbextent, maxlen );
1521 break;
1523 case SC_ScrollBarSlider:
1524 if (scrollbar->orientation() == Qt::Horizontal)
1525 ret.setRect(sliderstart, 0, sliderlen, sbextent);
1526 else
1527 ret.setRect(0, sliderstart, sbextent, sliderlen);
1528 break;
1530 default:
1531 break;
1534 break;
1537 case CC_Slider:
1539 const QSlider *slider = (const QSlider *) widget;
1540 int tickOffset = pixelMetric( PM_SliderTickmarkOffset, widget );
1541 int thickness = pixelMetric( PM_SliderControlThickness, widget );
1543 switch ( sc ) {
1544 case SC_SliderGroove:
1545 if ( slider->orientation() == Qt::Horizontal )
1546 ret.setRect( 0, tickOffset, slider->width(), thickness );
1547 else
1548 ret.setRect( tickOffset, 0, thickness, slider->height() );
1549 break;
1551 case SC_SliderHandle:
1553 int pos = slider->sliderStart();
1554 int len = pixelMetric( PM_SliderLength, widget );
1556 if ( slider->orientation() == Qt::Horizontal )
1557 ret.setRect( pos + 2, tickOffset + 2, len - 4, thickness - 4 );
1558 else
1559 ret.setRect( tickOffset + 2, pos + 2, thickness - 4, len - 4 );
1560 break;
1563 default:
1564 ret = QCommonStyle::querySubControlMetrics(control, widget, sc, data);
1565 break;
1568 break;
1571 default:
1572 ret = QCommonStyle::querySubControlMetrics(control, widget, sc, data);
1573 break;
1576 return ret;
1579 QStyle::SubControl LightStyleV3::querySubControl( ComplexControl control,
1580 const QWidget *widget,
1581 const QPoint &pos,
1582 const QStyleOption &data ) const
1584 QStyle::SubControl ret =
1585 QCommonStyle::querySubControl(control, widget, pos, data);
1587 // this is an ugly hack, but i really don't care, it's the quickest way to
1588 // enabled the third button
1589 if (control == CC_ScrollBar &&
1590 ret == SC_None)
1591 ret = SC_ScrollBarSubLine;
1593 return ret;
1596 int LightStyleV3::pixelMetric( PixelMetric metric,
1597 const QWidget *widget ) const
1599 int ret;
1601 switch (metric) {
1602 case PM_ButtonMargin:
1603 ret = 6;
1604 break;
1606 case PM_ButtonShiftHorizontal:
1607 case PM_ButtonShiftVertical:
1608 ret = 0;
1609 break;
1611 case PM_ButtonDefaultIndicator:
1612 ret = 0;
1613 break;
1615 case PM_DefaultFrameWidth:
1616 ret = 2;
1617 break;
1619 case PM_IndicatorWidth:
1620 case PM_IndicatorHeight:
1621 case PM_ExclusiveIndicatorWidth:
1622 case PM_ExclusiveIndicatorHeight:
1623 ret = 13;
1624 break;
1626 case PM_TabBarTabOverlap:
1627 case PM_TabBarBaseOverlap:
1628 ret = 0;
1629 break;
1631 case PM_ScrollBarExtent:
1632 case PM_ScrollBarSliderMin:
1633 ret = 15;
1634 break;
1636 case PM_MenuBarFrameWidth:
1637 ret = 1;
1638 break;
1640 case PM_ProgressBarChunkWidth:
1641 ret = 1;
1642 break;
1644 case PM_DockWindowHandleExtent:
1645 ret = 8;
1646 break;
1648 case PM_DockWindowSeparatorExtent:
1649 ret = 8;
1650 break;
1652 case PM_SplitterWidth:
1653 ret = 8;
1654 break;
1656 case PM_SliderLength:
1657 ret = 25;
1658 break;
1660 case PM_SliderThickness:
1661 ret = 11;
1662 break;
1664 case PM_SliderControlThickness:
1666 const QSlider * sl = (const QSlider *) widget;
1667 int space = (sl->orientation() == Qt::Horizontal) ? sl->height()
1668 : sl->width();
1669 int ticks = sl->tickmarks();
1670 int n = 0;
1671 if ( ticks & QSlider::TicksAbove ) n++;
1672 if ( ticks & QSlider::TicksBelow ) n++;
1673 if ( !n ) {
1674 ret = space;
1675 break;
1678 int thick = 6; // Magic constant to get 5 + 16 + 5
1680 space -= thick;
1681 //### the two sides may be unequal in size
1682 if ( space > 0 )
1683 thick += (space * 2) / (n + 2);
1684 ret = thick;
1685 break;
1688 case PM_MaximumDragDistance:
1689 ret = -1;
1690 break;
1692 default:
1693 ret = QCommonStyle::pixelMetric(metric, widget);
1694 break;
1697 return ret;
1700 QSize LightStyleV3::sizeFromContents( ContentsType contents,
1701 const QWidget *widget,
1702 const QSize &contentsSize,
1703 const QStyleOption &data ) const
1705 QSize ret;
1707 switch (contents) {
1708 case CT_ComboBox:
1710 int fw = pixelMetric( PM_DefaultFrameWidth, widget ) * 2;
1711 int sb = pixelMetric( PM_ScrollBarExtent ); // width of the arrow
1712 int w = contentsSize.width();
1713 int h = contentsSize.height();
1715 w += fw + sb + 1;
1716 h += fw;
1718 // try to keep a similar height to buttons
1719 if ( h < 21 )
1720 h = 21;
1722 ret = QSize( w, h );
1723 break;
1726 case CT_PushButton:
1728 const QPushButton *button = (const QPushButton *) widget;
1729 ret = QCommonStyle::sizeFromContents( contents, widget, contentsSize, data );
1730 int w = ret.width(), h = ret.height();
1731 int dbi = pixelMetric( PM_ButtonDefaultIndicator, widget ) * 2;
1732 int mw = 80 - dbi, mh = 25 - dbi;
1734 // only expand the button if we are displaying text...
1735 if ( ! button->text().isEmpty() ) {
1736 // button minimum size
1737 if ( w < mw )
1738 w = mw;
1739 if ( h < mh )
1740 h = mh;
1743 ret = QSize( w, h );
1744 break;
1747 case CT_PopupMenuItem:
1749 if (! widget || data.isDefault())
1750 break;
1752 QMenuItem *mi = data.menuItem();
1753 const QMenu *popupmenu = (const QMenu *) widget;
1754 int maxpmw = data.maxIconWidth();
1755 int w = contentsSize.width(), h = contentsSize.height();
1757 if (mi->custom()) {
1758 w = mi->custom()->sizeHint().width();
1759 h = mi->custom()->sizeHint().height();
1760 if (! mi->custom()->fullSpan() && h < 22)
1761 h = 22;
1762 } else if(mi->widget()) {
1763 } else if (mi->isSeparator()) {
1764 w = 10;
1765 h = 4;
1766 } else {
1767 // check is at least 16x16
1768 if (h < 16)
1769 h = 16;
1770 if (mi->pixmap())
1771 h = qMax(h, mi->pixmap()->height());
1772 else if (! mi->text().isNull())
1773 h = qMax(h, popupmenu->fontMetrics().height() + 2);
1774 if (mi->iconSet() != 0)
1775 h = qMax(h, mi->iconSet()->pixmap(QIcon::Small,
1776 QIcon::Normal).height());
1777 h += 2;
1780 // check | 4 pixels | item | 8 pixels | accel | 4 pixels | check
1782 // check is at least 16x16
1783 maxpmw = qMax(maxpmw, 16);
1784 w += (maxpmw * 2) + 8;
1786 if (! mi->text().isNull() && mi->text().find('\t') >= 0)
1787 w += 8;
1789 ret = QSize(w, h);
1790 break;
1793 case CT_ProgressBar:
1795 const QProgressBar* pb = static_cast<const QProgressBar*>(widget);
1797 //If we have to display the indicator, and we do it on RHS, give some more room
1798 //for it. This tries to match the logic and the spacing in SR_ProgressBarGroove/Contents
1799 //sizing in QCommonStyle.
1800 if (pb->percentageVisible() &&
1801 (pb->indicatorFollowsStyle() || ! pb->centerIndicator()))
1803 int addw = pb->fontMetrics().width("100%") + 6;
1804 return QSize(contentsSize.width() + addw, contentsSize.height());
1806 else
1807 return contentsSize; //Otherwise leave unchanged
1809 break;
1812 default:
1813 ret = QCommonStyle::sizeFromContents(contents, widget, contentsSize, data);
1814 break;
1817 return ret;
1820 int LightStyleV3::styleHint( StyleHint stylehint,
1821 const QWidget *widget,
1822 const QStyleOption &option,
1823 QStyleHintReturn* returnData ) const
1825 int ret;
1827 switch (stylehint) {
1828 case SH_EtchDisabledText:
1829 case SH_Slider_SnapToValue:
1830 case SH_PrintDialog_RightAlignButtons:
1831 case SH_FontDialog_SelectAssociatedText:
1832 case SH_MenuBar_AltKeyNavigation:
1833 case SH_MenuBar_MouseTracking:
1834 case SH_PopupMenu_MouseTracking:
1835 case SH_ComboBox_ListMouseTracking:
1836 case SH_ScrollBar_MiddleClickAbsolutePosition:
1837 ret = 1;
1838 break;
1840 case SH_MainWindow_SpaceBelowMenuBar:
1841 ret = 0;
1842 break;
1844 case SH_ScrollBar_BackgroundMode:
1845 ret = Qt::NoBackground;
1846 break;
1848 default:
1849 ret = QCommonStyle::styleHint(stylehint, widget, option, returnData);
1850 break;
1853 return ret;
1856 QPixmap LightStyleV3::stylePixmap( StylePixmap stylepixmap,
1857 const QWidget *widget,
1858 const QStyleOption &data ) const
1860 return basestyle->stylePixmap( stylepixmap, widget, data );
1862 #include "lightstyle-v3.moc"