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

kdefx

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

kdefx

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

kdefx

Skip menu "kdefx"
  • arts
  • dcop
  • dnssd
  • interfaces
  •     interface
  •     library
  •   kspeech
  •   ktexteditor
  • kabc
  • kate
  • kcmshell
  • kdecore
  • kded
  • kdefx
  • kdeprint
  • kdesu
  • kdeui
  • kdoctools
  • khtml
  • kimgio
  • kinit
  • kio
  •   bookmarks
  •   httpfilter
  •   kfile
  •   kio
  •   kioexec
  •   kpasswdserver
  •   kssl
  • kioslave
  •   http
  • kjs
  • kmdi
  •   kmdi
  • knewstuff
  • kparts
  • krandr
  • kresources
  • kspell2
  • kunittest
  • kutils
  • kwallet
  • libkmid
  • libkscreensaver
Generated for kdefx by doxygen 1.9.1
This website is maintained by Timothy Pearson.
KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. |