summaryrefslogtreecommitdiff
path: root/internal/switcher/switcher.go
blob: c4705571c317dc3b26ddf7cfbdac810fd3502229 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
package switcher

import (
	"fmt"
	"log/slog"

	"github.com/ChausseBenjamin/termpicker/internal/colors"
	"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/key"
	tea "github.com/charmbracelet/bubbletea"
)

type Model struct {
	active  int
	pickers []picker.Model
	preview preview.Model
}

func New(pickers []picker.Model) Model {
	return Model{
		active:  0,
		pickers: pickers,
		preview: *preview.New(colors.Hex(pickers[0].GetColor())),
	}
}

func (m Model) fixSel(val int) int {
	size := len(m.pickers)
	return (val%size + size) % size
}

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) Init() tea.Cmd {
	cmds := []tea.Cmd{}
	for _, p := range m.pickers {
		cmds = append(cmds, p.Init())
	}
	return tea.Batch(cmds...)
}

func (m Model) View() string {
	v := "|"
	for i, p := range m.pickers {
		if i == m.active {
			v += fmt.Sprintf(">%s<|", p.Title())
		} else {
			v += fmt.Sprintf(" %s |", p.Title())
		}
	}
	return fmt.Sprintf("%s\n%s\n%s", v, m.pickers[m.active].View(), m.preview.View())
}

func (m Model) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
	keys := newKeybinds()
	cmds := []tea.Cmd{}
	slog.Info("Received tea.Msg", "tea_msg", msg, "type", fmt.Sprintf("%T", msg))
	switch msg := msg.(type) {
	case tea.KeyMsg:
		switch {
		case key.Matches(msg, keys.next):
			cs := m.pickers[m.active].GetColor()
			m.Next()
			m.pickers[m.active].SetColor(cs)

		case key.Matches(msg, keys.prev):
			cs := m.pickers[m.active].GetColor()
			m.Prev()
			m.pickers[m.active].SetColor(cs)

		case key.Matches(msg, keys.cpHex):
			util.Copy(colors.Hex(m.pickers[m.active].GetColor()))

		case key.Matches(msg, keys.cpRgb):
			pc := m.pickers[m.active].GetColor().ToPrecise()
			rgb := colors.RGB{}.FromPrecise(pc).(colors.RGB)
			util.Copy(rgb.String())

		case key.Matches(msg, keys.cpHsl):
			pc := m.pickers[m.active].GetColor().ToPrecise()
			hsl := colors.HSL{}.FromPrecise(pc).(colors.HSL)
			util.Copy(hsl.String())

		case key.Matches(msg, keys.cpCmyk):
			pc := m.pickers[m.active].GetColor().ToPrecise()
			cmyk := colors.CMYK{}.FromPrecise(pc).(colors.CMYK)
			util.Copy(cmyk.String())

		case key.Matches(msg, keys.quit):
			return quit.Model{}, tea.Quit

		default:
			// Update the picker
			newActive, cmd := m.pickers[m.active].Update(msg)
			m.pickers[m.active] = newActive.(picker.Model)
			cmds = append(cmds, cmd)
			// Update the preview
			newPreview := preview.New(colors.Hex(m.pickers[m.active].GetColor()))
			m.preview = *newPreview

			return m, tea.Batch(cmds...)
		}
	default:
		// fmt.Printf("\nmsg: %T\n", msg)
	}
	for i, p := range m.pickers {
		newActive, cmd := p.Update(msg)
		m.pickers[i] = newActive.(picker.Model)
		cmds = append(cmds, cmd)
	}
	// Update the preview
	newPreview := preview.New(colors.Hex(m.pickers[m.active].GetColor()))
	m.preview = *newPreview
	return m, tea.Batch(cmds...)
}