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/public-api/object/type-registry-helper.h>
20 #include <dali/devel-api/scripting/enum-helper.h>
21 #include <dali-toolkit/devel-api/align-enums.h>
22 #include <dali-toolkit/devel-api/visual-factory/visual-factory.h>
23 #include <dali-toolkit/devel-api/visuals/visual-properties-devel.h>
27 using namespace Dali; // Needed for macros
28 using namespace Dali::Toolkit;
39 Dali::BaseHandle Create()
41 return Demo::ShadowButton::New();
44 DALI_TYPE_REGISTRATION_BEGIN( ShadowButton, Dali::Toolkit::Button, Create );
46 DALI_PROPERTY_REGISTRATION( Demo, ShadowButton, "activeTransition", ARRAY, ACTIVE_TRANSITION );
47 DALI_PROPERTY_REGISTRATION( Demo, ShadowButton, "inactiveTransition", ARRAY, INACTIVE_TRANSITION );
48 DALI_PROPERTY_REGISTRATION( Demo, ShadowButton, "checkTransition", ARRAY, CHECK_TRANSITION );
49 DALI_PROPERTY_REGISTRATION( Demo, ShadowButton, "uncheckTransition", ARRAY, UNCHECK_TRANSITION );
50 DALI_PROPERTY_REGISTRATION( Demo, ShadowButton, "backgroundVisual", MAP, BACKGROUND_VISUAL );
51 DALI_PROPERTY_REGISTRATION( Demo, ShadowButton, "checkboxBgVisual", MAP, CHECKBOX_BG_VISUAL );
52 DALI_PROPERTY_REGISTRATION( Demo, ShadowButton, "checkboxFgVisual", MAP, CHECKBOX_FG_VISUAL );
53 DALI_PROPERTY_REGISTRATION( Demo, ShadowButton, "labelVisual", MAP, LABEL_VISUAL );
54 DALI_PROPERTY_REGISTRATION( Demo, ShadowButton, "checkState", BOOLEAN, ACTIVE_STATE );
55 DALI_PROPERTY_REGISTRATION( Demo, ShadowButton, "checkState", BOOLEAN, CHECK_STATE );
57 DALI_TYPE_REGISTRATION_END();
59 DALI_ENUM_TO_STRING_TABLE_BEGIN( VISUAL_PROPERTIES )
60 { "backgroundVisual", Demo::ShadowButton::Property::BACKGROUND_VISUAL },
61 { "checkboxBgVisual", Demo::ShadowButton::Property::CHECKBOX_BG_VISUAL},
62 { "checkboxFgVisual", Demo::ShadowButton::Property::CHECKBOX_FG_VISUAL},
63 { "labelVisual", Demo::ShadowButton::Property::LABEL_VISUAL}
64 DALI_ENUM_TO_STRING_TABLE_END( VISUAL_PROPERTIES )
66 Toolkit::TransitionData ConvertPropertyToTransition( const Property::Value& value )
68 Toolkit::TransitionData transitionData;
70 if( value.GetType() == Property::ARRAY )
72 transitionData = Toolkit::TransitionData::New( *value.GetArray());
74 else if( value.GetType() == Property::MAP )
76 transitionData = Toolkit::TransitionData::New( *value.GetMap() );
78 return transitionData;
81 } // anonymous namespace
84 Internal::ShadowButton::ShadowButton()
85 : Control( ControlBehaviour( REQUIRES_STYLE_CHANGE_SIGNALS ) ),
91 Internal::ShadowButton::~ShadowButton()
95 Demo::ShadowButton Internal::ShadowButton::New()
97 IntrusivePtr<Internal::ShadowButton> impl = new Internal::ShadowButton();
98 Demo::ShadowButton handle = Demo::ShadowButton( *impl );
103 void ShadowButton::SetActiveState( bool active )
105 if( active != mActiveState )
107 mActiveState = active;
110 StartTransition( Demo::ShadowButton::Property::ACTIVE_TRANSITION );
114 StartTransition( Demo::ShadowButton::Property::INACTIVE_TRANSITION );
119 bool ShadowButton::GetActiveState()
124 void ShadowButton::SetCheckState( bool checkState )
126 mCheckState = checkState;
127 EnableVisual( Demo::ShadowButton::Property::CHECKBOX_FG_VISUAL, true );
128 if( Self().OnStage() )
132 StartTransition( Demo::ShadowButton::Property::CHECK_TRANSITION );
136 StartTransition( Demo::ShadowButton::Property::UNCHECK_TRANSITION );
142 bool ShadowButton::GetCheckState()
147 void ShadowButton::StartTransition( Property::Index transitionId )
149 Transitions::iterator iter = FindTransition( transitionId );
150 if( iter != mTransitions.end() )
152 if( iter->mAnimation )
154 iter->mAnimation.Stop();
155 iter->mPlaying = false;
157 iter->mAnimation.FinishedSignal().Disconnect( this, &ShadowButton::OnTransitionFinished );
160 iter->mAnimation = CreateTransition( iter->mTransitionData );
161 StoreTargetLayouts( iter->mTransitionData );
163 iter->mAnimation.FinishedSignal().Connect( this, &ShadowButton::OnTransitionFinished );
164 iter->mAnimation.Play();
165 iter->mPlaying = true;
169 void ShadowButton::OnTransitionFinished( Animation& src )
171 ShadowButton::Transitions::iterator iter = mTransitions.begin();
172 for( ; iter != mTransitions.end(); ++iter )
174 if( iter->mAnimation == src )
176 iter->mPlaying = false;
177 iter->mAnimation.Reset(); // Remove the animation when it's finished.
178 switch( iter->mTransitionId )
180 case Demo::ShadowButton::Property::ACTIVE_TRANSITION:
182 // Consider relayouting the text.
185 case Demo::ShadowButton::Property::INACTIVE_TRANSITION:
187 // Consider relayouting the text.
190 case Demo::ShadowButton::Property::UNCHECK_TRANSITION:
192 EnableVisual( Demo::ShadowButton::Property::CHECKBOX_FG_VISUAL, false );
201 void ShadowButton::OnInitialize()
206 void ShadowButton::OnStageConnection( int depth )
208 Control::OnStageConnection( depth );
211 void ShadowButton::OnStageDisconnection()
213 Control::OnStageDisconnection();
216 void ShadowButton::OnSizeSet( const Vector3& targetSize )
218 Control::OnSizeSet( targetSize );
219 RelayoutVisuals( Vector2( targetSize ) );
222 void ShadowButton::OnRelayout( const Vector2& targetSize, RelayoutContainer& container )
224 RelayoutVisuals( targetSize );
227 void ShadowButton::RelayoutVisuals( const Vector2& targetSize )
229 bool transitioning = false;
230 ShadowButton::Transitions::iterator iter = mTransitions.begin();
231 for( ; iter != mTransitions.end(); ++iter )
233 if( iter->mPlaying == true )
235 transitioning = true;
240 if( ! transitioning )
242 for( ShadowButton::Transforms::iterator iter = mTransforms.begin();
243 iter != mTransforms.end(); ++iter )
245 switch( iter->mTransformId )
247 case Demo::ShadowButton::Property::BACKGROUND_VISUAL:
249 mBackgroundVisual.SetTransformAndSize( iter->mTransform, targetSize );
252 case Demo::ShadowButton::Property::CHECKBOX_BG_VISUAL:
254 mCheckboxBgVisual.SetTransformAndSize( iter->mTransform, targetSize );
257 case Demo::ShadowButton::Property::CHECKBOX_FG_VISUAL:
259 mCheckboxFgVisual.SetTransformAndSize( iter->mTransform, targetSize );
262 case Demo::ShadowButton::Property::LABEL_VISUAL:
264 mLabelVisual.SetTransformAndSize( iter->mTransform, targetSize );
272 Vector3 ShadowButton::GetNaturalSize()
277 Vector2 checkboxBgSize;
278 Vector2 checkboxFgSize;
280 mCheckboxBgVisual.GetNaturalSize( checkboxBgSize );
281 mCheckboxFgVisual.GetNaturalSize( checkboxFgSize );
282 mLabelVisual.GetNaturalSize( labelSize );
284 width = std::max( checkboxBgSize.x, checkboxFgSize.x ) + labelSize.x;
285 height = std::max( std::max( checkboxFgSize.y, checkboxBgSize.y ), labelSize.y );
287 return Vector3( width, height, height );
290 void ShadowButton::OnStyleChange( Toolkit::StyleManager styleManager, StyleChange::Type change )
293 Control::OnStyleChange( styleManager, change );
296 ShadowButton::Transitions::iterator ShadowButton::FindTransition( Property::Index index )
299 ShadowButton::Transitions::iterator iter = mTransitions.begin();
300 for( ; iter != mTransitions.end(); ++iter )
302 if( iter->mTransitionId == index )
310 iter = mTransitions.end();
315 ShadowButton::Transforms::iterator ShadowButton::FindTransform( Property::Index index )
318 ShadowButton::Transforms::iterator iter = mTransforms.begin();
319 for( ; iter != mTransforms.end(); ++iter )
321 if( iter->mTransformId == index )
329 iter = mTransforms.end();
334 void ShadowButton::ResetVisual(
335 Property::Index index,
336 Visual::Base& visual,
337 const Property::Value& value )
341 // we are replacing an existing visual, so force relayout
344 Property::Map* map = value.GetMap();
347 visual = Toolkit::VisualFactory::Get().CreateVisual( *map );
349 // Set the appropriate depth index.
350 // @todo Should be able to set this from the style sheet
353 case Demo::ShadowButton::Property::BACKGROUND_VISUAL:
355 RegisterVisual( index, visual );
356 visual.SetDepthIndex(0.0f);
359 case Demo::ShadowButton::Property::CHECKBOX_BG_VISUAL:
361 RegisterVisual( index, visual );
362 visual.SetDepthIndex(1.0f);
365 case Demo::ShadowButton::Property::CHECKBOX_FG_VISUAL:
367 RegisterVisual( index, visual, mCheckState );
368 visual.SetDepthIndex(2.0f);
371 case Demo::ShadowButton::Property::LABEL_VISUAL:
373 RegisterVisual( index, visual );
374 visual.SetDepthIndex(1.0f);
379 // Extract transform maps out of the visual definition and store them
380 Property::Value* value = map->Find( DevelVisual::Property::TRANSFORM, "transform");
383 Property::Map* transformMap = value->GetMap();
386 ShadowButton::Transforms::iterator iter = FindTransform( index );
387 if( iter != mTransforms.end() )
389 iter->mTransform = *transformMap;
393 mTransforms.push_back( Transform( index, *transformMap ) );
400 bool IsTransformProperty( const std::string& property )
402 const char* transformProperties[]= { "size", "offset", "origin", "anchorPoint", "offsetSizeMode" };
403 const int NUM_TRANSFORM_PROPERTIES = sizeof( transformProperties ) / sizeof( const char * );
406 for( int i=0; i<NUM_TRANSFORM_PROPERTIES; ++i )
408 if( property == transformProperties[i] )
417 void ShadowButton::StoreTargetLayouts( TransitionData transitionData )
420 // foreach animator in transitionData
421 // if animator{"property"} in [ "size", "offset", "origin", "anchorPoint", "offsetSizeMode" ]
422 // transforms{ animator{"target"} }->{animator{"property"}} = animator{"targetValue"}
425 for( unsigned int i=0; i < transitionData.Count(); ++i )
427 Property::Map animator = transitionData.GetAnimatorAt(i);
428 Property::Value* target = animator.Find( "target" );
432 Property::Index index;
433 if( Scripting::GetEnumerationProperty( *target, VISUAL_PROPERTIES_TABLE, VISUAL_PROPERTIES_TABLE_COUNT, index ) )
435 ShadowButton::Transforms::iterator iter = FindTransform( index );
436 if( iter != mTransforms.end() )
438 Property::Value* property = animator.Find( "property" );
441 std::string propertyString;
442 property->Get(propertyString);
443 if( IsTransformProperty( propertyString ) )
445 Property::Value* targetValue = animator.Find( "targetValue" );
448 iter->mTransform[ propertyString ] = *targetValue;
458 void ShadowButton::ResetTransition(
459 Property::Index index,
460 const Property::Value& value)
462 ShadowButton::Transitions::iterator iter = FindTransition( index );
463 if( iter != mTransitions.end() )
466 iter->mTransitionData = ConvertPropertyToTransition( value );
467 iter->mAnimation.Stop();
468 iter->mAnimation.Clear();
472 mTransitions.push_back( Transition( index, ConvertPropertyToTransition( value ) ) );
477 void ShadowButton::SetProperty( BaseObject* object, Property::Index index, const Property::Value& value )
479 Demo::ShadowButton shadowButton = Demo::ShadowButton::DownCast( Dali::BaseHandle( object ) );
483 ShadowButton& impl = GetImpl( shadowButton );
486 case Demo::ShadowButton::Property::BACKGROUND_VISUAL:
488 impl.ResetVisual( index, impl.mBackgroundVisual, value );
491 case Demo::ShadowButton::Property::CHECKBOX_BG_VISUAL:
493 impl.ResetVisual( index, impl.mCheckboxBgVisual, value );
496 case Demo::ShadowButton::Property::CHECKBOX_FG_VISUAL:
498 impl.ResetVisual( index, impl.mCheckboxFgVisual, value );
499 impl.EnableVisual( Demo::ShadowButton::Property::CHECKBOX_FG_VISUAL, impl.mCheckState );
502 case Demo::ShadowButton::Property::LABEL_VISUAL:
504 impl.ResetVisual( index, impl.mLabelVisual, value );
507 case Demo::ShadowButton::Property::ACTIVE_TRANSITION:
508 case Demo::ShadowButton::Property::INACTIVE_TRANSITION:
509 case Demo::ShadowButton::Property::CHECK_TRANSITION:
510 case Demo::ShadowButton::Property::UNCHECK_TRANSITION:
512 impl.ResetTransition( index, value );
519 Property::Value ShadowButton::GetProperty( BaseObject* object, Property::Index propertyIndex )
521 Property::Value value;
523 Demo::ShadowButton shadowButton = Demo::ShadowButton::DownCast( Dali::BaseHandle( object ) );
527 ShadowButton& impl = GetImpl( shadowButton );
528 switch ( propertyIndex )
530 case Demo::ShadowButton::Property::BACKGROUND_VISUAL:
533 impl.mBackgroundVisual.CreatePropertyMap(map);
537 case Demo::ShadowButton::Property::CHECKBOX_BG_VISUAL:
540 impl.mCheckboxBgVisual.CreatePropertyMap(map);
544 case Demo::ShadowButton::Property::CHECKBOX_FG_VISUAL:
547 impl.mCheckboxFgVisual.CreatePropertyMap(map);
551 case Demo::ShadowButton::Property::LABEL_VISUAL:
554 impl.mLabelVisual.CreatePropertyMap(map);