浏览代码

Merge branches 'kgdev' and 'master' of gitlab.cds.internal.unity3d.com:upm-packages/ui-widgets/com.unity.uiwidgets into kgdev

/main
kg 6 年前
当前提交
7d8a57f1
共有 44 个文件被更改,包括 1651 次插入578 次删除
  1. 22
      README.md
  2. 1
      Runtime/editor/editor_window.cs
  3. 2
      Runtime/painting/text_painter.cs
  4. 41
      Runtime/painting/text_span.cs
  5. 25
      Runtime/painting/text_style.cs
  6. 490
      Runtime/rendering/editable.cs
  7. 13
      Runtime/rendering/paragraph.cs
  8. 8
      Runtime/rendering/viewport.cs
  9. 9
      Runtime/rendering/viewport_offset.cs
  10. 26
      Runtime/service/keyboard.cs
  11. 52
      Runtime/service/text_input.cs
  12. 2
      Runtime/ui/painting/canvas_impl.cs
  13. 6
      Runtime/ui/painting/shadow_utils.cs
  14. 102
      Runtime/ui/painting/txt/font_manager.cs
  15. 2
      Runtime/ui/painting/txt/mesh_generator.cs
  16. 111
      Runtime/ui/text.cs
  17. 2
      Runtime/ui/txt/layout.cs
  18. 1
      Runtime/ui/txt/linebreaker.cs
  19. 9
      Runtime/ui/txt/paragraph.cs
  20. 6
      Runtime/ui/txt/paragraph_builder.cs
  21. 11
      Runtime/widgets/basic.cs
  22. 228
      Runtime/widgets/editable_text.cs
  23. 8
      Runtime/widgets/scroll_position.cs
  24. 6
      Samples/UIWidgetSample/MaterialSample.cs
  25. 10
      Samples/UIWidgetsGallery/GalleryMain.cs
  26. 6
      Tests/Editor/Widgets.cs
  27. 24
      Third Party Notices.md
  28. 82
      Runtime/service/raw_keyboard.cs
  29. 11
      Runtime/service/raw_keyboard.cs.meta
  30. 11
      Runtime/ui/painting/shadow_utils.cs.meta
  31. 8
      Samples/UIWidgetSample/txt.meta
  32. 8
      Samples/UIWidgetsTheatre.meta
  33. 11
      Samples/UIWidgetSample/txt/FontWeightStyle.cs.meta
  34. 68
      Samples/UIWidgetSample/txt/TextSpanGesture.cs
  35. 11
      Samples/UIWidgetSample/txt/TextSpanGesture.cs.meta
  36. 85
      Samples/UIWidgetSample/txt/FontWeightStyle.cs
  37. 61
      Samples/UIWidgetsTheatre/UIWidgetsTheatre.cs
  38. 11
      Samples/UIWidgetsTheatre/UIWidgetsTheatre.cs.meta
  39. 468
      Samples/UIWidgetsTheatre/UIWidgetsTheatre.unity
  40. 7
      Samples/UIWidgetsTheatre/UIWidgetsTheatre.unity.meta
  41. 11
      Runtime/service/text_input_utils.cs.meta
  42. 153
      Runtime/service/text_input_utils.cs

22
README.md


using Unity.UIWidgets.foundation;
using Unity.UIWidgets.material;
using Unity.UIWidgets.painting;
using Unity.UIWidgets.ui;
using UnityEngine;
using FontStyle = Unity.UIWidgets.ui.FontStyle;
protected override void OnEnable() {
base.OnEnable();
protected override void Awake() {
base.Awake();
// 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");
// Application.targetFrameRate = 60; // or higher if you want a smoother scrolling experience.
// load custom font with weight & style. The font weight & style corresponds to fontWeight, fontStyle of
// a TextStyle object
// FontManager.instance.addFont(Resources.Load<Font>(path: "path to your font"), "Roboto", FontWeight.w500,
// FontStyle.italic);
// if you want to use your own font or font icons.
// use the asset name of font (file name without extension) in FontStyle.fontFamily.
// FontManager.instance.addFont(Resources.Load<Font>(path: "path to your font"));
// add material icons, familyName must be "Material Icons"
// FontManager.instance.addFont(Resources.Load<Font>(path: "path to material icons"), "Material Icons");
}
protected override Widget createWidget() {

you can refer to Flutter Wiki to access detailed descriptions of UIWidgets APIs
from those of their Flutter counterparts.
#### FAQ
| Question | Answer |

1
Runtime/editor/editor_window.cs


}
}
RawKeyboard.instance._handleKeyEvent(Event.current);
TextInput.OnGUI();
}

2
Runtime/painting/text_painter.cs


var builder = new ParagraphBuilder(this._createParagraphStyle(TextDirection.ltr)
); // direction doesn't matter, text is just a space
if (this.text != null && this.text.style != null) {
builder.pushStyle(this.text.style);
builder.pushStyle(this.text.style, this.textScaleFactor);
}
builder.addText(" ");

41
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.recognizer = recognizer;
var hasTyle = this.style != null;
if (hasTyle) {
builder.pushStyle(this.style);
var hasStyle = this.style != null;
if (hasStyle) {
builder.pushStyle(this.style, textScaleFactor);
}
if (!string.IsNullOrEmpty(this.text)) {

}
}
if (hasTyle) {
if (hasStyle) {
builder.pop();
}
}

