package ui import ( "opslag.de/schobers/geom" "opslag.de/schobers/zntg" ) var _ Control = &Overlays{} type OverlayVisibilityChangedArgs struct { Name string Visible bool } type Overlays struct { Proxy overlays map[string]Overlay order []string visible map[string]bool overlayHidden zntg.Events overlayShown zntg.Events visibilityChanged zntg.Events } func NewOverlays(over Control) *Overlays { return &Overlays{ Proxy: Proxy{Content: over}, overlays: map[string]Overlay{}, visible: map[string]bool{}, } } func (o *Overlays) setVisibility(name string, visible bool) { if o.visible[name] == visible { return } o.visible[name] = visible overlay, ok := o.overlays[name].(Overlay) if ok { if visible { overlay.Shown() } else { overlay.Hidden() } } o.visibilityChanged.Notify(OverlayVisibilityChangedArgs{Name: name, Visible: visible}) if visible { o.overlayShown.Notify(name) } else { o.overlayHidden.Notify(name) } } func (o *Overlays) AddOnTop(name string, overlay Overlay, visible bool) { o.order = append(o.order, name) o.overlays[name] = overlay o.visible[name] = false if visible { o.Show(name) } } func (o *Overlays) AddOnBottom(name string, overlay Overlay, visible bool) { o.order = append([]string{name}, o.order...) o.overlays[name] = overlay 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) bool { var handled bool for _, overlay := range o.order { if o.visible[overlay] { if o.overlays[overlay].Handle(ctx, e) { // handle all overlays regardless of return value handled = true } } } if handled { return true } return o.Proxy.Handle(ctx, e) } func (o *Overlays) Hide(name string) { o.SetVisibility(name, false) } func (o *Overlays) Render(ctx Context) { o.Proxy.Render(ctx) for _, overlay := range o.order { if o.visible[overlay] { o.overlays[overlay].Render(ctx) } } } func (o *Overlays) SetVisibility(name string, visible bool) { o.setVisibility(name, visible) } func (o *Overlays) Show(name string) { o.SetVisibility(name, true) } func (o *Overlays) Toggle(name string) { o.SetVisibility(name, !o.visible[name]) }