Merge "Add to set IME position" into devel/master
[platform/core/uifw/dali-adaptor.git] / dali / internal / input / windows / input-method-context-impl-win.cpp
1 /*\r
2  * Copyright (c) 2018 Samsung Electronics Co., Ltd.\r
3  *\r
4  * Licensed under the Apache License, Version 2.0 (the "License");\r
5  * you may not use this file except in compliance with the License.\r
6  * You may obtain a copy of the License at\r
7  *\r
8  * http://www.apache.org/licenses/LICENSE-2.0\r
9  *\r
10  * Unless required by applicable law or agreed to in writing, software\r
11  * distributed under the License is distributed on an "AS IS" BASIS,\r
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
13  * See the License for the specific language governing permissions and\r
14  * limitations under the License.\r
15  *\r
16  */\r
17 \r
18 // CLASS HEADER\r
19 #include <dali/internal/input/windows/input-method-context-impl-win.h>\r
20 \r
21 // EXTERNAL INCLUDES\r
22 #include <dali/public-api/events/key-event.h>\r
23 #include <dali/public-api/adaptor-framework/key.h>\r
24 #include <dali/public-api/object/type-registry.h>\r
25 #include <dali/integration-api/debug.h>\r
26 \r
27 // INTERNAL INCLUDES\r
28 #include <dali/integration-api/adaptor.h>\r
29 #include <dali/internal/adaptor/common/adaptor-impl.h>\r
30 #include <dali/internal/system/common/locale-utils.h>\r
31 #include <dali/internal/system/common/singleton-service-impl.h>\r
32 #include <dali/internal/input/common/virtual-keyboard-impl.h>\r
33 #include <dali/internal/input/common/key-impl.h>\r
34 \r
35 namespace Dali\r
36 {\r
37 \r
38 namespace Internal\r
39 {\r
40 \r
41 namespace Adaptor\r
42 {\r
43 \r
44 InputMethodContextPtr InputMethodContextWin::New( Dali::Actor actor )\r
45 {\r
46   InputMethodContextPtr manager;\r
47 \r
48   if ( actor && Adaptor::IsAvailable() )\r
49   {\r
50     manager = new InputMethodContextWin( actor );\r
51   }\r
52 \r
53   return manager;\r
54 }\r
55 \r
56 void InputMethodContextWin::Finalize()\r
57 {\r
58 }\r
59 \r
60 InputMethodContextWin::InputMethodContextWin( Dali::Actor actor )\r
61 : mWin32Window( 0 ),\r
62   mIMFCursorPosition( 0 ),\r
63   mSurroundingText(),\r
64   mRestoreAfterFocusLost( false ),\r
65   mIdleCallbackConnected( false )\r
66 {\r
67 \r
68   actor.OnStageSignal().Connect( this, &InputMethodContextWin::OnStaged );\r
69 }\r
70 \r
71 InputMethodContextWin::~InputMethodContextWin()\r
72 {\r
73   Finalize();\r
74 }\r
75 \r
76 void InputMethodContextWin::Initialize()\r
77 {\r
78   CreateContext( mWin32Window );\r
79   ConnectCallbacks();\r
80 }\r
81 \r
82 void InputMethodContextWin::CreateContext( WinWindowHandle winHandle )\r
83 {\r
84   DALI_LOG_INFO( gLogFilter, Debug::General, "InputMethodContextWin::CreateContext\n" );\r
85 }\r
86 \r
87 void InputMethodContextWin::DeleteContext()\r
88 {\r
89   DALI_LOG_INFO( gLogFilter, Debug::General, "InputMethodContextWin::DeleteContext\n" );\r
90 }\r
91 \r
92 // Callbacks for predicitive text support.\r
93 void InputMethodContextWin::ConnectCallbacks()\r
94 {\r
95 }\r
96 \r
97 void InputMethodContextWin::DisconnectCallbacks()\r
98 {\r
99 }\r
100 \r
101 void InputMethodContextWin::Activate()\r
102 {\r
103   // Reset mIdleCallbackConnected\r
104   mIdleCallbackConnected = false;\r
105 }\r
106 \r
107 void InputMethodContextWin::Deactivate()\r
108 {\r
109   mIdleCallbackConnected = false;\r
110 }\r
111 \r
112 void InputMethodContextWin::Reset()\r
113 {\r
114   DALI_LOG_INFO( gLogFilter, Debug::General, "InputMethodContextWin::Reset\n" );\r
115 }\r
116 \r
117 ImfContext* InputMethodContextWin::GetContext()\r
118 {\r
119   DALI_LOG_INFO( gLogFilter, Debug::General, "InputMethodContextWin::GetContext\n" );\r
120 \r
121   return NULL;\r
122 }\r
123 \r
124 bool InputMethodContextWin::RestoreAfterFocusLost() const\r
125 {\r
126   return mRestoreAfterFocusLost;\r
127 }\r
128 \r
129 void InputMethodContextWin::SetRestoreAfterFocusLost( bool toggle )\r
130 {\r
131   mRestoreAfterFocusLost = toggle;\r
132 }\r
133 \r
134 /**\r
135  * Called when an InputMethodContext Pre-Edit changed event is received.\r
136  * We are still predicting what the user is typing.  The latest string is what the InputMethodContext module thinks\r
137  * the user wants to type.\r
138  */\r
139 void InputMethodContextWin::PreEditChanged( void*, ImfContext* imfContext, void* eventInfo )\r
140 {\r
141   DALI_LOG_INFO( gLogFilter, Debug::General, "InputMethodContextWin::PreEditChanged\n" );\r
142 }\r
143 \r
144 void InputMethodContextWin::CommitReceived( void*, ImfContext* imfContext, void* eventInfo )\r
145 {\r
146   DALI_LOG_INFO( gLogFilter, Debug::General, "InputMethodContextWin::CommitReceived\n" );\r
147 \r
148   if ( Dali::Adaptor::IsAvailable() )\r
149   {\r
150     const std::string keyString( static_cast<char*>( eventInfo ) );\r
151 \r
152     Dali::InputMethodContext handle( this );\r
153     Dali::InputMethodContext::EventData eventData( Dali::InputMethodContext::COMMIT, keyString, 0, 0 );\r
154     Dali::InputMethodContext::CallbackData callbackData = mEventSignal.Emit( handle, eventData );\r
155 \r
156     if( callbackData.update )\r
157     {\r
158       mIMFCursorPosition = static_cast<int>( callbackData.cursorPosition );\r
159 \r
160       NotifyCursorPosition();\r
161     }\r
162   }\r
163 }\r
164 \r
165 /**\r
166  * Called when an InputMethodContext retrieve surround event is received.\r
167  * Here the InputMethodContext module wishes to know the string we are working with and where within the string the cursor is\r
168  * We need to signal the application to tell us this information.\r
169  */\r
170 bool InputMethodContextWin::RetrieveSurrounding( void* data, ImfContext* imfContext, char** text, int* cursorPosition )\r
171 {\r
172   DALI_LOG_INFO( gLogFilter, Debug::General, "InputMethodContextWin::RetrieveSurrounding\n" );\r
173 \r
174   Dali::InputMethodContext::EventData imfData( Dali::InputMethodContext::GET_SURROUNDING, std::string(), 0, 0 );\r
175   Dali::InputMethodContext handle( this );\r
176   Dali::InputMethodContext::CallbackData callbackData = mEventSignal.Emit( handle, imfData );\r
177 \r
178   if( callbackData.update )\r
179   {\r
180     if( text )\r
181     {\r
182       *text = strdup( callbackData.currentText.c_str() );\r
183     }\r
184 \r
185     if( cursorPosition )\r
186     {\r
187       mIMFCursorPosition = static_cast<int>( callbackData.cursorPosition );\r
188       *cursorPosition = mIMFCursorPosition;\r
189     }\r
190   }\r
191 \r
192   return true;\r
193 }\r
194 \r
195 /**\r
196  * Called when an InputMethodContext delete surrounding event is received.\r
197  * Here we tell the application that it should delete a certain range.\r
198  */\r
199 void InputMethodContextWin::DeleteSurrounding( void* data, ImfContext* imfContext, void* eventInfo )\r
200 {\r
201   DALI_LOG_INFO( gLogFilter, Debug::General, "InputMethodContextWin::DeleteSurrounding\n" );\r
202 }\r
203 \r
204 void InputMethodContextWin::NotifyCursorPosition()\r
205 {\r
206   DALI_LOG_INFO( gLogFilter, Debug::General, "InputMethodContextWin::NotifyCursorPosition\n" );\r
207 }\r
208 \r
209 void InputMethodContextWin::SetCursorPosition( unsigned int cursorPosition )\r
210 {\r
211   DALI_LOG_INFO( gLogFilter, Debug::General, "InputMethodContextWin::SetCursorPosition\n" );\r
212 \r
213   mIMFCursorPosition = static_cast<int>( cursorPosition );\r
214 }\r
215 \r
216 unsigned int InputMethodContextWin::GetCursorPosition() const\r
217 {\r
218   DALI_LOG_INFO( gLogFilter, Debug::General, "InputMethodContextWin::GetCursorPosition\n" );\r
219 \r
220   return static_cast<unsigned int>( mIMFCursorPosition );\r
221 }\r
222 \r
223 void InputMethodContextWin::SetSurroundingText( const std::string& text )\r
224 {\r
225   DALI_LOG_INFO( gLogFilter, Debug::General, "InputMethodContextWin::SetSurroundingText\n" );\r
226 \r
227   mSurroundingText = text;\r
228 }\r
229 \r
230 const std::string& InputMethodContextWin::GetSurroundingText() const\r
231 {\r
232   DALI_LOG_INFO( gLogFilter, Debug::General, "InputMethodContextWin::GetSurroundingText\n" );\r
233 \r
234   return mSurroundingText;\r
235 }\r
236 \r
237 void InputMethodContextWin::NotifyTextInputMultiLine( bool multiLine )\r
238 {\r
239 }\r
240 \r
241 Dali::InputMethodContext::TextDirection InputMethodContextWin::GetTextDirection()\r
242 {\r
243   Dali::InputMethodContext::TextDirection direction ( Dali::InputMethodContext::LeftToRight );\r
244 \r
245   return direction;\r
246 }\r
247 \r
248 Rect<int> InputMethodContextWin::GetInputMethodArea()\r
249 {\r
250   int xPos, yPos, width, height;\r
251 \r
252   width = height = xPos = yPos = 0;\r
253 \r
254   return Rect<int>(xPos,yPos,width,height);\r
255 }\r
256 \r
257 void InputMethodContextWin::ApplyOptions( const InputMethodOptions& options )\r
258 {\r
259   using namespace Dali::InputMethod::Category;\r
260 \r
261   int index;\r
262 \r
263   if ( mOptions.CompareAndSet(PANEL_LAYOUT, options, index) )\r
264   {\r
265   }\r
266   if ( mOptions.CompareAndSet(BUTTON_ACTION, options, index) )\r
267   {\r
268   }\r
269   if ( mOptions.CompareAndSet(AUTO_CAPITALIZE, options, index) )\r
270   {\r
271   }\r
272   if ( mOptions.CompareAndSet(VARIATION, options, index) )\r
273   {\r
274   }\r
275 }\r
276 \r
277 void InputMethodContextWin::SetInputPanelData( const std::string& data )\r
278 {\r
279   DALI_LOG_INFO( gLogFilter, Debug::General, "InputMethodContextWin::SetInputPanelData\n" );\r
280 }\r
281 \r
282 void InputMethodContextWin::GetInputPanelData( std::string& data )\r
283 {\r
284   DALI_LOG_INFO( gLogFilter, Debug::General, "InputMethodContextWin::GetInputPanelData\n" );\r
285 }\r
286 \r
287 Dali::InputMethodContext::State InputMethodContextWin::GetInputPanelState()\r
288 {\r
289   DALI_LOG_INFO( gLogFilter, Debug::General, "InputMethodContextWin::GetInputPanelState\n" );\r
290   return Dali::InputMethodContext::DEFAULT;\r
291 }\r
292 \r
293 void InputMethodContextWin::SetReturnKeyState( bool visible )\r
294 {\r
295   DALI_LOG_INFO( gLogFilter, Debug::General, "InputMethodContextWin::SetReturnKeyState\n" );\r
296 }\r
297 \r
298 void InputMethodContextWin::AutoEnableInputPanel( bool enabled )\r
299 {\r
300   DALI_LOG_INFO( gLogFilter, Debug::General, "InputMethodContextWin::AutoEnableInputPanel\n" );\r
301 }\r
302 \r
303 void InputMethodContextWin::ShowInputPanel()\r
304 {\r
305   DALI_LOG_INFO( gLogFilter, Debug::General, "InputMethodContextWin::ShowInputPanel\n" );\r
306 }\r
307 \r
308 void InputMethodContextWin::HideInputPanel()\r
309 {\r
310   DALI_LOG_INFO( gLogFilter, Debug::General, "InputMethodContextWin::HideInputPanel\n" );\r
311 }\r
312 \r
313 Dali::InputMethodContext::KeyboardType InputMethodContextWin::GetKeyboardType()\r
314 {\r
315   return Dali::InputMethodContext::KeyboardType::SOFTWARE_KEYBOARD;\r
316 }\r
317 \r
318 std::string InputMethodContextWin::GetInputPanelLocale()\r
319 {\r
320   DALI_LOG_INFO( gLogFilter, Debug::General, "InputMethodContextWin::GetInputPanelLocale\n" );\r
321 \r
322   std::string locale = "";\r
323   return locale;\r
324 }\r
325 \r
326 void InputMethodContextWin::SetContentMIMETypes( const std::string& mimeTypes )\r
327 {\r
328   DALI_LOG_INFO( gLogFilter, Debug::General, "InputMethodContextWin::SetContentMIMETypes\n" );\r
329 }\r
330 \r
331 bool InputMethodContextWin::FilterEventKey( const Dali::KeyEvent& keyEvent )\r
332 {\r
333   bool eventHandled( false );\r
334 \r
335   if ( ! KeyLookup::IsDeviceButton( keyEvent.keyPressedName.c_str() ))\r
336   {\r
337     //check whether it's key down or key up event\r
338     if ( keyEvent.state == KeyEvent::Down )\r
339     {\r
340       eventHandled = ProcessEventKeyDown( keyEvent );\r
341     }\r
342     else if ( keyEvent.state == KeyEvent::Up )\r
343     {\r
344       eventHandled = ProcessEventKeyUp( keyEvent );\r
345     }\r
346   }\r
347 \r
348   return eventHandled;\r
349 }\r
350 \r
351 void InputMethodContextWin::SetInputPanelLanguage( Dali::InputMethodContext::InputPanelLanguage language )\r
352 {\r
353   DALI_LOG_INFO( gLogFilter, Debug::General, "InputMethodContextWin::SetInputPanelLanguage\n" );\r
354 }\r
355 \r
356 Dali::InputMethodContext::InputPanelLanguage InputMethodContextWin::GetInputPanelLanguage() const\r
357 {\r
358   DALI_LOG_INFO( gLogFilter, Debug::General, "InputMethodContextWin::GetInputPanelLanguage\n" );\r
359   return Dali::InputMethodContext::InputPanelLanguage::AUTOMATIC;\r
360 }\r
361 \r
362 void InputMethodContextWin::SetInputPanelPosition( unsigned int x, unsigned int y )\r
363 {\r
364   DALI_LOG_INFO( gLogFilter, Debug::General, "InputMethodContextWin::SetInputPanelPosition\n" );\r
365 }\r
366 \r
367 bool InputMethodContextWin::ProcessEventKeyDown( const KeyEvent& keyEvent )\r
368 {\r
369   bool eventHandled( false );\r
370   return eventHandled;\r
371 }\r
372 \r
373 bool InputMethodContextWin::ProcessEventKeyUp( const KeyEvent& keyEvent )\r
374 {\r
375   bool eventHandled( false );\r
376   return eventHandled;\r
377 }\r
378 \r
379 void InputMethodContextWin::OnStaged( Dali::Actor actor )\r
380 {\r
381   WinWindowHandle winWindow( AnyCast< WinWindowHandle >( Dali::Integration::SceneHolder::Get( actor ).GetNativeHandle() ) );\r
382 \r
383   if( mWin32Window != winWindow )\r
384   {\r
385     mWin32Window = winWindow;\r
386 \r
387     // Reset\r
388     Finalize();\r
389     Initialize();\r
390   }\r
391 }\r
392 \r
393 } // Adaptor\r
394 \r
395 } // Internal\r
396 \r
397 } // Dali\r
398 \r