diff --git a/ui/context.go b/ui/context.go index 2282b52..a4a41ee 100644 --- a/ui/context.go +++ b/ui/context.go @@ -4,6 +4,7 @@ type Context interface { Animate() Fonts() *Fonts HasQuit() bool + Overlays() *Overlays Quit() Renderer() Renderer Style() *Style @@ -18,6 +19,7 @@ type context struct { quit chan struct{} renderer Renderer view Control + overlays *Overlays fonts *Fonts textures *Textures style *Style @@ -29,6 +31,7 @@ func newContext(r Renderer, s *Style, view Control) *context { renderer: r, style: s, view: view, + overlays: NewOverlays(view), fonts: NewFonts(r), textures: NewTextures(r)} } @@ -51,6 +54,8 @@ func (c *context) HasQuit() bool { } } +func (c *context) Overlays() *Overlays { return c.overlays } + func (c *context) Renderer() Renderer { return c.renderer } func (c *context) Style() *Style { return c.style } @@ -71,5 +76,5 @@ func (c *context) Handle(e Event) { c.Quit() return } - c.view.Handle(c, e) + c.overlays.Handle(c, e) } diff --git a/ui/overlays.go b/ui/overlays.go new file mode 100644 index 0000000..e292328 --- /dev/null +++ b/ui/overlays.go @@ -0,0 +1,71 @@ +package ui + +import "opslag.de/schobers/geom" + +var _ Control = &Overlays{} + +type Overlays struct { + Proxy + + overlays map[string]Control + order []string + visible map[string]bool +} + +func NewOverlays(over Control) *Overlays { + return &Overlays{ + Proxy: Proxy{Content: over}, + + overlays: map[string]Control{}, + visible: map[string]bool{}, + } +} + +func (o *Overlays) AddOnTop(name string, control Control, visible bool) { + o.order = append(o.order, name) + o.overlays[name] = control + o.visible[name] = visible +} + +func (o *Overlays) AddOnBottom(name string, control Control, visible bool) { + o.order = append([]string{name}, o.order...) + o.overlays[name] = control + o.visible[name] = visible +} + +func (o *Overlays) Arrange(ctx Context, bounds geom.RectangleF32, offset geom.PointF32, parent Control) { + o.Proxy.Arrange(ctx, bounds, offset, parent) + for _, overlay := range o.overlays { + overlay.Arrange(ctx, bounds, offset, parent) + } +} + +func (o *Overlays) Handle(ctx Context, e Event) { + for overlay, visible := range o.visible { + if visible { + o.overlays[overlay].Handle(ctx, e) + } + } + o.Proxy.Handle(ctx, e) +} + +func (o *Overlays) Hide(name string) { + o.visible[name] = false +} + +func (o *Overlays) Render(ctx Context) { + o.Proxy.Render(ctx) + for overlay, visible := range o.visible { + if visible { + o.overlays[overlay].Render(ctx) + } + } +} + +func (o *Overlays) Show(name string) { + o.visible[name] = true +} + +func (o *Overlays) Toggle(name string) { + o.visible[name] = !o.visible[name] +} diff --git a/ui/ui.go b/ui/ui.go index 42039f7..6a8a103 100644 --- a/ui/ui.go +++ b/ui/ui.go @@ -39,12 +39,13 @@ func RunWait(r Renderer, s *Style, view Control, wait bool) error { }() defer anim.Stop() + overlays := ctx.Overlays() ctx.Renderer().Refresh() for !ctx.HasQuit() { var size = r.Size() var bounds = geom.RectF32(0, 0, size.X, size.Y) - view.Arrange(ctx, bounds, geom.ZeroPtF32, nil) - view.Render(ctx) + overlays.Arrange(ctx, bounds, geom.ZeroPtF32, nil) + overlays.Render(ctx) if ctx.HasQuit() { return nil }