From e725799ad17c575a7a3cd2536f57bd82f85782e5 Mon Sep 17 00:00:00 2001 From: Sam Anthony Date: Sat, 24 Aug 2024 15:13:09 -0400 Subject: adapt grid to new layout design --- grid.go | 113 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ layout/grid.go | 115 -------------------------------------------------------- layout/split.go | 26 ------------- split.go | 26 +++++++++++++ 4 files changed, 139 insertions(+), 141 deletions(-) create mode 100644 grid.go delete mode 100644 layout/grid.go delete mode 100644 layout/split.go create mode 100644 split.go diff --git a/grid.go b/grid.go new file mode 100644 index 0000000..13e986a --- /dev/null +++ b/grid.go @@ -0,0 +1,113 @@ +package gui + +import ( + "image" + "image/color" + "image/draw" + "log" +) + +var _ Scheme = 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 + // Background represents the background of the grid as a uniform color. + Background color.Color + // Gap represents the grid gap, equal on all sides. + Gap int + // 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) { + col := g.Background + if col == nil { + 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.Inset(g.Border), image.NewUniform(col), image.ZP, draw.Src) +} + +func (g Grid) Intercept(env Env) Env { + return RedrawIntercepter{g.redraw}.Intercept(env) +} + +func (g Grid) Partition(bounds image.Rectangle) []image.Rectangle { + gap := g.Gap + rows := g.Rows + splitMain := g.Split + if splitMain == nil { + splitMain = EvenSplit + } + splitSec := g.SplitRows + if splitSec == nil { + splitSec = 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) + + // 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 := splitMain(cols, W-(gap*(cols+1))-margin*2) + X = gap + mX + margin + for _, w := range colsW { + 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 + } + + return ret +} diff --git a/layout/grid.go b/layout/grid.go deleted file mode 100644 index 3ff8112..0000000 --- a/layout/grid.go +++ /dev/null @@ -1,115 +0,0 @@ -package layout - -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 - // Background represents the background of the grid as a uniform color. - Background color.Color - // Gap represents the grid gap, equal on all sides. - Gap int - // 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) { - col := g.Background - if col == nil { - 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.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 - splitMain := g.Split - if splitMain == nil { - splitMain = EvenSplit - } - splitSec := g.SplitRows - if splitSec == nil { - splitSec = 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) - - // 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 := splitMain(cols, W-(gap*(cols+1))-margin*2) - X = gap + mX + margin - for _, w := range colsW { - 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 - } - - return ret -} diff --git a/layout/split.go b/layout/split.go deleted file mode 100644 index db04225..0000000 --- a/layout/split.go +++ /dev/null @@ -1,26 +0,0 @@ -package layout - -import "fmt" - -// SplitFunc represents a way to split a space among a number of elements. -// The length 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 - -var _ SplitFunc = EvenSplit - -// EvenSplit is a SplitFunc used 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 { - if elements <= 0 { - panic(fmt.Errorf("EvenSplit: elements must be greater than 0")) - } - ret := make([]int, elements) - for elements > 0 { - v := width / elements - width -= v - elements -= 1 - ret[elements] = v - } - return ret -} diff --git a/split.go b/split.go new file mode 100644 index 0000000..ab6789b --- /dev/null +++ b/split.go @@ -0,0 +1,26 @@ +package gui + +import "fmt" + +// SplitFunc represents a way to split a space among a number of elements. +// The length 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 + +var _ SplitFunc = EvenSplit + +// EvenSplit is a SplitFunc used 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 { + if elements <= 0 { + panic(fmt.Errorf("EvenSplit: elements must be greater than 0")) + } + ret := make([]int, elements) + for elements > 0 { + v := width / elements + width -= v + elements -= 1 + ret[elements] = v + } + return ret +} -- cgit v1.2.3