2 * Copyright (c) 2021 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/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>
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>
43 #if defined(DEBUG_ENABLED)
44 Debug::Filter* gLogFilter = Debug::Filter::New(Debug::NoLogging, false, "LOG_INPUT_METHOD_CONTEXT");
48 InputMethodContextPtr InputMethodContextCocoa::New(Dali::Actor actor)
50 InputMethodContextPtr manager;
52 if(actor && Adaptor::IsAvailable())
54 manager = new InputMethodContextCocoa(actor);
60 void InputMethodContextCocoa::Finalize()
64 InputMethodContextCocoa::InputMethodContextCocoa(Dali::Actor actor)
65 : mIMFCursorPosition(0),
67 mRestoreAfterFocusLost(false),
68 mIdleCallbackConnected(false)
70 actor.OnSceneSignal().Connect(this, &InputMethodContextCocoa::OnStaged);
73 InputMethodContextCocoa::~InputMethodContextCocoa()
78 void InputMethodContextCocoa::Initialize()
83 // Callbacks for predicitive text support.
84 void InputMethodContextCocoa::ConnectCallbacks()
88 void InputMethodContextCocoa::DisconnectCallbacks()
92 void InputMethodContextCocoa::Activate()
94 // Reset mIdleCallbackConnected
95 mIdleCallbackConnected = false;
98 void InputMethodContextCocoa::Deactivate()
100 mIdleCallbackConnected = false;
103 void InputMethodContextCocoa::Reset()
105 DALI_LOG_INFO(gLogFilter, Debug::General, "InputMethodContextCocoa::Reset\n");
108 ImfContext* InputMethodContextCocoa::GetContext()
110 DALI_LOG_INFO(gLogFilter, Debug::General, "InputMethodContextCocoa::GetContext\n");
115 bool InputMethodContextCocoa::RestoreAfterFocusLost() const
117 return mRestoreAfterFocusLost;
120 void InputMethodContextCocoa::SetRestoreAfterFocusLost(bool toggle)
122 mRestoreAfterFocusLost = toggle;
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.
130 void InputMethodContextCocoa::PreEditChanged(void*, ImfContext* imfContext, void* eventInfo)
132 DALI_LOG_INFO(gLogFilter, Debug::General, "InputMethodContextCocoa::PreEditChanged\n");
135 void InputMethodContextCocoa::CommitReceived(void*, ImfContext* imfContext, void* eventInfo)
137 DALI_LOG_INFO(gLogFilter, Debug::General, "InputMethodContextCocoa::CommitReceived\n");
139 if(Dali::Adaptor::IsAvailable())
141 const std::string keyString(static_cast<char*>(eventInfo));
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);
147 if(callbackData.update)
149 mIMFCursorPosition = static_cast<int>(callbackData.cursorPosition);
151 NotifyCursorPosition();
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.
161 bool InputMethodContextCocoa::RetrieveSurrounding(void* data, ImfContext* imfContext, char** text, int* cursorPosition)
163 DALI_LOG_INFO(gLogFilter, Debug::General, "InputMethodContextCocoa::RetrieveSurrounding\n");
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);
169 if(callbackData.update)
173 *text = strdup(callbackData.currentText.c_str());
178 mIMFCursorPosition = static_cast<int>(callbackData.cursorPosition);
179 *cursorPosition = mIMFCursorPosition;
187 * Called when an InputMethodContext delete surrounding event is received.
188 * Here we tell the application that it should delete a certain range.
190 void InputMethodContextCocoa::DeleteSurrounding(void* data, ImfContext* imfContext, void* eventInfo)
192 DALI_LOG_INFO(gLogFilter, Debug::General, "InputMethodContextCocoa::DeleteSurrounding\n");
195 void InputMethodContextCocoa::NotifyCursorPosition()
197 DALI_LOG_INFO(gLogFilter, Debug::General, "InputMethodContextCocoa::NotifyCursorPosition\n");
200 void InputMethodContextCocoa::SetCursorPosition(unsigned int cursorPosition)
202 DALI_LOG_INFO(gLogFilter, Debug::General, "InputMethodContextCocoa::SetCursorPosition\n");
204 mIMFCursorPosition = static_cast<int>(cursorPosition);
207 unsigned int InputMethodContextCocoa::GetCursorPosition() const
209 DALI_LOG_INFO(gLogFilter, Debug::General, "InputMethodContextCocoa::GetCursorPosition\n");
211 return static_cast<unsigned int>(mIMFCursorPosition);
214 void InputMethodContextCocoa::SetSurroundingText(const std::string& text)
216 DALI_LOG_INFO(gLogFilter, Debug::General, "InputMethodContextCocoa::SetSurroundingText\n");
218 mSurroundingText = text;
221 const std::string& InputMethodContextCocoa::GetSurroundingText() const
223 DALI_LOG_INFO(gLogFilter, Debug::General, "InputMethodContextCocoa::GetSurroundingText\n");
225 return mSurroundingText;
228 void InputMethodContextCocoa::NotifyTextInputMultiLine(bool multiLine)
232 Dali::InputMethodContext::TextDirection InputMethodContextCocoa::GetTextDirection()
234 Dali::InputMethodContext::TextDirection direction(Dali::InputMethodContext::LEFT_TO_RIGHT);
239 Rect<int> InputMethodContextCocoa::GetInputMethodArea()
241 int xPos, yPos, width, height;
243 width = height = xPos = yPos = 0;
245 return Rect<int>(xPos, yPos, width, height);
248 void InputMethodContextCocoa::ApplyOptions(const InputMethodOptions& options)
250 using namespace Dali::InputMethod::Category;
254 if(mOptions.CompareAndSet(PANEL_LAYOUT, options, index))
257 if(mOptions.CompareAndSet(BUTTON_ACTION, options, index))
260 if(mOptions.CompareAndSet(AUTO_CAPITALIZE, options, index))
263 if(mOptions.CompareAndSet(VARIATION, options, index))
268 void InputMethodContextCocoa::SetInputPanelData(const std::string& data)
270 DALI_LOG_INFO(gLogFilter, Debug::General, "InputMethodContextCocoa::SetInputPanelData\n");
273 void InputMethodContextCocoa::GetInputPanelData(std::string& data)
275 DALI_LOG_INFO(gLogFilter, Debug::General, "InputMethodContextCocoa::GetInputPanelData\n");
278 Dali::InputMethodContext::State InputMethodContextCocoa::GetInputPanelState()
280 DALI_LOG_INFO(gLogFilter, Debug::General, "InputMethodContextCocoa::GetInputPanelState\n");
281 return Dali::InputMethodContext::DEFAULT;
284 void InputMethodContextCocoa::SetReturnKeyState(bool visible)
286 DALI_LOG_INFO(gLogFilter, Debug::General, "InputMethodContextCocoa::SetReturnKeyState\n");
289 void InputMethodContextCocoa::AutoEnableInputPanel(bool enabled)
291 DALI_LOG_INFO(gLogFilter, Debug::General, "InputMethodContextCocoa::AutoEnableInputPanel\n");
294 void InputMethodContextCocoa::ShowInputPanel()
296 DALI_LOG_INFO(gLogFilter, Debug::General, "InputMethodContextCocoa::ShowInputPanel\n");
299 void InputMethodContextCocoa::HideInputPanel()
301 DALI_LOG_INFO(gLogFilter, Debug::General, "InputMethodContextCocoa::HideInputPanel\n");
304 Dali::InputMethodContext::KeyboardType InputMethodContextCocoa::GetKeyboardType()
306 return Dali::InputMethodContext::KeyboardType::SOFTWARE_KEYBOARD;
309 std::string InputMethodContextCocoa::GetInputPanelLocale()
311 DALI_LOG_INFO(gLogFilter, Debug::General, "InputMethodContextCocoa::GetInputPanelLocale\n");
313 std::string locale = "";
317 void InputMethodContextCocoa::SetContentMIMETypes(const std::string& mimeTypes)
319 DALI_LOG_INFO(gLogFilter, Debug::General, "InputMethodContextCocoa::SetContentMIMETypes\n");
322 bool InputMethodContextCocoa::FilterEventKey(const Dali::KeyEvent& keyEvent)
324 bool eventHandled(false);
326 if(!KeyLookup::IsDeviceButton(keyEvent.GetKeyName().c_str()))
328 //check whether it's key down or key up event
329 if(keyEvent.GetState() == Dali::KeyEvent::DOWN)
331 eventHandled = ProcessEventKeyDown(keyEvent);
333 else if(keyEvent.GetState() == Dali::KeyEvent::UP)
335 eventHandled = ProcessEventKeyUp(keyEvent);
342 void InputMethodContextCocoa::SetInputPanelLanguage(Dali::InputMethodContext::InputPanelLanguage language)
344 DALI_LOG_INFO(gLogFilter, Debug::General, "InputMethodContextCocoa::SetInputPanelLanguage\n");
347 Dali::InputMethodContext::InputPanelLanguage InputMethodContextCocoa::GetInputPanelLanguage() const
349 DALI_LOG_INFO(gLogFilter, Debug::General, "InputMethodContextCocoa::GetInputPanelLanguage\n");
350 return Dali::InputMethodContext::InputPanelLanguage::AUTOMATIC;
353 void InputMethodContextCocoa::SetInputPanelPosition(unsigned int x, unsigned int y)
355 DALI_LOG_INFO(gLogFilter, Debug::General, "InputMethodContextCocoa::SetInputPanelPosition\n");
358 void InputMethodContextCocoa::GetPreeditStyle(Dali::InputMethodContext::PreEditAttributeDataContainer& attrs) const
360 DALI_LOG_INFO(gLogFilter, Debug::General, "InputMethodContextCocoa::GetPreeditStyle\n");
361 attrs = mPreeditAttrs;
364 bool InputMethodContextCocoa::ProcessEventKeyDown(const Dali::KeyEvent& keyEvent)
366 bool eventHandled(false);
370 bool InputMethodContextCocoa::ProcessEventKeyUp(const Dali::KeyEvent& keyEvent)
372 bool eventHandled(false);
376 void InputMethodContextCocoa::OnStaged(Dali::Actor actor)
383 } // namespace Adaptor
385 } // namespace Internal