diff options
Diffstat (limited to 'ui/grid.go')
-rw-r--r-- | ui/grid.go | 70 |
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) { |