source: trunk/src/gui/painting/qdrawutil.cpp@ 508

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

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

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