package mujica import ( "log/slog" "math" "github.com/egoist/mygo/ui" "mujicaui/theme" ) // ScrubInputOptions configure a ScrubInput; the range and step rules are NumberInput's. type ScrubInputOptions struct { Min, Max float64 Step float64 Precision int Disabled bool } // scrubInputPixels is how far a drag moves for one step. const scrubInputPixels float32 = 4 // ScrubInput edits *value by dragging its label sideways, one Step per 4 DIPs, or by typing in its field. func ScrubInput(c *ui.Context, label string, value *float64, opts ScrubInputOptions) InputResult { if label == "" || value == nil { panic("mujica: ScrubInput needs a label and a value") } nopts := NumberInputOptions{Min: opts.Min, Max: opts.Max, Step: opts.Step, Precision: opts.Precision, Label: label, Disabled: opts.Disabled} s := numberInputResolve(nopts) k := Tokens(c) var r InputResult row := ui.Row(c).AlignItems(ui.Center).Gap(Density(c).Unit() * 2).Disabled(opts.Disabled) row.Children(func() { h := ui.Box(c).Shrink(0).MinHeight(theme.MinHitSize).MinWidth(theme.MinHitSize).Center().Cursor(ui.CursorResizeEW).Role(ui.RoleNone) drag := ui.Local(h, "scrub_input.drag", func() float64 { return math.NaN() }) dx, _, held := h.Dragged() scrubbed := false switch { case !held || h.IsDisabled(): *drag = math.NaN() case math.IsNaN(*drag): *drag = 0 fallthrough default: start := *value *drag += float64(dx) if n := int(*drag / float64(scrubInputPixels)); n != 0 { *drag -= float64(n) * float64(scrubInputPixels) // One grid step at a time, so a long drag stops at the bound. v := start for range max(n, -n) { v = s.stepBy(v, max(-1, min(1, n))) } if v != *value { *value, scrubbed = v, true } } } fg := k.TextMuted if held || h.Hovered() { fg = k.AccentText } h.Children(func() { ui.Text(c, label).TextColor(fg).Underline().DecorationColor(k.Border).SingleLine() }) r = NumberInput(c, value, nopts) r.Element.Width(Density(c).Unit() * 36) r.changed = r.changed || scrubbed if scrubbed { slog.Debug("mujica: scrub_input scrubbed", "label", label, "value", *value) } }) r.Element = row return r }