浏览代码

Merge pull request #139 from UnityTech/textselection

Textselection
/main
GitHub 5 年前
当前提交
30995c89
共有 8 个文件被更改,包括 207 次插入8 次删除
  1. 1
      Runtime/painting/basic_types.cs
  2. 23
      Runtime/painting/text_span.cs
  3. 59
      Runtime/rendering/paragraph.cs
  4. 2
      Samples/UIWidgetSample/txt/TextSpanGesture.cs
  5. 26
      Runtime/gestures/hover.cs
  6. 11
      Runtime/gestures/hover.cs.meta
  7. 82
      Samples/UIWidgetSample/HoverRecognizerSample.cs
  8. 11
      Samples/UIWidgetSample/HoverRecognizerSample.cs.meta

1
Runtime/painting/basic_types.cs


public enum RenderComparison {
identical,
metadata,
function,
paint,
layout,
}

23
Runtime/painting/text_span.cs


public readonly string text;
public readonly List<TextSpan> children;
public readonly GestureRecognizer recognizer;
public readonly HoverRecognizer hoverRecognizer;
GestureRecognizer recognizer = null) {
GestureRecognizer recognizer = null, HoverRecognizer hoverRecognizer = null) {
this.hoverRecognizer = hoverRecognizer;
}
public void build(ParagraphBuilder builder, float textScaleFactor = 1.0f) {

if (hasStyle) {
builder.pop();
}
}
public bool hasHoverRecognizer {
get {
bool need = false;
this.visitTextSpan((text) => {
if (text.hoverRecognizer != null) {
need = true;
return false;
}
return true;
});
return need;
}
}

