浏览代码

add gallery material samples and fix some issue

/zgh-devtools
xingweizhu 4 年前
当前提交
49bd6bad
共有 25 个文件被更改,包括 3248 次插入19 次删除
  1. 7
      Samples/UIWidgetsSamples_2019_4/Assets/UIWidgetsGallery/gallery/about.cs
  2. 7
      Samples/UIWidgetsSamples_2019_4/Assets/UIWidgetsGallery/gallery/updater.cs
  3. 2
      com.unity.uiwidgets/Runtime/material/banner.cs
  4. 2
      com.unity.uiwidgets/Runtime/material/bottom_sheet.cs
  5. 10
      com.unity.uiwidgets/Runtime/material/popup_menu.cs
  6. 3
      Samples/UIWidgetsSamples_2019_4/Assets/UIWidgetsGallery/demo/material.meta
  7. 241
      Samples/UIWidgetsSamples_2019_4/Assets/UIWidgetsGallery/gallery/demo.cs
  8. 3
      Samples/UIWidgetsSamples_2019_4/Assets/UIWidgetsGallery/gallery/demo.cs.meta
  9. 472
      Samples/UIWidgetsSamples_2019_4/Assets/UIWidgetsGallery/demo/material/backdrop_demo.cs
  10. 3
      Samples/UIWidgetsSamples_2019_4/Assets/UIWidgetsGallery/demo/material/backdrop_demo.cs.meta
  11. 126
      Samples/UIWidgetsSamples_2019_4/Assets/UIWidgetsGallery/demo/material/banner_demo.cs
  12. 3
      Samples/UIWidgetsSamples_2019_4/Assets/UIWidgetsGallery/demo/material/banner_demo.cs.meta
  13. 600
      Samples/UIWidgetsSamples_2019_4/Assets/UIWidgetsGallery/demo/material/bottom_app_bar_demo.cs
  14. 3
      Samples/UIWidgetsSamples_2019_4/Assets/UIWidgetsGallery/demo/material/bottom_app_bar_demo.cs.meta
  15. 254
      Samples/UIWidgetsSamples_2019_4/Assets/UIWidgetsGallery/demo/material/bottom_navigation_demo.cs
  16. 3
      Samples/UIWidgetsSamples_2019_4/Assets/UIWidgetsGallery/demo/material/bottom_navigation_demo.cs.meta
  17. 390
      Samples/UIWidgetsSamples_2019_4/Assets/UIWidgetsGallery/demo/material/buttons_demo.cs
  18. 3
      Samples/UIWidgetsSamples_2019_4/Assets/UIWidgetsGallery/demo/material/buttons_demo.cs.meta
  19. 477
      Samples/UIWidgetsSamples_2019_4/Assets/UIWidgetsGallery/demo/material/cards_demo.cs
  20. 3
      Samples/UIWidgetsSamples_2019_4/Assets/UIWidgetsGallery/demo/material/cards_demo.cs.meta
  21. 365
      Samples/UIWidgetsSamples_2019_4/Assets/UIWidgetsGallery/demo/material/chip_demo.cs
  22. 3
      Samples/UIWidgetsSamples_2019_4/Assets/UIWidgetsGallery/demo/material/chip_demo.cs.meta
  23. 284
      Samples/UIWidgetsSamples_2019_4/Assets/UIWidgetsGallery/demo/material/data_table_demo.cs
  24. 3
      Samples/UIWidgetsSamples_2019_4/Assets/UIWidgetsGallery/demo/material/data_table_demo.cs.meta

7
Samples/UIWidgetsSamples_2019_4/Assets/UIWidgetsGallery/gallery/about.cs


}
public class _LinkTextSpan : TextSpan
{
private static void launch(string url)
{
Process.Start(url);
}
recognizer: new TapGestureRecognizer {onTap = () => { launch(url); }}
recognizer: new TapGestureRecognizer {onTap = () => { BrowserUtils.launch(url); }}
)
{
}

7
Samples/UIWidgetsSamples_2019_4/Assets/UIWidgetsGallery/gallery/updater.cs


internal class UpdaterState : State<Updater>
{
private static void launch(string url)
{
Process.Start(url);
}
public override void initState()
{
base.initState();

material_.showDialog<bool>(context: this.context, builder: this._buildDialog).then(wantsUpdate =>
{
if (wantsUpdate != null && (bool) wantsUpdate)
launch((string) updateUrl);
BrowserUtils.launch((string) updateUrl);
});
});
}

2
com.unity.uiwidgets/Runtime/material/banner.cs


