Signed-off-by: bggRGjQaUbCoE <githubaccount56556@proton.me>
This commit is contained in:
bggRGjQaUbCoE
2025-12-25 13:43:20 +08:00
parent 161bf2eedb
commit 20a36e8f9a
97 changed files with 596 additions and 436 deletions

View File

@@ -24,88 +24,31 @@ class CustomTooltip extends StatefulWidget {
static final List<CustomTooltipState> _openedTooltips =
<CustomTooltipState>[];
static bool dismissAllToolTips() {
if (_openedTooltips.isNotEmpty) {
final List<CustomTooltipState> openedTooltips = _openedTooltips.toList();
for (final CustomTooltipState state in openedTooltips) {
assert(state.mounted);
state._scheduleDismissTooltip();
}
return true;
}
return false;
}
@override
State<CustomTooltip> createState() => CustomTooltipState();
}
class CustomTooltipState extends State<CustomTooltip>
with SingleTickerProviderStateMixin {
static const Duration _fadeInDuration = Duration(milliseconds: 150);
static const Duration _fadeOutDuration = Duration(milliseconds: 75);
final OverlayPortalController _overlayController = OverlayPortalController();
AnimationController? _backingController;
AnimationController get _controller {
return _backingController ??= AnimationController(
duration: _fadeInDuration,
reverseDuration: _fadeOutDuration,
vsync: this,
)..addStatusListener(_handleStatusChanged);
}
CurvedAnimation? _backingOverlayAnimation;
CurvedAnimation get _overlayAnimation {
return _backingOverlayAnimation ??= CurvedAnimation(
parent: _controller,
curve: Curves.fastOutSlowIn,
);
}
LongPressGestureRecognizer? _longPressRecognizer;
AnimationStatus _animationStatus = AnimationStatus.dismissed;
void _handleStatusChanged(AnimationStatus status) {
assert(mounted);
switch ((_animationStatus.isDismissed, status.isDismissed)) {
case (false, true):
CustomTooltip._openedTooltips.remove(this);
_overlayController.hide();
case (true, false):
_overlayController.show();
CustomTooltip._openedTooltips.add(this);
case (true, true) || (false, false):
break;
}
_animationStatus = status;
}
void _scheduleShowTooltip() {
_controller.forward();
_overlayController.show();
CustomTooltip._openedTooltips.add(this);
}
void _scheduleDismissTooltip() {
_controller.reverse();
CustomTooltip._openedTooltips.remove(this);
_overlayController.hide();
}
void _handlePointerDown(PointerDownEvent event) {
assert(mounted);
const Set<PointerDeviceKind> triggerModeDeviceKinds = <PointerDeviceKind>{
PointerDeviceKind.invertedStylus,
PointerDeviceKind.stylus,
PointerDeviceKind.touch,
PointerDeviceKind.unknown,
PointerDeviceKind.trackpad,
};
_longPressRecognizer ??= LongPressGestureRecognizer(
(_longPressRecognizer ??= LongPressGestureRecognizer(
debugOwner: this,
supportedDevices: triggerModeDeviceKinds,
);
_longPressRecognizer!
..onLongPress = _scheduleShowTooltip
..addPointer(event);
)..onLongPress = _scheduleShowTooltip).addPointer(event);
}
Widget _buildCustomTooltipOverlay(BuildContext context) {
@@ -123,7 +66,6 @@ class CustomTooltipState extends State<CustomTooltip>
verticalOffset: box.size.height / 2,
horizontalOffset: box.size.width / 2,
type: widget.type,
animation: _overlayAnimation,
target: target,
onDismiss: _scheduleDismissTooltip,
overlayWidget: widget.overlayWidget,
@@ -141,8 +83,6 @@ class CustomTooltipState extends State<CustomTooltip>
CustomTooltip._openedTooltips.remove(this);
_longPressRecognizer?.onLongPressCancel = null;
_longPressRecognizer?.dispose();
_backingController?.dispose();
_backingOverlayAnimation?.dispose();
super.dispose();
}
@@ -177,7 +117,6 @@ class _CustomTooltipOverlay extends StatelessWidget {
required this.verticalOffset,
required this.horizontalOffset,
required this.type,
required this.animation,
required this.target,
required this.onDismiss,
required this.overlayWidget,
@@ -187,7 +126,6 @@ class _CustomTooltipOverlay extends StatelessWidget {
final double verticalOffset;
final double horizontalOffset;
final TooltipType type;
final Animation<double> animation;
final Offset target;
final VoidCallback onDismiss;
final Widget Function() overlayWidget;

View File

@@ -81,7 +81,9 @@ class _MouseInteractiveViewerState extends State<MouseInteractiveViewer>
final GlobalKey _parentKey = GlobalKey();
Animation<Offset>? _animation;
CurvedAnimation? _curvedAnimation;
Animation<double>? _scaleAnimation;
CurvedAnimation? _curvedScaleAnimation;
late Offset _scaleAnimationFocalPoint;
late AnimationController _controller;
late AnimationController _scaleController;
@@ -96,17 +98,7 @@ class _MouseInteractiveViewerState extends State<MouseInteractiveViewer>
touchSlop: Platform.isIOS ? 9 : 4,
);
late final _scaleGestureRecognizer =
ScaleGestureRecognizer(
debugOwner: this,
allowedButtonsFilter: (buttons) => buttons == kPrimaryButton,
trackpadScrollToScaleFactor: Offset(0, -1 / widget.scaleFactor),
trackpadScrollCausesScale: widget.trackpadScrollCausesScale,
)
..gestureSettings = gestureSettings
..onStart = _onScaleStart
..onUpdate = _onScaleUpdate
..onEnd = _onScaleEnd;
late final ScaleGestureRecognizer _scaleGestureRecognizer;
final bool _rotateEnabled = false;
@@ -451,7 +443,10 @@ class _MouseInteractiveViewerState extends State<MouseInteractiveViewer>
frictionSimulationY.finalX,
),
).animate(
CurvedAnimation(parent: _controller, curve: Curves.decelerate),
_curvedAnimation ??= CurvedAnimation(
parent: _controller,
curve: Curves.decelerate,
),
)
..addListener(_handleInertiaAnimation);
_controller
@@ -478,7 +473,7 @@ class _MouseInteractiveViewerState extends State<MouseInteractiveViewer>
begin: scale,
end: frictionSimulation.x(tFinal),
).animate(
CurvedAnimation(
_curvedScaleAnimation ??= CurvedAnimation(
parent: _scaleController,
curve: Curves.decelerate,
),
@@ -700,6 +695,17 @@ class _MouseInteractiveViewerState extends State<MouseInteractiveViewer>
@override
void initState() {
super.initState();
_scaleGestureRecognizer =
ScaleGestureRecognizer(
debugOwner: this,
allowedButtonsFilter: (buttons) => buttons == kPrimaryButton,
trackpadScrollToScaleFactor: Offset(0, -1 / widget.scaleFactor),
trackpadScrollCausesScale: widget.trackpadScrollCausesScale,
)
..gestureSettings = gestureSettings
..onStart = _onScaleStart
..onUpdate = _onScaleUpdate
..onEnd = _onScaleEnd;
_controller = AnimationController(vsync: this);
_scaleController = AnimationController(vsync: this);
@@ -726,7 +732,9 @@ class _MouseInteractiveViewerState extends State<MouseInteractiveViewer>
@override
void dispose() {
_scaleGestureRecognizer.dispose();
_curvedAnimation?.dispose();
_controller.dispose();
_curvedScaleAnimation?.dispose();
_scaleController.dispose();
_transformer.removeListener(_handleTransformation);
if (widget.transformationController == null) {

View File

@@ -31,6 +31,18 @@ class HeroDialogRoute<T> extends PageRoute<T> {
@override
Color? get barrierColor => null;
CurvedAnimation? _curvedAnimation;
void _setAnimation(Animation<double> animation) {
if (_curvedAnimation?.parent != animation) {
_curvedAnimation?.dispose();
_curvedAnimation = CurvedAnimation(
parent: animation,
curve: Curves.easeOut,
);
}
}
@override
Widget buildTransitions(
BuildContext context,
@@ -38,12 +50,19 @@ class HeroDialogRoute<T> extends PageRoute<T> {
Animation<double> secondaryAnimation,
Widget child,
) {
_setAnimation(animation);
return FadeTransition(
opacity: CurvedAnimation(parent: animation, curve: Curves.easeOut),
opacity: _curvedAnimation!,
child: child,
);
}
@override
void dispose() {
_curvedAnimation?.dispose();
super.dispose();
}
@override
Widget buildPage(
BuildContext context,

View File

@@ -503,7 +503,9 @@ class _InteractiveViewerState extends State<InteractiveViewer>
final GlobalKey _childKey = GlobalKey();
final GlobalKey _parentKey = GlobalKey();
Animation<Offset>? _animation;
CurvedAnimation? _curvedAnimation;
Animation<double>? _scaleAnimation;
CurvedAnimation? _curvedScaleAnimation;
late Offset _scaleAnimationFocalPoint;
late AnimationController _controller;
late AnimationController _scaleController;
@@ -930,7 +932,10 @@ class _InteractiveViewerState extends State<InteractiveViewer>
frictionSimulationY.finalX,
),
).animate(
CurvedAnimation(parent: _controller, curve: Curves.decelerate),
_curvedAnimation ??= CurvedAnimation(
parent: _controller,
curve: Curves.decelerate,
),
);
_controller.duration = Duration(milliseconds: (tFinal * 1000).round());
_animation!.addListener(_handleInertiaAnimation);
@@ -956,7 +961,7 @@ class _InteractiveViewerState extends State<InteractiveViewer>
begin: scale,
end: frictionSimulation.x(tFinal),
).animate(
CurvedAnimation(
_curvedScaleAnimation ??= CurvedAnimation(
parent: _scaleController,
curve: Curves.decelerate,
),
@@ -1150,7 +1155,9 @@ class _InteractiveViewerState extends State<InteractiveViewer>
@override
void dispose() {
_curvedAnimation?.dispose();
_controller.dispose();
_curvedScaleAnimation?.dispose();
_scaleController.dispose();
_transformer.removeListener(_handleTransformation);
if (widget.transformationController == null) {