/*
- * Copyright (c) 2020 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2022 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-toolkit/public-api/controls/control-impl.h>
// EXTERNAL INCLUDES
+#include <dali/devel-api/actors/actor-devel.h>
+#include <dali/devel-api/common/stage.h>
#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/size-negotiation/relayout-container.h>
#include <cstring> // for strcmp
#include <limits>
#include <stack>
#include <typeinfo>
-#include <dali/public-api/object/type-info.h>
-#include <dali/devel-api/common/stage.h>
-#include <dali/devel-api/actors/actor-devel.h>
// 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/visual-actions-devel.h>
#include <dali-toolkit/devel-api/visuals/color-visual-properties-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/visual-string-constants.h>
#include <dali-toolkit/public-api/align-enumerations.h>
#include <dali-toolkit/public-api/controls/control.h>
+#include <dali-toolkit/public-api/controls/image-view/image-view.h>
#include <dali-toolkit/public-api/focus-manager/keyboard-focus-manager.h>
#include <dali-toolkit/public-api/styling/style-manager.h>
#include <dali-toolkit/public-api/visuals/color-visual-properties.h>
#include <dali-toolkit/public-api/visuals/visual-properties.h>
-#include <dali-toolkit/internal/controls/control/control-data-impl.h>
-#include <dali-toolkit/public-api/controls/image-view/image-view.h>
-#include <dali-toolkit/dali-toolkit.h>
namespace Dali
{
#endif
/**
- * @brief Replace the background visual if it's a color visual with the renderIfTransparent property set as required.
- * @param[in] controlImpl The control implementation
- * @param[in] renderIfTransaparent Whether we should render if the color is transparent
- */
-void ChangeBackgroundColorVisual(Control& controlImpl, bool renderIfTransparent)
-{
- Internal::Control::Impl& controlDataImpl = Internal::Control::Impl::Get(controlImpl);
-
- Toolkit::Visual::Base backgroundVisual = controlDataImpl.GetVisual(Toolkit::Control::Property::BACKGROUND);
- if(backgroundVisual && backgroundVisual.GetType() == Toolkit::Visual::COLOR)
- {
- Property::Map map;
- backgroundVisual.CreatePropertyMap(map);
-
- // Only change it if it's a color visual
- map[Toolkit::DevelColorVisual::Property::RENDER_IF_TRANSPARENT] = renderIfTransparent;
- controlImpl.SetBackground(map);
- }
-}
-
-/**
* @brief Creates a clipping renderer if required.
* (EG. If no renders exist and clipping is enabled).
* @param[in] controlImpl The control implementation.
int clippingMode = ClippingMode::DISABLED;
if(self.GetProperty(Actor::Property::CLIPPING_MODE).Get(clippingMode))
{
- switch(clippingMode)
- {
- case ClippingMode::CLIP_CHILDREN:
- {
- if(self.GetRendererCount() == 0u)
- {
- Internal::Control::Impl& controlDataImpl = Internal::Control::Impl::Get(controlImpl);
- if(controlDataImpl.mVisuals.Empty())
- {
- controlImpl.SetBackgroundColor(Color::TRANSPARENT);
- }
- else
- {
- // We have visuals, check if we've set the background and re-create it to
- // render even if transparent (only if it's a color visual)
- ChangeBackgroundColorVisual(controlImpl, true);
- }
- }
- break;
- }
+ Internal::Control::Impl& controlDataImpl = Internal::Control::Impl::Get(controlImpl);
- case ClippingMode::DISABLED:
- case ClippingMode::CLIP_TO_BOUNDING_BOX:
- {
- // If we have a background visual, check if it's a color visual and remove the render if transparent flag
- ChangeBackgroundColorVisual(controlImpl, false);
- break;
- }
+ if(clippingMode == ClippingMode::CLIP_CHILDREN && controlDataImpl.mVisuals.Empty() && self.GetRendererCount() == 0u)
+ {
+ controlImpl.SetBackgroundColor(Color::TRANSPARENT);
}
}
}
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);
map[Toolkit::Visual::Property::TYPE] = Toolkit::Visual::COLOR;
map[Toolkit::ColorVisual::Property::MIX_COLOR] = color;
- bool renderIfTransparent = false;
- int clippingMode = ClippingMode::DISABLED;
- if((Self().GetProperty(Actor::Property::CLIPPING_MODE).Get(clippingMode)) &&
- (clippingMode == ClippingMode::CLIP_CHILDREN))
- {
- // If clipping-mode is set to CLIP_CHILDREN, then force visual to add the render even if transparent
- map[Toolkit::DevelColorVisual::Property::RENDER_IF_TRANSPARENT] = true;
- renderIfTransparent = true;
- }
-
Toolkit::Visual::Base visual = mImpl->GetVisual(Toolkit::Control::Property::BACKGROUND);
if(visual && visual.GetType() == Toolkit::Visual::COLOR)
{
- Property::Map visualMap;
- visual.CreatePropertyMap(visualMap);
-
- Property::Value* renderValue = visualMap.Find(Toolkit::DevelColorVisual::Property::RENDER_IF_TRANSPARENT);
- Property::Value* colorValue = visualMap.Find(Toolkit::ColorVisual::Property::MIX_COLOR);
- if(renderValue && colorValue)
- {
- if((renderValue->Get<bool>() == true || colorValue->Get<Vector4>().a > 0.0f) && (renderIfTransparent || color.a > 0.0f))
- {
- // Update background color only
- mImpl->DoAction(Toolkit::Control::Property::BACKGROUND, DevelColorVisual::Action::UPDATE_PROPERTY, map);
- return;
- }
- }
+ // Update background color only
+ mImpl->DoAction(Toolkit::Control::Property::BACKGROUND, DevelVisual::Action::UPDATE_PROPERTY, map);
+ return;
}
SetBackground(map);
RelayoutRequest();
}
+Toolkit::DevelControl::ControlAccessible* Control::GetAccessibleObject()
+{
+ return mImpl->GetAccessibleObject();
+}
+
void Control::EnableGestureDetection(GestureType::Value type)
{
if((type & GestureType::PINCH) && !mImpl->mPinchGestureDetector)
bool Control::OnAccessibilityActivated()
{
- if( Toolkit::KeyboardFocusManager::Get().SetCurrentFocusActor( Self() ) )
+ if(Toolkit::KeyboardFocusManager::Get().SetCurrentFocusActor(Self()))
{
return OnKeyboardEnter();
}
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();
}
Dali::TypeInfo type;
- Self().GetTypeInfo( type );
- if (type)
+ Self().GetTypeInfo(type);
+ if(type)
{
auto typeName = type.GetName();
- DevelControl::AppendAccessibilityAttribute( Self(), "t", typeName );
+ DevelControl::AppendAccessibilityAttribute(Toolkit::Control::DownCast(Self()), "class", typeName);
}
-
- if (Accessibility::IsUp())
- mImpl->AccessibilityRegister();
}
void Control::OnInitialize()
{
Dali::Toolkit::Control handle(GetOwner());
- if( Accessibility::IsUp() )
+ if(Accessibility::IsUp())
{
- auto self = mImpl->GetAccessibilityObject( Self() );
- self->EmitFocused( focusGained );
+ auto self = GetAccessibleObject();
+ self->EmitFocused(focusGained);
auto parent = self->GetParent();
- if( parent && !self->GetStates()[Dali::Accessibility::State::MANAGES_DESCENDANTS] )
+ if(parent && !self->GetStates()[Dali::Accessibility::State::MANAGES_DESCENDANTS])
{
- parent->EmitActiveDescendantChanged( parent, self );
+ parent->EmitActiveDescendantChanged(self);
}
}
// The clipping renderer is only created if required.
CreateClippingRenderer(*this);
-
- // Request to be laid out when the control is connected to the Scene.
- // Signal that a Relayout may be needed
- if( Accessibility::IsUp() )
- {
- mImpl->AccessibilityRegister();
- }
}
void Control::OnSceneDisconnection()
{
- if( Accessibility::IsUp() )
- {
- mImpl->AccessibilityDeregister();
- }
mImpl->OnSceneDisconnection();
}
{
// If the clipping mode has been set, we may need to create a renderer.
// Only do this if we are already on-stage as the OnSceneConnection will handle the off-stage clipping controls.
- switch( index )
+ switch(index)
{
case Actor::Property::CLIPPING_MODE:
{
- if( Self().GetProperty< bool >( Actor::Property::CONNECTED_TO_SCENE ))
+ if(Self().GetProperty<bool>(Actor::Property::CONNECTED_TO_SCENE))
{
// Note: This method will handle whether creation of the renderer is required.
- CreateClippingRenderer( *this );
+ CreateClippingRenderer(*this);
}
break;
}
case Actor::Property::VISIBLE:
{
- if( Dali::Accessibility::IsUp() )
- {
- Dali::Accessibility::Accessible::Get(Self())->EmitVisible( Self().GetProperty( Actor::Property::VISIBLE ).Get<bool>() );
- }
+ GetAccessibleObject()->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(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(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();