File indexing completed on 2024-05-19 05:28:48
0001 /* 0002 * SPDX-FileCopyrightText: 2014 Hugo Pereira Da Costa <hugo.pereira@free.fr> 0003 * 0004 * SPDX-License-Identifier: GPL-2.0-or-later 0005 */ 0006 0007 #include "breezeanimations.h" 0008 #include "breezepropertynames.h" 0009 #include "breezestyleconfigdata.h" 0010 0011 #include <QAbstractItemView> 0012 #include <QCheckBox> 0013 #include <QComboBox> 0014 #include <QDial> 0015 #include <QGroupBox> 0016 #include <QHeaderView> 0017 #include <QLineEdit> 0018 #include <QProgressBar> 0019 #include <QRadioButton> 0020 #include <QScrollBar> 0021 #include <QSpinBox> 0022 #include <QTextEdit> 0023 #include <QToolBox> 0024 #include <QToolButton> 0025 0026 namespace Breeze 0027 { 0028 //____________________________________________________________ 0029 Animations::Animations(QObject *parent) 0030 : QObject(parent) 0031 { 0032 _widgetEnabilityEngine = new WidgetStateEngine(this); 0033 _busyIndicatorEngine = new BusyIndicatorEngine(this); 0034 _comboBoxEngine = new WidgetStateEngine(this); 0035 _toolButtonEngine = new WidgetStateEngine(this); 0036 _spinBoxEngine = new SpinBoxEngine(this); 0037 _toolBoxEngine = new ToolBoxEngine(this); 0038 0039 registerEngine(_headerViewEngine = new HeaderViewEngine(this)); 0040 registerEngine(_widgetStateEngine = new WidgetStateEngine(this)); 0041 registerEngine(_inputWidgetEngine = new WidgetStateEngine(this)); 0042 registerEngine(_scrollBarEngine = new ScrollBarEngine(this)); 0043 registerEngine(_stackedWidgetEngine = new StackedWidgetEngine(this)); 0044 registerEngine(_tabBarEngine = new TabBarEngine(this)); 0045 registerEngine(_dialEngine = new DialEngine(this)); 0046 } 0047 0048 //____________________________________________________________ 0049 void Animations::setupEngines() 0050 { 0051 // animation steps 0052 AnimationData::setSteps(StyleConfigData::animationSteps()); 0053 0054 const bool animationsEnabled(StyleConfigData::animationsEnabled()); 0055 const int animationsDuration(StyleConfigData::animationsDuration()); 0056 0057 _widgetEnabilityEngine->setEnabled(animationsEnabled); 0058 _comboBoxEngine->setEnabled(animationsEnabled); 0059 _toolButtonEngine->setEnabled(animationsEnabled); 0060 _spinBoxEngine->setEnabled(animationsEnabled); 0061 _toolBoxEngine->setEnabled(animationsEnabled); 0062 0063 _widgetEnabilityEngine->setDuration(animationsDuration); 0064 _comboBoxEngine->setDuration(animationsDuration); 0065 _toolButtonEngine->setDuration(animationsDuration); 0066 _spinBoxEngine->setDuration(animationsDuration); 0067 _stackedWidgetEngine->setDuration(animationsDuration); 0068 _toolBoxEngine->setDuration(animationsDuration); 0069 0070 // registered engines 0071 for (const BaseEngine::Pointer &engine : std::as_const(_engines)) { 0072 engine.data()->setEnabled(animationsEnabled); 0073 engine.data()->setDuration(animationsDuration); 0074 } 0075 0076 // stacked widget transition has an extra flag for animations 0077 _stackedWidgetEngine->setEnabled(animationsEnabled && StyleConfigData::stackedWidgetTransitionsEnabled()); 0078 0079 // busy indicator 0080 _busyIndicatorEngine->setEnabled(StyleConfigData::progressBarAnimated()); 0081 _busyIndicatorEngine->setDuration(StyleConfigData::progressBarBusyStepDuration()); 0082 } 0083 0084 //____________________________________________________________ 0085 void Animations::registerWidget(QWidget *widget) const 0086 { 0087 if (!widget) { 0088 return; 0089 } 0090 0091 // check against noAnimations property 0092 QVariant propertyValue(widget->property(PropertyNames::noAnimations)); 0093 if (propertyValue.isValid() && propertyValue.toBool()) { 0094 return; 0095 } 0096 0097 // all widgets are registered to the enability engine. 0098 _widgetEnabilityEngine->registerWidget(widget, AnimationEnable); 0099 0100 // install animation timers 0101 // for optimization, one should put with most used widgets here first 0102 0103 // buttons 0104 if (qobject_cast<QToolButton *>(widget)) { 0105 _toolButtonEngine->registerWidget(widget, AnimationHover | AnimationFocus); 0106 _widgetStateEngine->registerWidget(widget, AnimationHover | AnimationFocus); 0107 0108 } else if (qobject_cast<QCheckBox *>(widget) || qobject_cast<QRadioButton *>(widget)) { 0109 _widgetStateEngine->registerWidget(widget, AnimationHover | AnimationFocus | AnimationPressed); 0110 0111 } else if (qobject_cast<QAbstractButton *>(widget)) { 0112 // register to toolbox engine if needed 0113 if (qobject_cast<QToolBox *>(widget->parent())) { 0114 _toolBoxEngine->registerWidget(widget); 0115 } 0116 0117 _widgetStateEngine->registerWidget(widget, AnimationHover | AnimationFocus); 0118 0119 } 0120 0121 // groupboxes 0122 else if (QGroupBox *groupBox = qobject_cast<QGroupBox *>(widget)) { 0123 if (groupBox->isCheckable()) { 0124 _widgetStateEngine->registerWidget(widget, AnimationHover | AnimationFocus); 0125 } 0126 } 0127 0128 // sliders 0129 else if (qobject_cast<QScrollBar *>(widget)) { 0130 _scrollBarEngine->registerWidget(widget, AnimationHover | AnimationFocus); 0131 } else if (qobject_cast<QSlider *>(widget)) { 0132 _widgetStateEngine->registerWidget(widget, AnimationHover | AnimationFocus); 0133 } else if (qobject_cast<QDial *>(widget)) { 0134 _dialEngine->registerWidget(widget, AnimationHover | AnimationFocus); 0135 } 0136 0137 // progress bar 0138 else if (qobject_cast<QProgressBar *>(widget)) { 0139 _busyIndicatorEngine->registerWidget(widget); 0140 } 0141 0142 // combo box 0143 else if (qobject_cast<QComboBox *>(widget)) { 0144 _comboBoxEngine->registerWidget(widget, AnimationHover); 0145 _inputWidgetEngine->registerWidget(widget, AnimationHover | AnimationFocus); 0146 } 0147 0148 // spinbox 0149 else if (qobject_cast<QSpinBox *>(widget)) { 0150 _spinBoxEngine->registerWidget(widget); 0151 _inputWidgetEngine->registerWidget(widget, AnimationHover | AnimationFocus); 0152 } 0153 0154 // editors 0155 else if (qobject_cast<QLineEdit *>(widget)) { 0156 _inputWidgetEngine->registerWidget(widget, AnimationHover | AnimationFocus); 0157 } else if (qobject_cast<QTextEdit *>(widget)) { 0158 _inputWidgetEngine->registerWidget(widget, AnimationHover | AnimationFocus); 0159 } else if (widget->inherits("KTextEditor::View")) { 0160 _inputWidgetEngine->registerWidget(widget, AnimationHover | AnimationFocus); 0161 } 0162 0163 // header views 0164 // need to come before abstract item view, otherwise is skipped 0165 else if (qobject_cast<QHeaderView *>(widget)) { 0166 _headerViewEngine->registerWidget(widget); 0167 } 0168 0169 // lists 0170 else if (qobject_cast<QAbstractItemView *>(widget)) { 0171 _inputWidgetEngine->registerWidget(widget, AnimationHover | AnimationFocus); 0172 } 0173 0174 // tabbar 0175 else if (qobject_cast<QTabBar *>(widget)) { 0176 _tabBarEngine->registerWidget(widget); 0177 } 0178 0179 // scrollarea 0180 else if (QAbstractScrollArea *scrollArea = qobject_cast<QAbstractScrollArea *>(widget)) { 0181 if (scrollArea->frameShadow() == QFrame::Sunken && (widget->focusPolicy() & Qt::StrongFocus)) { 0182 _inputWidgetEngine->registerWidget(widget, AnimationHover | AnimationFocus); 0183 } 0184 } 0185 0186 // stacked widgets 0187 if (QStackedWidget *stack = qobject_cast<QStackedWidget *>(widget)) { 0188 _stackedWidgetEngine->registerWidget(stack); 0189 } 0190 } 0191 0192 //____________________________________________________________ 0193 void Animations::unregisterWidget(QWidget *widget) const 0194 { 0195 if (!widget) { 0196 return; 0197 } 0198 0199 _widgetEnabilityEngine->unregisterWidget(widget); 0200 _spinBoxEngine->unregisterWidget(widget); 0201 _comboBoxEngine->unregisterWidget(widget); 0202 _busyIndicatorEngine->unregisterWidget(widget); 0203 0204 // the following allows some optimization of widget unregistration 0205 // it assumes that a widget can be registered atmost in one of the 0206 // engines stored in the list. 0207 for (const BaseEngine::Pointer &engine : std::as_const(_engines)) { 0208 if (engine && engine.data()->unregisterWidget(widget)) { 0209 break; 0210 } 0211 } 0212 } 0213 0214 //_______________________________________________________________ 0215 void Animations::unregisterEngine(QObject *object) 0216 { 0217 int index(_engines.indexOf(qobject_cast<BaseEngine *>(object))); 0218 if (index >= 0) { 0219 _engines.removeAt(index); 0220 } 0221 } 0222 0223 //_______________________________________________________________ 0224 void Animations::registerEngine(BaseEngine *engine) 0225 { 0226 _engines.append(engine); 0227 connect(engine, &QObject::destroyed, this, &Animations::unregisterEngine); 0228 } 0229 0230 }