浏览代码

Merge branch 'add_hero_sample' of https://github.com/Unity-Technologies/awesome-uiwidgets into add_hero_sample

/add_hero_sample
siyao 3 年前
当前提交
cb0f6d6e
共有 7 个文件被更改,包括 645 次插入1 次删除
  1. 20
      AwesomeUIWidgets/Assets/Scripts/RaycastableScene/ItemPickerMainUIPanel.cs
  2. 156
      AwesomeUIWidgets/Assets/Scripts/RaycastableScene/LeftUIPanel.cs
  3. 3
      AwesomeUIWidgets/Assets/Scripts/RaycastableScene/LeftUIPanel.cs.meta
  4. 29
      AwesomeUIWidgets/Assets/Scripts/RaycastableScene/custom_card.cs
  5. 3
      AwesomeUIWidgets/Assets/Scripts/RaycastableScene/custom_card.cs.meta
  6. 432
      AwesomeUIWidgets/Assets/Scripts/RaycastableScene/custom_checkbox.cs
  7. 3
      AwesomeUIWidgets/Assets/Scripts/RaycastableScene/custom_checkbox.cs.meta

20
AwesomeUIWidgets/Assets/Scripts/RaycastableScene/ItemPickerMainUIPanel.cs


{
public class ItemPickerMainUIPanel : UIWidgetsRaycastablePanel
{
protected override void onEnable()
{
AddFont("Material Icons", new List<string> {"MaterialIcons-Regular.ttf"}, new List<int> {0});
}
protected override void main()
{
ui_.runApp(new ItemPickerMainUI());

private Widget buildLeft()
{
return new RaycastableContainer(child: new Container(width: 100f, color: Colors.green));
return new RaycastableContainer(child: new Container(width: 100f, color: Colors.green.withAlpha(125), child: new LeftUIPanel(
itemNames: new List<PickListItem>
{
new PickListItem("cube1"),
new PickListItem("cube2"),
new PickListItem("cube3"),
new PickListItem("cube4"),
new PickListItem("ball1"),
new PickListItem("ball2"),
new PickListItem("ball4"),
new PickListItem("cylinder1"),
new PickListItem("cylinder2")
}
)));
}
}
}

156
AwesomeUIWidgets/Assets/Scripts/RaycastableScene/LeftUIPanel.cs


using System.Collections.Generic;
using uiwidgets;
using Unity.UIWidgets.foundation;
using Unity.UIWidgets.material;
using Unity.UIWidgets.painting;
using Unity.UIWidgets.ui;
using Unity.UIWidgets.widgets;
using TextStyle = Unity.UIWidgets.painting.TextStyle;
namespace UIWidgetsSample.RaycastableScene
{
public class PickListItem
{
public string itemName;
public bool active;
public string showName;
public PickListItem(string itemName, bool active = true, string showName = null)
{
this.itemName = itemName;
this.active = active;
this.showName = showName ?? itemName;
}
}
public class LeftUIPanel : StatefulWidget
{
public LeftUIPanel(Key key = null,
List<PickListItem> itemNames = null) : base(key: key)
{
this.itemNames = itemNames ?? new List<PickListItem>();
}
public readonly List<PickListItem> itemNames;
public override State createState()
{
return new LeftUIPanelState();
}
}
public class LeftUIPanelState : State<LeftUIPanel>
{
readonly TextEditingController controller = new TextEditingController();
public override Widget build(BuildContext context)
{
return new Column(
children: new List<Widget>
{
buildSearchBar(),
buildItemList()
}
);
}
public override void initState()
{
base.initState();
_searchResult.AddRange(widget.itemNames);
}
private readonly List<PickListItem> _searchResult = new List<PickListItem>();
private Widget buildSearchBar()
{
return new Container(
color: Colors.lightBlue.withAlpha(125),
child: new Padding(
padding: EdgeInsets.all(1.0f),
child:
new Card(
child: new Row(
children: new List<Widget>{
new Padding(padding: EdgeInsets.only(left: 2f)),
new Icon(Icons.search, size: 14f),
new Flexible(child: new TextField(
controller: controller,
style: new TextStyle(fontSize: 8f),
decoration: new InputDecoration(
hintText: "Search", border: InputBorder.none,
contentPadding: EdgeInsets.all(4),
isDense: true),
onChanged: onSearchTextChanged
)),
new GestureDetector(
child: new Icon(Icons.cancel, size: 10f),
onTap: () =>
{
controller.clear();
onSearchTextChanged("");
}
),
new Padding(padding: EdgeInsets.only(right: 2f))
}))));
}
private Widget buildItemList()
{
return new Expanded(
child: _searchResult.Count != 0 ?
(Widget) ListView.builder(itemCount: _searchResult.Count,
itemBuilder: (build_context, index) =>
{
return new Container(
child: new Padding(
padding: EdgeInsets.only(left: 4.0f, right: 4f),
child: new Card(
shape:new RoundedRectangleBorder(
borderRadius: BorderRadius.all(Radius.circular(2.0f))
),
margin: EdgeInsets.all(1),
child: new Row(
children: new List<Widget> {
new Padding(padding: EdgeInsets.only(left: 2f)),
new Checkbox(value: _searchResult[index].active, onChanged: (value) =>
{
if (value == null)
{
return;
}
setState(() =>
{
_searchResult[index].active = value.Value;
});
}),
new Text(_searchResult[index].showName, style: new TextStyle(fontSize: 8f))
}
)
)));
}) : new Center(
child: new Text("No Available Item", style: new TextStyle(fontSize: 8f))
)
);
}
private void onSearchTextChanged(string text)
{
_searchResult.Clear();
if (text.isEmpty())
{
_searchResult.AddRange(widget.itemNames);
}
else
{
foreach (var item in widget.itemNames)
{
if (item.showName.StartsWith(text))
{
_searchResult.Add(item);
}
}
}
setState(() => {});
}
}
}

3
AwesomeUIWidgets/Assets/Scripts/RaycastableScene/LeftUIPanel.cs.meta


fileFormatVersion: 2
guid: 9eb5e0209eb64d63a223f69f35648cfd
timeCreated: 1627441065

29
AwesomeUIWidgets/Assets/Scripts/RaycastableScene/custom_card.cs


using uiwidgets;
using Unity.UIWidgets.foundation;
using Unity.UIWidgets.painting;
using Unity.UIWidgets.ui;
using Unity.UIWidgets.widgets;
namespace UIWidgetsSample.RaycastableScene {
public class CustomCard : StatelessWidget {
public CustomCard(
Key key = null,
Widget child = null) : base(key: key) {
this.child = child;
}
public readonly Widget child;
const float _defaultElevation = 1.0f;
const Clip _defaultClipBehavior = Clip.none;
public override Widget build(BuildContext context) {
return new Container(
margin: EdgeInsets.only(left: 5f, right: 5f, top: 4f, bottom: 4f),
color: Colors.white,
decoration: new BoxDecoration(borderRadius: BorderRadius.all(Radius.circular(20.0f))),
child: child
);
}
}
}

3
AwesomeUIWidgets/Assets/Scripts/RaycastableScene/custom_card.cs.meta


fileFormatVersion: 2
guid: 3b96b98fbc1c454c82475aac36aeefd1
timeCreated: 1627442468

432
AwesomeUIWidgets/Assets/Scripts/RaycastableScene/custom_checkbox.cs


using System;
using System.Collections.Generic;
using uiwidgets;
using Unity.UIWidgets.animation;
using Unity.UIWidgets.foundation;
using Unity.UIWidgets.material;
using Unity.UIWidgets.rendering;
using Unity.UIWidgets.scheduler;
using Unity.UIWidgets.ui;
using Unity.UIWidgets.widgets;
using UnityEngine;
using Canvas = Unity.UIWidgets.ui.Canvas;
using Color = Unity.UIWidgets.ui.Color;
using Rect = Unity.UIWidgets.ui.Rect;
namespace UIWidgetsSample.RaycastableScene {
class CheckboxUtils {
public const float _kEdgeSize = Checkbox.width;
public static readonly Radius _kEdgeRadius = Radius.circular(1.0f);
public const float _kStrokeWidth = 2.0f;
public static Color checkColor = Colors.blue;
public static float kRadialReactionRadius = 12f;
}
public class Checkbox : StatefulWidget {
public Checkbox(
Key key = null,
bool? value = false,
bool tristate = false,
ValueChanged<bool?> onChanged = null,
Color activeColor = null,
Color checkColor = null,
Color focusColor = null,
Color hoverColor = null,
MaterialTapTargetSize? materialTapTargetSize = null,
VisualDensity visualDensity = null,
FocusNode focusNode = null,
bool autofocus = false
) : base(key: key) {
D.assert(tristate || value != null);
this.value = value;
this.onChanged = onChanged;
this.activeColor = activeColor;
this.checkColor = checkColor;
this.focusColor = focusColor;
this.hoverColor = hoverColor;
this.tristate = tristate;
this.materialTapTargetSize = materialTapTargetSize;
this.visualDensity = visualDensity;
this.focusNode = focusNode;
this.autofocus = autofocus;
}
public readonly bool? value;
public readonly ValueChanged<bool?> onChanged;
public readonly Color activeColor;
public readonly Color checkColor;
public readonly bool tristate;
public readonly MaterialTapTargetSize? materialTapTargetSize;
public readonly VisualDensity visualDensity;
public readonly Color focusColor;
public readonly Color hoverColor;
public readonly FocusNode focusNode;
public readonly bool autofocus;
public const float width = 10.0f;
public override State createState() {
return new _CheckboxState();
}
}
class _CheckboxState : TickerProviderStateMixin<Checkbox> {
bool enabled {
get { return widget.onChanged != null; }
}
Dictionary<LocalKey, ActionFactory> _actionMap;
public override void initState() {
base.initState();
_actionMap = new Dictionary<LocalKey, ActionFactory> {
{ActivateAction.key, _createAction}
};
}
void _actionHandler(FocusNode node, Intent intent) {
if (widget.onChanged != null) {
switch (widget.value) {
case false:
widget.onChanged(true);
break;
case true:
widget.onChanged(widget.tristate);
break;
default: // case null:
widget.onChanged(false);
break;
}
}
RenderObject renderObject = node.context.findRenderObject();
// renderObject.sendSemanticsEvent(const TapSemanticEvent());
}
UiWidgetAction _createAction() {
return new CallbackAction(
ActivateAction.key,
onInvoke: _actionHandler
);
}
bool _focused = false;
void _handleFocusHighlightChanged(bool focused) {
if (focused != _focused) {
setState(() => { _focused = focused; });
}
}
bool _hovering = false;
void _handleHoverChanged(bool hovering) {
if (hovering != _hovering) {
setState(() => { _hovering = hovering; });
}
}
public override Widget build(BuildContext context) {
Size size;
switch (widget.materialTapTargetSize ?? MaterialTapTargetSize.padded) {
case MaterialTapTargetSize.padded:
size = new Size(2 * CheckboxUtils.kRadialReactionRadius,
2 * CheckboxUtils.kRadialReactionRadius);
break;
case MaterialTapTargetSize.shrinkWrap:
size = new Size(2 * CheckboxUtils.kRadialReactionRadius, 2 * CheckboxUtils.kRadialReactionRadius);
break;
default:
throw new Exception("Unknown target size: " + widget.materialTapTargetSize);
}
size += (widget.visualDensity ?? VisualDensity.standard).baseSizeAdjustment;
BoxConstraints additionalConstraints = BoxConstraints.tight(size);
return new FocusableActionDetector(
actions: _actionMap,
focusNode: widget.focusNode,
autofocus: widget.autofocus,
enabled: enabled,
onShowFocusHighlight: _handleFocusHighlightChanged,
onShowHoverHighlight: _handleHoverChanged,
child: new Builder(
builder: (BuildContext _context) => {
return new _CheckboxRenderObjectWidget(
value: widget.value,
tristate: widget.tristate,
activeColor: widget.activeColor ?? CheckboxUtils.checkColor,
checkColor: widget.checkColor ?? new Color(0xFFFFFFFF),
inactiveColor: enabled ? CheckboxUtils.checkColor : Colors.grey,
focusColor: widget.focusColor ?? CheckboxUtils.checkColor,
hoverColor: widget.hoverColor ?? CheckboxUtils.checkColor,
onChanged: widget.onChanged,
additionalConstraints: additionalConstraints,
vsync: this,
hasFocus: _focused,
hovering: _hovering
);
}
)
);
}
}
class _CheckboxRenderObjectWidget : LeafRenderObjectWidget {
public _CheckboxRenderObjectWidget(
Key key = null,
bool? value = null,
bool tristate = false,
Color activeColor = null,
Color checkColor = null,
Color inactiveColor = null,
Color focusColor = null,
Color hoverColor = null,
ValueChanged<bool?> onChanged = null,
TickerProvider vsync = null,
BoxConstraints additionalConstraints = null,
bool? hasFocus = null,
bool? hovering = null
) : base(key: key) {
D.assert(tristate || value != null);
D.assert(activeColor != null);
D.assert(inactiveColor != null);
D.assert(vsync != null);
this.value = value;
this.tristate = tristate;
this.activeColor = activeColor;
this.checkColor = checkColor;
this.inactiveColor = inactiveColor;
this.focusColor = focusColor;
this.hoverColor = hoverColor;
this.onChanged = onChanged;
this.vsync = vsync;
this.additionalConstraints = additionalConstraints;
this.hasFocus = hasFocus;
this.hovering = hovering;
}
public readonly bool? value;
public readonly bool tristate;
public readonly bool? hasFocus;
public readonly bool? hovering;
public readonly Color activeColor;
public readonly Color checkColor;
public readonly Color inactiveColor;
public readonly Color focusColor;
public readonly Color hoverColor;
public readonly ValueChanged<bool?> onChanged;
public readonly TickerProvider vsync;
public readonly BoxConstraints additionalConstraints;
public override RenderObject createRenderObject(BuildContext context) {
return new _RenderCheckbox(
value: value,
tristate: tristate,
activeColor: activeColor,
checkColor: checkColor,
inactiveColor: inactiveColor,
focusColor: focusColor,
hoverColor: hoverColor,
onChanged: onChanged,
vsync: vsync,
additionalConstraints: additionalConstraints,
hasFocus: hasFocus,
hovering: hovering
);
}
public override void updateRenderObject(BuildContext context, RenderObject _renderObject) {
_RenderCheckbox renderObject = _renderObject as _RenderCheckbox;
renderObject.value = value;
renderObject.tristate = tristate;
renderObject.activeColor = activeColor;
renderObject.checkColor = checkColor;
renderObject.focusColor = focusColor;
renderObject.hoverColor = hoverColor;
renderObject.inactiveColor = inactiveColor;
renderObject.onChanged = onChanged;
renderObject.additionalConstraints = additionalConstraints;
renderObject.vsync = vsync;
renderObject.hasFocus = hasFocus ?? false;
renderObject.hovering = hovering ?? false;
}
}
class _RenderCheckbox : RenderToggleable {
public _RenderCheckbox(
bool? value = null,
bool tristate = false,
Color activeColor = null,
Color checkColor = null,
Color inactiveColor = null,
Color focusColor = null,
Color hoverColor = null,
BoxConstraints additionalConstraints = null,
ValueChanged<bool?> onChanged = null,
TickerProvider vsync = null,
bool? hasFocus = null,
bool? hovering = null
) : base(
value: value,
tristate: tristate,
activeColor: activeColor,
inactiveColor: inactiveColor,
focusColor: focusColor,
hoverColor: hoverColor,
onChanged: onChanged,
additionalConstraints: additionalConstraints,
vsync: vsync,
hasFocus: hasFocus ?? false,
hovering: hovering ?? false
) {
_oldValue = value;
this.checkColor = checkColor;
}
bool? _oldValue;
public Color checkColor;
public override bool? value {
set {
if (value == this.value) {
return;
}
_oldValue = this.value;
base.value = value;
}
}
RRect _outerRectAt(Offset origin, float t) {
float inset = 1.0f - (t - 0.5f).abs() * 2.0f;
float size = CheckboxUtils._kEdgeSize - inset * CheckboxUtils._kStrokeWidth;
Rect rect = Rect.fromLTWH(origin.dx + inset, origin.dy + inset, size, size);
return RRect.fromRectAndRadius(rect, CheckboxUtils._kEdgeRadius);
}
Color _colorAt(float t) {
return onChanged == null
? inactiveColor
: (t >= 0.25f ? activeColor : Color.lerp(inactiveColor, activeColor, t * 4.0f));
}
Paint _createStrokePaint() {
var paint = new Paint();
paint.color = checkColor;
paint.style = PaintingStyle.stroke;
paint.strokeWidth = CheckboxUtils._kStrokeWidth;
return paint;
}
void _drawBorder(Canvas canvas, RRect outer, float t, Paint paint) {
D.assert(t >= 0.0f && t <= 0.5f);
float size = outer.width;
RRect inner = outer.deflate(Mathf.Min(size / 2.0f, CheckboxUtils._kStrokeWidth + size * t));
canvas.drawDRRect(outer, inner, paint);
}
void _drawCheck(Canvas canvas, Offset origin, float t, Paint paint) {
D.assert(t >= 0.0f && t <= 1.0f);
Path path = new Path();
Offset start = new Offset(CheckboxUtils._kEdgeSize * 0.15f, CheckboxUtils._kEdgeSize * 0.45f);
Offset mid = new Offset(CheckboxUtils._kEdgeSize * 0.4f, CheckboxUtils._kEdgeSize * 0.7f);
Offset end = new Offset(CheckboxUtils._kEdgeSize * 0.85f, CheckboxUtils._kEdgeSize * 0.25f);
if (t < 0.5f) {
float strokeT = t * 2.0f;
Offset drawMid = Offset.lerp(start, mid, strokeT);
path.moveTo(origin.dx + start.dx, origin.dy + start.dy);
path.lineTo(origin.dx + drawMid.dx, origin.dy + drawMid.dy);
}
else {
float strokeT = (t - 0.5f) * 2.0f;
Offset drawEnd = Offset.lerp(mid, end, strokeT);
path.moveTo(origin.dx + start.dx, origin.dy + start.dy);
path.lineTo(origin.dx + mid.dx, origin.dy + mid.dy);
path.lineTo(origin.dx + drawEnd.dx, origin.dy + drawEnd.dy);
}
canvas.drawPath(path, paint);
}
void _drawDash(Canvas canvas, Offset origin, float t, Paint paint) {
D.assert(t >= 0.0f && t <= 1.0f);
Offset start = new Offset(CheckboxUtils._kEdgeSize * 0.2f, CheckboxUtils._kEdgeSize * 0.5f);
Offset mid = new Offset(CheckboxUtils._kEdgeSize * 0.5f, CheckboxUtils._kEdgeSize * 0.5f);
Offset end = new Offset(CheckboxUtils._kEdgeSize * 0.8f, CheckboxUtils._kEdgeSize * 0.5f);
Offset drawStart = Offset.lerp(start, mid, 1.0f - t);
Offset drawEnd = Offset.lerp(mid, end, t);
canvas.drawLine(origin + drawStart, origin + drawEnd, paint);
}
public override void paint(PaintingContext context, Offset offset) {
Canvas canvas = context.canvas;
paintRadialReaction(canvas, offset, size.center(Offset.zero));
Paint strokePaint = _createStrokePaint();
Offset origin = offset + (size / 2.0f - Size.square(CheckboxUtils._kEdgeSize) / 2.0f);
AnimationStatus status = position.status;
float tNormalized = status == AnimationStatus.forward || status == AnimationStatus.completed
? position.value
: 1.0f - position.value;
if (_oldValue == false || value == false) {
float t = value == false ? 1.0f - tNormalized : tNormalized;
RRect outer = _outerRectAt(origin, t);
Paint paint = new Paint();
paint.color = _colorAt(t);
if (t <= 0.5f) {
_drawBorder(canvas, outer, t, paint);
}
else {
canvas.drawRRect(outer, paint);
float tShrink = (t - 0.5f) * 2.0f;
if (_oldValue == null || value == null) {
_drawDash(canvas, origin, tShrink, strokePaint);
}
else {
_drawCheck(canvas, origin, tShrink, strokePaint);
}
}
}
else {
// Two cases: null to true, true to null
RRect outer = _outerRectAt(origin, 1.0f);
Paint paint = new Paint();
paint.color = _colorAt(1.0f);
canvas.drawRRect(outer, paint);
if (tNormalized <= 0.5f) {
float tShrink = 1.0f - tNormalized * 2.0f;
if (_oldValue == true) {
_drawCheck(canvas, origin, tShrink, strokePaint);
}
else {
_drawDash(canvas, origin, tShrink, strokePaint);
}
}
else {
float tExpand = (tNormalized - 0.5f) * 2.0f;
if (value == true) {
_drawCheck(canvas, origin, tExpand, strokePaint);
}
else {
_drawDash(canvas, origin, tExpand, strokePaint);
}
}
}
}
}
}

3
AwesomeUIWidgets/Assets/Scripts/RaycastableScene/custom_checkbox.cs.meta


fileFormatVersion: 2
guid: 81ec2bb9ee8a44149413a67366a22958
timeCreated: 1627441046
正在加载...
取消
保存