File indexing completed on 2024-04-28 05:32:17
0001 #ifndef oxygenstyle_h 0002 #define oxygenstyle_h 0003 /* 0004 * this file is part of the oxygen gtk engine 0005 * SPDX-FileCopyrightText: 2010 Hugo Pereira Da Costa <hugo.pereira@free.fr> 0006 * SPDX-FileCopyrightText: 2010 Ruslan Kabatsayev <b7.10110111@gmail.com> 0007 * 0008 * SPDX-License-Identifier: LGPL-2.0-or-later 0009 */ 0010 0011 #include "oxygenanimations.h" 0012 #include "oxygenanimationdata.h" 0013 #include "oxygenanimationmodes.h" 0014 #include "oxygenargbhelper.h" 0015 #include "oxygencairocontext.h" 0016 #include "oxygengeometry.h" 0017 #include "oxygengtkcellinfo.h" 0018 #include "oxygengtkgap.h" 0019 #include "oxygenloghandler.h" 0020 #include "oxygenmetrics.h" 0021 #include "oxygenqtsettings.h" 0022 #include "oxygenshadowhelper.h" 0023 #include "oxygenstylehelper.h" 0024 #include "oxygenstyleoptions.h" 0025 #include "oxygentaboptions.h" 0026 #include "oxygentileset.h" 0027 #include "oxygenwidgetexplorer.h" 0028 #include "oxygenwindecooptions.h" 0029 #include "oxygenwindecobutton.h" 0030 #include "oxygenwindowmanager.h" 0031 0032 #include <gdk/gdk.h> 0033 0034 #ifdef GDK_WINDOWING_X11 0035 #include <X11/Xdefs.h> 0036 #endif 0037 0038 namespace Oxygen 0039 { 0040 0041 //! handle all plainting 0042 class Style 0043 { 0044 0045 public: 0046 0047 //! singleton 0048 static Style& instance( void ); 0049 0050 //! destructor 0051 virtual ~Style( void ) 0052 { 0053 if( _instance == this ) 0054 { _instance = 0L; } 0055 } 0056 0057 //! initialize 0058 bool initialize( unsigned int flags = QtSettings::All ); 0059 0060 //! settings 0061 const QtSettings& settings( void ) const 0062 { return _settings; } 0063 0064 //! settings 0065 QtSettings& settings( void ) 0066 { return _settings; } 0067 0068 //! helper 0069 StyleHelper& helper( void ) 0070 { return _helper; } 0071 0072 //! helper 0073 const StyleHelper& helper( void ) const 0074 { return _helper; } 0075 0076 //! animations 0077 const Animations& animations( void ) const 0078 { return _animations; } 0079 0080 //! animations 0081 Animations& animations( void ) 0082 { return _animations; } 0083 0084 //! argb helper 0085 ArgbHelper& argbHelper( void ) 0086 { return _argbHelper; } 0087 0088 //! shadow helper 0089 ShadowHelper& shadowHelper( void ) 0090 { return _shadowHelper; } 0091 0092 //! window manager 0093 WidgetExplorer& widgetExplorer( void ) 0094 { return _widgetExplorer; } 0095 0096 //! window manager 0097 WindowManager& windowManager( void ) 0098 { return _windowManager; } 0099 0100 //! return tabCloseButton for given set of options 0101 Cairo::Surface tabCloseButton( const StyleOptions& ); 0102 0103 //! background surface 0104 bool hasBackgroundSurface( void ) const; 0105 0106 //! update widget mask 0107 void adjustMask( GtkWidget*, int width, int height, bool alpha ); 0108 0109 //! update kwin blur region 0110 void setWindowBlur( GtkWidget*, bool enable ); 0111 0112 //!@name primitives 0113 //@{ 0114 0115 //! fill given rectangle with flat color 0116 void fill( GdkWindow* window, GdkRectangle* r, gint x, gint y, gint w, gint h, Palette::Role role ) const 0117 { fill( window, r, x, y, w, h, _settings.palette().color( Palette::Active, role ) ); } 0118 0119 //! fill given rectangle with flat color 0120 void fill( GdkWindow* window, GdkRectangle* r, gint x, gint y, gint w, gint h, Palette::Group group, Palette::Role role ) const 0121 { fill( window, r, x, y, w, h, _settings.palette().color( group, role ) ); } 0122 0123 //! fill given rectangle with flat color 0124 void fill( GdkWindow*, GdkRectangle*, gint, gint, gint, gint, const ColorUtils::Rgba& color ) const; 0125 0126 //! outline given rectangle with flat color 0127 void outline( GdkWindow*, GdkRectangle*, gint, gint, gint, gint, const ColorUtils::Rgba& color = ColorUtils::Rgba( 1, 0, 0 ) ) const; 0128 0129 //! separators 0130 void drawSeparator( GdkWindow*, GdkRectangle*, gint, gint, gint, gint, const StyleOptions& ); 0131 0132 //! window background 0133 /*! returns true if window gradient could be rendered */ 0134 bool renderWindowBackground( cairo_t*, GdkWindow*, GtkWidget*, GdkRectangle*, gint, gint, gint, gint, const StyleOptions& = StyleOptions(), bool isMaximized=false ); 0135 bool renderWindowBackground( GdkWindow* window, GtkWidget* widget, GdkRectangle* r, gint x, gint y, gint w, gint h, const StyleOptions& o = StyleOptions() ) 0136 { return renderWindowBackground( 0L, window, widget, r, x, y, w, h, o ); } 0137 0138 bool renderWindowBackground( cairo_t* c, gint x, gint y, gint w, gint h, StyleOptions& options, bool maximized ) 0139 { return renderWindowBackground( c, 0L, 0L, 0L, x, y, w, h, options, maximized ); } 0140 0141 bool renderWindowBackground( GdkWindow* window, GdkRectangle* r, gint x, gint y, gint w, gint h, const StyleOptions& o = StyleOptions()) 0142 { return renderWindowBackground( window, 0L, r, x, y, w, h, o ); } 0143 0144 // render background gradient 0145 bool renderBackgroundGradient( cairo_t*, GdkWindow*, GtkWidget*, GdkRectangle*, gint, gint, gint, gint, const StyleOptions& = StyleOptions(), bool isMaximized=false ); 0146 0147 // render background pixmap 0148 bool renderBackgroundPixmap( cairo_t*, GdkWindow*, GtkWidget*, GdkRectangle*, gint, gint, gint, gint, bool isMaximized=false ); 0149 0150 //! groupbox background 0151 bool renderGroupBoxBackground( GdkWindow* window, GtkWidget* widget, GdkRectangle* r, gint x, gint y, gint w, gint h, const StyleOptions& o, TileSet::Tiles tiles = TileSet::Center ) 0152 { return renderGroupBoxBackground( 0L, window, widget, r, x, y, w, h, o, tiles ); } 0153 0154 bool renderGroupBoxBackground( cairo_t*, GdkWindow*, GtkWidget*, GdkRectangle*, gint, gint, gint, gint, const StyleOptions&, TileSet::Tiles = TileSet::Center ); 0155 0156 //! menu background 0157 bool renderMenuBackground( GdkWindow*, Cairo::Context&, gint, gint, gint, gint, const StyleOptions& ) const; 0158 bool renderMenuBackground( GdkWindow* window, GdkRectangle* r, gint x, gint y, gint w, gint h, const StyleOptions& o) const 0159 { Cairo::Context c(window,r); return renderMenuBackground(window, c, x, y, w, h, o); } 0160 0161 //! tooltip background 0162 void renderTooltipBackground( GdkWindow*, GdkRectangle*, gint, gint, gint, gint, const StyleOptions& ) const; 0163 0164 //! tree view header 0165 void renderHeaderBackground( GdkWindow*, GdkRectangle*, gint, gint, gint, gint ); 0166 0167 //! tree view header 0168 void renderHeaderLines( GdkWindow*, GdkRectangle*, gint, gint, gint, gint ) const; 0169 0170 //! tree view lines 0171 void renderTreeLines( GdkWindow*, GdkRectangle*, gint, gint, gint, gint, const Gtk::CellInfoFlags&, const StyleOptions& ) const; 0172 0173 //! editors hole 0174 /*! returns true if window gradient could be rendered */ 0175 void renderHoleBackground( GdkWindow*, GtkWidget*, GdkRectangle*, gint, gint, gint, gint, const StyleOptions&, TileSet::Tiles = TileSet::Ring, gint = Entry_SideMargin ); 0176 void renderHoleBackground( GdkWindow* window, GtkWidget* widget, GdkRectangle* clip, gint x, gint y, gint w, gint h, TileSet::Tiles tiles = TileSet::Ring, gint margin = Entry_SideMargin ) 0177 { renderHoleBackground( window, widget, clip, x, y, w, h, StyleOptions(), tiles, margin ); } 0178 0179 //! splitters 0180 void renderSplitter( GdkWindow*, GdkRectangle*, gint, gint, gint, gint, const StyleOptions&, const AnimationData& = AnimationData() ) const; 0181 0182 //!@name progressbar 0183 //@{ 0184 void renderProgressBarHole( GdkWindow*, GdkRectangle*, gint, gint, gint, gint, const StyleOptions& ); 0185 void renderProgressBarHandle( GdkWindow*, GdkRectangle*, gint, gint, gint, gint, const StyleOptions& ); 0186 //@} 0187 0188 //!@name scrollbar 0189 //@{ 0190 void renderScrollBarHole( GdkWindow*, GdkRectangle*, gint, gint, gint, gint, const StyleOptions& ); 0191 void renderScrollBarHandle( GdkWindow*, GdkRectangle*, gint, gint, gint, gint, const StyleOptions&, const AnimationData& = AnimationData() ); 0192 //@} 0193 0194 //! toolbar handle 0195 void renderToolBarHandle( GdkWindow*, GdkRectangle*, gint, gint, gint, gint, const StyleOptions& ) const; 0196 0197 //! frame 0198 void drawFloatFrame( cairo_t* context, GdkWindow*, GdkRectangle*, gint, gint, gint, gint, const StyleOptions&, Palette::Role = Palette::Window ) const; 0199 void drawFloatFrame( GdkWindow* window, GdkRectangle* r, gint x, gint y, gint w, gint h, const StyleOptions& opt, Palette::Role role = Palette::Window) const 0200 { drawFloatFrame( 0L, window, r, x, y, w, h, opt, role ); } 0201 0202 //! button slab 0203 void renderButtonSlab( GdkWindow* window, GdkRectangle* clipRect, gint x, gint y, gint w, gint h, const StyleOptions& options, TileSet::Tiles tiles = TileSet::Ring ) 0204 { renderButtonSlab( window, clipRect, x, y, w, h, options, AnimationData(), tiles ); } 0205 0206 void renderButtonSlab( GdkWindow*, GdkRectangle*, gint, gint, gint, gint, const StyleOptions&, const AnimationData&, TileSet::Tiles = TileSet::Ring ); 0207 0208 //! checkbox 0209 /*! shadow type is used to decide whether check is on/off or tristate */ 0210 void renderCheckBox( GdkWindow*, GdkRectangle*, gint, gint, gint, gint, GtkShadowType, const StyleOptions&, const AnimationData& = AnimationData() ); 0211 0212 //! radio button 0213 void renderRadioButton( GdkWindow*, GdkRectangle*, gint, gint, gint, gint, GtkShadowType, const StyleOptions&, const AnimationData& = AnimationData() ); 0214 0215 //!@name generic slab 0216 //@{ 0217 0218 void renderSlab( GdkWindow* window, GdkRectangle* clipRect, int x, gint y, gint w, gint h, const StyleOptions& options, const AnimationData& animationData = AnimationData() ) 0219 { renderSlab( window, clipRect, x, y, w, h, Gtk::Gap(), options, animationData ); } 0220 0221 void renderSlab( GdkWindow*, GdkRectangle*, gint, gint, gint, gint, const Gtk::Gap&, const StyleOptions&, const AnimationData& = AnimationData() ); 0222 0223 //@} 0224 0225 //! info bar 0226 void renderInfoBar( GdkWindow*, GdkRectangle*, gint, gint, gint, gint, const ColorUtils::Rgba& ); 0227 0228 //!@name hole 0229 //@{ 0230 0231 void renderHole( GdkWindow*, GdkRectangle*, gint, gint, gint, gint, const Gtk::Gap&, const StyleOptions&, const AnimationData& = AnimationData(), TileSet::Tiles = TileSet::Ring ); 0232 0233 void renderHole( GdkWindow* window, GdkRectangle* r, gint x, gint y, gint w, gint h, const StyleOptions& o, TileSet::Tiles tiles = TileSet::Ring ) 0234 { renderHole( window, r, x, y, w, h, Gtk::Gap(), o, AnimationData(), tiles ); } 0235 0236 void renderHole( GdkWindow* window, GdkRectangle* r, gint x, gint y, gint w, gint h, const StyleOptions& o, const AnimationData& animationData, TileSet::Tiles tiles = TileSet::Ring ) 0237 { renderHole( window, r, x, y, w, h, Gtk::Gap(), o, animationData, tiles ); } 0238 0239 //@} 0240 0241 //!@name dock frame 0242 //@{ 0243 void renderDockFrame( GdkWindow*, GdkRectangle*, gint, gint, gint, gint, const Gtk::Gap&, const StyleOptions& ); 0244 void renderDockFrame( GdkWindow* window, GdkRectangle* r, gint x, gint y, gint w, gint h, const StyleOptions& o ) 0245 { renderDockFrame( window, r, x, y, w, h, Gtk::Gap(), o ); } 0246 //@} 0247 0248 //! groupbox frame 0249 void renderGroupBoxFrame( GdkWindow* window, GtkWidget*, GdkRectangle* r, gint x, gint y, gint w, gint h, const StyleOptions& ); 0250 0251 //! menu item 0252 void renderMenuItemRect( GdkWindow*, GdkRectangle*, GtkWidget*, gint, gint, gint, gint, const StyleOptions&, const AnimationData& = AnimationData() ); 0253 0254 //! selection 0255 void renderSelection( GdkWindow*, GdkRectangle*, gint, gint, gint, gint, TileSet::Tiles tiles, const StyleOptions& ); 0256 0257 //! arrow 0258 void renderArrow( GdkWindow*, GdkRectangle*, GtkArrowType, gint, gint, gint, gint, QtSettings::ArrowSize, const StyleOptions&, const AnimationData&, Palette::Role ) const; 0259 void renderArrow( GdkWindow* window, GdkRectangle* clipRect, GtkArrowType type, gint x, gint y, gint w, gint h, QtSettings::ArrowSize size = QtSettings::ArrowNormal, const StyleOptions& options = Contrast, Palette::Role role = Palette::ButtonText ) const 0260 { renderArrow( window, clipRect, type, x, y, w, h, size, options, AnimationData(), role ); } 0261 0262 //! slider groove 0263 void renderSliderGroove( GdkWindow*, GdkRectangle*, gint, gint, gint, gint, const StyleOptions& ); 0264 0265 //! slider handle 0266 void renderSliderHandle( GdkWindow*, GdkRectangle*, gint, gint, gint, gint, const StyleOptions&, const AnimationData& = AnimationData() ); 0267 0268 //! size grip 0269 void renderSizeGrip( GdkWindow*, GdkRectangle*, GdkWindowEdge, gint, gint, gint, gint ) const; 0270 0271 //! tab 0272 void renderTab( 0273 GdkWindow*, GdkRectangle*, 0274 gint, gint, gint, gint, 0275 GtkPositionType, 0276 const StyleOptions&, 0277 const TabOptions&, 0278 const AnimationData& = AnimationData() ); 0279 0280 //! tabbar base 0281 void renderTabBarBase( 0282 GdkWindow*, GdkRectangle*, 0283 gint, gint, gint, gint, 0284 GtkPositionType, Gtk::Gap, 0285 const StyleOptions&, 0286 const TabOptions& ); 0287 0288 //! tabwidget frame 0289 void renderTabBarFrame( GdkWindow*, GdkRectangle*, gint, gint, gint, gint, const Gtk::Gap&, const StyleOptions& ); 0290 0291 //! tree 'standard' expanders (that is: +!-) 0292 void renderTreeExpander( GdkWindow*, GdkRectangle*, gint, gint, gint, gint, GtkExpanderStyle, const StyleOptions&, const AnimationData&, Palette::Role ) const; 0293 void renderTreeExpander( GdkWindow* window, GdkRectangle* clipRect, gint x, gint y, gint w, gint h, GtkExpanderStyle style, const StyleOptions& options, Palette::Role role ) const 0294 { renderTreeExpander( window, clipRect, x, y, w, h, style, options, AnimationData(), role ); } 0295 0296 //@} 0297 0298 //! draw window decorations 0299 void drawWindowDecoration( cairo_t*, WinDeco::Options, gint, gint, gint, gint, const gchar**, gint, gint); 0300 0301 //! draw window shadow 0302 void drawWindowShadow( cairo_t* context, WinDeco::Options wopt, gint x, gint y, gint w, gint h ); 0303 0304 //! render XShape window decoration mask 0305 void drawWindecoShapeMask( cairo_t* context, WinDeco::Options wopt, gint x, gint y, gint w, gint h ); 0306 0307 //! draw windeco button 0308 void drawWindecoButton(cairo_t*,WinDeco::ButtonType,WinDeco::ButtonStatus,WinDeco::Options, gint,gint,gint,gint); 0309 0310 // adjust scrollbar hole, depending on orientation and buttons settings 0311 void adjustScrollBarHole( int& x, int& y, int& w, int& h, const StyleOptions& ) const; 0312 0313 //! sanitize size 0314 void sanitizeSize( GdkWindow* window, gint& width, gint& height ) const; 0315 0316 //! draw tab close x icon 0317 void renderTabCloseIcon(cairo_t* context, GdkRectangle* r) const; 0318 0319 //! draw tab close button 0320 void renderTabCloseButton(cairo_t* context, GdkRectangle* r, const ColorUtils::Rgba& base, const ColorUtils::Rgba& color); 0321 0322 // get tiles for given tab orientation 0323 TileSet::Tiles tabTiles( GtkPositionType position ) const 0324 { 0325 0326 TileSet::Tiles out( TileSet::Ring ); 0327 switch( position ) 0328 { 0329 case GTK_POS_BOTTOM: out &= ~TileSet::Bottom; break; 0330 case GTK_POS_TOP: out &= ~TileSet::Top; break; 0331 case GTK_POS_LEFT: out &= ~TileSet::Left; break; 0332 case GTK_POS_RIGHT: out &= ~TileSet::Right; break; 0333 default: break; 0334 } 0335 0336 return out; 0337 } 0338 0339 protected: 0340 0341 //! constructor 0342 Style( void ); 0343 0344 //! get color matching role from either style option or default palette 0345 const ColorUtils::Rgba& color( Palette::Role role, const StyleOptions& option ) const 0346 { return color( Palette::Active, role, option ); } 0347 0348 //! get color matching group and role from either style option or default palette 0349 const ColorUtils::Rgba& color( Palette::Group group, Palette::Role role, const StyleOptions& option ) const 0350 { 0351 Palette::ColorSet::const_iterator iter( option._customColors.find( role ) ); 0352 return iter == option._customColors.end() ? _settings.palette().color( group, role ) : iter->second; 0353 } 0354 0355 //! set background surface 0356 void setBackgroundSurface( const std::string& ); 0357 0358 //@name internal rendering 0359 //@{ 0360 0361 //! tab 0362 void renderActiveTab( 0363 GdkWindow*, GdkRectangle*, 0364 gint, gint, gint, gint, 0365 GtkPositionType, 0366 const StyleOptions&, 0367 const TabOptions& ); 0368 0369 //! tab 0370 void renderInactiveTab_Plain( 0371 GdkWindow*, GdkRectangle*, 0372 gint, gint, gint, gint, 0373 GtkPositionType, 0374 const StyleOptions&, 0375 const TabOptions&, 0376 const AnimationData& ); 0377 0378 //! tab 0379 void renderInactiveTab_Single( 0380 GdkWindow*, GdkRectangle*, 0381 gint, gint, gint, gint, 0382 GtkPositionType, 0383 const StyleOptions&, 0384 const TabOptions&, 0385 const AnimationData& ); 0386 0387 //! slab glowing color 0388 ColorUtils::Rgba slabShadowColor( const StyleOptions&, const AnimationData& = AnimationData() ) const; 0389 0390 //! hole glowing color 0391 ColorUtils::Rgba holeShadowColor( const StyleOptions&, const AnimationData& = AnimationData() ) const; 0392 0393 //! groupbox 0394 void renderGroupBox( cairo_t*, const ColorUtils::Rgba&, gint, gint, gint, gint, const StyleOptions& = StyleOptions() ); 0395 0396 //! slab 0397 void renderSlab( Cairo::Context&, gint, gint, gint, gint, const ColorUtils::Rgba&, const StyleOptions&, const AnimationData& = AnimationData(), TileSet::Tiles tiles = TileSet::Ring ); 0398 0399 //! progressbar hole (groove) 0400 /*! also used for progress bars */ 0401 void renderScrollBarHole( Cairo::Context&, gint, gint, gint, gint, const ColorUtils::Rgba&, bool vertical, TileSet::Tiles = TileSet::Full ); 0402 0403 //! add hole mask to context 0404 void renderHoleMask( cairo_t*, gint, gint, gint, gint, TileSet::Tiles, gint ); 0405 0406 //! returns point position for generic arrows 0407 Polygon genericArrow( GtkArrowType, QtSettings::ArrowSize = QtSettings::ArrowNormal ) const; 0408 0409 //@} 0410 0411 //!@name window decoration rendering 0412 //@{ 0413 0414 //! draw resize handles for window decoration 0415 void renderWindowDots(cairo_t*, gint x, gint y, gint w, gint h, const ColorUtils::Rgba&, WinDeco::Options); 0416 0417 //! internal windeco renderer 0418 void renderWindowDecoration( cairo_t*, WinDeco::Options, gint, gint, gint, gint, const gchar**, gint, gint, bool = true); 0419 0420 //@} 0421 0422 //!@name utilities 0423 //@{ 0424 0425 // center rect 0426 void centerRect( GdkRectangle*, GdkRectangle* ) const; 0427 0428 // generate map from gap 0429 void generateGapMask( Cairo::Context&, gint, gint, gint, gint, const Gtk::Gap& ) const; 0430 0431 //@} 0432 0433 //! monitored files is changed 0434 static void fileChanged( GFileMonitor*, GFile*, GFile*, GFileMonitorEvent, gpointer ); 0435 0436 //! used to store slab characteristics 0437 class SlabRect 0438 { 0439 public: 0440 0441 //! constructor 0442 explicit SlabRect(void): 0443 _x(0), 0444 _y(0), 0445 _w(-1), 0446 _h(-1), 0447 _tiles( TileSet::Ring ) 0448 {} 0449 0450 //! constructor 0451 explicit SlabRect( int x, int y, int w, int h, const TileSet::Tiles& tiles, const StyleOptions& options = StyleOptions() ): 0452 _x(x), 0453 _y(y), 0454 _w(w), 0455 _h(h), 0456 _tiles( TileSet::Tiles( tiles ) ), 0457 _options( options ) 0458 {} 0459 0460 int _x; 0461 int _y; 0462 int _w; 0463 int _h; 0464 TileSet::Tiles _tiles; 0465 StyleOptions _options; 0466 0467 typedef std::vector<SlabRect> List; 0468 0469 }; 0470 0471 private: 0472 0473 //! log handler 0474 LogHandler _logHandler; 0475 0476 //! Qt settings 0477 QtSettings _settings; 0478 0479 //! helper 0480 StyleHelper _helper; 0481 0482 //! animations 0483 Animations _animations; 0484 0485 //! argb helper 0486 ArgbHelper _argbHelper; 0487 0488 //! shadow helper 0489 ShadowHelper _shadowHelper; 0490 0491 //! widget explorer 0492 WidgetExplorer _widgetExplorer; 0493 0494 //! window manager 0495 WindowManager _windowManager; 0496 0497 //! background surface 0498 Cairo::Surface _backgroundSurface; 0499 0500 //! Tab close buttons 0501 class TabCloseButtons 0502 { 0503 public: 0504 0505 //! constructor 0506 TabCloseButtons( void ): 0507 normal(0L), 0508 active(0L), 0509 inactive(0L), 0510 prelight(0L) 0511 {} 0512 0513 //! destructor 0514 virtual ~TabCloseButtons( void ) 0515 {} 0516 0517 Cairo::Surface normal; 0518 Cairo::Surface active; 0519 Cairo::Surface inactive; 0520 Cairo::Surface prelight; 0521 }; 0522 0523 //! Tab close buttons 0524 TabCloseButtons _tabCloseButtons; 0525 0526 #ifdef GDK_WINDOWING_X11 0527 //! Atom to show kwin what regions of translucent windows should be blurred 0528 Atom _blurAtom; 0529 #endif 0530 0531 //! singleton 0532 static Style* _instance; 0533 0534 }; 0535 0536 } 0537 0538 #endif