diff --git a/backends/imgui_impl_sdl2.cpp b/backends/imgui_impl_sdl2.cpp index 7abeb0e89..033e39ca5 100644 --- a/backends/imgui_impl_sdl2.cpp +++ b/backends/imgui_impl_sdl2.cpp @@ -354,6 +354,7 @@ bool ImGui_ImplSDL2_ProcessEvent(const SDL_Event* event) case SDL_TEXTINPUT: { io.AddInputCharactersUTF8(event->text.text); + io.ClearPreEditText(); return true; } case SDL_KEYDOWN: @@ -379,13 +380,37 @@ bool ImGui_ImplSDL2_ProcessEvent(const SDL_Event* event) bd->MouseLastLeaveFrame = 0; } if (window_event == SDL_WINDOWEVENT_LEAVE) + { bd->MouseLastLeaveFrame = ImGui::GetFrameCount() + 1; + ImGui::GetIO().ClearPreEditText(); + } if (window_event == SDL_WINDOWEVENT_FOCUS_GAINED) io.AddFocusEvent(true); else if (event->window.event == SDL_WINDOWEVENT_FOCUS_LOST) + { io.AddFocusEvent(false); + ImGui::GetIO().ClearPreEditText(); + } return true; } + case SDL_TEXTEDITING: + { + if(strlen(event->edit.text) > 0) + ImGui::GetIO().SetPreEditText(event->edit.text); + else + io.ClearPreEditText(); + break; + } +#if defined(SDL_HINT_IME_SUPPORT_EXTENDED_TEXT) + case SDL_TEXTEDITING_EXT: + { + if( event->editExt.text != nullptr && strlen(event->editExt.text) > 0) + ImGui::GetIO().SetPreEditText( event->editExt.text ); + else + ImGui::GetIO().ClearPreEditText(); + break; + } +#endif case SDL_CONTROLLERDEVICEADDED: case SDL_CONTROLLERDEVICEREMOVED: { diff --git a/imgui.cpp b/imgui.cpp index 0b0c583c7..693fb2df8 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -1337,6 +1337,17 @@ ImGuiIO::ImGuiIO() AppAcceptingEvents = true; BackendUsingLegacyKeyArrays = (ImS8)-1; BackendUsingLegacyNavInputArray = true; // assume using legacy array until proven wrong + PreEditText[0] = NULL; +} + +void ImGuiIO::SetPreEditText(const char *str) +{ + strcpy(PreEditText, str); +} + +void ImGuiIO::ClearPreEditText() +{ + PreEditText[0] = NULL; } // Pass in translated ASCII characters for text input. diff --git a/imgui.h b/imgui.h index 782bf891f..85c4e3332 100644 --- a/imgui.h +++ b/imgui.h @@ -2168,6 +2168,8 @@ struct ImGuiIO IMGUI_API void AddInputCharacter(unsigned int c); // Queue a new character input IMGUI_API void AddInputCharacterUTF16(ImWchar16 c); // Queue a new character input from a UTF-16 character, it can be a surrogate IMGUI_API void AddInputCharactersUTF8(const char* str); // Queue a new characters input from a UTF-8 string + IMGUI_API void SetPreEditText(const char *str); + IMGUI_API void ClearPreEditText(); IMGUI_API void SetKeyEventNativeData(ImGuiKey key, int native_keycode, int native_scancode, int native_legacy_index = -1); // [Optional] Specify index for legacy <1.87 IsKeyXXX() functions with native indices + specify native keycode, scancode. IMGUI_API void SetAppAcceptingEvents(bool accepting_events); // Set master flag for accepting key/mouse/text events (default to true). Useful if you have native dialog boxes that are interrupting your application loop/refresh, and you want to disable events being queued while your app is frozen. @@ -2251,6 +2253,7 @@ struct ImGuiIO bool BackendUsingLegacyNavInputArray; // 0: using AddKeyAnalogEvent(), 1: writing to legacy io.NavInputs[] directly ImWchar16 InputQueueSurrogate; // For AddInputCharacterUTF16() ImVector InputQueueCharacters; // Queue of _characters_ input (obtained by platform backend). Fill using AddInputCharacter() helper. + char PreEditText[255]; IMGUI_API ImGuiIO(); }; diff --git a/imgui_widgets.cpp b/imgui_widgets.cpp index f1ffbf0f5..6194e21df 100644 --- a/imgui_widgets.cpp +++ b/imgui_widgets.cpp @@ -4973,7 +4973,30 @@ bool ImGui::InputTextEx(const char* label, const char* hint, char* buf, int buf_ if (is_multiline || (buf_display_end - buf_display) < buf_display_max_length) { ImU32 col = GetColorU32(is_displaying_hint ? ImGuiCol_TextDisabled : ImGuiCol_Text); - draw_window->DrawList->AddText(g.Font, g.FontSize, draw_pos - draw_scroll, col, buf_display, buf_display_end, 0.0f, is_multiline ? NULL : &clip_rect); + if(GImGui->IO.PreEditText && !is_multiline) + { + const char *preEditTextEnd = GImGui->IO.PreEditText + strlen(GImGui->IO.PreEditText); + ImWchar wcharBuf[255] = { 0 }; + int wlen = ImTextStrFromUtf8(wcharBuf, 255, GImGui->IO.PreEditText, preEditTextEnd); + char tmpBuf[255] = "\0"; + + ImVec2 drawPosStart = draw_pos - draw_scroll; + size_t tmpBufLen = ImTextStrToUtf8( tmpBuf, 255, text_begin, text_begin + state->Stb.cursor ); + draw_window->DrawList->AddText(g.Font, g.FontSize, drawPosStart, col, tmpBuf, tmpBuf + tmpBufLen, 0.0f, &clip_rect); + drawPosStart.x += InputTextCalcTextSizeW(GImGui, text_begin, text_begin + state->Stb.cursor).x; + ImU32 bg_color = GetColorU32( ImGuiCol_TextSelectedBg, 1.f ); + ImVec2 highlightRectMax = drawPosStart; + highlightRectMax += InputTextCalcTextSizeW(GImGui, wcharBuf, wcharBuf + wlen); + draw_window->DrawList->AddRectFilled( drawPosStart, highlightRectMax, bg_color ); + draw_window->DrawList->AddText(g.Font, g.FontSize, drawPosStart, col, GImGui->IO.PreEditText, preEditTextEnd, 0.0f, &clip_rect); + if( buf_display_end != NULL && buf_display + tmpBufLen < buf_display_end ) + { + drawPosStart.x = highlightRectMax.x; + draw_window->DrawList->AddText(g.Font, g.FontSize, drawPosStart, col, buf_display + tmpBufLen, buf_display_end, 0.0f, &clip_rect); + } + } + else + draw_window->DrawList->AddText(g.Font, g.FontSize, draw_pos - draw_scroll, col, buf_display, buf_display_end, 0.0f, is_multiline ? NULL : &clip_rect); } // Draw blinking cursor