package x import "image" import "git.tebibyte.media/tomo/tomo" import "git.tebibyte.media/tomo/x/canvas" import "git.tebibyte.media/tomo/tomo/canvas" type boxSet map[anyBox] struct { } func (set boxSet) Empty () bool { return set == nil || len(set) == 0 } func (set boxSet) Has (box anyBox) bool { if set == nil { return false } _, ok := set[box] return ok } func (set *boxSet) Add (box anyBox) { if *set == nil { *set = make(boxSet) } (*set)[box] = struct { } { } } func (set *boxSet) Pop () anyBox { for box := range *set { delete(*set, box) return box } return nil } type parent interface { window () *window canvas () canvas.Canvas } type anyBox interface { tomo.Box doDraw () doLayout () setParent (parent) recursiveRedo () } func (window *window) SetRoot (root tomo.Object) { box := root.Box().(anyBox) window.root.setParent(nil) box.setParent(window) window.invalidateLayout(box) window.root = box } func (window *window) window () *window { return window } func (window *window) canvas () canvas.Canvas { return window.xCanvas } func (window *window) invalidateDraw (box anyBox) { window.needDraw.Add(box) } func (window *window) invalidateLayout (box anyBox) { window.needLayout.Add(box) window.invalidateDraw(box) } func (window *window) focus (box anyBox) { if window.focused == box { return } window.invalidateDraw(window.focused) window.focused = box window.invalidateDraw(box) } func (window *window) afterEvent () { if window.needRedo { if window.root != nil { window.root.recursiveRedo() } window.xCanvas.Push(window.xWindow.Id) return } for len(window.needLayout) > 0 { window.needLayout.Pop().doLayout() } var toPush image.Rectangle for len(window.needDraw) > 0 { box := window.needDraw.Pop() box.doDraw() toPush = toPush.Union(box.Bounds()) } window.xCanvas.Clip(toPush).(xcanvas.Canvas).Push(window.xWindow.Id) }