return true;
}
TextSpan getSpanForPosition(TextPosition position) {
public TextSpan getSpanForPosition(TextPosition position) {
D.assert(this.debugAssertIsValid());
var offset = 0;
var targetOffset = position.offset;
var affinity = position.affinity;

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

return result;
}
bool debugAssertIsValid() {
D.assert(() => {
if (!this.visitTextSpan(span => {
if (span.children != null) {
foreach (TextSpan child in span.children) {
if (child == null)
return false;
}
}
return true;
})) {
throw new UIWidgetsError(
"A TextSpan object with a non-null child list should not have any nulls in its child list.\n" +
"The full text in question was:\n" +
this.toStringDeep(prefixLineOne:" "));
}
return true;
});
return true;
}
public RenderComparison compareTo(TextSpan other) {
if (this.Equals(other)) {
return RenderComparison.identical;

unchecked {
var hashCode = (this.style != null ? this.style.GetHashCode() : 0);
hashCode = (hashCode * 397) ^ (this.text != null ? this.text.GetHashCode() : 0);
hashCode = (hashCode * 397) ^ (this.recognizer != null ? this.recognizer.GetHashCode() : 0);
hashCode = (hashCode * 397) ^ (this.childHash());
return hashCode;
}

}
return Equals(this.style, other.style) && string.Equals(this.text, other.text) &&
childEquals(this.children, other.children);
childEquals(this.children, other.children) && this.recognizer == other.recognizer;
}
public static bool operator ==(TextSpan left, TextSpan right) {

25
Runtime/painting/text_style.cs


public readonly bool inherit;
public readonly Color color;
public readonly float? fontSize;
public readonly FontWeight? fontWeight;
public readonly FontWeight fontWeight;
public readonly FontStyle? fontStyle;
public readonly float? letterSpacing;
public readonly float? wordSpacing;

public TextStyle(bool inherit = true, Color color = null, float? fontSize = null,
FontWeight? fontWeight = null,
FontWeight fontWeight = null,
FontStyle? fontStyle = null, float? letterSpacing = null, float? wordSpacing = null,
TextBaseline? textBaseline = null, float? height = null, Paint background = null,
TextDecoration decoration = null,

this.background = background;
}
public ui.TextStyle getTextStyle(ui.TextStyle currentStyle = null) {
public ui.TextStyle getTextStyle(ui.TextStyle currentStyle = null, float textScaleFactor = 1.0f) {
fontSize: this.fontSize ?? currentStyle.fontSize,
fontSize: this.fontSize != null ? this.fontSize * textScaleFactor : currentStyle.fontSize,
fontWeight: this.fontWeight ?? currentStyle.fontWeight,
fontStyle: this.fontStyle ?? currentStyle.fontStyle,
letterSpacing: this.letterSpacing ?? currentStyle.letterSpacing,

return new ui.TextStyle(
color: this.color,
fontSize: this.fontSize,
fontSize: this.fontSize * textScaleFactor,
fontWeight: this.fontWeight,
fontStyle: this.fontStyle,
letterSpacing: this.letterSpacing,

public TextStyle copyWith(Color color = null,
string fontFamily = null,
float? fontSize = null,
FontWeight? fontWeight = null,
FontWeight fontWeight = null,
FontStyle? fontStyle = null,
float? letterSpacing = null,
float? wordSpacing = null,

defaultValue: Diagnostics.kNullDefaultValue));
string weightDescription = "";
if (this.fontWeight != null) {
switch (this.fontWeight) {
case FontWeight.w400:
weightDescription = "400";
break;
case FontWeight.w700:
weightDescription = "700";
break;
}
weightDescription = this.fontWeight.weightValue.ToString();
styles.Add(new DiagnosticsProperty<FontWeight?>(
styles.Add(new DiagnosticsProperty<FontWeight>(
"weight", this.fontWeight,
description: weightDescription,
defaultValue: Diagnostics.kNullDefaultValue

var hashCode = this.inherit.GetHashCode();
hashCode = (hashCode * 397) ^ (this.color != null ? this.color.GetHashCode() : 0);
hashCode = (hashCode * 397) ^ this.fontSize.GetHashCode();
hashCode = (hashCode * 397) ^ this.fontWeight.GetHashCode();
hashCode = (hashCode * 397) ^ (this.fontWeight != null ? this.fontWeight.GetHashCode() : 0);
hashCode = (hashCode * 397) ^ this.fontStyle.GetHashCode();
hashCode = (hashCode * 397) ^ this.letterSpacing.GetHashCode();
hashCode = (hashCode * 397) ^ this.wordSpacing.GetHashCode();

490
Runtime/rendering/editable.cs


return $"Point: {this.point}, Direction: {this.direction}";
}
}
/*
this._doubleTapGesture = new DoubleTapGestureRecognizer(this.rendererBindings.rendererBinding);
this._doubleTapGesture.onDoubleTap = () => { Debug.Log("onDoubleTap"); };*/
public class RenderEditable : RenderBox {
public static readonly char obscuringCharacter = '•';

TextPainter _textPainter;
Color _cursorColor;
bool _hasFocus;
int? _maxLines;
Color _selectionColor;
ViewportOffset _offset;

TextAlign textAlign = TextAlign.left, float textScaleFactor = 1.0f, Color cursorColor = null,
bool? hasFocus = null, int? maxLines = 1, Color selectionColor = null,
TextSelection selection = null, bool obscureText = false, SelectionChangedHandler onSelectionChanged = null,
CaretChangedHandler onCaretChanged = null, bool ignorePointer = false) {
CaretChangedHandler onCaretChanged = null, bool ignorePointer = false,
TextSelectionDelegate textSelectionDelegate = null) {
D.assert(textSelectionDelegate != null);
this._textPainter = new TextPainter(text: text, textAlign: textAlign, textDirection: textDirection,
textScaleFactor: textScaleFactor);
this._cursorColor = cursorColor;

this.ignorePointer = ignorePointer;
this.onCaretChanged = onCaretChanged;
this.onSelectionChanged = onSelectionChanged;
this.textSelectionDelegate = textSelectionDelegate;
D.assert(this._maxLines == null || this._maxLines > 0);
D.assert(this._showCursor != null);

}
}
public TextSelectionDelegate textSelectionDelegate;
int _extentOffset = -1;
int _baseOffset = -1;
int _previousCursorLocation;
bool _resetCursor = false;
void _handleKeyEvent(RawKeyEvent keyEvent) {
if (keyEvent is RawKeyUpEvent) {
return;
}
if (this.selection.isCollapsed) {
this._extentOffset = this.selection.extentOffset;
this._baseOffset = this.selection.baseOffset;
}
KeyCode pressedKeyCode = keyEvent.data.unityEvent.keyCode;
int modifiers = (int) keyEvent.data.unityEvent.modifiers;
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 downArrow = pressedKeyCode == KeyCode.DownArrow;
bool arrow = leftArrow || rightArrow || upArrow || downArrow;
bool aKey = pressedKeyCode == KeyCode.A;
bool xKey = pressedKeyCode == KeyCode.X;
bool vKey = pressedKeyCode == KeyCode.V;
bool cKey = pressedKeyCode == KeyCode.C;
bool del = pressedKeyCode == KeyCode.Delete;
bool backDel = pressedKeyCode == KeyCode.Backspace;
bool isMac = SystemInfo.operatingSystemFamily == OperatingSystemFamily.MacOSX;
if (arrow) {
int newOffset = this._extentOffset;
var word = (isMac && alt) || ctrl;
if (word) {
newOffset = this._handleControl(rightArrow, leftArrow, word, newOffset);
}
newOffset = this._handleHorizontalArrows(rightArrow, leftArrow, shift, newOffset);
if (downArrow || upArrow)
newOffset = this._handleVerticalArrows(upArrow, downArrow, shift, newOffset);
newOffset = this._handleShift(rightArrow, leftArrow, shift, newOffset);
this._extentOffset = newOffset;
} else if ((ctrl || (isMac && cmd)) && (xKey || vKey || cKey || aKey)) {
this._handleShortcuts(pressedKeyCode);
}
if (del || backDel) {
this._handleDelete(backDel);
}
}
int _handleControl(bool rightArrow, bool leftArrow, bool ctrl, int 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));
newOffset = textSelection.baseOffset + 1;
} else if (rightArrow && this._extentOffset < this.text.text.Length - 2) {
TextSelection textSelection = this._selectWordAtOffset(new TextPosition(offset: this._extentOffset + 1));
newOffset = textSelection.extentOffset - 1;
}
return newOffset;
}
int _handleHorizontalArrows(bool rightArrow, bool leftArrow, bool shift, int newOffset) {
if (rightArrow && this._extentOffset < this.text.text.Length) {
newOffset += 1;
if (shift) {
this._previousCursorLocation += 1;
}
}
if (leftArrow && this._extentOffset > 0) {
newOffset -= 1;
if (shift) {
this._previousCursorLocation -= 1;
}
}
return newOffset;
}
int _handleVerticalArrows(bool upArrow, bool downArrow, bool shift, int newOffset) {
float plh = this._textPainter.preferredLineHeight;
float verticalOffset = upArrow ? -0.5f * plh : 1.5f * plh;
Offset caretOffset = this._textPainter.getOffsetForCaret(new TextPosition(offset: this._extentOffset), this._caretPrototype);
Offset caretOffsetTranslated = caretOffset.translate(0.0f, verticalOffset);
TextPosition position = this._textPainter.getPositionForOffset(caretOffsetTranslated);
if (position.offset == this._extentOffset) {
if (downArrow)
newOffset = this.text.text.Length;
else if (upArrow)
newOffset = 0;
this._resetCursor = shift;
} else if (this._resetCursor && shift) {
newOffset = this._previousCursorLocation;
this._resetCursor = false;
} else {
newOffset = position.offset;
this._previousCursorLocation = newOffset;
}
return newOffset;
}
int _handleShift(bool rightArrow, bool leftArrow, bool shift, int newOffset) {
if (this.onSelectionChanged == null)
return newOffset;
if (shift) {
if (this._baseOffset < newOffset) {
this.onSelectionChanged(
new TextSelection(
baseOffset: this._baseOffset,
extentOffset: newOffset
),
this,
SelectionChangedCause.keyboard
);
} else {
this.onSelectionChanged(
new TextSelection(
baseOffset: newOffset,
extentOffset: this._baseOffset
),
this,
SelectionChangedCause.keyboard
);
}
} else {
if (!this.selection.isCollapsed) {
if (leftArrow)
newOffset = this._baseOffset < this._extentOffset ? this._baseOffset : this._extentOffset;
else if (rightArrow)
newOffset = this._baseOffset > this._extentOffset ? this._baseOffset : this._extentOffset;
}
this.onSelectionChanged(
TextSelection.fromPosition(
new TextPosition(
offset: newOffset
)
),
this,
SelectionChangedCause.keyboard
);
}
return newOffset;
}
void _handleShortcuts(KeyCode pressedKeyCode) {
switch (pressedKeyCode) {
case KeyCode.C:
if (!this.selection.isCollapsed) {
Clipboard.setData(
new ClipboardData(text: this.selection.textInside(this.text.text)));
}
break;
case KeyCode.X:
if (!this.selection.isCollapsed) {
Clipboard.setData(
new ClipboardData(text: this.selection.textInside(this.text.text)));
this.textSelectionDelegate.textEditingValue = new TextEditingValue(
text: this.selection.textBefore(this.text.text)
+ this.selection.textAfter(this.text.text),
selection: TextSelection.collapsed(offset: this.selection.start)
);
}
break;
case KeyCode.V:
TextEditingValue value = this.textSelectionDelegate.textEditingValue;
Clipboard.getData(Clipboard.kTextPlain).Then(data => {
if (data != null) {
this.textSelectionDelegate.textEditingValue = new TextEditingValue(
text: value.selection.textBefore(value.text)
+ data.text
+ value.selection.textAfter(value.text),
selection: TextSelection.collapsed(
offset: value.selection.start + data.text.Length
)
);
}
});
break;
case KeyCode.A:
this._baseOffset = 0;
this._extentOffset = this.textSelectionDelegate.textEditingValue.text.Length;
this.onSelectionChanged(
new TextSelection(
baseOffset: 0,
extentOffset: this.textSelectionDelegate.textEditingValue.text.Length
),
this,
SelectionChangedCause.keyboard
);
break;
default:
D.assert(false);
break;
}
}
void _handleDelete(bool backDel) {
var selection = this.selection;
if (backDel && selection.isCollapsed) {
if (selection.start <= 0) {
return;
}
selection = TextSelection.collapsed(selection.start - 1, selection.affinity);
}
if (selection.textAfter(this.text.text).isNotEmpty()) {
this.textSelectionDelegate.textEditingValue = new TextEditingValue(
text: selection.textBefore(this.text.text)
+ selection.textAfter(this.text.text).Substring(1),
selection: TextSelection.collapsed(offset: selection.start)
);
} else {
this.textSelectionDelegate.textEditingValue = new TextEditingValue(
text: selection.textBefore(this.text.text),
selection: TextSelection.collapsed(offset: selection.start)
);
}
}
protected void markNeedsTextLayout() {
this._textLayoutLastWidth = null;
this.markNeedsLayout();
}
public TextSpan text {
get { return this._textPainter.text; }
set {

}
}
public ValueNotifier<bool> ShowCursor {
public ValueNotifier<bool> showCursor {
get { return this._showCursor; }
set {
D.assert(value != null);

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

this._hasFocus = value;
if (this._hasFocus) {
D.assert(!this._listenerAttached);
RawKeyboard.instance.addListener(this._handleKeyEvent);
this._listenerAttached = true;
}
else {
D.assert(this._listenerAttached);
RawKeyboard.instance.removeListener(this._handleKeyEvent);
this._listenerAttached = false;
}
this.markNeedsSemanticsUpdate();
}
}

this.markNeedsLayout();
}
}
float _cursorWidth = 1.0f;
public ValueNotifier<bool> showCursor {
get { return this._showCursor; }
set {
D.assert(value != null);
if (this._showCursor == value) {
public float cursorWidth {
get { return this._cursorWidth; }
set {
if (this._cursorWidth == value)
}
if (this.attached) {
this._showCursor.removeListener(this.markNeedsPaint);
}
this._showCursor = value;
if (this.attached) {
this._showCursor.addListener(this.markNeedsPaint);
}
this.markNeedsPaint();
this._cursorWidth = value;
this.markNeedsLayout();
}
}
Radius _cursorRadius;
public Radius cursorRadius {
get { return this._cursorRadius; }
set {
if (this._cursorRadius == value)
return;
this._cursorRadius = value;
this.markNeedsLayout();
}
}
bool _enableInteractiveSelection;
public bool enableInteractiveSelection {
get { return this._enableInteractiveSelection; }
set {
if (this._enableInteractiveSelection == value)
return;
this._enableInteractiveSelection = value;
this.markNeedsTextLayout();
this.markNeedsSemanticsUpdate();
}
}

public override void detach() {
this._offset.removeListener(this.markNeedsLayout);
this._showCursor.removeListener(this.markNeedsPaint);
if (this._listenerAttached) {
RawKeyboard.instance.removeListener(this._handleKeyEvent);
}
base.detach();
}

this._longPress.addPointer((PointerDownEvent) evt);
}
}
public void handleTapDown(TapDownDetails details) {
this._lastTapDownPosition = details.globalPosition - this._paintOffset;
void handleTapDown(TapDownDetails details) {
this._lastTapDownPosition = details.globalPosition + - this._paintOffset;
this._selectForTap(this._lastTapDownPosition);
this.selectPosition(SelectionChangedCause.tap);
void _handleTapDown(TapDownDetails details) {
D.assert(!this.ignorePointer);
this.handleTapDown(details);
}
public void handleTap() {
this.selectPosition(cause: SelectionChangedCause.tap);
}
public void handleTap() {
this._layoutText(this.constraints.maxWidth);
D.assert(this._lastTapDownPosition != null);
if (Application.isMobilePlatform) {
this._selectForTap(this._lastTapDownPosition);
}
void _handleTap() {
D.assert(!this.ignorePointer);
this.handleTap();
void _handleDoubleTap(DoubleTapDetails details) {
D.assert(!this.ignorePointer);
this.handleDoubleTap(details);
}
// need set _lastTapDownPosition, otherwise it would be last single tap position
void _handleLongPress() {
D.assert(!this.ignorePointer);
this.handleLongPress();
}
void selectPosition(SelectionChangedCause? cause = null) {
D.assert(cause != null);
this._layoutText(this.constraints.maxWidth);
D.assert(this._lastTapDownPosition != null);
if (this.onSelectionChanged != null) {
TextPosition position = this._textPainter.getPositionForOffset(this.globalToLocal(this._lastTapDownPosition));
this.onSelectionChanged(TextSelection.fromPosition(position), this, cause.Value);
}
}
void selectWord(SelectionChangedCause? cause = null) {
this._layoutText(this.constraints.maxWidth);
D.assert(this._lastTapDownPosition != null);

}
}
void selectWordEdge(SelectionChangedCause cause) {
this._layoutText(this.constraints.maxWidth);
D.assert(this._lastTapDownPosition != null);
if (this.onSelectionChanged != null) {
TextPosition position = this._textPainter.getPositionForOffset(this.globalToLocal(this._lastTapDownPosition));
TextRange word = this._textPainter.getWordBoundary(position);
if (position.offset - word.start <= 1) {
this.onSelectionChanged(
TextSelection.collapsed(offset: word.start, affinity: TextAffinity.downstream),
this,
cause
);
} else {
this.onSelectionChanged(
TextSelection.collapsed(offset: word.end, affinity: TextAffinity.upstream),
this,
cause
);
}
}
}
TextSelection _selectWordAtOffset(TextPosition position) {
D.assert(this._textLayoutLastWidth == this.constraints.maxWidth);
var word = this._textPainter.getWordBoundary(position);
if (position.offset >= word.end) {
return TextSelection.fromPosition(position);
}
return new TextSelection(baseOffset: word.start, extentOffset: word.end);
}
void _layoutText(float constraintWidth) {
if (this._textLayoutLastWidth == constraintWidth) {
return;
}
var caretMargin = _kCaretGap + _kCaretWidth;
var avialableWidth = Mathf.Max(0.0f, constraintWidth - caretMargin);
var maxWidth = this._isMultiline ? avialableWidth : float.PositiveInfinity;
this._textPainter.layout(minWidth: avialableWidth, maxWidth: maxWidth);
this._textLayoutLastWidth = constraintWidth;
}
protected override void performLayout() {
this._layoutText(this.constraints.maxWidth);
this._caretPrototype = Rect.fromLTWH(0.0f, _kCaretHeightOffset, _kCaretWidth,

return true;
}
protected void markNeedsTextLayout() {
this._textLayoutLastWidth = null;
this.markNeedsLayout();
}
var caretRec = this._caretPrototype.shift(caretOffset + effectiveOffset);
canvas.drawRect(caretRec, paint);
if (!caretRec.Equals(this._lastCaretRect)) {
this._lastCaretRect = caretRec;
var caretRect = this._caretPrototype.shift(caretOffset + effectiveOffset);
if (this.cursorRadius == null) {
canvas.drawRect(caretRect, paint);
}
else {
RRect caretRRect = RRect.fromRectAndRadius(caretRect, this.cursorRadius);
canvas.drawRRect(caretRRect, paint);
}
if (!caretRect.Equals(this._lastCaretRect)) {
this._lastCaretRect = caretRect;
this.onCaretChanged(caretRec);
this.onCaretChanged(caretRect);
}
}
}

this._textPainter.paint(context.canvas, effectiveOffset);
}
void _handleSetSelection(TextSelection selection) {
this.onSelectionChanged(selection, this, SelectionChangedCause.keyboard);
}
void _handleTapDown(TapDownDetails details) {
D.assert(!this.ignorePointer);
this.handleTapDown(details);
}
void _handleTap() {
D.assert(!this.ignorePointer);
this.handleTap();
}
void _handleDoubleTap(DoubleTapDetails details) {
D.assert(!this.ignorePointer);
this.handleDoubleTap(details);
}
void _handleLongPress() {
D.assert(!this.ignorePointer);
this.handleLongPress();
}
void markNeedsSemanticsUpdate() {
// todo
}

return Mathf.Max(this.preferredLineHeight, this._textPainter.height);
}
void _layoutText(float constraintWidth) {
if (this._textLayoutLastWidth == constraintWidth) {
return;
}
var caretMargin = _kCaretGap + _kCaretWidth;
var avialableWidth = Mathf.Max(0.0f, constraintWidth - caretMargin);
var maxWidth = this._isMultiline ? avialableWidth : float.PositiveInfinity;
this._textPainter.layout(minWidth: avialableWidth, maxWidth: maxWidth);
this._textLayoutLastWidth = constraintWidth;
}
TextSelection _selectWordAtOffset(TextPosition position) {
D.assert(this._textLayoutLastWidth == this.constraints.maxWidth);
var word = this._textPainter.getWordBoundary(position);
if (position.offset >= word.end) {
return TextSelection.fromPosition(position);
}
return new TextSelection(baseOffset: word.start, extentOffset: word.end);
}
void _selectForTap(Offset pointerPosition) {
if (this.onSelectionChanged != null) {
var position = this._textPainter.getPositionForOffset(this.globalToLocal(pointerPosition));
this.onSelectionChanged(TextSelection.fromPosition(position), this, SelectionChangedCause.tap);
}
}
bool _isMultiline {
get { return this._maxLines != 1; }
}

return 0.0f;
}
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));

