render directly to Texture rather than PlatformView (Android only)
This commit is contained in:
@@ -5,7 +5,10 @@ import 'package:flutter/services.dart';
|
||||
typedef FilamentAsset = int;
|
||||
|
||||
abstract class FilamentController {
|
||||
void onFilamentViewCreated(int id);
|
||||
|
||||
late int textureId;
|
||||
Future initialize(int width, int height);
|
||||
Future resize(int width, int height);
|
||||
Future setBackgroundImage(String path);
|
||||
Future loadSkybox(String skyboxPath);
|
||||
Future removeSkybox();
|
||||
@@ -45,28 +48,24 @@ abstract class FilamentController {
|
||||
}
|
||||
|
||||
class PolyvoxFilamentController extends FilamentController {
|
||||
late int _id;
|
||||
late MethodChannel _channel;
|
||||
|
||||
final Function(int id)? onFilamentViewCreatedHandler;
|
||||
late MethodChannel _channel = MethodChannel("app.polyvox.filament/event");
|
||||
|
||||
PolyvoxFilamentController({this.onFilamentViewCreatedHandler});
|
||||
|
||||
@override
|
||||
void onFilamentViewCreated(int id) async {
|
||||
_id = id;
|
||||
_channel = MethodChannel("app.polyvox.filament/filament_view_$id");
|
||||
PolyvoxFilamentController() {
|
||||
_channel.setMethodCallHandler((call) async {
|
||||
print("Received Filament method channel call : ${call.method}");
|
||||
if (call.method == "ready") {
|
||||
onFilamentViewCreatedHandler?.call(_id);
|
||||
return Future.value(true);
|
||||
} else {
|
||||
throw Exception("Unknown method channel invocation ${call.method}");
|
||||
}
|
||||
throw Exception("Unknown method channel invocation ${call.method}");
|
||||
});
|
||||
}
|
||||
|
||||
Future initialize(int width, int height) async {
|
||||
textureId = await _channel.invokeMethod("initialize", [width, height]);
|
||||
}
|
||||
|
||||
Future resize(int width, int height) async {
|
||||
await _channel.invokeMethod("resize", [width, height]);
|
||||
}
|
||||
|
||||
@override
|
||||
Future setBackgroundImage(String path) async {
|
||||
await _channel.invokeMethod("setBackgroundImage", path);
|
||||
|
||||
88
lib/filament_widget.dart
Normal file
88
lib/filament_widget.dart
Normal file
@@ -0,0 +1,88 @@
|
||||
import 'package:flutter/rendering.dart';
|
||||
import 'package:flutter/widgets.dart';
|
||||
import 'filament_controller.dart';
|
||||
|
||||
|
||||
typedef ResizeCallback = void Function(Size oldSize, Size newSize);
|
||||
|
||||
class ResizeObserver extends SingleChildRenderObjectWidget {
|
||||
final ResizeCallback onResized;
|
||||
|
||||
const ResizeObserver({
|
||||
Key? key,
|
||||
required this.onResized,
|
||||
Widget? child,
|
||||
}) : super(
|
||||
key: key,
|
||||
child: child,
|
||||
);
|
||||
|
||||
@override
|
||||
RenderObject createRenderObject(BuildContext context) =>
|
||||
_RenderResizeObserver(onLayoutChangedCallback: onResized);
|
||||
}
|
||||
|
||||
class _RenderResizeObserver extends RenderProxyBox {
|
||||
final ResizeCallback onLayoutChangedCallback;
|
||||
|
||||
_RenderResizeObserver({
|
||||
RenderBox? child,
|
||||
required this.onLayoutChangedCallback,
|
||||
}) : super(child);
|
||||
|
||||
late var _oldSize = size;
|
||||
|
||||
@override
|
||||
void performLayout() {
|
||||
super.performLayout();
|
||||
if (size != _oldSize) {
|
||||
onLayoutChangedCallback(_oldSize, size);
|
||||
_oldSize = size;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class FilamentWidget extends StatefulWidget {
|
||||
|
||||
final FilamentController controller;
|
||||
|
||||
const FilamentWidget({Key? key, required this.controller}) : super(key: key);
|
||||
|
||||
@override
|
||||
_FilamentWidgetState createState() => _FilamentWidgetState();
|
||||
}
|
||||
|
||||
class _FilamentWidgetState extends State<FilamentWidget> {
|
||||
|
||||
bool _ready = false;
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
WidgetsBinding.instance.addPostFrameCallback((timeStamp) async {
|
||||
var size = ((context.findRenderObject()) as RenderBox).size;
|
||||
print("Requesting texture creation for Filament of size $size");
|
||||
await widget.controller.initialize(size.width.toInt(), size.height.toInt());
|
||||
print("Filament texture available");
|
||||
setState(() {
|
||||
_ready = true;
|
||||
});
|
||||
});
|
||||
|
||||
super.initState();
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
if(!_ready) {
|
||||
return Container();
|
||||
}
|
||||
return ResizeObserver(
|
||||
onResized: (Size oldSize, Size newSize) async {
|
||||
await widget.controller.resize(newSize.width.toInt(), newSize.height.toInt());
|
||||
},
|
||||
child:Texture(
|
||||
textureId: widget.controller.textureId,
|
||||
filterQuality: FilterQuality.none,
|
||||
));
|
||||
}
|
||||
}
|
||||
@@ -2,7 +2,7 @@ import 'package:flutter/material.dart';
|
||||
import 'package:flutter/widgets.dart';
|
||||
|
||||
import 'filament_controller.dart';
|
||||
import 'view/filament_widget.dart';
|
||||
import 'filament_widget.dart';
|
||||
|
||||
class GestureDetectingFilamentView extends StatefulWidget {
|
||||
final FilamentController controller;
|
||||
|
||||
@@ -1,39 +0,0 @@
|
||||
import 'package:flutter/foundation.dart';
|
||||
import 'package:flutter/gestures.dart';
|
||||
import 'package:flutter/rendering.dart';
|
||||
import 'package:flutter/widgets.dart';
|
||||
|
||||
import 'filament_view_platform.dart';
|
||||
|
||||
class FilamentView extends FilamentViewPlatform {
|
||||
static const FILAMENT_VIEW_ID = 'app.polyvox.filament/filament_view';
|
||||
|
||||
@override
|
||||
Widget buildView(
|
||||
int creationId,
|
||||
FilamentViewCreatedCallback onFilamentViewCreated,
|
||||
) {
|
||||
switch (defaultTargetPlatform) {
|
||||
case TargetPlatform.android:
|
||||
return AndroidView(
|
||||
viewType: FILAMENT_VIEW_ID,
|
||||
gestureRecognizers: <Factory<OneSequenceGestureRecognizer>>{},
|
||||
hitTestBehavior: PlatformViewHitTestBehavior.opaque,
|
||||
onPlatformViewCreated: (id) {
|
||||
onFilamentViewCreated(id);
|
||||
});
|
||||
case TargetPlatform.iOS:
|
||||
return UiKitView(
|
||||
viewType: FILAMENT_VIEW_ID,
|
||||
onPlatformViewCreated: (int id) {
|
||||
onFilamentViewCreated(id);
|
||||
},
|
||||
);
|
||||
case TargetPlatform.windows:
|
||||
return Text("Flutter doesn't support platform view on Windows yet.");
|
||||
default:
|
||||
return Text(
|
||||
'$defaultTargetPlatform is not yet implemented by Filament plugin.');
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,21 +0,0 @@
|
||||
import 'package:flutter/widgets.dart';
|
||||
import 'package:polyvox_filament/view/filament_view.dart';
|
||||
import 'package:plugin_platform_interface/plugin_platform_interface.dart';
|
||||
|
||||
typedef FilamentViewCreatedCallback = void Function(int id);
|
||||
|
||||
abstract class FilamentViewPlatform extends PlatformInterface {
|
||||
FilamentViewPlatform() : super(token: _token);
|
||||
|
||||
static final Object _token = Object();
|
||||
static final FilamentViewPlatform _instance = FilamentView();
|
||||
|
||||
static FilamentViewPlatform get instance => _instance;
|
||||
|
||||
Widget buildView(
|
||||
int creationId,
|
||||
FilamentViewCreatedCallback onFilamentViewCreated,
|
||||
) {
|
||||
throw UnimplementedError('buildView() has not been implemented.');
|
||||
}
|
||||
}
|
||||
@@ -1,29 +0,0 @@
|
||||
import 'package:flutter/foundation.dart';
|
||||
import 'package:flutter/gestures.dart';
|
||||
import 'package:flutter/rendering.dart';
|
||||
import 'package:flutter/widgets.dart';
|
||||
import 'package:polyvox_filament/view/filament_view.dart';
|
||||
|
||||
import '../filament_controller.dart';
|
||||
import 'filament_view_platform.dart';
|
||||
|
||||
int _nextFilamentCreationId = 0;
|
||||
|
||||
class FilamentWidget extends StatefulWidget {
|
||||
final FilamentController controller;
|
||||
|
||||
const FilamentWidget({Key? key, required this.controller}) : super(key: key);
|
||||
|
||||
@override
|
||||
_FilamentWidgetState createState() => _FilamentWidgetState();
|
||||
}
|
||||
|
||||
class _FilamentWidgetState extends State<FilamentWidget> {
|
||||
final _viewId = _nextFilamentCreationId++;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return FilamentViewPlatform.instance
|
||||
.buildView(_viewId, widget.controller.onFilamentViewCreated);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user