|
|
|
|
|
|
using System; |
|
|
|
using Unity.UIWidgets.animation; |
|
|
|
using Unity.UIWidgets.async; |
|
|
|
using Unity.UIWidgets.cupertino; |
|
|
|
using UnityEngine; |
|
|
|
using Color = Unity.UIWidgets.ui.Color; |
|
|
|
|
|
|
|
namespace Unity.UIWidgets.material { |
|
|
|
static class ScrollbarUtils { |
|
|
|
|
|
|
public class Scrollbar : StatefulWidget { |
|
|
|
public Scrollbar( |
|
|
|
Key key = null, |
|
|
|
Widget child = null) : base(key: key) { |
|
|
|
Widget child = null, |
|
|
|
ScrollController controller = null, |
|
|
|
bool isAlwaysShown = false) : base(key: key) { |
|
|
|
this.controller = controller; |
|
|
|
this.isAlwaysShown = isAlwaysShown; |
|
|
|
|
|
|
|
public readonly ScrollController controller; |
|
|
|
|
|
|
|
public readonly bool isAlwaysShown; |
|
|
|
|
|
|
|
public override State createState() { |
|
|
|
return new _ScrollbarState(); |
|
|
|
|
|
|
public TextDirection _textDirection; |
|
|
|
public Color _themeColor; |
|
|
|
|
|
|
|
bool? _useCupertinoScrollbar = null; |
|
|
|
|
|
|
|
public Animation<float> _FadeoutOpacityAnimation; |
|
|
|
public Animation<float> _fadeoutOpacityAnimation; |
|
|
|
public Timer _fadeoutTimer; |
|
|
|
|
|
|
|
public override void initState() { |
|
|
|
|
|
|
duration: ScrollbarUtils._kScrollbarFadeDuration |
|
|
|
); |
|
|
|
_FadeoutOpacityAnimation = new CurvedAnimation( |
|
|
|
_fadeoutOpacityAnimation = new CurvedAnimation( |
|
|
|
parent: _fadeoutAnimationController, |
|
|
|
curve: Curves.fastOutSlowIn |
|
|
|
); |
|
|
|
|
|
|
base.didChangeDependencies(); |
|
|
|
|
|
|
|
D.assert((() => { |
|
|
|
_useCupertinoScrollbar = null; |
|
|
|
return true; |
|
|
|
})); |
|
|
|
|
|
|
|
_themeColor = theme.highlightColor.withOpacity(1.0f); |
|
|
|
_textDirection = Directionality.of(context); |
|
|
|
_materialPainter = _BuildMaterialScrollbarPainter(); |
|
|
|
switch (theme.platform) { |
|
|
|
case RuntimePlatform.IPhonePlayer: |
|
|
|
case RuntimePlatform.OSXPlayer: |
|
|
|
case RuntimePlatform.OSXEditor: |
|
|
|
_fadeoutTimer?.cancel(); |
|
|
|
_fadeoutTimer = null; |
|
|
|
_fadeoutAnimationController.reset(); |
|
|
|
_useCupertinoScrollbar = true; |
|
|
|
break; |
|
|
|
default: |
|
|
|
_themeColor = theme.highlightColor.withOpacity(1.0f); |
|
|
|
_textDirection = Directionality.of(context); |
|
|
|
_materialPainter = _buildMaterialScrollbarPainter(); |
|
|
|
_useCupertinoScrollbar = false; |
|
|
|
WidgetsBinding.instance.addPostFrameCallback((TimeSpan duration) => { |
|
|
|
if (widget.isAlwaysShown) { |
|
|
|
D.assert(widget.controller != null); |
|
|
|
widget.controller.position.didUpdateScrollPositionBy(0); |
|
|
|
} |
|
|
|
}); |
|
|
|
break; |
|
|
|
} |
|
|
|
|
|
|
|
D.assert(_useCupertinoScrollbar != null); |
|
|
|
} |
|
|
|
|
|
|
|
public override void didUpdateWidget(StatefulWidget oldWidget) { |
|
|
|
var _oldWidget = (Scrollbar) oldWidget; |
|
|
|
base.didUpdateWidget(oldWidget); |
|
|
|
if (widget.isAlwaysShown != _oldWidget.isAlwaysShown) { |
|
|
|
D.assert(widget.controller != null); |
|
|
|
if (widget.isAlwaysShown == false) { |
|
|
|
_fadeoutAnimationController.reverse(); |
|
|
|
} |
|
|
|
else { |
|
|
|
_fadeoutAnimationController.animateTo(1.0f); |
|
|
|
} |
|
|
|
} |
|
|
|
public ScrollbarPainter _BuildMaterialScrollbarPainter() { |
|
|
|
public ScrollbarPainter _buildMaterialScrollbarPainter() { |
|
|
|
textDirection: _textDirection, |
|
|
|
thickness: ScrollbarUtils._kScrollbarThickness, |
|
|
|
fadeoutOpacityAnimation: _FadeoutOpacityAnimation |
|
|
|
textDirection: _textDirection, |
|
|
|
thickness: ScrollbarUtils._kScrollbarThickness, |
|
|
|
fadeoutOpacityAnimation: _fadeoutOpacityAnimation, |
|
|
|
padding: MediaQuery.of(context).padding |
|
|
|
if (notification is ScrollUpdateNotification || notification is OverscrollNotification) { |
|
|
|
ScrollMetrics metrics = notification.metrics; |
|
|
|
if (metrics.maxScrollExtent <= metrics.minScrollExtent) { |
|
|
|
return false; |
|
|
|
} |
|
|
|
if (!_useCupertinoScrollbar.Value && |
|
|
|
(notification is ScrollUpdateNotification || |
|
|
|
notification is OverscrollNotification)) { |
|
|
|
_materialPainter.update(notification.metrics, notification.metrics.axisDirection); |
|
|
|
_fadeoutTimer?.cancel(); |
|
|
|
|
|
|
|
_fadeoutTimer = Timer.create(ScrollbarUtils._kScrollbarTimeToFade, () => { |
|
|
|
_fadeoutAnimationController.reverse(); |
|
|
|
_fadeoutTimer = null; |
|
|
|
}); |
|
|
|
_materialPainter.update( |
|
|
|
notification.metrics, |
|
|
|
notification.metrics.axisDirection |
|
|
|
); |
|
|
|
if (!widget.isAlwaysShown) { |
|
|
|
_fadeoutTimer?.cancel(); |
|
|
|
_fadeoutTimer = Timer.create(ScrollbarUtils._kScrollbarTimeToFade, () => { |
|
|
|
_fadeoutAnimationController.reverse(); |
|
|
|
_fadeoutTimer = null; |
|
|
|
}); |
|
|
|
} |
|
|
|
|
|
|
|
return false; |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
public override Widget build(BuildContext context) { |
|
|
|
if (_useCupertinoScrollbar.Value) { |
|
|
|
return new CupertinoScrollbar( |
|
|
|
child: widget.child, |
|
|
|
isAlwaysShown: widget.isAlwaysShown, |
|
|
|
controller: widget.controller |
|
|
|
); |
|
|
|
} |
|
|
|
return new NotificationListener<ScrollNotification>( |
|
|
|
onNotification: _handleScrollNotification, |
|
|
|
child: new RepaintBoundary( |
|
|
|