siyao
4 年前
当前提交
57e6122f
共有 186 个文件被更改,包括 16354 次插入 和 0 次删除
-
222com.unity.uiwidgets/Runtime/material/animated_icons/animated_icons.cs
-
11com.unity.uiwidgets/Runtime/material/animated_icons/animated_icons.cs.meta
-
54com.unity.uiwidgets/Runtime/material/animated_icons/animated_icons_data.cs
-
3com.unity.uiwidgets/Runtime/material/animated_icons/animated_icons_data.cs.meta
-
8com.unity.uiwidgets/Runtime/material/animated_icons/data.meta
-
1001com.unity.uiwidgets/Runtime/material/animated_icons/data/add_event.g.cs
-
11com.unity.uiwidgets/Runtime/material/animated_icons/data/add_event.g.cs.meta
-
1001com.unity.uiwidgets/Runtime/material/animated_icons/data/arrow_menu.g.cs
-
1001com.unity.uiwidgets/Runtime/material/animated_icons/data/close_menu.g.cs
-
3com.unity.uiwidgets/Runtime/material/animated_icons/data/arrow_menu.g.cs.meta
-
3com.unity.uiwidgets/Runtime/material/animated_icons/data/close_menu.g.cs.meta
-
208com.unity.uiwidgets/Runtime/material/app.cs
-
11com.unity.uiwidgets/Runtime/material/app.cs.meta
-
715com.unity.uiwidgets/Runtime/material/app_bar.cs
-
11com.unity.uiwidgets/Runtime/material/app_bar.cs.meta
-
122com.unity.uiwidgets/Runtime/material/app_bar_theme.cs
-
3com.unity.uiwidgets/Runtime/material/app_bar_theme.cs.meta
-
425com.unity.uiwidgets/Runtime/material/arc.cs
-
11com.unity.uiwidgets/Runtime/material/arc.cs.meta
-
57com.unity.uiwidgets/Runtime/material/back_button.cs
-
11com.unity.uiwidgets/Runtime/material/back_button.cs.meta
-
110com.unity.uiwidgets/Runtime/material/bottom_app_bar.cs
-
3com.unity.uiwidgets/Runtime/material/bottom_app_bar.cs.meta
-
92com.unity.uiwidgets/Runtime/material/bottom_app_bar_theme.cs
-
3com.unity.uiwidgets/Runtime/material/bottom_app_bar_theme.cs.meta
-
716com.unity.uiwidgets/Runtime/material/bottom_navigation_bar.cs
-
3com.unity.uiwidgets/Runtime/material/bottom_navigation_bar.cs.meta
-
271com.unity.uiwidgets/Runtime/material/bottom_sheet.cs
-
11com.unity.uiwidgets/Runtime/material/bottom_sheet.cs.meta
-
169com.unity.uiwidgets/Runtime/material/button.cs
-
11com.unity.uiwidgets/Runtime/material/button.cs.meta
-
68com.unity.uiwidgets/Runtime/material/button_bar.cs
-
11com.unity.uiwidgets/Runtime/material/button_bar.cs.meta
-
582com.unity.uiwidgets/Runtime/material/button_theme.cs
-
11com.unity.uiwidgets/Runtime/material/button_theme.cs.meta
-
62com.unity.uiwidgets/Runtime/material/card.cs
-
11com.unity.uiwidgets/Runtime/material/card.cs.meta
-
89com.unity.uiwidgets/Runtime/material/card_theme.cs
-
3com.unity.uiwidgets/Runtime/material/card_theme.cs.meta
-
310com.unity.uiwidgets/Runtime/material/checkbox.cs
-
3com.unity.uiwidgets/Runtime/material/checkbox.cs.meta
-
1001com.unity.uiwidgets/Runtime/material/chip.cs
-
3com.unity.uiwidgets/Runtime/material/chip.cs.meta
-
319com.unity.uiwidgets/Runtime/material/chip_theme.cs
-
3com.unity.uiwidgets/Runtime/material/chip_theme.cs.meta
-
132com.unity.uiwidgets/Runtime/material/circle_avatar.cs
-
3com.unity.uiwidgets/Runtime/material/circle_avatar.cs.meta
-
352com.unity.uiwidgets/Runtime/material/color_scheme.cs
-
11com.unity.uiwidgets/Runtime/material/color_scheme.cs.meta
-
690com.unity.uiwidgets/Runtime/material/colors.cs
-
11com.unity.uiwidgets/Runtime/material/colors.cs.meta
-
28com.unity.uiwidgets/Runtime/material/constants.cs
-
11com.unity.uiwidgets/Runtime/material/constants.cs.meta
-
938com.unity.uiwidgets/Runtime/material/date_picker.cs
-
11com.unity.uiwidgets/Runtime/material/date_picker.cs.meta
-
91com.unity.uiwidgets/Runtime/material/debug.cs
-
11com.unity.uiwidgets/Runtime/material/debug.cs.meta
-
314com.unity.uiwidgets/Runtime/material/dialog.cs
-
11com.unity.uiwidgets/Runtime/material/dialog.cs.meta
-
117com.unity.uiwidgets/Runtime/material/dialog_theme.cs
-
11com.unity.uiwidgets/Runtime/material/dialog_theme.cs.meta
-
47com.unity.uiwidgets/Runtime/material/divider.cs
-
11com.unity.uiwidgets/Runtime/material/divider.cs.meta
-
325com.unity.uiwidgets/Runtime/material/drawer.cs
-
11com.unity.uiwidgets/Runtime/material/drawer.cs.meta
-
76com.unity.uiwidgets/Runtime/material/drawer_header.cs
-
11com.unity.uiwidgets/Runtime/material/drawer_header.cs.meta
-
850com.unity.uiwidgets/Runtime/material/dropdown.cs
-
3com.unity.uiwidgets/Runtime/material/dropdown.cs.meta
-
94com.unity.uiwidgets/Runtime/material/expand_icon.cs
-
11com.unity.uiwidgets/Runtime/material/expand_icon.cs.meta
-
343com.unity.uiwidgets/Runtime/material/expansion_panel.cs
-
11com.unity.uiwidgets/Runtime/material/expansion_panel.cs.meta
-
176com.unity.uiwidgets/Runtime/material/expansion_tile.cs
-
11com.unity.uiwidgets/Runtime/material/expansion_tile.cs.meta
-
57com.unity.uiwidgets/Runtime/material/feedback.cs
-
3com.unity.uiwidgets/Runtime/material/feedback.cs.meta
-
178com.unity.uiwidgets/Runtime/material/flat_button.cs
-
11com.unity.uiwidgets/Runtime/material/flat_button.cs.meta
-
223com.unity.uiwidgets/Runtime/material/flexible_space_bar.cs
-
11com.unity.uiwidgets/Runtime/material/flexible_space_bar.cs.meta
-
314com.unity.uiwidgets/Runtime/material/floating_action_button.cs
-
11com.unity.uiwidgets/Runtime/material/floating_action_button.cs.meta
-
313com.unity.uiwidgets/Runtime/material/floating_action_button_location.cs
-
11com.unity.uiwidgets/Runtime/material/floating_action_button_location.cs.meta
-
129com.unity.uiwidgets/Runtime/material/floatting_action_button_theme.cs
-
11com.unity.uiwidgets/Runtime/material/floatting_action_button_theme.cs.meta
-
53com.unity.uiwidgets/Runtime/material/grid_tile.cs
-
11com.unity.uiwidgets/Runtime/material/grid_tile.cs.meta
-
121com.unity.uiwidgets/Runtime/material/icon_button.cs
-
11com.unity.uiwidgets/Runtime/material/icon_button.cs.meta
-
1001com.unity.uiwidgets/Runtime/material/icons.cs
-
11com.unity.uiwidgets/Runtime/material/icons.cs.meta
-
240com.unity.uiwidgets/Runtime/material/ink_decoration.cs
-
11com.unity.uiwidgets/Runtime/material/ink_decoration.cs.meta
-
133com.unity.uiwidgets/Runtime/material/ink_highlight.cs
-
11com.unity.uiwidgets/Runtime/material/ink_highlight.cs.meta
|
|||
using System.Collections.Generic; |
|||
using Unity.UIWidgets.animation; |
|||
using Unity.UIWidgets.foundation; |
|||
using Unity.UIWidgets.ui; |
|||
using Unity.UIWidgets.widgets; |
|||
using UnityEngine; |
|||
using Canvas = Unity.UIWidgets.ui.Canvas; |
|||
using Color = Unity.UIWidgets.ui.Color; |
|||
|
|||
namespace Unity.UIWidgets.material { |
|||
static class AnimatedIconUtils { |
|||
public static T _interpolate<T>(List<T> values, float progress, _Interpolator<T> interpolator) { |
|||
D.assert(progress <= 1.0f); |
|||
D.assert(progress >= 0.0f); |
|||
if (values.Count == 1) { |
|||
return values[0]; |
|||
} |
|||
|
|||
float targetIdx = MathUtils.lerpFloat(0, values.Count - 1, progress); |
|||
int lowIdx = targetIdx.floor(); |
|||
int highIdx = targetIdx.ceil(); |
|||
float t = targetIdx - lowIdx; |
|||
return interpolator(values[lowIdx], values[highIdx], t); |
|||
} |
|||
} |
|||
|
|||
public class AnimatedIcon : StatelessWidget { |
|||
public AnimatedIcon( |
|||
Key key = null, |
|||
AnimatedIconData icon = null, |
|||
Animation<float> progress = null, |
|||
Color color = null, |
|||
float? size = null |
|||
) : base(key: key) { |
|||
D.assert(progress != null); |
|||
D.assert(icon != null); |
|||
this.progress = progress; |
|||
this.color = color; |
|||
this.size = size; |
|||
this.icon = icon; |
|||
} |
|||
|
|||
public readonly Animation<float> progress; |
|||
|
|||
public readonly Color color; |
|||
|
|||
public readonly float? size; |
|||
|
|||
public readonly AnimatedIconData icon; |
|||
|
|||
public static readonly _UiPathFactory _pathFactory = () => new Path(); |
|||
|
|||
public override Widget build(BuildContext context) { |
|||
_AnimatedIconData iconData = (_AnimatedIconData) icon; |
|||
IconThemeData iconTheme = IconTheme.of(context); |
|||
float iconSize = size ?? iconTheme.size ?? 0.0f; |
|||
float? iconOpacity = iconTheme.opacity; |
|||
Color iconColor = color ?? iconTheme.color; |
|||
if (iconOpacity != 1.0f) { |
|||
iconColor = iconColor.withOpacity(iconColor.opacity * (iconOpacity ?? 1.0f)); |
|||
} |
|||
|
|||
return new CustomPaint( |
|||
size: new Size(iconSize, iconSize), |
|||
painter: new _AnimatedIconPainter( |
|||
paths: iconData.paths, |
|||
progress: progress, |
|||
color: iconColor, |
|||
scale: iconSize / iconData.size.width, |
|||
uiPathFactory: _pathFactory |
|||
) |
|||
); |
|||
} |
|||
} |
|||
|
|||
public delegate Path _UiPathFactory(); |
|||
|
|||
class _AnimatedIconPainter : AbstractCustomPainter { |
|||
public _AnimatedIconPainter( |
|||
List<_PathFrames> paths = null, |
|||
Animation<float> progress = null, |
|||
Color color = null, |
|||
float? scale = null, |
|||
bool? shouldMirror = null, |
|||
_UiPathFactory uiPathFactory = null |
|||
) : base(repaint: progress) { |
|||
this.paths = paths; |
|||
this.progress = progress; |
|||
this.color = color; |
|||
this.scale = scale; |
|||
this.shouldMirror = shouldMirror; |
|||
this.uiPathFactory = uiPathFactory; |
|||
} |
|||
|
|||
public readonly List<_PathFrames> paths; |
|||
public readonly Animation<float> progress; |
|||
public readonly Color color; |
|||
public readonly float? scale; |
|||
public readonly bool? shouldMirror; |
|||
public readonly _UiPathFactory uiPathFactory; |
|||
|
|||
public override void paint(Canvas canvas, Size size) { |
|||
canvas.scale(scale ?? 1.0f, scale ?? 1.0f); |
|||
if (shouldMirror == true) { |
|||
canvas.rotate(Mathf.PI); |
|||
canvas.translate(-size.width, -size.height); |
|||
} |
|||
|
|||
float clampedProgress = progress.value.clamp(0.0f, 1.0f); |
|||
foreach (_PathFrames path in paths) { |
|||
path.paint(canvas, color, uiPathFactory, clampedProgress); |
|||
} |
|||
} |
|||
|
|||
|
|||
public override bool shouldRepaint(CustomPainter _oldDelegate) { |
|||
_AnimatedIconPainter oldDelegate = _oldDelegate as _AnimatedIconPainter; |
|||
return oldDelegate.progress.value != progress.value |
|||
|| oldDelegate.color != color |
|||
|| oldDelegate.paths != paths |
|||
|| oldDelegate.scale != scale |
|||
|| oldDelegate.uiPathFactory != uiPathFactory; |
|||
} |
|||
|
|||
public override bool? hitTest(Offset position) { |
|||
return null; |
|||
} |
|||
} |
|||
|
|||
class _PathFrames { |
|||
public _PathFrames( |
|||
List<_PathCommand> commands, |
|||
List<float> opacities |
|||
) { |
|||
this.commands = commands; |
|||
this.opacities = opacities; |
|||
} |
|||
|
|||
public readonly List<_PathCommand> commands; |
|||
public readonly List<float> opacities; |
|||
|
|||
public void paint(Canvas canvas, Color color, _UiPathFactory uiPathFactory, float progress) { |
|||
float opacity = AnimatedIconUtils._interpolate<float>(opacities, progress, MathUtils.lerpFloat); |
|||
Paint paint = new Paint(); |
|||
paint.style = PaintingStyle.fill; |
|||
paint.color = color.withOpacity(color.opacity * opacity); |
|||
Path path = uiPathFactory(); |
|||
foreach (_PathCommand command in commands) { |
|||
command.apply(path, progress); |
|||
} |
|||
|
|||
canvas.drawPath(path, paint); |
|||
} |
|||
} |
|||
|
|||
abstract class _PathCommand { |
|||
public _PathCommand() { |
|||
} |
|||
|
|||
public abstract void apply(Path path, float progress); |
|||
} |
|||
|
|||
class _PathMoveTo : _PathCommand { |
|||
public _PathMoveTo(List<Offset> points) { |
|||
this.points = points; |
|||
} |
|||
|
|||
public readonly List<Offset> points; |
|||
|
|||
public override void apply(Path path, float progress) { |
|||
Offset offset = AnimatedIconUtils._interpolate<Offset>(points, progress, Offset.lerp); |
|||
path.moveTo(offset.dx, offset.dy); |
|||
} |
|||
} |
|||
|
|||
class _PathCubicTo : _PathCommand { |
|||
public _PathCubicTo(List<Offset> controlPoints1, List<Offset> controlPoints2, List<Offset> targetPoints) { |
|||
this.controlPoints1 = controlPoints1; |
|||
this.controlPoints2 = controlPoints2; |
|||
this.targetPoints = targetPoints; |
|||
} |
|||
|
|||
public readonly List<Offset> controlPoints2; |
|||
public readonly List<Offset> controlPoints1; |
|||
public readonly List<Offset> targetPoints; |
|||
|
|||
public override void apply(Path path, float progress) { |
|||
Offset controlPoint1 = AnimatedIconUtils._interpolate<Offset>(controlPoints1, progress, Offset.lerp); |
|||
Offset controlPoint2 = AnimatedIconUtils._interpolate<Offset>(controlPoints2, progress, Offset.lerp); |
|||
Offset targetPoint = AnimatedIconUtils._interpolate<Offset>(targetPoints, progress, Offset.lerp); |
|||
path.cubicTo( |
|||
controlPoint1.dx, controlPoint1.dy, |
|||
controlPoint2.dx, controlPoint2.dy, |
|||
targetPoint.dx, targetPoint.dy |
|||
); |
|||
} |
|||
} |
|||
|
|||
class _PathLineTo : _PathCommand { |
|||
public _PathLineTo(List<Offset> points) { |
|||
this.points = points; |
|||
} |
|||
|
|||
List<Offset> points; |
|||
|
|||
public override void apply(Path path, float progress) { |
|||
Offset point = AnimatedIconUtils._interpolate<Offset>(points, progress, Offset.lerp); |
|||
path.lineTo(point.dx, point.dy); |
|||
} |
|||
} |
|||
|
|||
class _PathClose : _PathCommand { |
|||
public _PathClose() { |
|||
} |
|||
|
|||
public override void apply(Path path, float progress) { |
|||
path.close(); |
|||
} |
|||
} |
|||
|
|||
public delegate T _Interpolator<T>(T a, T b, float progress); |
|||
} |
|
|||
fileFormatVersion: 2 |
|||
guid: cd2f603947c5f4baea10dc2c394daafb |
|||
MonoImporter: |
|||
externalObjects: {} |
|||
serializedVersion: 2 |
|||
defaultReferences: [] |
|||
executionOrder: 0 |
|||
icon: {instanceID: 0} |
|||
userData: |
|||
assetBundleName: |
|||
assetBundleVariant: |
|
|||
using System.Collections.Generic; |
|||
using Unity.UIWidgets.ui; |
|||
|
|||
namespace Unity.UIWidgets.material { |
|||
public abstract class AnimatedIcons { |
|||
public static readonly AnimatedIconData add_event = AnimatedIconsData._add_event; |
|||
|
|||
public static readonly AnimatedIconData arrow_menu = AnimatedIconsData._arrow_menu; |
|||
|
|||
public static readonly AnimatedIconData close_menu = AnimatedIconsData._close_menu; |
|||
|
|||
// public readonly AnimatedIconData ellipsis_search = AnimatedIconsData._ellipsis_search;
|
|||
|
|||
// public readonly AnimatedIconData event_add = AnimatedIconsData._event_add;
|
|||
|
|||
// public readonly AnimatedIconData home_menu = AnimatedIconsData._home_menu;
|
|||
|
|||
// public readonly AnimatedIconData list_view = AnimatedIconsData._list_view;
|
|||
|
|||
// public readonly AnimatedIconData menu_arrow = AnimatedIconsData._menu_arrow;
|
|||
|
|||
// public readonly AnimatedIconData menu_close = AnimatedIconsData._menu_close;
|
|||
|
|||
// public readonly AnimatedIconData menu_home = AnimatedIconsData._menu_home;
|
|||
|
|||
// public readonly AnimatedIconData pause_play = AnimatedIconsData._pause_play;
|
|||
|
|||
// public readonly AnimatedIconData play_pause = AnimatedIconsData._play_pause;
|
|||
|
|||
// public readonly AnimatedIconData search_ellipsis = AnimatedIconsData._search_ellipsis;
|
|||
|
|||
// public readonly AnimatedIconData view_list = AnimatedIconsData._view_list;
|
|||
} |
|||
|
|||
public abstract class AnimatedIconData { |
|||
public AnimatedIconData() { |
|||
} |
|||
|
|||
public abstract bool matchTextDirection { get; } |
|||
} |
|||
|
|||
class _AnimatedIconData : AnimatedIconData { |
|||
public _AnimatedIconData(Size size, List<_PathFrames> paths, bool matchTextDirection = false) { |
|||
this.size = size; |
|||
this.paths = paths; |
|||
this.matchTextDirection = matchTextDirection; |
|||
} |
|||
|
|||
public readonly Size size; |
|||
public readonly List<_PathFrames> paths; |
|||
|
|||
public override bool matchTextDirection { get; } |
|||
} |
|||
} |
|
|||
fileFormatVersion: 2 |
|||
guid: 439a75e2cc39472ba806029b41996e9b |
|||
timeCreated: 1552892371 |
|
|||
fileFormatVersion: 2 |
|||
guid: 14a0ec7a1462b4e50861bac1c7cfc3bf |
|||
folderAsset: yes |
|||
DefaultImporter: |
|||
externalObjects: {} |
|||
userData: |
|||
assetBundleName: |
|||
assetBundleVariant: |
1001
com.unity.uiwidgets/Runtime/material/animated_icons/data/add_event.g.cs
文件差异内容过多而无法显示
查看文件
文件差异内容过多而无法显示
查看文件
|
|||
fileFormatVersion: 2 |
|||
guid: 885b0d58b510b4b3ea77c5c4c9e47694 |
|||
MonoImporter: |
|||
externalObjects: {} |
|||
serializedVersion: 2 |
|||
defaultReferences: [] |
|||
executionOrder: 0 |
|||
icon: {instanceID: 0} |
|||
userData: |
|||
assetBundleName: |
|||
assetBundleVariant: |
1001
com.unity.uiwidgets/Runtime/material/animated_icons/data/arrow_menu.g.cs
文件差异内容过多而无法显示
查看文件
文件差异内容过多而无法显示
查看文件
1001
com.unity.uiwidgets/Runtime/material/animated_icons/data/close_menu.g.cs
文件差异内容过多而无法显示
查看文件
文件差异内容过多而无法显示
查看文件
|
|||
fileFormatVersion: 2 |
|||
guid: f38795e53cc54f628c2125e5e50fea1c |
|||
timeCreated: 1552894502 |
|
|||
fileFormatVersion: 2 |
|||
guid: e3a716495016460c8599ef52f9bd690f |
|||
timeCreated: 1552894786 |
|
|||
using System.Collections.Generic; |
|||
using Unity.UIWidgets.animation; |
|||
using Unity.UIWidgets.cupertino; |
|||
using Unity.UIWidgets.foundation; |
|||
using Unity.UIWidgets.service; |
|||
using Unity.UIWidgets.ui; |
|||
using Unity.UIWidgets.widgets; |
|||
using Brightness = Unity.UIWidgets.ui.Brightness; |
|||
using Color = Unity.UIWidgets.ui.Color; |
|||
using Rect = Unity.UIWidgets.ui.Rect; |
|||
using TextStyle = Unity.UIWidgets.painting.TextStyle; |
|||
|
|||
namespace Unity.UIWidgets.material { |
|||
static class AppUtils { |
|||
public static readonly TextStyle _errorTextStyle = new TextStyle( |
|||
color: new Color(0xD0FF0000), |
|||
fontFamily: "monospace", |
|||
fontSize: 48.0f, |
|||
fontWeight: FontWeight.w700, |
|||
decoration: TextDecoration.underline, |
|||
decorationColor: new Color(0xFFFFFF00), |
|||
decorationStyle: TextDecorationStyle.doubleLine |
|||
); |
|||
} |
|||
|
|||
|
|||
public class MaterialApp : StatefulWidget { |
|||
public MaterialApp( |
|||
Key key = null, |
|||
GlobalKey<NavigatorState> navigatorKey = null, |
|||
Widget home = null, |
|||
Dictionary<string, WidgetBuilder> routes = null, |
|||
string initialRoute = null, |
|||
RouteFactory onGenerateRoute = null, |
|||
RouteFactory onUnknownRoute = null, |
|||
List<NavigatorObserver> navigatorObservers = null, |
|||
TransitionBuilder builder = null, |
|||
string title = "", |
|||
Color color = null, |
|||
ThemeData theme = null, |
|||
ThemeData darkTheme = null, |
|||
Locale locale = null, |
|||
List<LocalizationsDelegate> localizationsDelegates = null, |
|||
LocaleListResolutionCallback localeListResolutionCallback = null, |
|||
LocaleResolutionCallback localeResolutionCallback = null, |
|||
List<Locale> supportedLocales = null, |
|||
bool showPerformanceOverlay = false |
|||
) : base(key: key) { |
|||
supportedLocales = supportedLocales ?? new List<Locale> {new Locale("en", "US")}; |
|||
this.navigatorKey = navigatorKey; |
|||
this.home = home; |
|||
this.routes = routes ?? new Dictionary<string, WidgetBuilder>(); |
|||
this.initialRoute = initialRoute; |
|||
this.onGenerateRoute = onGenerateRoute; |
|||
this.onUnknownRoute = onUnknownRoute; |
|||
this.navigatorObservers = navigatorObservers ?? new List<NavigatorObserver>(); |
|||
this.builder = builder; |
|||
this.title = title; |
|||
this.color = color; |
|||
this.theme = theme; |
|||
this.darkTheme = darkTheme; |
|||
this.locale = locale; |
|||
this.localizationsDelegates = localizationsDelegates; |
|||
this.localeListResolutionCallback = localeListResolutionCallback; |
|||
this.localeResolutionCallback = localeResolutionCallback; |
|||
this.supportedLocales = supportedLocales; |
|||
this.showPerformanceOverlay = showPerformanceOverlay; |
|||
} |
|||
|
|||
public readonly GlobalKey<NavigatorState> navigatorKey; |
|||
|
|||
public readonly Widget home; |
|||
|
|||
public readonly Dictionary<string, WidgetBuilder> routes; |
|||
|
|||
public readonly string initialRoute; |
|||
|
|||
public readonly RouteFactory onGenerateRoute; |
|||
|
|||
public readonly RouteFactory onUnknownRoute; |
|||
|
|||
public readonly List<NavigatorObserver> navigatorObservers; |
|||
|
|||
public readonly TransitionBuilder builder; |
|||
|
|||
public readonly string title; |
|||
|
|||
public readonly ThemeData theme; |
|||
|
|||
public readonly ThemeData darkTheme; |
|||
|
|||
public readonly Color color; |
|||
|
|||
public readonly Locale locale; |
|||
|
|||
public readonly List<LocalizationsDelegate> localizationsDelegates; |
|||
|
|||
public readonly LocaleListResolutionCallback localeListResolutionCallback; |
|||
|
|||
public readonly LocaleResolutionCallback localeResolutionCallback; |
|||
|
|||
public readonly List<Locale> supportedLocales; |
|||
|
|||
public readonly bool showPerformanceOverlay; |
|||
|
|||
public override State createState() { |
|||
return new _MaterialAppState(); |
|||
} |
|||
} |
|||
|
|||
|
|||
class _MaterialAppState : State<MaterialApp> { |
|||
HeroController _heroController; |
|||
|
|||
public override void initState() { |
|||
base.initState(); |
|||
_heroController = new HeroController(createRectTween: _createRectTween); |
|||
_updateNavigator(); |
|||
} |
|||
|
|||
public override void didUpdateWidget(StatefulWidget oldWidget) { |
|||
base.didUpdateWidget(oldWidget); |
|||
if (widget.navigatorKey != (oldWidget as MaterialApp).navigatorKey) { |
|||
_heroController = new HeroController(createRectTween: _createRectTween); |
|||
} |
|||
_updateNavigator(); |
|||
} |
|||
|
|||
List<NavigatorObserver> _navigatorObservers; |
|||
|
|||
void _updateNavigator() { |
|||
if (widget.home != null || |
|||
widget.routes.isNotEmpty() || |
|||
widget.onGenerateRoute != null || |
|||
widget.onUnknownRoute != null) { |
|||
_navigatorObservers = new List<NavigatorObserver>(widget.navigatorObservers); |
|||
_navigatorObservers.Add(_heroController); |
|||
} |
|||
else { |
|||
_navigatorObservers = new List<NavigatorObserver>(); |
|||
} |
|||
} |
|||
|
|||
RectTween _createRectTween(Rect begin, Rect end) { |
|||
return new MaterialRectArcTween(begin: begin, end: end); |
|||
} |
|||
|
|||
List<LocalizationsDelegate> _localizationsDelegates { |
|||
get { |
|||
var _delegates = new List<LocalizationsDelegate>(); |
|||
if (widget.localizationsDelegates != null) { |
|||
_delegates.AddRange(widget.localizationsDelegates); |
|||
} |
|||
|
|||
_delegates.Add(DefaultCupertinoLocalizations.del); |
|||
_delegates.Add(DefaultMaterialLocalizations.del); |
|||
return new List<LocalizationsDelegate>(_delegates); |
|||
} |
|||
} |
|||
|
|||
public override Widget build(BuildContext context) { |
|||
Widget result = new WidgetsApp( |
|||
key: new GlobalObjectKey<State>(this), |
|||
navigatorKey: widget.navigatorKey, |
|||
navigatorObservers: _navigatorObservers, |
|||
pageRouteBuilder: (RouteSettings settings, WidgetBuilder builder) => |
|||
new MaterialPageRoute(settings: settings, builder: builder), |
|||
home: widget.home, |
|||
routes: widget.routes, |
|||
initialRoute: widget.initialRoute, |
|||
onGenerateRoute: widget.onGenerateRoute, |
|||
onUnknownRoute: widget.onUnknownRoute, |
|||
builder: (BuildContext _context, Widget child) => { |
|||
ThemeData theme; |
|||
Brightness platformBrightness = MediaQuery.platformBrightnessOf(_context); |
|||
if (platformBrightness == Brightness.dark && widget.darkTheme != null) { |
|||
theme = widget.darkTheme; |
|||
} |
|||
else if (widget.theme != null) { |
|||
theme = widget.theme; |
|||
} |
|||
else { |
|||
theme = ThemeData.fallback(); |
|||
} |
|||
|
|||
return new AnimatedTheme( |
|||
data: theme, |
|||
isMaterialAppTheme: true, |
|||
child: widget.builder != null |
|||
? new Builder( |
|||
builder: (__context) => { return widget.builder(__context, child); } |
|||
) |
|||
: child |
|||
); |
|||
}, |
|||
textStyle: AppUtils._errorTextStyle, |
|||
locale: widget.locale, |
|||
localizationsDelegates: _localizationsDelegates, |
|||
localeResolutionCallback: widget.localeResolutionCallback, |
|||
localeListResolutionCallback: widget.localeListResolutionCallback, |
|||
supportedLocales: widget.supportedLocales, |
|||
showPerformanceOverlay: widget.showPerformanceOverlay |
|||
); |
|||
|
|||
return result; |
|||
} |
|||
} |
|||
} |
|
|||
fileFormatVersion: 2 |
|||
guid: ed3c6aaa36fe54da5b914d3d605903ae |
|||
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.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 = null, |
|||
ShapeBorder shape = null, |
|||
Color backgroundColor = null, |
|||
Brightness? brightness = null, |
|||
IconThemeData iconTheme = null, |
|||
IconThemeData actionsIconTheme = 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) { |
|||
D.assert(elevation == null || elevation >= 0.0); |
|||
this.leading = leading; |
|||
this.automaticallyImplyLeading = automaticallyImplyLeading; |
|||
this.title = title; |
|||
this.actions = actions; |
|||
this.flexibleSpace = flexibleSpace; |
|||
this.bottom = bottom; |
|||
this.elevation = elevation; |
|||
this.shape = shape; |
|||
this.backgroundColor = backgroundColor; |
|||
this.brightness = brightness; |
|||
this.iconTheme = iconTheme; |
|||
this.actionsIconTheme = actionsIconTheme; |
|||
this.textTheme = textTheme; |
|||
this.primary = primary; |
|||
this.centerTitle = centerTitle; |
|||
this.titleSpacing = titleSpacing; |
|||
this.toolbarOpacity = toolbarOpacity; |
|||
this.bottomOpacity = bottomOpacity; |
|||
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 ShapeBorder shape; |
|||
|
|||
public readonly Color backgroundColor; |
|||
|
|||
public readonly Brightness? brightness; |
|||
|
|||
public readonly IconThemeData iconTheme; |
|||
|
|||
public readonly IconThemeData actionsIconTheme; |
|||
|
|||
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 (centerTitle != null) { |
|||
return centerTitle; |
|||
} |
|||
|
|||
switch (themeData.platform) { |
|||
case RuntimePlatform.IPhonePlayer: |
|||
return actions == null || actions.Count < 2; |
|||
default: |
|||
return false; |
|||
} |
|||
} |
|||
|
|||
public override State createState() { |
|||
return new _AppBarState(); |
|||
} |
|||
} |
|||
|
|||
|
|||
class _AppBarState : State<AppBar> { |
|||
const float _defaultElevation = 4.0f; |
|||
|
|||
void _handleDrawerButton() { |
|||
Scaffold.of(context).openDrawer(); |
|||
} |
|||
|
|||
void _handleDrawerButtonEnd() { |
|||
Scaffold.of(context).openEndDrawer(); |
|||
} |
|||
|
|||
public override Widget build(BuildContext context) { |
|||
D.assert(MaterialD.debugCheckHasMaterialLocalizations(context)); |
|||
ThemeData themeData = Theme.of(context); |
|||
AppBarTheme appBarTheme = AppBarTheme.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 overallIconTheme = widget.iconTheme |
|||
?? appBarTheme.iconTheme |
|||
?? themeData.primaryIconTheme; |
|||
IconThemeData actionsIconTheme = widget.actionsIconTheme |
|||
?? appBarTheme.actionsIconTheme |
|||
?? overallIconTheme; |
|||
TextStyle centerStyle = widget.textTheme?.title |
|||
?? appBarTheme.textTheme?.title |
|||
?? themeData.primaryTextTheme.title; |
|||
TextStyle sideStyle = widget.textTheme?.body1 |
|||
?? appBarTheme.textTheme?.body1 |
|||
?? themeData.primaryTextTheme.body1; |
|||
|
|||
if (widget.toolbarOpacity != 1.0f) { |
|||
float opacity = |
|||
new Interval(0.25f, 1.0f, curve: Curves.fastOutSlowIn).transform(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)); |
|||
} |
|||
|
|||
overallIconTheme = overallIconTheme.copyWith( |
|||
opacity: opacity * (overallIconTheme.opacity ?? 1.0f) |
|||
); |
|||
actionsIconTheme = actionsIconTheme.copyWith( |
|||
opacity: opacity * (actionsIconTheme.opacity ?? 1.0f) |
|||
); |
|||
} |
|||
|
|||
Widget leading = widget.leading; |
|||
if (leading == null && widget.automaticallyImplyLeading) { |
|||
if (hasDrawer) { |
|||
leading = new IconButton( |
|||
icon: new Icon(Icons.menu), |
|||
onPressed: _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 = widget.title; |
|||
if (title != null) { |
|||
title = new DefaultTextStyle( |
|||
style: centerStyle, |
|||
softWrap: false, |
|||
overflow: TextOverflow.ellipsis, |
|||
child: title); |
|||
} |
|||
|
|||
Widget actions = null; |
|||
if (widget.actions != null && widget.actions.isNotEmpty()) { |
|||
actions = new Row( |
|||
mainAxisSize: MainAxisSize.min, |
|||
crossAxisAlignment: CrossAxisAlignment.stretch, |
|||
children: widget.actions); |
|||
} |
|||
else if (hasEndDrawer) { |
|||
actions = new IconButton( |
|||
icon: new Icon(Icons.menu), |
|||
onPressed: _handleDrawerButtonEnd, |
|||
tooltip: MaterialLocalizations.of(context).openAppDrawerTooltip); |
|||
} |
|||
|
|||
if (actions != null) { |
|||
actions = IconTheme.merge( |
|||
data: actionsIconTheme, |
|||
child: actions |
|||
); |
|||
} |
|||
|
|||
Widget toolbar = new NavigationToolbar( |
|||
leading: leading, |
|||
middle: title, |
|||
trailing: actions, |
|||
centerMiddle: widget._getEffectiveCenterTitle(themeData).Value, |
|||
middleSpacing: widget.titleSpacing); |
|||
|
|||
Widget appBar = new ClipRect( |
|||
child: new CustomSingleChildLayout( |
|||
layoutDelegate: new _ToolbarContainerLayout(), |
|||
child: IconTheme.merge( |
|||
data: overallIconTheme, |
|||
child: new DefaultTextStyle( |
|||
style: sideStyle, |
|||
child: toolbar) |
|||
) |
|||
) |
|||
); |
|||
|
|||
if (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 |
|||
) |
|||
), |
|||
widget.bottomOpacity == 1.0f |
|||
? (Widget) widget.bottom |
|||
: new Opacity( |
|||
opacity: new Interval(0.25f, 1.0f, curve: Curves.fastOutSlowIn).transform(widget |
|||
.bottomOpacity), |
|||
child: widget.bottom |
|||
) |
|||
} |
|||
); |
|||
} |
|||
|
|||
if (widget.primary) { |
|||
appBar = new SafeArea( |
|||
top: true, |
|||
child: appBar); |
|||
} |
|||
|
|||
appBar = new Align( |
|||
alignment: Alignment.topCenter, |
|||
child: appBar); |
|||
|
|||
if (widget.flexibleSpace != null) { |
|||
appBar = new Stack( |
|||
fit: StackFit.passthrough, |
|||
children: new List<Widget> { |
|||
widget.flexibleSpace, |
|||
appBar |
|||
} |
|||
); |
|||
} |
|||
|
|||
Brightness brightness = widget.brightness |
|||
?? appBarTheme.brightness |
|||
?? themeData.primaryColorBrightness; |
|||
SystemUiOverlayStyle overlayStyle = brightness == Brightness.dark |
|||
? SystemUiOverlayStyle.light |
|||
: SystemUiOverlayStyle.dark; |
|||
|
|||
return new AnnotatedRegion<SystemUiOverlayStyle>( |
|||
value: overlayStyle, |
|||
child: new Material( |
|||
color: widget.backgroundColor |
|||
?? appBarTheme.color |
|||
?? themeData.primaryColor, |
|||
elevation: widget.elevation |
|||
?? appBarTheme.elevation |
|||
?? _defaultElevation, |
|||
shape: widget.shape, |
|||
child: appBar |
|||
)); |
|||
} |
|||
} |
|||
|
|||
class _FloatingAppBar : StatefulWidget { |
|||
public _FloatingAppBar(Key key = null, Widget child = null) : base(key: key) { |
|||
this.child = child; |
|||
} |
|||
|
|||
public readonly Widget child; |
|||
|
|||
public override State createState() { |
|||
return new _FloatingAppBarState(); |
|||
} |
|||
} |
|||
|
|||
class _FloatingAppBarState : State<_FloatingAppBar> { |
|||
ScrollPosition _position; |
|||
|
|||
public _FloatingAppBarState() { |
|||
} |
|||
|
|||
public override void didChangeDependencies() { |
|||
base.didChangeDependencies(); |
|||
if (_position != null) { |
|||
_position.isScrollingNotifier.removeListener(_isScrollingListener); |
|||
} |
|||
|
|||
_position = Scrollable.of(context)?.position; |
|||
if (_position != null) { |
|||
_position.isScrollingNotifier.addListener(_isScrollingListener); |
|||
} |
|||
} |
|||
|
|||
public override void dispose() { |
|||
if (_position != null) { |
|||
_position.isScrollingNotifier.removeListener(_isScrollingListener); |
|||
} |
|||
|
|||
base.dispose(); |
|||
} |
|||
|
|||
RenderSliverFloatingPersistentHeader _headerRenderer() { |
|||
return (RenderSliverFloatingPersistentHeader) context.ancestorRenderObjectOfType( |
|||
new TypeMatcher<RenderSliverFloatingPersistentHeader>()); |
|||
} |
|||
|
|||
void _isScrollingListener() { |
|||
if (_position == null) { |
|||
return; |
|||
} |
|||
|
|||
RenderSliverFloatingPersistentHeader header = _headerRenderer(); |
|||
if (_position.isScrollingNotifier.value) { |
|||
header?.maybeStopSnapAnimation(_position.userScrollDirection); |
|||
} |
|||
else { |
|||
header?.maybeStartSnapAnimation(_position.userScrollDirection); |
|||
} |
|||
} |
|||
|
|||
public override Widget build(BuildContext context) { |
|||
return widget.child; |
|||
} |
|||
} |
|||
|
|||
class _SliverAppBarDelegate : SliverPersistentHeaderDelegate { |
|||
public _SliverAppBarDelegate( |
|||
Widget leading, |
|||
bool automaticallyImplyLeading, |
|||
Widget title, |
|||
List<Widget> actions, |
|||
Widget flexibleSpace, |
|||
PreferredSizeWidget bottom, |
|||
float? elevation, |
|||
bool forceElevated, |
|||
Color backgroundColor, |
|||
Brightness? brightness, |
|||
IconThemeData iconTheme, |
|||
IconThemeData actionsIconTheme, |
|||
TextTheme textTheme, |
|||
bool primary, |
|||
bool? centerTitle, |
|||
float titleSpacing, |
|||
float? expandedHeight, |
|||
float? collapsedHeight, |
|||
float? topPadding, |
|||
bool floating, |
|||
bool pinned, |
|||
FloatingHeaderSnapConfiguration snapConfiguration |
|||
) { |
|||
D.assert(primary || topPadding == 0.0); |
|||
this.leading = leading; |
|||
this.automaticallyImplyLeading = automaticallyImplyLeading; |
|||
this.title = title; |
|||
this.actions = actions; |
|||
this.flexibleSpace = flexibleSpace; |
|||
this.bottom = bottom; |
|||
this.elevation = elevation; |
|||
this.forceElevated = forceElevated; |
|||
this.backgroundColor = backgroundColor; |
|||
this.brightness = brightness; |
|||
this.iconTheme = iconTheme; |
|||
this.actionsIconTheme = actionsIconTheme; |
|||
this.textTheme = textTheme; |
|||
this.primary = primary; |
|||
this.centerTitle = centerTitle; |
|||
this.titleSpacing = titleSpacing; |
|||
this.expandedHeight = expandedHeight; |
|||
this.collapsedHeight = collapsedHeight; |
|||
this.topPadding = topPadding; |
|||
this.floating = floating; |
|||
this.pinned = pinned; |
|||
_snapConfiguration = snapConfiguration; |
|||
_bottomHeight = 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 bool forceElevated; |
|||
public readonly Color backgroundColor; |
|||
public readonly Brightness? brightness; |
|||
public readonly IconThemeData iconTheme; |
|||
public readonly IconThemeData actionsIconTheme; |
|||
public readonly TextTheme textTheme; |
|||
public readonly bool primary; |
|||
public readonly bool? centerTitle; |
|||
public readonly float titleSpacing; |
|||
public readonly float? expandedHeight; |
|||
public readonly float? collapsedHeight; |
|||
public readonly float? topPadding; |
|||
public readonly bool floating; |
|||
public readonly bool pinned; |
|||
|
|||
readonly float _bottomHeight; |
|||
|
|||
public override float? minExtent { |
|||
get { return collapsedHeight ?? (topPadding + Constants.kToolbarHeight + _bottomHeight); } |
|||
} |
|||
|
|||
public override float? maxExtent { |
|||
get { |
|||
return Mathf.Max( |
|||
(topPadding ?? 0.0f) + (expandedHeight ?? Constants.kToolbarHeight + _bottomHeight), |
|||
minExtent ?? 0.0f); |
|||
} |
|||
} |
|||
|
|||
public override FloatingHeaderSnapConfiguration snapConfiguration { |
|||
get { return _snapConfiguration; } |
|||
} |
|||
|
|||
FloatingHeaderSnapConfiguration _snapConfiguration; |
|||
|
|||
public override Widget build(BuildContext context, float shrinkOffset, bool overlapsContent) { |
|||
float? visibleMainHeight = maxExtent - shrinkOffset - topPadding; |
|||
float toolbarOpacity = !pinned || (!floating && bottom != null) |
|||
? ((visibleMainHeight - _bottomHeight) / Constants.kToolbarHeight)?.clamp(0.0f, 1.0f) ?? 1.0f |
|||
: 1.0f; |
|||
Widget appBar = FlexibleSpaceBar.createSettings( |
|||
minExtent: minExtent, |
|||
maxExtent: maxExtent, |
|||
currentExtent: Mathf.Max(minExtent ?? 0.0f, maxExtent ?? 0.0f - shrinkOffset), |
|||
toolbarOpacity: toolbarOpacity, |
|||
child: new AppBar( |
|||
leading: leading, |
|||
automaticallyImplyLeading: automaticallyImplyLeading, |
|||
title: title, |
|||
actions: actions, |
|||
flexibleSpace: flexibleSpace, |
|||
bottom: bottom, |
|||
elevation: forceElevated || overlapsContent || |
|||
(pinned && shrinkOffset > maxExtent - minExtent) |
|||
? elevation ?? 4.0f |
|||
: 0.0f, |
|||
backgroundColor: backgroundColor, |
|||
brightness: brightness, |
|||
iconTheme: iconTheme, |
|||
textTheme: textTheme, |
|||
primary: primary, |
|||
centerTitle: centerTitle, |
|||
titleSpacing: titleSpacing, |
|||
toolbarOpacity: toolbarOpacity, |
|||
bottomOpacity: pinned |
|||
? 1.0f |
|||
: (visibleMainHeight / _bottomHeight)?.clamp(0.0f, 1.0f) ?? 1.0f |
|||
) |
|||
); |
|||
return floating ? new _FloatingAppBar(child: appBar) : appBar; |
|||
} |
|||
|
|||
public override bool shouldRebuild(SliverPersistentHeaderDelegate _oldDelegate) { |
|||
_SliverAppBarDelegate oldDelegate = _oldDelegate as _SliverAppBarDelegate; |
|||
return leading != oldDelegate.leading |
|||
|| automaticallyImplyLeading != oldDelegate.automaticallyImplyLeading |
|||
|| title != oldDelegate.title |
|||
|| actions != oldDelegate.actions |
|||
|| flexibleSpace != oldDelegate.flexibleSpace |
|||
|| bottom != oldDelegate.bottom |
|||
|| _bottomHeight != oldDelegate._bottomHeight |
|||
|| elevation != oldDelegate.elevation |
|||
|| backgroundColor != oldDelegate.backgroundColor |
|||
|| brightness != oldDelegate.brightness |
|||
|| iconTheme != oldDelegate.iconTheme |
|||
|| actionsIconTheme != oldDelegate.actionsIconTheme |
|||
|| textTheme != oldDelegate.textTheme |
|||
|| primary != oldDelegate.primary |
|||
|| centerTitle != oldDelegate.centerTitle |
|||
|| titleSpacing != oldDelegate.titleSpacing |
|||
|| expandedHeight != oldDelegate.expandedHeight |
|||
|| topPadding != oldDelegate.topPadding |
|||
|| pinned != oldDelegate.pinned |
|||
|| floating != oldDelegate.floating |
|||
|| snapConfiguration != oldDelegate.snapConfiguration; |
|||
} |
|||
|
|||
public override string ToString() { |
|||
return |
|||
$"{Diagnostics.describeIdentity(this)}(topPadding: {topPadding?.ToString("F1")}, bottomHeight: {_bottomHeight.ToString("F1")}, ...)"; |
|||
} |
|||
} |
|||
|
|||
public class SliverAppBar : StatefulWidget { |
|||
public SliverAppBar( |
|||
Key key = null, |
|||
Widget leading = null, |
|||
bool automaticallyImplyLeading = true, |
|||
Widget title = null, |
|||
List<Widget> actions = null, |
|||
Widget flexibleSpace = null, |
|||
PreferredSizeWidget bottom = null, |
|||
float? elevation = null, |
|||
bool forceElevated = false, |
|||
Color backgroundColor = null, |
|||
Brightness? brightness = null, |
|||
IconThemeData iconTheme = null, |
|||
IconThemeData actionsIconTheme = null, |
|||
TextTheme textTheme = null, |
|||
bool primary = true, |
|||
bool? centerTitle = null, |
|||
float titleSpacing = NavigationToolbar.kMiddleSpacing, |
|||
float? expandedHeight = null, |
|||
bool floating = false, |
|||
bool pinned = false, |
|||
bool snap = false |
|||
) : base(key: key) { |
|||
D.assert(floating || !snap, () => "The 'snap' argument only makes sense for floating app bars."); |
|||
this.leading = leading; |
|||
this.automaticallyImplyLeading = true; |
|||
this.title = title; |
|||
this.actions = actions; |
|||
this.flexibleSpace = flexibleSpace; |
|||
this.bottom = bottom; |
|||
this.elevation = elevation; |
|||
this.forceElevated = forceElevated; |
|||
this.backgroundColor = backgroundColor; |
|||
this.brightness = brightness; |
|||
this.iconTheme = iconTheme; |
|||
this.actionsIconTheme = actionsIconTheme; |
|||
this.textTheme = textTheme; |
|||
this.primary = primary; |
|||
this.centerTitle = centerTitle; |
|||
this.titleSpacing = NavigationToolbar.kMiddleSpacing; |
|||
this.expandedHeight = expandedHeight; |
|||
this.floating = floating; |
|||
this.pinned = pinned; |
|||
this.snap = snap; |
|||
} |
|||
|
|||
|
|||
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 bool forceElevated; |
|||
|
|||
public readonly Color backgroundColor; |
|||
|
|||
public readonly Brightness? brightness; |
|||
|
|||
public readonly IconThemeData iconTheme; |
|||
|
|||
public readonly IconThemeData actionsIconTheme; |
|||
|
|||
public readonly TextTheme textTheme; |
|||
|
|||
public readonly bool primary; |
|||
|
|||
public readonly bool? centerTitle; |
|||
|
|||
public readonly float titleSpacing; |
|||
|
|||
public readonly float? expandedHeight; |
|||
|
|||
public readonly bool floating; |
|||
|
|||
public readonly bool pinned; |
|||
|
|||
public readonly bool snap; |
|||
|
|||
public override State createState() { |
|||
return new _SliverAppBarState(); |
|||
} |
|||
} |
|||
|
|||
class _SliverAppBarState : TickerProviderStateMixin<SliverAppBar> { |
|||
FloatingHeaderSnapConfiguration _snapConfiguration; |
|||
|
|||
void _updateSnapConfiguration() { |
|||
if (widget.snap && widget.floating) { |
|||
_snapConfiguration = new FloatingHeaderSnapConfiguration( |
|||
vsync: this, |
|||
curve: Curves.easeOut, |
|||
duration: new TimeSpan(0, 0, 0, 0, 200) |
|||
); |
|||
} |
|||
else { |
|||
_snapConfiguration = null; |
|||
} |
|||
} |
|||
|
|||
public override void initState() { |
|||
base.initState(); |
|||
_updateSnapConfiguration(); |
|||
} |
|||
|
|||
public override void didUpdateWidget(StatefulWidget _oldWidget) { |
|||
base.didUpdateWidget(_oldWidget); |
|||
SliverAppBar oldWidget = _oldWidget as SliverAppBar; |
|||
if (widget.snap != oldWidget.snap || widget.floating != oldWidget.floating) { |
|||
_updateSnapConfiguration(); |
|||
} |
|||
} |
|||
|
|||
public override Widget build(BuildContext context) { |
|||
D.assert(!widget.primary || WidgetsD.debugCheckHasMediaQuery(context)); |
|||
float? topPadding = widget.primary ? MediaQuery.of(context).padding.top : 0.0f; |
|||
float? collapsedHeight = (widget.pinned && widget.floating && widget.bottom != null) |
|||
? widget.bottom.preferredSize.height + topPadding |
|||
: null; |
|||
|
|||
return MediaQuery.removePadding( |
|||
context: context, |
|||
removeBottom: true, |
|||
child: new SliverPersistentHeader( |
|||
floating: widget.floating, |
|||
pinned: widget.pinned, |
|||
del: new _SliverAppBarDelegate( |
|||
leading: widget.leading, |
|||
automaticallyImplyLeading: widget.automaticallyImplyLeading, |
|||
title: widget.title, |
|||
actions: widget.actions, |
|||
flexibleSpace: widget.flexibleSpace, |
|||
bottom: widget.bottom, |
|||
elevation: widget.elevation, |
|||
forceElevated: widget.forceElevated, |
|||
backgroundColor: widget.backgroundColor, |
|||
brightness: widget.brightness, |
|||
iconTheme: widget.iconTheme, |
|||
actionsIconTheme: widget.actionsIconTheme, |
|||
textTheme: widget.textTheme, |
|||
primary: widget.primary, |
|||
centerTitle: widget.centerTitle, |
|||
titleSpacing: widget.titleSpacing, |
|||
expandedHeight: widget.expandedHeight, |
|||
collapsedHeight: collapsedHeight, |
|||
topPadding: topPadding, |
|||
floating: widget.floating, |
|||
pinned: widget.pinned, |
|||
snapConfiguration: _snapConfiguration |
|||
) |
|||
) |
|||
); |
|||
} |
|||
} |
|||
} |
|
|||
fileFormatVersion: 2 |
|||
guid: da897030c4af84749a3ac5494e45c359 |
|||
MonoImporter: |
|||
externalObjects: {} |
|||
serializedVersion: 2 |
|||
defaultReferences: [] |
|||
executionOrder: 0 |
|||
icon: {instanceID: 0} |
|||
userData: |
|||
assetBundleName: |
|||
assetBundleVariant: |
|
|||
using Unity.UIWidgets.foundation; |
|||
using Unity.UIWidgets.service; |
|||
using Unity.UIWidgets.ui; |
|||
using Unity.UIWidgets.widgets; |
|||
|
|||
namespace Unity.UIWidgets.material { |
|||
public class AppBarTheme : Diagnosticable { |
|||
public AppBarTheme( |
|||
Brightness? brightness = null, |
|||
Color color = null, |
|||
float? elevation = null, |
|||
IconThemeData iconTheme = null, |
|||
IconThemeData actionsIconTheme = null, |
|||
TextTheme textTheme = null |
|||
) { |
|||
this.brightness = brightness; |
|||
this.color = color; |
|||
this.elevation = elevation; |
|||
this.iconTheme = iconTheme; |
|||
this.actionsIconTheme = actionsIconTheme; |
|||
this.textTheme = textTheme; |
|||
} |
|||
|
|||
public readonly Brightness? brightness; |
|||
|
|||
public readonly Color color; |
|||
|
|||
public readonly float? elevation; |
|||
|
|||
public readonly IconThemeData iconTheme; |
|||
|
|||
public readonly IconThemeData actionsIconTheme; |
|||
|
|||
public readonly TextTheme textTheme; |
|||
|
|||
AppBarTheme copyWith( |
|||
Brightness? brightness = null, |
|||
Color color = null, |
|||
float? elevation = null, |
|||
IconThemeData iconTheme = null, |
|||
IconThemeData actionsIconTheme = null, |
|||
TextTheme textTheme = null |
|||
) { |
|||
return new AppBarTheme( |
|||
brightness: brightness ?? this.brightness, |
|||
color: color ?? this.color, |
|||
elevation: elevation ?? this.elevation, |
|||
iconTheme: iconTheme ?? this.iconTheme, |
|||
actionsIconTheme: actionsIconTheme ?? this.actionsIconTheme, |
|||
textTheme: textTheme ?? this.textTheme |
|||
); |
|||
} |
|||
|
|||
public static AppBarTheme of(BuildContext context) { |
|||
return Theme.of(context).appBarTheme; |
|||
} |
|||
|
|||
public static AppBarTheme lerp(AppBarTheme a, AppBarTheme b, float t) { |
|||
return new AppBarTheme( |
|||
brightness: t < 0.5f ? a?.brightness : b?.brightness, |
|||
color: Color.lerp(a?.color, b?.color, t), |
|||
elevation: MathUtils.lerpFloat(a?.elevation ?? 0.0f, b?.elevation ?? 0.0f, t), |
|||
iconTheme: IconThemeData.lerp(a?.iconTheme, b?.iconTheme, t), |
|||
actionsIconTheme: IconThemeData.lerp(a?.actionsIconTheme, b?.actionsIconTheme, t), |
|||
textTheme: TextTheme.lerp(a?.textTheme, b?.textTheme, t) |
|||
); |
|||
} |
|||
|
|||
public override int GetHashCode() { |
|||
var hashCode = brightness?.GetHashCode() ?? 0; |
|||
hashCode = (hashCode * 397) ^ color?.GetHashCode() ?? 0; |
|||
hashCode = (hashCode * 397) ^ elevation?.GetHashCode() ?? 0; |
|||
hashCode = (hashCode * 397) ^ iconTheme?.GetHashCode() ?? 0; |
|||
hashCode = (hashCode * 397) ^ actionsIconTheme?.GetHashCode() ?? 0; |
|||
hashCode = (hashCode * 397) ^ textTheme?.GetHashCode() ?? 0; |
|||
return hashCode; |
|||
} |
|||
|
|||
public override bool Equals(object obj) { |
|||
if (ReferenceEquals(null, obj)) { |
|||
return false; |
|||
} |
|||
|
|||
if (ReferenceEquals(this, obj)) { |
|||
return true; |
|||
} |
|||
|
|||
if (obj.GetType() != GetType()) { |
|||
return false; |
|||
} |
|||
|
|||
return Equals((AppBarTheme) obj); |
|||
} |
|||
|
|||
public static bool operator ==(AppBarTheme left, AppBarTheme right) { |
|||
return Equals(left, right); |
|||
} |
|||
|
|||
public static bool operator !=(AppBarTheme left, AppBarTheme right) { |
|||
return !Equals(left, right); |
|||
} |
|||
|
|||
public bool Equals(AppBarTheme other) { |
|||
return other.brightness == brightness |
|||
&& other.color == color |
|||
&& other.elevation == elevation |
|||
&& other.iconTheme == iconTheme |
|||
&& other.actionsIconTheme == actionsIconTheme |
|||
&& other.textTheme == textTheme; |
|||
} |
|||
|
|||
public override void debugFillProperties(DiagnosticPropertiesBuilder properties) { |
|||
base.debugFillProperties(properties); |
|||
properties.add(new DiagnosticsProperty<Brightness?>("brightness", brightness, defaultValue: null)); |
|||
properties.add(new DiagnosticsProperty<Color>("color", color, defaultValue: null)); |
|||
properties.add(new DiagnosticsProperty<float?>("elevation", elevation, defaultValue: null)); |
|||
properties.add(new DiagnosticsProperty<IconThemeData>("iconTheme", iconTheme, defaultValue: null)); |
|||
properties.add(new DiagnosticsProperty<IconThemeData>("actionsIconTheme", actionsIconTheme, defaultValue: null)); |
|||
properties.add(new DiagnosticsProperty<TextTheme>("textTheme", textTheme, defaultValue: null)); |
|||
} |
|||
} |
|||
} |
|
|||
fileFormatVersion: 2 |
|||
guid: 0c0ee979ef6b4f32a092532c3bdae31e |
|||
timeCreated: 1556178331 |
|
|||
using System.Collections.Generic; |
|||
using Unity.UIWidgets.animation; |
|||
using Unity.UIWidgets.foundation; |
|||
using Unity.UIWidgets.ui; |
|||
using UnityEngine; |
|||
using Rect = Unity.UIWidgets.ui.Rect; |
|||
|
|||
namespace Unity.UIWidgets.material { |
|||
static class ArcUtils { |
|||
public const float _kOnAxisDelta = 2.0f; |
|||
|
|||
public static readonly List<_Diagonal> _allDiagonals = new List<_Diagonal> { |
|||
new _Diagonal(_CornerId.topLeft, _CornerId.bottomRight), |
|||
new _Diagonal(_CornerId.bottomRight, _CornerId.topLeft), |
|||
new _Diagonal(_CornerId.topRight, _CornerId.bottomLeft), |
|||
new _Diagonal(_CornerId.bottomLeft, _CornerId.topRight) |
|||
}; |
|||
|
|||
public delegate float _KeyFunc<T>(T input); |
|||
|
|||
|
|||
public static T _maxBy<T>(List<T> input, _KeyFunc<T> keyFunc) { |
|||
T maxValue = default(T); |
|||
float? maxKey = null; |
|||
foreach (T value in input) { |
|||
float key = keyFunc(value); |
|||
if (maxKey == null || key > maxKey) { |
|||
maxValue = value; |
|||
maxKey = key; |
|||
} |
|||
} |
|||
|
|||
return maxValue; |
|||
} |
|||
} |
|||
|
|||
public class MaterialPointArcTween : Tween<Offset> { |
|||
public MaterialPointArcTween( |
|||
Offset begin = null, |
|||
Offset end = null) : base(begin: begin, end: end) { |
|||
} |
|||
|
|||
bool _dirty = true; |
|||
|
|||
void _initialze() { |
|||
D.assert(begin != null); |
|||
D.assert(end != null); |
|||
|
|||
Offset delta = end - begin; |
|||
float deltaX = delta.dx.abs(); |
|||
float deltaY = delta.dy.abs(); |
|||
float distanceFromAtoB = delta.distance; |
|||
Offset c = new Offset(end.dx, begin.dy); |
|||
|
|||
float sweepAngle() { |
|||
return 2.0f * Mathf.Asin(distanceFromAtoB / (2.0f * _radius)); |
|||
} |
|||
|
|||
if (deltaX > ArcUtils._kOnAxisDelta && deltaY > ArcUtils._kOnAxisDelta) { |
|||
if (deltaX < deltaY) { |
|||
_radius = distanceFromAtoB * distanceFromAtoB / (c - begin).distance / 2.0f; |
|||
_center = new Offset(end.dx + _radius * (begin.dx - end.dx).sign(), |
|||
end.dy); |
|||
if (begin.dx < end.dx) { |
|||
_beginAngle = sweepAngle() * (begin.dy - end.dy).sign(); |
|||
_endAngle = 0.0f; |
|||
} |
|||
else { |
|||
_beginAngle = (Mathf.PI + sweepAngle() * (end.dy - begin.dy).sign()); |
|||
_endAngle = Mathf.PI; |
|||
} |
|||
} |
|||
else { |
|||
_radius = distanceFromAtoB * distanceFromAtoB / (c - end).distance / 2.0f; |
|||
_center = new Offset(begin.dx, |
|||
begin.dy + (end.dy - begin.dy).sign() * _radius); |
|||
if (begin.dy < end.dy) { |
|||
_beginAngle = -Mathf.PI / 2.0f; |
|||
_endAngle = _beginAngle + sweepAngle() * (end.dx - begin.dx).sign(); |
|||
} |
|||
else { |
|||
_beginAngle = Mathf.PI / 2.0f; |
|||
_endAngle = _beginAngle + sweepAngle() * (begin.dx - end.dx).sign(); |
|||
} |
|||
} |
|||
|
|||
D.assert(_beginAngle != null); |
|||
D.assert(_endAngle != null); |
|||
} |
|||
else { |
|||
_beginAngle = null; |
|||
_endAngle = null; |
|||
} |
|||
|
|||
_dirty = false; |
|||
} |
|||
|
|||
public Offset center { |
|||
get { |
|||
if (begin == null || end == null) { |
|||
return null; |
|||
} |
|||
|
|||
if (_dirty) { |
|||
_initialze(); |
|||
} |
|||
|
|||
return _center; |
|||
} |
|||
} |
|||
|
|||
Offset _center; |
|||
|
|||
public float? radius { |
|||
get { |
|||
if (begin == null || end == null) { |
|||
return null; |
|||
} |
|||
|
|||
if (_dirty) { |
|||
_initialze(); |
|||
} |
|||
|
|||
return _radius; |
|||
} |
|||
} |
|||
|
|||
float _radius; |
|||
|
|||
public float? beginAngle { |
|||
get { |
|||
if (begin == null || end == null) { |
|||
return null; |
|||
} |
|||
|
|||
if (_dirty) { |
|||
_initialze(); |
|||
} |
|||
|
|||
return _beginAngle; |
|||
} |
|||
} |
|||
|
|||
float? _beginAngle; |
|||
|
|||
public float? endAngle { |
|||
get { |
|||
if (begin == null || end == null) { |
|||
return null; |
|||
} |
|||
|
|||
if (_dirty) { |
|||
_initialze(); |
|||
} |
|||
|
|||
return _endAngle; |
|||
} |
|||
} |
|||
|
|||
float? _endAngle; |
|||
|
|||
public override Offset begin { |
|||
get { return base.begin; } |
|||
set { |
|||
if (value != base.begin) { |
|||
base.begin = value; |
|||
_dirty = true; |
|||
} |
|||
} |
|||
} |
|||
|
|||
public override Offset end { |
|||
get { return base.end; } |
|||
set { |
|||
if (value != base.end) { |
|||
base.end = value; |
|||
_dirty = true; |
|||
} |
|||
} |
|||
} |
|||
|
|||
public override Offset lerp(float t) { |
|||
if (_dirty) { |
|||
_initialze(); |
|||
} |
|||
|
|||
if (t == 0.0) { |
|||
return begin; |
|||
} |
|||
|
|||
if (t == 1.0) { |
|||
return end; |
|||
} |
|||
|
|||
if (_beginAngle == null || _endAngle == null) { |
|||
return Offset.lerp(begin, end, t); |
|||
} |
|||
|
|||
float angle = MathUtils.lerpNullableFloat(_beginAngle, _endAngle, t) ?? 0.0f; |
|||
float x = Mathf.Cos(angle) * _radius; |
|||
float y = Mathf.Sin(angle) * _radius; |
|||
return _center + new Offset(x, y); |
|||
} |
|||
|
|||
public override string ToString() { |
|||
return GetType() + "(" + begin + "->" + end + "); center=" + center + |
|||
", radius=" + radius + ", beginAngle=" + beginAngle + ", endAngle=" + endAngle; |
|||
} |
|||
} |
|||
|
|||
public enum _CornerId { |
|||
topLeft, |
|||
topRight, |
|||
bottomLeft, |
|||
bottomRight |
|||
} |
|||
|
|||
public class _Diagonal { |
|||
public _Diagonal( |
|||
_CornerId beginId, |
|||
_CornerId endId) { |
|||
this.beginId = beginId; |
|||
this.endId = endId; |
|||
} |
|||
|
|||
public readonly _CornerId beginId; |
|||
|
|||
public readonly _CornerId endId; |
|||
} |
|||
|
|||
public class MaterialRectArcTween : RectTween { |
|||
public MaterialRectArcTween( |
|||
Rect begin = null, |
|||
Rect end = null) : base(begin: begin, end: end) { |
|||
} |
|||
|
|||
bool _dirty = true; |
|||
|
|||
void _initialize() { |
|||
D.assert(begin != null); |
|||
D.assert(end != null); |
|||
Offset centersVector = end.center - begin.center; |
|||
_Diagonal diagonal = ArcUtils._maxBy(ArcUtils._allDiagonals, |
|||
(_Diagonal d) => _diagonalSupport(centersVector, d)); |
|||
_beginArc = new MaterialPointArcTween( |
|||
begin: _cornerFor(begin, diagonal.beginId), |
|||
end: _cornerFor(end, diagonal.beginId)); |
|||
_endArc = new MaterialPointArcTween( |
|||
begin: _cornerFor(begin, diagonal.endId), |
|||
end: _cornerFor(end, diagonal.endId)); |
|||
_dirty = false; |
|||
} |
|||
|
|||
float _diagonalSupport(Offset centersVector, _Diagonal diagonal) { |
|||
Offset delta = _cornerFor(begin, diagonal.endId) - _cornerFor(begin, diagonal.beginId); |
|||
float length = delta.distance; |
|||
return centersVector.dx * delta.dx / length + centersVector.dy * delta.dy / length; |
|||
} |
|||
|
|||
Offset _cornerFor(Rect rect, _CornerId id) { |
|||
switch (id) { |
|||
case _CornerId.topLeft: return rect.topLeft; |
|||
case _CornerId.topRight: return rect.topRight; |
|||
case _CornerId.bottomLeft: return rect.bottomLeft; |
|||
case _CornerId.bottomRight: return rect.bottomRight; |
|||
} |
|||
|
|||
return Offset.zero; |
|||
} |
|||
|
|||
public MaterialPointArcTween beginArc { |
|||
get { |
|||
if (begin == null) { |
|||
return null; |
|||
} |
|||
|
|||
if (_dirty) { |
|||
_initialize(); |
|||
} |
|||
|
|||
return _beginArc; |
|||
} |
|||
} |
|||
|
|||
MaterialPointArcTween _beginArc; |
|||
|
|||
public MaterialPointArcTween endArc { |
|||
get { |
|||
if (end == null) { |
|||
return null; |
|||
} |
|||
|
|||
if (_dirty) { |
|||
_initialize(); |
|||
} |
|||
|
|||
return _endArc; |
|||
} |
|||
} |
|||
|
|||
MaterialPointArcTween _endArc; |
|||
|
|||
public override Rect begin { |
|||
get { return base.begin; } |
|||
set { |
|||
if (value != base.begin) { |
|||
base.begin = value; |
|||
_dirty = true; |
|||
} |
|||
} |
|||
} |
|||
|
|||
public override Rect end { |
|||
get { return base.end; } |
|||
set { |
|||
if (value != base.end) { |
|||
base.end = value; |
|||
_dirty = true; |
|||
} |
|||
} |
|||
} |
|||
|
|||
public override Rect lerp(float t) { |
|||
if (_dirty) { |
|||
_initialize(); |
|||
} |
|||
|
|||
if (t == 0.0) { |
|||
return begin; |
|||
} |
|||
|
|||
if (t == 1.0) { |
|||
return end; |
|||
} |
|||
|
|||
return Rect.fromPoints(_beginArc.lerp(t), _endArc.lerp(t)); |
|||
} |
|||
|
|||
public override string ToString() { |
|||
return GetType() + "(" + begin + "->" + end + ")"; |
|||
} |
|||
} |
|||
|
|||
public class MaterialRectCenterArcTween : RectTween { |
|||
public MaterialRectCenterArcTween( |
|||
Rect begin = null, |
|||
Rect end = null) : base(begin: begin, end: end) { |
|||
} |
|||
|
|||
bool _dirty = true; |
|||
|
|||
void _initialize() { |
|||
D.assert(begin != null); |
|||
D.assert(end != null); |
|||
_centerArc = new MaterialPointArcTween( |
|||
begin: begin.center, |
|||
end: end.center); |
|||
_dirty = false; |
|||
} |
|||
|
|||
public MaterialPointArcTween centerArc { |
|||
get { |
|||
if (begin == null || end == null) { |
|||
return null; |
|||
} |
|||
|
|||
if (_dirty) { |
|||
_initialize(); |
|||
} |
|||
|
|||
return _centerArc; |
|||
} |
|||
} |
|||
|
|||
MaterialPointArcTween _centerArc; |
|||
|
|||
|
|||
public override Rect begin { |
|||
get { return base.begin; } |
|||
set { |
|||
if (value != base.begin) { |
|||
base.begin = value; |
|||
_dirty = true; |
|||
} |
|||
} |
|||
} |
|||
|
|||
public override Rect end { |
|||
get { return base.end; } |
|||
set { |
|||
if (value != base.end) { |
|||
base.end = value; |
|||
_dirty = true; |
|||
} |
|||
} |
|||
} |
|||
|
|||
public override Rect lerp(float t) { |
|||
if (_dirty) { |
|||
_initialize(); |
|||
} |
|||
|
|||
if (t == 0.0) { |
|||
return begin; |
|||
} |
|||
|
|||
if (t == 1.0) { |
|||
return end; |
|||
} |
|||
|
|||
Offset center = _centerArc.lerp(t); |
|||
float width = MathUtils.lerpFloat(begin.width, end.width, t); |
|||
float height = MathUtils.lerpFloat(begin.height, end.height, t); |
|||
return Rect.fromLTWH( |
|||
(center.dx - width / 2.0f), |
|||
(center.dy - height / 2.0f), |
|||
width, |
|||
height); |
|||
} |
|||
|
|||
public override string ToString() { |
|||
return GetType() + "(" + begin + "->" + end + "); centerArc=" + centerArc; |
|||
} |
|||
} |
|||
} |
|
|||
fileFormatVersion: 2 |
|||
guid: c31d4962cd3d8445a8cd357447154970 |
|||
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; |
|||
} |
|||
} |
|||
|
|||
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: 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 Unity.UIWidgets.foundation; |
|||
using Unity.UIWidgets.painting; |
|||
using Unity.UIWidgets.rendering; |
|||
using Unity.UIWidgets.ui; |
|||
using Unity.UIWidgets.widgets; |
|||
|
|||
namespace Unity.UIWidgets.material { |
|||
public class BottomAppBar : StatefulWidget { |
|||
public BottomAppBar( |
|||
Key key = null, |
|||
Color color = null, |
|||
float? elevation = null, |
|||
NotchedShape shape = null, |
|||
Clip clipBehavior = Clip.none, |
|||
float notchMargin = 4.0f, |
|||
Widget child = null |
|||
) : base(key: key) { |
|||
D.assert(elevation == null || elevation >= 0.0f); |
|||
this.child = child; |
|||
this.color = color; |
|||
this.elevation = elevation; |
|||
this.shape = shape; |
|||
this.clipBehavior = clipBehavior; |
|||
this.notchMargin = notchMargin; |
|||
} |
|||
|
|||
public readonly Widget child; |
|||
|
|||
public readonly Color color; |
|||
|
|||
public readonly float? elevation; |
|||
|
|||
public readonly NotchedShape shape; |
|||
|
|||
public readonly Clip clipBehavior; |
|||
|
|||
public readonly float notchMargin; |
|||
|
|||
public override State createState() { |
|||
return new _BottomAppBarState(); |
|||
} |
|||
} |
|||
|
|||
class _BottomAppBarState : State<BottomAppBar> { |
|||
ValueListenable<ScaffoldGeometry> geometryListenable; |
|||
const float _defaultElevation = 8.0f; |
|||
|
|||
public override void didChangeDependencies() { |
|||
base.didChangeDependencies(); |
|||
geometryListenable = Scaffold.geometryOf(context); |
|||
} |
|||
|
|||
public override Widget build(BuildContext context) { |
|||
BottomAppBarTheme babTheme = BottomAppBarTheme.of(context); |
|||
NotchedShape notchedShape = widget.shape ?? babTheme.shape; |
|||
CustomClipper<Path> clipper = notchedShape != null |
|||
? (CustomClipper<Path>) new _BottomAppBarClipper( |
|||
geometry: geometryListenable, |
|||
shape: notchedShape, |
|||
notchMargin: widget.notchMargin |
|||
) |
|||
: new ShapeBorderClipper(shape: new RoundedRectangleBorder()); |
|||
return new PhysicalShape( |
|||
clipper: clipper, |
|||
elevation: widget.elevation ?? babTheme.elevation ?? _defaultElevation, |
|||
color: widget.color ?? babTheme.color ?? Theme.of(context).bottomAppBarColor, |
|||
clipBehavior: widget.clipBehavior, |
|||
child: new Material( |
|||
type: MaterialType.transparency, |
|||
child: widget.child == null |
|||
? null |
|||
: new SafeArea(child: widget.child) |
|||
) |
|||
); |
|||
} |
|||
} |
|||
|
|||
class _BottomAppBarClipper : CustomClipper<Path> { |
|||
public _BottomAppBarClipper( |
|||
ValueListenable<ScaffoldGeometry> geometry, |
|||
NotchedShape shape, |
|||
float notchMargin |
|||
) : base(reclip: geometry) { |
|||
D.assert(geometry != null); |
|||
D.assert(shape != null); |
|||
this.geometry = geometry; |
|||
this.shape = shape; |
|||
this.notchMargin = notchMargin; |
|||
} |
|||
|
|||
public readonly ValueListenable<ScaffoldGeometry> geometry; |
|||
public readonly NotchedShape shape; |
|||
public readonly float notchMargin; |
|||
|
|||
public override Path getClip(Size size) { |
|||
Rect button = geometry.value.floatingActionButtonArea?.translate( |
|||
0.0f, |
|||
(geometry.value.bottomNavigationBarTop ?? 0.0f) * -1.0f |
|||
); |
|||
return shape.getOuterPath(Offset.zero & size, button?.inflate(notchMargin)); |
|||
} |
|||
|
|||
public override bool shouldReclip(CustomClipper<Path> _oldClipper) { |
|||
_BottomAppBarClipper oldClipper = _oldClipper as _BottomAppBarClipper; |
|||
return oldClipper.geometry != geometry |
|||
|| oldClipper.shape != shape |
|||
|| oldClipper.notchMargin != notchMargin; |
|||
} |
|||
} |
|||
} |
|
|||
fileFormatVersion: 2 |
|||
guid: aa89369405044a62a19225b2c20815f6 |
|||
timeCreated: 1553156127 |
|
|||
using Unity.UIWidgets.foundation; |
|||
using Unity.UIWidgets.painting; |
|||
using Unity.UIWidgets.ui; |
|||
using Unity.UIWidgets.widgets; |
|||
|
|||
namespace Unity.UIWidgets.material { |
|||
public class BottomAppBarTheme : Diagnosticable { |
|||
public BottomAppBarTheme( |
|||
Color color = null, |
|||
float? elevation = null, |
|||
NotchedShape shape = null |
|||
) { |
|||
this.color = color; |
|||
this.elevation = elevation; |
|||
this.shape = shape; |
|||
} |
|||
|
|||
public readonly Color color; |
|||
|
|||
public readonly float? elevation; |
|||
|
|||
public readonly NotchedShape shape; |
|||
|
|||
BottomAppBarTheme copyWith( |
|||
Color color = null, |
|||
float? elevation = null, |
|||
NotchedShape shape = null |
|||
) { |
|||
return new BottomAppBarTheme( |
|||
color: color ?? this.color, |
|||
elevation: elevation ?? this.elevation, |
|||
shape: shape ?? this.shape |
|||
); |
|||
} |
|||
|
|||
public static BottomAppBarTheme of(BuildContext context) { |
|||
return Theme.of(context).bottomAppBarTheme; |
|||
} |
|||
|
|||
public static BottomAppBarTheme lerp(BottomAppBarTheme a, BottomAppBarTheme b, float t) { |
|||
return new BottomAppBarTheme( |
|||
color: Color.lerp(a?.color, b?.color, t), |
|||
elevation: MathUtils.lerpFloat(a?.elevation ?? 0.0f, b?.elevation ?? 0.0f, t), |
|||
shape: t < 0.5f ? a?.shape : b?.shape |
|||
); |
|||
} |
|||
|
|||
public override int GetHashCode() { |
|||
var hashCode = color?.GetHashCode() ?? 0; |
|||
hashCode = (hashCode * 397) ^ elevation?.GetHashCode() ?? 0; |
|||
hashCode = (hashCode * 397) ^ shape?.GetHashCode() ?? 0; |
|||
return hashCode; |
|||
} |
|||
|
|||
public bool Equals(BottomAppBarTheme other) { |
|||
return other.color == color |
|||
&& other.elevation == elevation |
|||
&& other.shape == shape; |
|||
} |
|||
|
|||
public override bool Equals(object obj) { |
|||
if (ReferenceEquals(null, obj)) { |
|||
return false; |
|||
} |
|||
|
|||
if (ReferenceEquals(this, obj)) { |
|||
return true; |
|||
} |
|||
|
|||
if (obj.GetType() != GetType()) { |
|||
return false; |
|||
} |
|||
|
|||
return Equals((BottomAppBarTheme) obj); |
|||
} |
|||
|
|||
public static bool operator ==(BottomAppBarTheme left, BottomAppBarTheme right) { |
|||
return Equals(left, right); |
|||
} |
|||
|
|||
public static bool operator !=(BottomAppBarTheme left, BottomAppBarTheme right) { |
|||
return !Equals(left, right); |
|||
} |
|||
|
|||
public override void debugFillProperties(DiagnosticPropertiesBuilder properties) { |
|||
base.debugFillProperties(properties); |
|||
properties.add(new DiagnosticsProperty<Color>("color", color, defaultValue: null)); |
|||
properties.add(new DiagnosticsProperty<float?>("elevation", elevation, defaultValue: null)); |
|||
properties.add(new DiagnosticsProperty<NotchedShape>("shape", shape, defaultValue: null)); |
|||
} |
|||
} |
|||
} |
|
|||
fileFormatVersion: 2 |
|||
guid: 9c88d19dd1254f4eb6c0c998084832ea |
|||
timeCreated: 1556185402 |
|
|||
using System; |
|||
using System.Collections.Generic; |
|||
using System.Linq; |
|||
using Unity.UIWidgets.animation; |
|||
using Unity.UIWidgets.foundation; |
|||
using Unity.UIWidgets.gestures; |
|||
using Unity.UIWidgets.painting; |
|||
using Unity.UIWidgets.rendering; |
|||
using Unity.UIWidgets.scheduler; |
|||
using Unity.UIWidgets.service; |
|||
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; |
|||
using Transform = Unity.UIWidgets.widgets.Transform; |
|||
|
|||
namespace Unity.UIWidgets.material { |
|||
public enum BottomNavigationBarType { |
|||
fix, |
|||
shifting |
|||
} |
|||
|
|||
public class BottomNavigationBar : StatefulWidget { |
|||
public BottomNavigationBar( |
|||
Key key = null, |
|||
List<BottomNavigationBarItem> items = null, |
|||
ValueChanged<int> onTap = null, |
|||
int currentIndex = 0, |
|||
float elevation = 8.0f, |
|||
BottomNavigationBarType? type = null, |
|||
Color fixedColor = null, |
|||
Color backgroundColor = null, |
|||
float iconSize = 24.0f, |
|||
Color selectedItemColor = null, |
|||
Color unselectedItemColor = null, |
|||
float selectedFontSize = 14.0f, |
|||
float unselectedFontSize = 12.0f, |
|||
bool showSelectedLabels = true, |
|||
bool? showUnselectedLabels = null |
|||
) : base(key: key) { |
|||
D.assert(items != null); |
|||
D.assert(items.Count >= 2); |
|||
D.assert(items.All((BottomNavigationBarItem item) => item.title != null) == true, |
|||
() => "Every item must have a non-null title" |
|||
); |
|||
D.assert(0 <= currentIndex && currentIndex < items.Count); |
|||
D.assert(elevation >= 0.0f); |
|||
D.assert(iconSize >= 0.0f); |
|||
D.assert(selectedItemColor == null || fixedColor == null, |
|||
() => "Either selectedItemColor or fixedColor can be specified, but not both!"); |
|||
D.assert(selectedFontSize >= 0.0f); |
|||
D.assert(unselectedFontSize >= 0.0f); |
|||
type = _type(type, items); |
|||
this.items = items; |
|||
this.onTap = onTap; |
|||
this.currentIndex = currentIndex; |
|||
this.elevation = elevation; |
|||
this.type = type ?? (items.Count <= 3 ? BottomNavigationBarType.fix : BottomNavigationBarType.shifting); |
|||
this.backgroundColor = backgroundColor; |
|||
this.iconSize = iconSize; |
|||
this.selectedItemColor = selectedItemColor ?? fixedColor; |
|||
this.unselectedItemColor = unselectedItemColor; |
|||
this.selectedFontSize = selectedFontSize; |
|||
this.unselectedFontSize = unselectedFontSize; |
|||
this.showSelectedLabels = showSelectedLabels; |
|||
this.showUnselectedLabels = showUnselectedLabels ?? _defaultShowUnselected(_type(type, items)); |
|||
} |
|||
|
|||
public readonly List<BottomNavigationBarItem> items; |
|||
|
|||
public readonly ValueChanged<int> onTap; |
|||
|
|||
public readonly int currentIndex; |
|||
|
|||
public readonly float elevation; |
|||
|
|||
public readonly BottomNavigationBarType? type; |
|||
|
|||
public Color fixedColor { |
|||
get { return selectedItemColor; } |
|||
} |
|||
|
|||
public readonly Color backgroundColor; |
|||
|
|||
public readonly float iconSize; |
|||
|
|||
|
|||
public readonly Color selectedItemColor; |
|||
|
|||
public readonly Color unselectedItemColor; |
|||
|
|||
public readonly float selectedFontSize; |
|||
|
|||
public readonly float unselectedFontSize; |
|||
|
|||
public readonly bool showUnselectedLabels; |
|||
|
|||
public readonly bool showSelectedLabels; |
|||
|
|||
static BottomNavigationBarType _type( |
|||
BottomNavigationBarType? type, |
|||
List<BottomNavigationBarItem> items |
|||
) { |
|||
if (type != null) { |
|||
return type.Value; |
|||
} |
|||
|
|||
return items.Count <= 3 ? BottomNavigationBarType.fix : BottomNavigationBarType.shifting; |
|||
} |
|||
|
|||
static bool _defaultShowUnselected(BottomNavigationBarType type) { |
|||
switch (type) { |
|||
case BottomNavigationBarType.shifting: |
|||
return false; |
|||
case BottomNavigationBarType.fix: |
|||
return true; |
|||
} |
|||
|
|||
D.assert(false); |
|||
return false; |
|||
} |
|||
|
|||
public override State createState() { |
|||
return new _BottomNavigationBarState(); |
|||
} |
|||
} |
|||
|
|||
class _BottomNavigationTile : StatelessWidget { |
|||
public _BottomNavigationTile( |
|||
BottomNavigationBarType? type, |
|||
BottomNavigationBarItem item, |
|||
Animation<float> animation, |
|||
float? iconSize = null, |
|||
VoidCallback onTap = null, |
|||
ColorTween colorTween = null, |
|||
float? flex = null, |
|||
bool selected = false, |
|||
float? selectedFontSize = null, |
|||
float? unselectedFontSize = null, |
|||
bool? showSelectedLabels = null, |
|||
bool? showUnselectedLabels = null, |
|||
string indexLabel = null |
|||
) { |
|||
D.assert(type != null); |
|||
D.assert(item != null); |
|||
D.assert(animation != null); |
|||
D.assert(selectedFontSize != null && selectedFontSize >= 0); |
|||
D.assert(unselectedFontSize != null && unselectedFontSize >= 0); |
|||
this.type = type; |
|||
this.item = item; |
|||
this.animation = animation; |
|||
this.iconSize = iconSize; |
|||
this.onTap = onTap; |
|||
this.colorTween = colorTween; |
|||
this.flex = flex; |
|||
this.selected = selected; |
|||
this.selectedFontSize = selectedFontSize.Value; |
|||
this.unselectedFontSize = unselectedFontSize.Value; |
|||
this.showSelectedLabels = showSelectedLabels ?? false; |
|||
this.showUnselectedLabels = showUnselectedLabels ?? false; |
|||
this.indexLabel = indexLabel; |
|||
} |
|||
|
|||
public readonly BottomNavigationBarType? type; |
|||
public readonly BottomNavigationBarItem item; |
|||
public readonly Animation<float> animation; |
|||
public readonly float? iconSize; |
|||
public readonly VoidCallback onTap; |
|||
public readonly ColorTween colorTween; |
|||
public readonly float? flex; |
|||
public readonly bool selected; |
|||
public readonly float selectedFontSize; |
|||
public readonly float unselectedFontSize; |
|||
public readonly string indexLabel; |
|||
public readonly bool showSelectedLabels; |
|||
public readonly bool showUnselectedLabels; |
|||
|
|||
public override Widget build(BuildContext context) { |
|||
int size; |
|||
float bottomPadding = selectedFontSize / 2.0f; |
|||
float topPadding = selectedFontSize / 2.0f; |
|||
if (showSelectedLabels && !showUnselectedLabels) { |
|||
bottomPadding = new FloatTween( |
|||
begin: 0.0f, |
|||
end: selectedFontSize / 2.0f |
|||
).evaluate(animation); |
|||
topPadding = new FloatTween( |
|||
begin: selectedFontSize, |
|||
end: selectedFontSize / 2.0f |
|||
).evaluate(animation); |
|||
} |
|||
|
|||
if (!showSelectedLabels && !showUnselectedLabels) { |
|||
bottomPadding = 0.0f; |
|||
topPadding = selectedFontSize; |
|||
} |
|||
switch (type) { |
|||
case BottomNavigationBarType.fix: |
|||
size = 1; |
|||
break; |
|||
case BottomNavigationBarType.shifting: |
|||
size = ((flex * 1000.0f) ?? 0.0f).round(); |
|||
break; |
|||
default: |
|||
throw new Exception("Unknown BottomNavigationBarType: " + type); |
|||
} |
|||
|
|||
return new Expanded( |
|||
flex: size, |
|||
child: new Stack( |
|||
children: new List<Widget> { |
|||
new InkResponse( |
|||
onTap: onTap == null ? (GestureTapCallback) null : () => { onTap(); }, |
|||
child: new Padding( |
|||
padding: EdgeInsets.only(top: topPadding, bottom: bottomPadding), |
|||
child: new Column( |
|||
crossAxisAlignment: CrossAxisAlignment.center, |
|||
mainAxisAlignment: MainAxisAlignment.spaceBetween, |
|||
mainAxisSize: MainAxisSize.min, |
|||
children: new List<Widget> { |
|||
new _TileIcon( |
|||
colorTween: colorTween, |
|||
animation: animation, |
|||
iconSize: iconSize, |
|||
selected: selected, |
|||
item: item |
|||
), |
|||
new _Label( |
|||
colorTween: colorTween, |
|||
animation: animation, |
|||
item: item, |
|||
selectedFontSize: selectedFontSize, |
|||
unselectedFontSize: unselectedFontSize, |
|||
showSelectedLabels: showSelectedLabels, |
|||
showUnselectedLabels: showUnselectedLabels |
|||
) |
|||
} |
|||
) |
|||
) |
|||
) |
|||
} |
|||
) |
|||
); |
|||
} |
|||
} |
|||
|
|||
|
|||
class _TileIcon : StatelessWidget { |
|||
public _TileIcon( |
|||
Key key = null, |
|||
ColorTween colorTween = null, |
|||
Animation<float> animation = null, |
|||
float? iconSize = null, |
|||
bool? selected = null, |
|||
BottomNavigationBarItem item = null |
|||
) : base(key: key) { |
|||
D.assert(selected != null); |
|||
D.assert(item != null); |
|||
this.colorTween = colorTween; |
|||
this.animation = animation; |
|||
this.iconSize = iconSize; |
|||
this.selected = selected; |
|||
this.item = item; |
|||
} |
|||
|
|||
ColorTween colorTween; |
|||
Animation<float> animation; |
|||
float? iconSize; |
|||
bool? selected; |
|||
BottomNavigationBarItem item; |
|||
|
|||
public override Widget build(BuildContext context) { |
|||
Color iconColor = colorTween.evaluate(animation); |
|||
|
|||
return new Align( |
|||
alignment: Alignment.topCenter, |
|||
heightFactor: 1.0f, |
|||
child: new Container( |
|||
child: new IconTheme( |
|||
data: new IconThemeData( |
|||
color: iconColor, |
|||
size: iconSize |
|||
), |
|||
child: selected == true ? item.activeIcon : item.icon |
|||
) |
|||
) |
|||
); |
|||
} |
|||
} |
|||
|
|||
class _Label : StatelessWidget { |
|||
public _Label( |
|||
Key key = null, |
|||
ColorTween colorTween = null, |
|||
Animation<float> animation = null, |
|||
BottomNavigationBarItem item = null, |
|||
float? selectedFontSize = null, |
|||
float? unselectedFontSize = null, |
|||
bool? showSelectedLabels = null, |
|||
bool? showUnselectedLabels = null |
|||
) : base(key: key) { |
|||
D.assert(colorTween != null); |
|||
D.assert(animation != null); |
|||
D.assert(item != null); |
|||
D.assert(selectedFontSize != null); |
|||
D.assert(unselectedFontSize != null); |
|||
D.assert(showSelectedLabels != null); |
|||
D.assert(showUnselectedLabels != null); |
|||
this.colorTween = colorTween; |
|||
this.animation = animation; |
|||
this.item = item; |
|||
this.selectedFontSize = selectedFontSize.Value; |
|||
this.unselectedFontSize = unselectedFontSize.Value; |
|||
this.showSelectedLabels = showSelectedLabels.Value; |
|||
this.showUnselectedLabels = showUnselectedLabels.Value; |
|||
} |
|||
|
|||
public readonly ColorTween colorTween; |
|||
public readonly Animation<float> animation; |
|||
public readonly BottomNavigationBarItem item; |
|||
public readonly float selectedFontSize; |
|||
public readonly float unselectedFontSize; |
|||
public readonly bool showSelectedLabels; |
|||
public readonly bool showUnselectedLabels; |
|||
|
|||
public override Widget build(BuildContext context) { |
|||
float t = new FloatTween(begin: unselectedFontSize / selectedFontSize, end: 1.0f) |
|||
.evaluate(animation); |
|||
Widget text = DefaultTextStyle.merge( |
|||
style: new TextStyle( |
|||
fontSize: selectedFontSize, |
|||
color: colorTween.evaluate(animation) |
|||
), |
|||
child: new Transform( |
|||
transform: new Matrix4().diagonal3Values(t, t, t), |
|||
alignment: Alignment.bottomCenter, |
|||
child: item.title |
|||
) |
|||
); |
|||
if (!showUnselectedLabels && !showSelectedLabels) { |
|||
text = new Opacity( |
|||
opacity: 0.0f, |
|||
child: text |
|||
); |
|||
} |
|||
else if (!showUnselectedLabels) { |
|||
text = new FadeTransition( |
|||
opacity: animation, |
|||
child: text |
|||
); |
|||
} |
|||
else if (!showSelectedLabels) { |
|||
text = new FadeTransition( |
|||
opacity: new FloatTween(begin: 1.0f, end: 0.0f).animate(animation), |
|||
child: text |
|||
); |
|||
} |
|||
return new Align( |
|||
alignment: Alignment.bottomCenter, |
|||
heightFactor: 1.0f, |
|||
child: new Container(child: text) |
|||
); |
|||
} |
|||
} |
|||
|
|||
class _BottomNavigationBarState : TickerProviderStateMixin<BottomNavigationBar> { |
|||
public List<AnimationController> _controllers = new List<AnimationController> { }; |
|||
public List<CurvedAnimation> _animations; |
|||
|
|||
Queue<_Circle> _circles = new Queue<_Circle>(); |
|||
|
|||
Color _backgroundColor; |
|||
|
|||
static readonly Animatable<float> _flexTween = new FloatTween(begin: 1.0f, end: 1.5f); |
|||
|
|||
public _BottomNavigationBarState() { |
|||
} |
|||
|
|||
void _resetState() { |
|||
foreach (AnimationController controller in _controllers) { |
|||
controller.dispose(); |
|||
} |
|||
|
|||
foreach (_Circle circle in _circles) { |
|||
circle.dispose(); |
|||
} |
|||
|
|||
_circles.Clear(); |
|||
|
|||
_controllers = new List<AnimationController>(capacity: widget.items.Count); |
|||
for (int index = 0; index < widget.items.Count; index++) { |
|||
AnimationController controller = new AnimationController( |
|||
duration: ThemeUtils.kThemeAnimationDuration, |
|||
vsync: this |
|||
); |
|||
controller.addListener(_rebuild); |
|||
_controllers.Add(controller); |
|||
} |
|||
|
|||
_animations = new List<CurvedAnimation>(capacity: widget.items.Count); |
|||
for (int index = 0; index < widget.items.Count; index++) { |
|||
_animations.Add(new CurvedAnimation( |
|||
parent: _controllers[index], |
|||
curve: Curves.fastOutSlowIn, |
|||
reverseCurve: Curves.fastOutSlowIn.flipped |
|||
)); |
|||
} |
|||
|
|||
_controllers[widget.currentIndex].setValue(1.0f); |
|||
_backgroundColor = widget.items[widget.currentIndex].backgroundColor; |
|||
} |
|||
|
|||
public override void initState() { |
|||
base.initState(); |
|||
_resetState(); |
|||
} |
|||
|
|||
void _rebuild() { |
|||
setState(() => { }); |
|||
} |
|||
|
|||
public override void dispose() { |
|||
foreach (AnimationController controller in _controllers) { |
|||
controller.dispose(); |
|||
} |
|||
|
|||
foreach (_Circle circle in _circles) { |
|||
circle.dispose(); |
|||
} |
|||
|
|||
base.dispose(); |
|||
} |
|||
|
|||
public float _evaluateFlex(Animation<float> animation) { |
|||
return _flexTween.evaluate(animation); |
|||
} |
|||
|
|||
void _pushCircle(int index) { |
|||
if (widget.items[index].backgroundColor != null) { |
|||
_Circle circle = new _Circle( |
|||
state: this, |
|||
index: index, |
|||
color: widget.items[index].backgroundColor, |
|||
vsync: this |
|||
); |
|||
circle.controller.addStatusListener( |
|||
(AnimationStatus status) => { |
|||
switch (status) { |
|||
case AnimationStatus.completed: |
|||
setState(() => { |
|||
_Circle cir = _circles.Dequeue(); |
|||
_backgroundColor = cir.color; |
|||
cir.dispose(); |
|||
}); |
|||
break; |
|||
case AnimationStatus.dismissed: |
|||
case AnimationStatus.forward: |
|||
case AnimationStatus.reverse: |
|||
break; |
|||
} |
|||
} |
|||
); |
|||
_circles.Enqueue(circle); |
|||
} |
|||
} |
|||
|
|||
public override void didUpdateWidget(StatefulWidget _oldWidget) { |
|||
base.didUpdateWidget(_oldWidget); |
|||
BottomNavigationBar oldWidget = _oldWidget as BottomNavigationBar; |
|||
if (widget.items.Count != oldWidget.items.Count) { |
|||
_resetState(); |
|||
return; |
|||
} |
|||
|
|||
if (widget.currentIndex != oldWidget.currentIndex) { |
|||
switch (widget.type) { |
|||
case BottomNavigationBarType.fix: |
|||
break; |
|||
case BottomNavigationBarType.shifting: |
|||
_pushCircle(widget.currentIndex); |
|||
break; |
|||
} |
|||
|
|||
_controllers[oldWidget.currentIndex].reverse(); |
|||
_controllers[widget.currentIndex].forward(); |
|||
} |
|||
else { |
|||
if (_backgroundColor != widget.items[widget.currentIndex].backgroundColor) { |
|||
_backgroundColor = widget.items[widget.currentIndex].backgroundColor; |
|||
} |
|||
} |
|||
} |
|||
|
|||
List<Widget> _createTiles() { |
|||
MaterialLocalizations localizations = MaterialLocalizations.of(context); |
|||
D.assert(localizations != null); |
|||
ThemeData themeData = Theme.of(context); |
|||
Color themeColor; |
|||
switch (themeData.brightness) { |
|||
case Brightness.light: |
|||
themeColor = themeData.primaryColor; |
|||
break; |
|||
case Brightness.dark: |
|||
themeColor = themeData.accentColor; |
|||
break; |
|||
default: |
|||
throw new Exception("Unknown brightness: " + themeData.brightness); |
|||
} |
|||
|
|||
ColorTween colorTween; |
|||
switch (widget.type) { |
|||
case BottomNavigationBarType.fix: |
|||
colorTween = new ColorTween( |
|||
begin: widget.unselectedItemColor ?? themeData.textTheme.caption.color, |
|||
end: widget.selectedItemColor ?? widget.fixedColor ?? themeColor |
|||
); |
|||
break; |
|||
case BottomNavigationBarType.shifting: |
|||
colorTween = new ColorTween( |
|||
begin: widget.unselectedItemColor ?? Colors.white, |
|||
end: widget.selectedItemColor ?? Colors.white |
|||
); |
|||
break; |
|||
default: |
|||
throw new UIWidgetsError($"Unknown bottom navigation bar type: {widget.type}"); |
|||
} |
|||
|
|||
List<Widget> tiles = new List<Widget>(); |
|||
for (int i = 0; i < widget.items.Count; i++) { |
|||
int index = i; |
|||
tiles.Add(new _BottomNavigationTile( |
|||
widget.type, |
|||
widget.items[i], |
|||
_animations[i], |
|||
widget.iconSize, |
|||
selectedFontSize: widget.selectedFontSize, |
|||
unselectedFontSize: widget.unselectedFontSize, |
|||
onTap: () => { |
|||
if (widget.onTap != null) { |
|||
widget.onTap(index); |
|||
} |
|||
}, |
|||
colorTween: colorTween, |
|||
flex: _evaluateFlex(_animations[i]), |
|||
selected: i == widget.currentIndex, |
|||
showSelectedLabels: widget.showSelectedLabels, |
|||
showUnselectedLabels: widget.showUnselectedLabels, |
|||
indexLabel: localizations.tabLabel(tabIndex: i+1, tabCount: widget.items.Count) |
|||
)); |
|||
} |
|||
|
|||
return tiles; |
|||
} |
|||
|
|||
Widget _createContainer(List<Widget> tiles) { |
|||
return DefaultTextStyle.merge( |
|||
overflow: TextOverflow.ellipsis, |
|||
child: new Row( |
|||
mainAxisAlignment: MainAxisAlignment.spaceBetween, |
|||
children: tiles |
|||
) |
|||
); |
|||
} |
|||
|
|||
public override Widget build(BuildContext context) { |
|||
D.assert(WidgetsD.debugCheckHasDirectionality(context)); |
|||
D.assert(MaterialD.debugCheckHasMaterialLocalizations(context)); |
|||
|
|||
float additionalBottomPadding = |
|||
Mathf.Max(MediaQuery.of(context).padding.bottom - widget.selectedFontSize / 2.0f, 0.0f); |
|||
Color backgroundColor = null; |
|||
switch (widget.type) { |
|||
case BottomNavigationBarType.fix: |
|||
backgroundColor = widget.backgroundColor; |
|||
break; |
|||
case BottomNavigationBarType.shifting: |
|||
backgroundColor = _backgroundColor; |
|||
break; |
|||
} |
|||
|
|||
|
|||
return new Material( |
|||
elevation: widget.elevation, |
|||
color: backgroundColor, |
|||
child: new ConstrainedBox( |
|||
constraints: new BoxConstraints( |
|||
minHeight: Constants.kBottomNavigationBarHeight + additionalBottomPadding), |
|||
child: new CustomPaint( |
|||
painter: new _RadialPainter( |
|||
circles: _circles.ToList() |
|||
), |
|||
child: new Material( // Splashes.
|
|||
type: MaterialType.transparency, |
|||
child: new Padding( |
|||
padding: EdgeInsets.only(bottom: additionalBottomPadding), |
|||
child: MediaQuery.removePadding( |
|||
context: context, |
|||
removeBottom: true, |
|||
child: _createContainer(_createTiles()) |
|||
) |
|||
) |
|||
) |
|||
) |
|||
) |
|||
); |
|||
} |
|||
} |
|||
|
|||
class _Circle { |
|||
public _Circle( |
|||
_BottomNavigationBarState state = null, |
|||
int? index = null, |
|||
Color color = null, |
|||
TickerProvider vsync = null |
|||
) { |
|||
D.assert(state != null); |
|||
D.assert(index != null); |
|||
D.assert(color != null); |
|||
this.state = state; |
|||
this.index = index; |
|||
this.color = color; |
|||
controller = new AnimationController( |
|||
duration: ThemeUtils.kThemeAnimationDuration, |
|||
vsync: vsync |
|||
); |
|||
animation = new CurvedAnimation( |
|||
parent: controller, |
|||
curve: Curves.fastOutSlowIn |
|||
); |
|||
controller.forward(); |
|||
} |
|||
|
|||
public readonly _BottomNavigationBarState state; |
|||
public readonly int? index; |
|||
public readonly Color color; |
|||
public readonly AnimationController controller; |
|||
public readonly CurvedAnimation animation; |
|||
|
|||
public float horizontalLeadingOffset { |
|||
get { |
|||
float weightSum(IEnumerable<Animation<float>> animations) { |
|||
return animations.Select(state._evaluateFlex).Sum(); |
|||
} |
|||
|
|||
float allWeights = weightSum(state._animations); |
|||
float leadingWeights = weightSum(state._animations.GetRange(0, index ?? 0)); |
|||
|
|||
return (leadingWeights + state._evaluateFlex(state._animations[index ?? 0]) / 2.0f) / |
|||
allWeights; |
|||
} |
|||
} |
|||
|
|||
public void dispose() { |
|||
controller.dispose(); |
|||
} |
|||
} |
|||
|
|||
class _RadialPainter : AbstractCustomPainter { |
|||
public _RadialPainter( |
|||
List<_Circle> circles |
|||
) { |
|||
D.assert(circles != null); |
|||
this.circles = circles; |
|||
} |
|||
|
|||
public readonly List<_Circle> circles; |
|||
|
|||
static float _maxRadius(Offset center, Size size) { |
|||
float maxX = Mathf.Max(center.dx, size.width - center.dx); |
|||
float maxY = Mathf.Max(center.dy, size.height - center.dy); |
|||
return Mathf.Sqrt(maxX * maxX + maxY * maxY); |
|||
} |
|||
|
|||
public override bool shouldRepaint(CustomPainter _oldPainter) { |
|||
_RadialPainter oldPainter = _oldPainter as _RadialPainter; |
|||
if (circles == oldPainter.circles) { |
|||
return false; |
|||
} |
|||
|
|||
if (circles.Count != oldPainter.circles.Count) { |
|||
return true; |
|||
} |
|||
|
|||
for (int i = 0; i < circles.Count; i += 1) { |
|||
if (circles[i] != oldPainter.circles[i]) { |
|||
return true; |
|||
} |
|||
} |
|||
|
|||
return false; |
|||
} |
|||
|
|||
public override void paint(Canvas canvas, Size size) { |
|||
foreach (_Circle circle in circles) { |
|||
Paint paint = new Paint(); |
|||
paint.color = circle.color; |
|||
Rect rect = Rect.fromLTWH(0.0f, 0.0f, size.width, size.height); |
|||
canvas.clipRect(rect); |
|||
float leftFraction = circle.horizontalLeadingOffset; |
|||
Offset center = new Offset(leftFraction * size.width, size.height / 2.0f); |
|||
FloatTween radiusTween = new FloatTween( |
|||
begin: 0.0f, |
|||
end: _maxRadius(center, size) |
|||
); |
|||
canvas.drawCircle( |
|||
center, |
|||
radiusTween.evaluate(circle.animation), |
|||
paint |
|||
); |
|||
} |
|||
} |
|||
} |
|||
} |
|
|||
fileFormatVersion: 2 |
|||
guid: 6b8f793d1b8d4004b2c19c1c085752c3 |
|||
timeCreated: 1553161698 |
|
|||
using System; |
|||
using RSG; |
|||
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 { |
|||
public 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 static IPromise<object> showModalBottomSheet<T>( |
|||
BuildContext context, |
|||
WidgetBuilder builder |
|||
) { |
|||
D.assert(context != null); |
|||
D.assert(builder != null); |
|||
D.assert(MaterialD.debugCheckHasMaterialLocalizations(context)); |
|||
return Navigator.push(context, new _ModalBottomSheetRoute<T>( |
|||
builder: builder, |
|||
theme: Theme.of(context, shadowThemeOnly: true), |
|||
barrierLabel: MaterialLocalizations.of(context).modalBarrierDismissLabel |
|||
)); |
|||
} |
|||
|
|||
public static PersistentBottomSheetController<object> showBottomSheet( |
|||
BuildContext context, |
|||
WidgetBuilder builder |
|||
) { |
|||
D.assert(context != null); |
|||
D.assert(builder != null); |
|||
return Scaffold.of(context).showBottomSheet(builder); |
|||
} |
|||
} |
|||
|
|||
|
|||
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); |
|||
D.assert(elevation >= 0.0f); |
|||
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) _childKey.currentContext.findRenderObject(); |
|||
return renderBox.size.height; |
|||
} |
|||
} |
|||
|
|||
bool _dismissUnderway { |
|||
get { return widget.animationController.status == AnimationStatus.reverse; } |
|||
} |
|||
|
|||
void _handleDragUpdate(DragUpdateDetails details) { |
|||
if (_dismissUnderway) { |
|||
return; |
|||
} |
|||
|
|||
widget.animationController.setValue( |
|||
widget.animationController.value - |
|||
details.primaryDelta.Value / (_childHeight ?? details.primaryDelta.Value)); |
|||
} |
|||
|
|||
void _handleDragEnd(DragEndDetails details) { |
|||
if (_dismissUnderway) { |
|||
return; |
|||
} |
|||
|
|||
if (details.velocity.pixelsPerSecond.dy > BottomSheetUtils._kMinFlingVelocity) { |
|||
float flingVelocity = -details.velocity.pixelsPerSecond.dy / _childHeight.Value; |
|||
if (widget.animationController.value > 0.0f) { |
|||
widget.animationController.fling(velocity: flingVelocity); |
|||
} |
|||
|
|||
if (flingVelocity < 0.0f) { |
|||
widget.onClosing(); |
|||
} |
|||
} |
|||
else if (widget.animationController.value < BottomSheetUtils._kCloseProgressThreshold) { |
|||
if (widget.animationController.value > 0.0f) { |
|||
widget.animationController.fling(velocity: -1.0f); |
|||
} |
|||
|
|||
widget.onClosing(); |
|||
} |
|||
else { |
|||
widget.animationController.forward(); |
|||
} |
|||
} |
|||
|
|||
public override Widget build(BuildContext context) { |
|||
Widget bottomSheet = new Material( |
|||
key: _childKey, |
|||
elevation: widget.elevation, |
|||
child: widget.builder(context) |
|||
); |
|||
|
|||
return !widget.enableDrag |
|||
? bottomSheet |
|||
: new GestureDetector( |
|||
onVerticalDragUpdate: _handleDragUpdate, |
|||
onVerticalDragEnd: _handleDragEnd, |
|||
child: bottomSheet |
|||
); |
|||
} |
|||
} |
|||
|
|||
class _ModalBottomSheetLayout : SingleChildLayoutDelegate { |
|||
public _ModalBottomSheetLayout(float progress) { |
|||
this.progress = progress; |
|||
} |
|||
|
|||
|
|||
public readonly float progress; |
|||
|
|||
public override BoxConstraints getConstraintsForChild(BoxConstraints constraints) { |
|||
return new BoxConstraints( |
|||
minWidth: constraints.maxWidth, |
|||
maxWidth: constraints.maxWidth, |
|||
minHeight: 0.0f, |
|||
maxHeight: constraints.maxHeight * 9.0f / 16.0f |
|||
); |
|||
} |
|||
|
|||
public override Offset getPositionForChild(Size size, Size childSize) { |
|||
return new Offset(0.0f, size.height - childSize.height * progress); |
|||
} |
|||
|
|||
public override bool shouldRelayout(SingleChildLayoutDelegate _oldDelegate) { |
|||
_ModalBottomSheetLayout oldDelegate = _oldDelegate as _ModalBottomSheetLayout; |
|||
return progress != oldDelegate.progress; |
|||
} |
|||
} |
|||
|
|||
class _ModalBottomSheet<T> : StatefulWidget { |
|||
public _ModalBottomSheet(Key key = null, _ModalBottomSheetRoute<T> route = null) : base(key: key) { |
|||
this.route = route; |
|||
} |
|||
|
|||
public readonly _ModalBottomSheetRoute<T> route; |
|||
|
|||
public override State createState() { |
|||
return new _ModalBottomSheetState<T>(); |
|||
} |
|||
} |
|||
|
|||
class _ModalBottomSheetState<T> : State<_ModalBottomSheet<T>> { |
|||
public override Widget build(BuildContext context) { |
|||
MediaQueryData mediaQuery = MediaQuery.of(context); |
|||
MaterialLocalizations localizations = MaterialLocalizations.of(context); |
|||
|
|||
return new GestureDetector( |
|||
onTap: () => Navigator.pop(context), |
|||
child: new AnimatedBuilder( |
|||
animation: widget.route.animation, |
|||
builder: (BuildContext _context, Widget child) => { |
|||
float animationValue = |
|||
mediaQuery.accessibleNavigation ? 1.0f : widget.route.animation.value; |
|||
return new ClipRect( |
|||
child: new CustomSingleChildLayout( |
|||
layoutDelegate: new _ModalBottomSheetLayout(animationValue), |
|||
child: new BottomSheet( |
|||
animationController: widget.route._animationController, |
|||
onClosing: () => Navigator.pop(_context), |
|||
builder: widget.route.builder |
|||
) |
|||
) |
|||
); |
|||
} |
|||
) |
|||
); |
|||
} |
|||
} |
|||
|
|||
class _ModalBottomSheetRoute<T> : PopupRoute { |
|||
public _ModalBottomSheetRoute( |
|||
WidgetBuilder builder = null, |
|||
ThemeData theme = null, |
|||
string barrierLabel = null, |
|||
RouteSettings settings = null |
|||
) : base(settings: settings) { |
|||
this.builder = builder; |
|||
this.theme = theme; |
|||
this.barrierLabel = barrierLabel; |
|||
} |
|||
|
|||
public readonly WidgetBuilder builder; |
|||
public readonly ThemeData theme; |
|||
|
|||
public override TimeSpan transitionDuration { |
|||
get { return BottomSheetUtils._kBottomSheetDuration; } |
|||
} |
|||
|
|||
public override bool barrierDismissible { |
|||
get { return true; } |
|||
} |
|||
|
|||
public readonly string barrierLabel; |
|||
|
|||
public override Color barrierColor { |
|||
get { return Colors.black54; } |
|||
} |
|||
|
|||
public AnimationController _animationController; |
|||
|
|||
public override AnimationController createAnimationController() { |
|||
D.assert(_animationController == null); |
|||
_animationController = BottomSheet.createAnimationController(navigator.overlay); |
|||
return _animationController; |
|||
} |
|||
|
|||
public override Widget buildPage(BuildContext context, Animation<float> animation, |
|||
Animation<float> secondaryAnimation) { |
|||
Widget bottomSheet = MediaQuery.removePadding( |
|||
context: context, |
|||
removeTop: true, |
|||
child: new _ModalBottomSheet<T>(route: this) |
|||
); |
|||
if (theme != null) { |
|||
bottomSheet = new Theme(data: theme, child: bottomSheet); |
|||
} |
|||
|
|||
return bottomSheet; |
|||
} |
|||
} |
|||
} |
|
|||
fileFormatVersion: 2 |
|||
guid: 5219593daa853417ebb5f7835c74a969 |
|||
MonoImporter: |
|||
externalObjects: {} |
|||
serializedVersion: 2 |
|||
defaultReferences: [] |
|||
executionOrder: 0 |
|||
icon: {instanceID: 0} |
|||
userData: |
|||
assetBundleName: |
|||
assetBundleVariant: |
|
|||
using System; |
|||
using Unity.UIWidgets.foundation; |
|||
using Unity.UIWidgets.gestures; |
|||
using Unity.UIWidgets.painting; |
|||
using Unity.UIWidgets.rendering; |
|||
using Unity.UIWidgets.ui; |
|||
using Unity.UIWidgets.widgets; |
|||
using TextStyle = Unity.UIWidgets.painting.TextStyle; |
|||
|
|||
namespace Unity.UIWidgets.material { |
|||
public class RawMaterialButton : StatefulWidget { |
|||
public RawMaterialButton( |
|||
Key key = null, |
|||
VoidCallback onPressed = null, |
|||
ValueChanged<bool> onHighlightChanged = null, |
|||
TextStyle textStyle = null, |
|||
Color fillColor = null, |
|||
Color highlightColor = null, |
|||
Color splashColor = null, |
|||
float elevation = 2.0f, |
|||
float highlightElevation = 8.0f, |
|||
float disabledElevation = 0.0f, |
|||
EdgeInsets padding = null, |
|||
BoxConstraints constraints = null, |
|||
ShapeBorder shape = null, |
|||
TimeSpan? animationDuration = null, |
|||
Clip clipBehavior = Clip.none, |
|||
MaterialTapTargetSize? materialTapTargetSize = null, |
|||
Widget child = null) : base(key: key) { |
|||
D.assert(elevation >= 0.0); |
|||
D.assert(highlightElevation >= 0.0); |
|||
D.assert(disabledElevation >= 0.0); |
|||
|
|||
MaterialTapTargetSize _materialTapTargetSize = materialTapTargetSize ?? MaterialTapTargetSize.padded; |
|||
shape = shape ?? new RoundedRectangleBorder(); |
|||
padding = padding ?? EdgeInsets.zero; |
|||
constraints = constraints ?? new BoxConstraints(minWidth: 88.0f, minHeight: 36.0f); |
|||
TimeSpan _animationDuration = animationDuration ?? Constants.kThemeChangeDuration; |
|||
|
|||
this.onPressed = onPressed; |
|||
this.onHighlightChanged = onHighlightChanged; |
|||
this.textStyle = textStyle; |
|||
this.fillColor = fillColor; |
|||
this.highlightColor = highlightColor; |
|||
this.splashColor = splashColor; |
|||
this.elevation = elevation; |
|||
this.highlightElevation = highlightElevation; |
|||
this.disabledElevation = disabledElevation; |
|||
this.padding = padding; |
|||
this.constraints = constraints; |
|||
this.shape = shape; |
|||
this.animationDuration = _animationDuration; |
|||
this.clipBehavior = clipBehavior; |
|||
this.materialTapTargetSize = _materialTapTargetSize; |
|||
this.child = child; |
|||
} |
|||
|
|||
public readonly VoidCallback onPressed; |
|||
|
|||
public readonly ValueChanged<bool> onHighlightChanged; |
|||
|
|||
public readonly TextStyle textStyle; |
|||
|
|||
public readonly Color fillColor; |
|||
|
|||
public readonly Color highlightColor; |
|||
|
|||
public readonly Color splashColor; |
|||
|
|||
public readonly float elevation; |
|||
|
|||
public readonly float highlightElevation; |
|||
|
|||
public readonly float disabledElevation; |
|||
|
|||
public readonly EdgeInsets padding; |
|||
|
|||
public readonly BoxConstraints constraints; |
|||
|
|||
public readonly ShapeBorder shape; |
|||
|
|||
public readonly TimeSpan animationDuration; |
|||
|
|||
public readonly Widget child; |
|||
|
|||
public bool enabled { |
|||
get { return onPressed != null; } |
|||
} |
|||
|
|||
public readonly MaterialTapTargetSize materialTapTargetSize; |
|||
|
|||
public readonly Clip clipBehavior; |
|||
|
|||
public override State createState() { |
|||
return new _RawMaterialButtonState(); |
|||
} |
|||
} |
|||
|
|||
|
|||
class _RawMaterialButtonState : State<RawMaterialButton> { |
|||
bool _highlight = false; |
|||
|
|||
void _handleHighlightChanged(bool value) { |
|||
if (_highlight != value) { |
|||
setState(() => { |
|||
_highlight = value; |
|||
if (widget.onHighlightChanged != null) { |
|||
widget.onHighlightChanged(value); |
|||
} |
|||
}); |
|||
} |
|||
} |
|||
|
|||
public override void didUpdateWidget(StatefulWidget _oldWidget) { |
|||
RawMaterialButton oldWidget = _oldWidget as RawMaterialButton; |
|||
base.didUpdateWidget(oldWidget); |
|||
if (_highlight && !widget.enabled) { |
|||
_highlight = false; |
|||
if (widget.onHighlightChanged != null) { |
|||
widget.onHighlightChanged(false); |
|||
} |
|||
} |
|||
} |
|||
|
|||
public override Widget build(BuildContext context) { |
|||
float elevation = widget.enabled |
|||
? (_highlight ? widget.highlightElevation : widget.elevation) |
|||
: widget.disabledElevation; |
|||
|
|||
Widget result = new ConstrainedBox( |
|||
constraints: widget.constraints, |
|||
child: new Material( |
|||
elevation: elevation, |
|||
textStyle: widget.textStyle, |
|||
shape: widget.shape, |
|||
color: widget.fillColor, |
|||
type: widget.fillColor == null ? MaterialType.transparency : MaterialType.button, |
|||
animationDuration: widget.animationDuration, |
|||
clipBehavior: widget.clipBehavior, |
|||
child: new InkWell( |
|||
onHighlightChanged: _handleHighlightChanged, |
|||
splashColor: widget.splashColor, |
|||
highlightColor: widget.highlightColor, |
|||
onTap: widget.onPressed == null |
|||
? (GestureTapCallback) null |
|||
: () => { |
|||
if (widget.onPressed != null) { |
|||
widget.onPressed(); |
|||
} |
|||
}, |
|||
customBorder: widget.shape, |
|||
child: IconTheme.merge( |
|||
data: new IconThemeData(color: widget.textStyle?.color), |
|||
child: new Container( |
|||
padding: widget.padding, |
|||
child: new Center( |
|||
widthFactor: 1.0f, |
|||
heightFactor: 1.0f, |
|||
child: widget.child) |
|||
) |
|||
) |
|||
) |
|||
) |
|||
); |
|||
|
|||
return result; |
|||
} |
|||
} |
|||
} |
|
|||
fileFormatVersion: 2 |
|||
guid: 5452e0dd1a19646fda9cc8dc0b388ee4 |
|||
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.widgets; |
|||
|
|||
namespace Unity.UIWidgets.material { |
|||
public class ButtonBar : StatelessWidget { |
|||
public ButtonBar( |
|||
Key key = null, |
|||
MainAxisAlignment alignment = MainAxisAlignment.end, |
|||
MainAxisSize mainAxisSize = MainAxisSize.max, |
|||
List<Widget> children = null |
|||
) : base(key: key) { |
|||
this.alignment = alignment; |
|||
this.mainAxisSize = mainAxisSize; |
|||
this.children = children ?? new List<Widget>(); |
|||
} |
|||
|
|||
public readonly MainAxisAlignment alignment; |
|||
|
|||
public readonly MainAxisSize mainAxisSize; |
|||
|
|||
public readonly List<Widget> children; |
|||
|
|||
|
|||
public override Widget build(BuildContext context) { |
|||
ButtonThemeData buttonTheme = ButtonTheme.of(context); |
|||
float paddingUnit = buttonTheme.padding.horizontal / 4.0f; |
|||
List<Widget> _children = new List<Widget>(); |
|||
foreach (Widget _child in children) { |
|||
_children.Add( |
|||
new Padding( |
|||
padding: EdgeInsets.symmetric(horizontal: paddingUnit), |
|||
child: _child |
|||
) |
|||
); |
|||
} |
|||
|
|||
Widget child = new Row( |
|||
mainAxisAlignment: alignment, |
|||
mainAxisSize: mainAxisSize, |
|||
children: _children |
|||
); |
|||
|
|||
switch (buttonTheme.layoutBehavior) { |
|||
case ButtonBarLayoutBehavior.padded: |
|||
return new Padding( |
|||
padding: EdgeInsets.symmetric( |
|||
vertical: 2.0f * paddingUnit, |
|||
horizontal: paddingUnit |
|||
), |
|||
child: child |
|||
); |
|||
case ButtonBarLayoutBehavior.constrained: |
|||
return new Container( |
|||
padding: EdgeInsets.symmetric(horizontal: paddingUnit), |
|||
constraints: new BoxConstraints(minHeight: 52.0f), |
|||
alignment: Alignment.center, |
|||
child: child |
|||
); |
|||
} |
|||
|
|||
D.assert(false); |
|||
return null; |
|||
} |
|||
} |
|||
} |
|
|||
fileFormatVersion: 2 |
|||
guid: 2658772190aaa4fa79836ff61595171d |
|||
MonoImporter: |
|||
externalObjects: {} |
|||
serializedVersion: 2 |
|||
defaultReferences: [] |
|||
executionOrder: 0 |
|||
icon: {instanceID: 0} |
|||
userData: |
|||
assetBundleName: |
|||
assetBundleVariant: |
|
|||
using System; |
|||
using Unity.UIWidgets.foundation; |
|||
using Unity.UIWidgets.painting; |
|||
using Unity.UIWidgets.rendering; |
|||
using Unity.UIWidgets.service; |
|||
using Unity.UIWidgets.ui; |
|||
using Unity.UIWidgets.widgets; |
|||
|
|||
namespace Unity.UIWidgets.material { |
|||
public enum ButtonTextTheme { |
|||
normal, |
|||
|
|||
accent, |
|||
|
|||
primary |
|||
} |
|||
|
|||
public enum ButtonBarLayoutBehavior { |
|||
constrained, |
|||
|
|||
padded |
|||
} |
|||
|
|||
public class ButtonTheme : InheritedWidget { |
|||
public ButtonTheme( |
|||
Key key = null, |
|||
ButtonTextTheme textTheme = ButtonTextTheme.normal, |
|||
ButtonBarLayoutBehavior layoutBehavior = ButtonBarLayoutBehavior.padded, |
|||
float minWidth = 88.0f, |
|||
float height = 36.0f, |
|||
EdgeInsets padding = null, |
|||
ShapeBorder shape = null, |
|||
bool alignedDropdown = false, |
|||
Color buttonColor = null, |
|||
Color disabledColor = null, |
|||
Color highlightColor = null, |
|||
Color splashColor = null, |
|||
ColorScheme colorScheme = null, |
|||
MaterialTapTargetSize? materialTapTargetSize = null, |
|||
Widget child = null) : base(key: key, child: child) { |
|||
D.assert(minWidth >= 0.0); |
|||
D.assert(height >= 0.0); |
|||
data = new ButtonThemeData( |
|||
textTheme: textTheme, |
|||
minWidth: minWidth, |
|||
height: height, |
|||
padding: padding, |
|||
shape: shape, |
|||
alignedDropdown: alignedDropdown, |
|||
layoutBehavior: layoutBehavior, |
|||
buttonColor: buttonColor, |
|||
disabledColor: disabledColor, |
|||
highlightColor: highlightColor, |
|||
splashColor: splashColor, |
|||
colorScheme: colorScheme, |
|||
materialTapTargetSize: materialTapTargetSize); |
|||
} |
|||
|
|||
public ButtonTheme( |
|||
Key key = null, |
|||
ButtonThemeData data = null, |
|||
Widget child = null) : base(key: key, child: child) { |
|||
D.assert(data != null); |
|||
this.data = data; |
|||
} |
|||
|
|||
public static ButtonTheme fromButtonThemeData( |
|||
Key key = null, |
|||
ButtonThemeData data = null, |
|||
Widget child = null) { |
|||
return new ButtonTheme(key, data, child); |
|||
} |
|||
|
|||
public static ButtonTheme bar( |
|||
Key key = null, |
|||
ButtonTextTheme textTheme = ButtonTextTheme.accent, |
|||
float minWidth = 64.0f, |
|||
float height = 36.0f, |
|||
EdgeInsets padding = null, |
|||
ShapeBorder shape = null, |
|||
bool alignedDropdown = false, |
|||
Color buttonColor = null, |
|||
Color disabledColor = null, |
|||
Color highlightColor = null, |
|||
Color splashColor = null, |
|||
ColorScheme colorScheme = null, |
|||
Widget child = null, |
|||
ButtonBarLayoutBehavior layoutBehavior = ButtonBarLayoutBehavior.padded |
|||
) { |
|||
D.assert(minWidth >= 0.0); |
|||
D.assert(height >= 0.0); |
|||
return new ButtonTheme(key, new ButtonThemeData( |
|||
textTheme: textTheme, |
|||
minWidth: minWidth, |
|||
height: height, |
|||
padding: padding ?? EdgeInsets.symmetric(horizontal: 8.0f), |
|||
shape: shape, |
|||
alignedDropdown: alignedDropdown, |
|||
layoutBehavior: layoutBehavior, |
|||
buttonColor: buttonColor, |
|||
disabledColor: disabledColor, |
|||
highlightColor: highlightColor, |
|||
splashColor: splashColor, |
|||
colorScheme: colorScheme |
|||
), child); |
|||
} |
|||
|
|||
|
|||
public readonly ButtonThemeData data; |
|||
|
|||
public static ButtonThemeData of(BuildContext context) { |
|||
ButtonTheme inheritedButtonTheme = (ButtonTheme) context.inheritFromWidgetOfExactType(typeof(ButtonTheme)); |
|||
ButtonThemeData buttonTheme = inheritedButtonTheme?.data; |
|||
if (buttonTheme?.colorScheme == null) { |
|||
ThemeData theme = Theme.of(context); |
|||
buttonTheme = buttonTheme ?? theme.buttonTheme; |
|||
if (buttonTheme.colorScheme == null) { |
|||
buttonTheme = buttonTheme.copyWith( |
|||
colorScheme: theme.buttonTheme.colorScheme ?? theme.colorScheme); |
|||
D.assert(buttonTheme.colorScheme != null); |
|||
} |
|||
} |
|||
|
|||
return buttonTheme; |
|||
} |
|||
|
|||
public override bool updateShouldNotify(InheritedWidget oldWidget) { |
|||
return data != ((ButtonTheme) oldWidget).data; |
|||
} |
|||
} |
|||
|
|||
|
|||
public class ButtonThemeData : Diagnosticable, IEquatable<ButtonThemeData> { |
|||
public ButtonThemeData( |
|||
ButtonTextTheme textTheme = ButtonTextTheme.normal, |
|||
float minWidth = 88.0f, |
|||
float height = 36.0f, |
|||
EdgeInsets padding = null, |
|||
ShapeBorder shape = null, |
|||
ButtonBarLayoutBehavior layoutBehavior = ButtonBarLayoutBehavior.padded, |
|||
bool alignedDropdown = false, |
|||
Color buttonColor = null, |
|||
Color disabledColor = null, |
|||
Color highlightColor = null, |
|||
Color splashColor = null, |
|||
ColorScheme colorScheme = null, |
|||
MaterialTapTargetSize? materialTapTargetSize = null |
|||
) { |
|||
D.assert(minWidth >= 0.0); |
|||
D.assert(height >= 0.0); |
|||
this.textTheme = textTheme; |
|||
this.minWidth = minWidth; |
|||
this.height = height; |
|||
this.layoutBehavior = layoutBehavior; |
|||
this.alignedDropdown = alignedDropdown; |
|||
this.colorScheme = colorScheme; |
|||
_buttonColor = buttonColor; |
|||
_disabledColor = disabledColor; |
|||
_highlightColor = highlightColor; |
|||
_splashColor = splashColor; |
|||
_padding = padding; |
|||
_shape = shape; |
|||
_materialTapTargetSize = materialTapTargetSize; |
|||
} |
|||
|
|||
|
|||
public readonly float minWidth; |
|||
|
|||
public readonly float height; |
|||
|
|||
public readonly ButtonTextTheme textTheme; |
|||
|
|||
public readonly ButtonBarLayoutBehavior layoutBehavior; |
|||
|
|||
public BoxConstraints constraints { |
|||
get { |
|||
return new BoxConstraints(minWidth: minWidth, |
|||
minHeight: height); |
|||
} |
|||
} |
|||
|
|||
public EdgeInsets padding { |
|||
get { |
|||
if (_padding != null) { |
|||
return _padding; |
|||
} |
|||
|
|||
switch (textTheme) { |
|||
case ButtonTextTheme.normal: |
|||
case ButtonTextTheme.accent: |
|||
return EdgeInsets.symmetric(horizontal: 16.0f); |
|||
case ButtonTextTheme.primary: |
|||
return EdgeInsets.symmetric(horizontal: 24.0f); |
|||
} |
|||
|
|||
D.assert(false); |
|||
return EdgeInsets.zero; |
|||
} |
|||
} |
|||
|
|||
readonly EdgeInsets _padding; |
|||
|
|||
public ShapeBorder shape { |
|||
get { |
|||
if (_shape != null) { |
|||
return _shape; |
|||
} |
|||
|
|||
switch (textTheme) { |
|||
case ButtonTextTheme.normal: |
|||
case ButtonTextTheme.accent: |
|||
return new RoundedRectangleBorder( |
|||
borderRadius: BorderRadius.all(Radius.circular(2.0f))); |
|||
case ButtonTextTheme.primary: |
|||
return new RoundedRectangleBorder( |
|||
borderRadius: BorderRadius.all(Radius.circular(4.0f))); |
|||
} |
|||
|
|||
return new RoundedRectangleBorder(); |
|||
} |
|||
} |
|||
|
|||
readonly ShapeBorder _shape; |
|||
|
|||
public readonly bool alignedDropdown; |
|||
|
|||
readonly Color _buttonColor; |
|||
|
|||
readonly Color _disabledColor; |
|||
|
|||
readonly Color _highlightColor; |
|||
|
|||
readonly Color _splashColor; |
|||
|
|||
public readonly ColorScheme colorScheme; |
|||
|
|||
readonly MaterialTapTargetSize? _materialTapTargetSize; |
|||
|
|||
public Brightness getBrightness(MaterialButton button) { |
|||
return button.colorBrightness ?? colorScheme.brightness; |
|||
} |
|||
|
|||
public ButtonTextTheme getTextTheme(MaterialButton button) { |
|||
return button.textTheme ?? textTheme; |
|||
} |
|||
|
|||
Color _getDisabledColor(MaterialButton button) { |
|||
return getBrightness(button) == Brightness.dark |
|||
? colorScheme.onSurface.withOpacity(0.30f) |
|||
: colorScheme.onSurface.withOpacity(0.38f); |
|||
} |
|||
|
|||
|
|||
public Color getDisabledTextColor(MaterialButton button) { |
|||
if (button.disabledTextColor != null) { |
|||
return button.disabledTextColor; |
|||
} |
|||
|
|||
return _getDisabledColor(button); |
|||
} |
|||
|
|||
|
|||
Color getDisabledFillColor(MaterialButton button) { |
|||
if (button.disabledColor != null) { |
|||
return button.disabledColor; |
|||
} |
|||
|
|||
if (_disabledColor != null) { |
|||
return _disabledColor; |
|||
} |
|||
|
|||
return _getDisabledColor(button); |
|||
} |
|||
|
|||
|
|||
public Color getFillColor(MaterialButton button) { |
|||
Color fillColor = button.enabled ? button.color : button.disabledColor; |
|||
if (fillColor != null) { |
|||
return fillColor; |
|||
} |
|||
|
|||
if (button is FlatButton || button is OutlineButton || button.GetType() == typeof(MaterialButton)) { |
|||
return null; |
|||
} |
|||
|
|||
|
|||
if (button.enabled && button is RaisedButton && _buttonColor != null) { |
|||
return _buttonColor; |
|||
} |
|||
|
|||
switch (getTextTheme(button)) { |
|||
case ButtonTextTheme.normal: |
|||
case ButtonTextTheme.accent: |
|||
return button.enabled ? colorScheme.primary : getDisabledFillColor(button); |
|||
case ButtonTextTheme.primary: |
|||
return button.enabled |
|||
? _buttonColor ?? colorScheme.primary |
|||
: colorScheme.onSurface.withOpacity(0.12f); |
|||
} |
|||
|
|||
D.assert(false); |
|||
return null; |
|||
} |
|||
|
|||
public Color getTextColor(MaterialButton button) { |
|||
if (!button.enabled) { |
|||
return getDisabledTextColor(button); |
|||
} |
|||
|
|||
if (button.textColor != null) { |
|||
return button.textColor; |
|||
} |
|||
|
|||
switch (getTextTheme(button)) { |
|||
case ButtonTextTheme.normal: |
|||
return getBrightness(button) == Brightness.dark ? Colors.white : Colors.black87; |
|||
case ButtonTextTheme.accent: |
|||
return colorScheme.secondary; |
|||
case ButtonTextTheme.primary: { |
|||
Color fillColor = getFillColor(button); |
|||
bool fillIsDark = fillColor != null |
|||
? ThemeData.estimateBrightnessForColor(fillColor) == Brightness.dark |
|||
: getBrightness(button) == Brightness.dark; |
|||
if (fillIsDark) { |
|||
return Colors.white; |
|||
} |
|||
|
|||
if (button is FlatButton || button is OutlineButton) { |
|||
return colorScheme.primary; |
|||
} |
|||
|
|||
return Colors.black; |
|||
} |
|||
} |
|||
|
|||
D.assert(false); |
|||
return null; |
|||
} |
|||
|
|||
public Color getSplashColor(MaterialButton button) { |
|||
if (button.splashColor != null) { |
|||
return button.splashColor; |
|||
} |
|||
|
|||
if (_splashColor != null && (button is RaisedButton || button is OutlineButton)) { |
|||
return _splashColor; |
|||
} |
|||
|
|||
if (_splashColor != null && button is FlatButton) { |
|||
switch (getTextTheme(button)) { |
|||
case ButtonTextTheme.normal: |
|||
case ButtonTextTheme.accent: |
|||
return _splashColor; |
|||
case ButtonTextTheme.primary: |
|||
break; |
|||
} |
|||
} |
|||
|
|||
return getTextColor(button).withOpacity(0.12f); |
|||
} |
|||
|
|||
public Color getHighlightColor(MaterialButton button) { |
|||
if (button.highlightColor != null) { |
|||
return button.highlightColor; |
|||
} |
|||
|
|||
switch (getTextTheme(button)) { |
|||
case ButtonTextTheme.normal: |
|||
case ButtonTextTheme.accent: |
|||
return _highlightColor ?? getTextColor(button).withOpacity(0.16f); |
|||
case ButtonTextTheme.primary: |
|||
return Colors.transparent; |
|||
} |
|||
|
|||
D.assert(false); |
|||
return Colors.transparent; |
|||
} |
|||
|
|||
|
|||
public float getElevation(MaterialButton button) { |
|||
if (button.elevation != null) { |
|||
return button.elevation ?? 0.0f; |
|||
} |
|||
|
|||
if (button is FlatButton) { |
|||
return 0.0f; |
|||
} |
|||
|
|||
return 2.0f; |
|||
} |
|||
|
|||
|
|||
public float getHighlightElevation(MaterialButton button) { |
|||
if (button.highlightElevation != null) { |
|||
return button.highlightElevation ?? 0.0f; |
|||
} |
|||
|
|||
if (button is FlatButton) { |
|||
return 0.0f; |
|||
} |
|||
|
|||
if (button is OutlineButton) { |
|||
return 0.0f; |
|||
} |
|||
return 8.0f; |
|||
} |
|||
|
|||
|
|||
public float getDisabledElevation(MaterialButton button) { |
|||
if (button.disabledElevation != null) { |
|||
return button.disabledElevation ?? 0.0f; |
|||
} |
|||
|
|||
return 0.0f; |
|||
} |
|||
|
|||
|
|||
public EdgeInsets getPadding(MaterialButton button) { |
|||
if (button.padding != null) { |
|||
return button.padding; |
|||
} |
|||
|
|||
if (button is MaterialButtonWithIconMixin) { |
|||
return EdgeInsets.fromLTRB(12.0f, 0.0f, 16.0f, 0.0f); |
|||
} |
|||
|
|||
if (_padding != null) { |
|||
return _padding; |
|||
} |
|||
|
|||
switch (getTextTheme(button)) { |
|||
case ButtonTextTheme.normal: |
|||
case ButtonTextTheme.accent: |
|||
return EdgeInsets.symmetric(horizontal: 16.0f); |
|||
case ButtonTextTheme.primary: |
|||
return EdgeInsets.symmetric(horizontal: 24.0f); |
|||
} |
|||
|
|||
D.assert(false); |
|||
return EdgeInsets.zero; |
|||
} |
|||
|
|||
public ShapeBorder getShape(MaterialButton button) { |
|||
return button.shape ?? shape; |
|||
} |
|||
|
|||
|
|||
public TimeSpan getAnimationDuration(MaterialButton button) { |
|||
return button.animationDuration ?? Constants.kThemeChangeDuration; |
|||
} |
|||
|
|||
public BoxConstraints getConstraints(MaterialButton button) { |
|||
return constraints; |
|||
} |
|||
|
|||
|
|||
public MaterialTapTargetSize getMaterialTapTargetSize(MaterialButton button) { |
|||
return button.materialTapTargetSize ?? _materialTapTargetSize ?? MaterialTapTargetSize.padded; |
|||
} |
|||
|
|||
|
|||
public ButtonThemeData copyWith( |
|||
ButtonTextTheme? textTheme = null, |
|||
ButtonBarLayoutBehavior? layoutBehavior = null, |
|||
float? minWidth = null, |
|||
float? height = null, |
|||
EdgeInsets padding = null, |
|||
ShapeBorder shape = null, |
|||
bool? alignedDropdown = null, |
|||
Color buttonColor = null, |
|||
Color disabledColor = null, |
|||
Color highlightColor = null, |
|||
Color splashColor = null, |
|||
ColorScheme colorScheme = null, |
|||
MaterialTapTargetSize? materialTapTargetSize = null) { |
|||
return new ButtonThemeData( |
|||
textTheme: textTheme ?? this.textTheme, |
|||
layoutBehavior: layoutBehavior ?? this.layoutBehavior, |
|||
minWidth: minWidth ?? this.minWidth, |
|||
height: height ?? this.height, |
|||
padding: padding ?? this.padding, |
|||
shape: shape ?? this.shape, |
|||
alignedDropdown: alignedDropdown ?? this.alignedDropdown, |
|||
buttonColor: buttonColor ?? _buttonColor, |
|||
disabledColor: disabledColor ?? _disabledColor, |
|||
highlightColor: highlightColor ?? _highlightColor, |
|||
splashColor: splashColor ?? _splashColor, |
|||
colorScheme: colorScheme ?? this.colorScheme, |
|||
materialTapTargetSize: materialTapTargetSize ?? _materialTapTargetSize); |
|||
} |
|||
|
|||
public bool Equals(ButtonThemeData other) { |
|||
if (ReferenceEquals(null, other)) { |
|||
return false; |
|||
} |
|||
|
|||
if (ReferenceEquals(this, other)) { |
|||
return true; |
|||
} |
|||
|
|||
return textTheme == other.textTheme |
|||
&& minWidth == other.minWidth |
|||
&& height == other.height |
|||
&& padding == other.padding |
|||
&& shape == other.shape |
|||
&& alignedDropdown == other.alignedDropdown |
|||
&& _buttonColor == other._buttonColor |
|||
&& _disabledColor == other._disabledColor |
|||
&& _highlightColor == other._highlightColor |
|||
&& _splashColor == other._splashColor |
|||
&& colorScheme == other.colorScheme |
|||
&& _materialTapTargetSize == other._materialTapTargetSize; |
|||
} |
|||
|
|||
public override bool Equals(object obj) { |
|||
if (ReferenceEquals(null, obj)) { |
|||
return false; |
|||
} |
|||
|
|||
if (ReferenceEquals(this, obj)) { |
|||
return true; |
|||
} |
|||
|
|||
if (obj.GetType() != GetType()) { |
|||
return false; |
|||
} |
|||
|
|||
return Equals((ButtonThemeData) obj); |
|||
} |
|||
|
|||
public static bool operator ==(ButtonThemeData left, ButtonThemeData right) { |
|||
return Equals(left, right); |
|||
} |
|||
|
|||
public static bool operator !=(ButtonThemeData left, ButtonThemeData right) { |
|||
return !Equals(left, right); |
|||
} |
|||
|
|||
public override int GetHashCode() { |
|||
unchecked { |
|||
var hashCode = textTheme.GetHashCode(); |
|||
hashCode = (hashCode * 397) ^ minWidth.GetHashCode(); |
|||
hashCode = (hashCode * 397) ^ height.GetHashCode(); |
|||
hashCode = (hashCode * 397) ^ padding.GetHashCode(); |
|||
hashCode = (hashCode * 397) ^ shape.GetHashCode(); |
|||
hashCode = (hashCode * 397) ^ alignedDropdown.GetHashCode(); |
|||
hashCode = (hashCode * 397) ^ (_buttonColor != null ? _buttonColor.GetHashCode() : 0); |
|||
hashCode = (hashCode * 397) ^ (_disabledColor != null ? _disabledColor.GetHashCode() : 0); |
|||
hashCode = (hashCode * 397) ^ (_highlightColor != null ? _highlightColor.GetHashCode() : 0); |
|||
hashCode = (hashCode * 397) ^ (_splashColor != null ? _splashColor.GetHashCode() : 0); |
|||
hashCode = (hashCode * 397) ^ colorScheme.GetHashCode(); |
|||
hashCode = (hashCode * 397) ^ _materialTapTargetSize.GetHashCode(); |
|||
return hashCode; |
|||
} |
|||
} |
|||
|
|||
public override void debugFillProperties(DiagnosticPropertiesBuilder properties) { |
|||
base.debugFillProperties(properties); |
|||
ButtonThemeData defaultTheme = new ButtonThemeData(); |
|||
properties.add(new EnumProperty<ButtonTextTheme>("textTheme", textTheme, |
|||
defaultValue: defaultTheme.textTheme)); |
|||
properties.add(new FloatProperty("minWidth", minWidth, defaultValue: defaultTheme.minWidth)); |
|||
properties.add(new FloatProperty("height", height, defaultValue: defaultTheme.height)); |
|||
properties.add(new DiagnosticsProperty<EdgeInsets>("padding", padding, |
|||
defaultValue: defaultTheme.padding)); |
|||
properties.add(new DiagnosticsProperty<ShapeBorder>("shape", shape, defaultValue: defaultTheme.shape)); |
|||
properties.add(new FlagProperty("alignedDropdown", |
|||
value: alignedDropdown, |
|||
defaultValue: defaultTheme.alignedDropdown, |
|||
ifTrue: "dropdown width matches button" |
|||
)); |
|||
properties.add(new DiagnosticsProperty<Color>("buttonColor", _buttonColor, defaultValue: null)); |
|||
properties.add(new DiagnosticsProperty<Color>("disabledColor", _disabledColor, defaultValue: null)); |
|||
properties.add(new DiagnosticsProperty<Color>("highlightColor", _highlightColor, defaultValue: null)); |
|||
properties.add(new DiagnosticsProperty<Color>("splashColor", _splashColor, defaultValue: null)); |
|||
properties.add(new DiagnosticsProperty<ColorScheme>("colorScheme", colorScheme, |
|||
defaultValue: defaultTheme.colorScheme)); |
|||
properties.add(new DiagnosticsProperty<MaterialTapTargetSize?>("materialTapTargetSize", |
|||
_materialTapTargetSize, defaultValue: null)); |
|||
} |
|||
} |
|||
} |
|
|||
fileFormatVersion: 2 |
|||
guid: c00e9535ad31f481cbe2b83d490d714d |
|||
MonoImporter: |
|||
externalObjects: {} |
|||
serializedVersion: 2 |
|||
defaultReferences: [] |
|||
executionOrder: 0 |
|||
icon: {instanceID: 0} |
|||
userData: |
|||
assetBundleName: |
|||
assetBundleVariant: |
|
|||
using Unity.UIWidgets.foundation; |
|||
using Unity.UIWidgets.painting; |
|||
using Unity.UIWidgets.ui; |
|||
using Unity.UIWidgets.widgets; |
|||
|
|||
namespace Unity.UIWidgets.material { |
|||
public class Card : StatelessWidget { |
|||
public Card( |
|||
Key key = null, |
|||
Color color = null, |
|||
float? elevation = null, |
|||
ShapeBorder shape = null, |
|||
bool borderOnForeground = true, |
|||
EdgeInsets margin = null, |
|||
Clip? clipBehavior = null, |
|||
Widget child = null) : base(key: key) { |
|||
D.assert(elevation == null || elevation >= 0.0f); |
|||
this.color = color; |
|||
this.elevation = elevation; |
|||
this.shape = shape; |
|||
this.borderOnForeground = borderOnForeground; |
|||
this.margin = margin; |
|||
this.clipBehavior = clipBehavior; |
|||
this.child = child; |
|||
} |
|||
|
|||
public readonly Color color; |
|||
|
|||
public readonly float? elevation; |
|||
|
|||
public readonly ShapeBorder shape; |
|||
|
|||
public readonly bool borderOnForeground; |
|||
|
|||
public readonly Clip? clipBehavior; |
|||
|
|||
public readonly EdgeInsets margin; |
|||
|
|||
public readonly Widget child; |
|||
|
|||
const float _defaultElevation = 1.0f; |
|||
const Clip _defaultClipBehavior = Clip.none; |
|||
|
|||
public override Widget build(BuildContext context) { |
|||
CardTheme cardTheme = CardTheme.of(context); |
|||
|
|||
return new Container( |
|||
margin: margin ?? cardTheme.margin ?? EdgeInsets.all(4.0f), |
|||
child: new Material( |
|||
type: MaterialType.card, |
|||
color: color ?? cardTheme.color ?? Theme.of(context).cardColor, |
|||
elevation: elevation ?? cardTheme.elevation ?? _defaultElevation, |
|||
shape: shape ?? cardTheme.shape ?? new RoundedRectangleBorder( |
|||
borderRadius: BorderRadius.all(Radius.circular(4.0f)) |
|||
), |
|||
borderOnForeground: borderOnForeground, |
|||
clipBehavior: clipBehavior ?? cardTheme.clipBehavior ?? _defaultClipBehavior, |
|||
child: child) |
|||
); |
|||
} |
|||
} |
|||
} |
|
|||
fileFormatVersion: 2 |
|||
guid: 4f7e63a9f1e7d49e7896665f3c16bbe3 |
|||
MonoImporter: |
|||
externalObjects: {} |
|||
serializedVersion: 2 |
|||
defaultReferences: [] |
|||
executionOrder: 0 |
|||
icon: {instanceID: 0} |
|||
userData: |
|||
assetBundleName: |
|||
assetBundleVariant: |
|
|||
using Unity.UIWidgets.foundation; |
|||
using Unity.UIWidgets.painting; |
|||
using Unity.UIWidgets.ui; |
|||
using Unity.UIWidgets.widgets; |
|||
|
|||
namespace Unity.UIWidgets.material { |
|||
public class CardTheme : Diagnosticable { |
|||
public CardTheme( |
|||
Clip? clipBehavior = null, |
|||
Color color = null, |
|||
float? elevation = null, |
|||
EdgeInsets margin = null, |
|||
ShapeBorder shape = null |
|||
) { |
|||
D.assert(elevation == null || elevation >= 0.0f); |
|||
this.clipBehavior = clipBehavior; |
|||
this.color = color; |
|||
this.elevation = elevation; |
|||
this.margin = margin; |
|||
this.shape = shape; |
|||
} |
|||
|
|||
public readonly Clip? clipBehavior; |
|||
|
|||
public readonly Color color; |
|||
|
|||
public readonly float? elevation; |
|||
|
|||
public readonly EdgeInsets margin; |
|||
|
|||
public readonly ShapeBorder shape; |
|||
|
|||
CardTheme copyWith( |
|||
Clip? clipBehavior = null, |
|||
Color color = null, |
|||
float? elevation = null, |
|||
EdgeInsets margin = null, |
|||
ShapeBorder shape = null |
|||
) { |
|||
return new CardTheme( |
|||
clipBehavior: clipBehavior ?? this.clipBehavior, |
|||
color: color ?? this.color, |
|||
elevation: elevation ?? this.elevation, |
|||
margin: margin ?? this.margin, |
|||
shape: shape ?? this.shape |
|||
); |
|||
} |
|||
|
|||
public static CardTheme of(BuildContext context) { |
|||
return Theme.of(context).cardTheme; |
|||
} |
|||
|
|||
public static CardTheme lerp(CardTheme a, CardTheme b, float t) { |
|||
return new CardTheme( |
|||
clipBehavior: t < 0.5f ? a?.clipBehavior : b?.clipBehavior, |
|||
color: Color.lerp(a?.color, b?.color, t), |
|||
elevation: MathUtils.lerpFloat(a?.elevation ?? 0.0f, b?.elevation ?? 0.0f, t), |
|||
margin: EdgeInsets.lerp(a?.margin, b?.margin, t), |
|||
shape: ShapeBorder.lerp(a?.shape, b?.shape, t) |
|||
); |
|||
} |
|||
|
|||
public override int GetHashCode() { |
|||
var hashCode = clipBehavior?.GetHashCode() ?? 0; |
|||
hashCode = (hashCode * 397) ^ color?.GetHashCode() ?? 0; |
|||
hashCode = (hashCode * 397) ^ elevation?.GetHashCode() ?? 0; |
|||
hashCode = (hashCode * 397) ^ margin?.GetHashCode() ?? 0; |
|||
hashCode = (hashCode * 397) ^ shape?.GetHashCode() ?? 0; |
|||
return hashCode; |
|||
} |
|||
|
|||
public bool Equals(CardTheme other) { |
|||
return other.clipBehavior == clipBehavior |
|||
&& other.color == color |
|||
&& other.elevation == elevation |
|||
&& other.margin == margin |
|||
&& other.shape == shape; |
|||
} |
|||
|
|||
public override void debugFillProperties(DiagnosticPropertiesBuilder properties) { |
|||
base.debugFillProperties(properties); |
|||
properties.add(new DiagnosticsProperty<Clip?>("clipBehavior", clipBehavior, defaultValue: null)); |
|||
properties.add(new DiagnosticsProperty<Color>("color", color, defaultValue: null)); |
|||
properties.add(new DiagnosticsProperty<float?>("elevation", elevation, defaultValue: null)); |
|||
properties.add(new DiagnosticsProperty<EdgeInsets>("margin", margin, defaultValue: null)); |
|||
properties.add(new DiagnosticsProperty<ShapeBorder>("shape", shape, defaultValue: null)); |
|||
} |
|||
} |
|||
} |
|
|||
fileFormatVersion: 2 |
|||
guid: d74c4f94f0994a3880425c80ec3d9ba3 |
|||
timeCreated: 1556187816 |
|
|||
using System; |
|||
using Unity.UIWidgets.animation; |
|||
using Unity.UIWidgets.foundation; |
|||
using Unity.UIWidgets.rendering; |
|||
using Unity.UIWidgets.scheduler; |
|||
using Unity.UIWidgets.ui; |
|||
using Unity.UIWidgets.widgets; |
|||
using UnityEngine; |
|||
using Canvas = Unity.UIWidgets.ui.Canvas; |
|||
using Color = Unity.UIWidgets.ui.Color; |
|||
using Rect = Unity.UIWidgets.ui.Rect; |
|||
|
|||
namespace Unity.UIWidgets.material { |
|||
class CheckboxUtils { |
|||
public const float _kEdgeSize = Checkbox.width; |
|||
public static readonly Radius _kEdgeRadius = Radius.circular(1.0f); |
|||
public const float _kStrokeWidth = 2.0f; |
|||
} |
|||
|
|||
public class Checkbox : StatefulWidget { |
|||
public Checkbox( |
|||
Key key = null, |
|||
bool? value = false, |
|||
bool tristate = false, |
|||
ValueChanged<bool?> onChanged = null, |
|||
Color activeColor = null, |
|||
Color checkColor = null, |
|||
MaterialTapTargetSize? materialTapTargetSize = null |
|||
) : base(key: key) { |
|||
D.assert(tristate || value != null); |
|||
this.value = value; |
|||
this.onChanged = onChanged; |
|||
this.activeColor = activeColor; |
|||
this.checkColor = checkColor; |
|||
this.tristate = tristate; |
|||
this.materialTapTargetSize = materialTapTargetSize; |
|||
} |
|||
|
|||
public readonly bool? value; |
|||
|
|||
public readonly ValueChanged<bool?> onChanged; |
|||
|
|||
public readonly Color activeColor; |
|||
|
|||
public readonly Color checkColor; |
|||
|
|||
public readonly bool tristate; |
|||
|
|||
public readonly MaterialTapTargetSize? materialTapTargetSize; |
|||
|
|||
public const float width = 18.0f; |
|||
|
|||
public override State createState() { |
|||
return new _CheckboxState(); |
|||
} |
|||
} |
|||
|
|||
class _CheckboxState : TickerProviderStateMixin<Checkbox> { |
|||
public override Widget build(BuildContext context) { |
|||
D.assert(MaterialD.debugCheckHasMaterial(context)); |
|||
ThemeData themeData = Theme.of(context); |
|||
Size size; |
|||
switch (widget.materialTapTargetSize ?? themeData.materialTapTargetSize) { |
|||
case MaterialTapTargetSize.padded: |
|||
size = new Size(2 * Constants.kRadialReactionRadius + 8.0f, |
|||
2 * Constants.kRadialReactionRadius + 8.0f); |
|||
break; |
|||
case MaterialTapTargetSize.shrinkWrap: |
|||
size = new Size(2 * Constants.kRadialReactionRadius, 2 * Constants.kRadialReactionRadius); |
|||
break; |
|||
default: |
|||
throw new Exception("Unknown target size: " + widget.materialTapTargetSize); |
|||
} |
|||
|
|||
BoxConstraints additionalConstraints = BoxConstraints.tight(size); |
|||
return new _CheckboxRenderObjectWidget( |
|||
value: widget.value, |
|||
tristate: widget.tristate, |
|||
activeColor: widget.activeColor ?? themeData.toggleableActiveColor, |
|||
checkColor: widget.checkColor ?? new Color(0xFFFFFFFF), |
|||
inactiveColor: widget.onChanged != null |
|||
? themeData.unselectedWidgetColor |
|||
: themeData.disabledColor, |
|||
onChanged: widget.onChanged, |
|||
additionalConstraints: additionalConstraints, |
|||
vsync: this |
|||
); |
|||
} |
|||
} |
|||
|
|||
class _CheckboxRenderObjectWidget : LeafRenderObjectWidget { |
|||
public _CheckboxRenderObjectWidget( |
|||
Key key = null, |
|||
bool? value = null, |
|||
bool tristate = false, |
|||
Color activeColor = null, |
|||
Color checkColor = null, |
|||
Color inactiveColor = null, |
|||
ValueChanged<bool?> onChanged = null, |
|||
TickerProvider vsync = null, |
|||
BoxConstraints additionalConstraints = null |
|||
) : base(key: key) { |
|||
D.assert(tristate || value != null); |
|||
D.assert(activeColor != null); |
|||
D.assert(inactiveColor != null); |
|||
D.assert(vsync != null); |
|||
this.value = value; |
|||
this.tristate = tristate; |
|||
this.activeColor = activeColor; |
|||
this.checkColor = checkColor; |
|||
this.inactiveColor = inactiveColor; |
|||
this.onChanged = onChanged; |
|||
this.vsync = vsync; |
|||
this.additionalConstraints = additionalConstraints; |
|||
} |
|||
|
|||
public readonly bool? value; |
|||
public readonly bool tristate; |
|||
public readonly Color activeColor; |
|||
public readonly Color checkColor; |
|||
public readonly Color inactiveColor; |
|||
public readonly ValueChanged<bool?> onChanged; |
|||
public readonly TickerProvider vsync; |
|||
public readonly BoxConstraints additionalConstraints; |
|||
|
|||
public override RenderObject createRenderObject(BuildContext context) { |
|||
return new _RenderCheckbox( |
|||
value: value, |
|||
tristate: tristate, |
|||
activeColor: activeColor, |
|||
checkColor: checkColor, |
|||
inactiveColor: inactiveColor, |
|||
onChanged: onChanged, |
|||
vsync: vsync, |
|||
additionalConstraints: additionalConstraints |
|||
); |
|||
} |
|||
|
|||
public override void updateRenderObject(BuildContext context, RenderObject _renderObject) { |
|||
_RenderCheckbox renderObject = _renderObject as _RenderCheckbox; |
|||
renderObject.value = value; |
|||
renderObject.tristate = tristate; |
|||
renderObject.activeColor = activeColor; |
|||
renderObject.checkColor = checkColor; |
|||
renderObject.inactiveColor = inactiveColor; |
|||
renderObject.onChanged = onChanged; |
|||
renderObject.additionalConstraints = additionalConstraints; |
|||
renderObject.vsync = vsync; |
|||
} |
|||
} |
|||
|
|||
|
|||
class _RenderCheckbox : RenderToggleable { |
|||
public _RenderCheckbox( |
|||
bool? value = null, |
|||
bool tristate = false, |
|||
Color activeColor = null, |
|||
Color checkColor = null, |
|||
Color inactiveColor = null, |
|||
BoxConstraints additionalConstraints = null, |
|||
ValueChanged<bool?> onChanged = null, |
|||
TickerProvider vsync = null |
|||
) : base( |
|||
value: value, |
|||
tristate: tristate, |
|||
activeColor: activeColor, |
|||
inactiveColor: inactiveColor, |
|||
onChanged: onChanged, |
|||
additionalConstraints: additionalConstraints, |
|||
vsync: vsync |
|||
) { |
|||
_oldValue = value; |
|||
this.checkColor = checkColor; |
|||
} |
|||
|
|||
bool? _oldValue; |
|||
public Color checkColor; |
|||
|
|||
public override bool? value { |
|||
set { |
|||
if (value == this.value) { |
|||
return; |
|||
} |
|||
|
|||
_oldValue = this.value; |
|||
base.value = value; |
|||
} |
|||
} |
|||
|
|||
RRect _outerRectAt(Offset origin, float t) { |
|||
float inset = 1.0f - (t - 0.5f).abs() * 2.0f; |
|||
float size = CheckboxUtils._kEdgeSize - inset * CheckboxUtils._kStrokeWidth; |
|||
Rect rect = Rect.fromLTWH(origin.dx + inset, origin.dy + inset, size, size); |
|||
return RRect.fromRectAndRadius(rect, CheckboxUtils._kEdgeRadius); |
|||
} |
|||
|
|||
Color _colorAt(float t) { |
|||
return onChanged == null |
|||
? inactiveColor |
|||
: (t >= 0.25f ? activeColor : Color.lerp(inactiveColor, activeColor, t * 4.0f)); |
|||
} |
|||
|
|||
void _initStrokePaint(Paint paint) { |
|||
paint.color = checkColor; |
|||
paint.style = PaintingStyle.stroke; |
|||
paint.strokeWidth = CheckboxUtils._kStrokeWidth; |
|||
} |
|||
|
|||
void _drawBorder(Canvas canvas, RRect outer, float t, Paint paint) { |
|||
D.assert(t >= 0.0f && t <= 0.5f); |
|||
float size = outer.width; |
|||
RRect inner = outer.deflate(Mathf.Min(size / 2.0f, CheckboxUtils._kStrokeWidth + size * t)); |
|||
canvas.drawDRRect(outer, inner, paint); |
|||
} |
|||
|
|||
void _drawCheck(Canvas canvas, Offset origin, float t, Paint paint) { |
|||
D.assert(t >= 0.0f && t <= 1.0f); |
|||
Path path = new Path(); |
|||
Offset start = new Offset(CheckboxUtils._kEdgeSize * 0.15f, CheckboxUtils._kEdgeSize * 0.45f); |
|||
Offset mid = new Offset(CheckboxUtils._kEdgeSize * 0.4f, CheckboxUtils._kEdgeSize * 0.7f); |
|||
Offset end = new Offset(CheckboxUtils._kEdgeSize * 0.85f, CheckboxUtils._kEdgeSize * 0.25f); |
|||
if (t < 0.5f) { |
|||
float strokeT = t * 2.0f; |
|||
Offset drawMid = Offset.lerp(start, mid, strokeT); |
|||
path.moveTo(origin.dx + start.dx, origin.dy + start.dy); |
|||
path.lineTo(origin.dx + drawMid.dx, origin.dy + drawMid.dy); |
|||
} |
|||
else { |
|||
float strokeT = (t - 0.5f) * 2.0f; |
|||
Offset drawEnd = Offset.lerp(mid, end, strokeT); |
|||
path.moveTo(origin.dx + start.dx, origin.dy + start.dy); |
|||
path.lineTo(origin.dx + mid.dx, origin.dy + mid.dy); |
|||
path.lineTo(origin.dx + drawEnd.dx, origin.dy + drawEnd.dy); |
|||
} |
|||
|
|||
canvas.drawPath(path, paint); |
|||
} |
|||
|
|||
void _drawDash(Canvas canvas, Offset origin, float t, Paint paint) { |
|||
D.assert(t >= 0.0f && t <= 1.0f); |
|||
Offset start = new Offset(CheckboxUtils._kEdgeSize * 0.2f, CheckboxUtils._kEdgeSize * 0.5f); |
|||
Offset mid = new Offset(CheckboxUtils._kEdgeSize * 0.5f, CheckboxUtils._kEdgeSize * 0.5f); |
|||
Offset end = new Offset(CheckboxUtils._kEdgeSize * 0.8f, CheckboxUtils._kEdgeSize * 0.5f); |
|||
Offset drawStart = Offset.lerp(start, mid, 1.0f - t); |
|||
Offset drawEnd = Offset.lerp(mid, end, t); |
|||
canvas.drawLine(origin + drawStart, origin + drawEnd, paint); |
|||
} |
|||
|
|||
public override void paint(PaintingContext context, Offset offset) { |
|||
Canvas canvas = context.canvas; |
|||
paintRadialReaction(canvas, offset, size.center(Offset.zero)); |
|||
|
|||
Offset origin = offset + (size / 2.0f - Size.square(CheckboxUtils._kEdgeSize) / 2.0f); |
|||
AnimationStatus status = position.status; |
|||
float tNormalized = status == AnimationStatus.forward || status == AnimationStatus.completed |
|||
? position.value |
|||
: 1.0f - position.value; |
|||
|
|||
if (_oldValue == false || value == false) { |
|||
float t = value == false ? 1.0f - tNormalized : tNormalized; |
|||
RRect outer = _outerRectAt(origin, t); |
|||
Paint paint = new Paint(); |
|||
paint.color = _colorAt(t); |
|||
|
|||
if (t <= 0.5f) { |
|||
_drawBorder(canvas, outer, t, paint); |
|||
} |
|||
else { |
|||
canvas.drawRRect(outer, paint); |
|||
|
|||
_initStrokePaint(paint); |
|||
float tShrink = (t - 0.5f) * 2.0f; |
|||
if (_oldValue == null || value == null) { |
|||
_drawDash(canvas, origin, tShrink, paint); |
|||
} |
|||
else { |
|||
_drawCheck(canvas, origin, tShrink, paint); |
|||
} |
|||
} |
|||
} |
|||
else { |
|||
// Two cases: null to true, true to null
|
|||
RRect outer = _outerRectAt(origin, 1.0f); |
|||
Paint paint = new Paint(); |
|||
paint.color = _colorAt(1.0f); |
|||
canvas.drawRRect(outer, paint); |
|||
|
|||
_initStrokePaint(paint); |
|||
if (tNormalized <= 0.5f) { |
|||
float tShrink = 1.0f - tNormalized * 2.0f; |
|||
if (_oldValue == true) { |
|||
_drawCheck(canvas, origin, tShrink, paint); |
|||
} |
|||
else { |
|||
_drawDash(canvas, origin, tShrink, paint); |
|||
} |
|||
} |
|||
else { |
|||
float tExpand = (tNormalized - 0.5f) * 2.0f; |
|||
if (value == true) { |
|||
_drawCheck(canvas, origin, tExpand, paint); |
|||
} |
|||
else { |
|||
_drawDash(canvas, origin, tExpand, paint); |
|||
} |
|||
} |
|||
} |
|||
} |
|||
} |
|||
} |
|
|||
fileFormatVersion: 2 |
|||
guid: 3f506995b69c421cbdd95746b4ca2182 |
|||
timeCreated: 1554213056 |
1001
com.unity.uiwidgets/Runtime/material/chip.cs
文件差异内容过多而无法显示
查看文件
文件差异内容过多而无法显示
查看文件
|
|||
fileFormatVersion: 2 |
|||
guid: d4ca6b86209d4615b9aba98d6d112673 |
|||
timeCreated: 1555477997 |
|
|||
using Unity.UIWidgets.foundation; |
|||
using Unity.UIWidgets.painting; |
|||
using Unity.UIWidgets.service; |
|||
using Unity.UIWidgets.ui; |
|||
using Unity.UIWidgets.widgets; |
|||
using TextStyle = Unity.UIWidgets.painting.TextStyle; |
|||
|
|||
namespace Unity.UIWidgets.material { |
|||
public class ChipTheme : InheritedWidget { |
|||
public ChipTheme( |
|||
Key key = null, |
|||
ChipThemeData data = null, |
|||
Widget child = null |
|||
) : base(key: key, child: child) { |
|||
D.assert(child != null); |
|||
D.assert(data != null); |
|||
this.data = data; |
|||
} |
|||
|
|||
public readonly ChipThemeData data; |
|||
|
|||
public static ChipThemeData of(BuildContext context) { |
|||
ChipTheme inheritedTheme = (ChipTheme) context.inheritFromWidgetOfExactType(typeof(ChipTheme)); |
|||
return inheritedTheme?.data ?? Theme.of(context).chipTheme; |
|||
} |
|||
|
|||
public override bool updateShouldNotify(InheritedWidget _oldWidget) { |
|||
ChipTheme oldWidget = _oldWidget as ChipTheme; |
|||
return data != oldWidget.data; |
|||
} |
|||
} |
|||
|
|||
public class ChipThemeData : Diagnosticable { |
|||
public ChipThemeData( |
|||
Color backgroundColor = null, |
|||
Color deleteIconColor = null, |
|||
Color disabledColor = null, |
|||
Color selectedColor = null, |
|||
Color secondarySelectedColor = null, |
|||
Color shadowColor = null, |
|||
Color selectedShadowColor = null, |
|||
EdgeInsets labelPadding = null, |
|||
EdgeInsets padding = null, |
|||
ShapeBorder shape = null, |
|||
TextStyle labelStyle = null, |
|||
TextStyle secondaryLabelStyle = null, |
|||
Brightness? brightness = null, |
|||
float? elevation = null, |
|||
float? pressElevation = null |
|||
) { |
|||
D.assert(backgroundColor != null); |
|||
D.assert(disabledColor != null); |
|||
D.assert(selectedColor != null); |
|||
D.assert(secondarySelectedColor != null); |
|||
D.assert(labelPadding != null); |
|||
D.assert(padding != null); |
|||
D.assert(shape != null); |
|||
D.assert(labelStyle != null); |
|||
D.assert(secondaryLabelStyle != null); |
|||
D.assert(brightness != null); |
|||
this.backgroundColor = backgroundColor; |
|||
this.deleteIconColor = deleteIconColor; |
|||
this.disabledColor = disabledColor; |
|||
this.selectedColor = selectedColor; |
|||
this.secondarySelectedColor = secondarySelectedColor; |
|||
this.shadowColor = shadowColor; |
|||
this.selectedShadowColor = selectedShadowColor; |
|||
this.labelPadding = labelPadding; |
|||
this.padding = padding; |
|||
this.shape = shape; |
|||
this.labelStyle = labelStyle; |
|||
this.secondaryLabelStyle = secondaryLabelStyle; |
|||
this.brightness = brightness; |
|||
this.elevation = elevation; |
|||
this.pressElevation = pressElevation; |
|||
} |
|||
|
|||
public static ChipThemeData fromDefaults( |
|||
Brightness? brightness = null, |
|||
Color primaryColor = null, |
|||
Color secondaryColor = null, |
|||
TextStyle labelStyle = null |
|||
) { |
|||
D.assert(primaryColor != null || brightness != null, |
|||
() => "One of primaryColor or brightness must be specified"); |
|||
D.assert(primaryColor == null || brightness == null, |
|||
() => "Only one of primaryColor or brightness may be specified"); |
|||
D.assert(secondaryColor != null); |
|||
D.assert(labelStyle != null); |
|||
|
|||
if (primaryColor != null) { |
|||
brightness = ThemeData.estimateBrightnessForColor(primaryColor); |
|||
} |
|||
|
|||
const int backgroundAlpha = 0x1f; // 12%
|
|||
const int deleteIconAlpha = 0xde; // 87%
|
|||
const int disabledAlpha = 0x0c; // 38% * 12% = 5%
|
|||
const int selectAlpha = 0x3d; // 12% + 12% = 24%
|
|||
const int textLabelAlpha = 0xde; // 87%
|
|||
ShapeBorder shape = new StadiumBorder(); |
|||
EdgeInsets labelPadding = EdgeInsets.symmetric(horizontal: 8.0f); |
|||
EdgeInsets padding = EdgeInsets.all(4.0f); |
|||
|
|||
primaryColor = primaryColor ?? (brightness == Brightness.light ? Colors.black : Colors.white); |
|||
Color backgroundColor = primaryColor.withAlpha(backgroundAlpha); |
|||
Color deleteIconColor = primaryColor.withAlpha(deleteIconAlpha); |
|||
Color disabledColor = primaryColor.withAlpha(disabledAlpha); |
|||
Color selectedColor = primaryColor.withAlpha(selectAlpha); |
|||
Color secondarySelectedColor = secondaryColor.withAlpha(selectAlpha); |
|||
TextStyle secondaryLabelStyle = labelStyle.copyWith( |
|||
color: secondaryColor.withAlpha(textLabelAlpha) |
|||
); |
|||
labelStyle = labelStyle.copyWith(color: primaryColor.withAlpha(textLabelAlpha)); |
|||
|
|||
return new ChipThemeData( |
|||
backgroundColor: backgroundColor, |
|||
deleteIconColor: deleteIconColor, |
|||
disabledColor: disabledColor, |
|||
selectedColor: selectedColor, |
|||
secondarySelectedColor: secondarySelectedColor, |
|||
labelPadding: labelPadding, |
|||
padding: padding, |
|||
shape: shape, |
|||
labelStyle: labelStyle, |
|||
secondaryLabelStyle: secondaryLabelStyle, |
|||
brightness: brightness |
|||
); |
|||
} |
|||
|
|||
public readonly Color backgroundColor; |
|||
|
|||
public readonly Color deleteIconColor; |
|||
|
|||
public readonly Color disabledColor; |
|||
|
|||
public readonly Color selectedColor; |
|||
|
|||
public readonly Color secondarySelectedColor; |
|||
|
|||
public readonly Color shadowColor; |
|||
|
|||
public readonly Color selectedShadowColor; |
|||
|
|||
public readonly EdgeInsets labelPadding; |
|||
|
|||
public readonly EdgeInsets padding; |
|||
|
|||
public readonly ShapeBorder shape; |
|||
|
|||
public readonly TextStyle labelStyle; |
|||
|
|||
public readonly TextStyle secondaryLabelStyle; |
|||
|
|||
public readonly Brightness? brightness; |
|||
|
|||
public readonly float? elevation; |
|||
|
|||
public readonly float? pressElevation; |
|||
|
|||
public ChipThemeData copyWith( |
|||
Color backgroundColor = null, |
|||
Color deleteIconColor = null, |
|||
Color disabledColor = null, |
|||
Color selectedColor = null, |
|||
Color secondarySelectedColor = null, |
|||
Color shadowColor = null, |
|||
Color selectedShadowColor = null, |
|||
EdgeInsets labelPadding = null, |
|||
EdgeInsets padding = null, |
|||
ShapeBorder shape = null, |
|||
TextStyle labelStyle = null, |
|||
TextStyle secondaryLabelStyle = null, |
|||
Brightness? brightness = null, |
|||
float? elevation = null, |
|||
float? pressElevation = null |
|||
) { |
|||
return new ChipThemeData( |
|||
backgroundColor: backgroundColor ?? this.backgroundColor, |
|||
deleteIconColor: deleteIconColor ?? this.deleteIconColor, |
|||
disabledColor: disabledColor ?? this.disabledColor, |
|||
selectedColor: selectedColor ?? this.selectedColor, |
|||
secondarySelectedColor: secondarySelectedColor ?? this.secondarySelectedColor, |
|||
shadowColor: shadowColor ?? this.shadowColor, |
|||
selectedShadowColor: selectedShadowColor ?? this.selectedShadowColor, |
|||
labelPadding: labelPadding ?? this.labelPadding, |
|||
padding: padding ?? this.padding, |
|||
shape: shape ?? this.shape, |
|||
labelStyle: labelStyle ?? this.labelStyle, |
|||
secondaryLabelStyle: secondaryLabelStyle ?? this.secondaryLabelStyle, |
|||
brightness: brightness ?? this.brightness, |
|||
elevation: elevation ?? this.elevation, |
|||
pressElevation: pressElevation ?? this.pressElevation |
|||
); |
|||
} |
|||
|
|||
public static ChipThemeData lerp(ChipThemeData a, ChipThemeData b, float t) { |
|||
if (a == null && b == null) { |
|||
return null; |
|||
} |
|||
|
|||
return new ChipThemeData( |
|||
backgroundColor: Color.lerp(a?.backgroundColor, b?.backgroundColor, t), |
|||
deleteIconColor: Color.lerp(a?.deleteIconColor, b?.deleteIconColor, t), |
|||
disabledColor: Color.lerp(a?.disabledColor, b?.disabledColor, t), |
|||
selectedColor: Color.lerp(a?.selectedColor, b?.selectedColor, t), |
|||
secondarySelectedColor: Color.lerp(a?.secondarySelectedColor, b?.secondarySelectedColor, t), |
|||
shadowColor: Color.lerp(a?.shadowColor, b?.shadowColor, t), |
|||
selectedShadowColor: Color.lerp(a?.selectedShadowColor, b?.selectedShadowColor, t), |
|||
labelPadding: EdgeInsets.lerp(a?.labelPadding, b?.labelPadding, t), |
|||
padding: EdgeInsets.lerp(a?.padding, b?.padding, t), |
|||
shape: ShapeBorder.lerp(a?.shape, b?.shape, t), |
|||
labelStyle: TextStyle.lerp(a?.labelStyle, b?.labelStyle, t), |
|||
secondaryLabelStyle: TextStyle.lerp(a?.secondaryLabelStyle, b?.secondaryLabelStyle, t), |
|||
brightness: t < 0.5f ? a?.brightness ?? Brightness.light : b?.brightness ?? Brightness.light, |
|||
elevation: MathUtils.lerpFloat(a?.elevation ?? 0.0f, b?.elevation ?? 0.0f, t), |
|||
pressElevation: MathUtils.lerpFloat(a?.pressElevation ?? 0.0f, b?.pressElevation ?? 0.0f, t) |
|||
); |
|||
} |
|||
|
|||
public override int GetHashCode() { |
|||
var hashCode = backgroundColor.GetHashCode(); |
|||
hashCode = (hashCode * 397) ^ deleteIconColor.GetHashCode(); |
|||
hashCode = (hashCode * 397) ^ disabledColor.GetHashCode(); |
|||
hashCode = (hashCode * 397) ^ selectedColor.GetHashCode(); |
|||
hashCode = (hashCode * 397) ^ secondarySelectedColor.GetHashCode(); |
|||
hashCode = (hashCode * 397) ^ shadowColor?.GetHashCode() ?? 0; |
|||
hashCode = (hashCode * 397) ^ selectedShadowColor?.GetHashCode() ?? 0; |
|||
hashCode = (hashCode * 397) ^ labelPadding.GetHashCode(); |
|||
hashCode = (hashCode * 397) ^ padding.GetHashCode(); |
|||
hashCode = (hashCode * 397) ^ shape.GetHashCode(); |
|||
hashCode = (hashCode * 397) ^ labelStyle.GetHashCode(); |
|||
hashCode = (hashCode * 397) ^ secondaryLabelStyle.GetHashCode(); |
|||
hashCode = (hashCode * 397) ^ brightness.GetHashCode(); |
|||
hashCode = (hashCode * 397) ^ elevation.GetHashCode(); |
|||
hashCode = (hashCode * 397) ^ pressElevation.GetHashCode(); |
|||
return hashCode; |
|||
} |
|||
|
|||
public bool Equals(ChipThemeData other) { |
|||
return other.backgroundColor == backgroundColor |
|||
&& other.deleteIconColor == deleteIconColor |
|||
&& other.disabledColor == disabledColor |
|||
&& other.selectedColor == selectedColor |
|||
&& other.secondarySelectedColor == secondarySelectedColor |
|||
&& other.shadowColor == shadowColor |
|||
&& other.selectedShadowColor == selectedShadowColor |
|||
&& other.labelPadding == labelPadding |
|||
&& other.padding == padding |
|||
&& other.shape == shape |
|||
&& other.labelStyle == labelStyle |
|||
&& other.secondaryLabelStyle == secondaryLabelStyle |
|||
&& other.brightness == brightness |
|||
&& other.elevation == elevation |
|||
&& other.pressElevation == pressElevation; |
|||
} |
|||
|
|||
public override bool Equals(object obj) { |
|||
if (ReferenceEquals(null, obj)) { |
|||
return false; |
|||
} |
|||
|
|||
if (ReferenceEquals(this, obj)) { |
|||
return true; |
|||
} |
|||
|
|||
if (obj.GetType() != GetType()) { |
|||
return false; |
|||
} |
|||
|
|||
return Equals((ChipThemeData) obj); |
|||
} |
|||
|
|||
public static bool operator ==(ChipThemeData left, ChipThemeData right) { |
|||
return Equals(left, right); |
|||
} |
|||
|
|||
public static bool operator !=(ChipThemeData left, ChipThemeData right) { |
|||
return !Equals(left, right); |
|||
} |
|||
|
|||
public override void debugFillProperties(DiagnosticPropertiesBuilder properties) { |
|||
base.debugFillProperties(properties); |
|||
ThemeData defaultTheme = ThemeData.fallback(); |
|||
ChipThemeData defaultData = fromDefaults( |
|||
secondaryColor: defaultTheme.primaryColor, |
|||
brightness: defaultTheme.brightness, |
|||
labelStyle: defaultTheme.textTheme.body2 |
|||
); |
|||
properties.add(new DiagnosticsProperty<Color>("backgroundColor", backgroundColor, |
|||
defaultValue: defaultData.backgroundColor)); |
|||
properties.add(new DiagnosticsProperty<Color>("deleteIconColor", deleteIconColor, |
|||
defaultValue: defaultData.deleteIconColor)); |
|||
properties.add(new DiagnosticsProperty<Color>("disabledColor", disabledColor, |
|||
defaultValue: defaultData.disabledColor)); |
|||
properties.add(new DiagnosticsProperty<Color>("selectedColor", selectedColor, |
|||
defaultValue: defaultData.selectedColor)); |
|||
properties.add(new DiagnosticsProperty<Color>("secondarySelectedColor", secondarySelectedColor, |
|||
defaultValue: defaultData.secondarySelectedColor)); |
|||
properties.add(new DiagnosticsProperty<Color>("shadowColor", shadowColor, |
|||
defaultValue: defaultData.shadowColor)); |
|||
properties.add(new DiagnosticsProperty<Color>("selectedShadowColor", selectedShadowColor, |
|||
defaultValue: defaultData.selectedShadowColor)); |
|||
properties.add(new DiagnosticsProperty<EdgeInsets>("labelPadding", labelPadding, |
|||
defaultValue: defaultData.labelPadding)); |
|||
properties.add( |
|||
new DiagnosticsProperty<EdgeInsets>("padding", padding, defaultValue: defaultData.padding)); |
|||
properties.add(new DiagnosticsProperty<ShapeBorder>("shape", shape, defaultValue: defaultData.shape)); |
|||
properties.add(new DiagnosticsProperty<TextStyle>("labelStyle", labelStyle, |
|||
defaultValue: defaultData.labelStyle)); |
|||
properties.add(new DiagnosticsProperty<TextStyle>("secondaryLabelStyle", secondaryLabelStyle, |
|||
defaultValue: defaultData.secondaryLabelStyle)); |
|||
properties.add(new EnumProperty<Brightness?>("brightness", brightness, |
|||
defaultValue: defaultData.brightness)); |
|||
properties.add(new FloatProperty("elevation", elevation, defaultValue: defaultData.elevation)); |
|||
properties.add(new FloatProperty("pressElevation", pressElevation, |
|||
defaultValue: defaultData.pressElevation)); |
|||
} |
|||
} |
|||
} |
|
|||
fileFormatVersion: 2 |
|||
guid: 4d46bfb5d5bb492e92f07114849df905 |
|||
timeCreated: 1556165564 |
|
|||
using Unity.UIWidgets.foundation; |
|||
using Unity.UIWidgets.material; |
|||
using Unity.UIWidgets.painting; |
|||
using Unity.UIWidgets.rendering; |
|||
using Unity.UIWidgets.service; |
|||
using Unity.UIWidgets.ui; |
|||
using Unity.UIWidgets.widgets; |
|||
using TextStyle = Unity.UIWidgets.painting.TextStyle; |
|||
|
|||
namespace UIWidgetsGallery.gallery { |
|||
public class CircleAvatar : StatelessWidget { |
|||
public CircleAvatar( |
|||
Key key = null, |
|||
Widget child = null, |
|||
Color backgroundColor = null, |
|||
ImageProvider backgroundImage = null, |
|||
Color foregroundColor = null, |
|||
float? radius = null, |
|||
float? minRadius = null, |
|||
float? maxRadius = null |
|||
) : base(key: key) { |
|||
D.assert(radius == null || (minRadius == null && maxRadius == null)); |
|||
this.child = child; |
|||
this.backgroundColor = backgroundColor; |
|||
this.backgroundImage = backgroundImage; |
|||
this.foregroundColor = foregroundColor; |
|||
this.radius = radius; |
|||
this.minRadius = minRadius; |
|||
this.maxRadius = maxRadius; |
|||
} |
|||
|
|||
public readonly Widget child; |
|||
|
|||
public readonly Color backgroundColor; |
|||
|
|||
public readonly Color foregroundColor; |
|||
|
|||
public readonly ImageProvider backgroundImage; |
|||
|
|||
public readonly float? radius; |
|||
|
|||
public readonly float? minRadius; |
|||
|
|||
public readonly float? maxRadius; |
|||
|
|||
const float _defaultRadius = 20.0f; |
|||
|
|||
const float _defaultMinRadius = 0.0f; |
|||
|
|||
const float _defaultMaxRadius = float.PositiveInfinity; |
|||
|
|||
float _minDiameter { |
|||
get { |
|||
if (radius == null && minRadius == null && maxRadius == null) { |
|||
return _defaultRadius * 2.0f; |
|||
} |
|||
|
|||
return 2.0f * (radius ?? minRadius ?? _defaultMinRadius); |
|||
} |
|||
} |
|||
|
|||
float _maxDiameter { |
|||
get { |
|||
if (radius == null && minRadius == null && maxRadius == null) { |
|||
return _defaultRadius * 2.0f; |
|||
} |
|||
|
|||
return 2.0f * (radius ?? maxRadius ?? _defaultMaxRadius); |
|||
} |
|||
} |
|||
|
|||
public override Widget build(BuildContext context) { |
|||
D.assert(WidgetsD.debugCheckHasMediaQuery(context)); |
|||
ThemeData theme = Theme.of(context); |
|||
TextStyle textStyle = theme.primaryTextTheme.subhead.copyWith(color: foregroundColor); |
|||
Color effectiveBackgroundColor = backgroundColor; |
|||
if (effectiveBackgroundColor == null) { |
|||
switch (ThemeData.estimateBrightnessForColor(textStyle.color)) { |
|||
case Brightness.dark: |
|||
effectiveBackgroundColor = theme.primaryColorLight; |
|||
break; |
|||
case Brightness.light: |
|||
effectiveBackgroundColor = theme.primaryColorDark; |
|||
break; |
|||
} |
|||
} |
|||
else if (foregroundColor == null) { |
|||
switch (ThemeData.estimateBrightnessForColor(backgroundColor)) { |
|||
case Brightness.dark: |
|||
textStyle = textStyle.copyWith(color: theme.primaryColorLight); |
|||
break; |
|||
case Brightness.light: |
|||
textStyle = textStyle.copyWith(color: theme.primaryColorDark); |
|||
break; |
|||
} |
|||
} |
|||
|
|||
float minDiameter = _minDiameter; |
|||
float maxDiameter = _maxDiameter; |
|||
return new AnimatedContainer( |
|||
constraints: new BoxConstraints( |
|||
minHeight: minDiameter, |
|||
minWidth: minDiameter, |
|||
maxWidth: maxDiameter, |
|||
maxHeight: maxDiameter |
|||
), |
|||
duration: Constants.kThemeChangeDuration, |
|||
decoration: new BoxDecoration( |
|||
color: effectiveBackgroundColor, |
|||
image: backgroundImage != null |
|||
? new DecorationImage(image: backgroundImage, fit: BoxFit.cover) |
|||
: null, |
|||
shape: BoxShape.circle |
|||
), |
|||
child: child == null |
|||
? null |
|||
: new Center( |
|||
child: new MediaQuery( |
|||
data: MediaQuery.of(context).copyWith(textScaleFactor: 1.0f), |
|||
child: new IconTheme( |
|||
data: theme.iconTheme.copyWith(color: textStyle.color), |
|||
child: new DefaultTextStyle( |
|||
style: textStyle, |
|||
child: child |
|||
) |
|||
) |
|||
) |
|||
) |
|||
); |
|||
} |
|||
} |
|||
} |
|
|||
fileFormatVersion: 2 |
|||
guid: 32591e65e11049cab124c86bc8fe573c |
|||
timeCreated: 1556169017 |
|
|||
using System; |
|||
using Unity.UIWidgets.foundation; |
|||
using Unity.UIWidgets.service; |
|||
using Unity.UIWidgets.ui; |
|||
|
|||
namespace Unity.UIWidgets.material { |
|||
public class ColorScheme : Diagnosticable, IEquatable<ColorScheme> { |
|||
public ColorScheme( |
|||
Color primary, |
|||
Color primaryVariant, |
|||
Color secondary, |
|||
Color secondaryVariant, |
|||
Color surface, |
|||
Color background, |
|||
Color error, |
|||
Color onPrimary, |
|||
Color onSecondary, |
|||
Color onSurface, |
|||
Color onBackground, |
|||
Color onError, |
|||
Brightness brightness) { |
|||
D.assert(primary != null); |
|||
D.assert(primaryVariant != null); |
|||
D.assert(secondary != null); |
|||
D.assert(secondaryVariant != null); |
|||
D.assert(surface != null); |
|||
D.assert(background != null); |
|||
D.assert(error != null); |
|||
D.assert(onPrimary != null); |
|||
D.assert(onSecondary != null); |
|||
D.assert(onSurface != null); |
|||
D.assert(onBackground != null); |
|||
D.assert(onError != null); |
|||
|
|||
this.primary = primary; |
|||
this.primaryVariant = primaryVariant; |
|||
this.secondary = secondary; |
|||
this.secondaryVariant = secondaryVariant; |
|||
this.surface = surface; |
|||
this.background = background; |
|||
this.error = error; |
|||
this.onPrimary = onPrimary; |
|||
this.onSecondary = onSecondary; |
|||
this.onSurface = onSurface; |
|||
this.onBackground = onBackground; |
|||
this.onError = onError; |
|||
this.brightness = brightness; |
|||
} |
|||
|
|||
public static ColorScheme light( |
|||
Color primary = null, |
|||
Color primaryVariant = null, |
|||
Color secondary = null, |
|||
Color secondaryVariant = null, |
|||
Color surface = null, |
|||
Color background = null, |
|||
Color error = null, |
|||
Color onPrimary = null, |
|||
Color onSecondary = null, |
|||
Color onSurface = null, |
|||
Color onBackground = null, |
|||
Color onError = null, |
|||
Brightness brightness = Brightness.light |
|||
) { |
|||
primary = primary ?? new Color(0xFF6200EE); |
|||
primaryVariant = primaryVariant ?? new Color(0xFF3700B3); |
|||
secondary = secondary ?? new Color(0xFF03DAC6); |
|||
secondaryVariant = secondaryVariant ?? new Color(0xFF018786); |
|||
surface = surface ?? Colors.white; |
|||
background = background ?? Colors.white; |
|||
error = error ?? new Color(0xFFB00020); |
|||
onPrimary = onPrimary ?? Colors.white; |
|||
onSecondary = onSecondary ?? Colors.black; |
|||
onSurface = onSurface ?? Colors.black; |
|||
onBackground = onBackground ?? Colors.black; |
|||
onError = onError ?? Colors.white; |
|||
|
|||
return new ColorScheme( |
|||
primary: primary, |
|||
primaryVariant: primaryVariant, |
|||
secondary: secondary, |
|||
secondaryVariant: secondaryVariant, |
|||
surface: surface, |
|||
background: background, |
|||
error: error, |
|||
onPrimary: onPrimary, |
|||
onSecondary: onSecondary, |
|||
onSurface: onSurface, |
|||
onBackground: onBackground, |
|||
onError: onError, |
|||
brightness: brightness |
|||
); |
|||
} |
|||
|
|||
public static ColorScheme dark( |
|||
Color primary = null, |
|||
Color primaryVariant = null, |
|||
Color secondary = null, |
|||
Color secondaryVariant = null, |
|||
Color surface = null, |
|||
Color background = null, |
|||
Color error = null, |
|||
Color onPrimary = null, |
|||
Color onSecondary = null, |
|||
Color onSurface = null, |
|||
Color onBackground = null, |
|||
Color onError = null, |
|||
Brightness brightness = Brightness.dark |
|||
) { |
|||
primary = primary ?? new Color(0xFFBB86FC); |
|||
primaryVariant = primaryVariant ?? new Color(0xFF4B01D0); |
|||
secondary = secondary ?? new Color(0xFF03DAC6); |
|||
secondaryVariant = secondaryVariant ?? new Color(0xFF03DAC6); |
|||
surface = surface ?? Colors.black; |
|||
background = background ?? Colors.black; |
|||
error = error ?? new Color(0xFFB00020); |
|||
onPrimary = onPrimary ?? Colors.black; |
|||
onSecondary = onSecondary ?? Colors.black; |
|||
onSurface = onSurface ?? Colors.white; |
|||
onBackground = onBackground ?? Colors.white; |
|||
onError = onError ?? Colors.black; |
|||
|
|||
return new ColorScheme( |
|||
primary: primary, |
|||
primaryVariant: primaryVariant, |
|||
secondary: secondary, |
|||
secondaryVariant: secondaryVariant, |
|||
surface: surface, |
|||
background: background, |
|||
error: error, |
|||
onPrimary: onPrimary, |
|||
onSecondary: onSecondary, |
|||
onSurface: onSurface, |
|||
onBackground: onBackground, |
|||
onError: onError, |
|||
brightness: brightness |
|||
); |
|||
} |
|||
|
|||
public static ColorScheme fromSwatch( |
|||
MaterialColor primarySwatch = null, |
|||
Color primaryColorDark = null, |
|||
Color accentColor = null, |
|||
Color cardColor = null, |
|||
Color backgroundColor = null, |
|||
Color errorColor = null, |
|||
Brightness? brightness = Brightness.light) { |
|||
D.assert(brightness != null); |
|||
primarySwatch = primarySwatch ?? Colors.blue; |
|||
|
|||
bool isDark = brightness == Brightness.dark; |
|||
bool primaryIsDark = _brightnessFor(primarySwatch) == Brightness.dark; |
|||
Color secondary = accentColor ?? (isDark ? Colors.tealAccent[200] : primarySwatch); |
|||
bool secondaryIsDark = _brightnessFor(secondary) == Brightness.dark; |
|||
|
|||
return new ColorScheme( |
|||
primary: primarySwatch, |
|||
primaryVariant: primaryColorDark ?? (isDark ? Colors.black : primarySwatch[700]), |
|||
secondary: secondary, |
|||
secondaryVariant: isDark ? Colors.tealAccent[700] : primarySwatch[700], |
|||
surface: cardColor ?? (isDark ? Colors.grey[800] : Colors.white), |
|||
background: backgroundColor ?? (isDark ? Colors.grey[700] : primarySwatch[200]), |
|||
error: errorColor ?? Colors.red[700], |
|||
onPrimary: primaryIsDark ? Colors.white : Colors.black, |
|||
onSecondary: secondaryIsDark ? Colors.white : Colors.black, |
|||
onSurface: isDark ? Colors.white : Colors.black, |
|||
onBackground: primaryIsDark ? Colors.white : Colors.black, |
|||
onError: isDark ? Colors.black : Colors.white, |
|||
brightness: brightness ?? Brightness.light |
|||
); |
|||
} |
|||
|
|||
|
|||
static Brightness _brightnessFor(Color color) { |
|||
return ThemeData.estimateBrightnessForColor(color); |
|||
} |
|||
|
|||
|
|||
public readonly Color primary; |
|||
|
|||
public readonly Color primaryVariant; |
|||
|
|||
public readonly Color secondary; |
|||
|
|||
public readonly Color secondaryVariant; |
|||
|
|||
public readonly Color surface; |
|||
|
|||
public readonly Color background; |
|||
|
|||
public readonly Color error; |
|||
|
|||
public readonly Color onPrimary; |
|||
|
|||
public readonly Color onSecondary; |
|||
|
|||
public readonly Color onSurface; |
|||
|
|||
public readonly Color onBackground; |
|||
|
|||
public readonly Color onError; |
|||
|
|||
public readonly Brightness brightness; |
|||
|
|||
public ColorScheme copyWith( |
|||
Color primary = null, |
|||
Color primaryVariant = null, |
|||
Color secondary = null, |
|||
Color secondaryVariant = null, |
|||
Color surface = null, |
|||
Color background = null, |
|||
Color error = null, |
|||
Color onPrimary = null, |
|||
Color onSecondary = null, |
|||
Color onSurface = null, |
|||
Color onBackground = null, |
|||
Color onError = null, |
|||
Brightness? brightness = null) { |
|||
return new ColorScheme( |
|||
primary: primary ?? this.primary, |
|||
primaryVariant: primaryVariant ?? this.primaryVariant, |
|||
secondary: secondary ?? this.secondary, |
|||
secondaryVariant: secondaryVariant ?? this.secondaryVariant, |
|||
surface: surface ?? this.surface, |
|||
background: background ?? this.background, |
|||
error: error ?? this.error, |
|||
onPrimary: onPrimary ?? this.onPrimary, |
|||
onSecondary: onSecondary ?? this.onSecondary, |
|||
onSurface: onSurface ?? this.onSurface, |
|||
onBackground: onBackground ?? this.onBackground, |
|||
onError: onError ?? this.onError, |
|||
brightness: brightness ?? this.brightness |
|||
); |
|||
} |
|||
|
|||
public static ColorScheme lerp(ColorScheme a, ColorScheme b, float t) { |
|||
return new ColorScheme( |
|||
primary: Color.lerp(a.primary, b.primary, t), |
|||
primaryVariant: Color.lerp(a.primaryVariant, b.primaryVariant, t), |
|||
secondary: Color.lerp(a.secondary, b.secondary, t), |
|||
secondaryVariant: Color.lerp(a.secondaryVariant, b.secondaryVariant, t), |
|||
surface: Color.lerp(a.surface, b.surface, t), |
|||
background: Color.lerp(a.background, b.background, t), |
|||
error: Color.lerp(a.error, b.error, t), |
|||
onPrimary: Color.lerp(a.onPrimary, b.onPrimary, t), |
|||
onSecondary: Color.lerp(a.onSecondary, b.onSecondary, t), |
|||
onSurface: Color.lerp(a.onSurface, b.onSurface, t), |
|||
onBackground: Color.lerp(a.onBackground, b.onBackground, t), |
|||
onError: Color.lerp(a.onError, b.onError, t), |
|||
brightness: t < 0.5 ? a.brightness : b.brightness |
|||
); |
|||
} |
|||
|
|||
|
|||
public bool Equals(ColorScheme other) { |
|||
if (ReferenceEquals(null, other)) { |
|||
return false; |
|||
} |
|||
|
|||
if (ReferenceEquals(this, other)) { |
|||
return true; |
|||
} |
|||
|
|||
return other.primary == primary |
|||
&& other.primaryVariant == primaryVariant |
|||
&& other.secondary == secondary |
|||
&& other.secondaryVariant == secondaryVariant |
|||
&& other.surface == surface |
|||
&& other.background == background |
|||
&& other.error == error |
|||
&& other.onPrimary == onPrimary |
|||
&& other.onSecondary == onSecondary |
|||
&& other.onSurface == onSurface |
|||
&& other.onBackground == onBackground |
|||
&& other.onError == onError |
|||
&& other.brightness == brightness; |
|||
} |
|||
|
|||
public override bool Equals(object obj) { |
|||
if (ReferenceEquals(null, obj)) { |
|||
return false; |
|||
} |
|||
|
|||
if (ReferenceEquals(this, obj)) { |
|||
return true; |
|||
} |
|||
|
|||
if (obj.GetType() != GetType()) { |
|||
return false; |
|||
} |
|||
|
|||
return Equals((ColorScheme) obj); |
|||
} |
|||
|
|||
public static bool operator ==(ColorScheme left, ColorScheme right) { |
|||
return Equals(left, right); |
|||
} |
|||
|
|||
public static bool operator !=(ColorScheme left, ColorScheme right) { |
|||
return !Equals(left, right); |
|||
} |
|||
|
|||
public override int GetHashCode() { |
|||
unchecked { |
|||
var hashCode = primary.GetHashCode(); |
|||
hashCode = (hashCode * 397) ^ primaryVariant.GetHashCode(); |
|||
hashCode = (hashCode * 397) ^ secondary.GetHashCode(); |
|||
hashCode = (hashCode * 397) ^ secondaryVariant.GetHashCode(); |
|||
hashCode = (hashCode * 397) ^ surface.GetHashCode(); |
|||
hashCode = (hashCode * 397) ^ background.GetHashCode(); |
|||
hashCode = (hashCode * 397) ^ error.GetHashCode(); |
|||
hashCode = (hashCode * 397) ^ onPrimary.GetHashCode(); |
|||
hashCode = (hashCode * 397) ^ onSecondary.GetHashCode(); |
|||
hashCode = (hashCode * 397) ^ onSurface.GetHashCode(); |
|||
hashCode = (hashCode * 397) ^ onBackground.GetHashCode(); |
|||
hashCode = (hashCode * 397) ^ onError.GetHashCode(); |
|||
hashCode = (hashCode * 397) ^ brightness.GetHashCode(); |
|||
return hashCode; |
|||
} |
|||
} |
|||
|
|||
public override void debugFillProperties(DiagnosticPropertiesBuilder properties) { |
|||
base.debugFillProperties(properties); |
|||
ColorScheme defaultScheme = light(); |
|||
properties.add(new DiagnosticsProperty<Color>("primary", primary, |
|||
defaultValue: defaultScheme.primary)); |
|||
properties.add(new DiagnosticsProperty<Color>("primaryVariant", primaryVariant, |
|||
defaultValue: defaultScheme.primaryVariant)); |
|||
properties.add(new DiagnosticsProperty<Color>("secondary", secondary, |
|||
defaultValue: defaultScheme.secondary)); |
|||
properties.add(new DiagnosticsProperty<Color>("secondaryVariant", secondaryVariant, |
|||
defaultValue: defaultScheme.secondaryVariant)); |
|||
properties.add(new DiagnosticsProperty<Color>("surface", surface, |
|||
defaultValue: defaultScheme.surface)); |
|||
properties.add(new DiagnosticsProperty<Color>("background", background, |
|||
defaultValue: defaultScheme.background)); |
|||
properties.add(new DiagnosticsProperty<Color>("error", error, defaultValue: defaultScheme.error)); |
|||
properties.add(new DiagnosticsProperty<Color>("onPrimary", onPrimary, |
|||
defaultValue: defaultScheme.onPrimary)); |
|||
properties.add(new DiagnosticsProperty<Color>("onSecondary", onSecondary, |
|||
defaultValue: defaultScheme.onSecondary)); |
|||
properties.add(new DiagnosticsProperty<Color>("onSurface", onSurface, |
|||
defaultValue: defaultScheme.onSurface)); |
|||
properties.add(new DiagnosticsProperty<Color>("onBackground", onBackground, |
|||
defaultValue: defaultScheme.onBackground)); |
|||
properties.add(new DiagnosticsProperty<Color>("onError", onError, |
|||
defaultValue: defaultScheme.onError)); |
|||
properties.add(new DiagnosticsProperty<Brightness>("brightness", brightness, |
|||
defaultValue: defaultScheme.brightness)); |
|||
} |
|||
} |
|||
} |
|
|||
fileFormatVersion: 2 |
|||
guid: a610420b7a8ec44bfa84e81a1e5ff449 |
|||
MonoImporter: |
|||
externalObjects: {} |
|||
serializedVersion: 2 |
|||
defaultReferences: [] |
|||
executionOrder: 0 |
|||
icon: {instanceID: 0} |
|||
userData: |
|||
assetBundleName: |
|||
assetBundleVariant: |
|
|||
using System.Collections.Generic; |
|||
using Unity.UIWidgets.painting; |
|||
using Unity.UIWidgets.ui; |
|||
|
|||
namespace uiwidgets { |
|||
public class MaterialColor : ColorSwatch<uint> { |
|||
public MaterialColor(uint primary, Dictionary<uint, Color> swatch) : base(primary, swatch) { |
|||
} |
|||
|
|||
public Color shade50 { |
|||
get => this[50]; |
|||
} |
|||
|
|||
public Color shade100 { |
|||
get => this[100]; |
|||
} |
|||
|
|||
public Color shade200 { |
|||
get => this[200]; |
|||
} |
|||
|
|||
public Color shade300 { |
|||
get => this[300]; |
|||
} |
|||
|
|||
public Color shade400 { |
|||
get => this[400]; |
|||
} |
|||
|
|||
public Color shade500 { |
|||
get => this[500]; |
|||
} |
|||
|
|||
public Color shade600 { |
|||
get => this[600]; |
|||
} |
|||
|
|||
public Color shade700 { |
|||
get => this[700]; |
|||
} |
|||
|
|||
public Color shade800 { |
|||
get => this[800]; |
|||
} |
|||
|
|||
public Color shade900 { |
|||
get => this[900]; |
|||
} |
|||
} |
|||
|
|||
public class MaterialAccentColor : ColorSwatch<uint> { |
|||
public MaterialAccentColor(uint primary, Dictionary<uint, Color> swatch) : base(primary, swatch) { |
|||
} |
|||
|
|||
public Color shade50 { |
|||
get => this[50]; |
|||
} |
|||
|
|||
public Color shade100 { |
|||
get => this[100]; |
|||
} |
|||
|
|||
public Color shade200 { |
|||
get => this[200]; |
|||
} |
|||
|
|||
public Color shade400 { |
|||
get => this[400]; |
|||
} |
|||
|
|||
public Color shade700 { |
|||
get => this[700]; |
|||
} |
|||
} |
|||
|
|||
public class Colors { |
|||
private Colors() { |
|||
} |
|||
|
|||
public static Color transparent = new Color(0x00000000); |
|||
|
|||
public static Color black = new Color(0xFF000000); |
|||
|
|||
public static Color black87 = new Color(0xDD000000); |
|||
|
|||
public static Color black54 = new Color(0x8A000000); |
|||
|
|||
public static Color black45 = new Color(0x73000000); |
|||
|
|||
public static Color black38 = new Color(0x61000000); |
|||
|
|||
public static Color black26 = new Color(0x42000000); |
|||
|
|||
public static Color black12 = new Color(0x1F000000); |
|||
|
|||
public static Color white = new Color(0xFFFFFFFF); |
|||
|
|||
public static Color white70 = new Color(0xB3FFFFFF); |
|||
|
|||
public static Color white60 = new Color(0x99FFFFFF); |
|||
|
|||
public static Color white54 = new Color(0x8AFFFFFF); |
|||
|
|||
public static Color white38 = new Color(0x62FFFFFF); |
|||
|
|||
public static Color white30 = new Color(0x4DFFFFFF); |
|||
|
|||
public static Color white24 = new Color(0x3DFFFFFF); |
|||
|
|||
public static Color white12 = new Color(0x1FFFFFFF); |
|||
|
|||
public static Color white10 = new Color(0x1AFFFFFF); |
|||
|
|||
public static readonly MaterialColor red = new MaterialColor( |
|||
_redPrimaryValue, |
|||
new Dictionary<uint, Color>() { |
|||
{50, new Color(0xFFFFEBEE)}, |
|||
{100, new Color(0xFFFFCDD2)}, |
|||
{200, new Color(0xFFEF9A9A)}, |
|||
{300, new Color(0xFFE57373)}, |
|||
{400, new Color(0xFFEF5350)}, |
|||
{500, new Color(_redPrimaryValue)}, |
|||
{600, new Color(0xFFE53935)}, |
|||
{700, new Color(0xFFD32F2F)}, |
|||
{800, new Color(0xFFC62828)}, |
|||
{900, new Color(0xFFB71C1C)}, |
|||
} |
|||
); |
|||
|
|||
const uint _redPrimaryValue = 0xFFF44336; |
|||
|
|||
public static readonly MaterialAccentColor redAccent = new MaterialAccentColor( |
|||
_redAccentValue, |
|||
new Dictionary<uint, Color>() { |
|||
{100, new Color(0xFFFF8A80)}, |
|||
{200, new Color(_redAccentValue)}, |
|||
{400, new Color(0xFFFF1744)}, |
|||
{700, new Color(0xFFD50000)}, |
|||
} |
|||
); |
|||
|
|||
const uint _redAccentValue = 0xFFFF5252; |
|||
|
|||
public static readonly MaterialColor pink = new MaterialColor( |
|||
_pinkPrimaryValue, |
|||
new Dictionary<uint, Color>() { |
|||
{50, new Color(0xFFFCE4EC)}, |
|||
{100, new Color(0xFFF8BBD0)}, |
|||
{200, new Color(0xFFF48FB1)}, |
|||
{300, new Color(0xFFF06292)}, |
|||
{400, new Color(0xFFEC407A)}, |
|||
{500, new Color(_pinkPrimaryValue)}, |
|||
{600, new Color(0xFFD81B60)}, |
|||
{700, new Color(0xFFC2185B)}, |
|||
{800, new Color(0xFFAD1457)}, |
|||
{900, new Color(0xFF880E4F)}, |
|||
} |
|||
); |
|||
|
|||
const uint _pinkPrimaryValue = 0xFFE91E63; |
|||
|
|||
public static readonly MaterialAccentColor pinkAccent = new MaterialAccentColor( |
|||
_pinkAccentPrimaryValue, |
|||
new Dictionary<uint, Color>() { |
|||
{100, new Color(0xFFFF80AB)}, |
|||
{200, new Color(_pinkAccentPrimaryValue)}, |
|||
{400, new Color(0xFFF50057)}, |
|||
{700, new Color(0xFFC51162)}, |
|||
} |
|||
); |
|||
|
|||
const uint _pinkAccentPrimaryValue = 0xFFFF4081; |
|||
|
|||
public static readonly MaterialColor purple = new MaterialColor( |
|||
_purplePrimaryValue, |
|||
new Dictionary<uint, Color>() { |
|||
{50, new Color(0xFFF3E5F5)}, |
|||
{100, new Color(0xFFE1BEE7)}, |
|||
{200, new Color(0xFFCE93D8)}, |
|||
{300, new Color(0xFFBA68C8)}, |
|||
{400, new Color(0xFFAB47BC)}, |
|||
{500, new Color(_purplePrimaryValue)}, |
|||
{600, new Color(0xFF8E24AA)}, |
|||
{700, new Color(0xFF7B1FA2)}, |
|||
{800, new Color(0xFF6A1B9A)}, |
|||
{900, new Color(0xFF4A148C)}, |
|||
} |
|||
); |
|||
|
|||
const uint _purplePrimaryValue = 0xFF9C27B0; |
|||
|
|||
public static readonly MaterialAccentColor purpleAccent = new MaterialAccentColor( |
|||
_purpleAccentPrimaryValue, |
|||
new Dictionary<uint, Color>() { |
|||
{100, new Color(0xFFEA80FC)}, |
|||
{200, new Color(_purpleAccentPrimaryValue)}, |
|||
{400, new Color(0xFFD500F9)}, |
|||
{700, new Color(0xFFAA00FF)}, |
|||
} |
|||
); |
|||
|
|||
const uint _purpleAccentPrimaryValue = 0xFFE040FB; |
|||
|
|||
public static readonly MaterialColor deepPurple = new MaterialColor( |
|||
_deepPurplePrimaryValue, |
|||
new Dictionary<uint, Color>() { |
|||
{50, new Color(0xFFEDE7F6)}, |
|||
{100, new Color(0xFFD1C4E9)}, |
|||
{200, new Color(0xFFB39DDB)}, |
|||
{300, new Color(0xFF9575CD)}, |
|||
{400, new Color(0xFF7E57C2)}, |
|||
{500, new Color(_deepPurplePrimaryValue)}, |
|||
{600, new Color(0xFF5E35B1)}, |
|||
{700, new Color(0xFF512DA8)}, |
|||
{800, new Color(0xFF4527A0)}, |
|||
{900, new Color(0xFF311B92)}, |
|||
} |
|||
); |
|||
|
|||
const uint _deepPurplePrimaryValue = 0xFF673AB7; |
|||
|
|||
public static readonly MaterialAccentColor deepPurpleAccent = new MaterialAccentColor( |
|||
_deepPurpleAccentPrimaryValue, |
|||
new Dictionary<uint, Color>() { |
|||
{100, new Color(0xFFB388FF)}, |
|||
{200, new Color(_deepPurpleAccentPrimaryValue)}, |
|||
{400, new Color(0xFF651FFF)}, |
|||
{700, new Color(0xFF6200EA)}, |
|||
} |
|||
); |
|||
|
|||
const uint _deepPurpleAccentPrimaryValue = 0xFF7C4DFF; |
|||
|
|||
public static readonly MaterialColor indigo = new MaterialColor( |
|||
_indigoPrimaryValue, |
|||
new Dictionary<uint, Color>() { |
|||
{50, new Color(0xFFE8EAF6)}, |
|||
{100, new Color(0xFFC5CAE9)}, |
|||
{200, new Color(0xFF9FA8DA)}, |
|||
{300, new Color(0xFF7986CB)}, |
|||
{400, new Color(0xFF5C6BC0)}, |
|||
{500, new Color(_indigoPrimaryValue)}, |
|||
{600, new Color(0xFF3949AB)}, |
|||
{700, new Color(0xFF303F9F)}, |
|||
{800, new Color(0xFF283593)}, |
|||
{900, new Color(0xFF1A237E)}, |
|||
} |
|||
); |
|||
|
|||
const uint _indigoPrimaryValue = 0xFF3F51B5; |
|||
|
|||
public static readonly MaterialAccentColor indigoAccent = new MaterialAccentColor( |
|||
_indigoAccentPrimaryValue, |
|||
new Dictionary<uint, Color>() { |
|||
{100, new Color(0xFF8C9EFF)}, |
|||
{200, new Color(_indigoAccentPrimaryValue)}, |
|||
{400, new Color(0xFF3D5AFE)}, |
|||
{700, new Color(0xFF304FFE)}, |
|||
} |
|||
); |
|||
|
|||
const uint _indigoAccentPrimaryValue = 0xFF536DFE; |
|||
|
|||
public static readonly MaterialColor blue = new MaterialColor( |
|||
_bluePrimaryValue, |
|||
new Dictionary<uint, Color>() { |
|||
{50, new Color(0xFFE3F2FD)}, |
|||
{100, new Color(0xFFBBDEFB)}, |
|||
{200, new Color(0xFF90CAF9)}, |
|||
{300, new Color(0xFF64B5F6)}, |
|||
{400, new Color(0xFF42A5F5)}, |
|||
{500, new Color(_bluePrimaryValue)}, |
|||
{600, new Color(0xFF1E88E5)}, |
|||
{700, new Color(0xFF1976D2)}, |
|||
{800, new Color(0xFF1565C0)}, |
|||
{900, new Color(0xFF0D47A1)}, |
|||
} |
|||
); |
|||
|
|||
const uint _bluePrimaryValue = 0xFF2196F3; |
|||
|
|||
public static readonly MaterialAccentColor blueAccent = new MaterialAccentColor( |
|||
_blueAccentPrimaryValue, |
|||
new Dictionary<uint, Color>() { |
|||
{100, new Color(0xFF82B1FF)}, |
|||
{200, new Color(_blueAccentPrimaryValue)}, |
|||
{400, new Color(0xFF2979FF)}, |
|||
{700, new Color(0xFF2962FF)}, |
|||
} |
|||
); |
|||
|
|||
const uint _blueAccentPrimaryValue = 0xFF448AFF; |
|||
|
|||
public static readonly MaterialColor lightBlue = new MaterialColor( |
|||
_lightBluePrimaryValue, |
|||
new Dictionary<uint, Color>() { |
|||
{50, new Color(0xFFE1F5FE)}, |
|||
{100, new Color(0xFFB3E5FC)}, |
|||
{200, new Color(0xFF81D4FA)}, |
|||
{300, new Color(0xFF4FC3F7)}, |
|||
{400, new Color(0xFF29B6F6)}, |
|||
{500, new Color(_lightBluePrimaryValue)}, |
|||
{600, new Color(0xFF039BE5)}, |
|||
{700, new Color(0xFF0288D1)}, |
|||
{800, new Color(0xFF0277BD)}, |
|||
{900, new Color(0xFF01579B)}, |
|||
} |
|||
); |
|||
|
|||
const uint _lightBluePrimaryValue = 0xFF03A9F4; |
|||
|
|||
public static readonly MaterialAccentColor lightBlueAccent = new MaterialAccentColor( |
|||
_lightBlueAccentPrimaryValue, |
|||
new Dictionary<uint, Color>() { |
|||
{100, new Color(0xFF80D8FF)}, |
|||
{200, new Color(_lightBlueAccentPrimaryValue)}, |
|||
{400, new Color(0xFF00B0FF)}, |
|||
{700, new Color(0xFF0091EA)}, |
|||
} |
|||
); |
|||
|
|||
const uint _lightBlueAccentPrimaryValue = 0xFF40C4FF; |
|||
|
|||
public static readonly MaterialColor cyan = new MaterialColor( |
|||
_cyanPrimaryValue, |
|||
new Dictionary<uint, Color>() { |
|||
{50, new Color(0xFFE0F7FA)}, |
|||
{100, new Color(0xFFB2EBF2)}, |
|||
{200, new Color(0xFF80DEEA)}, |
|||
{300, new Color(0xFF4DD0E1)}, |
|||
{400, new Color(0xFF26C6DA)}, |
|||
{500, new Color(_cyanPrimaryValue)}, |
|||
{600, new Color(0xFF00ACC1)}, |
|||
{700, new Color(0xFF0097A7)}, |
|||
{800, new Color(0xFF00838F)}, |
|||
{900, new Color(0xFF006064)}, |
|||
} |
|||
); |
|||
|
|||
const uint _cyanPrimaryValue = 0xFF00BCD4; |
|||
|
|||
public static readonly MaterialAccentColor cyanAccent = new MaterialAccentColor( |
|||
_cyanAccentPrimaryValue, |
|||
new Dictionary<uint, Color>() { |
|||
{100, new Color(0xFF84FFFF)}, |
|||
{200, new Color(_cyanAccentPrimaryValue)}, |
|||
{400, new Color(0xFF00E5FF)}, |
|||
{700, new Color(0xFF00B8D4)}, |
|||
} |
|||
); |
|||
|
|||
const uint _cyanAccentPrimaryValue = 0xFF18FFFF; |
|||
|
|||
public static readonly MaterialColor teal = new MaterialColor( |
|||
_tealPrimaryValue, |
|||
new Dictionary<uint, Color>() { |
|||
{50, new Color(0xFFE0F2F1)}, |
|||
{100, new Color(0xFFB2DFDB)}, |
|||
{200, new Color(0xFF80CBC4)}, |
|||
{300, new Color(0xFF4DB6AC)}, |
|||
{400, new Color(0xFF26A69A)}, |
|||
{500, new Color(_tealPrimaryValue)}, |
|||
{600, new Color(0xFF00897B)}, |
|||
{700, new Color(0xFF00796B)}, |
|||
{800, new Color(0xFF00695C)}, |
|||
{900, new Color(0xFF004D40)}, |
|||
} |
|||
); |
|||
|
|||
const uint _tealPrimaryValue = 0xFF009688; |
|||
|
|||
public static readonly MaterialAccentColor tealAccent = new MaterialAccentColor( |
|||
_tealAccentPrimaryValue, |
|||
new Dictionary<uint, Color>() { |
|||
{100, new Color(0xFFA7FFEB)}, |
|||
{200, new Color(_tealAccentPrimaryValue)}, |
|||
{400, new Color(0xFF1DE9B6)}, |
|||
{700, new Color(0xFF00BFA5)}, |
|||
} |
|||
); |
|||
|
|||
const uint _tealAccentPrimaryValue = 0xFF64FFDA; |
|||
|
|||
public static readonly MaterialColor green = new MaterialColor( |
|||
_greenPrimaryValue, |
|||
new Dictionary<uint, Color>() { |
|||
{50, new Color(0xFFE8F5E9)}, |
|||
{100, new Color(0xFFC8E6C9)}, |
|||
{200, new Color(0xFFA5D6A7)}, |
|||
{300, new Color(0xFF81C784)}, |
|||
{400, new Color(0xFF66BB6A)}, |
|||
{500, new Color(_greenPrimaryValue)}, |
|||
{600, new Color(0xFF43A047)}, |
|||
{700, new Color(0xFF388E3C)}, |
|||
{800, new Color(0xFF2E7D32)}, |
|||
{900, new Color(0xFF1B5E20)}, |
|||
} |
|||
); |
|||
|
|||
const uint _greenPrimaryValue = 0xFF4CAF50; |
|||
|
|||
public static readonly MaterialAccentColor greenAccent = new MaterialAccentColor( |
|||
_greenAccentPrimaryValue, |
|||
new Dictionary<uint, Color>() { |
|||
{100, new Color(0xFFB9F6CA)}, |
|||
{200, new Color(_greenAccentPrimaryValue)}, |
|||
{400, new Color(0xFF00E676)}, |
|||
{700, new Color(0xFF00C853)}, |
|||
} |
|||
); |
|||
|
|||
const uint _greenAccentPrimaryValue = 0xFF69F0AE; |
|||
|
|||
public static readonly MaterialColor lightGreen = new MaterialColor( |
|||
_lightGreenPrimaryValue, |
|||
new Dictionary<uint, Color>() { |
|||
{50, new Color(0xFFF1F8E9)}, |
|||
{100, new Color(0xFFDCEDC8)}, |
|||
{200, new Color(0xFFC5E1A5)}, |
|||
{300, new Color(0xFFAED581)}, |
|||
{400, new Color(0xFF9CCC65)}, |
|||
{500, new Color(_lightGreenPrimaryValue)}, |
|||
{600, new Color(0xFF7CB342)}, |
|||
{700, new Color(0xFF689F38)}, |
|||
{800, new Color(0xFF558B2F)}, |
|||
{900, new Color(0xFF33691E)}, |
|||
} |
|||
); |
|||
|
|||
const uint _lightGreenPrimaryValue = 0xFF8BC34A; |
|||
|
|||
public static readonly MaterialAccentColor lightGreenAccent = new MaterialAccentColor( |
|||
_lightGreenAccentPrimaryValue, |
|||
new Dictionary<uint, Color>() { |
|||
{100, new Color(0xFFCCFF90)}, |
|||
{200, new Color(_lightGreenAccentPrimaryValue)}, |
|||
{400, new Color(0xFF76FF03)}, |
|||
{700, new Color(0xFF64DD17)}, |
|||
} |
|||
); |
|||
|
|||
const uint _lightGreenAccentPrimaryValue = 0xFFB2FF59; |
|||
|
|||
public static readonly MaterialColor lime = new MaterialColor( |
|||
_limePrimaryValue, |
|||
new Dictionary<uint, Color>() { |
|||
{50, new Color(0xFFF9FBE7)}, |
|||
{100, new Color(0xFFF0F4C3)}, |
|||
{200, new Color(0xFFE6EE9C)}, |
|||
{300, new Color(0xFFDCE775)}, |
|||
{400, new Color(0xFFD4E157)}, |
|||
{500, new Color(_limePrimaryValue)}, |
|||
{600, new Color(0xFFC0CA33)}, |
|||
{700, new Color(0xFFAFB42B)}, |
|||
{800, new Color(0xFF9E9D24)}, |
|||
{900, new Color(0xFF827717)}, |
|||
} |
|||
); |
|||
|
|||
const uint _limePrimaryValue = 0xFFCDDC39; |
|||
|
|||
public static readonly MaterialAccentColor limeAccent = new MaterialAccentColor( |
|||
_limeAccentPrimaryValue, |
|||
new Dictionary<uint, Color>() { |
|||
{100, new Color(0xFFF4FF81)}, |
|||
{200, new Color(_limeAccentPrimaryValue)}, |
|||
{400, new Color(0xFFC6FF00)}, |
|||
{700, new Color(0xFFAEEA00)}, |
|||
} |
|||
); |
|||
|
|||
const uint _limeAccentPrimaryValue = 0xFFEEFF41; |
|||
|
|||
public static readonly MaterialColor yellow = new MaterialColor( |
|||
_yellowPrimaryValue, |
|||
new Dictionary<uint, Color>() { |
|||
{50, new Color(0xFFFFFDE7)}, |
|||
{100, new Color(0xFFFFF9C4)}, |
|||
{200, new Color(0xFFFFF59D)}, |
|||
{300, new Color(0xFFFFF176)}, |
|||
{400, new Color(0xFFFFEE58)}, |
|||
{500, new Color(_yellowPrimaryValue)}, |
|||
{600, new Color(0xFFFDD835)}, |
|||
{700, new Color(0xFFFBC02D)}, |
|||
{800, new Color(0xFFF9A825)}, |
|||
{900, new Color(0xFFF57F17)}, |
|||
} |
|||
); |
|||
|
|||
const uint _yellowPrimaryValue = 0xFFFFEB3B; |
|||
|
|||
public static readonly MaterialAccentColor yellowAccent = new MaterialAccentColor( |
|||
_yellowAccentPrimaryValue, |
|||
new Dictionary<uint, Color>() { |
|||
{100, new Color(0xFFFFFF8D)}, |
|||
{200, new Color(_yellowAccentPrimaryValue)}, |
|||
{400, new Color(0xFFFFEA00)}, |
|||
{700, new Color(0xFFFFD600)}, |
|||
} |
|||
); |
|||
|
|||
const uint _yellowAccentPrimaryValue = 0xFFFFFF00; |
|||
|
|||
public static readonly MaterialColor amber = new MaterialColor( |
|||
_amberPrimaryValue, |
|||
new Dictionary<uint, Color>() { |
|||
{50, new Color(0xFFFFF8E1)}, |
|||
{100, new Color(0xFFFFECB3)}, |
|||
{200, new Color(0xFFFFE082)}, |
|||
{300, new Color(0xFFFFD54F)}, |
|||
{400, new Color(0xFFFFCA28)}, |
|||
{500, new Color(_amberPrimaryValue)}, |
|||
{600, new Color(0xFFFFB300)}, |
|||
{700, new Color(0xFFFFA000)}, |
|||
{800, new Color(0xFFFF8F00)}, |
|||
{900, new Color(0xFFFF6F00)}, |
|||
} |
|||
); |
|||
|
|||
const uint _amberPrimaryValue = 0xFFFFC107; |
|||
|
|||
public static readonly MaterialAccentColor amberAccent = new MaterialAccentColor( |
|||
_amberAccentPrimaryValue, |
|||
new Dictionary<uint, Color>() { |
|||
{100, new Color(0xFFFFE57F)}, |
|||
{200, new Color(_amberAccentPrimaryValue)}, |
|||
{400, new Color(0xFFFFC400)}, |
|||
{700, new Color(0xFFFFAB00)}, |
|||
} |
|||
); |
|||
|
|||
const uint _amberAccentPrimaryValue = 0xFFFFD740; |
|||
|
|||
public static readonly MaterialColor orange = new MaterialColor( |
|||
_orangePrimaryValue, |
|||
new Dictionary<uint, Color>() { |
|||
{50, new Color(0xFFFFF3E0)}, |
|||
{100, new Color(0xFFFFE0B2)}, |
|||
{200, new Color(0xFFFFCC80)}, |
|||
{300, new Color(0xFFFFB74D)}, |
|||
{400, new Color(0xFFFFA726)}, |
|||
{500, new Color(_orangePrimaryValue)}, |
|||
{600, new Color(0xFFFB8C00)}, |
|||
{700, new Color(0xFFF57C00)}, |
|||
{800, new Color(0xFFEF6C00)}, |
|||
{900, new Color(0xFFE65100)}, |
|||
} |
|||
); |
|||
|
|||
const uint _orangePrimaryValue = 0xFFFF9800; |
|||
|
|||
public static readonly MaterialAccentColor orangeAccent = new MaterialAccentColor( |
|||
_orangeAccentPrimaryValue, |
|||
new Dictionary<uint, Color>() { |
|||
{100, new Color(0xFFFFD180)}, |
|||
{200, new Color(_orangeAccentPrimaryValue)}, |
|||
{400, new Color(0xFFFF9100)}, |
|||
{700, new Color(0xFFFF6D00)}, |
|||
} |
|||
); |
|||
|
|||
const uint _orangeAccentPrimaryValue = 0xFFFFAB40; |
|||
|
|||
public static readonly MaterialColor deepOrange = new MaterialColor( |
|||
_deepOrangePrimaryValue, |
|||
new Dictionary<uint, Color>() { |
|||
{50, new Color(0xFFFBE9E7)}, |
|||
{100, new Color(0xFFFFCCBC)}, |
|||
{200, new Color(0xFFFFAB91)}, |
|||
{300, new Color(0xFFFF8A65)}, |
|||
{400, new Color(0xFFFF7043)}, |
|||
{500, new Color(_deepOrangePrimaryValue)}, |
|||
{600, new Color(0xFFF4511E)}, |
|||
{700, new Color(0xFFE64A19)}, |
|||
{800, new Color(0xFFD84315)}, |
|||
{900, new Color(0xFFBF360C)}, |
|||
} |
|||
); |
|||
|
|||
const uint _deepOrangePrimaryValue = 0xFFFF5722; |
|||
|
|||
public static readonly MaterialAccentColor deepOrangeAccent = new MaterialAccentColor( |
|||
_deepOrangeAccentPrimaryValue, |
|||
new Dictionary<uint, Color>() { |
|||
{100, new Color(0xFFFF9E80)}, |
|||
{200, new Color(_deepOrangeAccentPrimaryValue)}, |
|||
{400, new Color(0xFFFF3D00)}, |
|||
{700, new Color(0xFFDD2C00)}, |
|||
} |
|||
); |
|||
|
|||
const uint _deepOrangeAccentPrimaryValue = 0xFFFF6E40; |
|||
|
|||
public static readonly MaterialColor brown = new MaterialColor( |
|||
_brownPrimaryValue, |
|||
new Dictionary<uint, Color>() { |
|||
{50, new Color(0xFFEFEBE9)}, |
|||
{100, new Color(0xFFD7CCC8)}, |
|||
{200, new Color(0xFFBCAAA4)}, |
|||
{300, new Color(0xFFA1887F)}, |
|||
{400, new Color(0xFF8D6E63)}, |
|||
{500, new Color(_brownPrimaryValue)}, |
|||
{600, new Color(0xFF6D4C41)}, |
|||
{700, new Color(0xFF5D4037)}, |
|||
{800, new Color(0xFF4E342E)}, |
|||
{900, new Color(0xFF3E2723)}, |
|||
} |
|||
); |
|||
|
|||
const uint _brownPrimaryValue = 0xFF795548; |
|||
|
|||
public static readonly MaterialColor grey = new MaterialColor( |
|||
_greyPrimaryValue, |
|||
new Dictionary<uint, Color>() { |
|||
{50, new Color(0xFFFAFAFA)}, |
|||
{100, new Color(0xFFF5F5F5)}, |
|||
{200, new Color(0xFFEEEEEE)}, |
|||
{300, new Color(0xFFE0E0E0)}, |
|||
{350, new Color(0xFFD6D6D6)}, |
|||
{400, new Color(0xFFBDBDBD)}, |
|||
{500, new Color(_greyPrimaryValue)}, |
|||
{600, new Color(0xFF757575)}, |
|||
{700, new Color(0xFF616161)}, |
|||
{800, new Color(0xFF424242)}, |
|||
{850, new Color(0xFF303030)}, |
|||
{900, new Color(0xFF212121)}, |
|||
} |
|||
); |
|||
|
|||
const uint _greyPrimaryValue = 0xFF9E9E9E; |
|||
|
|||
public static readonly MaterialColor blueGrey = new MaterialColor( |
|||
_blueGreyPrimaryValue, |
|||
new Dictionary<uint, Color>() { |
|||
{50, new Color(0xFFECEFF1)}, |
|||
{100, new Color(0xFFCFD8DC)}, |
|||
{200, new Color(0xFFB0BEC5)}, |
|||
{300, new Color(0xFF90A4AE)}, |
|||
{400, new Color(0xFF78909C)}, |
|||
{500, new Color(_blueGreyPrimaryValue)}, |
|||
{600, new Color(0xFF546E7A)}, |
|||
{700, new Color(0xFF455A64)}, |
|||
{800, new Color(0xFF37474F)}, |
|||
{900, new Color(0xFF263238)}, |
|||
} |
|||
); |
|||
|
|||
const uint _blueGreyPrimaryValue = 0xFF607D8B; |
|||
|
|||
public static readonly List<MaterialColor> primaries = new List<MaterialColor>() { |
|||
red, |
|||
pink, |
|||
purple, |
|||
deepPurple, |
|||
indigo, |
|||
blue, |
|||
lightBlue, |
|||
cyan, |
|||
teal, |
|||
green, |
|||
lightGreen, |
|||
lime, |
|||
yellow, |
|||
amber, |
|||
orange, |
|||
deepOrange, |
|||
brown, |
|||
blueGrey |
|||
}; |
|||
|
|||
public static readonly List<MaterialAccentColor> accents = new List<MaterialAccentColor>() { |
|||
redAccent, |
|||
pinkAccent, |
|||
purpleAccent, |
|||
deepPurpleAccent, |
|||
indigoAccent, |
|||
blueAccent, |
|||
lightBlueAccent, |
|||
cyanAccent, |
|||
tealAccent, |
|||
greenAccent, |
|||
lightGreenAccent, |
|||
limeAccent, |
|||
yellowAccent, |
|||
amberAccent, |
|||
orangeAccent, |
|||
deepOrangeAccent, |
|||
}; |
|||
} |
|||
} |
|
|||
fileFormatVersion: 2 |
|||
guid: 2f6601e4d6a788a458d2f9e1d06fa1ea |
|||
MonoImporter: |
|||
externalObjects: {} |
|||
serializedVersion: 2 |
|||
defaultReferences: [] |
|||
executionOrder: 0 |
|||
icon: {instanceID: 0} |
|||
userData: |
|||
assetBundleName: |
|||
assetBundleVariant: |
|
|||
using System; |
|||
using Unity.UIWidgets.painting; |
|||
|
|||
namespace Unity.UIWidgets.material { |
|||
public static class Constants { |
|||
public const float kMinInteractiveDimension = 48.0f; |
|||
|
|||
public const float kToolbarHeight = 56.0f; |
|||
|
|||
public const float kBottomNavigationBarHeight = 56.0f; |
|||
|
|||
public const float kTextTabBarHeight = kMinInteractiveDimension; |
|||
|
|||
public static readonly TimeSpan kThemeChangeDuration = new TimeSpan(0, 0, 0, 0, 200); |
|||
|
|||
public const float kRadialReactionRadius = 20.0f; |
|||
|
|||
public static readonly TimeSpan kRadialReactionDuration = new TimeSpan(0, 0, 0, 0, 100); |
|||
|
|||
public const int kRadialReactionAlpha = 0x1F; |
|||
|
|||
public static readonly TimeSpan kTabScrollDuration = new TimeSpan(0, 0, 0, 0, 300); |
|||
|
|||
public static readonly EdgeInsets kTabLabelPadding = EdgeInsets.symmetric(horizontal: 16.0f); |
|||
|
|||
public static readonly EdgeInsets kMaterialListPadding = EdgeInsets.symmetric(vertical: 8.0f); |
|||
} |
|||
} |
|
|||
fileFormatVersion: 2 |
|||
guid: f20dccf2a552abc49bd30ca75acd19b1 |
|||
MonoImporter: |
|||
externalObjects: {} |
|||
serializedVersion: 2 |
|||
defaultReferences: [] |
|||
executionOrder: 0 |
|||
icon: {instanceID: 0} |
|||
userData: |
|||
assetBundleName: |
|||
assetBundleVariant: |
|
|||
using System; |
|||
using System.Collections.Generic; |
|||
using com.unity.uiwidgets.Runtime.rendering; |
|||
using RSG; |
|||
using Unity.UIWidgets.animation; |
|||
using Unity.UIWidgets.async; |
|||
using Unity.UIWidgets.foundation; |
|||
using Unity.UIWidgets.gestures; |
|||
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; |
|||
|
|||
/* |
|||
* Differences between Dart & C# |
|||
* Duration => TimeSpan |
|||
* -1 % 4 = 3 => -1 % 4 = -1 |
|||
* [Dart] [DateTime.weekday] provides a 1-based index (Start with Monday) |
|||
* [C#] [DateTime.DayOfWeek] provides a 0-based index (Start with Sunday) |
|||
* @IIzzaya |
|||
*/ |
|||
namespace Unity.UIWidgets.material { |
|||
public class DatePickerUtils { |
|||
public const float _kDatePickerHeaderPortraitHeight = 100.0f; |
|||
public const float _kDatePickerHeaderLandscapeWidth = 168.0f; |
|||
public static readonly TimeSpan _kMonthScrollDuration = new TimeSpan(0, 0, 0, 0, 200); |
|||
public const float _kDayPickerRowHeight = 42.0f; |
|||
public const int _kMaxDayPickerRowCount = 6; |
|||
|
|||
public const float _kMaxDayPickerHeight = _kDayPickerRowHeight * (_kMaxDayPickerRowCount + 2); |
|||
public const float _kMonthPickerPortraitWidth = 330.0f; |
|||
public const float _kMonthPickerLandscapeWidth = 344.0f; |
|||
public const float _kDialogActionBarHeight = 52.0f; |
|||
public const float _kDatePickerLandscapeHeight = _kMaxDayPickerHeight + _kDialogActionBarHeight; |
|||
|
|||
internal static readonly _DayPickerGridDelegate _kDayPickerGridDelegate = new _DayPickerGridDelegate(); |
|||
|
|||
public static IPromise<object> showDatePicker( |
|||
BuildContext context, |
|||
DateTime initialDate, |
|||
DateTime firstDate, |
|||
DateTime lastDate, |
|||
SelectableDayPredicate selectableDayPredicate = null, |
|||
DatePickerMode initialDatePickerMode = DatePickerMode.day, |
|||
Locale locale = null, |
|||
TransitionBuilder builder = null |
|||
) { |
|||
D.assert(initialDate >= firstDate, () => "initialDate must be on or after firstDate"); |
|||
D.assert(initialDate <= lastDate, () => "initialDate must be on or before lastDate"); |
|||
D.assert(firstDate <= lastDate, () => "lastDate must be on or after firstDate"); |
|||
D.assert( |
|||
selectableDayPredicate == null || selectableDayPredicate(initialDate), |
|||
() => "Provided initialDate must satisfy provided selectableDayPredicate" |
|||
); |
|||
D.assert(context != null); |
|||
D.assert(MaterialD.debugCheckHasMaterialLocalizations(context)); |
|||
|
|||
Widget child = new _DatePickerDialog( |
|||
initialDate: initialDate, |
|||
firstDate: firstDate, |
|||
lastDate: lastDate, |
|||
selectableDayPredicate: selectableDayPredicate, |
|||
initialDatePickerMode: initialDatePickerMode |
|||
); |
|||
|
|||
if (locale != null) { |
|||
child = Localizations.overrides( |
|||
context: context, |
|||
locale: locale, |
|||
child: child |
|||
); |
|||
} |
|||
|
|||
return DialogUtils.showDialog( |
|||
context: context, |
|||
builder: (BuildContext _context) => { return builder == null ? child : builder(_context, child); } |
|||
); |
|||
} |
|||
} |
|||
|
|||
public enum DatePickerMode { |
|||
day, |
|||
year |
|||
} |
|||
|
|||
class _DatePickerHeader : StatelessWidget { |
|||
public _DatePickerHeader( |
|||
DateTime selectedDate, |
|||
DatePickerMode mode, |
|||
ValueChanged<DatePickerMode> onModeChanged, |
|||
Orientation orientation, |
|||
Key key = null |
|||
) : base(key: key) { |
|||
this.selectedDate = selectedDate; |
|||
this.mode = mode; |
|||
this.onModeChanged = onModeChanged; |
|||
this.orientation = orientation; |
|||
} |
|||
|
|||
public readonly DateTime selectedDate; |
|||
public readonly DatePickerMode mode; |
|||
public readonly ValueChanged<DatePickerMode> onModeChanged; |
|||
public readonly Orientation orientation; |
|||
|
|||
void _handleChangeMode(DatePickerMode value) { |
|||
if (value != mode) { |
|||
onModeChanged(value); |
|||
} |
|||
} |
|||
|
|||
public override Widget build(BuildContext context) { |
|||
MaterialLocalizations localizations = MaterialLocalizations.of(context); |
|||
ThemeData themeData = Theme.of(context); |
|||
TextTheme headerTextTheme = themeData.primaryTextTheme; |
|||
Color dayColor = null; |
|||
Color yearColor = null; |
|||
switch (themeData.primaryColorBrightness) { |
|||
case Brightness.light: |
|||
dayColor = mode == DatePickerMode.day ? Colors.black87 : Colors.black54; |
|||
yearColor = mode == DatePickerMode.year ? Colors.black87 : Colors.black54; |
|||
break; |
|||
case Brightness.dark: |
|||
dayColor = mode == DatePickerMode.day ? Colors.white : Colors.white70; |
|||
yearColor = mode == DatePickerMode.year ? Colors.white : Colors.white70; |
|||
break; |
|||
} |
|||
|
|||
TextStyle dayStyle = headerTextTheme.display1.copyWith(color: dayColor, height: 1.4f); |
|||
TextStyle yearStyle = headerTextTheme.subhead.copyWith(color: yearColor, height: 1.4f); |
|||
Color backgroundColor = null; |
|||
switch (themeData.brightness) { |
|||
case Brightness.light: |
|||
backgroundColor = themeData.primaryColor; |
|||
break; |
|||
case Brightness.dark: |
|||
backgroundColor = themeData.backgroundColor; |
|||
break; |
|||
} |
|||
|
|||
float width = 0f; |
|||
float height = 0f; |
|||
EdgeInsets padding = null; |
|||
MainAxisAlignment mainAxisAlignment = MainAxisAlignment.center; |
|||
switch (orientation) { |
|||
case Orientation.portrait: |
|||
height = DatePickerUtils._kDatePickerHeaderPortraitHeight; |
|||
padding = EdgeInsets.symmetric(horizontal: 16.0f); |
|||
mainAxisAlignment = MainAxisAlignment.center; |
|||
break; |
|||
case Orientation.landscape: |
|||
width = DatePickerUtils._kDatePickerHeaderLandscapeWidth; |
|||
padding = EdgeInsets.all(8.0f); |
|||
mainAxisAlignment = MainAxisAlignment.start; |
|||
break; |
|||
} |
|||
|
|||
Widget yearButton = new IgnorePointer( |
|||
ignoring: mode != DatePickerMode.day, |
|||
child: new _DateHeaderButton( |
|||
color: backgroundColor, |
|||
onTap: Feedback.wrapForTap(() => _handleChangeMode(DatePickerMode.year), context), |
|||
child: new Text(localizations.formatYear(selectedDate), style: yearStyle) |
|||
) |
|||
); |
|||
Widget dayButton = new IgnorePointer( |
|||
ignoring: mode == DatePickerMode.day, |
|||
child: new _DateHeaderButton( |
|||
color: backgroundColor, |
|||
onTap: Feedback.wrapForTap(() => _handleChangeMode(DatePickerMode.day), context), |
|||
child: new Text(localizations.formatMediumDate(selectedDate), style: dayStyle) |
|||
) |
|||
); |
|||
return new Container( |
|||
width: width, |
|||
height: height, |
|||
padding: padding, |
|||
color: backgroundColor, |
|||
child: new Column( |
|||
mainAxisAlignment: mainAxisAlignment, |
|||
crossAxisAlignment: CrossAxisAlignment.start, |
|||
children: new List<Widget> {yearButton, dayButton} |
|||
) |
|||
); |
|||
} |
|||
} |
|||
|
|||
class _DateHeaderButton : StatelessWidget { |
|||
public _DateHeaderButton( |
|||
GestureTapCallback onTap, |
|||
Color color, |
|||
Widget child, |
|||
Key key = null |
|||
) : base(key: key) { |
|||
this.onTap = onTap; |
|||
this.color = color; |
|||
this.child = child; |
|||
} |
|||
|
|||
public readonly GestureTapCallback onTap; |
|||
public readonly Color color; |
|||
public readonly Widget child; |
|||
|
|||
public override Widget build(BuildContext context) { |
|||
ThemeData theme = Theme.of(context); |
|||
return new Material( |
|||
type: MaterialType.button, |
|||
color: color, |
|||
child: new InkWell( |
|||
borderRadius: MaterialConstantsUtils.kMaterialEdges[MaterialType.button], |
|||
highlightColor: theme.highlightColor, |
|||
splashColor: theme.splashColor, |
|||
onTap: onTap, |
|||
child: new Container( |
|||
padding: EdgeInsets.symmetric(horizontal: 8.0f), |
|||
child: child |
|||
) |
|||
) |
|||
); |
|||
} |
|||
} |
|||
|
|||
class _DayPickerGridDelegate : SliverGridDelegate { |
|||
public _DayPickerGridDelegate() { } |
|||
|
|||
public override SliverGridLayout getLayout(SliverConstraints constraints) { |
|||
const int columnCount = 7; // DateTime.daysPerWeek = 7
|
|||
float tileWidth = constraints.crossAxisExtent / columnCount; |
|||
float tileHeight = Mathf.Min( |
|||
DatePickerUtils._kDayPickerRowHeight, |
|||
constraints.viewportMainAxisExtent / (DatePickerUtils._kMaxDayPickerRowCount + 1) |
|||
); |
|||
return new SliverGridRegularTileLayout( |
|||
crossAxisCount: columnCount, |
|||
mainAxisStride: tileHeight, |
|||
crossAxisStride: tileWidth, |
|||
childMainAxisExtent: tileHeight, |
|||
childCrossAxisExtent: tileWidth, |
|||
reverseCrossAxis: AxisUtils.axisDirectionIsReversed(constraints.crossAxisDirection) |
|||
); |
|||
} |
|||
|
|||
public override bool shouldRelayout(SliverGridDelegate oldDelegate) { |
|||
return false; |
|||
} |
|||
} |
|||
|
|||
public class DayPicker : StatelessWidget { |
|||
public DayPicker( |
|||
DateTime selectedDate, |
|||
DateTime currentDate, |
|||
ValueChanged<DateTime> onChanged, |
|||
DateTime firstDate, |
|||
DateTime lastDate, |
|||
DateTime displayedMonth, |
|||
SelectableDayPredicate selectableDayPredicate = null, |
|||
DragStartBehavior dragStartBehavior = DragStartBehavior.start, |
|||
Key key = null |
|||
) : base(key: key) { |
|||
D.assert(onChanged != null); |
|||
D.assert(firstDate <= lastDate); |
|||
D.assert(selectedDate >= firstDate); |
|||
this.selectedDate = selectedDate; |
|||
this.currentDate = currentDate; |
|||
this.onChanged = onChanged; |
|||
this.firstDate = firstDate; |
|||
this.lastDate = lastDate; |
|||
this.displayedMonth = displayedMonth; |
|||
this.selectableDayPredicate = selectableDayPredicate; |
|||
this.dragStartBehavior = dragStartBehavior; |
|||
} |
|||
|
|||
public readonly DateTime selectedDate; |
|||
public readonly DateTime currentDate; |
|||
public readonly ValueChanged<DateTime> onChanged; |
|||
public readonly DateTime firstDate; |
|||
public readonly DateTime lastDate; |
|||
public readonly DateTime displayedMonth; |
|||
public readonly SelectableDayPredicate selectableDayPredicate; |
|||
public readonly DragStartBehavior dragStartBehavior; |
|||
|
|||
List<Widget> _getDayHeaders(TextStyle headerStyle, MaterialLocalizations localizations) { |
|||
List<Widget> result = new List<Widget>(); |
|||
for (int i = localizations.firstDayOfWeekIndex; true; i = (i + 1) % 7) { |
|||
string weekday = localizations.narrowWeekdays[i]; |
|||
result.Add(new Center(child: new Text(weekday, style: headerStyle))); |
|||
if (i == (localizations.firstDayOfWeekIndex + 6) % 7) { |
|||
break; |
|||
} |
|||
} |
|||
|
|||
return result; |
|||
} |
|||
|
|||
static readonly List<int> _daysInMonth = new List<int> {31, -1, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; |
|||
|
|||
static int getDaysInMonth(int year, int month) { |
|||
if (month == 2) { |
|||
bool isLeapYear = (year % 4 == 0) && (year % 100 != 0) || (year % 400 == 0); |
|||
if (isLeapYear) { |
|||
return 29; |
|||
} |
|||
|
|||
return 28; |
|||
} |
|||
|
|||
return _daysInMonth[month - 1]; |
|||
} |
|||
|
|||
int _computeFirstDayOffset(int year, int month, MaterialLocalizations localizations) { |
|||
int weekdayFromMonday = new DateTime(year, month, 1).DayOfWeek.GetHashCode(); |
|||
if (weekdayFromMonday == 0) { |
|||
weekdayFromMonday = 7; |
|||
} |
|||
|
|||
weekdayFromMonday--; |
|||
|
|||
int firstDayOfWeekFromSunday = localizations.firstDayOfWeekIndex; |
|||
int firstDayOfWeekFromMonday = (firstDayOfWeekFromSunday - 1) % 7; |
|||
return (weekdayFromMonday - firstDayOfWeekFromMonday) % 7; |
|||
} |
|||
|
|||
public override Widget build(BuildContext context) { |
|||
ThemeData themeData = Theme.of(context); |
|||
MaterialLocalizations localizations = MaterialLocalizations.of(context); |
|||
int year = displayedMonth.Year; |
|||
int month = displayedMonth.Month; |
|||
int daysInMonth = getDaysInMonth(year, month); |
|||
int firstDayOffset = _computeFirstDayOffset(year, month, localizations); |
|||
List<Widget> labels = new List<Widget>(); |
|||
labels.AddRange(_getDayHeaders(themeData.textTheme.caption, localizations)); |
|||
for (int i = 0; true; i += 1) { |
|||
int day = i - firstDayOffset + 1; |
|||
if (day > daysInMonth) { |
|||
break; |
|||
} |
|||
|
|||
if (day < 1) { |
|||
labels.Add(new Container()); |
|||
} |
|||
else { |
|||
DateTime dayToBuild = new DateTime(year, month, day); |
|||
bool disabled = dayToBuild > lastDate |
|||
|| dayToBuild < firstDate |
|||
|| (selectableDayPredicate != null && |
|||
!selectableDayPredicate(dayToBuild)); |
|||
BoxDecoration decoration = null; |
|||
TextStyle itemStyle = themeData.textTheme.body1; |
|||
bool isSelectedDay = selectedDate.Year == year && selectedDate.Month == month && |
|||
selectedDate.Day == day; |
|||
if (isSelectedDay) { |
|||
itemStyle = themeData.accentTextTheme.body2; |
|||
decoration = new BoxDecoration( |
|||
color: themeData.accentColor, |
|||
shape: BoxShape.circle |
|||
); |
|||
} |
|||
else if (disabled) { |
|||
itemStyle = themeData.textTheme.body1.copyWith(color: themeData.disabledColor); |
|||
} |
|||
else if (currentDate.Year == year && currentDate.Month == month && |
|||
currentDate.Day == day) { |
|||
itemStyle = themeData.textTheme.body2.copyWith(color: themeData.accentColor); |
|||
} |
|||
|
|||
Widget dayWidget = new Container( |
|||
decoration: decoration, |
|||
child: new Center( |
|||
child: new Text(localizations.formatDecimal(day), style: itemStyle) |
|||
) |
|||
); |
|||
if (!disabled) { |
|||
dayWidget = new GestureDetector( |
|||
behavior: HitTestBehavior.opaque, |
|||
onTap: () => { onChanged(dayToBuild); }, |
|||
child: dayWidget, |
|||
dragStartBehavior: dragStartBehavior |
|||
); |
|||
} |
|||
|
|||
labels.Add(dayWidget); |
|||
} |
|||
} |
|||
|
|||
return new Padding( |
|||
padding: EdgeInsets.symmetric(horizontal: 8.0f), |
|||
child: new Column( |
|||
children: new List<Widget> { |
|||
new Container( |
|||
height: DatePickerUtils._kDayPickerRowHeight, |
|||
child: new Center( |
|||
child: new Text( |
|||
localizations.formatMonthYear(displayedMonth), |
|||
style: themeData.textTheme.subhead |
|||
) |
|||
) |
|||
), |
|||
new Flexible( |
|||
child: GridView.custom( |
|||
gridDelegate: DatePickerUtils._kDayPickerGridDelegate, |
|||
childrenDelegate: new SliverChildListDelegate(labels, addRepaintBoundaries: false) |
|||
) |
|||
) |
|||
} |
|||
) |
|||
); |
|||
} |
|||
} |
|||
|
|||
class MonthPicker : StatefulWidget { |
|||
public MonthPicker( |
|||
DateTime selectedDate, |
|||
ValueChanged<DateTime> onChanged, |
|||
DateTime firstDate, |
|||
DateTime lastDate, |
|||
SelectableDayPredicate selectableDayPredicate, |
|||
DragStartBehavior dragStartBehavior = DragStartBehavior.start, |
|||
Key key = null |
|||
) : base(key: key) { |
|||
D.assert(selectedDate != null); |
|||
D.assert(onChanged != null); |
|||
D.assert(firstDate <= lastDate); |
|||
D.assert(selectedDate >= firstDate); |
|||
this.selectedDate = selectedDate; |
|||
this.onChanged = onChanged; |
|||
this.firstDate = firstDate; |
|||
this.lastDate = lastDate; |
|||
this.selectableDayPredicate = selectableDayPredicate; |
|||
this.dragStartBehavior = dragStartBehavior; |
|||
} |
|||
|
|||
public readonly DateTime selectedDate; |
|||
public readonly ValueChanged<DateTime> onChanged; |
|||
public readonly DateTime firstDate; |
|||
public readonly DateTime lastDate; |
|||
public readonly SelectableDayPredicate selectableDayPredicate; |
|||
public readonly DragStartBehavior dragStartBehavior; |
|||
|
|||
public override State createState() { |
|||
return new _MonthPickerState(); |
|||
} |
|||
} |
|||
|
|||
class _MonthPickerState : SingleTickerProviderStateMixin<MonthPicker> { |
|||
static Animatable<float> __chevronOpacityTween; |
|||
|
|||
static Animatable<float> _chevronOpacityTween { |
|||
get { |
|||
if (__chevronOpacityTween == null) { |
|||
__chevronOpacityTween = new FloatTween(begin: 1.0f, end: 0.0f) { }; |
|||
__chevronOpacityTween.chain(new CurveTween(curve: Curves.easeInOut)); |
|||
} |
|||
|
|||
return __chevronOpacityTween; |
|||
} |
|||
} |
|||
|
|||
public override void initState() { |
|||
base.initState(); |
|||
int monthPage = _monthDelta(widget.firstDate, widget.selectedDate); |
|||
_dayPickerController = new PageController(initialPage: monthPage); |
|||
_handleMonthPageChanged(monthPage); |
|||
_updateCurrentDate(); |
|||
_chevronOpacityController = new AnimationController( |
|||
duration: new TimeSpan(0, 0, 0, 0, 250), |
|||
vsync: this |
|||
); |
|||
_chevronOpacityAnimation = _chevronOpacityController.drive(_chevronOpacityTween); |
|||
} |
|||
|
|||
public override void didUpdateWidget(StatefulWidget oldWidget) { |
|||
base.didUpdateWidget(oldWidget); |
|||
if (widget.selectedDate != ((MonthPicker) oldWidget).selectedDate) { |
|||
int monthPage = _monthDelta(widget.firstDate, widget.selectedDate); |
|||
_dayPickerController = new PageController(initialPage: monthPage); |
|||
_handleMonthPageChanged(monthPage); |
|||
} |
|||
} |
|||
|
|||
MaterialLocalizations localizations; |
|||
|
|||
public override void didChangeDependencies() { |
|||
base.didChangeDependencies(); |
|||
localizations = MaterialLocalizations.of(context); |
|||
} |
|||
|
|||
DateTime _todayDate; |
|||
DateTime _currentDisplayedMonthDate; |
|||
Timer _timer; |
|||
PageController _dayPickerController; |
|||
AnimationController _chevronOpacityController; |
|||
Animation<float> _chevronOpacityAnimation; |
|||
|
|||
void _updateCurrentDate() { |
|||
_todayDate = DateTime.Now; |
|||
DateTime tomorrow = _todayDate.AddDays(1); |
|||
TimeSpan timeUntilTomorrow = tomorrow.TimeOfDay - _todayDate.TimeOfDay; |
|||
_timer?.cancel(); |
|||
_timer = Window.instance.run(timeUntilTomorrow, |
|||
() => { setState(() => { _updateCurrentDate(); }); }); |
|||
} |
|||
|
|||
static int _monthDelta(DateTime startDate, DateTime endDate) { |
|||
return (endDate.Year - startDate.Year) * 12 + endDate.Month - startDate.Month; |
|||
} |
|||
|
|||
DateTime _addMonthsToMonthDate(DateTime monthDate, int monthsToAdd) { |
|||
return monthDate.AddMonths(monthsToAdd); |
|||
} |
|||
|
|||
Widget _buildItems(BuildContext context, int index) { |
|||
DateTime month = _addMonthsToMonthDate(widget.firstDate, index); |
|||
return new DayPicker( |
|||
key: new ValueKey<DateTime>(month), |
|||
selectedDate: widget.selectedDate, |
|||
currentDate: _todayDate, |
|||
onChanged: widget.onChanged, |
|||
firstDate: widget.firstDate, |
|||
lastDate: widget.lastDate, |
|||
displayedMonth: month, |
|||
selectableDayPredicate: widget.selectableDayPredicate, |
|||
dragStartBehavior: widget.dragStartBehavior |
|||
); |
|||
} |
|||
|
|||
void _handleNextMonth() { |
|||
if (!_isDisplayingLastMonth) { |
|||
_dayPickerController.nextPage(duration: DatePickerUtils._kMonthScrollDuration, curve: Curves.ease); |
|||
} |
|||
} |
|||
|
|||
void _handlePreviousMonth() { |
|||
if (!_isDisplayingFirstMonth) { |
|||
_dayPickerController.previousPage(duration: DatePickerUtils._kMonthScrollDuration, |
|||
curve: Curves.ease); |
|||
} |
|||
} |
|||
|
|||
bool _isDisplayingFirstMonth { |
|||
get { |
|||
return _currentDisplayedMonthDate <= |
|||
new DateTime(widget.firstDate.Year, widget.firstDate.Month, 1); |
|||
} |
|||
} |
|||
|
|||
bool _isDisplayingLastMonth { |
|||
get { |
|||
return _currentDisplayedMonthDate >= |
|||
new DateTime(widget.lastDate.Year, widget.lastDate.Month, 1); |
|||
} |
|||
} |
|||
|
|||
DateTime _previousMonthDate; |
|||
DateTime _nextMonthDate; |
|||
|
|||
void _handleMonthPageChanged(int monthPage) { |
|||
setState(() => { |
|||
_previousMonthDate = _addMonthsToMonthDate(widget.firstDate, monthPage - 1); |
|||
_currentDisplayedMonthDate = _addMonthsToMonthDate(widget.firstDate, monthPage); |
|||
_nextMonthDate = _addMonthsToMonthDate(widget.firstDate, monthPage + 1); |
|||
}); |
|||
} |
|||
|
|||
public override Widget build(BuildContext context) { |
|||
return new SizedBox( |
|||
width: DatePickerUtils._kMonthPickerPortraitWidth, |
|||
height: DatePickerUtils._kMaxDayPickerHeight, |
|||
child: new Stack( |
|||
children: new List<Widget> { |
|||
new NotificationListener<ScrollStartNotification>( |
|||
onNotification: (_) => { |
|||
_chevronOpacityController.forward(); |
|||
return false; |
|||
}, |
|||
child: new NotificationListener<ScrollEndNotification>( |
|||
onNotification: (_) => { |
|||
_chevronOpacityController.reverse(); |
|||
return false; |
|||
}, |
|||
child: PageView.builder( |
|||
dragStartBehavior: widget.dragStartBehavior, |
|||
key: new ValueKey<DateTime>(widget.selectedDate), |
|||
controller: _dayPickerController, |
|||
scrollDirection: Axis.horizontal, |
|||
itemCount: _monthDelta(widget.firstDate, widget.lastDate) + 1, |
|||
itemBuilder: _buildItems, |
|||
onPageChanged: _handleMonthPageChanged |
|||
) |
|||
) |
|||
), |
|||
new Positioned( |
|||
top: 0.0f, |
|||
left: 8.0f, |
|||
child: new FadeTransition( |
|||
opacity: _chevronOpacityAnimation, |
|||
child: new IconButton( |
|||
icon: new Icon(Icons.chevron_left), |
|||
tooltip: _isDisplayingFirstMonth |
|||
? null |
|||
: $"{localizations.previousMonthTooltip} {localizations.formatMonthYear(_previousMonthDate)}", |
|||
onPressed: _isDisplayingFirstMonth |
|||
? (VoidCallback) null |
|||
: _handlePreviousMonth |
|||
) |
|||
) |
|||
), |
|||
new Positioned( |
|||
top: 0.0f, |
|||
right: 8.0f, |
|||
child: new FadeTransition( |
|||
opacity: _chevronOpacityAnimation, |
|||
child: new IconButton( |
|||
icon: new Icon(Icons.chevron_right), |
|||
tooltip: _isDisplayingLastMonth |
|||
? null |
|||
: $"{localizations.nextMonthTooltip} {localizations.formatMonthYear(_nextMonthDate)}", |
|||
onPressed: _isDisplayingLastMonth |
|||
? (VoidCallback) null |
|||
: _handleNextMonth |
|||
) |
|||
) |
|||
) |
|||
} |
|||
) |
|||
); |
|||
} |
|||
|
|||
public override void dispose() { |
|||
_timer?.cancel(); |
|||
_dayPickerController?.dispose(); |
|||
base.dispose(); |
|||
} |
|||
} |
|||
|
|||
class _MonthPickerSortKey : Diagnosticable { |
|||
public _MonthPickerSortKey(float order) { } |
|||
public static readonly _MonthPickerSortKey previousMonth = new _MonthPickerSortKey(1.0f); |
|||
public static readonly _MonthPickerSortKey nextMonth = new _MonthPickerSortKey(2.0f); |
|||
public static readonly _MonthPickerSortKey calendar = new _MonthPickerSortKey(3.0f); |
|||
} |
|||
|
|||
public class YearPicker : StatefulWidget { |
|||
public YearPicker( |
|||
DateTime selectedDate, |
|||
ValueChanged<DateTime> onChanged, |
|||
DateTime firstDate, |
|||
DateTime lastDate, |
|||
DragStartBehavior dragStartBehavior = DragStartBehavior.start, |
|||
Key key = null |
|||
) : base(key: key) { |
|||
D.assert(selectedDate != null); |
|||
D.assert(onChanged != null); |
|||
D.assert(firstDate <= lastDate); |
|||
this.selectedDate = selectedDate; |
|||
this.onChanged = onChanged; |
|||
this.firstDate = firstDate; |
|||
this.lastDate = lastDate; |
|||
this.dragStartBehavior = dragStartBehavior; |
|||
} |
|||
|
|||
public readonly DateTime selectedDate; |
|||
public readonly ValueChanged<DateTime> onChanged; |
|||
public readonly DateTime firstDate; |
|||
public readonly DateTime lastDate; |
|||
public readonly DragStartBehavior dragStartBehavior; |
|||
|
|||
public override State createState() { |
|||
return new _YearPickerState(); |
|||
} |
|||
} |
|||
|
|||
class _YearPickerState : State<YearPicker> { |
|||
const float _itemExtent = 50.0f; |
|||
ScrollController scrollController; |
|||
|
|||
public override void initState() { |
|||
base.initState(); |
|||
scrollController = new ScrollController( |
|||
initialScrollOffset: (widget.selectedDate.Year - widget.firstDate.Year) * _itemExtent |
|||
); |
|||
} |
|||
|
|||
public override Widget build(BuildContext context) { |
|||
D.assert(MaterialD.debugCheckHasMaterial(context)); |
|||
ThemeData themeData = Theme.of(context); |
|||
TextStyle style = themeData.textTheme.body1; |
|||
return ListView.builder( |
|||
dragStartBehavior: widget.dragStartBehavior, |
|||
controller: scrollController, |
|||
itemExtent: _itemExtent, |
|||
itemCount: widget.lastDate.Year - widget.firstDate.Year + 1, |
|||
itemBuilder: (BuildContext _context, int index) => { |
|||
int year = widget.firstDate.Year + index; |
|||
bool isSelected = year == widget.selectedDate.Year; |
|||
TextStyle itemStyle = isSelected |
|||
? themeData.textTheme.headline.copyWith(color: themeData.accentColor) |
|||
: style; |
|||
return new InkWell( |
|||
key: new ValueKey<int>(year), |
|||
onTap: () => { |
|||
widget.onChanged(new DateTime(year, widget.selectedDate.Month, |
|||
widget.selectedDate.Day)); |
|||
}, |
|||
child: new Center( |
|||
child: new Text(year.ToString(), style: itemStyle) |
|||
) |
|||
); |
|||
} |
|||
); |
|||
} |
|||
} |
|||
|
|||
class _DatePickerDialog : StatefulWidget { |
|||
public _DatePickerDialog( |
|||
DateTime initialDate, |
|||
DateTime firstDate, |
|||
DateTime lastDate, |
|||
SelectableDayPredicate selectableDayPredicate, |
|||
DatePickerMode initialDatePickerMode, |
|||
Key key = null |
|||
) : base(key: key) { |
|||
this.initialDate = initialDate; |
|||
this.firstDate = firstDate; |
|||
this.lastDate = lastDate; |
|||
this.selectableDayPredicate = selectableDayPredicate; |
|||
this.initialDatePickerMode = initialDatePickerMode; |
|||
} |
|||
|
|||
public readonly DateTime initialDate; |
|||
public readonly DateTime firstDate; |
|||
public readonly DateTime lastDate; |
|||
public readonly SelectableDayPredicate selectableDayPredicate; |
|||
public readonly DatePickerMode initialDatePickerMode; |
|||
|
|||
public override State createState() { |
|||
return new _DatePickerDialogState(); |
|||
} |
|||
} |
|||
|
|||
class _DatePickerDialogState : State<_DatePickerDialog> { |
|||
public override void initState() { |
|||
base.initState(); |
|||
_selectedDate = widget.initialDate; |
|||
_mode = widget.initialDatePickerMode; |
|||
} |
|||
|
|||
bool _announcedInitialDate = false; |
|||
public MaterialLocalizations localizations; |
|||
|
|||
public override void didChangeDependencies() { |
|||
base.didChangeDependencies(); |
|||
localizations = MaterialLocalizations.of(context); |
|||
if (!_announcedInitialDate) { |
|||
_announcedInitialDate = true; |
|||
} |
|||
} |
|||
|
|||
DateTime _selectedDate; |
|||
|
|||
DatePickerMode _mode; |
|||
GlobalKey _pickerKey = GlobalKey.key(); |
|||
|
|||
void _vibrate() { |
|||
switch (Theme.of(context).platform) { |
|||
case RuntimePlatform.Android: |
|||
// case RuntimePlatform.fuchsia:
|
|||
// HapticFeedback.vibrate();
|
|||
break; |
|||
} |
|||
} |
|||
|
|||
void _handleModeChanged(DatePickerMode mode) { |
|||
_vibrate(); |
|||
setState(() => { |
|||
_mode = mode; |
|||
if (_mode == DatePickerMode.day) { |
|||
// SemanticsService.announce(localizations.formatMonthYear(_selectedDate), textDirection);
|
|||
} |
|||
else { |
|||
// SemanticsService.announce(localizations.formatYear(_selectedDate), textDirection);
|
|||
} |
|||
}); |
|||
} |
|||
|
|||
void _handleYearChanged(DateTime value) { |
|||
if (value < widget.firstDate) { |
|||
value = widget.firstDate; |
|||
} |
|||
else if (value > widget.lastDate) { |
|||
value = widget.lastDate; |
|||
} |
|||
|
|||
if (value == _selectedDate) { |
|||
return; |
|||
} |
|||
|
|||
_vibrate(); |
|||
setState(() => { |
|||
_mode = DatePickerMode.day; |
|||
_selectedDate = value; |
|||
}); |
|||
} |
|||
|
|||
void _handleDayChanged(DateTime value) { |
|||
_vibrate(); |
|||
setState(() => { _selectedDate = value; }); |
|||
} |
|||
|
|||
void _handleCancel() { |
|||
Navigator.pop(context); |
|||
} |
|||
|
|||
void _handleOk() { |
|||
Navigator.pop(context, _selectedDate); |
|||
} |
|||
|
|||
Widget _buildPicker() { |
|||
switch (_mode) { |
|||
case DatePickerMode.day: |
|||
return new MonthPicker( |
|||
key: _pickerKey, |
|||
selectedDate: _selectedDate, |
|||
onChanged: _handleDayChanged, |
|||
firstDate: widget.firstDate, |
|||
lastDate: widget.lastDate, |
|||
selectableDayPredicate: widget.selectableDayPredicate |
|||
); |
|||
case DatePickerMode.year: |
|||
return new YearPicker( |
|||
key: _pickerKey, |
|||
selectedDate: _selectedDate, |
|||
onChanged: _handleYearChanged, |
|||
firstDate: widget.firstDate, |
|||
lastDate: widget.lastDate |
|||
); |
|||
} |
|||
|
|||
return null; |
|||
} |
|||
|
|||
public override Widget build(BuildContext context) { |
|||
ThemeData theme = Theme.of(context); |
|||
Widget picker = new Flexible( |
|||
child: new SizedBox( |
|||
height: DatePickerUtils._kMaxDayPickerHeight, |
|||
child: _buildPicker() |
|||
) |
|||
); |
|||
Widget actions = ButtonTheme.bar( |
|||
child: new ButtonBar( |
|||
children: new List<Widget> { |
|||
new FlatButton( |
|||
child: new Text(localizations.cancelButtonLabel), |
|||
onPressed: _handleCancel |
|||
), |
|||
new FlatButton( |
|||
child: new Text(localizations.okButtonLabel), |
|||
onPressed: _handleOk |
|||
) |
|||
} |
|||
) |
|||
); |
|||
Dialog dialog = new Dialog( |
|||
child: new OrientationBuilder( |
|||
builder: (BuildContext _context, Orientation orientation) => { |
|||
Widget header = new _DatePickerHeader( |
|||
selectedDate: _selectedDate, |
|||
mode: _mode, |
|||
onModeChanged: _handleModeChanged, |
|||
orientation: orientation |
|||
); |
|||
|
|||
switch (orientation) { |
|||
case Orientation.portrait: |
|||
return new SizedBox( |
|||
width: DatePickerUtils._kMonthPickerPortraitWidth, |
|||
child: new Column( |
|||
mainAxisSize: MainAxisSize.min, |
|||
crossAxisAlignment: CrossAxisAlignment.stretch, |
|||
children: new List<Widget> { |
|||
header, |
|||
new Container( |
|||
color: theme.dialogBackgroundColor, |
|||
child: new Column( |
|||
mainAxisSize: MainAxisSize.min, |
|||
crossAxisAlignment: CrossAxisAlignment.stretch, |
|||
children: new List<Widget> { |
|||
picker, |
|||
actions, |
|||
} |
|||
) |
|||
) |
|||
} |
|||
) |
|||
); |
|||
case Orientation.landscape: |
|||
return new SizedBox( |
|||
height: DatePickerUtils._kDatePickerLandscapeHeight, |
|||
child: new Row( |
|||
mainAxisSize: MainAxisSize.min, |
|||
crossAxisAlignment: CrossAxisAlignment.stretch, |
|||
children: new List<Widget> { |
|||
header, |
|||
new Flexible( |
|||
child: new Container( |
|||
width: DatePickerUtils._kMonthPickerLandscapeWidth, |
|||
color: theme.dialogBackgroundColor, |
|||
child: new Column( |
|||
mainAxisSize: MainAxisSize.min, |
|||
crossAxisAlignment: CrossAxisAlignment.stretch, |
|||
children: new List<Widget> {picker, actions} |
|||
) |
|||
) |
|||
) |
|||
} |
|||
) |
|||
); |
|||
} |
|||
|
|||
return null; |
|||
} |
|||
) |
|||
); |
|||
|
|||
return new Theme( |
|||
data: theme.copyWith( |
|||
dialogBackgroundColor: Colors.transparent |
|||
), |
|||
child: dialog |
|||
); |
|||
} |
|||
} |
|||
|
|||
public delegate bool SelectableDayPredicate(DateTime day); |
|||
} |
|
|||
fileFormatVersion: 2 |
|||
guid: a56231ebee8e54b6599292d673909844 |
|||
MonoImporter: |
|||
externalObjects: {} |
|||
serializedVersion: 2 |
|||
defaultReferences: [] |
|||
executionOrder: 0 |
|||
icon: {instanceID: 0} |
|||
userData: |
|||
assetBundleName: |
|||
assetBundleVariant: |
|
|||
using System.Collections.Generic; |
|||
using Unity.UIWidgets.foundation; |
|||
using Unity.UIWidgets.material; |
|||
using Unity.UIWidgets.widgets; |
|||
|
|||
namespace uiwidgets { |
|||
public partial class material_ { |
|||
public static bool debugCheckHasMaterial(BuildContext context) { |
|||
D.assert(() => { |
|||
if (!(context.widget is Material) && context.findAncestorWidgetOfExactType<Material>() == null) { |
|||
var list = new List<DiagnosticsNode>() { |
|||
new ErrorSummary("No Material widget found."), |
|||
new ErrorDescription( |
|||
$"{context.widget.GetType()} widgets require a Material " + |
|||
"widget ancestor.\n" + |
|||
"In material design, most widgets are conceptually \"printed\" on " + |
|||
"a sheet of material. In Flutter\"s material library, that " + |
|||
"material is represented by the Material widget. It is the " + |
|||
"Material widget that renders ink splashes, for instance. " + |
|||
"Because of this, many material library widgets require that " + |
|||
"there be a Material widget in the tree above them." |
|||
), |
|||
new ErrorHint( |
|||
"To introduce a Material widget, you can either directly " + |
|||
"include one, or use a widget that contains Material itself, " + |
|||
"such as a Card, Dialog, Drawer, or Scaffold." |
|||
) |
|||
// ...context.describeMissingAncestor(expectedAncestorType: Material)
|
|||
}; |
|||
list.AddRange(context.describeMissingAncestor(expectedAncestorType: typeof(Material))); |
|||
throw new UIWidgetsError(list); |
|||
} |
|||
|
|||
return true; |
|||
}); |
|||
return true; |
|||
} |
|||
|
|||
|
|||
public static bool debugCheckHasMaterialLocalizations(BuildContext context) { |
|||
D.assert(() => { |
|||
if (Localizations.of<MaterialLocalizations>(context, typeof(MaterialLocalizations)) == null) { |
|||
var list = new List<DiagnosticsNode>() { |
|||
new ErrorSummary("No MaterialLocalizations found."), |
|||
new ErrorDescription( |
|||
"${context.widget.runtimeType} widgets require MaterialLocalizations " + |
|||
"to be provided by a Localizations widget ancestor." |
|||
), |
|||
new ErrorDescription( |
|||
"Localizations are used to generate many different messages, labels, " + |
|||
"and abbreviations which are used by the material library." |
|||
), |
|||
new ErrorHint( |
|||
"To introduce a MaterialLocalizations, either use a " + |
|||
"MaterialApp at the root of your application to include them " + |
|||
"automatically, or add a Localization widget with a " + |
|||
"MaterialLocalizations delegate." |
|||
), |
|||
}; |
|||
list.AddRange(context.describeMissingAncestor(expectedAncestorType: typeof(MaterialLocalizations))); |
|||
throw new UIWidgetsError(list); |
|||
} |
|||
|
|||
return true; |
|||
}); |
|||
return true; |
|||
} |
|||
|
|||
public static bool debugCheckHasScaffold(BuildContext context) { |
|||
D.assert(() => { |
|||
if (!(context.widget is Scaffold) && context.findAncestorWidgetOfExactType<Scaffold>() == null) { |
|||
var list = new List<DiagnosticsNode>() { |
|||
new ErrorSummary("No Scaffold widget found."), |
|||
new ErrorDescription( |
|||
"${context.widget.runtimeType} widgets require a Scaffold widget ancestor."), |
|||
|
|||
new ErrorHint( |
|||
"Typically, the Scaffold widget is introduced by the MaterialApp or " + |
|||
"WidgetsApp widget at the top of your application widget tree." |
|||
) |
|||
}; |
|||
list.AddRange(context.describeMissingAncestor(expectedAncestorType: typeof(Scaffold))); |
|||
throw new UIWidgetsError(list); |
|||
} |
|||
|
|||
return true; |
|||
}); |
|||
return true; |
|||
} |
|||
} |
|||
} |
|
|||
fileFormatVersion: 2 |
|||
guid: 353f6a1d0791640349fe94187f15ad33 |
|||
MonoImporter: |
|||
externalObjects: {} |
|||
serializedVersion: 2 |
|||
defaultReferences: [] |
|||
executionOrder: 0 |
|||
icon: {instanceID: 0} |
|||
userData: |
|||
assetBundleName: |
|||
assetBundleVariant: |
|
|||
using System; |
|||
using System.Collections.Generic; |
|||
using RSG; |
|||
using Unity.UIWidgets.animation; |
|||
using Unity.UIWidgets.foundation; |
|||
using Unity.UIWidgets.painting; |
|||
using Unity.UIWidgets.rendering; |
|||
using Unity.UIWidgets.ui; |
|||
using Unity.UIWidgets.widgets; |
|||
using TextStyle = Unity.UIWidgets.painting.TextStyle; |
|||
|
|||
namespace Unity.UIWidgets.material { |
|||
public class Dialog : StatelessWidget { |
|||
public Dialog( |
|||
Key key = null, |
|||
Color backgroundColor = null, |
|||
float? elevation = null, |
|||
TimeSpan? insetAnimationDuration = null, |
|||
Curve insetAnimationCurve = null, |
|||
ShapeBorder shape = null, |
|||
Widget child = null |
|||
) : base(key: key) { |
|||
this.child = child; |
|||
this.backgroundColor = backgroundColor; |
|||
this.elevation = elevation; |
|||
this.insetAnimationDuration = insetAnimationDuration ?? new TimeSpan(0, 0, 0, 0, 100); |
|||
this.insetAnimationCurve = insetAnimationCurve ?? Curves.decelerate; |
|||
this.shape = shape; |
|||
} |
|||
|
|||
public readonly Color backgroundColor; |
|||
|
|||
public readonly float? elevation; |
|||
|
|||
public readonly TimeSpan insetAnimationDuration; |
|||
|
|||
public readonly Curve insetAnimationCurve; |
|||
|
|||
public readonly ShapeBorder shape; |
|||
|
|||
public readonly Widget child; |
|||
|
|||
public static readonly RoundedRectangleBorder _defaultDialogShape = |
|||
new RoundedRectangleBorder(borderRadius: BorderRadius.all(Radius.circular(2.0f))); |
|||
|
|||
const float _defaultElevation = 24.0f; |
|||
|
|||
public override Widget build(BuildContext context) { |
|||
DialogTheme dialogTheme = DialogTheme.of(context); |
|||
|
|||
return new AnimatedPadding( |
|||
padding: MediaQuery.of(context).viewInsets + EdgeInsets.symmetric(horizontal: 40.0f, vertical: 24.0f), |
|||
duration: insetAnimationDuration, |
|||
curve: insetAnimationCurve, |
|||
child: MediaQuery.removeViewInsets( |
|||
removeLeft: true, |
|||
removeTop: true, |
|||
removeRight: true, |
|||
removeBottom: true, |
|||
context: context, |
|||
child: new Center( |
|||
child: new ConstrainedBox( |
|||
constraints: new BoxConstraints(minWidth: 280.0f), |
|||
child: new Material( |
|||
color: backgroundColor ?? dialogTheme.backgroundColor ?? |
|||
Theme.of(context).dialogBackgroundColor, |
|||
elevation: elevation ?? dialogTheme.elevation ?? _defaultElevation, |
|||
shape: shape ?? dialogTheme.shape ?? _defaultDialogShape, |
|||
type: MaterialType.card, |
|||
child: child |
|||
) |
|||
) |
|||
) |
|||
) |
|||
); |
|||
} |
|||
} |
|||
|
|||
public class AlertDialog : StatelessWidget { |
|||
public AlertDialog( |
|||
Key key = null, |
|||
Widget title = null, |
|||
EdgeInsets titlePadding = null, |
|||
TextStyle titleTextStyle = null, |
|||
Widget content = null, |
|||
EdgeInsets contentPadding = null, |
|||
TextStyle contentTextStyle = null, |
|||
List<Widget> actions = null, |
|||
Color backgroundColor = null, |
|||
float? elevation = null, |
|||
ShapeBorder shape = null |
|||
) : base(key: key) { |
|||
this.title = title; |
|||
this.titlePadding = titlePadding; |
|||
this.titleTextStyle = titleTextStyle; |
|||
this.content = content; |
|||
this.contentPadding = contentPadding ?? EdgeInsets.fromLTRB(24.0f, 20.0f, 24.0f, 24.0f); |
|||
this.contentTextStyle = contentTextStyle; |
|||
this.actions = actions; |
|||
this.backgroundColor = backgroundColor; |
|||
this.elevation = elevation; |
|||
this.shape = shape; |
|||
} |
|||
|
|||
public readonly Widget title; |
|||
public readonly EdgeInsets titlePadding; |
|||
public readonly TextStyle titleTextStyle; |
|||
public readonly Widget content; |
|||
public readonly EdgeInsets contentPadding; |
|||
public readonly TextStyle contentTextStyle; |
|||
public readonly List<Widget> actions; |
|||
public readonly Color backgroundColor; |
|||
public readonly float? elevation; |
|||
public readonly ShapeBorder shape; |
|||
|
|||
public override Widget build(BuildContext context) { |
|||
// D.assert(debugCheckHasMaterialLocalizations(context));
|
|||
|
|||
ThemeData theme = Theme.of(context); |
|||
DialogTheme dialogTheme = DialogTheme.of(context); |
|||
|
|||
List<Widget> children = new List<Widget>(); |
|||
|
|||
if (title != null) { |
|||
children.Add(new Padding( |
|||
padding: titlePadding ?? |
|||
EdgeInsets.fromLTRB(24.0f, 24.0f, 24.0f, content == null ? 20.0f : 0.0f), |
|||
child: new DefaultTextStyle( |
|||
style: titleTextStyle ?? dialogTheme.titleTextStyle ?? theme.textTheme.title, |
|||
child: title |
|||
) |
|||
)); |
|||
} |
|||
|
|||
if (content != null) { |
|||
children.Add(new Flexible( |
|||
child: new Padding( |
|||
padding: contentPadding, |
|||
child: new DefaultTextStyle( |
|||
style: contentTextStyle ?? dialogTheme.contentTextStyle ?? theme.textTheme.subhead, |
|||
child: content |
|||
) |
|||
) |
|||
)); |
|||
} |
|||
|
|||
if (actions != null) { |
|||
children.Add(ButtonTheme.bar( |
|||
child: new ButtonBar( |
|||
children: actions |
|||
) |
|||
)); |
|||
} |
|||
|
|||
Widget dialogChild = new IntrinsicWidth( |
|||
child: new Column( |
|||
mainAxisSize: MainAxisSize.min, |
|||
crossAxisAlignment: CrossAxisAlignment.stretch, |
|||
children: children |
|||
) |
|||
); |
|||
|
|||
return new Dialog( |
|||
backgroundColor: backgroundColor, |
|||
elevation: elevation, |
|||
shape: shape, |
|||
child: dialogChild |
|||
); |
|||
} |
|||
} |
|||
|
|||
public class SimpleDialogOption : StatelessWidget { |
|||
public SimpleDialogOption( |
|||
Key key = null, |
|||
VoidCallback onPressed = null, |
|||
Widget child = null |
|||
) : base(key: key) { |
|||
this.onPressed = onPressed; |
|||
this.child = child; |
|||
} |
|||
|
|||
public readonly VoidCallback onPressed; |
|||
|
|||
public readonly Widget child; |
|||
|
|||
public override Widget build(BuildContext context) { |
|||
return new InkWell( |
|||
onTap: () => onPressed(), |
|||
child: new Padding( |
|||
padding: EdgeInsets.symmetric(vertical: 8.0f, horizontal: 24.0f), |
|||
child: child |
|||
) |
|||
); |
|||
} |
|||
} |
|||
|
|||
public class SimpleDialog : StatelessWidget { |
|||
public SimpleDialog( |
|||
Key key = null, |
|||
Widget title = null, |
|||
EdgeInsets titlePadding = null, |
|||
List<Widget> children = null, |
|||
EdgeInsets contentPadding = null, |
|||
Color backgroundColor = null, |
|||
float? elevation = null, |
|||
ShapeBorder shape = null |
|||
) : base(key: key) { |
|||
this.title = title; |
|||
this.titlePadding = titlePadding ?? EdgeInsets.fromLTRB(24.0f, 24.0f, 24.0f, 0.0f); |
|||
this.children = children; |
|||
this.contentPadding = contentPadding ?? EdgeInsets.fromLTRB(0.0f, 12.0f, 0.0f, 16.0f); |
|||
this.backgroundColor = backgroundColor; |
|||
this.elevation = elevation; |
|||
this.shape = shape; |
|||
} |
|||
|
|||
public readonly Widget title; |
|||
|
|||
public readonly EdgeInsets titlePadding; |
|||
|
|||
public readonly List<Widget> children; |
|||
|
|||
public readonly EdgeInsets contentPadding; |
|||
|
|||
public readonly Color backgroundColor; |
|||
|
|||
public readonly float? elevation; |
|||
|
|||
public readonly ShapeBorder shape; |
|||
|
|||
public override Widget build(BuildContext context) { |
|||
D.assert(MaterialD.debugCheckHasMaterialLocalizations(context)); |
|||
|
|||
List<Widget> body = new List<Widget>(); |
|||
|
|||
if (title != null) { |
|||
body.Add(new Padding( |
|||
padding: titlePadding, |
|||
child: new DefaultTextStyle( |
|||
style: Theme.of(context).textTheme.title, |
|||
child: title |
|||
) |
|||
)); |
|||
} |
|||
|
|||
if (children != null) { |
|||
body.Add(new Flexible( |
|||
child: new SingleChildScrollView( |
|||
padding: contentPadding, |
|||
child: new ListBody(children: children) |
|||
) |
|||
)); |
|||
} |
|||
|
|||
Widget dialogChild = new IntrinsicWidth( |
|||
stepWidth: 56.0f, |
|||
child: new ConstrainedBox( |
|||
constraints: new BoxConstraints(minWidth: 280.0f), |
|||
child: new Column( |
|||
mainAxisSize: MainAxisSize.min, |
|||
crossAxisAlignment: CrossAxisAlignment.stretch, |
|||
children: body |
|||
) |
|||
) |
|||
); |
|||
|
|||
return new Dialog( |
|||
backgroundColor: backgroundColor, |
|||
elevation: elevation, |
|||
shape: shape, |
|||
child: dialogChild |
|||
); |
|||
} |
|||
} |
|||
|
|||
public static class DialogUtils { |
|||
static Widget _buildMaterialDialogTransitions(BuildContext context, Animation<float> animation, |
|||
Animation<float> secondaryAnimation, Widget child) { |
|||
return new FadeTransition( |
|||
opacity: new CurvedAnimation( |
|||
parent: animation, |
|||
curve: Curves.easeOut |
|||
), |
|||
child: child |
|||
); |
|||
} |
|||
|
|||
public static IPromise<object> showDialog( |
|||
BuildContext context = null, |
|||
bool barrierDismissible = true, |
|||
WidgetBuilder builder = null |
|||
) { |
|||
D.assert(MaterialD.debugCheckHasMaterialLocalizations(context)); |
|||
|
|||
ThemeData theme = Theme.of(context, shadowThemeOnly: true); |
|||
return widgets.DialogUtils.showGeneralDialog( |
|||
context: context, |
|||
pageBuilder: (buildContext, animation, secondaryAnimation) => { |
|||
Widget pageChild = new Builder(builder: builder); |
|||
return new SafeArea( |
|||
child: new Builder( |
|||
builder: (_) => theme != null |
|||
? new Theme(data: theme, child: pageChild) |
|||
: pageChild) |
|||
); |
|||
}, |
|||
barrierDismissible: barrierDismissible, |
|||
barrierColor: Colors.black54, |
|||
transitionDuration: new TimeSpan(0, 0, 0, 0, 150), |
|||
transitionBuilder: _buildMaterialDialogTransitions |
|||
); |
|||
} |
|||
} |
|||
} |
|
|||
fileFormatVersion: 2 |
|||
guid: 813c881d6861d4a4c899bbd38814134c |
|||
MonoImporter: |
|||
externalObjects: {} |
|||
serializedVersion: 2 |
|||
defaultReferences: [] |
|||
executionOrder: 0 |
|||
icon: {instanceID: 0} |
|||
userData: |
|||
assetBundleName: |
|||
assetBundleVariant: |
|
|||
using System; |
|||
using Unity.UIWidgets.foundation; |
|||
using Unity.UIWidgets.painting; |
|||
using Unity.UIWidgets.ui; |
|||
using Unity.UIWidgets.widgets; |
|||
using TextStyle = Unity.UIWidgets.painting.TextStyle; |
|||
|
|||
namespace Unity.UIWidgets.material { |
|||
public class DialogTheme : Diagnosticable, IEquatable<DialogTheme> { |
|||
public DialogTheme( |
|||
Color backgroundColor = null, |
|||
float? elevation = null, |
|||
ShapeBorder shape = null, |
|||
TextStyle titleTextStyle = null, |
|||
TextStyle contentTextStyle = null |
|||
) { |
|||
this.backgroundColor = backgroundColor; |
|||
this.elevation = elevation; |
|||
this.shape = shape; |
|||
this.titleTextStyle = titleTextStyle; |
|||
this.contentTextStyle = contentTextStyle; |
|||
} |
|||
|
|||
public readonly Color backgroundColor; |
|||
|
|||
public readonly float? elevation; |
|||
|
|||
public readonly ShapeBorder shape; |
|||
|
|||
public readonly TextStyle titleTextStyle; |
|||
|
|||
public readonly TextStyle contentTextStyle; |
|||
|
|||
DialogTheme copyWith( |
|||
Color backgroundColor = null, |
|||
float? elevation = null, |
|||
ShapeBorder shape = null, |
|||
TextStyle titleTextStyle = null, |
|||
TextStyle contentTextStyle = null |
|||
) { |
|||
return new DialogTheme( |
|||
backgroundColor: backgroundColor ?? this.backgroundColor, |
|||
elevation: elevation ?? this.elevation, |
|||
shape: shape ?? this.shape, |
|||
titleTextStyle: titleTextStyle ?? this.titleTextStyle, |
|||
contentTextStyle: contentTextStyle ?? this.contentTextStyle |
|||
); |
|||
} |
|||
|
|||
public static DialogTheme of(BuildContext context) { |
|||
return Theme.of(context).dialogTheme; |
|||
} |
|||
|
|||
public static DialogTheme lerp(DialogTheme a, DialogTheme b, float t) { |
|||
return new DialogTheme( |
|||
backgroundColor: Color.lerp(a?.backgroundColor, b?.backgroundColor, t), |
|||
elevation: MathUtils.lerpFloat(a?.elevation ?? 0.0f, b?.elevation ?? 0.0f, t), |
|||
shape: ShapeBorder.lerp(a?.shape, b?.shape, t), |
|||
titleTextStyle: TextStyle.lerp(a?.titleTextStyle, b?.titleTextStyle, t), |
|||
contentTextStyle: TextStyle.lerp(a?.contentTextStyle, b?.contentTextStyle, t) |
|||
); |
|||
} |
|||
|
|||
public bool Equals(DialogTheme other) { |
|||
if (ReferenceEquals(null, other)) { |
|||
return false; |
|||
} |
|||
|
|||
if (ReferenceEquals(this, other)) { |
|||
return true; |
|||
} |
|||
|
|||
return Equals(backgroundColor, other.backgroundColor) |
|||
&& Equals(elevation, other.elevation) |
|||
&& Equals(shape, other.shape) |
|||
&& Equals(titleTextStyle, other.titleTextStyle) |
|||
&& Equals(contentTextStyle, other.contentTextStyle); |
|||
} |
|||
|
|||
public override bool Equals(object obj) { |
|||
if (ReferenceEquals(null, obj)) { |
|||
return false; |
|||
} |
|||
|
|||
if (ReferenceEquals(this, obj)) { |
|||
return true; |
|||
} |
|||
|
|||
if (obj.GetType() != GetType()) { |
|||
return false; |
|||
} |
|||
|
|||
return Equals((DialogTheme) obj); |
|||
} |
|||
|
|||
public override int GetHashCode() { |
|||
return (shape != null ? shape.GetHashCode() : 0); |
|||
} |
|||
|
|||
public static bool operator ==(DialogTheme left, DialogTheme right) { |
|||
return Equals(left, right); |
|||
} |
|||
|
|||
public static bool operator !=(DialogTheme left, DialogTheme right) { |
|||
return !Equals(left, right); |
|||
} |
|||
|
|||
public override void debugFillProperties(DiagnosticPropertiesBuilder properties) { |
|||
base.debugFillProperties(properties); |
|||
properties.add(new DiagnosticsProperty<Color>("backgroundColor", backgroundColor)); |
|||
properties.add(new DiagnosticsProperty<ShapeBorder>("shape", shape)); |
|||
properties.add(new DiagnosticsProperty<float?>("elevation", elevation)); |
|||
properties.add(new DiagnosticsProperty<TextStyle>("titleTextStyle", titleTextStyle)); |
|||
properties.add(new DiagnosticsProperty<TextStyle>("contentTextStyle", contentTextStyle)); |
|||
} |
|||
} |
|||
} |
|
|||
fileFormatVersion: 2 |
|||
guid: 555377d80e88a41b9b9918d8114897ab |
|||
MonoImporter: |
|||
externalObjects: {} |
|||
serializedVersion: 2 |
|||
defaultReferences: [] |
|||
executionOrder: 0 |
|||
icon: {instanceID: 0} |
|||
userData: |
|||
assetBundleName: |
|||
assetBundleVariant: |
|
|||
using Unity.UIWidgets.foundation; |
|||
using Unity.UIWidgets.painting; |
|||
using Unity.UIWidgets.ui; |
|||
using Unity.UIWidgets.widgets; |
|||
|
|||
namespace Unity.UIWidgets.material { |
|||
public class Divider : StatelessWidget { |
|||
public Divider( |
|||
Key key = null, |
|||
float height = 16.0f, |
|||
float indent = 0.0f, |
|||
Color color = null) : base(key: key) { |
|||
D.assert(height >= 0.0); |
|||
this.height = height; |
|||
this.indent = indent; |
|||
this.color = color; |
|||
} |
|||
|
|||
public readonly float height; |
|||
|
|||
public readonly float indent; |
|||
|
|||
public readonly Color color; |
|||
|
|||
public static BorderSide createBorderSide(BuildContext context, Color color = null, float width = 0.0f) { |
|||
return new BorderSide( |
|||
color: color ?? Theme.of(context).dividerColor, |
|||
width: width); |
|||
} |
|||
|
|||
public override Widget build(BuildContext context) { |
|||
return new SizedBox( |
|||
height: height, |
|||
child: new Center( |
|||
child: new Container( |
|||
height: 0.0f, |
|||
margin: EdgeInsets.only(indent), |
|||
decoration: new BoxDecoration( |
|||
border: new Border( |
|||
bottom: createBorderSide(context, color: color)) |
|||
) |
|||
) |
|||
) |
|||
); |
|||
} |
|||
} |
|||
} |
|
|||
fileFormatVersion: 2 |
|||
guid: defd4aeb126394fa09828fd8ad695931 |
|||
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.gestures; |
|||
using Unity.UIWidgets.painting; |
|||
using Unity.UIWidgets.rendering; |
|||
using Unity.UIWidgets.ui; |
|||
using Unity.UIWidgets.widgets; |
|||
using UnityEngine; |
|||
|
|||
namespace Unity.UIWidgets.material { |
|||
static class DrawerUtils { |
|||
public const float _kWidth = 304.0f; |
|||
public const float _kEdgeDragWidth = 20.0f; |
|||
public const float _kMinFlingVelocity = 365.0f; |
|||
public static readonly TimeSpan _kBaseSettleDuration = new TimeSpan(0, 0, 0, 0, 246); |
|||
} |
|||
|
|||
|
|||
public enum DrawerAlignment { |
|||
start, |
|||
end |
|||
} |
|||
|
|||
public class Drawer : StatelessWidget { |
|||
public Drawer( |
|||
Key key = null, |
|||
float elevation = 16.0f, |
|||
Widget child = null) : base(key: key) { |
|||
D.assert(elevation >= 0.0f); |
|||
this.elevation = elevation; |
|||
this.child = child; |
|||
} |
|||
|
|||
public readonly float elevation; |
|||
|
|||
public readonly Widget child; |
|||
|
|||
public override Widget build(BuildContext context) { |
|||
return new ConstrainedBox( |
|||
constraints: BoxConstraints.expand(width: DrawerUtils._kWidth), |
|||
child: new Material( |
|||
elevation: elevation, |
|||
child: child |
|||
) |
|||
); |
|||
} |
|||
} |
|||
|
|||
public delegate void DrawerCallback(bool isOpened); |
|||
|
|||
|
|||
public class DrawerController : StatefulWidget { |
|||
public DrawerController( |
|||
GlobalKey key = null, |
|||
Widget child = null, |
|||
DrawerAlignment? alignment = null, |
|||
DrawerCallback drawerCallback = null, |
|||
DragStartBehavior dragStartBehavior = DragStartBehavior.start |
|||
) : base(key: key) { |
|||
D.assert(child != null); |
|||
D.assert(alignment != null); |
|||
this.child = child; |
|||
this.alignment = alignment ?? DrawerAlignment.start; |
|||
this.drawerCallback = drawerCallback; |
|||
this.dragStartBehavior = dragStartBehavior; |
|||
} |
|||
|
|||
public readonly Widget child; |
|||
|
|||
public readonly DrawerAlignment alignment; |
|||
|
|||
public readonly DragStartBehavior? dragStartBehavior; |
|||
|
|||
public readonly DrawerCallback drawerCallback; |
|||
|
|||
public override State createState() { |
|||
return new DrawerControllerState(); |
|||
} |
|||
} |
|||
|
|||
|
|||
public class DrawerControllerState : SingleTickerProviderStateMixin<DrawerController> { |
|||
public override void initState() { |
|||
base.initState(); |
|||
_controller = new AnimationController(duration: DrawerUtils._kBaseSettleDuration, vsync: this); |
|||
_controller.addListener(_animationChanged); |
|||
_controller.addStatusListener(_animationStatusChanged); |
|||
} |
|||
|
|||
public override void dispose() { |
|||
_historyEntry?.remove(); |
|||
_controller.dispose(); |
|||
base.dispose(); |
|||
} |
|||
|
|||
void _animationChanged() { |
|||
setState(() => { }); |
|||
} |
|||
|
|||
LocalHistoryEntry _historyEntry; |
|||
readonly FocusScopeNode _focusScopeNode = new FocusScopeNode(); |
|||
|
|||
void _ensureHistoryEntry() { |
|||
if (_historyEntry == null) { |
|||
ModalRoute route = ModalRoute.of(context); |
|||
if (route != null) { |
|||
_historyEntry = new LocalHistoryEntry(onRemove: _handleHistoryEntryRemoved); |
|||
route.addLocalHistoryEntry(_historyEntry); |
|||
FocusScope.of(context).setFirstFocus(_focusScopeNode); |
|||
} |
|||
} |
|||
} |
|||
|
|||
void _animationStatusChanged(AnimationStatus status) { |
|||
switch (status) { |
|||
case AnimationStatus.forward: |
|||
_ensureHistoryEntry(); |
|||
break; |
|||
case AnimationStatus.reverse: |
|||
_historyEntry?.remove(); |
|||
_historyEntry = null; |
|||
break; |
|||
case AnimationStatus.dismissed: |
|||
break; |
|||
case AnimationStatus.completed: |
|||
break; |
|||
} |
|||
} |
|||
|
|||
void _handleHistoryEntryRemoved() { |
|||
_historyEntry = null; |
|||
close(); |
|||
} |
|||
|
|||
AnimationController _controller; |
|||
|
|||
|
|||
void _handleDragDown(DragDownDetails details) { |
|||
_controller.stop(); |
|||
_ensureHistoryEntry(); |
|||
} |
|||
|
|||
void _handleDragCancel() { |
|||
if (_controller.isDismissed || _controller.isAnimating) { |
|||
return; |
|||
} |
|||
|
|||
if (_controller.value < 0.5) { |
|||
close(); |
|||
} |
|||
else { |
|||
open(); |
|||
} |
|||
} |
|||
|
|||
public readonly GlobalKey _drawerKey = GlobalKey.key(); |
|||
|
|||
|
|||
float _width { |
|||
get { |
|||
RenderBox box = (RenderBox) _drawerKey.currentContext?.findRenderObject(); |
|||
if (box != null) { |
|||
return box.size.width; |
|||
} |
|||
|
|||
return DrawerUtils._kWidth; |
|||
} |
|||
} |
|||
|
|||
bool _previouslyOpened = false; |
|||
|
|||
void _move(DragUpdateDetails details) { |
|||
float delta = (details.primaryDelta ?? 0) / _width; |
|||
switch (widget.alignment) { |
|||
case DrawerAlignment.start: |
|||
break; |
|||
case DrawerAlignment.end: |
|||
delta = -delta; |
|||
break; |
|||
} |
|||
|
|||
_controller.setValue(_controller.value + delta); |
|||
|
|||
bool opened = _controller.value > 0.5; |
|||
if (opened != _previouslyOpened && widget.drawerCallback != null) { |
|||
widget.drawerCallback(opened); |
|||
} |
|||
|
|||
_previouslyOpened = opened; |
|||
} |
|||
|
|||
void _settle(DragEndDetails details) { |
|||
if (_controller.isDismissed) { |
|||
return; |
|||
} |
|||
|
|||
if (details.velocity.pixelsPerSecond.dx.abs() >= DrawerUtils._kMinFlingVelocity) { |
|||
float visualVelocity = details.velocity.pixelsPerSecond.dx / DrawerUtils._kWidth; |
|||
switch (widget.alignment) { |
|||
case DrawerAlignment.start: |
|||
break; |
|||
case DrawerAlignment.end: |
|||
visualVelocity = -visualVelocity; |
|||
break; |
|||
} |
|||
|
|||
_controller.fling(velocity: visualVelocity); |
|||
} |
|||
else if (_controller.value < 0.5) { |
|||
close(); |
|||
} |
|||
else { |
|||
open(); |
|||
} |
|||
} |
|||
|
|||
public void open() { |
|||
_controller.fling(velocity: 1.0f); |
|||
if (widget.drawerCallback != null) { |
|||
widget.drawerCallback(true); |
|||
} |
|||
} |
|||
|
|||
public void close() { |
|||
_controller.fling(velocity: -1.0f); |
|||
if (widget.drawerCallback != null) { |
|||
widget.drawerCallback(false); |
|||
} |
|||
} |
|||
|
|||
ColorTween _color = new ColorTween(begin: Colors.transparent, end: Colors.black54); |
|||
GlobalKey _gestureDetectorKey = GlobalKey.key(); |
|||
|
|||
Alignment _drawerOuterAlignment { |
|||
get { |
|||
switch (widget.alignment) { |
|||
case DrawerAlignment.start: |
|||
return Alignment.centerLeft; |
|||
case DrawerAlignment.end: |
|||
return Alignment.centerRight; |
|||
} |
|||
|
|||
return null; |
|||
} |
|||
} |
|||
|
|||
Alignment _drawerInnerAlignment { |
|||
get { |
|||
switch (widget.alignment) { |
|||
case DrawerAlignment.start: |
|||
return Alignment.centerRight; |
|||
case DrawerAlignment.end: |
|||
return Alignment.centerLeft; |
|||
} |
|||
|
|||
return null; |
|||
} |
|||
} |
|||
|
|||
Widget _buildDrawer(BuildContext context) { |
|||
bool drawerIsStart = widget.alignment == DrawerAlignment.start; |
|||
EdgeInsets padding = MediaQuery.of(context).padding; |
|||
float dragAreaWidth = drawerIsStart ? padding.left : padding.right; |
|||
|
|||
dragAreaWidth = Mathf.Max(dragAreaWidth, DrawerUtils._kEdgeDragWidth); |
|||
if (_controller.status == AnimationStatus.dismissed) { |
|||
return new Align( |
|||
alignment: _drawerOuterAlignment, |
|||
child: new GestureDetector( |
|||
key: _gestureDetectorKey, |
|||
onHorizontalDragUpdate: _move, |
|||
onHorizontalDragEnd: _settle, |
|||
behavior: HitTestBehavior.translucent, |
|||
dragStartBehavior: widget.dragStartBehavior ?? DragStartBehavior.down, |
|||
child: new Container(width: dragAreaWidth) |
|||
) |
|||
); |
|||
} |
|||
else { |
|||
return new GestureDetector( |
|||
key: _gestureDetectorKey, |
|||
onHorizontalDragDown: _handleDragDown, |
|||
onHorizontalDragUpdate: _move, |
|||
onHorizontalDragEnd: _settle, |
|||
onHorizontalDragCancel: _handleDragCancel, |
|||
dragStartBehavior: widget.dragStartBehavior ?? DragStartBehavior.down, |
|||
child: new RepaintBoundary( |
|||
child: new Stack( |
|||
children: new List<Widget> { |
|||
new GestureDetector( |
|||
onTap: close, |
|||
child: new Container( |
|||
color: _color.evaluate(_controller) |
|||
) |
|||
), |
|||
new Align( |
|||
alignment: _drawerOuterAlignment, |
|||
child: new Align( |
|||
alignment: _drawerInnerAlignment, |
|||
widthFactor: _controller.value, |
|||
child: new RepaintBoundary( |
|||
child: new FocusScope( |
|||
key: _drawerKey, |
|||
node: _focusScopeNode, |
|||
child: widget.child) |
|||
) |
|||
) |
|||
) |
|||
} |
|||
) |
|||
) |
|||
); |
|||
} |
|||
} |
|||
|
|||
|
|||
public override Widget build(BuildContext context) { |
|||
return new ListTileTheme( |
|||
style: ListTileStyle.drawer, |
|||
child: _buildDrawer(context)); |
|||
} |
|||
} |
|||
} |
|
|||
fileFormatVersion: 2 |
|||
guid: 82ae9917639b741da9df1fe50aeeca67 |
|||
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.painting; |
|||
using Unity.UIWidgets.widgets; |
|||
|
|||
namespace Unity.UIWidgets.material { |
|||
static class DrawerHeaderUtils { |
|||
public const float _kDrawerHeaderHeight = 160.0f + 1.0f; |
|||
} |
|||
|
|||
|
|||
public class DrawerHeader : StatelessWidget { |
|||
public DrawerHeader( |
|||
Key key = null, |
|||
Decoration decoration = null, |
|||
EdgeInsets margin = null, |
|||
EdgeInsets padding = null, |
|||
TimeSpan? duration = null, |
|||
Curve curve = null, |
|||
Widget child = null |
|||
) : base(key: key) { |
|||
D.assert(child != null); |
|||
this.decoration = decoration; |
|||
this.margin = margin ?? EdgeInsets.only(bottom: 8.0f); |
|||
this.padding = padding ?? EdgeInsets.fromLTRB(16.0f, 16.0f, 16.0f, 8.0f); |
|||
this.duration = duration ?? new TimeSpan(0, 0, 0, 0, 250); |
|||
this.curve = curve ?? Curves.fastOutSlowIn; |
|||
this.child = child; |
|||
} |
|||
|
|||
|
|||
public readonly Decoration decoration; |
|||
|
|||
public readonly EdgeInsets padding; |
|||
|
|||
public readonly EdgeInsets margin; |
|||
|
|||
public readonly TimeSpan duration; |
|||
|
|||
public readonly Curve curve; |
|||
|
|||
public readonly Widget child; |
|||
|
|||
|
|||
public override Widget build(BuildContext context) { |
|||
D.assert(MaterialD.debugCheckHasMaterial(context)); |
|||
ThemeData theme = Theme.of(context); |
|||
float statusBarHeight = MediaQuery.of(context).padding.top; |
|||
return new Container( |
|||
height: statusBarHeight + DrawerHeaderUtils._kDrawerHeaderHeight, |
|||
margin: margin, |
|||
decoration: new BoxDecoration( |
|||
border: new Border( |
|||
bottom: Divider.createBorderSide(context) |
|||
) |
|||
), |
|||
child: new AnimatedContainer( |
|||
padding: padding.add(EdgeInsets.only(top: statusBarHeight)), |
|||
decoration: decoration, |
|||
duration: duration, |
|||
curve: curve, |
|||
child: child == null |
|||
? null |
|||
: new DefaultTextStyle( |
|||
style: theme.textTheme.body2, |
|||
child: MediaQuery.removePadding( |
|||
context: context, |
|||
removeTop: true, |
|||
child: child) |
|||
) |
|||
) |
|||
); |
|||
} |
|||
} |
|||
} |
|
|||
fileFormatVersion: 2 |
|||
guid: b98e2be2eba264e28b3ca08fa93d0f2a |
|||
MonoImporter: |
|||
externalObjects: {} |
|||
serializedVersion: 2 |
|||
defaultReferences: [] |
|||
executionOrder: 0 |
|||
icon: {instanceID: 0} |
|||
userData: |
|||
assetBundleName: |
|||
assetBundleVariant: |
|
|||
using System; |
|||
using System.Collections.Generic; |
|||
using System.Linq; |
|||
using RSG; |
|||
using Unity.UIWidgets.animation; |
|||
using Unity.UIWidgets.foundation; |
|||
using Unity.UIWidgets.gestures; |
|||
using Unity.UIWidgets.painting; |
|||
using Unity.UIWidgets.rendering; |
|||
using Unity.UIWidgets.service; |
|||
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.material { |
|||
class DropdownConstants { |
|||
public static readonly TimeSpan _kDropdownMenuDuration = new TimeSpan(0, 0, 0, 0, 300); |
|||
public const float _kMenuItemHeight = 48.0f; |
|||
public const float _kDenseButtonHeight = 24.0f; |
|||
public static readonly EdgeInsets _kMenuItemPadding = EdgeInsets.symmetric(horizontal: 16.0f); |
|||
public static readonly EdgeInsets _kAlignedButtonPadding = EdgeInsets.only(left: 16.0f, right: 4.0f); |
|||
public static readonly EdgeInsets _kUnalignedButtonPadding = EdgeInsets.zero; |
|||
public static readonly EdgeInsets _kAlignedMenuMargin = EdgeInsets.zero; |
|||
public static readonly EdgeInsets _kUnalignedMenuMargin = EdgeInsets.only(left: 16.0f, right: 24.0f); |
|||
} |
|||
|
|||
class _DropdownMenuPainter : AbstractCustomPainter { |
|||
public _DropdownMenuPainter( |
|||
Color color = null, |
|||
int? elevation = null, |
|||
int? selectedIndex = null, |
|||
Animation<float> resize = null |
|||
) : base(repaint: resize) { |
|||
D.assert(elevation != null); |
|||
_painter = new BoxDecoration( |
|||
color: color, |
|||
borderRadius: BorderRadius.circular(2.0f), |
|||
boxShadow: ShadowConstants.kElevationToShadow[elevation ?? 0] |
|||
).createBoxPainter(); |
|||
this.color = color; |
|||
this.elevation = elevation; |
|||
this.selectedIndex = selectedIndex; |
|||
this.resize = resize; |
|||
} |
|||
|
|||
public readonly Color color; |
|||
public readonly int? elevation; |
|||
public readonly int? selectedIndex; |
|||
public readonly Animation<float> resize; |
|||
|
|||
public readonly BoxPainter _painter; |
|||
|
|||
public override void paint(Canvas canvas, Size size) { |
|||
float selectedItemOffset = selectedIndex ?? 0 * DropdownConstants._kMenuItemHeight + |
|||
Constants.kMaterialListPadding.top; |
|||
FloatTween top = new FloatTween( |
|||
begin: selectedItemOffset.clamp(0.0f, size.height - DropdownConstants._kMenuItemHeight), |
|||
end: 0.0f |
|||
); |
|||
|
|||
FloatTween bottom = new FloatTween( |
|||
begin: (top.begin + DropdownConstants._kMenuItemHeight).clamp(DropdownConstants._kMenuItemHeight, |
|||
size.height), |
|||
end: size.height |
|||
); |
|||
|
|||
Rect rect = Rect.fromLTRB(0.0f, top.evaluate(resize), size.width, bottom.evaluate(resize)); |
|||
|
|||
_painter.paint(canvas, rect.topLeft, new ImageConfiguration(size: rect.size)); |
|||
} |
|||
|
|||
public override bool shouldRepaint(CustomPainter painter) { |
|||
_DropdownMenuPainter oldPainter = painter as _DropdownMenuPainter; |
|||
return oldPainter.color != color |
|||
|| oldPainter.elevation != elevation |
|||
|| oldPainter.selectedIndex != selectedIndex |
|||
|| oldPainter.resize != resize; |
|||
} |
|||
} |
|||
|
|||
class _DropdownScrollBehavior : ScrollBehavior { |
|||
public _DropdownScrollBehavior() { |
|||
} |
|||
|
|||
public override Widget buildViewportChrome(BuildContext context, Widget child, AxisDirection axisDirection) { |
|||
return child; |
|||
} |
|||
|
|||
public override ScrollPhysics getScrollPhysics(BuildContext context) { |
|||
return new ClampingScrollPhysics(); |
|||
} |
|||
} |
|||
|
|||
class _DropdownMenu<T> : StatefulWidget where T : class { |
|||
public _DropdownMenu( |
|||
Key key = null, |
|||
EdgeInsets padding = null, |
|||
_DropdownRoute<T> route = null |
|||
) : base(key: key) { |
|||
this.route = route; |
|||
this.padding = padding; |
|||
} |
|||
|
|||
public readonly _DropdownRoute<T> route; |
|||
public readonly EdgeInsets padding; |
|||
|
|||
public override State createState() { |
|||
return new _DropdownMenuState<T>(); |
|||
} |
|||
} |
|||
|
|||
class _DropdownMenuState<T> : State<_DropdownMenu<T>> where T : class { |
|||
CurvedAnimation _fadeOpacity; |
|||
CurvedAnimation _resize; |
|||
|
|||
public _DropdownMenuState() { |
|||
} |
|||
|
|||
public override void initState() { |
|||
base.initState(); |
|||
_fadeOpacity = new CurvedAnimation( |
|||
parent: widget.route.animation, |
|||
curve: new Interval(0.0f, 0.25f), |
|||
reverseCurve: new Interval(0.75f, 1.0f) |
|||
); |
|||
_resize = new CurvedAnimation( |
|||
parent: widget.route.animation, |
|||
curve: new Interval(0.25f, 0.5f), |
|||
reverseCurve: new Threshold(0.0f) |
|||
); |
|||
} |
|||
|
|||
public override Widget build(BuildContext context) { |
|||
D.assert(MaterialD.debugCheckHasMaterialLocalizations(context)); |
|||
MaterialLocalizations localizations = MaterialLocalizations.of(context); |
|||
_DropdownRoute<T> route = widget.route; |
|||
float unit = 0.5f / (route.items.Count + 1.5f); |
|||
List<Widget> children = new List<Widget>(); |
|||
for (int itemIndex = 0; itemIndex < route.items.Count; ++itemIndex) { |
|||
CurvedAnimation opacity; |
|||
if (itemIndex == route.selectedIndex) { |
|||
opacity = new CurvedAnimation(parent: route.animation, curve: new Threshold(0.0f)); |
|||
} |
|||
else { |
|||
float start = (0.5f + (itemIndex + 1) * unit).clamp(0.0f, 1.0f); |
|||
float end = (start + 1.5f * unit).clamp(0.0f, 1.0f); |
|||
opacity = new CurvedAnimation(parent: route.animation, curve: new Interval(start, end)); |
|||
} |
|||
|
|||
var index = itemIndex; |
|||
children.Add(new FadeTransition( |
|||
opacity: opacity, |
|||
child: new InkWell( |
|||
child: new Container( |
|||
padding: widget.padding, |
|||
child: route.items[itemIndex] |
|||
), |
|||
onTap: () => Navigator.pop( |
|||
context, |
|||
new _DropdownRouteResult<T>(route.items[index].value) |
|||
) |
|||
) |
|||
)); |
|||
} |
|||
|
|||
return new FadeTransition( |
|||
opacity: _fadeOpacity, |
|||
child: new CustomPaint( |
|||
painter: new _DropdownMenuPainter( |
|||
color: Theme.of(context).canvasColor, |
|||
elevation: route.elevation, |
|||
selectedIndex: route.selectedIndex, |
|||
resize: _resize |
|||
), |
|||
child: new Material( |
|||
type: MaterialType.transparency, |
|||
textStyle: route.style, |
|||
child: new ScrollConfiguration( |
|||
behavior: new _DropdownScrollBehavior(), |
|||
child: new Scrollbar( |
|||
child: new ListView( |
|||
controller: widget.route.scrollController, |
|||
padding: Constants.kMaterialListPadding, |
|||
itemExtent: DropdownConstants._kMenuItemHeight, |
|||
shrinkWrap: true, |
|||
children: children |
|||
) |
|||
) |
|||
) |
|||
) |
|||
) |
|||
); |
|||
} |
|||
} |
|||
|
|||
class _DropdownMenuRouteLayout<T> : SingleChildLayoutDelegate { |
|||
public _DropdownMenuRouteLayout( |
|||
Rect buttonRect, |
|||
float menuTop, |
|||
float menuHeight |
|||
) { |
|||
this.buttonRect = buttonRect; |
|||
this.menuTop = menuTop; |
|||
this.menuHeight = menuHeight; |
|||
} |
|||
|
|||
public readonly Rect buttonRect; |
|||
public readonly float menuTop; |
|||
public readonly float menuHeight; |
|||
|
|||
public override BoxConstraints getConstraintsForChild(BoxConstraints constraints) { |
|||
float maxHeight = Mathf.Max(0.0f, constraints.maxHeight - 2 * DropdownConstants._kMenuItemHeight); |
|||
float width = Mathf.Min(constraints.maxWidth, buttonRect.width); |
|||
return new BoxConstraints( |
|||
minWidth: width, |
|||
maxWidth: width, |
|||
minHeight: 0.0f, |
|||
maxHeight: maxHeight |
|||
); |
|||
} |
|||
|
|||
public override Offset getPositionForChild(Size size, Size childSize) { |
|||
D.assert(() => { |
|||
Rect container = Offset.zero & size; |
|||
if (container.intersect(buttonRect) == buttonRect) { |
|||
D.assert(menuTop >= 0.0f); |
|||
D.assert(menuTop + menuHeight <= size.height); |
|||
} |
|||
|
|||
return true; |
|||
}); |
|||
float left = buttonRect.right.clamp(0.0f, size.width) - childSize.width; |
|||
return new Offset(left, menuTop); |
|||
} |
|||
|
|||
public override bool shouldRelayout(SingleChildLayoutDelegate _oldDelegate) { |
|||
_DropdownMenuRouteLayout<T> oldDelegate = _oldDelegate as _DropdownMenuRouteLayout<T>; |
|||
return buttonRect != oldDelegate.buttonRect |
|||
|| menuTop != oldDelegate.menuTop |
|||
|| menuHeight != oldDelegate.menuHeight; |
|||
} |
|||
} |
|||
|
|||
class _DropdownRouteResult<T> where T: class { |
|||
public _DropdownRouteResult(T result) { |
|||
this.result = result; |
|||
} |
|||
|
|||
public readonly T result; |
|||
|
|||
public static bool operator ==(_DropdownRouteResult<T> left, _DropdownRouteResult<T> right) { |
|||
return left.Equals(right); |
|||
} |
|||
|
|||
public static bool operator !=(_DropdownRouteResult<T> left, _DropdownRouteResult<T> right) { |
|||
return !left.Equals(right); |
|||
} |
|||
|
|||
public bool Equals(_DropdownRouteResult<T> other) { |
|||
return result == other.result; |
|||
} |
|||
|
|||
public override bool Equals(object obj) { |
|||
if (ReferenceEquals(null, obj)) { |
|||
return false; |
|||
} |
|||
if (ReferenceEquals(this, obj)) { |
|||
return true; |
|||
} |
|||
if (obj.GetType() != GetType()) { |
|||
return false; |
|||
} |
|||
return Equals((_DropdownRouteResult<T>) obj); |
|||
} |
|||
|
|||
public override int GetHashCode() { |
|||
return result.GetHashCode(); |
|||
} |
|||
} |
|||
|
|||
class _DropdownRoute<T> : PopupRoute where T : class { |
|||
public _DropdownRoute( |
|||
List<DropdownMenuItem<T>> items = null, |
|||
EdgeInsets padding = null, |
|||
Rect buttonRect = null, |
|||
int? selectedIndex = null, |
|||
int elevation = 8, |
|||
ThemeData theme = null, |
|||
TextStyle style = null, |
|||
string barrierLabel = null |
|||
) { |
|||
D.assert(style != null); |
|||
this.items = items; |
|||
this.padding = padding; |
|||
this.buttonRect = buttonRect; |
|||
this.selectedIndex = selectedIndex; |
|||
this.elevation = elevation; |
|||
this.theme = theme; |
|||
this.style = style; |
|||
this.barrierLabel = barrierLabel; |
|||
} |
|||
|
|||
public readonly List<DropdownMenuItem<T>> items; |
|||
public readonly EdgeInsets padding; |
|||
public readonly Rect buttonRect; |
|||
public readonly int? selectedIndex; |
|||
public readonly int elevation; |
|||
public readonly ThemeData theme; |
|||
public readonly TextStyle style; |
|||
|
|||
public ScrollController scrollController; |
|||
|
|||
public override TimeSpan transitionDuration { |
|||
get { return DropdownConstants._kDropdownMenuDuration; } |
|||
} |
|||
|
|||
public override bool barrierDismissible { |
|||
get { return true; } |
|||
} |
|||
|
|||
public override Color barrierColor { |
|||
get { return null; } |
|||
} |
|||
|
|||
public string barrierLabel; |
|||
|
|||
public override Widget buildPage(BuildContext context, Animation<float> animation, |
|||
Animation<float> secondaryAnimation) { |
|||
return new LayoutBuilder( |
|||
builder: (ctx, constraints) => { |
|||
return new _DropdownRoutePage<T>( |
|||
route: this, |
|||
constraints: constraints, |
|||
items: items, |
|||
padding: padding, |
|||
buttonRect: buttonRect, |
|||
selectedIndex: selectedIndex, |
|||
elevation: elevation, |
|||
theme: theme, |
|||
style: style |
|||
); |
|||
} |
|||
); |
|||
} |
|||
|
|||
internal void _dismiss() { |
|||
navigator?.removeRoute(this); |
|||
} |
|||
} |
|||
|
|||
class _DropdownRoutePage<T> : StatelessWidget where T : class { |
|||
public _DropdownRoutePage( |
|||
Key key = null, |
|||
_DropdownRoute<T> route = null, |
|||
BoxConstraints constraints = null, |
|||
List<DropdownMenuItem<T>> items = null, |
|||
EdgeInsets padding = null, |
|||
Rect buttonRect = null, |
|||
int? selectedIndex = null, |
|||
int elevation = 0, |
|||
ThemeData theme = null, |
|||
TextStyle style = null |
|||
) : base(key: key) { |
|||
this.route = route; |
|||
this.constraints = constraints; |
|||
this.items = items; |
|||
this.padding = padding; |
|||
this.buttonRect = buttonRect; |
|||
this.selectedIndex = selectedIndex; |
|||
this.elevation = elevation; |
|||
this.theme = theme; |
|||
this.style = style; |
|||
} |
|||
|
|||
public readonly _DropdownRoute<T> route; |
|||
public readonly BoxConstraints constraints; |
|||
public readonly List<DropdownMenuItem<T>> items; |
|||
public readonly EdgeInsets padding; |
|||
public readonly Rect buttonRect; |
|||
public readonly int? selectedIndex; |
|||
public readonly int elevation; |
|||
public readonly ThemeData theme; |
|||
public readonly TextStyle style; |
|||
|
|||
public override Widget build(BuildContext context) { |
|||
D.assert(WidgetsD.debugCheckHasDirectionality(context)); |
|||
float availableHeight = constraints.maxHeight; |
|||
float maxMenuHeight = availableHeight - 2.0f * DropdownConstants._kMenuItemHeight; |
|||
|
|||
float buttonTop = buttonRect.top; |
|||
float buttonBottom = Mathf.Min(buttonRect.bottom, availableHeight); |
|||
|
|||
float topLimit = Mathf.Min(DropdownConstants._kMenuItemHeight, buttonTop); |
|||
float bottomLimit = Mathf.Max(availableHeight - DropdownConstants._kMenuItemHeight, buttonBottom); |
|||
|
|||
float? selectedItemOffset = selectedIndex * DropdownConstants._kMenuItemHeight + |
|||
Constants.kMaterialListPadding.top; |
|||
|
|||
float? menuTop = (buttonTop - selectedItemOffset) - |
|||
(DropdownConstants._kMenuItemHeight - buttonRect.height) / 2.0f; |
|||
float preferredMenuHeight = (items.Count * DropdownConstants._kMenuItemHeight) + |
|||
Constants.kMaterialListPadding.vertical; |
|||
|
|||
float menuHeight = Mathf.Min(maxMenuHeight, preferredMenuHeight); |
|||
|
|||
float? menuBottom = menuTop + menuHeight; |
|||
|
|||
if (menuTop < topLimit) { |
|||
menuTop = Mathf.Min(buttonTop, topLimit); |
|||
} |
|||
|
|||
if (menuBottom > bottomLimit) { |
|||
menuBottom = Mathf.Max(buttonBottom, bottomLimit); |
|||
menuTop = menuBottom - menuHeight; |
|||
} |
|||
|
|||
if (route.scrollController == null) { |
|||
float scrollOffset = preferredMenuHeight > maxMenuHeight |
|||
? Mathf.Max(0.0f, selectedItemOffset ?? 0.0f - (buttonTop - (menuTop ?? 0.0f))) |
|||
: 0.0f; |
|||
route.scrollController = new ScrollController(initialScrollOffset: scrollOffset); |
|||
} |
|||
|
|||
Widget menu = new _DropdownMenu<T>( |
|||
route: route, |
|||
padding: padding |
|||
); |
|||
|
|||
if (theme != null) { |
|||
menu = new Theme(data: theme, child: menu); |
|||
} |
|||
|
|||
return MediaQuery.removePadding( |
|||
context: context, |
|||
removeTop: true, |
|||
removeBottom: true, |
|||
removeLeft: true, |
|||
removeRight: true, |
|||
child: new Builder( |
|||
builder: (BuildContext _context) => { |
|||
return new CustomSingleChildLayout( |
|||
layoutDelegate: new _DropdownMenuRouteLayout<T>( |
|||
buttonRect: buttonRect, |
|||
menuTop: menuTop ?? 0.0f, |
|||
menuHeight: menuHeight |
|||
), |
|||
child: menu |
|||
); |
|||
} |
|||
) |
|||
); |
|||
} |
|||
} |
|||
|
|||
public class DropdownMenuItem<T> : StatelessWidget where T : class { |
|||
public DropdownMenuItem( |
|||
Key key = null, |
|||
T value = null, |
|||
Widget child = null |
|||
) : base(key: key) { |
|||
D.assert(child != null); |
|||
this.value = value; |
|||
this.child = child; |
|||
} |
|||
|
|||
public readonly Widget child; |
|||
|
|||
public readonly T value; |
|||
|
|||
public override Widget build(BuildContext context) { |
|||
return new Container( |
|||
height: DropdownConstants._kMenuItemHeight, |
|||
alignment: Alignment.centerLeft, |
|||
child: child |
|||
); |
|||
} |
|||
} |
|||
|
|||
public class DropdownButtonHideUnderline : InheritedWidget { |
|||
public DropdownButtonHideUnderline( |
|||
Key key = null, |
|||
Widget child = null |
|||
) : base(key: key, child: child) { |
|||
D.assert(child != null); |
|||
} |
|||
|
|||
public static bool at(BuildContext context) { |
|||
return context.inheritFromWidgetOfExactType(typeof(DropdownButtonHideUnderline)) != null; |
|||
} |
|||
|
|||
public override bool updateShouldNotify(InheritedWidget oldWidget) { |
|||
return false; |
|||
} |
|||
} |
|||
|
|||
public class DropdownButton<T> : StatefulWidget where T : class { |
|||
public DropdownButton( |
|||
Key key = null, |
|||
List<DropdownMenuItem<T>> items = null, |
|||
T value = null, |
|||
Widget hint = null, |
|||
Widget disabledHint = null, |
|||
ValueChanged<T> onChanged = null, |
|||
int elevation = 8, |
|||
TextStyle style = null, |
|||
Widget underline = null, |
|||
Widget icon = null, |
|||
Color iconDisabledColor = null, |
|||
Color iconEnabledColor = null, |
|||
float iconSize = 24.0f, |
|||
bool isDense = false, |
|||
bool isExpanded = false |
|||
) : |
|||
base(key: key) { |
|||
D.assert(items == null || value == null || |
|||
items.Where<DropdownMenuItem<T>>((DropdownMenuItem<T> item) => item.value.Equals(value)).ToList() |
|||
.Count == 1); |
|||
this.items = items; |
|||
this.value = value; |
|||
this.hint = hint; |
|||
this.disabledHint = disabledHint; |
|||
this.onChanged = onChanged; |
|||
this.elevation = elevation; |
|||
this.style = style; |
|||
this.underline = underline; |
|||
this.icon = icon; |
|||
this.iconDisabledColor = iconDisabledColor; |
|||
this.iconEnabledColor = iconEnabledColor; |
|||
this.iconSize = iconSize; |
|||
this.isDense = isDense; |
|||
this.isExpanded = isExpanded; |
|||
} |
|||
|
|||
public readonly List<DropdownMenuItem<T>> items; |
|||
|
|||
public readonly T value; |
|||
|
|||
public readonly Widget hint; |
|||
|
|||
public readonly Widget disabledHint; |
|||
|
|||
public readonly ValueChanged<T> onChanged; |
|||
|
|||
public readonly int elevation; |
|||
|
|||
public readonly TextStyle style; |
|||
|
|||
public readonly Widget underline; |
|||
|
|||
public readonly Widget icon; |
|||
|
|||
public readonly Color iconDisabledColor; |
|||
|
|||
public readonly Color iconEnabledColor; |
|||
|
|||
public readonly float iconSize; |
|||
|
|||
public readonly bool isDense; |
|||
|
|||
public readonly bool isExpanded; |
|||
|
|||
public override State createState() { |
|||
return new _DropdownButtonState<T>(); |
|||
} |
|||
} |
|||
|
|||
class _DropdownButtonState<T> : State<DropdownButton<T>>, WidgetsBindingObserver where T : class { |
|||
int? _selectedIndex; |
|||
_DropdownRoute<T> _dropdownRoute; |
|||
|
|||
public void didChangeTextScaleFactor() { |
|||
} |
|||
|
|||
public void didChangeLocales(List<Locale> locale) { |
|||
} |
|||
|
|||
public IPromise<bool> didPopRoute() { |
|||
return Promise<bool>.Resolved(false); |
|||
} |
|||
|
|||
public IPromise<bool> didPushRoute(string route) { |
|||
return Promise<bool>.Resolved(false); |
|||
} |
|||
|
|||
public void didChangePlatformBrightness() { |
|||
} |
|||
|
|||
public override void initState() { |
|||
base.initState(); |
|||
_updateSelectedIndex(); |
|||
WidgetsBinding.instance.addObserver(this); |
|||
} |
|||
|
|||
public override void dispose() { |
|||
WidgetsBinding.instance.removeObserver(this); |
|||
_removeDropdownRoute(); |
|||
base.dispose(); |
|||
} |
|||
|
|||
public void didChangeMetrics() { |
|||
_removeDropdownRoute(); |
|||
} |
|||
|
|||
void _removeDropdownRoute() { |
|||
_dropdownRoute?._dismiss(); |
|||
_dropdownRoute = null; |
|||
} |
|||
|
|||
public override void didUpdateWidget(StatefulWidget oldWidget) { |
|||
base.didUpdateWidget(oldWidget); |
|||
_updateSelectedIndex(); |
|||
} |
|||
|
|||
void _updateSelectedIndex() { |
|||
if (!_enabled) { |
|||
return; |
|||
} |
|||
|
|||
D.assert(widget.value == null || |
|||
widget.items.Where((DropdownMenuItem<T> item) => item.value.Equals(widget.value)) |
|||
.ToList().Count == 1); |
|||
_selectedIndex = null; |
|||
for (int itemIndex = 0; itemIndex < widget.items.Count; itemIndex++) { |
|||
if (widget.items[itemIndex].value.Equals(widget.value)) { |
|||
_selectedIndex = itemIndex; |
|||
return; |
|||
} |
|||
} |
|||
} |
|||
|
|||
TextStyle _textStyle { |
|||
get { return widget.style ?? Theme.of(context).textTheme.subhead; } |
|||
} |
|||
|
|||
void _handleTap() { |
|||
RenderBox itemBox = (RenderBox) context.findRenderObject(); |
|||
Rect itemRect = itemBox.localToGlobal(Offset.zero) & itemBox.size; |
|||
EdgeInsets menuMargin = ButtonTheme.of(context).alignedDropdown |
|||
? DropdownConstants._kAlignedMenuMargin |
|||
: DropdownConstants._kUnalignedMenuMargin; |
|||
|
|||
D.assert(_dropdownRoute == null); |
|||
_dropdownRoute = new _DropdownRoute<T>( |
|||
items: widget.items, |
|||
buttonRect: menuMargin.inflateRect(itemRect), |
|||
padding: DropdownConstants._kMenuItemPadding, |
|||
selectedIndex: _selectedIndex ?? 0, |
|||
elevation: widget.elevation, |
|||
theme: Theme.of(context, shadowThemeOnly: true), |
|||
style: _textStyle, |
|||
barrierLabel: MaterialLocalizations.of(context).modalBarrierDismissLabel |
|||
); |
|||
|
|||
Navigator.push(context, _dropdownRoute).Then(newValue => { |
|||
_DropdownRouteResult<T> value = newValue as _DropdownRouteResult<T>; |
|||
_dropdownRoute = null; |
|||
if (!mounted || newValue == null) { |
|||
return; |
|||
} |
|||
|
|||
if (widget.onChanged != null) { |
|||
widget.onChanged(value.result); |
|||
} |
|||
}); |
|||
} |
|||
|
|||
float? _denseButtonHeight { |
|||
get { |
|||
return Mathf.Max(_textStyle.fontSize ?? 0.0f, |
|||
Mathf.Max(widget.iconSize, DropdownConstants._kDenseButtonHeight)); |
|||
} |
|||
} |
|||
|
|||
Color _iconColor { |
|||
get { |
|||
if (_enabled) { |
|||
if (widget.iconEnabledColor != null) { |
|||
return widget.iconEnabledColor; |
|||
} |
|||
|
|||
switch (Theme.of(context).brightness) { |
|||
case Brightness.light: |
|||
return Colors.grey.shade700; |
|||
case Brightness.dark: |
|||
return Colors.white70; |
|||
} |
|||
} |
|||
else { |
|||
if (widget.iconDisabledColor != null) { |
|||
return widget.iconDisabledColor; |
|||
} |
|||
|
|||
switch (Theme.of(context).brightness) { |
|||
case Brightness.light: |
|||
return Colors.grey.shade400; |
|||
case Brightness.dark: |
|||
return Colors.white10; |
|||
} |
|||
} |
|||
D.assert(false); |
|||
return null; |
|||
} |
|||
} |
|||
|
|||
bool _enabled { |
|||
get { return widget.items != null && widget.items.isNotEmpty() && widget.onChanged != null; } |
|||
} |
|||
|
|||
public override Widget build(BuildContext context) { |
|||
D.assert(MaterialD.debugCheckHasMaterial(context)); |
|||
D.assert(MaterialD.debugCheckHasMaterialLocalizations(context)); |
|||
|
|||
List<Widget> items = _enabled ? new List<Widget>(widget.items) : new List<Widget>(); |
|||
int hintIndex = 0; |
|||
if (widget.hint != null || (!_enabled && widget.disabledHint != null)) { |
|||
Widget emplacedHint = |
|||
_enabled |
|||
? widget.hint |
|||
: new DropdownMenuItem<Widget>(child: widget.disabledHint ?? widget.hint); |
|||
hintIndex = items.Count; |
|||
items.Add(new DefaultTextStyle( |
|||
style: _textStyle.copyWith(color: Theme.of(context).hintColor), |
|||
child: new IgnorePointer( |
|||
child: emplacedHint |
|||
) |
|||
)); |
|||
} |
|||
|
|||
EdgeInsets padding = ButtonTheme.of(context).alignedDropdown |
|||
? DropdownConstants._kAlignedButtonPadding |
|||
: DropdownConstants._kUnalignedButtonPadding; |
|||
|
|||
IndexedStack innerItemsWidget = new IndexedStack( |
|||
index: _enabled ? (_selectedIndex ?? hintIndex) : hintIndex, |
|||
alignment: Alignment.centerLeft, |
|||
children: items |
|||
); |
|||
|
|||
Icon defaultIcon = new Icon(Icons.arrow_drop_down); |
|||
Widget result = new DefaultTextStyle( |
|||
style: _textStyle, |
|||
child: new Container( |
|||
padding: padding, |
|||
height: widget.isDense ? _denseButtonHeight : null, |
|||
child: new Row( |
|||
mainAxisAlignment: MainAxisAlignment.spaceBetween, |
|||
mainAxisSize: MainAxisSize.min, |
|||
children: new List<Widget> { |
|||
widget.isExpanded ? new Expanded(child: innerItemsWidget) : (Widget) innerItemsWidget, |
|||
new IconTheme( |
|||
data: new IconThemeData( |
|||
color: _iconColor, |
|||
size: widget.iconSize |
|||
), |
|||
child: widget.icon ?? defaultIcon |
|||
) |
|||
} |
|||
) |
|||
) |
|||
); |
|||
|
|||
if (!DropdownButtonHideUnderline.at(context)) { |
|||
float bottom = widget.isDense ? 0.0f : 8.0f; |
|||
result = new Stack( |
|||
children: new List<Widget> { |
|||
result, |
|||
new Positioned( |
|||
left: 0.0f, |
|||
right: 0.0f, |
|||
bottom: bottom, |
|||
child: widget.underline ?? new Container( |
|||
height: 1.0f, |
|||
decoration: new BoxDecoration( |
|||
border: new Border( |
|||
bottom: new BorderSide(color: new Color(0xFFBDBDBD), width: 0.0f)) |
|||
) |
|||
) |
|||
) |
|||
} |
|||
); |
|||
} |
|||
|
|||
return new GestureDetector( |
|||
onTap: _enabled ? (GestureTapCallback) _handleTap : null, |
|||
behavior: HitTestBehavior.opaque, |
|||
child: result |
|||
); |
|||
} |
|||
} |
|||
|
|||
public class DropdownButtonFormField<T> : FormField<T> where T : class { |
|||
public DropdownButtonFormField( |
|||
Key key = null, |
|||
T value = null, |
|||
List<DropdownMenuItem<T>> items = null, |
|||
ValueChanged<T> onChanged = null, |
|||
InputDecoration decoration = null, |
|||
FormFieldSetter<T> onSaved = null, |
|||
FormFieldValidator<T> validator = null, |
|||
Widget hint = null |
|||
) : base( |
|||
key: key, |
|||
onSaved: onSaved, |
|||
initialValue: value, |
|||
validator: validator, |
|||
builder: (FormFieldState<T> field) => { |
|||
InputDecoration effectiveDecoration = (decoration ?? new InputDecoration()) |
|||
.applyDefaults(Theme.of(field.context).inputDecorationTheme); |
|||
return new InputDecorator( |
|||
decoration: effectiveDecoration.copyWith(errorText: field.errorText), |
|||
isEmpty: value == null, |
|||
child: new DropdownButtonHideUnderline( |
|||
child: new DropdownButton<T>( |
|||
isDense: true, |
|||
value: value, |
|||
items: items, |
|||
hint: hint, |
|||
onChanged: field.didChange |
|||
) |
|||
) |
|||
); |
|||
} |
|||
) { |
|||
this.onChanged = onChanged; |
|||
} |
|||
|
|||
public readonly ValueChanged<T> onChanged; |
|||
|
|||
public override State createState() { |
|||
return new _DropdownButtonFormFieldState<T>(); |
|||
} |
|||
} |
|||
|
|||
class _DropdownButtonFormFieldState<T> : FormFieldState<T> where T : class { |
|||
public new DropdownButtonFormField<T> widget { |
|||
get { return base.widget as DropdownButtonFormField<T>; } |
|||
} |
|||
|
|||
public override void didChange(T value) { |
|||
base.didChange(value); |
|||
if (widget.onChanged != null) { |
|||
widget.onChanged(value); |
|||
} |
|||
} |
|||
} |
|||
} |
|
|||
fileFormatVersion: 2 |
|||
guid: 54d382ec712d4e87b802716ca97c1f3d |
|||
timeCreated: 1552537966 |
|
|||
using System; |
|||
using Unity.UIWidgets.animation; |
|||
using Unity.UIWidgets.foundation; |
|||
using Unity.UIWidgets.painting; |
|||
using Unity.UIWidgets.service; |
|||
using Unity.UIWidgets.ui; |
|||
using Unity.UIWidgets.widgets; |
|||
using UnityEngine; |
|||
|
|||
namespace Unity.UIWidgets.material { |
|||
public class ExpandIcon : StatefulWidget { |
|||
public ExpandIcon( |
|||
Key key = null, |
|||
bool isExpanded = false, |
|||
float size = 24.0f, |
|||
ValueChanged<bool> onPressed = null, |
|||
EdgeInsets padding = null) : base(key: key) { |
|||
this.isExpanded = isExpanded; |
|||
this.size = size; |
|||
this.onPressed = onPressed; |
|||
this.padding = padding ?? EdgeInsets.all(8.0f); |
|||
} |
|||
|
|||
public readonly bool isExpanded; |
|||
|
|||
public readonly float size; |
|||
|
|||
public readonly ValueChanged<bool> onPressed; |
|||
|
|||
public readonly EdgeInsets padding; |
|||
|
|||
public override State createState() { |
|||
return new _ExpandIconState(); |
|||
} |
|||
} |
|||
|
|||
|
|||
public class _ExpandIconState : SingleTickerProviderStateMixin<ExpandIcon> { |
|||
AnimationController _controller; |
|||
Animation<float> _iconTurns; |
|||
|
|||
static readonly Animatable<float> _iconTurnTween = |
|||
new FloatTween(begin: 0.0f, end: 0.5f).chain(new CurveTween(curve: Curves.fastOutSlowIn)); |
|||
|
|||
public override void initState() { |
|||
base.initState(); |
|||
_controller = new AnimationController(duration: ThemeUtils.kThemeAnimationDuration, vsync: this); |
|||
_iconTurns = _controller.drive(_iconTurnTween); |
|||
if (widget.isExpanded) { |
|||
_controller.setValue(Mathf.PI); |
|||
} |
|||
} |
|||
|
|||
public override void dispose() { |
|||
_controller.dispose(); |
|||
base.dispose(); |
|||
} |
|||
|
|||
|
|||
public override void didUpdateWidget(StatefulWidget oldWidget) { |
|||
base.didUpdateWidget(oldWidget); |
|||
ExpandIcon _oldWidget = (ExpandIcon) oldWidget; |
|||
if (widget.isExpanded != _oldWidget.isExpanded) { |
|||
if (widget.isExpanded) { |
|||
_controller.forward(); |
|||
} |
|||
else { |
|||
_controller.reverse(); |
|||
} |
|||
} |
|||
} |
|||
|
|||
|
|||
void _handlePressed() { |
|||
if (widget.onPressed != null) { |
|||
widget.onPressed(widget.isExpanded); |
|||
} |
|||
} |
|||
|
|||
|
|||
public override Widget build(BuildContext context) { |
|||
D.assert(MaterialD.debugCheckHasMaterial(context)); |
|||
ThemeData theme = Theme.of(context); |
|||
return new IconButton( |
|||
padding: widget.padding, |
|||
color: theme.brightness == Brightness.dark ? Colors.white54 : Colors.black54, |
|||
onPressed: widget.onPressed == null ? (VoidCallback) null : _handlePressed, |
|||
icon: new RotationTransition( |
|||
turns: _iconTurns, |
|||
child: new Icon(Icons.expand_more)) |
|||
); |
|||
} |
|||
} |
|||
} |
|
|||
fileFormatVersion: 2 |
|||
guid: e4ab856e0b8e94feabef78ecb303733b |
|||
MonoImporter: |
|||
externalObjects: {} |
|||
serializedVersion: 2 |
|||
defaultReferences: [] |
|||
executionOrder: 0 |
|||
icon: {instanceID: 0} |
|||
userData: |
|||
assetBundleName: |
|||
assetBundleVariant: |
|
|||
using System; |
|||
using System.Collections.Generic; |
|||
using System.Linq; |
|||
using Unity.UIWidgets.animation; |
|||
using Unity.UIWidgets.foundation; |
|||
using Unity.UIWidgets.painting; |
|||
using Unity.UIWidgets.rendering; |
|||
using Unity.UIWidgets.widgets; |
|||
|
|||
namespace Unity.UIWidgets.material { |
|||
static class ExpansionPanelUtils { |
|||
public const float _kPanelHeaderCollapsedHeight = 48.0f; |
|||
public const float _kPanelHeaderExpandedHeight = 64.0f; |
|||
} |
|||
|
|||
|
|||
class _SaltedKey<S, V> : LocalKey { |
|||
public _SaltedKey( |
|||
S salt, |
|||
V value) { |
|||
this.salt = salt; |
|||
this.value = value; |
|||
} |
|||
|
|||
public readonly S salt; |
|||
|
|||
public readonly V value; |
|||
|
|||
public bool Equals(_SaltedKey<S, V> other) { |
|||
if (ReferenceEquals(null, other)) { |
|||
return false; |
|||
} |
|||
|
|||
if (ReferenceEquals(this, other)) { |
|||
return true; |
|||
} |
|||
|
|||
return other.salt.Equals(salt) |
|||
&& other.value.Equals(value); |
|||
} |
|||
|
|||
public override bool Equals(object obj) { |
|||
if (ReferenceEquals(null, obj)) { |
|||
return false; |
|||
} |
|||
|
|||
if (ReferenceEquals(this, obj)) { |
|||
return true; |
|||
} |
|||
|
|||
if (obj.GetType() != GetType()) { |
|||
return false; |
|||
} |
|||
|
|||
return Equals((_SaltedKey<S, V>) obj); |
|||
} |
|||
|
|||
public static bool operator ==(_SaltedKey<S, V> left, _SaltedKey<S, V> right) { |
|||
return Equals(left, right); |
|||
} |
|||
|
|||
public static bool operator !=(_SaltedKey<S, V> left, _SaltedKey<S, V> right) { |
|||
return !Equals(left, right); |
|||
} |
|||
|
|||
public override int GetHashCode() { |
|||
unchecked { |
|||
var hashCode = salt.GetHashCode(); |
|||
hashCode = (hashCode * 397) ^ value.GetHashCode(); |
|||
return hashCode; |
|||
} |
|||
} |
|||
|
|||
public override string ToString() { |
|||
string saltString = salt is string ? "<\'" + salt + "\'>" : "<" + salt + ">"; |
|||
string valueString = value is string ? "<\'" + value + "\'>" : "<" + value + ">"; |
|||
return "[" + saltString + " " + valueString + "]"; |
|||
} |
|||
} |
|||
|
|||
public delegate void ExpansionPanelCallback(int panelIndex, bool isExpanded); |
|||
|
|||
public delegate Widget ExpansionPanelHeaderBuilder(BuildContext context, bool isExpanded); |
|||
|
|||
|
|||
public class ExpansionPanel { |
|||
public ExpansionPanel( |
|||
ExpansionPanelHeaderBuilder headerBuilder = null, |
|||
Widget body = null, |
|||
bool isExpanded = false, |
|||
bool canTapOnHeader = false) { |
|||
D.assert(headerBuilder != null); |
|||
D.assert(body != null); |
|||
this.headerBuilder = headerBuilder; |
|||
this.body = body; |
|||
this.isExpanded = isExpanded; |
|||
this.canTapOnHeader = false; |
|||
} |
|||
|
|||
public readonly ExpansionPanelHeaderBuilder headerBuilder; |
|||
|
|||
public readonly Widget body; |
|||
|
|||
public readonly bool isExpanded; |
|||
|
|||
public readonly bool canTapOnHeader; |
|||
} |
|||
|
|||
|
|||
public class ExpansionPanelRadio : ExpansionPanel { |
|||
public ExpansionPanelRadio( |
|||
object value = null, |
|||
ExpansionPanelHeaderBuilder headerBuilder = null, |
|||
Widget body = null, |
|||
bool canTapOnHeader = false) |
|||
: base(body: body, headerBuilder: headerBuilder, canTapOnHeader: canTapOnHeader) { |
|||
D.assert(headerBuilder != null); |
|||
D.assert(body != null); |
|||
D.assert(value != null); |
|||
this.value = value; |
|||
} |
|||
|
|||
public readonly object value; |
|||
} |
|||
|
|||
public class ExpansionPanelList : StatefulWidget { |
|||
public ExpansionPanelList( |
|||
Key key = null, |
|||
List<ExpansionPanel> children = null, |
|||
ExpansionPanelCallback expansionCallback = null, |
|||
TimeSpan? animationDuration = null) : base(key: key) { |
|||
this.children = children ?? new List<ExpansionPanel>(); |
|||
this.expansionCallback = expansionCallback; |
|||
this.animationDuration = animationDuration ?? Constants.kThemeChangeDuration; |
|||
_allowOnlyOnePanelOpen = false; |
|||
initialOpenPanelValue = null; |
|||
} |
|||
|
|||
ExpansionPanelList( |
|||
Key key = null, |
|||
List<ExpansionPanel> children = null, |
|||
ExpansionPanelCallback expansionCallback = null, |
|||
TimeSpan? animationDuration = null, |
|||
object initialOpenPanelValue = null) : base(key: key) { |
|||
this.children = children ?? new List<ExpansionPanel>(); |
|||
this.expansionCallback = expansionCallback; |
|||
this.animationDuration = animationDuration ?? Constants.kThemeChangeDuration; |
|||
_allowOnlyOnePanelOpen = true; |
|||
this.initialOpenPanelValue = initialOpenPanelValue; |
|||
} |
|||
|
|||
public static ExpansionPanelList radio( |
|||
Key key = null, |
|||
List<ExpansionPanelRadio> children = null, |
|||
ExpansionPanelCallback expansionCallback = null, |
|||
TimeSpan? animationDuration = null, |
|||
object initialOpenPanelValue = null) { |
|||
children = children ?? new List<ExpansionPanelRadio>(); |
|||
var radio = new ExpansionPanelList( |
|||
key: key, |
|||
children: children.Cast<ExpansionPanel>().ToList(), |
|||
expansionCallback: expansionCallback, |
|||
animationDuration: animationDuration, |
|||
initialOpenPanelValue: initialOpenPanelValue |
|||
); |
|||
return radio; |
|||
} |
|||
|
|||
public readonly List<ExpansionPanel> children; |
|||
|
|||
public readonly ExpansionPanelCallback expansionCallback; |
|||
|
|||
public readonly TimeSpan animationDuration; |
|||
|
|||
public readonly bool _allowOnlyOnePanelOpen; |
|||
|
|||
public readonly object initialOpenPanelValue; |
|||
|
|||
public override State createState() { |
|||
return new _ExpansionPanelListState(); |
|||
} |
|||
} |
|||
|
|||
|
|||
public class _ExpansionPanelListState : State<ExpansionPanelList> { |
|||
ExpansionPanelRadio _currentOpenPanel; |
|||
|
|||
public override void initState() { |
|||
base.initState(); |
|||
if (widget._allowOnlyOnePanelOpen) { |
|||
D.assert(_allIdentifierUnique(), () => "All object identifiers are not unique!"); |
|||
foreach (ExpansionPanelRadio child in widget.children) { |
|||
if (widget.initialOpenPanelValue != null && |
|||
child.value == widget.initialOpenPanelValue) { |
|||
_currentOpenPanel = child; |
|||
} |
|||
} |
|||
} |
|||
} |
|||
|
|||
public override void didUpdateWidget(StatefulWidget oldWidget) { |
|||
base.didUpdateWidget(oldWidget); |
|||
ExpansionPanelList _oldWidget = (ExpansionPanelList) oldWidget; |
|||
if (widget._allowOnlyOnePanelOpen) { |
|||
D.assert(_allIdentifierUnique(), () => "All object identifiers are not unique!"); |
|||
foreach (ExpansionPanelRadio newChild in widget.children) { |
|||
if (widget.initialOpenPanelValue != null && |
|||
newChild.value == widget.initialOpenPanelValue) { |
|||
_currentOpenPanel = newChild; |
|||
} |
|||
} |
|||
} |
|||
else if (_oldWidget._allowOnlyOnePanelOpen) { |
|||
_currentOpenPanel = null; |
|||
} |
|||
} |
|||
|
|||
bool _allIdentifierUnique() { |
|||
Dictionary<object, bool> identifierMap = new Dictionary<object, bool>(); |
|||
foreach (ExpansionPanelRadio child in widget.children) { |
|||
identifierMap[child.value] = true; |
|||
} |
|||
|
|||
return identifierMap.Count == widget.children.Count; |
|||
} |
|||
|
|||
bool _isChildExpanded(int index) { |
|||
if (widget._allowOnlyOnePanelOpen) { |
|||
ExpansionPanelRadio radioWidget = (ExpansionPanelRadio) widget.children[index]; |
|||
return _currentOpenPanel?.value == radioWidget.value; |
|||
} |
|||
|
|||
return widget.children[index].isExpanded; |
|||
} |
|||
|
|||
void _handlePressed(bool isExpanded, int index) { |
|||
if (widget.expansionCallback != null) { |
|||
widget.expansionCallback(index, isExpanded); |
|||
} |
|||
|
|||
if (widget._allowOnlyOnePanelOpen) { |
|||
ExpansionPanelRadio pressedChild = (ExpansionPanelRadio) widget.children[index]; |
|||
|
|||
for (int childIndex = 0; childIndex < widget.children.Count; childIndex++) { |
|||
ExpansionPanelRadio child = (ExpansionPanelRadio) widget.children[childIndex]; |
|||
if (widget.expansionCallback != null && childIndex != index && |
|||
child.value == _currentOpenPanel?.value) { |
|||
widget.expansionCallback(childIndex, false); |
|||
} |
|||
} |
|||
|
|||
_currentOpenPanel = isExpanded ? null : pressedChild; |
|||
} |
|||
|
|||
setState(() => { }); |
|||
} |
|||
|
|||
public override Widget build(BuildContext context) { |
|||
List<MergeableMaterialItem> items = new List<MergeableMaterialItem>(); |
|||
EdgeInsets kExpandedEdgeInsets = EdgeInsets.symmetric( |
|||
vertical: ExpansionPanelUtils._kPanelHeaderExpandedHeight - |
|||
ExpansionPanelUtils._kPanelHeaderCollapsedHeight); |
|||
|
|||
for (int index = 0; index < widget.children.Count; index++) { |
|||
int expandIndex = index; |
|||
if (_isChildExpanded(index) && index != 0 && !_isChildExpanded(index - 1)) { |
|||
items.Add(new MaterialGap( |
|||
key: new _SaltedKey<BuildContext, int>(context, index * 2 - 1))); |
|||
} |
|||
|
|||
ExpansionPanel child = widget.children[index]; |
|||
Widget headerWidget = child.headerBuilder( |
|||
context, |
|||
_isChildExpanded(index) |
|||
); |
|||
Row header = new Row( |
|||
children: new List<Widget> { |
|||
new Expanded( |
|||
child: new AnimatedContainer( |
|||
duration: widget.animationDuration, |
|||
curve: Curves.fastOutSlowIn, |
|||
margin: _isChildExpanded(index) ? kExpandedEdgeInsets : EdgeInsets.zero, |
|||
child: new ConstrainedBox( |
|||
constraints: new BoxConstraints( |
|||
minHeight: ExpansionPanelUtils._kPanelHeaderCollapsedHeight), |
|||
child: headerWidget |
|||
) |
|||
) |
|||
), |
|||
new Container( |
|||
margin: EdgeInsets.fromLTRB(0, 0, 8, 0), |
|||
child: new ExpandIcon( |
|||
isExpanded: _isChildExpanded(index), |
|||
padding: EdgeInsets.all(16.0f), |
|||
onPressed: !child.canTapOnHeader |
|||
? (ValueChanged<bool>) ((bool isExpanded) => { |
|||
_handlePressed(isExpanded, expandIndex); |
|||
}) |
|||
: null |
|||
) |
|||
) |
|||
} |
|||
); |
|||
|
|||
items.Add(new MaterialSlice( |
|||
key: new _SaltedKey<BuildContext, int>(context, index * 2), |
|||
child: new Column( |
|||
children: new List<Widget> { |
|||
child.canTapOnHeader |
|||
? (Widget) new InkWell( |
|||
onTap: () => |
|||
_handlePressed(_isChildExpanded(expandIndex), expandIndex), |
|||
child: header |
|||
) |
|||
: header, |
|||
new AnimatedCrossFade( |
|||
firstChild: new Container(height: 0.0f), |
|||
secondChild: child.body, |
|||
firstCurve: new Interval(0.0f, 0.6f, curve: Curves.fastOutSlowIn), |
|||
secondCurve: new Interval(0.4f, 1.0f, curve: Curves.fastOutSlowIn), |
|||
sizeCurve: Curves.fastOutSlowIn, |
|||
crossFadeState: _isChildExpanded(index) |
|||
? CrossFadeState.showSecond |
|||
: CrossFadeState.showFirst, |
|||
duration: widget.animationDuration |
|||
) |
|||
} |
|||
) |
|||
) |
|||
); |
|||
|
|||
if (_isChildExpanded(index) && index != widget.children.Count - 1) { |
|||
items.Add(new MaterialGap( |
|||
key: new _SaltedKey<BuildContext, int>(context, index * 2 + 1))); |
|||
} |
|||
} |
|||
|
|||
return new MergeableMaterial( |
|||
hasDividers: true, |
|||
children: items); |
|||
} |
|||
} |
|||
} |
|
|||
fileFormatVersion: 2 |
|||
guid: dcaf0d752807146868207f41db41ccb1 |
|||
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.ui; |
|||
using Unity.UIWidgets.widgets; |
|||
|
|||
namespace Unity.UIWidgets.material { |
|||
static class ExpansionTileUtils { |
|||
public static readonly TimeSpan _kExpand = new TimeSpan(0, 0, 0, 0, 200); |
|||
} |
|||
|
|||
public class ExpansionTile : StatefulWidget { |
|||
public ExpansionTile( |
|||
Key key = null, |
|||
Widget leading = null, |
|||
Widget title = null, |
|||
Color backgroundColor = null, |
|||
ValueChanged<bool> onExpansionChanged = null, |
|||
List<Widget> children = null, |
|||
Widget trailing = null, |
|||
bool initiallyExpanded = false |
|||
) : base(key: key) { |
|||
D.assert(title != null); |
|||
this.leading = leading; |
|||
this.title = title; |
|||
this.backgroundColor = backgroundColor; |
|||
this.onExpansionChanged = onExpansionChanged; |
|||
this.children = children ?? new List<Widget>(); |
|||
this.trailing = trailing; |
|||
this.initiallyExpanded = initiallyExpanded; |
|||
} |
|||
|
|||
public readonly Widget leading; |
|||
|
|||
public readonly Widget title; |
|||
|
|||
public readonly ValueChanged<bool> onExpansionChanged; |
|||
|
|||
public readonly List<Widget> children; |
|||
|
|||
public readonly Color backgroundColor; |
|||
|
|||
public readonly Widget trailing; |
|||
|
|||
public readonly bool initiallyExpanded; |
|||
|
|||
public override State createState() { |
|||
return new _ExpansionTileState(); |
|||
} |
|||
} |
|||
|
|||
public class _ExpansionTileState : SingleTickerProviderStateMixin<ExpansionTile> { |
|||
static readonly Animatable<float> _easeOutTween = new CurveTween(curve: Curves.easeOut); |
|||
static readonly Animatable<float> _easeInTween = new CurveTween(curve: Curves.easeIn); |
|||
static readonly Animatable<float> _halfTween = new FloatTween(begin: 0.0f, end: 0.5f); |
|||
|
|||
readonly ColorTween _borderColorTween = new ColorTween(); |
|||
readonly ColorTween _headerColorTween = new ColorTween(); |
|||
readonly ColorTween _iconColorTween = new ColorTween(); |
|||
readonly ColorTween _backgroundColorTween = new ColorTween(); |
|||
|
|||
AnimationController _controller; |
|||
Animation<float> _iconTurns; |
|||
Animation<float> _heightFactor; |
|||
Animation<Color> _borderColor; |
|||
Animation<Color> _headerColor; |
|||
Animation<Color> _iconColor; |
|||
Animation<Color> _backgroundColor; |
|||
|
|||
bool _isExpanded = false; |
|||
|
|||
public override void initState() { |
|||
base.initState(); |
|||
_controller = new AnimationController(duration: ExpansionTileUtils._kExpand, vsync: this); |
|||
_heightFactor = _controller.drive(_easeInTween); |
|||
_iconTurns = _controller.drive(_halfTween.chain(_easeInTween)); |
|||
_borderColor = _controller.drive(_borderColorTween.chain(_easeOutTween)); |
|||
_headerColor = _controller.drive(_headerColorTween.chain(_easeInTween)); |
|||
_iconColor = _controller.drive(_iconColorTween.chain(_easeInTween)); |
|||
_backgroundColor = _controller.drive(_backgroundColorTween.chain(_easeOutTween)); |
|||
|
|||
_isExpanded = PageStorage.of(context)?.readState(context) == null |
|||
? widget.initiallyExpanded |
|||
: (bool) PageStorage.of(context)?.readState(context); |
|||
|
|||
if (_isExpanded) { |
|||
_controller.setValue(1.0f); |
|||
} |
|||
} |
|||
|
|||
public override void dispose() { |
|||
_controller.dispose(); |
|||
base.dispose(); |
|||
} |
|||
|
|||
void _handleTap() { |
|||
setState(() => { |
|||
_isExpanded = !_isExpanded; |
|||
if (_isExpanded) { |
|||
_controller.forward(); |
|||
} |
|||
else { |
|||
_controller.reverse().Then(() => { |
|||
if (!mounted) { |
|||
return; |
|||
} |
|||
|
|||
setState(() => { }); |
|||
}); |
|||
} |
|||
|
|||
PageStorage.of(context)?.writeState(context, _isExpanded); |
|||
}); |
|||
if (widget.onExpansionChanged != null) { |
|||
widget.onExpansionChanged(_isExpanded); |
|||
} |
|||
} |
|||
|
|||
Widget _buildChildren(BuildContext context, Widget child) { |
|||
Color borderSideColor = _borderColor.value ?? Colors.transparent; |
|||
|
|||
return new Container( |
|||
decoration: new BoxDecoration( |
|||
color: _backgroundColor.value ?? Colors.transparent, |
|||
border: new Border( |
|||
top: new BorderSide(color: borderSideColor), |
|||
bottom: new BorderSide(color: borderSideColor))), |
|||
child: new Column( |
|||
mainAxisSize: MainAxisSize.min, |
|||
children: new List<Widget> { |
|||
ListTileTheme.merge( |
|||
iconColor: _iconColor.value, |
|||
textColor: _headerColor.value, |
|||
child: new ListTile( |
|||
onTap: _handleTap, |
|||
leading: widget.leading, |
|||
title: widget.title, |
|||
trailing: widget.trailing ?? new RotationTransition( |
|||
turns: _iconTurns, |
|||
child: new Icon(Icons.expand_more) |
|||
) |
|||
) |
|||
), |
|||
new ClipRect( |
|||
child: new Align( |
|||
heightFactor: _heightFactor.value, |
|||
child: child) |
|||
) |
|||
} |
|||
) |
|||
); |
|||
} |
|||
|
|||
public override void didChangeDependencies() { |
|||
ThemeData theme = Theme.of(context); |
|||
_borderColorTween.end = theme.dividerColor; |
|||
_headerColorTween.begin = theme.textTheme.subhead.color; |
|||
_headerColorTween.end = theme.accentColor; |
|||
_iconColorTween.begin = theme.unselectedWidgetColor; |
|||
_iconColorTween.end = theme.accentColor; |
|||
_backgroundColorTween.end = widget.backgroundColor; |
|||
base.didChangeDependencies(); |
|||
} |
|||
|
|||
public override Widget build(BuildContext context) { |
|||
bool closed = !_isExpanded && _controller.isDismissed; |
|||
return new AnimatedBuilder( |
|||
animation: _controller.view, |
|||
builder: _buildChildren, |
|||
child: closed ? null : new Column(children: widget.children)); |
|||
} |
|||
} |
|||
} |
|
|||
fileFormatVersion: 2 |
|||
guid: dd2974d0b3bb843e782324d1b493fe24 |
|||
MonoImporter: |
|||
externalObjects: {} |
|||
serializedVersion: 2 |
|||
defaultReferences: [] |
|||
executionOrder: 0 |
|||
icon: {instanceID: 0} |
|||
userData: |
|||
assetBundleName: |
|||
assetBundleVariant: |
|
|||
using RSG; |
|||
using Unity.UIWidgets.gestures; |
|||
using Unity.UIWidgets.widgets; |
|||
using UnityEngine; |
|||
|
|||
namespace Unity.UIWidgets.material { |
|||
public class Feedback { |
|||
Feedback() { |
|||
} |
|||
|
|||
public static IPromise forTap(BuildContext context) { |
|||
switch (_platform(context)) { |
|||
case RuntimePlatform.Android: |
|||
return |
|||
Promise.Resolved(); // SystemSound.play(SystemSoundType.click); TODO: replace with unity equivalent
|
|||
default: |
|||
return Promise.Resolved(); |
|||
} |
|||
} |
|||
|
|||
public static GestureTapCallback wrapForTap(GestureTapCallback callback, BuildContext context) { |
|||
if (callback == null) { |
|||
return null; |
|||
} |
|||
|
|||
return () => { |
|||
forTap(context); |
|||
callback(); |
|||
}; |
|||
} |
|||
|
|||
public static IPromise forLongPress(BuildContext context) { |
|||
switch (_platform(context)) { |
|||
case RuntimePlatform.Android: |
|||
return Promise.Resolved(); // HapticFeedback.vibrate(); TODO
|
|||
default: |
|||
return Promise.Resolved(); |
|||
} |
|||
} |
|||
|
|||
public static GestureLongPressCallback |
|||
wrapForLongPress(GestureLongPressCallback callback, BuildContext context) { |
|||
if (callback == null) { |
|||
return null; |
|||
} |
|||
|
|||
return () => { |
|||
forLongPress(context); |
|||
callback(); |
|||
}; |
|||
} |
|||
|
|||
static RuntimePlatform _platform(BuildContext context) { |
|||
return Theme.of(context).platform; |
|||
} |
|||
} |
|||
} |
|
|||
fileFormatVersion: 2 |
|||
guid: 40b01a32a0bc4afc9de46b001ebd9b99 |
|||
timeCreated: 1554815981 |
|
|||
using System.Collections.Generic; |
|||
using Unity.UIWidgets.foundation; |
|||
using Unity.UIWidgets.painting; |
|||
using Unity.UIWidgets.rendering; |
|||
using Unity.UIWidgets.service; |
|||
using Unity.UIWidgets.ui; |
|||
using Unity.UIWidgets.widgets; |
|||
|
|||
namespace Unity.UIWidgets.material { |
|||
public class FlatButton : MaterialButton { |
|||
public FlatButton( |
|||
Key key = null, |
|||
VoidCallback onPressed = null, |
|||
ValueChanged<bool> onHighlightChanged = null, |
|||
ButtonTextTheme? textTheme = null, |
|||
Color textColor = null, |
|||
Color disabledTextColor = null, |
|||
Color color = null, |
|||
Color disabledColor = null, |
|||
Color highlightColor = null, |
|||
Color splashColor = null, |
|||
Brightness? colorBrightness = null, |
|||
EdgeInsets padding = null, |
|||
ShapeBorder shape = null, |
|||
Clip? clipBehavior = Clip.none, |
|||
MaterialTapTargetSize? materialTapTargetSize = null, |
|||
Widget child = null) : base( |
|||
key: key, |
|||
onPressed: onPressed, |
|||
onHighlightChanged: onHighlightChanged, |
|||
textTheme: textTheme, |
|||
textColor: textColor, |
|||
disabledTextColor: disabledTextColor, |
|||
color: color, |
|||
disabledColor: disabledColor, |
|||
highlightColor: highlightColor, |
|||
splashColor: splashColor, |
|||
colorBrightness: colorBrightness, |
|||
padding: padding, |
|||
shape: shape, |
|||
clipBehavior: clipBehavior, |
|||
materialTapTargetSize: materialTapTargetSize, |
|||
child: child) { |
|||
} |
|||
|
|||
public static FlatButton icon( |
|||
Key key = null, |
|||
VoidCallback onPressed = null, |
|||
ValueChanged<bool> onHighlightChanged = null, |
|||
ButtonTextTheme? textTheme = null, |
|||
Color textColor = null, |
|||
Color disabledTextColor = null, |
|||
Color color = null, |
|||
Color disabledColor = null, |
|||
Color highlightColor = null, |
|||
Color splashColor = null, |
|||
Brightness? colorBrightness = null, |
|||
EdgeInsets padding = null, |
|||
ShapeBorder shape = null, |
|||
Clip? clipBehavior = null, |
|||
MaterialTapTargetSize? materialTapTargetSize = null, |
|||
Widget icon = null, |
|||
Widget label = null) { |
|||
D.assert(icon != null); |
|||
D.assert(label != null); |
|||
|
|||
return new _FlatButtonWithIcon( |
|||
key: key, |
|||
onPressed: onPressed, |
|||
onHighlightChanged: onHighlightChanged, |
|||
textTheme: textTheme, |
|||
textColor: textColor, |
|||
disabledTextColor: disabledTextColor, |
|||
color: color, |
|||
disabledColor: disabledColor, |
|||
highlightColor: highlightColor, |
|||
splashColor: splashColor, |
|||
colorBrightness: colorBrightness, |
|||
padding: padding, |
|||
shape: shape, |
|||
clipBehavior: clipBehavior, |
|||
materialTapTargetSize: materialTapTargetSize, |
|||
icon: icon, |
|||
label: label |
|||
); |
|||
} |
|||
|
|||
public override Widget build(BuildContext context) { |
|||
ThemeData theme = Theme.of(context); |
|||
ButtonThemeData buttonTheme = ButtonTheme.of(context); |
|||
|
|||
return new RawMaterialButton( |
|||
onPressed: onPressed, |
|||
onHighlightChanged: onHighlightChanged, |
|||
clipBehavior: clipBehavior ?? Clip.none, |
|||
fillColor: buttonTheme.getFillColor(this), |
|||
textStyle: theme.textTheme.button.copyWith(color: buttonTheme.getTextColor(this)), |
|||
highlightColor: buttonTheme.getHighlightColor(this), |
|||
splashColor: buttonTheme.getSplashColor(this), |
|||
elevation: buttonTheme.getElevation(this), |
|||
highlightElevation: buttonTheme.getHighlightElevation(this), |
|||
disabledElevation: buttonTheme.getDisabledElevation(this), |
|||
padding: buttonTheme.getPadding(this), |
|||
constraints: buttonTheme.getConstraints(this), |
|||
shape: buttonTheme.getShape(this), |
|||
animationDuration: buttonTheme.getAnimationDuration(this), |
|||
materialTapTargetSize: buttonTheme.getMaterialTapTargetSize(this), |
|||
child: child |
|||
); |
|||
} |
|||
|
|||
public override void debugFillProperties(DiagnosticPropertiesBuilder properties) { |
|||
base.debugFillProperties(properties); |
|||
properties.add(new ObjectFlagProperty<VoidCallback>("onPressed", onPressed, ifNull: "disabled")); |
|||
properties.add(new DiagnosticsProperty<ButtonTextTheme?>("textTheme", textTheme, defaultValue: null)); |
|||
properties.add(new DiagnosticsProperty<Color>("textColor", textColor, defaultValue: null)); |
|||
properties.add(new DiagnosticsProperty<Color>("disabledTextColor", disabledTextColor, |
|||
defaultValue: null)); |
|||
properties.add(new DiagnosticsProperty<Color>("color", color, defaultValue: null)); |
|||
properties.add(new DiagnosticsProperty<Color>("disabledColor", disabledColor, defaultValue: null)); |
|||
properties.add(new DiagnosticsProperty<Color>("highlightColor", highlightColor, defaultValue: null)); |
|||
properties.add(new DiagnosticsProperty<Color>("splashColor", splashColor, defaultValue: null)); |
|||
properties.add(new DiagnosticsProperty<Brightness?>("colorBrightness", colorBrightness, |
|||
defaultValue: null)); |
|||
properties.add(new DiagnosticsProperty<EdgeInsets>("padding", padding, defaultValue: null)); |
|||
properties.add(new DiagnosticsProperty<ShapeBorder>("shape", shape, defaultValue: null)); |
|||
properties.add(new DiagnosticsProperty<MaterialTapTargetSize?>("materialTapTargetSize", |
|||
materialTapTargetSize, defaultValue: null)); |
|||
} |
|||
} |
|||
|
|||
class _FlatButtonWithIcon : FlatButton, MaterialButtonWithIconMixin { |
|||
public _FlatButtonWithIcon( |
|||
Key key = null, |
|||
VoidCallback onPressed = null, |
|||
ValueChanged<bool> onHighlightChanged = null, |
|||
ButtonTextTheme? textTheme = null, |
|||
Color textColor = null, |
|||
Color disabledTextColor = null, |
|||
Color color = null, |
|||
Color disabledColor = null, |
|||
Color highlightColor = null, |
|||
Color splashColor = null, |
|||
Brightness? colorBrightness = null, |
|||
EdgeInsets padding = null, |
|||
ShapeBorder shape = null, |
|||
Clip? clipBehavior = null, |
|||
MaterialTapTargetSize? materialTapTargetSize = null, |
|||
Widget icon = null, |
|||
Widget label = null) : base( |
|||
key: key, |
|||
onPressed: onPressed, |
|||
onHighlightChanged: onHighlightChanged, |
|||
textTheme: textTheme, |
|||
textColor: textColor, |
|||
disabledTextColor: disabledTextColor, |
|||
color: color, |
|||
disabledColor: disabledColor, |
|||
highlightColor: highlightColor, |
|||
splashColor: splashColor, |
|||
colorBrightness: colorBrightness, |
|||
padding: padding, |
|||
shape: shape, |
|||
clipBehavior: clipBehavior, |
|||
materialTapTargetSize: materialTapTargetSize, |
|||
child: new Row( |
|||
mainAxisSize: MainAxisSize.min, |
|||
children: new List<Widget> { |
|||
icon, |
|||
new SizedBox(width: 8.0f), |
|||
label |
|||
} |
|||
)) { |
|||
D.assert(icon != null); |
|||
D.assert(label != null); |
|||
} |
|||
} |
|||
} |
|
|||
fileFormatVersion: 2 |
|||
guid: ad54f63ca420e42518aead08e1b27526 |
|||
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, |
|||
EdgeInsets titlePadding = null, |
|||
CollapseMode collapseMode = CollapseMode.parallax |
|||
) : base(key: key) { |
|||
this.title = title; |
|||
this.background = background; |
|||
this.centerTitle = centerTitle; |
|||
this.titlePadding = titlePadding; |
|||
this.collapseMode = collapseMode; |
|||
} |
|||
|
|||
public readonly Widget title; |
|||
|
|||
public readonly Widget background; |
|||
|
|||
public readonly bool? centerTitle; |
|||
|
|||
public readonly CollapseMode collapseMode; |
|||
|
|||
public readonly EdgeInsets titlePadding; |
|||
|
|||
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 (widget.centerTitle != null) { |
|||
return widget.centerTitle; |
|||
} |
|||
|
|||
switch (themeData.platform) { |
|||
case RuntimePlatform.IPhonePlayer: |
|||
return true; |
|||
default: |
|||
return false; |
|||
} |
|||
} |
|||
|
|||
|
|||
Alignment _getTitleAlignment(bool effectiveCenterTitle) { |
|||
if (effectiveCenterTitle) { |
|||
return Alignment.bottomCenter; |
|||
} |
|||
|
|||
return Alignment.bottomLeft; |
|||
} |
|||
|
|||
float? _getCollapsePadding(float t, FlexibleSpaceBarSettings settings) { |
|||
switch (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 (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: _getCollapsePadding(t, settings), |
|||
left: 0.0f, |
|||
right: 0.0f, |
|||
height: settings.maxExtent, |
|||
child: new Opacity( |
|||
opacity: opacity, |
|||
child: widget.background) |
|||
) |
|||
); |
|||
} |
|||
} |
|||
|
|||
Widget title = null; |
|||
if (widget.title != null) { |
|||
switch (Application.platform) { |
|||
case RuntimePlatform.IPhonePlayer: |
|||
title = widget.title; |
|||
break; |
|||
default: |
|||
title = 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 = _getEffectiveCenterTitle(theme).Value; |
|||
EdgeInsets padding = widget.titlePadding ?? |
|||
EdgeInsets.only( |
|||
left: effectiveCenterTitle ? 0.0f : 72.0f, |
|||
bottom: 16.0f |
|||
); |
|||
float scaleValue = new FloatTween(begin: 1.5f, end: 1.0f).lerp(t); |
|||
Matrix4 scaleTransform = new Matrix4().diagonal3Values(scaleValue, scaleValue, 1); |
|||
Alignment titleAlignment = _getTitleAlignment(effectiveCenterTitle); |
|||
|
|||
children.Add(new Container( |
|||
padding: padding, |
|||
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 toolbarOpacity != _oldWidget.toolbarOpacity |
|||
|| minExtent != _oldWidget.minExtent |
|||
|| maxExtent != _oldWidget.maxExtent |
|||
|| 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; |
|||
using TextStyle = Unity.UIWidgets.painting.TextStyle; |
|||
|
|||
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 : StatelessWidget { |
|||
FloatingActionButton( |
|||
Key key = null, |
|||
Widget child = null, |
|||
string tooltip = null, |
|||
Color foregroundColor = null, |
|||
Color backgroundColor = null, |
|||
object heroTag = null, |
|||
float? elevation = null, |
|||
float? highlightElevation = null, |
|||
float? disabledElevation = null, |
|||
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) { |
|||
D.assert(elevation == null || elevation >= 0.0f); |
|||
D.assert(highlightElevation == null || highlightElevation >= 0.0f); |
|||
D.assert(disabledElevation == null || disabledElevation >= 0.0f); |
|||
heroTag = heroTag ?? new _DefaultHeroTag(); |
|||
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.disabledElevation = disabledElevation; |
|||
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 = null, |
|||
float? highlightElevation = null, |
|||
float? disabledElevation = null, |
|||
VoidCallback onPressed = null, |
|||
ShapeBorder shape = null, |
|||
bool isExtended = true, |
|||
MaterialTapTargetSize? materialTapTargetSize = null, |
|||
Clip clipBehavior = Clip.none, |
|||
Widget icon = null, |
|||
Widget label = null |
|||
) { |
|||
D.assert(elevation == null || elevation >= 0.0f); |
|||
D.assert(highlightElevation == null || highlightElevation >= 0.0f); |
|||
D.assert(disabledElevation == null || disabledElevation >= 0.0f); |
|||
D.assert(label != null); |
|||
heroTag = heroTag ?? new _DefaultHeroTag(); |
|||
|
|||
BoxConstraints _sizeConstraints = FloatActionButtonUtils._kExtendedSizeConstraints; |
|||
bool mini = false; |
|||
Widget child = new _ChildOverflowBox( |
|||
child: new Row( |
|||
mainAxisSize: MainAxisSize.min, |
|||
children: icon == null |
|||
? new List<Widget> { |
|||
new SizedBox(width: 20.0f), |
|||
label, |
|||
new SizedBox(width: 20.0f), |
|||
} |
|||
: 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, |
|||
disabledElevation: disabledElevation, |
|||
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 float? disabledElevation; |
|||
|
|||
public readonly bool mini; |
|||
|
|||
public readonly ShapeBorder shape; |
|||
|
|||
public readonly Clip clipBehavior; |
|||
|
|||
public readonly bool isExtended; |
|||
|
|||
public readonly MaterialTapTargetSize? materialTapTargetSize; |
|||
|
|||
readonly BoxConstraints _sizeConstraints; |
|||
|
|||
const float _defaultElevation = 6; |
|||
const float _defaultHighlightElevation = 12; |
|||
readonly ShapeBorder _defaultShape = new CircleBorder(); |
|||
readonly ShapeBorder _defaultExtendedShape = new StadiumBorder(); |
|||
|
|||
public override Widget build(BuildContext context) { |
|||
ThemeData theme = Theme.of(context); |
|||
FloatingActionButtonThemeData floatingActionButtonTheme = theme.floatingActionButtonTheme; |
|||
Color backgroundColor = this.backgroundColor |
|||
?? floatingActionButtonTheme.backgroundColor |
|||
?? theme.colorScheme.secondary; |
|||
Color foregroundColor = this.foregroundColor |
|||
?? floatingActionButtonTheme.foregroundColor |
|||
?? theme.accentIconTheme.color |
|||
?? theme.colorScheme.onSecondary; |
|||
|
|||
float elevation = this.elevation |
|||
?? floatingActionButtonTheme.elevation |
|||
?? _defaultElevation; |
|||
float disabledElevation = this.disabledElevation |
|||
?? floatingActionButtonTheme.disabledElevation |
|||
?? elevation; |
|||
float highlightElevation = this.highlightElevation |
|||
?? floatingActionButtonTheme.highlightElevation |
|||
?? _defaultHighlightElevation; |
|||
MaterialTapTargetSize materialTapTargetSize = this.materialTapTargetSize |
|||
?? theme.materialTapTargetSize; |
|||
TextStyle textStyle = theme.accentTextTheme.button.copyWith( |
|||
color: foregroundColor, |
|||
letterSpacing: 1.2f |
|||
); |
|||
ShapeBorder shape = this.shape |
|||
?? floatingActionButtonTheme.shape |
|||
?? (isExtended ? _defaultExtendedShape : _defaultShape); |
|||
|
|||
Widget result = null; |
|||
|
|||
if (child != null) { |
|||
result = IconTheme.merge( |
|||
data: new IconThemeData( |
|||
color: foregroundColor), |
|||
child: child |
|||
); |
|||
} |
|||
|
|||
result = new RawMaterialButton( |
|||
onPressed: onPressed, |
|||
elevation: elevation, |
|||
highlightElevation: highlightElevation, |
|||
disabledElevation: disabledElevation, |
|||
constraints: _sizeConstraints, |
|||
materialTapTargetSize: materialTapTargetSize, |
|||
fillColor: backgroundColor, |
|||
textStyle: textStyle, |
|||
shape: shape, |
|||
clipBehavior: clipBehavior, |
|||
child: result); |
|||
|
|||
if (tooltip != null) { |
|||
result = new Tooltip( |
|||
message: tooltip, |
|||
child: result); |
|||
} |
|||
|
|||
if (heroTag != null) { |
|||
result = new Hero( |
|||
tag: 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 (child != null) { |
|||
child.layout(new BoxConstraints(), parentUsesSize: true); |
|||
size = new Size( |
|||
Mathf.Max(constraints.minWidth, Mathf.Min(constraints.maxWidth, child.size.width)), |
|||
Mathf.Max(constraints.minHeight, Mathf.Min(constraints.maxHeight, child.size.height)) |
|||
); |
|||
alignChild(); |
|||
} |
|||
else { |
|||
size = constraints.biggest; |
|||
} |
|||
} |
|||
} |
|||
} |
|
|||
fileFormatVersion: 2 |
|||
guid: 44d53f5996891c54780cbc0073567bfd |
|||
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 static float _leftOffset(ScaffoldPrelayoutGeometry scaffoldGeometry, float offset = 0.0f) { |
|||
return kFloatingActionButtonMargin |
|||
+ scaffoldGeometry.minInsets.left |
|||
- offset; |
|||
} |
|||
|
|||
public static float _rightOffset(ScaffoldPrelayoutGeometry scaffoldGeometry, float offset = 0.0f) { |
|||
return scaffoldGeometry.scaffoldSize.width |
|||
- kFloatingActionButtonMargin |
|||
- scaffoldGeometry.minInsets.right |
|||
- scaffoldGeometry.floatingActionButtonSize.width |
|||
+ offset; |
|||
} |
|||
|
|||
public static float _endOffset(ScaffoldPrelayoutGeometry scaffoldGeometry, float offset = 0.0f) { |
|||
return _rightOffset(scaffoldGeometry, offset: offset); |
|||
} |
|||
|
|||
public static float _startOffset(ScaffoldPrelayoutGeometry scaffoldGeometry, float offset = 0.0f) { |
|||
return _leftOffset(scaffoldGeometry, offset: offset); |
|||
} |
|||
|
|||
public static float _straddleAppBar(ScaffoldPrelayoutGeometry scaffoldGeometry) { |
|||
float fabHalfHeight = scaffoldGeometry.floatingActionButtonSize.height / 2.0f; |
|||
return scaffoldGeometry.contentTop - fabHalfHeight; |
|||
} |
|||
} |
|||
|
|||
|
|||
public abstract class FloatingActionButtonLocation { |
|||
protected FloatingActionButtonLocation() { |
|||
} |
|||
|
|||
public static readonly FloatingActionButtonLocation endFloat = new _EndFloatFloatingActionButtonLocation(); |
|||
|
|||
public static readonly FloatingActionButtonLocation |
|||
centerFloat = new _CenterFloatFloatingActionButtonLocation(); |
|||
|
|||
public static readonly FloatingActionButtonLocation endDocked = new _EndDockedFloatingActionButtonLocation(); |
|||
|
|||
public static readonly FloatingActionButtonLocation centerDocked = |
|||
new _CenterDockedFloatingActionButtonLocation(); |
|||
|
|||
public static readonly FloatingActionButtonLocation startTop = new _StartTopFloatingActionButtonLocation(); |
|||
|
|||
public static readonly FloatingActionButtonLocation miniStartTop = |
|||
new _MiniStartTopFloatingActionButtonLocation(); |
|||
|
|||
public static readonly FloatingActionButtonLocation endTop = new _EndTopFloatingActionButtonLocation(); |
|||
|
|||
public abstract Offset getOffset(ScaffoldPrelayoutGeometry scaffoldGeometry); |
|||
|
|||
public override string ToString() { |
|||
return GetType().ToString(); |
|||
} |
|||
} |
|||
|
|||
class _CenterFloatFloatingActionButtonLocation : FloatingActionButtonLocation { |
|||
public _CenterFloatFloatingActionButtonLocation() { |
|||
} |
|||
|
|||
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); |
|||
} |
|||
|
|||
public override string ToString() { |
|||
return "FloatingActionButtonLocation.centerFloat"; |
|||
} |
|||
} |
|||
|
|||
class _EndFloatFloatingActionButtonLocation : FloatingActionButtonLocation { |
|||
public _EndFloatFloatingActionButtonLocation() { |
|||
} |
|||
|
|||
public override Offset getOffset(ScaffoldPrelayoutGeometry scaffoldGeometry) { |
|||
float fabX = FloatingActionButtonLocationUtils._endOffset(scaffoldGeometry); |
|||
|
|||
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); |
|||
} |
|||
|
|||
public override string ToString() { |
|||
return "FloatingActionButtonLocation.endFloat"; |
|||
} |
|||
} |
|||
|
|||
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 fabX = FloatingActionButtonLocationUtils._endOffset(scaffoldGeometry); |
|||
return new Offset(fabX, getDockedY(scaffoldGeometry)); |
|||
} |
|||
|
|||
public override string ToString() { |
|||
return "FloatingActionButtonLocation.endDocked"; |
|||
} |
|||
} |
|||
|
|||
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, getDockedY(scaffoldGeometry)); |
|||
} |
|||
|
|||
public override string ToString() { |
|||
return "FloatingActionButtonLocation.centerDocked"; |
|||
} |
|||
} |
|||
|
|||
|
|||
class _StartTopFloatingActionButtonLocation : FloatingActionButtonLocation { |
|||
public _StartTopFloatingActionButtonLocation() { |
|||
} |
|||
|
|||
public override Offset getOffset(ScaffoldPrelayoutGeometry scaffoldGeometry) { |
|||
return new Offset(FloatingActionButtonLocationUtils._startOffset(scaffoldGeometry), |
|||
FloatingActionButtonLocationUtils._straddleAppBar(scaffoldGeometry)); |
|||
} |
|||
|
|||
public override string ToString() { |
|||
return "FloatingActionButtonLocation.startTop"; |
|||
} |
|||
} |
|||
|
|||
class _MiniStartTopFloatingActionButtonLocation : FloatingActionButtonLocation { |
|||
public _MiniStartTopFloatingActionButtonLocation() { |
|||
} |
|||
|
|||
public override Offset getOffset(ScaffoldPrelayoutGeometry scaffoldGeometry) { |
|||
return new Offset(FloatingActionButtonLocationUtils._startOffset(scaffoldGeometry, offset: 4.0f), |
|||
FloatingActionButtonLocationUtils._straddleAppBar(scaffoldGeometry)); |
|||
} |
|||
|
|||
public override string ToString() { |
|||
return "FloatingActionButtonLocation.miniStartTop"; |
|||
} |
|||
} |
|||
|
|||
class _EndTopFloatingActionButtonLocation : FloatingActionButtonLocation { |
|||
public _EndTopFloatingActionButtonLocation() { |
|||
} |
|||
|
|||
public override Offset getOffset(ScaffoldPrelayoutGeometry scaffoldGeometry) { |
|||
return new Offset(FloatingActionButtonLocationUtils._endOffset(scaffoldGeometry), |
|||
FloatingActionButtonLocationUtils._straddleAppBar(scaffoldGeometry)); |
|||
} |
|||
|
|||
public override string ToString() { |
|||
return "FloatingActionButtonLocation.endTop"; |
|||
} |
|||
} |
|||
|
|||
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 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 parent.value < swapThreshold ? first.value : next.value; } |
|||
} |
|||
} |
|||
} |
|
|||
fileFormatVersion: 2 |
|||
guid: 6c8b71fe76d6bdb4ca66ecad56f25d3f |
|||
MonoImporter: |
|||
externalObjects: {} |
|||
serializedVersion: 2 |
|||
defaultReferences: [] |
|||
executionOrder: 0 |
|||
icon: {instanceID: 0} |
|||
userData: |
|||
assetBundleName: |
|||
assetBundleVariant: |
|
|||
using Unity.UIWidgets.foundation; |
|||
using Unity.UIWidgets.painting; |
|||
using Unity.UIWidgets.ui; |
|||
|
|||
namespace Unity.UIWidgets.material { |
|||
public class FloatingActionButtonThemeData : Diagnosticable { |
|||
public FloatingActionButtonThemeData( |
|||
Color backgroundColor = null, |
|||
Color foregroundColor = null, |
|||
float? elevation = null, |
|||
float? disabledElevation = null, |
|||
float? highlightElevation = null, |
|||
ShapeBorder shape = null |
|||
) { |
|||
this.backgroundColor = backgroundColor; |
|||
this.foregroundColor = foregroundColor; |
|||
this.elevation = elevation; |
|||
this.disabledElevation = disabledElevation; |
|||
this.highlightElevation = highlightElevation; |
|||
this.shape = shape; |
|||
} |
|||
|
|||
public readonly Color backgroundColor; |
|||
|
|||
public readonly Color foregroundColor; |
|||
|
|||
public readonly float? elevation; |
|||
|
|||
public readonly float? disabledElevation; |
|||
|
|||
public readonly float? highlightElevation; |
|||
|
|||
public readonly ShapeBorder shape; |
|||
|
|||
public FloatingActionButtonThemeData copyWith( |
|||
Color backgroundColor, |
|||
Color foregroundColor, |
|||
float? elevation, |
|||
float? disabledElevation, |
|||
float? highlightElevation, |
|||
ShapeBorder shape |
|||
) { |
|||
return new FloatingActionButtonThemeData( |
|||
backgroundColor: backgroundColor ?? this.backgroundColor, |
|||
foregroundColor: foregroundColor ?? this.foregroundColor, |
|||
elevation: elevation ?? this.elevation, |
|||
disabledElevation: disabledElevation ?? this.disabledElevation, |
|||
highlightElevation: highlightElevation ?? this.highlightElevation, |
|||
shape: shape ?? this.shape |
|||
); |
|||
} |
|||
|
|||
public static FloatingActionButtonThemeData lerp(FloatingActionButtonThemeData a, FloatingActionButtonThemeData b, |
|||
float t) { |
|||
if (a == null && b == null) { |
|||
return null; |
|||
} |
|||
|
|||
return new FloatingActionButtonThemeData( |
|||
backgroundColor: Color.lerp(a?.backgroundColor, b?.backgroundColor, t), |
|||
foregroundColor: Color.lerp(a?.foregroundColor, b?.foregroundColor, t), |
|||
elevation: MathUtils.lerpFloat(a?.elevation ?? 0, b?.elevation ?? 0, t), |
|||
disabledElevation: MathUtils.lerpFloat(a?.disabledElevation ?? 0, b?.disabledElevation ?? 0, t), |
|||
highlightElevation: MathUtils.lerpFloat(a?.highlightElevation ?? 0, b?.highlightElevation ?? 0, t), |
|||
shape: ShapeBorder.lerp(a?.shape, b?.shape, t) |
|||
); |
|||
} |
|||
|
|||
public override int GetHashCode() { |
|||
var hashCode = backgroundColor?.GetHashCode() ?? 0; |
|||
hashCode = (hashCode * 397) ^ foregroundColor?.GetHashCode() ?? 0; |
|||
hashCode = (hashCode * 397) ^ elevation?.GetHashCode() ?? 0; |
|||
hashCode = (hashCode * 397) ^ disabledElevation?.GetHashCode() ?? 0; |
|||
hashCode = (hashCode * 397) ^ highlightElevation?.GetHashCode() ?? 0; |
|||
hashCode = (hashCode * 397) ^ shape?.GetHashCode() ?? 0; |
|||
return hashCode; |
|||
} |
|||
|
|||
public bool Equals(FloatingActionButtonThemeData other) { |
|||
if (ReferenceEquals(null, other)) { |
|||
return false; |
|||
} |
|||
|
|||
if (ReferenceEquals(this, other)) { |
|||
return true; |
|||
} |
|||
|
|||
return Equals(backgroundColor, other.backgroundColor) |
|||
&& Equals(elevation, other.elevation) |
|||
&& Equals(shape, other.shape) |
|||
&& Equals(foregroundColor, other.foregroundColor) |
|||
&& Equals(disabledElevation, other.disabledElevation) |
|||
&& Equals(highlightElevation, other.highlightElevation); |
|||
} |
|||
|
|||
public override bool Equals(object obj) { |
|||
if (ReferenceEquals(null, obj)) { |
|||
return false; |
|||
} |
|||
|
|||
if (ReferenceEquals(this, obj)) { |
|||
return true; |
|||
} |
|||
|
|||
if (obj.GetType() != GetType()) { |
|||
return false; |
|||
} |
|||
|
|||
return Equals((FloatingActionButtonThemeData) obj); |
|||
} |
|||
|
|||
public override void debugFillProperties(DiagnosticPropertiesBuilder properties) { |
|||
base.debugFillProperties(properties); |
|||
FloatingActionButtonThemeData defaultData = new FloatingActionButtonThemeData(); |
|||
|
|||
properties.add(new DiagnosticsProperty<Color>("backgroundColor", backgroundColor, |
|||
defaultValue: defaultData.backgroundColor)); |
|||
properties.add(new DiagnosticsProperty<Color>("foregroundColor", foregroundColor, |
|||
defaultValue: defaultData.foregroundColor)); |
|||
properties.add(new DiagnosticsProperty<float?>("elevation", elevation, |
|||
defaultValue: defaultData.elevation)); |
|||
properties.add(new DiagnosticsProperty<float?>("disabledElevation", disabledElevation, |
|||
defaultValue: defaultData.disabledElevation)); |
|||
properties.add(new DiagnosticsProperty<float?>("highlightElevation", highlightElevation, |
|||
defaultValue: defaultData.highlightElevation)); |
|||
properties.add(new DiagnosticsProperty<ShapeBorder>("shape", shape, defaultValue: defaultData.shape)); |
|||
} |
|||
} |
|||
} |
|
|||
fileFormatVersion: 2 |
|||
guid: f2f4277e1c02b5b4281b4fc2b7ac3e21 |
|||
MonoImporter: |
|||
externalObjects: {} |
|||
serializedVersion: 2 |
|||
defaultReferences: [] |
|||
executionOrder: 0 |
|||
icon: {instanceID: 0} |
|||
userData: |
|||
assetBundleName: |
|||
assetBundleVariant: |
|
|||
using System.Collections.Generic; |
|||
using Unity.UIWidgets.foundation; |
|||
using Unity.UIWidgets.widgets; |
|||
|
|||
namespace Unity.UIWidgets.material { |
|||
public class GridTile : StatelessWidget { |
|||
public GridTile( |
|||
Key key = null, |
|||
Widget header = null, |
|||
Widget footer = null, |
|||
Widget child = null) : base(key: key) { |
|||
D.assert(child != null); |
|||
this.header = header; |
|||
this.footer = footer; |
|||
this.child = child; |
|||
} |
|||
|
|||
public readonly Widget header; |
|||
|
|||
public readonly Widget footer; |
|||
|
|||
public readonly Widget child; |
|||
|
|||
public override Widget build(BuildContext context) { |
|||
if (header == null && footer == null) { |
|||
return child; |
|||
} |
|||
|
|||
List<Widget> children = new List<Widget> { |
|||
Positioned.fill( |
|||
child: child) |
|||
}; |
|||
if (header != null) { |
|||
children.Add(new Positioned( |
|||
top: 0.0f, |
|||
left: 0.0f, |
|||
right: 0.0f, |
|||
child: header)); |
|||
} |
|||
|
|||
if (footer != null) { |
|||
children.Add(new Positioned( |
|||
left: 0.0f, |
|||
bottom: 0.0f, |
|||
right: 0.0f, |
|||
child: footer)); |
|||
} |
|||
|
|||
return new Stack( |
|||
children: children); |
|||
} |
|||
} |
|||
} |
|
|||
fileFormatVersion: 2 |
|||
guid: 8613dcab63f30445c80e76df18408797 |
|||
MonoImporter: |
|||
externalObjects: {} |
|||
serializedVersion: 2 |
|||
defaultReferences: [] |
|||
executionOrder: 0 |
|||
icon: {instanceID: 0} |
|||
userData: |
|||
assetBundleName: |
|||
assetBundleVariant: |
|
|||
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 IconButtonUtils { |
|||
public const float _kMinButtonSize = 48.0f; |
|||
} |
|||
|
|||
|
|||
public class IconButton : StatelessWidget { |
|||
public IconButton( |
|||
Key key = null, |
|||
float iconSize = 24.0f, |
|||
EdgeInsets padding = null, |
|||
Alignment alignment = null, |
|||
Widget icon = null, |
|||
Color color = null, |
|||
Color highlightColor = null, |
|||
Color splashColor = null, |
|||
Color disableColor = null, |
|||
VoidCallback onPressed = null, |
|||
string tooltip = null) : base(key: key) { |
|||
D.assert(icon != null); |
|||
|
|||
this.iconSize = iconSize; |
|||
this.padding = padding ?? EdgeInsets.all(8.0f); |
|||
this.alignment = alignment ?? Alignment.center; |
|||
this.icon = icon; |
|||
this.color = color; |
|||
this.highlightColor = highlightColor; |
|||
this.splashColor = splashColor; |
|||
disabledColor = disableColor; |
|||
this.onPressed = onPressed; |
|||
this.tooltip = tooltip; |
|||
} |
|||
|
|||
public readonly float iconSize; |
|||
|
|||
public readonly EdgeInsets padding; |
|||
|
|||
public readonly Alignment alignment; |
|||
|
|||
public readonly Widget icon; |
|||
|
|||
public readonly Color color; |
|||
|
|||
public readonly Color splashColor; |
|||
|
|||
public readonly Color highlightColor; |
|||
|
|||
public readonly Color disabledColor; |
|||
|
|||
public readonly VoidCallback onPressed; |
|||
|
|||
public readonly string tooltip; |
|||
|
|||
public override Widget build(BuildContext context) { |
|||
D.assert(MaterialD.debugCheckHasMaterial(context)); |
|||
Color currentColor; |
|||
if (onPressed != null) { |
|||
currentColor = color; |
|||
} |
|||
else { |
|||
currentColor = disabledColor ?? Theme.of(context).disabledColor; |
|||
} |
|||
|
|||
Widget result = new ConstrainedBox( |
|||
constraints: new BoxConstraints(minWidth: IconButtonUtils._kMinButtonSize, |
|||
minHeight: IconButtonUtils._kMinButtonSize), |
|||
child: new Padding( |
|||
padding: padding, |
|||
child: new SizedBox( |
|||
height: iconSize, |
|||
width: iconSize, |
|||
child: new Align( |
|||
alignment: alignment, |
|||
child: IconTheme.merge( |
|||
data: new IconThemeData( |
|||
size: iconSize, |
|||
color: currentColor), |
|||
child: icon) |
|||
) |
|||
) |
|||
) |
|||
); |
|||
|
|||
if (tooltip != null) { |
|||
result = new Tooltip( |
|||
message: tooltip, |
|||
child: result); |
|||
} |
|||
|
|||
return new InkResponse( |
|||
onTap: () => { |
|||
if (onPressed != null) { |
|||
onPressed(); |
|||
} |
|||
}, |
|||
child: result, |
|||
highlightColor: highlightColor ?? Theme.of(context).highlightColor, |
|||
splashColor: splashColor ?? Theme.of(context).splashColor, |
|||
radius: Mathf.Max( |
|||
Material.defaultSplashRadius, |
|||
(iconSize + Mathf.Min(padding.horizontal, padding.vertical)) * 0.7f) |
|||
); |
|||
} |
|||
|
|||
|
|||
public override void debugFillProperties(DiagnosticPropertiesBuilder properties) { |
|||
base.debugFillProperties(properties); |
|||
properties.add(new DiagnosticsProperty<Widget>("icon", icon, showName: false)); |
|||
properties.add(new ObjectFlagProperty<VoidCallback>("onPressed", onPressed, ifNull: "disabled")); |
|||
properties.add(new StringProperty("tooltip", tooltip, defaultValue: null, quoted: false)); |
|||
} |
|||
} |
|||
} |
|
|||
fileFormatVersion: 2 |
|||
guid: edff6e5006499451b804753d07e8133d |
|||
MonoImporter: |
|||
externalObjects: {} |
|||
serializedVersion: 2 |
|||
defaultReferences: [] |
|||
executionOrder: 0 |
|||
icon: {instanceID: 0} |
|||
userData: |
|||
assetBundleName: |
|||
assetBundleVariant: |
1001
com.unity.uiwidgets/Runtime/material/icons.cs
文件差异内容过多而无法显示
查看文件
文件差异内容过多而无法显示
查看文件
|
|||
fileFormatVersion: 2 |
|||
guid: 2507054e4ed9a4d9682f5453bd9e6061 |
|||
MonoImporter: |
|||
externalObjects: {} |
|||
serializedVersion: 2 |
|||
defaultReferences: [] |
|||
executionOrder: 0 |
|||
icon: {instanceID: 0} |
|||
userData: |
|||
assetBundleName: |
|||
assetBundleVariant: |
|
|||
using Unity.UIWidgets.foundation; |
|||
using Unity.UIWidgets.painting; |
|||
using Unity.UIWidgets.rendering; |
|||
using Unity.UIWidgets.ui; |
|||
using Unity.UIWidgets.widgets; |
|||
using ImageUtils = Unity.UIWidgets.widgets.ImageUtils; |
|||
|
|||
namespace Unity.UIWidgets.material { |
|||
public class Ink : StatefulWidget { |
|||
public Ink( |
|||
Key key = null, |
|||
EdgeInsets padding = null, |
|||
Color color = null, |
|||
Decoration decoration = null, |
|||
float? width = null, |
|||
float? height = null, |
|||
Widget child = null) : base(key: key) { |
|||
D.assert(padding == null || padding.isNonNegative); |
|||
D.assert(decoration == null || decoration.debugAssertIsValid()); |
|||
D.assert(color == null || decoration == null, |
|||
() => "Cannot provide both a color and a decoration\n" + |
|||
"The color argument is just a shorthand for \"decoration: new BoxDecoration(color: color)\"."); |
|||
decoration = decoration ?? (color != null ? new BoxDecoration(color: color) : null); |
|||
this.padding = padding; |
|||
this.width = width; |
|||
this.height = height; |
|||
this.child = child; |
|||
this.decoration = decoration; |
|||
} |
|||
|
|||
public static Ink image( |
|||
Key key = null, |
|||
EdgeInsets padding = null, |
|||
ImageProvider image = null, |
|||
ColorFilter colorFilter = null, |
|||
BoxFit? fit = null, |
|||
Alignment alignment = null, |
|||
Rect centerSlice = null, |
|||
ImageRepeat repeat = ImageRepeat.noRepeat, |
|||
float? width = null, |
|||
float? height = null, |
|||
Widget child = null |
|||
) { |
|||
D.assert(padding == null || padding.isNonNegative); |
|||
D.assert(image != null); |
|||
|
|||
alignment = alignment ?? Alignment.center; |
|||
Decoration decoration = new BoxDecoration( |
|||
image: new DecorationImage( |
|||
image: image, |
|||
colorFilter: colorFilter, |
|||
fit: fit, |
|||
alignment: alignment, |
|||
centerSlice: centerSlice, |
|||
repeat: repeat) |
|||
); |
|||
|
|||
return new Ink( |
|||
key: key, |
|||
padding: padding, |
|||
decoration: decoration, |
|||
width: width, |
|||
height: height, |
|||
child: child); |
|||
} |
|||
|
|||
|
|||
public readonly Widget child; |
|||
|
|||
public readonly EdgeInsets padding; |
|||
|
|||
public readonly Decoration decoration; |
|||
|
|||
public readonly float? width; |
|||
|
|||
public readonly float? height; |
|||
|
|||
public EdgeInsets _paddingIncludingDecoration { |
|||
get { |
|||
if (decoration == null || decoration.padding == null) { |
|||
return padding; |
|||
} |
|||
|
|||
EdgeInsets decorationPadding = decoration.padding; |
|||
if (padding == null) { |
|||
return decorationPadding; |
|||
} |
|||
|
|||
return padding.add(decorationPadding); |
|||
} |
|||
} |
|||
|
|||
public override void debugFillProperties(DiagnosticPropertiesBuilder properties) { |
|||
base.debugFillProperties(properties); |
|||
properties.add(new DiagnosticsProperty<EdgeInsets>("padding", padding, defaultValue: null)); |
|||
properties.add(new DiagnosticsProperty<Decoration>("bg", decoration, defaultValue: null)); |
|||
} |
|||
|
|||
public override State createState() { |
|||
return new _InkState(); |
|||
} |
|||
} |
|||
|
|||
|
|||
class _InkState : State<Ink> { |
|||
InkDecoration _ink; |
|||
|
|||
void _handleRemoved() { |
|||
_ink = null; |
|||
} |
|||
|
|||
public override void deactivate() { |
|||
_ink?.dispose(); |
|||
D.assert(_ink == null); |
|||
base.deactivate(); |
|||
} |
|||
|
|||
public Widget _build(BuildContext context, BoxConstraints constraints) { |
|||
if (_ink == null) { |
|||
_ink = new InkDecoration( |
|||
decoration: widget.decoration, |
|||
configuration: ImageUtils.createLocalImageConfiguration(context), |
|||
controller: Material.of(context), |
|||
referenceBox: (RenderBox) context.findRenderObject(), |
|||
onRemoved: _handleRemoved |
|||
); |
|||
} |
|||
else { |
|||
_ink.decoration = widget.decoration; |
|||
_ink.configuration = ImageUtils.createLocalImageConfiguration(context); |
|||
} |
|||
|
|||
Widget current = widget.child; |
|||
EdgeInsets effectivePadding = widget._paddingIncludingDecoration; |
|||
if (effectivePadding != null) { |
|||
current = new Padding( |
|||
padding: effectivePadding, |
|||
child: current); |
|||
} |
|||
|
|||
return current; |
|||
} |
|||
|
|||
public override Widget build(BuildContext context) { |
|||
D.assert(MaterialD.debugCheckHasMaterial(context)); |
|||
Widget result = new LayoutBuilder( |
|||
builder: _build |
|||
); |
|||
if (widget.width != null || widget.height != null) { |
|||
result = new SizedBox( |
|||
width: widget.width, |
|||
height: widget.height, |
|||
child: result); |
|||
} |
|||
|
|||
return result; |
|||
} |
|||
} |
|||
|
|||
|
|||
class InkDecoration : InkFeature { |
|||
public InkDecoration( |
|||
Decoration decoration = null, |
|||
ImageConfiguration configuration = null, |
|||
MaterialInkController controller = null, |
|||
RenderBox referenceBox = null, |
|||
VoidCallback onRemoved = null |
|||
) : base(controller: controller, referenceBox: referenceBox, onRemoved: onRemoved) { |
|||
D.assert(configuration != null); |
|||
D.assert(decoration != null); |
|||
D.assert(controller != null); |
|||
D.assert(referenceBox != null); |
|||
_configuration = configuration; |
|||
this.decoration = decoration; |
|||
this.controller.addInkFeature(this); |
|||
} |
|||
|
|||
BoxPainter _painter; |
|||
|
|||
public Decoration decoration { |
|||
get { return _decoration; } |
|||
set { |
|||
if (value == _decoration) { |
|||
return; |
|||
} |
|||
|
|||
_decoration = value; |
|||
_painter?.Dispose(); |
|||
_painter = _decoration?.createBoxPainter(_handleChanged); |
|||
controller.markNeedsPaint(); |
|||
} |
|||
} |
|||
|
|||
Decoration _decoration; |
|||
|
|||
public ImageConfiguration configuration { |
|||
get { return _configuration; } |
|||
set { |
|||
D.assert(value != null); |
|||
if (value == _configuration) { |
|||
return; |
|||
} |
|||
|
|||
_configuration = value; |
|||
controller.markNeedsPaint(); |
|||
} |
|||
} |
|||
|
|||
ImageConfiguration _configuration; |
|||
|
|||
void _handleChanged() { |
|||
controller.markNeedsPaint(); |
|||
} |
|||
|
|||
public override void dispose() { |
|||
_painter?.Dispose(); |
|||
base.dispose(); |
|||
} |
|||
|
|||
protected override void paintFeature(Canvas canvas, Matrix4 transform) { |
|||
if (_painter == null) { |
|||
return; |
|||
} |
|||
|
|||
Offset originOffset = transform.getAsTranslation(); |
|||
ImageConfiguration sizedConfiguration = configuration.copyWith( |
|||
size: referenceBox.size); |
|||
|
|||
if (originOffset == null) { |
|||
canvas.save(); |
|||
canvas.concat(transform.toMatrix3()); |
|||
_painter.paint(canvas, Offset.zero, sizedConfiguration); |
|||
canvas.restore(); |
|||
} |
|||
else { |
|||
_painter.paint(canvas, originOffset, sizedConfiguration); |
|||
} |
|||
} |
|||
} |
|||
} |
|
|||
fileFormatVersion: 2 |
|||
guid: 2aa14ff76c10f4d459b55674f0a2b57f |
|||
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.painting; |
|||
using Unity.UIWidgets.rendering; |
|||
using Unity.UIWidgets.ui; |
|||
|
|||
namespace Unity.UIWidgets.material { |
|||
static class InkHighlightUtils { |
|||
public static readonly TimeSpan _kHighlightFadeDuration = new TimeSpan(0, 0, 0, 0, 200); |
|||
} |
|||
|
|||
public class InkHighlight : InteractiveInkFeature { |
|||
public InkHighlight( |
|||
MaterialInkController controller = null, |
|||
RenderBox referenceBox = null, |
|||
Color color = null, |
|||
BoxShape shape = BoxShape.rectangle, |
|||
BorderRadius borderRadius = null, |
|||
ShapeBorder customBorder = null, |
|||
RectCallback rectCallback = null, |
|||
VoidCallback onRemoved = null) : base( |
|||
controller: controller, |
|||
referenceBox: referenceBox, |
|||
color: color, |
|||
onRemoved: onRemoved) { |
|||
D.assert(color != null); |
|||
D.assert(controller != null); |
|||
D.assert(referenceBox != null); |
|||
_shape = shape; |
|||
_borderRadius = borderRadius ?? BorderRadius.zero; |
|||
_customBorder = customBorder; |
|||
_rectCallback = rectCallback; |
|||
|
|||
_alphaController = new AnimationController( |
|||
duration: InkHighlightUtils._kHighlightFadeDuration, |
|||
vsync: controller.vsync); |
|||
_alphaController.addListener(controller.markNeedsPaint); |
|||
_alphaController.addStatusListener(_handleAlphaStatusChanged); |
|||
_alphaController.forward(); |
|||
|
|||
_alpha = _alphaController.drive(new IntTween( |
|||
begin: 0, end: color.alpha)); |
|||
|
|||
this.controller.addInkFeature(this); |
|||
} |
|||
|
|||
readonly BoxShape _shape; |
|||
|
|||
readonly BorderRadius _borderRadius; |
|||
|
|||
readonly ShapeBorder _customBorder; |
|||
|
|||
readonly RectCallback _rectCallback; |
|||
|
|||
Animation<int> _alpha; |
|||
AnimationController _alphaController; |
|||
|
|||
public bool active { |
|||
get { return _active; } |
|||
} |
|||
|
|||
bool _active = true; |
|||
|
|||
public void activate() { |
|||
_active = true; |
|||
_alphaController.forward(); |
|||
} |
|||
|
|||
public void deactivate() { |
|||
_active = false; |
|||
_alphaController.reverse(); |
|||
} |
|||
|
|||
void _handleAlphaStatusChanged(AnimationStatus status) { |
|||
if (status == AnimationStatus.dismissed && !_active) { |
|||
dispose(); |
|||
} |
|||
} |
|||
|
|||
public override void dispose() { |
|||
_alphaController.dispose(); |
|||
base.dispose(); |
|||
} |
|||
|
|||
void _paintHighlight(Canvas canvas, Rect rect, Paint paint) { |
|||
canvas.save(); |
|||
if (_customBorder != null) { |
|||
canvas.clipPath(_customBorder.getOuterPath(rect)); |
|||
} |
|||
|
|||
switch (_shape) { |
|||
case BoxShape.circle: { |
|||
canvas.drawCircle(rect.center, Material.defaultSplashRadius, paint); |
|||
break; |
|||
} |
|||
case BoxShape.rectangle: { |
|||
if (_borderRadius != BorderRadius.zero) { |
|||
RRect clipRRect = RRect.fromRectAndCorners( |
|||
rect, |
|||
topLeft: _borderRadius.topLeft, |
|||
topRight: _borderRadius.topRight, |
|||
bottomLeft: _borderRadius.bottomLeft, |
|||
bottomRight: _borderRadius.bottomRight); |
|||
canvas.drawRRect(clipRRect, paint); |
|||
} |
|||
else { |
|||
canvas.drawRect(rect, paint); |
|||
} |
|||
|
|||
break; |
|||
} |
|||
} |
|||
|
|||
canvas.restore(); |
|||
} |
|||
|
|||
protected override void paintFeature(Canvas canvas, Matrix4 transform) { |
|||
Paint paint = new Paint {color = color.withAlpha(_alpha.value)}; |
|||
Offset originOffset = transform.getAsTranslation(); |
|||
Rect rect = _rectCallback != null ? _rectCallback() : Offset.zero & referenceBox.size; |
|||
if (originOffset == null) { |
|||
canvas.save(); |
|||
canvas.concat(transform.toMatrix3()); |
|||
_paintHighlight(canvas, rect, paint); |
|||
canvas.restore(); |
|||
} |
|||
else { |
|||
_paintHighlight(canvas, rect.shift(originOffset), paint); |
|||
} |
|||
} |
|||
} |
|||
} |
|
|||
fileFormatVersion: 2 |
|||
guid: 96f34a8540bb74c7687149b4b2514998 |
|||
MonoImporter: |
|||
externalObjects: {} |
|||
serializedVersion: 2 |
|||
defaultReferences: [] |
|||
executionOrder: 0 |
|||
icon: {instanceID: 0} |
|||
userData: |
|||
assetBundleName: |
|||
assetBundleVariant: |
部分文件因为文件数量过多而无法显示
撰写
预览
正在加载...
取消
保存
Reference in new issue