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