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

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

styles/Warp4: Fixed painting of menu item icons and custom menu items.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id
File size: 144.6 KB
Line 
1/****************************************************************************
2** $Id: qwarp4style.cpp 182 2008-03-22 09:24:09Z 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 = (const QPopupMenu *) 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 int x, y, w, h;
2826 r.rect (&x, &y, &w, &h);
2827
2828 if (mi && mi->isSeparator()) // draw separator
2829 {
2830 p->setPen (cg.dark());
2831 p->drawLine (x, y + 3, x + w, y + 3);
2832 p->setPen (cg.light());
2833 p->drawLine (x, y + 4, x + w, y + 4);
2834 return;
2835 }
2836
2837 if (act)
2838 {
2839 QRect hr (r);
2840 hr.addCoords (3, 0, -3, 0);
2841 p->fillRect (hr, cg.highlight());
2842 p->setPen (cg.highlightedText());
2843 }
2844 else
2845 {
2846 p->setPen (cg.text());
2847 }
2848
2849 if (mi->iconSet()) // draw iconset
2850 {
2851 QIconSet::Mode mode = dis ? QIconSet::Disabled : QIconSet::Normal;
2852 if (act && !dis)
2853 mode = QIconSet::Active;
2854 QPixmap pixmap;
2855 if (popupmenu->isCheckable() && mi->isChecked())
2856 pixmap = mi->iconSet()->pixmap (QIconSet::Small, mode,
2857 QIconSet::On);
2858 else
2859 pixmap = mi->iconSet()->pixmap (QIconSet::Small, mode);
2860 int px = (reverse ? (w - pixmap.width() - 6) : 6);
2861 p->drawPixmap (px, y + (h - pixmap.height()) / 2, pixmap);
2862 }
2863 else if (popupmenu->isCheckable() && mi->isChecked()) // just "checking"...
2864 {
2865 SFlags cflags = Style_Default;
2866 if (!dis)
2867 cflags |= Style_Enabled;
2868 if (act)
2869 cflags |= Style_On;
2870
2871 int xc = (reverse ? w - iconw + 15 : iconw - 15),
2872 yc = (r.top() + r.bottom()) / 2 - 4;
2873 drawPrimitive (PE_CheckMark, p, QRect (xc, yc, 16, 8), cg, cflags);
2874 }
2875
2876 if (mi->custom())
2877 {
2878 p->save();
2879 // margins must be in sync with the draw text code below
2880 int tx = (reverse ? tabw + subw : iconw);
2881 mi->custom()->paint (p, cg, act, !dis, tx, y,
2882 w - iconw - tabw - subw, h);
2883 p->restore();
2884 }
2885
2886 QString s = mi->text();
2887 if (!s.isNull()) // draw text
2888 {
2889 int text_flags = AlignVCenter | ShowPrefix | DontClip | SingleLine;
2890 if (!styleHint (SH_UnderlineAccelerator, widget))
2891 text_flags |= NoAccel;
2892 text_flags |= (reverse ? AlignRight : AlignLeft);
2893
2894 // tab text
2895 int t = s.find ('\t');
2896 QString ts;
2897 if (t >= 0)
2898 {
2899 ts = s.mid (t + 1);
2900 s = s.left (t);
2901 int tx = (reverse ? subw : w - tabw - subw);
2902 p->drawText (tx, y, tabw, h, text_flags, ts);
2903 }
2904
2905 // normal text
2906 int tx = (reverse ? tabw + subw : iconw);
2907 p->drawText (tx, y, w - iconw - tabw - subw, h, text_flags, s);
2908 }
2909 else if (mi->pixmap()) // draw pixmap
2910 {
2911 QPixmap* pixmap = mi->pixmap();
2912 if (pixmap->depth() == 1)
2913 p->setBackgroundMode(OpaqueMode);
2914 int px = (reverse ? (w - pixmap->width() - iconw) : iconw);
2915 if (dis)
2916 {
2917 QIconSet is (*pixmap);
2918 p->drawPixmap (px, y, is.pixmap (QIconSet::Automatic,
2919 QIconSet::Disabled));
2920 }
2921 else
2922 {
2923 p->drawPixmap (px, y, *pixmap);
2924 }
2925 if (pixmap->depth() == 1)
2926 p->setBackgroundMode (TransparentMode);
2927 }
2928
2929 if (mi->popup()) // draw sub menu arrow
2930 {
2931 PrimitiveElement arrow;
2932 arrow = (reverse ? PE_ArrowLeft : PE_ArrowRight);
2933 int xa = (reverse ? 5 : w - 15),
2934 ya = (r.top() + r.bottom()) / 2 - 5;
2935 drawPrimitive (arrow, p, QRect (xa, ya, 12, 12),
2936 cg, dis ? Style_Default : Style_Enabled);
2937 }
2938
2939 break;
2940 }
2941#endif // QT_NO_POPUPMENU
2942
2943 case CE_MenuBarItem:
2944 {
2945 QWidget* w = (QWidget*)widget;
2946 while(true)
2947 {
2948 QWidget* p = w->parentWidget(true);
2949 if(0 == p)
2950 break;
2951 else
2952 w = p;
2953 }
2954
2955 // here we let the two grey lines disappear at the top and bottom of
2956 // the client area that are actually the empty top and bottom docking
2957 // areas (only as long as they are empty, of course)
2958 if(w->inherits("QMainWindow"))
2959 QWarpMainWindowLayouter::addIfNotPresent((QMainWindow*)w);
2960
2961 bool act = flags & Style_Active;
2962 QColorGroup mcg(cg);
2963
2964 if(act)
2965 {
2966 QRect hr(r);
2967 hr.addCoords(0, 2, 0, 0);
2968 p->fillRect(hr, cg.highlight());
2969 mcg.setColor(QColorGroup::ButtonText, mcg.highlightedText());
2970 }
2971 else
2972 {
2973 mcg.setColor(QColorGroup::ButtonText, mcg.text());
2974 }
2975
2976 QCommonStyle::drawControl(element, p, widget, r, mcg, flags, opt);
2977 break;
2978 }
2979
2980#ifndef QT_NO_TOOLBUTTON
2981 case CE_ToolButtonLabel:
2982 {
2983 if (!qstrcmp (widget->name(), "qt_left_btn") ||
2984 !qstrcmp (widget->name(), "qt_right_btn"))
2985 {
2986 // do nothing in this case!
2987 }
2988 else
2989 {
2990 QToolButton const *toolbutton = (QToolButton const *) widget;
2991 QRect rect = r;
2992 Qt::ArrowType arrowType = opt.isDefault() ?
2993 Qt::DownArrow : opt.arrowType();
2994
2995 if (flags & (Style_Down | Style_On))
2996 rect.moveBy (pixelMetric(PM_ButtonShiftHorizontal, widget),
2997 pixelMetric(PM_ButtonShiftVertical, widget));
2998
2999 if (!opt.isDefault())
3000 {
3001 PrimitiveElement pe;
3002 switch (arrowType)
3003 {
3004 case Qt::LeftArrow:
3005 pe = PE_ArrowLeft;
3006 break;
3007 case Qt::RightArrow:
3008 pe = PE_ArrowRight;
3009 break;
3010 case Qt::UpArrow:
3011 pe = PE_ArrowUp;
3012 break;
3013 default:
3014 case Qt::DownArrow:
3015 pe = PE_ArrowDown;
3016 break;
3017 }
3018
3019 drawPrimitive (pe, p, rect, cg, flags, opt);
3020 }
3021 else
3022 {
3023 QColor btext = toolbutton->paletteForegroundColor();
3024
3025 if (toolbutton->iconSet().isNull() &&
3026 !toolbutton->text().isNull() &&
3027 !toolbutton->usesTextLabel())
3028 {
3029 int alignment = AlignCenter | AlignVCenter | ShowPrefix;
3030
3031 if (!styleHint (SH_UnderlineAccelerator, widget,
3032 QStyleOption::Default, 0))
3033 alignment |= NoAccel;
3034
3035 drawItem (p, rect, alignment, cg,
3036 flags & Style_Enabled, 0, toolbutton->text(),
3037 toolbutton->text().length(), &btext);
3038 }
3039 else
3040 {
3041 QPixmap pm;
3042
3043 QIconSet::Size size =
3044 toolbutton->usesBigPixmap() ? QIconSet::Large : QIconSet::Small;
3045
3046 QIconSet::State state =
3047 toolbutton->isOn() ? QIconSet::On : QIconSet::Off;
3048
3049 QIconSet::Mode mode;
3050 if (!toolbutton->isEnabled())
3051 mode = QIconSet::Disabled;
3052 else if (flags & (Style_Down | Style_On | Style_Raised))
3053 mode = QIconSet::Active;
3054 else
3055 mode = QIconSet::Normal;
3056
3057 pm = toolbutton->iconSet().pixmap(size, mode, state);
3058
3059 if (toolbutton->usesTextLabel())
3060 {
3061 if (toolbutton->textPosition() == QToolButton::Under)
3062 {
3063 p->setFont(toolbutton->font());
3064
3065 QRect pr = rect, tr = rect;
3066 int fh = p->fontMetrics().height();
3067 pr.addCoords (0, 1, 0, -fh - 3);
3068 tr.addCoords (0, pr.bottom(), 0, -3);
3069 drawItem (p, pr, AlignCenter, cg, TRUE, &pm, QString::null);
3070 int alignment = AlignCenter | ShowPrefix;
3071
3072 if (!styleHint (SH_UnderlineAccelerator, widget, QStyleOption::Default, 0))
3073 alignment |= NoAccel;
3074
3075 drawItem (p, tr, alignment, cg,
3076 flags & Style_Enabled, 0, toolbutton->textLabel(),
3077 toolbutton->textLabel().length(), &btext);
3078 }
3079 else
3080 {
3081 p->setFont (toolbutton->font());
3082
3083 QRect pr = rect, tr = rect;
3084 pr.setWidth (pm.width() + 8);
3085 tr.addCoords (pr.right(), 0, 0, 0);
3086 drawItem (p, pr, AlignCenter, cg, TRUE, &pm, QString::null);
3087 int alignment = AlignLeft | AlignVCenter | ShowPrefix;
3088
3089 if (!styleHint(SH_UnderlineAccelerator, widget, QStyleOption::Default, 0))
3090 alignment |= NoAccel;
3091
3092 drawItem (p, tr, alignment, cg,
3093 flags & Style_Enabled, 0, toolbutton->textLabel(),
3094 toolbutton->textLabel().length(), &btext);
3095 }
3096 }
3097 else
3098 {
3099 drawItem (p, rect, AlignCenter, cg, TRUE, &pm, QString::null);
3100 }
3101 }
3102 }
3103 }
3104
3105 break;
3106 }
3107#endif // QT_NO_TOOLBUTTON
3108
3109 default:
3110 {
3111 QCommonStyle::drawControl(element, p, widget, r, cg, flags, opt);
3112 }
3113 }
3114}
3115
3116/*!
3117 \reimp
3118*/
3119int QWarp4Style::pixelMetric (PixelMetric metric, const QWidget *widget) const
3120{
3121 int ret;
3122
3123 switch (metric)
3124 {
3125 case PM_ButtonDefaultIndicator:
3126 case PM_ButtonShiftHorizontal:
3127 case PM_ButtonShiftVertical:
3128 {
3129 ret = 1;
3130 break;
3131 }
3132
3133 case PM_IndicatorWidth:
3134 case PM_ExclusiveIndicatorWidth:
3135 {
3136 QPixmap const* ip = qWarpSystemPixmaps.getPixmap (QWarpPixmap::chkboxnormal,
3137 QWarpPixmap::internal);
3138 ret = ip->width();
3139 break;
3140 }
3141
3142 case PM_IndicatorHeight:
3143 case PM_ExclusiveIndicatorHeight:
3144 {
3145 QPixmap const* ip = qWarpSystemPixmaps.getPixmap (QWarpPixmap::chkboxnormal,
3146 QWarpPixmap::internal);
3147 ret = ip->height();
3148 break;
3149 }
3150
3151#ifndef QT_NO_SCROLLBAR
3152 case PM_ScrollBarExtent:
3153 {
3154 if (!widget)
3155 {
3156 ret = 16;
3157 }
3158 else
3159 {
3160 const QScrollBar * bar = (const QScrollBar *) widget;
3161 int s = (bar->orientation() == Qt::Horizontal) ?
3162 QApplication::globalStrut().height() :
3163 QApplication::globalStrut().width();
3164 ret = QMAX(16, s);
3165 }
3166
3167 break;
3168 }
3169
3170 case PM_ScrollBarSliderMin:
3171 {
3172 ret = 20;
3173 break;
3174 }
3175#endif
3176
3177 case PM_MaximumDragDistance:
3178 {
3179 ret = -1;
3180 break;
3181 }
3182
3183#ifndef QT_NO_SLIDER
3184 case PM_SliderThickness:
3185 {
3186 ret = 20;
3187 break;
3188 }
3189
3190 case PM_SliderLength:
3191 {
3192 // we increase the "length" by 2 x 2, but then draw the slider 2 pixels
3193 // smaller than indicated, so we get the effect of a slider that does
3194 // not fully touch the extreme ends of the "groove"
3195 ret = 12 + 4;
3196 break;
3197 }
3198
3199 // Returns the number of pixels to use for the business part of the
3200 // slider (i.e., the non-tickmark portion). The remaining space is shared
3201 // equally between the tickmark regions.
3202 case PM_SliderControlThickness:
3203 {
3204 QSlider const* sl = (QSlider const*) widget;
3205 int space = (sl->orientation() == Horizontal) ? sl->height() : sl->width();
3206 int ticks = sl->tickmarks();
3207 int n = 0;
3208 if (ticks & QSlider::Above)
3209 n++;
3210 if (ticks & QSlider::Below)
3211 n++;
3212 if (!n)
3213 {
3214 ret = space;
3215 break;
3216 }
3217
3218 int thick = 6; // Magic constant to get 5 + 16 + 5
3219 if (ticks != QSlider::Both && ticks != QSlider::NoMarks)
3220 thick += pixelMetric (PM_SliderLength, sl) / 4;
3221
3222 space -= thick;
3223 //### the two sides may be unequal in size
3224 if(space > 0)
3225 thick += (space * 2) / (n + 2);
3226 ret = thick;
3227
3228 break;
3229 }
3230#endif // QT_NO_SLIDER
3231
3232 case PM_MenuBarFrameWidth:
3233 {
3234 ret = 0;
3235 break;
3236 }
3237
3238 case PM_MenuBarItemSpacing:
3239 {
3240 ret = 8;
3241 break;
3242 }
3243
3244 case PM_PopupMenuFrameHorizontalExtra:
3245 {
3246 ret = 0;
3247 break;
3248 }
3249
3250 case PM_PopupMenuFrameVerticalExtra:
3251 {
3252 ret = 1;
3253 break;
3254 }
3255
3256 case PM_DefaultFrameWidth:
3257 {
3258 if (widget && widget->inherits ("QWidgetStack") &&
3259 !qstrcmp (widget->name(), "tab pages"))
3260 {
3261#ifndef QT_PM_NO_TABWIDGET_HEADERS
3262 // cause 1px overlap with the tab header base widget to get the
3263 // left vertical line joined with the bended corner (see the
3264 // PE_PanelTabWidget primitive and QTabWidget::setUpLayout())
3265 ret = 1;
3266#else
3267 // no frame is drawn within the the widget stack frame rect
3268 ret = 0;
3269#endif
3270 break;
3271 }
3272 ret = QCommonStyle::pixelMetric (metric, widget);
3273 break;
3274 }
3275
3276 case PM_TabBarTabOverlap:
3277 {
3278 ret = 10;
3279 break;
3280 }
3281
3282 case PM_TabBarBaseHeight:
3283 {
3284#ifndef QT_PM_NO_TABWIDGET_HEADERS
3285 ret = QFontMetrics (widget->font()).boundingRect ("X").height() + 28;
3286#else
3287 ret = 12;
3288#endif
3289 break;
3290 }
3291
3292 case PM_TabBarBaseOverlap:
3293 {
3294 ret = 5;
3295 break;
3296 }
3297
3298 case PM_TabBarTabHSpace:
3299 {
3300 ret = 28;
3301 break;
3302 }
3303
3304 case PM_TabBarTabVSpace:
3305 {
3306 ret = 9;
3307 break;
3308 }
3309
3310 case PM_TabBarScrollButtonWidth:
3311 {
3312 ret = 25;
3313 break;
3314 }
3315
3316 case PM_TabBarTabShiftHorizontal:
3317 case PM_TabBarTabShiftVertical:
3318 {
3319 ret = 0;
3320 break;
3321 }
3322
3323 case PM_SplitterWidth:
3324 {
3325 ret = QMAX(6, QApplication::globalStrut().width());
3326 break;
3327 }
3328
3329 default:
3330 {
3331 ret = QCommonStyle::pixelMetric(metric, widget);
3332 break;
3333 }
3334 }
3335
3336 return ret;
3337}
3338
3339/*!
3340 \reimp
3341*/
3342QSize QWarp4Style::sizeFromContents(ContentsType contents,
3343 QWidget const* widget,
3344 QSize const& contentsSize,
3345 QStyleOption const& opt) const
3346{
3347 QSize sz(contentsSize);
3348
3349 switch (contents)
3350 {
3351 case CT_PushButton:
3352 {
3353#ifndef QT_NO_PUSHBUTTON
3354 const QPushButton* button = (const QPushButton*)widget;
3355 sz = QCommonStyle::sizeFromContents(contents, widget, contentsSize, opt);
3356 int w = sz.width(),
3357 h = sz.height();
3358
3359 int defwidth = 0;
3360 if(button->isDefault() || button->autoDefault())
3361 defwidth = 2 * pixelMetric(PM_ButtonDefaultIndicator, widget);
3362 if(w < 80 + defwidth && !button->pixmap())
3363 w = 80 + defwidth;
3364 if(h < 23 + defwidth)
3365 h = 23 + defwidth;
3366
3367 sz = QSize(w, h);
3368#endif // QT_NO_PUSHBUTTON
3369
3370 break;
3371 }
3372
3373 case CT_ToolButton:
3374 {
3375 // this includes 3px margin drawn for PE_ButtonTool + 1px spacing
3376 // around contents + 1px extra width/height for pressed icon shift
3377 sz = QSize (sz.width() + 9, sz.height() + 9);
3378 break;
3379 }
3380
3381 case CT_PopupMenuItem:
3382 {
3383#ifndef QT_NO_POPUPMENU
3384 if(! widget || opt.isDefault())
3385 break;
3386
3387 QPopupMenu const* popup = (QPopupMenu const*)widget;
3388 QMenuItem* mi = opt.menuItem();
3389 int iconw = QMAX(11, opt.maxIconWidth());
3390 QString s = mi->text();
3391 int w = sz.width(),
3392 h = sz.height();
3393
3394 if(mi->custom())
3395 {
3396 w = mi->custom()->sizeHint().width();
3397 h = mi->custom()->sizeHint().height();
3398 if(!mi->custom()->fullSpan())
3399 w += iconw;
3400 }
3401 else if(mi->widget())
3402 {
3403 }
3404 else if(mi->isSeparator())
3405 {
3406 w = 10; // arbitrary
3407 h = 8;
3408 }
3409 else
3410 {
3411 if(mi->pixmap())
3412 h = QMAX(h, mi->pixmap()->height() + 3);
3413 else if(!s.isNull())
3414 h = QMAX(h, popup->fontMetrics().height() + 1);
3415
3416 if(mi->iconSet())
3417 {
3418 h = QMAX(h, mi->iconSet()->
3419 pixmap(QIconSet::Small, QIconSet::Normal).height() + 3);
3420 w = QMAX(w, iconw);
3421 }
3422 }
3423
3424 if(!s.isNull())
3425 {
3426 w += 19;
3427 }
3428
3429 if(qPopupMenuHasSub(popup))
3430 {
3431 w += 19;
3432 }
3433
3434 w += 9;
3435
3436 sz = QSize(w, h);
3437#endif // QT_NO_POPUPMENU
3438
3439 break;
3440 }
3441
3442 case CT_MenuBar:
3443 {
3444 // It looks like this code is never being called!
3445 break;
3446 }
3447
3448 case CT_SpinBox:
3449 {
3450 sz.setHeight(sz.height() - 2);
3451 break;
3452 }
3453
3454 case CT_TabWidget:
3455 {
3456 sz.setWidth(sz.width() + 32); // 16, 16
3457 sz.setHeight(sz.height() + 14); // 0, 14
3458 break;
3459 }
3460
3461 case CT_LineEdit:
3462 {
3463 sz.setHeight(sz.height() - 1);
3464 break;
3465 }
3466
3467 default:
3468 {
3469 sz = QCommonStyle::sizeFromContents(contents, widget, sz, opt);
3470 break;
3471 }
3472 }
3473
3474 return sz;
3475}
3476
3477/*! \reimp
3478*/
3479void QWarp4Style::polishPopupMenu(QPopupMenu* p)
3480{
3481 #ifndef QT_NO_POPUPMENU
3482 if(!p->testWState(WState_Polished))
3483 p->setCheckable(TRUE);
3484 #endif
3485}
3486
3487/*!
3488 \reimp
3489 */
3490QPixmap QWarp4Style::stylePixmap(StylePixmap stylepixmap,
3491 QWidget const* widget,
3492 QStyleOption const& opt) const
3493{
3494#ifndef QT_NO_IMAGEIO_XPM
3495 switch (stylepixmap)
3496 {
3497 // SP_TitleBarShadeButton - shade button on titlebars.
3498 case SP_TitleBarShadeButton:
3499 return *qWarpSystemPixmaps.getPixmap(54, // any SBMP_ value??
3500 QWarpPixmap::bmp);
3501
3502 // SP_TitleBarUnshadeButton - unshade button on titlebars.
3503 case SP_TitleBarUnshadeButton:
3504 return *qWarpSystemPixmaps.getPixmap(56, // any SBMP_ value??
3505 QWarpPixmap::bmp);
3506
3507 // SP_TitleBarNormalButton - normal (restore) button on titlebars.
3508 case SP_TitleBarNormalButton:
3509 return *qWarpSystemPixmaps.getPixmap(SBMP_RESTOREBUTTON,
3510 QWarpPixmap::bmp);
3511
3512 // SP_TitleBarMinButton - minimize button on titlebars. For example, in a QWorkspace.
3513 case SP_TitleBarMinButton:
3514 return *qWarpSystemPixmaps.getPixmap(SBMP_MINBUTTON,
3515 QWarpPixmap::bmp);
3516
3517 // SP_TitleBarMaxButton - maximize button on titlebars.
3518 case SP_TitleBarMaxButton:
3519 return *qWarpSystemPixmaps.getPixmap(SBMP_MAXBUTTON,
3520 QWarpPixmap::bmp);
3521
3522 // SP_TitleBarCloseButton - close button on titlebars.
3523 case SP_TitleBarCloseButton:
3524 return *qWarpSystemPixmaps.getPixmap(52, // any SBMP_ value??
3525 QWarpPixmap::bmp);
3526
3527 // SP_DockWindowCloseButton - close button on dock windows; see also QDockWindow.
3528 case SP_DockWindowCloseButton:
3529 return *qWarpSystemPixmaps.getPixmap(52, // should be a bit smaller!
3530 QWarpPixmap::bmp);
3531
3532 // SP_MessageBoxInformation - the 'information' icon.
3533 case SP_MessageBoxInformation:
3534 return *qWarpSystemPixmaps.getPixmap(SPTR_ICONINFORMATION,
3535 QWarpPixmap::ico);
3536
3537 // SP_MessageBoxWarning - the 'warning' icon.
3538 case SP_MessageBoxWarning:
3539 return *qWarpSystemPixmaps.getPixmap(SPTR_ICONWARNING,
3540 QWarpPixmap::ico);
3541
3542 // SP_MessageBoxCritical - the 'critical' icon.
3543 case SP_MessageBoxCritical:
3544 return *qWarpSystemPixmaps.getPixmap(SPTR_ICONERROR,
3545 QWarpPixmap::ico);
3546
3547 // SP_MessageBoxQuestion - the 'question' icon.
3548 case SP_MessageBoxQuestion:
3549 return *qWarpSystemPixmaps.getPixmap(SPTR_ICONQUESTION,
3550 QWarpPixmap::ico);
3551
3552 default:
3553 break;
3554 }
3555#endif //QT_NO_IMAGEIO_XPM
3556
3557 return QCommonStyle::stylePixmap(stylepixmap, widget, opt);
3558}
3559
3560/*!\reimp
3561*/
3562void QWarp4Style::drawComplexControl(ComplexControl ctrl, QPainter *p,
3563 QWidget const* widget,
3564 QRect const& r,
3565 QColorGroup const& cg,
3566 SFlags flags,
3567 SCFlags sub,
3568 SCFlags subActive,
3569 QStyleOption const& opt) const
3570{
3571 switch (ctrl)
3572 {
3573#ifndef QT_NO_SCROLLBAR
3574 case CC_ScrollBar:
3575 {
3576 QScrollBar const* scrollbar = (QScrollBar const*)widget;
3577 bool maxedOut = (scrollbar->minValue() == scrollbar->maxValue());
3578
3579 QRect subline = querySubControlMetrics(ctrl, widget, SC_ScrollBarSubLine, opt),
3580 addline = querySubControlMetrics(ctrl, widget, SC_ScrollBarAddLine, opt),
3581 subpage = querySubControlMetrics(ctrl, widget, SC_ScrollBarSubPage, opt),
3582 addpage = querySubControlMetrics(ctrl, widget, SC_ScrollBarAddPage, opt),
3583 slider = querySubControlMetrics(ctrl, widget, SC_ScrollBarSlider, opt);
3584 if(!scrollbar->isEnabled())
3585 {
3586 subpage.unite(addpage).unite(slider); // fill the whole, empty bar
3587 addpage = slider = QRect(); // invalid rectangle
3588 maxedOut = true; // to avoid setting the Style_Enabled flag
3589 }
3590 bool isMin = scrollbar->value() <= scrollbar->minValue(),
3591 isMax = scrollbar->value() >= scrollbar->maxValue();
3592
3593 if((sub & SC_ScrollBarSubLine) && subline.isValid())
3594 drawPrimitive(PE_ScrollBarSubLine, p, subline, cg,
3595 ((maxedOut || isMin) ? Style_Default : Style_Enabled) |
3596 ((!isMin && (subActive == SC_ScrollBarSubLine)) ? Style_Down : Style_Default) |
3597 ((scrollbar->orientation() == Qt::Horizontal) ? Style_Horizontal : 0));
3598 if((sub & SC_ScrollBarAddLine) && addline.isValid())
3599 drawPrimitive(PE_ScrollBarAddLine, p, addline, cg,
3600 ((maxedOut || isMax) ? Style_Default : Style_Enabled) |
3601 ((!isMax && (subActive == SC_ScrollBarAddLine)) ? Style_Down : Style_Default) |
3602 ((scrollbar->orientation() == Qt::Horizontal) ? Style_Horizontal : 0));
3603 if((sub & SC_ScrollBarSubPage) && subpage.isValid())
3604 drawPrimitive(PE_ScrollBarSubPage, p, subpage, cg,
3605 ((maxedOut) ? Style_Default : Style_Enabled) |
3606 ((subActive == SC_ScrollBarSubPage) ? Style_Down : Style_Default) |
3607 ((scrollbar->orientation() == Qt::Horizontal) ? Style_Horizontal : 0));
3608 if((sub & SC_ScrollBarAddPage) && addpage.isValid())
3609 drawPrimitive(PE_ScrollBarAddPage, p, addpage, cg,
3610 ((maxedOut) ? Style_Default : Style_Enabled) |
3611 ((subActive == SC_ScrollBarAddPage) ? Style_Down : Style_Default) |
3612 ((scrollbar->orientation() == Qt::Horizontal) ? Style_Horizontal : 0));
3613 if((sub & SC_ScrollBarSlider) && slider.isValid())
3614 drawPrimitive(PE_ScrollBarSlider, p, slider, cg,
3615 ((maxedOut) ? Style_Default : Style_Enabled) |
3616 ((subActive == SC_ScrollBarSlider) ? Style_Down : Style_Default) |
3617 ((scrollbar->orientation() == Qt::Horizontal) ? Style_Horizontal : 0));
3618
3619 break;
3620 }
3621#endif // QT_NO_SCROLLBAR
3622
3623 case CC_SpinWidget:
3624 {
3625#ifndef QT_NO_SPINWIDGET
3626 QSpinWidget const* sw = (QSpinWidget const*)widget;
3627 SFlags flags;
3628 PrimitiveElement pe;
3629
3630 if(sub & SC_SpinWidgetFrame)
3631 {
3632 qDrawWarpPanel(p, r, cg, -1);
3633 }
3634
3635 if((sub & SC_SpinWidgetUp) ||
3636 (sub & SC_SpinWidgetDown))
3637 {
3638 flags = Style_Enabled;
3639 if((subActive == SC_SpinWidgetUp) ||
3640 (subActive == SC_SpinWidgetDown))
3641 flags |= Style_Sunken;
3642 else
3643 flags |= Style_Raised;
3644
3645 // we "misuse" the On flag to indicate whether the
3646 // "up" part or the "down" part of the button is sunken
3647 if(subActive == SC_SpinWidgetUp)
3648 flags |= Style_On;
3649
3650 if(sub & SC_SpinWidgetUp)
3651 {
3652 if(sw->buttonSymbols() == QSpinWidget::PlusMinus)
3653 pe = PE_SpinWidgetPlus;
3654 else
3655 pe = PE_SpinWidgetUp;
3656 }
3657 else
3658 {
3659 if(sw->buttonSymbols() == QSpinWidget::PlusMinus)
3660 pe = PE_SpinWidgetMinus;
3661 else
3662 pe = PE_SpinWidgetDown;
3663 }
3664
3665 QRect re = sw->upRect();
3666 re.setWidth(re.width() - 2);
3667 bool reverse = QApplication::reverseLayout();
3668 if(!reverse)
3669 re.moveLeft(re.left() + 2);
3670 drawPrimitive(pe, p, re, cg, flags);
3671
3672 // doesn't work yet...
3673 int x = re.left() - 1;
3674 if(reverse)
3675 {
3676 x = re.right() + 2;
3677 p->setPen(cg.light());
3678 }
3679 else
3680 {
3681 p->setPen(cg.dark());
3682 }
3683 p->drawLine(x, re.top(), x, re.bottom());
3684 p->setPen(cg.button());
3685 x--;
3686 p->drawLine(x, re.top(), x, re.bottom());
3687 }
3688
3689 //if(sub & SC_SpinWidgetDown)
3690 //{
3691 // do nothing!
3692 // note: for the Warp style we put all the up/down button
3693 // functionality into the "up" button with the diagonal
3694 // separator
3695 //}
3696#endif
3697
3698 break;
3699 }
3700
3701#ifndef QT_NO_TOOLBUTTON
3702 case CC_ToolButton:
3703 {
3704 bool right;
3705 if((right = (QString("qt_right_btn") == widget->name())) ||
3706 (QString("qt_left_btn") == widget->name()))
3707 {
3708 QToolButton* tb = (QToolButton*)widget;
3709 QTabBar* ptb = (QTabBar*)tb->parentWidget();
3710 if((0 == ptb) || !ptb->inherits("QTabBar"))
3711 return;
3712 bool bottom = (QTabBar::RoundedBelow == ptb->shape()) ||
3713 (QTabBar::TriangularBelow == ptb->shape());
3714
3715 QRect r(visualRect(querySubControlMetrics(ctrl, widget, SC_ToolButton, opt), widget));
3716 if(right)
3717 r.addCoords(-3, 0, 0, 0);
3718 else
3719 r.addCoords(0, 0, 3, 0);
3720 p->setClipRect(r);
3721
3722 p->setPen(cg.dark());
3723 if(right)
3724 {
3725 if(bottom)
3726 p->drawLine(r.right(), r.top(), r.right(), r.top() + 3);
3727 else
3728 p->drawLine(r.right(), r.bottom(), r.right(), r.bottom() - 3);
3729 }
3730
3731 QRect tr1(r), tr2(r);
3732 if(right)
3733 {
3734 tr1.addCoords(-1, 0, 1, 0);
3735 tr2.addCoords(-21, 0, -21, 0);
3736 }
3737 else
3738 {
3739 tr1.addCoords(21, 0, 21, 0);
3740 tr2.addCoords(-1, 0, 1, 0);
3741 }
3742
3743 QColorGroup const& cg(tb->colorGroup());
3744 qDrawTabBar(p, tr1, cg, cg.background(), false, bottom);
3745 qDrawTabBar(p, tr2, cg, cg.background(), false, bottom);
3746
3747 if(bottom)
3748 r.addCoords(0, 2, 0, 2);
3749 QPointArray triang;
3750 if(right)
3751 {
3752 triang.putPoints(0, 3,
3753 r.left() + 8, r.top() + 6,
3754 r.left() + 19, r.top() + 12,
3755 r.left() + 8, r.top() + 18);
3756 }
3757 else
3758 {
3759 triang.putPoints(0, 3,
3760 r.right() - 10, r.top() + 6,
3761 r.right() - 21, r.top() + 12,
3762 r.right() - 10, r.top() + 18);
3763 }
3764 p->setBrush(QColor(0, 0, 255));
3765 p->setPen(QPen::NoPen);
3766 p->drawPolygon(triang);
3767 }
3768
3769 else
3770 {
3771 QCommonStyle::drawComplexControl(ctrl, p, widget, r, cg, flags, sub,
3772 subActive, opt);
3773 }
3774
3775 break;
3776 }
3777#endif // QT_NO_TOOLBUTTON
3778
3779#ifndef QT_NO_LISTVIEW
3780 case CC_ListView:
3781 {
3782 if(sub & SC_ListView)
3783 {
3784 QCommonStyle::drawComplexControl(ctrl, p, widget, r, cg, flags, sub, subActive, opt);
3785 }
3786
3787 if(sub & (SC_ListViewBranch | SC_ListViewExpand))
3788 {
3789 QListViewItem *item = opt.listViewItem(),
3790 *child = item->firstChild();
3791 QListView* v = item->listView();
3792 int y = r.y();
3793 int bx = r.width() / 2;
3794 int // linetop = 0,
3795 linebot = 0;
3796
3797 // skip the stuff above the exposed rectangle
3798 while(child && ((y + child->height()) <= 0))
3799 {
3800 y += child->totalHeight();
3801 child = child->nextSibling();
3802 }
3803
3804 // notes about drawing lines for Warp:
3805 // 1. Warp type lines follow a different logic than the "normal" lines
3806 // for "tree views" in Qt (which follows more or less Windows)
3807 // 2. In order to ensure partial repaints, it looks like we have to
3808 // draw some lines twice: once with the parent and once with the
3809 // child (and hopefully to the same place...)
3810
3811 while(child && (y < r.height()))
3812 {
3813 if(child->isVisible())
3814 {
3815 int lh;
3816 if(!item->multiLinesEnabled())
3817 lh = child->height();
3818 else
3819 lh = p->fontMetrics().height() + 2 * v->itemMargin();
3820 lh = QMAX(lh, QApplication::globalStrut().height());
3821 if((lh % 2) > 0)
3822 lh++;
3823 linebot = y + lh / 2;
3824 p->setPen(cg.shadow());
3825
3826 // parents and grandparents
3827 int vlx = bx - v->treeStepSize() + 2,
3828 vlyt = linebot - child->height() + 8,
3829 vlyb = linebot - child->height() + 9 + child->totalHeight();
3830 if(0 <= item->depth())
3831 {
3832 // vertical line for parent
3833 if(item->isOpen())
3834 {
3835 if(0 == child->nextSibling())
3836 p->drawLine(vlx, vlyt, vlx, linebot - 2);
3837 else
3838 p->drawLine(vlx, vlyt, vlx, vlyb);
3839 }
3840
3841 // vertical lines for grandparents and "older"
3842 QListViewItem* gp = item;
3843 while(0 < gp->depth())
3844 {
3845 gp = gp->parent();
3846 vlx -= v->treeStepSize();
3847 if(0 != gp->nextSibling())
3848 p->drawLine(vlx, vlyt, vlx, vlyb);
3849 }
3850 }
3851
3852 // draw child itself
3853 if((child->isExpandable() || child->childCount()) &&
3854 (child->height() > 0))
3855 {
3856 // horizontal line up to button
3857 if((0 <= item->depth()) && item->isOpen())
3858 {
3859 p->drawLine(bx - v->treeStepSize() + 3, linebot - 2,
3860 bx - 6, linebot - 2);
3861 }
3862
3863 // button
3864 QRect rr(bx - 6, linebot - 9, 16, 16);
3865 drawPrimitive(PE_ButtonCommand, p, rr, cg,
3866 Style_Raised | Style_ButtonDefault);
3867
3868 // plus or minus
3869 p->setPen(cg.light());
3870 p->drawLine(bx, linebot - 1, bx + 6, linebot - 1);
3871 if(!child->isOpen())
3872 p->drawLine(bx + 3, linebot + 2, bx + 3, linebot - 4);
3873 p->setPen(cg.shadow());
3874 p->drawLine(bx - 1, linebot - 2, bx + 5, linebot - 2);
3875 if(!child->isOpen())
3876 p->drawLine(bx + 2, linebot + 1, bx + 2, linebot - 5);
3877
3878 // lines below expanded child
3879 if(child->isOpen())
3880 {
3881 // vertical line
3882 p->drawLine(bx + 2,
3883 linebot + child->height() - 15,
3884 bx + 2,
3885 linebot + child->totalHeight() - child->height() - 2);
3886
3887 // horizontal lines at child's children
3888 QListViewItem* child2 = child->firstChild();
3889 int y2 = linebot + child->height() - 2;
3890 while(child2 && (y2 < r.height()))
3891 {
3892 if(child2->isVisible())
3893 {
3894 p->drawLine(bx + 2, y2,
3895 bx + v->treeStepSize() - 12, y2);
3896 y2 += child2->totalHeight();
3897 }
3898 child2 = child2->nextSibling();
3899 }
3900 }
3901 }
3902 else if((0 <= item->depth()) && item->isOpen())
3903 {
3904 // horizontal line without button
3905 p->setPen(cg.shadow());
3906 p->drawLine(bx - v->treeStepSize() + 3, linebot - 2,
3907 bx + 8, linebot - 2);
3908 }
3909
3910 y += child->totalHeight();
3911 }
3912 child = child->nextSibling();
3913 }
3914 }
3915
3916 break;
3917 }
3918#endif //QT_NO_LISTVIEW
3919
3920#ifndef QT_NO_COMBOBOX
3921 case CC_ComboBox:
3922 {
3923 if(sub & SC_ComboBoxFrame)
3924 {
3925 qDrawWarpPanel(p, r, cg, -1);
3926 p->setPen(cg.dark());
3927 int x = r.right() - 2 - 16;
3928 p->drawLine(x, r.top() + 2, x, r.bottom() - 2);
3929 }
3930
3931 if(sub & SC_ComboBoxArrow)
3932 {
3933 QRect ar = visualRect(querySubControlMetrics(CC_ComboBox, widget,
3934 SC_ComboBoxArrow),
3935 widget);
3936 QBrush fill = cg.brush(QColorGroup::Button);
3937 bool sunken = subActive == SC_ComboBoxArrow;
3938 qDrawWarpFilledRect(p, ar, cg.dark(), cg.light(), &fill, 2, sunken);
3939 p->setPen(cg.button());
3940 p->drawLine(ar.bottomLeft(), ar.topRight());
3941 QPixmap const* pm = qWarpSystemPixmaps.getPixmap(SBMP_COMBODOWN,
3942 QWarpPixmap::bmp);
3943 QPoint ppt = ar.topLeft() +
3944 QPoint((ar.width() - pm->width()) / 2,
3945 (ar.height() - pm->height()) / 2);
3946 p->drawPixmap(ppt, *pm);
3947 }
3948
3949 if(sub & SC_ComboBoxEditField)
3950 {
3951 QComboBox const* cb = (QComboBox const*)widget;
3952 QRect re = QStyle::visualRect(querySubControlMetrics(CC_ComboBox, widget,
3953 SC_ComboBoxEditField),
3954 widget);
3955 p->fillRect(re, cg.brush(QColorGroup::Base));
3956
3957 if(cb->hasFocus())
3958 {
3959 p->setPen(cg.highlightedText());
3960 p->setBackgroundColor(cg.highlight());
3961 }
3962 else
3963 {
3964 p->setPen(cg.text());
3965 p->setBackgroundColor(cg.background());
3966 }
3967
3968 if(cb->hasFocus() && !cb->editable())
3969 {
3970 re = QStyle::visualRect(subRect(SR_ComboBoxFocusRect, cb), widget);
3971 p->fillRect(re, cg.brush(QColorGroup::Highlight));
3972 }
3973 }
3974
3975 break;
3976 }
3977#endif // QT_NO_COMBOBOX
3978
3979#ifndef QT_NO_SLIDER
3980 case CC_Slider:
3981 {
3982 QSlider const* sl = (QSlider const*)widget;
3983 QRect groove = querySubControlMetrics(CC_Slider, widget, SC_SliderGroove, opt),
3984 handle = querySubControlMetrics(CC_Slider, widget, SC_SliderHandle, opt);
3985
3986 // reducing the handle length by 2 on each side
3987 if(sl->orientation() == Horizontal)
3988 {
3989 handle.setLeft(handle.left() + 2);
3990 handle.setRight(handle.right() - 2);
3991 }
3992 else
3993 {
3994 handle.setTop(handle.top() + 2);
3995 handle.setBottom(handle.bottom() - 2);
3996 }
3997
3998 if((sub & SC_SliderGroove) && groove.isValid())
3999 {
4000 if(sl->orientation() == Horizontal)
4001 {
4002 groove.setTop(groove.top() + 4);
4003 groove.setBottom(groove.bottom() - 4);
4004 }
4005 else
4006 {
4007 groove.setLeft(groove.left() + 4);
4008 groove.setRight(groove.right() - 4);
4009 }
4010
4011 qDrawWarpFilledRect(p, groove, cg.dark(), cg.light(),
4012 &cg.brush(QColorGroup::Button), 2, true);
4013
4014 groove.setTop(groove.top() + 2);
4015 groove.setLeft(groove.left() + 2);
4016 if(sl->orientation() == Horizontal)
4017 {
4018 groove.setRight(groove.right() - 2);
4019 groove.setBottom(groove.bottom() - 1);
4020 }
4021 else
4022 {
4023 groove.setRight(groove.right() - 1);
4024 groove.setBottom(groove.bottom() - 2);
4025 }
4026
4027 if(flags & Style_HasFocus)
4028 p->setPen(cg.shadow());
4029 else
4030 p->setPen(cg.dark());
4031
4032 p->drawRect(groove);
4033 }
4034
4035 if(sub & SC_SliderTickmarks)
4036 {
4037 int tickOffset = pixelMetric(PM_SliderTickmarkOffset, sl);
4038 int thickness = pixelMetric(PM_SliderControlThickness, sl);
4039 int len = pixelMetric(PM_SliderLength, sl);
4040 int ticks = sl->tickmarks();
4041 int available = pixelMetric(PM_SliderSpaceAvailable, sl);
4042 int interval = sl->tickInterval();
4043
4044 if(interval <= 0 )
4045 {
4046 interval = sl->lineStep();
4047 if((qPositionFromValue(sl, interval, available) -
4048 qPositionFromValue(sl, 0, available)) < 3)
4049 interval = sl->pageStep();
4050 }
4051
4052 int fudge = len / 2;
4053 int pos;
4054
4055 if(ticks & QSlider::Above)
4056 {
4057 if(sl->orientation() == Horizontal)
4058 p->fillRect(0, 0, sl->width(), tickOffset,
4059 cg.brush(QColorGroup::Background));
4060 else
4061 p->fillRect(0, 0, tickOffset, sl->width(),
4062 cg.brush(QColorGroup::Background));
4063 int v = sl->minValue();
4064 if (!interval)
4065 interval = 1;
4066 while(v <= sl->maxValue() + 1)
4067 {
4068 pos = qPositionFromValue(sl, v, available) + fudge;
4069 if(sl->orientation() == Horizontal)
4070 {
4071 p->setPen(cg.dark());
4072 p->drawLine(pos - 1, 0, pos - 1, tickOffset - 1);
4073 p->setPen(cg.light());
4074 p->drawLine(pos, 0, pos, tickOffset - 1);
4075 }
4076 else
4077 {
4078 p->setPen(cg.dark());
4079 p->drawLine(0, pos - 1, tickOffset - 1, pos - 1);
4080 p->setPen(cg.light());
4081 p->drawLine(0, pos, tickOffset - 1, pos);
4082 }
4083 v += interval;
4084 }
4085 }
4086
4087 if(ticks & QSlider::Below)
4088 {
4089 if(sl->orientation() == Horizontal)
4090 p->fillRect(0, tickOffset + thickness, sl->width(), tickOffset,
4091 cg.brush(QColorGroup::Background));
4092 else
4093 p->fillRect(tickOffset + thickness, 0, tickOffset, sl->height(),
4094 cg.brush(QColorGroup::Background));
4095 int v = sl->minValue();
4096 if(!interval)
4097 interval = 1;
4098 while(v <= sl->maxValue() + 1)
4099 {
4100 pos = qPositionFromValue(sl, v, available) + fudge;
4101 if(sl->orientation() == Horizontal)
4102 {
4103 p->setPen(cg.dark());
4104 p->drawLine(pos - 1, tickOffset + thickness + 1,
4105 pos - 1, tickOffset + thickness + 1 + available - 1);
4106 p->setPen(cg.light());
4107 p->drawLine(pos, tickOffset + thickness + 1,
4108 pos, tickOffset + thickness + 1 + available - 1);
4109 }
4110 else
4111 {
4112 p->setPen(cg.dark());
4113 p->drawLine(tickOffset + thickness + 1, pos - 1,
4114 tickOffset + thickness + 1 + available - 1, pos - 1);
4115 p->setPen(cg.light());
4116 p->drawLine(tickOffset + thickness + 1, pos,
4117 tickOffset + thickness + 1 + available - 1, pos);
4118 }
4119 v += interval;
4120 }
4121 }
4122 }
4123
4124 if(sub & SC_SliderHandle)
4125 {
4126 qDrawWarpFilledRect(p, handle, cg.dark(), cg.light(),
4127 &cg.brush(QColorGroup::Button), 2, false);
4128
4129 if(flags & Style_HasFocus)
4130 p->setPen(cg.shadow());
4131 else
4132 p->setPen(cg.dark());
4133
4134 if(sl->orientation() == Horizontal)
4135 p->drawLine(handle.topLeft() + QPoint(5, 2),
4136 handle.bottomLeft() + QPoint(5, -2));
4137 else
4138 p->drawLine(handle.topLeft() + QPoint(2, 5),
4139 handle.topRight() + QPoint(-2, 5));
4140
4141 p->setPen(cg.light());
4142
4143 if(sl->orientation() == Horizontal)
4144 p->drawLine(handle.topLeft() + QPoint(6, 2),
4145 handle.bottomLeft() + QPoint(6, -2));
4146 else
4147 p->drawLine(handle.topLeft() + QPoint(2, 6),
4148 handle.topRight() + QPoint(-2, 6));
4149 }
4150
4151 break;
4152 }
4153#endif // QT_NO_SLIDER
4154
4155 default:
4156 {
4157 QCommonStyle::drawComplexControl(ctrl, p, widget, r, cg, flags, sub,
4158 subActive, opt);
4159 break;
4160 }
4161 }
4162}
4163
4164/*! \reimp */
4165QRect QWarp4Style::querySubControlMetrics(ComplexControl control,
4166 QWidget const* widget,
4167 SubControl sc,
4168 QStyleOption const& opt) const
4169{
4170 switch(control)
4171 {
4172#ifndef QT_NO_SCROLLBAR
4173 case CC_ScrollBar:
4174 {
4175 QScrollBar const* scrollbar = (QScrollBar const*)widget;
4176 int sbextent = pixelMetric(PM_ScrollBarExtent, widget);
4177 int maxlen = ((scrollbar->orientation() == Qt::Horizontal) ?
4178 scrollbar->width() : scrollbar->height()) -
4179 (2 * 21); // 2 buttons incl. lines
4180 int sliderstart = scrollbar->sliderStart();
4181
4182 // calculate slider length
4183 int sliderlen;
4184 if(scrollbar->maxValue() != scrollbar->minValue())
4185 {
4186 uint range = scrollbar->maxValue() - scrollbar->minValue();
4187 sliderlen = (scrollbar->pageStep() * maxlen) /
4188 (range + scrollbar->pageStep());
4189 int slidermin = pixelMetric(PM_ScrollBarSliderMin, widget);
4190 if((sliderlen < slidermin) || (range > INT_MAX / 2))
4191 sliderlen = slidermin;
4192 if(sliderlen > maxlen)
4193 sliderlen = maxlen;
4194 }
4195 else
4196 {
4197 sliderlen = maxlen;
4198 }
4199
4200 // calculate button width (for vertical scroll bars this is the height)
4201 // note: the "button" includes the lines at the extreme ends of the sb
4202 int buttonWidth;
4203 if(scrollbar->orientation() == Qt::Horizontal)
4204 buttonWidth = QMIN(scrollbar->width() / 2, 21);
4205 else
4206 buttonWidth = QMIN(scrollbar->height() / 2, 21);
4207
4208 switch(sc)
4209 {
4210 case SC_ScrollBarSubLine: // top/left button
4211 {
4212 if(scrollbar->orientation() == Qt::Horizontal)
4213 return QRect(0, 0, buttonWidth, sbextent);
4214 else
4215 return QRect(0, 0, sbextent, buttonWidth);
4216 }
4217
4218 case SC_ScrollBarAddLine: // bottom/right button
4219 {
4220 if(scrollbar->orientation() == Qt::Horizontal)
4221 return QRect(scrollbar->width() - buttonWidth, 0,
4222 buttonWidth, sbextent);
4223 else
4224 return QRect(0, scrollbar->height() - buttonWidth,
4225 sbextent, buttonWidth);
4226 }
4227
4228 case SC_ScrollBarSubPage: // between top/left button and slider
4229 {
4230 if(scrollbar->orientation() == Qt::Horizontal)
4231 return QRect(buttonWidth, 0,
4232 sliderstart - buttonWidth, sbextent);
4233 else
4234 return QRect(0, buttonWidth,
4235 sbextent, sliderstart - buttonWidth);
4236 }
4237
4238 case SC_ScrollBarAddPage: // between bottom/right button and slider
4239 {
4240 if(scrollbar->orientation() == Qt::Horizontal)
4241 return QRect(sliderstart + sliderlen, 0,
4242 maxlen + buttonWidth - sliderstart - sliderlen, sbextent);
4243 else
4244 return QRect(0, sliderstart + sliderlen,
4245 sbextent, maxlen + buttonWidth - sliderstart - sliderlen);
4246 }
4247
4248 case SC_ScrollBarGroove:
4249 {
4250 if(scrollbar->orientation() == Qt::Horizontal)
4251 return QRect(buttonWidth, 0,
4252 scrollbar->width() - buttonWidth * 2, sbextent);
4253 else
4254 return QRect(0, buttonWidth,
4255 sbextent, scrollbar->height() - buttonWidth * 2);
4256 }
4257
4258 case SC_ScrollBarSlider:
4259 {
4260 if(scrollbar->orientation() == Qt::Horizontal)
4261 return QRect(sliderstart, 0, sliderlen, sbextent);
4262 else
4263 return QRect(0, sliderstart, sbextent, sliderlen);
4264 }
4265 }
4266
4267 break;
4268 }
4269#endif // QT_NO_SCROLLBAR
4270
4271 case CC_SpinWidget:
4272 {
4273 int fw = pixelMetric(PM_SpinBoxFrameWidth, widget);
4274 QSize bs;
4275 bs.setHeight(widget->height() - 2 * fw);
4276 if(bs.height() < 16)
4277 bs.setHeight(16);
4278 bs.setWidth(bs.height() + 2);
4279 bs = bs.expandedTo(QApplication::globalStrut());
4280 int bx = widget->width() - bs.width() - fw,
4281 by = fw;
4282
4283 switch(sc)
4284 {
4285 case SC_SpinWidgetUp:
4286 return QRect(bx, by, bs.width(), bs.height());
4287 case SC_SpinWidgetDown:
4288 return QRect(bx, by + bs.height(), bs.width(), 0);
4289 case SC_SpinWidgetButtonField:
4290 return QRect(bx, by, bs.width(), widget->height() - 2 * fw);
4291 case SC_SpinWidgetEditField:
4292 return QRect(fw, fw,
4293 widget->width() - bs.width() - 2 * fw,
4294 widget->height() - 2 * fw);
4295 case SC_SpinWidgetFrame:
4296 return widget->rect();
4297 default:
4298 break;
4299 }
4300
4301 break;
4302 }
4303
4304 case CC_ComboBox:
4305 {
4306 QRect r(widget->rect());
4307 int x = r.left(),
4308 y = r.top(),
4309 wi = r.width(),
4310 he = r.height();
4311 int xpos = x;
4312 xpos += wi - 2 - 16;
4313
4314 switch(sc)
4315 {
4316 case SC_ComboBoxFrame:
4317 return widget->rect();
4318 case SC_ComboBoxArrow:
4319 return QRect(xpos, y + 2, 16, he - 4);
4320 case SC_ComboBoxEditField:
4321 return QRect(x + 2, y + 2, wi - 5 - 16, he - 4);
4322 case SC_ComboBoxListBoxPopup:
4323 return opt.rect();
4324 default:
4325 break;
4326 }
4327 break;
4328 }
4329
4330 default:
4331 {
4332 return QCommonStyle::querySubControlMetrics(control, widget, sc, opt);
4333 }
4334 }
4335
4336 return QRect();
4337}
4338
4339/*! \reimp */
4340int QWarp4Style::styleHint(StyleHint hint,
4341 QWidget const* widget,
4342 QStyleOption const& opt,
4343 QStyleHintReturn *returnData) const
4344{
4345 int ret;
4346
4347 switch (hint)
4348 {
4349 case SH_EtchDisabledText:
4350 case SH_Slider_SnapToValue:
4351 case SH_PrintDialog_RightAlignButtons:
4352 case SH_FontDialog_SelectAssociatedText:
4353 case SH_MenuBar_AltKeyNavigation:
4354 case SH_MainWindow_SpaceBelowMenuBar:
4355 case SH_ScrollBar_StopMouseOverSlider:
4356 {
4357 ret = 1;
4358 break;
4359 }
4360
4361 case SH_MenuBar_MouseTracking:
4362 case SH_PopupMenu_MouseTracking:
4363 case SH_PopupMenu_AllowActiveAndDisabled:
4364 case SH_PopupMenu_SpaceActivatesItem:
4365 case SH_PopupMenu_Scrollable:
4366 case SH_PopupMenu_SloppySubMenus:
4367 case SH_PopupMenu_SubMenuPopupDelay:
4368 case SH_ComboBox_ListMouseTracking:
4369 case SH_ItemView_ChangeHighlightOnFocus:
4370 case SH_ToolBox_SelectedPageTitleBold:
4371 {
4372 ret = 0;
4373 break;
4374 }
4375
4376 case SH_GUIStyle:
4377 {
4378 // This value still exists from Qt 1.0 (as it seems), but is never
4379 // ever used in the current code! So the function of setting it
4380 // here is only to avoid using one of the other GUI styles still
4381 // being used (i.e., WindowsStyle and MotifStyle - which in turn are
4382 // also due to being removed entirely with some new Qt version...)
4383 // Note: currently it is being used to add some space to the left of
4384 // the menubar - as that space (another amount...) is also added
4385 // for other OS styles in QMenuBar.cpp (looks like an 1.0 inheritance!)
4386 ret = PMStyle;
4387 break;
4388 }
4389
4390 default:
4391 {
4392 ret = QCommonStyle::styleHint(hint, widget, opt, returnData);
4393 break;
4394 }
4395 }
4396
4397 return ret;
4398}
4399
4400/*! \reimp */
4401QRect QWarp4Style::subRect(SubRect r, QWidget const* widget) const
4402{
4403 QRect rect;
4404
4405 switch(r)
4406 {
4407 case SR_PushButtonFocusRect:
4408 case SR_CheckBoxFocusRect:
4409 case SR_RadioButtonFocusRect:
4410 {
4411 QButton const* button = (QButton const*)widget;
4412 if(!button->pixmap() && button->text().isEmpty())
4413 {
4414 switch(r)
4415 {
4416 case SR_PushButtonFocusRect:
4417 rect = QRect(widget->rect().center(), QSize(0, 0));
4418 break;
4419 case SR_CheckBoxFocusRect:
4420 rect = subRect(SR_CheckBoxIndicator, widget);
4421 break;
4422 case SR_RadioButtonFocusRect:
4423 rect = subRect(SR_RadioButtonIndicator, widget);
4424 break;
4425 }
4426 rect.addCoords(1, 1, -1, -1);
4427 break;
4428 }
4429 QPainter* p = new QPainter(button);
4430 QRect cr;
4431 switch(r)
4432 {
4433 case SR_PushButtonFocusRect:
4434 cr = subRect(SR_PushButtonContents, widget);
4435 break;
4436 case SR_CheckBoxFocusRect:
4437 cr = subRect(SR_CheckBoxContents, widget);
4438 break;
4439 case SR_RadioButtonFocusRect:
4440 cr = subRect(SR_RadioButtonContents, widget);
4441 break;
4442 }
4443 int align = ((SR_PushButtonFocusRect == r) ?
4444 Qt::AlignCenter | Qt::AlignVCenter :
4445 Qt::AlignLeft | Qt::AlignVCenter | Qt::ShowPrefix);
4446 rect = itemRect(p, cr, align,
4447 button->isEnabled(), button->pixmap(), button->text());
4448 delete p;
4449 rect.addCoords(-1, -1, 1, 1);
4450 rect = rect.intersect(widget->rect());
4451 break;
4452 }
4453
4454#ifndef QT_NO_SLIDER
4455 case SR_SliderFocusRect:
4456 {
4457 rect = widget->rect();
4458 break;
4459 }
4460#endif // QT_NO_SLIDER
4461
4462#ifndef QT_NO_PROGRESSBAR
4463 case SR_ProgressBarGroove:
4464 case SR_ProgressBarContents:
4465 {
4466 QFontMetrics fm((widget ? widget->fontMetrics() :
4467 QApplication::fontMetrics()));
4468 QProgressBar const* progressbar = (QProgressBar const*)widget;
4469 int textw = 0;
4470 if(progressbar->percentageVisible())
4471 textw = fm.width("100%") + 6;
4472
4473 // only change for Warp4 compared to "common": the style default
4474 // is "centered"
4475 QRect wrect(widget->rect());
4476 if(!progressbar->indicatorFollowsStyle() &&
4477 !progressbar->centerIndicator())
4478 rect.setCoords(wrect.left(), wrect.top(),
4479 wrect.right() - textw, wrect.bottom());
4480 else
4481 rect = wrect;
4482 break;
4483 }
4484
4485 case SR_ProgressBarLabel:
4486 {
4487 QFontMetrics fm((widget ? widget->fontMetrics() :
4488 QApplication::fontMetrics()));
4489 QProgressBar const* progressbar = (QProgressBar const*)widget;
4490 int textw = 0;
4491 if(progressbar->percentageVisible())
4492 textw = fm.width("100%") + 6;
4493
4494 // only change for Warp4 compared to "common": the style default
4495 // is "centered"
4496 QRect wrect(widget->rect());
4497 if(!progressbar->indicatorFollowsStyle() &&
4498 !progressbar->centerIndicator())
4499 rect.setCoords(wrect.right() - textw, wrect.top(),
4500 wrect.right(), wrect.bottom());
4501 else
4502 rect = wrect;
4503 break;
4504 }
4505#endif // QT_NO_PROGRESSBAR
4506
4507 case SR_ToolBoxTabContents:
4508 {
4509 rect = widget->rect();
4510 break;
4511 }
4512
4513 default:
4514 {
4515 rect = QCommonStyle::subRect(r, widget);
4516 break;
4517 }
4518 }
4519
4520 return rect;
4521}
4522
4523#include "qwarp4style.moc"
4524
4525#endif
Note: See TracBrowser for help on using the repository browser.