2 * Copyright (c) 2016 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>
38 namespace // Unnamed namespace
43 return Dali::Toolkit::ProgressBar::New();
46 // Setup properties, signals and actions using the type-registry.
47 DALI_TYPE_REGISTRATION_BEGIN( Toolkit::ProgressBar, Toolkit::Control, Create )
49 DALI_PROPERTY_REGISTRATION( Toolkit, ProgressBar, "progressValue", FLOAT, PROGRESS_VALUE )
50 DALI_PROPERTY_REGISTRATION( Toolkit, ProgressBar, "trackVisual", MAP, TRACK_VISUAL )
51 DALI_PROPERTY_REGISTRATION( Toolkit, ProgressBar, "progressVisual", MAP, PROGRESS_VISUAL )
52 DALI_SIGNAL_REGISTRATION( Toolkit, ProgressBar, "valueChanged", SIGNAL_VALUE_CHANGED )
54 DALI_TYPE_REGISTRATION_END()
56 const char* SKINNED_TRACK_VISUAL = DALI_IMAGE_DIR "slider-skin.9.png";
57 const char* SKINNED_PROGRESS_VISUAL = DALI_IMAGE_DIR "slider-skin-progress.9.png";
59 float DEFAULT_VALUE = 0.0f;
60 float DEFAULT_LOWER_BOUND = 0.0f;
61 float DEFAULT_UPPER_BOUND = 1.0f;
62 float DEFAULT_PADDING = 24.0f;
64 } // Unnamed namespace
66 ///////////////////////////////////////////////////////////////////////////////////////////////////
68 ///////////////////////////////////////////////////////////////////////////////////////////////////
70 Dali::Toolkit::ProgressBar ProgressBar::New()
72 // Create the implementation
73 ProgressBarPtr progressBar( new ProgressBar() );
75 // Pass ownership to CustomActor via derived handle
76 Dali::Toolkit::ProgressBar handle( *progressBar );
78 // Second-phase init of the implementation
79 // This can only be done after the CustomActor connection has been made...
80 progressBar->Initialize();
85 ProgressBar::ProgressBar()
86 : Control( ControlBehaviour( CONTROL_BEHAVIOUR_DEFAULT ) ),
91 mProgressVisualSize(),
92 mValue( DEFAULT_VALUE )
96 ProgressBar::~ProgressBar()
100 void ProgressBar::OnInitialize()
106 SetTrackVisual( SKINNED_TRACK_VISUAL );
107 SetProgressVisual( SKINNED_PROGRESS_VISUAL );
109 DisplayValue( mValue, false ); // Run this last to display the correct value
112 void ProgressBar::OnRelayout( const Vector2& size, RelayoutContainer& container )
114 Vector2 trackSize( size );
115 trackSize.width = std::max( 0.0f, size.width - DEFAULT_PADDING ); // Ensure we don't go negative
120 container.Add( mTrack, trackSize );
122 // mValueTextLabel will have its relayout method called automatically as it's a child of mTrack,
123 // which is added to the container
129 mDomain = CalcDomain( trackSize );
131 Vector2 progressSize( trackSize );
133 // If no progress, then we do not want a n-patch image shown incorrectly
134 progressSize.width = std::max( mProgressVisualSize.width, mDomain.from.x + mValue * ( mDomain.to.x - mDomain.from.x ) );
135 progressSize.width = std::min( progressSize.width, trackSize.width ); // We should not exceed given size
137 container.Add( mProgress, progressSize );
141 Vector3 ProgressBar::GetNaturalSize()
143 // Return the maximum width/height combinations of our visuals
146 naturalSize.width = std::max( mTrackVisualSize.width, mProgressVisualSize.width );
147 naturalSize.height = std::max( mTrackVisualSize.height, mProgressVisualSize.height );
151 ProgressBar::Domain ProgressBar::CalcDomain( const Vector2& currentSize )
153 return Domain( Vector2( 0.0f, 0.0f ), currentSize );
156 void ProgressBar::DisplayValue( float value, bool raiseSignals )
161 Toolkit::ProgressBar self = Toolkit::ProgressBar::DownCast( Self() );
162 mValueChangedSignal.Emit( self, value );
165 // Change the value of the text label
166 if( mValueTextLabel )
168 std::stringstream ss;
170 ss << std::fixed << ( value * 100 ) << "%";
172 std::string label = mValueTextLabel.GetProperty<std::string>( Toolkit::TextLabel::Property::TEXT );
173 if( label.compare(ss.str()) )
175 mValueTextLabel.SetProperty( Toolkit::TextLabel::Property::TEXT, ss.str() );
180 Toolkit::ImageView ProgressBar::CreateTrack()
182 Toolkit::ImageView track = Toolkit::ImageView::New();
183 track.SetParentOrigin( ParentOrigin::CENTER );
184 track.SetAnchorPoint( AnchorPoint::CENTER );
185 track.SetResizePolicy(ResizePolicy::USE_ASSIGNED_SIZE, Dimension::ALL_DIMENSIONS );
190 void ProgressBar::SetTrackVisual( const std::string& filename )
192 if( mTrack && filename.size() > 0 )
194 mTrack.SetImage( filename );
195 mTrackVisual = filename;
196 mTrackVisualSize = Vector2::ZERO;
201 void ProgressBar::SetTrackVisual( Property::Map map )
203 bool relayoutRequired = false;
205 Property::Value* imageValue = map.Find( "url" );
208 mTrackVisual.clear();
209 std::string filename;
210 if( imageValue->Get( filename ) )
212 if( mTrack && ( filename.size() > 0 ) )
214 mTrack.SetImage( filename );
216 relayoutRequired = true;
221 Property::Value* sizeValue = map.Find( "size" );
225 if( sizeValue->Get( size ) )
227 mTrackVisualSize = size;
228 relayoutRequired = true;
232 // Visual and/or visual size changed so we need to relayout
233 if( relayoutRequired )
239 std::string ProgressBar::GetTrackVisual()
244 Toolkit::ImageView ProgressBar::CreateProgress()
246 Toolkit::ImageView progress = Toolkit::ImageView::New();
247 progress.SetParentOrigin( ParentOrigin::CENTER_LEFT );
248 progress.SetAnchorPoint( AnchorPoint::CENTER_LEFT );
249 progress.SetResizePolicy(ResizePolicy::USE_ASSIGNED_SIZE, Dimension::ALL_DIMENSIONS );
254 void ProgressBar::SetProgressVisual( const std::string& filename )
256 if( mProgress && ( filename.size() > 0 ) )
258 mProgress.SetImage( filename );
259 mProgressVisual = filename;
260 mProgressVisualSize = Vector2::ZERO;
265 void ProgressBar::SetProgressVisual( Property::Map map )
267 bool relayoutRequired = false;
269 Property::Value* imageValue = map.Find( "url" );
272 mProgressVisual.clear();
273 std::string filename;
274 if( imageValue->Get( filename ) )
276 if( mProgress && ( filename.size() > 0 ) )
278 mProgress.SetImage( filename );
280 relayoutRequired = true;
285 Property::Value* sizeValue = map.Find( "size" );
289 if( sizeValue->Get( size ) )
291 mProgressVisualSize = size;
292 relayoutRequired = true;
296 // Visual and/or visual size changed so we need to relayout
297 if( relayoutRequired )
303 std::string ProgressBar::GetProgressVisual()
305 return mProgressVisual;
308 Toolkit::ProgressBar::ValueChangedSignalType& ProgressBar::ValueChangedSignal()
310 return mValueChangedSignal;
313 void ProgressBar::CreateChildren()
318 mTrack = CreateTrack();
319 self.Add( mTrack ); // Needs to be a direct child as we want to manipulate its size
322 mProgress = CreateProgress();
323 self.Add( mProgress ); // Needs to be a direct child as we want to manipulate its size
326 mValueTextLabel = Toolkit::TextLabel::New();
327 mValueTextLabel.SetName( "ProgressBarValueTextLabel" );
328 mValueTextLabel.SetStyleName( "ProgressBarValueTextLabel" );
329 mValueTextLabel.SetParentOrigin( ParentOrigin::CENTER );
330 mValueTextLabel.SetAnchorPoint( AnchorPoint::CENTER );
331 mValueTextLabel.SetProperty( Toolkit::TextLabel::Property::HORIZONTAL_ALIGNMENT, "CENTER" );
332 mValueTextLabel.SetProperty( Toolkit::TextLabel::Property::VERTICAL_ALIGNMENT, "CENTER" );
333 mTrack.Add( mValueTextLabel ); // Add to mTrack and let it automatically set its size
336 void ProgressBar::SetProgressValue( float value )
338 // update the progress bar value (taking float precision errors into account)
339 if( ( mValue != value ) &&
340 ( ( value >= DEFAULT_LOWER_BOUND ) || ( Equals( value, DEFAULT_LOWER_BOUND ) ) ) &&
341 ( ( value <= DEFAULT_UPPER_BOUND ) || ( Equals( value, DEFAULT_UPPER_BOUND ) ) ) )
343 mValue = Clamp( value, DEFAULT_LOWER_BOUND, DEFAULT_UPPER_BOUND );
344 DisplayValue( mValue, true );
349 float ProgressBar::GetProgressValue() const
354 // Static class method to support script connecting signals
355 bool ProgressBar::DoConnectSignal( BaseObject* object, ConnectionTrackerInterface* tracker, const std::string& signalName, FunctorDelegate* functor )
357 Dali::BaseHandle handle( object );
359 bool connected = true;
360 Toolkit::ProgressBar ProgressBar = Toolkit::ProgressBar::DownCast( handle );
362 if( 0 == strcmp( signalName.c_str(), SIGNAL_VALUE_CHANGED ) )
364 ProgressBar.ValueChangedSignal().Connect( tracker, functor );
368 // signalName does not match any signal
375 void ProgressBar::SetProperty( BaseObject* object, Property::Index propertyIndex, const Property::Value& value )
377 Toolkit::ProgressBar progressBar = Toolkit::ProgressBar::DownCast( Dali::BaseHandle( object ) );
381 ProgressBar& progressBarImpl( GetImpl( progressBar ) );
383 switch ( propertyIndex )
385 case Toolkit::ProgressBar::Property::PROGRESS_VALUE:
387 progressBarImpl.SetProgressValue( value.Get< float >() );
391 case Toolkit::ProgressBar::Property::TRACK_VISUAL:
394 if( value.Get( map ) )
396 progressBarImpl.SetTrackVisual( map );
401 case Toolkit::ProgressBar::Property::PROGRESS_VISUAL:
404 if( value.Get( map ) )
406 progressBarImpl.SetProgressVisual( map );
414 Property::Value ProgressBar::GetProperty( BaseObject* object, Property::Index propertyIndex )
416 Property::Value value;
418 Toolkit::ProgressBar progressBar = Toolkit::ProgressBar::DownCast( Dali::BaseHandle( object ) );
422 ProgressBar& progressBarImpl( GetImpl( progressBar ) );
424 switch ( propertyIndex )
426 case Toolkit::ProgressBar::Property::PROGRESS_VALUE:
428 value = progressBarImpl.GetProgressValue();
432 case Toolkit::ProgressBar::Property::TRACK_VISUAL:
434 if( !progressBarImpl.mTrackVisual.empty() )
436 value = progressBarImpl.GetTrackVisual();
438 else if( !progressBarImpl.mTrackMap.Empty() )
440 value = progressBarImpl.mTrackMap;
445 case Toolkit::ProgressBar::Property::PROGRESS_VISUAL:
447 if( !progressBarImpl.mProgressVisual.empty() )
449 value = progressBarImpl.GetProgressVisual();
451 else if( !progressBarImpl.mProgressMap.Empty() )
453 value = progressBarImpl.mProgressMap;
463 } // namespace Internal
465 } // namespace Toolkit