浏览代码

Merge branch 'master' into yczhang

/main
Yuncong Zhang 5 年前
当前提交
6f2578e2
共有 14 个文件被更改,包括 1737 次插入30 次删除
  1. 9
      Runtime/gestures/team.cs
  2. 3
      Runtime/material/animated_icons/animated_icons.cs
  3. 20
      Runtime/material/theme_data.cs
  4. 4
      Runtime/painting/notched_shapes.cs
  5. 4
      Runtime/painting/text_painter.cs
  6. 1
      Runtime/rendering/proxy_box.cs
  7. 10
      Runtime/ui/painting/canvas.cs
  8. 41
      Runtime/ui/painting/path.cs
  9. 2
      Runtime/widgets/binding.cs
  10. 39
      Samples/UIWidgetSample/MaterialSample.cs
  11. 805
      Runtime/material/slider.cs
  12. 11
      Runtime/material/slider.cs.meta
  13. 807
      Runtime/material/slider_theme.cs
  14. 11
      Runtime/material/slider_theme.cs.meta

9
Runtime/gestures/team.cs


D.assert(this._pointer == pointer);
this._members.Add(member);
this._entry = this._entry ?? this._owner._gestureArena.add(pointer, this);
this._entry = this._entry ?? GestureBinding.instance.gestureArena.add(pointer, this);
return new _CombiningGestureArenaEntry(this, member);
}

}
}
else {
D.assert(disposition == GestureDisposition.accepted);
this._winner = this._winner ?? this._owner.captain ?? member;
this._entry.resolve(disposition);
}

