Made the Cut layout significantly more powerful

This commit is contained in:
Sasha Koshka 2023-08-14 00:24:28 -04:00
parent 3cf8df0cb2
commit 84313885df

View File

@ -5,87 +5,46 @@ import "git.tebibyte.media/tomo/tomo"
// Cut is a layout that can be divided into smaller and smaller sections. // Cut is a layout that can be divided into smaller and smaller sections.
type Cut struct { type Cut struct {
branches [2]*Cut branches []*Cut
expand [2]bool expand []bool
vertical bool vertical bool
} }
// Vertical divides the layout in equal halves vertically. // NewCut creates and returns a new Cut layout.
func (this *Cut) Vertical () (top, bottom *Cut) { func NewCut () *Cut {
this.fill() return new(Cut)
this.even() }
// Vertical divides the layout vertically. Sections are specified using
// booleans. If a section is true, it will expand. If false, it will contract.
func (this *Cut) Vertical (expand ...bool) {
this.expand = expand
this.vertical = true this.vertical = true
return this.Branches()
}
// Top divides the layout vertically, expanding the top half and contracting the
// bottom half.
func (this *Cut) Top () (top, bottom *Cut) {
this.fill() this.fill()
this.first()
this.vertical = true
return this.Branches()
} }
// Bottom divides the layout vertically, expanding the bottom half and // Horizontal divides the layout horizontally. Sections are specified using
// contracting the top half. // booleans. If a section is true, it will expand. If false, it will contract.
func (this *Cut) Bottom () (top, bottom *Cut) { func (this *Cut) Horizontal (expand ...bool) {
this.expand = expand
this.vertical = false
this.fill() this.fill()
this.second()
this.vertical = true
return this.Branches()
} }
// Horizontal divides the layout in equal halves horizontally. // At returns the section of this layout at the specified index.
func (this *Cut) Horizontal () (top, bottom *Cut) { func (this *Cut) At (index int) *Cut {
this.fill() return this.branches[index]
this.even()
return this.Branches()
}
// Left divides the layout horizontally, expanding the left half and contracting
// the right half.
func (this *Cut) Left () (top, bottom *Cut) {
this.fill()
this.first()
return this.Branches()
}
// Right divides the layout horizontally, expanding the right half and
// contracting the left half.
func (this *Cut) Right () (top, bottom *Cut) {
this.fill()
this.second()
return this.Branches()
}
// Branches returns the two halves of this layout.
func (this *Cut) Branches () (first, second *Cut) {
return this.branches[0], this.branches[1]
} }
func (this *Cut) real () bool { func (this *Cut) real () bool {
return this != nil && this.branches[0] != nil && this.branches[1] != nil return this != nil && this.branches != nil
} }
func (this *Cut) fill () { func (this *Cut) fill () {
this.branches[0] = &Cut { } this.branches = make([]*Cut, len(this.expand))
this.branches[1] = &Cut { } for index := range this.branches {
} this.branches[index] = new(Cut)
}
func (this *Cut) first () {
this.expand[0] = true
this.expand[1] = false
}
func (this *Cut) second () {
this.expand[0] = false
this.expand[1] = true
}
func (this *Cut) even () {
this.expand[0] = true
this.expand[1] = true
} }
func (this *Cut) MinimumSize (hints tomo.LayoutHints, boxes []tomo.Box) image.Point { func (this *Cut) MinimumSize (hints tomo.LayoutHints, boxes []tomo.Box) image.Point {
@ -126,9 +85,11 @@ func (this *Cut) minimumSize (hints tomo.LayoutHints, boxes []tomo.Box) (image.P
} }
func (this *Cut) arrange (hints tomo.LayoutHints, boxes []tomo.Box) []tomo.Box { func (this *Cut) arrange (hints tomo.LayoutHints, boxes []tomo.Box) []tomo.Box {
nChildren := len(this.branches)
// collect minimum sizes and physical endpoints // collect minimum sizes and physical endpoints
var minimums [2]image.Point var minimums = make([]image.Point, nChildren)
var leaves [2]tomo.Box var leaves = make([]tomo.Box, nChildren)
var nBranches int var nBranches int
remaining := boxes remaining := boxes
for index, branch := range this.branches { for index, branch := range this.branches {
@ -163,7 +124,7 @@ func (this *Cut) arrange (hints tomo.LayoutHints, boxes []tomo.Box) []tomo.Box {
expandingSize := freeSpace / nExpanding expandingSize := freeSpace / nExpanding
// calculate the size and position of branches // calculate the size and position of branches
var bounds [2]image.Rectangle var bounds = make([]image.Rectangle, nChildren)
x := float64(hints.Bounds.Min.X) x := float64(hints.Bounds.Min.X)
y := float64(hints.Bounds.Min.Y) y := float64(hints.Bounds.Min.Y)
for index, minimum := range minimums { for index, minimum := range minimums {