chore: rearrange library/export structure

This commit is contained in:
Nick Fisher
2024-09-26 16:35:33 +08:00
parent f023810859
commit 3dffaddfe8
74 changed files with 119 additions and 810 deletions

View File

@@ -8,7 +8,7 @@ import 'package:thermion_flutter_platform_interface/thermion_flutter_texture.dar
/// Handles all platform-specific initialization to create a backing rendering
/// surface in a Flutter application and lifecycle listeners to pause rendering
/// when the app is inactive or in the background.
/// Call [createViewer] to create an instance of [ThermionViewer].
/// Call [createViewerWithOptions] to create an instance of [ThermionViewer].
///
class ThermionFlutterPlugin {
ThermionFlutterPlugin._();

View File

@@ -1,5 +1,6 @@
import 'package:thermion_dart/thermion_dart/thermion_viewer.dart';import 'package:flutter/material.dart';
import 'package:thermion_dart/thermion_dart.dart';
import 'package:flutter/material.dart';
import '../../../utils/camera_orientation.dart';
import 'dart:math';

View File

@@ -1,28 +0,0 @@
// import 'package:flutter/widgets.dart';
// import 'package:thermion_dart/thermion_dart/input/input_handler.dart';
// class MobileGestureHandlerSelectorWidget extends StatelessWidget {
// final InputHandler handler;
// const MobileGestureHandlerSelectorWidget({super.key, required this.handler});
// @override
// Widget build(BuildContext context) {
// throw Exception("TODO");
// // return GestureDetector(
// // onTap: () {
// // var curIdx =
// // InputType.values.indexOf(handler.gestureType);
// // var nextIdx =
// // curIdx == InputType.values.length - 1 ? 0 : curIdx + 1;
// // handler.setInputType(InputType.values[nextIdx]);
// // });
// // },
// // child: Container(
// // padding: const EdgeInsets.all(50),
// // child: Icon(_icons[widget.gestureHandler.gestureType],
// // color: Colors.green),
// // ),
// // );
// }
// }

View File

@@ -1,86 +0,0 @@
import 'package:thermion_dart/thermion_dart/thermion_viewer.dart';
import 'package:flutter/material.dart';
///
/// A widget that translates finger/mouse gestures to zoom/pan/rotate actions.
///
@Deprecated("Use ThermionListenerWidget instead")
class ThermionGestureDetector extends StatelessWidget {
///
/// The content to display below the gesture detector/listener widget.
/// This will usually be a ThermionWidget (so you can navigate by directly interacting with the viewport), but this is not necessary.
/// It is equally possible to render the viewport/gesture controls elsewhere in the widget hierarchy. The only requirement is that they share the same [FilamentController].
///
final Widget? child;
///
/// The [controller] attached to the [ThermionWidget] you wish to control.
///
final ThermionViewer controller;
///
/// If true, an overlay will be shown with buttons to toggle whether pointer movements are interpreted as:
/// 1) rotate or a pan (mobile only),
/// 2) moving the camera or the background image (TODO).
///
final bool showControlOverlay;
///
/// If false, gestures will not manipulate the active camera.
///
final bool enableCamera;
///
/// If false, pointer down events will not trigger hit-testing (picking).
///
final bool enablePicking;
final void Function(ScaleStartDetails)? onScaleStart;
final void Function(ScaleUpdateDetails)? onScaleUpdate;
final void Function(ScaleEndDetails)? onScaleEnd;
const ThermionGestureDetector(
{Key? key,
required this.controller,
this.child,
this.showControlOverlay = false,
this.enableCamera = true,
this.enablePicking = false,
this.onScaleStart,
this.onScaleUpdate,
this.onScaleEnd})
: super(key: key);
@override
Widget build(BuildContext context) {
throw Exception("TODO");
// return FutureBuilder(
// future: controller.initialized,
// builder: (_, initialized) {
// if (initialized.data != true) {
// return child ?? Container();
// }
// if (kIsWeb || Platform.isLinux ||
// Platform.isWindows ||
// Platform.isMacOS) {
// return ThermionGestureDetectorDesktop(
// controller: controller,
// child: child,
// showControlOverlay: showControlOverlay,
// enableCamera: enableCamera,
// enablePicking: enablePicking,
// );
// } else {
// return ThermionGestureDetectorMobile(
// controller: controller,
// child: child,
// showControlOverlay: showControlOverlay,
// enableCamera: enableCamera,
// enablePicking: enablePicking,
// onScaleStart: onScaleStart,
// onScaleUpdate: onScaleUpdate,
// onScaleEnd: onScaleEnd);
// }
// });
}
}

View File

@@ -1,60 +0,0 @@
// import 'package:thermion_dart/thermion_dart.dart';
// import 'package:flutter/gestures.dart';
// import 'package:flutter/material.dart';
// import 'package:vector_math/vector_math_64.dart';
// import 'dart:ui' show Offset;
// extension OffsetExtension on Offset {
// Vector2 toVector2() {
// return Vector2(dx, dy);
// }
// }
// class ThermionGestureDetectorDesktop extends StatefulWidget {
// final Widget? child;
// final InputHandler gestureHandler;
// final bool showControlOverlay;
// final bool enableCamera;
// final bool enablePicking;
// const ThermionGestureDetectorDesktop({
// Key? key,
// required this.gestureHandler,
// this.child,
// this.showControlOverlay = false,
// this.enableCamera = true,
// this.enablePicking = true,
// }) : super(key: key);
// @override
// State<StatefulWidget> createState() => _ThermionGestureDetectorDesktopState();
// }
// class _ThermionGestureDetectorDesktopState
// extends State<ThermionGestureDetectorDesktop> {
// @override
// Widget build(BuildContext context) {
// return Listener(
// onPointerHover: (event) =>
// widget.gestureHandler.onPointerHover(event.localPosition.toVector2(), event.delta.toVector2()),
// onPointerSignal: (PointerSignalEvent pointerSignal) {
// if (pointerSignal is PointerScrollEvent) {
// widget.gestureHandler.onPointerScroll(
// pointerSignal.localPosition.toVector2(), pointerSignal.scrollDelta.dy);
// }
// },
// onPointerPanZoomStart: (pzs) {
// throw Exception("TODO - is this a pinch zoom on laptop trackpad?");
// },
// onPointerDown: (d) =>
// widget.gestureHandler.onPointerDown(d.localPosition.toVector2(), d.buttons & kMiddleMouseButton != 0),
// onPointerMove: (PointerMoveEvent d) =>
// widget.gestureHandler.onPointerMove(d.localPosition.toVector2(), d.delta.toVector2(), d.buttons & kMiddleMouseButton != 0),
// onPointerUp: (d) => widget.gestureHandler.onPointerUp(d.buttons),
// child: widget.child,
// );
// }
// }

View File

@@ -1,234 +0,0 @@
import 'dart:async';
import 'package:thermion_dart/thermion_dart/thermion_viewer.dart';
import 'package:flutter/material.dart';
enum InputType { rotateCamera, panCamera, panBackground }
///
/// A widget that translates finger/mouse gestures to zoom/pan/rotate actions.
///
class ThermionGestureDetectorMobile extends StatefulWidget {
///
/// The content to display below the gesture detector/listener widget.
/// This will usually be a ThermionWidget (so you can navigate by directly interacting with the viewport), but this is not necessary.
/// It is equally possible to render the viewport/gesture controls elsewhere in the widget hierarchy. The only requirement is that they share the same [Filamentviewer].
///
final Widget? child;
///
/// The [viewer] attached to the [ThermionWidget] you wish to control.
///
final ThermionViewer viewer;
///
/// If true, an overlay will be shown with buttons to toggle whether pointer movements are interpreted as:
/// 1) rotate or a pan (mobile only),
/// 2) moving the camera or the background image (TODO).
///
final bool showControlOverlay;
///
/// If false, gestures will not manipulate the active camera.
///
final bool enableCamera;
///
/// If false, pointer down events will not trigger hit-testing (picking).
///
final bool enablePicking;
final double zoomDelta;
final void Function(ScaleStartDetails)? onScaleStart;
final void Function(ScaleUpdateDetails)? onScaleUpdate;
final void Function(ScaleEndDetails)? onScaleEnd;
const ThermionGestureDetectorMobile(
{Key? key,
required this.viewer,
this.child,
this.showControlOverlay = false,
this.enableCamera = true,
this.enablePicking = true,
this.onScaleStart,
this.onScaleUpdate,
this.onScaleEnd,
this.zoomDelta = 1})
: super(key: key);
@override
State<StatefulWidget> createState() => _ThermionGestureDetectorMobileState();
}
class _ThermionGestureDetectorMobileState
extends State<ThermionGestureDetectorMobile> {
InputType gestureType = InputType.panCamera;
final _icons = {
InputType.panBackground: Icons.image,
InputType.panCamera: Icons.pan_tool,
InputType.rotateCamera: Icons.rotate_90_degrees_ccw
};
// on mobile, we can't differentiate between pointer down events like we do on desktop with primary/secondary/tertiary buttons
// we allow the user to toggle between panning and rotating by double-tapping the widget
bool _rotateOnPointerMove = false;
//
//
//
bool _scaling = false;
// to avoid duplicating code for pan/rotate (panStart, panUpdate, panEnd, rotateStart, rotateUpdate etc)
// we have only a single function for start/update/end.
// when the gesture type is changed, these properties are updated to point to the correct function.
// ignore: unused_field
late Function(double x, double y) _functionStart;
// ignore: unused_field
late Function(double x, double y) _functionUpdate;
// ignore: unused_field
late Function() _functionEnd;
@override
void initState() {
_setFunction();
super.initState();
}
void _setFunction() {
switch (gestureType) {
case InputType.rotateCamera:
_functionStart = widget.viewer.rotateStart;
_functionUpdate = widget.viewer.rotateUpdate;
_functionEnd = widget.viewer.rotateEnd;
break;
case InputType.panCamera:
_functionStart = widget.viewer.panStart;
_functionUpdate = widget.viewer.panUpdate;
_functionEnd = widget.viewer.panEnd;
break;
// TODO
case InputType.panBackground:
_functionStart = (x, y) async {};
_functionUpdate = (x, y) async {};
_functionEnd = () async {};
}
}
@override
void didUpdateWidget(ThermionGestureDetectorMobile oldWidget) {
if (widget.showControlOverlay != oldWidget.showControlOverlay ||
widget.enableCamera != oldWidget.enableCamera ||
widget.enablePicking != oldWidget.enablePicking) {
setState(() {});
}
super.didUpdateWidget(oldWidget);
}
// ignore: unused_field
Timer? _scrollTimer;
double _lastScale = 0;
// pinch zoom on mobile
// couldn't find any equivalent for pointerCount in Listener (?) so we use a GestureDetector
@override
Widget build(BuildContext context) {
return Stack(children: [
Positioned.fill(
child: GestureDetector(
behavior: HitTestBehavior.translucent,
onTapDown: (d) {
if (!widget.enablePicking) {
return;
}
widget.viewer.pick(
d.globalPosition.dx.toInt(), d.globalPosition.dy.toInt());
},
onDoubleTap: () {
setState(() {
_rotateOnPointerMove = !_rotateOnPointerMove;
});
},
onScaleStart: (d) async {
if (widget.onScaleStart != null) {
widget.onScaleStart!.call(d);
return;
}
if (d.pointerCount == 2 && widget.enableCamera) {
_scaling = true;
await widget.viewer.zoomBegin();
} else if (!_scaling && widget.enableCamera) {
if (_rotateOnPointerMove) {
widget.viewer.rotateStart(
d.localFocalPoint.dx, d.localFocalPoint.dy);
} else {
widget.viewer
.panStart(d.localFocalPoint.dx, d.localFocalPoint.dy);
}
}
},
onScaleUpdate: (ScaleUpdateDetails d) async {
if (widget.onScaleUpdate != null) {
widget.onScaleUpdate!.call(d);
return;
}
if (d.pointerCount == 2 && widget.enableCamera) {
if (d.horizontalScale != _lastScale) {
widget.viewer.zoomUpdate(
d.localFocalPoint.dx,
d.localFocalPoint.dy,
d.horizontalScale > _lastScale ? 0.1 : -0.1);
_lastScale = d.horizontalScale;
}
} else if (!_scaling && widget.enableCamera) {
if (_rotateOnPointerMove) {
widget.viewer
.rotateUpdate(d.focalPoint.dx, d.focalPoint.dy);
} else {
widget.viewer
.panUpdate(d.focalPoint.dx, d.focalPoint.dy);
}
}
},
onScaleEnd: (d) async {
if (widget.onScaleEnd != null) {
widget.onScaleEnd!.call(d);
return;
}
if (d.pointerCount == 2 && widget.enableCamera) {
widget.viewer.zoomEnd();
} else if (!_scaling && widget.enableCamera) {
if (_rotateOnPointerMove) {
widget.viewer.rotateEnd();
} else {
widget.viewer.panEnd();
}
}
_scaling = false;
},
child: widget.child)),
widget.showControlOverlay
? Align(
alignment: Alignment.bottomRight,
child: GestureDetector(
onTap: () {
setState(() {
var curIdx = InputType.values.indexOf(gestureType);
var nextIdx = curIdx == InputType.values.length - 1
? 0
: curIdx + 1;
gestureType = InputType.values[nextIdx];
_setFunction();
});
},
child: Container(
padding: const EdgeInsets.all(50),
child: Icon(_icons[gestureType], color: Colors.green)),
))
: Container()
]);
}
}

View File

@@ -1,5 +1,5 @@
import 'package:animation_tools_dart/animation_tools_dart.dart';
import 'package:thermion_dart/thermion_dart/thermion_viewer.dart';
import 'package:thermion_dart/thermion_dart.dart';
import 'package:flutter/material.dart';
import 'dart:math';

View File

@@ -1,7 +1,6 @@
import 'dart:math';
import 'package:thermion_dart/thermion_dart.dart';
import 'package:thermion_dart/thermion_dart/thermion_viewer.dart';
import 'package:animation_tools_dart/animation_tools_dart.dart';
import 'package:flutter/material.dart';
import 'package:flutter/widgets.dart';

View File

@@ -1,6 +1,6 @@
import 'dart:math';
import 'package:thermion_dart/thermion_dart/thermion_viewer.dart';
import 'package:flutter/material.dart';
import 'package:thermion_dart/thermion_dart.dart';
import 'package:vector_math/vector_math_64.dart' as v;
class IblRotationSliderWidget extends StatefulWidget {

View File

@@ -1,4 +1,4 @@
library;
export 'src/thermion_widget.dart';
export 'src/camera/gestures/thermion_listener_widget.dart';
export 'src/thermion_listener_widget.dart';

View File

@@ -2,7 +2,7 @@ import 'dart:async';
import 'package:flutter/services.dart';
import 'dart:ffi';
import 'package:thermion_dart/thermion_dart.dart';
import 'package:thermion_dart/thermion_dart/viewer/ffi/thermion_viewer_ffi.dart';
import 'package:thermion_dart/src/viewer/src/ffi/thermion_viewer_ffi.dart';
import 'package:thermion_flutter_platform_interface/thermion_flutter_platform_interface.dart';
import 'package:thermion_flutter_platform_interface/thermion_flutter_texture.dart';
import 'package:logging/logging.dart';

View File

@@ -1,7 +1,7 @@
import 'dart:async';
import 'package:thermion_dart/thermion_dart/thermion_viewer.dart';
import 'package:plugin_platform_interface/plugin_platform_interface.dart';
import 'package:thermion_dart/thermion_dart.dart';
import 'thermion_flutter_texture.dart';
class ThermionFlutterOptions {

View File

@@ -1,5 +1,4 @@
import 'package:thermion_dart/thermion_dart/thermion_viewer.dart';
import 'package:thermion_dart/thermion_dart/viewer/web_wasm/src/thermion_viewer_wasm.dart';
import 'package:thermion_dart/thermion_dart.dart';
import 'package:thermion_flutter_platform_interface/thermion_flutter_platform_interface.dart';
import 'package:thermion_flutter_platform_interface/thermion_flutter_texture.dart';
import 'package:flutter_web_plugins/flutter_web_plugins.dart';