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

867 行
31 KiB

using System.Collections.Generic;
using System.Linq;
using Unity.UIWidgets.foundation;
using Unity.UIWidgets.gestures;
using Unity.UIWidgets.painting;
using Unity.UIWidgets.rendering;
using Unity.UIWidgets.service;
using Unity.UIWidgets.ui;
using Unity.UIWidgets.widgets;
using UnityEngine;
using Color = Unity.UIWidgets.ui.Color;
using TextStyle = Unity.UIWidgets.painting.TextStyle;
namespace Unity.UIWidgets.material {
public enum ListTileStyle {
list,
drawer
}
public class ListTileTheme : InheritedWidget {
public ListTileTheme(
Key key = null,
bool dense = false,
ListTileStyle style = ListTileStyle.list,
Color selectedColor = null,
Color iconColor = null,
Color textColor = null,
EdgeInsets contentPadding = null,
Widget child = null) : base(key: key, child: child) {
this.dense = dense;
this.style = style;
this.selectedColor = selectedColor;
this.iconColor = iconColor;
this.textColor = textColor;
this.contentPadding = contentPadding;
}
public static Widget merge(
Key key = null,
bool? dense = null,
ListTileStyle? style = null,
Color selectedColor = null,
Color iconColor = null,
Color textColor = null,
EdgeInsets contentPadding = null,
Widget child = null) {
D.assert(child != null);
return new Builder(
builder: (BuildContext context) => {
ListTileTheme parent = of(context);
return new ListTileTheme(
key: key,
dense: dense ?? parent.dense,
style: style ?? parent.style,
selectedColor: selectedColor ?? parent.selectedColor,
iconColor: iconColor ?? parent.iconColor,
textColor: textColor ?? parent.textColor,
contentPadding: contentPadding ?? parent.contentPadding,
child: child);
}
);
}
public readonly bool dense;
public readonly ListTileStyle style;
public readonly Color selectedColor;
public readonly Color iconColor;
public readonly Color textColor;
public readonly EdgeInsets contentPadding;
public static ListTileTheme of(BuildContext context) {
ListTileTheme result = (ListTileTheme) context.inheritFromWidgetOfExactType(typeof(ListTileTheme));
return result ?? new ListTileTheme();
}
public override bool updateShouldNotify(InheritedWidget oldWidget) {
ListTileTheme _oldWidget = (ListTileTheme) oldWidget;
return this.dense != _oldWidget.dense ||
this.style != _oldWidget.style ||
this.selectedColor != _oldWidget.selectedColor ||
this.iconColor != _oldWidget.iconColor ||
this.textColor != _oldWidget.textColor ||
this.contentPadding != _oldWidget.contentPadding;
}
}
public enum ListTileControlAffinity {
leading,
trailing,
platform
}
public class ListTile : StatelessWidget {
public ListTile(
Key key = null,
Widget leading = null,
Widget title = null,
Widget subtitle = null,
Widget trailing = null,
bool isThreeLine = false,
bool? dense = null,
EdgeInsets contentPadding = null,
bool enabled = true,
GestureTapCallback onTap = null,
GestureLongPressCallback onLongPress = null,
bool selected = false
) : base(key: key) {
D.assert(!isThreeLine || subtitle != null);
this.leading = leading;
this.title = title;
this.subtitle = subtitle;
this.trailing = trailing;
this.isThreeLine = isThreeLine;
this.dense = dense;
this.contentPadding = contentPadding;
this.enabled = enabled;
this.onTap = onTap;
this.onLongPress = onLongPress;
this.selected = selected;
}
public readonly Widget leading;
public readonly Widget title;
public readonly Widget subtitle;
public readonly Widget trailing;
public readonly bool isThreeLine;
public readonly bool? dense;
public readonly EdgeInsets contentPadding;
public readonly bool enabled;
public readonly GestureTapCallback onTap;
public readonly GestureLongPressCallback onLongPress;
public readonly bool selected;
Color _iconColor(ThemeData theme, ListTileTheme tileTheme) {
if (!this.enabled) {
return theme.disabledColor;
}
if (this.selected && tileTheme?.selectedColor != null) {
return tileTheme.selectedColor;
}
if (!this.selected && tileTheme?.iconColor != null) {
return tileTheme.iconColor;
}
switch (theme.brightness) {
case Brightness.light:
return this.selected ? theme.primaryColor : Colors.black45;
case Brightness.dark:
return this.selected ? theme.accentColor : null;
}
return null;
}
Color _textColor(ThemeData theme, ListTileTheme tileTheme, Color defaultColor) {
if (!this.enabled) {
return theme.disabledColor;
}
if (this.selected && tileTheme?.selectedColor != null) {
return tileTheme.selectedColor;
}
if (!this.selected && tileTheme?.textColor != null) {
return tileTheme.textColor;
}
if (this.selected) {
switch (theme.brightness) {
case Brightness.light:
return theme.primaryColor;
case Brightness.dark:
return theme.accentColor;
}
}
return defaultColor;
}
bool _isDenseLayout(ListTileTheme tileTheme) {
return this.dense != null ? this.dense ?? false : (tileTheme?.dense ?? false);
}
TextStyle _titleTextStyle(ThemeData theme, ListTileTheme tileTheme) {
TextStyle style = null;
if (tileTheme != null) {
switch (tileTheme.style) {
case ListTileStyle.drawer:
style = theme.textTheme.body2;
break;
case ListTileStyle.list:
style = theme.textTheme.subhead;
break;
}
}
else {
style = theme.textTheme.subhead;
}
Color color = this._textColor(theme, tileTheme, style.color);
return this._isDenseLayout(tileTheme)
? style.copyWith(fontSize: 13.0f, color: color)
: style.copyWith(color: color);
}
TextStyle _subtitleTextStyle(ThemeData theme, ListTileTheme tileTheme) {
TextStyle style = theme.textTheme.body1;
Color color = this._textColor(theme, tileTheme, theme.textTheme.caption.color);
return this._isDenseLayout(tileTheme)
? style.copyWith(color: color, fontSize: 12.0f)
: style.copyWith(color: color);
}
public override Widget build(BuildContext context) {
D.assert(MaterialD.debugCheckHasMaterial(context));
ThemeData theme = Theme.of(context);
ListTileTheme tileTheme = ListTileTheme.of(context);
IconThemeData iconThemeData = null;
if (this.leading != null || this.trailing != null) {
iconThemeData = new IconThemeData(color: this._iconColor(theme, tileTheme));
}
Widget leadingIcon = null;
if (this.leading != null) {
leadingIcon = IconTheme.merge(
data: iconThemeData,
child: this.leading);
}
TextStyle titleStyle = this._titleTextStyle(theme, tileTheme);
Widget titleText = new AnimatedDefaultTextStyle(
style: titleStyle,
duration: Constants.kThemeChangeDuration,
child: this.title ?? new SizedBox()
);
Widget subtitleText = null;
TextStyle subtitleStyle = null;
if (this.subtitle != null) {
subtitleStyle = this._subtitleTextStyle(theme, tileTheme);
subtitleText = new AnimatedDefaultTextStyle(
style: subtitleStyle,
duration: Constants.kThemeChangeDuration,
child: this.subtitle);
}
Widget trailingIcon = null;
if (this.trailing != null) {
trailingIcon = IconTheme.merge(
data: iconThemeData,
child: this.trailing);
}
EdgeInsets _defaultContentPadding = EdgeInsets.symmetric(horizontal: 16.0f);
EdgeInsets resolvedContentPadding =
this.contentPadding ?? tileTheme?.contentPadding ?? _defaultContentPadding;
return new InkWell(
onTap: this.enabled ? this.onTap : null,
onLongPress: this.enabled ? this.onLongPress : null,
child: new SafeArea(
top: false,
bottom: false,
mininum: resolvedContentPadding,
child: new _ListTile(
leading: leadingIcon,
title: titleText,
subtitle: subtitleText,
trailing: trailingIcon,
isDense: this._isDenseLayout(tileTheme),
isThreeLine: this.isThreeLine,
titleBaselineType: titleStyle.textBaseline,
subtitleBaselineType: subtitleStyle?.textBaseline
)
)
);
}
}
public enum _ListTileSlot {
leading,
title,
subtitle,
trailing
}
public class _ListTile : RenderObjectWidget {
public _ListTile(
Key key = null,
Widget leading = null,
Widget title = null,
Widget subtitle = null,
Widget trailing = null,
bool? isThreeLine = null,
bool? isDense = null,
TextBaseline? titleBaselineType = null,
TextBaseline? subtitleBaselineType = null) : base(key: key) {
D.assert(isThreeLine != null);
D.assert(isDense != null);
D.assert(titleBaselineType != null);
this.leading = leading;
this.title = title;
this.subtitle = subtitle;
this.trailing = trailing;
this.isThreeLine = isThreeLine ?? false;
this.isDense = isDense ?? false;
this.titleBaselineType = titleBaselineType ?? TextBaseline.alphabetic;
this.subtitleBaselineType = subtitleBaselineType;
}
public readonly Widget leading;
public readonly Widget title;
public readonly Widget subtitle;
public readonly Widget trailing;
public readonly bool isThreeLine;
public readonly bool isDense;
public readonly TextBaseline titleBaselineType;
public readonly TextBaseline? subtitleBaselineType;
public override Element createElement() {
return new _ListTileElement(this);
}
public override RenderObject createRenderObject(BuildContext context) {
return new _RenderListTile(
isThreeLine: this.isThreeLine,
isDense: this.isDense,
titleBaselineType: this.titleBaselineType,
subtitleBaselineType: this.subtitleBaselineType
);
}
public override void updateRenderObject(BuildContext context, RenderObject renderObject) {
_RenderListTile _renderObject = (_RenderListTile) renderObject;
_renderObject.isThreeLine = this.isThreeLine;
_renderObject.isDense = this.isDense;
_renderObject.titleBaselineType = this.titleBaselineType;
_renderObject.subtitleBaselineType = this.subtitleBaselineType;
}
}
public class _ListTileElement : RenderObjectElement {
public _ListTileElement(RenderObjectWidget widget) : base(widget) {
}
readonly Dictionary<_ListTileSlot, Element> slotToChild = new Dictionary<_ListTileSlot, Element>();
readonly Dictionary<Element, _ListTileSlot> childToSlot = new Dictionary<Element, _ListTileSlot>();
public new _ListTile widget {
get { return (_ListTile) base.widget; }
}
public new _RenderListTile renderObject {
get { return (_RenderListTile) base.renderObject; }
}
public override void visitChildren(ElementVisitor visitor) {
foreach (var element in this.slotToChild.Values) {
visitor(element);
}
}
protected override void forgetChild(Element child) {
D.assert(this.slotToChild.Values.Contains(child));
D.assert(this.childToSlot.Keys.Contains(child));
_ListTileSlot slot = this.childToSlot[child];
this.childToSlot.Remove(child);
this.slotToChild.Remove(slot);
}
void _mountChild(Widget widget, _ListTileSlot slot) {
Element oldChild = this.slotToChild.getOrDefault(slot);
Element newChild = this.updateChild(oldChild, widget, slot);
if (oldChild != null) {
this.slotToChild.Remove(slot);
this.childToSlot.Remove(oldChild);
}
if (newChild != null) {
this.slotToChild[slot] = newChild;
this.childToSlot[newChild] = slot;
}
}
public override void mount(Element parent, object newSlot) {
base.mount(parent, newSlot);
this._mountChild(this.widget.leading, _ListTileSlot.leading);
this._mountChild(this.widget.title, _ListTileSlot.title);
this._mountChild(this.widget.subtitle, _ListTileSlot.subtitle);
this._mountChild(this.widget.trailing, _ListTileSlot.trailing);
}
void _updateChild(Widget widget, _ListTileSlot slot) {
Element oldChild = this.slotToChild.getOrDefault(slot);
Element newChild = this.updateChild(oldChild, widget, slot);
if (oldChild != null) {
this.childToSlot.Remove(oldChild);
this.slotToChild.Remove(slot);
}
if (newChild != null) {
this.slotToChild[slot] = newChild;
this.childToSlot[newChild] = slot;
}
}
public override void update(Widget newWidget) {
base.update(newWidget);
D.assert(this.widget == newWidget);
this._updateChild(this.widget.leading, _ListTileSlot.leading);
this._updateChild(this.widget.title, _ListTileSlot.title);
this._updateChild(this.widget.subtitle, _ListTileSlot.subtitle);
this._updateChild(this.widget.trailing, _ListTileSlot.trailing);
}
void _updateRenderObject(RenderObject child, _ListTileSlot slot) {
switch (slot) {
case _ListTileSlot.leading:
this.renderObject.leading = (RenderBox) child;
break;
case _ListTileSlot.title:
this.renderObject.title = (RenderBox) child;
break;
case _ListTileSlot.subtitle:
this.renderObject.subtitle = (RenderBox) child;
break;
case _ListTileSlot.trailing:
this.renderObject.trailing = (RenderBox) child;
break;
}
}
protected override void insertChildRenderObject(RenderObject child, object slotValue) {
D.assert(child is RenderBox);
D.assert(slotValue is _ListTileSlot);
_ListTileSlot slot = (_ListTileSlot) slotValue;
this._updateRenderObject(child, slot);
D.assert(this.renderObject.childToSlot.Keys.Contains(child));
D.assert(this.renderObject.slotToChild.Keys.Contains(slot));
}
protected override void removeChildRenderObject(RenderObject child) {
D.assert(child is RenderBox);
D.assert(this.renderObject.childToSlot.Keys.Contains(child));
_ListTileSlot slot = this.renderObject.childToSlot[(RenderBox) child];
this._updateRenderObject(null, slot);
D.assert(!this.renderObject.childToSlot.Keys.Contains(child));
D.assert(!this.renderObject.slotToChild.Keys.Contains(slot));
}
protected override void moveChildRenderObject(RenderObject child, object slotValue) {
D.assert(false, "not reachable");
}
}
public class _RenderListTile : RenderBox {
public _RenderListTile(
bool? isDense = null,
bool? isThreeLine = null,
TextBaseline? titleBaselineType = null,
TextBaseline? subtitleBaselineType = null) {
D.assert(isDense != null);
D.assert(isThreeLine != null);
D.assert(titleBaselineType != null);
this._isDense = isDense ?? false;
this._isThreeLine = isThreeLine ?? false;
this._titleBaselineType = titleBaselineType ?? TextBaseline.alphabetic;
this._subtitleBaselineType = subtitleBaselineType;
}
const float _minLeadingWidth = 40.0f;
const float _horizontalTitleGap = 16.0f;
const float _minVerticalPadding = 4.0f;
public readonly Dictionary<_ListTileSlot, RenderBox> slotToChild = new Dictionary<_ListTileSlot, RenderBox>();
public readonly Dictionary<RenderBox, _ListTileSlot> childToSlot = new Dictionary<RenderBox, _ListTileSlot>();
RenderBox _updateChild(RenderBox oldChild, RenderBox newChild, _ListTileSlot slot) {
if (oldChild != null) {
this.dropChild(oldChild);
this.childToSlot.Remove(oldChild);
this.slotToChild.Remove(slot);
}
if (newChild != null) {
this.childToSlot[newChild] = slot;
this.slotToChild[slot] = newChild;
this.adoptChild(newChild);
}
return newChild;
}
RenderBox _leading;
public RenderBox leading {
get { return this._leading; }
set { this._leading = this._updateChild(this._leading, value, _ListTileSlot.leading); }
}
RenderBox _title;
public RenderBox title {
get { return this._title; }
set { this._title = this._updateChild(this._title, value, _ListTileSlot.title); }
}
RenderBox _subtitle;
public RenderBox subtitle {
get { return this._subtitle; }
set { this._subtitle = this._updateChild(this._subtitle, value, _ListTileSlot.subtitle); }
}
RenderBox _trailing;
public RenderBox trailing {
get { return this._trailing; }
set { this._trailing = this._updateChild(this._trailing, value, _ListTileSlot.trailing); }
}
List<RenderObject> _children {
get {
List<RenderObject> ret = new List<RenderObject>();
if (this.leading != null) {
ret.Add(this.leading);
}
if (this.title != null) {
ret.Add(this.title);
}
if (this.subtitle != null) {
ret.Add(this.subtitle);
}
if (this.trailing != null) {
ret.Add(this.trailing);
}
return ret;
}
}
public bool isDense {
get { return this._isDense; }
set {
if (this._isDense == value) {
return;
}
this._isDense = value;
this.markNeedsLayout();
}
}
bool _isDense;
public bool isThreeLine {
get { return this._isThreeLine; }
set {
if (this._isThreeLine == value) {
return;
}
this._isThreeLine = value;
this.markNeedsLayout();
}
}
bool _isThreeLine;
public TextBaseline titleBaselineType {
get { return this._titleBaselineType; }
set {
if (this._titleBaselineType == value) {
return;
}
this._titleBaselineType = value;
this.markNeedsLayout();
}
}
TextBaseline _titleBaselineType;
public TextBaseline? subtitleBaselineType {
get { return this._subtitleBaselineType; }
set {
if (this._subtitleBaselineType == value) {
return;
}
this._subtitleBaselineType = value;
this.markNeedsLayout();
}
}
TextBaseline? _subtitleBaselineType;
public override void attach(object owner) {
base.attach(owner);
foreach (RenderBox child in this._children) {
child.attach(owner);
}
}
public override void detach() {
base.detach();
foreach (RenderBox child in this._children) {
child.detach();
}
}
public override void redepthChildren() {
foreach (var child in this._children) {
this.redepthChild(child);
}
}
public override void visitChildren(RenderObjectVisitor visitor) {
foreach (var child in this._children) {
visitor(child);
}
}
public override List<DiagnosticsNode> debugDescribeChildren() {
List<DiagnosticsNode> value = new List<DiagnosticsNode>();
void add(RenderBox child, string name) {
if (child != null) {
value.Add(child.toDiagnosticsNode(name: name));
}
}
add(this.leading, "leading");
add(this.title, "title");
add(this.subtitle, "subtitle");
add(this.trailing, "trailing");
return value;
}
public new bool sizedByParent {
get { return false; }
}
static float _minWidth(RenderBox box, float height) {
return box == null ? 0.0f : box.getMinIntrinsicWidth(height);
}
static float _maxWidth(RenderBox box, float height) {
return box == null ? 0.0f : box.getMaxIntrinsicWidth(height);
}
protected override float computeMinIntrinsicWidth(float height) {
float leadingWidth = this.leading != null
? Mathf.Max(this.leading.getMinIntrinsicWidth(height), _minLeadingWidth) + _horizontalTitleGap
: 0.0f;
return leadingWidth + Mathf.Max(_minWidth(this.title, height), _minWidth(this.subtitle, height)) +
_maxWidth(this.trailing, height);
}
protected override float computeMaxIntrinsicWidth(float height) {
float leadingWidth = this.leading != null
? Mathf.Max(this.leading.getMaxIntrinsicWidth(height), _minLeadingWidth) + _horizontalTitleGap
: 0.0f;
return leadingWidth + Mathf.Max(_maxWidth(this.title, height), _maxWidth(this.subtitle, height)) +
_maxWidth(this.trailing, height);
}
float _defaultTileHeight {
get {
bool hasSubtitle = this.subtitle != null;
bool isTwoLine = !this.isThreeLine && hasSubtitle;
bool isOneLine = !this.isThreeLine && !hasSubtitle;
if (isOneLine) {
return this.isDense ? 48.0f : 56.0f;
}
if (isTwoLine) {
return this.isDense ? 64.0f : 72.0f;
}
return this.isDense ? 76.0f : 88.0f;
}
}
protected override float computeMinIntrinsicHeight(float width) {
return Mathf.Max(
this._defaultTileHeight,
this.title.getMinIntrinsicHeight(width) + this.subtitle?.getMinIntrinsicHeight(width) ?? 0.0f);
}
protected override float computeMaxIntrinsicHeight(float width) {
return this.computeMinIntrinsicHeight(width);
}
protected override float? computeDistanceToActualBaseline(TextBaseline baseline) {
D.assert(this.title != null);
BoxParentData parentData = (BoxParentData) this.title.parentData;
return parentData.offset.dy + this.title.getDistanceToActualBaseline(baseline);
}
static float _boxBaseline(RenderBox box, TextBaseline baseline) {
return box.getDistanceToBaseline(baseline) ?? 0.0f;
}
static Size _layoutBox(RenderBox box, BoxConstraints constraints) {
if (box == null) {
return Size.zero;
}
box.layout(constraints, parentUsesSize: true);
return box.size;
}
static void _positionBox(RenderBox box, Offset offset) {
BoxParentData parentData = (BoxParentData) box.parentData;
parentData.offset = offset;
}
protected override void performLayout() {
bool hasLeading = this.leading != null;
bool hasSubtitle = this.subtitle != null;
bool hasTrailing = this.trailing != null;
bool isTwoLine = !this.isThreeLine && hasSubtitle;
bool isOneLine = !this.isThreeLine && !hasSubtitle;
BoxConstraints looseConstraints = this.constraints.loosen();
float tileWidth = looseConstraints.maxWidth;
Size leadingSize = _layoutBox(this.leading, looseConstraints);
Size trailingSize = _layoutBox(this.trailing, looseConstraints);
float titleStart = hasLeading
? Mathf.Max(_minLeadingWidth, leadingSize.width) + _horizontalTitleGap
: 0.0f;
BoxConstraints textConstraints = looseConstraints.tighten(
width: tileWidth - titleStart - (hasTrailing ? trailingSize.width + _horizontalTitleGap : 0.0f));
Size titleSize = _layoutBox(this.title, textConstraints);
Size subtitleSize = _layoutBox(this.subtitle, textConstraints);
float titleBaseline = 0.0f;
float subtitleBaseline = 0.0f;
if (isTwoLine) {
titleBaseline = this.isDense ? 28.0f : 32.0f;
subtitleBaseline = this.isDense ? 48.0f : 52.0f;
}
else if (this.isThreeLine) {
titleBaseline = this.isDense ? 22.0f : 28.0f;
subtitleBaseline = this.isDense ? 42.0f : 48.0f;
}
else {
D.assert(isOneLine);
}
float tileHeight = 0.0f;
float titleY = 0.0f;
float subtitleY = 0.0f;
if (!hasSubtitle) {
tileHeight = Mathf.Max(this._defaultTileHeight, titleSize.height + 2.0f * _minVerticalPadding);
titleY = (tileHeight - titleSize.height) / 2.0f;
}
else {
D.assert(this.subtitleBaselineType != null);
titleY = titleBaseline - _boxBaseline(this.title, this.titleBaselineType);
subtitleY = subtitleBaseline -
_boxBaseline(this.subtitle, this.subtitleBaselineType ?? TextBaseline.alphabetic);
tileHeight = this._defaultTileHeight;
float titleOverlap = titleY + titleSize.height - subtitleY;
if (titleOverlap > 0.0f) {
titleY -= titleOverlap / 2.0f;
subtitleY += titleOverlap / 2.0f;
}
if (titleY < _minVerticalPadding ||
(subtitleY + subtitleSize.height + _minVerticalPadding) > tileHeight) {
tileHeight = titleSize.height + subtitleSize.height + 2.0f * _minVerticalPadding;
titleY = _minVerticalPadding;
subtitleY = titleSize.height + _minVerticalPadding;
}
}
float leadingY = (tileHeight - leadingSize.height) / 2.0f;
float trailingY = (tileHeight - trailingSize.height) / 2.0f;
if (hasLeading) {
_positionBox(this.leading, new Offset(0.0f, leadingY));
}
_positionBox(this.title, new Offset(titleStart, titleY));
if (hasSubtitle) {
_positionBox(this.subtitle, new Offset(titleStart, subtitleY));
}
if (hasTrailing) {
_positionBox(this.trailing, new Offset(tileWidth - trailingSize.width, trailingY));
}
this.size = this.constraints.constrain(new Size(tileWidth, tileHeight));
D.assert(this.size.width == this.constraints.constrainWidth(tileWidth));
D.assert(this.size.height == this.constraints.constrainHeight(tileHeight));
}
public override void paint(PaintingContext context, Offset offset) {
void doPaint(RenderBox child) {
if (child != null) {
BoxParentData parentData = (BoxParentData) child.parentData;
context.paintChild(child, parentData.offset + offset);
}
}
doPaint(this.leading);
doPaint(this.title);
doPaint(this.subtitle);
doPaint(this.trailing);
}
protected override bool hitTestSelf(Offset position) {
return true;
}
protected override bool hitTestChildren(HitTestResult result, Offset position) {
D.assert(position != null);
foreach (RenderBox child in this._children) {
BoxParentData parentData = (BoxParentData) child.parentData;
if (child.hitTest(result, position: position - parentData.offset)) {
return true;
}
}
return false;
}
}
}