File indexing completed on 2024-05-19 05:35:25
0001 ////////////////////////////////////////////////////////////////////////////// 0002 // oxygenlabeldata.cpp 0003 // data container for QLabel transition 0004 // ------------------- 0005 // 0006 // SPDX-FileCopyrightText: 2009 Hugo Pereira Da Costa <hugo.pereira@free.fr> 0007 // 0008 // SPDX-License-Identifier: MIT 0009 ////////////////////////////////////////////////////////////////////////////// 0010 0011 #include "oxygenlabeldata.h" 0012 0013 #include <QEvent> 0014 #include <QPainter> 0015 #include <QTextStream> 0016 0017 namespace Oxygen 0018 { 0019 // use 300 milliseconds for animation lock 0020 const int LabelData::_lockTime = 300; 0021 0022 //______________________________________________________ 0023 LabelData::LabelData(QObject *parent, QLabel *target, int duration) 0024 : TransitionData(parent, target, duration) 0025 , _target(target) 0026 { 0027 _target.data()->installEventFilter(this); 0028 0029 const bool hasProxy(_target.data()->graphicsProxyWidget()); 0030 const bool hasMessageWidget(hasParent(target, "KMessageWidget")); 0031 0032 transition().data()->setFlags(hasProxy || hasMessageWidget ? TransitionWidget::Transparent : TransitionWidget::GrabFromWindow); 0033 0034 connect(_target.data(), SIGNAL(destroyed()), SLOT(targetDestroyed())); 0035 } 0036 0037 //___________________________________________________________________ 0038 bool LabelData::eventFilter(QObject *object, QEvent *event) 0039 { 0040 if (object != _target.data()) 0041 return TransitionData::eventFilter(object, event); 0042 switch (event->type()) { 0043 case QEvent::Show: 0044 /* 0045 at show event, on set the old text to current 0046 to avoid animate the "first" paint event. 0047 text mnemonic is always removed to avoid triggering the animation when only the 0048 latter is changed 0049 */ 0050 _text = _target.data()->text().remove(QChar::fromLatin1('&')); 0051 break; 0052 0053 case QEvent::Paint: { 0054 if (enabled() && _target) { 0055 // remove showMnemonic from text before comparing 0056 QString text(_target.data()->text().remove(QChar::fromLatin1('&'))); 0057 if (text == _text) { 0058 if (transparent() && transition().data()->isAnimated() && TransitionWidget::paintEnabled()) 0059 return true; 0060 else 0061 break; 0062 } 0063 0064 // update text and pixmap 0065 _text = text; 0066 0067 if (!(transition() && _target.data()->isVisible())) 0068 break; 0069 0070 if (transition().data()->isAnimated()) { 0071 transition().data()->endAnimation(); 0072 } 0073 0074 // check whether animations are locked 0075 if (isLocked()) { 0076 // hide transition widget 0077 transition().data()->hide(); 0078 0079 // restart the lock timer 0080 // and abort transition 0081 lockAnimations(); 0082 break; 0083 } 0084 0085 // restart the lock timer 0086 // and prepare transition 0087 lockAnimations(); 0088 initializeAnimation(); 0089 _timer.start(0, this); 0090 0091 if (!transition().data()->startPixmap().isNull() && TransitionWidget::paintEnabled()) { 0092 // show the transition widget 0093 // and disable this event painting 0094 transition().data()->show(); 0095 transition().data()->raise(); 0096 if (transparent()) 0097 return true; 0098 else 0099 break; 0100 0101 } else { 0102 // hide transition widget and abort transition 0103 transition().data()->hide(); 0104 break; 0105 } 0106 0107 } else if (transition().data()->isAnimated() && TransitionWidget::paintEnabled()) { 0108 // disable painting when transition is running 0109 // since label is obscured by transition widget 0110 return true; 0111 0112 } else 0113 break; 0114 } 0115 0116 default: 0117 break; 0118 } 0119 0120 return TransitionData::eventFilter(object, event); 0121 } 0122 0123 //___________________________________________________________________ 0124 void LabelData::timerEvent(QTimerEvent *event) 0125 { 0126 if (event->timerId() == _timer.timerId()) { 0127 _timer.stop(); 0128 0129 // check transition and widget validity 0130 if (!(enabled() && _target && transition())) 0131 return; 0132 0133 // assign end pixmap 0134 transition().data()->setEndPixmap(transition().data()->grab(_target.data())); 0135 0136 // start animation 0137 animate(); 0138 0139 } else if (event->timerId() == _animationLockTimer.timerId()) { 0140 unlockAnimations(); 0141 0142 // check transition and widget validity 0143 if (!(enabled() && _target && transition())) 0144 return; 0145 0146 // reassign end pixmap for the next transition to be properly initialized 0147 transition().data()->setEndPixmap(transition().data()->grab(_target.data())); 0148 0149 } else 0150 return TransitionData::timerEvent(event); 0151 } 0152 0153 //___________________________________________________________________ 0154 bool LabelData::initializeAnimation(void) 0155 { 0156 transition().data()->setOpacity(0); 0157 QRect current(_target.data()->geometry()); 0158 if (_widgetRect.isValid() && _widgetRect != current) { 0159 _widgetRect = current; 0160 transition().data()->resetStartPixmap(); 0161 transition().data()->resetEndPixmap(); 0162 return false; 0163 } 0164 0165 transition().data()->setStartPixmap(transition().data()->currentPixmap()); 0166 transition().data()->setGeometry(_target.data()->rect()); 0167 _widgetRect = current; 0168 return true; 0169 } 0170 0171 //___________________________________________________________________ 0172 bool LabelData::animate(void) 0173 { 0174 if (transition().data()->startPixmap().isNull()) 0175 return false; 0176 0177 transition().data()->animate(); 0178 return true; 0179 } 0180 0181 //___________________________________________________________________ 0182 void LabelData::targetDestroyed(void) 0183 { 0184 setEnabled(false); 0185 _target.clear(); 0186 } 0187 }