From a96e654983c066e90a7ccf07996f05751a7c2918 Mon Sep 17 00:00:00 2001 From: iizzaya Date: Mon, 26 Aug 2019 21:44:36 +0800 Subject: [PATCH 1/5] [Cupertino] Fix warnings --- Runtime/cupertino/button.cs | 14 ++++++-------- Runtime/cupertino/nav_bar.cs | 28 ++++++++++++---------------- Runtime/cupertino/page_scaffold.cs | 1 - Runtime/cupertino/route.cs | 13 ++++++------- Runtime/cupertino/slider.cs | 6 ++---- Runtime/cupertino/switch.cs | 10 +--------- Runtime/cupertino/tab_scaffold.cs | 6 ++++-- 7 files changed, 31 insertions(+), 47 deletions(-) diff --git a/Runtime/cupertino/button.cs b/Runtime/cupertino/button.cs index efb40df3..ebd3d597 100644 --- a/Runtime/cupertino/button.cs +++ b/Runtime/cupertino/button.cs @@ -31,7 +31,7 @@ public CupertinoButton( BorderRadius borderRadius = null, bool filled = false ) : base(key: key) { - D.assert(pressedOpacity == null || (pressedOpacity >= 0.0 && pressedOpacity <= 1.0)); + D.assert(pressedOpacity >= 0.0 && pressedOpacity <= 1.0); this._filled = filled; this.child = child; this.onPressed = onPressed; @@ -53,7 +53,7 @@ public static CupertinoButton filled( float pressedOpacity = 0.1f, BorderRadius borderRadius = null ) { - D.assert(pressedOpacity == null || (pressedOpacity >= 0.0 && pressedOpacity <= 1.0)); + D.assert(pressedOpacity >= 0.0 && pressedOpacity <= 1.0); return new CupertinoButton( key: key, color: null, @@ -202,12 +202,10 @@ public override Widget build(BuildContext context) { } }, child: new ConstrainedBox( - constraints: this.widget.minSize == null - ? new BoxConstraints() - : new BoxConstraints( - minWidth: this.widget.minSize, - minHeight: this.widget.minSize - ), + constraints: new BoxConstraints( + minWidth: this.widget.minSize, + minHeight: this.widget.minSize + ), child: new FadeTransition( opacity: this._opacityAnimation, child: new DecoratedBox( diff --git a/Runtime/cupertino/nav_bar.cs b/Runtime/cupertino/nav_bar.cs index 5e285b3e..489b7ece 100644 --- a/Runtime/cupertino/nav_bar.cs +++ b/Runtime/cupertino/nav_bar.cs @@ -100,7 +100,7 @@ public static bool _isTransitionable(BuildContext context) { BuildContext toHeroContext ) => { D.assert(animation != null); - D.assert(flightDirection != null); + D.assert(fromHeroContext != null); D.assert(toHeroContext != null); D.assert(fromHeroContext.widget is Hero); @@ -130,7 +130,6 @@ BuildContext toHeroContext bottomNavBar: fromNavBar, topNavBar: toNavBar ); - break; case HeroFlightDirection.pop: return new _NavigationBarTransition( animation: animation, @@ -351,7 +350,7 @@ public override Widget build(BuildContext context) { new Builder( builder: (BuildContext _context) => { return new Hero( - tag: this.widget.heroTag == NavBarUtils._defaultHeroTag + tag: this.widget.heroTag as _HeroTag == NavBarUtils._defaultHeroTag ? new _HeroTag(Navigator.of(_context)) : this.widget.heroTag, createRectTween: NavBarUtils._linearTranslateWithLargestRectSizeTween, @@ -393,8 +392,6 @@ public CupertinoSliverNavigationBar( bool transitionBetweenRoutes = true, object heroTag = null ) : base(key: key) { - D.assert(automaticallyImplyLeading != null); - D.assert(automaticallyImplyTitle != null); D.assert( automaticallyImplyTitle == true || largeTitle != null, () => "No largeTitle has been provided but automaticallyImplyTitle is also " + @@ -516,9 +513,6 @@ public _LargeTitleNavigationBarSliverDelegate( float persistentHeight, bool alwaysShowMiddle ) { - D.assert(this.persistentHeight != null); - D.assert(this.alwaysShowMiddle != null); - D.assert(this.transitionBetweenRoutes != null); this.keys = keys; this.components = components; this.userMiddle = userMiddle; @@ -621,7 +615,7 @@ public override Widget build(BuildContext context, float shrinkOffset, bool over } return new Hero( - tag: this.heroTag == NavBarUtils._defaultHeroTag + tag: this.heroTag as _HeroTag == NavBarUtils._defaultHeroTag ? new _HeroTag(Navigator.of(context)) : this.heroTag, createRectTween: NavBarUtils._linearTranslateWithLargestRectSizeTween, @@ -682,13 +676,11 @@ public override Widget build(BuildContext context) { style: CupertinoTheme.of(context).textTheme.navTitleTextStyle, child: middle ); - middle = this.middleVisible == null - ? middle - : new AnimatedOpacity( - opacity: this.middleVisible ? 1.0f : 0.0f, - duration: NavBarUtils._kNavBarTitleFadeDuration, - child: middle - ); + middle = new AnimatedOpacity( + opacity: this.middleVisible ? 1.0f : 0.0f, + duration: NavBarUtils._kNavBarTitleFadeDuration, + child: middle + ); } Widget leading = this.components.leading; @@ -1247,6 +1239,9 @@ public _NavigationBarTransition( _TransitionableNavigationBar topNavBar, _TransitionableNavigationBar bottomNavBar ) { + this.animation = animation; + this.topNavBar = topNavBar; + this.bottomNavBar = bottomNavBar; this.heightTween = new FloatTween( begin: this.bottomNavBar.renderBox.size.height, end: this.topNavBar.renderBox.size.height @@ -1325,6 +1320,7 @@ public _NavigationBarComponentsTransition( _TransitionableNavigationBar topNavBar, TextDirection directionality ) { + this.animation = animation; this.bottomComponents = bottomNavBar.componentsKeys; this.topComponents = topNavBar.componentsKeys; this.bottomNavBarBox = bottomNavBar.renderBox; diff --git a/Runtime/cupertino/page_scaffold.cs b/Runtime/cupertino/page_scaffold.cs index 45b18da5..9010251f 100644 --- a/Runtime/cupertino/page_scaffold.cs +++ b/Runtime/cupertino/page_scaffold.cs @@ -17,7 +17,6 @@ public CupertinoPageScaffold( bool resizeToAvoidBottomInset = true ) : base(key: key) { D.assert(child != null); - D.assert(resizeToAvoidBottomInset != null); this.child = child; this.navigationBar = navigationBar; diff --git a/Runtime/cupertino/route.cs b/Runtime/cupertino/route.cs index d735d673..9e1d8b54 100644 --- a/Runtime/cupertino/route.cs +++ b/Runtime/cupertino/route.cs @@ -133,7 +133,6 @@ static _CupertinoEdgeShadowDecoration lerp( _CupertinoEdgeShadowDecoration b, float t ) { - D.assert(t != null); if (a == null && b == null) { return null; } @@ -163,6 +162,10 @@ public override BoxPainter createBoxPainter(VoidCallback onChanged = null) { return new _CupertinoEdgeShadowPainter(this, onChanged); } + public override int GetHashCode() { + return this.edgeGradient.GetHashCode(); + } + public bool Equals(_CupertinoEdgeShadowDecoration other) { if (ReferenceEquals(null, other)) { return false; @@ -244,8 +247,6 @@ public CupertinoPageRoute( ) : base(settings: settings, fullscreenDialog: fullscreenDialog) { D.assert(builder != null); - D.assert(maintainState != null); - D.assert(fullscreenDialog != null); D.assert(this.opaque); this.builder = builder; this.title = title; @@ -409,7 +410,7 @@ public override Widget buildTransitions(BuildContext context, Animation a return buildPageTransitions(this, context, animation, secondaryAnimation, child); } - public string debugLabel { + public new string debugLabel { get { return $"{base.debugLabel}(${this.settings.name})"; } } } @@ -422,7 +423,6 @@ public CupertinoPageTransition( bool linearTransition, Key key = null ) : base(key: key) { - D.assert(linearTransition != null); this._primaryPositionAnimation = (linearTransition ? primaryRouteAnimation @@ -717,11 +717,10 @@ public override TimeSpan transitionDuration { get { return CupertinoRouteUtils._kModalPopupTransitionDuration; } } - Animation _animation; + new Animation _animation; Tween _offsetTween; - public override Animation createAnimation() { D.assert(this._animation == null); this._animation = new CurvedAnimation( diff --git a/Runtime/cupertino/slider.cs b/Runtime/cupertino/slider.cs index 5c8dc753..ede86c8f 100644 --- a/Runtime/cupertino/slider.cs +++ b/Runtime/cupertino/slider.cs @@ -35,8 +35,6 @@ public CupertinoSlider( ) : base(key: key) { D.assert(value != null); D.assert(onChanged != null); - D.assert(min != null); - D.assert(max != null); D.assert(value >= min && value <= max); D.assert(divisions == null || divisions > 0); this.value = value.Value; @@ -171,7 +169,7 @@ public _RenderCupertinoSlider( TickerProvider vsync = null ) : base(additionalConstraints: BoxConstraints.tightFor(width: SliderUtils._kSliderWidth, height: SliderUtils._kSliderHeight)) { - D.assert(value != null && value >= 0.0f && value <= 1.0f); + D.assert(value >= 0.0f && value <= 1.0f); this._value = value; this._divisions = divisions; this._activeColor = activeColor; @@ -191,7 +189,7 @@ public _RenderCupertinoSlider( public float value { get { return this._value; } set { - D.assert(value != null && value >= 0.0f && value <= 1.0f); + D.assert(value >= 0.0f && value <= 1.0f); if (value == this._value) { return; } diff --git a/Runtime/cupertino/switch.cs b/Runtime/cupertino/switch.cs index 20b2457c..31b15b45 100644 --- a/Runtime/cupertino/switch.cs +++ b/Runtime/cupertino/switch.cs @@ -34,11 +34,7 @@ public CupertinoSwitch( Key key = null, Color activeColor = null, DragStartBehavior dragStartBehavior = DragStartBehavior.start - ) : - base(key: key) { - D.assert(value != null); - D.assert(dragStartBehavior != null); - + ) : base(key: key) { this.value = value; this.onChanged = onChanged; this.activeColor = activeColor; @@ -136,7 +132,6 @@ public _RenderCupertinoSwitch( width: CupertinoSwitchUtils._kSwitchWidth, height: CupertinoSwitchUtils._kSwitchHeight) ) { - D.assert(value != null); D.assert(activeColor != null); D.assert(vsync != null); this._value = value; @@ -190,7 +185,6 @@ public _RenderCupertinoSwitch( public bool value { get { return this._value; } set { - D.assert(value != null); if (value == this._value) { return; } @@ -261,7 +255,6 @@ public ValueChanged onChanged { public TextDirection textDirection { get { return this._textDirection; } set { - D.assert(value != null); if (this._textDirection == value) { return; } @@ -277,7 +270,6 @@ public TextDirection textDirection { public DragStartBehavior dragStartBehavior { get { return this._drag.dragStartBehavior; } set { - D.assert(value != null); if (this._drag.dragStartBehavior == value) { return; } diff --git a/Runtime/cupertino/tab_scaffold.cs b/Runtime/cupertino/tab_scaffold.cs index 9444d0fc..3e182ef3 100644 --- a/Runtime/cupertino/tab_scaffold.cs +++ b/Runtime/cupertino/tab_scaffold.cs @@ -137,9 +137,11 @@ public _TabSwitchingView( int tabNumber, IndexedWidgetBuilder tabBuilder ) { - D.assert(currentTabIndex != null); - D.assert(tabNumber != null && tabNumber > 0); + D.assert(tabNumber > 0); D.assert(tabBuilder != null); + this.currentTabIndex = currentTabIndex; + this.tabNumber = tabNumber; + this.tabBuilder = tabBuilder; } public readonly int currentTabIndex; From 96a835277025319e1395181e7bbc0acb8e5e6587 Mon Sep 17 00:00:00 2001 From: iizzaya Date: Tue, 27 Aug 2019 15:17:14 +0800 Subject: [PATCH 2/5] [Cupertino] Add Action Sheet & Dialog --- Runtime/cupertino/action_sheet.cs | 1042 +++++++++++++ Runtime/cupertino/action_sheet.cs.meta | 11 + Runtime/cupertino/app.cs | 8 +- Runtime/cupertino/dialog.cs | 1341 +++++++++++++++++ Runtime/cupertino/dialog.cs.meta | 11 + Runtime/cupertino/route.cs | 11 +- Runtime/material/chip.cs | 2 +- Runtime/material/input_decorator.cs | 2 +- Runtime/material/list_tile.cs | 2 +- Runtime/material/slider.cs | 2 +- Runtime/rendering/box.cs | 2 +- Runtime/rendering/custom_layout.cs | 2 +- Runtime/rendering/editable.cs | 2 +- Runtime/rendering/flex.cs | 2 +- Runtime/rendering/image.cs | 2 +- Runtime/rendering/list_body.cs | 2 +- Runtime/rendering/paragraph.cs | 2 +- Runtime/rendering/performance_overlay.cs | 2 +- Runtime/rendering/proxy_box.cs | 8 +- Runtime/rendering/proxy_box.mixin.gen.cs | 2 +- Runtime/rendering/rotated_box.cs | 2 +- Runtime/rendering/shifted_box.cs | 10 +- Runtime/rendering/stack.cs | 2 +- Runtime/rendering/table.cs | 2 +- Runtime/rendering/viewport.cs | 2 +- Runtime/rendering/wrap.cs | 2 +- Runtime/widgets/layout_builder.cs | 2 +- Runtime/widgets/single_child_scroll_view.cs | 2 +- .../demo/cupertino/cupertino_alert_demo.cs | 42 +- Samples/UIWidgetsGallery/gallery/demos.cs | 16 +- 30 files changed, 2474 insertions(+), 66 deletions(-) create mode 100644 Runtime/cupertino/action_sheet.cs create mode 100644 Runtime/cupertino/action_sheet.cs.meta create mode 100644 Runtime/cupertino/dialog.cs create mode 100644 Runtime/cupertino/dialog.cs.meta diff --git a/Runtime/cupertino/action_sheet.cs b/Runtime/cupertino/action_sheet.cs new file mode 100644 index 00000000..97399843 --- /dev/null +++ b/Runtime/cupertino/action_sheet.cs @@ -0,0 +1,1042 @@ +using System.Collections.Generic; +using Unity.UIWidgets.foundation; +using Unity.UIWidgets.gestures; +using Unity.UIWidgets.painting; +using Unity.UIWidgets.rendering; +using Unity.UIWidgets.ui; +using Unity.UIWidgets.widgets; +using UnityEngine; +using Canvas = Unity.UIWidgets.ui.Canvas; +using Color = Unity.UIWidgets.ui.Color; +using Rect = Unity.UIWidgets.ui.Rect; +using TextStyle = Unity.UIWidgets.painting.TextStyle; + +namespace Unity.UIWidgets.cupertino { + class CupertinoActionSheetUtils { + public static TextStyle _kActionSheetActionStyle = new TextStyle( + // fontFamily: ".SF UI Text", + fontFamily: ".SF Pro Text", + inherit: false, + fontSize: 20.0f, + fontWeight: FontWeight.w400, + color: CupertinoColors.activeBlue, + textBaseline: TextBaseline.alphabetic + ); + + public static TextStyle _kActionSheetContentStyle = new TextStyle( + // fontFamily: ".SF UI Text", + fontFamily: ".SF Pro Text", + inherit: false, + fontSize: 13.0f, + fontWeight: FontWeight.w400, + color: _kContentTextColor, + textBaseline: TextBaseline.alphabetic + ); + + public static BoxDecoration _kAlertBlurOverlayDecoration = new BoxDecoration( + color: CupertinoColors.white, + backgroundBlendMode: BlendMode.overlay + ); + + public static Color _kBackgroundColor = new Color(0xD1F8F8F8); + public static Color _kPressedColor = new Color(0xA6E5E5EA); + public static Color _kButtonDividerColor = new Color(0x403F3F3F); + public static Color _kContentTextColor = new Color(0xFF8F8F8F); + public static Color _kCancelButtonPressedColor = new Color(0xFFEAEAEA); + + public const float _kBlurAmount = 20.0f; + public const float _kEdgeHorizontalPadding = 8.0f; + public const float _kCancelButtonPadding = 8.0f; + public const float _kEdgeVerticalPadding = 10.0f; + public const float _kContentHorizontalPadding = 40.0f; + public const float _kContentVerticalPadding = 14.0f; + public const float _kButtonHeight = 56.0f; + public const float _kCornerRadius = 14.0f; + public const float _kDividerThickness = 1.0f; + } + + public class CupertinoActionSheet : StatelessWidget { + public CupertinoActionSheet( + Key key = null, + Widget title = null, + Widget message = null, + List actions = null, + ScrollController messageScrollController = null, + ScrollController actionScrollController = null, + Widget cancelButton = null + ) : base(key: key) { + D.assert(actions != null || title != null || message != null || cancelButton != null, + () => + "An action sheet must have a non-null value for at least one of the following arguments: actions, title, message, or cancelButton"); + this.title = title; + this.message = message; + this.actions = actions ?? new List(); + this.messageScrollController = messageScrollController; + this.actionScrollController = actionScrollController; + this.cancelButton = cancelButton; + } + + public readonly Widget title; + public readonly Widget message; + public readonly List actions; + public readonly ScrollController messageScrollController; + public readonly ScrollController actionScrollController; + public readonly Widget cancelButton; + + Widget _buildContent() { + List content = new List(); + if (this.title != null || this.message != null) { + Widget titleSection = new _CupertinoAlertContentSection( + title: this.title, + message: this.message, + scrollController: this.messageScrollController + ); + content.Add(new Flexible(child: titleSection)); + } + + return new Container( + color: CupertinoActionSheetUtils._kBackgroundColor, + child: new Column( + mainAxisSize: MainAxisSize.min, + crossAxisAlignment: CrossAxisAlignment.stretch, + children: content + ) + ); + } + + Widget _buildActions() { + if (this.actions == null || this.actions.isEmpty()) { + return new Container(height: 0.0f); + } + + Debug.Log("_buildActions"); + + return new Container( + child: new _CupertinoAlertActionSection( + children: this.actions, + scrollController: this.actionScrollController, + hasCancelButton: this.cancelButton != null + ) + ); + } + + Widget _buildCancelButton() { + float cancelPadding = (this.actions != null || this.message != null || this.title != null) + ? CupertinoActionSheetUtils._kCancelButtonPadding + : 0.0f; + return new Padding( + padding: EdgeInsets.only(top: cancelPadding), + child: new _CupertinoActionSheetCancelButton( + child: this.cancelButton + ) + ); + } + + public override Widget build(BuildContext context) { + List children = new List { + new Flexible(child: new ClipRRect( + borderRadius: BorderRadius.circular(12.0f), + child: new BackdropFilter( + filter: ImageFilter.blur(sigmaX: CupertinoActionSheetUtils._kBlurAmount, + sigmaY: CupertinoActionSheetUtils._kBlurAmount), + child: new Container( + decoration: CupertinoActionSheetUtils._kAlertBlurOverlayDecoration, + child: new _CupertinoAlertRenderWidget( + contentSection: this._buildContent(), + actionsSection: this._buildActions() + ) + ) + ) + ) + ), + }; + + if (this.cancelButton != null) { + children.Add(this._buildCancelButton() + ); + } + + Orientation orientation = MediaQuery.of(context).orientation; + + float actionSheetWidth; + if (orientation == Orientation.portrait) { + actionSheetWidth = MediaQuery.of(context).size.width - + (CupertinoActionSheetUtils._kEdgeHorizontalPadding * 2); + } + else { + actionSheetWidth = MediaQuery.of(context).size.height - + (CupertinoActionSheetUtils._kEdgeHorizontalPadding * 2); + } + + return new SafeArea( + child: new Container( + width: actionSheetWidth, + margin: EdgeInsets.symmetric( + horizontal: CupertinoActionSheetUtils._kEdgeHorizontalPadding, + vertical: CupertinoActionSheetUtils._kEdgeVerticalPadding + ), + child: new Column( + children: children, + mainAxisSize: MainAxisSize.min, + crossAxisAlignment: CrossAxisAlignment.stretch + ) + ) + ); + } + } + + + public class CupertinoActionSheetAction : StatelessWidget { + public CupertinoActionSheetAction( + Widget child, + VoidCallback onPressed, + bool isDefaultAction = false, + bool isDestructiveAction = false + ) { + Debug.Log("constructor"); + D.assert(child != null); + D.assert(onPressed != null); + this.child = child; + this.onPressed = onPressed; + this.isDefaultAction = isDefaultAction; + this.isDestructiveAction = isDestructiveAction; + } + + public readonly VoidCallback onPressed; + public readonly bool isDefaultAction; + public readonly bool isDestructiveAction; + public readonly Widget child; + + public override Widget build(BuildContext context) { + Debug.Log("build"); + TextStyle style = CupertinoActionSheetUtils._kActionSheetActionStyle; + + if (this.isDefaultAction) { + style = style.copyWith(fontWeight: FontWeight.w600); + } + + if (this.isDestructiveAction) { + style = style.copyWith(color: CupertinoColors.destructiveRed); + } + + + return new GestureDetector( + onTap: () => this.onPressed(), + behavior: HitTestBehavior.opaque, + child: new ConstrainedBox( + constraints: new BoxConstraints( + minHeight: CupertinoActionSheetUtils._kButtonHeight + ), + child: new Container( + alignment: Alignment.center, + padding: EdgeInsets.symmetric( + vertical: 16.0f, + horizontal: 10.0f + ), + child: new DefaultTextStyle( + style: style, + child: this.child, + textAlign: TextAlign.center + ) + ) + ) + ); + } + } + + class _CupertinoActionSheetCancelButton : StatefulWidget { + public _CupertinoActionSheetCancelButton( + Key key = null, + Widget child = null + ) : base(key: key) { + this.child = child; + } + + public readonly Widget child; + + public override State createState() { + return new _CupertinoActionSheetCancelButtonState(); + } + } + + class _CupertinoActionSheetCancelButtonState : State<_CupertinoActionSheetCancelButton> { + Color _backgroundColor; + + public override void initState() { + this._backgroundColor = CupertinoColors.white; + base.initState(); + } + + void _onTapDown(TapDownDetails evt) { + this.setState(() => { this._backgroundColor = CupertinoActionSheetUtils._kCancelButtonPressedColor; }); + } + + void _onTapUp(TapUpDetails evt) { + this.setState(() => { this._backgroundColor = CupertinoColors.white; }); + } + + void _onTapCancel() { + this.setState(() => { this._backgroundColor = CupertinoColors.white; }); + } + + public override Widget build(BuildContext context) { + return new GestureDetector( + onTapDown: this._onTapDown, + onTapUp: this._onTapUp, + onTapCancel: this._onTapCancel, + child: new Container( + decoration: new BoxDecoration( + color: this._backgroundColor, + borderRadius: BorderRadius.circular(CupertinoActionSheetUtils._kCornerRadius) + ), + child: this.widget.child + ) + ); + } + } + + class _CupertinoAlertRenderWidget : RenderObjectWidget { + public _CupertinoAlertRenderWidget( + Widget contentSection, + Widget actionsSection, + Key key = null + ) : base(key: key) { + this.contentSection = contentSection; + this.actionsSection = actionsSection; + } + + public readonly Widget contentSection; + public readonly Widget actionsSection; + + public override RenderObject createRenderObject(BuildContext context) { + return new _RenderCupertinoAlert( + dividerThickness: CupertinoActionSheetUtils._kDividerThickness / + MediaQuery.of(context).devicePixelRatio + ); + } + + public override Element createElement() { + return new _CupertinoAlertRenderElement(this); + } + } + + class _CupertinoAlertRenderElement : RenderObjectElement { + public _CupertinoAlertRenderElement(_CupertinoAlertRenderWidget widget) : base(widget) { } + + Element _contentElement; + Element _actionsElement; + + public new _CupertinoAlertRenderWidget widget { + get { return base.widget as _CupertinoAlertRenderWidget; } + } + + public new _RenderCupertinoAlert renderObject { + get { return base.renderObject as _RenderCupertinoAlert; } + } + + public override void visitChildren(ElementVisitor visitor) { + if (this._contentElement != null) { + visitor(this._contentElement); + } + + if (this._actionsElement != null) { + visitor(this._actionsElement); + } + } + + public override void mount(Element parent, object newSlot) { + base.mount(parent, newSlot); + this._contentElement = this.updateChild(this._contentElement, this.widget.contentSection, + _AlertSections.contentSection); + this._actionsElement = this.updateChild(this._actionsElement, this.widget.actionsSection, + _AlertSections.actionsSection); + } + + protected override void insertChildRenderObject(RenderObject child, object slot) { + this._placeChildInSlot(child, (_AlertSections) slot); + } + + protected override void moveChildRenderObject(RenderObject child, object slot) { + this._placeChildInSlot(child, (_AlertSections) slot); + } + + public override void update(Widget newWidget) { + base.update(newWidget); + this._contentElement = this.updateChild(this._contentElement, this.widget.contentSection, + _AlertSections.contentSection); + this._actionsElement = this.updateChild(this._actionsElement, this.widget.actionsSection, + _AlertSections.actionsSection); + } + + protected override void forgetChild(Element child) { + D.assert(child == this._contentElement || child == this._actionsElement); + if (this._contentElement == child) { + this._contentElement = null; + } + else if (this._actionsElement == child) { + this._actionsElement = null; + } + } + + protected override void removeChildRenderObject(RenderObject child) { + D.assert(child == this.renderObject.contentSection || child == this.renderObject.actionsSection); + if (this.renderObject.contentSection == child) { + this.renderObject.contentSection = null; + } + else if (this.renderObject.actionsSection == child) { + this.renderObject.actionsSection = null; + } + } + + void _placeChildInSlot(RenderObject child, _AlertSections slot) { + switch (slot) { + case _AlertSections.contentSection: + this.renderObject.contentSection = child as RenderBox; + break; + case _AlertSections.actionsSection: + this.renderObject.actionsSection = child as RenderBox; + ; + break; + } + } + } + + + class _RenderCupertinoAlert : RenderBox { + public _RenderCupertinoAlert( + RenderBox contentSection = null, + RenderBox actionsSection = null, + float dividerThickness = 0.0f + ) { + this._contentSection = contentSection; + this._actionsSection = actionsSection; + this._dividerThickness = dividerThickness; + } + + public RenderBox contentSection { + get { return this._contentSection; } + set { + if (value != this._contentSection) { + if (null != this._contentSection) { + this.dropChild(this._contentSection); + } + + this._contentSection = value; + if (null != this._contentSection) { + this.adoptChild(this._contentSection); + } + } + } + } + + RenderBox _contentSection; + + + public RenderBox actionsSection { + get { return this._actionsSection; } + set { + if (value != this._actionsSection) { + if (null != this._actionsSection) { + this.dropChild(this._actionsSection); + } + + this._actionsSection = value; + if (null != this._actionsSection) { + this.adoptChild(this._actionsSection); + } + } + } + } + + RenderBox _actionsSection; + + readonly float _dividerThickness; + + readonly Paint _dividerPaint = new Paint() { + color = CupertinoActionSheetUtils._kButtonDividerColor, + style = PaintingStyle.fill + }; + + public override void attach(object owner) { + base.attach(owner); + if (null != this.contentSection) { + this.contentSection.attach(owner); + } + + if (null != this.actionsSection) { + this.actionsSection.attach(owner); + } + } + + public override void detach() { + base.detach(); + if (null != this.contentSection) { + this.contentSection.detach(); + } + + if (null != this.actionsSection) { + this.actionsSection.detach(); + } + } + + public override void redepthChildren() { + if (null != this.contentSection) { + this.redepthChild(this.contentSection); + } + + if (null != this.actionsSection) { + this.redepthChild(this.actionsSection); + } + } + + public override void setupParentData(RenderObject child) { + if (!(child.parentData is MultiChildLayoutParentData)) { + child.parentData = new MultiChildLayoutParentData(); + } + } + + public override void visitChildren(RenderObjectVisitor visitor) { + if (this.contentSection != null) { + visitor(this.contentSection); + } + + if (this.actionsSection != null) { + visitor(this.actionsSection); + } + } + + public override List debugDescribeChildren() { + List value = new List(); + if (this.contentSection != null) { + value.Add(this.contentSection.toDiagnosticsNode(name: "content")); + } + + if (this.actionsSection != null) { + value.Add(this.actionsSection.toDiagnosticsNode(name: "actions")); + } + + return value; + } + + protected override float computeMinIntrinsicWidth(float height) { + return this.constraints.minWidth; + } + + protected override float computeMaxIntrinsicWidth(float height) { + return this.constraints.maxWidth; + } + + protected override float computeMinIntrinsicHeight(float width) { + float contentHeight = this.contentSection.getMinIntrinsicHeight(width); + float actionsHeight = this.actionsSection.getMinIntrinsicHeight(width); + bool hasDivider = contentHeight > 0.0f && actionsHeight > 0.0f; + float height = contentHeight + (hasDivider ? this._dividerThickness : 0.0f) + actionsHeight; + + if (actionsHeight > 0 || contentHeight > 0) { + height -= 2 * CupertinoActionSheetUtils._kEdgeVerticalPadding; + } + + if (height.isFinite()) { + return height; + } + + return 0.0f; + } + + protected internal override float computeMaxIntrinsicHeight(float width) { + float contentHeight = this.contentSection.getMaxIntrinsicHeight(width); + float actionsHeight = this.actionsSection.getMaxIntrinsicHeight(width); + bool hasDivider = contentHeight > 0.0f && actionsHeight > 0.0f; + float height = contentHeight + (hasDivider ? this._dividerThickness : 0.0f) + actionsHeight; + + if (actionsHeight > 0 || contentHeight > 0) { + height -= 2 * CupertinoActionSheetUtils._kEdgeVerticalPadding; + } + + if (height.isFinite()) { + return height; + } + + return 0.0f; + } + + protected override void performLayout() { + bool hasDivider = this.contentSection.getMaxIntrinsicHeight(this.constraints.maxWidth) > 0.0f + && this.actionsSection.getMaxIntrinsicHeight(this.constraints.maxWidth) > 0.0f; + float dividerThickness = hasDivider ? this._dividerThickness : 0.0f; + + float minActionsHeight = this.actionsSection.getMinIntrinsicHeight(this.constraints.maxWidth); + + + this.contentSection.layout( + this.constraints.deflate(EdgeInsets.only(bottom: minActionsHeight + dividerThickness)), + parentUsesSize: true + ); + Size contentSize = this.contentSection.size; + + + this.actionsSection.layout( + this.constraints.deflate(EdgeInsets.only(top: contentSize.height + dividerThickness)), + parentUsesSize: true + ); + Size actionsSize = this.actionsSection.size; + + + float actionSheetHeight = contentSize.height + dividerThickness + actionsSize.height; + + + this.size = new Size(this.constraints.maxWidth, actionSheetHeight); + + + D.assert(this.actionsSection.parentData is MultiChildLayoutParentData); + MultiChildLayoutParentData actionParentData = this.actionsSection.parentData as MultiChildLayoutParentData; + actionParentData.offset = new Offset(0.0f, contentSize.height + dividerThickness); + } + + public override void paint(PaintingContext context, Offset offset) { + MultiChildLayoutParentData contentParentData = this.contentSection.parentData as MultiChildLayoutParentData; + this.contentSection.paint(context, offset + contentParentData.offset); + + bool hasDivider = this.contentSection.size.height > 0.0f && this.actionsSection.size.height > 0.0f; + if (hasDivider) { + this._paintDividerBetweenContentAndActions(context.canvas, offset); + } + + MultiChildLayoutParentData actionsParentData = this.actionsSection.parentData as MultiChildLayoutParentData; + this.actionsSection.paint(context, offset + actionsParentData.offset); + } + + void _paintDividerBetweenContentAndActions(Canvas canvas, Offset offset) { + canvas.drawRect( + Rect.fromLTWH( + offset.dx, + offset.dy + this.contentSection.size.height, this.size.width, this._dividerThickness + ), this._dividerPaint + ); + } + + protected override bool hitTestChildren(HitTestResult result, Offset position = null) { + bool isHit = false; + MultiChildLayoutParentData contentSectionParentData = + this.contentSection.parentData as MultiChildLayoutParentData; + MultiChildLayoutParentData actionsSectionParentData = + this.actionsSection.parentData as MultiChildLayoutParentData; + ; + if (this.contentSection.hitTest(result, position: position - contentSectionParentData.offset)) { + isHit = true; + } + else if (this.actionsSection.hitTest(result, + position: position - actionsSectionParentData.offset)) { + isHit = true; + } + + return isHit; + } + } + + + enum _AlertSections { + contentSection, + actionsSection, + } + + + class _CupertinoAlertContentSection : StatelessWidget { + public _CupertinoAlertContentSection( + Key key = null, + Widget title = null, + Widget message = null, + ScrollController scrollController = null + ) : base(key: key) { + this.title = title; + this.message = message; + this.scrollController = scrollController; + } + + public readonly Widget title; + public readonly Widget message; + public readonly ScrollController scrollController; + + public override Widget build(BuildContext context) { + List titleContentGroup = new List(); + if (this.title != null) { + titleContentGroup.Add(new Padding( + padding: EdgeInsets.only( + left: CupertinoActionSheetUtils._kContentHorizontalPadding, + right: CupertinoActionSheetUtils._kContentHorizontalPadding, + bottom: CupertinoActionSheetUtils._kContentVerticalPadding, + top: CupertinoActionSheetUtils._kContentVerticalPadding + ), + child: new DefaultTextStyle( + style: this.message == null + ? CupertinoActionSheetUtils._kActionSheetContentStyle + : CupertinoActionSheetUtils._kActionSheetContentStyle.copyWith(fontWeight: FontWeight.w600), + textAlign: TextAlign.center, + child: this.title + ) + )); + } + + if (this.message != null) { + titleContentGroup.Add( + new Padding( + padding: EdgeInsets.only( + left: CupertinoActionSheetUtils._kContentHorizontalPadding, + right: CupertinoActionSheetUtils._kContentHorizontalPadding, + bottom: this.title == null ? CupertinoActionSheetUtils._kContentVerticalPadding : 22.0f, + top: this.title == null ? CupertinoActionSheetUtils._kContentVerticalPadding : 0.0f + ), + child: new DefaultTextStyle( + style: this.title == null + ? CupertinoActionSheetUtils._kActionSheetContentStyle.copyWith( + fontWeight: FontWeight.w600) + : CupertinoActionSheetUtils._kActionSheetContentStyle, + textAlign: TextAlign.center, + child: this.message + ) + ) + ); + } + + if (titleContentGroup.isEmpty()) { + return new SingleChildScrollView( + controller: this.scrollController, + child: new Container( + width: 0.0f, + height: 0.0f + ) + ); + } + + + if (titleContentGroup.Count > 1) { + titleContentGroup.Insert(1, new Padding(padding: EdgeInsets.only(top: 8.0f))); + } + + return new CupertinoScrollbar( + child: new SingleChildScrollView( + controller: this.scrollController, + child: new Column( + mainAxisSize: MainAxisSize.max, + crossAxisAlignment: CrossAxisAlignment.stretch, + children: titleContentGroup + ) + ) + ); + } + } + + + class _CupertinoAlertActionSection : StatefulWidget { + public _CupertinoAlertActionSection( + List children, + Key key = null, + ScrollController scrollController = null, + bool hasCancelButton = false + ) : base(key: key) { + D.assert(children != null); + this.children = children; + this.scrollController = scrollController; + this.hasCancelButton = hasCancelButton; + } + + public readonly List children; + public readonly ScrollController scrollController; + public readonly bool hasCancelButton; + + public override State createState() { + return new _CupertinoAlertActionSectionState(); + } + } + + class _CupertinoAlertActionSectionState : State<_CupertinoAlertActionSection> { + public override Widget build(BuildContext context) { + Debug.Log("AlertAction build"); + float devicePixelRatio = MediaQuery.of(context).devicePixelRatio; + + List interactiveButtons = new List(); + for (int i = 0; i < this.widget.children.Count; i += 1) { + interactiveButtons.Add(new _PressableActionButton( + child: this.widget.children[i] + ) + ); + } + + return new CupertinoScrollbar( + child: new SingleChildScrollView( + controller: this.widget.scrollController, + child: new _CupertinoAlertActionsRenderWidget( + actionButtons: interactiveButtons, + dividerThickness: CupertinoActionSheetUtils._kDividerThickness / devicePixelRatio, + hasCancelButton: this.widget.hasCancelButton + ) + ) + ); + } + } + + class _CupertinoAlertActionsRenderWidget : MultiChildRenderObjectWidget { + public _CupertinoAlertActionsRenderWidget( + List actionButtons, + Key key = null, + float dividerThickness = 0.0f, + bool hasCancelButton = false + ) : base(key: key, children: actionButtons) { + Debug.Log("AlertActionRenderWidget build"); + this._dividerThickness = dividerThickness; + this._hasCancelButton = hasCancelButton; + } + + readonly float _dividerThickness; + readonly bool _hasCancelButton; + + public override RenderObject createRenderObject(BuildContext context) { + return new _RenderCupertinoAlertActions( + dividerThickness: this._dividerThickness, + hasCancelButton: this._hasCancelButton + ); + } + + public override void updateRenderObject(BuildContext context, RenderObject renderObject) { + ((_RenderCupertinoAlertActions) renderObject).dividerThickness = this._dividerThickness; + ((_RenderCupertinoAlertActions) renderObject).hasCancelButton = this._hasCancelButton; + } + } + + class _RenderCupertinoAlertActions : RenderBoxContainerDefaultsMixinContainerRenderObjectMixinRenderBox { + public _RenderCupertinoAlertActions( + List children = null, + float dividerThickness = 0.0f, + bool hasCancelButton = false + ) { + this._dividerThickness = dividerThickness; + this._hasCancelButton = hasCancelButton; + this.addAll(children); + Debug.Log("_RenderCupertinoAlertActions"); + } + + public float dividerThickness { + get { return this._dividerThickness; } + set { + if (value == this._dividerThickness) { + return; + } + + this._dividerThickness = value; + this.markNeedsLayout(); + } + } + + float _dividerThickness; + + bool _hasCancelButton; + + public bool hasCancelButton { + get { return this._hasCancelButton; } + set { + if (value == this._hasCancelButton) { + return; + } + + this._hasCancelButton = value; + this.markNeedsLayout(); + } + } + + + readonly Paint _buttonBackgroundPaint = new Paint() { + color = CupertinoActionSheetUtils._kBackgroundColor, + style = PaintingStyle.fill + }; + + readonly Paint _pressedButtonBackgroundPaint = new Paint() { + color = CupertinoActionSheetUtils._kPressedColor, + style = PaintingStyle.fill + }; + + readonly Paint _dividerPaint = new Paint() { + color = CupertinoActionSheetUtils._kButtonDividerColor, + style = PaintingStyle.fill + }; + + public override void setupParentData(RenderObject child) { + if (!(child.parentData is _ActionButtonParentData)) { + child.parentData = new _ActionButtonParentData(); + } + } + + protected override float computeMinIntrinsicWidth(float height) { + return this.constraints.minWidth; + } + + protected override float computeMaxIntrinsicWidth(float height) { + return this.constraints.maxWidth; + } + + protected override float computeMinIntrinsicHeight(float width) { + if (this.childCount == 0) { + return 0.0f; + } + + if (this.childCount == 1) { + return this.firstChild.computeMaxIntrinsicHeight(width) + this.dividerThickness; + } + + if (this.hasCancelButton && this.childCount < 4) { + return this._computeMinIntrinsicHeightWithCancel(width); + } + + return this._computeMinIntrinsicHeightWithoutCancel(width); + } + + float _computeMinIntrinsicHeightWithCancel(float width) { + D.assert(this.childCount == 2 || this.childCount == 3); + if (this.childCount == 2) { + return this.firstChild.getMinIntrinsicHeight(width) + + this.childAfter(this.firstChild).getMinIntrinsicHeight(width) + + this.dividerThickness; + } + + return this.firstChild.getMinIntrinsicHeight(width) + + this.childAfter(this.firstChild).getMinIntrinsicHeight(width) + + this.childAfter(this.childAfter(this.firstChild)).getMinIntrinsicHeight(width) + + (this.dividerThickness * 2); + } + + float _computeMinIntrinsicHeightWithoutCancel(float width) { + D.assert(this.childCount >= 2); + return this.firstChild.getMinIntrinsicHeight(width) + + this.dividerThickness + + (0.5f * this.childAfter(this.firstChild).getMinIntrinsicHeight(width)); + } + + protected internal override float computeMaxIntrinsicHeight(float width) { + if (this.childCount == 0) { + return 0.0f; + } + + if (this.childCount == 1) { + return this.firstChild.computeMaxIntrinsicHeight(width) + this.dividerThickness; + } + + return this._computeMaxIntrinsicHeightStacked(width); + } + + float _computeMaxIntrinsicHeightStacked(float width) { + D.assert(this.childCount >= 2); + float allDividersHeight = (this.childCount - 1) * this.dividerThickness; + float heightAccumulation = allDividersHeight; + RenderBox button = this.firstChild; + while (button != null) { + heightAccumulation += button.getMaxIntrinsicHeight(width); + button = this.childAfter(button); + } + + return heightAccumulation; + } + + protected override void performLayout() { + BoxConstraints perButtonConstraints = this.constraints.copyWith( + minHeight: 0.0f, + maxHeight: float.PositiveInfinity + ); + RenderBox child = this.firstChild; + int index = 0; + float verticalOffset = 0.0f; + while (child != null) { + child.layout( + perButtonConstraints, + parentUsesSize: true + ); + D.assert(child.parentData is MultiChildLayoutParentData); + MultiChildLayoutParentData parentData = child.parentData as MultiChildLayoutParentData; + parentData.offset = new Offset(0.0f, verticalOffset); + verticalOffset += child.size.height; + if (index < this.childCount - 1) { + verticalOffset += this.dividerThickness; + } + + index += 1; + child = this.childAfter(child); + } + + this.size = this.constraints.constrain( + new Size(this.constraints.maxWidth, verticalOffset) + ); + } + + public override void paint(PaintingContext context, Offset offset) { + Canvas canvas = context.canvas; + this._drawButtonBackgroundsAndDividersStacked(canvas, offset); + this._drawButtons(context, offset); + } + + void _drawButtonBackgroundsAndDividersStacked(Canvas canvas, Offset offset) { + Offset dividerOffset = new Offset(0.0f, this.dividerThickness); + Path backgroundFillPath = new Path(); + // fillType = PathFillType.evenOdd + backgroundFillPath.addRect(Rect.fromLTWH(0.0f, 0.0f, this.size.width, this.size.height)); + + Path pressedBackgroundFillPath = new Path(); + Path dividersPath = new Path(); + Offset accumulatingOffset = offset; + RenderBox child = this.firstChild; + RenderBox prevChild = null; + while (child != null) { + D.assert(child.parentData is _ActionButtonParentData); + _ActionButtonParentData currentButtonParentData = child.parentData as _ActionButtonParentData; + bool isButtonPressed = currentButtonParentData.isPressed; + bool isPrevButtonPressed = false; + if (prevChild != null) { + D.assert(prevChild.parentData is _ActionButtonParentData); + _ActionButtonParentData previousButtonParentData = prevChild.parentData as _ActionButtonParentData; + isPrevButtonPressed = previousButtonParentData.isPressed; + } + + bool isDividerPresent = child != this.firstChild; + bool isDividerPainted = isDividerPresent && !(isButtonPressed || isPrevButtonPressed); + Rect dividerRect = Rect.fromLTWH( + accumulatingOffset.dx, + accumulatingOffset.dy, this.size.width, this._dividerThickness + ); + Rect buttonBackgroundRect = Rect.fromLTWH( + accumulatingOffset.dx, + accumulatingOffset.dy + (isDividerPresent ? this.dividerThickness : 0.0f), this.size.width, + child.size.height + ); + if (isButtonPressed) { + backgroundFillPath.addRect(buttonBackgroundRect); + pressedBackgroundFillPath.addRect(buttonBackgroundRect); + } + + if (isDividerPainted) { + backgroundFillPath.addRect(dividerRect); + dividersPath.addRect(dividerRect); + } + + accumulatingOffset += (isDividerPresent ? dividerOffset : Offset.zero) + + new Offset(0.0f, child.size.height); + prevChild = child; + child = this.childAfter(child); + } + + canvas.drawPath(backgroundFillPath, this._buttonBackgroundPaint); + canvas.drawPath(pressedBackgroundFillPath, this._pressedButtonBackgroundPaint); + canvas.drawPath(dividersPath, this._dividerPaint); + } + + void _drawButtons(PaintingContext context, Offset offset) { + RenderBox child = this.firstChild; + while (child != null) { + MultiChildLayoutParentData childParentData = child.parentData as MultiChildLayoutParentData; + context.paintChild(child, childParentData.offset + offset); + child = this.childAfter(child); + } + } + + protected override bool hitTestChildren(HitTestResult result, Offset position = null) { + return this.defaultHitTestChildren(result, position: position); + } + } +} \ No newline at end of file diff --git a/Runtime/cupertino/action_sheet.cs.meta b/Runtime/cupertino/action_sheet.cs.meta new file mode 100644 index 00000000..2fa7b7cd --- /dev/null +++ b/Runtime/cupertino/action_sheet.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: ea4f1fabac9a048f085e528a41c2415d +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Runtime/cupertino/app.cs b/Runtime/cupertino/app.cs index 69c1948e..1ffe73ad 100644 --- a/Runtime/cupertino/app.cs +++ b/Runtime/cupertino/app.cs @@ -124,7 +124,13 @@ void _updateNavigator() { this._navigatorObservers = new List(); } } - + + // Iterable> get _localizationsDelegates sync* { + // if (widget.localizationsDelegates != null) + // yield* widget.localizationsDelegates; + // yield DefaultCupertinoLocalizations.delegate; + // } + List _localizationsDelegates { get { List> _delegates = diff --git a/Runtime/cupertino/dialog.cs b/Runtime/cupertino/dialog.cs new file mode 100644 index 00000000..04bff338 --- /dev/null +++ b/Runtime/cupertino/dialog.cs @@ -0,0 +1,1341 @@ +using System.Collections.Generic; +using Unity.UIWidgets.foundation; +using Unity.UIWidgets.gestures; +using Unity.UIWidgets.painting; +using Unity.UIWidgets.rendering; +using Unity.UIWidgets.ui; +using Unity.UIWidgets.widgets; +using UnityEngine; +using Canvas = Unity.UIWidgets.ui.Canvas; +using Color = Unity.UIWidgets.ui.Color; +using Rect = Unity.UIWidgets.ui.Rect; +using TextStyle = Unity.UIWidgets.painting.TextStyle; + +namespace Unity.UIWidgets.cupertino { + class CupertinoDialogUtils { + public static TextStyle _kCupertinoDialogTitleStyle = new TextStyle( + fontFamily: ".SF UI Display", + fontSize: 18.0f, + fontWeight: FontWeight.w600, + color: CupertinoColors.black, + letterSpacing: 0.48f, + textBaseline: TextBaseline.alphabetic + ); + + public static TextStyle _kCupertinoDialogContentStyle = new TextStyle( + fontFamily: ".SF UI Text", + fontSize: 13.4f, + fontWeight: FontWeight.w400, + color: CupertinoColors.black, + height: 1.036f, + letterSpacing: -0.25f, + textBaseline: TextBaseline.alphabetic + ); + + public static TextStyle _kCupertinoDialogActionStyle = new TextStyle( + fontFamily: ".SF UI Text", + fontSize: 16.8f, + fontWeight: FontWeight.w400, + color: CupertinoColors.activeBlue, + textBaseline: TextBaseline.alphabetic + ); + + public const float _kCupertinoDialogWidth = 270.0f; + public const float _kAccessibilityCupertinoDialogWidth = 310.0f; + + public static BoxDecoration _kCupertinoDialogBlurOverlayDecoration = new BoxDecoration( + color: CupertinoColors.white, + backgroundBlendMode: BlendMode.overlay + ); + + public const float _kBlurAmount = 20.0f; + public const float _kEdgePadding = 20.0f; + public const float _kMinButtonHeight = 45.0f; + public const float _kMinButtonFontSize = 10.0f; + public const float _kDialogCornerRadius = 12.0f; + public const float _kDividerThickness = 1.0f; + + public static Color _kDialogColor = new Color(0xC0FFFFFF); + public static Color _kDialogPressedColor = new Color(0x90FFFFFF); + public static Color _kButtonDividerColor = new Color(0x40FFFFFF); + + + public const float _kMaxRegularTextScaleFactor = 1.4f; + + public static bool _isInAccessibilityMode(BuildContext context) { + MediaQueryData data = MediaQuery.of(context, nullOk: true); + return data != null && data.textScaleFactor > _kMaxRegularTextScaleFactor; + } + } + + + public class CupertinoAlertDialog : StatelessWidget { + public CupertinoAlertDialog( + Key key = null, + Widget title = null, + Widget content = null, + List actions = null, + ScrollController scrollController = null, + ScrollController actionScrollController = null + ) : base(key: key) { + D.assert(actions != null); + + this.title = title; + this.content = content; + this.actions = actions ?? new List(); + this.scrollController = scrollController; + this.actionScrollController = actionScrollController; + } + + public readonly Widget title; + public readonly Widget content; + public readonly List actions; + public readonly ScrollController scrollController; + public readonly ScrollController actionScrollController; + + Widget _buildContent() { + List children = new List(); + if (this.title != null || this.content != null) { + Widget titleSection = new _CupertinoDialogAlertContentSection( + title: this.title, + content: this.content, + scrollController: this.scrollController + ); + children.Add(new Flexible(flex: 3, child: titleSection)); + } + + return new Container( + color: CupertinoDialogUtils._kDialogColor, + child: new Column( + mainAxisSize: MainAxisSize.min, + crossAxisAlignment: CrossAxisAlignment.stretch, + children: children + ) + ); + } + + Widget _buildActions() { + Widget actionSection = new Container( + height: 0.0f + ); + if (this.actions.isNotEmpty()) { + actionSection = new _CupertinoDialogAlertActionSection( + children: this.actions, + scrollController: this.actionScrollController + ); + } + + return actionSection; + } + + public override Widget build(BuildContext context) { + CupertinoLocalizations localizations = CupertinoLocalizations.of(context); + bool isInAccessibilityMode = CupertinoDialogUtils._isInAccessibilityMode(context); + + float textScaleFactor = MediaQuery.of(context).textScaleFactor; + return new MediaQuery( + data: MediaQuery.of(context).copyWith( + textScaleFactor: Mathf.Max(textScaleFactor, 1.0f) + ), + child: new LayoutBuilder( + builder: (BuildContext _context, BoxConstraints constraints) => { + return new Center( + child: new Container( + margin: EdgeInsets.symmetric(vertical: CupertinoDialogUtils._kEdgePadding), + width: isInAccessibilityMode + ? CupertinoDialogUtils._kAccessibilityCupertinoDialogWidth + : CupertinoDialogUtils._kCupertinoDialogWidth, + child: new CupertinoPopupSurface( + isSurfacePainted: false, + child: new _CupertinoDialogRenderWidget( + contentSection: this._buildContent(), + actionsSection: this._buildActions() + ) + ) + ) + ); + } + ) + ); + } + } + + public class CupertinoDialog : StatelessWidget { + public CupertinoDialog( + Key key = null, + Widget child = null + ) : base(key: key) { + this.child = child; + } + + public readonly Widget child; + + public override Widget build(BuildContext context) { + return new Center( + child: new SizedBox( + width: CupertinoDialogUtils._kCupertinoDialogWidth, + child: new CupertinoPopupSurface( + child: this.child + ) + ) + ); + } + } + + public class CupertinoPopupSurface : StatelessWidget { + public CupertinoPopupSurface( + Key key = null, + bool isSurfacePainted = true, + Widget child = null + ) : base(key: key) { + this.isSurfacePainted = isSurfacePainted; + this.child = child; + } + + public readonly bool isSurfacePainted; + public readonly Widget child; + + public override Widget build(BuildContext context) { + return new ClipRRect( + borderRadius: BorderRadius.circular(CupertinoDialogUtils._kDialogCornerRadius), + child: new BackdropFilter( + filter: ImageFilter.blur(sigmaX: CupertinoDialogUtils._kBlurAmount, + sigmaY: CupertinoDialogUtils._kBlurAmount), + child: new Container( + decoration: CupertinoDialogUtils._kCupertinoDialogBlurOverlayDecoration, + child: new Container( + color: this.isSurfacePainted ? CupertinoDialogUtils._kDialogColor : null, + child: this.child + ) + ) + ) + ); + } + } + + class _CupertinoDialogRenderWidget : RenderObjectWidget { + public _CupertinoDialogRenderWidget( + Widget contentSection, + Widget actionsSection, + Key key = null + ) : base(key: key) { + this.contentSection = contentSection; + this.actionsSection = actionsSection; + } + + public readonly Widget contentSection; + public readonly Widget actionsSection; + + public override RenderObject createRenderObject(BuildContext context) { + return new _RenderCupertinoDialog( + dividerThickness: CupertinoDialogUtils._kDividerThickness / MediaQuery.of(context).devicePixelRatio, + isInAccessibilityMode: CupertinoDialogUtils._isInAccessibilityMode(context) + ); + } + + public override void updateRenderObject(BuildContext context, RenderObject renderObject) { + ((_RenderCupertinoDialog) renderObject).isInAccessibilityMode = + CupertinoDialogUtils._isInAccessibilityMode(context); + } + + public override Element createElement() { + return new _CupertinoDialogRenderElement(this); + } + } + + class _CupertinoDialogRenderElement : RenderObjectElement { + public _CupertinoDialogRenderElement(_CupertinoDialogRenderWidget widget) : base(widget) { } + + Element _contentElement; + Element _actionsElement; + + public new _CupertinoDialogRenderWidget widget { + get { return base.widget as _CupertinoDialogRenderWidget; } + } + + public new _RenderCupertinoDialog renderObject { + get { return base.renderObject as _RenderCupertinoDialog; } + } + + public override void visitChildren(ElementVisitor visitor) { + if (this._contentElement != null) { + visitor(this._contentElement); + } + + if (this._actionsElement != null) { + visitor(this._actionsElement); + } + } + + public override void mount(Element parent, object newSlot) { + base.mount(parent, newSlot); + this._contentElement = this.updateChild(this._contentElement, this.widget.contentSection, + _AlertDialogSections.contentSection); + this._actionsElement = this.updateChild(this._actionsElement, this.widget.actionsSection, + _AlertDialogSections.actionsSection); + } + + + protected override void insertChildRenderObject(RenderObject child, object slot) { + D.assert(slot != null); + switch (slot) { + case _AlertDialogSections.contentSection: + this.renderObject.contentSection = child as RenderBox; + break; + case _AlertDialogSections.actionsSection: + this.renderObject.actionsSection = child as RenderBox; + ; + break; + } + } + + protected override void moveChildRenderObject(RenderObject child, object slot) { + D.assert(false); + } + + public override void update(Widget newWidget) { + base.update(newWidget); + this._contentElement = this.updateChild(this._contentElement, this.widget.contentSection, + _AlertDialogSections.contentSection); + this._actionsElement = this.updateChild(this._actionsElement, this.widget.actionsSection, + _AlertDialogSections.actionsSection); + } + + protected override void forgetChild(Element child) { + D.assert(child == this._contentElement || child == this._actionsElement); + if (this._contentElement == child) { + this._contentElement = null; + } + else { + D.assert(this._actionsElement == child); + this._actionsElement = null; + } + } + + protected override void removeChildRenderObject(RenderObject child) { + D.assert(child == this.renderObject.contentSection || child == this.renderObject.actionsSection); + if (this.renderObject.contentSection == child) { + this.renderObject.contentSection = null; + } + else { + D.assert(this.renderObject.actionsSection == child); + this.renderObject.actionsSection = null; + } + } + } + + class _RenderCupertinoDialog : RenderBox { + public _RenderCupertinoDialog( + RenderBox contentSection = null, + RenderBox actionsSection = null, + float dividerThickness = 0.0f, + bool isInAccessibilityMode = false + ) { + this._contentSection = contentSection; + this._actionsSection = actionsSection; + this._dividerThickness = dividerThickness; + this._isInAccessibilityMode = isInAccessibilityMode; + } + + public RenderBox contentSection { + get { return this._contentSection; } + set { + if (value != this._contentSection) { + if (this._contentSection != null) { + this.dropChild(this._contentSection); + } + + this._contentSection = value; + if (this._contentSection != null) { + this.adoptChild(this._contentSection); + } + } + } + } + + RenderBox _contentSection; + + + public RenderBox actionsSection { + get { return this._actionsSection; } + set { + if (value != this._actionsSection) { + if (null != this._actionsSection) { + this.dropChild(this._actionsSection); + } + + this._actionsSection = value; + if (null != this._actionsSection) { + this.adoptChild(this._actionsSection); + } + } + } + } + + RenderBox _actionsSection; + + public bool isInAccessibilityMode { + get { return this._isInAccessibilityMode; } + set { + if (value != this._isInAccessibilityMode) { + this._isInAccessibilityMode = value; + this.markNeedsLayout(); + } + } + } + + bool _isInAccessibilityMode; + + float _dialogWidth { + get { + return this.isInAccessibilityMode + ? CupertinoDialogUtils._kAccessibilityCupertinoDialogWidth + : CupertinoDialogUtils._kCupertinoDialogWidth; + } + } + + readonly float _dividerThickness; + + readonly Paint _dividerPaint = new Paint() { + color = CupertinoDialogUtils._kButtonDividerColor, + style = PaintingStyle.fill + }; + + public override void attach(object owner) { + base.attach(owner); + if (null != this.contentSection) { + this.contentSection.attach(owner); + } + + if (null != this.actionsSection) { + this.actionsSection.attach(owner); + } + } + + public override void detach() { + base.detach(); + if (null != this.contentSection) { + this.contentSection.detach(); + } + + if (null != this.actionsSection) { + this.actionsSection.detach(); + } + } + + public override void redepthChildren() { + if (null != this.contentSection) { + this.redepthChild(this.contentSection); + } + + if (null != this.actionsSection) { + this.redepthChild(this.actionsSection); + } + } + + public override void setupParentData(RenderObject child) { + if (!(child.parentData is BoxParentData)) { + child.parentData = new BoxParentData(); + } + } + + public override void visitChildren(RenderObjectVisitor visitor) { + if (this.contentSection != null) { + visitor(this.contentSection); + } + + if (this.actionsSection != null) { + visitor(this.actionsSection); + } + } + + public override List debugDescribeChildren() { + List value = new List(); + if (this.contentSection != null) { + value.Add(this.contentSection.toDiagnosticsNode(name: "content")); + } + + if (this.actionsSection != null) { + value.Add(this.actionsSection.toDiagnosticsNode(name: "actions")); + } + + return value; + } + + protected override float computeMinIntrinsicWidth(float height) { + return this._dialogWidth; + } + + protected override float computeMaxIntrinsicWidth(float height) { + return this._dialogWidth; + } + + protected override float computeMinIntrinsicHeight(float width) { + float contentHeight = this.contentSection.getMinIntrinsicHeight(width); + float actionsHeight = this.actionsSection.getMinIntrinsicHeight(width); + bool hasDivider = contentHeight > 0.0f && actionsHeight > 0.0f; + float height = contentHeight + (hasDivider ? this._dividerThickness : 0.0f) + actionsHeight; + if (height.isFinite()) { + return height; + } + + return 0.0f; + } + + protected internal override float computeMaxIntrinsicHeight(float width) { + float contentHeight = this.contentSection.getMaxIntrinsicHeight(width); + float actionsHeight = this.actionsSection.getMaxIntrinsicHeight(width); + bool hasDivider = contentHeight > 0.0f && actionsHeight > 0.0f; + float height = contentHeight + (hasDivider ? this._dividerThickness : 0.0f) + actionsHeight; + if (height.isFinite()) { + return height; + } + + return 0.0f; + } + + protected override void performLayout() { + if (this.isInAccessibilityMode) { + this.performAccessibilityLayout(); + } + else { + this.performRegularLayout(); + } + } + + void performRegularLayout() { + bool hasDivider = this.contentSection.getMaxIntrinsicHeight(this._dialogWidth) > 0.0f + && this.actionsSection.getMaxIntrinsicHeight(this._dialogWidth) > 0.0f; + float dividerThickness = hasDivider ? this._dividerThickness : 0.0f; + float minActionsHeight = this.actionsSection.getMinIntrinsicHeight(this._dialogWidth); + this.contentSection.layout( + this.constraints.deflate(EdgeInsets.only(bottom: minActionsHeight + dividerThickness)), + parentUsesSize: true + ); + Size contentSize = this.contentSection.size; + this.actionsSection.layout( + this.constraints.deflate(EdgeInsets.only(top: contentSize.height + dividerThickness)), + parentUsesSize: true + ); + Size actionsSize = this.actionsSection.size; + float dialogHeight = contentSize.height + dividerThickness + actionsSize.height; + this.size = this.constraints.constrain( + new Size(this._dialogWidth, dialogHeight) + ); + D.assert(this.actionsSection.parentData is BoxParentData); + BoxParentData actionParentData = this.actionsSection.parentData as BoxParentData; + actionParentData.offset = new Offset(0.0f, contentSize.height + dividerThickness); + } + + void performAccessibilityLayout() { + bool hasDivider = this.contentSection.getMaxIntrinsicHeight(this._dialogWidth) > 0.0f + && this.actionsSection.getMaxIntrinsicHeight(this._dialogWidth) > 0.0f; + float dividerThickness = hasDivider ? this._dividerThickness : 0.0f; + float maxContentHeight = this.contentSection.getMaxIntrinsicHeight(this._dialogWidth); + float maxActionsHeight = this.actionsSection.getMaxIntrinsicHeight(this._dialogWidth); + Size contentSize; + Size actionsSize; + if (maxContentHeight + dividerThickness + maxActionsHeight > this.constraints.maxHeight) { + this.actionsSection.layout( + this.constraints.deflate(EdgeInsets.only(top: this.constraints.maxHeight / 2.0f)), + parentUsesSize: true + ); + actionsSize = this.actionsSection.size; + this.contentSection.layout( + this.constraints.deflate(EdgeInsets.only(bottom: actionsSize.height + dividerThickness)), + parentUsesSize: true + ); + contentSize = this.contentSection.size; + } + else { + this.contentSection.layout(this.constraints, + parentUsesSize: true + ); + contentSize = this.contentSection.size; + this.actionsSection.layout(this.constraints.deflate(EdgeInsets.only(top: contentSize.height)), + parentUsesSize: true + ); + actionsSize = this.actionsSection.size; + } + + float dialogHeight = contentSize.height + dividerThickness + actionsSize.height; + this.size = this.constraints.constrain( + new Size(this._dialogWidth, dialogHeight) + ); + D.assert(this.actionsSection.parentData is BoxParentData); + BoxParentData actionParentData = this.actionsSection.parentData as BoxParentData; + actionParentData.offset = new Offset(0.0f, contentSize.height + dividerThickness); + } + + public override void paint(PaintingContext context, Offset offset) { + BoxParentData contentParentData = this.contentSection.parentData as BoxParentData; + this.contentSection.paint(context, offset + contentParentData.offset); + bool hasDivider = this.contentSection.size.height > 0.0f && this.actionsSection.size.height > 0.0f; + if (hasDivider) { + this._paintDividerBetweenContentAndActions(context.canvas, offset); + } + + BoxParentData actionsParentData = this.actionsSection.parentData as BoxParentData; + this.actionsSection.paint(context, offset + actionsParentData.offset); + } + + void _paintDividerBetweenContentAndActions(Canvas canvas, Offset offset) { + canvas.drawRect( + Rect.fromLTWH( + offset.dx, + offset.dy + this.contentSection.size.height, this.size.width, this._dividerThickness + ), this._dividerPaint + ); + } + + protected override bool hitTestChildren(HitTestResult result, Offset position = null + ) { + bool isHit = false; + BoxParentData contentSectionParentData = this.contentSection.parentData as BoxParentData; + BoxParentData actionsSectionParentData = this.actionsSection.parentData as BoxParentData; + ; + if (this.contentSection.hitTest(result, position: position - contentSectionParentData.offset)) { + isHit = true; + } + else if (this.actionsSection.hitTest(result, position: position - actionsSectionParentData.offset)) { + isHit = true; + } + + return isHit; + } + } + + enum _AlertDialogSections { + contentSection, + actionsSection, + } + + class _CupertinoDialogAlertContentSection : StatelessWidget { + public _CupertinoDialogAlertContentSection( + Key key = null, + Widget title = null, + Widget content = null, + ScrollController scrollController = null + ) : base(key: key) { + this.title = title; + this.content = content; + this.scrollController = scrollController; + } + + public readonly Widget title; + public readonly Widget content; + public readonly ScrollController scrollController; + + public override Widget build(BuildContext context) { + float textScaleFactor = MediaQuery.of(context).textScaleFactor; + List titleContentGroup = new List(); + if (this.title != null) { + titleContentGroup.Add(new Padding( + padding: EdgeInsets.only( + left: CupertinoDialogUtils._kEdgePadding, + right: CupertinoDialogUtils._kEdgePadding, + bottom: this.content == null ? CupertinoDialogUtils._kEdgePadding : 1.0f, + top: CupertinoDialogUtils._kEdgePadding * textScaleFactor + ), + child: new DefaultTextStyle( + style: CupertinoDialogUtils._kCupertinoDialogTitleStyle, + textAlign: TextAlign.center, + child: this.title + ) + )); + } + + if (this.content != null) { + titleContentGroup.Add( + new Padding( + padding: EdgeInsets.only( + left: CupertinoDialogUtils._kEdgePadding, + right: CupertinoDialogUtils._kEdgePadding, + bottom: CupertinoDialogUtils._kEdgePadding * textScaleFactor, + top: this.title == null ? CupertinoDialogUtils._kEdgePadding : 1.0f + ), + child: new DefaultTextStyle( + style: CupertinoDialogUtils._kCupertinoDialogContentStyle, + textAlign: TextAlign.center, + child: this.content + ) + ) + ); + } + + if (titleContentGroup.isEmpty()) { + return new SingleChildScrollView( + controller: this.scrollController, + child: new Container(width: 0.0f, height: 0.0f) + ); + } + + return new CupertinoScrollbar( + child: new SingleChildScrollView( + controller: this.scrollController, + child: new Column( + mainAxisSize: MainAxisSize.max, + crossAxisAlignment: CrossAxisAlignment.stretch, + children: titleContentGroup + ) + ) + ); + } + } + + class _CupertinoDialogAlertActionSection : StatefulWidget { + public _CupertinoDialogAlertActionSection( + List children, + Key key = null, + ScrollController scrollController = null + ) : base(key: key) { + D.assert(children != null); + this.children = children; + this.scrollController = scrollController; + } + + public readonly List children; + public readonly ScrollController scrollController; + + public override State createState() { + return new _CupertinoDialogAlertActionSectionState(); + } + } + + class _CupertinoDialogAlertActionSectionState : State<_CupertinoDialogAlertActionSection> { + public override Widget build(BuildContext context) { + float devicePixelRatio = MediaQuery.of(context).devicePixelRatio; + List interactiveButtons = new List(); + for (int i = 0; i < this.widget.children.Count; i += 1) { + interactiveButtons.Add( + new _PressableActionButton( + child: this.widget.children[i] + ) + ); + } + + return new CupertinoScrollbar( + child: new SingleChildScrollView( + controller: this.widget.scrollController, + child: new _CupertinoDialogActionsRenderWidget( + actionButtons: interactiveButtons, + dividerThickness: CupertinoDialogUtils._kDividerThickness / devicePixelRatio + ) + ) + ); + } + } + + class _PressableActionButton : StatefulWidget { + public _PressableActionButton( + Widget child + ) { + this.child = child; + } + + public readonly Widget child; + + public override State createState() { + return new _PressableActionButtonState(); + } + } + + class _PressableActionButtonState : State<_PressableActionButton> { + bool _isPressed = false; + + public override Widget build(BuildContext context) { + return new _ActionButtonParentDataWidget( + isPressed: this._isPressed, + child: new GestureDetector( + behavior: HitTestBehavior.opaque, + onTapDown: (TapDownDetails details) => this.setState(() => { this._isPressed = true; }), + onTapUp: (TapUpDetails details) => this.setState(() => { this._isPressed = false; }), + onTapCancel: () => this.setState(() => this._isPressed = false), + child: this.widget.child + ) + ); + } + } + + class _ActionButtonParentDataWidget : ParentDataWidget<_CupertinoDialogActionsRenderWidget> { + public _ActionButtonParentDataWidget( + Widget child, + bool isPressed = false, + Key key = null + ) : base(key: key, child: child) { + this.isPressed = isPressed; + } + + public readonly bool isPressed; + + public override void applyParentData(RenderObject renderObject) { + D.assert(renderObject.parentData is _ActionButtonParentData); + _ActionButtonParentData parentData = renderObject.parentData as _ActionButtonParentData; + if (parentData.isPressed != this.isPressed) { + parentData.isPressed = this.isPressed; + AbstractNodeMixinDiagnosticableTree targetParent = renderObject.parent; + if (targetParent is RenderObject) { + ((RenderObject) targetParent).markNeedsPaint(); + } + } + } + } + + class _ActionButtonParentData : MultiChildLayoutParentData { + public _ActionButtonParentData( + bool isPressed = false + ) { + this.isPressed = isPressed; + } + + public bool isPressed; + } + + public class CupertinoDialogAction : StatelessWidget { + public CupertinoDialogAction( + Widget child, + VoidCallback onPressed = null, + bool isDefaultAction = false, + bool isDestructiveAction = false, + TextStyle textStyle = null + ) { + D.assert(child != null); + this.onPressed = onPressed; + this.isDefaultAction = isDefaultAction; + this.isDestructiveAction = isDestructiveAction; + this.textStyle = textStyle; + this.child = child; + } + + public readonly VoidCallback onPressed; + public readonly bool isDefaultAction; + public readonly bool isDestructiveAction; + public readonly TextStyle textStyle; + public readonly Widget child; + + public bool enabled { + get { return this.onPressed != null; } + } + + float _calculatePadding(BuildContext context) { + return 8.0f * MediaQuery.textScaleFactorOf(context); + } + + Widget _buildContentWithRegularSizingPolicy( + BuildContext context, + TextStyle textStyle, + Widget content + ) { + bool isInAccessibilityMode = CupertinoDialogUtils._isInAccessibilityMode(context); + float dialogWidth = isInAccessibilityMode + ? CupertinoDialogUtils._kAccessibilityCupertinoDialogWidth + : CupertinoDialogUtils._kCupertinoDialogWidth; + float textScaleFactor = MediaQuery.textScaleFactorOf(context); + float fontSizeRatio = + (textScaleFactor * textStyle.fontSize) / CupertinoDialogUtils._kMinButtonFontSize ?? 0f; + float padding = this._calculatePadding(context); + return new IntrinsicHeight( + child: new SizedBox( + width: float.PositiveInfinity, + child: new FittedBox( + fit: BoxFit.scaleDown, + child: new ConstrainedBox( + constraints: new BoxConstraints( + maxWidth: fontSizeRatio * (dialogWidth - (2 * padding)) + ), + child: new DefaultTextStyle( + style: textStyle, + textAlign: TextAlign.center, + overflow: TextOverflow.ellipsis, + maxLines: 1, + child: content + ) + ) + ) + ) + ); + } + + Widget _buildContentWithAccessibilitySizingPolicy( + TextStyle textStyle, + Widget content + ) { + return new DefaultTextStyle( + style: textStyle, + textAlign: TextAlign.center, + child: content + ); + } + + public override Widget build(BuildContext context) { + TextStyle style = CupertinoDialogUtils._kCupertinoDialogActionStyle; + style = style.merge(this.textStyle); + if (this.isDestructiveAction) { + style = style.copyWith(color: CupertinoColors.destructiveRed); + } + + if (!this.enabled) { + style = style.copyWith(color: style.color.withOpacity(0.5f)); + } + + Widget sizedContent = CupertinoDialogUtils._isInAccessibilityMode(context) + ? this._buildContentWithAccessibilitySizingPolicy( + textStyle: style, + content: this.child + ) + : this._buildContentWithRegularSizingPolicy( + context: context, + textStyle: style, + content: this.child + ); + return new GestureDetector( + onTap: () => this.onPressed(), + behavior: HitTestBehavior.opaque, + child: new ConstrainedBox( + constraints: new BoxConstraints( + minHeight: CupertinoDialogUtils._kMinButtonHeight + ), + child: new Container( + alignment: Alignment.center, + padding: EdgeInsets.all(this._calculatePadding(context)), + child: sizedContent + ) + ) + ); + } + } + + class _CupertinoDialogActionsRenderWidget : MultiChildRenderObjectWidget { + public _CupertinoDialogActionsRenderWidget( + List actionButtons, + Key key = null, + float dividerThickness = 0.0f + ) : base(key: key, children: actionButtons) { + this._dividerThickness = dividerThickness; + } + + public readonly float _dividerThickness; + + public override RenderObject createRenderObject(BuildContext context) { + return new _RenderCupertinoDialogActions( + dialogWidth: CupertinoDialogUtils._isInAccessibilityMode(context) + ? CupertinoDialogUtils._kAccessibilityCupertinoDialogWidth + : CupertinoDialogUtils._kCupertinoDialogWidth, + dividerThickness: this._dividerThickness + ); + } + + public override void updateRenderObject(BuildContext context, RenderObject renderObject) { + (renderObject as _RenderCupertinoDialogActions).dialogWidth = + CupertinoDialogUtils._isInAccessibilityMode(context) + ? CupertinoDialogUtils._kAccessibilityCupertinoDialogWidth + : CupertinoDialogUtils._kCupertinoDialogWidth; + (renderObject as _RenderCupertinoDialogActions).dividerThickness = this._dividerThickness; + } + } + + class _RenderCupertinoDialogActions : RenderBoxContainerDefaultsMixinContainerRenderObjectMixinRenderBox< + RenderBox, MultiChildLayoutParentData> { + public _RenderCupertinoDialogActions( + float dialogWidth, + List children = null, + float dividerThickness = 0.0f + ) { + this._dialogWidth = dialogWidth; + this._dividerThickness = dividerThickness; + this.addAll(children); + } + + public float dialogWidth { + get { return this._dialogWidth; } + set { + if (value != this._dialogWidth) { + this._dialogWidth = value; + this.markNeedsLayout(); + } + } + } + + float _dialogWidth; + + + public float dividerThickness { + get { return this._dividerThickness; } + set { + if (value != this._dividerThickness) { + this._dividerThickness = value; + this.markNeedsLayout(); + } + } + } + + float _dividerThickness; + + readonly Paint _buttonBackgroundPaint = new Paint() { + color = CupertinoDialogUtils._kDialogColor, + style = PaintingStyle.fill + }; + + readonly Paint _pressedButtonBackgroundPaint = new Paint() { + color = CupertinoDialogUtils._kDialogPressedColor, + style = PaintingStyle.fill + }; + + + readonly Paint _dividerPaint = new Paint() { + color = CupertinoDialogUtils._kButtonDividerColor, + style = PaintingStyle.fill + }; + + List _pressedButtons { + get { + List childList = new List(); + + RenderBox currentChild = this.firstChild; + while (currentChild != null) { + D.assert(currentChild.parentData is _ActionButtonParentData); + _ActionButtonParentData parentData = currentChild.parentData as _ActionButtonParentData; + if (parentData.isPressed) { + childList.Add(currentChild); + } + + currentChild = this.childAfter(currentChild); + } + + return childList; + } + } + + bool _isButtonPressed { + get { + RenderBox currentChild = this.firstChild; + while (currentChild != null) { + D.assert(currentChild.parentData is _ActionButtonParentData); + _ActionButtonParentData parentData = currentChild.parentData as _ActionButtonParentData; + if (parentData.isPressed) { + return true; + } + + currentChild = this.childAfter(currentChild); + } + + return false; + } + } + + public override void setupParentData(RenderObject child) { + if (!(child.parentData is _ActionButtonParentData)) { + child.parentData = new _ActionButtonParentData(); + } + } + + protected override float computeMinIntrinsicWidth(float height) { + return this.dialogWidth; + } + + protected override float computeMaxIntrinsicWidth(float height) { + return this.dialogWidth; + } + + protected override float computeMinIntrinsicHeight(float width) { + float minHeight; + if (this.childCount == 0) { + minHeight = 0.0f; + } + else if (this.childCount == 1) { + minHeight = this._computeMinIntrinsicHeightSideBySide(width); + } + else { + if (this.childCount == 2 && this._isSingleButtonRow(width)) { + minHeight = this._computeMinIntrinsicHeightSideBySide(width); + } + else { + minHeight = this._computeMinIntrinsicHeightStacked(width); + } + } + + return minHeight; + } + + float _computeMinIntrinsicHeightSideBySide(float width) { + D.assert(this.childCount >= 1 && this.childCount <= 2); + float minHeight; + if (this.childCount == 1) { + minHeight = this.firstChild.getMinIntrinsicHeight(width); + } + else { + float perButtonWidth = (width - this.dividerThickness) / 2.0f; + minHeight = Mathf.Max(this.firstChild.getMinIntrinsicHeight(perButtonWidth), + this.lastChild.getMinIntrinsicHeight(perButtonWidth) + ); + } + + return minHeight; + } + + float _computeMinIntrinsicHeightStacked(float width) { + D.assert(this.childCount >= 2); + return this.firstChild.getMinIntrinsicHeight(width) + + this.dividerThickness + + (0.5f * this.childAfter(this.firstChild).getMinIntrinsicHeight(width)); + } + + protected internal override float computeMaxIntrinsicHeight(float width) { + float maxHeight; + if (this.childCount == 0) { + maxHeight = 0.0f; + } + else if (this.childCount == 1) { + maxHeight = this.firstChild.getMaxIntrinsicHeight(width); + } + else if (this.childCount == 2) { + if (this._isSingleButtonRow(width)) { + float perButtonWidth = (width - this.dividerThickness) / 2.0f; + maxHeight = Mathf.Max(this.firstChild.getMaxIntrinsicHeight(perButtonWidth), + this.lastChild.getMaxIntrinsicHeight(perButtonWidth) + ); + } + else { + maxHeight = this._computeMaxIntrinsicHeightStacked(width); + } + } + else { + maxHeight = this._computeMaxIntrinsicHeightStacked(width); + } + + return maxHeight; + } + + float _computeMaxIntrinsicHeightStacked(float width) { + D.assert(this.childCount >= 2); + float allDividersHeight = (this.childCount - 1) * this.dividerThickness; + float heightAccumulation = allDividersHeight; + RenderBox button = this.firstChild; + while (button != null) { + heightAccumulation += button.getMaxIntrinsicHeight(width); + button = this.childAfter(button); + } + + return heightAccumulation; + } + + bool _isSingleButtonRow(float width) { + bool isSingleButtonRow; + if (this.childCount == 1) { + isSingleButtonRow = true; + } + else if (this.childCount == 2) { + float sideBySideWidth = this.firstChild.getMaxIntrinsicWidth(float.PositiveInfinity) + + this.dividerThickness + + this.lastChild.getMaxIntrinsicWidth(float.PositiveInfinity); + isSingleButtonRow = sideBySideWidth <= width; + } + else { + isSingleButtonRow = false; + } + + return isSingleButtonRow; + } + + protected override void performLayout() { + if (this._isSingleButtonRow(this.dialogWidth)) { + if (this.childCount == 1) { + this.firstChild.layout( + this.constraints, + parentUsesSize: true + ); + this.size = this.constraints.constrain( + new Size(this.dialogWidth, this.firstChild.size.height) + ); + } + else { + BoxConstraints perButtonnewraints = new BoxConstraints( + minWidth: (this.constraints.minWidth - this.dividerThickness) / 2.0f, + maxWidth: (this.constraints.maxWidth - this.dividerThickness) / 2.0f, + minHeight: 0.0f, + maxHeight: float.PositiveInfinity + ); + this.firstChild.layout( + perButtonnewraints, + parentUsesSize: true + ); + this.lastChild.layout( + perButtonnewraints, + parentUsesSize: true + ); + D.assert(this.lastChild.parentData is MultiChildLayoutParentData); + MultiChildLayoutParentData secondButtonParentData = + this.lastChild.parentData as MultiChildLayoutParentData; + secondButtonParentData.offset = + new Offset(this.firstChild.size.width + this.dividerThickness, 0.0f); + this.size = this.constraints.constrain( + new Size(this.dialogWidth, + Mathf.Max(this.firstChild.size.height, this.lastChild.size.height + ) + ) + ); + } + } + else { + BoxConstraints perButtonnewraints = this.constraints.copyWith( + minHeight: 0.0f, + maxHeight: float.PositiveInfinity + ); + RenderBox child = this.firstChild; + int index = 0; + float verticalOffset = 0.0f; + while (child != null) { + child.layout( + perButtonnewraints, + parentUsesSize: true + ); + D.assert(child.parentData is MultiChildLayoutParentData); + MultiChildLayoutParentData parentData = child.parentData as MultiChildLayoutParentData; + parentData.offset = new Offset(0.0f, verticalOffset); + verticalOffset += child.size.height; + if (index < this.childCount - 1) { + verticalOffset += this.dividerThickness; + } + + index += 1; + child = this.childAfter(child); + } + + this.size = this.constraints.constrain( + new Size(this.dialogWidth, verticalOffset) + ); + } + } + + public override void paint(PaintingContext context, Offset offset) { + Canvas canvas = context.canvas; + if (this._isSingleButtonRow(this.size.width)) { + this._drawButtonBackgroundsAndDividersSingleRow(canvas, offset); + } + else { + this._drawButtonBackgroundsAndDividersStacked(canvas, offset); + } + + this._drawButtons(context, offset); + } + + void _drawButtonBackgroundsAndDividersSingleRow(Canvas canvas, Offset offset) { + Rect verticalDivider = this.childCount == 2 && !this._isButtonPressed + ? Rect.fromLTWH( + offset.dx + this.firstChild.size.width, + offset.dy, this.dividerThickness, + Mathf.Max(this.firstChild.size.height, this.lastChild.size.height + ) + ) + : Rect.zero; + List pressedButtonRects = new List(); + + foreach (var item in this._pressedButtons) { + MultiChildLayoutParentData buttonParentData = item.parentData as MultiChildLayoutParentData; + pressedButtonRects.Add( + Rect.fromLTWH( + offset.dx + buttonParentData.offset.dx, + offset.dy + buttonParentData.offset.dy, + item.size.width, + item.size.height + )); + } + + Path backgroundFillPath = new Path(); + + // backgroundFillPath.fillType = PathFillType.evenOdd; + backgroundFillPath.addRect(Rect.fromLTWH(0.0f, 0.0f, this.size.width, this.size.height)); + backgroundFillPath.addRect(verticalDivider); + + for (int i = 0; i < pressedButtonRects.Count; i += 1) { + backgroundFillPath.addRect(pressedButtonRects[i]); + } + + canvas.drawPath( + backgroundFillPath, this._buttonBackgroundPaint + ); + Path pressedBackgroundFillPath = new Path(); + for (int i = 0; i < pressedButtonRects.Count; i += 1) { + pressedBackgroundFillPath.addRect(pressedButtonRects[i]); + } + + canvas.drawPath( + pressedBackgroundFillPath, this._pressedButtonBackgroundPaint + ); + Path dividersPath = new Path(); + dividersPath.addRect(verticalDivider); + canvas.drawPath( + dividersPath, this._dividerPaint + ); + } + + void _drawButtonBackgroundsAndDividersStacked(Canvas canvas, Offset offset) { + Offset dividerOffset = new Offset(0.0f, this.dividerThickness); + Path backgroundFillPath = new Path(); + // ..fillType = PathFillType.evenOdd + backgroundFillPath.addRect(Rect.fromLTWH(0.0f, 0.0f, this.size.width, this.size.height)); + Path pressedBackgroundFillPath = new Path(); + Path dividersPath = new Path(); + Offset accumulatingOffset = offset; + RenderBox child = this.firstChild; + RenderBox prevChild = null; + + while (child != null) { + D.assert(child.parentData is _ActionButtonParentData); + _ActionButtonParentData currentButtonParentData = child.parentData as _ActionButtonParentData; + bool isButtonPressed = currentButtonParentData.isPressed; + bool isPrevButtonPressed = false; + if (prevChild != null) { + D.assert(prevChild.parentData is _ActionButtonParentData); + _ActionButtonParentData previousButtonParentData = prevChild.parentData as _ActionButtonParentData; + isPrevButtonPressed = previousButtonParentData.isPressed; + } + + bool isDividerPresent = child != this.firstChild; + bool isDividerPainted = isDividerPresent && !(isButtonPressed || isPrevButtonPressed); + Rect dividerRect = Rect.fromLTWH( + accumulatingOffset.dx, + accumulatingOffset.dy, this.size.width, this.dividerThickness + ); + Rect buttonBackgroundRect = Rect.fromLTWH( + accumulatingOffset.dx, + accumulatingOffset.dy + (isDividerPresent ? this.dividerThickness : 0.0f), this.size.width, + child.size.height + ); + if (isButtonPressed) { + backgroundFillPath.addRect(buttonBackgroundRect); + pressedBackgroundFillPath.addRect(buttonBackgroundRect); + } + + if (isDividerPainted) { + backgroundFillPath.addRect(dividerRect); + dividersPath.addRect(dividerRect); + } + + accumulatingOffset += (isDividerPresent ? dividerOffset : Offset.zero) + + new Offset(0.0f, child.size.height); + prevChild = child; + child = this.childAfter(child); + } + + canvas.drawPath(backgroundFillPath, this._buttonBackgroundPaint); + canvas.drawPath(pressedBackgroundFillPath, this._pressedButtonBackgroundPaint); + canvas.drawPath(dividersPath, this._dividerPaint); + } + + void _drawButtons(PaintingContext context, Offset offset) { + RenderBox child = this.firstChild; + while (child != null) { + MultiChildLayoutParentData childParentData = child.parentData as MultiChildLayoutParentData; + context.paintChild(child, childParentData.offset + offset); + child = this.childAfter(child); + } + } + + protected override bool hitTestChildren(HitTestResult result, + Offset position = null + ) { + return this.defaultHitTestChildren(result, position: position); + } + } +} \ No newline at end of file diff --git a/Runtime/cupertino/dialog.cs.meta b/Runtime/cupertino/dialog.cs.meta new file mode 100644 index 00000000..555583a6 --- /dev/null +++ b/Runtime/cupertino/dialog.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: e184ed6bf781845be961798e888aa6ef +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Runtime/cupertino/route.cs b/Runtime/cupertino/route.cs index 9e1d8b54..3b56263a 100644 --- a/Runtime/cupertino/route.cs +++ b/Runtime/cupertino/route.cs @@ -58,11 +58,11 @@ public class CupertinoRouteUtils { ); - public static IPromise showCupertinoModalPopup( + public static IPromise showCupertinoModalPopup( BuildContext context, WidgetBuilder builder ) { - return (IPromise) Navigator.of(context, rootNavigator: true).push( + return Navigator.of(context, rootNavigator: true).push( new _CupertinoModalPopupRoute( builder: builder, barrierLabel: "Dismiss" @@ -97,18 +97,17 @@ public static Widget _buildCupertinoDialogTransitions(BuildContext context, Anim ); } - public static IPromise showCupertinoDialog( + public static IPromise showCupertinoDialog( BuildContext context, WidgetBuilder builder ) { D.assert(builder != null); - return (IPromise) DialogUtils.showGeneralDialog( + return DialogUtils.showGeneralDialog( context: context, barrierDismissible: false, barrierColor: _kModalBarrierColor, transitionDuration: new TimeSpan(0, 0, 0, 0, 250), - pageBuilder: - (BuildContext _context, Animation animation, Animation secondaryAnimation) => { + pageBuilder: (BuildContext _context, Animation animation, Animation secondaryAnimation) => { return builder(_context); }, transitionBuilder: _buildCupertinoDialogTransitions diff --git a/Runtime/material/chip.cs b/Runtime/material/chip.cs index c464b353..320a6d35 100644 --- a/Runtime/material/chip.cs +++ b/Runtime/material/chip.cs @@ -2104,7 +2104,7 @@ protected override float computeMinIntrinsicHeight(float width) { ); } - protected override float computeMaxIntrinsicHeight(float width) { + protected internal override float computeMaxIntrinsicHeight(float width) { return this.computeMinIntrinsicHeight(width); } diff --git a/Runtime/material/input_decorator.cs b/Runtime/material/input_decorator.cs index 8269303f..fd7046b1 100644 --- a/Runtime/material/input_decorator.cs +++ b/Runtime/material/input_decorator.cs @@ -1166,7 +1166,7 @@ protected override float computeMinIntrinsicHeight(float width) { + this.contentPadding.bottom; } - protected override float computeMaxIntrinsicHeight(float width) { + protected internal override float computeMaxIntrinsicHeight(float width) { return this.computeMinIntrinsicHeight(width); } diff --git a/Runtime/material/list_tile.cs b/Runtime/material/list_tile.cs index 186f008b..c91b9fb8 100644 --- a/Runtime/material/list_tile.cs +++ b/Runtime/material/list_tile.cs @@ -749,7 +749,7 @@ protected override float computeMinIntrinsicHeight(float width) { this.title.getMinIntrinsicHeight(width) + this.subtitle?.getMinIntrinsicHeight(width) ?? 0.0f); } - protected override float computeMaxIntrinsicHeight(float width) { + protected internal override float computeMaxIntrinsicHeight(float width) { return this.computeMinIntrinsicHeight(width); } diff --git a/Runtime/material/slider.cs b/Runtime/material/slider.cs index d91bd70a..048e7242 100644 --- a/Runtime/material/slider.cs +++ b/Runtime/material/slider.cs @@ -698,7 +698,7 @@ protected override float computeMinIntrinsicHeight(float width) { return Mathf.Max(this._minPreferredTrackHeight, this._maxSliderPartHeight); } - protected override float computeMaxIntrinsicHeight(float width) { + protected internal override float computeMaxIntrinsicHeight(float width) { return Mathf.Max(this._minPreferredTrackHeight, this._maxSliderPartHeight); } diff --git a/Runtime/rendering/box.cs b/Runtime/rendering/box.cs index 787543b9..54321bf6 100644 --- a/Runtime/rendering/box.cs +++ b/Runtime/rendering/box.cs @@ -772,7 +772,7 @@ public float getMaxIntrinsicHeight(float width) { this.computeMaxIntrinsicHeight); } - protected virtual float computeMaxIntrinsicHeight(float width) { + protected internal virtual float computeMaxIntrinsicHeight(float width) { return 0.0f; } diff --git a/Runtime/rendering/custom_layout.cs b/Runtime/rendering/custom_layout.cs index f3f6c9f5..536ae8f4 100644 --- a/Runtime/rendering/custom_layout.cs +++ b/Runtime/rendering/custom_layout.cs @@ -233,7 +233,7 @@ protected override float computeMinIntrinsicHeight(float width) { return 0.0f; } - protected override float computeMaxIntrinsicHeight(float width) { + protected internal override float computeMaxIntrinsicHeight(float width) { float height = this._getSize(BoxConstraints.tightForFinite(width: width)).height; if (height.isFinite()) { return height; diff --git a/Runtime/rendering/editable.cs b/Runtime/rendering/editable.cs index bd588052..619f40be 100644 --- a/Runtime/rendering/editable.cs +++ b/Runtime/rendering/editable.cs @@ -1017,7 +1017,7 @@ protected override float computeMinIntrinsicHeight(float width) { return this._preferredHeight(width); } - protected override float computeMaxIntrinsicHeight(float width) { + protected internal override float computeMaxIntrinsicHeight(float width) { return this._preferredHeight(width); } diff --git a/Runtime/rendering/flex.cs b/Runtime/rendering/flex.cs index 569ff61b..4e9037d4 100644 --- a/Runtime/rendering/flex.cs +++ b/Runtime/rendering/flex.cs @@ -274,7 +274,7 @@ protected override float computeMinIntrinsicHeight(float width) { ); } - protected override float computeMaxIntrinsicHeight(float width) { + protected internal override float computeMaxIntrinsicHeight(float width) { return this._getIntrinsicSize( sizingDirection: Axis.vertical, extent: width, diff --git a/Runtime/rendering/image.cs b/Runtime/rendering/image.cs index d7981867..1b2af006 100644 --- a/Runtime/rendering/image.cs +++ b/Runtime/rendering/image.cs @@ -259,7 +259,7 @@ protected override float computeMinIntrinsicHeight(float width) { return this._sizeForConstraints(BoxConstraints.tightForFinite(width: width)).height; } - protected override float computeMaxIntrinsicHeight(float width) { + protected internal override float computeMaxIntrinsicHeight(float width) { D.assert(width >= 0.0); return this._sizeForConstraints(BoxConstraints.tightForFinite(width: width)).height; } diff --git a/Runtime/rendering/list_body.cs b/Runtime/rendering/list_body.cs index 090737e6..1c1ef934 100644 --- a/Runtime/rendering/list_body.cs +++ b/Runtime/rendering/list_body.cs @@ -253,7 +253,7 @@ protected override float computeMinIntrinsicHeight(float width) { } - protected override float computeMaxIntrinsicHeight(float width) { + protected internal override float computeMaxIntrinsicHeight(float width) { switch (this.mainAxis) { case Axis.horizontal: return this._getIntrinsicMainAxis((RenderBox child) => child.getMaxIntrinsicHeight(width)); diff --git a/Runtime/rendering/paragraph.cs b/Runtime/rendering/paragraph.cs index e3bd2d58..baca4fa5 100644 --- a/Runtime/rendering/paragraph.cs +++ b/Runtime/rendering/paragraph.cs @@ -214,7 +214,7 @@ protected override float computeMinIntrinsicHeight(float width) { return this._computeIntrinsicHeight(width); } - protected override float computeMaxIntrinsicHeight(float width) { + protected internal override float computeMaxIntrinsicHeight(float width) { return this._computeIntrinsicHeight(width); } diff --git a/Runtime/rendering/performance_overlay.cs b/Runtime/rendering/performance_overlay.cs index f9dca3e8..ba743f10 100644 --- a/Runtime/rendering/performance_overlay.cs +++ b/Runtime/rendering/performance_overlay.cs @@ -62,7 +62,7 @@ protected override float computeMinIntrinsicHeight(float width) { return this._intrinsicHeight; } - protected override float computeMaxIntrinsicHeight(float width) { + protected internal override float computeMaxIntrinsicHeight(float width) { return this._intrinsicHeight; } diff --git a/Runtime/rendering/proxy_box.cs b/Runtime/rendering/proxy_box.cs index 6f1d88f6..4eac4bd1 100644 --- a/Runtime/rendering/proxy_box.cs +++ b/Runtime/rendering/proxy_box.cs @@ -125,7 +125,7 @@ protected override float computeMinIntrinsicHeight(float width) { return height; } - protected override float computeMaxIntrinsicHeight(float width) { + protected internal override float computeMaxIntrinsicHeight(float width) { if (this._additionalConstraints.hasBoundedHeight && this._additionalConstraints.hasTightHeight) { return this._additionalConstraints.minHeight; } @@ -300,7 +300,7 @@ protected override float computeMinIntrinsicHeight(float width) { return 0.0f; } - protected override float computeMaxIntrinsicHeight(float width) { + protected internal override float computeMaxIntrinsicHeight(float width) { if (width.isFinite()) { return width / this._aspectRatio; } @@ -435,7 +435,7 @@ protected override float computeMinIntrinsicHeight(float width) { return _applyStep(height, this._stepHeight); } - protected override float computeMaxIntrinsicHeight(float width) { + protected internal override float computeMaxIntrinsicHeight(float width) { if (this.child == null) { return 0.0f; } @@ -2364,7 +2364,7 @@ protected override float computeMinIntrinsicHeight(float width) { return base.computeMinIntrinsicHeight(width); } - protected override float computeMaxIntrinsicHeight(float width) { + protected internal override float computeMaxIntrinsicHeight(float width) { if (this.offstage) { return 0.0f; } diff --git a/Runtime/rendering/proxy_box.mixin.gen.cs b/Runtime/rendering/proxy_box.mixin.gen.cs index 07b42182..372e0485 100644 --- a/Runtime/rendering/proxy_box.mixin.gen.cs +++ b/Runtime/rendering/proxy_box.mixin.gen.cs @@ -37,7 +37,7 @@ protected override float computeMinIntrinsicHeight(float width) { return 0.0f; } - protected override float computeMaxIntrinsicHeight(float width) { + protected internal override float computeMaxIntrinsicHeight(float width) { if (this.child != null) { return this.child.getMaxIntrinsicHeight(width); } diff --git a/Runtime/rendering/rotated_box.cs b/Runtime/rendering/rotated_box.cs index d479cfde..362366ab 100644 --- a/Runtime/rendering/rotated_box.cs +++ b/Runtime/rendering/rotated_box.cs @@ -64,7 +64,7 @@ protected override float computeMinIntrinsicHeight(float width) { return this._isVertical ? this.child.getMinIntrinsicWidth(width) : this.child.getMinIntrinsicHeight(width); } - protected override float computeMaxIntrinsicHeight(float width) { + protected internal override float computeMaxIntrinsicHeight(float width) { if (this.child == null) { return 0.0f; } diff --git a/Runtime/rendering/shifted_box.cs b/Runtime/rendering/shifted_box.cs index 5a867bd0..5197ead7 100644 --- a/Runtime/rendering/shifted_box.cs +++ b/Runtime/rendering/shifted_box.cs @@ -36,7 +36,7 @@ protected override float computeMinIntrinsicHeight(float width) { return 0.0f; } - protected override float computeMaxIntrinsicHeight(float width) { + protected internal override float computeMaxIntrinsicHeight(float width) { if (this.child != null) { return this.child.getMaxIntrinsicHeight(width); } @@ -135,7 +135,7 @@ protected override float computeMinIntrinsicHeight(float width) { return this._padding.vertical; } - protected override float computeMaxIntrinsicHeight(float width) { + protected internal override float computeMaxIntrinsicHeight(float width) { if (this.child != null) { return this.child.getMaxIntrinsicHeight(Mathf.Max(0.0f, width - this._padding.horizontal)) + this._padding.vertical; @@ -566,7 +566,7 @@ protected override float computeMinIntrinsicHeight(float width) { return this._requestedSize.height; } - protected override float computeMaxIntrinsicHeight(float width) { + protected internal override float computeMaxIntrinsicHeight(float width) { return this._requestedSize.height; } @@ -687,7 +687,7 @@ protected override float computeMinIntrinsicHeight(float width) { return result / (this._heightFactor ?? 1.0f); } - protected override float computeMaxIntrinsicHeight(float width) { + protected internal override float computeMaxIntrinsicHeight(float width) { float result; if (this.child == null) { result = base.computeMaxIntrinsicHeight(width); @@ -807,7 +807,7 @@ protected override float computeMinIntrinsicHeight(float width) { return 0.0f; } - protected override float computeMaxIntrinsicHeight(float width) { + protected internal override float computeMaxIntrinsicHeight(float width) { float height = this._getSize(BoxConstraints.tightForFinite(width: width)).height; if (height.isFinite()) { return height; diff --git a/Runtime/rendering/stack.cs b/Runtime/rendering/stack.cs index 6494b6c8..e78be2e5 100644 --- a/Runtime/rendering/stack.cs +++ b/Runtime/rendering/stack.cs @@ -300,7 +300,7 @@ protected override float computeMinIntrinsicHeight(float width) { return this._getIntrinsicDimension((RenderBox child) => child.getMinIntrinsicHeight(width)); } - protected override float computeMaxIntrinsicHeight(float width) { + protected internal override float computeMaxIntrinsicHeight(float width) { return this._getIntrinsicDimension((RenderBox child) => child.getMaxIntrinsicHeight(width)); } diff --git a/Runtime/rendering/table.cs b/Runtime/rendering/table.cs index 99f75bd8..f2022b3b 100644 --- a/Runtime/rendering/table.cs +++ b/Runtime/rendering/table.cs @@ -708,7 +708,7 @@ protected override float computeMinIntrinsicHeight(float width) { return rowTop; } - protected override float computeMaxIntrinsicHeight(float width) { + protected internal override float computeMaxIntrinsicHeight(float width) { return this.computeMinIntrinsicHeight(width); } diff --git a/Runtime/rendering/viewport.cs b/Runtime/rendering/viewport.cs index 357b6b4e..ff8298d9 100644 --- a/Runtime/rendering/viewport.cs +++ b/Runtime/rendering/viewport.cs @@ -185,7 +185,7 @@ protected override float computeMinIntrinsicHeight(float width) { return 0.0f; } - protected override float computeMaxIntrinsicHeight(float width) { + protected internal override float computeMaxIntrinsicHeight(float width) { D.assert(this.debugThrowIfNotCheckingIntrinsics()); return 0.0f; } diff --git a/Runtime/rendering/wrap.cs b/Runtime/rendering/wrap.cs index 55a729b1..bc943154 100644 --- a/Runtime/rendering/wrap.cs +++ b/Runtime/rendering/wrap.cs @@ -362,7 +362,7 @@ protected override float computeMinIntrinsicHeight(float width) { throw new Exception("Unknown axis: " + this.direction); } - protected override float computeMaxIntrinsicHeight(float width) { + protected internal override float computeMaxIntrinsicHeight(float width) { switch (this.direction) { case Axis.horizontal: return this._computeIntrinsicHeightForWidth(width); diff --git a/Runtime/widgets/layout_builder.cs b/Runtime/widgets/layout_builder.cs index f53b2072..6bdf74ee 100644 --- a/Runtime/widgets/layout_builder.cs +++ b/Runtime/widgets/layout_builder.cs @@ -158,7 +158,7 @@ protected override float computeMinIntrinsicHeight(float width) { return 0.0f; } - protected override float computeMaxIntrinsicHeight(float width) { + protected internal override float computeMaxIntrinsicHeight(float width) { D.assert(this._debugThrowIfNotCheckingIntrinsics()); return 0.0f; } diff --git a/Runtime/widgets/single_child_scroll_view.cs b/Runtime/widgets/single_child_scroll_view.cs index a155a1c7..14cb693a 100644 --- a/Runtime/widgets/single_child_scroll_view.cs +++ b/Runtime/widgets/single_child_scroll_view.cs @@ -296,7 +296,7 @@ protected override float computeMinIntrinsicHeight(float width) { return 0.0f; } - protected override float computeMaxIntrinsicHeight(float width) { + protected internal override float computeMaxIntrinsicHeight(float width) { if (this.child != null) { return this.child.getMaxIntrinsicHeight(width); } diff --git a/Samples/UIWidgetsGallery/demo/cupertino/cupertino_alert_demo.cs b/Samples/UIWidgetsGallery/demo/cupertino/cupertino_alert_demo.cs index 928fdea8..d110f0e2 100644 --- a/Samples/UIWidgetsGallery/demo/cupertino/cupertino_alert_demo.cs +++ b/Samples/UIWidgetsGallery/demo/cupertino/cupertino_alert_demo.cs @@ -5,10 +5,12 @@ using Unity.UIWidgets.widgets; namespace UIWidgetsGallery.gallery { - /* class CupertinoAlertDemo : StatefulWidget { public static string routeName = "/cupertino/alert"; - public override State createState() => new _CupertinoAlertDemoState(); + + public override State createState() { + return new _CupertinoAlertDemoState(); + } } class _CupertinoAlertDemoState : State { @@ -18,12 +20,12 @@ void showDemoDialog( BuildContext context = null, Widget child = null ) { - CupertinoRouteUtils.showCupertinoDialog( + CupertinoRouteUtils.showCupertinoDialog( context: context, builder: (BuildContext _context) => child - ).Then((string value) => { + ).Then((object value) => { if (value != null) { - this.setState(() => { this.lastSelectedValue = value; }); + this.setState(() => { this.lastSelectedValue = value as string; }); } }); } @@ -32,12 +34,12 @@ void showDemoActionSheet( BuildContext context = null, Widget child = null ) { - CupertinoRouteUtils.showCupertinoModalPopup( + CupertinoRouteUtils.showCupertinoModalPopup( context: context, builder: (BuildContext _context) => child - ).Then((string value) => { + ).Then((object value) => { if (value != null) { - this.setState(() => { this.lastSelectedValue = value; }); + this.setState(() => { this.lastSelectedValue = value as string; }); } }); } @@ -64,7 +66,8 @@ public override Widget build(BuildContext context) { onPressed: () => { this.showDemoDialog( context: _context, - child: new CupertinoAlertDialog( + child: + new CupertinoAlertDialog( title: new Text("Discard draft?"), actions: new List { new CupertinoDialogAction( @@ -150,11 +153,9 @@ public override Widget build(BuildContext context) { context: _context, child: new CupertinoActionSheet( title: new Text("Favorite Dessert"), - message: - new Text( + message: new Text( "Please select the best dessert from the options below."), - actions: - new List { + actions: new List { new CupertinoActionSheetAction( child: new Text("Profiteroles"), onPressed: () => { @@ -170,14 +171,12 @@ public override Widget build(BuildContext context) { new CupertinoActionSheetAction( child: new Text("Trifle"), onPressed: () => { Navigator.pop(_context, "Trifle"); } - ), + ) }, cancelButton: new CupertinoActionSheetAction( child: new Text("Cancel"), - isDefaultAction: - true, - onPressed: - () => { Navigator.pop(_context, "Cancel"); } + isDefaultAction: true, + onPressed: () => { Navigator.pop(_context, "Cancel"); } ) ) ); @@ -191,7 +190,7 @@ public override Widget build(BuildContext context) { stackChildren.Add( new Positioned( bottom: 32.0f, - child: new Text("You selected: $lastSelectedValue") + child: new Text($"You selected: {this.lastSelectedValue}") ) ); } @@ -222,8 +221,8 @@ public CupertinoDessertDialog( public override Widget build(BuildContext context) { return new CupertinoAlertDialog( - title: title, - content: content, + title: this.title, + content: this.content, actions: new List { new CupertinoDialogAction( child: new Text("Cheesecake"), @@ -269,5 +268,4 @@ public override Widget build(BuildContext context) { ); } } - */ } \ No newline at end of file diff --git a/Samples/UIWidgetsGallery/gallery/demos.cs b/Samples/UIWidgetsGallery/gallery/demos.cs index be10d4f7..e0509fd6 100644 --- a/Samples/UIWidgetsGallery/gallery/demos.cs +++ b/Samples/UIWidgetsGallery/gallery/demos.cs @@ -483,14 +483,14 @@ static List _buildGalleryDemos() { // documentationUrl: "https://docs.flutter.io/flutter/cupertino/CupertinoActivityIndicator-class.html", // buildRoute: (BuildContext context) => CupertinoProgressIndicatorDemo() // ), - // new GalleryDemo( - // title: "Alerts", - // icon: GalleryIcons.dialogs, - // category: GalleryDemoCategory._kCupertinoComponents, - // routeName: CupertinoAlertDemo.routeName, - // documentationUrl: "https://docs.flutter.io/flutter/cupertino/showCupertinoDialog.html", - // buildRoute: (BuildContext context) => CupertinoAlertDemo() - // ), + new GalleryDemo( + title: "Alerts", + icon: GalleryIcons.dialogs, + category: _kCupertinoComponents, + routeName: CupertinoAlertDemo.routeName, + documentationUrl: "https://docs.flutter.io/flutter/cupertino/showCupertinoDialog.html", + buildRoute: (BuildContext context) => new CupertinoAlertDemo() + ), new GalleryDemo( title: "Buttons", icon: GalleryIcons.generic_buttons, From 8a8f16b0db47a73e65f4d0c4aa500db77d311ed1 Mon Sep 17 00:00:00 2001 From: iizzaya Date: Tue, 27 Aug 2019 15:24:22 +0800 Subject: [PATCH 3/5] [Cupertino] Add unfinished Navigation gallery demo. --- Runtime/cupertino/route.cs | 2 +- .../cupertino/cupertino_navigation_demo.cs | 841 +++++++++++++++++- .../cupertino_navigation_demo.cs.meta | 2 +- 3 files changed, 841 insertions(+), 4 deletions(-) diff --git a/Runtime/cupertino/route.cs b/Runtime/cupertino/route.cs index 3b56263a..a7230e28 100644 --- a/Runtime/cupertino/route.cs +++ b/Runtime/cupertino/route.cs @@ -239,7 +239,7 @@ public override void paint(Canvas canvas, Offset offset, ImageConfiguration conf public class CupertinoPageRoute : PageRoute { public CupertinoPageRoute( WidgetBuilder builder, - RouteSettings settings, + RouteSettings settings = null, string title = "", bool maintainState = true, bool fullscreenDialog = false diff --git a/Samples/UIWidgetsGallery/demo/cupertino/cupertino_navigation_demo.cs b/Samples/UIWidgetsGallery/demo/cupertino/cupertino_navigation_demo.cs index 2c4da0aa..b48f2c3d 100644 --- a/Samples/UIWidgetsGallery/demo/cupertino/cupertino_navigation_demo.cs +++ b/Samples/UIWidgetsGallery/demo/cupertino/cupertino_navigation_demo.cs @@ -1,5 +1,842 @@ +using System.Collections.Generic; +using RSG; +using Unity.UIWidgets.cupertino; +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 UnityEngine; +using Color = Unity.UIWidgets.ui.Color; + namespace UIWidgetsGallery.gallery { - public class cupertino_navigation_demo { - + /* + class CupertinoNavigationDemoUtils { + public const string _kGalleryAssetsPackage = "flutter_gallery_assets"; + + public const int _kChildCount = 50; + + public static List coolColors = new List { + Color.fromARGB(255, 255, 59, 48), + Color.fromARGB(255, 255, 149, 0), + Color.fromARGB(255, 255, 204, 0), + Color.fromARGB(255, 76, 217, 100), + Color.fromARGB(255, 90, 200, 250), + Color.fromARGB(255, 0, 122, 255), + Color.fromARGB(255, 88, 86, 214), + Color.fromARGB(255, 255, 45, 85), + }; + + public static List coolColorNames = new List { + "Sarcoline", "Coquelicot", "Smaragdine", "Mikado", "Glaucous", "Wenge", + "Fulvous", "Xanadu", "Falu", "Eburnean", "Amaranth", "Australien", + "Banan", "Falu", "Gingerline", "Incarnadine", "Labrador", "Nattier", + "Pervenche", "Sinoper", "Verditer", "Watchet", "Zafre", + }; + + public static Widget trailingButtons { + get { + return new Row( + mainAxisSize: MainAxisSize.min, + children: new List { + new CupertinoDemoDocumentationButton(CupertinoNavigationDemo.routeName), + new Padding(padding: EdgeInsets.only(left: 8.0f)), + new ExitButton(), + } + ); + } + } + + public static List buildTab2Conversation() { + return new List { + new Tab2ConversationRow( + text: "My Xanadu doesn't look right" + ), + new Tab2ConversationRow( + avatar: new Tab2ConversationAvatar( + text: "KL", + color: new Color(0xfFD5015) + ), + text: "We'll rush you a new one.\nIt's gonna be incredible" + ), + new Tab2ConversationRow( + text: "Awesome thanks!" + ), + new Tab2ConversationRow( + avatar: new Tab2ConversationAvatar( + text: "SJ", + color: new Color(0xf34CAD6) + ), + text: "We'll send you our\nnewest Labrador too!" + ), + new Tab2ConversationRow( + text: "Yay" + ), + new Tab2ConversationRow( + avatar: new Tab2ConversationAvatar( + text: "KL", + color: new Color(0xfFD5015) + ), + text: "Actually there's one more thing..." + ), + new Tab2ConversationRow( + text: "What's that ? " + ), + }; + } + + + class CupertinoNavigationDemo : StatelessWidget { + public CupertinoNavigationDemo() { + this.colorItems = new List(); + + for (int i = 0; i < _kChildCount; i++) { + this.colorItems.Add(coolColors[ + Random.Range(0, coolColors.Count) + ]); + } + + this.colorNameItems = new List(); + + for (int i = 0; i < _kChildCount; i++) { + this.colorNameItems.Add(coolColorNames[ + Random.Range(0, coolColorNames.Count) + ]); + } + } + + public static string routeName = "/cupertino/navigation"; + public readonly List colorItems; + public readonly List colorNameItems; + + public override Widget build(BuildContext context) { + return new WillPopScope( + onWillPop: () => new IPromise().value(true), + child: new DefaultTextStyle( + style: CupertinoTheme.of(context).textTheme.textStyle, + child: new CupertinoTabScaffold( + tabBar: new CupertinoTabBar( + items: new List { + new BottomNavigationBarItem( + icon: new Icon(CupertinoIcons.home), + title: new Text("Home") + ), + new BottomNavigationBarItem( + icon: new Icon(CupertinoIcons.conversation_bubble), + title: new Text("Support") + ), + new BottomNavigationBarItem( + icon: new Icon(CupertinoIcons.profile_circled), + title: new Text("Profile") + ) + } + ), + tabBuilder: (BuildContext _context, int index) => { + D.assert(index >= 0 && index <= 2); + switch (index) { + case 0: + return new CupertinoTabView( + builder: (BuildContext _context1) => { + return new CupertinoDemoTab1( + colorItems: this.colorItems, + colorNameItems: this.colorNameItems + ); + }, + defaultTitle: "Colors" + ); + break; + case 1: + return new CupertinoTabView( + builder: (BuildContext _context2) => new CupertinoDemoTab2(), + defaultTitle: "Support Chat" + ); + break; + case 2: + return new CupertinoTabView( + builder: (BuildContext _context3) => new CupertinoDemoTab3(), + defaultTitle: "Account" + ); + break; + } + + return null; + } + ) + ) + ); + } + } + + class ExitButton : StatelessWidget { + public ExitButton() { } + + public override Widget build(BuildContext context) { + return new CupertinoButton( + padding: EdgeInsets.zero, + child: new Tooltip( + message: "Back", + child: new Text("Exit") + ), + onPressed: () => { Navigator.of(context, rootNavigator: true).pop(); } + ); + } + } + + + class CupertinoDemoTab1 : StatelessWidget { + public CupertinoDemoTab1( + List colorItems = null, + List colorNameItems = null + ) { + this.colorItems = colorItems; + this.colorNameItems = colorNameItems; + } + + public readonly List colorItems; + public readonly List colorNameItems; + + public override Widget build(BuildContext context) { + return new CupertinoPageScaffold( + child: new CustomScrollView( + slivers: new List { + new CupertinoSliverNavigationBar( + trailing: trailingButtons + ), + new SliverPadding( + padding: MediaQuery.of(context).removePadding( + removeTop: true, + removeLeft: true, + removeRight: true + ).padding, + sliver: new SliverList( + del: new SliverChildBuilderDelegate( + (BuildContext _context, int index) => { + return new Tab1RowItem( + index: index, + lastItem: index == _kChildCount - 1, + color: this.colorItems[index], + colorName: this.colorNameItems[index] + ); + }, + childCount: _kChildCount + ) + ) + ) + } + ) + ); + } + } + + class Tab1RowItem : StatelessWidget { + public Tab1RowItem( + int index, + bool lastItem, + Color color, + string colorName + ) { + this.index = index; + this.lastItem = lastItem; + this.color = color; + this.colorName = colorName; + } + + public readonly int index; + public readonly bool lastItem; + public readonly Color color; + public readonly string colorName; + + public override Widget build(BuildContext context) { + Widget row = new GestureDetector( + behavior: HitTestBehavior.opaque, + onTap: () => { + Navigator.of(context).push(new CupertinoPageRoute( + title: this.colorName, + builder: (BuildContext _context) => new Tab1ItemPage( + color: this.color, + colorName: this.colorName, + index: this.index + ) + )); + }, + child: new SafeArea( + top: false, + bottom: false, + child: new Padding( + padding: EdgeInsets.only(left: 16.0f, top: 8.0f, bottom: 8.0f, right: 8.0f), + child: new Row( + children: new List { + new Container( + height: 60.0f, + width: 60.0f, + decoration: new BoxDecoration( + color: this.color, + borderRadius: BorderRadius.circular(8.0f) + ) + ), + new Expanded( + child: new Padding( + padding: EdgeInsets.symmetric(horizontal: 12.0f), + child: new Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: new List { + new Text(this.colorName), + new Padding(padding: EdgeInsets.only(top: 8.0f)), + new Text( + "Buy this cool color", + style: new TextStyle( + color: new Color(0xf8E8E93), + fontSize: 13.0f, + fontWeight: FontWeight.w300 + ) + ) + } + ) + ) + ), + new CupertinoButton( + padding: EdgeInsets.zero, + child: new Icon(CupertinoIcons.plus_circled + ), + onPressed: () => { } + ), + new CupertinoButton( + padding: EdgeInsets.zero, + child: new Icon(CupertinoIcons.share + ), + onPressed: () => { } + ) + } + ) + ) + ) + ); + if (this.lastItem) { + return row; + } + + return new Column( + children: new List { + row, + new Container( + height: 1.0f, + color: new Color(0xfD9D9D9) + ) + } + ); + } + } + + class Tab1ItemPage : StatefulWidget { + public Tab1ItemPage( + Color color, + string colorName, + int index + ) { + this.color = color; + this.colorName = colorName; + this.index = index; + } + + public readonly Color color; + public readonly string colorName; + public readonly int index; + + public override State createState() { + return new Tab1ItemPageState(); + } + } + + class Tab1ItemPageState : State { + public override void initState() { + base.initState(); + + for (int i = 0; i < 10; i++) { + this.relatedColors.Add( + Color.fromARGB( + 255, this.widget.color.red + Random.Range(0, 50).clamp(0, 255), + this.widget.color.green + Random.Range(0, 50).clamp(0, 255), + this.widget.color.blue + Random.Range(0, 50).clamp(0, 255) + ) + ); + } + } + + List relatedColors; + + public override Widget build(BuildContext context) { + return new CupertinoPageScaffold( + navigationBar: new CupertinoNavigationBar( + trailing: new ExitButton() + ), + child: new SafeArea( + top: false, + bottom: false, + child: new ListView( + children: new List { + new Padding(padding: EdgeInsets.only(top: 16.0f)), + new Padding( + padding: EdgeInsets.symmetric(horizontal: 16.0f), + child: new Row( + mainAxisSize: MainAxisSize.max, + children: new List { + new Container( + height: 128.0f, + width: 128.0f, + decoration: new BoxDecoration( + color: this.widget.color, + borderRadius: BorderRadius.circular(24.0f) + ) + ), + new Padding(padding: EdgeInsets.only(left: 18.0f)), + new Expanded( + child: new Column( + crossAxisAlignment: CrossAxisAlignment.start, + mainAxisSize: MainAxisSize.min, + children: new List { + new Text(this.widget.colorName, + style: new TextStyle(fontSize: 24.0f, + fontWeight: FontWeight.bold) + ), + new Padding(padding: EdgeInsets.only(top: 6.0f)), + new Text( + "Item number ${widget.index}", + style: new TextStyle( + color: new Color(0xf8E8E93), + fontSize: 16.0f, + fontWeight: FontWeight.w100 + ) + ), + new Padding(padding: EdgeInsets.only(top: 20.0f)), + new Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: new List { + CupertinoButton.filled( + minSize: 30.0f, + padding: EdgeInsets.symmetric(horizontal: 24.0f), + borderRadius: BorderRadius.circular(32.0f), + child: new Text( + "GET", + style: new TextStyle( + fontSize: 14.0f, + fontWeight: FontWeight.w700, + letterSpacing: -0.28f + ) + ), + onPressed: () => { } + ), + CupertinoButton.filled( + minSize: 30.0f, + padding: EdgeInsets.zero, + borderRadius: BorderRadius.circular(32.0f), + child: new Icon(CupertinoIcons.ellipsis), + onPressed: () => { } + ) + } + ) + } + ) + ) + } + ) + ), + new Padding( + padding: EdgeInsets.only(left: 16.0f, top: 28.0f, bottom: 8.0f), + child: new Text( + "USERS ALSO LIKED", + style: new TextStyle( + color: new Color(0xf646464), + letterSpacing: -0.60f, + fontSize: 15.0f, + fontWeight: FontWeight.w500 + ) + ) + ), + new SizedBox( + height: 200.0f, + child: ListView.builder( + scrollDirection: Axis.horizontal, + itemCount: 10, + itemExtent: 160.0f, + itemBuilder: (BuildContext _context, int index) => { + return new Padding( + padding: EdgeInsets.only(left: 16.0f), + child: new Container( + decoration: new BoxDecoration( + borderRadius: BorderRadius.circular(8.0f), + color: this.relatedColors[index] + ), + child: new Center( + child: new CupertinoButton( + child: new Icon( + CupertinoIcons.plus_circled, + color: CupertinoColors.white, + size: 36.0f + ), + onPressed: () => { } + ) + ) + ) + ); + } + ) + ), + } + ) + ) + ); + } + } + + class CupertinoDemoTab2 : StatelessWidget { + public override Widget build(BuildContext context) { + var listViewList = new List(); + listViewList.Add(new Tab2Header()); + listViewList.AddRange(buildTab2Conversation()); + + return new CupertinoPageScaffold( + navigationBar: new CupertinoNavigationBar( + trailing: trailingButtons + ), + child: new ListView( + children: listViewList + ) + ); + } + } + + class Tab2Header : StatelessWidget { + public override Widget build(BuildContext context) { + return new Padding( + padding: EdgeInsets.all(16.0f), + child: new SafeArea( + top: false, + bottom: false, + child: new ClipRRect( + borderRadius: BorderRadius.all(Radius.circular(16.0f)), + child: new Column( + mainAxisSize: MainAxisSize.min, + children: new List { + new Container( + decoration: new BoxDecoration( + color: new Color(0xfE5E5E5) + ), + child: new Padding( + padding: EdgeInsets.symmetric(horizontal: 18.0f, vertical: 12.0f), + child: new Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: new List { + new Text( + "SUPPORT TICKET", + style: new TextStyle( + color: new Color(0xf646464), + letterSpacing: -0.9f, + fontSize: 14.0f, + fontWeight: FontWeight.w500 + ) + ), + new Text( + "Show More", + style: new TextStyle( + color: new Color(0xf646464), + letterSpacing: -0.6f, + fontSize: 12.0f, + fontWeight: FontWeight.w500 + ) + ) + } + ) + ) + ), + new Container( + decoration: new BoxDecoration( + color: new Color(0xfF3F3F3) + ), + child: new Padding( + padding: EdgeInsets.symmetric(horizontal: 18.0f, vertical: 12.0f), + child: new Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: new List { + new Text( + "Product or product packaging damaged during transit", + style: new TextStyle( + fontSize: 16.0f, + fontWeight: FontWeight.w700, + letterSpacing: -0.46f + ) + ), + new Padding(padding: EdgeInsets.only(top: 16.0f)), + new Text( + "REVIEWERS", + style: new TextStyle( + color: new Color(0xf646464), + fontSize: 12.0f, + letterSpacing: -0.6f, + fontWeight: FontWeight.w500 + ) + ), + new Padding(padding: EdgeInsets.only(top: 8.0f)), + new Row( + children: new List { + new Container( + width: 44.0f, + height: 44.0f, + decoration: new BoxDecoration( + image: new DecorationImage( + image: new AssetImage( + "people/square/trevor.png", + package: _kGalleryAssetsPackage + ) + ), + shape: BoxShape.circle + ) + ), + new Padding(padding: EdgeInsets.only(left: 8.0f)), + new Container( + width: 44.0f, + height: 44.0f, + decoration: new BoxDecoration( + image: new DecorationImage( + image: new AssetImage( + "people/square/sandra.png", + package: _kGalleryAssetsPackage + ) + ), + shape: BoxShape.circle + ) + ), + new Padding(padding: EdgeInsets.only(left: 2.0f)), + new Icon( + CupertinoIcons.check_mark_circled, + color: new Color(0xf646464), + size: 20.0f + ) + } + ) + } + ) + ) + ) + } + ) + ) + ) + ); + } + } + + enum Tab2ConversationBubbleColor { + blue, + gray, + } + + class Tab2ConversationBubble : StatelessWidget { + public Tab2ConversationBubble( + string text, + Tab2ConversationBubbleColor color + ) { + this.text = text; + this.color = color; + } + + public readonly string text; + public readonly Tab2ConversationBubbleColor color; + + public override Widget build(BuildContext context) { + return new Container( + decoration: new BoxDecoration( + borderRadius: BorderRadius.all(Radius.circular(18.0f)), + color: this.color == Tab2ConversationBubbleColor.blue + ? CupertinoColors.activeBlue + : CupertinoColors.lightBackgroundGray + ), + margin: EdgeInsets.symmetric(horizontal: 8.0f, vertical: 8.0f), + padding: EdgeInsets.symmetric(horizontal: 14.0f, vertical: 10.0f), + child: new Text(this.text, + style: new TextStyle( + color: this.color == Tab2ConversationBubbleColor.blue + ? CupertinoColors.white + : CupertinoColors.black, + letterSpacing: -0.4f, + fontSize: 15.0f, + fontWeight: FontWeight.w400 + ) + ) + ); + } + } + + class Tab2ConversationAvatar : StatelessWidget { + public Tab2ConversationAvatar( + string text, + Color color + ) { + this.text = text; + this.color = color; + } + + public readonly string text; + public readonly Color color; + + public override Widget build(BuildContext context) { + return new Container( + decoration: new BoxDecoration( + shape: BoxShape.circle, + gradient: new LinearGradient( + begin: Alignment.topCenter, // FractionalOfset.topCenter, + end: Alignment.bottomCenter, // FractionalOfset.bottomCenter, + colors: new List { + this.color, + Color.fromARGB(this.color.alpha, + (this.color.red - 60).clamp(0, 255), + (this.color.green - 60).clamp(0, 255), + (this.color.blue - 60).clamp(0, 255) + ) + } + ) + ), + margin: EdgeInsets.only(left: 8.0f, bottom: 8.0f), + padding: EdgeInsets.all(12.0f), + child: new Text(this.text, + style: new TextStyle( + color: CupertinoColors.white, + fontSize: 13.0f, + fontWeight: FontWeight.w500 + ) + ) + ); + } + } + + class Tab2ConversationRow : StatelessWidget { + public Tab2ConversationRow( + string text, + Tab2ConversationAvatar avatar = null + ) { + this.avatar = avatar; + this.text = text; + } + + public readonly Tab2ConversationAvatar avatar; + public readonly string text; + + public override Widget build(BuildContext context) { + List children = new List(); + + if (this.avatar != null) { + children.Add(this.avatar); + } + + bool isSelf = this.avatar == null; + children.Add( + new Tab2ConversationBubble( + text: this.text, + color: isSelf + ? Tab2ConversationBubbleColor.blue + : Tab2ConversationBubbleColor.gray + ) + ); + return new SafeArea( + child: new Row( + mainAxisAlignment: isSelf ? MainAxisAlignment.end : MainAxisAlignment.start, + mainAxisSize: MainAxisSize.min, + crossAxisAlignment: isSelf ? CrossAxisAlignment.center : CrossAxisAlignment.end, + children: children + ) + ); + } + } } + + class CupertinoDemoTab3 : StatelessWidget { + public override Widget build(BuildContext context) { + return new CupertinoPageScaffold( + navigationBar: new CupertinoNavigationBar( + trailing: CupertinoNavigationDemoUtils.trailingButtons + ), + child: new DecoratedBox( + decoration: new BoxDecoration( + color: CupertinoTheme.of(context).brightness == Brightness.light + ? CupertinoColors.extraLightBackgroundGray + : CupertinoColors.darkBackgroundGray + ), + child: new ListView( + children: new List { + new Padding(padding: EdgeInsets.only(top: 32.0f)), + new GestureDetector( + onTap: () => { + Navigator.of(context, rootNavigator: true).push( + new CupertinoPageRoute( + fullscreenDialog: true, + builder: (BuildContext _context) => new Tab3Dialog() + ) + ); + }, + child: new Container( + decoration: new BoxDecoration( + color: CupertinoTheme.of(context).scaffoldBackgroundColor, + border: new Border( + top: new BorderSide(color: new Color(0xfBCBBC1), width: 0.0f), + bottom: new BorderSide(color: new Color(0xfBCBBC1), width: 0.0f) + ) + ), + height: 44.0f, + child: new Padding( + padding: EdgeInsets.symmetric(horizontal: 16.0f, vertical: 8.0f), + child: new SafeArea( + top: false, + bottom: false, + child: new Row( + children: new List { + new Text( + "Sign in", + style: new TextStyle(color: CupertinoTheme.of(context) + .primaryColor) + ), + } + ) + ) + ) + ) + ) + } + ) + ) + ); + } + } + + class Tab3Dialog : StatelessWidget { + public override Widget build(BuildContext context) { + return new CupertinoPageScaffold( + navigationBar: new CupertinoNavigationBar( + leading: new CupertinoButton( + child: new Text("Cancel"), + padding: EdgeInsets.zero, + onPressed: () => { Navigator.of(context).pop(false); } + ) + ), + child: new Center( + child: new Column( + mainAxisSize: MainAxisSize.min, + children: new List { + new Icon( + CupertinoIcons.profile_circled, + size: 160.0f, + color: new Color(0xf646464) + ), + new Padding(padding: EdgeInsets.only(top: 18.0f)), + CupertinoButton.filled( + child: new Text("Sign in"), + onPressed: () => { Navigator.pop(context); } + ), + } + ) + ) + ); + } + } + */ } \ No newline at end of file diff --git a/Samples/UIWidgetsGallery/demo/cupertino/cupertino_navigation_demo.cs.meta b/Samples/UIWidgetsGallery/demo/cupertino/cupertino_navigation_demo.cs.meta index 6a7c59b6..e20d8425 100644 --- a/Samples/UIWidgetsGallery/demo/cupertino/cupertino_navigation_demo.cs.meta +++ b/Samples/UIWidgetsGallery/demo/cupertino/cupertino_navigation_demo.cs.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: 9d0fe47e7d9d146ba97b488de16fe828 +guid: d5de5bf11a3f04d208266b21a0acda47 MonoImporter: externalObjects: {} serializedVersion: 2 From 919c773b9ab92efce5ad20fd92e018decd5eaf7c Mon Sep 17 00:00:00 2001 From: iizzaya Date: Tue, 27 Aug 2019 15:29:09 +0800 Subject: [PATCH 4/5] [Cupertino] Annotate bug demo --- .../demo/cupertino/cupertino_alert_demo.cs | 77 ++++++++++--------- .../demo/cupertino/cupertino_slider_demo.cs | 30 ++++---- 2 files changed, 54 insertions(+), 53 deletions(-) diff --git a/Samples/UIWidgetsGallery/demo/cupertino/cupertino_alert_demo.cs b/Samples/UIWidgetsGallery/demo/cupertino/cupertino_alert_demo.cs index d110f0e2..3fa73ab5 100644 --- a/Samples/UIWidgetsGallery/demo/cupertino/cupertino_alert_demo.cs +++ b/Samples/UIWidgetsGallery/demo/cupertino/cupertino_alert_demo.cs @@ -144,44 +144,45 @@ public override Widget build(BuildContext context) { ); } ), - new Padding(padding: EdgeInsets.all(8.0f)), - CupertinoButton.filled( - child: new Text("Action Sheet"), - padding: EdgeInsets.symmetric(vertical: 16.0f, horizontal: 36.0f), - onPressed: () => { - this.showDemoActionSheet( - context: _context, - child: new CupertinoActionSheet( - title: new Text("Favorite Dessert"), - message: new Text( - "Please select the best dessert from the options below."), - actions: new List { - new CupertinoActionSheetAction( - child: new Text("Profiteroles"), - onPressed: () => { - Navigator.pop(_context, "Profiteroles"); - } - ), - new CupertinoActionSheetAction( - child: new Text("Cannolis"), - onPressed: () => { - Navigator.pop(_context, "Cannolis"); - } - ), - new CupertinoActionSheetAction( - child: new Text("Trifle"), - onPressed: () => { Navigator.pop(_context, "Trifle"); } - ) - }, - cancelButton: new CupertinoActionSheetAction( - child: new Text("Cancel"), - isDefaultAction: true, - onPressed: () => { Navigator.pop(_context, "Cancel"); } - ) - ) - ); - } - ) + // TODO: FIX BUG + // new Padding(padding: EdgeInsets.all(8.0f)), + // CupertinoButton.filled( + // child: new Text("Action Sheet"), + // padding: EdgeInsets.symmetric(vertical: 16.0f, horizontal: 36.0f), + // onPressed: () => { + // this.showDemoActionSheet( + // context: _context, + // child: new CupertinoActionSheet( + // title: new Text("Favorite Dessert"), + // message: new Text( + // "Please select the best dessert from the options below."), + // actions: new List { + // new CupertinoActionSheetAction( + // child: new Text("Profiteroles"), + // onPressed: () => { + // Navigator.pop(_context, "Profiteroles"); + // } + // ), + // new CupertinoActionSheetAction( + // child: new Text("Cannolis"), + // onPressed: () => { + // Navigator.pop(_context, "Cannolis"); + // } + // ), + // new CupertinoActionSheetAction( + // child: new Text("Trifle"), + // onPressed: () => { Navigator.pop(_context, "Trifle"); } + // ) + // }, + // cancelButton: new CupertinoActionSheetAction( + // child: new Text("Cancel"), + // isDefaultAction: true, + // onPressed: () => { Navigator.pop(_context, "Cancel"); } + // ) + // ) + // ); + // } + // ) } ) }; diff --git a/Samples/UIWidgetsGallery/demo/cupertino/cupertino_slider_demo.cs b/Samples/UIWidgetsGallery/demo/cupertino/cupertino_slider_demo.cs index 254680aa..d0efa803 100644 --- a/Samples/UIWidgetsGallery/demo/cupertino/cupertino_slider_demo.cs +++ b/Samples/UIWidgetsGallery/demo/cupertino/cupertino_slider_demo.cs @@ -30,21 +30,21 @@ public override Widget build(BuildContext context) { child: new Column( mainAxisAlignment: MainAxisAlignment.spaceAround, children: new List { - new Column( - mainAxisSize: MainAxisSize.min, - children: new List { - new CupertinoSlider( - value: this._value, - min: 0.0f, - max: 100.0f, - divisions: 100, // TODO: FIX BUG - onChanged: (float value) => { - this.setState(() => { this._value = value; }); - } - ), - new Text($"Cupertino Continuous: {this._value.ToString("F1")}"), - } - ), + // TODO: FIX BUG + // new Column( + // mainAxisSize: MainAxisSize.min, + // children: new List { + // new CupertinoSlider( + // value: this._value, + // min: 0.0f, + // max: 100.0f, + // onChanged: (float value) => { + // this.setState(() => { this._value = value; }); + // } + // ), + // new Text($"Cupertino Continuous: {this._value.ToString("F1")}"), + // } + // ), new Column( mainAxisSize: MainAxisSize.min, children: new List { From 67bd18c12cd607a7efc89d3b129b9d20c22dd345 Mon Sep 17 00:00:00 2001 From: iizzaya Date: Tue, 27 Aug 2019 16:55:12 +0800 Subject: [PATCH 5/5] [Cupertino] Fix bugs. --- Runtime/cupertino/app.cs | 5 +- Runtime/cupertino/bottom_app_bar.cs | 6 +- Runtime/cupertino/slider.cs | 2 +- Runtime/cupertino/tab_scaffold.cs | 7 +- .../demo/cupertino/cupertino_alert_demo.cs | 76 +- .../cupertino/cupertino_navigation_demo.cs | 1149 ++++++++--------- .../demo/cupertino/cupertino_slider_demo.cs | 29 +- Samples/UIWidgetsGallery/gallery/demos.cs | 4 +- 8 files changed, 639 insertions(+), 639 deletions(-) diff --git a/Runtime/cupertino/app.cs b/Runtime/cupertino/app.cs index 1ffe73ad..94277e8b 100644 --- a/Runtime/cupertino/app.cs +++ b/Runtime/cupertino/app.cs @@ -27,10 +27,7 @@ public CupertinoApp( List supportedLocales = null, bool showPerformanceOverlay = false ) : base(key: key) { - // D.assert(routes != null); - // D.assert(navigatorObservers != null); - // D.assert(title != null); - // D.assert(showPerformanceOverlay != null); + D.assert(title != null); supportedLocales = supportedLocales ?? new List {new Locale("en", "US")}; this.navigatorKey = navigatorKey; diff --git a/Runtime/cupertino/bottom_app_bar.cs b/Runtime/cupertino/bottom_app_bar.cs index 8b86bacc..e1928582 100644 --- a/Runtime/cupertino/bottom_app_bar.cs +++ b/Runtime/cupertino/bottom_app_bar.cs @@ -31,7 +31,8 @@ public CupertinoTabBar( () => "Tabs need at least 2 items to conform to Apple's HIG" ); D.assert(0 <= currentIndex && currentIndex < items.Count); - D.assert(inactiveColor != null); + + this.items = items; this.onTap = onTap; this.currentIndex = currentIndex; @@ -122,13 +123,14 @@ List _buildTabItems(BuildContext context) { for (int index = 0; index < this.items.Count; index += 1) { bool active = index == this.currentIndex; + var tabIndex = index; result.Add( this._wrapActiveItem( context, new Expanded( child: new GestureDetector( behavior: HitTestBehavior.opaque, - onTap: this.onTap == null ? null : (GestureTapCallback) (() => { this.onTap(index); }), + onTap: this.onTap == null ? null : (GestureTapCallback) (() => { this.onTap(tabIndex); }), child: new Padding( padding: EdgeInsets.only(bottom: 4.0f), child: new Column( diff --git a/Runtime/cupertino/slider.cs b/Runtime/cupertino/slider.cs index ede86c8f..09988286 100644 --- a/Runtime/cupertino/slider.cs +++ b/Runtime/cupertino/slider.cs @@ -150,7 +150,7 @@ public override RenderObject createRenderObject(BuildContext context) { public override void updateRenderObject(BuildContext context, RenderObject _renderObject) { _RenderCupertinoSlider renderObject = _renderObject as _RenderCupertinoSlider; renderObject.value = this.value ?? 0.0f; - renderObject.divisions = this.divisions ?? 0; + renderObject.divisions = this.divisions; renderObject.activeColor = this.activeColor; renderObject.onChanged = this.onChanged; renderObject.onChangeStart = this.onChangeStart; diff --git a/Runtime/cupertino/tab_scaffold.cs b/Runtime/cupertino/tab_scaffold.cs index 3e182ef3..3905ddcb 100644 --- a/Runtime/cupertino/tab_scaffold.cs +++ b/Runtime/cupertino/tab_scaffold.cs @@ -43,6 +43,7 @@ class _CupertinoTabScaffoldState : State { public override void initState() { base.initState(); this._currentPage = this.widget.tabBar.currentIndex; + } public override void didUpdateWidget(StatefulWidget _oldWidget) { @@ -160,6 +161,9 @@ class _TabSwitchingViewState : State<_TabSwitchingView> { public override void initState() { base.initState(); this.tabs = new List(this.widget.tabNumber); + for (int i = 0; i < this.widget.tabNumber; i++) { + this.tabs.Add(null); + } this.tabFocusNodes = Enumerable.Repeat(new FocusScopeNode(), this.widget.tabNumber).ToList(); } @@ -191,8 +195,9 @@ public override Widget build(BuildContext context) { for (int index = 0; index < this.widget.tabNumber; index++) { bool active = index == this.widget.currentTabIndex; + var tabIndex = index; if (active || this.tabs[index] != null) { - this.tabs[index] = this.widget.tabBuilder(context, index); + this.tabs[index] = this.widget.tabBuilder(context, tabIndex); } children.Add(new Offstage( diff --git a/Samples/UIWidgetsGallery/demo/cupertino/cupertino_alert_demo.cs b/Samples/UIWidgetsGallery/demo/cupertino/cupertino_alert_demo.cs index 3fa73ab5..485bb398 100644 --- a/Samples/UIWidgetsGallery/demo/cupertino/cupertino_alert_demo.cs +++ b/Samples/UIWidgetsGallery/demo/cupertino/cupertino_alert_demo.cs @@ -145,44 +145,44 @@ public override Widget build(BuildContext context) { } ), // TODO: FIX BUG - // new Padding(padding: EdgeInsets.all(8.0f)), - // CupertinoButton.filled( - // child: new Text("Action Sheet"), - // padding: EdgeInsets.symmetric(vertical: 16.0f, horizontal: 36.0f), - // onPressed: () => { - // this.showDemoActionSheet( - // context: _context, - // child: new CupertinoActionSheet( - // title: new Text("Favorite Dessert"), - // message: new Text( - // "Please select the best dessert from the options below."), - // actions: new List { - // new CupertinoActionSheetAction( - // child: new Text("Profiteroles"), - // onPressed: () => { - // Navigator.pop(_context, "Profiteroles"); - // } - // ), - // new CupertinoActionSheetAction( - // child: new Text("Cannolis"), - // onPressed: () => { - // Navigator.pop(_context, "Cannolis"); - // } - // ), - // new CupertinoActionSheetAction( - // child: new Text("Trifle"), - // onPressed: () => { Navigator.pop(_context, "Trifle"); } - // ) - // }, - // cancelButton: new CupertinoActionSheetAction( - // child: new Text("Cancel"), - // isDefaultAction: true, - // onPressed: () => { Navigator.pop(_context, "Cancel"); } - // ) - // ) - // ); - // } - // ) + new Padding(padding: EdgeInsets.all(8.0f)), + CupertinoButton.filled( + child: new Text("Action Sheet"), + padding: EdgeInsets.symmetric(vertical: 16.0f, horizontal: 36.0f), + onPressed: () => { + this.showDemoActionSheet( + context: _context, + child: new CupertinoActionSheet( + title: new Text("Favorite Dessert"), + message: new Text( + "Please select the best dessert from the options below."), + actions: new List { + // new CupertinoActionSheetAction( + // child: new Text("Profiteroles"), + // onPressed: () => { + // Navigator.pop(_context, "Profiteroles"); + // } + // ), + // new CupertinoActionSheetAction( + // child: new Text("Cannolis"), + // onPressed: () => { + // Navigator.pop(_context, "Cannolis"); + // } + // ), + // new CupertinoActionSheetAction( + // child: new Text("Trifle"), + // onPressed: () => { Navigator.pop(_context, "Trifle"); } + // ) + }, + cancelButton: new CupertinoActionSheetAction( + child: new Text("Cancel"), + isDefaultAction: true, + onPressed: () => { Navigator.pop(_context, "Cancel"); } + ) + ) + ); + } + ) } ) }; diff --git a/Samples/UIWidgetsGallery/demo/cupertino/cupertino_navigation_demo.cs b/Samples/UIWidgetsGallery/demo/cupertino/cupertino_navigation_demo.cs index b48f2c3d..a25f7b72 100644 --- a/Samples/UIWidgetsGallery/demo/cupertino/cupertino_navigation_demo.cs +++ b/Samples/UIWidgetsGallery/demo/cupertino/cupertino_navigation_demo.cs @@ -12,7 +12,6 @@ using Color = Unity.UIWidgets.ui.Color; namespace UIWidgetsGallery.gallery { - /* class CupertinoNavigationDemoUtils { public const string _kGalleryAssetsPackage = "flutter_gallery_assets"; @@ -86,670 +85,669 @@ public static List buildTab2Conversation() { ), }; } + } - class CupertinoNavigationDemo : StatelessWidget { - public CupertinoNavigationDemo() { - this.colorItems = new List(); + public class CupertinoNavigationDemo : StatelessWidget { + public CupertinoNavigationDemo() { + this.colorItems = new List(); - for (int i = 0; i < _kChildCount; i++) { - this.colorItems.Add(coolColors[ - Random.Range(0, coolColors.Count) - ]); - } + for (int i = 0; i < CupertinoNavigationDemoUtils._kChildCount; i++) { + this.colorItems.Add(CupertinoNavigationDemoUtils.coolColors[ + Random.Range(0, CupertinoNavigationDemoUtils.coolColors.Count) + ]); + } - this.colorNameItems = new List(); + this.colorNameItems = new List(); - for (int i = 0; i < _kChildCount; i++) { - this.colorNameItems.Add(coolColorNames[ - Random.Range(0, coolColorNames.Count) - ]); - } + for (int i = 0; i < CupertinoNavigationDemoUtils._kChildCount; i++) { + this.colorNameItems.Add(CupertinoNavigationDemoUtils.coolColorNames[ + Random.Range(0, CupertinoNavigationDemoUtils.coolColorNames.Count) + ]); } + } - public static string routeName = "/cupertino/navigation"; - public readonly List colorItems; - public readonly List colorNameItems; - - public override Widget build(BuildContext context) { - return new WillPopScope( - onWillPop: () => new IPromise().value(true), - child: new DefaultTextStyle( - style: CupertinoTheme.of(context).textTheme.textStyle, - child: new CupertinoTabScaffold( - tabBar: new CupertinoTabBar( - items: new List { - new BottomNavigationBarItem( - icon: new Icon(CupertinoIcons.home), - title: new Text("Home") - ), - new BottomNavigationBarItem( - icon: new Icon(CupertinoIcons.conversation_bubble), - title: new Text("Support") - ), - new BottomNavigationBarItem( - icon: new Icon(CupertinoIcons.profile_circled), - title: new Text("Profile") - ) - } - ), - tabBuilder: (BuildContext _context, int index) => { - D.assert(index >= 0 && index <= 2); - switch (index) { - case 0: - return new CupertinoTabView( - builder: (BuildContext _context1) => { - return new CupertinoDemoTab1( - colorItems: this.colorItems, - colorNameItems: this.colorNameItems - ); - }, - defaultTitle: "Colors" - ); - break; - case 1: - return new CupertinoTabView( - builder: (BuildContext _context2) => new CupertinoDemoTab2(), - defaultTitle: "Support Chat" - ); - break; - case 2: - return new CupertinoTabView( - builder: (BuildContext _context3) => new CupertinoDemoTab3(), - defaultTitle: "Account" - ); - break; - } + public static string routeName = "/cupertino/navigation"; + public readonly List colorItems; + public readonly List colorNameItems; - return null; + public override Widget build(BuildContext context) { + return new WillPopScope( + onWillPop: () => { return Promise.Resolved(true); }, + child: new DefaultTextStyle( + style: CupertinoTheme.of(context).textTheme.textStyle, + child: new CupertinoTabScaffold( + tabBar: new CupertinoTabBar( + items: new List { + new BottomNavigationBarItem( + icon: new Icon(CupertinoIcons.home), + title: new Text("Home") + ), + new BottomNavigationBarItem( + icon: new Icon(CupertinoIcons.conversation_bubble), + title: new Text("Support") + ), + new BottomNavigationBarItem( + icon: new Icon(CupertinoIcons.profile_circled), + title: new Text("Profile") + ) } - ) + ), + tabBuilder: (BuildContext _context, int index) => { + D.assert(index >= 0 && index <= 2); + switch (index) { + case 0: + return new CupertinoTabView( + builder: (BuildContext _context1) => { + return new CupertinoDemoTab1( + colorItems: this.colorItems, + colorNameItems: this.colorNameItems + ); + }, + defaultTitle: "Colors" + ); + break; + case 1: + return new CupertinoTabView( + builder: (BuildContext _context2) => new CupertinoDemoTab2(), + defaultTitle: "Support Chat" + ); + break; + case 2: + return new CupertinoTabView( + builder: (BuildContext _context3) => new CupertinoDemoTab3(), + defaultTitle: "Account" + ); + break; + } + + return null; + } ) - ); - } + ) + ); } + } - class ExitButton : StatelessWidget { - public ExitButton() { } + class ExitButton : StatelessWidget { + public ExitButton() { } - public override Widget build(BuildContext context) { - return new CupertinoButton( - padding: EdgeInsets.zero, - child: new Tooltip( - message: "Back", - child: new Text("Exit") - ), - onPressed: () => { Navigator.of(context, rootNavigator: true).pop(); } - ); - } + public override Widget build(BuildContext context) { + return new CupertinoButton( + padding: EdgeInsets.zero, + child: new Tooltip( + message: "Back", + child: new Text("Exit") + ), + onPressed: () => { Navigator.of(context, rootNavigator: true).pop(); } + ); } + } - class CupertinoDemoTab1 : StatelessWidget { - public CupertinoDemoTab1( - List colorItems = null, - List colorNameItems = null - ) { - this.colorItems = colorItems; - this.colorNameItems = colorNameItems; - } - - public readonly List colorItems; - public readonly List colorNameItems; - - public override Widget build(BuildContext context) { - return new CupertinoPageScaffold( - child: new CustomScrollView( - slivers: new List { - new CupertinoSliverNavigationBar( - trailing: trailingButtons - ), - new SliverPadding( - padding: MediaQuery.of(context).removePadding( - removeTop: true, - removeLeft: true, - removeRight: true - ).padding, - sliver: new SliverList( - del: new SliverChildBuilderDelegate( - (BuildContext _context, int index) => { - return new Tab1RowItem( - index: index, - lastItem: index == _kChildCount - 1, - color: this.colorItems[index], - colorName: this.colorNameItems[index] - ); - }, - childCount: _kChildCount - ) - ) - ) - } - ) - ); - } + class CupertinoDemoTab1 : StatelessWidget { + public CupertinoDemoTab1( + List colorItems = null, + List colorNameItems = null + ) { + this.colorItems = colorItems; + this.colorNameItems = colorNameItems; } - class Tab1RowItem : StatelessWidget { - public Tab1RowItem( - int index, - bool lastItem, - Color color, - string colorName - ) { - this.index = index; - this.lastItem = lastItem; - this.color = color; - this.colorName = colorName; - } + public readonly List colorItems; + public readonly List colorNameItems; - public readonly int index; - public readonly bool lastItem; - public readonly Color color; - public readonly string colorName; - - public override Widget build(BuildContext context) { - Widget row = new GestureDetector( - behavior: HitTestBehavior.opaque, - onTap: () => { - Navigator.of(context).push(new CupertinoPageRoute( - title: this.colorName, - builder: (BuildContext _context) => new Tab1ItemPage( - color: this.color, - colorName: this.colorName, - index: this.index - ) - )); - }, - child: new SafeArea( - top: false, - bottom: false, - child: new Padding( - padding: EdgeInsets.only(left: 16.0f, top: 8.0f, bottom: 8.0f, right: 8.0f), - child: new Row( - children: new List { - new Container( - height: 60.0f, - width: 60.0f, - decoration: new BoxDecoration( - color: this.color, - borderRadius: BorderRadius.circular(8.0f) - ) - ), - new Expanded( - child: new Padding( - padding: EdgeInsets.symmetric(horizontal: 12.0f), - child: new Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: new List { - new Text(this.colorName), - new Padding(padding: EdgeInsets.only(top: 8.0f)), - new Text( - "Buy this cool color", - style: new TextStyle( - color: new Color(0xf8E8E93), - fontSize: 13.0f, - fontWeight: FontWeight.w300 - ) - ) - } - ) - ) - ), - new CupertinoButton( - padding: EdgeInsets.zero, - child: new Icon(CupertinoIcons.plus_circled - ), - onPressed: () => { } - ), - new CupertinoButton( - padding: EdgeInsets.zero, - child: new Icon(CupertinoIcons.share - ), - onPressed: () => { } - ) - } + public override Widget build(BuildContext context) { + return new CupertinoPageScaffold( + child: new CustomScrollView( + slivers: new List { + new CupertinoSliverNavigationBar( + trailing: CupertinoNavigationDemoUtils.trailingButtons + ), + new SliverPadding( + padding: MediaQuery.of(context).removePadding( + removeTop: true, + removeLeft: true, + removeRight: true + ).padding, + sliver: new SliverList( + del: new SliverChildBuilderDelegate( + (BuildContext _context, int index) => { + return new Tab1RowItem( + index: index, + lastItem: index == CupertinoNavigationDemoUtils._kChildCount - 1, + color: this.colorItems[index], + colorName: this.colorNameItems[index] + ); + }, + childCount: CupertinoNavigationDemoUtils._kChildCount + ) ) ) - ) - ); - if (this.lastItem) { - return row; - } - - return new Column( - children: new List { - row, - new Container( - height: 1.0f, - color: new Color(0xfD9D9D9) - ) } - ); - } + ) + ); } + } - class Tab1ItemPage : StatefulWidget { - public Tab1ItemPage( - Color color, - string colorName, - int index - ) { - this.color = color; - this.colorName = colorName; - this.index = index; - } - - public readonly Color color; - public readonly string colorName; - public readonly int index; - - public override State createState() { - return new Tab1ItemPageState(); - } + class Tab1RowItem : StatelessWidget { + public Tab1RowItem( + int index, + bool lastItem, + Color color, + string colorName + ) { + this.index = index; + this.lastItem = lastItem; + this.color = color; + this.colorName = colorName; } - class Tab1ItemPageState : State { - public override void initState() { - base.initState(); + public readonly int index; + public readonly bool lastItem; + public readonly Color color; + public readonly string colorName; - for (int i = 0; i < 10; i++) { - this.relatedColors.Add( - Color.fromARGB( - 255, this.widget.color.red + Random.Range(0, 50).clamp(0, 255), - this.widget.color.green + Random.Range(0, 50).clamp(0, 255), - this.widget.color.blue + Random.Range(0, 50).clamp(0, 255) + public override Widget build(BuildContext context) { + Widget row = new GestureDetector( + behavior: HitTestBehavior.opaque, + onTap: () => { + Navigator.of(context).push(new CupertinoPageRoute( + title: this.colorName, + builder: (BuildContext _context) => new Tab1ItemPage( + color: this.color, + colorName: this.colorName, + index: this.index ) - ); - } - } - - List relatedColors; - - public override Widget build(BuildContext context) { - return new CupertinoPageScaffold( - navigationBar: new CupertinoNavigationBar( - trailing: new ExitButton() - ), - child: new SafeArea( - top: false, - bottom: false, - child: new ListView( + )); + }, + child: new SafeArea( + top: false, + bottom: false, + child: new Padding( + padding: EdgeInsets.only(left: 16.0f, top: 8.0f, bottom: 8.0f, right: 8.0f), + child: new Row( children: new List { - new Padding(padding: EdgeInsets.only(top: 16.0f)), - new Padding( - padding: EdgeInsets.symmetric(horizontal: 16.0f), - child: new Row( - mainAxisSize: MainAxisSize.max, - children: new List { - new Container( - height: 128.0f, - width: 128.0f, - decoration: new BoxDecoration( - color: this.widget.color, - borderRadius: BorderRadius.circular(24.0f) - ) - ), - new Padding(padding: EdgeInsets.only(left: 18.0f)), - new Expanded( - child: new Column( - crossAxisAlignment: CrossAxisAlignment.start, - mainAxisSize: MainAxisSize.min, - children: new List { - new Text(this.widget.colorName, - style: new TextStyle(fontSize: 24.0f, - fontWeight: FontWeight.bold) - ), - new Padding(padding: EdgeInsets.only(top: 6.0f)), - new Text( - "Item number ${widget.index}", - style: new TextStyle( - color: new Color(0xf8E8E93), - fontSize: 16.0f, - fontWeight: FontWeight.w100 - ) - ), - new Padding(padding: EdgeInsets.only(top: 20.0f)), - new Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: new List { - CupertinoButton.filled( - minSize: 30.0f, - padding: EdgeInsets.symmetric(horizontal: 24.0f), - borderRadius: BorderRadius.circular(32.0f), - child: new Text( - "GET", - style: new TextStyle( - fontSize: 14.0f, - fontWeight: FontWeight.w700, - letterSpacing: -0.28f - ) - ), - onPressed: () => { } - ), - CupertinoButton.filled( - minSize: 30.0f, - padding: EdgeInsets.zero, - borderRadius: BorderRadius.circular(32.0f), - child: new Icon(CupertinoIcons.ellipsis), - onPressed: () => { } - ) - } - ) - } - ) - ) - } - ) - ), - new Padding( - padding: EdgeInsets.only(left: 16.0f, top: 28.0f, bottom: 8.0f), - child: new Text( - "USERS ALSO LIKED", - style: new TextStyle( - color: new Color(0xf646464), - letterSpacing: -0.60f, - fontSize: 15.0f, - fontWeight: FontWeight.w500 - ) + new Container( + height: 60.0f, + width: 60.0f, + decoration: new BoxDecoration( + color: this.color, + borderRadius: BorderRadius.circular(8.0f) ) ), - new SizedBox( - height: 200.0f, - child: ListView.builder( - scrollDirection: Axis.horizontal, - itemCount: 10, - itemExtent: 160.0f, - itemBuilder: (BuildContext _context, int index) => { - return new Padding( - padding: EdgeInsets.only(left: 16.0f), - child: new Container( - decoration: new BoxDecoration( - borderRadius: BorderRadius.circular(8.0f), - color: this.relatedColors[index] - ), - child: new Center( - child: new CupertinoButton( - child: new Icon( - CupertinoIcons.plus_circled, - color: CupertinoColors.white, - size: 36.0f - ), - onPressed: () => { } - ) + new Expanded( + child: new Padding( + padding: EdgeInsets.symmetric(horizontal: 12.0f), + child: new Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: new List { + new Text(this.colorName), + new Padding(padding: EdgeInsets.only(top: 8.0f)), + new Text( + "Buy this cool color", + style: new TextStyle( + color: new Color(0xf8E8E93), + fontSize: 13.0f, + fontWeight: FontWeight.w300 ) ) - ); - } + } + ) ) ), + new CupertinoButton( + padding: EdgeInsets.zero, + child: new Icon(CupertinoIcons.plus_circled + ), + onPressed: () => { } + ), + new CupertinoButton( + padding: EdgeInsets.zero, + child: new Icon(CupertinoIcons.share + ), + onPressed: () => { } + ) } ) ) - ); + ) + ); + if (this.lastItem) { + return row; } + + return new Column( + children: new List { + row, + new Container( + height: 1.0f, + color: new Color(0xfD9D9D9) + ) + } + ); } + } - class CupertinoDemoTab2 : StatelessWidget { - public override Widget build(BuildContext context) { - var listViewList = new List(); - listViewList.Add(new Tab2Header()); - listViewList.AddRange(buildTab2Conversation()); + class Tab1ItemPage : StatefulWidget { + public Tab1ItemPage( + Color color, + string colorName, + int index + ) { + this.color = color; + this.colorName = colorName; + this.index = index; + } - return new CupertinoPageScaffold( - navigationBar: new CupertinoNavigationBar( - trailing: trailingButtons - ), - child: new ListView( - children: listViewList + public readonly Color color; + public readonly string colorName; + public readonly int index; + + public override State createState() { + return new Tab1ItemPageState(); + } + } + + class Tab1ItemPageState : State { + public override void initState() { + base.initState(); + + for (int i = 0; i < 10; i++) { + this.relatedColors.Add( + Color.fromARGB( + 255, this.widget.color.red + Random.Range(0, 50).clamp(0, 255), + this.widget.color.green + Random.Range(0, 50).clamp(0, 255), + this.widget.color.blue + Random.Range(0, 50).clamp(0, 255) ) ); } } - class Tab2Header : StatelessWidget { - public override Widget build(BuildContext context) { - return new Padding( - padding: EdgeInsets.all(16.0f), - child: new SafeArea( - top: false, - bottom: false, - child: new ClipRRect( - borderRadius: BorderRadius.all(Radius.circular(16.0f)), - child: new Column( - mainAxisSize: MainAxisSize.min, - children: new List { - new Container( - decoration: new BoxDecoration( - color: new Color(0xfE5E5E5) - ), - child: new Padding( - padding: EdgeInsets.symmetric(horizontal: 18.0f, vertical: 12.0f), - child: new Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: new List { - new Text( - "SUPPORT TICKET", - style: new TextStyle( - color: new Color(0xf646464), - letterSpacing: -0.9f, - fontSize: 14.0f, - fontWeight: FontWeight.w500 - ) - ), - new Text( - "Show More", - style: new TextStyle( - color: new Color(0xf646464), - letterSpacing: -0.6f, - fontSize: 12.0f, - fontWeight: FontWeight.w500 - ) - ) - } + List relatedColors; + + public override Widget build(BuildContext context) { + return new CupertinoPageScaffold( + navigationBar: new CupertinoNavigationBar( + trailing: new ExitButton() + ), + child: new SafeArea( + top: false, + bottom: false, + child: new ListView( + children: new List { + new Padding(padding: EdgeInsets.only(top: 16.0f)), + new Padding( + padding: EdgeInsets.symmetric(horizontal: 16.0f), + child: new Row( + mainAxisSize: MainAxisSize.max, + children: new List { + new Container( + height: 128.0f, + width: 128.0f, + decoration: new BoxDecoration( + color: this.widget.color, + borderRadius: BorderRadius.circular(24.0f) ) - ) - ), - new Container( - decoration: new BoxDecoration( - color: new Color(0xfF3F3F3) ), - child: new Padding( - padding: EdgeInsets.symmetric(horizontal: 18.0f, vertical: 12.0f), + new Padding(padding: EdgeInsets.only(left: 18.0f)), + new Expanded( child: new Column( crossAxisAlignment: CrossAxisAlignment.start, + mainAxisSize: MainAxisSize.min, children: new List { - new Text( - "Product or product packaging damaged during transit", - style: new TextStyle( - fontSize: 16.0f, - fontWeight: FontWeight.w700, - letterSpacing: -0.46f - ) + new Text(this.widget.colorName, + style: new TextStyle(fontSize: 24.0f, + fontWeight: FontWeight.bold) ), - new Padding(padding: EdgeInsets.only(top: 16.0f)), + new Padding(padding: EdgeInsets.only(top: 6.0f)), new Text( - "REVIEWERS", + "Item number ${widget.index}", style: new TextStyle( - color: new Color(0xf646464), - fontSize: 12.0f, - letterSpacing: -0.6f, - fontWeight: FontWeight.w500 + color: new Color(0xf8E8E93), + fontSize: 16.0f, + fontWeight: FontWeight.w100 ) ), - new Padding(padding: EdgeInsets.only(top: 8.0f)), + new Padding(padding: EdgeInsets.only(top: 20.0f)), new Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, children: new List { - new Container( - width: 44.0f, - height: 44.0f, - decoration: new BoxDecoration( - image: new DecorationImage( - image: new AssetImage( - "people/square/trevor.png", - package: _kGalleryAssetsPackage - ) - ), - shape: BoxShape.circle - ) - ), - new Padding(padding: EdgeInsets.only(left: 8.0f)), - new Container( - width: 44.0f, - height: 44.0f, - decoration: new BoxDecoration( - image: new DecorationImage( - image: new AssetImage( - "people/square/sandra.png", - package: _kGalleryAssetsPackage - ) - ), - shape: BoxShape.circle - ) + CupertinoButton.filled( + minSize: 30.0f, + padding: EdgeInsets.symmetric(horizontal: 24.0f), + borderRadius: BorderRadius.circular(32.0f), + child: new Text( + "GET", + style: new TextStyle( + fontSize: 14.0f, + fontWeight: FontWeight.w700, + letterSpacing: -0.28f + ) + ), + onPressed: () => { } ), - new Padding(padding: EdgeInsets.only(left: 2.0f)), - new Icon( - CupertinoIcons.check_mark_circled, - color: new Color(0xf646464), - size: 20.0f + CupertinoButton.filled( + minSize: 30.0f, + padding: EdgeInsets.zero, + borderRadius: BorderRadius.circular(32.0f), + child: new Icon(CupertinoIcons.ellipsis), + onPressed: () => { } ) } ) } ) ) + } + ) + ), + new Padding( + padding: EdgeInsets.only(left: 16.0f, top: 28.0f, bottom: 8.0f), + child: new Text( + "USERS ALSO LIKED", + style: new TextStyle( + color: new Color(0xf646464), + letterSpacing: -0.60f, + fontSize: 15.0f, + fontWeight: FontWeight.w500 ) - } - ) - ) + ) + ), + new SizedBox( + height: 200.0f, + child: ListView.builder( + scrollDirection: Axis.horizontal, + itemCount: 10, + itemExtent: 160.0f, + itemBuilder: (BuildContext _context, int index) => { + return new Padding( + padding: EdgeInsets.only(left: 16.0f), + child: new Container( + decoration: new BoxDecoration( + borderRadius: BorderRadius.circular(8.0f), + color: this.relatedColors[index] + ), + child: new Center( + child: new CupertinoButton( + child: new Icon( + CupertinoIcons.plus_circled, + color: CupertinoColors.white, + size: 36.0f + ), + onPressed: () => { } + ) + ) + ) + ); + } + ) + ), + } ) - ); - } + ) + ); } + } + + class CupertinoDemoTab2 : StatelessWidget { + public override Widget build(BuildContext context) { + var listViewList = new List(); + listViewList.Add(new Tab2Header()); + listViewList.AddRange(CupertinoNavigationDemoUtils.buildTab2Conversation()); - enum Tab2ConversationBubbleColor { - blue, - gray, + return new CupertinoPageScaffold( + navigationBar: new CupertinoNavigationBar( + trailing: CupertinoNavigationDemoUtils.trailingButtons + ), + child: new ListView( + children: listViewList + ) + ); } + } - class Tab2ConversationBubble : StatelessWidget { - public Tab2ConversationBubble( - string text, - Tab2ConversationBubbleColor color - ) { - this.text = text; - this.color = color; - } + class Tab2Header : StatelessWidget { + public override Widget build(BuildContext context) { + return new Padding( + padding: EdgeInsets.all(16.0f), + child: new SafeArea( + top: false, + bottom: false, + child: new ClipRRect( + borderRadius: BorderRadius.all(Radius.circular(16.0f)), + child: new Column( + mainAxisSize: MainAxisSize.min, + children: new List { + new Container( + decoration: new BoxDecoration( + color: new Color(0xfE5E5E5) + ), + child: new Padding( + padding: EdgeInsets.symmetric(horizontal: 18.0f, vertical: 12.0f), + child: new Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: new List { + new Text( + "SUPPORT TICKET", + style: new TextStyle( + color: new Color(0xf646464), + letterSpacing: -0.9f, + fontSize: 14.0f, + fontWeight: FontWeight.w500 + ) + ), + new Text( + "Show More", + style: new TextStyle( + color: new Color(0xf646464), + letterSpacing: -0.6f, + fontSize: 12.0f, + fontWeight: FontWeight.w500 + ) + ) + } + ) + ) + ), + new Container( + decoration: new BoxDecoration( + color: new Color(0xfF3F3F3) + ), + child: new Padding( + padding: EdgeInsets.symmetric(horizontal: 18.0f, vertical: 12.0f), + child: new Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: new List { + new Text( + "Product or product packaging damaged during transit", + style: new TextStyle( + fontSize: 16.0f, + fontWeight: FontWeight.w700, + letterSpacing: -0.46f + ) + ), + new Padding(padding: EdgeInsets.only(top: 16.0f)), + new Text( + "REVIEWERS", + style: new TextStyle( + color: new Color(0xf646464), + fontSize: 12.0f, + letterSpacing: -0.6f, + fontWeight: FontWeight.w500 + ) + ), + new Padding(padding: EdgeInsets.only(top: 8.0f)), + new Row( + children: new List { + new Container( + width: 44.0f, + height: 44.0f, + decoration: new BoxDecoration( + image: new DecorationImage( + image: new AssetImage( + "people/square/trevor" + ) + ), + shape: BoxShape.circle + ) + ), + new Padding(padding: EdgeInsets.only(left: 8.0f)), + new Container( + width: 44.0f, + height: 44.0f, + decoration: new BoxDecoration( + image: new DecorationImage( + image: new AssetImage( + "people/square/sandra" + ) + ), + shape: BoxShape.circle + ) + ), + new Padding(padding: EdgeInsets.only(left: 2.0f)), + new Icon( + CupertinoIcons.check_mark_circled, + color: new Color(0xf646464), + size: 20.0f + ) + } + ) + } + ) + ) + ) + } + ) + ) + ) + ); + } + } - public readonly string text; - public readonly Tab2ConversationBubbleColor color; + enum Tab2ConversationBubbleColor { + blue, + gray, + } - public override Widget build(BuildContext context) { - return new Container( - decoration: new BoxDecoration( - borderRadius: BorderRadius.all(Radius.circular(18.0f)), + class Tab2ConversationBubble : StatelessWidget { + public Tab2ConversationBubble( + string text, + Tab2ConversationBubbleColor color + ) { + this.text = text; + this.color = color; + } + + public readonly string text; + public readonly Tab2ConversationBubbleColor color; + + public override Widget build(BuildContext context) { + return new Container( + decoration: new BoxDecoration( + borderRadius: BorderRadius.all(Radius.circular(18.0f)), + color: this.color == Tab2ConversationBubbleColor.blue + ? CupertinoColors.activeBlue + : CupertinoColors.lightBackgroundGray + ), + margin: EdgeInsets.symmetric(horizontal: 8.0f, vertical: 8.0f), + padding: EdgeInsets.symmetric(horizontal: 14.0f, vertical: 10.0f), + child: new Text(this.text, + style: new TextStyle( color: this.color == Tab2ConversationBubbleColor.blue - ? CupertinoColors.activeBlue - : CupertinoColors.lightBackgroundGray - ), - margin: EdgeInsets.symmetric(horizontal: 8.0f, vertical: 8.0f), - padding: EdgeInsets.symmetric(horizontal: 14.0f, vertical: 10.0f), - child: new Text(this.text, - style: new TextStyle( - color: this.color == Tab2ConversationBubbleColor.blue - ? CupertinoColors.white - : CupertinoColors.black, - letterSpacing: -0.4f, - fontSize: 15.0f, - fontWeight: FontWeight.w400 - ) + ? CupertinoColors.white + : CupertinoColors.black, + letterSpacing: -0.4f, + fontSize: 15.0f, + fontWeight: FontWeight.w400 ) - ); - } + ) + ); } + } - class Tab2ConversationAvatar : StatelessWidget { - public Tab2ConversationAvatar( - string text, - Color color - ) { - this.text = text; - this.color = color; - } + class Tab2ConversationAvatar : StatelessWidget { + public Tab2ConversationAvatar( + string text, + Color color + ) { + this.text = text; + this.color = color; + } - public readonly string text; - public readonly Color color; + public readonly string text; + public readonly Color color; - public override Widget build(BuildContext context) { - return new Container( - decoration: new BoxDecoration( - shape: BoxShape.circle, - gradient: new LinearGradient( - begin: Alignment.topCenter, // FractionalOfset.topCenter, - end: Alignment.bottomCenter, // FractionalOfset.bottomCenter, - colors: new List { - this.color, - Color.fromARGB(this.color.alpha, - (this.color.red - 60).clamp(0, 255), - (this.color.green - 60).clamp(0, 255), - (this.color.blue - 60).clamp(0, 255) - ) - } - ) - ), - margin: EdgeInsets.only(left: 8.0f, bottom: 8.0f), - padding: EdgeInsets.all(12.0f), - child: new Text(this.text, - style: new TextStyle( - color: CupertinoColors.white, - fontSize: 13.0f, - fontWeight: FontWeight.w500 - ) + public override Widget build(BuildContext context) { + return new Container( + decoration: new BoxDecoration( + shape: BoxShape.circle, + gradient: new LinearGradient( + begin: Alignment.topCenter, // FractionalOfset.topCenter, + end: Alignment.bottomCenter, // FractionalOfset.bottomCenter, + colors: new List { + this.color, + Color.fromARGB(this.color.alpha, + (this.color.red - 60).clamp(0, 255), + (this.color.green - 60).clamp(0, 255), + (this.color.blue - 60).clamp(0, 255) + ) + } ) - ); - } + ), + margin: EdgeInsets.only(left: 8.0f, bottom: 8.0f), + padding: EdgeInsets.all(12.0f), + child: new Text(this.text, + style: new TextStyle( + color: CupertinoColors.white, + fontSize: 13.0f, + fontWeight: FontWeight.w500 + ) + ) + ); } + } - class Tab2ConversationRow : StatelessWidget { - public Tab2ConversationRow( - string text, - Tab2ConversationAvatar avatar = null - ) { - this.avatar = avatar; - this.text = text; - } - - public readonly Tab2ConversationAvatar avatar; - public readonly string text; + class Tab2ConversationRow : StatelessWidget { + public Tab2ConversationRow( + string text, + Tab2ConversationAvatar avatar = null + ) { + this.avatar = avatar; + this.text = text; + } - public override Widget build(BuildContext context) { - List children = new List(); + public readonly Tab2ConversationAvatar avatar; + public readonly string text; - if (this.avatar != null) { - children.Add(this.avatar); - } + public override Widget build(BuildContext context) { + List children = new List(); - bool isSelf = this.avatar == null; - children.Add( - new Tab2ConversationBubble( - text: this.text, - color: isSelf - ? Tab2ConversationBubbleColor.blue - : Tab2ConversationBubbleColor.gray - ) - ); - return new SafeArea( - child: new Row( - mainAxisAlignment: isSelf ? MainAxisAlignment.end : MainAxisAlignment.start, - mainAxisSize: MainAxisSize.min, - crossAxisAlignment: isSelf ? CrossAxisAlignment.center : CrossAxisAlignment.end, - children: children - ) - ); + if (this.avatar != null) { + children.Add(this.avatar); } + + bool isSelf = this.avatar == null; + children.Add( + new Tab2ConversationBubble( + text: this.text, + color: isSelf + ? Tab2ConversationBubbleColor.blue + : Tab2ConversationBubbleColor.gray + ) + ); + return new SafeArea( + child: new Row( + mainAxisAlignment: isSelf ? MainAxisAlignment.end : MainAxisAlignment.start, + mainAxisSize: MainAxisSize.min, + crossAxisAlignment: isSelf ? CrossAxisAlignment.center : CrossAxisAlignment.end, + children: children + ) + ); } } + class CupertinoDemoTab3 : StatelessWidget { public override Widget build(BuildContext context) { return new CupertinoPageScaffold( @@ -838,5 +836,4 @@ public override Widget build(BuildContext context) { ); } } - */ } \ No newline at end of file diff --git a/Samples/UIWidgetsGallery/demo/cupertino/cupertino_slider_demo.cs b/Samples/UIWidgetsGallery/demo/cupertino/cupertino_slider_demo.cs index d0efa803..58cef5f9 100644 --- a/Samples/UIWidgetsGallery/demo/cupertino/cupertino_slider_demo.cs +++ b/Samples/UIWidgetsGallery/demo/cupertino/cupertino_slider_demo.cs @@ -30,21 +30,20 @@ public override Widget build(BuildContext context) { child: new Column( mainAxisAlignment: MainAxisAlignment.spaceAround, children: new List { - // TODO: FIX BUG - // new Column( - // mainAxisSize: MainAxisSize.min, - // children: new List { - // new CupertinoSlider( - // value: this._value, - // min: 0.0f, - // max: 100.0f, - // onChanged: (float value) => { - // this.setState(() => { this._value = value; }); - // } - // ), - // new Text($"Cupertino Continuous: {this._value.ToString("F1")}"), - // } - // ), + new Column( + mainAxisSize: MainAxisSize.min, + children: new List { + new CupertinoSlider( + value: this._value, + min: 0.0f, + max: 100.0f, + onChanged: (float value) => { + this.setState(() => { this._value = value; }); + } + ), + new Text($"Cupertino Continuous: {this._value.ToString("F1")}"), + } + ), new Column( mainAxisSize: MainAxisSize.min, children: new List { diff --git a/Samples/UIWidgetsGallery/gallery/demos.cs b/Samples/UIWidgetsGallery/gallery/demos.cs index e0509fd6..93e53118 100644 --- a/Samples/UIWidgetsGallery/gallery/demos.cs +++ b/Samples/UIWidgetsGallery/gallery/demos.cs @@ -502,10 +502,10 @@ static List _buildGalleryDemos() { // new GalleryDemo( // title: "Navigation", // icon: GalleryIcons.bottom_navigation, - // category: GalleryDemoCategory._kCupertinoComponents, + // category: _kCupertinoComponents, // routeName: CupertinoNavigationDemo.routeName, // documentationUrl: "https://docs.flutter.io/flutter/cupertino/CupertinoTabScaffold-class.html", - // buildRoute: (BuildContext context) => CupertinoNavigationDemo() + // buildRoute: (BuildContext context) => new CupertinoNavigationDemo() // ), // new GalleryDemo( // title: "Pickers",