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 "config-breeze.h"
0008 
0009 #include "breezebusyindicatorengine.h"
0010 
0011 #include "breezemetrics.h"
0012 
0013 #if BREEZE_HAVE_QTQUICK
0014 #include <QQuickItem>
0015 #endif
0016 
0017 #include <QVariant>
0018 
0019 namespace Breeze
0020 {
0021 //_______________________________________________
0022 BusyIndicatorEngine::BusyIndicatorEngine(QObject *object)
0023     : BaseEngine(object)
0024 {
0025 }
0026 
0027 //_______________________________________________
0028 bool BusyIndicatorEngine::registerWidget(QObject *object)
0029 {
0030     // check widget validity
0031     if (!object) {
0032         return false;
0033     }
0034 
0035     // create new data class
0036     if (!_data.contains(object)) {
0037         _data.insert(object, new BusyIndicatorData(this));
0038 
0039         // connect destruction signal
0040         connect(object, &QObject::destroyed, this, &BusyIndicatorEngine::unregisterWidget, Qt::UniqueConnection);
0041 
0042 #if BREEZE_HAVE_QTQUICK
0043         if (QQuickItem *item = qobject_cast<QQuickItem *>(object)) {
0044             connect(item, &QQuickItem::visibleChanged, this, [this, item, object]() {
0045                 if (!item->isVisible()) {
0046                     this->setAnimated(object, false);
0047                 }
0048                 // no need for the else {} branch, as its animation will be reset anyway
0049             });
0050         }
0051 #endif
0052     }
0053 
0054     return true;
0055 }
0056 
0057 //____________________________________________________________
0058 bool BusyIndicatorEngine::isAnimated(const QObject *object)
0059 {
0060     DataMap<BusyIndicatorData>::Value data(BusyIndicatorEngine::data(object));
0061     return data && data.data()->isAnimated();
0062 }
0063 
0064 //____________________________________________________________
0065 void BusyIndicatorEngine::setDuration(int value)
0066 {
0067     if (duration() == value) {
0068         return;
0069     }
0070     BaseEngine::setDuration(value);
0071 
0072     // restart timer with specified time
0073     if (_animation) {
0074         _animation.data()->setDuration(value);
0075     }
0076 }
0077 
0078 //____________________________________________________________
0079 void BusyIndicatorEngine::setAnimated(const QObject *object, bool value)
0080 {
0081     DataMap<BusyIndicatorData>::Value data(BusyIndicatorEngine::data(object));
0082     if (data) {
0083         // update data
0084         data.data()->setAnimated(value);
0085 
0086         // start timer if needed
0087         if (value) {
0088             if (!_animation) {
0089                 // create animation if not already there
0090                 _animation = new Animation(duration(), this);
0091 
0092                 // setup
0093                 _animation.data()->setStartValue(0);
0094                 _animation.data()->setEndValue(2 * Metrics::ProgressBar_BusyIndicatorSize);
0095                 _animation.data()->setTargetObject(this);
0096                 _animation.data()->setPropertyName("value");
0097                 _animation.data()->setLoopCount(-1);
0098                 _animation.data()->setDuration(duration());
0099             }
0100 
0101             // start if  not already running
0102             if (!_animation.data()->isRunning()) {
0103                 _animation.data()->start();
0104             }
0105         }
0106     }
0107 }
0108 
0109 //____________________________________________________________
0110 DataMap<BusyIndicatorData>::Value BusyIndicatorEngine::data(const QObject *object)
0111 {
0112     return _data.find(object).data();
0113 }
0114 
0115 //_______________________________________________
0116 void BusyIndicatorEngine::setValue(int value)
0117 {
0118     // update
0119     _value = value;
0120 
0121     bool animated(false);
0122 
0123     // loop over objects in map
0124     for (DataMap<BusyIndicatorData>::iterator iter = _data.begin(); iter != _data.end(); ++iter) {
0125         if (iter.value().data()->isAnimated()) {
0126             // update animation flag
0127             animated = true;
0128 
0129 #if BREEZE_HAVE_QTQUICK
0130             const void *key = iter.key();
0131             QObject *obj = const_cast<QObject *>(static_cast<const QObject *>(key));
0132             if (QQuickItem *item = qobject_cast<QQuickItem *>(obj)) {
0133                 item->polish();
0134             }
0135 #endif
0136         }
0137     }
0138 
0139     if (_animation && !animated) {
0140         _animation.data()->stop();
0141         _animation.data()->deleteLater();
0142         _animation.clear();
0143     }
0144 }
0145 
0146 //__________________________________________________________
0147 bool BusyIndicatorEngine::unregisterWidget(QObject *object)
0148 {
0149     const bool removed(_data.unregisterWidget(object));
0150     if (_animation && _data.isEmpty()) {
0151         _animation.data()->stop();
0152         _animation.data()->deleteLater();
0153         _animation.clear();
0154     }
0155 
0156     return removed;
0157 }
0158 
0159 }