using TextStyle = Unity.UIWidgets.painting.TextStyle;
namespace Unity.UIWidgets.material {
class MaterialBanner : StatelessWidget {
public class MaterialBanner : StatelessWidget {
public MaterialBanner(
Key key = null,
Widget content = null,

2
com.unity.uiwidgets/Runtime/material/bottom_sheet.cs


public static Future<T> showModalBottomSheet<T>(
BuildContext context,
WidgetBuilder builder,
Color backgroundColor,
Color backgroundColor = null,
float? elevation = null,
ShapeBorder shape = null,
Clip? clipBehavior = null,

10
com.unity.uiwidgets/Runtime/material/popup_menu.cs


}
public class PopupMenuDivider : PopupMenuEntry<object> {
public class PopupMenuDivider<T> : PopupMenuEntry<T> {
public PopupMenuDivider(Key key = null, float height = material_._kMenuDividerHeight) : base(key: key) {
_height = height;
}

get { return _height; }
}
public override bool represents(object value) {
public override bool represents(T value) {
return new _PopupMenuDividerState();
return new _PopupMenuDividerState<T>();
class _PopupMenuDividerState : State<PopupMenuDivider> {
class _PopupMenuDividerState<T> : State<PopupMenuDivider<T>> {
public override Widget build(BuildContext context) {
return new Divider(height: widget.height);
}

}
}
class CheckedPopupMenuItem<T> : PopupMenuItem<T> {
public class CheckedPopupMenuItem<T> : PopupMenuItem<T> {
public CheckedPopupMenuItem(
Key key = null,
T value = default,

3
Samples/UIWidgetsSamples_2019_4/Assets/UIWidgetsGallery/demo/material.meta


fileFormatVersion: 2
guid: 27e2b642479d4616ad980ef32f76e152
timeCreated: 1612406310

241
Samples/UIWidgetsSamples_2019_4/Assets/UIWidgetsGallery/gallery/demo.cs


using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using Unity.UIWidgets.async2;
using Unity.UIWidgets.foundation;
using Unity.UIWidgets.material;
using Unity.UIWidgets.painting;
using Unity.UIWidgets.widgets;
namespace UIWidgetsGallery.gallery
{
public static class BrowserUtils
{
internal static void launch(string url)
{
Process.Start(url);
}
internal static bool canLaunch(string url)
{
return true;
}
}
internal class ComponentDemoTabData : IEquatable<ComponentDemoTabData>
{
public ComponentDemoTabData(
Widget demoWidget = null,
string exampleCodeTag = null,
string description = null,
string tabName = null,
string documentationUrl = null
)
{
this.demoWidget = demoWidget;
this.exampleCodeTag = exampleCodeTag;
this.description = description;
this.tabName = tabName;
this.documentationUrl = documentationUrl;
}
public readonly Widget demoWidget;
public readonly string exampleCodeTag;
public readonly string description;
public readonly string tabName;
public readonly string documentationUrl;
public bool Equals(ComponentDemoTabData other)
{
if (ReferenceEquals(null, other)) return false;
if (ReferenceEquals(this, other)) return true;
return this.tabName.Equals(other.tabName)
&& this.description.Equals(other.description)
&& this.documentationUrl.Equals(other.documentationUrl);
}
public override bool Equals(object obj)
{
if (ReferenceEquals(null, obj)) return false;
if (ReferenceEquals(this, obj)) return true;
if (obj.GetType() != this.GetType()) return false;
return this.Equals((ComponentDemoTabData) obj);
}
public override int GetHashCode()
{
unchecked
{
var hashCode = (this.tabName.GetHashCode() * 397);
hashCode = (hashCode * 397) ^ this.description.GetHashCode();
hashCode = (hashCode * 397) ^ this.documentationUrl.GetHashCode();
return hashCode;
}
}
public static bool operator ==(ComponentDemoTabData left, ComponentDemoTabData right)
{
return Equals(left, right);
}
public static bool operator !=(ComponentDemoTabData left, ComponentDemoTabData right)
{
return !Equals(left, right);
}
}
internal class TabbedComponentDemoScaffold : StatelessWidget
{
public TabbedComponentDemoScaffold(
List<ComponentDemoTabData> demos,
string title,
List<Widget> actions,
bool isScrollable = true,
bool showExampleCodeAction = true
)
{
this.title = title;
this.demos = demos;
this.actions = actions;
this.isScrollable = isScrollable;
this.showExampleCodeAction = showExampleCodeAction;
}
public readonly List<ComponentDemoTabData> demos;
public readonly string title;
public readonly List<Widget> actions;
public readonly bool isScrollable;
public readonly bool showExampleCodeAction;
private void _showExampleCode(BuildContext context)
{
string tag = this.demos[DefaultTabController.of(context).index].exampleCodeTag;
if (tag != null) D.assert(false, () => "TO DO >>>");
/*Navigator.push(context, MaterialPageRoute<FullScreenCodeDialog>(
builder: (BuildContext context) => FullScreenCodeDialog(exampleCodeTag: tag)
));*/
}
private Future _showApiDocumentation(BuildContext context)
{
string url = this.demos[DefaultTabController.of(context).index].documentationUrl;
if (url == null)
return null;
if (BrowserUtils.canLaunch(url))
BrowserUtils.launch(url);
else
material_.showDialog<object>(
context: context,
builder: (BuildContext subContext) =>
{
return new SimpleDialog(
title: new Text("Couldn't display URL:"),
children: new List<Widget>
{
new Padding(
padding: EdgeInsets.symmetric(horizontal: 16.0f),
child: new Text(url)
)
}
);
}
);
return Future.value();
}
public override Widget build(BuildContext context)
{
var children = new List<Widget>(this.actions);
children.Add(new Builder(
builder: (BuildContext subContext) =>
{
return new IconButton(
icon: new Icon(Icons.library_books),
onPressed: () => this._showApiDocumentation(context)
);
}
)
);
if (this.showExampleCodeAction)
children.Add(new Builder(
builder: (BuildContext subContext) =>
{
return new IconButton(
icon: new Icon(Icons.code),
tooltip: "Show example code",
onPressed: () => this._showExampleCode(context)
);
}
));
return new DefaultTabController(
length: this.demos.Count,
child: new Scaffold(
appBar: new AppBar(
title: new Text(this.title),
actions: children,
bottom: new TabBar(
isScrollable: this.isScrollable,
tabs: this.demos.Select<ComponentDemoTabData, Widget>((ComponentDemoTabData data) =>
new Tab(text: data.tabName)).ToList()
)
),
body: new TabBarView(
children: this.demos.Select<ComponentDemoTabData, Widget>((ComponentDemoTabData demo) =>
{
return new SafeArea(
top: false,
bottom: false,
child: new Column(
children: new List<Widget>
{
new Padding(
padding: EdgeInsets.all(16.0f),
child: new Text(demo.description,
style: Theme.of(context).textTheme.subtitle1
)
),
new Expanded(child: demo.demoWidget)
}
)
);
}).ToList()
)
)
);
}
}
internal class MaterialDemoDocumentationButton : StatelessWidget
{
internal MaterialDemoDocumentationButton(string routeName, Key key = null) : base(key: key)
{
D.assert(
GalleryDemo.kDemoDocumentationUrl[routeName] != null,
() => $"A documentation URL was not specified for demo route {routeName} in kAllGalleryDemos"
);
this.documentationUrl = GalleryDemo.kDemoDocumentationUrl[routeName];
}
public readonly string documentationUrl;
public override Widget build(BuildContext context)
{
return new IconButton(
icon: new Icon(Icons.library_books),
tooltip: "API documentation",
onPressed: () => BrowserUtils.launch(this.documentationUrl)
);
}
}
}

3
Samples/UIWidgetsSamples_2019_4/Assets/UIWidgetsGallery/gallery/demo.cs.meta


fileFormatVersion: 2
guid: a66930d03e874eb0ba49812d9c1f952f
timeCreated: 1612409591

472
Samples/UIWidgetsSamples_2019_4/Assets/UIWidgetsGallery/demo/material/backdrop_demo.cs


using System;
using System.Collections.Generic;
using System.Linq;
using uiwidgets;
using Unity.UIWidgets.animation;
using Unity.UIWidgets.foundation;
using Unity.UIWidgets.gestures;
using Unity.UIWidgets.material;
using Unity.UIWidgets.painting;
using Unity.UIWidgets.rendering;
using Unity.UIWidgets.ui;
using Unity.UIWidgets.widgets;
using UnityEngine;
using Image = Unity.UIWidgets.widgets.Image;
using Material = Unity.UIWidgets.material.Material;
namespace UIWidgetsGallery.demo.material
{
public class Category
{
public Category(string title = null, List<string> assets = null)
{
this.title = title;
this.assets = assets;
}
public readonly string title;
public readonly List<string> assets;
public override string ToString()
{
return $"{this.GetType()}({this.title})";
}
public static readonly List<Category> allCategories = new List<Category>
{
new Category(
title: "Accessories",
assets: new List<string>
{
"products/belt.png",
"products/earrings.png",
"products/backpack.png",
"products/hat.png",
"products/scarf.png",
"products/sunnies.png"
}
),
new Category(
title: "Blue",
assets: new List<string>
{
"products/backpack.png",
"products/cup.png",
"products/napkins.png",
"products/top.png"
}
),
new Category(
title: "Cold Weather",
assets: new List<string>
{
"products/jacket.png",
"products/jumper.png",
"products/scarf.png",
"products/sweater.png",
"products/sweats.png"
}
),
new Category(
title: "Home",
assets: new List<string>
{
"products/cup.png",
"products/napkins.png",
"products/planters.png",
"products/table.png",
"products/teaset.png"
}
),
new Category(
title: "Tops",
assets: new List<string>
{
"products/jumper.png",
"products/shirt.png",
"products/sweater.png",
"products/top.png"
}
),
new Category(
title: "Everything",
assets: new List<string>
{
"products/backpack.png",
"products/belt.png",
"products/cup.png",
"products/dress.png",
"products/earrings.png",
"products/flatwear.png",
"products/hat.png",
"products/jacket.png",
"products/jumper.png",
"products/napkins.png",
"products/planters.png",
"products/scarf.png",
"products/shirt.png",
"products/sunnies.png",
"products/sweater.png",
"products/sweats.png",
"products/table.png",
"products/teaset.png",
"products/top.png"
}
)
};
}
public class CategoryView : StatelessWidget
{
public CategoryView(Key key = null, Category category = null) : base(key: key)
{
this.category = category;
}
public readonly Category category;
public override Widget build(BuildContext context)
{
ThemeData theme = Theme.of(context);
return new Scrollbar(
child: new ListView(
key: new PageStorageKey<Category>(this.category),
padding: EdgeInsets.symmetric(
vertical: 16.0f,
horizontal: 64.0f
),
children: this.category.assets.Select<string, Widget>((string asset) =>
{
return new Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: new List<Widget>
{
new Card(
child: new Container(
width: 144.0f,
alignment: Alignment.center,
child: new Column(
children: new List<Widget>
{
Image.asset(
asset,
package: "uiwidgets_gallery_assets",
fit: BoxFit.contain
),
new Container(
padding: EdgeInsets.only(bottom: 16.0f),
alignment: AlignmentDirectional.center,
child: new Text(
asset,
style: theme.textTheme.caption
)
)
}
)
)
),
new SizedBox(height: 24.0f)
}
);
}).ToList()
)
);
}
}
internal class BackdropPanel : StatelessWidget
{
public BackdropPanel(
Key key = null,
VoidCallback onTap = null,
GestureDragUpdateCallback onVerticalDragUpdate = null,
GestureDragEndCallback onVerticalDragEnd = null,
Widget title = null,
Widget child = null
) : base(key: key)
{
this.onTap = onTap;
this.onVerticalDragUpdate = onVerticalDragUpdate;
this.onVerticalDragEnd = onVerticalDragEnd;
this.title = title;
this.child = child;
}
public readonly VoidCallback onTap;
public readonly GestureDragUpdateCallback onVerticalDragUpdate;
public readonly GestureDragEndCallback onVerticalDragEnd;
public readonly Widget title;
public readonly Widget child;
public override Widget build(BuildContext context)
{
ThemeData theme = Theme.of(context);
return new Material(
elevation: 2.0f,
borderRadius: BorderRadius.only(
topLeft: Radius.circular(16.0f),
topRight: Radius.circular(16.0f)
),
child: new Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: new List<Widget>
{
new GestureDetector(
behavior: HitTestBehavior.opaque,
onVerticalDragUpdate: this.onVerticalDragUpdate,
onVerticalDragEnd: this.onVerticalDragEnd,
onTap: () => { this.onTap?.Invoke(); },
child: new Container(
height: 48.0f,
//TODO: uncomment this when fixes on EdgeInsetsDirectional lands
//padding: EdgeInsetsDirectional.only(start: 16.0f),
padding: EdgeInsets.only(left: 16.0f),
alignment: AlignmentDirectional.centerStart,
child: new DefaultTextStyle(
style: theme.textTheme.subtitle1,
child: new Tooltip(
message: "Tap to dismiss",
child: this.title
)
)
)
),
new Divider(height: 1.0f),
new Expanded(child: this.child)
}
)
);
}
}
internal class BackdropTitle : AnimatedWidget
{
public BackdropTitle(
Key key = null,
Animation<float> listenable = null
) : base(key: key, listenable: listenable)
{
}
protected override Widget build(BuildContext context)
{
Animation<float> animation = this.listenable as Animation<float>;
return new DefaultTextStyle(
style: Theme.of(context).primaryTextTheme.headline6,
softWrap: false,
overflow: TextOverflow.ellipsis,
child: new Stack(
children: new List<Widget>
{
new Opacity(
opacity: new CurvedAnimation(
parent: new ReverseAnimation(animation),
curve: new Interval(0.5f, 1.0f)
).value,
child: new Text("Select a Category")
),
new Opacity(
opacity: new CurvedAnimation(
parent: animation,
curve: new Interval(0.5f, 1.0f)
).value,
child: new Text("Asset Viewer")
)
}
)
);
}
}
internal class BackdropDemo : StatefulWidget
{
public static readonly string routeName = "/material/backdrop";
public override State createState()
{
return new _BackdropDemoState();
}
}
internal class _BackdropDemoState : SingleTickerProviderStateMixin<BackdropDemo>
{
private GlobalKey _backdropKey = GlobalKey.key(debugLabel: "Backdrop");
private AnimationController _controller;
private Category _category = Category.allCategories[0];
public override void initState()
{
base.initState();
this._controller = new AnimationController(
duration: new TimeSpan(0, 0, 0, 0, 300),
value: 1.0f,
vsync: this
);
}
public override void dispose()
{
this._controller.dispose();
base.dispose();
}
private void _changeCategory(Category category)
{
this.setState(() =>
{
this._category = category;
this._controller.fling(velocity: 2.0f);
});
}
private bool _backdropPanelVisible
{
get
{
AnimationStatus status = this._controller.status;
return status == AnimationStatus.completed || status == AnimationStatus.forward;
}
}
private void _toggleBackdropPanelVisibility()
{
this._controller.fling(velocity: this._backdropPanelVisible ? -2.0f : 2.0f);
}
private float _backdropHeight
{
get
{
RenderBox renderBox = this._backdropKey.currentContext.findRenderObject() as RenderBox;
return renderBox.size.height;
}
}
// By design: the panel can only be opened with a swipe. To close the panel
// the user must either tap its heading or the backdrop's menu icon.
private void _handleDragUpdate(DragUpdateDetails details)
{
if (this._controller.isAnimating || this._controller.status == AnimationStatus.completed)
return;
this._controller.setValue(this._controller.value - details.primaryDelta.Value / (this._backdropHeight));
}
private void _handleDragEnd(DragEndDetails details)
{
if (this._controller.isAnimating || this._controller.status == AnimationStatus.completed)
return;
float flingVelocity = details.velocity.pixelsPerSecond.dy / this._backdropHeight;
if (flingVelocity < 0.0f)
this._controller.fling(velocity: Mathf.Max(2.0f, -flingVelocity));
else if (flingVelocity > 0.0f)
this._controller.fling(velocity: Mathf.Min(-2.0f, -flingVelocity));
else
this._controller.fling(velocity: this._controller.value < 0.5 ? -2.0f : 2.0f);
}
// Stacks a BackdropPanel, which displays the selected category, on top
// of the backdrop. The categories are displayed with ListTiles. Just one
// can be selected at a time. This is a LayoutWidgetBuild function because
// we need to know how big the BackdropPanel will be to set up its
// animation.
private Widget _buildStack(BuildContext context, BoxConstraints constraints)
{
float panelTitleHeight = 48.0f;
Size panelSize = constraints.biggest;
float panelTop = panelSize.height - panelTitleHeight;
Animation<RelativeRect> panelAnimation = this._controller.drive(
new RelativeRectTween(
begin: RelativeRect.fromLTRB(
0.0f,
panelTop - MediaQuery.of(context).padding.bottom,
0.0f,
panelTop - panelSize.height
),
end: RelativeRect.fromLTRB(0.0f, 0.0f, 0.0f, 0.0f)
)
);
ThemeData theme = Theme.of(context);
List<Widget> backdropItems = Category.allCategories.Select<Category, Widget>((Category category) =>
{
bool selected = category == this._category;
return new Material(
shape: new RoundedRectangleBorder(
borderRadius: BorderRadius.all(Radius.circular(4.0f))
),
color: selected
? Colors.white.withOpacity(0.25f)
: Colors.transparent,
child: new ListTile(
title: new Text(category.title),
selected: selected,
onTap: () => { this._changeCategory(category); }
)
);
}).ToList();
return new Container(
key: this._backdropKey,
color: theme.primaryColor,
child: new Stack(
children: new List<Widget>
{
new ListTileTheme(
iconColor: theme.primaryIconTheme.color,
textColor: theme.primaryTextTheme.headline6.color.withOpacity(0.6f),
selectedColor: theme.primaryTextTheme.headline6.color,
child: new Padding(
padding: EdgeInsets.symmetric(horizontal: 16.0f),
child: new Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: backdropItems
)
)
),
new PositionedTransition(
rect: panelAnimation,
child: new BackdropPanel(
onTap: this._toggleBackdropPanelVisibility,
onVerticalDragUpdate: this._handleDragUpdate,
onVerticalDragEnd: this._handleDragEnd,
title: new Text(this._category.title),
child: new CategoryView(category: this._category)
)
)
}
)
);
}
public override Widget build(BuildContext context)
{
return new Scaffold(
appBar: new AppBar(
elevation: 0.0f,
title: new BackdropTitle(
listenable: this._controller.view
),
actions: new List<Widget>
{
new IconButton(
onPressed: this._toggleBackdropPanelVisibility,
icon: new AnimatedIcon(
icon: AnimatedIcons.close_menu,
progress: this._controller.view
)
)
}
),
body: new LayoutBuilder(
builder: this._buildStack
)
);
}
}
}

3
Samples/UIWidgetsSamples_2019_4/Assets/UIWidgetsGallery/demo/material/backdrop_demo.cs.meta


fileFormatVersion: 2
guid: 0d229d2babb945ec933ff8ce2c53a9f4
timeCreated: 1612406341

126
Samples/UIWidgetsSamples_2019_4/Assets/UIWidgetsGallery/demo/material/banner_demo.cs


using System.Collections.Generic;
using UIWidgetsGallery.gallery;
using Unity.UIWidgets.foundation;
using Unity.UIWidgets.material;
using Unity.UIWidgets.widgets;
namespace UIWidgetsGallery.demo.material
{
internal enum BannerDemoAction
{
reset,
showMultipleActions,
showLeading,
}
internal class BannerDemo : StatefulWidget
{
public BannerDemo(Key key = null) : base(key: key)
{
}
public static readonly string routeName = "/material/banner";
public override State createState()
{
return new _BannerDemoState();
}
}
internal class _BannerDemoState : State<BannerDemo>
{
private const int _numItems = 20;
private bool _displayBanner = true;
private bool _showMultipleActions = true;
private bool _showLeading = true;
private void handleDemoAction(BannerDemoAction action)
{
this.setState(() =>
{
switch (action)
{
case BannerDemoAction.reset:
this._displayBanner = true;
this._showMultipleActions = true;
this._showLeading = true;
break;
case BannerDemoAction.showMultipleActions:
this._showMultipleActions = !this._showMultipleActions;
break;
case BannerDemoAction.showLeading:
this._showLeading = !this._showLeading;
break;
}
});
}
public override Widget build(BuildContext context)
{
var children = new List<Widget>
{
new FlatButton(
child: new Text("SIGN IN"),
onPressed: () => { this.setState(() => { this._displayBanner = false; }); }
)
};
if (this._showMultipleActions)
children.Add(new FlatButton(
child: new Text("DISMISS"),
onPressed: () => { this.setState(() => { this._displayBanner = false; }); }
));
Widget banner = new MaterialBanner(
content: new Text("Your password was updated on your other device. Please sign in again."),
leading: this._showLeading ? new CircleAvatar(child: new Icon(Icons.access_alarm)) : null,
actions: children
);
return new Scaffold(
appBar: new AppBar(
title: new Text("Banner"),
actions: new List<Widget>
{
new MaterialDemoDocumentationButton(BannerDemo.routeName),
new PopupMenuButton<BannerDemoAction>(
onSelected: this.handleDemoAction,
itemBuilder: (BuildContext subContext) =>
{
var menuEntries = new List<PopupMenuEntry<BannerDemoAction>>();
menuEntries.Add(new PopupMenuItem<BannerDemoAction>(
value: BannerDemoAction.reset,
child: new Text("Reset the banner")
));
menuEntries.Add(new PopupMenuDivider<BannerDemoAction>());
menuEntries.Add(new CheckedPopupMenuItem<BannerDemoAction>(
value: BannerDemoAction.showMultipleActions,
isChecked: this._showMultipleActions,
child: new Text("Multiple actions")
));
menuEntries.Add(new CheckedPopupMenuItem<BannerDemoAction>(
value: BannerDemoAction.showLeading,
isChecked: this._showLeading,
child: new Text("Leading icon")
));
return menuEntries;
})
}
),
body: ListView.builder(itemCount: this._displayBanner ? _numItems + 1 : _numItems,
itemBuilder: (BuildContext subContext, int index) =>
{
if (index == 0 && this._displayBanner) return banner;
var itemIndex = this._displayBanner ? index : index + 1;
return new ListTile(title: new Text($"Item {itemIndex}"));
})
);
}
}
}

3
Samples/UIWidgetsSamples_2019_4/Assets/UIWidgetsGallery/demo/material/banner_demo.cs.meta


fileFormatVersion: 2
guid: e535b3a1ad7a44868e26cd44fecc9c31
timeCreated: 1612408411

600
Samples/UIWidgetsSamples_2019_4/Assets/UIWidgetsGallery/demo/material/bottom_app_bar_demo.cs


using System.Collections.Generic;
using System.Linq;
using uiwidgets;
using UIWidgetsGallery.gallery;
using Unity.UIWidgets.foundation;
using Unity.UIWidgets.material;
using Unity.UIWidgets.painting;
using Unity.UIWidgets.rendering;
using Unity.UIWidgets.ui;
using Unity.UIWidgets.widgets;
using UnityEngine;
using Canvas = Unity.UIWidgets.ui.Canvas;
using Color = Unity.UIWidgets.ui.Color;
using Material = Unity.UIWidgets.material.Material;
using Rect = Unity.UIWidgets.ui.Rect;
namespace UIWidgetsGallery.demo.material
{
internal class BottomAppBarDemo : StatefulWidget
{
public static readonly string routeName = "/material/bottom_app_bar";
public override State createState()
{
return new _BottomAppBarDemoState();
}
}
internal class _BottomAppBarDemoState : State<BottomAppBarDemo>
{
private static GlobalKey<ScaffoldState> _scaffoldKey = GlobalKey<ScaffoldState>.key();
// FAB shape
private static readonly _ChoiceValue<Widget> kNoFab = new _ChoiceValue<Widget>(
title: "None",
label: "do not show a floating action button",
value: null
);
private static readonly _ChoiceValue<Widget> kCircularFab = new _ChoiceValue<Widget>(
title: "Circular",
label: "circular floating action button",
value: new FloatingActionButton(
onPressed: _showSnackbar,
child: new Icon(Icons.add),
backgroundColor: Colors.orange
)
);
private static readonly _ChoiceValue<Widget> kDiamondFab = new _ChoiceValue<Widget>(
title: "Diamond",
label: "diamond shape floating action button",
value: new _DiamondFab(
onPressed: _showSnackbar,
child: new Icon(Icons.add)
)
);
// Notch
private static readonly _ChoiceValue<bool> kShowNotchTrue = new _ChoiceValue<bool>(
title: "On",
label: "show bottom appbar notch",
value: true
);
private static readonly _ChoiceValue<bool> kShowNotchFalse = new _ChoiceValue<bool>(
title: "Off",
label: "do not show bottom appbar notch",
value: false
);
// FAB Position
private static readonly _ChoiceValue<FloatingActionButtonLocation> kFabEndDocked =
new _ChoiceValue<FloatingActionButtonLocation>(
title: "Attached - End",
label: "floating action button is docked at the end of the bottom app bar",
value: FloatingActionButtonLocation.endDocked
);
private static readonly _ChoiceValue<FloatingActionButtonLocation> kFabCenterDocked =
new _ChoiceValue<FloatingActionButtonLocation>(
title: "Attached - Center",
label: "floating action button is docked at the center of the bottom app bar",
value: FloatingActionButtonLocation.centerDocked
);
private static readonly _ChoiceValue<FloatingActionButtonLocation> kFabEndFloat =
new _ChoiceValue<FloatingActionButtonLocation>(
title: "Free - End",
label: "floating action button floats above the end of the bottom app bar",
value: FloatingActionButtonLocation.endFloat
);
private static readonly _ChoiceValue<FloatingActionButtonLocation> kFabCenterFloat =
new _ChoiceValue<FloatingActionButtonLocation>(
title: "Free - Center",
label: "floating action button is floats above the center of the bottom app bar",
value: FloatingActionButtonLocation.centerFloat
);
private static void _showSnackbar()
{
string text =
"When the Scaffold\"s floating action button location changes, " +
"the floating action button animates to its new position. " +
"The BottomAppBar adapts its shape appropriately.";
_scaffoldKey.currentState.showSnackBar(
new SnackBar(content: new Text(text))
);
}
// App bar color
private static List<_NamedColor> kBabColors = new List<_NamedColor>
{
new _NamedColor(null, "Clear"),
new _NamedColor(new Color(0xFFFFC100), "Orange"),
new _NamedColor(new Color(0xFF91FAFF), "Light Blue"),
new _NamedColor(new Color(0xFF00D1FF), "Cyan"),
new _NamedColor(new Color(0xFF00BCFF), "Cerulean"),
new _NamedColor(new Color(0xFF009BEE), "Blue"),
};
private _ChoiceValue<Widget> _fabShape = kCircularFab;
private _ChoiceValue<bool> _showNotch = kShowNotchTrue;
private _ChoiceValue<FloatingActionButtonLocation> _fabLocation = kFabEndDocked;
private Color _babColor = kBabColors.First().color;
private void _onShowNotchChanged(_ChoiceValue<bool> value)
{
this.setState(() => { this._showNotch = value; });
}
private void _onFabShapeChanged(_ChoiceValue<Widget> value)
{
this.setState(() => { this._fabShape = value; });
}
private void _onFabLocationChanged(_ChoiceValue<FloatingActionButtonLocation> value)
{
this.setState(() => { this._fabLocation = value; });
}
private void _onBabColorChanged(Color value)
{
this.setState(() => { this._babColor = value; });
}
public override Widget build(BuildContext context)
{
return new Scaffold(
key: _scaffoldKey,
appBar: new AppBar(
title: new Text("Bottom app bar"),
elevation: 0.0f,
actions: new List<Widget>
{
new MaterialDemoDocumentationButton(BottomAppBarDemo.routeName),
new IconButton(
icon: new Icon(Icons.sentiment_very_satisfied),
onPressed: () =>
{
this.setState(() =>
{
this._fabShape = this._fabShape == kCircularFab ? kDiamondFab : kCircularFab;
});
}
)
}
),
body: new Scrollbar(
child: new ListView(
padding: EdgeInsets.only(bottom: 88.0f),
children: new List<Widget>
{
new _Heading("FAB Shape"),
new _RadioItem<Widget>(kCircularFab, this._fabShape, this._onFabShapeChanged),
new _RadioItem<Widget>(kDiamondFab, this._fabShape, this._onFabShapeChanged),
new _RadioItem<Widget>(kNoFab, this._fabShape, this._onFabShapeChanged),
new Divider(),
new _Heading("Notch"),
new _RadioItem<bool>(kShowNotchTrue, this._showNotch, this._onShowNotchChanged),
new _RadioItem<bool>(kShowNotchFalse, this._showNotch, this._onShowNotchChanged),
new Divider(),
new _Heading("FAB Position"),
new _RadioItem<FloatingActionButtonLocation>(kFabEndDocked, this._fabLocation,
this._onFabLocationChanged),
new _RadioItem<FloatingActionButtonLocation>(kFabCenterDocked, this._fabLocation,
this._onFabLocationChanged),
new _RadioItem<FloatingActionButtonLocation>(kFabEndFloat, this._fabLocation,
this._onFabLocationChanged),
new _RadioItem<FloatingActionButtonLocation>(kFabCenterFloat, this._fabLocation,
this._onFabLocationChanged),
new Divider(),
new _Heading("App bar color"),
new _ColorsItem(kBabColors, this._babColor, this._onBabColorChanged)
}
)
),
floatingActionButton: this._fabShape.value,
floatingActionButtonLocation: this._fabLocation.value,
bottomNavigationBar: new _DemoBottomAppBar(
color: this._babColor,
fabLocation: this._fabLocation.value,
shape: this._selectNotch()
)
);
}
private NotchedShape _selectNotch()
{
if (!this._showNotch.value)
return null;
if (this._fabShape == kCircularFab)
return new CircularNotchedRectangle();
if (this._fabShape == kDiamondFab)
return new _DiamondNotchedRectangle();
return null;
}
}
internal class _ChoiceValue<T>
{
public _ChoiceValue(T value, string title, string label)
{
this.value = value;
this.title = title;
this.label = label;
}
public readonly T value;
public readonly string title;
public readonly string label; // For the Semantics widget that contains title
public override string ToString()
{
return $"{this.GetType()}(\"{this.title}\")";
}
}
internal class _RadioItem<T> : StatelessWidget
{
public _RadioItem(_ChoiceValue<T> value, _ChoiceValue<T> groupValue, ValueChanged<_ChoiceValue<T>> onChanged)
{
this.value = value;
this.groupValue = groupValue;
this.onChanged = onChanged;
}
public readonly _ChoiceValue<T> value;
public readonly _ChoiceValue<T> groupValue;
public readonly ValueChanged<_ChoiceValue<T>> onChanged;
public override Widget build(BuildContext context)
{
ThemeData theme = Theme.of(context);
return new Container(
height: 56.0f,
//TODO: uncomment this when fixes on EdgeInsetsDirectional lands
//padding: const EdgeInsetsDirectional.only(start: 16.0),
padding: EdgeInsets.only(left: 16.0f),
alignment: AlignmentDirectional.centerStart,
child: new Row(
children: new List<Widget>
{
new Radio<_ChoiceValue<T>>(
value: this.value,
groupValue: this.groupValue,
onChanged: this.onChanged
),
new Expanded(
child: new GestureDetector(
behavior: HitTestBehavior.opaque,
onTap: () => { this.onChanged(this.value); },
child: new Text(this.value.title,
style: theme.textTheme.subtitle1
)
)
)
}
)
);
}
}
internal class _NamedColor
{
public _NamedColor(Color color, string name)
{
this.color = color;
this.name = name;
}
public readonly Color color;
public readonly string name;
}
internal class _ColorsItem : StatelessWidget
{
public _ColorsItem(List<_NamedColor> colors, Color selectedColor, ValueChanged<Color> onChanged)
{
this.colors = colors;
this.selectedColor = selectedColor;
this.onChanged = onChanged;
}
public readonly List<_NamedColor> colors;
public readonly Color selectedColor;
public readonly ValueChanged<Color> onChanged;
public override Widget build(BuildContext context)
{
return new Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: this.colors.Select<_NamedColor, Widget>((_NamedColor namedColor) =>
{
return new RawMaterialButton(
onPressed: () => { this.onChanged(namedColor.color); },
constraints: BoxConstraints.tightFor(
width: 32.0f,
height: 32.0f
),
fillColor: namedColor.color,
shape: new CircleBorder(
side: new BorderSide(
color: namedColor.color == this.selectedColor ? Colors.black : new Color(0xFFD5D7DA),
width: 2.0f
)
),
child: new Text(
namedColor.name
)
);
}).ToList()
);
}
}
internal class _Heading : StatelessWidget
{
public _Heading(string text)
{
this.text = text;
}
public readonly string text;
public override Widget build(BuildContext context)
{
ThemeData theme = Theme.of(context);
return new Container(
height: 48.0f,
//TODO: uncomment this when fixes on EdgeInsetsDirectional lands
//padding: EdgeInsetsDirectional.only(start: 56.0),
padding: EdgeInsets.only(left: 56.0f),
alignment: AlignmentDirectional.centerStart,
child: new Text(this.text,
style: theme.textTheme.bodyText2.copyWith(
color: theme.primaryColor
)
)
);
}
}
internal class _DemoBottomAppBar : StatelessWidget
{
public _DemoBottomAppBar(
Color color = null,
FloatingActionButtonLocation fabLocation = null,
NotchedShape shape = null
)
{
this.color = color;
this.fabLocation = fabLocation;
this.shape = shape;
}
public readonly Color color;
public readonly FloatingActionButtonLocation fabLocation;
public readonly NotchedShape shape;
private static readonly List<FloatingActionButtonLocation> kCenterLocations =
new List<FloatingActionButtonLocation>
{
FloatingActionButtonLocation.centerDocked,
FloatingActionButtonLocation.centerFloat
};
public override Widget build(BuildContext context)
{
var children = new List<Widget>
{
new IconButton(
icon: new Icon(Icons.menu),
onPressed: () =>
{
material_.showModalBottomSheet<object>(
context: context,
builder: (BuildContext subContext) => new _DemoDrawer()
);
}
)
};
if (kCenterLocations.Contains(this.fabLocation)) children.Add(new Expanded(child: new SizedBox()));
children.Add(
new IconButton(
icon: new Icon(Icons.search),
onPressed: () =>
{
Scaffold.of(context).showSnackBar(
new SnackBar(content: new Text("This is a dummy search action."))
);
}
)
);
children.Add(
new IconButton(
icon: new Icon(
Theme.of(context).platform == RuntimePlatform.IPhonePlayer
? Icons.more_horiz
: Icons.more_vert
),
onPressed: () =>
{
Scaffold.of(context).showSnackBar(
new SnackBar(content: new Text("This is a dummy menu action."))
);
}
)
);
return new BottomAppBar(
color: this.color,
shape: this.shape,
child: new Row(children: children)
);
}
}
internal class _DemoDrawer : StatelessWidget
{
public _DemoDrawer()
{
}
public override Widget build(BuildContext context)
{
return new Drawer(
child: new Column(
children: new List<Widget>
{
new ListTile(
leading: new Icon(Icons.search),
title: new Text("Search")
),
new ListTile(
leading: new Icon(Icons.threed_rotation),
title: new Text("3D")
)
}
)
);
}
}
internal class _DiamondFab : StatelessWidget
{
public _DiamondFab(
Widget child = null,
VoidCallback onPressed = null
)
{
this.child = child;
this.onPressed = onPressed;
}
public readonly Widget child;
public readonly VoidCallback onPressed;
public override Widget build(BuildContext context)
{
return new Material(
shape: new _DiamondBorder(),
color: Colors.orange,
child: new InkWell(
onTap: () => this.onPressed?.Invoke(),
child: new Container(
width: 56.0f,
height: 56.0f,
child: IconTheme.merge(
data: new IconThemeData(color: Theme.of(context).accentIconTheme.color),
child: this.child
)
)
),
elevation: 6.0f
);
}
}
internal class _DiamondNotchedRectangle : NotchedShape
{
public _DiamondNotchedRectangle()
{
}
public override Path getOuterPath(Rect host, Rect guest)
{
if (!host.overlaps(guest))
{
var path = new Path();
path.addRect(host);
return path;
}
D.assert(guest.width > 0.0f);
Rect intersection = guest.intersect(host);
// We are computing a "V" shaped notch, as in this diagram:
// -----\**** /-----
// \ /
// \ /
// \ /
//
// "-" marks the top edge of the bottom app bar.
// "\" and "/" marks the notch outline
//
// notchToCenter is the horizontal distance between the guest's center and
// the host's top edge where the notch starts (marked with "*").
// We compute notchToCenter by similar triangles:
float notchToCenter =
intersection.height * (guest.height / 2.0f)
/ (guest.width / 2.0f);
var retPath = new Path();
retPath.moveTo(host.left, host.top);
retPath.lineTo(guest.center.dx - notchToCenter, host.top);
retPath.lineTo(guest.left + guest.width / 2.0f, guest.bottom);
retPath.lineTo(guest.center.dx + notchToCenter, host.top);
retPath.lineTo(host.right, host.top);
retPath.lineTo(host.right, host.bottom);
retPath.lineTo(host.left, host.bottom);
retPath.close();
return retPath;
}
}
internal class _DiamondBorder : ShapeBorder
{
public _DiamondBorder()
{
}
public override EdgeInsetsGeometry dimensions => EdgeInsets.only();
public override Path getInnerPath(Rect rect, TextDirection? textDirection = null)
{
return this.getOuterPath(rect, textDirection: textDirection);
}
public override Path getOuterPath(Rect rect, TextDirection? textDirection = null)
{
var path = new Path();
path.moveTo(rect.left + rect.width / 2.0f, rect.top);
path.lineTo(rect.right, rect.top + rect.height / 2.0f);
path.lineTo(rect.left + rect.width / 2.0f, rect.bottom);
path.lineTo(rect.left, rect.top + rect.height / 2.0f);
path.close();
return path;
}
public override void paint(Canvas canvas, Rect rect, TextDirection? textDirection = null)
{
}
public override ShapeBorder scale(float t)
{
return null;
}
}
}

3
Samples/UIWidgetsSamples_2019_4/Assets/UIWidgetsGallery/demo/material/bottom_app_bar_demo.cs.meta


fileFormatVersion: 2
guid: c1ce2a2020fa4af0b42ffceb1bba8f6a
timeCreated: 1612409991

254
Samples/UIWidgetsSamples_2019_4/Assets/UIWidgetsGallery/demo/material/bottom_navigation_demo.cs


using System.Collections.Generic;
using System.Linq;
using uiwidgets;
using UIWidgetsGallery.gallery;
using Unity.UIWidgets.animation;
using Unity.UIWidgets.material;
using Unity.UIWidgets.painting;
using Unity.UIWidgets.scheduler2;
using Unity.UIWidgets.ui;
using Unity.UIWidgets.widgets;
namespace UIWidgetsGallery.demo.material
{
internal class NavigationIconView
{
internal NavigationIconView(
Widget icon = null,
Widget activeIcon = null,
string title = null,
Color color = null,
TickerProvider vsync = null
)
{
this._icon = icon;
this._color = color;
this._title = title;
this.item = new BottomNavigationBarItem(
icon: icon,
activeIcon: activeIcon,
title: new Text(title),
backgroundColor: color
);
this.controller = new AnimationController(
duration: ThemeUtils.kThemeAnimationDuration,
vsync: vsync);
this._animation = this.controller.drive(new CurveTween(
curve: new Interval(0.5f, 1.0f, curve: Curves.fastOutSlowIn)
));
}
public readonly Widget _icon;
public readonly Color _color;
public readonly string _title;
public readonly BottomNavigationBarItem item;
public readonly AnimationController controller;
private Animation<float> _animation;
internal FadeTransition transition(BottomNavigationBarType type, BuildContext context)
{
Color iconColor;
if (type == BottomNavigationBarType.shifting)
{
iconColor = this._color;
}
else
{
ThemeData themeData = Theme.of(context);
iconColor = themeData.brightness == Brightness.light
? themeData.primaryColor
: themeData.accentColor;
}
return new FadeTransition(
opacity: this._animation,
child: new SlideTransition(
position: this._animation.drive(
new Tween<Offset>(
begin: new Offset(0.0f, 0.02f), // Slightly down.
end: Offset.zero
)
),
child: new IconTheme(
data: new IconThemeData(
color: iconColor,
size: 120.0f
),
child: this._icon
)
)
);
}
}
internal class CustomIcon : StatelessWidget
{
public override Widget build(BuildContext context)
{
IconThemeData iconTheme = IconTheme.of(context);
return new Container(
margin: EdgeInsets.all(4.0f),
width: iconTheme.size - 8.0f,
height: iconTheme.size - 8.0f,
color: iconTheme.color
);
}
}
internal class CustomInactiveIcon : StatelessWidget
{
public override Widget build(BuildContext context)
{
IconThemeData iconTheme = IconTheme.of(context);
return new Container(
margin: EdgeInsets.all(4.0f),
width: iconTheme.size - 8.0f,
height: iconTheme.size - 8.0f,
decoration: new BoxDecoration(
border: Border.all(color: iconTheme.color, width: 2.0f)
)
);
}
}
internal class BottomNavigationDemo : StatefulWidget
{
public static readonly string routeName = "/material/bottom_navigation";
public override State createState()
{
return new _BottomNavigationDemoState();
}
}
internal class _BottomNavigationDemoState : TickerProviderStateMixin<BottomNavigationDemo>
{
private int _currentIndex = 0;
private BottomNavigationBarType _type = BottomNavigationBarType.shifting;
private List<NavigationIconView> _navigationViews;
public override void initState()
{
base.initState();
this._navigationViews = new List<NavigationIconView>
{
new NavigationIconView(
icon: new Icon(Icons.access_alarm),
title: "Alarm",
color: Colors.deepPurple,
vsync: this
),
new NavigationIconView(
activeIcon: new CustomIcon(),
icon: new CustomInactiveIcon(),
title: "Box",
color: Colors.deepOrange,
vsync: this
),
new NavigationIconView(
activeIcon: new Icon(Icons.cloud),
icon: new Icon(Icons.cloud_queue),
title: "Cloud",
color: Colors.teal,
vsync: this
),
new NavigationIconView(
activeIcon: new Icon(Icons.favorite),
icon: new Icon(Icons.favorite_border),
title: "Favorites",
color: Colors.indigo,
vsync: this
),
new NavigationIconView(
icon: new Icon(Icons.event_available),
title: "Event",
color: Colors.pink,
vsync: this
)
};
this._navigationViews[this._currentIndex].controller.setValue(1.0f);
}
public override void dispose()
{
foreach (NavigationIconView view in this._navigationViews)
view.controller.dispose();
base.dispose();
}
private Widget _buildTransitionsStack()
{
List<FadeTransition> transitions = new List<FadeTransition>();
foreach (NavigationIconView view in this._navigationViews)
transitions.Add(view.transition(this._type, this.context));
// We want to have the newly animating (fading in) views on top.
transitions.Sort((FadeTransition a, FadeTransition b) =>
{
Animation<float> aAnimation = a.opacity;
Animation<float> bAnimation = b.opacity;
float aValue = aAnimation.value;
float bValue = bAnimation.value;
return aValue.CompareTo(bValue);
});
return new Stack(children: new List<Widget>(transitions));
}
public override Widget build(BuildContext context)
{
BottomNavigationBar botNavBar = new BottomNavigationBar(
items: this._navigationViews
.Select<NavigationIconView, BottomNavigationBarItem>((NavigationIconView navigationView) =>
navigationView.item)
.ToList(),
currentIndex: this._currentIndex,
type: this._type,
onTap: (int index) =>
{
this.setState(() =>
{
this._navigationViews[this._currentIndex].controller.reverse();
this._currentIndex = index;
this._navigationViews[this._currentIndex].controller.forward();
});
}
);
return new Scaffold(
appBar: new AppBar(
title: new Text("Bottom navigation"),
actions: new List<Widget>
{
new MaterialDemoDocumentationButton(BottomNavigationDemo.routeName),
new PopupMenuButton<BottomNavigationBarType>(
onSelected: (BottomNavigationBarType value) =>
{
this.setState(() => { this._type = value; });
},
itemBuilder: (BuildContext subContext) => new List<PopupMenuEntry<BottomNavigationBarType>>
{
new PopupMenuItem<BottomNavigationBarType>(
value: BottomNavigationBarType.fix,
child: new Text("Fixed")
),
new PopupMenuItem<BottomNavigationBarType>(
value: BottomNavigationBarType.shifting,
child: new Text("Shifting")
)
}
)
}
),
body: new Center(
child: this._buildTransitionsStack()
),
bottomNavigationBar: botNavBar
);
}
}
}

3
Samples/UIWidgetsSamples_2019_4/Assets/UIWidgetsGallery/demo/material/bottom_navigation_demo.cs.meta


fileFormatVersion: 2
guid: 0141eef318dd42e6acc4f3400430dcc8
timeCreated: 1612419869

390
Samples/UIWidgetsSamples_2019_4/Assets/UIWidgetsGallery/demo/material/buttons_demo.cs


using System;
using System.Collections.Generic;
using System.Linq;
using UIWidgetsGallery.gallery;
using Unity.UIWidgets.material;
using Unity.UIWidgets.painting;
using Unity.UIWidgets.rendering;
using Unity.UIWidgets.widgets;
namespace UIWidgetsGallery.demo.material
{
public static class ButtonsDemoUtils
{
public static readonly string _raisedText =
"Raised buttons add dimension to mostly flat layouts. They emphasize " +
"functions on busy or wide spaces.";
public static readonly string _raisedCode = "buttons_raised";
public static readonly string _flatText = "A flat button displays an ink splash on press " +
"but does not lift. Use flat buttons on toolbars, in dialogs and " +
"inline with padding";
public static readonly string _flatCode = "buttons_flat";
public static readonly string _outlineText =
"Outline buttons become opaque and elevate when pressed. They are often " +
"paired with raised buttons to indicate an alternative, secondary action.";
public static readonly string _outlineCode = "buttons_outline";
public static readonly string _dropdownText =
"A dropdown button displays a menu that\"s used to select a value from a " +
"small set of values. The button displays the current value and a down " +
"arrow.";
public static readonly string _dropdownCode = "buttons_dropdown";
public static readonly string _iconText =
"IconButtons are appropriate for toggle buttons that allow a single choice " +
"to be selected or deselected, such as adding or removing an item\"s star.";
public static readonly string _iconCode = "buttons_icon";
public static readonly string _actionText =
"Floating action buttons are used for a promoted action. They are " +
"distinguished by a circled icon floating above the UI and can have motion " +
"behaviors that include morphing, launching, and a transferring anchor " +
"point.";
public static readonly string _actionCode = "buttons_action";
}
class ButtonsDemo : StatefulWidget {
public static readonly string routeName = "/material/buttons";
public override State createState() => new _ButtonsDemoState();
}
class _ButtonsDemoState : State<ButtonsDemo> {
ShapeBorder _buttonShape;
public override Widget build(BuildContext context)
{
ButtonThemeData buttonTheme = ButtonTheme.of(context).copyWith(
shape: _buttonShape
);
List<ComponentDemoTabData> demos = new List<ComponentDemoTabData>{
new ComponentDemoTabData(
tabName: "RAISED",
description: ButtonsDemoUtils._raisedText,
demoWidget: ButtonTheme.fromButtonThemeData(
data: buttonTheme,
child: buildRaisedButton()
),
exampleCodeTag: ButtonsDemoUtils._raisedCode,
documentationUrl: "https://docs.flutter.io/flutter/material/RaisedButton-class.html"
),
new ComponentDemoTabData(
tabName: "FLAT",
description: ButtonsDemoUtils._flatText,
demoWidget: ButtonTheme.fromButtonThemeData(
data: buttonTheme,
child: buildFlatButton()
),
exampleCodeTag: ButtonsDemoUtils._flatCode,
documentationUrl: "https://docs.flutter.io/flutter/material/FlatButton-class.html"
),
new ComponentDemoTabData(
tabName: "OUTLINE",
description: ButtonsDemoUtils._outlineText,
demoWidget: ButtonTheme.fromButtonThemeData(
data: buttonTheme,
child: buildOutlineButton()
),
exampleCodeTag: ButtonsDemoUtils._outlineCode,
documentationUrl: "https://docs.flutter.io/flutter/material/OutlineButton-class.html"
),
new ComponentDemoTabData(
tabName: "DROPDOWN",
description: ButtonsDemoUtils._dropdownText,
demoWidget: buildDropdownButton(),
exampleCodeTag: ButtonsDemoUtils._dropdownCode,
documentationUrl: "https://docs.flutter.io/flutter/material/DropdownButton-class.html"
),
new ComponentDemoTabData(
tabName: "ICON",
description: ButtonsDemoUtils._iconText,
demoWidget: buildIconButton(),
exampleCodeTag: ButtonsDemoUtils._iconCode,
documentationUrl: "https://docs.flutter.io/flutter/material/IconButton-class.html"
),
new ComponentDemoTabData(
tabName: "ACTION",
description: ButtonsDemoUtils._actionText,
demoWidget: buildActionButton(),
exampleCodeTag: ButtonsDemoUtils._actionCode,
documentationUrl: "https://docs.flutter.io/flutter/material/FloatingActionButton-class.html"
)
};
return new TabbedComponentDemoScaffold(
title: "Buttons",
demos: demos,
actions: new List<Widget>{
new IconButton(
icon: new Icon(Icons.sentiment_very_satisfied),
onPressed: () => {
setState(() => {
_buttonShape = _buttonShape == null ? new StadiumBorder() : null;
});
}
)
}
);
}
Widget buildRaisedButton() {
return new Align(
alignment: new Alignment(0.0f, -0.2f),
child: new Column(
mainAxisSize: MainAxisSize.min,
children: new List<Widget>{
new ButtonBar(
mainAxisSize: MainAxisSize.min,
children: new List<Widget>{
new RaisedButton(
child: new Text("RAISED BUTTON"),
onPressed: () => {
// Perform some action
}
),
new RaisedButton(
child: new Text("DISABLED"),
onPressed: null
)
}
),
new ButtonBar(
mainAxisSize: MainAxisSize.min,
children: new List<Widget>{
RaisedButton.icon(
icon: new Icon(Icons.add, size: 18.0f),
label: new Text("RAISED BUTTON"),
onPressed: () => {
// Perform some action
}
),
RaisedButton.icon(
icon: new Icon(Icons.add, size: 18.0f),
label: new Text("DISABLED"),
onPressed: null
)
}
)
}
)
);
}
Widget buildFlatButton() {
return new Align(
alignment: new Alignment(0.0f, -0.2f),
child: new Column(
mainAxisSize: MainAxisSize.min,
children: new List<Widget>{
new ButtonBar(
mainAxisSize: MainAxisSize.min,
children: new List<Widget>{
new FlatButton(
child: new Text("FLAT BUTTON"),
onPressed: () => {
// Perform some action
}
),
new FlatButton(
child: new Text("DISABLED"),
onPressed: null
)
}
),
new ButtonBar(
mainAxisSize: MainAxisSize.min,
children: new List<Widget>{
FlatButton.icon(
icon: new Icon(Icons.add_circle_outline, size: 18.0f),
label: new Text("FLAT BUTTON"),
onPressed: () => {
// Perform some action
}
),
FlatButton.icon(
icon: new Icon(Icons.add_circle_outline, size: 18.0f),
label: new Text("DISABLED"),
onPressed: null
)
}
)
}
)
);
}
Widget buildOutlineButton() {
return new Align(
alignment: new Alignment(0.0f, -0.2f),
child: new Column(
mainAxisSize: MainAxisSize.min,
children: new List<Widget>{
new ButtonBar(
mainAxisSize: MainAxisSize.min,
children: new List<Widget>{
new OutlineButton(
child: new Text("OUTLINE BUTTON"),
onPressed: () => {
// Perform some action
}
),
new OutlineButton(
child: new Text("DISABLED"),
onPressed: null
)
}
),
new ButtonBar(
mainAxisSize: MainAxisSize.min,
children: new List<Widget>{
OutlineButton.icon(
icon: new Icon(Icons.add, size: 18.0f),
label: new Text("OUTLINE BUTTON"),
onPressed: () => {
// Perform some action
}
),
OutlineButton.icon(
icon: new Icon(Icons.add, size: 18.0f),
label: new Text("DISABLED"),
onPressed: null
)
}
)
}
)
);
}
// https://en.wikipedia.org/wiki/Free_Four
string dropdown1Value = "Free";
string dropdown2Value = "";
string dropdown3Value = "Four";
Widget buildDropdownButton() {
return new Padding(
padding: EdgeInsets.all(24.0f),
child: new Column(
mainAxisAlignment: MainAxisAlignment.start,
children: new List<Widget>{
new ListTile(
title: new Text("Simple dropdown:"),
trailing: new DropdownButton<string>(
value: dropdown1Value,
onChanged: (string newValue) => {
setState(() => {
dropdown1Value = newValue;
});
},
items: new List<string>{"One", "Two", "Free", "Four"}.Select<string, DropdownMenuItem<string>>((string value) => {
return new DropdownMenuItem<string>(
value: value,
child: new Text(value)
);
}).ToList()
)
),
new SizedBox(
height: 24.0f
),
new ListTile(
title: new Text("Dropdown with a hint:"),
trailing: new DropdownButton<string>(
value: dropdown2Value,
hint: new Text("Choose"),
onChanged: (string newValue) => {
setState(() => {
dropdown2Value = newValue;
});
},
items: new List<string>{"One", "Two", "Free", "Four"}.Select<string, DropdownMenuItem<string>>((string value) => {
return new DropdownMenuItem<string>(
value: value,
child: new Text(value)
);
}).ToList()
)
),
new SizedBox(
height: 24.0f
),
new ListTile(
title: new Text("Scrollable dropdown:"),
trailing: new DropdownButton<string>(
value: dropdown3Value,
onChanged: (string newValue) => {
setState(() => {
dropdown3Value = newValue;
});
},
items: new List<string>{
"One", "Two", "Free", "Four", "Can", "I", "Have", "A", "Little",
"Bit", "More", "Five", "Six", "Seven", "Eight", "Nine", "Ten",
}
.Select<string, DropdownMenuItem<string>>((string value) => {
return new DropdownMenuItem<string>(
value: value,
child: new Text(value)
);
})
.ToList()
)
)
}
)
);
}
bool iconButtonToggle = false;
Widget buildIconButton() {
return new Align(
alignment: new Alignment(0.0f, -0.2f),
child: new Row(
mainAxisSize: MainAxisSize.min,
children: new List<Widget>{
new IconButton(
icon: new Icon(
Icons.thumb_up
),
onPressed: () =>{
setState(() => iconButtonToggle = !iconButtonToggle);
},
color: iconButtonToggle ? Theme.of(context).primaryColor : null
),
new IconButton(
icon: new Icon(
Icons.thumb_up
),
onPressed: null
)
}
.Select<Widget, Widget>((Widget button) => new SizedBox(width: 64.0f, height: 64.0f, child: button))
.ToList()
)
);
}
Widget buildActionButton() {
return new Align(
alignment: new Alignment(0.0f, -0.2f),
child: new FloatingActionButton(
child: new Icon(Icons.add),
onPressed: () => {
// Perform some action
},
tooltip: "floating action button"
)
);
}
}
}

3
Samples/UIWidgetsSamples_2019_4/Assets/UIWidgetsGallery/demo/material/buttons_demo.cs.meta


fileFormatVersion: 2
guid: d6d69568df64484b9aaee159d11dffc8
timeCreated: 1612421132

477
Samples/UIWidgetsSamples_2019_4/Assets/UIWidgetsGallery/demo/material/cards_demo.cs


using System.Collections.Generic;
using System.Linq;
using uiwidgets;
using UIWidgetsGallery.gallery;
using Unity.UIWidgets.foundation;
using Unity.UIWidgets.material;
using Unity.UIWidgets.painting;
using Unity.UIWidgets.rendering;
using Unity.UIWidgets.ui;
using Unity.UIWidgets.widgets;
using UnityEngine;
using TextStyle = Unity.UIWidgets.painting.TextStyle;
namespace UIWidgetsGallery.demo.material
{
public static class CardsDemoUtils
{
public static readonly string _kGalleryAssetsPackage = "flutter_gallery_assets";
}
internal enum CardDemoType
{
standard,
tappable,
selectable,
}
internal class TravelDestination
{
public TravelDestination(
string assetName = null,
string assetPackage = null,
string title = null,
string description = null,
string city = null,
string location = null,
CardDemoType type = CardDemoType.standard
)
{
D.assert(assetName != null);
D.assert(assetPackage != null);
D.assert(title != null);
D.assert(description != null);
D.assert(city != null);
D.assert(location != null);
}
public readonly string assetName;
public readonly string assetPackage;
public readonly string title;
public readonly string description;
public readonly string city;
public readonly string location;
public readonly CardDemoType type;
public static readonly List<TravelDestination> destinations = new List<TravelDestination>
{
new TravelDestination(
assetName: "places/india_thanjavur_market.png",
assetPackage: CardsDemoUtils._kGalleryAssetsPackage,
title: "Top 10 Cities to Visit in Tamil Nadu",
description: "Number 10",
city: "Thanjavur",
location: "Thanjavur, Tamil Nadu"
),
new TravelDestination(
assetName: "places/india_chettinad_silk_maker.png",
assetPackage: CardsDemoUtils._kGalleryAssetsPackage,
title: "Artisans of Southern India",
description: "Silk Spinners",
city: "Chettinad",
location: "Sivaganga, Tamil Nadu",
type: CardDemoType.tappable
),
new TravelDestination(
assetName: "places/india_tanjore_thanjavur_temple.png",
assetPackage: CardsDemoUtils._kGalleryAssetsPackage,
title: "Brihadisvara Temple",
description: "Temples",
city: "Thanjavur",
location: "Thanjavur, Tamil Nadu",
type: CardDemoType.selectable
),
};
}
internal class TravelDestinationItem : StatelessWidget
{
public TravelDestinationItem(Key key = null, TravelDestination destination = null, ShapeBorder shape = null)
: base(key: key)
{
D.assert(destination != null);
this.destination = destination;
this.shape = shape;
}
// This height will allow for all the Card's content to fit comfortably within the card.
private const float height = 338.0f;
public readonly TravelDestination destination;
public readonly ShapeBorder shape;
public override Widget build(BuildContext context)
{
return new SafeArea(
top: false,
bottom: false,
child: new Padding(
padding: EdgeInsets.all(8.0f),
child: new Column(
children: new List<Widget>
{
new SectionTitle(title: "Normal"),
new SizedBox(
height: height,
child: new Card(
// This ensures that the Card's children are clipped correctly.
clipBehavior: Clip.antiAlias,
shape: this.shape,
child: new TravelDestinationContent(destination: this.destination)
)
)
}
)
)
);
}
}
internal class TappableTravelDestinationItem : StatelessWidget
{
public TappableTravelDestinationItem(Key key = null, TravelDestination destination = null,
ShapeBorder shape = null)
: base(key: key)
{
D.assert(destination != null);
this.destination = destination;
this.shape = shape;
}
// This height will allow for all the Card's content to fit comfortably within the card.
private const float height = 298.0f;
public readonly TravelDestination destination;
public readonly ShapeBorder shape;
public override Widget build(BuildContext context)
{
return new SafeArea(
top: false,
bottom: false,
child: new Padding(
padding: EdgeInsets.all(8.0f),
child: new Column(
children: new List<Widget>
{
new SectionTitle(title: "Tappable"),
new SizedBox(
height: height,
child: new Card(
// This ensures that the Card's children (including the ink splash) are clipped correctly.
clipBehavior: Clip.antiAlias,
shape: this.shape,
child: new InkWell(
onTap: () => { Debug.Log("Card was tapped"); },
// Generally, material cards use onSurface with 12% opacity for the pressed state.
splashColor: Theme.of(context).colorScheme.onSurface.withOpacity(0.12f),
// Generally, material cards do not have a highlight overlay.
highlightColor: Colors.transparent,
child: new TravelDestinationContent(destination: this.destination)
)
)
)
}
)
)
);
}
}
internal class SelectableTravelDestinationItem : StatefulWidget
{
public SelectableTravelDestinationItem(Key key = null, TravelDestination destination = null,
ShapeBorder shape = null)
: base(key: key)
{
D.assert(destination != null);
this.destination = destination;
this.shape = shape;
}
public readonly TravelDestination destination;
public readonly ShapeBorder shape;
public override State createState()
{
return new _SelectableTravelDestinationItemState();
}
}
internal class _SelectableTravelDestinationItemState : State<SelectableTravelDestinationItem>
{
// This height will allow for all the Card's content to fit comfortably within the card.
private const float height = 298.0f;
private bool _isSelected = false;
public override Widget build(BuildContext context)
{
ColorScheme colorScheme = Theme.of(context).colorScheme;
return new SafeArea(
top: false,
bottom: false,
child: new Padding(
padding: EdgeInsets.all(8.0f),
child: new Column(
children: new List<Widget>
{
new SectionTitle(title: "Selectable (long press)"),
new SizedBox(
height: height,
child: new Card(
// This ensures that the Card's children (including the ink splash) are clipped correctly.
clipBehavior: Clip.antiAlias,
shape: this.widget.shape,
child: new InkWell(
onLongPress: () =>
{
Debug.Log("Selectable card state changed");
this.setState(() => { this._isSelected = !this._isSelected; });
},
// Generally, material cards use onSurface with 12% opacity for the pressed state.
splashColor: colorScheme.onSurface.withOpacity(0.12f),
// Generally, material cards do not have a highlight overlay.
highlightColor: Colors.transparent,
child: new Stack(
children: new List<Widget>
{
new Container(
color: this._isSelected
// Generally, material cards use primary with 8% opacity for the selected state.
// See: https://material.io/design/interaction/states.html#anatomy
? colorScheme.primary.withOpacity(0.08f)
: Colors.transparent
),
new TravelDestinationContent(destination: this.widget.destination),
new Align(
alignment: Alignment.topRight,
child: new Padding(
padding: EdgeInsets.all(8.0f),
child: new Icon(
Icons.check_circle,
color: this._isSelected
? colorScheme.primary
: Colors.transparent
)
)
)
}
)
)
)
)
}
)
)
);
}
}
internal class SectionTitle : StatelessWidget
{
public SectionTitle(
Key key = null,
string title = null
) : base(key: key)
{
this.title = title;
}
public readonly string title;
public override Widget build(BuildContext context)
{
return new Padding(
padding: EdgeInsets.fromLTRB(4.0f, 4.0f, 4.0f, 12.0f),
child: new Align(
alignment: Alignment.centerLeft,
child: new Text(this.title, style: Theme.of(context).textTheme.subtitle1)
)
);
}
}
internal class TravelDestinationContent : StatelessWidget
{
public TravelDestinationContent(Key key = null, TravelDestination destination = null)
: base(key: key)
{
D.assert(destination != null);
this.destination = destination;
}
public readonly TravelDestination destination;
public override Widget build(BuildContext context)
{
ThemeData theme = Theme.of(context);
TextStyle titleStyle = theme.textTheme.headline5.copyWith(color: Colors.white);
TextStyle descriptionStyle = theme.textTheme.subtitle1;
var children = new List<Widget>
{
// Photo and title.
new SizedBox(
height: 184.0f,
child: new Stack(
children: new List<Widget>
{
Positioned.fill(
// In order to have the ink splash appear above the image, you
// must use Ink.image. This allows the image to be painted as part
// of the Material and display ink effects above it. Using a
// standard Image will obscure the ink splash.
child: Ink.image(
image: new FileImage(this.destination.assetPackage + "/" +
this.destination.assetName),
fit: BoxFit.cover,
child: new Container()
)
),
new Positioned(
bottom: 16.0f,
left: 16.0f,
right: 16.0f,
child: new FittedBox(
fit: BoxFit.scaleDown,
alignment: Alignment.centerLeft,
child: new Text(this.destination.title,
style: titleStyle
)
)
)
}
)
),
// Description and share/explore buttons.
new Padding(
padding: EdgeInsets.fromLTRB(16.0f, 16.0f, 16.0f, 0.0f),
child: new DefaultTextStyle(
softWrap: false,
overflow: TextOverflow.ellipsis,
style: descriptionStyle,
child: new Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: new List<Widget>
{
// three line description
new Padding(
padding: EdgeInsets.only(bottom: 8.0f),
child: new Text(this.destination.description,
style: descriptionStyle.copyWith(color: Colors.black54)
)
),
new Text(this.destination.city),
new Text(this.destination.location)
}
)
)
)
};
if (this.destination.type == CardDemoType.standard)
// share, explore buttons
children.Add(new ButtonBar(
alignment: MainAxisAlignment.start,
children: new List<Widget>
{
new FlatButton(
child: new Text("SHARE"),
textColor: Colors.amber.shade500,
onPressed: () => { Debug.Log("pressed"); }
),
new FlatButton(
child: new Text("EXPLORE"),
textColor: Colors.amber.shade500,
onPressed: () => { Debug.Log("pressed"); }
)
}
));
return new Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: children
);
}
}
internal class CardsDemo : StatefulWidget
{
public static readonly string routeName = "/material/cards";
public override State createState()
{
return new _CardsDemoState();
}
}
internal class _CardsDemoState : State<CardsDemo>
{
private ShapeBorder _shape;
public override Widget build(BuildContext context)
{
return new Scaffold(
appBar: new AppBar(
title: new Text("Cards"),
actions: new List<Widget>
{
new MaterialDemoDocumentationButton(CardsDemo.routeName),
new IconButton(
icon: new Icon(
Icons.sentiment_very_satisfied
),
onPressed: () =>
{
this.setState(() =>
{
this._shape = this._shape != null
? null
: new RoundedRectangleBorder(
borderRadius: BorderRadius.only(
topLeft: Radius.circular(16.0f),
topRight: Radius.circular(16.0f),
bottomLeft: Radius.circular(2.0f),
bottomRight: Radius.circular(2.0f)
)
);
});
}
)
}
),
body: new Scrollbar(
child: new ListView(
padding: EdgeInsets.only(top: 8.0f, left: 8.0f, right: 8.0f),
children: TravelDestination.destinations.Select<TravelDestination, Widget>(
(TravelDestination destination) =>
{
Widget child = null;
switch (destination.type)
{
case CardDemoType.standard:
child = new TravelDestinationItem(destination: destination, shape: this._shape);
break;
case CardDemoType.tappable:
child = new TappableTravelDestinationItem(destination: destination,
shape: this._shape);
break;
case CardDemoType.selectable:
child = new SelectableTravelDestinationItem(destination: destination,
shape: this._shape);
break;
}
return new Container(
margin: EdgeInsets.only(bottom: 8.0f),
child: child
);
}).ToList()
)
)
);
}
}
}

3
Samples/UIWidgetsSamples_2019_4/Assets/UIWidgetsGallery/demo/material/cards_demo.cs.meta


fileFormatVersion: 2
guid: e5eef436049c4b8ba60592f26681bb56
timeCreated: 1612423408

365
Samples/UIWidgetsSamples_2019_4/Assets/UIWidgetsGallery/demo/material/chip_demo.cs


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

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


fileFormatVersion: 2
guid: f9c596e7b509434aab8b7b7830e287ab
timeCreated: 1612425059

284
Samples/UIWidgetsSamples_2019_4/Assets/UIWidgetsGallery/demo/material/data_table_demo.cs


using System;
using System.Collections.Generic;
using UIWidgetsGallery.gallery;
using Unity.UIWidgets.foundation;
using Unity.UIWidgets.material;
using Unity.UIWidgets.painting;
using Unity.UIWidgets.widgets;
namespace UIWidgetsGallery.demo.material
{
internal delegate T getDessertField<T>(Dessert d);
internal class Dessert
{
public Dessert(string name, int calories, float fat, int carbs, float protein, int sodium, int calcium,
int iron)
{
this.name = name;
this.calories = calories;
this.fat = fat;
this.carbs = carbs;
this.protein = protein;
this.sodium = sodium;
this.calcium = calcium;
this.iron = iron;
}
public readonly string name;
public readonly int calories;
public readonly float fat;
public readonly int carbs;
public readonly float protein;
public readonly int sodium;
public readonly int calcium;
public readonly int iron;
internal bool selected = false;
}
internal class DessertDataSource : DataTableSource
{
public readonly List<Dessert> _desserts = new List<Dessert>
{
new Dessert("Frozen yogurt", 159, 6.0f, 24, 4.0f, 87, 14, 1),
new Dessert("Ice cream sandwich", 237, 9.0f, 37, 4.3f, 129, 8, 1),
new Dessert("Eclair", 262, 16.0f, 24, 6.0f, 337, 6, 7),
new Dessert("Cupcake", 305, 3.7f, 67, 4.3f, 413, 3, 8),
new Dessert("Gingerbread", 356, 16.0f, 49, 3.9f, 327, 7, 16),
new Dessert("Jelly bean", 375, 0.0f, 94, 0.0f, 50, 0, 0),
new Dessert("Lollipop", 392, 0.2f, 98, 0.0f, 38, 0, 2),
new Dessert("Honeycomb", 408, 3.2f, 87, 6.5f, 562, 0, 45),
new Dessert("Donut", 452, 25.0f, 51, 4.9f, 326, 2, 22),
new Dessert("KitKat", 518, 26.0f, 65, 7.0f, 54, 12, 6),
new Dessert("Frozen yogurt with sugar", 168, 6.0f, 26, 4.0f, 87, 14, 1),
new Dessert("Ice cream sandwich with sugar", 246, 9.0f, 39, 4.3f, 129, 8, 1),
new Dessert("Eclair with sugar", 271, 16.0f, 26, 6.0f, 337, 6, 7),
new Dessert("Cupcake with sugar", 314, 3.7f, 69, 4.3f, 413, 3, 8),
new Dessert("Gingerbread with sugar", 345, 16.0f, 51, 3.9f, 327, 7, 16),
new Dessert("Jelly bean with sugar", 364, 0.0f, 96, 0.0f, 50, 0, 0),
new Dessert("Lollipop with sugar", 401, 0.2f, 100, 0.0f, 38, 0, 2),
new Dessert("Honeycomb with sugar", 417, 3.2f, 89, 6.5f, 562, 0, 45),
new Dessert("Donut with sugar", 461, 25.0f, 53, 4.9f, 326, 2, 22),
new Dessert("KitKat with sugar", 527, 26.0f, 67, 7.0f, 54, 12, 6),
new Dessert("Frozen yogurt with honey", 223, 6.0f, 36, 4.0f, 87, 14, 1),
new Dessert("Ice cream sandwich with honey", 301, 9.0f, 49, 4.3f, 129, 8, 1),
new Dessert("Eclair with honey", 326, 16.0f, 36, 6.0f, 337, 6, 7),
new Dessert("Cupcake with honey", 369, 3.7f, 79, 4.3f, 413, 3, 8),
new Dessert("Gingerbread with honey", 420, 16.0f, 61, 3.9f, 327, 7, 16),
new Dessert("Jelly bean with honey", 439, 0.0f, 106, 0.0f, 50, 0, 0),
new Dessert("Lollipop with honey", 456, 0.2f, 110, 0.0f, 38, 0, 2),
new Dessert("Honeycomb with honey", 472, 3.2f, 99, 6.5f, 562, 0, 45),
new Dessert("Donut with honey", 516, 25.0f, 63, 4.9f, 326, 2, 22),
new Dessert("KitKat with honey", 582, 26.0f, 77, 7.0f, 54, 12, 6),
new Dessert("Frozen yogurt with milk", 262, 8.4f, 36, 12.0f, 194, 44, 1),
new Dessert("Ice cream sandwich with milk", 339, 11.4f, 49, 12.3f, 236, 38, 1),
new Dessert("Eclair with milk", 365, 18.4f, 36, 14.0f, 444, 36, 7),
new Dessert("Cupcake with milk", 408, 6.1f, 79, 12.3f, 520, 33, 8),
new Dessert("Gingerbread with milk", 459, 18.4f, 61, 11.9f, 434, 37, 16),
new Dessert("Jelly bean with milk", 478, 2.4f, 106, 8.0f, 157, 30, 0),
new Dessert("Lollipop with milk", 495, 2.6f, 110, 8.0f, 145, 30, 2),
new Dessert("Honeycomb with milk", 511, 5.6f, 99, 14.5f, 669, 30, 45),
new Dessert("Donut with milk", 555, 27.4f, 63, 12.9f, 433, 32, 22),
new Dessert("KitKat with milk", 621, 28.4f, 77, 15.0f, 161, 42, 6),
new Dessert("Coconut slice and frozen yogurt", 318, 21.0f, 31, 5.5f, 96, 14, 7),
new Dessert("Coconut slice and ice cream sandwich", 396, 24.0f, 44, 5.8f, 138, 8, 7),
new Dessert("Coconut slice and eclair", 421, 31.0f, 31, 7.5f, 346, 6, 13),
new Dessert("Coconut slice and cupcake", 464, 18.7f, 74, 5.8f, 422, 3, 14),
new Dessert("Coconut slice and gingerbread", 515, 31.0f, 56, 5.4f, 316, 7, 22),
new Dessert("Coconut slice and jelly bean", 534, 15.0f, 101, 1.5f, 59, 0, 6),
new Dessert("Coconut slice and lollipop", 551, 15.2f, 105, 1.5f, 47, 0, 8),
new Dessert("Coconut slice and honeycomb", 567, 18.2f, 94, 8.0f, 571, 0, 51),
new Dessert("Coconut slice and donut", 611, 40.0f, 58, 6.4f, 335, 2, 28),
new Dessert("Coconut slice and KitKat", 677, 41.0f, 72, 8.5f, 63, 12, 12),
};
internal void _sort<T>(getDessertField<T> getField, bool isAscending) where T : IComparable
{
this._desserts.Sort((Dessert a, Dessert b) =>
{
if (!isAscending)
{
Dessert c = a;
a = b;
b = c;
}
T aValue = getField(a);
T bValue = getField(b);
return aValue.CompareTo(bValue);
});
this.notifyListeners();
}
private int _selectedCount = 0;
public override DataRow getRow(int index)
{
D.assert(index >= 0);
if (index >= this._desserts.Count)
return null;
Dessert dessert = this._desserts[index];
return DataRow.byIndex(
index: index,
selected: dessert.selected,
onSelectChanged: (bool value) =>
{
if (dessert.selected != value)
{
this._selectedCount += value ? 1 : -1;
D.assert(this._selectedCount >= 0);
dessert.selected = value;
this.notifyListeners();
}
},
cells: new List<DataCell>
{
new DataCell(new Text(dessert.name)),
new DataCell(new Text($"{dessert.calories}")),
new DataCell(new Text($"{dessert.fat:F1}")),
new DataCell(new Text($"{dessert.carbs}")),
new DataCell(new Text($"{dessert.protein:F1}")),
new DataCell(new Text($"{dessert.sodium}")),
new DataCell(new Text($"{dessert.calcium}%")),
new DataCell(new Text($"{dessert.iron}%")),
}
);
}
private new int rowCount => this._desserts.Count;
private new bool isRowCountApproximate => false;
private new int selectedRowCount => this._selectedCount;
public void _selectAll(bool isChecked)
{
foreach (Dessert dessert in this._desserts)
dessert.selected = isChecked;
this._selectedCount = isChecked ? this._desserts.Count : 0;
this.notifyListeners();
}
}
internal class DataTableDemo : StatefulWidget
{
public const string routeName = "/material/data-table";
public override State createState()
{
return new _DataTableDemoState();
}
}
internal class _DataTableDemoState : State<DataTableDemo>
{
private int _rowsPerPage = PaginatedDataTable.defaultRowsPerPage;
private int _sortColumnIndex;
private bool _sortAscending = true;
private DessertDataSource _dessertsDataSource = new DessertDataSource();
private void _sort<T>(getDessertField<T> getField, int columnIndex, bool ascending) where T : IComparable
{
this._dessertsDataSource._sort<T>(getField, ascending);
this.setState(() =>
{
this._sortColumnIndex = columnIndex;
this._sortAscending = ascending;
});
}
public override Widget build(BuildContext context)
{
return new Scaffold(
appBar: new AppBar(
title: new Text("Data tables"),
actions: new List<Widget>
{
new MaterialDemoDocumentationButton(DataTableDemo.routeName)
}
),
body: new Scrollbar(
child: new ListView(
padding: EdgeInsets.all(20.0f),
children: new List<Widget>
{
new PaginatedDataTable(
header: new Text("Nutrition"),
rowsPerPage: this._rowsPerPage,
onRowsPerPageChanged: (int value) =>
{
this.setState(() => { this._rowsPerPage = value; });
},
sortColumnIndex: this._sortColumnIndex,
sortAscending: this._sortAscending,
onSelectAll: this._dessertsDataSource._selectAll,
columns: new List<DataColumn>
{
new DataColumn(
label: new Text("Dessert (100g serving)"),
onSort: (int columnIndex, bool ascending) =>
this._sort<string>((Dessert d) => d.name, columnIndex, ascending)
),
new DataColumn(
label: new Text("Calories"),
tooltip: "The total amount of food energy in the given serving size.",
numeric: true,
onSort: (int columnIndex, bool ascending) =>
this._sort<int>((Dessert d) => d.calories, columnIndex, ascending)
),
new DataColumn(
label: new Text("Fat (g)"),
numeric: true,
onSort: (int columnIndex, bool ascending) =>
this._sort<float>((Dessert d) => d.fat, columnIndex, ascending)
),
new DataColumn(
label: new Text("Carbs (g)"),
numeric: true,
onSort: (int columnIndex, bool ascending) =>
this._sort<int>((Dessert d) => d.carbs, columnIndex, ascending)
),
new DataColumn(
label: new Text("Protein (g)"),
numeric: true,
onSort: (int columnIndex, bool ascending) =>
this._sort<float>((Dessert d) => d.protein, columnIndex, ascending)
),
new DataColumn(
label: new Text("Sodium (mg)"),
numeric: true,
onSort: (int columnIndex, bool ascending) =>
this._sort<int>((Dessert d) => d.sodium, columnIndex, ascending)
),
new DataColumn(
label: new Text("Calcium (%)"),
tooltip:
"The amount of calcium as a percentage of the recommended daily amount.",
numeric: true,
onSort: (int columnIndex, bool ascending) =>
this._sort<int>((Dessert d) => d.calcium, columnIndex, ascending)
),
new DataColumn(
label: new Text("Iron (%)"),
numeric: true,
onSort: (int columnIndex, bool ascending) =>
this._sort<int>((Dessert d) => d.iron, columnIndex, ascending)
)
},
source: this._dessertsDataSource
)
}
)
)
);
}
}
}

3
Samples/UIWidgetsSamples_2019_4/Assets/UIWidgetsGallery/demo/material/data_table_demo.cs.meta


fileFormatVersion: 2
guid: 3074c923fe324b40ab4ba2c7e57c4132
timeCreated: 1612427217
正在加载...
取消
保存