Files
8bitMyGoUI/media/recordbutton.go
T
ZacharyZhang-NY 0e21870b64 Add media components 346-365; input.SlideBase, guarded Pad
An audio player with transport, scrubber and volume; an equalizer and
a visualizer; a playlist; a cassette, cartridge and record that turn
while they play and hold where they stop; piano keys, a step sequencer
and a tracker you can type into; a waveform, a 16:9 video frame, an
image compare, a gallery, a filmstrip, a record button and an FM tuner.

input exports SlideBase, the undrawn rail its sliders share; the
gallery treats exported Bases as building blocks, not components.
pixel's micro font gains '#' for notes like C#4. pixel.Pad and the
slide rail read input only while their base is enabled, so Inert or a
fresh Disabled stops a drag or a key already sent. AGENTS records why
a drawn container keeps the DISABLED description: MyGo paints a
disabled subtree at half opacity.
2026-10-12 06:17:12 -04:00

81 lines
1.7 KiB
Go

package media
import (
"log/slog"
"time"
"github.com/egoist/mygo/ui"
"git.zacharyzhang.com/ZacharyZhang-NY/8bitMyGoUI/input"
"git.zacharyzhang.com/ZacharyZhang-NY/8bitMyGoUI/pixel"
)
type RecordButtonOptions struct {
Disabled bool
}
type RecordButtonResult struct {
Element *ui.Element
Changed bool
}
type takeKey struct{}
// take is when recording began and the last take's length.
type take struct {
since time.Time
took time.Duration
}
var (
recDot = pixel.MustSprite(`
..rrr..
.rrrrr.
rrrrrrr
rrrrrrr
rrrrrrr
.rrrrr.
..rrr..
`)
recOff = pixel.MustSprite(`
..sss..
.s...s.
s.....s
s.....s
s.....s
.s...s.
..sss..
`)
)
// RecordButton toggles *rec; the dot blinks, time runs.
func RecordButton(c *ui.Context, text string, rec *bool, o RecordButtonOptions) RecordButtonResult {
k := pixel.K(c)
now := k.Now()
row := ui.Row(c)
tk := ui.Local(row, takeKey{}, func() take { return take{} })
// Follow *rec, whoever flips it; a click builds again.
switch {
case *rec && tk.since.IsZero():
tk.since, tk.took = now, 0
case !*rec && !tk.since.IsZero():
tk.since, tk.took = time.Time{}, now.Sub(tk.since)
}
took, dot := tk.took, recDot
if *rec {
took = now.Sub(tk.since)
k.At(c, tk.since.Add(took.Truncate(time.Second)+time.Second))
if !k.Reduce() && k.Tick(c, 2)%2 == 1 {
dot = recOff
}
}
res := RecordButtonResult{Element: row}
row.Children(func() {
res.Changed = input.Toggle(c, k.Msg("rec")+" "+mmss(took), rec, input.ToggleOptions{Icon: dot, Label: text + ", " + mmss(took), Disabled: o.Disabled}).Changed
})
if res.Changed {
slog.Debug("8bit: record button", "label", text, "rec", *rec, "time", mmss(took))
}
return res
}