浏览代码

Merge branch 'yczhang' into match_flutter12

/main
Yuncong Zhang 5 年前
当前提交
8b890902
共有 49 个文件被更改,包括 3612 次插入121 次删除
  1. 6
      Runtime/Plugins/platform/ios/UIWidgetsViewController.mm
  2. 17
      Runtime/animation/animation_controller.cs
  3. 54
      Runtime/animation/curves.cs
  4. 10
      Runtime/animation/listener_helpers.mixin.gen.cs
  5. 4
      Runtime/animation/listener_helpers.mixin.njk
  6. 13
      Runtime/animation/tween.cs
  7. 8
      Runtime/engine/UIWidgetsPanel.cs
  8. 32
      Runtime/foundation/debug.cs
  9. 40
      Runtime/gestures/binding.cs
  10. 6
      Runtime/gestures/converter.cs
  11. 7
      Runtime/gestures/monodrag.cs
  12. 38
      Runtime/gestures/recognizer.cs
  13. 26
      Runtime/material/list_tile.cs
  14. 18
      Runtime/material/theme_data.cs
  15. 1
      Runtime/painting/basic_types.cs
  16. 23
      Runtime/painting/text_span.cs
  17. 12
      Runtime/rendering/image.cs
  18. 59
      Runtime/rendering/paragraph.cs
  19. 18
      Runtime/widgets/binding.cs
  20. 2
      Samples/UIWidgetSample/txt/TextSpanGesture.cs
  21. 92
      Samples/UIWidgetsGallery/gallery/demos.cs
  22. 26
      Runtime/gestures/hover.cs
  23. 11
      Runtime/gestures/hover.cs.meta
  24. 1001
      Runtime/material/chip.cs
  25. 3
      Runtime/material/chip.cs.meta
  26. 298
      Runtime/material/chip_theme.cs
  27. 3
      Runtime/material/chip_theme.cs.meta
  28. 132
      Runtime/material/circle_avatar.cs
  29. 3
      Runtime/material/circle_avatar.cs.meta
  30. 82
      Samples/UIWidgetSample/HoverRecognizerSample.cs
  31. 11
      Samples/UIWidgetSample/HoverRecognizerSample.cs.meta
  32. 3
      Samples/UIWidgetsGallery/demo/animation.meta
  33. 15
      Samples/UIWidgetsGallery/demo/animation_demo.cs
  34. 3
      Samples/UIWidgetsGallery/demo/animation_demo.cs.meta
  35. 322
      Samples/UIWidgetsGallery/demo/material/chip_demo.cs
  36. 3
      Samples/UIWidgetsGallery/demo/material/chip_demo.cs.meta
  37. 42
      Samples/UIWidgetsGallery/demo/material/modal_bottom_sheet_demo.cs
  38. 3
      Samples/UIWidgetsGallery/demo/material/modal_bottom_sheet_demo.cs.meta
  39. 102
      Samples/UIWidgetsGallery/demo/material/persistent_bottom_sheet_demo.cs
  40. 3
      Samples/UIWidgetsGallery/demo/material/persistent_bottom_sheet_demo.cs.meta
  41. 184
      Samples/UIWidgetsGallery/demo/material/tabs_fab_demo.cs
  42. 3
      Samples/UIWidgetsGallery/demo/material/tabs_fab_demo.cs.meta
  43. 3
      Samples/UIWidgetsGallery/demo/animation/home.cs.meta
  44. 615
      Samples/UIWidgetsGallery/demo/animation/home.cs
  45. 201
      Samples/UIWidgetsGallery/demo/animation/sections.cs
  46. 3
      Samples/UIWidgetsGallery/demo/animation/sections.cs.meta
  47. 169
      Samples/UIWidgetsGallery/demo/animation/widgets.cs
  48. 3
      Samples/UIWidgetsGallery/demo/animation/widgets.cs.meta

6
Runtime/Plugins/platform/ios/UIWidgetsViewController.mm


CGFloat bottom = CGRectGetHeight([[info objectForKey:UIKeyboardFrameEndUserInfoKey] CGRectValue]);
CGFloat scale = [UIScreen mainScreen].scale;
// scale == 3 => screen is 1242 * 2208 => we have to perform down-sampling to obtain the real length
// 0.8696 = 1920 / 2208, the vertical down-sampling ratio
if (scale == 3) {
bottom = bottom * 0.8696;
}
viewInsets.bottom = bottom * scale;
padding.bottom = 0;

17
Runtime/animation/animation_controller.cs


this._direction = _AnimationDirection.forward;
return this._animateToInternal(target, duration: duration, curve: curve);
}
TickerFuture animateBack(float target, TimeSpan? duration, Curve curve = null) {
public TickerFuture animateBack(float target, TimeSpan? duration, Curve curve = null) {
D.assert(
this._ticker != null,
"AnimationController.animateBack() called after AnimationController.dispose()\n" +

new _InterpolationSimulation(this._value, target, simulationDuration.Value, curve));
}
public TickerFuture repeat(float? min = null, float? max = null, bool reverse = false, TimeSpan? period = null) {
public TickerFuture repeat(float? min = null, float? max = null, bool reverse = false,
TimeSpan? period = null) {
min = min ?? this.lowerBound;
max = max ?? this.upperBound;
period = period ?? this.duration;

return true;
});
D.assert(max >= min);
D.assert(max <= this.upperBound && min >= this.lowerBound);
return this.animateWith(new _RepeatingSimulation(this._value, min.Value, max.Value, reverse, period.Value));

this._min = min;
this._max = max;
this._periodInSeconds = (float) period.Ticks / TimeSpan.TicksPerSecond;
this._initialT = (max == min) ? 0.0f : (initialValue / (max - min)) * (period.Ticks / TimeSpan.TicksPerSecond);
this._initialT =
(max == min) ? 0.0f : (initialValue / (max - min)) * (period.Ticks / TimeSpan.TicksPerSecond);
this._reverse = reverse;
D.assert(this._periodInSeconds > 0.0f);
D.assert(this._initialT >= 0.0f);

D.assert(timeInSeconds >= 0.0f);
float totalTimeInSeconds = timeInSeconds + this._initialT;
float t = (totalTimeInSeconds / this._periodInSeconds) % 1.0f;
bool _isPlayingReverse = ((int)(totalTimeInSeconds / this._periodInSeconds)) % 2 == 1;
bool _isPlayingReverse = ((int) (totalTimeInSeconds / this._periodInSeconds)) % 2 == 1;
} else {
}
else {
return MathUtils.lerpFloat(this._min, this._max, t);
}
}

54
Runtime/animation/curves.cs


public static readonly Curve linear = new _Linear();
public static readonly Curve decelerate = new _DecelerateCurve();
public static readonly Cubic easeInOutBack = new Cubic(0.68f, -0.55f, 0.265f, 1.55f);
public static readonly Curve fastOutSlowIn = new Cubic(0.4f, 0.0f, 0.2f, 1.0f);

10
Runtime/animation/listener_helpers.mixin.gen.cs


