浏览代码

Merge pull request #384 from UnityTech/filter_records

Filter picture records
/main
GitHub 5 年前
当前提交
41137c2c
共有 33 个文件被更改,包括 1777 次插入540 次删除
  1. 4
      Runtime/Plugins/platform/ios/UIWidgetsTextInputPlugin.mm
  2. 1
      Runtime/cupertino/button.cs
  3. 2
      Runtime/cupertino/slider.cs
  4. 7
      Runtime/editor/window_config.cs
  5. 4
      Runtime/material/input_decorator.cs
  6. 1
      Runtime/painting/gradient.cs
  7. 2
      Runtime/painting/text_painter.cs
  8. 32
      Runtime/painting/text_style.cs
  9. 34
      Runtime/rendering/editable.cs
  10. 8
      Runtime/rendering/shifted_box.cs
  11. 8
      Runtime/ui/geometry.cs
  12. 2
      Runtime/ui/painting/draw_cmd.cs
  13. 8
      Runtime/ui/painting/path.cs
  14. 53
      Runtime/ui/painting/picture.cs
  15. 59
      Runtime/ui/renderer/cmdbufferCanvas/rendering/canvas_impl.cs
  16. 16
      Runtime/ui/renderer/common/geometry/path/path.cs
  17. 4
      Runtime/ui/renderer/common/geometry/path/path_cache.cs
  18. 8
      Runtime/ui/renderer/common/geometry/rect.cs
  19. 58
      Runtime/ui/renderer/common/picture.cs
  20. 31
      Runtime/ui/text.cs
  21. 491
      Runtime/ui/txt/paragraph.cs
  22. 1
      Runtime/widgets/list_wheel_scroll_view.cs
  23. 2
      Runtime/widgets/pages.cs
  24. 5
      Runtime/widgets/routes.cs
  25. 1
      Runtime/widgets/sliver.cs
  26. 130
      Runtime/cupertino/activity_indicator.cs
  27. 11
      Runtime/cupertino/activity_indicator.cs.meta
  28. 524
      Runtime/external/RTree.cs
  29. 11
      Runtime/external/RTree.cs.meta
  30. 493
      Runtime/external/SplayTree.cs
  31. 11
      Runtime/external/SplayTree.cs.meta
  32. 284
      Runtime/material/search.cs
  33. 11
      Runtime/material/search.cs.meta

4
Runtime/Plugins/platform/ios/UIWidgetsTextInputPlugin.mm


- (UITextPosition*)positionFromPosition:(UITextPosition*)position offset:(NSInteger)offset {
NSUInteger offsetPosition = ((UIWidgetsTextPosition*)position).index;
NSInteger newLocation = (NSInteger)offsetPosition + offset;
if (newLocation < 0 || newLocation > (NSInteger)self.text.length) {
return nil;
}
if (offset >= 0) {
for (NSInteger i = 0; i < offset && offsetPosition < self.text.length; ++i)
offsetPosition = [self incrementOffsetPosition:offsetPosition];

1
Runtime/cupertino/button.cs


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

2
Runtime/cupertino/slider.cs


this._divisions = divisions;
this._activeColor = activeColor;
this._onChanged = onChanged;
this.onChangeStart = onChangeStart;
this.onChangeEnd = onChangeEnd;
this._drag = new HorizontalDragGestureRecognizer();
this._drag.onStart = this._handleDragStart;
this._drag.onUpdate = this._handleDragUpdate;

7
Runtime/editor/window_config.cs


public class WindowConfig {
public readonly bool disableRasterCache;
public static float MaxRasterImageSize = 4096;
#if UNITY_ANDROID
//make API compatible to low-end Android devices
public static float MaxRasterImageSize = 2048;
#else
public static float MaxRasterImageSize = 4096;
#endif
static bool? _disableComputeBuffer = null;

4
Runtime/material/input_decorator.cs


this.hasFloatingPlaceholder = hasFloatingPlaceholder;
this.isDense = isDense;
this.contentPadding = contentPadding;
this.prefix = prefix;
this.prefixText = prefixText;
this.suffix = suffix;
this.suffixText = suffixText;
this.suffixIcon = suffixIcon;
this.suffixStyle = suffixStyle;
this.counter = counter;

1
Runtime/painting/gradient.cs


using System.Collections.Generic;
using System.Linq;
using Unity.UIWidgets.foundation;
using Unity.UIWidgets.Runtime.external;
using Unity.UIWidgets.ui;
using UnityEngine;
using Color = Unity.UIWidgets.ui.Color;

2
Runtime/painting/text_painter.cs


using System.Collections.Generic;
using System.Collections.Generic;
using Unity.UIWidgets.foundation;
using Unity.UIWidgets.service;
using Unity.UIWidgets.ui;

32
Runtime/painting/text_style.cs


public readonly Paint foreground;
public readonly Paint background;
public readonly string fontFamily;
public readonly List<BoxShadow> shadows;
public List<string> fontFamilyFallback {
get { return this._fontFamilyFallback; }

float? decorationThickness = null,
string fontFamily = null,
List<string> fontFamilyFallback = null,
List<BoxShadow> shadows = null,
string debugLabel = null) {
D.assert(color == null || foreground == null, () => _kColorForegroundWarning);
D.assert(backgroundColor == null || background == null, () => _kColorBackgroundWarning);

this.debugLabel = debugLabel;
this.foreground = foreground;
this.background = background;
this.shadows = shadows;
if (this.inherit != other.inherit || this.fontFamily != other.fontFamily
|| this.fontSize != other.fontSize || this.fontWeight != other.fontWeight
|| this.fontStyle != other.fontStyle ||
this.letterSpacing != other.letterSpacing
|| this.wordSpacing != other.wordSpacing ||
this.textBaseline != other.textBaseline
|| this.height != other.height || this.background != other.background) {
if (this.inherit != other.inherit || this.fontFamily != other.fontFamily ||
this.fontSize != other.fontSize || this.fontWeight != other.fontWeight ||
this.fontStyle != other.fontStyle || this.letterSpacing != other.letterSpacing ||
this.wordSpacing != other.wordSpacing || this.textBaseline != other.textBaseline ||
this.height != other.height || this.background != other.background ||
this.shadows.equalsList(other.shadows)) {
this.decorationColor != other.decorationColor
|| this.decorationStyle != other.decorationStyle) {
this.decorationColor != other.decorationColor ||
this.decorationStyle != other.decorationStyle) {
return RenderComparison.paint;
}

float decorationThicknessDelta = 0.0f,
string fontFamily = null,
List<string> fontFamilyFallback = null,
List<BoxShadow> shadows = null,
float fontSizeFactor = 1.0f,
float fontSizeDelta = 0.0f,
int fontWeightDelta = 0,

decorationThickness: this.decorationThickness == null
? null
: this.decorationThickness * decorationThicknessFactor + decorationThicknessDelta,
shadows: shadows ?? this.shadows,
debugLabel: modifiedDebugLabel
);
}

decorationColor: other.decorationColor,
decorationStyle: other.decorationStyle,
decorationThickness: other.decorationThickness,
shadows: other.shadows,
debugLabel: mergedDebugLabel
);
}

Color decorationColor = null,
TextDecorationStyle? decorationStyle = null,
float? decorationThickness = null,
List<BoxShadow> shadows = null,
string debugLabel = null) {
D.assert(color == null || foreground == null, () => _kColorForegroundWarning);
D.assert(backgroundColor == null || background == null, () => _kColorBackgroundWarning);

decorationThickness: decorationThickness ?? this.decorationThickness,
foreground: foreground ?? this.foreground,
background: background ?? this.background,
shadows: shadows ?? this.shadows,
debugLabel: newDebugLabel
);
}

decorationColor: Color.lerp(null, b.decorationColor, t),
decorationStyle: t < 0.5f ? null : b.decorationStyle,
decorationThickness: t < 0.5f ? null : b.decorationThickness,
shadows: t < 0.5f ? null : b.shadows,
debugLabel: lerpDebugLabel
);
}

decorationColor: Color.lerp(a.decorationColor, null, t),
decorationStyle: t < 0.5f ? a.decorationStyle : null,
decorationThickness: t < 0.5f ? a.decorationThickness : null,
shadows: t < 0.5f ? a.shadows : null,
debugLabel: lerpDebugLabel
);
}

decorationThickness: MathUtils.lerpFloat(
a.decorationThickness ?? b.decorationThickness ?? 0.0f,
b.decorationThickness ?? a.decorationThickness ?? 0.0f, t),
shadows: t < 0.5f ? a.shadows : b.shadows,
debugLabel: lerpDebugLabel
);
}

this.decorationThickness == other.decorationThickness &&
Equals(this.foreground, other.foreground) &&
Equals(this.background, other.background) &&
CollectionUtils.equalsList(this.fontFamilyFallback, other.fontFamilyFallback) &&
this.fontFamilyFallback.equalsList(other.fontFamilyFallback) &&
this.shadows.equalsList(other.shadows) &&
string.Equals(this.fontFamily, other.fontFamily);
}

hashCode = (hashCode * 397) ^ (this.fontFamily != null ? this.fontFamily.GetHashCode() : 0);
hashCode = (hashCode * 397) ^
(this.fontFamilyFallback != null ? this.fontFamilyFallback.GetHashCode() : 0);
hashCode = (hashCode * 397) ^ (this.shadows != null ? this.shadows.GetHashCode() : 0);
return hashCode;
}
}

34
Runtime/rendering/editable.cs


