浏览代码

Merge branch 'master' of github.com:UnityTech/UIWidgets

/main
xingwei.zhu 6 年前
当前提交
f9c0307f
共有 18 个文件被更改,包括 323 次插入150 次删除
  1. 9
      README-ZH.md
  2. 7
      README.md
  3. 22
      Runtime/editor/editor_window.cs
  4. 2
      Runtime/material/bottom_navigation_bar.cs
  5. 18
      Runtime/material/text_field.cs
  6. 6
      Runtime/material/text_theme.cs
  7. 18
      Runtime/material/theme_data.cs
  8. 3
      Runtime/material/tooltip.cs
  9. 2
      Runtime/painting/image_cache.cs
  10. 15
      Runtime/painting/text_span.cs
  11. 165
      Runtime/rendering/editable.cs
  12. 24
      Runtime/ui/painting/path.cs
  13. 63
      Runtime/ui/text.cs
  14. 27
      Runtime/ui/txt/wordbreaker.cs
  15. 46
      Runtime/ui/window.cs
  16. 8
      Runtime/widgets/automatic_keep_alive.cs
  17. 16
      Runtime/widgets/ticker_provider.cs
  18. 22
      Samples/UIWidgetsGallery/demo/shrine/shrine_types.cs

9
README-ZH.md


