mirror of
https://github.com/ocornut/imgui.git
synced 2024-11-24 07:40:22 +01:00
Scrollbar: clicking above or below the grab scrolls by one page, holding mouse button repeats scrolling. (#7328, #150)
Remove absolute seeking entirely. Amend f02108085
.
This commit is contained in:
parent
479c5f62fc
commit
5cbc34a10c
@ -45,6 +45,8 @@ Other changes:
|
||||
|
||||
- Windows: fixed altering FramePadding mid-frame not correctly affecting logic
|
||||
responsible for honoring io.ConfigWindowsMoveFromTitleBarOnly. (#7576, #899)
|
||||
- Scrollbar: made scrolling logic more standard: clicking above or below the
|
||||
grab scrolls by one page, holding mouse button repeats scrolling. (#7328, #150)
|
||||
|
||||
|
||||
-----------------------------------------------------------------------
|
||||
|
@ -472,7 +472,7 @@ template<typename T> static inline T ImSubClampOverflow(T a, T b, T mn, T mx)
|
||||
// - Misc maths helpers
|
||||
static inline ImVec2 ImMin(const ImVec2& lhs, const ImVec2& rhs) { return ImVec2(lhs.x < rhs.x ? lhs.x : rhs.x, lhs.y < rhs.y ? lhs.y : rhs.y); }
|
||||
static inline ImVec2 ImMax(const ImVec2& lhs, const ImVec2& rhs) { return ImVec2(lhs.x >= rhs.x ? lhs.x : rhs.x, lhs.y >= rhs.y ? lhs.y : rhs.y); }
|
||||
static inline ImVec2 ImClamp(const ImVec2& v, const ImVec2& mn, ImVec2 mx) { return ImVec2((v.x < mn.x) ? mn.x : (v.x > mx.x) ? mx.x : v.x, (v.y < mn.y) ? mn.y : (v.y > mx.y) ? mx.y : v.y); }
|
||||
static inline ImVec2 ImClamp(const ImVec2& v, const ImVec2&mn, const ImVec2&mx) { return ImVec2((v.x < mn.x) ? mn.x : (v.x > mx.x) ? mx.x : v.x, (v.y < mn.y) ? mn.y : (v.y > mx.y) ? mx.y : v.y); }
|
||||
static inline ImVec2 ImLerp(const ImVec2& a, const ImVec2& b, float t) { return ImVec2(a.x + (b.x - a.x) * t, a.y + (b.y - a.y) * t); }
|
||||
static inline ImVec2 ImLerp(const ImVec2& a, const ImVec2& b, const ImVec2& t) { return ImVec2(a.x + (b.x - a.x) * t.x, a.y + (b.y - a.y) * t.y); }
|
||||
static inline ImVec4 ImLerp(const ImVec4& a, const ImVec4& b, float t) { return ImVec4(a.x + (b.x - a.x) * t, a.y + (b.y - a.y) * t, a.z + (b.z - a.z) * t, a.w + (b.w - a.w) * t); }
|
||||
@ -2162,13 +2162,14 @@ struct ImGuiContext
|
||||
ImGuiComboPreviewData ComboPreviewData;
|
||||
ImRect WindowResizeBorderExpectedRect; // Expected border rect, switch to relative edit if moving
|
||||
bool WindowResizeRelativeMode;
|
||||
short ScrollbarSeekMode; // 0: relative, -1/+1: prev/next page.
|
||||
float ScrollbarClickDeltaToGrabCenter; // Distance between mouse and center of grab box, normalized in parent space. Use storage?
|
||||
float SliderGrabClickOffset;
|
||||
float SliderCurrentAccum; // Accumulated slider delta when using navigation controls.
|
||||
bool SliderCurrentAccumDirty; // Has the accumulated slider delta changed since last time we tried to apply it?
|
||||
bool DragCurrentAccumDirty;
|
||||
float DragCurrentAccum; // Accumulator for dragging modification. Always high-precision, not rounded by end-user precision settings
|
||||
float DragSpeedDefaultRatio; // If speed == 0.0f, uses (max-min) * DragSpeedDefaultRatio
|
||||
float ScrollbarClickDeltaToGrabCenter; // Distance between mouse and center of grab box, normalized in parent space. Use storage?
|
||||
float DisabledAlphaBackup; // Backup for style.Alpha for BeginDisabled()
|
||||
short DisabledStackSize;
|
||||
short LockMarkEdited;
|
||||
@ -2376,13 +2377,14 @@ struct ImGuiContext
|
||||
ColorEditSavedHue = ColorEditSavedSat = 0.0f;
|
||||
ColorEditSavedColor = 0;
|
||||
WindowResizeRelativeMode = false;
|
||||
ScrollbarSeekMode = 0;
|
||||
ScrollbarClickDeltaToGrabCenter = 0.0f;
|
||||
SliderGrabClickOffset = 0.0f;
|
||||
SliderCurrentAccum = 0.0f;
|
||||
SliderCurrentAccumDirty = false;
|
||||
DragCurrentAccumDirty = false;
|
||||
DragCurrentAccum = 0.0f;
|
||||
DragSpeedDefaultRatio = 1.0f / 100.0f;
|
||||
ScrollbarClickDeltaToGrabCenter = 0.0f;
|
||||
DisabledAlphaBackup = 0.0f;
|
||||
DisabledStackSize = 0;
|
||||
LockMarkEdited = 0;
|
||||
|
@ -916,10 +916,10 @@ void ImGui::Scrollbar(ImGuiAxis axis)
|
||||
if (!window->ScrollbarX)
|
||||
rounding_corners |= ImDrawFlags_RoundCornersBottomRight;
|
||||
}
|
||||
float size_avail = window->InnerRect.Max[axis] - window->InnerRect.Min[axis];
|
||||
float size_visible = window->InnerRect.Max[axis] - window->InnerRect.Min[axis];
|
||||
float size_contents = window->ContentSize[axis] + window->WindowPadding[axis] * 2.0f;
|
||||
ImS64 scroll = (ImS64)window->Scroll[axis];
|
||||
ScrollbarEx(bb, id, axis, &scroll, (ImS64)size_avail, (ImS64)size_contents, rounding_corners);
|
||||
ScrollbarEx(bb, id, axis, &scroll, (ImS64)size_visible, (ImS64)size_contents, rounding_corners);
|
||||
window->Scroll[axis] = (float)scroll;
|
||||
}
|
||||
|
||||
@ -929,7 +929,7 @@ void ImGui::Scrollbar(ImGuiAxis axis)
|
||||
// - We store values as normalized ratio and in a form that allows the window content to change while we are holding on a scrollbar
|
||||
// - We handle both horizontal and vertical scrollbars, which makes the terminology not ideal.
|
||||
// Still, the code should probably be made simpler..
|
||||
bool ImGui::ScrollbarEx(const ImRect& bb_frame, ImGuiID id, ImGuiAxis axis, ImS64* p_scroll_v, ImS64 size_avail_v, ImS64 size_contents_v, ImDrawFlags flags)
|
||||
bool ImGui::ScrollbarEx(const ImRect& bb_frame, ImGuiID id, ImGuiAxis axis, ImS64* p_scroll_v, ImS64 size_visible_v, ImS64 size_contents_v, ImDrawFlags flags)
|
||||
{
|
||||
ImGuiContext& g = *GImGui;
|
||||
ImGuiWindow* window = g.CurrentWindow;
|
||||
@ -959,9 +959,9 @@ bool ImGui::ScrollbarEx(const ImRect& bb_frame, ImGuiID id, ImGuiAxis axis, ImS6
|
||||
|
||||
// Calculate the height of our grabbable box. It generally represent the amount visible (vs the total scrollable amount)
|
||||
// But we maintain a minimum size in pixel to allow for the user to still aim inside.
|
||||
IM_ASSERT(ImMax(size_contents_v, size_avail_v) > 0.0f); // Adding this assert to check if the ImMax(XXX,1.0f) is still needed. PLEASE CONTACT ME if this triggers.
|
||||
const ImS64 win_size_v = ImMax(ImMax(size_contents_v, size_avail_v), (ImS64)1);
|
||||
const float grab_h_pixels = ImClamp(scrollbar_size_v * ((float)size_avail_v / (float)win_size_v), style.GrabMinSize, scrollbar_size_v);
|
||||
IM_ASSERT(ImMax(size_contents_v, size_visible_v) > 0.0f); // Adding this assert to check if the ImMax(XXX,1.0f) is still needed. PLEASE CONTACT ME if this triggers.
|
||||
const ImS64 win_size_v = ImMax(ImMax(size_contents_v, size_visible_v), (ImS64)1);
|
||||
const float grab_h_pixels = ImClamp(scrollbar_size_v * ((float)size_visible_v / (float)win_size_v), style.GrabMinSize, scrollbar_size_v);
|
||||
const float grab_h_norm = grab_h_pixels / scrollbar_size_v;
|
||||
|
||||
// Handle input right away. None of the code of Begin() is relying on scrolling position before calling Scrollbar().
|
||||
@ -970,7 +970,7 @@ bool ImGui::ScrollbarEx(const ImRect& bb_frame, ImGuiID id, ImGuiAxis axis, ImS6
|
||||
ItemAdd(bb_frame, id, NULL, ImGuiItemFlags_NoNav);
|
||||
ButtonBehavior(bb, id, &hovered, &held, ImGuiButtonFlags_NoNavFocus);
|
||||
|
||||
const ImS64 scroll_max = ImMax((ImS64)1, size_contents_v - size_avail_v);
|
||||
const ImS64 scroll_max = ImMax((ImS64)1, size_contents_v - size_visible_v);
|
||||
float scroll_ratio = ImSaturate((float)*p_scroll_v / (float)scroll_max);
|
||||
float grab_v_norm = scroll_ratio * (scrollbar_size_v - grab_h_pixels) / scrollbar_size_v; // Grab position in normalized space
|
||||
if (held && allow_interaction && grab_h_norm < 1.0f)
|
||||
@ -981,29 +981,39 @@ bool ImGui::ScrollbarEx(const ImRect& bb_frame, ImGuiID id, ImGuiAxis axis, ImS6
|
||||
// Click position in scrollbar normalized space (0.0f->1.0f)
|
||||
const float clicked_v_norm = ImSaturate((mouse_pos_v - scrollbar_pos_v) / scrollbar_size_v);
|
||||
|
||||
bool seek_absolute = false;
|
||||
const int held_dir = (clicked_v_norm < grab_v_norm) ? -1 : (clicked_v_norm > grab_v_norm + grab_h_norm) ? +1 : 0;
|
||||
if (g.ActiveIdIsJustActivated)
|
||||
{
|
||||
// On initial click calculate the distance between mouse and the center of the grab
|
||||
seek_absolute = (clicked_v_norm < grab_v_norm || clicked_v_norm > grab_v_norm + grab_h_norm);
|
||||
if (seek_absolute)
|
||||
g.ScrollbarClickDeltaToGrabCenter = 0.0f;
|
||||
else
|
||||
g.ScrollbarClickDeltaToGrabCenter = clicked_v_norm - grab_v_norm - grab_h_norm * 0.5f;
|
||||
g.ScrollbarSeekMode = (short)held_dir;
|
||||
g.ScrollbarClickDeltaToGrabCenter = (g.ScrollbarSeekMode == 0.0f) ? clicked_v_norm - grab_v_norm - grab_h_norm * 0.5f : 0.0f;
|
||||
}
|
||||
|
||||
// Apply scroll (p_scroll_v will generally point on one member of window->Scroll)
|
||||
// It is ok to modify Scroll here because we are being called in Begin() after the calculation of ContentSize and before setting up our starting position
|
||||
const float scroll_v_norm = ImSaturate((clicked_v_norm - g.ScrollbarClickDeltaToGrabCenter - grab_h_norm * 0.5f) / (1.0f - grab_h_norm));
|
||||
*p_scroll_v = (ImS64)(scroll_v_norm * scroll_max);
|
||||
if (g.ScrollbarSeekMode == 0)
|
||||
{
|
||||
// Absolute seeking
|
||||
const float scroll_v_norm = ImSaturate((clicked_v_norm - g.ScrollbarClickDeltaToGrabCenter - grab_h_norm * 0.5f) / (1.0f - grab_h_norm));
|
||||
*p_scroll_v = (ImS64)(scroll_v_norm * scroll_max);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Page by page
|
||||
if (IsMouseClicked(ImGuiMouseButton_Left, ImGuiInputFlags_Repeat) && held_dir == g.ScrollbarSeekMode)
|
||||
{
|
||||
float page_dir = (g.ScrollbarSeekMode > 0.0f) ? +1.0f : -1.0f;
|
||||
*p_scroll_v = ImClamp(*p_scroll_v + (ImS64)(page_dir * size_visible_v), (ImS64)0, scroll_max);
|
||||
}
|
||||
}
|
||||
|
||||
// Update values for rendering
|
||||
scroll_ratio = ImSaturate((float)*p_scroll_v / (float)scroll_max);
|
||||
grab_v_norm = scroll_ratio * (scrollbar_size_v - grab_h_pixels) / scrollbar_size_v;
|
||||
|
||||
// Update distance to grab now that we have seek'ed and saturated
|
||||
if (seek_absolute)
|
||||
g.ScrollbarClickDeltaToGrabCenter = clicked_v_norm - grab_v_norm - grab_h_norm * 0.5f;
|
||||
//if (seek_absolute)
|
||||
// g.ScrollbarClickDeltaToGrabCenter = clicked_v_norm - grab_v_norm - grab_h_norm * 0.5f;
|
||||
}
|
||||
|
||||
// Render
|
||||
|
Loading…
Reference in New Issue
Block a user