Salome HOME
SMH: Add again in binary mode
[modules/gui.git] / src / Style / SalomeStyle.cxx
1 #include "SalomeStyle.h"\r
2 \r
3 #include <qimage.h>\r
4 #include <qcursor.h>\r
5 #include <qtabbar.h>\r
6 #include <qpalette.h>\r
7 #include <qtoolbar.h>\r
8 #include <qspinbox.h>\r
9 #include <qpainter.h>\r
10 #include <qlineedit.h>\r
11 #include <qlistview.h>\r
12 #include <qdrawutil.h>\r
13 #include <qpopupmenu.h>\r
14 #include <qpushbutton.h>\r
15 #include <qobjectlist.h>\r
16 #include <qtoolbutton.h>\r
17 #include <qapplication.h>\r
18 \r
19 static const char* const hole_xpm[] = {\r
20 "3 3 3 1",\r
21 ". c None",\r
22 "a c #999999",\r
23 "b c #FFFFFF",\r
24 "aa.",\r
25 "aab",\r
26 ".bb"\r
27 };\r
28 \r
29 static const char* const cross_xpm[] = {\r
30 "12 12 4 1",\r
31 ". c None",\r
32 "a c #000000",\r
33 "b c #FFFFFF",\r
34 "c c #666666",\r
35 "............",\r
36 "............",\r
37 "............",\r
38 ".aaaa..aaaa.",\r
39 "..abbaabba..",\r
40 "...abbbba...",\r
41 "....abba....",\r
42 "...abbbba...",\r
43 "..abbaabba..",\r
44 ".aaaa..aaaa.",\r
45 "............",\r
46 "............"\r
47 };\r
48 \r
49 static const char* const maximize_xpm[] = {\r
50 "12 12 4 1",\r
51 ". c None",\r
52 "a c #000000",\r
53 "b c #FFFFFF",\r
54 "c c #666666",\r
55 "............",\r
56 ".aaaaaaaaaa.",\r
57 ".acccccccca.",\r
58 ".acccccccca.",\r
59 ".abbbbbbbba.",\r
60 ".abbbbbbbba.",\r
61 ".abbbbbbbba.",\r
62 ".abbbbbbbba.",\r
63 ".abbbbbbbba.",\r
64 ".abbbbbbbba.",\r
65 ".aaaaaaaaaa.",\r
66 "............"\r
67 };\r
68 \r
69 static const char* const normal_xpm[] = {\r
70 "12 12 4 1",\r
71 ". c None",\r
72 "a c #000000",\r
73 "b c #FFFFFF",\r
74 "c c #666666",\r
75 "............",\r
76 "...aaaaaaaa.",\r
77 "...acccccca.",\r
78 "...abbbbbba.",\r
79 "...aaaaaaba.",\r
80 ".aaaaaaaaba.",\r
81 ".accccccaba.",\r
82 ".abbbbbbaaa.",\r
83 ".abbbbbba...",\r
84 ".abbbbbba...",\r
85 ".aaaaaaaa...",\r
86 "............"\r
87 };\r
88 \r
89 static const char* const minimize_xpm[] = {\r
90 "12 12 4 1",\r
91 ". c None",\r
92 "a c #000000",\r
93 "b c #FFFFFF",\r
94 "c c #666666",\r
95 "............",\r
96 "............",\r
97 "............",\r
98 "............",\r
99 "............",\r
100 "............",\r
101 "............",\r
102 "............",\r
103 "aaaaaaaaaaaa",\r
104 "abbbbbbbbbba",\r
105 "aaaaaaaaaaaa",\r
106 "............"\r
107 };\r
108 \r
109 /*!\r
110     Class: SalomeStyle [Public]\r
111     Descr: Style for SALOME platform\r
112 */\r
113 \r
114 SalomeStyle::SalomeStyle()\r
115 : myTitleParent( 0 )\r
116 {\r
117   qApp->installEventFilter( this ); \r
118 }\r
119 \r
120 SalomeStyle::~SalomeStyle()\r
121 {\r
122 }\r
123 \r
124 void SalomeStyle::polish( QWidget* w )\r
125 {\r
126   if ( !w )\r
127     return;\r
128 /*\r
129   if ( w->inherits( "QLineEdit" ) )\r
130   {\r
131     QLineEdit* fr = (QLineEdit*)w;\r
132     if ( w->parentWidget() && w->parentWidget()->inherits( "QSpinWidget" ) )\r
133       fr->setFrameStyle( QFrame::Plain );\r
134     else\r
135     {\r
136       fr->setFrameStyle( QFrame::Plain | QFrame::Box );\r
137       fr->setLineWidth( 1 );\r
138       fr->setMidLineWidth( 0 );\r
139     }\r
140   }\r
141   else\r
142 */\r
143   if ( w->inherits( "QToolBar" ) )\r
144   {\r
145     QToolBar* tb = (QToolBar*)w;\r
146     tb->setFrameStyle( QFrame::ToolBarPanel | QFrame::Plain );\r
147     tb->setLineWidth( 1 );\r
148     tb->setMidLineWidth( 1 );\r
149   }\r
150   else\r
151   if ( w->inherits( "QDockWindow" ) )\r
152   {\r
153     QDockWindow* dw = (QDockWindow*)w;\r
154     dw->setFrameStyle( QFrame::ToolBarPanel | QFrame::Raised );\r
155   }\r
156 /*\r
157   else if ( w->inherits( "QListView" ) )\r
158   {\r
159     QListView* lv = (QListView*)w;\r
160     lv->setFrameStyle( QFrame::Box | QFrame::Plain );\r
161   }\r
162 */\r
163   else\r
164     PARENT_STYLE::polish( w );\r
165 }\r
166 \r
167 bool SalomeStyle::eventFilter( QObject* o, QEvent* e )\r
168 {\r
169   if ( e->type() == QEvent::FocusIn || e->type() == QEvent::FocusOut )\r
170   {\r
171     QDockWindow* wnd = NULL;\r
172     while( o && !wnd )\r
173       if( o->inherits( "QDockWindow" ) )\r
174         wnd = ( QDockWindow* )o;\r
175       else\r
176         o = o->parent();\r
177 \r
178     if ( wnd )\r
179     {\r
180       const QObjectList* objList = o->children();\r
181       for( QObjectListIterator anIt( *objList ); anIt.current(); ++anIt )\r
182         if( anIt.current()->inherits( "QDockWindowHandle" ) )\r
183         {\r
184           QWidget* ww = ( QWidget* )anIt.current();\r
185           ww->repaint( ww->rect() );\r
186           const QObjectList* wc = ww->children();\r
187           for( QObjectListIterator anIt2( *wc ); anIt2.current(); ++anIt2 )\r
188             if( anIt2.current()->inherits( "QToolButton" ) )\r
189             {\r
190               QWidget* tb = ( QWidget* )anIt2.current();\r
191               tb->repaint( tb->rect() );\r
192             }\r
193         }      \r
194     }\r
195   }\r
196 \r
197   if ( o && o->inherits( "QPushButton" ) && ( e->type() == QEvent::Enter || e->type() == QEvent::Leave ) )\r
198     ((QWidget*)o)->update();\r
199 \r
200   return false;\r
201 }\r
202 \r
203 double linear( double x )\r
204 {\r
205   return x;\r
206 }\r
207 \r
208 void SalomeStyle::mix( const double t, const QColor& c1, const QColor& c2, QColor& res )\r
209 {\r
210   if( t<0.0 || t>1.0 )\r
211     return;\r
212 \r
213   int r = int( c1.red() * (1-t) + c2.red() * t ),\r
214       g = int( c1.green() * (1-t) + c2.green() * t ),\r
215       b = int( c1.blue() * (1-t) + c2.blue() * t );\r
216   res.setRgb( r, g, b );\r
217 }\r
218 \r
219 void SalomeStyle::mix( const double t, QRgb& rgb1, const QRgb& rgb2 )\r
220 {\r
221   if( t<0.0 || t>1.0 )\r
222     return;\r
223 \r
224   int c[2][4] = { qRed( rgb1 ), qGreen( rgb1 ), qBlue( rgb1 ), qAlpha( rgb1 ),\r
225                   qRed( rgb2 ), qGreen( rgb2 ), qBlue( rgb2 ), qAlpha( rgb2 ) };\r
226   for( int i=0; i<4; i++ )\r
227     c[0][i] = c[0][i] * (1-t) + c[1][i] * t;\r
228 \r
229   rgb1 = qRgba( c[0][0], c[0][1], c[0][2], qAlpha( rgb1 ) );\r
230 }\r
231 \r
232 void SalomeStyle::mix( const double t, QPixmap& pix, const QColor& col )\r
233 {\r
234   if( t<0.0 || t>1.0 )\r
235     return;\r
236 \r
237   QImage anImage = pix.convertToImage();\r
238   if( anImage.isNull() )\r
239     return;\r
240 \r
241   if( anImage.depth()!=32 )\r
242     anImage = anImage.convertDepth( 32 );\r
243 \r
244   int w = anImage.width(),\r
245       h = anImage.height();\r
246 \r
247   QRgb colrgb = col.rgb(), cur;\r
248   for( int y=0; y<h; y++ )\r
249   {\r
250     uchar* line = anImage.scanLine( y );\r
251     QRgb*  colorline = ( QRgb* ) line;\r
252     for( int x=0; x<w; x++ )\r
253     {\r
254       cur = colorline[ x ];\r
255       mix( t, cur, colrgb );\r
256       colorline[ x ] = cur;\r
257     }\r
258   }\r
259   pix = anImage;\r
260 }\r
261 \r
262 void SalomeStyle::toGrayscale( QPixmap& pix, double k )\r
263 {\r
264   QImage anImage = pix.convertToImage();\r
265   if( anImage.isNull() )\r
266     return;\r
267 \r
268   if( anImage.depth()!=32 )\r
269     anImage = anImage.convertDepth( 32 );\r
270 \r
271   int w = anImage.width(),\r
272       h = anImage.height();\r
273 \r
274   for( int y=0; y<h; y++ )\r
275   {\r
276     uchar* line = anImage.scanLine( y );\r
277     QRgb*  colorline = ( QRgb* ) line;\r
278     for( int x=0; x<w; x++ )\r
279     {\r
280       int gray = k*qGray( colorline[ x ] );\r
281       if( gray>255 )\r
282         gray = 255;\r
283       else if( gray<0 )\r
284         gray = 0;\r
285       colorline[ x ] = qRgba( gray, gray, gray, qAlpha( colorline[x] ) );\r
286     }\r
287   }\r
288   pix = anImage;\r
289 }\r
290 \r
291 void SalomeStyle::drawGradient( QPainter* p, const QRect& r,\r
292                                     const QColor& c1, const QColor& c2,\r
293                                     const Direction d, gradient_func f ) const \r
294 {\r
295   p->save();\r
296   p->translate( r.x(), r.y() );\r
297 \r
298   QColor mid;\r
299   if( d==LeftToRight || d==RightToLeft )\r
300     for( int xmax = r.width(), x = d==LeftToRight ? 0 : xmax;\r
301          d==LeftToRight ? x<=xmax : x>=0;\r
302          d==LeftToRight ? x++ : x-- )\r
303     {\r
304       double t = double( x ) / double( xmax );\r
305       mix( d==LeftToRight ? f(t) : 1-f(t), c1, c2, mid );\r
306       p->setPen( mid );\r
307       p->drawLine( x, 0, x, r.height() );\r
308     }\r
309   else\r
310     for( int ymax = r.height(), y = d==UpToDown ? 0 : ymax;\r
311          d==UpToDown ? y<=ymax : y>=0;\r
312          d==UpToDown ? y++ : y-- )\r
313     {\r
314       double t = double( y ) / double( ymax );\r
315       mix( d==UpToDown ? f(t) : 1-f(t), c1, c2, mid );\r
316       p->setPen( mid );\r
317       p->drawLine( 0, y, r.width(), y );\r
318     }\r
319 \r
320   p->restore();\r
321 }\r
322 \r
323 void SalomeStyle::drawPrimitive( PrimitiveElement pe, QPainter* p, const QRect& r,\r
324                                                          const QColorGroup& cg, SFlags flags, const QStyleOption& opt ) const\r
325 {\r
326   switch ( pe )\r
327   {\r
328   case PE_ButtonTool:\r
329     if ( !myTitleParent )\r
330       PARENT_STYLE::drawPrimitive( pe, p, r, cg, flags, opt );\r
331     break;\r
332 \r
333   case PE_DockWindowResizeHandle:\r
334     p->fillRect( r.x(), r.y(), r.width(), r.height(), cg.dark() );\r
335     if ( flags & Style_Horizontal )\r
336       p->fillRect( r.x(), r.y() + 1, r.width(), r.height() - 2, cg.midlight() );\r
337     else\r
338       p->fillRect( r.x() + 1, r.y(), r.width() - 2, r.height(), cg.midlight() );\r
339     break;\r
340 \r
341   case PE_DockWindowHandle:\r
342     {\r
343       QPaintDevice* pd = p->device();\r
344       if ( !pd )\r
345         break;\r
346 \r
347       QWidget* w = (QWidget*)pd;\r
348 \r
349       if ( !w || !w->inherits( "QDockWindowHandle" ) )\r
350         break;\r
351 \r
352       QDockWindow* wnd = ( QDockWindow* ) w->parent();\r
353       if ( !wnd )\r
354         return;\r
355 \r
356       QObject* activeWidget = qApp->focusWidget();\r
357       QDockWindow* activeWnd = 0;\r
358       while ( !activeWnd && activeWidget )\r
359       {\r
360         if ( activeWidget->inherits( "QDockWindow" ) )\r
361           activeWnd = (QDockWindow*)activeWidget;\r
362         else\r
363           activeWidget = activeWidget->parent();\r
364       }\r
365 \r
366             bool act = wnd == activeWnd, horiz = flags & Style_Horizontal;\r
367 \r
368       QPixmap hole( (const char**)hole_xpm );\r
369 \r
370       if ( wnd->inherits( "QToolBar" ) )\r
371       {\r
372         drawGradient( p, r, cg.light(), cg.background(), horiz ? UpToDown : LeftToRight, linear );\r
373 \r
374         int c = 4, i; double d = ( horiz ? r.height() : r.width() ) / (c+1);\r
375         QBrush fill = cg.brush( QColorGroup::Dark );\r
376         p->setPen( Qt::red );\r
377         for ( i = 0; i < c; i++ )\r
378         {\r
379           if ( horiz )\r
380             p->drawPixmap( r.x()+r.width()/2-1, r.y()+(i+1)*d-1, hole );\r
381           else\r
382             p->drawPixmap( r.x()+(i+1)*d-1, r.y()+r.height()/2-1, hole );\r
383         }\r
384 \r
385         int dd = (int(d)/2) + (int(d)%2);\r
386         for ( i = 0; i < c - 1; i++ )\r
387         {\r
388           if ( horiz )\r
389             p->drawPixmap( r.x()+r.width()/2+2, r.y()+dd+(i+1)*d-1, hole );\r
390           else\r
391             p->drawPixmap( r.x()+dd+(i+1)*d-1, r.y()+r.height()/2+2, hole );\r
392         }\r
393       }\r
394       else\r
395       {\r
396         int d = 1;\r
397         QRect rr( r.x()+d, r.y()+d, r.width()-2*d, r.height()-2*d );\r
398 \r
399         QColor col; \r
400         if ( act )\r
401           mix( 0.5, cg.highlight(), Qt::white, col );\r
402         else\r
403           col = cg.background();\r
404 \r
405         drawGradient( p, rr, act ? cg.highlight() : cg.dark(), col,\r
406                       horiz ? LeftToRight : UpToDown, linear );\r
407       }\r
408       break;\r
409     }\r
410 \r
411   case PE_DockWindowSeparator:\r
412     {\r
413       bool horiz = ( flags & Style_Horizontal );\r
414       QWidget* w = ( QWidget* )p->device();\r
415       if( w->inherits( "QToolBarSeparator" ) )\r
416       {\r
417         drawGradient( p, r, cg.light(), cg.background(), horiz ? UpToDown : LeftToRight, linear );\r
418         int w = r.width(), h = r.height();\r
419         int part = 8;\r
420 \r
421         p->setPen( cg.dark() );\r
422         if( horiz )\r
423           p->drawLine( r.x() + w/2, r.y() + h/part, r.x() + w/2, r.y() + (part-1)*h/part );\r
424         else\r
425           p->drawLine( r.x() + w/part, r.y() + h/2, r.x() + (part-1)*w/part, r.y() + h/2 );\r
426 \r
427         p->setPen( cg.light() );\r
428         if( horiz )\r
429           p->drawLine( r.x() + w/2 + 1, r.y() + h/part + 1, r.x() + w/2 + 1, r.y() + (part-1)*h/part + 1 );\r
430         else\r
431           p->drawLine( r.x() + w/part + 1, r.y() + h/2 + 1, r.x() + (part-1)*w/part + 1, r.y() + h/2 + 1 );\r
432       }\r
433       else\r
434         PARENT_STYLE::drawPrimitive( pe, p, r, cg, flags, opt );\r
435       break;\r
436     }\r
437     \r
438   case PE_PanelDockWindow:\r
439     {\r
440       QWidget* w = ( QWidget* )p->device();\r
441 \r
442       int offset = pixelMetric( PM_DockWindowHandleExtent, w );\r
443       if ( w->inherits( "QToolBar" ) )\r
444       {\r
445         bool vert = ( ( QToolBar* )w )->orientation() == Qt::Vertical;\r
446         if ( vert )\r
447           drawGradient( p, QRect( r.x(), r.y()+offset, r.x()+r.width(), r.y()+offset ),\r
448                         cg.light(), cg.background(), LeftToRight, linear );\r
449         else\r
450           drawGradient( p, QRect( r.x()+offset, r.y(), r.x()+offset, r.y()+r.height() ),\r
451                         cg.light(), cg.background(), UpToDown, linear );\r
452 \r
453         p->setPen( QPen( cg.light(), 1 ) );\r
454         p->drawRect( r );\r
455       }\r
456       else\r
457       {\r
458         p->setPen( QPen( cg.dark(), 1 ) );\r
459         p->setBrush( cg.light() );\r
460         p->drawRect( r );\r
461       }\r
462 \r
463       break;\r
464     }\r
465 \r
466   case PE_PanelPopup:\r
467     p->setPen( QPen( cg.dark(), 1 ) );\r
468     p->setBrush( cg.light() );\r
469     p->drawRect( r );\r
470     break;\r
471 \r
472   case PE_HeaderSection:\r
473     {\r
474       QColor col; mix( 0.2, cg.light(), Qt::black, col );\r
475       drawGradient( p, r, cg.light(), col, DownToUp, linear );\r
476       drawGradient( p, QRect( r.x(), r.y(), 1, r.height() ), cg.light(), cg.dark(), DownToUp, linear );\r
477       p->setPen( cg.dark() );\r
478       p->drawLine( r.x(), r.y()+r.height()-1, r.x()+r.width(), r.y()+r.height()-1 );\r
479       break;\r
480     }\r
481 \r
482   case PE_Splitter:\r
483     p->fillRect( r.x() + 1, r.y() + 1, r.width() - 2, r.height() - 2, cg.dark() );\r
484     p->fillRect( r.x() + 2, r.y() + 2, r.width() - 4, r.height() - 4, cg.midlight() );\r
485           break;\r
486 \r
487   case PE_ButtonBevel:\r
488     PARENT_STYLE::drawPrimitive( PE_ButtonDropDown, p, r, cg, flags, opt );\r
489     break;\r
490 \r
491   case PE_ButtonCommand:\r
492     {\r
493       QColorGroup cGrp( cg );\r
494       if ( flags & Style_MouseOver )\r
495         cGrp.setColor( QColorGroup::Button, cGrp.midlight() );\r
496 \r
497       if ( flags & Style_MouseOver )\r
498         PARENT_STYLE::drawPrimitive( PE_ButtonDropDown, p, r, cGrp, flags, opt );\r
499       else\r
500         PARENT_STYLE::drawPrimitive( flags & Style_Raised ? PE_ButtonDropDown : pe, p, r, cGrp, flags, opt );\r
501     }\r
502     break;\r
503 \r
504   default:\r
505     PARENT_STYLE::drawPrimitive( pe, p, r, cg, flags, opt );\r
506     break;\r
507   }\r
508 }\r
509 \r
510 void SalomeStyle::drawControl( ControlElement element, QPainter* p, const QWidget* widget, const QRect& r,\r
511                                const QColorGroup& cg, SFlags flags, const QStyleOption& opt ) const \r
512 {\r
513   switch( element )\r
514   {\r
515     case CE_PopupMenuItem:\r
516     {\r
517           if(! widget || opt.isDefault())\r
518             break;\r
519 \r
520       const QPopupMenu *popupmenu = (const QPopupMenu *) widget;\r
521       QMenuItem *mi = opt.menuItem();\r
522       if( !mi )\r
523             break;\r
524 \r
525           int tab = opt.tabWidth();\r
526           int maxpmw = opt.maxIconWidth();\r
527           bool dis = !( flags & Style_Enabled );\r
528           bool checkable = popupmenu->isCheckable();\r
529           bool act = flags & Style_Active;\r
530       bool use2000style = true;\r
531           int x, y, w, h;\r
532 \r
533       int windowsItemFrame = 2,\r
534           windowsItemHMargin = 5,\r
535           windowsItemVMargin = 1,\r
536           windowsRightBorder = 2,\r
537           windowsArrowHMargin = 2;\r
538 \r
539           r.rect(&x, &y, &w, &h);\r
540 \r
541           if ( checkable )\r
542       {\r
543             // space for the checkmarks\r
544         if (use2000style)\r
545                   maxpmw = QMAX( maxpmw, 20 );\r
546                 else\r
547                   maxpmw = QMAX( maxpmw, 12 );\r
548           }\r
549 \r
550           int checkcol = maxpmw;\r
551 \r
552           if ( mi && mi->isSeparator() )\r
553       {\r
554                 p->setPen( cg.dark() );\r
555                 p->drawLine( x+3*checkcol/2, y, x+w, y );\r
556                 //p->setPen( cg.light() );\r
557                 //p->drawLine( x, y+1, x+w, y+1 );\r
558                 return;\r
559           }\r
560 \r
561       QBrush fill = ( act && !dis ?\r
562                  cg.brush( QColorGroup::Highlight ) :\r
563                          cg.brush( QColorGroup::Light ) );\r
564           p->fillRect( x, y, w, h, fill );\r
565 \r
566           if( !mi )\r
567                 return;\r
568 \r
569           int xpos = x;\r
570           QRect vrect = visualRect( QRect( xpos, y, checkcol, h ), r );\r
571           int xvis = vrect.x();\r
572 \r
573           if( mi->isChecked() )\r
574       {\r
575             if( act && !dis )\r
576                   qDrawShadePanel( p, xvis, y, checkcol, h,\r
577                            cg, TRUE, 1, &cg.brush( QColorGroup::Button ) );\r
578                 else\r
579         {\r
580                   QBrush fill( cg.light(), Dense4Pattern );\r
581                   // set the brush origin for the hash pattern to the x/y coordinate\r
582                   // of the menu item's checkmark... this way, the check marks have\r
583                   // a consistent look\r
584                   QPoint origin = p->brushOrigin();\r
585                   p->setBrushOrigin( xvis, y );\r
586                   qDrawShadePanel( p, xvis, y, checkcol, h, cg, TRUE, 1, &fill );\r
587           // restore the previous brush origin\r
588                   p->setBrushOrigin( origin );\r
589                 }\r
590           }\r
591       else if( !act )\r
592                 p->fillRect(x+checkcol, y, w-checkcol , h, cg.brush( QColorGroup::Light ));\r
593 \r
594       if( !( act && !dis ) && !mi->isChecked() )\r
595       {\r
596         QColor col; mix( 0.5, cg.mid(), Qt::white, col );\r
597         drawGradient( p, QRect( xvis, y, checkcol, h+1 ), cg.light(), col, LeftToRight, linear );\r
598       }\r
599 \r
600       if( mi->iconSet() )\r
601       { // draw iconset\r
602                 QIconSet::Mode mode = dis ? QIconSet::Active : QIconSet::Normal;\r
603                 if(act && !dis )\r
604                   mode = QIconSet::Active;\r
605                 QPixmap pixmap;\r
606                 if( checkable && mi->isChecked() )\r
607                   pixmap = mi->iconSet()->pixmap( QIconSet::Small, mode, QIconSet::On );\r
608                 else\r
609                   pixmap = mi->iconSet()->pixmap( QIconSet::Small, mode );\r
610                 int pixw = pixmap.width();\r
611                 int pixh = pixmap.height();\r
612 \r
613         if( dis )\r
614           toGrayscale( pixmap, 1.1 );\r
615 \r
616                 //if( act && !dis && !mi->isChecked() )\r
617                 //  qDrawShadePanel( p, xvis, y, checkcol, h, cg, FALSE, 1, &cg.brush( QColorGroup::Button ) );\r
618 \r
619                 QRect pmr( 0, 0, pixw, pixh );\r
620                 pmr.moveCenter( vrect.center() );\r
621                 p->setPen( cg.text() );\r
622                 p->drawPixmap( pmr.topLeft(), pixmap );\r
623 \r
624                 QBrush fill = ( act ? cg.brush( QColorGroup::Highlight ) : cg.brush( QColorGroup::Light ));\r
625                 int xp = xpos + checkcol + 1;\r
626         if( !dis )\r
627                   p->fillRect( visualRect( QRect( xp, y, w - checkcol - 1, h ), r ), fill);\r
628           }\r
629       else if( checkable )\r
630       {  // just "checking"...\r
631                 if( mi->isChecked() )\r
632         {\r
633                   int xp = xpos + windowsItemFrame;\r
634 \r
635                   SFlags cflags = Style_Default;\r
636                   if( !dis )\r
637                     cflags |= Style_Enabled;\r
638                   if( act )\r
639                         cflags |= Style_On;\r
640 \r
641                   drawPrimitive( PE_CheckMark, p,\r
642                                          visualRect( QRect( xp, y + windowsItemFrame,\r
643                                              checkcol - 2*windowsItemFrame,\r
644                                              h - 2*windowsItemFrame), r ), cg, cflags, opt );\r
645                 }\r
646           }\r
647 \r
648           p->setPen( act ? cg.highlightedText() : cg.buttonText() );\r
649 \r
650           QColor discol;\r
651           if( dis )\r
652       {\r
653                 discol = cg.text();\r
654                 p->setPen( discol );\r
655           }\r
656 \r
657           int xm = windowsItemFrame + checkcol + windowsItemHMargin;\r
658           xpos += xm;\r
659 \r
660           vrect = visualRect( QRect( xpos, y+windowsItemVMargin, w-xm-tab+1, h-2*windowsItemVMargin ), r );\r
661           xvis = vrect.x();\r
662           if( mi->custom() )\r
663       {\r
664                 p->save();\r
665                 if ( dis && !act )\r
666         {\r
667                   p->setPen( cg.light() );\r
668                   mi->custom()->paint( p, cg, act, !dis,\r
669                                                    xvis+1, y+windowsItemVMargin+1,\r
670                                w-xm-tab+1, h-2*windowsItemVMargin );\r
671                   p->setPen( discol );\r
672                 }\r
673                 mi->custom()->paint( p, cg, act, !dis, xvis, y+windowsItemVMargin,\r
674                              w-xm-tab+1, h-2*windowsItemVMargin );\r
675                 p->restore();\r
676           }\r
677           QString s = mi->text();\r
678           if( !s.isNull() )\r
679       { // draw text\r
680                 int t = s.find( '\t' );\r
681                 int text_flags = AlignVCenter | ShowPrefix | DontClip | SingleLine;\r
682                 if( !styleHint( SH_UnderlineAccelerator, widget ) )\r
683                   text_flags |= NoAccel;\r
684                 text_flags |= (QApplication::reverseLayout() ? AlignRight : AlignLeft );\r
685                 if( t >= 0 )\r
686         { // draw tab text\r
687                   int xp = x + w - tab - windowsItemHMargin - windowsItemFrame + 1;\r
688                   if( use2000style )\r
689                     xp -= 20;\r
690                   else\r
691                         xp -= windowsRightBorder;\r
692                   int xoff = visualRect( QRect( xp, y+windowsItemVMargin, tab, h-2*windowsItemVMargin ), r ).x();\r
693                   if( dis && !act )\r
694           {\r
695                         p->setPen( cg.light() );\r
696                         p->drawText( xoff+1, y+windowsItemVMargin+1, tab, h-2*windowsItemVMargin, text_flags, s.mid( t+1 ));\r
697                         p->setPen( discol );\r
698                   }\r
699                   p->drawText( xoff, y+windowsItemVMargin, tab, h-2*windowsItemVMargin, text_flags, s.mid( t+1 ) );\r
700                   s = s.left( t );\r
701                 }\r
702                 if( dis && !act )\r
703         {\r
704                   p->setPen( cg.light() );\r
705                   p->drawText( xvis+1, y+windowsItemVMargin+1, w-xm-tab+1, h-2*windowsItemVMargin, text_flags, s, t );\r
706                   p->setPen( discol );\r
707                 }\r
708                 p->drawText( xvis, y+windowsItemVMargin, w-xm-tab+1, h-2*windowsItemVMargin, text_flags, s, t );\r
709           }\r
710       else if( mi->pixmap() )\r
711       { // draw pixmap\r
712                 QPixmap *pixmap = mi->pixmap();\r
713                 if( pixmap->depth() == 1 )\r
714                   p->setBackgroundMode( OpaqueMode );\r
715                 p->drawPixmap( xvis, y+windowsItemFrame, *pixmap );\r
716                 if( pixmap->depth() == 1 )\r
717                   p->setBackgroundMode( TransparentMode );\r
718           }\r
719           if( mi->popup() )\r
720       { // draw sub menu arrow\r
721                 int dim = (h-2*windowsItemFrame) / 2;\r
722                 PrimitiveElement arrow;\r
723                 arrow = ( QApplication::reverseLayout() ? PE_ArrowLeft : PE_ArrowRight );\r
724                 xpos = x+w - windowsArrowHMargin - windowsItemFrame - dim;\r
725                 vrect = visualRect( QRect(xpos, y + h / 2 - dim / 2, dim, dim), r );\r
726                 if( act )\r
727         {\r
728                   QColorGroup g2 = cg;\r
729                   g2.setColor( QColorGroup::ButtonText, g2.highlightedText() );\r
730                   drawPrimitive( arrow, p, vrect, g2, dis ? Style_Default : Style_Enabled, opt );\r
731                 }\r
732         else\r
733         {\r
734                   drawPrimitive( arrow, p, vrect, cg, dis ? Style_Default : Style_Enabled, opt );\r
735                 }\r
736           }\r
737 \r
738       if( act && !dis )\r
739       {\r
740         p->setPen( cg.dark() );\r
741         p->drawRect( r );\r
742       }\r
743           break;\r
744     }\r
745 \r
746     case CE_MenuBarItem:\r
747         {\r
748       bool active = flags & Style_Active;\r
749           bool down = flags & Style_Down;\r
750           QRect pr = r;\r
751 \r
752       p->save();\r
753       if( active && down )\r
754       {\r
755         //QColor col; mix( 0.5, cg.mid(), Qt::white, col );\r
756         //drawGradient( p, r, col, cg.light(), UpToDown, linear );\r
757         p->setPen( cg.light() );\r
758         p->setBrush( cg.light() );\r
759         p->drawRect( r );\r
760         \r
761         p->setPen( cg.dark() );\r
762         int w = r.width()-1, h = r.height();\r
763         p->drawLine( r.x(), r.y(), r.x()+w, r.y() );\r
764         p->drawLine( r.x(), r.y(), r.x(), r.y()+h );\r
765         p->drawLine( r.x()+w, r.y(), r.x()+w, r.y()+h );\r
766 \r
767         p->translate( 1, 1 );\r
768       }\r
769       else\r
770         drawGradient( p, r, cg.light(), cg.background(), active ? DownToUp : UpToDown, linear );\r
771 \r
772           QCommonStyle::drawControl(element, p, widget, pr, cg, flags, opt);\r
773       p->restore();\r
774           break;\r
775         }\r
776 \r
777     case CE_MenuBarEmptyArea:\r
778     {\r
779       drawGradient( p, r, cg.light(), cg.background(), UpToDown, linear );\r
780           break;\r
781     }\r
782 \r
783     case CE_ToolButtonLabel:\r
784         {\r
785       const QToolButton *toolbutton = (const QToolButton *) widget;\r
786       QObject* parent = toolbutton->parent();\r
787 \r
788       QToolBar* tb = NULL;\r
789       while( parent )\r
790         if( parent->inherits( "QToolBar" ) )\r
791         {\r
792           tb = ( QToolBar* )parent;\r
793           break;\r
794         }\r
795         else\r
796           parent = parent->parent();\r
797       parent = toolbutton->parent();\r
798 \r
799       int horiz = -1;\r
800       if( tb )\r
801       {\r
802         if( tb->orientation()==Qt::Horizontal )\r
803           horiz = 1;\r
804         else\r
805           horiz = 0;\r
806         drawGradient( p, r, cg.light(), cg.background(), horiz ? UpToDown : LeftToRight, linear );\r
807       }\r
808       else if( parent->inherits( "QDockWindowHandle" ) )\r
809       {\r
810         QWidget* w = ( QWidget* ) parent;\r
811         QDockWindow* wnd = ( QDockWindow* )w->parent();\r
812         if( !wnd->orientation()==Qt::Horizontal )\r
813           horiz=1;\r
814         else\r
815           horiz=0;\r
816 \r
817         QPoint pp( r.x(), r.y() ),\r
818                qq = toolbutton->mapToParent( pp );\r
819         \r
820         bitBlt( p->device(), r.x(), r.y(), w, horiz ? qq.x()-r.width() : qq.x(),\r
821                 horiz ? qq.y() : qq.y()+r.height(),\r
822                 r.width(), r.height(), Qt::CopyROP, true );\r
823       }\r
824 \r
825       bool highlight = ( flags & Style_MouseOver ),\r
826            down = ( flags & ( Style_Down | Style_On ) ),\r
827            en = toolbutton->isEnabled();\r
828 \r
829       if( down )\r
830         if( horiz>=0 )\r
831         {\r
832           drawGradient( p, r, cg.light(), cg.background(), horiz==1 ? DownToUp : RightToLeft, linear );\r
833           p->setPen( cg.background() );\r
834           p->drawRect( r );\r
835         }\r
836         else\r
837         {\r
838           p->setPen( cg.dark() );\r
839           p->setBrush( cg.light() );\r
840           p->drawRect( r );\r
841         }\r
842       if( highlight )\r
843       {\r
844         p->setPen( cg.dark() );\r
845         QColor col; mix( 0.05, cg.background(), Qt::black, col );\r
846         p->setBrush( col );\r
847         p->drawRect( r );\r
848       }\r
849 \r
850 \r
851           QRect rect = r;\r
852           Qt::ArrowType arrowType = opt.isDefault() ? Qt::DownArrow : opt.arrowType();\r
853 \r
854           int shiftX = 0, shiftY = 0;\r
855           if( flags & ( Style_Down | Style_On ) )\r
856       {\r
857                 shiftX = pixelMetric(PM_ButtonShiftHorizontal, widget);\r
858                 shiftY = pixelMetric(PM_ButtonShiftVertical, widget);\r
859           }\r
860 \r
861           if (!opt.isDefault())\r
862       {\r
863                 PrimitiveElement pe;\r
864                 switch (arrowType)\r
865         {\r
866                   case Qt::LeftArrow:  pe = PE_ArrowLeft;  break;\r
867                   case Qt::RightArrow: pe = PE_ArrowRight; break;\r
868                   case Qt::UpArrow:    pe = PE_ArrowUp;    break;\r
869                   default:\r
870                   case Qt::DownArrow:  pe = PE_ArrowDown;  break;\r
871         }\r
872 \r
873         rect.moveBy(shiftX, shiftY);\r
874             drawPrimitive(pe, p, rect, cg, flags, opt);\r
875           }\r
876       else\r
877       {\r
878                 QColor btext = toolbutton->paletteForegroundColor();\r
879 \r
880                 if (toolbutton->iconSet().isNull() &&\r
881                     ! toolbutton->text().isNull() &&\r
882                     ! toolbutton->usesTextLabel())\r
883         {\r
884                     int alignment = AlignCenter | ShowPrefix;\r
885                     if (!styleHint(SH_UnderlineAccelerator, widget, QStyleOption::Default, 0))\r
886                           alignment |= NoAccel;\r
887 \r
888                     rect.moveBy(shiftX, shiftY);\r
889                     drawItem( p, rect, alignment, cg, flags & Style_Enabled, 0, toolbutton->text(),\r
890                                   toolbutton->text().length(), &btext);\r
891         }\r
892         else\r
893         {\r
894               QPixmap pm;\r
895                   QIconSet::Size size =\r
896                   toolbutton->usesBigPixmap() ? QIconSet::Large : QIconSet::Small;\r
897                   QIconSet::State state = toolbutton->isOn() ? QIconSet::On : QIconSet::Off;\r
898                   QIconSet::Mode mode;\r
899                   if( !toolbutton->isEnabled() )\r
900                 mode = QIconSet::Active; //QIconSet::Disabled;\r
901                   else if( flags & (Style_Down | Style_On ) || ( flags & Style_Raised ) && (flags & Style_AutoRaise))\r
902                     mode = QIconSet::Active;\r
903                   else\r
904                     mode = QIconSet::Normal;\r
905                   pm = toolbutton->iconSet().pixmap( size, mode, state );\r
906 \r
907                   if( toolbutton->usesTextLabel() )\r
908           {\r
909                     p->setFont( toolbutton->font() );\r
910                     QRect pr = rect, tr = rect;\r
911                     int alignment = ShowPrefix;\r
912                     if (!styleHint(SH_UnderlineAccelerator, widget, QStyleOption::Default, 0))\r
913                           alignment |= NoAccel;\r
914 \r
915                     if( toolbutton->textPosition() == QToolButton::Under )\r
916             {\r
917                           int fh = p->fontMetrics().height();\r
918                           pr.addCoords( 0, 1, 0, -fh-3 );\r
919                           tr.addCoords( 0, pr.bottom(), 0, -3 );\r
920                           pr.moveBy(shiftX, shiftY);\r
921                           drawItem( p, pr, AlignCenter, cg, TRUE, &pm, QString::null );\r
922                           alignment |= AlignCenter;\r
923             }\r
924             else\r
925             {\r
926                           pr.setWidth( pm.width() + 8 );\r
927                           tr.addCoords( pr.right(), 0, 0, 0 );\r
928                           pr.moveBy(shiftX, shiftY);\r
929  \r
930                           drawItem( p, pr, AlignCenter, cg, TRUE, &pm, QString::null );\r
931                           alignment |= AlignLeft | AlignVCenter;\r
932             }\r
933 \r
934                 tr.moveBy(shiftX, shiftY);\r
935                     drawItem( p, tr, alignment, cg, flags & Style_Enabled, 0, toolbutton->textLabel(),\r
936                                       toolbutton->textLabel().length(), &btext);\r
937           }\r
938           else\r
939           {\r
940             /*if( en && !highlight )\r
941               mix( 0.6, pm, cg.background() );\r
942             else*/ if( !en )\r
943             {\r
944               toGrayscale( pm, 1.1 );\r
945               mix( 0.8, pm, cg.background() );\r
946             }\r
947 \r
948                     rect.moveBy(shiftX, shiftY);\r
949                     drawItem( p, rect, AlignCenter, cg, true, &pm, QString::null );\r
950           }\r
951         }\r
952       }\r
953     }\r
954     break;\r
955 \r
956     case CE_TabBarTab:\r
957           {\r
958       QPen oldPen = p->pen();\r
959 \r
960             QRect r2( r );\r
961             bool selected = flags & Style_Selected;\r
962 \r
963       p->setPen( cg.midlight() );\r
964       p->drawLine( r2.left(), r2.bottom(), r2.right(), r2.bottom() );\r
965 \r
966       if ( !selected )\r
967         r2.setRect( r2.left(), r2.top() + 1, r2.width(), r2.height() - 1 );\r
968       else\r
969         r2.setRect( r2.left(), r2.top(), r2.width() - 2, r2.height() - 1 );\r
970 \r
971       p->setPen( cg.foreground() );\r
972       QBrush brsh = cg.brush( selected ? QColorGroup::Base : QColorGroup::Background );\r
973       p->fillRect( r2.left(), r2.top(), r2.width(), r2.height() - 1, brsh );\r
974       p->drawRect( r2.left(), r2.top(), r2.width(), r2.height() - 1 );\r
975 \r
976       if ( selected )\r
977       {\r
978         p->setPen( cg.shadow() );\r
979         p->drawLine( r2.left() + 1, r2.bottom(), r2.right() + 1, r2.bottom() );\r
980         p->drawLine( r2.right() + 1, r2.top() + 1, r2.right() + 1, r2.bottom() );\r
981       }\r
982 \r
983             break;\r
984     }\r
985 \r
986     case CE_PushButton:\r
987           {\r
988       if ( flags & Style_Enabled && !( flags & Style_Down || flags & Style_On ) )\r
989       {\r
990               const QPushButton* button = (const QPushButton*)widget;\r
991         QRect br = QRect( button->mapToGlobal( button->rect().topLeft() ), button->rect().size() );\r
992         if ( br.contains( QCursor::pos() )  )\r
993           flags |= Style_MouseOver;\r
994       }\r
995 \r
996       PARENT_STYLE::drawControl( element, p, widget, r, cg, flags, opt );\r
997             break;\r
998           }\r
999 \r
1000     default:\r
1001       PARENT_STYLE::drawControl( element, p, widget, r, cg, flags, opt );\r
1002       break;\r
1003   }\r
1004 }\r
1005 \r
1006 QRect SalomeStyle::subRect( SubRect subrect, const QWidget* w ) const\r
1007 {\r
1008   QRect r = PARENT_STYLE::subRect( subrect, w );\r
1009   if ( subrect==SR_DockWindowHandleRect && w->inherits( "QDockWindowHandle" ) )\r
1010   {\r
1011     QDockWindow* wnd = ( QDockWindow* ) w->parent();\r
1012     if( wnd->orientation()==Qt::Vertical )\r
1013       r.setWidth( w->width() );\r
1014     else\r
1015     {\r
1016       r.setY( r.y()+r.height()-w->height() );\r
1017       r.setHeight( w->height() );\r
1018     }\r
1019   }\r
1020 \r
1021   return r;\r
1022 }\r
1023 \r
1024 void SalomeStyle::drawComplexControl( ComplexControl control, QPainter* p, const QWidget* widget,\r
1025                                                               const QRect& r, const QColorGroup& cg, SFlags flags,\r
1026                                                               SCFlags controls, SCFlags active, const QStyleOption& opt ) const\r
1027 {\r
1028 \r
1029 \r
1030 \r
1031 \r
1032   ((SalomeStyle*)this)->myTitleParent = 0;\r
1033 \r
1034   switch ( control )\r
1035   {\r
1036   case CC_ComboBox:\r
1037           if ( controls & SC_ComboBoxArrow )\r
1038     {\r
1039             SFlags flags = Style_Default;\r
1040 \r
1041       qDrawShadeRect( p, r, cg, true, pixelMetric( PM_DefaultFrameWidth, widget ),\r
1042                       0, widget->isEnabled() ? &cg.brush( QColorGroup::Base ) : &cg.brush( QColorGroup::Background ) );\r
1043 \r
1044             QRect ar = QStyle::visualRect( querySubControlMetrics( CC_ComboBox, widget, SC_ComboBoxArrow ), widget );\r
1045             if ( active == SC_ComboBoxArrow )\r
1046       {\r
1047                     p->setPen( cg.dark() );\r
1048                     p->setBrush( cg.brush( QColorGroup::Button ) );\r
1049                     p->drawRect( ar );\r
1050             }\r
1051       else\r
1052                     qDrawWinPanel( p, ar, cg, FALSE, &cg.brush( QColorGroup::Button ) );\r
1053 \r
1054             ar.addCoords( 2, 2, -2, -2 );\r
1055             if ( widget->isEnabled() )\r
1056                     flags |= Style_Enabled;\r
1057 \r
1058             if ( active == SC_ComboBoxArrow )\r
1059                     flags |= Style_Sunken;\r
1060             drawPrimitive( PE_ArrowDown, p, ar, cg, flags );\r
1061           }\r
1062     PARENT_STYLE::drawComplexControl( control, p, widget, r, cg, flags, controls & ~SC_ComboBoxArrow, active, opt );\r
1063     break;\r
1064 \r
1065   case CC_TitleBar:\r
1066     if( widget->inherits( "QTitleBar" ) )\r
1067       ( ( SalomeStyle* )this )->myTitleParent = ( QWidget* )widget->parent();\r
1068 \r
1069   default:\r
1070     PARENT_STYLE::drawComplexControl( control, p, widget, r, cg, flags, controls, active, opt );\r
1071     break;\r
1072   }\r
1073 }\r
1074 \r
1075 QPixmap SalomeStyle::stylePixmap( StylePixmap st, const QWidget* w, const QStyleOption& opt ) const\r
1076 {\r
1077   switch ( st )\r
1078   {\r
1079   case SP_DockWindowCloseButton:\r
1080   case SP_TitleBarCloseButton:\r
1081     return QPixmap( cross_xpm );\r
1082   case SP_TitleBarMaxButton:\r
1083     return QPixmap( maximize_xpm );\r
1084   case SP_TitleBarNormalButton:\r
1085     return QPixmap( normal_xpm );\r
1086   case SP_TitleBarMinButton:\r
1087     return QPixmap( minimize_xpm );\r
1088   default:\r
1089     return PARENT_STYLE::stylePixmap( st, w, opt );\r
1090   }\r
1091 }\r
1092 \r
1093 int SalomeStyle::pixelMetric( PixelMetric pm, const QWidget* widget ) const\r
1094 {\r
1095   int ret = 0;\r
1096 \r
1097   switch ( pm )\r
1098   {\r
1099   case PM_ButtonMargin:\r
1100     ret = 5;\r
1101     break;\r
1102   case PM_DockWindowFrameWidth:\r
1103     ret = 0;\r
1104     break;\r
1105   case PM_TabBarTabOverlap:\r
1106           ret = 2;\r
1107           break;\r
1108   case PM_TabBarTabHSpace:\r
1109           ret = 20;\r
1110           break;\r
1111   case PM_TabBarTabShiftHorizontal:\r
1112   case PM_TabBarTabShiftVertical:\r
1113           ret = 0;\r
1114           break;\r
1115   case PM_TabBarTabVSpace:\r
1116                 ret = 5;\r
1117     break;\r
1118   case PM_DefaultFrameWidth:\r
1119     ret = 1;\r
1120     break;\r
1121   case PM_SpinBoxFrameWidth:\r
1122     ret = 1;\r
1123     break;\r
1124   default:\r
1125     ret = PARENT_STYLE::pixelMetric( pm, widget );\r
1126     break;\r
1127   }\r
1128   return ret;\r
1129 }\r
1130 \r
1131 /*!\r
1132     Class: SalomeStylePlugin [Internal]\r
1133     Descr: Plugin for Qt style mechanism\r
1134 */\r
1135 \r
1136 SalomeStylePlugin::SalomeStylePlugin()\r
1137 {\r
1138 }\r
1139 \r
1140 SalomeStylePlugin::~SalomeStylePlugin()\r
1141 {\r
1142 }\r
1143 \r
1144 QStringList SalomeStylePlugin::keys() const\r
1145 {\r
1146   printf( "SalomeStylePlugin::keys()\n" );\r
1147 \r
1148   return QStringList() << "salome";\r
1149 }\r
1150 \r
1151 QStyle* SalomeStylePlugin::create( const QString& str )\r
1152 {\r
1153   if ( str == "salome" )\r
1154     return new SalomeStyle();\r
1155   else\r
1156     return 0;\r
1157 }\r
1158 \r
1159 Q_EXPORT_PLUGIN( SalomeStylePlugin )\r