From 62698593154efee273374c3fbc2c30328355a120 Mon Sep 17 00:00:00 2001 From: ocornut Date: Sun, 29 Nov 2015 14:15:07 +0000 Subject: [PATCH] Replace OS IME (Input Method Editor) cursor on top-left when we are not text editing. --- imgui.cpp | 22 +++++++++++++--------- imgui_internal.h | 3 ++- 2 files changed, 15 insertions(+), 10 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index 0f84d8c8c..824387fef 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -1988,6 +1988,7 @@ void ImGui::NewFrame() g.IO.WantTextInput = (g.ActiveId != 0 && g.InputTextState.Id == g.ActiveId); g.MouseCursor = ImGuiMouseCursor_Arrow; g.CaptureMouseNextFrame = g.CaptureKeyboardNextFrame = false; + g.OsImePosRequest = ImVec2(1.0f, 1.0f); // OS Input Method Editor showing on top-left of our window by default // If mouse was first clicked outside of ImGui bounds we also cancel out hovering. if (mouse_owned_by_application) @@ -2336,6 +2337,13 @@ void ImGui::EndFrame() ImGui::EndTooltip(); } + // Notify OS when our Input Method Editor cursor has moved (e.g. CJK inputs using Microsoft IME) + if (g.IO.ImeSetInputScreenPosFn && ImLengthSqr(g.OsImePosRequest - g.OsImePosSet) > 0.0001f) + { + g.IO.ImeSetInputScreenPosFn((int)g.OsImePosRequest.x, (int)g.OsImePosRequest.y); + g.OsImePosSet = g.OsImePosRequest; + } + // Hide implicit "Debug" window if it hasn't been used IM_ASSERT(g.CurrentWindowStack.Size == 1); // Mismatched Begin/End if (g.CurrentWindow && !g.CurrentWindow->Accessed) @@ -2373,9 +2381,8 @@ void ImGui::EndFrame() for (int i = 0; i != g.Windows.Size; i++) { ImGuiWindow* window = g.Windows[i]; - if (window->Flags & ImGuiWindowFlags_ChildWindow) // if a child is active its parent will add it - if (window->Active) - continue; + if (window->Active && (window->Flags & ImGuiWindowFlags_ChildWindow)) // if a child is active its parent will add it + continue; AddWindowToSortedBuffer(g.WindowsSortBuffer, window); } IM_ASSERT(g.Windows.Size == g.WindowsSortBuffer.Size); // we done something wrong @@ -7209,7 +7216,6 @@ bool ImGui::InputTextEx(const char* label, char* buf, int buf_size, const ImVec2 const char* buf_end = NULL; edit_state.CurLenW = ImTextStrFromUtf8(edit_state.Text.Data, edit_state.Text.Size, buf, NULL, &buf_end); edit_state.CurLenA = (int)(buf_end - buf); // We can't get the result from ImFormatString() above because it is not UTF-8 aware. Here we'll cut off malformed UTF-8. - edit_state.InputCursorScreenPos = ImVec2(-1.f, -1.f); edit_state.CursorAnimReset(); // Preserve cursor position and undo/redo stack if we come back to same widget @@ -7628,11 +7634,9 @@ bool ImGui::InputTextEx(const char* label, char* buf, int buf_size, const ImVec2 if (cursor_is_visible) draw_window->DrawList->AddLine(cursor_screen_pos + ImVec2(0.0f,-g.FontSize+0.5f), cursor_screen_pos + ImVec2(0.0f,-1.5f), window->Color(ImGuiCol_Text)); - // Notify OS of text input position for advanced IME - if (is_editable && io.ImeSetInputScreenPosFn && ImLengthSqr(edit_state.InputCursorScreenPos - cursor_screen_pos) > 0.0001f) - io.ImeSetInputScreenPosFn((int)cursor_screen_pos.x - 1, (int)(cursor_screen_pos.y - g.FontSize)); // -1 x offset so that Windows IME can cover our cursor. Bit of an extra nicety. - - edit_state.InputCursorScreenPos = cursor_screen_pos; + // Notify OS of text input position for advanced IME (-1 x offset so that Windows IME can cover our cursor. Bit of an extra nicety.) + if (is_editable) + g.OsImePosRequest = ImVec2(cursor_screen_pos.x - 1, cursor_screen_pos.y - g.FontSize); } else { diff --git a/imgui_internal.h b/imgui_internal.h index 84b7653eb..22acb8109 100644 --- a/imgui_internal.h +++ b/imgui_internal.h @@ -294,7 +294,6 @@ struct IMGUI_API ImGuiTextEditState ImGuiStb::STB_TexteditState StbState; float CursorAnim; bool CursorFollow; - ImVec2 InputCursorScreenPos; // Cursor position in screen space to be used by IME callback. bool SelectedAllMouseLock; ImGuiTextEditState() { memset(this, 0, sizeof(*this)); } @@ -414,6 +413,7 @@ struct ImGuiState ImVec2 ScrollbarClickDeltaToGrabCenter; // Distance between mouse and center of grab box, normalized in parent space. Use storage? char Tooltip[1024]; char* PrivateClipboard; // If no custom clipboard handler is defined + ImVec2 OsImePosRequest, OsImePosSet; // Cursor position request & last passed to the OS Input Method Editor // Logging bool LogEnabled; @@ -477,6 +477,7 @@ struct ImGuiState ScrollbarClickDeltaToGrabCenter = ImVec2(0.0f, 0.0f); memset(Tooltip, 0, sizeof(Tooltip)); PrivateClipboard = NULL; + OsImePosRequest = OsImePosSet = ImVec2(-1.0f, -1.0f); ModalWindowDarkeningRatio = 0.0f; OverlayDrawList._OwnerName = "##Overlay"; // Give it a name for debugging