Skip to content
This repository was archived by the owner on Apr 29, 2021. It is now read-only.

Commit a6ad616

Browse files
committed
pointer hover recognizer on TextSpan
1 parent 7ba4991 commit a6ad616

File tree

7 files changed

+144
-19
lines changed

7 files changed

+144
-19
lines changed

Runtime/gestures/binding.cs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -125,7 +125,8 @@ void _handlePointerHoverEvent(PointerEvent evt) {
125125
timeStamp: evt.timeStamp,
126126
pointer: evt.pointer,
127127
device: evt.device,
128-
kind: evt.kind
128+
kind: evt.kind,
129+
position: evt.position
129130
), null);
130131
}
131132

@@ -135,7 +136,8 @@ void _handlePointerHoverEvent(PointerEvent evt) {
135136
timeStamp: evt.timeStamp,
136137
pointer: evt.pointer,
137138
device: evt.device,
138-
kind: evt.kind
139+
kind: evt.kind,
140+
position: evt.position
139141
), hitTestEntry);
140142
}
141143

Runtime/gestures/hover.cs

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
using System;
2+
using Unity.UIWidgets.foundation;
3+
using UnityEngine;
4+
5+
namespace Unity.UIWidgets.gestures {
6+
7+
public class HoverRecognizer : DiagnosticableTree {
8+
public HoverRecognizer(object debugOwner = null) {
9+
this.debugOwner = debugOwner;
10+
}
11+
12+
readonly object debugOwner;
13+
14+
public Action OnPointerEnter = () => {};
15+
16+
public Action OnPointerLeave = () => {};
17+
}
18+
}

Runtime/gestures/hover.cs.meta

