diff --git a/mwp/lib/main.dart b/mwp/lib/main.dart index 0fa454e..b4eab19 100644 --- a/mwp/lib/main.dart +++ b/mwp/lib/main.dart @@ -80,94 +80,3 @@ class _MyTooltipState extends State { ); } } - -class Window extends StatefulWidget { - const Window({super.key, this.controller, required this.child}); - - final Widget child; - final WindowController? controller; - - @override - State createState() => _WindowState(); -} - -class _WindowState extends State { - FlutterWindow? _window; - bool _windowNeedsConfigurationUpdate = false; - - @override - void initState() { - super.initState(); - widget.controller?.addListener(_handleWindowConfigurationChange); - _createWindow(); - } - - // TODO: didUpdateWidget (changing controller). - - void _handleWindowConfigurationChange() { - if (_window == null) { - _windowNeedsConfigurationUpdate = true; - } else { - _window!.configuration = widget.controller!.toConfiguration(); - } - } - - Future _createWindow() async { - final FlutterWindow window = await WindowingAPI.createWindow( - widget.controller?.toConfiguration() ?? WindowConfiguration(), - ); - if (!mounted) { - window.dispose(); - return; - } - setState(() { - _window = window; - }); - if (_windowNeedsConfigurationUpdate) { - _windowNeedsConfigurationUpdate = false; - _window!.configuration = widget.controller!.toConfiguration(); - } - - // TODO: Connect the window with the window controller. - } - - @override - void dispose() { - super.dispose(); - _window?.dispose(); - } - - @override - Widget build(BuildContext context) { - if (_window == null) { - // TODO: This doesn't work since there is no render tree to attach this to. - return const SizedBox(); - } - return View( - view: _window!.view, - child: widget.child, - ); - } -} - -abstract class WindowController implements Listenable { - WindowConfiguration toConfiguration(); -} - -class WindowConfiguration { - -} - -// Lower level API. - -class WindowingAPI { - static Future createWindow(WindowConfiguration config) async { - - } -} - -abstract class FlutterWindow { - FlutterView get view; // class could also extend FlutterView - WindowConfiguration configuration; - void dispose(); -} diff --git a/mwp/lib/window.dart b/mwp/lib/window.dart new file mode 100644 index 0000000..6f5733a --- /dev/null +++ b/mwp/lib/window.dart @@ -0,0 +1,98 @@ +import 'package:flutter/material.dart'; + +class Window extends StatefulWidget { + const Window({super.key, this.controller, required this.child}); + + final Widget child; + final WindowController? controller; + + @override + State createState() => _WindowState(); +} + +class _WindowState extends State { + FlutterWindow? _window; + bool _pendingConfigurationUpdate = false; + + @override + void initState() { + super.initState(); + widget.controller?._attach(this); + _createWindow(); + } + + // TODO: didUpdateWidget (changing controller). + + void _handleWindowConfigurationChange() { + if (_window == null) { + _windowNeedsConfigurationUpdate = true; + } else { + _window!.configuration = widget.controller!.toConfiguration(); + } + } + + Future _createWindow() async { + final FlutterWindow window = await WindowingAPI.createWindow( + widget.controller?._configuration ?? WindowConfiguration(), + ); + if (!mounted) { + window.dispose(); + return; + } + setState(() { + _window = window; + }); + if (_windowNeedsConfigurationUpdate) { + _windowNeedsConfigurationUpdate = false; + _window!.configuration = widget.controller!.toConfiguration(); + } + + // TODO: Connect the window with the window controller. + } + + @override + void dispose() { + super.dispose(); + _window?.dispose(); + } + + @override + Widget build(BuildContext context) { + if (_window == null) { + // TODO: This doesn't work since there is no render tree to attach this to. + return const SizedBox(); + } + return View( + view: _window!.view, + child: widget.child, + ); + } +} + +abstract class WindowController implements Listenable { + WindowController({ + +}); + +WindowConfiguration _configuration; + +void requestUpdate +} + +class WindowConfiguration { + +} + +// Lower level API. + +class WindowingAPI { + static Future createWindow(WindowConfiguration config) async { + + } +} + +abstract class FlutterWindow { + FlutterView get view; // class could also extend FlutterView + WindowConfiguration configuration; + void dispose(); +} diff --git a/mwp/lib/window2.dart b/mwp/lib/window2.dart new file mode 100644 index 0000000..5f53146 --- /dev/null +++ b/mwp/lib/window2.dart @@ -0,0 +1,49 @@ +import 'package:flutter/material.dart'; + +class Window extends StatefulWidget { + const Window({super.key, this.controller, required this.child}); + + final WindowController? controller; + final Widget child; + + @override + State createState() => _WindowState(); +} + +class _WindowState extends State { + @override + Widget build(BuildContext context) { + return const Placeholder(); + } +} + +class WindowController extends ChangeNotifier { + WindowController({ + BoxConstraints constraints = const BoxConstraints.tightFor(width: 400, height: 800), + }) : _requestedConfiguration = _WindowConfigurationRequest(constraints: constraints); + + _WindowConfigurationRequest _requestedConfiguration; + _WindowConfiguration? _configuration; + + bool get isAttached => _configuration != null; + + Size get size => _configuration!.size; +} + +@immutable +class _WindowConfigurationRequest { + const _WindowConfigurationRequest({ + this.constraints, + }); + + final BoxConstraints? constraints; +} + +@immutable +class _WindowConfiguration { + const _WindowConfiguration({ + required this.size, + }); + + final Size size; +} diff --git a/mwp/test/widget_test.dart b/mwp/test/widget_test.dart index a20a2a0..4206eba 100644 --- a/mwp/test/widget_test.dart +++ b/mwp/test/widget_test.dart @@ -1,7 +1,10 @@ +import 'package:flutter/cupertino.dart'; import 'package:flutter_test/flutter_test.dart'; void main() { testWidgets('Counter increments smoke test', (WidgetTester tester) async { expect(1, 1); + tester.pumpWidget(const Placeholder(), null, EnginePhase.build); + tester.pumpWidget(); }); }