Skip to content

HSV color picker UI widget#10754

Closed
torsteingrindvik wants to merge 7 commits intobevyengine:mainfrom
torsteingrindvik:color-picker
Closed

HSV color picker UI widget#10754
torsteingrindvik wants to merge 7 commits intobevyengine:mainfrom
torsteingrindvik:color-picker

Conversation

@torsteingrindvik
Copy link
Contributor

@torsteingrindvik torsteingrindvik commented Nov 26, 2023

Objective

  • Bevy is lacking a way to pick colors interactively

Solution

It's very likely that my solution might not be the best approach, looking for input.

Iteration 1 video

color-picker.mp4

Iteration 2 video

color-picker-002.mp4
  • Added a marker within the sat-val box
  • Example uses flex column
  • User must mark a relationship between wheel and box with a component

Iteration 3 video

color-picker-003.mp4
  • Added a marker on the hue wheel
  • Colors update both if color is picked on hue wheel as well as sat-val box now

Description

The color picker is made out of two parts: The outer wheel (the "hue wheel") and the inner box (the "saturation-value box").

Each have their own shader used to display the colors to pick.

Interaction is done via relative cursor positions- which is why the split into two UI nodes was done. It made the math a lot simpler.

bevy_ui now sends events when:

  • A hue wheel is pressed
  • A saturation-value box is pressed

If the HueWheelSibling component is added to the box, the box will be kept in sync when the wheel hue changes.


Changelog

Added

  • Added HSV color pickers now usable via UI bundles
  • Added an example to showcase independent color pickers

@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 labels Nov 26, 2023
@alice-i-cecile alice-i-cecile changed the title HSV color picker UI element HSV color picker UI widget Nov 26, 2023
@github-actions
Copy link
Contributor

The generated examples/README.md is out of sync with the example metadata in Cargo.toml or the example readme template. Please run cargo run -p build-templated-pages -- update examples to update it, and commit the file change.

@torsteingrindvik
Copy link
Contributor Author

Some thoughts after sleeping on it.

I think it's better for the user to explicitly add the wheel-box relationship via a component.
Something like

/// If this is added to a saturation-value box, the box will update automatically when
/// the related hue changes.
#[derive(Component)]
struct HueWheelSibling {
  /// The hue-wheel's entity
  sibling: entity
}

should then be added by end-users.

Right now, this is done implicitly when both the wheel and box share a parent (and fails otherwise).

So this relationship is required:

parent
   \--- wheel
   \--- box

so this forces a common parent node.

Also, what happens if:

parent
   \--- wheel
   \--- box1
   \--- box2

for example? It's not clear which one is implicitly linked to the wheel (or both, or none).

So later I'll make it explicit, which will also allow interesting use-cases such as placing the wheel and box entirely separately in the UI.

@torsteingrindvik
Copy link
Contributor Author

Updated the PR with the thoughts I wrote in previous comment. Updated description and added new video

@NiseVoid
Copy link
Contributor

Haven't looked at the actual code, but it seems a bit weird that changing the hue doesn't update the color and that there's nothing showing you the selected hue.

There's also the question of how well this color wheel works. Changing the hue on HSV can cause the saturation/value to change subtly (but not as badly as HSL), maybe something like oklab would be interesting so changing the hue works as expected? Not something that should block this PR if that would be an easy change later.

Torstein Grindvik added 6 commits December 2, 2023 09:03
Signed-off-by: Torstein Grindvik <torstein.grindvik@muybridge.com>
Signed-off-by: Torstein Grindvik <torstein.grindvik@muybridge.com>
… make little marker

Signed-off-by: Torstein Grindvik <torstein.grindvik@muybridge.com>
Signed-off-by: Torstein Grindvik <torstein.grindvik@muybridge.com>
Signed-off-by: Torstein Grindvik <torstein.grindvik@muybridge.com>
Signed-off-by: Torstein Grindvik <torstein.grindvik@muybridge.com>
Signed-off-by: Torstein Grindvik <torstein.grindvik@muybridge.com>
@torsteingrindvik
Copy link
Contributor Author

torsteingrindvik commented Dec 2, 2023

Haven't looked at the actual code, but it seems a bit weird that changing the hue doesn't update the color and that there's nothing showing you the selected hue.

There's also the question of how well this color wheel works. Changing the hue on HSV can cause the saturation/value to change subtly (but not as badly as HSL), maybe something like oklab would be interesting so changing the hue works as expected? Not something that should block this PR if that would be an easy change later.

Updated OP with new video, implemented both your suggestions about the updating via hue and added a hue marker.

I agree that HSV isn't perfect for all use cases.
What I'm thinking is that in the future users can spawn any variant they want, whether it be HSL or HSV or Oklab or whichever by just constructing the right bundle(s).

But initially since all image processing software and game engines I checked (Krita, Unity, Unreal, Godot iirc) have the ability to pick HSV, I think it's a decent place to start out (EDIT: because it can be useful and I think users will expect it).

@torsteingrindvik
Copy link
Contributor Author

When #9698 lands I can get rid of the hsv_to_rgb function.

@torsteingrindvik
Copy link
Contributor Author

I wasn't very fond of my implementation and I think with the many UI experiments and editor prototypes etc. coming to Bevy a cleaner more Bevy idiomatic approach can be found soon, so closing this out.

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

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants