Add post processor
[platform/core/uifw/dali-toolkit.git] / dali-toolkit / internal / focus-manager / keyinput-focus-manager-impl.cpp
1 /*
2  * Copyright (c) 2021 Samsung Electronics Co., Ltd.
3  *
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
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
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.
15  *
16  */
17
18 // CLASS HEADER
19 #include "keyinput-focus-manager-impl.h"
20
21 // EXTERNAL INCLUDES
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
28
29 namespace Dali
30 {
31 namespace Toolkit
32 {
33 namespace Internal
34 {
35 namespace
36 {
37 // Signals
38
39 const char* const SIGNAL_KEY_INPUT_FOCUS_CHANGED = "keyInputFocusChanged";
40
41 } // namespace
42
43 KeyInputFocusManager::KeyInputFocusManager()
44 : mSlotDelegate(this),
45   mCurrentFocusControl()
46 {
47   // Retrieve all the existing widnows
48   Dali::SceneHolderList sceneHolders = Adaptor::Get().GetSceneHolders();
49   for(auto iter = sceneHolders.begin(); iter != sceneHolders.end(); ++iter)
50   {
51     (*iter).KeyEventGeneratedSignal().Connect(mSlotDelegate, &KeyInputFocusManager::OnKeyEvent);
52   }
53
54   // Get notified when any new scene holder is created afterwards
55   Adaptor::Get().WindowCreatedSignal().Connect(mSlotDelegate, &KeyInputFocusManager::OnSceneHolderCreated);
56 }
57
58 KeyInputFocusManager::~KeyInputFocusManager()
59 {
60 }
61
62 void KeyInputFocusManager::OnSceneHolderCreated(Dali::Integration::SceneHolder& sceneHolder)
63 {
64   sceneHolder.KeyEventGeneratedSignal().Connect(mSlotDelegate, &KeyInputFocusManager::OnKeyEvent);
65 }
66
67 void KeyInputFocusManager::SetFocus(Toolkit::Control control)
68 {
69   if(!control)
70   {
71     // No-op
72     return;
73   }
74
75   if(control == mCurrentFocusControl)
76   {
77     // Control already has focus
78     return;
79   }
80
81   control.OffSceneSignal().Connect(mSlotDelegate, &KeyInputFocusManager::OnFocusControlSceneDisconnection);
82
83   Dali::Toolkit::Control previousFocusControl = GetCurrentFocusControl();
84   if(previousFocusControl)
85   {
86     // Notify the control that it has lost key input focus
87     GetImplementation(previousFocusControl).OnKeyInputFocusLost();
88   }
89
90   // Set control to currentFocusControl
91   mCurrentFocusControl = control;
92
93   // Tell the new actor that it has gained focus.
94   GetImplementation(control).OnKeyInputFocusGained();
95
96   // Emit the signal to inform focus change to the application.
97   if(!mKeyInputFocusChangedSignal.Empty())
98   {
99     mKeyInputFocusChangedSignal.Emit(control, previousFocusControl);
100   }
101 }
102
103 void KeyInputFocusManager::RemoveFocus(Toolkit::Control control)
104 {
105   if(control == mCurrentFocusControl)
106   {
107     control.OffSceneSignal().Disconnect(mSlotDelegate, &KeyInputFocusManager::OnFocusControlSceneDisconnection);
108
109     // Notify the control that it has lost key input focus
110     GetImplementation(control).OnKeyInputFocusLost();
111
112     mCurrentFocusControl.Reset();
113   }
114 }
115
116 Toolkit::Control KeyInputFocusManager::GetCurrentFocusControl() const
117 {
118   return mCurrentFocusControl;
119 }
120
121 Toolkit::KeyInputFocusManager::KeyInputFocusChangedSignalType& KeyInputFocusManager::KeyInputFocusChangedSignal()
122 {
123   return mKeyInputFocusChangedSignal;
124 }
125
126 bool KeyInputFocusManager::OnKeyEvent(const KeyEvent& event)
127 {
128   bool consumed = false;
129
130   Toolkit::Control control = GetCurrentFocusControl();
131   if(control)
132   {
133     // Notify the control about the key event
134     consumed = EmitKeyEventSignal(control, event);
135   }
136
137   return consumed;
138 }
139
140 bool KeyInputFocusManager::EmitKeyEventSignal(Toolkit::Control control, const KeyEvent& event)
141 {
142   bool consumed = false;
143
144   if(control)
145   {
146     consumed = GetImplementation(control).EmitKeyEventSignal(event);
147
148     // if control doesn't consume KeyEvent, give KeyEvent to its parent.
149     if(!consumed)
150     {
151       Toolkit::Control parent = Toolkit::Control::DownCast(control.GetParent());
152
153       if(parent)
154       {
155         consumed = EmitKeyEventSignal(parent, event);
156       }
157     }
158   }
159
160   return consumed;
161 }
162
163 void KeyInputFocusManager::OnFocusControlSceneDisconnection(Dali::Actor actor)
164 {
165   RemoveFocus(Dali::Toolkit::Control::DownCast(actor));
166 }
167
168 bool KeyInputFocusManager::DoConnectSignal(BaseObject* object, ConnectionTrackerInterface* tracker, const std::string& signalName, FunctorDelegate* functor)
169 {
170   bool                  connected(true);
171   KeyInputFocusManager* manager = dynamic_cast<KeyInputFocusManager*>(object);
172
173   if(manager)
174   {
175     if(0 == strcmp(signalName.c_str(), SIGNAL_KEY_INPUT_FOCUS_CHANGED))
176     {
177       manager->KeyInputFocusChangedSignal().Connect(tracker, functor);
178     }
179     else
180     {
181       // signalName does not match any signal
182       connected = false;
183     }
184   }
185
186   return connected;
187 }
188
189 } // namespace Internal
190
191 } // namespace Toolkit
192
193 } // namespace Dali