diff --git a/frontend/app_flowy/packages/appflowy_editor/lib/src/render/toolbar/toolbar_widget.dart b/frontend/app_flowy/packages/appflowy_editor/lib/src/render/toolbar/toolbar_widget.dart index d987b2f87b..2a03d96140 100644 --- a/frontend/app_flowy/packages/appflowy_editor/lib/src/render/toolbar/toolbar_widget.dart +++ b/frontend/app_flowy/packages/appflowy_editor/lib/src/render/toolbar/toolbar_widget.dart @@ -16,12 +16,14 @@ class ToolbarWidget extends StatefulWidget { required this.layerLink, required this.offset, required this.items, + this.aligment = Alignment.topLeft, }) : super(key: key); final EditorState editorState; final LayerLink layerLink; final Offset offset; final List items; + final Alignment aligment; @override State createState() => _ToolbarWidgetState(); @@ -39,6 +41,7 @@ class _ToolbarWidgetState extends State with ToolbarMixin { link: widget.layerLink, showWhenUnlinked: true, offset: widget.offset, + followerAnchor: widget.aligment, child: _buildToolbar(context), ), ); diff --git a/frontend/app_flowy/packages/appflowy_editor/lib/src/service/selection_service.dart b/frontend/app_flowy/packages/appflowy_editor/lib/src/service/selection_service.dart index 86d39ba826..22de73c429 100644 --- a/frontend/app_flowy/packages/appflowy_editor/lib/src/service/selection_service.dart +++ b/frontend/app_flowy/packages/appflowy_editor/lib/src/service/selection_service.dart @@ -388,9 +388,11 @@ class _AppFlowySelectionState extends State // TODO: need to be refactored. Offset? toolbarOffset; + Alignment? alignment; LayerLink? layerLink; final editorOffset = editorState.renderBox?.localToGlobal(Offset.zero) ?? Offset.zero; + final editorSize = editorState.renderBox?.size ?? Size.zero; final backwardNodes = selection.isBackward ? nodes : nodes.reversed.toList(growable: false); @@ -438,10 +440,33 @@ class _AppFlowySelectionState extends State // TODO: Need to compute more precise location. if ((selectionRect.topLeft.dy - editorOffset.dy) <= baseToolbarOffset.dy) { - toolbarOffset ??= rect.bottomLeft; + if (selectionRect.topLeft.dx <= + editorSize.width / 3.0 + editorOffset.dx) { + toolbarOffset ??= rect.bottomLeft; + alignment ??= Alignment.topLeft; + } else if (selectionRect.topRight.dx >= + editorSize.width * 2.0 / 3.0 + editorOffset.dx) { + toolbarOffset ??= rect.bottomRight; + alignment ??= Alignment.topRight; + } else { + toolbarOffset ??= rect.bottomCenter; + alignment ??= Alignment.topCenter; + } } else { - toolbarOffset ??= rect.topLeft - baseToolbarOffset; + if (selectionRect.topLeft.dx <= + editorSize.width / 3.0 + editorOffset.dx) { + toolbarOffset ??= rect.topLeft - baseToolbarOffset; + alignment ??= Alignment.topLeft; + } else if (selectionRect.topRight.dx >= + editorSize.width * 2.0 / 3.0 + editorOffset.dx) { + toolbarOffset ??= rect.topRight - baseToolbarOffset; + alignment ??= Alignment.topRight; + } else { + toolbarOffset ??= rect.topCenter - baseToolbarOffset; + alignment ??= Alignment.topCenter; + } } + layerLink ??= node.layerLink; final overlay = OverlayEntry( @@ -460,6 +485,7 @@ class _AppFlowySelectionState extends State if (toolbarOffset != null && layerLink != null) { editorState.service.toolbarService?.showInOffset( toolbarOffset, + alignment!, layerLink, ); } diff --git a/frontend/app_flowy/packages/appflowy_editor/lib/src/service/toolbar_service.dart b/frontend/app_flowy/packages/appflowy_editor/lib/src/service/toolbar_service.dart index 8991d0a30a..9b9d002cd1 100644 --- a/frontend/app_flowy/packages/appflowy_editor/lib/src/service/toolbar_service.dart +++ b/frontend/app_flowy/packages/appflowy_editor/lib/src/service/toolbar_service.dart @@ -8,7 +8,7 @@ import 'package:appflowy_editor/src/extensions/object_extensions.dart'; abstract class AppFlowyToolbarService { /// Show the toolbar widget beside the offset. - void showInOffset(Offset offset, LayerLink layerLink); + void showInOffset(Offset offset, Alignment alignment, LayerLink layerLink); /// Hide the toolbar widget. void hide(); @@ -37,7 +37,7 @@ class _FlowyToolbarState extends State final _toolbarWidgetKey = GlobalKey(debugLabel: '_toolbar_widget'); @override - void showInOffset(Offset offset, LayerLink layerLink) { + void showInOffset(Offset offset, Alignment alignment, LayerLink layerLink) { hide(); final items = _filterItems(defaultToolbarItems); if (items.isEmpty) { @@ -50,6 +50,7 @@ class _FlowyToolbarState extends State layerLink: layerLink, offset: offset, items: items, + aligment: alignment, ), ); Overlay.of(context)?.insert(_toolbarOverlay!);