浏览代码

Move the package content into `com.unity.uiwidgets` folder.

/main
Vincent Zhang 4 年前
当前提交
81c1d349
共有 89 个文件被更改,包括 3274 次插入3613 次删除
  1. 4
      com.unity.uiwidgets/Runtime/widgets/banner.cs.meta
  2. 4
      com.unity.uiwidgets/Runtime/widgets/basic.cs.meta
  3. 4
      com.unity.uiwidgets/Runtime/widgets/binding.cs.meta
  4. 4
      com.unity.uiwidgets/Runtime/widgets/bottom_navigation_bar_item.cs.meta
  5. 4
      com.unity.uiwidgets/Runtime/widgets/container.cs.meta
  6. 4
      com.unity.uiwidgets/Runtime/widgets/dismissible.cs.meta
  7. 4
      com.unity.uiwidgets/Runtime/widgets/form.cs.meta
  8. 4
      com.unity.uiwidgets/Runtime/widgets/heroes.cs.meta
  9. 4
      com.unity.uiwidgets/Runtime/widgets/image.cs.meta
  10. 4
      com.unity.uiwidgets/Runtime/widgets/overscroll_indicator.cs.meta
  11. 4
      com.unity.uiwidgets/Runtime/widgets/sliver_persistent_header.cs.meta
  12. 4
      com.unity.uiwidgets/Runtime/widgets/ticker_provider.cs.meta
  13. 124
      com.unity.uiwidgets/Runtime/widgets/value_listenable_builder.cs
  14. 4
      com.unity.uiwidgets/Runtime/widgets/visibility.cs.meta
  15. 4
      com.unity.uiwidgets/Runtime/widgets/will_pop_scope.cs.meta
  16. 1001
      com.unity.uiwidgets/Runtime/ui/txt/emoji.cs
  17. 564
      com.unity.uiwidgets/Runtime/ui/txt/layout.cs
  18. 694
      com.unity.uiwidgets/Runtime/ui/txt/linebreaker.cs
  19. 4
      com.unity.uiwidgets/Runtime/ui/painting/image.cs.meta
  20. 192
      com.unity.uiwidgets/Runtime/ui/painting/txt/text_blob.cs
  21. 8
      com.unity.uiwidgets/Runtime/rendering/debug.cs
  22. 4
      com.unity.uiwidgets/Runtime/rendering/error.cs.meta
  23. 4
      com.unity.uiwidgets/Runtime/rendering/image.cs.meta
  24. 4
      com.unity.uiwidgets/Runtime/rendering/rotated_box.cs.meta
  25. 4
      com.unity.uiwidgets/Runtime/rendering/sliver_persistent_header.cs.meta
  26. 4
      com.unity.uiwidgets/Runtime/rendering/wrap.cs.meta
  27. 4
      com.unity.uiwidgets/Runtime/promise/EnumerableExt.cs.meta
  28. 4
      com.unity.uiwidgets/Runtime/promise/Promise.cs.meta
  29. 4
      com.unity.uiwidgets/Runtime/promise/PromiseException.cs.meta
  30. 4
      com.unity.uiwidgets/Runtime/promise/PromiseHelpers.cs.meta
  31. 4
      com.unity.uiwidgets/Runtime/promise/PromiseStateException.cs.meta
  32. 4
      com.unity.uiwidgets/Runtime/promise/PromiseTimer.cs.meta
  33. 4
      com.unity.uiwidgets/Runtime/promise/Promise_NonGeneric.cs.meta
  34. 4
      com.unity.uiwidgets/Runtime/promise/Tuple.cs.meta
  35. 4
      com.unity.uiwidgets/Runtime/painting/box_fit.cs.meta
  36. 4
      com.unity.uiwidgets/Runtime/painting/image_cache.cs.meta
  37. 4
      com.unity.uiwidgets/Runtime/painting/image_provider.cs.meta
  38. 4
      com.unity.uiwidgets/Runtime/painting/image_stream.cs.meta
  39. 4
      com.unity.uiwidgets/Runtime/painting/notched_shapes.cs.meta
  40. 438
      com.unity.uiwidgets/Runtime/painting/strut_style.cs
  41. 4
      com.unity.uiwidgets/Runtime/material/app_bar_theme.cs.meta
  42. 4
      com.unity.uiwidgets/Runtime/material/bottom_app_bar.cs.meta
  43. 4
      com.unity.uiwidgets/Runtime/material/bottom_app_bar_theme.cs.meta
  44. 4
      com.unity.uiwidgets/Runtime/material/bottom_navigation_bar.cs.meta
  45. 4
      com.unity.uiwidgets/Runtime/material/card_theme.cs.meta
  46. 4
      com.unity.uiwidgets/Runtime/material/chip.cs.meta
  47. 4
      com.unity.uiwidgets/Runtime/material/chip_theme.cs.meta
  48. 4
      com.unity.uiwidgets/Runtime/material/circle_avatar.cs.meta
  49. 4
      com.unity.uiwidgets/Runtime/material/dropdown.cs.meta
  50. 256
      com.unity.uiwidgets/Runtime/material/floatting_action_button_theme.cs
  51. 4
      com.unity.uiwidgets/Runtime/material/input_border.cs.meta
  52. 4
      com.unity.uiwidgets/Runtime/material/input_decorator.cs.meta
  53. 4
      com.unity.uiwidgets/Runtime/material/outline_button.cs.meta
  54. 4
      com.unity.uiwidgets/Runtime/material/progress_indicator.cs.meta
  55. 4
      com.unity.uiwidgets/Runtime/material/radio.cs.meta
  56. 4
      com.unity.uiwidgets/Runtime/material/refresh_indicator.cs.meta
  57. 4
      com.unity.uiwidgets/Runtime/material/text_form_field.cs.meta
  58. 4
      com.unity.uiwidgets/Runtime/material/user_accounts_drawer_header.cs.meta
  59. 4
      com.unity.uiwidgets/Runtime/material/animated_icons/animated_icons_data.cs.meta
  60. 4
      com.unity.uiwidgets/Runtime/material/animated_icons/data/arrow_menu.g.cs.meta
  61. 4
      com.unity.uiwidgets/Runtime/material/animated_icons/data/close_menu.g.cs.meta
  62. 4
      com.unity.uiwidgets/Runtime/foundation/constants.cs.meta
  63. 406
      com.unity.uiwidgets/Runtime/cupertino/bottom_app_bar.cs
  64. 1001
      com.unity.uiwidgets/Runtime/cupertino/nav_bar.cs
  65. 758
      com.unity.uiwidgets/Runtime/cupertino/slider.cs
  66. 440
      com.unity.uiwidgets/Runtime/cupertino/tab_scaffold.cs
  67. 789
      com.unity.uiwidgets/Runtime/Plugins/platform/ios/UIWidgetsTextInputPlugin.mm
  68. 0
      /com.unity.uiwidgets/.npmignore
  69. 0
      /com.unity.uiwidgets/CHANGELOG.md
  70. 0
      /com.unity.uiwidgets/CHANGELOG.md.meta
  71. 0
      /com.unity.uiwidgets/Documentation~
  72. 0
      /com.unity.uiwidgets/Editor.meta
  73. 0
      /com.unity.uiwidgets/Editor
  74. 0
      /com.unity.uiwidgets/LICENSE.md
  75. 0
      /com.unity.uiwidgets/LICENSE.md.meta
  76. 0
      /com.unity.uiwidgets/QAReport.md
  77. 0
      /com.unity.uiwidgets/QAReport.md.meta
  78. 0
      /com.unity.uiwidgets/Runtime.meta
  79. 0
      /com.unity.uiwidgets/Third Party Notices.md
  80. 0
      /com.unity.uiwidgets/Third Party Notices.md.meta
  81. 0
      /com.unity.uiwidgets/package.json
  82. 0
      /com.unity.uiwidgets/package.json.meta
  83. 0
      /com.unity.uiwidgets/scripts.meta
  84. 0
      /com.unity.uiwidgets/.editorconfig
  85. 0
      /com.unity.uiwidgets/UIWidgetCleanupPlugin.DotSettings.meta
  86. 0
      /com.unity.uiwidgets/UIWidgetCleanupPlugin.DotSettings
  87. 0
      /com.unity.uiwidgets/Scripts
  88. 0
      /com.unity.uiwidgets/Runtime

4
com.unity.uiwidgets/Runtime/widgets/banner.cs.meta


fileFormatVersion: 2
guid: e2e859ca92594b5d98bcce5ce505ca7b
fileFormatVersion: 2
guid: e2e859ca92594b5d98bcce5ce505ca7b
timeCreated: 1552882905

4
com.unity.uiwidgets/Runtime/widgets/basic.cs.meta


fileFormatVersion: 2
guid: 69241aaa538e4e2baa651ffa39d6f355
fileFormatVersion: 2
guid: 69241aaa538e4e2baa651ffa39d6f355
timeCreated: 1536564821

4
com.unity.uiwidgets/Runtime/widgets/binding.cs.meta


fileFormatVersion: 2
guid: 39d3379616cb4c64afdedd889e3ac2a2
fileFormatVersion: 2
guid: 39d3379616cb4c64afdedd889e3ac2a2
timeCreated: 1536213633

4
com.unity.uiwidgets/Runtime/widgets/bottom_navigation_bar_item.cs.meta


fileFormatVersion: 2
guid: 7000f1f897684e08a0831ca5d920589f
fileFormatVersion: 2
guid: 7000f1f897684e08a0831ca5d920589f
timeCreated: 1553162159

4
com.unity.uiwidgets/Runtime/widgets/container.cs.meta


fileFormatVersion: 2
guid: 7c96e4ace3a14122bc2107afe55771da
fileFormatVersion: 2
guid: 7c96e4ace3a14122bc2107afe55771da
timeCreated: 1536831109

4
com.unity.uiwidgets/Runtime/widgets/dismissible.cs.meta


fileFormatVersion: 2
guid: abd926e0982c44ca80edbb282a52b90b
fileFormatVersion: 2
guid: abd926e0982c44ca80edbb282a52b90b
timeCreated: 1552033946

4
com.unity.uiwidgets/Runtime/widgets/form.cs.meta


fileFormatVersion: 2
guid: 3ce8dad5676b40ec862b142dd03b9f64
fileFormatVersion: 2
guid: 3ce8dad5676b40ec862b142dd03b9f64
timeCreated: 1552545243

4
com.unity.uiwidgets/Runtime/widgets/heroes.cs.meta


fileFormatVersion: 2
guid: ae21d125110c4c989fd2ce9e5a0bc1c0
fileFormatVersion: 2
guid: ae21d125110c4c989fd2ce9e5a0bc1c0
timeCreated: 1554263028

4
com.unity.uiwidgets/Runtime/widgets/image.cs.meta


fileFormatVersion: 2
guid: d1d313d74f6044198caad151f52721b8
fileFormatVersion: 2
guid: d1d313d74f6044198caad151f52721b8
timeCreated: 1536219326

4
com.unity.uiwidgets/Runtime/widgets/overscroll_indicator.cs.meta


fileFormatVersion: 2
guid: b87c58140c4b442e82a27b804f8502c7
fileFormatVersion: 2
guid: b87c58140c4b442e82a27b804f8502c7
timeCreated: 1554348404

4
com.unity.uiwidgets/Runtime/widgets/sliver_persistent_header.cs.meta


fileFormatVersion: 2
guid: 1e795962fe2d4c3291bbbe4bb1146a80
fileFormatVersion: 2
guid: 1e795962fe2d4c3291bbbe4bb1146a80
timeCreated: 1553067038

4
com.unity.uiwidgets/Runtime/widgets/ticker_provider.cs.meta


fileFormatVersion: 2
guid: aa6922a60d7945ffb3b92dede5941836
fileFormatVersion: 2
guid: aa6922a60d7945ffb3b92dede5941836
timeCreated: 1536807803

124
com.unity.uiwidgets/Runtime/widgets/value_listenable_builder.cs


