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
30 #include <dali-toolkit/devel-api/controls/control-devel.h>
42 const char* const SIGNAL_KEY_INPUT_FOCUS_CHANGED = "keyInputFocusChanged";
46 KeyInputFocusManager::KeyInputFocusManager()
47 : mSlotDelegate(this),
48 mCurrentFocusControl()
50 // Retrieve all the existing widnows
51 Dali::SceneHolderList sceneHolders = Adaptor::Get().GetSceneHolders();
52 for(auto iter = sceneHolders.begin(); iter != sceneHolders.end(); ++iter)
54 (*iter).KeyEventGeneratedSignal().Connect(mSlotDelegate, &KeyInputFocusManager::OnKeyEvent);
57 // Get notified when any new scene holder is created afterwards
58 Adaptor::Get().WindowCreatedSignal().Connect(mSlotDelegate, &KeyInputFocusManager::OnSceneHolderCreated);
61 KeyInputFocusManager::~KeyInputFocusManager()
65 void KeyInputFocusManager::OnSceneHolderCreated(Dali::Integration::SceneHolder& sceneHolder)
67 sceneHolder.KeyEventGeneratedSignal().Connect(mSlotDelegate, &KeyInputFocusManager::OnKeyEvent);
70 void KeyInputFocusManager::SetFocus(Toolkit::Control control)
78 if(control == mCurrentFocusControl)
80 // Control already has focus
84 control.OffSceneSignal().Connect(mSlotDelegate, &KeyInputFocusManager::OnFocusControlSceneDisconnection);
86 Dali::Toolkit::Control previousFocusControl = GetCurrentFocusControl();
88 // Set control to currentFocusControl
89 mCurrentFocusControl = control;
91 if(previousFocusControl)
93 // Notify the control that it has lost key input focus
94 GetImplementation(previousFocusControl).OnKeyInputFocusLost();
97 // Tell the new actor that it has gained focus.
98 GetImplementation(control).OnKeyInputFocusGained();
100 // Emit the signal to inform focus change to the application.
101 if(!mKeyInputFocusChangedSignal.Empty())
103 mKeyInputFocusChangedSignal.Emit(control, previousFocusControl);
107 void KeyInputFocusManager::RemoveFocus(Toolkit::Control control)
109 if(control == mCurrentFocusControl)
111 control.OffSceneSignal().Disconnect(mSlotDelegate, &KeyInputFocusManager::OnFocusControlSceneDisconnection);
113 mCurrentFocusControl.Reset();
115 // Notify the control that it has lost key input focus
116 GetImplementation(control).OnKeyInputFocusLost();
120 Toolkit::Control KeyInputFocusManager::GetCurrentFocusControl() const
122 return mCurrentFocusControl;
125 Toolkit::KeyInputFocusManager::KeyInputFocusChangedSignalType& KeyInputFocusManager::KeyInputFocusChangedSignal()
127 return mKeyInputFocusChangedSignal;
130 bool KeyInputFocusManager::OnKeyEvent(const KeyEvent& event)
132 bool consumed = false;
134 Toolkit::Control control = GetCurrentFocusControl();
137 Dali::Actor dispatch = control;
140 // If the DISPATCH_KEY_EVENTS is false, it cannot emit key event.
141 Toolkit::Control dispatchControl = Toolkit::Control::DownCast(dispatch);
142 if(dispatchControl && !dispatchControl.GetProperty<bool>(Toolkit::DevelControl::Property::DISPATCH_KEY_EVENTS))
146 dispatch = dispatch.GetParent();
149 // Notify the control about the key event
150 consumed = EmitKeyEventSignal(control, event);
156 bool KeyInputFocusManager::EmitKeyEventSignal(Toolkit::Control control, const KeyEvent& event)
158 bool consumed = false;
162 consumed = GetImplementation(control).EmitKeyEventSignal(event);
164 // if control doesn't consume KeyEvent, give KeyEvent to its parent.
167 Toolkit::Control parent = Toolkit::Control::DownCast(control.GetParent());
171 consumed = EmitKeyEventSignal(parent, event);
179 void KeyInputFocusManager::OnFocusControlSceneDisconnection(Dali::Actor actor)
181 RemoveFocus(Dali::Toolkit::Control::DownCast(actor));
184 bool KeyInputFocusManager::DoConnectSignal(BaseObject* object, ConnectionTrackerInterface* tracker, const std::string& signalName, FunctorDelegate* functor)
186 bool connected(true);
187 KeyInputFocusManager* manager = dynamic_cast<KeyInputFocusManager*>(object);
191 if(0 == strcmp(signalName.c_str(), SIGNAL_KEY_INPUT_FOCUS_CHANGED))
193 manager->KeyInputFocusChangedSignal().Connect(tracker, functor);
197 // signalName does not match any signal
205 } // namespace Internal
207 } // namespace Toolkit