File indexing completed on 2024-05-19 05:35:19

0001 //////////////////////////////////////////////////////////////////////////////
0002 // oxygenanimations.cpp
0003 // container for all animation engines
0004 // -------------------
0005 //
0006 // SPDX-FileCopyrightText: 2006, 2007 Riccardo Iaconelli <riccardo@kde.org>
0007 // SPDX-FileCopyrightText: 2006, 2007 Casper Boemann <cbr@boemann.dk>
0008 // SPDX-FileCopyrightText: 2009 Hugo Pereira Da Costa <hugo.pereira@free.fr>
0009 //
0010 // SPDX-License-Identifier: MIT
0011 //////////////////////////////////////////////////////////////////////////////
0012 
0013 #include "oxygenanimations.h"
0014 #include "oxygenpropertynames.h"
0015 #include "oxygenstyleconfigdata.h"
0016 
0017 #include <QAbstractItemView>
0018 #include <QComboBox>
0019 #include <QDial>
0020 #include <QGroupBox>
0021 #include <QHeaderView>
0022 #include <QLineEdit>
0023 #include <QMainWindow>
0024 #include <QMdiSubWindow>
0025 #include <QProgressBar>
0026 #include <QScrollBar>
0027 #include <QSpinBox>
0028 #include <QSplitterHandle>
0029 #include <QTextEdit>
0030 #include <QToolBar>
0031 #include <QToolBox>
0032 #include <QToolButton>
0033 
0034 namespace Oxygen
0035 {
0036 //____________________________________________________________
0037 Animations::Animations(QObject *parent)
0038     : QObject(parent)
0039 {
0040     _widgetEnableStateEngine = new WidgetStateEngine(this);
0041     _spinBoxEngine = new SpinBoxEngine(this);
0042     _comboBoxEngine = new WidgetStateEngine(this);
0043     _toolButtonEngine = new WidgetStateEngine(this);
0044     _toolBoxEngine = new ToolBoxEngine(this);
0045     _busyIndicatorEngine = new BusyIndicatorEngine(this);
0046 
0047     registerEngine(_dockSeparatorEngine = new DockSeparatorEngine(this));
0048     registerEngine(_headerViewEngine = new HeaderViewEngine(this));
0049     registerEngine(_widgetStateEngine = new WidgetStateEngine(this));
0050     registerEngine(_progressBarEngine = new ProgressBarEngine(this));
0051     registerEngine(_menuBarEngine = new MenuBarEngineV1(this));
0052     registerEngine(_menuEngine = new MenuEngineV1(this));
0053     registerEngine(_scrollBarEngine = new ScrollBarEngine(this));
0054     registerEngine(_inputWidgetEngine = new WidgetStateEngine(this));
0055     registerEngine(_splitterEngine = new SplitterEngine(this));
0056     registerEngine(_tabBarEngine = new TabBarEngine(this));
0057     registerEngine(_toolBarEngine = new ToolBarEngine(this));
0058     registerEngine(_mdiWindowEngine = new MdiWindowEngine(this));
0059 }
0060 
0061 //____________________________________________________________
0062 void Animations::setupEngines(void)
0063 {
0064     // animation steps
0065     AnimationData::setSteps(StyleConfigData::animationSteps());
0066 
0067     {
0068         // default enability, duration and maxFrame
0069         bool animationsEnabled(StyleConfigData::animationsEnabled());
0070 
0071         // enability
0072         _widgetEnableStateEngine->setEnabled(animationsEnabled && StyleConfigData::genericAnimationsEnabled());
0073         _widgetStateEngine->setEnabled(animationsEnabled && StyleConfigData::genericAnimationsEnabled());
0074         _inputWidgetEngine->setEnabled(animationsEnabled && StyleConfigData::genericAnimationsEnabled());
0075         _comboBoxEngine->setEnabled(animationsEnabled && StyleConfigData::genericAnimationsEnabled());
0076         _toolButtonEngine->setEnabled(animationsEnabled && StyleConfigData::genericAnimationsEnabled());
0077         _toolBoxEngine->setEnabled(animationsEnabled && StyleConfigData::genericAnimationsEnabled());
0078         _splitterEngine->setEnabled(animationsEnabled && StyleConfigData::genericAnimationsEnabled());
0079         _scrollBarEngine->setEnabled(animationsEnabled && StyleConfigData::genericAnimationsEnabled());
0080         _spinBoxEngine->setEnabled(animationsEnabled && StyleConfigData::genericAnimationsEnabled());
0081         _tabBarEngine->setEnabled(animationsEnabled && StyleConfigData::genericAnimationsEnabled());
0082         _dockSeparatorEngine->setEnabled(animationsEnabled && StyleConfigData::genericAnimationsEnabled());
0083         _headerViewEngine->setEnabled(animationsEnabled && StyleConfigData::genericAnimationsEnabled());
0084         _mdiWindowEngine->setEnabled(animationsEnabled && StyleConfigData::genericAnimationsEnabled());
0085         _progressBarEngine->setEnabled(animationsEnabled && StyleConfigData::progressBarAnimationsEnabled());
0086 
0087         // busy indicator
0088         _busyIndicatorEngine->setEnabled(StyleConfigData::progressBarAnimated());
0089 
0090         // menubar engine
0091         int menuBarAnimationType(StyleConfigData::menuBarAnimationType());
0092         if (menuBarAnimationType == StyleConfigData::MB_FADE && !qobject_cast<MenuBarEngineV1 *>(_menuBarEngine)) {
0093             if (_menuBarEngine) {
0094                 MenuBarEngineV1 *newEngine = new MenuBarEngineV1(this, _menuBarEngine);
0095                 registerEngine(newEngine);
0096                 _menuBarEngine->deleteLater();
0097                 _menuBarEngine = newEngine;
0098 
0099             } else
0100                 registerEngine(_menuBarEngine = new MenuBarEngineV1(this));
0101 
0102         } else if (menuBarAnimationType == StyleConfigData::MB_FOLLOW_MOUSE && !qobject_cast<MenuBarEngineV2 *>(_menuBarEngine)) {
0103             if (_menuBarEngine) {
0104                 MenuBarEngineV2 *newEngine = new MenuBarEngineV2(this, _menuBarEngine);
0105                 registerEngine(newEngine);
0106                 _menuBarEngine->deleteLater();
0107                 _menuBarEngine = newEngine;
0108 
0109             } else
0110                 registerEngine(_menuBarEngine = new MenuBarEngineV1(this));
0111         }
0112 
0113         // menu engine
0114         int menuAnimationType(StyleConfigData::menuAnimationType());
0115         if (menuAnimationType == StyleConfigData::ME_FADE && !qobject_cast<MenuEngineV1 *>(_menuEngine)) {
0116             if (_menuEngine) {
0117                 MenuEngineV1 *newEngine = new MenuEngineV1(this, _menuEngine);
0118                 registerEngine(newEngine);
0119                 _menuEngine->deleteLater();
0120                 _menuEngine = newEngine;
0121 
0122             } else
0123                 registerEngine(_menuEngine = new MenuEngineV1(this));
0124 
0125         } else if (menuAnimationType == StyleConfigData::ME_FOLLOW_MOUSE && !qobject_cast<MenuEngineV2 *>(_menuEngine)) {
0126             if (_menuEngine) {
0127                 MenuEngineV2 *newEngine = new MenuEngineV2(this, _menuEngine);
0128                 registerEngine(newEngine);
0129                 _menuEngine->deleteLater();
0130                 _menuEngine = newEngine;
0131 
0132             } else
0133                 registerEngine(_menuEngine = new MenuEngineV1(this));
0134         }
0135 
0136         _menuBarEngine->setEnabled(animationsEnabled && menuBarAnimationType != StyleConfigData::MB_NONE);
0137         _menuEngine->setEnabled(animationsEnabled && menuAnimationType != StyleConfigData::ME_NONE);
0138 
0139         // toolbar engine
0140         int toolBarAnimationType(StyleConfigData::toolBarAnimationType());
0141         if (toolBarAnimationType == StyleConfigData::TB_NONE || toolBarAnimationType == StyleConfigData::TB_FOLLOW_MOUSE) {
0142             // disable toolbar engine
0143             _toolBarEngine->setEnabled(animationsEnabled && toolBarAnimationType == StyleConfigData::TB_FOLLOW_MOUSE);
0144 
0145             // unregister all toolbuttons that belong to a toolbar
0146             const auto widgets = _widgetStateEngine->registeredWidgets(AnimationHover | AnimationFocus);
0147             for (QWidget *widget : widgets) {
0148                 if (qobject_cast<QToolButton *>(widget) && qobject_cast<QToolBar *>(widget->parentWidget())) {
0149                     _widgetStateEngine->unregisterWidget(widget);
0150                 }
0151             }
0152 
0153         } else if (toolBarAnimationType == StyleConfigData::TB_FADE) {
0154             // disable toolbar engine
0155             _toolBarEngine->setEnabled(false);
0156 
0157             // retrieve all registered toolbars
0158             const BaseEngine::WidgetList widgets(_toolBarEngine->registeredWidgets());
0159             for (QWidget *widget : widgets) {
0160                 // get all toolbuttons
0161                 const auto children = widget->children();
0162                 for (QObject *child : children) {
0163                     if (QToolButton *toolButton = qobject_cast<QToolButton *>(child)) {
0164                         _widgetStateEngine->registerWidget(toolButton, AnimationHover);
0165                     }
0166                 }
0167             }
0168         }
0169     }
0170 
0171     {
0172         // durations
0173         _widgetEnableStateEngine->setDuration(StyleConfigData::genericAnimationsDuration());
0174         _widgetStateEngine->setDuration(StyleConfigData::genericAnimationsDuration());
0175         _inputWidgetEngine->setDuration(StyleConfigData::genericAnimationsDuration());
0176         _comboBoxEngine->setDuration(StyleConfigData::genericAnimationsDuration());
0177         _toolButtonEngine->setDuration(StyleConfigData::genericAnimationsDuration());
0178         _toolBoxEngine->setDuration(StyleConfigData::genericAnimationsDuration());
0179         _splitterEngine->setDuration(StyleConfigData::genericAnimationsDuration());
0180         _scrollBarEngine->setDuration(StyleConfigData::genericAnimationsDuration());
0181         _spinBoxEngine->setDuration(StyleConfigData::genericAnimationsDuration());
0182         _tabBarEngine->setDuration(StyleConfigData::genericAnimationsDuration());
0183         _dockSeparatorEngine->setDuration(StyleConfigData::genericAnimationsDuration());
0184         _headerViewEngine->setDuration(StyleConfigData::genericAnimationsDuration());
0185         _mdiWindowEngine->setDuration(StyleConfigData::genericAnimationsDuration());
0186 
0187         _progressBarEngine->setDuration(StyleConfigData::progressBarAnimationsDuration());
0188         _busyIndicatorEngine->setDuration(StyleConfigData::progressBarBusyStepDuration());
0189 
0190         _toolBarEngine->setDuration(StyleConfigData::genericAnimationsDuration());
0191         _toolBarEngine->setFollowMouseDuration(StyleConfigData::toolBarAnimationsDuration());
0192 
0193         _menuBarEngine->setDuration(StyleConfigData::menuBarAnimationsDuration());
0194         _menuBarEngine->setFollowMouseDuration(StyleConfigData::menuBarFollowMouseAnimationsDuration());
0195 
0196         _menuEngine->setDuration(StyleConfigData::menuAnimationsDuration());
0197         _menuEngine->setFollowMouseDuration(StyleConfigData::menuFollowMouseAnimationsDuration());
0198     }
0199 }
0200 
0201 //____________________________________________________________
0202 void Animations::registerWidget(QWidget *widget) const
0203 {
0204     if (!widget)
0205         return;
0206 
0207     // check against noAnimations propery
0208     QVariant propertyValue(widget->property(PropertyNames::noAnimations));
0209     if (propertyValue.isValid() && propertyValue.toBool())
0210         return;
0211 
0212     // these are needed to not register animations for kwin widgets
0213     if (widget->objectName() == QStringLiteral("decoration widget"))
0214         return;
0215     if (widget->inherits("KCommonDecorationButton"))
0216         return;
0217     if (widget->inherits("QShapedPixmapWidget"))
0218         return;
0219 
0220     // all widgets are registered to the enability engine.
0221     _widgetEnableStateEngine->registerWidget(widget, AnimationEnable);
0222 
0223     // install animation timers
0224     // for optimization, one should put with most used widgets here first
0225     if (qobject_cast<QToolButton *>(widget)) {
0226         _toolButtonEngine->registerWidget(widget, AnimationHover);
0227         bool isInToolBar(qobject_cast<QToolBar *>(widget->parent()));
0228         if (isInToolBar) {
0229             if (StyleConfigData::toolBarAnimationType() == StyleConfigData::TB_FADE) {
0230                 _widgetStateEngine->registerWidget(widget, AnimationHover);
0231             }
0232 
0233         } else
0234             _widgetStateEngine->registerWidget(widget, AnimationHover | AnimationFocus);
0235 
0236     } else if (qobject_cast<QAbstractButton *>(widget)) {
0237         if (qobject_cast<QToolBox *>(widget->parent())) {
0238             _toolBoxEngine->registerWidget(widget);
0239         }
0240 
0241         _widgetStateEngine->registerWidget(widget, AnimationHover | AnimationFocus);
0242 
0243     } else if (qobject_cast<QDial *>(widget)) {
0244         _widgetStateEngine->registerWidget(widget, AnimationHover | AnimationFocus);
0245 
0246     }
0247 
0248     // groupboxes
0249     else if (QGroupBox *groupBox = qobject_cast<QGroupBox *>(widget)) {
0250         if (groupBox->isCheckable()) {
0251             _widgetStateEngine->registerWidget(widget, AnimationHover | AnimationFocus);
0252         }
0253     }
0254 
0255     // scrollbar
0256     else if (qobject_cast<QScrollBar *>(widget)) {
0257         _scrollBarEngine->registerWidget(widget);
0258     } else if (qobject_cast<QSlider *>(widget)) {
0259         _widgetStateEngine->registerWidget(widget, AnimationHover | AnimationFocus);
0260     } else if (qobject_cast<QProgressBar *>(widget)) {
0261         _progressBarEngine->registerWidget(widget);
0262         _busyIndicatorEngine->registerWidget(widget);
0263     } else if (qobject_cast<QSplitterHandle *>(widget)) {
0264         _splitterEngine->registerWidget(widget);
0265     } else if (qobject_cast<QMainWindow *>(widget)) {
0266         _dockSeparatorEngine->registerWidget(widget);
0267     } else if (qobject_cast<QHeaderView *>(widget)) {
0268         _headerViewEngine->registerWidget(widget);
0269     }
0270 
0271     // menu
0272     else if (qobject_cast<QMenu *>(widget)) {
0273         _menuEngine->registerWidget(widget);
0274     } else if (qobject_cast<QMenuBar *>(widget)) {
0275         _menuBarEngine->registerWidget(widget);
0276     } else if (qobject_cast<QTabBar *>(widget)) {
0277         _tabBarEngine->registerWidget(widget);
0278     } else if (qobject_cast<QToolBar *>(widget)) {
0279         _toolBarEngine->registerWidget(widget);
0280     }
0281 
0282     // editors
0283     else if (qobject_cast<QComboBox *>(widget)) {
0284         _comboBoxEngine->registerWidget(widget, AnimationHover);
0285         _inputWidgetEngine->registerWidget(widget, AnimationHover | AnimationFocus);
0286     } else if (qobject_cast<QSpinBox *>(widget)) {
0287         _spinBoxEngine->registerWidget(widget);
0288         _inputWidgetEngine->registerWidget(widget, AnimationHover | AnimationFocus);
0289     } else if (qobject_cast<QLineEdit *>(widget)) {
0290         _inputWidgetEngine->registerWidget(widget, AnimationHover | AnimationFocus);
0291     } else if (qobject_cast<QTextEdit *>(widget)) {
0292         _inputWidgetEngine->registerWidget(widget, AnimationHover | AnimationFocus);
0293     } else if (widget->inherits("KTextEditor::View")) {
0294         _inputWidgetEngine->registerWidget(widget, AnimationHover | AnimationFocus);
0295     }
0296 
0297     // lists
0298     else if (qobject_cast<QAbstractItemView *>(widget)) {
0299         _inputWidgetEngine->registerWidget(widget, AnimationHover | AnimationFocus);
0300     }
0301 
0302     // scrollarea
0303     else if (QAbstractScrollArea *scrollArea = qobject_cast<QAbstractScrollArea *>(widget)) {
0304         if (scrollArea->frameShadow() == QFrame::Sunken && (widget->focusPolicy() & Qt::StrongFocus)) {
0305             _inputWidgetEngine->registerWidget(widget, AnimationHover | AnimationFocus);
0306         }
0307 
0308     }
0309 
0310     // mdi subwindows
0311     else if (qobject_cast<QMdiSubWindow *>(widget)) {
0312         _mdiWindowEngine->registerWidget(widget);
0313     }
0314 
0315     return;
0316 }
0317 
0318 //____________________________________________________________
0319 void Animations::unregisterWidget(QWidget *widget) const
0320 {
0321     if (!widget)
0322         return;
0323 
0324     /*
0325     these are the engines that have not been stored
0326     inside the list, because they can be register widgets in combination
0327     with other engines
0328     */
0329     _widgetEnableStateEngine->unregisterWidget(widget);
0330     _spinBoxEngine->unregisterWidget(widget);
0331     _comboBoxEngine->unregisterWidget(widget);
0332     _toolButtonEngine->unregisterWidget(widget);
0333     _toolBoxEngine->unregisterWidget(widget);
0334     _busyIndicatorEngine->unregisterWidget(widget);
0335 
0336     // the following allows some optimization of widget unregistration
0337     // it assumes that a widget can be registered atmost in one of the
0338     // engines stored in the list.
0339     for (const BaseEngine::Pointer &engine : std::as_const(_engines)) {
0340         if (engine && engine.data()->unregisterWidget(widget))
0341             break;
0342     }
0343 }
0344 
0345 //_______________________________________________________________
0346 void Animations::unregisterEngine(QObject *object)
0347 {
0348     int index(_engines.indexOf(qobject_cast<BaseEngine *>(object)));
0349     if (index >= 0)
0350         _engines.removeAt(index);
0351 }
0352 
0353 //_______________________________________________________________
0354 void Animations::registerEngine(BaseEngine *engine)
0355 {
0356     _engines.append(engine);
0357     connect(engine, SIGNAL(destroyed(QObject *)), this, SLOT(unregisterEngine(QObject *)));
0358 }
0359 }