File indexing completed on 2024-05-05 05:35:34

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