source: trunk/src/styles/qwarp4style.cpp@ 181

Last change on this file since 181 was 181, checked in by dmik, 17 years ago

styles/Warp4: Correctly remove tab widget's page headers and the fat raised tab frame when switching styles on the fly. Don't draw decorative page borders when QT_PM_NO_TABWIDGET_HEADERS is set (and therefore no bended corner is drawn).

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id
File size: 146.0 KB
Line 
1/****************************************************************************
2** $Id: qwarp4style.cpp 181 2008-03-03 15:16:32Z dmik $
3**
4** Implementation of OS/2 Warp-like style class
5**
6** Copyright (C) 1992-2003 Trolltech AS. All rights reserved.
7** Copyright (C) 2007-2007 netlabs.org. OS/2 Development.
8**
9** This file is part of the widgets module of the Qt GUI Toolkit.
10**
11** This file may be distributed under the terms of the Q Public License
12** as defined by Trolltech AS of Norway and appearing in the file
13** LICENSE.QPL included in the packaging of this file.
14**
15** This file may be distributed and/or modified under the terms of the
16** GNU General Public License version 2 as published by the Free Software
17** Foundation and appearing in the file LICENSE.GPL included in the
18** packaging of this file.
19**
20** Licensees holding valid Qt Enterprise Edition or Qt Professional Edition
21** licenses may use this file in accordance with the Qt Commercial License
22** Agreement provided with the Software.
23**
24** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
25** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
26**
27** See http://www.trolltech.com/pricing.html or email sales@trolltech.com for
28** information about Qt Commercial License Agreements.
29** See http://www.trolltech.com/qpl/ for QPL licensing information.
30** See http://www.trolltech.com/gpl/ for GPL licensing information.
31**
32** Contact info@trolltech.com if any conditions of this licensing are
33** not clear to you.
34**
35**********************************************************************/
36
37#if !defined(QT_NO_STYLE_WARP4) || defined(QT_PLUGIN)
38
39#include <limits.h>
40#include "qapplication.h"
41#include "qpainter.h"
42#include "qdrawutil.h" // for now
43#include "qlabel.h"
44#include "qimage.h"
45#include "qcombobox.h"
46#include "qlistbox.h"
47#include "qrangecontrol.h"
48#include "qscrollbar.h"
49#include "qslider.h"
50#include "qtabwidget.h"
51#include "qlistview.h"
52#include "qbitmap.h"
53#include "qcleanuphandler.h"
54#include "qdockwindow.h"
55#include "qobjectlist.h"
56#include "qmenubar.h"
57#include "qprogressbar.h"
58#include "qptrlist.h"
59#include "qvaluelist.h"
60#include "qmainwindow.h"
61#include "qdockarea.h"
62
63#include "qpixmap.h"
64#include "qmap.h"
65#include "qtabbar.h"
66#include "qwidget.h"
67#include "qwidgetstack.h"
68#include "qtoolbutton.h"
69#include "qpushbutton.h"
70#include "qpopupmenu.h"
71#include "qevent.h"
72
73#include "qwarp4style.h"
74
75#ifndef QT_NO_ICONSET
76#include "qiconset.h"
77#endif
78
79// defined in qapplication_pm.cpp
80extern QRgb qt_sysclr2qrgb(LONG sysClr);
81
82/*----------------------------------------------------------------------*\
83 * Internal pixmaps
84\*----------------------------------------------------------------------*/
85
86// Note: All these colors only serve as placeholders; they are being replaced
87// by system colors in the QWarpPixmap constructor. After that, they are being
88// cached as pixmaps (like the system bitmaps and icons)
89
90static char* arrowup_xpm[] =
91{
92/* width height ncolors chars_per_pixel */
93"12 12 4 1",
94/* colors */
95" c #0000FF", // transparent
96"! c #808080", // dark grey
97"# c #FFFFFF", // light
98"$ c #000000", // shadow
99/* pixels */
100" ",
101" ",
102" ",
103" ## ",
104" #!!# ",
105" #!!!!# ",
106" #!!!!!!# ",
107" #!!!!!!!!# ",
108"#$$$$$$$$$$#",
109" ",
110" ",
111" "
112};
113
114static char* arrowdown_xpm[] =
115{
116/* width height ncolors chars_per_pixel */
117"12 12 4 1",
118/* colors */
119" c #0000FF", // transparent
120"! c #808080", // dark grey
121"# c #FFFFFF", // light
122"$ c #000000", // shadow
123/* pixels */
124" ",
125" ",
126" ",
127"#$$$$$$$$$$#",
128" #!!!!!!!!# ",
129" #!!!!!!# ",
130" #!!!!# ",
131" #!!# ",
132" ## ",
133" ",
134" ",
135" "
136};
137
138static char* arrowright_xpm[] =
139{
140/* width height ncolors chars_per_pixel */
141"12 12 4 1",
142/* colors */
143" c #0000FF", // transparent
144"! c #808080", // dark grey
145"# c #FFFFFF", // light
146"$ c #000000", // shadow
147/* pixels */
148" # ",
149" $# ",
150" $!# ",
151" $!!# ",
152" $!!!# ",
153" $!!!!# ",
154" $!!!!# ",
155" $!!!# ",
156" $!!# ",
157" $!# ",
158" $# ",
159" # "
160};
161
162static char* arrowleft_xpm[] =
163{
164/* width height ncolors chars_per_pixel */
165"12 12 4 1",
166/* colors */
167" c #0000FF", // transparent
168"! c #808080", // dark grey
169"# c #FFFFFF", // light
170"$ c #000000", // shadow
171/* pixels */
172" # ",
173" #$ ",
174" #!$ ",
175" #!!$ ",
176" #!!!$ ",
177" #!!!!$ ",
178" #!!!!$ ",
179" #!!!$ ",
180" #!!$ ",
181" #!$ ",
182" #$ ",
183" # "
184};
185
186static char* checkmark_xpm[] =
187{
188/* width height ncolors chars_per_pixel */
189"8 8 4 1",
190/* colors */
191" c #0000FF", // transparent
192"! c #808080", // dark grey
193"# c #FFFFFF", // light
194"$ c #000000", // shadow
195/* pixels */
196" #! ",
197" ##!! ",
198" ###!!! ",
199"####!!!!",
200"!!!!$$$$",
201" !!!$$$ ",
202" !!$$ ",
203" !$ "
204};
205
206static char* tabhdrplus_xpm[] =
207{
208/* width height ncolors chars_per_pixel */
209"7 7 4 1",
210/* colors */
211" c #0000FF", // transparent
212"! c #C0C0C0", // button (lignt grey)
213"# c #808080", // dark grey
214"- c #FFFFFF", // light
215/* pixels */
216" --- ",
217" -!# ",
218"---!#--",
219"-!!!!!#",
220"-##!###",
221" -!# ",
222" -## "
223};
224
225static char* tabhdrminus_xpm[] =
226{
227/* width height ncolors chars_per_pixel */
228"7 7 4 1",
229/* colors */
230" c #0000FF", // transparent
231"! c #C0C0C0", // button (lignt grey)
232"# c #808080", // dark grey
233"- c #FFFFFF", // light
234/* pixels */
235" ",
236" ",
237"-------",
238"-!!!!!#",
239"#######",
240" ",
241" "
242};
243
244#ifndef QT_NO_ICONSET
245
246class Q_EXPORT QIconFactoryPM: public QIconFactory
247{
248public:
249 virtual QPixmap* createPixmap(QIconSet const& iconSet, QIconSet::Size size,
250 QIconSet::Mode mode, QIconSet::State state);
251};
252
253QPixmap* QIconFactoryPM::createPixmap(QIconSet const& iconSet, QIconSet::Size size,
254 QIconSet::Mode mode, QIconSet::State state)
255{
256 // we are only providing a way to "disable" icons
257 if(QIconSet::Disabled != mode)
258 return 0;
259
260 // generate "normal" pixmap, and return 0 if this fails
261 QPixmap normPixmap = iconSet.pixmap(size, QIconSet::Normal, state);
262 if(normPixmap.isNull())
263 return 0;
264
265 // For PM/Warp style, "disabling" a pixmap means overimpose a raster
266 // of transparency.
267 // Note: if possible we realize this transparency raster with a mask;
268 // only if the pixmap comes with an alpha channel already, we are making
269 // use of that one
270
271 QBitmap mask;
272 QImage alphaImg;
273 if(normPixmap.mask())
274 {
275 // if a mask exists, use it
276 mask = *normPixmap.mask();
277 }
278 else if(normPixmap.hasAlphaChannel())
279 {
280 // if an alpha channel exists, use it
281 alphaImg = normPixmap.convertToImage();
282 }
283 else
284 {
285 // if none exists, generate a mask and initialize it with "fully opaque)
286 mask = QBitmap(normPixmap.size());
287 mask.fill(Qt::color1);
288 }
289
290 QPixmap* pixmap = 0;
291 int r, c;
292
293 // alpha channel case
294 if(mask.isNull())
295 {
296 if(32 != alphaImg.depth())
297 alphaImg = alphaImg.convertDepth(32);
298 for(r = 0; c < alphaImg.height(); ++r)
299 {
300 for(c = 0; c < alphaImg.width(); ++c);
301 {
302 if(0 ==((r + c) % 2))
303 alphaImg.setPixel(c, r, 0);
304 }
305 }
306 pixmap = new QPixmap(alphaImg);
307 }
308
309 // mask case
310 else
311 {
312 QImage img = mask.convertToImage();
313 for(r = 0; r < img.height(); ++r)
314 {
315 int pix;
316 for(c = 0; c < img.width(); ++c)
317 {
318 pix = img.pixelIndex(c, r);
319 pix = ((0 == pix) || (0 == ((r + c) % 2))) ? 0 : 1;
320 img.setPixel(c, r, pix);
321 }
322 }
323 mask.convertFromImage(img);
324 pixmap = new QPixmap(normPixmap);
325 pixmap->setMask(mask);
326 }
327
328 return pixmap;
329}
330
331#endif // ifndef QT_NO_ICONSET
332
333/*! \internal
334 Helper function to make the "background" of an image transparent.
335 this is done heuristically by assuming that if all corners have the
336 same color, and if that color happens to be also the same as the
337 system dialog background color, then this color is actually intended
338 to be "transparent", and it is changed to that, starting at the
339 four corners and as far as this color is continuously there (flood fill).
340*/
341static void qFloodFill(QImage& im, int x, int y, QRgb color)
342{
343 // note: this is a primitive, completely un-optimized flood fill,
344 // but since 1) only rather small images are treated and 2) they are
345 // even cached, the overhead does not seem to be excessive!
346
347 // get current color and change to new color
348 QRgb currentCol = im.pixel(x, y);
349 im.setPixel(x, y, color);
350
351 // recursive calls in all four directions, if color is right
352 if((x > 0) && (im.pixel(x - 1, y) == currentCol))
353 qFloodFill(im, x - 1, y, color);
354 if((x < (im.width() - 1)) && (im.pixel(x + 1, y) == currentCol))
355 qFloodFill(im, x + 1, y, color);
356 if((y > 0) && (im.pixel(x, y - 1) == currentCol))
357 qFloodFill(im, x, y - 1, color);
358 if((y < (im.height() - 1)) && (im.pixel(x, y + 1) == currentCol))
359 qFloodFill(im, x, y + 1, color);
360}
361
362static void qImageBackgroundTransparent(QImage& im)
363{
364 // if colors in all four corners are equal and equal to the system
365 // standard dialog background color, we assume this color is meant to
366 // be the "background" and change that to "transparent"
367 // this makes radiobuttons look ok on other than a standard dialog
368 // background, like inside a listview control
369 int xm = im.width() - 1,
370 ym = im.height() - 1;
371 static QRgb dlgBackCol = qt_sysclr2qrgb(SYSCLR_DIALOGBACKGROUND) | 0xff000000;
372 QRgb cornerCol = im.pixel(0, 0);
373 if((cornerCol == dlgBackCol) &&
374 (cornerCol == im.pixel(0, ym)) &&
375 (cornerCol == im.pixel(xm, 0)) &&
376 (cornerCol == im.pixel(xm, ym)))
377 {
378 im.setAlphaBuffer(true);
379 qFloodFill(im, 0, 0, (QRgb)0);
380 qFloodFill(im, 0, ym, (QRgb)0);
381 qFloodFill(im, xm, 0, (QRgb)0);
382 qFloodFill(im, xm, ym, (QRgb)0);
383 }
384}
385
386/*----------------------------------------------------------------------*\
387 * QWarpPixmap class
388 * Describes a pixmap that is being read from the PM system
389\*----------------------------------------------------------------------*/
390
391/*! \internal
392 Describes a pixmap that is being read from the PM system.
393*/
394class QWarpPixmap: public QPixmap
395{
396public:
397 typedef enum
398 {
399 bmp,
400 ico,
401 internal
402 }
403 QWarpPixmapType;
404
405 typedef enum
406 {
407 arrowup,
408 arrowdown,
409 arrowleft,
410 arrowright,
411 tabheadertr,
412 tabheaderbr,
413 tabheadertl,
414 tabheaderbl,
415 tabhdrplus,
416 tabhdrminus,
417 chkboxnormal,
418 chkboxsunken,
419 chkboxchecked,
420 chkboxcheckedsunken,
421 chkboxtri,
422 chkboxtrisunken,
423 radbutnormal,
424 radbutsunken,
425 radbutchecked,
426 radbutcheckedsunken,
427 checkmark
428 }
429 QWarpInternalPixmap;
430
431 QWarpPixmap(unsigned long id, QWarpPixmapType type, long sz = -1);
432
433 bool isOk() const { return ok; }
434
435private:
436 bool ok;
437 static QMap<QString, QPixmap>* tabHeaderCorners;
438
439 bool indicatorPixmap(bool isCheckbox, uint status, bool sunken);
440 bool drawTabHeaderTopRight(int sz);
441 bool drawTabHeaderBottomRight(int sz);
442 bool drawTabHeaderTopLeft(int sz);
443 bool drawTabHeaderBottomLeft(int sz);
444};
445
446QMap<QString, QPixmap>* QWarpPixmap::tabHeaderCorners = 0;
447
448QWarpPixmap::QWarpPixmap(unsigned long id, QWarpPixmapType type, long sz)
449 : ok(false)
450{
451 QImage img;
452
453 if(internal == type)
454 {
455 switch(id)
456 {
457 case arrowleft:
458 img = QImage(arrowleft_xpm);
459 break;
460 case arrowright:
461 img = QImage(arrowright_xpm);
462 break;
463 case arrowup:
464 img = QImage(arrowup_xpm);
465 break;
466 case arrowdown:
467 img = QImage(arrowdown_xpm);
468 break;
469 case tabheadertr:
470 ok = drawTabHeaderTopRight(sz);
471 break;
472 case tabheaderbr:
473 ok = drawTabHeaderBottomRight(sz);
474 break;
475 case tabheadertl:
476 ok = drawTabHeaderTopLeft(sz);
477 break;
478 case tabheaderbl:
479 ok = drawTabHeaderBottomLeft(sz);
480 break;
481 case tabhdrplus:
482 img = QImage(tabhdrplus_xpm);
483 break;
484 case tabhdrminus:
485 img = QImage(tabhdrminus_xpm);
486 break;
487 case chkboxnormal:
488 ok = indicatorPixmap(true, 0, false);
489 break;
490 case chkboxsunken:
491 ok = indicatorPixmap(true, 0, true);
492 break;
493 case chkboxchecked:
494 ok = indicatorPixmap(true, 1, false);
495 break;
496 case chkboxcheckedsunken:
497 ok = indicatorPixmap(true, 1, true);
498 break;
499 case chkboxtri:
500 ok = indicatorPixmap(true, 2, false);
501 break;
502 case chkboxtrisunken:
503 ok = indicatorPixmap(true, 2, true);
504 break;
505 case radbutnormal:
506 ok = indicatorPixmap(false, 0, false);
507 break;
508 case radbutsunken:
509 ok = indicatorPixmap(false, 0, true);
510 break;
511 case radbutchecked:
512 ok = indicatorPixmap(false, 1, false);
513 break;
514 case radbutcheckedsunken:
515 ok = indicatorPixmap(false, 1, true);
516 break;
517 case checkmark:
518 default:
519 img = QImage(checkmark_xpm);
520 break;
521 }
522
523 img.setAlphaBuffer(true);
524
525 QColorGroup const& cg = QApplication::palette().active();
526 int col;
527 for(col = 0; col < img.numColors(); ++col)
528 {
529 switch(img.color(col))
530 {
531 case 0xff0000ff: // transparent
532 img.setColor(col, QRgb(0x00000000));
533 break;
534 case 0xffc0c0c0: // button (light grey)
535 img.setColor(col, QRgb(cg.button().rgb() | 0xff000000));
536 break;
537 case 0xff808080: // dark grey
538 img.setColor(col, QRgb(cg.dark().rgb() | 0xff000000));
539 break;
540 case 0xffffffff: // light
541 img.setColor(col, QRgb(cg.light().rgb() | 0xff000000));
542 break;
543 case 0xff000000: // shadow
544 img.setColor(col, QRgb(cg.shadow().rgb() | 0xff000000));
545 break;
546 }
547 }
548 }
549
550 else
551 {
552 HBITMAP hbits = NULLHANDLE,
553 hmask = NULLHANDLE;
554 bool color = true;
555
556 switch(type)
557 {
558 case bmp:
559 {
560 hbits = WinGetSysBitmap(HWND_DESKTOP, id);
561 break;
562 }
563
564 default: // ico
565 {
566 HPOINTER ptr = WinQuerySysPointer(HWND_DESKTOP, id, FALSE);
567 if(NULLHANDLE != ptr)
568 {
569 POINTERINFO ptrInfo;
570 WinQueryPointerInfo(ptr, (PPOINTERINFO)&ptrInfo);
571 hmask = ptrInfo.hbmPointer;
572 color = NULLHANDLE != ptrInfo.hbmColor;
573 if(color)
574 hbits = ptrInfo.hbmColor;
575 else
576 hbits = ptrInfo.hbmPointer;
577 }
578 break;
579 }
580 }
581
582 if(NULLHANDLE == hbits)
583 return;
584
585 BITMAPINFOHEADER2 bmpHdr;
586 ::memset(&bmpHdr, 0, sizeof(bmpHdr));
587 bmpHdr.cbFix = sizeof(bmpHdr);
588 GpiQueryBitmapInfoHeader(hbits, (PBITMAPINFOHEADER2)&bmpHdr);
589
590 BITMAPINFOHEADER2 maskHdr;
591 if(NULLHANDLE != hmask)
592 {
593 ::memset(&maskHdr, 0, sizeof(maskHdr));
594 maskHdr.cbFix = sizeof(maskHdr);
595 GpiQueryBitmapInfoHeader(hmask, (PBITMAPINFOHEADER2)&maskHdr);
596 }
597
598 HAB hab = WinQueryAnchorBlock(HWND_DESKTOP);
599 HDC hdc = DevOpenDC(hab, OD_MEMORY, "*", 0, NULL, NULLHANDLE);
600 if(0 == hdc)
601 return;
602
603 SIZEL size;
604 size.cx = bmpHdr.cx;
605 size.cy = bmpHdr.cy;
606 HPS hps = GpiCreatePS(hab, hdc, (PSIZEL)&size,
607 PU_PELS | GPIF_LONG | GPIT_NORMAL | GPIA_ASSOC);
608 if(0 == hps)
609 return;
610
611 if((ico == type) && !color)
612 size.cy /= 2;
613 img = QImage(size.cx, size.cy, 32);
614
615 unsigned long bmpInfoSize = sizeof(BITMAPINFO2) + 255 * sizeof(RGB2);
616 BITMAPINFO2* bmpInfo = (BITMAPINFO2*)new BYTE[bmpInfoSize];
617 int lBufSize = 4 * size.cx * size.cy;
618
619 PBYTE mBuf = 0;
620 if(NULLHANDLE != hmask)
621 {
622 GpiSetBitmap(hps, hmask);
623 img.setAlphaBuffer(true);
624
625 ::memset(bmpInfo, 0, bmpInfoSize);
626 ::memcpy(bmpInfo, &maskHdr, sizeof(BITMAPINFOHEADER2));
627 bmpInfo->cBitCount = 32; // note: this avoids padding at row ends!
628 bmpInfo->ulCompression = BCA_UNCOMP;
629
630 mBuf = new BYTE[lBufSize];
631 ::memset(mBuf, 0, lBufSize);
632
633 if(size.cy != GpiQueryBitmapBits(hps, size.cy, size.cy, mBuf, bmpInfo))
634 {
635 delete[] mBuf;
636 delete[] (PBYTE)bmpInfo;
637 return;
638 }
639 }
640
641 GpiSetBitmap(hps, hbits);
642
643 ::memset(bmpInfo, 0, bmpInfoSize);
644 ::memcpy(bmpInfo, &bmpHdr, sizeof(BITMAPINFOHEADER2));
645 bmpInfo->cBitCount = 32;
646 bmpInfo->ulCompression = BCA_UNCOMP;
647
648 PBYTE lBuf = new BYTE[lBufSize];
649 ::memset(lBuf, 0, lBufSize);
650
651 if(size.cy != GpiQueryBitmapBits(hps, 0, size.cy, lBuf, bmpInfo))
652 {
653 delete[] lBuf;
654 delete[] mBuf;
655 delete[] (PBYTE)bmpInfo;
656 return;
657 }
658
659 int r, c;
660 uint col;
661 for(r = 0; r < size.cy; ++r)
662 {
663 for(c = 0; c < size.cx; ++c)
664 {
665 col = *((uint*)&lBuf[(r * size.cx + c) * 4]);
666 uint alpha = 255;
667 if(NULLHANDLE != hmask)
668 alpha -= (uint)(unsigned char)mBuf[(r * size.cx + c) * 4];
669 col |= 0x01000000 * alpha;
670 img.setPixel(c, size.cy - r - 1, col);
671 }
672 }
673
674 delete[] mBuf;
675 delete[] lBuf;
676 delete[] (PBYTE)bmpInfo;
677 GpiSetBitmap(hps, NULLHANDLE);
678 GpiDestroyPS(hps);
679 DevCloseDC(hdc);
680 }
681
682 if(!img.isNull())
683 {
684 // images that are to be made transparent from the corners, if
685 // standard dialog background is the color there
686 // note: there seems to be nothing like the STL set<> in Qt, which
687 // would be more appropriate for the purpose here!
688 static QValueList<int> tbl;
689 if(tbl.empty())
690 {
691 tbl.push_back(52);
692 tbl.push_back(54);
693 tbl.push_back(56);
694 tbl.push_back(SBMP_RESTOREBUTTON);
695 tbl.push_back(SBMP_MINBUTTON);
696 tbl.push_back(SBMP_MAXBUTTON);
697 }
698 if((bmp == type) && (tbl.end() != tbl.find(id)))
699 qImageBackgroundTransparent(img);
700
701 ok = convertFromImage(img);
702 }
703}
704
705bool QWarpPixmap::indicatorPixmap(bool isCheckbox, uint status, bool sunken)
706{
707 QImage ii = QWarpPixmap(SBMP_CHECKBOXES, QWarpPixmap::bmp).convertToImage();
708
709 int c = 0;
710 if(sunken)
711 c += 2;
712 if(0 < status)
713 ++c;
714 int r = (isCheckbox ? 0 : 1);
715 if(2 <= status)
716 r = 2;
717
718 unsigned long w = ii.width() / 4,
719 h = ii.height() / 3;
720 QRect rect(0, 0, w, h);
721 rect.moveBy(c * w, r * h);
722
723 // cut out the right sub-image and make "background" transparent
724 ii = ii.copy(rect);
725 qImageBackgroundTransparent(ii);
726
727 // convert to pixmap
728 convertFromImage(ii);
729
730 return true;
731}
732
733bool QWarpPixmap::drawTabHeaderTopRight(int sz)
734{
735 QColorGroup const& cg = QApplication::palette().active();
736
737 resize(sz, sz);
738 fill(cg.button());
739 QPainter p(this);
740
741 // short lines in the corners
742 p.setPen(cg.dark());
743 QPoint pt(0, 0);
744 QPoint pt2(2, 0);
745 p.drawLine(pt, pt2);
746 pt2 += QPoint(1, 1);
747 p.drawLine(pt2, pt += QPoint(5, 1));
748 pt2 = pt + QPoint(sz - 7, sz - 7);
749 p.drawLine(pt2 + QPoint(0, 1), pt2 + QPoint(0, 5));
750
751 // corner
752 p.drawLine(pt, QPoint(pt.x(), pt2.y()));
753 p.drawLine(pt2, QPoint(pt.x(), pt2.y()));
754
755 // corner shadow
756 p.drawLine(pt.x() + 5, pt2.y() + 2, pt2.x() - 1, pt2.y() + 2);
757 QPoint pd(pt.x() + 6, pt2.y() + 3);
758 while(pd.x() < pt2.x())
759 {
760 p.drawPoint(pd);
761 pd += QPoint(2, 0);
762 }
763 p.setPen(cg.shadow());
764 p.drawLine(pt.x() + 5, pt2.y() + 1, pt2.x() - 1, pt2.y() + 1);
765
766 // bend
767 p.drawLine(pt += QPoint(1, 1), pt2);
768 p.setPen(cg.dark());
769 p.drawLine(pt + QPoint(2, 1), pt2 += QPoint(0, -1));
770 p.drawLine(pt += QPoint(0, 1), pt2 += QPoint(-2, 0));
771 p.drawLine(pt += QPoint(0, 1), pt2 += QPoint(-1, 0));
772 p.setPen(cg.light());
773 p.drawLine(pt + QPoint(0, 3), pt2 + QPoint(-3, 0));
774
775 return true;
776}
777
778bool QWarpPixmap::drawTabHeaderBottomRight(int sz)
779{
780 QColorGroup const& cg = QApplication::palette().active();
781
782 resize(sz, sz);
783 fill(cg.button());
784 QPainter p(this);
785
786 // short lines in the corners
787 p.setPen(cg.dark());
788 QPoint pt(0, sz - 1);
789 QPoint pt2(2, sz - 1);
790 p.drawLine(pt, pt2);
791 pt2 += QPoint(1, -1);
792 p.drawLine(pt2, pt += QPoint(5, -1));
793 pt2 = pt + QPoint(sz - 7, -sz + 7);
794 p.drawLine(pt2 + QPoint(0, -1), pt2 + QPoint(0, -5));
795
796 // corner
797 p.drawLine(pt, QPoint(pt.x(), pt2.y()));
798 p.drawLine(pt2, QPoint(pt.x(), pt2.y()));
799
800 // bend
801 p.setPen(cg.shadow());
802 p.drawLine(pt += QPoint(1, -1), pt2);
803 p.drawLine(pt += QPoint(1, 1), pt2 += QPoint(0, 2));
804 p.setPen(cg.dark());
805 p.drawLine(pt += QPoint(1, 0), pt2 += QPoint(0, 1));
806 p.drawLine(pt += QPoint(-2, 0), pt2 += QPoint(0, -2));
807 p.drawLine(pt += QPoint(0, -2), pt2 += QPoint(-2, 0));
808 p.drawLine(pt += QPoint(0, -1), pt2 += QPoint(-1, 0));
809 QPoint pd(pt + QPoint(5, 1));
810 while(pd.x() < (pt2.x() + 2))
811 {
812 p.drawPoint(pd);
813 pd += QPoint(2, -2);
814 }
815 p.setPen(cg.light());
816 p.drawLine(pt + QPoint(0, -3), pt2 + QPoint(-3, 0));
817
818 return true;
819}
820
821bool QWarpPixmap::drawTabHeaderTopLeft(int sz)
822{
823 QColorGroup const& cg = QApplication::palette().active();
824
825 resize(sz, sz);
826 fill(cg.button());
827 QPainter p(this);
828
829 // short lines in the corners
830 p.setPen(cg.dark());
831 QPoint pt(sz - 1, 0);
832 QPoint pt2(sz - 3, 0);
833 p.drawLine(pt, pt2);
834 pt2 += QPoint(-1, 1);
835 p.drawLine(pt2, pt += QPoint(-5, 1));
836 pt2 = pt + QPoint(7 - sz, sz - 7);
837 p.drawLine(pt2 + QPoint(0, 1), pt2 + QPoint(0, 5));
838
839 // corner
840 p.drawLine(pt, QPoint(pt.x(), pt2.y()));
841 p.drawLine(pt2, QPoint(pt.x(), pt2.y()));
842
843 // corner shadow
844 p.drawLine(pt.x() + 2, pt2.y() + 2, pt2.x() + 5, pt2.y() + 2);
845 p.drawLine(pt.x() + 2, pt.y() + 5, pt.x() + 2, pt2.y() + 2);
846 QPoint pd(pt2.x() + 6, pt2.y() + 3);
847 while(pd.x() < (pt.x() + 3))
848 {
849 p.drawPoint(pd);
850 pd += QPoint(2, 0);
851 }
852 pd -= QPoint(1, 1);
853 while(pd.y() > (pt.y() + 5))
854 {
855 p.drawPoint(pd);
856 pd += QPoint(0, -2);
857 }
858 p.setPen(cg.shadow());
859 p.drawLine(pt.x() + 1, pt2.y() + 1, pt2.x() + 5, pt2.y() + 1);
860 p.drawLine(pt.x() + 1, pt.y() + 5, pt.x() + 1, pt2.y() + 1);
861
862 // bend
863 p.drawLine(pt += QPoint(-1, 1), pt2 += QPoint(1, -1));
864 p.setPen(cg.dark());
865 p.drawLine(pt += QPoint(0, 1), pt2 += QPoint(1, 0));
866 p.drawLine(pt += QPoint(0, 1), pt2 += QPoint(1, 0));
867 p.setPen(cg.light());
868 p.drawLine(pt + QPoint(0, 3), pt2 + QPoint(3, 0));
869
870 return true;
871}
872
873bool QWarpPixmap::drawTabHeaderBottomLeft(int sz)
874{
875 QColorGroup const& cg = QApplication::palette().active();
876
877 resize(sz, sz);
878 fill(cg.button());
879 QPainter p(this);
880
881 // short lines in the corners
882 p.setPen(cg.dark());
883 QPoint pt(sz - 1, sz - 1);
884 QPoint pt2(sz - 3, sz - 1);
885 p.drawLine(pt, pt2);
886 pt2 += QPoint(-1, -1);
887 p.drawLine(pt2, pt += QPoint(-5, -1));
888 pt2 = pt + QPoint(7 - sz, 7 - sz);
889 p.drawLine(pt2 + QPoint(0, -1), pt2 + QPoint(0, -5));
890
891 // corner
892 p.drawLine(pt, QPoint(pt.x(), pt2.y()));
893 p.drawLine(pt2, QPoint(pt.x(), pt2.y()));
894
895 // corner shadow
896 p.drawLine(pt.x() + 2, pt.y() - 1, pt.x() + 2, pt2.y() + 5);
897 QPoint pd(pt.x() + 3, pt.y() - 2);
898 while(pd.y() > (pt2.y() + 5))
899 {
900 p.drawPoint(pd);
901 pd += QPoint(0, -2);
902 }
903 p.setPen(cg.shadow());
904 p.drawLine(pt.x() + 1, pt.y() - 1, pt.x() + 1, pt2.y() + 5);
905
906 // bend
907 p.drawLine(pt += QPoint(-1, -1), pt2 += QPoint(1, 1));
908 p.setPen(cg.dark());
909 p.drawLine(pt += QPoint(0, 1), pt2 += QPoint(-1, 0));
910 p.drawLine(pt += QPoint(0, -2), pt2 += QPoint(2, 0));
911 p.drawLine(pt += QPoint(0, -1), pt2 += QPoint(1, 0));
912 p.setPen(cg.light());
913 p.drawLine(pt + QPoint(0, -3), pt2 + QPoint(3, 0));
914
915 return true;
916}
917
918/*----------------------------------------------------------------------*\
919 * QWarpSystemPixmaps class
920\*----------------------------------------------------------------------*/
921
922/*! \internal
923 Retrieve and buffer PM system pixmaps.
924*/
925class QWarpSystemPixmaps
926{
927public:
928 QWarpSystemPixmaps() {}
929 ~QWarpSystemPixmaps();
930 QPixmap const* getPixmap(unsigned long id, QWarpPixmap::QWarpPixmapType type,
931 long sz = -1);
932
933private:
934 QMap<QString, QWarpPixmap*> pmr;
935};
936
937QWarpSystemPixmaps::~QWarpSystemPixmaps()
938{
939 QMap<QString, QWarpPixmap*>::iterator it;
940 for(it = pmr.begin(); it != pmr.end(); ++it)
941 delete *it;
942}
943
944QPixmap const* QWarpSystemPixmaps::getPixmap(unsigned long id,
945 QWarpPixmap::QWarpPixmapType type,
946 long sz /*= -1*/)
947{
948 QWarpPixmap* pix = 0;
949
950 QString key = QString("%1.%2.%3")
951 .arg((unsigned long)type, 8, 16)
952 .arg(id, 8, 16)
953 .arg(sz, 8, 16)
954 .replace(' ', '0');
955
956 QMap<QString, QWarpPixmap*>::iterator pix_it = pmr.find(key);
957 if(pmr.end() != pix_it)
958 {
959 pix = *pix_it;
960 }
961 else
962 {
963 pix = new QWarpPixmap(id, type, sz);
964 if(pix->isOk())
965 {
966 pmr.insert(key, pix);
967 }
968 else
969 {
970 delete pix;
971 pix = 0;
972 }
973 }
974
975 return (QPixmap const*)pix;
976}
977
978static QWarpSystemPixmaps qWarpSystemPixmaps;
979
980/*----------------------------------------------------------------------*\
981 * functions for drawing PM frames and pushbuttons
982\*----------------------------------------------------------------------*/
983
984static
985void qDrawWarpDefFrame(QPainter* p, QRect const& rect,
986 QColorGroup const& cg, bool def = FALSE)
987{
988 QRect rr(rect);
989
990 // outer frame of button that shows "default" state, but is unchanged
991 // if "sunken"
992
993 if(def)
994 {
995 p->setPen(cg.shadow());
996 p->drawRect(rr);
997 }
998
999 else
1000 {
1001 p->setPen(cg.dark());
1002 p->drawLine(rr.left(), rr.top(), rr.right() - 1, rr.top());
1003 p->drawLine(rr.left(), rr.top(), rr.left(), rr.bottom() - 1);
1004 p->setPen(cg.light());
1005 p->drawLine(rr.left() + 1, rr.bottom(), rr.right(), rr.bottom());
1006 p->drawLine(rr.right(), rr.top() + 1, rr.right(), rr.bottom());
1007 }
1008}
1009
1010static
1011void qDrawWarpFilledRect(QPainter* p, QRect const& rect,
1012 QColor dark, QColor light, QBrush const* fill,
1013 unsigned long mult, bool sunken = FALSE)
1014{
1015 QRect rr(rect);
1016
1017 // inner frame of button that shows "sunken" state, but is
1018 // unchanged if "default"
1019
1020 unsigned long l;
1021 for(l = 0; l < mult; ++l)
1022 {
1023 p->setPen(sunken ? dark : light);
1024 p->drawLine(rr.left(), rr.top(), rr.right() - 1, rr.top());
1025 p->drawLine(rr.left(), rr.top(), rr.left(), rr.bottom());
1026 p->setPen(sunken ? light : dark);
1027 p->drawLine(rr.left() + 1, rr.bottom(), rr.right(), rr.bottom());
1028 p->drawLine(rr.right(), rr.top(), rr.right(), rr.bottom());
1029 rr.addCoords(1, 1, -1, -1);
1030 }
1031
1032 if(0 != fill)
1033 {
1034 p->fillRect(rr, *fill);
1035 }
1036}
1037
1038static
1039void qDrawWarpPanel(QPainter* p, QRect const& rect,
1040 QColorGroup const& cg, int sunkenState = 1,
1041 QBrush const* fill = 0)
1042 // sunkenState: -1 = sunken
1043 // 0 = flat
1044 // 1 = raised
1045{
1046 QRect rr(rect);
1047
1048 if(0 == sunkenState) // flat
1049 {
1050 rr.addCoords(1, 1, 0, 0);
1051 p->setPen(cg.light());
1052 p->drawRect(rr);
1053 rr.addCoords(-1, -1, -1, -1);
1054 p->setPen(cg.dark());
1055 p->drawRect(rr);
1056 }
1057
1058 else if(0 > sunkenState) // sunken
1059 {
1060 qDrawWarpFilledRect(p, rect, cg.dark(), cg.light(), 0, 1, true);
1061 rr.addCoords(1, 1, -1, -1);
1062 qDrawWarpFilledRect(p, rr, cg.shadow(), cg.button(), fill, 1, true);
1063 }
1064
1065 else // raised
1066 {
1067 qDrawWarpFilledRect(p, rect, cg.shadow(), cg.dark(), 0, 1, false);
1068 rr.addCoords(1, 1, -1, -1);
1069 qDrawWarpFilledRect(p, rr, cg.dark(), cg.light(), fill, 1, false);
1070 }
1071}
1072
1073static
1074void qDrawTabBar(QPainter* p, QRect const& r,
1075 QColorGroup const& cg, QColor color,
1076 bool selected, bool bottom)
1077{
1078 QPointArray ptDark, ptColor, ptLight;
1079
1080 if(selected)
1081 {
1082 ptDark.putPoints(0, 4,
1083 r.right() - 9, r.top(),
1084 r.right() - 5, r.top() + 4,
1085 r.right(), r.bottom() - 5,
1086 r.right() - 2, r.bottom() - 5);
1087 ptColor.putPoints(0, 11,
1088 r.left(), r.bottom() - 4,
1089 r.left() + 6, r.top() + 2,
1090 r.left() + 8, r.top() + 1,
1091 r.right() - 9, r.top() + 1,
1092 r.right() - 8, r.top() + 4,
1093 r.right() - 4, r.bottom() - 9,
1094 r.right() - 2, r.bottom() - 4,
1095 r.right() - 3, r.bottom() - 2,
1096 r.right() - 5, r.bottom(),
1097 r.left() + 4, r.bottom(),
1098 r.left() + 2, r.bottom() - 2);
1099 ptLight.putPoints(0, 4,
1100 r.left(), r.bottom() - 5,
1101 r.left() + 6, r.top() + 2,
1102 r.left() + 8, r.top(),
1103 r.right() - 10, r.top());
1104 }
1105 else
1106 {
1107 ptDark.putPoints(0, 5,
1108 r.right() - 9, r.top() + 1,
1109 r.right() - 5, r.top() + 5,
1110 r.right() - 1, r.bottom() - 7,
1111 r.right() - 1, r.bottom() - 5,
1112 r.right() - 3, r.bottom() - 5);
1113 ptColor.putPoints(0, 7,
1114 r.left() + 1, r.bottom() - 5,
1115 r.left() + 6, r.top() + 4,
1116 r.left() + 8, r.top() + 2,
1117 r.right() - 9, r.top() + 2,
1118 r.right() - 8, r.top() + 5,
1119 r.right() - 5, r.bottom() - 8,
1120 r.right() - 3, r.bottom() - 5);
1121 ptLight.putPoints(0, 8,
1122 r.right(), r.bottom() - 4,
1123 r.left(), r.bottom() - 4,
1124 r.left() + 1, r.bottom() - 4,
1125 r.left() + 1, r.bottom() - 7,
1126 r.left() + 5, r.top() + 5,
1127 r.left() + 6, r.top() + 3,
1128 r.left() + 8, r.top() + 1,
1129 r.right() - 10, r.top() + 1);
1130 }
1131
1132 if(bottom)
1133 {
1134 unsigned long n;
1135 for(n = 0; n < ptDark.size(); ++n)
1136 {
1137 QPoint pt = ptDark.point(n);
1138 pt.setY(r.bottom() - pt.y());
1139 ptDark.setPoint(n, pt);
1140 }
1141 for(n = 0; n < ptColor.size(); ++n)
1142 {
1143 QPoint pt = ptColor.point(n);
1144 pt.setY(r.bottom() - pt.y());
1145 ptColor.setPoint(n, pt);
1146 }
1147 for(n = 0; n < ptLight.size(); ++n)
1148 {
1149 QPoint pt = ptLight.point(n);
1150 pt.setY(r.bottom() - pt.y());
1151 ptLight.setPoint(n, pt);
1152 }
1153 }
1154
1155 p->setBrush(cg.dark());
1156 p->setPen(QPen::NoPen);
1157 p->drawPolygon(ptDark);
1158 p->setBrush(color);
1159 p->drawPolygon(ptColor);
1160 p->setPen(cg.light());
1161 p->drawPolyline(ptLight);
1162
1163 // if bottom orientation, some "light" lines need to be "dark"
1164 if(bottom)
1165 {
1166 p->setPen(cg.dark());
1167 p->drawLine(ptLight.point(ptLight.size() - 2), ptLight.point(ptLight.size() - 1));
1168 if(!selected)
1169 p->drawLine(ptLight.point(0), ptLight.point(1));
1170 }
1171}
1172
1173// Note: This function is being copied 1:1 from QCommonStyle.cpp, only
1174// because we need to rewrite the code for drawing slider tick marks in
1175// two colors instead of only one in the "common" style! But the makers
1176// of Qt decided not to expose it or export it otherwise...
1177
1178#ifndef QT_NO_RANGECONTROL
1179// I really need this and I don't want to expose it in QRangeControl..
1180static int qPositionFromValue(QRangeControl const* rc, int logical_val,
1181 int span)
1182{
1183 if(span <= 0 ||
1184 logical_val < rc->minValue() ||
1185 rc->maxValue() <= rc->minValue())
1186 return 0;
1187 if(logical_val > rc->maxValue())
1188 return span;
1189
1190 uint range = rc->maxValue() - rc->minValue();
1191 uint p = logical_val - rc->minValue();
1192
1193 if(range > (uint)INT_MAX/4096)
1194 {
1195 const int scale = 4096 * 2;
1196 return ((p / scale) * span) / (range / scale);
1197 // ### the above line is probably not 100% correct
1198 // ### but fixing it isn't worth the extreme pain...
1199 }
1200 else if(range > (uint)span)
1201 {
1202 return (2 * p * span + range) / (2 * range);
1203 }
1204 else
1205 {
1206 uint div = span / range;
1207 uint mod = span % range;
1208 return p * div + (2 * p * mod + range) / (2 * range);
1209 }
1210 // equiv. to (p * span) / range + 0.5
1211 // no overflow because of this implicit assumption:
1212 // span <= 4096
1213}
1214#endif // QT_NO_RANGECONTROL
1215
1216/*----------------------------------------------------------------------*\
1217 * QWarpTabPanelHeader class
1218\*----------------------------------------------------------------------*/
1219
1220/*! \internal
1221 Panel header class for tab widget display and functionality in PM style
1222 (the "new" Warp4 style with the colored tabs...).
1223
1224 This is the parent/child setup of a QTabWidget:
1225 class QTabWidget
1226 class <QWidgetStack>, name <tab pages> -> panel(s) area
1227 class <QWidgetStackPrivate::Invisible>, name <qt_invisible_widgetstack>
1228 class <...panel...>
1229 class <QLabel>, name <unnamed>
1230 ...
1231 class <QWidget>, name <tab base> -> tab bar base area
1232 class <QTabBar>, name <tab control> -> tab bar
1233 class <QToolButton>, name <qt_left_btn> -> left tab bar button
1234 class <QToolButton>, name <qt_right_btn> -> right tab bar button
1235 class <QWarpTabPanelHeader>, name <qt_tabwidget_warpheader>
1236 -> this is the panel header widget that is added below, covering the
1237 tab bar base area
1238*/
1239class QWarpTabPanelHeader: public QWidget
1240{
1241 Q_OBJECT
1242
1243#ifndef QT_PM_NO_TABWIDGET_HEADERS
1244
1245public:
1246
1247 QWarpTabPanelHeader (QTabWidget* tw);
1248
1249protected:
1250
1251 virtual bool eventFilter (QObject* watched, QEvent* ev);
1252 virtual void paintEvent (QPaintEvent* pev);
1253 virtual void mouseReleaseEvent (QMouseEvent* e);
1254
1255private:
1256
1257 bool _bottom;
1258
1259 QTabWidget *_tabWidget;
1260 QWidgetStack *_widgetStack;
1261 QTabBar *_tabBar;
1262 QWidget *_tabBarBase;
1263
1264 void setupLayout (QRect rect);
1265
1266 static void drawBentCornerTR (QPoint pt, int h, QPainter& p);
1267 static void drawBentCornerTL (QPoint pt, int h, QPainter& p);
1268 static void drawBentCornerBR (QPoint pt, int h, QPainter& p);
1269 static void drawBentCornerBL (QPoint pt, int h, QPainter& p);
1270 static void drawPlusButton (QPoint pt, QPainter& p);
1271 static void drawMinusButton (QPoint pt, QPainter& p);
1272
1273 int currentInx();
1274
1275#endif // QT_PM_NO_TABWIDGET_HEADERS
1276};
1277
1278#ifndef QT_PM_NO_TABWIDGET_HEADERS
1279
1280QWarpTabPanelHeader::QWarpTabPanelHeader (QTabWidget *tw)
1281 : QWidget (tw, "qt_warp_tabpanel_header")
1282 , _bottom (false), _tabWidget (0), _widgetStack (0)
1283 , _tabBar (0), _tabBarBase (0)
1284{
1285 Q_ASSERT (tw);
1286 if (tw == 0)
1287 return;
1288
1289 _bottom = tw->tabPosition() == QTabWidget::Bottom;
1290
1291 _tabWidget = tw;
1292
1293 _widgetStack = (QWidgetStack *) tw->child ("tab pages", "QWidgetStack", false);
1294 Q_ASSERT (_widgetStack != 0);
1295 if (_widgetStack == 0)
1296 return;
1297
1298 _tabBar = (QTabBar *) tw->child (NULL, "QTabBar", false);
1299 Q_ASSERT (_tabBar != 0);
1300 if (_tabBar == 0)
1301 return;
1302
1303 _tabBarBase = (QWidget *) tw->child ("tab base", "QWidget", false);
1304 Q_ASSERT (_tabBarBase != 0);
1305 if (_tabBarBase == 0)
1306 return;
1307
1308 setupLayout (_tabBarBase->geometry());
1309
1310 // catch resize/move events from the tab bar base widget in order to adapt
1311 // the size of this panel header widget accordingly
1312
1313 _tabBarBase->installEventFilter (this);
1314
1315 // make this visible: it displays the tab title
1316 show();
1317}
1318
1319bool QWarpTabPanelHeader::eventFilter (QObject *watched, QEvent *ev)
1320{
1321 if ((ev->type() != QEvent::Resize && ev->type() != QEvent::Move))
1322 return false;
1323
1324 // adapt the panel header widget position if the tab bar base widget is
1325 // being resized/moved
1326 setupLayout (((QWidget *) watched)->geometry());
1327
1328 return false;
1329}
1330
1331void QWarpTabPanelHeader::paintEvent(QPaintEvent* pev)
1332{
1333 if (_tabWidget == 0)
1334 return; // should never happen
1335
1336 // draw the caption of the page in the tab bar base area
1337
1338 QRect r (rect());
1339 QPainter p(this);
1340 bool reverse = QApplication::reverseLayout();
1341
1342 QFont f = _tabWidget->font();
1343 f.setBold (true);
1344 p.setFont (f);
1345 QRect fr = QFontMetrics(f).boundingRect (caption());
1346
1347 int x = (reverse ?
1348 r.right() - 5 - QFontMetrics(f).boundingRect(caption()).width() :
1349 r.left() + 5),
1350 y = (r.top() + r.bottom() + fr.height()) / 2 - 2;
1351
1352 QString cap = caption();
1353 cap.remove (cap.find ('&'), 1);
1354 p.drawText (x, y, cap);
1355
1356 QPoint pt1l, pt1r, pt2l, pt2r;
1357 int hh = r.height();
1358 if (_bottom)
1359 {
1360 pt1l = QPoint (1, r.bottom());
1361 pt1r = QPoint (r.width() - hh, r.bottom());
1362 pt2l = QPoint (5, r.top() + 1);
1363 pt2r = QPoint (r.width() - hh, r.top() + 1);
1364 }
1365 else
1366 {
1367 pt1l = QPoint (1, r.top());
1368 pt1r = QPoint (r.width() - hh, r.top());
1369 pt2l = QPoint (5, hh - 3);
1370 pt2r = QPoint (r.width() - hh, hh - 3);
1371 }
1372 if (reverse)
1373 {
1374 pt1l.setX (r.right() - pt1l.x());
1375 pt1r.setX (r.right() - pt1r.x());
1376 pt2l.setX (r.right() - pt2l.x());
1377 pt2r.setX (r.right() - pt2r.x());
1378 }
1379
1380 const QColorGroup &cg = colorGroup();
1381 p.setPen (cg.dark());
1382 p.drawLine (pt1l, pt1r);
1383 p.drawLine (pt2l, pt2r);
1384 p.setPen (cg.light());
1385 ++ pt2l.ry();
1386 ++ pt2r.ry();
1387 p.drawLine (pt2l, pt2r);
1388
1389 if (_tabBar == 0)
1390 return; // should never happen
1391
1392 int inx = currentInx();
1393 bool noPlus = inx >= _tabBar->count() - 1,
1394 noMinus = inx <= 0;
1395
1396 QPoint cpt (pt1r);
1397 if (_bottom)
1398 {
1399 if (reverse)
1400 {
1401 cpt += QPoint (-hh, -hh + 1);
1402 drawBentCornerBL (cpt, hh, p);
1403 if (!noPlus)
1404 drawPlusButton (cpt + QPoint (5, hh - 12), p);
1405 if (!noMinus)
1406 drawMinusButton (cpt + QPoint (hh - 15, 7), p);
1407 }
1408 else
1409 {
1410 cpt += QPoint (1, -hh + 1);
1411 drawBentCornerBR (cpt, hh, p);
1412 if (!noPlus)
1413 drawPlusButton (cpt + QPoint (hh - 12, hh - 12), p);
1414 if (!noMinus)
1415 drawMinusButton (cpt + QPoint (8, 7), p);
1416 }
1417 }
1418 else
1419 {
1420 if(reverse)
1421 {
1422 cpt += QPoint (-hh, 0);
1423 drawBentCornerTL (cpt, hh, p);
1424 if (!noPlus)
1425 drawPlusButton (cpt + QPoint (5, 5), p);
1426 if (!noMinus)
1427 drawMinusButton (cpt + QPoint (hh - 15, hh - 14), p);
1428 }
1429 else
1430 {
1431 cpt += QPoint (1, 0);
1432 drawBentCornerTR (cpt, hh, p);
1433 if (!noPlus)
1434 drawPlusButton (cpt + QPoint (hh - 12, 5), p);
1435 if (!noMinus)
1436 drawMinusButton (cpt + QPoint (8, hh - 14), p);
1437 }
1438 }
1439}
1440
1441void QWarpTabPanelHeader::mouseReleaseEvent(QMouseEvent* e)
1442{
1443 QPoint p = e->pos();
1444 bool reverse = QApplication::reverseLayout(),
1445 corner = false;
1446 if(reverse)
1447 corner = p.x() < height();
1448 else
1449 corner = p.x() > (width() - height());
1450 if(!corner)
1451 return; // the click was outside the bent corner area
1452
1453 // calculate sum of x and y coordinates, measured from the corner
1454 // where the + button is
1455 long sum = 0;
1456 if(_bottom)
1457 {
1458 if(reverse)
1459 sum = p.x() + height() - p.y();
1460 else
1461 sum = width() - p.x() + height() - p.y();
1462 }
1463 else
1464 {
1465 if(reverse)
1466 sum = p.x() + p.y();
1467 else
1468 sum = width() - p.x() + p.y();
1469 }
1470
1471 // if this sum is less than the widget height, we are in the
1472 // + triangle of the bent corner, otherwise in the - triangle
1473 int inx = currentInx();
1474 if(height() > sum)
1475 ++inx;
1476 else
1477 --inx;
1478
1479 if(_tabBar == 0)
1480 return; // should never happen
1481
1482 if (inx >= 0 && _tabBar->count() > inx)
1483 _tabBar->setCurrentTab (_tabBar->tabAt (inx)->identifier());
1484}
1485
1486void QWarpTabPanelHeader::drawBentCornerTR(QPoint pt, int h, QPainter& p)
1487{
1488 p.drawPixmap (pt, *qWarpSystemPixmaps.getPixmap (QWarpPixmap::tabheadertr,
1489 QWarpPixmap::internal, h));
1490}
1491
1492void QWarpTabPanelHeader::drawBentCornerTL(QPoint pt, int h, QPainter& p)
1493{
1494 p.drawPixmap (pt, *qWarpSystemPixmaps.getPixmap (QWarpPixmap::tabheadertl,
1495 QWarpPixmap::internal, h));
1496}
1497
1498void QWarpTabPanelHeader::drawBentCornerBR(QPoint pt, int h, QPainter& p)
1499{
1500 p.drawPixmap (pt, *qWarpSystemPixmaps.getPixmap (QWarpPixmap::tabheaderbr,
1501 QWarpPixmap::internal, h));
1502}
1503
1504void QWarpTabPanelHeader::drawBentCornerBL(QPoint pt, int h, QPainter& p)
1505{
1506 p.drawPixmap (pt, *qWarpSystemPixmaps.getPixmap (QWarpPixmap::tabheaderbl,
1507 QWarpPixmap::internal, h));
1508}
1509
1510void QWarpTabPanelHeader::drawPlusButton(QPoint pt, QPainter& p)
1511{
1512 p.drawPixmap (pt, *qWarpSystemPixmaps.getPixmap (QWarpPixmap::tabhdrplus,
1513 QWarpPixmap::internal));
1514}
1515
1516void QWarpTabPanelHeader::drawMinusButton(QPoint pt, QPainter& p)
1517{
1518 p.drawPixmap (pt, *qWarpSystemPixmaps.getPixmap (QWarpPixmap::tabhdrminus,
1519 QWarpPixmap::internal));
1520}
1521
1522int QWarpTabPanelHeader::currentInx()
1523{
1524 if (_tabBar == 0)
1525 return 0; // should never happen
1526 int id = _tabBar->currentTab();
1527
1528 return (id == 0) ? 0 : _tabBar->indexOf (id);
1529}
1530
1531void QWarpTabPanelHeader::setupLayout (QRect rect)
1532{
1533 QRect r (rect);
1534 bool reverse = QApplication::reverseLayout();
1535 if (_bottom)
1536 {
1537 if (reverse)
1538 r.addCoords (14, 0, -12, -13);
1539 else
1540 r.addCoords (12, 0, -14, -13);
1541 }
1542 else
1543 {
1544 if (reverse)
1545 r.addCoords (14, 13, -12, 0);
1546 else
1547 r.addCoords (12, 13, -14, 0);
1548 }
1549
1550 setGeometry (r);
1551}
1552
1553#endif // QT_PM_NO_TABWIDGET_HEADERS
1554
1555/*----------------------------------------------------------------------*\
1556 * QWarpMainWindowLayouter class
1557\*----------------------------------------------------------------------*/
1558
1559/*! \internal
1560 A widget that catches resize events for the main window and corrects
1561 the layout if necessary.
1562*/
1563class QWarpMainWindowLayouter: public QWidget
1564{
1565 Q_OBJECT
1566
1567public:
1568 QWarpMainWindowLayouter(QMainWindow* mw);
1569
1570protected:
1571 virtual bool eventFilter(QObject* watched, QEvent* ev);
1572 virtual bool event(QEvent* e);
1573
1574private:
1575 QMainWindow* getMainWindow();
1576
1577 void setupLayout();
1578
1579public:
1580 static void addIfNotPresent(QMainWindow* mw);
1581};
1582
1583QWarpMainWindowLayouter::QWarpMainWindowLayouter(QMainWindow* mw)
1584: QWidget(mw, "qt_warp_mainwindow_layouter")
1585{
1586 // we need to catch resize events from the main window, in order to adapt
1587 // the size of the client area to really cover the top and bottom dock
1588 // areas if they are empty
1589
1590 mw->installEventFilter(this);
1591 setupLayout();
1592}
1593
1594bool QWarpMainWindowLayouter::eventFilter(QObject* watched, QEvent* ev)
1595{
1596 if(!watched->inherits("QMainWindow") ||
1597 (QEvent::Resize != ev->type()))
1598 return false;
1599
1600 // we need to adapt the client area if the main window is being resized,
1601 // but only after the layouter has done its work, so we have to delay the
1602 // action by posting an event to ourselves
1603
1604 QApplication::postEvent(this, new QEvent((QEvent::Type)(QEvent::User + 2318)));
1605
1606 return false;
1607}
1608
1609bool QWarpMainWindowLayouter::event(QEvent* e)
1610{
1611 if(((QEvent::Type)(QEvent::User + 2318)) == e->type())
1612 setupLayout();
1613
1614 return QWidget::event(e);
1615}
1616
1617QMainWindow* QWarpMainWindowLayouter::getMainWindow()
1618{
1619 QWidget* ww = parentWidget();
1620 if((0 == ww) || !ww->inherits("QMainWindow"))
1621 return 0;
1622
1623 return (QMainWindow*)ww;
1624}
1625
1626void QWarpMainWindowLayouter::setupLayout()
1627{
1628 QMainWindow* mw = getMainWindow();
1629 if(0 == mw)
1630 return;
1631
1632 QWidget* cw = mw->centralWidget();
1633 if(0 == cw)
1634 return;
1635
1636 QDockArea* td = mw->topDock();
1637 QDockArea* bd = mw->bottomDock();
1638 QRect gg = cw->geometry();
1639 QRect gg2(gg);
1640
1641 if((0 != td) && (1 == td->height()))
1642 gg2.setTop(td->geometry().top());
1643
1644 if((0 != bd) && (1 == bd->height()))
1645 gg2.setBottom(bd->geometry().bottom());
1646
1647 if(gg != gg2)
1648 cw->setGeometry(gg2);
1649}
1650
1651void QWarpMainWindowLayouter::addIfNotPresent(QMainWindow* mw)
1652{
1653 if(0 != mw->child("qt_warp_mainwindow_layouter", "QWarpMainWindowLayouter", false))
1654 return; // layouter already there
1655
1656 // create if not yet present, with the main window as parent
1657 // note: deletion occurs when the main window is destroyed
1658
1659 new QWarpMainWindowLayouter(mw);
1660}
1661
1662/*! \internal
1663 Global function for determining whether a popup menu has submenus.
1664
1665 Note: this function is "ugly" because it is called for every menu
1666 item once, while the popup widget in turn scans through the menu
1667 items - but there is no other way to correct the problem with having
1668 at the same time an accelerator key (string after \t (tab)) and a
1669 submenu arrow displayed!
1670
1671 btw., the Windows style solves that problem by always having some space left
1672 for the arrow, and Motiv overpaints the arrow over the accelerator string,
1673 but native PM handles the case in a flexible and correct way!...
1674*/
1675static
1676bool qPopupMenuHasSub(QPopupMenu const* pm)
1677{
1678 bool hasSub = false;
1679 unsigned long ix;
1680 for(ix = 0; ix < pm->count(); ++ix)
1681 {
1682 QMenuItem const* mi = pm->findItem(pm->idAt(ix));
1683 hasSub = hasSub || (0 != mi->popup());
1684 }
1685
1686 return hasSub;
1687}
1688
1689/*----------------------------------------------------------------------*\
1690 * Auxiliary functions
1691\*----------------------------------------------------------------------*/
1692
1693/*! \internal
1694 Debug log of widget hierarchy.
1695*/
1696#if 0
1697static void qDebugLog(QWidget* widget,
1698 bool withChildren = false,
1699 unsigned long indent = 0)
1700{
1701 qDebug("%*sclass <%s>, name <%s>", (int)indent, "", widget->className(), widget->name());
1702 QRect r(widget->geometry());
1703 qDebug("%*sgeom (%d, %d) - (%d, %d) (size = %d, %d)", (int)indent, "", r.left(), r.top(), r.right(), r.bottom(), r.width(), r.height());
1704 r = widget->frameGeometry();
1705 qDebug("%*sframe (%d, %d) - (%d, %d)", (int)indent, "", r.left(), r.top(), r.right(), r.bottom());
1706
1707 if(withChildren)
1708 {
1709 QObjectList* wl = widget->queryList("QWidget", 0, false, false);
1710 QObjectListIterator wlit(*wl);
1711 QWidget* cw;
1712 while((cw = (QWidget*)wlit.current()) != 0)
1713 {
1714 ++wlit;
1715 qDebugLog(cw, true, indent + 2);
1716 }
1717 delete wl;
1718 }
1719}
1720#endif
1721
1722/*----------------------------------------------------------------------*\
1723 * QWarp4Style class
1724\*----------------------------------------------------------------------*/
1725
1726/*!
1727 \class QWarp4Style qwarp4style.h
1728 \brief The QWarp4Style class provides an OS/2 Warp 4 like look and feel.
1729
1730 \ingroup appearance
1731
1732 This style is Qt's default GUI style on OS/2 (or eComStation).
1733*/
1734
1735/*!
1736 Constructs a QWarp4Style
1737*/
1738QWarp4Style::QWarp4Style()
1739 : QCommonStyle()
1740 , oldDefIconFactory(0)
1741{
1742 pmDefIconFactory = new QIconFactoryPM();
1743}
1744
1745/*! \reimp */
1746QWarp4Style::~QWarp4Style()
1747{
1748 delete pmDefIconFactory;
1749}
1750
1751/*! \reimp */
1752void QWarp4Style::polish (QApplication *app)
1753{
1754#ifndef QT_NO_ICONSET
1755 // replace the "disabled" creation mechanism for pixmaps
1756 // and do it "the Warp way"
1757 oldDefIconFactory = QIconFactory::defaultFactory();
1758 bool oldAutoDelete = oldDefIconFactory->autoDelete();
1759 // prevent the old factory from being deleted when replacing
1760 oldDefIconFactory->setAutoDelete(FALSE);
1761 QIconFactory::installDefaultFactory(pmDefIconFactory);
1762 oldDefIconFactory->setAutoDelete(oldAutoDelete);
1763#endif
1764}
1765
1766/*! \reimp */
1767void QWarp4Style::unPolish (QApplication *)
1768{
1769#ifndef QT_NO_ICONSET
1770 // restore the original default iconfactory (unless it has been changed
1771 // externally after we were polished)
1772 if (pmDefIconFactory == QIconFactory::defaultFactory())
1773 {
1774 QIconFactory::installDefaultFactory(oldDefIconFactory);
1775 }
1776 else
1777 {
1778 // We are now responsible for deleting the old factory.
1779 // Note: the QIconFactory reference management in Qt is unreliable
1780 // (see qiconset.cpp, qcleanuphandler.h) so even after our attempt to
1781 // be tidy there is still a zillion cases for memory leaks or freed
1782 // memory access. I'm not going to fix Qt in this part.
1783 if (oldDefIconFactory->autoDelete())
1784 delete oldDefIconFactory;
1785 }
1786#endif
1787}
1788
1789/*! \reimp */
1790void QWarp4Style::polish (QWidget *widget)
1791{
1792 if (widget != 0 && widget->inherits ("QTabWidget"))
1793 {
1794 QTabWidget *tw = (QTabWidget *) widget;
1795
1796#ifndef QT_PM_NO_TABWIDGET_HEADERS
1797 // create the tab panel header widget
1798 new QWarpTabPanelHeader (tw);
1799#endif
1800
1801 // reduce the widget stack's frame rect to get space for drawing
1802 // PE_PanelTabWidget. Hackish, but there seems to be no any official way
1803 // in the QStyle framework to change the tab the width of the frame
1804 // drawn by PE_PanelTabWidget (QFrame::TabWidgetPanel style).
1805 QWidgetStack *ws = (QWidgetStack *) tw->child ("tab pages",
1806 "QWidgetStack", false);
1807 Q_ASSERT (ws);
1808 if (ws)
1809 {
1810 QRect r = ws->rect();
1811#ifndef QT_PM_NO_TABWIDGET_HEADERS
1812 bool reverse = QApplication::reverseLayout();
1813 if (reverse)
1814 {
1815 if (tw->tabPosition() == QTabWidget::Bottom)
1816 r.addCoords (15, 12, -12, 0);
1817 else
1818 r.addCoords (15, 0, -12, -12);
1819 }
1820 else
1821 {
1822 if (tw->tabPosition() == QTabWidget::Bottom)
1823 r.addCoords (12, 12, -15, 0);
1824 else
1825 r.addCoords (12, 0, -15, -12);
1826 }
1827#else
1828 if (tw->tabPosition() == QTabWidget::Bottom)
1829 r.addCoords (12, 12, -12, 0);
1830 else
1831 r.addCoords (12, 0, -12, -12);
1832#endif
1833 ws->setFrameRect (r);
1834 }
1835 }
1836
1837 QCommonStyle::polish (widget);
1838}
1839
1840/*! \reimp */
1841void QWarp4Style::unPolish (QWidget *widget)
1842{
1843 if (widget != 0 && widget->inherits ("QTabWidget"))
1844 {
1845 QTabWidget *tw = (QTabWidget *) widget;
1846
1847 // restore the widget stack's frame rect
1848 QWidgetStack *ws = (QWidgetStack *) tw->child ("tab pages",
1849 "QWidgetStack", false);
1850 Q_ASSERT (ws);
1851 if (ws)
1852 ws->setFrameRect (QRect());
1853
1854#ifndef QT_PM_NO_TABWIDGET_HEADERS
1855 // delete the tab panel header widget
1856 QWarpTabPanelHeader* tph =
1857 (QWarpTabPanelHeader *) tw->child ("qt_warp_tabpanel_header",
1858 "QWarpTabPanelHeader", false);
1859 Q_ASSERT (tph);
1860 if (tph != 0)
1861 delete tph;
1862#endif
1863 }
1864
1865 QCommonStyle::unPolish (widget);
1866}
1867
1868/*! \reimp */
1869void QWarp4Style::polish (QPalette &pal)
1870{
1871 QCommonStyle::polish (pal);
1872}
1873
1874/*! \reimp */
1875void QWarp4Style::drawPrimitive (PrimitiveElement pe,
1876 QPainter *p,
1877 const QRect &r,
1878 const QColorGroup &cg,
1879 SFlags flags,
1880 const QStyleOption &opt) const
1881{
1882 QRect rr (r);
1883
1884 switch (pe)
1885 {
1886 case PE_ButtonCommand:
1887 case PE_ButtonTool:
1888 {
1889 bool def = flags & Style_ButtonDefault;
1890 qDrawWarpDefFrame (p, rr, cg, def);
1891 rr.addCoords (1, 1, -1, -1);
1892
1893 bool sunken = flags & (Style_Sunken | Style_Down | Style_On);
1894 QBrush fill = cg.brush (QColorGroup::Button);
1895 qDrawWarpFilledRect (p, rr, cg.dark(), cg.light(), &fill, 2, sunken);
1896 break;
1897 }
1898
1899 case PE_HeaderArrow:
1900 {
1901 p->save();
1902 while(0 != (rr.width() % 4))
1903 rr.setWidth(rr.width() - 1);
1904 rr.moveTop(rr.top() + rr.height() / 2 - rr.width() / 4 - 1);
1905 rr.setHeight(rr.width() / 2 + 1);
1906 rr.setWidth(rr.width() + 1);
1907 QPointArray pa(3);
1908 if(flags & Style_Down)
1909 {
1910 pa.setPoint(0, rr.left() + rr.width() / 2, rr.bottom());
1911 pa.setPoint(1, rr.left(), rr.top());
1912 pa.setPoint(2, rr.right(), rr.top());
1913 }
1914 else
1915 {
1916 pa.setPoint(0, rr.left(), rr.bottom());
1917 pa.setPoint(1, rr.right(), rr.bottom());
1918 pa.setPoint(2, rr.left() + rr.width() / 2, rr.top());
1919 }
1920 p->setPen(Qt::NoPen);
1921 p->setBrush(cg.shadow());
1922 p->drawPolygon(pa);
1923 p->restore();
1924 break;
1925 }
1926
1927 case PE_ButtonBevel:
1928 case PE_HeaderSection:
1929 {
1930 QBrush fill;
1931
1932 if(!(flags & Style_Down) && (flags & Style_On))
1933 fill = QBrush(cg.light(), Dense4Pattern);
1934 else
1935 fill = cg.brush(QColorGroup::Button);
1936
1937 if(flags & (Style_Raised | Style_Down | Style_On | Style_Sunken))
1938 qDrawWarpFilledRect(p, r, cg.dark(), cg.light(), &fill, 2,
1939 flags & (Style_Down | Style_On));
1940 else
1941 p->fillRect(r, fill);
1942
1943 break;
1944 }
1945
1946 case PE_ButtonDefault:
1947 {
1948 p->setPen(cg.shadow());
1949 p->drawRect(r);
1950
1951 break;
1952 }
1953
1954 case PE_Separator:
1955 {
1956 p->setPen(cg.dark());
1957 rr.addCoords(0, 0, 0, -1);
1958 p->drawLine(rr.bottomLeft(), rr.bottomRight());
1959 break;
1960 }
1961
1962 case PE_FocusRect:
1963 {
1964 if(opt.isDefault())
1965 p->drawWinFocusRect(r);
1966 else
1967 p->drawWinFocusRect(r, opt.color());
1968
1969 break;
1970 }
1971
1972 case PE_Indicator:
1973 case PE_CheckListIndicator:
1974 case PE_ExclusiveIndicator:
1975 case PE_CheckListExclusiveIndicator:
1976 {
1977 bool sunken = flags & (Style_Sunken | Style_Down);
1978 QWarpPixmap::QWarpInternalPixmap type;
1979 switch(pe)
1980 {
1981 case PE_Indicator:
1982 case PE_CheckListIndicator:
1983 {
1984 if(flags & Style_On)
1985 {
1986 if(sunken)
1987 type = QWarpPixmap::chkboxcheckedsunken;
1988 else
1989 type = QWarpPixmap::chkboxchecked;
1990 }
1991 else if(flags & Style_NoChange)
1992 {
1993 if(sunken)
1994 type = QWarpPixmap::chkboxtrisunken;
1995 else
1996 type = QWarpPixmap::chkboxtri;
1997 }
1998 else
1999 {
2000 if(sunken)
2001 type = QWarpPixmap::chkboxsunken;
2002 else
2003 type = QWarpPixmap::chkboxnormal;
2004 }
2005 break;
2006 }
2007 case PE_ExclusiveIndicator:
2008 case PE_CheckListExclusiveIndicator:
2009 default:
2010 {
2011 if(flags & Style_On)
2012 {
2013 if(sunken)
2014 type = QWarpPixmap::radbutcheckedsunken;
2015 else
2016 type = QWarpPixmap::radbutchecked;
2017 }
2018 else
2019 {
2020 if(sunken)
2021 type = QWarpPixmap::radbutsunken;
2022 else
2023 type = QWarpPixmap::radbutnormal;
2024 }
2025 }
2026 }
2027
2028 QPixmap const* pix = qWarpSystemPixmaps.getPixmap(type,
2029 QWarpPixmap::internal);
2030 p->drawPixmap(r.x(), r.y(), *pix);
2031
2032 break;
2033 }
2034
2035 case PE_IndicatorMask:
2036 {
2037 p->fillRect(r, color1);
2038 break;
2039 }
2040
2041 case PE_ExclusiveIndicatorMask:
2042 {
2043 p->setPen(color1);
2044 p->setBrush(color1);
2045 p->drawEllipse(r);
2046
2047 break;
2048 }
2049
2050 case PE_SpinWidgetPlus:
2051 case PE_SpinWidgetMinus:
2052 case PE_SpinWidgetUp:
2053 case PE_SpinWidgetDown:
2054 {
2055 p->save();
2056
2057 // button background
2058 p->setPen(cg.shadow());
2059 p->fillRect(r, QBrush(cg.button()));
2060
2061 // three possible states
2062 enum { normal, upPressed, downPressed } st;
2063 st = normal;
2064 if(flags & Style_Sunken)
2065 {
2066 if(flags & Style_On)
2067 st = upPressed;
2068 else
2069 st = downPressed;
2070 }
2071
2072 // left and top border
2073 if(upPressed == st) p->setPen(cg.dark());
2074 else p->setPen(cg.light());
2075 p->drawLine(r.topLeft(), r.topRight());
2076 p->drawLine(r.topLeft(), r.bottomLeft());
2077 p->drawLine(r.left(), r.top() + 1, r.right(), r.top() + 1);
2078 p->drawLine(r.left() + 1, r.top(), r.left() + 1, r.bottom());
2079
2080 // right and bottom border
2081 if(downPressed == st) p->setPen(cg.light());
2082 else p->setPen(cg.dark());
2083 p->drawLine(r.topRight(), r.bottomRight());
2084 p->drawLine(r.bottomLeft(), r.bottomRight());
2085 p->drawLine(r.right() - 1, r.top(), r.right() - 1, r.bottom());
2086 p->drawLine(r.left(), r.bottom() - 1, r.right(), r.bottom() - 1);
2087
2088 // diagonal
2089 if(upPressed == st) p->setPen(cg.light());
2090 else p->setPen(cg.shadow());
2091 p->drawLine(r.bottomLeft(), r.topRight());
2092 if(upPressed == st) p->setPen(cg.light());
2093 else p->setPen(cg.dark());
2094 p->drawLine(r.left(), r.bottom() - 1, r.right() - 1, r.top());
2095 if(downPressed == st) p->setPen(cg.dark());
2096 else p->setPen(cg.light());
2097 p->drawLine(r.left() + 1, r.bottom(), r.right(), r.top() + 1);
2098
2099 // rectangles for up/down symbols
2100 QRect upRect;
2101 upRect.setWidth((r.width() - 4) / 2 - 1);
2102 if(1 != (upRect.width() % 2))
2103 {
2104 // we want an odd number for the width and height, and in
2105 // order to avoid too small symbols, we add 1 in case we
2106 // already rounded off during the division by 2 above
2107 if(1 == (r.width() % 2))
2108 upRect.setWidth(upRect.width() + 1);
2109 else
2110 upRect.setWidth(upRect.width() - 1);
2111 }
2112 upRect.setHeight(upRect.width());
2113 upRect.moveTopLeft(r.topLeft() + QPoint(2, 3));
2114 QRect downRect(upRect);
2115 downRect.moveBottomRight(r.bottomRight() - QPoint(3, 3));
2116 if(upPressed == st)
2117 upRect.moveBy(1, 1);
2118 if(downPressed == st)
2119 downRect.moveBy(1, 1);
2120
2121 switch(pe)
2122 {
2123 case PE_SpinWidgetPlus:
2124 case PE_SpinWidgetMinus:
2125 {
2126 p->setPen(cg.buttonText());
2127 p->drawLine(upRect.left(), upRect.center().y(),
2128 upRect.right(), upRect.center().y());
2129 p->drawLine(upRect.center().x(), upRect.top(),
2130 upRect.center().x(), upRect.bottom());
2131 p->drawLine(downRect.left(), downRect.center().y(),
2132 downRect.right(), downRect.center().y());
2133 break;
2134 }
2135
2136 case PE_SpinWidgetUp:
2137 case PE_SpinWidgetDown:
2138 default:
2139 {
2140 p->setBrush(cg.buttonText());
2141 p->setPen(QPen::NoPen);
2142 QPointArray a;
2143 a.putPoints(0, 3,
2144 upRect.left(), upRect.center().y(),
2145 upRect.center().x(), upRect.top(),
2146 upRect.right(), upRect.center().y());
2147 p->drawPolygon(a);
2148 a.resize(0);
2149 a.putPoints(0, 3,
2150 downRect.left(), downRect.center().y(),
2151 downRect.center().x(), downRect.bottom(),
2152 downRect.right(), downRect.center().y());
2153 p->drawPolygon(a);
2154 }
2155 }
2156
2157 p->restore();
2158
2159 break;
2160 }
2161
2162 case PE_Panel:
2163 {
2164 qDrawWarpPanel(p, rr, cg, -1);
2165 break;
2166 }
2167
2168 case PE_PanelPopup:
2169 {
2170 QBrush br(cg.background());
2171 qDrawWarpPanel(p, rr, cg, 1, &br);
2172 break;
2173 }
2174
2175 case PE_PanelTabWidget:
2176 {
2177 bool reverse = QApplication::reverseLayout();
2178
2179 QRect rr2 (rr);
2180
2181 // compensate for reduced frame rect in polish(). Note that due to
2182 // this frame rect hack, it's not possible to draw a
2183 // QFrame::TabWidgetPanel styled frame outside the QTabWidget
2184 // context.
2185#ifndef QT_PM_NO_TABWIDGET_HEADERS
2186 if (reverse)
2187 {
2188 rr.addCoords (-15, -12, 12, 12);
2189 rr2.addCoords (-4, -1, 1, 1);
2190 }
2191 else
2192 {
2193 rr.addCoords (-12, -12, 15, 12);
2194 rr2.addCoords (-1, -1, 4, 1);
2195 }
2196#else
2197 rr.addCoords (-12, -12, 12, 12);
2198 rr2.addCoords (-1, -1, 1, 1);
2199#endif
2200
2201 p->setClipRect (rr);
2202
2203 for (int i = 0; i < 2; ++ i)
2204 {
2205 p->setPen (i == 0 ? cg.light() : cg.dark());
2206 if (i > 0)
2207 {
2208 QRect rt = rr2;
2209 rr2 = rr;
2210 rr = rt;
2211 }
2212
2213 p->drawLine (rr.left(), rr.top(), rr.left(), rr.bottom() - 1);
2214 p->drawLine (rr.left(), rr.top(), rr.right(), rr.top());
2215 p->drawLine (rr2.left(), rr2.bottom(), rr2.right(), rr2.bottom());
2216 p->drawLine (rr2.right(), rr2.top() + 1, rr2.right(), rr2.bottom());
2217 }
2218
2219#ifndef QT_PM_NO_TABWIDGET_HEADERS
2220 if (reverse)
2221 p->drawLine (rr.left() + 3, rr.bottom() - 2,
2222 rr.left() + 3, rr.top() + 2);
2223 else
2224 p->drawLine (rr.right() - 3, rr.bottom() - 2,
2225 rr.right() - 3, rr.top() + 2);
2226#endif
2227 break;
2228 }
2229
2230 case PE_PanelMenuBar:
2231 {
2232 // It looks like this code is never being called!
2233 break;
2234 }
2235
2236 case PE_PanelGroupBox:
2237 {
2238 qDrawWarpPanel(p, rr, cg, 0);
2239 break;
2240 }
2241
2242 case PE_TabBarBase:
2243 {
2244 bool bottom = flags & Style_Bottom;
2245
2246 QRect rr2 (rr);
2247 if (bottom)
2248 rr2.addCoords (11, 0, -11, -11);
2249 else
2250 rr2.addCoords (11, 11, -11, 0);
2251
2252 for (int i = 0; i < 2; ++ i)
2253 {
2254 p->setPen (i == 0 ? cg.light() : cg.dark());
2255 if (i > 0)
2256 {
2257 QRect rt = rr2;
2258 rr2 = rr;
2259 rr = rt;
2260 }
2261
2262 if(bottom)
2263 {
2264 p->drawLine (rr.left(), rr.top(), rr.left(), rr.bottom() - 1);
2265 p->drawLine (rr2.right(), rr2.top(), rr2.right(), rr2.bottom());
2266 p->drawLine (rr2.left(), rr2.bottom(), rr2.right(), rr2.bottom());
2267 }
2268 else
2269 {
2270 p->drawLine (rr.left(), rr.top(), rr.right(), rr.top());
2271 p->drawLine (rr.left(), rr.top(), rr.left(), rr.bottom());
2272 p->drawLine (rr2.right(), rr2.top() + 1, rr2.right(), rr2.bottom());
2273 }
2274 }
2275
2276 break;
2277 }
2278
2279 case PE_Splitter:
2280 {
2281 QPen oldPen = p->pen();
2282 p->setPen(cg.light());
2283
2284 if(flags & Style_Horizontal)
2285 {
2286 p->drawLine(r.x() + 1, r.y(), r.x() + 1, r.height());
2287 p->setPen(cg.dark());
2288 p->drawLine(r.x(), r.y(), r.x(), r.height());
2289 p->drawLine(r.right()-1, r.y(), r.right()-1, r.height());
2290 p->setPen(cg.shadow());
2291 p->drawLine(r.right(), r.y(), r.right(), r.height());
2292 }
2293 else
2294 {
2295 p->drawLine(r.x(), r.y() + 1, r.width(), r.y() + 1);
2296 p->setPen(cg.dark());
2297 p->drawLine(r.x(), r.bottom() - 1, r.width(), r.bottom() - 1);
2298 p->setPen(cg.shadow());
2299 p->drawLine(r.x(), r.bottom(), r.width(), r.bottom());
2300 }
2301 p->setPen(oldPen);
2302
2303 break;
2304 }
2305
2306 case PE_DockWindowResizeHandle:
2307 {
2308 QPen oldPen = p->pen();
2309 p->setPen(cg.light());
2310
2311 if(flags & Style_Horizontal)
2312 {
2313 p->drawLine(r.x(), r.y(), r.width(), r.y());
2314 p->setPen(cg.dark());
2315 p->drawLine(r.x(), r.bottom() - 1, r.width(), r.bottom() - 1);
2316 p->setPen(cg.shadow());
2317 p->drawLine(r.x(), r.bottom(), r.width(), r.bottom());
2318 }
2319 else
2320 {
2321 p->drawLine(r.x(), r.y(), r.x(), r.height());
2322 p->setPen(cg.dark());
2323 p->drawLine(r.right()-1, r.y(), r.right()-1, r.height());
2324 p->setPen(cg.shadow());
2325 p->drawLine(r.right(), r.y(), r.right(), r.height());
2326 }
2327 p->setPen(oldPen);
2328
2329 break;
2330 }
2331
2332 case PE_ScrollBarSubLine:
2333 case PE_ScrollBarAddLine:
2334 {
2335 QPointArray pa;
2336 if(flags & Style_Horizontal)
2337 {
2338 int height2 = rr.height() / 2 - 4,
2339 width2 = height2 / 2;
2340 if(pe == PE_ScrollBarSubLine)
2341 {
2342 pa.putPoints(0, 4,
2343 width2, height2,
2344 width2, 1 - height2,
2345 1 - width2, 0,
2346 1 - width2, 1);
2347 }
2348 else
2349 {
2350 pa.putPoints(0, 4,
2351 1 - width2, 1 - height2,
2352 1 - width2, height2,
2353 width2, 1,
2354 width2, 0);
2355 }
2356 }
2357 else
2358 {
2359 int width2 = rr.width() / 2 - 4,
2360 height2 = width2 / 2;
2361 if(pe == PE_ScrollBarSubLine)
2362 {
2363 pa.putPoints(0, 4,
2364 1 - width2, height2,
2365 width2, height2,
2366 1, 1 - height2,
2367 0, 1 - height2);
2368 }
2369 else
2370 {
2371 pa.putPoints(0, 4,
2372 width2, 1 - height2,
2373 1 - width2, 1 - height2,
2374 0, height2,
2375 1, height2);
2376 }
2377 }
2378 pa.translate(rr.center().x(), rr.center().y());
2379
2380 p->setPen(cg.dark());
2381 if(!((flags & Style_Horizontal) && (pe == PE_ScrollBarAddLine)))
2382 {
2383 p->drawLine(rr.topLeft(), rr.bottomLeft());
2384 rr.setLeft(rr.left() + 1);
2385 }
2386 if(!(!(flags & Style_Horizontal) && (pe == PE_ScrollBarAddLine)))
2387 {
2388 p->drawLine(rr.topLeft(), rr.topRight());
2389 rr.setTop(rr.top() + 1);
2390 }
2391 p->setPen(cg.light());
2392 if(!((flags & Style_Horizontal) && (pe == PE_ScrollBarSubLine)))
2393 {
2394 p->drawLine(rr.topRight(), rr.bottomRight());
2395 rr.setRight(rr.right() - 1);
2396 }
2397 if(!(!(flags & Style_Horizontal) && (pe == PE_ScrollBarSubLine)))
2398 {
2399 p->drawLine(rr.bottomLeft(), rr.bottomRight());
2400 rr.setBottom(rr.bottom() - 1);
2401 }
2402
2403 if(!(flags & Style_Down))
2404 flags |= Style_Raised;
2405 drawPrimitive(PE_ButtonBevel, p, rr, cg, flags);
2406 p->setPen(cg.light());
2407 p->drawLine(rr.topRight(), rr.topRight() + QPoint(-1, 1));
2408
2409 QBrush::BrushStyle bs = (flags & Style_Enabled) ? Qt::SolidPattern : Qt::Dense4Pattern;
2410 p->setBrush(QBrush(cg.shadow(), bs));
2411 p->setPen(QPen(Qt::NoPen));
2412 p->drawPolygon(pa);
2413
2414 break;
2415 }
2416
2417 case PE_ScrollBarAddPage:
2418 case PE_ScrollBarSubPage:
2419 case PE_ScrollBarSlider:
2420 {
2421 if(!rr.isValid())
2422 break;
2423
2424 p->setPen(cg.light());
2425 if(flags & Style_Horizontal)
2426 {
2427 p->drawLine(rr.bottomLeft(), rr.bottomRight());
2428 rr.setBottom(rr.bottom() - 1);
2429 }
2430 else
2431 {
2432 p->drawLine(rr.topRight(), rr.bottomRight());
2433 rr.setRight(rr.right() - 1);
2434 }
2435 p->setPen(cg.dark());
2436 if(flags & Style_Horizontal)
2437 {
2438 p->drawLine(rr.topLeft(), rr.topRight());
2439 rr.setTop(rr.top() + 1);
2440 }
2441 else
2442 {
2443 p->drawLine(rr.topLeft(), rr.bottomLeft());
2444 rr.setLeft(rr.left() + 1);
2445 }
2446 p->drawLine(rr.topLeft(), rr.topRight());
2447
2448 if(pe == PE_ScrollBarSlider)
2449 {
2450 if(!(flags & Style_Down))
2451 flags |= Style_Raised;
2452 drawPrimitive(PE_ButtonBevel, p, rr, cg, flags);
2453 QPoint from, to, step;
2454 if(flags & Style_Horizontal)
2455 {
2456 from = QPoint(rr.center().x() - 5, rr.top() + 4);
2457 to = QPoint(rr.center().x() - 5, rr.bottom() - 4);
2458 step = QPoint(1, 0);
2459 }
2460 else
2461 {
2462 from = QPoint(rr.left() + 4, rr.center().y() - 5);
2463 to = QPoint(rr.right() - 4, rr.center().y() - 5);
2464 step = QPoint(0, 1);
2465 }
2466
2467 int i;
2468 for(i = 0; i < 12; ++i)
2469 {
2470 if(0 == (i % 2))
2471 p->setPen(cg.shadow());
2472 else
2473 p->setPen(cg.light());
2474 p->drawLine(from, to);
2475 from += step;
2476 to += step;
2477 }
2478 }
2479
2480 else // ..AddPage or ..SubPage
2481 {
2482 rr.setTop(rr.top() + 1);
2483 p->drawLine(rr.topLeft(), rr.bottomLeft());
2484 rr.setLeft(rr.left() + 1);
2485
2486 QBrush br;
2487 if(flags & Style_Down)
2488 br = QBrush(cg.shadow());
2489 else
2490 br = QBrush(qt_sysclr2qrgb(SYSCLR_SCROLLBAR));
2491 p->setPen(QPen(Qt::NoPen));
2492
2493 p->fillRect(rr, br);
2494 }
2495
2496 break;
2497 }
2498
2499 case PE_WindowFrame:
2500 {
2501 QColorGroup popupCG = cg;
2502 popupCG.setColor(QColorGroup::Light, cg.background());
2503 popupCG.setColor(QColorGroup::Midlight, cg.light());
2504
2505 int lw = opt.isDefault() ? pixelMetric(PM_MDIFrameWidth)
2506 : opt.lineWidth();
2507
2508 if(lw == 2)
2509 {
2510 qDrawWarpPanel(p, r, popupCG, -1);
2511 }
2512 else
2513 {
2514 QBrush fill = QBrush(cg.background());
2515 qDrawWarpPanel(p, r, popupCG, -1, &fill);
2516 }
2517
2518 break;
2519 }
2520
2521 default:
2522 {
2523 if((PE_CheckMark == pe) ||
2524 ((pe >= PE_ArrowUp) && (pe <= PE_ArrowLeft)))
2525 {
2526 QPixmap const* pm = 0;
2527
2528 switch(pe)
2529 {
2530 case PE_ArrowUp:
2531 pm = qWarpSystemPixmaps.getPixmap(QWarpPixmap::arrowup,
2532 QWarpPixmap::internal);
2533 break;
2534
2535 case PE_ArrowDown:
2536 pm = qWarpSystemPixmaps.getPixmap(QWarpPixmap::arrowdown,
2537 QWarpPixmap::internal);
2538 break;
2539
2540 case PE_ArrowRight:
2541 pm = qWarpSystemPixmaps.getPixmap(QWarpPixmap::arrowright,
2542 QWarpPixmap::internal);
2543 break;
2544
2545 case PE_ArrowLeft:
2546 pm = qWarpSystemPixmaps.getPixmap(QWarpPixmap::arrowleft,
2547 QWarpPixmap::internal);
2548 break;
2549
2550 default: // PE_CheckMark
2551 pm = qWarpSystemPixmaps.getPixmap(QWarpPixmap::checkmark,
2552 QWarpPixmap::internal);
2553 break;
2554 }
2555
2556 int x = rr.left() + (rr.width() - pm->width()) / 2,
2557 y = rr.top() + (rr.height() - pm->height()) / 2;
2558 p->drawPixmap(x, y, *pm);
2559 }
2560 else
2561 {
2562 QCommonStyle::drawPrimitive(pe, p, r, cg, flags, opt);
2563 }
2564 }
2565 }
2566}
2567
2568/*!
2569 \reimp
2570*/
2571void QWarp4Style::drawControl(ControlElement element,
2572 QPainter* p,
2573 QWidget const* widget,
2574 QRect const& r,
2575 QColorGroup const& cg,
2576 SFlags flags,
2577 QStyleOption const& opt) const
2578{
2579 switch (element)
2580 {
2581#ifndef QT_NO_TABBAR
2582 case CE_TabBarTab:
2583 {
2584 if(!widget || !widget->parentWidget() || !opt.tab())
2585 break;
2586
2587 QTabBar const* tb = (QTabBar const*)widget;
2588 QTab const* t = opt.tab();
2589 bool selected = flags & Style_Selected,
2590 bottom = (QTabBar::RoundedBelow == tb->shape()) ||
2591 (QTabBar::TriangularBelow == tb->shape());
2592 int id = tb->indexOf(t->identifier());
2593
2594 static const QColor tabCols[10] =
2595 {
2596 QColor(85, 219, 255),
2597 QColor(128, 219, 170),
2598 QColor(128, 146, 255),
2599 QColor(213, 182, 170),
2600 QColor(255, 255, 170),
2601 QColor(170, 146, 170),
2602 QColor(255, 146, 85),
2603 QColor(255, 219, 85),
2604 QColor(255, 182, 170),
2605 QColor(255, 219, 170)
2606 };
2607
2608 qDrawTabBar(p, r, cg, tabCols[id % 10], selected, bottom);
2609
2610 if(QApplication::reverseLayout())
2611 {
2612 p->setPen(cg.dark());
2613 int right = tb->size().width() - 1;
2614 if(bottom)
2615 p->drawLine(right, r.top(), right, r.top() + 4);
2616 else
2617 p->drawLine(right, r.bottom(), right, r.bottom() - 4);
2618
2619 }
2620 p->setPen(cg.light());
2621 if(bottom)
2622 p->drawLine(0, r.top(), 0, r.top() + 4);
2623 else
2624 p->drawLine(0, r.bottom(), 0, r.bottom() - 4);
2625
2626 break;
2627 }
2628
2629 case CE_TabBarLabel:
2630 {
2631 if(opt.isDefault())
2632 break;
2633
2634 QTabBar const* tb = (QTabBar const*)widget;
2635 QTab const* t = opt.tab();
2636 bool selected = flags & Style_Selected,
2637 bottom = (QTabBar::RoundedBelow == tb->shape()) ||
2638 (QTabBar::TriangularBelow == tb->shape());
2639
2640 QRect tr(r);
2641 if(bottom)
2642 tr.addCoords(3, 4, 1, 0);
2643 else
2644 tr.addCoords(3, 1, 1, -3);
2645
2646 if(selected)
2647 {
2648 QFont f = p->font();
2649 QRect rold = QFontMetrics(f).boundingRect(t->text());
2650 f.setBold(true);
2651 QRect rnew = QFontMetrics(f).boundingRect(t->text());
2652 p->setFont(f);
2653 int hdiff = rnew.width() - rold.width() + 1;
2654 tr.addCoords(-hdiff / 2, 0, hdiff / 2, 0);
2655
2656#ifndef QT_PM_NO_TABWIDGET_HEADERS
2657 QWidget* pw = widget->parentWidget();
2658 if (pw != 0 && pw->inherits ("QTabWidget"))
2659 {
2660 QTabWidget *tw = (QTabWidget *) pw;
2661 QWarpTabPanelHeader *tph =
2662 (QWarpTabPanelHeader *) tw->child ("qt_warp_tabpanel_header",
2663 "QWarpTabPanelHeader", false);
2664 if (tph != 0)
2665 {
2666 tph->setCaption (t->text());
2667 QRect r (tph->visibleRect());
2668 tph->repaint();
2669 }
2670 }
2671#endif // QT_PM_NO_TABWIDGET_HEADERS
2672 }
2673
2674 int alignment = AlignCenter | ShowPrefix;
2675 if(!styleHint(SH_UnderlineAccelerator, widget, QStyleOption::Default, 0))
2676 alignment |= NoAccel;
2677 drawItem(p, tr, alignment, cg, flags & Style_Enabled, 0, t->text());
2678
2679 if((flags & Style_HasFocus) && !t->text().isEmpty())
2680 drawPrimitive(PE_FocusRect, p, tr, cg);
2681
2682 break;
2683 }
2684#endif // QT_NO_TABBAR
2685
2686 case CE_ToolBoxTab:
2687 {
2688 qDrawWarpPanel(p, r, cg, -1, &cg.brush(QColorGroup::Button));
2689 break;
2690 }
2691
2692 case CE_ProgressBarGroove:
2693 {
2694 QRect rr(r);
2695 QBrush fill = cg.brush(QColorGroup::Button);
2696 qDrawWarpFilledRect(p, rr, cg.dark(), cg.light(), &fill, 2, true);
2697 // For OS/2, this can be also cg.shadow() if the user has clicked on
2698 // the bar with the mouse, but this is only due to the fact that an "OS/2
2699 // progressbar" is actually a slider, not just a display widget
2700 p->setPen(cg.dark());
2701 rr.addCoords(2, 2, -2, -1);
2702 p->drawRect(rr);
2703 break;
2704 }
2705
2706#ifndef QT_NO_PROGRESSBAR
2707 case CE_ProgressBarContents:
2708 {
2709 QProgressBar const* progressbar = (QProgressBar const*)widget;
2710 QColorGroup cgh = cg;
2711 cgh.setColor(QColorGroup::Highlight, QColor(0, 0, 170));
2712 bool reverse = QApplication::reverseLayout();
2713 QRect br(r);
2714 br.addCoords(3, 3, -3, -2);
2715
2716 if(!progressbar->totalSteps())
2717 {
2718 // draw busy indicator
2719 static const int indWidth = 30;
2720 br.addCoords(indWidth / 2, 0, -indWidth / 2, 0);
2721 int bw = br.width();
2722 int x = progressbar->progress() % (bw * 2);
2723 if(x > bw)
2724 x = 2 * bw - x;
2725 x = reverse ? br.right() - x : br.left() + x;
2726 p->setPen(QPen(cgh.highlight(), indWidth));
2727 p->drawLine(x, br.top(), x, br.bottom());
2728 }
2729
2730 else
2731 {
2732 int pos = (progressbar->progress() * br.width()) /
2733 progressbar->totalSteps();
2734 pos = reverse ?
2735 br.right() - pos :
2736 br.left() + pos;
2737
2738 p->setPen(cgh.dark());
2739 p->drawLine(pos, br.top(), pos, br.bottom());
2740
2741 if(reverse)
2742 br.setLeft(pos + 1);
2743 else
2744 br.setRight(pos - 1);
2745
2746 p->fillRect(br, cgh.highlight());
2747 }
2748
2749 break;
2750 }
2751
2752 case CE_ProgressBarLabel:
2753 {
2754 QProgressBar const* progressbar = (QProgressBar const*)widget;
2755 if(0 == progressbar->totalSteps())
2756 break;
2757
2758 if(progressbar->indicatorFollowsStyle() ||
2759 progressbar->centerIndicator())
2760 {
2761 QRect br(r);
2762 br.addCoords(3, 3, -3, -2);
2763 int pos = (progressbar->progress() * br.width()) /
2764 progressbar->totalSteps();
2765 bool reverse = QApplication::reverseLayout();
2766 if(reverse)
2767 pos = br.right() - pos;
2768 else
2769 pos = br.left() + pos;
2770
2771 // paint label black in background area
2772 QRect clip(br);
2773 if(reverse)
2774 clip.setRight(pos);
2775 else
2776 clip.setLeft(pos);
2777 p->setClipRect(clip);
2778 drawItem(p, br, AlignCenter | SingleLine, cg, flags & Style_Enabled, 0,
2779 progressbar->progressString());
2780
2781 // paint label "light" in blue ribbonstrip area
2782 clip = br;
2783 if(reverse)
2784 clip.setLeft(pos);
2785 else
2786 clip.setRight(pos);
2787 p->setClipRect(clip);
2788 drawItem(p, br, AlignCenter | SingleLine, cg, flags & Style_Enabled, 0,
2789 progressbar->progressString(), -1, &cg.highlightedText());
2790 }
2791
2792 else
2793 {
2794 drawItem(p, r, AlignCenter | SingleLine, cg, flags & Style_Enabled, 0,
2795 progressbar->progressString(), -1, 0);
2796 }
2797
2798 break;
2799 }
2800#endif // QT_NO_PROGRESSBAR
2801
2802#ifndef QT_NO_POPUPMENU
2803 case CE_PopupMenuItem:
2804 {
2805 if(!widget || opt.isDefault())
2806 break;
2807
2808 // QPopupMenu has WResizeNoErase and WRepaintNoErase flags, so we
2809 // must erase areas not covered by menu items (this is requested by
2810 // QPopupMenu using 0 as the menu item argument).
2811 // note: we do this with the frame drawing (PE_PanelPopup)
2812
2813 QPopupMenu const* popupmenu = (QPopupMenu const*)widget;
2814 QMenuItem* mi = opt.menuItem();
2815 if(!mi)
2816 break;
2817
2818 int tabw = opt.tabWidth() + 3;
2819 int iconw = QMAX(11, opt.maxIconWidth()) + 6;
2820 bool dis = !(flags & Style_Enabled);
2821 bool act = flags & Style_Active;
2822 bool reverse = QApplication::reverseLayout();
2823 int subw = (qPopupMenuHasSub(popupmenu) ? 19 : 0);
2824
2825 // the popup menu adds 1 pixel vertically on top and bottom, but
2826 // actually needs only 2 at the bottom, so we move all items
2827 // 1 pixel up
2828
2829 QRect rr(r);
2830 rr.moveBy(0, -1);
2831
2832 int x, y, w, h;
2833 rr.rect(&x, &y, &w, &h);
2834
2835 if(mi && mi->isSeparator()) // draw separator
2836 {
2837 p->setPen(cg.dark());
2838 p->drawLine(x, y + 4, x + w, y + 4);
2839 p->setPen(cg.light());
2840 p->drawLine(x, y + 5, x + w, y + 5);
2841 return;
2842 }
2843
2844 if(act)
2845 {
2846 QRect hr(rr);
2847 hr.addCoords(3, 0, -3, 1);
2848 p->fillRect(hr, cg.highlight());
2849 p->setPen(cg.highlightedText());
2850 }
2851 else
2852 {
2853 p->setPen(cg.text());
2854 }
2855
2856 if(mi->iconSet()) // draw iconset
2857 {
2858 QIconSet::Mode mode = dis ? QIconSet::Disabled : QIconSet::Normal;
2859 if(act && !dis)
2860 mode = QIconSet::Active;
2861 QPixmap pixmap;
2862 if(popupmenu->isCheckable() && mi->isChecked())
2863 pixmap = mi->iconSet()->pixmap(QIconSet::Small, mode, QIconSet::On);
2864 else
2865 pixmap = mi->iconSet()->pixmap(QIconSet::Small, mode);
2866 int px = (reverse ? (w - pixmap.width() - 6) : 6);
2867 p->drawPixmap(px, y, pixmap);
2868 }
2869
2870 else if(popupmenu->isCheckable() && mi->isChecked()) // just "checking"...
2871 {
2872 SFlags cflags = Style_Default;
2873 if(!dis)
2874 cflags |= Style_Enabled;
2875 if(act)
2876 cflags |= Style_On;
2877
2878 int xc = (reverse ? w - iconw + 15 : iconw - 15),
2879 yc = (rr.top() + rr.bottom()) / 2 - 3;
2880 drawPrimitive(PE_CheckMark, p, QRect(xc, yc, 16, 8), cg, cflags);
2881 }
2882
2883 if(mi->custom())
2884 {
2885 mi->custom()->paint(p, cg, act, !dis, 0, 10, 8, 8);
2886 }
2887
2888 QString s = mi->text();
2889 if(!s.isNull()) // draw text
2890 {
2891 int text_flags = AlignVCenter | ShowPrefix | DontClip | SingleLine;
2892 if(!styleHint(SH_UnderlineAccelerator, widget))
2893 text_flags |= NoAccel;
2894 text_flags |= (reverse ? AlignRight : AlignLeft);
2895
2896 // tab text
2897 int t = s.find('\t');
2898 QString ts;
2899 if(t >= 0)
2900 {
2901 ts = s.mid(t + 1);
2902 s = s.left(t);
2903 int tx = (reverse ? subw : w - tabw - subw);
2904 p->drawText(tx, y + 1, tabw, h, text_flags, ts);
2905 }
2906
2907 // normal text
2908 int tx = (reverse ? tabw + subw : iconw);
2909 p->drawText(tx, y + 1, w - iconw - tabw - subw, h, text_flags, s);
2910 }
2911
2912 else if(mi->pixmap()) // draw pixmap
2913 {
2914 QPixmap* pixmap = mi->pixmap();
2915 if(pixmap->depth() == 1)
2916 p->setBackgroundMode(OpaqueMode);
2917 int px = (reverse ? (w - pixmap->width() - iconw) : iconw);
2918 if(dis)
2919 {
2920 QIconSet is(*pixmap);
2921 p->drawPixmap(px, y, is.pixmap(QIconSet::Automatic, QIconSet::Disabled));
2922 }
2923 else
2924 {
2925 p->drawPixmap(px, y, *pixmap);
2926 }
2927 if(pixmap->depth() == 1)
2928 p->setBackgroundMode(TransparentMode);
2929 }
2930
2931 if(mi->popup()) // draw sub menu arrow
2932 {
2933 PrimitiveElement arrow;
2934 arrow = (reverse ? PE_ArrowLeft : PE_ArrowRight);
2935 int xa = (reverse ? 5 : w - 15),
2936 ya = (rr.top() + rr.bottom()) / 2 - 4;
2937 drawPrimitive(arrow, p, QRect(xa, ya, 12, 12),
2938 cg, dis ? Style_Default : Style_Enabled);
2939 }
2940 break;
2941 }
2942#endif // QT_NO_POPUPMENU
2943
2944 case CE_MenuBarItem:
2945 {
2946 QWidget* w = (QWidget*)widget;
2947 while(true)
2948 {
2949 QWidget* p = w->parentWidget(true);
2950 if(0 == p)
2951 break;
2952 else
2953 w = p;
2954 }
2955
2956 // here we let the two grey lines disappear at the top and bottom of
2957 // the client area that are actually the empty top and bottom docking
2958 // areas (only as long as they are empty, of course)
2959 if(w->inherits("QMainWindow"))
2960 QWarpMainWindowLayouter::addIfNotPresent((QMainWindow*)w);
2961
2962 bool act = flags & Style_Active;
2963 QColorGroup mcg(cg);
2964
2965 if(act)
2966 {
2967 QRect hr(r);
2968 hr.addCoords(0, 2, 0, 0);
2969 p->fillRect(hr, cg.highlight());
2970 mcg.setColor(QColorGroup::ButtonText, mcg.highlightedText());
2971 }
2972 else
2973 {
2974 mcg.setColor(QColorGroup::ButtonText, mcg.text());
2975 }
2976
2977 QCommonStyle::drawControl(element, p, widget, r, mcg, flags, opt);
2978 break;
2979 }
2980
2981#ifndef QT_NO_TOOLBUTTON
2982 case CE_ToolButtonLabel:
2983 {
2984 if (!qstrcmp (widget->name(), "qt_left_btn") ||
2985 !qstrcmp (widget->name(), "qt_right_btn"))
2986 {
2987 // do nothing in this case!
2988 }
2989 else
2990 {
2991 QToolButton const *toolbutton = (QToolButton const *) widget;
2992 QRect rect = r;
2993 Qt::ArrowType arrowType = opt.isDefault() ?
2994 Qt::DownArrow : opt.arrowType();
2995
2996 if (flags & (Style_Down | Style_On))
2997 rect.moveBy (pixelMetric(PM_ButtonShiftHorizontal, widget),
2998 pixelMetric(PM_ButtonShiftVertical, widget));
2999
3000 if (!opt.isDefault())
3001 {
3002 PrimitiveElement pe;
3003 switch (arrowType)
3004 {
3005 case Qt::LeftArrow:
3006 pe = PE_ArrowLeft;
3007 break;
3008 case Qt::RightArrow:
3009 pe = PE_ArrowRight;
3010 break;
3011 case Qt::UpArrow:
3012 pe = PE_ArrowUp;
3013 break;
3014 default:
3015 case Qt::DownArrow:
3016 pe = PE_ArrowDown;
3017 break;
3018 }
3019
3020 drawPrimitive (pe, p, rect, cg, flags, opt);
3021 }
3022 else
3023 {
3024 QColor btext = toolbutton->paletteForegroundColor();
3025
3026 if (toolbutton->iconSet().isNull() &&
3027 !toolbutton->text().isNull() &&
3028 !toolbutton->usesTextLabel())
3029 {
3030 int alignment = AlignCenter | AlignVCenter | ShowPrefix;
3031
3032 if (!styleHint (SH_UnderlineAccelerator, widget,
3033 QStyleOption::Default, 0))
3034 alignment |= NoAccel;
3035
3036 drawItem (p, rect, alignment, cg,
3037 flags & Style_Enabled, 0, toolbutton->text(),
3038 toolbutton->text().length(), &btext);
3039 }
3040 else
3041 {
3042 QPixmap pm;
3043
3044 QIconSet::Size size =
3045 toolbutton->usesBigPixmap() ? QIconSet::Large : QIconSet::Small;
3046
3047 QIconSet::State state =
3048 toolbutton->isOn() ? QIconSet::On : QIconSet::Off;
3049
3050 QIconSet::Mode mode;
3051 if (!toolbutton->isEnabled())
3052 mode = QIconSet::Disabled;
3053 else if (flags & (Style_Down | Style_On | Style_Raised))
3054 mode = QIconSet::Active;
3055 else
3056 mode = QIconSet::Normal;
3057
3058 pm = toolbutton->iconSet().pixmap(size, mode, state);
3059
3060 if (toolbutton->usesTextLabel())
3061 {
3062 if (toolbutton->textPosition() == QToolButton::Under)
3063 {
3064 p->setFont(toolbutton->font());
3065
3066 QRect pr = rect, tr = rect;
3067 int fh = p->fontMetrics().height();
3068 pr.addCoords (0, 1, 0, -fh - 3);
3069 tr.addCoords (0, pr.bottom(), 0, -3);
3070 drawItem (p, pr, AlignCenter, cg, TRUE, &pm, QString::null);
3071 int alignment = AlignCenter | ShowPrefix;
3072
3073 if (!styleHint (SH_UnderlineAccelerator, widget, QStyleOption::Default, 0))
3074 alignment |= NoAccel;
3075
3076 drawItem (p, tr, alignment, cg,
3077 flags & Style_Enabled, 0, toolbutton->textLabel(),
3078 toolbutton->textLabel().length(), &btext);
3079 }
3080 else
3081 {
3082 p->setFont (toolbutton->font());
3083
3084 QRect pr = rect, tr = rect;
3085 pr.setWidth (pm.width() + 8);
3086 tr.addCoords (pr.right(), 0, 0, 0);
3087 drawItem (p, pr, AlignCenter, cg, TRUE, &pm, QString::null);
3088 int alignment = AlignLeft | AlignVCenter | ShowPrefix;
3089
3090 if (!styleHint(SH_UnderlineAccelerator, widget, QStyleOption::Default, 0))
3091 alignment |= NoAccel;
3092
3093 drawItem (p, tr, alignment, cg,
3094 flags & Style_Enabled, 0, toolbutton->textLabel(),
3095 toolbutton->textLabel().length(), &btext);
3096 }
3097 }
3098 else
3099 {
3100 drawItem (p, rect, AlignCenter, cg, TRUE, &pm, QString::null);
3101 }
3102 }
3103 }
3104 }
3105
3106 break;
3107 }
3108#endif // QT_NO_TOOLBUTTON
3109
3110 default:
3111 {
3112 QCommonStyle::drawControl(element, p, widget, r, cg, flags, opt);
3113 }
3114 }
3115}
3116
3117/*!
3118 \reimp
3119*/
3120int QWarp4Style::pixelMetric (PixelMetric metric, const QWidget *widget) const
3121{
3122 int ret;
3123
3124 switch (metric)
3125 {
3126 case PM_ButtonDefaultIndicator:
3127 case PM_ButtonShiftHorizontal:
3128 case PM_ButtonShiftVertical:
3129 {
3130 ret = 1;
3131 break;
3132 }
3133
3134 case PM_IndicatorWidth:
3135 case PM_ExclusiveIndicatorWidth:
3136 {
3137 QPixmap const* ip = qWarpSystemPixmaps.getPixmap (QWarpPixmap::chkboxnormal,
3138 QWarpPixmap::internal);
3139 ret = ip->width();
3140 break;
3141 }
3142
3143 case PM_IndicatorHeight:
3144 case PM_ExclusiveIndicatorHeight:
3145 {
3146 QPixmap const* ip = qWarpSystemPixmaps.getPixmap (QWarpPixmap::chkboxnormal,
3147 QWarpPixmap::internal);
3148 ret = ip->height();
3149 break;
3150 }
3151
3152#ifndef QT_NO_SCROLLBAR
3153 case PM_ScrollBarExtent:
3154 {
3155 if (!widget)
3156 {
3157 ret = 16;
3158 }
3159 else
3160 {
3161 const QScrollBar * bar = (const QScrollBar *) widget;
3162 int s = (bar->orientation() == Qt::Horizontal) ?
3163 QApplication::globalStrut().height() :
3164 QApplication::globalStrut().width();
3165 ret = QMAX(16, s);
3166 }
3167
3168 break;
3169 }
3170
3171 case PM_ScrollBarSliderMin:
3172 {
3173 ret = 20;
3174 break;
3175 }
3176#endif
3177
3178 case PM_MaximumDragDistance:
3179 {
3180 ret = -1;
3181 break;
3182 }
3183
3184#ifndef QT_NO_SLIDER
3185 case PM_SliderThickness:
3186 {
3187 ret = 20;
3188 break;
3189 }
3190
3191 case PM_SliderLength:
3192 {
3193 // we increase the "length" by 2 x 2, but then draw the slider 2 pixels
3194 // smaller than indicated, so we get the effect of a slider that does
3195 // not fully touch the extreme ends of the "groove"
3196 ret = 12 + 4;
3197 break;
3198 }
3199
3200 // Returns the number of pixels to use for the business part of the
3201 // slider (i.e., the non-tickmark portion). The remaining space is shared
3202 // equally between the tickmark regions.
3203 case PM_SliderControlThickness:
3204 {
3205 QSlider const* sl = (QSlider const*) widget;
3206 int space = (sl->orientation() == Horizontal) ? sl->height() : sl->width();
3207 int ticks = sl->tickmarks();
3208 int n = 0;
3209 if (ticks & QSlider::Above)
3210 n++;
3211 if (ticks & QSlider::Below)
3212 n++;
3213 if (!n)
3214 {
3215 ret = space;
3216 break;
3217 }
3218
3219 int thick = 6; // Magic constant to get 5 + 16 + 5
3220 if (ticks != QSlider::Both && ticks != QSlider::NoMarks)
3221 thick += pixelMetric (PM_SliderLength, sl) / 4;
3222
3223 space -= thick;
3224 //### the two sides may be unequal in size
3225 if(space > 0)
3226 thick += (space * 2) / (n + 2);
3227 ret = thick;
3228
3229 break;
3230 }
3231#endif // QT_NO_SLIDER
3232
3233 case PM_MenuBarFrameWidth:
3234 {
3235 ret = 0;
3236 break;
3237 }
3238
3239 case PM_MenuBarItemSpacing:
3240 {
3241 ret = 8;
3242 break;
3243 }
3244
3245 case PM_PopupMenuFrameHorizontalExtra:
3246 {
3247 ret = 0;
3248 break;
3249 }
3250
3251 case PM_PopupMenuFrameVerticalExtra:
3252 {
3253 ret = 1;
3254 break;
3255 }
3256
3257 case PM_DefaultFrameWidth:
3258 {
3259 if (widget && widget->inherits ("QWidgetStack") &&
3260 !qstrcmp (widget->name(), "tab pages"))
3261 {
3262#ifndef QT_PM_NO_TABWIDGET_HEADERS
3263 // cause 1px overlap with the tab header base widget to get the
3264 // left vertical line joined with the bended corner (see the
3265 // PE_PanelTabWidget primitive and QTabWidget::setUpLayout())
3266 ret = 1;
3267#else
3268 // no frame is drawn within the the widget stack frame rect
3269 ret = 0;
3270#endif
3271 break;
3272 }
3273 ret = QCommonStyle::pixelMetric (metric, widget);
3274 break;
3275 }
3276
3277 case PM_TabBarTabOverlap:
3278 {
3279 ret = 10;
3280 break;
3281 }
3282
3283 case PM_TabBarBaseHeight:
3284 {
3285#ifndef QT_PM_NO_TABWIDGET_HEADERS
3286 ret = QFontMetrics (widget->font()).boundingRect ("X").height() + 28;
3287#else
3288 ret = 12;
3289#endif
3290 break;
3291 }
3292
3293 case PM_TabBarBaseOverlap:
3294 {
3295 ret = 5;
3296 break;
3297 }
3298
3299 case PM_TabBarTabHSpace:
3300 {
3301 ret = 28;
3302 break;
3303 }
3304
3305 case PM_TabBarTabVSpace:
3306 {
3307 ret = 9;
3308 break;
3309 }
3310
3311 case PM_TabBarScrollButtonWidth:
3312 {
3313 ret = 25;
3314 break;
3315 }
3316
3317 case PM_TabBarTabShiftHorizontal:
3318 case PM_TabBarTabShiftVertical:
3319 {
3320 ret = 0;
3321 break;
3322 }
3323
3324 case PM_SplitterWidth:
3325 {
3326 ret = QMAX(6, QApplication::globalStrut().width());
3327 break;
3328 }
3329
3330 default:
3331 {
3332 ret = QCommonStyle::pixelMetric(metric, widget);
3333 break;
3334 }
3335 }
3336
3337 return ret;
3338}
3339
3340/*!
3341 \reimp
3342*/
3343QSize QWarp4Style::sizeFromContents(ContentsType contents,
3344 QWidget const* widget,
3345 QSize const& contentsSize,
3346 QStyleOption const& opt) const
3347{
3348 QSize sz(contentsSize);
3349
3350 switch (contents)
3351 {
3352 case CT_PushButton:
3353 {
3354#ifndef QT_NO_PUSHBUTTON
3355 const QPushButton* button = (const QPushButton*)widget;
3356 sz = QCommonStyle::sizeFromContents(contents, widget, contentsSize, opt);
3357 int w = sz.width(),
3358 h = sz.height();
3359
3360 int defwidth = 0;
3361 if(button->isDefault() || button->autoDefault())
3362 defwidth = 2 * pixelMetric(PM_ButtonDefaultIndicator, widget);
3363 if(w < 80 + defwidth && !button->pixmap())
3364 w = 80 + defwidth;
3365 if(h < 23 + defwidth)
3366 h = 23 + defwidth;
3367
3368 sz = QSize(w, h);
3369#endif // QT_NO_PUSHBUTTON
3370
3371 break;
3372 }
3373
3374 case CT_ToolButton:
3375 {
3376 // this includes 3px margin drawn for PE_ButtonTool + 1px spacing
3377 // around contents + 1px extra width/height for pressed icon shift
3378 sz = QSize (sz.width() + 9, sz.height() + 9);
3379 break;
3380 }
3381
3382 case CT_PopupMenuItem:
3383 {
3384#ifndef QT_NO_POPUPMENU
3385 if(! widget || opt.isDefault())
3386 break;
3387
3388 QPopupMenu const* popup = (QPopupMenu const*)widget;
3389 QMenuItem* mi = opt.menuItem();
3390 int iconw = QMAX(11, opt.maxIconWidth());
3391 QString s = mi->text();
3392 int w = sz.width(),
3393 h = sz.height();
3394
3395 if(mi->custom())
3396 {
3397 w = mi->custom()->sizeHint().width();
3398 h = mi->custom()->sizeHint().height();
3399 if(!mi->custom()->fullSpan())
3400 w += iconw;
3401 }
3402 else if(mi->widget())
3403 {
3404 }
3405 else if(mi->isSeparator())
3406 {
3407 w = 10; // arbitrary
3408 h = 8;
3409 }
3410 else
3411 {
3412 if(mi->pixmap())
3413 h = QMAX(h, mi->pixmap()->height() + 3);
3414 else if(!s.isNull())
3415 h = QMAX(h, popup->fontMetrics().height() + 1);
3416
3417 if(mi->iconSet())
3418 {
3419 h = QMAX(h, mi->iconSet()->
3420 pixmap(QIconSet::Small, QIconSet::Normal).height() + 3);
3421 w = QMAX(w, iconw);
3422 }
3423 }
3424
3425 if(!s.isNull())
3426 {
3427 w += 19;
3428 }
3429
3430 if(qPopupMenuHasSub(popup))
3431 {
3432 w += 19;
3433 }
3434
3435 w += 9;
3436
3437 sz = QSize(w, h);
3438#endif // QT_NO_POPUPMENU
3439
3440 break;
3441 }
3442
3443 case CT_MenuBar:
3444 {
3445 // It looks like this code is never being called!
3446 break;
3447 }
3448
3449 case CT_SpinBox:
3450 {
3451 sz.setHeight(sz.height() - 2);
3452 break;
3453 }
3454
3455 case CT_TabWidget:
3456 {
3457 sz.setWidth(sz.width() + 32); // 16, 16
3458 sz.setHeight(sz.height() + 14); // 0, 14
3459 break;
3460 }
3461
3462 case CT_LineEdit:
3463 {
3464 sz.setHeight(sz.height() - 1);
3465 break;
3466 }
3467
3468 default:
3469 {
3470 sz = QCommonStyle::sizeFromContents(contents, widget, sz, opt);
3471 break;
3472 }
3473 }
3474
3475 return sz;
3476}
3477
3478/*! \reimp
3479*/
3480void QWarp4Style::polishPopupMenu(QPopupMenu* p)
3481{
3482 #ifndef QT_NO_POPUPMENU
3483 if(!p->testWState(WState_Polished))
3484 p->setCheckable(TRUE);
3485 #endif
3486}
3487
3488/*!
3489 \reimp
3490 */
3491QPixmap QWarp4Style::stylePixmap(StylePixmap stylepixmap,
3492 QWidget const* widget,
3493 QStyleOption const& opt) const
3494{
3495#ifndef QT_NO_IMAGEIO_XPM
3496 switch (stylepixmap)
3497 {
3498 // SP_TitleBarShadeButton - shade button on titlebars.
3499 case SP_TitleBarShadeButton:
3500 return *qWarpSystemPixmaps.getPixmap(54, // any SBMP_ value??
3501 QWarpPixmap::bmp);
3502
3503 // SP_TitleBarUnshadeButton - unshade button on titlebars.
3504 case SP_TitleBarUnshadeButton:
3505 return *qWarpSystemPixmaps.getPixmap(56, // any SBMP_ value??
3506 QWarpPixmap::bmp);
3507
3508 // SP_TitleBarNormalButton - normal (restore) button on titlebars.
3509 case SP_TitleBarNormalButton:
3510 return *qWarpSystemPixmaps.getPixmap(SBMP_RESTOREBUTTON,
3511 QWarpPixmap::bmp);
3512
3513 // SP_TitleBarMinButton - minimize button on titlebars. For example, in a QWorkspace.
3514 case SP_TitleBarMinButton:
3515 return *qWarpSystemPixmaps.getPixmap(SBMP_MINBUTTON,
3516 QWarpPixmap::bmp);
3517
3518 // SP_TitleBarMaxButton - maximize button on titlebars.
3519 case SP_TitleBarMaxButton:
3520 return *qWarpSystemPixmaps.getPixmap(SBMP_MAXBUTTON,
3521 QWarpPixmap::bmp);
3522
3523 // SP_TitleBarCloseButton - close button on titlebars.
3524 case SP_TitleBarCloseButton:
3525 return *qWarpSystemPixmaps.getPixmap(52, // any SBMP_ value??
3526 QWarpPixmap::bmp);
3527
3528 // SP_DockWindowCloseButton - close button on dock windows; see also QDockWindow.
3529 case SP_DockWindowCloseButton:
3530 return *qWarpSystemPixmaps.getPixmap(52, // should be a bit smaller!
3531 QWarpPixmap::bmp);
3532
3533 // SP_MessageBoxInformation - the 'information' icon.
3534 case SP_MessageBoxInformation:
3535 return *qWarpSystemPixmaps.getPixmap(SPTR_ICONINFORMATION,
3536 QWarpPixmap::ico);
3537
3538 // SP_MessageBoxWarning - the 'warning' icon.
3539 case SP_MessageBoxWarning:
3540 return *qWarpSystemPixmaps.getPixmap(SPTR_ICONWARNING,
3541 QWarpPixmap::ico);
3542
3543 // SP_MessageBoxCritical - the 'critical' icon.
3544 case SP_MessageBoxCritical:
3545 return *qWarpSystemPixmaps.getPixmap(SPTR_ICONERROR,
3546 QWarpPixmap::ico);
3547
3548 // SP_MessageBoxQuestion - the 'question' icon.
3549 case SP_MessageBoxQuestion:
3550 return *qWarpSystemPixmaps.getPixmap(SPTR_ICONQUESTION,
3551 QWarpPixmap::ico);
3552
3553 default:
3554 break;
3555 }
3556#endif //QT_NO_IMAGEIO_XPM
3557
3558 return QCommonStyle::stylePixmap(stylepixmap, widget, opt);
3559}
3560
3561/*!\reimp
3562*/
3563void QWarp4Style::drawComplexControl(ComplexControl ctrl, QPainter *p,
3564 QWidget const* widget,
3565 QRect const& r,
3566 QColorGroup const& cg,
3567 SFlags flags,
3568 SCFlags sub,
3569 SCFlags subActive,
3570 QStyleOption const& opt) const
3571{
3572 switch (ctrl)
3573 {
3574#ifndef QT_NO_SCROLLBAR
3575 case CC_ScrollBar:
3576 {
3577 QScrollBar const* scrollbar = (QScrollBar const*)widget;
3578 bool maxedOut = (scrollbar->minValue() == scrollbar->maxValue());
3579
3580 QRect subline = querySubControlMetrics(ctrl, widget, SC_ScrollBarSubLine, opt),
3581 addline = querySubControlMetrics(ctrl, widget, SC_ScrollBarAddLine, opt),
3582 subpage = querySubControlMetrics(ctrl, widget, SC_ScrollBarSubPage, opt),
3583 addpage = querySubControlMetrics(ctrl, widget, SC_ScrollBarAddPage, opt),
3584 slider = querySubControlMetrics(ctrl, widget, SC_ScrollBarSlider, opt);
3585 if(!scrollbar->isEnabled())
3586 {
3587 subpage.unite(addpage).unite(slider); // fill the whole, empty bar
3588 addpage = slider = QRect(); // invalid rectangle
3589 maxedOut = true; // to avoid setting the Style_Enabled flag
3590 }
3591 bool isMin = scrollbar->value() <= scrollbar->minValue(),
3592 isMax = scrollbar->value() >= scrollbar->maxValue();
3593
3594 if((sub & SC_ScrollBarSubLine) && subline.isValid())
3595 drawPrimitive(PE_ScrollBarSubLine, p, subline, cg,
3596 ((maxedOut || isMin) ? Style_Default : Style_Enabled) |
3597 ((!isMin && (subActive == SC_ScrollBarSubLine)) ? Style_Down : Style_Default) |
3598 ((scrollbar->orientation() == Qt::Horizontal) ? Style_Horizontal : 0));
3599 if((sub & SC_ScrollBarAddLine) && addline.isValid())
3600 drawPrimitive(PE_ScrollBarAddLine, p, addline, cg,
3601 ((maxedOut || isMax) ? Style_Default : Style_Enabled) |
3602 ((!isMax && (subActive == SC_ScrollBarAddLine)) ? Style_Down : Style_Default) |
3603 ((scrollbar->orientation() == Qt::Horizontal) ? Style_Horizontal : 0));
3604 if((sub & SC_ScrollBarSubPage) && subpage.isValid())
3605 drawPrimitive(PE_ScrollBarSubPage, p, subpage, cg,
3606 ((maxedOut) ? Style_Default : Style_Enabled) |
3607 ((subActive == SC_ScrollBarSubPage) ? Style_Down : Style_Default) |
3608 ((scrollbar->orientation() == Qt::Horizontal) ? Style_Horizontal : 0));
3609 if((sub & SC_ScrollBarAddPage) && addpage.isValid())
3610 drawPrimitive(PE_ScrollBarAddPage, p, addpage, cg,
3611 ((maxedOut) ? Style_Default : Style_Enabled) |
3612 ((subActive == SC_ScrollBarAddPage) ? Style_Down : Style_Default) |
3613 ((scrollbar->orientation() == Qt::Horizontal) ? Style_Horizontal : 0));
3614 if((sub & SC_ScrollBarSlider) && slider.isValid())
3615 drawPrimitive(PE_ScrollBarSlider, p, slider, cg,
3616 ((maxedOut) ? Style_Default : Style_Enabled) |
3617 ((subActive == SC_ScrollBarSlider) ? Style_Down : Style_Default) |
3618 ((scrollbar->orientation() == Qt::Horizontal) ? Style_Horizontal : 0));
3619
3620 break;
3621 }
3622#endif // QT_NO_SCROLLBAR
3623
3624 case CC_SpinWidget:
3625 {
3626#ifndef QT_NO_SPINWIDGET
3627 QSpinWidget const* sw = (QSpinWidget const*)widget;
3628 SFlags flags;
3629 PrimitiveElement pe;
3630
3631 if(sub & SC_SpinWidgetFrame)
3632 {
3633 qDrawWarpPanel(p, r, cg, -1);
3634 }
3635
3636 if((sub & SC_SpinWidgetUp) ||
3637 (sub & SC_SpinWidgetDown))
3638 {
3639 flags = Style_Enabled;
3640 if((subActive == SC_SpinWidgetUp) ||
3641 (subActive == SC_SpinWidgetDown))
3642 flags |= Style_Sunken;
3643 else
3644 flags |= Style_Raised;
3645
3646 // we "misuse" the On flag to indicate whether the
3647 // "up" part or the "down" part of the button is sunken
3648 if(subActive == SC_SpinWidgetUp)
3649 flags |= Style_On;
3650
3651 if(sub & SC_SpinWidgetUp)
3652 {
3653 if(sw->buttonSymbols() == QSpinWidget::PlusMinus)
3654 pe = PE_SpinWidgetPlus;
3655 else
3656 pe = PE_SpinWidgetUp;
3657 }
3658 else
3659 {
3660 if(sw->buttonSymbols() == QSpinWidget::PlusMinus)
3661 pe = PE_SpinWidgetMinus;
3662 else
3663 pe = PE_SpinWidgetDown;
3664 }
3665
3666 QRect re = sw->upRect();
3667 re.setWidth(re.width() - 2);
3668 bool reverse = QApplication::reverseLayout();
3669 if(!reverse)
3670 re.moveLeft(re.left() + 2);
3671 drawPrimitive(pe, p, re, cg, flags);
3672
3673 // doesn't work yet...
3674 int x = re.left() - 1;
3675 if(reverse)
3676 {
3677 x = re.right() + 2;
3678 p->setPen(cg.light());
3679 }
3680 else
3681 {
3682 p->setPen(cg.dark());
3683 }
3684 p->drawLine(x, re.top(), x, re.bottom());
3685 p->setPen(cg.button());
3686 x--;
3687 p->drawLine(x, re.top(), x, re.bottom());
3688 }
3689
3690 //if(sub & SC_SpinWidgetDown)
3691 //{
3692 // do nothing!
3693 // note: for the Warp style we put all the up/down button
3694 // functionality into the "up" button with the diagonal
3695 // separator
3696 //}
3697#endif
3698
3699 break;
3700 }
3701
3702#ifndef QT_NO_TOOLBUTTON
3703 case CC_ToolButton:
3704 {
3705 bool right;
3706 if((right = (QString("qt_right_btn") == widget->name())) ||
3707 (QString("qt_left_btn") == widget->name()))
3708 {
3709 QToolButton* tb = (QToolButton*)widget;
3710 QTabBar* ptb = (QTabBar*)tb->parentWidget();
3711 if((0 == ptb) || !ptb->inherits("QTabBar"))
3712 return;
3713 bool bottom = (QTabBar::RoundedBelow == ptb->shape()) ||
3714 (QTabBar::TriangularBelow == ptb->shape());
3715
3716 QRect r(visualRect(querySubControlMetrics(ctrl, widget, SC_ToolButton, opt), widget));
3717 if(right)
3718 r.addCoords(-3, 0, 0, 0);
3719 else
3720 r.addCoords(0, 0, 3, 0);
3721 p->setClipRect(r);
3722
3723 p->setPen(cg.dark());
3724 if(right)
3725 {
3726 if(bottom)
3727 p->drawLine(r.right(), r.top(), r.right(), r.top() + 3);
3728 else
3729 p->drawLine(r.right(), r.bottom(), r.right(), r.bottom() - 3);
3730 }
3731
3732 QRect tr1(r), tr2(r);
3733 if(right)
3734 {
3735 tr1.addCoords(-1, 0, 1, 0);
3736 tr2.addCoords(-21, 0, -21, 0);
3737 }
3738 else
3739 {
3740 tr1.addCoords(21, 0, 21, 0);
3741 tr2.addCoords(-1, 0, 1, 0);
3742 }
3743
3744 QColorGroup const& cg(tb->colorGroup());
3745 qDrawTabBar(p, tr1, cg, cg.background(), false, bottom);
3746 qDrawTabBar(p, tr2, cg, cg.background(), false, bottom);
3747
3748 if(bottom)
3749 r.addCoords(0, 2, 0, 2);
3750 QPointArray triang;
3751 if(right)
3752 {
3753 triang.putPoints(0, 3,
3754 r.left() + 8, r.top() + 6,
3755 r.left() + 19, r.top() + 12,
3756 r.left() + 8, r.top() + 18);
3757 }
3758 else
3759 {
3760 triang.putPoints(0, 3,
3761 r.right() - 10, r.top() + 6,
3762 r.right() - 21, r.top() + 12,
3763 r.right() - 10, r.top() + 18);
3764 }
3765 p->setBrush(QColor(0, 0, 255));
3766 p->setPen(QPen::NoPen);
3767 p->drawPolygon(triang);
3768 }
3769
3770 else
3771 {
3772 QCommonStyle::drawComplexControl(ctrl, p, widget, r, cg, flags, sub,
3773 subActive, opt);
3774 }
3775
3776 break;
3777 }
3778#endif // QT_NO_TOOLBUTTON
3779
3780#ifndef QT_NO_LISTVIEW
3781 case CC_ListView:
3782 {
3783 if(sub & SC_ListView)
3784 {
3785 QCommonStyle::drawComplexControl(ctrl, p, widget, r, cg, flags, sub, subActive, opt);
3786 }
3787
3788 if(sub & (SC_ListViewBranch | SC_ListViewExpand))
3789 {
3790 QListViewItem *item = opt.listViewItem(),
3791 *child = item->firstChild();
3792 QListView* v = item->listView();
3793 int y = r.y();
3794 int bx = r.width() / 2;
3795 int // linetop = 0,
3796 linebot = 0;
3797
3798 // skip the stuff above the exposed rectangle
3799 while(child && ((y + child->height()) <= 0))
3800 {
3801 y += child->totalHeight();
3802 child = child->nextSibling();
3803 }
3804
3805 // notes about drawing lines for Warp:
3806 // 1. Warp type lines follow a different logic than the "normal" lines
3807 // for "tree views" in Qt (which follows more or less Windows)
3808 // 2. In order to ensure partial repaints, it looks like we have to
3809 // draw some lines twice: once with the parent and once with the
3810 // child (and hopefully to the same place...)
3811
3812 while(child && (y < r.height()))
3813 {
3814 if(child->isVisible())
3815 {
3816 int lh;
3817 if(!item->multiLinesEnabled())
3818 lh = child->height();
3819 else
3820 lh = p->fontMetrics().height() + 2 * v->itemMargin();
3821 lh = QMAX(lh, QApplication::globalStrut().height());
3822 if((lh % 2) > 0)
3823 lh++;
3824 linebot = y + lh / 2;
3825 p->setPen(cg.shadow());
3826
3827 // parents and grandparents
3828 int vlx = bx - v->treeStepSize() + 2,
3829 vlyt = linebot - child->height() + 8,
3830 vlyb = linebot - child->height() + 9 + child->totalHeight();
3831 if(0 <= item->depth())
3832 {
3833 // vertical line for parent
3834 if(item->isOpen())
3835 {
3836 if(0 == child->nextSibling())
3837 p->drawLine(vlx, vlyt, vlx, linebot - 2);
3838 else
3839 p->drawLine(vlx, vlyt, vlx, vlyb);
3840 }
3841
3842 // vertical lines for grandparents and "older"
3843 QListViewItem* gp = item;
3844 while(0 < gp->depth())
3845 {
3846 gp = gp->parent();
3847 vlx -= v->treeStepSize();
3848 if(0 != gp->nextSibling())
3849 p->drawLine(vlx, vlyt, vlx, vlyb);
3850 }
3851 }
3852
3853 // draw child itself
3854 if((child->isExpandable() || child->childCount()) &&
3855 (child->height() > 0))
3856 {
3857 // horizontal line up to button
3858 if((0 <= item->depth()) && item->isOpen())
3859 {
3860 p->drawLine(bx - v->treeStepSize() + 3, linebot - 2,
3861 bx - 6, linebot - 2);
3862 }
3863
3864 // button
3865 QRect rr(bx - 6, linebot - 9, 16, 16);
3866 drawPrimitive(PE_ButtonCommand, p, rr, cg,
3867 Style_Raised | Style_ButtonDefault);
3868
3869 // plus or minus
3870 p->setPen(cg.light());
3871 p->drawLine(bx, linebot - 1, bx + 6, linebot - 1);
3872 if(!child->isOpen())
3873 p->drawLine(bx + 3, linebot + 2, bx + 3, linebot - 4);
3874 p->setPen(cg.shadow());
3875 p->drawLine(bx - 1, linebot - 2, bx + 5, linebot - 2);
3876 if(!child->isOpen())
3877 p->drawLine(bx + 2, linebot + 1, bx + 2, linebot - 5);
3878
3879 // lines below expanded child
3880 if(child->isOpen())
3881 {
3882 // vertical line
3883 p->drawLine(bx + 2,
3884 linebot + child->height() - 15,
3885 bx + 2,
3886 linebot + child->totalHeight() - child->height() - 2);
3887
3888 // horizontal lines at child's children
3889 QListViewItem* child2 = child->firstChild();
3890 int y2 = linebot + child->height() - 2;
3891 while(child2 && (y2 < r.height()))
3892 {
3893 if(child2->isVisible())
3894 {
3895 p->drawLine(bx + 2, y2,
3896 bx + v->treeStepSize() - 12, y2);
3897 y2 += child2->totalHeight();
3898 }
3899 child2 = child2->nextSibling();
3900 }
3901 }
3902 }
3903 else if((0 <= item->depth()) && item->isOpen())
3904 {
3905 // horizontal line without button
3906 p->setPen(cg.shadow());
3907 p->drawLine(bx - v->treeStepSize() + 3, linebot - 2,
3908 bx + 8, linebot - 2);
3909 }
3910
3911 y += child->totalHeight();
3912 }
3913 child = child->nextSibling();
3914 }
3915 }
3916
3917 break;
3918 }
3919#endif //QT_NO_LISTVIEW
3920
3921#ifndef QT_NO_COMBOBOX
3922 case CC_ComboBox:
3923 {
3924 if(sub & SC_ComboBoxFrame)
3925 {
3926 qDrawWarpPanel(p, r, cg, -1);
3927 p->setPen(cg.dark());
3928 int x = r.right() - 2 - 16;
3929 p->drawLine(x, r.top() + 2, x, r.bottom() - 2);
3930 }
3931
3932 if(sub & SC_ComboBoxArrow)
3933 {
3934 QRect ar = visualRect(querySubControlMetrics(CC_ComboBox, widget,
3935 SC_ComboBoxArrow),
3936 widget);
3937 QBrush fill = cg.brush(QColorGroup::Button);
3938 bool sunken = subActive == SC_ComboBoxArrow;
3939 qDrawWarpFilledRect(p, ar, cg.dark(), cg.light(), &fill, 2, sunken);
3940 p->setPen(cg.button());
3941 p->drawLine(ar.bottomLeft(), ar.topRight());
3942 QPixmap const* pm = qWarpSystemPixmaps.getPixmap(SBMP_COMBODOWN,
3943 QWarpPixmap::bmp);
3944 QPoint ppt = ar.topLeft() +
3945 QPoint((ar.width() - pm->width()) / 2,
3946 (ar.height() - pm->height()) / 2);
3947 p->drawPixmap(ppt, *pm);
3948 }
3949
3950 if(sub & SC_ComboBoxEditField)
3951 {
3952 QComboBox const* cb = (QComboBox const*)widget;
3953 QRect re = QStyle::visualRect(querySubControlMetrics(CC_ComboBox, widget,
3954 SC_ComboBoxEditField),
3955 widget);
3956 p->fillRect(re, cg.brush(QColorGroup::Base));
3957
3958 if(cb->hasFocus())
3959 {
3960 p->setPen(cg.highlightedText());
3961 p->setBackgroundColor(cg.highlight());
3962 }
3963 else
3964 {
3965 p->setPen(cg.text());
3966 p->setBackgroundColor(cg.background());
3967 }
3968
3969 if(cb->hasFocus() && !cb->editable())
3970 {
3971 re = QStyle::visualRect(subRect(SR_ComboBoxFocusRect, cb), widget);
3972 p->fillRect(re, cg.brush(QColorGroup::Highlight));
3973 }
3974 }
3975
3976 break;
3977 }
3978#endif // QT_NO_COMBOBOX
3979
3980#ifndef QT_NO_SLIDER
3981 case CC_Slider:
3982 {
3983 QSlider const* sl = (QSlider const*)widget;
3984 QRect groove = querySubControlMetrics(CC_Slider, widget, SC_SliderGroove, opt),
3985 handle = querySubControlMetrics(CC_Slider, widget, SC_SliderHandle, opt);
3986
3987 // reducing the handle length by 2 on each side
3988 if(sl->orientation() == Horizontal)
3989 {
3990 handle.setLeft(handle.left() + 2);
3991 handle.setRight(handle.right() - 2);
3992 }
3993 else
3994 {
3995 handle.setTop(handle.top() + 2);
3996 handle.setBottom(handle.bottom() - 2);
3997 }
3998
3999 if((sub & SC_SliderGroove) && groove.isValid())
4000 {
4001 if(sl->orientation() == Horizontal)
4002 {
4003 groove.setTop(groove.top() + 4);
4004 groove.setBottom(groove.bottom() - 4);
4005 }
4006 else
4007 {
4008 groove.setLeft(groove.left() + 4);
4009 groove.setRight(groove.right() - 4);
4010 }
4011
4012 qDrawWarpFilledRect(p, groove, cg.dark(), cg.light(),
4013 &cg.brush(QColorGroup::Button), 2, true);
4014
4015 groove.setTop(groove.top() + 2);
4016 groove.setLeft(groove.left() + 2);
4017 if(sl->orientation() == Horizontal)
4018 {
4019 groove.setRight(groove.right() - 2);
4020 groove.setBottom(groove.bottom() - 1);
4021 }
4022 else
4023 {
4024 groove.setRight(groove.right() - 1);
4025 groove.setBottom(groove.bottom() - 2);
4026 }
4027
4028 if(flags & Style_HasFocus)
4029 p->setPen(cg.shadow());
4030 else
4031 p->setPen(cg.dark());
4032
4033 p->drawRect(groove);
4034 }
4035
4036 if(sub & SC_SliderTickmarks)
4037 {
4038 int tickOffset = pixelMetric(PM_SliderTickmarkOffset, sl);
4039 int thickness = pixelMetric(PM_SliderControlThickness, sl);
4040 int len = pixelMetric(PM_SliderLength, sl);
4041 int ticks = sl->tickmarks();
4042 int available = pixelMetric(PM_SliderSpaceAvailable, sl);
4043 int interval = sl->tickInterval();
4044
4045 if(interval <= 0 )
4046 {
4047 interval = sl->lineStep();
4048 if((qPositionFromValue(sl, interval, available) -
4049 qPositionFromValue(sl, 0, available)) < 3)
4050 interval = sl->pageStep();
4051 }
4052
4053 int fudge = len / 2;
4054 int pos;
4055
4056 if(ticks & QSlider::Above)
4057 {
4058 if(sl->orientation() == Horizontal)
4059 p->fillRect(0, 0, sl->width(), tickOffset,
4060 cg.brush(QColorGroup::Background));
4061 else
4062 p->fillRect(0, 0, tickOffset, sl->width(),
4063 cg.brush(QColorGroup::Background));
4064 int v = sl->minValue();
4065 if (!interval)
4066 interval = 1;
4067 while(v <= sl->maxValue() + 1)
4068 {
4069 pos = qPositionFromValue(sl, v, available) + fudge;
4070 if(sl->orientation() == Horizontal)
4071 {
4072 p->setPen(cg.dark());
4073 p->drawLine(pos - 1, 0, pos - 1, tickOffset - 1);
4074 p->setPen(cg.light());
4075 p->drawLine(pos, 0, pos, tickOffset - 1);
4076 }
4077 else
4078 {
4079 p->setPen(cg.dark());
4080 p->drawLine(0, pos - 1, tickOffset - 1, pos - 1);
4081 p->setPen(cg.light());
4082 p->drawLine(0, pos, tickOffset - 1, pos);
4083 }
4084 v += interval;
4085 }
4086 }
4087
4088 if(ticks & QSlider::Below)
4089 {
4090 if(sl->orientation() == Horizontal)
4091 p->fillRect(0, tickOffset + thickness, sl->width(), tickOffset,
4092 cg.brush(QColorGroup::Background));
4093 else
4094 p->fillRect(tickOffset + thickness, 0, tickOffset, sl->height(),
4095 cg.brush(QColorGroup::Background));
4096 int v = sl->minValue();
4097 if(!interval)
4098 interval = 1;
4099 while(v <= sl->maxValue() + 1)
4100 {
4101 pos = qPositionFromValue(sl, v, available) + fudge;
4102 if(sl->orientation() == Horizontal)
4103 {
4104 p->setPen(cg.dark());
4105 p->drawLine(pos - 1, tickOffset + thickness + 1,
4106 pos - 1, tickOffset + thickness + 1 + available - 1);
4107 p->setPen(cg.light());
4108 p->drawLine(pos, tickOffset + thickness + 1,
4109 pos, tickOffset + thickness + 1 + available - 1);
4110 }
4111 else
4112 {
4113 p->setPen(cg.dark());
4114 p->drawLine(tickOffset + thickness + 1, pos - 1,
4115 tickOffset + thickness + 1 + available - 1, pos - 1);
4116 p->setPen(cg.light());
4117 p->drawLine(tickOffset + thickness + 1, pos,
4118 tickOffset + thickness + 1 + available - 1, pos);
4119 }
4120 v += interval;
4121 }
4122 }
4123 }
4124
4125 if(sub & SC_SliderHandle)
4126 {
4127 qDrawWarpFilledRect(p, handle, cg.dark(), cg.light(),
4128 &cg.brush(QColorGroup::Button), 2, false);
4129
4130 if(flags & Style_HasFocus)
4131 p->setPen(cg.shadow());
4132 else
4133 p->setPen(cg.dark());
4134
4135 if(sl->orientation() == Horizontal)
4136 p->drawLine(handle.topLeft() + QPoint(5, 2),
4137 handle.bottomLeft() + QPoint(5, -2));
4138 else
4139 p->drawLine(handle.topLeft() + QPoint(2, 5),
4140 handle.topRight() + QPoint(-2, 5));
4141
4142 p->setPen(cg.light());
4143
4144 if(sl->orientation() == Horizontal)
4145 p->drawLine(handle.topLeft() + QPoint(6, 2),
4146 handle.bottomLeft() + QPoint(6, -2));
4147 else
4148 p->drawLine(handle.topLeft() + QPoint(2, 6),
4149 handle.topRight() + QPoint(-2, 6));
4150 }
4151
4152 break;
4153 }
4154#endif // QT_NO_SLIDER
4155
4156 default:
4157 {
4158 QCommonStyle::drawComplexControl(ctrl, p, widget, r, cg, flags, sub,
4159 subActive, opt);
4160 break;
4161 }
4162 }
4163}
4164
4165/*! \reimp */
4166QRect QWarp4Style::querySubControlMetrics(ComplexControl control,
4167 QWidget const* widget,
4168 SubControl sc,
4169 QStyleOption const& opt) const
4170{
4171 switch(control)
4172 {
4173#ifndef QT_NO_SCROLLBAR
4174 case CC_ScrollBar:
4175 {
4176 QScrollBar const* scrollbar = (QScrollBar const*)widget;
4177 int sbextent = pixelMetric(PM_ScrollBarExtent, widget);
4178 int maxlen = ((scrollbar->orientation() == Qt::Horizontal) ?
4179 scrollbar->width() : scrollbar->height()) -
4180 (2 * 21); // 2 buttons incl. lines
4181 int sliderstart = scrollbar->sliderStart();
4182
4183 // calculate slider length
4184 int sliderlen;
4185 if(scrollbar->maxValue() != scrollbar->minValue())
4186 {
4187 uint range = scrollbar->maxValue() - scrollbar->minValue();
4188 sliderlen = (scrollbar->pageStep() * maxlen) /
4189 (range + scrollbar->pageStep());
4190 int slidermin = pixelMetric(PM_ScrollBarSliderMin, widget);
4191 if((sliderlen < slidermin) || (range > INT_MAX / 2))
4192 sliderlen = slidermin;
4193 if(sliderlen > maxlen)
4194 sliderlen = maxlen;
4195 }
4196 else
4197 {
4198 sliderlen = maxlen;
4199 }
4200
4201 // calculate button width (for vertical scroll bars this is the height)
4202 // note: the "button" includes the lines at the extreme ends of the sb
4203 int buttonWidth;
4204 if(scrollbar->orientation() == Qt::Horizontal)
4205 buttonWidth = QMIN(scrollbar->width() / 2, 21);
4206 else
4207 buttonWidth = QMIN(scrollbar->height() / 2, 21);
4208
4209 switch(sc)
4210 {
4211 case SC_ScrollBarSubLine: // top/left button
4212 {
4213 if(scrollbar->orientation() == Qt::Horizontal)
4214 return QRect(0, 0, buttonWidth, sbextent);
4215 else
4216 return QRect(0, 0, sbextent, buttonWidth);
4217 }
4218
4219 case SC_ScrollBarAddLine: // bottom/right button
4220 {
4221 if(scrollbar->orientation() == Qt::Horizontal)
4222 return QRect(scrollbar->width() - buttonWidth, 0,
4223 buttonWidth, sbextent);
4224 else
4225 return QRect(0, scrollbar->height() - buttonWidth,
4226 sbextent, buttonWidth);
4227 }
4228
4229 case SC_ScrollBarSubPage: // between top/left button and slider
4230 {
4231 if(scrollbar->orientation() == Qt::Horizontal)
4232 return QRect(buttonWidth, 0,
4233 sliderstart - buttonWidth, sbextent);
4234 else
4235 return QRect(0, buttonWidth,
4236 sbextent, sliderstart - buttonWidth);
4237 }
4238
4239 case SC_ScrollBarAddPage: // between bottom/right button and slider
4240 {
4241 if(scrollbar->orientation() == Qt::Horizontal)
4242 return QRect(sliderstart + sliderlen, 0,
4243 maxlen + buttonWidth - sliderstart - sliderlen, sbextent);
4244 else
4245 return QRect(0, sliderstart + sliderlen,
4246 sbextent, maxlen + buttonWidth - sliderstart - sliderlen);
4247 }
4248
4249 case SC_ScrollBarGroove:
4250 {
4251 if(scrollbar->orientation() == Qt::Horizontal)
4252 return QRect(buttonWidth, 0,
4253 scrollbar->width() - buttonWidth * 2, sbextent);
4254 else
4255 return QRect(0, buttonWidth,
4256 sbextent, scrollbar->height() - buttonWidth * 2);
4257 }
4258
4259 case SC_ScrollBarSlider:
4260 {
4261 if(scrollbar->orientation() == Qt::Horizontal)
4262 return QRect(sliderstart, 0, sliderlen, sbextent);
4263 else
4264 return QRect(0, sliderstart, sbextent, sliderlen);
4265 }
4266 }
4267
4268 break;
4269 }
4270#endif // QT_NO_SCROLLBAR
4271
4272 case CC_SpinWidget:
4273 {
4274 int fw = pixelMetric(PM_SpinBoxFrameWidth, widget);
4275 QSize bs;
4276 bs.setHeight(widget->height() - 2 * fw);
4277 if(bs.height() < 16)
4278 bs.setHeight(16);
4279 bs.setWidth(bs.height() + 2);
4280 bs = bs.expandedTo(QApplication::globalStrut());
4281 int bx = widget->width() - bs.width() - fw,
4282 by = fw;
4283
4284 switch(sc)
4285 {
4286 case SC_SpinWidgetUp:
4287 return QRect(bx, by, bs.width(), bs.height());
4288 case SC_SpinWidgetDown:
4289 return QRect(bx, by + bs.height(), bs.width(), 0);
4290 case SC_SpinWidgetButtonField:
4291 return QRect(bx, by, bs.width(), widget->height() - 2 * fw);
4292 case SC_SpinWidgetEditField:
4293 return QRect(fw, fw,
4294 widget->width() - bs.width() - 2 * fw,
4295 widget->height() - 2 * fw);
4296 case SC_SpinWidgetFrame:
4297 return widget->rect();
4298 default:
4299 break;
4300 }
4301
4302 break;
4303 }
4304
4305 case CC_ComboBox:
4306 {
4307 QRect r(widget->rect());
4308 int x = r.left(),
4309 y = r.top(),
4310 wi = r.width(),
4311 he = r.height();
4312 int xpos = x;
4313 xpos += wi - 2 - 16;
4314
4315 switch(sc)
4316 {
4317 case SC_ComboBoxFrame:
4318 return widget->rect();
4319 case SC_ComboBoxArrow:
4320 return QRect(xpos, y + 2, 16, he - 4);
4321 case SC_ComboBoxEditField:
4322 return QRect(x + 2, y + 2, wi - 5 - 16, he - 4);
4323 case SC_ComboBoxListBoxPopup:
4324 return opt.rect();
4325 default:
4326 break;
4327 }
4328 break;
4329 }
4330
4331 default:
4332 {
4333 return QCommonStyle::querySubControlMetrics(control, widget, sc, opt);
4334 }
4335 }
4336
4337 return QRect();
4338}
4339
4340/*! \reimp */
4341int QWarp4Style::styleHint(StyleHint hint,
4342 QWidget const* widget,
4343 QStyleOption const& opt,
4344 QStyleHintReturn *returnData) const
4345{
4346 int ret;
4347
4348 switch (hint)
4349 {
4350 case SH_EtchDisabledText:
4351 case SH_Slider_SnapToValue:
4352 case SH_PrintDialog_RightAlignButtons:
4353 case SH_FontDialog_SelectAssociatedText:
4354 case SH_MenuBar_AltKeyNavigation:
4355 case SH_MainWindow_SpaceBelowMenuBar:
4356 case SH_ScrollBar_StopMouseOverSlider:
4357 {
4358 ret = 1;
4359 break;
4360 }
4361
4362 case SH_MenuBar_MouseTracking:
4363 case SH_PopupMenu_MouseTracking:
4364 case SH_PopupMenu_AllowActiveAndDisabled:
4365 case SH_PopupMenu_SpaceActivatesItem:
4366 case SH_PopupMenu_Scrollable:
4367 case SH_PopupMenu_SloppySubMenus:
4368 case SH_PopupMenu_SubMenuPopupDelay:
4369 case SH_ComboBox_ListMouseTracking:
4370 case SH_ItemView_ChangeHighlightOnFocus:
4371 case SH_ToolBox_SelectedPageTitleBold:
4372 {
4373 ret = 0;
4374 break;
4375 }
4376
4377 case SH_GUIStyle:
4378 {
4379 // This value still exists from Qt 1.0 (as it seems), but is never
4380 // ever used in the current code! So the function of setting it
4381 // here is only to avoid using one of the other GUI styles still
4382 // being used (i.e., WindowsStyle and MotifStyle - which in turn are
4383 // also due to being removed entirely with some new Qt version...)
4384 // Note: currently it is being used to add some space to the left of
4385 // the menubar - as that space (another amount...) is also added
4386 // for other OS styles in QMenuBar.cpp (looks like an 1.0 inheritance!)
4387 ret = PMStyle;
4388 break;
4389 }
4390
4391 default:
4392 {
4393 ret = QCommonStyle::styleHint(hint, widget, opt, returnData);
4394 break;
4395 }
4396 }
4397
4398 return ret;
4399}
4400
4401/*! \reimp */
4402QRect QWarp4Style::subRect(SubRect r, QWidget const* widget) const
4403{
4404 QRect rect;
4405
4406 switch(r)
4407 {
4408 case SR_PushButtonFocusRect:
4409 case SR_CheckBoxFocusRect:
4410 case SR_RadioButtonFocusRect:
4411 {
4412 QButton const* button = (QButton const*)widget;
4413 if(!button->pixmap() && button->text().isEmpty())
4414 {
4415 switch(r)
4416 {
4417 case SR_PushButtonFocusRect:
4418 rect = QRect(widget->rect().center(), QSize(0, 0));
4419 break;
4420 case SR_CheckBoxFocusRect:
4421 rect = subRect(SR_CheckBoxIndicator, widget);
4422 break;
4423 case SR_RadioButtonFocusRect:
4424 rect = subRect(SR_RadioButtonIndicator, widget);
4425 break;
4426 }
4427 rect.addCoords(1, 1, -1, -1);
4428 break;
4429 }
4430 QPainter* p = new QPainter(button);
4431 QRect cr;
4432 switch(r)
4433 {
4434 case SR_PushButtonFocusRect:
4435 cr = subRect(SR_PushButtonContents, widget);
4436 break;
4437 case SR_CheckBoxFocusRect:
4438 cr = subRect(SR_CheckBoxContents, widget);
4439 break;
4440 case SR_RadioButtonFocusRect:
4441 cr = subRect(SR_RadioButtonContents, widget);
4442 break;
4443 }
4444 int align = ((SR_PushButtonFocusRect == r) ?
4445 Qt::AlignCenter | Qt::AlignVCenter :
4446 Qt::AlignLeft | Qt::AlignVCenter | Qt::ShowPrefix);
4447 rect = itemRect(p, cr, align,
4448 button->isEnabled(), button->pixmap(), button->text());
4449 delete p;
4450 rect.addCoords(-1, -1, 1, 1);
4451 rect = rect.intersect(widget->rect());
4452 break;
4453 }
4454
4455#ifndef QT_NO_SLIDER
4456 case SR_SliderFocusRect:
4457 {
4458 rect = widget->rect();
4459 break;
4460 }
4461#endif // QT_NO_SLIDER
4462
4463#ifndef QT_NO_PROGRESSBAR
4464 case SR_ProgressBarGroove:
4465 case SR_ProgressBarContents:
4466 {
4467 QFontMetrics fm((widget ? widget->fontMetrics() :
4468 QApplication::fontMetrics()));
4469 QProgressBar const* progressbar = (QProgressBar const*)widget;
4470 int textw = 0;
4471 if(progressbar->percentageVisible())
4472 textw = fm.width("100%") + 6;
4473
4474 // only change for Warp4 compared to "common": the style default
4475 // is "centered"
4476 QRect wrect(widget->rect());
4477 if(!progressbar->indicatorFollowsStyle() &&
4478 !progressbar->centerIndicator())
4479 rect.setCoords(wrect.left(), wrect.top(),
4480 wrect.right() - textw, wrect.bottom());
4481 else
4482 rect = wrect;
4483 break;
4484 }
4485
4486 case SR_ProgressBarLabel:
4487 {
4488 QFontMetrics fm((widget ? widget->fontMetrics() :
4489 QApplication::fontMetrics()));
4490 QProgressBar const* progressbar = (QProgressBar const*)widget;
4491 int textw = 0;
4492 if(progressbar->percentageVisible())
4493 textw = fm.width("100%") + 6;
4494
4495 // only change for Warp4 compared to "common": the style default
4496 // is "centered"
4497 QRect wrect(widget->rect());
4498 if(!progressbar->indicatorFollowsStyle() &&
4499 !progressbar->centerIndicator())
4500 rect.setCoords(wrect.right() - textw, wrect.top(),
4501 wrect.right(), wrect.bottom());
4502 else
4503 rect = wrect;
4504 break;
4505 }
4506#endif // QT_NO_PROGRESSBAR
4507
4508 case SR_ToolBoxTabContents:
4509 {
4510 rect = widget->rect();
4511 break;
4512 }
4513
4514 default:
4515 {
4516 rect = QCommonStyle::subRect(r, widget);
4517 break;
4518 }
4519 }
4520
4521 return rect;
4522}
4523
4524#include "qwarp4style.moc"
4525
4526#endif
Note: See TracBrowser for help on using the repository browser.