From e2d0b3cfca8675d68b077fe76cf3d1015fb2dc33 Mon Sep 17 00:00:00 2001 From: Elias Naur Date: Wed, 16 Oct 2019 00:36:31 +0200 Subject: [PATCH] layout: invert baseline to measure positive distance from bottom With an inverted baseline, the zero value results in the widget baseline aligned to its bottom. Signed-off-by: Elias Naur --- layout/flex.go | 42 +++++++++++++++++-------------------- layout/layout.go | 4 ++-- layout/stack.go | 21 +++++++------------ widget/label.go | 2 +- widget/material/image.go | 2 +- widget/material/material.go | 2 +- 6 files changed, 32 insertions(+), 41 deletions(-) diff --git a/layout/flex.go b/layout/flex.go index 316926da..1eeaa855 100644 --- a/layout/flex.go +++ b/layout/flex.go @@ -23,9 +23,7 @@ type Flex struct { size int rigidSize int // fraction is the rounding error from a Flex weighting. - fraction float32 - maxCross int - maxBaseline int + fraction float32 } // FlexChild is the layout result of a call End. @@ -108,20 +106,23 @@ func (f *Flex) Flex(gtx *Context, weight float32, w Widget) FlexChild { func (f *Flex) expand(dims Dimensions) { sz := axisMain(f.Axis, dims.Size) f.size += sz - if c := axisCross(f.Axis, dims.Size); c > f.maxCross { - f.maxCross = c - } - if b := dims.Baseline; b > f.maxBaseline { - f.maxBaseline = b - } } // Layout a list of children. The order of the children determines their laid // out order. func (f *Flex) Layout(gtx *Context, children ...FlexChild) { + var maxCross int + var maxBaseline int + for _, child := range children { + if c := axisCross(f.Axis, child.dims.Size); c > maxCross { + maxCross = c + } + if b := child.dims.Size.Y - child.dims.Baseline; b > maxBaseline { + maxBaseline = b + } + } cs := gtx.Constraints mainc := axisMainConstraint(f.Axis, cs) - crossSize := axisCrossConstraint(f.Axis, cs).Constrain(f.maxCross) var space int if mainc.Min > f.size { space = mainc.Min - f.size @@ -140,16 +141,19 @@ func (f *Flex) Layout(gtx *Context, children ...FlexChild) { } for i, child := range children { dims := child.dims - b := dims.Baseline + b := dims.Size.Y - dims.Baseline var cross int switch f.Alignment { case End: - cross = crossSize - axisCross(f.Axis, dims.Size) + cross = maxCross - axisCross(f.Axis, dims.Size) case Middle: - cross = (crossSize - axisCross(f.Axis, dims.Size)) / 2 + cross = (maxCross - axisCross(f.Axis, dims.Size)) / 2 case Baseline: if f.Axis == Horizontal { - cross = f.maxBaseline - b + cross = maxBaseline - b + if dims.Baseline != 0 { + baseline = maxCross - b + } } } var stack op.StackOp @@ -168,9 +172,6 @@ func (f *Flex) Layout(gtx *Context, children ...FlexChild) { mainSize += space / (len(children) - 1) } } - if b != dims.Size.Y { - baseline = b - } } switch f.Spacing { case SpaceSides: @@ -182,15 +183,10 @@ func (f *Flex) Layout(gtx *Context, children ...FlexChild) { case SpaceAround: mainSize += space / (len(children) * 2) } - sz := axisPoint(f.Axis, mainSize, crossSize) - if baseline == 0 { - baseline = sz.Y - } + sz := axisPoint(f.Axis, mainSize, maxCross) gtx.Dimensions = Dimensions{Size: sz, Baseline: baseline} f.size = 0 f.rigidSize = 0 - f.maxCross = 0 - f.maxBaseline = 0 } func axisPoint(a Axis, main, cross int) image.Point { diff --git a/layout/layout.go b/layout/layout.go index 1be6da15..65c36f5e 100644 --- a/layout/layout.go +++ b/layout/layout.go @@ -170,7 +170,7 @@ func (in Inset) Layout(gtx *Context, w Widget) { stack.Pop() gtx.Dimensions = Dimensions{ Size: dims.Size.Add(image.Point{X: right + left, Y: top + bottom}), - Baseline: dims.Baseline + top, + Baseline: dims.Baseline + bottom, } } @@ -217,7 +217,7 @@ func (a Align) Layout(gtx *Context, w Widget) { stack.Pop() gtx.Dimensions = Dimensions{ Size: sz, - Baseline: dims.Baseline + p.Y, + Baseline: dims.Baseline + sz.Y - dims.Size.Y - p.Y, } } diff --git a/layout/stack.go b/layout/stack.go index 858dcad3..9d56d61e 100644 --- a/layout/stack.go +++ b/layout/stack.go @@ -15,8 +15,7 @@ type Stack struct { // smaller than the available space. Alignment Direction - maxSZ image.Point - baseline int + maxSZ image.Point } // StackChild is the layout result of a call to End. @@ -60,11 +59,6 @@ func (s *Stack) expand(dims Dimensions) { if h := dims.Size.Y; h > s.maxSZ.Y { s.maxSZ.Y = h } - if s.baseline == 0 { - if b := dims.Baseline; b != dims.Size.Y { - s.baseline = b - } - } } // Layout a list of children. The order of the children determines their laid @@ -72,6 +66,7 @@ func (s *Stack) expand(dims Dimensions) { func (s *Stack) Layout(gtx *Context, children ...StackChild) { maxSZ := gtx.Constraints.Constrain(s.maxSZ) s.maxSZ = image.Point{} + var baseline int for _, ch := range children { sz := ch.dims.Size var p image.Point @@ -92,14 +87,14 @@ func (s *Stack) Layout(gtx *Context, children ...StackChild) { op.TransformOp{}.Offset(toPointF(p)).Add(gtx.Ops) ch.macro.Add(gtx.Ops) stack.Pop() - } - b := s.baseline - if b == 0 { - b = maxSZ.Y + if baseline == 0 { + if b := ch.dims.Baseline; b != 0 { + baseline = b + maxSZ.Y - sz.Y - p.Y + } + } } gtx.Dimensions = Dimensions{ Size: maxSZ, - Baseline: b, + Baseline: baseline, } - s.baseline = 0 } diff --git a/widget/label.go b/widget/label.go index 7b492f74..16927b06 100644 --- a/widget/label.go +++ b/widget/label.go @@ -165,7 +165,7 @@ func linesDimens(lines []text.Line) layout.Dimensions { X: w, Y: h, }, - Baseline: baseline, + Baseline: h - baseline, } } diff --git a/widget/material/image.go b/widget/material/image.go index 2be634c6..3c8ff771 100644 --- a/widget/material/image.go +++ b/widget/material/image.go @@ -46,5 +46,5 @@ func (im Image) Layout(gtx *layout.Context) { } im.Src.Add(gtx.Ops) paint.PaintOp{Rect: dr}.Add(gtx.Ops) - gtx.Dimensions = layout.Dimensions{Size: d, Baseline: d.Y} + gtx.Dimensions = layout.Dimensions{Size: d} } diff --git a/widget/material/material.go b/widget/material/material.go index 4b3dcfeb..4bd44c23 100644 --- a/widget/material/material.go +++ b/widget/material/material.go @@ -53,7 +53,7 @@ func fill(gtx *layout.Context, col color.RGBA) { } paint.ColorOp{Color: col}.Add(gtx.Ops) paint.PaintOp{Rect: dr}.Add(gtx.Ops) - gtx.Dimensions = layout.Dimensions{Size: d, Baseline: d.Y} + gtx.Dimensions = layout.Dimensions{Size: d} } // https://pomax.github.io/bezierinfo/#circles_cubic.