소스 검색

[infra_ui][overlar] Implement corner aligned anchor mode and update example project

Jaylen Bian 3 년 전
부모
커밋
dffb56d1a9

+ 101 - 71
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<AnchorDirection>(
+                  value: context.watch<OverlayDemoAnchorDirection>().anchorDirection,
+                  onChanged: (AnchorDirection? newValue) {
+                    if (newValue != null) {
+                      context.read<OverlayDemoAnchorDirection>().anchorDirection = newValue;
+                    }
+                  },
+                  items: AnchorDirection.values.map((AnchorDirection classType) {
+                    return DropdownMenuItem<AnchorDirection>(value: classType, child: Text(classType.toString()));
+                  }).toList(),
                 ),
-              ),
-            ),
-            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(
+                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],
-                        child: GestureDetector(
-                          onTapDown: (_) => print('Hello Flutter'),
-                          child: const Center(child: FlutterLogo(size: 100)),
-                        ),
                       ),
                     ),
-                    identifier: 'overlay_card',
-                    delegate: null,
-                    anchorContext: buttonContext,
-                    anchorDirection: AnchorDirection.topLeft,
+                  ),
+                ),
+                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<OverlayDemoAnchorDirection>().anchorDirection,
+                      );
+                    },
+                    child: const Text('Show Anchored Overlay'),
                   );
-                },
-                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)),
+                }),
+                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<OverlayDemoAnchorDirection>().anchorDirection,
+                    );
+                  },
+                  child: const Text('Show Positioned Overlay'),
+                ),
+              ],
+            );
+          }),
         ));
   }
 }

+ 12 - 6
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)),
     );
   }
 }