#ifndef OXYGEN_STYLE_HELPER_H #define OXYGEN_STYLE_HELPER_H /* * Copyright 2010 Hugo Pereira Da Costa * Copyright 2008 Long Huynh Huu * Copyright 2007 Matthew Woehlke * Copyright 2007 Casper Boemann * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public * License version 2 as published by the Free Software Foundation. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Library General Public License for more details. * * You should have received a copy of the GNU Library General Public License * along with this library; see the file COPYING.LIB. If not, write to * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #include "oxygenhelper.h" #include #include #ifdef Q_WS_X11 #include #include #endif //! helper class /*! contains utility functions used at multiple places in oxygen style */ namespace Oxygen { enum HoleOption { HoleFocus = 0x1, HoleHover = 0x2, HoleOutline = 0x4, HoleContrast = 0x8 }; Q_DECLARE_FLAGS(HoleOptions, HoleOption) class StyleHelper : public Helper { public: //! constructor explicit StyleHelper( const QByteArray &componentName ); //! destructor virtual ~StyleHelper() {} //! dynamically allocated debug area int debugArea( void ) const { return _debugArea; } //! clear cache virtual void invalidateCaches(); //! update maximum cache size virtual void setMaxCacheSize( int ); //! background gradient virtual void setUseBackgroundGradient( bool value ) { _useBackgroundGradient = value; } //! render window background using a given color as a reference /*! For the widget style, both the gradient and the background pixmap are rendered in the same method. All the actual rendering is performed by the base class */ using Helper::renderWindowBackground; virtual void renderWindowBackground( QPainter*, const QRect&, const QWidget*, const QColor&, int y_shift=-23, int gradientHeight = 20 ); //! set background gradient hint to widget virtual void setHasBackgroundGradient( WId, bool ) const; // render menu background void renderMenuBackground( QPainter* p, const QRect& clipRect, const QWidget* widget, const QPalette& pal ) { renderMenuBackground( p, clipRect, widget, pal.color( widget->window()->backgroundRole() ) ); } // render menu background void renderMenuBackground( QPainter*, const QRect&, const QWidget*, const QColor& ); //! returns menu background color matching position in a given menu widget virtual const QColor& menuBackgroundColor( const QColor& color, const QWidget* w, const QPoint& point ) { if( !( w && w->window() ) || checkAutoFillBackground( w ) ) return color; else return menuBackgroundColor( color, w->window()->height(), w->mapTo( w->window(), point ).y() ); } //! returns menu background color matching position in a menu widget of given height virtual const QColor& menuBackgroundColor( const QColor& color, int height, int y ) { return backgroundColor( color, qMin( qreal( 1.0 ), qreal( y )/qMin( 200, 3*height/4 ) ) ); } //! color inline const QColor& calcMidColor( const QColor& color ); //! merge active and inactive palettes based on ratio, for smooth enable state change transition QPalette mergePalettes( const QPalette&, qreal ratio ) const; //! overloaded window decoration buttons for MDI windows virtual QPixmap dockWidgetButton( const QColor& color, bool pressed, int size = 21 ); //! round corners( used for Menus, combobox drop-down, detached toolbars and dockwidgets TileSet *roundCorner( const QColor&, int size = 5 ); //! groupbox background TileSet *slope( const QColor&, qreal shade, int size = 7 ); //!@name slabs //@{ //! progressbar TileSet *progressBarIndicator( const QPalette&, int ); //! dial QPixmap dialSlab( const QColor& color, qreal shade, int size = 7 ) { return dialSlab( color, QColor(), shade, size ); } //! dial QPixmap dialSlab( const QColor&, const QColor&, qreal shade, int size = 7 ); // round slabs QPixmap roundSlab( const QColor& color, qreal shade, int size = 7 ) { return roundSlab( color, QColor(), shade, size ); } // round slab QPixmap roundSlab( const QColor&, const QColor& glow, qreal shade, int size = 7 ); //! slider slab QPixmap sliderSlab( const QColor&, const QColor& glow, bool sunken, qreal shade, int size = 7 ); //@} //!@name holes //@{ void fillHole( QPainter&, const QRect&, int size = 7 ) const; //! generic hole void renderHole( QPainter *p, const QColor& color, const QRect &r, HoleOptions options = 0, TileSet::Tiles tiles = TileSet::Ring ); TileSet *holeFlat( const QColor&, qreal shade, bool fill = true, int size = 7 ); //! scrollbar hole TileSet *scrollHole( const QColor&, Qt::Orientation orientation, bool smallShadow = false ); //! scrollbar handle TileSet *scrollHandle( const QColor&, const QColor&, int size = 7 ); //@} //! scrollbar groove TileSet *groove( const QColor&, int size = 7 ); //! focus rect for flat toolbuttons TileSet *slitFocused( const QColor& ); //! dock frame TileSet *dockFrame( const QColor&, const QColor& ); //! selection TileSet *selection( const QColor&, int height, bool custom ); //! inverse glow /*! this method must be public because it is used directly by OxygenStyle to draw dials */ void drawInverseGlow( QPainter&, const QColor&, int pad, int size, int rsize ) const; //!@name utility functions //! returns true if compositing is active bool compositingActive( void ) const; //! returns true if a given widget supports alpha channel inline bool hasAlphaChannel( const QWidget* ) const; //! returns true if given widget will get a decoration bool hasDecoration( const QWidget* ) const; //@} protected: //!@name holes //@{ //! holes TileSet *hole( const QColor& color, int size = 7, HoleOptions options = 0 ) { return hole( color, QColor(), size, options ); } //! holes TileSet *hole( const QColor&, const QColor& glow, int size = 7, HoleOptions = 0 ); //@} // round slabs void drawRoundSlab( QPainter&, const QColor&, qreal ); // slider slabs void drawSliderSlab( QPainter&, const QColor&, bool sunken, qreal ); private: //! dynamically allocated debug area int _debugArea; //! background grandient bool _useBackgroundGradient; Cache _dialSlabCache; Cache _roundSlabCache; Cache _sliderSlabCache; Cache _holeCache; Cache _scrollHandleCache; //! mid color cache ColorCache _midColorCache; //! dock button cache PixmapCache _dockWidgetButtonCache; typedef BaseCache TileSetCache; TileSetCache _cornerCache; TileSetCache _holeFlatCache; TileSetCache _slopeCache; TileSetCache _grooveCache; TileSetCache _slitCache; TileSetCache _dockFrameCache; TileSetCache _scrollHoleCache; TileSetCache _selectionCache; TileSetCache _progressBarCache; #ifdef Q_WS_X11 //! background gradient hint atom Atom _compositingManagerAtom; #endif }; //____________________________________________________________________ const QColor& StyleHelper::calcMidColor( const QColor& color ) { const quint64 key( color.rgba() ); QColor* out( _midColorCache.object( key ) ); if( !out ) { out = new QColor( KColorScheme::shade( color, KColorScheme::MidShade, _contrast - 1.0 ) ); _midColorCache.insert( key, out ); } return *out; } //____________________________________________________________________ bool StyleHelper::hasAlphaChannel( const QWidget* widget ) const { #ifdef Q_WS_X11 if( compositingActive() ) { if( widget ) return widget->x11Info().depth() == 32; else return QX11Info().appDepth() == 32; } else return false; #else return compositingActive(); #endif } } #endif