1 /************************************************************************* 2 * Copyright (C) 2014 by Hugo Pereira Da Costa <hugo.pereira@free.fr> * 3 * * 4 * This program is free software; you can redistribute it and/or modify * 5 * it under the terms of the GNU General Public License as published by * 6 * the Free Software Foundation; either version 2 of the License, or * 7 * (at your option) any later version. * 8 * * 9 * This program is distributed in the hope that it will be useful, * 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of * 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * 12 * GNU General Public License for more details. * 13 * * 14 * You should have received a copy of the GNU General Public License * 15 * along with this program; if not, write to the * 16 * Free Software Foundation, Inc., * 17 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA . * 18 *************************************************************************/ 19 20 #include "adwaitabusyindicatorengine.h" 21 22 #include "adwaita.h" 23 24 #include <QVariant> 25 26 namespace Adwaita 27 { 28 29 //_______________________________________________ BusyIndicatorEngine(QObject * object)30 BusyIndicatorEngine::BusyIndicatorEngine( QObject* object ): 31 BaseEngine( object ) 32 {} 33 34 //_______________________________________________ registerWidget(QObject * object)35 bool BusyIndicatorEngine::registerWidget( QObject* object ) 36 { 37 38 // check widget validity 39 if( !object ) return false; 40 41 // create new data class 42 if( !_data.contains( object ) ) 43 { 44 _data.insert( object, new BusyIndicatorData( this ) ); 45 46 // connect destruction signal 47 connect( object, SIGNAL(destroyed(QObject*)), this, SLOT(unregisterWidget(QObject*)), Qt::UniqueConnection ); 48 } 49 50 return true; 51 52 } 53 54 //____________________________________________________________ isAnimated(const QObject * object)55 bool BusyIndicatorEngine::isAnimated( const QObject* object ) 56 { 57 58 DataMap<BusyIndicatorData>::Value data( BusyIndicatorEngine::data( object ) ); 59 return data && data.data()->isAnimated(); 60 61 } 62 63 //____________________________________________________________ setDuration(int value)64 void BusyIndicatorEngine::setDuration( int value ) 65 { 66 67 if( duration() == value ) return; 68 BaseEngine::setDuration( value ); 69 70 // restart timer with specified time 71 if( _animation ) 72 { _animation.data()->setDuration( value ); } 73 74 } 75 76 //____________________________________________________________ setAnimated(const QObject * object,bool value)77 void BusyIndicatorEngine::setAnimated( const QObject* object, bool value ) 78 { 79 80 DataMap<BusyIndicatorData>::Value data( BusyIndicatorEngine::data( object ) ); 81 if( data ) 82 { 83 // update data 84 data.data()->setAnimated( value ); 85 86 // start timer if needed 87 if( value ) 88 { 89 if( !_animation ) 90 { 91 92 // create animation if not already there 93 _animation = new Animation( duration(), this ); 94 95 // setup 96 _animation.data()->setStartValue( 0.0 ); 97 _animation.data()->setEndValue( 100.0 ); 98 _animation.data()->setTargetObject( this ); 99 _animation.data()->setPropertyName( "value" ); 100 _animation.data()->setLoopCount( -1 ); 101 _animation.data()->setDuration( duration() * 3); 102 103 } 104 105 // start if not already running 106 if( !_animation.data()->isRunning() ) 107 { _animation.data()->start(); } 108 109 } 110 111 } 112 113 return; 114 115 } 116 117 118 //____________________________________________________________ data(const QObject * object)119 DataMap<BusyIndicatorData>::Value BusyIndicatorEngine::data( const QObject* object ) 120 { return _data.find( object ).data(); } 121 122 //_______________________________________________ setValue(int value)123 void BusyIndicatorEngine::setValue( int value ) 124 { 125 126 // update 127 _value = value; 128 129 bool animated( false ); 130 131 // loop over objects in map 132 for( DataMap<BusyIndicatorData>::iterator iter = _data.begin(); iter != _data.end(); ++iter ) 133 { 134 135 if( iter.value().data()->isAnimated() ) 136 { 137 138 // update animation flag 139 animated = true; 140 141 // emit update signal on object 142 if( const_cast<QObject*>( iter.key() )->inherits( "QQuickStyleItem" )) 143 { 144 145 //QtQuickControls "rerender" method is updateItem 146 QMetaObject::invokeMethod( const_cast<QObject*>( iter.key() ), "updateItem", Qt::QueuedConnection); 147 148 } else { 149 150 QMetaObject::invokeMethod( const_cast<QObject*>( iter.key() ), "update", Qt::QueuedConnection); 151 152 } 153 154 } 155 156 } 157 158 if( _animation && !animated ) 159 { 160 _animation.data()->stop(); 161 _animation.data()->deleteLater(); 162 _animation.clear(); 163 } 164 165 } 166 167 //__________________________________________________________ unregisterWidget(QObject * object)168 bool BusyIndicatorEngine::unregisterWidget( QObject* object ) 169 { 170 bool removed( _data.unregisterWidget( object ) ); 171 if( _animation && _data.isEmpty() ) 172 { 173 _animation.data()->stop(); 174 _animation.data()->deleteLater(); 175 _animation.clear(); 176 } 177 178 return removed; 179 } 180 181 } 182