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

Last change on this file since 180 was 179, checked in by dmik, 18 years ago

styles/Warp4: Remove '&' from tab's caption when drawing it in the tab pane's header (#9).

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