From 902b99609087dc3f003ca12e84b8a4d5fd989302 Mon Sep 17 00:00:00 2001 From: "Daniel R." <47796739+polybiusproxy@users.noreply.github.com> Date: Sat, 19 Oct 2024 20:14:25 +0200 Subject: [PATCH] core/ime: Implement caret events --- src/core/libraries/ime/ime_common.h | 16 ++++++- src/core/libraries/ime/ime_ui.cpp | 68 ++++++++++++++++++++--------- 2 files changed, 62 insertions(+), 22 deletions(-) diff --git a/src/core/libraries/ime/ime_common.h b/src/core/libraries/ime/ime_common.h index 99005872..8965b277 100644 --- a/src/core/libraries/ime/ime_common.h +++ b/src/core/libraries/ime/ime_common.h @@ -145,10 +145,24 @@ struct OrbisImeKeyboardResourceIdArray { u32 resourceId[6]; }; +enum class OrbisImeCaretMovementDirection : u32 { + STILL = 0, + LEFT = 1, + RIGHT = 2, + UP = 3, + DOWN = 4, + HOME = 5, + END = 6, + PAGE_UP = 7, + PAGE_DOWN = 8, + TOP = 9, + BOTTOM = 10, +}; + union OrbisImeEventParam { OrbisImeRect rect; OrbisImeEditText text; - u32 caretMove; // OrbisImeCaretMovementDirection + OrbisImeCaretMovementDirection caretMove; OrbisImeKeycode keycode; OrbisImeKeyboardResourceIdArray resourceIdArray; char16_t* candidateWord; diff --git a/src/core/libraries/ime/ime_ui.cpp b/src/core/libraries/ime/ime_ui.cpp index b8fba8a7..0207761e 100644 --- a/src/core/libraries/ime/ime_ui.cpp +++ b/src/core/libraries/ime/ime_ui.cpp @@ -160,7 +160,7 @@ void ImeUi::DrawInputText() { SetKeyboardFocusHere(); } if (InputTextEx("##ImeInput", nullptr, state->current_text.begin(), ime_param->maxTextLength, - input_size, ImGuiInputTextFlags_CallbackEdit, InputTextCallback, this)) { + input_size, ImGuiInputTextFlags_CallbackAlways, InputTextCallback, this)) { state->input_changed = true; } } @@ -169,32 +169,58 @@ int ImeUi::InputTextCallback(ImGuiInputTextCallbackData* data) { ImeUi* ui = static_cast(data->UserData); ASSERT(ui); - OrbisImeEditText eventParam{}; - eventParam.str = reinterpret_cast(ui->ime_param->work); - eventParam.caretIndex = data->CursorPos; - eventParam.areaNum = 1; + static int lastCaretPos = -1; + if (lastCaretPos == -1) { + lastCaretPos = data->CursorPos; + } else if (data->CursorPos != lastCaretPos) { + OrbisImeCaretMovementDirection caretDirection = OrbisImeCaretMovementDirection::STILL; + if (data->CursorPos < lastCaretPos) { + caretDirection = OrbisImeCaretMovementDirection::LEFT; + } else if (data->CursorPos > lastCaretPos) { + caretDirection = OrbisImeCaretMovementDirection::RIGHT; + } - eventParam.textArea[0].mode = 1; // Edit - eventParam.textArea[0].index = 0; - eventParam.textArea[0].length = data->BufTextLen; + OrbisImeEvent event{}; + event.id = OrbisImeEventId::UPDATE_CARET; + event.param.caretMove = caretDirection; - if (!ui->state->ConvertUTF8ToOrbis(data->Buf, data->BufTextLen, eventParam.str, - ui->ime_param->maxTextLength)) { - LOG_ERROR(Lib_ImeDialog, "Failed to convert Orbis char to UTF-8"); - return 0; + lastCaretPos = data->CursorPos; + ui->state->SendEvent(&event); } - if (!ui->state->ConvertUTF8ToOrbis(data->Buf, data->BufTextLen, ui->ime_param->inputTextBuffer, - ui->ime_param->maxTextLength)) { - LOG_ERROR(Lib_ImeDialog, "Failed to convert Orbis char to UTF-8"); - return 0; + static std::string lastText; + std::string currentText(data->Buf, data->BufTextLen); + if (currentText != lastText) { + OrbisImeEditText eventParam{}; + eventParam.str = reinterpret_cast(ui->ime_param->work); + eventParam.caretIndex = data->CursorPos; + eventParam.areaNum = 1; + + eventParam.textArea[0].mode = 1; // Edit + eventParam.textArea[0].index = 0; + eventParam.textArea[0].length = data->BufTextLen; + + if (!ui->state->ConvertUTF8ToOrbis(data->Buf, data->BufTextLen, eventParam.str, + ui->ime_param->maxTextLength)) { + LOG_ERROR(Lib_ImeDialog, "Failed to convert Orbis char to UTF-8"); + return 0; + } + + if (!ui->state->ConvertUTF8ToOrbis(data->Buf, data->BufTextLen, + ui->ime_param->inputTextBuffer, + ui->ime_param->maxTextLength)) { + LOG_ERROR(Lib_ImeDialog, "Failed to convert Orbis char to UTF-8"); + return 0; + } + + OrbisImeEvent event{}; + event.id = OrbisImeEventId::UPDATE_TEXT; + event.param.text = eventParam; + + lastText = currentText; + ui->state->SendEvent(&event); } - OrbisImeEvent event{}; - event.id = OrbisImeEventId::UPDATE_TEXT; - event.param.text = eventParam; - - ui->state->SendEvent(&event); return 0; }