Color Arc

Edit a color channel on a partial circular track.

Try it

Drag the hue arc to update the preview and committed hue. This preview runs the exact code sample below.

Open example separately ↗

Basic use

Hue arc with preview and commit
use gpui::{Context, Entity, Render, Window, div, prelude::*, px};
use xgpui_luma::controls::slider::{SliderControl, SliderEventExt};
use xgpui_luma_color::color_arc::ColorArcBuilder;
use xgpui_luma_color::style::Size;

struct Example {
    control: Entity<SliderControl>,
    preview: f32,
    committed: f32,
}
impl Example {
    fn new(cx: &mut Context<Self>) -> Self {
        let control = ColorArcBuilder::hue("hue-arc", 210.0, 0.8, 0.5)
            .size(Size::Medium).start_degrees(-45.0).sweep_degrees(270.0)
            .spawn(cx)
            .on_value_changed(cx, |owner: &mut Self, _, value, cx| {
                owner.preview = value;
                cx.notify();
            })
            .on_release(cx, |owner, _, value, cx| {
                owner.committed = value;
                cx.notify();
            });
        Self { control, preview: 210.0, committed: 210.0 }
    }
}
impl Render for Example {
    fn render(&mut self, _: &mut Window, _: &mut Context<Self>) -> impl IntoElement {
        div().w(px(240.0)).child(self.control.clone())
    }
}

Channels and appearance

hue(id, hue, saturation, lightness), saturation(id, saturation, hue, hsv_value), and lightness(id, lightness, hue, saturation) choose the channel. Hue uses degrees; saturation/lightness use 0..1.

Use start_degrees and sweep_degrees for geometry, reversed for value direction, and size(Size), arc_thickness, and thumb_size for appearance. Raster rendering is the default; the *_with_renderer constructors accept ColorArcRenderer.

Events

EventPayloadCallback
Changethumb_id: ThumbId
value: f32
on_value_changed
Update the live preview.
Releasethumb_id: ThumbId
value: f32
on_release
Commit the interaction value.
DragStartthumb_id: ThumbIdon_drag_start
Begin a pointer gesture.
DragEndthumb_id: ThumbId
value: f32
on_drag_end
Finish a pointer gesture.
ThumbAddedthumb_id: ThumbId
value: f32
on_thumb_added
Track an added gradient stop.
ThumbRemovedthumb_id: ThumbIdon_thumb_removed
Track a removed stop.
ThumbSelectedthumb_id: ThumbIdon_thumb_selected
Update the selected thumb.
FocusChangedfocused: boolon_focus_changed
React to keyboard focus.
HoverChangedhovered: boolon_hover_changed
React to pointer hover.
EnabledChangedenabled: boolon_enabled_changed
React to enablement changes.

These are SDK SliderEvent callbacks, available through SliderEventExt. The builders return Entity<SliderControl>. Each callback receives the owner, the listed payload values, and the owner context. Register callbacks after spawn; use on_event or cx.subscribe for the full event stream. See Slider events.

Keyboard and synchronization

The arc uses the SDK Slider’s angular input strategy over a bounded start/sweep range. It does not enable the full ring’s wrapping policy. Use the normal SDK slider keyboard bindings and configure scalar step for channel snapping.

Retain domain_renderer() and track_context() before spawning. Update dependent color delegates and refresh thumb previews with update_arc_delegate / refresh_color_arc, or use the corresponding ColorCompositionSync helper. Numeric value changes alone do not update the base colors of the track.

Source

Implementation · Color controls