~eliasnaur/gio-example

ref: 8a3a65c8c0340253beaba1c2e5687a000fa74789 gio-example/life/style.go -rw-r--r-- 2.0 KiB
8a3a65c8Chris Waldon gio-extras/*,x: rename gio-extras demos and change imports 9 months ago
                                                                                
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
// SPDX-License-Identifier: Unlicense OR MIT

package main

import (
	"image"
	"image/color"

	"gioui.org/f32"        // f32 is used for shape calculations.
	"gioui.org/io/pointer" // system is used for system events (e.g. closing the window).
	"gioui.org/layout"     // layout is used for layouting widgets.
	"gioui.org/op"         // op is used for recording different operations.
	"gioui.org/op/clip"    // clip is used to draw the cell shape.
	"gioui.org/op/paint"   // paint is used to paint the cells.
)

// BoardStyle draws Board with rectangles.
type BoardStyle struct {
	CellSizePx int
	*Board
}

// Layout draws the Board and accepts input for adding alive cells.
func (board BoardStyle) Layout(gtx layout.Context) layout.Dimensions {
	defer op.Push(gtx.Ops).Pop()

	// Calculate the board size based on the cell size in pixels.
	size := board.Size.Mul(board.CellSizePx)
	gtx.Constraints = layout.Exact(size)

	// Handle any input from a pointer.
	for _, ev := range gtx.Events(board.Board) {
		if ev, ok := ev.(pointer.Event); ok {
			p := image.Pt(int(ev.Position.X), int(ev.Position.Y))
			// Calculate the board coordinate given a cursor position.
			p = p.Div(board.CellSizePx)
			board.SetWithoutWrap(p)
		}
	}
	// Register to listen for pointer Drag events.
	pointer.Rect(image.Rectangle{Max: size}).Add(gtx.Ops)
	pointer.InputOp{Tag: board.Board, Types: pointer.Drag}.Add(gtx.Ops)

	cellSize := float32(board.CellSizePx)

	// Draw a shape for each alive cell.
	var p clip.Path
	p.Begin(gtx.Ops)
	for i, v := range board.Cells {
		if v == 0 {
			continue
		}

		c := layout.FPt(board.Pt(i).Mul(board.CellSizePx))
		p.MoveTo(f32.Pt(c.X, c.Y))
		p.LineTo(f32.Pt(c.X+cellSize, c.Y))
		p.LineTo(f32.Pt(c.X+cellSize, c.Y+cellSize))
		p.LineTo(f32.Pt(c.X, c.Y+cellSize))
		p.Close()
	}
	clip.Outline{Path: p.End()}.Op().Add(gtx.Ops)

	// Paint the shape with a black color.
	paint.ColorOp{Color: color.NRGBA{A: 0xFF}}.Add(gtx.Ops)
	paint.PaintOp{}.Add(gtx.Ops)

	return layout.Dimensions{Size: size}
}