allg5/alui/stackpanel.go

100 lines
2.2 KiB
Go
Raw Normal View History

2020-03-08 09:10:41 +00:00
package alui
import (
"opslag.de/schobers/allg5"
"opslag.de/schobers/geom"
)
var _ Control = &StackPanel{}
type StackPanel struct {
Container
Orientation Orientation
}
func (s *StackPanel) asLength(p geom.PointF32) float32 {
switch s.Orientation {
case OrientationHorizontal:
return p.X
default:
return p.Y
}
}
func (s *StackPanel) asWidth(p geom.PointF32) float32 {
switch s.Orientation {
case OrientationHorizontal:
return p.Y
default:
return p.X
}
}
func (s *StackPanel) asSize(length, width float32) geom.PointF32 {
switch s.Orientation {
case OrientationHorizontal:
return geom.PtF32(length, width)
default:
return geom.PtF32(width, length)
}
}
func (s *StackPanel) CalculateLayout(ctx *Context) ([]geom.PointF32, geom.PointF32) {
desired := make([]geom.PointF32, len(s.Children))
for i, child := range s.Children {
desired[i] = child.DesiredSize(ctx)
}
var length, width float32
for _, size := range desired {
w, l := s.asWidth(size), s.asLength(size)
if geom.IsNaN32(w) {
width = geom.NaN32()
} else if !geom.IsNaN32(width) {
width = geom.Max32(width, w)
}
if geom.IsNaN32(l) {
panic("not implemented")
}
length += l
}
switch s.Orientation {
case OrientationHorizontal:
return desired, geom.PtF32(length, width)
default:
return desired, geom.PtF32(width, length)
}
}
func (s *StackPanel) DesiredSize(ctx *Context) geom.PointF32 {
_, size := s.CalculateLayout(ctx)
return size
}
2020-04-10 09:00:27 +00:00
func (s *StackPanel) Handle(ctx *Context, e allg5.Event) {
s.Container.Handle(ctx, e)
2020-03-08 09:10:41 +00:00
}
func (s *StackPanel) Layout(ctx *Context, bounds geom.RectangleF32) {
s.Container.Layout(ctx, bounds)
desired, _ := s.CalculateLayout(ctx)
width := s.asWidth(bounds.Size())
var offset = bounds.Min
for i, child := range s.Children {
length := s.asLength(desired[i])
childSize := s.asSize(length, width)
var bottomRight = offset.Add(childSize)
var childBounds = geom.RectF32(offset.X, offset.Y, bottomRight.X, bottomRight.Y)
child.Layout(ctx, childBounds)
offset = offset.Add(s.asSize(length, 0))
}
}
func (s *StackPanel) Render(ctx *Context, bounds geom.RectangleF32) {
for _, child := range s.Children {
child.Render(ctx, child.Bounds())
}
}