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.
17 #include "shadow-button-impl.h"
18 #include <dali-toolkit/dali-toolkit.h>
19 #include <dali/devel-api/scripting/enum-helper.h>
20 #include <dali-toolkit/devel-api/visual-factory/visual-factory.h>
21 #include <dali-toolkit/devel-api/controls/control-devel.h>
25 using namespace Dali; // Needed for macros
26 using namespace Dali::Toolkit;
37 Dali::BaseHandle Create()
39 return Demo::ShadowButton::New();
42 DALI_TYPE_REGISTRATION_BEGIN( ShadowButton, Dali::Toolkit::Button, Create );
44 DALI_PROPERTY_REGISTRATION( Demo, ShadowButton, "activeTransition", ARRAY, ACTIVE_TRANSITION );
45 DALI_PROPERTY_REGISTRATION( Demo, ShadowButton, "inactiveTransition", ARRAY, INACTIVE_TRANSITION );
46 DALI_PROPERTY_REGISTRATION( Demo, ShadowButton, "checkTransition", ARRAY, CHECK_TRANSITION );
47 DALI_PROPERTY_REGISTRATION( Demo, ShadowButton, "uncheckTransition", ARRAY, UNCHECK_TRANSITION );
48 DALI_PROPERTY_REGISTRATION( Demo, ShadowButton, "backgroundVisual", MAP, BACKGROUND_VISUAL );
49 DALI_PROPERTY_REGISTRATION( Demo, ShadowButton, "checkboxBgVisual", MAP, CHECKBOX_BG_VISUAL );
50 DALI_PROPERTY_REGISTRATION( Demo, ShadowButton, "checkboxFgVisual", MAP, CHECKBOX_FG_VISUAL );
51 DALI_PROPERTY_REGISTRATION( Demo, ShadowButton, "labelVisual", MAP, LABEL_VISUAL );
52 DALI_PROPERTY_REGISTRATION( Demo, ShadowButton, "checkState", BOOLEAN, ACTIVE_STATE );
53 DALI_PROPERTY_REGISTRATION( Demo, ShadowButton, "checkState", BOOLEAN, CHECK_STATE );
55 DALI_TYPE_REGISTRATION_END();
57 DALI_ENUM_TO_STRING_TABLE_BEGIN( VISUAL_PROPERTIES )
58 { "backgroundVisual", Demo::ShadowButton::Property::BACKGROUND_VISUAL },
59 { "checkboxBgVisual", Demo::ShadowButton::Property::CHECKBOX_BG_VISUAL},
60 { "checkboxFgVisual", Demo::ShadowButton::Property::CHECKBOX_FG_VISUAL},
61 { "labelVisual", Demo::ShadowButton::Property::LABEL_VISUAL}
62 DALI_ENUM_TO_STRING_TABLE_END( VISUAL_PROPERTIES )
64 Toolkit::TransitionData ConvertPropertyToTransition( const Property::Value& value )
66 Toolkit::TransitionData transitionData;
68 if( value.GetType() == Property::ARRAY )
70 transitionData = Toolkit::TransitionData::New( *value.GetArray());
72 else if( value.GetType() == Property::MAP )
74 transitionData = Toolkit::TransitionData::New( *value.GetMap() );
76 return transitionData;
79 } // anonymous namespace
82 Internal::ShadowButton::ShadowButton()
83 : Control( ControlBehaviour( REQUIRES_STYLE_CHANGE_SIGNALS ) ),
89 Internal::ShadowButton::~ShadowButton()
93 Demo::ShadowButton Internal::ShadowButton::New()
95 IntrusivePtr<Internal::ShadowButton> impl = new Internal::ShadowButton();
96 Demo::ShadowButton handle = Demo::ShadowButton( *impl );
101 void ShadowButton::SetActiveState( bool active )
103 if( active != mActiveState )
105 mActiveState = active;
108 StartTransition( Demo::ShadowButton::Property::ACTIVE_TRANSITION );
112 StartTransition( Demo::ShadowButton::Property::INACTIVE_TRANSITION );
117 bool ShadowButton::GetActiveState()
122 void ShadowButton::SetCheckState( bool checkState )
124 mCheckState = checkState;
125 DevelControl::EnableVisual( *this, Demo::ShadowButton::Property::CHECKBOX_FG_VISUAL, true );
126 if( Self().OnStage() )
130 StartTransition( Demo::ShadowButton::Property::CHECK_TRANSITION );
134 StartTransition( Demo::ShadowButton::Property::UNCHECK_TRANSITION );
140 bool ShadowButton::GetCheckState()
145 void ShadowButton::StartTransition( Property::Index transitionId )
147 Transitions::iterator iter = FindTransition( transitionId );
148 if( iter != mTransitions.end() )
150 if( iter->mAnimation )
152 iter->mAnimation.Stop();
153 iter->mPlaying = false;
155 iter->mAnimation.FinishedSignal().Disconnect( this, &ShadowButton::OnTransitionFinished );
158 iter->mAnimation = DevelControl::CreateTransition( *this, iter->mTransitionData );
159 StoreTargetLayouts( iter->mTransitionData );
161 iter->mAnimation.FinishedSignal().Connect( this, &ShadowButton::OnTransitionFinished );
162 iter->mAnimation.Play();
163 iter->mPlaying = true;
167 void ShadowButton::OnTransitionFinished( Animation& src )
169 ShadowButton::Transitions::iterator iter = mTransitions.begin();
170 for( ; iter != mTransitions.end(); ++iter )
172 if( iter->mAnimation == src )
174 iter->mPlaying = false;
175 iter->mAnimation.Reset(); // Remove the animation when it's finished.
176 switch( iter->mTransitionId )
178 case Demo::ShadowButton::Property::ACTIVE_TRANSITION:
180 // Consider relayouting the text.
183 case Demo::ShadowButton::Property::INACTIVE_TRANSITION:
185 // Consider relayouting the text.
188 case Demo::ShadowButton::Property::UNCHECK_TRANSITION:
190 DevelControl::EnableVisual( *this, Demo::ShadowButton::Property::CHECKBOX_FG_VISUAL, false );
199 void ShadowButton::OnInitialize()
204 void ShadowButton::OnStageConnection( int depth )
206 Control::OnStageConnection( depth );
209 void ShadowButton::OnStageDisconnection()
211 Control::OnStageDisconnection();
214 void ShadowButton::OnSizeSet( const Vector3& targetSize )
216 Control::OnSizeSet( targetSize );
217 RelayoutVisuals( Vector2( targetSize ) );
220 void ShadowButton::OnRelayout( const Vector2& targetSize, RelayoutContainer& container )
222 RelayoutVisuals( targetSize );
225 void ShadowButton::RelayoutVisuals( const Vector2& targetSize )
227 bool transitioning = false;
228 ShadowButton::Transitions::iterator iter = mTransitions.begin();
229 for( ; iter != mTransitions.end(); ++iter )
231 if( iter->mPlaying == true )
233 transitioning = true;
238 if( ! transitioning )
240 for( ShadowButton::Transforms::iterator iter = mTransforms.begin();
241 iter != mTransforms.end(); ++iter )
243 switch( iter->mTransformId )
245 case Demo::ShadowButton::Property::BACKGROUND_VISUAL:
247 mBackgroundVisual.SetTransformAndSize( iter->mTransform, targetSize );
250 case Demo::ShadowButton::Property::CHECKBOX_BG_VISUAL:
252 mCheckboxBgVisual.SetTransformAndSize( iter->mTransform, targetSize );
255 case Demo::ShadowButton::Property::CHECKBOX_FG_VISUAL:
257 mCheckboxFgVisual.SetTransformAndSize( iter->mTransform, targetSize );
260 case Demo::ShadowButton::Property::LABEL_VISUAL:
262 mLabelVisual.SetTransformAndSize( iter->mTransform, targetSize );
270 Vector3 ShadowButton::GetNaturalSize()
275 Vector2 checkboxBgSize;
276 Vector2 checkboxFgSize;
278 mCheckboxBgVisual.GetNaturalSize( checkboxBgSize );
279 mCheckboxFgVisual.GetNaturalSize( checkboxFgSize );
280 mLabelVisual.GetNaturalSize( labelSize );
282 width = std::max( checkboxBgSize.x, checkboxFgSize.x ) + labelSize.x;
283 height = std::max( std::max( checkboxFgSize.y, checkboxBgSize.y ), labelSize.y );
285 return Vector3( width, height, height );
288 void ShadowButton::OnStyleChange( Toolkit::StyleManager styleManager, StyleChange::Type change )
291 Control::OnStyleChange( styleManager, change );
294 ShadowButton::Transitions::iterator ShadowButton::FindTransition( Property::Index index )
297 ShadowButton::Transitions::iterator iter = mTransitions.begin();
298 for( ; iter != mTransitions.end(); ++iter )
300 if( iter->mTransitionId == index )
308 iter = mTransitions.end();
313 ShadowButton::Transforms::iterator ShadowButton::FindTransform( Property::Index index )
316 ShadowButton::Transforms::iterator iter = mTransforms.begin();
317 for( ; iter != mTransforms.end(); ++iter )
319 if( iter->mTransformId == index )
327 iter = mTransforms.end();
332 void ShadowButton::ResetVisual(
333 Property::Index index,
334 Visual::Base& visual,
335 const Property::Value& value )
339 // we are replacing an existing visual, so force relayout
342 Property::Map* map = value.GetMap();
345 visual = Toolkit::VisualFactory::Get().CreateVisual( *map );
347 // Set the appropriate depth index.
348 // @todo Should be able to set this from the style sheet
351 case Demo::ShadowButton::Property::BACKGROUND_VISUAL:
353 DevelControl::RegisterVisual( *this, index, visual, 0 );
356 case Demo::ShadowButton::Property::CHECKBOX_BG_VISUAL:
358 DevelControl::RegisterVisual( *this, index, visual, 1 );
361 case Demo::ShadowButton::Property::CHECKBOX_FG_VISUAL:
363 DevelControl::RegisterVisual( *this, index, visual, mCheckState, 2 );
366 case Demo::ShadowButton::Property::LABEL_VISUAL:
368 DevelControl::RegisterVisual( *this, index, visual, 1 );
373 // Extract transform maps out of the visual definition and store them
374 Property::Value* value = map->Find( Visual::Property::TRANSFORM, "transform");
377 Property::Map* transformMap = value->GetMap();
380 ShadowButton::Transforms::iterator iter = FindTransform( index );
381 if( iter != mTransforms.end() )
383 iter->mTransform = *transformMap;
387 mTransforms.push_back( Transform( index, *transformMap ) );
394 bool IsTransformProperty( const std::string& property )
396 const char* transformProperties[]= { "size", "offset", "origin", "anchorPoint", "offsetPolicy", "sizePolicy" };
397 const int NUM_TRANSFORM_PROPERTIES = sizeof( transformProperties ) / sizeof( const char * );
400 for( int i=0; i<NUM_TRANSFORM_PROPERTIES; ++i )
402 if( property == transformProperties[i] )
411 void ShadowButton::StoreTargetLayouts( TransitionData transitionData )
414 // foreach animator in transitionData
415 // if animator{"property"} in [ "size", "offset", "origin", "anchorPoint", "offsetPolicy", "sizePolicy" ]
416 // transforms{ animator{"target"} }->{animator{"property"}} = animator{"targetValue"}
419 for( unsigned int i=0; i < transitionData.Count(); ++i )
421 Property::Map animator = transitionData.GetAnimatorAt(i);
422 Property::Value* target = animator.Find( "target" );
426 Property::Index index = Property::INVALID_INDEX;
427 if( Scripting::GetEnumerationProperty( *target, VISUAL_PROPERTIES_TABLE, VISUAL_PROPERTIES_TABLE_COUNT, index ) )
429 ShadowButton::Transforms::iterator iter = FindTransform( index );
430 if( iter != mTransforms.end() )
432 Property::Value* property = animator.Find( "property" );
435 std::string propertyString;
436 property->Get(propertyString);
437 if( IsTransformProperty( propertyString ) )
439 Property::Value* targetValue = animator.Find( "targetValue" );
442 iter->mTransform[ propertyString ] = *targetValue;
452 void ShadowButton::ResetTransition(
453 Property::Index index,
454 const Property::Value& value)
456 ShadowButton::Transitions::iterator iter = FindTransition( index );
457 if( iter != mTransitions.end() )
460 iter->mTransitionData = ConvertPropertyToTransition( value );
461 iter->mAnimation.Stop();
462 iter->mAnimation.Clear();
466 mTransitions.push_back( Transition( index, ConvertPropertyToTransition( value ) ) );
471 void ShadowButton::SetProperty( BaseObject* object, Property::Index index, const Property::Value& value )
473 Demo::ShadowButton shadowButton = Demo::ShadowButton::DownCast( Dali::BaseHandle( object ) );
477 ShadowButton& impl = GetImpl( shadowButton );
480 case Demo::ShadowButton::Property::BACKGROUND_VISUAL:
482 impl.ResetVisual( index, impl.mBackgroundVisual, value );
485 case Demo::ShadowButton::Property::CHECKBOX_BG_VISUAL:
487 impl.ResetVisual( index, impl.mCheckboxBgVisual, value );
490 case Demo::ShadowButton::Property::CHECKBOX_FG_VISUAL:
492 impl.ResetVisual( index, impl.mCheckboxFgVisual, value );
493 DevelControl::EnableVisual( impl, Demo::ShadowButton::Property::CHECKBOX_FG_VISUAL, impl.mCheckState );
496 case Demo::ShadowButton::Property::LABEL_VISUAL:
498 impl.ResetVisual( index, impl.mLabelVisual, value );
501 case Demo::ShadowButton::Property::ACTIVE_TRANSITION:
502 case Demo::ShadowButton::Property::INACTIVE_TRANSITION:
503 case Demo::ShadowButton::Property::CHECK_TRANSITION:
504 case Demo::ShadowButton::Property::UNCHECK_TRANSITION:
506 impl.ResetTransition( index, value );
513 Property::Value ShadowButton::GetProperty( BaseObject* object, Property::Index propertyIndex )
515 Property::Value value;
517 Demo::ShadowButton shadowButton = Demo::ShadowButton::DownCast( Dali::BaseHandle( object ) );
521 ShadowButton& impl = GetImpl( shadowButton );
522 switch ( propertyIndex )
524 case Demo::ShadowButton::Property::BACKGROUND_VISUAL:
527 impl.mBackgroundVisual.CreatePropertyMap(map);
531 case Demo::ShadowButton::Property::CHECKBOX_BG_VISUAL:
534 impl.mCheckboxBgVisual.CreatePropertyMap(map);
538 case Demo::ShadowButton::Property::CHECKBOX_FG_VISUAL:
541 impl.mCheckboxFgVisual.CreatePropertyMap(map);
545 case Demo::ShadowButton::Property::LABEL_VISUAL:
548 impl.mLabelVisual.CreatePropertyMap(map);