X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=dali-toolkit%2Fpublic-api%2Fcontrols%2Fcontrol-impl.cpp;h=40f34a0094663390f8641d0ecb71be6d9a4e8db7;hb=e591332735fe123a1d72ec7b88133a5dc14dc493;hp=781b531dff024714af62647127417f0f2a17f387;hpb=f360f24dc7ce4d8944d479e9753d42574e4cfb3a;p=platform%2Fcore%2Fuifw%2Fdali-toolkit.git diff --git a/dali-toolkit/public-api/controls/control-impl.cpp b/dali-toolkit/public-api/controls/control-impl.cpp index 781b531..40f34a0 100644 --- a/dali-toolkit/public-api/controls/control-impl.cpp +++ b/dali-toolkit/public-api/controls/control-impl.cpp @@ -1,5 +1,5 @@ /* - * 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. @@ -24,21 +24,19 @@ #include #include #include -#include -#include +#include #include #include // for strcmp #include #include -#include // INTERNAL INCLUDES #include #include #include #include -#include #include +#include #include #include #include @@ -64,27 +62,6 @@ Debug::Filter* gLogFilter = Debug::Filter::New(Debug::NoLogging, false, "LOG_CON #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. @@ -96,34 +73,11 @@ void CreateClippingRenderer(Control& controlImpl) 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); } } } @@ -132,8 +86,13 @@ void CreateClippingRenderer(Control& controlImpl) Toolkit::Control Control::New() { + return New(ControlBehaviour::CONTROL_BEHAVIOUR_DEFAULT); +} + +Toolkit::Control Control::New(ControlBehaviour additionalBehaviour) +{ // Create the implementation, temporarily owned on stack - IntrusivePtr controlImpl = new Control(ControlBehaviour(CONTROL_BEHAVIOUR_DEFAULT)); + IntrusivePtr controlImpl = new Control(ControlBehaviour(CONTROL_BEHAVIOUR_DEFAULT | additionalBehaviour)); // Pass ownership to handle Toolkit::Control handle(*controlImpl); @@ -173,33 +132,12 @@ void Control::SetBackgroundColor(const Vector4& color) 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() == true || colorValue->Get().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); @@ -227,6 +165,17 @@ void Control::ClearBackground() 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) @@ -359,12 +308,6 @@ bool Control::IsKeyboardFocusGroup() return Toolkit::KeyboardFocusManager::Get().IsFocusGroup(Self()); } -void Control::AccessibilityActivate() -{ - // Inform deriving classes - OnAccessibilityActivated(); -} - void Control::KeyboardEnter() { // Inform deriving classes @@ -400,6 +343,11 @@ bool Control::OnAccessibilityZoom() 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(); @@ -486,20 +434,18 @@ void Control::Initialize() { 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 @@ -544,12 +490,15 @@ void Control::EmitKeyInputFocusSignal(bool focusGained) 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); + } } } @@ -589,13 +538,10 @@ void Control::OnSceneConnection(int depth) // The clipping renderer is only created if required. CreateClippingRenderer(*this); - - mImpl->AccessibilityRegister(); } void Control::OnSceneDisconnection() { - mImpl->AccessibilityDeregister(true); mImpl->OnSceneDisconnection(); } @@ -634,17 +580,19 @@ void Control::OnPropertySet(Property::Index index, const Property::Value& proper } case Actor::Property::VISIBLE: { - if(Dali::Accessibility::IsUp()) + auto* accessible = GetAccessibleObject(); + if(DALI_LIKELY(accessible) && accessible->IsHighlighted()) { - Dali::Accessibility::Accessible::Get(Self())->EmitVisible(Self().GetProperty(Actor::Property::VISIBLE).Get()); + accessible->EmitVisible(Self().GetProperty(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(); + if(!enabled && Self() == Dali::Toolkit::KeyboardFocusManager::Get().GetCurrentFocusActor()) { - Dali::Accessibility::Accessible::Get(Self())->Emit(Dali::Accessibility::ObjectPropertyChangeEvent::ROLE); + Dali::Toolkit::KeyboardFocusManager::Get().ClearFocus(); } break; } @@ -770,6 +718,99 @@ void Control::SignalDisconnected(SlotObserver* slotObserver, CallbackBase* callb 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(); + } + 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(); + } + 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();