2 // Copyright (c) 2014 Samsung Electronics Co., Ltd.
4 // Licensed under the Flora License, Version 1.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://floralicense.org/license/
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.
18 #include "keyinput-focus-manager-impl.h"
21 #include <dali-toolkit/public-api/controls/control-impl.h>
22 #include <dali/integration-api/debug.h>
33 KeyInputFocusManager::KeyInputFocusManager()
34 : mSlotDelegate( this )
36 Stage::GetCurrent().KeyEventSignal().Connect(mSlotDelegate, &KeyInputFocusManager::OnKeyEvent);
39 KeyInputFocusManager::~KeyInputFocusManager()
43 void KeyInputFocusManager::SetFocus(Toolkit::Control control)
51 unsigned int actorID = control.GetId();
53 ActorQueueIterator pos = std::find( mFocusActorsQueue.begin(), mFocusActorsQueue.end(), actorID);
55 if((!mFocusActorsQueue.empty()) && (pos == mFocusActorsQueue.begin()))
57 //Actor allready in front, so No-op
61 if(pos != mFocusActorsQueue.end())
63 //A previously focused actor wants to regain focus
64 mFocusActorsQueue.erase(pos);
68 control.OffStageSignal().Connect( mSlotDelegate, &KeyInputFocusManager::OnFocusActorStageDisconnection );
71 Dali::Toolkit::Control previousFocusControl;
72 if(!mFocusActorsQueue.empty())
74 previousFocusControl = Dali::Toolkit::Control::DownCast(Stage::GetCurrent().GetRootLayer().FindChildById(mFocusActorsQueue.front()));
75 if(previousFocusControl)
77 // Notify the control that it has lost key input focus
78 previousFocusControl.GetImplementation().OnKeyInputFocusLost();
82 mFocusActorsQueue.push_front(actorID);
84 // Tell the new actor that it has gained focus.
85 control.GetImplementation().OnKeyInputFocusGained();
87 // Emit the signal to inform focus change to the application.
88 if ( !mKeyInputFocusChangedSignalV2.Empty() )
90 mKeyInputFocusChangedSignalV2.Emit( control, previousFocusControl );
94 Control KeyInputFocusManager::GetCurrentFocusControl() const
96 Control currentFocusControl;
98 if(!mFocusActorsQueue.empty())
100 currentFocusControl = Dali::Toolkit::Control::DownCast(Stage::GetCurrent().GetRootLayer().FindChildById(mFocusActorsQueue.front()));
103 return currentFocusControl;
106 void KeyInputFocusManager::RemoveFocus(Toolkit::Control control)
110 unsigned int actorId = control.GetId();
111 ActorQueueIterator pos = std::find( mFocusActorsQueue.begin(), mFocusActorsQueue.end(), actorId);
113 if(pos != mFocusActorsQueue.end())
115 control.OffStageSignal().Disconnect( mSlotDelegate, &KeyInputFocusManager::OnFocusActorStageDisconnection );
117 // Notify the control that it has lost key input focus
118 control.GetImplementation().OnKeyInputFocusLost();
120 if(pos == mFocusActorsQueue.begin())
122 Actor previousFocusActor;
124 mFocusActorsQueue.erase(pos);
125 if(!mFocusActorsQueue.empty())
127 previousFocusActor = Stage::GetCurrent().GetRootLayer().FindChildById(mFocusActorsQueue.front());
130 Dali::Toolkit::Control previouscontrol = Dali::Toolkit::Control::DownCast(previousFocusActor);
133 // Tell the new actor that it has gained focus.
134 previouscontrol.GetImplementation().OnKeyInputFocusGained();
139 //If the removed actor is not currently focused, then no need to emit signal.
140 mFocusActorsQueue.erase(pos);
147 bool KeyInputFocusManager::IsKeyboardListener(Toolkit::Control control) const
151 if(!mFocusActorsQueue.empty())
153 unsigned int actorId = control.GetId();
154 ActorQueueConstIterator pos = std::find(mFocusActorsQueue.begin(), mFocusActorsQueue.end(), actorId);
156 if(pos != mFocusActorsQueue.end())
165 Toolkit::KeyInputFocusManager::KeyInputFocusChangedSignalV2& KeyInputFocusManager::KeyInputFocusChangedSignal()
167 return mKeyInputFocusChangedSignalV2;
170 Toolkit::KeyInputFocusManager::UnhandledKeyEventSignalV2& KeyInputFocusManager::UnhandledKeyEventSignal()
172 return mUnhandledKeyEventSignalV2;
175 void KeyInputFocusManager::OnKeyEvent(const KeyEvent& event)
177 bool consumed = false;
179 ActorQueueIterator iter = mFocusActorsQueue.begin();
181 Layer rootLayer = Stage::GetCurrent().GetRootLayer();
183 while(!mFocusActorsQueue.empty() && !consumed && (iter != mFocusActorsQueue.end()))
185 Actor actor = rootLayer.FindChildById(*iter);
186 Dali::Toolkit::Control control = Dali::Toolkit::Control::DownCast(actor);
189 // Notify the control about the key event
190 consumed = control.GetImplementation().EmitKeyEventSignal(event);
197 // Emit signal to inform that a key event is not consumed.
198 if( !mUnhandledKeyEventSignalV2.Empty() )
200 mUnhandledKeyEventSignalV2.Emit(event);
205 void KeyInputFocusManager::OnFocusActorStageDisconnection( Dali::Actor actor )
207 RemoveFocus(Dali::Toolkit::Control::DownCast(actor));
210 bool KeyInputFocusManager::DoConnectSignal( BaseObject* object, ConnectionTrackerInterface* tracker, const std::string& signalName, FunctorDelegate* functor )
212 Dali::BaseHandle handle( object );
214 bool connected( true );
215 KeyInputFocusManager* manager = dynamic_cast<KeyInputFocusManager*>(object);
217 if( Dali::Toolkit::KeyInputFocusManager::SIGNAL_KEY_INPUT_FOCUS_CHANGED == signalName )
219 manager->KeyInputFocusChangedSignal().Connect( tracker, functor );
223 // signalName does not match any signal
230 } // namespace Internal
232 } // namespace Toolkit