2 * Copyright (c) 2021 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 for(ShadowButton::Transitions::iterator iter = mTransitions.begin();
225 iter != mTransitions.end();
228 if(iter->mPlaying == true)
230 transitioning = true;
237 for(ShadowButton::Transforms::iterator iter = mTransforms.begin();
238 iter != mTransforms.end();
241 switch(iter->mTransformId)
243 case Demo::ShadowButton::Property::BACKGROUND_VISUAL:
245 mBackgroundVisual.SetTransformAndSize(iter->mTransform, targetSize);
248 case Demo::ShadowButton::Property::CHECKBOX_BG_VISUAL:
250 mCheckboxBgVisual.SetTransformAndSize(iter->mTransform, targetSize);
253 case Demo::ShadowButton::Property::CHECKBOX_FG_VISUAL:
255 mCheckboxFgVisual.SetTransformAndSize(iter->mTransform, targetSize);
258 case Demo::ShadowButton::Property::LABEL_VISUAL:
260 mLabelVisual.SetTransformAndSize(iter->mTransform, targetSize);
268 Vector3 ShadowButton::GetNaturalSize()
273 Vector2 checkboxBgSize;
274 Vector2 checkboxFgSize;
276 mCheckboxBgVisual.GetNaturalSize(checkboxBgSize);
277 mCheckboxFgVisual.GetNaturalSize(checkboxFgSize);
278 mLabelVisual.GetNaturalSize(labelSize);
280 width = std::max(checkboxBgSize.x, checkboxFgSize.x) + labelSize.x;
281 height = std::max(std::max(checkboxFgSize.y, checkboxBgSize.y), labelSize.y);
283 return Vector3(width, height, height);
286 void ShadowButton::OnStyleChange(Toolkit::StyleManager styleManager, StyleChange::Type change)
289 Control::OnStyleChange(styleManager, change);
292 ShadowButton::Transitions::iterator ShadowButton::FindTransition(Property::Index index)
295 ShadowButton::Transitions::iterator iter = mTransitions.begin();
296 for(; iter != mTransitions.end(); ++iter)
298 if(iter->mTransitionId == index)
306 iter = mTransitions.end();
311 ShadowButton::Transforms::iterator ShadowButton::FindTransform(Property::Index index)
314 ShadowButton::Transforms::iterator iter = mTransforms.begin();
315 for(; iter != mTransforms.end(); ++iter)
317 if(iter->mTransformId == index)
325 iter = mTransforms.end();
330 void ShadowButton::ResetVisual(
331 Property::Index index,
332 Visual::Base& visual,
333 const Property::Value& value)
337 // we are replacing an existing visual, so force relayout
340 const Property::Map* map = value.GetMap();
343 visual = Toolkit::VisualFactory::Get().CreateVisual(*map);
345 // Set the appropriate depth index.
346 // @todo Should be able to set this from the style sheet
349 case Demo::ShadowButton::Property::BACKGROUND_VISUAL:
351 DevelControl::RegisterVisual(*this, index, visual, 0);
354 case Demo::ShadowButton::Property::CHECKBOX_BG_VISUAL:
356 DevelControl::RegisterVisual(*this, index, visual, 1);
359 case Demo::ShadowButton::Property::CHECKBOX_FG_VISUAL:
361 DevelControl::RegisterVisual(*this, index, visual, mCheckState, 2);
364 case Demo::ShadowButton::Property::LABEL_VISUAL:
366 DevelControl::RegisterVisual(*this, index, visual, 1);
371 // Extract transform maps out of the visual definition and store them
372 Property::Value* transformValue = map->Find(Visual::Property::TRANSFORM, "transform");
375 Property::Map* transformMap = transformValue->GetMap();
378 ShadowButton::Transforms::iterator iter = FindTransform(index);
379 if(iter != mTransforms.end())
381 iter->mTransform = *transformMap;
385 mTransforms.push_back(Transform(index, *transformMap));
392 bool IsTransformProperty(const std::string& property)
394 const char* transformProperties[] = {"size", "offset", "origin", "anchorPoint", "offsetPolicy", "sizePolicy"};
395 const int NUM_TRANSFORM_PROPERTIES = sizeof(transformProperties) / sizeof(const char*);
398 for(int i = 0; i < NUM_TRANSFORM_PROPERTIES; ++i)
400 if(property == transformProperties[i])
409 void ShadowButton::StoreTargetLayouts(TransitionData transitionData)
412 // foreach animator in transitionData
413 // if animator{"property"} in [ "size", "offset", "origin", "anchorPoint", "offsetPolicy", "sizePolicy" ]
414 // transforms{ animator{"target"} }->{animator{"property"}} = animator{"targetValue"}
416 for(unsigned int i = 0; i < transitionData.Count(); ++i)
418 Property::Map animator = transitionData.GetAnimatorAt(i);
419 Property::Value* target = animator.Find("target");
423 Property::Index index = Property::INVALID_INDEX;
424 if(Scripting::GetEnumerationProperty(*target, VISUAL_PROPERTIES_TABLE, VISUAL_PROPERTIES_TABLE_COUNT, index))
426 ShadowButton::Transforms::iterator iter = FindTransform(index);
427 if(iter != mTransforms.end())
429 Property::Value* property = animator.Find("property");
432 std::string propertyString;
433 property->Get(propertyString);
434 if(IsTransformProperty(propertyString))
436 Property::Value* targetValue = animator.Find("targetValue");
439 iter->mTransform[propertyString] = *targetValue;
449 void ShadowButton::ResetTransition(
450 Property::Index index,
451 const Property::Value& value)
453 ShadowButton::Transitions::iterator iter = FindTransition(index);
454 if(iter != mTransitions.end())
457 iter->mTransitionData = ConvertPropertyToTransition(value);
458 iter->mAnimation.Stop();
459 iter->mAnimation.Clear();
463 mTransitions.push_back(Transition(index, ConvertPropertyToTransition(value)));
467 void ShadowButton::SetProperty(BaseObject* object, Property::Index index, const Property::Value& value)
469 Demo::ShadowButton shadowButton = Demo::ShadowButton::DownCast(Dali::BaseHandle(object));
473 ShadowButton& impl = GetImpl(shadowButton);
476 case Demo::ShadowButton::Property::BACKGROUND_VISUAL:
478 impl.ResetVisual(index, impl.mBackgroundVisual, value);
481 case Demo::ShadowButton::Property::CHECKBOX_BG_VISUAL:
483 impl.ResetVisual(index, impl.mCheckboxBgVisual, value);
486 case Demo::ShadowButton::Property::CHECKBOX_FG_VISUAL:
488 impl.ResetVisual(index, impl.mCheckboxFgVisual, value);
489 DevelControl::EnableVisual(impl, Demo::ShadowButton::Property::CHECKBOX_FG_VISUAL, impl.mCheckState);
492 case Demo::ShadowButton::Property::LABEL_VISUAL:
494 impl.ResetVisual(index, impl.mLabelVisual, value);
497 case Demo::ShadowButton::Property::ACTIVE_TRANSITION:
498 case Demo::ShadowButton::Property::INACTIVE_TRANSITION:
499 case Demo::ShadowButton::Property::CHECK_TRANSITION:
500 case Demo::ShadowButton::Property::UNCHECK_TRANSITION:
502 impl.ResetTransition(index, value);
509 Property::Value ShadowButton::GetProperty(BaseObject* object, Property::Index propertyIndex)
511 Property::Value value;
513 Demo::ShadowButton shadowButton = Demo::ShadowButton::DownCast(Dali::BaseHandle(object));
517 ShadowButton& impl = GetImpl(shadowButton);
518 switch(propertyIndex)
520 case Demo::ShadowButton::Property::BACKGROUND_VISUAL:
523 impl.mBackgroundVisual.CreatePropertyMap(map);
527 case Demo::ShadowButton::Property::CHECKBOX_BG_VISUAL:
530 impl.mCheckboxBgVisual.CreatePropertyMap(map);
534 case Demo::ShadowButton::Property::CHECKBOX_FG_VISUAL:
537 impl.mCheckboxFgVisual.CreatePropertyMap(map);
541 case Demo::ShadowButton::Property::LABEL_VISUAL:
544 impl.mLabelVisual.CreatePropertyMap(map);
557 } // namespace Internal