Skip to content

Widgets: Added SliderFloatRange2(), SliderIntRange2() for range selection (#76)#9164

Open
Entrpi wants to merge 3 commits intoocornut:masterfrom
Entrpi:feature/slider-range2
Open

Widgets: Added SliderFloatRange2(), SliderIntRange2() for range selection (#76)#9164
Entrpi wants to merge 3 commits intoocornut:masterfrom
Entrpi:feature/slider-range2

Conversation

@Entrpi
Copy link

@Entrpi Entrpi commented Jan 12, 2026

Summary

This PR implements range sliders as discussed in #76.

Features:

  • Two-handle slider for selecting a min/max range
  • Middle bar dragging to move both handles together while maintaining range size
  • Hover highlighting to show which handle will be selected on click
  • Ctrl+Click text input with "XXX...YYYY" parsing to set both values at once
  • Per-handle format strings for different precision on each handle
  • Optional step parameter for snapping values

API

bool SliderFloatRange2(const char* label, float* v_current_min, float* v_current_max, 
                       float v_min = 0.0f, float v_max = 1.0f, 
                       const char* format = "%.3f", const char* format_max = NULL, 
                       ImGuiSliderFlags flags = 0, float step = 0.0f);

bool SliderIntRange2(const char* label, int* v_current_min, int* v_current_max, 
                     int v_min = 0, int v_max = 100, 
                     const char* format = "%d", const char* format_max = NULL, 
                     ImGuiSliderFlags flags = 0, int step = 0);

Changes

  • imgui.h: Function declarations
  • imgui_internal.h: Added SliderRangeActiveHandle context field
  • imgui_widgets.cpp: Full implementation
  • imgui_demo.cpp: Demo in Widgets/Basic section

Test Plan

  • Min handle can be dragged independently
  • Max handle can be dragged independently
  • Bar between handles drags both together
  • Handles cannot cross (min always <= max)
  • Hover highlights correct handle
  • Multiple SliderRange2 widgets don't interfere
  • Ctrl+Click text input works per-handle
  • "X...Y" format sets both values

@Entrpi
Copy link
Author

Entrpi commented Jan 12, 2026

slider-range-demo

…tion. (ocornut#76)

- Two-handle slider for selecting a min/max range
- Middle bar dragging to move both handles together while maintaining range
- Hover highlighting to show which handle will be selected on click
- Ctrl+Click text input with "XXX...YYYY" parsing to set both values
- Per-handle format strings for different precision on each handle
- Optional step parameter for snapping
@Entrpi Entrpi force-pushed the feature/slider-range2 branch from d2ddb97 to 5743047 Compare January 12, 2026 12:34
@ocornut
Copy link
Owner

ocornut commented Jan 12, 2026

Thanks, wonderful. Further feedback:

  • When both handles are at the same location, it feels like the initial click should set an special "unknown" state that's automatically update to left or right handle based on the sign of the accumulator?
  • Ideally you can add to imgui_test_suite but I'll add some tests if you can't, it's rather easy for this sorts of things.
  • Use single format string? aka "%.3f...%.3f", may require extra parsing work but there are helpers... this makes things more flexible but it's a little more work to customize.
  • Displaying the range size.. could use the format string for this purpose? "%.3f...%.3f (%.3f)"... omitting last part would simply hide the value.
  • CTRL+Click could default to print "...". Enter should definitively.
  • Using .. instead of ... may be faster to type, but when parsing we should decide to accept any number of points.
  • Default display format could match the "..." ?

What's your opinion on those?

  • Moonshot: if min and max values are contiguous, and we adopt the format string ideas above, we could technically use SliderFloat2() with a ImGuiSliderFlags_Range value valid for 2D and minimize new API. Not sure if it is a good idea but it's technically quite at reach.

@ocornut
Copy link
Owner

ocornut commented Jan 12, 2026

I was having a bad day so the swift and unusually quality updates in this PR are very comforting! Thank you!

@Entrpi Entrpi force-pushed the feature/slider-range2 branch from d08ba62 to f998eae Compare January 12, 2026 13:36
- Single format string API: removed format_max parameter, format can be
  "%.3f" (same for both) or "%.3f...%.3f" (different for min/max)
- Accept any number of dots (.., ..., ....) as separator when parsing
- Accept " - " as separator in addition to dots
- Ctrl+Click shows "min...max" format for editing both values
- Unknown state (-2) when handles overlap: drag direction determines
  which handle to use
- Display uses " - " separator by default (customizable via format)
@Entrpi Entrpi force-pushed the feature/slider-range2 branch from f998eae to 94d0184 Compare January 12, 2026 14:01
Entrpi added a commit to Entrpi/imgui_test_engine that referenced this pull request Jan 12, 2026
Tests for the new SliderRange2 widgets (ocornut/imgui#9164):
- Overlapping handles resolution by drag direction
- Ctrl+Click text input with "..." separator
- Ctrl+Click text input with " - " separator
- Handles can't cross constraint
- Integer range slider text input
@Entrpi
Copy link
Author

Entrpi commented Jan 12, 2026

That means a lot to hear, glad I could brighten your day a bit! Hope things turn around for you.

Addressed the feedback:

API changes:

  • Single format string API - removed format_max parameter
  • Format string accepts any number of dots as separator (.., ..., ....)
  • Format like "%.2f...%.2f (%.2f)" displays range size

Behavior:

  • Default display uses " - " separator
  • Ctrl+Click text input shows "min...max" format by default
  • Accepts both "..." and " - " as input separators
  • When handles overlap, drag direction determines which handle moves (undetermined state until drag threshold reached)

Tests: ocornut/imgui_test_engine#88

All 5 tests pass:

  • widgets_slider_range2_overlap_resolve
  • widgets_slider_range2_text_input
  • widgets_slider_range2_text_input_dash
  • widgets_slider_range2_no_cross
  • widgets_slider_range2_int

Let me know if you'd like any adjustments!

Alternative API: SliderFloat2(label, v, min, max, fmt, ImGuiSliderFlags_Range)
renders as a range slider instead of two separate sliders.

This minimizes API surface by reusing existing SliderScalarN functions.
Entrpi added a commit to Entrpi/imgui_test_engine that referenced this pull request Jan 12, 2026
Tests for the new SliderRange2 widgets (ocornut/imgui#9164):
- Overlapping handles resolution by drag direction
- Ctrl+Click text input with "..." separator
- Ctrl+Click text input with " - " separator
- Handles can't cross constraint
- Integer range slider text input
@Entrpi
Copy link
Author

Entrpi commented Jan 12, 2026

Also implemented the moonshot: added ImGuiSliderFlags_Range flag.

Now you can do either:

// Dedicated function
SliderFloatRange2("range", &min, &max, 0.0f, 1.0f);

// Or use SliderFloat2 with flag
float v[2] = { min, max };
SliderFloat2("range", v, 0.0f, 1.0f, "%.3f", ImGuiSliderFlags_Range);

Both approaches work identically. The flag version routes through SliderScalarN when components == 2.

@ocornut
Copy link
Owner

ocornut commented Jan 12, 2026

Thanks, please give me some time to digest all that and get through all details.
There's quite too much code right now (+670 lines) so I will aim to simplify some of it.
The "moonshot" is mostly an API decision to make.

@ocornut
Copy link
Owner

ocornut commented Jan 12, 2026

I'll try work on this on wednesday, please avoid further force-pushing to the branch. 🙏

@Entrpi
Copy link
Author

Entrpi commented Jan 13, 2026

Sounds good, look forward to seeing where you take it!

Yes, I agree re: the API choice. Personally I prefer the "feel" of breaking it out into new functions, but not a strong preference.

I wasn't entirely sure about your intended approach with multi-format strings and just thought through the first thing that made some sense to me. I like your idea, so happy if that's the approach!

I do need the step feature, but it doesn't need to be done as I have.

@ocornut ocornut mentioned this pull request Jan 19, 2026
@ocornut ocornut added this to the v1.93 milestone Jan 19, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants