summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--internal/exporter/exporter.go56
-rw-r--r--internal/picker/picker.go89
-rw-r--r--internal/slider/slider.go22
-rw-r--r--internal/tui/tui.go5
4 files changed, 167 insertions, 5 deletions
diff --git a/internal/exporter/exporter.go b/internal/exporter/exporter.go
new file mode 100644
index 0000000..3ecf6ef
--- /dev/null
+++ b/internal/exporter/exporter.go
@@ -0,0 +1,56 @@
+package exporter
+
+import (
+ "fmt"
+ "strings"
+)
+
+const (
+ rgbFormat = iota
+ hexFormat
+ hslFormat
+ hwbFormat
+)
+
+func Export(hex string, format int) string {
+ switch format {
+ case hexFormat:
+ return hex
+ case rgbFormat:
+ return toRgb(hex)
+ case hslFormat:
+ return "Not Implemented yet..."
+ case hwbFormat:
+ return "Not Implemented yet..."
+ default:
+ return "Unknown export format requested"
+ }
+}
+
+func toRgb(hex string) string {
+ hex = strings.TrimPrefix(hex, "#")
+ r, g, b := HexToI(hex[:2]), HexToI(hex[2:4]), HexToI(hex[4:6])
+ return fmt.Sprintf("rgb(%d, %d, %d)", r, g, b)
+}
+
+func HexToI(s string) int {
+ lenS := len(s) - 1
+ chars := "0123456789ABCDEF"
+ s = strings.ToUpper(s)
+ var ttl int = 0
+
+ for n := lenS; n >= 0; n-- {
+ done := false
+ for i := 0; i < len(chars); i++ {
+ if s[n] == chars[i] {
+ ttl += i * (n << 4)
+ done = true
+ break
+ }
+ }
+ if !done { // Still not done after checking all chars
+ return -1
+ }
+ }
+ return ttl
+}
diff --git a/internal/picker/picker.go b/internal/picker/picker.go
new file mode 100644
index 0000000..290e9f9
--- /dev/null
+++ b/internal/picker/picker.go
@@ -0,0 +1,89 @@
+package picker
+
+import (
+ "github.com/ChausseBenjamin/golorpicker/internal/slider"
+ "github.com/charmbracelet/bubbles/list"
+ tea "github.com/charmbracelet/bubbletea"
+)
+
+const (
+ rgbTitle string = "RGB"
+)
+
+// A picker is a list of sliders allowing the user to select a color
+// It must therefore be capable of exporting a HEX value for previewing
+// as well as a
+
+type RGBPicker struct {
+ sliders list.Model
+ r, g, b slider.Slider
+ loaded bool
+}
+
+func NewRGB() *RGBPicker {
+ r := slider.New("R", 0, 255)
+ g := slider.New("G", 0, 255)
+ b := slider.New("B", 0, 255)
+
+ sliders := list.New(
+ []list.Item{*r, *g, *b},
+ list.NewDefaultDelegate(),
+ 80, 6,
+ )
+ sliders.Title = rgbTitle
+ sliders.SetShowHelp(false)
+ sliders.SetShowFilter(false)
+ sliders.DisableQuitKeybindings()
+
+ return &RGBPicker{
+ sliders: sliders,
+ r: *r,
+ g: *g,
+ b: *b,
+ loaded: false,
+ }
+}
+
+func (p RGBPicker) toHex() string {
+ const txt = "0123456789ABCDEF"
+ rgb := string([]byte{
+ '#',
+ txt[(p.r.Val()>>4)&0x0F],
+ txt[p.r.Val()&0x0F],
+ txt[(p.g.Val()>>4)&0x0F],
+ txt[p.g.Val()&0x0F],
+ txt[(p.b.Val()>>4)&0x0F],
+ txt[p.b.Val()&0x0F],
+ })
+ return rgb
+}
+
+func (p RGBPicker) Init() tea.Cmd {
+ return nil
+}
+
+func (p RGBPicker) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
+ switch msg := msg.(type) {
+ case tea.WindowSizeMsg:
+ if p.sliders.Width() != msg.Width && !p.loaded {
+ p.sliders.SetWidth(msg.Width - 6)
+ p.loaded = true
+ }
+ case tea.KeyMsg:
+ key := msg.String()
+ for _, k := range slider.Keystrokes() {
+ if key == k {
+ m := p.sliders.Items()[p.sliders.Index()].(slider.Slider)
+ return m.Update(msg)
+ }
+ }
+ }
+
+ var cmd tea.Cmd
+ p.sliders, cmd = p.sliders.Update(msg)
+ return p, cmd
+}
+
+func (p RGBPicker) View() string {
+ return p.sliders.View()
+}
diff --git a/internal/slider/slider.go b/internal/slider/slider.go
index 0c0a89e..e882a29 100644
--- a/internal/slider/slider.go
+++ b/internal/slider/slider.go
@@ -51,8 +51,13 @@ 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) Val() int {
+ return s.val
+}
+
+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) Animate(msg tea.Msg) (tea.Model, tea.Cmd) {
@@ -66,9 +71,8 @@ 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) View() string {
+ return s.bar.View() + fmt.Sprintf(" (%d)", s.val)
}
func (s Slider) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
@@ -103,3 +107,11 @@ func (s Slider) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
}
// }}}
+// Implement the list.Item interface {{{
+
+func (s Slider) FilterValue() string {
+ // Sliders shouldn't be filtered
+ return ""
+}
+
+// }}}
diff --git a/internal/tui/tui.go b/internal/tui/tui.go
new file mode 100644
index 0000000..3bbbc95
--- /dev/null
+++ b/internal/tui/tui.go
@@ -0,0 +1,5 @@
+package tui
+
+// TODO: Implement the TUI struct
+// This will be the main thing containing all elements
+type TUI struct{}