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