1
//////////////////////////////////////////////////////////////////////////////
2
// oxygenmdiwindowshadow.cpp
3
// handle MDI windows' shadows
6
// Copyright (c) 2010 Hugo Pereira Da Costa <hugo@oxygen-icons.org>
8
// Largely inspired from skulpture widget style
9
// Copyright (c) 2007-2009 Christoph Feck <christoph@maxiom.de>
11
// Permission is hereby granted, free of charge, to any person obtaining a copy
12
// of this software and associated documentation files (the "Software"), to
13
// deal in the Software without restriction, including without limitation the
14
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
15
// sell copies of the Software, and to permit persons to whom the Software is
16
// furnished to do so, subject to the following conditions:
18
// The above copyright notice and this permission notice shall be included in
19
// all copies or substantial portions of the Software.
21
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
22
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
23
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
24
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
25
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
26
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
28
//////////////////////////////////////////////////////////////////////////////
30
#include "oxygenmdiwindowshadow.h"
31
#include "oxygenmdiwindowshadow.moc"
32
#include "oxygenshadowcache.h"
34
#include <QtGui/QMdiSubWindow>
35
#include <QtGui/QPainter>
36
#include <QtCore/QTextStream>
41
//____________________________________________________________________
42
void MdiWindowShadow::updateGeometry( void )
43
{ setGeometry( _widget->frameGeometry().adjusted( -ShadowSize, -ShadowSize, ShadowSize, ShadowSize ) ); }
45
//____________________________________________________________________
46
void MdiWindowShadow::updateZOrder( void )
47
{ stackUnder( _widget ); }
49
//____________________________________________________________________
50
void MdiWindowShadow::paintEvent( QPaintEvent* event )
53
if( !_tileSet.isValid() ) return;
56
p.setRenderHints( QPainter::Antialiasing );
57
p.setClipRegion( event->region() );
58
_tileSet.render( rect(), &p );
62
//____________________________________________________________________
63
MdiWindowShadowFactory::MdiWindowShadowFactory( QObject* parent, StyleHelper& helper ):
67
// create shadow cache
68
ShadowCache cache( helper );
70
// set shadow configuration
72
ShadowConfiguration shadowConfiguration( QPalette::Inactive );
73
shadowConfiguration.setShadowSize( MdiWindowShadow::ShadowSize );
74
cache.setShadowConfiguration( shadowConfiguration );
78
ShadowConfiguration shadowConfiguration( QPalette::Active );
79
shadowConfiguration.setShadowSize( MdiWindowShadow::ShadowSize );
80
cache.setShadowConfiguration( shadowConfiguration );
84
_tileSet = *cache.tileSet( ShadowCache::Key() );
87
//____________________________________________________________________________________
88
bool MdiWindowShadowFactory::registerWidget( QWidget* widget )
92
if( !( widget && qobject_cast<QMdiSubWindow*>( widget ) ) ) return false;
94
// make sure widget is not already registered
95
if( isRegistered( widget ) ) return false;
98
_registeredWidgets.insert( widget );
100
widget->installEventFilter( this );
102
// catch object destruction
103
connect( widget, SIGNAL( destroyed( QObject* ) ), SLOT( widgetDestroyed( QObject* ) ) );
109
//____________________________________________________________________________________
110
void MdiWindowShadowFactory::unregisterWidget( QWidget* widget )
112
if( !isRegistered( widget ) ) return;
113
widget->removeEventFilter( this );
114
_registeredWidgets.remove( widget );
115
removeShadow( widget );
118
//____________________________________________________________________________________
119
bool MdiWindowShadowFactory::eventFilter( QObject* object, QEvent* event )
122
switch( event->type() )
124
// TODO: possibly implement ZOrderChange event, to make sure that
125
// the shadow is always painted on top
126
case QEvent::ZOrderChange:
127
updateShadowZOrder( object );
131
case QEvent::Destroy:
132
if( isRegistered( object ) )
134
_registeredWidgets.remove( object );
135
removeShadow( object );
140
installShadow( object );
141
updateShadowGeometry( object );
142
updateShadowZOrder( object );
147
updateShadowGeometry( object );
153
return QObject::eventFilter( object, event );
157
//____________________________________________________________________________________
158
MdiWindowShadow* MdiWindowShadowFactory::findShadow( QObject* object ) const
162
if( !object->parent() ) return 0L;
164
// find existing window shadows
165
const QList<QObject* > children = object->parent()->children();
166
foreach( QObject *child, children )
168
if( MdiWindowShadow* shadow = qobject_cast<MdiWindowShadow*>(child) )
169
{ if( shadow->widget() == object ) return shadow; }
176
//____________________________________________________________________________________
177
void MdiWindowShadowFactory::installShadow( QObject* object )
181
QWidget* widget( static_cast<QWidget*>( object ) );
182
if( !widget->parentWidget() ) return;
184
// make sure shadow is not already installed
185
if( findShadow( object ) ) return;
188
MdiWindowShadow* windowShadow( new MdiWindowShadow( widget->parentWidget(), _tileSet ) );
189
windowShadow->setWidget( widget );
190
windowShadow->show();
195
//____________________________________________________________________________________
196
void MdiWindowShadowFactory::removeShadow( QObject* object )
198
if( MdiWindowShadow* windowShadow = findShadow( object ) )
200
windowShadow->hide();
201
windowShadow->deleteLater();
205
//____________________________________________________________________________________
206
void MdiWindowShadowFactory::widgetDestroyed( QObject* object )
207
{ _registeredWidgets.remove( object ); }