796e7ff92a
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
462 lines
14 KiB
C++
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
|