namespace UIWidgetsSample {
public class UIWidgetsExample : UIWidgetsPanel {
protected override void OnEnable() {
// Application.targetFrameRate = 60; // or higher if you want a smoother scrolling experience.
// if you want to use your own font or font icons.
// FontManager.instance.addFont(Resources.Load<Font>(path: "path to your font"), "font family name");

当一个Unity项目运行在Android设备上时,状态栏是默认隐藏且无法在编辑内进行调整的。
如果您希望在您的UIWidgets App中显示状态栏,您可以使用这个[解决方案](https://github.com/Over17/UnityShowAndroidStatusBar)。我们将尽快推出我们自己的解决方案,并保证届时开发者可以进行无缝切换。
#### 七、自动调节帧率
如果要使得构建出的应用能够自动调节帧率,请打开Project Settings,将构建目标平台对应的Quality选项卡中的V Sync Count设置为Don't Sync。
默认的逻辑是在界面静止时将帧率降低为15,在界面变动时将帧率提高至60。
如果您需要修改帧率升高或降低时的行为,请将`Window.onFrameRateSpeedUp`和/或`Window.onFrameRateCoolDown`设置为您自己的函数。
## 调试UIWidgets应用程序

#### Wiki
目前开发团队仍在改进UIWidgets Wiki。 由于UIWidgets主要来源于Flutter,你也可以参考Flutter Wiki中与UIWidgets API对应部分的详细描述。同时,你可以加入我们的讨论组(https://connect.unity.com/g/uiwidgets)。
目前开发团队仍在改进UIWidgets Wiki。 由于UIWidgets主要来源于Flutter,你也可以参考Flutter Wiki中与UIWidgets API对应部分的详细描述。同时,你可以加入我们的讨论组( https://connect.unity.com/g/uiwidgets )。
#### 常问问题解答

7
README.md


namespace UIWidgetsSample {
public class UIWidgetsExample : UIWidgetsPanel {
protected override void OnEnable() {
// Application.targetFrameRate = 60; // or higher if you want a smoother scrolling experience.
// if you want to use your own font or font icons.
// FontManager.instance.addFont(Resources.Load<Font>(path: "path to your font"), "font family name");

compatible to UIWidgets, therefore can be used as a good option before we release our
full support solution on this issue.
#### Automatically Adjust Frame Rate
To build an App that is able to adjust the frame rate automatically, please open Project Settings, and in the Quality tab, set the "V Sync Count" option of the target platform to "Don't Sync".
The default logic is to set the frame rate to 15 when the screen is static, and change the frame rate to 60 whenever the screen changes.
If you would like to modify the behavior of speeding up or cooling down the frame rate, please set `Window.onFrameRateSpeedUp` and/or `Window.onFrameRateCoolDown` to your own functions.
## Debug UIWidgets Application

22
Runtime/editor/editor_window.cs


protected override float queryDevicePixelRatio() {
return EditorGUIUtility.pixelsPerPoint;
}
return Window.defaultAntiAliasing;
return defaultAntiAliasing;
}
protected override Vector2 queryWindowSize() {

public void OnEnable() {
this._devicePixelRatio = this.queryDevicePixelRatio();
this._antiAliasing = this.queryAntiAliasing();
var size = this.queryWindowSize();
this._lastWindowWidth = size.x;
this._lastWindowHeight = size.y;

if (this.displayMetricsChanged()) {
this._devicePixelRatio = this.queryDevicePixelRatio();
this._antiAliasing = this.queryAntiAliasing();
var size = this.queryWindowSize();
this._lastWindowWidth = size.x;
this._lastWindowHeight = size.y;

this.flushMicrotasks();
}
}
static readonly TimeSpan _coolDownDelay = new TimeSpan(0, 0, 0, 0, 200);
static Timer frameCoolDownTimer;
onFrameRateSpeedUp();
frameCoolDownTimer?.cancel();
frameCoolDownTimer = instance.run(
_coolDownDelay,
() => {
onFrameRateCoolDown();
frameCoolDownTimer = null;
});
}
public override void render(Scene scene) {

2
Runtime/material/bottom_navigation_bar.cs


color: this.colorTween.evaluate(this.animation)
),
child: new Transform(
transform: Matrix3.makeAll(t, 0, 0, 0, t, 0, 0, 0, t),
transform: Matrix3.makeScale(t),
alignment: Alignment.bottomCenter,
child: this.item.title
)

18
Runtime/material/text_field.cs


using System;
using System.Collections.Generic;
using Unity.UIWidgets.foundation;
using Unity.UIWidgets.gestures;

namespace Unity.UIWidgets.material {
public class TextField : StatefulWidget {
public TextField(Key key = null, TextEditingController controller = null, FocusNode focusNode = null,
InputDecoration decoration = null, bool noDecoration = false, TextInputType keyboardType = null,
TextInputAction? textInputAction = null,

public readonly VoidCallback onEditingComplete;
public readonly ValueChanged<String> onSubmitted;
public readonly ValueChanged<string> onSubmitted;
public readonly List<TextInputFormatter> inputFormatters;

ifTrue: "max length enforced"));
properties.add(new DiagnosticsProperty<GestureTapCallback>("onTap", this.onTap, defaultValue: null));
}
readonly GlobalKey<EditableTextState> _editableTextKey = new LabeledGlobalKey<EditableTextState>();
HashSet<InteractiveInkFeature> _splashes;

if (this._splashes != null) {
D.assert(this._splashes.Contains(splash));
this._splashes.Remove(splash);
if (this._currentSplash == splash) this._currentSplash = null;
if (this._currentSplash == splash) {
this._currentSplash = null;
}
this.updateKeepAlive();
} // else we're probably in deactivate()
}

}
RenderEditable _renderEditable {
get {
return this._editableTextKey.currentState.renderEditable;
}
}
get { return this._editableTextKey.currentState.renderEditable; }
}
void _handleTapDown(TapDownDetails details) {
this._renderEditable.handleTapDown(details);

child: child
)
);
}
}
}

6
Runtime/material/text_theme.cs


return !Equals(left, right);
}
int? _cachedHashCode = null;
if (this._cachedHashCode != null) {
return this._cachedHashCode.Value;
}
unchecked {
var hashCode = this.display4.GetHashCode();
hashCode = (hashCode * 397) ^ this.display3.GetHashCode();

hashCode = (hashCode * 397) ^ this.button.GetHashCode();
hashCode = (hashCode * 397) ^ this.subtitle.GetHashCode();
hashCode = (hashCode * 397) ^ this.overline.GetHashCode();
this._cachedHashCode = hashCode;
return hashCode;
}
}

18
Runtime/material/theme_data.cs


return !Equals(left, right);
}
int? _cachedHashCode = null;
if (this._cachedHashCode != null) {
return this._cachedHashCode.Value;
}
unchecked {
var hashCode = this.brightness.GetHashCode();
hashCode = (hashCode * 397) ^ this.primaryColor.GetHashCode();

hashCode = (hashCode * 397) ^ this.colorScheme.GetHashCode();
hashCode = (hashCode * 397) ^ this.dialogTheme.GetHashCode();
hashCode = (hashCode * 397) ^ this.typography.GetHashCode();
this._cachedHashCode = hashCode;
return hashCode;
}
}

