Yuncong Zhang
6 年前
当前提交
cac6a69b
共有 36 个文件被更改,包括 2332 次插入 和 220 次删除
-
20Runtime/foundation/change_notifier.cs
-
9Runtime/gestures/team.cs
-
3Runtime/material/animated_icons/animated_icons.cs
-
4Runtime/material/app.cs
-
10Runtime/material/chip.cs
-
1Runtime/material/chip_theme.cs
-
2Runtime/material/float_action_button.cs
-
20Runtime/material/theme_data.cs
-
4Runtime/painting/notched_shapes.cs
-
4Runtime/painting/text_painter.cs
-
3Runtime/rendering/binding.cs
-
353Runtime/rendering/editable.cs
-
8Runtime/rendering/layer.cs
-
2Runtime/rendering/object.cs
-
11Runtime/rendering/proxy_box.cs
-
6Runtime/rendering/sliver.cs
-
2Runtime/rendering/sliver_multi_box_adaptor.cs
-
10Runtime/rendering/sliver_persistent_header.cs
-
3Runtime/rendering/table.cs
-
51Runtime/rendering/viewport.cs
-
79Runtime/service/text_input.cs
-
10Runtime/ui/painting/canvas.cs
-
41Runtime/ui/painting/path.cs
-
2Runtime/widgets/binding.cs
-
148Runtime/widgets/editable_text.cs
-
22Runtime/widgets/focus_scope.cs
-
24Runtime/widgets/text_selection.cs
-
1Samples/ReduxSample/ObjectFinder/ObjectFinderApp.cs
-
39Samples/UIWidgetSample/MaterialSample.cs
-
16Samples/UIWidgetSample/TextInputSample.cs
-
7Runtime/foundation/constants.cs
-
3Runtime/foundation/constants.cs.meta
-
805Runtime/material/slider.cs
-
11Runtime/material/slider.cs.meta
-
807Runtime/material/slider_theme.cs
-
11Runtime/material/slider_theme.cs.meta
|
|||
using UnityEngine; |
|||
|
|||
namespace Unity.UIWidgets.foundation { |
|||
public class FoundationConstants { |
|||
public bool kReleaseMode = !Debug.isDebugBuild; |
|||
} |
|||
} |
|
|||
fileFormatVersion: 2 |
|||
guid: 36d19e17f3d947f98c7accec2cd5771b |
|||
timeCreated: 1556097117 |
|
|||
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 |
|||
); |
|||
} |
|||
} |
|||
} |
|
|||
fileFormatVersion: 2 |
|||
guid: 99da8b1c2d9074a1781711f773197af1 |
|||
MonoImporter: |
|||
externalObjects: {} |
|||
serializedVersion: 2 |
|||
defaultReferences: [] |
|||
executionOrder: 0 |
|||
icon: {instanceID: 0} |
|||
userData: |
|||
assetBundleName: |
|||
assetBundleVariant: |
|
|||
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.arcTo(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 |
|||
); |
|||
} |
|||
} |
|||
} |
|
|||
fileFormatVersion: 2 |
|||
guid: b0979d058a7d54b689709e0312d2732b |
|||
MonoImporter: |
|||
externalObjects: {} |
|||
serializedVersion: 2 |
|||
defaultReferences: [] |
|||
executionOrder: 0 |
|||
icon: {instanceID: 0} |
|||
userData: |
|||
assetBundleName: |
|||
assetBundleVariant: |
撰写
预览
正在加载...
取消
保存
Reference in new issue