From 7ce3f39d3204560b140d2fbe294484c561c90d78 Mon Sep 17 00:00:00 2001 From: Xingwei Zhu Date: Thu, 25 Aug 2022 17:55:01 +0800 Subject: [PATCH] fix bug on cupertino/segmented_control and fade_in_image --- .../Runtime/animation/tween_sequence.cs | 12 - .../Runtime/cupertino/segmented_control.cs | 1082 +++++++++-------- .../Runtime/widgets/fade_in_image.cs | 130 +- com.unity.uiwidgets/Runtime/widgets/image.cs | 4 +- 4 files changed, 657 insertions(+), 571 deletions(-) diff --git a/com.unity.uiwidgets/Runtime/animation/tween_sequence.cs b/com.unity.uiwidgets/Runtime/animation/tween_sequence.cs index 89cbebf9..ac9635bc 100644 --- a/com.unity.uiwidgets/Runtime/animation/tween_sequence.cs +++ b/com.unity.uiwidgets/Runtime/animation/tween_sequence.cs @@ -1,17 +1,5 @@ using System.Collections.Generic; using Unity.UIWidgets.foundation; -using Unity.UIWidgets.animation; -using Unity.UIWidgets.rendering; -using Unity.UIWidgets.ui; -using Unity.UIWidgets.widgets; -using Unity.UIWidgets.scheduler; -using System; -using Unity.UIWidgets.gestures; -using Unity.UIWidgets.painting; -using UnityEngine; -using Color = Unity.UIWidgets.ui.Color; -using Rect = Unity.UIWidgets.ui.Rect; -using Transform = Unity.UIWidgets.widgets.Transform; namespace Unity.UIWidgets.animation { public class TweenSequence : Animatable { diff --git a/com.unity.uiwidgets/Runtime/cupertino/segmented_control.cs b/com.unity.uiwidgets/Runtime/cupertino/segmented_control.cs index 81bf5f7b..81786f8b 100644 --- a/com.unity.uiwidgets/Runtime/cupertino/segmented_control.cs +++ b/com.unity.uiwidgets/Runtime/cupertino/segmented_control.cs @@ -11,322 +11,361 @@ using Unity.UIWidgets.rendering; using UnityEngine; using Color = Unity.UIWidgets.ui.Color; using Rect = Unity.UIWidgets.ui.Rect; -using TextStyle = Unity.UIWidgets.painting.TextStyle; namespace Unity.UIWidgets.cupertino { - class CupertinoSegmentedControlsUtils { + static class CupertinoSegmentedControlsUtils { public static readonly EdgeInsetsGeometry _kHorizontalItemPadding = EdgeInsets.symmetric(horizontal: 16.0f); public const float _kMinSegmentedControlHeight = 28.0f; public static readonly TimeSpan _kFadeDuration = TimeSpan.FromMilliseconds(165); } - public class CupertinoSegmentedControl : StatefulWidget { + public class CupertinoSegmentedControl : StatefulWidget + { public CupertinoSegmentedControl( - Key key = null, - Dictionary children = null, - ValueChanged onValueChanged = null, - T groupValue = default, - Color unselectedColor = null, - Color selectedColor = null, - Color borderColor = null, - Color pressedColor = null, - EdgeInsetsGeometry padding = null - ) :base(key: key) - { D.assert(children != null); - D.assert(children.Count >= 2); - D.assert(onValueChanged != null); - D.assert( - groupValue == null || children.Keys.Any((T child) => child.Equals(groupValue)), () => - "The groupValue must be either null or one of the keys in the children map." - ); - this.children = children; - this.onValueChanged = onValueChanged; - this.groupValue = groupValue; - this.unselectedColor = unselectedColor; - this.selectedColor = selectedColor; - this.borderColor = borderColor; - this.pressedColor = pressedColor; - this.padding = padding; - - } - public readonly Dictionary children; - public readonly T groupValue; - public readonly ValueChanged onValueChanged; - public readonly Color unselectedColor; - public readonly Color selectedColor; - public readonly Color borderColor; - public readonly Color pressedColor; - public readonly EdgeInsetsGeometry padding; - - public override State createState() { - return new _SegmentedControlState(); - } - } - class _SegmentedControlState : TickerProviderStateMixin> { - T _pressedKey; - - public readonly List _selectionControllers = new List(); - public readonly List _childTweens = new List(); - - ColorTween _forwardBackgroundColorTween; - ColorTween _reverseBackgroundColorTween; - ColorTween _textColorTween; - - Color _selectedColor; - Color _unselectedColor; - Color _borderColor; - Color _pressedColor; - - AnimationController createAnimationController() { - var controller = new AnimationController( - duration: CupertinoSegmentedControlsUtils._kFadeDuration, - vsync: this + Key key = null, + Dictionary children = null, + ValueChanged onValueChanged = null, + T groupValue = default, + Color unselectedColor = null, + Color selectedColor = null, + Color borderColor = null, + Color pressedColor = null, + EdgeInsetsGeometry padding = null + ) : base(key: key) { + D.assert(children != null); + D.assert(children.Count >= 2); + D.assert(onValueChanged != null); + D.assert( + groupValue == null || children.Keys.Any((T child) => child.Equals(groupValue)), () => + "The groupValue must be either null or one of the keys in the children map." ); - controller.addListener(()=> { - setState(() =>{ - // State of background/text colors has changed - }); - }); - return controller; - } - - bool _updateColors() { - D.assert(mounted, ()=>"This should only be called after didUpdateDependencies"); - bool changed = false; - Color selectedColor = widget.selectedColor ?? CupertinoTheme.of(context).primaryColor; - if (_selectedColor != selectedColor) { - changed = true; - _selectedColor = selectedColor; - } - Color unselectedColor = widget.unselectedColor ?? CupertinoTheme.of(context).primaryContrastingColor; - if (_unselectedColor != unselectedColor) { - changed = true; - _unselectedColor = unselectedColor; - } - Color borderColor = widget.borderColor ?? CupertinoTheme.of(context).primaryColor; - if (_borderColor != borderColor) { - changed = true; - _borderColor = borderColor; - } - Color pressedColor = widget.pressedColor ?? CupertinoTheme.of(context).primaryColor.withOpacity(0.2f); - if (_pressedColor != pressedColor) { - changed = true; - _pressedColor = pressedColor; + this.children = children; + this.onValueChanged = onValueChanged; + this.groupValue = groupValue; + this.unselectedColor = unselectedColor; + this.selectedColor = selectedColor; + this.borderColor = borderColor; + this.pressedColor = pressedColor; + this.padding = padding; } - _forwardBackgroundColorTween = new ColorTween( - begin: _pressedColor, - end: _selectedColor - ); - _reverseBackgroundColorTween = new ColorTween( - begin: _unselectedColor, - end: _selectedColor - ); - _textColorTween = new ColorTween( - begin: _selectedColor, - end: _unselectedColor - ); - return changed; - } + public readonly Dictionary children; + public readonly T groupValue; + public readonly ValueChanged onValueChanged; + public readonly Color unselectedColor; + public readonly Color selectedColor; + public readonly Color borderColor; + public readonly Color pressedColor; + public readonly EdgeInsetsGeometry padding; - void _updateAnimationControllers() { - D.assert(mounted, ()=>"This should only be called after didUpdateDependencies"); - foreach ( AnimationController controller in _selectionControllers) { - controller.dispose(); + public override State createState() { + return new _SegmentedControlState(); } - _selectionControllers.Clear(); - _childTweens.Clear(); - foreach ( T key in widget.children.Keys) { - AnimationController animationController = createAnimationController(); - if (widget.groupValue.Equals(key)) { - _childTweens.Add(_reverseBackgroundColorTween); - animationController.setValue(1.0f); - } else { - _childTweens.Add(_forwardBackgroundColorTween); - } - _selectionControllers.Add(animationController); - } - } - - public override void didChangeDependencies() { - base.didChangeDependencies(); - - if (_updateColors()) { - _updateAnimationControllers(); - } - } - - public override void didUpdateWidget(StatefulWidget oldWidget) { - oldWidget = (CupertinoSegmentedControl) oldWidget; - base.didUpdateWidget(oldWidget); - - if (_updateColors() || ((CupertinoSegmentedControl) oldWidget).children.Count != widget.children.Count) { - _updateAnimationControllers(); - } - - if (!((CupertinoSegmentedControl)oldWidget).groupValue.Equals(widget.groupValue)) { - int index = 0; - foreach ( T key in widget.children.Keys) { - if (widget.groupValue.Equals(key)) { - _childTweens[index] = _forwardBackgroundColorTween; - _selectionControllers[index].forward(); - } else { - _childTweens[index] = _reverseBackgroundColorTween; - _selectionControllers[index].reverse(); - } - index += 1; - } - } - } - - public override void dispose() { - foreach( AnimationController animationController in _selectionControllers) { - animationController.dispose(); - } - base.dispose(); - } - - - void _onTapDown(T currentKey) { - if (_pressedKey == null && !currentKey.Equals(widget.groupValue)) { - setState(()=> { - _pressedKey = currentKey; - }); - } - } - - void _onTapCancel() { - setState(()=> { - _pressedKey = default(T); - }); - } - - void _onTap(T currentKey) { - if (!currentKey.Equals( _pressedKey)) - return; - if (!currentKey.Equals(widget.groupValue)) { - widget.onValueChanged(currentKey); - } - _pressedKey = default; - } - - Color getTextColor(int index, T currentKey) { - if (_selectionControllers[index].isAnimating) - return _textColorTween.evaluate(_selectionControllers[index]); - if (widget.groupValue.Equals(currentKey)) - return _unselectedColor; - return _selectedColor; - } - - Color getBackgroundColor(int index, T currentKey) { - if (_selectionControllers[index].isAnimating) - return _childTweens[index].evaluate(_selectionControllers[index]); - if (widget.groupValue.Equals(currentKey)) - return _selectedColor; - if (_pressedKey.Equals(currentKey)) - return _pressedColor; - return _unselectedColor; - } - - public override Widget build(BuildContext context) { - List _gestureChildren = new List(); - List _backgroundColors = new List(); - int index = 0; - int selectedIndex = 0; - int pressedIndex = 0; - foreach ( T currentKey in widget.children.Keys) { - selectedIndex = (widget.groupValue.Equals(currentKey)) ? index : selectedIndex; - pressedIndex = (_pressedKey.Equals(currentKey)) ? index : pressedIndex; - TextStyle textStyle = DefaultTextStyle.of(context).style.copyWith( - color: getTextColor(index, currentKey) - ); - IconThemeData iconTheme = new IconThemeData( - color: getTextColor(index, currentKey) - ); - - Widget child = new Center( - child: widget.children[currentKey] - ); - - child = new GestureDetector( - onTapDown: (TapDownDetails _event)=> { - _onTapDown(currentKey); - }, - onTapCancel: _onTapCancel, - onTap: ()=> { - _onTap(currentKey); - }, - child: new IconTheme( - data: iconTheme, - child: new DefaultTextStyle( - style: textStyle, - child: child - ) - ) - ); - - _backgroundColors.Add(getBackgroundColor(index, currentKey)); - _gestureChildren.Add(child); - index += 1; - } - - Widget box = new _SegmentedControlRenderWidget( - children: _gestureChildren, - selectedIndex: selectedIndex, - pressedIndex: pressedIndex, - backgroundColors: _backgroundColors, - borderColor: _borderColor - ); - - return new Padding( - padding: widget.padding ?? CupertinoSegmentedControlsUtils._kHorizontalItemPadding, - child: new UnconstrainedBox( - constrainedAxis: Axis.horizontal, - child: box - ) - ); - } } + + class _SegmentedControlState : TickerProviderStateMixin> { + + T __pressedKey = default; + bool __isNull = true; + + void setPressedKey(T newkey) { + __pressedKey = newkey; + __isNull = false; + } + + void setPressedKeyNull() { + __pressedKey = default; + __isNull = true; + } + + bool isPressedKeyNull() { + return __isNull; + } + + T getPressedKey() { + return __pressedKey; + } + + readonly List _selectionControllers = new List(); + readonly List _childTweens = new List(); + + ColorTween _forwardBackgroundColorTween; + ColorTween _reverseBackgroundColorTween; + ColorTween _textColorTween; + + Color _selectedColor; + Color _unselectedColor; + Color _borderColor; + Color _pressedColor; + + AnimationController createAnimationController() { + var controller = new AnimationController( + duration: CupertinoSegmentedControlsUtils._kFadeDuration, + vsync: this + ); + controller.addListener(() => { + setState(() => { + }); + }); + return controller; + } + + bool _updateColors() { + D.assert(mounted, () => "This should only be called after didUpdateDependencies"); + var changed = false; + var selectedColor = widget.selectedColor ?? CupertinoTheme.of(context).primaryColor; + if (_selectedColor != selectedColor) { + changed = true; + _selectedColor = selectedColor; + } + + var unselectedColor = widget.unselectedColor ?? CupertinoTheme.of(context).primaryContrastingColor; + if (_unselectedColor != unselectedColor) { + changed = true; + _unselectedColor = unselectedColor; + } + + var borderColor = widget.borderColor ?? CupertinoTheme.of(context).primaryColor; + if (_borderColor != borderColor) { + changed = true; + _borderColor = borderColor; + } + + var pressedColor = widget.pressedColor ?? CupertinoTheme.of(context).primaryColor.withOpacity(0.2f); + if (_pressedColor != pressedColor) { + changed = true; + _pressedColor = pressedColor; + } + + _forwardBackgroundColorTween = new ColorTween( + begin: _pressedColor, + end: _selectedColor + ); + _reverseBackgroundColorTween = new ColorTween( + begin: _unselectedColor, + end: _selectedColor + ); + + _textColorTween = new ColorTween( + begin: _selectedColor, + end: _unselectedColor + ); + + return changed; + } + + void _updateAnimationControllers() { + D.assert(mounted, () => "This should only be called after didUpdateDependencies"); + foreach (var controller in _selectionControllers) { + controller.dispose(); + } + + _selectionControllers.Clear(); + _childTweens.Clear(); + foreach (var key in widget.children.Keys) { + var animationController = createAnimationController(); + if (widget.groupValue.Equals(key)) { + _childTweens.Add(_reverseBackgroundColorTween); + animationController.setValue(1.0f); + } + else { + _childTweens.Add(_forwardBackgroundColorTween); + } + + _selectionControllers.Add(animationController); + } + } + + public override void didChangeDependencies() { + base.didChangeDependencies(); + + if (_updateColors()) { + _updateAnimationControllers(); + } + } + + public override void didUpdateWidget(StatefulWidget oldWidget) { + var _oldWidget = oldWidget as CupertinoSegmentedControl; + base.didUpdateWidget(oldWidget); + + if (_updateColors() || _oldWidget.children.Count != widget.children.Count) { + _updateAnimationControllers(); + } + + if (!_oldWidget.groupValue.Equals(widget.groupValue)) { + var index = 0; + foreach (var key in widget.children.Keys) { + if (widget.groupValue.Equals(key)) { + _childTweens[index] = _forwardBackgroundColorTween; + _selectionControllers[index].forward(); + } + else { + _childTweens[index] = _reverseBackgroundColorTween; + _selectionControllers[index].reverse(); + } + + index += 1; + } + } + } + + public override void dispose() { + foreach (var animationController in _selectionControllers) { + animationController.dispose(); + } + + base.dispose(); + } + + + void _onTapDown(T currentKey) { + if (isPressedKeyNull() && !currentKey.Equals(widget.groupValue)) { + setState(() => { + setPressedKey(currentKey); + }); + } + } + + void _onTapCancel() { + setState(setPressedKeyNull); + } + + bool isPressKeyEquals(T currentKey) { + return isPressedKeyNull() && currentKey == null || + !isPressedKeyNull() && currentKey.Equals(getPressedKey()); + } + + void _onTap(T currentKey) { + if (!isPressKeyEquals(currentKey)) + return; + + if (!currentKey.Equals(widget.groupValue)) { + widget.onValueChanged(currentKey); + } + + setPressedKeyNull(); + } + + Color getTextColor(int index, T currentKey) { + if (_selectionControllers[index].isAnimating) + return _textColorTween.evaluate(_selectionControllers[index]); + if (widget.groupValue.Equals(currentKey)) + return _unselectedColor; + return _selectedColor; + } + + Color getBackgroundColor(int index, T currentKey) { + if (_selectionControllers[index].isAnimating) + return _childTweens[index].evaluate(_selectionControllers[index]); + if (widget.groupValue.Equals(currentKey)) + return _selectedColor; + if (isPressKeyEquals(currentKey)) + return _pressedColor; + return _unselectedColor; + } + + public override Widget build(BuildContext context) { + List _gestureChildren = new List(); + List _backgroundColors = new List(); + int index = 0; + int? selectedIndex = null; + int? pressedIndex = null; + foreach (var currentKey in widget.children.Keys) { + var currentKey2 = currentKey; + selectedIndex = (widget.groupValue.Equals(currentKey2)) ? index : selectedIndex; + pressedIndex = (isPressKeyEquals(currentKey2)) ? index : pressedIndex; + var textStyle = DefaultTextStyle.of(context).style.copyWith( + color: getTextColor(index, currentKey2) + ); + var iconTheme = new IconThemeData( + color: getTextColor(index, currentKey2) + ); + + Widget child = new Center( + child: widget.children[currentKey2] + ); + + child = new GestureDetector( + onTapDown: (TapDownDetails _event) => { + _onTapDown(currentKey2); + }, + onTapCancel: _onTapCancel, + onTap: () => { + _onTap(currentKey2); + }, + child: new IconTheme( + data: iconTheme, + child: new DefaultTextStyle( + style: textStyle, + child: child + ) + ) + ); + + _backgroundColors.Add(getBackgroundColor(index, currentKey2)); + _gestureChildren.Add(child); + index += 1; + } + + Widget box = new _SegmentedControlRenderWidget( + children: _gestureChildren, + selectedIndex: selectedIndex, + pressedIndex: pressedIndex, + backgroundColors: _backgroundColors, + borderColor: _borderColor + ); + + return new Padding( + padding: widget.padding ?? CupertinoSegmentedControlsUtils._kHorizontalItemPadding, + child: new UnconstrainedBox( + constrainedAxis: Axis.horizontal, + child: box + ) + ); + } + } + public class _SegmentedControlRenderWidget : MultiChildRenderObjectWidget { public _SegmentedControlRenderWidget( - Key key = null, - List children = null, - int? selectedIndex = null, - int? pressedIndex = null, - List backgroundColors = null, - Color borderColor = null - ) : base( - key: key, - children: children ?? new List() - ) { - this.selectedIndex = selectedIndex; - this.pressedIndex = pressedIndex; - this.backgroundColors = backgroundColors; - this.borderColor = borderColor; - } + Key key = null, + List children = null, + int? selectedIndex = null, + int? pressedIndex = null, + List backgroundColors = null, + Color borderColor = null + ) : base( + key: key, + children: children ?? new List() + ) { + this.selectedIndex = selectedIndex; + this.pressedIndex = pressedIndex; + this.backgroundColors = backgroundColors; + this.borderColor = borderColor; + } - public readonly int? selectedIndex; - public readonly int? pressedIndex; - public readonly List backgroundColors; - public readonly Color borderColor; - public override RenderObject createRenderObject(BuildContext context) { - return new _RenderSegmentedControl( - textDirection: Directionality.of(context), - selectedIndex: selectedIndex, - pressedIndex: pressedIndex, - backgroundColors: backgroundColors, - borderColor: borderColor - ); - } - public override void updateRenderObject(BuildContext context,RenderObject renderObject) { - renderObject = (_RenderSegmentedControl) renderObject; - ((_RenderSegmentedControl) renderObject).textDirection = Directionality.of(context); - ((_RenderSegmentedControl) renderObject).selectedIndex = selectedIndex; - ((_RenderSegmentedControl) renderObject).pressedIndex = pressedIndex; - ((_RenderSegmentedControl) renderObject).backgroundColors = backgroundColors; - ((_RenderSegmentedControl) renderObject).borderColor = borderColor; - - } + public readonly int? selectedIndex; + public readonly int? pressedIndex; + public readonly List backgroundColors; + public readonly Color borderColor; + + public override RenderObject createRenderObject(BuildContext context) { + return new _RenderSegmentedControl( + textDirection: Directionality.of(context), + selectedIndex: selectedIndex, + pressedIndex: pressedIndex, + backgroundColors: backgroundColors, + borderColor: borderColor + ); + } + + public override void updateRenderObject(BuildContext context, RenderObject renderObject) { + renderObject = (_RenderSegmentedControl) renderObject; + ((_RenderSegmentedControl) renderObject).textDirection = Directionality.of(context); + ((_RenderSegmentedControl) renderObject).selectedIndex = selectedIndex; + ((_RenderSegmentedControl) renderObject).pressedIndex = pressedIndex; + ((_RenderSegmentedControl) renderObject).backgroundColors = backgroundColors; + ((_RenderSegmentedControl) renderObject).borderColor = borderColor; + } } class _SegmentedControlContainerBoxParentData : ContainerBoxParentData { @@ -336,13 +375,13 @@ namespace Unity.UIWidgets.cupertino { public delegate RenderBox _NextChild(RenderBox child); class _RenderSegmentedControl : RenderBoxContainerDefaultsMixinContainerRenderObjectMixinRenderBox> { + ContainerBoxParentData> { public _RenderSegmentedControl( int? selectedIndex = null, int? pressedIndex = null, TextDirection? textDirection = null, List backgroundColors = null, - Color borderColor = null + Color borderColor = null ) { D.assert(textDirection != null); _textDirection = textDirection; @@ -352,267 +391,282 @@ namespace Unity.UIWidgets.cupertino { _borderColor = borderColor; } - public int? selectedIndex { - get {return _selectedIndex; } - set { - if (_selectedIndex == value) { - return; - } - _selectedIndex = value; - markNeedsPaint(); - } - } - int? _selectedIndex; - - public int? pressedIndex { - get { - return _pressedIndex; - } - set { - if (_pressedIndex == value) { - return; - } - _pressedIndex = value; - markNeedsPaint(); - } - } - int? _pressedIndex; - - public TextDirection? textDirection { - get { - return _textDirection; - } - set { - if (_textDirection == value) { - return; - } - _textDirection = value; - markNeedsLayout(); - } - } - TextDirection? _textDirection; - - - public List backgroundColors { - get { - return _backgroundColors; - } - set { - if (_backgroundColors == value) { - return; - } - _backgroundColors = value; - markNeedsPaint(); - } - } - List _backgroundColors; - - - public Color borderColor { - get { - return _borderColor; - - } - set { - if (_borderColor == value) { - return; - } - _borderColor = value; - markNeedsPaint(); - - } - - } - Color _borderColor; - - - protected internal override float computeMinIntrinsicWidth(float height) { - RenderBox child = firstChild; - float minWidth = 0.0f; - while (child != null) { - _SegmentedControlContainerBoxParentData childParentData = child.parentData as _SegmentedControlContainerBoxParentData; - float childWidth = child.getMinIntrinsicWidth(height); - minWidth = Mathf.Max(minWidth, childWidth); - child = childParentData.nextSibling; + public int? selectedIndex { + get { return _selectedIndex; } + set { + if (_selectedIndex == value) { + return; } - return minWidth * childCount; - } - protected internal override float computeMaxIntrinsicWidth(float height) { - RenderBox child = firstChild; - float maxWidth = 0.0f; - while (child != null) { - _SegmentedControlContainerBoxParentData childParentData = child.parentData as _SegmentedControlContainerBoxParentData; - float childWidth = child.getMaxIntrinsicWidth(height); - maxWidth = Mathf.Max(maxWidth, childWidth); - child = childParentData.nextSibling; - } - return maxWidth * childCount; - } - - protected internal override float computeMinIntrinsicHeight(float width) { - RenderBox child = firstChild; - float minHeight = 0.0f; - while (child != null) { - _SegmentedControlContainerBoxParentData childParentData = child.parentData as _SegmentedControlContainerBoxParentData; - float childHeight = child.getMinIntrinsicHeight(width); - minHeight = Mathf.Max(minHeight, childHeight); - child = childParentData.nextSibling; - } - return minHeight; - } - protected internal override float computeMaxIntrinsicHeight(float width) { - RenderBox child = firstChild; - float maxHeight = 0.0f; - while (child != null) { - _SegmentedControlContainerBoxParentData childParentData = child.parentData as _SegmentedControlContainerBoxParentData; - float childHeight = child.getMaxIntrinsicHeight(width); - maxHeight = Mathf.Max(maxHeight, childHeight); - child = childParentData.nextSibling; - } - return maxHeight; - } - - public override float? computeDistanceToActualBaseline(TextBaseline baseline) { - return defaultComputeDistanceToHighestActualBaseline(baseline); - } - - public override void setupParentData(RenderObject child) { - child = (RenderBox) child; - if (!(child.parentData is _SegmentedControlContainerBoxParentData)) { - child.parentData = new _SegmentedControlContainerBoxParentData(); + _selectedIndex = value; + markNeedsPaint(); } - } + } - void _layoutRects(_NextChild nextChild, RenderBox leftChild, RenderBox rightChild) { + int? _selectedIndex; + + public int? pressedIndex { + get { return _pressedIndex; } + set { + if (_pressedIndex == value) { + return; + } + + _pressedIndex = value; + markNeedsPaint(); + } + } + + int? _pressedIndex; + + public TextDirection? textDirection { + get { return _textDirection; } + set { + if (_textDirection == value) { + return; + } + + _textDirection = value; + markNeedsLayout(); + } + } + + TextDirection? _textDirection; + + + public List backgroundColors { + get { return _backgroundColors; } + set { + if (_backgroundColors == value) { + return; + } + + _backgroundColors = value; + markNeedsPaint(); + } + } + + List _backgroundColors; + + + public Color borderColor { + get { return _borderColor; } + set { + if (_borderColor == value) { + return; + } + + _borderColor = value; + markNeedsPaint(); + } + } + + Color _borderColor; + + + protected internal override float computeMinIntrinsicWidth(float height) { + RenderBox child = firstChild; + float minWidth = 0.0f; + while (child != null) { + _SegmentedControlContainerBoxParentData childParentData = + child.parentData as _SegmentedControlContainerBoxParentData; + float childWidth = child.getMinIntrinsicWidth(height); + minWidth = Mathf.Max(minWidth, childWidth); + child = childParentData.nextSibling; + } + + return minWidth * childCount; + } + + protected internal override float computeMaxIntrinsicWidth(float height) { + RenderBox child = firstChild; + float maxWidth = 0.0f; + while (child != null) { + _SegmentedControlContainerBoxParentData childParentData = + child.parentData as _SegmentedControlContainerBoxParentData; + float childWidth = child.getMaxIntrinsicWidth(height); + maxWidth = Mathf.Max(maxWidth, childWidth); + child = childParentData.nextSibling; + } + + return maxWidth * childCount; + } + + protected internal override float computeMinIntrinsicHeight(float width) { + RenderBox child = firstChild; + float minHeight = 0.0f; + while (child != null) { + _SegmentedControlContainerBoxParentData childParentData = + child.parentData as _SegmentedControlContainerBoxParentData; + float childHeight = child.getMinIntrinsicHeight(width); + minHeight = Mathf.Max(minHeight, childHeight); + child = childParentData.nextSibling; + } + + return minHeight; + } + + protected internal override float computeMaxIntrinsicHeight(float width) { + RenderBox child = firstChild; + float maxHeight = 0.0f; + while (child != null) { + _SegmentedControlContainerBoxParentData childParentData = + child.parentData as _SegmentedControlContainerBoxParentData; + float childHeight = child.getMaxIntrinsicHeight(width); + maxHeight = Mathf.Max(maxHeight, childHeight); + child = childParentData.nextSibling; + } + + return maxHeight; + } + + public override float? computeDistanceToActualBaseline(TextBaseline baseline) { + return defaultComputeDistanceToHighestActualBaseline(baseline); + } + + public override void setupParentData(RenderObject child) { + child = (RenderBox) child; + if (!(child.parentData is _SegmentedControlContainerBoxParentData)) { + child.parentData = new _SegmentedControlContainerBoxParentData(); + } + } + + void _layoutRects(_NextChild nextChild, RenderBox leftChild, RenderBox rightChild) { RenderBox child = leftChild; float start = 0.0f; while (child != null) { - _SegmentedControlContainerBoxParentData childParentData = child.parentData as _SegmentedControlContainerBoxParentData; - Offset childOffset = new Offset(start, 0.0f); - childParentData.offset = childOffset; - Rect childRect = Rect.fromLTWH(start, 0.0f, child.size.width, child.size.height); - RRect rChildRect = null; - if (child == leftChild) { - rChildRect = RRect.fromRectAndCorners(childRect, topLeft: Radius.circular(3.0f), - bottomLeft: Radius.circular(3.0f)); - } else if (child == rightChild) { - rChildRect = RRect.fromRectAndCorners(childRect, topRight: Radius.circular(3.0f), - bottomRight: Radius.circular(3.0f)); - } else { - rChildRect = RRect.fromRectAndCorners(childRect,topRight:Radius.zero); - } - childParentData.surroundingRect = rChildRect; - start += child.size.width; - child = nextChild(child); + _SegmentedControlContainerBoxParentData childParentData = + child.parentData as _SegmentedControlContainerBoxParentData; + Offset childOffset = new Offset(start, 0.0f); + childParentData.offset = childOffset; + Rect childRect = Rect.fromLTWH(start, 0.0f, child.size.width, child.size.height); + RRect rChildRect = null; + if (child == leftChild) { + rChildRect = RRect.fromRectAndCorners(childRect, topLeft: Radius.circular(3.0f), + bottomLeft: Radius.circular(3.0f)); + } + else if (child == rightChild) { + rChildRect = RRect.fromRectAndCorners(childRect, topRight: Radius.circular(3.0f), + bottomRight: Radius.circular(3.0f)); + } + else { + rChildRect = RRect.fromRectAndCorners(childRect, topRight: Radius.zero); + } + + childParentData.surroundingRect = rChildRect; + start += child.size.width; + child = nextChild(child); } - } - protected override void performLayout() { - BoxConstraints constraints = this.constraints; + } + + protected override void performLayout() { + BoxConstraints constraints = this.constraints; float maxHeight = CupertinoSegmentedControlsUtils._kMinSegmentedControlHeight; float childWidth = constraints.minWidth / childCount; - foreach ( RenderBox child in getChildrenAsList()) { - childWidth = Mathf.Max(childWidth, child.getMaxIntrinsicWidth(float.PositiveInfinity)); + foreach (RenderBox child in getChildrenAsList()) { + childWidth = Mathf.Max(childWidth, child.getMaxIntrinsicWidth(float.PositiveInfinity)); } + childWidth = Mathf.Min(childWidth, constraints.maxWidth / childCount); RenderBox child1 = firstChild; while (child1 != null) { - float boxHeight = child1.getMaxIntrinsicHeight(childWidth); - maxHeight = Mathf.Max(maxHeight, boxHeight); - child1 = childAfter(child1); + float boxHeight = child1.getMaxIntrinsicHeight(childWidth); + maxHeight = Mathf.Max(maxHeight, boxHeight); + child1 = childAfter(child1); } constraints.constrainHeight(maxHeight); - BoxConstraints childConstraints = BoxConstraints.tightFor( - width: childWidth, - height: maxHeight + BoxConstraints childConstraints = BoxConstraints.tightFor( + width: childWidth, + height: maxHeight ); child1 = firstChild; while (child1 != null) { - child1.layout(childConstraints, parentUsesSize: true); - child1 = childAfter(child1); + child1.layout(childConstraints, parentUsesSize: true); + child1 = childAfter(child1); } switch (textDirection) { - case TextDirection.rtl: - _layoutRects( - childBefore, - lastChild, - firstChild - ); - break; - case TextDirection.ltr: - _layoutRects( - childAfter, - firstChild, - lastChild - ); - break; + case TextDirection.rtl: + _layoutRects( + childBefore, + lastChild, + firstChild + ); + break; + case TextDirection.ltr: + _layoutRects( + childAfter, + firstChild, + lastChild + ); + break; } size = constraints.constrain(new Size(childWidth * childCount, maxHeight)); - } - public override void paint(PaintingContext context, Offset offset) { + } + + public override void paint(PaintingContext context, Offset offset) { RenderBox child = firstChild; int index = 0; while (child != null) { - _paintChild(context, offset, child, index); - child = childAfter(child); - index += 1; + _paintChild(context, offset, child, index); + child = childAfter(child); + index += 1; } - } + } - void _paintChild(PaintingContext context, Offset offset, RenderBox child, int childIndex) { + void _paintChild(PaintingContext context, Offset offset, RenderBox child, int childIndex) { D.assert(child != null); - _SegmentedControlContainerBoxParentData childParentData = child.parentData as _SegmentedControlContainerBoxParentData; + _SegmentedControlContainerBoxParentData childParentData = + child.parentData as _SegmentedControlContainerBoxParentData; context.canvas.drawRRect( - childParentData.surroundingRect.shift(offset), - new Paint(){ - color = backgroundColors[childIndex], - style = PaintingStyle.fill} + childParentData.surroundingRect.shift(offset), + new Paint() { + color = backgroundColors[childIndex], + style = PaintingStyle.fill + } ); context.canvas.drawRRect( - childParentData.surroundingRect.shift(offset), - new Paint(){ - color = borderColor, - strokeWidth = 1.0f, - style = PaintingStyle.stroke} + childParentData.surroundingRect.shift(offset), + new Paint() { + color = borderColor, + strokeWidth = 1.0f, + style = PaintingStyle.stroke + } ); context.paintChild(child, childParentData.offset + offset); - } + } - protected override bool hitTestChildren(BoxHitTestResult result, Offset position = null ) { + protected override bool hitTestChildren(BoxHitTestResult result, Offset position = null) { D.assert(position != null); RenderBox child = lastChild; while (child != null) { - _SegmentedControlContainerBoxParentData childParentData = child.parentData as _SegmentedControlContainerBoxParentData; - if (childParentData.surroundingRect.contains(position)) { - Offset center = (Offset.zero & child.size).center; - return result.addWithRawTransform( - transform: MatrixUtils.forceToPoint(center), - position: center, - hitTest: (BoxHitTestResult result1, Offset position1) =>{ - D.assert(position1 == center); - return child.hitTest(result1, position: center); - } - ); - } - child = childParentData.previousSibling; + _SegmentedControlContainerBoxParentData childParentData = + child.parentData as _SegmentedControlContainerBoxParentData; + if (childParentData.surroundingRect.contains(position)) { + Offset center = (Offset.zero & child.size).center; + return result.addWithRawTransform( + transform: MatrixUtils.forceToPoint(center), + position: center, + hitTest: (BoxHitTestResult result1, Offset position1) => { + D.assert(position1 == center); + return child.hitTest(result1, position: center); + } + ); + } + + child = childParentData.previousSibling; } + return false; - } -} - - - - - - + } + } } \ No newline at end of file diff --git a/com.unity.uiwidgets/Runtime/widgets/fade_in_image.cs b/com.unity.uiwidgets/Runtime/widgets/fade_in_image.cs index af119de0..66d84771 100644 --- a/com.unity.uiwidgets/Runtime/widgets/fade_in_image.cs +++ b/com.unity.uiwidgets/Runtime/widgets/fade_in_image.cs @@ -1,15 +1,11 @@ using System; using System.Collections.Generic; -using System.Runtime.CompilerServices; using Unity.UIWidgets.animation; using Unity.UIWidgets.foundation; using Unity.UIWidgets.painting; using Unity.UIWidgets.rendering; using Unity.UIWidgets.ui; using UnityEngine; -using Color = Unity.UIWidgets.ui.Color; -using Debug = System.Diagnostics.Debug; -using Object = System.Object; namespace Unity.UIWidgets.widgets { public class FadeInImage : StatelessWidget { @@ -30,7 +26,6 @@ namespace Unity.UIWidgets.widgets { Key key = null, bool matchTextDirection = false ) : base(key) { - D.assert(image != null); D.assert(fadeOutDuration != null); D.assert(fadeOutCurve != null); @@ -54,8 +49,8 @@ namespace Unity.UIWidgets.widgets { } public static FadeInImage memoryNetwork( - byte[] placeholder , - string image , + byte[] placeholder, + string image, Key key = null, ImageErrorWidgetBuilder placeholderErrorBuilder = null, ImageErrorWidgetBuilder imageErrorBuilder = null, @@ -77,13 +72,13 @@ namespace Unity.UIWidgets.widgets { int? imageCacheHeight = null ) { alignment = alignment ?? Alignment.center; - fadeOutDuration = fadeOutDuration ?? TimeSpan.FromMilliseconds( 300 ); + fadeOutDuration = fadeOutDuration ?? TimeSpan.FromMilliseconds(300); fadeOutCurve = fadeOutCurve ?? Curves.easeOut; - fadeInDuration = fadeInDuration ?? TimeSpan.FromMilliseconds( 700 ); + fadeInDuration = fadeInDuration ?? TimeSpan.FromMilliseconds(700); fadeInCurve = fadeInCurve ?? Curves.easeIn; ImageProvider memoryImage = new MemoryImage(placeholder, placeholderScale); ImageProvider networkImage = new NetworkImage(image, imageScale); - + //placeholder = ResizeImage.resizeIfNeeded(placeholderCacheWidth, placeholderCacheHeight, memoryImage); //image = ResizeImage.resizeIfNeeded(imageCacheWidth, imageCacheHeight, networkImage); return new FadeInImage( @@ -128,7 +123,6 @@ namespace Unity.UIWidgets.widgets { int? imageCacheWidth = null, int? imageCacheHeight = null ) { - fadeOutDuration = fadeOutDuration ?? new TimeSpan(0, 0, 0, 0, 300); fadeOutCurve = fadeOutCurve ?? Curves.easeOut; fadeInDuration = fadeInDuration ?? new TimeSpan(0, 0, 0, 0, 700); @@ -143,7 +137,61 @@ namespace Unity.UIWidgets.widgets { return new FadeInImage( placeholder: _placeholder, placeholderErrorBuilder: placeholderErrorBuilder, - image: ResizeImage.resizeIfNeeded(imageCacheWidth, imageCacheHeight, new NetworkImage(image, scale: imageScale)), + image: ResizeImage.resizeIfNeeded(imageCacheWidth, imageCacheHeight, + new NetworkImage(image, scale: imageScale)), + imageErrorBuilder: imageErrorBuilder, + fadeOutDuration: fadeOutDuration, + fadeOutCurve: fadeOutCurve, + fadeInDuration: fadeInDuration, + fadeInCurve: fadeInCurve, + width: width, height: height, + fit: fit, + alignment: alignment, + repeat: repeat, + matchTextDirection: matchTextDirection, + key: key + ); + } + + public static FadeInImage fileNetwork( + string placeholder, + string image, + ImageErrorWidgetBuilder placeholderErrorBuilder = null, + ImageErrorWidgetBuilder imageErrorBuilder = null, + float? placeholderScale = null, + float imageScale = 1.0f, + TimeSpan? fadeOutDuration = null, + Curve fadeOutCurve = null, + TimeSpan? fadeInDuration = null, + Curve fadeInCurve = null, + float? width = null, + float? height = null, + BoxFit? fit = null, + AlignmentGeometry alignment = null, + ImageRepeat repeat = ImageRepeat.noRepeat, + bool matchTextDirection = false, + Key key = null, + int? placeholderCacheWidth = null, + int? placeholderCacheHeight = null, + int? imageCacheWidth = null, + int? imageCacheHeight = null + ) { + fadeOutDuration = fadeOutDuration ?? new TimeSpan(0, 0, 0, 0, 300); + fadeOutCurve = fadeOutCurve ?? Curves.easeOut; + fadeInDuration = fadeInDuration ?? new TimeSpan(0, 0, 0, 0, 700); + fadeInCurve = Curves.easeIn; + alignment = alignment ?? Alignment.center; + var holder = placeholderScale ?? 1.0f; + var _placeholder = placeholderScale != null + ? ResizeImage.resizeIfNeeded(placeholderCacheWidth, placeholderCacheHeight, + new FileImage(placeholder, scale: holder)) + : ResizeImage.resizeIfNeeded(placeholderCacheWidth, placeholderCacheHeight, + new FileImage(placeholder)); + return new FadeInImage( + placeholder: _placeholder, + placeholderErrorBuilder: placeholderErrorBuilder, + image: ResizeImage.resizeIfNeeded(imageCacheWidth, imageCacheHeight, + new NetworkImage(image, scale: imageScale)), imageErrorBuilder: imageErrorBuilder, fadeOutDuration: fadeOutDuration, fadeOutCurve: fadeOutCurve, @@ -190,7 +238,6 @@ namespace Unity.UIWidgets.widgets { repeat: repeat, matchTextDirection: matchTextDirection, gaplessPlayback: true - ); } @@ -198,19 +245,19 @@ namespace Unity.UIWidgets.widgets { Widget result = _image( image: image, errorBuilder: imageErrorBuilder, - frameBuilder: (BuildContext context1, Widget child, int? frame, bool wasSynchronouslyLoaded)=> { - if (wasSynchronouslyLoaded) - return child; - return new _AnimatedFadeOutFadeIn( - target: child, - placeholder: _image(image: placeholder, errorBuilder: placeholderErrorBuilder), - isTargetLoaded: frame != null, - fadeInDuration: fadeInDuration, - fadeOutDuration: fadeOutDuration, - fadeInCurve: fadeInCurve, - fadeOutCurve: fadeOutCurve - ); - } + frameBuilder: (BuildContext context1, Widget child, int? frame, bool wasSynchronouslyLoaded) => { + if (wasSynchronouslyLoaded) + return child; + return new _AnimatedFadeOutFadeIn( + target: child, + placeholder: _image(image: placeholder, errorBuilder: placeholderErrorBuilder), + isTargetLoaded: frame != null, + fadeInDuration: fadeInDuration, + fadeOutDuration: fadeOutDuration, + fadeInCurve: fadeInCurve, + fadeOutCurve: fadeOutCurve + ); + } ); return result; } @@ -218,16 +265,15 @@ namespace Unity.UIWidgets.widgets { public class _AnimatedFadeOutFadeIn : ImplicitlyAnimatedWidget { public _AnimatedFadeOutFadeIn( - Widget target , - Widget placeholder , - bool isTargetLoaded , + Widget target, + Widget placeholder, + bool isTargetLoaded, TimeSpan fadeOutDuration, TimeSpan fadeInDuration, Curve fadeOutCurve, Curve fadeInCurve, Key key = null ) : base(key: key, duration: fadeInDuration + fadeOutDuration) { - this.target = target; this.placeholder = placeholder; this.isTargetLoaded = isTargetLoaded; @@ -260,48 +306,48 @@ namespace Unity.UIWidgets.widgets { state: this, tween: _targetOpacity, targetValue: widget.isTargetLoaded ? 1.0f : 0.0f, - constructor: (float value) => new FloatTween(begin: value, 0)); + constructor: (float value) => new FloatTween(begin: 1 - value, 0)); //TODO: in flutter it is "new FloatTween(begin: value, 0)", which doesn't work out in UIWidgets _placeholderOpacity = (FloatTween) visitor.visit( state: this, tween: _placeholderOpacity, targetValue: widget.isTargetLoaded ? 0.0f : 1.0f, - constructor: (float value) => new FloatTween(begin: value, 0)); + constructor: (float value) => new FloatTween(begin: 1 - value, 0)); //TODO: in flutter it is "new FloatTween(begin: value, 0)", which doesn't work out in UIWidgets } protected override void didUpdateTweens() { List> list = new List>(); - Debug.Assert(widget.fadeOutDuration?.Milliseconds != null, + Debug.Assert(widget.fadeOutDuration?.TotalMilliseconds != null, "widget.fadeOutDuration?.Milliseconds != null"); list.Add(new TweenSequenceItem( tween: _placeholderOpacity.chain(new CurveTween(curve: widget.fadeOutCurve)), - weight: (float) widget.fadeOutDuration?.Milliseconds + weight: (float) widget.fadeOutDuration?.TotalMilliseconds )); - Debug.Assert(widget.fadeInDuration?.Milliseconds != null, + Debug.Assert(widget.fadeInDuration?.TotalMilliseconds != null, "widget.fadeInDuration?.Milliseconds != null"); list.Add(new TweenSequenceItem( tween: new ConstantTween(0), - weight: (float) widget.fadeInDuration?.Milliseconds + weight: (float) widget.fadeInDuration?.TotalMilliseconds )); - + _placeholderOpacityAnimation = animation.drive(new TweenSequence(list)); - _placeholderOpacityAnimation.addStatusListener((AnimationStatus status) =>{ + _placeholderOpacityAnimation.addStatusListener((AnimationStatus status) => { if (_placeholderOpacityAnimation.isCompleted) { - setState(() => {}); + setState(() => { }); } }); List> list2 = new List>(); list2.Add(new TweenSequenceItem( tween: new ConstantTween(0), - weight: (float) widget.fadeOutDuration?.Milliseconds + weight: (float) widget.fadeOutDuration?.TotalMilliseconds )); list2.Add(new TweenSequenceItem( tween: _targetOpacity.chain(new CurveTween(curve: widget.fadeInCurve)), - weight: (float) widget.fadeInDuration?.Milliseconds + weight: (float) widget.fadeInDuration?.TotalMilliseconds )); _targetOpacityAnimation = animation.drive(new TweenSequence(list2)); if (!widget.isTargetLoaded && _isValid(_placeholderOpacity) && _isValid(_targetOpacity)) { @@ -313,7 +359,6 @@ namespace Unity.UIWidgets.widgets { return tween?.begin != null && tween?.end != null; } - public override Widget build(BuildContext context) { Widget target = new FadeTransition( opacity: _targetOpacityAnimation, @@ -345,6 +390,5 @@ namespace Unity.UIWidgets.widgets { new DiagnosticsProperty>("placeholderOpacity", _placeholderOpacityAnimation)); } } - } } \ No newline at end of file diff --git a/com.unity.uiwidgets/Runtime/widgets/image.cs b/com.unity.uiwidgets/Runtime/widgets/image.cs index 8c9c5b7c..c85f3fe8 100644 --- a/com.unity.uiwidgets/Runtime/widgets/image.cs +++ b/com.unity.uiwidgets/Runtime/widgets/image.cs @@ -339,7 +339,7 @@ namespace Unity.UIWidgets.widgets { } public class _ImageState : State, WidgetsBindingObserver { - int _frameNumber; + int? _frameNumber = null; ImageInfo _imageInfo; ImageStream _imageStream; @@ -584,7 +584,7 @@ namespace Unity.UIWidgets.widgets { description.add(new DiagnosticsProperty("stream", value: _imageStream)); description.add(new DiagnosticsProperty("pixels", value: _imageInfo)); description.add(new DiagnosticsProperty("loadingProgress", value: _loadingProgress)); - description.add(new DiagnosticsProperty("frameNumber", value: _frameNumber)); + description.add(new DiagnosticsProperty("frameNumber", value: _frameNumber)); description.add(new DiagnosticsProperty("wasSynchronouslyLoaded", value: _wasSynchronouslyLoaded)); } }