浏览代码
Merge branch 'material' into 'master'
Merge branch 'material' into 'master'
Material Scaffold See merge request upm-packages/ui-widgets/com.unity.uiwidgets!120/main
Shenhua Gu
6 年前
当前提交
de6befa5
共有 39 个文件被更改,包括 3664 次插入 和 86 次删除
-
42Runtime/material/app.cs
-
10Runtime/material/button_theme.cs
-
3Runtime/material/list_tile.cs
-
5Runtime/material/page_transitions_theme.cs
-
31Runtime/material/popup_menu.cs
-
6Runtime/material/theme.cs
-
107Runtime/material/theme_data.cs
-
125Runtime/rendering/layer.cs
-
157Runtime/rendering/proxy_box.cs
-
16Runtime/service/system_chrome.cs
-
20Runtime/ui/compositing.cs
-
126Runtime/widgets/app.cs
-
2Runtime/widgets/framework.cs
-
19Runtime/widgets/localizations.cs
-
36Runtime/widgets/transitions.cs
-
198Samples/UIWidgetSample/MaterialSample.cs
-
140Samples/UIWidgetSample/UIWidgetSample.unity
-
82Runtime/flow/physical_shape_layer.cs
-
11Runtime/flow/physical_shape_layer.cs.meta
-
301Runtime/material/app_bar.cs
-
11Runtime/material/app_bar.cs.meta
-
60Runtime/material/back_button.cs
-
11Runtime/material/back_button.cs.meta
-
127Runtime/material/bottom_sheet.cs
-
11Runtime/material/bottom_sheet.cs.meta
-
221Runtime/material/flexible_space_bar.cs
-
11Runtime/material/flexible_space_bar.cs.meta
-
282Runtime/material/float_action_button.cs
-
11Runtime/material/float_action_button.cs.meta
-
223Runtime/material/float_action_button_location.cs
-
11Runtime/material/float_action_button_location.cs.meta
-
1001Runtime/material/scaffold.cs
-
11Runtime/material/scaffold.cs.meta
-
220Runtime/material/snack_bar.cs
-
11Runtime/material/snack_bar.cs.meta
-
33Runtime/widgets/annotated_region.cs
-
11Runtime/widgets/annotated_region.cs.meta
-
36Runtime/widgets/perferred_size.cs
-
11Runtime/widgets/perferred_size.cs.meta
|
|||
using Unity.UIWidgets.ui; |
|||
|
|||
namespace Unity.UIWidgets.flow { |
|||
public class PhysicalShapeLayer : ContainerLayer { |
|||
public PhysicalShapeLayer( |
|||
Clip clipBehavior) { |
|||
this._isRect = false; |
|||
this._clip_behavior = clipBehavior; |
|||
} |
|||
|
|||
float _elevation; |
|||
Color _color; |
|||
Color _shadow_color; |
|||
float _device_pixel_ratio; |
|||
Path _path; |
|||
bool _isRect; |
|||
Rect _frameRRect; |
|||
Clip _clip_behavior; |
|||
|
|||
public Path path { |
|||
set { |
|||
//todo: xingwei.zhu : try to do path => rect transfer
|
|||
this._path = value; |
|||
this._isRect = false; |
|||
this._frameRRect = value.getBounds(); |
|||
} |
|||
} |
|||
|
|||
public float elevation { |
|||
set { this._elevation = value; } |
|||
} |
|||
|
|||
public Color color { |
|||
set { this._color = value; } |
|||
} |
|||
|
|||
public Color shadowColor { |
|||
set { this._shadow_color = value; } |
|||
} |
|||
|
|||
public float devicePixelRatio { |
|||
set { this._device_pixel_ratio = value; } |
|||
} |
|||
|
|||
public override void preroll(PrerollContext context, Matrix3 matrix) { |
|||
Rect child_paint_bounds = Rect.zero; |
|||
this.prerollChildren(context, matrix, ref child_paint_bounds); |
|||
|
|||
if (this._elevation == 0) { |
|||
this.paintBounds = this._path.getBounds(); |
|||
} |
|||
else { |
|||
Rect bounds = this._path.getBounds(); |
|||
//todo xingwei.zhu: outter set shadow
|
|||
//bounds.outset(20.0f, 20.0f);
|
|||
this.paintBounds = bounds; |
|||
} |
|||
} |
|||
|
|||
public override void paint(PaintContext context) { |
|||
if (this._elevation != 0) { |
|||
this.drawShadow(context.canvas, this._path, this._shadow_color, this._elevation, |
|||
this._color.alpha != 255, this._device_pixel_ratio); |
|||
} |
|||
|
|||
Paint paint = new Paint {color = this._color}; |
|||
//todo: xingwei.zhu: process according to different clipBehavior, currently use antiAlias as default
|
|||
|
|||
context.canvas.drawPath(this._path, paint); |
|||
|
|||
context.canvas.save(); |
|||
context.canvas.clipPath(this._path); |
|||
this.paintChildren(context); |
|||
context.canvas.restore(); |
|||
} |
|||
|
|||
|
|||
void drawShadow(Canvas canvas, Path path, Color color, float elevation, bool transparentOccluder, float dpr) { |
|||
//todo xingwei.zhu: to be implemented
|
|||
} |
|||
} |
|||
} |
|
|||
fileFormatVersion: 2 |
|||
guid: e4609617e4ba5483b811e8cc9d60ce15 |
|||
MonoImporter: |
|||
externalObjects: {} |
|||
serializedVersion: 2 |
|||
defaultReferences: [] |
|||
executionOrder: 0 |
|||
icon: {instanceID: 0} |
|||
userData: |
|||
assetBundleName: |
|||
assetBundleVariant: |
|
|||
using System.Collections.Generic; |
|||
using Unity.UIWidgets.animation; |
|||
using Unity.UIWidgets.foundation; |
|||
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; |
|||
using TextStyle = Unity.UIWidgets.painting.TextStyle; |
|||
|
|||
namespace Unity.UIWidgets.material { |
|||
static class AppBarUtils { |
|||
internal const float _kLeadingWidth = Constants.kToolbarHeight; |
|||
} |
|||
|
|||
class _ToolbarContainerLayout : SingleChildLayoutDelegate { |
|||
public _ToolbarContainerLayout() { |
|||
} |
|||
|
|||
public override BoxConstraints getConstraintsForChild(BoxConstraints constraints) { |
|||
return constraints.tighten(height: Constants.kToolbarHeight); |
|||
} |
|||
|
|||
public override Size getSize(BoxConstraints constraints) { |
|||
return new Size(constraints.maxWidth, Constants.kToolbarHeight); |
|||
} |
|||
|
|||
public override Offset getPositionForChild(Size size, Size childSize) { |
|||
return new Offset(0.0f, size.height - childSize.height); |
|||
} |
|||
|
|||
public override bool shouldRelayout(SingleChildLayoutDelegate oldDelegate) { |
|||
return false; |
|||
} |
|||
} |
|||
|
|||
public class AppBar : PreferredSizeWidget { |
|||
public AppBar( |
|||
Key key = null, |
|||
Widget leading = null, |
|||
bool automaticallyImplyLeading = true, |
|||
Widget title = null, |
|||
List<Widget> actions = null, |
|||
Widget flexibleSpace = null, |
|||
PreferredSizeWidget bottom = null, |
|||
float elevation = 4.0f, |
|||
Color backgroundColor = null, |
|||
Brightness? brightness = null, |
|||
IconThemeData iconTheme = null, |
|||
TextTheme textTheme = null, |
|||
bool primary = true, |
|||
bool? centerTitle = null, |
|||
float titleSpacing = NavigationToolbar.kMiddleSpacing, |
|||
float toolbarOpacity = 1.0f, |
|||
float bottomOpacity = 1.0f |
|||
) : base(key: key) { |
|||
this.leading = leading; |
|||
this.automaticallyImplyLeading = automaticallyImplyLeading; |
|||
this.title = title; |
|||
this.actions = actions; |
|||
this.flexibleSpace = flexibleSpace; |
|||
this.bottom = bottom; |
|||
this.elevation = elevation; |
|||
this.backgroundColor = backgroundColor; |
|||
this.brightness = brightness; |
|||
this.iconTheme = iconTheme; |
|||
this.textTheme = textTheme; |
|||
this.primary = primary; |
|||
this.centerTitle = centerTitle; |
|||
this.titleSpacing = titleSpacing; |
|||
this.toolbarOpacity = toolbarOpacity; |
|||
this.bottomOpacity = bottomOpacity; |
|||
this.preferredSize = Size.fromHeight(Constants.kToolbarHeight + (bottom?.preferredSize?.height ?? 0.0f)); |
|||
} |
|||
|
|||
public readonly Widget leading; |
|||
|
|||
public readonly bool automaticallyImplyLeading; |
|||
|
|||
public readonly Widget title; |
|||
|
|||
public readonly List<Widget> actions; |
|||
|
|||
public readonly Widget flexibleSpace; |
|||
|
|||
public readonly PreferredSizeWidget bottom; |
|||
|
|||
public readonly float elevation; |
|||
|
|||
public readonly Color backgroundColor; |
|||
|
|||
public readonly Brightness? brightness; |
|||
|
|||
public readonly IconThemeData iconTheme; |
|||
|
|||
public readonly TextTheme textTheme; |
|||
|
|||
public readonly bool primary; |
|||
|
|||
public readonly bool? centerTitle; |
|||
|
|||
public readonly float titleSpacing; |
|||
|
|||
public readonly float toolbarOpacity; |
|||
|
|||
public readonly float bottomOpacity; |
|||
|
|||
public override Size preferredSize { get; } |
|||
|
|||
public bool? _getEffectiveCenterTitle(ThemeData themeData) { |
|||
if (this.centerTitle != null) { |
|||
return this.centerTitle; |
|||
} |
|||
|
|||
D.assert(themeData.platform != null); |
|||
switch (themeData.platform) { |
|||
case RuntimePlatform.IPhonePlayer: |
|||
return this.actions == null || this.actions.Count < 2; |
|||
default: |
|||
return false; |
|||
} |
|||
|
|||
return null; |
|||
} |
|||
|
|||
public override State createState() { |
|||
return new _AppBarState(); |
|||
} |
|||
} |
|||
|
|||
|
|||
class _AppBarState : State<AppBar> { |
|||
void _handleDrawerButton() { |
|||
Scaffold.of(this.context).openDrawer(); |
|||
} |
|||
|
|||
void _handleDrawerButtonEnd() { |
|||
Scaffold.of(this.context).openEndDrawer(); |
|||
} |
|||
|
|||
public override Widget build(BuildContext context) { |
|||
D.assert(MaterialD.debugCheckHasMaterialLocalizations(context)); |
|||
ThemeData themeData = Theme.of(context); |
|||
ScaffoldState scaffold = Scaffold.of(context, nullOk: true); |
|||
ModalRoute parentRoute = ModalRoute.of(context); |
|||
|
|||
bool hasDrawer = scaffold?.hasDrawer ?? false; |
|||
bool hasEndDrawer = scaffold?.hasEndDrawer ?? false; |
|||
bool canPop = parentRoute?.canPop ?? false; |
|||
bool useCloseButton = parentRoute is PageRoute && ((PageRoute) parentRoute).fullscreenDialog; |
|||
|
|||
IconThemeData appBarIconTheme = this.widget.iconTheme ?? themeData.primaryIconTheme; |
|||
TextStyle centerStyle = this.widget.textTheme?.title ?? themeData.primaryTextTheme.title; |
|||
TextStyle sideStyle = this.widget.textTheme?.body1 ?? themeData.primaryTextTheme.body1; |
|||
|
|||
if (this.widget.toolbarOpacity != 1.0f) { |
|||
float opacity = |
|||
new Interval(0.25f, 1.0f, curve: Curves.fastOutSlowIn).transform(this.widget.toolbarOpacity); |
|||
if (centerStyle?.color != null) { |
|||
centerStyle = centerStyle.copyWith(color: centerStyle.color.withOpacity(opacity)); |
|||
} |
|||
|
|||
if (sideStyle?.color != null) { |
|||
sideStyle = sideStyle.copyWith(color: sideStyle.color.withOpacity(opacity)); |
|||
} |
|||
|
|||
appBarIconTheme = appBarIconTheme.copyWith( |
|||
opacity: opacity * (appBarIconTheme.opacity ?? 1.0f) |
|||
); |
|||
} |
|||
|
|||
Widget leading = this.widget.leading; |
|||
if (leading == null && this.widget.automaticallyImplyLeading) { |
|||
if (hasDrawer) { |
|||
leading = new IconButton( |
|||
icon: new Icon(Icons.menu), |
|||
onPressed: this._handleDrawerButton, |
|||
tooltip: MaterialLocalizations.of(context).openAppDrawerTooltip); |
|||
} |
|||
else { |
|||
if (canPop) { |
|||
leading = useCloseButton ? (Widget) new CloseButton() : new BackButton(); |
|||
} |
|||
} |
|||
} |
|||
|
|||
if (leading != null) { |
|||
leading = new ConstrainedBox( |
|||
constraints: BoxConstraints.tightFor(width: AppBarUtils._kLeadingWidth), |
|||
child: leading); |
|||
} |
|||
|
|||
Widget title = this.widget.title; |
|||
if (title != null) { |
|||
bool namesRoute = false; |
|||
switch (Application.platform) { |
|||
case RuntimePlatform.IPhonePlayer: |
|||
break; |
|||
default: |
|||
namesRoute = true; |
|||
break; |
|||
} |
|||
|
|||
title = new DefaultTextStyle( |
|||
style: centerStyle, |
|||
softWrap: false, |
|||
overflow: TextOverflow.ellipsis, |
|||
child: title); |
|||
} |
|||
|
|||
Widget actions = null; |
|||
if (this.widget.actions != null && this.widget.actions.isNotEmpty()) { |
|||
actions = new Row( |
|||
mainAxisSize: MainAxisSize.min, |
|||
crossAxisAlignment: CrossAxisAlignment.stretch, |
|||
children: this.widget.actions); |
|||
} |
|||
else if (hasEndDrawer) { |
|||
actions = new IconButton( |
|||
icon: new Icon(Icons.menu), |
|||
onPressed: this._handleDrawerButtonEnd, |
|||
tooltip: MaterialLocalizations.of(context).openAppDrawerTooltip); |
|||
} |
|||
|
|||
Widget toolbar = new NavigationToolbar( |
|||
leading: leading, |
|||
middle: title, |
|||
trailing: actions, |
|||
centerMiddle: this.widget._getEffectiveCenterTitle(themeData).Value, |
|||
middleSpacing: this.widget.titleSpacing); |
|||
|
|||
Widget appBar = new ClipRect( |
|||
child: new CustomSingleChildLayout( |
|||
layoutDelegate: new _ToolbarContainerLayout(), |
|||
child: IconTheme.merge( |
|||
data: appBarIconTheme, |
|||
child: new DefaultTextStyle( |
|||
style: sideStyle, |
|||
child: toolbar) |
|||
) |
|||
) |
|||
); |
|||
|
|||
if (this.widget.bottom != null) { |
|||
appBar = new Column( |
|||
mainAxisAlignment: MainAxisAlignment.spaceBetween, |
|||
children: new List<Widget> { |
|||
new Flexible( |
|||
child: new ConstrainedBox( |
|||
constraints: new BoxConstraints(maxHeight: Constants.kToolbarHeight), |
|||
child: appBar |
|||
) |
|||
), |
|||
this.widget.bottomOpacity == 1.0f |
|||
? (Widget) this.widget.bottom |
|||
: new Opacity( |
|||
opacity: new Interval(0.25f, 1.0f, curve: Curves.fastOutSlowIn).transform(this.widget |
|||
.bottomOpacity), |
|||
child: this.widget.bottom |
|||
) |
|||
} |
|||
); |
|||
} |
|||
|
|||
if (this.widget.primary) { |
|||
appBar = new SafeArea( |
|||
top: true, |
|||
child: appBar); |
|||
} |
|||
|
|||
appBar = new Align( |
|||
alignment: Alignment.topCenter, |
|||
child: appBar); |
|||
|
|||
if (this.widget.flexibleSpace != null) { |
|||
appBar = new Stack( |
|||
fit: StackFit.passthrough, |
|||
children: new List<Widget> { |
|||
this.widget.flexibleSpace, |
|||
appBar |
|||
} |
|||
); |
|||
} |
|||
|
|||
Brightness brightness = this.widget.brightness ?? themeData.primaryColorBrightness; |
|||
SystemUiOverlayStyle overlayStyle = brightness == Brightness.dark |
|||
? SystemUiOverlayStyle.light |
|||
: SystemUiOverlayStyle.dark; |
|||
|
|||
return new AnnotatedRegion<SystemUiOverlayStyle>( |
|||
value: overlayStyle, |
|||
child: new Material( |
|||
color: this.widget.backgroundColor ?? themeData.primaryColor, |
|||
elevation: this.widget.elevation, |
|||
child: appBar |
|||
)); |
|||
} |
|||
} |
|||
} |
|
|||
fileFormatVersion: 2 |
|||
guid: da897030c4af84749a3ac5494e45c359 |
|||
MonoImporter: |
|||
externalObjects: {} |
|||
serializedVersion: 2 |
|||
defaultReferences: [] |
|||
executionOrder: 0 |
|||
icon: {instanceID: 0} |
|||
userData: |
|||
assetBundleName: |
|||
assetBundleVariant: |
|
|||
using Unity.UIWidgets.foundation; |
|||
using Unity.UIWidgets.widgets; |
|||
using UnityEngine; |
|||
using Color = Unity.UIWidgets.ui.Color; |
|||
|
|||
namespace Unity.UIWidgets.material { |
|||
public class BackButtonIcon : StatelessWidget { |
|||
public BackButtonIcon( |
|||
Key key = null) : base(key: key) { |
|||
} |
|||
|
|||
static IconData _getIconData(RuntimePlatform platform) { |
|||
switch (platform) { |
|||
case RuntimePlatform.IPhonePlayer: |
|||
return Icons.arrow_back_ios; |
|||
default: |
|||
return Icons.arrow_back; |
|||
} |
|||
|
|||
D.assert(false); |
|||
return null; |
|||
} |
|||
|
|||
public override Widget build(BuildContext context) { |
|||
return new Icon(_getIconData(Theme.of(context).platform)); |
|||
} |
|||
} |
|||
|
|||
public class BackButton : StatelessWidget { |
|||
public BackButton( |
|||
Key key = null, |
|||
Color color = null) : base(key: key) { |
|||
this.color = color; |
|||
} |
|||
|
|||
public readonly Color color; |
|||
|
|||
public override Widget build(BuildContext context) { |
|||
return new IconButton( |
|||
icon: new BackButtonIcon(), |
|||
color: this.color, |
|||
tooltip: MaterialLocalizations.of(context).backButtonTooltip, |
|||
onPressed: () => { Navigator.maybePop(context); }); |
|||
} |
|||
} |
|||
|
|||
public class CloseButton : StatelessWidget { |
|||
public CloseButton( |
|||
Key key = null) : base(key: key) { |
|||
} |
|||
|
|||
public override Widget build(BuildContext context) { |
|||
D.assert(MaterialD.debugCheckHasMaterialLocalizations(context)); |
|||
return new IconButton( |
|||
icon: new Icon(Icons.close), |
|||
tooltip: MaterialLocalizations.of(context).closeButtonTooltip, |
|||
onPressed: () => { Navigator.maybePop(context); }); |
|||
} |
|||
} |
|||
} |
|
|||
fileFormatVersion: 2 |
|||
guid: 485e2aa6981384670925d74e140d54b4 |
|||
MonoImporter: |
|||
externalObjects: {} |
|||
serializedVersion: 2 |
|||
defaultReferences: [] |
|||
executionOrder: 0 |
|||
icon: {instanceID: 0} |
|||
userData: |
|||
assetBundleName: |
|||
assetBundleVariant: |
|
|||
using System; |
|||
using Unity.UIWidgets.animation; |
|||
using Unity.UIWidgets.foundation; |
|||
using Unity.UIWidgets.gestures; |
|||
using Unity.UIWidgets.rendering; |
|||
using Unity.UIWidgets.scheduler; |
|||
using Unity.UIWidgets.ui; |
|||
using Unity.UIWidgets.widgets; |
|||
|
|||
namespace Unity.UIWidgets.material { |
|||
static class BottomSheetUtils { |
|||
public static readonly TimeSpan _kBottomSheetDuration = new TimeSpan(0, 0, 0, 0, 200); |
|||
public const float _kMinFlingVelocity = 700.0f; |
|||
public const float _kCloseProgressThreshold = 0.5f; |
|||
} |
|||
|
|||
|
|||
public class BottomSheet : StatefulWidget { |
|||
public BottomSheet( |
|||
Key key = null, |
|||
AnimationController animationController = null, |
|||
bool enableDrag = true, |
|||
float elevation = 0.0f, |
|||
VoidCallback onClosing = null, |
|||
WidgetBuilder builder = null |
|||
) : base(key: key) { |
|||
D.assert(onClosing != null); |
|||
D.assert(builder != null); |
|||
this.animationController = animationController; |
|||
this.enableDrag = enableDrag; |
|||
this.elevation = elevation; |
|||
this.onClosing = onClosing; |
|||
this.builder = builder; |
|||
} |
|||
|
|||
public readonly AnimationController animationController; |
|||
|
|||
public readonly VoidCallback onClosing; |
|||
|
|||
public readonly WidgetBuilder builder; |
|||
|
|||
public readonly bool enableDrag; |
|||
|
|||
public readonly float elevation; |
|||
|
|||
public override State createState() { |
|||
return new _BottomSheetState(); |
|||
} |
|||
|
|||
public static AnimationController createAnimationController(TickerProvider vsync) { |
|||
return new AnimationController( |
|||
duration: BottomSheetUtils._kBottomSheetDuration, |
|||
debugLabel: "BottomSheet", |
|||
vsync: vsync |
|||
); |
|||
} |
|||
} |
|||
|
|||
|
|||
class _BottomSheetState : State<BottomSheet> { |
|||
readonly GlobalKey _childKey = GlobalKey.key(debugLabel: "BottomSheet child"); |
|||
|
|||
float? _childHeight { |
|||
get { |
|||
RenderBox renderBox = (RenderBox) this._childKey.currentContext.findRenderObject(); |
|||
return renderBox.size.height; |
|||
} |
|||
} |
|||
|
|||
bool _dismissUnderway { |
|||
get { return this.widget.animationController.status == AnimationStatus.reverse; } |
|||
} |
|||
|
|||
void _handleDragUpdate(DragUpdateDetails details) { |
|||
if (this._dismissUnderway) { |
|||
return; |
|||
} |
|||
|
|||
this.widget.animationController.setValue( |
|||
this.widget.animationController.value - |
|||
details.primaryDelta.Value / (this._childHeight ?? details.primaryDelta.Value)); |
|||
} |
|||
|
|||
void _handleDragEnd(DragEndDetails details) { |
|||
if (this._dismissUnderway) { |
|||
return; |
|||
} |
|||
|
|||
if (details.velocity.pixelsPerSecond.dy > BottomSheetUtils._kMinFlingVelocity) { |
|||
float flingVelocity = -details.velocity.pixelsPerSecond.dy / this._childHeight.Value; |
|||
if (this.widget.animationController.value > 0.0f) { |
|||
this.widget.animationController.fling(velocity: flingVelocity); |
|||
} |
|||
|
|||
if (flingVelocity < 0.0f) { |
|||
this.widget.onClosing(); |
|||
} |
|||
} |
|||
else if (this.widget.animationController.value < BottomSheetUtils._kCloseProgressThreshold) { |
|||
if (this.widget.animationController.value > 0.0f) { |
|||
this.widget.animationController.fling(velocity: -1.0f); |
|||
} |
|||
|
|||
this.widget.onClosing(); |
|||
} |
|||
else { |
|||
this.widget.animationController.forward(); |
|||
} |
|||
} |
|||
|
|||
public override Widget build(BuildContext context) { |
|||
Widget bottomSheet = new Material( |
|||
key: this._childKey, |
|||
elevation: this.widget.elevation, |
|||
child: this.widget.builder(context) |
|||
); |
|||
|
|||
return !this.widget.enableDrag |
|||
? bottomSheet |
|||
: new GestureDetector( |
|||
onVerticalDragUpdate: this._handleDragUpdate, |
|||
onVerticalDragEnd: this._handleDragEnd, |
|||
child: bottomSheet |
|||
); |
|||
} |
|||
} |
|||
} |
|
|||
fileFormatVersion: 2 |
|||
guid: 5219593daa853417ebb5f7835c74a969 |
|||
MonoImporter: |
|||
externalObjects: {} |
|||
serializedVersion: 2 |
|||
defaultReferences: [] |
|||
executionOrder: 0 |
|||
icon: {instanceID: 0} |
|||
userData: |
|||
assetBundleName: |
|||
assetBundleVariant: |
|
|||
using System.Collections.Generic; |
|||
using Unity.UIWidgets.animation; |
|||
using Unity.UIWidgets.foundation; |
|||
using Unity.UIWidgets.painting; |
|||
using Unity.UIWidgets.ui; |
|||
using Unity.UIWidgets.widgets; |
|||
using UnityEngine; |
|||
using TextStyle = Unity.UIWidgets.painting.TextStyle; |
|||
using Transform = Unity.UIWidgets.widgets.Transform; |
|||
|
|||
namespace Unity.UIWidgets.material { |
|||
public enum CollapseMode { |
|||
parallax, |
|||
pin, |
|||
none |
|||
} |
|||
|
|||
public class FlexibleSpaceBar : StatefulWidget { |
|||
public FlexibleSpaceBar( |
|||
Key key = null, |
|||
Widget title = null, |
|||
Widget background = null, |
|||
bool? centerTitle = null, |
|||
CollapseMode collapseMode = CollapseMode.parallax |
|||
) : base(key: key) { |
|||
this.title = title; |
|||
this.background = background; |
|||
this.centerTitle = centerTitle; |
|||
this.collapseMode = collapseMode; |
|||
} |
|||
|
|||
public readonly Widget title; |
|||
|
|||
public readonly Widget background; |
|||
|
|||
public readonly bool? centerTitle; |
|||
|
|||
public readonly CollapseMode collapseMode; |
|||
|
|||
public static Widget createSettings( |
|||
float? toolbarOpacity = null, |
|||
float? minExtent = null, |
|||
float? maxExtent = null, |
|||
float? currentExtent = null, |
|||
Widget child = null) { |
|||
D.assert(currentExtent != null); |
|||
D.assert(child != null); |
|||
return new FlexibleSpaceBarSettings( |
|||
toolbarOpacity: toolbarOpacity ?? 1.0f, |
|||
minExtent: minExtent ?? currentExtent, |
|||
maxExtent: maxExtent ?? currentExtent, |
|||
currentExtent: currentExtent, |
|||
child: child |
|||
); |
|||
} |
|||
|
|||
public override State createState() { |
|||
return new _FlexibleSpaceBarState(); |
|||
} |
|||
} |
|||
|
|||
|
|||
class _FlexibleSpaceBarState : State<FlexibleSpaceBar> { |
|||
bool? _getEffectiveCenterTitle(ThemeData themeData) { |
|||
if (this.widget.centerTitle != null) { |
|||
return this.widget.centerTitle; |
|||
} |
|||
|
|||
D.assert(themeData.platform != null); |
|||
switch (themeData.platform) { |
|||
case RuntimePlatform.IPhonePlayer: |
|||
return true; |
|||
default: |
|||
return false; |
|||
} |
|||
|
|||
return null; |
|||
} |
|||
|
|||
|
|||
Alignment _getTitleAlignment(bool effectiveCenterTitle) { |
|||
if (effectiveCenterTitle) { |
|||
return Alignment.bottomCenter; |
|||
} |
|||
|
|||
return Alignment.bottomLeft; |
|||
} |
|||
|
|||
float? _getCollapsePadding(float t, FlexibleSpaceBarSettings settings) { |
|||
switch (this.widget.collapseMode) { |
|||
case CollapseMode.pin: |
|||
return -(settings.maxExtent.Value - settings.currentExtent.Value); |
|||
case CollapseMode.none: |
|||
return 0.0f; |
|||
case CollapseMode.parallax: |
|||
float deltaExtent = settings.maxExtent.Value - settings.minExtent.Value; |
|||
return -new FloatTween(begin: 0.0f, end: deltaExtent / 4.0f).lerp(t); |
|||
} |
|||
|
|||
return null; |
|||
} |
|||
|
|||
public override Widget build(BuildContext context) { |
|||
FlexibleSpaceBarSettings settings = |
|||
(FlexibleSpaceBarSettings) context.inheritFromWidgetOfExactType(typeof(FlexibleSpaceBarSettings)); |
|||
D.assert(settings != null, |
|||
"A FlexibleSpaceBar must be wrapped in the widget returned by FlexibleSpaceBar.createSettings()."); |
|||
|
|||
List<Widget> children = new List<Widget>(); |
|||
float deltaExtent = settings.maxExtent.Value - settings.minExtent.Value; |
|||
|
|||
float t = (1.0f - (settings.currentExtent.Value - settings.minExtent.Value) / deltaExtent) |
|||
.clamp(0.0f, 1.0f); |
|||
|
|||
if (this.widget.background != null) { |
|||
float fadeStart = Mathf.Max(0.0f, 1.0f - Constants.kToolbarHeight / deltaExtent); |
|||
float fadeEnd = 1.0f; |
|||
D.assert(fadeStart <= fadeEnd); |
|||
|
|||
float opacity = 1.0f - new Interval(fadeStart, fadeEnd).transform(t); |
|||
if (opacity > 0.0f) { |
|||
children.Add(new Positioned( |
|||
top: this._getCollapsePadding(t, settings), |
|||
left: 0.0f, |
|||
right: 0.0f, |
|||
height: settings.maxExtent, |
|||
child: new Opacity( |
|||
opacity: opacity, |
|||
child: this.widget.background) |
|||
) |
|||
); |
|||
} |
|||
} |
|||
|
|||
Widget title = null; |
|||
if (this.widget.title != null) { |
|||
switch (Application.platform) { |
|||
case RuntimePlatform.IPhonePlayer: |
|||
title = this.widget.title; |
|||
break; |
|||
default: |
|||
title = this.widget.title; |
|||
break; |
|||
} |
|||
} |
|||
|
|||
ThemeData theme = Theme.of(context); |
|||
float toolbarOpacity = settings.toolbarOpacity.Value; |
|||
if (toolbarOpacity > 0.0f) { |
|||
TextStyle titleStyle = theme.primaryTextTheme.title; |
|||
titleStyle = titleStyle.copyWith( |
|||
color: titleStyle.color.withOpacity(toolbarOpacity)); |
|||
|
|||
bool effectiveCenterTitle = this._getEffectiveCenterTitle(theme).Value; |
|||
float scaleValue = new FloatTween(begin: 1.5f, end: 1.0f).lerp(t); |
|||
Matrix3 scaleTransform = Matrix3.makeScale(scaleValue, scaleValue); |
|||
Alignment titleAlignment = this._getTitleAlignment(effectiveCenterTitle); |
|||
|
|||
children.Add(new Container( |
|||
padding: EdgeInsets.fromLTRB( |
|||
effectiveCenterTitle ? 0.0f : 72.0f, |
|||
0f, |
|||
0f, |
|||
16.0f), |
|||
child: new Transform( |
|||
alignment: titleAlignment, |
|||
transform: scaleTransform, |
|||
child: new Align( |
|||
alignment: titleAlignment, |
|||
child: new DefaultTextStyle( |
|||
style: titleStyle, |
|||
child: title) |
|||
) |
|||
) |
|||
) |
|||
); |
|||
} |
|||
|
|||
return new ClipRect( |
|||
child: new Stack( |
|||
children: children) |
|||
); |
|||
} |
|||
} |
|||
|
|||
|
|||
public class FlexibleSpaceBarSettings : InheritedWidget { |
|||
public FlexibleSpaceBarSettings( |
|||
Key key = null, |
|||
float? toolbarOpacity = null, |
|||
float? minExtent = null, |
|||
float? maxExtent = null, |
|||
float? currentExtent = null, |
|||
Widget child = null |
|||
) : base(key: key, child: child) { |
|||
D.assert(currentExtent != null); |
|||
D.assert(child != null); |
|||
this.toolbarOpacity = toolbarOpacity; |
|||
this.minExtent = minExtent; |
|||
this.maxExtent = maxExtent; |
|||
this.currentExtent = currentExtent; |
|||
} |
|||
|
|||
public readonly float? toolbarOpacity; |
|||
|
|||
public readonly float? minExtent; |
|||
|
|||
public readonly float? maxExtent; |
|||
|
|||
public readonly float? currentExtent; |
|||
|
|||
|
|||
public override bool updateShouldNotify(InheritedWidget oldWidget) { |
|||
FlexibleSpaceBarSettings _oldWidget = (FlexibleSpaceBarSettings) oldWidget; |
|||
return this.toolbarOpacity != _oldWidget.toolbarOpacity |
|||
|| this.minExtent != _oldWidget.minExtent |
|||
|| this.maxExtent != _oldWidget.maxExtent |
|||
|| this.currentExtent != _oldWidget.currentExtent; |
|||
} |
|||
} |
|||
} |
|
|||
fileFormatVersion: 2 |
|||
guid: ae1ab951014d2444da9ac1419a3f111b |
|||
MonoImporter: |
|||
externalObjects: {} |
|||
serializedVersion: 2 |
|||
defaultReferences: [] |
|||
executionOrder: 0 |
|||
icon: {instanceID: 0} |
|||
userData: |
|||
assetBundleName: |
|||
assetBundleVariant: |
|
|||
using System.Collections.Generic; |
|||
using Unity.UIWidgets.foundation; |
|||
using Unity.UIWidgets.painting; |
|||
using Unity.UIWidgets.rendering; |
|||
using Unity.UIWidgets.ui; |
|||
using Unity.UIWidgets.widgets; |
|||
using UnityEngine; |
|||
using Color = Unity.UIWidgets.ui.Color; |
|||
|
|||
namespace Unity.UIWidgets.material { |
|||
static class FloatActionButtonUtils { |
|||
public static readonly BoxConstraints _kSizeConstraints = BoxConstraints.tightFor(width: 56.0f, height: 56.0f); |
|||
|
|||
public static readonly BoxConstraints _kMiniSizeConstraints = |
|||
BoxConstraints.tightFor(width: 40.0f, height: 40.0f); |
|||
|
|||
public static readonly BoxConstraints _kExtendedSizeConstraints = |
|||
new BoxConstraints(minHeight: 48.0f, maxHeight: 48.0f); |
|||
} |
|||
|
|||
|
|||
class _DefaultHeroTag { |
|||
public _DefaultHeroTag() { |
|||
} |
|||
|
|||
public override string ToString() { |
|||
return "<default FloatingActionButton tag>"; |
|||
} |
|||
} |
|||
|
|||
public class FloatingActionButton : StatefulWidget { |
|||
FloatingActionButton( |
|||
Key key = null, |
|||
Widget child = null, |
|||
string tooltip = null, |
|||
Color foregroundColor = null, |
|||
Color backgroundColor = null, |
|||
object heroTag = null, |
|||
float elevation = 6.0f, |
|||
float highlightElevation = 12.0f, |
|||
VoidCallback onPressed = null, |
|||
bool mini = false, |
|||
ShapeBorder shape = null, |
|||
Clip clipBehavior = Clip.none, |
|||
MaterialTapTargetSize? materialTapTargetSize = null, |
|||
bool isExtended = false, |
|||
BoxConstraints _sizeConstraints = null |
|||
) : base(key: key) { |
|||
heroTag = heroTag ?? new _DefaultHeroTag(); |
|||
shape = shape ?? new CircleBorder(); |
|||
this.child = child; |
|||
this.tooltip = tooltip; |
|||
this.foregroundColor = foregroundColor; |
|||
this.backgroundColor = backgroundColor; |
|||
this.heroTag = heroTag; |
|||
this.elevation = elevation; |
|||
this.highlightElevation = highlightElevation; |
|||
this.onPressed = onPressed; |
|||
this.mini = mini; |
|||
this.shape = shape; |
|||
this.clipBehavior = clipBehavior; |
|||
this.materialTapTargetSize = materialTapTargetSize; |
|||
this.isExtended = isExtended; |
|||
this._sizeConstraints = _sizeConstraints ?? |
|||
(mini |
|||
? FloatActionButtonUtils._kMiniSizeConstraints |
|||
: FloatActionButtonUtils._kSizeConstraints); |
|||
} |
|||
|
|||
public FloatingActionButton( |
|||
Key key = null, |
|||
Widget child = null, |
|||
string tooltip = null, |
|||
Color foregroundColor = null, |
|||
Color backgroundColor = null, |
|||
object heroTag = null, |
|||
float elevation = 6.0f, |
|||
float highlightElevation = 12.0f, |
|||
VoidCallback onPressed = null, |
|||
bool mini = false, |
|||
ShapeBorder shape = null, |
|||
Clip clipBehavior = Clip.none, |
|||
MaterialTapTargetSize? materialTapTargetSize = null, |
|||
bool isExtended = false |
|||
) : this(key: key, |
|||
child: child, |
|||
tooltip: tooltip, |
|||
foregroundColor: foregroundColor, |
|||
backgroundColor: backgroundColor, |
|||
heroTag: heroTag, |
|||
elevation: elevation, |
|||
highlightElevation: highlightElevation, |
|||
onPressed: onPressed, |
|||
mini: mini, |
|||
shape: shape, |
|||
clipBehavior: clipBehavior, |
|||
materialTapTargetSize: materialTapTargetSize, |
|||
isExtended: isExtended, |
|||
_sizeConstraints: null) { |
|||
} |
|||
|
|||
public static FloatingActionButton extended( |
|||
Key key = null, |
|||
string tooltip = null, |
|||
Color foregroundColor = null, |
|||
Color backgroundColor = null, |
|||
object heroTag = null, |
|||
float elevation = 6.0f, |
|||
float highlightElevation = 12.0f, |
|||
VoidCallback onPressed = null, |
|||
ShapeBorder shape = null, |
|||
bool isExtended = true, |
|||
MaterialTapTargetSize? materialTapTargetSize = null, |
|||
Clip clipBehavior = Clip.none, |
|||
Widget icon = null, |
|||
Widget label = null |
|||
) { |
|||
heroTag = heroTag ?? new _DefaultHeroTag(); |
|||
shape = shape ?? new StadiumBorder(); |
|||
D.assert(icon != null); |
|||
D.assert(label != null); |
|||
|
|||
BoxConstraints _sizeConstraints = FloatActionButtonUtils._kExtendedSizeConstraints; |
|||
bool mini = false; |
|||
Widget child = new _ChildOverflowBox( |
|||
child: new Row( |
|||
mainAxisSize: MainAxisSize.min, |
|||
children: new List<Widget> { |
|||
new SizedBox(width: 16.0f), |
|||
icon, |
|||
new SizedBox(width: 8.0f), |
|||
label, |
|||
new SizedBox(width: 20.0f) |
|||
})); |
|||
|
|||
return new FloatingActionButton( |
|||
key: key, |
|||
child: child, |
|||
tooltip: tooltip, |
|||
foregroundColor: foregroundColor, |
|||
backgroundColor: backgroundColor, |
|||
heroTag: heroTag, |
|||
elevation: elevation, |
|||
highlightElevation: highlightElevation, |
|||
onPressed: onPressed, |
|||
mini: mini, |
|||
shape: shape, |
|||
clipBehavior: clipBehavior, |
|||
materialTapTargetSize: materialTapTargetSize, |
|||
isExtended: isExtended, |
|||
_sizeConstraints: _sizeConstraints |
|||
); |
|||
} |
|||
|
|||
public readonly Widget child; |
|||
|
|||
public readonly string tooltip; |
|||
|
|||
public readonly Color foregroundColor; |
|||
|
|||
public readonly Color backgroundColor; |
|||
|
|||
public readonly object heroTag; |
|||
|
|||
public readonly VoidCallback onPressed; |
|||
|
|||
public readonly float elevation; |
|||
|
|||
public readonly float highlightElevation; |
|||
|
|||
public readonly bool mini; |
|||
|
|||
public readonly ShapeBorder shape; |
|||
|
|||
public readonly Clip clipBehavior; |
|||
|
|||
public readonly bool isExtended; |
|||
|
|||
public readonly MaterialTapTargetSize? materialTapTargetSize; |
|||
|
|||
public readonly BoxConstraints _sizeConstraints; |
|||
|
|||
public override State createState() { |
|||
return new _FloatingActionButtonState(); |
|||
} |
|||
} |
|||
|
|||
|
|||
public class _FloatingActionButtonState : State<FloatingActionButton> { |
|||
bool _highlight = false; |
|||
|
|||
void _handleHighlightChanged(bool value) { |
|||
this.setState(() => { this._highlight = value; }); |
|||
} |
|||
|
|||
public override Widget build(BuildContext context) { |
|||
ThemeData theme = Theme.of(context); |
|||
Color foregroundColor = this.widget.foregroundColor ?? theme.accentIconTheme.color; |
|||
Widget result = null; |
|||
|
|||
if (this.widget.child != null) { |
|||
result = IconTheme.merge( |
|||
data: new IconThemeData( |
|||
color: foregroundColor), |
|||
child: this.widget.child |
|||
); |
|||
} |
|||
|
|||
result = new RawMaterialButton( |
|||
onPressed: this.widget.onPressed, |
|||
onHighlightChanged: this._handleHighlightChanged, |
|||
elevation: this._highlight ? this.widget.highlightElevation : this.widget.elevation, |
|||
constraints: this.widget._sizeConstraints, |
|||
materialTapTargetSize: this.widget.materialTapTargetSize ?? theme.materialTapTargetSize, |
|||
fillColor: this.widget.backgroundColor ?? theme.accentColor, |
|||
textStyle: theme.accentTextTheme.button.copyWith( |
|||
color: foregroundColor, |
|||
letterSpacing: 1.2f), |
|||
shape: this.widget.shape, |
|||
clipBehavior: this.widget.clipBehavior, |
|||
child: result); |
|||
|
|||
if (this.widget.tooltip != null) { |
|||
result = new Tooltip( |
|||
message: this.widget.tooltip, |
|||
child: result); |
|||
} |
|||
|
|||
//todo: xingwei.zhu: Hero widget
|
|||
// if (this.widget.heroTag != null) {
|
|||
// result = new Hero(
|
|||
// tag: this.widget.heroTag,
|
|||
// child: result);
|
|||
// }
|
|||
|
|||
return result; |
|||
} |
|||
} |
|||
|
|||
class _ChildOverflowBox : SingleChildRenderObjectWidget { |
|||
public _ChildOverflowBox( |
|||
Key key = null, |
|||
Widget child = null) : base(key: key, child: child) { |
|||
} |
|||
|
|||
public override RenderObject createRenderObject(BuildContext context) { |
|||
return new _RenderChildOverflowBox(); |
|||
} |
|||
|
|||
public override void updateRenderObject(BuildContext context, RenderObject renderObject) { |
|||
} |
|||
} |
|||
|
|||
|
|||
class _RenderChildOverflowBox : RenderAligningShiftedBox { |
|||
public _RenderChildOverflowBox( |
|||
RenderBox child = null) : base(child: child, alignment: Alignment.center) { |
|||
} |
|||
|
|||
protected override float computeMinIntrinsicWidth(float height) { |
|||
return 0.0f; |
|||
} |
|||
|
|||
protected override float computeMinIntrinsicHeight(float width) { |
|||
return 0.0f; |
|||
} |
|||
|
|||
protected override void performLayout() { |
|||
if (this.child != null) { |
|||
this.child.layout(new BoxConstraints(), parentUsesSize: true); |
|||
this.size = new Size( |
|||
Mathf.Max(this.constraints.minWidth, Mathf.Min(this.constraints.maxWidth, this.child.size.width)), |
|||
Mathf.Max(this.constraints.minHeight, Mathf.Min(this.constraints.maxHeight, this.child.size.height)) |
|||
); |
|||
this.alignChild(); |
|||
} |
|||
else { |
|||
this.size = this.constraints.biggest; |
|||
} |
|||
} |
|||
} |
|||
} |
|
|||
fileFormatVersion: 2 |
|||
guid: 274f3c1005cd046a28b169d8048c0292 |
|||
MonoImporter: |
|||
externalObjects: {} |
|||
serializedVersion: 2 |
|||
defaultReferences: [] |
|||
executionOrder: 0 |
|||
icon: {instanceID: 0} |
|||
userData: |
|||
assetBundleName: |
|||
assetBundleVariant: |
|
|||
using System; |
|||
using Unity.UIWidgets.animation; |
|||
using Unity.UIWidgets.ui; |
|||
using UnityEngine; |
|||
|
|||
namespace Unity.UIWidgets.material { |
|||
public static class FloatingActionButtonLocationUtils { |
|||
public const float kFloatingActionButtonMargin = 16.0f; |
|||
|
|||
public static readonly TimeSpan kFloatingActionButtonSegue = new TimeSpan(0, 0, 0, 0, 200); |
|||
|
|||
public const float kFloatingActionButtonTurnInterval = 0.125f; |
|||
} |
|||
|
|||
|
|||
public abstract class FloatingActionButtonLocation { |
|||
protected FloatingActionButtonLocation() { |
|||
} |
|||
|
|||
public static readonly FloatingActionButtonLocation endFloat = new _EndFloatFabLocation(); |
|||
|
|||
public static readonly FloatingActionButtonLocation centerFloat = new _CenterFloatFabLocation(); |
|||
|
|||
public static readonly FloatingActionButtonLocation endDocked = new _EndDockedFloatingActionButtonLocation(); |
|||
|
|||
public static readonly FloatingActionButtonLocation centerDocked = |
|||
new _CenterDockedFloatingActionButtonLocation(); |
|||
|
|||
public abstract Offset getOffset(ScaffoldPrelayoutGeometry scaffoldGeometry); |
|||
|
|||
public override string ToString() { |
|||
return this.GetType().ToString(); |
|||
} |
|||
} |
|||
|
|||
class _CenterFloatFabLocation : FloatingActionButtonLocation { |
|||
public _CenterFloatFabLocation() { |
|||
} |
|||
|
|||
public override Offset getOffset(ScaffoldPrelayoutGeometry scaffoldGeometry) { |
|||
float fabX = (scaffoldGeometry.scaffoldSize.width - scaffoldGeometry.floatingActionButtonSize.width) / 2.0f; |
|||
|
|||
float contentBottom = scaffoldGeometry.contentBottom; |
|||
float bottomSheetHeight = scaffoldGeometry.bottomSheetSize.height; |
|||
float fabHeight = scaffoldGeometry.floatingActionButtonSize.height; |
|||
float snackBarHeight = scaffoldGeometry.snackBarSize.height; |
|||
float fabY = contentBottom - fabHeight - FloatingActionButtonLocationUtils.kFloatingActionButtonMargin; |
|||
if (snackBarHeight > 0.0f) { |
|||
fabY = Mathf.Min(fabY, |
|||
contentBottom - snackBarHeight - fabHeight - |
|||
FloatingActionButtonLocationUtils.kFloatingActionButtonMargin); |
|||
} |
|||
|
|||
if (bottomSheetHeight > 0.0f) { |
|||
fabY = Mathf.Min(fabY, contentBottom - bottomSheetHeight - fabHeight / 2.0f); |
|||
} |
|||
|
|||
return new Offset(fabX, fabY); |
|||
} |
|||
} |
|||
|
|||
class _EndFloatFabLocation : FloatingActionButtonLocation { |
|||
public _EndFloatFabLocation() { |
|||
} |
|||
|
|||
public override Offset getOffset(ScaffoldPrelayoutGeometry scaffoldGeometry) { |
|||
float endPadding = scaffoldGeometry.minInsets.right; |
|||
float fabX = scaffoldGeometry.scaffoldSize.width - scaffoldGeometry.floatingActionButtonSize.width - |
|||
FloatingActionButtonLocationUtils.kFloatingActionButtonMargin - endPadding; |
|||
|
|||
float contentBottom = scaffoldGeometry.contentBottom; |
|||
float bottomSheetHeight = scaffoldGeometry.bottomSheetSize.height; |
|||
float fabHeight = scaffoldGeometry.floatingActionButtonSize.height; |
|||
float snackBarHeight = scaffoldGeometry.snackBarSize.height; |
|||
|
|||
float fabY = contentBottom - fabHeight - FloatingActionButtonLocationUtils.kFloatingActionButtonMargin; |
|||
if (snackBarHeight > 0.0f) { |
|||
fabY = Mathf.Min(fabY, |
|||
contentBottom - snackBarHeight - fabHeight - |
|||
FloatingActionButtonLocationUtils.kFloatingActionButtonMargin); |
|||
} |
|||
|
|||
if (bottomSheetHeight > 0.0f) { |
|||
fabY = Mathf.Min(fabY, contentBottom - bottomSheetHeight - fabHeight / 2.0f); |
|||
} |
|||
|
|||
return new Offset(fabX, fabY); |
|||
} |
|||
} |
|||
|
|||
abstract class _DockedFloatingActionButtonLocation : FloatingActionButtonLocation { |
|||
protected _DockedFloatingActionButtonLocation() { |
|||
} |
|||
|
|||
protected float getDockedY(ScaffoldPrelayoutGeometry scaffoldGeometry) { |
|||
float contentBottom = scaffoldGeometry.contentBottom; |
|||
float bottomSheetHeight = scaffoldGeometry.bottomSheetSize.height; |
|||
float fabHeight = scaffoldGeometry.floatingActionButtonSize.height; |
|||
float snackBarHeight = scaffoldGeometry.snackBarSize.height; |
|||
|
|||
float fabY = contentBottom - fabHeight / 2.0f; |
|||
if (snackBarHeight > 0.0f) { |
|||
fabY = Mathf.Min(fabY, |
|||
contentBottom - snackBarHeight - fabHeight - |
|||
FloatingActionButtonLocationUtils.kFloatingActionButtonMargin); |
|||
} |
|||
|
|||
if (bottomSheetHeight > 0.0f) { |
|||
fabY = Mathf.Min(fabY, contentBottom - bottomSheetHeight - fabHeight / 2.0f); |
|||
} |
|||
|
|||
float maxFabY = scaffoldGeometry.scaffoldSize.height - fabHeight; |
|||
return Mathf.Min(maxFabY, fabY); |
|||
} |
|||
} |
|||
|
|||
class _EndDockedFloatingActionButtonLocation : _DockedFloatingActionButtonLocation { |
|||
public _EndDockedFloatingActionButtonLocation() { |
|||
} |
|||
|
|||
public override Offset getOffset(ScaffoldPrelayoutGeometry scaffoldGeometry) { |
|||
float endPadding = scaffoldGeometry.minInsets.right; |
|||
float fabX = scaffoldGeometry.scaffoldSize.width - scaffoldGeometry.floatingActionButtonSize.width - |
|||
FloatingActionButtonLocationUtils.kFloatingActionButtonMargin - endPadding; |
|||
return new Offset(fabX, this.getDockedY(scaffoldGeometry)); |
|||
} |
|||
} |
|||
|
|||
class _CenterDockedFloatingActionButtonLocation : _DockedFloatingActionButtonLocation { |
|||
public _CenterDockedFloatingActionButtonLocation() { |
|||
} |
|||
|
|||
public override Offset getOffset(ScaffoldPrelayoutGeometry scaffoldGeometry) { |
|||
float fabX = (scaffoldGeometry.scaffoldSize.width - scaffoldGeometry.floatingActionButtonSize.width) / 2.0f; |
|||
return new Offset(fabX, this.getDockedY(scaffoldGeometry)); |
|||
} |
|||
} |
|||
|
|||
public abstract class FloatingActionButtonAnimator { |
|||
protected FloatingActionButtonAnimator() { |
|||
} |
|||
|
|||
public static readonly FloatingActionButtonAnimator scaling = new _ScalingFabMotionAnimator(); |
|||
|
|||
public abstract Offset getOffset(Offset begin, Offset end, float progress); |
|||
|
|||
public abstract Animation<float> getScaleAnimation(Animation<float> parent); |
|||
|
|||
public abstract Animation<float> getRotationAnimation(Animation<float> parent); |
|||
|
|||
public virtual float getAnimationRestart(float previousValue) { |
|||
return 0.0f; |
|||
} |
|||
|
|||
public override string ToString() { |
|||
return this.GetType().ToString(); |
|||
} |
|||
} |
|||
|
|||
class _ScalingFabMotionAnimator : FloatingActionButtonAnimator { |
|||
public _ScalingFabMotionAnimator() { |
|||
} |
|||
|
|||
public override Offset getOffset(Offset begin, Offset end, float progress) { |
|||
if (progress < 0.5f) { |
|||
return begin; |
|||
} |
|||
else { |
|||
return end; |
|||
} |
|||
} |
|||
|
|||
public override Animation<float> getScaleAnimation(Animation<float> parent) { |
|||
Curve curve = new Interval(0.5f, 1.0f, curve: Curves.ease); |
|||
return new _AnimationSwap<float>( |
|||
new ReverseAnimation(parent.drive(new CurveTween(curve: curve.flipped))), |
|||
parent.drive(new CurveTween(curve: curve)), |
|||
parent, |
|||
0.5f |
|||
); |
|||
} |
|||
|
|||
static readonly Animatable<float> _rotationTween = new FloatTween( |
|||
begin: 1.0f - FloatingActionButtonLocationUtils.kFloatingActionButtonTurnInterval * 2.0f, |
|||
end: 1.0f |
|||
); |
|||
|
|||
static readonly Animatable<float> _thresholdCenterTween = new CurveTween(curve: new Threshold(0.5f)); |
|||
|
|||
public override Animation<float> getRotationAnimation(Animation<float> parent) { |
|||
return new _AnimationSwap<float>( |
|||
parent.drive(_rotationTween), |
|||
new ReverseAnimation(parent.drive(_thresholdCenterTween)), |
|||
parent, |
|||
0.5f |
|||
); |
|||
} |
|||
|
|||
public override float getAnimationRestart(float previousValue) { |
|||
return Mathf.Min(1.0f - previousValue, previousValue); |
|||
} |
|||
} |
|||
|
|||
|
|||
class _AnimationSwap<T> : CompoundAnimation<T> { |
|||
public _AnimationSwap( |
|||
Animation<T> first, |
|||
Animation<T> next, |
|||
Animation<float> parent, |
|||
float swapThreshold |
|||
) : base(first: first, next: next) { |
|||
this.parent = parent; |
|||
this.swapThreshold = swapThreshold; |
|||
} |
|||
|
|||
public readonly Animation<float> parent; |
|||
public readonly float swapThreshold; |
|||
|
|||
public override T value { |
|||
get { return this.parent.value < this.swapThreshold ? this.first.value : this.next.value; } |
|||
} |
|||
} |
|||
} |
|
|||
fileFormatVersion: 2 |
|||
guid: cfa1c894caa2a46b19d419f6f53ae91f |
|||
MonoImporter: |
|||
externalObjects: {} |
|||
serializedVersion: 2 |
|||
defaultReferences: [] |
|||
executionOrder: 0 |
|||
icon: {instanceID: 0} |
|||
userData: |
|||
assetBundleName: |
|||
assetBundleVariant: |
1001
Runtime/material/scaffold.cs
文件差异内容过多而无法显示
查看文件
文件差异内容过多而无法显示
查看文件
|
|||
fileFormatVersion: 2 |
|||
guid: 2ed8ea3a4f90842e7884a5aff0ca6ec3 |
|||
MonoImporter: |
|||
externalObjects: {} |
|||
serializedVersion: 2 |
|||
defaultReferences: [] |
|||
executionOrder: 0 |
|||
icon: {instanceID: 0} |
|||
userData: |
|||
assetBundleName: |
|||
assetBundleVariant: |
|
|||
using System; |
|||
using System.Collections.Generic; |
|||
using Unity.UIWidgets.animation; |
|||
using Unity.UIWidgets.foundation; |
|||
using Unity.UIWidgets.painting; |
|||
using Unity.UIWidgets.rendering; |
|||
using Unity.UIWidgets.scheduler; |
|||
using Unity.UIWidgets.service; |
|||
using Unity.UIWidgets.ui; |
|||
using Unity.UIWidgets.widgets; |
|||
|
|||
namespace Unity.UIWidgets.material { |
|||
static class SnackBarUtils { |
|||
public const float _kSnackBarPadding = 24.0f; |
|||
public const float _kSingleLineVerticalPadding = 14.0f; |
|||
public static readonly Color _kSnackBackground = new Color(0xFF323232); |
|||
|
|||
public static readonly TimeSpan _kSnackBarTransitionDuration = new TimeSpan(0, 0, 0, 0, 250); |
|||
public static readonly TimeSpan _kSnackBarDisplayDuration = new TimeSpan(0, 0, 0, 0, 4000); |
|||
public static readonly Curve _snackBarHeightCurve = Curves.fastOutSlowIn; |
|||
public static readonly Curve _snackBarFadeCurve = new Interval(0.72f, 1.0f, curve: Curves.fastOutSlowIn); |
|||
} |
|||
|
|||
public enum SnackBarClosedReason { |
|||
action, |
|||
dismiss, |
|||
swipe, |
|||
hide, |
|||
remove, |
|||
timeout |
|||
} |
|||
|
|||
public class SnackBarAction : StatefulWidget { |
|||
public SnackBarAction( |
|||
Key key = null, |
|||
Color textColor = null, |
|||
Color disabledTextColor = null, |
|||
string label = null, |
|||
VoidCallback onPressed = null |
|||
) : base(key: key) { |
|||
D.assert(label != null); |
|||
D.assert(onPressed != null); |
|||
this.textColor = textColor; |
|||
this.disabledTextColor = disabledTextColor; |
|||
this.label = label; |
|||
this.onPressed = onPressed; |
|||
} |
|||
|
|||
public readonly Color textColor; |
|||
|
|||
public readonly Color disabledTextColor; |
|||
|
|||
public readonly string label; |
|||
|
|||
public readonly VoidCallback onPressed; |
|||
|
|||
public override State createState() { |
|||
return new _SnackBarActionState(); |
|||
} |
|||
} |
|||
|
|||
|
|||
class _SnackBarActionState : State<SnackBarAction> { |
|||
bool _haveTriggeredAction = false; |
|||
|
|||
void _handlePressed() { |
|||
if (this._haveTriggeredAction) { |
|||
return; |
|||
} |
|||
|
|||
this.setState(() => { this._haveTriggeredAction = true; }); |
|||
|
|||
this.widget.onPressed(); |
|||
Scaffold.of(this.context).hideCurrentSnackBar(reason: SnackBarClosedReason.action); |
|||
} |
|||
|
|||
public override Widget build(BuildContext context) { |
|||
return new FlatButton( |
|||
onPressed: this._haveTriggeredAction ? (VoidCallback) null : this._handlePressed, |
|||
child: new Text(this.widget.label), |
|||
textColor: this.widget.textColor, |
|||
disabledTextColor: this.widget.disabledTextColor |
|||
); |
|||
} |
|||
} |
|||
|
|||
public class SnackBar : StatelessWidget { |
|||
public SnackBar( |
|||
Key key = null, |
|||
Widget content = null, |
|||
Color backgroundColor = null, |
|||
SnackBarAction action = null, |
|||
TimeSpan? duration = null, |
|||
Animation<float> animation = null |
|||
) : base(key: key) { |
|||
duration = duration ?? SnackBarUtils._kSnackBarDisplayDuration; |
|||
D.assert(content != null); |
|||
this.content = content; |
|||
this.backgroundColor = backgroundColor; |
|||
this.action = action; |
|||
this.duration = duration.Value; |
|||
this.animation = animation; |
|||
} |
|||
|
|||
public readonly Widget content; |
|||
|
|||
public readonly Color backgroundColor; |
|||
|
|||
public readonly SnackBarAction action; |
|||
|
|||
public readonly TimeSpan duration; |
|||
|
|||
public readonly Animation<float> animation; |
|||
|
|||
|
|||
public override Widget build(BuildContext context) { |
|||
MediaQueryData mediaQueryData = MediaQuery.of(context); |
|||
D.assert(this.animation != null); |
|||
|
|||
ThemeData theme = Theme.of(context); |
|||
ThemeData darkTheme = new ThemeData( |
|||
brightness: Brightness.dark, |
|||
accentColor: theme.accentColor, |
|||
accentColorBrightness: theme.accentColorBrightness |
|||
); |
|||
|
|||
List<Widget> children = new List<Widget> { |
|||
new SizedBox(width: SnackBarUtils._kSnackBarPadding), |
|||
new Expanded( |
|||
child: new Container( |
|||
padding: EdgeInsets.symmetric(vertical: SnackBarUtils._kSingleLineVerticalPadding), |
|||
child: new DefaultTextStyle( |
|||
style: darkTheme.textTheme.subhead, |
|||
child: this.content) |
|||
) |
|||
) |
|||
}; |
|||
|
|||
if (this.action != null) { |
|||
children.Add(ButtonTheme.bar( |
|||
padding: EdgeInsets.symmetric(horizontal: SnackBarUtils._kSnackBarPadding), |
|||
textTheme: ButtonTextTheme.accent, |
|||
child: this.action |
|||
)); |
|||
} |
|||
else { |
|||
children.Add(new SizedBox(width: SnackBarUtils._kSnackBarPadding)); |
|||
} |
|||
|
|||
CurvedAnimation heightAnimation = |
|||
new CurvedAnimation(parent: this.animation, curve: SnackBarUtils._snackBarHeightCurve); |
|||
CurvedAnimation fadeAnimation = new CurvedAnimation(parent: this.animation, |
|||
curve: SnackBarUtils._snackBarFadeCurve, reverseCurve: new Threshold(0.0f)); |
|||
Widget snackbar = new SafeArea( |
|||
top: false, |
|||
child: new Row( |
|||
children: children, |
|||
crossAxisAlignment: CrossAxisAlignment.center |
|||
) |
|||
); |
|||
|
|||
snackbar = new Dismissible( |
|||
key: Key.key("dismissible"), |
|||
direction: DismissDirection.down, |
|||
resizeDuration: null, |
|||
onDismissed: (DismissDirection? direction) => { |
|||
Scaffold.of(context).removeCurrentSnackBar(reason: SnackBarClosedReason.swipe); |
|||
}, |
|||
child: new Material( |
|||
elevation: 6.0f, |
|||
color: this.backgroundColor ?? SnackBarUtils._kSnackBackground, |
|||
child: new Theme( |
|||
data: darkTheme, |
|||
child: mediaQueryData.accessibleNavigation |
|||
? snackbar |
|||
: new FadeTransition( |
|||
opacity: fadeAnimation, |
|||
child: snackbar |
|||
) |
|||
) |
|||
) |
|||
); |
|||
|
|||
return new ClipRect( |
|||
child: mediaQueryData.accessibleNavigation |
|||
? snackbar |
|||
: new AnimatedBuilder( |
|||
animation: heightAnimation, |
|||
builder: (BuildContext subContext, Widget child) => { |
|||
return new Align( |
|||
alignment: Alignment.topLeft, |
|||
heightFactor: heightAnimation.value, |
|||
child: child |
|||
); |
|||
}, |
|||
child: snackbar |
|||
) |
|||
); |
|||
} |
|||
|
|||
public static AnimationController createAnimationController(TickerProvider vsync) { |
|||
return new AnimationController( |
|||
duration: SnackBarUtils._kSnackBarTransitionDuration, |
|||
debugLabel: "SnackBar", |
|||
vsync: vsync |
|||
); |
|||
} |
|||
|
|||
public SnackBar withAnimation(Animation<float> newAnimation, Key fallbackKey = null) { |
|||
return new SnackBar( |
|||
key: this.key ?? fallbackKey, |
|||
content: this.content, |
|||
backgroundColor: this.backgroundColor, |
|||
action: this.action, |
|||
duration: this.duration, |
|||
animation: newAnimation |
|||
); |
|||
} |
|||
} |
|||
} |
|
|||
fileFormatVersion: 2 |
|||
guid: f7d31af27df5e4deea4b02f89109f9fd |
|||
MonoImporter: |
|||
externalObjects: {} |
|||
serializedVersion: 2 |
|||
defaultReferences: [] |
|||
executionOrder: 0 |
|||
icon: {instanceID: 0} |
|||
userData: |
|||
assetBundleName: |
|||
assetBundleVariant: |
|
|||
using Unity.UIWidgets.foundation; |
|||
using Unity.UIWidgets.rendering; |
|||
|
|||
namespace Unity.UIWidgets.widgets { |
|||
public class AnnotatedRegion<T> : SingleChildRenderObjectWidget |
|||
where T : class { |
|||
public AnnotatedRegion( |
|||
Key key = null, |
|||
Widget child = null, |
|||
T value = null, |
|||
bool sized = true |
|||
) : base(key: key, child: child) { |
|||
D.assert(value != null); |
|||
D.assert(child != null); |
|||
this.value = value; |
|||
this.sized = sized; |
|||
} |
|||
|
|||
public readonly T value; |
|||
|
|||
public readonly bool sized; |
|||
|
|||
public override RenderObject createRenderObject(BuildContext context) { |
|||
return new RenderAnnotatedRegion<T>(value: this.value, sized: this.sized); |
|||
} |
|||
|
|||
public override void updateRenderObject(BuildContext context, RenderObject renderObject) { |
|||
RenderAnnotatedRegion<T> _renderObject = (RenderAnnotatedRegion<T>) renderObject; |
|||
_renderObject.value = this.value; |
|||
_renderObject.sized = this.sized; |
|||
} |
|||
} |
|||
} |
|
|||
fileFormatVersion: 2 |
|||
guid: b7edf2448377d4d3b9b9f63eb136266b |
|||
MonoImporter: |
|||
externalObjects: {} |
|||
serializedVersion: 2 |
|||
defaultReferences: [] |
|||
executionOrder: 0 |
|||
icon: {instanceID: 0} |
|||
userData: |
|||
assetBundleName: |
|||
assetBundleVariant: |
|
|||
using Unity.UIWidgets.foundation; |
|||
using Unity.UIWidgets.ui; |
|||
|
|||
namespace Unity.UIWidgets.widgets { |
|||
public interface SizePreferred { |
|||
Size preferredSize { get; } |
|||
} |
|||
|
|||
public abstract class PreferredSizeWidget : StatefulWidget, SizePreferred { |
|||
protected PreferredSizeWidget(Key key = null) : base(key: key) { |
|||
} |
|||
|
|||
public virtual Size preferredSize { get; } |
|||
} |
|||
|
|||
|
|||
public class PreferredSize : StatelessWidget, SizePreferred { |
|||
public PreferredSize( |
|||
Key key = null, |
|||
Widget child = null, |
|||
Size preferredSize = null) : base(key: key) { |
|||
D.assert(child != null); |
|||
D.assert(preferredSize != null); |
|||
this.child = child; |
|||
this.preferredSize = preferredSize; |
|||
} |
|||
|
|||
public readonly Widget child; |
|||
|
|||
public Size preferredSize { get; } |
|||
|
|||
public override Widget build(BuildContext context) { |
|||
return this.child; |
|||
} |
|||
} |
|||
} |
|
|||
fileFormatVersion: 2 |
|||
guid: 60513bb9173ce47ad8d4c7840bcfe836 |
|||
MonoImporter: |
|||
externalObjects: {} |
|||
serializedVersion: 2 |
|||
defaultReferences: [] |
|||
executionOrder: 0 |
|||
icon: {instanceID: 0} |
|||
userData: |
|||
assetBundleName: |
|||
assetBundleVariant: |
撰写
预览
正在加载...
取消
保存
Reference in new issue