return true;
}
return this.baseTheme == other.baseTheme &&
this.localTextGeometry == other.localTextGeometry;
return ReferenceEquals(this.baseTheme, other.baseTheme) &&
ReferenceEquals(this.localTextGeometry, other.localTextGeometry);
}
public override bool Equals(object obj) {

public V putIfAbsent(K key, Func<V> value) {
D.assert(key != null);
D.assert(value != null);
if (this._cache.ContainsKey(key)) {
return this._cache[key];
V get_value;
if (this._cache.TryGetValue(key, out get_value)) {
return get_value;
}
if (this._cache.Count == this._maximumSize) {

3
Runtime/material/tooltip.cs


void _handleLongPress() {
bool tooltipCreated = this.ensureTooltipVisible();
if (tooltipCreated)
if (tooltipCreated) {
}
}

2
Runtime/painting/image_cache.cs


D.assert(this._pendingImages.ContainsKey(key));
this._pendingImages.Remove(key);
int imageSize = info?.image == null ? 0 : info.image.width & (info.image.height * 4);
int imageSize = info?.image == null ? 0 : info.image.width * info.image.height * 4;
_CachedImage cachedImage = new _CachedImage {
completer = result,
sizeBytes = imageSize,

15
Runtime/painting/text_span.cs


public readonly List<TextSpan> children;
public readonly GestureRecognizer recognizer;
public TextSpan(string text = "", TextStyle style = null, List<TextSpan> children = null,
public TextSpan(string text = "", TextStyle style = null, List<TextSpan> children = null,
GestureRecognizer recognizer = null) {
this.text = text;
this.style = style;

});
return result;
}
public string toPlainText() {
var sb = new StringBuilder();
this.visitTextSpan((span) => {

if (!this.visitTextSpan(span => {
if (span.children != null) {
foreach (TextSpan child in span.children) {
if (child == null)
if (child == null) {
}
"The full text in question was:\n" +
this.toStringDeep(prefixLineOne:" "));
"The full text in question was:\n" +
this.toStringDeep(prefixLineOne: " "));
public RenderComparison compareTo(TextSpan other) {
if (this.Equals(other)) {
return RenderComparison.identical;

165
Runtime/rendering/editable.cs


int _previousCursorLocation;
bool _resetCursor = false;
void _handleKeyEvent(RawKeyEvent keyEvent) {
if (keyEvent is RawKeyUpEvent) {
return;

this._extentOffset = this.selection.extentOffset;
this._baseOffset = this.selection.baseOffset;
}
bool shift = (modifiers & (int)EventModifiers.Shift) > 0;
bool ctrl = (modifiers & (int)EventModifiers.Control) > 0;
bool alt = (modifiers & (int)EventModifiers.Alt) > 0;
bool cmd = (modifiers & (int)EventModifiers.Command) > 0;
bool shift = (modifiers & (int) EventModifiers.Shift) > 0;
bool ctrl = (modifiers & (int) EventModifiers.Control) > 0;
bool alt = (modifiers & (int) EventModifiers.Alt) > 0;
bool cmd = (modifiers & (int) EventModifiers.Command) > 0;
bool rightArrow = pressedKeyCode == KeyCode.RightArrow;
bool leftArrow = pressedKeyCode == KeyCode.LeftArrow;
bool upArrow = pressedKeyCode == KeyCode.UpArrow;

bool del = pressedKeyCode == KeyCode.Delete;
bool isMac = SystemInfo.operatingSystemFamily == OperatingSystemFamily.MacOSX;
if (keyEvent is RawKeyCommandEvent) { // editor case
this._handleShortcuts(((RawKeyCommandEvent)keyEvent).command);
if (keyEvent is RawKeyCommandEvent) {
// editor case
this._handleShortcuts(((RawKeyCommandEvent) keyEvent).command);
if ((ctrl || (isMac && cmd)) && (xKey || vKey || cKey || aKey)) { // runtime case
if ((ctrl || (isMac && cmd)) && (xKey || vKey || cKey || aKey)) {
// runtime case
} else if (aKey) {
}
else if (aKey) {
} else if (vKey) {
}
else if (vKey) {
} else if (cKey) {
}
else if (cKey) {
if (arrow) {
int newOffset = this._extentOffset;
var word = (isMac && alt) || ctrl;

if (downArrow || upArrow)
if (downArrow || upArrow) {
}
newOffset = this._handleShift(rightArrow, leftArrow, shift, newOffset);
this._extentOffset = newOffset;

// If control is pressed, we will decide which way to look for a word
// based on which arrow is pressed.
if (leftArrow && this._extentOffset > 2) {
TextSelection textSelection = this._selectWordAtOffset(new TextPosition(offset: this._extentOffset - 2));
TextSelection textSelection =
this._selectWordAtOffset(new TextPosition(offset: this._extentOffset - 2));
} else if (rightArrow && this._extentOffset < this.text.text.Length - 2) {
TextSelection textSelection = this._selectWordAtOffset(new TextPosition(offset: this._extentOffset + 1));
}
else if (rightArrow && this._extentOffset < this.text.text.Length - 2) {
TextSelection textSelection =
this._selectWordAtOffset(new TextPosition(offset: this._extentOffset + 1));
int _handleHorizontalArrows(bool rightArrow, bool leftArrow, bool shift, int newOffset) {
if (rightArrow && this._extentOffset < this.text.text.Length) {
newOffset += 1;

}
if (leftArrow && this._extentOffset > 0) {
newOffset -= 1;
if (shift) {

Offset caretOffset = this._textPainter.getOffsetForCaret(new TextPosition(offset: this._extentOffset), this._caretPrototype);
Offset caretOffset =
this._textPainter.getOffsetForCaret(new TextPosition(offset: this._extentOffset), this._caretPrototype);
if (downArrow)
if (downArrow) {
else if (upArrow)
}
else if (upArrow) {
}
} else if (this._resetCursor && shift) {
}
else if (this._resetCursor && shift) {
} else {
}
else {
if (this.onSelectionChanged == null)
if (this.onSelectionChanged == null) {
}
if (shift) {
if (this._baseOffset < newOffset) {
this.onSelectionChanged(

this,
SelectionChangedCause.keyboard
);
} else {
}
else {
this.onSelectionChanged(
new TextSelection(
baseOffset: newOffset,

SelectionChangedCause.keyboard
);
}
} else {
}
else {
if (leftArrow)
if (leftArrow) {
else if (rightArrow)
}
else if (rightArrow) {
}
}
this.onSelectionChanged(

SelectionChangedCause.keyboard
);
}
return newOffset;
}

Clipboard.setData(
new ClipboardData(text: this.selection.textInside(this.text.text)));
}
break;
case KeyCommand.Cut:
if (!this.selection.isCollapsed) {

selection: TextSelection.collapsed(offset: this.selection.start)
);
}
break;
case KeyCommand.Paste:
TextEditingValue value = this.textSelectionDelegate.textEditingValue;

);
}
});
break;
case KeyCommand.SelectAll:
this._baseOffset = 0;

+ selection.textAfter(this.text.text).Substring(1),
selection: TextSelection.collapsed(offset: selection.start)
);
} else {
}
else {
this.textSelectionDelegate.textEditingValue = new TextEditingValue(
text: selection.textBefore(this.text.text),
selection: TextSelection.collapsed(offset: selection.start)

this._textLayoutLastWidth = null;
this.markNeedsLayout();
}
public TextSpan text {
get { return this._textPainter.text; }
set {

bool _hasFocus;
bool _listenerAttached = false;
public bool hasFocus {
get { return this._hasFocus; }
set {

RawKeyboard.instance.removeListener(this._handleKeyEvent);
this._listenerAttached = false;
}
this.markNeedsSemanticsUpdate();
}
}

this.markNeedsLayout();
}
}
set {
if (this._cursorWidth == value)
set {
if (this._cursorWidth == value) {
}
set {
if (this._cursorRadius == value)
set {
if (this._cursorRadius == value) {
}
set {
if (this._enableInteractiveSelection == value)
set {
if (this._enableInteractiveSelection == value) {
}
this._enableInteractiveSelection = value;
this.markNeedsTextLayout();
this.markNeedsSemanticsUpdate();

if (this._listenerAttached) {
RawKeyboard.instance.removeListener(this._handleKeyEvent);
}
base.detach();
}

this._longPress.addPointer((PointerDownEvent) evt);
}
}
this._lastTapDownPosition = details.globalPosition + - this._paintOffset;
this._lastTapDownPosition = details.globalPosition + -this._paintOffset;
public void handleTap() {
this.selectPosition(cause: SelectionChangedCause.tap);
}

D.assert(!this.ignorePointer);
this.handleDoubleTap(details);
}
public void handleDoubleTap(DoubleTapDetails details) {
// need set _lastTapDownPosition, otherwise it would be last single tap position
this._lastTapDownPosition = details.firstGlobalPosition - this._paintOffset;

public void handleLongPress() {
this.selectWord(cause: SelectionChangedCause.longPress);
}
TextPosition position = this._textPainter.getPositionForOffset(this.globalToLocal(this._lastTapDownPosition));
TextPosition position =
this._textPainter.getPositionForOffset(this.globalToLocal(this._lastTapDownPosition));
void selectWord(SelectionChangedCause? cause = null) {
this._layoutText(this.constraints.maxWidth);
D.assert(this._lastTapDownPosition != null);

this._layoutText(this.constraints.maxWidth);
D.assert(this._lastTapDownPosition != null);
if (this.onSelectionChanged != null) {
TextPosition position = this._textPainter.getPositionForOffset(this.globalToLocal(this._lastTapDownPosition));
TextPosition position =
this._textPainter.getPositionForOffset(this.globalToLocal(this._lastTapDownPosition));
TextRange word = this._textPainter.getWordBoundary(position);
if (position.offset - word.start <= 1) {
this.onSelectionChanged(

);
} else {
}
else {
this.onSelectionChanged(
TextSelection.collapsed(offset: word.end, affinity: TextAffinity.upstream),
this,

}
}
TextSelection _selectWordAtOffset(TextPosition position) {
D.assert(this._textLayoutLastWidth == this.constraints.maxWidth);
var word = this._textPainter.getWordBoundary(position);

return new TextSelection(baseOffset: word.start, extentOffset: word.end);
}
void _layoutText(float constraintWidth) {
if (this._textLayoutLastWidth == constraintWidth) {
return;

this._textLayoutLastWidth = constraintWidth;
}
protected override void performLayout() {
this._layoutText(this.constraints.maxWidth);
this._caretPrototype = Rect.fromLTWH(0.0f, _kCaretHeightOffset, this.cursorWidth,

RRect caretRRect = RRect.fromRectAndRadius(caretRect, this.cursorRadius);
canvas.drawRRect(caretRRect, paint);
}
if (!caretRect.Equals(this._lastCaretRect)) {
this._lastCaretRect = caretRect;
if (this.onCaretChanged != null) {

public override Rect describeApproximatePaintClip(RenderObject child) {
return this._hasVisualOverflow ? Offset.zero & this.size : null;
}
public override void debugFillProperties(DiagnosticPropertiesBuilder properties) {
base.debugFillProperties(properties);
properties.add(new DiagnosticsProperty<Color>("cursorColor", this.cursorColor));

24
Runtime/ui/painting/path.cs


float dlx = dy;
float dly = -dx;
dst.Add(new Vector2(px + dlx * w, py + dly * w));
dst.Add(new Vector2(px - dlx * w, py - dly * w));
float a = i / (ncap - 1) * Mathf.PI;
float a = (float) i / (ncap - 1) * Mathf.PI;
dst.Add(new Vector2(px - dlx * ax - dx * ay, py - dly * ax - dy * ay));
dst.Add(new Vector2(px - dlx * ax + dx * ay, py - dly * ax + dy * ay));
dst.Add(new Vector2(px + dlx * w, py + dly * w));
dst.Add(new Vector2(px - dlx * w, py - dly * w));
}
public static void roundCapEnd(this List<Vector3> dst, PathPoint p,

float dlx = dy;
float dly = -dx;
dst.Add(new Vector2(px + dlx * w, py + dly * w));
dst.Add(new Vector2(px - dlx * w, py - dly * w));
float a = i / (ncap - 1) * Mathf.PI;
float a = (float) i / (ncap - 1) * Mathf.PI;
dst.Add(new Vector2(px - dlx * ax - dx * ay, py - dly * ax - dy * ay));
dst.Add(new Vector2(px - dlx * ax + dx * ay, py - dly * ax + dy * ay));
dst.Add(new Vector2(px + dlx * w, py + dly * w));
dst.Add(new Vector2(px - dlx * w, py - dly * w));
}
public static void chooseBevel(bool bevel, PathPoint p0, PathPoint p1, float w,

var n = Mathf.CeilToInt((a0 - a1) / Mathf.PI * ncap).clamp(2, ncap);
for (var i = 0; i < n; i++) {
float u = i / (n - 1);
float u = (float) i / (n - 1);
float a = a0 + u * (a1 - a0);
float rx = p1.x + Mathf.Cos(a) * rw;
float ry = p1.y + Mathf.Sin(a) * rw;

var n = Mathf.CeilToInt((a1 - a0) / Mathf.PI * ncap).clamp(2, ncap);
for (var i = 0; i < n; i++) {
float u = i / (n - 1);
float u = (float) i / (n - 1);
float a = a0 + u * (a1 - a0);
float lx = p1.x + Mathf.Cos(a) * lw;
float ly = p1.y + Mathf.Sin(a) * lw;

63
Runtime/ui/text.cs


}
}
internal class TextStyle : IEquatable<TextStyle> {
class TextStyle : IEquatable<TextStyle> {
public readonly Color color = Color.fromARGB(255, 0, 0, 0);
public readonly float fontSize = 14.0f;
public readonly FontWeight fontWeight = FontWeight.w400;

public static TextStyle applyStyle(TextStyle currentStyle, painting.TextStyle style, float textScaleFactor) {
if (currentStyle != null) {
return new ui.TextStyle(
return new TextStyle(
color: style.color ?? currentStyle.color,
fontSize: style.fontSize != null ? style.fontSize * textScaleFactor : currentStyle.fontSize,
fontWeight: style.fontWeight ?? currentStyle.fontWeight,

);
}
return new ui.TextStyle(
return new TextStyle(
color: style.color,
fontSize: style.fontSize * textScaleFactor,
fontWeight: style.fontWeight,

downstream,
}
public class FontWeight: IEquatable<FontWeight> {
private FontWeight(int index) {
public class FontWeight : IEquatable<FontWeight> {
FontWeight(int index) {
public static readonly FontWeight w100 = new FontWeight(0);
public static readonly FontWeight w200 = new FontWeight(1);
public static readonly FontWeight w300 = new FontWeight(2);
public static readonly FontWeight w400 = new FontWeight(3);
public static readonly FontWeight w500 = new FontWeight(4);
public static readonly FontWeight w600 = new FontWeight(5);
public static readonly FontWeight w700 = new FontWeight(6);
public static readonly FontWeight w800 = new FontWeight(7);
public static readonly FontWeight w900 = new FontWeight(8);
public static readonly FontWeight normal = w400;
public static readonly FontWeight bold = w700;
public static readonly List<FontWeight> values = new List<FontWeight>{
public static readonly FontWeight w100 = new FontWeight(0);
public static readonly FontWeight w200 = new FontWeight(1);
public static readonly FontWeight w300 = new FontWeight(2);
public static readonly FontWeight w400 = new FontWeight(3);
public static readonly FontWeight w500 = new FontWeight(4);
public static readonly FontWeight w600 = new FontWeight(5);
public static readonly FontWeight w700 = new FontWeight(6);
public static readonly FontWeight w800 = new FontWeight(7);
public static readonly FontWeight w900 = new FontWeight(8);
public static readonly FontWeight normal = w400;
public static readonly FontWeight bold = w700;
public static readonly List<FontWeight> values = new List<FontWeight> {
public static readonly Dictionary<int, int> indexToFontWeight = new Dictionary<int, int> {
{0, 100},
{1, 200},

{7, 800},
{8, 900},
};
public bool Equals(FontWeight other) {
if (ReferenceEquals(null, other)) {
return false;

public override string ToString() {
return $"FontWeight.w{this.weightValue}";
}
get {
return indexToFontWeight[this.index];
}
get { return indexToFontWeight[this.index]; }
}
}

27
Runtime/ui/txt/wordbreaker.cs


if (this._current == this._size) {
return -1;
}
bool preBoundaryChar = isBoundaryChar(this._text[this._current + this._offset]);
if (preBoundaryChar) {
return this._current;
}
break;
}
if (isBoundaryChar(this._text[this._current + this._offset])) {
break;
}
var currentType = WordSeparate.classifyChar(this._text, this._current + this._offset);

return (char) (((uint) (lead) << 10) + (uint) (trail - U16_SURROGATE_OFFSET));
}
public static bool isBoundaryChar(char code) {
if (char.IsPunctuation(code)) {
return true;
}
if (code >= 0x4E00 && code <= 0x9FFF) { // cjk https://en.wikipedia.org/wiki/CJK_Unified_Ideographs
return true;
}
// https://social.msdn.microsoft.com/Forums/en-US/0d1888de-9745-4dd1-80fd-d3c29d3e381d/checking-for-japanese-characters-in-a-string?forum=vcmfcatl
if (code >= 0x3040 && code <= 0x30FF) { // Hiragana or Katakana
return true;
}
return false;
}
void nextUntilCodePoint() {
while (this._current < this._size
&& (char.IsLowSurrogate(this._text[this._current + this._offset])

46
Runtime/ui/window.cs


using System.Collections.Generic;
using Unity.UIWidgets.async;
using Unity.UIWidgets.foundation;
using UnityEngine;
namespace Unity.UIWidgets.ui {
public delegate void VoidCallback();

}
protected float _devicePixelRatio = 1.0f;
public int antiAliasing {
get { return this._antiAliasing; }
}

public abstract Timer run(TimeSpan duration, Action callback, bool periodic = false);
public Timer periodic(TimeSpan duration, Action callback) {
return this.run(duration, callback, true);
}
public Timer run(Action callback) {
return this.run(TimeSpan.Zero, callback);
}

public float getFPS() {
return 1.0f / this.fpsDeltaTime;
}
public const int defaultMaxTargetFrameRate = 60;
public const int defaultMinTargetFrameRate = 15;
static Action _onFrameRateSpeedUp = defaultFrameRateSpeedUp;
public static Action onFrameRateSpeedUp {
get { return _onFrameRateSpeedUp; }
set {
if (value == null) {
_onFrameRateSpeedUp = defaultFrameRateSpeedUp;
}
else {
_onFrameRateSpeedUp = value;
}
}
}
static void defaultFrameRateSpeedUp() {
Application.targetFrameRate = defaultMaxTargetFrameRate;
}
static Action _onFrameRateCoolDown = defaultFrameRateCoolDown;
public static Action onFrameRateCoolDown {
get { return _onFrameRateCoolDown; }
set {
if (value == null) {
_onFrameRateCoolDown = defaultFrameRateCoolDown;
}
else {
_onFrameRateCoolDown = value;
}
}
}
static void defaultFrameRateCoolDown() {
Application.targetFrameRate = defaultMinTargetFrameRate;
}
}
}

8
Runtime/widgets/automatic_keep_alive.cs


public Ticker createTicker(TickerCallback onTick) {
this._tickers = this._tickers ?? new HashSet<Ticker>();
var result = new _AutomaticWidgetTicker<T>(onTick, this, debugLabel: "created by " + this);
var debugLabel = "";
D.assert(() => {
debugLabel = "created by " + this;
return true;
});
var result = new _AutomaticWidgetTicker<T>(onTick, this, debugLabel: debugLabel);
this._tickers.Add(result);
return result;
}

16
Runtime/widgets/ticker_provider.cs


"mixing in a SingleTickerProviderStateMixin, use a regular TickerProviderStateMixin."
);
});
this._ticker = new Ticker(onTick, debugLabel: "created by " + this);
var debugLabel = "";
D.assert(() => {
debugLabel = "created by " + this;
return true;
});
this._ticker = new Ticker(onTick, debugLabel: debugLabel);
return this._ticker;
}

public Ticker createTicker(TickerCallback onTick) {
this._tickers = this._tickers ?? new HashSet<Ticker>();
var result = new _WidgetTicker<T>(onTick, this, debugLabel: "created by " + this);
var debugLabel = "";
D.assert(() => {
debugLabel = "created by " + this;
return true;
});
var result = new _WidgetTicker<T>(onTick, this, debugLabel: debugLabel);
this._tickers.Add(result);
return result;
}

22
Samples/UIWidgetsGallery/demo/shrine/shrine_types.cs


}
public override string ToString() {
return "Vendor($name)";
return $"Vendor({this.name})";
}
}

}
public static bool operator ==(Order left, Order right) {
if (left is null && right is null) return true;
if (left is null || right is null) return false;
if (left is null && right is null) {
return true;
}
if (left is null || right is null) {
return false;
}
if (left is null && right is null) return false;
if (left is null || right is null) return true;
if (left is null && right is null) {
return false;
}
if (left is null || right is null) {
return true;
}
return !left.Equals(right);
}

正在加载...
取消
保存