public override void removeListener(VoidCallback listener) {
bool removed = this._listeners.Remove(listener);
if(removed) {
if (removed) {
this.didUnregisterListener();
}
}

public override void removeListener(VoidCallback listener) {
bool removed = this._listeners.Remove(listener);
if(removed) {
if (removed) {
this.didUnregisterListener();
}
}

public override void removeStatusListener(AnimationStatusListener listener) {
bool removed = this._statusListeners.Remove(listener);
if(removed) {
if (removed) {
this.didUnregisterListener();
}
}

public override void removeStatusListener(AnimationStatusListener listener) {
bool removed = this._statusListeners.Remove(listener);
if(removed) {
if (removed) {
this.didUnregisterListener();
}
}

public override void removeStatusListener(AnimationStatusListener listener) {
bool removed = this._statusListeners.Remove(listener);
if(removed) {
if (removed) {
this.didUnregisterListener();
}
}

4
Runtime/animation/listener_helpers.mixin.njk


public override void removeListener(VoidCallback listener) {
bool removed = this._listeners.Remove(listener);
if(removed) {
if (removed) {
this.didUnregisterListener();
}
}

public override void removeStatusListener(AnimationStatusListener listener) {
bool removed = this._statusListeners.Remove(listener);
if(removed) {
if (removed) {
this.didUnregisterListener();
}
}

13
Runtime/animation/tween.cs


}
}
class ConstantTween<T> : Tween<T> {
public ConstantTween(T value) : base(begin: value, end: value) {
}
public override T lerp(float t) {
return this.begin;
}
public override string ToString() {
return $"{this.GetType()}(value: {this.begin})";
}
}
public class CurveTween : Animatable<float> {
public CurveTween(Curve curve = null) {
D.assert(curve != null);

8
Runtime/engine/UIWidgetsPanel.cs


protected virtual void Update() {
this._displayMetrics.Update();
UIWidgetsMessageManager.ensureUIWidgetsMessageManagerIfNeeded();
#if UNITY_ANDROID
if (Input.GetKeyDown(KeyCode.Escape)) {
this._windowAdapter.withBinding(() => {
WidgetsBinding.instance.handlePopRoute();
});
}
#endif
if (!this._viewMetricsCallbackRegistered) {
this._viewMetricsCallbackRegistered = true;

32
Runtime/foundation/debug.cs


using Unity.UIWidgets.editor;
using Unity.UIWidgets.painting;
using Unity.UIWidgets.ui;
using Canvas = Unity.UIWidgets.ui.Canvas;
using Color = Unity.UIWidgets.ui.Color;
using Rect = Unity.UIWidgets.ui.Rect;
public static void logError(string message, Exception ex = null) {
Debug.LogException(new AssertionError(message, ex));
}

#endif
}
}
[Conditional("UIWidgets_DEBUG")]
public static void assert(Func<bool> result, string message = null) {
if (!result()) {

public static bool debugCheckIntrinsicSizes = false;
public static HSVColor debugCurrentRepaintColor =
public static bool debugPrintMouseHoverEvents = false;
public static HSVColor debugCurrentRepaintColor =
HSVColor.fromAHSV(0.4f, 60.0f, 1.0f, 1.0f);
public static void _debugDrawDoubleRect(Canvas canvas, Rect outerRect, Rect innerRect, Color color) {

return true;
});
}
bool? debugPaintPointersEnabled= null,
bool? debugPaintPointersEnabled = null,
bool? debugRepaintRainbowEnabled = null ) {
bool? debugRepaintRainbowEnabled = null) {
if (debugPaintLayerBordersEnabled != null && debugPaintLayerBordersEnabled != D.debugPaintLayerBordersEnabled) {
if (debugPaintLayerBordersEnabled != null &&
debugPaintLayerBordersEnabled != D.debugPaintLayerBordersEnabled) {
if (debugRepaintRainbowEnabled != null && debugRepaintRainbowEnabled != D.debugRepaintRainbowEnabled) {
D.debugRepaintRainbowEnabled = debugRepaintRainbowEnabled.Value;
needRepaint = true;

[Serializable]
public class AssertionError : Exception {
readonly Exception innerException;
public AssertionError(string message) : base(message) {
}

if (this.innerException != null) {
return this.innerException.StackTrace;
}
var stackTrace = base.StackTrace;
var lines = stackTrace.Split('\n');
var strippedLines = lines.Skip(1);

40
Runtime/gestures/binding.cs


this._handlePointerHoverEvent(evt);
}
HitTestResult result;
HitTestResult result = null;
if (evt is PointerDownEvent) {
D.assert(!this._hitTests.ContainsKey(evt.pointer));
result = new HitTestResult();

else if (evt.down) {
result = this._hitTests.getOrDefault(evt.pointer);
}
else {
return;
}
D.assert(() => {
if (D.debugPrintMouseHoverEvents && evt is PointerHoverEvent) {
Debug.LogFormat("{0}", evt);
}
return true;
});
if (result != null) {
if (result != null ||
evt is PointerHoverEvent ||
evt is PointerAddedEvent ||
evt is PointerRemovedEvent
) {
this.dispatchEvent(evt, result);
}
}

}
public void dispatchEvent(PointerEvent evt, HitTestResult result) {
if (result == null) {
D.assert(evt is PointerHoverEvent || evt is PointerAddedEvent || evt is PointerRemovedEvent);
try {
this.pointerRouter.route(evt);
}
catch (Exception ex) {
UIWidgetsError.reportError(new UIWidgetsErrorDetails(
exception: ex,
library: "gesture library",
context: "while dispatching a non-hit-tested pointer event",
informationCollector: information => {
information.AppendLine("Event: ");
information.AppendFormat(" {0}", evt);
}
)
);
}
return;
}
foreach (HitTestEntry entry in result.path) {
try {
entry.target.handleEvent(evt, entry);

6
Runtime/gestures/converter.cs


public static class PointerEventConverter {
static readonly Dictionary<int, _PointerState> _pointers = new Dictionary<int, _PointerState>();
static void clearPointers() {
_pointers.Clear();
}
static _PointerState _ensureStateForPointer(PointerData datum, Offset position) {
return _pointers.putIfAbsent(
datum.device,

if (state == null || !state.down) {
break;
}
D.assert(state.down);
if (position != state.lastPosition) {
Offset offset = position - state.lastPosition;

7
Runtime/gestures/monodrag.cs


public DragGestureRecognizer(
object debugOwner = null,
PointerDeviceKind? kind = null,
DragStartBehavior dragStartBehavior = DragStartBehavior.start)
DragStartBehavior dragStartBehavior = DragStartBehavior.down)
: base(debugOwner: debugOwner, kind: kind) {
this.dragStartBehavior = dragStartBehavior;
}

public override void dispose() {
this._velocityTrackers.Clear();
base.dispose();
}
public override void debugFillProperties(DiagnosticPropertiesBuilder properties) {
base.debugFillProperties(properties);
properties.add(new EnumProperty<DragStartBehavior>("start behavior", this.dragStartBehavior));
}
}

38
Runtime/gestures/recognizer.cs


public enum GestureRecognizerState {
ready,
possible,
accepted,
defunct,
}

object debugOwner = null,
PointerDeviceKind? kind = null
PointerDeviceKind? kind = null,
float? preAcceptSlotTolerance = Constants.kTouchSlop,
float? postAcceptSlotTolerance = Constants.kTouchSlop
D.assert(preAcceptSlotTolerance == null || preAcceptSlotTolerance >= 0,
"The preAcceptSlopTolerance must be positive or null");
D.assert(postAcceptSlotTolerance == null || postAcceptSlotTolerance >= 0,
"The postAcceptSlopTolerance must be positive or null");
this.preAcceptSlotTolerance = preAcceptSlotTolerance;
this.postAcceptSlotTolerance = postAcceptSlotTolerance;
public readonly float? preAcceptSlotTolerance;
public readonly float? postAcceptSlotTolerance;
public GestureRecognizerState state = GestureRecognizerState.ready;

protected override void handleEvent(PointerEvent evt) {
D.assert(this.state != GestureRecognizerState.ready);
if (this.state == GestureRecognizerState.possible && evt.pointer == this.primaryPointer) {
if (evt is PointerMoveEvent && this._getDistance(evt) > Constants.kTouchSlop) {
if (evt.pointer == this.primaryPointer) {
bool isPreAcceptSlopPastTolerance = this.state == GestureRecognizerState.possible &&
this.preAcceptSlotTolerance != null &&
this._getDistance(evt) > this.preAcceptSlotTolerance;
bool isPostAcceptSlopPastTolerance = this.state == GestureRecognizerState.accepted &&
this.postAcceptSlotTolerance != null &&
this._getDistance(evt) > this.postAcceptSlotTolerance;
if (evt is PointerMoveEvent && (isPreAcceptSlopPastTolerance || isPostAcceptSlopPastTolerance)) {
this.resolve(GestureDisposition.rejected);
this.stopTrackingPointer(this.primaryPointer);
}

D.assert(this.deadline == null);
}
public override void acceptGesture(int pointer) {
if (pointer == this.primaryPointer && this.state == GestureRecognizerState.possible) {
this.state = GestureRecognizerState.accepted;
}
}
if (pointer == this.primaryPointer && this.state == GestureRecognizerState.possible) {
if (pointer == this.primaryPointer && (this.state == GestureRecognizerState.possible ||
this.state == GestureRecognizerState.accepted)) {
this._stopTimer();
this.state = GestureRecognizerState.defunct;
}

26
Runtime/material/list_tile.cs


public readonly bool selected;
public static IEnumerable<Widget> divideTiles(BuildContext context = null, IEnumerable<Widget> tiles = null,
Color color = null) {
D.assert(tiles != null);
D.assert(color != null || context != null);
IEnumerator<Widget> enumerator = tiles.GetEnumerator();
List<Widget> result = new List<Widget> { };
Decoration decoration = new BoxDecoration(
border: new Border(
bottom: Divider.createBorderSide(context, color: color)
)
);
Widget tile = enumerator.Current;
while (enumerator.MoveNext()) {
result.Add(new DecoratedBox(
position: DecorationPosition.foreground,
decoration: decoration,
child: tile
));
tile = enumerator.Current;
}
return result;
}
Color _iconColor(ThemeData theme, ListTileTheme tileTheme) {
if (!this.enabled) {

18
Runtime/material/theme_data.cs


IconThemeData accentIconTheme = null,
TabBarTheme tabBarTheme = null,
CardTheme cardTheme = null,
ChipThemeData chipTheme = null,
RuntimePlatform? platform = null,
MaterialTapTargetSize? materialTapTargetSize = null,
PageTransitionsTheme pageTransitionsTheme = null,

tabBarTheme = tabBarTheme ?? new TabBarTheme();
cardTheme = cardTheme ?? new CardTheme();
chipTheme = chipTheme ?? ChipThemeData.fromDefaults(
secondaryColor: primaryColor,
brightness: brightness,
labelStyle: textTheme.body2
);
dialogTheme = dialogTheme ?? new DialogTheme();
D.assert(brightness != null);

D.assert(buttonColor != null);
D.assert(tabBarTheme != null);
D.assert(cardTheme != null);
D.assert(chipTheme != null);
D.assert(dialogTheme != null);
this.brightness = brightness ?? Brightness.light;

this.accentIconTheme = accentIconTheme;
this.tabBarTheme = tabBarTheme;
this.cardTheme = cardTheme;
this.chipTheme = chipTheme;
this.platform = platform.Value;
this.materialTapTargetSize = materialTapTargetSize ?? MaterialTapTargetSize.padded;
this.pageTransitionsTheme = pageTransitionsTheme;

IconThemeData accentIconTheme = null,
TabBarTheme tabBarTheme = null,
CardTheme cardTheme = null,
ChipThemeData chipTheme = null,
RuntimePlatform? platform = null,
MaterialTapTargetSize? materialTapTargetSize = null,
PageTransitionsTheme pageTransitionsTheme = null,

D.assert(buttonColor != null);
D.assert(tabBarTheme != null);
D.assert(cardTheme != null);
D.assert(chipTheme != null);
D.assert(dialogTheme != null);
return new ThemeData(

accentIconTheme: accentIconTheme,
tabBarTheme: tabBarTheme,
cardTheme: cardTheme,
chipTheme: chipTheme,
platform: platform,
materialTapTargetSize: materialTapTargetSize,
pageTransitionsTheme: pageTransitionsTheme,

public readonly TabBarTheme tabBarTheme;
public readonly CardTheme cardTheme;
public readonly ChipThemeData chipTheme;
public readonly RuntimePlatform platform;

IconThemeData accentIconTheme = null,
TabBarTheme tabBarTheme = null,
CardTheme cardTheme = null,
ChipThemeData chipTheme = null,
RuntimePlatform? platform = null,
MaterialTapTargetSize? materialTapTargetSize = null,
PageTransitionsTheme pageTransitionsTheme = null,

accentIconTheme: accentIconTheme ?? this.accentIconTheme,
tabBarTheme: tabBarTheme ?? this.tabBarTheme,
cardTheme: cardTheme ?? this.cardTheme,
chipTheme: chipTheme ?? this.chipTheme,
platform: platform ?? this.platform,
materialTapTargetSize: materialTapTargetSize ?? this.materialTapTargetSize,
pageTransitionsTheme: pageTransitionsTheme ?? this.pageTransitionsTheme,

accentIconTheme: IconThemeData.lerp(a.accentIconTheme, b.accentIconTheme, t),
tabBarTheme: TabBarTheme.lerp(a.tabBarTheme, b.tabBarTheme, t),
cardTheme: CardTheme.lerp(a.cardTheme, b.cardTheme, t),
chipTheme: ChipThemeData.lerp(a.chipTheme, b.chipTheme, t),
platform: t < 0.5 ? a.platform : b.platform,
materialTapTargetSize: t < 0.5 ? a.materialTapTargetSize : b.materialTapTargetSize,
pageTransitionsTheme: t < 0.5 ? a.pageTransitionsTheme : b.pageTransitionsTheme,

other.accentIconTheme == this.accentIconTheme &&
other.tabBarTheme == this.tabBarTheme &&
other.cardTheme == this.cardTheme &&
other.chipTheme == this.chipTheme &&
other.platform == this.platform &&
other.materialTapTargetSize == this.materialTapTargetSize &&
other.pageTransitionsTheme == this.pageTransitionsTheme &&

hashCode = (hashCode * 397) ^ this.accentIconTheme.GetHashCode();
hashCode = (hashCode * 397) ^ this.tabBarTheme.GetHashCode();
hashCode = (hashCode * 397) ^ this.cardTheme.GetHashCode();
hashCode = (hashCode * 397) ^ this.chipTheme.GetHashCode();
hashCode = (hashCode * 397) ^ this.platform.GetHashCode();
hashCode = (hashCode * 397) ^ this.materialTapTargetSize.GetHashCode();
hashCode = (hashCode * 397) ^ this.pageTransitionsTheme.GetHashCode();

properties.add(new DiagnosticsProperty<IconThemeData>("accentIconTheme", this.accentIconTheme));
properties.add(new DiagnosticsProperty<TabBarTheme>("tabBarTheme", this.tabBarTheme));
properties.add(new DiagnosticsProperty<CardTheme>("cardTheme", this.cardTheme));
properties.add(new DiagnosticsProperty<ChipThemeData>("chipTheme", this.chipTheme));
properties.add(
new DiagnosticsProperty<MaterialTapTargetSize>("materialTapTargetSize", this.materialTapTargetSize));
properties.add(

1
Runtime/painting/basic_types.cs


public enum RenderComparison {
identical,
metadata,
function,
paint,
layout,
}

23
Runtime/painting/text_span.cs


public readonly string text;
public readonly List<TextSpan> children;
public readonly GestureRecognizer recognizer;
public readonly HoverRecognizer hoverRecognizer;
GestureRecognizer recognizer = null) {
GestureRecognizer recognizer = null, HoverRecognizer hoverRecognizer = null) {
this.hoverRecognizer = hoverRecognizer;
}
public void build(ParagraphBuilder builder, float textScaleFactor = 1.0f) {

if (hasStyle) {
builder.pop();
}
}
public bool hasHoverRecognizer {
get {
bool need = false;
this.visitTextSpan((text) => {
if (text.hoverRecognizer != null) {
need = true;
return false;
}
return true;
});
return need;
}
}

RenderComparison result = Equals(this.recognizer, other.recognizer)
? RenderComparison.identical
: RenderComparison.metadata;
if (!Equals(this.hoverRecognizer, other.hoverRecognizer)) {
result = RenderComparison.function > result ? RenderComparison.function : result;
}
if (this.style != null) {
var candidate = this.style.compareTo(other.style);
if (candidate > result) {

12
Runtime/rendering/image.cs


this.markNeedsLayout();
}
}
ColorFilter _colorFilter;
void _updateColorFilter() {
if (this._color == null)
this._colorFilter = null;
else
this._colorFilter = ColorFilter.mode(this._color, this._colorBlendMode);
}
Color _color;

rect: offset & this.size,
image: this._image,
scale: this._scale,
// colorFilter: this._colorFilter,
colorFilter: this._colorFilter,
fit: this._fit,
alignment: this._alignment,
centerSlice: this._centerSlice,

59
Runtime/rendering/paragraph.cs


this._selection = null;
this.onSelectionChanged = onSelectionChanged;
this.selectionColor = selectionColor;
this._resetHoverHandler();
}
public Action onSelectionChanged;

case RenderComparison.identical:
case RenderComparison.metadata:
return;
case RenderComparison.function:
this._textPainter.text = value;
break;
case RenderComparison.paint:
this._textPainter.text = value;
this.markNeedsPaint();

this.markNeedsLayout();
break;
}
this._resetHoverHandler();
}
}

}
}
TextSpan _previousHoverSpan;
bool _pointerHoverInside;
bool _hasHoverRecognizer;
void _resetHoverHandler() {
this._hasHoverRecognizer = this._textPainter.text.hasHoverRecognizer;
this._previousHoverSpan = null;
this._pointerHoverInside = false;
}
void _handleKeyEvent(RawKeyEvent keyEvent) {
//only allow KCommand.copy
if (keyEvent is RawKeyUpEvent) {

this.onSelectionChanged?.Invoke();
}
void _handlePointerHover(PointerEvent evt) {
if (!this._hasHoverRecognizer) {
return;
}
if (evt is PointerEnterEvent) {
this._pointerHoverInside = true;
}
else if (evt is PointerLeaveEvent) {
this._pointerHoverInside = false;
this._previousHoverSpan?.hoverRecognizer?.OnPointerLeave?.Invoke();
this._previousHoverSpan = null;
}
else if (evt is PointerHoverEvent && this._pointerHoverInside) {
this._layoutTextWithConstraints(this.constraints);
Offset offset = this.globalToLocal(evt.position);
TextPosition position = this._textPainter.getPositionForOffset(offset);
TextSpan span = this._textPainter.text.getSpanForPosition(position);
if (this._previousHoverSpan != span) {
this._previousHoverSpan?.hoverRecognizer?.OnPointerLeave?.Invoke();
span?.hoverRecognizer?.OnPointerEnter?.Invoke((PointerHoverEvent) evt);
this._previousHoverSpan = span;
}
}
}
if (!(evt is PointerDownEvent)) {
if (evt is PointerDownEvent) {
this._layoutTextWithConstraints(this.constraints);
Offset offset = ((BoxHitTestEntry) entry).localPosition;
TextPosition position = this._textPainter.getPositionForOffset(offset);
TextSpan span = this._textPainter.text.getSpanForPosition(position);
span?.recognizer?.addPointer((PointerDownEvent) evt);
this._layoutTextWithConstraints(this.constraints);
Offset offset = ((BoxHitTestEntry) entry).localPosition;
TextPosition position = this._textPainter.getPositionForOffset(offset);
TextSpan span = this._textPainter.text.getSpanForPosition(position);
span?.recognizer?.addPointer((PointerDownEvent) evt);
this._handlePointerHover(evt);
}
protected override void performLayout() {

foreach (var box in this._selectionRects) {
barPath.addRect(box.toRect().shift(effectiveOffset));
}
canvas.drawPath(barPath, paint);
}

18
Runtime/widgets/binding.cs


using Unity.UIWidgets.foundation;
using Unity.UIWidgets.rendering;
using Unity.UIWidgets.ui;
using UnityEngine;
namespace Unity.UIWidgets.widgets {
public interface WidgetsBindingObserver {

public bool removeObserver(WidgetsBindingObserver observer) {
return this._observers.Remove(observer);
}
public void handlePopRoute() {
var idx = -1;
void _handlePopRouteSub(bool result) {
if (!result) {
idx++;
if (idx >= this._observers.Count) {
Application.Quit();
return;
}
this._observers[idx].didPopRoute().Then(_handlePopRouteSub);
}
}
_handlePopRouteSub(false);
}
public readonly WidgetInspectorService widgetInspectorService;

2
Samples/UIWidgetSample/txt/TextSpanGesture.cs


color: Colors.green,
decoration: TextDecoration.underline
)
// recognizer: this._longPressRecognizer
//recognizer: this._longPressRecognizer
),
new TextSpan(
text: " secret?"

92
Samples/UIWidgetsGallery/gallery/demos.cs


routeName: ContactsDemo.routeName,
buildRoute: (BuildContext context) => new ContactsDemo()
),
// new GalleryDemo(
// title: "Animation",
// subtitle: "Section organizer",
// icon: GalleryIcons.animation,
// category: GalleryDemoCategory._kDemos,
// routeName: AnimationDemo.routeName,
// buildRoute: (BuildContext context) => new AnimationDemo()
// ),
//
// // Style
new GalleryDemo(
title: "Animation",
subtitle: "Section organizer",
icon: GalleryIcons.animation,
category: DemoUtils._kDemos,
routeName: AnimationDemo.routeName,
buildRoute: (BuildContext context) => new AnimationDemo()
),
// Style
new GalleryDemo(
title: "Colors",
subtitle: "All of the predefined colors",

documentationUrl: "https://docs.flutter.io/flutter/material/BottomNavigationBar-class.html",
buildRoute: (BuildContext context) => new BottomNavigationDemo()
),
// new GalleryDemo(
// title: "Bottom sheet: Modal",
// subtitle: "A dismissable bottom sheet",
// icon: GalleryIcons.bottom_sheets,
// category: GalleryDemoCategory._kMaterialComponents,
// routeName: ModalBottomSheetDemo.routeName,
// documentationUrl: "https://docs.flutter.io/flutter/material/showModalBottomSheet.html",
// buildRoute: (BuildContext context) => ModalBottomSheetDemo()
// ),
// new GalleryDemo(
// title: "Bottom sheet: Persistent",
// subtitle: "A bottom sheet that sticks around",
// icon: GalleryIcons.bottom_sheet_persistent,
// category: GalleryDemoCategory._kMaterialComponents,
// routeName: PersistentBottomSheetDemo.routeName,
// documentationUrl: "https://docs.flutter.io/flutter/material/ScaffoldState/showBottomSheet.html",
// buildRoute: (BuildContext context) => PersistentBottomSheetDemo()
// ),
new GalleryDemo(
title: "Bottom sheet: Modal",
subtitle: "A dismissable bottom sheet",
icon: GalleryIcons.bottom_sheets,
category: _kMaterialComponents,
routeName: ModalBottomSheetDemo.routeName,
documentationUrl: "https://docs.flutter.io/flutter/material/showModalBottomSheet.html",
buildRoute: (BuildContext context) => new ModalBottomSheetDemo()
),
new GalleryDemo(
title: "Bottom sheet: Persistent",
subtitle: "A bottom sheet that sticks around",
icon: GalleryIcons.bottom_sheet_persistent,
category: _kMaterialComponents,
routeName: PersistentBottomSheetDemo.routeName,
documentationUrl: "https://docs.flutter.io/flutter/material/ScaffoldState/showBottomSheet.html",
buildRoute: (BuildContext context) => new PersistentBottomSheetDemo()
),
new GalleryDemo(
title: "Buttons",
subtitle: "Flat, raised, dropdown, and more",

buildRoute: (BuildContext context) => new ButtonsDemo()
),
// new GalleryDemo(
// title: "Buttons: Floating Action Button",
// subtitle: "FAB with transitions",
// icon: GalleryIcons.buttons,
// category: GalleryDemoCategory._kMaterialComponents,
// routeName: TabsFabDemo.routeName,
// documentationUrl: "https://docs.flutter.io/flutter/material/FloatingActionButton-class.html",
// buildRoute: (BuildContext context) => TabsFabDemo()
// ),
new GalleryDemo(
title: "Buttons: Floating Action Button",
subtitle: "FAB with transitions",
icon: GalleryIcons.buttons,
category: _kMaterialComponents,
routeName: TabsFabDemo.routeName,
documentationUrl: "https://docs.flutter.io/flutter/material/FloatingActionButton-class.html",
buildRoute: (BuildContext context) => new TabsFabDemo()
),
new GalleryDemo(
title: "Cards",
subtitle: "Baseline cards with rounded corners",

documentationUrl: "https://docs.flutter.io/flutter/material/Card-class.html",
buildRoute: (BuildContext context) => new CardsDemo()
),
// new GalleryDemo(
// title: "Chips",
// subtitle: "Labeled with delete buttons and avatars",
// icon: GalleryIcons.chips,
// category: GalleryDemoCategory._kMaterialComponents,
// routeName: ChipDemo.routeName,
// documentationUrl: "https://docs.flutter.io/flutter/material/Chip-class.html",
// buildRoute: (BuildContext context) => ChipDemo()
// ),
new GalleryDemo(
title: "Chips",
subtitle: "Labeled with delete buttons and avatars",
icon: GalleryIcons.chips,
category: _kMaterialComponents,
routeName: ChipDemo.routeName,
documentationUrl: "https://docs.flutter.io/flutter/material/Chip-class.html",
buildRoute: (BuildContext context) => new ChipDemo()
),
// new GalleryDemo(
// title: "Data tables",
// subtitle: "Rows and columns",

26
Runtime/gestures/hover.cs


using Unity.UIWidgets.foundation;
namespace Unity.UIWidgets.gestures {
public delegate void PointerHoverEnterCallback(PointerHoverEvent evt);
public delegate void PointerHoverLeaveCallback();
public class HoverRecognizer : DiagnosticableTree {
public HoverRecognizer(object debugOwner = null) {
this.debugOwner = debugOwner;
}
readonly object debugOwner;
public PointerHoverEnterCallback OnPointerEnter;
public PointerHoverLeaveCallback OnPointerLeave;
public override void debugFillProperties(DiagnosticPropertiesBuilder properties) {
base.debugFillProperties(properties);
properties.add(new DiagnosticsProperty<object>("debugOwner", this.debugOwner,
defaultValue: Diagnostics.kNullDefaultValue));
}
}
}

11
Runtime/gestures/hover.cs.meta


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

1001
Runtime/material/chip.cs
文件差异内容过多而无法显示
查看文件

3
Runtime/material/chip.cs.meta


fileFormatVersion: 2
guid: d4ca6b86209d4615b9aba98d6d112673
timeCreated: 1555477997

298
Runtime/material/chip_theme.cs


using Unity.UIWidgets.foundation;
using Unity.UIWidgets.painting;
using Unity.UIWidgets.service;
using Unity.UIWidgets.ui;
using Unity.UIWidgets.widgets;
using TextStyle = Unity.UIWidgets.painting.TextStyle;
namespace Unity.UIWidgets.material {
public class ChipTheme : InheritedWidget {
public ChipTheme(
Key key = null,
ChipThemeData data = null,
Widget child = null
) : base(key: key, child: child) {
D.assert(child != null);
D.assert(data != null);
this.data = data;
}
public readonly ChipThemeData data;
public static ChipThemeData of(BuildContext context) {
ChipTheme inheritedTheme = (ChipTheme) context.inheritFromWidgetOfExactType(typeof(ChipTheme));
return inheritedTheme?.data ?? Theme.of(context).chipTheme;
}
public override bool updateShouldNotify(InheritedWidget _oldWidget) {
ChipTheme oldWidget = _oldWidget as ChipTheme;
return this.data != oldWidget.data;
}
}
public class ChipThemeData : Diagnosticable {
public ChipThemeData(
Color backgroundColor = null,
Color deleteIconColor = null,
Color disabledColor = null,
Color selectedColor = null,
Color secondarySelectedColor = null,
EdgeInsets labelPadding = null,
EdgeInsets padding = null,
ShapeBorder shape = null,
TextStyle labelStyle = null,
TextStyle secondaryLabelStyle = null,
Brightness? brightness = null,
float? elevation = null,
float? pressElevation = null
) {
D.assert(backgroundColor != null);
D.assert(disabledColor != null);
D.assert(selectedColor != null);
D.assert(secondarySelectedColor != null);
D.assert(labelPadding != null);
D.assert(padding != null);
D.assert(shape != null);
D.assert(labelStyle != null);
D.assert(secondaryLabelStyle != null);
D.assert(brightness != null);
this.backgroundColor = backgroundColor;
this.deleteIconColor = deleteIconColor;
this.disabledColor = disabledColor;
this.selectedColor = selectedColor;
this.secondarySelectedColor = secondarySelectedColor;
this.labelPadding = labelPadding;
this.padding = padding;
this.shape = shape;
this.labelStyle = labelStyle;
this.secondaryLabelStyle = secondaryLabelStyle;
this.brightness = brightness;
this.elevation = elevation;
this.pressElevation = pressElevation;
}
public static ChipThemeData fromDefaults(
Brightness? brightness = null,
Color primaryColor = null,
Color secondaryColor = null,
TextStyle labelStyle = null
) {
D.assert(primaryColor != null || brightness != null,
"One of primaryColor or brightness must be specified");
D.assert(primaryColor == null || brightness == null,
"Only one of primaryColor or brightness may be specified");
D.assert(secondaryColor != null);
D.assert(labelStyle != null);
if (primaryColor != null) {
brightness = ThemeData.estimateBrightnessForColor(primaryColor);
}
const int backgroundAlpha = 0x1f; // 12%
const int deleteIconAlpha = 0xde; // 87%
const int disabledAlpha = 0x0c; // 38% * 12% = 5%
const int selectAlpha = 0x3d; // 12% + 12% = 24%
const int textLabelAlpha = 0xde; // 87%
ShapeBorder shape = new StadiumBorder();
EdgeInsets labelPadding = EdgeInsets.symmetric(horizontal: 8.0f);
EdgeInsets padding = EdgeInsets.all(4.0f);
primaryColor = primaryColor ?? (brightness == Brightness.light ? Colors.black : Colors.white);
Color backgroundColor = primaryColor.withAlpha(backgroundAlpha);
Color deleteIconColor = primaryColor.withAlpha(deleteIconAlpha);
Color disabledColor = primaryColor.withAlpha(disabledAlpha);
Color selectedColor = primaryColor.withAlpha(selectAlpha);
Color secondarySelectedColor = secondaryColor.withAlpha(selectAlpha);
TextStyle secondaryLabelStyle = labelStyle.copyWith(
color: secondaryColor.withAlpha(textLabelAlpha)
);
labelStyle = labelStyle.copyWith(color: primaryColor.withAlpha(textLabelAlpha));
return new ChipThemeData(
backgroundColor: backgroundColor,
deleteIconColor: deleteIconColor,
disabledColor: disabledColor,
selectedColor: selectedColor,
secondarySelectedColor: secondarySelectedColor,
labelPadding: labelPadding,
padding: padding,
shape: shape,
labelStyle: labelStyle,
secondaryLabelStyle: secondaryLabelStyle,
brightness: brightness
);
}
public readonly Color backgroundColor;
public readonly Color deleteIconColor;
public readonly Color disabledColor;
public readonly Color selectedColor;
public readonly Color secondarySelectedColor;
public readonly EdgeInsets labelPadding;
public readonly EdgeInsets padding;
public readonly ShapeBorder shape;
public readonly TextStyle labelStyle;
public readonly TextStyle secondaryLabelStyle;
public readonly Brightness? brightness;
public readonly float? elevation;
public readonly float? pressElevation;
public ChipThemeData copyWith(
Color backgroundColor = null,
Color deleteIconColor = null,
Color disabledColor = null,
Color selectedColor = null,
Color secondarySelectedColor = null,
EdgeInsets labelPadding = null,
EdgeInsets padding = null,
ShapeBorder shape = null,
TextStyle labelStyle = null,
TextStyle secondaryLabelStyle = null,
Brightness? brightness = null,
float? elevation = null,
float? pressElevation = null
) {
return new ChipThemeData(
backgroundColor: backgroundColor ?? this.backgroundColor,
deleteIconColor: deleteIconColor ?? this.deleteIconColor,
disabledColor: disabledColor ?? this.disabledColor,
selectedColor: selectedColor ?? this.selectedColor,
secondarySelectedColor: secondarySelectedColor ?? this.secondarySelectedColor,
labelPadding: labelPadding ?? this.labelPadding,
padding: padding ?? this.padding,
shape: shape ?? this.shape,
labelStyle: labelStyle ?? this.labelStyle,
secondaryLabelStyle: secondaryLabelStyle ?? this.secondaryLabelStyle,
brightness: brightness ?? this.brightness,
elevation: elevation ?? this.elevation,
pressElevation: pressElevation ?? this.pressElevation
);
}
public static ChipThemeData lerp(ChipThemeData a, ChipThemeData b, float t) {
D.assert(t != null);
if (a == null && b == null) {
return null;
}
return new ChipThemeData(
backgroundColor: Color.lerp(a?.backgroundColor, b?.backgroundColor, t),
deleteIconColor: Color.lerp(a?.deleteIconColor, b?.deleteIconColor, t),
disabledColor: Color.lerp(a?.disabledColor, b?.disabledColor, t),
selectedColor: Color.lerp(a?.selectedColor, b?.selectedColor, t),
secondarySelectedColor: Color.lerp(a?.secondarySelectedColor, b?.secondarySelectedColor, t),
labelPadding: EdgeInsets.lerp(a?.labelPadding, b?.labelPadding, t),
padding: EdgeInsets.lerp(a?.padding, b?.padding, t),
shape: ShapeBorder.lerp(a?.shape, b?.shape, t),
labelStyle: TextStyle.lerp(a?.labelStyle, b?.labelStyle, t),
secondaryLabelStyle: TextStyle.lerp(a?.secondaryLabelStyle, b?.secondaryLabelStyle, t),
brightness: t < 0.5f ? a?.brightness ?? Brightness.light : b?.brightness ?? Brightness.light,
elevation: MathUtils.lerpFloat(a?.elevation ?? 0.0f, b?.elevation ?? 0.0f, t),
pressElevation: MathUtils.lerpFloat(a?.pressElevation ?? 0.0f, b?.pressElevation ?? 0.0f, t)
);
}
public override int GetHashCode() {
var hashCode = this.backgroundColor.GetHashCode();
hashCode = (hashCode * 397) ^ this.deleteIconColor.GetHashCode();
hashCode = (hashCode * 397) ^ this.disabledColor.GetHashCode();
hashCode = (hashCode * 397) ^ this.selectedColor.GetHashCode();
hashCode = (hashCode * 397) ^ this.secondarySelectedColor.GetHashCode();
hashCode = (hashCode * 397) ^ this.labelPadding.GetHashCode();
hashCode = (hashCode * 397) ^ this.padding.GetHashCode();
hashCode = (hashCode * 397) ^ this.shape.GetHashCode();
hashCode = (hashCode * 397) ^ this.labelStyle.GetHashCode();
hashCode = (hashCode * 397) ^ this.secondaryLabelStyle.GetHashCode();
hashCode = (hashCode * 397) ^ this.brightness.GetHashCode();
hashCode = (hashCode * 397) ^ this.elevation.GetHashCode();
hashCode = (hashCode * 397) ^ this.pressElevation.GetHashCode();
return hashCode;
}
public bool Equals(ChipThemeData other) {
return other.backgroundColor == this.backgroundColor
&& other.deleteIconColor == this.deleteIconColor
&& other.disabledColor == this.disabledColor
&& other.selectedColor == this.selectedColor
&& other.secondarySelectedColor == this.secondarySelectedColor
&& other.labelPadding == this.labelPadding
&& other.padding == this.padding
&& other.shape == this.shape
&& other.labelStyle == this.labelStyle
&& other.secondaryLabelStyle == this.secondaryLabelStyle
&& other.brightness == this.brightness
&& other.elevation == this.elevation
&& other.pressElevation == this.pressElevation;
}
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((ChipThemeData) obj);
}
public static bool operator ==(ChipThemeData left, ChipThemeData right) {
return Equals(left, right);
}
public static bool operator !=(ChipThemeData left, ChipThemeData right) {
return !Equals(left, right);
}
public override void debugFillProperties(DiagnosticPropertiesBuilder properties) {
base.debugFillProperties(properties);
ThemeData defaultTheme = ThemeData.fallback();
ChipThemeData defaultData = fromDefaults(
secondaryColor: defaultTheme.primaryColor,
brightness: defaultTheme.brightness,
labelStyle: defaultTheme.textTheme.body2
);
properties.add(new DiagnosticsProperty<Color>("backgroundColor", this.backgroundColor,
defaultValue: defaultData.backgroundColor));
properties.add(new DiagnosticsProperty<Color>("deleteIconColor", this.deleteIconColor,
defaultValue: defaultData.deleteIconColor));
properties.add(new DiagnosticsProperty<Color>("disabledColor", this.disabledColor,
defaultValue: defaultData.disabledColor));
properties.add(new DiagnosticsProperty<Color>("selectedColor", this.selectedColor,
defaultValue: defaultData.selectedColor));
properties.add(new DiagnosticsProperty<Color>("secondarySelectedColor", this.secondarySelectedColor,
defaultValue: defaultData.secondarySelectedColor));
properties.add(new DiagnosticsProperty<EdgeInsets>("labelPadding", this.labelPadding,
defaultValue: defaultData.labelPadding));
properties.add(
new DiagnosticsProperty<EdgeInsets>("padding", this.padding, defaultValue: defaultData.padding));
properties.add(new DiagnosticsProperty<ShapeBorder>("shape", this.shape, defaultValue: defaultData.shape));
properties.add(new DiagnosticsProperty<TextStyle>("labelStyle", this.labelStyle,
defaultValue: defaultData.labelStyle));
properties.add(new DiagnosticsProperty<TextStyle>("secondaryLabelStyle", this.secondaryLabelStyle,
defaultValue: defaultData.secondaryLabelStyle));
properties.add(new EnumProperty<Brightness?>("brightness", this.brightness,
defaultValue: defaultData.brightness));
properties.add(new FloatProperty("elevation", this.elevation, defaultValue: defaultData.elevation));
properties.add(new FloatProperty("pressElevation", this.pressElevation,
defaultValue: defaultData.pressElevation));
}
}
}

3
Runtime/material/chip_theme.cs.meta


fileFormatVersion: 2
guid: 4d46bfb5d5bb492e92f07114849df905
timeCreated: 1556165564

132
Runtime/material/circle_avatar.cs


using Unity.UIWidgets.foundation;
using Unity.UIWidgets.material;
using Unity.UIWidgets.painting;
using Unity.UIWidgets.rendering;
using Unity.UIWidgets.service;
using Unity.UIWidgets.ui;
using Unity.UIWidgets.widgets;
using TextStyle = Unity.UIWidgets.painting.TextStyle;
namespace UIWidgetsGallery.gallery {
public class CircleAvatar : StatelessWidget {
public CircleAvatar(
Key key = null,
Widget child = null,
Color backgroundColor = null,
ImageProvider backgroundImage = null,
Color foregroundColor = null,
float? radius = null,
float? minRadius = null,
float? maxRadius = null
) : base(key: key) {
D.assert(radius == null || (minRadius == null && maxRadius == null));
this.child = child;
this.backgroundColor = backgroundColor;
this.backgroundImage = backgroundImage;
this.foregroundColor = foregroundColor;
this.radius = radius;
this.minRadius = minRadius;
this.maxRadius = maxRadius;
}
public readonly Widget child;
public readonly Color backgroundColor;
public readonly Color foregroundColor;
public readonly ImageProvider backgroundImage;
public readonly float? radius;
public readonly float? minRadius;
public readonly float? maxRadius;
const float _defaultRadius = 20.0f;
const float _defaultMinRadius = 0.0f;
const float _defaultMaxRadius = float.PositiveInfinity;
float _minDiameter {
get {
if (this.radius == null && this.minRadius == null && this.maxRadius == null) {
return _defaultRadius * 2.0f;
}
return 2.0f * (this.radius ?? this.minRadius ?? _defaultMinRadius);
}
}
float _maxDiameter {
get {
if (this.radius == null && this.minRadius == null && this.maxRadius == null) {
return _defaultRadius * 2.0f;
}
return 2.0f * (this.radius ?? this.maxRadius ?? _defaultMaxRadius);
}
}
public override Widget build(BuildContext context) {
D.assert(WidgetsD.debugCheckHasMediaQuery(context));
ThemeData theme = Theme.of(context);
TextStyle textStyle = theme.primaryTextTheme.subhead.copyWith(color: this.foregroundColor);
Color effectiveBackgroundColor = this.backgroundColor;
if (effectiveBackgroundColor == null) {
switch (ThemeData.estimateBrightnessForColor(textStyle.color)) {
case Brightness.dark:
effectiveBackgroundColor = theme.primaryColorLight;
break;
case Brightness.light:
effectiveBackgroundColor = theme.primaryColorDark;
break;
}
}
else if (this.foregroundColor == null) {
switch (ThemeData.estimateBrightnessForColor(this.backgroundColor)) {
case Brightness.dark:
textStyle = textStyle.copyWith(color: theme.primaryColorLight);
break;
case Brightness.light:
textStyle = textStyle.copyWith(color: theme.primaryColorDark);
break;
}
}
float minDiameter = this._minDiameter;
float maxDiameter = this._maxDiameter;
return new AnimatedContainer(
constraints: new BoxConstraints(
minHeight: minDiameter,
minWidth: minDiameter,
maxWidth: maxDiameter,
maxHeight: maxDiameter
),
duration: Constants.kThemeChangeDuration,
decoration: new BoxDecoration(
color: effectiveBackgroundColor,
image: this.backgroundImage != null
? new DecorationImage(image: this.backgroundImage, fit: BoxFit.cover)
: null,
shape: BoxShape.circle
),
child: this.child == null
? null
: new Center(
child: new MediaQuery(
data: MediaQuery.of(context).copyWith(textScaleFactor: 1.0f),
child: new IconTheme(
data: theme.iconTheme.copyWith(color: textStyle.color),
child: new DefaultTextStyle(
style: textStyle,
child: this.child
)
)
)
)
);
}
}
}

3
Runtime/material/circle_avatar.cs.meta


fileFormatVersion: 2
guid: 32591e65e11049cab124c86bc8fe573c
timeCreated: 1556169017

82
Samples/UIWidgetSample/HoverRecognizerSample.cs


using System.Collections.Generic;
using Unity.UIWidgets.gestures;
using Unity.UIWidgets.material;
using Unity.UIWidgets.painting;
using Unity.UIWidgets.rendering;
using Unity.UIWidgets.ui;
using Unity.UIWidgets.widgets;
using UnityEngine;
namespace UIWidgetsSample {
public class HoverRecognizerSample : UIWidgetsSamplePanel {
protected override Widget createWidget() {
return new MaterialApp(
showPerformanceOverlay: false,
home: new HoverMainPanel()
);
}
protected override void OnEnable() {
FontManager.instance.addFont(Resources.Load<Font>(path: "MaterialIcons-Regular"), "Material Icons");
base.OnEnable();
}
}
class HoverMainPanel : StatefulWidget {
public override State createState() {
return new HoverMainPanelState();
}
}
class HoverMainPanelState : State<HoverMainPanel> {
bool hoverActivated = false;
public override Widget build(BuildContext context) {
return new Scaffold(
appBar: new AppBar(
title: new Center(
child: new Text("Test Hover Widget")
)
),
body: new Card(
color: Colors.white,
child: new Center(
child: new Column(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.center,
children: new List<Widget> {
new Icon(this.hoverActivated ? Unity.UIWidgets.material.Icons.pool : Unity.UIWidgets.material.Icons.directions_walk, size: 128.0f),
new RichText(
text: new TextSpan(
text: "Test <",
style: new TextStyle(color: Colors.black),
children: new List<TextSpan>() {
new TextSpan(
text: "Hover Me",
style: new TextStyle(
color: Colors.green,
decoration: TextDecoration.underline
),
hoverRecognizer: new HoverRecognizer {
OnPointerEnter = evt => {
this.setState(() => { this.hoverActivated = true; });
},
OnPointerLeave = () => {
this.setState(() => { this.hoverActivated = false;});
}
}
),
new TextSpan(
text: ">"
)
}
)
)
}
)
)
)
);
}
}
}

11
Samples/UIWidgetSample/HoverRecognizerSample.cs.meta


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

3
Samples/UIWidgetsGallery/demo/animation.meta


fileFormatVersion: 2
guid: 4861503ddfc74b9ba36f159521c79b65
timeCreated: 1554970886

15
Samples/UIWidgetsGallery/demo/animation_demo.cs


using Unity.UIWidgets.foundation;
using Unity.UIWidgets.widgets;
namespace UIWidgetsGallery.gallery {
public class AnimationDemo : StatelessWidget {
public AnimationDemo(Key key = null) : base(key: key) {
}
public const string routeName = "/animation";
public override Widget build(BuildContext context) {
return new AnimationDemoHome();
}
}
}

3
Samples/UIWidgetsGallery/demo/animation_demo.cs.meta


fileFormatVersion: 2
guid: f13faff4d2b84ce0935236f3b953849f
timeCreated: 1554969121

322
Samples/UIWidgetsGallery/demo/material/chip_demo.cs


using System.Collections.Generic;
using System.Linq;
using Unity.UIWidgets.foundation;
using Unity.UIWidgets.material;
using Unity.UIWidgets.painting;
using Unity.UIWidgets.rendering;
using Unity.UIWidgets.ui;
using Unity.UIWidgets.widgets;
namespace UIWidgetsGallery.gallery {
class ChipDemoUtils {
public static readonly List<string> _defaultMaterials = new List<string> {
"poker",
"tortilla",
"fish and",
"micro",
"wood"
};
public static readonly List<string> _defaultActions = new List<string> {
"flake",
"cut",
"fragment",
"splinter",
"nick",
"fry",
"solder",
"cash in",
"eat"
};
public static readonly Dictionary<string, string> _results = new Dictionary<string, string> {
{"flake", "flaking"},
{"cut", "cutting"},
{"fragment", "fragmenting"},
{"splinter", "splintering"},
{"nick", "nicking"},
{"fry", "frying"},
{"solder", "soldering"},
{"cash in", "cashing in"},
{"eat", "eating"}
};
public static readonly List<string> _defaultTools = new List<string> {
"hammer",
"chisel",
"fryer",
"fabricator",
"customer"
};
public static readonly Dictionary<string, string> _avatars = new Dictionary<string, string> {
{"hammer", "people/square/ali"},
{"chisel", "people/square/sandra"},
{"fryer", "people/square/trevor"},
{"fabricator", "people/square/stella"},
{"customer", "people/square/peter"}
};
public static readonly Dictionary<string, HashSet<string>> _toolActions =
new Dictionary<string, HashSet<string>> {
{"hammer", new HashSet<string>(new List<string> {"flake", "fragment", "splinter"})},
{"chisel", new HashSet<string>(new List<string> {"flake", "nick", "splinter"})},
{"fryer", new HashSet<string>(new List<string> {"fry"})},
{"fabricator", new HashSet<string>(new List<string> {"solder"})},
{"customer", new HashSet<string>(new List<string> {"cash in", "eat"})}
};
public static readonly Dictionary<string, HashSet<string>> _materialActions =
new Dictionary<string, HashSet<string>> {
{"poker", new HashSet<string>(new List<string> {"cash in"})},
{"tortilla", new HashSet<string>(new List<string> {"fry", "eat"})},
{"fish and", new HashSet<string>(new List<string> {"fry", "eat"})},
{"micro", new HashSet<string>(new List<string> {"solder", "fragment"})},
{"wood", new HashSet<string>(new List<string> {"flake", "cut", "splinter", "nick"})}
};
}
class _ChipsTile : StatelessWidget {
public _ChipsTile(
Key key = null,
string label = null,
List<Widget> children = null
) : base(key: key) {
this.label = label;
this.children = children;
}
public readonly string label;
public readonly List<Widget> children;
public override Widget build(BuildContext context) {
List<Widget> cardChildren = new List<Widget> {
new Container(
padding: EdgeInsets.only(top: 16.0f, bottom: 4.0f),
alignment: Alignment.center,
child: new Text(this.label, textAlign: TextAlign.left)
)
};
if (this.children.isNotEmpty()) {
cardChildren.Add(new Wrap(
children: this.children.Select<Widget, Widget>((Widget chip) => {
return new Padding(
padding: EdgeInsets.all(2.0f),
child: chip
);
}).ToList()));
}
else {
TextStyle textStyle = Theme.of(context).textTheme.caption.copyWith(fontStyle: FontStyle.italic);
cardChildren.Add(
new Container(
alignment: Alignment.center,
constraints: new BoxConstraints(minWidth: 48.0f, minHeight: 48.0f),
padding: EdgeInsets.all(8.0f),
child: new Text("None", style: textStyle)
)
);
}
return new Card(
child: new Column(
mainAxisSize: MainAxisSize.min,
children: cardChildren
)
);
}
}
public class ChipDemo : StatefulWidget {
public const string routeName = "/material/chip";
public override State createState() {
return new _ChipDemoState();
}
}
class _ChipDemoState : State<ChipDemo> {
public _ChipDemoState() {
this._reset();
}
HashSet<string> _materials = new HashSet<string>(new List<string> { });
string _selectedMaterial = "";
string _selectedAction = "";
HashSet<string> _tools = new HashSet<string>(new List<string> { });
HashSet<string> _selectedTools = new HashSet<string>(new List<string> { });
HashSet<string> _actions = new HashSet<string>(new List<string> { });
bool _showShapeBorder = false;
void _reset() {
this._materials.Clear();
this._materials.UnionWith(ChipDemoUtils._defaultMaterials);
this._actions.Clear();
this._actions.UnionWith(ChipDemoUtils._defaultActions);
this._tools.Clear();
this._tools.UnionWith(ChipDemoUtils._defaultTools);
this._selectedMaterial = "";
this._selectedAction = "";
this._selectedTools.Clear();
}
void _removeMaterial(string name) {
this._materials.Remove(name);
if (this._selectedMaterial == name) {
this._selectedMaterial = "";
}
}
void _removeTool(string name) {
this._tools.Remove(name);
this._selectedTools.Remove(name);
}
string _capitalize(string name) {
D.assert(name != null && name.isNotEmpty());
return name.Substring(0, 1).ToUpper() + name.Substring(1);
}
Color _nameToColor(string name) {
D.assert(name.Length > 1);
int hash = name.GetHashCode() & 0xffff;
float hue = (360.0f * hash / (1 << 15)) % 360.0f;
return HSVColor.fromAHSV(1.0f, hue, 0.4f, 0.90f).toColor();
}
AssetImage _nameToAvatar(string name) {
D.assert(ChipDemoUtils._avatars.ContainsKey(name));
return new AssetImage(
ChipDemoUtils._avatars[name]
);
}
string _createResult() {
if (this._selectedAction.isEmpty()) {
return "";
}
return this._capitalize(ChipDemoUtils._results[this._selectedAction]) + "!";
}
public override Widget build(BuildContext context) {
List<Widget> chips = this._materials.Select<string, Widget>((string name) => {
return new Chip(
key: Key.key(name),
backgroundColor: this._nameToColor(name),
label: new Text(this._capitalize(name)),
onDeleted: () => { this.setState(() => { this._removeMaterial(name); }); }
);
}).ToList();
List<Widget> inputChips = this._tools.Select<string, Widget>((string name) => {
return new InputChip(
key: ValueKey<string>.key(name),
avatar: new CircleAvatar(
backgroundImage: this._nameToAvatar(name)
),
label: new Text(this._capitalize(name)),
onDeleted: () => { this.setState(() => { this._removeTool(name); }); });
}).ToList();
List<Widget> choiceChips = this._materials.Select<string, Widget>((string name) => {
return new ChoiceChip(
key: ValueKey<string>.key(name),
backgroundColor: this._nameToColor(name),
label: new Text(this._capitalize(name)),
selected: this._selectedMaterial == name,
onSelected: (bool value) => {
this.setState(() => { this._selectedMaterial = value ? name : ""; });
}
);
}).ToList();
List<Widget> filterChips = ChipDemoUtils._defaultTools.Select<string, Widget>((string name) => {
return new FilterChip(
key: ValueKey<string>.key(name),
label: new Text(this._capitalize(name)),
selected: this._tools.Contains(name) ? this._selectedTools.Contains(name) : false,
onSelected: !this._tools.Contains(name)
? (ValueChanged<bool>) null
: (bool value) => {
this.setState(() => {
if (!value) {
this._selectedTools.Remove(name);
}
else {
this._selectedTools.Add(name);
}
});
}
);
}).ToList();
HashSet<string> allowedActions = new HashSet<string>(new List<string> { });
if (this._selectedMaterial != null && this._selectedMaterial.isNotEmpty()) {
foreach (string tool in this._selectedTools) {
allowedActions.UnionWith(ChipDemoUtils._toolActions[tool]);
}
allowedActions =
new HashSet<string>(
allowedActions.Intersect(ChipDemoUtils._materialActions[this._selectedMaterial]));
}
List<Widget> actionChips = allowedActions.Select<string, Widget>((string name) => {
return new ActionChip(
label: new Text(this._capitalize(name)),
onPressed: () => { this.setState(() => { this._selectedAction = name; }); }
);
}).ToList();
ThemeData theme = Theme.of(context);
List<Widget> tiles = new List<Widget> {
new SizedBox(height: 8.0f, width: 0.0f),
new _ChipsTile(label: "Available Materials (Chip)", children: chips),
new _ChipsTile(label: "Available Tools (InputChip)", children: inputChips),
new _ChipsTile(label: "Choose a Material (ChoiceChip)", children: choiceChips),
new _ChipsTile(label: "Choose Tools (FilterChip)", children: filterChips),
new _ChipsTile(label: "Perform Allowed Action (ActionChip)", children: actionChips),
new Divider(),
new Padding(
padding: EdgeInsets.all(8.0f),
child: new Center(
child: new Text(this._createResult(),
style: theme.textTheme.title
)
)
)
};
return new Scaffold(
appBar: new AppBar(
title: new Text("Chips"),
actions: new List<Widget> {
new MaterialDemoDocumentationButton(ChipDemo.routeName),
new IconButton(
onPressed: () => {
this.setState(() => { this._showShapeBorder = !this._showShapeBorder; });
},
icon: new Icon(Icons.vignette)
)
}
),
body: new ChipTheme(
data: this._showShapeBorder
? theme.chipTheme.copyWith(
shape: new BeveledRectangleBorder(
side: new BorderSide(width: 0.66f, style: BorderStyle.solid, color: Colors.grey),
borderRadius: BorderRadius.circular(10.0f)
))
: theme.chipTheme,
child: new ListView(children: tiles)
),
floatingActionButton: new FloatingActionButton(
onPressed: () => this.setState(this._reset),
child: new Icon(Icons.refresh)
)
);
}
}
}

3
Samples/UIWidgetsGallery/demo/material/chip_demo.cs.meta


fileFormatVersion: 2
guid: c65920c8c4b64c709b62586d0bde9579
timeCreated: 1555411023

42
Samples/UIWidgetsGallery/demo/material/modal_bottom_sheet_demo.cs


using System.Collections.Generic;
using Unity.UIWidgets.material;
using Unity.UIWidgets.painting;
using Unity.UIWidgets.ui;
using Unity.UIWidgets.widgets;
namespace UIWidgetsGallery.gallery {
public class ModalBottomSheetDemo : StatelessWidget {
public const string routeName = "/material/modal-bottom-sheet";
public override Widget build(BuildContext context) {
return new Scaffold(
appBar: new AppBar(
title: new Text("Modal bottom sheet"),
actions: new List<Widget> {new MaterialDemoDocumentationButton(routeName)}
),
body: new Center(
child: new RaisedButton(
child: new Text("SHOW BOTTOM SHEET"),
onPressed: () => {
BottomSheetUtils.showModalBottomSheet<object>(context: context,
builder: (BuildContext _context) => {
return new Container(
child: new Padding(
padding: EdgeInsets.all(32.0f),
child: new Text("This is the modal bottom sheet. Tap anywhere to dismiss.",
textAlign: TextAlign.center,
style: new TextStyle(
color: Theme.of(_context).accentColor,
fontSize: 24.0f
)
)
)
);
});
}
)
)
);
}
}
}

3
Samples/UIWidgetsGallery/demo/material/modal_bottom_sheet_demo.cs.meta


fileFormatVersion: 2
guid: 3c47b9e1a46e47858145acbe84590d05
timeCreated: 1555059325

102
Samples/UIWidgetsGallery/demo/material/persistent_bottom_sheet_demo.cs


using System.Collections.Generic;
using Unity.UIWidgets.material;
using Unity.UIWidgets.painting;
using Unity.UIWidgets.ui;
using Unity.UIWidgets.widgets;
using DialogUtils = Unity.UIWidgets.material.DialogUtils;
namespace UIWidgetsGallery.gallery {
public class PersistentBottomSheetDemo : StatefulWidget {
public const string routeName = "/material/persistent-bottom-sheet";
public override State createState() {
return new _PersistentBottomSheetDemoState();
}
}
class _PersistentBottomSheetDemoState : State<PersistentBottomSheetDemo> {
GlobalKey<ScaffoldState> _scaffoldKey = GlobalKey<ScaffoldState>.key();
VoidCallback _showBottomSheetCallback;
public override void initState() {
base.initState();
this._showBottomSheetCallback = this._showBottomSheet;
}
void _showBottomSheet() {
this.setState(() => {
// disable the button
this._showBottomSheetCallback = null;
});
this._scaffoldKey.currentState.showBottomSheet((BuildContext context) => {
ThemeData themeData = Theme.of(this.context);
return new Container(
decoration: new BoxDecoration(
border: new Border(top: new BorderSide(color: themeData.disabledColor))
),
child: new Padding(
padding: EdgeInsets.all(32.0f),
child: new Text("This is a Material persistent bottom sheet. Drag downwards to dismiss it.",
textAlign: TextAlign.center,
style: new TextStyle(
color: themeData.accentColor,
fontSize: 24.0f
)
)
)
);
})
.closed.Then((value) => {
if (this.mounted) {
this.setState(() => {
// re-enable the button
this._showBottomSheetCallback = this._showBottomSheet;
});
}
});
}
void _showMessage() {
DialogUtils.showDialog(
context: this.context,
builder: (BuildContext context) => {
return new AlertDialog(
content: new Text("You tapped the floating action button."),
actions: new List<Widget> {
new FlatButton(
onPressed: () => { Navigator.pop(context); },
child: new Text("OK")
)
}
);
}
);
}
public override Widget build(BuildContext context) {
return new Scaffold(
key: this._scaffoldKey,
appBar: new AppBar(
title: new Text("Persistent bottom sheet"),
actions: new List<Widget> {
new MaterialDemoDocumentationButton(PersistentBottomSheetDemo.routeName)
}
),
floatingActionButton: new FloatingActionButton(
onPressed: this._showMessage,
backgroundColor: Colors.redAccent,
child: new Icon(
Icons.add
)
),
body: new Center(
child: new RaisedButton(
onPressed: this._showBottomSheetCallback,
child: new Text("SHOW BOTTOM SHEET")
)
)
);
}
}
}

3
Samples/UIWidgetsGallery/demo/material/persistent_bottom_sheet_demo.cs.meta


fileFormatVersion: 2
guid: afb410d95c524a18b8761713f1335427
timeCreated: 1555059936

184
Samples/UIWidgetsGallery/demo/material/tabs_fab_demo.cs


using System.Collections.Generic;
using System.Linq;
using Unity.UIWidgets.foundation;
using Unity.UIWidgets.material;
using Unity.UIWidgets.painting;
using Unity.UIWidgets.ui;
using Unity.UIWidgets.widgets;
namespace UIWidgetsGallery.gallery {
class TabsFabDemoUtils {
public const string _explanatoryText =
"When the Scaffold's floating action button changes, the new button fades and " +
"turns into view. In this demo, changing tabs can cause the app to be rebuilt " +
"with a FloatingActionButton that the Scaffold distinguishes from the others " +
"by its key.";
public static readonly List<_Page> _allPages = new List<_Page> {
new _Page(label: "Blue", colors: Colors.indigo, icon: Icons.add),
new _Page(label: "Eco", colors: Colors.green, icon: Icons.create),
new _Page(label: "No"),
new _Page(label: "Teal", colors: Colors.teal, icon: Icons.add),
new _Page(label: "Red", colors: Colors.red, icon: Icons.create)
};
}
class _Page {
public _Page(
string label,
MaterialColor colors = null,
IconData icon = null
) {
this.label = label;
this.colors = colors;
this.icon = icon;
}
public readonly string label;
public readonly MaterialColor colors;
public readonly IconData icon;
public Color labelColor {
get { return this.colors != null ? this.colors.shade300 : Colors.grey.shade300; }
}
public bool fabDefined {
get { return this.colors != null && this.icon != null; }
}
public Color fabColor {
get { return this.colors.shade400; }
}
public Icon fabIcon {
get { return new Icon(this.icon); }
}
public Key fabKey {
get { return new ValueKey<Color>(this.fabColor); }
}
}
public class TabsFabDemo : StatefulWidget {
public const string routeName = "/material/tabs-fab";
public override State createState() {
return new _TabsFabDemoState();
}
}
class _TabsFabDemoState : SingleTickerProviderStateMixin<TabsFabDemo> {
GlobalKey<ScaffoldState> _scaffoldKey = GlobalKey<ScaffoldState>.key();
TabController _controller;
_Page _selectedPage;
bool _extendedButtons = false;
public override void initState() {
base.initState();
this._controller = new TabController(vsync: this, length: TabsFabDemoUtils._allPages.Count);
this._controller.addListener(this._handleTabSelection);
this._selectedPage = TabsFabDemoUtils._allPages[0];
}
public override void dispose() {
this._controller.dispose();
base.dispose();
}
void _handleTabSelection() {
this.setState(() => { this._selectedPage = TabsFabDemoUtils._allPages[this._controller.index]; });
}
void _showExplanatoryText() {
this._scaffoldKey.currentState.showBottomSheet((BuildContext context) => {
return new Container(
decoration: new BoxDecoration(
border: new Border(top: new BorderSide(color: Theme.of(this.context).dividerColor))
),
child: new Padding(
padding: EdgeInsets.all(32.0f),
child: new Text(TabsFabDemoUtils._explanatoryText,
style: Theme.of(this.context).textTheme.subhead)
)
);
});
}
Widget buildTabView(_Page page) {
return new Builder(
builder: (BuildContext context) => {
return new Container(
key: new ValueKey<string>(page.label),
padding: EdgeInsets.fromLTRB(48.0f, 48.0f, 48.0f, 96.0f),
child: new Card(
child: new Center(
child: new Text(page.label,
style: new TextStyle(
color: page.labelColor,
fontSize: 32.0f
),
textAlign: TextAlign.center
)
)
)
);
}
);
}
Widget buildFloatingActionButton(_Page page) {
if (!page.fabDefined) {
return null;
}
if (this._extendedButtons) {
return FloatingActionButton.extended(
key: new ValueKey<Key>(page.fabKey),
tooltip: "Show explanation",
backgroundColor: page.fabColor,
icon: page.fabIcon,
label: new Text(page.label.ToUpper()),
onPressed: this._showExplanatoryText
);
}
return new FloatingActionButton(
key: page.fabKey,
tooltip: "Show explanation",
backgroundColor: page.fabColor,
child: page.fabIcon,
onPressed: this._showExplanatoryText
);
}
public override Widget build(BuildContext context) {
return new Scaffold(
key: this._scaffoldKey,
appBar: new AppBar(
title: new Text("FAB per tab"),
bottom: new TabBar(
controller: this._controller,
tabs: TabsFabDemoUtils._allPages
.Select<_Page, Widget>((_Page page) => new Tab(text: page.label.ToUpper())).ToList()
),
actions: new List<Widget> {
new MaterialDemoDocumentationButton(TabsFabDemo.routeName),
new IconButton(
icon: new Icon(Icons.sentiment_very_satisfied),
onPressed: () => {
this.setState(() => { this._extendedButtons = !this._extendedButtons; });
}
)
}
),
floatingActionButton: this.buildFloatingActionButton(this._selectedPage),
body: new TabBarView(
controller: this._controller,
children: TabsFabDemoUtils._allPages.Select<_Page, Widget>(this.buildTabView).ToList()
)
);
}
}
}

3
Samples/UIWidgetsGallery/demo/material/tabs_fab_demo.cs.meta


fileFormatVersion: 2
guid: 7c2dcb794cc84a458f028f3751cf08a7
timeCreated: 1555060923

3
Samples/UIWidgetsGallery/demo/animation/home.cs.meta


fileFormatVersion: 2
guid: 628b4648bdda4c8d8c8fc6778c874067
timeCreated: 1554970915

615
Samples/UIWidgetsGallery/demo/animation/home.cs


using System;
using System.Collections.Generic;
using System.Linq;
using Unity.UIWidgets.animation;
using Unity.UIWidgets.foundation;
using Unity.UIWidgets.gestures;
using Unity.UIWidgets.material;
using Unity.UIWidgets.painting;
using Unity.UIWidgets.physics;
using Unity.UIWidgets.rendering;
using Unity.UIWidgets.ui;
using Unity.UIWidgets.widgets;
using UnityEngine;
using Color = Unity.UIWidgets.ui.Color;
using Rect = Unity.UIWidgets.ui.Rect;
namespace UIWidgetsGallery.gallery {
class AnimationHomeUtils {
public static readonly Color _kAppBackgroundColor = new Color(0xFF353662);
public static readonly TimeSpan _kScrollDuration = new TimeSpan(0, 0, 0, 0, 400);
public static readonly Curve _kScrollCurve = Curves.fastOutSlowIn;
public const float _kAppBarMinHeight = 90.0f;
public const float _kAppBarMidHeight = 256.0f;
}
class _RenderStatusBarPaddingSliver : RenderSliver {
public _RenderStatusBarPaddingSliver(
float? maxHeight = null,
float? scrollFactor = null
) {
D.assert(maxHeight >= 0.0f);
D.assert(scrollFactor >= 1.0f);
this._maxHeight = maxHeight;
this._scrollFactor = scrollFactor;
}
public float? maxHeight {
get { return this._maxHeight; }
set {
D.assert(this.maxHeight >= 0.0f);
if (this._maxHeight == value) {
return;
}
this._maxHeight = value;
this.markNeedsLayout();
}
}
float? _maxHeight;
public float? scrollFactor {
get { return this._scrollFactor; }
set {
D.assert(this.scrollFactor >= 1.0f);
if (this._scrollFactor == value) {
return;
}
this._scrollFactor = value;
this.markNeedsLayout();
}
}
float? _scrollFactor;
protected override void performLayout() {
float? height =
(this.maxHeight - this.constraints.scrollOffset / this.scrollFactor)?.clamp(0.0f,
this.maxHeight ?? 0.0f);
this.geometry = new SliverGeometry(
paintExtent: Mathf.Min(height ?? 0.0f, this.constraints.remainingPaintExtent),
scrollExtent: this.maxHeight ?? 0.0f,
maxPaintExtent: this.maxHeight ?? 0.0f
);
}
}
class _StatusBarPaddingSliver : SingleChildRenderObjectWidget {
public _StatusBarPaddingSliver(
Key key = null,
float? maxHeight = null,
float scrollFactor = 5.0f
) : base(key: key) {
D.assert(maxHeight != null && maxHeight >= 0.0f);
D.assert(scrollFactor != null && scrollFactor >= 1.0f);
this.maxHeight = maxHeight;
this.scrollFactor = scrollFactor;
}
public readonly float? maxHeight;
public readonly float scrollFactor;
public override RenderObject createRenderObject(BuildContext context) {
return new _RenderStatusBarPaddingSliver(
maxHeight: this.maxHeight,
scrollFactor: this.scrollFactor
);
}
public override void updateRenderObject(BuildContext context, RenderObject _renderObject) {
_RenderStatusBarPaddingSliver renderObject = _renderObject as _RenderStatusBarPaddingSliver;
renderObject.maxHeight = this.maxHeight;
renderObject.scrollFactor = this.scrollFactor;
}
public override void debugFillProperties(DiagnosticPropertiesBuilder description) {
base.debugFillProperties(description);
description.add(new FloatProperty("maxHeight", this.maxHeight));
description.add(new FloatProperty("scrollFactor", this.scrollFactor));
}
}
class _SliverAppBarDelegate : SliverPersistentHeaderDelegate {
public _SliverAppBarDelegate(
float minHeight,
float maxHeight,
Widget child
) {
this.minHeight = minHeight;
this.maxHeight = maxHeight;
this.child = child;
}
public readonly float minHeight;
public readonly float maxHeight;
public readonly Widget child;
public override float? minExtent {
get { return this.minHeight; }
}
public override float? maxExtent {
get { return Mathf.Max(this.maxHeight, this.minHeight); }
}
public override Widget build(BuildContext context, float shrinkOffset, bool overlapsContent) {
return SizedBox.expand(child: this.child);
}
public override bool shouldRebuild(SliverPersistentHeaderDelegate _oldDelegate) {
_SliverAppBarDelegate oldDelegate = _oldDelegate as _SliverAppBarDelegate;
return this.maxHeight != oldDelegate.maxHeight
|| this.minHeight != oldDelegate.minHeight
|| this.child != oldDelegate.child;
}
public override string ToString() {
return "_SliverAppBarDelegate";
}
}
class _AllSectionsLayout : MultiChildLayoutDelegate {
public _AllSectionsLayout(
Alignment translation,
float tColumnToRow,
float tCollapsed,
int cardCount,
float selectedIndex
) {
this.translation = translation;
this.tColumnToRow = tColumnToRow;
this.tCollapsed = tCollapsed;
this.cardCount = cardCount;
this.selectedIndex = selectedIndex;
}
public readonly Alignment translation;
public readonly float tColumnToRow;
public readonly float tCollapsed;
public readonly int cardCount;
public readonly float selectedIndex;
Rect _interpolateRect(Rect begin, Rect end) {
return Rect.lerp(begin, end, this.tColumnToRow);
}
Offset _interpolatePoint(Offset begin, Offset end) {
return Offset.lerp(begin, end, this.tColumnToRow);
}
public override void performLayout(Size size) {
float columnCardX = size.width / 5.0f;
float columnCardWidth = size.width - columnCardX;
float columnCardHeight = size.height / this.cardCount;
float rowCardWidth = size.width;
Offset offset = this.translation.alongSize(size);
float columnCardY = 0.0f;
float rowCardX = -(this.selectedIndex * rowCardWidth);
float columnTitleX = size.width / 10.0f;
float rowTitleWidth = size.width * ((1 + this.tCollapsed) / 2.25f);
float rowTitleX = (size.width - rowTitleWidth) / 2.0f - this.selectedIndex * rowTitleWidth;
const float paddedSectionIndicatorWidth = AnimationWidgetsUtils.kSectionIndicatorWidth + 8.0f;
float rowIndicatorWidth = paddedSectionIndicatorWidth +
(1.0f - this.tCollapsed) * (rowTitleWidth - paddedSectionIndicatorWidth);
float rowIndicatorX = (size.width - rowIndicatorWidth) / 2.0f - this.selectedIndex * rowIndicatorWidth;
for (int index = 0; index < this.cardCount; index++) {
Rect columnCardRect = Rect.fromLTWH(columnCardX, columnCardY, columnCardWidth, columnCardHeight);
Rect rowCardRect = Rect.fromLTWH(rowCardX, 0.0f, rowCardWidth, size.height);
Rect cardRect = this._interpolateRect(columnCardRect, rowCardRect).shift(offset);
string cardId = $"card{index}";
if (this.hasChild(cardId)) {
this.layoutChild(cardId, BoxConstraints.tight(cardRect.size));
this.positionChild(cardId, cardRect.topLeft);
}
Size titleSize = this.layoutChild($"title{index}", BoxConstraints.loose(cardRect.size));
float columnTitleY = columnCardRect.centerLeft.dy - titleSize.height / 2.0f;
float rowTitleY = rowCardRect.centerLeft.dy - titleSize.height / 2.0f;
float centeredRowTitleX = rowTitleX + (rowTitleWidth - titleSize.width) / 2.0f;
Offset columnTitleOrigin = new Offset(columnTitleX, columnTitleY);
Offset rowTitleOrigin = new Offset(centeredRowTitleX, rowTitleY);
Offset titleOrigin = this._interpolatePoint(columnTitleOrigin, rowTitleOrigin);
this.positionChild($"title{index}", titleOrigin + offset);
Size indicatorSize = this.layoutChild($"indicator{index}", BoxConstraints.loose(cardRect.size));
float columnIndicatorX = cardRect.centerRight.dx - indicatorSize.width - 16.0f;
float columnIndicatorY = cardRect.bottomRight.dy - indicatorSize.height - 16.0f;
Offset columnIndicatorOrigin = new Offset(columnIndicatorX, columnIndicatorY);
Rect titleRect = Rect.fromPoints(titleOrigin, titleSize.bottomRight(titleOrigin));
float centeredRowIndicatorX = rowIndicatorX + (rowIndicatorWidth - indicatorSize.width) / 2.0f;
float rowIndicatorY = titleRect.bottomCenter.dy + 16.0f;
Offset rowIndicatorOrigin = new Offset(centeredRowIndicatorX, rowIndicatorY);
Offset indicatorOrigin = this._interpolatePoint(columnIndicatorOrigin, rowIndicatorOrigin);
this.positionChild($"indicator{index}", indicatorOrigin + offset);
columnCardY += columnCardHeight;
rowCardX += rowCardWidth;
rowTitleX += rowTitleWidth;
rowIndicatorX += rowIndicatorWidth;
}
}
public override bool shouldRelayout(MultiChildLayoutDelegate _oldDelegate) {
_AllSectionsLayout oldDelegate = _oldDelegate as _AllSectionsLayout;
return this.tColumnToRow != oldDelegate.tColumnToRow
|| this.cardCount != oldDelegate.cardCount
|| this.selectedIndex != oldDelegate.selectedIndex;
}
}
class _AllSectionsView : AnimatedWidget {
public _AllSectionsView(
Key key = null,
int? sectionIndex = null,
List<Section> sections = null,
ValueNotifier<float> selectedIndex = null,
float? minHeight = null,
float? midHeight = null,
float? maxHeight = null,
List<Widget> sectionCards = null
) : base(key: key, listenable: selectedIndex) {
sectionCards = sectionCards ?? new List<Widget>();
D.assert(sections != null);
D.assert(sectionCards.Count == sections.Count);
D.assert(sectionIndex >= 0 && sectionIndex < sections.Count);
D.assert(selectedIndex != null);
D.assert(selectedIndex.value >= 0.0f && (float) selectedIndex.value < sections.Count);
this.sectionIndex = sectionIndex;
this.sections = sections;
this.selectedIndex = selectedIndex;
this.minHeight = minHeight;
this.midHeight = midHeight;
this.maxHeight = maxHeight;
this.sectionCards = sectionCards;
}
public readonly int? sectionIndex;
public readonly List<Section> sections;
public readonly ValueNotifier<float> selectedIndex;
public readonly float? minHeight;
public readonly float? midHeight;
public readonly float? maxHeight;
public readonly List<Widget> sectionCards;
float _selectedIndexDelta(int index) {
return (index - this.selectedIndex.value).abs().clamp(0.0f, 1.0f);
}
Widget _build(BuildContext context, BoxConstraints constraints) {
Size size = constraints.biggest;
float? tColumnToRow =
1.0f - ((size.height - this.midHeight) /
(this.maxHeight - this.midHeight))?.clamp(0.0f, 1.0f);
float? tCollapsed =
1.0f - ((size.height - this.minHeight) /
(this.midHeight - this.minHeight))?.clamp(0.0f, 1.0f);
float _indicatorOpacity(int index) {
return 1.0f - this._selectedIndexDelta(index) * 0.5f;
}
float? _titleOpacity(int index) {
return 1.0f - this._selectedIndexDelta(index) * tColumnToRow * 0.5f;
}
float? _titleScale(int index) {
return 1.0f - this._selectedIndexDelta(index) * tColumnToRow * 0.15f;
}
List<Widget> children = new List<Widget>(this.sectionCards);
for (int index = 0; index < this.sections.Count; index++) {
Section section = this.sections[index];
children.Add(new LayoutId(
id: $"title{index}",
child: new SectionTitle(
section: section,
scale: _titleScale(index),
opacity: _titleOpacity(index)
)
));
}
for (int index = 0; index < this.sections.Count; index++) {
children.Add(new LayoutId(
id: $"indicator{index}",
child: new SectionIndicator(
opacity: _indicatorOpacity(index)
)
));
}
return new CustomMultiChildLayout(
layoutDelegate: new _AllSectionsLayout(
translation: new Alignment((this.selectedIndex.value - this.sectionIndex) * 2.0f - 1.0f ?? 0.0f,
-1.0f),
tColumnToRow: tColumnToRow ?? 0.0f,
tCollapsed: tCollapsed ?? 0.0f,
cardCount: this.sections.Count,
selectedIndex: this.selectedIndex.value
),
children: children
);
}
protected override Widget build(BuildContext context) {
return new LayoutBuilder(builder: this._build);
}
}
class _SnappingScrollPhysics : ClampingScrollPhysics {
public _SnappingScrollPhysics(
ScrollPhysics parent = null,
float? midScrollOffset = null
) : base(parent: parent) {
D.assert(midScrollOffset != null);
}
public readonly float midScrollOffset;
public override ScrollPhysics applyTo(ScrollPhysics ancestor) {
return new _SnappingScrollPhysics(parent: this.buildParent(ancestor),
midScrollOffset: this.midScrollOffset);
}
Simulation _toMidScrollOffsetSimulation(float offset, float dragVelocity) {
float velocity = Mathf.Max(dragVelocity, this.minFlingVelocity);
return new ScrollSpringSimulation(this.spring, offset, this.midScrollOffset, velocity,
tolerance: this.tolerance);
}
Simulation _toZeroScrollOffsetSimulation(float offset, float dragVelocity) {
float velocity = Mathf.Max(dragVelocity, this.minFlingVelocity);
return new ScrollSpringSimulation(this.spring, offset, 0.0f, velocity, tolerance: this.tolerance);
}
public override Simulation createBallisticSimulation(ScrollMetrics position, float dragVelocity) {
Simulation simulation = base.createBallisticSimulation(position, dragVelocity);
float offset = position.pixels;
if (simulation != null) {
float simulationEnd = simulation.x(float.PositiveInfinity);
if (simulationEnd >= this.midScrollOffset) {
return simulation;
}
if (dragVelocity > 0.0f) {
return this._toMidScrollOffsetSimulation(offset, dragVelocity);
}
if (dragVelocity < 0.0f) {
return this._toZeroScrollOffsetSimulation(offset, dragVelocity);
}
}
else {
float snapThreshold = this.midScrollOffset / 2.0f;
if (offset >= snapThreshold && offset < this.midScrollOffset) {
return this._toMidScrollOffsetSimulation(offset, dragVelocity);
}
if (offset > 0.0f && offset < snapThreshold) {
return this._toZeroScrollOffsetSimulation(offset, dragVelocity);
}
}
return simulation;
}
}
public class AnimationDemoHome : StatefulWidget {
public AnimationDemoHome(Key key = null) : base(key: key) {
}
public const string routeName = "/animation";
public override State createState() {
return new _AnimationDemoHomeState();
}
}
class _AnimationDemoHomeState : State<AnimationDemoHome> {
ScrollController _scrollController = new ScrollController();
PageController _headingPageController = new PageController();
PageController _detailsPageController = new PageController();
ScrollPhysics _headingScrollPhysics = new NeverScrollableScrollPhysics();
ValueNotifier<float> selectedIndex = new ValueNotifier<float>(0.0f);
public override Widget build(BuildContext context) {
return new Scaffold(
backgroundColor: AnimationHomeUtils._kAppBackgroundColor,
body: new Builder(
builder: this._buildBody
)
);
}
void _handleBackButton(float midScrollOffset) {
if (this._scrollController.offset >= midScrollOffset) {
this._scrollController.animateTo(0.0f, curve: AnimationHomeUtils._kScrollCurve,
duration: AnimationHomeUtils._kScrollDuration);
}
else {
Navigator.maybePop(this.context);
}
}
bool _handleScrollNotification(ScrollNotification notification, float midScrollOffset) {
if (notification.depth == 0 && notification is ScrollUpdateNotification) {
ScrollPhysics physics = this._scrollController.position.pixels >= midScrollOffset
? (ScrollPhysics) new PageScrollPhysics()
: new NeverScrollableScrollPhysics();
if (physics != this._headingScrollPhysics) {
this.setState(() => { this._headingScrollPhysics = physics; });
}
}
return false;
}
void _maybeScroll(float midScrollOffset, int pageIndex, float xOffset) {
if (this._scrollController.offset < midScrollOffset) {
this._headingPageController.animateToPage(pageIndex, curve: AnimationHomeUtils._kScrollCurve,
duration: AnimationHomeUtils._kScrollDuration);
this._scrollController.animateTo(midScrollOffset, curve: AnimationHomeUtils._kScrollCurve,
duration: AnimationHomeUtils._kScrollDuration);
}
else {
float centerX = this._headingPageController.position.viewportDimension / 2.0f;
int newPageIndex = xOffset > centerX ? pageIndex + 1 : pageIndex - 1;
this._headingPageController.animateToPage(newPageIndex, curve: AnimationHomeUtils._kScrollCurve,
duration: AnimationHomeUtils._kScrollDuration);
}
}
bool _handlePageNotification(ScrollNotification notification, PageController leader, PageController follower) {
if (notification.depth == 0 && notification is ScrollUpdateNotification) {
this.selectedIndex.value = leader.page;
if (follower.page != leader.page) {
follower.position.jumpTo(leader.position.pixels); // ignore: deprecated_member_use
}
}
return false;
}
IEnumerable<Widget> _detailItemsFor(Section section) {
IEnumerable<Widget> detailItems = section.details.Select<SectionDetail, Widget>((SectionDetail detail) => {
return new SectionDetailView(detail: detail);
});
return ListTile.divideTiles(context: this.context, tiles: detailItems);
}
List<Widget> _allHeadingItems(float maxHeight, float midScrollOffset) {
List<Widget> sectionCards = new List<Widget> { };
for (int index = 0; index < AnimationSectionsUtils.allSections.Count; index++) {
sectionCards.Add(new LayoutId(
id: $"card{index}",
child: new GestureDetector(
behavior: HitTestBehavior.opaque,
child: new SectionCard(section: AnimationSectionsUtils.allSections[index]),
onTapUp: (TapUpDetails details) => {
float xOffset = details.globalPosition.dx;
this.setState(() => { this._maybeScroll(midScrollOffset, index, xOffset); });
}
)
));
}
List<Widget> headings = new List<Widget> { };
for (int index = 0; index < AnimationSectionsUtils.allSections.Count; index++) {
headings.Add(new Container(
color: AnimationHomeUtils._kAppBackgroundColor,
child: new ClipRect(
child: new _AllSectionsView(
sectionIndex: index,
sections: AnimationSectionsUtils.allSections,
selectedIndex: this.selectedIndex,
minHeight: AnimationHomeUtils._kAppBarMinHeight,
midHeight: AnimationHomeUtils._kAppBarMidHeight,
maxHeight: maxHeight,
sectionCards: sectionCards
)
)
)
);
}
return headings;
}
Widget _buildBody(BuildContext context) {
MediaQueryData mediaQueryData = MediaQuery.of(context);
float statusBarHeight = mediaQueryData.padding.top;
float screenHeight = mediaQueryData.size.height;
float appBarMaxHeight = screenHeight - statusBarHeight;
float appBarMidScrollOffset = statusBarHeight + appBarMaxHeight - AnimationHomeUtils._kAppBarMidHeight;
return SizedBox.expand(
child: new Stack(
children: new List<Widget> {
new NotificationListener<ScrollNotification>(
onNotification: (ScrollNotification notification) => {
return this._handleScrollNotification(notification, appBarMidScrollOffset);
},
child: new CustomScrollView(
controller: this._scrollController,
physics: new _SnappingScrollPhysics(midScrollOffset: appBarMidScrollOffset),
slivers: new List<Widget> {
new _StatusBarPaddingSliver(
maxHeight: statusBarHeight,
scrollFactor: 7.0f
),
new SliverPersistentHeader(
pinned: true,
del: new _SliverAppBarDelegate(
minHeight: AnimationHomeUtils._kAppBarMinHeight,
maxHeight: appBarMaxHeight,
child: new NotificationListener<ScrollNotification>(
onNotification: (ScrollNotification notification) => {
return this._handlePageNotification(notification,
this._headingPageController, this._detailsPageController);
},
child: new PageView(
physics: this._headingScrollPhysics,
controller: this._headingPageController,
children: this._allHeadingItems(appBarMaxHeight,
appBarMidScrollOffset)
)
)
)
),
new SliverToBoxAdapter(
child: new SizedBox(
height: 610.0f,
child: new NotificationListener<ScrollNotification>(
onNotification: (ScrollNotification notification) => {
return this._handlePageNotification(notification,
this._detailsPageController, this._headingPageController);
},
child: new PageView(
controller: this._detailsPageController,
children: AnimationSectionsUtils.allSections
.Select<Section, Widget>((Section section) => {
return new Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: this._detailItemsFor(section).ToList()
);
}).ToList()
)
)
)
)
}
)
),
new Positioned(
top: statusBarHeight,
left: 0.0f,
child: new IconTheme(
data: new IconThemeData(color: Colors.white),
child: new SafeArea(
top: false,
bottom: false,
child: new IconButton(
icon: new BackButtonIcon(),
tooltip: "Back",
onPressed: () => { this._handleBackButton(appBarMidScrollOffset); }
)
)
)
)
}
)
);
}
}
}

201
Samples/UIWidgetsGallery/demo/animation/sections.cs


using System.Collections.Generic;
using Unity.UIWidgets.material;
using Unity.UIWidgets.ui;
namespace UIWidgetsGallery.gallery {
public class AnimationSectionsUtils {
public static readonly Color _mariner = new Color(0xFF3B5F8F);
public static readonly Color _mediumPurple = new Color(0xFF8266D4);
public static readonly Color _tomato = new Color(0xFFF95B57);
public static readonly Color _mySin = new Color(0xFFF3A646);
const string _kGalleryAssetsPackage = "flutter_gallery_assets";
public static readonly SectionDetail _eyeglassesDetail = new SectionDetail(
imageAsset: "products/sunnies",
imageAssetPackage: _kGalleryAssetsPackage,
title: "Flutter enables interactive animation",
subtitle: "3K views - 5 days"
);
public static readonly SectionDetail _eyeglassesImageDetail = new SectionDetail(
imageAsset: "products/sunnies",
imageAssetPackage: _kGalleryAssetsPackage
);
public static readonly SectionDetail _seatingDetail = new SectionDetail(
imageAsset: "products/table",
imageAssetPackage: _kGalleryAssetsPackage,
title: "Flutter enables interactive animation",
subtitle: "3K views - 5 days"
);
public static readonly SectionDetail _seatingImageDetail = new SectionDetail(
imageAsset: "products/table",
imageAssetPackage: _kGalleryAssetsPackage
);
public static readonly SectionDetail _decorationDetail = new SectionDetail(
imageAsset: "products/earrings",
imageAssetPackage: _kGalleryAssetsPackage,
title: "Flutter enables interactive animation",
subtitle: "3K views - 5 days"
);
public static readonly SectionDetail _decorationImageDetail = new SectionDetail(
imageAsset: "products/earrings",
imageAssetPackage: _kGalleryAssetsPackage
);
public static readonly SectionDetail _protectionDetail = new SectionDetail(
imageAsset: "products/hat",
imageAssetPackage: _kGalleryAssetsPackage,
title: "Flutter enables interactive animation",
subtitle: "3K views - 5 days"
);
public static readonly SectionDetail _protectionImageDetail = new SectionDetail(
imageAsset: "products/hat",
imageAssetPackage: _kGalleryAssetsPackage
);
public static List<Section> allSections = new List<Section> {
new Section(
title: "SUNGLASSES",
leftColor: _mediumPurple,
rightColor: _mariner,
backgroundAsset: "products/sunnies",
backgroundAssetPackage: _kGalleryAssetsPackage,
details: new List<SectionDetail> {
_eyeglassesDetail,
_eyeglassesImageDetail,
_eyeglassesDetail,
_eyeglassesDetail,
_eyeglassesDetail,
_eyeglassesDetail
}
),
new Section(
title: "FURNITURE",
leftColor: _tomato,
rightColor: _mediumPurple,
backgroundAsset: "products/table",
backgroundAssetPackage: _kGalleryAssetsPackage,
details: new List<SectionDetail> {
_seatingDetail,
_seatingImageDetail,
_seatingDetail,
_seatingDetail,
_seatingDetail,
_seatingDetail
}
),
new Section(
title: "JEWELRY",
leftColor: _mySin,
rightColor: _tomato,
backgroundAsset: "products/earrings",
backgroundAssetPackage: _kGalleryAssetsPackage,
details: new List<SectionDetail> {
_decorationDetail,
_decorationImageDetail,
_decorationDetail,
_decorationDetail,
_decorationDetail,
_decorationDetail
}
),
new Section(
title: "HEADWEAR",
leftColor: Colors.white,
rightColor: _tomato,
backgroundAsset: "products/hat",
backgroundAssetPackage: _kGalleryAssetsPackage,
details: new List<SectionDetail> {
_protectionDetail,
_protectionImageDetail,
_protectionDetail,
_protectionDetail,
_protectionDetail,
_protectionDetail
}
)
};
}
public class SectionDetail {
public SectionDetail(
string title = null,
string subtitle = null,
string imageAsset = null,
string imageAssetPackage = null
) {
this.title = title;
this.subtitle = subtitle;
this.imageAsset = imageAsset;
this.imageAssetPackage = imageAssetPackage;
}
public readonly string title;
public readonly string subtitle;
public readonly string imageAsset;
public readonly string imageAssetPackage;
}
public class Section {
public Section(
string title,
string backgroundAsset,
string backgroundAssetPackage,
Color leftColor,
Color rightColor,
List<SectionDetail> details
) {
this.title = title;
this.backgroundAsset = backgroundAsset;
this.backgroundAssetPackage = backgroundAssetPackage;
this.leftColor = leftColor;
this.rightColor = rightColor;
this.details = details;
}
public readonly string title;
public readonly string backgroundAsset;
public readonly string backgroundAssetPackage;
public readonly Color leftColor;
public readonly Color rightColor;
public readonly List<SectionDetail> details;
public static bool operator ==(Section left, Section right) {
return Equals(left, right);
}
public static bool operator !=(Section left, Section right) {
return !Equals(left, right);
}
public bool Equals(Section other) {
return this.title == other.title;
}
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((Section) obj);
}
public override int GetHashCode() {
return this.title.GetHashCode();
}
}
}

3
Samples/UIWidgetsGallery/demo/animation/sections.cs.meta


fileFormatVersion: 2
guid: 5180fb461b7448de8d4d084ff3f7c761
timeCreated: 1555049317

169
Samples/UIWidgetsGallery/demo/animation/widgets.cs


using System.Collections.Generic;
using Unity.UIWidgets.foundation;
using Unity.UIWidgets.material;
using Unity.UIWidgets.painting;
using Unity.UIWidgets.ui;
using Unity.UIWidgets.widgets;
using Image = Unity.UIWidgets.widgets.Image;
namespace UIWidgetsGallery.gallery {
class AnimationWidgetsUtils {
public const float kSectionIndicatorWidth = 32.0f;
}
public class SectionCard : StatelessWidget {
public SectionCard(
Key key = null,
Section section = null
) : base(key: key) {
D.assert(section != null);
this.section = section;
}
public readonly Section section;
public override Widget build(BuildContext context) {
return new DecoratedBox(
decoration: new BoxDecoration(
gradient: new LinearGradient(
begin: Alignment.centerLeft,
end: Alignment.centerRight,
colors: new List<Color> {
this.section.leftColor, this.section.rightColor
}
)
),
child: Image.asset(this.section.backgroundAsset,
color: Color.fromRGBO(255, 255, 255, 0.075f),
colorBlendMode: BlendMode.modulate,
fit: BoxFit.cover
)
);
}
}
public class SectionTitle : StatelessWidget {
public SectionTitle(
Key key = null,
Section section = null,
float? scale = null,
float? opacity = null
) : base(key: key) {
D.assert(section != null);
D.assert(scale != null);
D.assert(opacity != null && opacity >= 0.0f && opacity <= 1.0f);
this.section = section;
this.scale = scale;
this.opacity = opacity;
}
public readonly Section section;
public readonly float? scale;
public readonly float? opacity;
public static readonly TextStyle sectionTitleStyle = new TextStyle(
fontFamily: "Raleway",
inherit: false,
fontSize: 24.0f,
fontWeight: FontWeight.w500,
color: Colors.white,
textBaseline: TextBaseline.alphabetic
);
public static readonly TextStyle sectionTitleShadowStyle = sectionTitleStyle.copyWith(
color: new Color(0x19000000)
);
public override Widget build(BuildContext context) {
return new IgnorePointer(
child: new Opacity(
opacity: this.opacity ?? 1.0f,
child: new Transform(
transform: Matrix3.makeScale(this.scale ?? 1.0f),
alignment: Alignment.center,
child: new Stack(
children: new List<Widget> {
new Positioned(
top: 4.0f,
child: new Text(this.section.title, style: sectionTitleShadowStyle)
),
new Text(this.section.title, style: sectionTitleStyle)
}
)
)
)
);
}
}
public class SectionIndicator : StatelessWidget {
public SectionIndicator(Key key = null, float opacity = 1.0f) : base(key: key) {
this.opacity = opacity;
}
public readonly float opacity;
public override Widget build(BuildContext context) {
return new IgnorePointer(
child: new Container(
width: AnimationWidgetsUtils.kSectionIndicatorWidth,
height: 3.0f,
color: Colors.white.withOpacity(this.opacity)
)
);
}
}
public class SectionDetailView : StatelessWidget {
public SectionDetailView(
Key key = null,
SectionDetail detail = null
) : base(key: key) {
D.assert(detail != null && detail.imageAsset != null);
D.assert((detail.imageAsset ?? detail.title) != null);
this.detail = detail;
}
public readonly SectionDetail detail;
public override Widget build(BuildContext context) {
Widget image = new DecoratedBox(
decoration: new BoxDecoration(
borderRadius: BorderRadius.circular(6.0f),
image: new DecorationImage(
image: new AssetImage(
this.detail.imageAsset
),
fit: BoxFit.cover,
alignment: Alignment.center
)
)
);
Widget item;
if (this.detail.title == null && this.detail.subtitle == null) {
item = new Container(
height: 240.0f,
padding: EdgeInsets.all(16.0f),
child: new SafeArea(
top: false,
bottom: false,
child: image
)
);
}
else {
item = new ListTile(
title: new Text(this.detail.title),
subtitle: new Text(this.detail.subtitle),
leading: new SizedBox(width: 32.0f, height: 32.0f, child: image)
);
}
return new DecoratedBox(
decoration: new BoxDecoration(color: Colors.grey.shade200),
child: item
);
}
}
}

3
Samples/UIWidgetsGallery/demo/animation/widgets.cs.meta


fileFormatVersion: 2
guid: 4c84aedb64bf44338944d63be7c563ed
timeCreated: 1555049115
正在加载...
取消
保存