forked from go/golangs_learn
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
166 lines
3.7 KiB
166 lines
3.7 KiB
package main
|
|
|
|
import (
|
|
"fmt"
|
|
"image"
|
|
"image/color"
|
|
"log"
|
|
"os"
|
|
"strconv"
|
|
|
|
"gioui.org/app"
|
|
"gioui.org/font/gofont"
|
|
"gioui.org/io/system"
|
|
"gioui.org/layout"
|
|
"gioui.org/op"
|
|
"gioui.org/op/clip"
|
|
"gioui.org/op/paint"
|
|
"gioui.org/unit"
|
|
"gioui.org/widget"
|
|
"gioui.org/widget/material"
|
|
"gioui.org/x/outlay"
|
|
)
|
|
|
|
func main() {
|
|
go func() {
|
|
w := app.NewWindow(
|
|
app.Size(unit.Dp(800), unit.Dp(400)),
|
|
app.Title("Gio layouts"),
|
|
)
|
|
if err := loop(w); err != nil {
|
|
log.Fatal(err)
|
|
}
|
|
os.Exit(0)
|
|
}()
|
|
app.Main()
|
|
}
|
|
|
|
func loop(w *app.Window) error {
|
|
var table = uiTable{
|
|
theme: material.NewTheme(gofont.Collection()),
|
|
Table: outlay.Table{
|
|
CellSize: func(m unit.Metric, x, y int) image.Point {
|
|
return image.Pt(m.Px(unit.Dp(50)), m.Px(unit.Dp(30)))
|
|
},
|
|
},
|
|
}
|
|
|
|
var ops op.Ops
|
|
for e := range w.Events() {
|
|
switch e := e.(type) {
|
|
case system.DestroyEvent:
|
|
return e.Err
|
|
|
|
case system.FrameEvent:
|
|
gtx := layout.NewContext(&ops, e)
|
|
table.Layout(gtx)
|
|
e.Frame(gtx.Ops)
|
|
}
|
|
}
|
|
return nil
|
|
}
|
|
|
|
type uiTable struct {
|
|
theme *material.Theme
|
|
xed, yed widget.Editor
|
|
cells []cell
|
|
outlay.Table
|
|
}
|
|
|
|
type cell struct {
|
|
click widget.Clickable
|
|
clicked bool
|
|
}
|
|
|
|
func (t *uiTable) Layout(gtx layout.Context) layout.Dimensions {
|
|
th := t.theme
|
|
return layout.Flex{
|
|
Axis: layout.Vertical,
|
|
}.Layout(gtx,
|
|
layout.Rigid(func(gtx layout.Context) layout.Dimensions {
|
|
return layout.Flex{
|
|
Axis: layout.Horizontal,
|
|
Spacing: layout.SpaceSides,
|
|
}.Layout(gtx,
|
|
layout.Rigid(material.Body1(th, "Number of columns: ").Layout),
|
|
layout.Rigid(material.Editor(th, &t.xed, "columns").Layout),
|
|
)
|
|
}),
|
|
layout.Rigid(func(gtx layout.Context) layout.Dimensions {
|
|
return layout.Flex{
|
|
Axis: layout.Horizontal,
|
|
Spacing: layout.SpaceSides,
|
|
}.Layout(gtx,
|
|
layout.Rigid(material.Body1(th, "Number of rows: ").Layout),
|
|
layout.Rigid(material.Editor(th, &t.yed, "rows").Layout),
|
|
)
|
|
}),
|
|
layout.Rigid(func(gtx layout.Context) layout.Dimensions {
|
|
return layout.Flex{
|
|
Axis: layout.Horizontal,
|
|
Spacing: layout.SpaceSides,
|
|
}.Layout(gtx,
|
|
layout.Rigid(func(gtx layout.Context) layout.Dimensions {
|
|
var selected int
|
|
for i := range t.cells {
|
|
if t.cells[i].clicked {
|
|
selected++
|
|
}
|
|
}
|
|
var txt string
|
|
switch selected {
|
|
case 0:
|
|
txt = "Click cells to select them."
|
|
case 1:
|
|
txt = fmt.Sprint("1 cell selected. Click again to unselect.")
|
|
default:
|
|
txt = fmt.Sprintf("%d cells selected. Click again to unselect.", selected)
|
|
}
|
|
return material.Body1(th, txt).Layout(gtx)
|
|
}),
|
|
)
|
|
}),
|
|
layout.Flexed(1, func(gtx layout.Context) layout.Dimensions {
|
|
xn, _ := strconv.Atoi(t.xed.Text())
|
|
yn, _ := strconv.Atoi(t.yed.Text())
|
|
t.cells = growCells(t.cells, xn*yn)
|
|
return t.Table.Layout(gtx, xn, yn, func(gtx layout.Context, x, y int) layout.Dimensions {
|
|
c := &t.cells[x+y*xn]
|
|
return c.Layout(gtx, th, x, y)
|
|
})
|
|
}),
|
|
)
|
|
}
|
|
|
|
func (c *cell) Layout(gtx layout.Context, th *material.Theme, x, y int) layout.Dimensions {
|
|
var txt string
|
|
if y < 0 {
|
|
txt = fmt.Sprintf("item %d", x)
|
|
} else {
|
|
txt = fmt.Sprintf("%dx%d", x, y)
|
|
}
|
|
macro := op.Record(gtx.Ops)
|
|
dims := material.Clickable(gtx, &c.click, func(gtx layout.Context) layout.Dimensions {
|
|
return layout.Center.Layout(gtx, material.Body1(th, txt).Layout)
|
|
})
|
|
call := macro.Stop()
|
|
|
|
if c.click.Clicked() {
|
|
c.clicked = !c.clicked
|
|
}
|
|
defer clip.Rect{Max: dims.Size}.Push(gtx.Ops).Pop()
|
|
col := color.NRGBA{R: 255, G: 255, B: 255, A: 255}
|
|
if c.clicked {
|
|
col = color.NRGBA{R: 128, G: 128, B: 128, A: 255}
|
|
}
|
|
paint.Fill(gtx.Ops, col)
|
|
call.Add(gtx.Ops)
|
|
return dims
|
|
}
|
|
|
|
func growCells(cells []cell, n int) []cell {
|
|
if len(cells) < n {
|
|
cells = append(cells, make([]cell, n-len(cells))...)
|
|
}
|
|
return cells[:n]
|
|
}
|
|
|