diff options
| -rw-r--r-- | layout/box.go | 54 | ||||
| -rw-r--r-- | layout/grid.go | 43 | ||||
| -rw-r--r-- | layout/split.go | 19 |
3 files changed, 66 insertions, 50 deletions
diff --git a/layout/box.go b/layout/box.go index 2fd29cf..01a1143 100644 --- a/layout/box.go +++ b/layout/box.go @@ -8,35 +8,22 @@ import ( "github.com/faiface/gui" ) -func evenSplit(elements int, width int) []int { - ret := make([]int, 0, elements) - for elements > 0 { - v := width / elements - width -= v - elements -= 1 - ret = append(ret, v) - } - return ret -} - -type Box struct { - // Defaults to []*gui.Env{} - Contents []*gui.Env - // Defaults to image.Black +type box struct { + Contents []*gui.Env Background color.Color - // Defaults to an even split - Split func(int, int) []int - // Defaults to 0 - Gap int + Split SplitFunc + Gap int vertical bool } -func NewBox(env gui.Env, contents []*gui.Env, options ...func(*Box)) gui.Env { - ret := &Box{ +// NewBox creates a familiar flexbox-like list layout. +// It can be horizontal or vertical. +func NewBox(env gui.Env, contents []*gui.Env, options ...func(*box)) gui.Env { + ret := &box{ Background: image.Black, Contents: contents, - Split: evenSplit, + Split: EvenSplit, } for _, f := range options { f(ret) @@ -49,33 +36,38 @@ func NewBox(env gui.Env, contents []*gui.Env, options ...func(*Box)) gui.Env { return env } -func BoxVertical(b *Box) { +// BoxVertical changes the otherwise horizontal Box to be vertical. +func BoxVertical(b *box) { b.vertical = true } -func BoxBackground(c color.Color) func(*Box) { - return func(grid *Box) { +// BoxBackground changes the background of the box to a uniform color. +func BoxBackground(c color.Color) func(*box) { + return func(grid *box) { grid.Background = c } } -func BoxSplit(split func(int, int) []int) func(*Box) { - return func(grid *Box) { +// BoxSplit changes the way the space is divided among the elements. +func BoxSplit(split SplitFunc) func(*box) { + return func(grid *box) { grid.Split = split } } -func BoxGap(gap int) func(*Box) { - return func(grid *Box) { +// BoxGap changes the box gap. +// The gap is identical everywhere (top, left, bottom, right). +func BoxGap(gap int) func(*box) { + return func(grid *box) { grid.Gap = gap } } -func (g *Box) Redraw(drw draw.Image, bounds image.Rectangle) { +func (g *box) Redraw(drw draw.Image, bounds image.Rectangle) { draw.Draw(drw, bounds, image.NewUniform(g.Background), image.ZP, draw.Src) } -func (g *Box) Lay(bounds image.Rectangle) []image.Rectangle { +func (g *box) Lay(bounds image.Rectangle) []image.Rectangle { items := len(g.Contents) ret := make([]image.Rectangle, 0, items) if g.vertical { diff --git a/layout/grid.go b/layout/grid.go index 1831794..9c79343 100644 --- a/layout/grid.go +++ b/layout/grid.go @@ -8,23 +8,23 @@ import ( "github.com/faiface/gui" ) -// Grid represents a simple grid layout. -// Do not edit properties directly, use the constructor instead. -type Grid struct { +type grid struct { Contents [][]*gui.Env Background color.Color Gap int - SplitX func(int, int) []int - SplitY func(int, int) []int + SplitX SplitFunc + SplitY SplitFunc } -func NewGrid(env gui.Env, contents [][]*gui.Env, options ...func(*Grid)) gui.Env { - ret := &Grid{ +// NewGrid creates a familiar flexbox-like grid layout. +// Each row can be a different length. +func NewGrid(env gui.Env, contents [][]*gui.Env, options ...func(*grid)) gui.Env { + ret := &grid{ Background: image.Black, Gap: 0, Contents: contents, - SplitX: evenSplit, - SplitY: evenSplit, + SplitX: EvenSplit, + SplitY: EvenSplit, } for _, f := range options { f(ret) @@ -40,35 +40,40 @@ func NewGrid(env gui.Env, contents [][]*gui.Env, options ...func(*Grid)) gui.Env return env } -func GridBackground(c color.Color) func(*Grid) { - return func(grid *Grid) { +// GridBackground changes the background of the grid to a uniform color. +func GridBackground(c color.Color) func(*grid) { + return func(grid *grid) { grid.Background = c } } -func GridGap(g int) func(*Grid) { - return func(grid *Grid) { +// GridGap changes the grid gap. +// The gap is identical everywhere (top, left, bottom, right). +func GridGap(g int) func(*grid) { + return func(grid *grid) { grid.Gap = g } } -func GridSplitX(split func(int, int) []int) func(*Grid) { - return func(grid *Grid) { +// GridSplitX changes the way the space is divided among the columns in each row. +func GridSplitX(split SplitFunc) func(*grid) { + return func(grid *grid) { grid.SplitX = split } } -func GridSplitY(split func(int, int) []int) func(*Grid) { - return func(grid *Grid) { +// GridSplitY changes the way the space is divided among the rows. +func GridSplitY(split SplitFunc) func(*grid) { + return func(grid *grid) { grid.SplitY = split } } -func (g *Grid) Redraw(drw draw.Image, bounds image.Rectangle) { +func (g *grid) Redraw(drw draw.Image, bounds image.Rectangle) { draw.Draw(drw, bounds, image.NewUniform(g.Background), image.ZP, draw.Src) } -func (g *Grid) Lay(bounds image.Rectangle) []image.Rectangle { +func (g *grid) Lay(bounds image.Rectangle) []image.Rectangle { gap := g.Gap ret := make([]image.Rectangle, 0) rows := len(g.Contents) diff --git a/layout/split.go b/layout/split.go new file mode 100644 index 0000000..4bf00a7 --- /dev/null +++ b/layout/split.go @@ -0,0 +1,19 @@ +package layout + +// SplitFunc represents a way to split a space among a number of elements. +// The space of the returned slice must be equal to the number of elements. +// The sum of all elements of the returned slice must be eqal to the space. +type SplitFunc func(elements int, space int) []int + +// EvenSplit implements SplitFunc to split a space (almost) evenly among the elements. +// It is almost evenly because width may not be divisible by elements. +func EvenSplit(elements int, width int) []int { + ret := make([]int, 0, elements) + for elements > 0 { + v := width / elements + width -= v + elements -= 1 + ret = append(ret, v) + } + return ret +} |