mirror of
https://git.sr.ht/~eliasnaur/gio
synced 2026-07-07 18:35:34 +00:00
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:
+2
-2
@@ -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
@@ -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
@@ -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
@@ -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
|
||||||
|
|||||||
@@ -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)
|
||||||
|
|||||||
Reference in New Issue
Block a user