Quellcode durchsuchen

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

Jaylen Bian vor 3 Jahren
Ursprung
Commit
5c4df3c6f2

+ 99 - 84
app_flowy/packages/flowy_infra_ui/example/lib/overlay/overlay_screen.dart

@@ -43,96 +43,111 @@ class OverlayScreen extends StatelessWidget {
           title: const Text('Overlay Demo'),
         ),
         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(),
-                ),
-                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)),
+          create: (context) => OverlayDemoAnchorDirection(AnchorDirection.rightWithTopAligned),
+          child: Builder(builder: (providerContext) {
+            return Center(
+              child: ConstrainedBox(
+                constraints: const BoxConstraints.tightFor(width: 500),
+                child: Column(
+                  crossAxisAlignment: CrossAxisAlignment.center,
+                  children: [
+                    const SizedBox(height: 48.0),
+                    ElevatedButton(
+                      onPressed: () {
+                        final windowSize = MediaQuery.of(context).size;
+                        FlowyOverlay.of(context).insertCustom(
+                          widget: Positioned(
+                            left: windowSize.width / 2.0 - 100,
+                            top: 200,
+                            child: SizedBox(
+                              width: 200,
+                              height: 100,
+                              child: Card(
+                                color: Colors.green[200],
+                                child: GestureDetector(
+                                  // ignore: avoid_print
+                                  onTapDown: (_) => print('Hello Flutter'),
+                                  child: const Center(child: FlutterLogo(size: 100)),
+                                ),
+                              ),
                             ),
                           ),
+                          identifier: 'overlay_flutter_logo',
+                          delegate: null,
+                        );
+                      },
+                      child: const Text('Show Overlay'),
+                    ),
+                    const SizedBox(height: 24.0),
+                    DropdownButton<AnchorDirection>(
+                      value: providerContext.watch<OverlayDemoAnchorDirection>().anchorDirection,
+                      onChanged: (AnchorDirection? newValue) {
+                        if (newValue != null) {
+                          providerContext.read<OverlayDemoAnchorDirection>().anchorDirection = newValue;
+                        }
+                      },
+                      items: AnchorDirection.values.map((AnchorDirection classType) {
+                        return DropdownMenuItem<AnchorDirection>(value: classType, child: Text(classType.toString()));
+                      }).toList(),
+                    ),
+                    const SizedBox(height: 24.0),
+                    Builder(builder: (buttonContext) {
+                      return SizedBox(
+                        height: 100,
+                        child: ElevatedButton(
+                          onPressed: () {
+                            FlowyOverlay.of(context).insertWithAnchor(
+                              widget: SizedBox(
+                                width: 100,
+                                height: 50,
+                                child: Card(
+                                  color: Colors.grey[200],
+                                  child: GestureDetector(
+                                    // ignore: avoid_print
+                                    onTapDown: (_) => print('Hello Flutter'),
+                                    child: const Center(child: FlutterLogo(size: 50)),
+                                  ),
+                                ),
+                              ),
+                              identifier: 'overlay_anchored_card',
+                              delegate: null,
+                              anchorContext: buttonContext,
+                              anchorDirection: providerContext.read<OverlayDemoAnchorDirection>().anchorDirection,
+                            );
+                          },
+                          child: const Text('Show Anchored Overlay'),
                         ),
-                        identifier: 'overlay_card',
-                        delegate: null,
-                        anchorContext: buttonContext,
-                        anchorDirection: context.read<OverlayDemoAnchorDirection>().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)),
+                    }),
+                    const SizedBox(height: 24.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(
+                                // ignore: avoid_print
+                                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: context.read<OverlayDemoAnchorDirection>().anchorDirection,
-                    );
-                  },
-                  child: const Text('Show Positioned Overlay'),
+                          identifier: 'overlay_positioned_card',
+                          delegate: null,
+                          anchorPosition: Offset(0, windowSize.height - 200),
+                          anchorSize: Size.zero,
+                          anchorDirection: providerContext.read<OverlayDemoAnchorDirection>().anchorDirection,
+                        );
+                      },
+                      child: const Text('Show Positioned Overlay'),
+                    ),
+                  ],
                 ),
-              ],
+              ),
             );
           }),
         ));

+ 85 - 4
app_flowy/packages/flowy_infra_ui/lib/src/flowy_overlay/overlay_layout_delegate.dart

@@ -39,16 +39,97 @@ 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);
+        position = Offset(
+          anchorRect.right,
+          anchorRect.top - childSize.height,
+        );
         break;
       case AnchorDirection.bottomLeft:
-        position = Offset(anchorRect.left - childSize.width, anchorRect.bottom);
+        position = Offset(
+          anchorRect.left - childSize.width,
+          anchorRect.bottom,
+        );
         break;
       case AnchorDirection.bottomRight:
-        position = Offset(anchorRect.right, anchorRect.bottom);
+        position = Offset(
+          anchorRect.right,
+          anchorRect.bottom,
+        );
+        break;
+      case AnchorDirection.topWithLeftAligned:
+        position = Offset(
+          anchorRect.left,
+          anchorRect.top - childSize.height,
+        );
+        break;
+      case AnchorDirection.topWithCenterAligned:
+        position = Offset(
+          anchorRect.left + anchorRect.width / 2.0 - childSize.width / 2.0,
+          anchorRect.top - childSize.height,
+        );
+        break;
+      case AnchorDirection.topWithRightAligned:
+        position = Offset(
+          anchorRect.right - childSize.width,
+          anchorRect.top - childSize.height,
+        );
+        break;
+      case AnchorDirection.rightWithTopAligned:
+        position = Offset(anchorRect.right, anchorRect.top);
+        break;
+      case AnchorDirection.rightWithCenterAligned:
+        position = Offset(
+          anchorRect.right,
+          anchorRect.top + anchorRect.height / 2.0 - childSize.height / 2.0,
+        );
+        break;
+      case AnchorDirection.rightWithBottomAligned:
+        position = Offset(
+          anchorRect.right,
+          anchorRect.bottom - childSize.height,
+        );
+        break;
+      case AnchorDirection.bottomWithLeftAligned:
+        position = Offset(
+          anchorRect.left,
+          anchorRect.bottom,
+        );
+        break;
+      case AnchorDirection.bottomWithCenterAligned:
+        position = Offset(
+          anchorRect.left + anchorRect.width / 2.0 - childSize.width / 2.0,
+          anchorRect.bottom,
+        );
+        break;
+      case AnchorDirection.bottomWithRightAligned:
+        position = Offset(
+          anchorRect.right - childSize.width,
+          anchorRect.bottom,
+        );
+        break;
+      case AnchorDirection.leftWithTopAligned:
+        position = Offset(
+          anchorRect.left - childSize.width,
+          anchorRect.top,
+        );
+        break;
+      case AnchorDirection.leftWithCenterAligned:
+        position = Offset(
+          anchorRect.left - childSize.width,
+          anchorRect.top + anchorRect.height / 2.0 - childSize.height / 2.0,
+        );
+        break;
+      case AnchorDirection.leftWithBottomAligned:
+        position = Offset(
+          anchorRect.left - childSize.width,
+          anchorRect.bottom - childSize.height,
+        );
         break;
       default:
         throw UnimplementedError();