Switch the theme live
Widgets copy their colors when they are created, so they now get role tokens (one unique RGB value per role) instead of colors, and a wrapper around the tcell screen replaces the tokens with the current theme's colors in SetContent. Changing the theme in the Config view swaps that table; the next draw recolors everything. Poster colors that equal a token are nudged off it. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_019reK4DUGYqDUjniWYJvwUW
This commit is contained in:
@@ -51,29 +51,65 @@ func TestChooseTheme(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestThemeApply(t *testing.T) {
|
||||
oldStyles, oldCurrent := tview.Styles, current
|
||||
func TestUseTokens(t *testing.T) {
|
||||
oldStyles := tview.Styles
|
||||
oldNames := map[string]tcell.Color{}
|
||||
for k, v := range tcell.ColorNames {
|
||||
oldNames[k] = v
|
||||
}
|
||||
defer func() {
|
||||
tview.Styles, current = oldStyles, oldCurrent
|
||||
tview.Styles = oldStyles
|
||||
for k, v := range oldNames {
|
||||
tcell.ColorNames[k] = v
|
||||
}
|
||||
}()
|
||||
|
||||
lightTheme.apply()
|
||||
if tview.Styles.PrimitiveBackgroundColor != lightTheme.bg || tview.Styles.PrimaryTextColor != lightTheme.text {
|
||||
useTokens()
|
||||
if tview.Styles.PrimitiveBackgroundColor != tokens.bg || tview.Styles.PrimaryTextColor != tokens.text {
|
||||
t.Error("tview styles not set")
|
||||
}
|
||||
// Color names in texts mean the theme's colors.
|
||||
if named("yellow") != lightTheme.yellow || tcell.GetColor("black") != lightTheme.bg || tcell.GetColor("white") != lightTheme.text {
|
||||
// Color names in texts mean the roles.
|
||||
if named("yellow") != tokens.yellow || tcell.GetColor("black") != tokens.bg || tcell.GetColor("white") != tokens.text {
|
||||
t.Error("color names not set")
|
||||
}
|
||||
if current.name != "light" {
|
||||
t.Error("current theme not set")
|
||||
}
|
||||
|
||||
func TestThemedScreenSwitchesLive(t *testing.T) {
|
||||
sim := tcell.NewSimulationScreen("")
|
||||
if err := sim.Init(); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
defer sim.Fini()
|
||||
sim.SetSize(4, 1)
|
||||
s := newThemedScreen(sim, darkTheme)
|
||||
poster := tcell.NewRGBColor(10, 20, 30)
|
||||
|
||||
draw := func() {
|
||||
s.SetContent(0, 0, 'a', nil, tcell.StyleDefault.Foreground(tokens.yellow).Background(tokens.bg))
|
||||
s.SetContent(1, 0, 'b', nil, tcell.StyleDefault.Foreground(poster).Background(poster))
|
||||
}
|
||||
check := func(th theme) {
|
||||
_, _, st, _ := sim.GetContent(0, 0)
|
||||
if fg, bg, _ := st.Decompose(); fg != th.yellow || bg != th.bg {
|
||||
t.Errorf("%s: role colors drawn as %v on %v", th.name, fg, bg)
|
||||
}
|
||||
_, _, st, _ = sim.GetContent(1, 0)
|
||||
if fg, bg, _ := st.Decompose(); fg != poster || bg != poster {
|
||||
t.Errorf("%s: other colors changed to %v on %v", th.name, fg, bg)
|
||||
}
|
||||
}
|
||||
draw()
|
||||
check(darkTheme)
|
||||
s.setTheme(lightTheme)
|
||||
draw()
|
||||
check(lightTheme)
|
||||
|
||||
// A poster color that equals a role color is nudged off it.
|
||||
if c := notToken(tokens.red); c == tokens.red {
|
||||
t.Error("role color in a picture not nudged")
|
||||
}
|
||||
if notToken(poster) != poster {
|
||||
t.Error("ordinary color changed")
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user