13
Runtime/rendering/paragraph.cs


using System;
using System.Collections.Generic;
using Unity.UIWidgets.foundation;
using Unity.UIWidgets.gestures;
using Unity.UIWidgets.painting;
using Unity.UIWidgets.ui;
using UnityEngine;

protected override bool hitTestSelf(Offset position) {
return true;
}
public override void handleEvent(PointerEvent evt, HitTestEntry entry) {
D.assert(this.debugHandleEvent(evt, entry));
if (!(evt is PointerDownEvent)) {
return;
}
this._layoutTextWithConstraints(this.constraints);
Offset offset = ((BoxHitTestEntry)entry).localPosition;
TextPosition position = this._textPainter.getPositionForOffset(offset);
TextSpan span = this._textPainter.text.getSpanForPosition(position);
span?.recognizer?.addPointer((PointerDownEvent)evt);
}
protected override void performLayout() {

8
Runtime/rendering/viewport.cs


D.assert(targetOffset != null);
if (duration == TimeSpan.Zero) {
offset.jumpTo(targetOffset.offset);
}
else {
offset.animateTo(targetOffset.offset, duration: duration.Value, curve: curve);
}
offset.moveTo(targetOffset.offset, duration: duration.Value, curve: curve);
return targetOffset.rect;
}
}

9
Runtime/rendering/viewport_offset.cs


public abstract IPromise animateTo(float to, TimeSpan duration, Curve curve);
public virtual IPromise moveTo(float to, TimeSpan? duration, Curve curve = null, bool clamp = true) {
if (duration == null || duration.Value == TimeSpan.Zero) {
this.jumpTo(to);
return Promise.Resolved();
} else {
return this.animateTo(to, duration: duration??TimeSpan.Zero , curve: curve ?? Curves.ease);
}
}
public abstract ScrollDirection userScrollDirection { get; }
public abstract bool allowImplicitScrolling { get; }

26
Runtime/service/keyboard.cs


