• 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
74namespace
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
131namespace
132{
133class 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
162struct 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
189TDEStyle::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
244TDEStyle::~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
256TQString TDEStyle::defaultStyle()
257{
258 if (TQPixmap::defaultDepth() > 8)
259 return TQString("plastik");
260 else
261 return TQString("light, 3rd revision");
262}
263
264void 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
288void 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.
307void 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
330void TDEStyle::setScrollBarType(TDEStyleScrollBarType sbtype)
331{
332 d->scrollbarType = sbtype;
333}
334
335TDEStyle::TDEStyleFlags TDEStyle::styleFlags() const
336{
337 return d->flags;
338}
339
340void 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
346void 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
358void 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
546int 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
572void 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
667void 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
969TQRect 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
991int 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
1100static 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
1112void 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
1418TQStyle::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
1436TQRect 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
1580static 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
1597static 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
1615static 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
1632static 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
1650static 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
1667static 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
1684static 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 */
1704static 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 */
1744static 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 */
1783static 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
1822TQPixmap 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
1856int 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
1915bool 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
1973TransparencyHandler::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
1984TransparencyHandler::~TransparencyHandler()
1985{
1986}
1987
1988bool 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.
2002void 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
2067void 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
2124TQImage 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.
2142void 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
2201void 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
2220bool 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.
2296void 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
2307void 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.
2336void 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
2381void TDEStyle::virtual_hook( int, void* )
2382{ /*BASE::virtual_hook( id, data );*/ }
2383
2384// HACK for gtk-qt-engine
2385
2386extern "C" TDE_EXPORT
2387void 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.4
This website is maintained by Timothy Pearson.