From 17b9d972842d30a0ca61a650a325d80cdbfbeab8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Th=C3=A9o=20Poizat?= Date: Mon, 26 Jan 2026 16:10:48 +0100 Subject: [PATCH] Adjust Scribe context menu to support tablet screens - Support tap in addition to hover for context menu - Improve clamping for greater screen sizes to avoid Scribe getting off screen - Set a padding to 0 to avoid random padding depending on screen sizes --- .../modal/anchored_modal_layout_calculator.dart | 6 +++++- .../context_menu/ai_scribe_context_menu.dart | 2 +- .../ai_scribe_context_menu_item.dart | 16 ++++++++++++---- .../widgets/context_menu/ai_scribe_submenu.dart | 1 + 4 files changed, 19 insertions(+), 6 deletions(-) diff --git a/scribe/lib/scribe/ai/presentation/utils/modal/anchored_modal_layout_calculator.dart b/scribe/lib/scribe/ai/presentation/utils/modal/anchored_modal_layout_calculator.dart index f42e60c97..6e9218149 100644 --- a/scribe/lib/scribe/ai/presentation/utils/modal/anchored_modal_layout_calculator.dart +++ b/scribe/lib/scribe/ai/presentation/utils/modal/anchored_modal_layout_calculator.dart @@ -154,10 +154,14 @@ class AnchoredModalLayoutCalculator { if (isTop) { final availableHeight = anchorPosition.dy - padding - gap; final positionBottom = screenSize.height - anchorPosition.dy + gap; + final clampedLeft = anchorPosition.dx.clamp( + padding, + screenSize.width - menuSize.width - padding, + ); return AnchoredSuggestionLayoutResult( availableHeight: availableHeight, - left: anchorPosition.dx, + left: clampedLeft, bottom: positionBottom, ); } diff --git a/scribe/lib/scribe/ai/presentation/widgets/context_menu/ai_scribe_context_menu.dart b/scribe/lib/scribe/ai/presentation/widgets/context_menu/ai_scribe_context_menu.dart index f06a6698e..eceb5caec 100644 --- a/scribe/lib/scribe/ai/presentation/widgets/context_menu/ai_scribe_context_menu.dart +++ b/scribe/lib/scribe/ai/presentation/widgets/context_menu/ai_scribe_context_menu.dart @@ -53,7 +53,7 @@ class _AiScribeContextMenuContentState extends State { widget.submenuController?.hide(); widget.onActionSelected(menuAction); }, - onHoverShowSubmenu: (itemKey) => + onSelectCategory: (itemKey) => menuAction.submenuActions?.isNotEmpty == true ? _showSubmenu( context: context, diff --git a/scribe/lib/scribe/ai/presentation/widgets/context_menu/ai_scribe_context_menu_item.dart b/scribe/lib/scribe/ai/presentation/widgets/context_menu/ai_scribe_context_menu_item.dart index db7d62331..3583e1561 100644 --- a/scribe/lib/scribe/ai/presentation/widgets/context_menu/ai_scribe_context_menu_item.dart +++ b/scribe/lib/scribe/ai/presentation/widgets/context_menu/ai_scribe_context_menu_item.dart @@ -6,7 +6,7 @@ class AiScribeContextMenuItem extends StatefulWidget { final AiScribeContextMenuAction menuAction; final ImagePaths imagePaths; final ValueChanged onSelectAction; - final OnHoverShowSubmenu? onHoverShowSubmenu; + final OnHoverShowSubmenu onSelectCategory; final VoidCallback? onHoverOtherItem; const AiScribeContextMenuItem({ @@ -14,7 +14,7 @@ class AiScribeContextMenuItem extends StatefulWidget { required this.menuAction, required this.imagePaths, required this.onSelectAction, - this.onHoverShowSubmenu, + required this.onSelectCategory, this.onHoverOtherItem, }); @@ -44,7 +44,7 @@ class _AiScribeContextMenuItemState extends State { _hoverController?.enter(); if (_itemKey != null) { - widget.onHoverShowSubmenu?.call(_itemKey!); + widget.onSelectCategory.call(_itemKey!); } else { widget.onHoverOtherItem?.call(); } @@ -55,7 +55,15 @@ class _AiScribeContextMenuItemState extends State { child: AiScribeMenuItem( itemKey: _itemKey, menuAction: widget.menuAction, - onSelectAction: widget.onSelectAction, + onSelectAction: (menuAction) { + if (menuAction.submenuActions?.isNotEmpty == true) { + if (_itemKey != null) { + widget.onSelectCategory.call(_itemKey!); + } + } else { + widget.onSelectAction(menuAction); + } + }, imagePaths: widget.imagePaths, ) ); diff --git a/scribe/lib/scribe/ai/presentation/widgets/context_menu/ai_scribe_submenu.dart b/scribe/lib/scribe/ai/presentation/widgets/context_menu/ai_scribe_submenu.dart index e9fd8dbac..b0f6db8c4 100644 --- a/scribe/lib/scribe/ai/presentation/widgets/context_menu/ai_scribe_submenu.dart +++ b/scribe/lib/scribe/ai/presentation/widgets/context_menu/ai_scribe_submenu.dart @@ -24,6 +24,7 @@ class AiScribeSubmenu extends StatelessWidget { clipBehavior: Clip.antiAlias, child: ListView.builder( shrinkWrap: true, + padding: EdgeInsets.zero, itemCount: menuActions.length, itemBuilder: (_, index) { final action = menuActions[index];