Browse Source

[flutter]:enable add doc with FlowyOverlay

appflowy 3 years ago
parent
commit
4afbe62475

+ 4 - 1
app_flowy/lib/startup/tasks/application_task.dart

@@ -20,6 +20,8 @@ class AppWidgetTask extends LaunchTask {
   }
   }
 }
 }
 
 
+final GlobalKey<FlowyOverlayState> _key = GlobalKey<FlowyOverlayState>();
+
 class ApplicationWidget extends StatelessWidget {
 class ApplicationWidget extends StatelessWidget {
   final Widget child;
   final Widget child;
   const ApplicationWidget({
   const ApplicationWidget({
@@ -36,10 +38,11 @@ class ApplicationWidget extends StatelessWidget {
     setWindowFrame(const Rect.fromLTRB(0, 0, launchWidth, launchWidth / ratio));
     setWindowFrame(const Rect.fromLTRB(0, 0, launchWidth, launchWidth / ratio));
 
 
     final theme = AppTheme.fromType(ThemeType.light);
     final theme = AppTheme.fromType(ThemeType.light);
+    FlowyOverlayConfig config = FlowyOverlayConfig(barrierColor: theme.bg3.withOpacity(0.3));
     return Provider.value(
     return Provider.value(
         value: theme,
         value: theme,
         child: MaterialApp(
         child: MaterialApp(
-          builder: overlayManagerBuilder(),
+          builder: overlayManagerBuilder(config: config),
           debugShowCheckedModeBanner: false,
           debugShowCheckedModeBanner: false,
           theme: theme.themeData,
           theme: theme.themeData,
           navigatorKey: AppGlobals.rootNavKey,
           navigatorKey: AppGlobals.rootNavKey,

+ 78 - 24
app_flowy/lib/workspace/presentation/widgets/menu/widget/app/header.dart

@@ -1,16 +1,19 @@
-import 'package:app_flowy/workspace/application/app/app_bloc.dart';
 import 'package:expandable/expandable.dart';
 import 'package:expandable/expandable.dart';
+import 'package:flowy_infra/flowy_icon_data_icons.dart';
+import 'package:flowy_infra/image.dart';
 import 'package:flowy_infra/theme.dart';
 import 'package:flowy_infra/theme.dart';
+import 'package:flowy_infra_ui/flowy_infra_ui.dart';
 import 'package:flowy_infra_ui/style_widget/icon_button.dart';
 import 'package:flowy_infra_ui/style_widget/icon_button.dart';
 import 'package:flowy_infra_ui/style_widget/text.dart';
 import 'package:flowy_infra_ui/style_widget/text.dart';
 import 'package:flowy_infra_ui/widget/spacing.dart';
 import 'package:flowy_infra_ui/widget/spacing.dart';
-import 'package:flowy_infra/flowy_icon_data_icons.dart';
 import 'package:flowy_sdk/protobuf/flowy-workspace/app_create.pb.dart';
 import 'package:flowy_sdk/protobuf/flowy-workspace/app_create.pb.dart';
 import 'package:flowy_sdk/protobuf/flowy-workspace/view_create.pb.dart';
 import 'package:flowy_sdk/protobuf/flowy-workspace/view_create.pb.dart';
 import 'package:flutter/material.dart';
 import 'package:flutter/material.dart';
 import 'package:flutter_bloc/flutter_bloc.dart';
 import 'package:flutter_bloc/flutter_bloc.dart';
 import 'package:styled_widget/styled_widget.dart';
 import 'package:styled_widget/styled_widget.dart';
 
 
+import 'package:app_flowy/workspace/application/app/app_bloc.dart';
+
 import 'menu_app.dart';
 import 'menu_app.dart';
 
 
 class MenuAppHeader extends StatelessWidget {
 class MenuAppHeader extends StatelessWidget {
@@ -55,37 +58,88 @@ class MenuAppHeader extends StatelessWidget {
               fontSize: 12,
               fontSize: 12,
             ),
             ),
           )),
           )),
-
-          ViewAddButton(
-            onPressed: () {
-              debugPrint('add view');
-              // FlowyOverlay.of(context)
-              //     .insert(widget: Text('test'), identifier: 'identifier');
+          DisclosureButton(
+            onSelected: (viewType) {
+              context.read<AppBloc>().add(AppEvent.createView("New view", "", viewType));
             },
             },
           ).padding(right: MenuAppSizes.expandedIconPadding),
           ).padding(right: MenuAppSizes.expandedIconPadding),
-          // PopupMenuButton(
-          //     iconSize: 16,
-          //     tooltip: 'create new view',
-          //     icon: svg("home/add"),
-          //     padding: EdgeInsets.zero,
-          //     onSelected: (viewType) => _createView(viewType as ViewType, context),
-          //     itemBuilder: (context) => menuItemBuilder())
         ],
         ],
       ),
       ),
     );
     );
   }
   }