namespace Unity.UIWidgets.service {
interface KeyboardDelegate: IDisposable {
void show();
void hide();

if (currentEvent != null && currentEvent.type == EventType.KeyDown) {
var action = TextInputUtils.getInputAction(currentEvent);
if (action != null) {
Window.instance.run(() => { TextInput._performAction(this._client, action.Value); });
if (currentEvent.keyCode == KeyCode.Return) {
Window.instance.run(() => { TextInput._performAction(this._client, TextInputAction.newline); });
if (action == null || action == TextInputAction.newline) {
if (currentEvent.keyCode == KeyCode.None) {
char ch = currentEvent.character;
if (ch == '\r' || ch == 3) {
ch = '\n';
}
this._value = this._value.clearCompose();
if (_validateCharacter(ch)) {
this._value = this._value.insert(new string(ch, 1));
}
Window.instance.run(() => { TextInput._updateEditingState(this._client, this._value); });
if (currentEvent.character != '\0') {
char ch = currentEvent.character;
if (ch == '\r' || ch == 3) {
ch = '\n';
this._value = this._value.clearCompose();
if (_validateCharacter(ch)) {
this._value = this._value.insert(new string(ch, 1));
}
Window.instance.run(() => { TextInput._updateEditingState(this._client, this._value); });
}
currentEvent.Use();

52
Runtime/service/text_input.cs


join,
route,
emergencyCall,
newline,
moveLeft,
moveRight,
moveUp,
moveDown,
moveLineStart,
moveLineEnd,
moveTextStart,
moveTextEnd,
movePageUp,
movePageDown,
moveGraphicalLineStart,
moveGraphicalLineEnd,
moveWordLeft,
moveWordRight,
moveParagraphForward,
moveParagraphBackward,
moveToStartOfNextWord,
moveToEndOfPreviousWord,
selectLeft,
selectRight,
selectUp,
selectDown,
selectTextStart,
selectTextEnd,
selectPageUp,
selectPageDown,
expandSelectGraphicalLineStart,
expandSelectGraphicalLineEnd,
selectGraphicalLineStart,
selectGraphicalLineEnd,
selectWordLeft,
selectWordRight,
selectToEndOfPreviousWord,
selectToStartOfNextWord,
selectParagraphBackward,
selectParagraphForward,
delete,
backspace,
deleteWordBack,
deleteWordForward,
deleteLineBack,
cut,
copy,
paste,
selectAll,
selectNone,
scrollStart,
scrollEnd,
scrollPageUp,
scrollPageDown,
newline
}
public enum TextCapitalization {

2
Runtime/ui/painting/canvas_impl.cs


var mesh = new TextBlobMesh(textBlob, scale, matrix);
// request font texture so text mesh could be generated correctly
var font = FontManager.instance.getOrCreate(textBlob.style.fontFamily).font;
var font = FontManager.instance.getOrCreate(textBlob.style.fontFamily, style.fontWeight, style.fontStyle).font;
var fontSizeToLoad = Mathf.CeilToInt(style.UnityFontSize * scale);
var subText = textBlob.text.Substring(textBlob.textOffset, textBlob.textSize);
font.RequestCharactersInTexture(subText, fontSizeToLoad, style.UnityFontStyle);

6
Runtime/ui/painting/shadow_utils.cs


namespace Unity.UIWidgets.ui {
public static class ShadowUtils {
public const bool _drawShadowFlag = false;
public const float kAmbientHeightFactor = 1.0f / 128.0f;
public const float kAmbientGeomFactor = 64.0f;

public static void drawShadow(Canvas canvas, Path path, Vector3 zPlaneParams, Vector3 devLightPos,
float lightRadius, Color ambientColor, Color spotColor, int flags) {
if (!_drawShadowFlag) {
return;
}
Matrix3 viewMatrix = canvas.getTotalMatrix();
//ambient light

102
Runtime/ui/painting/txt/font_manager.cs


using System.Collections.Generic;
using System;
using System.Collections.Generic;
using System.Linq;
using Unity.UIWidgets.foundation;
using UnityEngine;

}
}
class FontRef : IEquatable<FontRef> {
public readonly string familyName;
public readonly FontWeight fontWeight;
public readonly FontStyle fontStyle;
public FontRef(string familyName, FontWeight fontWeight, FontStyle fontStyle) {
this.familyName = familyName;
this.fontWeight = fontWeight;
this.fontStyle = fontStyle;
}
public bool Equals(FontRef other) {
if (ReferenceEquals(null, other)) {
return false;
}
if (ReferenceEquals(this, other)) {
return true;
}
return string.Equals(this.familyName, other.familyName) && this.fontWeight == other.fontWeight && this.fontStyle == other.fontStyle;
}
public override bool Equals(object obj) {
if (ReferenceEquals(null, obj)) {
return false;
}
if (ReferenceEquals(this, obj)) {
return true;
}
if (obj.GetType() != this.GetType()) {
return false;
}
return this.Equals((FontRef) obj);
}
public override int GetHashCode() {
unchecked {
var hashCode = (this.familyName != null ? this.familyName.GetHashCode() : 0);
hashCode = (hashCode * 397) ^ (this.fontWeight != null ? this.fontWeight.GetHashCode() : 0);
hashCode = (hashCode * 397) ^ (int) this.fontStyle;
return hashCode;
}
}
public static bool operator ==(FontRef left, FontRef right) {
return Equals(left, right);
}
public static bool operator !=(FontRef left, FontRef right) {
return !Equals(left, right);
}
public override string ToString() {
return $"{nameof(this.familyName)}: {this.familyName}, {nameof(this.fontWeight)}: {this.fontWeight}, {nameof(this.fontStyle)}: {this.fontStyle}";
}
}
readonly Dictionary<string, FontInfo> _fonts = new Dictionary<string, FontInfo>();
readonly Dictionary<FontRef, FontInfo> _fonts = new Dictionary<FontRef, FontInfo>();
static readonly int defaultFontSize = 14;

Font.textureRebuilt += this.onFontTextureRebuilt;
}
public void addFont(Font font) {
public void addFont(Font font, string familyName,
FontWeight fontWeight = null, FontStyle fontStyle = FontStyle.normal) {
if (fontWeight == null) {
fontWeight = FontWeight.normal;
}
FontRef fontRef = new FontRef(familyName, fontWeight, fontStyle);
D.assert(font != null);
D.assert(font.dynamic, $"adding font which is not dynamic is not allowed {font.name}");
font.hideFlags = HideFlags.DontSave & ~HideFlags.DontSaveInBuild;

this._fonts.TryGetValue(name, out current);
D.assert(current == null || current.font == font, $"font with name {name} already exists");
this._fonts.TryGetValue(fontRef, out current);
D.assert(current == null || current.font == font, $"font with key {fontRef} already exists");
this._fonts[name] = fontInfo;
this._fonts[fontRef] = fontInfo;
internal FontInfo getOrCreate(string name) {
if (this._fonts.TryGetValue(name, out var fontInfo)) {
D.assert(fontInfo.font.name == name);
internal FontInfo getOrCreate(string familyName, FontWeight fontWeight, FontStyle fontStyle) {
if (fontWeight == null) {
fontWeight = FontWeight.normal;
}
FontRef fontRef = new FontRef(familyName, fontWeight, fontStyle);
if (this._fonts.TryGetValue(fontRef, out var fontInfo)) {
var osFont = Font.CreateDynamicFontFromOSFont(name, defaultFontSize);
// fallback to normal weight & style
if (fontWeight != FontWeight.normal || fontStyle != FontStyle.normal) {
fontInfo = this.getOrCreate(familyName, FontWeight.normal, FontStyle.normal);
if (fontInfo != null) {
return fontInfo;
}
}
var osFont = Font.CreateDynamicFontFromOSFont(familyName, defaultFontSize);
this._fonts[osFont.name] = newFont;
fontRef = new FontRef(familyName, fontWeight, fontStyle);
this._fonts[fontRef] = newFont;
return newFont;
}

2
Runtime/ui/painting/txt/mesh_generator.cs


this._resolved = true;
var style = this._textBlob.style;
var fontInfo = FontManager.instance.getOrCreate(style.fontFamily);
var fontInfo = FontManager.instance.getOrCreate(style.fontFamily, style.fontWeight, style.fontStyle);
var key = new MeshKey(this._textBlob.instanceId, this._scale);
_meshes.TryGetValue(key, out var meshInfo);

111
Runtime/ui/text.cs


using System;
using System.Collections.Generic;
using Unity.UIWidgets.foundation;
namespace Unity.UIWidgets.ui {
public enum FontStyle {

internal UnityEngine.FontStyle UnityFontStyle {
get {
bool isBold = this.fontWeight == FontWeight.bold;
if (this.fontWeight == FontWeight.w700) {
if (isBold) {
return UnityEngine.FontStyle.BoldAndItalic;
}
else {

else if (this.fontWeight == FontWeight.w700) {
else if (isBold) {
return UnityEngine.FontStyle.Bold;
}

unchecked {
var hashCode = (this.color != null ? this.color.GetHashCode() : 0);
hashCode = (hashCode * 397) ^ this.fontSize.GetHashCode();
hashCode = (hashCode * 397) ^ this.fontWeight.GetHashCode();
hashCode = (hashCode * 397) ^ (this.fontWeight != null ? this.fontWeight.GetHashCode() : 0);
hashCode = (hashCode * 397) ^ this.fontStyle.GetHashCode();
hashCode = (hashCode * 397) ^ this.letterSpacing.GetHashCode();
hashCode = (hashCode * 397) ^ this.wordSpacing.GetHashCode();

public TextStyle(Color color = null, float? fontSize = null,
FontWeight? fontWeight = null, FontStyle? fontStyle = null, float? letterSpacing = 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,
string fontFamily = null,

public class ParagraphStyle : IEquatable<ParagraphStyle> {
public ParagraphStyle(TextAlign? textAlign = null,
TextDirection? textDirection = null,
FontWeight? fontWeight = null,
FontWeight fontWeight = null,
FontStyle? fontStyle = null,
int? maxLines = null,
float? fontSize = null,

unchecked {
var hashCode = this.textAlign.GetHashCode();
hashCode = (hashCode * 397) ^ this.textDirection.GetHashCode();
hashCode = (hashCode * 397) ^ this.fontWeight.GetHashCode();
hashCode = (hashCode * 397) ^ (this.fontWeight != null ? this.fontWeight.GetHashCode() : 0);
hashCode = (hashCode * 397) ^ this.fontStyle.GetHashCode();
hashCode = (hashCode * 397) ^ this.maxLines.GetHashCode();
hashCode = (hashCode * 397) ^ this.fontSize.GetHashCode();

public readonly TextAlign? textAlign;
public readonly TextDirection? textDirection;
public readonly FontWeight? fontWeight;
public readonly FontWeight fontWeight;
public readonly FontStyle? fontStyle;
public readonly int? maxLines;
public readonly float? fontSize;

downstream,
}
public enum FontWeight {
w400, // normal
w700, // bold
public class FontWeight: IEquatable<FontWeight> {
private FontWeight(int index) {
this.index = index;
}
public readonly 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>{
w100, w200, w300, w400, w500, w600, w700, w800, w900
};
public static readonly Dictionary<int, int> indexToFontWeight = new Dictionary<int, int> {
{0, 100},
{1, 200},
{2, 300},
{3, 400},
{4, 500},
{5, 600},
{6, 700},
{7, 800},
{8, 900},
};
public bool Equals(FontWeight other) {
if (ReferenceEquals(null, other)) {
return false;
}
if (ReferenceEquals(this, other)) {
return true;
}
return this.index == other.index;
}
public override bool Equals(object obj) {
if (ReferenceEquals(null, obj)) {
return false;
}
if (ReferenceEquals(this, obj)) {
return true;
}
if (obj.GetType() != this.GetType()) {
return false;
}
return this.Equals((FontWeight) obj);
}
public override int GetHashCode() {
return this.index;
}
public static bool operator ==(FontWeight left, FontWeight right) {
return Equals(left, right);
}
public static bool operator !=(FontWeight left, FontWeight right) {
return !Equals(left, right);
}
public override string ToString() {
return $"FontWeight.w{this.weightValue}";
}
public int weightValue {
get {
return indexToFontWeight[this.index];
}
}
public class TextPosition : IEquatable<TextPosition> {
public readonly int offset;

2
Runtime/ui/txt/layout.cs


this._advances.Clear();
this._positions.Clear();
this._count = count;
var font = FontManager.instance.getOrCreate(style.fontFamily).font;
var font = FontManager.instance.getOrCreate(style.fontFamily, style.fontWeight, style.fontStyle).font;
font.RequestCharactersInTexture(this._text.Substring(start, count),
style.UnityFontSize,
style.UnityFontStyle);

1
Runtime/ui/txt/linebreaker.cs


this._charWidths, start, this._tabStops);
}
var font = FontManager.instance.getOrCreate(style.fontFamily).font;
int current = this._wordBreaker.current();
int afterWord = start;
int lastBreak = start;

9
Runtime/ui/txt/paragraph.cs


}
var textStyle = this._paragraphStyle.getTextStyle();
this._tabStops.setFont(FontManager.instance.getOrCreate(textStyle.fontFamily).font,
this._tabStops.setFont(FontManager.instance.getOrCreate(textStyle.fontFamily,
textStyle.fontWeight, textStyle.fontStyle).font,
textStyle.UnityFontSize);
this._needsLayout = false;

continue;
}
var font = FontManager.instance.getOrCreate(run.style.fontFamily).font;
var font = FontManager.instance.getOrCreate(run.style.fontFamily,
run.style.fontWeight, run.style.fontStyle).font;
var metrics = FontMetrics.fromFont(font, run.style.UnityFontSize);
paintRecords.Add(new PaintRecord(run.style, new Offset(runXOffset, 0),
builder.make(), metrics, lineNumber, layout.getAdvance()

if (paintRecords.Count == 0) {
var defaultStyle = this._paragraphStyle.getTextStyle();
var defaultFont = FontManager.instance.getOrCreate(defaultStyle.fontFamily).font;
var defaultFont = FontManager.instance.getOrCreate(defaultStyle.fontFamily,
defaultStyle.fontWeight, defaultStyle.fontStyle).font;
var metrics = FontMetrics.fromFont(defaultFont, defaultStyle.UnityFontSize);
updateLineMetrics(metrics, defaultStyle);
}

6
Runtime/ui/txt/paragraph_builder.cs


int _paragraph_style_index;
public interface ITextStyleProvider {
TextStyle getTextStyle(TextStyle current = null);
TextStyle getTextStyle(TextStyle current = null, float textScaleFactor = 1.0f);
}
public ParagraphBuilder(ParagraphStyle style) {

return paragraph;
}
public void pushStyle(ITextStyleProvider style) {
var newStyle = style.getTextStyle(this.peekStyle());
public void pushStyle(ITextStyleProvider style, float textScaleFactor) {
var newStyle = style.getTextStyle(this.peekStyle(), textScaleFactor: textScaleFactor);
var styleIndex = this._runs.addStyle(newStyle);
this._styleStack.Add(styleIndex);
this._runs.startRun(styleIndex, this._text.Length);

11
Runtime/widgets/basic.cs


((RenderFlex) renderObject).verticalDirection = this.verticalDirection;
((RenderFlex) renderObject).textBaseline = this.textBaseline ?? TextBaseline.alphabetic;
}
public override void debugFillProperties(DiagnosticPropertiesBuilder properties) {
base.debugFillProperties(properties);
properties.add(new EnumProperty<Axis>("direction", this.direction));
properties.add(new EnumProperty<MainAxisAlignment>("mainAxisAlignment", this.mainAxisAlignment));
properties.add(new EnumProperty<MainAxisSize>("mainAxisSize", this.mainAxisSize, defaultValue: MainAxisSize.max));
properties.add(new EnumProperty<CrossAxisAlignment>("crossAxisAlignment", this.crossAxisAlignment));
properties.add(new EnumProperty<TextDirection?>("textDirection", this.textDirection, defaultValue: null));
properties.add(new EnumProperty<VerticalDirection>("verticalDirection", this.verticalDirection, defaultValue: VerticalDirection.down));
properties.add(new EnumProperty<TextBaseline?>("textBaseline", this.textBaseline, defaultValue: null));
}
}
public class Offstage : SingleChildRenderObjectWidget {

228
Runtime/widgets/editable_text.cs


using System;
using System.Collections.Generic;
using RSG;
using Unity.UIWidgets.animation;
using Unity.UIWidgets.async;
using Unity.UIWidgets.foundation;

}
}
public class EditableTextState : AutomaticKeepAliveClientMixin<EditableText>, TextInputClient,
public class EditableTextState : AutomaticKeepAliveClientMixin<EditableText>, WidgetsBindingObserver, TextInputClient,
TextSelectionDelegate {
const int _kObscureShowLatestCharCursorTicks = 3;
static TimeSpan _kCursorBlinkHalfPeriod = TimeSpan.FromMilliseconds(500);

TextSelectionOverlay _selectionOverlay;
int _obscureShowCharTicksPending = 0;
int _obscureLatestCharIndex;
bool _textChangedSinceLastCaretUpdate = false;
protected override bool wantKeepAlive {
get { return this.widget.focusNode.hasFocus; }

this._formatAndSetValue(value);
}
public TextEditingValue getValueForAction(TextInputAction operation) {
TextPosition newPosition = null;
TextPosition newExtend = null;
TextEditingValue newValue = null;
TextSelection newSelection = null;
TextPosition startPos = new TextPosition(this._value.selection.start, this._value.selection.affinity);
switch (operation) {
case TextInputAction.moveLeft:
newValue = this._value.moveLeft();
break;
case TextInputAction.moveRight:
newValue = this._value.moveRight();
break;
case TextInputAction.moveUp:
newPosition = this.renderEditable.getPositionUp(startPos);
break;
case TextInputAction.moveDown:
newPosition = this.renderEditable.getPositionDown(startPos);
break;
case TextInputAction.moveLineStart:
newPosition = this.renderEditable.getParagraphStart(startPos, TextAffinity.downstream);
break;
case TextInputAction.moveLineEnd:
newPosition = this.renderEditable.getParagraphEnd(startPos, TextAffinity.upstream);
break;
case TextInputAction.moveWordRight:
newPosition = this.renderEditable.getWordRight(startPos);
break;
case TextInputAction.moveWordLeft:
newPosition = this.renderEditable.getWordLeft(startPos);
break;
// case TextInputAction.MoveToStartOfNextWord: MoveToStartOfNextWord(); break;
// case TextInputAction.MoveToEndOfPreviousWord: MoveToEndOfPreviousWord(); break;
case TextInputAction.moveTextStart:
newPosition = new TextPosition(0);
break;
case TextInputAction.moveTextEnd:
newPosition = new TextPosition(this._value.text.Length);
break;
case TextInputAction.moveParagraphForward:
newPosition = this.renderEditable.getParagraphForward(startPos);
break;
case TextInputAction.moveParagraphBackward:
newPosition = this.renderEditable.getParagraphBackward(startPos);
break;
case TextInputAction.moveGraphicalLineStart:
newPosition = this.renderEditable.getLineStartPosition(startPos, TextAffinity.downstream);
break;
case TextInputAction.moveGraphicalLineEnd:
newPosition = this.renderEditable.getLineEndPosition(startPos, TextAffinity.upstream);
break;
case TextInputAction.selectLeft:
newValue = this._value.extendLeft();
break;
case TextInputAction.selectRight:
newValue = this._value.extendRight();
break;
case TextInputAction.selectUp:
newExtend = this.renderEditable.getPositionUp(this._value.selection.extendPos);
break;
case TextInputAction.selectDown:
newExtend = this.renderEditable.getPositionDown(this._value.selection.extendPos);
break;
case TextInputAction.selectWordRight:
newExtend = this.renderEditable.getWordRight(this._value.selection.extendPos);
break;
case TextInputAction.selectWordLeft:
newExtend = this.renderEditable.getWordLeft(this._value.selection.extendPos);
break;
// case TextInputAction.SelectToEndOfPreviousWord: SelectToEndOfPreviousWord(); break;
// case TextInputAction.SelectToStartOfNextWord: SelectToStartOfNextWord(); break;
//
case TextInputAction.selectTextStart:
newExtend = new TextPosition(0);
break;
case TextInputAction.selectTextEnd:
newExtend = new TextPosition(this._value.text.Length);
break;
case TextInputAction.expandSelectGraphicalLineStart:
if (this._value.selection.isCollapsed ||
!this.renderEditable.isLineEndOrStart(this._value.selection.start)) {
newSelection = new TextSelection(this.renderEditable.getLineStartPosition(startPos).offset,
this._value.selection.end, this._value.selection.affinity);
}
break;
case TextInputAction.expandSelectGraphicalLineEnd:
if (this._value.selection.isCollapsed ||
!this.renderEditable.isLineEndOrStart(this._value.selection.end)) {
newSelection = new TextSelection(this._value.selection.start,
this.renderEditable.getLineEndPosition(this._value.selection.endPos).offset,
this._value.selection.affinity);
}
break;
case TextInputAction.selectParagraphForward:
newExtend = this.renderEditable.getParagraphForward(this._value.selection.extendPos);
break;
case TextInputAction.selectParagraphBackward:
newExtend = this.renderEditable.getParagraphBackward(this._value.selection.extendPos);
break;
case TextInputAction.selectGraphicalLineStart:
newExtend = this.renderEditable.getLineStartPosition(this._value.selection.extendPos);
break;
case TextInputAction.selectGraphicalLineEnd:
newExtend = this.renderEditable.getLineEndPosition(startPos);
break;
case TextInputAction.delete:
newValue = this._value.deleteSelection(false);
break;
case TextInputAction.backspace:
newValue = this._value.deleteSelection();
break;
case TextInputAction.selectAll:
newSelection = this._value.selection.copyWith(baseOffset: 0, extentOffset: this._value.text.Length);
break;
}
if (newPosition != null) {
return this._value.copyWith(selection: TextSelection.fromPosition(newPosition));
}
else if (newExtend != null) {
return this._value.copyWith(selection: this._value.selection.copyWith(extentOffset: newExtend.offset));
}
else if (newSelection != null) {
return this._value.copyWith(selection: newSelection);
}
else if (newValue != null) {
return newValue;
}
return this._value;
}
TextEditingValue newValue;
switch (action) {
case TextInputAction.newline:
if (this.widget.maxLines == 1) {

case TextInputAction.search:
this._finalizeEditing(true);
break;
case TextInputAction.next:
case TextInputAction.previous:
case TextInputAction.continueAction:
case TextInputAction.join:
case TextInputAction.route:
case TextInputAction.emergencyCall:
default:
break;
default:
newValue = this.getValueForAction(action);
if (newValue != this.textEditingValue) {
this.textEditingValue = newValue;
}
break;
}
}

this._textInputConnection.setEditingState(localValue);
}
TextEditingValue _value {
get { return this.widget.controller.value; }
set { this.widget.controller.value = value; }
}
bool _hasFocus {
get { return this.widget.focusNode.hasFocus; }
}
bool _isMultiline {
get { return this.widget.maxLines != 1; }
}
// Calculate the new scroll offset so the cursor remains visible.
float _getScrollOffsetForCaret(Rect caretRect) {

}
}
bool _textChangedSinceLastCaretUpdate = false;
Rect _currentCaretRect;
void _handleCaretChanged(Rect caretRect) {

);
});
}
double _lastBottomViewInset;
public void didChangeMetrics() {
if (this._lastBottomViewInset < Window.instance.viewInsets.bottom) {
this._showCaretOnScreen();
}
this._lastBottomViewInset = Window.instance.viewInsets.bottom;
}
public void didChangeTextScaleFactor() {}
public void didChangeLocales(List<Locale> locale) {}
public IPromise<bool> didPopRoute() {
return Promise<bool>.Resolved(false);
}
public IPromise<bool> didPushRoute(string route) {
return Promise<bool>.Resolved(false);
}
void _formatAndSetValue(TextEditingValue value) {
var textChanged = (this._value == null ? null : this._value.text) != (value == null ? null : value.text);

}
}
TextEditingValue _value {
get { return this.widget.controller.value; }
set { this.widget.controller.value = value; }
}
bool _hasFocus {
get { return this.widget.focusNode.hasFocus; }
}
bool _isMultiline {
get { return this.widget.maxLines != 1; }
}
void _didChangeTextEditingValue() {
this._updateRemoteEditingValueIfNeeded();

this._openOrCloseInputConnectionIfNeeded();
this._startOrStopCursorTimerIfNeeded();
this._updateOrDisposeSelectionOverlayIfNeeded();
if (!this._hasFocus) {
this._value = new TextEditingValue(text: this._value.text);
if (this._hasFocus) {
WidgetsBinding.instance.addObserver(this);
this._lastBottomViewInset = Window.instance.viewInsets.bottom;
this._showCaretOnScreen();
if (!this._value.selection.isValid) {
this.widget.controller.selection = TextSelection.collapsed(offset: this._value.text.Length);
}
else if (!this._value.selection.isValid) {
this.widget.controller.selection = TextSelection.collapsed(offset: this._value.text.Length);
else {
WidgetsBinding.instance.removeObserver(this);
this._value = new TextEditingValue(text: this._value.text);
this.updateKeepAlive();
}

offset: offset,
onSelectionChanged: this._handleSelectionChanged,
onCaretChanged: this._handleCaretChanged,
rendererIgnoresPointer: this.widget.rendererIgnoresPointer
rendererIgnoresPointer: this.widget.rendererIgnoresPointer,
textSelectionDelegate: this
)
)
);

public readonly SelectionChangedHandler onSelectionChanged;
public readonly CaretChangedHandler onCaretChanged;
public readonly bool rendererIgnoresPointer;
public readonly TextSelectionDelegate textSelectionDelegate;
public _Editable(TextSpan textSpan = null, TextEditingValue value = null,

bool autocorrect = false, ViewportOffset offset = null, SelectionChangedHandler onSelectionChanged = null,
CaretChangedHandler onCaretChanged = null, bool rendererIgnoresPointer = false,
Key key = null) : base(key) {
Key key = null, TextSelectionDelegate textSelectionDelegate = null) : base(key) {
this.textSpan = textSpan;
this.value = value;
this.cursorColor = cursorColor;

this.onSelectionChanged = onSelectionChanged;
this.onCaretChanged = onCaretChanged;
this.rendererIgnoresPointer = rendererIgnoresPointer;
this.textSelectionDelegate = textSelectionDelegate;
}
public override RenderObject createRenderObject(BuildContext context) {

obscureText: this.obscureText,
onSelectionChanged: this.onSelectionChanged,
onCaretChanged: this.onCaretChanged,
ignorePointer: this.rendererIgnoresPointer
ignorePointer: this.rendererIgnoresPointer,
textSelectionDelegate: this.textSelectionDelegate
);
}

edit.onCaretChanged = this.onCaretChanged;
edit.ignorePointer = this.rendererIgnoresPointer;
edit.obscureText = this.obscureText;
edit.textSelectionDelegate = this.textSelectionDelegate;
}
}
}

8
Runtime/widgets/scroll_position.cs


public readonly ValueNotifier<bool> isScrollingNotifier = new ValueNotifier<bool>(false);
public override IPromise moveTo(float to, TimeSpan? duration, Curve curve = null, bool clamp = true) {
if (clamp) {
to = to.clamp(this.minScrollExtent, this.maxScrollExtent);
}
return base.moveTo(to, duration: duration, curve: curve, clamp: clamp);
}
public override bool allowImplicitScrolling {
get { return this.physics.allowImplicitScrolling; }
}

6
Samples/UIWidgetSample/MaterialSample.cs


home: this.testCases[this.testCaseId]);
}
protected override void OnEnable() {
base.OnEnable();
FontManager.instance.addFont(Resources.Load<Font>(path: "MaterialIcons-Regular"));
protected override void Awake() {
base.Awake();
FontManager.instance.addFont(Resources.Load<Font>(path: "MaterialIcons-Regular"), "Material Icons");
}
}

10
Samples/UIWidgetsGallery/GalleryMain.cs


protected override Widget createWidget() {
return new GalleryApp();
}
protected override void OnEnable() {
base.OnEnable();
FontManager.instance.addFont(Resources.Load<Font>("MaterialIcons-Regular"));
FontManager.instance.addFont(Resources.Load<Font>("GalleryIcons"));
protected override void Awake() {
base.Awake();
FontManager.instance.addFont(Resources.Load<Font>("MaterialIcons-Regular"), "Material Icons");
FontManager.instance.addFont(Resources.Load<Font>("GalleryIcons"), "GalleryIcons");
}
}
}

6
Tests/Editor/Widgets.cs


this.windowAdapter.Update();
}
void Awake() {
FontManager.instance.addFont(Resources.Load<Font>("MaterialIcons-Regular"), "Material Icons");
}
FontManager.instance.addFont(Resources.Load<Font>("MaterialIcons-Regular"));
}
void OnDisable() {

24
Third Party Notices.md


ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
Component Name: [SimpleJSON](https://wiki.unity3d.com/index.php/SimpleJSON)
License Type: MIT
Copyright (c) 2012-2017 Markus Göbel (Bunny83)
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

82
Runtime/service/raw_keyboard.cs


using System.Collections.Generic;
using Unity.UIWidgets.foundation;
using UnityEngine;
namespace Unity.UIWidgets.service {
public class RawKeyboard {
public static readonly RawKeyboard instance = new RawKeyboard();
RawKeyboard() {
}
readonly List<ValueChanged<RawKeyEvent>> _listeners = new List<ValueChanged<RawKeyEvent>>();
public void addListener(ValueChanged<RawKeyEvent> listener) {
this._listeners.Add(listener);
}
public void removeListener(ValueChanged<RawKeyEvent> listener) {
this._listeners.Remove(listener);
}
internal void _handleKeyEvent(Event evt) {
if (this._listeners.isEmpty()) {
return;
}
var keyboardEvent = RawKeyEvent.fromEvent(evt);
if (keyboardEvent == null) {
return;
}
foreach (var listener in new List<ValueChanged<RawKeyEvent>>(this._listeners)) {
if (this._listeners.Contains(listener)) {
listener(keyboardEvent);
}
}
}
}
public abstract class RawKeyEvent {
protected RawKeyEvent(RawKeyEventData data) {
this.data = data;
}
public static RawKeyEvent fromEvent(Event evt) {
if (evt == null) {
return null;
}
if (evt.type == EventType.KeyDown) {
return new RawKeyDownEvent(new RawKeyEventData(evt));
} else if (evt.type == EventType.KeyUp) {
return new RawKeyUpEvent(new RawKeyEventData(evt));
}
return null;
}
public readonly RawKeyEventData data;
}
public class RawKeyDownEvent: RawKeyEvent {
public RawKeyDownEvent(RawKeyEventData data) : base(data) {
}
}
public class RawKeyUpEvent : RawKeyEvent {
public RawKeyUpEvent(RawKeyEventData data) : base(data) {
}
}
public class RawKeyEventData {
public readonly Event unityEvent;
public RawKeyEventData(Event unityEvent) {
this.unityEvent = unityEvent;
}
}
}

11
Runtime/service/raw_keyboard.cs.meta


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

11
Runtime/ui/painting/shadow_utils.cs.meta


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

8
Samples/UIWidgetSample/txt.meta


fileFormatVersion: 2
guid: 57dc3a2ca4c5643b482cd6c4e9e545d6
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

8
Samples/UIWidgetsTheatre.meta


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

11
Samples/UIWidgetSample/txt/FontWeightStyle.cs.meta


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

68
Samples/UIWidgetSample/txt/TextSpanGesture.cs


using System.Collections.Generic;
using Unity.UIWidgets.gestures;
using Unity.UIWidgets.material;
using Unity.UIWidgets.painting;
using Unity.UIWidgets.ui;
using Unity.UIWidgets.widgets;
using UnityEngine;
using TextStyle = Unity.UIWidgets.painting.TextStyle;
namespace UIWidgetsSample {
public class TextSpanGesture : UIWidgetsSamplePanel {
protected override Widget createWidget() {
return new WidgetsApp(
home: new BuzzingText(),
pageRouteBuilder: this.pageRouteBuilder);
}
}
class BuzzingText : StatefulWidget {
public override State createState() {
return new _BuzzingTextState();
}
}
class _BuzzingTextState : State<BuzzingText> {
LongPressGestureRecognizer _longPressRecognizer;
public override void initState() {
base.initState();
this._longPressRecognizer = new LongPressGestureRecognizer();
this._longPressRecognizer.onLongPress = this._handlePress;
}
public override void dispose() {
this._longPressRecognizer.dispose();
base.dispose();
}
void _handlePress() {
Debug.Log("Long Pressed Text");
}
/*
Any professional looking app you have seen probably has multiple screens in it. It can contain a welcome screen, a login screen and then further screens.
*/
public override Widget build(BuildContext context) {
return new RichText(
text: new TextSpan(
text: "Can you ",
style: new TextStyle(color: Colors.black),
children: new List<TextSpan>() {
new TextSpan(
text: "find the",
style: new TextStyle(
color: Colors.green,
decoration: TextDecoration.underline
)
// recognizer: this._longPressRecognizer
),
new TextSpan(
text: " secret?"
)
}
));
}
}
}

11
Samples/UIWidgetSample/txt/TextSpanGesture.cs.meta


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

85
Samples/UIWidgetSample/txt/FontWeightStyle.cs


using System.Collections.Generic;
using Unity.UIWidgets.material;
using Unity.UIWidgets.ui;
using Unity.UIWidgets.widgets;
using UnityEngine;
using FontStyle = Unity.UIWidgets.ui.FontStyle;
using TextStyle = Unity.UIWidgets.painting.TextStyle;
namespace UIWidgetsSample {
public class FontWeightStyle : UIWidgetsSamplePanel {
protected override void Awake() {
base.Awake();
// To run this sample, you need to download Roboto fonts and place them under Resources/Fonts folder
// Roboto fonts could be downloaded from google website
// https://fonts.google.com/specimen/Roboto?selection.family=Roboto
FontManager.instance.addFont(Resources.Load<Font>(path: "MaterialIcons-Regular"), "Material Icons");
FontManager.instance.addFont(Resources.Load<Font>(path: "Fonts/Roboto-Black"), "Roboto",
FontWeight.w900);
FontManager.instance.addFont(Resources.Load<Font>(path: "Fonts/Roboto-BlackItalic"), "Roboto",
FontWeight.w900, FontStyle.italic);
FontManager.instance.addFont(Resources.Load<Font>(path: "Fonts/Roboto-Bold"), "Roboto",
FontWeight.bold);
FontManager.instance.addFont(Resources.Load<Font>(path: "Fonts/Roboto-BoldItalic"), "Roboto",
FontWeight.bold, FontStyle.italic);
FontManager.instance.addFont(Resources.Load<Font>(path: "Fonts/Roboto-Regular"), "Roboto",
FontWeight.normal);
FontManager.instance.addFont(Resources.Load<Font>(path: "Fonts/Roboto-Italic"), "Roboto",
FontWeight.normal, FontStyle.italic);
FontManager.instance.addFont(Resources.Load<Font>(path: "Fonts/Roboto-Medium"), "Roboto",
FontWeight.w500);
FontManager.instance.addFont(Resources.Load<Font>(path: "Fonts/Roboto-MediumItalic"), "Roboto",
FontWeight.w500, FontStyle.italic);
FontManager.instance.addFont(Resources.Load<Font>(path: "Fonts/Roboto-Light"), "Roboto",
FontWeight.w300);
FontManager.instance.addFont(Resources.Load<Font>(path: "Fonts/Roboto-LightItalic"), "Roboto",
FontWeight.w300, FontStyle.italic);
FontManager.instance.addFont(Resources.Load<Font>(path: "Fonts/Roboto-Thin"), "Roboto",
FontWeight.w100);
FontManager.instance.addFont(Resources.Load<Font>(path: "Fonts/Roboto-ThinItalic"), "Roboto",
FontWeight.w100, FontStyle.italic);
}
protected override Widget createWidget() {
return new MaterialApp(
title: "Navigation Basics",
home: new FontWeightStyleWidget()
);
}
}
class FontWeightStyleWidget : StatelessWidget {
public override Widget build(BuildContext context) {
var fontStyleTexts = new List<Widget> {
new Text("Thin", style: new TextStyle(fontWeight: FontWeight.w100)),
new Text("Thin Italic", style: new TextStyle(fontWeight: FontWeight.w100,
fontStyle: FontStyle.italic)),
new Text("Light", style: new TextStyle(fontWeight: FontWeight.w300)),
new Text("Light Italic", style: new TextStyle(fontWeight: FontWeight.w300,
fontStyle: FontStyle.italic)),
new Text("Regular", style: new TextStyle(fontWeight: FontWeight.normal)),
new Text("Regular Italic", style: new TextStyle(fontWeight: FontWeight.normal,
fontStyle: FontStyle.italic)),
new Text("Medium", style: new TextStyle(fontWeight: FontWeight.w500)),
new Text("Medium Italic", style: new TextStyle(fontWeight: FontWeight.w500,
fontStyle: FontStyle.italic)),
new Text("Bold", style: new TextStyle(fontWeight: FontWeight.bold)),
new Text("Bold Italic", style: new TextStyle(fontWeight: FontWeight.bold,
fontStyle: FontStyle.italic)),
new Text("Black", style: new TextStyle(fontWeight: FontWeight.w900)),
new Text("Black Italic", style: new TextStyle(fontWeight: FontWeight.w900,
fontStyle: FontStyle.italic)),
};
return new Scaffold(
appBar: new AppBar(
title: new Text("Font weight & style")
),
body: new Card(
child: new DefaultTextStyle(
style: new TextStyle(fontSize: 40, fontFamily: "Roboto"),
child: new ListView(children: fontStyleTexts))
)
);
}
}
}

61
Samples/UIWidgetsTheatre/UIWidgetsTheatre.cs


using System.Collections.Generic;
using Unity.UIWidgets.material;
using Unity.UIWidgets.ui;
using Unity.UIWidgets.widgets;
using UnityEditor;
using UnityEditor.UI;
using UnityEngine;
namespace UIWidgetsSample {
class TheatreEntry {
public string entryName;
public Widget entryWidget;
}
class UIWidgetsTheatre : UIWidgetsSamplePanel {
static readonly List<TheatreEntry> entries = new List<TheatreEntry> {
new TheatreEntry{entryName = "Material App Bar", entryWidget = new MaterialAppBarWidget()},
new TheatreEntry{entryName = "Material Tab Bar" , entryWidget = new MaterialTabBarWidget()}
};
public static string[] entryKeys {
get {
List<string> ret = new List<string>();
foreach (var entry in entries) {
ret.Add(entry.entryName);
}
return ret.ToArray();
}
}
[SerializeField] public int testCaseId;
protected override Widget createWidget() {
return new MaterialApp(
showPerformanceOverlay: false,
home: entries[this.testCaseId].entryWidget);
}
protected override void OnEnable() {
base.OnEnable();
FontManager.instance.addFont(Resources.Load<Font>(path: "MaterialIcons-Regular"));
}
}
[CustomEditor(typeof(UIWidgetsTheatre), true)]
[CanEditMultipleObjects]
public class UIWidgetTheatreEditor : RawImageEditor {
int _choiceIndex;
public override void OnInspectorGUI() {
var materialSample = this.target as UIWidgetsTheatre;
this._choiceIndex = EditorGUILayout.Popup("Test Case", materialSample.testCaseId, UIWidgetsTheatre.entryKeys);
materialSample.testCaseId = this._choiceIndex;
EditorUtility.SetDirty(this.target);
}
}
}

11
Samples/UIWidgetsTheatre/UIWidgetsTheatre.cs.meta


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

468
Samples/UIWidgetsTheatre/UIWidgetsTheatre.unity


%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!29 &1
OcclusionCullingSettings:
m_ObjectHideFlags: 0
serializedVersion: 2
m_OcclusionBakeSettings:
smallestOccluder: 5
smallestHole: 0.25
backfaceThreshold: 100
m_SceneGUID: 00000000000000000000000000000000
m_OcclusionCullingData: {fileID: 0}
--- !u!104 &2
RenderSettings:
m_ObjectHideFlags: 0
serializedVersion: 9
m_Fog: 0
m_FogColor: {r: 0.5, g: 0.5, b: 0.5, a: 1}
m_FogMode: 3
m_FogDensity: 0.01
m_LinearFogStart: 0
m_LinearFogEnd: 300
m_AmbientSkyColor: {r: 0.212, g: 0.227, b: 0.259, a: 1}
m_AmbientEquatorColor: {r: 0.114, g: 0.125, b: 0.133, a: 1}
m_AmbientGroundColor: {r: 0.047, g: 0.043, b: 0.035, a: 1}
m_AmbientIntensity: 1
m_AmbientMode: 0
m_SubtractiveShadowColor: {r: 0.42, g: 0.478, b: 0.627, a: 1}
m_SkyboxMaterial: {fileID: 10304, guid: 0000000000000000f000000000000000, type: 0}
m_HaloStrength: 0.5
m_FlareStrength: 1
m_FlareFadeSpeed: 3
m_HaloTexture: {fileID: 0}
m_SpotCookie: {fileID: 10001, guid: 0000000000000000e000000000000000, type: 0}
m_DefaultReflectionMode: 0
m_DefaultReflectionResolution: 128
m_ReflectionBounces: 1
m_ReflectionIntensity: 1
m_CustomReflection: {fileID: 0}
m_Sun: {fileID: 0}
m_IndirectSpecularColor: {r: 0.44657898, g: 0.49641287, b: 0.5748173, a: 1}
m_UseRadianceAmbientProbe: 0
--- !u!157 &3
LightmapSettings:
m_ObjectHideFlags: 0
serializedVersion: 11
m_GIWorkflowMode: 0
m_GISettings:
serializedVersion: 2
m_BounceScale: 1
m_IndirectOutputScale: 1
m_AlbedoBoost: 1
m_EnvironmentLightingMode: 0
m_EnableBakedLightmaps: 1
m_EnableRealtimeLightmaps: 1
m_LightmapEditorSettings:
serializedVersion: 10
m_Resolution: 2
m_BakeResolution: 40
m_AtlasSize: 1024
m_AO: 0
m_AOMaxDistance: 1
m_CompAOExponent: 1
m_CompAOExponentDirect: 0
m_Padding: 2
m_LightmapParameters: {fileID: 0}
m_LightmapsBakeMode: 1
m_TextureCompression: 1
m_FinalGather: 0
m_FinalGatherFiltering: 1
m_FinalGatherRayCount: 256
m_ReflectionCompression: 2
m_MixedBakeMode: 2
m_BakeBackend: 1
m_PVRSampling: 1
m_PVRDirectSampleCount: 32
m_PVRSampleCount: 500
m_PVRBounces: 2
m_PVRFilterTypeDirect: 0
m_PVRFilterTypeIndirect: 0
m_PVRFilterTypeAO: 0
m_PVRFilteringMode: 1
m_PVRCulling: 1
m_PVRFilteringGaussRadiusDirect: 1
m_PVRFilteringGaussRadiusIndirect: 5
m_PVRFilteringGaussRadiusAO: 2
m_PVRFilteringAtrousPositionSigmaDirect: 0.5
m_PVRFilteringAtrousPositionSigmaIndirect: 2
m_PVRFilteringAtrousPositionSigmaAO: 1
m_ShowResolutionOverlay: 1
m_LightingDataAsset: {fileID: 0}
m_UseShadowmask: 1
--- !u!196 &4
NavMeshSettings:
serializedVersion: 2
m_ObjectHideFlags: 0
m_BuildSettings:
serializedVersion: 2
agentTypeID: 0
agentRadius: 0.5
agentHeight: 2
agentSlope: 45
agentClimb: 0.4
ledgeDropHeight: 0
maxJumpAcrossDistance: 0
minRegionArea: 2
manualCellSize: 0
cellSize: 0.16666667
manualTileSize: 0
tileSize: 256
accuratePlacement: 0
debug:
m_Flags: 0
m_NavMeshData: {fileID: 0}
--- !u!1 &314914769
GameObject:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
serializedVersion: 6
m_Component:
- component: {fileID: 314914773}
- component: {fileID: 314914772}
- component: {fileID: 314914771}
- component: {fileID: 314914770}
- component: {fileID: 314914775}
- component: {fileID: 314914774}
m_Layer: 5
m_Name: Canvas
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!114 &314914770
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 314914769}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 1301386320, guid: f70555f144d8491a825f0804e09c671c, type: 3}
m_Name:
m_EditorClassIdentifier:
m_IgnoreReversedGraphics: 1
m_BlockingObjects: 0
m_BlockingMask:
serializedVersion: 2
m_Bits: 4294967295
--- !u!114 &314914771
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 314914769}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 1980459831, guid: f70555f144d8491a825f0804e09c671c, type: 3}
m_Name:
m_EditorClassIdentifier:
m_UiScaleMode: 0
m_ReferencePixelsPerUnit: 100
m_ScaleFactor: 1
m_ReferenceResolution: {x: 800, y: 600}
m_ScreenMatchMode: 0
m_MatchWidthOrHeight: 0
m_PhysicalUnit: 3
m_FallbackScreenDPI: 96
m_DefaultSpriteDPI: 96
m_DynamicPixelsPerUnit: 1
--- !u!223 &314914772
Canvas:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 314914769}
m_Enabled: 1
serializedVersion: 3
m_RenderMode: 0
m_Camera: {fileID: 0}
m_PlaneDistance: 100
m_PixelPerfect: 0
m_ReceivesEvents: 1
m_OverrideSorting: 0
m_OverridePixelPerfect: 0
m_SortingBucketNormalizedSize: 0
m_AdditionalShaderChannelsFlag: 0
m_SortingLayerID: 0
m_SortingOrder: 0
m_TargetDisplay: 0
--- !u!224 &314914773
RectTransform:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 314914769}
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
m_LocalPosition: {x: 0, y: 0, z: 0}
m_LocalScale: {x: 0, y: 0, z: 0}
m_Children: []
m_Father: {fileID: 0}
m_RootOrder: 2
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_AnchorMin: {x: 0, y: 0}
m_AnchorMax: {x: 0, y: 0}
m_AnchoredPosition: {x: 0, y: 0}
m_SizeDelta: {x: 0, y: 0}
m_Pivot: {x: 0, y: 0}
--- !u!114 &314914774
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 314914769}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 3ace0d3c7f55946559f1497f0fbf6025, type: 3}
m_Name:
m_EditorClassIdentifier:
m_Material: {fileID: 0}
m_Color: {r: 1, g: 1, b: 1, a: 1}
m_RaycastTarget: 1
m_OnCullStateChanged:
m_PersistentCalls:
m_Calls: []
m_TypeName: UnityEngine.UI.MaskableGraphic+CullStateChangedEvent, UnityEngine.UI,
Version=1.0.0.0, Culture=neutral, PublicKeyToken=null
m_Texture: {fileID: 0}
m_UVRect:
serializedVersion: 2
x: 0
y: 0
width: 1
height: 1
devicePixelRatioOverride: 0
testCaseId: 0
--- !u!222 &314914775
CanvasRenderer:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 314914769}
m_CullTransparentMesh: 0
--- !u!1 &1040325770
GameObject:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
serializedVersion: 6
m_Component:
- component: {fileID: 1040325773}
- component: {fileID: 1040325772}
- component: {fileID: 1040325771}
m_Layer: 0
m_Name: EventSystem
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!114 &1040325771
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 1040325770}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 1077351063, guid: f70555f144d8491a825f0804e09c671c, type: 3}
m_Name:
m_EditorClassIdentifier:
m_HorizontalAxis: Horizontal
m_VerticalAxis: Vertical
m_SubmitButton: Submit
m_CancelButton: Cancel
m_InputActionsPerSecond: 10
m_RepeatDelay: 0.5
m_ForceModuleActive: 0
--- !u!114 &1040325772
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 1040325770}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: -619905303, guid: f70555f144d8491a825f0804e09c671c, type: 3}
m_Name:
m_EditorClassIdentifier:
m_FirstSelected: {fileID: 0}
m_sendNavigationEvents: 1
m_DragThreshold: 10
--- !u!4 &1040325773
Transform:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 1040325770}
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
m_LocalPosition: {x: 0, y: 0, z: 0}
m_LocalScale: {x: 1, y: 1, z: 1}
m_Children: []
m_Father: {fileID: 0}
m_RootOrder: 3
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
--- !u!1 &1125362302
GameObject:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
serializedVersion: 6
m_Component:
- component: {fileID: 1125362304}
- component: {fileID: 1125362303}
m_Layer: 0
m_Name: Directional Light
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!108 &1125362303
Light:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 1125362302}
m_Enabled: 1
serializedVersion: 8
m_Type: 1
m_Color: {r: 1, g: 0.95686275, b: 0.8392157, a: 1}
m_Intensity: 1
m_Range: 10
m_SpotAngle: 30
m_CookieSize: 10
m_Shadows:
m_Type: 2
m_Resolution: -1
m_CustomResolution: -1
m_Strength: 1
m_Bias: 0.05
m_NormalBias: 0.4
m_NearPlane: 0.2
m_Cookie: {fileID: 0}
m_DrawHalo: 0
m_Flare: {fileID: 0}
m_RenderMode: 0
m_CullingMask:
serializedVersion: 2
m_Bits: 4294967295
m_Lightmapping: 4
m_LightShadowCasterMode: 0
m_AreaSize: {x: 1, y: 1}
m_BounceIntensity: 1
m_ColorTemperature: 6570
m_UseColorTemperature: 0
m_ShadowRadius: 0
m_ShadowAngle: 0
--- !u!4 &1125362304
Transform:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 1125362302}
m_LocalRotation: {x: 0.40821788, y: -0.23456968, z: 0.10938163, w: 0.8754261}
m_LocalPosition: {x: 0, y: 3, z: 0}
m_LocalScale: {x: 1, y: 1, z: 1}
m_Children: []
m_Father: {fileID: 0}
m_RootOrder: 1
m_LocalEulerAnglesHint: {x: 50, y: -30, z: 0}
--- !u!1 &1814350050
GameObject:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
serializedVersion: 6
m_Component:
- component: {fileID: 1814350053}
- component: {fileID: 1814350052}
- component: {fileID: 1814350051}
m_Layer: 0
m_Name: Main Camera
m_TagString: MainCamera
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!81 &1814350051
AudioListener:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 1814350050}
m_Enabled: 1
--- !u!20 &1814350052
Camera:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 1814350050}
m_Enabled: 1
serializedVersion: 2
m_ClearFlags: 1
m_BackGroundColor: {r: 0.19215687, g: 0.3019608, b: 0.4745098, a: 0}
m_projectionMatrixMode: 1
m_SensorSize: {x: 36, y: 24}
m_LensShift: {x: 0, y: 0}
m_GateFitMode: 2
m_FocalLength: 50
m_NormalizedViewPortRect:
serializedVersion: 2
x: 0
y: 0
width: 1
height: 1
near clip plane: 0.3
far clip plane: 1000
field of view: 60
orthographic: 0
orthographic size: 5
m_Depth: -1
m_CullingMask:
serializedVersion: 2
m_Bits: 4294967295
m_RenderingPath: -1
m_TargetTexture: {fileID: 0}
m_TargetDisplay: 0
m_TargetEye: 3
m_HDR: 1
m_AllowMSAA: 1
m_AllowDynamicResolution: 0
m_ForceIntoRT: 0
m_OcclusionCulling: 1
m_StereoConvergence: 10
m_StereoSeparation: 0.022
--- !u!4 &1814350053
Transform:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 1814350050}
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
m_LocalPosition: {x: 0, y: 1, z: -10}
m_LocalScale: {x: 1, y: 1, z: 1}
m_Children: []
m_Father: {fileID: 0}
m_RootOrder: 0
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}

