all: make pointer.Area an interface

With an interface instead of anonymous functions, amending an
area's parameters can be done even after adding it to an OpHandler.

This will be useful when we switch to serialized op lists.

Signed-off-by: Elias Naur <mail@eliasnaur.com>
This commit is contained in:
Elias Naur
2019-04-24 15:39:53 +02:00
parent 3ad94ed20e
commit a8bb3c2f14
6 changed files with 34 additions and 28 deletions
+2 -2
View File
@@ -498,7 +498,7 @@ func (a *ActionButton) Layout(cs layout.Constraints) (ui.Op, layout.Dimens) {
layout.Margins{Top: ui.Dp(4)}, layout.Margins{Top: ui.Dp(4)},
layout.F(func(cs layout.Constraints) (ui.Op, layout.Dimens) { layout.F(func(cs layout.Constraints) (ui.Op, layout.Dimens) {
op, dims := fab(c, a.sendIco.image(c), fabCol, ui.Dp(56)).Layout(cs) op, dims := fab(c, a.sendIco.image(c), fabCol, ui.Dp(56)).Layout(cs)
ops := ui.Ops{op, a.btnClicker.Op(gesture.Ellipse(dims.Size))} ops := ui.Ops{op, a.btnClicker.Op(&gesture.Ellipse{dims.Size})}
return ops, dims return ops, dims
}), }),
)) ))
@@ -556,7 +556,7 @@ func (a *App) user(c *ui.Config, index int) layout.Widget {
Layout() Layout()
}), }),
).Layout(cs) ).Layout(cs)
ops := ui.Ops{op, click.Op(gesture.Rect(dims.Size))} ops := ui.Ops{op, click.Op(&gesture.Rect{dims.Size})}
return ops, dims return ops, dims
})) }))
return elem.Layout() return elem.Layout()
+25 -21
View File
@@ -37,6 +37,14 @@ type Scroll struct {
scroll float32 scroll float32
} }
type Rect struct {
Size image.Point
}
type Ellipse struct {
Size image.Point
}
type flinger struct { type flinger struct {
// Current offset in pixels. // Current offset in pixels.
x float32 x float32
@@ -254,30 +262,26 @@ func (f *flinger) Tick(now time.Time) int {
return idist return idist
} }
func Rect(sz image.Point) pointer.Area { func (r *Rect) Hit(pos f32.Point) pointer.HitResult {
return func(pos f32.Point) pointer.HitResult { if 0 <= pos.X && pos.X < float32(r.Size.X) &&
if 0 <= pos.X && pos.X < float32(sz.X) && 0 <= pos.Y && pos.Y < float32(r.Size.Y) {
0 <= pos.Y && pos.Y < float32(sz.Y) { return pointer.HitOpaque
return pointer.HitOpaque } else {
} else { return pointer.HitNone
return pointer.HitNone
}
} }
} }
func Ellipse(sz image.Point) pointer.Area { func (e *Ellipse) Hit(pos f32.Point) pointer.HitResult {
return func(pos f32.Point) pointer.HitResult { rx := float32(e.Size.X) / 2
rx := float32(sz.X) / 2 ry := float32(e.Size.Y) / 2
ry := float32(sz.Y) / 2 rx2 := rx * rx
rx2 := rx * rx ry2 := ry * ry
ry2 := ry * ry xh := pos.X - rx
xh := pos.X - rx yk := pos.Y - ry
yk := pos.Y - ry if xh*xh*ry2+yk*yk*rx2 <= rx2*ry2 {
if xh*xh*ry2+yk*yk*rx2 <= rx2*ry2 { return pointer.HitOpaque
return pointer.HitOpaque } else {
} else { return pointer.HitNone
return pointer.HitNone
}
} }
} }
+1 -1
View File
@@ -83,7 +83,7 @@ func (l *List) Index() (int, bool) {
} }
func (l *List) Layout() (ui.Op, Dimens) { func (l *List) Layout() (ui.Op, Dimens) {
ops := append(ui.Ops{l.scroll.Op(gesture.Rect(l.size))}, l.ops...) ops := append(ui.Ops{l.scroll.Op(&gesture.Rect{l.size})}, l.ops...)
return ops, Dimens{Size: l.size} return ops, Dimens{Size: l.size}
} }
+3 -1
View File
@@ -25,7 +25,9 @@ type OpHandler struct {
Grab bool Grab bool
} }
type Area func(pos f32.Point) HitResult type Area interface {
Hit(pos f32.Point) HitResult
}
type Key interface{} type Key interface{}
+2 -2
View File
@@ -101,7 +101,7 @@ func (q *Queue) opHit(handlers *[]Key, op ui.Op, pos f32.Point) (HitResult, bool
return HitNone, false return HitNone, false
} }
tpos := h.transform.InvTransform(pos) tpos := h.transform.InvTransform(pos)
res := h.area(tpos) res := h.area.Hit(tpos)
if res != HitNone { if res != HitNone {
*handlers = append(*handlers, op.Key) *handlers = append(*handlers, op.Key)
} }
@@ -229,7 +229,7 @@ func (q *Queue) Push(e Event) {
e.Priority = Foremost e.Priority = Foremost
} }
e.Position = h.transform.InvTransform(e.Position) e.Position = h.transform.InvTransform(e.Position)
e.Hit = h.area(e.Position) != HitNone e.Hit = h.area.Hit(e.Position) != HitNone
h.events = append(h.events, e) h.events = append(h.events, e)
if e.Type == Release { if e.Type == Release {
// Release grab when the number of grabs reaches zero. // Release grab when the number of grabs reaches zero.
+1 -1
View File
@@ -206,7 +206,7 @@ func (e *Editor) Layout(cs layout.Constraints) (ui.Op, layout.Dimens) {
} }
baseline := e.padTop + e.dims.Baseline baseline := e.padTop + e.dims.Baseline
area := gesture.Rect(e.viewSize) area := &gesture.Rect{e.viewSize}
e.ops = append(e.ops, e.scroller.Op(area), e.clicker.Op(area)) e.ops = append(e.ops, e.scroller.Op(area), e.clicker.Op(area))
return e.ops, layout.Dimens{Size: e.viewSize, Baseline: baseline} return e.ops, layout.Dimens{Size: e.viewSize, Baseline: baseline}
} }