Contract layouts are now based on new Row and Column layouts
This commit is contained in:
		
							parent
							
								
									1596d54834
								
							
						
					
					
						commit
						9ce7f8b8f3
					
				@ -5,9 +5,9 @@ import "git.tebibyte.media/tomo/tomo/input"
 | 
				
			|||||||
import "git.tebibyte.media/tomo/tomo/event"
 | 
					import "git.tebibyte.media/tomo/tomo/event"
 | 
				
			||||||
import "git.tebibyte.media/tomo/objects/layouts"
 | 
					import "git.tebibyte.media/tomo/objects/layouts"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
var buttonLayout     = layouts.NewGrid([]bool { true        }, []bool { true })
 | 
					var buttonLayout     = layouts.Row { true        }
 | 
				
			||||||
var iconButtonLayout = layouts.NewGrid([]bool { true        }, []bool { true })
 | 
					var iconButtonLayout = layouts.Row { true        }
 | 
				
			||||||
var bothButtonLayout = layouts.NewGrid([]bool { false, true }, []bool { true })
 | 
					var bothButtonLayout = layouts.Row { false, true }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Button is a clickable button.
 | 
					// Button is a clickable button.
 | 
				
			||||||
type Button struct {
 | 
					type Button struct {
 | 
				
			||||||
 | 
				
			|||||||
@ -16,93 +16,25 @@ const ContractVertical Contract = true
 | 
				
			|||||||
const ContractHorizontal Contract = false
 | 
					const ContractHorizontal Contract = false
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (contract Contract) MinimumSize (hints tomo.LayoutHints, boxes []tomo.Box) image.Point {
 | 
					func (contract Contract) MinimumSize (hints tomo.LayoutHints, boxes []tomo.Box) image.Point {
 | 
				
			||||||
	if contract.v() {
 | 
						return contract.fallback().MinimumSize(hints, boxes)
 | 
				
			||||||
		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) {
 | 
					func (contract Contract) Arrange (hints tomo.LayoutHints, boxes []tomo.Box) {
 | 
				
			||||||
	// TODO if we overflow in a direction, respect the reccomended size
 | 
						contract.fallback().Arrange(hints, boxes)
 | 
				
			||||||
	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) RecommendedHeight (hints tomo.LayoutHints, boxes []tomo.Box, width int) int {
 | 
					func (contract Contract) RecommendedHeight (hints tomo.LayoutHints, boxes []tomo.Box, width int) int {
 | 
				
			||||||
	// TODO
 | 
						return contract.fallback().RecommendedHeight(hints, boxes, width)
 | 
				
			||||||
	return 0
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (contract Contract) RecommendedWidth (hints tomo.LayoutHints, boxes []tomo.Box, height int) int {
 | 
					func (contract Contract) RecommendedWidth (hints tomo.LayoutHints, boxes []tomo.Box, height int) int {
 | 
				
			||||||
	// TODO
 | 
						return contract.fallback().RecommendedWidth(hints, boxes, height)
 | 
				
			||||||
	return 0
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (contract Contract) v () bool { return contract == ContractVertical   }
 | 
					func (contract Contract) fallback () tomo.Layout {
 | 
				
			||||||
func (contract Contract) h () bool { return contract == ContractHorizontal }
 | 
						if contract == ContractVertical {
 | 
				
			||||||
 | 
							return Column { }
 | 
				
			||||||
 | 
						} else {
 | 
				
			||||||
 | 
							return Row { }
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										200
									
								
								layouts/rowcol.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										200
									
								
								layouts/rowcol.go
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,200 @@
 | 
				
			|||||||
 | 
					package layouts
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import "image"
 | 
				
			||||||
 | 
					import "git.tebibyte.media/tomo/tomo"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					var _ tomo.Layout = ContractVertical
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Row arranges boxes in a row. Boxes that share an index with a true value will
 | 
				
			||||||
 | 
					// expand, and others will contract.
 | 
				
			||||||
 | 
					type Row []bool
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Column arranges boxes in a column. Boxes that share an index with a true
 | 
				
			||||||
 | 
					// value will expand, and others will contract.
 | 
				
			||||||
 | 
					type Column []bool
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (column Column) MinimumSize (hints tomo.LayoutHints, boxes []tomo.Box) image.Point {
 | 
				
			||||||
 | 
						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
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (row Row) MinimumSize (hints tomo.LayoutHints, boxes []tomo.Box) image.Point {
 | 
				
			||||||
 | 
						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 (column Column) Arrange (hints tomo.LayoutHints, boxes []tomo.Box) {
 | 
				
			||||||
 | 
						expands := func (index int) bool {
 | 
				
			||||||
 | 
							if index < len(boxes) { return false }
 | 
				
			||||||
 | 
							return column[index]
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// determine expanding box size
 | 
				
			||||||
 | 
						expandingSize := 0
 | 
				
			||||||
 | 
						if !hints.OverflowY {
 | 
				
			||||||
 | 
							gaps       := len(boxes) - 1
 | 
				
			||||||
 | 
							freeSpace  := float64(hints.Bounds.Dy() - hints.Gap.Y * gaps)
 | 
				
			||||||
 | 
							nExpanding := 0; for index, box := range boxes {
 | 
				
			||||||
 | 
								if expands(index) {
 | 
				
			||||||
 | 
									nExpanding ++
 | 
				
			||||||
 | 
								} else {
 | 
				
			||||||
 | 
									freeSpace -= float64(box.MinimumSize().X)
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// determine width
 | 
				
			||||||
 | 
						width := 0
 | 
				
			||||||
 | 
						if hints.OverflowX {
 | 
				
			||||||
 | 
							for _, box := range boxes {
 | 
				
			||||||
 | 
								minimum := box.MinimumSize()
 | 
				
			||||||
 | 
								if width < minimum.X { width = minimum.X }
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						} else {
 | 
				
			||||||
 | 
							width = hints.Bounds.Dx()
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// arrange
 | 
				
			||||||
 | 
						dot := hints.Bounds.Min
 | 
				
			||||||
 | 
						for index, box := range boxes {
 | 
				
			||||||
 | 
							if index > 0 { dot.Y += hints.Gap.Y }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							// determine height
 | 
				
			||||||
 | 
							height := box.MinimumSize().Y
 | 
				
			||||||
 | 
							if hints.OverflowY {
 | 
				
			||||||
 | 
								if box, ok := box.(tomo.ContentBox); ok {
 | 
				
			||||||
 | 
									height = box.RecommendedHeight(width)
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							} else {
 | 
				
			||||||
 | 
								if expands(index) {
 | 
				
			||||||
 | 
									height = expandingSize
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							// set bounds
 | 
				
			||||||
 | 
							box.SetBounds(image.Rectangle {
 | 
				
			||||||
 | 
								Min: dot,
 | 
				
			||||||
 | 
								Max: dot.Add(image.Pt(width, height)),
 | 
				
			||||||
 | 
							})
 | 
				
			||||||
 | 
							dot.Y += height
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						
 | 
				
			||||||
 | 
						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)))
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (row Row) Arrange (hints tomo.LayoutHints, boxes []tomo.Box) {
 | 
				
			||||||
 | 
						expands := func (index int) bool {
 | 
				
			||||||
 | 
							if index < len(boxes) { return false }
 | 
				
			||||||
 | 
							return row[index]
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// determine expanding box size
 | 
				
			||||||
 | 
						expandingSize := 0
 | 
				
			||||||
 | 
						if !hints.OverflowY {
 | 
				
			||||||
 | 
							gaps       := len(boxes) - 1
 | 
				
			||||||
 | 
							freeSpace  := float64(hints.Bounds.Dx() - hints.Gap.X * gaps)
 | 
				
			||||||
 | 
							nExpanding := 0; for index, box := range boxes {
 | 
				
			||||||
 | 
								if expands(index) {
 | 
				
			||||||
 | 
									nExpanding ++
 | 
				
			||||||
 | 
								} else {
 | 
				
			||||||
 | 
									freeSpace -= float64(box.MinimumSize().Y)
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// determine height
 | 
				
			||||||
 | 
						height := 0
 | 
				
			||||||
 | 
						if hints.OverflowY {
 | 
				
			||||||
 | 
							for _, box := range boxes {
 | 
				
			||||||
 | 
								minimum := box.MinimumSize()
 | 
				
			||||||
 | 
								if height < minimum.Y { height = minimum.Y }
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						} else {
 | 
				
			||||||
 | 
							height = hints.Bounds.Dy()
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// arrange
 | 
				
			||||||
 | 
						dot := hints.Bounds.Min
 | 
				
			||||||
 | 
						for index, box := range boxes {
 | 
				
			||||||
 | 
							if index > 0 { dot.X += hints.Gap.X }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							// determine width
 | 
				
			||||||
 | 
							width := box.MinimumSize().X
 | 
				
			||||||
 | 
							if hints.OverflowY {
 | 
				
			||||||
 | 
								if box, ok := box.(tomo.ContentBox); ok {
 | 
				
			||||||
 | 
									width = box.RecommendedHeight(height)
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							} else {
 | 
				
			||||||
 | 
								if expands(index) {
 | 
				
			||||||
 | 
									width = expandingSize
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							// set bounds
 | 
				
			||||||
 | 
							box.SetBounds(image.Rectangle {
 | 
				
			||||||
 | 
								Min: dot,
 | 
				
			||||||
 | 
								Max: dot.Add(image.Pt(width, height)),
 | 
				
			||||||
 | 
							})
 | 
				
			||||||
 | 
							dot.X += width
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						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 (column Column) RecommendedHeight (hints tomo.LayoutHints, boxes []tomo.Box, width int) int {
 | 
				
			||||||
 | 
						// TODO
 | 
				
			||||||
 | 
						return 0
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (row Row) RecommendedHeight (hints tomo.LayoutHints, boxes []tomo.Box, width int) int {
 | 
				
			||||||
 | 
						// TODO
 | 
				
			||||||
 | 
						return 0
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (column Column) RecommendedWidth (hints tomo.LayoutHints, boxes []tomo.Box, height int) int {
 | 
				
			||||||
 | 
						// TODO
 | 
				
			||||||
 | 
						return 0
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (row Row) RecommendedWidth (hints tomo.LayoutHints, boxes []tomo.Box, height int) int {
 | 
				
			||||||
 | 
						// TODO
 | 
				
			||||||
 | 
						return 0
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user