[AT-SPI] Rename AccessibleImpl to <Control>Accessible
[platform/core/uifw/dali-toolkit.git] / dali-toolkit / internal / controls / progress-bar / progress-bar-impl.cpp
1 /*
2  * Copyright (c) 2021 Samsung Electronics Co., Ltd.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  *
16  */
17
18 // CLASS HEADER
19 #include <dali-toolkit/internal/controls/progress-bar/progress-bar-impl.h>
20
21 // EXTERNAL INCLUDES
22 #include <dali-toolkit/devel-api/controls/control-devel.h>
23 #include <dali-toolkit/devel-api/visual-factory/visual-base.h>
24 #include <dali-toolkit/devel-api/visual-factory/visual-factory.h>
25 #include <dali-toolkit/devel-api/visuals/arc-visual-properties-devel.h>
26 #include <dali-toolkit/internal/controls/control/control-data-impl.h>
27 #include <dali-toolkit/internal/visuals/visual-base-impl.h>
28 #include <dali-toolkit/internal/visuals/visual-string-constants.h>
29 #include <dali-toolkit/public-api/align-enumerations.h>
30 #include <dali-toolkit/public-api/visuals/color-visual-properties.h>
31 #include <dali-toolkit/public-api/visuals/image-visual-properties.h>
32 #include <dali-toolkit/public-api/visuals/text-visual-properties.h>
33 #include <dali-toolkit/public-api/visuals/visual-properties.h>
34 #include <dali/public-api/math/math-utils.h>
35 #include <dali/public-api/object/type-registry-helper.h>
36 #include <dali/public-api/size-negotiation/relayout-container.h>
37 #include <algorithm>
38 #include <cstring> // for strcmp
39 #include <sstream>
40
41 #include <dali/integration-api/debug.h>
42
43 namespace Dali
44 {
45 namespace Toolkit
46 {
47 namespace Internal
48 {
49 namespace // Unnamed namespace
50 {
51 BaseHandle Create()
52 {
53   return Dali::Toolkit::ProgressBar::New();
54 }
55
56 // clang-format off
57 // Setup properties, signals and actions using the type-registry.
58 DALI_TYPE_REGISTRATION_BEGIN(Toolkit::ProgressBar, Toolkit::Control, Create)
59
60 DALI_PROPERTY_REGISTRATION(Toolkit, ProgressBar, "progressValue",                FLOAT,   PROGRESS_VALUE                )
61 DALI_PROPERTY_REGISTRATION(Toolkit, ProgressBar, "secondaryProgressValue",       FLOAT,   SECONDARY_PROGRESS_VALUE      )
62 DALI_PROPERTY_REGISTRATION(Toolkit, ProgressBar, "indeterminate",                BOOLEAN, INDETERMINATE                 )
63 DALI_PROPERTY_REGISTRATION(Toolkit, ProgressBar, "trackVisual",                  MAP,     TRACK_VISUAL                  )
64 DALI_PROPERTY_REGISTRATION(Toolkit, ProgressBar, "progressVisual",               MAP,     PROGRESS_VISUAL               )
65 DALI_PROPERTY_REGISTRATION(Toolkit, ProgressBar, "secondaryProgressVisual",      MAP,     SECONDARY_PROGRESS_VISUAL     )
66 DALI_PROPERTY_REGISTRATION(Toolkit, ProgressBar, "indeterminateVisual",          MAP,     INDETERMINATE_VISUAL          )
67 DALI_PROPERTY_REGISTRATION(Toolkit, ProgressBar, "indeterminateVisualAnimation", ARRAY,   INDETERMINATE_VISUAL_ANIMATION)
68 DALI_PROPERTY_REGISTRATION(Toolkit, ProgressBar, "labelVisual",                  MAP,     LABEL_VISUAL                  )
69
70 DALI_SIGNAL_REGISTRATION(Toolkit, ProgressBar, "valueChanged", SIGNAL_VALUE_CHANGED)
71
72 DALI_TYPE_REGISTRATION_END()
73 // clang-format on
74
75 struct ProgressDepthIndex
76 {
77   // Enum to make sure the visual order
78   enum
79   {
80     TRACK_VISUAL,
81     SECONDARY_PROGRESS_VISUAL,
82     PROGRESS_VISUAL,
83     LABEL_VISUAL,
84     INDETERMINATE_VISUAL
85   };
86 };
87
88 float       DEFAULT_VALUE                    = 0.0f;
89 float       DEFAULT_LOWER_BOUND              = 0.0f;
90 float       DEFAULT_UPPER_BOUND              = 1.0f;
91 float       DEFAULT_FONT_SIZE                = 12.0f;
92 const char* CIRCULAR_PROGRESS_BAR_STYLE_NAME = "CircularProgressBar";
93
94 void BackupVisualProperties(const Control* control, Property::Index index, Property::Map& map)
95 {
96   Toolkit::Visual::Base visual = DevelControl::GetVisual(*control, index);
97
98   if(visual)
99   {
100     map.Clear();
101     visual.CreatePropertyMap(map);
102   }
103 }
104
105 void RestoreVisualProperties(Control* control, Property::Index index, Property::Map& map, int depth)
106 {
107   if(!map.Empty())
108   {
109     Toolkit::Visual::Base visual = DevelControl::GetVisual(*control, index);
110
111     Visual::Base& visualImpl = Toolkit::GetImplementation(visual);
112
113     visualImpl.SetProperties(map);
114
115     DevelControl::UnregisterVisual(*control, index);
116
117     DevelControl::RegisterVisual(*control, index, visual, true, depth);
118   }
119 }
120
121 } // Unnamed namespace
122
123 ///////////////////////////////////////////////////////////////////////////////////////////////////
124 // ProgressBar
125 ///////////////////////////////////////////////////////////////////////////////////////////////////
126
127 Dali::Toolkit::ProgressBar ProgressBar::New(DevelProgressBar::Style progressBarStyle)
128 {
129   // Create the implementation
130   ProgressBarPtr progressBar(new ProgressBar());
131
132   Dali::Toolkit::ProgressBar handle(*progressBar);
133
134   switch(progressBarStyle)
135   {
136     case DevelProgressBar::Style::CIRCULAR:
137     {
138       progressBar->SetStyleName(CIRCULAR_PROGRESS_BAR_STYLE_NAME);
139       break;
140     }
141     default:
142     {
143       break;
144     }
145   }
146
147   // Second-phase init of the implementation
148   // This can only be done after the CustomActor connection has been made...
149   progressBar->Initialize();
150
151   return handle;
152 }
153
154 ProgressBar::ProgressBar()
155 : Control(ControlBehaviour(CONTROL_BEHAVIOUR_DEFAULT)),
156   mProgressValue(DEFAULT_VALUE),
157   mSecondaryProgressValue(DEFAULT_VALUE),
158   mIndeterminate(false)
159 {
160 }
161
162 ProgressBar::~ProgressBar()
163 {
164 }
165
166 void ProgressBar::OnInitialize()
167 {
168   DevelControl::SetAccessibilityConstructor(Self(), [](Dali::Actor actor) {
169     return std::make_unique<ProgressBarAccessible>(actor, Dali::Accessibility::Role::PROGRESS_BAR);
170   });
171   //Enable highightability
172   Self().SetProperty(Toolkit::DevelControl::Property::ACCESSIBILITY_HIGHLIGHTABLE, true);
173 }
174
175 void ProgressBar::OnRelayout(const Vector2& size, RelayoutContainer& container)
176 {
177   Vector2 trackSize(size);
178   mDomain = CalcDomain(size);
179
180   trackSize.width = std::max(0.0f, size.width); // Ensure we don't go negative
181
182   Toolkit::Visual::Base trackVisual         = DevelControl::GetVisual(*this, Toolkit::ProgressBar::Property::TRACK_VISUAL);
183   Toolkit::Visual::Base labelVisual         = DevelControl::GetVisual(*this, Toolkit::ProgressBar::Property::LABEL_VISUAL);
184   Toolkit::Visual::Base indeterminateVisual = DevelControl::GetVisual(*this, Toolkit::ProgressBar::Property::INDETERMINATE_VISUAL);
185
186   if(trackVisual)
187   {
188     Property::Map visualTransform;
189
190     visualTransform.Add(Toolkit::Visual::Transform::Property::SIZE, trackSize)
191       .Add(Toolkit::Visual::Transform::Property::OFFSET_POLICY, Vector2(Toolkit::Visual::Transform::Policy::ABSOLUTE, Toolkit::Visual::Transform::Policy::ABSOLUTE))
192       .Add(Toolkit::Visual::Transform::Property::SIZE_POLICY, Vector2(Toolkit::Visual::Transform::Policy::ABSOLUTE, Toolkit::Visual::Transform::Policy::ABSOLUTE));
193
194     trackVisual.SetTransformAndSize(visualTransform, trackSize);
195   }
196
197   ApplyProgressToVisualTransform(mSecondaryProgressValue, trackSize, Toolkit::ProgressBar::Property::SECONDARY_PROGRESS_VISUAL);
198
199   ApplyProgressToVisualTransform(mProgressValue, trackSize, Toolkit::ProgressBar::Property::PROGRESS_VISUAL);
200
201   if(labelVisual)
202   {
203     Property::Map visualTransform;
204
205     visualTransform.Add(Toolkit::Visual::Transform::Property::SIZE, trackSize)
206       .Add(Toolkit::Visual::Transform::Property::OFFSET_POLICY, Vector2(Toolkit::Visual::Transform::Policy::ABSOLUTE, Toolkit::Visual::Transform::Policy::ABSOLUTE))
207       .Add(Toolkit::Visual::Transform::Property::SIZE_POLICY, Vector2(Toolkit::Visual::Transform::Policy::ABSOLUTE, Toolkit::Visual::Transform::Policy::ABSOLUTE));
208     labelVisual.SetTransformAndSize(visualTransform, trackSize);
209   }
210
211   if(indeterminateVisual)
212   {
213     Property::Map visualTransform;
214
215     visualTransform.Add(Toolkit::Visual::Transform::Property::SIZE, trackSize)
216       .Add(Toolkit::Visual::Transform::Property::OFFSET_POLICY, Vector2(Toolkit::Visual::Transform::Policy::ABSOLUTE, Toolkit::Visual::Transform::Policy::ABSOLUTE))
217       .Add(Toolkit::Visual::Transform::Property::SIZE_POLICY, Vector2(Toolkit::Visual::Transform::Policy::ABSOLUTE, Toolkit::Visual::Transform::Policy::ABSOLUTE));
218     indeterminateVisual.SetTransformAndSize(visualTransform, trackSize);
219   }
220 }
221
222 Vector3 ProgressBar::GetNaturalSize()
223 {
224   // Return the bigger size after comparing trackVisual naturalSize and labelVisual naturalSize
225   Toolkit::Visual::Base trackVisual = DevelControl::GetVisual(*this, Toolkit::ProgressBar::Property::TRACK_VISUAL);
226   Toolkit::Visual::Base labelVisual = DevelControl::GetVisual(*this, Toolkit::ProgressBar::Property::LABEL_VISUAL);
227
228   Size trackSize;
229   Size labelSize;
230
231   if(trackVisual)
232   {
233     trackVisual.GetNaturalSize(trackSize);
234   }
235   if(labelVisual)
236   {
237     labelVisual.GetNaturalSize(labelSize);
238   }
239
240   Vector3 naturalSize;
241   naturalSize.width  = (trackSize.width > labelSize.width) ? trackSize.width : labelSize.width;
242   naturalSize.height = (trackSize.height > labelSize.height) ? trackSize.height : labelSize.height;
243
244   return naturalSize;
245 }
246
247 ProgressBar::Domain ProgressBar::CalcDomain(const Vector2& currentSize)
248 {
249   return Domain(Vector2(0.0f, 0.0f), currentSize);
250 }
251
252 Toolkit::ProgressBar::ValueChangedSignalType& ProgressBar::ValueChangedSignal()
253 {
254   return mValueChangedSignal;
255 }
256
257 void ProgressBar::SetProgressValue(float value)
258 {
259   // update the progress bar value (taking float precision errors into account)
260   // TODO : it seems 0.0f cannot into this statement.
261   if((mProgressValue != value) &&
262      ((value >= DEFAULT_LOWER_BOUND) || (Equals(value, DEFAULT_LOWER_BOUND))) &&
263      ((value <= DEFAULT_UPPER_BOUND) || (Equals(value, DEFAULT_UPPER_BOUND))))
264   {
265     mProgressValue = Clamp(value, DEFAULT_LOWER_BOUND, DEFAULT_UPPER_BOUND);
266
267     ApplyProgressToVisual(mProgressValue, Toolkit::ProgressBar::Property::PROGRESS_VISUAL, ProgressDepthIndex::PROGRESS_VISUAL);
268
269     Toolkit::ProgressBar self = Toolkit::ProgressBar::DownCast(Self());
270     mValueChangedSignal.Emit(self, mProgressValue, mSecondaryProgressValue);
271     if(Self() == Dali::Accessibility::Accessible::GetCurrentlyHighlightedActor())
272     {
273       Control::Impl::GetAccessibilityObject(Self())->Emit(Dali::Accessibility::ObjectPropertyChangeEvent::VALUE);
274     }
275     RelayoutRequest();
276   }
277 }
278
279 float ProgressBar::GetProgressValue() const
280 {
281   return mProgressValue;
282 }
283
284 void ProgressBar::SetSecondaryProgressValue(float value)
285 {
286   // update the progress bar value (taking float precision errors into account)
287   // TODO : it seems 0.0f cannot into this statement.
288   if((mSecondaryProgressValue != value) &&
289      ((value >= DEFAULT_LOWER_BOUND) || (Equals(value, DEFAULT_LOWER_BOUND))) &&
290      ((value <= DEFAULT_UPPER_BOUND) || (Equals(value, DEFAULT_UPPER_BOUND))))
291   {
292     mSecondaryProgressValue = Clamp(value, DEFAULT_LOWER_BOUND, DEFAULT_UPPER_BOUND);
293
294     ApplyProgressToVisual(mSecondaryProgressValue, Toolkit::ProgressBar::Property::SECONDARY_PROGRESS_VISUAL, ProgressDepthIndex::SECONDARY_PROGRESS_VISUAL);
295
296     Toolkit::ProgressBar self = Toolkit::ProgressBar::DownCast(Self());
297     mValueChangedSignal.Emit(self, mProgressValue, mSecondaryProgressValue);
298
299     RelayoutRequest();
300   }
301 }
302
303 float ProgressBar::GetSecondaryProgressValue() const
304 {
305   return mSecondaryProgressValue;
306 }
307
308 void ProgressBar::SetIndeterminate(bool value)
309 {
310   mIndeterminate = value;
311   DevelControl::EnableVisual(*this, Toolkit::ProgressBar::Property::INDETERMINATE_VISUAL, mIndeterminate);
312
313   if(mIndeterminate)
314   {
315     RelayoutRequest();
316     if(mIndeterminateVisualTransition)
317     {
318       PlayIndeterminateVisualTransition();
319     }
320   }
321   else
322   {
323     if(mIndeterminateVisualAni)
324     {
325       mIndeterminateVisualAni.Stop();
326     }
327
328     // Restore previous visual data after animation finished.
329     RestoreVisualProperties(this, Toolkit::ProgressBar::Property::TRACK_VISUAL, mTrackVisualMap, ProgressDepthIndex::TRACK_VISUAL);
330     RestoreVisualProperties(this, Toolkit::ProgressBar::Property::SECONDARY_PROGRESS_VISUAL, mSecondaryProgressVisualMap, ProgressDepthIndex::SECONDARY_PROGRESS_VISUAL);
331     RestoreVisualProperties(this, Toolkit::ProgressBar::Property::PROGRESS_VISUAL, mProgressVisualMap, ProgressDepthIndex::PROGRESS_VISUAL);
332
333     RelayoutRequest();
334   }
335 }
336
337 bool ProgressBar::GetIndeterminate() const
338 {
339   return mIndeterminate;
340 }
341
342 void ProgressBar::SetIndeterminateVisualTransition(Toolkit::TransitionData transition)
343 {
344   mIndeterminateVisualTransition = transition;
345   if(mIndeterminate)
346   {
347     PlayIndeterminateVisualTransition();
348   }
349 }
350
351 void ProgressBar::PlayIndeterminateVisualTransition()
352 {
353   // Store current visual data before animation changes it.
354   BackupVisualProperties(this, Toolkit::ProgressBar::Property::TRACK_VISUAL, mTrackVisualMap);
355   BackupVisualProperties(this, Toolkit::ProgressBar::Property::SECONDARY_PROGRESS_VISUAL, mSecondaryProgressVisualMap);
356   BackupVisualProperties(this, Toolkit::ProgressBar::Property::PROGRESS_VISUAL, mProgressVisualMap);
357
358   if(mIndeterminateVisualAni)
359   {
360     mIndeterminateVisualAni.Stop();
361     mIndeterminateVisualAni.Clear();
362   }
363
364   mIndeterminateVisualAni = DevelControl::CreateTransition(*this, mIndeterminateVisualTransition);
365
366   if(mIndeterminate && mIndeterminateVisualAni)
367   {
368     mIndeterminateVisualAni.SetLooping(true);
369     mIndeterminateVisualAni.Play();
370   }
371 }
372
373 Toolkit::TransitionData ProgressBar::ConvertPropertyToTransition(const Property::Value& value)
374 {
375   Toolkit::TransitionData transitionData;
376
377   if(value.GetType() == Property::ARRAY)
378   {
379     transitionData = Toolkit::TransitionData::New(*value.GetArray());
380   }
381   else if(value.GetType() == Property::MAP)
382   {
383     transitionData = Toolkit::TransitionData::New(*value.GetMap());
384   }
385
386   return transitionData;
387 }
388
389 /**
390  * Create Visual for given index from a property map or url.
391  * 1) Check if value passed in is a url and create visual
392  * 2) Create visual from map if step (1) is false
393  * 3) Register visual with control with false for enable flag.
394  * 4) Unregister visual if empty map was provided. This is the method to remove a visual
395  */
396
397 void ProgressBar::CreateVisualsForComponent(Property::Index index, const Property::Value& value, const int visualDepth)
398 {
399   Toolkit::VisualFactory visualFactory = Toolkit::VisualFactory::Get();
400   Toolkit::Visual::Base  progressVisual;
401
402   std::string imageUrl;
403   if(value.Get(imageUrl))
404   {
405     if(!imageUrl.empty())
406     {
407       progressVisual = visualFactory.CreateVisual(imageUrl, ImageDimensions());
408     }
409   }
410   else // Does this code make text-visual can be accepted as visual?
411   {
412     // if its not a string then get a Property::Map from the property if possible.
413     const Property::Map* map = value.GetMap();
414     if(map && !map->Empty()) // Empty map results in current visual removal.
415     {
416       progressVisual = visualFactory.CreateVisual(*map);
417     }
418   }
419
420   if(progressVisual)
421   {
422     if(index == Toolkit::ProgressBar::Property::INDETERMINATE_VISUAL)
423     {
424       DevelControl::RegisterVisual(*this, index, progressVisual, mIndeterminate, visualDepth);
425     }
426     else
427     {
428       DevelControl::RegisterVisual(*this, index, progressVisual, true, visualDepth);
429     }
430   }
431   else
432   {
433     DevelControl::UnregisterVisual(*this, index);
434   }
435 }
436
437 bool ProgressBar::GetPropertyMapForVisual(Property::Index visualIndex, Property::Map& retreivedMap) const
438 {
439   bool                  success = false;
440   Toolkit::Visual::Base visual  = DevelControl::GetVisual(*this, visualIndex);
441
442   if(visual)
443   {
444     visual.CreatePropertyMap(retreivedMap);
445     success = true;
446   }
447
448   return success;
449 }
450
451 void ProgressBar::ApplyProgressToVisual(float progress, Property::Index index, int depth)
452 {
453   Toolkit::Visual::Base visual = DevelControl::GetVisual(*this, index);
454
455   if(visual && static_cast<DevelVisual::Type>(visual.GetType()) == DevelVisual::ARC && !mIndeterminate)
456   {
457     Visual::Base& visualImpl = Toolkit::GetImplementation(visual);
458
459     Property::Map map;
460
461     map[Toolkit::DevelArcVisual::Property::SWEEP_ANGLE] = Property::Value(360.0f * progress);
462
463     visualImpl.SetProperties(map);
464
465     DevelControl::UnregisterVisual(*this, index);
466     DevelControl::RegisterVisual(*this, index, visual, true, depth);
467   }
468 }
469
470 void ProgressBar::ApplyProgressToVisualTransform(float progress, Vector2 trackSize, Property::Index index)
471 {
472   Toolkit::Visual::Base visual = DevelControl::GetVisual(*this, index);
473
474   if(visual)
475   {
476     Property::Map visualTransform;
477
478     if(static_cast<DevelVisual::Type>(visual.GetType()) != DevelVisual::ARC)
479     {
480       visualTransform.Add(Toolkit::Visual::Transform::Property::SIZE, Vector2(mDomain.from.x + progress * (mDomain.to.x - mDomain.from.x), trackSize.height))
481         .Add(Toolkit::Visual::Transform::Property::OFFSET_POLICY, Vector2(Toolkit::Visual::Transform::Policy::ABSOLUTE, Toolkit::Visual::Transform::Policy::ABSOLUTE))
482         .Add(Toolkit::Visual::Transform::Property::SIZE_POLICY, Vector2(Toolkit::Visual::Transform::Policy::ABSOLUTE, Toolkit::Visual::Transform::Policy::ABSOLUTE))
483         .Add(Toolkit::Visual::Transform::Property::ORIGIN, Toolkit::Align::TOP_BEGIN)
484         .Add(Toolkit::Visual::Transform::Property::ANCHOR_POINT, Toolkit::Align::TOP_BEGIN);
485     }
486
487     visual.SetTransformAndSize(visualTransform, trackSize);
488   }
489 }
490
491 // Static class method to support script connecting signals
492 bool ProgressBar::DoConnectSignal(BaseObject* object, ConnectionTrackerInterface* tracker, const std::string& signalName, FunctorDelegate* functor)
493 {
494   Dali::BaseHandle handle(object);
495
496   bool                 connected   = true;
497   Toolkit::ProgressBar ProgressBar = Toolkit::ProgressBar::DownCast(handle);
498
499   if(0 == strcmp(signalName.c_str(), SIGNAL_VALUE_CHANGED))
500   {
501     ProgressBar.ValueChangedSignal().Connect(tracker, functor);
502   }
503   else
504   {
505     // signalName does not match any signal
506     connected = false;
507   }
508
509   return connected;
510 }
511
512 void ProgressBar::SetProperty(BaseObject* object, Property::Index propertyIndex, const Property::Value& value)
513 {
514   Toolkit::ProgressBar progressBar = Toolkit::ProgressBar::DownCast(Dali::BaseHandle(object));
515
516   if(progressBar)
517   {
518     ProgressBar& progressBarImpl(GetImpl(progressBar));
519
520     switch(propertyIndex)
521     {
522       case Toolkit::ProgressBar::Property::TRACK_VISUAL:
523       {
524         progressBarImpl.CreateVisualsForComponent(propertyIndex, value, ProgressDepthIndex::TRACK_VISUAL);
525         break;
526       }
527
528       case Toolkit::ProgressBar::Property::SECONDARY_PROGRESS_VISUAL:
529       {
530         progressBarImpl.CreateVisualsForComponent(propertyIndex, value, ProgressDepthIndex::SECONDARY_PROGRESS_VISUAL);
531         progressBarImpl.ApplyProgressToVisual(progressBarImpl.mSecondaryProgressValue, propertyIndex, ProgressDepthIndex::SECONDARY_PROGRESS_VISUAL);
532         break;
533       }
534
535       case Toolkit::ProgressBar::Property::PROGRESS_VISUAL:
536       {
537         progressBarImpl.CreateVisualsForComponent(propertyIndex, value, ProgressDepthIndex::PROGRESS_VISUAL);
538         progressBarImpl.ApplyProgressToVisual(progressBarImpl.mProgressValue, propertyIndex, ProgressDepthIndex::PROGRESS_VISUAL);
539         break;
540       }
541
542       case Toolkit::ProgressBar::Property::INDETERMINATE_VISUAL:
543       {
544         progressBarImpl.CreateVisualsForComponent(propertyIndex, value, ProgressDepthIndex::INDETERMINATE_VISUAL);
545         break;
546       }
547
548       case Toolkit::ProgressBar::Property::LABEL_VISUAL:
549       {
550         Property::Map map;
551         std::string   textString;
552
553         if(value.Get(textString))
554         {
555           // set new text string as TEXT property
556           Property::Map         newTextMap;
557           Toolkit::Visual::Base label = DevelControl::GetVisual(progressBarImpl, Toolkit::ProgressBar::Property::LABEL_VISUAL);
558
559           if(label)
560           {
561             label.CreatePropertyMap(map);
562           }
563
564           // if LABEL_VISUAL doesn't set before, add Visual property "TYPE" to create new text Visual
565           if(map.Empty())
566           {
567             newTextMap.Add(Toolkit::Visual::Property::TYPE, Toolkit::Visual::TEXT);
568             newTextMap.Add(Toolkit::TextVisual::Property::POINT_SIZE, DEFAULT_FONT_SIZE);
569           }
570           newTextMap.Add(Toolkit::TextVisual::Property::TEXT, textString);
571
572           map.Merge(newTextMap);
573         }
574         else
575         {
576           value.Get(map);
577         }
578
579         if(!map.Empty())
580         {
581           progressBarImpl.CreateVisualsForComponent(propertyIndex, map, ProgressDepthIndex::LABEL_VISUAL);
582         }
583         break;
584       }
585
586       case Toolkit::ProgressBar::Property::PROGRESS_VALUE:
587       {
588         progressBarImpl.SetProgressValue(value.Get<float>());
589         break;
590       }
591
592       case Toolkit::ProgressBar::Property::SECONDARY_PROGRESS_VALUE:
593       {
594         progressBarImpl.SetSecondaryProgressValue(value.Get<float>());
595         break;
596       }
597
598       case Toolkit::ProgressBar::Property::INDETERMINATE:
599       {
600         progressBarImpl.SetIndeterminate(value.Get<bool>());
601         break;
602       }
603
604       case Toolkit::ProgressBar::Property::INDETERMINATE_VISUAL_ANIMATION:
605       {
606         progressBarImpl.SetIndeterminateVisualTransition(progressBarImpl.ConvertPropertyToTransition(value));
607         break;
608       }
609     }
610   }
611 }
612
613 Property::Value ProgressBar::GetProperty(BaseObject* object, Property::Index propertyIndex)
614 {
615   Property::Value value;
616
617   Toolkit::ProgressBar progressBar = Toolkit::ProgressBar::DownCast(Dali::BaseHandle(object));
618
619   if(progressBar)
620   {
621     ProgressBar& progressBarImpl(GetImpl(progressBar));
622
623     switch(propertyIndex)
624     {
625       case Toolkit::ProgressBar::Property::TRACK_VISUAL:
626       case Toolkit::ProgressBar::Property::PROGRESS_VISUAL:
627       case Toolkit::ProgressBar::Property::SECONDARY_PROGRESS_VISUAL:
628       case Toolkit::ProgressBar::Property::INDETERMINATE_VISUAL:
629       case Toolkit::ProgressBar::Property::LABEL_VISUAL:
630       {
631         Property::Map visualProperty;
632         if(progressBarImpl.GetPropertyMapForVisual(propertyIndex, visualProperty))
633         {
634           value = visualProperty;
635         }
636         break;
637       }
638
639       case Toolkit::ProgressBar::Property::PROGRESS_VALUE:
640       {
641         value = progressBarImpl.GetProgressValue();
642         break;
643       }
644
645       case Toolkit::ProgressBar::Property::SECONDARY_PROGRESS_VALUE:
646       {
647         value = progressBarImpl.GetSecondaryProgressValue();
648         break;
649       }
650
651       case Toolkit::ProgressBar::Property::INDETERMINATE:
652       {
653         value = progressBarImpl.GetIndeterminate();
654         break;
655       }
656
657       case Toolkit::ProgressBar::Property::INDETERMINATE_VISUAL_ANIMATION:
658       {
659         //TODO: Return INDETERMINATE_VISUAL_TRANSITION;
660       }
661     }
662   }
663
664   return value;
665 }
666
667 void ProgressBar::OnSceneConnection(int depth)
668 {
669   // Chain up first (ensures visuals are ready to draw)
670   Control::OnSceneConnection(depth);
671
672   if(mIndeterminate)
673   {
674     PlayIndeterminateVisualTransition();
675   }
676 }
677
678 double ProgressBar::ProgressBarAccessible::GetMinimum() const
679 {
680   return DEFAULT_LOWER_BOUND;
681 }
682
683 double ProgressBar::ProgressBarAccessible::GetCurrent() const
684 {
685   auto self = Toolkit::ProgressBar::DownCast(Self());
686   return self.GetProperty(Toolkit::ProgressBar::Property::PROGRESS_VALUE).Get<float>();
687 }
688
689 double ProgressBar::ProgressBarAccessible::GetMaximum() const
690 {
691   return DEFAULT_UPPER_BOUND;
692 }
693
694 bool ProgressBar::ProgressBarAccessible::SetCurrent(double current)
695 {
696   if(current < GetMinimum() || current > GetMaximum())
697   {
698     return false;
699   }
700
701   auto self = Toolkit::ProgressBar::DownCast(Self());
702   self.SetProperty(Toolkit::ProgressBar::Property::PROGRESS_VALUE, static_cast<float>(current));
703   return true;
704 }
705
706 double ProgressBar::ProgressBarAccessible::GetMinimumIncrement() const
707 {
708   return 0.0;
709 }
710
711 } // namespace Internal
712
713 } // namespace Toolkit
714
715 } // namespace Dali