using Unity.UIWidgets.foundation;
namespace Unity.UIWidgets.widgets {
public delegate Widget ValueWidgetBuilder<T>(BuildContext context, T value, Widget child);
public class ValueListenableBuilder<T> : StatefulWidget {
public ValueListenableBuilder(
ValueListenable<T> valueListenable,
ValueWidgetBuilder<T> builder,
Widget child = null
) {
D.assert(valueListenable != null);
D.assert(builder != null);
this.valueListenable = valueListenable;
this.builder = builder;
this.child = child;
}
public readonly ValueListenable<T> valueListenable;
public readonly ValueWidgetBuilder<T> builder;
public readonly Widget child;
public override State createState() {
return new _ValueListenableBuilderState<T>();
}
}
class _ValueListenableBuilderState<T> : State<ValueListenableBuilder<T>> {
T value;
public override void initState() {
base.initState();
this.value = this.widget.valueListenable.value;
this.widget.valueListenable.addListener(this._valueChanged);
}
public override void didUpdateWidget(StatefulWidget _oldWidget) {
ValueListenableBuilder<T> oldWidget = _oldWidget as ValueListenableBuilder<T>;
if (oldWidget.valueListenable != this.widget.valueListenable) {
oldWidget.valueListenable.removeListener(this._valueChanged);
this.value = this.widget.valueListenable.value;
this.widget.valueListenable.addListener(this._valueChanged);
}
base.didUpdateWidget(oldWidget);
}
public override void dispose() {
this.widget.valueListenable.removeListener(this._valueChanged);
base.dispose();
}
void _valueChanged() {
this.setState(() => { this.value = this.widget.valueListenable.value; });
}
public override Widget build(BuildContext context) {
return this.widget.builder(context, this.value, this.widget.child);
}
}
using Unity.UIWidgets.foundation;
namespace Unity.UIWidgets.widgets {
public delegate Widget ValueWidgetBuilder<T>(BuildContext context, T value, Widget child);
public class ValueListenableBuilder<T> : StatefulWidget {
public ValueListenableBuilder(
ValueListenable<T> valueListenable,
ValueWidgetBuilder<T> builder,
Widget child = null
) {
D.assert(valueListenable != null);
D.assert(builder != null);
this.valueListenable = valueListenable;
this.builder = builder;
this.child = child;
}
public readonly ValueListenable<T> valueListenable;
public readonly ValueWidgetBuilder<T> builder;
public readonly Widget child;
public override State createState() {
return new _ValueListenableBuilderState<T>();
}
}
class _ValueListenableBuilderState<T> : State<ValueListenableBuilder<T>> {
T value;
public override void initState() {
base.initState();
this.value = this.widget.valueListenable.value;
this.widget.valueListenable.addListener(this._valueChanged);
}
public override void didUpdateWidget(StatefulWidget _oldWidget) {
ValueListenableBuilder<T> oldWidget = _oldWidget as ValueListenableBuilder<T>;
if (oldWidget.valueListenable != this.widget.valueListenable) {
oldWidget.valueListenable.removeListener(this._valueChanged);
this.value = this.widget.valueListenable.value;
this.widget.valueListenable.addListener(this._valueChanged);
}
base.didUpdateWidget(oldWidget);
}
public override void dispose() {
this.widget.valueListenable.removeListener(this._valueChanged);
base.dispose();
}
void _valueChanged() {
this.setState(() => { this.value = this.widget.valueListenable.value; });
}
public override Widget build(BuildContext context) {
return this.widget.builder(context, this.value, this.widget.child);
}
}
}

4
com.unity.uiwidgets/Runtime/widgets/visibility.cs.meta


fileFormatVersion: 2
guid: f24846c5a2354d9a8b02bf83f3e8398e
fileFormatVersion: 2
guid: f24846c5a2354d9a8b02bf83f3e8398e
timeCreated: 1552895385

4
com.unity.uiwidgets/Runtime/widgets/will_pop_scope.cs.meta


fileFormatVersion: 2
guid: 624e6292cdfc4b43ac439df81ae8efee
fileFormatVersion: 2
guid: 624e6292cdfc4b43ac439df81ae8efee
timeCreated: 1552547854

1001
com.unity.uiwidgets/Runtime/ui/txt/emoji.cs
文件差异内容过多而无法显示
查看文件

564
com.unity.uiwidgets/Runtime/ui/txt/layout.cs


using UnityEngine;
namespace Unity.UIWidgets.ui {
static class Layout {
// Measure the length of the span of the text. Currently, this is only used to compute the length
// of ellipsis, assuming that the ellipsis does not contain any tab, tab is not considered for simplicity
public static float measureText(string text, TextStyle style) {
char startingChar = text[0];
float totalWidth = 0;
if (char.IsHighSurrogate(startingChar) || EmojiUtils.isSingleCharEmoji(startingChar)) {
float advance = style.fontSize * EmojiUtils.advanceFactor + style.letterSpacing;
for (int i = 0; i < text.Length; i++) {
char ch = text[i];
if (char.IsHighSurrogate(ch) || EmojiUtils.isSingleCharNonEmptyEmoji(ch)) {
totalWidth += advance;
}
}
}
else {
Font font = FontManager.instance.getOrCreate(style.fontFamily, style.fontWeight, style.fontStyle).font;
font.RequestCharactersInTextureSafe(text, style.UnityFontSize, style.UnityFontStyle);
for (int i = 0; i < text.Length; i++) {
char ch = text[i];
if (font.getGlyphInfo(ch, out var glyphInfo, style.UnityFontSize, style.UnityFontStyle)) {
totalWidth += glyphInfo.advance + style.letterSpacing;
}
else {
totalWidth += style.letterSpacing;
}
if (LayoutUtils.isWordSpace(ch)) {
totalWidth += style.wordSpacing;
}
}
}
return totalWidth;
}
public static int computeTruncateCount(float offset, string text, int start, int count, TextStyle style,
float advanceLimit, TabStops tabStops) {
char startingChar = text[start];
float currentAdvance = offset;
if (char.IsHighSurrogate(startingChar) || EmojiUtils.isSingleCharEmoji(startingChar)) {
float advance = style.fontSize * EmojiUtils.advanceFactor + style.letterSpacing;
for (int i = 0; i < count; i++) {
char ch = text[start + i];
if (char.IsHighSurrogate(ch) || EmojiUtils.isSingleCharNonEmptyEmoji(ch)) {
currentAdvance += advance;
if (currentAdvance > advanceLimit) {
return count - i;
}
}
}
}
else {
Font font = FontManager.instance.getOrCreate(style.fontFamily, style.fontWeight, style.fontStyle).font;
for (int i = 0; i < count; i++) {
char ch = text[start + i];
if (ch == '\t') {
currentAdvance = tabStops.nextTab(currentAdvance);
}
else if (font.getGlyphInfo(ch, out var glyphInfo, style.UnityFontSize, style.UnityFontStyle)) {
currentAdvance += glyphInfo.advance + style.letterSpacing;
}
else {
currentAdvance += style.letterSpacing;
}
if (LayoutUtils.isWordSpace(ch)) {
currentAdvance += style.wordSpacing;
}
if (currentAdvance > advanceLimit) {
return count - i;
}
}
}
return 0;
}
public static float computeCharWidths(float offset, string text, int start, int count, TextStyle style,
float[] advances, int advanceOffset, TabStops tabStops) {
char startingChar = text[start];
float totalWidths = 0;
if (char.IsHighSurrogate(startingChar) || EmojiUtils.isSingleCharEmoji(startingChar)) {
float advance = style.fontSize * EmojiUtils.advanceFactor + style.letterSpacing;
for (int i = 0; i < count; i++) {
char ch = text[start + i];
if (char.IsHighSurrogate(ch) || EmojiUtils.isSingleCharNonEmptyEmoji(ch)) {
advances[i + advanceOffset] = advance;
totalWidths += advance;
}
else {
advances[i + advanceOffset] = 0;
}
}
}
else {
Font font = FontManager.instance.getOrCreate(style.fontFamily, style.fontWeight, style.fontStyle).font;
// TODO: it is kind of a waste to require the entire string for this style, but SubString causes alloc
font.RequestCharactersInTextureSafe(text, style.UnityFontSize, style.UnityFontStyle);
for (int i = 0; i < count; i++) {
char ch = text[start + i];
if (ch == '\t') {
advances[i + advanceOffset] = tabStops.nextTab(offset + totalWidths) - (offset + totalWidths);
}
else if (font.getGlyphInfo(ch, out var glyphInfo, style.UnityFontSize, style.UnityFontStyle)) {
advances[i + advanceOffset] = glyphInfo.advance + style.letterSpacing;
}
else {
advances[i + advanceOffset] = style.letterSpacing;
}
if (LayoutUtils.isWordSpace(ch)) {
advances[i + advanceOffset] += style.wordSpacing;
}
totalWidths += advances[i + advanceOffset];
}
}
return totalWidths;
}
public static float doLayout(float offset, string text, int start, int count, TextStyle style,
float[] advances, float[] positions, TabStops tabStops, out UnityEngine.Rect bounds) {
float advance = 0;
Font font = FontManager.instance.getOrCreate(style.fontFamily, style.fontWeight, style.fontStyle).font;
char startingChar = text[start];
bounds = new UnityEngine.Rect();
if (char.IsHighSurrogate(startingChar) || EmojiUtils.isSingleCharEmoji(startingChar)) {
advance = _layoutEmoji(text, start, count, style, font, advances, positions, ref bounds);
}
else {
// According to the logic of Paragraph.layout, it is assured that all the characters are requested
// in the texture before (in computing line breaks), so skip it here for optimization.
// The only exception is the ellipsis, which did not appear in line breaking. It is taken care of
// only when needed.
// font.RequestCharactersInTextureSafe(buff.text, style.UnityFontSize, style.UnityFontStyle);
// int wordstart = start == buff.size
// ? start
// : LayoutUtils.getPrevWordBreakForCache(buff, start + 1);
int wordend;
for (int iter = start; iter < start + count; iter = wordend) {
wordend = LayoutUtils.getNextWordBreak(text, iter, start + count);
advance = _layoutWord(offset, iter - start, text, iter,
wordend - iter, style, font, advances, positions, advance,
tabStops, ref bounds);
}
}
// bounds relative to first character
bounds.x -= positions[0];
return advance;
}
static float _layoutWord(float offset, int layoutOffset,
string text, int start, int wordCount, TextStyle style, Font font, float[] advances,
float[] positions, float initAdvance, TabStops tabStops, ref UnityEngine.Rect bounds) {
float wordSpacing =
wordCount == 1 && LayoutUtils.isWordSpace(text[start]) ? style.wordSpacing : 0;
float x = initAdvance;
float letterSpace = style.letterSpacing;
float letterSpaceHalfLeft = letterSpace * 0.5f;
float letterSpaceHalfRight = letterSpace - letterSpaceHalfLeft;
for (int i = 0; i < wordCount; i++) {
initAdvance = x;
var ch = text[start + i];
if (i == 0) {
x += letterSpaceHalfLeft + wordSpacing;
advances[i + layoutOffset] = letterSpaceHalfLeft + wordSpacing;
}
else {
advances[i - 1 + layoutOffset] += letterSpaceHalfRight;
advances[i + layoutOffset] = letterSpaceHalfLeft;
x += letterSpace;
}
if (font.getGlyphInfo(ch, out var glyphInfo, style.UnityFontSize, style.UnityFontStyle)) {
_updateBounds(glyphInfo, x, ref bounds);
}
positions[i + layoutOffset] = x;
float advance;
if (ch == '\t') {
advance = tabStops.nextTab(initAdvance + offset) - initAdvance - offset;
}
else {
advance = glyphInfo.advance;
}
x += advance;
advances[i + layoutOffset] += advance;
if (i + 1 == wordCount) {
advances[i + layoutOffset] += letterSpaceHalfRight;
x += letterSpaceHalfRight;
}
}
return x;
}
static float _layoutEmoji(string text, int start, int count, TextStyle style, Font font, float[] advances,
float[] positions, ref UnityEngine.Rect bounds) {
var metrics = FontMetrics.fromFont(font, style.UnityFontSize);
float x = 0;
for (int i = 0; i < count; i++) {
char c = text[start + i];
if (EmojiUtils.isSingleCharNonEmptyEmoji(c) || char.IsHighSurrogate(c)) {
float letterSpace = style.letterSpacing;
float letterSpaceHalfLeft = letterSpace * 0.5f;
float letterSpaceHalfRight = letterSpace - letterSpaceHalfLeft;
x += letterSpaceHalfLeft;
advances[i] = letterSpaceHalfLeft;
float advance = style.fontSize * EmojiUtils.advanceFactor;
var minX = x;
var maxX = advance + x;
var minY = -style.fontSize * EmojiUtils.sizeFactor;
var maxY = metrics.descent;
_updateBounds(minX, maxX, minY, maxY, ref bounds);
positions[i] = x;
x += advance;
advances[i] += advance;
advances[i] += letterSpaceHalfRight;
x += letterSpaceHalfRight;
}
else {
advances[i] = 0;
positions[i] = x;
}
}
return x;
}
static void _updateBounds(CharacterInfo glyphInfo, float x, ref UnityEngine.Rect bounds) {
var minX = glyphInfo.minX + x;
var maxX = glyphInfo.maxX + x;
var minY = -glyphInfo.maxY;
var maxY = -glyphInfo.minY;
_updateBounds(minX, maxX, minY, maxY, ref bounds);
}
static void _updateBounds(float minX, float maxX, float minY, float maxY, ref UnityEngine.Rect bounds) {
if (bounds.width <= 0 || bounds.height <= 0) {
bounds.Set(minX, minY, maxX - minX, maxY - minY);
}
else {
if (minX < bounds.x) {
bounds.x = minX;
}
if (minY < bounds.y) {
bounds.y = minY;
}
if (maxX > bounds.xMax) {
bounds.xMax = maxX;
}
if (maxY > bounds.yMax) {
bounds.yMax = maxY;
}
}
}
}
using UnityEngine;
namespace Unity.UIWidgets.ui {
static class Layout {
// Measure the length of the span of the text. Currently, this is only used to compute the length
// of ellipsis, assuming that the ellipsis does not contain any tab, tab is not considered for simplicity
public static float measureText(string text, TextStyle style) {
char startingChar = text[0];
float totalWidth = 0;
if (char.IsHighSurrogate(startingChar) || EmojiUtils.isSingleCharEmoji(startingChar)) {
float advance = style.fontSize * EmojiUtils.advanceFactor + style.letterSpacing;
for (int i = 0; i < text.Length; i++) {
char ch = text[i];
if (char.IsHighSurrogate(ch) || EmojiUtils.isSingleCharNonEmptyEmoji(ch)) {
totalWidth += advance;
}
}
}
else {
Font font = FontManager.instance.getOrCreate(style.fontFamily, style.fontWeight, style.fontStyle).font;
font.RequestCharactersInTextureSafe(text, style.UnityFontSize, style.UnityFontStyle);
for (int i = 0; i < text.Length; i++) {
char ch = text[i];
if (font.getGlyphInfo(ch, out var glyphInfo, style.UnityFontSize, style.UnityFontStyle)) {
totalWidth += glyphInfo.advance + style.letterSpacing;
}
else {
totalWidth += style.letterSpacing;
}
if (LayoutUtils.isWordSpace(ch)) {
totalWidth += style.wordSpacing;
}
}
}
return totalWidth;
}
public static int computeTruncateCount(float offset, string text, int start, int count, TextStyle style,
float advanceLimit, TabStops tabStops) {
char startingChar = text[start];
float currentAdvance = offset;
if (char.IsHighSurrogate(startingChar) || EmojiUtils.isSingleCharEmoji(startingChar)) {
float advance = style.fontSize * EmojiUtils.advanceFactor + style.letterSpacing;
for (int i = 0; i < count; i++) {
char ch = text[start + i];
if (char.IsHighSurrogate(ch) || EmojiUtils.isSingleCharNonEmptyEmoji(ch)) {
currentAdvance += advance;
if (currentAdvance > advanceLimit) {
return count - i;
}
}
}
}
else {
Font font = FontManager.instance.getOrCreate(style.fontFamily, style.fontWeight, style.fontStyle).font;
for (int i = 0; i < count; i++) {
char ch = text[start + i];
if (ch == '\t') {
currentAdvance = tabStops.nextTab(currentAdvance);
}
else if (font.getGlyphInfo(ch, out var glyphInfo, style.UnityFontSize, style.UnityFontStyle)) {
currentAdvance += glyphInfo.advance + style.letterSpacing;
}
else {
currentAdvance += style.letterSpacing;
}
if (LayoutUtils.isWordSpace(ch)) {
currentAdvance += style.wordSpacing;
}
if (currentAdvance > advanceLimit) {
return count - i;
}
}
}
return 0;
}
public static float computeCharWidths(float offset, string text, int start, int count, TextStyle style,
float[] advances, int advanceOffset, TabStops tabStops) {
char startingChar = text[start];
float totalWidths = 0;
if (char.IsHighSurrogate(startingChar) || EmojiUtils.isSingleCharEmoji(startingChar)) {
float advance = style.fontSize * EmojiUtils.advanceFactor + style.letterSpacing;
for (int i = 0; i < count; i++) {
char ch = text[start + i];
if (char.IsHighSurrogate(ch) || EmojiUtils.isSingleCharNonEmptyEmoji(ch)) {
advances[i + advanceOffset] = advance;
totalWidths += advance;
}
else {
advances[i + advanceOffset] = 0;
}
}
}
else {
Font font = FontManager.instance.getOrCreate(style.fontFamily, style.fontWeight, style.fontStyle).font;
// TODO: it is kind of a waste to require the entire string for this style, but SubString causes alloc
font.RequestCharactersInTextureSafe(text, style.UnityFontSize, style.UnityFontStyle);
for (int i = 0; i < count; i++) {
char ch = text[start + i];
if (ch == '\t') {
advances[i + advanceOffset] = tabStops.nextTab(offset + totalWidths) - (offset + totalWidths);
}
else if (font.getGlyphInfo(ch, out var glyphInfo, style.UnityFontSize, style.UnityFontStyle)) {
advances[i + advanceOffset] = glyphInfo.advance + style.letterSpacing;
}
else {
advances[i + advanceOffset] = style.letterSpacing;
}
if (LayoutUtils.isWordSpace(ch)) {
advances[i + advanceOffset] += style.wordSpacing;
}
totalWidths += advances[i + advanceOffset];
}
}
return totalWidths;
}
public static float doLayout(float offset, string text, int start, int count, TextStyle style,
float[] advances, float[] positions, TabStops tabStops, out UnityEngine.Rect bounds) {
float advance = 0;
Font font = FontManager.instance.getOrCreate(style.fontFamily, style.fontWeight, style.fontStyle).font;
char startingChar = text[start];
bounds = new UnityEngine.Rect();
if (char.IsHighSurrogate(startingChar) || EmojiUtils.isSingleCharEmoji(startingChar)) {
advance = _layoutEmoji(text, start, count, style, font, advances, positions, ref bounds);
}
else {
// According to the logic of Paragraph.layout, it is assured that all the characters are requested
// in the texture before (in computing line breaks), so skip it here for optimization.
// The only exception is the ellipsis, which did not appear in line breaking. It is taken care of
// only when needed.
// font.RequestCharactersInTextureSafe(buff.text, style.UnityFontSize, style.UnityFontStyle);
// int wordstart = start == buff.size
// ? start
// : LayoutUtils.getPrevWordBreakForCache(buff, start + 1);
int wordend;
for (int iter = start; iter < start + count; iter = wordend) {
wordend = LayoutUtils.getNextWordBreak(text, iter, start + count);
advance = _layoutWord(offset, iter - start, text, iter,
wordend - iter, style, font, advances, positions, advance,
tabStops, ref bounds);
}
}
// bounds relative to first character
bounds.x -= positions[0];
return advance;
}
static float _layoutWord(float offset, int layoutOffset,
string text, int start, int wordCount, TextStyle style, Font font, float[] advances,
float[] positions, float initAdvance, TabStops tabStops, ref UnityEngine.Rect bounds) {
float wordSpacing =
wordCount == 1 && LayoutUtils.isWordSpace(text[start]) ? style.wordSpacing : 0;
float x = initAdvance;
float letterSpace = style.letterSpacing;
float letterSpaceHalfLeft = letterSpace * 0.5f;
float letterSpaceHalfRight = letterSpace - letterSpaceHalfLeft;
for (int i = 0; i < wordCount; i++) {
initAdvance = x;
var ch = text[start + i];
if (i == 0) {
x += letterSpaceHalfLeft + wordSpacing;
advances[i + layoutOffset] = letterSpaceHalfLeft + wordSpacing;
}
else {
advances[i - 1 + layoutOffset] += letterSpaceHalfRight;
advances[i + layoutOffset] = letterSpaceHalfLeft;
x += letterSpace;
}
if (font.getGlyphInfo(ch, out var glyphInfo, style.UnityFontSize, style.UnityFontStyle)) {
_updateBounds(glyphInfo, x, ref bounds);
}
positions[i + layoutOffset] = x;
float advance;
if (ch == '\t') {
advance = tabStops.nextTab(initAdvance + offset) - initAdvance - offset;
}
else {
advance = glyphInfo.advance;
}
x += advance;
advances[i + layoutOffset] += advance;
if (i + 1 == wordCount) {
advances[i + layoutOffset] += letterSpaceHalfRight;
x += letterSpaceHalfRight;
}
}
return x;
}
static float _layoutEmoji(string text, int start, int count, TextStyle style, Font font, float[] advances,
float[] positions, ref UnityEngine.Rect bounds) {
var metrics = FontMetrics.fromFont(font, style.UnityFontSize);
float x = 0;
for (int i = 0; i < count; i++) {
char c = text[start + i];
if (EmojiUtils.isSingleCharNonEmptyEmoji(c) || char.IsHighSurrogate(c)) {
float letterSpace = style.letterSpacing;
float letterSpaceHalfLeft = letterSpace * 0.5f;
float letterSpaceHalfRight = letterSpace - letterSpaceHalfLeft;
x += letterSpaceHalfLeft;
advances[i] = letterSpaceHalfLeft;
float advance = style.fontSize * EmojiUtils.advanceFactor;
var minX = x;
var maxX = advance + x;
var minY = -style.fontSize * EmojiUtils.sizeFactor;
var maxY = metrics.descent;
_updateBounds(minX, maxX, minY, maxY, ref bounds);
positions[i] = x;
x += advance;
advances[i] += advance;
advances[i] += letterSpaceHalfRight;
x += letterSpaceHalfRight;
}
else {
advances[i] = 0;
positions[i] = x;
}
}
return x;
}
static void _updateBounds(CharacterInfo glyphInfo, float x, ref UnityEngine.Rect bounds) {
var minX = glyphInfo.minX + x;
var maxX = glyphInfo.maxX + x;
var minY = -glyphInfo.maxY;
var maxY = -glyphInfo.minY;
_updateBounds(minX, maxX, minY, maxY, ref bounds);
}
static void _updateBounds(float minX, float maxX, float minY, float maxY, ref UnityEngine.Rect bounds) {
if (bounds.width <= 0 || bounds.height <= 0) {
bounds.Set(minX, minY, maxX - minX, maxY - minY);
}
else {
if (minX < bounds.x) {
bounds.x = minX;
}
if (minY < bounds.y) {
bounds.y = minY;
}
if (maxX > bounds.xMax) {
bounds.xMax = maxX;
}
if (maxY > bounds.yMax) {
bounds.yMax = maxY;
}
}
}
}
}

694
com.unity.uiwidgets/Runtime/ui/txt/linebreaker.cs


using System.Collections.Generic;
using UnityEngine;
namespace Unity.UIWidgets.ui {
class TabStops {
int _tabWidth = int.MaxValue;
Font _font;
int _fontSize;
int _spaceAdvance;
const int kTabSpaceCount = 4;
public void setFont(Font font, int size) {
if (this._font != font || this._fontSize != size) {
this._tabWidth = int.MaxValue;
}
this._font = font;
// Recompute the advance of space (' ') if font size changes
if (this._fontSize != size) {
this._fontSize = size;
this._font.RequestCharactersInTextureSafe(" ", this._fontSize);
this._font.getGlyphInfo(' ', out var glyphInfo, this._fontSize, UnityEngine.FontStyle.Normal);
this._spaceAdvance = glyphInfo.advance;
}
}
public float nextTab(float widthSoFar) {
if (this._tabWidth == int.MaxValue) {
if (this._fontSize > 0) {
this._tabWidth = this._spaceAdvance * kTabSpaceCount;
}
}
if (this._tabWidth == 0) {
return widthSoFar;
}
return (Mathf.Floor(widthSoFar / this._tabWidth + 1) * this._tabWidth);
}
}
struct Candidate {
public int offset;
public int pre;
public float preBreak;
public float penalty;
public float postBreak;
public int preSpaceCount;
public int postSpaceCount;
}
class LineBreaker {
const float ScoreInfty = float.MaxValue;
const float ScoreDesperate = 1e10f;
int _lineLimit = 0;
// Limit number of lines, 0 means no limit
public int lineLimit {
get { return this._lineLimit; }
set { this._lineLimit = value; }
}
public static LineBreaker instance {
get {
if (_instance == null) {
_instance = new LineBreaker();
}
return _instance;
}
}
static LineBreaker _instance;
public static int[] newLinePositions(string text, out int count) {
count = 0;
for (var i = 0; i < text.Length; i++) {
if (text[i] == '\n') {
count++;
}
}
count++;
if (_newLinePositions == null || _newLinePositions.Length < count) {
_newLinePositions = new int[count];
}
count = 0;
for (var i = 0; i < text.Length; i++) {
if (text[i] == '\n') {
_newLinePositions[count++] = i;
}
}
_newLinePositions[count++] = text.Length;
return _newLinePositions;
}
static int[] _newLinePositions;
TextBuff _textBuf;
float[] _charWidths;
List<int> _breaks = new List<int>();
int _breaksCount = 0;
List<float> _widths = new List<float>();
int _widthsCount = 0;
WordBreaker _wordBreaker = new WordBreaker();
float _width = 0.0f;
float _preBreak;
float _lineWidth;
int _lastBreak;
int _bestBreak;
float _bestScore;
int _spaceCount;
TabStops _tabStops;
int mFirstTabIndex;
List<Candidate> _candidates = new List<Candidate>();
int _candidatesCount = 0;
public int computeBreaks() {
int nCand = this._candidatesCount;
if (nCand > 0 && (nCand == 1 || this._lastBreak != nCand - 1)) {
var cand = this._candidates[this._candidatesCount - 1];
this._pushBreak(cand.offset, (cand.postBreak - this._preBreak));
}
return this._breaksCount;
}
public int getBreaksCount() {
return this._breaksCount;
}
public int getBreak(int i) {
return this._breaks[i];
}
public float getWidth(int i) {
return this._widths[i];
}
public void resize(int size) {
if (this._charWidths == null || this._charWidths.Length < size) {
this._charWidths = new float[LayoutUtils.minPowerOfTwo(size)];
}
}
public void setText(string text, int textOffset, int textLength) {
this._textBuf = new TextBuff(text, textOffset, textLength);
this._wordBreaker.setText(this._textBuf);
this._wordBreaker.next();
this._candidatesCount = 0;
Candidate can = new Candidate {
offset = 0, postBreak = 0, preBreak = 0, postSpaceCount = 0, preSpaceCount = 0, pre = 0
};
this._addCandidateToList(can);
this._lastBreak = 0;
this._bestBreak = 0;
this._bestScore = ScoreInfty;
this._preBreak = 0;
this.mFirstTabIndex = int.MaxValue;
this._spaceCount = 0;
}
public void setLineWidth(float lineWidth) {
this._lineWidth = lineWidth;
}
public float addStyleRun(TextStyle style, int start, int end) {
float width = 0;
if (style != null) {
// Layout.measureText(this._width - this._preBreak, this._textBuf,
// start, end - start, style,
// this._charWidths, start, this._tabStops);
width = Layout.computeCharWidths(this._width - this._preBreak, this._textBuf.text,
this._textBuf.offset + start, end - start, style,
this._charWidths, start, this._tabStops);
}
int current = this._wordBreaker.current();
float postBreak = this._width;
int postSpaceCount = this._spaceCount;
for (int i = start; i < end; i++) {
char c = this._textBuf.charAt(i);
if (c == '\t') {
this._width = this._preBreak + this._tabStops.nextTab(this._width - this._preBreak);
if (this.mFirstTabIndex == int.MaxValue) {
this.mFirstTabIndex = i;
}
}
else {
if (LayoutUtils.isWordSpace(c)) {
this._spaceCount += 1;
}
this._width += this._charWidths[i];
if (!LayoutUtils.isLineEndSpace(c)) {
postBreak = this._width;
postSpaceCount = this._spaceCount;
}
}
if (i + 1 == current) {
if (style != null || current == end || this._charWidths[current] > 0) {
this._addWordBreak(current, this._width, postBreak, this._spaceCount, postSpaceCount, 0);
}
current = this._wordBreaker.next();
}
}
return width;
}
public void finish() {
this._wordBreaker.finish();
this._width = 0;
this._candidatesCount = 0;
this._breaksCount = 0;
this._widthsCount = 0;
this._textBuf = default;
}
public int getWidthsCount() {
return this._widthsCount;
}
public void setTabStops(TabStops tabStops) {
this._tabStops = tabStops;
}
void _addWordBreak(int offset, float preBreak, float postBreak, int preSpaceCount, int postSpaceCount,
float penalty) {
float width = this._candidates[this._candidatesCount - 1].preBreak;
if (postBreak - width > this._lineWidth) {
this._addCandidatesInsideWord(width, offset, postSpaceCount);
}
this._addCandidate(new Candidate {
offset = offset,
preBreak = preBreak,
postBreak = postBreak,
preSpaceCount = preSpaceCount,
postSpaceCount = postSpaceCount,
penalty = penalty
});
}
void _addCandidatesInsideWord(float width, int offset, int postSpaceCount) {
int i = this._candidates[this._candidatesCount - 1].offset;
width += this._charWidths[i++];
for (; i < offset; i++) {
float w = this._charWidths[i];
if (w > 0) {
this._addCandidate(new Candidate {
offset = i,
preBreak = width,
postBreak = width,
preSpaceCount = postSpaceCount,
postSpaceCount = postSpaceCount,
penalty = ScoreDesperate,
});
width += w;
}
}
}
void _addCandidateToList(Candidate cand) {
if (this._candidates.Count == this._candidatesCount) {
this._candidates.Add(cand);
this._candidatesCount++;
}
else {
this._candidates[this._candidatesCount++] = cand;
}
}
void _addCandidate(Candidate cand) {
int candIndex = this._candidatesCount;
this._addCandidateToList(cand);
if (cand.postBreak - this._preBreak > this._lineWidth) {
if (this._bestBreak == this._lastBreak) {
this._bestBreak = candIndex;
}
this._pushGreedyBreak();
}
while (this._lastBreak != candIndex && cand.postBreak - this._preBreak > this._lineWidth) {
for (int i = this._lastBreak + 1; i < candIndex; i++) {
float penalty = this._candidates[i].penalty;
if (penalty <= this._bestScore) {
this._bestBreak = i;
this._bestScore = penalty;
}
}
if (this._bestBreak == this._lastBreak) {
this._bestBreak = candIndex;
}
this._pushGreedyBreak();
}
if (cand.penalty <= this._bestScore) {
this._bestBreak = candIndex;
this._bestScore = cand.penalty;
}
}
void _pushGreedyBreak() {
var bestCandidate = this._candidates[this._bestBreak];
this._pushBreak(bestCandidate.offset, bestCandidate.postBreak - this._preBreak);
this._bestScore = ScoreInfty;
this._lastBreak = this._bestBreak;
this._preBreak = bestCandidate.preBreak;
}
void _pushBreak(int offset, float width) {
if (this.lineLimit == 0 || this._breaksCount < this.lineLimit) {
if (this._breaks.Count == this._breaksCount) {
this._breaks.Add(offset);
this._breaksCount++;
}
else {
this._breaks[this._breaksCount++] = offset;
}
if (this._widths.Count == this._widthsCount) {
this._widths.Add(width);
this._widthsCount++;
}
else {
this._widths[this._widthsCount++] = width;
}
}
}
}
using System.Collections.Generic;
using UnityEngine;
namespace Unity.UIWidgets.ui {
class TabStops {
int _tabWidth = int.MaxValue;
Font _font;
int _fontSize;
int _spaceAdvance;
const int kTabSpaceCount = 4;
public void setFont(Font font, int size) {
if (this._font != font || this._fontSize != size) {
this._tabWidth = int.MaxValue;
}
this._font = font;
// Recompute the advance of space (' ') if font size changes
if (this._fontSize != size) {
this._fontSize = size;
this._font.RequestCharactersInTextureSafe(" ", this._fontSize);
this._font.getGlyphInfo(' ', out var glyphInfo, this._fontSize, UnityEngine.FontStyle.Normal);
this._spaceAdvance = glyphInfo.advance;
}
}
public float nextTab(float widthSoFar) {
if (this._tabWidth == int.MaxValue) {
if (this._fontSize > 0) {
this._tabWidth = this._spaceAdvance * kTabSpaceCount;
}
}
if (this._tabWidth == 0) {
return widthSoFar;
}
return (Mathf.Floor(widthSoFar / this._tabWidth + 1) * this._tabWidth);
}
}
struct Candidate {
public int offset;
public int pre;
public float preBreak;
public float penalty;
public float postBreak;
public int preSpaceCount;
public int postSpaceCount;
}
class LineBreaker {
const float ScoreInfty = float.MaxValue;
const float ScoreDesperate = 1e10f;
int _lineLimit = 0;
// Limit number of lines, 0 means no limit
public int lineLimit {
get { return this._lineLimit; }
set { this._lineLimit = value; }
}
public static LineBreaker instance {
get {
if (_instance == null) {
_instance = new LineBreaker();
}
return _instance;
}
}
static LineBreaker _instance;
public static int[] newLinePositions(string text, out int count) {
count = 0;
for (var i = 0; i < text.Length; i++) {
if (text[i] == '\n') {
count++;
}
}
count++;
if (_newLinePositions == null || _newLinePositions.Length < count) {
_newLinePositions = new int[count];
}
count = 0;
for (var i = 0; i < text.Length; i++) {
if (text[i] == '\n') {
_newLinePositions[count++] = i;
}
}
_newLinePositions[count++] = text.Length;
return _newLinePositions;
}
static int[] _newLinePositions;
TextBuff _textBuf;
float[] _charWidths;
List<int> _breaks = new List<int>();
int _breaksCount = 0;
List<float> _widths = new List<float>();
int _widthsCount = 0;
WordBreaker _wordBreaker = new WordBreaker();
float _width = 0.0f;
float _preBreak;
float _lineWidth;
int _lastBreak;
int _bestBreak;
float _bestScore;
int _spaceCount;
TabStops _tabStops;
int mFirstTabIndex;
List<Candidate> _candidates = new List<Candidate>();
int _candidatesCount = 0;
public int computeBreaks() {
int nCand = this._candidatesCount;
if (nCand > 0 && (nCand == 1 || this._lastBreak != nCand - 1)) {
var cand = this._candidates[this._candidatesCount - 1];
this._pushBreak(cand.offset, (cand.postBreak - this._preBreak));
}
return this._breaksCount;
}
public int getBreaksCount() {
return this._breaksCount;
}
public int getBreak(int i) {
return this._breaks[i];
}
public float getWidth(int i) {
return this._widths[i];
}
public void resize(int size) {
if (this._charWidths == null || this._charWidths.Length < size) {
this._charWidths = new float[LayoutUtils.minPowerOfTwo(size)];
}
}
public void setText(string text, int textOffset, int textLength) {
this._textBuf = new TextBuff(text, textOffset, textLength);
this._wordBreaker.setText(this._textBuf);
this._wordBreaker.next();
this._candidatesCount = 0;
Candidate can = new Candidate {
offset = 0, postBreak = 0, preBreak = 0, postSpaceCount = 0, preSpaceCount = 0, pre = 0
};
this._addCandidateToList(can);
this._lastBreak = 0;
this._bestBreak = 0;
this._bestScore = ScoreInfty;
this._preBreak = 0;
this.mFirstTabIndex = int.MaxValue;
this._spaceCount = 0;
}
public void setLineWidth(float lineWidth) {
this._lineWidth = lineWidth;
}
public float addStyleRun(TextStyle style, int start, int end) {
float width = 0;
if (style != null) {
// Layout.measureText(this._width - this._preBreak, this._textBuf,
// start, end - start, style,
// this._charWidths, start, this._tabStops);
width = Layout.computeCharWidths(this._width - this._preBreak, this._textBuf.text,
this._textBuf.offset + start, end - start, style,
this._charWidths, start, this._tabStops);
}
int current = this._wordBreaker.current();
float postBreak = this._width;
int postSpaceCount = this._spaceCount;
for (int i = start; i < end; i++) {
char c = this._textBuf.charAt(i);
if (c == '\t') {
this._width = this._preBreak + this._tabStops.nextTab(this._width - this._preBreak);
if (this.mFirstTabIndex == int.MaxValue) {
this.mFirstTabIndex = i;
}
}
else {
if (LayoutUtils.isWordSpace(c)) {
this._spaceCount += 1;
}
this._width += this._charWidths[i];
if (!LayoutUtils.isLineEndSpace(c)) {
postBreak = this._width;
postSpaceCount = this._spaceCount;
}
}
if (i + 1 == current) {
if (style != null || current == end || this._charWidths[current] > 0) {
this._addWordBreak(current, this._width, postBreak, this._spaceCount, postSpaceCount, 0);
}
current = this._wordBreaker.next();
}
}
return width;
}
public void finish() {
this._wordBreaker.finish();
this._width = 0;
this._candidatesCount = 0;
this._breaksCount = 0;
this._widthsCount = 0;
this._textBuf = default;
}
public int getWidthsCount() {
return this._widthsCount;
}
public void setTabStops(TabStops tabStops) {
this._tabStops = tabStops;
}
void _addWordBreak(int offset, float preBreak, float postBreak, int preSpaceCount, int postSpaceCount,
float penalty) {
float width = this._candidates[this._candidatesCount - 1].preBreak;
if (postBreak - width > this._lineWidth) {
this._addCandidatesInsideWord(width, offset, postSpaceCount);
}
this._addCandidate(new Candidate {
offset = offset,
preBreak = preBreak,
postBreak = postBreak,
preSpaceCount = preSpaceCount,
postSpaceCount = postSpaceCount,
penalty = penalty
});
}
void _addCandidatesInsideWord(float width, int offset, int postSpaceCount) {
int i = this._candidates[this._candidatesCount - 1].offset;
width += this._charWidths[i++];
for (; i < offset; i++) {
float w = this._charWidths[i];
if (w > 0) {
this._addCandidate(new Candidate {
offset = i,
preBreak = width,
postBreak = width,
preSpaceCount = postSpaceCount,
postSpaceCount = postSpaceCount,
penalty = ScoreDesperate,
});
width += w;
}
}
}
void _addCandidateToList(Candidate cand) {
if (this._candidates.Count == this._candidatesCount) {
this._candidates.Add(cand);
this._candidatesCount++;
}
else {
this._candidates[this._candidatesCount++] = cand;
}
}
void _addCandidate(Candidate cand) {
int candIndex = this._candidatesCount;
this._addCandidateToList(cand);
if (cand.postBreak - this._preBreak > this._lineWidth) {
if (this._bestBreak == this._lastBreak) {
this._bestBreak = candIndex;
}
this._pushGreedyBreak();
}
while (this._lastBreak != candIndex && cand.postBreak - this._preBreak > this._lineWidth) {
for (int i = this._lastBreak + 1; i < candIndex; i++) {
float penalty = this._candidates[i].penalty;
if (penalty <= this._bestScore) {
this._bestBreak = i;
this._bestScore = penalty;
}
}
if (this._bestBreak == this._lastBreak) {
this._bestBreak = candIndex;
}
this._pushGreedyBreak();
}
if (cand.penalty <= this._bestScore) {
this._bestBreak = candIndex;
this._bestScore = cand.penalty;
}
}
void _pushGreedyBreak() {
var bestCandidate = this._candidates[this._bestBreak];
this._pushBreak(bestCandidate.offset, bestCandidate.postBreak - this._preBreak);
this._bestScore = ScoreInfty;
this._lastBreak = this._bestBreak;
this._preBreak = bestCandidate.preBreak;
}
void _pushBreak(int offset, float width) {
if (this.lineLimit == 0 || this._breaksCount < this.lineLimit) {
if (this._breaks.Count == this._breaksCount) {
this._breaks.Add(offset);
this._breaksCount++;
}
else {
this._breaks[this._breaksCount++] = offset;
}
if (this._widths.Count == this._widthsCount) {
this._widths.Add(width);
this._widthsCount++;
}
else {
this._widths[this._widthsCount++] = width;
}
}
}
}
}

4
com.unity.uiwidgets/Runtime/ui/painting/image.cs.meta


fileFormatVersion: 2
guid: bfd6fdb0d13948d6acbc528589ebef33
fileFormatVersion: 2
guid: bfd6fdb0d13948d6acbc528589ebef33
timeCreated: 1534821698

192
com.unity.uiwidgets/Runtime/ui/painting/txt/text_blob.cs


namespace Unity.UIWidgets.ui {
public struct TextBlob {
internal TextBlob(string text, int textOffset, int textSize, float[] positionXs,
UnityEngine.Rect bounds, TextStyle style) {
this.instanceId = ++_nextInstanceId;
this._positionXs = positionXs;
this.text = text;
this.textOffset = textOffset;
this.textSize = textSize;
this.style = style;
this._bounds = bounds;
this._boundsInText = null;
}
public Rect boundsInText {
get {
if (this._boundsInText == null) {
var pos = this.getPositionX(0);
this._boundsInText = Rect.fromLTWH(this._bounds.xMin + pos, this._bounds.yMin,
this._bounds.width, this._bounds.height);
}
return this._boundsInText;
}
}
public Rect shiftedBoundsInText(float dx, float dy) {
var pos = this.getPositionX(0);
return Rect.fromLTWH(this._bounds.xMin + pos + dx, this._bounds.yMin + dy,
this._bounds.width, this._bounds.height);
}
public float getPositionX(int i) {
return this._positionXs[this.textOffset + i];
}
static long _nextInstanceId;
internal readonly long instanceId;
internal readonly string text;
internal readonly int textOffset;
internal readonly int textSize;
internal readonly TextStyle style;
readonly UnityEngine.Rect _bounds; // bounds with positions[start] as origin
readonly float[] _positionXs;
Rect _boundsInText;
}
public struct TextBlobBuilder {
TextStyle _style;
float[] _positionXs;
string _text;
int _textOffset;
int _size;
UnityEngine.Rect _bounds;
public void allocRunPos(painting.TextStyle style, string text, int offset, int size,
float textScaleFactor = 1.0f) {
this.allocRunPos(TextStyle.applyStyle(null, style, textScaleFactor), text, offset, size);
}
internal void allocRunPos(TextStyle style, string text, int offset, int size) {
this._style = style;
this._text = text;
this._textOffset = offset;
this._size = size;
// Allocate a single buffer for all text blobs that share this text, to save memory and GC.
// It is assumed that all of `text` is being used. This may cause great waste if a long text is passed
// but only a small part of it is to be rendered, which is not the case for now.
this.allocPos(text.Length);
}
internal void allocPos(int size) {
if (this._positionXs == null || this._positionXs.Length < size) {
this._positionXs = new float[size];
}
}
public void setPositionX(int i, float positionX) {
this._positionXs[this._textOffset + i] = positionX;
}
public void setPositionXs(float[] positionXs) {
this._positionXs = positionXs;
}
public void setBounds(UnityEngine.Rect bounds) {
this._bounds = bounds;
}
public TextBlob make() {
var result = new TextBlob(this._text, this._textOffset,
this._size, this._positionXs, this._bounds, this._style);
return result;
}
}
namespace Unity.UIWidgets.ui {
public struct TextBlob {
internal TextBlob(string text, int textOffset, int textSize, float[] positionXs,
UnityEngine.Rect bounds, TextStyle style) {
this.instanceId = ++_nextInstanceId;
this._positionXs = positionXs;
this.text = text;
this.textOffset = textOffset;
this.textSize = textSize;
this.style = style;
this._bounds = bounds;
this._boundsInText = null;
}
public Rect boundsInText {
get {
if (this._boundsInText == null) {
var pos = this.getPositionX(0);
this._boundsInText = Rect.fromLTWH(this._bounds.xMin + pos, this._bounds.yMin,
this._bounds.width, this._bounds.height);
}
return this._boundsInText;
}
}
public Rect shiftedBoundsInText(float dx, float dy) {
var pos = this.getPositionX(0);
return Rect.fromLTWH(this._bounds.xMin + pos + dx, this._bounds.yMin + dy,
this._bounds.width, this._bounds.height);
}
public float getPositionX(int i) {
return this._positionXs[this.textOffset + i];
}
static long _nextInstanceId;
internal readonly long instanceId;
internal readonly string text;
internal readonly int textOffset;
internal readonly int textSize;
internal readonly TextStyle style;
readonly UnityEngine.Rect _bounds; // bounds with positions[start] as origin
readonly float[] _positionXs;
Rect _boundsInText;
}
public struct TextBlobBuilder {
TextStyle _style;
float[] _positionXs;
string _text;
int _textOffset;
int _size;
UnityEngine.Rect _bounds;
public void allocRunPos(painting.TextStyle style, string text, int offset, int size,
float textScaleFactor = 1.0f) {
this.allocRunPos(TextStyle.applyStyle(null, style, textScaleFactor), text, offset, size);
}
internal void allocRunPos(TextStyle style, string text, int offset, int size) {
this._style = style;
this._text = text;
this._textOffset = offset;
this._size = size;
// Allocate a single buffer for all text blobs that share this text, to save memory and GC.
// It is assumed that all of `text` is being used. This may cause great waste if a long text is passed
// but only a small part of it is to be rendered, which is not the case for now.
this.allocPos(text.Length);
}
internal void allocPos(int size) {
if (this._positionXs == null || this._positionXs.Length < size) {
this._positionXs = new float[size];
}
}
public void setPositionX(int i, float positionX) {
this._positionXs[this._textOffset + i] = positionX;
}
public void setPositionXs(float[] positionXs) {
this._positionXs = positionXs;
}
public void setBounds(UnityEngine.Rect bounds) {
this._bounds = bounds;
}
public TextBlob make() {
var result = new TextBlob(this._text, this._textOffset,
this._size, this._positionXs, this._bounds, this._style);
return result;
}
}
}

8
com.unity.uiwidgets/Runtime/rendering/debug.cs


namespace Unity.UIWidgets.rendering {
public static class RenderingDebugUtils {
public static bool debugCheckElevationsEnabled = false;
}
namespace Unity.UIWidgets.rendering {
public static class RenderingDebugUtils {
public static bool debugCheckElevationsEnabled = false;
}
}

4
com.unity.uiwidgets/Runtime/rendering/error.cs.meta


fileFormatVersion: 2
guid: 64dfb38ea47d49c7b9f3d0debeee4409
fileFormatVersion: 2
guid: 64dfb38ea47d49c7b9f3d0debeee4409
timeCreated: 1536819405

4
com.unity.uiwidgets/Runtime/rendering/image.cs.meta


fileFormatVersion: 2
guid: d0413272d07e4c958f45f9c7597fe2b7
fileFormatVersion: 2
guid: d0413272d07e4c958f45f9c7597fe2b7
timeCreated: 1534820838

4
com.unity.uiwidgets/Runtime/rendering/rotated_box.cs.meta


fileFormatVersion: 2
guid: 057a0f3b94794fce9f9f3aa7bb624256
fileFormatVersion: 2
guid: 057a0f3b94794fce9f9f3aa7bb624256
timeCreated: 1557210363

4
com.unity.uiwidgets/Runtime/rendering/sliver_persistent_header.cs.meta


fileFormatVersion: 2
guid: 8bf4842a43ca4b13ae8d333813e166c9
fileFormatVersion: 2
guid: 8bf4842a43ca4b13ae8d333813e166c9
timeCreated: 1553064435

4
com.unity.uiwidgets/Runtime/rendering/wrap.cs.meta


fileFormatVersion: 2
guid: bf63171d5e9d4f9fb93cf8cf7a0534bb
fileFormatVersion: 2
guid: bf63171d5e9d4f9fb93cf8cf7a0534bb
timeCreated: 1552011675

4
com.unity.uiwidgets/Runtime/promise/EnumerableExt.cs.meta


fileFormatVersion: 2
guid: bb9a3c5b387541cb800b11c84121f7f3
fileFormatVersion: 2
guid: bb9a3c5b387541cb800b11c84121f7f3
timeCreated: 1534828260

4
com.unity.uiwidgets/Runtime/promise/Promise.cs.meta


fileFormatVersion: 2
guid: ffdd174fa01b47d99dae6b8b38945413
fileFormatVersion: 2
guid: ffdd174fa01b47d99dae6b8b38945413
timeCreated: 1534828022

4
com.unity.uiwidgets/Runtime/promise/PromiseException.cs.meta


fileFormatVersion: 2
guid: ef24fa8abd794ec9ad904f149ade425b
fileFormatVersion: 2
guid: ef24fa8abd794ec9ad904f149ade425b
timeCreated: 1534828173

4
com.unity.uiwidgets/Runtime/promise/PromiseHelpers.cs.meta


fileFormatVersion: 2
guid: 07f0b3c08d53427992f828dd9c4f0f15
fileFormatVersion: 2
guid: 07f0b3c08d53427992f828dd9c4f0f15
timeCreated: 1534828078

4
com.unity.uiwidgets/Runtime/promise/PromiseStateException.cs.meta


fileFormatVersion: 2
guid: d922956f02bc4ff2a82f9404787380b0
fileFormatVersion: 2
guid: d922956f02bc4ff2a82f9404787380b0
timeCreated: 1534828191

4
com.unity.uiwidgets/Runtime/promise/PromiseTimer.cs.meta


fileFormatVersion: 2
guid: e47ddf579a9a45f48fd9203faf93b52f
fileFormatVersion: 2
guid: e47ddf579a9a45f48fd9203faf93b52f
timeCreated: 1534828095

4
com.unity.uiwidgets/Runtime/promise/Promise_NonGeneric.cs.meta


fileFormatVersion: 2
guid: fad6eb2d15b84c7cb92f115245ac09f8
fileFormatVersion: 2
guid: fad6eb2d15b84c7cb92f115245ac09f8
timeCreated: 1534828106

4
com.unity.uiwidgets/Runtime/promise/Tuple.cs.meta


fileFormatVersion: 2
guid: 2e1ff13e974447a080559101999e17d9
fileFormatVersion: 2
guid: 2e1ff13e974447a080559101999e17d9
timeCreated: 1534828127

4
com.unity.uiwidgets/Runtime/painting/box_fit.cs.meta


fileFormatVersion: 2
guid: 4d75ec15a75b4a7baca1968978b1eec9
fileFormatVersion: 2
guid: 4d75ec15a75b4a7baca1968978b1eec9
timeCreated: 1534820694

4
com.unity.uiwidgets/Runtime/painting/image_cache.cs.meta


fileFormatVersion: 2
guid: 80732e4248ce48ec92e1463ddc59451d
fileFormatVersion: 2
guid: 80732e4248ce48ec92e1463ddc59451d
timeCreated: 1534833891

4
com.unity.uiwidgets/Runtime/painting/image_provider.cs.meta


fileFormatVersion: 2
guid: 858587f8fb5d435e8a07a0ff46e5bc95
fileFormatVersion: 2
guid: 858587f8fb5d435e8a07a0ff46e5bc95
timeCreated: 1534820746

4
com.unity.uiwidgets/Runtime/painting/image_stream.cs.meta


fileFormatVersion: 2
guid: 462d84cff25d484895d1a81e7ebd2a24
fileFormatVersion: 2
guid: 462d84cff25d484895d1a81e7ebd2a24
timeCreated: 1534820764

4
com.unity.uiwidgets/Runtime/painting/notched_shapes.cs.meta


fileFormatVersion: 2
guid: c89c524fa7c242aa91900b63841be8b3
fileFormatVersion: 2
guid: c89c524fa7c242aa91900b63841be8b3
timeCreated: 1553153571

438
com.unity.uiwidgets/Runtime/painting/strut_style.cs


using System.Collections.Generic;
using System.Linq;
using Unity.UIWidgets.foundation;
using Unity.UIWidgets.ui;
namespace Unity.UIWidgets.painting {
public class StrutStyle : Diagnosticable {
public StrutStyle(
string fontFamily = null,
List<string> fontFamilyFallback = null,
float? fontSize = null,
float? height = null,
float? leading = null,
FontWeight fontWeight = null,
FontStyle? fontStyle = null,
bool forceStrutHeight = false,
string debugLabel = null
) {
D.assert(fontSize == null || fontSize > 0);
D.assert(leading == null || leading >= 0);
this.fontFamily = fontFamily;
this._fontFamilyFallback = fontFamilyFallback;
this.fontSize = fontSize;
this.height = height;
this.fontWeight = fontWeight;
this.fontStyle = fontStyle;
this.leading = leading;
this.forceStrutHeight = forceStrutHeight;
this.debugLabel = debugLabel;
}
public static StrutStyle fromTextStyle(
TextStyle textStyle,
string fontFamily = null,
List<string> fontFamilyFallback = null,
float? fontSize = null,
float? height = null,
float? leading = null,
FontWeight fontWeight = null,
FontStyle? fontStyle = null,
bool forceStrutHeight = false,
string debugLabel = null
) {
D.assert(textStyle != null);
D.assert(fontSize == null || fontSize > 0);
D.assert(leading == null || leading >= 0);
return new StrutStyle(
fontFamily: fontFamily ?? textStyle.fontFamily,
fontFamilyFallback: fontFamilyFallback ?? textStyle.fontFamilyFallback,
height: height ?? textStyle.height,
fontSize: fontSize ?? textStyle.fontSize,
fontWeight: fontWeight ?? textStyle.fontWeight,
fontStyle: fontStyle ?? textStyle.fontStyle,
debugLabel: debugLabel ?? textStyle.debugLabel
);
}
public static readonly StrutStyle disabled = new StrutStyle(
height: 0.0f,
leading: 0.0f
);
public readonly string fontFamily;
public List<string> fontFamilyFallback {
get { return this._fontFamilyFallback; }
}
readonly List<string> _fontFamilyFallback;
public readonly float? fontSize;
public readonly float? height;
public readonly FontWeight fontWeight;
public readonly FontStyle? fontStyle;
public readonly float? leading;
public readonly bool forceStrutHeight;
public readonly string debugLabel;
public RenderComparison compareTo(StrutStyle other) {
if (ReferenceEquals(this, other)) {
return RenderComparison.identical;
}
if (other == null) {
return RenderComparison.layout;
}
if (this.fontFamily != other.fontFamily ||
this.fontSize != other.fontSize ||
this.fontWeight != other.fontWeight ||
this.fontStyle != other.fontStyle ||
this.height != other.height ||
this.leading != other.leading ||
this.forceStrutHeight != other.forceStrutHeight ||
!CollectionUtils.equalsList(this.fontFamilyFallback, other.fontFamilyFallback)) {
return RenderComparison.layout;
}
return RenderComparison.identical;
}
public StrutStyle inheritFromTextStyle(TextStyle other) {
if (other == null) {
return this;
}
return new StrutStyle(
fontFamily: this.fontFamily ?? other.fontFamily,
fontFamilyFallback: this.fontFamilyFallback ?? other.fontFamilyFallback,
height: this.height ?? other.height,
leading: this.leading,
fontSize: this.fontSize ?? other.fontSize,
fontWeight: this.fontWeight ?? other.fontWeight,
fontStyle: this.fontStyle ?? other.fontStyle,
forceStrutHeight: this.forceStrutHeight,
debugLabel: this.debugLabel ?? other.debugLabel
);
}
public bool Equals(StrutStyle other) {
if (ReferenceEquals(null, other)) {
return false;
}
if (ReferenceEquals(this, other)) {
return true;
}
return this.fontFamily == other.fontFamily &&
this.fontSize == other.fontSize &&
this.fontWeight == other.fontWeight &&
this.fontStyle == other.fontStyle &&
this.height == other.height &&
this.leading == other.leading &&
this.forceStrutHeight == other.forceStrutHeight;
}
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((StrutStyle) obj);
}
public static bool operator ==(StrutStyle left, StrutStyle right) {
return Equals(left, right);
}
public static bool operator !=(StrutStyle left, StrutStyle right) {
return !Equals(left, right);
}
public override int GetHashCode() {
unchecked {
var hashCode = this.fontFamily?.GetHashCode() ?? 0;
hashCode = (hashCode * 397) ^ (this.fontSize?.GetHashCode() ?? 0);
hashCode = (hashCode * 397) ^ (this.fontWeight?.GetHashCode() ?? 0);
hashCode = (hashCode * 397) ^ (this.fontStyle?.GetHashCode() ?? 0);
hashCode = (hashCode * 397) ^ (this.height?.GetHashCode() ?? 0);
hashCode = (hashCode * 397) ^ (this.leading?.GetHashCode() ?? 0);
hashCode = (hashCode * 397) ^ this.forceStrutHeight.GetHashCode();
return hashCode;
}
}
public override string toStringShort() {
return $"{this.GetType()}";
}
public override void debugFillProperties(DiagnosticPropertiesBuilder properties) {
base.debugFillProperties(properties);
if (this.debugLabel != null) {
properties.add(new MessageProperty("debugLabel", this.debugLabel));
}
List<DiagnosticsNode> styles = new List<DiagnosticsNode>();
styles.Add(new StringProperty("family", this.fontFamily, defaultValue: Diagnostics.kNullDefaultValue,
quoted: false));
styles.Add(new EnumerableProperty<string>("familyFallback", this.fontFamilyFallback));
styles.Add(new DiagnosticsProperty<float?>("size", this.fontSize,
defaultValue: Diagnostics.kNullDefaultValue));
string weightDescription = "";
if (this.fontWeight != null) {
weightDescription = this.fontWeight.weightValue.ToString();
}
styles.Add(new DiagnosticsProperty<FontWeight>(
"weight", this.fontWeight,
description: weightDescription,
defaultValue: Diagnostics.kNullDefaultValue
));
styles.Add(new EnumProperty<FontStyle?>("style", this.fontStyle,
defaultValue: Diagnostics.kNullDefaultValue));
styles.Add(new DiagnosticsProperty<float?>("height", this.height,
defaultValue: Diagnostics.kNullDefaultValue));
styles.Add(new FlagProperty("forceStrutHeight", value: this.forceStrutHeight,
defaultValue: Diagnostics.kNullDefaultValue));
bool styleSpecified = styles.Any((DiagnosticsNode n) => !n.isFiltered(DiagnosticLevel.info));
foreach (var style in styles) {
properties.add(style);
}
if (!styleSpecified) {
properties.add(new FlagProperty("forceStrutHeight", value: this.forceStrutHeight,
ifTrue: "<strut height forced>",
ifFalse: "<strut height normal>"));
}
}
}
using System.Collections.Generic;
using System.Linq;
using Unity.UIWidgets.foundation;
using Unity.UIWidgets.ui;
namespace Unity.UIWidgets.painting {
public class StrutStyle : Diagnosticable {
public StrutStyle(
string fontFamily = null,
List<string> fontFamilyFallback = null,
float? fontSize = null,
float? height = null,
float? leading = null,
FontWeight fontWeight = null,
FontStyle? fontStyle = null,
bool forceStrutHeight = false,
string debugLabel = null
) {
D.assert(fontSize == null || fontSize > 0);
D.assert(leading == null || leading >= 0);
this.fontFamily = fontFamily;
this._fontFamilyFallback = fontFamilyFallback;
this.fontSize = fontSize;
this.height = height;
this.fontWeight = fontWeight;
this.fontStyle = fontStyle;
this.leading = leading;
this.forceStrutHeight = forceStrutHeight;
this.debugLabel = debugLabel;
}
public static StrutStyle fromTextStyle(
TextStyle textStyle,
string fontFamily = null,
List<string> fontFamilyFallback = null,
float? fontSize = null,
float? height = null,
float? leading = null,
FontWeight fontWeight = null,
FontStyle? fontStyle = null,
bool forceStrutHeight = false,
string debugLabel = null
) {
D.assert(textStyle != null);
D.assert(fontSize == null || fontSize > 0);
D.assert(leading == null || leading >= 0);
return new StrutStyle(
fontFamily: fontFamily ?? textStyle.fontFamily,
fontFamilyFallback: fontFamilyFallback ?? textStyle.fontFamilyFallback,
height: height ?? textStyle.height,
fontSize: fontSize ?? textStyle.fontSize,
fontWeight: fontWeight ?? textStyle.fontWeight,
fontStyle: fontStyle ?? textStyle.fontStyle,
debugLabel: debugLabel ?? textStyle.debugLabel
);
}
public static readonly StrutStyle disabled = new StrutStyle(
height: 0.0f,
leading: 0.0f
);
public readonly string fontFamily;
public List<string> fontFamilyFallback {
get { return this._fontFamilyFallback; }
}
readonly List<string> _fontFamilyFallback;
public readonly float? fontSize;
public readonly float? height;
public readonly FontWeight fontWeight;
public readonly FontStyle? fontStyle;
public readonly float? leading;
public readonly bool forceStrutHeight;
public readonly string debugLabel;
public RenderComparison compareTo(StrutStyle other) {
if (ReferenceEquals(this, other)) {
return RenderComparison.identical;
}
if (other == null) {
return RenderComparison.layout;
}
if (this.fontFamily != other.fontFamily ||
this.fontSize != other.fontSize ||
this.fontWeight != other.fontWeight ||
this.fontStyle != other.fontStyle ||
this.height != other.height ||
this.leading != other.leading ||
this.forceStrutHeight != other.forceStrutHeight ||
!CollectionUtils.equalsList(this.fontFamilyFallback, other.fontFamilyFallback)) {
return RenderComparison.layout;
}
return RenderComparison.identical;
}
public StrutStyle inheritFromTextStyle(TextStyle other) {
if (other == null) {
return this;
}
return new StrutStyle(
fontFamily: this.fontFamily ?? other.fontFamily,
fontFamilyFallback: this.fontFamilyFallback ?? other.fontFamilyFallback,
height: this.height ?? other.height,
leading: this.leading,
fontSize: this.fontSize ?? other.fontSize,
fontWeight: this.fontWeight ?? other.fontWeight,
fontStyle: this.fontStyle ?? other.fontStyle,
forceStrutHeight: this.forceStrutHeight,
debugLabel: this.debugLabel ?? other.debugLabel
);
}
public bool Equals(StrutStyle other) {
if (ReferenceEquals(null, other)) {
return false;
}
if (ReferenceEquals(this, other)) {
return true;
}
return this.fontFamily == other.fontFamily &&
this.fontSize == other.fontSize &&
this.fontWeight == other.fontWeight &&
this.fontStyle == other.fontStyle &&
this.height == other.height &&
this.leading == other.leading &&
this.forceStrutHeight == other.forceStrutHeight;
}
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((StrutStyle) obj);
}
public static bool operator ==(StrutStyle left, StrutStyle right) {
return Equals(left, right);
}
public static bool operator !=(StrutStyle left, StrutStyle right) {
return !Equals(left, right);
}
public override int GetHashCode() {
unchecked {
var hashCode = this.fontFamily?.GetHashCode() ?? 0;
hashCode = (hashCode * 397) ^ (this.fontSize?.GetHashCode() ?? 0);
hashCode = (hashCode * 397) ^ (this.fontWeight?.GetHashCode() ?? 0);
hashCode = (hashCode * 397) ^ (this.fontStyle?.GetHashCode() ?? 0);
hashCode = (hashCode * 397) ^ (this.height?.GetHashCode() ?? 0);
hashCode = (hashCode * 397) ^ (this.leading?.GetHashCode() ?? 0);
hashCode = (hashCode * 397) ^ this.forceStrutHeight.GetHashCode();
return hashCode;
}
}
public override string toStringShort() {
return $"{this.GetType()}";
}
public override void debugFillProperties(DiagnosticPropertiesBuilder properties) {
base.debugFillProperties(properties);
if (this.debugLabel != null) {
properties.add(new MessageProperty("debugLabel", this.debugLabel));
}
List<DiagnosticsNode> styles = new List<DiagnosticsNode>();
styles.Add(new StringProperty("family", this.fontFamily, defaultValue: Diagnostics.kNullDefaultValue,
quoted: false));
styles.Add(new EnumerableProperty<string>("familyFallback", this.fontFamilyFallback));
styles.Add(new DiagnosticsProperty<float?>("size", this.fontSize,
defaultValue: Diagnostics.kNullDefaultValue));
string weightDescription = "";
if (this.fontWeight != null) {
weightDescription = this.fontWeight.weightValue.ToString();
}
styles.Add(new DiagnosticsProperty<FontWeight>(
"weight", this.fontWeight,
description: weightDescription,
defaultValue: Diagnostics.kNullDefaultValue
));
styles.Add(new EnumProperty<FontStyle?>("style", this.fontStyle,
defaultValue: Diagnostics.kNullDefaultValue));
styles.Add(new DiagnosticsProperty<float?>("height", this.height,
defaultValue: Diagnostics.kNullDefaultValue));
styles.Add(new FlagProperty("forceStrutHeight", value: this.forceStrutHeight,
defaultValue: Diagnostics.kNullDefaultValue));
bool styleSpecified = styles.Any((DiagnosticsNode n) => !n.isFiltered(DiagnosticLevel.info));
foreach (var style in styles) {
properties.add(style);
}
if (!styleSpecified) {
properties.add(new FlagProperty("forceStrutHeight", value: this.forceStrutHeight,
ifTrue: "<strut height forced>",
ifFalse: "<strut height normal>"));
}
}
}
}

4
com.unity.uiwidgets/Runtime/material/app_bar_theme.cs.meta


fileFormatVersion: 2
guid: 0c0ee979ef6b4f32a092532c3bdae31e
fileFormatVersion: 2
guid: 0c0ee979ef6b4f32a092532c3bdae31e
timeCreated: 1556178331

4
com.unity.uiwidgets/Runtime/material/bottom_app_bar.cs.meta


fileFormatVersion: 2
guid: aa89369405044a62a19225b2c20815f6
fileFormatVersion: 2
guid: aa89369405044a62a19225b2c20815f6
timeCreated: 1553156127

4
com.unity.uiwidgets/Runtime/material/bottom_app_bar_theme.cs.meta


fileFormatVersion: 2
guid: 9c88d19dd1254f4eb6c0c998084832ea
fileFormatVersion: 2
guid: 9c88d19dd1254f4eb6c0c998084832ea
timeCreated: 1556185402

4
com.unity.uiwidgets/Runtime/material/bottom_navigation_bar.cs.meta


fileFormatVersion: 2
guid: 6b8f793d1b8d4004b2c19c1c085752c3
fileFormatVersion: 2
guid: 6b8f793d1b8d4004b2c19c1c085752c3
timeCreated: 1553161698

4
com.unity.uiwidgets/Runtime/material/card_theme.cs.meta


fileFormatVersion: 2
guid: d74c4f94f0994a3880425c80ec3d9ba3
fileFormatVersion: 2
guid: d74c4f94f0994a3880425c80ec3d9ba3
timeCreated: 1556187816

4
com.unity.uiwidgets/Runtime/material/chip.cs.meta


fileFormatVersion: 2
guid: d4ca6b86209d4615b9aba98d6d112673
fileFormatVersion: 2
guid: d4ca6b86209d4615b9aba98d6d112673
timeCreated: 1555477997

4
com.unity.uiwidgets/Runtime/material/chip_theme.cs.meta


fileFormatVersion: 2
guid: 4d46bfb5d5bb492e92f07114849df905
fileFormatVersion: 2
guid: 4d46bfb5d5bb492e92f07114849df905
timeCreated: 1556165564

4
com.unity.uiwidgets/Runtime/material/circle_avatar.cs.meta


fileFormatVersion: 2
guid: 32591e65e11049cab124c86bc8fe573c
fileFormatVersion: 2
guid: 32591e65e11049cab124c86bc8fe573c
timeCreated: 1556169017

4
com.unity.uiwidgets/Runtime/material/dropdown.cs.meta


fileFormatVersion: 2
guid: 54d382ec712d4e87b802716ca97c1f3d
fileFormatVersion: 2
guid: 54d382ec712d4e87b802716ca97c1f3d
timeCreated: 1552537966

256
com.unity.uiwidgets/Runtime/material/floatting_action_button_theme.cs


using Unity.UIWidgets.foundation;
using Unity.UIWidgets.painting;
using Unity.UIWidgets.ui;
namespace Unity.UIWidgets.material {
public class FloatingActionButtonThemeData : Diagnosticable {
public FloatingActionButtonThemeData(
Color backgroundColor = null,
Color foregroundColor = null,
float? elevation = null,
float? disabledElevation = null,
float? highlightElevation = null,
ShapeBorder shape = null
) {
this.backgroundColor = backgroundColor;
this.foregroundColor = foregroundColor;
this.elevation = elevation;
this.disabledElevation = disabledElevation;
this.highlightElevation = highlightElevation;
this.shape = shape;
}
public readonly Color backgroundColor;
public readonly Color foregroundColor;
public readonly float? elevation;
public readonly float? disabledElevation;
public readonly float? highlightElevation;
public readonly ShapeBorder shape;
public FloatingActionButtonThemeData copyWith(
Color backgroundColor,
Color foregroundColor,
float? elevation,
float? disabledElevation,
float? highlightElevation,
ShapeBorder shape
) {
return new FloatingActionButtonThemeData(
backgroundColor: backgroundColor ?? this.backgroundColor,
foregroundColor: foregroundColor ?? this.foregroundColor,
elevation: elevation ?? this.elevation,
disabledElevation: disabledElevation ?? this.disabledElevation,
highlightElevation: highlightElevation ?? this.highlightElevation,
shape: shape ?? this.shape
);
}
public static FloatingActionButtonThemeData lerp(FloatingActionButtonThemeData a, FloatingActionButtonThemeData b,
float t) {
if (a == null && b == null) {
return null;
}
return new FloatingActionButtonThemeData(
backgroundColor: Color.lerp(a?.backgroundColor, b?.backgroundColor, t),
foregroundColor: Color.lerp(a?.foregroundColor, b?.foregroundColor, t),
elevation: MathUtils.lerpFloat(a?.elevation ?? 0, b?.elevation ?? 0, t),
disabledElevation: MathUtils.lerpFloat(a?.disabledElevation ?? 0, b?.disabledElevation ?? 0, t),
highlightElevation: MathUtils.lerpFloat(a?.highlightElevation ?? 0, b?.highlightElevation ?? 0, t),
shape: ShapeBorder.lerp(a?.shape, b?.shape, t)
);
}
public override int GetHashCode() {
var hashCode = this.backgroundColor?.GetHashCode() ?? 0;
hashCode = (hashCode * 397) ^ this.foregroundColor?.GetHashCode() ?? 0;
hashCode = (hashCode * 397) ^ this.elevation?.GetHashCode() ?? 0;
hashCode = (hashCode * 397) ^ this.disabledElevation?.GetHashCode() ?? 0;
hashCode = (hashCode * 397) ^ this.highlightElevation?.GetHashCode() ?? 0;
hashCode = (hashCode * 397) ^ this.shape?.GetHashCode() ?? 0;
return hashCode;
}
public bool Equals(FloatingActionButtonThemeData other) {
if (ReferenceEquals(null, other)) {
return false;
}
if (ReferenceEquals(this, other)) {
return true;
}
return Equals(this.backgroundColor, other.backgroundColor)
&& Equals(this.elevation, other.elevation)
&& Equals(this.shape, other.shape)
&& Equals(this.foregroundColor, other.foregroundColor)
&& Equals(this.disabledElevation, other.disabledElevation)
&& Equals(this.highlightElevation, other.highlightElevation);
}
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((FloatingActionButtonThemeData) obj);
}
public override void debugFillProperties(DiagnosticPropertiesBuilder properties) {
base.debugFillProperties(properties);
FloatingActionButtonThemeData defaultData = new FloatingActionButtonThemeData();
properties.add(new DiagnosticsProperty<Color>("backgroundColor", this.backgroundColor,
defaultValue: defaultData.backgroundColor));
properties.add(new DiagnosticsProperty<Color>("foregroundColor", this.foregroundColor,
defaultValue: defaultData.foregroundColor));
properties.add(new DiagnosticsProperty<float?>("elevation", this.elevation,
defaultValue: defaultData.elevation));
properties.add(new DiagnosticsProperty<float?>("disabledElevation", this.disabledElevation,
defaultValue: defaultData.disabledElevation));
properties.add(new DiagnosticsProperty<float?>("highlightElevation", this.highlightElevation,
defaultValue: defaultData.highlightElevation));
properties.add(new DiagnosticsProperty<ShapeBorder>("shape", this.shape, defaultValue: defaultData.shape));
}
}
using Unity.UIWidgets.foundation;
using Unity.UIWidgets.painting;
using Unity.UIWidgets.ui;
namespace Unity.UIWidgets.material {
public class FloatingActionButtonThemeData : Diagnosticable {
public FloatingActionButtonThemeData(
Color backgroundColor = null,
Color foregroundColor = null,
float? elevation = null,
float? disabledElevation = null,
float? highlightElevation = null,
ShapeBorder shape = null
) {
this.backgroundColor = backgroundColor;
this.foregroundColor = foregroundColor;
this.elevation = elevation;
this.disabledElevation = disabledElevation;
this.highlightElevation = highlightElevation;
this.shape = shape;
}
public readonly Color backgroundColor;
public readonly Color foregroundColor;
public readonly float? elevation;
public readonly float? disabledElevation;
public readonly float? highlightElevation;
public readonly ShapeBorder shape;
public FloatingActionButtonThemeData copyWith(
Color backgroundColor,
Color foregroundColor,
float? elevation,
float? disabledElevation,
float? highlightElevation,
ShapeBorder shape
) {
return new FloatingActionButtonThemeData(
backgroundColor: backgroundColor ?? this.backgroundColor,
foregroundColor: foregroundColor ?? this.foregroundColor,
elevation: elevation ?? this.elevation,
disabledElevation: disabledElevation ?? this.disabledElevation,
highlightElevation: highlightElevation ?? this.highlightElevation,
shape: shape ?? this.shape
);
}
public static FloatingActionButtonThemeData lerp(FloatingActionButtonThemeData a, FloatingActionButtonThemeData b,
float t) {
if (a == null && b == null) {
return null;
}
return new FloatingActionButtonThemeData(
backgroundColor: Color.lerp(a?.backgroundColor, b?.backgroundColor, t),
foregroundColor: Color.lerp(a?.foregroundColor, b?.foregroundColor, t),
elevation: MathUtils.lerpFloat(a?.elevation ?? 0, b?.elevation ?? 0, t),
disabledElevation: MathUtils.lerpFloat(a?.disabledElevation ?? 0, b?.disabledElevation ?? 0, t),
highlightElevation: MathUtils.lerpFloat(a?.highlightElevation ?? 0, b?.highlightElevation ?? 0, t),
shape: ShapeBorder.lerp(a?.shape, b?.shape, t)
);
}
public override int GetHashCode() {
var hashCode = this.backgroundColor?.GetHashCode() ?? 0;
hashCode = (hashCode * 397) ^ this.foregroundColor?.GetHashCode() ?? 0;
hashCode = (hashCode * 397) ^ this.elevation?.GetHashCode() ?? 0;
hashCode = (hashCode * 397) ^ this.disabledElevation?.GetHashCode() ?? 0;
hashCode = (hashCode * 397) ^ this.highlightElevation?.GetHashCode() ?? 0;
hashCode = (hashCode * 397) ^ this.shape?.GetHashCode() ?? 0;
return hashCode;
}
public bool Equals(FloatingActionButtonThemeData other) {
if (ReferenceEquals(null, other)) {
return false;
}
if (ReferenceEquals(this, other)) {
return true;
}
return Equals(this.backgroundColor, other.backgroundColor)
&& Equals(this.elevation, other.elevation)
&& Equals(this.shape, other.shape)
&& Equals(this.foregroundColor, other.foregroundColor)
&& Equals(this.disabledElevation, other.disabledElevation)
&& Equals(this.highlightElevation, other.highlightElevation);
}
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((FloatingActionButtonThemeData) obj);
}
public override void debugFillProperties(DiagnosticPropertiesBuilder properties) {
base.debugFillProperties(properties);
FloatingActionButtonThemeData defaultData = new FloatingActionButtonThemeData();
properties.add(new DiagnosticsProperty<Color>("backgroundColor", this.backgroundColor,
defaultValue: defaultData.backgroundColor));
properties.add(new DiagnosticsProperty<Color>("foregroundColor", this.foregroundColor,
defaultValue: defaultData.foregroundColor));
properties.add(new DiagnosticsProperty<float?>("elevation", this.elevation,
defaultValue: defaultData.elevation));
properties.add(new DiagnosticsProperty<float?>("disabledElevation", this.disabledElevation,
defaultValue: defaultData.disabledElevation));
properties.add(new DiagnosticsProperty<float?>("highlightElevation", this.highlightElevation,
defaultValue: defaultData.highlightElevation));
properties.add(new DiagnosticsProperty<ShapeBorder>("shape", this.shape, defaultValue: defaultData.shape));
}
}
}

4
com.unity.uiwidgets/Runtime/material/input_border.cs.meta


fileFormatVersion: 2
guid: 6431f8efd0b444ea9982ff6d0a0e74f4
fileFormatVersion: 2
guid: 6431f8efd0b444ea9982ff6d0a0e74f4
timeCreated: 1552619063

4
com.unity.uiwidgets/Runtime/material/input_decorator.cs.meta


fileFormatVersion: 2
guid: 2106361ab28b4560a12fdbae0f1b1c8f
fileFormatVersion: 2
guid: 2106361ab28b4560a12fdbae0f1b1c8f
timeCreated: 1552548801

4
com.unity.uiwidgets/Runtime/material/outline_button.cs.meta


fileFormatVersion: 2
guid: 5c535b1d86054795b33e7f0f358d957a
fileFormatVersion: 2
guid: 5c535b1d86054795b33e7f0f358d957a
timeCreated: 1552641292

4
com.unity.uiwidgets/Runtime/material/progress_indicator.cs.meta


fileFormatVersion: 2
guid: 42b0b0b180624c38b2dec573a232bd8a
fileFormatVersion: 2
guid: 42b0b0b180624c38b2dec573a232bd8a
timeCreated: 1552530632

4
com.unity.uiwidgets/Runtime/material/radio.cs.meta


fileFormatVersion: 2
guid: 1328fb437a4047c49b51dfe3a2c3d106
fileFormatVersion: 2
guid: 1328fb437a4047c49b51dfe3a2c3d106
timeCreated: 1553154501

4
com.unity.uiwidgets/Runtime/material/refresh_indicator.cs.meta


fileFormatVersion: 2
guid: 74dd879101fe4541a5b42619cf4f309c
fileFormatVersion: 2
guid: 74dd879101fe4541a5b42619cf4f309c
timeCreated: 1554344854

4
com.unity.uiwidgets/Runtime/material/text_form_field.cs.meta


fileFormatVersion: 2
guid: 0a9f1467be1c4653b3dbf8a1c7209f70
fileFormatVersion: 2
guid: 0a9f1467be1c4653b3dbf8a1c7209f70
timeCreated: 1557304128

4
com.unity.uiwidgets/Runtime/material/user_accounts_drawer_header.cs.meta


fileFormatVersion: 2
guid: fb34d1a7ff484d05b8074a10730d51a5
fileFormatVersion: 2
guid: fb34d1a7ff484d05b8074a10730d51a5
timeCreated: 1554352270

4
com.unity.uiwidgets/Runtime/material/animated_icons/animated_icons_data.cs.meta


fileFormatVersion: 2
guid: 439a75e2cc39472ba806029b41996e9b
fileFormatVersion: 2
guid: 439a75e2cc39472ba806029b41996e9b
timeCreated: 1552892371

4
com.unity.uiwidgets/Runtime/material/animated_icons/data/arrow_menu.g.cs.meta


fileFormatVersion: 2
guid: f38795e53cc54f628c2125e5e50fea1c
fileFormatVersion: 2
guid: f38795e53cc54f628c2125e5e50fea1c
timeCreated: 1552894502

4
com.unity.uiwidgets/Runtime/material/animated_icons/data/close_menu.g.cs.meta


fileFormatVersion: 2
guid: e3a716495016460c8599ef52f9bd690f
fileFormatVersion: 2
guid: e3a716495016460c8599ef52f9bd690f
timeCreated: 1552894786

4
com.unity.uiwidgets/Runtime/foundation/constants.cs.meta


fileFormatVersion: 2
guid: 36d19e17f3d947f98c7accec2cd5771b
fileFormatVersion: 2
guid: 36d19e17f3d947f98c7accec2cd5771b
timeCreated: 1556097117

406
com.unity.uiwidgets/Runtime/cupertino/bottom_app_bar.cs


using System.Collections.Generic;
using Unity.UIWidgets.foundation;
using Unity.UIWidgets.gestures;
using Unity.UIWidgets.painting;
using Unity.UIWidgets.rendering;
using Unity.UIWidgets.ui;
using Unity.UIWidgets.widgets;
using TextStyle = Unity.UIWidgets.painting.TextStyle;
namespace Unity.UIWidgets.cupertino {
class BottomAppBarUtils {
public const float _kTabBarHeight = 50.0f;
public static readonly Color _kDefaultTabBarBorderColor = new Color(0x4C000000);
}
public class CupertinoTabBar : StatelessWidget {
public CupertinoTabBar(
Key key = null,
List<BottomNavigationBarItem> items = null,
ValueChanged<int> onTap = null,
int currentIndex = 0,
Color backgroundColor = null,
Color activeColor = null,
Color inactiveColor = null,
float iconSize = 30.0f,
Border border = null
) : base(key: key) {
D.assert(items != null);
D.assert(items.Count >= 2,
() => "Tabs need at least 2 items to conform to Apple's HIG"
);
D.assert(0 <= currentIndex && currentIndex < items.Count);
this.items = items;
this.onTap = onTap;
this.currentIndex = currentIndex;
this.backgroundColor = backgroundColor;
this.activeColor = activeColor;
this.inactiveColor = inactiveColor ?? CupertinoColors.inactiveGray;
this.iconSize = iconSize;
this.border = border ?? new Border(
top: new BorderSide(
color: BottomAppBarUtils._kDefaultTabBarBorderColor,
width: 0.0f, // One physical pixel.
style: BorderStyle.solid
)
);
}
public readonly List<BottomNavigationBarItem> items;
public readonly ValueChanged<int> onTap;
public readonly int currentIndex;
public readonly Color backgroundColor;
public readonly Color activeColor;
public readonly Color inactiveColor;
public readonly float iconSize;
public readonly Border border;
public Size preferredSize {
get { return Size.fromHeight(BottomAppBarUtils._kTabBarHeight); }
}
public bool opaque(BuildContext context) {
Color backgroundColor =
this.backgroundColor ?? CupertinoTheme.of(context).barBackgroundColor;
return backgroundColor.alpha == 0xFF;
}
public override Widget build(BuildContext context) {
float bottomPadding = MediaQuery.of(context).padding.bottom;
Widget result = new DecoratedBox(
decoration: new BoxDecoration(
border: this.border,
color: this.backgroundColor ?? CupertinoTheme.of(context).barBackgroundColor
),
child: new SizedBox(
height: BottomAppBarUtils._kTabBarHeight + bottomPadding,
child: IconTheme.merge( // Default with the inactive state.
data: new IconThemeData(
color: this.inactiveColor,
size: this.iconSize
),
child: new DefaultTextStyle( // Default with the inactive state.
style: CupertinoTheme.of(context).textTheme.tabLabelTextStyle
.copyWith(color: this.inactiveColor),
child: new Padding(
padding: EdgeInsets.only(bottom: bottomPadding),
child: new Row(
crossAxisAlignment: CrossAxisAlignment.end,
children: this._buildTabItems(context)
)
)
)
)
)
);
if (!this.opaque(context)) {
result = new ClipRect(
child: new BackdropFilter(
filter: ImageFilter.blur(sigmaX: 10.0f, sigmaY: 10.0f),
child: result
)
);
}
return result;
}
List<Widget> _buildTabItems(BuildContext context) {
List<Widget> result = new List<Widget> { };
for (int index = 0; index < this.items.Count; index += 1) {
bool active = index == this.currentIndex;
var tabIndex = index;
result.Add(
this._wrapActiveItem(
context,
new Expanded(
child: new GestureDetector(
behavior: HitTestBehavior.opaque,
onTap: this.onTap == null ? null : (GestureTapCallback) (() => { this.onTap(tabIndex); }),
child: new Padding(
padding: EdgeInsets.only(bottom: 4.0f),
child: new Column(
mainAxisAlignment: MainAxisAlignment.end,
children: this._buildSingleTabItem(this.items[index], active)
)
)
)
),
active: active
)
);
}
return result;
}
List<Widget> _buildSingleTabItem(BottomNavigationBarItem item, bool active) {
List<Widget> components = new List<Widget> {
new Expanded(
child: new Center(child: active ? item.activeIcon : item.icon)
)
};
if (item.title != null) {
components.Add(item.title);
}
return components;
}
Widget _wrapActiveItem(BuildContext context, Widget item, bool active) {
if (!active) {
return item;
}
Color activeColor = this.activeColor ?? CupertinoTheme.of(context).primaryColor;
return IconTheme.merge(
data: new IconThemeData(color: activeColor),
child: DefaultTextStyle.merge(
style: new TextStyle(color: activeColor),
child: item
)
);
}
public CupertinoTabBar copyWith(
Key key = null,
List<BottomNavigationBarItem> items = null,
Color backgroundColor = null,
Color activeColor = null,
Color inactiveColor = null,
float? iconSize = null,
Border border = null,
int? currentIndex = null,
ValueChanged<int> onTap = null
) {
return new CupertinoTabBar(
key: key ?? this.key,
items: items ?? this.items,
backgroundColor: backgroundColor ?? this.backgroundColor,
activeColor: activeColor ?? this.activeColor,
inactiveColor: inactiveColor ?? this.inactiveColor,
iconSize: iconSize ?? this.iconSize,
border: border ?? this.border,
currentIndex: currentIndex ?? this.currentIndex,
onTap: onTap ?? this.onTap
);
}
}
using System.Collections.Generic;
using Unity.UIWidgets.foundation;
using Unity.UIWidgets.gestures;
using Unity.UIWidgets.painting;
using Unity.UIWidgets.rendering;
using Unity.UIWidgets.ui;
using Unity.UIWidgets.widgets;
using TextStyle = Unity.UIWidgets.painting.TextStyle;
namespace Unity.UIWidgets.cupertino {
class BottomAppBarUtils {
public const float _kTabBarHeight = 50.0f;
public static readonly Color _kDefaultTabBarBorderColor = new Color(0x4C000000);
}
public class CupertinoTabBar : StatelessWidget {
public CupertinoTabBar(
Key key = null,
List<BottomNavigationBarItem> items = null,
ValueChanged<int> onTap = null,
int currentIndex = 0,
Color backgroundColor = null,
Color activeColor = null,
Color inactiveColor = null,
float iconSize = 30.0f,
Border border = null
) : base(key: key) {
D.assert(items != null);
D.assert(items.Count >= 2,
() => "Tabs need at least 2 items to conform to Apple's HIG"
);
D.assert(0 <= currentIndex && currentIndex < items.Count);
this.items = items;
this.onTap = onTap;
this.currentIndex = currentIndex;
this.backgroundColor = backgroundColor;
this.activeColor = activeColor;
this.inactiveColor = inactiveColor ?? CupertinoColors.inactiveGray;
this.iconSize = iconSize;
this.border = border ?? new Border(
top: new BorderSide(
color: BottomAppBarUtils._kDefaultTabBarBorderColor,
width: 0.0f, // One physical pixel.
style: BorderStyle.solid
)
);
}
public readonly List<BottomNavigationBarItem> items;
public readonly ValueChanged<int> onTap;
public readonly int currentIndex;
public readonly Color backgroundColor;
public readonly Color activeColor;
public readonly Color inactiveColor;
public readonly float iconSize;
public readonly Border border;
public Size preferredSize {
get { return Size.fromHeight(BottomAppBarUtils._kTabBarHeight); }
}
public bool opaque(BuildContext context) {
Color backgroundColor =
this.backgroundColor ?? CupertinoTheme.of(context).barBackgroundColor;
return backgroundColor.alpha == 0xFF;
}
public override Widget build(BuildContext context) {
float bottomPadding = MediaQuery.of(context).padding.bottom;
Widget result = new DecoratedBox(
decoration: new BoxDecoration(
border: this.border,
color: this.backgroundColor ?? CupertinoTheme.of(context).barBackgroundColor
),
child: new SizedBox(
height: BottomAppBarUtils._kTabBarHeight + bottomPadding,
child: IconTheme.merge( // Default with the inactive state.
data: new IconThemeData(
color: this.inactiveColor,
size: this.iconSize
),
child: new DefaultTextStyle( // Default with the inactive state.
style: CupertinoTheme.of(context).textTheme.tabLabelTextStyle
.copyWith(color: this.inactiveColor),
child: new Padding(
padding: EdgeInsets.only(bottom: bottomPadding),
child: new Row(
crossAxisAlignment: CrossAxisAlignment.end,
children: this._buildTabItems(context)
)
)
)
)
)
);
if (!this.opaque(context)) {
result = new ClipRect(
child: new BackdropFilter(
filter: ImageFilter.blur(sigmaX: 10.0f, sigmaY: 10.0f),
child: result
)
);
}
return result;
}
List<Widget> _buildTabItems(BuildContext context) {
List<Widget> result = new List<Widget> { };
for (int index = 0; index < this.items.Count; index += 1) {
bool active = index == this.currentIndex;
var tabIndex = index;
result.Add(
this._wrapActiveItem(
context,
new Expanded(
child: new GestureDetector(
behavior: HitTestBehavior.opaque,
onTap: this.onTap == null ? null : (GestureTapCallback) (() => { this.onTap(tabIndex); }),
child: new Padding(
padding: EdgeInsets.only(bottom: 4.0f),
child: new Column(
mainAxisAlignment: MainAxisAlignment.end,
children: this._buildSingleTabItem(this.items[index], active)
)
)
)
),
active: active
)
);
}
return result;
}
List<Widget> _buildSingleTabItem(BottomNavigationBarItem item, bool active) {
List<Widget> components = new List<Widget> {
new Expanded(
child: new Center(child: active ? item.activeIcon : item.icon)
)
};
if (item.title != null) {
components.Add(item.title);
}
return components;
}
Widget _wrapActiveItem(BuildContext context, Widget item, bool active) {
if (!active) {
return item;
}
Color activeColor = this.activeColor ?? CupertinoTheme.of(context).primaryColor;
return IconTheme.merge(
data: new IconThemeData(color: activeColor),
child: DefaultTextStyle.merge(
style: new TextStyle(color: activeColor),
child: item
)
);
}
public CupertinoTabBar copyWith(
Key key = null,
List<BottomNavigationBarItem> items = null,
Color backgroundColor = null,
Color activeColor = null,
Color inactiveColor = null,
float? iconSize = null,
Border border = null,
int? currentIndex = null,
ValueChanged<int> onTap = null
) {
return new CupertinoTabBar(
key: key ?? this.key,
items: items ?? this.items,
backgroundColor: backgroundColor ?? this.backgroundColor,
activeColor: activeColor ?? this.activeColor,
inactiveColor: inactiveColor ?? this.inactiveColor,
iconSize: iconSize ?? this.iconSize,
border: border ?? this.border,
currentIndex: currentIndex ?? this.currentIndex,
onTap: onTap ?? this.onTap
);
}
}
}

1001
com.unity.uiwidgets/Runtime/cupertino/nav_bar.cs
文件差异内容过多而无法显示
查看文件

758
com.unity.uiwidgets/Runtime/cupertino/slider.cs


using System;
using Unity.UIWidgets.animation;
using Unity.UIWidgets.foundation;
using Unity.UIWidgets.gestures;
using Unity.UIWidgets.rendering;
using Unity.UIWidgets.scheduler;
using Unity.UIWidgets.ui;
using Unity.UIWidgets.widgets;
using UnityEngine;
using Canvas = Unity.UIWidgets.ui.Canvas;
using Color = Unity.UIWidgets.ui.Color;
using Rect = Unity.UIWidgets.ui.Rect;
namespace Unity.UIWidgets.cupertino {
class SliderUtils {
public const float _kPadding = 8.0f;
public static readonly Color _kTrackColor = new Color(0xFFB5B5B5);
public const float _kSliderHeight = 2.0f * (CupertinoThumbPainter.radius + _kPadding);
public const float _kSliderWidth = 176.0f; // Matches Material Design slider.
public static readonly TimeSpan _kDiscreteTransitionDuration = new TimeSpan(0, 0, 0, 0, 500);
public const float _kAdjustmentUnit = 0.1f; // Matches iOS implementation of material slider.
}
public class CupertinoSlider : StatefulWidget {
public CupertinoSlider(
Key key = null,
float? value = null,
ValueChanged<float> onChanged = null,
ValueChanged<float> onChangeStart = null,
ValueChanged<float> onChangeEnd = null,
float min = 0.0f,
float max = 1.0f,
int? divisions = null,
Color activeColor = null
) : base(key: key) {
D.assert(value != null);
D.assert(onChanged != null);
D.assert(value >= min && value <= max);
D.assert(divisions == null || divisions > 0);
this.value = value.Value;
this.onChanged = onChanged;
this.onChangeStart = onChangeStart;
this.onChangeEnd = onChangeEnd;
this.min = min;
this.max = max;
this.divisions = divisions;
this.activeColor = activeColor;
}
public readonly float value;
public readonly ValueChanged<float> onChanged;
public readonly ValueChanged<float> onChangeStart;
public readonly ValueChanged<float> onChangeEnd;
public readonly float min;
public readonly float max;
public readonly int? divisions;
public readonly Color activeColor;
public override State createState() {
return new _CupertinoSliderState();
}
public override void debugFillProperties(DiagnosticPropertiesBuilder properties) {
base.debugFillProperties(properties);
properties.add(new FloatProperty("value", this.value));
properties.add(new FloatProperty("min", this.min));
properties.add(new FloatProperty("max", this.max));
}
}
class _CupertinoSliderState : TickerProviderStateMixin<CupertinoSlider> {
void _handleChanged(float value) {
D.assert(this.widget.onChanged != null);
float lerpValue = MathUtils.lerpFloat(this.widget.min, this.widget.max, value);
if (lerpValue != this.widget.value) {
this.widget.onChanged(lerpValue);
}
}
void _handleDragStart(float value) {
D.assert(this.widget.onChangeStart != null);
this.widget.onChangeStart(MathUtils.lerpFloat(this.widget.min, this.widget.max, value));
}
void _handleDragEnd(float value) {
D.assert(this.widget.onChangeEnd != null);
this.widget.onChangeEnd(MathUtils.lerpFloat(this.widget.min, this.widget.max, value));
}
public override Widget build(BuildContext context) {
return new _CupertinoSliderRenderObjectWidget(
value: (this.widget.value - this.widget.min) / (this.widget.max - this.widget.min),
divisions: this.widget.divisions,
activeColor: this.widget.activeColor ?? CupertinoTheme.of(context).primaryColor,
onChanged: this.widget.onChanged != null ? (ValueChanged<float>) this._handleChanged : null,
onChangeStart: this.widget.onChangeStart != null ? (ValueChanged<float>) this._handleDragStart : null,
onChangeEnd: this.widget.onChangeEnd != null ? (ValueChanged<float>) this._handleDragEnd : null,
vsync: this
);
}
}
class _CupertinoSliderRenderObjectWidget : LeafRenderObjectWidget {
public _CupertinoSliderRenderObjectWidget(
Key key = null,
float? value = null,
int? divisions = null,
Color activeColor = null,
ValueChanged<float> onChanged = null,
ValueChanged<float> onChangeStart = null,
ValueChanged<float> onChangeEnd = null,
TickerProvider vsync = null
) : base(key: key) {
this.value = value;
this.divisions = divisions;
this.activeColor = activeColor;
this.onChanged = onChanged;
this.onChangeStart = onChangeStart;
this.onChangeEnd = onChangeEnd;
this.vsync = vsync;
}
public readonly float? value;
public readonly int? divisions;
public readonly Color activeColor;
public readonly ValueChanged<float> onChanged;
public readonly ValueChanged<float> onChangeStart;
public readonly ValueChanged<float> onChangeEnd;
public readonly TickerProvider vsync;
public override RenderObject createRenderObject(BuildContext context) {
return new _RenderCupertinoSlider(
value: this.value ?? 0.0f,
divisions: this.divisions,
activeColor: this.activeColor,
onChanged: this.onChanged,
onChangeStart: this.onChangeStart,
onChangeEnd: this.onChangeEnd,
vsync: this.vsync
);
}
public override void updateRenderObject(BuildContext context, RenderObject _renderObject) {
_RenderCupertinoSlider renderObject = _renderObject as _RenderCupertinoSlider;
renderObject.value = this.value ?? 0.0f;
renderObject.divisions = this.divisions;
renderObject.activeColor = this.activeColor;
renderObject.onChanged = this.onChanged;
renderObject.onChangeStart = this.onChangeStart;
renderObject.onChangeEnd = this.onChangeEnd;
}
}
class _RenderCupertinoSlider : RenderConstrainedBox {
public _RenderCupertinoSlider(
float value,
int? divisions = null,
Color activeColor = null,
ValueChanged<float> onChanged = null,
ValueChanged<float> onChangeStart = null,
ValueChanged<float> onChangeEnd = null,
TickerProvider vsync = null
) : base(additionalConstraints: BoxConstraints.tightFor(width: SliderUtils._kSliderWidth,
height: SliderUtils._kSliderHeight)) {
D.assert(value >= 0.0f && value <= 1.0f);
this._value = value;
this._divisions = divisions;
this._activeColor = activeColor;
this._onChanged = onChanged;
this.onChangeStart = onChangeStart;
this.onChangeEnd = onChangeEnd;
this._drag = new HorizontalDragGestureRecognizer();
this._drag.onStart = this._handleDragStart;
this._drag.onUpdate = this._handleDragUpdate;
this._drag.onEnd = this._handleDragEnd;
this._position = new AnimationController(
value: value,
duration: SliderUtils._kDiscreteTransitionDuration,
vsync: vsync
);
this._position.addListener(this.markNeedsPaint);
}
public float value {
get { return this._value; }
set {
D.assert(value >= 0.0f && value <= 1.0f);
if (value == this._value) {
return;
}
this._value = value;
if (this.divisions != null) {
this._position.animateTo(value, curve: Curves.fastOutSlowIn);
}
else {
this._position.setValue(value);
}
}
}
float _value;
public int? divisions {
get { return this._divisions; }
set {
if (value == this._divisions) {
return;
}
this._divisions = value;
this.markNeedsPaint();
}
}
int? _divisions;
public Color activeColor {
get { return this._activeColor; }
set {
if (value == this._activeColor) {
return;
}
this._activeColor = value;
this.markNeedsPaint();
}
}
Color _activeColor;
public ValueChanged<float> onChanged {
get { return this._onChanged; }
set {
if (value == this._onChanged) {
return;
}
this._onChanged = value;
}
}
ValueChanged<float> _onChanged;
public ValueChanged<float> onChangeStart;
public ValueChanged<float> onChangeEnd;
AnimationController _position;
HorizontalDragGestureRecognizer _drag;
float _currentDragValue = 0.0f;
float _discretizedCurrentDragValue {
get {
float dragValue = this._currentDragValue.clamp(0.0f, 1.0f);
if (this.divisions != null) {
dragValue = Mathf.Round(dragValue * this.divisions.Value) / this.divisions.Value;
}
return dragValue;
}
}
public float _trackLeft {
get { return SliderUtils._kPadding; }
}
public float _trackRight {
get { return this.size.width - SliderUtils._kPadding; }
}
float _thumbCenter {
get {
float visualPosition = this._value;
return MathUtils.lerpFloat(this._trackLeft + CupertinoThumbPainter.radius,
this._trackRight - CupertinoThumbPainter.radius,
visualPosition);
}
}
public bool isInteractive {
get { return this.onChanged != null; }
}
void _handleDragStart(DragStartDetails details) {
this._startInteraction(details.globalPosition);
}
void _handleDragUpdate(DragUpdateDetails details) {
if (this.isInteractive) {
float extent = Mathf.Max(SliderUtils._kPadding,
this.size.width - 2.0f * (SliderUtils._kPadding + CupertinoThumbPainter.radius));
float? valueDelta = details.primaryDelta / extent;
this._currentDragValue += valueDelta ?? 0.0f;
this.onChanged(this._discretizedCurrentDragValue);
}
}
void _handleDragEnd(DragEndDetails details) {
this._endInteraction();
}
void _startInteraction(Offset globalPosition) {
if (this.isInteractive) {
if (this.onChangeStart != null) {
this.onChangeStart(this._discretizedCurrentDragValue);
}
this._currentDragValue = this._value;
this.onChanged(this._discretizedCurrentDragValue);
}
}
void _endInteraction() {
if (this.onChangeEnd != null) {
this.onChangeEnd(this._discretizedCurrentDragValue);
}
this._currentDragValue = 0.0f;
}
protected override bool hitTestSelf(Offset position) {
return (position.dx - this._thumbCenter).abs() < CupertinoThumbPainter.radius + SliderUtils._kPadding;
}
public override void handleEvent(PointerEvent e, HitTestEntry entry) {
D.assert(this.debugHandleEvent(e, entry));
if (e is PointerDownEvent pointerDownEvent && this.isInteractive) {
this._drag.addPointer(pointerDownEvent);
}
}
CupertinoThumbPainter _thumbPainter = new CupertinoThumbPainter();
public override
void paint(PaintingContext context, Offset offset) {
float visualPosition;
Color leftColor;
Color rightColor;
visualPosition = this._position.value;
leftColor = SliderUtils._kTrackColor;
rightColor = this._activeColor;
float trackCenter = offset.dy + this.size.height / 2.0f;
float trackLeft = offset.dx + this._trackLeft;
float trackTop = trackCenter - 1.0f;
float trackBottom = trackCenter + 1.0f;
float trackRight = offset.dx + this._trackRight;
float trackActive = offset.dx + this._thumbCenter;
Canvas canvas = context.canvas;
if (visualPosition > 0.0f) {
Paint paint = new Paint();
paint.color = rightColor;
canvas.drawRRect(RRect.fromLTRBXY(trackLeft, trackTop, trackActive, trackBottom, 1.0f, 1.0f), paint);
}
if (visualPosition < 1.0f) {
Paint paint = new Paint();
paint.color = leftColor;
canvas.drawRRect(RRect.fromLTRBXY(trackActive, trackTop, trackRight, trackBottom, 1.0f, 1.0f), paint);
}
Offset thumbCenter = new Offset(trackActive, trackCenter);
this._thumbPainter.paint(canvas,
Rect.fromCircle(center: thumbCenter, radius: CupertinoThumbPainter.radius));
}
}
using System;
using Unity.UIWidgets.animation;
using Unity.UIWidgets.foundation;
using Unity.UIWidgets.gestures;
using Unity.UIWidgets.rendering;
using Unity.UIWidgets.scheduler;
using Unity.UIWidgets.ui;
using Unity.UIWidgets.widgets;
using UnityEngine;
using Canvas = Unity.UIWidgets.ui.Canvas;
using Color = Unity.UIWidgets.ui.Color;
using Rect = Unity.UIWidgets.ui.Rect;
namespace Unity.UIWidgets.cupertino {
class SliderUtils {
public const float _kPadding = 8.0f;
public static readonly Color _kTrackColor = new Color(0xFFB5B5B5);
public const float _kSliderHeight = 2.0f * (CupertinoThumbPainter.radius + _kPadding);
public const float _kSliderWidth = 176.0f; // Matches Material Design slider.
public static readonly TimeSpan _kDiscreteTransitionDuration = new TimeSpan(0, 0, 0, 0, 500);
public const float _kAdjustmentUnit = 0.1f; // Matches iOS implementation of material slider.
}
public class CupertinoSlider : StatefulWidget {
public CupertinoSlider(
Key key = null,
float? value = null,
ValueChanged<float> onChanged = null,
ValueChanged<float> onChangeStart = null,
ValueChanged<float> onChangeEnd = null,
float min = 0.0f,
float max = 1.0f,
int? divisions = null,
Color activeColor = null
) : base(key: key) {
D.assert(value != null);
D.assert(onChanged != null);
D.assert(value >= min && value <= max);
D.assert(divisions == null || divisions > 0);
this.value = value.Value;
this.onChanged = onChanged;
this.onChangeStart = onChangeStart;
this.onChangeEnd = onChangeEnd;
this.min = min;
this.max = max;
this.divisions = divisions;
this.activeColor = activeColor;
}
public readonly float value;
public readonly ValueChanged<float> onChanged;
public readonly ValueChanged<float> onChangeStart;
public readonly ValueChanged<float> onChangeEnd;
public readonly float min;
public readonly float max;
public readonly int? divisions;
public readonly Color activeColor;
public override State createState() {
return new _CupertinoSliderState();
}
public override void debugFillProperties(DiagnosticPropertiesBuilder properties) {
base.debugFillProperties(properties);
properties.add(new FloatProperty("value", this.value));
properties.add(new FloatProperty("min", this.min));
properties.add(new FloatProperty("max", this.max));
}
}
class _CupertinoSliderState : TickerProviderStateMixin<CupertinoSlider> {
void _handleChanged(float value) {
D.assert(this.widget.onChanged != null);
float lerpValue = MathUtils.lerpFloat(this.widget.min, this.widget.max, value);
if (lerpValue != this.widget.value) {
this.widget.onChanged(lerpValue);
}
}
void _handleDragStart(float value) {
D.assert(this.widget.onChangeStart != null);
this.widget.onChangeStart(MathUtils.lerpFloat(this.widget.min, this.widget.max, value));
}
void _handleDragEnd(float value) {
D.assert(this.widget.onChangeEnd != null);
this.widget.onChangeEnd(MathUtils.lerpFloat(this.widget.min, this.widget.max, value));
}
public override Widget build(BuildContext context) {
return new _CupertinoSliderRenderObjectWidget(
value: (this.widget.value - this.widget.min) / (this.widget.max - this.widget.min),
divisions: this.widget.divisions,
activeColor: this.widget.activeColor ?? CupertinoTheme.of(context).primaryColor,
onChanged: this.widget.onChanged != null ? (ValueChanged<float>) this._handleChanged : null,
onChangeStart: this.widget.onChangeStart != null ? (ValueChanged<float>) this._handleDragStart : null,
onChangeEnd: this.widget.onChangeEnd != null ? (ValueChanged<float>) this._handleDragEnd : null,
vsync: this
);
}
}
class _CupertinoSliderRenderObjectWidget : LeafRenderObjectWidget {
public _CupertinoSliderRenderObjectWidget(
Key key = null,
float? value = null,
int? divisions = null,
Color activeColor = null,
ValueChanged<float> onChanged = null,
ValueChanged<float> onChangeStart = null,
ValueChanged<float> onChangeEnd = null,
TickerProvider vsync = null
) : base(key: key) {
this.value = value;
this.divisions = divisions;
this.activeColor = activeColor;
this.onChanged = onChanged;
this.onChangeStart = onChangeStart;
this.onChangeEnd = onChangeEnd;
this.vsync = vsync;
}
public readonly float? value;
public readonly int? divisions;
public readonly Color activeColor;
public readonly ValueChanged<float> onChanged;
public readonly ValueChanged<float> onChangeStart;
public readonly ValueChanged<float> onChangeEnd;
public readonly TickerProvider vsync;
public override RenderObject createRenderObject(BuildContext context) {
return new _RenderCupertinoSlider(
value: this.value ?? 0.0f,
divisions: this.divisions,
activeColor: this.activeColor,
onChanged: this.onChanged,
onChangeStart: this.onChangeStart,
onChangeEnd: this.onChangeEnd,
vsync: this.vsync
);
}
public override void updateRenderObject(BuildContext context, RenderObject _renderObject) {
_RenderCupertinoSlider renderObject = _renderObject as _RenderCupertinoSlider;
renderObject.value = this.value ?? 0.0f;
renderObject.divisions = this.divisions;
renderObject.activeColor = this.activeColor;
renderObject.onChanged = this.onChanged;
renderObject.onChangeStart = this.onChangeStart;
renderObject.onChangeEnd = this.onChangeEnd;
}
}
class _RenderCupertinoSlider : RenderConstrainedBox {
public _RenderCupertinoSlider(
float value,
int? divisions = null,
Color activeColor = null,
ValueChanged<float> onChanged = null,
ValueChanged<float> onChangeStart = null,
ValueChanged<float> onChangeEnd = null,
TickerProvider vsync = null
) : base(additionalConstraints: BoxConstraints.tightFor(width: SliderUtils._kSliderWidth,
height: SliderUtils._kSliderHeight)) {
D.assert(value >= 0.0f && value <= 1.0f);
this._value = value;
this._divisions = divisions;
this._activeColor = activeColor;
this._onChanged = onChanged;
this.onChangeStart = onChangeStart;
this.onChangeEnd = onChangeEnd;
this._drag = new HorizontalDragGestureRecognizer();
this._drag.onStart = this._handleDragStart;
this._drag.onUpdate = this._handleDragUpdate;
this._drag.onEnd = this._handleDragEnd;
this._position = new AnimationController(
value: value,
duration: SliderUtils._kDiscreteTransitionDuration,
vsync: vsync
);
this._position.addListener(this.markNeedsPaint);
}
public float value {
get { return this._value; }
set {
D.assert(value >= 0.0f && value <= 1.0f);
if (value == this._value) {
return;
}
this._value = value;
if (this.divisions != null) {
this._position.animateTo(value, curve: Curves.fastOutSlowIn);
}
else {
this._position.setValue(value);
}
}
}
float _value;
public int? divisions {
get { return this._divisions; }
set {
if (value == this._divisions) {
return;
}
this._divisions = value;
this.markNeedsPaint();
}
}
int? _divisions;
public Color activeColor {
get { return this._activeColor; }
set {
if (value == this._activeColor) {
return;
}
this._activeColor = value;
this.markNeedsPaint();
}
}
Color _activeColor;
public ValueChanged<float> onChanged {
get { return this._onChanged; }
set {
if (value == this._onChanged) {
return;
}
this._onChanged = value;
}
}
ValueChanged<float> _onChanged;
public ValueChanged<float> onChangeStart;
public ValueChanged<float> onChangeEnd;
AnimationController _position;
HorizontalDragGestureRecognizer _drag;
float _currentDragValue = 0.0f;
float _discretizedCurrentDragValue {
get {
float dragValue = this._currentDragValue.clamp(0.0f, 1.0f);
if (this.divisions != null) {
dragValue = Mathf.Round(dragValue * this.divisions.Value) / this.divisions.Value;
}
return dragValue;
}
}
public float _trackLeft {
get { return SliderUtils._kPadding; }
}
public float _trackRight {
get { return this.size.width - SliderUtils._kPadding; }
}
float _thumbCenter {
get {
float visualPosition = this._value;
return MathUtils.lerpFloat(this._trackLeft + CupertinoThumbPainter.radius,
this._trackRight - CupertinoThumbPainter.radius,
visualPosition);
}
}
public bool isInteractive {
get { return this.onChanged != null; }
}
void _handleDragStart(DragStartDetails details) {
this._startInteraction(details.globalPosition);
}
void _handleDragUpdate(DragUpdateDetails details) {
if (this.isInteractive) {
float extent = Mathf.Max(SliderUtils._kPadding,
this.size.width - 2.0f * (SliderUtils._kPadding + CupertinoThumbPainter.radius));
float? valueDelta = details.primaryDelta / extent;
this._currentDragValue += valueDelta ?? 0.0f;
this.onChanged(this._discretizedCurrentDragValue);
}
}
void _handleDragEnd(DragEndDetails details) {
this._endInteraction();
}
void _startInteraction(Offset globalPosition) {
if (this.isInteractive) {
if (this.onChangeStart != null) {
this.onChangeStart(this._discretizedCurrentDragValue);
}
this._currentDragValue = this._value;
this.onChanged(this._discretizedCurrentDragValue);
}
}
void _endInteraction() {
if (this.onChangeEnd != null) {
this.onChangeEnd(this._discretizedCurrentDragValue);
}
this._currentDragValue = 0.0f;
}
protected override bool hitTestSelf(Offset position) {
return (position.dx - this._thumbCenter).abs() < CupertinoThumbPainter.radius + SliderUtils._kPadding;
}
public override void handleEvent(PointerEvent e, HitTestEntry entry) {
D.assert(this.debugHandleEvent(e, entry));
if (e is PointerDownEvent pointerDownEvent && this.isInteractive) {
this._drag.addPointer(pointerDownEvent);
}
}
CupertinoThumbPainter _thumbPainter = new CupertinoThumbPainter();
public override
void paint(PaintingContext context, Offset offset) {
float visualPosition;
Color leftColor;
Color rightColor;
visualPosition = this._position.value;
leftColor = SliderUtils._kTrackColor;
rightColor = this._activeColor;
float trackCenter = offset.dy + this.size.height / 2.0f;
float trackLeft = offset.dx + this._trackLeft;
float trackTop = trackCenter - 1.0f;
float trackBottom = trackCenter + 1.0f;
float trackRight = offset.dx + this._trackRight;
float trackActive = offset.dx + this._thumbCenter;
Canvas canvas = context.canvas;
if (visualPosition > 0.0f) {
Paint paint = new Paint();
paint.color = rightColor;
canvas.drawRRect(RRect.fromLTRBXY(trackLeft, trackTop, trackActive, trackBottom, 1.0f, 1.0f), paint);
}
if (visualPosition < 1.0f) {
Paint paint = new Paint();
paint.color = leftColor;
canvas.drawRRect(RRect.fromLTRBXY(trackActive, trackTop, trackRight, trackBottom, 1.0f, 1.0f), paint);
}
Offset thumbCenter = new Offset(trackActive, trackCenter);
this._thumbPainter.paint(canvas,
Rect.fromCircle(center: thumbCenter, radius: CupertinoThumbPainter.radius));
}
}
}

440
com.unity.uiwidgets/Runtime/cupertino/tab_scaffold.cs


using System.Collections.Generic;
using System.Linq;
using Unity.UIWidgets.foundation;
using Unity.UIWidgets.painting;
using Unity.UIWidgets.rendering;
using Unity.UIWidgets.ui;
using Unity.UIWidgets.widgets;
namespace Unity.UIWidgets.cupertino {
public class CupertinoTabScaffold : StatefulWidget {
public CupertinoTabScaffold(
Key key = null,
CupertinoTabBar tabBar = null,
IndexedWidgetBuilder tabBuilder = null,
Color backgroundColor = null,
bool resizeToAvoidBottomInset = true
) : base(key: key) {
D.assert(tabBar != null);
D.assert(tabBuilder != null);
this.tabBar = tabBar;
this.tabBuilder = tabBuilder;
this.backgroundColor = backgroundColor;
this.resizeToAvoidBottomInset = resizeToAvoidBottomInset;
}
public readonly CupertinoTabBar tabBar;
public readonly IndexedWidgetBuilder tabBuilder;
public readonly Color backgroundColor;
public readonly bool resizeToAvoidBottomInset;
public override State createState() {
return new _CupertinoTabScaffoldState();
}
}
class _CupertinoTabScaffoldState : State<CupertinoTabScaffold> {
int _currentPage;
public override void initState() {
base.initState();
this._currentPage = this.widget.tabBar.currentIndex;
}
public override void didUpdateWidget(StatefulWidget _oldWidget) {
CupertinoTabScaffold oldWidget = _oldWidget as CupertinoTabScaffold;
base.didUpdateWidget(oldWidget);
if (this._currentPage >= this.widget.tabBar.items.Count) {
this._currentPage = this.widget.tabBar.items.Count - 1;
D.assert(this._currentPage >= 0,
() => "CupertinoTabBar is expected to keep at least 2 tabs after updating"
);
}
if (this.widget.tabBar.currentIndex != oldWidget.tabBar.currentIndex) {
this._currentPage = this.widget.tabBar.currentIndex;
}
}
public override Widget build(BuildContext context) {
List<Widget> stacked = new List<Widget> { };
MediaQueryData existingMediaQuery = MediaQuery.of(context);
MediaQueryData newMediaQuery = MediaQuery.of(context);
Widget content = new _TabSwitchingView(
currentTabIndex: this._currentPage,
tabNumber: this.widget.tabBar.items.Count,
tabBuilder: this.widget.tabBuilder
);
EdgeInsets contentPadding = EdgeInsets.zero;
if (this.widget.resizeToAvoidBottomInset) {
newMediaQuery = newMediaQuery.removeViewInsets(removeBottom: true);
contentPadding = EdgeInsets.only(bottom: existingMediaQuery.viewInsets.bottom);
}
if (this.widget.tabBar != null &&
(!this.widget.resizeToAvoidBottomInset ||
this.widget.tabBar.preferredSize.height > existingMediaQuery.viewInsets.bottom)) {
float bottomPadding = this.widget.tabBar.preferredSize.height + existingMediaQuery.padding.bottom;
if (this.widget.tabBar.opaque(context)) {
contentPadding = EdgeInsets.only(bottom: bottomPadding);
}
else {
newMediaQuery = newMediaQuery.copyWith(
padding: newMediaQuery.padding.copyWith(
bottom: bottomPadding
)
);
}
}
content = new MediaQuery(
data: newMediaQuery,
child: new Padding(
padding: contentPadding,
child: content
)
);
stacked.Add(content);
if (this.widget.tabBar != null) {
stacked.Add(new Align(
alignment: Alignment.bottomCenter,
child: this.widget.tabBar.copyWith(
currentIndex: this._currentPage,
onTap: (int newIndex) => {
this.setState(() => { this._currentPage = newIndex; });
if (this.widget.tabBar.onTap != null) {
this.widget.tabBar.onTap(newIndex);
}
}
)
));
}
return new DecoratedBox(
decoration: new BoxDecoration(
color: this.widget.backgroundColor ?? CupertinoTheme.of(context).scaffoldBackgroundColor
),
child: new Stack(
children: stacked
)
);
}
}
class _TabSwitchingView : StatefulWidget {
public _TabSwitchingView(
int currentTabIndex,
int tabNumber,
IndexedWidgetBuilder tabBuilder
) {
D.assert(tabNumber > 0);
D.assert(tabBuilder != null);
this.currentTabIndex = currentTabIndex;
this.tabNumber = tabNumber;
this.tabBuilder = tabBuilder;
}
public readonly int currentTabIndex;
public readonly int tabNumber;
public readonly IndexedWidgetBuilder tabBuilder;
public override State createState() {
return new _TabSwitchingViewState();
}
}
class _TabSwitchingViewState : State<_TabSwitchingView> {
List<Widget> tabs;
List<FocusScopeNode> tabFocusNodes;
public override void initState() {
base.initState();
this.tabs = new List<Widget>(this.widget.tabNumber);
for (int i = 0; i < this.widget.tabNumber; i++) {
this.tabs.Add(null);
}
this.tabFocusNodes = Enumerable.Repeat(new FocusScopeNode(), this.widget.tabNumber).ToList();
}
public override void didChangeDependencies() {
base.didChangeDependencies();
this._focusActiveTab();
}
public override void didUpdateWidget(StatefulWidget _oldWidget) {
_TabSwitchingView oldWidget = _oldWidget as _TabSwitchingView;
base.didUpdateWidget(oldWidget);
this._focusActiveTab();
}
void _focusActiveTab() {
FocusScope.of(this.context).setFirstFocus(this.tabFocusNodes[this.widget.currentTabIndex]);
}
public override void dispose() {
foreach (FocusScopeNode focusScopeNode in this.tabFocusNodes) {
focusScopeNode.detach();
}
base.dispose();
}
public override Widget build(BuildContext context) {
List<Widget> children = new List<Widget>();
for (int index = 0; index < this.widget.tabNumber; index++) {
bool active = index == this.widget.currentTabIndex;
var tabIndex = index;
if (active || this.tabs[index] != null) {
this.tabs[index] = this.widget.tabBuilder(context, tabIndex);
}
children.Add(new Offstage(
offstage: !active,
child: new TickerMode(
enabled: active,
child: new FocusScope(
node: this.tabFocusNodes[index],
child: this.tabs[index] ?? new Container()
)
)
));
}
return new Stack(
fit: StackFit.expand,
children: children
);
}
}
using System.Collections.Generic;
using System.Linq;
using Unity.UIWidgets.foundation;
using Unity.UIWidgets.painting;
using Unity.UIWidgets.rendering;
using Unity.UIWidgets.ui;
using Unity.UIWidgets.widgets;
namespace Unity.UIWidgets.cupertino {
public class CupertinoTabScaffold : StatefulWidget {
public CupertinoTabScaffold(
Key key = null,
CupertinoTabBar tabBar = null,
IndexedWidgetBuilder tabBuilder = null,
Color backgroundColor = null,
bool resizeToAvoidBottomInset = true
) : base(key: key) {
D.assert(tabBar != null);
D.assert(tabBuilder != null);
this.tabBar = tabBar;
this.tabBuilder = tabBuilder;
this.backgroundColor = backgroundColor;
this.resizeToAvoidBottomInset = resizeToAvoidBottomInset;
}
public readonly CupertinoTabBar tabBar;
public readonly IndexedWidgetBuilder tabBuilder;
public readonly Color backgroundColor;
public readonly bool resizeToAvoidBottomInset;
public override State createState() {
return new _CupertinoTabScaffoldState();
}
}
class _CupertinoTabScaffoldState : State<CupertinoTabScaffold> {
int _currentPage;
public override void initState() {
base.initState();
this._currentPage = this.widget.tabBar.currentIndex;
}
public override void didUpdateWidget(StatefulWidget _oldWidget) {
CupertinoTabScaffold oldWidget = _oldWidget as CupertinoTabScaffold;
base.didUpdateWidget(oldWidget);
if (this._currentPage >= this.widget.tabBar.items.Count) {
this._currentPage = this.widget.tabBar.items.Count - 1;
D.assert(this._currentPage >= 0,
() => "CupertinoTabBar is expected to keep at least 2 tabs after updating"
);
}
if (this.widget.tabBar.currentIndex != oldWidget.tabBar.currentIndex) {
this._currentPage = this.widget.tabBar.currentIndex;
}
}
public override Widget build(BuildContext context) {
List<Widget> stacked = new List<Widget> { };
MediaQueryData existingMediaQuery = MediaQuery.of(context);
MediaQueryData newMediaQuery = MediaQuery.of(context);
Widget content = new _TabSwitchingView(
currentTabIndex: this._currentPage,
tabNumber: this.widget.tabBar.items.Count,
tabBuilder: this.widget.tabBuilder
);
EdgeInsets contentPadding = EdgeInsets.zero;
if (this.widget.resizeToAvoidBottomInset) {
newMediaQuery = newMediaQuery.removeViewInsets(removeBottom: true);
contentPadding = EdgeInsets.only(bottom: existingMediaQuery.viewInsets.bottom);
}
if (this.widget.tabBar != null &&
(!this.widget.resizeToAvoidBottomInset ||
this.widget.tabBar.preferredSize.height > existingMediaQuery.viewInsets.bottom)) {
float bottomPadding = this.widget.tabBar.preferredSize.height + existingMediaQuery.padding.bottom;
if (this.widget.tabBar.opaque(context)) {
contentPadding = EdgeInsets.only(bottom: bottomPadding);
}
else {
newMediaQuery = newMediaQuery.copyWith(
padding: newMediaQuery.padding.copyWith(
bottom: bottomPadding
)
);
}
}
content = new MediaQuery(
data: newMediaQuery,
child: new Padding(
padding: contentPadding,
child: content
)
);
stacked.Add(content);
if (this.widget.tabBar != null) {
stacked.Add(new Align(
alignment: Alignment.bottomCenter,
child: this.widget.tabBar.copyWith(
currentIndex: this._currentPage,
onTap: (int newIndex) => {
this.setState(() => { this._currentPage = newIndex; });
if (this.widget.tabBar.onTap != null) {
this.widget.tabBar.onTap(newIndex);
}
}
)
));
}
return new DecoratedBox(
decoration: new BoxDecoration(
color: this.widget.backgroundColor ?? CupertinoTheme.of(context).scaffoldBackgroundColor
),
child: new Stack(
children: stacked
)
);
}
}
class _TabSwitchingView : StatefulWidget {
public _TabSwitchingView(
int currentTabIndex,
int tabNumber,
IndexedWidgetBuilder tabBuilder
) {
D.assert(tabNumber > 0);
D.assert(tabBuilder != null);
this.currentTabIndex = currentTabIndex;
this.tabNumber = tabNumber;
this.tabBuilder = tabBuilder;
}
public readonly int currentTabIndex;
public readonly int tabNumber;
public readonly IndexedWidgetBuilder tabBuilder;
public override State createState() {
return new _TabSwitchingViewState();
}
}
class _TabSwitchingViewState : State<_TabSwitchingView> {
List<Widget> tabs;
List<FocusScopeNode> tabFocusNodes;
public override void initState() {
base.initState();
this.tabs = new List<Widget>(this.widget.tabNumber);
for (int i = 0; i < this.widget.tabNumber; i++) {
this.tabs.Add(null);
}
this.tabFocusNodes = Enumerable.Repeat(new FocusScopeNode(), this.widget.tabNumber).ToList();
}
public override void didChangeDependencies() {
base.didChangeDependencies();
this._focusActiveTab();
}
public override void didUpdateWidget(StatefulWidget _oldWidget) {
_TabSwitchingView oldWidget = _oldWidget as _TabSwitchingView;
base.didUpdateWidget(oldWidget);
this._focusActiveTab();
}
void _focusActiveTab() {
FocusScope.of(this.context).setFirstFocus(this.tabFocusNodes[this.widget.currentTabIndex]);
}
public override void dispose() {
foreach (FocusScopeNode focusScopeNode in this.tabFocusNodes) {
focusScopeNode.detach();
}
base.dispose();
}
public override Widget build(BuildContext context) {
List<Widget> children = new List<Widget>();
for (int index = 0; index < this.widget.tabNumber; index++) {
bool active = index == this.widget.currentTabIndex;
var tabIndex = index;
if (active || this.tabs[index] != null) {
this.tabs[index] = this.widget.tabBuilder(context, tabIndex);
}
children.Add(new Offstage(
offstage: !active,
child: new TickerMode(
enabled: active,
child: new FocusScope(
node: this.tabFocusNodes[index],
child: this.tabs[index] ?? new Container()
)
)
));
}
return new Stack(
fit: StackFit.expand,
children: children
);
}
}
}

789
com.unity.uiwidgets/Runtime/Plugins/platform/ios/UIWidgetsTextInputPlugin.mm


#include "UIWidgetsTextInputPlugin.h"
#include "UIWidgetsMessageManager.h"
#include <Foundation/Foundation.h>
#include <UIKit/UIKit.h>
static const char _kTextAffinityDownstream[] = "TextAffinity.downstream";
static const char _kTextAffinityUpstream[] = "TextAffinity.upstream";
static UIKeyboardType ToUIKeyboardType(NSDictionary* type) {
NSString* inputType = type[@"name"];
if ([inputType isEqualToString:@"TextInputType.text"])
return UIKeyboardTypeDefault;
if ([inputType isEqualToString:@"TextInputType.multiline"])
return UIKeyboardTypeDefault;
if ([inputType isEqualToString:@"TextInputType.number"]) {
if ([type[@"signed"] boolValue])
return UIKeyboardTypeNumbersAndPunctuation;
return UIKeyboardTypeDecimalPad;
}
if ([inputType isEqualToString:@"TextInputType.phone"])
return UIKeyboardTypePhonePad;
if ([inputType isEqualToString:@"TextInputType.emailAddress"])
return UIKeyboardTypeEmailAddress;
if ([inputType isEqualToString:@"TextInputType.url"])
return UIKeyboardTypeURL;
return UIKeyboardTypeDefault;
}
static UITextAutocapitalizationType ToUITextAutoCapitalizationType(NSDictionary* type) {
NSString* textCapitalization = type[@"textCapitalization"];
if ([textCapitalization isEqualToString:@"TextCapitalization.characters"]) {
return UITextAutocapitalizationTypeAllCharacters;
} else if ([textCapitalization isEqualToString:@"TextCapitalization.sentences"]) {
return UITextAutocapitalizationTypeSentences;
} else if ([textCapitalization isEqualToString:@"TextCapitalization.words"]) {
return UITextAutocapitalizationTypeWords;
}
return UITextAutocapitalizationTypeNone;
}
static UIReturnKeyType ToUIReturnKeyType(NSString* inputType) {
// Where did the term "unspecified" come from? iOS has a "default" and Android
// has "unspecified." These 2 terms seem to mean the same thing but we need
// to pick just one. "unspecified" was chosen because "default" is often a
// reserved word in languages with switch statements (dart, java, etc).
if ([inputType isEqualToString:@"TextInputAction.unspecified"])
return UIReturnKeyDefault;
if ([inputType isEqualToString:@"TextInputAction.done"])
return UIReturnKeyDone;
if ([inputType isEqualToString:@"TextInputAction.go"])
return UIReturnKeyGo;
if ([inputType isEqualToString:@"TextInputAction.send"])
return UIReturnKeySend;
if ([inputType isEqualToString:@"TextInputAction.search"])
return UIReturnKeySearch;
if ([inputType isEqualToString:@"TextInputAction.next"])
return UIReturnKeyNext;
if (@available(iOS 9.0, *))
if ([inputType isEqualToString:@"TextInputAction.continueAction"])
return UIReturnKeyContinue;
if ([inputType isEqualToString:@"TextInputAction.join"])
return UIReturnKeyJoin;
if ([inputType isEqualToString:@"TextInputAction.route"])
return UIReturnKeyRoute;
if ([inputType isEqualToString:@"TextInputAction.emergencyCall"])
return UIReturnKeyEmergencyCall;
if ([inputType isEqualToString:@"TextInputAction.newline"])
return UIReturnKeyDefault;
// Present default key if bad input type is given.
return UIReturnKeyDefault;
}
#pragma mark - UIWidgetsTextPosition
@implementation UIWidgetsTextPosition
+ (instancetype)positionWithIndex:(NSUInteger)index {
return [[[UIWidgetsTextPosition alloc] initWithIndex:index] autorelease];
}
- (instancetype)initWithIndex:(NSUInteger)index {
self = [super init];
if (self) {
_index = index;
}
return self;
}
@end
#pragma mark - UIWidgetsTextRange
@implementation UIWidgetsTextRange
+ (instancetype)rangeWithNSRange:(NSRange)range {
return [[[UIWidgetsTextRange alloc] initWithNSRange:range] autorelease];
}
- (instancetype)initWithNSRange:(NSRange)range {
self = [super init];
if (self) {
_range = range;
}
return self;
}
- (UITextPosition*)start {
return [UIWidgetsTextPosition positionWithIndex:self.range.location];
}
- (UITextPosition*)end {
return [UIWidgetsTextPosition positionWithIndex:self.range.location + self.range.length];
}
- (BOOL)isEmpty {
return self.range.length == 0;
}
- (id)copyWithZone:(NSZone*)zone {
return [[UIWidgetsTextRange allocWithZone:zone] initWithNSRange:self.range];
}
@end
@interface UIWidgetsTextInputView : UIView <UITextInput>
// UITextInput
@property(nonatomic, readonly) NSMutableString* text;
@property(nonatomic, readonly) NSMutableString* markedText;
@property(readwrite, copy) UITextRange* selectedTextRange;
@property(nonatomic, strong) UITextRange* markedTextRange;
@property(nonatomic, copy) NSDictionary* markedTextStyle;
@property(nonatomic, assign) id<UITextInputDelegate> inputDelegate;
// UITextInputTraits
@property(nonatomic) UITextAutocapitalizationType autocapitalizationType;
@property(nonatomic) UITextAutocorrectionType autocorrectionType;
@property(nonatomic) UITextSpellCheckingType spellCheckingType;
@property(nonatomic) BOOL enablesReturnKeyAutomatically;
@property(nonatomic) UIKeyboardAppearance keyboardAppearance;
@property(nonatomic) UIKeyboardType keyboardType;
@property(nonatomic) UIReturnKeyType returnKeyType;
@property(nonatomic, getter=isSecureTextEntry) BOOL secureTextEntry;
@property(nonatomic, assign) id<UIWidgetsTextInputDelegate> textInputDelegate;
@end
@implementation UIWidgetsTextInputView {
int _textInputClient;
const char* _selectionAffinity;
UIWidgetsTextRange* _selectedTextRange;
}
@synthesize tokenizer = _tokenizer;
- (instancetype)init {
self = [super init];
if (self) {
_textInputClient = 0;
_selectionAffinity = _kTextAffinityUpstream;
// UITextInput
_text = [[NSMutableString alloc] init];
_markedText = [[NSMutableString alloc] init];
_selectedTextRange = [[UIWidgetsTextRange alloc] initWithNSRange:NSMakeRange(0, 0)];
// UITextInputTraits
_autocapitalizationType = UITextAutocapitalizationTypeSentences;
_autocorrectionType = UITextAutocorrectionTypeDefault;
_spellCheckingType = UITextSpellCheckingTypeDefault;
_enablesReturnKeyAutomatically = NO;
_keyboardAppearance = UIKeyboardAppearanceDefault;
_keyboardType = UIKeyboardTypeDefault;
_returnKeyType = UIReturnKeyDone;
_secureTextEntry = NO;
}
return self;
}
- (void)dealloc {
[_text release];
[_markedText release];
[_markedTextRange release];
[_selectedTextRange release];
[_tokenizer release];
[super dealloc];
}
- (void)setTextInputClient:(int)client {
_textInputClient = client;
}
- (void)setTextInputState:(NSDictionary*)state {
NSString* newText = state[@"text"];
BOOL textChanged = ![self.text isEqualToString:newText];
if (textChanged) {
[self.inputDelegate textWillChange:self];
[self.text setString:newText];
}
NSInteger composingBase = [state[@"composingBase"] intValue];
NSInteger composingExtent = [state[@"composingExtent"] intValue];
NSRange composingRange = [self clampSelection:NSMakeRange(MIN(composingBase, composingExtent), ABS(composingBase - composingExtent)) forText:self.text];
self.markedTextRange = composingRange.length > 0 ? [UIWidgetsTextRange rangeWithNSRange:composingRange] : nil;
NSInteger selectionBase = [state[@"selectionBase"] intValue];
NSInteger selectionExtent = [state[@"selectionExtent"] intValue];
NSRange selectedRange = [self clampSelection:NSMakeRange(MIN(selectionBase, selectionExtent),
ABS(selectionBase - selectionExtent))
forText:self.text];
NSRange oldSelectedRange = [(UIWidgetsTextRange*)self.selectedTextRange range];
if (selectedRange.location != oldSelectedRange.location ||
selectedRange.length != oldSelectedRange.length) {
[self.inputDelegate selectionWillChange:self];
[self setSelectedTextRange:[UIWidgetsTextRange rangeWithNSRange:selectedRange]
updateEditingState:NO];
_selectionAffinity = _kTextAffinityDownstream;
if ([state[@"selectionAffinity"] isEqualToString:@(_kTextAffinityUpstream)])
_selectionAffinity = _kTextAffinityUpstream;
[self.inputDelegate selectionDidChange:self];
}
if (textChanged) {
[self.inputDelegate textDidChange:self];
// For consistency with Android behavior, send an update to the framework.
[self updateEditingState];
}
}
- (NSRange)clampSelection:(NSRange)range forText:(NSString*)text {
int start = MIN(MAX(range.location, 0), text.length);
int length = MIN(range.length, text.length - start);
return NSMakeRange(start, length);
}
#pragma mark - UIResponder Overrides
- (BOOL)canBecomeFirstResponder {
return YES;
}
#pragma mark - UITextInput Overrides
- (id<UITextInputTokenizer>)tokenizer {
if (_tokenizer == nil) {
_tokenizer = [[UITextInputStringTokenizer alloc] initWithTextInput:self];
}
return _tokenizer;
}
- (UITextRange*)selectedTextRange {
return [[_selectedTextRange copy] autorelease];
}
- (void)setSelectedTextRange:(UITextRange*)selectedTextRange {
[self setSelectedTextRange:selectedTextRange updateEditingState:YES];
}
- (void)setSelectedTextRange:(UITextRange*)selectedTextRange updateEditingState:(BOOL)update {
if (_selectedTextRange != selectedTextRange) {
UITextRange* oldSelectedRange = _selectedTextRange;
_selectedTextRange = [selectedTextRange copy];
[oldSelectedRange release];
if (update)
[self updateEditingState];
}
}
- (id)insertDictationResultPlaceholder {
return @"";
}
- (void)removeDictationResultPlaceholder:(id)placeholder willInsertResult:(BOOL)willInsertResult {
}
- (NSString*)textInRange:(UITextRange*)range {
NSRange textRange = ((UIWidgetsTextRange*)range).range;
return [self.text substringWithRange:textRange];
}
- (void)replaceRange:(UITextRange*)range withText:(NSString*)text {
NSRange replaceRange = ((UIWidgetsTextRange*)range).range;
NSRange selectedRange = _selectedTextRange.range;
// Adjust the text selection:
// * reduce the length by the intersection length
// * adjust the location by newLength - oldLength + intersectionLength
NSRange intersectionRange = NSIntersectionRange(replaceRange, selectedRange);
if (replaceRange.location <= selectedRange.location)
selectedRange.location += text.length - replaceRange.length;
if (intersectionRange.location != NSNotFound) {
selectedRange.location += intersectionRange.length;
selectedRange.length -= intersectionRange.length;
}
[self.text replaceCharactersInRange:[self clampSelection:replaceRange forText:self.text]
withString:text];
[self setSelectedTextRange:[UIWidgetsTextRange rangeWithNSRange:[self clampSelection:selectedRange
forText:self.text]]
updateEditingState:NO];
[self updateEditingState];
}
- (BOOL)shouldChangeTextInRange:(UITextRange*)range replacementText:(NSString*)text {
if (self.returnKeyType == UIReturnKeyDefault && [text isEqualToString:@"\n"]) {
[_textInputDelegate performAction:UIWidgetsTextInputActionNewline withClient:_textInputClient];
return YES;
}
if ([text isEqualToString:@"\n"]) {
UIWidgetsTextInputAction action;
switch (self.returnKeyType) {
case UIReturnKeyDefault:
action = UIWidgetsTextInputActionUnspecified;
break;
case UIReturnKeyDone:
action = UIWidgetsTextInputActionDone;
break;
case UIReturnKeyGo:
action = UIWidgetsTextInputActionGo;
break;
case UIReturnKeySend:
action = UIWidgetsTextInputActionSend;
break;
case UIReturnKeySearch:
case UIReturnKeyGoogle:
case UIReturnKeyYahoo:
action = UIWidgetsTextInputActionSearch;
break;
case UIReturnKeyNext:
action = UIWidgetsTextInputActionNext;
break;
case UIReturnKeyContinue:
action = UIWidgetsTextInputActionContinue;
break;
case UIReturnKeyJoin:
action = UIWidgetsTextInputActionJoin;
break;
case UIReturnKeyRoute:
action = UIWidgetsTextInputActionRoute;
break;
case UIReturnKeyEmergencyCall:
action = UIWidgetsTextInputActionEmergencyCall;
break;
}
[_textInputDelegate performAction:action withClient:_textInputClient];
return NO;
}
return YES;
}
- (void)setMarkedText:(NSString*)markedText selectedRange:(NSRange)markedSelectedRange {
NSRange selectedRange = _selectedTextRange.range;
NSRange markedTextRange = ((UIWidgetsTextRange*)self.markedTextRange).range;
if (markedText == nil)
markedText = @"";
if (markedTextRange.length > 0) {
// Replace text in the marked range with the new text.
[self replaceRange:self.markedTextRange withText:markedText];
markedTextRange.length = markedText.length;
} else {
// Replace text in the selected range with the new text.
[self replaceRange:_selectedTextRange withText:markedText];
markedTextRange = NSMakeRange(selectedRange.location, markedText.length);
}
self.markedTextRange =
markedTextRange.length > 0 ? [UIWidgetsTextRange rangeWithNSRange:markedTextRange] : nil;
NSUInteger selectionLocation = markedSelectedRange.location + markedTextRange.location;
selectedRange = NSMakeRange(selectionLocation, markedSelectedRange.length);
[self setSelectedTextRange:[UIWidgetsTextRange rangeWithNSRange:[self clampSelection:selectedRange
forText:self.text]]
updateEditingState:YES];
}
- (void)unmarkText {
self.markedTextRange = nil;
[self updateEditingState];
}
- (UITextRange*)textRangeFromPosition:(UITextPosition*)fromPosition
toPosition:(UITextPosition*)toPosition {
NSUInteger fromIndex = ((UIWidgetsTextPosition*)fromPosition).index;
NSUInteger toIndex = ((UIWidgetsTextPosition*)toPosition).index;
return [UIWidgetsTextRange rangeWithNSRange:NSMakeRange(fromIndex, toIndex - fromIndex)];
}
/** Returns the range of the character sequence at the specified index in the
* text. */
- (NSRange)rangeForCharacterAtIndex:(NSUInteger)index {
if (index < self.text.length)
return [self.text rangeOfComposedCharacterSequenceAtIndex:index];
return NSMakeRange(index, 0);
}
- (NSUInteger)decrementOffsetPosition:(NSUInteger)position {
return [self rangeForCharacterAtIndex:MAX(0, position - 1)].location;
}
- (NSUInteger)incrementOffsetPosition:(NSUInteger)position {
NSRange charRange = [self rangeForCharacterAtIndex:position];
return MIN(position + charRange.length, self.text.length);
}
- (UITextPosition*)positionFromPosition:(UITextPosition*)position offset:(NSInteger)offset {
NSUInteger offsetPosition = ((UIWidgetsTextPosition*)position).index;
NSInteger newLocation = (NSInteger)offsetPosition + offset;
if (newLocation < 0 || newLocation > (NSInteger)self.text.length) {
return nil;
}
if (offset >= 0) {
for (NSInteger i = 0; i < offset && offsetPosition < self.text.length; ++i)
offsetPosition = [self incrementOffsetPosition:offsetPosition];
} else {
for (NSInteger i = 0; i < ABS(offset) && offsetPosition > 0; ++i)
offsetPosition = [self decrementOffsetPosition:offsetPosition];
}
return [UIWidgetsTextPosition positionWithIndex:offsetPosition];
}
- (UITextPosition*)positionFromPosition:(UITextPosition*)position
inDirection:(UITextLayoutDirection)direction
offset:(NSInteger)offset {
// TODO(cbracken) Add RTL handling.
switch (direction) {
case UITextLayoutDirectionLeft:
case UITextLayoutDirectionUp:
return [self positionFromPosition:position offset:offset * -1];
case UITextLayoutDirectionRight:
case UITextLayoutDirectionDown:
return [self positionFromPosition:position offset:1];
}
}
- (UITextPosition*)beginningOfDocument {
return [UIWidgetsTextPosition positionWithIndex:0];
}
- (UITextPosition*)endOfDocument {
return [UIWidgetsTextPosition positionWithIndex:self.text.length];
}
- (NSComparisonResult)comparePosition:(UITextPosition*)position toPosition:(UITextPosition*)other {
NSUInteger positionIndex = ((UIWidgetsTextPosition*)position).index;
NSUInteger otherIndex = ((UIWidgetsTextPosition*)other).index;
if (positionIndex < otherIndex)
return NSOrderedAscending;
if (positionIndex > otherIndex)
return NSOrderedDescending;
return NSOrderedSame;
}
- (NSInteger)offsetFromPosition:(UITextPosition*)from toPosition:(UITextPosition*)toPosition {
return ((UIWidgetsTextPosition*)toPosition).index - ((UIWidgetsTextPosition*)from).index;
}
- (UITextPosition*)positionWithinRange:(UITextRange*)range
farthestInDirection:(UITextLayoutDirection)direction {
NSUInteger index;
switch (direction) {
case UITextLayoutDirectionLeft:
case UITextLayoutDirectionUp:
index = ((UIWidgetsTextPosition*)range.start).index;
break;
case UITextLayoutDirectionRight:
case UITextLayoutDirectionDown:
index = ((UIWidgetsTextPosition*)range.end).index;
break;
}
return [UIWidgetsTextPosition positionWithIndex:index];
}
- (UITextRange*)characterRangeByExtendingPosition:(UITextPosition*)position
inDirection:(UITextLayoutDirection)direction {
NSUInteger positionIndex = ((UIWidgetsTextPosition*)position).index;
NSUInteger startIndex;
NSUInteger endIndex;
switch (direction) {
case UITextLayoutDirectionLeft:
case UITextLayoutDirectionUp:
startIndex = [self decrementOffsetPosition:positionIndex];
endIndex = positionIndex;
break;
case UITextLayoutDirectionRight:
case UITextLayoutDirectionDown:
startIndex = positionIndex;
endIndex = [self incrementOffsetPosition:positionIndex];
break;
}
return [UIWidgetsTextRange rangeWithNSRange:NSMakeRange(startIndex, endIndex - startIndex)];
}
#pragma mark - UITextInput text direction handling
- (UITextWritingDirection)baseWritingDirectionForPosition:(UITextPosition*)position
inDirection:(UITextStorageDirection)direction {
return UITextWritingDirectionNatural;
}
- (void)setBaseWritingDirection:(UITextWritingDirection)writingDirection
forRange:(UITextRange*)range {
}
#pragma mark - UITextInput cursor, selection rect handling
- (CGRect)firstRectForRange:(UITextRange*)range {
return CGRectZero;
}
- (CGRect)caretRectForPosition:(UITextPosition*)position {
return CGRectZero;
}
- (UITextPosition*)closestPositionToPoint:(CGPoint)point {
NSUInteger currentIndex = ((UIWidgetsTextPosition*)_selectedTextRange.start).index;
return [UIWidgetsTextPosition positionWithIndex:currentIndex];
}
- (NSArray*)selectionRectsForRange:(UITextRange*)range {
return @[];
}
- (UITextPosition*)closestPositionToPoint:(CGPoint)point withinRange:(UITextRange*)range {
return range.start;
}
- (UITextRange*)characterRangeAtPoint:(CGPoint)point {
NSUInteger currentIndex = ((UIWidgetsTextPosition*)_selectedTextRange.start).index;
return [UIWidgetsTextRange rangeWithNSRange:[self rangeForCharacterAtIndex:currentIndex]];
}
#pragma mark - UIKeyInput Overrides
- (void)updateEditingState {
NSUInteger selectionBase = ((UIWidgetsTextPosition*)_selectedTextRange.start).index;
NSUInteger selectionExtent = ((UIWidgetsTextPosition*)_selectedTextRange.end).index;
NSUInteger composingBase = 0;
NSUInteger composingExtent = 0;
if (self.markedTextRange != nil) {
composingBase = ((UIWidgetsTextPosition*)self.markedTextRange.start).index;
composingExtent = ((UIWidgetsTextPosition*)self.markedTextRange.end).index;
}
[_textInputDelegate updateEditingClient:_textInputClient
withState:@{
@"selectionBase" : @(selectionBase),
@"selectionExtent" : @(selectionExtent),
@"selectionAffinity" : @(_selectionAffinity),
@"selectionIsDirectional" : @(false),
@"composingBase" : @(composingBase),
@"composingExtent" : @(composingExtent),
@"text" : [NSString stringWithString:self.text],
}];
}
- (BOOL)hasText {
return self.text.length > 0;
}
- (void)insertText:(NSString*)text {
_selectionAffinity = _kTextAffinityDownstream;
[self replaceRange:_selectedTextRange withText:text];
}
- (void)deleteBackward {
_selectionAffinity = _kTextAffinityDownstream;
if (!_selectedTextRange.isEmpty)
[self replaceRange:_selectedTextRange withText:@""];
}
@end
/**
* Hides `UIWidgetsTextInputView` from iOS accessibility system so it
* does not show up twice, once where it is in the `UIView` hierarchy,
* and a second time as part of the `SemanticsObject` hierarchy.
*/
@interface UIWidgetsTextInputViewAccessibilityHider : UIView {
}
@end
@implementation UIWidgetsTextInputViewAccessibilityHider {
}
- (BOOL)accessibilityElementsHidden {
return YES;
}
@end
@implementation UIWidgetsTextInputPlugin {
UIWidgetsTextInputView* _view;
UIWidgetsTextInputViewAccessibilityHider* _inputHider;
}
@synthesize textInputDelegate = _textInputDelegate;
- (instancetype)init {
self = [super init];
if (self) {
_view = [[UIWidgetsTextInputView alloc] init];
_inputHider = [[UIWidgetsTextInputViewAccessibilityHider alloc] init];
}
return self;
}
- (void)dealloc {
[self hideTextInput];
[_view release];
[_inputHider release];
[super dealloc];
}
- (UIView<UITextInput>*)textInputView {
return _view;
}
- (void)showTextInput {
NSAssert([UIApplication sharedApplication].keyWindow != nullptr,
@"The application must have a key window since the keyboard client "
@"must be part of the responder chain to function");
_view.textInputDelegate = _textInputDelegate;
[_inputHider addSubview:_view];
[[UIApplication sharedApplication].keyWindow addSubview:_inputHider];
[_view becomeFirstResponder];
}
- (void)hideTextInput {
[_view resignFirstResponder];
[_view removeFromSuperview];
[_inputHider removeFromSuperview];
}
- (void)setTextInputClient:(int)client withConfiguration:(NSDictionary*)configuration {
NSDictionary* inputType = configuration[@"inputType"];
NSString* keyboardAppearance = configuration[@"keyboardAppearance"];
_view.keyboardType = ToUIKeyboardType(inputType);
_view.returnKeyType = ToUIReturnKeyType(configuration[@"inputAction"]);
_view.autocapitalizationType = ToUITextAutoCapitalizationType(configuration);
if ([keyboardAppearance isEqualToString:@"Brightness.dark"]) {
_view.keyboardAppearance = UIKeyboardAppearanceDark;
} else if ([keyboardAppearance isEqualToString:@"Brightness.light"]) {
_view.keyboardAppearance = UIKeyboardAppearanceLight;
} else {
_view.keyboardAppearance = UIKeyboardAppearanceDefault;
}
_view.secureTextEntry = [configuration[@"obscureText"] boolValue];
NSString* autocorrect = configuration[@"autocorrect"];
_view.autocorrectionType = autocorrect && ![autocorrect boolValue]
? UITextAutocorrectionTypeNo
: UITextAutocorrectionTypeDefault;
[_view setTextInputClient:client];
[_view reloadInputViews];
}
- (void)setTextInputEditingState:(NSDictionary*)state {
[_view setTextInputState:state];
}
- (void)clearTextInputClient {
[_view setTextInputClient:0];
}
+ (instancetype)sharedInstance {
static UIWidgetsTextInputPlugin *sharedInstance = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
sharedInstance = [[UIWidgetsTextInputPlugin alloc] init];
sharedInstance.textInputDelegate = [[DefaultUIWidgetsTextInputDelegate alloc] init];
});
return sharedInstance;
}
@end
@implementation DefaultUIWidgetsTextInputDelegate
- (void)updateEditingClient:(int)client withState:(NSDictionary*)state {
UIWidgetsMethodMessage(@"TextInput", @"TextInputClient.updateEditingState", @[@(client), state]);
}
- (void)performAction:(UIWidgetsTextInputAction)action withClient:(int)client {
NSString* actionString;
switch (action) {
case UIWidgetsTextInputActionUnspecified:
// Where did the term "unspecified" come from? iOS has a "default" and Android
// has "unspecified." These 2 terms seem to mean the same thing but we need
// to pick just one. "unspecified" was chosen because "default" is often a
// reserved word in languages with switch statements (dart, java, etc).
actionString = @"TextInputAction.unspecified";
break;
case UIWidgetsTextInputActionDone:
actionString = @"TextInputAction.done";
break;
case UIWidgetsTextInputActionGo:
actionString = @"TextInputAction.go";
break;
case UIWidgetsTextInputActionSend:
actionString = @"TextInputAction.send";
break;
case UIWidgetsTextInputActionSearch:
actionString = @"TextInputAction.search";
break;
case UIWidgetsTextInputActionNext:
actionString = @"TextInputAction.next";
break;
case UIWidgetsTextInputActionContinue:
actionString = @"TextInputAction.continue";
break;
case UIWidgetsTextInputActionJoin:
actionString = @"TextInputAction.join";
break;
case UIWidgetsTextInputActionRoute:
actionString = @"TextInputAction.route";
break;
case UIWidgetsTextInputActionEmergencyCall:
actionString = @"TextInputAction.emergencyCall";
break;
case UIWidgetsTextInputActionNewline:
actionString = @"TextInputAction.newline";
break;
}
UIWidgetsMethodMessage(@"TextInput", @"TextInputClient.performAction", @[@(client), actionString]);
}
@end
extern "C" {
void UIWidgetsTextInputShow() {
[[UIWidgetsTextInputPlugin sharedInstance] showTextInput];
}
void UIWidgetsTextInputHide() {
[[UIWidgetsTextInputPlugin sharedInstance] hideTextInput];
}
void UIWidgetsTextInputSetClient(int client, const char* configurationJson) {
NSError *jsonError = nil;
NSString *nsJsonString=[NSString stringWithUTF8String:configurationJson];
NSData *objectData = [nsJsonString dataUsingEncoding:NSUTF8StringEncoding];
NSDictionary *json = [NSJSONSerialization JSONObjectWithData:objectData
options:NSJSONReadingMutableContainers
error:&jsonError];
[[UIWidgetsTextInputPlugin sharedInstance] setTextInputClient:client withConfiguration:json];
}
void UIWidgetsTextInputSetTextInputEditingState(const char* jsonText) {
NSError *jsonError;
NSString *nsJsonString=[NSString stringWithUTF8String:jsonText];
NSData *objectData = [nsJsonString dataUsingEncoding:NSUTF8StringEncoding];
NSDictionary *args = [NSJSONSerialization JSONObjectWithData:objectData
options:NSJSONReadingMutableContainers
error:&jsonError];
[[UIWidgetsTextInputPlugin sharedInstance] setTextInputEditingState:args];
}
void UIWidgetsTextInputClearTextInputClient() {
[[UIWidgetsTextInputPlugin sharedInstance] clearTextInputClient];
}
}

/.npmignore → /com.unity.uiwidgets/.npmignore

/CHANGELOG.md → /com.unity.uiwidgets/CHANGELOG.md

/CHANGELOG.md.meta → /com.unity.uiwidgets/CHANGELOG.md.meta

/Documentation~ → /com.unity.uiwidgets/Documentation~

/Editor.meta → /com.unity.uiwidgets/Editor.meta

/Editor → /com.unity.uiwidgets/Editor

/LICENSE.md → /com.unity.uiwidgets/LICENSE.md

/LICENSE.md.meta → /com.unity.uiwidgets/LICENSE.md.meta

/QAReport.md → /com.unity.uiwidgets/QAReport.md

/QAReport.md.meta → /com.unity.uiwidgets/QAReport.md.meta

/Runtime.meta → /com.unity.uiwidgets/Runtime.meta

/Third Party Notices.md → /com.unity.uiwidgets/Third Party Notices.md

/Third Party Notices.md.meta → /com.unity.uiwidgets/Third Party Notices.md.meta

/package.json → /com.unity.uiwidgets/package.json

/package.json.meta → /com.unity.uiwidgets/package.json.meta

/scripts.meta → /com.unity.uiwidgets/scripts.meta

/.editorconfig → /com.unity.uiwidgets/.editorconfig

/UIWidgetCleanupPlugin.DotSettings.meta → /com.unity.uiwidgets/UIWidgetCleanupPlugin.DotSettings.meta

/UIWidgetCleanupPlugin.DotSettings → /com.unity.uiwidgets/UIWidgetCleanupPlugin.DotSettings

/Scripts → /com.unity.uiwidgets/Scripts

/Runtime → /com.unity.uiwidgets/Runtime

正在加载...
取消
保存