get {
switch (Application.platform) {
case RuntimePlatform.IPhonePlayer:
return Rect.fromLTWH(0.0f, -EditableUtils._kCaretHeightOffset + 0.5f, this.cursorWidth,
return Rect.fromLTWH(0.0f, 0.0f, this.cursorWidth,
this.preferredLineHeight + 2.0f);
default:
return Rect.fromLTWH(0.0f, EditableUtils._kCaretHeightOffset, this.cursorWidth,

if (this._cursorOffset != null) {
caretRect = caretRect.shift(this._cursorOffset);
}
#if !UNITY_IOS
if (this._textPainter.getFullHeightForCaret(textPosition, this._caretPrototype) != null) {
caretRect = Rect.fromLTWH(
caretRect.left,
caretRect.top - EditableUtils._kCaretHeightOffset,
caretRect.width,
this._textPainter.getFullHeightForCaret(textPosition, this._caretPrototype).Value
);
float? caretHeight = this._textPainter.getFullHeightForCaret(textPosition, this._caretPrototype);
if (caretHeight != null) {
switch (Application.platform) {
case RuntimePlatform.IPhonePlayer:
float heightDiff = caretHeight.Value - caretRect.height;
caretRect = Rect.fromLTWH(
caretRect.left,
caretRect.top + heightDiff / 2f,
caretRect.width,
caretRect.height
);
break;
default:
caretRect = Rect.fromLTWH(
caretRect.left,
caretRect.top - EditableUtils._kCaretHeightOffset,
caretRect.width,
caretHeight.Value
);
break;
}
#endif
caretRect = caretRect.shift(this._getPixelPerfectCursorOffset(caretRect));

8
Runtime/rendering/shifted_box.cs


public float? widthFactor {
get { return this._widthFactor; }
set {
if (this._widthFactor != value) {
if (this._widthFactor == value) {
return;
}

public float? heightFactor {
get { return this._heightFactor; }
set {
if (this._heightFactor != value) {
if (this._heightFactor == value) {
return;
}

public float baseline {
get { return this._baseline; }
set {
if (this._baseline != value) {
if (this._baseline == value) {
return;
}

public TextBaseline baselineType {
get { return this._baselineType; }
set {
if (this._baselineType != value) {
if (this._baselineType == value) {
return;
}

8
Runtime/ui/geometry.cs


get { return new Size(this.width, this.height); }
}
public float area {
get { return this.width * this.height; }
}
public float margin {
get { return this.width + this.height; }
}
public static readonly Rect zero = new Rect(0, 0, 0, 0);
public static readonly Rect one = new Rect(0, 0, 1, 1);

2
Runtime/ui/painting/draw_cmd.cs


namespace Unity.UIWidgets.ui {
namespace Unity.UIWidgets.ui {
public abstract class DrawCmd {
}

8
Runtime/ui/painting/path.cs


return Rect.fromLTRB(this._minX, this._minY, this._maxX, this._maxY);
}
public Rect getBoundsWithMargin(float margin) {
if (this._minX - margin >= this._maxX + margin || this._minY - margin >= this._maxY + margin) {
return Rect.zero;
}
return Rect.fromLTRB(this._minX - margin, this._minY - margin, this._maxX + margin, this._maxY + margin);
}
public static Path combine(PathOperation operation, Path path1, Path path2) {
D.assert(path1 != null);
D.assert(path2 != null);

53
Runtime/ui/painting/picture.cs


using System;
using System.Collections.Generic;
using Unity.UIWidgets.foundation;
using Unity.UIWidgets.Runtime.external;
public Picture(List<DrawCmd> drawCmds, Rect paintBounds, bool isDynamic = false) {
public Picture(List<DrawCmd> drawCmds,
Rect paintBounds,
bool isDynamic = false,
BBoxHierarchy<IndexedRect> bbh = null,
List<int> stateUpdatesIndices = null) {
this.bbh = bbh;
this.stateUpdatesIndices = stateUpdatesIndices;
public readonly BBoxHierarchy<IndexedRect> bbh;
public readonly List<int> stateUpdatesIndices;
public bool isDynamic {
get { return this._isDynamic; }

readonly List<DrawCmd> _drawCmds = new List<DrawCmd>();
readonly List<CanvasState> _states = new List<CanvasState>();
readonly BBoxHierarchy<IndexedRect> _bbh = new RTree<IndexedRect>();
readonly List<int> _stateUpdateIndices = new List<int>();
bool _isDynamic;

layerOffset = null,
paintBounds = Rect.zero,
});
this._bbh.Clear();
this._stateUpdateIndices.Clear();
}
public Picture endRecording() {

var state = this._getState();
return new Picture(new List<DrawCmd>(this._drawCmds), state.paintBounds, this._isDynamic);
return new Picture(
new List<DrawCmd>(this._drawCmds),
state.paintBounds,
this._isDynamic,
this._bbh,
this._stateUpdateIndices);
}
public void addDrawCmd(DrawCmd drawCmd) {

case DrawSave _:
this._states.Add(this._getState().copy());
this._stateUpdateIndices.Add(this._drawCmds.Count - 1);
break;
case DrawSaveLayer cmd: {
this._states.Add(new CanvasState {

layerOffset = cmd.rect.topLeft,
paintBounds = Rect.zero,
});
this._stateUpdateIndices.Add(this._drawCmds.Count - 1);
break;
}

paintBounds = state.xform.mapRect(paintBounds);
this._addPaintBounds(paintBounds);
}
this._stateUpdateIndices.Add(this._drawCmds.Count - 1);
break;
}

state.xform = new Matrix3(state.xform);
state.xform.preTranslate(cmd.dx, cmd.dy);
this._stateUpdateIndices.Add(this._drawCmds.Count - 1);
break;
}

state.xform.preScale(cmd.sx, (cmd.sy ?? cmd.sx));
this._stateUpdateIndices.Add(this._drawCmds.Count - 1);
break;
}

cmd.offset.dx,
cmd.offset.dy);
}
this._stateUpdateIndices.Add(this._drawCmds.Count - 1);
break;
}

state.xform = new Matrix3(state.xform);
state.xform.preSkew(cmd.sx, cmd.sy);
this._stateUpdateIndices.Add(this._drawCmds.Count - 1);
break;
}

state.xform.preConcat(cmd.matrix);
this._stateUpdateIndices.Add(this._drawCmds.Count - 1);
break;
}

this._stateUpdateIndices.Add(this._drawCmds.Count - 1);
break;
}

this._stateUpdateIndices.Add(this._drawCmds.Count - 1);
break;
}

var rect = state.xform.mapRect(cmd.rect);
state.scissor = state.scissor == null ? rect : state.scissor.intersect(rect);
this._stateUpdateIndices.Add(this._drawCmds.Count - 1);
break;
}

var rect = state.xform.mapRect(cmd.rrect.outerRect);
state.scissor = state.scissor == null ? rect : state.scissor.intersect(rect);
this._stateUpdateIndices.Add(this._drawCmds.Count - 1);
break;
}

cache.computeFillMesh(0.0f, out _);
var rect = cache.fillMesh.transform(state.xform).bounds;
state.scissor = state.scissor == null ? rect : state.scissor.intersect(rect);
this._stateUpdateIndices.Add(this._drawCmds.Count - 1);
break;
}

float sigma = scale * paint.maskFilter.sigma;
float sigma3 = 3 * sigma;
this._addPaintBounds(mesh.bounds.inflate(sigma3));
this._bbh.Insert(new IndexedRect(uiRectHelper.fromRect(mesh.bounds.inflate(sigma3 + 5)).Value,
this._drawCmds.Count - 1));
this._bbh.Insert(new IndexedRect(uiRectHelper.fromRect(mesh.bounds.inflate(5)).Value,
this._drawCmds.Count - 1));
}
break;

cmd.image.width, cmd.image.height);
rect = state.xform.mapRect(rect);
this._addPaintBounds(rect);
this._bbh.Insert(new IndexedRect(uiRectHelper.fromRect(rect.inflate(5)).Value,
this._drawCmds.Count - 1));
if (cmd.image.isDynamic) {
this._isDynamic = true;
}

var state = this._getState();
var rect = state.xform.mapRect(cmd.dst);
this._addPaintBounds(rect);
this._bbh.Insert(new IndexedRect(uiRectHelper.fromRect(rect.inflate(5)).Value,
this._drawCmds.Count - 1));
if (cmd.image.isDynamic) {
this._isDynamic = true;
}

var state = this._getState();
var rect = state.xform.mapRect(cmd.dst);
this._addPaintBounds(rect);
this._bbh.Insert(new IndexedRect(uiRectHelper.fromRect(rect.inflate(5)).Value,
this._drawCmds.Count - 1));
if (cmd.image.isDynamic) {
this._isDynamic = true;
}

var state = this._getState();
var rect = state.xform.mapRect(cmd.picture.paintBounds);
this._addPaintBounds(rect);
this._bbh.Insert(new IndexedRect(uiRectHelper.fromRect(rect.inflate(5)).Value,
this._drawCmds.Count - 1));
if (cmd.picture.isDynamic) {
this._isDynamic = true;
}

float sigma = scale * paint.maskFilter.sigma;
float sigma3 = 3 * sigma;
this._addPaintBounds(rect.inflate(sigma3));
this._bbh.Insert(new IndexedRect(uiRectHelper.fromRect(rect.inflate(sigma3 + 5)).Value,
this._drawCmds.Count - 1));
this._bbh.Insert(new IndexedRect(uiRectHelper.fromRect(rect.inflate(5)).Value,
this._drawCmds.Count - 1));
}
break;

59
Runtime/ui/renderer/cmdbufferCanvas/rendering/canvas_impl.cs


using System;
using System.Collections.Generic;
using System.Linq;
using Unity.UIWidgets.Runtime.external;
using UnityEngine;
using UnityEngine.Rendering;

int saveCount = 0;
var drawCmds = picture.drawCmds;
var queryBound = this._currentLayer.currentState.matrix?.invert().Value
.mapRect(this._currentLayer.layerBounds) ??
this._currentLayer.layerBounds;
if (!uiRectHelper.contains(queryBound, uiRectHelper.fromRect(picture.paintBounds).Value)) {
var indices = picture.bbh.Search(queryBound).Select(bound => bound.index);
List<int> cmdIndices = indices.ToList();
cmdIndices.AddRange(picture.stateUpdatesIndices);
cmdIndices.Sort();
drawCmds = new List<DrawCmd>();
for (int i = 0; i < cmdIndices.Count; i++) {
drawCmds.Add(picture.drawCmds[cmdIndices[i]]);
}
}
foreach (var drawCmd in drawCmds) {
switch (drawCmd) {
case DrawSave _:

}
case DrawTextBlob cmd: {
this._paintTextShadow(cmd.textBlob, cmd.offset);
this._drawTextBlob(cmd.textBlob, (uiOffset.fromOffset(cmd.offset)).Value,
uiPaint.fromPaint(cmd.paint));
break;

int saveCount = 0;
var drawCmds = picture.drawCmds;
var queryBound = this._currentLayer.currentState.matrix?.invert().Value
.mapRect(this._currentLayer.layerBounds) ??
this._currentLayer.layerBounds;
if (!uiRectHelper.contains(queryBound, picture.paintBounds)) {
var indices = picture.bbh.Search(queryBound).Select(bound => bound.index);
List<int> cmdIndices = indices.ToList();
cmdIndices.Capacity += picture.stateUpdatesIndices.Count;
for (int i = 0; i < picture.stateUpdatesIndices.Count; i++) {
cmdIndices.Add(picture.stateUpdatesIndices[i]);
}
cmdIndices.Sort();
drawCmds = new List<uiDrawCmd>();
for (int i = 0; i < cmdIndices.Count; i++) {
drawCmds.Add(picture.drawCmds[cmdIndices[i]]);
}
}
foreach (var drawCmd in drawCmds) {
switch (drawCmd) {
case uiDrawSave _:

}
case uiDrawTextBlob cmd: {
this._paintTextShadow(cmd.textBlob, new Offset(cmd.offset.Value.dx, cmd.offset.Value.dy));
this._drawTextBlob(cmd.textBlob, cmd.offset.Value, cmd.paint);
break;
}

}
}
void _paintTextShadow(TextBlob? textBlob, Offset offset) {
D.assert(textBlob != null);
if (textBlob.Value.style.shadows != null && textBlob.Value.style.shadows.isNotEmpty()) {
textBlob.Value.style.shadows.ForEach(shadow => {
Paint paint = new Paint {
color = shadow.color,
maskFilter = shadow.blurRadius != 0
? MaskFilter.blur(BlurStyle.normal, shadow.blurRadius)
: null,
};
this._drawTextBlob(textBlob, uiOffset.fromOffset(shadow.offset + offset).Value,
uiPaint.fromPaint(paint));
});
}
}
void _drawTextBlob(TextBlob? textBlob, uiOffset offset, uiPaint paint) {
D.assert(textBlob != null);

}
if (paint.maskFilter != null && paint.maskFilter.Value.sigma != 0) {
this._drawWithMaskFilter(textBlobBounds, paint, paint.maskFilter.Value, null, null, false, 0, 0, tex,
textBlobBounds, mesh, notEmoji, this.___drawTextDrawMeshCallback);
this._drawWithMaskFilter(textBlobBounds, paint, paint.maskFilter.Value, null, null, false, 0, 0,
notEmoji ? tex : EmojiUtils.image.texture,
textBlobBounds, mesh, true, this.___drawTextDrawMeshCallback);
}
public void flush(uiPicture picture) {

16
Runtime/ui/renderer/common/geometry/path/path.cs


return;
}
this._isNaiveRRect = isNaiveRRect && this._hasOnlyMoveTos();
if (this._isNaiveRRect) {
this._shapeHint = shapeHint;
this._rRectCorner = corner;
}
this._shapeHint = shapeHint;
this._rRectCorner = corner;
}
bool _hasOnlyMoveTos() {

this.needCache = false;
this.pathKey = 0;
this._isNaiveRRect = false;
this._shapeHint = uiPathShapeHint.Other;
this._rRectCorner = 0;
}
void _reset() {

}
return uiRectHelper.fromLTRB(this._minX, this._minY, this._maxX, this._maxY);
}
public uiRect getBoundsWithMargin(float margin) {
if (this._minX - margin >= this._maxX + margin || this._minY - margin >= this._maxY + margin) {
return uiRectHelper.zero;
}
return uiRectHelper.fromLTRB(this._minX - margin, this._minY - margin, this._maxX + margin, this._maxY + margin);
}
void _appendMoveTo(float x, float y) {

4
Runtime/ui/renderer/common/geometry/path/path_cache.cs


}
uiVertexUV _expandFill(float fringe) {
float aa = fringe;
float aa = this.canSkipAAHairline ? 0f : fringe;
float woff = aa * 0.5f;
var points = this._points;
var paths = this._paths;

uiList<Vector3> _strokeVertices = null;
uiList<Vector2> _strokeUV = null;
if (aa > 0.0f && !this.canSkipAAHairline) {
if (aa > 0.0f) {
_strokeVertices = ObjectPool<uiList<Vector3>>.alloc();
_strokeUV = ObjectPool<uiList<Vector2>>.alloc();
cvertices = 0;

8
Runtime/ui/renderer/common/geometry/rect.cs


get { return this.bottom - this.top; }
}
public float area {
get { return this.width * this.height; }
}
public float margin {
get { return this.width + this.height; }
}
public uiOffset topLeft {
get { return new uiOffset(this.left, this.top); }
}

58
Runtime/ui/renderer/common/picture.cs


using System;
using System.Collections.Generic;
using Unity.UIWidgets.foundation;
using Unity.UIWidgets.Runtime.external;
namespace Unity.UIWidgets.ui {
public class uiPicture : PoolObject {

public static uiPicture create(List<uiDrawCmd> drawCmds, uiRect paintBounds) {
public static uiPicture create(List<uiDrawCmd> drawCmds,
uiRect paintBounds,
BBoxHierarchy<IndexedRect> bbh = null,
uiList<int> stateUpdateIndices = null) {
picture.bbh = bbh;
picture.stateUpdatesIndices = stateUpdateIndices;
public BBoxHierarchy<IndexedRect> bbh;
public uiList<int> stateUpdatesIndices;
ObjectPool<uiList<int>>.release(this.stateUpdatesIndices);
}
}

readonly List<uiCanvasState> _states = new List<uiCanvasState>(32);
readonly BBoxHierarchy<IndexedRect> _bbh = new RTree<IndexedRect>();
readonly List<int> _stateUpdateIndices = new List<int>();
public uiPictureRecorder() {
this.reset();

layerOffset = null,
paintBounds = uiRectHelper.zero
});
this._bbh.Clear();
this._stateUpdateIndices.Clear();
}
public uiPicture endRecording() {

uiList<int> stateUpdateIndices = ObjectPool<uiList<int>>.alloc();
stateUpdateIndices.AddRange(this._stateUpdateIndices);
return uiPicture.create(this._drawCmds, state.paintBounds);
return uiPicture.create(
this._drawCmds,
state.paintBounds,
bbh: this._bbh,
stateUpdateIndices: stateUpdateIndices);
}
public void addDrawCmd(uiDrawCmd drawCmd) {

case uiDrawSave _:
this._states.Add(this._getState().copy());
this._stateUpdateIndices.Add(this._drawCmds.Count - 1);
break;
case uiDrawSaveLayer cmd: {
this._states.Add(new uiCanvasState {

layerOffset = cmd.rect.Value.topLeft,
paintBounds = uiRectHelper.zero
});
this._stateUpdateIndices.Add(this._drawCmds.Count - 1);
break;
}
case uiDrawRestore _: {

}
this._setState(state);
this._stateUpdateIndices.Add(this._drawCmds.Count - 1);
break;
}
case uiDrawTranslate cmd: {

this._setState(state);
this._stateUpdateIndices.Add(this._drawCmds.Count - 1);
break;
}
case uiDrawScale cmd: {

this._setState(state);
this._stateUpdateIndices.Add(this._drawCmds.Count - 1);
break;
}
case uiDrawRotate cmd: {

}
this._setState(state);
this._stateUpdateIndices.Add(this._drawCmds.Count - 1);
break;
}
case uiDrawSkew cmd: {

this._setState(state);
this._stateUpdateIndices.Add(this._drawCmds.Count - 1);
break;
}
case uiDrawConcat cmd: {

this._setState(state);
this._stateUpdateIndices.Add(this._drawCmds.Count - 1);
break;
}
case uiDrawResetMatrix _: {

this._stateUpdateIndices.Add(this._drawCmds.Count - 1);
break;
}
case uiDrawSetMatrix cmd: {

this._stateUpdateIndices.Add(this._drawCmds.Count - 1);
break;
}
case uiDrawClipRect cmd: {

state.scissor = state.scissor == null ? rect : state.scissor.Value.intersect(rect);
this._setState(state);
this._stateUpdateIndices.Add(this._drawCmds.Count - 1);
break;
}
case uiDrawClipRRect cmd: {

state.scissor = state.scissor == null ? rect : state.scissor.Value.intersect(rect);
this._setState(state);
this._stateUpdateIndices.Add(this._drawCmds.Count - 1);
break;
}
case uiDrawClipPath cmd: {

state.scissor = state.scissor == null ? rect : state.scissor.Value.intersect(rect);
this._setState(state);
ObjectPool<uiMeshMesh>.release(transformedMesh);
this._stateUpdateIndices.Add(this._drawCmds.Count - 1);
break;
}
case uiDrawPath cmd: {

float sigma = scale * paint.maskFilter.Value.sigma;
float sigma3 = 3 * sigma;
this._addPaintBounds(uiRectHelper.inflate(mesh.bounds, sigma3));
this._bbh.Insert(new IndexedRect(uiRectHelper.inflate(mesh.bounds, sigma3 + 5),
this._drawCmds.Count - 1));
this._bbh.Insert(new IndexedRect(uiRectHelper.inflate(mesh.bounds, 5),
this._drawCmds.Count - 1));
}
ObjectPool<uiMeshMesh>.release(mesh);

cmd.image.width, cmd.image.height);
rect = state.xform.mapRect(rect);
this._addPaintBounds(rect);
this._bbh.Insert(new IndexedRect(uiRectHelper.inflate(rect, 5),
this._drawCmds.Count - 1));
break;
}
case uiDrawImageRect cmd: {

this._bbh.Insert(new IndexedRect(uiRectHelper.inflate(rect, 5),
this._drawCmds.Count - 1));
break;
}
case uiDrawImageNine cmd: {

this._bbh.Insert(new IndexedRect(uiRectHelper.inflate(rect, 5),
this._drawCmds.Count - 1));
break;
}
case uiDrawPicture cmd: {

this._bbh.Insert(new IndexedRect(uiRectHelper.inflate(rect, 5),
this._drawCmds.Count - 1));
break;
}
case uiDrawTextBlob cmd: {

cmd.textBlob.Value.shiftedBoundsInText(cmd.offset.Value.dx, cmd.offset.Value.dy)).Value;
rect = state.xform.mapRect(rect);
this._bbh.Insert(new IndexedRect(uiRectHelper.inflate(rect, 5),
this._drawCmds.Count - 1));
var paint = cmd.paint;
if (paint.maskFilter != null && paint.maskFilter.Value.sigma != 0) {

this._bbh.Insert(new IndexedRect(uiRectHelper.inflate(rect, sigma3 + 5),
this._drawCmds.Count - 1));
this._bbh.Insert(new IndexedRect(uiRectHelper.inflate(rect, 5),
this._drawCmds.Count - 1));
}
break;

31
Runtime/ui/text.cs


using System;
using System.Collections.Generic;
using Unity.UIWidgets.foundation;
using Unity.UIWidgets.painting;
namespace Unity.UIWidgets.ui {

public readonly string fontFamily = kDefaultFontFamily;
public readonly Paint foreground;
public readonly Paint background;
public readonly List<BoxShadow> shadows;
internal UnityEngine.Color UnityColor {
get { return this.color.toColor(); }

decorationColor: style.decorationColor ?? currentStyle.decorationColor,
fontFamily: style.fontFamily ?? currentStyle.fontFamily,
foreground: style.foreground ?? currentStyle.foreground,
background: style.background ?? currentStyle.background
background: style.background ?? currentStyle.background,
shadows: style.shadows ?? currentStyle.shadows
);
}

decorationColor: style.decorationColor,
fontFamily: style.fontFamily,
foreground: style.foreground,
background: style.background
background: style.background,
shadows: style.shadows
);
}

