import 'package:flutter/material.dart'; import 'package:rive/rive.dart'; import 'package:rive_example/main.dart'; class ExampleHitTestBehaviour extends StatefulWidget { const ExampleHitTestBehaviour({super.key}); @override State createState() => _ExampleHitTestBehaviourState(); } class _ExampleHitTestBehaviourState extends State { FileLoader fileLoader = FileLoader.fromAsset( 'assets/button.riv', riveFactory: RiveExampleApp.getCurrentFactory, ); int count = 0; RiveHitTestBehavior hitTestBehavior = RiveHitTestBehavior.opaque; MouseCursor cursor = MouseCursor.defer; @override void dispose() { fileLoader.dispose(); super.dispose(); } @override Widget build(BuildContext context) { return Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Expanded( child: Stack( children: [ Center( child: MouseRegion( cursor: SystemMouseCursors.copy, child: GestureDetector( onTap: () { setState(() { count++; }); }, child: Container( width: 300, height: 300, color: Colors.red, ), ), ), ), Center( child: MouseRegion( opaque: true, cursor: SystemMouseCursors.click, hitTestBehavior: HitTestBehavior.deferToChild, child: RiveWidgetBuilder( fileLoader: fileLoader, builder: (context, state) => switch (state) { RiveLoading() => const Center( child: Center(child: CircularProgressIndicator()), ), RiveFailed() => ErrorWidget.withDetails( message: state.error.toString(), error: FlutterError(state.error.toString()), ), RiveLoaded() => RiveWidget( controller: state.controller, hitTestBehavior: hitTestBehavior, cursor: cursor, ) }, ), ), ), ], ), ), Padding( padding: const EdgeInsets.all(8.0), child: Text('Underlying Flutter container tapped: $count'), ), Padding( padding: const EdgeInsets.all(8.0), child: Text('Current hit test behaviour: $hitTestBehavior'), ), Padding( padding: const EdgeInsets.all(8.0), child: Wrap( spacing: 8, runSpacing: 8, crossAxisAlignment: WrapCrossAlignment.start, children: [ ElevatedButton( onPressed: () { setState(() { hitTestBehavior = RiveHitTestBehavior.none; }); }, child: const Text('none'), ), ElevatedButton( onPressed: () { setState(() { hitTestBehavior = RiveHitTestBehavior.opaque; }); }, child: const Text('opaque'), ), ElevatedButton( onPressed: () { setState(() { hitTestBehavior = RiveHitTestBehavior.translucent; }); }, child: const Text('translucent'), ), ElevatedButton( onPressed: () { setState(() { hitTestBehavior = RiveHitTestBehavior.transparent; }); }, child: const Text('transparent'), ) ], ), ), Padding( padding: const EdgeInsets.all(8.0), child: Text('Current mouse cursor: $cursor'), ), Expanded( child: Padding( padding: const EdgeInsets.all(8.0), child: Wrap( spacing: 8, runSpacing: 8, alignment: WrapAlignment.spaceAround, children: [ ElevatedButton( onPressed: () { setState(() { cursor = MouseCursor.defer; }); }, child: const Text('defer'), ), ElevatedButton( onPressed: () { setState(() { cursor = MouseCursor.uncontrolled; }); }, child: const Text('unconrolled'), ), ElevatedButton( onPressed: () { setState(() { cursor = SystemMouseCursors.contextMenu; }); }, child: const Text('context menu'), ), ElevatedButton( onPressed: () { setState(() { cursor = SystemMouseCursors.text; }); }, child: const Text('text'), ), ], ), ), ) ], ); } }