From 03ca852475d1dad45783b0b7e627fc38778011da Mon Sep 17 00:00:00 2001 From: Sasha Koshka Date: Wed, 12 Jun 2024 00:19:12 -0400 Subject: [PATCH] Restructure internal theme --- .../icons/fallback/assets/icons-large.png | Bin .../icons/fallback/assets/icons-large.xcf | Bin .../icons/fallback/assets/icons-small.png | Bin .../icons/fallback/assets/icons-small.xcf | Bin .../icons/fallback/assets/old/icons-large.png | Bin .../icons/fallback/assets/old/icons-large.xcf | Bin .../icons/fallback/assets/old/icons-small.png | Bin .../icons/fallback/assets/old/icons-small.xcf | Bin internal/{theme => }/icons/fallback/icon.go | 3 +- internal/{theme => }/icons/xdg/icon.go | 5 +- internal/{theme => }/icons/xdg/xdgiconname.go | 0 internal/registrar/registrar_unix.go | 27 +-- .../{theme => }/style/aluminum/aluminum.go | 6 +- internal/{theme => }/style/aluminum/style.go | 218 +++++++++--------- internal/{theme => style}/attribute.go | 2 +- internal/{theme => }/style/fallback/style.go | 214 ++++++++--------- .../{theme => }/style/fallback/wintergreen.go | 10 +- internal/{theme => style}/missing.go | 2 +- internal/{theme/theme.go => style/style.go} | 57 ++--- 19 files changed, 257 insertions(+), 287 deletions(-) rename internal/{theme => }/icons/fallback/assets/icons-large.png (100%) rename internal/{theme => }/icons/fallback/assets/icons-large.xcf (100%) rename internal/{theme => }/icons/fallback/assets/icons-small.png (100%) rename internal/{theme => }/icons/fallback/assets/icons-small.xcf (100%) rename internal/{theme => }/icons/fallback/assets/old/icons-large.png (100%) rename internal/{theme => }/icons/fallback/assets/old/icons-large.xcf (100%) rename internal/{theme => }/icons/fallback/assets/old/icons-small.png (100%) rename internal/{theme => }/icons/fallback/assets/old/icons-small.xcf (100%) rename internal/{theme => }/icons/fallback/icon.go (99%) rename internal/{theme => }/icons/xdg/icon.go (96%) rename internal/{theme => }/icons/xdg/xdgiconname.go (100%) rename internal/{theme => }/style/aluminum/aluminum.go (76%) rename internal/{theme => }/style/aluminum/style.go (54%) rename internal/{theme => style}/attribute.go (99%) rename internal/{theme => }/style/fallback/style.go (55%) rename internal/{theme => }/style/fallback/wintergreen.go (60%) rename internal/{theme => style}/missing.go (97%) rename internal/{theme/theme.go => style/style.go} (78%) diff --git a/internal/theme/icons/fallback/assets/icons-large.png b/internal/icons/fallback/assets/icons-large.png similarity index 100% rename from internal/theme/icons/fallback/assets/icons-large.png rename to internal/icons/fallback/assets/icons-large.png diff --git a/internal/theme/icons/fallback/assets/icons-large.xcf b/internal/icons/fallback/assets/icons-large.xcf similarity index 100% rename from internal/theme/icons/fallback/assets/icons-large.xcf rename to internal/icons/fallback/assets/icons-large.xcf diff --git a/internal/theme/icons/fallback/assets/icons-small.png b/internal/icons/fallback/assets/icons-small.png similarity index 100% rename from internal/theme/icons/fallback/assets/icons-small.png rename to internal/icons/fallback/assets/icons-small.png diff --git a/internal/theme/icons/fallback/assets/icons-small.xcf b/internal/icons/fallback/assets/icons-small.xcf similarity index 100% rename from internal/theme/icons/fallback/assets/icons-small.xcf rename to internal/icons/fallback/assets/icons-small.xcf diff --git a/internal/theme/icons/fallback/assets/old/icons-large.png b/internal/icons/fallback/assets/old/icons-large.png similarity index 100% rename from internal/theme/icons/fallback/assets/old/icons-large.png rename to internal/icons/fallback/assets/old/icons-large.png diff --git a/internal/theme/icons/fallback/assets/old/icons-large.xcf b/internal/icons/fallback/assets/old/icons-large.xcf similarity index 100% rename from internal/theme/icons/fallback/assets/old/icons-large.xcf rename to internal/icons/fallback/assets/old/icons-large.xcf diff --git a/internal/theme/icons/fallback/assets/old/icons-small.png b/internal/icons/fallback/assets/old/icons-small.png similarity index 100% rename from internal/theme/icons/fallback/assets/old/icons-small.png rename to internal/icons/fallback/assets/old/icons-small.png diff --git a/internal/theme/icons/fallback/assets/old/icons-small.xcf b/internal/icons/fallback/assets/old/icons-small.xcf similarity index 100% rename from internal/theme/icons/fallback/assets/old/icons-small.xcf rename to internal/icons/fallback/assets/old/icons-small.xcf diff --git a/internal/theme/icons/fallback/icon.go b/internal/icons/fallback/icon.go similarity index 99% rename from internal/theme/icons/fallback/icon.go rename to internal/icons/fallback/icon.go index 5c3eb67..27c5104 100644 --- a/internal/theme/icons/fallback/icon.go +++ b/internal/icons/fallback/icon.go @@ -7,7 +7,6 @@ import _ "image/png" import "git.tebibyte.media/tomo/tomo" import "git.tebibyte.media/tomo/tomo/data" import "git.tebibyte.media/tomo/tomo/canvas" -import dataTheme "git.tebibyte.media/tomo/nasin/internal/theme" //go:embed assets/icons-small.png var atlasSmallBytes []byte @@ -418,7 +417,7 @@ type iconTheme struct { } // New creates a new fallback icon theme. -func New () dataTheme.IconTheme { +func New () tomo.Icons { return new(iconTheme) } diff --git a/internal/theme/icons/xdg/icon.go b/internal/icons/xdg/icon.go similarity index 96% rename from internal/theme/icons/xdg/icon.go rename to internal/icons/xdg/icon.go index f59d207..1a2dbbf 100644 --- a/internal/theme/icons/xdg/icon.go +++ b/internal/icons/xdg/icon.go @@ -11,17 +11,16 @@ import "git.tebibyte.media/tomo/tomo" import xdgIconTheme "git.tebibyte.media/tomo/xdg/icon-theme" import "git.tebibyte.media/tomo/tomo/data" import "git.tebibyte.media/tomo/tomo/canvas" -import "git.tebibyte.media/tomo/nasin/internal/theme" type iconTheme struct { xdg xdgIconTheme.Theme - fallback theme.IconTheme + fallback tomo.Icons texturesSmall map[tomo.Icon] canvas.Texture texturesMedium map[tomo.Icon] canvas.Texture texturesLarge map[tomo.Icon] canvas.Texture } -func FindThemeWarn (name string, fallback theme.IconTheme, path ...string) (theme.IconTheme, error) { +func FindThemeWarn (name string, fallback tomo.Icons, path ...string) (tomo.Icons, error) { this := &iconTheme { fallback: fallback, texturesLarge: make(map[tomo.Icon] canvas.Texture), diff --git a/internal/theme/icons/xdg/xdgiconname.go b/internal/icons/xdg/xdgiconname.go similarity index 100% rename from internal/theme/icons/xdg/xdgiconname.go rename to internal/icons/xdg/xdgiconname.go diff --git a/internal/registrar/registrar_unix.go b/internal/registrar/registrar_unix.go index caea02c..ee9a8ea 100644 --- a/internal/registrar/registrar_unix.go +++ b/internal/registrar/registrar_unix.go @@ -3,36 +3,37 @@ package registrar import "os" import "log" -import "git.tebibyte.media/tomo/backend/x" import "git.tebibyte.media/tomo/tomo" -import dataTheme "git.tebibyte.media/tomo/nasin/internal/theme" -import "git.tebibyte.media/tomo/nasin/internal/theme/icons/xdg" -import "git.tebibyte.media/tomo/nasin/internal/theme/icons/fallback" -import "git.tebibyte.media/tomo/nasin/internal/theme/style/fallback" -import "git.tebibyte.media/tomo/nasin/internal/theme/style/aluminum" +import "git.tebibyte.media/tomo/backend/x" +import "git.tebibyte.media/tomo/nasin/internal/style" +import "git.tebibyte.media/tomo/nasin/internal/icons/xdg" +import "git.tebibyte.media/tomo/nasin/internal/icons/fallback" +import "git.tebibyte.media/tomo/nasin/internal/style/fallback" +import "git.tebibyte.media/tomo/nasin/internal/style/aluminum" func Init () error { - var theme *dataTheme.Theme + var styl *style.Style // TODO eventually get rid of this when we make a file format for // storing visual styles if os.Getenv("TOMO_USE_ALUMINUM_STYLE") != "" { - theme = aluminumStyle.New() + styl = aluminumStyle.New() } else { - theme = fallbackStyle.New() + styl = fallbackStyle.New() } - theme.IconTheme = fallbackIcons.New() + icons := fallbackIcons.New() iconThemeName := os.Getenv("TOMO_XDG_ICON_THEME") if iconThemeName != "" { - iconTheme, err := xdgIcons.FindThemeWarn(iconThemeName, theme.IconTheme) + xdgIconTheme, err := xdgIcons.FindThemeWarn(iconThemeName, icons) if err == nil { - theme.IconTheme = iconTheme + icons = xdgIconTheme } else { log.Printf("nasin: could not load icon theme '%s': %v", iconThemeName, err) } } - tomo.SetTheme(theme) + tomo.SetStyle(styl) + tomo.SetIcons(icons) tomo.Register(1, x.New) return nil } diff --git a/internal/theme/style/aluminum/aluminum.go b/internal/style/aluminum/aluminum.go similarity index 76% rename from internal/theme/style/aluminum/aluminum.go rename to internal/style/aluminum/aluminum.go index 0a7c40d..ae4622d 100644 --- a/internal/theme/style/aluminum/aluminum.go +++ b/internal/style/aluminum/aluminum.go @@ -2,11 +2,11 @@ package aluminumStyle import "image/color" import "git.tebibyte.media/tomo/tomo" -import dataTheme "git.tebibyte.media/tomo/nasin/internal/theme" +import "git.tebibyte.media/tomo/nasin/internal/style" // New returns Aluminum, a futuristic, bluish-white style. -func New () *dataTheme.Theme { - return &dataTheme.Theme { +func New () *style.Style { + return &style.Style { Colors: map[tomo.Color] color.Color { tomo.ColorBackground: colorBackground, tomo.ColorForeground: colorForeground, diff --git a/internal/theme/style/aluminum/style.go b/internal/style/aluminum/style.go similarity index 54% rename from internal/theme/style/aluminum/style.go rename to internal/style/aluminum/style.go index b534e60..17d7569 100644 --- a/internal/theme/style/aluminum/style.go +++ b/internal/style/aluminum/style.go @@ -3,7 +3,7 @@ package aluminumStyle import "image/color" import "git.tebibyte.media/tomo/tomo" import "golang.org/x/image/font/basicfont" -import dataTheme "git.tebibyte.media/tomo/nasin/internal/theme" +import "git.tebibyte.media/tomo/nasin/internal/style" func hex (color uint32) (c color.RGBA) { c.A = uint8(color) @@ -62,66 +62,66 @@ var borderTearPadFocused = border(0x7391c080, 0x7391c080, 0x7391c080, 0x7391c080 var borderInnerShadow = border(0xa4afc0FF, 0xa4afc0FF, 0xa4afc0ff, 0xa4afc0ff, 1, 0, 0, 1) var borderOuterShadow = border(0xa4afc0FF, 0xa4afc0FF, 0xa4afc0ff, 0xa4afc0ff, 0, 1, 1, 0) -var rules = []dataTheme.Rule { +var rules = []style.Rule { // *.*[*] - dataTheme.Rule { - Default: dataTheme.AS ( - dataTheme.AttrFace { Face: basicfont.Face7x13 }, - dataTheme.AttrTextColor { Color: tomo.ColorForeground }, - dataTheme.AttrDotColor { Color: colorDot }, - dataTheme.AttrGap { X: 8, Y: 8 }, + style.Rule { + Default: style.AS ( + style.AttrFace { Face: basicfont.Face7x13 }, + style.AttrTextColor { Color: tomo.ColorForeground }, + style.AttrDotColor { Color: colorDot }, + style.AttrGap { X: 8, Y: 8 }, ), }, // *.Button[*] - dataTheme.Rule { + style.Rule { Role: tomo.R("", "Button", ""), - Default: dataTheme.AS ( - dataTheme.AttrBorder { + Default: style.AS ( + style.AttrBorder { borderEngraved, borderGap, borderLifted, }, - dataTheme.AttrPadding(tomo.I(4, 8)), - dataTheme.AttrColor { Color: tomo.ColorRaised }, + style.AttrPadding(tomo.I(4, 8)), + style.AttrColor { Color: tomo.ColorRaised }, ), - Pressed: dataTheme.AS ( - dataTheme.AttrBorder { + Pressed: style.AS ( + style.AttrBorder { borderEngraved, borderGap, borderInnerShadow, }, - dataTheme.AttrPadding(tomo.I(5, 8, 4, 9)), - dataTheme.AttrColor { Color: colorRaisedPressed }, + style.AttrPadding(tomo.I(5, 8, 4, 9)), + style.AttrColor { Color: colorRaisedPressed }, ), - Focused: dataTheme.AS ( - dataTheme.AttrBorder { + Focused: style.AS ( + style.AttrBorder { borderEngraved, borderGap, borderLiftedFocused, }, - dataTheme.AttrPadding(tomo.I(4, 8)), - dataTheme.AttrColor { Color: colorRaisedFocused }, + style.AttrPadding(tomo.I(4, 8)), + style.AttrColor { Color: colorRaisedFocused }, ), - Hovered: dataTheme.AS ( - dataTheme.AttrColor { Color: colorRaisedHovered }, + Hovered: style.AS ( + style.AttrColor { Color: colorRaisedHovered }, ), }, // *.TextInput[*] - dataTheme.Rule { + style.Rule { Role: tomo.R("", "TextInput", ""), - Default: dataTheme.AS ( - dataTheme.AttrBorder { + Default: style.AS ( + style.AttrBorder { borderEngraved, borderGap, borderInnerShadow, }, - dataTheme.AttrColor { Color: tomo.ColorSunken }, - dataTheme.AttrPadding(tomo.I(5, 4, 4, 5)), + style.AttrColor { Color: tomo.ColorSunken }, + style.AttrPadding(tomo.I(5, 4, 4, 5)), ), - Focused: dataTheme.AS ( - dataTheme.AttrBorder { + Focused: style.AS ( + style.AttrBorder { borderEngraved, borderFocused, borderInnerShadow, @@ -130,206 +130,206 @@ var rules = []dataTheme.Rule { }, // *.TextView[*] - dataTheme.Rule { + style.Rule { Role: tomo.R("", "TextView", ""), - Default: dataTheme.AS ( - dataTheme.AttrBorder { + Default: style.AS ( + style.AttrBorder { borderEngraved, borderGap, borderInnerShadow, }, - dataTheme.AttrColor { Color: tomo.ColorSunken }, - dataTheme.AttrPadding(tomo.I(8)), + style.AttrColor { Color: tomo.ColorSunken }, + style.AttrPadding(tomo.I(8)), ), }, // *.NumberInput[*] - dataTheme.Rule { + style.Rule { Role: tomo.R("", "NumberInput", ""), - Default: dataTheme.AS ( - dataTheme.AttrGap { }, + Default: style.AS ( + style.AttrGap { }, ), }, // *.Container[sunken] - dataTheme.Rule { + style.Rule { Role: tomo.R("", "Container", "sunken"), - Default: dataTheme.AS ( - dataTheme.AttrBorder { + Default: style.AS ( + style.AttrBorder { borderEngraved, borderGap, borderInnerShadow, }, - dataTheme.AttrColor { Color: tomo.ColorSunken }, - dataTheme.AttrPadding(tomo.I(8)), + style.AttrColor { Color: tomo.ColorSunken }, + style.AttrPadding(tomo.I(8)), ), }, // *.Container[outer] - dataTheme.Rule { + style.Rule { Role: tomo.R("", "Container", "outer"), - Default: dataTheme.AS ( - dataTheme.AttrColor { Color: tomo.ColorBackground }, - dataTheme.AttrPadding(tomo.I(8)), + Default: style.AS ( + style.AttrColor { Color: tomo.ColorBackground }, + style.AttrPadding(tomo.I(8)), ), }, // *.Container[menu] - dataTheme.Rule { + style.Rule { Role: tomo.R("", "Container", "menu"), - Default: dataTheme.AS ( - dataTheme.AttrBorder { + Default: style.AS ( + style.AttrBorder { borderGap, borderLifted, }, - dataTheme.AttrColor { Color: tomo.ColorBackground }, - dataTheme.AttrGap { }, + style.AttrColor { Color: tomo.ColorBackground }, + style.AttrGap { }, ), }, // *.Heading[*] - dataTheme.Rule { + style.Rule { Role: tomo.R("", "Heading", ""), - Default: dataTheme.AS ( - dataTheme.AttrAlign { X: tomo.AlignMiddle, Y: tomo.AlignMiddle }, + Default: style.AS ( + style.AttrAlign { X: tomo.AlignMiddle, Y: tomo.AlignMiddle }, ), }, // *.Separator[*] - dataTheme.Rule { + style.Rule { Role: tomo.R("", "Separator", ""), - Default: dataTheme.AS ( - dataTheme.AttrBorder { + Default: style.AS ( + style.AttrBorder { borderEngraved, }, ), }, // *.Slider[*] - dataTheme.Rule { + style.Rule { Role: tomo.R("", "Slider", ""), - Default: dataTheme.AS ( - dataTheme.AttrBorder { + Default: style.AS ( + style.AttrBorder { borderEngraved, borderGap, borderInnerShadow, }, - dataTheme.AttrColor { Color: colorGutter }, + style.AttrColor { Color: colorGutter }, ), - Focused: dataTheme.AS ( - dataTheme.AttrBorder { + Focused: style.AS ( + style.AttrBorder { borderEngraved, borderFocused, borderInnerShadow, }, ), - Hovered: dataTheme.AS ( - dataTheme.AttrColor { Color: colorGutterHovered }, + Hovered: style.AS ( + style.AttrColor { Color: colorGutterHovered }, ), }, // *.Slider[horizontal] - dataTheme.Rule { + style.Rule { Role: tomo.R("", "Slider", "horizontal"), - Default: dataTheme.AS(dataTheme.AttrMinimumSize { X: 48 }), + Default: style.AS(style.AttrMinimumSize { X: 48 }), }, // *.Slider[vertical] - dataTheme.Rule { + style.Rule { Role: tomo.R("", "Slider", "vertical"), - Default: dataTheme.AS(dataTheme.AttrMinimumSize { Y: 48 }), + Default: style.AS(style.AttrMinimumSize { Y: 48 }), }, // *.SliderHandle[*] - dataTheme.Rule { + style.Rule { Role: tomo.R("", "SliderHandle", ""), - Default: dataTheme.AS ( - dataTheme.AttrBorder { + Default: style.AS ( + style.AttrBorder { borderOuterShadow, borderGap, borderLifted, }, - dataTheme.AttrColor { Color: tomo.ColorRaised }, - dataTheme.AttrMinimumSize { X: 12, Y: 12, }, + style.AttrColor { Color: tomo.ColorRaised }, + style.AttrMinimumSize { X: 12, Y: 12, }, ), }, // *.Checkbox[*] - dataTheme.Rule { + style.Rule { Role: tomo.R("", "Checkbox", ""), - Default: dataTheme.AS ( - dataTheme.AttrBorder { + Default: style.AS ( + style.AttrBorder { borderEngraved, borderGap, borderInnerShadow, }, - dataTheme.AttrColor { Color: tomo.ColorSunken }, - dataTheme.AttrPadding(tomo.I(0, 1, 1, 0)), - dataTheme.AttrMinimumSize { X: 19, Y: 19 }, + style.AttrColor { Color: tomo.ColorSunken }, + style.AttrPadding(tomo.I(0, 1, 1, 0)), + style.AttrMinimumSize { X: 19, Y: 19 }, ), - Focused: dataTheme.AS ( - dataTheme.AttrBorder { + Focused: style.AS ( + style.AttrBorder { borderEngraved, borderFocused, borderInnerShadow, }, - dataTheme.AttrPadding(tomo.I(0)), - dataTheme.AttrColor { Color: colorSunkenFocused }, + style.AttrPadding(tomo.I(0)), + style.AttrColor { Color: colorSunkenFocused }, ), }, // *.LabelCheckbox[*] - dataTheme.Rule { + style.Rule { Role: tomo.R("", "LabelCheckbox", ""), - Default: dataTheme.AS ( - dataTheme.AttrGap { X: 8, Y: 8 }, + Default: style.AS ( + style.AttrGap { X: 8, Y: 8 }, ), }, // *.MenuItem[*] - dataTheme.Rule { + style.Rule { Role: tomo.R("", "MenuItem", ""), - Default: dataTheme.AS ( - dataTheme.AttrPadding(tomo.I(4)), - dataTheme.AttrGap { X: 4, Y: 4 }, - dataTheme.AttrColor { Color: color.Transparent }, + Default: style.AS ( + style.AttrPadding(tomo.I(4)), + style.AttrGap { X: 4, Y: 4 }, + style.AttrColor { Color: color.Transparent }, ), - Hovered: dataTheme.AS ( - dataTheme.AttrColor { Color: colorDot }, + Hovered: style.AS ( + style.AttrColor { Color: colorDot }, ), - Focused: dataTheme.AS ( - dataTheme.AttrColor { Color: colorDot }, + Focused: style.AS ( + style.AttrColor { Color: colorDot }, ), }, // *.File[*] - dataTheme.Rule { + style.Rule { Role: tomo.R("", "File", ""), - Default: dataTheme.AS ( - dataTheme.AttrColor { Color: color.Transparent }, + Default: style.AS ( + style.AttrColor { Color: color.Transparent }, ), - Focused: dataTheme.AS ( - dataTheme.AttrColor { Color: colorDot }, + Focused: style.AS ( + style.AttrColor { Color: colorDot }, ), }, // *.TearLine[*] - dataTheme.Rule { + style.Rule { Role: tomo.R("", "TearLine", ""), - Default: dataTheme.AS ( - dataTheme.AttrBorder { + Default: style.AS ( + style.AttrBorder { borderTearPad, borderTear, }, ), - Hovered: dataTheme.AS ( - dataTheme.AttrBorder { + Hovered: style.AS ( + style.AttrBorder { borderTearPadFocused, borderTearFocused, }, ), - Focused: dataTheme.AS ( - dataTheme.AttrBorder { + Focused: style.AS ( + style.AttrBorder { borderTearPadFocused, borderTearFocused, }, diff --git a/internal/theme/attribute.go b/internal/style/attribute.go similarity index 99% rename from internal/theme/attribute.go rename to internal/style/attribute.go index 6d2738f..d14c030 100644 --- a/internal/theme/attribute.go +++ b/internal/style/attribute.go @@ -1,4 +1,4 @@ -package theme +package style import "image" import "image/color" diff --git a/internal/theme/style/fallback/style.go b/internal/style/fallback/style.go similarity index 55% rename from internal/theme/style/fallback/style.go rename to internal/style/fallback/style.go index 5193475..4537fbe 100644 --- a/internal/theme/style/fallback/style.go +++ b/internal/style/fallback/style.go @@ -3,7 +3,7 @@ package fallbackStyle import "image/color" import "git.tebibyte.media/tomo/tomo" import "golang.org/x/image/font/basicfont" -import dataTheme "git.tebibyte.media/tomo/nasin/internal/theme" +import "git.tebibyte.media/tomo/nasin/internal/style" var colorFocus = color.RGBA { R: 61, G: 128, B: 143, A: 255 } var colorInput = color.RGBA { R: 208, G: 203, B: 150, A: 255 } @@ -32,70 +32,70 @@ var borderColorLifted = [4]color.Color { colorHighlight, colorShadow, col var borderColorInput = [4]color.Color { colorInputShadow, colorInput, colorInput, colorInputShadow } var borderColorFocused = [4]color.Color { colorFocus, colorFocus, colorFocus, colorFocus } -var rules = []dataTheme.Rule { +var rules = []style.Rule { // *.*[*] - dataTheme.Rule { - Default: dataTheme.AS ( - dataTheme.AttrFace { Face: basicfont.Face7x13 }, - dataTheme.AttrTextColor { Color: tomo.ColorForeground }, - dataTheme.AttrDotColor { Color: tomo.ColorAccent }, - dataTheme.AttrGap { X: 8, Y: 8 }, + style.Rule { + Default: style.AS ( + style.AttrFace { Face: basicfont.Face7x13 }, + style.AttrTextColor { Color: tomo.ColorForeground }, + style.AttrDotColor { Color: tomo.ColorAccent }, + style.AttrGap { X: 8, Y: 8 }, ), }, // *.Button[*] - dataTheme.Rule { + style.Rule { Role: tomo.R("", "Button", ""), - Default: dataTheme.AS ( - dataTheme.AttrBorder { + Default: style.AS ( + style.AttrBorder { outline, tomo.Border { Width: tomo.I(1), Color: borderColorLifted, }, }, - dataTheme.AttrPadding(tomo.I(4, 8)), - dataTheme.AttrColor { Color: tomo.ColorRaised }, + style.AttrPadding(tomo.I(4, 8)), + style.AttrColor { Color: tomo.ColorRaised }, ), - Pressed: dataTheme.AS ( - dataTheme.AttrBorder { + Pressed: style.AS ( + style.AttrBorder { outline, tomo.Border { Width: tomo.I(1, 0, 0, 1), Color: borderColorEngraved, }, }, - dataTheme.AttrPadding(tomo.I(5, 8, 4, 9)), - dataTheme.AttrColor { Color: colorCarvedPressed }, + style.AttrPadding(tomo.I(5, 8, 4, 9)), + style.AttrColor { Color: colorCarvedPressed }, ), - Focused: dataTheme.AS ( - dataTheme.AttrBorder { + Focused: style.AS ( + style.AttrBorder { outline, tomo.Border { Width: tomo.I(1), Color: borderColorFocused, }, }, - dataTheme.AttrPadding(tomo.I(4, 8)), + style.AttrPadding(tomo.I(4, 8)), ), }, // *.TextInput[*] - dataTheme.Rule { + style.Rule { Role: tomo.R("", "TextInput", ""), - Default: dataTheme.AS ( - dataTheme.AttrBorder { + Default: style.AS ( + style.AttrBorder { outline, tomo.Border { Width: tomo.I(1), Color: borderColorInput, }, }, - dataTheme.AttrColor { Color: colorInput }, - dataTheme.AttrPadding(tomo.I(5, 4, 4, 5)), + style.AttrColor { Color: colorInput }, + style.AttrPadding(tomo.I(5, 4, 4, 5)), ), - Focused: dataTheme.AS ( - dataTheme.AttrBorder { + Focused: style.AS ( + style.AttrBorder { outline, tomo.Border { Width: tomo.I(1), @@ -106,83 +106,83 @@ var rules = []dataTheme.Rule { }, // *.TextView[*] - dataTheme.Rule { + style.Rule { Role: tomo.R("", "TextView", ""), - Default: dataTheme.AS ( - dataTheme.AttrBorder { + Default: style.AS ( + style.AttrBorder { outline, tomo.Border { Width: tomo.I(1, 0, 0, 1), Color: borderColorEngraved, }, }, - dataTheme.AttrColor { Color: tomo.ColorSunken }, - dataTheme.AttrPadding(tomo.I(8)), + style.AttrColor { Color: tomo.ColorSunken }, + style.AttrPadding(tomo.I(8)), ), }, // *.NumberInput[*] - dataTheme.Rule { + style.Rule { Role: tomo.R("", "NumberInput", ""), - Default: dataTheme.AS ( - dataTheme.AttrGap { }, + Default: style.AS ( + style.AttrGap { }, ), }, // *.Container[sunken] - dataTheme.Rule { + style.Rule { Role: tomo.R("", "Container", "sunken"), - Default: dataTheme.AS ( - dataTheme.AttrBorder { + Default: style.AS ( + style.AttrBorder { outline, tomo.Border { Width: tomo.I(1, 0, 0, 1), Color: borderColorEngraved, }, }, - dataTheme.AttrColor { Color: tomo.ColorSunken }, - dataTheme.AttrPadding(tomo.I(8)), + style.AttrColor { Color: tomo.ColorSunken }, + style.AttrPadding(tomo.I(8)), ), }, // *.Container[outer] - dataTheme.Rule { + style.Rule { Role: tomo.R("", "Container", "outer"), - Default: dataTheme.AS ( - dataTheme.AttrColor { Color: tomo.ColorBackground }, - dataTheme.AttrPadding(tomo.I(8)), + Default: style.AS ( + style.AttrColor { Color: tomo.ColorBackground }, + style.AttrPadding(tomo.I(8)), ), }, // *.Container[menu] - dataTheme.Rule { + style.Rule { Role: tomo.R("", "Container", "menu"), - Default: dataTheme.AS ( - dataTheme.AttrBorder { + Default: style.AS ( + style.AttrBorder { outline, tomo.Border { Width: tomo.I(1), Color: borderColorLifted, }, }, - dataTheme.AttrColor { Color: tomo.ColorBackground }, - dataTheme.AttrGap { }, + style.AttrColor { Color: tomo.ColorBackground }, + style.AttrGap { }, ), }, // *.Heading[*] - dataTheme.Rule { + style.Rule { Role: tomo.R("", "Heading", ""), - Default: dataTheme.AS ( - dataTheme.AttrAlign { X: tomo.AlignMiddle, Y: tomo.AlignMiddle }, + Default: style.AS ( + style.AttrAlign { X: tomo.AlignMiddle, Y: tomo.AlignMiddle }, ), }, // *.Separator[*] - dataTheme.Rule { + style.Rule { Role: tomo.R("", "Separator", ""), - Default: dataTheme.AS ( - dataTheme.AttrBorder { + Default: style.AS ( + style.AttrBorder { tomo.Border { Width: tomo.I(1), Color: borderColorEngraved, @@ -192,126 +192,126 @@ var rules = []dataTheme.Rule { }, // *.Slider[*] - dataTheme.Rule { + style.Rule { Role: tomo.R("", "Slider", ""), - Default: dataTheme.AS ( - dataTheme.AttrBorder { + Default: style.AS ( + style.AttrBorder { outline, tomo.Border { Width: tomo.I(1, 0, 0, 1), Color: borderColorEngraved, }, }, - dataTheme.AttrColor { Color: colorGutter }, - dataTheme.AttrPadding(tomo.I(0, 1, 1, 0)), + style.AttrColor { Color: colorGutter }, + style.AttrPadding(tomo.I(0, 1, 1, 0)), ), - Focused: dataTheme.AS ( - dataTheme.AttrBorder { + Focused: style.AS ( + style.AttrBorder { outline, tomo.Border { Width: tomo.I(1), Color: borderColorFocused, }, }, - dataTheme.AttrPadding(tomo.I(0)), + style.AttrPadding(tomo.I(0)), ), }, // *.Slider[horizontal] - dataTheme.Rule { + style.Rule { Role: tomo.R("", "Slider", "horizontal"), - Default: dataTheme.AS(dataTheme.AttrMinimumSize { X: 48 }), + Default: style.AS(style.AttrMinimumSize { X: 48 }), }, // *.Slider[vertical] - dataTheme.Rule { + style.Rule { Role: tomo.R("", "Slider", "vertical"), - Default: dataTheme.AS(dataTheme.AttrMinimumSize { Y: 48 }), + Default: style.AS(style.AttrMinimumSize { Y: 48 }), }, // *.SliderHandle[*] - dataTheme.Rule { + style.Rule { Role: tomo.R("", "SliderHandle", ""), - Default: dataTheme.AS ( - dataTheme.AttrBorder { + Default: style.AS ( + style.AttrBorder { outline, tomo.Border { Width: tomo.I(1), Color: borderColorLifted, }, }, - dataTheme.AttrColor { Color: tomo.ColorRaised }, - dataTheme.AttrMinimumSize { X: 12, Y: 12, }, + style.AttrColor { Color: tomo.ColorRaised }, + style.AttrMinimumSize { X: 12, Y: 12, }, ), }, // *.Checkbox[*] - dataTheme.Rule { + style.Rule { Role: tomo.R("", "Checkbox", ""), - Default: dataTheme.AS ( - dataTheme.AttrBorder { + Default: style.AS ( + style.AttrBorder { outline, tomo.Border { Width: tomo.I(1, 0, 0, 1), Color: borderColorEngraved, }, }, - dataTheme.AttrColor { Color: tomo.ColorSunken }, - dataTheme.AttrPadding(tomo.I(0, 1, 1, 0)), - dataTheme.AttrMinimumSize { X: 19, Y: 19 }, + style.AttrColor { Color: tomo.ColorSunken }, + style.AttrPadding(tomo.I(0, 1, 1, 0)), + style.AttrMinimumSize { X: 19, Y: 19 }, ), - Focused: dataTheme.AS ( - dataTheme.AttrBorder { + Focused: style.AS ( + style.AttrBorder { outline, tomo.Border { Width: tomo.I(1), Color: borderColorFocused, }, }, - dataTheme.AttrPadding(tomo.I(0)), + style.AttrPadding(tomo.I(0)), ), }, // *.LabelCheckbox[*] - dataTheme.Rule { + style.Rule { Role: tomo.R("", "LabelCheckbox", ""), - Default: dataTheme.AS ( - dataTheme.AttrGap { X: 8, Y: 8 }, + Default: style.AS ( + style.AttrGap { X: 8, Y: 8 }, ), }, // *.MenuItem[*] - dataTheme.Rule { + style.Rule { Role: tomo.R("", "MenuItem", ""), - Default: dataTheme.AS ( - dataTheme.AttrPadding(tomo.I(4)), - dataTheme.AttrGap { X: 4, Y: 4 }, - dataTheme.AttrColor { Color: color.Transparent }, + Default: style.AS ( + style.AttrPadding(tomo.I(4)), + style.AttrGap { X: 4, Y: 4 }, + style.AttrColor { Color: color.Transparent }, ), - Hovered: dataTheme.AS ( - dataTheme.AttrColor { Color: tomo.ColorAccent }, + Hovered: style.AS ( + style.AttrColor { Color: tomo.ColorAccent }, ), - Focused: dataTheme.AS ( - dataTheme.AttrColor { Color: tomo.ColorAccent }, + Focused: style.AS ( + style.AttrColor { Color: tomo.ColorAccent }, ), }, // *.File[*] - dataTheme.Rule { + style.Rule { Role: tomo.R("", "File", ""), - Default: dataTheme.AS ( - dataTheme.AttrColor { Color: color.Transparent }, + Default: style.AS ( + style.AttrColor { Color: color.Transparent }, ), - Focused: dataTheme.AS ( - dataTheme.AttrColor { Color: tomo.ColorAccent }, + Focused: style.AS ( + style.AttrColor { Color: tomo.ColorAccent }, ), }, // *.TearLine[*] - dataTheme.Rule { + style.Rule { Role: tomo.R("", "TearLine", ""), - Default: dataTheme.AS ( - dataTheme.AttrBorder { + Default: style.AS ( + style.AttrBorder { tomo.Border { Width: tomo.I(3), Color: [4]color.Color { @@ -322,19 +322,19 @@ var rules = []dataTheme.Rule { }, }, }, - dataTheme.AttrColor { Color: tomo.ColorForeground }, - dataTheme.AttrPadding(tomo.I(1, 0, 0, 1)), + style.AttrColor { Color: tomo.ColorForeground }, + style.AttrPadding(tomo.I(1, 0, 0, 1)), ), - Hovered: dataTheme.AS ( - dataTheme.AttrBorder { + Hovered: style.AS ( + style.AttrBorder { tomo.Border { Width: tomo.I(3), Color: borderColorFocused, }, }, ), - Focused: dataTheme.AS ( - dataTheme.AttrBorder { + Focused: style.AS ( + style.AttrBorder { tomo.Border { Width: tomo.I(3), Color: borderColorFocused, diff --git a/internal/theme/style/fallback/wintergreen.go b/internal/style/fallback/wintergreen.go similarity index 60% rename from internal/theme/style/fallback/wintergreen.go rename to internal/style/fallback/wintergreen.go index 604147f..229501d 100644 --- a/internal/theme/style/fallback/wintergreen.go +++ b/internal/style/fallback/wintergreen.go @@ -2,12 +2,12 @@ package fallbackStyle import "image/color" import "git.tebibyte.media/tomo/tomo" -import dataTheme "git.tebibyte.media/tomo/nasin/internal/theme" +import "git.tebibyte.media/tomo/nasin/internal/style" -// New returns Wintergreen, the default Tomo tomo. It is neutral-gray with green -// and turquoise accents. -func New () *dataTheme.Theme { - return &dataTheme.Theme { +// New returns Wintergreen, the default Tomo style. It is neutral-gray with +// green and turquoise accents. +func New () *style.Style { + return &style.Style { Colors: map[tomo.Color] color.Color { tomo.ColorBackground: colorBackground, tomo.ColorForeground: colorForeground, diff --git a/internal/theme/missing.go b/internal/style/missing.go similarity index 97% rename from internal/theme/missing.go rename to internal/style/missing.go index 641a7ce..5d7b9f6 100644 --- a/internal/theme/missing.go +++ b/internal/style/missing.go @@ -1,4 +1,4 @@ -package theme +package style import "image" import "image/color" diff --git a/internal/theme/theme.go b/internal/style/style.go similarity index 78% rename from internal/theme/theme.go rename to internal/style/style.go index 4faf2f2..001731b 100644 --- a/internal/theme/theme.go +++ b/internal/style/style.go @@ -1,18 +1,17 @@ -// Package theme provides a data-driven theme implementation. -package theme +// Package style provides a data-driven style implementation. +package style import "image" import "image/color" import "git.tebibyte.media/tomo/tomo" -import "git.tebibyte.media/tomo/tomo/data" import "git.tebibyte.media/tomo/tomo/event" import "git.tebibyte.media/tomo/tomo/input" import "git.tebibyte.media/tomo/tomo/canvas" // this is CSS's bastard child -// Theme allows the use of data to define a visual style. -type Theme struct { +// Style allows the use of data to define a visual style. +type Style struct { // Textures maps texture names to image textures. Textures map[string] image.Image textures map[string] canvas.TextureCloser // private texture cache @@ -23,18 +22,6 @@ type Theme struct { // Colors maps tomo.Color values to color.RGBA values. Colors map[tomo.Color] color.Color - - // This type does not handle icons, and as such, a special icon theme - // must be separately specified. - IconTheme -} - -// IconTheme implements the part of tomo.Theme that handles icons. -type IconTheme interface { - // Icon returns a texture of the corresponding icon ID. - Icon (tomo.Icon, tomo.IconSize) canvas.Texture - // MimeIcon returns an icon corresponding to a MIME type. - MimeIcon (data.Mime, tomo.IconSize) canvas.Texture } // Rule describes under what circumstances should certain style attributes be @@ -96,7 +83,7 @@ func (this *AttrSet) ensure () { if this.set == nil { this.set = make(map[int] Attr) } } -func (this *Theme) execute (object tomo.Object, set AttrSet) { +func (this *Style) execute (object tomo.Object, set AttrSet) { box := object.GetBox() for _, attr := range set.set { @@ -137,7 +124,7 @@ func (this *Theme) execute (object tomo.Object, set AttrSet) { } } -func (this *Theme) texture (name string) canvas.Texture { +func (this *Style) texture (name string) canvas.Texture { this.ensureTextureCache() if texture, ok := this.textures[name]; ok { return texture @@ -152,19 +139,19 @@ func (this *Theme) texture (name string) canvas.Texture { return this.missingTexture() } -func (this *Theme) missingTexture () canvas.Texture { +func (this *Style) missingTexture () canvas.Texture { if this.missing == nil { this.missing = tomo.NewTexture(missingTexture(16)) } return this.missing } -func (this *Theme) ensureTextureCache () { +func (this *Style) ensureTextureCache () { if this.textures == nil { this.textures = make(map[string] canvas.TextureCloser) } } // setsFor builds flattened attr sets for a specific role based on the rules list -func (this *Theme) setsFor (role tomo.Role) (defaul, hovered, pressed, focused AttrSet) { +func (this *Style) setsFor (role tomo.Role) (defaul, hovered, pressed, focused AttrSet) { for _, current := range this.Rules { // check for a match packageMatch := current.Role.Package == role.Package || current.Role.Package == "" @@ -186,7 +173,7 @@ func (this *Theme) setsFor (role tomo.Role) (defaul, hovered, pressed, focused A return defaul, hovered, pressed, focused } -func (this *Theme) Apply (object tomo.Object) event.Cookie { +func (this *Style) Apply (object tomo.Object) event.Cookie { pressed := false hovered := false box := object.GetBox() @@ -232,32 +219,16 @@ func (this *Theme) Apply (object tomo.Object) event.Cookie { } -func (this *Theme) RGBA (c tomo.Color) (r, g, b, a uint32) { +func (this *Style) RGBA (c tomo.Color) (r, g, b, a uint32) { if this.Colors == nil { return 0xFFFF, 0, 0xFFFF, 0xFFFF } color, ok := this.Colors[c] if !ok { return 0xFFFF, 0, 0xFFFF, 0xFFFF } return color.RGBA() } -func (this *Theme) Icon (icon tomo.Icon, size tomo.IconSize) canvas.Texture { - if this.IconTheme == nil { - return this.missingTexture() - } else { - return this.IconTheme.Icon(icon, size) - } -} - -func (this *Theme) MimeIcon (mime data.Mime, size tomo.IconSize) canvas.Texture { - if this.IconTheme == nil { - return this.missingTexture() - } else { - return this.IconTheme.MimeIcon(mime, size) - } -} - -// Close closes all cached textures this theme has open. Do not call this while -// the theme is in use. -func (this *Theme) Close () error { +// Close closes all cached textures this style has open. Do not call this while +// the style is in use. +func (this *Style) Close () error { this.missing.Close() this.missing = nil for _, texture := range this.textures {