mirror of
https://github.com/AppFlowy-IO/AppFlowy.git
synced 2024-08-30 18:12:39 +00:00
[flutter]: config popup window
This commit is contained in:
@ -36,11 +36,10 @@ class ApplicationWidget extends StatelessWidget {
|
|||||||
// setWindowFrame(const Rect.fromLTWH(0, 0, launchWidth, launchWidth / ratio));
|
// setWindowFrame(const Rect.fromLTWH(0, 0, launchWidth, launchWidth / ratio));
|
||||||
|
|
||||||
final theme = AppTheme.fromType(ThemeType.light);
|
final theme = AppTheme.fromType(ThemeType.light);
|
||||||
FlowyOverlayConfig config = FlowyOverlayConfig(barrierColor: Colors.transparent);
|
|
||||||
return Provider.value(
|
return Provider.value(
|
||||||
value: theme,
|
value: theme,
|
||||||
child: MaterialApp(
|
child: MaterialApp(
|
||||||
builder: overlayManagerBuilder(config: config),
|
builder: overlayManagerBuilder(),
|
||||||
debugShowCheckedModeBanner: false,
|
debugShowCheckedModeBanner: false,
|
||||||
theme: theme.themeData,
|
theme: theme.themeData,
|
||||||
navigatorKey: AppGlobals.rootNavKey,
|
navigatorKey: AppGlobals.rootNavKey,
|
||||||
|
@ -0,0 +1,77 @@
|
|||||||
|
import 'package:dartz/dartz.dart' as dartz;
|
||||||
|
import 'package:flowy_infra/theme.dart';
|
||||||
|
import 'package:flowy_infra_ui/flowy_infra_ui.dart';
|
||||||
|
import 'package:flowy_infra_ui/style_widget/hover.dart';
|
||||||
|
import 'package:flowy_infra_ui/style_widget/text.dart';
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||||
|
import 'package:provider/provider.dart';
|
||||||
|
import 'package:styled_widget/styled_widget.dart';
|
||||||
|
import 'package:app_flowy/workspace/domain/view_edit.dart';
|
||||||
|
|
||||||
|
class ViewActionList implements FlowyOverlayDelegate {
|
||||||
|
final Function(dartz.Option<ViewAction>) onSelected;
|
||||||
|
final BuildContext anchorContext;
|
||||||
|
final String _identifier = 'ViewActionList';
|
||||||
|
|
||||||
|
const ViewActionList({required this.anchorContext, required this.onSelected});
|
||||||
|
|
||||||
|
void show(BuildContext buildContext) {
|
||||||
|
final items = ViewAction.values
|
||||||
|
.map((action) => ActionItem(
|
||||||
|
action: action,
|
||||||
|
onSelected: (action) {
|
||||||
|
FlowyOverlay.of(buildContext).remove(_identifier);
|
||||||
|
onSelected(dartz.some(action));
|
||||||
|
}))
|
||||||
|
.toList();
|
||||||
|
|
||||||
|
ListOverlay.showWithAnchor(
|
||||||
|
buildContext,
|
||||||
|
identifier: _identifier,
|
||||||
|
itemCount: items.length,
|
||||||
|
itemBuilder: (context, index) => items[index],
|
||||||
|
anchorContext: anchorContext,
|
||||||
|
anchorDirection: AnchorDirection.bottomRight,
|
||||||
|
maxWidth: 120,
|
||||||
|
maxHeight: 80,
|
||||||
|
delegate: this,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
void didRemove() {
|
||||||
|
onSelected(dartz.none());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class ActionItem extends StatelessWidget {
|
||||||
|
final ViewAction action;
|
||||||
|
final Function(ViewAction) onSelected;
|
||||||
|
const ActionItem({
|
||||||
|
Key? key,
|
||||||
|
required this.action,
|
||||||
|
required this.onSelected,
|
||||||
|
}) : super(key: key);
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
final theme = context.watch<AppTheme>();
|
||||||
|
|
||||||
|
return FlowyHover(
|
||||||
|
config: HoverDisplayConfig(hoverColor: theme.hover),
|
||||||
|
builder: (context, onHover) {
|
||||||
|
return GestureDetector(
|
||||||
|
onTap: () => onSelected(action),
|
||||||
|
child: FlowyText.medium(
|
||||||
|
action.name,
|
||||||
|
fontSize: 12,
|
||||||
|
).padding(
|
||||||
|
horizontal: 10,
|
||||||
|
vertical: 6,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
@ -2,10 +2,10 @@ import 'package:app_flowy/startup/startup.dart';
|
|||||||
import 'package:app_flowy/workspace/application/view/view_bloc.dart';
|
import 'package:app_flowy/workspace/application/view/view_bloc.dart';
|
||||||
import 'package:app_flowy/workspace/domain/page_stack/page_stack.dart';
|
import 'package:app_flowy/workspace/domain/page_stack/page_stack.dart';
|
||||||
import 'package:app_flowy/workspace/domain/view_ext.dart';
|
import 'package:app_flowy/workspace/domain/view_ext.dart';
|
||||||
|
import 'package:app_flowy/workspace/presentation/widgets/pop_up_window.dart';
|
||||||
import 'package:dartz/dartz.dart' as dartz;
|
import 'package:dartz/dartz.dart' as dartz;
|
||||||
import 'package:flowy_infra/image.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/hover.dart';
|
import 'package:flowy_infra_ui/style_widget/hover.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';
|
||||||
@ -20,6 +20,8 @@ import 'package:app_flowy/workspace/domain/image.dart';
|
|||||||
import 'package:app_flowy/workspace/domain/view_edit.dart';
|
import 'package:app_flowy/workspace/domain/view_edit.dart';
|
||||||
import 'package:app_flowy/workspace/presentation/widgets/menu/widget/app/menu_app.dart';
|
import 'package:app_flowy/workspace/presentation/widgets/menu/widget/app/menu_app.dart';
|
||||||
|
|
||||||
|
import 'action.dart';
|
||||||
|
|
||||||
// ignore: must_be_immutable
|
// ignore: must_be_immutable
|
||||||
class ViewSectionItem extends StatelessWidget {
|
class ViewSectionItem extends StatelessWidget {
|
||||||
final bool isSelected;
|
final bool isSelected;
|
||||||
@ -89,8 +91,12 @@ class ViewSectionItem extends StatelessWidget {
|
|||||||
action.foldRight({}, (action, previous) {
|
action.foldRight({}, (action, previous) {
|
||||||
switch (action) {
|
switch (action) {
|
||||||
case ViewAction.rename:
|
case ViewAction.rename:
|
||||||
|
FlowyPoppuWindow.show(
|
||||||
// TODO: Handle this case.
|
context,
|
||||||
|
child: ViewRenamePannel(renameCallback: (name) {
|
||||||
|
context.read<ViewBloc>().add(ViewEvent.rename(name));
|
||||||
|
}),
|
||||||
|
);
|
||||||
break;
|
break;
|
||||||
case ViewAction.delete:
|
case ViewAction.delete:
|
||||||
context.read<ViewBloc>().add(const ViewEvent.delete());
|
context.read<ViewBloc>().add(const ViewEvent.delete());
|
||||||
@ -128,69 +134,12 @@ class ViewDisclosureButton extends StatelessWidget {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class ViewActionList implements FlowyOverlayDelegate {
|
class ViewRenamePannel extends StatelessWidget {
|
||||||
final Function(dartz.Option<ViewAction>) onSelected;
|
final void Function(String) renameCallback;
|
||||||
final BuildContext anchorContext;
|
const ViewRenamePannel({Key? key, required this.renameCallback}) : super(key: key);
|
||||||
final String _identifier = 'ViewActionList';
|
|
||||||
|
|
||||||
const ViewActionList({required this.anchorContext, required this.onSelected});
|
|
||||||
|
|
||||||
void show(BuildContext buildContext) {
|
|
||||||
final items = ViewAction.values
|
|
||||||
.map((action) => ActionItem(
|
|
||||||
action: action,
|
|
||||||
onSelected: (action) {
|
|
||||||
FlowyOverlay.of(buildContext).remove(_identifier);
|
|
||||||
onSelected(dartz.some(action));
|
|
||||||
}))
|
|
||||||
.toList();
|
|
||||||
|
|
||||||
ListOverlay.showWithAnchor(
|
|
||||||
buildContext,
|
|
||||||
identifier: _identifier,
|
|
||||||
itemCount: items.length,
|
|
||||||
itemBuilder: (context, index) => items[index],
|
|
||||||
anchorContext: anchorContext,
|
|
||||||
anchorDirection: AnchorDirection.bottomRight,
|
|
||||||
maxWidth: 120,
|
|
||||||
maxHeight: 80,
|
|
||||||
delegate: this,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
void didRemove() {
|
|
||||||
onSelected(dartz.none());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
class ActionItem extends StatelessWidget {
|
|
||||||
final ViewAction action;
|
|
||||||
final Function(ViewAction) onSelected;
|
|
||||||
const ActionItem({
|
|
||||||
Key? key,
|
|
||||||
required this.action,
|
|
||||||
required this.onSelected,
|
|
||||||
}) : super(key: key);
|
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
final theme = context.watch<AppTheme>();
|
return SizedBox(width: 100, height: 200, child: Container(color: Colors.black));
|
||||||
|
|
||||||
return FlowyHover(
|
|
||||||
config: HoverDisplayConfig(hoverColor: theme.hover),
|
|
||||||
builder: (context, onHover) {
|
|
||||||
return GestureDetector(
|
|
||||||
onTap: () => onSelected(action),
|
|
||||||
child: FlowyText.medium(
|
|
||||||
action.name,
|
|
||||||
fontSize: 12,
|
|
||||||
).padding(
|
|
||||||
horizontal: 10,
|
|
||||||
vertical: 6,
|
|
||||||
),
|
|
||||||
);
|
|
||||||
},
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3,6 +3,7 @@ import 'package:flutter/foundation.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:provider/provider.dart';
|
import 'package:provider/provider.dart';
|
||||||
|
import 'package:styled_widget/styled_widget.dart';
|
||||||
import 'item.dart';
|
import 'item.dart';
|
||||||
|
|
||||||
class ViewListNotifier extends ChangeNotifier {
|
class ViewListNotifier extends ChangeNotifier {
|
||||||
@ -47,10 +48,7 @@ class ViewSection extends StatelessWidget {
|
|||||||
// The ViewListNotifier will be updated after ViewListData changed passed by parent widget
|
// The ViewListNotifier will be updated after ViewListData changed passed by parent widget
|
||||||
return ChangeNotifierProxyProvider<ViewListNotifier, ViewSectionNotifier>(
|
return ChangeNotifierProxyProvider<ViewListNotifier, ViewSectionNotifier>(
|
||||||
create: (_) {
|
create: (_) {
|
||||||
final views = Provider.of<ViewListNotifier>(
|
final views = Provider.of<ViewListNotifier>(context, listen: false).items;
|
||||||
context,
|
|
||||||
listen: false,
|
|
||||||
).items;
|
|
||||||
return ViewSectionNotifier(views);
|
return ViewSectionNotifier(views);
|
||||||
},
|
},
|
||||||
update: (_, notifier, controller) => controller!..update(notifier),
|
update: (_, notifier, controller) => controller!..update(notifier),
|
||||||
@ -61,20 +59,15 @@ class ViewSection extends StatelessWidget {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Widget _renderSectionItems(BuildContext context, List<View> views) {
|
Widget _renderSectionItems(BuildContext context, List<View> views) {
|
||||||
var viewWidgets = views.map((view) {
|
var viewWidgets = views.map(
|
||||||
final item = ViewSectionItem(
|
(view) => ViewSectionItem(
|
||||||
view: view,
|
view: view,
|
||||||
isSelected: _isViewSelected(context, view.id),
|
isSelected: _isViewSelected(context, view.id),
|
||||||
onSelected: (view) => context.read<ViewSectionNotifier>().setSelectedView(view),
|
onSelected: (view) => context.read<ViewSectionNotifier>().setSelectedView(view),
|
||||||
);
|
).padding(vertical: 4),
|
||||||
|
);
|
||||||
|
|
||||||
return Padding(
|
return Column(children: viewWidgets.toList(growable: false));
|
||||||
padding: const EdgeInsets.symmetric(vertical: 4),
|
|
||||||
child: item,
|
|
||||||
);
|
|
||||||
}).toList(growable: false);
|
|
||||||
|
|
||||||
return Column(children: viewWidgets);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool _isViewSelected(BuildContext context, String viewId) {
|
bool _isViewSelected(BuildContext context, String viewId) {
|
||||||
|
@ -0,0 +1,28 @@
|
|||||||
|
import 'package:flowy_infra_ui/flowy_infra_ui.dart';
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:window_size/window_size.dart';
|
||||||
|
|
||||||
|
class FlowyPoppuWindow extends StatelessWidget {
|
||||||
|
final Widget child;
|
||||||
|
const FlowyPoppuWindow({Key? key, required this.child}) : super(key: key);
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return child;
|
||||||
|
}
|
||||||
|
|
||||||
|
static Future<void> show(
|
||||||
|
BuildContext context, {
|
||||||
|
required Widget child,
|
||||||
|
}) async {
|
||||||
|
final window = await getWindowInfo();
|
||||||
|
FlowyOverlay.of(context).insertWithRect(
|
||||||
|
widget: FlowyPoppuWindow(child: child),
|
||||||
|
identifier: 'FlowyPoppuWindow',
|
||||||
|
anchorPosition: Offset.zero,
|
||||||
|
anchorSize: window.frame.size,
|
||||||
|
anchorDirection: AnchorDirection.center,
|
||||||
|
style: FlowyOverlayStyle(blur: true),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
@ -3,6 +3,7 @@
|
|||||||
import 'package:dartz/dartz.dart' show Tuple3;
|
import 'package:dartz/dartz.dart' show Tuple3;
|
||||||
import 'package:flowy_infra_ui/src/flowy_overlay/layout.dart';
|
import 'package:flowy_infra_ui/src/flowy_overlay/layout.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
import 'dart:ui';
|
||||||
|
|
||||||
/// Specifies how overlay are anchored to the SourceWidget
|
/// Specifies how overlay are anchored to the SourceWidget
|
||||||
enum AnchorDirection {
|
enum AnchorDirection {
|
||||||
@ -11,6 +12,7 @@ enum AnchorDirection {
|
|||||||
topRight,
|
topRight,
|
||||||
bottomLeft,
|
bottomLeft,
|
||||||
bottomRight,
|
bottomRight,
|
||||||
|
center,
|
||||||
|
|
||||||
// Edge aligned with a edge of the SourceWidget
|
// Edge aligned with a edge of the SourceWidget
|
||||||
topWithLeftAligned,
|
topWithLeftAligned,
|
||||||
@ -55,21 +57,20 @@ enum OnBackBehavior {
|
|||||||
dismiss,
|
dismiss,
|
||||||
}
|
}
|
||||||
|
|
||||||
class FlowyOverlayConfig {
|
class FlowyOverlayStyle {
|
||||||
final Color barrierColor;
|
final Color barrierColor;
|
||||||
|
bool blur;
|
||||||
|
|
||||||
FlowyOverlayConfig({required this.barrierColor});
|
FlowyOverlayStyle({this.barrierColor = Colors.transparent, this.blur = false});
|
||||||
|
|
||||||
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({FlowyOverlayConfig config = const FlowyOverlayConfig.defualt()}) {
|
TransitionBuilder overlayManagerBuilder() {
|
||||||
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!, config: config);
|
return FlowyOverlay(key: _key, child: child!);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -78,12 +79,10 @@ abstract class FlowyOverlayDelegate {
|
|||||||
}
|
}
|
||||||
|
|
||||||
class FlowyOverlay extends StatefulWidget {
|
class FlowyOverlay extends StatefulWidget {
|
||||||
const FlowyOverlay({Key? key, required this.child, required this.config}) : super(key: key);
|
const FlowyOverlay({Key? key, required this.child}) : super(key: key);
|
||||||
|
|
||||||
final Widget child;
|
final Widget child;
|
||||||
|
|
||||||
final FlowyOverlayConfig config;
|
|
||||||
|
|
||||||
static FlowyOverlayState of(BuildContext context, {bool rootOverlay = false}) {
|
static FlowyOverlayState of(BuildContext context, {bool rootOverlay = false}) {
|
||||||
FlowyOverlayState? state = maybeOf(context, rootOverlay: rootOverlay);
|
FlowyOverlayState? state = maybeOf(context, rootOverlay: rootOverlay);
|
||||||
assert(() {
|
assert(() {
|
||||||
@ -113,6 +112,7 @@ class FlowyOverlay extends StatefulWidget {
|
|||||||
|
|
||||||
class FlowyOverlayState extends State<FlowyOverlay> {
|
class FlowyOverlayState extends State<FlowyOverlay> {
|
||||||
List<Tuple3<Widget, String, FlowyOverlayDelegate?>> _overlayList = [];
|
List<Tuple3<Widget, String, FlowyOverlayDelegate?>> _overlayList = [];
|
||||||
|
FlowyOverlayStyle style = FlowyOverlayStyle();
|
||||||
|
|
||||||
/// Insert a overlay widget which frame is set by the widget, not the component.
|
/// Insert a overlay widget which frame is set by the widget, not the component.
|
||||||
/// Be sure to specify the offset and size using a anchorable widget (like `Postition`, `CompositedTransformFollower`)
|
/// Be sure to specify the offset and size using a anchorable widget (like `Postition`, `CompositedTransformFollower`)
|
||||||
@ -137,7 +137,12 @@ class FlowyOverlayState extends State<FlowyOverlay> {
|
|||||||
AnchorDirection? anchorDirection,
|
AnchorDirection? anchorDirection,
|
||||||
FlowyOverlayDelegate? delegate,
|
FlowyOverlayDelegate? delegate,
|
||||||
OverlapBehaviour? overlapBehaviour,
|
OverlapBehaviour? overlapBehaviour,
|
||||||
|
FlowyOverlayStyle? style,
|
||||||
}) {
|
}) {
|
||||||
|
if (style != null) {
|
||||||
|
this.style = style;
|
||||||
|
}
|
||||||
|
|
||||||
_showOverlay(
|
_showOverlay(
|
||||||
widget: widget,
|
widget: widget,
|
||||||
identifier: identifier,
|
identifier: identifier,
|
||||||
@ -157,7 +162,10 @@ class FlowyOverlayState extends State<FlowyOverlay> {
|
|||||||
AnchorDirection? anchorDirection,
|
AnchorDirection? anchorDirection,
|
||||||
FlowyOverlayDelegate? delegate,
|
FlowyOverlayDelegate? delegate,
|
||||||
OverlapBehaviour? overlapBehaviour,
|
OverlapBehaviour? overlapBehaviour,
|
||||||
|
FlowyOverlayStyle? style,
|
||||||
}) {
|
}) {
|
||||||
|
this.style = style ?? FlowyOverlayStyle();
|
||||||
|
|
||||||
_showOverlay(
|
_showOverlay(
|
||||||
widget: widget,
|
widget: widget,
|
||||||
identifier: identifier,
|
identifier: identifier,
|
||||||
@ -245,17 +253,30 @@ class FlowyOverlayState extends State<FlowyOverlay> {
|
|||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
final overlays = _overlayList.map((ele) => ele.value1);
|
final overlays = _overlayList.map((ele) => ele.value1);
|
||||||
final children = <Widget>[
|
List<Widget> children = <Widget>[widget.child];
|
||||||
widget.child,
|
|
||||||
if (overlays.isNotEmpty)
|
Widget? child;
|
||||||
Container(
|
if (overlays.isNotEmpty) {
|
||||||
color: widget.config.barrierColor,
|
child = Container(
|
||||||
child: GestureDetector(
|
color: style.barrierColor,
|
||||||
behavior: HitTestBehavior.opaque,
|
child: GestureDetector(
|
||||||
onTap: _handleTapOnBackground,
|
behavior: HitTestBehavior.opaque,
|
||||||
),
|
onTap: _handleTapOnBackground,
|
||||||
),
|
),
|
||||||
];
|
);
|
||||||
|
|
||||||
|
if (style.blur) {
|
||||||
|
child = BackdropFilter(
|
||||||
|
child: child,
|
||||||
|
filter: ImageFilter.blur(sigmaX: 4, sigmaY: 4),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (child != null) {
|
||||||
|
children.add(child);
|
||||||
|
}
|
||||||
|
|
||||||
return Stack(
|
return Stack(
|
||||||
children: children..addAll(overlays),
|
children: children..addAll(overlays),
|
||||||
);
|
);
|
||||||
|
@ -55,6 +55,12 @@ class OverlayLayoutDelegate extends SingleChildLayoutDelegate {
|
|||||||
constraints.maxHeight - anchorRect.bottom,
|
constraints.maxHeight - anchorRect.bottom,
|
||||||
));
|
));
|
||||||
break;
|
break;
|
||||||
|
case AnchorDirection.center:
|
||||||
|
childConstraints = BoxConstraints.loose(Size(
|
||||||
|
constraints.maxWidth,
|
||||||
|
constraints.maxHeight,
|
||||||
|
));
|
||||||
|
break;
|
||||||
case AnchorDirection.topWithLeftAligned:
|
case AnchorDirection.topWithLeftAligned:
|
||||||
childConstraints = BoxConstraints.loose(Size(
|
childConstraints = BoxConstraints.loose(Size(
|
||||||
constraints.maxWidth - anchorRect.left,
|
constraints.maxWidth - anchorRect.left,
|
||||||
@ -165,6 +171,9 @@ class OverlayLayoutDelegate extends SingleChildLayoutDelegate {
|
|||||||
anchorRect.bottom,
|
anchorRect.bottom,
|
||||||
);
|
);
|
||||||
break;
|
break;
|
||||||
|
case AnchorDirection.center:
|
||||||
|
position = anchorRect.center;
|
||||||
|
break;
|
||||||
case AnchorDirection.topWithLeftAligned:
|
case AnchorDirection.topWithLeftAligned:
|
||||||
position = Offset(
|
position = Offset(
|
||||||
anchorRect.left,
|
anchorRect.left,
|
||||||
|
@ -55,6 +55,7 @@ class ListOverlay extends StatelessWidget {
|
|||||||
AnchorDirection? anchorDirection,
|
AnchorDirection? anchorDirection,
|
||||||
FlowyOverlayDelegate? delegate,
|
FlowyOverlayDelegate? delegate,
|
||||||
OverlapBehaviour? overlapBehaviour,
|
OverlapBehaviour? overlapBehaviour,
|
||||||
|
FlowyOverlayStyle? style,
|
||||||
}) {
|
}) {
|
||||||
FlowyOverlay.of(context).insertWithAnchor(
|
FlowyOverlay.of(context).insertWithAnchor(
|
||||||
widget: ListOverlay(
|
widget: ListOverlay(
|
||||||
@ -69,6 +70,7 @@ class ListOverlay extends StatelessWidget {
|
|||||||
anchorDirection: anchorDirection,
|
anchorDirection: anchorDirection,
|
||||||
delegate: delegate,
|
delegate: delegate,
|
||||||
overlapBehaviour: overlapBehaviour,
|
overlapBehaviour: overlapBehaviour,
|
||||||
|
style: style,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -86,6 +88,7 @@ class ListOverlay extends StatelessWidget {
|
|||||||
AnchorDirection? anchorDirection,
|
AnchorDirection? anchorDirection,
|
||||||
FlowyOverlayDelegate? delegate,
|
FlowyOverlayDelegate? delegate,
|
||||||
OverlapBehaviour? overlapBehaviour,
|
OverlapBehaviour? overlapBehaviour,
|
||||||
|
FlowyOverlayStyle? style,
|
||||||
}) {
|
}) {
|
||||||
FlowyOverlay.of(context).insertWithRect(
|
FlowyOverlay.of(context).insertWithRect(
|
||||||
widget: ListOverlay(
|
widget: ListOverlay(
|
||||||
@ -101,6 +104,7 @@ class ListOverlay extends StatelessWidget {
|
|||||||
anchorDirection: anchorDirection,
|
anchorDirection: anchorDirection,
|
||||||
delegate: delegate,
|
delegate: delegate,
|
||||||
overlapBehaviour: overlapBehaviour,
|
overlapBehaviour: overlapBehaviour,
|
||||||
|
style: style,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user