feat(flutter): add multitouch support (#10688) d5e74de08c

fix(vulkan): Correctly support Vulkan 1.0 on Android (#10679) 8e0fadf978
VkBootstrap will incorrecty error with `vulkan_version_1_1_unavailable` on Vulkan 1.0 systems that do not have the vkEnumerateInstanceVersion function, even when we specifically said that it was fine to fall back to 1.0. To work around this, we will detect that error and then try again to create the Vulkan instance, specifically requesting version 1.0.

Additionally fix a "function must return" error when building in MSVC on Windows, and update LOG_ERROR to be LOG_ERROR_LINE to make it clear that it writes lines (and update its use of fprintf to match what the android logging does)

chore: Rename draw_clockwise_* shaders to draw_clockwise_atomic_* (#10689) 7e676124de
The interlock mode these shaders implement is clockwiseAtomic. Let's be
more specific with the naming so we can support other clockwise modes.

Co-authored-by: Gordon <pggordonhayes@gmail.com>
This commit is contained in:
HayesGordon
2025-10-02 11:59:27 +00:00
parent bc2f8e8d53
commit 6da3205de4
7 changed files with 51 additions and 6 deletions

View File

@ -1 +1 @@
2f8251e8b9b9b98ae61144c3be87cb970db2e35e
d5e74de08cf60ca51715c034727c840cda6e683f

View File

@ -2,6 +2,7 @@
Bumps to `rive_native: 0.0.12`. Updates the Rive C++ runtime and renderer for the latest features, bug fixes, and performance improvements.
- Added multi-touch support
- Reduced the number of texture allocations made when resizing widgets using `Factory.rive`, improving memory efficiency and performance.
- Enhanced painting and texture creation behavior when resizing widgets or windows with `Factory.rive`, resulting in smoother widget resizing.
- Better aligned the native and web implementations to ensure consistent behavior across all platforms.

Binary file not shown.

View File

@ -6,6 +6,7 @@ export 'databinding_lists.dart';
export 'events.dart';
export 'hit_test_behaviour.dart';
export 'inputs.dart';
export 'multi_touch.dart';
export 'pause_play.dart';
export 'network_asset.dart';
export 'out_of_band_assets.dart';

View File

@ -0,0 +1,41 @@
import 'package:flutter/material.dart';
import 'package:rive/rive.dart';
import 'package:rive_example/main.dart' show RiveExampleApp;
class ExampleMultiTouch extends StatefulWidget {
const ExampleMultiTouch({super.key});
@override
State<ExampleMultiTouch> createState() => _ExampleMultiTouchState();
}
class _ExampleMultiTouchState extends State<ExampleMultiTouch> {
FileLoader fileLoader = FileLoader.fromAsset(
'assets/multitouch.riv',
riveFactory: RiveExampleApp.getCurrentFactory,
);
@override
void dispose() {
fileLoader.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return RiveWidgetBuilder(
fileLoader: fileLoader,
dataBind: DataBind.auto(),
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)
},
);
}
}

View File

@ -128,6 +128,8 @@ class _RiveExampleAppState extends State<RiveExampleApp> {
'Rive graphics respect Flutter time dilation.'),
_Page('Flutter Transform', ExampleTransform(),
'Rive graphics respect Flutter transform.'),
_Page('Flutter Multi Touch', ExampleMultiTouch(),
'Rive graphics respect Flutter multi touch.'),
// _Page('Flutter Hero Transitions', Todo(),
// 'Create smooth transitions between pages with Rive graphics.'),
// _Page('Flutter State Management', Todo(),

View File

@ -170,15 +170,15 @@ base class RiveWidgetController extends BasicArtboardPainter
);
final HitResult hitResult;
if (event is PointerDownEvent) {
hitResult = stateMachine.pointerDown(position);
hitResult = stateMachine.pointerDown(position, pointerId: event.pointer);
} else if (event is PointerUpEvent) {
hitResult = stateMachine.pointerUp(position);
hitResult = stateMachine.pointerUp(position, pointerId: event.pointer);
} else if (event is PointerMoveEvent) {
hitResult = stateMachine.pointerMove(position);
hitResult = stateMachine.pointerMove(position, pointerId: event.pointer);
} else if (event is PointerHoverEvent) {
hitResult = stateMachine.pointerMove(position);
hitResult = stateMachine.pointerMove(position, pointerId: event.pointer);
} else if (event is PointerExitEvent) {
hitResult = stateMachine.pointerExit(position);
hitResult = stateMachine.pointerExit(position, pointerId: event.pointer);
} else {
hitResult = HitResult.none;
}