summaryrefslogtreecommitdiff
path: root/internal/tui/theme.go
diff options
context:
space:
mode:
Diffstat (limited to 'internal/tui/theme.go')
-rw-r--r--internal/tui/theme.go103
1 files changed, 103 insertions, 0 deletions
diff --git a/internal/tui/theme.go b/internal/tui/theme.go
new file mode 100644
index 0000000..862f193
--- /dev/null
+++ b/internal/tui/theme.go
@@ -0,0 +1,103 @@
+package tui
+
+import (
+ "math/rand/v2"
+ "strconv"
+)
+
+// Theme defines the shared color palette used across the TUI.
+type Theme struct {
+ HeaderFG string
+ SelectedFG string
+ SelectedBG string
+ RowFG string
+ RowBG string
+ StatusFG string
+ StatusBG string
+ SearchFG string
+ SearchBG string
+}
+
+// DefaultTheme returns the baseline theme inspired by Task Samurai.
+func DefaultTheme() Theme {
+ return Theme{
+ HeaderFG: "205",
+ SelectedFG: "229",
+ SelectedBG: "57",
+ RowFG: "15",
+ RowBG: "236",
+ StatusFG: "229",
+ StatusBG: "57",
+ SearchFG: "21",
+ SearchBG: "226",
+ }
+}
+
+// RandomTheme returns a randomized high-contrast palette for disco mode.
+func RandomTheme() Theme {
+ theme := Theme{
+ HeaderFG: randomColor(),
+ SelectedBG: randomColor(),
+ RowBG: randomColor(),
+ StatusBG: randomColor(),
+ SearchBG: randomColor(),
+ }
+
+ theme.SelectedFG = contrastColor(theme.SelectedBG)
+ theme.RowFG = contrastColor(theme.RowBG)
+ theme.StatusFG = contrastColor(theme.StatusBG)
+ theme.SearchFG = contrastColor(theme.SearchBG)
+ return theme
+}
+
+func randomColor() string {
+ return strconv.Itoa(rand.IntN(256))
+}
+
+func contrastColor(background string) string {
+ value, err := strconv.Atoi(background)
+ if err != nil {
+ return "15"
+ }
+
+ if xtermBrightness(value) > 128 {
+ return "0"
+ }
+ return "15"
+}
+
+func xtermBrightness(index int) float64 {
+ red, green, blue := xtermRGB(index)
+ return 0.299*float64(red) + 0.587*float64(green) + 0.114*float64(blue)
+}
+
+func xtermRGB(index int) (int, int, int) {
+ if index < 0 {
+ index = 0
+ }
+ if index > 255 {
+ index = 255
+ }
+
+ if index < 16 {
+ table := [16][3]int{
+ {0, 0, 0}, {205, 0, 0}, {0, 205, 0}, {205, 205, 0},
+ {0, 0, 238}, {205, 0, 205}, {0, 205, 205}, {229, 229, 229},
+ {127, 127, 127}, {255, 0, 0}, {0, 255, 0}, {255, 255, 0},
+ {92, 92, 255}, {255, 0, 255}, {0, 255, 255}, {255, 255, 255},
+ }
+ rgb := table[index]
+ return rgb[0], rgb[1], rgb[2]
+ }
+
+ if index <= 231 {
+ index -= 16
+ red := (index / 36) * 51
+ green := (index % 36 / 6) * 51
+ blue := (index % 6) * 51
+ return red, green, blue
+ }
+
+ gray := (index-232)*10 + 8
+ return gray, gray, gray
+}