diff options
Diffstat (limited to 'layout/grid.go')
| -rw-r--r-- | layout/grid.go | 95 |
1 files changed, 76 insertions, 19 deletions
diff --git a/layout/grid.go b/layout/grid.go index f3cced6..3ff8112 100644 --- a/layout/grid.go +++ b/layout/grid.go @@ -4,8 +4,15 @@ import ( "image" "image/color" "image/draw" + "log" + + "github.com/faiface/gui" ) +var _ Layout = Grid{} + +// Grid represents a grid with rows and columns in each row. +// Each row can be a different length. type Grid struct { // Rows represents the number of childs of each row. Rows []int @@ -13,42 +20,92 @@ type Grid struct { Background color.Color // Gap represents the grid gap, equal on all sides. Gap int - // SplitX represents the way the space is divided among the columns in each row. - SplitX SplitFunc - // SplitY represents the way the space is divided among the rows. - SplitY SplitFunc + // Split represents the way the space is divided among the columns in each row. + Split SplitFunc + // SplitRows represents the way the space is divided among the rows. + SplitRows SplitFunc + + Margin int + Border int + BorderColor color.Color + + // Flip represents the orientation of the grid. + // When false, rows are spread in the Y axis and columns in the X axis. + // When true, rows are spread in the X axis and columns in the Y axis. + Flip bool } -func (g Grid) Redraw(drw draw.Image, bounds image.Rectangle) { +func (g Grid) redraw(drw draw.Image, bounds image.Rectangle) { col := g.Background if col == nil { - col = image.Black + col = color.Black + } + if g.Border > 0 { + bcol := g.BorderColor + if bcol == nil { + bcol = color.Black + } + draw.Draw(drw, bounds, image.NewUniform(bcol), image.ZP, draw.Src) } - draw.Draw(drw, bounds, image.NewUniform(col), image.ZP, draw.Src) + draw.Draw(drw, bounds.Inset(g.Border), image.NewUniform(col), image.ZP, draw.Src) +} + +func (g Grid) Intercept(env gui.Env) gui.Env { + return RedrawIntercepter{g.redraw}.Intercept(env) } func (g Grid) Lay(bounds image.Rectangle) []image.Rectangle { gap := g.Gap rows := g.Rows - splitX := g.SplitX - if splitX == nil { - splitX = EvenSplit + splitMain := g.Split + if splitMain == nil { + splitMain = EvenSplit + } + splitSec := g.SplitRows + if splitSec == nil { + splitSec = EvenSplit } - splitY := g.SplitY - if splitY == nil { - splitY = EvenSplit + margin := g.Margin + flip := g.Flip + if margin+gap < 0 { + log.Println("Grid goes out of bounds") + } + if margin+gap < g.Border { + log.Println("Grid border will not be shown properly") } ret := make([]image.Rectangle, 0) - rowsH := splitY(len(rows), bounds.Dy()-(gap*(len(rows)+1))) - X := gap + bounds.Min.X - Y := gap + bounds.Min.Y + + // Sorry it's not very understandable + var H, W int + var mX, mY int + if flip { + H = bounds.Dx() + W = bounds.Dy() + mX = bounds.Min.Y + mY = bounds.Min.X + } else { + H = bounds.Dy() + W = bounds.Dx() + mX = bounds.Min.X + mY = bounds.Min.Y + } + rowsH := splitSec(len(rows), H-(gap*(len(rows)+1))-margin*2) + var X int + var Y int + Y = gap + mY + margin for y, cols := range rows { h := rowsH[y] - colsW := splitX(cols, bounds.Dx()-(gap*(cols+1))) - X = gap + bounds.Min.X + colsW := splitMain(cols, W-(gap*(cols+1))-margin*2) + X = gap + mX + margin for _, w := range colsW { - ret = append(ret, image.Rect(X, Y, X+w, Y+h)) + var r image.Rectangle + if flip { + r = image.Rect(Y, X, Y+h, X+w) + } else { + r = image.Rect(X, Y, X+w, Y+h) + } + ret = append(ret, r) X += gap + w } Y += gap + h |