Skip to content

Add vertical slider support to bevy_ui_widgets slider#21827

Merged
alice-i-cecile merged 8 commits intobevyengine:mainfrom
DuckyBlender:main
Dec 9, 2025
Merged

Add vertical slider support to bevy_ui_widgets slider#21827
alice-i-cecile merged 8 commits intobevyengine:mainfrom
DuckyBlender:main

Conversation

@DuckyBlender
Copy link
Contributor

Objective

  • Fixes the issue of vertical sliders not being functional. Previously, when creating a vertical slider, the slider drag behavior was still horizontal, meaning dragging left/right would change the value instead of dragging up/down. Additionally, clicking on the slider track was offset and didn't correctly map to the clicked position.

Solution

The slider widget now automatically detects its orientation based on the node's dimensions (height > width for vertical, otherwise horizontal) and adjusts its interaction behavior accordingly:

  1. Orientation Detection: Added automatic detection of slider orientation by comparing node.size().y to node.size().x in both slider_on_pointer_down and slider_on_drag functions.

  2. Drag Direction Fix:

    • For vertical sliders, the drag calculation now uses the Y-axis (distance.y) instead of X-axis
    • The Y coordinate is properly inverted (since screen Y increases downward) to match expected behavior (dragging up increases value)
    • Thumb size calculation uses thumb.size().y for vertical sliders instead of always using thumb.size().x
  3. Click Position Fix:

    • Fixed coordinate conversion from Bevy's center-origin coordinate system to top/left-origin coordinates
    • For vertical sliders: converts local_pos.y from [-height/2, +height/2] to [0, height] before calculating the slider value
    • Accounts for thumb size offset to center the calculation properly
    • Inverts the Y coordinate for vertical sliders since Y increases downward
  4. Track Size Calculation: Uses node.size().y - thumb_size for vertical sliders and node.size().x - thumb_size for horizontal sliders when calculating the available track space.

The changes are backward compatible - horizontal sliders continue to work exactly as before, and the orientation detection is transparent to users of the API.

Testing

  • Manual Testing: Created test application with both vertical and horizontal sliders to verify:

    • Vertical sliders respond correctly to vertical drag movements (up = increase, down = decrease)
    • Horizontal sliders continue to work correctly with horizontal drag movements
    • Clicking anywhere on the slider track correctly snaps to that position for both orientations
    • Thumb positioning updates correctly during drag operations
    • Multiple sliders can coexist without interfering with each other
  • Edge Cases Tested:

    • Clicking at the very top/bottom of vertical sliders
    • Clicking at the very left/right of horizontal sliders
    • Dragging from one extreme to the other
    • Rapid clicking and dragging interactions

Areas that may need more testing:

  • Sliders with non-standard aspect ratios (very wide vertical sliders or very tall horizontal sliders)
  • Sliders with custom transforms/rotations applied
  • Sliders in nested UI hierarchies with complex transforms

How reviewers can test:

  1. Create a vertical slider (height > width) and verify:
    • Dragging up increases the value
    • Dragging down decreases the value
    • Clicking anywhere on the track snaps to that exact position
  2. Create a horizontal slider (width > height) and verify it still works as before
  3. Test with multiple sliders of both orientations simultaneously

Platforms tested:

  • macOS (Apple Silicon)

Showcase

Before

  • Vertical sliders were unusable - dragging would move horizontally instead of vertically
  • Clicking on vertical slider tracks was offset, with clicks near the bottom snapping to the middle instead
before.mov

After

  • Vertical sliders work correctly with intuitive up/down drag behavior
  • Clicking anywhere on the slider track accurately snaps to the clicked position
  • Both vertical and horizontal sliders work seamlessly together
after.mov

Code Example

// Vertical slider - now works correctly!
commands.spawn((
    Node {
        width: Val::Px(12.0),
        height: Val::Px(300.0),  // height > width = vertical
        ..default()
    },
    Slider::default(),
    SliderValue(50.0),
    SliderRange::new(0.0, 100.0),
    // ... thumb and track children
));

// Horizontal slider - continues to work as before
commands.spawn((
    Node {
        width: Val::Px(300.0),
        height: Val::Px(12.0),  // width > height = horizontal
        ..default()
    },
    Slider::default(),
    SliderValue(50.0),
    SliderRange::new(0.0, 100.0),
    // ... thumb and track children
));

The orientation is automatically detected based on the node dimensions - no API changes required!

@github-actions
Copy link
Contributor

Welcome, new contributor!

Please make sure you've read our contributing guide and we look forward to reviewing your pull request shortly ✨

@alice-i-cecile alice-i-cecile added C-Feature A new feature, making something new possible A-UI Graphical user interfaces, styles, layouts, and widgets X-Uncontroversial This work is generally agreed upon D-Straightforward Simple bug fixes and API improvements, docs, test and examples labels Nov 16, 2025
@alice-i-cecile alice-i-cecile added this to the 0.18 milestone Nov 16, 2025
@alice-i-cecile alice-i-cecile added the S-Needs-Review Needs reviewer attention (from anyone!) to move forward label Nov 16, 2025
return;
}

// Detect orientation: vertical if height > width
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a clever idea and I want to keep it, but we should call this out in the docs somewhere.

Copy link
Member

@alice-i-cecile alice-i-cecile left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A quick note on docs, and I would like a vertical slider in one of our examples so we can quickly test this please.

@DuckyBlender
Copy link
Contributor Author

DuckyBlender commented Nov 17, 2025

Made a fix to slider.rs and created the example
cargo run --example vertical_slider --features="experimental_bevy_ui_widgets"

@DuckyBlender
Copy link
Contributor Author

I don't think I can do anything about the failing check

@alice-i-cecile
Copy link
Member

Yep, that's an upstream problem.

@alice-i-cecile alice-i-cecile added S-Ready-For-Final-Review This PR has been approved by the community. It's ready for a maintainer to consider merging it and removed S-Needs-Review Needs reviewer attention (from anyone!) to move forward labels Nov 17, 2025
@alice-i-cecile alice-i-cecile added this pull request to the merge queue Dec 9, 2025
Merged via the queue into bevyengine:main with commit 8a0367e Dec 9, 2025
40 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

A-UI Graphical user interfaces, styles, layouts, and widgets C-Feature A new feature, making something new possible D-Straightforward Simple bug fixes and API improvements, docs, test and examples S-Ready-For-Final-Review This PR has been approved by the community. It's ready for a maintainer to consider merging it X-Uncontroversial This work is generally agreed upon

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants