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.
19 #include "keyinput-focus-manager-impl.h"
22 #include <dali-toolkit/public-api/controls/control-impl.h>
23 #include <dali/integration-api/adaptor-framework/adaptor.h>
24 #include <dali/integration-api/adaptor-framework/scene-holder.h>
25 #include <dali/integration-api/debug.h>
26 #include <dali/public-api/actors/layer.h>
27 #include <cstring> // for strcmp
39 const char* const SIGNAL_KEY_INPUT_FOCUS_CHANGED = "keyInputFocusChanged";
43 KeyInputFocusManager::KeyInputFocusManager()
44 : mSlotDelegate(this),
45 mCurrentFocusControl()
47 // Retrieve all the existing widnows
48 Dali::SceneHolderList sceneHolders = Adaptor::Get().GetSceneHolders();
49 for(auto iter = sceneHolders.begin(); iter != sceneHolders.end(); ++iter)
51 (*iter).KeyEventGeneratedSignal().Connect(mSlotDelegate, &KeyInputFocusManager::OnKeyEvent);
54 // Get notified when any new scene holder is created afterwards
55 Adaptor::Get().WindowCreatedSignal().Connect(mSlotDelegate, &KeyInputFocusManager::OnSceneHolderCreated);
58 KeyInputFocusManager::~KeyInputFocusManager()
62 void KeyInputFocusManager::OnSceneHolderCreated(Dali::Integration::SceneHolder& sceneHolder)
64 sceneHolder.KeyEventGeneratedSignal().Connect(mSlotDelegate, &KeyInputFocusManager::OnKeyEvent);
67 void KeyInputFocusManager::SetFocus(Toolkit::Control control)
75 if(control == mCurrentFocusControl)
77 // Control already has focus
81 control.OffSceneSignal().Connect(mSlotDelegate, &KeyInputFocusManager::OnFocusControlSceneDisconnection);
83 Dali::Toolkit::Control previousFocusControl = GetCurrentFocusControl();
84 if(previousFocusControl)
86 // Notify the control that it has lost key input focus
87 GetImplementation(previousFocusControl).OnKeyInputFocusLost();
90 // Set control to currentFocusControl
91 mCurrentFocusControl = control;
93 // Tell the new actor that it has gained focus.
94 GetImplementation(control).OnKeyInputFocusGained();
96 // Emit the signal to inform focus change to the application.
97 if(!mKeyInputFocusChangedSignal.Empty())
99 mKeyInputFocusChangedSignal.Emit(control, previousFocusControl);
103 void KeyInputFocusManager::RemoveFocus(Toolkit::Control control)
105 if(control == mCurrentFocusControl)
107 control.OffSceneSignal().Disconnect(mSlotDelegate, &KeyInputFocusManager::OnFocusControlSceneDisconnection);
109 // Notify the control that it has lost key input focus
110 GetImplementation(control).OnKeyInputFocusLost();
112 mCurrentFocusControl.Reset();
116 Toolkit::Control KeyInputFocusManager::GetCurrentFocusControl() const
118 return mCurrentFocusControl;
121 Toolkit::KeyInputFocusManager::KeyInputFocusChangedSignalType& KeyInputFocusManager::KeyInputFocusChangedSignal()
123 return mKeyInputFocusChangedSignal;
126 bool KeyInputFocusManager::OnKeyEvent(const KeyEvent& event)
128 bool consumed = false;
130 Toolkit::Control control = GetCurrentFocusControl();
133 // Notify the control about the key event
134 consumed = EmitKeyEventSignal(control, event);
140 bool KeyInputFocusManager::EmitKeyEventSignal(Toolkit::Control control, const KeyEvent& event)
142 bool consumed = false;
146 consumed = GetImplementation(control).EmitKeyEventSignal(event);
148 // if control doesn't consume KeyEvent, give KeyEvent to its parent.
151 Toolkit::Control parent = Toolkit::Control::DownCast(control.GetParent());
155 consumed = EmitKeyEventSignal(parent, event);
163 void KeyInputFocusManager::OnFocusControlSceneDisconnection(Dali::Actor actor)
165 RemoveFocus(Dali::Toolkit::Control::DownCast(actor));
168 bool KeyInputFocusManager::DoConnectSignal(BaseObject* object, ConnectionTrackerInterface* tracker, const std::string& signalName, FunctorDelegate* functor)
170 bool connected(true);
171 KeyInputFocusManager* manager = dynamic_cast<KeyInputFocusManager*>(object);
175 if(0 == strcmp(signalName.c_str(), SIGNAL_KEY_INPUT_FOCUS_CHANGED))
177 manager->KeyInputFocusChangedSignal().Connect(tracker, functor);
181 // signalName does not match any signal
189 } // namespace Internal
191 } // namespace Toolkit