io/router: use integer coordinates for bounds

There is no need for floating point coordinates, except for transforming
bounds and hit testing.

Signed-off-by: Elias Naur <mail@eliasnaur.com>
This commit is contained in:
Elias Naur
2022-03-30 12:08:48 +02:00
parent 1f11a5a17b
commit e72c46f13c
5 changed files with 26 additions and 26 deletions
+2 -2
View File
@@ -605,7 +605,7 @@ func Java_org_gioui_GioView_initializeAccessibilityNodeInfo(env *C.JNIEnv, class
semID := w.semIDFor(virtID) semID := w.semIDFor(virtID)
sem, found := w.callbacks.LookupSemantic(semID) sem, found := w.callbacks.LookupSemantic(semID)
if found { if found {
off := f32.Pt(float32(screenX), float32(screenY)) off := image.Pt(int(screenX), int(screenY))
if err := w.initAccessibilityNodeInfo(env, sem, off, info); err != nil { if err := w.initAccessibilityNodeInfo(env, sem, off, info); err != nil {
panic(err) panic(err)
} }
@@ -657,7 +657,7 @@ func Java_org_gioui_GioView_onClearA11yFocus(env *C.JNIEnv, class C.jclass, view
} }
} }
func (w *window) initAccessibilityNodeInfo(env *C.JNIEnv, sem router.SemanticNode, off f32.Point, info C.jobject) error { func (w *window) initAccessibilityNodeInfo(env *C.JNIEnv, sem router.SemanticNode, off image.Point, info C.jobject) error {
for _, ch := range sem.Children { for _, ch := range sem.Children {
err := callVoidMethod(env, info, android.accessibilityNodeInfo.addChild, jvalue(w.view), jvalue(w.virtualIDFor(ch.ID))) err := callVoidMethod(env, info, android.accessibilityNodeInfo.addChild, jvalue(w.view), jvalue(w.virtualIDFor(ch.ID)))
if err != nil { if err != nil {
+9 -9
View File
@@ -3,7 +3,7 @@
package router package router
import ( import (
"math" "image"
"sort" "sort"
"gioui.org/f32" "gioui.org/f32"
@@ -54,7 +54,7 @@ type keyCollector struct {
type dirFocusEntry struct { type dirFocusEntry struct {
tag event.Tag tag event.Tag
row int row int
bounds f32.Rectangle bounds image.Rectangle
} }
const ( const (
@@ -150,7 +150,7 @@ func (q *keyQueue) updateFocusLayout() {
end := 1 end := 1
for ; end < len(order); end++ { for ; end < len(order); end++ {
h := &order[end] h := &order[end]
center := (h.bounds.Min.Y + h.bounds.Max.Y) * .5 center := (h.bounds.Min.Y + h.bounds.Max.Y) / 2
if center > bottom { if center > bottom {
break break
} }
@@ -217,14 +217,14 @@ func (q *keyQueue) MoveFocus(dir FocusDirection, events *handlerEvents) {
nextRow = focus.row + delta nextRow = focus.row + delta
} }
var closest event.Tag var closest event.Tag
dist := float32(math.Inf(+1)) dist := int(1e6)
center := (focus.bounds.Min.X + focus.bounds.Max.X) * .5 center := (focus.bounds.Min.X + focus.bounds.Max.X) / 2
loop: loop:
for 0 <= order && order < len(q.dirOrder) { for 0 <= order && order < len(q.dirOrder) {
next := q.dirOrder[order] next := q.dirOrder[order]
switch next.row { switch next.row {
case nextRow: case nextRow:
nextCenter := (next.bounds.Min.X + next.bounds.Max.X) * .5 nextCenter := (next.bounds.Min.X + next.bounds.Max.X) / 2
d := center - nextCenter d := center - nextCenter
if d < 0 { if d < 0 {
d = -d d = -d
@@ -251,7 +251,7 @@ func (q *keyQueue) Push(e event.Event, events *handlerEvents) {
} }
} }
func (q *keyQueue) BoundsFor(t event.Tag) f32.Rectangle { func (q *keyQueue) BoundsFor(t event.Tag) image.Rectangle {
order := q.handlers[t].dirOrder order := q.handlers[t].dirOrder
return q.dirOrder[order].bounds return q.dirOrder[order].bounds
} }
@@ -291,7 +291,7 @@ func (k *keyCollector) softKeyboard(show bool) {
} }
} }
func (k *keyCollector) handlerFor(tag event.Tag, bounds f32.Rectangle) *keyHandler { func (k *keyCollector) handlerFor(tag event.Tag, bounds image.Rectangle) *keyHandler {
h, ok := k.q.handlers[tag] h, ok := k.q.handlers[tag]
if !ok { if !ok {
h = &keyHandler{new: true, order: -1} h = &keyHandler{new: true, order: -1}
@@ -305,7 +305,7 @@ func (k *keyCollector) handlerFor(tag event.Tag, bounds f32.Rectangle) *keyHandl
return h return h
} }
func (k *keyCollector) inputOp(op key.InputOp, bounds f32.Rectangle) { func (k *keyCollector) inputOp(op key.InputOp, bounds image.Rectangle) {
h := k.handlerFor(op.Tag, bounds) h := k.handlerFor(op.Tag, bounds)
h.visible = true h.visible = true
h.hint = op.Hint h.hint = op.Hint
+11 -11
View File
@@ -74,7 +74,7 @@ type pointerHandler struct {
type areaOp struct { type areaOp struct {
kind areaKind kind areaKind
rect f32.Rectangle rect image.Rectangle
} }
type areaNode struct { type areaNode struct {
@@ -153,10 +153,10 @@ func (c *pointerCollector) clip(op ops.ClipOp) {
if op.Shape == ops.Ellipse { if op.Shape == ops.Ellipse {
kind = areaEllipse kind = areaEllipse
} }
c.pushArea(kind, frect(op.Bounds)) c.pushArea(kind, op.Bounds)
} }
func (c *pointerCollector) pushArea(kind areaKind, bounds f32.Rectangle) { func (c *pointerCollector) pushArea(kind areaKind, bounds image.Rectangle) {
parentID := c.currentArea() parentID := c.currentArea()
areaID := len(c.q.areas) areaID := len(c.q.areas)
areaOp := areaOp{kind: kind, rect: bounds} areaOp := areaOp{kind: kind, rect: bounds}
@@ -223,7 +223,7 @@ func (c *pointerCollector) currentArea() int {
return -1 return -1
} }
func (c *pointerCollector) currentAreaBounds() f32.Rectangle { func (c *pointerCollector) currentAreaBounds() image.Rectangle {
a := c.currentArea() a := c.currentArea()
if a == -1 { if a == -1 {
panic("no root area") panic("no root area")
@@ -340,7 +340,7 @@ func (c *pointerCollector) ensureRoot() {
if len(c.q.areas) > 0 { if len(c.q.areas) > 0 {
return return
} }
c.pushArea(areaRect, f32.Rect(-1e6, -1e6, 1e6, 1e6)) c.pushArea(areaRect, image.Rect(-1e6, -1e6, 1e6, 1e6))
// Make it semantic to ensure a single semantic root. // Make it semantic to ensure a single semantic root.
c.q.areas[0].semantic.valid = true c.q.areas[0].semantic.valid = true
} }
@@ -854,8 +854,8 @@ func firstMimeMatch(src, tgt *pointerHandler) (first string, matched bool) {
} }
func (op *areaOp) Hit(pos f32.Point) bool { func (op *areaOp) Hit(pos f32.Point) bool {
pos = pos.Sub(op.rect.Min) pos = pos.Sub(fpt(op.rect.Min))
size := op.rect.Size() size := fpt(op.rect.Size())
switch op.kind { switch op.kind {
case areaRect: case areaRect:
return 0 <= pos.X && pos.X < size.X && return 0 <= pos.X && pos.X < size.X &&
@@ -873,11 +873,11 @@ func (op *areaOp) Hit(pos f32.Point) bool {
} }
} }
func (a *areaNode) bounds() f32.Rectangle { func (a *areaNode) bounds() image.Rectangle {
return f32.Rectangle{ return f32.Rectangle{
Min: a.trans.Transform(a.area.rect.Min), Min: a.trans.Transform(fpt(a.area.rect.Min)),
Max: a.trans.Transform(a.area.rect.Max), Max: a.trans.Transform(fpt(a.area.rect.Max)),
} }.Round()
} }
func setScrollEvent(scroll float32, min, max int) (left, scrolled float32) { func setScrollEvent(scroll float32, min, max int) (left, scrolled float32) {
+3 -3
View File
@@ -77,7 +77,7 @@ type SemanticDesc struct {
Selected bool Selected bool
Disabled bool Disabled bool
Gestures SemanticGestures Gestures SemanticGestures
Bounds f32.Rectangle Bounds image.Rectangle
} }
// SemanticGestures is a bit-set of supported gestures. // SemanticGestures is a bit-set of supported gestures.
@@ -158,9 +158,9 @@ func (q *Router) ClickFocus() {
return return
} }
bounds := q.key.queue.BoundsFor(focus) bounds := q.key.queue.BoundsFor(focus)
center := bounds.Max.Add(bounds.Min).Mul(.5) center := bounds.Max.Add(bounds.Min).Div(2)
e := pointer.Event{ e := pointer.Event{
Position: center, Position: f32.Pt(float32(center.X), float32(center.Y)),
Source: pointer.Touch, Source: pointer.Touch,
} }
e.Type = pointer.Press e.Type = pointer.Press
+1 -1
View File
@@ -91,7 +91,7 @@ func TestSemanticDescription(t *testing.T) {
Selected: true, Selected: true,
Disabled: true, Disabled: true,
Gestures: ClickGesture, Gestures: ClickGesture,
Bounds: f32.Rectangle{Min: f32.Point{X: -1e+06, Y: -1e+06}, Max: f32.Point{X: 1e+06, Y: 1e+06}}, Bounds: image.Rectangle{Min: image.Point{X: -1e+06, Y: -1e+06}, Max: image.Point{X: 1e+06, Y: 1e+06}},
} }
if got != exp { if got != exp {
t.Errorf("semantic description mismatch:\nGot: %+v\nWant: %+v", got, exp) t.Errorf("semantic description mismatch:\nGot: %+v\nWant: %+v", got, exp)