diff --git a/imgui.cpp b/imgui.cpp index f452f0e8b..3e5d1700b 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -547,6 +547,7 @@ static bool CloseWindowButton(bool* p_opened = NULL); static void FocusWindow(ImGuiWindow* window); static ImGuiWindow* FindHoveredWindow(ImVec2 pos, bool excluding_childs); static void CloseInactivePopups(); +static void SetWindowScrollY(ImGuiWindow* window, float scroll_y); // Helpers: String static int ImStricmp(const char* str1, const char* str2); @@ -2195,7 +2196,7 @@ void ImGui::NewFrame() if (!(window->Flags & ImGuiWindowFlags_NoScrollWithMouse)) { const int scroll_lines = (window->Flags & ImGuiWindowFlags_ComboBox) ? 3 : 5; - window->ScrollY -= g.IO.MouseWheel * window->CalcFontSize() * scroll_lines; + SetWindowScrollY(window, window->ScrollY - g.IO.MouseWheel * window->CalcFontSize() * scroll_lines); } } } @@ -4028,6 +4029,7 @@ static void Scrollbar(ImGuiWindow* window) } // Apply scroll + // It is ok to modify ScrollY here because we are being called in Begin() after the calculation of SizeContents and before setting up our starting position const float scroll_y_norm = ImSaturate((clicked_y_norm - g.ScrollbarClickDeltaToGrabCenter - grab_h_norm*0.5f) / (1.0f - grab_h_norm)); window->ScrollY = (float)(int)(0.5f + scroll_y_norm * (window->SizeContents.y - window->Size.y)); @@ -4374,6 +4376,13 @@ ImVec2 ImGui::GetWindowPos() return window->Pos; } +static void SetWindowScrollY(ImGuiWindow* window, float new_scroll_y) +{ + window->DC.CursorMaxPos.y += window->ScrollY; + window->ScrollY = new_scroll_y; + window->DC.CursorMaxPos.y -= window->ScrollY; +} + static void SetWindowPos(ImGuiWindow* window, const ImVec2& pos, ImGuiSetCond cond) { // Test condition (NB: bit 0 is always true) and clear flags for next time @@ -6933,8 +6942,8 @@ static bool InputTextEx(const char* label, char* buf, size_t buf_size, const ImV const bool is_ctrl_only = is_ctrl_down && !is_alt_down && !is_shift_down; if (IsKeyPressedMap(ImGuiKey_LeftArrow)) { edit_state.OnKeyPressed(is_ctrl_down ? STB_TEXTEDIT_K_WORDLEFT | k_mask : STB_TEXTEDIT_K_LEFT | k_mask); } else if (IsKeyPressedMap(ImGuiKey_RightArrow)) { edit_state.OnKeyPressed(is_ctrl_down ? STB_TEXTEDIT_K_WORDRIGHT | k_mask : STB_TEXTEDIT_K_RIGHT | k_mask); } - else if (is_multiline && IsKeyPressedMap(ImGuiKey_UpArrow)) { if (is_ctrl_down) draw_window->ScrollY -= g.FontSize; else edit_state.OnKeyPressed(STB_TEXTEDIT_K_UP | k_mask); } - else if (is_multiline && IsKeyPressedMap(ImGuiKey_DownArrow)) { if (is_ctrl_down) draw_window->ScrollY += g.FontSize; else edit_state.OnKeyPressed(STB_TEXTEDIT_K_DOWN| k_mask); } + else if (is_multiline && IsKeyPressedMap(ImGuiKey_UpArrow)) { if (is_ctrl_down) SetWindowScrollY(draw_window, draw_window->ScrollY - g.FontSize); else edit_state.OnKeyPressed(STB_TEXTEDIT_K_UP | k_mask); } + else if (is_multiline && IsKeyPressedMap(ImGuiKey_DownArrow)) { if (is_ctrl_down) SetWindowScrollY(draw_window, draw_window->ScrollY + g.FontSize); else edit_state.OnKeyPressed(STB_TEXTEDIT_K_DOWN| k_mask); } else if (IsKeyPressedMap(ImGuiKey_Home)) { edit_state.OnKeyPressed(is_ctrl_down ? STB_TEXTEDIT_K_TEXTSTART | k_mask : STB_TEXTEDIT_K_LINESTART | k_mask); } else if (IsKeyPressedMap(ImGuiKey_End)) { edit_state.OnKeyPressed(is_ctrl_down ? STB_TEXTEDIT_K_TEXTEND | k_mask : STB_TEXTEDIT_K_LINEEND | k_mask); } else if (IsKeyPressedMap(ImGuiKey_Delete)) { edit_state.OnKeyPressed(STB_TEXTEDIT_K_DELETE | k_mask); }