diff --git a/layouts/cut.go b/layouts/cut.go index 8fbbd1c..3ee9d73 100644 --- a/layouts/cut.go +++ b/layouts/cut.go @@ -5,87 +5,46 @@ import "git.tebibyte.media/tomo/tomo" // Cut is a layout that can be divided into smaller and smaller sections. type Cut struct { - branches [2]*Cut - expand [2]bool + branches []*Cut + expand []bool vertical bool } -// Vertical divides the layout in equal halves vertically. -func (this *Cut) Vertical () (top, bottom *Cut) { - this.fill() - this.even() +// NewCut creates and returns a new Cut layout. +func NewCut () *Cut { + return new(Cut) +} + +// 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 - 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.first() - this.vertical = true - return this.Branches() } -// Bottom divides the layout vertically, expanding the bottom half and -// contracting the top half. -func (this *Cut) Bottom () (top, bottom *Cut) { +// Horizontal divides the layout horizontally. Sections are specified using +// booleans. If a section is true, it will expand. If false, it will contract. +func (this *Cut) Horizontal (expand ...bool) { + this.expand = expand + this.vertical = false this.fill() - this.second() - this.vertical = true - return this.Branches() } -// Horizontal divides the layout in equal halves horizontally. -func (this *Cut) Horizontal () (top, bottom *Cut) { - this.fill() - 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] +// At returns the section of this layout at the specified index. +func (this *Cut) At (index int) *Cut { + return this.branches[index] } 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 () { - this.branches[0] = &Cut { } - this.branches[1] = &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 + this.branches = make([]*Cut, len(this.expand)) + for index := range this.branches { + this.branches[index] = new(Cut) + } } 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 { + nChildren := len(this.branches) + // collect minimum sizes and physical endpoints - var minimums [2]image.Point - var leaves [2]tomo.Box + var minimums = make([]image.Point, nChildren) + var leaves = make([]tomo.Box, nChildren) var nBranches int remaining := boxes 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 // calculate the size and position of branches - var bounds [2]image.Rectangle + var bounds = make([]image.Rectangle, nChildren) x := float64(hints.Bounds.Min.X) y := float64(hints.Bounds.Min.Y) for index, minimum := range minimums {