mirror of
https://bitbucket.org/smil3y/kde-workspace.git
synced 2025-02-23 18:32:50 +00:00
223 lines
7.4 KiB
C++
223 lines
7.4 KiB
C++
//////////////////////////////////////////////////////////////////////////////
|
|
// oxygenmdiwindowshadow.cpp
|
|
// handle MDI windows' shadows
|
|
// -------------------
|
|
//
|
|
// Copyright (c) 2010 Hugo Pereira Da Costa <hugo.pereira@free.fr>
|
|
//
|
|
// Largely inspired from skulpture widget style
|
|
// Copyright (c) 2007-2009 Christoph Feck <christoph@maxiom.de>
|
|
//
|
|
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
// of this software and associated documentation files (the "Software"), to
|
|
// deal in the Software without restriction, including without limitation the
|
|
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
|
// sell copies of the Software, and to permit persons to whom the Software is
|
|
// furnished to do so, subject to the following conditions:
|
|
//
|
|
// The above copyright notice and this permission notice shall be included in
|
|
// all copies or substantial portions of the Software.
|
|
//
|
|
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
|
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
|
// IN THE SOFTWARE.
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
|
|
#include "oxygenmdiwindowshadow.h"
|
|
#include "moc_oxygenmdiwindowshadow.cpp"
|
|
#include "oxygenshadowcache.h"
|
|
|
|
#include <QtGui/QMdiArea>
|
|
#include <QtGui/QMdiSubWindow>
|
|
#include <QtGui/QPainter>
|
|
#include <QtCore/QTextStream>
|
|
|
|
namespace Oxygen
|
|
{
|
|
|
|
//____________________________________________________________________
|
|
void MdiWindowShadow::updateGeometry( void )
|
|
{
|
|
if( !_widget ) return;
|
|
|
|
// get tileSet rect
|
|
_tileSetRect = _widget->frameGeometry().adjusted( -ShadowSize, -ShadowSize, ShadowSize, ShadowSize );
|
|
|
|
// get parent MDI area's viewport
|
|
QWidget *parent( parentWidget() );
|
|
if (parent && !qobject_cast<QMdiArea *>(parent) && qobject_cast<QMdiArea*>(parent->parentWidget()))
|
|
{ parent = parent->parentWidget(); }
|
|
if( qobject_cast<QAbstractScrollArea *>( parent ) )
|
|
{ parent = qobject_cast<QAbstractScrollArea *>( parent )->viewport(); }
|
|
|
|
// set geometry
|
|
QRect geometry( _tileSetRect );
|
|
if( parent ) geometry &= parent->rect();
|
|
setGeometry( geometry );
|
|
|
|
// translate rendering rect
|
|
_tileSetRect.translate( -geometry.topLeft() );
|
|
|
|
}
|
|
|
|
//____________________________________________________________________
|
|
void MdiWindowShadow::updateZOrder( void )
|
|
{ stackUnder( _widget ); }
|
|
|
|
//____________________________________________________________________
|
|
void MdiWindowShadow::paintEvent( QPaintEvent* event )
|
|
{
|
|
|
|
if( !_tileSet.isValid() ) return;
|
|
|
|
QPainter p( this );
|
|
p.setRenderHints( QPainter::Antialiasing );
|
|
p.setClipRegion( event->region() );
|
|
_tileSet.render( _tileSetRect, &p );
|
|
|
|
}
|
|
|
|
//____________________________________________________________________
|
|
MdiWindowShadowFactory::MdiWindowShadowFactory( QObject* parent, StyleHelper& helper ):
|
|
QObject( parent )
|
|
{
|
|
|
|
// create shadow cache
|
|
ShadowCache cache( helper );
|
|
cache.setShadowSize( QPalette::Inactive, MdiWindowShadow::ShadowSize );
|
|
cache.setShadowSize( QPalette::Active, MdiWindowShadow::ShadowSize );
|
|
|
|
// get tileset
|
|
_tileSet = *cache.tileSet( ShadowCache::Key() );
|
|
}
|
|
|
|
//____________________________________________________________________________________
|
|
bool MdiWindowShadowFactory::registerWidget( QWidget* widget )
|
|
{
|
|
|
|
// check widget type
|
|
if( !( widget && qobject_cast<QMdiSubWindow*>( widget ) ) ) return false;
|
|
|
|
// make sure widget is not already registered
|
|
if( isRegistered( widget ) ) return false;
|
|
|
|
// store in set
|
|
_registeredWidgets.insert( widget );
|
|
|
|
widget->installEventFilter( this );
|
|
|
|
// catch object destruction
|
|
connect( widget, SIGNAL(destroyed(QObject*)), SLOT(widgetDestroyed(QObject*)) );
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
//____________________________________________________________________________________
|
|
void MdiWindowShadowFactory::unregisterWidget( QWidget* widget )
|
|
{
|
|
if( !isRegistered( widget ) ) return;
|
|
widget->removeEventFilter( this );
|
|
_registeredWidgets.remove( widget );
|
|
removeShadow( widget );
|
|
}
|
|
|
|
//____________________________________________________________________________________
|
|
bool MdiWindowShadowFactory::eventFilter( QObject* object, QEvent* event )
|
|
{
|
|
|
|
switch( event->type() )
|
|
{
|
|
// TODO: possibly implement ZOrderChange event, to make sure that
|
|
// the shadow is always painted on top
|
|
case QEvent::ZOrderChange:
|
|
updateShadowZOrder( object );
|
|
break;
|
|
|
|
case QEvent::Destroy:
|
|
if( isRegistered( object ) )
|
|
{
|
|
_registeredWidgets.remove( object );
|
|
removeShadow( object );
|
|
}
|
|
break;
|
|
|
|
case QEvent::Hide:
|
|
hideShadows( object );
|
|
break;
|
|
|
|
case QEvent::Show:
|
|
installShadow( object );
|
|
updateShadowGeometry( object );
|
|
updateShadowZOrder( object );
|
|
break;
|
|
|
|
case QEvent::Move:
|
|
case QEvent::Resize:
|
|
updateShadowGeometry( object );
|
|
break;
|
|
|
|
default: break;
|
|
}
|
|
|
|
return QObject::eventFilter( object, event );
|
|
|
|
}
|
|
|
|
//____________________________________________________________________________________
|
|
MdiWindowShadow* MdiWindowShadowFactory::findShadow( QObject* object ) const
|
|
{
|
|
|
|
// check object,
|
|
if( !object->parent() ) return 0L;
|
|
|
|
// find existing window shadows
|
|
const QList<QObject* > children = object->parent()->children();
|
|
foreach( QObject *child, children )
|
|
{
|
|
if( MdiWindowShadow* shadow = qobject_cast<MdiWindowShadow*>(child) )
|
|
{ if( shadow->widget() == object ) return shadow; }
|
|
}
|
|
|
|
return 0L;
|
|
|
|
}
|
|
|
|
//____________________________________________________________________________________
|
|
void MdiWindowShadowFactory::installShadow( QObject* object )
|
|
{
|
|
|
|
// cast
|
|
QWidget* widget( static_cast<QWidget*>( object ) );
|
|
if( !widget->parentWidget() ) return;
|
|
|
|
// make sure shadow is not already installed
|
|
if( findShadow( object ) ) return;
|
|
|
|
// create new shadow
|
|
MdiWindowShadow* windowShadow( new MdiWindowShadow( widget->parentWidget(), _tileSet ) );
|
|
windowShadow->setWidget( widget );
|
|
windowShadow->show();
|
|
return;
|
|
|
|
}
|
|
|
|
//____________________________________________________________________________________
|
|
void MdiWindowShadowFactory::removeShadow( QObject* object )
|
|
{
|
|
if( MdiWindowShadow* windowShadow = findShadow( object ) )
|
|
{
|
|
windowShadow->hide();
|
|
windowShadow->deleteLater();
|
|
}
|
|
}
|
|
|
|
//____________________________________________________________________________________
|
|
void MdiWindowShadowFactory::widgetDestroyed( QObject* object )
|
|
{ _registeredWidgets.remove( object ); }
|
|
|
|
}
|