File indexing completed on 2024-05-12 17:06:31

0001 #ifndef oxygen_shadowCacheh
0002 #define oxygen_shadowCacheh
0003 
0004 //////////////////////////////////////////////////////////////////////////////
0005 // oxygenshadowcache.h
0006 // handles caching of TileSet objects to draw shadows
0007 // -------------------
0008 //
0009 // SPDX-FileCopyrightText: 2009 Hugo Pereira Da Costa <hugo.pereira@free.fr>
0010 //
0011 // SPDX-License-Identifier: MIT
0012 //////////////////////////////////////////////////////////////////////////////
0013 
0014 #include "oxygen_export.h"
0015 #include "oxygenhelper.h"
0016 
0017 #include <QCache>
0018 #include <QRadialGradient>
0019 #include <cmath>
0020 
0021 namespace Oxygen
0022 {
0023 
0024 class OXYGEN_EXPORT ShadowCache
0025 {
0026 public:
0027     //* constructor
0028     explicit ShadowCache(Helper &);
0029 
0030     //* read configuration
0031     void readConfig(void);
0032 
0033     //* animations duration
0034     void setAnimationsDuration(int);
0035 
0036     //* cache size
0037     void setEnabled(bool enabled)
0038     {
0039         _enabled = enabled;
0040         if (enabled) {
0041             _shadowCache.setMaxCost(1 << 6);
0042             _animatedShadowCache.setMaxCost(_maxIndex << 6);
0043 
0044         } else {
0045             _shadowCache.setMaxCost(1);
0046             _animatedShadowCache.setMaxCost(1);
0047         }
0048     }
0049 
0050     //* max animation index
0051     int maxIndex(void) const
0052     {
0053         return _maxIndex;
0054     }
0055 
0056     //* max animation index
0057     void setMaxIndex(int value)
0058     {
0059         _maxIndex = value;
0060         if (_enabled) {
0061             _shadowCache.setMaxCost(1 << 6);
0062             _animatedShadowCache.setMaxCost(_maxIndex << 6);
0063         }
0064     }
0065 
0066     //* invalidate caches
0067     void invalidateCaches(void)
0068     {
0069         _shadowCache.clear();
0070         _animatedShadowCache.clear();
0071     }
0072 
0073     //* true if shadow is enabled for a given group
0074     bool isEnabled(QPalette::ColorGroup) const;
0075 
0076     //* set shadow size manually
0077     void setShadowSize(QPalette::ColorGroup, int);
0078 
0079     //* shadow size
0080     int shadowSize(void) const;
0081 
0082     //* Key class to be used into QCache
0083     /*! class is entirely inline for optimization */
0084     class Key
0085     {
0086     public:
0087         //* explicit constructor
0088         explicit Key(void)
0089         {
0090         }
0091 
0092         //* constructor from int
0093         explicit Key(int hash)
0094             : index(hash >> 3)
0095             , active((hash >> 2) & 1)
0096             , isShade((hash >> 1) & 1)
0097             , hasBorder((hash)&1)
0098         {
0099         }
0100 
0101         //* hash function
0102         int hash(void) const
0103         {
0104             return (index << 3) | (active << 2) | (isShade << 1) | (hasBorder);
0105         }
0106 
0107         int index = 0;
0108         bool active = false;
0109         bool isShade = false;
0110         bool hasBorder = true;
0111     };
0112 
0113     //* get shadow matching client
0114     TileSet tileSet(const Key &);
0115 
0116     //* get shadow matching client and opacity
0117     TileSet tileSet(Key, qreal);
0118 
0119     //* simple pixmap
0120     QPixmap pixmap(const Key &key) const
0121     {
0122         return pixmap(key, key.active);
0123     }
0124 
0125     //* simple pixmap, with opacity
0126     QPixmap animatedPixmap(const Key &, qreal opacity);
0127 
0128 private:
0129     Helper &helper(void) const
0130     {
0131         return _helper;
0132     }
0133 
0134     //* simple pixmap
0135     QPixmap pixmap(const Key &, bool active) const;
0136 
0137     //* draw gradient into rect
0138     /*! a separate method is used in order to properly account for corners */
0139     void renderGradient(QPainter &, const QRectF &, const QRadialGradient &, bool hasBorder = true) const;
0140 
0141     //* helper
0142     Helper &_helper;
0143 
0144     //* defines overlap between shadows and body
0145     enum { overlap = 4 };
0146 
0147     //* caching enable state
0148     bool _enabled;
0149 
0150     //* shadow size
0151     int _activeShadowSize;
0152 
0153     //* shadow size
0154     int _inactiveShadowSize;
0155 
0156     //* max index
0157     /*! it is used to set caches max cost, and calculate animation opacity */
0158     int _maxIndex;
0159 
0160     //* cache
0161     using TileSetCache = QCache<int, TileSet>;
0162 
0163     //* shadow cache
0164     TileSetCache _shadowCache;
0165 
0166     //* animated shadow cache
0167     TileSetCache _animatedShadowCache;
0168 };
0169 }
0170 
0171 #endif