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;
63 } // Unnamed namespace
65 ///////////////////////////////////////////////////////////////////////////////////////////////////
67 ///////////////////////////////////////////////////////////////////////////////////////////////////
69 Dali::Toolkit::ProgressBar ProgressBar::New()
71 // Create the implementation
72 ProgressBarPtr progressBar( new ProgressBar() );
74 // Pass ownership to CustomActor via derived handle
75 Dali::Toolkit::ProgressBar handle( *progressBar );
77 // Second-phase init of the implementation
78 // This can only be done after the CustomActor connection has been made...
79 progressBar->Initialize();
84 ProgressBar::ProgressBar()
85 : Control( ControlBehaviour( CONTROL_BEHAVIOUR_DEFAULT ) ),
90 mProgressVisualSize(),
91 mValue( DEFAULT_VALUE )
95 ProgressBar::~ProgressBar()
99 void ProgressBar::OnInitialize()
105 SetTrackVisual( SKINNED_TRACK_VISUAL );
106 SetProgressVisual( SKINNED_PROGRESS_VISUAL );
108 DisplayValue( mValue, false ); // Run this last to display the correct value
111 void ProgressBar::OnRelayout( const Vector2& size, RelayoutContainer& container )
116 container.Add( mTrack, size );
118 // mValueTextLabel will have its relayout method called automatically as it's a child of mTrack,
119 // which is added to the container
125 mDomain = CalcDomain( size );
127 Vector2 progressSize( size );
129 // If no progress, then we do not want a n-patch image shown incorrectly
130 progressSize.width = std::max( mProgressVisualSize.width, mDomain.from.x + mValue * ( mDomain.to.x - mDomain.from.x ) );
131 progressSize.width = std::min( progressSize.width, size.width ); // We should not exceed given size
133 container.Add( mProgress, progressSize );
137 Vector3 ProgressBar::GetNaturalSize()
139 // Return the maximum width/height combinations of our visuals
142 naturalSize.width = std::max( mTrackVisualSize.width, mProgressVisualSize.width );
143 naturalSize.height = std::max( mTrackVisualSize.height, mProgressVisualSize.height );
147 ProgressBar::Domain ProgressBar::CalcDomain( const Vector2& currentSize )
149 return Domain( Vector2( 0.0f, 0.0f ), currentSize );
152 void ProgressBar::DisplayValue( float value, bool raiseSignals )
157 Toolkit::ProgressBar self = Toolkit::ProgressBar::DownCast( Self() );
158 mValueChangedSignal.Emit( self, value );
161 // Change the value of the text label
162 if( mValueTextLabel )
164 std::stringstream ss;
166 ss << std::fixed << ( value * 100 ) << "%";
168 std::string label = mValueTextLabel.GetProperty<std::string>( Toolkit::TextLabel::Property::TEXT );
169 if( label.compare(ss.str()) )
171 mValueTextLabel.SetProperty( Toolkit::TextLabel::Property::TEXT, ss.str() );
176 Toolkit::ImageView ProgressBar::CreateTrack()
178 Toolkit::ImageView track = Toolkit::ImageView::New();
179 track.SetParentOrigin( ParentOrigin::CENTER );
180 track.SetAnchorPoint( AnchorPoint::CENTER );
181 track.SetResizePolicy(ResizePolicy::USE_ASSIGNED_SIZE, Dimension::ALL_DIMENSIONS );
186 void ProgressBar::SetTrackVisual( const std::string& filename )
188 if( mTrack && filename.size() > 0 )
190 mTrack.SetImage( filename );
191 mTrackVisual = filename;
192 mTrackVisualSize = Vector2::ZERO;
197 void ProgressBar::SetTrackVisual( Property::Map map )
199 bool relayoutRequired = false;
201 Property::Value* imageValue = map.Find( "url" );
204 mTrackVisual.clear();
205 std::string filename;
206 if( imageValue->Get( filename ) )
208 if( mTrack && ( filename.size() > 0 ) )
210 mTrack.SetImage( filename );
212 relayoutRequired = true;
217 Property::Value* sizeValue = map.Find( "size" );
221 if( sizeValue->Get( size ) )
223 mTrackVisualSize = size;
224 relayoutRequired = true;
228 // Visual and/or visual size changed so we need to relayout
229 if( relayoutRequired )
235 std::string ProgressBar::GetTrackVisual()
240 Toolkit::ImageView ProgressBar::CreateProgress()
242 Toolkit::ImageView progress = Toolkit::ImageView::New();
243 progress.SetParentOrigin( ParentOrigin::CENTER_LEFT );
244 progress.SetAnchorPoint( AnchorPoint::CENTER_LEFT );
245 progress.SetResizePolicy(ResizePolicy::USE_ASSIGNED_SIZE, Dimension::ALL_DIMENSIONS );
250 void ProgressBar::SetProgressVisual( const std::string& filename )
252 if( mProgress && ( filename.size() > 0 ) )
254 mProgress.SetImage( filename );
255 mProgressVisual = filename;
256 mProgressVisualSize = Vector2::ZERO;
261 void ProgressBar::SetProgressVisual( Property::Map map )
263 bool relayoutRequired = false;
265 Property::Value* imageValue = map.Find( "url" );
268 mProgressVisual.clear();
269 std::string filename;
270 if( imageValue->Get( filename ) )
272 if( mProgress && ( filename.size() > 0 ) )
274 mProgress.SetImage( filename );
276 relayoutRequired = true;
281 Property::Value* sizeValue = map.Find( "size" );
285 if( sizeValue->Get( size ) )
287 mProgressVisualSize = size;
288 relayoutRequired = true;
292 // Visual and/or visual size changed so we need to relayout
293 if( relayoutRequired )
299 std::string ProgressBar::GetProgressVisual()
301 return mProgressVisual;
304 Toolkit::ProgressBar::ValueChangedSignalType& ProgressBar::ValueChangedSignal()
306 return mValueChangedSignal;
309 void ProgressBar::CreateChildren()
314 mTrack = CreateTrack();
315 self.Add( mTrack ); // Needs to be a direct child as we want to manipulate its size
318 mProgress = CreateProgress();
319 self.Add( mProgress ); // Needs to be a direct child as we want to manipulate its size
322 mValueTextLabel = Toolkit::TextLabel::New();
323 mValueTextLabel.SetName( "ProgressBarValueTextLabel" );
324 mValueTextLabel.SetStyleName( "ProgressBarValueTextLabel" );
325 mValueTextLabel.SetParentOrigin( ParentOrigin::CENTER );
326 mValueTextLabel.SetAnchorPoint( AnchorPoint::CENTER );
327 mValueTextLabel.SetProperty( Toolkit::TextLabel::Property::HORIZONTAL_ALIGNMENT, "CENTER" );
328 mValueTextLabel.SetProperty( Toolkit::TextLabel::Property::VERTICAL_ALIGNMENT, "CENTER" );
329 mTrack.Add( mValueTextLabel ); // Add to mTrack and let it automatically set its size
332 void ProgressBar::SetProgressValue( float value )
334 // update the progress bar value (taking float precision errors into account)
335 if( ( mValue != value ) &&
336 ( ( value >= DEFAULT_LOWER_BOUND ) || ( Equals( value, DEFAULT_LOWER_BOUND ) ) ) &&
337 ( ( value <= DEFAULT_UPPER_BOUND ) || ( Equals( value, DEFAULT_UPPER_BOUND ) ) ) )
339 mValue = Clamp( value, DEFAULT_LOWER_BOUND, DEFAULT_UPPER_BOUND );
340 DisplayValue( mValue, true );
345 float ProgressBar::GetProgressValue() const
350 // Static class method to support script connecting signals
351 bool ProgressBar::DoConnectSignal( BaseObject* object, ConnectionTrackerInterface* tracker, const std::string& signalName, FunctorDelegate* functor )
353 Dali::BaseHandle handle( object );
355 bool connected = true;
356 Toolkit::ProgressBar ProgressBar = Toolkit::ProgressBar::DownCast( handle );
358 if( 0 == strcmp( signalName.c_str(), SIGNAL_VALUE_CHANGED ) )
360 ProgressBar.ValueChangedSignal().Connect( tracker, functor );
364 // signalName does not match any signal
371 void ProgressBar::SetProperty( BaseObject* object, Property::Index propertyIndex, const Property::Value& value )
373 Toolkit::ProgressBar progressBar = Toolkit::ProgressBar::DownCast( Dali::BaseHandle( object ) );
377 ProgressBar& progressBarImpl( GetImpl( progressBar ) );
379 switch ( propertyIndex )
381 case Toolkit::ProgressBar::Property::PROGRESS_VALUE:
383 progressBarImpl.SetProgressValue( value.Get< float >() );
387 case Toolkit::ProgressBar::Property::TRACK_VISUAL:
390 if( value.Get( map ) )
392 progressBarImpl.SetTrackVisual( map );
397 case Toolkit::ProgressBar::Property::PROGRESS_VISUAL:
400 if( value.Get( map ) )
402 progressBarImpl.SetProgressVisual( map );
410 Property::Value ProgressBar::GetProperty( BaseObject* object, Property::Index propertyIndex )
412 Property::Value value;
414 Toolkit::ProgressBar progressBar = Toolkit::ProgressBar::DownCast( Dali::BaseHandle( object ) );
418 ProgressBar& progressBarImpl( GetImpl( progressBar ) );
420 switch ( propertyIndex )
422 case Toolkit::ProgressBar::Property::PROGRESS_VALUE:
424 value = progressBarImpl.GetProgressValue();
428 case Toolkit::ProgressBar::Property::TRACK_VISUAL:
430 if( !progressBarImpl.mTrackVisual.empty() )
432 value = progressBarImpl.GetTrackVisual();
434 else if( !progressBarImpl.mTrackMap.Empty() )
436 value = progressBarImpl.mTrackMap;
441 case Toolkit::ProgressBar::Property::PROGRESS_VISUAL:
443 if( !progressBarImpl.mProgressVisual.empty() )
445 value = progressBarImpl.GetProgressVisual();
447 else if( !progressBarImpl.mProgressMap.Empty() )
449 value = progressBarImpl.mProgressMap;
459 } // namespace Internal
461 } // namespace Toolkit