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