source: trunk/src/kernel/qdrawutil.cpp@ 154

Last change on this file since 154 was 2, checked in by dmik, 20 years ago

Imported xplatform parts of the official release 3.3.1 from Trolltech

  • Property svn:keywords set to Id
File size: 28.0 KB
Line 
1/****************************************************************************
2** $Id: qdrawutil.cpp 2 2005-11-16 15:49:26Z dmik $
3**
4** Implementation of draw utilities
5**
6** Created : 950920
7**
8** Copyright (C) 1992-2000 Trolltech AS. All rights reserved.
9**
10** This file is part of the kernel module of the Qt GUI Toolkit.
11**
12** This file may be distributed under the terms of the Q Public License
13** as defined by Trolltech AS of Norway and appearing in the file
14** LICENSE.QPL included in the packaging of this file.
15**
16** This file may be distributed and/or modified under the terms of the
17** GNU General Public License version 2 as published by the Free Software
18** Foundation and appearing in the file LICENSE.GPL included in the
19** packaging of this file.
20**
21** Licensees holding valid Qt Enterprise Edition or Qt Professional Edition
22** licenses may use this file in accordance with the Qt Commercial License
23** Agreement provided with the Software.
24**
25** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
26** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
27**
28** See http://www.trolltech.com/pricing.html or email sales@trolltech.com for
29** information about Qt Commercial License Agreements.
30** See http://www.trolltech.com/qpl/ for QPL licensing information.
31** See http://www.trolltech.com/gpl/ for GPL licensing information.
32**
33** Contact info@trolltech.com if any conditions of this licensing are
34** not clear to you.
35**
36**********************************************************************/
37
38#include "qdrawutil.h"
39#ifndef QT_NO_DRAWUTIL
40#include "qbitmap.h"
41#include "qpixmapcache.h"
42#include "qapplication.h"
43#include "qpainter.h"
44
45/*!
46 \relates QPainter
47
48 \c{#include <qdrawutil.h>}
49
50 Draws a horizontal (\a y1 == \a y2) or vertical (\a x1 == \a x2)
51 shaded line using the painter \a p.
52
53 Nothing is drawn if \a y1 != \a y2 and \a x1 != \a x2 (i.e. the
54 line is neither horizontal nor vertical).
55
56 The color group argument \a g specifies the shading colors (\link
57 QColorGroup::light() light\endlink, \link QColorGroup::dark()
58 dark\endlink and \link QColorGroup::mid() middle\endlink colors).
59
60 The line appears sunken if \a sunken is TRUE, or raised if \a
61 sunken is FALSE.
62
63 The \a lineWidth argument specifies the line width for each of the
64 lines. It is not the total line width.
65
66 The \a midLineWidth argument specifies the width of a middle line
67 drawn in the QColorGroup::mid() color.
68
69 If you want to use a QFrame widget instead, you can make it
70 display a shaded line, for example \c{QFrame::setFrameStyle(
71 QFrame::HLine | QFrame::Sunken )}.
72
73 \warning This function does not look at QWidget::style() or
74 QApplication::style(). Use the drawing functions in QStyle to make
75 widgets that follow the current GUI style.
76
77 \sa qDrawShadeRect(), qDrawShadePanel(), QStyle::drawPrimitive()
78*/
79
80void qDrawShadeLine( QPainter *p, int x1, int y1, int x2, int y2,
81 const QColorGroup &g, bool sunken,
82 int lineWidth, int midLineWidth )
83{
84 if (!( p && lineWidth >= 0 && midLineWidth >= 0 ) ) {
85#if defined(QT_CHECK_RANGE)
86 qWarning( "qDrawShadeLine invalid parameters." );
87#endif
88 return;
89 }
90 int tlw = lineWidth*2 + midLineWidth; // total line width
91 QPen oldPen = p->pen(); // save pen
92 if ( sunken )
93 p->setPen( g.dark() );
94 else
95 p->setPen( g.light() );
96 QPointArray a;
97 int i;
98 if ( y1 == y2 ) { // horizontal line
99 int y = y1 - tlw/2;
100 if ( x1 > x2 ) { // swap x1 and x2
101 int t = x1;
102 x1 = x2;
103 x2 = t;
104 }
105 x2--;
106 for ( i=0; i<lineWidth; i++ ) { // draw top shadow
107 a.setPoints( 3, x1+i, y+tlw-1-i,
108 x1+i, y+i,
109 x2-i, y+i );
110 p->drawPolyline( a );
111 }
112 if ( midLineWidth > 0 ) {
113 p->setPen( g.mid() );
114 for ( i=0; i<midLineWidth; i++ ) // draw lines in the middle
115 p->drawLine( x1+lineWidth, y+lineWidth+i,
116 x2-lineWidth, y+lineWidth+i );
117 }
118 if ( sunken )
119 p->setPen( g.light() );
120 else
121 p->setPen( g.dark() );
122 for ( i=0; i<lineWidth; i++ ) { // draw bottom shadow
123 a.setPoints( 3, x1+i, y+tlw-i-1,
124 x2-i, y+tlw-i-1,
125 x2-i, y+i+1 );
126 p->drawPolyline( a );
127 }
128 }
129 else if ( x1 == x2 ) { // vertical line
130 int x = x1 - tlw/2;
131 if ( y1 > y2 ) { // swap y1 and y2
132 int t = y1;
133 y1 = y2;
134 y2 = t;
135 }
136 y2--;
137 for ( i=0; i<lineWidth; i++ ) { // draw left shadow
138 a.setPoints( 3, x+i, y2,
139 x+i, y1+i,
140 x+tlw-1, y1+i );
141 p->drawPolyline( a );
142 }
143 if ( midLineWidth > 0 ) {
144 p->setPen( g.mid() );
145 for ( i=0; i<midLineWidth; i++ ) // draw lines in the middle
146 p->drawLine( x+lineWidth+i, y1+lineWidth, x+lineWidth+i, y2 );
147 }
148 if ( sunken )
149 p->setPen( g.light() );
150 else
151 p->setPen( g.dark() );
152 for ( i=0; i<lineWidth; i++ ) { // draw right shadow
153 a.setPoints( 3, x+lineWidth, y2-i,
154 x+tlw-i-1, y2-i,
155 x+tlw-i-1, y1+lineWidth );
156 p->drawPolyline( a );
157 }
158 }
159 p->setPen( oldPen );
160}
161
162
163/*!
164 \relates QPainter
165
166 \c{#include <qdrawutil.h>}
167
168 Draws the shaded rectangle specified by (\a x, \a y, \a w, \a h)
169 using the painter \a p.
170
171 The color group argument \a g specifies the shading colors (\link
172 QColorGroup::light() light\endlink, \link QColorGroup::dark()
173 dark\endlink and \link QColorGroup::mid() middle\endlink colors).
174
175 The rectangle appears sunken if \a sunken is TRUE, or raised if \a
176 sunken is FALSE.
177
178 The \a lineWidth argument specifies the line width for each of the
179 lines. It is not the total line width.
180
181 The \a midLineWidth argument specifies the width of a middle line
182 drawn in the QColorGroup::mid() color.
183
184 The rectangle's interior is filled with the \a fill brush unless
185 \a fill is 0.
186
187 If you want to use a QFrame widget instead, you can make it
188 display a shaded rectangle, for example \c{QFrame::setFrameStyle(
189 QFrame::Box | QFrame::Raised )}.
190
191 \warning This function does not look at QWidget::style() or
192 QApplication::style(). Use the drawing functions in QStyle to make
193 widgets that follow the current GUI style.
194
195 \sa qDrawShadeLine(), qDrawShadePanel(), qDrawPlainRect(),
196 QStyle::drawItem(), QStyle::drawControl()
197 QStyle::drawComplexControl()
198*/
199
200void qDrawShadeRect( QPainter *p, int x, int y, int w, int h,
201 const QColorGroup &g, bool sunken,
202 int lineWidth, int midLineWidth,
203 const QBrush *fill )
204{
205 if ( w == 0 || h == 0 )
206 return;
207 if ( ! ( w > 0 && h > 0 && lineWidth >= 0 && midLineWidth >= 0 ) ) {
208#if defined(QT_CHECK_RANGE)
209 qWarning( "qDrawShadeRect(): Invalid parameters" );
210#endif
211 return;
212 }
213 QPen oldPen = p->pen();
214 if ( sunken )
215 p->setPen( g.dark() );
216 else
217 p->setPen( g.light() );
218 int x1=x, y1=y, x2=x+w-1, y2=y+h-1;
219 QPointArray a;
220
221 if ( lineWidth == 1 && midLineWidth == 0 ) {// standard shade rectangle
222 p->drawRect( x1, y1, w-1, h-1 );
223 if ( sunken )
224 p->setPen( g.light() );
225 else
226 p->setPen( g.dark() );
227 a.setPoints( 8, x1+1,y1+1, x2-2,y1+1, x1+1,y1+2, x1+1,y2-2,
228 x1,y2, x2,y2, x2,y1, x2,y2-1 );
229 p->drawLineSegments( a ); // draw bottom/right lines
230 } else { // more complicated
231 int m = lineWidth+midLineWidth;
232 int i, j=0, k=m;
233 for ( i=0; i<lineWidth; i++ ) { // draw top shadow
234 a.setPoints( 8, x1+i, y2-i, x1+i, y1+i, x1+i, y1+i, x2-i, y1+i,
235 x1+k, y2-k, x2-k, y2-k, x2-k, y2-k, x2-k, y1+k );
236 p->drawLineSegments( a );
237 k++;
238 }
239 p->setPen( g.mid() );
240 j = lineWidth*2;
241 for ( i=0; i<midLineWidth; i++ ) { // draw lines in the middle
242 p->drawRect( x1+lineWidth+i, y1+lineWidth+i, w-j, h-j );
243 j += 2;
244 }
245 if ( sunken )
246 p->setPen( g.light() );
247 else
248 p->setPen( g.dark() );
249 k = m;
250 for ( i=0; i<lineWidth; i++ ) { // draw bottom shadow
251 a.setPoints( 8, x1+1+i,y2-i, x2-i, y2-i, x2-i, y2-i, x2-i, y1+i+1,
252 x1+k, y2-k, x1+k, y1+k, x1+k, y1+k, x2-k, y1+k );
253 p->drawLineSegments( a );
254 k++;
255 }
256 }
257 if ( fill ) {
258 QBrush oldBrush = p->brush();
259 int tlw = lineWidth + midLineWidth;
260 p->setPen( Qt::NoPen );
261 p->setBrush( *fill );
262 p->drawRect( x+tlw, y+tlw, w-2*tlw, h-2*tlw );
263 p->setBrush( oldBrush );
264 }
265 p->setPen( oldPen ); // restore pen
266}
267
268
269/*!
270 \relates QPainter
271
272 \c{#include <qdrawutil.h>}
273
274 Draws the shaded panel specified by (\a x, \a y, \a w, \a h) using
275 the painter \a p.
276
277 The color group argument \a g specifies the shading colors (\link
278 QColorGroup::light() light\endlink, \link QColorGroup::dark()
279 dark\endlink and \link QColorGroup::mid() middle\endlink colors).
280
281 The panel appears sunken if \a sunken is TRUE, or raised if \a
282 sunken is FALSE.
283
284 The \a lineWidth argument specifies the line width.
285
286 The panel's interior is filled with the \a fill brush unless \a
287 fill is 0.
288
289 If you want to use a QFrame widget instead, you can make it
290 display a shaded panel, for example \c{QFrame::setFrameStyle(
291 QFrame::Panel | QFrame::Sunken )}.
292
293 \warning This function does not look at QWidget::style() or
294 QApplication::style(). Use the drawing functions in QStyle to make
295 widgets that follow the current GUI style.
296
297 \sa qDrawWinPanel(), qDrawShadeLine(), qDrawShadeRect(),
298 QStyle::drawPrimitive()
299*/
300
301void qDrawShadePanel( QPainter *p, int x, int y, int w, int h,
302 const QColorGroup &g, bool sunken,
303 int lineWidth, const QBrush *fill )
304{
305 if ( w == 0 || h == 0 )
306 return;
307 if ( !( w > 0 && h > 0 && lineWidth >= 0 ) ) {
308#if defined(QT_CHECK_RANGE)
309 qWarning( "qDrawShadePanel() Invalid parameters." );
310#endif
311 }
312 QColor shade = g.dark();
313 QColor light = g.light();
314 if ( fill ) {
315 if ( fill->color() == shade )
316 shade = g.shadow();
317 if ( fill->color() == light )
318 light = g.midlight();
319 }
320 QPen oldPen = p->pen(); // save pen
321 QPointArray a( 4*lineWidth );
322 if ( sunken )
323 p->setPen( shade );
324 else
325 p->setPen( light );
326 int x1, y1, x2, y2;
327 int i;
328 int n = 0;
329 x1 = x;
330 y1 = y2 = y;
331 x2 = x+w-2;
332 for ( i=0; i<lineWidth; i++ ) { // top shadow
333 a.setPoint( n++, x1, y1++ );
334 a.setPoint( n++, x2--, y2++ );
335 }
336 x2 = x1;
337 y1 = y+h-2;
338 for ( i=0; i<lineWidth; i++ ) { // left shadow
339 a.setPoint( n++, x1++, y1 );
340 a.setPoint( n++, x2++, y2-- );
341 }
342 p->drawLineSegments( a );
343 n = 0;
344 if ( sunken )
345 p->setPen( light );
346 else
347 p->setPen( shade );
348 x1 = x;
349 y1 = y2 = y+h-1;
350 x2 = x+w-1;
351 for ( i=0; i<lineWidth; i++ ) { // bottom shadow
352 a.setPoint( n++, x1++, y1-- );
353 a.setPoint( n++, x2, y2-- );
354 }
355 x1 = x2;
356 y1 = y;
357 y2 = y+h-lineWidth-1;
358 for ( i=0; i<lineWidth; i++ ) { // right shadow
359 a.setPoint( n++, x1--, y1++ );
360 a.setPoint( n++, x2--, y2 );
361 }
362 p->drawLineSegments( a );
363 if ( fill ) { // fill with fill color
364 QBrush oldBrush = p->brush();
365 p->setPen( Qt::NoPen );
366 p->setBrush( *fill );
367 p->drawRect( x+lineWidth, y+lineWidth, w-lineWidth*2, h-lineWidth*2 );
368 p->setBrush( oldBrush );
369 }
370 p->setPen( oldPen ); // restore pen
371}
372
373
374/*!
375 \internal
376 This function draws a rectangle with two pixel line width.
377 It is called from qDrawWinButton() and qDrawWinPanel().
378
379 c1..c4 and fill are used:
380
381 1 1 1 1 1 2
382 1 3 3 3 4 2
383 1 3 F F 4 2
384 1 3 F F 4 2
385 1 4 4 4 4 2
386 2 2 2 2 2 2
387*/
388
389static void qDrawWinShades( QPainter *p,
390 int x, int y, int w, int h,
391 const QColor &c1, const QColor &c2,
392 const QColor &c3, const QColor &c4,
393 const QBrush *fill )
394{
395 if ( w < 2 || h < 2 ) // can't do anything with that
396 return;
397 QPen oldPen = p->pen();
398 QPointArray a( 3 );
399 a.setPoints( 3, x, y+h-2, x, y, x+w-2, y );
400 p->setPen( c1 );
401 p->drawPolyline( a );
402 a.setPoints( 3, x, y+h-1, x+w-1, y+h-1, x+w-1, y );
403 p->setPen( c2 );
404 p->drawPolyline( a );
405 if ( w > 4 && h > 4 ) {
406 a.setPoints( 3, x+1, y+h-3, x+1, y+1, x+w-3, y+1 );
407 p->setPen( c3 );
408 p->drawPolyline( a );
409 a.setPoints( 3, x+1, y+h-2, x+w-2, y+h-2, x+w-2, y+1 );
410 p->setPen( c4 );
411 p->drawPolyline( a );
412 if ( fill ) {
413 QBrush oldBrush = p->brush();
414 p->setBrush( *fill );
415 p->setPen( Qt::NoPen );
416 p->drawRect( x+2, y+2, w-4, h-4 );
417 p->setBrush( oldBrush );
418 }
419 }
420 p->setPen( oldPen );
421}
422
423
424/*!
425 \relates QPainter
426
427 \c{#include <qdrawutil.h>}
428
429 Draws the Windows-style button specified by (\a x, \a y, \a w, \a
430 h) using the painter \a p.
431
432 The color group argument \a g specifies the shading colors (\link
433 QColorGroup::light() light\endlink, \link QColorGroup::dark()
434 dark\endlink and \link QColorGroup::mid() middle\endlink colors).
435
436 The button appears sunken if \a sunken is TRUE, or raised if \a
437 sunken is FALSE.
438
439 The line width is 2 pixels.
440
441 The button's interior is filled with the \a *fill brush unless \a
442 fill is 0.
443
444 \warning This function does not look at QWidget::style() or
445 QApplication::style(). Use the drawing functions in QStyle to make
446 widgets that follow the current GUI style.
447
448 \sa qDrawWinPanel(), QStyle::drawControl()
449*/
450
451void qDrawWinButton( QPainter *p, int x, int y, int w, int h,
452 const QColorGroup &g, bool sunken,
453 const QBrush *fill )
454{
455 if ( sunken )
456 qDrawWinShades( p, x, y, w, h,
457 g.shadow(), g.light(), g.dark(), g.button(), fill );
458 else
459 qDrawWinShades( p, x, y, w, h,
460 g.light(), g.shadow(), g.button(), g.dark(), fill );
461}
462
463/*!
464 \relates QPainter
465
466 \c{#include <qdrawutil.h>}
467
468 Draws the Windows-style panel specified by (\a x, \a y, \a w, \a
469 h) using the painter \a p.
470
471 The color group argument \a g specifies the shading colors.
472
473 The panel appears sunken if \a sunken is TRUE, or raised if \a
474 sunken is FALSE.
475
476 The line width is 2 pixels.
477
478 The button's interior is filled with the \a fill brush unless \a
479 fill is 0.
480
481 If you want to use a QFrame widget instead, you can make it
482 display a shaded panel, for example \c{QFrame::setFrameStyle(
483 QFrame::WinPanel | QFrame::Raised )}.
484
485 \warning This function does not look at QWidget::style() or
486 QApplication::style(). Use the drawing functions in QStyle to make
487 widgets that follow the current GUI style.
488
489 \sa qDrawShadePanel(), qDrawWinButton(), QStyle::drawPrimitive()
490*/
491
492void qDrawWinPanel( QPainter *p, int x, int y, int w, int h,
493 const QColorGroup &g, bool sunken,
494 const QBrush *fill )
495{
496 if ( sunken )
497 qDrawWinShades( p, x, y, w, h,
498 g.dark(), g.light(), g.shadow(), g.midlight(), fill );
499 else
500 qDrawWinShades( p, x, y, w, h,
501 g.light(), g.shadow(), g.midlight(), g.dark(), fill );
502}
503
504
505/*!
506 \relates QPainter
507
508 \c{#include <qdrawutil.h>}
509
510 Draws the plain rectangle specified by (\a x, \a y, \a w, \a h)
511 using the painter \a p.
512
513 The color argument \a c specifies the line color.
514
515 The \a lineWidth argument specifies the line width.
516
517 The rectangle's interior is filled with the \a fill brush unless
518 \a fill is 0.
519
520 If you want to use a QFrame widget instead, you can make it
521 display a plain rectangle, for example \c{QFrame::setFrameStyle(
522 QFrame::Box | QFrame::Plain )}.
523
524 \warning This function does not look at QWidget::style() or
525 QApplication::style(). Use the drawing functions in QStyle to make
526 widgets that follow the current GUI style.
527
528 \sa qDrawShadeRect(), QStyle::drawPrimitive()
529*/
530
531void qDrawPlainRect( QPainter *p, int x, int y, int w, int h, const QColor &c,
532 int lineWidth, const QBrush *fill )
533{
534 if ( w == 0 || h == 0 )
535 return;
536 if ( !( w > 0 && h > 0 && lineWidth >= 0 ) ) {
537#if defined(QT_CHECK_RANGE)
538 qWarning( "qDrawPlainRect() Invalid parameters." );
539#endif
540 }
541 QPen oldPen = p->pen();
542 QBrush oldBrush = p->brush();
543 p->setPen( c );
544 p->setBrush( Qt::NoBrush );
545 for ( int i=0; i<lineWidth; i++ )
546 p->drawRect( x+i, y+i, w-i*2, h-i*2 );
547 if ( fill ) { // fill with fill color
548 p->setPen( Qt::NoPen );
549 p->setBrush( *fill );
550 p->drawRect( x+lineWidth, y+lineWidth, w-lineWidth*2, h-lineWidth*2 );
551 }
552 p->setPen( oldPen );
553 p->setBrush( oldBrush );
554}
555
556
557QRect qItemRect( QPainter *p, Qt::GUIStyle gs,
558 int x, int y, int w, int h,
559 int flags,
560 bool enabled,
561 const QPixmap *pixmap,
562 const QString& text, int len )
563{
564 QRect result;
565
566 if ( pixmap ) {
567 if ( (flags & Qt::AlignVCenter) == Qt::AlignVCenter )
568 y += h/2 - pixmap->height()/2;
569 else if ( (flags & Qt::AlignBottom) == Qt::AlignBottom)
570 y += h - pixmap->height();
571 if ( (flags & Qt::AlignRight) == Qt::AlignRight )
572 x += w - pixmap->width();
573 else if ( (flags & Qt::AlignHCenter) == Qt::AlignHCenter )
574 x += w/2 - pixmap->width()/2;
575 else if ( (flags & Qt::AlignLeft) != Qt::AlignLeft && QApplication::reverseLayout() )
576 x += w - pixmap->width();
577 result = QRect(x, y, pixmap->width(), pixmap->height());
578 } else if ( !text.isNull() && p ) {
579 result = p->boundingRect( x, y, w, h, flags, text, len );
580 if ( gs == Qt::WindowsStyle && !enabled ) {
581 result.setWidth(result.width()+1);
582 result.setHeight(result.height()+1);
583 }
584 } else {
585 result = QRect(x, y, w, h);
586 }
587
588 return result;
589}
590
591
592void qDrawItem( QPainter *p, Qt::GUIStyle gs,
593 int x, int y, int w, int h,
594 int flags,
595 const QColorGroup &g, bool enabled,
596 const QPixmap *pixmap,
597 const QString& text, int len , const QColor* penColor )
598{
599 p->setPen( penColor?*penColor:g.foreground() );
600 if ( pixmap ) {
601 QPixmap pm( *pixmap );
602 bool clip = (flags & Qt::DontClip) == 0;
603 if ( clip ) {
604 if ( pm.width() < w && pm.height() < h )
605 clip = FALSE;
606 else
607 p->setClipRect( x, y, w, h );
608 }
609 if ( (flags & Qt::AlignVCenter) == Qt::AlignVCenter )
610 y += h/2 - pm.height()/2;
611 else if ( (flags & Qt::AlignBottom) == Qt::AlignBottom)
612 y += h - pm.height();
613 if ( (flags & Qt::AlignRight) == Qt::AlignRight )
614 x += w - pm.width();
615 else if ( (flags & Qt::AlignHCenter) == Qt::AlignHCenter )
616 x += w/2 - pm.width()/2;
617 else if ( ((flags & Qt::AlignLeft) != Qt::AlignLeft) && QApplication::reverseLayout() ) // AlignAuto && rightToLeft
618 x += w - pm.width();
619
620 if ( !enabled ) {
621 if ( pm.mask() ) { // pixmap with a mask
622 if ( !pm.selfMask() ) { // mask is not pixmap itself
623 QPixmap pmm( *pm.mask() );
624 pmm.setMask( *((QBitmap *)&pmm) );
625 pm = pmm;
626 }
627 } else if ( pm.depth() == 1 ) { // monochrome pixmap, no mask
628 pm.setMask( *((QBitmap *)&pm) );
629#ifndef QT_NO_IMAGE_HEURISTIC_MASK
630 } else { // color pixmap, no mask
631 QString k;
632 k.sprintf( "$qt-drawitem-%x", pm.serialNumber() );
633 QPixmap *mask = QPixmapCache::find(k);
634 bool del=FALSE;
635 if ( !mask ) {
636 mask = new QPixmap( pm.createHeuristicMask() );
637 mask->setMask( *((QBitmap*)mask) );
638 del = !QPixmapCache::insert( k, mask );
639 }
640 pm = *mask;
641 if (del) delete mask;
642#endif
643 }
644 if ( gs == Qt::WindowsStyle ) {
645 p->setPen( g.light() );
646 p->drawPixmap( x+1, y+1, pm );
647 p->setPen( g.text() );
648 }
649 }
650 p->drawPixmap( x, y, pm );
651 if ( clip )
652 p->setClipping( FALSE );
653 } else if ( !text.isNull() ) {
654 if ( gs == Qt::WindowsStyle && !enabled ) {
655 p->setPen( g.light() );
656 p->drawText( x+1, y+1, w, h, flags, text, len );
657 p->setPen( g.text() );
658 }
659 p->drawText( x, y, w, h, flags, text, len );
660 }
661}
662
663
664/*****************************************************************************
665 Overloaded functions.
666 *****************************************************************************/
667
668/*!
669 \overload void qDrawShadeLine( QPainter *p, const QPoint &p1, const QPoint &p2, const QColorGroup &g, bool sunken, int lineWidth, int midLineWidth )
670*/
671
672void qDrawShadeLine( QPainter *p, const QPoint &p1, const QPoint &p2,
673 const QColorGroup &g, bool sunken,
674 int lineWidth, int midLineWidth )
675{
676 qDrawShadeLine( p, p1.x(), p1.y(), p2.x(), p2.y(), g, sunken,
677 lineWidth, midLineWidth );
678}
679
680/*!
681 \overload void qDrawShadeRect( QPainter *p, const QRect &r, const QColorGroup &g, bool sunken, int lineWidth, int midLineWidth, const QBrush *fill )
682*/
683
684void qDrawShadeRect( QPainter *p, const QRect &r,
685 const QColorGroup &g, bool sunken,
686 int lineWidth, int midLineWidth,
687 const QBrush *fill )
688{
689 qDrawShadeRect( p, r.x(), r.y(), r.width(), r.height(), g, sunken,
690 lineWidth, midLineWidth, fill );
691}
692
693/*!
694 \overload void qDrawShadePanel( QPainter *p, const QRect &r, const QColorGroup &g, bool sunken, int lineWidth, const QBrush *fill )
695*/
696
697void qDrawShadePanel( QPainter *p, const QRect &r,
698 const QColorGroup &g, bool sunken,
699 int lineWidth, const QBrush *fill )
700{
701 qDrawShadePanel( p, r.x(), r.y(), r.width(), r.height(), g, sunken,
702 lineWidth, fill );
703}
704
705/*!
706 \overload void qDrawWinButton( QPainter *p, const QRect &r, const QColorGroup &g, bool sunken, const QBrush *fill )
707*/
708
709void qDrawWinButton( QPainter *p, const QRect &r,
710 const QColorGroup &g, bool sunken,
711 const QBrush *fill )
712{
713 qDrawWinButton( p, r.x(), r.y(), r.width(), r.height(), g, sunken, fill );
714}
715
716/*!
717 \overload void qDrawWinPanel( QPainter *p, const QRect &r, const QColorGroup &g, bool sunken, const QBrush *fill )
718*/
719
720void qDrawWinPanel( QPainter *p, const QRect &r,
721 const QColorGroup &g, bool sunken,
722 const QBrush *fill )
723{
724 qDrawWinPanel( p, r.x(), r.y(), r.width(), r.height(), g, sunken, fill );
725}
726
727/*!
728 \overload void qDrawPlainRect( QPainter *p, const QRect &r, const QColor &c, int lineWidth, const QBrush *fill )
729*/
730
731void qDrawPlainRect( QPainter *p, const QRect &r, const QColor &c,
732 int lineWidth, const QBrush *fill )
733{
734 qDrawPlainRect( p, r.x(), r.y(), r.width(), r.height(), c,
735 lineWidth, fill );
736}
737
738
739static void qDrawWinArrow( QPainter *p, Qt::ArrowType type, bool down,
740 int x, int y, int w, int h,
741 const QColorGroup &g, bool enabled )
742{
743 QPointArray a; // arrow polygon
744 switch ( type ) {
745 case Qt::UpArrow:
746 a.setPoints( 7, -3,1, 3,1, -2,0, 2,0, -1,-1, 1,-1, 0,-2 );
747 break;
748 case Qt::DownArrow:
749 a.setPoints( 7, -3,-1, 3,-1, -2,0, 2,0, -1,1, 1,1, 0,2 );
750 break;
751 case Qt::LeftArrow:
752 a.setPoints( 7, 1,-3, 1,3, 0,-2, 0,2, -1,-1, -1,1, -2,0 );
753 break;
754 case Qt::RightArrow:
755 a.setPoints( 7, -1,-3, -1,3, 0,-2, 0,2, 1,-1, 1,1, 2,0 );
756 break;
757 }
758 if ( a.isNull() )
759 return;
760
761 if ( down ) {
762 x++;
763 y++;
764 }
765
766 QPen savePen = p->pen(); // save current pen
767 if (down)
768 p->setBrushOrigin(p->brushOrigin() + QPoint(1,1));
769 p->fillRect( x, y, w, h, g.brush( QColorGroup::Button ) );
770 if (down)
771 p->setBrushOrigin(p->brushOrigin() - QPoint(1,1));
772 if ( enabled ) {
773 a.translate( x+w/2, y+h/2 );
774 p->setPen( g.foreground() );
775 p->drawLineSegments( a, 0, 3 ); // draw arrow
776 p->drawPoint( a[6] );
777 } else {
778 a.translate( x+w/2+1, y+h/2+1 );
779 p->setPen( g.light() );
780 p->drawLineSegments( a, 0, 3 ); // draw arrow
781 p->drawPoint( a[6] );
782 a.translate( -1, -1 );
783 p->setPen( g.mid() );
784 p->drawLineSegments( a, 0, 3 ); // draw arrow
785 p->drawPoint( a[6] );
786 }
787 p->setPen( savePen ); // restore pen
788}
789
790
791#if defined(Q_CC_MSVC)
792#pragma warning(disable: 4244)
793#endif
794
795#ifndef QT_NO_STYLE_MOTIF
796// motif arrows look the same whether they are used or not
797// is this correct?
798static void qDrawMotifArrow( QPainter *p, Qt::ArrowType type, bool down,
799 int x, int y, int w, int h,
800 const QColorGroup &g, bool )
801{
802 QPointArray bFill; // fill polygon
803 QPointArray bTop; // top shadow.
804 QPointArray bBot; // bottom shadow.
805 QPointArray bLeft; // left shadow.
806#ifndef QT_NO_TRANSFORMATIONS
807 QWMatrix matrix; // xform matrix
808#endif
809 bool vertical = type == Qt::UpArrow || type == Qt::DownArrow;
810 bool horizontal = !vertical;
811 int dim = w < h ? w : h;
812 int colspec = 0x0000; // color specification array
813
814 if ( dim < 2 ) // too small arrow
815 return;
816
817 if ( dim > 3 ) {
818 if ( dim > 6 )
819 bFill.resize( dim & 1 ? 3 : 4 );
820 bTop.resize( (dim/2)*2 );
821 bBot.resize( dim & 1 ? dim + 1 : dim );
822 bLeft.resize( dim > 4 ? 4 : 2 );
823 bLeft.putPoints( 0, 2, 0,0, 0,dim-1 );
824 if ( dim > 4 )
825 bLeft.putPoints( 2, 2, 1,2, 1,dim-3 );
826 bTop.putPoints( 0, 4, 1,0, 1,1, 2,1, 3,1 );
827 bBot.putPoints( 0, 4, 1,dim-1, 1,dim-2, 2,dim-2, 3,dim-2 );
828
829 for( int i=0; i<dim/2-2 ; i++ ) {
830 bTop.putPoints( i*2+4, 2, 2+i*2,2+i, 5+i*2, 2+i );
831 bBot.putPoints( i*2+4, 2, 2+i*2,dim-3-i, 5+i*2,dim-3-i );
832 }
833 if ( dim & 1 ) // odd number size: extra line
834 bBot.putPoints( dim-1, 2, dim-3,dim/2, dim-1,dim/2 );
835 if ( dim > 6 ) { // dim>6: must fill interior
836 bFill.putPoints( 0, 2, 1,dim-3, 1,2 );
837 if ( dim & 1 ) // if size is an odd number
838 bFill.setPoint( 2, dim - 3, dim / 2 );
839 else
840 bFill.putPoints( 2, 2, dim-4,dim/2-1, dim-4,dim/2 );
841 }
842 }
843 else {
844 if ( dim == 3 ) { // 3x3 arrow pattern
845 bLeft.setPoints( 4, 0,0, 0,2, 1,1, 1,1 );
846 bTop .setPoints( 2, 1,0, 1,0 );
847 bBot .setPoints( 2, 1,2, 2,1 );
848 }
849 else { // 2x2 arrow pattern
850 bLeft.setPoints( 2, 0,0, 0,1 );
851 bTop .setPoints( 2, 1,0, 1,0 );
852 bBot .setPoints( 2, 1,1, 1,1 );
853 }
854 }
855
856 if ( type == Qt::UpArrow || type == Qt::LeftArrow ) {
857#ifndef QT_NO_TRANSFORMATIONS // #### fix me!
858 matrix.translate( x, y );
859 if ( vertical ) {
860 matrix.translate( 0, h - 1 );
861 matrix.rotate( -90 );
862 } else {
863 matrix.translate( w - 1, h - 1 );
864 matrix.rotate( 180 );
865 }
866#endif
867 if ( down )
868 colspec = horizontal ? 0x2334 : 0x2343;
869 else
870 colspec = horizontal ? 0x1443 : 0x1434;
871 }
872 else if ( type == Qt::DownArrow || type == Qt::RightArrow ) {
873#ifndef QT_NO_TRANSFORMATIONS // #### fix me!
874 matrix.translate( x, y );
875 if ( vertical ) {
876 matrix.translate( w-1, 0 );
877 matrix.rotate( 90 );
878 }
879#endif
880 if ( down )
881 colspec = horizontal ? 0x2443 : 0x2434;
882 else
883 colspec = horizontal ? 0x1334 : 0x1343;
884 }
885
886 QColor *cols[5];
887 cols[0] = 0;
888 cols[1] = (QColor *)&g.button();
889 cols[2] = (QColor *)&g.mid();
890 cols[3] = (QColor *)&g.light();
891 cols[4] = (QColor *)&g.dark();
892#define CMID *cols[ (colspec>>12) & 0xf ]
893#define CLEFT *cols[ (colspec>>8) & 0xf ]
894#define CTOP *cols[ (colspec>>4) & 0xf ]
895#define CBOT *cols[ colspec & 0xf ]
896
897 QPen savePen = p->pen(); // save current pen
898 QBrush saveBrush = p->brush(); // save current brush
899#ifndef QT_NO_TRANSFORMATIONS
900 QWMatrix wxm = p->worldMatrix();
901#endif
902 QPen pen( Qt::NoPen );
903 const QBrush &brush = g.brush( QColorGroup::Button );
904
905 p->setPen( pen );
906 p->setBrush( brush );
907#ifndef QT_NO_TRANSFORMATIONS
908 p->setWorldMatrix( matrix, TRUE ); // set transformation matrix
909#endif
910 p->drawPolygon( bFill ); // fill arrow
911 p->setBrush( Qt::NoBrush ); // don't fill
912
913 p->setPen( CLEFT );
914 p->drawLineSegments( bLeft );
915 p->setPen( CTOP );
916 p->drawLineSegments( bTop );
917 p->setPen( CBOT );
918 p->drawLineSegments( bBot );
919
920#ifndef QT_NO_TRANSFORMATIONS
921 p->setWorldMatrix( wxm );
922#endif
923 p->setBrush( saveBrush ); // restore brush
924 p->setPen( savePen ); // restore pen
925
926#undef CMID
927#undef CLEFT
928#undef CTOP
929#undef CBOT
930}
931#endif
932
933void qDrawArrow( QPainter *p, Qt::ArrowType type, Qt::GUIStyle style, bool down,
934 int x, int y, int w, int h,
935 const QColorGroup &g, bool enabled )
936{
937 switch ( style ) {
938 case Qt::WindowsStyle:
939 qDrawWinArrow( p, type, down, x, y, w, h, g, enabled );
940 break;
941#ifndef QT_NO_STYLE_MOTIF
942 case Qt::MotifStyle:
943 qDrawMotifArrow( p, type, down, x, y, w, h, g, enabled );
944 break;
945#endif
946 default:
947#if defined(QT_CHECK_RANGE)
948 qWarning( "qDrawArrow: Requested GUI style not supported" );
949#else
950 ;
951#endif
952 }
953}
954#endif //QT_NO_DRAWUTIL
Note: See TracBrowser for help on using the repository browser.