ref: 1a9e03bf68dc38df757f26d84b10bb2398b1602a gio/ui/pointer/pointer.go -rw-r--r-- 2.5 KiB View raw
                                                                                
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
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
// SPDX-License-Identifier: Unlicense OR MIT

package pointer

import (
	"encoding/binary"
	"image"
	"time"

	"gioui.org/ui"
	"gioui.org/ui/f32"
	"gioui.org/ui/input"
	"gioui.org/ui/internal/opconst"
)

type Event struct {
	Type      Type
	Source    Source
	PointerID ID
	Priority  Priority
	Time      time.Duration
	Hit       bool
	Position  f32.Point
	Scroll    f32.Point
}

type RectAreaOp struct {
	Rect image.Rectangle
}

type EllipseAreaOp struct {
	Rect image.Rectangle
}

// Must match the structure in input.areaOp
type areaOp struct {
	kind areaKind
	rect image.Rectangle
}

type HandlerOp struct {
	Key  input.Key
	Grab bool
}

// PassOp change the current event pass-through
// setting.
type PassOp struct {
	Pass bool
}

type ID uint16
type Type uint8
type Priority uint8
type Source uint8

// Must match input.areaKind
type areaKind uint8

const (
	Cancel Type = iota
	Press
	Release
	Move
)

const (
	Mouse Source = iota
	Touch
)

const (
	Shared Priority = iota
	Foremost
	Grabbed
)

const (
	areaRect areaKind = iota
	areaEllipse
)

func (op RectAreaOp) Add(ops *ui.Ops) {
	areaOp{
		kind: areaRect,
		rect: op.Rect,
	}.add(ops)
}

func (op EllipseAreaOp) Add(ops *ui.Ops) {
	areaOp{
		kind: areaEllipse,
		rect: op.Rect,
	}.add(ops)
}

func (op areaOp) add(o *ui.Ops) {
	data := make([]byte, opconst.TypeAreaLen)
	data[0] = byte(opconst.TypeArea)
	data[1] = byte(op.kind)
	bo := binary.LittleEndian
	bo.PutUint32(data[2:], uint32(op.rect.Min.X))
	bo.PutUint32(data[6:], uint32(op.rect.Min.Y))
	bo.PutUint32(data[10:], uint32(op.rect.Max.X))
	bo.PutUint32(data[14:], uint32(op.rect.Max.Y))
	o.Write(data)
}

func (h HandlerOp) Add(o *ui.Ops) {
	data := make([]byte, opconst.TypePointerHandlerLen)
	data[0] = byte(opconst.TypePointerHandler)
	if h.Grab {
		data[1] = 1
	}
	o.Write(data, h.Key)
}

func (op PassOp) Add(o *ui.Ops) {
	data := make([]byte, opconst.TypePassLen)
	data[0] = byte(opconst.TypePass)
	if op.Pass {
		data[1] = 1
	}
	o.Write(data)
}

func (t Type) String() string {
	switch t {
	case Press:
		return "Press"
	case Release:
		return "Release"
	case Cancel:
		return "Cancel"
	case Move:
		return "Move"
	default:
		panic("unknown Type")
	}
}

func (p Priority) String() string {
	switch p {
	case Shared:
		return "Shared"
	case Foremost:
		return "Foremost"
	case Grabbed:
		return "Grabbed"
	default:
		panic("unknown priority")
	}
}

func (s Source) String() string {
	switch s {
	case Mouse:
		return "Mouse"
	case Touch:
		return "Touch"
	default:
		panic("unknown source")
	}
}

func (Event) ImplementsEvent() {}