RenderComparison result = Equals(this.recognizer, other.recognizer)
? RenderComparison.identical
: RenderComparison.metadata;
if (!Equals(this.hoverRecognizer, other.hoverRecognizer)) {
result = RenderComparison.function > result ? RenderComparison.function : result;
}
if (this.style != null) {
var candidate = this.style.compareTo(other.style);
if (candidate > result) {

59
Runtime/rendering/paragraph.cs


this._selection = null;
this.onSelectionChanged = onSelectionChanged;
this.selectionColor = selectionColor;
this._resetHoverHandler();
}
public Action onSelectionChanged;

case RenderComparison.identical:
case RenderComparison.metadata:
return;
case RenderComparison.function:
this._textPainter.text = value;
break;
case RenderComparison.paint:
this._textPainter.text = value;
this.markNeedsPaint();

this.markNeedsLayout();
break;
}
this._resetHoverHandler();
}
}

}
}
TextSpan _previousHoverSpan;
bool _pointerHoverInside;
bool _hasHoverRecognizer;
void _resetHoverHandler() {
this._hasHoverRecognizer = this._textPainter.text.hasHoverRecognizer;
this._previousHoverSpan = null;
this._pointerHoverInside = false;
}
void _handleKeyEvent(RawKeyEvent keyEvent) {
//only allow KCommand.copy
if (keyEvent is RawKeyUpEvent) {

this.onSelectionChanged?.Invoke();
}
void _handlePointerHover(PointerEvent evt) {
if (!this._hasHoverRecognizer) {
return;
}
if (evt is PointerEnterEvent) {
this._pointerHoverInside = true;
}
else if (evt is PointerLeaveEvent) {
this._pointerHoverInside = false;
this._previousHoverSpan?.hoverRecognizer?.OnPointerLeave?.Invoke();
this._previousHoverSpan = null;
}
else if (evt is PointerHoverEvent && this._pointerHoverInside) {
this._layoutTextWithConstraints(this.constraints);
Offset offset = this.globalToLocal(evt.position);
TextPosition position = this._textPainter.getPositionForOffset(offset);
TextSpan span = this._textPainter.text.getSpanForPosition(position);
if (this._previousHoverSpan != span) {
this._previousHoverSpan?.hoverRecognizer?.OnPointerLeave?.Invoke();
span?.hoverRecognizer?.OnPointerEnter?.Invoke((PointerHoverEvent) evt);
this._previousHoverSpan = span;
}
}
}
if (!(evt is PointerDownEvent)) {
if (evt is PointerDownEvent) {
this._layoutTextWithConstraints(this.constraints);
Offset offset = ((BoxHitTestEntry) entry).localPosition;
TextPosition position = this._textPainter.getPositionForOffset(offset);
TextSpan span = this._textPainter.text.getSpanForPosition(position);
span?.recognizer?.addPointer((PointerDownEvent) evt);
this._layoutTextWithConstraints(this.constraints);
Offset offset = ((BoxHitTestEntry) entry).localPosition;
TextPosition position = this._textPainter.getPositionForOffset(offset);
TextSpan span = this._textPainter.text.getSpanForPosition(position);
span?.recognizer?.addPointer((PointerDownEvent) evt);
this._handlePointerHover(evt);
}
protected override void performLayout() {

foreach (var box in this._selectionRects) {
barPath.addRect(box.toRect().shift(effectiveOffset));
}
canvas.drawPath(barPath, paint);
}

2
Samples/UIWidgetSample/txt/TextSpanGesture.cs


color: Colors.green,
decoration: TextDecoration.underline
)
// recognizer: this._longPressRecognizer
//recognizer: this._longPressRecognizer
),
new TextSpan(
text: " secret?"

26
Runtime/gestures/hover.cs


using Unity.UIWidgets.foundation;
namespace Unity.UIWidgets.gestures {
public delegate void PointerHoverEnterCallback(PointerHoverEvent evt);
public delegate void PointerHoverLeaveCallback();
public class HoverRecognizer : DiagnosticableTree {
public HoverRecognizer(object debugOwner = null) {
this.debugOwner = debugOwner;
}
readonly object debugOwner;
public PointerHoverEnterCallback OnPointerEnter;
public PointerHoverLeaveCallback OnPointerLeave;
public override void debugFillProperties(DiagnosticPropertiesBuilder properties) {
base.debugFillProperties(properties);
properties.add(new DiagnosticsProperty<object>("debugOwner", this.debugOwner,
defaultValue: Diagnostics.kNullDefaultValue));
}
}
}

11
Runtime/gestures/hover.cs.meta


fileFormatVersion: 2
guid: 0482dd5944bd647da9d8a1a32a86801b
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

82
Samples/UIWidgetSample/HoverRecognizerSample.cs


using System.Collections.Generic;
using Unity.UIWidgets.gestures;
using Unity.UIWidgets.material;
using Unity.UIWidgets.painting;
using Unity.UIWidgets.rendering;
using Unity.UIWidgets.ui;
using Unity.UIWidgets.widgets;
using UnityEngine;
namespace UIWidgetsSample {
public class HoverRecognizerSample : UIWidgetsSamplePanel {
protected override Widget createWidget() {
return new MaterialApp(
showPerformanceOverlay: false,
home: new HoverMainPanel()
);
}
protected override void OnEnable() {
FontManager.instance.addFont(Resources.Load<Font>(path: "MaterialIcons-Regular"), "Material Icons");
base.OnEnable();
}
}
class HoverMainPanel : StatefulWidget {
public override State createState() {
return new HoverMainPanelState();
}
}
class HoverMainPanelState : State<HoverMainPanel> {
bool hoverActivated = false;
public override Widget build(BuildContext context) {
return new Scaffold(
appBar: new AppBar(
title: new Center(
child: new Text("Test Hover Widget")
)
),
body: new Card(
color: Colors.white,
child: new Center(
child: new Column(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.center,
children: new List<Widget> {
new Icon(this.hoverActivated ? Unity.UIWidgets.material.Icons.pool : Unity.UIWidgets.material.Icons.directions_walk, size: 128.0f),
new RichText(
text: new TextSpan(
text: "Test <",
style: new TextStyle(color: Colors.black),
children: new List<TextSpan>() {
new TextSpan(
text: "Hover Me",
style: new TextStyle(
color: Colors.green,
decoration: TextDecoration.underline
),
hoverRecognizer: new HoverRecognizer {
OnPointerEnter = evt => {
this.setState(() => { this.hoverActivated = true; });
},
OnPointerLeave = () => {
this.setState(() => { this.hoverActivated = false;});
}
}
),
new TextSpan(
text: ">"
)
}
)
)
}
)
)
)
);
}
}
}

11
Samples/UIWidgetSample/HoverRecognizerSample.cs.meta


fileFormatVersion: 2
guid: aeab7b6e566d741a8a11a4400d52e708
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
正在加载...
取消
保存