/*
- * Copyright (c) 2021 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2024 Samsung Electronics Co., Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
#include <dali/devel-api/scripting/scripting.h>
#include <dali/integration-api/debug.h>
#include <dali/public-api/animation/constraint.h>
-#include <dali/public-api/object/type-info.h>
-#include <dali/public-api/object/type-registry-helper.h>
+#include <dali/public-api/math/math-utils.h>
#include <dali/public-api/size-negotiation/relayout-container.h>
#include <cstring> // for strcmp
#include <limits>
#include <stack>
-#include <typeinfo>
// INTERNAL INCLUDES
#include <dali-toolkit/dali-toolkit.h>
#include <dali-toolkit/devel-api/controls/control-depth-index-ranges.h>
#include <dali-toolkit/devel-api/controls/control-devel.h>
#include <dali-toolkit/devel-api/focus-manager/keyinput-focus-manager.h>
-#include <dali-toolkit/devel-api/visuals/color-visual-actions-devel.h>
#include <dali-toolkit/devel-api/visuals/color-visual-properties-devel.h>
+#include <dali-toolkit/devel-api/visuals/visual-actions-devel.h>
#include <dali-toolkit/internal/controls/control/control-data-impl.h>
#include <dali-toolkit/internal/styling/style-manager-impl.h>
#include <dali-toolkit/internal/visuals/color/color-visual.h>
Toolkit::Control Control::New()
{
+ return New(ControlBehaviour::CONTROL_BEHAVIOUR_DEFAULT);
+}
+
+Toolkit::Control Control::New(ControlBehaviour additionalBehaviour)
+{
// Create the implementation, temporarily owned on stack
- IntrusivePtr<Control> controlImpl = new Control(ControlBehaviour(CONTROL_BEHAVIOUR_DEFAULT));
+ IntrusivePtr<Control> controlImpl = new Control(ControlBehaviour(CONTROL_BEHAVIOUR_DEFAULT | additionalBehaviour));
// Pass ownership to handle
Toolkit::Control handle(*controlImpl);
if(visual && visual.GetType() == Toolkit::Visual::COLOR)
{
// Update background color only
- mImpl->DoAction(Toolkit::Control::Property::BACKGROUND, DevelColorVisual::Action::UPDATE_PROPERTY, map);
+ mImpl->DoAction(Toolkit::Control::Property::BACKGROUND, DevelVisual::Action::UPDATE_PROPERTY, map);
return;
}
RelayoutRequest();
}
+void Control::SetResourceReady()
+{
+ Internal::Control::Impl& controlDataImpl = Internal::Control::Impl::Get(*this);
+ controlDataImpl.ResourceReady();
+}
+
+Toolkit::DevelControl::ControlAccessible* Control::GetAccessibleObject()
+{
+ return mImpl->GetAccessibleObject();
+}
+
void Control::EnableGestureDetection(GestureType::Value type)
{
if((type & GestureType::PINCH) && !mImpl->mPinchGestureDetector)
return false; // Accessibility zoom action is not handled by default
}
+DevelControl::ControlAccessible* Control::CreateAccessibleObject()
+{
+ return new DevelControl::ControlAccessible(Self());
+}
+
Actor Control::GetNextKeyboardFocusableActor(Actor currentFocusedActor, Toolkit::Control::KeyboardFocus::Direction direction, bool loopEnabled)
{
return Actor();
{
SetKeyboardNavigationSupport(true);
}
-
- Dali::TypeInfo type;
- Self().GetTypeInfo(type);
- if(type)
- {
- auto typeName = type.GetName();
- DevelControl::AppendAccessibilityAttribute(Self(), "class", typeName);
- }
}
void Control::OnInitialize()
{
}
+bool Control::IsResourceReady() const
+{
+ const Internal::Control::Impl& controlDataImpl = Internal::Control::Impl::Get(*this);
+ return controlDataImpl.IsResourceReady();
+}
+
void Control::OnStyleChange(Toolkit::StyleManager styleManager, StyleChange::Type change)
{
// By default the control is only interested in theme (not font) changes
if(Accessibility::IsUp())
{
- auto self = mImpl->GetAccessibilityObject(Self());
- self->EmitFocused(focusGained);
- auto parent = self->GetParent();
- if(parent && !self->GetStates()[Dali::Accessibility::State::MANAGES_DESCENDANTS])
+ auto accessible = GetAccessibleObject();
+ if(DALI_LIKELY(accessible))
{
- parent->EmitActiveDescendantChanged(parent, self);
+ accessible->EmitFocused(focusGained);
+ auto parent = accessible->GetParent();
+ if(parent && !accessible->GetStates()[Dali::Accessibility::State::MANAGES_DESCENDANTS])
+ {
+ parent->EmitActiveDescendantChanged(accessible);
+ }
}
}
}
case Actor::Property::VISIBLE:
{
- if(Dali::Accessibility::IsUp())
+ auto* accessible = GetAccessibleObject();
+ if(DALI_LIKELY(accessible))
{
- Dali::Accessibility::Accessible::Get(Self())->EmitVisible(Self().GetProperty(Actor::Property::VISIBLE).Get<bool>());
+ accessible->EmitVisible(Self().GetProperty<bool>(Actor::Property::VISIBLE));
}
break;
}
- case Toolkit::DevelControl::Property::ACCESSIBILITY_ROLE:
+ case DevelActor::Property::USER_INTERACTION_ENABLED:
{
- if(Dali::Accessibility::IsUp())
+ const bool enabled = propertyValue.Get<bool>();
+ if(!enabled && Self() == Dali::Toolkit::KeyboardFocusManager::Get().GetCurrentFocusActor())
{
- Dali::Accessibility::Accessible::Get(Self())->Emit(Dali::Accessibility::ObjectPropertyChangeEvent::ROLE);
+ Dali::Toolkit::KeyboardFocusManager::Get().ClearFocus();
}
break;
}
mImpl->SignalDisconnected(slotObserver, callback);
}
+void Control::MakeVisualTransition(Dali::Property::Map& sourcePropertyMap, Dali::Property::Map& destinationPropertyMap, Dali::Toolkit::Control source, Dali::Toolkit::Control destination, Dali::Property::Index visualIndex)
+{
+ sourcePropertyMap.Clear();
+ destinationPropertyMap.Clear();
+
+ Toolkit::Visual::Base sourceVisual = DevelControl::GetVisual(GetImplementation(source), visualIndex);
+ Toolkit::Visual::Base destinationVisual = DevelControl::GetVisual(GetImplementation(destination), visualIndex);
+
+ // If source or destination doesn't have the visual, do not create transition for the visual.
+ if(!sourceVisual || !destinationVisual)
+ {
+ return;
+ }
+
+ Property::Map sourceMap;
+ Property::Map destinationMap;
+ sourceVisual.CreatePropertyMap(sourceMap);
+ destinationVisual.CreatePropertyMap(destinationMap);
+
+ static auto findValueVector4 = [](const Property::Map& map, Property::Index index, const Vector4& defaultValue = Vector4()) -> Vector4 {
+ Property::Value* propertyValue = map.Find(index);
+ if(propertyValue)
+ {
+ return propertyValue->Get<Vector4>();
+ }
+ return defaultValue;
+ };
+
+ static auto findValueFloat = [](const Property::Map& map, Property::Index index, const float& defaultValue = 0.0f) -> float {
+ Property::Value* propertyValue = map.Find(index);
+ if(propertyValue)
+ {
+ return propertyValue->Get<float>();
+ }
+ return defaultValue;
+ };
+
+ Vector4 defaultMixColor(Color::TRANSPARENT);
+ Vector4 defaultCornerRadius(0.0f, 0.0f, 0.0f, 0.0f);
+ float defaultBorderlineWidth(0.0f);
+ Vector4 defaultBorderlineColor(0.0f, 0.0f, 0.0f, 1.0f);
+ float defaultBorderlineOffset(0.0f);
+
+ Vector4 sourceMixColor = findValueVector4(sourceMap, Dali::Toolkit::Visual::Property::MIX_COLOR, defaultMixColor);
+ Vector4 sourceCornerRadius = findValueVector4(sourceMap, Toolkit::DevelVisual::Property::CORNER_RADIUS, defaultCornerRadius);
+ float sourceBorderlineWidth = findValueFloat(sourceMap, Toolkit::DevelVisual::Property::BORDERLINE_WIDTH, defaultBorderlineWidth);
+ Vector4 sourceBorderlineColor = findValueVector4(sourceMap, Toolkit::DevelVisual::Property::BORDERLINE_COLOR, defaultBorderlineColor);
+ float sourceBorderlineOffset = findValueFloat(sourceMap, Toolkit::DevelVisual::Property::BORDERLINE_OFFSET, defaultBorderlineOffset);
+
+ Vector4 destinationMixColor = findValueVector4(destinationMap, Dali::Toolkit::Visual::Property::MIX_COLOR, defaultMixColor);
+ Vector4 destinationCornerRadius = findValueVector4(destinationMap, Toolkit::DevelVisual::Property::CORNER_RADIUS, defaultCornerRadius);
+ float destinationBorderlineWidth = findValueFloat(destinationMap, Toolkit::DevelVisual::Property::BORDERLINE_WIDTH, defaultBorderlineWidth);
+ Vector4 destinationBorderlineColor = findValueVector4(destinationMap, Toolkit::DevelVisual::Property::BORDERLINE_COLOR, defaultBorderlineColor);
+ float destinationBorderlineOffset = findValueFloat(destinationMap, Toolkit::DevelVisual::Property::BORDERLINE_OFFSET, defaultBorderlineOffset);
+
+ // If the value of the source Control and that of destination Control is different, the property should be transitioned.
+ if(Vector3(sourceMixColor) != Vector3(destinationMixColor))
+ {
+ sourcePropertyMap.Add(Dali::Toolkit::Visual::Property::MIX_COLOR, Vector3(sourceMixColor));
+ destinationPropertyMap.Add(Dali::Toolkit::Visual::Property::MIX_COLOR, Vector3(destinationMixColor));
+ }
+
+ if(std::abs(sourceMixColor.a - destinationMixColor.a) > Math::MACHINE_EPSILON_1)
+ {
+ sourcePropertyMap.Add(Dali::Toolkit::Visual::Property::OPACITY, sourceMixColor.a);
+ destinationPropertyMap.Add(Dali::Toolkit::Visual::Property::OPACITY, destinationMixColor.a);
+ }
+
+ if(sourceCornerRadius != destinationCornerRadius)
+ {
+ sourcePropertyMap.Add(Dali::Toolkit::DevelVisual::Property::CORNER_RADIUS, sourceCornerRadius);
+ destinationPropertyMap.Add(Dali::Toolkit::DevelVisual::Property::CORNER_RADIUS, destinationCornerRadius);
+ }
+
+ if(!Dali::Equals(sourceBorderlineWidth, destinationBorderlineWidth))
+ {
+ sourcePropertyMap.Add(Dali::Toolkit::DevelVisual::Property::BORDERLINE_WIDTH, sourceBorderlineWidth);
+ destinationPropertyMap.Add(Dali::Toolkit::DevelVisual::Property::BORDERLINE_WIDTH, destinationBorderlineWidth);
+ }
+
+ if(sourceBorderlineColor != destinationBorderlineColor)
+ {
+ sourcePropertyMap.Add(Dali::Toolkit::DevelVisual::Property::BORDERLINE_COLOR, sourceBorderlineColor);
+ destinationPropertyMap.Add(Dali::Toolkit::DevelVisual::Property::BORDERLINE_COLOR, destinationBorderlineColor);
+ }
+
+ if(!Dali::Equals(sourceBorderlineOffset, destinationBorderlineOffset))
+ {
+ sourcePropertyMap.Add(Dali::Toolkit::DevelVisual::Property::BORDERLINE_OFFSET, sourceBorderlineOffset);
+ destinationPropertyMap.Add(Dali::Toolkit::DevelVisual::Property::BORDERLINE_OFFSET, destinationBorderlineOffset);
+ }
+}
+
Control& GetImplementation(Dali::Toolkit::Control& handle)
{
CustomActorImpl& customInterface = handle.GetImplementation();