From de7c6e9ab8bb4ab3af4557800cf92dd5ebddd2f8 Mon Sep 17 00:00:00 2001 From: Benjamin Chausse Date: Mon, 25 Nov 2024 21:44:11 -0500 Subject: feat: Interactive input (#16) * Refactor copy keybinds into single help entry * Manually input color values at runtime * Showcase input instead of clipboard in demo * more vhs updates --- internal/switcher/switcher.go | 79 ++++++++++++++++++++++++++++--------------- 1 file changed, 52 insertions(+), 27 deletions(-) (limited to 'internal/switcher/switcher.go') diff --git a/internal/switcher/switcher.go b/internal/switcher/switcher.go index 860bf81..74f0d6b 100644 --- a/internal/switcher/switcher.go +++ b/internal/switcher/switcher.go @@ -9,30 +9,43 @@ import ( "github.com/ChausseBenjamin/termpicker/internal/picker" "github.com/ChausseBenjamin/termpicker/internal/preview" "github.com/ChausseBenjamin/termpicker/internal/quit" - "github.com/ChausseBenjamin/termpicker/internal/util" "github.com/charmbracelet/bubbles/help" "github.com/charmbracelet/bubbles/key" + "github.com/charmbracelet/bubbles/textinput" tea "github.com/charmbracelet/bubbletea" "github.com/charmbracelet/lipgloss" ) +const ( + IndexRgb int = iota + IndexCmyk + IndexHsl +) + type Model struct { active int pickers []picker.Model preview preview.Model help help.Model - fullHelp bool // When false, only show help for the switcher (not children) + input textinput.Model notices notices.Model + fullHelp bool // When false, only show help for the switcher (not children) } -func New(pickers []picker.Model) Model { +func New() Model { + pickers := []picker.Model{ // Order MUST match the Index* constants + *picker.RGB(), + *picker.CMYK(), + *picker.HSL(), + } return Model{ active: 0, pickers: pickers, preview: *preview.New(colors.Hex(pickers[0].GetColor())), help: help.New(), - fullHelp: false, + input: textinput.New(), notices: notices.New(), + fullHelp: false, } } @@ -110,14 +123,20 @@ func (m Model) View() string { // helpstr = m.help.FullHelpView([][]key.Binding{m.AllKeys()[0]}) helpstr = m.help.FullHelpView(shortKeys()) } - helpstr = boxStyle.Render(helpstr) - return fmt.Sprintf("%s\n%s\n%s\n%v\n%v", + inputStr := "" + if m.input.Focused() { + boxStyle = boxStyle.Border(lipgloss.RoundedBorder(), true, true, true, true).Width(w) + inputStr = boxStyle.Render(m.input.View()) + } + + return fmt.Sprintf("%s\n%s\n%s\n%v\n%v\n%v", tabs, pickerView, previewStr, helpstr, + inputStr, m.notices.View(), ) } @@ -131,7 +150,28 @@ func (m Model) Update(msg tea.Msg) (tea.Model, tea.Cmd) { newNotices, cmd := m.notices.Update(msg) m.notices = newNotices.(notices.Model) cmds = append(cmds, cmd) + case tea.KeyMsg: + + if m.input.Focused() { + keys.esc.SetEnabled(true) + keys.confirm.SetEnabled(true) + if key.Matches(msg, keys.esc) { + m.input.Blur() + } else if key.Matches(msg, keys.confirm) { + m.input.Blur() + cmds = append( + cmds, + m.NewNotice(m.SetColorFromText(m.input.Value())), + m.Init(), // Will force a slider update/animation + ) + } + newInput, cmd := m.input.Update(msg) + m.input = newInput + cmds = append(cmds, cmd) + return m, tea.Batch(cmds...) + } + switch { case key.Matches(msg, keys.next): cs := m.pickers[m.active].GetColor() @@ -143,31 +183,17 @@ func (m Model) Update(msg tea.Msg) (tea.Model, tea.Cmd) { m.Prev() m.pickers[m.active].SetColor(cs) - case key.Matches(msg, keys.cpHex): - cmd := m.notices.New(util.Copy(colors.Hex(m.pickers[m.active].GetColor()))) - cmds = append(cmds, cmd) - - case key.Matches(msg, keys.cpRgb): - pc := m.pickers[m.active].GetColor().ToPrecise() - rgb := colors.RGB{}.FromPrecise(pc).(colors.RGB) - cmd := m.notices.New(util.Copy(rgb.String())) - cmds = append(cmds, cmd) - - case key.Matches(msg, keys.cpHsl): - pc := m.pickers[m.active].GetColor().ToPrecise() - hsl := colors.HSL{}.FromPrecise(pc).(colors.HSL) - cmd := m.notices.New(util.Copy(hsl.String())) - cmds = append(cmds, cmd) - - case key.Matches(msg, keys.cpCmyk): - pc := m.pickers[m.active].GetColor().ToPrecise() - cmyk := colors.CMYK{}.FromPrecise(pc).(colors.CMYK) - cmd := m.notices.New(util.Copy(cmyk.String())) + case key.Matches(msg, keys.copy): + cmd := m.notices.New(m.copyColor(msg.String())) cmds = append(cmds, cmd) case key.Matches(msg, keys.help): m.fullHelp = !m.fullHelp + case key.Matches(msg, keys.insert): + cmd := m.input.Focus() + cmds = append(cmds, cmd) + case key.Matches(msg, keys.quit): return quit.Model{}, tea.Quit @@ -183,7 +209,6 @@ func (m Model) Update(msg tea.Msg) (tea.Model, tea.Cmd) { newNotices, cmd := m.notices.Update(msg) m.notices = newNotices.(notices.Model) cmds = append(cmds, cmd) - return m, tea.Batch(cmds...) } default: -- cgit v1.2.3