kexi

kexigradientwidget.cpp
1/* This file is part of the KDE project
2 Copyright (C) 2005 Christian Nitschkowski <segfault_ii@web.de>
3
4 This program is free software; you can redistribute it and/or
5 modify it under the terms of the GNU Library General Public
6 License as published by the Free Software Foundation; either
7 version 2 of the License, or (at your option) any later version.
8
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 Library General Public License for more details.
13
14 You should have received a copy of the GNU Library General Public License
15 along with this program; see the file COPYING. If not, write to
16 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
17 * Boston, MA 02110-1301, USA.
18*/
19
20#include <tqapplication.h>
21#include <tqbitmap.h>
22#include <tqimage.h>
23#include <tqobjectlist.h>
24#include <tqpainter.h>
25#include <tqstyle.h>
26
27#include <kimageeffect.h>
28#include <kpixmap.h>
29
30#include "kexigradientwidget.h"
31
32KexiGradientWidget::KexiGradientWidget( TQWidget *parent, const char *name, WFlags f )
33 : TQWidget( parent, name, f ), p_displayMode( NoGradient ),
34 p_gradientType( VerticalGradient ),
35 p_color1( TQt::white ), p_color2( TQt::blue ), p_currentChild( 0 ),
36 p_opacity( 0.5 ), p_cacheDirty( true )
37{
38 p_customBackgroundWidgets.setAutoDelete( false );
39 p_knownWidgets.setAutoDelete( false );
40
41 p_backgroundColor = TQWidget::paletteBackgroundColor();
42
43 connect ( &p_rebuildDelayTimer, TQ_SIGNAL( timeout() ), this, TQ_SLOT( setCacheDirty() ) );
44
45 installEventFilter( this );
46}
47
48KexiGradientWidget::~KexiGradientWidget()
49{
50}
51
52bool KexiGradientWidget::isValidChildWidget( TQObject* child ) {
53 const TQWidget* wgt = dynamic_cast<TQWidget*>( child );
54
55 if ( wgt == 0L )
56 return false;
57
58 if ( wgt->inherits( "TQScrollView" ) )
59 return false;
60 if ( wgt->inherits( "TQComboBox" ) )
61 return false;
62 if ( wgt->inherits( "TQLineEdit" ) )
63 return false;
64 if ( wgt->inherits( "KexiDBForm" ) )
65 return false;
66
67 return true;
68}
69
70void KexiGradientWidget::buildChildrenList( WidgetList& list, TQWidget* p ) {
71 TQObjectList* objects = p->queryList( "TQWidget", 0, false, false );
72
73 for ( TQObjectList::Iterator it = objects->begin(); it != objects->end(); ++it ) {
74 if ( isValidChildWidget( ( *it ) ) == false )
75 continue;
76 list.append( dynamic_cast<TQWidget*>( ( *it ) ) );
77 buildChildrenList( list, dynamic_cast<TQWidget*>( ( *it ) ) );
78 }
79
80 delete objects;
81}
82
83void KexiGradientWidget::rebuildCache( void ) {
84 WidgetList childWidgetList;
85 buildChildrenList( childWidgetList, this );
86
90 if ( p_displayMode == NoGradient ) {
91// if ( p_backgroundPixmap.isNull() ) {
92 //unsetPalette();
93 //} else {
94 TQWidget::setPaletteBackgroundPixmap( p_backgroundPixmap );
95 //}
96 TQWidget::setPaletteBackgroundColor( p_backgroundColor );
97
98 for ( WidgetList::Iterator it = childWidgetList.begin();
99 it != childWidgetList.end(); ++it ) {
100
101 if ( p_customBackgroundWidgets.contains( ( *it ) ) == false ) {
102 ( *it )->unsetPalette();
103 }
104 }
108 p_cacheDirty = false;
109 return;
110 }
111
112 KPixmap tempPixmap;
113 TQImage gradientImage;
114 TQImage bgImage;
115
119 gradientImage = KImageEffect::gradient( size(), p_color1, p_color2,
120 (KImageEffect::GradientType)p_gradientType );
121
125 if ( p_displayMode == FadedGradient ) {
126 tempPixmap.resize( size() );
127 TQPainter p( &tempPixmap, this );
128
129 if ( p_backgroundPixmap.isNull() ) {
130 /*
131 Need to unset the palette, otherwise the old gradient
132 will be used as a background, not the widget's default bg.
133 */
134 unsetPalette();
135 p.fillRect( 0, 0, width(), height(), palette().brush(
136 isEnabled() ? TQPalette::Active : TQPalette::Disabled,
137 TQColorGroup::Background ) );
138 } else {
139 p.drawTiledPixmap( 0, 0, width(), height(), p_backgroundPixmap );
140 }
141
142 p.end();
143
144 bgImage = tempPixmap;
145
146 KImageEffect::blend( gradientImage, bgImage, (float)p_opacity );
147
148 tempPixmap.convertFromImage( bgImage );
149 } else if ( p_displayMode == SimpleGradient ) {
154 tempPixmap.convertFromImage( gradientImage );
155 }
156
160 KPixmap partPixmap;
161 TQRect area;
162 TQWidget* childWidget = 0;
163 const TQPoint topLeft( 0, 0 );
164
165 for ( WidgetList::Iterator it = childWidgetList.begin();
166 it != childWidgetList.end(); ++it ) {
167
168 childWidget = ( *it );
169
173 if ( p_customBackgroundWidgets.contains( childWidget ) ) {
174 continue;
175 }
176
177 partPixmap.resize( childWidget->size() );
182 if ( childWidget->parent() == this ) {
183 area = childWidget->geometry();
184 } else {
185 area.setTopLeft( childWidget->mapTo( this,
186 childWidget->clipRegion().boundingRect().topLeft() ) );
187 area.setSize( childWidget->size() );
188 }
189 bitBlt( &partPixmap, topLeft, &tempPixmap, area );
190
191 p_currentChild = childWidget;
192 childWidget->setPaletteBackgroundPixmap( partPixmap );
193 }
194
195 TQWidget::setPaletteBackgroundPixmap( tempPixmap );
202 p_cacheDirty = false;
203}
204
205void KexiGradientWidget::paintEvent( TQPaintEvent* e ) {
209 if ( p_cacheDirty == true ) {
210 rebuildCache();
211 }
212
216 TQWidget::paintEvent( e );
217}
218
219bool KexiGradientWidget::eventFilter( TQObject* object, TQEvent* event ) {
220 TQWidget* child = dynamic_cast<TQWidget*>( object );
221
225 if ( object == this ) {
226 if ( event->type() == TQEvent::ChildInserted ) {
227 child = dynamic_cast<TQWidget*>( dynamic_cast<TQChildEvent*>( event )->child() );
228 if ( isValidChildWidget( child ) == false ) {
229 return false;
230 }
234 p_knownWidgets.append( child );
238 child->installEventFilter( this );
239 } else if ( event->type() == TQEvent::ChildRemoved ) {
243 p_knownWidgets.remove( dynamic_cast<TQWidget*>( dynamic_cast<TQChildEvent*>( event )->child() ) );
244 }
245 return false;
246 }
247
251 if ( event->type() == TQEvent::PaletteChange ) {
257 if ( p_currentChild == 0L && child != 0L ) {
258 if ( p_customBackgroundWidgets.contains( child ) == false ) {
259 p_customBackgroundWidgets.append( child );
260 return false;
261 }
262 }
267 if ( child != p_currentChild && child != 0L ) {
272 if ( p_customBackgroundWidgets.contains( child ) == false ) {
273 if ( child->paletteBackgroundPixmap() != 0L ) {
274 p_customBackgroundWidgets.append( child );
275 }
276 } else {
282 if ( child->paletteBackgroundPixmap() == 0L ) {
283 p_customBackgroundWidgets.remove( child );
284 if ( p_displayMode != NoGradient ) {
285 p_cacheDirty = true;
286 }
287 }
288 }
289 }
290 p_currentChild = 0;
291 }
292
293 if ( event->type() == TQEvent::Move ) {
294 if ( p_customBackgroundWidgets.contains( child ) == false ) {
295 updateChildBackground( child );
296 }
297 }
298 return false;
299}
300
301void KexiGradientWidget::updateChildBackground( TQWidget* childWidget )
302{
303 KPixmap partPixmap;
304 KPixmap bgPixmap;
305 TQRect area;
306 const TQPoint topLeft( 0, 0 );
307
308 bgPixmap = paletteBackgroundPixmap() ? (*paletteBackgroundPixmap()) : TQPixmap();
309 if ( bgPixmap.isNull() )
310 return;
311
317 if ( childWidget->parent() == 0L )
318 return;
319
323 if ( p_customBackgroundWidgets.contains( childWidget ) ) {
324 return;
325 }
326
327 partPixmap.resize( childWidget->size() );
332 if ( childWidget->parent() == this ) {
333 area = childWidget->geometry();
334 } else {
335 area.setTopLeft( childWidget->mapTo( this,
336 childWidget->clipRegion().boundingRect().topLeft() ) );
337 area.setSize( childWidget->size() );
338 }
339 bitBlt( &partPixmap, topLeft, &bgPixmap, area );
340
341 p_currentChild = childWidget;
342 childWidget->setPaletteBackgroundPixmap( partPixmap );
343}
344
345void KexiGradientWidget::setPaletteBackgroundColor( const TQColor& color )
346{
347 p_backgroundColor = color;
348 if ( p_displayMode == NoGradient ) {
349 TQWidget::setPaletteBackgroundColor( p_backgroundColor );
350 }
351}
352
353const TQColor& KexiGradientWidget::paletteBackgroundColor() const
354{
355 return p_backgroundColor;
356}
357
358#include "kexigradientwidget.moc"
virtual void paintEvent(TQPaintEvent *e)
@ FadedGradient
Gradient will be faded with the widgets background.
@ NoGradient
No gradient at all. Will behave just like a TQWidget.
@ SimpleGradient
Gradient will replace the usual widget background.
virtual bool eventFilter(TQObject *object, TQEvent *event)