1 /*
2  * SPDX-FileCopyrightText: 2014 Hugo Pereira Da Costa <hugo.pereira@free.fr>
3  *
4  * SPDX-License-Identifier: GPL-2.0-or-later
5  */
6 
7 #include "breezebusyindicatorengine.h"
8 
9 #include "breezemetrics.h"
10 
11 #include <QVariant>
12 
13 namespace Breeze
14 {
15 
16     //_______________________________________________
BusyIndicatorEngine(QObject * object)17     BusyIndicatorEngine::BusyIndicatorEngine( QObject* object ):
18         BaseEngine( object )
19     {}
20 
21     //_______________________________________________
registerWidget(QObject * object)22     bool BusyIndicatorEngine::registerWidget( QObject* object )
23     {
24 
25         // check widget validity
26         if( !object ) return false;
27 
28          // create new data class
29         if( !_data.contains( object ) )
30         {
31             _data.insert( object, new BusyIndicatorData( this ) );
32 
33             // connect destruction signal
34             connect( object, SIGNAL(destroyed(QObject*)), this, SLOT(unregisterWidget(QObject*)), Qt::UniqueConnection );
35         }
36 
37         return true;
38 
39     }
40 
41     //____________________________________________________________
isAnimated(const QObject * object)42     bool BusyIndicatorEngine::isAnimated( const QObject* object )
43     {
44 
45         DataMap<BusyIndicatorData>::Value data( BusyIndicatorEngine::data( object ) );
46         return data && data.data()->isAnimated();
47 
48     }
49 
50     //____________________________________________________________
setDuration(int value)51     void BusyIndicatorEngine::setDuration( int value )
52     {
53 
54         if( duration() == value ) return;
55         BaseEngine::setDuration( value );
56 
57         // restart timer with specified time
58         if( _animation )
59         { _animation.data()->setDuration( value ); }
60 
61     }
62 
63     //____________________________________________________________
setAnimated(const QObject * object,bool value)64     void BusyIndicatorEngine::setAnimated( const QObject* object, bool value )
65     {
66 
67         DataMap<BusyIndicatorData>::Value data( BusyIndicatorEngine::data( object ) );
68         if( data )
69         {
70             // update data
71             data.data()->setAnimated( value );
72 
73             // start timer if needed
74             if( value )
75             {
76                 if( !_animation )
77                 {
78 
79                     // create animation if not already there
80                     _animation = new Animation( duration(), this );
81 
82                     // setup
83                     _animation.data()->setStartValue( 0 );
84                     _animation.data()->setEndValue( 2*Metrics::ProgressBar_BusyIndicatorSize );
85                     _animation.data()->setTargetObject( this );
86                     _animation.data()->setPropertyName( "value" );
87                     _animation.data()->setLoopCount( -1 );
88                     _animation.data()->setDuration( duration() );
89 
90                 }
91 
92                 // start if  not already running
93                 if( !_animation.data()->isRunning() )
94                 { _animation.data()->start(); }
95 
96             }
97 
98         }
99 
100 
101     }
102 
103 
104     //____________________________________________________________
data(const QObject * object)105     DataMap<BusyIndicatorData>::Value BusyIndicatorEngine::data( const QObject* object )
106     { return _data.find( object ).data(); }
107 
108     //_______________________________________________
setValue(int value)109     void BusyIndicatorEngine::setValue( int value )
110     {
111 
112         // update
113         _value = value;
114 
115         bool animated( false );
116 
117         // loop over objects in map
118         for( DataMap<BusyIndicatorData>::iterator iter = _data.begin(); iter != _data.end(); ++iter )
119         {
120 
121             if( iter.value().data()->isAnimated() )
122             {
123 
124                 // update animation flag
125                 animated = true;
126 
127                 // emit update signal on object
128                 if( const_cast<QObject*>( iter.key() )->inherits( "QQuickStyleItem" ))
129                 {
130 
131                     //QtQuickControls "rerender" method is updateItem
132                     QMetaObject::invokeMethod( const_cast<QObject*>( iter.key() ), "updateItem", Qt::QueuedConnection);
133 
134                 } else {
135 
136                     QMetaObject::invokeMethod( const_cast<QObject*>( iter.key() ), "update", Qt::QueuedConnection);
137 
138                 }
139 
140             }
141 
142         }
143 
144         if( _animation && !animated )
145         {
146             _animation.data()->stop();
147             _animation.data()->deleteLater();
148             _animation.clear();
149         }
150 
151     }
152 
153     //__________________________________________________________
unregisterWidget(QObject * object)154     bool BusyIndicatorEngine::unregisterWidget( QObject* object )
155     {
156         const bool removed( _data.unregisterWidget( object ) );
157         if( _animation && _data.isEmpty() )
158         {
159             _animation.data()->stop();
160             _animation.data()->deleteLater();
161             _animation.clear();
162         }
163 
164         return removed;
165     }
166 
167 }
168