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

Commit 65080d8

Browse files
committed
fix a bug in flutter + reimport support to textSpan-level hoverrecognizer
1 parent ddc7c05 commit 65080d8

File tree

2 files changed

+100
-59
lines changed

2 files changed

+100
-59
lines changed

Runtime/rendering/paragraph.cs

Lines changed: 68 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,7 @@ public TextSpan text {
9090
return;
9191
case RenderComparison.function:
9292
this._textPainter.text = value;
93+
this.markNeedsPaint();
9394
break;
9495
case RenderComparison.paint:
9596
this._textPainter.text = value;
@@ -251,11 +252,30 @@ public bool hasFocus {
251252
TextSpan _previousHoverSpan;
252253
bool _pointerHoverInside;
253254
bool _hasHoverRecognizer;
255+
MouseTrackerAnnotation _hoverAnnotation;
254256

255257
void _resetHoverHandler() {
256258
this._hasHoverRecognizer = this._textPainter.text.hasHoverRecognizer;
257259
this._previousHoverSpan = null;
258260
this._pointerHoverInside = false;
261+
262+
if (this._hoverAnnotation != null && this.attached) {
263+
RendererBinding.instance.mouseTracker.detachAnnotation(this._hoverAnnotation);
264+
}
265+
266+
if (this._hasHoverRecognizer) {
267+
this._hoverAnnotation = new MouseTrackerAnnotation(
268+
onEnter: this._onPointerEnter,
269+
onHover: this._onPointerHover,
270+
onExit: this._onPointerExit);
271+
272+
if (this.attached) {
273+
RendererBinding.instance.mouseTracker.attachAnnotation(this._hoverAnnotation);
274+
}
275+
}
276+
else {
277+
this._hoverAnnotation = null;
278+
}
259279
}
260280

261281
void _handleKeyEvent(RawKeyEvent keyEvent) {
@@ -288,12 +308,22 @@ void _handleKeyEvent(RawKeyEvent keyEvent) {
288308
}
289309
}
290310

311+
public override void attach(object owner) {
312+
base.attach(owner);
313+
if (this._hoverAnnotation != null) {
314+
RendererBinding.instance.mouseTracker.attachAnnotation(this._hoverAnnotation);
315+
}
316+
}
317+
291318
public override void detach() {
292319
if (this._listenerAttached) {
293320
RawKeyboard.instance.removeListener(this._handleKeyEvent);
294321
}
295322

296323
base.detach();
324+
if (this._hoverAnnotation != null) {
325+
RendererBinding.instance.mouseTracker.detachAnnotation(this._hoverAnnotation);
326+
}
297327
}
298328

299329
TextSelection _selection;
@@ -333,46 +363,40 @@ void _handleSelectionChanged(TextSelection selection,
333363
this.onSelectionChanged?.Invoke();
334364
}
335365

366+
void _onPointerEnter(PointerEvent evt) {
367+
this._pointerHoverInside = true;
368+
}
336369

337-
void _handlePointerHover(PointerEvent evt) {
338-
if (!this._hasHoverRecognizer) {
339-
return;
340-
}
370+
void _onPointerExit(PointerEvent evt) {
371+
this._pointerHoverInside = false;
372+
this._previousHoverSpan?.hoverRecognizer?.OnPointerLeave?.Invoke();
373+
this._previousHoverSpan = null;
374+
}
341375

342-
if (evt is PointerEnterEvent) {
343-
this._pointerHoverInside = true;
344-
}
345-
else if (evt is PointerExitEvent) {
346-
this._pointerHoverInside = false;
376+
void _onPointerHover(PointerEvent evt) {
377+
this._layoutTextWithConstraints(this.constraints);
378+
Offset offset = this.globalToLocal(evt.position);
379+
TextPosition position = this._textPainter.getPositionForOffset(offset);
380+
TextSpan span = this._textPainter.text.getSpanForPosition(position);
381+
382+
if (this._previousHoverSpan != span) {
347383
this._previousHoverSpan?.hoverRecognizer?.OnPointerLeave?.Invoke();
348-
this._previousHoverSpan = null;
349-
}
350-
else if (evt is PointerHoverEvent && this._pointerHoverInside) {
351-
this._layoutTextWithConstraints(this.constraints);
352-
Offset offset = this.globalToLocal(evt.position);
353-
TextPosition position = this._textPainter.getPositionForOffset(offset);
354-
TextSpan span = this._textPainter.text.getSpanForPosition(position);
355-
356-
if (this._previousHoverSpan != span) {
357-
this._previousHoverSpan?.hoverRecognizer?.OnPointerLeave?.Invoke();
358-
span?.hoverRecognizer?.OnPointerEnter?.Invoke((PointerHoverEvent) evt);
359-
this._previousHoverSpan = span;
360-
}
384+
span?.hoverRecognizer?.OnPointerEnter?.Invoke((PointerHoverEvent) evt);
385+
this._previousHoverSpan = span;
361386
}
362387
}
363388

364389
public override void handleEvent(PointerEvent evt, HitTestEntry entry) {
365390
D.assert(this.debugHandleEvent(evt, entry));
366-
if (evt is PointerDownEvent) {
367-
this._layoutTextWithConstraints(this.constraints);
368-
Offset offset = ((BoxHitTestEntry) entry).localPosition;
369-
TextPosition position = this._textPainter.getPositionForOffset(offset);
370-
TextSpan span = this._textPainter.text.getSpanForPosition(position);
371-
span?.recognizer?.addPointer((PointerDownEvent) evt);
391+
if (!(evt is PointerDownEvent)) {
372392
return;
373393
}
374-
375-
this._handlePointerHover(evt);
394+
395+
this._layoutTextWithConstraints(this.constraints);
396+
Offset offset = ((BoxHitTestEntry) entry).localPosition;
397+
TextPosition position = this._textPainter.getPositionForOffset(offset);
398+
TextSpan span = this._textPainter.text.getSpanForPosition(position);
399+
span?.recognizer?.addPointer((PointerDownEvent) evt);
376400
}
377401

378402
protected override void performLayout() {
@@ -387,7 +411,8 @@ protected override void performLayout() {
387411
this._selectionRects = null;
388412
}
389413

390-
public override void paint(PaintingContext context, Offset offset) {
414+
415+
void paintParagraph(PaintingContext context, Offset offset) {
391416
this._layoutTextWithConstraints(this.constraints);
392417
var canvas = context.canvas;
393418

@@ -411,6 +436,18 @@ public override void paint(PaintingContext context, Offset offset) {
411436
}
412437
}
413438

439+
public override void paint(PaintingContext context, Offset offset) {
440+
if (this._hoverAnnotation != null) {
441+
AnnotatedRegionLayer<MouseTrackerAnnotation> layer = new AnnotatedRegionLayer<MouseTrackerAnnotation>(
442+
this._hoverAnnotation, size: this.size, offset: offset);
443+
444+
context.pushLayer(layer, this.paintParagraph, offset);
445+
}
446+
else {
447+
this.paintParagraph(context, offset);
448+
}
449+
}
450+
414451

415452
void _paintSelection(Canvas canvas, Offset effectiveOffset) {
416453
D.assert(this._selectionRects != null);

Runtime/rendering/proxy_box.cs

Lines changed: 32 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
1-
using System;
2-
using System.Collections.Generic;
1+
using System.Collections.Generic;
32
using Unity.UIWidgets.animation;
43
using Unity.UIWidgets.foundation;
54
using Unity.UIWidgets.gestures;
@@ -1195,7 +1194,7 @@ public override bool hitTest(HitTestResult result, Offset position = null) {
11951194
return base.hitTest(result, position: position);
11961195
}
11971196

1198-
1197+
11991198
public override void paint(PaintingContext context, Offset offset) {
12001199
if (this.child != null) {
12011200
this._updateClip();
@@ -1283,7 +1282,7 @@ public override bool hitTest(HitTestResult result, Offset position = null) {
12831282
return base.hitTest(result, position: position);
12841283
}
12851284

1286-
1285+
12871286
public override void paint(PaintingContext context, Offset offset) {
12881287
if (this.child != null) {
12891288
this._updateClip();
@@ -1302,19 +1301,20 @@ public override void paint(PaintingContext context, Offset offset) {
13021301
}
13031302
else {
13041303
Canvas canvas = context.canvas;
1305-
if (this.elevation != 0.0) {
1306-
canvas.drawRect(
1307-
offsetBounds.inflate(20.0f),
1308-
_transparentPaint
1309-
);
1310-
1311-
canvas.drawShadow(
1312-
offsetPath,
1313-
this.shadowColor,
1314-
this.elevation,
1315-
this.color.alpha != 0xFF
1316-
);
1317-
}
1304+
if (this.elevation != 0.0) {
1305+
canvas.drawRect(
1306+
offsetBounds.inflate(20.0f),
1307+
_transparentPaint
1308+
);
1309+
1310+
canvas.drawShadow(
1311+
offsetPath,
1312+
this.shadowColor,
1313+
this.elevation,
1314+
this.color.alpha != 0xFF
1315+
);
1316+
}
1317+
13181318
Paint paint = new Paint {color = this.color, style = PaintingStyle.fill};
13191319
canvas.drawPath(offsetPath, paint);
13201320
context.clipPathAndPaint(offsetPath, this.clipBehavior,
@@ -1909,6 +1909,7 @@ public PointerEnterEventListener onPointerEnter {
19091909
}
19101910
}
19111911
}
1912+
19121913
PointerEnterEventListener _onPointerEnter;
19131914

19141915
public PointerHoverEventListener onPointerHover {
@@ -1920,6 +1921,7 @@ public PointerHoverEventListener onPointerHover {
19201921
}
19211922
}
19221923
}
1924+
19231925
PointerHoverEventListener _onPointerHover;
19241926

19251927
public PointerExitEventListener onPointerExit {
@@ -1931,6 +1933,7 @@ public PointerExitEventListener onPointerExit {
19311933
}
19321934
}
19331935
}
1936+
19341937
PointerExitEventListener _onPointerExit;
19351938

19361939
public PointerUpEventListener onPointerUp;
@@ -1942,17 +1945,16 @@ public PointerExitEventListener onPointerExit {
19421945
MouseTrackerAnnotation _hoverAnnotation;
19431946

19441947
void _updateAnnotations() {
1945-
D.assert(this._onPointerEnter != this._hoverAnnotation.onEnter ||
1948+
D.assert(this._onPointerEnter != this._hoverAnnotation.onEnter ||
19461949
this._onPointerHover != this._hoverAnnotation.onHover ||
19471950
this._onPointerExit != this._hoverAnnotation.onExit,
19481951
"Shouldn't call _updateAnnotations if nothing has changed.");
1949-
1952+
19501953
if (this._hoverAnnotation != null && this.attached) {
19511954
RendererBinding.instance.mouseTracker.detachAnnotation(this._hoverAnnotation);
19521955
}
1953-
1954-
if (this._onPointerEnter != null || this._onPointerHover != null || this._onPointerExit != null)
1955-
{
1956+
1957+
if (this._onPointerEnter != null || this._onPointerHover != null || this._onPointerExit != null) {
19561958
this._hoverAnnotation = new MouseTrackerAnnotation(
19571959
onEnter: this._onPointerEnter,
19581960
onHover: this._onPointerHover,
@@ -1965,11 +1967,11 @@ void _updateAnnotations() {
19651967
else {
19661968
this._hoverAnnotation = null;
19671969
}
1968-
1970+
19691971
this.markNeedsPaint();
19701972
}
19711973

1972-
public override void attach(Object owner) {
1974+
public override void attach(object owner) {
19731975
base.attach(owner);
19741976
if (this._hoverAnnotation != null) {
19751977
RendererBinding.instance.mouseTracker.attachAnnotation(this._hoverAnnotation);
@@ -1987,10 +1989,12 @@ public override void paint(PaintingContext context, Offset offset) {
19871989
if (this._hoverAnnotation != null) {
19881990
AnnotatedRegionLayer<MouseTrackerAnnotation> layer = new AnnotatedRegionLayer<MouseTrackerAnnotation>(
19891991
this._hoverAnnotation, size: this.size, offset: offset);
1990-
1992+
19911993
context.pushLayer(layer, base.paint, offset);
19921994
}
1993-
base.paint(context, offset);
1995+
else {
1996+
base.paint(context, offset);
1997+
}
19941998
}
19951999

19962000
protected override void performResize() {
@@ -2550,10 +2554,10 @@ protected override bool alwaysNeedsCompositing {
25502554
public override void paint(PaintingContext context, Offset offset) {
25512555
AnnotatedRegionLayer<T> layer =
25522556
new AnnotatedRegionLayer<T>(
2553-
value: this.value,
2557+
value: this.value,
25542558
size: this.sized ? this.size : null,
25552559
offset: this.sized ? offset : null);
2556-
2560+
25572561
context.pushLayer(layer, base.paint, offset);
25582562
}
25592563
}

0 commit comments

Comments
 (0)