X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=dali-toolkit%2Finternal%2Ffocus-manager%2Fkeyboard-focus-manager-impl.cpp;h=16f73862f322a06b52cb064de748d6be45a8b042;hb=e3929ce19d02903f5b5c9c356ae157183e37facb;hp=61cb48190982a0327c7acb8fa14298262354b517;hpb=26efc210fc636e51a4d3df9ae7fbcc1d2a8bac40;p=platform%2Fcore%2Fuifw%2Fdali-toolkit.git diff --git a/dali-toolkit/internal/focus-manager/keyboard-focus-manager-impl.cpp b/dali-toolkit/internal/focus-manager/keyboard-focus-manager-impl.cpp index 61cb481..16f7386 100644 --- a/dali-toolkit/internal/focus-manager/keyboard-focus-manager-impl.cpp +++ b/dali-toolkit/internal/focus-manager/keyboard-focus-manager-impl.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019 Samsung Electronics Co., Ltd. + * Copyright (c) 2020 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. @@ -21,28 +21,30 @@ // EXTERNAL INCLUDES #include // for strcmp #include -#include +#include +#include +#include #include #include -#include #include -#include +#include #include #include #include -#include -#include -#include #include +#include +#include // INTERNAL INCLUDES +#include #include #include #include +#include #include +#include #include #include -#include namespace Dali { @@ -62,7 +64,7 @@ Debug::Filter* gLogFilter = Debug::Filter::New(Debug::NoLogging, false, "LOG_KEY const char* const IS_FOCUS_GROUP_PROPERTY_NAME = "isKeyboardFocusGroup"; // This property will be replaced by a flag in Control. -const char* const FOCUS_BORDER_IMAGE_PATH = DALI_IMAGE_DIR "keyboard_focus.9.png"; +const char* const FOCUS_BORDER_IMAGE_FILE_NAME = "keyboard_focus.9.png"; BaseHandle Create() { @@ -130,7 +132,8 @@ KeyboardFocusManager::KeyboardFocusManager() mAlwaysShowIndicator( ALWAYS_SHOW ), mFocusGroupLoopEnabled( false ), mIsWaitingKeyboardFocusChangeCommit( false ), - mClearFocusOnTouch( true ) + mClearFocusOnTouch( true ), + mEnableDefaultAlgorithm(false) { // TODO: Get FocusIndicatorEnable constant from stylesheet to set mIsFocusIndicatorShown. @@ -146,7 +149,7 @@ void KeyboardFocusManager::OnAdaptorInit() for( auto iter = sceneHolders.begin(); iter != sceneHolders.end(); ++iter ) { ( *iter ).KeyEventSignal().Connect( mSlotDelegate, &KeyboardFocusManager::OnKeyEvent ); - ( *iter ).TouchSignal().Connect( mSlotDelegate, &KeyboardFocusManager::OnTouch ); + ( *iter ).TouchedSignal().Connect( mSlotDelegate, &KeyboardFocusManager::OnTouch ); Dali::Window window = DevelWindow::DownCast( *iter ); if( window ) { @@ -162,7 +165,7 @@ void KeyboardFocusManager::OnAdaptorInit() void KeyboardFocusManager::OnSceneHolderCreated( Dali::Integration::SceneHolder& sceneHolder ) { sceneHolder.KeyEventSignal().Connect( mSlotDelegate, &KeyboardFocusManager::OnKeyEvent ); - sceneHolder.TouchSignal().Connect( mSlotDelegate, &KeyboardFocusManager::OnTouch ); + sceneHolder.TouchedSignal().Connect( mSlotDelegate, &KeyboardFocusManager::OnTouch ); Dali::Window window = DevelWindow::DownCast( sceneHolder ); if( window ) { @@ -201,7 +204,23 @@ bool KeyboardFocusManager::SetCurrentFocusActor( Actor actor ) bool KeyboardFocusManager::DoSetCurrentFocusActor( Actor actor ) { bool success = false; - if( actor && actor.IsKeyboardFocusable() && actor.OnStage() ) + + // If the parent's KEYBOARD_FOCUSABLE_CHILDREN is false, it cannot have focus. + if(actor) + { + Actor parent = actor.GetParent(); + while(parent) + { + if(!parent.GetProperty(DevelActor::Property::KEYBOARD_FOCUSABLE_CHILDREN)) + { + DALI_LOG_INFO(gLogFilter, Debug::General, "[%s:%d] Parent Actor has KEYBOARD_FOCUSABLE_CHILDREN false,\n", __FUNCTION__, __LINE__); + return false; + } + parent = parent.GetParent(); + } + } + + if(actor && actor.GetProperty(Actor::Property::KEYBOARD_FOCUSABLE) && actor.GetProperty(Actor::Property::CONNECTED_TO_SCENE)) { Integration::SceneHolder currentWindow = Integration::SceneHolder::Get( actor ); @@ -225,7 +244,7 @@ bool KeyboardFocusManager::DoSetCurrentFocusActor( Actor actor ) } // Check whether the actor is in the stage and is keyboard focusable. - if( actor && actor.IsKeyboardFocusable() && actor.OnStage() ) + if( actor && actor.GetProperty< bool >( Actor::Property::KEYBOARD_FOCUSABLE ) && actor.GetProperty< bool >( Actor::Property::CONNECTED_TO_SCENE ) ) { if( ( mIsFocusIndicatorShown == SHOW ) && ( mEnableFocusIndicator == ENABLE ) ) { @@ -299,7 +318,7 @@ Actor KeyboardFocusManager::GetCurrentFocusActor() { Actor actor = mCurrentFocusActor.GetHandle(); - if( actor && ! actor.OnStage() ) + if( actor && ! actor.GetProperty< bool >( Actor::Property::CONNECTED_TO_SCENE ) ) { // If the actor has been removed from the stage, then it should not be focused actor.Reset(); @@ -321,7 +340,7 @@ Actor KeyboardFocusManager::GetFocusActorFromCurrentWindow() } } - if( actor && ! actor.OnStage() ) + if( actor && ! actor.GetProperty< bool >( Actor::Property::CONNECTED_TO_SCENE ) ) { // If the actor has been removed from the window, then the window doesn't have any focused actor actor.Reset(); @@ -351,7 +370,7 @@ void KeyboardFocusManager::MoveFocusBackward() Actor target = mFocusHistory[ mFocusHistory.size() -1 ].GetHandle(); // Impl of Actor is not null - if( target && target.OnStage() ) + if( target && target.GetProperty< bool >( Actor::Property::CONNECTED_TO_SCENE ) ) { // Delete pre focused actor in history because it will pushed again by SetCurrentFocusActor() mFocusHistory.pop_back(); @@ -500,9 +519,18 @@ bool KeyboardFocusManager::MoveFocus(Toolkit::Control::KeyboardFocus::Direction nextFocusableActor = mPreFocusChangeSignal.Emit( currentFocusActor, Actor(), direction ); mIsWaitingKeyboardFocusChangeCommit = false; } + else if(mEnableDefaultAlgorithm) + { + // We should find it among the actors nearby. + Integration::SceneHolder window = Integration::SceneHolder::Get(currentFocusActor); + if(window) + { + nextFocusableActor = Toolkit::FocusFinder::GetNearestFocusableActor(window.GetRootLayer(), currentFocusActor, direction); + } + } } - if( nextFocusableActor && nextFocusableActor.IsKeyboardFocusable() ) + if( nextFocusableActor && nextFocusableActor.GetProperty< bool >( Actor::Property::KEYBOARD_FOCUSABLE ) ) { // Whether the next focusable actor is a layout control if( IsLayoutControl( nextFocusableActor ) ) @@ -528,7 +556,7 @@ bool KeyboardFocusManager::DoMoveFocusWithinLayoutControl(Toolkit::Control contr Actor nextFocusableActor = GetImplementation( control ).GetNextKeyboardFocusableActor(actor, direction, mFocusGroupLoopEnabled); if(nextFocusableActor) { - if(!nextFocusableActor.IsKeyboardFocusable()) + if(!nextFocusableActor.GetProperty< bool >( Actor::Property::KEYBOARD_FOCUSABLE )) { // If the actor is not focusable, ask the same layout control for the next actor to focus return DoMoveFocusWithinLayoutControl(control, nextFocusableActor, direction); @@ -547,7 +575,7 @@ bool KeyboardFocusManager::DoMoveFocusWithinLayoutControl(Toolkit::Control contr mIsWaitingKeyboardFocusChangeCommit = false; } - if (committedFocusActor && committedFocusActor.IsKeyboardFocusable()) + if (committedFocusActor && committedFocusActor.GetProperty< bool >( Actor::Property::KEYBOARD_FOCUSABLE )) { // Whether the commited focusable actor is a layout control if(IsLayoutControl(committedFocusActor)) @@ -730,22 +758,28 @@ Actor KeyboardFocusManager::GetFocusIndicatorActor() if( ! mFocusIndicatorActor ) { // Create the default if it hasn't been set and one that's shared by all the keyboard focusable actors - mFocusIndicatorActor = Toolkit::ImageView::New( FOCUS_BORDER_IMAGE_PATH ); + const std::string imageDirPath = AssetManager::GetDaliImagePath(); + mFocusIndicatorActor = Toolkit::ImageView::New( imageDirPath + FOCUS_BORDER_IMAGE_FILE_NAME ); // Apply size constraint to the focus indicator mFocusIndicatorActor.SetResizePolicy( ResizePolicy::FILL_TO_PARENT, Dimension::ALL_DIMENSIONS ); } - mFocusIndicatorActor.SetParentOrigin( ParentOrigin::CENTER ); - mFocusIndicatorActor.SetAnchorPoint( AnchorPoint::CENTER ); - mFocusIndicatorActor.SetPosition(0.0f, 0.0f); + mFocusIndicatorActor.SetProperty( Actor::Property::PARENT_ORIGIN, ParentOrigin::CENTER ); + mFocusIndicatorActor.SetProperty( Actor::Property::ANCHOR_POINT, AnchorPoint::CENTER ); + mFocusIndicatorActor.SetProperty( Actor::Property::POSITION, Vector2(0.0f, 0.0f)); return mFocusIndicatorActor; } void KeyboardFocusManager::OnKeyEvent(const KeyEvent& event) { - std::string keyName = event.keyPressedName; + AccessibilityAdaptor accessibilityAdaptor = AccessibilityAdaptor::Get(); + bool isAccessibilityEnabled = accessibilityAdaptor.IsEnabled(); + + Toolkit::AccessibilityManager accessibilityManager = Toolkit::AccessibilityManager::Get(); + + std::string keyName = event.GetKeyName(); if( mIsFocusIndicatorShown == UNKNOWN ) { @@ -754,11 +788,11 @@ void KeyboardFocusManager::OnKeyEvent(const KeyEvent& event) bool isFocusStartableKey = false; - if(event.state == KeyEvent::Down) + if(event.GetState() == KeyEvent::DOWN) { if (keyName == "Left") { - if(!mIsFocusIndicatorShown) + if(!isAccessibilityEnabled) { if(mIsFocusIndicatorShown == HIDE) { @@ -775,15 +809,13 @@ void KeyboardFocusManager::OnKeyEvent(const KeyEvent& event) } else { - // Move the focus towards left - MoveFocus(Toolkit::Control::KeyboardFocus::LEFT); + // Move the accessibility focus backward + accessibilityManager.MoveFocusBackward(); } - - isFocusStartableKey = true; } else if (keyName == "Right") { - if(!mIsFocusIndicatorShown) + if(!isAccessibilityEnabled) { if( mIsFocusIndicatorShown == HIDE ) { @@ -798,13 +830,13 @@ void KeyboardFocusManager::OnKeyEvent(const KeyEvent& event) } else { - // Move the focus towards right - MoveFocus(Toolkit::Control::KeyboardFocus::RIGHT); + // Move the accessibility focus forward + accessibilityManager.MoveFocusForward(); } isFocusStartableKey = true; } - else if (keyName == "Up") + else if (keyName == "Up" && !isAccessibilityEnabled) { if( mIsFocusIndicatorShown == HIDE ) { @@ -819,7 +851,7 @@ void KeyboardFocusManager::OnKeyEvent(const KeyEvent& event) isFocusStartableKey = true; } - else if (keyName == "Down") + else if (keyName == "Down" && !isAccessibilityEnabled) { if( mIsFocusIndicatorShown == HIDE ) { @@ -834,7 +866,7 @@ void KeyboardFocusManager::OnKeyEvent(const KeyEvent& event) isFocusStartableKey = true; } - else if (keyName == "Prior") + else if (keyName == "Prior" && !isAccessibilityEnabled) { if( mIsFocusIndicatorShown == HIDE ) { @@ -849,7 +881,7 @@ void KeyboardFocusManager::OnKeyEvent(const KeyEvent& event) isFocusStartableKey = true; } - else if (keyName == "Next") + else if (keyName == "Next" && !isAccessibilityEnabled) { if( mIsFocusIndicatorShown == HIDE ) { @@ -864,7 +896,7 @@ void KeyboardFocusManager::OnKeyEvent(const KeyEvent& event) isFocusStartableKey = true; } - else if (keyName == "Tab") + else if (keyName == "Tab" && !isAccessibilityEnabled) { if( mIsFocusIndicatorShown == HIDE ) { @@ -875,12 +907,20 @@ void KeyboardFocusManager::OnKeyEvent(const KeyEvent& event) { // "Tab" key changes the focus group in the forward direction and // "Shift-Tab" key changes it in the backward direction. - DoMoveFocusToNextFocusGroup(!event.IsShiftModifier()); + if(!DoMoveFocusToNextFocusGroup(!event.IsShiftModifier())) + { + // If the focus group is not changed, Move the focus towards right, "Shift-Tap" key moves the focus towards left. + if(!MoveFocus(event.IsShiftModifier() ? Toolkit::Control::KeyboardFocus::LEFT : Toolkit::Control::KeyboardFocus::RIGHT)) + { + // If the focus is not moved, Move the focus towards down, "Shift-Tap" key moves the focus towards up. + MoveFocus(event.IsShiftModifier() ? Toolkit::Control::KeyboardFocus::UP : Toolkit::Control::KeyboardFocus::DOWN); + } + } } isFocusStartableKey = true; } - else if (keyName == "space") + else if (keyName == "space" && !isAccessibilityEnabled) { if( mIsFocusIndicatorShown == HIDE ) { @@ -890,7 +930,7 @@ void KeyboardFocusManager::OnKeyEvent(const KeyEvent& event) isFocusStartableKey = true; } - else if (keyName == "") + else if (keyName == "" && !isAccessibilityEnabled) { // Check the fake key event for evas-plugin case if( mIsFocusIndicatorShown == HIDE ) @@ -901,19 +941,19 @@ void KeyboardFocusManager::OnKeyEvent(const KeyEvent& event) isFocusStartableKey = true; } - else if (keyName == "Backspace") + else if (keyName == "Backspace" && !isAccessibilityEnabled) { // Emit signal to go back to the previous view??? } - else if (keyName == "Escape") + else if (keyName == "Escape" && !isAccessibilityEnabled) { } } - else if(event.state == KeyEvent::Up) + else if(event.GetState() == KeyEvent::UP) { if (keyName == "Return") { - if( mIsFocusIndicatorShown == HIDE ) + if((mIsFocusIndicatorShown == HIDE) && !isAccessibilityEnabled) { // Show focus indicator mIsFocusIndicatorShown = SHOW; @@ -921,7 +961,16 @@ void KeyboardFocusManager::OnKeyEvent(const KeyEvent& event) else { // The focused actor has enter pressed on it - Actor actor = GetCurrentFocusActor(); + Actor actor; + if( !isAccessibilityEnabled ) + { + actor = GetCurrentFocusActor(); + } + else + { + actor = accessibilityManager.GetCurrentFocusActor(); + } + if( actor ) { DoKeyboardEnter( actor ); @@ -932,7 +981,7 @@ void KeyboardFocusManager::OnKeyEvent(const KeyEvent& event) } } - if( isFocusStartableKey && mIsFocusIndicatorShown == SHOW ) + if(isFocusStartableKey && ( mIsFocusIndicatorShown == SHOW ) && !isAccessibilityEnabled) { Actor actor = GetCurrentFocusActor(); if( actor ) @@ -949,11 +998,10 @@ void KeyboardFocusManager::OnKeyEvent(const KeyEvent& event) // Let's try to move the initial focus MoveFocus(Toolkit::Control::KeyboardFocus::RIGHT); } - } } -void KeyboardFocusManager::OnTouch(const TouchData& touch) +void KeyboardFocusManager::OnTouch(const TouchEvent& touch) { // if mIsFocusIndicatorShown is UNKNOWN, it means Configuration is not loaded. // Try to load configuration. @@ -964,10 +1012,20 @@ void KeyboardFocusManager::OnTouch(const TouchData& touch) // Clear the focus when user touch the screen. // We only do this on a Down event, otherwise the clear action may override a manually focused actor. - // If mClearFocusOnTouch is false, do not clear the focus even if user touch the screen. - if( (( touch.GetPointCount() < 1 ) || ( touch.GetState( 0 ) == PointState::DOWN )) && mClearFocusOnTouch ) + if(((touch.GetPointCount() < 1) || (touch.GetState(0) == PointState::DOWN))) { - ClearFocus(); + // If mClearFocusOnTouch is false, do not clear the focus even if user touch the screen. + if(mClearFocusOnTouch) + { + ClearFocus(); + } + + // If KEYBOARD_FOCUSABLE and TOUCH_FOCUSABLE is true, set focus actor + Actor hitActor = touch.GetHitActor(0); + if(hitActor && hitActor.GetProperty(Actor::Property::KEYBOARD_FOCUSABLE) && hitActor.GetProperty(DevelActor::Property::TOUCH_FOCUSABLE)) + { + SetCurrentFocusActor(hitActor); + } } } @@ -1065,6 +1123,16 @@ bool KeyboardFocusManager::IsFocusIndicatorEnabled() const return ( mEnableFocusIndicator == ENABLE ); } +void KeyboardFocusManager::EnableDefaultAlgorithm(bool enable) +{ + mEnableDefaultAlgorithm = enable; +} + +bool KeyboardFocusManager::IsDefaultAlgorithmEnabled() const +{ + return mEnableDefaultAlgorithm; +} + } // namespace Internal } // namespace Toolkit