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 }