package layouts import "image" import "git.tebibyte.media/tomo/tomo" // Contract is a layout that arranges boxes in a simple row or column according // to their minimum sizes. type Contract bool // ContractVertical is a vertical contracted layout. const ContractVertical Contract = true // ContractHorizontal is a horizontal contracted layout. const ContractHorizontal Contract = false func (contract Contract) MinimumSize (hints tomo.LayoutHints, boxes []tomo.Box) image.Point { if contract.v() { dot := image.Point { } for _, box := range boxes { minimum := box.MinimumSize() dot.Y += minimum.Y if dot.X < minimum.X { dot.X = minimum.X } } dot.Y += hints.Gap.Y * (len(boxes) - 1) return dot } else { dot := image.Point { } for _, box := range boxes { minimum := box.MinimumSize() dot.X += minimum.X if dot.Y < minimum.Y { dot.Y = minimum.Y } } dot.X += hints.Gap.X * (len(boxes) - 1) return dot } } func (contract Contract) Arrange (hints tomo.LayoutHints, boxes []tomo.Box) { if contract.v() { dot := hints.Bounds.Min for index, box := range boxes { if index > 0 { dot.Y += hints.Gap.Y } minimum := box.MinimumSize() box.SetBounds(image.Rectangle { Min: dot, Max: dot.Add(image.Pt(hints.Bounds.Dx(), minimum.Y)), }) dot.Y += minimum.Y } height := dot.Y - hints.Bounds.Min.Y offset := 0 switch hints.AlignY { case tomo.AlignMiddle: offset = (hints.Bounds.Dy() - height) / 2 case tomo.AlignEnd: offset = hints.Bounds.Dy() - height } for _, box := range boxes { box.SetBounds(box.Bounds().Add(image.Pt(0, offset))) } } else { dot := hints.Bounds.Min for index, box := range boxes { if index > 0 { dot.X += hints.Gap.X } minimum := box.MinimumSize() box.SetBounds(image.Rectangle { Min: dot, Max: dot.Add(image.Pt(minimum.X, hints.Bounds.Dy())), }) dot.X += minimum.X } width := dot.X - hints.Bounds.Min.X offset := 0 switch hints.AlignX { case tomo.AlignMiddle: offset = (hints.Bounds.Dx() - width) / 2 case tomo.AlignEnd: offset = hints.Bounds.Dx() - width } for _, box := range boxes { box.SetBounds(box.Bounds().Add(image.Pt(offset, 0))) } } } func (contract Contract) v () bool { return contract == ContractVertical } func (contract Contract) h () bool { return contract == ContractHorizontal }