ui/pointer: introduce OpArea for pointer hit testing

Split out OpArea from OpHandler to allow stacked areas in a followup.

Replace hit closures with static shapes (rectangles and ellipses) to
avoid allocations. If needed, generic hit functions can be introduced
again later.

Signed-off-by: Elias Naur <mail@eliasnaur.com>
This commit is contained in:
Elias Naur
2019-06-03 13:09:07 +02:00
parent 559db02035
commit 40856a244e
6 changed files with 108 additions and 58 deletions
+4 -36
View File
@@ -3,7 +3,6 @@
package gesture
import (
"image"
"math"
"runtime"
"time"
@@ -38,14 +37,6 @@ type Scroll struct {
scroll float32
}
type Rect struct {
Size image.Point
}
type Ellipse struct {
Size image.Point
}
type flinger struct {
// Current offset in pixels.
x float32
@@ -84,8 +75,8 @@ const (
thresholdVelocity = 1
)
func (c *Click) Op(ops *ui.Ops, a pointer.Area) {
op := pointer.OpHandler{Area: a, Key: c}
func (c *Click) Add(ops *ui.Ops) {
op := pointer.OpHandler{Key: c}
op.Add(ops)
}
@@ -117,8 +108,8 @@ func (c *Click) Update(q pointer.Events) []ClickEvent {
return events
}
func (s *Scroll) Op(ops *ui.Ops, a pointer.Area) {
oph := pointer.OpHandler{Area: a, Key: s, Grab: s.grab}
func (s *Scroll) Add(ops *ui.Ops) {
oph := pointer.OpHandler{Key: s, Grab: s.grab}
oph.Add(ops)
if s.flinger.Active() {
ui.OpRedraw{}.Add(ops)
@@ -264,29 +255,6 @@ func (f *flinger) Tick(now time.Time) int {
return idist
}
func (r *Rect) Hit(pos f32.Point) pointer.HitResult {
if 0 <= pos.X && pos.X < float32(r.Size.X) &&
0 <= pos.Y && pos.Y < float32(r.Size.Y) {
return pointer.HitOpaque
} else {
return pointer.HitNone
}
}
func (e *Ellipse) Hit(pos f32.Point) pointer.HitResult {
rx := float32(e.Size.X) / 2
ry := float32(e.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 pointer.HitOpaque
} else {
return pointer.HitNone
}
}
func (a Axis) String() string {
switch a {
case Horizontal: