summaryrefslogtreecommitdiff
path: root/internal
diff options
context:
space:
mode:
authorBenjamin Chausse <benjamin@chausse.xyz>2024-10-17 23:12:11 -0400
committerBenjamin Chausse <benjamin@chausse.xyz>2024-10-17 23:12:11 -0400
commit81300eeac7af56439cedba2b461cacc57944175c (patch)
treeec8810e34f59b0593fa69a382d717d7d7895ce69 /internal
parent0ab03ce4c13e63b2403eb1039b7d0185d3d30d9d (diff)
A single slider
Diffstat (limited to 'internal')
-rw-r--r--internal/slider/slider.go105
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
+}
+
+// }}}