fix: add isMetricsChanged to FloatingToolbarBuilder (#1081)

This commit is contained in:
Morn 2025-03-27 13:42:48 +08:00 • committed by GitHub
commit c40ee05b39
No known key found for this signature in database
GPG key ID: B5690EEEBB952194

View file

@ -23,6 +23,7 @@ typedef FloatingToolbarBuilder = Widget Function(
BuildContext context, BuildContext context,
Widget child, Widget child,
VoidCallback onDismiss, VoidCallback onDismiss,
bool isMetricsChanged,
); );
/// A floating toolbar that displays at the top of the editor when the selection /// A floating toolbar that displays at the top of the editor when the selection
@ -73,6 +74,8 @@ class _FloatingToolbarState extends State<FloatingToolbar>
late Brightness brightness = Theme.of(context).brightness; late Brightness brightness = Theme.of(context).brightness;
bool hasMetricsChanged = false;
@override @override
void initState() { void initState() {
super.initState(); super.initState();
@ -118,8 +121,8 @@ class _FloatingToolbarState extends State<FloatingToolbar>
@override @override
void didChangeMetrics() { void didChangeMetrics() {
super.didChangeMetrics(); super.didChangeMetrics();
hasMetricsChanged = true;
_showAfterDelay(); _showAfterDelay(isMetricsChanged: true);
} }
@override @override
@ -139,7 +142,11 @@ class _FloatingToolbarState extends State<FloatingToolbar>
_clear(); _clear();
} else { } else {
// uses debounce to avoid the computing the rects too frequently. // uses debounce to avoid the computing the rects too frequently.
_showAfterDelay(const Duration(milliseconds: 200)); _showAfterDelay(
duration: const Duration(milliseconds: 200),
isMetricsChanged: hasMetricsChanged,
);
if (hasMetricsChanged) hasMetricsChanged = false;
} }
} }
@ -148,7 +155,7 @@ class _FloatingToolbarState extends State<FloatingToolbar>
// TODO: optimize the toolbar showing logic, making it more smooth. // TODO: optimize the toolbar showing logic, making it more smooth.
// A quick idea: based on the scroll controller's offset to display the toolbar. // A quick idea: based on the scroll controller's offset to display the toolbar.
_showAfterDelay(Duration.zero); _showAfterDelay();
} }
final String _debounceKey = 'show the toolbar'; final String _debounceKey = 'show the toolbar';
@ -160,19 +167,22 @@ class _FloatingToolbarState extends State<FloatingToolbar>
_toolbarContainer = null; _toolbarContainer = null;
} }
void _showAfterDelay([Duration duration = Duration.zero]) { void _showAfterDelay({
Duration duration = Duration.zero,
bool isMetricsChanged = false,
}) {
// uses debounce to avoid the computing the rects too frequently. // uses debounce to avoid the computing the rects too frequently.
Debounce.debounce( Debounce.debounce(
_debounceKey, _debounceKey,
duration, duration,
() { () {
_clear(); // clear the previous toolbar. _clear(); // clear the previous toolbar.
_showToolbar(); _showToolbar(isMetricsChanged);
}, },
); );
} }
void _showToolbar() { void _showToolbar(bool isMetricsChanged) {
final selection = editorState.selection; final selection = editorState.selection;
if (selection == null || selection.isCollapsed) { if (selection == null || selection.isCollapsed) {
return; return;
@ -212,7 +222,8 @@ class _FloatingToolbarState extends State<FloatingToolbar>
_toolbarContainer = OverlayEntry( _toolbarContainer = OverlayEntry(
builder: (context) { builder: (context) {
final child = _buildToolbar(context); final child = _buildToolbar(context);
return widget.toolbarBuilder?.call(context, child, _clear) ?? return widget.toolbarBuilder
?.call(context, child, _clear, isMetricsChanged) ??
Positioned( Positioned(
top: max(0, top) - floatingToolbarHeight, top: max(0, top) - floatingToolbarHeight,
left: left, left: left,