public class GestureArenaTeam {
public GestureArenaTeam(GestureArenaManager gestureArena) {
this._gestureArena = gestureArena;
}
internal readonly GestureArenaManager _gestureArena;
internal readonly Dictionary<int, _CombiningGestureArenaMember> _combiners =
new Dictionary<int, _CombiningGestureArenaMember>();

3
Runtime/material/animated_icons/animated_icons.cs


Offset controlPoint1 = AnimatedIconUtils._interpolate<Offset>(this.controlPoints1, progress, Offset.lerp);
Offset controlPoint2 = AnimatedIconUtils._interpolate<Offset>(this.controlPoints2, progress, Offset.lerp);
Offset targetPoint = AnimatedIconUtils._interpolate<Offset>(this.targetPoints, progress, Offset.lerp);
// TODO: replace with cubicTo
path.bezierTo(
path.cubicTo(
controlPoint1.dx, controlPoint1.dy,
controlPoint2.dx, controlPoint2.dy,
targetPoint.dx, targetPoint.dy

20
Runtime/material/theme_data.cs


IconThemeData iconTheme = null,
IconThemeData primaryIconTheme = null,
IconThemeData accentIconTheme = null,
SliderThemeData sliderTheme = null,
TabBarTheme tabBarTheme = null,
CardTheme cardTheme = null,
ChipThemeData chipTheme = null,

? ThemeDataUtils._kDarkThemeSplashColor
: ThemeDataUtils._kLightThemeSplashColor);
sliderTheme = sliderTheme ?? SliderThemeData.fromPrimaryColors(
primaryColor: primaryColor,
primaryColorLight: primaryColorLight,
primaryColorDark: primaryColorDark,
valueIndicatorTextStyle: accentTextTheme.body2);
tabBarTheme = tabBarTheme ?? new TabBarTheme();
cardTheme = cardTheme ?? new CardTheme();
chipTheme = chipTheme ?? ChipThemeData.fromDefaults(

D.assert(textTheme != null);
D.assert(primaryTextTheme != null);
D.assert(accentTextTheme != null);
D.assert(sliderTheme != null);
D.assert(iconTheme != null);
D.assert(primaryIconTheme != null);
D.assert(accentIconTheme != null);

this.iconTheme = iconTheme;
this.primaryIconTheme = primaryIconTheme;
this.accentIconTheme = accentIconTheme;
this.sliderTheme = sliderTheme;
this.tabBarTheme = tabBarTheme;
this.cardTheme = cardTheme;
this.chipTheme = chipTheme;

TextTheme textTheme = null,
TextTheme primaryTextTheme = null,
TextTheme accentTextTheme = null,
SliderThemeData sliderTheme = null,
InputDecorationTheme inputDecorationTheme = null,
IconThemeData iconTheme = null,
IconThemeData primaryIconTheme = null,

D.assert(textTheme != null);
D.assert(primaryTextTheme != null);
D.assert(accentTextTheme != null);
D.assert(sliderTheme != null);
D.assert(inputDecorationTheme != null);
D.assert(iconTheme != null);
D.assert(primaryIconTheme != null);

iconTheme: iconTheme,
primaryIconTheme: primaryIconTheme,
accentIconTheme: accentIconTheme,
sliderTheme: sliderTheme,
tabBarTheme: tabBarTheme,
cardTheme: cardTheme,
chipTheme: chipTheme,

public readonly TextTheme accentTextTheme;
public readonly SliderThemeData sliderTheme;
public readonly InputDecorationTheme inputDecorationTheme;
public readonly IconThemeData iconTheme;

TextTheme textTheme = null,
TextTheme primaryTextTheme = null,
TextTheme accentTextTheme = null,
SliderThemeData sliderTheme = null,
InputDecorationTheme inputDecorationTheme = null,
IconThemeData iconTheme = null,
IconThemeData primaryIconTheme = null,

textTheme: textTheme ?? this.textTheme,
primaryTextTheme: primaryTextTheme ?? this.primaryTextTheme,
accentTextTheme: accentTextTheme ?? this.accentTextTheme,
sliderTheme: sliderTheme ?? this.sliderTheme,
inputDecorationTheme: this.inputDecorationTheme ?? this.inputDecorationTheme,
iconTheme: iconTheme ?? this.iconTheme,
primaryIconTheme: primaryIconTheme ?? this.primaryIconTheme,

iconTheme: IconThemeData.lerp(a.iconTheme, b.iconTheme, t),
primaryIconTheme: IconThemeData.lerp(a.primaryIconTheme, b.primaryIconTheme, t),
accentIconTheme: IconThemeData.lerp(a.accentIconTheme, b.accentIconTheme, t),
sliderTheme: SliderThemeData.lerp(a.sliderTheme, b.sliderTheme, t),
tabBarTheme: TabBarTheme.lerp(a.tabBarTheme, b.tabBarTheme, t),
cardTheme: CardTheme.lerp(a.cardTheme, b.cardTheme, t),
chipTheme: ChipThemeData.lerp(a.chipTheme, b.chipTheme, t),

other.textTheme == this.textTheme &&
other.primaryTextTheme == this.primaryTextTheme &&
other.accentTextTheme == this.accentTextTheme &&
other.sliderTheme == this.sliderTheme &&
other.inputDecorationTheme == this.inputDecorationTheme &&
other.toggleableActiveColor == this.toggleableActiveColor &&
other.iconTheme == this.iconTheme &&

hashCode = (hashCode * 397) ^ this.iconTheme.GetHashCode();
hashCode = (hashCode * 397) ^ this.primaryIconTheme.GetHashCode();
hashCode = (hashCode * 397) ^ this.accentIconTheme.GetHashCode();
hashCode = (hashCode * 397) ^ this.sliderTheme.GetHashCode();
hashCode = (hashCode * 397) ^ this.tabBarTheme.GetHashCode();
hashCode = (hashCode * 397) ^ this.cardTheme.GetHashCode();
hashCode = (hashCode * 397) ^ this.chipTheme.GetHashCode();

properties.add(new DiagnosticsProperty<IconThemeData>("iconTheme", this.iconTheme));
properties.add(new DiagnosticsProperty<IconThemeData>("primaryIconTheme", this.primaryIconTheme));
properties.add(new DiagnosticsProperty<IconThemeData>("accentIconTheme", this.accentIconTheme));
properties.add(new DiagnosticsProperty<SliderThemeData>("sliderTheme", this.sliderTheme));
properties.add(new DiagnosticsProperty<TabBarTheme>("tabBarTheme", this.tabBarTheme));
properties.add(new DiagnosticsProperty<CardTheme>("cardTheme", this.cardTheme));
properties.add(new DiagnosticsProperty<ChipThemeData>("chipTheme", this.chipTheme));

4
Runtime/painting/notched_shapes.cs


Path ret = new Path();
ret.moveTo(host.left, host.top);
ret.lineTo(p[0].dx, p[0].dy);
ret.quadTo(p[1].dx, p[1].dy, p[2].dx, p[2].dy);
ret.quadraticBezierTo(p[1].dx, p[1].dy, p[2].dx, p[2].dy);
ret.quadTo(p[4].dx, p[4].dy, p[5].dx, p[5].dy);
ret.quadraticBezierTo(p[4].dx, p[4].dy, p[5].dx, p[5].dy);
ret.lineTo(host.right, host.top);
ret.lineTo(host.right, host.bottom);
ret.lineTo(host.left, host.bottom);

4
Runtime/painting/text_painter.cs


float _lastMinWidth;
float _lastMaxWidth;
public TextPainter(TextSpan text,
public TextPainter(TextSpan text = null,
TextAlign textAlign = TextAlign.left,
TextDirection textDirection = TextDirection.ltr,
float textScaleFactor = 1.0f,

public TextSpan text {
get { return this._text; }
set {
if (this.text.Equals(value)) {
if ((this._text == null && value == null) || (this._text != null && this.text.Equals(value))) {
return;
}

1
Runtime/rendering/proxy_box.cs


this._updateClip();
context.pushClipPath(this.needsCompositing, offset, Offset.zero & this.size,
this._clip, base.paint, clipBehavior: this.clipBehavior);
base.paint(context, offset);
}
}

10
Runtime/ui/painting/canvas.cs


bool forceMoveTo = !useCenter;
while (sweepAngle <= -Mathf.PI * 2) {
path.addArc(rect, startAngle, -Mathf.PI, forceMoveTo);
path.arcTo(rect, startAngle, -Mathf.PI, forceMoveTo);
path.addArc(rect, startAngle, -Mathf.PI, false);
path.arcTo(rect, startAngle, -Mathf.PI, false);
startAngle -= Mathf.PI;
forceMoveTo = false;
sweepAngle += Mathf.PI * 2;

path.addArc(rect, startAngle, Mathf.PI, forceMoveTo);
path.arcTo(rect, startAngle, Mathf.PI, forceMoveTo);
path.addArc(rect, startAngle, Mathf.PI, false);
path.arcTo(rect, startAngle, Mathf.PI, false);
path.addArc(rect, startAngle, sweepAngle, forceMoveTo);
path.arcTo(rect, startAngle, sweepAngle, forceMoveTo);
if (useCenter) {
path.close();
}

41
Runtime/ui/painting/path.cs


x + x0, y + y0,
});
}
}
}
public void relativeLineTo(float x, float y) {
var x0 = this._commandx;
var y0 = this._commandy;
this._appendCommands(new[] {
(float) PathCommand.lineTo,
x + x0, y + y0,
});
}
public void lineTo(float x, float y) {
this._appendCommands(new[] {
(float) PathCommand.lineTo,

public void bezierTo(float c1x, float c1y, float c2x, float c2y, float x, float y) {
public void cubicTo(float c1x, float c1y, float c2x, float c2y, float x, float y) {
public void relativeCubicTo(float c1x, float c1y, float c2x, float c2y, float x, float y) {
var x0 = this._commandx;
var y0 = this._commandy;
this.cubicTo(x0 + c1x, y0 + c1y, x0 + c2x, y0 + c2y, x0 + x, y0 + y);
}
public void quadTo(float cx, float cy, float x, float y) {
public void quadraticBezierTo(float cx, float cy, float x, float y) {
var x0 = this._commandx;
var y0 = this._commandy;

(x + 2.0f / 3.0f * (cx - x)), (y + 2.0f / 3.0f * (cy - y)),
x, y,
});
}
public void relativeQuadraticBezierTo(float cx, float cy, float x, float y) {
var x0 = this._commandx;
var y0 = this._commandy;
this.quadraticBezierTo(x0 + cx, y0 + cy, x0 + x, y0 + y);
}
public void close() {

this.addArc(cx, cy, radius, a0, a1, dir);
}
public void addArc(Rect rect, float startAngle, float sweepAngle, bool forceMoveTo = true) {
public void arcTo(Rect rect, float startAngle, float sweepAngle, bool forceMoveTo = true) {
var mat = Matrix3.makeScale(rect.width / 2, rect.height / 2);
var center = rect.center;
mat.postTranslate(center.dx, center.dy);

this._transformCommands(vals, mat);
this._appendCommands(vals.ToArray());
}
public void addArc(Rect rect, float startAngle, float sweepAngle) {
this.arcTo(rect, startAngle, sweepAngle, true);
}
public Path transform(Matrix3 mat) {

var res1 = mat.mapXY(this._commands[i + 1], this._commands[i + 2]);
var res2 = mat.mapXY(this._commands[i + 3], this._commands[i + 4]);
var res3 = mat.mapXY(this._commands[i + 5], this._commands[i + 6]);
ret.bezierTo(res1.dx, res1.dy, res2.dx, res2.dy, res3.dx, res3.dy);
ret.cubicTo(res1.dx, res1.dy, res2.dx, res2.dy, res3.dx, res3.dy);
i += 7;
break;
case PathCommand.close:

2
Runtime/widgets/binding.cs


Application.Quit();
return;
}
this._observers[idx].didPopRoute().Then(_handlePopRouteSub);
this._observers[idx].didPopRoute().Then((Action<bool>) _handlePopRouteSub);
}
}

39
Samples/UIWidgetSample/MaterialSample.cs


namespace UIWidgetsSample {
public class MaterialSample : UIWidgetsSamplePanel {
int testCaseId = 2;
const int testCaseId = 6;
List<Widget> testCases = new List<Widget> {
readonly List<Widget> testCases = new List<Widget> {
new BottomAppBarWidget()
new BottomAppBarWidget(),
new MaterialSliderWidget()
home: this.testCases[this.testCaseId]);
home: this.testCases[testCaseId]);
}
protected override void OnEnable() {

),
new PerformanceOverlay()
}
);
}
}
public class MaterialSliderWidget : StatefulWidget {
public override State createState() {
return new MaterialSliderState();
}
}
public class MaterialSliderState : State<MaterialSliderWidget> {
float _value = 0.0f;
void onChanged(float value) {
this.setState(() => { this._value = value; });
}
public override Widget build(BuildContext context) {
return new Scaffold(
appBar: new AppBar(
title: new Text("Slider and Indicators")),
body: new Column(
children : new List<Widget> {
new Container(
child: new Slider(
value: this._value,
onChanged: this.onChanged))
}
)
);
}
}

805
Runtime/material/slider.cs


using System;
using Unity.UIWidgets.animation;
using Unity.UIWidgets.async;
using Unity.UIWidgets.foundation;
using Unity.UIWidgets.gestures;
using Unity.UIWidgets.painting;
using Unity.UIWidgets.rendering;
using Unity.UIWidgets.scheduler;
using Unity.UIWidgets.ui;
using Unity.UIWidgets.widgets;
using UnityEngine;
using Canvas = Unity.UIWidgets.ui.Canvas;
using Color = Unity.UIWidgets.ui.Color;
using Rect = Unity.UIWidgets.ui.Rect;
namespace Unity.UIWidgets.material {
public class Slider : StatefulWidget {
public Slider(
Key key = null,
float? value = null,
ValueChanged<float> onChanged = null,
ValueChanged<float> onChangeStart = null,
ValueChanged<float> onChangeEnd = null,
float min = 0.0f,
float max = 1.0f,
int? divisions = null,
string label = null,
Color activeColor = null,
Color inactiveColor = null
) : base(key: key) {
D.assert(value != null);
D.assert(min <= max);
D.assert(value >= min && value <= max);
D.assert(divisions == null || divisions > 0);
this.value = value.Value;
this.onChanged = onChanged;
this.onChangeStart = onChangeStart;
this.onChangeEnd = onChangeEnd;
this.min = min;
this.max = max;
this.divisions = divisions;
this.label = label;
this.activeColor = activeColor;
this.inactiveColor = inactiveColor;
}
public readonly float value;
public readonly ValueChanged<float> onChanged;
public readonly ValueChanged<float> onChangeStart;
public readonly ValueChanged<float> onChangeEnd;
public readonly float min;
public readonly float max;
public readonly int? divisions;
public readonly string label;
public readonly Color activeColor;
public readonly Color inactiveColor;
public override State createState() {
return new _SliderState();
}
public override void debugFillProperties(DiagnosticPropertiesBuilder properties) {
base.debugFillProperties(properties);
properties.add(new FloatProperty("value", this.value));
properties.add(new FloatProperty("min", this.min));
properties.add(new FloatProperty("max", this.max));
}
}
class _SliderState : TickerProviderStateMixin<Slider> {
static TimeSpan enableAnimationDuration = new TimeSpan(0, 0, 0, 0, 75);
static TimeSpan valueIndicatorAnimationDuration = new TimeSpan(0, 0, 0, 0, 100);
public AnimationController overlayController;
public AnimationController valueIndicatorController;
public AnimationController enableController;
public AnimationController positionController;
public Timer interactionTimer;
public override void initState() {
base.initState();
this.overlayController = new AnimationController(
duration: Constants.kRadialReactionDuration,
vsync: this
);
this.valueIndicatorController = new AnimationController(
duration: valueIndicatorAnimationDuration,
vsync: this
);
this.enableController = new AnimationController(
duration: enableAnimationDuration,
vsync: this
);
this.positionController = new AnimationController(
duration: TimeSpan.Zero,
vsync: this
);
this.enableController.setValue(this.widget.onChanged != null ? 1.0f : 0.0f);
this.positionController.setValue(this._unlerp(this.widget.value));
}
public override void dispose() {
this.interactionTimer?.cancel();
this.overlayController.dispose();
this.valueIndicatorController.dispose();
this.enableController.dispose();
this.positionController.dispose();
base.dispose();
}
void _handleChanged(float value) {
D.assert(this.widget.onChanged != null);
float lerpValue = this._lerp(value);
if (lerpValue != this.widget.value) {
this.widget.onChanged(lerpValue);
}
}
void _handleDragStart(float value) {
D.assert(this.widget.onChangeStart != null);
this.widget.onChangeStart(this._lerp(value));
}
void _handleDragEnd(float value) {
D.assert(this.widget.onChangeEnd != null);
this.widget.onChangeEnd(this._lerp(value));
}
float _lerp(float value) {
D.assert(value >= 0.0f);
D.assert(value <= 1.0f);
return value * (this.widget.max - this.widget.min) + this.widget.min;
}
float _unlerp(float value) {
D.assert(value <= this.widget.max);
D.assert(value >= this.widget.min);
return this.widget.max > this.widget.min
? (value - this.widget.min) / (this.widget.max - this.widget.min)
: 0.0f;
}
public override Widget build(BuildContext context) {
D.assert(MaterialD.debugCheckHasMaterial(context));
D.assert(WidgetsD.debugCheckHasMediaQuery(context));
SliderThemeData sliderTheme = SliderTheme.of(context);
if (this.widget.activeColor != null || this.widget.inactiveColor != null) {
sliderTheme = sliderTheme.copyWith(
activeTrackColor: this.widget.activeColor,
inactiveTrackColor: this.widget.inactiveColor,
activeTickMarkColor: this.widget.inactiveColor,
inactiveTickMarkColor: this.widget.activeColor,
thumbColor: this.widget.activeColor,
valueIndicatorColor: this.widget.activeColor,
overlayColor: this.widget.activeColor?.withAlpha(0x29)
);
}
return new _SliderRenderObjectWidget(
value: this._unlerp(this.widget.value),
divisions: this.widget.divisions,
label: this.widget.label,
sliderTheme: sliderTheme,
mediaQueryData: MediaQuery.of(context),
onChanged: (this.widget.onChanged != null) && (this.widget.max > this.widget.min)
? this._handleChanged
: (ValueChanged<float>) null,
onChangeStart: this.widget.onChangeStart != null ? this._handleDragStart : (ValueChanged<float>) null,
onChangeEnd: this.widget.onChangeEnd != null ? this._handleDragEnd : (ValueChanged<float>) null,
state: this
);
}
}
class _SliderRenderObjectWidget : LeafRenderObjectWidget {
public _SliderRenderObjectWidget(
Key key = null,
float? value = null,
int? divisions = null,
string label = null,
SliderThemeData sliderTheme = null,
MediaQueryData mediaQueryData = null,
ValueChanged<float> onChanged = null,
ValueChanged<float> onChangeStart = null,
ValueChanged<float> onChangeEnd = null,
_SliderState state = null
) : base(key: key) {
this.value = value.Value;
this.divisions = divisions;
this.label = label;
this.sliderTheme = sliderTheme;
this.mediaQueryData = mediaQueryData;
this.onChanged = onChanged;
this.onChangeStart = onChangeStart;
this.onChangeEnd = onChangeEnd;
this.state = state;
}
public readonly float value;
public readonly int? divisions;
public readonly string label;
public readonly SliderThemeData sliderTheme;
public readonly MediaQueryData mediaQueryData;
public readonly ValueChanged<float> onChanged;
public readonly ValueChanged<float> onChangeStart;
public readonly ValueChanged<float> onChangeEnd;
public readonly _SliderState state;
public override RenderObject createRenderObject(BuildContext context) {
return new _RenderSlider(
value: this.value,
divisions: this.divisions,
label: this.label,
sliderTheme: this.sliderTheme,
theme: Theme.of(context),
mediaQueryData: this.mediaQueryData,
onChanged: this.onChanged,
onChangeStart: this.onChangeStart,
onChangeEnd: this.onChangeEnd,
state: this.state,
platform: Theme.of(context).platform
);
}
public override void updateRenderObject(BuildContext context, RenderObject renderObject) {
_RenderSlider _renderObject = (_RenderSlider) renderObject;
_renderObject.value = this.value;
_renderObject.divisions = this.divisions;
_renderObject.label = this.label;
_renderObject.sliderTheme = this.sliderTheme;
_renderObject.theme = Theme.of(context);
_renderObject.mediaQueryData = this.mediaQueryData;
_renderObject.onChanged = this.onChanged;
_renderObject.onChangeStart = this.onChangeStart;
_renderObject.onChangeEnd = this.onChangeEnd;
_renderObject.platform = Theme.of(context).platform;
}
}
class _RenderSlider : RenderBox {
public _RenderSlider(
float? value = null,
int? divisions = null,
string label = null,
SliderThemeData sliderTheme = null,
ThemeData theme = null,
MediaQueryData mediaQueryData = null,
RuntimePlatform? platform = null,
ValueChanged<float> onChanged = null,
ValueChanged<float> onChangeStart = null,
ValueChanged<float> onChangeEnd = null,
_SliderState state = null
) {
D.assert(value != null && value >= 0.0 && value <= 1.0);
D.assert(state != null);
this.onChangeStart = onChangeStart;
this.onChangeEnd = onChangeEnd;
this._platform = platform;
this._label = label;
this._value = value.Value;
this._divisions = divisions;
this._sliderTheme = sliderTheme;
this._theme = theme;
this._mediaQueryData = mediaQueryData;
this._onChanged = onChanged;
this._state = state;
this._updateLabelPainter();
GestureArenaTeam team = new GestureArenaTeam();
this._drag = new HorizontalDragGestureRecognizer {
team = team,
onStart = this._handleDragStart,
onUpdate = this._handleDragUpdate,
onEnd = this._handleDragEnd,
onCancel = this._endInteraction
};
this._tap = new TapGestureRecognizer {
team = team,
onTapDown = this._handleTapDown,
onTapUp = this._handleTapUp,
onTapCancel = this._endInteraction
};
this._overlayAnimation = new CurvedAnimation(
parent: this._state.overlayController,
curve: Curves.fastOutSlowIn);
this._valueIndicatorAnimation = new CurvedAnimation(
parent: this._state.valueIndicatorController,
curve: Curves.fastOutSlowIn);
this._enableAnimation = new CurvedAnimation(
parent: this._state.enableController,
curve: Curves.easeInOut);
}
const float _positionAnimationDurationMilliSeconds = 75;
const float _overlayRadius = 16.0f;
const float _overlayDiameter = _overlayRadius * 2.0f;
const float _trackHeight = 2.0f;
const float _preferredTrackWidth = 144.0f;
const float _preferredTotalWidth = _preferredTrackWidth + _overlayDiameter;
const float _minimumInteractionTimeMilliSeconds = 500;
static readonly Animatable<float> _overlayRadiusTween = new FloatTween(begin: 0.0f, end: _overlayRadius);
_SliderState _state;
Animation<float> _overlayAnimation;
Animation<float> _valueIndicatorAnimation;
Animation<float> _enableAnimation;
TextPainter _labelPainter = new TextPainter();
HorizontalDragGestureRecognizer _drag;
TapGestureRecognizer _tap;
bool _active = false;
float _currentDragValue = 0.0f;
float _trackLength {
get { return this.size.width - _overlayDiameter; }
}
bool isInteractive {
get { return this.onChanged != null; }
}
bool isDiscrete {
get { return this.divisions != null && this.divisions.Value > 0; }
}
public float value {
get { return this._value; }
set {
D.assert(value != null && value >= 0.0f && value <= 1.0f);
float convertedValue = this.isDiscrete ? this._discretize(value) : value;
if (convertedValue == this._value) {
return;
}
this._value = convertedValue;
if (this.isDiscrete) {
float distance = (this._value - this._state.positionController.value).abs();
this._state.positionController.duration = distance != 0.0f
? new TimeSpan(0, 0, 0, 0, (int) (_positionAnimationDurationMilliSeconds * (1.0f / distance)))
: TimeSpan.Zero;
this._state.positionController.animateTo(convertedValue, curve: Curves.easeInOut);
}
else {
this._state.positionController.setValue(convertedValue);
}
}
}
float _value;
public RuntimePlatform? platform {
get { return this._platform; }
set {
if (this._platform == value) {
return;
}
this._platform = value;
}
}
RuntimePlatform? _platform;
public int? divisions {
get { return this._divisions; }
set {
if (value == this._divisions) {
return;
}
this._divisions = value;
this.markNeedsPaint();
}
}
int? _divisions;
public string label {
get { return this._label; }
set {
if (value == this._label) {
return;
}
this._label = value;
this._updateLabelPainter();
}
}
string _label;
public SliderThemeData sliderTheme {
get { return this._sliderTheme; }
set {
if (value == this._sliderTheme) {
return;
}
this._sliderTheme = value;
this.markNeedsPaint();
}
}
SliderThemeData _sliderTheme;
public ThemeData theme {
get { return this._theme; }
set {
if (value == this._theme) {
return;
}
this._theme = value;
this.markNeedsPaint();
}
}
ThemeData _theme;
public MediaQueryData mediaQueryData {
get { return this._mediaQueryData; }
set {
if (value == this._mediaQueryData) {
return;
}
this._mediaQueryData = value;
this._updateLabelPainter();
}
}
MediaQueryData _mediaQueryData;
public ValueChanged<float> onChanged {
get { return this._onChanged; }
set {
if (value == this._onChanged) {
return;
}
bool wasInteractive = this.isInteractive;
this._onChanged = value;
if (wasInteractive != this.isInteractive) {
if (this.isInteractive) {
this._state.enableController.forward();
}
else {
this._state.enableController.reverse();
}
this.markNeedsPaint();
}
}
}
ValueChanged<float> _onChanged;
public ValueChanged<float> onChangeStart;
public ValueChanged<float> onChangeEnd;
public bool showValueIndicator {
get {
bool showValueIndicator = false;
switch (this._sliderTheme.showValueIndicator) {
case ShowValueIndicator.onlyForDiscrete:
showValueIndicator = this.isDiscrete;
break;
case ShowValueIndicator.onlyForContinuous:
showValueIndicator = !this.isDiscrete;
break;
case ShowValueIndicator.always:
showValueIndicator = true;
break;
case ShowValueIndicator.never:
showValueIndicator = false;
break;
}
return showValueIndicator;
}
}
float _adjustmentUnit {
get {
switch (this._platform) {
case RuntimePlatform.IPhonePlayer:
return 0.1f;
default:
return 0.05f;
}
}
}
void _updateLabelPainter() {
if (this.label != null) {
this._labelPainter.text = new TextSpan(
style: this._sliderTheme.valueIndicatorTextStyle,
text: this.label
);
this._labelPainter.textScaleFactor = this._mediaQueryData.textScaleFactor;
this._labelPainter.layout();
}
else {
this._labelPainter.text = null;
}
this.markNeedsLayout();
}
public override void attach(object owner) {
base.attach(owner);
this._overlayAnimation.addListener(this.markNeedsPaint);
this._valueIndicatorAnimation.addListener(this.markNeedsPaint);
this._enableAnimation.addListener(this.markNeedsPaint);
this._state.positionController.addListener(this.markNeedsPaint);
}
public override void detach() {
this._overlayAnimation.removeListener(this.markNeedsPaint);
this._valueIndicatorAnimation.removeListener(this.markNeedsPaint);
this._enableAnimation.removeListener(this.markNeedsPaint);
this._state.positionController.removeListener(this.markNeedsPaint);
base.detach();
}
float _getValueFromVisualPosition(float visualPosition) {
return visualPosition;
}
float _getValueFromGlobalPosition(Offset globalPosition) {
float visualPosition =
(this.globalToLocal(globalPosition).dx - _overlayRadius) / this._trackLength;
return this._getValueFromVisualPosition(visualPosition);
}
float _discretize(float value) {
float result = value.clamp(0.0f, 1.0f);
if (this.isDiscrete) {
result = (result * this.divisions.Value).round() / this.divisions.Value;
}
return result;
}
void _startInteraction(Offset globalPosition) {
if (this.isInteractive) {
this._active = true;
if (this.onChangeStart != null) {
this.onChangeStart(this._discretize(this.value));
}
this._currentDragValue = this._getValueFromGlobalPosition(globalPosition);
this.onChanged(this._discretize(this._currentDragValue));
this._state.overlayController.forward();
if (this.showValueIndicator) {
this._state.valueIndicatorController.forward();
this._state.interactionTimer?.cancel();
this._state.interactionTimer = Window.instance.run(
new TimeSpan(0, 0, 0, 0,
(int) (_minimumInteractionTimeMilliSeconds * SchedulerBinding.instance.timeDilation)),
() => {
this._state.interactionTimer = null;
if (!this._active &&
this._state.valueIndicatorController.status == AnimationStatus.completed) {
this._state.valueIndicatorController.reverse();
}
});
}
}
}
void _endInteraction() {
if (this._active && this._state.mounted) {
if (this.onChangeEnd != null) {
this.onChangeEnd(this._discretize(this._currentDragValue));
}
this._active = false;
this._currentDragValue = 0.0f;
this._state.overlayController.reverse();
if (this.showValueIndicator && this._state.interactionTimer == null) {
this._state.valueIndicatorController.reverse();
}
}
}
void _handleDragStart(DragStartDetails details) {
this._startInteraction(details.globalPosition);
}
void _handleDragUpdate(DragUpdateDetails details) {
if (this.isInteractive) {
float valueDelta = details.primaryDelta.Value / this._trackLength;
this._currentDragValue += valueDelta;
this.onChanged(this._discretize(this._currentDragValue));
}
}
void _handleDragEnd(DragEndDetails details) {
this._endInteraction();
}
void _handleTapDown(TapDownDetails details) {
this._startInteraction(details.globalPosition);
}
void _handleTapUp(TapUpDetails details) {
this._endInteraction();
}
protected override bool hitTestSelf(Offset position) {
return true;
}
public override void handleEvent(PointerEvent evt, HitTestEntry entry) {
D.assert(this.debugHandleEvent(evt, entry));
if (evt is PointerDownEvent && this.isInteractive) {
this._drag.addPointer((PointerDownEvent) evt);
this._tap.addPointer((PointerDownEvent) evt);
}
}
protected override float computeMinIntrinsicWidth(float height) {
return Mathf.Max(_overlayDiameter,
this._sliderTheme.thumbShape.getPreferredSize(this.isInteractive, this.isDiscrete).width);
}
protected override float computeMaxIntrinsicWidth(float height) {
return _preferredTotalWidth;
}
protected override float computeMinIntrinsicHeight(float width) {
return _overlayDiameter;
}
protected override float computeMaxIntrinsicHeight(float width) {
return _overlayDiameter;
}
protected override bool sizedByParent {
get { return true; }
}
protected override void performResize() {
this.size = new Size(
this.constraints.hasBoundedWidth
? this.constraints.maxWidth
: _preferredTotalWidth,
this.constraints.hasBoundedHeight
? this.constraints.maxHeight
: _overlayDiameter
);
}
void _paintTickMarks(
Canvas canvas,
Rect trackLeft,
Rect trackRight,
Paint leftPaint,
Paint rightPaint) {
if (this.isDiscrete) {
const float tickRadius = _trackHeight / 2.0f;
float trackWidth = trackRight.right - trackLeft.left;
float dx = (trackWidth - _trackHeight) / this.divisions.Value;
if (dx >= 3.0 * _trackHeight) {
for (int i = 0; i <= this.divisions.Value; i += 1) {
float left = trackLeft.left + i * dx;
Offset center = new Offset(left + tickRadius, trackLeft.top + tickRadius);
if (trackLeft.contains(center)) {
canvas.drawCircle(center, tickRadius, leftPaint);
}
else if (trackRight.contains(center)) {
canvas.drawCircle(center, tickRadius, rightPaint);
}
}
}
}
}
void _paintOverlay(
Canvas canvas,
Offset center) {
Paint overlayPaint = new Paint {color = this._sliderTheme.overlayColor};
float radius = _overlayRadiusTween.evaluate(this._overlayAnimation);
canvas.drawCircle(center, radius, overlayPaint);
}
public override void paint(PaintingContext context, Offset offset) {
Canvas canvas = context.canvas;
float trackLength = this.size.width - 2 * _overlayRadius;
float value = this._state.positionController.value;
ColorTween activeTrackEnableColor = new ColorTween(begin: this._sliderTheme.disabledActiveTrackColor,
end: this._sliderTheme.activeTrackColor);
ColorTween inactiveTrackEnableColor = new ColorTween(begin: this._sliderTheme.disabledInactiveTrackColor,
end: this._sliderTheme.inactiveTrackColor);
ColorTween activeTickMarkEnableColor = new ColorTween(begin: this._sliderTheme.disabledActiveTickMarkColor,
end: this._sliderTheme.activeTickMarkColor);
ColorTween inactiveTickMarkEnableColor =
new ColorTween(begin: this._sliderTheme.disabledInactiveTickMarkColor,
end: this._sliderTheme.inactiveTickMarkColor);
Paint activeTrackPaint = new Paint {color = activeTrackEnableColor.evaluate(this._enableAnimation)};
Paint inactiveTrackPaint = new Paint {color = inactiveTrackEnableColor.evaluate(this._enableAnimation)};
Paint activeTickMarkPaint = new Paint {color = activeTickMarkEnableColor.evaluate(this._enableAnimation)};
Paint inactiveTickMarkPaint = new Paint
{color = inactiveTickMarkEnableColor.evaluate(this._enableAnimation)};
float visualPosition = value;
Paint leftTrackPaint = activeTrackPaint;
Paint rightTrackPaint = inactiveTrackPaint;
Paint leftTickMarkPaint = activeTickMarkPaint;
Paint rightTickMarkPaint = inactiveTickMarkPaint;
float trackRadius = _trackHeight / 2.0f;
float thumbGap = 2.0f;
float trackVerticalCenter = offset.dy + (this.size.height) / 2.0f;
float trackLeft = offset.dx + _overlayRadius;
float trackTop = trackVerticalCenter - trackRadius;
float trackBottom = trackVerticalCenter + trackRadius;
float trackRight = trackLeft + trackLength;
float trackActive = trackLeft + trackLength * visualPosition;
float thumbRadius =
this._sliderTheme.thumbShape.getPreferredSize(this.isInteractive, this.isDiscrete).width / 2.0f;
float trackActiveLeft = Mathf.Max(0.0f,
trackActive - thumbRadius - thumbGap * (1.0f - this._enableAnimation.value));
float trackActiveRight =
Mathf.Min(trackActive + thumbRadius + thumbGap * (1.0f - this._enableAnimation.value), trackRight);
Rect trackLeftRect = Rect.fromLTRB(trackLeft, trackTop, trackActiveLeft, trackBottom);
Rect trackRightRect = Rect.fromLTRB(trackActiveRight, trackTop, trackRight, trackBottom);
Offset thumbCenter = new Offset(trackActive, trackVerticalCenter);
if (visualPosition > 0.0) {
canvas.drawRect(trackLeftRect, leftTrackPaint);
}
if (visualPosition < 1.0) {
canvas.drawRect(trackRightRect, rightTrackPaint);
}
this._paintOverlay(canvas, thumbCenter);
this._paintTickMarks(
canvas,
trackLeftRect,
trackRightRect,
leftTickMarkPaint,
rightTickMarkPaint
);
if (this.isInteractive && this.label != null &&
this._valueIndicatorAnimation.status != AnimationStatus.dismissed) {
if (this.showValueIndicator) {
this._sliderTheme.valueIndicatorShape.paint(
context,
thumbCenter,
activationAnimation: this._valueIndicatorAnimation,
enableAnimation: this._enableAnimation,
isDiscrete: this.isDiscrete,
labelPainter: this._labelPainter,
parentBox: this,
sliderTheme: this._sliderTheme,
value: this._value
);
}
}
this._sliderTheme.thumbShape.paint(
context,
thumbCenter,
activationAnimation: this._valueIndicatorAnimation,
enableAnimation: this._enableAnimation,
isDiscrete: this.isDiscrete,
labelPainter: this._labelPainter,
parentBox: this,
sliderTheme: this._sliderTheme,
value: this._value
);
}
}
}

11
Runtime/material/slider.cs.meta


fileFormatVersion: 2
guid: 99da8b1c2d9074a1781711f773197af1
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

807
Runtime/material/slider_theme.cs


using Unity.UIWidgets.animation;
using Unity.UIWidgets.foundation;
using Unity.UIWidgets.painting;
using Unity.UIWidgets.rendering;
using Unity.UIWidgets.ui;
using Unity.UIWidgets.widgets;
using UnityEngine;
using Canvas = Unity.UIWidgets.ui.Canvas;
using Color = Unity.UIWidgets.ui.Color;
using Rect = Unity.UIWidgets.ui.Rect;
using TextStyle = Unity.UIWidgets.painting.TextStyle;
namespace Unity.UIWidgets.material {
public class SliderTheme : InheritedWidget {
public SliderTheme(
Key key = null,
SliderThemeData data = null,
Widget child = null)
: base(key: key, child: child) {
D.assert(child != null);
D.assert(data != null);
this.data = data;
}
public readonly SliderThemeData data;
public static SliderThemeData of(BuildContext context) {
SliderTheme inheritedTheme = (SliderTheme) context.inheritFromWidgetOfExactType(typeof(SliderTheme));
return inheritedTheme != null ? inheritedTheme.data : Theme.of(context).sliderTheme;
}
public override bool updateShouldNotify(InheritedWidget oldWidget) {
SliderTheme _oldWidget = (SliderTheme) oldWidget;
return this.data != _oldWidget.data;
}
}
public enum ShowValueIndicator {
onlyForDiscrete,
onlyForContinuous,
always,
never
}
public class SliderThemeData : Diagnosticable {
public SliderThemeData(
Color activeTrackColor = null,
Color inactiveTrackColor = null,
Color disabledActiveTrackColor = null,
Color disabledInactiveTrackColor = null,
Color activeTickMarkColor = null,
Color inactiveTickMarkColor = null,
Color disabledActiveTickMarkColor = null,
Color disabledInactiveTickMarkColor = null,
Color thumbColor = null,
Color disabledThumbColor = null,
Color overlayColor = null,
Color valueIndicatorColor = null,
SliderComponentShape thumbShape = null,
SliderComponentShape valueIndicatorShape = null,
ShowValueIndicator? showValueIndicator = null,
TextStyle valueIndicatorTextStyle = null
) {
D.assert(activeTrackColor != null);
D.assert(inactiveTrackColor != null);
D.assert(disabledActiveTrackColor != null);
D.assert(disabledInactiveTrackColor != null);
D.assert(activeTickMarkColor != null);
D.assert(inactiveTickMarkColor != null);
D.assert(disabledActiveTickMarkColor != null);
D.assert(disabledInactiveTickMarkColor != null);
D.assert(thumbColor != null);
D.assert(disabledThumbColor != null);
D.assert(overlayColor != null);
D.assert(valueIndicatorColor != null);
D.assert(thumbShape != null);
D.assert(valueIndicatorShape != null);
D.assert(valueIndicatorTextStyle != null);
D.assert(showValueIndicator != null);
this.activeTrackColor = activeTrackColor;
this.inactiveTrackColor = inactiveTrackColor;
this.disabledActiveTrackColor = disabledActiveTrackColor;
this.disabledInactiveTrackColor = disabledInactiveTrackColor;
this.activeTickMarkColor = activeTickMarkColor;
this.inactiveTickMarkColor = inactiveTickMarkColor;
this.disabledActiveTickMarkColor = disabledActiveTickMarkColor;
this.disabledInactiveTickMarkColor = disabledInactiveTickMarkColor;
this.thumbColor = thumbColor;
this.disabledThumbColor = disabledThumbColor;
this.overlayColor = overlayColor;
this.valueIndicatorColor = valueIndicatorColor;
this.thumbShape = thumbShape;
this.valueIndicatorShape = valueIndicatorShape;
this.showValueIndicator = showValueIndicator.Value;
this.valueIndicatorTextStyle = valueIndicatorTextStyle;
}
public static SliderThemeData fromPrimaryColors(
Color primaryColor = null,
Color primaryColorDark = null,
Color primaryColorLight = null,
TextStyle valueIndicatorTextStyle = null) {
D.assert(primaryColor != null);
D.assert(primaryColorDark != null);
D.assert(primaryColorLight != null);
D.assert(valueIndicatorTextStyle != null);
const int activeTrackAlpha = 0xff;
const int inactiveTrackAlpha = 0x3d; // 24% opacity
const int disabledActiveTrackAlpha = 0x52; // 32% opacity
const int disabledInactiveTrackAlpha = 0x1f; // 12% opacity
const int activeTickMarkAlpha = 0x8a; // 54% opacity
const int inactiveTickMarkAlpha = 0x8a; // 54% opacity
const int disabledActiveTickMarkAlpha = 0x1f; // 12% opacity
const int disabledInactiveTickMarkAlpha = 0x1f; // 12% opacity
const int thumbAlpha = 0xff;
const int disabledThumbAlpha = 0x52; // 32% opacity
const int valueIndicatorAlpha = 0xff;
const int overlayLightAlpha = 0x29;
return new SliderThemeData(
activeTrackColor: primaryColor.withAlpha(activeTrackAlpha),
inactiveTrackColor: primaryColor.withAlpha(inactiveTrackAlpha),
disabledActiveTrackColor: primaryColorDark.withAlpha(disabledActiveTrackAlpha),
disabledInactiveTrackColor: primaryColorDark.withAlpha(disabledInactiveTrackAlpha),
activeTickMarkColor: primaryColorLight.withAlpha(activeTickMarkAlpha),
inactiveTickMarkColor: primaryColor.withAlpha(inactiveTickMarkAlpha),
disabledActiveTickMarkColor: primaryColorLight.withAlpha(disabledActiveTickMarkAlpha),
disabledInactiveTickMarkColor: primaryColorDark.withAlpha(disabledInactiveTickMarkAlpha),
thumbColor: primaryColor.withAlpha(thumbAlpha),
disabledThumbColor: primaryColorDark.withAlpha(disabledThumbAlpha),
overlayColor: primaryColor.withAlpha(overlayLightAlpha),
valueIndicatorColor: primaryColor.withAlpha(valueIndicatorAlpha),
thumbShape: new RoundSliderThumbShape(),
valueIndicatorShape: new PaddleSliderValueIndicatorShape(),
valueIndicatorTextStyle: valueIndicatorTextStyle,
showValueIndicator: ShowValueIndicator.onlyForDiscrete
);
}
public readonly Color activeTrackColor;
public readonly Color inactiveTrackColor;
public readonly Color disabledActiveTrackColor;
public readonly Color disabledInactiveTrackColor;
public readonly Color activeTickMarkColor;
public readonly Color inactiveTickMarkColor;
public readonly Color disabledActiveTickMarkColor;
public readonly Color disabledInactiveTickMarkColor;
public readonly Color thumbColor;
public readonly Color disabledThumbColor;
public readonly Color overlayColor;
public readonly Color valueIndicatorColor;
public readonly SliderComponentShape thumbShape;
public readonly SliderComponentShape valueIndicatorShape;
public readonly ShowValueIndicator showValueIndicator;
public readonly TextStyle valueIndicatorTextStyle;
public SliderThemeData copyWith(
float? trackHeight = null,
Color activeTrackColor = null,
Color inactiveTrackColor = null,
Color disabledActiveTrackColor = null,
Color disabledInactiveTrackColor = null,
Color activeTickMarkColor = null,
Color inactiveTickMarkColor = null,
Color disabledActiveTickMarkColor = null,
Color disabledInactiveTickMarkColor = null,
Color thumbColor = null,
Color disabledThumbColor = null,
Color overlayColor = null,
Color valueIndicatorColor = null,
SliderTrackShape trackShape = null,
SliderTickMarkShape tickMarkShape = null,
SliderComponentShape thumbShape = null,
SliderComponentShape overlayShape = null,
SliderComponentShape valueIndicatorShape = null,
ShowValueIndicator? showValueIndicator = null,
TextStyle valueIndicatorTextStyle = null
) {
return new SliderThemeData(
activeTrackColor: activeTrackColor ?? this.activeTrackColor,
inactiveTrackColor: inactiveTrackColor ?? this.inactiveTrackColor,
disabledActiveTrackColor: disabledActiveTrackColor ?? this.disabledActiveTrackColor,
disabledInactiveTrackColor: disabledInactiveTrackColor ?? this.disabledInactiveTrackColor,
activeTickMarkColor: activeTickMarkColor ?? this.activeTickMarkColor,
inactiveTickMarkColor: inactiveTickMarkColor ?? this.inactiveTickMarkColor,
disabledActiveTickMarkColor: disabledActiveTickMarkColor ?? this.disabledActiveTickMarkColor,
disabledInactiveTickMarkColor: disabledInactiveTickMarkColor ?? this.disabledInactiveTickMarkColor,
thumbColor: thumbColor ?? this.thumbColor,
disabledThumbColor: disabledThumbColor ?? this.disabledThumbColor,
overlayColor: overlayColor ?? this.overlayColor,
valueIndicatorColor: valueIndicatorColor ?? this.valueIndicatorColor,
thumbShape: thumbShape ?? this.thumbShape,
valueIndicatorShape: valueIndicatorShape ?? this.valueIndicatorShape,
showValueIndicator: showValueIndicator ?? this.showValueIndicator,
valueIndicatorTextStyle: valueIndicatorTextStyle ?? this.valueIndicatorTextStyle
);
}
public static SliderThemeData lerp(SliderThemeData a, SliderThemeData b, float t) {
D.assert(a != null);
D.assert(b != null);
return new SliderThemeData(
activeTrackColor: Color.lerp(a.activeTrackColor, b.activeTrackColor, t),
inactiveTrackColor: Color.lerp(a.inactiveTrackColor, b.inactiveTrackColor, t),
disabledActiveTrackColor: Color.lerp(a.disabledActiveTrackColor, b.disabledActiveTrackColor, t),
disabledInactiveTrackColor: Color.lerp(a.disabledInactiveTrackColor, b.disabledInactiveTrackColor, t),
activeTickMarkColor: Color.lerp(a.activeTickMarkColor, b.activeTickMarkColor, t),
inactiveTickMarkColor: Color.lerp(a.inactiveTickMarkColor, b.inactiveTickMarkColor, t),
disabledActiveTickMarkColor: Color.lerp(a.disabledActiveTickMarkColor, b.disabledActiveTickMarkColor,
t),
disabledInactiveTickMarkColor: Color.lerp(a.disabledInactiveTickMarkColor,
b.disabledInactiveTickMarkColor, t),
thumbColor: Color.lerp(a.thumbColor, b.thumbColor, t),
disabledThumbColor: Color.lerp(a.disabledThumbColor, b.disabledThumbColor, t),
overlayColor: Color.lerp(a.overlayColor, b.overlayColor, t),
valueIndicatorColor: Color.lerp(a.valueIndicatorColor, b.valueIndicatorColor, t),
thumbShape: t < 0.5 ? a.thumbShape : b.thumbShape,
valueIndicatorShape: t < 0.5 ? a.valueIndicatorShape : b.valueIndicatorShape,
showValueIndicator: t < 0.5 ? a.showValueIndicator : b.showValueIndicator,
valueIndicatorTextStyle: TextStyle.lerp(a.valueIndicatorTextStyle, b.valueIndicatorTextStyle, t)
);
}
public bool Equals(SliderThemeData other) {
if (ReferenceEquals(null, other)) {
return false;
}
if (ReferenceEquals(this, other)) {
return true;
}
return other.activeTrackColor == this.activeTrackColor
&& other.inactiveTrackColor == this.inactiveTrackColor
&& other.disabledActiveTrackColor == this.disabledActiveTrackColor
&& other.disabledInactiveTrackColor == this.disabledInactiveTrackColor
&& other.activeTickMarkColor == this.activeTickMarkColor
&& other.inactiveTickMarkColor == this.inactiveTickMarkColor
&& other.disabledActiveTickMarkColor == this.disabledActiveTickMarkColor
&& other.disabledInactiveTickMarkColor == this.disabledInactiveTickMarkColor
&& other.thumbColor == this.thumbColor
&& other.disabledThumbColor == this.disabledThumbColor
&& other.overlayColor == this.overlayColor
&& other.valueIndicatorColor == this.valueIndicatorColor
&& other.thumbShape == this.thumbShape
&& other.valueIndicatorShape == this.valueIndicatorShape
&& other.showValueIndicator == this.showValueIndicator
&& other.valueIndicatorTextStyle == this.valueIndicatorTextStyle;
}
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((SliderThemeData) obj);
}
public static bool operator ==(SliderThemeData left, SliderThemeData right) {
return Equals(left, right);
}
public static bool operator !=(SliderThemeData left, SliderThemeData right) {
return !Equals(left, right);
}
int? _cachedHashCode = null;
public override int GetHashCode() {
if (this._cachedHashCode != null) {
return this._cachedHashCode.Value;
}
unchecked {
var hashCode = this.activeTrackColor.GetHashCode();
hashCode = (hashCode * 397) ^ this.inactiveTrackColor.GetHashCode();
hashCode = (hashCode * 397) ^ this.disabledActiveTrackColor.GetHashCode();
hashCode = (hashCode * 397) ^ this.disabledInactiveTrackColor.GetHashCode();
hashCode = (hashCode * 397) ^ this.activeTickMarkColor.GetHashCode();
hashCode = (hashCode * 397) ^ this.inactiveTickMarkColor.GetHashCode();
hashCode = (hashCode * 397) ^ this.disabledActiveTickMarkColor.GetHashCode();
hashCode = (hashCode * 397) ^ this.disabledInactiveTickMarkColor.GetHashCode();
hashCode = (hashCode * 397) ^ this.thumbColor.GetHashCode();
hashCode = (hashCode * 397) ^ this.disabledThumbColor.GetHashCode();
hashCode = (hashCode * 397) ^ this.overlayColor.GetHashCode();
hashCode = (hashCode * 397) ^ this.valueIndicatorColor.GetHashCode();
hashCode = (hashCode * 397) ^ this.thumbShape.GetHashCode();
hashCode = (hashCode * 397) ^ this.valueIndicatorShape.GetHashCode();
hashCode = (hashCode * 397) ^ this.showValueIndicator.GetHashCode();
hashCode = (hashCode * 397) ^ this.valueIndicatorTextStyle.GetHashCode();
this._cachedHashCode = hashCode;
return hashCode;
}
}
public override void debugFillProperties(DiagnosticPropertiesBuilder properties) {
base.debugFillProperties(properties);
ThemeData defaultTheme = ThemeData.fallback();
SliderThemeData defaultData = fromPrimaryColors(
primaryColor: defaultTheme.primaryColor,
primaryColorDark: defaultTheme.primaryColorDark,
primaryColorLight: defaultTheme.primaryColorLight,
valueIndicatorTextStyle: defaultTheme.accentTextTheme.body2
);
properties.add(new DiagnosticsProperty<Color>("activeTrackColor", this.activeTrackColor,
defaultValue: defaultData.activeTrackColor));
properties.add(new DiagnosticsProperty<Color>("activeTrackColor", this.activeTrackColor,
defaultValue: defaultData.activeTrackColor));
properties.add(new DiagnosticsProperty<Color>("inactiveTrackColor", this.inactiveTrackColor,
defaultValue: defaultData.inactiveTrackColor));
properties.add(new DiagnosticsProperty<Color>("disabledActiveTrackColor", this.disabledActiveTrackColor,
defaultValue: defaultData.disabledActiveTrackColor, level: DiagnosticLevel.debug));
properties.add(new DiagnosticsProperty<Color>("disabledInactiveTrackColor", this.disabledInactiveTrackColor,
defaultValue: defaultData.disabledInactiveTrackColor, level: DiagnosticLevel.debug));
properties.add(new DiagnosticsProperty<Color>("activeTickMarkColor", this.activeTickMarkColor,
defaultValue: defaultData.activeTickMarkColor, level: DiagnosticLevel.debug));
properties.add(new DiagnosticsProperty<Color>("inactiveTickMarkColor", this.inactiveTickMarkColor,
defaultValue: defaultData.inactiveTickMarkColor, level: DiagnosticLevel.debug));
properties.add(new DiagnosticsProperty<Color>("disabledActiveTickMarkColor",
this.disabledActiveTickMarkColor, defaultValue: defaultData.disabledActiveTickMarkColor,
level: DiagnosticLevel.debug));
properties.add(new DiagnosticsProperty<Color>("disabledInactiveTickMarkColor",
this.disabledInactiveTickMarkColor, defaultValue: defaultData.disabledInactiveTickMarkColor,
level: DiagnosticLevel.debug));
properties.add(new DiagnosticsProperty<Color>("thumbColor", this.thumbColor,
defaultValue: defaultData.thumbColor));
properties.add(new DiagnosticsProperty<Color>("disabledThumbColor", this.disabledThumbColor,
defaultValue: defaultData.disabledThumbColor, level: DiagnosticLevel.debug));
properties.add(new DiagnosticsProperty<Color>("overlayColor", this.overlayColor,
defaultValue: defaultData.overlayColor, level: DiagnosticLevel.debug));
properties.add(new DiagnosticsProperty<Color>("valueIndicatorColor", this.valueIndicatorColor,
defaultValue: defaultData.valueIndicatorColor));
properties.add(new DiagnosticsProperty<SliderComponentShape>("thumbShape", this.thumbShape,
defaultValue: defaultData.thumbShape, level: DiagnosticLevel.debug));
properties.add(new DiagnosticsProperty<SliderComponentShape>("valueIndicatorShape",
this.valueIndicatorShape, defaultValue: defaultData.valueIndicatorShape, level: DiagnosticLevel.debug));
properties.add(new EnumProperty<ShowValueIndicator>("showValueIndicator", this.showValueIndicator,
defaultValue: defaultData.showValueIndicator));
properties.add(new DiagnosticsProperty<TextStyle>("valueIndicatorTextStyle", this.valueIndicatorTextStyle,
defaultValue: defaultData.valueIndicatorTextStyle));
}
}
public abstract class SliderTrackShape {
public SliderTrackShape() {
}
public abstract Rect getPreferredRect(
RenderBox parentBox = null,
Offset offset = null,
SliderThemeData sliderTheme = null,
bool? isEnabled = null,
bool? isDiscrete = null);
public abstract void paint(
PaintingContext context,
Offset offset,
RenderBox parentBox = null,
SliderThemeData sliderTheme = null,
Animation<float> enableAnimation = null,
Offset thumbCenter = null,
bool? isEnabled = null,
bool? isDiscrete = null
);
}
public abstract class SliderTickMarkShape {
public SliderTickMarkShape() {
}
public abstract Size getPreferredSize(
SliderThemeData sliderTheme = null,
bool? isEnabled = null);
public abstract void paint(
PaintingContext context,
Offset offset,
RenderBox parentBox = null,
SliderThemeData sliderTheme = null,
Animation<float> enableAnimation = null,
Offset thumbCenter = null,
bool? isEnabled = null);
public static readonly SliderTickMarkShape noTickMark = new _EmptySliderTickMarkShape();
}
class _EmptySliderTickMarkShape : SliderTickMarkShape {
public override Size getPreferredSize(
SliderThemeData sliderTheme = null,
bool? isEnabled = null) {
return Size.zero;
}
public override void paint(
PaintingContext context,
Offset offset,
RenderBox parentBox = null,
SliderThemeData sliderTheme = null,
Animation<float> enableAnimation = null,
Offset thumbCenter = null,
bool? isEnabled = null) {
}
}
public abstract class SliderComponentShape {
public SliderComponentShape() {
}
public abstract Size getPreferredSize(
bool? isEnabled,
bool? isDiscrete);
public abstract void paint(
PaintingContext context,
Offset thumbCenter,
Animation<float> activationAnimation = null,
Animation<float> enableAnimation = null,
bool? isDiscrete = null,
TextPainter labelPainter = null,
RenderBox parentBox = null,
SliderThemeData sliderTheme = null,
float? value = null);
public static readonly SliderComponentShape noThumb = new _EmptySliderComponentShape();
public static readonly SliderComponentShape noOverlay = new _EmptySliderComponentShape();
}
class _EmptySliderComponentShape : SliderComponentShape {
public override Size getPreferredSize(
bool? isEnabled,
bool? isDiscrete) {
return Size.zero;
}
public override void paint(
PaintingContext context,
Offset thumbCenter,
Animation<float> activationAnimation = null,
Animation<float> enableAnimation = null,
bool? isDiscrete = null,
TextPainter labelPainter = null,
RenderBox parentBox = null,
SliderThemeData sliderTheme = null,
float? value = null) {
}
}
public class RoundSliderThumbShape : SliderComponentShape {
public RoundSliderThumbShape(
float enabledThumbRadius = 6.0f,
float? disabledThumbRadius = null
) {
this.enabledThumbRadius = enabledThumbRadius;
this.disabledThumbRadius = disabledThumbRadius;
}
public readonly float enabledThumbRadius;
public readonly float? disabledThumbRadius;
float _disabledThumbRadius {
get { return this.disabledThumbRadius ?? this.enabledThumbRadius * 2f / 3f; }
}
public override Size getPreferredSize(bool? isEnabled, bool? isDiscrete) {
return Size.fromRadius(isEnabled.Value ? this.enabledThumbRadius : this._disabledThumbRadius);
}
public override void paint(
PaintingContext context,
Offset center,
Animation<float> activationAnimation = null,
Animation<float> enableAnimation = null,
bool? isDiscrete = null,
TextPainter labelPainter = null,
RenderBox parentBox = null,
SliderThemeData sliderTheme = null,
float? value = null
) {
Canvas canvas = context.canvas;
FloatTween radiusTween = new FloatTween(
begin: this._disabledThumbRadius,
end: this.enabledThumbRadius
);
ColorTween colorTween = new ColorTween(
begin: sliderTheme.disabledThumbColor,
end: sliderTheme.thumbColor
);
canvas.drawCircle(
center,
radiusTween.evaluate(enableAnimation),
new Paint {color = colorTween.evaluate(enableAnimation)}
);
}
}
public class PaddleSliderValueIndicatorShape : SliderComponentShape {
public PaddleSliderValueIndicatorShape() {
}
const float _topLobeRadius = 16.0f;
const float _labelTextDesignSize = 14.0f;
const float _bottomLobeRadius = 6.0f;
const float _bottomLobeStartAngle = -1.1f * Mathf.PI / 4.0f;
const float _bottomLobeEndAngle = 1.1f * 5 * Mathf.PI / 4.0f;
const float _labelPadding = 8.0f;
const float _distanceBetweenTopBottomCenters = 40.0f;
static readonly Offset _topLobeCenter = new Offset(0.0f, -_distanceBetweenTopBottomCenters);
const float _topNeckRadius = 14.0f;
const float _neckTriangleHypotenuse = _topLobeRadius + _topNeckRadius;
const float _twoSeventyDegrees = 3.0f * Mathf.PI / 2.0f;
const float _ninetyDegrees = Mathf.PI / 2.0f;
const float _thirtyDegrees = Mathf.PI / 6.0f;
static readonly Size _preferredSize =
Size.fromHeight(_distanceBetweenTopBottomCenters + _topLobeRadius + _bottomLobeRadius);
const bool _debuggingLabelLocation = false;
static Path _bottomLobePath;
static Offset _bottomLobeEnd;
public override Size getPreferredSize(
bool? isEnabled,
bool? isDiscrete) {
return _preferredSize;
}
static void _addArc(Path path, Offset center, float radius, float startAngle, float endAngle) {
Rect arcRect = Rect.fromCircle(center: center, radius: radius);
path.addArc(arcRect, startAngle, endAngle - startAngle, false);
}
static void _generateBottomLobe() {
const float bottomNeckRadius = 4.5f;
const float bottomNeckStartAngle = _bottomLobeEndAngle - Mathf.PI;
const float bottomNeckEndAngle = 0.0f;
Path path = new Path();
Offset bottomKnobStart = new Offset(
_bottomLobeRadius * Mathf.Cos(_bottomLobeStartAngle),
_bottomLobeRadius * Mathf.Sin(_bottomLobeStartAngle)
);
Offset bottomNeckRightCenter = bottomKnobStart +
new Offset(
bottomNeckRadius * Mathf.Cos(bottomNeckStartAngle),
-bottomNeckRadius * Mathf.Sin(bottomNeckStartAngle)
);
Offset bottomNeckLeftCenter = new Offset(
-bottomNeckRightCenter.dx,
bottomNeckRightCenter.dy
);
Offset bottomNeckStartRight = new Offset(
bottomNeckRightCenter.dx - bottomNeckRadius,
bottomNeckRightCenter.dy
);
path.moveTo(bottomNeckStartRight.dx, bottomNeckStartRight.dy);
_addArc(
path,
bottomNeckRightCenter,
bottomNeckRadius,
Mathf.PI - bottomNeckEndAngle,
Mathf.PI - bottomNeckStartAngle
);
_addArc(
path,
Offset.zero,
_bottomLobeRadius,
_bottomLobeStartAngle,
_bottomLobeEndAngle
);
_addArc(
path,
bottomNeckLeftCenter,
bottomNeckRadius,
bottomNeckStartAngle,
bottomNeckEndAngle
);
_bottomLobeEnd = new Offset(
-bottomNeckStartRight.dx,
bottomNeckStartRight.dy
);
_bottomLobePath = path;
}
Offset _addBottomLobe(Path path) {
if (_bottomLobePath == null || _bottomLobeEnd == null) {
_generateBottomLobe();
}
path.addPath(_bottomLobePath, Offset.zero);
return _bottomLobeEnd;
}
float _getIdealOffset(
RenderBox parentBox,
float halfWidthNeeded,
float scale,
Offset center
) {
const float edgeMargin = 4.0f;
Rect topLobeRect = Rect.fromLTWH(
-_topLobeRadius - halfWidthNeeded,
-_topLobeRadius - _distanceBetweenTopBottomCenters,
2.0f * (_topLobeRadius + halfWidthNeeded),
2.0f * _topLobeRadius
);
Offset topLeft = (topLobeRect.topLeft * scale) + center;
Offset bottomRight = (topLobeRect.bottomRight * scale) + center;
float shift = 0.0f;
if (topLeft.dx < edgeMargin) {
shift = edgeMargin - topLeft.dx;
}
if (bottomRight.dx > parentBox.size.width - edgeMargin) {
shift = parentBox.size.width - bottomRight.dx - edgeMargin;
}
shift = scale == 0.0f ? 0.0f : shift / scale;
return shift;
}
void _drawValueIndicator(
RenderBox parentBox,
Canvas canvas,
Offset center,
Paint paint,
float scale,
TextPainter labelPainter
) {
canvas.save();
canvas.translate(center.dx, center.dy);
float textScaleFactor = labelPainter.height / _labelTextDesignSize;
float overallScale = scale * textScaleFactor;
canvas.scale(overallScale, overallScale);
float inverseTextScale = textScaleFactor != 0 ? 1.0f / textScaleFactor : 0.0f;
float labelHalfWidth = labelPainter.width / 2.0f;
float halfWidthNeeded = Mathf.Max(
0.0f,
inverseTextScale * labelHalfWidth - (_topLobeRadius - _labelPadding)
);
float shift = this._getIdealOffset(parentBox, halfWidthNeeded, overallScale, center);
float leftWidthNeeded;
float rightWidthNeeded;
if (shift < 0.0) {
shift = Mathf.Max(shift, -halfWidthNeeded);
}
else {
shift = Mathf.Min(shift, halfWidthNeeded);
}
rightWidthNeeded = halfWidthNeeded + shift;
leftWidthNeeded = halfWidthNeeded - shift;
Path path = new Path();
Offset bottomLobeEnd = this._addBottomLobe(path);
float neckTriangleBase = _topNeckRadius - bottomLobeEnd.dx;
float leftAmount = Mathf.Max(0.0f, Mathf.Min(1.0f, leftWidthNeeded / neckTriangleBase));
float rightAmount = Mathf.Max(0.0f, Mathf.Min(1.0f, rightWidthNeeded / neckTriangleBase));
float leftTheta = (1.0f - leftAmount) * _thirtyDegrees;
float rightTheta = (1.0f - rightAmount) * _thirtyDegrees;
Offset neckLeftCenter = new Offset(
-neckTriangleBase,
_topLobeCenter.dy + Mathf.Cos(leftTheta) * _neckTriangleHypotenuse
);
Offset neckRightCenter = new Offset(
neckTriangleBase,
_topLobeCenter.dy + Mathf.Cos(rightTheta) * _neckTriangleHypotenuse
);
float leftNeckArcAngle = _ninetyDegrees - leftTheta;
float rightNeckArcAngle = Mathf.PI + _ninetyDegrees - rightTheta;
float neckStretchBaseline = bottomLobeEnd.dy - Mathf.Max(neckLeftCenter.dy, neckRightCenter.dy);
float t = Mathf.Pow(inverseTextScale, 3.0f);
float stretch = (neckStretchBaseline * t).clamp(0.0f, 10.0f * neckStretchBaseline);
Offset neckStretch = new Offset(0.0f, neckStretchBaseline - stretch);
D.assert(() => {
if (!_debuggingLabelLocation) {
return true;
}
Offset leftCenter = _topLobeCenter - new Offset(leftWidthNeeded, 0.0f) + neckStretch;
Offset rightCenter = _topLobeCenter + new Offset(rightWidthNeeded, 0.0f) + neckStretch;
Rect valueRect = Rect.fromLTRB(
leftCenter.dx - _topLobeRadius,
leftCenter.dy - _topLobeRadius,
rightCenter.dx + _topLobeRadius,
rightCenter.dy + _topLobeRadius
);
Paint outlinePaint = new Paint();
outlinePaint.color = new Color(0xffff0000);
outlinePaint.style = PaintingStyle.stroke;
outlinePaint.strokeWidth = 1.0f;
canvas.drawRect(valueRect, outlinePaint);
return true;
});
_addArc(
path,
neckLeftCenter + neckStretch,
_topNeckRadius,
0.0f,
-leftNeckArcAngle
);
_addArc(
path,
_topLobeCenter - new Offset(leftWidthNeeded, 0.0f) + neckStretch,
_topLobeRadius,
_ninetyDegrees + leftTheta,
_twoSeventyDegrees
);
_addArc(
path,
_topLobeCenter + new Offset(rightWidthNeeded, 0.0f) + neckStretch,
_topLobeRadius,
_twoSeventyDegrees,
_twoSeventyDegrees + Mathf.PI - rightTheta
);
_addArc(
path,
neckRightCenter + neckStretch,
_topNeckRadius,
rightNeckArcAngle,
Mathf.PI
);
canvas.drawPath(path, paint);
canvas.save();
canvas.translate(shift, -_distanceBetweenTopBottomCenters + neckStretch.dy);
canvas.scale(inverseTextScale, inverseTextScale);
labelPainter.paint(canvas, Offset.zero - new Offset(labelHalfWidth, labelPainter.height / 2.0f));
canvas.restore();
canvas.restore();
}
public override void paint(
PaintingContext context,
Offset center,
Animation<float> activationAnimation = null,
Animation<float> enableAnimation = null,
bool? isDiscrete = null,
TextPainter labelPainter = null,
RenderBox parentBox = null,
SliderThemeData sliderTheme = null,
float? value = null) {
ColorTween enableColor = new ColorTween(
begin: sliderTheme.disabledThumbColor,
end: sliderTheme.valueIndicatorColor
);
this._drawValueIndicator(
parentBox,
context.canvas,
center,
new Paint {color = enableColor.evaluate(enableAnimation)},
activationAnimation.value,
labelPainter
);
}
}
}

11
Runtime/material/slider_theme.cs.meta


fileFormatVersion: 2
guid: b0979d058a7d54b689709e0312d2732b
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
正在加载...
取消
保存