diff options
author | Benjamin Chausse <benjamin@chausse.xyz> | 2024-11-23 18:12:03 -0500 |
---|---|---|
committer | Benjamin Chausse <benjamin@chausse.xyz> | 2024-11-23 18:12:03 -0500 |
commit | 89094fecf4cb1c018f15c976641cd18c255eac28 (patch) | |
tree | 9f6e32c38013bc526399ab324891e0b3269e50dc /internal/slider |
Semi-working POC
Diffstat (limited to 'internal/slider')
-rw-r--r-- | internal/slider/evaluation.go | 46 | ||||
-rw-r--r-- | internal/slider/keys.go | 52 | ||||
-rw-r--r-- | internal/slider/slider.go | 71 |
3 files changed, 169 insertions, 0 deletions
diff --git a/internal/slider/evaluation.go b/internal/slider/evaluation.go new file mode 100644 index 0000000..363efe7 --- /dev/null +++ b/internal/slider/evaluation.go @@ -0,0 +1,46 @@ +package slider + +func (m Model) Val() int { return m.current } + +func (m *Model) Set(v int) { + m.current = v + m.fixRange() +} + +func (m *Model) Inc(v int) { + m.current += v + m.fixRange() +} + +func (m *Model) Dec(v int) { + m.current -= v + m.fixRange() +} + +func (m *Model) Pcnt() float64 { + return float64(m.current) / float64(m.max) +} + +func (m *Model) SetPcnt(p float64) { + m.current = int(float64(m.max) * p) + m.fixRange() +} + +func (m *Model) IncPcnt(p float64) { + m.current += int(float64(m.max) * p) + m.fixRange() +} + +func (m *Model) DecPcnt(p float64) { + m.current -= int(float64(m.max) * p) + m.fixRange() +} + +func (m *Model) fixRange() { + if m.current > m.max { + m.current = m.max + } + if m.current < 0 { + m.current = 0 + } +} diff --git a/internal/slider/keys.go b/internal/slider/keys.go new file mode 100644 index 0000000..9f96903 --- /dev/null +++ b/internal/slider/keys.go @@ -0,0 +1,52 @@ +package slider + +import "github.com/charmbracelet/bubbles/key" + +type keybinds struct { + incRegular key.Binding + decRegular key.Binding + incPrecise key.Binding + decPrecise key.Binding + // quitApp key.Binding +} + +func newKeybinds() keybinds { + return keybinds{ + incRegular: key.NewBinding( + key.WithKeys("right", "l"), + key.WithHelp("l", "Increase (coarse)"), + ), + decRegular: key.NewBinding( + key.WithKeys("left", "h"), + key.WithHelp("h", "Decrease (coarse)"), + ), + incPrecise: key.NewBinding( + key.WithKeys("shift+right", "L"), + key.WithHelp("L", "Increase (fine)"), + ), + decPrecise: key.NewBinding( + key.WithKeys("shift+left", "H"), + key.WithHelp("H", "Decrease (fine)"), + ), + } +} + +// Join all keybindings into a single slice +// a parent can use to know what Keys +// it's children have. +func Keys() []key.Binding { + k := newKeybinds() + return []key.Binding{ + k.incRegular, + k.decRegular, + k.incPrecise, + k.decPrecise, + } +} + +// AllKeys returns key.Bindings for the Model +// and all of its active children. The parent +// can use this to generate help text. +func (m Model) AllKeys() []key.Binding { + return Keys() +} diff --git a/internal/slider/slider.go b/internal/slider/slider.go new file mode 100644 index 0000000..d726e7b --- /dev/null +++ b/internal/slider/slider.go @@ -0,0 +1,71 @@ +package slider + +import ( + "fmt" + + "github.com/charmbracelet/bubbles/key" + "github.com/charmbracelet/bubbles/progress" + tea "github.com/charmbracelet/bubbletea" +) + +type Model struct { + label byte + progress progress.Model + max int + current int + mappings keybinds +} + +func New(label byte, maxVal int, opts ...progress.Option) Model { + slider := Model{ + label: label, + progress: progress.New( + progress.WithoutPercentage(), + ), + max: maxVal, + current: maxVal / 2, + mappings: newKeybinds(), + } + for _, opt := range opts { + opt(&slider.progress) + } + return slider +} + +func (m Model) Title() string { return fmt.Sprintf("%c", m.label) } + +func (m Model) Init() tea.Cmd { + return nil +} + +func (m Model) Update(msg tea.Msg) (tea.Model, tea.Cmd) { + keys := newKeybinds() + switch msg := msg.(type) { + case tea.KeyMsg: + switch { + case key.Matches(msg, keys.incRegular): + m.IncPcnt(0.05) + case key.Matches(msg, keys.decRegular): + m.DecPcnt(0.05) + case key.Matches(msg, keys.incPrecise): + m.Inc(1) + case key.Matches(msg, keys.decPrecise): + m.Dec(1) + } + return m, m.progress.SetPercent(m.Pcnt()) + case progress.FrameMsg: + progressModel, cmd := m.progress.Update(msg) + m.progress = progressModel.(progress.Model) + return m, cmd + default: + return m, nil + } +} + +func (m Model) ViewValue(current int) string { + return fmt.Sprintf("(%3d/%d)", current, m.max) +} + +func (m Model) View() string { + return fmt.Sprintf("%v: %v %v", m.Title(), m.progress.View(), m.ViewValue(m.current)) +} |