1#ifndef oxygen_style_helper_h
2#define oxygen_style_helper_h
3
4/*
5 * Copyright 2010 Hugo Pereira Da Costa <hugo.pereira@free.fr>
6 * Copyright 2008 Long Huynh Huu <long.upcase@googlemail.com>
7 * Copyright 2007 Matthew Woehlke <mw_triad@users.sourceforge.net>
8 * Copyright 2007 Casper Boemann <cbr@boemann.dk>
9 *
10 * This library is free software; you can redistribute it and/or
11 * modify it under the terms of the GNU Library General Public
12 * License version 2 as published by the Free Software Foundation.
13 *
14 * This library is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * Library General Public License for more details.
18 *
19 * You should have received a copy of the GNU Library General Public License
20 * along with this library; see the file COPYING.LIB. If not, write to
21 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
22 * Boston, MA 02110-1301, USA.
23 */
24
25#include "oxygenhelper.h"
26#include "oxygenanimationmodes.h"
27
28#include <KWindowSystem>
29#include <KDebug>
30
31#ifdef Q_WS_X11
32#include <QtGui/QX11Info>
33#include <X11/Xdefs.h>
34#endif
35
36//! helper class
37/*! contains utility functions used at multiple places in oxygen style */
38namespace Oxygen
39{
40
41 enum HoleOption
42 {
43 HoleFocus = 0x1,
44 HoleHover = 0x2,
45 HoleOutline = 0x4,
46 HoleContrast = 0x8
47 };
48
49 Q_DECLARE_FLAGS(HoleOptions, HoleOption)
50
51 class StyleHelper : public Helper
52 {
53 public:
54
55 //! constructor
56 explicit StyleHelper( const QByteArray &componentName );
57
58 //! destructor
59 virtual ~StyleHelper() {}
60
61 //! dynamically allocated debug area
62 int debugArea( void ) const
63 { return _debugArea; }
64
65 //! clear cache
66 virtual void invalidateCaches();
67
68 //! update maximum cache size
69 virtual void setMaxCacheSize( int );
70
71 //! background gradient
72 virtual void setUseBackgroundGradient( bool value )
73 { _useBackgroundGradient = value; }
74
75 //! render window background using a given color as a reference
76 /*!
77 For the widget style, both the gradient and the background pixmap are rendered in the same method.
78 All the actual rendering is performed by the base class
79 */
80 using Helper::renderWindowBackground;
81 virtual void renderWindowBackground( QPainter*, const QRect&, const QWidget*, const QColor&, int y_shift=-23, int gradientHeight = 20 );
82
83 //! set background gradient hint to widget
84 virtual void setHasBackgroundGradient( WId, bool ) const;
85
86 // render menu background
87 void renderMenuBackground( QPainter* p, const QRect& clipRect, const QWidget* widget, const QPalette& pal )
88 { renderMenuBackground( p, clipRect, widget, pal.color( widget->window()->backgroundRole() ) ); }
89
90 // render menu background
91 void renderMenuBackground( QPainter*, const QRect&, const QWidget*, const QColor& );
92
93 //! returns menu background color matching position in a given menu widget
94 virtual const QColor& menuBackgroundColor( const QColor& color, const QWidget* w, const QPoint& point )
95 {
96 if( !( w && w->window() ) || checkAutoFillBackground( w ) ) return color;
97 else return menuBackgroundColor( color, w->window()->height(), w->mapTo( w->window(), point ).y() );
98 }
99
100 //! returns menu background color matching position in a menu widget of given height
101 virtual const QColor& menuBackgroundColor( const QColor& color, int height, int y )
102 { return backgroundColor( color, qMin( qreal( 1.0 ), qreal( y )/qMin( 200, 3*height/4 ) ) ); }
103
104 //! color
105 inline const QColor& calcMidColor( const QColor& color );
106
107 //! merge active and inactive palettes based on ratio, for smooth enable state change transition
108 QPalette mergePalettes( const QPalette&, qreal ratio ) const;
109
110 //! overloaded window decoration buttons for MDI windows
111 virtual QPixmap dockWidgetButton( const QColor& color, bool pressed, int size = 21 );
112
113 //! round corners( used for Menus, combobox drop-down, detached toolbars and dockwidgets
114 TileSet *roundCorner( const QColor&, int size = 5 );
115
116 //! groupbox background
117 TileSet *slope( const QColor&, qreal shade, int size = 7 );
118
119 //!@name slabs
120 //@{
121
122 //! progressbar
123 TileSet *progressBarIndicator( const QPalette&, int );
124
125 //! dial
126 QPixmap dialSlab( const QColor& color, qreal shade, int size = 7 )
127 { return dialSlab( color, QColor(), shade, size ); }
128
129 //! dial
130 QPixmap dialSlab( const QColor&, const QColor&, qreal shade, int size = 7 );
131
132 // round slabs
133 QPixmap roundSlab( const QColor& color, qreal shade, int size = 7 )
134 { return roundSlab( color, QColor(), shade, size ); }
135
136 // round slab
137 QPixmap roundSlab( const QColor&, const QColor& glow, qreal shade, int size = 7 );
138
139 //! slider slab
140 QPixmap sliderSlab( const QColor&, const QColor& glow, bool sunken, qreal shade, int size = 7 );
141
142 //@}
143
144 //!@name holes
145 //@{
146
147 void fillHole( QPainter&, const QRect&, int size = 7 ) const;
148
149 //! generic hole
150 void renderHole( QPainter *p, const QColor& color, const QRect &r,
151 HoleOptions options = 0,
152 TileSet::Tiles tiles = TileSet::Ring )
153 { renderHole( p, color, r, options, -1, Oxygen::AnimationNone, tiles ); }
154
155 //! generic hole (with animated glow)
156 void renderHole(
157 QPainter*, const QColor&, const QRect &r,
158 HoleOptions,
159 qreal opacity, Oxygen::AnimationMode animationMode,
160 TileSet::Tiles = TileSet::Ring );
161
162 TileSet *holeFlat( const QColor&, qreal shade, bool fill = true, int size = 7 );
163
164 //! scrollbar hole
165 TileSet *scrollHole( const QColor&, Qt::Orientation orientation, bool smallShadow = false );
166
167 //! scrollbar handle
168 TileSet *scrollHandle( const QColor&, const QColor&, int size = 7 );
169
170 //@}
171
172 //! scrollbar groove
173 TileSet *groove( const QColor&, int size = 7 );
174
175 //! focus rect for flat toolbuttons
176 TileSet *slitFocused( const QColor& );
177
178 //! dock frame
179 TileSet *dockFrame( const QColor&, const QColor& );
180
181 //! selection
182 TileSet *selection( const QColor&, int height, bool custom );
183
184 //! inverse glow
185 /*! this method must be public because it is used directly by OxygenStyle to draw dials */
186 void drawInverseGlow( QPainter&, const QColor&, int pad, int size, int rsize ) const;
187
188 //!@name utility functions
189
190 //! returns true if compositing is active
191 bool compositingActive( void ) const;
192
193 //! returns true if a given widget supports alpha channel
194 inline bool hasAlphaChannel( const QWidget* ) const;
195
196 //! returns true if given widget will get a decoration
197 bool hasDecoration( const QWidget* ) const;
198
199 //@}
200
201 protected:
202
203 //!@name holes
204 //@{
205
206 //! holes
207 TileSet *hole( const QColor& color, int size = 7, HoleOptions options = 0 )
208 { return hole( color, QColor(), size, options ); }
209
210 //! holes
211 TileSet *hole( const QColor&, const QColor& glow, int size = 7, HoleOptions = 0 );
212
213 //@}
214
215 // round slabs
216 void drawRoundSlab( QPainter&, const QColor&, qreal );
217
218 // slider slabs
219 void drawSliderSlab( QPainter&, const QColor&, bool sunken, qreal );
220
221 private:
222
223 //! dynamically allocated debug area
224 int _debugArea;
225
226 //! background grandient
227 bool _useBackgroundGradient;
228
229 Cache<QPixmap> _dialSlabCache;
230 Cache<QPixmap> _roundSlabCache;
231 Cache<QPixmap> _sliderSlabCache;
232 Cache<TileSet> _holeCache;
233 Cache<TileSet> _scrollHandleCache;
234
235 //! mid color cache
236 ColorCache _midColorCache;
237
238 //! dock button cache
239 PixmapCache _dockWidgetButtonCache;
240
241 typedef BaseCache<TileSet> TileSetCache;
242 TileSetCache _cornerCache;
243 TileSetCache _holeFlatCache;
244 TileSetCache _slopeCache;
245 TileSetCache _grooveCache;
246 TileSetCache _slitCache;
247 TileSetCache _dockFrameCache;
248 TileSetCache _scrollHoleCache;
249 TileSetCache _selectionCache;
250 TileSetCache _progressBarCache;
251
252 #ifdef Q_WS_X11
253
254 //! background gradient hint atom
255 Atom _compositingManagerAtom;
256
257 #endif
258
259 };
260
261 //____________________________________________________________________
262 const QColor& StyleHelper::calcMidColor( const QColor& color )
263 {
264 const quint64 key( color.rgba() );
265 QColor* out( _midColorCache.object( key ) );
266 if( !out )
267 {
268 out = new QColor( KColorScheme::shade( color, KColorScheme::MidShade, _contrast - 1.0 ) );
269 _midColorCache.insert( key, out );
270 }
271
272 return *out;
273 }
274
275 //____________________________________________________________________
276 bool StyleHelper::hasAlphaChannel( const QWidget* widget ) const
277 {
278
279 #ifdef Q_WS_X11
280 if( compositingActive() )
281 {
282
283 if( widget ) return widget->x11Info().depth() == 32;
284 else return QX11Info().appDepth() == 32;
285
286 } else return false;
287
288 #else
289 return compositingActive();
290 #endif
291
292 }
293
294}
295#endif
296