7
Samples/UIWidgetsTheatre/UIWidgetsTheatre.unity.meta


fileFormatVersion: 2
guid: 98c373eb224884f5f9606a9eefe03de7
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

11
Runtime/service/text_input_utils.cs.meta


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

153
Runtime/service/text_input_utils.cs


using System.Collections.Generic;
using UnityEngine;
namespace Unity.UIWidgets.service {
static partial class TextInputUtils {
static Dictionary<Event, TextInputAction> _keyToOperations;
public static TextInputAction? getInputAction(Event evt) {
if (_keyToOperations == null) {
initKeyToOperations();
}
EventModifiers m = evt.modifiers;
evt.modifiers &= ~EventModifiers.CapsLock;
TextInputAction result;
var exists = _keyToOperations.TryGetValue(evt, out result);
evt.modifiers = m;
if (exists) {
return result;
}
return null;
}
public static void initKeyToOperations() {
if (_keyToOperations != null) {
return;
}
_keyToOperations = new Dictionary<Event, TextInputAction>();
// key mappings shared by the platforms
mapKey("return", TextInputAction.newline);
mapKey("left", TextInputAction.moveLeft);
mapKey("right", TextInputAction.moveRight);
mapKey("up", TextInputAction.moveUp);
mapKey("down", TextInputAction.moveDown);
mapKey("#left", TextInputAction.selectLeft);
mapKey("#right", TextInputAction.selectRight);
mapKey("#up", TextInputAction.selectUp);
mapKey("#down", TextInputAction.selectDown);
mapKey("delete", TextInputAction.delete);
mapKey("backspace", TextInputAction.backspace);
mapKey("#backspace", TextInputAction.backspace);
// OSX is the special case for input shortcuts
if (SystemInfo.operatingSystemFamily == OperatingSystemFamily.MacOSX) {
// Keyboard mappings for mac
// TODO mapKey ("home", TextInputAction.scrollStart);
// TODO mapKey ("end", TextInputAction.scrollEnd);
// TODO mapKey ("page up", TextInputAction.scrollPageUp);
// TODO mapKey ("page down", TextInputAction.scrollPageDown);
mapKey("^left", TextInputAction.moveGraphicalLineStart);
mapKey("^right", TextInputAction.moveGraphicalLineEnd);
// TODO mapKey ("^up", TextInputAction.scrollPageUp);
// TODO mapKey ("^down", TextInputAction.scrollPageDown);
mapKey("&left", TextInputAction.moveWordLeft);
mapKey("&right", TextInputAction.moveWordRight);
mapKey("&up", TextInputAction.moveParagraphBackward);
mapKey("&down", TextInputAction.moveParagraphForward);
mapKey("%left", TextInputAction.moveGraphicalLineStart);
mapKey("%right", TextInputAction.moveGraphicalLineEnd);
mapKey("%up", TextInputAction.moveTextStart);
mapKey("%down", TextInputAction.moveTextEnd);
mapKey("#home", TextInputAction.selectTextStart);
mapKey("#end", TextInputAction.selectTextEnd);
// TODO mapKey ("#page up", TextInputAction.selectPageUp);
// TODO mapKey ("#page down", TextInputAction.selectPageDown);
mapKey("#^left", TextInputAction.expandSelectGraphicalLineStart);
mapKey("#^right", TextInputAction.expandSelectGraphicalLineEnd);
mapKey("#^up", TextInputAction.selectParagraphBackward);
mapKey("#^down", TextInputAction.selectParagraphForward);
mapKey("#&left", TextInputAction.selectWordLeft);
mapKey("#&right", TextInputAction.selectWordRight);
mapKey("#&up", TextInputAction.selectParagraphBackward);
mapKey("#&down", TextInputAction.selectParagraphForward);
mapKey("#%left", TextInputAction.expandSelectGraphicalLineStart);
mapKey("#%right", TextInputAction.expandSelectGraphicalLineEnd);
mapKey("#%up", TextInputAction.selectTextStart);
mapKey("#%down", TextInputAction.selectTextEnd);
mapKey("%a", TextInputAction.selectAll);
mapKey("%x", TextInputAction.cut);
mapKey("%c", TextInputAction.copy);
mapKey("%v", TextInputAction.paste);
// emacs-like keybindings
mapKey("^d", TextInputAction.delete);
mapKey("^h", TextInputAction.backspace);
mapKey("^b", TextInputAction.moveLeft);
mapKey("^f", TextInputAction.moveRight);
mapKey("^a", TextInputAction.moveLineStart);
mapKey("^e", TextInputAction.moveLineEnd);
mapKey("&delete", TextInputAction.deleteWordForward);
mapKey("&backspace", TextInputAction.deleteWordBack);
mapKey("%backspace", TextInputAction.deleteLineBack);
}
else {
// Windows/Linux keymappings
mapKey("home", TextInputAction.moveGraphicalLineStart);
mapKey("end", TextInputAction.moveGraphicalLineEnd);
// TODO mapKey ("page up", TextInputAction.movePageUp);
// TODO mapKey ("page down", TextInputAction.movePageDown);
mapKey("%left", TextInputAction.moveWordLeft);
mapKey("%right", TextInputAction.moveWordRight);
mapKey("%up", TextInputAction.moveParagraphBackward);
mapKey("%down", TextInputAction.moveParagraphForward);
mapKey("^left", TextInputAction.moveToEndOfPreviousWord);
mapKey("^right", TextInputAction.moveToStartOfNextWord);
mapKey("^up", TextInputAction.moveParagraphBackward);
mapKey("^down", TextInputAction.moveParagraphForward);
mapKey("#^left", TextInputAction.selectToEndOfPreviousWord);
mapKey("#^right", TextInputAction.selectToStartOfNextWord);
mapKey("#^up", TextInputAction.selectParagraphBackward);
mapKey("#^down", TextInputAction.selectParagraphForward);
mapKey("#home", TextInputAction.selectGraphicalLineStart);
mapKey("#end", TextInputAction.selectGraphicalLineEnd);
// TODO mapKey ("#page up", TextInputAction.selectPageUp);
// TODO mapKey ("#page down", TextInputAction.selectPageDown);
mapKey("^delete", TextInputAction.deleteWordForward);
mapKey("^backspace", TextInputAction.deleteWordBack);
mapKey("%backspace", TextInputAction.deleteLineBack);
mapKey("^a", TextInputAction.selectAll);
mapKey("^x", TextInputAction.cut);
mapKey("^c", TextInputAction.copy);
mapKey("^v", TextInputAction.paste);
mapKey("#delete", TextInputAction.cut);
mapKey("^insert", TextInputAction.copy);
mapKey("#insert", TextInputAction.paste);
}
}
static void mapKey(string key, TextInputAction action) {
_keyToOperations[Event.KeyboardEvent(key)] = action;
}
}
}
正在加载...
取消
保存