Equals(this.decoration, other.decoration) &&
Equals(this.decorationColor, other.decorationColor) &&
this.decorationStyle == other.decorationStyle &&
string.Equals(this.fontFamily, other.fontFamily);
string.Equals(this.fontFamily, other.fontFamily) &&
this.shadows.equalsList(other.shadows);
}
public override bool Equals(object obj) {

hashCode = (hashCode * 397) ^ (this.decorationColor != null ? this.decorationColor.GetHashCode() : 0);
hashCode = (hashCode * 397) ^ this.decorationStyle.GetHashCode();
hashCode = (hashCode * 397) ^ (this.fontFamily != null ? this.fontFamily.GetHashCode() : 0);
hashCode = (hashCode * 397) ^ (this.shadows != null ? this.shadows.GetHashCode() : 0);
return hashCode;
}
}

}
public TextStyle(Color color = null, float? fontSize = null,
FontWeight fontWeight = null, FontStyle? fontStyle = null, float? letterSpacing = null,
float? wordSpacing = null, TextBaseline? textBaseline = null, float? height = null,
TextDecoration decoration = null, TextDecorationStyle? decorationStyle = null, Color decorationColor = null,
public TextStyle(Color color = null,
float? fontSize = null,
FontWeight fontWeight = null,
FontStyle? fontStyle = null,
float? letterSpacing = null,
float? wordSpacing = null,
TextBaseline? textBaseline = null,
float? height = null,
TextDecoration decoration = null,
TextDecorationStyle? decorationStyle = null,
Color decorationColor = null,
Paint background = null
Paint background = null,
List<BoxShadow> shadows = null
) {
this.color = color ?? this.color;
this.fontSize = fontSize ?? this.fontSize;

this.fontFamily = fontFamily ?? this.fontFamily;
this.foreground = foreground ?? this.foreground;
this.background = background ?? this.background;
this.shadows = shadows ?? this.shadows;
}
}

