2 * Copyright (c) 2017 Samsung Electronics Co., Ltd.
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
19 #include <dali-toolkit/internal/controls/progress-bar/progress-bar-impl.h>
22 #include <cstring> // for strcmp
25 #include <dali/public-api/object/type-registry-helper.h>
26 #include <dali/public-api/size-negotiation/relayout-container.h>
27 #include <dali/public-api/math/math-utils.h>
28 #include <dali-toolkit/public-api/align-enumerations.h>
29 #include <dali-toolkit/devel-api/controls/control-devel.h>
30 #include <dali-toolkit/devel-api/visual-factory/visual-base.h>
31 #include <dali-toolkit/public-api/visuals/color-visual-properties.h>
32 #include <dali-toolkit/public-api/visuals/image-visual-properties.h>
33 #include <dali-toolkit/public-api/visuals/text-visual-properties.h>
34 #include <dali-toolkit/public-api/visuals/visual-properties.h>
35 #include <dali-toolkit/devel-api/visual-factory/visual-factory.h>
37 #include <dali/integration-api/debug.h>
48 namespace // Unnamed namespace
53 return Dali::Toolkit::ProgressBar::New();
56 // Setup properties, signals and actions using the type-registry.
57 DALI_TYPE_REGISTRATION_BEGIN( Toolkit::ProgressBar, Toolkit::Control, Create )
59 DALI_PROPERTY_REGISTRATION( Toolkit, ProgressBar, "progressValue", FLOAT, PROGRESS_VALUE )
60 DALI_PROPERTY_REGISTRATION( Toolkit, ProgressBar, "secondaryProgressValue", FLOAT, SECONDARY_PROGRESS_VALUE )
61 DALI_PROPERTY_REGISTRATION( Toolkit, ProgressBar, "indeterminate", BOOLEAN, INDETERMINATE )
62 DALI_PROPERTY_REGISTRATION( Toolkit, ProgressBar, "trackVisual", MAP, TRACK_VISUAL )
63 DALI_PROPERTY_REGISTRATION( Toolkit, ProgressBar, "progressVisual", MAP, PROGRESS_VISUAL )
64 DALI_PROPERTY_REGISTRATION( Toolkit, ProgressBar, "secondaryProgressVisual", MAP, SECONDARY_PROGRESS_VISUAL )
65 DALI_PROPERTY_REGISTRATION( Toolkit, ProgressBar, "indeterminateVisual", MAP, INDETERMINATE_VISUAL )
66 DALI_PROPERTY_REGISTRATION( Toolkit, ProgressBar, "indeterminateVisualAnimation", ARRAY, INDETERMINATE_VISUAL_ANIMATION )
67 DALI_PROPERTY_REGISTRATION( Toolkit, ProgressBar, "labelVisual", MAP, LABEL_VISUAL )
68 DALI_SIGNAL_REGISTRATION( Toolkit, ProgressBar, "valueChanged", SIGNAL_VALUE_CHANGED )
70 DALI_TYPE_REGISTRATION_END()
72 struct ProgressDepthIndex
74 // Enum to make sure the visual order
78 SECONDARY_PROGRESS_VISUAL,
85 float DEFAULT_VALUE = 0.0f;
86 float DEFAULT_LOWER_BOUND = 0.0f;
87 float DEFAULT_UPPER_BOUND = 1.0f;
88 float DEFAULT_FONT_SIZE = 12.0f;
90 } // Unnamed namespace
92 ///////////////////////////////////////////////////////////////////////////////////////////////////
94 ///////////////////////////////////////////////////////////////////////////////////////////////////
96 Dali::Toolkit::ProgressBar ProgressBar::New()
98 // Create the implementation
99 ProgressBarPtr progressBar( new ProgressBar() );
101 // Pass ownership to CustomActor via derived handle
102 Dali::Toolkit::ProgressBar handle( *progressBar );
104 // Second-phase init of the implementation
105 // This can only be done after the CustomActor connection has been made...
106 progressBar->Initialize();
111 ProgressBar::ProgressBar()
112 : Control( ControlBehaviour( CONTROL_BEHAVIOUR_DEFAULT ) ),
113 mProgressValue( DEFAULT_VALUE ),
114 mSecondaryProgressValue( DEFAULT_VALUE ),
115 mIndeterminate( false )
117 DevelControl::SetAccessibilityConstructor( Self(), []( Dali::Actor actor ) {
118 return std::unique_ptr< Dali::Accessibility::Accessible >(
119 new AccessibleImpl( actor, Dali::Accessibility::Role::PROGRESS_BAR ) );
123 ProgressBar::~ProgressBar()
127 void ProgressBar::OnInitialize()
131 void ProgressBar::OnRelayout( const Vector2& size, RelayoutContainer& container )
134 Vector2 trackSize( size );
135 mDomain = CalcDomain( size );
137 trackSize.width = std::max( 0.0f, size.width ); // Ensure we don't go negative
139 Toolkit::Visual::Base trackVisual = DevelControl::GetVisual( *this, Toolkit::ProgressBar::Property::TRACK_VISUAL );
140 Toolkit::Visual::Base secondProgressVisual = DevelControl::GetVisual( *this, Toolkit::ProgressBar::Property::SECONDARY_PROGRESS_VISUAL );
141 Toolkit::Visual::Base progressVisual = DevelControl::GetVisual( *this, Toolkit::ProgressBar::Property::PROGRESS_VISUAL );
142 Toolkit::Visual::Base labelVisual = DevelControl::GetVisual( *this, Toolkit::ProgressBar::Property::LABEL_VISUAL );
143 Toolkit::Visual::Base indeterminateVisual = DevelControl::GetVisual( *this, Toolkit::ProgressBar::Property::INDETERMINATE_VISUAL );
147 Property::Map visualTransform;
149 visualTransform.Add( Toolkit::Visual::Transform::Property::SIZE, trackSize )
150 .Add( Toolkit::Visual::Transform::Property::OFFSET_POLICY, Vector2( Toolkit::Visual::Transform::Policy::ABSOLUTE, Toolkit::Visual::Transform::Policy::ABSOLUTE ) )
151 .Add( Toolkit::Visual::Transform::Property::SIZE_POLICY, Vector2( Toolkit::Visual::Transform::Policy::ABSOLUTE, Toolkit::Visual::Transform::Policy::ABSOLUTE ) );
153 trackVisual.SetTransformAndSize( visualTransform, trackSize );
156 if( secondProgressVisual )
158 Property::Map visualTransform;
160 visualTransform.Add( Toolkit::Visual::Transform::Property::SIZE, Vector2( mDomain.from.x + mSecondaryProgressValue * ( mDomain.to.x - mDomain.from.x ), trackSize.height ) )
161 .Add( Toolkit::Visual::Transform::Property::OFFSET_POLICY, Vector2( Toolkit::Visual::Transform::Policy::ABSOLUTE, Toolkit::Visual::Transform::Policy::ABSOLUTE ) )
162 .Add( Toolkit::Visual::Transform::Property::SIZE_POLICY, Vector2( Toolkit::Visual::Transform::Policy::ABSOLUTE, Toolkit::Visual::Transform::Policy::ABSOLUTE ) )
163 .Add( Toolkit::Visual::Transform::Property::ORIGIN, Toolkit::Align::TOP_BEGIN )
164 .Add( Toolkit::Visual::Transform::Property::ANCHOR_POINT, Toolkit::Align::TOP_BEGIN );
165 secondProgressVisual.SetTransformAndSize( visualTransform, trackSize );
170 Property::Map visualTransform;
172 visualTransform.Add( Toolkit::Visual::Transform::Property::SIZE, Vector2( mDomain.from.x + mProgressValue * ( mDomain.to.x - mDomain.from.x ), trackSize.height ) )
173 .Add( Toolkit::Visual::Transform::Property::OFFSET_POLICY, Vector2( Toolkit::Visual::Transform::Policy::ABSOLUTE, Toolkit::Visual::Transform::Policy::ABSOLUTE ) )
174 .Add( Toolkit::Visual::Transform::Property::SIZE_POLICY, Vector2( Toolkit::Visual::Transform::Policy::ABSOLUTE, Toolkit::Visual::Transform::Policy::ABSOLUTE ) )
175 .Add( Toolkit::Visual::Transform::Property::ORIGIN, Toolkit::Align::TOP_BEGIN )
176 .Add( Toolkit::Visual::Transform::Property::ANCHOR_POINT, Toolkit::Align::TOP_BEGIN );
177 progressVisual.SetTransformAndSize( visualTransform, trackSize );
182 Property::Map visualTransform;
184 visualTransform.Add( Toolkit::Visual::Transform::Property::SIZE, trackSize )
185 .Add( Toolkit::Visual::Transform::Property::OFFSET_POLICY, Vector2( Toolkit::Visual::Transform::Policy::ABSOLUTE, Toolkit::Visual::Transform::Policy::ABSOLUTE ) )
186 .Add( Toolkit::Visual::Transform::Property::SIZE_POLICY, Vector2( Toolkit::Visual::Transform::Policy::ABSOLUTE, Toolkit::Visual::Transform::Policy::ABSOLUTE ) );
187 labelVisual.SetTransformAndSize( visualTransform, trackSize );
190 if( indeterminateVisual )
192 Property::Map visualTransform;
194 visualTransform.Add( Toolkit::Visual::Transform::Property::SIZE, trackSize )
195 .Add( Toolkit::Visual::Transform::Property::OFFSET_POLICY, Vector2( Toolkit::Visual::Transform::Policy::ABSOLUTE, Toolkit::Visual::Transform::Policy::ABSOLUTE ) )
196 .Add( Toolkit::Visual::Transform::Property::SIZE_POLICY, Vector2( Toolkit::Visual::Transform::Policy::ABSOLUTE, Toolkit::Visual::Transform::Policy::ABSOLUTE ) );
197 indeterminateVisual.SetTransformAndSize( visualTransform, trackSize );
202 Vector3 ProgressBar::GetNaturalSize()
204 // Return the bigger size after comparing trackVisual naturalSize and labelVisual naturalSize
205 Toolkit::Visual::Base trackVisual = DevelControl::GetVisual( *this, Toolkit::ProgressBar::Property::TRACK_VISUAL );
206 Toolkit::Visual::Base labelVisual = DevelControl::GetVisual( *this, Toolkit::ProgressBar::Property::LABEL_VISUAL );
213 trackVisual.GetNaturalSize( trackSize );
217 labelVisual.GetNaturalSize( labelSize );
221 naturalSize.width = ( trackSize.width > labelSize.width ) ? trackSize.width: labelSize.width;
222 naturalSize.height = ( trackSize.height > labelSize.height ) ? trackSize.height: labelSize.height;
227 ProgressBar::Domain ProgressBar::CalcDomain( const Vector2& currentSize )
229 return Domain( Vector2( 0.0f, 0.0f ), currentSize );
232 Toolkit::ProgressBar::ValueChangedSignalType& ProgressBar::ValueChangedSignal()
234 return mValueChangedSignal;
237 void ProgressBar::SetProgressValue( float value )
239 // update the progress bar value (taking float precision errors into account)
240 // TODO : it seems 0.0f cannot into this statement.
241 if( ( mProgressValue != value ) &&
242 ( ( value >= DEFAULT_LOWER_BOUND ) || ( Equals( value, DEFAULT_LOWER_BOUND ) ) ) &&
243 ( ( value <= DEFAULT_UPPER_BOUND ) || ( Equals( value, DEFAULT_UPPER_BOUND ) ) ) )
245 mProgressValue = Clamp( value, DEFAULT_LOWER_BOUND, DEFAULT_UPPER_BOUND );
247 Toolkit::ProgressBar self = Toolkit::ProgressBar::DownCast( Self() );
248 mValueChangedSignal.Emit( self, mProgressValue, mSecondaryProgressValue );
253 float ProgressBar::GetProgressValue() const
255 return mProgressValue;
258 void ProgressBar::SetSecondaryProgressValue( float value )
260 // update the progress bar value (taking float precision errors into account)
261 // TODO : it seems 0.0f cannot into this statement.
262 if( ( mSecondaryProgressValue != value ) &&
263 ( ( value >= DEFAULT_LOWER_BOUND ) || ( Equals( value, DEFAULT_LOWER_BOUND ) ) ) &&
264 ( ( value <= DEFAULT_UPPER_BOUND ) || ( Equals( value, DEFAULT_UPPER_BOUND ) ) ) )
266 mSecondaryProgressValue = Clamp( value, DEFAULT_LOWER_BOUND, DEFAULT_UPPER_BOUND );
268 Toolkit::ProgressBar self = Toolkit::ProgressBar::DownCast( Self() );
269 mValueChangedSignal.Emit( self, mProgressValue, mSecondaryProgressValue );
275 float ProgressBar::GetSecondaryProgressValue() const
277 return mSecondaryProgressValue;
280 void ProgressBar::SetIndeterminate( bool value )
282 mIndeterminate = value;
283 DevelControl::EnableVisual( *this, Toolkit::ProgressBar::Property::INDETERMINATE_VISUAL, mIndeterminate );
288 if( mIndeterminateVisualTransition )
290 PlayIndeterminateVisualTransition();
295 if( mIndeterminateVisualAni )
297 mIndeterminateVisualAni.Stop();
302 bool ProgressBar::GetIndeterminate() const
304 return mIndeterminate;
307 void ProgressBar::SetIndeterminateVisualTransition( Toolkit::TransitionData transition )
309 mIndeterminateVisualTransition = transition;
312 PlayIndeterminateVisualTransition();
316 void ProgressBar::PlayIndeterminateVisualTransition()
318 if( mIndeterminateVisualAni )
320 mIndeterminateVisualAni.Stop();
321 mIndeterminateVisualAni.Clear();
324 mIndeterminateVisualAni = DevelControl::CreateTransition( *this, mIndeterminateVisualTransition );
326 if( mIndeterminate && mIndeterminateVisualAni )
328 mIndeterminateVisualAni.SetLooping(true);
329 mIndeterminateVisualAni.Play();
333 Toolkit::TransitionData ProgressBar::ConvertPropertyToTransition( const Property::Value& value )
335 Toolkit::TransitionData transitionData;
337 if( value.GetType() == Property::ARRAY )
339 transitionData = Toolkit::TransitionData::New( *value.GetArray() );
341 else if( value.GetType() == Property::MAP )
343 transitionData = Toolkit::TransitionData::New( *value.GetMap() );
346 return transitionData;
350 * Create Visual for given index from a property map or url.
351 * 1) Check if value passed in is a url and create visual
352 * 2) Create visual from map if step (1) is false
353 * 3) Register visual with control with false for enable flag.
354 * 4) Unregister visual if empty map was provided. This is the method to remove a visual
357 void ProgressBar::CreateVisualsForComponent( Property::Index index, const Property::Value& value, const int visualDepth )
359 Toolkit::VisualFactory visualFactory = Toolkit::VisualFactory::Get();
360 Toolkit::Visual::Base progressVisual;
362 std::string imageUrl;
363 if( value.Get( imageUrl ) )
365 if ( !imageUrl.empty() )
367 progressVisual = visualFactory.CreateVisual( imageUrl, ImageDimensions() );
370 else // Does this code make text-visual can be accepted as visual?
372 // if its not a string then get a Property::Map from the property if possible.
373 Property::Map *map = value.GetMap();
374 if( map && !map->Empty() ) // Empty map results in current visual removal.
376 progressVisual = visualFactory.CreateVisual( *map );
380 if ( progressVisual )
382 if( index == Toolkit::ProgressBar::Property::INDETERMINATE_VISUAL )
384 DevelControl::RegisterVisual( *this, index, progressVisual, mIndeterminate, visualDepth );
388 DevelControl::RegisterVisual( *this, index, progressVisual, true, visualDepth );
393 DevelControl::UnregisterVisual( *this, index );
397 bool ProgressBar::GetPropertyMapForVisual( Property::Index visualIndex, Property::Map& retreivedMap ) const
399 bool success = false;
400 Toolkit::Visual::Base visual = DevelControl::GetVisual( *this, visualIndex );
404 visual.CreatePropertyMap( retreivedMap );
411 // Static class method to support script connecting signals
412 bool ProgressBar::DoConnectSignal( BaseObject* object, ConnectionTrackerInterface* tracker, const std::string& signalName, FunctorDelegate* functor )
414 Dali::BaseHandle handle( object );
416 bool connected = true;
417 Toolkit::ProgressBar ProgressBar = Toolkit::ProgressBar::DownCast( handle );
419 if( 0 == strcmp( signalName.c_str(), SIGNAL_VALUE_CHANGED ) )
421 ProgressBar.ValueChangedSignal().Connect( tracker, functor );
425 // signalName does not match any signal
432 void ProgressBar::SetProperty( BaseObject* object, Property::Index propertyIndex, const Property::Value& value )
434 Toolkit::ProgressBar progressBar = Toolkit::ProgressBar::DownCast( Dali::BaseHandle( object ) );
438 ProgressBar& progressBarImpl( GetImpl( progressBar ) );
440 switch ( propertyIndex )
442 case Toolkit::ProgressBar::Property::TRACK_VISUAL:
444 progressBarImpl.CreateVisualsForComponent( propertyIndex, value, ProgressDepthIndex::TRACK_VISUAL );
448 case Toolkit::ProgressBar::Property::SECONDARY_PROGRESS_VISUAL:
450 progressBarImpl.CreateVisualsForComponent( propertyIndex, value, ProgressDepthIndex::SECONDARY_PROGRESS_VISUAL );
454 case Toolkit::ProgressBar::Property::PROGRESS_VISUAL:
456 progressBarImpl.CreateVisualsForComponent( propertyIndex, value, ProgressDepthIndex::PROGRESS_VISUAL );
460 case Toolkit::ProgressBar::Property::INDETERMINATE_VISUAL:
462 progressBarImpl.CreateVisualsForComponent( propertyIndex, value, ProgressDepthIndex::INDETERMINATE_VISUAL );
466 case Toolkit::ProgressBar::Property::LABEL_VISUAL:
469 std::string textString;
471 if ( value.Get( textString ) )
473 // set new text string as TEXT property
474 Property::Map newTextMap;
475 Toolkit::Visual::Base label = DevelControl::GetVisual( progressBarImpl, Toolkit::ProgressBar::Property::LABEL_VISUAL );
479 label.CreatePropertyMap( map );
482 // if LABEL_VISUAL doesn't set before, add Visual property "TYPE" to create new text Visual
485 newTextMap.Add( Toolkit::Visual::Property::TYPE, Toolkit::Visual::TEXT );
486 newTextMap.Add( Toolkit::TextVisual::Property::POINT_SIZE, DEFAULT_FONT_SIZE );
488 newTextMap.Add( Toolkit::TextVisual::Property::TEXT, textString );
490 map.Merge( newTextMap );
499 progressBarImpl.CreateVisualsForComponent( propertyIndex, map, ProgressDepthIndex::LABEL_VISUAL );
504 case Toolkit::ProgressBar::Property::PROGRESS_VALUE:
506 progressBarImpl.SetProgressValue( value.Get< float >() );
510 case Toolkit::ProgressBar::Property::SECONDARY_PROGRESS_VALUE:
512 progressBarImpl.SetSecondaryProgressValue( value.Get< float >() );
516 case Toolkit::ProgressBar::Property::INDETERMINATE:
518 progressBarImpl.SetIndeterminate( value.Get< bool >() );
522 case Toolkit::ProgressBar::Property::INDETERMINATE_VISUAL_ANIMATION:
524 progressBarImpl.SetIndeterminateVisualTransition( progressBarImpl.ConvertPropertyToTransition( value ) );
531 Property::Value ProgressBar::GetProperty( BaseObject* object, Property::Index propertyIndex )
533 Property::Value value;
535 Toolkit::ProgressBar progressBar = Toolkit::ProgressBar::DownCast( Dali::BaseHandle( object ) );
539 ProgressBar& progressBarImpl( GetImpl( progressBar ) );
541 switch ( propertyIndex )
543 case Toolkit::ProgressBar::Property::TRACK_VISUAL:
544 case Toolkit::ProgressBar::Property::PROGRESS_VISUAL:
545 case Toolkit::ProgressBar::Property::SECONDARY_PROGRESS_VISUAL:
546 case Toolkit::ProgressBar::Property::INDETERMINATE_VISUAL:
547 case Toolkit::ProgressBar::Property::LABEL_VISUAL:
549 Property::Map visualProperty;
550 if ( progressBarImpl.GetPropertyMapForVisual( propertyIndex, visualProperty ) )
552 value = visualProperty;
557 case Toolkit::ProgressBar::Property::PROGRESS_VALUE:
559 value = progressBarImpl.GetProgressValue();
563 case Toolkit::ProgressBar::Property::SECONDARY_PROGRESS_VALUE:
565 value = progressBarImpl.GetSecondaryProgressValue();
569 case Toolkit::ProgressBar::Property::INDETERMINATE:
571 value = progressBarImpl.GetIndeterminate();
575 case Toolkit::ProgressBar::Property::INDETERMINATE_VISUAL_ANIMATION:
577 //TODO: Return INDETERMINATE_VISUAL_TRANSITION;
585 void ProgressBar::OnStageConnection( int depth )
587 // Chain up first (ensures visuals are ready to draw)
588 Control::OnStageConnection( depth );
592 PlayIndeterminateVisualTransition();
596 double ProgressBar::AccessibleImpl::GetMinimum() { return DEFAULT_LOWER_BOUND; }
598 double ProgressBar::AccessibleImpl::GetCurrent()
600 auto p = Toolkit::ProgressBar::DownCast( self );
601 return p.GetProperty( Toolkit::ProgressBar::Property::PROGRESS_VALUE )
605 double ProgressBar::AccessibleImpl::GetMaximum() { return DEFAULT_UPPER_BOUND; }
607 bool ProgressBar::AccessibleImpl::SetCurrent( double current )
609 if( current < GetMinimum() || current > GetMaximum() )
611 auto p = Toolkit::ProgressBar::DownCast( self );
612 p.SetProperty( Toolkit::ProgressBar::Property::PROGRESS_VALUE,
613 static_cast< float >( current ) );
617 double ProgressBar::AccessibleImpl::GetMinimumIncrement() { return 0.001; }
619 } // namespace Internal
621 } // namespace Toolkit