Files
MujicaUI/media_controls.go
T

78 lines
2.6 KiB
Go

package mujica
import (
"fmt"
"log/slog"
"github.com/egoist/mygo/ui"
)
// LoopMode is how playback repeats. The zero value repeats nothing.
type LoopMode int
const (
LoopOff LoopMode = iota
LoopAll
LoopOne
)
// next cycles off, all, one.
func (m LoopMode) next() LoopMode { return (m + 1) % 3 }
// MediaControlsState is what the caller's playback reports.
type MediaControlsState struct {
Playing bool
Loop LoopMode
Shuffle bool
// NoPrevious and NoNext disable those buttons at the ends.
NoPrevious, NoNext bool
}
// MediaControlsOptions are the callbacks; every one is required.
type MediaControlsOptions struct {
OnPrevious, OnPlay, OnPause, OnNext func()
OnLoop func(LoopMode)
OnShuffle func(bool)
Disabled bool
}
// MediaControls are previous, play, next, loop and shuffle buttons.
func MediaControls(c *ui.Context, st MediaControlsState, opts MediaControlsOptions) *ui.Element {
if opts.OnPrevious == nil || opts.OnPlay == nil || opts.OnPause == nil || opts.OnNext == nil || opts.OnLoop == nil || opts.OnShuffle == nil {
panic("mujica: MediaControls needs every callback")
}
if st.Loop < LoopOff || st.Loop > LoopOne {
panic(fmt.Sprintf("mujica: unknown LoopMode %d", st.Loop))
}
row := ui.Row(c).Gap(Density(c).Unit()).AlignItems(ui.Center).FocusGroup(ui.Horizontal).Role(ui.RoleToolbar).
Label(msg(c, "media_controls.label")).Disabled(opts.Disabled)
row.Children(func() {
shuffle := mediaToggleAction(c, mediaShuffle, msg(c, "media_controls.shuffle"), st.Shuffle)
if shuffle.Clicked() && !shuffle.IsDisabled() {
slog.Debug("mujica: media_controls shuffle", "on", !st.Shuffle)
opts.OnShuffle(!st.Shuffle)
}
prev := iconAction(c, mediaPrev, msg(c, "media_controls.previous")).Disabled(st.NoPrevious)
if prev.Clicked() && !prev.IsDisabled() {
slog.Debug("mujica: media_controls previous")
opts.OnPrevious()
}
mediaPlayToggle(c, st.Playing, opts.OnPlay, opts.OnPause)
next := iconAction(c, mediaNext, msg(c, "media_controls.next")).Disabled(st.NoNext)
if next.Clicked() && !next.IsDisabled() {
slog.Debug("mujica: media_controls next")
opts.OnNext()
}
icon := mediaRepeat
if st.Loop == LoopOne {
icon = mediaRepeatOne
}
loop := mediaToggleAction(c, icon, msg(c, []string{"media_controls.loopOff", "media_controls.loopAll", "media_controls.loopOne"}[st.Loop]), st.Loop != LoopOff)
if loop.Clicked() && !loop.IsDisabled() {
slog.Debug("mujica: media_controls loop", "mode", st.Loop.next())
opts.OnLoop(st.Loop.next())
}
})
return row
}