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 }