491
Runtime/ui/txt/paragraph.cs


using System;
using System.Collections;
using Unity.UIWidgets.Runtime.external;
using UnityEngine;
namespace Unity.UIWidgets.ui {

// If all the positions have not changed, use the cached ellipsized text
// else update the cache
if (!(this._ellipsizedLength == textStart + textCount - truncateCount &&
if (!(this._ellipsizedText != null &&
this._ellipsizedLength == textStart + textCount - truncateCount &&
this._ellipsizedText.Length == this._ellipsizedLength + ellipsis.Length &&
this._ellipsizedText.EndsWith(ellipsis))) {
this._ellipsizedText =

}
}
class SplayTree<TKey, TValue> : IDictionary<TKey, TValue> where TKey : IComparable<TKey> {
SplayTreeNode root;
int count;
int version = 0;
public void Add(TKey key, TValue value) {
this.Set(key, value, throwOnExisting: true);
}
public void Add(KeyValuePair<TKey, TValue> item) {
this.Set(item.Key, item.Value, throwOnExisting: true);
}
public void AddAll(IEnumerable<TKey> list) {
foreach (var key in list) {
this.Add(new KeyValuePair<TKey, TValue>(key, default));
}
}
void Set(TKey key, TValue value, bool throwOnExisting) {
if (this.count == 0) {
this.version++;
this.root = new SplayTreeNode(key, value);
this.count = 1;
return;
}
this.Splay(key);
var c = key.CompareTo(this.root.Key);
if (c == 0) {
if (throwOnExisting) {
throw new ArgumentException("An item with the same key already exists in the tree.");
}
this.version++;
this.root.Value = value;
return;
}
var n = new SplayTreeNode(key, value);
if (c < 0) {
n.LeftChild = this.root.LeftChild;
n.RightChild = this.root;
this.root.LeftChild = null;
}
else {
n.RightChild = this.root.RightChild;
n.LeftChild = this.root;
this.root.RightChild = null;
}
this.root = n;
this.count++;
this.Splay(key);
this.version++;
}
public void Clear() {
this.root = null;
this.count = 0;
this.version++;
}
public bool ContainsKey(TKey key) {
if (this.count == 0) {
return false;
}
this.Splay(key);
return key.CompareTo(this.root.Key) == 0;
}
public bool Contains(KeyValuePair<TKey, TValue> item) {
if (this.count == 0) {
return false;
}
this.Splay(item.Key);
return item.Key.CompareTo(this.root.Key) == 0 &&
(ReferenceEquals(this.root.Value, item.Value) ||
(!ReferenceEquals(item.Value, null) && item.Value.Equals(this.root.Value)));
}
public KeyValuePair<TKey, TValue>? First() {
SplayTreeNode t = this.root;
if (t == null) {
return null;
}
while (t.LeftChild != null) {
t = t.LeftChild;
}
return new KeyValuePair<TKey, TValue>(t.Key, t.Value);
}
public KeyValuePair<TKey, TValue> FirstOrDefault() {
SplayTreeNode t = this.root;
if (t == null) {
return new KeyValuePair<TKey, TValue>(default(TKey), default(TValue));
}
while (t.LeftChild != null) {
t = t.LeftChild;
}
return new KeyValuePair<TKey, TValue>(t.Key, t.Value);
}
public KeyValuePair<TKey, TValue>? Last() {
SplayTreeNode t = this.root;
if (t == null) {
return null;
}
while (t.RightChild != null) {
t = t.RightChild;
}
return new KeyValuePair<TKey, TValue>(t.Key, t.Value);
}
public KeyValuePair<TKey, TValue> LastOrDefault() {
SplayTreeNode t = this.root;
if (t == null) {
return new KeyValuePair<TKey, TValue>(default(TKey), default(TValue));
}
while (t.RightChild != null) {
t = t.RightChild;
}
return new KeyValuePair<TKey, TValue>(t.Key, t.Value);
}
void Splay(TKey key) {
SplayTreeNode l, r, t, y, header;
l = r = header = new SplayTreeNode(default(TKey), default(TValue));
t = this.root;
while (true) {
var c = key.CompareTo(t.Key);
if (c < 0) {
if (t.LeftChild == null) {
break;
}
if (key.CompareTo(t.LeftChild.Key) < 0) {
y = t.LeftChild;
t.LeftChild = y.RightChild;
y.RightChild = t;
t = y;
if (t.LeftChild == null) {
break;
}
}
r.LeftChild = t;
r = t;
t = t.LeftChild;
}
else if (c > 0) {
if (t.RightChild == null) {
break;
}
if (key.CompareTo(t.RightChild.Key) > 0) {
y = t.RightChild;
t.RightChild = y.LeftChild;
y.LeftChild = t;
t = y;
if (t.RightChild == null) {
break;
}
}
l.RightChild = t;
l = t;
t = t.RightChild;
}
else {
break;
}
}
l.RightChild = t.LeftChild;
r.LeftChild = t.RightChild;
t.LeftChild = header.RightChild;
t.RightChild = header.LeftChild;
this.root = t;
}
public bool Remove(TKey key) {
if (this.count == 0) {
return false;
}
this.Splay(key);
if (key.CompareTo(this.root.Key) != 0) {
return false;
}
if (this.root.LeftChild == null) {
this.root = this.root.RightChild;
}
else {
var swap = this.root.RightChild;
this.root = this.root.LeftChild;
this.Splay(key);
this.root.RightChild = swap;
}
this.version++;
this.count--;
return true;
}
public bool TryGetValue(TKey key, out TValue value) {
if (this.count == 0) {
value = default(TValue);
return false;
}
this.Splay(key);
if (key.CompareTo(this.root.Key) != 0) {
value = default(TValue);
return false;
}
value = this.root.Value;
return true;
}
public TValue this[TKey key] {
get {
if (this.count == 0) {
throw new KeyNotFoundException("The key was not found in the tree.");
}
this.Splay(key);
if (key.CompareTo(this.root.Key) != 0) {
throw new KeyNotFoundException("The key was not found in the tree.");
}
return this.root.Value;
}
set { this.Set(key, value, throwOnExisting: false); }
}
public int Count {
get { return this.count; }
}
public bool IsReadOnly {
get { return false; }
}
public bool Remove(KeyValuePair<TKey, TValue> item) {
if (this.count == 0) {
return false;
}
this.Splay(item.Key);
if (item.Key.CompareTo(this.root.Key) == 0 && (ReferenceEquals(this.root.Value, item.Value) ||
(!ReferenceEquals(item.Value, null) &&
item.Value.Equals(this.root.Value)))) {
return false;
}
if (this.root.LeftChild == null) {
this.root = this.root.RightChild;
}
else {
var swap = this.root.RightChild;
this.root = this.root.LeftChild;
this.Splay(item.Key);
this.root.RightChild = swap;
}
this.version++;
this.count--;
return true;
}
public void Trim(int depth) {
if (depth < 0) {
throw new ArgumentOutOfRangeException("depth", "The trim depth must not be negative.");
}
if (this.count == 0) {
return;
}
if (depth == 0) {
this.Clear();
}
else {
var prevCount = this.count;
this.count = this.Trim(this.root, depth - 1);
if (prevCount != this.count) {
this.version++;
}
}
}
int Trim(SplayTreeNode node, int depth) {
if (depth == 0) {
node.LeftChild = null;
node.RightChild = null;
return 1;
}
else {
int count = 1;
if (node.LeftChild != null) {
count += this.Trim(node.LeftChild, depth - 1);
}
if (node.RightChild != null) {
count += this.Trim(node.RightChild, depth - 1);
}
return count;
}
}
public ICollection<TKey> Keys {
get { return new TiedList<TKey>(this, this.version, this.AsList(node => node.Key)); }
}
public ICollection<TValue> Values {
get { return new TiedList<TValue>(this, this.version, this.AsList(node => node.Value)); }
}
public void CopyTo(KeyValuePair<TKey, TValue>[] array, int arrayIndex) {
this.AsList(node => new KeyValuePair<TKey, TValue>(node.Key, node.Value)).CopyTo(array, arrayIndex);
}
public IEnumerator<KeyValuePair<TKey, TValue>> GetEnumerator() {
return new TiedList<KeyValuePair<TKey, TValue>>(this, this.version,
this.AsList(node => new KeyValuePair<TKey, TValue>(node.Key, node.Value))).GetEnumerator();
}
IList<TEnumerator> AsList<TEnumerator>(Func<SplayTreeNode, TEnumerator> selector) {
if (this.root == null) {
return new TEnumerator[0];
}
var result = new List<TEnumerator>(this.count);
this.PopulateList(this.root, result, selector);
return result;
}
void PopulateList<TEnumerator>(SplayTreeNode node, List<TEnumerator> list,
Func<SplayTreeNode, TEnumerator> selector) {
if (node.LeftChild != null) {
this.PopulateList(node.LeftChild, list, selector);
}
list.Add(selector(node));
if (node.RightChild != null) {
this.PopulateList(node.RightChild, list, selector);
}
}
IEnumerator IEnumerable.GetEnumerator() {
return this.GetEnumerator();
}
sealed class SplayTreeNode {
public readonly TKey Key;
public TValue Value;
public SplayTreeNode LeftChild;
public SplayTreeNode RightChild;
public SplayTreeNode(TKey key, TValue value) {
this.Key = key;
this.Value = value;
}
}
sealed class TiedList<T> : IList<T> {
readonly SplayTree<TKey, TValue> tree;
readonly int version;
readonly IList<T> backingList;
public TiedList(SplayTree<TKey, TValue> tree, int version, IList<T> backingList) {
if (tree == null) {
throw new ArgumentNullException("tree");
}
if (backingList == null) {
throw new ArgumentNullException("backingList");
}
this.tree = tree;
this.version = version;
this.backingList = backingList;
}
public int IndexOf(T item) {
if (this.tree.version != this.version) {
throw new InvalidOperationException("The collection has been modified.");
}
return this.backingList.IndexOf(item);
}
public void Insert(int index, T item) {
throw new NotSupportedException();
}
public void RemoveAt(int index) {
throw new NotSupportedException();
}
public T this[int index] {
get {
if (this.tree.version != this.version) {
throw new InvalidOperationException("The collection has been modified.");
}
return this.backingList[index];
}
set { throw new NotSupportedException(); }
}
public void Add(T item) {
throw new NotSupportedException();
}
public void Clear() {
throw new NotSupportedException();
}
public bool Contains(T item) {
if (this.tree.version != this.version) {
throw new InvalidOperationException("The collection has been modified.");
}
return this.backingList.Contains(item);
}
public void CopyTo(T[] array, int arrayIndex) {
if (this.tree.version != this.version) {
throw new InvalidOperationException("The collection has been modified.");
}
this.backingList.CopyTo(array, arrayIndex);
}
public int Count {
get { return this.tree.count; }
}
public bool IsReadOnly {
get { return true; }
}
public bool Remove(T item) {
throw new NotSupportedException();
}
public IEnumerator<T> GetEnumerator() {
if (this.tree.version != this.version) {
throw new InvalidOperationException("The collection has been modified.");
}
foreach (var item in this.backingList) {
yield return item;
if (this.tree.version != this.version) {
throw new InvalidOperationException("The collection has been modified.");
}
}
}
IEnumerator IEnumerable.GetEnumerator() {
return this.GetEnumerator();
}
}
}
}

1
Runtime/widgets/list_wheel_scroll_view.cs


using Unity.UIWidgets.painting;
using Unity.UIWidgets.physics;
using Unity.UIWidgets.rendering;
using Unity.UIWidgets.Runtime.external;
using Unity.UIWidgets.scheduler;
using Unity.UIWidgets.ui;
using UnityEngine;

2
Runtime/widgets/pages.cs


public abstract class PageRoute : ModalRoute {
public readonly bool fullscreenDialog;
public PageRoute() {}
public PageRoute(RouteSettings settings, bool fullscreenDialog = false) : base(settings) {
this.fullscreenDialog = fullscreenDialog;
}

5
Runtime/widgets/routes.cs


}
public abstract class ModalRoute : LocalHistoryRouteTransitionRoute {
protected ModalRoute(RouteSettings settings) : base(settings) {
}
protected ModalRoute() {}
protected ModalRoute(RouteSettings settings) : base(settings) { }
public static Color _kTransparent = new Color(0x00000000);

1
Runtime/widgets/sliver.cs


using Unity.UIWidgets.foundation;
using Unity.UIWidgets.painting;
using Unity.UIWidgets.rendering;
using Unity.UIWidgets.Runtime.external;
using Unity.UIWidgets.ui;
namespace Unity.UIWidgets.widgets {

130
Runtime/cupertino/activity_indicator.cs


using System;
using Unity.UIWidgets.animation;
using Unity.UIWidgets.foundation;
using Unity.UIWidgets.ui;
using Unity.UIWidgets.widgets;
using UnityEngine;
using Canvas = Unity.UIWidgets.ui.Canvas;
using Color = Unity.UIWidgets.ui.Color;
namespace Unity.UIWidgets.cupertino {
static class CupertinoActivityIndicatorUtils {
public const float _kDefaultIndicatorRadius = 10.0f;
public const float _kTwoPI = Mathf.PI * 2.0f;
public const int _kTickCount = 12;
public const int _kHalfTickCount = _kTickCount / 2;
public static readonly Color _kTickColor = CupertinoColors.lightBackgroundGray;
public static readonly Color _kActiveTickColor = new Color(0xFF9D9D9D);
}
public class CupertinoActivityIndicator : StatefulWidget {
public CupertinoActivityIndicator(
Key key = null,
bool animating = true,
float radius = CupertinoActivityIndicatorUtils._kDefaultIndicatorRadius
) : base(key: key) {
D.assert(radius > 0);
this.animating = animating;
this.radius = radius;
}
public readonly bool animating;
public readonly float radius;
public override State createState() {
return new _CupertinoActivityIndicatorState();
}
}
class _CupertinoActivityIndicatorState : TickerProviderStateMixin<CupertinoActivityIndicator> {
AnimationController _controller;
public override void initState() {
base.initState();
this._controller = new AnimationController(
duration: TimeSpan.FromSeconds(1),
vsync: this
);
if (this.widget.animating) {
this._controller.repeat();
}
}
public override void didUpdateWidget(StatefulWidget oldWidget) {
base.didUpdateWidget(oldWidget: oldWidget);
if (oldWidget is CupertinoActivityIndicator _oldWidget) {
if (this.widget.animating != _oldWidget.animating) {
if (this.widget.animating) {
this._controller.repeat();
}
else {
this._controller.stop();
}
}
}
}
public override void dispose() {
this._controller.dispose();
base.dispose();
}
public override Widget build(BuildContext context) {
return new SizedBox(
height: this.widget.radius * 2,
width: this.widget.radius * 2,
child: new CustomPaint(
painter: new _CupertinoActivityIndicatorPainter(
position: this._controller,
radius: this.widget.radius
)
)
);
}
}
class _CupertinoActivityIndicatorPainter : AbstractCustomPainter {
public _CupertinoActivityIndicatorPainter(
Animation<float> position,
float radius
) : base(repaint: position) {
this.tickFundamentalRRect = RRect.fromLTRBXY(
left: -radius,
top: 1.0f * radius / CupertinoActivityIndicatorUtils._kDefaultIndicatorRadius,
right: -radius / 2.0f,
bottom: -1.0f * radius / CupertinoActivityIndicatorUtils._kDefaultIndicatorRadius,
radiusX: 1.0f,
radiusY: 1.0f
);
this.position = position;
}
readonly Animation<float> position;
readonly RRect tickFundamentalRRect;
public override void paint(Canvas canvas, Size size) {
Paint paint = new Paint();
canvas.save();
canvas.translate(size.width / 2.0f, size.height / 2.0f);
int activeTick = (CupertinoActivityIndicatorUtils._kTickCount * this.position.value).floor();
for (int i = 0; i < CupertinoActivityIndicatorUtils._kTickCount; ++i) {
float t = (((i + activeTick) % CupertinoActivityIndicatorUtils._kTickCount) /
CupertinoActivityIndicatorUtils._kHalfTickCount).clamp(0, 1);
paint.color = Color.lerp(a: CupertinoActivityIndicatorUtils._kActiveTickColor,
b: CupertinoActivityIndicatorUtils._kTickColor, t: t);
canvas.drawRRect(rect: this.tickFundamentalRRect, paint: paint);
canvas.rotate(-CupertinoActivityIndicatorUtils._kTwoPI / CupertinoActivityIndicatorUtils._kTickCount);
}
canvas.restore();
}
public override bool shouldRepaint(CustomPainter oldPainter) {
return (oldPainter as _CupertinoActivityIndicatorPainter).position != this.position;
}
}
}

11
Runtime/cupertino/activity_indicator.cs.meta


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

524
Runtime/external/RTree.cs


using System;
using System.Collections.Generic;
using System.Linq;
using Unity.UIWidgets.ui;
namespace Unity.UIWidgets.Runtime.external
{
public interface ISpatialData
{
uiRect bounds { get; }
}
public class IndexedRect : ISpatialData
{
private uiRect _bounds;
public uiRect bounds
{
get { return _bounds; }
}
public readonly int index;
public IndexedRect(uiRect bounds, int index)
{
this._bounds = bounds;
this.index = index;
}
}
/// <summary>
/// Non-generic class to produce instances of the generic class,
/// optionally using type inference.
/// </summary>
public static class ProjectionComparer
{
/// <summary>
/// Creates an instance of ProjectionComparer using the specified projection.
/// </summary>
/// <typeparam name="TSource">Type parameter for the elements to be compared</typeparam>
/// <typeparam name="TKey">Type parameter for the keys to be compared, after being projected from the elements</typeparam>
/// <param name="projection">Projection to use when determining the key of an element</param>
/// <returns>A comparer which will compare elements by projecting each element to its key, and comparing keys</returns>
public static ProjectionComparer<TSource, TKey> Create<TSource, TKey>(Func<TSource, TKey> projection)
{
return new ProjectionComparer<TSource, TKey>(projection);
}
/// <summary>
/// Creates an instance of ProjectionComparer using the specified projection.
/// The ignored parameter is solely present to aid type inference.
/// </summary>
/// <typeparam name="TSource">Type parameter for the elements to be compared</typeparam>
/// <typeparam name="TKey">Type parameter for the keys to be compared, after being projected from the elements</typeparam>
/// <param name="ignored">Value is ignored - type may be used by type inference</param>
/// <param name="projection">Projection to use when determining the key of an element</param>
/// <returns>A comparer which will compare elements by projecting each element to its key, and comparing keys</returns>
public static ProjectionComparer<TSource, TKey> Create<TSource, TKey>
(TSource ignored,
Func<TSource, TKey> projection)
{
return new ProjectionComparer<TSource, TKey>(projection);
}
}
/// <summary>
/// Class generic in the source only to produce instances of the
/// doubly generic class, optionally using type inference.
/// </summary>
public static class ProjectionComparer<TSource>
{
/// <summary>
/// Creates an instance of ProjectionComparer using the specified projection.
/// </summary>
/// <typeparam name="TKey">Type parameter for the keys to be compared, after being projected from the elements</typeparam>
/// <param name="projection">Projection to use when determining the key of an element</param>
/// <returns>A comparer which will compare elements by projecting each element to its key, and comparing keys</returns>
public static ProjectionComparer<TSource, TKey> Create<TKey>(Func<TSource, TKey> projection)
{
return new ProjectionComparer<TSource, TKey>(projection);
}
}
/// <summary>
/// Comparer which projects each element of the comparison to a key, and then compares
/// those keys using the specified (or default) comparer for the key type.
/// </summary>
/// <typeparam name="TSource">Type of elements which this comparer will be asked to compare</typeparam>
/// <typeparam name="TKey">Type of the key projected from the element</typeparam>
public class ProjectionComparer<TSource, TKey> : IComparer<TSource>
{
private readonly IComparer<TKey> comparer;
private readonly Func<TSource, TKey> projection;
/// <summary>
/// Creates a new instance using the specified projection, which must not be null.
/// The default comparer for the projected type is used.
/// </summary>
/// <param name="projection">Projection to use during comparisons</param>
public ProjectionComparer(Func<TSource, TKey> projection)
: this(projection, null)
{
}
/// <summary>
/// Creates a new instance using the specified projection, which must not be null.
/// </summary>
/// <param name="projection">Projection to use during comparisons</param>
/// <param name="comparer">
/// The comparer to use on the keys. May be null, in
/// which case the default comparer will be used.
/// </param>
public ProjectionComparer(Func<TSource, TKey> projection, IComparer<TKey> comparer)
{
this.comparer = comparer ?? Comparer<TKey>.Default;
this.projection = projection;
}
/// <summary>
/// Compares x and y by projecting them to keys and then comparing the keys.
/// Null values are not projected; they obey the
/// standard comparer contract such that two null values are equal; any null value is
/// less than any non-null value.
/// </summary>
public int Compare(TSource x, TSource y)
{
// Don't want to project from nullity
if (x == null && y == null) return 0;
if (x == null) return -1;
if (y == null) return 1;
return comparer.Compare(projection(x), projection(y));
}
}
public interface BBoxHierarchy<T> where T : ISpatialData
{
IReadOnlyList<T> Search(in uiRect boundingBox);
void BulkLoad(IEnumerable<T> items);
void Insert(T data);
void Clear();
}
public class RTree<T> : BBoxHierarchy<T> where T : ISpatialData
{
public class RTreeNode : ISpatialData
{
internal readonly List<ISpatialData> children;
private uiRect _Rect;
internal RTreeNode(List<ISpatialData> items, int height)
{
Height = height;
children = items;
ResetRect();
}
public IReadOnlyList<ISpatialData> Children => children;
public int Height { get; }
public bool IsLeaf => Height == 1;
public uiRect bounds => _Rect;
internal void Add(ISpatialData node)
{
children.Add(node);
_Rect = bounds.expandToInclude(node.bounds);
}
internal void Remove(ISpatialData node)
{
children.Remove(node);
ResetRect();
}
internal void RemoveRange(int index, int count)
{
children.RemoveRange(index, count);
ResetRect();
}
internal void ResetRect()
{
_Rect = GetEnclosingRect(children);
}
}
#region Search
private List<T> DoSearch(in uiRect boundingBox)
{
if (!uiRectHelper.overlaps(Root.bounds, boundingBox))
return new List<T>();
var intersections = new List<T>();
var queue = new Queue<RTreeNode>();
queue.Enqueue(Root);
while (queue.Count != 0)
{
var item = queue.Dequeue();
if (item.IsLeaf)
{
foreach (var leafChildItem in item.children.Cast<T>())
if (uiRectHelper.overlaps(leafChildItem.bounds, boundingBox))
intersections.Add(leafChildItem);
}
else
{
foreach (var child in item.children.Cast<RTreeNode>())
if (uiRectHelper.overlaps(child.bounds, boundingBox))
queue.Enqueue(child);
}
}
return intersections;
}
#endregion
private static uiRect GetEnclosingRect(IEnumerable<ISpatialData> items)
{
var uiRect = uiRectHelper.zero;
foreach (var data in items) uiRect = uiRect.expandToInclude(data.bounds);
return uiRect;
}
private List<T> GetAllChildren(List<T> list, RTreeNode n)
{
if (n.IsLeaf)
list.AddRange(
n.children.Cast<T>());
else
foreach (var node in n.children.Cast<RTreeNode>())
GetAllChildren(list, node);
return list;
}
#region Sort Functions
private static readonly IComparer<ISpatialData> CompareMinX =
ProjectionComparer<ISpatialData>.Create(d => d.bounds.left);
private static readonly IComparer<ISpatialData> CompareMinY =
ProjectionComparer<ISpatialData>.Create(d => d.bounds.top);
#endregion
#region Insert
private List<RTreeNode> FindCoveringArea(in uiRect area, int depth)
{
var path = new List<RTreeNode>();
var node = Root;
var _area = area; //FIX CS1628
while (true)
{
path.Add(node);
if (node.IsLeaf || path.Count == depth) return path;
node = node.children
.Select(c => new
{EnlargedArea = c.bounds.expandToInclude(_area).area, c.bounds.area, Node = c as RTreeNode})
.OrderBy(x => x.EnlargedArea)
.ThenBy(x => x.area)
.Select(x => x.Node)
.First();
}
}
private void Insert(ISpatialData data, int depth)
{
var path = FindCoveringArea(data.bounds, depth);
var insertNode = path.Last();
insertNode.Add(data);
while (--depth >= 0)
if (path[depth].children.Count > maxEntries)
{
var newNode = SplitNode(path[depth]);
if (depth == 0)
SplitRoot(newNode);
else
path[depth - 1].Add(newNode);
}
else
{
path[depth].ResetRect();
}
}
#region SplitNode
private void SplitRoot(RTreeNode newRTreeNode)
{
Root = new RTreeNode(new List<ISpatialData> {Root, newRTreeNode}, Root.Height + 1);
}
private RTreeNode SplitNode(RTreeNode rTreeNode)
{
SortChildren(rTreeNode);
var splitPoint = GetBestSplitIndex(rTreeNode.children);
var newChildren = rTreeNode.children.Skip(splitPoint).ToList();
rTreeNode.RemoveRange(splitPoint, rTreeNode.children.Count - splitPoint);
return new RTreeNode(newChildren, rTreeNode.Height);
}
#region SortChildren
private void SortChildren(RTreeNode rTreeNode)
{
rTreeNode.children.Sort(CompareMinX);
var splitsByX = GetPotentialSplitMargins(rTreeNode.children);
rTreeNode.children.Sort(CompareMinY);
var splitsByY = GetPotentialSplitMargins(rTreeNode.children);
if (splitsByX < splitsByY)
rTreeNode.children.Sort(CompareMinX);
}
private float GetPotentialSplitMargins(List<ISpatialData> children)
{
return GetPotentialEnclosingMargins(children) +
GetPotentialEnclosingMargins(children.AsEnumerable().Reverse().ToList());
}
private float GetPotentialEnclosingMargins(List<ISpatialData> children)
{
var uiRect = uiRectHelper.zero;
var i = 0;
for (; i < minEntries; i++) uiRect = uiRect.expandToInclude(children[i].bounds);
var totalMargin = uiRect.margin;
for (; i < children.Count - minEntries; i++)
{
uiRect = uiRect.expandToInclude(children[i].bounds);
totalMargin += uiRect.margin;
}
return totalMargin;
}
#endregion
private int GetBestSplitIndex(List<ISpatialData> children)
{
return Enumerable.Range(minEntries, children.Count - minEntries)
.Select(i =>
{
var leftRect = GetEnclosingRect(children.Take(i));
var rightRect = GetEnclosingRect(children.Skip(i));
var overlap = leftRect.intersect(rightRect).area;
var totalArea = leftRect.area + rightRect.area;
return new {i, overlap, totalArea};
})
.OrderBy(x => x.overlap)
.ThenBy(x => x.totalArea)
.Select(x => x.i)
.First();
}
#endregion
#endregion
#region BuildTree
private RTreeNode BuildTree(List<ISpatialData> data)
{
var treeHeight = GetDepth(data.Count);
var rootMaxEntries = (int) Math.Ceiling(data.Count / Math.Pow(maxEntries, treeHeight - 1));
return BuildNodes(data, 0, data.Count - 1, treeHeight, rootMaxEntries);
}
private int GetDepth(int numNodes)
{
return (int) Math.Ceiling(Math.Log(numNodes) / Math.Log(maxEntries));
}
private RTreeNode BuildNodes(List<ISpatialData> data, int left, int right, int height, int maxEntries)
{
var num = right - left + 1;
if (num <= maxEntries)
return height == 1
? new RTreeNode(data.GetRange(left, num), height)
: new RTreeNode(
new List<ISpatialData>
{
BuildNodes(data, left, right, height - 1, this.maxEntries)
},
height);
data.Sort(left, num, CompareMinX);
var nodeSize = (num + (maxEntries - 1)) / maxEntries;
var subSortLength = nodeSize * (int) Math.Ceiling(Math.Sqrt(maxEntries));
var children = new List<ISpatialData>(maxEntries);
for (var subCounter = left; subCounter <= right; subCounter += subSortLength)
{
var subRight = Math.Min(subCounter + subSortLength - 1, right);
data.Sort(subCounter, subRight - subCounter + 1, CompareMinY);
for (var nodeCounter = subCounter; nodeCounter <= subRight; nodeCounter += nodeSize)
children.Add(
BuildNodes(
data,
nodeCounter,
Math.Min(nodeCounter + nodeSize - 1, subRight),
height - 1,
this.maxEntries));
}
return new RTreeNode(children, height);
}
#endregion
private const int DefaultMaxEntries = 9;
private const int MinimumMaxEntries = 4;
private const int MinimumMinEntries = 2;
private const float DefaultFillFactor = 0.4f;
private readonly EqualityComparer<T> comparer;
private readonly int maxEntries;
private readonly int minEntries;
public RTree() : this(DefaultMaxEntries)
{
}
public RTree(int maxEntries)
: this(maxEntries, EqualityComparer<T>.Default)
{
}
public RTree(int maxEntries, EqualityComparer<T> comparer)
{
this.comparer = comparer;
this.maxEntries = Math.Max(MinimumMaxEntries, maxEntries);
minEntries = Math.Max(MinimumMinEntries, (int) Math.Ceiling(this.maxEntries * DefaultFillFactor));
Clear();
}
public RTreeNode Root { get; private set; }
public uiRect uiRect => Root.bounds;
public int Count { get; private set; }
public void Clear()
{
Root = new RTreeNode(new List<ISpatialData>(), 1);
Count = 0;
}
public IReadOnlyList<T> Search()
{
return GetAllChildren(new List<T>(), Root);
}
public IReadOnlyList<T> Search(in uiRect boundingBox)
{
return DoSearch(boundingBox);
}
public void Insert(T item)
{
Insert(item, Root.Height);
Count++;
}
public void BulkLoad(IEnumerable<T> items)
{
var data = items.Cast<ISpatialData>().ToList();
if (data.Count == 0) return;
if (Root.IsLeaf &&
Root.children.Count + data.Count < maxEntries)
{
foreach (var i in data)
Insert((T) i);
return;
}
if (data.Count < minEntries)
{
foreach (var i in data)
Insert((T) i);
return;
}
var dataRoot = BuildTree(data);
Count += data.Count;
if (Root.children.Count == 0)
{
Root = dataRoot;
}
else if (Root.Height == dataRoot.Height)
{
if (Root.children.Count + dataRoot.children.Count <= maxEntries)
foreach (var isd in dataRoot.children)
Root.Add(isd);
else
SplitRoot(dataRoot);
}
else
{
if (Root.Height < dataRoot.Height)
{
var tmp = Root;
Root = dataRoot;
dataRoot = tmp;
}
Insert(dataRoot, Root.Height - dataRoot.Height);
}
}
}
}

11
Runtime/external/RTree.cs.meta


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

493
Runtime/external/SplayTree.cs


using System;
using System.Collections;
using System.Collections.Generic;
namespace Unity.UIWidgets.Runtime.external
{ class SplayTree<TKey, TValue> : IDictionary<TKey, TValue> where TKey : IComparable<TKey> {
SplayTreeNode root;
int count;
int version = 0;
public void Add(TKey key, TValue value) {
this.Set(key, value, throwOnExisting: true);
}
public void Add(KeyValuePair<TKey, TValue> item) {
this.Set(item.Key, item.Value, throwOnExisting: true);
}
public void AddAll(IEnumerable<TKey> list) {
foreach (var key in list) {
this.Add(new KeyValuePair<TKey, TValue>(key, default));
}
}
void Set(TKey key, TValue value, bool throwOnExisting) {
if (this.count == 0) {
this.version++;
this.root = new SplayTreeNode(key, value);
this.count = 1;
return;
}
this.Splay(key);
var c = key.CompareTo(this.root.Key);
if (c == 0) {
if (throwOnExisting) {
throw new ArgumentException("An item with the same key already exists in the tree.");
}
this.version++;
this.root.Value = value;
return;
}
var n = new SplayTreeNode(key, value);
if (c < 0) {
n.LeftChild = this.root.LeftChild;
n.RightChild = this.root;
this.root.LeftChild = null;
}
else {
n.RightChild = this.root.RightChild;
n.LeftChild = this.root;
this.root.RightChild = null;
}
this.root = n;
this.count++;
this.Splay(key);
this.version++;
}
public void Clear() {
this.root = null;
this.count = 0;
this.version++;
}
public bool ContainsKey(TKey key) {
if (this.count == 0) {
return false;
}
this.Splay(key);
return key.CompareTo(this.root.Key) == 0;
}
public bool Contains(KeyValuePair<TKey, TValue> item) {
if (this.count == 0) {
return false;
}
this.Splay(item.Key);
return item.Key.CompareTo(this.root.Key) == 0 &&
(ReferenceEquals(this.root.Value, item.Value) ||
(!ReferenceEquals(item.Value, null) && item.Value.Equals(this.root.Value)));
}
public KeyValuePair<TKey, TValue>? First() {
SplayTreeNode t = this.root;
if (t == null) {
return null;
}
while (t.LeftChild != null) {
t = t.LeftChild;
}
return new KeyValuePair<TKey, TValue>(t.Key, t.Value);
}
public KeyValuePair<TKey, TValue> FirstOrDefault() {
SplayTreeNode t = this.root;
if (t == null) {
return new KeyValuePair<TKey, TValue>(default(TKey), default(TValue));
}
while (t.LeftChild != null) {
t = t.LeftChild;
}
return new KeyValuePair<TKey, TValue>(t.Key, t.Value);
}
public KeyValuePair<TKey, TValue>? Last() {
SplayTreeNode t = this.root;
if (t == null) {
return null;
}
while (t.RightChild != null) {
t = t.RightChild;
}
return new KeyValuePair<TKey, TValue>(t.Key, t.Value);
}
public KeyValuePair<TKey, TValue> LastOrDefault() {
SplayTreeNode t = this.root;
if (t == null) {
return new KeyValuePair<TKey, TValue>(default(TKey), default(TValue));
}
while (t.RightChild != null) {
t = t.RightChild;
}
return new KeyValuePair<TKey, TValue>(t.Key, t.Value);
}
void Splay(TKey key) {
SplayTreeNode l, r, t, y, header;
l = r = header = new SplayTreeNode(default(TKey), default(TValue));
t = this.root;
while (true) {
var c = key.CompareTo(t.Key);
if (c < 0) {
if (t.LeftChild == null) {
break;
}
if (key.CompareTo(t.LeftChild.Key) < 0) {
y = t.LeftChild;
t.LeftChild = y.RightChild;
y.RightChild = t;
t = y;
if (t.LeftChild == null) {
break;
}
}
r.LeftChild = t;
r = t;
t = t.LeftChild;
}
else if (c > 0) {
if (t.RightChild == null) {
break;
}
if (key.CompareTo(t.RightChild.Key) > 0) {
y = t.RightChild;
t.RightChild = y.LeftChild;
y.LeftChild = t;
t = y;
if (t.RightChild == null) {
break;
}
}
l.RightChild = t;
l = t;
t = t.RightChild;
}
else {
break;
}
}
l.RightChild = t.LeftChild;
r.LeftChild = t.RightChild;
t.LeftChild = header.RightChild;
t.RightChild = header.LeftChild;
this.root = t;
}
public bool Remove(TKey key) {
if (this.count == 0) {
return false;
}
this.Splay(key);
if (key.CompareTo(this.root.Key) != 0) {
return false;
}
if (this.root.LeftChild == null) {
this.root = this.root.RightChild;
}
else {
var swap = this.root.RightChild;
this.root = this.root.LeftChild;
this.Splay(key);
this.root.RightChild = swap;
}
this.version++;
this.count--;
return true;
}
public bool TryGetValue(TKey key, out TValue value) {
if (this.count == 0) {
value = default(TValue);
return false;
}
this.Splay(key);
if (key.CompareTo(this.root.Key) != 0) {
value = default(TValue);
return false;
}
value = this.root.Value;
return true;
}
public TValue this[TKey key] {
get {
if (this.count == 0) {
throw new KeyNotFoundException("The key was not found in the tree.");
}
this.Splay(key);
if (key.CompareTo(this.root.Key) != 0) {
throw new KeyNotFoundException("The key was not found in the tree.");
}
return this.root.Value;
}
set { this.Set(key, value, throwOnExisting: false); }
}
public int Count {
get { return this.count; }
}
public bool IsReadOnly {
get { return false; }
}
public bool Remove(KeyValuePair<TKey, TValue> item) {
if (this.count == 0) {
return false;
}
this.Splay(item.Key);
if (item.Key.CompareTo(this.root.Key) == 0 && (ReferenceEquals(this.root.Value, item.Value) ||
(!ReferenceEquals(item.Value, null) &&
item.Value.Equals(this.root.Value)))) {
return false;
}
if (this.root.LeftChild == null) {
this.root = this.root.RightChild;
}
else {
var swap = this.root.RightChild;
this.root = this.root.LeftChild;
this.Splay(item.Key);
this.root.RightChild = swap;
}
this.version++;
this.count--;
return true;
}
public void Trim(int depth) {
if (depth < 0) {
throw new ArgumentOutOfRangeException("depth", "The trim depth must not be negative.");
}
if (this.count == 0) {
return;
}
if (depth == 0) {
this.Clear();
}
else {
var prevCount = this.count;
this.count = this.Trim(this.root, depth - 1);
if (prevCount != this.count) {
this.version++;
}
}
}
int Trim(SplayTreeNode node, int depth) {
if (depth == 0) {
node.LeftChild = null;
node.RightChild = null;
return 1;
}
else {
int count = 1;
if (node.LeftChild != null) {
count += this.Trim(node.LeftChild, depth - 1);
}
if (node.RightChild != null) {
count += this.Trim(node.RightChild, depth - 1);
}
return count;
}
}
public ICollection<TKey> Keys {
get { return new TiedList<TKey>(this, this.version, this.AsList(node => node.Key)); }
}
public ICollection<TValue> Values {
get { return new TiedList<TValue>(this, this.version, this.AsList(node => node.Value)); }
}
public void CopyTo(KeyValuePair<TKey, TValue>[] array, int arrayIndex) {
this.AsList(node => new KeyValuePair<TKey, TValue>(node.Key, node.Value)).CopyTo(array, arrayIndex);
}
public IEnumerator<KeyValuePair<TKey, TValue>> GetEnumerator() {
return new TiedList<KeyValuePair<TKey, TValue>>(this, this.version,
this.AsList(node => new KeyValuePair<TKey, TValue>(node.Key, node.Value))).GetEnumerator();
}
IList<TEnumerator> AsList<TEnumerator>(Func<SplayTreeNode, TEnumerator> selector) {
if (this.root == null) {
return new TEnumerator[0];
}
var result = new List<TEnumerator>(this.count);
this.PopulateList(this.root, result, selector);
return result;
}
void PopulateList<TEnumerator>(SplayTreeNode node, List<TEnumerator> list,
Func<SplayTreeNode, TEnumerator> selector) {
if (node.LeftChild != null) {
this.PopulateList(node.LeftChild, list, selector);
}
list.Add(selector(node));
if (node.RightChild != null) {
this.PopulateList(node.RightChild, list, selector);
}
}
IEnumerator IEnumerable.GetEnumerator() {
return this.GetEnumerator();
}
sealed class SplayTreeNode {
public readonly TKey Key;
public TValue Value;
public SplayTreeNode LeftChild;
public SplayTreeNode RightChild;
public SplayTreeNode(TKey key, TValue value) {
this.Key = key;
this.Value = value;
}
}
sealed class TiedList<T> : IList<T> {
readonly SplayTree<TKey, TValue> tree;
readonly int version;
readonly IList<T> backingList;
public TiedList(SplayTree<TKey, TValue> tree, int version, IList<T> backingList) {
if (tree == null) {
throw new ArgumentNullException("tree");
}
if (backingList == null) {
throw new ArgumentNullException("backingList");
}
this.tree = tree;
this.version = version;
this.backingList = backingList;
}
public int IndexOf(T item) {
if (this.tree.version != this.version) {
throw new InvalidOperationException("The collection has been modified.");
}
return this.backingList.IndexOf(item);
}
public void Insert(int index, T item) {
throw new NotSupportedException();
}
public void RemoveAt(int index) {
throw new NotSupportedException();
}
public T this[int index] {
get {
if (this.tree.version != this.version) {
throw new InvalidOperationException("The collection has been modified.");
}
return this.backingList[index];
}
set { throw new NotSupportedException(); }
}
public void Add(T item) {
throw new NotSupportedException();
}
public void Clear() {
throw new NotSupportedException();
}
public bool Contains(T item) {
if (this.tree.version != this.version) {
throw new InvalidOperationException("The collection has been modified.");
}
return this.backingList.Contains(item);
}
public void CopyTo(T[] array, int arrayIndex) {
if (this.tree.version != this.version) {
throw new InvalidOperationException("The collection has been modified.");
}
this.backingList.CopyTo(array, arrayIndex);
}
public int Count {
get { return this.tree.count; }
}
public bool IsReadOnly {
get { return true; }
}
public bool Remove(T item) {
throw new NotSupportedException();
}
public IEnumerator<T> GetEnumerator() {
if (this.tree.version != this.version) {
throw new InvalidOperationException("The collection has been modified.");
}
foreach (var item in this.backingList) {
yield return item;
if (this.tree.version != this.version) {
throw new InvalidOperationException("The collection has been modified.");
}
}
}
IEnumerator IEnumerable.GetEnumerator() {
return this.GetEnumerator();
}
}
}
}

11
Runtime/external/SplayTree.cs.meta


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

284
Runtime/material/search.cs


using System;
using System.Collections.Generic;
using RSG;
using Unity.UIWidgets.animation;
using Unity.UIWidgets.foundation;
using Unity.UIWidgets.service;
using Unity.UIWidgets.widgets;
using UnityEngine;
using Color = Unity.UIWidgets.ui.Color;
namespace Unity.UIWidgets.material {
public class SearchUtils {
public static IPromise<object> showSearch(
BuildContext context,
SearchDelegate del,
string query = ""
) {
D.assert(del != null);
D.assert(context != null);
del.query = query ?? del.query;
del._currentBody = _SearchBody.suggestions;
return Navigator.of(context).push(new _SearchPageRoute(
del: del
));
}
}
public abstract class SearchDelegate {
public abstract Widget buildSuggestions(BuildContext context);
public abstract Widget buildResults(BuildContext context);
public abstract Widget buildLeading(BuildContext context);
public abstract List<Widget> buildActions(BuildContext context);
public virtual ThemeData appBarTheme(BuildContext context) {
D.assert(context != null);
ThemeData theme = Theme.of(context);
D.assert(theme != null);
return theme.copyWith(
primaryColor: Colors.white,
primaryIconTheme: theme.primaryIconTheme.copyWith(color: Colors.grey),
primaryColorBrightness: Brightness.light,
primaryTextTheme: theme.textTheme
);
}
public virtual string query {
get { return this._queryTextController.text; }
set {
D.assert(this.query != null);
this._queryTextController.text = value;
}
}
public virtual void showResults(BuildContext context) {
this._focusNode.unfocus();
this._currentBody = _SearchBody.results;
}
public virtual void showSuggestions(BuildContext context) {
FocusScope.of(context).requestFocus(this._focusNode);
this._currentBody = _SearchBody.suggestions;
}
public virtual void close(BuildContext context, object result) {
this._currentBody = null;
this._focusNode.unfocus();
var state = Navigator.of(context);
state.popUntil((Route route) => route == this._route);
state.pop(result);
}
public virtual Animation<float> transitionAnimation {
get { return this._proxyAnimation; }
}
readonly internal FocusNode _focusNode = new FocusNode();
readonly internal TextEditingController _queryTextController = new TextEditingController();
readonly internal ProxyAnimation _proxyAnimation = new ProxyAnimation(Animations.kAlwaysDismissedAnimation);
readonly internal ValueNotifier<_SearchBody?> _currentBodyNotifier = new ValueNotifier<_SearchBody?>(null);
internal _SearchBody? _currentBody {
get { return this._currentBodyNotifier.value; }
set { this._currentBodyNotifier.value = value; }
}
internal _SearchPageRoute _route;
}
enum _SearchBody {
suggestions,
results
}
class _SearchPageRoute : PageRoute {
public _SearchPageRoute(SearchDelegate del) {
D.assert(del != null);
D.assert(del._route == null,
() => $"The {this.del.GetType()} instance is currently used by another active " +
"search. Please close that search by calling close() on the SearchDelegate " +
"before openening another search with the same delegate instance."
);
this.del = del;
this.del._route = this;
}
public readonly SearchDelegate del;
public override Color barrierColor {
get { return null; }
}
public override TimeSpan transitionDuration {
get { return new TimeSpan(0, 0, 0, 0, 300); }
}
public override bool maintainState {
get { return false; }
}
public override Widget buildTransitions(
BuildContext context,
Animation<float> animation,
Animation<float> secondaryAnimation,
Widget child
) {
return new FadeTransition(
opacity: animation,
child: child
);
}
public override Animation<float> createAnimation() {
Animation<float> animation = base.createAnimation();
this.del._proxyAnimation.parent = animation;
return animation;
}
public override Widget buildPage(
BuildContext context,
Animation<float> animation,
Animation<float> secondaryAnimation
) {
return new _SearchPage(
del: this.del,
animation: animation
);
}
protected internal override void didComplete(object result) {
base.didComplete(result);
D.assert(this.del._route == this);
this.del._route = null;
this.del._currentBody = null;
}
}
class _SearchPage : StatefulWidget {
public _SearchPage(
SearchDelegate del,
Animation<float> animation
) {
this.del = del;
this.animation = animation;
}
public readonly SearchDelegate del;
public readonly Animation<float> animation;
public override State createState() {
return new _SearchPageState();
}
}
class _SearchPageState : State<_SearchPage> {
public override void initState() {
base.initState();
this.queryTextController.addListener(this._onQueryChanged);
this.widget.animation.addStatusListener(this._onAnimationStatusChanged);
this.widget.del._currentBodyNotifier.addListener(this._onSearchBodyChanged);
this.widget.del._focusNode.addListener(this._onFocusChanged);
}
public override void dispose() {
base.dispose();
this.queryTextController.removeListener(this._onQueryChanged);
this.widget.animation.removeStatusListener(this._onAnimationStatusChanged);
this.widget.del._currentBodyNotifier.removeListener(this._onSearchBodyChanged);
this.widget.del._focusNode.removeListener(this._onFocusChanged);
}
void _onAnimationStatusChanged(AnimationStatus status) {
if (status != AnimationStatus.completed) {
return;
}
this.widget.animation.removeStatusListener(this._onAnimationStatusChanged);
if (this.widget.del._currentBody == _SearchBody.suggestions) {
FocusScope.of(this.context).requestFocus(this.widget.del._focusNode);
}
}
void _onFocusChanged() {
if (this.widget.del._focusNode.hasFocus && this.widget.del._currentBody != _SearchBody.suggestions) {
this.widget.del.showSuggestions(this.context);
}
}
void _onQueryChanged() {
this.setState(() => { });
}
void _onSearchBodyChanged() {
this.setState(() => { });
}
public override Widget build(BuildContext context) {
MaterialD.debugCheckHasMaterialLocalizations(context);
ThemeData theme = this.widget.del.appBarTheme(context);
string searchFieldLabel = MaterialLocalizations.of(context).searchFieldLabel;
Widget body = null;
switch (this.widget.del._currentBody) {
case _SearchBody.suggestions:
body = new KeyedSubtree(
key: new ValueKey<_SearchBody>(_SearchBody.suggestions),
child: this.widget.del.buildSuggestions(context)
);
break;
case _SearchBody.results:
body = new KeyedSubtree(
key: new ValueKey<_SearchBody>(_SearchBody.results),
child: this.widget.del.buildResults(context)
);
break;
}
string routeName;
switch (Theme.of(this.context).platform) {
case RuntimePlatform.IPhonePlayer:
routeName = "";
break;
case RuntimePlatform.Android:
routeName = searchFieldLabel;
break;
}
return new Scaffold(
appBar: new AppBar(
backgroundColor: theme.primaryColor,
iconTheme: theme.primaryIconTheme,
textTheme: theme.primaryTextTheme,
brightness: theme.primaryColorBrightness,
leading: this.widget.del.buildLeading(context),
title: new TextField(
controller: this.queryTextController,
focusNode: this.widget.del._focusNode,
style: theme.textTheme.title,
textInputAction: TextInputAction.search,
onSubmitted: (string _) => { this.widget.del.showResults(context); },
decoration: new InputDecoration(
border: InputBorder.none,
hintText: searchFieldLabel
)
),
actions: this.widget.del.buildActions(context)
),
body: new AnimatedSwitcher(
duration: new TimeSpan(0, 0, 0, 0, 300),
child: body
)
);
}
TextEditingController queryTextController {
get { return this.widget.del._queryTextController; }
}
}
}

11
Runtime/material/search.cs.meta


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