浏览代码

merge framework

/main
gewentao 6 年前
当前提交
7d1c51c4
共有 49 个文件被更改,包括 3788 次插入187 次删除
  1. 5
      Assets/UIWidgets/Tests/Menu.cs
  2. 119
      Assets/UIWidgets/foundation/diagnostics.cs
  3. 4
      Assets/UIWidgets/gestures/recognizer.cs
  4. 2
      Assets/UIWidgets/gestures/tap.cs
  5. 107
      Assets/UIWidgets/painting/text_painter.cs
  6. 13
      Assets/UIWidgets/painting/text_span.cs
  7. 10
      Assets/UIWidgets/physics/spring_simulation.cs
  8. 4
      Assets/UIWidgets/rendering/box.cs
  9. 34
      Assets/UIWidgets/rendering/object.cs
  10. 398
      Assets/UIWidgets/rendering/object.mixin.gen.cs
  11. 182
      Assets/UIWidgets/rendering/object.mixin.njk
  12. 4
      Assets/UIWidgets/rendering/proxy_box.cs
  13. 9
      Assets/UIWidgets/rendering/proxy_box.mixin.gen.cs
  14. 9
      Assets/UIWidgets/rendering/proxy_box.mixin.njk
  15. 16
      Assets/UIWidgets/rendering/shifted_box.cs
  16. 1
      Assets/UIWidgets/scheduler/ticker.cs
  17. 85
      Assets/UIWidgets/ui/text.cs
  18. 232
      Assets/UIWidgets/ui/txt/paragraph.cs
  19. 18
      Assets/UIWidgets/widgets/basic.cs
  20. 28
      Assets/UIWidgets/widgets/binding.cs
  21. 4
      Assets/UIWidgets/widgets/container.cs
  22. 977
      Assets/UIWidgets/widgets/framework.cs
  23. 12
      Assets/UIWidgets/widgets/image.cs
  24. 2
      Assets/UIWidgets/widgets/notification_listener.cs
  25. 196
      Assets/UIWidgets/widgets/scroll_activity.cs
  26. 148
      Assets/UIWidgets/widgets/scroll_position.cs
  27. 2
      Assets/UIWidgets/widgets/ticker_provider.cs
  28. 203
      Assets/UIWidgets/Tests/RenderEditable.cs
  29. 3
      Assets/UIWidgets/Tests/RenderEditable.cs.meta
  30. 8
      Assets/UIWidgets/animation.meta
  31. 61
      Assets/UIWidgets/foundation/key.cs
  32. 3
      Assets/UIWidgets/foundation/key.cs.meta
  33. 8
      Assets/UIWidgets/physics.meta
  34. 703
      Assets/UIWidgets/rendering/editable.cs
  35. 3
      Assets/UIWidgets/rendering/editable.cs.meta
  36. 3
      Assets/UIWidgets/service.meta
  37. 70
      Assets/UIWidgets/ui/txt/word_separate.cs
  38. 3
      Assets/UIWidgets/ui/txt/word_separate.cs.meta
  39. 78
      Assets/UIWidgets/widgets/debug.cs
  40. 3
      Assets/UIWidgets/widgets/debug.cs.meta
  41. 5
      Assets/UIWidgets/widgets/focus_manager.cs
  42. 3
      Assets/UIWidgets/widgets/focus_manager.cs.meta
  43. 191
      Assets/UIWidgets/service/text_editing.cs
  44. 3
      Assets/UIWidgets/service/text_editing.cs.meta
  45. 3
      Assets/UIWidgets/math.meta
  46. 0
      /Assets/UIWidgets/widgets/scroll_metrics.cs.meta
  47. 0
      /Assets/UIWidgets/widgets/scroll_metrics.cs

5
Assets/UIWidgets/Tests/Menu.cs


public static void gestures() {
EditorWindow.GetWindow(typeof(Gestures));
}
[MenuItem("UIWidgetsTests/RenderEditable")]
public static void renderEditable() {
EditorWindow.GetWindow(typeof(RenderEditable));
}
}
}

