~pierrec/giox

ref: f2af8f824417422c9374715fb0229001c073a3f7 giox/widgetx/modal.go -rw-r--r-- 1.4 KiB
f2af8f82pierre widgetx/materialx: added comments to ModalAlertStyle 10 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
package widgetx

import (
	"image"
	"image/color"

	"gioui.org/io/key"
	"gioui.org/io/pointer"
	"gioui.org/layout"
	"gioui.org/op"
	"gioui.org/op/clip"
	"gioui.org/op/paint"
	"gioui.org/widget"
)

// Modal displays a widget and deactivates its background by grabbing
// keyboard and mouse events as specified by the Release fields.
type Modal struct {
	Background   color.NRGBA
	ReleaseKeys  bool
	ReleaseMouse bool
	click        widget.Clickable
	changed      bool
}

func (m *Modal) update(gtx layout.Context) {
	if m.click.Clicked() {
		m.changed = true
		op.InvalidateOp{}.Add(gtx.Ops)
		return
	}
	for _, ev := range gtx.Events(m) {
		if e, ok := ev.(key.Event); ok && e.Name == key.NameEscape {
			m.changed = true
			break
		}
	}
}

// Layout displays the modal as a defer operation.
func (m *Modal) Layout(gtx layout.Context) layout.Dimensions {
	m.update(gtx)
	macro := op.Record(gtx.Ops)
	size := gtx.Constraints.Min
	if !m.ReleaseKeys {
		key.InputOp{Tag: m}.Add(gtx.Ops)
		key.FocusOp{Tag: m}.Add(gtx.Ops)
	}
	if !m.ReleaseMouse {
		pointer.Rect(image.Rectangle{Max: size}).Add(gtx.Ops)
		m.click.Layout(gtx)
	}
	paint.FillShape(gtx.Ops, m.Background, clip.Rect{Max: size}.Op())
	op.Defer(gtx.Ops, macro.Stop())
	return layout.Dimensions{Size: size}
}

// Changed returns whether or not the area was clicked or ESC was pressed.
func (m *Modal) Changed() bool {
	changed := m.changed
	m.changed = false
	return changed
}