Lines changed: 11 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Runtime/painting/text_span.cs

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,13 +15,15 @@ public class TextSpan : DiagnosticableTree, IEquatable<TextSpan> {
1515
public readonly string text;
1616
public readonly List<TextSpan> children;
1717
public readonly GestureRecognizer recognizer;
18+
public readonly HoverRecognizer hoverRecognizer;
1819

1920
public TextSpan(string text = "", TextStyle style = null, List<TextSpan> children = null,
20-
GestureRecognizer recognizer = null) {
21+
GestureRecognizer recognizer = null, HoverRecognizer hoverRecognizer = null) {
2122
this.text = text;
2223
this.style = style;
2324
this.children = children;
2425
this.recognizer = recognizer;
26+
this.hoverRecognizer = hoverRecognizer;
2527
}
2628

2729
public void build(ParagraphBuilder builder, float textScaleFactor = 1.0f) {
@@ -46,6 +48,21 @@ public void build(ParagraphBuilder builder, float textScaleFactor = 1.0f) {
4648
}
4749
}
4850

51+
public bool needHoverRecognizer {
52+
get {
53+
bool need = false;
54+
this.visitTextSpan((text) => {
55+
if (text.hoverRecognizer != null) {
56+
need = true;
57+
return false;
58+
}
59+
return true;
60+
});
61+
62+
return need;
63+
}
64+
}
65+
4966
bool visitTextSpan(Visitor visitor) {
5067
if (!string.IsNullOrEmpty(this.text)) {
5168
if (!visitor.Invoke(this)) {

Runtime/rendering/paragraph.cs

Lines changed: 41 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,11 @@ public RenderParagraph(TextSpan text,
5959
this._selection = null;
6060
this.onSelectionChanged = onSelectionChanged;
6161
this.selectionColor = selectionColor;
62+
63+
64+
this._listenToHoverEvent = this._textPainter.text.needHoverRecognizer;
65+
this._previousHoverSpan = null;
66+
this._pointerHoverInside = false;
6267
}
6368

6469
public Action onSelectionChanged;
@@ -95,6 +100,10 @@ public TextSpan text {
95100
this.markNeedsLayout();
96101
break;
97102
}
103+
104+
this._listenToHoverEvent = this._textPainter.text.needHoverRecognizer;
105+
this._previousHoverSpan = null;
106+
this._pointerHoverInside = false;
98107
}
99108
}
100109

@@ -316,17 +325,43 @@ void _handleSelectionChanged(TextSelection selection,
316325
this.onSelectionChanged?.Invoke();
317326
}
318327

328+
TextSpan _previousHoverSpan = null;
329+
bool _pointerHoverInside = false;
330+
bool _listenToHoverEvent = false;
331+
319332
public override void handleEvent(PointerEvent evt, HitTestEntry entry) {
320333
D.assert(this.debugHandleEvent(evt, entry));
321-
if (!(evt is PointerDownEvent)) {
334+
if (evt is PointerDownEvent) {
335+
this._layoutTextWithConstraints(this.constraints);
336+
Offset offset = ((BoxHitTestEntry) entry).localPosition;
337+
TextPosition position = this._textPainter.getPositionForOffset(offset);
338+
TextSpan span = this._textPainter.text.getSpanForPosition(position);
339+
span?.recognizer?.addPointer((PointerDownEvent) evt);
340+
}
341+
342+
if (!this._listenToHoverEvent) {
322343
return;
323344
}
324345

325-
this._layoutTextWithConstraints(this.constraints);
326-
Offset offset = ((BoxHitTestEntry) entry).localPosition;
327-
TextPosition position = this._textPainter.getPositionForOffset(offset);
328-
TextSpan span = this._textPainter.text.getSpanForPosition(position);
329-
span?.recognizer?.addPointer((PointerDownEvent) evt);
346+
if (evt is PointerEnterEvent) {
347+
this._pointerHoverInside = true;
348+
} else if (evt is PointerLeaveEvent) {
349+
this._pointerHoverInside = false;
350+
this._previousHoverSpan?.hoverRecognizer?.OnPointerLeave();
351+
this._previousHoverSpan = null;
352+
}
353+
else if (evt is PointerHoverEvent && this._pointerHoverInside) {
354+
this._layoutTextWithConstraints(this.constraints);
355+
Offset offset = this.globalToLocal(evt.position);
356+
TextPosition position = this._textPainter.getPositionForOffset(offset);
357+
TextSpan span = this._textPainter.text.getSpanForPosition(position);
358+
359+
if (this._previousHoverSpan != span) {
360+
this._previousHoverSpan?.hoverRecognizer?.OnPointerLeave();
361+
span?.hoverRecognizer?.OnPointerEnter();
362+
this._previousHoverSpan = span;
363+
}
364+
}
330365
}
331366

332367
protected override void performLayout() {

Samples/UIWidgetSample/MaterialSample.cs

Lines changed: 33 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
using System.Collections.Generic;
22
using RSG;
33
using Unity.UIWidgets.foundation;
4+
using Unity.UIWidgets.gestures;
45
using Unity.UIWidgets.material;
56
using Unity.UIWidgets.painting;
67
using Unity.UIWidgets.rendering;
@@ -170,10 +171,21 @@ public class MaterialAppBarWidgetState : State<MaterialAppBarWidget> {
170171
GlobalKey<ScaffoldState> _scaffoldKey = GlobalKey<ScaffoldState>.key();
171172

172173
VoidCallback _showBottomSheetCallback;
174+
175+
TapGestureRecognizer _tapRecognizer;
176+
HoverRecognizer _hoverRecognizer;
173177

174178
public override void initState() {
175179
base.initState();
176180
this._showBottomSheetCallback = this._showBottomSheet;
181+
182+
this._tapRecognizer = new TapGestureRecognizer();
183+
this._tapRecognizer.onTap = () => {
184+
Debug.Log("Tap");
185+
};
186+
this._hoverRecognizer = new HoverRecognizer();
187+
this._hoverRecognizer.OnPointerEnter = () => { Debug.Log("Pointer Enter"); };
188+
this._hoverRecognizer.OnPointerLeave = () => { Debug.Log("Pointer Leave"); };
177189
}
178190

179191
void _showBottomSheet() {
@@ -212,7 +224,25 @@ public override Widget build(BuildContext context) {
212224
return new Scaffold(
213225
key: this._scaffoldKey,
214226
appBar: new AppBar(
215-
title: new Text("Basic AppBar"),
227+
title: new RichText(
228+
text: new TextSpan(
229+
text: "Can you ",
230+
style: new TextStyle(color: Colors.black),
231+
children: new List<TextSpan>() {
232+
new TextSpan(
233+
text: "find the",
234+
style: new TextStyle(
235+
color: Colors.green,
236+
decoration: TextDecoration.underline
237+
),
238+
recognizer: this._tapRecognizer,
239+
hoverRecognizer: this._hoverRecognizer
240+
),
241+
new TextSpan(
242+
text: " secret?"
243+
)
244+
}
245+
)),
216246
actions: new List<Widget> {
217247
new IconButton(
218248
icon: new Icon(Choice.choices[0].icon),
@@ -317,7 +347,8 @@ public override Widget build(BuildContext context) {
317347
children: new List<Widget> {
318348
new Icon(this.choice.icon, size: 128.0f, color: textStyle.color),
319349
new RaisedButton(
320-
child: new Text(this.choice.title, style: textStyle),
350+
//child: new Text(this.choice.title, style: textStyle),
351+
child: new Icon(Unity.UIWidgets.material.Icons.pool),
321352
onPressed: () => {
322353
SnackBar snackBar = new SnackBar(
323354
content: new Text(this.choice.title + " is chosen !"),

Samples/UIWidgetSample/txt/TextSpanGesture.cs

Lines changed: 19 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -23,21 +23,31 @@ public override State createState() {
2323
}
2424

2525
class _BuzzingTextState : State<BuzzingText> {
26-
LongPressGestureRecognizer _longPressRecognizer;
26+
TapGestureRecognizer _tapRecognizer;
27+
HoverRecognizer _hoverRecognizer;
2728

2829
public override void initState() {
2930
base.initState();
30-
this._longPressRecognizer = new LongPressGestureRecognizer();
31-
this._longPressRecognizer.onLongPress = this._handlePress;
31+
this._tapRecognizer = new TapGestureRecognizer();
32+
this._tapRecognizer.onTap = () => {
33+
Debug.Log("Tap");
34+
};
35+
this._hoverRecognizer = new HoverRecognizer();
36+
this._hoverRecognizer.OnPointerEnter = () => { Debug.Log("Pointer Enter"); };
37+
this._hoverRecognizer.OnPointerLeave = () => { Debug.Log("Pointer Leave"); };
3238
}
3339

3440
public override void dispose() {
35-
this._longPressRecognizer.dispose();
41+
this._tapRecognizer.dispose();
3642
base.dispose();
3743
}
3844

39-
void _handlePress() {
40-
Debug.Log("Long Pressed Text");
45+
void _handleEnter() {
46+
Debug.Log("Enter");
47+
}
48+
49+
void _handleLeave() {
50+
Debug.Log("Leave");
4151
}
4252
/*
4353
@@ -55,8 +65,9 @@ public override Widget build(BuildContext context) {
5565
style: new TextStyle(
5666
color: Colors.green,
5767
decoration: TextDecoration.underline
58-
)
59-
// recognizer: this._longPressRecognizer
68+
),
69+
recognizer: this._tapRecognizer,
70+
hoverRecognizer: this._hoverRecognizer
6071
),
6172
new TextSpan(
6273
text: " secret?"

0 commit comments

Comments
 (0)