100 lines
2.2 KiB
Go
100 lines
2.2 KiB
Go
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
|
|
}
|
|
|
|
func (s *StackPanel) Handle(e allg5.Event) {
|
|
s.Container.Handle(e)
|
|
}
|
|
|
|
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())
|
|
}
|
|
}
|