pointer.go 25 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018
  1. // SPDX-License-Identifier: Unlicense OR MIT
  2. package input
  3. import (
  4. "image"
  5. "io"
  6. "gioui.org/f32"
  7. f32internal "gioui.org/internal/f32"
  8. "gioui.org/internal/ops"
  9. "gioui.org/io/event"
  10. "gioui.org/io/pointer"
  11. "gioui.org/io/semantic"
  12. "gioui.org/io/system"
  13. "gioui.org/io/transfer"
  14. )
  15. type pointerQueue struct {
  16. hitTree []hitNode
  17. areas []areaNode
  18. semantic struct {
  19. idsAssigned bool
  20. lastID SemanticID
  21. // contentIDs maps semantic content to a list of semantic IDs
  22. // previously assigned. It is used to maintain stable IDs across
  23. // frames.
  24. contentIDs map[semanticContent][]semanticID
  25. }
  26. }
  27. type hitNode struct {
  28. next int
  29. area int
  30. // For handler nodes.
  31. tag event.Tag
  32. pass bool
  33. }
  34. // pointerState is the input state related to pointer events.
  35. type pointerState struct {
  36. cursor pointer.Cursor
  37. pointers []pointerInfo
  38. }
  39. type pointerInfo struct {
  40. id pointer.ID
  41. pressed bool
  42. handlers []event.Tag
  43. // last tracks the last pointer event received,
  44. // used while processing frame events.
  45. last pointer.Event
  46. // entered tracks the tags that contain the pointer.
  47. entered []event.Tag
  48. dataSource event.Tag // dragging source tag
  49. dataTarget event.Tag // dragging target tag
  50. }
  51. type pointerHandler struct {
  52. // areaPlusOne is the index into the list of pointerQueue.areas, plus 1.
  53. areaPlusOne int
  54. // setup tracks whether the handler has received
  55. // the pointer.Cancel event that resets its state.
  56. setup bool
  57. }
  58. // pointerFilter represents the union of a set of pointer filters.
  59. type pointerFilter struct {
  60. kinds pointer.Kind
  61. // min and max horizontal/vertical scroll
  62. scrollX, scrollY pointer.ScrollRange
  63. sourceMimes []string
  64. targetMimes []string
  65. }
  66. type areaOp struct {
  67. kind areaKind
  68. rect image.Rectangle
  69. }
  70. type areaNode struct {
  71. trans f32.Affine2D
  72. area areaOp
  73. cursor pointer.Cursor
  74. // Tree indices, with -1 being the sentinel.
  75. parent int
  76. firstChild int
  77. lastChild int
  78. sibling int
  79. semantic struct {
  80. valid bool
  81. id SemanticID
  82. content semanticContent
  83. }
  84. action system.Action
  85. }
  86. type areaKind uint8
  87. // collectState represents the state for pointerCollector.
  88. type collectState struct {
  89. t f32.Affine2D
  90. // nodePlusOne is the current node index, plus one to
  91. // make the zero value collectState the initial state.
  92. nodePlusOne int
  93. pass int
  94. }
  95. // pointerCollector tracks the state needed to update an pointerQueue
  96. // from pointer ops.
  97. type pointerCollector struct {
  98. q *pointerQueue
  99. state collectState
  100. nodeStack []int
  101. }
  102. type semanticContent struct {
  103. tag event.Tag
  104. label string
  105. desc string
  106. class semantic.ClassOp
  107. gestures SemanticGestures
  108. selected bool
  109. disabled bool
  110. }
  111. type semanticID struct {
  112. id SemanticID
  113. used bool
  114. }
  115. const (
  116. areaRect areaKind = iota
  117. areaEllipse
  118. )
  119. func (c *pointerCollector) resetState() {
  120. c.state = collectState{}
  121. c.nodeStack = c.nodeStack[:0]
  122. // Pop every node except the root.
  123. if len(c.q.hitTree) > 0 {
  124. c.state.nodePlusOne = 0 + 1
  125. }
  126. }
  127. func (c *pointerCollector) setTrans(t f32.Affine2D) {
  128. c.state.t = t
  129. }
  130. func (c *pointerCollector) clip(op ops.ClipOp) {
  131. kind := areaRect
  132. if op.Shape == ops.Ellipse {
  133. kind = areaEllipse
  134. }
  135. c.pushArea(kind, op.Bounds)
  136. }
  137. func (c *pointerCollector) pushArea(kind areaKind, bounds image.Rectangle) {
  138. parentID := c.currentArea()
  139. areaID := len(c.q.areas)
  140. areaOp := areaOp{kind: kind, rect: bounds}
  141. if parentID != -1 {
  142. parent := &c.q.areas[parentID]
  143. if parent.firstChild == -1 {
  144. parent.firstChild = areaID
  145. }
  146. if siblingID := parent.lastChild; siblingID != -1 {
  147. c.q.areas[siblingID].sibling = areaID
  148. }
  149. parent.lastChild = areaID
  150. }
  151. an := areaNode{
  152. trans: c.state.t,
  153. area: areaOp,
  154. parent: parentID,
  155. sibling: -1,
  156. firstChild: -1,
  157. lastChild: -1,
  158. }
  159. c.q.areas = append(c.q.areas, an)
  160. c.nodeStack = append(c.nodeStack, c.state.nodePlusOne-1)
  161. c.addHitNode(hitNode{
  162. area: areaID,
  163. pass: true,
  164. })
  165. }
  166. func (c *pointerCollector) popArea() {
  167. n := len(c.nodeStack)
  168. c.state.nodePlusOne = c.nodeStack[n-1] + 1
  169. c.nodeStack = c.nodeStack[:n-1]
  170. }
  171. func (c *pointerCollector) pass() {
  172. c.state.pass++
  173. }
  174. func (c *pointerCollector) popPass() {
  175. c.state.pass--
  176. }
  177. func (c *pointerCollector) currentArea() int {
  178. if i := c.state.nodePlusOne - 1; i != -1 {
  179. n := c.q.hitTree[i]
  180. return n.area
  181. }
  182. return -1
  183. }
  184. func (c *pointerCollector) currentAreaBounds() image.Rectangle {
  185. a := c.currentArea()
  186. if a == -1 {
  187. panic("no root area")
  188. }
  189. return c.q.areas[a].bounds()
  190. }
  191. func (c *pointerCollector) addHitNode(n hitNode) {
  192. n.next = c.state.nodePlusOne - 1
  193. c.q.hitTree = append(c.q.hitTree, n)
  194. c.state.nodePlusOne = len(c.q.hitTree) - 1 + 1
  195. }
  196. // newHandler returns the current handler or a new one for tag.
  197. func (c *pointerCollector) newHandler(tag event.Tag, state *pointerHandler) {
  198. areaID := c.currentArea()
  199. c.addHitNode(hitNode{
  200. area: areaID,
  201. tag: tag,
  202. pass: c.state.pass > 0,
  203. })
  204. state.areaPlusOne = areaID + 1
  205. }
  206. func (s *pointerHandler) Reset() {
  207. s.areaPlusOne = 0
  208. }
  209. func (c *pointerCollector) actionInputOp(act system.Action) {
  210. areaID := c.currentArea()
  211. area := &c.q.areas[areaID]
  212. area.action = act
  213. }
  214. func (q *pointerQueue) grab(state pointerState, req pointer.GrabCmd) (pointerState, []taggedEvent) {
  215. var evts []taggedEvent
  216. for _, p := range state.pointers {
  217. if !p.pressed || p.id != req.ID {
  218. continue
  219. }
  220. // Drop other handlers that lost their grab.
  221. for i := len(p.handlers) - 1; i >= 0; i-- {
  222. if tag := p.handlers[i]; tag != req.Tag {
  223. evts = append(evts, taggedEvent{
  224. tag: tag,
  225. event: pointer.Event{Kind: pointer.Cancel},
  226. })
  227. state = dropHandler(state, tag)
  228. }
  229. }
  230. break
  231. }
  232. return state, evts
  233. }
  234. func (c *pointerCollector) inputOp(tag event.Tag, state *pointerHandler) {
  235. areaID := c.currentArea()
  236. area := &c.q.areas[areaID]
  237. area.semantic.content.tag = tag
  238. c.newHandler(tag, state)
  239. }
  240. func (p *pointerFilter) Add(f event.Filter) {
  241. switch f := f.(type) {
  242. case transfer.SourceFilter:
  243. for _, m := range p.sourceMimes {
  244. if m == f.Type {
  245. return
  246. }
  247. }
  248. p.sourceMimes = append(p.sourceMimes, f.Type)
  249. case transfer.TargetFilter:
  250. for _, m := range p.targetMimes {
  251. if m == f.Type {
  252. return
  253. }
  254. }
  255. p.targetMimes = append(p.targetMimes, f.Type)
  256. case pointer.Filter:
  257. p.kinds = p.kinds | f.Kinds
  258. p.scrollX = p.scrollX.Union(f.ScrollX)
  259. p.scrollY = p.scrollY.Union(f.ScrollY)
  260. }
  261. }
  262. func (p *pointerFilter) Matches(e event.Event) bool {
  263. switch e := e.(type) {
  264. case pointer.Event:
  265. return e.Kind&p.kinds == e.Kind
  266. case transfer.CancelEvent, transfer.InitiateEvent:
  267. return len(p.sourceMimes) > 0 || len(p.targetMimes) > 0
  268. case transfer.RequestEvent:
  269. for _, t := range p.sourceMimes {
  270. if t == e.Type {
  271. return true
  272. }
  273. }
  274. case transfer.DataEvent:
  275. for _, t := range p.targetMimes {
  276. if t == e.Type {
  277. return true
  278. }
  279. }
  280. }
  281. return false
  282. }
  283. func (p *pointerFilter) Merge(p2 pointerFilter) {
  284. p.kinds = p.kinds | p2.kinds
  285. p.scrollX = p.scrollX.Union(p2.scrollX)
  286. p.scrollY = p.scrollY.Union(p2.scrollY)
  287. p.sourceMimes = append(p.sourceMimes, p2.sourceMimes...)
  288. p.targetMimes = append(p.targetMimes, p2.targetMimes...)
  289. }
  290. // clampScroll splits a scroll distance in the remaining scroll and the
  291. // scroll accepted by the filter.
  292. func (p *pointerFilter) clampScroll(scroll f32.Point) (left, scrolled f32.Point) {
  293. left.X, scrolled.X = clampSplit(scroll.X, p.scrollX.Min, p.scrollX.Max)
  294. left.Y, scrolled.Y = clampSplit(scroll.Y, p.scrollY.Min, p.scrollY.Max)
  295. return
  296. }
  297. func clampSplit(v float32, min, max int) (float32, float32) {
  298. if m := float32(max); v > m {
  299. return v - m, m
  300. }
  301. if m := float32(min); v < m {
  302. return v - m, m
  303. }
  304. return 0, v
  305. }
  306. func (s *pointerHandler) ResetEvent() (event.Event, bool) {
  307. if s.setup {
  308. return nil, false
  309. }
  310. s.setup = true
  311. return pointer.Event{Kind: pointer.Cancel}, true
  312. }
  313. func (c *pointerCollector) semanticLabel(lbl string) {
  314. areaID := c.currentArea()
  315. area := &c.q.areas[areaID]
  316. area.semantic.valid = true
  317. area.semantic.content.label = lbl
  318. }
  319. func (c *pointerCollector) semanticDesc(desc string) {
  320. areaID := c.currentArea()
  321. area := &c.q.areas[areaID]
  322. area.semantic.valid = true
  323. area.semantic.content.desc = desc
  324. }
  325. func (c *pointerCollector) semanticClass(class semantic.ClassOp) {
  326. areaID := c.currentArea()
  327. area := &c.q.areas[areaID]
  328. area.semantic.valid = true
  329. area.semantic.content.class = class
  330. }
  331. func (c *pointerCollector) semanticSelected(selected bool) {
  332. areaID := c.currentArea()
  333. area := &c.q.areas[areaID]
  334. area.semantic.valid = true
  335. area.semantic.content.selected = selected
  336. }
  337. func (c *pointerCollector) semanticEnabled(enabled bool) {
  338. areaID := c.currentArea()
  339. area := &c.q.areas[areaID]
  340. area.semantic.valid = true
  341. area.semantic.content.disabled = !enabled
  342. }
  343. func (c *pointerCollector) cursor(cursor pointer.Cursor) {
  344. areaID := c.currentArea()
  345. area := &c.q.areas[areaID]
  346. area.cursor = cursor
  347. }
  348. func (q *pointerQueue) offerData(handlers map[event.Tag]*handler, state pointerState, req transfer.OfferCmd) (pointerState, []taggedEvent) {
  349. var evts []taggedEvent
  350. for i, p := range state.pointers {
  351. if p.dataSource != req.Tag {
  352. continue
  353. }
  354. if p.dataTarget != nil {
  355. evts = append(evts, taggedEvent{tag: p.dataTarget, event: transfer.DataEvent{
  356. Type: req.Type,
  357. Open: func() io.ReadCloser {
  358. return req.Data
  359. },
  360. }})
  361. }
  362. state.pointers = append([]pointerInfo{}, state.pointers...)
  363. state.pointers[i], evts = q.deliverTransferCancelEvent(handlers, p, evts)
  364. break
  365. }
  366. return state, evts
  367. }
  368. func (c *pointerCollector) Reset() {
  369. c.q.reset()
  370. c.resetState()
  371. c.ensureRoot()
  372. }
  373. // Ensure implicit root area for semantic descriptions to hang onto.
  374. func (c *pointerCollector) ensureRoot() {
  375. if len(c.q.areas) > 0 {
  376. return
  377. }
  378. c.pushArea(areaRect, image.Rect(-1e6, -1e6, 1e6, 1e6))
  379. // Make it semantic to ensure a single semantic root.
  380. c.q.areas[0].semantic.valid = true
  381. }
  382. func (q *pointerQueue) assignSemIDs() {
  383. if q.semantic.idsAssigned {
  384. return
  385. }
  386. q.semantic.idsAssigned = true
  387. for i, a := range q.areas {
  388. if a.semantic.valid {
  389. q.areas[i].semantic.id = q.semanticIDFor(a.semantic.content)
  390. }
  391. }
  392. }
  393. func (q *pointerQueue) AppendSemantics(nodes []SemanticNode) []SemanticNode {
  394. q.assignSemIDs()
  395. nodes = q.appendSemanticChildren(nodes, 0)
  396. nodes = q.appendSemanticArea(nodes, 0, 0)
  397. return nodes
  398. }
  399. func (q *pointerQueue) appendSemanticArea(nodes []SemanticNode, parentID SemanticID, nodeIdx int) []SemanticNode {
  400. areaIdx := nodes[nodeIdx].areaIdx
  401. a := q.areas[areaIdx]
  402. childStart := len(nodes)
  403. nodes = q.appendSemanticChildren(nodes, a.firstChild)
  404. childEnd := len(nodes)
  405. for i := childStart; i < childEnd; i++ {
  406. nodes = q.appendSemanticArea(nodes, a.semantic.id, i)
  407. }
  408. n := &nodes[nodeIdx]
  409. n.ParentID = parentID
  410. n.Children = nodes[childStart:childEnd]
  411. return nodes
  412. }
  413. func (q *pointerQueue) appendSemanticChildren(nodes []SemanticNode, areaIdx int) []SemanticNode {
  414. if areaIdx == -1 {
  415. return nodes
  416. }
  417. a := q.areas[areaIdx]
  418. if semID := a.semantic.id; semID != 0 {
  419. cnt := a.semantic.content
  420. nodes = append(nodes, SemanticNode{
  421. ID: semID,
  422. Desc: SemanticDesc{
  423. Bounds: a.bounds(),
  424. Label: cnt.label,
  425. Description: cnt.desc,
  426. Class: cnt.class,
  427. Gestures: cnt.gestures,
  428. Selected: cnt.selected,
  429. Disabled: cnt.disabled,
  430. },
  431. areaIdx: areaIdx,
  432. })
  433. } else {
  434. nodes = q.appendSemanticChildren(nodes, a.firstChild)
  435. }
  436. return q.appendSemanticChildren(nodes, a.sibling)
  437. }
  438. func (q *pointerQueue) semanticIDFor(content semanticContent) SemanticID {
  439. ids := q.semantic.contentIDs[content]
  440. for i, id := range ids {
  441. if !id.used {
  442. ids[i].used = true
  443. return id.id
  444. }
  445. }
  446. // No prior assigned ID; allocate a new one.
  447. q.semantic.lastID++
  448. id := semanticID{id: q.semantic.lastID, used: true}
  449. if q.semantic.contentIDs == nil {
  450. q.semantic.contentIDs = make(map[semanticContent][]semanticID)
  451. }
  452. q.semantic.contentIDs[content] = append(q.semantic.contentIDs[content], id)
  453. return id.id
  454. }
  455. func (q *pointerQueue) ActionAt(pos f32.Point) (action system.Action, hasAction bool) {
  456. q.hitTest(pos, func(n *hitNode) bool {
  457. area := q.areas[n.area]
  458. if area.action != 0 {
  459. action = area.action
  460. hasAction = true
  461. return false
  462. }
  463. return true
  464. })
  465. return action, hasAction
  466. }
  467. func (q *pointerQueue) SemanticAt(pos f32.Point) (semID SemanticID, hasSemID bool) {
  468. q.assignSemIDs()
  469. q.hitTest(pos, func(n *hitNode) bool {
  470. area := q.areas[n.area]
  471. if area.semantic.id != 0 {
  472. semID = area.semantic.id
  473. hasSemID = true
  474. return false
  475. }
  476. return true
  477. })
  478. return semID, hasSemID
  479. }
  480. // hitTest searches the hit tree for nodes matching pos. Any node matching pos will
  481. // have the onNode func invoked on it to allow the caller to extract whatever information
  482. // is necessary for further processing. onNode may return false to terminate the walk of
  483. // the hit tree, or true to continue. Providing this algorithm in this generic way
  484. // allows normal event routing and system action event routing to share the same traversal
  485. // logic even though they are interested in different aspects of hit nodes.
  486. func (q *pointerQueue) hitTest(pos f32.Point, onNode func(*hitNode) bool) pointer.Cursor {
  487. // Track whether we're passing through hits.
  488. pass := true
  489. idx := len(q.hitTree) - 1
  490. cursor := pointer.CursorDefault
  491. for idx >= 0 {
  492. n := &q.hitTree[idx]
  493. hit, c := q.hit(n.area, pos)
  494. if !hit {
  495. idx--
  496. continue
  497. }
  498. if cursor == pointer.CursorDefault {
  499. cursor = c
  500. }
  501. pass = pass && n.pass
  502. if pass {
  503. idx--
  504. } else {
  505. idx = n.next
  506. }
  507. if !onNode(n) {
  508. break
  509. }
  510. }
  511. return cursor
  512. }
  513. func (q *pointerQueue) invTransform(areaIdx int, p f32.Point) f32.Point {
  514. if areaIdx == -1 {
  515. return p
  516. }
  517. return q.areas[areaIdx].trans.Invert().Transform(p)
  518. }
  519. func (q *pointerQueue) hit(areaIdx int, p f32.Point) (bool, pointer.Cursor) {
  520. c := pointer.CursorDefault
  521. for areaIdx != -1 {
  522. a := &q.areas[areaIdx]
  523. if c == pointer.CursorDefault {
  524. c = a.cursor
  525. }
  526. p := a.trans.Invert().Transform(p)
  527. if !a.area.Hit(p) {
  528. return false, c
  529. }
  530. areaIdx = a.parent
  531. }
  532. return true, c
  533. }
  534. func (q *pointerQueue) reset() {
  535. q.hitTree = q.hitTree[:0]
  536. q.areas = q.areas[:0]
  537. q.semantic.idsAssigned = false
  538. for k, ids := range q.semantic.contentIDs {
  539. for i := len(ids) - 1; i >= 0; i-- {
  540. if !ids[i].used {
  541. ids = append(ids[:i], ids[i+1:]...)
  542. } else {
  543. ids[i].used = false
  544. }
  545. }
  546. if len(ids) > 0 {
  547. q.semantic.contentIDs[k] = ids
  548. } else {
  549. delete(q.semantic.contentIDs, k)
  550. }
  551. }
  552. }
  553. func (q *pointerQueue) Frame(handlers map[event.Tag]*handler, state pointerState) (pointerState, []taggedEvent) {
  554. for _, h := range handlers {
  555. if h.pointer.areaPlusOne != 0 {
  556. area := &q.areas[h.pointer.areaPlusOne-1]
  557. if h.filter.pointer.kinds&(pointer.Press|pointer.Release) != 0 {
  558. area.semantic.content.gestures |= ClickGesture
  559. }
  560. if h.filter.pointer.kinds&pointer.Scroll != 0 {
  561. area.semantic.content.gestures |= ScrollGesture
  562. }
  563. area.semantic.valid = area.semantic.content.gestures != 0
  564. }
  565. }
  566. var evts []taggedEvent
  567. for i, p := range state.pointers {
  568. changed := false
  569. p, evts, state.cursor, changed = q.deliverEnterLeaveEvents(handlers, state.cursor, p, evts, p.last)
  570. if changed {
  571. state.pointers = append([]pointerInfo{}, state.pointers...)
  572. state.pointers[i] = p
  573. }
  574. }
  575. return state, evts
  576. }
  577. func dropHandler(state pointerState, tag event.Tag) pointerState {
  578. pointers := state.pointers
  579. state.pointers = nil
  580. for _, p := range pointers {
  581. handlers := p.handlers
  582. p.handlers = nil
  583. for _, h := range handlers {
  584. if h != tag {
  585. p.handlers = append(p.handlers, h)
  586. }
  587. }
  588. entered := p.entered
  589. p.entered = nil
  590. for _, h := range entered {
  591. if h != tag {
  592. p.entered = append(p.entered, h)
  593. }
  594. }
  595. state.pointers = append(state.pointers, p)
  596. }
  597. return state
  598. }
  599. // pointerOf returns the pointerInfo index corresponding to the pointer in e.
  600. func (s pointerState) pointerOf(e pointer.Event) (pointerState, int) {
  601. for i, p := range s.pointers {
  602. if p.id == e.PointerID {
  603. return s, i
  604. }
  605. }
  606. n := len(s.pointers)
  607. s.pointers = append(s.pointers[:n:n], pointerInfo{id: e.PointerID})
  608. return s, len(s.pointers) - 1
  609. }
  610. // Deliver is like Push, but delivers an event to a particular area.
  611. func (q *pointerQueue) Deliver(handlers map[event.Tag]*handler, areaIdx int, e pointer.Event) []taggedEvent {
  612. scroll := e.Scroll
  613. idx := len(q.hitTree) - 1
  614. // Locate first potential receiver.
  615. for idx != -1 {
  616. n := &q.hitTree[idx]
  617. if n.area == areaIdx {
  618. break
  619. }
  620. idx--
  621. }
  622. var evts []taggedEvent
  623. for idx != -1 {
  624. n := &q.hitTree[idx]
  625. idx = n.next
  626. h, ok := handlers[n.tag]
  627. if !ok || !h.filter.pointer.Matches(e) {
  628. continue
  629. }
  630. e := e
  631. if e.Kind == pointer.Scroll {
  632. if scroll == (f32.Point{}) {
  633. break
  634. }
  635. scroll, e.Scroll = h.filter.pointer.clampScroll(scroll)
  636. }
  637. e.Position = q.invTransform(h.pointer.areaPlusOne-1, e.Position)
  638. evts = append(evts, taggedEvent{tag: n.tag, event: e})
  639. if e.Kind != pointer.Scroll {
  640. break
  641. }
  642. }
  643. return evts
  644. }
  645. // SemanticArea returns the sematic content for area, and its parent area.
  646. func (q *pointerQueue) SemanticArea(areaIdx int) (semanticContent, int) {
  647. for areaIdx != -1 {
  648. a := &q.areas[areaIdx]
  649. areaIdx = a.parent
  650. if !a.semantic.valid {
  651. continue
  652. }
  653. return a.semantic.content, areaIdx
  654. }
  655. return semanticContent{}, -1
  656. }
  657. func (q *pointerQueue) Push(handlers map[event.Tag]*handler, state pointerState, e pointer.Event) (pointerState, []taggedEvent) {
  658. var evts []taggedEvent
  659. if e.Kind == pointer.Cancel {
  660. for k := range handlers {
  661. evts = append(evts, taggedEvent{
  662. event: pointer.Event{Kind: pointer.Cancel},
  663. tag: k,
  664. })
  665. }
  666. state.pointers = nil
  667. return state, evts
  668. }
  669. state, pidx := state.pointerOf(e)
  670. p := state.pointers[pidx]
  671. switch e.Kind {
  672. case pointer.Press:
  673. p, evts, state.cursor, _ = q.deliverEnterLeaveEvents(handlers, state.cursor, p, evts, e)
  674. p.pressed = true
  675. evts = q.deliverEvent(handlers, p, evts, e)
  676. case pointer.Move:
  677. if p.pressed {
  678. e.Kind = pointer.Drag
  679. }
  680. p, evts, state.cursor, _ = q.deliverEnterLeaveEvents(handlers, state.cursor, p, evts, e)
  681. evts = q.deliverEvent(handlers, p, evts, e)
  682. if p.pressed {
  683. p, evts = q.deliverDragEvent(handlers, p, evts)
  684. }
  685. case pointer.Release:
  686. evts = q.deliverEvent(handlers, p, evts, e)
  687. p.pressed = false
  688. p, evts, state.cursor, _ = q.deliverEnterLeaveEvents(handlers, state.cursor, p, evts, e)
  689. p, evts = q.deliverDropEvent(handlers, p, evts)
  690. case pointer.Scroll:
  691. p, evts, state.cursor, _ = q.deliverEnterLeaveEvents(handlers, state.cursor, p, evts, e)
  692. evts = q.deliverEvent(handlers, p, evts, e)
  693. default:
  694. panic("unsupported pointer event type")
  695. }
  696. p.last = e
  697. if !p.pressed && len(p.entered) == 0 {
  698. // No longer need to track pointer.
  699. state.pointers = append(state.pointers[:pidx:pidx], state.pointers[pidx+1:]...)
  700. } else {
  701. state.pointers = append([]pointerInfo{}, state.pointers...)
  702. state.pointers[pidx] = p
  703. }
  704. return state, evts
  705. }
  706. func (q *pointerQueue) deliverEvent(handlers map[event.Tag]*handler, p pointerInfo, evts []taggedEvent, e pointer.Event) []taggedEvent {
  707. foremost := true
  708. if p.pressed && len(p.handlers) == 1 {
  709. e.Priority = pointer.Grabbed
  710. foremost = false
  711. }
  712. scroll := e.Scroll
  713. for _, k := range p.handlers {
  714. h, ok := handlers[k]
  715. if !ok {
  716. continue
  717. }
  718. f := h.filter.pointer
  719. if !f.Matches(e) {
  720. continue
  721. }
  722. if e.Kind == pointer.Scroll {
  723. if scroll == (f32.Point{}) {
  724. return evts
  725. }
  726. scroll, e.Scroll = f.clampScroll(scroll)
  727. }
  728. e := e
  729. if foremost {
  730. foremost = false
  731. e.Priority = pointer.Foremost
  732. }
  733. e.Position = q.invTransform(h.pointer.areaPlusOne-1, e.Position)
  734. evts = append(evts, taggedEvent{event: e, tag: k})
  735. }
  736. return evts
  737. }
  738. func (q *pointerQueue) deliverEnterLeaveEvents(handlers map[event.Tag]*handler, cursor pointer.Cursor, p pointerInfo, evts []taggedEvent, e pointer.Event) (pointerInfo, []taggedEvent, pointer.Cursor, bool) {
  739. changed := false
  740. var hits []event.Tag
  741. if e.Source != pointer.Mouse && !p.pressed && e.Kind != pointer.Press {
  742. // Consider non-mouse pointers leaving when they're released.
  743. } else {
  744. var transSrc *pointerFilter
  745. if p.dataSource != nil {
  746. transSrc = &handlers[p.dataSource].filter.pointer
  747. }
  748. cursor = q.hitTest(e.Position, func(n *hitNode) bool {
  749. h, ok := handlers[n.tag]
  750. if !ok {
  751. return true
  752. }
  753. add := true
  754. if p.pressed {
  755. add = false
  756. // Filter out non-participating handlers,
  757. // except potential transfer targets when a transfer has been initiated.
  758. if _, found := searchTag(p.handlers, n.tag); found {
  759. add = true
  760. }
  761. if transSrc != nil {
  762. if _, ok := firstMimeMatch(transSrc, &h.filter.pointer); ok {
  763. add = true
  764. }
  765. }
  766. }
  767. if add {
  768. hits = addHandler(hits, n.tag)
  769. }
  770. return true
  771. })
  772. if !p.pressed {
  773. changed = true
  774. p.handlers = hits
  775. }
  776. }
  777. // Deliver Leave events.
  778. for _, k := range p.entered {
  779. if _, found := searchTag(hits, k); found {
  780. continue
  781. }
  782. h, ok := handlers[k]
  783. if !ok {
  784. continue
  785. }
  786. changed = true
  787. e := e
  788. e.Kind = pointer.Leave
  789. if h.filter.pointer.Matches(e) {
  790. e.Position = q.invTransform(h.pointer.areaPlusOne-1, e.Position)
  791. evts = append(evts, taggedEvent{tag: k, event: e})
  792. }
  793. }
  794. // Deliver Enter events.
  795. for _, k := range hits {
  796. if _, found := searchTag(p.entered, k); found {
  797. continue
  798. }
  799. h, ok := handlers[k]
  800. if !ok {
  801. continue
  802. }
  803. changed = true
  804. e := e
  805. e.Kind = pointer.Enter
  806. if h.filter.pointer.Matches(e) {
  807. e.Position = q.invTransform(h.pointer.areaPlusOne-1, e.Position)
  808. evts = append(evts, taggedEvent{tag: k, event: e})
  809. }
  810. }
  811. p.entered = hits
  812. return p, evts, cursor, changed
  813. }
  814. func (q *pointerQueue) deliverDragEvent(handlers map[event.Tag]*handler, p pointerInfo, evts []taggedEvent) (pointerInfo, []taggedEvent) {
  815. if p.dataSource != nil {
  816. return p, evts
  817. }
  818. // Identify the data source.
  819. for _, k := range p.entered {
  820. src := &handlers[k].filter.pointer
  821. if len(src.sourceMimes) == 0 {
  822. continue
  823. }
  824. // One data source handler per pointer.
  825. p.dataSource = k
  826. // Notify all potential targets.
  827. for k, tgt := range handlers {
  828. if _, ok := firstMimeMatch(src, &tgt.filter.pointer); ok {
  829. evts = append(evts, taggedEvent{tag: k, event: transfer.InitiateEvent{}})
  830. }
  831. }
  832. break
  833. }
  834. return p, evts
  835. }
  836. func (q *pointerQueue) deliverDropEvent(handlers map[event.Tag]*handler, p pointerInfo, evts []taggedEvent) (pointerInfo, []taggedEvent) {
  837. if p.dataSource == nil {
  838. return p, evts
  839. }
  840. // Request data from the source.
  841. src := &handlers[p.dataSource].filter.pointer
  842. for _, k := range p.entered {
  843. h := handlers[k]
  844. if m, ok := firstMimeMatch(src, &h.filter.pointer); ok {
  845. p.dataTarget = k
  846. evts = append(evts, taggedEvent{tag: p.dataSource, event: transfer.RequestEvent{Type: m}})
  847. return p, evts
  848. }
  849. }
  850. // No valid target found, abort.
  851. return q.deliverTransferCancelEvent(handlers, p, evts)
  852. }
  853. func (q *pointerQueue) deliverTransferCancelEvent(handlers map[event.Tag]*handler, p pointerInfo, evts []taggedEvent) (pointerInfo, []taggedEvent) {
  854. evts = append(evts, taggedEvent{tag: p.dataSource, event: transfer.CancelEvent{}})
  855. // Cancel all potential targets.
  856. src := &handlers[p.dataSource].filter.pointer
  857. for k, h := range handlers {
  858. if _, ok := firstMimeMatch(src, &h.filter.pointer); ok {
  859. evts = append(evts, taggedEvent{tag: k, event: transfer.CancelEvent{}})
  860. }
  861. }
  862. p.dataSource = nil
  863. p.dataTarget = nil
  864. return p, evts
  865. }
  866. // ClipFor clips r to the parents of area.
  867. func (q *pointerQueue) ClipFor(area int, r image.Rectangle) image.Rectangle {
  868. a := &q.areas[area]
  869. parent := a.parent
  870. for parent != -1 {
  871. a := &q.areas[parent]
  872. r = r.Intersect(a.bounds())
  873. parent = a.parent
  874. }
  875. return r
  876. }
  877. func searchTag(tags []event.Tag, tag event.Tag) (int, bool) {
  878. for i, t := range tags {
  879. if t == tag {
  880. return i, true
  881. }
  882. }
  883. return 0, false
  884. }
  885. // addHandler adds tag to the slice if not present.
  886. func addHandler(tags []event.Tag, tag event.Tag) []event.Tag {
  887. for _, t := range tags {
  888. if t == tag {
  889. return tags
  890. }
  891. }
  892. return append(tags, tag)
  893. }
  894. // firstMimeMatch returns the first type match between src and tgt.
  895. func firstMimeMatch(src, tgt *pointerFilter) (first string, matched bool) {
  896. for _, m1 := range tgt.targetMimes {
  897. for _, m2 := range src.sourceMimes {
  898. if m1 == m2 {
  899. return m1, true
  900. }
  901. }
  902. }
  903. return "", false
  904. }
  905. func (op *areaOp) Hit(pos f32.Point) bool {
  906. pos = pos.Sub(f32internal.FPt(op.rect.Min))
  907. size := f32internal.FPt(op.rect.Size())
  908. switch op.kind {
  909. case areaRect:
  910. return 0 <= pos.X && pos.X < size.X &&
  911. 0 <= pos.Y && pos.Y < size.Y
  912. case areaEllipse:
  913. rx := size.X / 2
  914. ry := size.Y / 2
  915. xh := pos.X - rx
  916. yk := pos.Y - ry
  917. // The ellipse function works in all cases because
  918. // 0/0 is not <= 1.
  919. return (xh*xh)/(rx*rx)+(yk*yk)/(ry*ry) <= 1
  920. default:
  921. panic("invalid area kind")
  922. }
  923. }
  924. func (a *areaNode) bounds() image.Rectangle {
  925. return f32internal.Rectangle{
  926. Min: a.trans.Transform(f32internal.FPt(a.area.rect.Min)),
  927. Max: a.trans.Transform(f32internal.FPt(a.area.rect.Max)),
  928. }.Round()
  929. }