package ui import "opslag.de/schobers/geom" type StackPanel struct { ContainerBase Orientation Orientation } func BuildStackPanel(o Orientation, fn func(*StackPanel)) *StackPanel { var p = &StackPanel{Orientation: o} if fn != nil { fn(p) } return p } func (p *StackPanel) Arrange(ctx Context, bounds geom.RectangleF32, offset geom.PointF32) { bounds = p.Orientation.FlipRect(bounds) var length float32 var stretch int var desired = make([]geom.PointF32, len(p.Children)) for i, child := range p.Children { var size = p.Orientation.FlipPt(child.DesiredSize(ctx)) if geom.IsNaN32(size.Y) { stretch++ } else { length += size.Y } desired[i] = size } var remainder = bounds.Dy() - length var childOffset float32 for i, size := range desired { var height = size.Y if geom.IsNaN32(size.Y) { if remainder < 0 { height = 0 } else { height = remainder / float32(stretch) } } var child = geom.RectF32(bounds.Min.X, bounds.Min.Y+childOffset, bounds.Max.X, bounds.Min.Y+childOffset+height) p.Children[i].Arrange(ctx, p.Orientation.FlipRect(child), offset) childOffset += height } p.ControlBase.Arrange(ctx, p.Orientation.FlipRect(bounds), offset) } func (p *StackPanel) DesiredSize(ctx Context) geom.PointF32 { var length float32 var width float32 for _, child := range p.Children { var size = child.DesiredSize(ctx) var l, w = p.Orientation.LengthParallel(size), p.Orientation.LengthPerpendicular(size) if geom.IsNaN32(l) { length = l } else { if !geom.IsNaN32(length) { length += l } } if geom.IsNaN32(w) { width = w } else { if !geom.IsNaN32(width) { width = geom.Max32(width, w) } } } return p.Orientation.Pt(length, width) } func (p *StackPanel) Render(ctx Context) { p.RenderBackground(ctx) var bounds = p.Bounds() for _, child := range p.Children { var childB = child.Bounds() if childB.Min.X >= bounds.Max.X || childB.Min.Y >= bounds.Max.Y || childB.Max.X < bounds.Min.X || childB.Max.Y < bounds.Min.Y { continue } child.Render(ctx) } }