+}
 
 
-  List<PopupMenuEntry> menuItemBuilder() {
-    return ViewType.values.where((element) => element != ViewType.Blank).map((ty) {
-      return PopupMenuItem<ViewType>(
-          value: ty,
-          child: Row(
-            children: <Widget>[Text(ty.name)],
-          ));
+class DisclosureButton extends StatelessWidget {
+  final Function(ViewType) onSelected;
+  const DisclosureButton({
+    Key? key,
+    required this.onSelected,
+  }) : super(key: key);
+
+  @override
+  Widget build(BuildContext context) {
+    return FlowyIconButton(
+      width: 16,
+      onPressed: () {
+        DisclosureButtonActionList(
+          anchorContext: context,
+          onSelected: onSelected,
+        ).show(context);
+      },
+      icon: svg("home/add"),
+    );
+  }
+}
+
+class DisclosureButtonActionList {
+  final Function(ViewType) onSelected;
+  final BuildContext anchorContext;
+  final String _identifier = 'DisclosureButtonActionList';
+
+  const DisclosureButtonActionList({required this.anchorContext, required this.onSelected});
+
+  void show(BuildContext buildContext) {
+    final items = ViewType.values.where((element) => element != ViewType.Blank).map((ty) {
+      return CreateItem(
+          viewType: ty,
+          onSelected: (viewType) {
+            FlowyOverlay.of(buildContext).remove(_identifier);
+            onSelected(viewType);
+          });
     }).toList();
     }).toList();
+
+    ListOverlay.showWithAnchor(
+      buildContext,
+      identifier: _identifier,
+      itemCount: items.length,
+      itemBuilder: (context, index) => items[index],
+      anchorContext: anchorContext,
+      anchorDirection: AnchorDirection.bottomRight,
+      maxWidth: 120,
+      maxHeight: 80,
+    );
   }
   }
+}
 
 
-  void _createView(ViewType viewType, BuildContext context) {
-    context.read<AppBloc>().add(AppEvent.createView("New view", "", viewType));
+class CreateItem extends StatelessWidget {
+  final ViewType viewType;
+  final Function(ViewType) onSelected;
+  const CreateItem({
+    Key? key,
+    required this.viewType,
+    required this.onSelected,
+  }) : super(key: key);
+
+  @override
+  Widget build(BuildContext context) {
+    return GestureDetector(
+      onTap: () {
+        onSelected(viewType);
+      },
+      child: FlowyText.medium(
+        viewType.name,
+        fontSize: 12,
+      ).padding(horizontal: 10, vertical: 10),
+    );
   }
   }
 }
 }

+ 24 - 34
app_flowy/packages/flowy_infra_ui/lib/src/flowy_overlay/flowy_overlay.dart

@@ -1,7 +1,7 @@
 // ignore_for_file: unused_element
 // ignore_for_file: unused_element
 
 
 import 'package:dartz/dartz.dart' show Tuple3;
 import 'package:dartz/dartz.dart' show Tuple3;
-import 'package:flowy_infra_ui/src/flowy_overlay/overlay_layout_delegate.dart';
+import 'package:flowy_infra_ui/src/flowy_overlay/layout.dart';
 import 'package:flutter/material.dart';
 import 'package:flutter/material.dart';
 
 
 /// Specifies how overlay are anchored to the SourceWidget
 /// Specifies how overlay are anchored to the SourceWidget
