File indexing completed on 2024-05-19 05:35:26
0001 #ifndef oxygentransitionwidget_h 0002 #define oxygentransitionwidget_h 0003 ////////////////////////////////////////////////////////////////////////////// 0004 // oxygentransitionwidget.h 0005 // stores event filters and maps widgets to transitions for transitions 0006 // ------------------- 0007 // 0008 // SPDX-FileCopyrightText: 2009 Hugo Pereira Da Costa <hugo.pereira@free.fr> 0009 // 0010 // SPDX-License-Identifier: MIT 0011 ////////////////////////////////////////////////////////////////////////////// 0012 0013 #include "oxygen.h" 0014 #include "oxygenanimation.h" 0015 0016 #include <QWidget> 0017 0018 #include <cmath> 0019 0020 namespace Oxygen 0021 { 0022 //* temporary widget used to perform smooth transition between one widget state and another 0023 class TransitionWidget : public QWidget 0024 { 0025 Q_OBJECT 0026 0027 //* declare opacity property 0028 Q_PROPERTY(qreal opacity READ opacity WRITE setOpacity) 0029 0030 public: 0031 //* shortcut to painter 0032 using Pointer = WeakPointer<TransitionWidget>; 0033 0034 //* constructor 0035 TransitionWidget(QWidget *parent, int duration); 0036 0037 //*@name flags 0038 //@{ 0039 enum Flag { None = 0, GrabFromWindow = 1 << 0, Transparent = 1 << 1, PaintOnWidget = 1 << 2 }; 0040 0041 Q_DECLARE_FLAGS(Flags, Flag) 0042 0043 void setFlags(Flags value) 0044 { 0045 _flags = value; 0046 } 0047 0048 void setFlag(Flag flag, bool value = true) 0049 { 0050 if (value) 0051 _flags |= flag; 0052 else 0053 _flags &= (~flag); 0054 } 0055 0056 bool testFlag(Flag flag) const 0057 { 0058 return _flags.testFlag(flag); 0059 } 0060 0061 //@} 0062 0063 //* duration 0064 void setDuration(int duration) 0065 { 0066 if (_animation) { 0067 _animation.data()->setDuration(duration); 0068 } 0069 } 0070 0071 //* duration 0072 int duration(void) const 0073 { 0074 return (_animation) ? _animation.data()->duration() : 0; 0075 } 0076 0077 //* steps 0078 static void setSteps(int value) 0079 { 0080 _steps = value; 0081 } 0082 0083 //*@name opacity 0084 //@{ 0085 0086 qreal opacity(void) const 0087 { 0088 return _opacity; 0089 } 0090 0091 void setOpacity(qreal value) 0092 { 0093 value = digitize(value); 0094 if (_opacity == value) 0095 return; 0096 _opacity = value; 0097 update(); 0098 } 0099 0100 //@} 0101 0102 //@name pixmaps handling 0103 //@{ 0104 0105 //* start 0106 void resetStartPixmap(void) 0107 { 0108 setStartPixmap(QPixmap()); 0109 } 0110 0111 //* start 0112 void setStartPixmap(QPixmap pixmap) 0113 { 0114 _startPixmap = pixmap; 0115 } 0116 0117 //* start 0118 const QPixmap &startPixmap(void) const 0119 { 0120 return _startPixmap; 0121 } 0122 0123 //* end 0124 void resetEndPixmap(void) 0125 { 0126 setEndPixmap(QPixmap()); 0127 } 0128 0129 //* end 0130 void setEndPixmap(QPixmap pixmap) 0131 { 0132 _endPixmap = pixmap; 0133 _currentPixmap = pixmap; 0134 } 0135 0136 //* start 0137 const QPixmap &endPixmap(void) const 0138 { 0139 return _endPixmap; 0140 } 0141 0142 //* current 0143 const QPixmap ¤tPixmap(void) const 0144 { 0145 return _currentPixmap; 0146 } 0147 0148 //@} 0149 0150 //* grap pixmap 0151 QPixmap grab(QWidget * = nullptr, QRect = QRect()); 0152 0153 //* true if animated 0154 bool isAnimated(void) const 0155 { 0156 return _animation.data()->isRunning(); 0157 } 0158 0159 //* end animation 0160 void endAnimation(void) 0161 { 0162 if (_animation.data()->isRunning()) 0163 _animation.data()->stop(); 0164 } 0165 0166 //* animate transition 0167 void animate(void) 0168 { 0169 if (_animation.data()->isRunning()) 0170 _animation.data()->stop(); 0171 _animation.data()->start(); 0172 } 0173 0174 //* true if paint is enabled 0175 static bool paintEnabled(void); 0176 0177 protected: 0178 //* generic event filter 0179 bool event(QEvent *) override; 0180 0181 //* paint event 0182 void paintEvent(QPaintEvent *) override; 0183 0184 private: 0185 //* grab widget background 0186 /** 0187 Background is not rendered properly using QWidget::render. 0188 Use home-made grabber instead. This is directly inspired from bespin. 0189 SPDX-FileCopyrightText: 2007 Thomas Luebking <thomas.luebking@web.de> 0190 */ 0191 void grabBackground(QPixmap &, QWidget *, QRect &) const; 0192 0193 //* grab widget 0194 void grabWidget(QPixmap &, QWidget *, QRect &) const; 0195 0196 //* fade pixmap 0197 void fade(const QPixmap &source, QPixmap &target, qreal opacity, const QRect &) const; 0198 0199 //* apply step 0200 qreal digitize(const qreal &value) const 0201 { 0202 if (_steps > 0) 0203 return std::floor(value * _steps) / _steps; 0204 else 0205 return value; 0206 } 0207 0208 //* Flags 0209 Flags _flags = None; 0210 0211 //* paint enabled 0212 static bool _paintEnabled; 0213 0214 //* internal transition animation 0215 Animation::Pointer _animation; 0216 0217 //* animation starting pixmap 0218 QPixmap _startPixmap; 0219 0220 //* animation starting pixmap 0221 QPixmap _localStartPixmap; 0222 0223 //* animation starting pixmap 0224 QPixmap _endPixmap; 0225 0226 //* current pixmap 0227 QPixmap _currentPixmap; 0228 0229 //* current state opacity 0230 qreal _opacity = 0; 0231 0232 //* steps 0233 static int _steps; 0234 }; 0235 } 0236 0237 #endif