diff --git a/lib/src/presentation/widgets/clickable_widget.dart b/lib/src/presentation/widgets/clickable_widget.dart index 55528af..d411ec8 100644 --- a/lib/src/presentation/widgets/clickable_widget.dart +++ b/lib/src/presentation/widgets/clickable_widget.dart @@ -1,6 +1,7 @@ import 'package:flutter/material.dart'; +import 'package:jplayer/src/presentation/utils/utils.dart'; -class ClickableWidget extends StatelessWidget { +class ClickableWidget extends StatefulWidget { const ClickableWidget({ required this.child, this.textStyle, @@ -12,32 +13,60 @@ class ClickableWidget extends StatelessWidget { final TextStyle? textStyle; final VoidCallback? onPressed; + @override + State createState() => _ClickableWidgetState(); +} + +class _ClickableWidgetState extends State { + final _isActive = ValueNotifier(false); + + late DeviceType _device; + + @override + void didChangeDependencies() { + super.didChangeDependencies(); + _device = DeviceType.fromScreenSize(MediaQuery.sizeOf(context)); + } + @override Widget build(BuildContext context) { - return Focus( - canRequestFocus: true, - child: StatefulBuilder( - builder: (context, setState) { - final focusNode = Focus.of(context); - return DefaultTextStyle( - style: TextStyle( - decoration: focusNode.hasFocus - ? TextDecoration.underline - : TextDecoration.none, - decorationColor: textStyle?.color, - ).merge(textStyle), - child: GestureDetector( - onTap: onPressed, - onTapDown: (_) { - if (focusNode.canRequestFocus) setState(focusNode.requestFocus); - }, - onTapUp: (_) => setState(focusNode.unfocus), - onTapCancel: () => setState(focusNode.unfocus), - child: child, - ), - ); - }, + final child = ValueListenableBuilder( + valueListenable: _isActive, + builder: (context, isActive, child) => DefaultTextStyle( + style: TextStyle( + decoration: isActive ? TextDecoration.underline : TextDecoration.none, + decorationColor: widget.textStyle?.color, + ).merge(widget.textStyle), + child: widget.child, ), ); + + if (_device.isDesktop) { + return MouseRegion( + cursor: (widget.onPressed != null) + ? WidgetStateMouseCursor.clickable + : MouseCursor.defer, + onHover: (_) => _isActive.value = true, + onExit: (_) => _isActive.value = false, + child: GestureDetector( + onTap: widget.onPressed, + child: child, + ), + ); + } else { + return GestureDetector( + onTap: widget.onPressed, + onTapDown: (_) => _isActive.value = true, + onTapUp: (_) => _isActive.value = false, + onTapCancel: () => _isActive.value = false, + child: child, + ); + } + } + + @override + void dispose() { + _isActive.dispose(); + super.dispose(); } }