diff options
Diffstat (limited to 'internal')
-rw-r--r-- | internal/slider/slider.go | 105 |
1 files changed, 105 insertions, 0 deletions
diff --git a/internal/slider/slider.go b/internal/slider/slider.go new file mode 100644 index 0000000..0c0a89e --- /dev/null +++ b/internal/slider/slider.go @@ -0,0 +1,105 @@ +package slider + +import ( + "fmt" + + "github.com/charmbracelet/bubbles/progress" + tea "github.com/charmbracelet/bubbletea" +) + +const ( + // Global Keystrokes for sliders + setMinKey = "i" // i -> Initialise + setMaxKey = "I" + bigDecKey = "h" // vim left + smallDecKey = "H" + bigIncKey = "l" // vim right + smallIncKey = "L" +) + +func Keystrokes() []string { + return []string{ + setMinKey, setMaxKey, bigIncKey, bigDecKey, smallIncKey, smallDecKey, + } +} + +type Slider struct { + name string + val int + max int + bar progress.Model + loaded bool + options []progress.Option +} + +func (s Slider) Set(val int) (tea.Model, tea.Cmd) { + s.val = val + if s.val > s.max { + s.val = s.max + } + if s.val < 0 { + s.val = 0 + } + return s, s.bar.SetPercent(float64(s.val) / float64(s.max)) +} + +func (s Slider) Inc(val int) (tea.Model, tea.Cmd) { + return s.Set(s.val + val) +} + +func (s Slider) Dec(val int) (tea.Model, tea.Cmd) { + return s.Set(s.val - val) +} + +func (s Slider) View() string { + return s.bar.View() + fmt.Sprintf(" (%d)", s.val) +} + +func (s Slider) Animate(msg tea.Msg) (tea.Model, tea.Cmd) { + progressModel, cmd := s.bar.Update(msg) + s.bar = progressModel.(progress.Model) + return s, cmd +} + +// Implement tea.Model interface {{{ +func (s Slider) Init() tea.Cmd { + return s.bar.Init() +} + +func New(name string, v int, maxV int, opt ...progress.Option) *Slider { + opt = append(opt, progress.WithoutPercentage()) + return &Slider{name: name, max: maxV, val: v, options: opt} +} + +func (s Slider) Update(msg tea.Msg) (tea.Model, tea.Cmd) { + switch msg := msg.(type) { + case tea.KeyMsg: + switch msg.String() { + case bigIncKey: + return s.Inc(25) + case smallIncKey: + return s.Inc(1) + case bigDecKey: + return s.Dec(25) + case smallDecKey: + return s.Dec(1) + case setMinKey: + return s.Set(0) + case setMaxKey: + return s.Set(s.max) + default: + return s, tea.Quit + } + case tea.WindowSizeMsg: + if s.bar.Width != msg.Width && !s.loaded { + s.loaded = true + s.bar = progress.New(s.options...) + return s.Set(s.val) + } + case progress.FrameMsg: + return s.Animate(msg) + } + return s, nil +} + +// }}} |