diff --git a/backends/x/window.go b/backends/x/window.go index d51d948..5509bf2 100644 --- a/backends/x/window.go +++ b/backends/x/window.go @@ -8,6 +8,8 @@ import "github.com/jezek/xgbutil/xevent" import "github.com/jezek/xgbutil/xwindow" import "github.com/jezek/xgbutil/xgraphics" import "git.tebibyte.media/sashakoshka/tomo/input" +import "git.tebibyte.media/sashakoshka/tomo/theme" +import "git.tebibyte.media/sashakoshka/tomo/config" import "git.tebibyte.media/sashakoshka/tomo/canvas" import "git.tebibyte.media/sashakoshka/tomo/elements" @@ -20,6 +22,9 @@ type Window struct { onClose func () skipChildDrawCallback bool + theme theme.Theme + config config.Config + metrics struct { width int height int @@ -69,6 +74,9 @@ func (backend *Backend) NewWindow ( Connect(backend.connection, window.xWindow.Id) xevent.MotionNotifyFun(window.handleMotionNotify). Connect(backend.connection, window.xWindow.Id) + + window.SetTheme(backend.theme) + window.SetConfig(backend.config) window.metrics.width = width window.metrics.height = height @@ -100,6 +108,12 @@ func (window *Window) Adopt (child elements.Element) { // adopt new child window.child = child + if newChild, ok := child.(elements.Themeable); ok { + newChild.SetTheme(window.theme) + } + if newChild, ok := child.(elements.Configurable); ok { + newChild.SetConfig(window.config) + } if newChild, ok := child.(elements.Flexible); ok { newChild.OnFlexibleHeightChange(window.resizeChildToFit) } @@ -196,6 +210,20 @@ func (window *Window) OnClose (callback func ()) { window.onClose = callback } +func (window *Window) SetTheme (theme theme.Theme) { + window.theme = theme + if child, ok := window.child.(elements.Themeable); ok { + child.SetTheme(theme) + } +} + +func (window *Window) SetConfig (config config.Config) { + window.config = config + if child, ok := window.child.(elements.Configurable); ok { + child.SetConfig(config) + } +} + func (window *Window) reallocateCanvas () { window.canvas.Reallocate(window.metrics.width, window.metrics.height) diff --git a/backends/x/x.go b/backends/x/x.go index c7a514b..d3c08f5 100644 --- a/backends/x/x.go +++ b/backends/x/x.go @@ -2,6 +2,8 @@ package x import "git.tebibyte.media/sashakoshka/tomo" import "git.tebibyte.media/sashakoshka/tomo/data" +import "git.tebibyte.media/sashakoshka/tomo/theme" +import "git.tebibyte.media/sashakoshka/tomo/config" import "github.com/jezek/xgbutil" import "github.com/jezek/xgb/xproto" @@ -25,6 +27,9 @@ type Backend struct { hyper uint16 } + theme theme.Theme + config config.Config + windows map[xproto.Window] *Window } @@ -95,6 +100,25 @@ func (backend *Backend) Paste (accept []data.Mime) (data data.Data) { return } + +// SetTheme sets the theme of all open windows. +func (backend *Backend) SetTheme (theme theme.Theme) { + backend.assert() + backend.theme = theme + for _, window := range backend.windows { + window.SetTheme(theme) + } +} + +// SetConfig sets the configuration of all open windows. +func (backend *Backend) SetConfig (config config.Config) { + backend.assert() + backend.config = config + for _, window := range backend.windows { + window.SetConfig(config) + } +} + func (backend *Backend) assert () { if backend == nil { panic("nil backend") } } diff --git a/elements/element.go b/elements/element.go index 30022ee..8aaa63f 100644 --- a/elements/element.go +++ b/elements/element.go @@ -164,6 +164,8 @@ type Scrollable interface { // Themeable represents an element that can modify its appearance to fit within // a theme. type Themeable interface { + Element + // SetTheme sets the element's theme to something fulfilling the // theme.Theme interface. SetTheme (theme.Theme) @@ -172,6 +174,8 @@ type Themeable interface { // Configurable represents an element that can modify its behavior to fit within // a set of configuration parameters. type Configurable interface { + Element + // SetConfig sets the element's configuration to something fulfilling // the config.Config interface. SetConfig (config.Config)