kwin/clients/oxygen/oxygenclient.h
Hugo Pereira Da Costa 796e7ff92a Properly account for window's shaded state, and number of clients in groups when deciding whether or
not the titlebar should be hidden. This is half the job, cause the above does not work (yet) when 
grouping windows among which one has hidden titlebar. Shading works well now, though.

CCBUG: 260815

svn path=/trunk/KDE/kdebase/workspace/; revision=1208187
2010-12-20 22:18:52 +00:00

462 lines
14 KiB
C++

#ifndef oxygenclient_h
#define oxygenclient_h
//////////////////////////////////////////////////////////////////////////////
// oxygenclient.h
// -------------------
//
// Copyright (c) 2009 Hugo Pereira Da Costa <hugo.pereira@free.fr>
// Copyright (c) 2003, 2004 David Johnson <david@usermode.org>
// Copyright (c) 2006, 2007 Riccardo Iaconelli <ruphy@fsfe.org>
//
// 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 "oxygenanimation.h"
#include "oxygenclientgroupitemdata.h"
#include "oxygenconfiguration.h"
#include "oxygendecohelper.h"
#include "oxygenfactory.h"
#include "oxygenshadowcache.h"
#include "oxygentitleanimationdata.h"
#include <kcommondecoration.h>
#include <QtCore/QBasicTimer>
#include <QtCore/QTextStream>
#include <QtCore/QTimerEvent>
namespace Oxygen
{
class SizeGrip;
class Client : public KCommonDecorationUnstable
{
Q_OBJECT
//! declare glow intensity property
Q_PROPERTY( qreal glowIntensity READ glowIntensityUnbiased WRITE setGlowIntensity )
public:
//! constructor
Client(KDecorationBridge *b, Factory *f);
//! destructor
virtual ~Client();
//! decoration name
virtual QString visibleName() const;
//! buttons
virtual KCommonDecorationButton *createButton(::ButtonType type);
//!@name flags
//@{
//! true if decoration has iquired behavior
virtual bool decorationBehaviour(DecorationBehaviour behaviour) const;
//! true if window is maximized
virtual bool isMaximized( void ) const
{ return maximizeMode()==MaximizeFull && !options()->moveResizeMaximizedWindows(); }
//! true if animations are used
bool useAnimations( void ) const
{ return configuration().useAnimations(); }
//! true if glow is animated
bool glowIsAnimated( void ) const
{ return glowAnimation_->isRunning(); }
//! true when decoration is forced active
bool isForcedActive( void ) const
{ return forceActive_ && clientGroupItems().count() > 1; }
//! true when separator is to be drawn
bool drawSeparator( void ) const
{
if( configuration().drawTitleOutline() ) return false;
switch( configuration().separatorMode() )
{
case Configuration::SeparatorAlways:
return true;
case Configuration::SeparatorActive:
return ( glowIsAnimated() || isActive() );
default:
case Configuration::SeparatorNever:
return false;
}
}
//! true if titlebar is hidden
bool hideTitleBar( void ) const
{
return
configuration().hideTitleBar() &&
!isShade() &&
clientGroupItems().count() == 1;
}
//@}
//! window shape
virtual void updateWindowShape();
//! initialization
virtual void init();
// reset
virtual void reset( unsigned long changed );
//! return associated configuration
const Configuration& configuration( void ) const
{ return configuration_; }
//!@name glow animation
//@{
void setGlowIntensity( qreal value )
{
if( glowIntensity_ == value ) return;
glowIntensity_ = value;
widget()->update();
}
//! unbiased glow intensity
qreal glowIntensityUnbiased( void ) const
{ return glowIntensity_; }
//! glow bias
static qreal glowBias( void )
{ return 0.2; }
//! true (biased) intensity
/*! this is needed to have glow go from either 0.2->1 or 0.8->0 depending on the animation direction */
qreal glowIntensity( void ) const
{ return glowAnimation_->direction() == Animation::Forward ? glowIntensity_ : glowIntensity_-glowBias(); }
//@}
//! helper class
DecoHelper& helper( void ) const
{ return factory_->helper(); }
//! helper class
ShadowCache& shadowCache( void ) const
{ return factory_->shadowCache(); }
//!@name metrics and color definitions
//@{
//! dimensions
virtual int layoutMetric(LayoutMetric lm, bool respectWindowState = true, const KCommonDecorationButton * = 0) const;
//! get title rect for untabbed window
virtual QRect defaultTitleRect( bool active = true ) const;
//! get title bounding rect
virtual QRect titleBoundingRect( const QFont& font, const QString& caption ) const
{ return titleBoundingRect( font, titleRect(), caption ); }
//! get title bounding rect
virtual QRect titleBoundingRect( const QFont&, QRect, const QString& ) const;
//! palette background
QPalette backgroundPalette( const QWidget*, QPalette ) const;
//! background
QColor backgroundColor( const QWidget* widget, QPalette palette ) const
{ return backgroundColor( widget, palette, isActive() || isForcedActive() ); }
//! background
QColor backgroundColor( const QWidget*, QPalette, bool ) const;
//@}
//! default buttons located on the left
virtual QString defaultButtonsLeft() const;
//! default buttons located on the right
virtual QString defaultButtonsRight() const;
//!@name status change methods (overloaded from KCommonDecorationUnstable)
//@{
//! triggered when window activity is changed
virtual void activeChange();
//! triggered when maximize state changed
virtual void maximizeChange();
//! triggered when window shade is changed
virtual void shadeChange();
//! triggered when window shade is changed
virtual void captionChange();
//@}
//! event filter
virtual bool eventFilter( QObject*, QEvent* );
//! resize event
virtual void resizeEvent(QResizeEvent *e);
public slots:
//! triggers widget update in titleRect only
/*! one needs to add the title top margin to avoid some clipping glitches */
void updateTitleRect( void )
{ widget()->update( titleRect().adjusted( 0, -layoutMetric( LM_TitleEdgeTop ), 0, 1 ) ); }
protected:
//! return shadow cache key associated to this client
ShadowCache::Key key( void ) const
{
ShadowCache::Key key;
key.active = isActive() || isForcedActive();
key.useOxygenShadows = configuration().useOxygenShadows();
key.isShade = isShade();
key.hasTitleOutline = configuration().drawTitleOutline();
key.hasBorder = ( configuration().frameBorder() > Configuration::BorderNone );
return key;
}
//! true when decoration is forced active
void setForceActive( bool value )
{ forceActive_ = value; }
//!@name event filters
//@{
//! paint
virtual void paintEvent( QPaintEvent* );
//! mouse press event
virtual bool mousePressEvent( QMouseEvent* );
//! mouse release event
virtual bool mouseReleaseEvent( QMouseEvent* );
//! mouse move event
virtual bool mouseMoveEvent( QMouseEvent* );
//! drag enter event
virtual bool dragEnterEvent( QDragEnterEvent* );
//! drag move event
virtual bool dragMoveEvent( QDragMoveEvent* );
//! drag leave event
virtual bool dragLeaveEvent( QDragLeaveEvent* );
//! drop event
virtual bool dropEvent( QDropEvent* );
//! timer event
virtual void timerEvent( QTimerEvent* );
//@}
//!@name rendering methods (called in paintEvent)
//@{
//! window background
virtual void renderWindowBackground( QPainter*, const QRect&, const QWidget*, const QPalette& ) const;
//! window border
// this draws a "blue" border around active window
virtual void renderWindowBorder( QPainter*, const QRect&, const QWidget*, const QPalette& ) const;
//! separator
virtual void renderSeparator( QPainter*, const QRect&, const QWidget*, const QColor& ) const;
//! title outline
virtual void renderTitleOutline( QPainter*, const QRect&, const QPalette& ) const;
//! title text
/*! second color, if valid, is for contrast pixel */
virtual void renderTitleText( QPainter*, const QRect&, const QColor&, const QColor& = QColor() ) const;
//! title text
/*! second color, if valid, is for contrast pixel */
virtual void renderTitleText( QPainter*, const QRect&, const QString&, const QColor&, const QColor& = QColor(), bool elide = true ) const;
//! title text
virtual QPixmap renderTitleText( const QRect&, const QString&, const QColor&, bool elide = true ) const;
//! GroupItem
virtual void renderItem( QPainter*, int, const QPalette& );
//! tabbing target rect
virtual void renderTargetRect( QPainter*, const QPalette& );
//! render float frame
virtual void renderFloatFrame( QPainter*, const QRect&, const QPalette& ) const;
//! render dots
virtual void renderDots( QPainter*, const QRect&, const QColor& ) const;
//@}
//! close tab matching give button
virtual bool closeItem( const Button* );
//! index of item matching point
int itemClicked( const QPoint& position, bool between = false ) const
{ return itemData_.itemAt( position , between ); }
//! return pixmap corresponding to a given tab, for dragging
QPixmap itemDragPixmap( int, const QRect& );
//! return true when activity change are animated
bool animateActiveChange( void ) const
{ return ( useAnimations() && !isPreview() ); }
//! return true when activity change are animated
bool animateTitleChange( void ) const
{
return
useAnimations() &&
configuration().animateTitleChange() &&
!configuration().drawTitleOutline() &&
!hideTitleBar() &&
!isPreview();
}
//! true if some title outline is rendered
bool hasTitleOutline( void ) const
{
return
clientGroupItems().count() >= 2 ||
itemData_.isAnimated() ||
( isActive() && configuration().drawTitleOutline() );
}
//! calculate mask
QRegion calcMask( void ) const;
//! text color
QColor titlebarTextColor(const QPalette&) const;
//! text color
QColor titlebarTextColor(const QPalette& palette, bool active) const
{
return active ?
palette.color(QPalette::Active, QPalette::WindowText):
helper().inactiveTitleBarTextColor( palette );
}
//! text color
QColor titlebarContrastColor(const QPalette& palette ) const
{ return titlebarContrastColor( palette.color( widget()->window()->backgroundRole() ) ); }
//! text color
QColor titlebarContrastColor(const QColor& color ) const
{ return helper().calcLightColor( color ); }
//!@name size grip
//@{
//! create size grip
void createSizeGrip( void );
//! delete size grip
void deleteSizeGrip( void );
// size grip
bool hasSizeGrip( void ) const
{ return (bool)sizeGrip_; }
//! size grip
SizeGrip& sizeGrip( void ) const
{ return *sizeGrip_; }
//@}
protected slots:
//! set target item to -1
void clearTargetItem( void );
//! clear force active flag
void clearForceActive( void )
{ if( isActive() ) setForceActive( false ); }
//! title bounding rects
/*! calculate and return title bounding rects in case of tabbed window */
void updateItemBoundingRects( bool alsoUpdate = true );
private:
//! factory
Factory* factory_;
//! size grip widget
SizeGrip* sizeGrip_;
//! configuration
Configuration configuration_;
//! glow animation
Animation* glowAnimation_;
//! title animation data
TitleAnimationData* titleAnimationData_;
//! glow intensity
qreal glowIntensity_;
//! true when initialized
bool initialized_;
//! true when decoration is forced active
bool forceActive_;
//! mouse button
Qt::MouseButton mouseButton_;
//! tab bounding rects
ClientGroupItemDataList itemData_;
//! index of tab being dragged if any, -1 otherwise
int sourceItem_;
//! drag start point
QPoint dragPoint_;
//! drag start timer.
/*!
it is needed to activate animations when this was not done via either
dragMoveEvent or dragLeaveEvent
*/
QBasicTimer dragStartTimer_;
};
} // namespace Oxygen
#endif // EXAMPLECLIENT_H