source: trunk/src/gui/styles/qmotifstyle.cpp@ 104

Last change on this file since 104 was 2, checked in by Dmitry A. Kuminov, 16 years ago

Initially imported qt-all-opensource-src-4.5.1 from Trolltech.

File size: 102.8 KB
Line 
1/****************************************************************************
2**
3** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
4** Contact: Qt Software Information ([email protected])
5**
6** This file is part of the QtGui module of the Qt Toolkit.
7**
8** $QT_BEGIN_LICENSE:LGPL$
9** Commercial Usage
10** Licensees holding valid Qt Commercial licenses may use this file in
11** accordance with the Qt Commercial License Agreement provided with the
12** Software or, alternatively, in accordance with the terms contained in
13** a written agreement between you and Nokia.
14**
15** GNU Lesser General Public License Usage
16** Alternatively, this file may be used under the terms of the GNU Lesser
17** General Public License version 2.1 as published by the Free Software
18** Foundation and appearing in the file LICENSE.LGPL included in the
19** packaging of this file. Please review the following information to
20** ensure the GNU Lesser General Public License version 2.1 requirements
21** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
22**
23** In addition, as a special exception, Nokia gives you certain
24** additional rights. These rights are described in the Nokia Qt LGPL
25** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
26** package.
27**
28** GNU General Public License Usage
29** Alternatively, this file may be used under the terms of the GNU
30** General Public License version 3.0 as published by the Free Software
31** Foundation and appearing in the file LICENSE.GPL included in the
32** packaging of this file. Please review the following information to
33** ensure the GNU General Public License version 3.0 requirements will be
34** met: http://www.gnu.org/copyleft/gpl.html.
35**
36** If you are unsure which license is appropriate for your use, please
37** contact the sales department at [email protected].
38** $QT_END_LICENSE$
39**
40****************************************************************************/
41
42#include "qmotifstyle.h"
43#include "qcdestyle.h"
44
45#if !defined(QT_NO_STYLE_MOTIF) || defined(QT_PLUGIN)
46
47#include "qmenu.h"
48#include "qapplication.h"
49#include "qpainter.h"
50#include "qdrawutil.h"
51#include "qpixmap.h"
52#include "qpalette.h"
53#include "qwidget.h"
54#include "qpushbutton.h"
55#include "qscrollbar.h"
56#include "qtabbar.h"
57#include "qtabwidget.h"
58#include "qlistview.h"
59#include "qsplitter.h"
60#include "qslider.h"
61#include "qcombobox.h"
62#include "qlineedit.h"
63#include "qprogressbar.h"
64#include "qimage.h"
65#include "qfocusframe.h"
66#include "qdebug.h"
67#include "qpainterpath.h"
68#include "qmotifstyle_p.h"
69#include "qdialogbuttonbox.h"
70#include "qformlayout.h"
71#include <limits.h>
72#include <QtGui/qgraphicsproxywidget.h>
73#include <QtGui/qgraphicsview.h>
74
75#ifdef Q_WS_X11
76#include "qx11info_x11.h"
77#endif
78
79QT_BEGIN_NAMESPACE
80
81// old constants that might still be useful...
82static const int motifItemFrame = 2; // menu item frame width
83static const int motifSepHeight = 2; // separator item height
84static const int motifItemHMargin = 3; // menu item hor text margin
85static const int motifItemVMargin = 2; // menu item ver text margin
86static const int motifArrowHMargin = 6; // arrow horizontal margin
87static const int motifTabSpacing = 12; // space between text and tab
88static const int motifCheckMarkHMargin = 2; // horiz. margins of check mark
89static const int motifCheckMarkSpace = 16;
90
91
92/*!
93 \class QMotifStyle
94 \brief The QMotifStyle class provides Motif look and feel.
95
96 \ingroup appearance
97
98 This class implements the Motif look and feel. It closely
99 resembles the original Motif look as defined by the Open Group,
100 but with some minor improvements. The Motif style is Qt's default
101 GUI style on Unix platforms.
102
103 \img qmotifstyle.png
104 \sa QWindowsXPStyle, QMacStyle, QWindowsStyle, QPlastiqueStyle, QCDEStyle
105*/
106
107/*!
108 \variable QMotifStyle::focus
109 \internal
110*/
111
112/*!
113 Constructs a QMotifStyle.
114
115 If \a useHighlightCols is false (the default), the style will
116 polish the application's color palette to emulate the Motif way of
117 highlighting, which is a simple inversion between the base and the
118 text color.
119*/
120QMotifStyle::QMotifStyle(bool useHighlightCols)
121 : QCommonStyle(*new QMotifStylePrivate)
122{
123 focus = 0;
124 highlightCols = useHighlightCols;
125}
126
127
128/*!
129 \internal
130*/
131QMotifStyle::QMotifStyle(QMotifStylePrivate &dd, bool useHighlightColors)
132 : QCommonStyle(dd)
133{
134 focus = 0;
135 highlightCols = useHighlightColors;
136}
137
138
139/*!
140 \overload
141
142 Destroys the style.
143*/
144QMotifStyle::~QMotifStyle()
145{
146 delete focus;
147}
148
149/*!
150 \internal
151 Animate indeterminate progress bars only when visible
152*/
153bool QMotifStyle::eventFilter(QObject *o, QEvent *e)
154{
155#ifndef QT_NO_PROGRESSBAR
156 Q_D(QMotifStyle);
157 switch(e->type()) {
158 case QEvent::StyleChange:
159 case QEvent::Show:
160 if (QProgressBar *bar = qobject_cast<QProgressBar *>(o)) {
161 d->bars << bar;
162 if (d->bars.size() == 1) {
163 Q_ASSERT(d->animationFps> 0);
164 d->animateTimer = startTimer(1000 / d->animationFps);
165 }
166 }
167 break;
168 case QEvent::Destroy:
169 case QEvent::Hide:
170 // reinterpret_cast because there is no type info when getting
171 // the destroy event. We know that it is a QProgressBar.
172 if (QProgressBar *bar = reinterpret_cast<QProgressBar *>(o)) {
173 d->bars.removeAll(bar);
174 if (d->bars.isEmpty() && d->animateTimer) {
175 killTimer(d->animateTimer);
176 d->animateTimer = 0;
177 }
178 }
179 default:
180 break;
181 }
182#endif // QT_NO_PROGRESSBAR
183 return QStyle::eventFilter(o, e);
184}
185
186/*!
187 \internal
188*/
189QIcon QMotifStyle::standardIconImplementation(StandardPixmap standardIcon, const QStyleOption *opt,
190 const QWidget *widget) const
191{
192 return QCommonStyle::standardIconImplementation(standardIcon, opt, widget);
193}
194
195/*!
196 \reimp
197*/
198void QMotifStyle::timerEvent(QTimerEvent *event)
199{
200#ifndef QT_NO_PROGRESSBAR
201 Q_D(QMotifStyle);
202 if (event->timerId() == d->animateTimer) {
203 Q_ASSERT(d->animationFps > 0);
204 d->animateStep = d->startTime.elapsed() / (1000 / d->animationFps);
205 foreach (QProgressBar *bar, d->bars) {
206 if ((bar->minimum() == 0 && bar->maximum() == 0))
207 bar->update();
208 }
209 }
210#endif // QT_NO_PROGRESSBAR
211 event->ignore();
212}
213
214
215QMotifStylePrivate::QMotifStylePrivate()
216#ifndef QT_NO_PROGRESSBAR
217 : animationFps(25), animateTimer(0), animateStep(0)
218#endif
219{
220}
221
222/*!
223 If \a arg is false, the style will polish the application's color
224 palette to emulate the Motif way of highlighting, which is a
225 simple inversion between the base and the text color.
226
227 The effect will show up the next time an application palette is
228 set via QApplication::setPalette(). The current color palette of
229 the application remains unchanged.
230
231 \sa QStyle::polish()
232*/
233void QMotifStyle::setUseHighlightColors(bool arg)
234{
235 highlightCols = arg;
236}
237
238/*!
239 Returns true if the style treats the highlight colors of the
240 palette in a Motif-like manner, which is a simple inversion
241 between the base and the text color; otherwise returns false. The
242 default is false.
243*/
244bool QMotifStyle::useHighlightColors() const
245{
246 return highlightCols;
247}
248
249/*! \reimp */
250
251void QMotifStyle::polish(QPalette& pal)
252{
253 if (pal.brush(QPalette::Active, QPalette::Light) == pal.brush(QPalette::Active, QPalette::Base)) {
254 QColor nlight = pal.color(QPalette::Active, QPalette::Light).darker(108);
255 pal.setColor(QPalette::Active, QPalette::Light, nlight) ;
256 pal.setColor(QPalette::Disabled, QPalette::Light, nlight) ;
257 pal.setColor(QPalette::Inactive, QPalette::Light, nlight) ;
258 }
259
260 if (highlightCols)
261 return;
262
263 // force the ugly motif way of highlighting *sigh*
264 pal.setColor(QPalette::Active, QPalette::Highlight,
265 pal.color(QPalette::Active, QPalette::Text));
266 pal.setColor(QPalette::Active, QPalette::HighlightedText,
267 pal.color(QPalette::Active, QPalette::Base));
268 pal.setColor(QPalette::Disabled, QPalette::Highlight,
269 pal.color(QPalette::Disabled, QPalette::Text));
270 pal.setColor(QPalette::Disabled, QPalette::HighlightedText,
271 pal.color(QPalette::Disabled, QPalette::Base));
272 pal.setColor(QPalette::Inactive, QPalette::Highlight,
273 pal.color(QPalette::Active, QPalette::Text));
274 pal.setColor(QPalette::Inactive, QPalette::HighlightedText,
275 pal.color(QPalette::Active, QPalette::Base));
276}
277
278/*!
279 \reimp
280 \internal
281 Keep QStyle::polish() visible.
282*/
283void QMotifStyle::polish(QWidget* widget)
284{
285 QStyle::polish(widget);
286#ifndef QT_NO_PROGRESSBAR
287 if (qobject_cast<QProgressBar *>(widget))
288 widget->installEventFilter(this);
289#endif
290}
291
292/*!
293 \reimp
294 \internal
295 Keep QStyle::polish() visible.
296*/
297void QMotifStyle::unpolish(QWidget* widget)
298{
299 QCommonStyle::unpolish(widget);
300#ifndef QT_NO_PROGRESSBAR
301 if (qobject_cast<QProgressBar *>(widget))
302 widget->removeEventFilter(this);
303#endif
304}
305
306
307/*!
308 \reimp
309 \internal
310 Keep QStyle::polish() visible.
311*/
312void QMotifStyle::polish(QApplication* a)
313{
314 QCommonStyle::polish(a);
315}
316
317
318/*!
319 \reimp
320 \internal
321 Keep QStyle::polish() visible.
322*/
323void QMotifStyle::unpolish(QApplication* a)
324{
325 QCommonStyle::unpolish(a);
326}
327
328static void rot(QPolygon& a, int n)
329{
330 QPolygon r(a.size());
331 for (int i = 0; i < (int)a.size(); i++) {
332 switch (n) {
333 case 1: r.setPoint(i,-a[i].y(),a[i].x()); break;
334 case 2: r.setPoint(i,-a[i].x(),-a[i].y()); break;
335 case 3: r.setPoint(i,a[i].y(),-a[i].x()); break;
336 }
337 }
338 a = r;
339}
340
341
342/*!
343 \reimp
344*/
345void QMotifStyle::drawPrimitive(PrimitiveElement pe, const QStyleOption *opt, QPainter *p,
346 const QWidget *w) const
347{
348 switch(pe) {
349 case PE_Q3CheckListExclusiveIndicator:
350 if (const QStyleOptionQ3ListView *lv = qstyleoption_cast<const QStyleOptionQ3ListView *>(opt)) {
351 if (lv->items.isEmpty())
352 return;
353
354 if (lv->state & State_Enabled)
355 p->setPen(QPen(opt->palette.text().color()));
356 else
357 p->setPen(QPen(lv->palette.color(QPalette::Disabled, QPalette::Text)));
358 QPolygon a;
359
360 int cx = opt->rect.width()/2 - 1;
361 int cy = opt->rect.height()/2;
362 int e = opt->rect.width()/2 - 1;
363 for (int i = 0; i < 3; i++) { //penWidth 2 doesn't quite work
364 a.setPoints(4, cx-e, cy, cx, cy-e, cx+e, cy, cx, cy+e);
365 p->drawPolygon(a);
366 e--;
367 }
368 if (opt->state & State_On) {
369 if (lv->state & State_Enabled)
370 p->setPen(QPen(opt->palette.text().color()));
371 else
372 p->setPen(QPen(lv->palette.color(QPalette::Disabled,
373 QPalette::Text)));
374 QBrush saveBrush = p->brush();
375 p->setBrush(opt->palette.text());
376 e = e - 2;
377 a.setPoints(4, cx-e, cy, cx, cy-e, cx+e, cy, cx, cy+e);
378 p->drawPolygon(a);
379 p->setBrush(saveBrush);
380 }
381 }
382 break;
383
384 case PE_FrameTabWidget:
385 case PE_FrameWindow:
386 qDrawShadePanel(p, opt->rect, opt->palette, QStyle::State_None, pixelMetric(PM_DefaultFrameWidth));
387 break;
388 case PE_FrameFocusRect:
389 if (const QStyleOptionFocusRect *fropt = qstyleoption_cast<const QStyleOptionFocusRect *>(opt)) {
390 if ((fropt->state & State_HasFocus) && focus && focus->isVisible()
391 && !(fropt->state & QStyle::State_Item))
392 break;
393 QCommonStyle::drawPrimitive(pe, opt, p, w);
394 }
395 break;
396
397 case PE_IndicatorToolBarHandle: {
398 p->save();
399 p->translate(opt->rect.x(), opt->rect.y());
400
401 QColor dark(opt->palette.dark().color());
402 QColor light(opt->palette.light().color());
403 int i;
404 if (opt->state & State_Horizontal) {
405 int h = opt->rect.height();
406 if (h > 6) {
407 if (opt->state & State_On)
408 p->fillRect(1, 1, 8, h - 2, opt->palette.highlight());
409 QPolygon a(2 * ((h-6)/3));
410 int y = 3 + (h%3)/2;
411 p->setPen(dark);
412 p->drawLine(8, 1, 8, h-2);
413 for (i=0; 2*i < a.size(); ++i) {
414 a.setPoint(2*i, 5, y+1+3*i);
415 a.setPoint(2*i+1, 2, y+2+3*i);
416 }
417 p->drawPoints(a);
418 p->setPen(light);
419 p->drawLine(9, 1, 9, h-2);
420 for (i=0; 2*i < a.size(); i++) {
421 a.setPoint(2*i, 4, y+3*i);
422 a.setPoint(2*i+1, 1, y+1+3*i);
423 }
424 p->drawPoints(a);
425 // if (drawBorder) {
426 // p->setPen(QPen(Qt::darkGray));
427 // p->drawLine(0, opt->rect.height() - 1,
428 // tbExtent, opt->rect.height() - 1);
429 // }
430 }
431 } else {
432 int w = opt->rect.width();
433 if (w > 6) {
434 if (opt->state & State_On)
435 p->fillRect(1, 1, w - 2, 9, opt->palette.highlight());
436 QPolygon a(2 * ((w-6)/3));
437
438 int x = 3 + (w%3)/2;
439 p->setPen(dark);
440 p->drawLine(1, 8, w-2, 8);
441 for (i=0; 2*i < a.size(); ++i) {
442 a.setPoint(2*i, x+1+3*i, 6);
443 a.setPoint(2*i+1, x+2+3*i, 3);
444 }
445 p->drawPoints(a);
446 p->setPen(light);
447 p->drawLine(1, 9, w-2, 9);
448 for (i=0; 2*i < a.size(); ++i) {
449 a.setPoint(2*i, x+3*i, 5);
450 a.setPoint(2*i+1, x+1+3*i, 2);
451 }
452 p->drawPoints(a);
453 // if (drawBorder) {
454 // p->setPen(QPen(Qt::darkGray));
455 // p->drawLine(opt->rect.width() - 1, 0,
456 // opt->rect.width() - 1, tbExtent);
457 // }
458 }
459 }
460 p->restore();
461 break; }
462
463 case PE_PanelButtonCommand:
464 case PE_PanelButtonBevel:
465 case PE_PanelButtonTool: {
466 QBrush fill;
467 if (opt->state & State_Sunken)
468 fill = opt->palette.brush(QPalette::Mid);
469 else if ((opt->state & State_On) && (opt->state & State_Enabled))
470 fill = QBrush(opt->palette.mid().color(), Qt::Dense4Pattern);
471 else
472 fill = opt->palette.brush(QPalette::Button);
473 if ((opt->state & State_Enabled || opt->state & State_On) || !(opt->state & State_AutoRaise))
474 qDrawShadePanel(p, opt->rect, opt->palette, bool(opt->state & (State_Sunken | State_On)),
475 pixelMetric(PM_DefaultFrameWidth), &fill);
476 break; }
477
478 case PE_IndicatorCheckBox: {
479 bool on = opt->state & State_On;
480 bool down = opt->state & State_Sunken;
481 bool showUp = !(down ^ on);
482 QBrush fill = opt->palette.brush((showUp || opt->state & State_NoChange) ?QPalette::Button : QPalette::Mid);
483 if (opt->state & State_NoChange) {
484 qDrawPlainRect(p, opt->rect, opt->palette.text().color(),
485 1, &fill);
486 p->drawLine(opt->rect.x() + opt->rect.width() - 1, opt->rect.y(),
487 opt->rect.x(), opt->rect.y() + opt->rect.height() - 1);
488 } else {
489 qDrawShadePanel(p, opt->rect, opt->palette, !showUp,
490 pixelMetric(PM_DefaultFrameWidth), &fill);
491 }
492 if (!(opt->state & State_Enabled) && styleHint(SH_DitherDisabledText))
493 p->fillRect(opt->rect, QBrush(p->background().color(), Qt::Dense5Pattern));
494 break; }
495
496 case PE_IndicatorRadioButton: {
497#define INTARRLEN(x) sizeof(x)/(sizeof(int)*2)
498 int inner_pts[] = { // used for filling diamond
499 2,opt->rect.height()/2,
500 opt->rect.width()/2,2,
501 opt->rect.width()-3,opt->rect.height()/2,
502 opt->rect.width()/2,opt->rect.height()-3
503 };
504 int top_pts[] = { // top (^) of diamond
505 0,opt->rect.height()/2,
506 opt->rect.width()/2,0,
507 opt->rect.width()-2,opt->rect.height()/2-1,
508 opt->rect.width()-3,opt->rect.height()/2-1,
509 opt->rect.width()/2,1,
510 1,opt->rect.height()/2,
511 2,opt->rect.height()/2,
512 opt->rect.width()/2,2,
513 opt->rect.width()-4,opt->rect.height()/2-1
514 };
515 int bottom_pts[] = { // bottom (v) of diamond
516 1,opt->rect.height()/2+1,
517 opt->rect.width()/2,opt->rect.height()-1,
518 opt->rect.width()-1,opt->rect.height()/2,
519 opt->rect.width()-2,opt->rect.height()/2,
520 opt->rect.width()/2,opt->rect.height()-2,
521 2,opt->rect.height()/2+1,
522 3,opt->rect.height()/2+1,
523 opt->rect.width()/2,opt->rect.height()-3,
524 opt->rect.width()-3,opt->rect.height()/2
525 };
526 bool on = opt->state & State_On;
527 bool down = opt->state & State_Sunken;
528 bool showUp = !(down ^ on);
529 QPen oldPen = p->pen();
530 QBrush oldBrush = p->brush();
531 QPolygon a(INTARRLEN(inner_pts), inner_pts);
532 p->setPen(Qt::NoPen);
533 p->setBrush(opt->palette.brush(showUp ? QPalette::Button : QPalette::Mid));
534 a.translate(opt->rect.x(), opt->rect.y());
535 p->drawPolygon(a);
536 p->setPen(showUp ? opt->palette.light().color() : opt->palette.dark().color());
537 p->setBrush(Qt::NoBrush);
538 a.setPoints(INTARRLEN(top_pts), top_pts);
539 a.translate(opt->rect.x(), opt->rect.y());
540 p->drawPolyline(a);
541 p->setPen(showUp ? opt->palette.dark().color() : opt->palette.light().color());
542 a.setPoints(INTARRLEN(bottom_pts), bottom_pts);
543 a.translate(opt->rect.x(), opt->rect.y());
544 p->drawPolyline(a);
545 if (!(opt->state & State_Enabled) && styleHint(SH_DitherDisabledText))
546 p->fillRect(opt->rect, QBrush(p->background().color(), Qt::Dense5Pattern));
547 p->setPen(oldPen);
548 p->setBrush(oldBrush);
549 break; }
550
551 case PE_IndicatorSpinUp:
552 case PE_IndicatorSpinPlus:
553 case PE_IndicatorSpinDown:
554 case PE_IndicatorSpinMinus:
555 case PE_IndicatorArrowUp:
556 case PE_IndicatorArrowDown:
557 case PE_IndicatorArrowRight:
558 case PE_IndicatorArrowLeft: {
559 QRect rect = opt->rect;
560 QPolygon bFill;
561 QPolygon bTop;
562 QPolygon bBot;
563 QPolygon bLeft;
564 if (pe == PE_IndicatorSpinPlus || pe == PE_IndicatorSpinUp)
565 pe = PE_IndicatorArrowUp;
566 else if (pe == PE_IndicatorSpinMinus || pe == PE_IndicatorSpinDown)
567 pe = PE_IndicatorArrowDown;
568 bool vertical = pe == PE_IndicatorArrowUp || pe == PE_IndicatorArrowDown;
569 bool horizontal = !vertical;
570 int dim = rect.width() < rect.height() ? rect.width() : rect.height();
571 int colspec = 0x0000;
572
573 if (!(opt->state & State_Enabled))
574 dim -= 2;
575 if(dim < 2)
576 break;
577
578 // adjust size and center (to fix rotation below)
579 if (rect.width() > dim) {
580 rect.setX(rect.x() + ((rect.width() - dim) / 2));
581 rect.setWidth(dim);
582 }
583 if (rect.height() > dim) {
584 rect.setY(rect.y() + ((rect.height() - dim) / 2));
585 rect.setHeight(dim);
586 }
587
588 if (dim > 3) {
589 if (pixelMetric(PM_DefaultFrameWidth) < 2) { // thin style
590 bFill.resize( dim & 1 ? 3 : 4 );
591 bTop.resize( 2 );
592 bBot.resize( 2 );
593 bLeft.resize( 2 );
594 bLeft.putPoints( 0, 2, 0, 0, 0, dim-1 );
595 bTop.putPoints( 0, 2, 1, 0, dim-1, dim/2 );
596 bBot.putPoints( 0, 2, 1, dim-1, dim-1, dim/2 );
597
598 if ( dim > 6 ) { // dim>6: must fill interior
599 bFill.putPoints( 0, 2, 0, dim-1, 0, 0 );
600 if ( dim & 1 ) // if size is an odd number
601 bFill.setPoint( 2, dim - 1, dim / 2 );
602 else
603 bFill.putPoints( 2, 2, dim-1, dim/2-1, dim-1, dim/2 );
604 }
605 } else {
606 if (dim > 6)
607 bFill.resize(dim & 1 ? 3 : 4);
608 bTop.resize((dim/2)*2);
609 bBot.resize(dim & 1 ? dim + 1 : dim);
610 bLeft.resize(dim > 4 ? 4 : 2);
611 bLeft.putPoints(0, 2, 0,0, 0,dim-1);
612 if (dim > 4)
613 bLeft.putPoints(2, 2, 1,2, 1,dim-3);
614 bTop.putPoints(0, 4, 1,0, 1,1, 2,1, 3,1);
615 bBot.putPoints(0, 4, 1,dim-1, 1,dim-2, 2,dim-2, 3,dim-2);
616
617 for(int i=0; i<dim/2-2 ; i++) {
618 bTop.putPoints(i*2+4, 2, 2+i*2,2+i, 5+i*2, 2+i);
619 bBot.putPoints(i*2+4, 2, 2+i*2,dim-3-i, 5+i*2,dim-3-i);
620 }
621 if (dim & 1) // odd number size: extra line
622 bBot.putPoints(dim-1, 2, dim-3,dim/2, dim-1,dim/2);
623 if (dim > 6) { // dim>6: must fill interior
624 bFill.putPoints(0, 2, 1,dim-3, 1,2);
625 if (dim & 1) // if size is an odd number
626 bFill.setPoint(2, dim - 3, dim / 2);
627 else
628 bFill.putPoints(2, 2, dim-4,dim/2-1, dim-4,dim/2);
629 }
630 }
631 } else {
632 if (dim == 3) { // 3x3 arrow pattern
633 bLeft.setPoints(4, 0,0, 0,2, 1,1, 1,1);
634 bTop .setPoints(2, 1,0, 1,0);
635 bBot .setPoints(2, 1,2, 2,1);
636 }
637 else { // 2x2 arrow pattern
638 bLeft.setPoints(2, 0,0, 0,1);
639 bTop .setPoints(2, 1,0, 1,0);
640 bBot .setPoints(2, 1,1, 1,1);
641 }
642 }
643
644 // We use rot() and translate() as it is more efficient that
645 // matrix transformations on the painter, and because it still
646 // works with QT_NO_TRANSFORMATIONS defined.
647
648 if (pe == PE_IndicatorArrowUp || pe == PE_IndicatorArrowLeft) {
649 if (vertical) {
650 rot(bFill,3);
651 rot(bLeft,3);
652 rot(bTop,3);
653 rot(bBot,3);
654 bFill.translate(0, rect.height() - 1);
655 bLeft.translate(0, rect.height() - 1);
656 bTop.translate(0, rect.height() - 1);
657 bBot.translate(0, rect.height() - 1);
658 } else {
659 rot(bFill,2);
660 rot(bLeft,2);
661 rot(bTop,2);
662 rot(bBot,2);
663 bFill.translate(rect.width() - 1, rect.height() - 1);
664 bLeft.translate(rect.width() - 1, rect.height() - 1);
665 bTop.translate(rect.width() - 1, rect.height() - 1);
666 bBot.translate(rect.width() - 1, rect.height() - 1);
667 }
668 if (opt->state & State_Sunken)
669 colspec = horizontal ? 0x2334 : 0x2343;
670 else
671 colspec = horizontal ? 0x1443 : 0x1434;
672 } else {
673 if (vertical) {
674 rot(bFill,1);
675 rot(bLeft,1);
676 rot(bTop,1);
677 rot(bBot,1);
678 bFill.translate(rect.width() - 1, 0);
679 bLeft.translate(rect.width() - 1, 0);
680 bTop.translate(rect.width() - 1, 0);
681 bBot.translate(rect.width() - 1, 0);
682 }
683 if (opt->state & State_Sunken)
684 colspec = horizontal ? 0x2443 : 0x2434;
685 else
686 colspec = horizontal ? 0x1334 : 0x1343;
687 }
688 bFill.translate(rect.x(), rect.y());
689 bLeft.translate(rect.x(), rect.y());
690 bTop.translate(rect.x(), rect.y());
691 bBot.translate(rect.x(), rect.y());
692
693 const QColor *cols[5];
694 if (opt->state & State_Enabled) {
695 cols[0] = 0;
696 cols[1] = &opt->palette.button().color();
697 cols[2] = &opt->palette.mid().color();
698 cols[3] = &opt->palette.light().color();
699 cols[4] = &opt->palette.dark().color();
700 } else {
701 cols[0] = 0;
702 cols[1] = &opt->palette.mid().color();
703 cols[2] = &opt->palette.mid().color();
704 cols[3] = &opt->palette.mid().color();
705 cols[4] = &opt->palette.mid().color();
706 }
707
708#define CMID *cols[(colspec>>12) & 0xf]
709#define CLEFT *cols[(colspec>>8) & 0xf]
710#define CTOP *cols[(colspec>>4) & 0xf]
711#define CBOT *cols[colspec & 0xf]
712
713 QPen savePen = p->pen();
714 QBrush saveBrush = p->brush();
715 QPen pen(Qt::NoPen);
716 QBrush brush = opt->palette.brush((opt->state & State_Enabled) ?
717 QPalette::Button : QPalette::Mid);
718 p->setPen(pen);
719 p->setBrush(brush);
720 p->drawPolygon(bFill);
721 p->setBrush(Qt::NoBrush);
722
723 p->setPen(CLEFT);
724 p->drawPolyline(bLeft);
725 p->setPen(CTOP);
726 p->drawPolyline(bTop);
727 p->setPen(CBOT);
728 p->drawPolyline(bBot);
729
730 p->setBrush(saveBrush);
731 p->setPen(savePen);
732#undef CMID
733#undef CLEFT
734#undef CTOP
735#undef CBOT
736 if (!(opt->state & State_Enabled) && styleHint(SH_DitherDisabledText))
737 p->fillRect(opt->rect, QBrush(p->background().color(), Qt::Dense5Pattern));
738 break; }
739
740 case PE_IndicatorDockWidgetResizeHandle: {
741 const int motifOffset = 10;
742 int sw = pixelMetric(PM_SplitterWidth);
743 if (opt->state & State_Horizontal) {
744 int yPos = opt->rect.y() + opt->rect.height() / 2;
745 int kPos = opt->rect.right() - motifOffset - sw;
746 int kSize = sw - 2;
747
748 qDrawShadeLine(p, opt->rect.left(), yPos, kPos, yPos, opt->palette);
749 qDrawShadePanel(p, kPos, yPos - sw / 2 + 1, kSize, kSize,
750 opt->palette, false, 1, &opt->palette.brush(QPalette::Button));
751 qDrawShadeLine(p, kPos + kSize - 1, yPos, opt->rect.right(), yPos, opt->palette);
752 } else {
753 int xPos = opt->rect.x() + opt->rect.width() / 2;
754 int kPos = motifOffset;
755 int kSize = sw - 2;
756
757 qDrawShadeLine(p, xPos, opt->rect.top() + kPos + kSize - 1, xPos, opt->rect.bottom(), opt->palette);
758 qDrawShadePanel(p, xPos - sw / 2 + 1, opt->rect.top() + kPos, kSize, kSize, opt->palette,
759 false, 1, &opt->palette.brush(QPalette::Button));
760 qDrawShadeLine(p, xPos, opt->rect.top(), xPos, opt->rect.top() + kPos, opt->palette);
761 }
762 break; }
763
764 case PE_IndicatorMenuCheckMark: {
765 const int markW = 6;
766 const int markH = 6;
767 int posX = opt->rect.x() + (opt->rect.width() - markW) / 2 - 1;
768 int posY = opt->rect.y() + (opt->rect.height() - markH) / 2;
769 int dfw = pixelMetric(PM_DefaultFrameWidth);
770
771 if (dfw < 2) {
772 // Could do with some optimizing/caching...
773 QPolygon a(7*2);
774 int i, xx, yy;
775 xx = posX;
776 yy = 3 + posY;
777 for (i=0; i<3; i++) {
778 a.setPoint(2*i, xx, yy);
779 a.setPoint(2*i+1, xx, yy+2);
780 xx++; yy++;
781 }
782 yy -= 2;
783 for (i=3; i<7; i++) {
784 a.setPoint(2*i, xx, yy);
785 a.setPoint(2*i+1, xx, yy+2);
786 xx++; yy--;
787 }
788 if (! (opt->state & State_Enabled) && ! (opt->state & State_On)) {
789 int pnt;
790 p->setPen(opt->palette.highlightedText().color());
791 QPoint offset(1,1);
792 for (pnt = 0; pnt < (int)a.size(); pnt++)
793 a[pnt] += offset;
794 p->drawPolyline(a);
795 for (pnt = 0; pnt < (int)a.size(); pnt++)
796 a[pnt] -= offset;
797 }
798 p->setPen(opt->palette.text().color());
799 p->drawPolyline(a);
800
801 qDrawShadePanel(p, posX-2, posY-2, markW+4, markH+6, opt->palette, true, dfw);
802 } else
803 qDrawShadePanel(p, posX, posY, markW, markH, opt->palette, true, dfw,
804 &opt->palette.brush(QPalette::Mid));
805
806 break; }
807
808 case PE_IndicatorProgressChunk:
809 {
810 bool vertical = false;
811 if (const QStyleOptionProgressBarV2 *pb2 = qstyleoption_cast<const QStyleOptionProgressBarV2 *>(opt))
812 vertical = (pb2->orientation == Qt::Vertical);
813 if (!vertical) {
814 p->fillRect(opt->rect.x(), opt->rect.y(), opt->rect.width(),
815 opt->rect.height(), opt->palette.brush(QPalette::Highlight));
816 } else {
817 p->fillRect(opt->rect.x(), opt->rect.y(), opt->rect.width(), opt->rect.height(),
818 opt->palette.brush(QPalette::Highlight));
819 }
820 }
821 break;
822
823 default:
824 QCommonStyle::drawPrimitive(pe, opt, p, w);
825 break;
826 }
827}
828
829
830/*!
831 \reimp
832*/
833void QMotifStyle::drawControl(ControlElement element, const QStyleOption *opt, QPainter *p,
834 const QWidget *widget) const
835{
836 switch(element) {
837 case CE_Splitter: {
838 QStyleOption handleOpt = *opt;
839 if (handleOpt.state & State_Horizontal)
840 handleOpt.state &= ~State_Horizontal;
841 else
842 handleOpt.state |= State_Horizontal;
843 drawPrimitive(PE_IndicatorDockWidgetResizeHandle, &handleOpt, p, widget);
844 break; }
845
846 case CE_ScrollBarSubLine:
847 case CE_ScrollBarAddLine:{
848 PrimitiveElement pe;
849 if (element == CE_ScrollBarAddLine)
850 pe = (opt->state & State_Horizontal) ? (opt->direction == Qt::LeftToRight ? PE_IndicatorArrowRight : PE_IndicatorArrowLeft) : PE_IndicatorArrowDown;
851 else
852 pe = (opt->state & State_Horizontal) ? (opt->direction == Qt::LeftToRight ? PE_IndicatorArrowLeft : PE_IndicatorArrowRight) : PE_IndicatorArrowUp;
853 QStyleOption arrowOpt = *opt;
854 arrowOpt.state |= State_Enabled;
855 drawPrimitive(pe, &arrowOpt, p, widget);
856 if (!(opt->state & State_Enabled) && styleHint(SH_DitherDisabledText)) {
857 int fw = pixelMetric(PM_DefaultFrameWidth);
858 p->fillRect(opt->rect.adjusted(fw, fw, -fw, -fw), QBrush(p->background().color(), Qt::Dense5Pattern));
859 }
860 }break;
861
862 case CE_ScrollBarSubPage:
863 case CE_ScrollBarAddPage:
864 p->fillRect(opt->rect, opt->palette.brush((opt->state & State_Enabled) ? QPalette::Mid : QPalette::Window));
865 break;
866
867 case CE_ScrollBarSlider: {
868 QStyleOption bevelOpt = *opt;
869 bevelOpt.state |= State_Raised;
870 bevelOpt.state &= ~(State_Sunken | State_On);
871 p->save();
872 p->setBrushOrigin(bevelOpt.rect.topLeft());
873 drawPrimitive(PE_PanelButtonBevel, &bevelOpt, p, widget);
874 p->restore();
875 if (!(opt->state & State_Enabled) && styleHint(SH_DitherDisabledText))
876 p->fillRect(opt->rect, QBrush(p->background().color(), Qt::Dense5Pattern));
877 break; }
878
879 case CE_RadioButton:
880 case CE_CheckBox:
881 if (const QStyleOptionButton *btn = qstyleoption_cast<const QStyleOptionButton *>(opt)) {
882 bool isRadio = (element == CE_RadioButton);
883 QStyleOptionButton subopt = *btn;
884 subopt.rect = subElementRect(isRadio ? SE_RadioButtonIndicator
885 : SE_CheckBoxIndicator, btn, widget);
886 drawPrimitive(isRadio ? PE_IndicatorRadioButton : PE_IndicatorCheckBox,
887 &subopt, p, widget);
888 subopt.rect = subElementRect(isRadio ? SE_RadioButtonContents
889 : SE_CheckBoxContents, btn, widget);
890 drawControl(isRadio ? CE_RadioButtonLabel : CE_CheckBoxLabel, &subopt, p, widget);
891 if ((btn->state & State_HasFocus) && (!focus || !focus->isVisible())) {
892 QStyleOptionFocusRect fropt;
893 fropt.QStyleOption::operator=(*btn);
894 fropt.rect = subElementRect(isRadio ? SE_RadioButtonFocusRect
895 : SE_CheckBoxFocusRect, btn, widget);
896 drawPrimitive(PE_FrameFocusRect, &fropt, p, widget);
897 }
898 }
899 break;
900 case CE_PushButton:
901 if (const QStyleOptionButton *btn = qstyleoption_cast<const QStyleOptionButton *>(opt)) {
902 drawControl(CE_PushButtonBevel, btn, p, widget);
903 QStyleOptionButton subopt = *btn;
904 subopt.rect = subElementRect(SE_PushButtonContents, btn, widget);
905 drawControl(CE_PushButtonLabel, &subopt, p, widget);
906 if ((btn->state & State_HasFocus) && (!focus || !focus->isVisible())) {
907 QStyleOptionFocusRect fropt;
908 fropt.QStyleOption::operator=(*btn);
909 fropt.rect = subElementRect(SE_PushButtonFocusRect, btn, widget);
910 drawPrimitive(PE_FrameFocusRect, &fropt, p, widget);
911 }
912 }
913 break;
914 case CE_PushButtonBevel:
915 if (const QStyleOptionButton *btn = qstyleoption_cast<const QStyleOptionButton *>(opt)) {
916 int diw, x1, y1, x2, y2;
917 p->setPen(opt->palette.foreground().color());
918 p->setBrush(QBrush(opt->palette.button().color(), Qt::NoBrush));
919 diw = pixelMetric(PM_ButtonDefaultIndicator);
920 opt->rect.getCoords(&x1, &y1, &x2, &y2);
921 if (btn->features & (QStyleOptionButton::AutoDefaultButton|QStyleOptionButton::DefaultButton)) {
922 x1 += diw;
923 y1 += diw;
924 x2 -= diw;
925 y2 -= diw;
926 }
927 if (btn->features & QStyleOptionButton::DefaultButton) {
928 if (diw == 0) {
929 QPolygon a;
930 a.setPoints(9,
931 x1, y1, x2, y1, x2, y2, x1, y2, x1, y1+1,
932 x2-1, y1+1, x2-1, y2-1, x1+1, y2-1, x1+1, y1+1);
933 p->setPen(opt->palette.shadow().color());
934 p->drawPolygon(a);
935 x1 += 2;
936 y1 += 2;
937 x2 -= 2;
938 y2 -= 2;
939 } else {
940 qDrawShadePanel(p, opt->rect.adjusted(1, 1, -1, -1), opt->palette, true);
941 }
942 }
943 if (!(btn->features & QStyleOptionButton::Flat) ||
944 (btn->state & (State_Sunken | State_On))) {
945 QStyleOptionButton newOpt = *btn;
946 newOpt.rect = QRect(x1, y1, x2 - x1 + 1, y2 - y1 + 1);
947 p->setBrushOrigin(p->brushOrigin());
948 drawPrimitive(PE_PanelButtonCommand, &newOpt, p, widget);
949 }
950 if (btn->features & QStyleOptionButton::HasMenu) {
951 int mbi = pixelMetric(PM_MenuButtonIndicator, btn, widget);
952 QRect ir = btn->rect;
953 QStyleOptionButton newBtn = *btn;
954 newBtn.rect = QRect(ir.right() - mbi - 3, ir.y() + 4, mbi, ir.height() - 8);
955 drawPrimitive(PE_IndicatorArrowDown, &newBtn, p, widget);
956 }
957 break;
958 }
959
960#ifndef QT_NO_TABBAR
961 case CE_TabBarTabShape:
962 if (const QStyleOptionTab *tab = qstyleoption_cast<const QStyleOptionTab *>(opt)) {
963 const int default_frame = pixelMetric(PM_DefaultFrameWidth, tab, widget);
964 const int frame_offset = (default_frame > 1) ? 1 : 0;
965
966 if (tab->shape == QTabBar::RoundedNorth || tab->shape == QTabBar::RoundedEast ||
967 tab->shape == QTabBar::RoundedSouth || tab->shape == QTabBar::RoundedWest) {
968 p->save();
969 QRect tabRect = opt->rect;
970 QColor tabLight = opt->palette.light().color();
971 QColor tabDark = opt->palette.dark().color();
972
973 p->fillRect(opt->rect.adjusted(default_frame, default_frame,
974 -default_frame, -default_frame),
975 tab->palette.background());
976
977 if(tab->shape == QTabBar::RoundedWest) {
978 tabDark = opt->palette.light().color();
979 tabLight = opt->palette.dark().color();
980 tabRect = QRect(0, 0, tabRect.height(), tabRect.width());
981 p->translate(opt->rect.left(), opt->rect.bottom());
982 p->rotate(-90);
983 } else if(tab->shape == QTabBar::RoundedSouth) {
984 tabDark = opt->palette.light().color();
985 tabLight = opt->palette.dark().color();
986 tabRect = QRect(0, 0, tabRect.width(), tabRect.height());
987 p->translate(opt->rect.right(), opt->rect.bottom());
988 p->rotate(180);
989 } else if(tab->shape == QTabBar::RoundedEast) {
990 tabRect = QRect(0, 0, tabRect.height(), tabRect.width());
991 p->translate(opt->rect.right(), opt->rect.top());
992 p->rotate(90);
993 }
994
995 if (default_frame > 1) {
996 p->setPen(tabLight);
997 p->drawLine(tabRect.left(), tabRect.bottom(),
998 tabRect.right(), tabRect.bottom());
999 p->setPen(tabLight);
1000 p->drawLine(tabRect.left(), tabRect.bottom()-1,
1001 tabRect.right(), tabRect.bottom()-1);
1002 if (tabRect.left() == 0)
1003 p->drawPoint(tabRect.bottomLeft());
1004 } else {
1005 p->setPen(tabLight);
1006 p->drawLine(tabRect.left(), tabRect.bottom(),
1007 tabRect.right(), tabRect.bottom());
1008 }
1009
1010 if (opt->state & State_Selected) {
1011 p->fillRect(QRect(tabRect.left()+1, tabRect.bottom()-frame_offset,
1012 tabRect.width()-3, 2),
1013 tab->palette.brush(QPalette::Active, QPalette::Background));
1014 p->setPen(tab->palette.background().color());
1015 p->drawLine(tabRect.left()+1, tabRect.bottom(),
1016 tabRect.left()+1, tabRect.top()+2);
1017 p->setPen(tabLight);
1018 } else {
1019 p->setPen(tabLight);
1020 }
1021 p->drawLine(tabRect.left(), tabRect.bottom()-1,
1022 tabRect.left(), tabRect.top() + 2);
1023 p->drawPoint(tabRect.left()+1, tabRect.top() + 1);
1024 p->drawLine(tabRect.left()+2, tabRect.top(),
1025 tabRect.right() - 2, tabRect.top());
1026 p->drawPoint(tabRect.left(), tabRect.bottom());
1027
1028 if (default_frame > 1) {
1029 p->drawLine(tabRect.left()+1, tabRect.bottom(),
1030 tabRect.left()+1, tabRect.top() + 2);
1031 p->drawLine(tabRect.left()+2, tabRect.top()+1,
1032 tabRect.right() - 2, tabRect.top()+1);
1033 }
1034
1035 p->setPen(tabDark);
1036 p->drawLine(tabRect.right() - 1, tabRect.top() + 2,
1037 tabRect.right() - 1, tabRect.bottom() - 1 +
1038 ((opt->state & State_Selected) ? frame_offset : -frame_offset));
1039 if (default_frame > 1) {
1040 p->drawPoint(tabRect.right() - 1, tabRect.top() + 1);
1041 p->drawLine(tabRect.right(), tabRect.top() + 2, tabRect.right(),
1042 tabRect.bottom() -
1043 ((opt->state & State_Selected) ?
1044 ((tab->position == QStyleOptionTab::End) ? 0:1):1+frame_offset));
1045 p->drawPoint(tabRect.right() - 1, tabRect.top() + 1);
1046 }
1047 p->restore();
1048 } else {
1049 QCommonStyle::drawControl(element, opt, p, widget);
1050 }
1051 break; }
1052#endif // QT_NO_TABBAR
1053 case CE_ProgressBarGroove:
1054 qDrawShadePanel(p, opt->rect, opt->palette, true, 2);
1055 break;
1056
1057 case CE_ProgressBarLabel:
1058 if (const QStyleOptionProgressBar *pb = qstyleoption_cast<const QStyleOptionProgressBar *>(opt)) {
1059 QTransform oldMatrix = p->transform();
1060 QRect rect = pb->rect;
1061 bool vertical = false;
1062 bool invert = false;
1063 bool bottomToTop = false;
1064 if (const QStyleOptionProgressBarV2 *pb2 = qstyleoption_cast<const QStyleOptionProgressBarV2 *>(opt)) {
1065 vertical = (pb2->orientation == Qt::Vertical);
1066 invert = pb2->invertedAppearance;
1067 bottomToTop = pb2->bottomToTop;
1068 }
1069 if (vertical) {
1070 QTransform m;
1071 rect = QRect(rect.left(), rect.top(), rect.height(), rect.width()); // flip width and height
1072 if (bottomToTop) {
1073 m.translate(0.0, rect.width());
1074 m.rotate(-90);
1075 } else {
1076 m.translate(rect.height(), 0.0);
1077 m.rotate(90);
1078 }
1079 p->setTransform(m, true);
1080 }
1081 const int unit_width = pixelMetric(PM_ProgressBarChunkWidth, opt, widget);
1082 int u = rect.width() / unit_width;
1083 int p_v = pb->progress - pb->minimum;
1084 int t_s = qMax(0, pb->maximum - pb->minimum);
1085 if (u > 0 && pb->progress >= INT_MAX / u && t_s >= u) {
1086 // scale down to something usable.
1087 p_v /= u;
1088 t_s /= u;
1089 }
1090 if (pb->textVisible && t_s) {
1091 int nu = (u * p_v + t_s/2) / t_s;
1092 int x = unit_width * nu;
1093 QRect left(rect.x(), rect.y(), x, rect.height());
1094 QRect right(rect.x() + x, rect.y(), rect.width() - x, rect.height());
1095 Qt::LayoutDirection dir;
1096 dir = vertical ? (bottomToTop ? Qt::LeftToRight : Qt::RightToLeft) : pb->direction;
1097 if (invert)
1098 dir = (dir == Qt::LeftToRight) ? Qt::RightToLeft : Qt::LeftToRight;
1099 const QRect highlighted = visualRect(dir, rect, left);
1100 const QRect background = visualRect(dir, rect, right);
1101 p->setPen(opt->palette.highlightedText().color());
1102 p->setClipRect(highlighted);
1103 p->drawText(rect, Qt::AlignCenter | Qt::TextSingleLine, pb->text);
1104
1105 if (pb->progress != pb->maximum) {
1106 p->setClipRect(background);
1107 p->setPen(opt->palette.highlight().color());
1108 p->drawText(rect, Qt::AlignCenter | Qt::TextSingleLine, pb->text);
1109 }
1110 }
1111 p->setTransform(oldMatrix, false);
1112 break;
1113 }
1114
1115 case CE_MenuTearoff: {
1116 if(opt->state & State_Selected) {
1117 if(pixelMetric(PM_MenuPanelWidth, opt, widget) > 1)
1118 qDrawShadePanel(p, opt->rect.x(), opt->rect.y(), opt->rect.width(),
1119 opt->rect.height(), opt->palette, false, motifItemFrame,
1120 &opt->palette.brush(QPalette::Button));
1121 else
1122 qDrawShadePanel(p, opt->rect.x()+1, opt->rect.y()+1, opt->rect.width()-2,
1123 opt->rect.height()-2, opt->palette, true, 1, &opt->palette.brush(QPalette::Button));
1124 } else {
1125 p->fillRect(opt->rect, opt->palette.brush(QPalette::Button));
1126 }
1127 p->setPen(QPen(opt->palette.dark().color(), 1, Qt::DashLine));
1128 p->drawLine(opt->rect.x()+2, opt->rect.y()+opt->rect.height()/2-1, opt->rect.x()+opt->rect.width()-4,
1129 opt->rect.y()+opt->rect.height()/2-1);
1130 p->setPen(QPen(opt->palette.light().color(), 1, Qt::DashLine));
1131 p->drawLine(opt->rect.x()+2, opt->rect.y()+opt->rect.height()/2, opt->rect.x()+opt->rect.width()-4,
1132 opt->rect.y()+opt->rect.height()/2);
1133 break; }
1134
1135 case CE_MenuItem:
1136 if (const QStyleOptionMenuItem *menuitem = qstyleoption_cast<const QStyleOptionMenuItem *>(opt)) {
1137 int maxpmw = menuitem->maxIconWidth;
1138 if(menuitem->menuHasCheckableItems)
1139 maxpmw = qMax(maxpmw, motifCheckMarkSpace);
1140
1141 int x, y, w, h;
1142 opt->rect.getRect(&x, &y, &w, &h);
1143
1144 if (menuitem->menuItemType == QStyleOptionMenuItem::Separator) { // draw separator
1145 int textWidth = 0;
1146 if (!menuitem->text.isEmpty()) {
1147 QFont oldFont = p->font();
1148 p->setFont(menuitem->font);
1149 p->fillRect(x, y, w, h, opt->palette.brush(QPalette::Button));
1150 drawItemText(p, menuitem->rect.adjusted(10, 0, -5, 0), Qt::AlignLeft | Qt::AlignVCenter,
1151 menuitem->palette, menuitem->state & State_Enabled, menuitem->text,
1152 QPalette::Text);
1153 textWidth = menuitem->fontMetrics.width(menuitem->text) + 10;
1154 y += menuitem->fontMetrics.lineSpacing() / 2;
1155 p->setFont(oldFont);
1156 }
1157 p->setPen(opt->palette.dark().color());
1158 p->drawLine(x, y, x + 5, y);
1159 p->drawLine(x + 5 + textWidth, y, x+w, y);
1160 p->setPen(opt->palette.light().color());
1161 p->drawLine(x, y + 1, x + 5, y + 1);
1162 p->drawLine(x + 5 + textWidth, y + 1, x+w, y + 1);
1163 return;
1164 }
1165
1166 int pw = motifItemFrame;
1167 if((opt->state & State_Selected) && (opt->state & State_Enabled)) { // active item frame
1168 if(pixelMetric(PM_MenuPanelWidth, opt) > 1)
1169 qDrawShadePanel(p, x, y, w, h, opt->palette, false, pw,
1170 &opt->palette.brush(QPalette::Button));
1171 else
1172 qDrawShadePanel(p, x+1, y+1, w-2, h-2, opt->palette, true, 1,
1173 &opt->palette.brush(QPalette::Button));
1174 } else { // incognito frame
1175 p->fillRect(x, y, w, h, opt->palette.brush(QPalette::Button));
1176 }
1177
1178 QRect vrect = visualRect(opt->direction, opt->rect,
1179 QRect(x+motifItemFrame, y+motifItemFrame, maxpmw,
1180 h-2*motifItemFrame));
1181 int xvis = vrect.x();
1182 if (menuitem->checked) {
1183 if(!menuitem->icon.isNull())
1184 qDrawShadePanel(p, xvis, y+motifItemFrame, maxpmw, h-2*motifItemFrame,
1185 opt->palette, true, 1, &opt->palette.brush(QPalette::Midlight));
1186 } else if (!(opt->state & State_Selected)) {
1187 p->fillRect(xvis, y+motifItemFrame, maxpmw, h-2*motifItemFrame,
1188 opt->palette.brush(QPalette::Button));
1189 }
1190
1191 if(!menuitem->icon.isNull()) { // draw icon
1192 QIcon::Mode mode = QIcon::Normal; // no disabled icons in Motif
1193 if ((opt->state & State_Selected) && !!(opt->state & State_Enabled))
1194 mode = QIcon::Active;
1195 QPixmap pixmap;
1196 if (menuitem->checkType != QStyleOptionMenuItem::NotCheckable && menuitem->checked)
1197 pixmap = menuitem->icon.pixmap(pixelMetric(PM_SmallIconSize, opt, widget), mode, QIcon::On);
1198 else
1199 pixmap = menuitem->icon.pixmap(pixelMetric(PM_SmallIconSize, opt, widget), mode);
1200
1201 int pixw = pixmap.width();
1202 int pixh = pixmap.height();
1203 QRect pmr(0, 0, pixw, pixh);
1204 pmr.moveCenter(vrect.center());
1205 p->setPen(opt->palette.text().color());
1206 p->drawPixmap(pmr.topLeft(), pixmap);
1207
1208 } else if (menuitem->checkType != QStyleOptionMenuItem::NotCheckable) { // just "checking"...
1209 int mh = h - 2*motifItemFrame;
1210
1211 QStyleOptionButton newMenuItem;
1212 newMenuItem.state = menuitem->checked ? State_On : State_None;
1213 if (opt->state & State_Enabled) {
1214 newMenuItem.state |= State_Enabled;
1215 if (menuitem->state & State_Sunken)
1216 newMenuItem.state |= State_Sunken;
1217 }
1218 if (menuitem->checkType & QStyleOptionMenuItem::Exclusive) {
1219 newMenuItem.rect.setRect(xvis + 2, y + motifItemFrame + mh / 4, 11, 11);
1220 drawPrimitive(PE_IndicatorRadioButton, &newMenuItem, p, widget);
1221 } else {
1222 newMenuItem.rect.setRect(xvis + 5, y + motifItemFrame + mh / 4, 9, 9);
1223 drawPrimitive(PE_IndicatorCheckBox, &newMenuItem, p, widget);
1224 }
1225 }
1226
1227 p->setPen(opt->palette.buttonText().color());
1228
1229 QColor discol;
1230 if (!(opt->state & State_Enabled)) {
1231 discol = opt->palette.text().color();
1232 p->setPen(discol);
1233 }
1234
1235 int xm = motifItemFrame + maxpmw + motifItemHMargin;
1236
1237 vrect = visualRect(opt->direction, opt->rect,
1238 QRect(x+xm, y+motifItemVMargin, w-xm-menuitem->tabWidth,
1239 h-2*motifItemVMargin));
1240 xvis = vrect.x();
1241
1242 QString s = menuitem->text;
1243 if (!s.isNull()) { // draw text
1244 int t = s.indexOf(QLatin1Char('\t'));
1245 int m = motifItemVMargin;
1246 int text_flags = Qt::AlignVCenter|Qt::TextShowMnemonic | Qt::TextDontClip | Qt::TextSingleLine;
1247 text_flags |= Qt::AlignLeft;
1248 QFont oldFont = p->font();
1249 p->setFont(menuitem->font);
1250 if (t >= 0) { // draw tab text
1251 QRect vr = visualRect(opt->direction, opt->rect,
1252 QRect(x+w-menuitem->tabWidth-motifItemHMargin-motifItemFrame,
1253 y+motifItemVMargin, menuitem->tabWidth,
1254 h-2*motifItemVMargin));
1255 int xv = vr.x();
1256 QRect tr(xv, y+m, menuitem->tabWidth, h-2*m);
1257 p->drawText(tr, text_flags, s.mid(t+1));
1258 if (!(opt->state & State_Enabled) && styleHint(SH_DitherDisabledText))
1259 p->fillRect(tr, QBrush(p->background().color(), Qt::Dense5Pattern));
1260 s = s.left(t);
1261 }
1262 QRect tr(xvis, y+m, w - xm - menuitem->tabWidth + 1, h-2*m);
1263 p->drawText(tr, text_flags, s.left(t));
1264 p->setFont(oldFont);
1265 if (!(opt->state & State_Enabled) && styleHint(SH_DitherDisabledText))
1266 p->fillRect(tr, QBrush(p->background().color(), Qt::Dense5Pattern));
1267 }
1268 if (menuitem->menuItemType == QStyleOptionMenuItem::SubMenu) { // draw sub menu arrow
1269 int dim = (h-2*motifItemFrame) / 2;
1270 QStyle::PrimitiveElement arrow = (opt->direction == Qt::RightToLeft ? PE_IndicatorArrowLeft : PE_IndicatorArrowRight);
1271 QStyleOption arrowOpt = *opt;
1272 arrowOpt.rect = visualRect(opt->direction, opt->rect,
1273 QRect(x+w - motifArrowHMargin - motifItemFrame - dim,
1274 y+h/2-dim/2, dim, dim));
1275 if ((opt->state & State_Selected))
1276 arrowOpt.state = (State_Sunken | ((opt->state & State_Enabled) ? State_Enabled : State_None));
1277 else
1278 arrowOpt.state = ((opt->state & State_Enabled) ? State_Enabled : State_None);
1279 drawPrimitive(arrow, &arrowOpt, p, widget);
1280 }
1281 break; }
1282
1283 case CE_MenuBarItem:
1284 if (opt->state & State_Selected) // active item
1285 qDrawShadePanel(p, opt->rect, opt->palette, false, motifItemFrame,
1286 &opt->palette.brush(QPalette::Button));
1287 else // other item
1288 p->fillRect(opt->rect, opt->palette.brush(QPalette::Button));
1289 QCommonStyle::drawControl(element, opt, p, widget);
1290 break;
1291
1292 case CE_HeaderSection:
1293 p->save();
1294 p->setBrushOrigin(opt->rect.topLeft());
1295 qDrawShadePanel(p, opt->rect, opt->palette, bool(opt->state & (State_Sunken|State_On)),
1296 pixelMetric(PM_DefaultFrameWidth),
1297 &opt->palette.brush((opt->state & State_Sunken) ? QPalette::Mid : QPalette::Button));
1298 p->restore();
1299 break;
1300 case CE_RubberBand: {
1301 QPixmap tiledPixmap(16, 16);
1302 QPainter pixmapPainter(&tiledPixmap);
1303 pixmapPainter.setPen(Qt::NoPen);
1304 pixmapPainter.setBrush(Qt::Dense4Pattern);
1305 pixmapPainter.setBackground(QBrush(opt->palette.base()));
1306 pixmapPainter.setBackgroundMode(Qt::OpaqueMode);
1307 pixmapPainter.drawRect(0, 0, tiledPixmap.width(), tiledPixmap.height());
1308 pixmapPainter.end();
1309 // ### workaround for borked XRENDER
1310 tiledPixmap = QPixmap::fromImage(tiledPixmap.toImage());
1311
1312 p->save();
1313 QRect r = opt->rect;
1314 QStyleHintReturnMask mask;
1315 if (styleHint(QStyle::SH_RubberBand_Mask, opt, widget, &mask))
1316 p->setClipRegion(mask.region);
1317 p->drawTiledPixmap(r.x(), r.y(), r.width(), r.height(), tiledPixmap);
1318 p->restore();
1319 }
1320 break;
1321#ifndef QT_NO_PROGRESSBAR
1322 case CE_ProgressBarContents:
1323 if (const QStyleOptionProgressBar *pb = qstyleoption_cast<const QStyleOptionProgressBar *>(opt)) {
1324 QRect rect = pb->rect;
1325 bool vertical = false;
1326 bool inverted = false;
1327
1328 // Get extra style options if version 2
1329 const QStyleOptionProgressBarV2 *pb2 = qstyleoption_cast<const QStyleOptionProgressBarV2 *>(opt);
1330 if (pb2) {
1331 vertical = (pb2->orientation == Qt::Vertical);
1332 inverted = pb2->invertedAppearance;
1333 }
1334
1335 QTransform m;
1336 if (vertical) {
1337 rect = QRect(rect.left(), rect.top(), rect.height(), rect.width()); // flip width and height
1338 m.rotate(90);
1339 m.translate(0, -(rect.height() + rect.y()*2));
1340 }
1341
1342 QPalette pal2 = pb->palette;
1343 // Correct the highlight color if it is the same as the background
1344 if (pal2.highlight() == pal2.background())
1345 pal2.setColor(QPalette::Highlight, pb->palette.color(QPalette::Active,
1346 QPalette::Highlight));
1347 bool reverse = ((!vertical && (pb->direction == Qt::RightToLeft)) || vertical);
1348 if (inverted)
1349 reverse = !reverse;
1350 int w = rect.width();
1351 if (pb->minimum == 0 && pb->maximum == 0) {
1352 QRect progressBar;
1353 Q_D(const QMotifStyle);
1354 // draw busy indicator
1355 int x = (d->animateStep*8)% (w * 2);
1356 if (x > w)
1357 x = 2 * w - x;
1358 x = reverse ? rect.right() - x : x + rect.x();
1359 p->setTransform(m, true);
1360 p->setPen(QPen(pal2.highlight().color(), 4));
1361 p->drawLine(x, rect.y(), x, rect.height());
1362
1363 } else
1364 QCommonStyle::drawControl(element, opt, p, widget);
1365 }
1366 break;
1367#endif // QT_NO_PROGRESSBAR
1368 default:
1369 QCommonStyle::drawControl(element, opt, p, widget);
1370 break; }
1371}
1372
1373static int get_combo_extra_width(int h, int w, int *return_awh=0)
1374{
1375 int awh,
1376 tmp;
1377 if (h < 8) {
1378 awh = 6;
1379 } else if (h < 14) {
1380 awh = h - 2;
1381 } else {
1382 awh = h/2;
1383 }
1384 tmp = (awh * 3) / 2;
1385 if (tmp > w / 2) {
1386 awh = w / 2 - 3;
1387 tmp = w / 2 + 3;
1388 }
1389
1390 if (return_awh)
1391 *return_awh = awh;
1392
1393 return tmp;
1394}
1395
1396static void get_combo_parameters(const QRect &r,
1397 int &ew, int &awh, int &ax,
1398 int &ay, int &sh, int &dh,
1399 int &sy)
1400{
1401 ew = get_combo_extra_width(r.height(), r.width(), &awh);
1402
1403 sh = (awh+3)/4;
1404 if (sh < 3)
1405 sh = 3;
1406 dh = sh/2 + 1;
1407
1408 ay = r.y() + (r.height()-awh-sh-dh)/2;
1409 if (ay < 0) {
1410 //panic mode
1411 ay = 0;
1412 sy = r.height();
1413 } else {
1414 sy = ay+awh+dh;
1415 }
1416 ax = r.x() + r.width() - ew;
1417 ax += (ew-awh)/2;
1418}
1419
1420/*!
1421 \reimp
1422*/
1423void QMotifStyle::drawComplexControl(ComplexControl cc, const QStyleOptionComplex *opt, QPainter *p,
1424 const QWidget *widget) const
1425{
1426 switch (cc) {
1427 case CC_ToolButton:
1428 if (const QStyleOptionToolButton *toolbutton
1429 = qstyleoption_cast<const QStyleOptionToolButton *>(opt)) {
1430 QRect button, menuarea;
1431 button = subControlRect(cc, toolbutton, SC_ToolButton, widget);
1432 menuarea = subControlRect(cc, toolbutton, SC_ToolButtonMenu, widget);
1433
1434 State bflags = toolbutton->state & ~State_Sunken;
1435 if (bflags & State_AutoRaise) {
1436 if (!(bflags & State_MouseOver) || !(bflags & State_Enabled)) {
1437 bflags &= ~State_Raised;
1438 }
1439 }
1440 State mflags = bflags;
1441 if (toolbutton->state & State_Sunken) {
1442 if (toolbutton->activeSubControls & SC_ToolButton)
1443 bflags |= State_Sunken;
1444 mflags |= State_Sunken;
1445 }
1446
1447 QStyleOption tool(0);
1448 tool.palette = toolbutton->palette;
1449 if (toolbutton->subControls & SC_ToolButton) {
1450 if (bflags & (State_Sunken | State_On | State_Raised)) {
1451 tool.rect = button;
1452 tool.state = bflags;
1453 drawPrimitive(PE_PanelButtonTool, &tool, p, widget);
1454 }
1455 }
1456
1457 if ((toolbutton->state & State_HasFocus) && (!focus || !focus->isVisible())) {
1458 QStyleOptionFocusRect fr;
1459 fr.QStyleOption::operator=(*toolbutton);
1460 fr.rect = toolbutton->rect.adjusted(3, 3, -3, -3);
1461 drawPrimitive(PE_FrameFocusRect, &fr, p, widget);
1462 }
1463 QStyleOptionToolButton label = *toolbutton;
1464 label.state = bflags;
1465 int fw = pixelMetric(PM_DefaultFrameWidth, opt, widget);
1466 label.rect = button.adjusted(fw, fw, -fw, -fw);
1467 drawControl(CE_ToolButtonLabel, &label, p, widget);
1468
1469 if (toolbutton->subControls & SC_ToolButtonMenu) {
1470 tool.rect = menuarea;
1471 tool.state = mflags;
1472 if (mflags & (State_Sunken | State_On | State_Raised))
1473 drawPrimitive(PE_IndicatorButtonDropDown, &tool, p, widget);
1474 drawPrimitive(PE_IndicatorArrowDown, &tool, p, widget);
1475 } else if (toolbutton->features & QStyleOptionToolButton::HasMenu) {
1476 int mbi = pixelMetric(PM_MenuButtonIndicator, toolbutton, widget);
1477 QRect ir = toolbutton->rect;
1478 QStyleOptionToolButton newBtn = *toolbutton;
1479 newBtn.rect = QRect(ir.right() + 5 - mbi, ir.height() - mbi + 4, mbi - 6, mbi - 6);
1480 drawPrimitive(PE_IndicatorArrowDown, &newBtn, p, widget);
1481 }
1482 }
1483 break;
1484#ifndef QT_NO_SPINBOX
1485 case CC_SpinBox:
1486 if (const QStyleOptionSpinBox *spinbox = qstyleoption_cast<const QStyleOptionSpinBox *>(opt)) {
1487 QStyleOptionSpinBox copy = *spinbox;
1488 PrimitiveElement pe;
1489
1490 if (spinbox->frame && (spinbox->subControls & SC_SpinBoxFrame)) {
1491 QRect r = subControlRect(CC_SpinBox, spinbox, SC_SpinBoxFrame, widget);
1492 qDrawShadePanel(p, r, opt->palette, false, pixelMetric(PM_SpinBoxFrameWidth));
1493
1494 int fw = pixelMetric(QStyle::PM_DefaultFrameWidth);
1495 r = subControlRect(CC_SpinBox, spinbox, SC_SpinBoxEditField, widget).adjusted(-fw,-fw,fw,fw);
1496 QStyleOptionFrame lineOpt;
1497 lineOpt.QStyleOption::operator=(*opt);
1498 lineOpt.rect = r;
1499 lineOpt.lineWidth = fw;
1500 lineOpt.midLineWidth = 0;
1501 lineOpt.state |= QStyle::State_Sunken;
1502 drawPrimitive(QStyle::PE_FrameLineEdit, &lineOpt, p, widget);
1503 }
1504
1505 if (spinbox->subControls & SC_SpinBoxUp) {
1506 copy.subControls = SC_SpinBoxUp;
1507 QPalette pal2 = spinbox->palette;
1508 if (!(spinbox->stepEnabled & QAbstractSpinBox::StepUpEnabled)) {
1509 pal2.setCurrentColorGroup(QPalette::Disabled);
1510 copy.state &= ~State_Enabled;
1511 }
1512
1513 copy.palette = pal2;
1514
1515 if (spinbox->activeSubControls == SC_SpinBoxUp && (spinbox->state & State_Sunken)) {
1516 copy.state |= State_On;
1517 copy.state |= State_Sunken;
1518 } else {
1519 copy.state |= State_Raised;
1520 copy.state &= ~State_Sunken;
1521 }
1522 pe = (spinbox->buttonSymbols == QAbstractSpinBox::PlusMinus ? PE_IndicatorSpinPlus
1523 : PE_IndicatorSpinUp);
1524
1525 copy.rect = subControlRect(CC_SpinBox, spinbox, SC_SpinBoxUp, widget);
1526 drawPrimitive(pe, &copy, p, widget);
1527 }
1528
1529 if (spinbox->subControls & SC_SpinBoxDown) {
1530 copy.subControls = SC_SpinBoxDown;
1531 copy.state = spinbox->state;
1532 QPalette pal2 = spinbox->palette;
1533 if (!(spinbox->stepEnabled & QAbstractSpinBox::StepDownEnabled)) {
1534 pal2.setCurrentColorGroup(QPalette::Disabled);
1535 copy.state &= ~State_Enabled;
1536 }
1537 copy.palette = pal2;
1538
1539 if (spinbox->activeSubControls == SC_SpinBoxDown && (spinbox->state & State_Sunken)) {
1540 copy.state |= State_On;
1541 copy.state |= State_Sunken;
1542 } else {
1543 copy.state |= State_Raised;
1544 copy.state &= ~State_Sunken;
1545 }
1546 pe = (spinbox->buttonSymbols == QAbstractSpinBox::PlusMinus ? PE_IndicatorSpinMinus
1547 : PE_IndicatorSpinDown);
1548
1549 copy.rect = subControlRect(CC_SpinBox, spinbox, SC_SpinBoxDown, widget);
1550 drawPrimitive(pe, &copy, p, widget);
1551 }
1552 }
1553 break;
1554#endif // QT_NO_SPINBOX
1555#ifndef QT_NO_SLIDER
1556 case CC_Slider:
1557 if (const QStyleOptionSlider *slider = qstyleoption_cast<const QStyleOptionSlider *>(opt)) {
1558 QRect groove = subControlRect(CC_Slider, opt, SC_SliderGroove, widget),
1559 handle = subControlRect(CC_Slider, opt, SC_SliderHandle, widget);
1560
1561 if ((opt->subControls & SC_SliderGroove) && groove.isValid()) {
1562 qDrawShadePanel(p, groove, opt->palette, true, pixelMetric(PM_DefaultFrameWidth),
1563 &opt->palette.brush((opt->state & State_Enabled) ? QPalette::Mid : QPalette::Window));
1564 if ((opt->state & State_HasFocus) && (!focus || !focus->isVisible())) {
1565 QStyleOption focusOpt = *opt;
1566 focusOpt.rect = subElementRect(SE_SliderFocusRect, opt, widget);
1567 drawPrimitive(PE_FrameFocusRect, &focusOpt, p, widget);
1568 }
1569 }
1570
1571 if ((opt->subControls & SC_SliderHandle) && handle.isValid()) {
1572 QStyleOption bevelOpt = *opt;
1573 bevelOpt.state = (opt->state | State_Raised) & ~State_Sunken;
1574 bevelOpt.rect = handle;
1575 p->save();
1576 p->setBrushOrigin(bevelOpt.rect.topLeft());
1577 drawPrimitive(PE_PanelButtonBevel, &bevelOpt, p, widget);
1578 p->restore();
1579
1580 if (slider->orientation == Qt::Horizontal) {
1581 int mid = handle.x() + handle.width() / 2;
1582 qDrawShadeLine(p, mid, handle.y(), mid, handle.y() + handle.height() - 2,
1583 opt->palette, true, 1);
1584 } else {
1585 int mid = handle.y() + handle.height() / 2;
1586 qDrawShadeLine(p, handle.x(), mid, handle.x() + handle.width() - 2, mid, opt->palette,
1587 true, 1);
1588 }
1589 if (!(opt->state & State_Enabled) && styleHint(SH_DitherDisabledText))
1590 p->fillRect(handle, QBrush(p->background().color(), Qt::Dense5Pattern));
1591 }
1592
1593 if (slider->subControls & SC_SliderTickmarks) {
1594 QStyleOptionSlider tmpSlider = *slider;
1595 tmpSlider.subControls = SC_SliderTickmarks;
1596 int frameWidth = pixelMetric(PM_DefaultFrameWidth);
1597 tmpSlider.rect.translate(frameWidth - 1, 0);
1598 QCommonStyle::drawComplexControl(cc, &tmpSlider, p, widget);
1599 }
1600 }
1601 break;
1602#endif // QT_NO_SLIDER
1603 case CC_ComboBox:
1604 if (const QStyleOptionComboBox *cb = qstyleoption_cast<const QStyleOptionComboBox *>(opt)) {
1605 if (opt->subControls & SC_ComboBoxArrow) {
1606 int awh, ax, ay, sh, sy, dh, ew;
1607 int fw = cb->frame ? pixelMetric(PM_ComboBoxFrameWidth, opt, widget) : 0;
1608
1609 if (cb->frame) {
1610 QStyleOptionButton btn;
1611 btn.QStyleOption::operator=(*cb);
1612 btn.state |= QStyle::State_Raised;
1613 drawPrimitive(PE_PanelButtonCommand, &btn, p, widget);
1614 } else {
1615 p->fillRect(opt->rect, opt->palette.brush(QPalette::Button));
1616 }
1617
1618 QRect tr = opt->rect;
1619 tr.adjust(fw, fw, -fw, -fw);
1620 get_combo_parameters(tr, ew, awh, ax, ay, sh, dh, sy);
1621
1622 QRect ar = QStyle::visualRect(opt->direction, opt->rect, QRect(ax,ay,awh,awh));
1623
1624 QStyleOption arrowOpt = *opt;
1625 arrowOpt.rect = ar;
1626 arrowOpt.state |= State_Enabled;
1627 drawPrimitive(PE_IndicatorArrowDown, &arrowOpt, p, widget);
1628
1629
1630 // draws the shaded line under the arrow
1631 p->setPen(opt->palette.light().color());
1632 p->drawLine(ar.x(), sy, ar.x()+awh-1, sy);
1633 p->drawLine(ar.x(), sy, ar.x(), sy+sh-1);
1634 p->setPen(opt->palette.dark().color());
1635 p->drawLine(ar.x()+1, sy+sh-1, ar.x()+awh-1, sy+sh-1);
1636 p->drawLine(ar.x()+awh-1, sy+1, ar.x()+awh-1, sy+sh-1);
1637
1638 if ((cb->state & State_HasFocus) && (!focus || !focus->isVisible())) {
1639 QStyleOptionFocusRect focus;
1640 focus.QStyleOption::operator=(*opt);
1641 focus.rect = subElementRect(SE_ComboBoxFocusRect, opt, widget);
1642 focus.backgroundColor = opt->palette.button().color();
1643 drawPrimitive(PE_FrameFocusRect, &focus, p, widget);
1644 }
1645 }
1646
1647 if (opt->subControls & SC_ComboBoxEditField) {
1648 if (cb->editable) {
1649 QRect er = subControlRect(CC_ComboBox, opt, SC_ComboBoxEditField, widget);
1650 er.adjust(-1, -1, 1, 1);
1651 qDrawShadePanel(p, er, opt->palette, true, 1,
1652 &opt->palette.brush(QPalette::Base));
1653 }
1654 }
1655 p->setPen(opt->palette.buttonText().color());
1656 }
1657 break;
1658
1659#ifndef QT_NO_SCROLLBAR
1660 case CC_ScrollBar: {
1661 if (opt->subControls & SC_ScrollBarGroove)
1662 qDrawShadePanel(p, opt->rect, opt->palette, true,
1663 pixelMetric(PM_DefaultFrameWidth, opt, widget),
1664 &opt->palette.brush((opt->state & State_Enabled) ? QPalette::Mid : QPalette::Window));
1665
1666 if (const QStyleOptionSlider *scrollbar = qstyleoption_cast<const QStyleOptionSlider *>(opt)) {
1667 QStyleOptionSlider newScrollbar = *scrollbar;
1668 if (scrollbar->minimum == scrollbar->maximum)
1669 newScrollbar.state |= State_Enabled; // make sure that the slider is drawn.
1670 QCommonStyle::drawComplexControl(cc, &newScrollbar, p, widget);
1671 }
1672 break; }
1673#endif
1674
1675 case CC_Q3ListView:
1676 if (opt->subControls & (SC_Q3ListViewBranch | SC_Q3ListViewExpand)) {
1677 int i;
1678 if (opt->subControls & SC_Q3ListView)
1679 QCommonStyle::drawComplexControl(cc, opt, p, widget);
1680 if (const QStyleOptionQ3ListView *lv = qstyleoption_cast<const QStyleOptionQ3ListView *>(opt)) {
1681 QStyleOptionQ3ListViewItem item = lv->items.at(0);
1682 int y = opt->rect.y();
1683 int c;
1684 QPolygon dotlines;
1685 if ((opt->activeSubControls & SC_All) && (opt->subControls & SC_Q3ListViewExpand)) {
1686 c = 2;
1687 dotlines.resize(2);
1688 dotlines[0] = QPoint(opt->rect.right(), opt->rect.top());
1689 dotlines[1] = QPoint(opt->rect.right(), opt->rect.bottom());
1690 } else {
1691 int linetop = 0, linebot = 0;
1692 // each branch needs at most two lines, ie. four end points
1693 dotlines.resize(item.childCount * 4);
1694 c = 0;
1695
1696 // skip the stuff above the exposed rectangle
1697 for (i = 1; i < lv->items.size(); ++i) {
1698 QStyleOptionQ3ListViewItem child = lv->items.at(i);
1699 if (child.height + y > 0)
1700 break;
1701 y += child.totalHeight;
1702 }
1703
1704 int bx = opt->rect.width() / 2;
1705
1706 // paint stuff in the magical area
1707 while (i < lv->items.size() && y < lv->rect.height()) {
1708 QStyleOptionQ3ListViewItem child = lv->items.at(i);
1709 if (child.features & QStyleOptionQ3ListViewItem::Visible) {
1710 int lh;
1711 if (!(item.features & QStyleOptionQ3ListViewItem::MultiLine))
1712 lh = child.height;
1713 else
1714 lh = p->fontMetrics().height() + 2 * lv->itemMargin;
1715 lh = qMax(lh, QApplication::globalStrut().height());
1716 if (lh % 2 > 0)
1717 lh++;
1718 linebot = y + lh/2;
1719 if ((child.features & QStyleOptionQ3ListViewItem::Expandable || child.childCount > 0) &&
1720 child.height > 0) {
1721 // needs a box
1722 p->setPen(opt->palette.text().color());
1723 p->drawRect(bx-4, linebot-4, 9, 9);
1724 QPolygon a;
1725 if ((child.state & State_Open))
1726 a.setPoints(3, bx-2, linebot-2,
1727 bx, linebot+2,
1728 bx+2, linebot-2); //Qt::RightArrow
1729 else
1730 a.setPoints(3, bx-2, linebot-2,
1731 bx+2, linebot,
1732 bx-2, linebot+2); //Qt::DownArrow
1733 p->setBrush(opt->palette.text());
1734 p->drawPolygon(a);
1735 p->setBrush(Qt::NoBrush);
1736 // dotlinery
1737 dotlines[c++] = QPoint(bx, linetop);
1738 dotlines[c++] = QPoint(bx, linebot - 5);
1739 dotlines[c++] = QPoint(bx + 5, linebot);
1740 dotlines[c++] = QPoint(opt->rect.width(), linebot);
1741 linetop = linebot + 5;
1742 } else {
1743 // just dotlinery
1744 dotlines[c++] = QPoint(bx+1, linebot);
1745 dotlines[c++] = QPoint(opt->rect.width(), linebot);
1746 }
1747 y += child.totalHeight;
1748 }
1749 ++i;
1750 }
1751
1752 // Expand line height to edge of rectangle if there's any
1753 // visible child below
1754 while (i < lv->items.size() && lv->items.at(i).height <= 0)
1755 ++i;
1756 if (i < lv->items.size())
1757 linebot = opt->rect.height();
1758
1759 if (linetop < linebot) {
1760 dotlines[c++] = QPoint(bx, linetop);
1761 dotlines[c++] = QPoint(bx, linebot);
1762 }
1763 }
1764
1765 int line; // index into dotlines
1766 p->setPen(opt->palette.text().color());
1767 if (opt->subControls & SC_Q3ListViewBranch) for(line = 0; line < c; line += 2) {
1768 p->drawLine(dotlines[line].x(), dotlines[line].y(),
1769 dotlines[line+1].x(), dotlines[line+1].y());
1770 }
1771 }
1772 break; }
1773
1774 default:
1775 QCommonStyle::drawComplexControl(cc, opt, p, widget);
1776 break;
1777 }
1778}
1779
1780
1781/*! \reimp */
1782int QMotifStyle::pixelMetric(PixelMetric pm, const QStyleOption *opt,
1783 const QWidget *widget) const
1784{
1785 int ret = 0;
1786
1787 switch(pm) {
1788 case PM_ButtonDefaultIndicator:
1789 ret = 5;
1790 break;
1791
1792 case PM_CheckBoxLabelSpacing:
1793 case PM_RadioButtonLabelSpacing:
1794 ret = 10;
1795 break;
1796
1797 case PM_ToolBarFrameWidth:
1798 ret = pixelMetric(PM_DefaultFrameWidth);
1799 break;
1800
1801 case PM_ToolBarItemMargin:
1802 ret = 1;
1803 break;
1804
1805 case PM_ButtonShiftHorizontal:
1806 case PM_ButtonShiftVertical:
1807 ret = 0;
1808 break;
1809
1810 case PM_SplitterWidth:
1811 ret = qMax(10, QApplication::globalStrut().width());
1812 break;
1813
1814 case PM_SliderLength:
1815 ret = 30;
1816 break;
1817
1818 case PM_SliderThickness:
1819 ret = 16 + 4 * pixelMetric(PM_DefaultFrameWidth);
1820 break;
1821#ifndef QT_NO_SLIDER
1822 case PM_SliderControlThickness:
1823 if (const QStyleOptionSlider *sl = qstyleoption_cast<const QStyleOptionSlider *>(opt)) {
1824 int space = (sl->orientation == Qt::Horizontal) ? sl->rect.height() : sl->rect.width();
1825 int ticks = sl->tickPosition;
1826 int n = 0;
1827 if (ticks & QSlider::TicksAbove)
1828 n++;
1829 if (ticks & QSlider::TicksBelow)
1830 n++;
1831 if (!n) {
1832 ret = space;
1833 break;
1834 }
1835
1836 int thick = 6; // Magic constant to get 5 + 16 + 5
1837
1838 space -= thick;
1839 //### the two sides may be unequal in size
1840 if (space > 0)
1841 thick += (space * 2) / (n + 2);
1842 ret = thick;
1843 }
1844 break;
1845
1846 case PM_SliderSpaceAvailable:
1847 if (const QStyleOptionSlider *sl = qstyleoption_cast<const QStyleOptionSlider *>(opt)) {
1848 if (sl->orientation == Qt::Horizontal)
1849 ret = sl->rect.width() - pixelMetric(PM_SliderLength, opt, widget) - 2 * pixelMetric(PM_DefaultFrameWidth, opt, widget);
1850 else
1851 ret = sl->rect.height() - pixelMetric(PM_SliderLength, opt, widget) - 2 * pixelMetric(PM_DefaultFrameWidth, opt, widget);
1852 }
1853 break;
1854#endif // QT_NO_SLIDER
1855 case PM_DockWidgetFrameWidth:
1856 ret = 2;
1857 break;
1858
1859 case PM_DockWidgetHandleExtent:
1860 ret = 9;
1861 break;
1862
1863 case PM_ProgressBarChunkWidth:
1864 ret = 1;
1865 break;
1866
1867 case PM_ExclusiveIndicatorWidth:
1868 case PM_ExclusiveIndicatorHeight:
1869 ret = 13;
1870 break;
1871
1872 case PM_MenuBarHMargin:
1873 ret = 2; // really ugly, but Motif
1874 break;
1875
1876 case PM_MenuButtonIndicator:
1877 if (!opt)
1878 ret = 12;
1879 else
1880 ret = qMax(12, (opt->rect.height() - 4) / 3);
1881 break;
1882 default:
1883 ret = QCommonStyle::pixelMetric(pm, opt, widget);
1884 break;
1885 }
1886 return ret;
1887}
1888
1889
1890/*!
1891 \reimp
1892*/
1893QRect
1894QMotifStyle::subControlRect(ComplexControl cc, const QStyleOptionComplex *opt,
1895 SubControl sc, const QWidget *widget) const
1896{
1897 switch (cc) {
1898#ifndef QT_NO_SPINBOX
1899 case CC_SpinBox:
1900 if (const QStyleOptionSpinBox *spinbox = qstyleoption_cast<const QStyleOptionSpinBox *>(opt)) {
1901 int fw = spinbox->frame ? pixelMetric(PM_SpinBoxFrameWidth, spinbox, widget) : 0;
1902 QSize bs;
1903 bs.setHeight(opt->rect.height()/2 - fw);
1904 bs.setWidth(qMin(bs.height() * 8 / 5, opt->rect.width() / 4)); // 1.6 -approximate golden mean
1905 bs = bs.expandedTo(QApplication::globalStrut());
1906 int y = fw + spinbox->rect.y();
1907 int x, lx, rx;
1908 x = spinbox->rect.x() + opt->rect.width() - fw - bs.width();
1909 lx = fw;
1910 rx = x - fw * 2;
1911 const int margin = spinbox->frame ? 4 : 0;
1912 switch (sc) {
1913 case SC_SpinBoxUp:
1914 if (spinbox->buttonSymbols == QAbstractSpinBox::NoButtons)
1915 return QRect();
1916 return visualRect(spinbox->direction, spinbox->rect,
1917 QRect(x, y, bs.width(), bs.height() - 1));
1918 case SC_SpinBoxDown:
1919 if (spinbox->buttonSymbols == QAbstractSpinBox::NoButtons)
1920 return QRect();
1921 return visualRect(spinbox->direction, spinbox->rect,
1922 QRect(x, y + bs.height() + 1, bs.width(), bs.height() - 1));
1923 case SC_SpinBoxEditField:
1924 if (spinbox->buttonSymbols == QAbstractSpinBox::NoButtons)
1925 return visualRect(spinbox->direction, spinbox->rect,
1926 QRect(lx + margin, y + margin,
1927 spinbox->rect.width() - 2*fw - 2*margin,
1928 spinbox->rect.height() - 2*fw - 2*margin));
1929
1930 return visualRect(spinbox->direction, spinbox->rect,
1931 QRect(lx + margin, y + margin, rx - margin,
1932 spinbox->rect.height() - 2*fw - 2 * margin));
1933 case SC_SpinBoxFrame:
1934 return visualRect(spinbox->direction, spinbox->rect, spinbox->rect);
1935 default:
1936 break;
1937 }
1938 break; }
1939#endif // QT_NO_SPINBOX
1940#ifndef QT_NO_SLIDER
1941 case CC_Slider:
1942 if (const QStyleOptionSlider *slider = qstyleoption_cast<const QStyleOptionSlider *>(opt)) {
1943 if (sc == SC_SliderHandle) {
1944 int tickOffset = pixelMetric(PM_SliderTickmarkOffset, opt, widget);
1945 int thickness = pixelMetric(PM_SliderControlThickness, opt, widget);
1946 bool horizontal = slider->orientation == Qt::Horizontal;
1947 int len = pixelMetric(PM_SliderLength, opt, widget);
1948 int motifBorder = pixelMetric(PM_DefaultFrameWidth);
1949 int sliderPos = sliderPositionFromValue(slider->minimum, slider->maximum, slider->sliderPosition,
1950 horizontal ? slider->rect.width() - len - 2 * motifBorder
1951 : slider->rect.height() - len - 2 * motifBorder,
1952 slider->upsideDown);
1953 if (horizontal)
1954 return visualRect(slider->direction, slider->rect,
1955 QRect(sliderPos + motifBorder, tickOffset + motifBorder, len,
1956 thickness - 2 * motifBorder));
1957 return visualRect(slider->direction, slider->rect,
1958 QRect(tickOffset + motifBorder, sliderPos + motifBorder,
1959 thickness - 2 * motifBorder, len));
1960 }
1961 }
1962 break;
1963#endif // QT_NO_SLIDER
1964#ifndef QT_NO_SCROLLBAR
1965 case CC_ScrollBar:
1966 if (const QStyleOptionSlider *scrollbar = qstyleoption_cast<const QStyleOptionSlider *>(opt)) {
1967 int dfw = pixelMetric(PM_DefaultFrameWidth);
1968 QRect rect = visualRect(scrollbar->direction, scrollbar->rect,
1969 QCommonStyle::subControlRect(cc, scrollbar, sc, widget));
1970 if (sc == SC_ScrollBarSlider) {
1971 if (scrollbar->orientation == Qt::Horizontal)
1972 rect.adjust(-dfw, dfw, dfw, -dfw);
1973 else
1974 rect.adjust(dfw, -dfw, -dfw, dfw);
1975 } else if (sc != SC_ScrollBarGroove) {
1976 if (scrollbar->orientation == Qt::Horizontal)
1977 rect.adjust(0, dfw, 0, -dfw);
1978 else
1979 rect.adjust(dfw, 0, -dfw, 0);
1980 }
1981 return visualRect(scrollbar->direction, scrollbar->rect, rect);
1982 }
1983 break;
1984#endif // QT_NO_SCROLLBAR
1985#ifndef QT_NO_COMBOBOX
1986 case CC_ComboBox:
1987 if (const QStyleOptionComboBox *cb = qstyleoption_cast<const QStyleOptionComboBox *>(opt)) {
1988 switch (sc) {
1989 case SC_ComboBoxArrow: {
1990 int ew, awh, sh, dh, ax, ay, sy;
1991 int fw = cb->frame ? pixelMetric(PM_ComboBoxFrameWidth, opt, widget) : 0;
1992 QRect cr = opt->rect;
1993 cr.adjust(fw, fw, -fw, -fw);
1994 get_combo_parameters(cr, ew, awh, ax, ay, sh, dh, sy);
1995 return visualRect(cb->direction, cb->rect, QRect(QPoint(ax, ay), cr.bottomRight()));
1996 }
1997
1998 case SC_ComboBoxEditField: {
1999 int fw = cb->frame ? pixelMetric(PM_ComboBoxFrameWidth, opt, widget) : 0;
2000 QRect rect = opt->rect;
2001 rect.adjust(fw, fw, -fw, -fw);
2002 int ew = get_combo_extra_width(rect.height(), rect.width());
2003 rect.adjust(1, 1, -1-ew, -1);
2004 return visualRect(cb->direction, cb->rect, rect);
2005 }
2006
2007 default:
2008 break;
2009 }
2010 }
2011 break;
2012#endif // QT_NO_SCROLLBAR
2013 default:
2014 break;
2015 }
2016 return QCommonStyle::subControlRect(cc, opt, sc, widget);
2017}
2018
2019/*!
2020 \reimp
2021*/
2022QSize
2023QMotifStyle::sizeFromContents(ContentsType ct, const QStyleOption *opt,
2024 const QSize &contentsSize, const QWidget *widget) const
2025{
2026 QSize sz(contentsSize);
2027
2028 switch(ct) {
2029 case CT_Splitter:
2030 sz = QSize(10, 10);
2031 break;
2032
2033 case CT_RadioButton:
2034 case CT_CheckBox:
2035 sz = QCommonStyle::sizeFromContents(ct, opt, contentsSize, widget);
2036 sz.rwidth() += motifItemFrame;
2037 break;
2038
2039 case CT_PushButton:
2040 if (const QStyleOptionButton *btn = qstyleoption_cast<const QStyleOptionButton *>(opt)) {
2041 sz = QCommonStyle::sizeFromContents(ct, opt, contentsSize, widget);
2042 if (!btn->text.isEmpty() && (btn->features & (QStyleOptionButton::AutoDefaultButton|QStyleOptionButton::DefaultButton)))
2043 sz.setWidth(qMax(75, sz.width()));
2044 sz += QSize(0, 1); // magical extra pixel
2045 }
2046 break;
2047
2048 case CT_MenuBarItem: {
2049 if(!sz.isEmpty())
2050 sz += QSize(5*motifItemHMargin+1, 2*motifItemVMargin + motifItemFrame);
2051 break; }
2052
2053 case CT_MenuItem:
2054 if (const QStyleOptionMenuItem *mi = qstyleoption_cast<const QStyleOptionMenuItem *>(opt)) {
2055 sz = QCommonStyle::sizeFromContents(ct, opt, sz, widget);
2056 int w = sz.width(), h = sz.height();
2057
2058 if (mi->menuItemType == QStyleOptionMenuItem::Separator) {
2059 w = 10;
2060 h = (mi->text.isEmpty()) ? motifSepHeight : mi->fontMetrics.lineSpacing();
2061 }
2062
2063 // a little bit of border can never harm
2064 w += 2*motifItemHMargin + 2*motifItemFrame;
2065
2066 if (!mi->text.isNull() && mi->text.indexOf(QLatin1Char('\t')) >= 0)
2067 // string contains tab
2068 w += motifTabSpacing;
2069 else if (mi->menuItemType == QStyleOptionMenuItem::SubMenu)
2070 // submenu indicator needs some room if we don't have a tab column
2071 w += motifArrowHMargin + 4*motifItemFrame;
2072
2073 int checkColumn = mi->maxIconWidth;
2074 if (mi->menuHasCheckableItems)
2075 checkColumn = qMax(checkColumn, motifCheckMarkSpace);
2076 if (checkColumn > 0)
2077 w += checkColumn + motifCheckMarkHMargin;
2078
2079 sz = QSize(w, h);
2080 }
2081 break;
2082
2083
2084 default:
2085 sz = QCommonStyle::sizeFromContents(ct, opt, contentsSize, widget);
2086 break;
2087 }
2088
2089 return sz;
2090}
2091
2092/*!
2093 \reimp
2094*/
2095QRect
2096QMotifStyle::subElementRect(SubElement sr, const QStyleOption *opt, const QWidget *widget) const
2097{
2098 QRect rect;
2099
2100 switch (sr) {
2101 case SE_SliderFocusRect:
2102 rect = QCommonStyle::subElementRect(sr, opt, widget);
2103 rect.adjust(2, 2, -2, -2);
2104 break;
2105
2106 case SE_CheckBoxIndicator:
2107 case SE_RadioButtonIndicator:
2108 {
2109 rect = visualRect(opt->direction, opt->rect,
2110 QCommonStyle::subElementRect(sr, opt, widget));
2111 rect.adjust(motifItemFrame,0, motifItemFrame,0);
2112 rect = visualRect(opt->direction, opt->rect, rect);
2113 }
2114 break;
2115
2116 case SE_ComboBoxFocusRect:
2117 {
2118 int awh, ax, ay, sh, sy, dh, ew;
2119 int fw = pixelMetric(PM_DefaultFrameWidth, opt, widget);
2120 QRect tr = opt->rect;
2121
2122 tr.adjust(fw, fw, -fw, -fw);
2123 get_combo_parameters(tr, ew, awh, ax, ay, sh, dh, sy);
2124 rect.setRect(ax-2, ay-2, awh+4, awh+sh+dh+4);
2125 break;
2126 }
2127
2128 case SE_Q3DockWindowHandleRect:
2129 if (const QStyleOptionQ3DockWindow *dw = qstyleoption_cast<const QStyleOptionQ3DockWindow *>(opt)) {
2130 if (!dw->docked || !dw->closeEnabled)
2131 rect.setRect(0, 0, opt->rect.width(), opt->rect.height());
2132 else {
2133 if (dw->state == State_Horizontal)
2134 rect.setRect(2, 15, opt->rect.width()-2, opt->rect.height() - 15);
2135 else
2136 rect.setRect(0, 2, opt->rect.width() - 15, opt->rect.height() - 2);
2137 }
2138 rect = visualRect(dw->direction, dw->rect, rect);
2139 }
2140 break;
2141
2142 case SE_ProgressBarLabel:
2143 case SE_ProgressBarGroove:
2144 case SE_ProgressBarContents:
2145 if (const QStyleOptionProgressBar *pb = qstyleoption_cast<const QStyleOptionProgressBar *>(opt)) {
2146 int textw = 0;
2147 if (pb->textVisible)
2148 textw = pb->fontMetrics.width(QLatin1String("100%")) + 6;
2149
2150 if (pb->textAlignment == Qt::AlignLeft || pb->textAlignment == Qt::AlignCenter) {
2151 rect = opt->rect;
2152 } else {
2153 if(sr == SE_ProgressBarLabel)
2154 rect.setCoords(opt->rect.right() - textw, opt->rect.top(),
2155 opt->rect.right(), opt->rect.bottom());
2156 else
2157 rect.setCoords(opt->rect.left(), opt->rect.top(),
2158 opt->rect.right() - textw, opt->rect.bottom());
2159 }
2160 if (sr == SE_ProgressBarContents)
2161 rect.adjust(2, 2, -2, -2);
2162 rect = visualRect(pb->direction, pb->rect, rect);
2163 }
2164 break;
2165 case SE_CheckBoxClickRect:
2166 case SE_RadioButtonClickRect:
2167 rect = visualRect(opt->direction, opt->rect, opt->rect);
2168 break;
2169
2170 default:
2171 rect = QCommonStyle::subElementRect(sr, opt, widget);
2172 }
2173 return rect;
2174}
2175
2176#ifndef QT_NO_IMAGEFORMAT_XPM
2177static const char * const qt_menu_xpm[] = {
2178"16 16 11 1",
2179" c #000000",
2180", c #336600",
2181". c #99CC00",
2182"X c #666600",
2183"o c #999933",
2184"+ c #333300",
2185"@ c #669900",
2186"# c #999900",
2187"$ c #336633",
2188"% c #666633",
2189"& c #99CC33",
2190"................",
2191"................",
2192".....#,++X#.....",
2193"....X X....",
2194"...X Xo#% X&..",
2195"..# o..&@o o..",
2196".., X..#+ @X X..",
2197"..+ o.o+ +o# +..",
2198"..+ #o+ +## +..",
2199".., %@ ++ +, X..",
2200"..# o@oo+ #..",
2201"...X X##$ o..",
2202"....X X..",
2203"....&oX++X#oX...",
2204"................",
2205"................"};
2206
2207
2208static const char * const qt_close_xpm[] = {
2209 "12 12 2 1",
2210 " s None c None",
2211 ". c black",
2212 " ",
2213 " ",
2214 " . . ",
2215 " ... ... ",
2216 " ...... ",
2217 " .... ",
2218 " .... ",
2219 " ...... ",
2220 " ... ... ",
2221 " . . ",
2222 " ",
2223 " "};
2224
2225static const char * const qt_maximize_xpm[] = {
2226 "12 12 2 1",
2227 " s None c None",
2228 ". c black",
2229 " ",
2230 " ",
2231 " ",
2232 " . ",
2233 " ... ",
2234 " ..... ",
2235 " ....... ",
2236 " ......... ",
2237 " ",
2238 " ",
2239 " ",
2240 " "};
2241
2242static const char * const qt_minimize_xpm[] = {
2243 "12 12 2 1",
2244 " s None c None",
2245 ". c black",
2246 " ",
2247 " ",
2248 " ",
2249 " ",
2250 " ......... ",
2251 " ....... ",
2252 " ..... ",
2253 " ... ",
2254 " . ",
2255 " ",
2256 " ",
2257 " "};
2258
2259#if 0 // ### not used???
2260static const char * const qt_normalize_xpm[] = {
2261 "12 12 2 1",
2262 " s None c None",
2263 ". c black",
2264 " ",
2265 " ",
2266 " . ",
2267 " .. ",
2268 " ... ",
2269 " .... ",
2270 " ..... ",
2271 " ...... ",
2272 " ....... ",
2273 " ",
2274 " ",
2275 " "};
2276#endif
2277
2278static const char * const qt_normalizeup_xpm[] = {
2279 "12 12 2 1",
2280 " s None c None",
2281 ". c black",
2282 " ",
2283 " ",
2284 " ",
2285 " ....... ",
2286 " ...... ",
2287 " ..... ",
2288 " .... ",
2289 " ... ",
2290 " .. ",
2291 " . ",
2292 " ",
2293 " "};
2294
2295static const char * const qt_shade_xpm[] = {
2296 "12 12 2 1", "# c #000000",
2297 ". c None",
2298 "............",
2299 "............",
2300 ".#########..",
2301 ".#########..",
2302 "............",
2303 "............",
2304 "............",
2305 "............",
2306 "............",
2307 "............",
2308 "............",
2309 "............"};
2310
2311
2312static const char * const qt_unshade_xpm[] = {
2313 "12 12 2 1",
2314 "# c #000000",
2315 ". c None",
2316 "............",
2317 "............",
2318 ".#########..",
2319 ".#########..",
2320 ".#.......#..",
2321 ".#.......#..",
2322 ".#.......#..",
2323 ".#.......#..",
2324 ".#.......#..",
2325 ".#########..",
2326 "............",
2327 "............"};
2328
2329
2330static const char * dock_window_close_xpm[] = {
2331 "8 8 2 1",
2332 "# c #000000",
2333 ". c None",
2334 "##....##",
2335 ".##..##.",
2336 "..####..",
2337 "...##...",
2338 "..####..",
2339 ".##..##.",
2340 "##....##",
2341 "........"};
2342
2343// Message box icons, from page 210 of the Windows style guide.
2344
2345// Hand-drawn to resemble Microsoft's icons, but in the Mac/Netscape palette.
2346// Thanks to TrueColor displays, it is slightly more efficient to have
2347// them duplicated.
2348/* XPM */
2349static const char * const information_xpm[]={
2350 "32 32 5 1",
2351 ". c None",
2352 "c c #000000",
2353 "* c #999999",
2354 "a c #ffffff",
2355 "b c #0000ff",
2356 "...........********.............",
2357 "........***aaaaaaaa***..........",
2358 "......**aaaaaaaaaaaaaa**........",
2359 ".....*aaaaaaaaaaaaaaaaaa*.......",
2360 "....*aaaaaaaabbbbaaaaaaaac......",
2361 "...*aaaaaaaabbbbbbaaaaaaaac.....",
2362 "..*aaaaaaaaabbbbbbaaaaaaaaac....",
2363 ".*aaaaaaaaaaabbbbaaaaaaaaaaac...",
2364 ".*aaaaaaaaaaaaaaaaaaaaaaaaaac*..",
2365 "*aaaaaaaaaaaaaaaaaaaaaaaaaaaac*.",
2366 "*aaaaaaaaaabbbbbbbaaaaaaaaaaac*.",
2367 "*aaaaaaaaaaaabbbbbaaaaaaaaaaac**",
2368 "*aaaaaaaaaaaabbbbbaaaaaaaaaaac**",
2369 "*aaaaaaaaaaaabbbbbaaaaaaaaaaac**",
2370 "*aaaaaaaaaaaabbbbbaaaaaaaaaaac**",
2371 "*aaaaaaaaaaaabbbbbaaaaaaaaaaac**",
2372 ".*aaaaaaaaaaabbbbbaaaaaaaaaac***",
2373 ".*aaaaaaaaaaabbbbbaaaaaaaaaac***",
2374 "..*aaaaaaaaaabbbbbaaaaaaaaac***.",
2375 "...caaaaaaabbbbbbbbbaaaaaac****.",
2376 "....caaaaaaaaaaaaaaaaaaaac****..",
2377 ".....caaaaaaaaaaaaaaaaaac****...",
2378 "......ccaaaaaaaaaaaaaacc****....",
2379 ".......*cccaaaaaaaaccc*****.....",
2380 "........***cccaaaac*******......",
2381 "..........****caaac*****........",
2382 ".............*caaac**...........",
2383 "...............caac**...........",
2384 "................cac**...........",
2385 ".................cc**...........",
2386 "..................***...........",
2387 "...................**..........."};
2388/* XPM */
2389static const char* const warning_xpm[]={
2390 "32 32 4 1",
2391 ". c None",
2392 "a c #ffff00",
2393 "* c #000000",
2394 "b c #999999",
2395 ".............***................",
2396 "............*aaa*...............",
2397 "...........*aaaaa*b.............",
2398 "...........*aaaaa*bb............",
2399 "..........*aaaaaaa*bb...........",
2400 "..........*aaaaaaa*bb...........",
2401 ".........*aaaaaaaaa*bb..........",
2402 ".........*aaaaaaaaa*bb..........",
2403 "........*aaaaaaaaaaa*bb.........",
2404 "........*aaaa***aaaa*bb.........",
2405 ".......*aaaa*****aaaa*bb........",
2406 ".......*aaaa*****aaaa*bb........",
2407 "......*aaaaa*****aaaaa*bb.......",
2408 "......*aaaaa*****aaaaa*bb.......",
2409 ".....*aaaaaa*****aaaaaa*bb......",
2410 ".....*aaaaaa*****aaaaaa*bb......",
2411 "....*aaaaaaaa***aaaaaaaa*bb.....",
2412 "....*aaaaaaaa***aaaaaaaa*bb.....",
2413 "...*aaaaaaaaa***aaaaaaaaa*bb....",
2414 "...*aaaaaaaaaa*aaaaaaaaaa*bb....",
2415 "..*aaaaaaaaaaa*aaaaaaaaaaa*bb...",
2416 "..*aaaaaaaaaaaaaaaaaaaaaaa*bb...",
2417 ".*aaaaaaaaaaaa**aaaaaaaaaaa*bb..",
2418 ".*aaaaaaaaaaa****aaaaaaaaaa*bb..",
2419 "*aaaaaaaaaaaa****aaaaaaaaaaa*bb.",
2420 "*aaaaaaaaaaaaa**aaaaaaaaaaaa*bb.",
2421 "*aaaaaaaaaaaaaaaaaaaaaaaaaaa*bbb",
2422 "*aaaaaaaaaaaaaaaaaaaaaaaaaaa*bbb",
2423 ".*aaaaaaaaaaaaaaaaaaaaaaaaa*bbbb",
2424 "..*************************bbbbb",
2425 "....bbbbbbbbbbbbbbbbbbbbbbbbbbb.",
2426 ".....bbbbbbbbbbbbbbbbbbbbbbbbb.."};
2427/* XPM */
2428static const char* const critical_xpm[]={
2429 "32 32 4 1",
2430 ". c None",
2431 "a c #999999",
2432 "* c #ff0000",
2433 "b c #ffffff",
2434 "...........********.............",
2435 ".........************...........",
2436 ".......****************.........",
2437 "......******************........",
2438 ".....********************a......",
2439 "....**********************a.....",
2440 "...************************a....",
2441 "..*******b**********b*******a...",
2442 "..******bbb********bbb******a...",
2443 ".******bbbbb******bbbbb******a..",
2444 ".*******bbbbb****bbbbb*******a..",
2445 "*********bbbbb**bbbbb*********a.",
2446 "**********bbbbbbbbbb**********a.",
2447 "***********bbbbbbbb***********aa",
2448 "************bbbbbb************aa",
2449 "************bbbbbb************aa",
2450 "***********bbbbbbbb***********aa",
2451 "**********bbbbbbbbbb**********aa",
2452 "*********bbbbb**bbbbb*********aa",
2453 ".*******bbbbb****bbbbb*******aa.",
2454 ".******bbbbb******bbbbb******aa.",
2455 "..******bbb********bbb******aaa.",
2456 "..*******b**********b*******aa..",
2457 "...************************aaa..",
2458 "....**********************aaa...",
2459 "....a********************aaa....",
2460 ".....a******************aaa.....",
2461 "......a****************aaa......",
2462 ".......aa************aaaa.......",
2463 ".........aa********aaaaa........",
2464 "...........aaaaaaaaaaa..........",
2465 ".............aaaaaaa............"};
2466/* XPM */
2467static const char *const question_xpm[] = {
2468 "32 32 5 1",
2469 ". c None",
2470 "c c #000000",
2471 "* c #999999",
2472 "a c #ffffff",
2473 "b c #0000ff",
2474 "...........********.............",
2475 "........***aaaaaaaa***..........",
2476 "......**aaaaaaaaaaaaaa**........",
2477 ".....*aaaaaaaaaaaaaaaaaa*.......",
2478 "....*aaaaaaaaaaaaaaaaaaaac......",
2479 "...*aaaaaaaabbbbbbaaaaaaaac.....",
2480 "..*aaaaaaaabaaabbbbaaaaaaaac....",
2481 ".*aaaaaaaabbaaaabbbbaaaaaaaac...",
2482 ".*aaaaaaaabbbbaabbbbaaaaaaaac*..",
2483 "*aaaaaaaaabbbbaabbbbaaaaaaaaac*.",
2484 "*aaaaaaaaaabbaabbbbaaaaaaaaaac*.",
2485 "*aaaaaaaaaaaaabbbbaaaaaaaaaaac**",
2486 "*aaaaaaaaaaaaabbbaaaaaaaaaaaac**",
2487 "*aaaaaaaaaaaaabbaaaaaaaaaaaaac**",
2488 "*aaaaaaaaaaaaabbaaaaaaaaaaaaac**",
2489 "*aaaaaaaaaaaaaaaaaaaaaaaaaaaac**",
2490 ".*aaaaaaaaaaaabbaaaaaaaaaaaac***",
2491 ".*aaaaaaaaaaabbbbaaaaaaaaaaac***",
2492 "..*aaaaaaaaaabbbbaaaaaaaaaac***.",
2493 "...caaaaaaaaaabbaaaaaaaaaac****.",
2494 "....caaaaaaaaaaaaaaaaaaaac****..",
2495 ".....caaaaaaaaaaaaaaaaaac****...",
2496 "......ccaaaaaaaaaaaaaacc****....",
2497 ".......*cccaaaaaaaaccc*****.....",
2498 "........***cccaaaac*******......",
2499 "..........****caaac*****........",
2500 ".............*caaac**...........",
2501 "...............caac**...........",
2502 "................cac**...........",
2503 ".................cc**...........",
2504 "..................***...........",
2505 "...................**...........",
2506};
2507#endif
2508
2509/*!
2510 \reimp
2511*/
2512QPixmap
2513QMotifStyle::standardPixmap(StandardPixmap standardPixmap, const QStyleOption *opt,
2514 const QWidget *widget) const
2515{
2516#ifndef QT_NO_IMAGEFORMAT_XPM
2517 switch (standardPixmap) {
2518 case SP_TitleBarMenuButton:
2519 return QPixmap(qt_menu_xpm);
2520 case SP_TitleBarShadeButton:
2521 return QPixmap(qt_shade_xpm);
2522 case SP_TitleBarUnshadeButton:
2523 return QPixmap(qt_unshade_xpm);
2524 case SP_TitleBarNormalButton:
2525 return QPixmap(qt_normalizeup_xpm);
2526 case SP_TitleBarMinButton:
2527 return QPixmap(qt_minimize_xpm);
2528 case SP_TitleBarMaxButton:
2529 return QPixmap(qt_maximize_xpm);
2530 case SP_TitleBarCloseButton:
2531 return QPixmap(qt_close_xpm);
2532 case SP_DockWidgetCloseButton:
2533 return QPixmap(dock_window_close_xpm);
2534
2535 case SP_MessageBoxInformation:
2536 case SP_MessageBoxWarning:
2537 case SP_MessageBoxCritical:
2538 case SP_MessageBoxQuestion:
2539 {
2540 const char * const * xpm_data;
2541 switch (standardPixmap) {
2542 case SP_MessageBoxInformation:
2543 xpm_data = information_xpm;
2544 break;
2545 case SP_MessageBoxWarning:
2546 xpm_data = warning_xpm;
2547 break;
2548 case SP_MessageBoxCritical:
2549 xpm_data = critical_xpm;
2550 break;
2551 case SP_MessageBoxQuestion:
2552 xpm_data = question_xpm;
2553 break;
2554 default:
2555 xpm_data = 0;
2556 break;
2557 }
2558 QPixmap pm;
2559 if (xpm_data) {
2560 QImage image((const char **) xpm_data);
2561 // All that color looks ugly in Motif
2562 const QPalette &pal = QApplication::palette();
2563 switch (standardPixmap) {
2564 case SP_MessageBoxInformation:
2565 case SP_MessageBoxQuestion:
2566 image.setColor(2, 0xff000000 |
2567 pal.color(QPalette::Active, QPalette::Dark).rgb());
2568 image.setColor(3, 0xff000000 |
2569 pal.color(QPalette::Active, QPalette::Base).rgb());
2570 image.setColor(4, 0xff000000 |
2571 pal.color(QPalette::Active, QPalette::Text).rgb());
2572 break;
2573 case SP_MessageBoxWarning:
2574 image.setColor(1, 0xff000000 |
2575 pal.color(QPalette::Active, QPalette::Base).rgb());
2576 image.setColor(2, 0xff000000 |
2577 pal.color(QPalette::Active, QPalette::Text).rgb());
2578 image.setColor(3, 0xff000000 |
2579 pal.color(QPalette::Active, QPalette::Dark).rgb());
2580 break;
2581 case SP_MessageBoxCritical:
2582 image.setColor(1, 0xff000000 |
2583 pal.color(QPalette::Active, QPalette::Dark).rgb());
2584 image.setColor(2, 0xff000000 |
2585 pal.color(QPalette::Active, QPalette::Text).rgb());
2586 image.setColor(3, 0xff000000 |
2587 pal.color(QPalette::Active, QPalette::Base).rgb());
2588 break;
2589 default:
2590 break;
2591 }
2592 pm = QPixmap::fromImage(image);
2593 }
2594 return pm;
2595 }
2596
2597 default:
2598 break;
2599 }
2600#endif
2601
2602 return QCommonStyle::standardPixmap(standardPixmap, opt, widget);
2603}
2604
2605/*! \reimp */
2606bool QMotifStyle::event(QEvent *e)
2607{
2608 if(e->type() == QEvent::FocusIn) {
2609 if (QWidget *focusWidget = QApplication::focusWidget()) {
2610#ifndef QT_NO_GRAPHICSVIEW
2611 if (QGraphicsView *graphicsView = qobject_cast<QGraphicsView *>(focusWidget)) {
2612 QGraphicsItem *focusItem = graphicsView->scene() ? graphicsView->scene()->focusItem() : 0;
2613 if (focusItem && focusItem->type() == QGraphicsProxyWidget::Type) {
2614 QGraphicsProxyWidget *proxy = static_cast<QGraphicsProxyWidget *>(focusItem);
2615 if (proxy->widget())
2616 focusWidget = proxy->widget()->focusWidget();
2617 }
2618 }
2619#endif
2620 if(!focus)
2621 focus = new QFocusFrame(focusWidget);
2622 focus->setWidget(focusWidget);
2623 } else {
2624 if(focus)
2625 focus->setWidget(0);
2626 }
2627 } else if(e->type() == QEvent::FocusOut) {
2628 if(focus)
2629 focus->setWidget(0);
2630 }
2631 return QCommonStyle::event(e);
2632}
2633
2634
2635/*! \reimp */
2636int
2637QMotifStyle::styleHint(StyleHint hint, const QStyleOption *opt, const QWidget *widget,
2638 QStyleHintReturn *returnData) const
2639{
2640 int ret;
2641
2642 switch (hint) {
2643#ifdef QT3_SUPPORT
2644 case SH_GUIStyle:
2645 ret = Qt::MotifStyle;
2646 break;
2647#endif
2648 case SH_DrawMenuBarSeparator:
2649 ret = true;
2650 break;
2651
2652 case SH_ScrollBar_MiddleClickAbsolutePosition:
2653 case SH_Slider_SloppyKeyEvents:
2654 case SH_ProgressDialog_CenterCancelButton:
2655 case SH_Menu_SpaceActivatesItem:
2656 case SH_ScrollView_FrameOnlyAroundContents:
2657 case SH_DitherDisabledText:
2658 ret = 1;
2659 break;
2660
2661 case SH_Menu_SubMenuPopupDelay:
2662 ret = 96;
2663 break;
2664
2665 case SH_ProgressDialog_TextLabelAlignment:
2666 ret = Qt::AlignLeft | Qt::AlignVCenter;
2667 break;
2668
2669 case SH_ItemView_ChangeHighlightOnFocus:
2670 ret = 0;
2671 break;
2672
2673 case SH_MessageBox_UseBorderForButtonSpacing:
2674 ret = 1;
2675 break;
2676
2677 case SH_Dial_BackgroundRole:
2678 ret = QPalette::Mid;
2679 break;
2680
2681 case SH_DialogButtonLayout:
2682 ret = QDialogButtonBox::KdeLayout;
2683 break;
2684 case SH_LineEdit_PasswordCharacter:
2685 ret = '*';
2686 break;
2687 default:
2688 ret = QCommonStyle::styleHint(hint, opt, widget, returnData);
2689 break;
2690 }
2691
2692 return ret;
2693}
2694
2695/*! \reimp */
2696QPalette QMotifStyle::standardPalette() const
2697{
2698#ifdef Q_WS_X11
2699 QColor background(0xcf, 0xcf, 0xcf);
2700 if (QX11Info::appDepth() <= 8)
2701 background = QColor(0xc0, 0xc0, 0xc0);
2702#else
2703 QColor background = QColor(0xcf, 0xcf, 0xcf);
2704#endif
2705
2706 QColor light = background.lighter();
2707 QColor mid = QColor(0xa6, 0xa6, 0xa6);
2708 QColor dark = QColor(0x79, 0x7d, 0x79);
2709 QPalette palette(Qt::black, background, light, dark, mid, Qt::black, Qt::white);
2710 palette.setBrush(QPalette::Disabled, QPalette::WindowText, dark);
2711 palette.setBrush(QPalette::Disabled, QPalette::Text, dark);
2712 palette.setBrush(QPalette::Disabled, QPalette::ButtonText, dark);
2713 palette.setBrush(QPalette::Disabled, QPalette::Base, background);
2714 return palette;
2715}
2716
2717QT_END_NAMESPACE
2718
2719#endif // !defined(QT_NO_STYLE_MOTIF) || defined(QT_PLUGIN)
Note: See TracBrowser for help on using the repository browser.