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/devel-api/align-enums.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/devel-api/visuals/text-visual-properties.h>
34 #include <dali-toolkit/devel-api/visuals/visual-properties-devel.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 )
119 ProgressBar::~ProgressBar()
123 void ProgressBar::OnInitialize()
127 void ProgressBar::OnRelayout( const Vector2& size, RelayoutContainer& container )
130 Vector2 trackSize( size );
131 mDomain = CalcDomain( size );
133 trackSize.width = std::max( 0.0f, size.width ); // Ensure we don't go negative
135 Toolkit::Visual::Base trackVisual = DevelControl::GetVisual( *this, Toolkit::ProgressBar::Property::TRACK_VISUAL );
136 Toolkit::Visual::Base secondProgressVisual = DevelControl::GetVisual( *this, Toolkit::ProgressBar::Property::SECONDARY_PROGRESS_VISUAL );
137 Toolkit::Visual::Base progressVisual = DevelControl::GetVisual( *this, Toolkit::ProgressBar::Property::PROGRESS_VISUAL );
138 Toolkit::Visual::Base labelVisual = DevelControl::GetVisual( *this, Toolkit::ProgressBar::Property::LABEL_VISUAL );
139 Toolkit::Visual::Base indeterminateVisual = DevelControl::GetVisual( *this, Toolkit::ProgressBar::Property::INDETERMINATE_VISUAL );
143 Property::Map visualTransform;
145 visualTransform.Add( Toolkit::DevelVisual::Transform::Property::SIZE, trackSize )
146 .Add( Toolkit::DevelVisual::Transform::Property::OFFSET_POLICY, Vector2( DevelVisual::Transform::Policy::ABSOLUTE, DevelVisual::Transform::Policy::ABSOLUTE ) )
147 .Add( Toolkit::DevelVisual::Transform::Property::SIZE_POLICY, Vector2( DevelVisual::Transform::Policy::ABSOLUTE, DevelVisual::Transform::Policy::ABSOLUTE ) );
149 trackVisual.SetTransformAndSize( visualTransform, trackSize );
152 if( secondProgressVisual )
154 Property::Map visualTransform;
156 visualTransform.Add( Toolkit::DevelVisual::Transform::Property::SIZE, Vector2( mDomain.from.x + mSecondaryProgressValue * ( mDomain.to.x - mDomain.from.x ), trackSize.height ) )
157 .Add( Toolkit::DevelVisual::Transform::Property::OFFSET_POLICY, Vector2( DevelVisual::Transform::Policy::ABSOLUTE, DevelVisual::Transform::Policy::ABSOLUTE ) )
158 .Add( Toolkit::DevelVisual::Transform::Property::SIZE_POLICY, Vector2( DevelVisual::Transform::Policy::ABSOLUTE, DevelVisual::Transform::Policy::ABSOLUTE ) )
159 .Add( Toolkit::DevelVisual::Transform::Property::ORIGIN, Toolkit::Align::TOP_BEGIN )
160 .Add( Toolkit::DevelVisual::Transform::Property::ANCHOR_POINT, Toolkit::Align::TOP_BEGIN );
161 secondProgressVisual.SetTransformAndSize( visualTransform, trackSize );
166 Property::Map visualTransform;
168 visualTransform.Add( Toolkit::DevelVisual::Transform::Property::SIZE, Vector2( mDomain.from.x + mProgressValue * ( mDomain.to.x - mDomain.from.x ), trackSize.height ) )
169 .Add( Toolkit::DevelVisual::Transform::Property::OFFSET_POLICY, Vector2( DevelVisual::Transform::Policy::ABSOLUTE, DevelVisual::Transform::Policy::ABSOLUTE ) )
170 .Add( Toolkit::DevelVisual::Transform::Property::SIZE_POLICY, Vector2( DevelVisual::Transform::Policy::ABSOLUTE, DevelVisual::Transform::Policy::ABSOLUTE ) )
171 .Add( Toolkit::DevelVisual::Transform::Property::ORIGIN, Toolkit::Align::TOP_BEGIN )
172 .Add( Toolkit::DevelVisual::Transform::Property::ANCHOR_POINT, Toolkit::Align::TOP_BEGIN );
173 progressVisual.SetTransformAndSize( visualTransform, trackSize );
178 Property::Map visualTransform;
180 visualTransform.Add( Toolkit::DevelVisual::Transform::Property::SIZE, trackSize )
181 .Add( Toolkit::DevelVisual::Transform::Property::OFFSET_POLICY, Vector2( DevelVisual::Transform::Policy::ABSOLUTE, DevelVisual::Transform::Policy::ABSOLUTE ) )
182 .Add( Toolkit::DevelVisual::Transform::Property::SIZE_POLICY, Vector2( DevelVisual::Transform::Policy::ABSOLUTE, DevelVisual::Transform::Policy::ABSOLUTE ) );
183 labelVisual.SetTransformAndSize( visualTransform, trackSize );
186 if( indeterminateVisual )
188 Property::Map visualTransform;
190 visualTransform.Add( Toolkit::DevelVisual::Transform::Property::SIZE, trackSize )
191 .Add( Toolkit::DevelVisual::Transform::Property::OFFSET_POLICY, Vector2( DevelVisual::Transform::Policy::ABSOLUTE, DevelVisual::Transform::Policy::ABSOLUTE ) )
192 .Add( Toolkit::DevelVisual::Transform::Property::SIZE_POLICY, Vector2( DevelVisual::Transform::Policy::ABSOLUTE, DevelVisual::Transform::Policy::ABSOLUTE ) );
193 indeterminateVisual.SetTransformAndSize( visualTransform, trackSize );
198 Vector3 ProgressBar::GetNaturalSize()
200 // Return the bigger size after comparing trackVisual naturalSize and labelVisual naturalSize
201 Toolkit::Visual::Base trackVisual = DevelControl::GetVisual( *this, Toolkit::ProgressBar::Property::TRACK_VISUAL );
202 Toolkit::Visual::Base labelVisual = DevelControl::GetVisual( *this, Toolkit::ProgressBar::Property::LABEL_VISUAL );
209 trackVisual.GetNaturalSize( trackSize );
213 labelVisual.GetNaturalSize( labelSize );
217 naturalSize.width = ( trackSize.width > labelSize.width ) ? trackSize.width: labelSize.width;
218 naturalSize.height = ( trackSize.height > labelSize.height ) ? trackSize.height: labelSize.height;
223 ProgressBar::Domain ProgressBar::CalcDomain( const Vector2& currentSize )
225 return Domain( Vector2( 0.0f, 0.0f ), currentSize );
228 Toolkit::ProgressBar::ValueChangedSignalType& ProgressBar::ValueChangedSignal()
230 return mValueChangedSignal;
233 void ProgressBar::SetProgressValue( float value )
235 // update the progress bar value (taking float precision errors into account)
236 // TODO : it seems 0.0f cannot into this statement.
237 if( ( mProgressValue != value ) &&
238 ( ( value >= DEFAULT_LOWER_BOUND ) || ( Equals( value, DEFAULT_LOWER_BOUND ) ) ) &&
239 ( ( value <= DEFAULT_UPPER_BOUND ) || ( Equals( value, DEFAULT_UPPER_BOUND ) ) ) )
241 mProgressValue = Clamp( value, DEFAULT_LOWER_BOUND, DEFAULT_UPPER_BOUND );
243 Toolkit::ProgressBar self = Toolkit::ProgressBar::DownCast( Self() );
244 mValueChangedSignal.Emit( self, mProgressValue, mSecondaryProgressValue );
249 float ProgressBar::GetProgressValue() const
251 return mProgressValue;
254 void ProgressBar::SetSecondaryProgressValue( float value )
256 // update the progress bar value (taking float precision errors into account)
257 // TODO : it seems 0.0f cannot into this statement.
258 if( ( mSecondaryProgressValue != value ) &&
259 ( ( value >= DEFAULT_LOWER_BOUND ) || ( Equals( value, DEFAULT_LOWER_BOUND ) ) ) &&
260 ( ( value <= DEFAULT_UPPER_BOUND ) || ( Equals( value, DEFAULT_UPPER_BOUND ) ) ) )
262 mSecondaryProgressValue = Clamp( value, DEFAULT_LOWER_BOUND, DEFAULT_UPPER_BOUND );
264 Toolkit::ProgressBar self = Toolkit::ProgressBar::DownCast( Self() );
265 mValueChangedSignal.Emit( self, mProgressValue, mSecondaryProgressValue );
271 float ProgressBar::GetSecondaryProgressValue() const
273 return mSecondaryProgressValue;
276 void ProgressBar::SetIndeterminate( bool value )
278 mIndeterminate = value;
279 DevelControl::EnableVisual( *this, Toolkit::ProgressBar::Property::INDETERMINATE_VISUAL, mIndeterminate );
284 if( mIndeterminateVisualTransition )
286 PlayIndeterminateVisualTransition();
291 if( mIndeterminateVisualAni )
293 mIndeterminateVisualAni.Stop();
298 bool ProgressBar::GetIndeterminate() const
300 return mIndeterminate;
303 void ProgressBar::SetIndeterminateVisualTransition( Toolkit::TransitionData transition )
305 mIndeterminateVisualTransition = transition;
308 PlayIndeterminateVisualTransition();
312 void ProgressBar::PlayIndeterminateVisualTransition()
314 if( mIndeterminateVisualAni )
316 mIndeterminateVisualAni.Stop();
317 mIndeterminateVisualAni.Clear();
320 mIndeterminateVisualAni = DevelControl::CreateTransition( *this, mIndeterminateVisualTransition );
322 if( mIndeterminate && mIndeterminateVisualAni )
324 mIndeterminateVisualAni.SetLooping(true);
325 mIndeterminateVisualAni.Play();
329 Toolkit::TransitionData ProgressBar::ConvertPropertyToTransition( const Property::Value& value )
331 Toolkit::TransitionData transitionData;
333 if( value.GetType() == Property::ARRAY )
335 transitionData = Toolkit::TransitionData::New( *value.GetArray() );
337 else if( value.GetType() == Property::MAP )
339 transitionData = Toolkit::TransitionData::New( *value.GetMap() );
342 return transitionData;
346 * Create Visual for given index from a property map or url.
347 * 1) Check if value passed in is a url and create visual
348 * 2) Create visual from map if step (1) is false
349 * 3) Register visual with control with false for enable flag.
350 * 4) Unregister visual if empty map was provided. This is the method to remove a visual
353 void ProgressBar::CreateVisualsForComponent( Property::Index index, const Property::Value& value, const int visualDepth )
355 Toolkit::VisualFactory visualFactory = Toolkit::VisualFactory::Get();
356 Toolkit::Visual::Base progressVisual;
358 std::string imageUrl;
359 if( value.Get( imageUrl ) )
361 if ( !imageUrl.empty() )
363 progressVisual = visualFactory.CreateVisual( imageUrl, ImageDimensions() );
366 else // Does this code make text-visual can be accepted as visual?
368 // if its not a string then get a Property::Map from the property if possible.
369 Property::Map *map = value.GetMap();
370 if( map && !map->Empty() ) // Empty map results in current visual removal.
372 progressVisual = visualFactory.CreateVisual( *map );
376 if ( progressVisual )
378 if( index == Toolkit::ProgressBar::Property::INDETERMINATE_VISUAL )
380 DevelControl::RegisterVisual( *this, index, progressVisual, mIndeterminate, visualDepth );
384 DevelControl::RegisterVisual( *this, index, progressVisual, true, visualDepth );
389 DevelControl::UnregisterVisual( *this, index );
393 bool ProgressBar::GetPropertyMapForVisual( Property::Index visualIndex, Property::Map& retreivedMap ) const
395 bool success = false;
396 Toolkit::Visual::Base visual = DevelControl::GetVisual( *this, visualIndex );
400 visual.CreatePropertyMap( retreivedMap );
407 // Static class method to support script connecting signals
408 bool ProgressBar::DoConnectSignal( BaseObject* object, ConnectionTrackerInterface* tracker, const std::string& signalName, FunctorDelegate* functor )
410 Dali::BaseHandle handle( object );
412 bool connected = true;
413 Toolkit::ProgressBar ProgressBar = Toolkit::ProgressBar::DownCast( handle );
415 if( 0 == strcmp( signalName.c_str(), SIGNAL_VALUE_CHANGED ) )
417 ProgressBar.ValueChangedSignal().Connect( tracker, functor );
421 // signalName does not match any signal
428 void ProgressBar::SetProperty( BaseObject* object, Property::Index propertyIndex, const Property::Value& value )
430 Toolkit::ProgressBar progressBar = Toolkit::ProgressBar::DownCast( Dali::BaseHandle( object ) );
434 ProgressBar& progressBarImpl( GetImpl( progressBar ) );
436 switch ( propertyIndex )
438 case Toolkit::ProgressBar::Property::TRACK_VISUAL:
440 progressBarImpl.CreateVisualsForComponent( propertyIndex, value, ProgressDepthIndex::TRACK_VISUAL );
444 case Toolkit::ProgressBar::Property::SECONDARY_PROGRESS_VISUAL:
446 progressBarImpl.CreateVisualsForComponent( propertyIndex, value, ProgressDepthIndex::SECONDARY_PROGRESS_VISUAL );
450 case Toolkit::ProgressBar::Property::PROGRESS_VISUAL:
452 progressBarImpl.CreateVisualsForComponent( propertyIndex, value, ProgressDepthIndex::PROGRESS_VISUAL );
456 case Toolkit::ProgressBar::Property::INDETERMINATE_VISUAL:
458 progressBarImpl.CreateVisualsForComponent( propertyIndex, value, ProgressDepthIndex::INDETERMINATE_VISUAL );
462 case Toolkit::ProgressBar::Property::LABEL_VISUAL:
465 std::string textString;
467 if ( value.Get( textString ) )
469 // set new text string as TEXT property
470 Property::Map newTextMap;
471 Toolkit::Visual::Base label = DevelControl::GetVisual( progressBarImpl, Toolkit::ProgressBar::Property::LABEL_VISUAL );
475 label.CreatePropertyMap( map );
478 // if LABEL_VISUAL doesn't set before, add Visual property "TYPE" to create new text Visual
481 newTextMap.Add( Toolkit::Visual::Property::TYPE, Toolkit::DevelVisual::TEXT );
482 newTextMap.Add( Toolkit::TextVisual::Property::POINT_SIZE, DEFAULT_FONT_SIZE );
484 newTextMap.Add( Toolkit::TextVisual::Property::TEXT, textString );
486 map.Merge( newTextMap );
495 progressBarImpl.CreateVisualsForComponent( propertyIndex, map, ProgressDepthIndex::LABEL_VISUAL );
500 case Toolkit::ProgressBar::Property::PROGRESS_VALUE:
502 progressBarImpl.SetProgressValue( value.Get< float >() );
506 case Toolkit::ProgressBar::Property::SECONDARY_PROGRESS_VALUE:
508 progressBarImpl.SetSecondaryProgressValue( value.Get< float >() );
512 case Toolkit::ProgressBar::Property::INDETERMINATE:
514 progressBarImpl.SetIndeterminate( value.Get< bool >() );
518 case Toolkit::ProgressBar::Property::INDETERMINATE_VISUAL_ANIMATION:
520 progressBarImpl.SetIndeterminateVisualTransition( progressBarImpl.ConvertPropertyToTransition( value ) );
527 Property::Value ProgressBar::GetProperty( BaseObject* object, Property::Index propertyIndex )
529 Property::Value value;
531 Toolkit::ProgressBar progressBar = Toolkit::ProgressBar::DownCast( Dali::BaseHandle( object ) );
535 ProgressBar& progressBarImpl( GetImpl( progressBar ) );
537 switch ( propertyIndex )
539 case Toolkit::ProgressBar::Property::TRACK_VISUAL:
540 case Toolkit::ProgressBar::Property::PROGRESS_VISUAL:
541 case Toolkit::ProgressBar::Property::SECONDARY_PROGRESS_VISUAL:
542 case Toolkit::ProgressBar::Property::INDETERMINATE_VISUAL:
543 case Toolkit::ProgressBar::Property::LABEL_VISUAL:
545 Property::Map visualProperty;
546 if ( progressBarImpl.GetPropertyMapForVisual( propertyIndex, visualProperty ) )
548 value = visualProperty;
553 case Toolkit::ProgressBar::Property::PROGRESS_VALUE:
555 value = progressBarImpl.GetProgressValue();
559 case Toolkit::ProgressBar::Property::SECONDARY_PROGRESS_VALUE:
561 value = progressBarImpl.GetSecondaryProgressValue();
565 case Toolkit::ProgressBar::Property::INDETERMINATE:
567 value = progressBarImpl.GetIndeterminate();
571 case Toolkit::ProgressBar::Property::INDETERMINATE_VISUAL_ANIMATION:
573 //TODO: Return INDETERMINATE_VISUAL_TRANSITION;
581 void ProgressBar::OnStageConnection( int depth )
583 // Chain up first (ensures visuals are ready to draw)
584 Control::OnStageConnection( depth );
588 PlayIndeterminateVisualTransition();
592 } // namespace Internal
594 } // namespace Toolkit