mirror of
https://git.sr.ht/~eliasnaur/gio
synced 2026-07-02 16:06:19 +00:00
ui/pointer: split AreaOp into RectAreaOp and EllipseAreaOp
Now that the pass through mode is moved into its own PassOp op, it doesn't make sense to collect all area types into one exported type. Add RectAreaOp and EllipseAreaOp for clients; the internal representation is still a single op. It can be changed later without breaking clients. Signed-off-by: Elias Naur <mail@eliasnaur.com>
This commit is contained in:
+58
-2
@@ -3,6 +3,9 @@
|
||||
package input
|
||||
|
||||
import (
|
||||
"encoding/binary"
|
||||
"image"
|
||||
|
||||
"gioui.org/ui"
|
||||
"gioui.org/ui/f32"
|
||||
"gioui.org/ui/internal/ops"
|
||||
@@ -41,12 +44,24 @@ type pointerHandler struct {
|
||||
wantsGrab bool
|
||||
}
|
||||
|
||||
type areaOp struct {
|
||||
kind areaKind
|
||||
size image.Point
|
||||
}
|
||||
|
||||
type areaNode struct {
|
||||
trans ui.Transform
|
||||
next int
|
||||
area pointer.AreaOp
|
||||
area areaOp
|
||||
}
|
||||
|
||||
type areaKind uint8
|
||||
|
||||
const (
|
||||
areaRect areaKind = iota
|
||||
areaEllipse
|
||||
)
|
||||
|
||||
func (q *pointerQueue) collectHandlers(r *ui.OpsReader, events handlerEvents, t ui.Transform, area, node int, pass bool) {
|
||||
for {
|
||||
encOp, ok := r.Decode()
|
||||
@@ -63,7 +78,7 @@ func (q *pointerQueue) collectHandlers(r *ui.OpsReader, events handlerEvents, t
|
||||
op.Decode(encOp.Data)
|
||||
pass = op.Pass
|
||||
case ops.TypeArea:
|
||||
var op pointer.AreaOp
|
||||
var op areaOp
|
||||
op.Decode(encOp.Data)
|
||||
q.areas = append(q.areas, areaNode{trans: t, next: area, area: op})
|
||||
area = len(q.areas) - 1
|
||||
@@ -257,3 +272,44 @@ func (q *pointerQueue) Push(e pointer.Event, events handlerEvents) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (op *areaOp) Decode(d []byte) {
|
||||
if ops.OpType(d[0]) != ops.TypeArea {
|
||||
panic("invalid op")
|
||||
}
|
||||
bo := binary.LittleEndian
|
||||
size := image.Point{
|
||||
X: int(bo.Uint32(d[2:])),
|
||||
Y: int(bo.Uint32(d[6:])),
|
||||
}
|
||||
*op = areaOp{
|
||||
kind: areaKind(d[1]),
|
||||
size: size,
|
||||
}
|
||||
}
|
||||
|
||||
func (op *areaOp) Hit(pos f32.Point) bool {
|
||||
switch op.kind {
|
||||
case areaRect:
|
||||
if 0 <= pos.X && pos.X < float32(op.size.X) &&
|
||||
0 <= pos.Y && pos.Y < float32(op.size.Y) {
|
||||
return true
|
||||
} else {
|
||||
return false
|
||||
}
|
||||
case areaEllipse:
|
||||
rx := float32(op.size.X) / 2
|
||||
ry := float32(op.size.Y) / 2
|
||||
rx2 := rx * rx
|
||||
ry2 := ry * ry
|
||||
xh := pos.X - rx
|
||||
yk := pos.Y - ry
|
||||
if xh*xh*ry2+yk*yk*rx2 <= rx2*ry2 {
|
||||
return true
|
||||
} else {
|
||||
return false
|
||||
}
|
||||
default:
|
||||
panic("invalid area kind")
|
||||
}
|
||||
}
|
||||
|
||||
+1
-1
@@ -209,7 +209,7 @@ func (l *List) Layout() Dimens {
|
||||
}
|
||||
dims := axisPoint(l.Axis, mainc.Constrain(pos), maxCross)
|
||||
block := ops.End()
|
||||
pointer.AreaRect(dims).Add(ops)
|
||||
pointer.RectAreaOp{Size: dims}.Add(ops)
|
||||
l.scroll.Add(ops)
|
||||
block.Add(ops)
|
||||
return Dimens{Size: dims}
|
||||
|
||||
+20
-51
@@ -23,7 +23,16 @@ type Event struct {
|
||||
Scroll f32.Point
|
||||
}
|
||||
|
||||
type AreaOp struct {
|
||||
type RectAreaOp struct {
|
||||
Size image.Point
|
||||
}
|
||||
|
||||
type EllipseAreaOp struct {
|
||||
Size image.Point
|
||||
}
|
||||
|
||||
// Must match the structure in input.areaOp
|
||||
type areaOp struct {
|
||||
kind areaKind
|
||||
size image.Point
|
||||
}
|
||||
@@ -46,6 +55,7 @@ type Type uint8
|
||||
type Priority uint8
|
||||
type Source uint8
|
||||
|
||||
// Must match input.areaKind
|
||||
type areaKind uint8
|
||||
|
||||
const (
|
||||
@@ -71,21 +81,21 @@ const (
|
||||
areaEllipse
|
||||
)
|
||||
|
||||
func AreaRect(size image.Point) AreaOp {
|
||||
return AreaOp{
|
||||
func (op RectAreaOp) Add(ops *ui.Ops) {
|
||||
areaOp{
|
||||
kind: areaRect,
|
||||
size: size,
|
||||
}
|
||||
size: op.Size,
|
||||
}.add(ops)
|
||||
}
|
||||
|
||||
func AreaEllipse(size image.Point) AreaOp {
|
||||
return AreaOp{
|
||||
func (op EllipseAreaOp) Add(ops *ui.Ops) {
|
||||
areaOp{
|
||||
kind: areaEllipse,
|
||||
size: size,
|
||||
}
|
||||
size: op.Size,
|
||||
}.add(ops)
|
||||
}
|
||||
|
||||
func (op AreaOp) Add(o *ui.Ops) {
|
||||
func (op areaOp) add(o *ui.Ops) {
|
||||
data := make([]byte, ops.TypeAreaLen)
|
||||
data[0] = byte(ops.TypeArea)
|
||||
data[1] = byte(op.kind)
|
||||
@@ -95,47 +105,6 @@ func (op AreaOp) Add(o *ui.Ops) {
|
||||
o.Write(data)
|
||||
}
|
||||
|
||||
func (op *AreaOp) Decode(d []byte) {
|
||||
if ops.OpType(d[0]) != ops.TypeArea {
|
||||
panic("invalid op")
|
||||
}
|
||||
bo := binary.LittleEndian
|
||||
size := image.Point{
|
||||
X: int(bo.Uint32(d[2:])),
|
||||
Y: int(bo.Uint32(d[6:])),
|
||||
}
|
||||
*op = AreaOp{
|
||||
kind: areaKind(d[1]),
|
||||
size: size,
|
||||
}
|
||||
}
|
||||
|
||||
func (op *AreaOp) Hit(pos f32.Point) bool {
|
||||
switch op.kind {
|
||||
case areaRect:
|
||||
if 0 <= pos.X && pos.X < float32(op.size.X) &&
|
||||
0 <= pos.Y && pos.Y < float32(op.size.Y) {
|
||||
return true
|
||||
} else {
|
||||
return false
|
||||
}
|
||||
case areaEllipse:
|
||||
rx := float32(op.size.X) / 2
|
||||
ry := float32(op.size.Y) / 2
|
||||
rx2 := rx * rx
|
||||
ry2 := ry * ry
|
||||
xh := pos.X - rx
|
||||
yk := pos.Y - ry
|
||||
if xh*xh*ry2+yk*yk*rx2 <= rx2*ry2 {
|
||||
return true
|
||||
} else {
|
||||
return false
|
||||
}
|
||||
default:
|
||||
panic("invalid area kind")
|
||||
}
|
||||
}
|
||||
|
||||
func (h HandlerOp) Add(o *ui.Ops) {
|
||||
data := make([]byte, ops.TypePointerHandlerLen)
|
||||
data[0] = byte(ops.TypePointerHandler)
|
||||
|
||||
+1
-1
@@ -259,7 +259,7 @@ func (e *Editor) Layout(ops *ui.Ops, cs layout.Constraints) layout.Dimens {
|
||||
ui.PopOp{}.Add(ops)
|
||||
|
||||
baseline := e.padTop + e.dims.Baseline
|
||||
pointer.AreaRect(e.viewSize).Add(ops)
|
||||
pointer.RectAreaOp{Size: e.viewSize}.Add(ops)
|
||||
e.scroller.Add(ops)
|
||||
e.clicker.Add(ops)
|
||||
return layout.Dimens{Size: e.viewSize, Baseline: baseline}
|
||||
|
||||
Reference in New Issue
Block a user