extend ClideTappable with press/longpress, retrofit button + rail
ClideTappable builder now receives (context, hovered, pressed). Optional onLongPress and onPressChanged callbacks. ClideButton is now a StatelessWidget wrapping ClideTappable. ClideIconRail refactored — _RailButton uses ClideTappable with tooltip. ClideTooltip positions smart (above when near screen bottom). Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -1,16 +1,23 @@
|
||||
import 'package:clide/widgets/src/clide_tooltip.dart';
|
||||
import 'package:flutter/widgets.dart';
|
||||
|
||||
class ClideTappable extends StatefulWidget {
|
||||
const ClideTappable({
|
||||
super.key,
|
||||
required this.onTap,
|
||||
required this.builder,
|
||||
this.onTap,
|
||||
this.onLongPress,
|
||||
this.onPressChanged,
|
||||
this.cursor = SystemMouseCursors.click,
|
||||
this.tooltip,
|
||||
});
|
||||
|
||||
final VoidCallback onTap;
|
||||
final Widget Function(BuildContext context, bool hovered) builder;
|
||||
final Widget Function(BuildContext context, bool hovered, bool pressed) builder;
|
||||
final VoidCallback? onTap;
|
||||
final VoidCallback? onLongPress;
|
||||
final ValueChanged<bool>? onPressChanged;
|
||||
final MouseCursor cursor;
|
||||
final String? tooltip;
|
||||
|
||||
@override
|
||||
State<ClideTappable> createState() => _ClideTappableState();
|
||||
@@ -18,18 +25,36 @@ class ClideTappable extends StatefulWidget {
|
||||
|
||||
class _ClideTappableState extends State<ClideTappable> {
|
||||
bool _hover = false;
|
||||
bool _pressed = false;
|
||||
|
||||
void _setPressed(bool v) {
|
||||
if (_pressed == v) return;
|
||||
setState(() => _pressed = v);
|
||||
widget.onPressChanged?.call(v);
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return MouseRegion(
|
||||
Widget child = MouseRegion(
|
||||
cursor: widget.cursor,
|
||||
onEnter: (_) => setState(() => _hover = true),
|
||||
onExit: (_) => setState(() => _hover = false),
|
||||
onExit: (_) {
|
||||
setState(() => _hover = false);
|
||||
_setPressed(false);
|
||||
},
|
||||
child: GestureDetector(
|
||||
behavior: HitTestBehavior.opaque,
|
||||
onTap: widget.onTap,
|
||||
child: widget.builder(context, _hover),
|
||||
onLongPress: widget.onLongPress,
|
||||
onTapDown: (_) => _setPressed(true),
|
||||
onTapUp: (_) => _setPressed(false),
|
||||
onTapCancel: () => _setPressed(false),
|
||||
child: widget.builder(context, _hover, _pressed),
|
||||
),
|
||||
);
|
||||
if (widget.tooltip != null) {
|
||||
child = ClideTooltip(message: widget.tooltip!, child: child);
|
||||
}
|
||||
return child;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user