119
Assets/UIWidgets/foundation/diagnostics.cs


}
public class MessageProperty : DiagnosticsProperty<object> {
MessageProperty(String name, String message,
public MessageProperty(String name, String message,
DiagnosticLevel level = DiagnosticLevel.info
) : base(name, null, description: message, level: level) {
D.assert(name != null);

public class StringProperty : DiagnosticsProperty<string> {
StringProperty(string name, string value,
string description,
string tooltip,
public StringProperty(string name, string value,
string description = null,
string tooltip = null,
bool showName = true,
object defaultValue = null,
bool quoted = true,

}
}
public class ObjectFlagProperty<T> : DiagnosticsProperty<T> {
public ObjectFlagProperty(String name, T value,
string ifPresent = null,
String ifNull = null,
bool showName = false,
DiagnosticLevel level = DiagnosticLevel.info
) : base(
name,
value,
showName: showName,
ifNull: ifNull,
level: level
) {
D.assert(ifPresent != null || ifNull != null);
}
private ObjectFlagProperty(
String name,
T value,
DiagnosticLevel level = DiagnosticLevel.info
) : base(
name,
value,
showName: false,
level: level
) {
D.assert(name != null);
this.ifPresent = "has " + name;
}
public static ObjectFlagProperty<T> has(
String name,
T value,
DiagnosticLevel level = DiagnosticLevel.info
) {
return new ObjectFlagProperty<T>(name, value, level);
}
public readonly string ifPresent;
protected override string valueToString(
TextTreeConfiguration parentConfiguration = null) {
if (this.value != null) {
if (this.ifPresent != null) {
return this.ifPresent;
}
} else {
if (this.ifNull != null) {
return this.ifNull;
}
}
return base.valueToString(parentConfiguration: parentConfiguration);
}
public override bool showName {
get {
if ((this.value != null && this.ifPresent == null) || (this.value == null && this.ifNull == null)) {
return true;
}
return base.showName;
}
}
public override DiagnosticLevel level {
get {
if (this.value != null) {
if (this.ifPresent == null) {
return DiagnosticLevel.hidden;
}
} else {
if (this.ifNull == null) {
return DiagnosticLevel.hidden;
}
}
return base.level;
}
}
public override Dictionary<String, Object> toJsonMap() {
var json = base.toJsonMap();
if (this.ifPresent != null) {
json["ifPresent"] = this.ifPresent;
}
return json;
}
}
public delegate T ComputePropertyValueCallback<T>();
public class DiagnosticsProperty<T> : DiagnosticsNode {

}
D.assert(defaultValue == null || defaultValue == Diagnostics.kNoDefaultValue || defaultValue is T);
this._description = description;
this._valueComputed = true;
this._value = value;

this.ifEmpty = ifEmpty;
this.defaultValue = defaultValue;
this.tooltip = tooltip;

}
D.assert(defaultValue == null || defaultValue == Diagnostics.kNoDefaultValue || defaultValue is T);
this._description = description;
this._valueComputed = false;
this._value = default(T);

this.ifEmpty = ifEmpty;
this.defaultValue = defaultValue;
this.tooltip = tooltip;

public override Dictionary<string, object> toJsonMap() {
var json = base.toJsonMap();
if (this.defaultValue != Diagnostics.kNoDefaultValue) {
json["defaultValue"] = this.defaultValue == null ? "null" : this.defaultValue.ToString();
}

}
json["missingIfNull"] = this.missingIfNull;
if (typeof(Diagnosticable).IsAssignableFrom(typeof(T))) {
json["isDiagnosticableValue"] = true;
}

}
public readonly string ifNull;
public readonly bool missingIfNull;
public Type propertyType {

}
public readonly object defaultValue;
DiagnosticLevel _defaultLevel;
public override DiagnosticLevel level {

}
readonly T _value;
DiagnosticPropertiesBuilder _cachedBuilder;
DiagnosticPropertiesBuilder _builder {

);
}
protected internal virtual void debugFillProperties(DiagnosticPropertiesBuilder properties) {
public virtual void debugFillProperties(DiagnosticPropertiesBuilder properties) {
}
}

);
}
protected internal virtual List<DiagnosticsNode> debugDescribeChildren() {
public virtual List<DiagnosticsNode> debugDescribeChildren() {
return new List<DiagnosticsNode>();
}
}

);
internal static readonly _NoDefaultValue kNoDefaultValue = new _NoDefaultValue();
internal static readonly _NoDefaultValue kNullDefaultValue = new _NoDefaultValue();
internal static readonly _NullDefaultValue kNullDefaultValue = new _NullDefaultValue();
public static string shortHash(object o) {
return (o.GetHashCode() & 0xFFFFF).ToString("X").PadLeft(5, '0');

4
Assets/UIWidgets/gestures/recognizer.cs


public abstract void acceptGesture(int pointer);
public abstract void rejectGesture(int pointer);
protected internal override void debugFillProperties(DiagnosticPropertiesBuilder properties) {
public override void debugFillProperties(DiagnosticPropertiesBuilder properties) {
base.debugFillProperties(properties);
properties.add(new DiagnosticsProperty<object>("debugOwner", this.debugOwner,
defaultValue: Diagnostics.kNullDefaultValue));

return offset.distance;
}
protected internal override void debugFillProperties(DiagnosticPropertiesBuilder properties) {
public override void debugFillProperties(DiagnosticPropertiesBuilder properties) {
base.debugFillProperties(properties);
properties.add(new EnumProperty<GestureRecognizerState>("state", this.state));
}

2
Assets/UIWidgets/gestures/tap.cs


get { return "tap"; }
}
protected internal override void debugFillProperties(DiagnosticPropertiesBuilder properties) {
public override void debugFillProperties(DiagnosticPropertiesBuilder properties) {
base.debugFillProperties(properties);
properties.add(new FlagProperty("wonArenaForPrimaryPointer",
value: this._wonArenaForPrimaryPointer,

107
Assets/UIWidgets/painting/text_painter.cs


using System;
using System.Runtime.ConstrainedExecution;
using UIWidgets.math;
using System.Collections.Generic;
using UIWidgets.foundation;
using UIWidgets.service;
using Rect = UIWidgets.ui.Rect;
namespace UIWidgets.painting
{

if (minWidth != maxWidth)
{
var newWidth = MathUtil.Clamp(maxIntrinsicWidth, minWidth, maxWidth);
var newWidth = MathUtils.clamp(maxIntrinsicWidth, minWidth, maxWidth);
if (newWidth != width)
{
_paragraph.layout(new ParagraphConstraints(newWidth));

_paragraph.paint(canvas, offset.dx, offset.dy);
}
public Offset getOffsetForCaret(TextPosition position, Rect caretPrototype)
{
D.assert(!_needsLayout);
var offset = position.offset;
switch (position.affinity)
{
case TextAffinity.upstream:
return _getOffsetFromUpstream(offset, caretPrototype) ??
_getOffsetFromDownstream(offset, caretPrototype) ?? _emptyOffset;
case TextAffinity.downstream:
return _getOffsetFromDownstream(offset, caretPrototype) ??
_getOffsetFromUpstream(offset, caretPrototype) ?? _emptyOffset;
}
return null;
}
public List<TextBox> getBoxesForSelection(TextSelection selection)
{
D.assert(!_needsLayout);
var results = _paragraph.getRectsForRange(selection.start, selection.end);
if (results.Count > 0)
{
Debug.Log(string.Format(" getBoxesForSelection {0}", results[0]));
}
return results;
}
public TextPosition getPositionForOffset(Offset offset) {
D.assert(!_needsLayout);
var result = _paragraph.getGlyphPositionAtCoordinate(offset.dx, offset.dy);
return new TextPosition(result.position, result.affinity);
}
public TextRange getWordBoundary(TextPosition position)
{
D.assert(!_needsLayout);
var range = _paragraph.getWordBoundary(position.offset);
return new TextRange(range.start, range.end);
}
private ParagraphStyle _createParagraphStyle(TextDirection defaultTextDirection = TextDirection.ltr)
{
if (_text.style == null)

{
return Math.Ceiling(layoutValue);
}
private Offset _getOffsetFromUpstream(int offset, Rect caretPrototype) {
var prevCodeUnit = _text.codeUnitAt(offset - 1);
if (prevCodeUnit == null)
return null;
var prevRuneOffset = _isUtf16Surrogate((int)prevCodeUnit) ? offset - 2 : offset - 1;
var boxes = _paragraph.getRectsForRange(prevRuneOffset, offset);
if (boxes.Count == 0)
return null;
var box = boxes[0];
var caretEnd = box.end;
var dx = box.direction == TextDirection.rtl ? caretEnd : caretEnd - caretPrototype.width;
return new Offset(dx, box.top);
}
private Offset _getOffsetFromDownstream(int offset, Rect caretPrototype) {
var nextCodeUnit = _text.codeUnitAt(offset);
if (nextCodeUnit == null)
return null;
var nextRuneOffset = _isUtf16Surrogate((int)nextCodeUnit) ? offset + 2 : offset + 1;
var boxes = _paragraph.getRectsForRange(offset, nextRuneOffset);
if (boxes.Count == 0)
return null;
var box = boxes[0];
var caretStart = box.start;
var dx = box.direction == TextDirection.rtl ? caretStart - caretPrototype.width : caretStart;
return new Offset(dx, box.top);
}
private Offset _emptyOffset
{
get
{
D.assert(!_needsLayout);
switch (textAlign)
{
case TextAlign.left:
return Offset.zero;
case TextAlign.right:
return new Offset(width, 0.0);
case TextAlign.center:
return new Offset(width / 2.0, 0.0);
case TextAlign.justify:
if (textDirection == TextDirection.rtl)
{
return new Offset(width, 0.0);
}
return Offset.zero;
}
return null;
}
}
private static bool _isUtf16Surrogate(int value)
{
return (value & 0xF800) == 0xD800;
}
}
}

13
Assets/UIWidgets/painting/text_span.cs


return sb.ToString();
}
public int codeUnitAt(int index)
public int? codeUnitAt(int index)
return -1;
return null;
}
var offset = 0;

if (ReferenceEquals(this, other)) return true;
return Equals(style, other.style) && string.Equals(text, other.text) && childEquals(children, other.children);
}
public static bool operator ==(TextSpan left, TextSpan right)
{
return Equals(left, right);
}
public static bool operator !=(TextSpan left, TextSpan right)
{
return !Equals(left, right);
}
private int childHash()
{
unchecked

10
Assets/UIWidgets/physics/spring_simulation.cs


) : base(spring, start, end, velocity, tolerance: tolerance) {
}
public double x(double time) {
public override double x(double time) {
public static _SpringSolution create(
internal static _SpringSolution create(
SpringDescription spring,
double initialPosition,
double initialVelocity

}
class _CriticalSolution : _SpringSolution {
internal static _CriticalSolution create(
internal new static _CriticalSolution create(
SpringDescription spring,
double distance,
double velocity

}
class _OverdampedSolution : _SpringSolution {
internal static _OverdampedSolution create(
internal new static _OverdampedSolution create(
SpringDescription spring,
double distance,
double velocity

}
class _UnderdampedSolution : _SpringSolution {
internal static _UnderdampedSolution create(
internal new static _UnderdampedSolution create(
SpringDescription spring,
double distance,
double velocity

4
Assets/UIWidgets/rendering/box.cs


return false;
}
protected bool hitTestChildren(HitTestResult result, Offset position = null) {
protected virtual bool hitTestChildren(HitTestResult result, Offset position = null) {
return false;
}

return true;
}
protected internal override void debugFillProperties(DiagnosticPropertiesBuilder properties) {
public override void debugFillProperties(DiagnosticPropertiesBuilder properties) {
base.debugFillProperties(properties);
properties.add(new DiagnosticsProperty<Size>("size", this._size, missingIfNull: true));
}

34
Assets/UIWidgets/rendering/object.cs


}
}
public interface RenderObjectWithChildMixin {
bool debugValidateChild(RenderObject child);
RenderObject child { get; set; }
}
}
public interface ContainerRenderObjectMixin {
int childCount { get; }
bool debugValidateChild(RenderObject child);
void insert(RenderObject child, RenderObject after = null);
void remove(RenderObject child);
void move(RenderObject child, RenderObject after = null);
RenderObject firstChild { get; }
RenderObject lastChild { get; }
RenderObject childBefore(RenderObject child);
RenderObject childAfter(RenderObject child);
}
public abstract class RenderObject : AbstractNodeMixinDiagnosticableTree, HitTestTarget {

}
}
public bool _needsLayout = true;
public bool debugNeedsLayout {
get {
bool result = false;
D.assert(() => {
result = this._needsLayout;
return true;
});
return result;
}
}
internal bool _needsLayout = true;
public RenderObject _relayoutBoundary;
bool _doingThisLayoutWithCallback = false;

public virtual void handleEvent(PointerEvent evt, HitTestEntry entry) {
}
protected internal override void debugFillProperties(DiagnosticPropertiesBuilder properties) {
public override void debugFillProperties(DiagnosticPropertiesBuilder properties) {
properties.add(new DiagnosticsProperty<object>(
"creator", this.debugCreator, defaultValue: Diagnostics.kNullDefaultValue,
level: DiagnosticLevel.debug));

398
Assets/UIWidgets/rendering/object.mixin.gen.cs


namespace UIWidgets.rendering {
public abstract class RenderObjectWithChildMixinRenderObject<ChildType> : RenderObject where ChildType : RenderObject {
public ChildType _child;
public abstract class RenderObjectWithChildMixinRenderObject<ChildType> : RenderObject, RenderObjectWithChildMixin where ChildType : RenderObject {
internal ChildType _child;
public ChildType child {
get { return this._child; }

}
}
RenderObject RenderObjectWithChildMixin.child {
get { return this.child; }
set { this.child = (ChildType) value; }
}
public bool debugValidateChild(RenderObject child) {
D.assert(() => {
if (!(child is ChildType)) {
throw new UIWidgetsError(
"A " + this.GetType() + " expected a child of type " + typeof(ChildType) + " but received a " +
"child of type " + child.GetType() + ".\n" +
"RenderObjects expect specific types of children because they " +
"coordinate with their children during layout and paint. For " +
"example, a RenderSliver cannot be the child of a RenderBox because " +
"a RenderSliver does not understand the RenderBox layout protocol.\n" +
"\n" +
"The " + this.GetType() + " that expected a " + typeof(ChildType) + " child was created by:\n" +
" " + this.debugCreator + "\n" +
"\n" +
"The " + child.GetType() + " that did not match the expected child type " +
"was created by:\n" +
" " + child.debugCreator + "\n"
);
}
return true;
});
return true;
}
public override void attach(object owner) {
base.attach(owner);
if (this._child != null) {

}
public abstract class RenderObjectWithChildMixinRenderBox<ChildType> : RenderBox where ChildType : RenderObject {
public ChildType _child;
public abstract class RenderObjectWithChildMixinRenderBox<ChildType> : RenderBox, RenderObjectWithChildMixin where ChildType : RenderObject {
internal ChildType _child;
public ChildType child {
get { return this._child; }

}
}
RenderObject RenderObjectWithChildMixin.child {
get { return this.child; }
set { this.child = (ChildType) value; }
}
public bool debugValidateChild(RenderObject child) {
D.assert(() => {
if (!(child is ChildType)) {
throw new UIWidgetsError(
"A " + this.GetType() + " expected a child of type " + typeof(ChildType) + " but received a " +
"child of type " + child.GetType() + ".\n" +
"RenderObjects expect specific types of children because they " +
"coordinate with their children during layout and paint. For " +
"example, a RenderSliver cannot be the child of a RenderBox because " +
"a RenderSliver does not understand the RenderBox layout protocol.\n" +
"\n" +
"The " + this.GetType() + " that expected a " + typeof(ChildType) + " child was created by:\n" +
" " + this.debugCreator + "\n" +
"\n" +
"The " + child.GetType() + " that did not match the expected child type " +
"was created by:\n" +
" " + child.debugCreator + "\n"
);
}
return true;
});
return true;
}
public override void attach(object owner) {
base.attach(owner);
if (this._child != null) {

}
public abstract class RenderObjectWithChildMixinRenderSliver<ChildType> : RenderSliver where ChildType : RenderObject {
public ChildType _child;
public abstract class RenderObjectWithChildMixinRenderSliver<ChildType> : RenderSliver, RenderObjectWithChildMixin where ChildType : RenderObject {
internal ChildType _child;
public ChildType child {
get { return this._child; }

}
}
RenderObject RenderObjectWithChildMixin.child {
get { return this.child; }
set { this.child = (ChildType) value; }
}
public bool debugValidateChild(RenderObject child) {
D.assert(() => {
if (!(child is ChildType)) {
throw new UIWidgetsError(
"A " + this.GetType() + " expected a child of type " + typeof(ChildType) + " but received a " +
"child of type " + child.GetType() + ".\n" +
"RenderObjects expect specific types of children because they " +
"coordinate with their children during layout and paint. For " +
"example, a RenderSliver cannot be the child of a RenderBox because " +
"a RenderSliver does not understand the RenderBox layout protocol.\n" +
"\n" +
"The " + this.GetType() + " that expected a " + typeof(ChildType) + " child was created by:\n" +
" " + this.debugCreator + "\n" +
"\n" +
"The " + child.GetType() + " that did not match the expected child type " +
"was created by:\n" +
" " + child.debugCreator + "\n"
);
}
return true;
});
return true;
}
public override void attach(object owner) {
base.attach(owner);
if (this._child != null) {

public abstract class ContainerRenderObjectMixinRenderBox<ChildType, ParentDataType> : RenderBox
public abstract class ContainerRenderObjectMixinRenderBox<ChildType, ParentDataType> : RenderBox, ContainerRenderObjectMixin
public int _childCount = 0;
bool _debugUltimatePreviousSiblingOf(ChildType child, ChildType equals = null) {
ParentDataType childParentData = (ParentDataType) child.parentData;
while (childParentData.previousSibling != null) {
D.assert(childParentData.previousSibling != child);
child = childParentData.previousSibling;
childParentData = (ParentDataType) child.parentData;
}
return child == equals;
}
bool _debugUltimateNextSiblingOf(ChildType child, ChildType equals = null) {
ParentDataType childParentData = (ParentDataType) child.parentData;
while (childParentData.nextSibling != null) {
D.assert(childParentData.nextSibling != child);
child = childParentData.nextSibling;
childParentData = (ParentDataType) child.parentData;
}
return child == equals;
}
int _childCount = 0;
public ChildType _firstChild;
public bool debugValidateChild(RenderObject child) {
D.assert(() => {
if (!(child is ChildType)) {
throw new UIWidgetsError(
"A " + this.GetType() + " expected a child of type " + typeof(ChildType) + " but received a " +
"child of type " + child.GetType() + ".\n" +
"RenderObjects expect specific types of children because they " +
"coordinate with their children during layout and paint. For " +
"example, a RenderSliver cannot be the child of a RenderBox because " +
"a RenderSliver does not understand the RenderBox layout protocol.\n" +
"\n" +
"The " + this.GetType() + " that expected a $ChildType child was created by:\n" +
" " + this.debugCreator + "\n" +
"\n" +
"The " + child.GetType() + " that did not match the expected child type " +
"was created by:\n" +
" " + child.debugCreator + "\n"
);
}
return true;
});
return true;
}
ChildType _firstChild;
public ChildType _lastChild;
ChildType _lastChild;
public void _insertIntoChildList(ChildType child, ChildType after = null) {
void _insertIntoChildList(ChildType child, ChildType after = null) {
D.assert(childParentData.nextSibling == null);
D.assert(childParentData.previousSibling == null);
D.assert(this._childCount > 0);
if (after == null) {
childParentData.nextSibling = this._firstChild;
if (this._firstChild != null) {

this._firstChild = child;
if (this._lastChild == null) {
this._lastChild = child;
}
this._lastChild = this._lastChild ?? child;
D.assert(this._firstChild != null);
D.assert(this._lastChild != null);
D.assert(this._debugUltimatePreviousSiblingOf(after, equals: this._firstChild));
D.assert(this._debugUltimateNextSiblingOf(after, equals: this._lastChild));
D.assert(after == this._lastChild);
childParentData.previousSibling = after;
afterParentData.nextSibling = child;
this._lastChild = child;

var childNextSiblingParentData = (ParentDataType) childParentData.nextSibling.parentData;
childPreviousSiblingParentData.nextSibling = child;
childNextSiblingParentData.previousSibling = child;
D.assert(afterParentData.nextSibling == child);
D.assert(child != this, "A RenderObject cannot be inserted into itself.");
D.assert(after != this,
"A RenderObject cannot simultaneously be both the parent and the sibling of another RenderObject.");
D.assert(child != after, "A RenderObject cannot be inserted after itself.");
D.assert(child != this._firstChild);
D.assert(child != this._lastChild);
this.adoptChild(child);
this._insertIntoChildList(child, after);
}

public void _removeFromChildList(ChildType child) {
var childParentData = (ParentDataType) child.parentData;
D.assert(this._debugUltimatePreviousSiblingOf(child, equals: this._firstChild));
D.assert(this._debugUltimateNextSiblingOf(child, equals: this._lastChild));
D.assert(this._childCount >= 0);
D.assert(this._firstChild == child);
this._firstChild = childParentData.nextSibling;
} else {
var childPreviousSiblingParentData = (ParentDataType) childParentData.previousSibling.parentData;

if (childParentData.nextSibling == null) {
D.assert(this._lastChild == child);
this._lastChild = childParentData.previousSibling;
} else {
var childNextSiblingParentData = (ParentDataType) childParentData.nextSibling.parentData;

this.dropChild(child);
child = next;
}
this._firstChild = null;
this._lastChild = null;
this._childCount = 0;

D.assert(child != this);
D.assert(after != this);
D.assert(child != after);
D.assert(child.parent == this);
this._removeFromChildList(child);
this._insertIntoChildList(child, after);
this.markNeedsLayout();

}
public ChildType childBefore(ChildType child) {
D.assert(child != null);
D.assert(child.parent == this);
D.assert(child != null);
D.assert(child.parent == this);
public override List<DiagnosticsNode> debugDescribeChildren() {
var children = new List<DiagnosticsNode>();
if (this.firstChild != null) {
ChildType child = this.firstChild;
int count = 1;
while (true) {
children.Add(child.toDiagnosticsNode(name: "child " + count));
if (child == this.lastChild) {
break;
}
count += 1;
var childParentData = (ParentDataType) child.parentData;
child = childParentData.nextSibling;
}
}
return children;
}
void ContainerRenderObjectMixin.insert(RenderObject child, RenderObject after) {
this.insert((ChildType) child, (ChildType) after);
}
void ContainerRenderObjectMixin.remove(RenderObject child) {
this.remove((ChildType) child);
}
void ContainerRenderObjectMixin.move(RenderObject child, RenderObject after) {
this.move((ChildType) child, (ChildType) after);
}
RenderObject ContainerRenderObjectMixin.firstChild {
get { return this.firstChild; }
}
RenderObject ContainerRenderObjectMixin.lastChild {
get { return this.lastChild; }
}
RenderObject ContainerRenderObjectMixin.childBefore(RenderObject child) {
return this.childBefore((ChildType) child);
}
RenderObject ContainerRenderObjectMixin.childAfter(RenderObject child) {
return this.childAfter((ChildType) child);
}
public abstract class ContainerRenderObjectMixinRenderSliver<ChildType, ParentDataType> : RenderSliver
public abstract class ContainerRenderObjectMixinRenderSliver<ChildType, ParentDataType> : RenderSliver, ContainerRenderObjectMixin
public int _childCount = 0;
bool _debugUltimatePreviousSiblingOf(ChildType child, ChildType equals = null) {
ParentDataType childParentData = (ParentDataType) child.parentData;
while (childParentData.previousSibling != null) {
D.assert(childParentData.previousSibling != child);
child = childParentData.previousSibling;
childParentData = (ParentDataType) child.parentData;
}
return child == equals;
}
bool _debugUltimateNextSiblingOf(ChildType child, ChildType equals = null) {
ParentDataType childParentData = (ParentDataType) child.parentData;
while (childParentData.nextSibling != null) {
D.assert(childParentData.nextSibling != child);
child = childParentData.nextSibling;
childParentData = (ParentDataType) child.parentData;
}
return child == equals;
}
int _childCount = 0;
public ChildType _firstChild;
public bool debugValidateChild(RenderObject child) {
D.assert(() => {
if (!(child is ChildType)) {
throw new UIWidgetsError(
"A " + this.GetType() + " expected a child of type " + typeof(ChildType) + " but received a " +
"child of type " + child.GetType() + ".\n" +
"RenderObjects expect specific types of children because they " +
"coordinate with their children during layout and paint. For " +
"example, a RenderSliver cannot be the child of a RenderBox because " +
"a RenderSliver does not understand the RenderBox layout protocol.\n" +
"\n" +
"The " + this.GetType() + " that expected a $ChildType child was created by:\n" +
" " + this.debugCreator + "\n" +
"\n" +
"The " + child.GetType() + " that did not match the expected child type " +
"was created by:\n" +
" " + child.debugCreator + "\n"
);
}
return true;
});
return true;
}
ChildType _firstChild;
public ChildType _lastChild;
ChildType _lastChild;
public void _insertIntoChildList(ChildType child, ChildType after = null) {
void _insertIntoChildList(ChildType child, ChildType after = null) {
D.assert(childParentData.nextSibling == null);
D.assert(childParentData.previousSibling == null);
D.assert(this._childCount > 0);
if (after == null) {
childParentData.nextSibling = this._firstChild;
if (this._firstChild != null) {

this._firstChild = child;
if (this._lastChild == null) {
this._lastChild = child;
}
this._lastChild = this._lastChild ?? child;
D.assert(this._firstChild != null);
D.assert(this._lastChild != null);
D.assert(this._debugUltimatePreviousSiblingOf(after, equals: this._firstChild));
D.assert(this._debugUltimateNextSiblingOf(after, equals: this._lastChild));
D.assert(after == this._lastChild);
childParentData.previousSibling = after;
afterParentData.nextSibling = child;
this._lastChild = child;

var childNextSiblingParentData = (ParentDataType) childParentData.nextSibling.parentData;
childPreviousSiblingParentData.nextSibling = child;
childNextSiblingParentData.previousSibling = child;
D.assert(afterParentData.nextSibling == child);
D.assert(child != this, "A RenderObject cannot be inserted into itself.");
D.assert(after != this,
"A RenderObject cannot simultaneously be both the parent and the sibling of another RenderObject.");
D.assert(child != after, "A RenderObject cannot be inserted after itself.");
D.assert(child != this._firstChild);
D.assert(child != this._lastChild);
this.adoptChild(child);
this._insertIntoChildList(child, after);
}

public void _removeFromChildList(ChildType child) {
var childParentData = (ParentDataType) child.parentData;
D.assert(this._debugUltimatePreviousSiblingOf(child, equals: this._firstChild));
D.assert(this._debugUltimateNextSiblingOf(child, equals: this._lastChild));
D.assert(this._childCount >= 0);
D.assert(this._firstChild == child);
this._firstChild = childParentData.nextSibling;
} else {
var childPreviousSiblingParentData = (ParentDataType) childParentData.previousSibling.parentData;

if (childParentData.nextSibling == null) {
D.assert(this._lastChild == child);
this._lastChild = childParentData.previousSibling;
} else {
var childNextSiblingParentData = (ParentDataType) childParentData.nextSibling.parentData;

this.dropChild(child);
child = next;
}
this._firstChild = null;
this._lastChild = null;
this._childCount = 0;

D.assert(child != this);
D.assert(after != this);
D.assert(child != after);
D.assert(child.parent == this);
this._removeFromChildList(child);
this._insertIntoChildList(child, after);
this.markNeedsLayout();

}
public ChildType childBefore(ChildType child) {
D.assert(child != null);
D.assert(child.parent == this);
D.assert(child != null);
D.assert(child.parent == this);
}
public override List<DiagnosticsNode> debugDescribeChildren() {
var children = new List<DiagnosticsNode>();
if (this.firstChild != null) {
ChildType child = this.firstChild;
int count = 1;
while (true) {
children.Add(child.toDiagnosticsNode(name: "child " + count));
if (child == this.lastChild) {
break;
}
count += 1;
var childParentData = (ParentDataType) child.parentData;
child = childParentData.nextSibling;
}
}
return children;
}
void ContainerRenderObjectMixin.insert(RenderObject child, RenderObject after) {
this.insert((ChildType) child, (ChildType) after);
}
void ContainerRenderObjectMixin.remove(RenderObject child) {
this.remove((ChildType) child);
}
void ContainerRenderObjectMixin.move(RenderObject child, RenderObject after) {
this.move((ChildType) child, (ChildType) after);
}
RenderObject ContainerRenderObjectMixin.firstChild {
get { return this.firstChild; }
}
RenderObject ContainerRenderObjectMixin.lastChild {
get { return this.lastChild; }
}
RenderObject ContainerRenderObjectMixin.childBefore(RenderObject child) {
return this.childBefore((ChildType) child);
}
RenderObject ContainerRenderObjectMixin.childAfter(RenderObject child) {
return this.childAfter((ChildType) child);
}
}

182
Assets/UIWidgets/rendering/object.mixin.njk


namespace UIWidgets.rendering {
{% macro RenderObjectWithChildMixin(with) %}
public abstract class RenderObjectWithChildMixin{{with}}<ChildType> : {{with}} where ChildType : RenderObject {
public ChildType _child;
public abstract class RenderObjectWithChildMixin{{with}}<ChildType> : {{with}}, RenderObjectWithChildMixin where ChildType : RenderObject {
internal ChildType _child;
public ChildType child {
get { return this._child; }

this.adoptChild(this._child);
}
}
}
RenderObject RenderObjectWithChildMixin.child {
get { return this.child; }
set { this.child = (ChildType) value; }
}
public bool debugValidateChild(RenderObject child) {
D.assert(() => {
if (!(child is ChildType)) {
throw new UIWidgetsError(
"A " + this.GetType() + " expected a child of type " + typeof(ChildType) + " but received a " +
"child of type " + child.GetType() + ".\n" +
"RenderObjects expect specific types of children because they " +
"coordinate with their children during layout and paint. For " +
"example, a RenderSliver cannot be the child of a RenderBox because " +
"a RenderSliver does not understand the RenderBox layout protocol.\n" +
"\n" +
"The " + this.GetType() + " that expected a " + typeof(ChildType) + " child was created by:\n" +
" " + this.debugCreator + "\n" +
"\n" +
"The " + child.GetType() + " that did not match the expected child type " +
"was created by:\n" +
" " + child.debugCreator + "\n"
);
}
return true;
});
return true;
}
public override void attach(object owner) {

{% macro ContainerRenderObjectMixin(with) %}
public abstract class ContainerRenderObjectMixin{{with}}<ChildType, ParentDataType> : {{with}}
public abstract class ContainerRenderObjectMixin{{with}}<ChildType, ParentDataType> : {{with}}, ContainerRenderObjectMixin
public int _childCount = 0;
bool _debugUltimatePreviousSiblingOf(ChildType child, ChildType equals = null) {
ParentDataType childParentData = (ParentDataType) child.parentData;
while (childParentData.previousSibling != null) {
D.assert(childParentData.previousSibling != child);
child = childParentData.previousSibling;
childParentData = (ParentDataType) child.parentData;
}
return child == equals;
}
bool _debugUltimateNextSiblingOf(ChildType child, ChildType equals = null) {
ParentDataType childParentData = (ParentDataType) child.parentData;
while (childParentData.nextSibling != null) {
D.assert(childParentData.nextSibling != child);
child = childParentData.nextSibling;
childParentData = (ParentDataType) child.parentData;
}
return child == equals;
}
int _childCount = 0;
public ChildType _firstChild;
public bool debugValidateChild(RenderObject child) {
D.assert(() => {
if (!(child is ChildType)) {
throw new UIWidgetsError(
"A " + this.GetType() + " expected a child of type " + typeof(ChildType) + " but received a " +
"child of type " + child.GetType() + ".\n" +
"RenderObjects expect specific types of children because they " +
"coordinate with their children during layout and paint. For " +
"example, a RenderSliver cannot be the child of a RenderBox because " +
"a RenderSliver does not understand the RenderBox layout protocol.\n" +
"\n" +
"The " + this.GetType() + " that expected a $ChildType child was created by:\n" +
" " + this.debugCreator + "\n" +
"\n" +
"The " + child.GetType() + " that did not match the expected child type " +
"was created by:\n" +
" " + child.debugCreator + "\n"
);
}
public ChildType _lastChild;
return true;
});
return true;
}
ChildType _firstChild;
ChildType _lastChild;
public void _insertIntoChildList(ChildType child, ChildType after = null) {
void _insertIntoChildList(ChildType child, ChildType after = null) {
D.assert(childParentData.nextSibling == null);
D.assert(childParentData.previousSibling == null);
D.assert(this._childCount > 0);
if (after == null) {
childParentData.nextSibling = this._firstChild;
if (this._firstChild != null) {

this._firstChild = child;
if (this._lastChild == null) {
this._lastChild = child;
}
this._lastChild = this._lastChild ?? child;
D.assert(this._firstChild != null);
D.assert(this._lastChild != null);
D.assert(this._debugUltimatePreviousSiblingOf(after, equals: this._firstChild));
D.assert(this._debugUltimateNextSiblingOf(after, equals: this._lastChild));
D.assert(after == this._lastChild);
childParentData.previousSibling = after;
afterParentData.nextSibling = child;
this._lastChild = child;

var childNextSiblingParentData = (ParentDataType) childParentData.nextSibling.parentData;
childPreviousSiblingParentData.nextSibling = child;
childNextSiblingParentData.previousSibling = child;
D.assert(afterParentData.nextSibling == child);
D.assert(child != this, "A RenderObject cannot be inserted into itself.");
D.assert(after != this,
"A RenderObject cannot simultaneously be both the parent and the sibling of another RenderObject.");
D.assert(child != after, "A RenderObject cannot be inserted after itself.");
D.assert(child != this._firstChild);
D.assert(child != this._lastChild);
this.adoptChild(child);
this._insertIntoChildList(child, after);
}

public void _removeFromChildList(ChildType child) {
var childParentData = (ParentDataType) child.parentData;
D.assert(this._debugUltimatePreviousSiblingOf(child, equals: this._firstChild));
D.assert(this._debugUltimateNextSiblingOf(child, equals: this._lastChild));
D.assert(this._childCount >= 0);
D.assert(this._firstChild == child);
this._firstChild = childParentData.nextSibling;
} else {
var childPreviousSiblingParentData = (ParentDataType) childParentData.previousSibling.parentData;

if (childParentData.nextSibling == null) {
D.assert(this._lastChild == child);
this._lastChild = childParentData.previousSibling;
} else {
var childNextSiblingParentData = (ParentDataType) childParentData.nextSibling.parentData;

this.dropChild(child);
child = next;
}
this._firstChild = null;
this._lastChild = null;
this._childCount = 0;

D.assert(child != this);
D.assert(after != this);
D.assert(child != after);
D.assert(child.parent == this);
this._removeFromChildList(child);
this._insertIntoChildList(child, after);
this.markNeedsLayout();

}
public ChildType childBefore(ChildType child) {
D.assert(child != null);
D.assert(child.parent == this);
D.assert(child != null);
D.assert(child.parent == this);
}
public override List<DiagnosticsNode> debugDescribeChildren() {
var children = new List<DiagnosticsNode>();
if (this.firstChild != null) {
ChildType child = this.firstChild;
int count = 1;
while (true) {
children.Add(child.toDiagnosticsNode(name: "child " + count));
if (child == this.lastChild) {
break;
}
count += 1;
var childParentData = (ParentDataType) child.parentData;
child = childParentData.nextSibling;
}
}
return children;
}
void ContainerRenderObjectMixin.insert(RenderObject child, RenderObject after) {
this.insert((ChildType) child, (ChildType) after);
}
void ContainerRenderObjectMixin.remove(RenderObject child) {
this.remove((ChildType) child);
}
void ContainerRenderObjectMixin.move(RenderObject child, RenderObject after) {
this.move((ChildType) child, (ChildType) after);
}
RenderObject ContainerRenderObjectMixin.firstChild {
get { return this.firstChild; }
}
RenderObject ContainerRenderObjectMixin.lastChild {
get { return this.lastChild; }
}
RenderObject ContainerRenderObjectMixin.childBefore(RenderObject child) {
return this.childBefore((ChildType) child);
}
RenderObject ContainerRenderObjectMixin.childAfter(RenderObject child) {
return this.childAfter((ChildType) child);
}
}
{% endmacro %}

4
Assets/UIWidgets/rendering/proxy_box.cs


return this.behavior == HitTestBehavior.opaque;
}
protected internal override void debugFillProperties(DiagnosticPropertiesBuilder properties) {
public override void debugFillProperties(DiagnosticPropertiesBuilder properties) {
base.debugFillProperties(properties);
properties.add(new EnumProperty<HitTestBehavior>(
"behavior", this.behavior, defaultValue: Diagnostics.kNullDefaultValue));

}
}
protected internal override void debugFillProperties(DiagnosticPropertiesBuilder properties) {
public override void debugFillProperties(DiagnosticPropertiesBuilder properties) {
base.debugFillProperties(properties);
var listeners = new List<string>();
if (this.onPointerDown != null)

9
Assets/UIWidgets/rendering/proxy_box.mixin.gen.cs


using UIWidgets.ui;
using UIWidgets.gestures;
using UnityEngine;
namespace UIWidgets.rendering {

if (this.child != null) {
context.paintChild(this.child, offset);
}
}
protected override bool hitTestChildren(HitTestResult result, Offset position = null) {
if (this.child != null) {
return this.child.hitTest(result, position);
}
return false;
}
}

9
Assets/UIWidgets/rendering/proxy_box.mixin.njk


using UIWidgets.ui;
using UIWidgets.gestures;
using UnityEngine;
namespace UIWidgets.rendering {

if (this.child != null) {
context.paintChild(this.child, offset);
}
}
protected override bool hitTestChildren(HitTestResult result, Offset position = null) {
if (this.child != null) {
return this.child.hitTest(result, position);
}
return false;
}
}
{% endmacro %}

16
Assets/UIWidgets/rendering/shifted_box.cs


using System;
using UIWidgets.gestures;
using UIWidgets.painting;
using UIWidgets.ui;

var childParentData = (BoxParentData) this.child.parentData;
context.paintChild(this.child, childParentData.offset + offset);
}
}
protected override bool hitTestChildren(HitTestResult result, Offset position = null)
{
if (child != null)
{
var childParentData = child.parentData as BoxParentData;
if (childParentData != null)
{
position = position - childParentData.offset;
}
return child.hitTest(result, position);
}
return false;
}
}

1
Assets/UIWidgets/scheduler/ticker.cs


public interface TickerProvider {
Ticker createTicker(TickerCallback onTick);
SchedulerBinding schedulerBinding { get; }
}
public class Ticker {

85
Assets/UIWidgets/ui/text.cs


}
}
}
public class TextBox: IEquatable<TextBox>
{
public readonly double left;
public readonly double top;
public readonly double right;
public readonly double bottom;
public readonly TextDirection direction;
private TextBox(double left, double top, double right, double bottom, TextDirection direction)
{
this.left = left;
this.top = top;
this.right = right;
this.bottom = bottom;
this.direction = direction;
}
public static TextBox fromLTBD(double left, double top, double right, double bottom, TextDirection direction)
{
return new TextBox(left, top, right, bottom, direction);
}
public Rect toRect()
{
return Rect.fromLTRB(left, top, right, bottom);
}
public double start
{
get { return direction == TextDirection.ltr ? left : right; }
}
public double end
{
get { return direction == TextDirection.ltr ? right : left; }
}
public bool Equals(TextBox other)
{
if (ReferenceEquals(null, other)) return false;
if (ReferenceEquals(this, other)) return true;
return left.Equals(other.left) && top.Equals(other.top) && right.Equals(other.right) && bottom.Equals(other.bottom) && direction == other.direction;
}
public override bool Equals(object obj)
{
if (ReferenceEquals(null, obj)) return false;
if (ReferenceEquals(this, obj)) return true;
if (obj.GetType() != this.GetType()) return false;
return Equals((TextBox) obj);
}
public override string ToString()
{
return string.Format("Left: {0}, Top: {1}, Right: {2}, Bottom: {3}, Direction: {4}", left, top, right, bottom, direction);
}
public override int GetHashCode()
{
unchecked
{
var hashCode = left.GetHashCode();
hashCode = (hashCode * 397) ^ top.GetHashCode();
hashCode = (hashCode * 397) ^ right.GetHashCode();
hashCode = (hashCode * 397) ^ bottom.GetHashCode();
hashCode = (hashCode * 397) ^ (int) direction;
return hashCode;
}
}
public static bool operator ==(TextBox left, TextBox right)
{
return Equals(left, right);
}
public static bool operator !=(TextBox left, TextBox right)
{
return !Equals(left, right);
}
}
}

232
Assets/UIWidgets/ui/txt/paragraph.cs


using System;
using System.Collections.Generic;
using UIWidgets.painting;
using UIWidgets.ui.txt;
using UnityEngine;

return new Vector2d(a.x - b.x, a.y - b.y);
}
}
public class CodeUnitRun
{
public int lineNumber;
public TextDirection direction;
public IndexRange codeUnits;
public FontMetrics fontMetrics;
public CodeUnitRun(IndexRange cu, int line, FontMetrics fontMetrics, TextDirection direction)
{
this.lineNumber = line;
this.codeUnits = cu;
this.fontMetrics = fontMetrics;
this.direction = direction;
}
}
public class FontMetrics
{
public readonly double ascent;
public readonly double descent;
public FontMetrics(double ascent, double descent)
{
this.ascent = ascent;
this.descent = descent;
}
}
public struct IndexRange :IEquatable<IndexRange>
{
public int start, end;
public IndexRange(int s, int e)
{
start = s;
end = e;
}
int width()
{
return end - start;
}
void shift(int delta)
{
start += delta;
end += delta;
}
public bool Equals(IndexRange other)
{
return start == other.start && end == other.end;
}
public override bool Equals(object obj)
{
if (ReferenceEquals(null, obj)) return false;
return obj is IndexRange && Equals((IndexRange) obj);
}
public override int GetHashCode()
{
unchecked
{
return (start * 397) ^ end;
}
}
public static bool operator ==(IndexRange left, IndexRange right)
{
return left.Equals(right);
}
public static bool operator !=(IndexRange left, IndexRange right)
{
return !left.Equals(right);
}
}
public class PositionWithAffinity
{
public readonly int position;
public readonly TextAffinity affinity;
public PositionWithAffinity(int p, TextAffinity a)
{
position = p;
affinity = a;
}
}
public class Paragraph
{

private ParagraphStyle _paragraphStyle;
private List<LineRange> _lineRanges = new List<LineRange>();
private List<double> _lineWidths = new List<double>();
private List<double> _lineBaseLines = new List<double>();
private Vector2d[] _characterPositions;
private double _maxIntrinsicWidth;
private double _minIntrinsicWidth;

private List<double> _lineHeights = new List<double>();
private List<PaintRecord> _paintRecords = new List<PaintRecord>();
private List<CodeUnitRun> _codeUnitRuns = new List<CodeUnitRun>();
private bool _didExceedMaxLines;
// private double _characterWidth;

_paragraphStyle = style;
}
public List<TextBox> getRectsForRange(int start, int end)
{
var lineBoxes = new SortedDictionary<int, List<TextBox>>();
foreach (var run in _codeUnitRuns)
{
if (run.codeUnits.start >= end)
{
break;
}
if (run.codeUnits.end <= start)
{
continue;
}
var baseLine = _lineBaseLines[run.lineNumber];
double top = baseLine - run.fontMetrics.ascent;
double bottom = baseLine + run.fontMetrics.descent;
// double left, right;
var from = Math.Max(start, run.codeUnits.start);
var to = Math.Min(end, run.codeUnits.end);
if (from < to)
{
List<TextBox> boxs;
if (!lineBoxes.TryGetValue(run.lineNumber, out boxs))
{
boxs = new List<TextBox>();
lineBoxes.Add(run.lineNumber, boxs);
}
double left = _characterPositions[from].x;
double right = _characterPositions[to - 1].x + _characterWidths[to - 1];
boxs.Add(TextBox.fromLTBD(left, top, right, bottom, run.direction));
}
}
for (int lineNumber = 0; lineNumber < _lineRanges.Count; ++lineNumber)
{
var line = _lineRanges[lineNumber];
if (line.start >= end)
{
break;
}
if (line.endIncludingNewLine <= start)
{
continue;
}
if (!lineBoxes.ContainsKey(lineNumber))
{
if (line.end != line.endIncludingNewLine && line.end >= start && line.endIncludingNewLine <= end)
{
var x = _lineWidths[lineNumber];
var top = (lineNumber > 0) ? _lineHeights[lineNumber - 1] : 0;
var bottom = _lineHeights[lineNumber];
lineBoxes.Add(lineNumber, new List<TextBox>(){TextBox.fromLTBD(
x, top, x, bottom, TextDirection.ltr)});
}
}
}
var result = new List<TextBox>();
foreach (var keyValuePair in lineBoxes)
{
result.AddRange(keyValuePair.Value);
}
return result;
}
public PositionWithAffinity getGlyphPositionAtCoordinate(double dx, double dy)
{
if (_lineHeights.Count == 0)
{
return new PositionWithAffinity(0, TextAffinity.downstream);
}
int yIndex;
for (yIndex = 0; yIndex < _lineHeights.Count - 1; ++yIndex)
{
if (dy < _lineHeights[yIndex])
{
break;
}
}
var line = _lineRanges[yIndex];
if (line.start >= line.end)
{
return new PositionWithAffinity(line.start, TextAffinity.downstream);
}
int index;
for (index = line.start; index < line.end; ++index)
{
if (dx < _characterPositions[index].x + _characterWidths[index])
{
break;
}
}
if (index >= line.end)
{
return new PositionWithAffinity(line.end, TextAffinity.upstream);
}
TextDirection direction = TextDirection.ltr;
var codeUnit = _codeUnitRuns.Find((u) => u.codeUnits.start >= index && index < u.codeUnits.end);
if (codeUnit != null)
{
direction = codeUnit.direction;
}
double glyphCenter = (_characterPositions[index].x + _characterPositions[index].x + _characterWidths[index]) / 2;
if ((direction == TextDirection.ltr && dx < glyphCenter) || (direction == TextDirection.rtl && dx >= glyphCenter))
{
return new PositionWithAffinity(index, TextAffinity.downstream);
} else
{
return new PositionWithAffinity(index, TextAffinity.upstream);
}
}
public IndexRange getWordBoundary(int offset)
{
WordSeparate s = new WordSeparate(_text);
return s.findWordRange(offset);
}
public static void offsetCharacters(Vector2d offset, Vector2d[] characterPos, int start, int end)
{
if (characterPos != null)

}
}
}
private void computeWidthMetrics(double maxWordWidth)
{

_lineHeights.Clear();
_lineRanges.Clear();
_lineWidths.Clear();
_lineBaseLines.Clear();
_codeUnitRuns.Clear();
_characterWidths = new double[_text.Length];
for (int i = 0; i < _runs.size; ++i)
{

_paintRecords.Add(new PaintRecord(run.style, new TextBlob(
_text, start, end, _characterPositions, run.style, bounds),
lineNumber, width));
_codeUnitRuns.Add(new CodeUnitRun(
new IndexRange(start, end), lineNumber, new FontMetrics(ascent, descent), TextDirection.ltr));
}
}

_lineHeights.Add((_lineHeights.Count == 0 ? 0 : _lineHeights[_lineHeights.Count - 1]) +
Math.Round(maxAscent + maxDescent));
_lineBaseLines.Add(yOffset);
}
}

18
Assets/UIWidgets/widgets/basic.cs


public Directionality(
Widget child,
TextDirection textDirection,
string key = null
Key key = null
) : base(key, child) {
this.textDirection = textDirection;
}

}
public class Opacity : SingleChildRenderObjectWidget {
public Opacity(double opacity, string key = null, Widget child = null) : base(key, child) {
public Opacity(double opacity, Key key = null, Widget child = null) : base(key, child) {
this.opacity = opacity;
}

public class LimitedBox : SingleChildRenderObjectWidget {
public LimitedBox(
string key = null,
Key key = null,
Widget child = null,
double maxWidth = double.MaxValue,
double maxHeight = double.MaxValue

public class ConstrainedBox : SingleChildRenderObjectWidget {
public ConstrainedBox(
string key = null,
Key key = null,
BoxConstraints constraints = null,
Widget child = null
) : base(key, child) {

public class Padding : SingleChildRenderObjectWidget {
public Padding(
EdgeInsets padding,
string key = null,
Key key = null,
Widget child = null
) : base(key, child) {
this.padding = padding;

Offset origin = null,
Alignment alignment = null,
bool transformHitTests = false,
string key = null,
Key key = null,
Widget child = null
) : base(key, child) {
this.alignment = alignment ?? Alignment.center;

Offset origin,
Alignment alignment,
bool transformHitTests = false,
string key = null,
Key key = null,
Widget child = null
) : base(key, child) {
this.alignment = alignment ?? Alignment.center;

public Align(
double widthFactor = 0.0,
double heightFactor = 0.0,
string key = null,
Key key = null,
Widget child = null,
Alignment alignment = null
) : base(key, child) {

}
public class RawImage : LeafRenderObjectWidget {
public RawImage(string key, ui.Image image, double width, double height, double scale, Color color,
public RawImage(Key key, ui.Image image, double width, double height, double scale, Color color,
BlendMode colorBlendMode, BoxFit fit, Rect centerSlice, Alignment alignment = null,
ImageRepeat repeat = ImageRepeat.noRepeat) : base(key) {
this.image = image;

28
Assets/UIWidgets/widgets/binding.cs


// dispatchLocaleChanged(window.locale);
}
public void drawFrame() {
protected override void drawFrame() {
if (renderViewElement != null) {
buildOwner.buildScope(renderViewElement);
}

public class RenderObjectToWidgetAdapter<T> : RenderObjectWidget where T : RenderObject {
public RenderObjectToWidgetAdapter(Widget child, RenderObjectWithChildMixinRenderObject<T> container) : base(
new GlobalObjectKey(container)) {
new GlobalObjectKey<State<StatefulWidget>>(container)) {
this.child = child;
this.container = container;
}

public Widget _newWidget;
public new RenderObjectWithChildMixin renderObject {
get { return base.renderObject as RenderObjectWithChildMixin; }
}
public override void forgetChild(Element child) {
protected override void forgetChild(Element child) {
D.assert(child == _child);
_child = null;
}

_rebuild();
}
public override void performRebuild() {
protected override void performRebuild() {
if (_newWidget != null) {
Widget newWidget = _newWidget;
_newWidget = null;

D.assert(_newWidget == null);
}
protected override void insertChildRenderObject(RenderObject child, object slot) {
D.assert(slot == _rootChildSlot);
renderObject.child = child;
}
protected override void moveChildRenderObject(RenderObject child, object slot) {
D.assert(false);
}
protected override void removeChildRenderObject(RenderObject child) {
D.assert(renderObject.child == child);
renderObject.child = null;
}
void _rebuild() {
try {
_child = updateChild(_child, widget.child, _rootChildSlot);

Widget error = ErrorWidget.builder(e);
Widget error = ErrorWidget.builder(new UIWidgetsErrorDetails(e));
_child = updateChild(null, error, _rootChildSlot);
}
}

4
Assets/UIWidgets/widgets/container.cs


public DecoratedBox(
Decoration decoration,
Widget child,
string key = null,
Key key = null,
DecorationPosition position = DecorationPosition.background
) : base(key, child) {
this.position = position;

public class Container : StatelessWidget {
public Container(
string key,
Key key,
Alignment alignment,
EdgeInsets padding,
Color color,

977
Assets/UIWidgets/widgets/framework.cs
文件差异内容过多而无法显示
查看文件

12
Assets/UIWidgets/widgets/image.cs


public bool gaplessPlayback;
public Image(
string key,
Key key,
ImageProvider<System.Object> image,
double width,
double height,

// Network Image
public Image(
string src,
string key,
Key key,
double width,
double height,
Color color,

_resolveImage();
}
public override void reassemble() {
_resolveImage(); // in case the image cache was flushed
}
// public override void reassemble() {
// _resolveImage(); // in case the image cache was flushed
// }
void _resolveImage() {
var imageWidget = (Image<T>) widget;

public override Widget build(BuildContext context) {
var imageWidget = (Image<T>) widget;
RawImage image = new RawImage(
"", // todo
null, // todo
_imageInfo == null ? null : _imageInfo.image,
imageWidget.width,
imageWidget.height,

2
Assets/UIWidgets/widgets/notification_listener.cs


public class NotificationListener<T> : StatelessWidget, _NotificationListener where T : Notification {
public NotificationListener(
string key = null,
Key key = null,
Widget child = null,
NotificationListenerCallback<T> onNotification = null) : base(key) {
this.child = child;

196
Assets/UIWidgets/widgets/scroll_activity.cs


using System;
using RSG;
using UIWidgets.animation;
using UIWidgets.foundation;
using UIWidgets.gestures;
using UIWidgets.painting;

}
public abstract class ScrollActivity {
public ScrollActivity(ScrollActivityDelegate @delegate) {
this._delegate = @delegate;
public ScrollActivity(ScrollActivityDelegate del) {
this._del = del;
public ScrollActivityDelegate @delegate {
get { return this._delegate; }
public ScrollActivityDelegate del {
get { return this._del; }
ScrollActivityDelegate _delegate;
ScrollActivityDelegate _del;
D.assert(this._delegate != value);
this._delegate = value;
D.assert(this._del != value);
this._del = value;
}
public virtual void resetActivity() {

public abstract double velocity { get; }
public virtual void dispose() {
this._delegate = null;
this._del = null;
}
public override string ToString() {

public class IdleScrollActivity : ScrollActivity {
public IdleScrollActivity(ScrollActivityDelegate @delegate) : base(@delegate) {
public IdleScrollActivity(ScrollActivityDelegate del) : base(del) {
this.@delegate.goBallistic(0.0);
this.del.goBallistic(0.0);
}
public override bool shouldIgnorePointer {

public class HoldScrollActivity : ScrollActivity, ScrollHoldController {
public HoldScrollActivity(
ScrollActivityDelegate @delegate = null,
ScrollActivityDelegate del = null,
) : base(@delegate) {
) : base(del) {
this.onHoldCanceled = onHoldCanceled;
}

}
public void cancel() {
this.@delegate.goBallistic(0.0);
this.del.goBallistic(0.0);
}
public override void dispose() {

public class ScrollDragController : Drag {
public ScrollDragController(
ScrollActivityDelegate @delegate = null,
ScrollActivityDelegate del = null,
D.assert(@delegate != null);
D.assert(del != null);
D.assert(details != null);
D.assert(
motionStartDistanceThreshold == null || motionStartDistanceThreshold > 0.0,

this._delegate = @delegate;
this._del = del;
this._lastDetails = details;
this._retainMomentum = carriedVelocity != null && carriedVelocity != 0.0;
this._lastNonStationaryTimestamp = details.sourceTimeStamp;

this.motionStartDistanceThreshold = motionStartDistanceThreshold;
}
public ScrollActivityDelegate @delegate {
get { return this._delegate; }
public ScrollActivityDelegate del {
get { return this._del; }
ScrollActivityDelegate _delegate;
ScrollActivityDelegate _del;
public readonly VoidCallback onDragCanceled;

const double _bigThresholdBreakDistance = 24.0;
bool _reversed {
get { return AxisUtils.axisDirectionIsReversed(this.@delegate.axisDirection); }
get { return AxisUtils.axisDirectionIsReversed(this.del.axisDirection); }
D.assert(this._delegate != value);
this._delegate = value;
D.assert(this._del != value);
this._del = value;
}
void _maybeLoseMomentum(double offset, DateTime? timestamp) {

offset = -offset;
}
this.@delegate.applyUserOffset(offset);
this.del.applyUserOffset(offset);
}
public void end(DragEndDetails details) {

velocity += this.carriedVelocity.Value;
}
this.@delegate.goBallistic(velocity);
this.del.goBallistic(velocity);
this.@delegate.goBallistic(0.0);
this.del.goBallistic(0.0);
}
public virtual void dispose() {

public class DragScrollActivity : ScrollActivity {
public DragScrollActivity(
ScrollActivityDelegate @delegate,
ScrollActivityDelegate del,
) : base(@delegate) {
) : base(del) {
this._controller = controller;
}

public override void dispose() {
this._controller = null;
base.dispose();
}
public override string ToString() {
return string.Format("{0}({1})", Diagnostics.describeIdentity(this), this._controller);
}
}
public class BallisticScrollActivity : ScrollActivity {
public BallisticScrollActivity(
ScrollActivityDelegate del,
Simulation simulation,
TickerProvider vsync
) : base(del) {
this._controller = AnimationController.unbounded(
debugLabel: this.GetType().ToString(),
vsync: vsync
);
this._controller.addListener(this._tick);
this._controller.animateWith(simulation).Then(() => this._end());
}
public override double velocity {
get { return this._controller.velocity; }
}
readonly AnimationController _controller;
public override void resetActivity() {
this.del.goBallistic(this.velocity);
}
public override void applyNewDimensions() {
this.del.goBallistic(this.velocity);
}
void _tick() {
if (!this.applyMoveTo(this._controller.value)) {
this.del.goIdle();
}
}
protected bool applyMoveTo(double value) {
return this.del.setPixels(value) == 0.0;
}
void _end() {
if (this.del != null) {
this.del.goBallistic(0.0);
}
}
public override void dispatchOverscrollNotification(
ScrollMetrics metrics, BuildContext context, double overscroll) {
new OverscrollNotification(metrics: metrics, context: context, overscroll: overscroll,
velocity: this.velocity).dispatch(context);
}
public override bool shouldIgnorePointer {
get { return true; }
}
public override bool isScrolling {
get { return true; }
}
public override void dispose() {
this._controller.dispose();
base.dispose();
}
public override string ToString() {
return string.Format("{0}({1})", Diagnostics.describeIdentity(this), this._controller);
}
}
public class DrivenScrollActivity : ScrollActivity {
public DrivenScrollActivity(
ScrollActivityDelegate del,
double from,
double to,
TimeSpan duration,
Curve curve,
TickerProvider vsync
) : base(del) {
D.assert(duration > TimeSpan.Zero);
D.assert(curve != null);
this._completer = new Promise();
this._controller = AnimationController.unbounded(
value: from,
debugLabel: this.GetType().ToString(),
vsync: vsync
);
this._controller.addListener(this._tick);
this._controller.animateTo(to, duration: duration, curve: curve)
.Then(() => this._end());
}
readonly Promise _completer;
readonly AnimationController _controller;
public IPromise done {
get { return this._completer; }
}
public override double velocity {
get { return this._controller.velocity; }
}
void _tick() {
if (this.del.setPixels(this._controller.value) != 0.0) {
this.del.goIdle();
}
}
void _end() {
if (this.del != null) {
this.del.goBallistic(this.velocity);
}
}
public override void dispatchOverscrollNotification(
ScrollMetrics metrics, BuildContext context, double overscroll) {
new OverscrollNotification(metrics: metrics, context: context, overscroll: overscroll,
velocity: this.velocity).dispatch(context);
}
public override bool shouldIgnorePointer {
get { return true; }
}
public override bool isScrolling {
get { return true; }
}
public override void dispose() {
this._completer.Resolve();
this._controller.dispose();
base.dispose();
}

148
Assets/UIWidgets/widgets/scroll_position.cs


using UIWidgets.foundation;
using UIWidgets.scheduler;
using UIWidgets.ui;
// ScrollPosition(
// ScrollPhysics physics = null,
// ScrollContext context = null,
// bool keepScrollOffset = true,
// ScrollPosition oldPosition = null,
// string debugLabel = null
// ) {
// D.assert(physics != null);
// D.assert(context != null);
// D.assert(context.vsync != null);
//
// this.physics = physics;
// this.context = context;
// this.keepScrollOffset = keepScrollOffset;
// this.debugLabel = debugLabel;
//
// if (oldPosition != null) {
// this.absorb(oldPosition);
// }
//
// if (keepScrollOffset) {
// this.restoreScrollOffset();
// }
// }
//
// public readonly ScrollPhysics physics;
// public readonly ScrollContext context;
// public readonly bool keepScrollOffset;
// public readonly string debugLabel;
//
// public double minScrollExtent {
// get { return this._minScrollExtent; }
// }
//
// double _minScrollExtent;
//
// public double maxScrollExtent {
// get { return this._maxScrollExtent; }
// }
//
// double _maxScrollExtent;
//
// public override double? pixels {
// get { return this._pixels; }
// }
//
// double? _pixels;
//
// public double viewportDimension {
// get { return this._viewportDimension; }
// }
//
// double _viewportDimension;
//
// public bool haveDimensions {
// get { return this._haveDimensions; }
// }
//
// bool _haveDimensions = false;
//
// protected virtual void absorb(ScrollPosition other) {
// D.assert(other != null);
// D.assert(other.context == context);
// D.assert(_pixels == null);
// _minScrollExtent = other.minScrollExtent;
// _maxScrollExtent = other.maxScrollExtent;
// _pixels = other._pixels;
// _viewportDimension = other.viewportDimension;
//
// D.assert(activity == null);
// D.assert(other.activity != null);
// _activity = other.activity;
// other._activity = null;
// if (other.runtimeType != runtimeType)
// activity.resetActivity();
// context.setIgnorePointer(activity.shouldIgnorePointer);
// isScrollingNotifier.value = activity.isScrolling;
// }
//
// public double setPixels(double newPixels) {
// D.assert(this._pixels != null);
// D.assert(this.context.vsync.schedulerBinding.schedulerPhase <= SchedulerPhase.transientCallbacks);
// if (newPixels != this.pixels) {
// double overscroll = this.applyBoundaryConditions(newPixels);
// D.assert(() => {
// double delta = newPixels - this.pixels;
// if (overscroll.abs() > delta.abs()) {
// throw new UIWidgetsError(
// string.Format(
// "{0}.applyBoundaryConditions returned invalid overscroll value.\n" +
// "setPixels() was called to change the scroll offset from {1} to {2}.\n" +
// "That is a delta of {3} units.\n" +
// "{0}.applyBoundaryConditions reported an overscroll of {4} units."
// , this.GetType(), this.pixels, newPixels, delta, overscroll));
// }
//
// return true;
// });
//
// double oldPixels = this.pixels;
// this._pixels = newPixels - overscroll;
// if (this._pixels != oldPixels) {
// this.notifyListeners();
// this.didUpdateScrollPositionBy(this._pixels - oldPixels);
// }
//
// if (overscroll != 0.0) {
// this.didOverscrollBy(overscroll);
// return overscroll;
// }
// }
//
// return 0.0;
// }
// public void correctPixels(double value) {
// this._pixels = value;
// }
//
// public override void correctBy(double correction) {
// D.assert(
// this._pixels != null,
// "An initial pixels value must exist by caling correctPixels on the ScrollPosition"
// );
//
// this._pixels += correction;
// this._didChangeViewportDimensionOrReceiveCorrection = true;
// }
//
// protected void forcePixels(double value) {
// D.assert(this.pixels != null);
// _pixels = value;
// notifyListeners();
// }
//
// protected void saveScrollOffset() {
// PageStorage.of(context.storageContext)?.writeState(context.storageContext, pixels);
// }
//
// protected void restoreScrollOffset() {
// if (pixels == null) {
// final double value = PageStorage.of(context.storageContext)?.readState(context.storageContext);
// if (value != null)
// correctPixels(value);
// }
// }
// }
}

2
Assets/UIWidgets/widgets/ticker_provider.cs


namespace UIWidgets.widgets {
public class TickerMode : InheritedWidget {
public TickerMode(string key, bool enabled, Widget child) : base(key, child) {
public TickerMode(Key key, bool enabled, Widget child) : base(key, child) {
this.enabled = enabled;
}

203
Assets/UIWidgets/Tests/RenderEditable.cs


using UnityEditor;
using System;
using System.Collections.Generic;
using System.Linq;
using RSG;
using UIWidgets.animation;
using UIWidgets.editor;
using UIWidgets.foundation;
using UIWidgets.painting;
using UIWidgets.rendering;
using UIWidgets.service;
using UIWidgets.ui;
using UnityEditor;
using UnityEngine;
using Color = UIWidgets.ui.Color;
using FontStyle = UIWidgets.ui.FontStyle;
namespace UIWidgets.Tests
{
public class RenderEditable: EditorWindow
{
private readonly Func<RenderBox>[] _options;
private readonly string[] _optionStrings;
private int _selected;
class _FixedViewportOffset : ViewportOffset {
internal _FixedViewportOffset(double _pixels) {
this._pixels = _pixels;
}
internal new static _FixedViewportOffset zero() {
return new _FixedViewportOffset(0.0);
}
double _pixels;
public override double pixels {
get { return this._pixels; }
}
public override bool applyViewportDimension(double viewportDimension) {
return true;
}
public override bool applyContentDimensions(double minScrollExtent, double maxScrollExtent) {
return true;
}
public override void correctBy(double correction) {
this._pixels += correction;
}
public override void jumpTo(double pixels) {
}
public override IPromise<object> animateTo(double to, TimeSpan duration, Curve curve) {
return Promise<object>.Resolved(null);
}
public override ScrollDirection userScrollDirection {
get { return ScrollDirection.idle; }
}
public override bool allowImplicitScrolling {
get { return false; }
}
}
RenderEditable() {
this._options = new Func<RenderBox>[] {
this.textEditable,
};
this._optionStrings = this._options.Select(x => x.Method.Name).ToArray();
this._selected = 0;
this.titleContent = new GUIContent("RenderEditable");
}
private WindowAdapter windowAdapter;
private RendererBindings rendererBindings;
[NonSerialized] private bool hasInvoked = false;
void OnGUI() {
var selected = EditorGUILayout.Popup("test case", this._selected, this._optionStrings);
if (selected != this._selected || !this.hasInvoked) {
this._selected = selected;
this.hasInvoked = true;
var renderBox = this._options[this._selected]();
this.rendererBindings.setRoot(renderBox);
}
if (this.windowAdapter != null) {
this.windowAdapter.OnGUI();
}
}
void Update() {
if (this.windowAdapter != null) {
this.windowAdapter.Update();
}
}
private void OnEnable() {
this.windowAdapter = new WindowAdapter(this);
this.rendererBindings = new RendererBindings(this.windowAdapter);
}
void OnDestroy() {
this.windowAdapter = null;
this.rendererBindings = null;
}
private RenderBox box(RenderBox p, int width = 400, int height = 400)
{
return new RenderConstrainedOverflowBox(
minWidth: width,
maxWidth: width,
minHeight: height,
maxHeight: height,
alignment: Alignment.center,
child: p
)
;
}
private RenderBox flexItemBox(RenderBox p, int width = 200, int height = 100)
{
return new RenderConstrainedBox(
additionalConstraints: new BoxConstraints(minWidth: width, maxWidth: width, minHeight: height,
maxHeight: height),
child: new RenderDecoratedBox(
decoration: new BoxDecoration(
color: new Color(0xFFFFFFFF),
borderRadius: BorderRadius.all(3),
border: Border.all(Color.fromARGB(255, 255, 0, 0), 1)
),
child: new RenderPadding(EdgeInsets.all(10), p
)
));
}
RenderBox textEditable()
{
var span = new TextSpan("", children:
new List<TextSpan>
{
new TextSpan("Word Wrap:The ascent of the font is the distance from the baseline to the top line of the font, as defined in the font's original data file.", null),
}, style:new painting.TextStyle(height:1.0));
var flexbox = new RenderFlex(
direction: Axis.vertical,
mainAxisAlignment: MainAxisAlignment.spaceAround,
crossAxisAlignment: CrossAxisAlignment.center);
flexbox.add(flexItemBox(
new rendering.RenderEditable(span, TextDirection.ltr,
new _FixedViewportOffset(0.0), new ValueNotifier<bool>(true), this.rendererBindings.rendererBinding,
onSelectionChanged: selectionChanged, cursorColor: Color.fromARGB(255, 0, 0, 0),
maxLines: 100,
selectionColor: Color.fromARGB(255, 255, 0, 0))
));
span = new TextSpan("", children:
new List<TextSpan>
{
new TextSpan("Hard Break:The ascent of the font is the distance\nfrom the baseline to the top \nline of the font,\nas defined in", null),
}, style:new painting.TextStyle(height:1.0));
flexbox.add(flexItemBox(
new rendering.RenderEditable(span, TextDirection.ltr,
new _FixedViewportOffset(0.0), new ValueNotifier<bool>(true), this.rendererBindings.rendererBinding,
onSelectionChanged: selectionChanged, cursorColor: Color.fromARGB(255, 0, 0, 0),
maxLines: 100,
selectionColor: Color.fromARGB(255, 255, 0, 0))
));
span = new TextSpan("", children:
new List<TextSpan>
{
new TextSpan("Single Line:How to create mixin", null),
}, style:new painting.TextStyle(height:1.0));
flexbox.add(flexItemBox(
new rendering.RenderEditable(span, TextDirection.ltr,
new _FixedViewportOffset(0.0), new ValueNotifier<bool>(true), this.rendererBindings.rendererBinding,
onSelectionChanged: selectionChanged, cursorColor: Color.fromARGB(255, 0, 0, 0),
selectionColor: Color.fromARGB(255, 255, 0, 0))
, width:300));
return flexbox;
}
private void selectionChanged(TextSelection selection, rendering.RenderEditable renderObject,
SelectionChangedCause cause)
{
Debug.Log(string.Format("selection {0}", selection));
renderObject.selection = selection;
}
}
}

3
Assets/UIWidgets/Tests/RenderEditable.cs.meta


fileFormatVersion: 2
guid: 3133671f82dc4c0e93d4dbeb9e50b55d
timeCreated: 1536660300

8
Assets/UIWidgets/animation.meta


fileFormatVersion: 2
guid: 1c53122c52c3f4fd897b13cc476e8baf
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

61
Assets/UIWidgets/foundation/key.cs


using System;
using System.Collections.Generic;
namespace UIWidgets.foundation {
public abstract class Key {
protected Key() {
}
public static Key key(string value) {
return new ValueKey<string>(value);
}
}
public abstract class LocalKey : Key {
protected LocalKey() {
}
}
public class ValueKey<T> : LocalKey, IEquatable<ValueKey<T>> {
public ValueKey(T value) {
this.value = value;
}
public readonly T value;
public bool Equals(ValueKey<T> other) {
if (object.ReferenceEquals(null, other)) return false;
if (object.ReferenceEquals(this, other)) return true;
return EqualityComparer<T>.Default.Equals(this.value, other.value);
}
public override bool Equals(object obj) {
if (object.ReferenceEquals(null, obj)) return false;
if (object.ReferenceEquals(this, obj)) return true;
if (obj.GetType() != this.GetType()) return false;
return this.Equals((ValueKey<T>) obj);
}
public override int GetHashCode() {
return EqualityComparer<T>.Default.GetHashCode(this.value);
}
public static bool operator ==(ValueKey<T> left, ValueKey<T> right) {
return object.Equals(left, right);
}
public static bool operator !=(ValueKey<T> left, ValueKey<T> right) {
return !object.Equals(left, right);
}
public override string ToString() {
string valueString = typeof(T) == typeof(string) ? "<\'" + this.value + "\'>" : "<" + this.value + ">";
if (this.GetType() == typeof(ValueKey<T>)) {
return string.Format("[{0}]", valueString);
}
return string.Format("[{0} {1}]", this.GetType(), valueString);
}
}
}

3
Assets/UIWidgets/foundation/key.cs.meta


fileFormatVersion: 2
guid: 69b5bafdaadd44a9b8ef37ee8f62164e
timeCreated: 1536806963

8
Assets/UIWidgets/physics.meta


fileFormatVersion: 2
guid: 9fced70753a79436d832caab7657fef3
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

703
Assets/UIWidgets/rendering/editable.cs


using System;
using System.Collections.Generic;
using UIWidgets.foundation;
using UIWidgets.gestures;
using UIWidgets.painting;
using UIWidgets.service;
using UIWidgets.ui;
using UnityEngine;
using Canvas = UIWidgets.ui.Canvas;
using Color = UIWidgets.ui.Color;
using Rect = UIWidgets.ui.Rect;
namespace UIWidgets.rendering
{
public delegate void SelectionChangedHandler(TextSelection selection, RenderEditable renderObject,
SelectionChangedCause cause);
public delegate void CaretChangedHandler(Rect caretRect);
public enum SelectionChangedCause
{
tap,
doubleTap,
longPress,
keyboard,
}
public class TextSelectionPoint
{
public readonly Offset point;
public readonly TextDirection? direction;
public TextSelectionPoint(Offset point, TextDirection? direction)
{
D.assert(point != null);
this.point = point;
this.direction = direction;
}
public override string ToString()
{
return string.Format("Point: {0}, Direction: {1}", point, direction);
}
}
/*
this._doubleTapGesture = new DoubleTapGestureRecognizer(this.rendererBindings.rendererBinding);
this._doubleTapGesture.onDoubleTap = () => { Debug.Log("onDoubleTap"); };*/
public class RenderEditable : RenderBox
{
public static readonly string obscuringCharacter = "•";
private static readonly double _kCaretGap = 1.0;
private static readonly double _kCaretHeightOffset = 2.0;
private static readonly double _kCaretWidth = 1.0;
private TextPainter _textPainter;
private Color _cursorColor;
private bool _hasFocus;
private int _maxLines;
private Color _selectionColor;
private ViewportOffset _offset;
private ValueNotifier<bool> _showCursor;
private TextSelection _selection;
private bool _obscureText;
private TapGestureRecognizer _tap;
private DoubleTapGestureRecognizer _doubleTap;
private bool ignorePointer;
private SelectionChangedHandler onSelectionChanged;
private CaretChangedHandler onCaretChanged;
private Rect _lastCaretRect;
private double? _textLayoutLastWidth;
private List<TextBox> _selectionRects;
private Rect _caretPrototype;
private bool _hasVisualOverflow = false;
private Offset _lastTapDownPosition;
public RenderEditable(TextSpan text, TextDirection textDirection, ViewportOffset offset,
ValueNotifier<bool> showCursor,
GestureBinding binding,
TextAlign textAlign = TextAlign.left, double textScaleFactor = 1.0, Color cursorColor = null,
bool? hasFocus = null, int maxLines = 1, Color selectionColor = null,
TextSelection selection = null, bool obscureText = false, SelectionChangedHandler onSelectionChanged = null,
CaretChangedHandler onCaretChanged = null, bool ignorePointer = false)
{
_textPainter = new TextPainter(text: text, textAlign: textAlign, textDirection: textDirection,
textScaleFactor: textScaleFactor);
_cursorColor = cursorColor;
_showCursor = showCursor ?? new ValueNotifier<bool>(false);
_hasFocus = hasFocus ?? false;
_maxLines = maxLines;
_selectionColor = selectionColor;
_selection = selection;
_obscureText = obscureText;
_offset = offset;
this.ignorePointer = ignorePointer;
this.onCaretChanged = onCaretChanged;
this.onSelectionChanged = onSelectionChanged;
D.assert(_showCursor != null);
D.assert(!_showCursor.value || cursorColor != null);
_tap = new TapGestureRecognizer(binding, this);
_doubleTap = new DoubleTapGestureRecognizer(binding, this);
_tap.onTapDown = this._handleTapDown;
_tap.onTap = this._handleTap;
_doubleTap.onDoubleTap = this._handleDoubleTap;
}
public bool obscureText
{
get { return _obscureText; }
set
{
if (_obscureText == value)
return;
_obscureText = value;
markNeedsSemanticsUpdate();
}
}
public TextSpan text
{
get { return _textPainter.text; }
set
{
if (_textPainter.text == value)
{
return;
}
_textPainter.text = value;
markNeedsTextLayout();
markNeedsSemanticsUpdate();
}
}
public TextAlign textAlign
{
get { return _textPainter.textAlign; }
set
{
if (_textPainter.textAlign == value)
{
return;
}
_textPainter.textAlign = value;
markNeedsPaint();
}
}
public TextDirection? textDirection
{
get { return _textPainter.textDirection; }
set
{
if (_textPainter.textDirection == value)
{
return;
}
_textPainter.textDirection = value;
markNeedsTextLayout();
markNeedsSemanticsUpdate();
}
}
public Color cursorColor
{
get { return _cursorColor; }
set
{
if (_cursorColor == value)
{
return;
}
_cursorColor = value;
markNeedsPaint();
}
}
public ValueNotifier<bool> ShowCursor
{
get { return _showCursor; }
set
{
D.assert(value != null);
if (_showCursor == value)
{
return;
}
if (attached)
{
_showCursor.removeListener(markNeedsPaint);
}
_showCursor = value;
if (attached)
{
_showCursor.addListener(markNeedsPaint);
}
markNeedsPaint();
}
}
public bool hasFocus
{
get { return _hasFocus; }
set
{
if (_hasFocus == value)
{
return;
}
hasFocus = value;
markNeedsSemanticsUpdate();
}
}
public int maxLines
{
get { return _maxLines; }
set
{
D.assert(value > 0);
if (_maxLines == value)
{
return;
}
_maxLines = value;
markNeedsTextLayout();
}
}
public Color selectionColor
{
get { return _selectionColor; }
set
{
if (_selectionColor == value)
{
return;
}
_selectionColor = value;
markNeedsPaint();
}
}
public double textScaleFactor
{
get { return _textPainter.textScaleFactor; }
set
{
if (_textPainter.textScaleFactor == value)
{
return;
}
_textPainter.textScaleFactor = value;
markNeedsTextLayout();
}
}
public TextSelection selection
{
get { return _selection; }
set
{
if (_selection == value)
{
return;
}
_selection = value;
_selectionRects = null;
markNeedsPaint();
markNeedsSemanticsUpdate();
}
}
public ViewportOffset offset
{
get { return _offset; }
set
{
D.assert(offset != null);
if (_offset == value)
{
return;
}
if (attached)
{
_offset.removeListener(markNeedsPaint);
}
_offset = value;
if (attached)
{
_offset.addListener(markNeedsPaint);
}
markNeedsLayout();
}
}
public ValueNotifier<bool> showCursor
{
get { return _showCursor; }
set
{
D.assert(value != null);
if (_showCursor == value)
{
return;
}
if (attached)
{
_showCursor.removeListener(markNeedsPaint);
}
_showCursor = value;
if (attached)
{
_showCursor.addListener(markNeedsPaint);
}
markNeedsPaint();
}
}
public double preferredLineHeight
{
get { return _textPainter.preferredLineHeight; }
}
public override void attach(object ownerObject)
{
base.attach(ownerObject);
_offset.addListener(markNeedsLayout);
_showCursor.addListener(markNeedsPaint);
}
public override void detach()
{
_offset.removeListener(markNeedsLayout);
_showCursor.removeListener(markNeedsPaint);
base.detach();
}
/// Returns the local coordinates of the endpoints of the given selection.
///
/// If the selection is collapsed (and therefore occupies a single point), the
/// returned list is of length one. Otherwise, the selection is not collapsed
/// and the returned list is of length two. In this case, however, the two
/// points might actually be co-located (e.g., because of a bidirectional
/// selection that contains some text but whose ends meet in the middle).
///
public List<TextSelectionPoint> getEndpointsForSelection(TextSelection selection)
{
D.assert(constraints != null);
_layoutText(constraints.maxWidth);
var paintOffset = _paintOffset;
if (selection.isCollapsed)
{
var caretOffset = _textPainter.getOffsetForCaret(selection.extendPos, _caretPrototype);
var start = new Offset(0.0, preferredLineHeight) + caretOffset + paintOffset;
return new List<TextSelectionPoint>{new TextSelectionPoint(start, null)};
}
else
{
var boxes = _textPainter.getBoxesForSelection(selection);
var start = new Offset(boxes[0].start, boxes[0].bottom) + paintOffset;
var last = boxes.Count - 1;
var end = new Offset(boxes[last].end, boxes[last].bottom) + paintOffset;
return new List<TextSelectionPoint>
{
new TextSelectionPoint(start, boxes[0].direction),
new TextSelectionPoint(end, boxes[last].direction),
};
}
}
public TextPosition getPositionForPoint(Offset globalPosition)
{
_layoutText(constraints.maxWidth);
globalPosition -= _paintOffset;
return _textPainter.getPositionForOffset(globalPosition);
}
public Rect getLocalRectForCaret(TextPosition caretPosition)
{
_layoutText(constraints.maxWidth);
var caretOffset = _textPainter.getOffsetForCaret(caretPosition, _caretPrototype);
return Rect.fromLTWH(0.0, 0.0, _kCaretWidth, preferredLineHeight).shift(caretOffset + _paintOffset);
}
public override double computeMinIntrinsicWidth(double height) {
_layoutText(double.PositiveInfinity);
return _textPainter.minIntrinsicWidth;
}
public override double computeMaxIntrinsicWidth(double height) {
_layoutText(double.PositiveInfinity);
return _textPainter.maxIntrinsicWidth;
}
public override double computeMinIntrinsicHeight(double width) {
return _preferredHeight(width);
}
public override double computeMaxIntrinsicHeight(double width) {
return _preferredHeight(width);
}
public override double? computeDistanceToActualBaseline(TextBaseline baseline) {
_layoutText(constraints.maxWidth);
return _textPainter.computeDistanceToActualBaseline(baseline);
}
public override void handleEvent(PointerEvent evt, HitTestEntry entry) {
if (ignorePointer)
return;
D.assert(debugHandleEvent(evt, entry));
if (evt is PointerDownEvent && onSelectionChanged != null) {
_tap.addPointer((PointerDownEvent)evt);
_doubleTap.addPointer((PointerDownEvent)evt);
// todo long press
}
}
public void handleTapDown(TapDownDetails details)
{
_lastTapDownPosition = details.globalPosition - _paintOffset;
}
public void handleTap()
{
_layoutText(constraints.maxWidth);
D.assert(_lastTapDownPosition != null);
if (onSelectionChanged != null)
{
var position = _textPainter.getPositionForOffset(globalToLocal(_lastTapDownPosition));
onSelectionChanged(TextSelection.fromPosition(position), this, SelectionChangedCause.tap);
}
}
public void handleDoubleTap()
{
_layoutText(constraints.maxWidth);
D.assert(_lastTapDownPosition != null);
if (onSelectionChanged != null)
{
var position = _textPainter.getPositionForOffset(globalToLocal(_lastTapDownPosition));
onSelectionChanged(_selectWordAtOffset(position), this, SelectionChangedCause.doubleTap);
}
}
public override void performLayout() {
_layoutText(constraints.maxWidth);
_caretPrototype = Rect.fromLTWH(0.0, _kCaretHeightOffset, _kCaretWidth,
preferredLineHeight - 2.0 * _kCaretHeightOffset);
_selectionRects = null;
var textPainterSize = _textPainter.size;
size = new Size(constraints.maxWidth, constraints.constrainHeight(_preferredHeight(constraints.maxWidth)));
var contentSize = new Size(textPainterSize.width + _kCaretGap + _kCaretWidth, textPainterSize.height);
var _maxScrollExtent = _getMaxScrollExtend(contentSize);
_hasVisualOverflow = _maxScrollExtent > 0.0;
offset.applyViewportDimension(_viewportExtend);
offset.applyContentDimensions(0.0, _maxScrollExtent);
}
public override void paint(PaintingContext context, Offset offset)
{
_layoutText(constraints.maxWidth);
if (_hasVisualOverflow)
{
context.pushClipRect(needsCompositing, offset, Offset.zero & size, _paintContents);
}
else
{
_paintContents(context, offset);
}
}
protected override bool hitTestSelf(Offset position)
{
return true;
}
protected void markNeedsTextLayout()
{
_textLayoutLastWidth = null;
markNeedsLayout();
}
// describeSemanticsConfiguration todo
public override void debugFillProperties(DiagnosticPropertiesBuilder properties) {
base.debugFillProperties(properties);
properties.add(new DiagnosticsProperty<Color>("cursorColor", cursorColor));
properties.add(new DiagnosticsProperty<ValueNotifier<bool>>("showCursor", showCursor));
properties.add(new DiagnosticsProperty<int>("maxLines", maxLines));
properties.add(new DiagnosticsProperty<Color>("selectionColor", selectionColor));
properties.add(new DiagnosticsProperty<double>("textScaleFactor", textScaleFactor));
properties.add(new DiagnosticsProperty<TextSelection>("selection", selection));
properties.add(new DiagnosticsProperty<ViewportOffset>("offset", offset));
}
private void _paintCaret(Canvas canvas, Offset effectiveOffset)
{
D.assert(_textLayoutLastWidth == constraints.maxWidth);
var caretOffset = _textPainter.getOffsetForCaret(_selection.extendPos, _caretPrototype);
var paint = new Paint() {color = _cursorColor};
var caretRec = _caretPrototype.shift(caretOffset + effectiveOffset);
canvas.drawRect(caretRec, BorderWidth.zero, BorderRadius.zero, paint);
if (!caretRec.Equals(_lastCaretRect))
{
_lastCaretRect = caretRec;
if (onCaretChanged != null)
{
onCaretChanged(caretRec);
}
}
}
void _paintSelection(Canvas canvas, Offset effectiveOffset)
{
D.assert(_textLayoutLastWidth == constraints.maxWidth);
D.assert(_selectionRects != null);
var paint = new Paint() {color = _selectionColor};
foreach (var box in _selectionRects)
{
Debug.Log(string.Format("draw box {0}", box.toRect().shift(effectiveOffset)));
canvas.drawRect(box.toRect().shift(effectiveOffset), BorderWidth.zero, BorderRadius.zero, paint);
}
}
void _paintContents(PaintingContext context, Offset offset)
{
D.assert(_textLayoutLastWidth == constraints.maxWidth);
var effectiveOffset = offset + _paintOffset;
if (_selection != null) {
if (_selection.isCollapsed && _showCursor.value && cursorColor != null) {
_paintCaret(context.canvas, effectiveOffset);
} else if (!_selection.isCollapsed && _selectionColor != null) {
_selectionRects = _selectionRects??_textPainter.getBoxesForSelection(_selection);
_paintSelection(context.canvas, effectiveOffset);
}
}
_textPainter.paint(context.canvas, effectiveOffset);
}
private void _handleSetSelection(TextSelection selection)
{
onSelectionChanged(selection, this, SelectionChangedCause.keyboard);
}
private void _handleTapDown(TapDownDetails details)
{
D.assert(!ignorePointer);
handleTapDown(details);
}
private void _handleTap()
{
D.assert(!ignorePointer);
handleTap();
}
private void _handleDoubleTap()
{
D.assert(!ignorePointer);
handleDoubleTap();
}
private void markNeedsSemanticsUpdate()
{
// todo
}
private double _preferredHeight(double width)
{
if (maxLines <= 0)
{
return preferredLineHeight * maxLines;
}
if (double.IsInfinity(width))
{
var text = _textPainter.text.text;
int lines = 1;
for (int index = 0; index < text.Length; ++index)
{
if (text[index] == 0x0A)
{
lines += 1;
}
}
return preferredLineHeight * lines;
}
_layoutText(width);
return Math.Max(preferredLineHeight, _textPainter.height);
}
private void _layoutText(double constraintWidth)
{
if (_textLayoutLastWidth == constraintWidth)
{
return;
}
var caretMargin = _kCaretGap + _kCaretWidth;
var avialableWidth = Math.Max(0.0, constraintWidth - caretMargin);
var maxWidth = _isMultiline ? avialableWidth : double.PositiveInfinity;
_textPainter.layout(minWidth: avialableWidth, maxWidth: maxWidth);
_textLayoutLastWidth = constraintWidth;
}
TextSelection _selectWordAtOffset(TextPosition position)
{
D.assert(_textLayoutLastWidth == constraints.maxWidth);
var word = _textPainter.getWordBoundary(position);
if (position.offset >= word.end)
{
return TextSelection.fromPosition(position);
}
return new TextSelection(baseOffset: word.start, extendOffset: word.end);
}
private bool _isMultiline
{
get { return _maxLines != 1; }
}
private Axis _viewportAxis
{
get { return _isMultiline ? Axis.vertical : Axis.horizontal; }
}
private Offset _paintOffset
{
get
{
switch (_viewportAxis)
{
case Axis.horizontal:
return new Offset(-offset.pixels, 0.0);
case Axis.vertical:
return new Offset(0.0, -offset.pixels);
}
return null;
}
}
private double _viewportExtend
{
get
{
D.assert(hasSize);
switch (_viewportAxis)
{
case Axis.horizontal:
return size.width;
case Axis.vertical:
return size.height;
}
return 0.0;
}
}
private double _getMaxScrollExtend(Size contentSize)
{
D.assert(hasSize);
switch (_viewportAxis)
{
case Axis.horizontal:
return Math.Max(0.0, contentSize.width - size.width);
case Axis.vertical:
return Math.Max(0.0, contentSize.height - size.height);
}
return 0.0;
}
}
}

3
Assets/UIWidgets/rendering/editable.cs.meta


fileFormatVersion: 2
guid: f171ccb5173340cf99e2ddd274a3cbd6
timeCreated: 1536565172

3
Assets/UIWidgets/service.meta


fileFormatVersion: 2
guid: 355cc83db152457b8eb6da935c588fbc
timeCreated: 1536566821

70
Assets/UIWidgets/ui/txt/word_separate.cs


using System;
namespace UIWidgets.ui
{
public class WordSeparate
{
enum Direction
{
Forward,
Backward,
}
enum characterType
{
LetterLike,
Symbol,
WhiteSpace
}
private string _text;
public WordSeparate(string text)
{
this._text = text;
}
public IndexRange findWordRange(int index)
{
var t = classifyChar(index);
int start = index;
for (int i = index; i >= 0; --i)
{
if (!char.IsLowSurrogate(_text[start]))
{
if (classifyChar(i) != t)
{
break;
}
start = i;
}
}
int end = index;
for (int i = index; i < _text.Length; ++i)
{
if (!char.IsLowSurrogate(_text[i]))
{
if (classifyChar(i) != t)
{
break;
}
end = i;
}
}
return new IndexRange(start, end + 1);
}
private characterType classifyChar(int index)
{
if (char.IsWhiteSpace(_text, index))
return characterType.WhiteSpace;
if (char.IsLetterOrDigit(_text, index) || _text[index] == '\'')
return characterType.LetterLike;
return characterType.Symbol;
}
}
}

3
Assets/UIWidgets/ui/txt/word_separate.cs.meta


fileFormatVersion: 2
guid: 1c8f1db7a67b4775942ad83def1ce873
timeCreated: 1536654844

78
Assets/UIWidgets/widgets/debug.cs


using System;
using System.Collections.Generic;
using UIWidgets.foundation;
namespace UIWidgets.widgets {
public static class WidgetsD {
public static bool debugPrintRebuildDirtyWidgets = false;
public static bool debugPrintBuildScope = false;
public static bool debugPrintGlobalKeyedWidgetLifecycle = false;
public static bool debugPrintScheduleBuildForStacks = false;
static Key _firstNonUniqueKey(IEnumerable<Widget> widgets) {
var keySet = new HashSet<Key>();
foreach (Widget widget in widgets) {
D.assert(widget != null);
if (widget.key == null) {
continue;
}
if (!keySet.Add(widget.key)) {
return widget.key;
}
}
return null;
}
public static bool debugChildrenHaveDuplicateKeys(Widget parent, IEnumerable<Widget> children) {
D.assert(() => {
Key nonUniqueKey = _firstNonUniqueKey(children);
if (nonUniqueKey != null) {
throw new UIWidgetsError(
"Duplicate keys found.\n" +
"If multiple keyed nodes exist as children of another node, they must have unique keys.\n" +
parent + " has multiple children with key " + children + "."
);
}
return true;
});
return false;
}
public static void debugWidgetBuilderValue(Widget widget, Widget built) {
D.assert(() => {
if (built == null) {
throw new UIWidgetsError(
"A build function returned null.\n" +
"The offending widget is: " + widget + "\n" +
"Build functions must never return null. " +
"To return an empty space that causes the building widget to fill available room, return \"new Container()\". " +
"To return an empty space that takes as little room as possible, return \"new Container(width: 0.0, height: 0.0)\".");
}
return true;
});
}
internal static UIWidgetsErrorDetails _debugReportException(
string context,
Exception exception,
InformationCollector informationCollector = null
) {
var details = new UIWidgetsErrorDetails(
exception: exception,
library: "widgets library",
context: context,
informationCollector: informationCollector
);
UIWidgetsError.reportError(details);
return details;
}
}
}

3
Assets/UIWidgets/widgets/debug.cs.meta


fileFormatVersion: 2
guid: 3211d930ee9840718a013e09295ce087
timeCreated: 1536894099

5
Assets/UIWidgets/widgets/focus_manager.cs


namespace UIWidgets.widgets {
public class FocusManager {
}
}

3
Assets/UIWidgets/widgets/focus_manager.cs.meta


fileFormatVersion: 2
guid: 78895a8736b34e4085f9324116273d59
timeCreated: 1536819300

191
Assets/UIWidgets/service/text_editing.cs


using System;
using UIWidgets.foundation;
using UIWidgets.ui;
namespace UIWidgets.service
{
public class TextRange: IEquatable<TextRange>
{
public readonly int start;
public readonly int end;
public static TextRange collapsed(int offset)
{
D.assert(offset >= -1);
return new TextRange(offset, offset);
}
public static readonly TextRange empty = new TextRange(-1, -1);
public TextRange(int start, int end)
{
D.assert(start >= -1);
D.assert(end >= -1);
this.start = start;
this.end = end;
}
public bool isValid
{
get { return start >= 0 && end >= 0; }
}
public bool isCollapsed
{
get { return start == end; }
}
public bool isNormalized
{
get { return start <= end; }
}
public string textBefore(string text)
{
D.assert(isNormalized);
return text.Substring(0, start);
}
public string textAfter(string text)
{
D.assert(isNormalized);
return text.Substring(end);
}
public string textInside(string text)
{
D.assert(isNormalized);
return text.Substring(start, end - start);
}
public bool Equals(TextRange other)
{
if (ReferenceEquals(null, other)) return false;
if (ReferenceEquals(this, other)) return true;
return start == other.start && end == other.end;
}
public override bool Equals(object obj)
{
if (ReferenceEquals(null, obj)) return false;
if (ReferenceEquals(this, obj)) return true;
if (obj.GetType() != this.GetType()) return false;
return Equals((TextRange) obj);
}
public override int GetHashCode()
{
unchecked
{
return (start * 397) ^ end;
}
}
public static bool operator ==(TextRange left, TextRange right)
{
return Equals(left, right);
}
public static bool operator !=(TextRange left, TextRange right)
{
return !Equals(left, right);
}
public override string ToString()
{
return string.Format("TextRange Start: {0}, End: {1}", start, end);
}
}
public class TextSelection : TextRange, IEquatable<TextSelection>
{
public readonly int baseOffset;
public readonly int extendOffset;
public readonly TextAffinity affinity;
public readonly bool isDirectional;
public TextSelection(int baseOffset, int extendOffset, TextAffinity affinity = TextAffinity.downstream,
bool isDirectional = false):base(baseOffset < extendOffset ? baseOffset: extendOffset,
baseOffset < extendOffset ? extendOffset : baseOffset )
{
this.baseOffset = baseOffset;
this.extendOffset = extendOffset;
this.affinity = affinity;
this.isDirectional = isDirectional;
}
public static TextSelection collapsed(int offset, TextAffinity affinity = TextAffinity.downstream)
{
return new TextSelection(offset, offset, affinity, false);
}
public static TextSelection fromPosition(TextPosition position)
{
return collapsed(position.offset, position.affinity);
}
public TextPosition basePos
{
get
{
return new TextPosition(offset: baseOffset, affinity: affinity);
}
}
public TextPosition extendPos
{
get
{
return new TextPosition(offset: extendOffset, affinity: affinity);
}
}
public bool Equals(TextSelection other)
{
if (ReferenceEquals(null, other)) return false;
if (ReferenceEquals(this, other)) return true;
return baseOffset == other.baseOffset && extendOffset == other.extendOffset &&
affinity == other.affinity && isDirectional == other.isDirectional;
}
public override bool Equals(object obj)
{
if (ReferenceEquals(null, obj)) return false;
if (ReferenceEquals(this, obj)) return true;
if (obj.GetType() != this.GetType()) return false;
return Equals((TextSelection) obj);
}
public override int GetHashCode()
{
unchecked
{
int hashCode = 0;
hashCode = (hashCode * 397) ^ baseOffset;
hashCode = (hashCode * 397) ^ extendOffset;
hashCode = (hashCode * 397) ^ (int) affinity;
hashCode = (hashCode * 397) ^ isDirectional.GetHashCode();
return hashCode;
}
}
public static bool operator ==(TextSelection left, TextSelection right)
{
return Equals(left, right);
}
public static bool operator !=(TextSelection left, TextSelection right)
{
return !Equals(left, right);
}
public TextSelection copyWith(int? baseOffset = null, int? extendOffset = null, TextAffinity? affinity = null,
bool? isDirectional = null)
{
return new TextSelection(
baseOffset??this.baseOffset, extendOffset??this.extendOffset, affinity??this.affinity,
isDirectional??this.isDirectional
);
}
}
}

3
Assets/UIWidgets/service/text_editing.cs.meta


fileFormatVersion: 2
guid: 75983962965c4fd8bf21cc55ba91bde0
timeCreated: 1536566838

3
Assets/UIWidgets/math.meta


fileFormatVersion: 2
guid: c53bae489a2f499ea5b9000edb31b0bb
timeCreated: 1535421229

/Assets/UIWidgets/widgets/scroll_matrics.cs.meta → /Assets/UIWidgets/widgets/scroll_metrics.cs.meta

/Assets/UIWidgets/widgets/scroll_matrics.cs → /Assets/UIWidgets/widgets/scroll_metrics.cs

正在加载...
取消
保存