您最多选择25个主题 主题必须以中文或者字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符
 
 
 
 
 
 

365 行
14 KiB

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", "gallery/people/square/ali.png"},
{"chisel", "gallery/people/square/sandra.png"},
{"fryer", "gallery/people/square/trevor.png"},
{"fabricator", "gallery/people/square/stella.png"},
{"customer", "gallery/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)
)
);
}
}
}