Merge "DALi Version 1.2.49" into devel/master
[platform/core/uifw/dali-toolkit.git] / dali-toolkit / internal / focus-manager / keyinput-focus-manager-impl.cpp
1 /*
2  * Copyright (c) 2014 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 <cstring> // for strcmp
23 #include <dali/public-api/actors/layer.h>
24 #include <dali/public-api/common/stage.h>
25 #include <dali/devel-api/common/stage-devel.h>
26
27 // INTERNAL INCLUDES
28 #include <dali-toolkit/public-api/controls/control-impl.h>
29 #include <dali/integration-api/debug.h>
30
31 namespace Dali
32 {
33
34 namespace Toolkit
35 {
36
37 namespace Internal
38 {
39
40 namespace
41 {
42
43 // Signals
44
45 const char* const SIGNAL_KEY_INPUT_FOCUS_CHANGED = "keyInputFocusChanged";
46
47 }
48
49 KeyInputFocusManager::KeyInputFocusManager()
50 : mSlotDelegate( this ),
51   mCurrentFocusControl()
52 {
53   DevelStage::KeyEventGeneratedSignal( Stage::GetCurrent() ).Connect(mSlotDelegate, &KeyInputFocusManager::OnKeyEvent);
54 }
55
56 KeyInputFocusManager::~KeyInputFocusManager()
57 {
58 }
59
60 void KeyInputFocusManager::SetFocus( Toolkit::Control control )
61 {
62   if( !control )
63   {
64     // No-op
65     return;
66   }
67
68   if( control == mCurrentFocusControl )
69   {
70     // Control already has focus
71     return;
72   }
73
74   control.OffStageSignal().Connect( mSlotDelegate, &KeyInputFocusManager::OnFocusControlStageDisconnection );
75
76   Dali::Toolkit::Control previousFocusControl = GetCurrentFocusControl();
77   if( previousFocusControl )
78   {
79     // Notify the control that it has lost key input focus
80     GetImplementation( previousFocusControl ).OnKeyInputFocusLost();
81   }
82
83   // Set control to currentFocusControl
84   mCurrentFocusControl = control;
85
86   // Tell the new actor that it has gained focus.
87   GetImplementation( control ).OnKeyInputFocusGained();
88
89   // Emit the signal to inform focus change to the application.
90   if ( !mKeyInputFocusChangedSignal.Empty() )
91   {
92     mKeyInputFocusChangedSignal.Emit( control, previousFocusControl );
93   }
94 }
95
96 void KeyInputFocusManager::RemoveFocus( Toolkit::Control control )
97 {
98   if( control == mCurrentFocusControl )
99   {
100     control.OffStageSignal().Disconnect( mSlotDelegate, &KeyInputFocusManager::OnFocusControlStageDisconnection );
101
102     // Notify the control that it has lost key input focus
103     GetImplementation( control ).OnKeyInputFocusLost();
104
105     mCurrentFocusControl.Reset();
106   }
107 }
108
109 Toolkit::Control KeyInputFocusManager::GetCurrentFocusControl() const
110 {
111   return mCurrentFocusControl;
112 }
113
114 Toolkit::KeyInputFocusManager::KeyInputFocusChangedSignalType& KeyInputFocusManager::KeyInputFocusChangedSignal()
115 {
116   return mKeyInputFocusChangedSignal;
117 }
118
119 bool KeyInputFocusManager::OnKeyEvent( const KeyEvent& event )
120 {
121   bool consumed = false;
122
123   Toolkit::Control control = GetCurrentFocusControl();
124   if( control )
125   {
126     // Notify the control about the key event
127     consumed = EmitKeyEventSignal( control, event );
128   }
129
130   return consumed;
131 }
132
133 bool KeyInputFocusManager::EmitKeyEventSignal( Toolkit::Control control, const KeyEvent& event )
134 {
135   bool consumed = false;
136
137   if( control )
138   {
139     consumed = GetImplementation( control ).EmitKeyEventSignal( event );
140
141     // if control doesn't consume KeyEvent, give KeyEvent to its parent.
142     if( !consumed )
143     {
144       Toolkit::Control parent = Toolkit::Control::DownCast( control.GetParent() );
145
146       if( parent )
147       {
148         consumed = EmitKeyEventSignal( parent, event );
149       }
150     }
151   }
152
153   return consumed;
154 }
155
156 void KeyInputFocusManager::OnFocusControlStageDisconnection( Dali::Actor actor )
157 {
158   RemoveFocus( Dali::Toolkit::Control::DownCast( actor ) );
159 }
160
161
162 bool KeyInputFocusManager::DoConnectSignal( BaseObject* object, ConnectionTrackerInterface* tracker, const std::string& signalName, FunctorDelegate* functor )
163 {
164   bool connected( true );
165   KeyInputFocusManager* manager = dynamic_cast<KeyInputFocusManager*>( object );
166
167   if( manager )
168   {
169     if( 0 == strcmp( signalName.c_str(), SIGNAL_KEY_INPUT_FOCUS_CHANGED ) )
170     {
171       manager->KeyInputFocusChangedSignal().Connect( tracker, functor );
172     }
173     else
174     {
175       // signalName does not match any signal
176       connected = false;
177     }
178   }
179
180   return connected;
181 }
182
183 } // namespace Internal
184
185 } // namespace Toolkit
186
187 } // namespace Dali