diff options
Diffstat (limited to 'internal/tui/theme.go')
| -rw-r--r-- | internal/tui/theme.go | 103 |
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 +} |
