2 * Copyright (c) 2020 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-toolkit/devel-api/controls/control-devel.h>
20 #include <dali-toolkit/devel-api/visual-factory/visual-factory.h>
21 #include <dali/devel-api/scripting/enum-helper.h>
25 using namespace Dali; // Needed for macros
26 using namespace Dali::Toolkit;
34 Dali::BaseHandle Create()
36 return Demo::ShadowButton::New();
39 DALI_TYPE_REGISTRATION_BEGIN(ShadowButton, Dali::Toolkit::Button, Create);
41 DALI_PROPERTY_REGISTRATION(Demo, ShadowButton, "activeTransition", ARRAY, ACTIVE_TRANSITION);
42 DALI_PROPERTY_REGISTRATION(Demo, ShadowButton, "inactiveTransition", ARRAY, INACTIVE_TRANSITION);
43 DALI_PROPERTY_REGISTRATION(Demo, ShadowButton, "checkTransition", ARRAY, CHECK_TRANSITION);
44 DALI_PROPERTY_REGISTRATION(Demo, ShadowButton, "uncheckTransition", ARRAY, UNCHECK_TRANSITION);
45 DALI_PROPERTY_REGISTRATION(Demo, ShadowButton, "backgroundVisual", MAP, BACKGROUND_VISUAL);
46 DALI_PROPERTY_REGISTRATION(Demo, ShadowButton, "checkboxBgVisual", MAP, CHECKBOX_BG_VISUAL);
47 DALI_PROPERTY_REGISTRATION(Demo, ShadowButton, "checkboxFgVisual", MAP, CHECKBOX_FG_VISUAL);
48 DALI_PROPERTY_REGISTRATION(Demo, ShadowButton, "labelVisual", MAP, LABEL_VISUAL);
49 DALI_PROPERTY_REGISTRATION(Demo, ShadowButton, "checkState", BOOLEAN, ACTIVE_STATE);
50 DALI_PROPERTY_REGISTRATION(Demo, ShadowButton, "checkState", BOOLEAN, CHECK_STATE);
52 DALI_TYPE_REGISTRATION_END();
54 DALI_ENUM_TO_STRING_TABLE_BEGIN(VISUAL_PROPERTIES)
55 {"backgroundVisual", Demo::ShadowButton::Property::BACKGROUND_VISUAL},
56 {"checkboxBgVisual", Demo::ShadowButton::Property::CHECKBOX_BG_VISUAL},
57 {"checkboxFgVisual", Demo::ShadowButton::Property::CHECKBOX_FG_VISUAL},
58 {"labelVisual", Demo::ShadowButton::Property::LABEL_VISUAL}
59 DALI_ENUM_TO_STRING_TABLE_END(VISUAL_PROPERTIES)
61 Toolkit::TransitionData ConvertPropertyToTransition(const Property::Value& value)
63 Toolkit::TransitionData transitionData;
65 if(value.GetType() == Property::ARRAY)
67 transitionData = Toolkit::TransitionData::New(*value.GetArray());
69 else if(value.GetType() == Property::MAP)
71 transitionData = Toolkit::TransitionData::New(*value.GetMap());
73 return transitionData;
76 } // anonymous namespace
78 Internal::ShadowButton::ShadowButton()
79 : Control(ControlBehaviour(CONTROL_BEHAVIOUR_DEFAULT)),
85 Internal::ShadowButton::~ShadowButton()
89 Demo::ShadowButton Internal::ShadowButton::New()
91 IntrusivePtr<Internal::ShadowButton> impl = new Internal::ShadowButton();
92 Demo::ShadowButton handle = Demo::ShadowButton(*impl);
97 void ShadowButton::SetActiveState(bool active)
99 if(active != mActiveState)
101 mActiveState = active;
104 StartTransition(Demo::ShadowButton::Property::ACTIVE_TRANSITION);
108 StartTransition(Demo::ShadowButton::Property::INACTIVE_TRANSITION);
113 bool ShadowButton::GetActiveState()
118 void ShadowButton::SetCheckState(bool checkState)
120 mCheckState = checkState;
121 DevelControl::EnableVisual(*this, Demo::ShadowButton::Property::CHECKBOX_FG_VISUAL, true);
122 if(Self().GetProperty<bool>(Actor::Property::CONNECTED_TO_SCENE))
126 StartTransition(Demo::ShadowButton::Property::CHECK_TRANSITION);
130 StartTransition(Demo::ShadowButton::Property::UNCHECK_TRANSITION);
136 bool ShadowButton::GetCheckState()
141 void ShadowButton::StartTransition(Property::Index transitionId)
143 Transitions::iterator iter = FindTransition(transitionId);
144 if(iter != mTransitions.end())
148 iter->mAnimation.Stop();
149 iter->mPlaying = false;
151 iter->mAnimation.FinishedSignal().Disconnect(this, &ShadowButton::OnTransitionFinished);
154 iter->mAnimation = DevelControl::CreateTransition(*this, iter->mTransitionData);
155 StoreTargetLayouts(iter->mTransitionData);
157 iter->mAnimation.FinishedSignal().Connect(this, &ShadowButton::OnTransitionFinished);
158 iter->mAnimation.Play();
159 iter->mPlaying = true;
163 void ShadowButton::OnTransitionFinished(Animation& src)
165 ShadowButton::Transitions::iterator iter = mTransitions.begin();
166 for(; iter != mTransitions.end(); ++iter)
168 if(iter->mAnimation == src)
170 iter->mPlaying = false;
171 iter->mAnimation.Reset(); // Remove the animation when it's finished.
172 switch(iter->mTransitionId)
174 case Demo::ShadowButton::Property::ACTIVE_TRANSITION:
176 // Consider relayouting the text.
179 case Demo::ShadowButton::Property::INACTIVE_TRANSITION:
181 // Consider relayouting the text.
184 case Demo::ShadowButton::Property::UNCHECK_TRANSITION:
186 DevelControl::EnableVisual(*this, Demo::ShadowButton::Property::CHECKBOX_FG_VISUAL, false);
195 void ShadowButton::OnInitialize()
200 void ShadowButton::OnSceneConnection(int depth)
202 Control::OnSceneConnection(depth);
205 void ShadowButton::OnSceneDisconnection()
207 Control::OnSceneDisconnection();
210 void ShadowButton::OnSizeSet(const Vector3& targetSize)
212 Control::OnSizeSet(targetSize);
213 RelayoutVisuals(Vector2(targetSize));
216 void ShadowButton::OnRelayout(const Vector2& targetSize, RelayoutContainer& container)
218 RelayoutVisuals(targetSize);
221 void ShadowButton::RelayoutVisuals(const Vector2& targetSize)
223 bool transitioning = false;
224 ShadowButton::Transitions::iterator iter = mTransitions.begin();
225 for(; iter != mTransitions.end(); ++iter)
227 if(iter->mPlaying == true)
229 transitioning = true;
236 for(ShadowButton::Transforms::iterator iter = mTransforms.begin();
237 iter != mTransforms.end();
240 switch(iter->mTransformId)
242 case Demo::ShadowButton::Property::BACKGROUND_VISUAL:
244 mBackgroundVisual.SetTransformAndSize(iter->mTransform, targetSize);
247 case Demo::ShadowButton::Property::CHECKBOX_BG_VISUAL:
249 mCheckboxBgVisual.SetTransformAndSize(iter->mTransform, targetSize);
252 case Demo::ShadowButton::Property::CHECKBOX_FG_VISUAL:
254 mCheckboxFgVisual.SetTransformAndSize(iter->mTransform, targetSize);
257 case Demo::ShadowButton::Property::LABEL_VISUAL:
259 mLabelVisual.SetTransformAndSize(iter->mTransform, targetSize);
267 Vector3 ShadowButton::GetNaturalSize()
272 Vector2 checkboxBgSize;
273 Vector2 checkboxFgSize;
275 mCheckboxBgVisual.GetNaturalSize(checkboxBgSize);
276 mCheckboxFgVisual.GetNaturalSize(checkboxFgSize);
277 mLabelVisual.GetNaturalSize(labelSize);
279 width = std::max(checkboxBgSize.x, checkboxFgSize.x) + labelSize.x;
280 height = std::max(std::max(checkboxFgSize.y, checkboxBgSize.y), labelSize.y);
282 return Vector3(width, height, height);
285 void ShadowButton::OnStyleChange(Toolkit::StyleManager styleManager, StyleChange::Type change)
288 Control::OnStyleChange(styleManager, change);
291 ShadowButton::Transitions::iterator ShadowButton::FindTransition(Property::Index index)
294 ShadowButton::Transitions::iterator iter = mTransitions.begin();
295 for(; iter != mTransitions.end(); ++iter)
297 if(iter->mTransitionId == index)
305 iter = mTransitions.end();
310 ShadowButton::Transforms::iterator ShadowButton::FindTransform(Property::Index index)
313 ShadowButton::Transforms::iterator iter = mTransforms.begin();
314 for(; iter != mTransforms.end(); ++iter)
316 if(iter->mTransformId == index)
324 iter = mTransforms.end();
329 void ShadowButton::ResetVisual(
330 Property::Index index,
331 Visual::Base& visual,
332 const Property::Value& value)
336 // we are replacing an existing visual, so force relayout
339 const Property::Map* map = value.GetMap();
342 visual = Toolkit::VisualFactory::Get().CreateVisual(*map);
344 // Set the appropriate depth index.
345 // @todo Should be able to set this from the style sheet
348 case Demo::ShadowButton::Property::BACKGROUND_VISUAL:
350 DevelControl::RegisterVisual(*this, index, visual, 0);
353 case Demo::ShadowButton::Property::CHECKBOX_BG_VISUAL:
355 DevelControl::RegisterVisual(*this, index, visual, 1);
358 case Demo::ShadowButton::Property::CHECKBOX_FG_VISUAL:
360 DevelControl::RegisterVisual(*this, index, visual, mCheckState, 2);
363 case Demo::ShadowButton::Property::LABEL_VISUAL:
365 DevelControl::RegisterVisual(*this, index, visual, 1);
370 // Extract transform maps out of the visual definition and store them
371 Property::Value* value = map->Find(Visual::Property::TRANSFORM, "transform");
374 Property::Map* transformMap = value->GetMap();
377 ShadowButton::Transforms::iterator iter = FindTransform(index);
378 if(iter != mTransforms.end())
380 iter->mTransform = *transformMap;
384 mTransforms.push_back(Transform(index, *transformMap));
391 bool IsTransformProperty(const std::string& property)
393 const char* transformProperties[] = {"size", "offset", "origin", "anchorPoint", "offsetPolicy", "sizePolicy"};
394 const int NUM_TRANSFORM_PROPERTIES = sizeof(transformProperties) / sizeof(const char*);
397 for(int i = 0; i < NUM_TRANSFORM_PROPERTIES; ++i)
399 if(property == transformProperties[i])
408 void ShadowButton::StoreTargetLayouts(TransitionData transitionData)
411 // foreach animator in transitionData
412 // if animator{"property"} in [ "size", "offset", "origin", "anchorPoint", "offsetPolicy", "sizePolicy" ]
413 // transforms{ animator{"target"} }->{animator{"property"}} = animator{"targetValue"}
415 for(unsigned int i = 0; i < transitionData.Count(); ++i)
417 Property::Map animator = transitionData.GetAnimatorAt(i);
418 Property::Value* target = animator.Find("target");
422 Property::Index index = Property::INVALID_INDEX;
423 if(Scripting::GetEnumerationProperty(*target, VISUAL_PROPERTIES_TABLE, VISUAL_PROPERTIES_TABLE_COUNT, index))
425 ShadowButton::Transforms::iterator iter = FindTransform(index);
426 if(iter != mTransforms.end())
428 Property::Value* property = animator.Find("property");
431 std::string propertyString;
432 property->Get(propertyString);
433 if(IsTransformProperty(propertyString))
435 Property::Value* targetValue = animator.Find("targetValue");
438 iter->mTransform[propertyString] = *targetValue;
448 void ShadowButton::ResetTransition(
449 Property::Index index,
450 const Property::Value& value)
452 ShadowButton::Transitions::iterator iter = FindTransition(index);
453 if(iter != mTransitions.end())
456 iter->mTransitionData = ConvertPropertyToTransition(value);
457 iter->mAnimation.Stop();
458 iter->mAnimation.Clear();
462 mTransitions.push_back(Transition(index, ConvertPropertyToTransition(value)));
466 void ShadowButton::SetProperty(BaseObject* object, Property::Index index, const Property::Value& value)
468 Demo::ShadowButton shadowButton = Demo::ShadowButton::DownCast(Dali::BaseHandle(object));
472 ShadowButton& impl = GetImpl(shadowButton);
475 case Demo::ShadowButton::Property::BACKGROUND_VISUAL:
477 impl.ResetVisual(index, impl.mBackgroundVisual, value);
480 case Demo::ShadowButton::Property::CHECKBOX_BG_VISUAL:
482 impl.ResetVisual(index, impl.mCheckboxBgVisual, value);
485 case Demo::ShadowButton::Property::CHECKBOX_FG_VISUAL:
487 impl.ResetVisual(index, impl.mCheckboxFgVisual, value);
488 DevelControl::EnableVisual(impl, Demo::ShadowButton::Property::CHECKBOX_FG_VISUAL, impl.mCheckState);
491 case Demo::ShadowButton::Property::LABEL_VISUAL:
493 impl.ResetVisual(index, impl.mLabelVisual, value);
496 case Demo::ShadowButton::Property::ACTIVE_TRANSITION:
497 case Demo::ShadowButton::Property::INACTIVE_TRANSITION:
498 case Demo::ShadowButton::Property::CHECK_TRANSITION:
499 case Demo::ShadowButton::Property::UNCHECK_TRANSITION:
501 impl.ResetTransition(index, value);
508 Property::Value ShadowButton::GetProperty(BaseObject* object, Property::Index propertyIndex)
510 Property::Value value;
512 Demo::ShadowButton shadowButton = Demo::ShadowButton::DownCast(Dali::BaseHandle(object));
516 ShadowButton& impl = GetImpl(shadowButton);
517 switch(propertyIndex)
519 case Demo::ShadowButton::Property::BACKGROUND_VISUAL:
522 impl.mBackgroundVisual.CreatePropertyMap(map);
526 case Demo::ShadowButton::Property::CHECKBOX_BG_VISUAL:
529 impl.mCheckboxBgVisual.CreatePropertyMap(map);
533 case Demo::ShadowButton::Property::CHECKBOX_FG_VISUAL:
536 impl.mCheckboxFgVisual.CreatePropertyMap(map);
540 case Demo::ShadowButton::Property::LABEL_VISUAL:
543 impl.mLabelVisual.CreatePropertyMap(map);
556 } // namespace Internal