@@ -55,13 +55,21 @@ enum OnBackBehavior {
   dismiss,
   dismiss,
 }
 }
 
 
+class FlowyOverlayConfig {
+  final Color barrierColor;
+
+  FlowyOverlayConfig({required this.barrierColor});
+
+  const FlowyOverlayConfig.defualt() : barrierColor = Colors.transparent;
+}
+
 final GlobalKey<FlowyOverlayState> _key = GlobalKey<FlowyOverlayState>();
 final GlobalKey<FlowyOverlayState> _key = GlobalKey<FlowyOverlayState>();
 
 
 /// Invoke this method in app generation process
 /// Invoke this method in app generation process
-TransitionBuilder overlayManagerBuilder() {
+TransitionBuilder overlayManagerBuilder({FlowyOverlayConfig config = const FlowyOverlayConfig.defualt()}) {
   return (context, child) {
   return (context, child) {
     assert(child != null, 'Child can\'t be null.');
     assert(child != null, 'Child can\'t be null.');
-    return FlowyOverlay(key: _key, child: child!);
+    return FlowyOverlay(key: _key, child: child!, config: config);
   };
   };
 }
 }
 
 
@@ -70,50 +78,33 @@ abstract class FlowyOverlayDelegate {
 }
 }
 
 
 class FlowyOverlay extends StatefulWidget {
 class FlowyOverlay extends StatefulWidget {
-  const FlowyOverlay({
-    Key? key,
-    required this.child,
-    this.barrierColor = Colors.transparent,
-  }) : super(key: key);
+  const FlowyOverlay({Key? key, required this.child, required this.config}) : super(key: key);
 
 
   final Widget child;
   final Widget child;
 
 
-  final Color? barrierColor;
-
-  static FlowyOverlayState of(
-    BuildContext context, {
-    bool rootOverlay = false,
-  }) {
-    FlowyOverlayState? overlayManager;
-    if (rootOverlay) {
-      overlayManager = context.findRootAncestorStateOfType<FlowyOverlayState>() ?? overlayManager;
-    } else {
-      overlayManager = overlayManager ?? context.findAncestorStateOfType<FlowyOverlayState>();
-    }
+  final FlowyOverlayConfig config;
 
 
+  static FlowyOverlayState of(BuildContext context, {bool rootOverlay = false}) {
+    FlowyOverlayState? state = maybeOf(context, rootOverlay: rootOverlay);
     assert(() {
     assert(() {
-      if (overlayManager == null) {
+      if (state == null) {
         throw FlutterError(
         throw FlutterError(
           'Can\'t find overlay manager in current context, please check if already wrapped by overlay manager.',
           'Can\'t find overlay manager in current context, please check if already wrapped by overlay manager.',
         );
         );
       }
       }
       return true;
       return true;
     }());
     }());
-    return overlayManager!;
+    return state!;
   }
   }
 
 
-  static FlowyOverlayState? maybeOf(
-    BuildContext context, {
-    bool rootOverlay = false,
-  }) {
-    FlowyOverlayState? overlayManager;
+  static FlowyOverlayState? maybeOf(BuildContext context, {bool rootOverlay = false}) {
+    FlowyOverlayState? state;
     if (rootOverlay) {
     if (rootOverlay) {
-      overlayManager = context.findRootAncestorStateOfType<FlowyOverlayState>() ?? overlayManager;
+      state = context.findRootAncestorStateOfType<FlowyOverlayState>();
     } else {
     } else {
-      overlayManager = overlayManager ?? context.findAncestorStateOfType<FlowyOverlayState>();
+      state = context.findAncestorStateOfType<FlowyOverlayState>();
     }
     }
-
-    return overlayManager;
+    return state;
   }
   }
 
 
   @override
   @override
@@ -239,8 +230,7 @@ class FlowyOverlayState extends State<FlowyOverlay> {
       overlay = CustomSingleChildLayout(
       overlay = CustomSingleChildLayout(
         delegate: OverlayLayoutDelegate(
         delegate: OverlayLayoutDelegate(
           anchorRect: anchorRect,
           anchorRect: anchorRect,
-          anchorDirection:
-              shouldAnchor ? anchorDirection ?? AnchorDirection.rightWithTopAligned : AnchorDirection.custom,
+          anchorDirection: anchorDirection ?? AnchorDirection.rightWithTopAligned,
           overlapBehaviour: overlapBehaviour ?? OverlapBehaviour.stretch,
           overlapBehaviour: overlapBehaviour ?? OverlapBehaviour.stretch,
         ),
         ),
         child: widget,
         child: widget,
@@ -259,7 +249,7 @@ class FlowyOverlayState extends State<FlowyOverlay> {
       widget.child,
       widget.child,
       if (overlays.isNotEmpty)
       if (overlays.isNotEmpty)
         Container(
         Container(
-          color: widget.barrierColor,
+          color: widget.config.barrierColor,
           child: GestureDetector(
           child: GestureDetector(
             behavior: HitTestBehavior.opaque,
             behavior: HitTestBehavior.opaque,
             onTap: _handleTapOnBackground,
             onTap: _handleTapOnBackground,

+ 0 - 0
app_flowy/packages/flowy_infra_ui/lib/src/flowy_overlay/overlay_layout_delegate.dart → app_flowy/packages/flowy_infra_ui/lib/src/flowy_overlay/layout.dart


+ 20 - 19
app_flowy/packages/flowy_infra_ui/lib/src/flowy_overlay/list_overlay.dart

@@ -17,6 +17,26 @@ class ListOverlay extends StatelessWidget {
   final double maxWidth;
   final double maxWidth;
   final double maxHeight;
   final double maxHeight;
 
 
+  @override
+  Widget build(BuildContext context) {
+    return Container(
+      constraints: BoxConstraints.tight(Size(maxWidth, maxHeight)),
+      decoration: BoxDecoration(
+        color: Colors.white,
+        borderRadius: const BorderRadius.all(Radius.circular(6)),
+        boxShadow: [
+          BoxShadow(color: Colors.black.withOpacity(0.1), spreadRadius: 1, blurRadius: 20.0),
+        ],
+      ),
+      child: ListView.builder(
+        shrinkWrap: true,
+        itemBuilder: itemBuilder,
+        itemCount: itemCount,
+        controller: controller,
+      ),
+    );
+  }
+
   static void showWithAnchor(
   static void showWithAnchor(
     BuildContext context, {
     BuildContext context, {
     required String identifier,
     required String identifier,
@@ -77,23 +97,4 @@ class ListOverlay extends StatelessWidget {
       overlapBehaviour: overlapBehaviour,
       overlapBehaviour: overlapBehaviour,
     );
     );
   }
   }
-
-  @override
-  Widget build(BuildContext context) {
-    return Container(
-      constraints: BoxConstraints.tight(Size(maxWidth, maxHeight)),
-      decoration: BoxDecoration(
-        color: Colors.white,
-        borderRadius: const BorderRadius.all(Radius.circular(6)),
-        boxShadow: [
-          BoxShadow(color: Colors.black.withOpacity(0.1), spreadRadius: 1, blurRadius: 20.0),
-        ],
-      ),
-      child: ListView.builder(
-        shrinkWrap: true,
-        itemBuilder: itemBuilder,
-        itemCount: itemCount,
-      ),
-    );
-  }
 }
 }

+ 0 - 17
app_flowy/packages/flowy_infra_ui/lib/style_widget/icon_button.dart

@@ -48,23 +48,6 @@ class FlowyDropdownButton extends StatelessWidget {
   }
   }
 }
 }
 
 
-class ViewAddButton extends StatelessWidget {
-  final VoidCallback? onPressed;
-  const ViewAddButton({
-    Key? key,
-    this.onPressed,
-  }) : super(key: key);
-
-  @override
-  Widget build(BuildContext context) {
-    return FlowyIconButton(
-      width: 16,
-      onPressed: onPressed,
-      icon: svg("home/add"),
-    );
-  }
-}
-
 class ViewMoreButton extends StatelessWidget {
 class ViewMoreButton extends StatelessWidget {
   final VoidCallback? onPressed;
   final VoidCallback? onPressed;
   const ViewMoreButton({
   const ViewMoreButton({