summaryrefslogtreecommitdiff
path: root/ui/grid.go
diff options
context:
space:
mode:
Diffstat (limited to 'ui/grid.go')
-rw-r--r--ui/grid.go70
1 files changed, 55 insertions, 15 deletions
diff --git a/ui/grid.go b/ui/grid.go
index 2183a55..2091fc5 100644
--- a/ui/grid.go
+++ b/ui/grid.go
@@ -1,6 +1,9 @@
package ui
-import "fmt"
+import (
+ "fmt"
+ "math"
+)
type Grid struct {
Rows []DimSpec
@@ -42,6 +45,22 @@ type GridCell struct {
invalid bool
}
+func NewGrid() *Grid {
+ return &Grid{invalid: true}
+}
+
+func (cell *GridCell) At(row, col int) *GridCell {
+ cell.Row = row
+ cell.Column = col
+ return cell
+}
+
+func (cell *GridCell) Span(rows, cols int) *GridCell {
+ cell.RowSpan = rows
+ cell.ColSpan = cols
+ return cell
+}
+
func (grid *Grid) Draw(ctx *Context) {
invalid := grid.invalid
if invalid {
@@ -51,17 +70,17 @@ func (grid *Grid) Draw(ctx *Context) {
if !cell.invalid && !invalid {
continue
}
- rows := grid.rowLayout[cell.Row:cell.RowSpan]
- cols := grid.columnLayout[cell.Column:cell.ColSpan]
+ rows := grid.rowLayout[cell.Row : cell.Row+cell.RowSpan]
+ cols := grid.columnLayout[cell.Column : cell.Column+cell.ColSpan]
x := cols[0].Offset
y := rows[0].Offset
width := 0
height := 0
- for _, row := range rows {
- width += row.Size
- }
for _, col := range cols {
- height += col.Size
+ width += col.Size
+ }
+ for _, row := range rows {
+ height += row.Size
}
subctx := ctx.Subcontext(x, y, width, height)
cell.Content.Draw(subctx)
@@ -74,10 +93,12 @@ func (grid *Grid) reflow(ctx *Context) {
flow := func(specs *[]DimSpec, layouts *[]dimLayout, extent int) {
exact := 0
weight := 0
+ nweights := 0
for _, dim := range *specs {
if dim.Strategy == SIZE_EXACT {
exact += dim.Size
} else if dim.Strategy == SIZE_WEIGHT {
+ nweights += 1
weight += dim.Size
}
}
@@ -87,30 +108,49 @@ func (grid *Grid) reflow(ctx *Context) {
if dim.Strategy == SIZE_EXACT {
layout.Size = dim.Size
} else if dim.Strategy == SIZE_WEIGHT {
- size := float64(dim.Size) / float64(weight) * float64(extent)
- layout.Size = int(size)
+ size := float64(dim.Size) / float64(weight)
+ size *= float64(extent - exact)
+ layout.Size = int(math.Floor(size))
}
+ offset += layout.Size
*layouts = append(*layouts, layout)
}
}
- flow(&grid.Rows, &grid.rowLayout, ctx.Width())
- flow(&grid.Columns, &grid.columnLayout, ctx.Height())
+ flow(&grid.Rows, &grid.rowLayout, ctx.Height())
+ flow(&grid.Columns, &grid.columnLayout, ctx.Width())
grid.invalid = false
}
-func (grid *Grid) InvalidateLayout() {
+func (grid *Grid) invalidateLayout() {
grid.invalid = true
+ if grid.onInvalidate != nil {
+ grid.onInvalidate(grid)
+ }
+}
+
+func (grid *Grid) Invalidate() {
+ grid.invalidateLayout()
+ for _, cell := range grid.Cells {
+ cell.Content.Invalidate()
+ }
}
func (grid *Grid) OnInvalidate(onInvalidate func(d Drawable)) {
grid.onInvalidate = onInvalidate
}
-func (grid *Grid) AddChild(cell *GridCell) {
+func (grid *Grid) AddChild(content Drawable) *GridCell {
+ cell := &GridCell{
+ RowSpan: 1,
+ ColSpan: 1,
+ Content: content,
+ invalid: true,
+ }
grid.Cells = append(grid.Cells, cell)
cell.Content.OnInvalidate(grid.cellInvalidated)
cell.invalid = true
- grid.InvalidateLayout()
+ grid.invalidateLayout()
+ return cell
}
func (grid *Grid) RemoveChild(cell *GridCell) {
@@ -120,7 +160,7 @@ func (grid *Grid) RemoveChild(cell *GridCell) {
break
}
}
- grid.InvalidateLayout()
+ grid.invalidateLayout()
}
func (grid *Grid) cellInvalidated(drawable Drawable) {