• Skip to content
  • Skip to link menu
Trinity API Reference
  • Trinity API Reference
  • tdefx
 

tdefx

  • tdefx
tdestyle.cpp
1 /*
2  *
3  * TDEStyle
4  * Copyright (C) 2001-2002 Karol Szwed <gallium@kde.org>
5  *
6  * TQWindowsStyle CC_ListView and style images were kindly donated by TrollTech,
7  * Copyright (C) 1998-2000 TrollTech AS.
8  *
9  * Many thanks to Bradley T. Hughes for the 3 button scrollbar code.
10  *
11  * This library is free software; you can redistribute it and/or
12  * modify it under the terms of the GNU Library General Public
13  * License version 2 as published by the Free Software Foundation.
14  *
15  * This library is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18  * Library General Public License for more details.
19  *
20  * You should have received a copy of the GNU Library General Public License
21  * along with this library; see the file COPYING.LIB. If not, write to
22  * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
23  * Boston, MA 02110-1301, USA.
24  */
25 
26 #ifdef HAVE_CONFIG_H
27 #include "config.h"
28 #endif
29 
30 #include "tdestyle.h"
31 
32 #include <tqapplication.h>
33 #include <tqbitmap.h>
34 #include <tqmetaobject.h>
35 #include <tqcleanuphandler.h>
36 #include <tqmap.h>
37 #include <tqimage.h>
38 #include <tqlistview.h>
39 #include <tqmenubar.h>
40 #include <tqpainter.h>
41 #include <tqpixmap.h>
42 #include <tqpopupmenu.h>
43 #include <tqprogressbar.h>
44 #include <tqscrollbar.h>
45 #include <tqsettings.h>
46 #include <tqslider.h>
47 #include <tqstylefactory.h>
48 #include <tqtabbar.h>
49 #include <tqtoolbar.h>
50 #include <tqframe.h>
51 
52 #include <kpixmap.h>
53 #include <kpixmapeffect.h>
54 #include <kimageeffect.h>
55 
56 #ifdef TQ_WS_X11
57 # include <X11/Xlib.h>
58 # ifdef HAVE_XRENDER
59 # include <X11/extensions/Xrender.h> // schroder
60  extern bool tqt_use_xrender;
61 # endif
62 #else
63 #undef HAVE_XRENDER
64 #endif
65 
66 #ifdef HAVE_XCOMPOSITE
67 #include <X11/extensions/Xrender.h>
68 #include <X11/extensions/Xcomposite.h>
69 #include <dlfcn.h>
70 #endif
71 
72 #include <limits.h>
73 
74 namespace
75 {
76  // INTERNAL
77  enum TransparencyEngine {
78  Disabled = 0,
79  SoftwareTint,
80  SoftwareBlend,
81  XRender
82  };
83 
84  // Drop Shadow
85  struct ShadowElements {
86  TQWidget* w1;
87  TQWidget* w2;
88  };
89  typedef TQMap<const TQWidget*,ShadowElements> ShadowMap;
90  static ShadowMap *_shadowMap = 0;
91  TQSingleCleanupHandler<ShadowMap> cleanupShadowMap;
92  ShadowMap &shadowMap() {
93  if ( !_shadowMap ) {
94  _shadowMap = new ShadowMap;
95  cleanupShadowMap.set( &_shadowMap );
96  }
97  return *_shadowMap;
98  }
99 
100 
101  // DO NOT ASK ME HOW I MADE THESE TABLES!
102  // (I probably won't remember anyway ;)
103  const double top_right_corner[16] =
104  { 0.949, 0.965, 0.980, 0.992,
105  0.851, 0.890, 0.945, 0.980,
106  0.706, 0.780, 0.890, 0.960,
107  0.608, 0.706, 0.851, 0.949 };
108 
109  const double bottom_right_corner[16] =
110  { 0.608, 0.706, 0.851, 0.949,
111  0.706, 0.780, 0.890, 0.960,
112  0.851, 0.890, 0.945, 0.980,
113  0.949, 0.965, 0.980, 0.992 };
114 
115  const double bottom_left_corner[16] =
116  { 0.949, 0.851, 0.706, 0.608,
117  0.965, 0.890, 0.780, 0.706,
118  0.980, 0.945, 0.890, 0.851,
119  0.992, 0.980, 0.960, 0.949 };
120 
121  const double shadow_strip[4] =
122  { 0.565, 0.675, 0.835, 0.945 };
123 
124  static bool useDropShadow(TQWidget* w)
125  {
126  return w && w->metaObject() &&
127  w->metaObject()->findProperty("TDEStyleMenuDropShadow") != -1;
128  }
129 }
130 
131 namespace
132 {
133 class TransparencyHandler : public TQObject
134 {
135  public:
136  TransparencyHandler(TDEStyle* style, TransparencyEngine tEngine,
137  float menuOpacity, bool useDropShadow);
138  ~TransparencyHandler();
139  bool eventFilter(TQObject* object, TQEvent* event);
140 
141  protected:
142  void blendToColor(const TQColor &col);
143  void blendToPixmap(const TQColorGroup &cg, const TQWidget* p);
144 #ifdef HAVE_XRENDER
145  void XRenderBlendToPixmap(const TQWidget* p);
146 #endif
147  bool haveX11RGBASupport();
148  TQImage handleRealAlpha(TQImage);
149  void createShadowWindows(const TQWidget* p);
150  void removeShadowWindows(const TQWidget* p);
151  void rightShadow(TQImage& dst);
152  void bottomShadow(TQImage& dst);
153  private:
154  bool dropShadow;
155  float opacity;
156  TQPixmap pix;
157  TDEStyle* tdestyle;
158  TransparencyEngine te;
159 };
160 } // namespace
161 
162 struct TDEStylePrivate
163 {
164  bool highcolor : 1;
165  bool useFilledFrameWorkaround : 1;
166  bool etchDisabledText : 1;
167  bool scrollablePopupmenus : 1;
168  bool autoHideAccelerators : 1;
169  bool menuAltKeyNavigation : 1;
170  bool menuDropShadow : 1;
171  bool sloppySubMenus : 1;
172  bool semiTransparentRubberband : 1;
173  int popupMenuDelay;
174  float menuOpacity;
175 
176  TransparencyEngine transparencyEngine;
177  TDEStyle::TDEStyleScrollBarType scrollbarType;
178  TransparencyHandler* menuHandler;
179  TDEStyle::TDEStyleFlags flags;
180 
181  //For KPE_ListViewBranch
182  TQBitmap *verticalLine;
183  TQBitmap *horizontalLine;
184 };
185 
186 // -----------------------------------------------------------------------------
187 
188 
189 TDEStyle::TDEStyle( TDEStyleFlags flags, TDEStyleScrollBarType sbtype )
190  : TQCommonStyle(), d(new TDEStylePrivate)
191 {
192  d->flags = flags;
193  bool useMenuTransparency = (flags & AllowMenuTransparency);
194  d->useFilledFrameWorkaround = (flags & FilledFrameWorkaround);
195  d->scrollbarType = sbtype;
196  d->highcolor = TQPixmap::defaultDepth() > 8;
197 
198  // Read style settings
199  TQSettings settings;
200  d->popupMenuDelay = settings.readNumEntry ("/TDEStyle/Settings/PopupMenuDelay", 250);
201  d->sloppySubMenus = settings.readBoolEntry("/TDEStyle/Settings/SloppySubMenus", false);
202  d->etchDisabledText = settings.readBoolEntry("/TDEStyle/Settings/EtchDisabledText", true);
203  d->menuAltKeyNavigation = settings.readBoolEntry("/TDEStyle/Settings/MenuAltKeyNavigation", true);
204  d->scrollablePopupmenus = settings.readBoolEntry("/TDEStyle/Settings/ScrollablePopupMenus", false);
205  d->autoHideAccelerators = settings.readBoolEntry("/TDEStyle/Settings/AutoHideAccelerators", false);
206  d->menuDropShadow = settings.readBoolEntry("/TDEStyle/Settings/MenuDropShadow", false);
207  d->semiTransparentRubberband = settings.readBoolEntry("/TDEStyle/Settings/SemiTransparentRubberband", false);
208  d->menuHandler = NULL;
209 
210  if (useMenuTransparency) {
211  TQString effectEngine = settings.readEntry("/TDEStyle/Settings/MenuTransparencyEngine", "Disabled");
212 
213 #ifdef HAVE_XRENDER
214  if (effectEngine == "XRender")
215  d->transparencyEngine = XRender;
216 #else
217  if (effectEngine == "XRender")
218  d->transparencyEngine = SoftwareBlend;
219 #endif
220  else if (effectEngine == "SoftwareBlend")
221  d->transparencyEngine = SoftwareBlend;
222  else if (effectEngine == "SoftwareTint")
223  d->transparencyEngine = SoftwareTint;
224  else
225  d->transparencyEngine = Disabled;
226 
227  if (d->transparencyEngine != Disabled) {
228  // Create an instance of the menu transparency handler
229  d->menuOpacity = settings.readDoubleEntry("/TDEStyle/Settings/MenuOpacity", 0.90);
230  d->menuHandler = new TransparencyHandler(this, d->transparencyEngine,
231  d->menuOpacity, d->menuDropShadow);
232  }
233  }
234 
235  d->verticalLine = 0;
236  d->horizontalLine = 0;
237 
238  // Create a transparency handler if only drop shadows are enabled.
239  if (!d->menuHandler && d->menuDropShadow)
240  d->menuHandler = new TransparencyHandler(this, Disabled, 1.0, d->menuDropShadow);
241 }
242 
243 
244 TDEStyle::~TDEStyle()
245 {
246  delete d->verticalLine;
247  delete d->horizontalLine;
248 
249  delete d->menuHandler;
250 
251  d->menuHandler = NULL;
252  delete d;
253 }
254 
255 
256 TQString TDEStyle::defaultStyle()
257 {
258  if (TQPixmap::defaultDepth() > 8)
259  return TQString("plastik");
260  else
261  return TQString("light, 3rd revision");
262 }
263 
264 void TDEStyle::polish( const TQStyleControlElementData &ceData, ControlElementFlags elementFlags, void *ptr )
265 {
266  if (ceData.widgetObjectTypes.contains("TQWidget")) {
267  TQWidget* widget = reinterpret_cast<TQWidget*>(ptr);
268  if ( d->useFilledFrameWorkaround )
269  {
270  if ( TQFrame *frame = ::tqt_cast< TQFrame* >( widget ) ) {
271  TQFrame::Shape shape = frame->frameShape();
272  if (shape == TQFrame::ToolBarPanel || shape == TQFrame::MenuBarPanel)
273  widget->installEventFilter(this);
274  }
275  }
276  if (widget->isTopLevel())
277  {
278  if (!d->menuHandler && useDropShadow(widget))
279  d->menuHandler = new TransparencyHandler(this, Disabled, 1.0, false);
280 
281  if (d->menuHandler && useDropShadow(widget))
282  widget->installEventFilter(d->menuHandler);
283  }
284  }
285 }
286 ␌
287 
288 void TDEStyle::unPolish( const TQStyleControlElementData &ceData, ControlElementFlags elementFlags, void *ptr )
289 {
290  if (ceData.widgetObjectTypes.contains("TQWidget")) {
291  TQWidget* widget = reinterpret_cast<TQWidget*>(ptr);
292  if ( d->useFilledFrameWorkaround )
293  {
294  if ( TQFrame *frame = ::tqt_cast< TQFrame* >( widget ) ) {
295  TQFrame::Shape shape = frame->frameShape();
296  if (shape == TQFrame::ToolBarPanel || shape == TQFrame::MenuBarPanel)
297  widget->removeEventFilter(this);
298  }
299  }
300  if (widget->isTopLevel() && d->menuHandler && useDropShadow(widget))
301  widget->removeEventFilter(d->menuHandler);
302  }
303 }
304 
305 
306 // Style changes (should) always re-polish popups.
307 void TDEStyle::polishPopupMenu( const TQStyleControlElementData &ceData, ControlElementFlags elementFlags, void *ptr )
308 {
309  if ( !(ceData.windowState & WState_Polished ) ) {
310  widgetActionRequest(ceData, elementFlags, ptr, WAR_SetCheckable);
311  }
312 
313  if (ceData.widgetObjectTypes.contains("TQWidget")) {
314  TQWidget* widget = reinterpret_cast<TQWidget*>(ptr);
315  TQPopupMenu *p = dynamic_cast<TQPopupMenu*>(widget);
316  if (p) {
317  // Install transparency handler if the effect is enabled.
318  if ( d->menuHandler && (strcmp(p->name(), "tear off menu") != 0)) {
319  p->installEventFilter(d->menuHandler);
320  }
321  }
322  }
323 }
324 
325 
326 // -----------------------------------------------------------------------------
327 // TDEStyle extensions
328 // -----------------------------------------------------------------------------
329 
330 void TDEStyle::setScrollBarType(TDEStyleScrollBarType sbtype)
331 {
332  d->scrollbarType = sbtype;
333 }
334 
335 TDEStyle::TDEStyleFlags TDEStyle::styleFlags() const
336 {
337  return d->flags;
338 }
339 
340 void TDEStyle::renderMenuBlendPixmap( KPixmap &pix, const TQColorGroup &cg,
341  const TQPopupMenu* /* popup */ ) const
342 {
343  pix.fill(cg.button()); // Just tint as the default behavior
344 }
345 
346 void TDEStyle::drawTDEStylePrimitive( TDEStylePrimitive kpe,
347  TQPainter* p,
348  const TQWidget* widget,
349  const TQRect &r,
350  const TQColorGroup &cg,
351  SFlags flags,
352  const TQStyleOption &opt ) const
353 {
354  const TQStyleControlElementData &ceData = populateControlElementDataFromWidget(widget, TQStyleOption());
355  drawTDEStylePrimitive(kpe, p, ceData, getControlElementFlagsForObject(widget, TQStyleOption()), r, cg, flags, opt);
356 }
357 
358 void TDEStyle::drawTDEStylePrimitive( TDEStylePrimitive kpe,
359  TQPainter* p,
360  const TQStyleControlElementData &ceData,
361  ControlElementFlags elementFlags,
362  const TQRect &r,
363  const TQColorGroup &cg,
364  SFlags flags,
365  const TQStyleOption&, /* opt */
366  const TQWidget* widget ) const
367 {
368  switch( kpe )
369  {
370  // Dock / Toolbar / General handles.
371  // ---------------------------------
372 
373  case KPE_DockWindowHandle: {
374 
375  // Draws a nice DockWindow handle including the dock title.
376  TQWidget* wid = const_cast<TQWidget*>(widget);
377  bool horizontal = flags & Style_Horizontal;
378  int x,y,w,h,x2,y2;
379 
380  r.rect( &x, &y, &w, &h );
381  if ((w <= 2) || (h <= 2)) {
382  p->fillRect(r, cg.highlight());
383  return;
384  }
385 
386 
387  x2 = x + w - 1;
388  y2 = y + h - 1;
389 
390  TQFont fnt;
391  fnt = TQApplication::font(wid);
392  fnt.setPointSize( fnt.pointSize()-2 );
393 
394  // Draw the item on an off-screen pixmap
395  // to preserve Xft antialiasing for
396  // vertically oriented handles.
397  TQPixmap pix;
398  if (horizontal)
399  pix.resize( h-2, w-2 );
400  else
401  pix.resize( w-2, h-2 );
402 
403  TQString title = wid->parentWidget()->caption();
404  TQPainter p2;
405  p2.begin(&pix);
406  p2.fillRect(pix.rect(), cg.brush(TQColorGroup::Highlight));
407  p2.setPen(cg.highlightedText());
408  p2.setFont(fnt);
409  p2.drawText(pix.rect(), AlignCenter, title);
410  p2.end();
411 
412  // Draw a sunken bevel
413  p->setPen(cg.dark());
414  p->drawLine(x, y, x2, y);
415  p->drawLine(x, y, x, y2);
416  p->setPen(cg.light());
417  p->drawLine(x+1, y2, x2, y2);
418  p->drawLine(x2, y+1, x2, y2);
419 
420  if (horizontal) {
421  TQWMatrix m;
422  m.rotate(-90.0);
423  TQPixmap vpix = pix.xForm(m);
424  bitBlt(wid, r.x()+1, r.y()+1, &vpix);
425  } else
426  bitBlt(wid, r.x()+1, r.y()+1, &pix);
427 
428  break;
429  }
430 
431 
432  /*
433  * KPE_ListViewExpander and KPE_ListViewBranch are based on code from
434  * QWindowStyle's CC_ListView, kindly donated by TrollTech.
435  * CC_ListView code is Copyright (C) 1998-2000 TrollTech AS.
436  */
437 
438  case KPE_ListViewExpander: {
439  // Typical Windows style expand/collapse element.
440  int radius = (r.width() - 4) / 2;
441  int centerx = r.x() + r.width()/2;
442  int centery = r.y() + r.height()/2;
443 
444  // Outer box
445  p->setPen( cg.mid() );
446  p->drawRect( r );
447 
448  // plus or minus
449  p->setPen( cg.text() );
450  p->drawLine( centerx - radius, centery, centerx + radius, centery );
451  if ( flags & Style_On ) // Collapsed = On
452  p->drawLine( centerx, centery - radius, centerx, centery + radius );
453  break;
454  }
455 
456  case KPE_ListViewBranch: {
457  // Typical Windows style listview branch element (dotted line).
458 
459  // Create the dotline pixmaps if not already created
460  if ( !d->verticalLine )
461  {
462  // make 128*1 and 1*128 bitmaps that can be used for
463  // drawing the right sort of lines.
464  d->verticalLine = new TQBitmap( 1, 129, true );
465  d->horizontalLine = new TQBitmap( 128, 1, true );
466  TQPointArray a( 64 );
467  TQPainter p2;
468  p2.begin( d->verticalLine );
469 
470  int i;
471  for( i=0; i < 64; i++ )
472  a.setPoint( i, 0, i*2+1 );
473  p2.setPen( color1 );
474  p2.drawPoints( a );
475  p2.end();
476  TQApplication::flushX();
477  d->verticalLine->setMask( *d->verticalLine );
478 
479  p2.begin( d->horizontalLine );
480  for( i=0; i < 64; i++ )
481  a.setPoint( i, i*2+1, 0 );
482  p2.setPen( color1 );
483  p2.drawPoints( a );
484  p2.end();
485  TQApplication::flushX();
486  d->horizontalLine->setMask( *d->horizontalLine );
487  }
488 
489  p->setPen( cg.text() ); // cg.dark() is bad for dark color schemes.
490 
491  if (flags & Style_Horizontal)
492  {
493  int point = r.x();
494  int other = r.y();
495  int end = r.x()+r.width();
496  int thickness = r.height();
497 
498  while( point < end )
499  {
500  int i = 128;
501  if ( i+point > end )
502  i = end-point;
503  p->drawPixmap( point, other, *d->horizontalLine, 0, 0, i, thickness );
504  point += i;
505  }
506 
507  } else {
508  int point = r.y();
509  int other = r.x();
510  int end = r.y()+r.height();
511  int thickness = r.width();
512  int pixmapoffset = (flags & Style_NoChange) ? 0 : 1; // ### Hackish
513 
514  while( point < end )
515  {
516  int i = 128;
517  if ( i+point > end )
518  i = end-point;
519  p->drawPixmap( other, point, *d->verticalLine, 0, pixmapoffset, thickness, i );
520  point += i;
521  }
522  }
523 
524  break;
525  }
526 
527  // Reimplement the other primitives in your styles.
528  // The current implementation just paints something visibly different.
529  case KPE_ToolBarHandle:
530  case KPE_GeneralHandle:
531  case KPE_SliderHandle:
532  p->fillRect(r, cg.light());
533  break;
534 
535  case KPE_SliderGroove:
536  p->fillRect(r, cg.dark());
537  break;
538 
539  default:
540  p->fillRect(r, TQt::yellow); // Something really bad happened - highlight.
541  break;
542  }
543 }
544 
545 
546 int TDEStyle::kPixelMetric( TDEStylePixelMetric kpm, const TQStyleControlElementData &ceData, ControlElementFlags elementFlags, const TQWidget* /* widget */) const
547 {
548  int value;
549  switch(kpm)
550  {
551  case KPM_ListViewBranchThickness:
552  value = 1;
553  break;
554 
555  case KPM_MenuItemSeparatorHeight:
556  case KPM_MenuItemHMargin:
557  case KPM_MenuItemVMargin:
558  case KPM_MenuItemHFrame:
559  case KPM_MenuItemVFrame:
560  case KPM_MenuItemCheckMarkHMargin:
561  case KPM_MenuItemArrowHMargin:
562  case KPM_MenuItemTabSpacing:
563  default:
564  value = 0;
565  }
566 
567  return value;
568 }
569 
570 // -----------------------------------------------------------------------------
571 
572 void TDEStyle::drawPrimitive( PrimitiveElement pe,
573  TQPainter* p,
574  const TQStyleControlElementData &ceData,
575  ControlElementFlags elementFlags,
576  const TQRect &r,
577  const TQColorGroup &cg,
578  SFlags flags,
579  const TQStyleOption& opt ) const
580 {
581  // TOOLBAR/DOCK WINDOW HANDLE
582  // ------------------------------------------------------------------------
583  if (pe == PE_DockWindowHandle)
584  {
585  // Wild workarounds are here. Beware.
586  TQWidget *widget, *parent;
587 
588  if (p && p->device()->devType() == TQInternal::Widget) {
589  widget = static_cast<TQWidget*>(p->device());
590  parent = widget->parentWidget();
591  } else
592  return; // Don't paint on non-widgets
593 
594  // Check if we are a normal toolbar or a hidden dockwidget.
595  if ( parent &&
596  (parent->inherits("TQToolBar") || // Normal toolbar
597  (parent->inherits("TQMainWindow")) )) // Collapsed dock
598 
599  // Draw a toolbar handle
600  drawTDEStylePrimitive( KPE_ToolBarHandle, p, ceData, elementFlags, r, cg, flags, opt, widget );
601 
602  else if (ceData.widgetObjectTypes.contains("TQDockWindowHandle"))
603 
604  // Draw a dock window handle
605  drawTDEStylePrimitive( KPE_DockWindowHandle, p, ceData, elementFlags, r, cg, flags, opt, widget );
606 
607  else
608  // General handle, probably a kicker applet handle.
609  drawTDEStylePrimitive( KPE_GeneralHandle, p, ceData, elementFlags, r, cg, flags, opt, widget );
610 #if TQT_VERSION >= 0x030300
611 #ifdef HAVE_XRENDER
612  } else if ( d->semiTransparentRubberband && pe == TQStyle::PE_RubberBand ) {
613  TQRect rect = r.normalize();
614  TQPoint point;
615  point = p->xForm( point );
616 
617  static XRenderColor clr = { 0, 0, 0, 0 };
618  static unsigned long fillColor = 0;
619  if ( fillColor != cg.highlight().rgb() ) {
620  fillColor = cg.highlight().rgb();
621 
622  unsigned long color = fillColor << 8 | 0x40;
623 
624  int red = (color >> 24) & 0xff;
625  int green = (color >> 16) & 0xff;
626  int blue = (color >> 8) & 0xff;
627  int alpha = (color >> 0) & 0xff;
628 
629  red = red * alpha / 255;
630  green = green * alpha / 255;
631  blue = blue * alpha / 255;
632 
633  clr.red = (red << 8) + red;
634  clr.green = (green << 8) + green;
635  clr.blue = (blue << 8) + blue;
636  clr.alpha = (alpha << 8) + alpha;
637  }
638 
639  XRenderFillRectangle(
640  p->device()->x11Display(),
641  PictOpOver,
642  p->device()->x11RenderHandle(),
643  &clr,
644  rect.x() + point.x(),
645  rect.y() + point.y(),
646  rect.width(),
647  rect.height() );
648 
649  p->save();
650  p->setRasterOp( TQt::CopyROP );
651  p->setPen( TQPen( cg.highlight().dark( 160 ), 1 ) );
652  p->setBrush( NoBrush );
653  p->drawRect(
654  rect.x() + point.x(),
655  rect.y() + point.y(),
656  rect.width(),
657  rect.height() );
658  p->restore();
659 #endif
660 #endif
661  } else
662  TQCommonStyle::drawPrimitive( pe, p, ceData, elementFlags, r, cg, flags, opt );
663 }
664 
665 
666 
667 void TDEStyle::drawControl( ControlElement element,
668  TQPainter* p,
669  const TQStyleControlElementData &ceData,
670  ControlElementFlags elementFlags,
671  const TQRect &r,
672  const TQColorGroup &cg,
673  SFlags flags,
674  const TQStyleOption &opt,
675  const TQWidget* widget ) const
676 {
677  switch (element)
678  {
679  // TABS
680  // ------------------------------------------------------------------------
681  case CE_TabBarTab: {
682  TQTabBar::Shape tbs = ceData.tabBarData.shape;
683  bool selected = flags & Style_Selected;
684  int x = r.x(), y=r.y(), bottom=r.bottom(), right=r.right();
685 
686  switch (tbs) {
687 
688  case TQTabBar::RoundedAbove: {
689  if (!selected)
690  p->translate(0,1);
691  p->setPen(selected ? cg.light() : cg.shadow());
692  p->drawLine(x, y+4, x, bottom);
693  p->drawLine(x, y+4, x+4, y);
694  p->drawLine(x+4, y, right-1, y);
695  if (selected)
696  p->setPen(cg.shadow());
697  p->drawLine(right, y+1, right, bottom);
698 
699  p->setPen(cg.midlight());
700  p->drawLine(x+1, y+4, x+1, bottom);
701  p->drawLine(x+1, y+4, x+4, y+1);
702  p->drawLine(x+5, y+1, right-2, y+1);
703 
704  if (selected) {
705  p->setPen(cg.mid());
706  p->drawLine(right-1, y+1, right-1, bottom);
707  } else {
708  p->setPen(cg.mid());
709  p->drawPoint(right-1, y+1);
710  p->drawLine(x+4, y+2, right-1, y+2);
711  p->drawLine(x+3, y+3, right-1, y+3);
712  p->fillRect(x+2, y+4, r.width()-3, r.height()-6, cg.mid());
713 
714  p->setPen(cg.light());
715  p->drawLine(x, bottom-1, right, bottom-1);
716  p->translate(0,-1);
717  }
718  break;
719  }
720 
721  case TQTabBar::RoundedBelow: {
722  if (!selected)
723  p->translate(0,-1);
724  p->setPen(selected ? cg.light() : cg.shadow());
725  p->drawLine(x, bottom-4, x, y);
726  if (selected)
727  p->setPen(cg.mid());
728  p->drawLine(x, bottom-4, x+4, bottom);
729  if (selected)
730  p->setPen(cg.shadow());
731  p->drawLine(x+4, bottom, right-1, bottom);
732  p->drawLine(right, bottom-1, right, y);
733 
734  p->setPen(cg.midlight());
735  p->drawLine(x+1, bottom-4, x+1, y);
736  p->drawLine(x+1, bottom-4, x+4, bottom-1);
737  p->drawLine(x+5, bottom-1, right-2, bottom-1);
738 
739  if (selected) {
740  p->setPen(cg.mid());
741  p->drawLine(right-1, y, right-1, bottom-1);
742  } else {
743  p->setPen(cg.mid());
744  p->drawPoint(right-1, bottom-1);
745  p->drawLine(x+4, bottom-2, right-1, bottom-2);
746  p->drawLine(x+3, bottom-3, right-1, bottom-3);
747  p->fillRect(x+2, y+2, r.width()-3, r.height()-6, cg.mid());
748  p->translate(0,1);
749  p->setPen(cg.dark());
750  p->drawLine(x, y, right, y);
751  }
752  break;
753  }
754 
755  case TQTabBar::TriangularAbove: {
756  if (!selected)
757  p->translate(0,1);
758  p->setPen(selected ? cg.light() : cg.shadow());
759  p->drawLine(x, bottom, x, y+6);
760  p->drawLine(x, y+6, x+6, y);
761  p->drawLine(x+6, y, right-6, y);
762  if (selected)
763  p->setPen(cg.mid());
764  p->drawLine(right-5, y+1, right-1, y+5);
765  p->setPen(cg.shadow());
766  p->drawLine(right, y+6, right, bottom);
767 
768  p->setPen(cg.midlight());
769  p->drawLine(x+1, bottom, x+1, y+6);
770  p->drawLine(x+1, y+6, x+6, y+1);
771  p->drawLine(x+6, y+1, right-6, y+1);
772  p->drawLine(right-5, y+2, right-2, y+5);
773  p->setPen(cg.mid());
774  p->drawLine(right-1, y+6, right-1, bottom);
775 
776  TQPointArray a(6);
777  a.setPoint(0, x+2, bottom);
778  a.setPoint(1, x+2, y+7);
779  a.setPoint(2, x+7, y+2);
780  a.setPoint(3, right-7, y+2);
781  a.setPoint(4, right-2, y+7);
782  a.setPoint(5, right-2, bottom);
783  p->setPen (selected ? cg.background() : cg.mid());
784  p->setBrush(selected ? cg.background() : cg.mid());
785  p->drawPolygon(a);
786  p->setBrush(NoBrush);
787  if (!selected) {
788  p->translate(0,-1);
789  p->setPen(cg.light());
790  p->drawLine(x, bottom, right, bottom);
791  }
792  break;
793  }
794 
795  default: { // TQTabBar::TriangularBelow
796  if (!selected)
797  p->translate(0,-1);
798  p->setPen(selected ? cg.light() : cg.shadow());
799  p->drawLine(x, y, x, bottom-6);
800  if (selected)
801  p->setPen(cg.mid());
802  p->drawLine(x, bottom-6, x+6, bottom);
803  if (selected)
804  p->setPen(cg.shadow());
805  p->drawLine(x+6, bottom, right-6, bottom);
806  p->drawLine(right-5, bottom-1, right-1, bottom-5);
807  if (!selected)
808  p->setPen(cg.shadow());
809  p->drawLine(right, bottom-6, right, y);
810 
811  p->setPen(cg.midlight());
812  p->drawLine(x+1, y, x+1, bottom-6);
813  p->drawLine(x+1, bottom-6, x+6, bottom-1);
814  p->drawLine(x+6, bottom-1, right-6, bottom-1);
815  p->drawLine(right-5, bottom-2, right-2, bottom-5);
816  p->setPen(cg.mid());
817  p->drawLine(right-1, bottom-6, right-1, y);
818 
819  TQPointArray a(6);
820  a.setPoint(0, x+2, y);
821  a.setPoint(1, x+2, bottom-7);
822  a.setPoint(2, x+7, bottom-2);
823  a.setPoint(3, right-7, bottom-2);
824  a.setPoint(4, right-2, bottom-7);
825  a.setPoint(5, right-2, y);
826  p->setPen (selected ? cg.background() : cg.mid());
827  p->setBrush(selected ? cg.background() : cg.mid());
828  p->drawPolygon(a);
829  p->setBrush(NoBrush);
830  if (!selected) {
831  p->translate(0,1);
832  p->setPen(cg.dark());
833  p->drawLine(x, y, right, y);
834  }
835  break;
836  }
837  };
838 
839  break;
840  }
841 
842  // Popup menu scroller
843  // ------------------------------------------------------------------------
844  case CE_PopupMenuScroller: {
845  p->fillRect(r, cg.background());
846  drawPrimitive(PE_ButtonTool, p, ceData, elementFlags, r, cg, Style_Enabled);
847  drawPrimitive((flags & Style_Up) ? PE_ArrowUp : PE_ArrowDown, p, ceData, elementFlags, r, cg, Style_Enabled);
848  break;
849  }
850 
851 
852  // PROGRESSBAR
853  // ------------------------------------------------------------------------
854  case CE_ProgressBarGroove: {
855  TQRect fr = subRect(SR_ProgressBarGroove, ceData, elementFlags, widget);
856  drawPrimitive(PE_Panel, p, ceData, elementFlags, fr, cg, Style_Sunken, TQStyleOption::Default);
857  break;
858  }
859 
860  case CE_ProgressBarContents: {
861  // ### Take into account totalSteps() for busy indicator
862  TQRect cr = subRect(SR_ProgressBarContents, ceData, elementFlags, widget);
863  double progress = ceData.currentStep;
864  bool reverse = TQApplication::reverseLayout();
865  int steps = ceData.totalSteps;
866 
867  if (!cr.isValid())
868  return;
869 
870  // Draw progress bar
871  if (progress > 0 || steps == 0) {
872  double pg = (steps == 0) ? 0.1 : progress / steps;
873  int width = TQMIN(cr.width(), (int)(pg * cr.width()));
874  if (steps == 0) { //Busy indicator
875 
876  if (width < 1) width = 1; //A busy indicator with width 0 is kind of useless
877 
878  int remWidth = cr.width() - width; //Never disappear completely
879  if (remWidth <= 0) remWidth = 1; //Do something non-crashy when too small...
880 
881  int pstep = int(progress) % ( 2 * remWidth );
882 
883  if ( pstep > remWidth ) {
884  //Bounce about.. We're remWidth + some delta, we want to be remWidth - delta...
885  // - ( (remWidth + some delta) - 2* remWidth ) = - (some deleta - remWidth) = remWidth - some delta..
886  pstep = - (pstep - 2 * remWidth );
887  }
888 
889  if (reverse)
890  p->fillRect(cr.x() + cr.width() - width - pstep, cr.y(), width, cr.height(),
891  cg.brush(TQColorGroup::Highlight));
892  else
893  p->fillRect(cr.x() + pstep, cr.y(), width, cr.height(),
894  cg.brush(TQColorGroup::Highlight));
895 
896  return;
897  }
898 
899 
900  // Do fancy gradient for highcolor displays
901  if (d->highcolor) {
902  TQColor c(cg.highlight());
903  KPixmap pix;
904  pix.resize(cr.width(), cr.height());
905  KPixmapEffect::gradient(pix, reverse ? c.light(150) : c.dark(150),
906  reverse ? c.dark(150) : c.light(150),
907  KPixmapEffect::HorizontalGradient);
908  if (reverse)
909  p->drawPixmap(cr.x()+(cr.width()-width), cr.y(), pix,
910  cr.width()-width, 0, width, cr.height());
911  else
912  p->drawPixmap(cr.x(), cr.y(), pix, 0, 0, width, cr.height());
913  } else
914  if (reverse)
915  p->fillRect(cr.x()+(cr.width()-width), cr.y(), width, cr.height(),
916  cg.brush(TQColorGroup::Highlight));
917  else
918  p->fillRect(cr.x(), cr.y(), width, cr.height(),
919  cg.brush(TQColorGroup::Highlight));
920  }
921  break;
922  }
923 
924  case CE_ProgressBarLabel: {
925  TQRect cr = subRect(SR_ProgressBarContents, ceData, elementFlags, widget);
926  double progress = ceData.currentStep;
927  bool reverse = TQApplication::reverseLayout();
928  int steps = ceData.totalSteps;
929 
930  if (!cr.isValid())
931  return;
932 
933  TQFont font = p->font();
934  font.setBold(true);
935  p->setFont(font);
936 
937  // Draw label
938  if (progress > 0 || steps == 0) {
939  double pg = (steps == 0) ? 1.0 : progress / steps;
940  int width = TQMIN(cr.width(), (int)(pg * cr.width()));
941  TQRect crect;
942  if (reverse)
943  crect.setRect(cr.x()+(cr.width()-width), cr.y(), cr.width(), cr.height());
944  else
945  crect.setRect(cr.x()+width, cr.y(), cr.width(), cr.height());
946 
947  p->save();
948  p->setPen((elementFlags & CEF_IsEnabled) ? (reverse ? cg.text() : cg.highlightedText()) : cg.text());
949  p->drawText(r, AlignCenter, ceData.progressText);
950  p->setClipRect(crect);
951  p->setPen(reverse ? cg.highlightedText() : cg.text());
952  p->drawText(r, AlignCenter, ceData.progressText);
953  p->restore();
954 
955  } else {
956  p->setPen(cg.text());
957  p->drawText(r, AlignCenter, ceData.progressText);
958  }
959 
960  break;
961  }
962 
963  default:
964  TQCommonStyle::drawControl(element, p, ceData, elementFlags, r, cg, flags, opt, widget);
965  }
966 }
967 
968 
969 TQRect TDEStyle::subRect(SubRect r, const TQStyleControlElementData &ceData, const ControlElementFlags elementFlags, const TQWidget* widget) const
970 {
971  switch(r)
972  {
973  // KDE2 look smooth progress bar
974  // ------------------------------------------------------------------------
975  case SR_ProgressBarGroove:
976  return ceData.rect;
977 
978  case SR_ProgressBarContents:
979  case SR_ProgressBarLabel: {
980  // ### take into account indicatorFollowsStyle()
981  TQRect rt = ceData.rect;
982  return TQRect(rt.x()+2, rt.y()+2, rt.width()-4, rt.height()-4);
983  }
984 
985  default:
986  return TQCommonStyle::subRect(r, ceData, elementFlags, widget);
987  }
988 }
989 
990 
991 int TDEStyle::pixelMetric(PixelMetric m, const TQStyleControlElementData &ceData, ControlElementFlags elementFlags, const TQWidget* widget) const
992 {
993  switch(m)
994  {
995  // BUTTONS
996  // ------------------------------------------------------------------------
997  case PM_ButtonShiftHorizontal: // Offset by 1
998  case PM_ButtonShiftVertical: // ### Make configurable
999  return 1;
1000 
1001  case PM_DockWindowHandleExtent:
1002  {
1003  // Check that we are not a normal toolbar or a hidden dockwidget,
1004  // in which case we need to adjust the height for font size
1005  if (widget
1006  && !(ceData.parentWidgetData.widgetObjectTypes.contains("TQToolBar"))
1007  && !(ceData.parentWidgetData.widgetObjectTypes.contains("TQMainWindow"))
1008  && (ceData.widgetObjectTypes.contains("TQDockWindowHandle")) )
1009  return widget->fontMetrics().lineSpacing();
1010  else
1011  return TQCommonStyle::pixelMetric(m, ceData, elementFlags, widget);
1012  }
1013 
1014  // TABS
1015  // ------------------------------------------------------------------------
1016  case PM_TabBarTabHSpace:
1017  return 24;
1018 
1019  case PM_TabBarTabVSpace: {
1020  if ( ceData.tabBarData.shape == TQTabBar::RoundedAbove ||
1021  ceData.tabBarData.shape == TQTabBar::RoundedBelow )
1022  return 10;
1023  else
1024  return 4;
1025  }
1026 
1027  case PM_TabBarTabOverlap: {
1028  TQTabBar::Shape tbs = ceData.tabBarData.shape;
1029 
1030  if ( (tbs == TQTabBar::RoundedAbove) ||
1031  (tbs == TQTabBar::RoundedBelow) )
1032  return 0;
1033  else
1034  return 2;
1035  }
1036 
1037  // SLIDER
1038  // ------------------------------------------------------------------------
1039  case PM_SliderLength:
1040  return 18;
1041 
1042  case PM_SliderThickness:
1043  return 24;
1044 
1045  // Determines how much space to leave for the actual non-tickmark
1046  // portion of the slider.
1047  case PM_SliderControlThickness: {
1048  TQSlider::TickSetting ts = (TQSlider::TickSetting)ceData.tickMarkSetting;
1049  int thickness = (ceData.orientation == TQt::Horizontal) ?
1050  ceData.rect.height() : ceData.rect.width();
1051  switch (ts) {
1052  case TQSlider::NoMarks: // Use total area.
1053  break;
1054  case TQSlider::Both:
1055  thickness = (thickness/2) + 3; // Use approx. 1/2 of area.
1056  break;
1057  default: // Use approx. 2/3 of area
1058  thickness = ((thickness*2)/3) + 3;
1059  break;
1060  };
1061  return thickness;
1062  }
1063 
1064  // SPLITTER
1065  // ------------------------------------------------------------------------
1066  case PM_SplitterWidth:
1067  if (ceData.widgetObjectTypes.contains("TQDockWindowResizeHandle"))
1068  return 8; // ### why do we need 2pix extra?
1069  else
1070  return 6;
1071 
1072  // FRAMES
1073  // ------------------------------------------------------------------------
1074  case PM_MenuBarFrameWidth:
1075  return 1;
1076 
1077  case PM_DockWindowFrameWidth:
1078  return 1;
1079 
1080  // GENERAL
1081  // ------------------------------------------------------------------------
1082  case PM_MaximumDragDistance:
1083  return -1;
1084 
1085  case PM_MenuBarItemSpacing:
1086  return 5;
1087 
1088  case PM_ToolBarItemSpacing:
1089  return 0;
1090 
1091  case PM_PopupMenuScrollerHeight:
1092  return pixelMetric( PM_ScrollBarExtent, ceData, elementFlags, 0);
1093 
1094  default:
1095  return TQCommonStyle::pixelMetric( m, ceData, elementFlags, widget );
1096  }
1097 }
1098 
1099 //Helper to find the next sibling that's not hidden
1100 static TQListViewItem* nextVisibleSibling(TQListViewItem* item)
1101 {
1102  TQListViewItem* sibling = item;
1103  do
1104  {
1105  sibling = sibling->nextSibling();
1106  }
1107  while (sibling && !sibling->isVisible());
1108 
1109  return sibling;
1110 }
1111 
1112 void TDEStyle::drawComplexControl( ComplexControl control,
1113  TQPainter* p,
1114  const TQStyleControlElementData &ceData,
1115  ControlElementFlags elementFlags,
1116  const TQRect &r,
1117  const TQColorGroup &cg,
1118  SFlags flags,
1119  SCFlags controls,
1120  SCFlags active,
1121  const TQStyleOption &opt,
1122  const TQWidget* widget ) const
1123 {
1124  switch(control)
1125  {
1126  // 3 BUTTON SCROLLBAR
1127  // ------------------------------------------------------------------------
1128  case CC_ScrollBar: {
1129  // Many thanks to Brad Hughes for contributing this code.
1130  bool useThreeButtonScrollBar = (d->scrollbarType & ThreeButtonScrollBar);
1131 
1132  bool maxedOut = (ceData.minSteps == ceData.maxSteps);
1133  bool horizontal = (ceData.orientation == TQt::Horizontal);
1134  SFlags sflags = ((horizontal ? Style_Horizontal : Style_Default) |
1135  (maxedOut ? Style_Default : Style_Enabled));
1136 
1137  TQRect addline, subline, subline2, addpage, subpage, slider, first, last;
1138  subline = querySubControlMetrics(control, ceData, elementFlags, SC_ScrollBarSubLine, opt, widget);
1139  addline = querySubControlMetrics(control, ceData, elementFlags, SC_ScrollBarAddLine, opt, widget);
1140  subpage = querySubControlMetrics(control, ceData, elementFlags, SC_ScrollBarSubPage, opt, widget);
1141  addpage = querySubControlMetrics(control, ceData, elementFlags, SC_ScrollBarAddPage, opt, widget);
1142  slider = querySubControlMetrics(control, ceData, elementFlags, SC_ScrollBarSlider, opt, widget);
1143  first = querySubControlMetrics(control, ceData, elementFlags, SC_ScrollBarFirst, opt, widget);
1144  last = querySubControlMetrics(control, ceData, elementFlags, SC_ScrollBarLast, opt, widget);
1145  subline2 = addline;
1146 
1147  if ( useThreeButtonScrollBar ) {
1148  if (horizontal) {
1149  subline2.moveBy(-addline.width(), 0);
1150  }
1151  else {
1152  subline2.moveBy(0, -addline.height());
1153  }
1154  }
1155 
1156  // Draw the up/left button set
1157  if ((controls & SC_ScrollBarSubLine) && subline.isValid()) {
1158  drawPrimitive(PE_ScrollBarSubLine, p, ceData, elementFlags, subline, cg,
1159  sflags | (active == SC_ScrollBarSubLine ?
1160  Style_Down : Style_Default));
1161 
1162  if (useThreeButtonScrollBar && subline2.isValid())
1163  drawPrimitive(PE_ScrollBarSubLine, p, ceData, elementFlags, subline2, cg,
1164  sflags | (active == SC_ScrollBarSubLine ?
1165  Style_Down : Style_Default));
1166  }
1167 
1168  if ((controls & SC_ScrollBarAddLine) && addline.isValid())
1169  drawPrimitive(PE_ScrollBarAddLine, p, ceData, elementFlags, addline, cg,
1170  sflags | ((active == SC_ScrollBarAddLine) ?
1171  Style_Down : Style_Default));
1172 
1173  if ((controls & SC_ScrollBarSubPage) && subpage.isValid())
1174  drawPrimitive(PE_ScrollBarSubPage, p, ceData, elementFlags, subpage, cg,
1175  sflags | ((active == SC_ScrollBarSubPage) ?
1176  Style_Down : Style_Default));
1177 
1178  if ((controls & SC_ScrollBarAddPage) && addpage.isValid())
1179  drawPrimitive(PE_ScrollBarAddPage, p, ceData, elementFlags, addpage, cg,
1180  sflags | ((active == SC_ScrollBarAddPage) ?
1181  Style_Down : Style_Default));
1182 
1183  if ((controls & SC_ScrollBarFirst) && first.isValid())
1184  drawPrimitive(PE_ScrollBarFirst, p, ceData, elementFlags, first, cg,
1185  sflags | ((active == SC_ScrollBarFirst) ?
1186  Style_Down : Style_Default));
1187 
1188  if ((controls & SC_ScrollBarLast) && last.isValid())
1189  drawPrimitive(PE_ScrollBarLast, p, ceData, elementFlags, last, cg,
1190  sflags | ((active == SC_ScrollBarLast) ?
1191  Style_Down : Style_Default));
1192 
1193  if ((controls & SC_ScrollBarSlider) && slider.isValid()) {
1194  drawPrimitive(PE_ScrollBarSlider, p, ceData, elementFlags, slider, cg,
1195  sflags | ((active == SC_ScrollBarSlider) ?
1196  Style_Down : Style_Default));
1197  // Draw focus rect
1198  if (elementFlags & CEF_HasFocus) {
1199  TQRect fr(slider.x() + 2, slider.y() + 2,
1200  slider.width() - 5, slider.height() - 5);
1201  drawPrimitive(PE_FocusRect, p, ceData, elementFlags, fr, cg, Style_Default);
1202  }
1203  }
1204  break;
1205  }
1206 
1207 
1208  // SLIDER
1209  // -------------------------------------------------------------------
1210  case CC_Slider: {
1211  TQRect groove = querySubControlMetrics(CC_Slider, ceData, elementFlags, SC_SliderGroove, opt, widget);
1212  TQRect handle = querySubControlMetrics(CC_Slider, ceData, elementFlags, SC_SliderHandle, opt, widget);
1213 
1214  // Double-buffer slider for no flicker
1215  TQPixmap pix(ceData.rect.size());
1216  TQPainter p2;
1217  p2.begin(&pix);
1218 
1219  if ( (elementFlags & CEF_HasParentWidget) &&
1220  !ceData.parentWidgetData.bgPixmap.isNull() ) {
1221  TQPixmap pixmap = ceData.parentWidgetData.bgPixmap;
1222  p2.drawTiledPixmap(r, pixmap, ceData.pos);
1223  } else
1224  pix.fill(cg.background());
1225 
1226  // Draw slider groove
1227  if ((controls & SC_SliderGroove) && groove.isValid()) {
1228  drawTDEStylePrimitive( KPE_SliderGroove, &p2, ceData, elementFlags, groove, cg, flags, opt, widget );
1229 
1230  // Draw the focus rect around the groove
1231  if (elementFlags & CEF_HasFocus) {
1232  drawPrimitive(PE_FocusRect, &p2, ceData, elementFlags, groove, cg);
1233  }
1234  }
1235 
1236  // Draw the tickmarks
1237  if (controls & SC_SliderTickmarks)
1238  TQCommonStyle::drawComplexControl(control, &p2, ceData, elementFlags,
1239  r, cg, flags, SC_SliderTickmarks, active, opt, widget);
1240 
1241  // Draw the slider handle
1242  if ((controls & SC_SliderHandle) && handle.isValid()) {
1243  if (active == SC_SliderHandle)
1244  flags |= Style_Active;
1245  drawTDEStylePrimitive( KPE_SliderHandle, &p2, ceData, elementFlags, handle, cg, flags, opt, widget );
1246  }
1247 
1248  p2.end();
1249 
1250  TQPaintDevice* ppd = p->device();
1251  if (ppd->isExtDev()) {
1252  p->drawPixmap(0, 0, pix);
1253  }
1254  else {
1255  bitBlt((TQWidget*)widget, r.x(), r.y(), &pix);
1256  }
1257  break;
1258  }
1259 
1260  // LISTVIEW
1261  // -------------------------------------------------------------------
1262  case CC_ListView: {
1263 
1264  /*
1265  * Many thanks to TrollTech AS for donating CC_ListView from TQWindowsStyle.
1266  * CC_ListView code is Copyright (C) 1998-2000 TrollTech AS.
1267  */
1268 
1269  // Paint the icon and text.
1270  if ( controls & SC_ListView )
1271  TQCommonStyle::drawComplexControl( control, p, ceData, elementFlags, r, cg, flags, controls, active, opt, widget );
1272 
1273  // If we're have a branch or are expanded...
1274  if ( controls & (SC_ListViewBranch | SC_ListViewExpand) )
1275  {
1276  // If no list view item was supplied, break
1277  if (opt.isDefault())
1278  break;
1279 
1280  TQListViewItem *item = opt.listViewItem();
1281  TQListViewItem *child = item->firstChild();
1282 
1283  int y = r.y();
1284  int c; // dotline vertice count
1285  int dotoffset = 0;
1286  TQPointArray dotlines;
1287 
1288  if ( active == SC_All && controls == SC_ListViewExpand ) {
1289  // We only need to draw a vertical line
1290  c = 2;
1291  dotlines.resize(2);
1292  dotlines[0] = TQPoint( r.right(), r.top() );
1293  dotlines[1] = TQPoint( r.right(), r.bottom() );
1294 
1295  } else {
1296 
1297  int linetop = 0, linebot = 0;
1298  // each branch needs at most two lines, ie. four end points
1299  dotoffset = (item->itemPos() + item->height() - y) % 2;
1300  dotlines.resize( item->childCount() * 4 );
1301  c = 0;
1302 
1303  // skip the stuff above the exposed rectangle
1304  while ( child && y + child->height() <= 0 )
1305  {
1306  y += child->totalHeight();
1307  child = nextVisibleSibling(child);
1308  }
1309 
1310  int bx = r.width() / 2;
1311 
1312  // paint stuff in the magical area
1313  TQListView* v = item->listView();
1314  int lh = TQMAX( p->fontMetrics().height() + 2 * v->itemMargin(),
1315  TQApplication::globalStrut().height() );
1316  if ( lh % 2 > 0 )
1317  lh++;
1318 
1319  // Draw all the expand/close boxes...
1320  TQRect boxrect;
1321  TQStyle::StyleFlags boxflags;
1322  while ( child && y < r.height() )
1323  {
1324  linebot = y + lh/2;
1325  if ( (child->isExpandable() || child->childCount()) &&
1326  (child->height() > 0) )
1327  {
1328  // The primitive requires a rect.
1329  boxrect = TQRect( bx-4, linebot-4, 9, 9 );
1330  boxflags = child->isOpen() ? TQStyle::Style_Off : TQStyle::Style_On;
1331 
1332  // TDEStyle extension: Draw the box and expand/collapse indicator
1333  drawTDEStylePrimitive( KPE_ListViewExpander, p, ceData, elementFlags, boxrect, cg, boxflags, opt, NULL );
1334 
1335  // dotlinery
1336  p->setPen( cg.mid() );
1337  dotlines[c++] = TQPoint( bx, linetop );
1338  dotlines[c++] = TQPoint( bx, linebot - 5 );
1339  dotlines[c++] = TQPoint( bx + 5, linebot );
1340  dotlines[c++] = TQPoint( r.width(), linebot );
1341  linetop = linebot + 5;
1342  } else {
1343  // just dotlinery
1344  dotlines[c++] = TQPoint( bx+1, linebot );
1345  dotlines[c++] = TQPoint( r.width(), linebot );
1346  }
1347 
1348  y += child->totalHeight();
1349  child = nextVisibleSibling(child);
1350  }
1351 
1352  if ( child ) // there's a child to draw, so move linebot to edge of rectangle
1353  linebot = r.height();
1354 
1355  if ( linetop < linebot )
1356  {
1357  dotlines[c++] = TQPoint( bx, linetop );
1358  dotlines[c++] = TQPoint( bx, linebot );
1359  }
1360  }
1361 
1362  // Draw all the branches...
1363  static int thickness = kPixelMetric( KPM_ListViewBranchThickness, ceData, elementFlags );
1364  int line; // index into dotlines
1365  TQRect branchrect;
1366  TQStyle::StyleFlags branchflags;
1367  for( line = 0; line < c; line += 2 )
1368  {
1369  // assumptions here: lines are horizontal or vertical.
1370  // lines always start with the numerically lowest
1371  // coordinate.
1372 
1373  // point ... relevant coordinate of current point
1374  // end ..... same coordinate of the end of the current line
1375  // other ... the other coordinate of the current point/line
1376  if ( dotlines[line].y() == dotlines[line+1].y() )
1377  {
1378  // Horizontal branch
1379  int end = dotlines[line+1].x();
1380  int point = dotlines[line].x();
1381  int other = dotlines[line].y();
1382 
1383  branchrect = TQRect( point, other-(thickness/2), end-point, thickness );
1384  branchflags = TQStyle::Style_Horizontal;
1385 
1386  // TDEStyle extension: Draw the horizontal branch
1387  drawTDEStylePrimitive( KPE_ListViewBranch, p, ceData, elementFlags, branchrect, cg, branchflags, opt, NULL );
1388 
1389  } else {
1390  // Vertical branch
1391  int end = dotlines[line+1].y();
1392  int point = dotlines[line].y();
1393  int other = dotlines[line].x();
1394  int pixmapoffset = ((point & 1) != dotoffset ) ? 1 : 0;
1395 
1396  branchrect = TQRect( other-(thickness/2), point, thickness, end-point );
1397  if (!pixmapoffset) // ### Hackish - used to hint the offset
1398  branchflags = TQStyle::Style_NoChange;
1399  else
1400  branchflags = TQStyle::Style_Default;
1401 
1402  // TDEStyle extension: Draw the vertical branch
1403  drawTDEStylePrimitive( KPE_ListViewBranch, p, ceData, elementFlags, branchrect, cg, branchflags, opt, NULL );
1404  }
1405  }
1406  }
1407  break;
1408  }
1409 
1410  default:
1411  TQCommonStyle::drawComplexControl( control, p, ceData, elementFlags, r, cg,
1412  flags, controls, active, opt, widget );
1413  break;
1414  }
1415 }
1416 
1417 
1418 TQStyle::SubControl TDEStyle::querySubControl( ComplexControl control,
1419  const TQStyleControlElementData &ceData,
1420  ControlElementFlags elementFlags,
1421  const TQPoint &pos,
1422  const TQStyleOption &opt,
1423  const TQWidget* widget ) const
1424 {
1425  TQStyle::SubControl ret = TQCommonStyle::querySubControl(control, ceData, elementFlags, pos, opt, widget);
1426 
1427  if (d->scrollbarType == ThreeButtonScrollBar) {
1428  // Enable third button
1429  if (control == CC_ScrollBar && ret == SC_None)
1430  ret = SC_ScrollBarSubLine;
1431  }
1432  return ret;
1433 }
1434 
1435 
1436 TQRect TDEStyle::querySubControlMetrics( ComplexControl control,
1437  const TQStyleControlElementData &ceData,
1438  ControlElementFlags elementFlags,
1439  SubControl sc,
1440  const TQStyleOption &opt,
1441  const TQWidget* widget ) const
1442 {
1443  TQRect ret;
1444 
1445  if (control == CC_ScrollBar)
1446  {
1447  bool threeButtonScrollBar = d->scrollbarType & ThreeButtonScrollBar;
1448  bool platinumScrollBar = d->scrollbarType & PlatinumStyleScrollBar;
1449  bool nextScrollBar = d->scrollbarType & NextStyleScrollBar;
1450 
1451  bool horizontal = ceData.orientation == TQt::Horizontal;
1452  int sliderstart = ceData.startStep;
1453  int sbextent = pixelMetric(PM_ScrollBarExtent, ceData, elementFlags, widget);
1454  int maxlen = (horizontal ? ceData.rect.width() : ceData.rect.height())
1455  - (sbextent * (threeButtonScrollBar ? 3 : 2));
1456  int sliderlen;
1457 
1458  // calculate slider length
1459  if (ceData.maxSteps != ceData.minSteps)
1460  {
1461  uint range = ceData.maxSteps - ceData.minSteps;
1462  sliderlen = (ceData.pageStep * maxlen) / (range + ceData.pageStep);
1463 
1464  int slidermin = pixelMetric( PM_ScrollBarSliderMin, ceData, elementFlags, widget );
1465  if ( sliderlen < slidermin || range > INT_MAX / 2 )
1466  sliderlen = slidermin;
1467  if ( sliderlen > maxlen )
1468  sliderlen = maxlen;
1469  } else
1470  sliderlen = maxlen;
1471 
1472  // Subcontrols
1473  switch (sc)
1474  {
1475  case SC_ScrollBarSubLine: {
1476  // top/left button
1477  if (platinumScrollBar) {
1478  if (horizontal)
1479  ret.setRect(ceData.rect.width() - 2 * sbextent, 0, sbextent, sbextent);
1480  else
1481  ret.setRect(0, ceData.rect.height() - 2 * sbextent, sbextent, sbextent);
1482  } else
1483  ret.setRect(0, 0, sbextent, sbextent);
1484  break;
1485  }
1486 
1487  case SC_ScrollBarAddLine: {
1488  // bottom/right button
1489  if (nextScrollBar) {
1490  if (horizontal)
1491  ret.setRect(sbextent, 0, sbextent, sbextent);
1492  else
1493  ret.setRect(0, sbextent, sbextent, sbextent);
1494  } else {
1495  if (horizontal)
1496  ret.setRect(ceData.rect.width() - sbextent, 0, sbextent, sbextent);
1497  else
1498  ret.setRect(0, ceData.rect.height() - sbextent, sbextent, sbextent);
1499  }
1500  break;
1501  }
1502 
1503  case SC_ScrollBarSubPage: {
1504  // between top/left button and slider
1505  if (platinumScrollBar) {
1506  if (horizontal)
1507  ret.setRect(0, 0, sliderstart, sbextent);
1508  else
1509  ret.setRect(0, 0, sbextent, sliderstart);
1510  } else if (nextScrollBar) {
1511  if (horizontal)
1512  ret.setRect(sbextent*2, 0, sliderstart-2*sbextent, sbextent);
1513  else
1514  ret.setRect(0, sbextent*2, sbextent, sliderstart-2*sbextent);
1515  } else {
1516  if (horizontal)
1517  ret.setRect(sbextent, 0, sliderstart - sbextent, sbextent);
1518  else
1519  ret.setRect(0, sbextent, sbextent, sliderstart - sbextent);
1520  }
1521  break;
1522  }
1523 
1524  case SC_ScrollBarAddPage: {
1525  // between bottom/right button and slider
1526  int fudge;
1527 
1528  if (platinumScrollBar)
1529  fudge = 0;
1530  else if (nextScrollBar)
1531  fudge = 2*sbextent;
1532  else
1533  fudge = sbextent;
1534 
1535  if (horizontal)
1536  ret.setRect(sliderstart + sliderlen, 0,
1537  maxlen - sliderstart - sliderlen + fudge, sbextent);
1538  else
1539  ret.setRect(0, sliderstart + sliderlen, sbextent,
1540  maxlen - sliderstart - sliderlen + fudge);
1541  break;
1542  }
1543 
1544  case SC_ScrollBarGroove: {
1545  int multi = threeButtonScrollBar ? 3 : 2;
1546  int fudge;
1547 
1548  if (platinumScrollBar)
1549  fudge = 0;
1550  else if (nextScrollBar)
1551  fudge = 2*sbextent;
1552  else
1553  fudge = sbextent;
1554 
1555  if (horizontal)
1556  ret.setRect(fudge, 0, ceData.rect.width() - sbextent * multi, ceData.rect.height());
1557  else
1558  ret.setRect(0, fudge, ceData.rect.width(), ceData.rect.height() - sbextent * multi);
1559  break;
1560  }
1561 
1562  case SC_ScrollBarSlider: {
1563  if (horizontal)
1564  ret.setRect(sliderstart, 0, sliderlen, sbextent);
1565  else
1566  ret.setRect(0, sliderstart, sbextent, sliderlen);
1567  break;
1568  }
1569 
1570  default:
1571  ret = TQCommonStyle::querySubControlMetrics(control, ceData, elementFlags, sc, opt, widget);
1572  break;
1573  }
1574  } else
1575  ret = TQCommonStyle::querySubControlMetrics(control, ceData, elementFlags, sc, opt, widget);
1576 
1577  return ret;
1578 }
1579 
1580 static const char * const tdestyle_close_xpm[] = {
1581 "12 12 2 1",
1582 "# c #000000",
1583 ". c None",
1584 "............",
1585 "............",
1586 "..##....##..",
1587 "...##..##...",
1588 "....####....",
1589 ".....##.....",
1590 "....####....",
1591 "...##..##...",
1592 "..##....##..",
1593 "............",
1594 "............",
1595 "............"};
1596 
1597 static const char * const tdestyle_maximize_xpm[]={
1598 "12 12 2 1",
1599 "# c #000000",
1600 ". c None",
1601 "............",
1602 "............",
1603 ".##########.",
1604 ".##########.",
1605 ".#........#.",
1606 ".#........#.",
1607 ".#........#.",
1608 ".#........#.",
1609 ".#........#.",
1610 ".#........#.",
1611 ".##########.",
1612 "............"};
1613 
1614 
1615 static const char * const tdestyle_minimize_xpm[] = {
1616 "12 12 2 1",
1617 "# c #000000",
1618 ". c None",
1619 "............",
1620 "............",
1621 "............",
1622 "............",
1623 "............",
1624 "............",
1625 "............",
1626 "...######...",
1627 "...######...",
1628 "............",
1629 "............",
1630 "............"};
1631 
1632 static const char * const tdestyle_normalizeup_xpm[] = {
1633 "12 12 2 1",
1634 "# c #000000",
1635 ". c None",
1636 "............",
1637 "...#######..",
1638 "...#######..",
1639 "...#.....#..",
1640 ".#######.#..",
1641 ".#######.#..",
1642 ".#.....#.#..",
1643 ".#.....###..",
1644 ".#.....#....",
1645 ".#.....#....",
1646 ".#######....",
1647 "............"};
1648 
1649 
1650 static const char * const tdestyle_shade_xpm[] = {
1651 "12 12 2 1",
1652 "# c #000000",
1653 ". c None",
1654 "............",
1655 "............",
1656 "............",
1657 "............",
1658 "............",
1659 ".....#......",
1660 "....###.....",
1661 "...#####....",
1662 "..#######...",
1663 "............",
1664 "............",
1665 "............"};
1666 
1667 static const char * const tdestyle_unshade_xpm[] = {
1668 "12 12 2 1",
1669 "# c #000000",
1670 ". c None",
1671 "............",
1672 "............",
1673 "............",
1674 "............",
1675 "..#######...",
1676 "...#####....",
1677 "....###.....",
1678 ".....#......",
1679 "............",
1680 "............",
1681 "............",
1682 "............"};
1683 
1684 static const char * const dock_window_close_xpm[] = {
1685 "8 8 2 1",
1686 "# c #000000",
1687 ". c None",
1688 "##....##",
1689 ".##..##.",
1690 "..####..",
1691 "...##...",
1692 "..####..",
1693 ".##..##.",
1694 "##....##",
1695 "........"};
1696 
1697 // Message box icons, from page 210 of the Windows style guide.
1698 
1699 // Hand-drawn to resemble Microsoft's icons, but in the Mac/Netscape
1700 // palette. The "question mark" icon, which Microsoft recommends not
1701 // using but a lot of people still use, is left out.
1702 
1703 /* XPM */
1704 static const char * const information_xpm[]={
1705 "32 32 5 1",
1706 ". c None",
1707 "c c #000000",
1708 "* c #999999",
1709 "a c #ffffff",
1710 "b c #0000ff",
1711 "...........********.............",
1712 "........***aaaaaaaa***..........",
1713 "......**aaaaaaaaaaaaaa**........",
1714 ".....*aaaaaaaaaaaaaaaaaa*.......",
1715 "....*aaaaaaaabbbbaaaaaaaac......",
1716 "...*aaaaaaaabbbbbbaaaaaaaac.....",
1717 "..*aaaaaaaaabbbbbbaaaaaaaaac....",
1718 ".*aaaaaaaaaaabbbbaaaaaaaaaaac...",
1719 ".*aaaaaaaaaaaaaaaaaaaaaaaaaac*..",
1720 "*aaaaaaaaaaaaaaaaaaaaaaaaaaaac*.",
1721 "*aaaaaaaaaabbbbbbbaaaaaaaaaaac*.",
1722 "*aaaaaaaaaaaabbbbbaaaaaaaaaaac**",
1723 "*aaaaaaaaaaaabbbbbaaaaaaaaaaac**",
1724 "*aaaaaaaaaaaabbbbbaaaaaaaaaaac**",
1725 "*aaaaaaaaaaaabbbbbaaaaaaaaaaac**",
1726 "*aaaaaaaaaaaabbbbbaaaaaaaaaaac**",
1727 ".*aaaaaaaaaaabbbbbaaaaaaaaaac***",
1728 ".*aaaaaaaaaaabbbbbaaaaaaaaaac***",
1729 "..*aaaaaaaaaabbbbbaaaaaaaaac***.",
1730 "...caaaaaaabbbbbbbbbaaaaaac****.",
1731 "....caaaaaaaaaaaaaaaaaaaac****..",
1732 ".....caaaaaaaaaaaaaaaaaac****...",
1733 "......ccaaaaaaaaaaaaaacc****....",
1734 ".......*cccaaaaaaaaccc*****.....",
1735 "........***cccaaaac*******......",
1736 "..........****caaac*****........",
1737 ".............*caaac**...........",
1738 "...............caac**...........",
1739 "................cac**...........",
1740 ".................cc**...........",
1741 "..................***...........",
1742 "...................**..........."};
1743 /* XPM */
1744 static const char* const warning_xpm[]={
1745 "32 32 4 1",
1746 ". c None",
1747 "a c #ffff00",
1748 "* c #000000",
1749 "b c #999999",
1750 ".............***................",
1751 "............*aaa*...............",
1752 "...........*aaaaa*b.............",
1753 "...........*aaaaa*bb............",
1754 "..........*aaaaaaa*bb...........",
1755 "..........*aaaaaaa*bb...........",
1756 ".........*aaaaaaaaa*bb..........",
1757 ".........*aaaaaaaaa*bb..........",
1758 "........*aaaaaaaaaaa*bb.........",
1759 "........*aaaa***aaaa*bb.........",
1760 ".......*aaaa*****aaaa*bb........",
1761 ".......*aaaa*****aaaa*bb........",
1762 "......*aaaaa*****aaaaa*bb.......",
1763 "......*aaaaa*****aaaaa*bb.......",
1764 ".....*aaaaaa*****aaaaaa*bb......",
1765 ".....*aaaaaa*****aaaaaa*bb......",
1766 "....*aaaaaaaa***aaaaaaaa*bb.....",
1767 "....*aaaaaaaa***aaaaaaaa*bb.....",
1768 "...*aaaaaaaaa***aaaaaaaaa*bb....",
1769 "...*aaaaaaaaaa*aaaaaaaaaa*bb....",
1770 "..*aaaaaaaaaaa*aaaaaaaaaaa*bb...",
1771 "..*aaaaaaaaaaaaaaaaaaaaaaa*bb...",
1772 ".*aaaaaaaaaaaa**aaaaaaaaaaa*bb..",
1773 ".*aaaaaaaaaaa****aaaaaaaaaa*bb..",
1774 "*aaaaaaaaaaaa****aaaaaaaaaaa*bb.",
1775 "*aaaaaaaaaaaaa**aaaaaaaaaaaa*bb.",
1776 "*aaaaaaaaaaaaaaaaaaaaaaaaaaa*bbb",
1777 "*aaaaaaaaaaaaaaaaaaaaaaaaaaa*bbb",
1778 ".*aaaaaaaaaaaaaaaaaaaaaaaaa*bbbb",
1779 "..*************************bbbbb",
1780 "....bbbbbbbbbbbbbbbbbbbbbbbbbbb.",
1781 ".....bbbbbbbbbbbbbbbbbbbbbbbbb.."};
1782 /* XPM */
1783 static const char* const critical_xpm[]={
1784 "32 32 4 1",
1785 ". c None",
1786 "a c #999999",
1787 "* c #ff0000",
1788 "b c #ffffff",
1789 "...........********.............",
1790 ".........************...........",
1791 ".......****************.........",
1792 "......******************........",
1793 ".....********************a......",
1794 "....**********************a.....",
1795 "...************************a....",
1796 "..*******b**********b*******a...",
1797 "..******bbb********bbb******a...",
1798 ".******bbbbb******bbbbb******a..",
1799 ".*******bbbbb****bbbbb*******a..",
1800 "*********bbbbb**bbbbb*********a.",
1801 "**********bbbbbbbbbb**********a.",
1802 "***********bbbbbbbb***********aa",
1803 "************bbbbbb************aa",
1804 "************bbbbbb************aa",
1805 "***********bbbbbbbb***********aa",
1806 "**********bbbbbbbbbb**********aa",
1807 "*********bbbbb**bbbbb*********aa",
1808 ".*******bbbbb****bbbbb*******aa.",
1809 ".******bbbbb******bbbbb******aa.",
1810 "..******bbb********bbb******aaa.",
1811 "..*******b**********b*******aa..",
1812 "...************************aaa..",
1813 "....**********************aaa...",
1814 "....a********************aaa....",
1815 ".....a******************aaa.....",
1816 "......a****************aaa......",
1817 ".......aa************aaaa.......",
1818 ".........aa********aaaaa........",
1819 "...........aaaaaaaaaaa..........",
1820 ".............aaaaaaa............"};
1821 
1822 TQPixmap TDEStyle::stylePixmap( StylePixmap stylepixmap,
1823  const TQStyleControlElementData &ceData,
1824  ControlElementFlags elementFlags,
1825  const TQStyleOption& opt,
1826  const TQWidget* widget) const
1827 {
1828  switch (stylepixmap) {
1829  case SP_TitleBarShadeButton:
1830  return TQPixmap(const_cast<const char**>(tdestyle_shade_xpm));
1831  case SP_TitleBarUnshadeButton:
1832  return TQPixmap(const_cast<const char**>(tdestyle_unshade_xpm));
1833  case SP_TitleBarNormalButton:
1834  return TQPixmap(const_cast<const char**>(tdestyle_normalizeup_xpm));
1835  case SP_TitleBarMinButton:
1836  return TQPixmap(const_cast<const char**>(tdestyle_minimize_xpm));
1837  case SP_TitleBarMaxButton:
1838  return TQPixmap(const_cast<const char**>(tdestyle_maximize_xpm));
1839  case SP_TitleBarCloseButton:
1840  return TQPixmap(const_cast<const char**>(tdestyle_close_xpm));
1841  case SP_DockWindowCloseButton:
1842  return TQPixmap(const_cast<const char**>(dock_window_close_xpm ));
1843  case SP_MessageBoxInformation:
1844  return TQPixmap(const_cast<const char**>(information_xpm));
1845  case SP_MessageBoxWarning:
1846  return TQPixmap(const_cast<const char**>(warning_xpm));
1847  case SP_MessageBoxCritical:
1848  return TQPixmap(const_cast<const char**>(critical_xpm));
1849  default:
1850  break;
1851  }
1852  return TQCommonStyle::stylePixmap(stylepixmap, ceData, elementFlags, opt, widget);
1853 }
1854 
1855 
1856 int TDEStyle::styleHint( StyleHint sh, const TQStyleControlElementData &ceData, ControlElementFlags elementFlags,
1857  const TQStyleOption &opt, TQStyleHintReturn* shr, const TQWidget* w) const
1858 {
1859  switch (sh)
1860  {
1861  case SH_EtchDisabledText:
1862  return d->etchDisabledText ? 1 : 0;
1863 
1864  case SH_PopupMenu_Scrollable:
1865  return d->scrollablePopupmenus ? 1 : 0;
1866 
1867  case SH_HideUnderlineAcceleratorWhenAltUp:
1868  return d->autoHideAccelerators ? 1 : 0;
1869 
1870  case SH_MenuBar_AltKeyNavigation:
1871  return d->menuAltKeyNavigation ? 1 : 0;
1872 
1873  case SH_PopupMenu_SubMenuPopupDelay:
1874  if ( styleHint( SH_PopupMenu_SloppySubMenus, ceData, elementFlags, TQStyleOption::Default, 0, w ) )
1875  return TQMIN( 100, d->popupMenuDelay );
1876  else
1877  return d->popupMenuDelay;
1878 
1879  case SH_PopupMenu_SloppySubMenus:
1880  return d->sloppySubMenus;
1881 
1882  case SH_ItemView_ChangeHighlightOnFocus:
1883  case SH_Slider_SloppyKeyEvents:
1884  case SH_MainWindow_SpaceBelowMenuBar:
1885  case SH_PopupMenu_AllowActiveAndDisabled:
1886  return 0;
1887 
1888  case SH_Slider_SnapToValue:
1889  case SH_PrintDialog_RightAlignButtons:
1890  case SH_FontDialog_SelectAssociatedText:
1891  case SH_MenuBar_MouseTracking:
1892  case SH_PopupMenu_MouseTracking:
1893  case SH_ComboBox_ListMouseTracking:
1894  case SH_ScrollBar_MiddleClickAbsolutePosition:
1895  return 1;
1896  case SH_LineEdit_PasswordCharacter:
1897  {
1898  if (w) {
1899  const TQFontMetrics &fm = w->fontMetrics();
1900  if (fm.inFont(TQChar(0x25CF))) {
1901  return 0x25CF;
1902  } else if (fm.inFont(TQChar(0x2022))) {
1903  return 0x2022;
1904  }
1905  }
1906  return '*';
1907  }
1908 
1909  default:
1910  return TQCommonStyle::styleHint(sh, ceData, elementFlags, opt, shr, w);
1911  }
1912 }
1913 
1914 
1915 bool TDEStyle::objectEventHandler( const TQStyleControlElementData &ceData, ControlElementFlags elementFlags, void* source, TQEvent *event )
1916 {
1917  if (ceData.widgetObjectTypes.contains("TQObject")) {
1918  TQObject* object = reinterpret_cast<TQObject*>(source);
1919  if ( d->useFilledFrameWorkaround )
1920  {
1921  // Make the QMenuBar/TQToolBar paintEvent() cover a larger area to
1922  // ensure that the filled frame contents are properly painted.
1923  // We essentially modify the paintEvent's rect to include the
1924  // panel border, which also paints the widget's interior.
1925  // This is nasty, but I see no other way to properly repaint
1926  // filled frames in all QMenuBars and QToolBars.
1927  // -- Karol.
1928  TQFrame *frame = 0;
1929  if ( event->type() == TQEvent::Paint
1930  && (frame = ::tqt_cast<TQFrame*>(object)) )
1931  {
1932  if (frame->frameShape() != TQFrame::ToolBarPanel && frame->frameShape() != TQFrame::MenuBarPanel)
1933  return false;
1934 
1935  bool horizontal = true;
1936  TQPaintEvent* pe = (TQPaintEvent*)event;
1937  TQToolBar *toolbar = ::tqt_cast< TQToolBar *>( frame );
1938  TQRect r = pe->rect();
1939 
1940  if (toolbar && toolbar->orientation() == TQt::Vertical)
1941  horizontal = false;
1942 
1943  if (horizontal) {
1944  if ( r.height() == frame->height() )
1945  return false; // Let TQFrame handle the painting now.
1946 
1947  // Else, send a new paint event with an updated paint rect.
1948  TQPaintEvent dummyPE( TQRect( r.x(), 0, r.width(), frame->height()) );
1949  TQApplication::sendEvent( frame, &dummyPE );
1950  }
1951  else { // Vertical
1952  if ( r.width() == frame->width() )
1953  return false;
1954 
1955  TQPaintEvent dummyPE( TQRect( 0, r.y(), frame->width(), r.height()) );
1956  TQApplication::sendEvent( frame, &dummyPE );
1957  }
1958 
1959  // Discard this event as we sent a new paintEvent.
1960  return true;
1961  }
1962  }
1963  }
1964 
1965  return false;
1966 }
1967 
1968 
1969 // -----------------------------------------------------------------------------
1970 // I N T E R N A L - TDEStyle menu transparency handler
1971 // -----------------------------------------------------------------------------
1972 
1973 TransparencyHandler::TransparencyHandler( TDEStyle* style,
1974  TransparencyEngine tEngine, float menuOpacity, bool useDropShadow )
1975  : TQObject()
1976 {
1977  te = tEngine;
1978  tdestyle = style;
1979  opacity = menuOpacity;
1980  dropShadow = useDropShadow;
1981  pix.setOptimization(TQPixmap::BestOptim);
1982 }
1983 
1984 TransparencyHandler::~TransparencyHandler()
1985 {
1986 }
1987 
1988 bool TransparencyHandler::haveX11RGBASupport()
1989 {
1990  // Simple way to determine if we have ARGB support
1991  if (TQPaintDevice::x11AppDepth() == 32) {
1992  return true;
1993  }
1994  else {
1995  return false;
1996  }
1997 }
1998 
1999 #define REAL_ALPHA_STRENGTH 255.0
2000 
2001 // This is meant to be ugly but fast.
2002 void TransparencyHandler::rightShadow(TQImage& dst)
2003 {
2004  bool have_composite = haveX11RGBASupport();
2005 
2006  if (dst.depth() != 32)
2007  dst = dst.convertDepth(32);
2008 
2009  // blend top-right corner.
2010  int pixels = dst.width() * dst.height();
2011 #ifdef WORDS_BIGENDIAN
2012  unsigned char* data = dst.bits() + 1; // Skip alpha
2013 #else
2014  unsigned char* data = dst.bits(); // Skip alpha
2015 #endif
2016  for(int i = 0; i < 16; i++) {
2017  if (have_composite) {
2018  data++;
2019  data++;
2020  data++;
2021  *data = (unsigned char)(REAL_ALPHA_STRENGTH*(1.0-top_right_corner[i])); data++;
2022  }
2023  else {
2024  *data = (unsigned char)((*data)*top_right_corner[i]); data++;
2025  *data = (unsigned char)((*data)*top_right_corner[i]); data++;
2026  *data = (unsigned char)((*data)*top_right_corner[i]); data++;
2027  data++; // skip alpha
2028  }
2029  }
2030 
2031  pixels -= 32; // tint right strip without rounded edges.
2032  int c = 0;
2033  for(int i = 0; i < pixels; i++) {
2034  if (have_composite) {
2035  data++;
2036  data++;
2037  data++;;
2038  *data = (unsigned char)(REAL_ALPHA_STRENGTH*(1.0-shadow_strip[c])); data++;
2039  }
2040  else {
2041  *data = (unsigned char)((*data)*shadow_strip[c]); data++;
2042  *data = (unsigned char)((*data)*shadow_strip[c]); data++;
2043  *data = (unsigned char)((*data)*shadow_strip[c]); data++;
2044  data++; // skip alpha
2045  }
2046  ++c;
2047  c %= 4;
2048  }
2049 
2050  // tint bottom edge
2051  for(int i = 0; i < 16; i++) {
2052  if (have_composite) {
2053  data++;
2054  data++;
2055  data++;
2056  *data = (unsigned char)(REAL_ALPHA_STRENGTH*(1.0-bottom_right_corner[i])); data++;
2057  }
2058  else {
2059  *data = (unsigned char)((*data)*bottom_right_corner[i]); data++;
2060  *data = (unsigned char)((*data)*bottom_right_corner[i]); data++;
2061  *data = (unsigned char)((*data)*bottom_right_corner[i]); data++;
2062  data++; // skip alpha
2063  }
2064  }
2065 }
2066 
2067 void TransparencyHandler::bottomShadow(TQImage& dst)
2068 {
2069  bool have_composite = haveX11RGBASupport();
2070 
2071  if (dst.depth() != 32)
2072  dst = dst.convertDepth(32);
2073 
2074  int line = 0;
2075  int width = dst.width() - 4;
2076  double strip_data = shadow_strip[0];
2077  double* corner = const_cast<double*>(bottom_left_corner);
2078 
2079 #ifdef WORDS_BIGENDIAN
2080  unsigned char* data = dst.bits() + 1; // Skip alpha
2081 #else
2082  unsigned char* data = dst.bits(); // Skip alpha
2083 #endif
2084 
2085  for(int y = 0; y < 4; y++)
2086  {
2087  // Bottom-left Corner
2088  for(int x = 0; x < 4; x++) {
2089  if (have_composite) {
2090  data++;
2091  data++;
2092  data++;
2093  *data = (unsigned char)(REAL_ALPHA_STRENGTH*(1.0-(*corner))); data++;
2094  }
2095  else {
2096  *data = (unsigned char)((*data)*(*corner)); data++;
2097  *data = (unsigned char)((*data)*(*corner)); data++;
2098  *data = (unsigned char)((*data)*(*corner)); data++;
2099  data++; // skip alpha
2100  }
2101  corner++;
2102  }
2103 
2104  // Scanline
2105  for(int x = 0; x < width; x++) {
2106  if (have_composite) {
2107  data++;
2108  data++;
2109  data++;
2110  *data = (unsigned char)(REAL_ALPHA_STRENGTH*(1.0-strip_data)); data++;
2111  }
2112  else {
2113  *data = (unsigned char)((*data)*strip_data); data++;
2114  *data = (unsigned char)((*data)*strip_data); data++;
2115  *data = (unsigned char)((*data)*strip_data); data++;
2116  data++; // skip alpha
2117  }
2118  }
2119 
2120  strip_data = shadow_strip[line++];
2121  }
2122 }
2123 
2124 TQImage TransparencyHandler::handleRealAlpha(TQImage img) {
2125  TQImage clearImage = img.convertDepth(32);
2126  clearImage.setAlphaBuffer(true);
2127 
2128  int w = clearImage.width();
2129  int h = clearImage.height();
2130 
2131  for (int y = 0; y < h; ++y) {
2132  TQRgb *ls = (TQRgb *)clearImage.scanLine( y );
2133  for (int x = 0; x < w; ++x) {
2134  ls[x] = tqRgba( 0, 0, 0, 0 );
2135  }
2136  }
2137 
2138  return clearImage;
2139 }
2140 
2141 // Create a shadow of thickness 4.
2142 void TransparencyHandler::createShadowWindows(const TQWidget* p)
2143 {
2144 #ifdef TQ_WS_X11
2145  int x2 = p->x()+p->width();
2146  int y2 = p->y()+p->height();
2147  TQRect shadow1(x2, p->y() + 4, 4, p->height());
2148  TQRect shadow2(p->x() + 4, y2, p->width() - 4, 4);
2149 
2150  bool have_composite = haveX11RGBASupport();
2151 
2152  // Create a fake drop-down shadow effect via blended Xwindows
2153  ShadowElements se;
2154  se.w1 = new TQWidget(0, 0, (WFlags)(WStyle_Customize | WType_Popup | WX11BypassWM) );
2155  se.w2 = new TQWidget(0, 0, (WFlags)(WStyle_Customize | WType_Popup | WX11BypassWM) );
2156  se.w1->setGeometry(shadow1);
2157  se.w2->setGeometry(shadow2);
2158  XSelectInput(tqt_xdisplay(), se.w1->winId(), StructureNotifyMask );
2159  XSelectInput(tqt_xdisplay(), se.w2->winId(), StructureNotifyMask );
2160 
2161  // Insert a new ShadowMap entry
2162  shadowMap()[p] = se;
2163 
2164  // Some hocus-pocus here to create the drop-shadow.
2165  TQPixmap pix_shadow1;
2166  TQPixmap pix_shadow2;
2167  if (have_composite) {
2168  pix_shadow1 = TQPixmap(shadow1.width(), shadow1.height());
2169  pix_shadow2 = TQPixmap(shadow2.width(), shadow2.height());
2170  }
2171  else {
2172  pix_shadow1 = TQPixmap::grabWindow(tqt_xrootwin(),
2173  shadow1.x(), shadow1.y(), shadow1.width(), shadow1.height());
2174  pix_shadow2 = TQPixmap::grabWindow(tqt_xrootwin(),
2175  shadow2.x(), shadow2.y(), shadow2.width(), shadow2.height());
2176  }
2177 
2178  TQImage img;
2179  img = pix_shadow1.convertToImage();
2180  if (have_composite) img = handleRealAlpha(img);
2181  rightShadow(img);
2182  pix_shadow1.convertFromImage(img);
2183  img = pix_shadow2.convertToImage();
2184  if (have_composite) img = handleRealAlpha(img);
2185  bottomShadow(img);
2186  pix_shadow2.convertFromImage(img);
2187 
2188  // Set the background pixmaps
2189  se.w1->setErasePixmap(pix_shadow1);
2190  se.w2->setErasePixmap(pix_shadow2);
2191 
2192  // Show the 'shadow' just before showing the popup menu window
2193  // Don't use TQWidget::show() so we don't confuse QEffects, thus causing broken focus.
2194  XMapWindow(tqt_xdisplay(), se.w1->winId());
2195  XMapWindow(tqt_xdisplay(), se.w2->winId());
2196 #else
2197  Q_UNUSED( p )
2198 #endif
2199 }
2200 
2201 void TransparencyHandler::removeShadowWindows(const TQWidget* p)
2202 {
2203 #ifdef TQ_WS_X11
2204  ShadowMap::iterator it = shadowMap().find(p);
2205  if (it != shadowMap().end())
2206  {
2207  ShadowElements se = it.data();
2208  XUnmapWindow(tqt_xdisplay(), se.w1->winId()); // hide
2209  XUnmapWindow(tqt_xdisplay(), se.w2->winId());
2210  XFlush(tqt_xdisplay()); // try to hide faster
2211  delete se.w1;
2212  delete se.w2;
2213  shadowMap().erase(it);
2214  }
2215 #else
2216  Q_UNUSED( p )
2217 #endif
2218 }
2219 
2220 bool TransparencyHandler::eventFilter( TQObject* object, TQEvent* event )
2221 {
2222 #if !defined TQ_WS_MAC && !defined TQ_WS_WIN
2223  // Transparency idea was borrowed from KDE2's "MegaGradient" Style,
2224  // Copyright (C) 2000 Daniel M. Duley <mosfet@kde.org>
2225 
2226  // Added 'fake' menu shadows <04-Jul-2002> -- Karol
2227  TQWidget* p = (TQWidget*)object;
2228  TQEvent::Type et = event->type();
2229 
2230  if (et == TQEvent::Show)
2231  {
2232  // Handle translucency
2233  if (te != Disabled)
2234  {
2235  pix = TQPixmap::grabWindow(tqt_xrootwin(),
2236  p->x(), p->y(), p->width(), p->height());
2237 
2238  switch (te) {
2239 #ifdef HAVE_XRENDER
2240  case XRender:
2241  if (tqt_use_xrender) {
2242  XRenderBlendToPixmap(p);
2243  break;
2244  }
2245  // Fall through intended
2246 #else
2247  case XRender:
2248 #endif
2249  case SoftwareBlend:
2250  blendToPixmap(p->colorGroup(), p);
2251  break;
2252 
2253  case SoftwareTint:
2254  default:
2255  blendToColor(p->colorGroup().button());
2256  };
2257 
2258  p->setErasePixmap(pix);
2259  }
2260 
2261  // Handle drop shadow
2262  // * FIXME : !shadowMap().contains(p) is a workaround for leftover
2263  // * shadows after duplicate show events.
2264  // * TODO : determine real cause for duplicate events
2265  // * till 20021005
2266  if ((dropShadow || useDropShadow(p))
2267  && p->width() > 16 && p->height() > 16 && !shadowMap().contains( p ))
2268  createShadowWindows(p);
2269  }
2270  else if (et == TQEvent::Resize && p->isShown() && p->isTopLevel())
2271  {
2272  // Handle drop shadow
2273  if (dropShadow || useDropShadow(p))
2274  {
2275  removeShadowWindows(p);
2276  createShadowWindows(p);
2277  }
2278  }
2279  else if (et == TQEvent::Hide)
2280  {
2281  // Handle drop shadow
2282  if (dropShadow || useDropShadow(p))
2283  removeShadowWindows(p);
2284 
2285  // Handle translucency
2286  if (te != Disabled)
2287  p->setErasePixmap(TQPixmap());
2288  }
2289 
2290 #endif
2291  return false;
2292 }
2293 
2294 
2295 // Blends a TQImage to a predefined color, with a given opacity.
2296 void TransparencyHandler::blendToColor(const TQColor &col)
2297 {
2298  if (opacity < 0.0 || opacity > 1.0)
2299  return;
2300 
2301  TQImage img = pix.convertToImage();
2302  KImageEffect::blend(col, img, opacity);
2303  pix.convertFromImage(img);
2304 }
2305 
2306 
2307 void TransparencyHandler::blendToPixmap(const TQColorGroup &cg, const TQWidget* p)
2308 {
2309  if (opacity < 0.0 || opacity > 1.0)
2310  return;
2311 
2312  KPixmap blendPix;
2313  blendPix.resize( pix.width(), pix.height() );
2314 
2315  if (blendPix.width() != pix.width() ||
2316  blendPix.height() != pix.height())
2317  return;
2318 
2319  // Allow styles to define the blend pixmap - allows for some interesting effects.
2320  if (::tqt_cast<TQPopupMenu*>(p))
2321  tdestyle->renderMenuBlendPixmap( blendPix, cg, ::tqt_cast<TQPopupMenu*>(p) );
2322  else
2323  blendPix.fill(cg.button()); // Just tint as the default behavior
2324 
2325  TQImage blendImg = blendPix.convertToImage();
2326  TQImage backImg = pix.convertToImage();
2327  KImageEffect::blend(blendImg, backImg, opacity);
2328  pix.convertFromImage(backImg);
2329 }
2330 
2331 
2332 #ifdef HAVE_XRENDER
2333 // Here we go, use XRender in all its glory.
2334 // NOTE: This is actually a bit slower than the above routines
2335 // on non-accelerated displays. -- Karol.
2336 void TransparencyHandler::XRenderBlendToPixmap(const TQWidget* p)
2337 {
2338  KPixmap renderPix;
2339  renderPix.resize( pix.width(), pix.height() );
2340 
2341  // Allow styles to define the blend pixmap - allows for some interesting effects.
2342  if (::tqt_cast<TQPopupMenu*>(p))
2343  tdestyle->renderMenuBlendPixmap( renderPix, p->colorGroup(),
2344  ::tqt_cast<TQPopupMenu*>(p) );
2345  else
2346  renderPix.fill(p->colorGroup().button()); // Just tint as the default behavior
2347 
2348  Display* dpy = tqt_xdisplay();
2349  Pixmap alphaPixmap;
2350  Picture alphaPicture;
2351  XRenderPictFormat Rpf;
2352  XRenderPictureAttributes Rpa;
2353  XRenderColor clr;
2354  clr.alpha = ((unsigned short)(255*opacity) << 8);
2355 
2356  Rpf.type = PictTypeDirect;
2357  Rpf.depth = 8;
2358  Rpf.direct.alphaMask = 0xff;
2359  Rpa.repeat = True; // Tile
2360 
2361  XRenderPictFormat* xformat = XRenderFindFormat(dpy,
2362  PictFormatType | PictFormatDepth | PictFormatAlphaMask, &Rpf, 0);
2363 
2364  alphaPixmap = XCreatePixmap(dpy, p->handle(), 1, 1, 8);
2365  alphaPicture = XRenderCreatePicture(dpy, alphaPixmap, xformat, CPRepeat, &Rpa);
2366 
2367  XRenderFillRectangle(dpy, PictOpSrc, alphaPicture, &clr, 0, 0, 1, 1);
2368 
2369  XRenderComposite(dpy, PictOpOver,
2370  renderPix.x11RenderHandle(), alphaPicture, pix.x11RenderHandle(), // src, mask, dst
2371  0, 0, // srcx, srcy
2372  0, 0, // maskx, masky
2373  0, 0, // dstx, dsty
2374  pix.width(), pix.height());
2375 
2376  XRenderFreePicture(dpy, alphaPicture);
2377  XFreePixmap(dpy, alphaPixmap);
2378 }
2379 #endif
2380 
2381 void TDEStyle::virtual_hook( int, void* )
2382 { /*BASE::virtual_hook( id, data );*/ }
2383 
2384 // HACK for gtk-qt-engine
2385 
2386 extern "C" TDE_EXPORT
2387 void kde_tdestyle_set_scrollbar_type_windows( void* style )
2388 {
2389  ((TDEStyle*)style)->setScrollBarType( TDEStyle::WindowsStyleScrollBar );
2390 }
2391 #include "tdestyle.moc"
KImageEffect::blend
static TQImage & blend(const TQColor &clr, TQImage &dst, float opacity)
Blends a color into the destination image, using an opacity value for blending one into another.
Definition: kimageeffect.cpp:1067
KPixmapEffect::gradient
static KPixmap & gradient(KPixmap &pixmap, const TQColor &ca, const TQColor &cb, GradientType type, int ncols=3)
Creates a gradient from color a to color b of the specified type.
Definition: kpixmapeffect.cpp:24
KPixmap
Off-screen paint device with extended features.
Definition: kpixmap.h:58
KPixmap::convertFromImage
bool convertFromImage(const TQImage &img, int conversion_flags)
Converts an image and sets this pixmap.
Definition: kpixmap.cpp:223
TDEStyle
Simplifies and extends the TQStyle API to make style coding easier.
Definition: tdestyle.h:58
TDEStyle::TDEStyleScrollBarType
TDEStyleScrollBarType
TDEStyle ScrollBarType:
Definition: tdestyle.h:110
TDEStyle::NextStyleScrollBar
@ NextStyleScrollBar
two button, NeXT style
Definition: tdestyle.h:114
TDEStyle::PlatinumStyleScrollBar
@ PlatinumStyleScrollBar
two button, platinum style
Definition: tdestyle.h:112
TDEStyle::ThreeButtonScrollBar
@ ThreeButtonScrollBar
three buttons, KDE style
Definition: tdestyle.h:113
TDEStyle::WindowsStyleScrollBar
@ WindowsStyleScrollBar
two button, windows style
Definition: tdestyle.h:111
TDEStyle::TDEStyle
TDEStyle(TDEStyleFlags flags=TDEStyle::Default, TDEStyleScrollBarType sbtype=TDEStyle::WindowsStyleScrollBar)
Constructs a TDEStyle object.
Definition: tdestyle.cpp:189
TDEStyle::~TDEStyle
~TDEStyle()
Destructs the TDEStyle object.
Definition: tdestyle.cpp:244
TDEStyle::AllowMenuTransparency
@ AllowMenuTransparency
Internal transparency enabled.
Definition: tdestyle.h:83
TDEStyle::FilledFrameWorkaround
@ FilledFrameWorkaround
Filled frames enabled.
Definition: tdestyle.h:84
TDEStyle::TDEStyleFlags
uint TDEStyleFlags
TDEStyle Flags:
Definition: tdestyle.h:80
TDEStyle::setScrollBarType
void setScrollBarType(TDEStyleScrollBarType sbtype)
Modifies the scrollbar type used by the style.
Definition: tdestyle.cpp:330
TDEStyle::styleFlags
TDEStyleFlags styleFlags() const
Returns the TDEStyle flags used to initialize the style.
Definition: tdestyle.cpp:335
TDEStyle::renderMenuBlendPixmap
virtual void renderMenuBlendPixmap(KPixmap &pix, const TQColorGroup &cg, const TQPopupMenu *popup) const
This virtual function defines the pixmap used to blend between the popup menu and the background to c...
Definition: tdestyle.cpp:340
TDEStyle::defaultStyle
static TQString defaultStyle()
Returns the default widget style depending on color depth.
Definition: tdestyle.cpp:256
TDEStyle::TDEStylePrimitive
TDEStylePrimitive
TDEStyle Primitive Elements:
Definition: tdestyle.h:228
KNotifyClient::event
int event(const TQString &message, const TQString &text=TQString::null) TDE_DEPRECATED
TDEStdAccel::end
const TDEShortcut & end()

tdefx

Skip menu "tdefx"
  • Main Page
  • Alphabetical List
  • Class List
  • File List
  • Class Members
  • Related Pages

tdefx

Skip menu "tdefx"
  • arts
  • dcop
  • dnssd
  • interfaces
  •   kspeech
  •     interface
  •     library
  •   tdetexteditor
  • kate
  • kded
  • kdoctools
  • kimgio
  • kjs
  • libtdemid
  • libtdescreensaver
  • tdeabc
  • tdecmshell
  • tdecore
  • tdefx
  • tdehtml
  • tdeinit
  • tdeio
  •   bookmarks
  •   httpfilter
  •   kpasswdserver
  •   kssl
  •   tdefile
  •   tdeio
  •   tdeioexec
  • tdeioslave
  •   http
  • tdemdi
  •   tdemdi
  • tdenewstuff
  • tdeparts
  • tdeprint
  • tderandr
  • tderesources
  • tdespell2
  • tdesu
  • tdeui
  • tdeunittest
  • tdeutils
  • tdewallet
Generated for tdefx by doxygen 1.9.1
This website is maintained by Timothy Pearson.