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

Last change on this file since 1147 was 846, checked in by Dmitry A. Kuminov, 14 years ago

trunk: Merged in qt 4.7.2 sources from branches/vendor/nokia/qt.

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