2 * Copyright (c) 2020 Samsung Electronics Co., Ltd.
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
19 #include <dali/internal/input/macos/input-method-context-impl-mac.h>
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>
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>
46 #if defined(DEBUG_ENABLED)
47 Debug::Filter* gLogFilter = Debug::Filter::New( Debug::NoLogging, false, "LOG_INPUT_METHOD_CONTEXT" );
51 InputMethodContextPtr InputMethodContextCocoa::New( Dali::Actor actor )
53 InputMethodContextPtr manager;
55 if ( actor && Adaptor::IsAvailable() )
57 manager = new InputMethodContextCocoa( actor );
63 void InputMethodContextCocoa::Finalize()
67 InputMethodContextCocoa::InputMethodContextCocoa( Dali::Actor actor )
68 : mIMFCursorPosition( 0 ),
70 mRestoreAfterFocusLost( false ),
71 mIdleCallbackConnected( false )
74 actor.OnSceneSignal().Connect( this, &InputMethodContextCocoa::OnStaged );
77 InputMethodContextCocoa::~InputMethodContextCocoa()
82 void InputMethodContextCocoa::Initialize()
87 // Callbacks for predicitive text support.
88 void InputMethodContextCocoa::ConnectCallbacks()
92 void InputMethodContextCocoa::DisconnectCallbacks()
96 void InputMethodContextCocoa::Activate()
98 // Reset mIdleCallbackConnected
99 mIdleCallbackConnected = false;
102 void InputMethodContextCocoa::Deactivate()
104 mIdleCallbackConnected = false;
107 void InputMethodContextCocoa::Reset()
109 DALI_LOG_INFO( gLogFilter, Debug::General, "InputMethodContextCocoa::Reset\n" );
112 ImfContext* InputMethodContextCocoa::GetContext()
114 DALI_LOG_INFO( gLogFilter, Debug::General, "InputMethodContextCocoa::GetContext\n" );
119 bool InputMethodContextCocoa::RestoreAfterFocusLost() const
121 return mRestoreAfterFocusLost;
124 void InputMethodContextCocoa::SetRestoreAfterFocusLost( bool toggle )
126 mRestoreAfterFocusLost = toggle;
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.
134 void InputMethodContextCocoa::PreEditChanged( void*, ImfContext* imfContext, void* eventInfo )
136 DALI_LOG_INFO( gLogFilter, Debug::General, "InputMethodContextCocoa::PreEditChanged\n" );
139 void InputMethodContextCocoa::CommitReceived( void*, ImfContext* imfContext, void* eventInfo )
141 DALI_LOG_INFO( gLogFilter, Debug::General, "InputMethodContextCocoa::CommitReceived\n" );
143 if ( Dali::Adaptor::IsAvailable() )
145 const std::string keyString( static_cast<char*>( eventInfo ) );
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 );
151 if( callbackData.update )
153 mIMFCursorPosition = static_cast<int>( callbackData.cursorPosition );
155 NotifyCursorPosition();
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.
165 bool InputMethodContextCocoa::RetrieveSurrounding( void* data, ImfContext* imfContext, char** text, int* cursorPosition )
167 DALI_LOG_INFO( gLogFilter, Debug::General, "InputMethodContextCocoa::RetrieveSurrounding\n" );
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 );
173 if( callbackData.update )
177 *text = strdup( callbackData.currentText.c_str() );
182 mIMFCursorPosition = static_cast<int>( callbackData.cursorPosition );
183 *cursorPosition = mIMFCursorPosition;
191 * Called when an InputMethodContext delete surrounding event is received.
192 * Here we tell the application that it should delete a certain range.
194 void InputMethodContextCocoa::DeleteSurrounding( void* data, ImfContext* imfContext, void* eventInfo )
196 DALI_LOG_INFO( gLogFilter, Debug::General, "InputMethodContextCocoa::DeleteSurrounding\n" );
199 void InputMethodContextCocoa::NotifyCursorPosition()
201 DALI_LOG_INFO( gLogFilter, Debug::General, "InputMethodContextCocoa::NotifyCursorPosition\n" );
204 void InputMethodContextCocoa::SetCursorPosition( unsigned int cursorPosition )
206 DALI_LOG_INFO( gLogFilter, Debug::General, "InputMethodContextCocoa::SetCursorPosition\n" );
208 mIMFCursorPosition = static_cast<int>( cursorPosition );
211 unsigned int InputMethodContextCocoa::GetCursorPosition() const
213 DALI_LOG_INFO( gLogFilter, Debug::General, "InputMethodContextCocoa::GetCursorPosition\n" );
215 return static_cast<unsigned int>( mIMFCursorPosition );
218 void InputMethodContextCocoa::SetSurroundingText( const std::string& text )
220 DALI_LOG_INFO( gLogFilter, Debug::General, "InputMethodContextCocoa::SetSurroundingText\n" );
222 mSurroundingText = text;
225 const std::string& InputMethodContextCocoa::GetSurroundingText() const
227 DALI_LOG_INFO( gLogFilter, Debug::General, "InputMethodContextCocoa::GetSurroundingText\n" );
229 return mSurroundingText;
232 void InputMethodContextCocoa::NotifyTextInputMultiLine( bool multiLine )
236 Dali::InputMethodContext::TextDirection InputMethodContextCocoa::GetTextDirection()
238 Dali::InputMethodContext::TextDirection direction ( Dali::InputMethodContext::LEFT_TO_RIGHT);
243 Rect<int> InputMethodContextCocoa::GetInputMethodArea()
245 int xPos, yPos, width, height;
247 width = height = xPos = yPos = 0;
249 return Rect<int>(xPos,yPos,width,height);
252 void InputMethodContextCocoa::ApplyOptions( const InputMethodOptions& options )
254 using namespace Dali::InputMethod::Category;
258 if ( mOptions.CompareAndSet(PANEL_LAYOUT, options, index) )
261 if ( mOptions.CompareAndSet(BUTTON_ACTION, options, index) )
264 if ( mOptions.CompareAndSet(AUTO_CAPITALIZE, options, index) )
267 if ( mOptions.CompareAndSet(VARIATION, options, index) )
272 void InputMethodContextCocoa::SetInputPanelData( const std::string& data )
274 DALI_LOG_INFO( gLogFilter, Debug::General, "InputMethodContextCocoa::SetInputPanelData\n" );
277 void InputMethodContextCocoa::GetInputPanelData( std::string& data )
279 DALI_LOG_INFO( gLogFilter, Debug::General, "InputMethodContextCocoa::GetInputPanelData\n" );
282 Dali::InputMethodContext::State InputMethodContextCocoa::GetInputPanelState()
284 DALI_LOG_INFO( gLogFilter, Debug::General, "InputMethodContextCocoa::GetInputPanelState\n" );
285 return Dali::InputMethodContext::DEFAULT;
288 void InputMethodContextCocoa::SetReturnKeyState( bool visible )
290 DALI_LOG_INFO( gLogFilter, Debug::General, "InputMethodContextCocoa::SetReturnKeyState\n" );
293 void InputMethodContextCocoa::AutoEnableInputPanel( bool enabled )
295 DALI_LOG_INFO( gLogFilter, Debug::General, "InputMethodContextCocoa::AutoEnableInputPanel\n" );
298 void InputMethodContextCocoa::ShowInputPanel()
300 DALI_LOG_INFO( gLogFilter, Debug::General, "InputMethodContextCocoa::ShowInputPanel\n" );
303 void InputMethodContextCocoa::HideInputPanel()
305 DALI_LOG_INFO( gLogFilter, Debug::General, "InputMethodContextCocoa::HideInputPanel\n" );
308 Dali::InputMethodContext::KeyboardType InputMethodContextCocoa::GetKeyboardType()
310 return Dali::InputMethodContext::KeyboardType::SOFTWARE_KEYBOARD;
313 std::string InputMethodContextCocoa::GetInputPanelLocale()
315 DALI_LOG_INFO( gLogFilter, Debug::General, "InputMethodContextCocoa::GetInputPanelLocale\n" );
317 std::string locale = "";
321 void InputMethodContextCocoa::SetContentMIMETypes( const std::string& mimeTypes )
323 DALI_LOG_INFO( gLogFilter, Debug::General, "InputMethodContextCocoa::SetContentMIMETypes\n" );
326 bool InputMethodContextCocoa::FilterEventKey( const Dali::KeyEvent& keyEvent )
328 bool eventHandled( false );
330 if ( ! KeyLookup::IsDeviceButton( keyEvent.GetKeyName().c_str() ))
332 //check whether it's key down or key up event
333 if ( keyEvent.GetState() == Dali::KeyEvent::DOWN )
335 eventHandled = ProcessEventKeyDown( keyEvent );
337 else if ( keyEvent.GetState() == Dali::KeyEvent::UP )
339 eventHandled = ProcessEventKeyUp( keyEvent );
346 void InputMethodContextCocoa::SetInputPanelLanguage( Dali::InputMethodContext::InputPanelLanguage language )
348 DALI_LOG_INFO( gLogFilter, Debug::General, "InputMethodContextCocoa::SetInputPanelLanguage\n" );
351 Dali::InputMethodContext::InputPanelLanguage InputMethodContextCocoa::GetInputPanelLanguage() const
353 DALI_LOG_INFO( gLogFilter, Debug::General, "InputMethodContextCocoa::GetInputPanelLanguage\n" );
354 return Dali::InputMethodContext::InputPanelLanguage::AUTOMATIC;
357 void InputMethodContextCocoa::SetInputPanelPosition( unsigned int x, unsigned int y )
359 DALI_LOG_INFO( gLogFilter, Debug::General, "InputMethodContextCocoa::SetInputPanelPosition\n" );
362 void InputMethodContextCocoa::GetPreeditStyle( Dali::InputMethodContext::PreEditAttributeDataContainer& attrs ) const
364 DALI_LOG_INFO( gLogFilter, Debug::General, "InputMethodContextCocoa::GetPreeditStyle\n" );
365 attrs = mPreeditAttrs;
368 bool InputMethodContextCocoa::ProcessEventKeyDown( const Dali::KeyEvent& keyEvent )
370 bool eventHandled( false );
374 bool InputMethodContextCocoa::ProcessEventKeyUp( const Dali::KeyEvent& keyEvent )
376 bool eventHandled( false );
380 void InputMethodContextCocoa::OnStaged( Dali::Actor actor )