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