diff --git a/app_flowy/packages/flowy_infra_ui/example/lib/overlay/overlay_screen.dart b/app_flowy/packages/flowy_infra_ui/example/lib/overlay/overlay_screen.dart index ffb702816d..be1779b146 100644 --- a/app_flowy/packages/flowy_infra_ui/example/lib/overlay/overlay_screen.dart +++ b/app_flowy/packages/flowy_infra_ui/example/lib/overlay/overlay_screen.dart @@ -1,5 +1,6 @@ import 'package:flowy_infra_ui/flowy_infra_ui_web.dart'; import 'package:flutter/material.dart'; +import 'package:provider/provider.dart'; import '../home/demo_item.dart'; @@ -19,6 +20,19 @@ class OverlayItem extends DemoItem { } } +class OverlayDemoAnchorDirection extends ChangeNotifier { + OverlayDemoAnchorDirection(this._anchorDirection); + + AnchorDirection _anchorDirection; + + AnchorDirection get anchorDirection => _anchorDirection; + + set anchorDirection(AnchorDirection value) { + _anchorDirection = value; + notifyListeners(); + } +} + class OverlayScreen extends StatelessWidget { const OverlayScreen({Key? key}) : super(key: key); @@ -28,83 +42,99 @@ class OverlayScreen extends StatelessWidget { appBar: AppBar( title: const Text('Overlay Demo'), ), - body: Column( - children: [ - Flexible( - child: Padding( - padding: const EdgeInsets.all(16.0), - child: Container( - height: 300.0, - decoration: BoxDecoration( - borderRadius: BorderRadius.circular(15.0), - color: Colors.grey[200], + body: ChangeNotifierProvider( + create: (context) => OverlayDemoAnchorDirection(AnchorDirection.topLeft), + child: Builder(builder: (context) { + return Column( + children: [ + DropdownButton( + value: context.watch().anchorDirection, + onChanged: (AnchorDirection? newValue) { + if (newValue != null) { + context.read().anchorDirection = newValue; + } + }, + items: AnchorDirection.values.map((AnchorDirection classType) { + return DropdownMenuItem(value: classType, child: Text(classType.toString())); + }).toList(), + ), + Flexible( + child: Padding( + padding: const EdgeInsets.all(16.0), + child: Container( + height: 300.0, + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(15.0), + color: Colors.grey[200], + ), + ), ), ), - ), - ), - ElevatedButton( - onPressed: () { - FlowyOverlay.of(context).insertCustom( - widget: const FlutterLogo( - size: 200, - ), - identifier: 'overlay_flutter_logo', - delegate: null, - ); - }, - child: const Text('Show Overlay'), - ), - const SizedBox(height: 12.0), - Builder(builder: (buttonContext) { - return ElevatedButton( - onPressed: () { - FlowyOverlay.of(context).insertWithAnchor( - widget: SizedBox( - width: 200, - height: 100, - child: Card( - color: Colors.grey[200], - child: GestureDetector( - onTapDown: (_) => print('Hello Flutter'), - child: const Center(child: FlutterLogo(size: 100)), + ElevatedButton( + onPressed: () { + FlowyOverlay.of(context).insertCustom( + widget: const FlutterLogo( + size: 200, + ), + identifier: 'overlay_flutter_logo', + delegate: null, + ); + }, + child: const Text('Show Overlay'), + ), + const SizedBox(height: 12.0), + Builder(builder: (buttonContext) { + return ElevatedButton( + onPressed: () { + FlowyOverlay.of(context).insertWithAnchor( + widget: SizedBox( + width: 200, + height: 100, + child: Card( + color: Colors.grey[200], + child: GestureDetector( + onTapDown: (_) => print('Hello Flutter'), + child: const Center(child: FlutterLogo(size: 100)), + ), + ), + ), + identifier: 'overlay_card', + delegate: null, + anchorContext: buttonContext, + anchorDirection: context.read().anchorDirection, + ); + }, + child: const Text('Show Anchored Overlay'), + ); + }), + const SizedBox(height: 12.0), + ElevatedButton( + onPressed: () { + final windowSize = MediaQuery.of(context).size; + FlowyOverlay.of(context).insertWithRect( + widget: SizedBox( + width: 200, + height: 100, + child: Card( + color: Colors.orange[200], + child: GestureDetector( + onTapDown: (_) => print('Hello Flutter'), + child: const Center(child: FlutterLogo(size: 100)), + ), ), ), - ), - identifier: 'overlay_card', - delegate: null, - anchorContext: buttonContext, - anchorDirection: AnchorDirection.topLeft, - ); - }, - child: const Text('Show Anchored Overlay'), - ); - }), - const SizedBox(height: 12.0), - ElevatedButton( - onPressed: () { - final windowSize = MediaQuery.of(context).size; - FlowyOverlay.of(context).insertWithRect( - widget: SizedBox( - width: 200, - height: 100, - child: Card( - color: Colors.orange[200], - child: GestureDetector( - onTapDown: (_) => print('Hello Flutter'), - child: const Center(child: FlutterLogo(size: 100)), - ), - ), - ), - identifier: 'overlay_card', - delegate: null, - anchorPosition: Offset(0, windowSize.height - 200), - anchorSize: Size.zero, - anchorDirection: AnchorDirection.topLeft, - ); - }, - child: const Text('Show Positioned Overlay'), - ), - ], + identifier: 'overlay_card', + delegate: null, + anchorPosition: Offset(0, windowSize.height - 200), + anchorSize: Size.zero, + anchorDirection: context.read().anchorDirection, + ); + }, + child: const Text('Show Positioned Overlay'), + ), + ], + ); + }), )); } } diff --git a/app_flowy/packages/flowy_infra_ui/lib/src/flowy_overlay/overlay_layout_delegate.dart b/app_flowy/packages/flowy_infra_ui/lib/src/flowy_overlay/overlay_layout_delegate.dart index b09eb3a28e..350a87d4f7 100644 --- a/app_flowy/packages/flowy_infra_ui/lib/src/flowy_overlay/overlay_layout_delegate.dart +++ b/app_flowy/packages/flowy_infra_ui/lib/src/flowy_overlay/overlay_layout_delegate.dart @@ -39,17 +39,23 @@ class OverlayLayoutDelegate extends SingleChildLayoutDelegate { Offset position; switch (anchorDirection) { case AnchorDirection.topLeft: - position = Offset( - anchorRect.left - childSize.width, - anchorRect.top - childSize.height, - ); + position = Offset(anchorRect.left - childSize.width, anchorRect.top - childSize.height); + break; + case AnchorDirection.topRight: + position = Offset(anchorRect.right, anchorRect.top - childSize.height); + break; + case AnchorDirection.bottomLeft: + position = Offset(anchorRect.left - childSize.width, anchorRect.bottom); + break; + case AnchorDirection.bottomRight: + position = Offset(anchorRect.right, anchorRect.bottom); break; default: throw UnimplementedError(); } return Offset( - math.max(0.0, math.min(size.width, position.dx)), - math.max(0.0, math.min(size.height, position.dy)), + math.max(0.0, math.min(size.width - childSize.width, position.dx)), + math.max(0.0, math.min(size.height - childSize.height, position.dy)), ); } }