File indexing completed on 2024-05-05 05:35:25
0001 #ifndef oxygenframeshadow_h 0002 #define oxygenframeshadow_h 0003 0004 ////////////////////////////////////////////////////////////////////////////// 0005 // oxygenframeshadow.h 0006 // handle frames' shadows and rounded corners 0007 // ------------------- 0008 // 0009 // SPDX-FileCopyrightText: 2010 Hugo Pereira Da Costa <hugo.pereira@free.fr> 0010 // 0011 // Largely inspired from skulpture widget style 0012 // SPDX-FileCopyrightText: 2007-2009 Christoph Feck <christoph@maxiom.de> 0013 // 0014 // SPDX-License-Identifier: MIT 0015 ////////////////////////////////////////////////////////////////////////////// 0016 0017 #include "oxygenaddeventfilter.h" 0018 #include "oxygenstylehelper.h" 0019 0020 #include <QEvent> 0021 #include <QObject> 0022 #include <QSet> 0023 0024 #include <KColorScheme> 0025 #include <QPaintEvent> 0026 #include <QWidget> 0027 0028 namespace Oxygen 0029 { 0030 //* shadow manager 0031 class FrameShadowFactory : public QObject 0032 { 0033 Q_OBJECT 0034 0035 public: 0036 //* constructor 0037 explicit FrameShadowFactory(QObject *parent) 0038 : QObject(parent) 0039 { 0040 } 0041 0042 //* register widget 0043 bool registerWidget(QWidget *, StyleHelper &); 0044 0045 //* unregister 0046 void unregisterWidget(QWidget *); 0047 0048 //* true if widget is registered 0049 bool isRegistered(const QWidget *widget) const 0050 { 0051 return _registeredWidgets.contains(widget); 0052 } 0053 0054 //* event filter 0055 bool eventFilter(QObject *, QEvent *) override; 0056 0057 //* set contrast 0058 void setHasContrast(const QWidget *widget, bool) const; 0059 0060 //* update state 0061 void updateState(const QWidget *, bool focus, bool hover, qreal opacity, AnimationMode) const; 0062 0063 //* update shadows geometry 0064 void updateShadowsGeometry(const QObject *, QRect) const; 0065 0066 private Q_SLOTS: 0067 0068 //* triggered by object destruction 0069 void widgetDestroyed(QObject *); 0070 0071 private: 0072 //* install shadows on given widget 0073 void installShadows(QWidget *, StyleHelper &, bool flat = false); 0074 0075 //* update shadows geometry 0076 void updateShadowsGeometry(QObject *) const; 0077 0078 //* remove shadows from widget 0079 void removeShadows(QWidget *); 0080 0081 //* raise shadows 0082 void raiseShadows(QObject *) const; 0083 0084 //* update shadows 0085 void update(QObject *) const; 0086 0087 //* install shadow on given side 0088 void installShadow(QWidget *, StyleHelper &, ShadowArea, bool flat = false) const; 0089 0090 //* needed to block ChildAdded events when creating shadows 0091 AddEventFilter _addEventFilter; 0092 0093 //* set of registered widgets 0094 QSet<const QObject *> _registeredWidgets; 0095 }; 0096 0097 //* frame shadow 0098 /** this allows the shadow to be painted over the widgets viewport */ 0099 class FrameShadowBase : public QWidget 0100 { 0101 Q_OBJECT 0102 0103 public: 0104 //* constructor 0105 explicit FrameShadowBase(ShadowArea area) 0106 : _area(area) 0107 { 0108 } 0109 0110 //* shadow area 0111 void setShadowArea(ShadowArea area) 0112 { 0113 _area = area; 0114 } 0115 0116 //* shadow area 0117 const ShadowArea &shadowArea() const 0118 { 0119 return _area; 0120 } 0121 0122 //* set contrast 0123 void setHasContrast(bool value) 0124 { 0125 if (_contrast == value) 0126 return; 0127 _contrast = value; 0128 } 0129 0130 //* true if contrast pixel is enabled 0131 bool hasContrast(void) const 0132 { 0133 return _contrast; 0134 } 0135 0136 //* update geometry 0137 virtual void updateGeometry(void) = 0; 0138 0139 //* update geometry 0140 virtual void updateGeometry(QRect) = 0; 0141 0142 //* update state 0143 virtual void updateState(bool, bool, qreal, AnimationMode) 0144 { 0145 } 0146 0147 protected: 0148 //* initialization 0149 virtual void init(); 0150 0151 //* return viewport associated to parent widget 0152 virtual QWidget *viewport(void) const; 0153 0154 //* parent margins 0155 /** offsets between update rect and parent widget rect. It is set via updateGeometry */ 0156 const QMargins &margins(void) const 0157 { 0158 return _margins; 0159 } 0160 0161 //* margins 0162 /** offsets between update rect and parent widget rect. It is set via updateGeometry */ 0163 void setMargins(const QMargins &margins) 0164 { 0165 _margins = margins; 0166 } 0167 0168 private: 0169 //* shadow area 0170 ShadowArea _area; 0171 0172 //* margins 0173 /** offsets between update rect and parent widget rect. It is set via updateGeometry */ 0174 QMargins _margins; 0175 0176 //* contrast pixel 0177 bool _contrast = false; 0178 }; 0179 0180 //* frame shadow 0181 /** this allows the shadow to be painted over the widgets viewport */ 0182 class SunkenFrameShadow : public FrameShadowBase 0183 { 0184 Q_OBJECT 0185 0186 public: 0187 //* constructor 0188 SunkenFrameShadow(ShadowArea area, StyleHelper &helper) 0189 : FrameShadowBase(area) 0190 , _helper(helper) 0191 { 0192 init(); 0193 } 0194 0195 //* update geometry 0196 /** nothing is done. Rect must be passed explicitly */ 0197 void updateGeometry(void) override 0198 { 0199 } 0200 0201 //* update geometry 0202 void updateGeometry(QRect) override; 0203 0204 //* update state 0205 void updateState(bool focus, bool hover, qreal opacity, AnimationMode) override; 0206 0207 protected: 0208 //* painting 0209 void paintEvent(QPaintEvent *) override; 0210 0211 private: 0212 //* helper 0213 StyleHelper &_helper; 0214 0215 //*@name widget state 0216 //@{ 0217 bool _hasFocus = false; 0218 bool _mouseOver = false; 0219 qreal _opacity = -1; 0220 AnimationMode _mode = AnimationNone; 0221 }; 0222 0223 //* frame shadow 0224 /** this allows the shadow to be painted over the widgets viewport */ 0225 class FlatFrameShadow : public FrameShadowBase 0226 { 0227 Q_OBJECT 0228 0229 public: 0230 //* constructor 0231 FlatFrameShadow(ShadowArea area, StyleHelper &helper) 0232 : FrameShadowBase(area) 0233 , _helper(helper) 0234 { 0235 init(); 0236 } 0237 0238 //* update geometry 0239 void updateGeometry(void) override; 0240 0241 //* update geometry 0242 void updateGeometry(QRect) override; 0243 0244 protected: 0245 //* painting 0246 void paintEvent(QPaintEvent *) override; 0247 0248 private: 0249 //* helper 0250 StyleHelper &_helper; 0251 }; 0252 } 0253 0254 #endif