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/picker |
Semi-working POC
Diffstat (limited to 'internal/picker')
-rw-r--r-- | internal/picker/keys.go | 29 | ||||
-rw-r--r-- | internal/picker/picker.go | 137 |
2 files changed, 166 insertions, 0 deletions
diff --git a/internal/picker/keys.go b/internal/picker/keys.go new file mode 100644 index 0000000..f5b7135 --- /dev/null +++ b/internal/picker/keys.go @@ -0,0 +1,29 @@ +package picker + +import "github.com/charmbracelet/bubbles/key" + +type keybinds struct { + next, prev key.Binding +} + +func newKeybinds() keybinds { + return keybinds{ + next: key.NewBinding( + key.WithKeys("j", "down"), + key.WithHelp("j", "previous slider"), + ), + prev: key.NewBinding( + key.WithKeys("k", "up"), + key.WithHelp("k", "next slider"), + ), + } +} + +func Keys() []key.Binding { + k := newKeybinds() + return []key.Binding{k.next, k.prev} +} + +func (m Model) AllKeys() []key.Binding { + return append(Keys(), m.sliders[m.active].AllKeys()...) +} diff --git a/internal/picker/picker.go b/internal/picker/picker.go new file mode 100644 index 0000000..e3c396e --- /dev/null +++ b/internal/picker/picker.go @@ -0,0 +1,137 @@ +package picker + +import ( + "fmt" + + "github.com/charmbracelet/bubbles/key" + tea "github.com/charmbracelet/bubbletea" + "github.com/charmbracelet/bubbletea-app-template/internal/colors" + "github.com/charmbracelet/bubbletea-app-template/internal/slider" +) + +type Model struct { + title string + active int + sliders []slider.Model +} + +func (m *Model) Next() int { + m.active = m.fixSel(m.active + 1) + return m.active +} + +func (m *Model) Prev() int { + m.active = m.fixSel(m.active - 1) + return m.active +} + +func (m *Model) Sel(i int) int { + m.active = m.fixSel(i) + return m.active +} + +func (m Model) fixSel(val int) int { + size := len(m.sliders) + return (val%size + size) % size +} + +func New(sliders []slider.Model, title string) *Model { + return &Model{ + title: title, + active: 0, + sliders: sliders, + } +} + +func (m Model) Title() string { + return m.title +} + +func (m Model) GetColor() colors.ColorSpace { + switch m.title { + case "RGB": + return colors.RGB{ + R: m.sliders[0].Val(), + G: m.sliders[1].Val(), + B: m.sliders[2].Val(), + } + case "CMYK": + return colors.CMYK{ + C: m.sliders[0].Val(), + M: m.sliders[1].Val(), + Y: m.sliders[2].Val(), + K: m.sliders[3].Val(), + } + // TODO: HSL + default: // Default to white if we don't know the color space + return colors.RGB{ + R: 255, + G: 255, + B: 255, + } + } +} + +func (m Model) SetColor(c colors.ColorSpace) { + p := c.ToPrecise() + switch m.title { + case "RGB": + rgb := colors.RGB{}.FromPrecise(p).(colors.RGB) + m.sliders[0].Set(rgb.R) + m.sliders[1].Set(rgb.G) + m.sliders[2].Set(rgb.B) + case "CMYK": + cmyk := colors.CMYK{}.FromPrecise(p).(colors.CMYK) + m.sliders[0].Set(cmyk.C) + m.sliders[1].Set(cmyk.M) + m.sliders[2].Set(cmyk.Y) + m.sliders[3].Set(cmyk.K) + } +} + +func (m Model) Init() tea.Cmd { + cmds := []tea.Cmd{} + for _, s := range m.sliders { + cmds = append(cmds, s.Init()) + } + return tea.Batch(cmds...) +} + +func (m Model) View() string { + var s string + for i, slider := range m.sliders { + if i == m.active { + s += fmt.Sprintf("\n-> %s", slider.View()) + } else { + s += fmt.Sprintf("\n %s", slider.View()) + } + } + return s +} + +func (m Model) Update(msg tea.Msg) (tea.Model, tea.Cmd) { + keys := newKeybinds() + cmds := []tea.Cmd{} + switch msg := msg.(type) { + case tea.KeyMsg: + switch { + case key.Matches(msg, keys.next): + m.Next() + case key.Matches(msg, keys.prev): + m.Prev() + default: + newActive, cmd := m.sliders[m.active].Update(msg) + m.sliders[m.active] = newActive.(slider.Model) + cmds = append(cmds, cmd) + return m, tea.Batch(cmds...) + } + } + // Keys are only sent to the active sliders + // However, other messages (ex: tick, resize) must be sent to all + for i, s := range m.sliders { + newSlider, cmd := s.Update(msg) + m.sliders[i] = newSlider.(slider.Model) + cmds = append(cmds, cmd) + } + return m, tea.Batch(cmds...) +} |