core/ime: Implement caret events
Some checks are pending
Build and Release / reuse (push) Waiting to run
Build and Release / clang-format (push) Waiting to run
Build and Release / get-info (push) Waiting to run
Build and Release / windows-sdl (push) Blocked by required conditions
Build and Release / windows-qt (push) Blocked by required conditions
Build and Release / macos-sdl (push) Blocked by required conditions
Build and Release / macos-qt (push) Blocked by required conditions
Build and Release / linux-sdl (push) Blocked by required conditions
Build and Release / linux-qt (push) Blocked by required conditions
Build and Release / pre-release (push) Blocked by required conditions

This commit is contained in:
Daniel R. 2024-10-19 20:14:25 +02:00
parent 9f354ba29b
commit 902b996090
No known key found for this signature in database
GPG key ID: B8ADC8F57BA18DBA
2 changed files with 62 additions and 22 deletions

View file

@ -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;

View file

@ -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<ImeUi*>(data->UserData);
ASSERT(ui);
OrbisImeEditText eventParam{};
eventParam.str = reinterpret_cast<char16_t*>(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<char16_t*>(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;
}