-
Notifications
You must be signed in to change notification settings - Fork 845
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
chore: move members of magnifier feature into a separate files when possible (not final yet) #2251
Changes from 1 commit
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
part of '../editor.dart'; | ||
|
||
extension QuillEditorSelectionGestureDetectorBuilderMagnifierExt | ||
on _QuillEditorSelectionGestureDetectorBuilder { | ||
void _showMagnifierIfSupportedByPlatform(Offset positionToShow) { | ||
switch (defaultTargetPlatform) { | ||
case TargetPlatform.android: | ||
case TargetPlatform.iOS: | ||
editor?.showMagnifier(positionToShow); | ||
default: | ||
} | ||
} | ||
|
||
void _hideMagnifierIfSupportedByPlatform() { | ||
switch (defaultTargetPlatform) { | ||
case TargetPlatform.android: | ||
case TargetPlatform.iOS: | ||
editor?.hideMagnifier(); | ||
default: | ||
} | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
import 'package:flutter/widgets.dart'; | ||
import 'package:meta/meta.dart'; | ||
|
||
// TODO: See the difference between Flutter MagnifierController and QuillMagnifierController | ||
// and document it. | ||
@internal | ||
@experimental | ||
abstract class QuillMagnifierController { | ||
void showMagnifier(Offset positionToShow); | ||
|
||
void updateMagnifier(Offset positionToShow); | ||
|
||
void hideMagnifier(); | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
part of '../raw_editor/raw_editor_state.dart'; | ||
|
||
extension QuillRawEditorStateMagnifierExt on QuillRawEditorState { | ||
void _hideMagnifier() { | ||
if (_selectionOverlay == null) return; | ||
_selectionOverlay?.hideMagnifier(); | ||
} | ||
|
||
void _showMagnifier(ui.Offset positionToShow) { | ||
if (_hasFocus == false) return; | ||
if (_selectionOverlay == null) return; | ||
final position = renderEditor.getPositionForOffset(positionToShow); | ||
if (_selectionOverlay!.magnifierIsVisible) { | ||
_selectionOverlay! | ||
.updateMagnifier(position, positionToShow, renderEditor); | ||
} else { | ||
_selectionOverlay!.showMagnifier(position, positionToShow, renderEditor); | ||
} | ||
} | ||
|
||
void _updateMagnifier(ui.Offset positionToShow) => | ||
showMagnifier(positionToShow); | ||
|
||
TextMagnifierConfiguration get _magnifierConfiguration => | ||
widget.configurations.magnifierConfiguration ?? | ||
TextMagnifier.adaptiveMagnifierConfiguration; | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,116 @@ | ||
part of '../widgets/text/text_selection.dart'; | ||
|
||
final MagnifierController _magnifierController = MagnifierController(); | ||
|
||
/// Restore the selection context menu after the magnifier is dismissed. | ||
/// Fix: https://github.com/singerdmx/flutter-quill/issues/2046 | ||
bool _restoreToolbar = false; | ||
|
||
extension EditorTextSelectionOverlayMagnifierExt on EditorTextSelectionOverlay { | ||
// build magnifier info | ||
MagnifierInfo _buildMagnifier( | ||
{required RenderEditor renderEditable, | ||
required Offset globalGesturePosition, | ||
required TextPosition currentTextPosition}) { | ||
final globalRenderEditableTopLeft = | ||
renderEditable.localToGlobal(Offset.zero); | ||
final localCaretRect = | ||
renderEditable.getLocalRectForCaret(currentTextPosition); | ||
|
||
final lineAtOffset = renderEditable.getLineAtOffset(currentTextPosition); | ||
final positionAtEndOfLine = TextPosition( | ||
offset: lineAtOffset.extentOffset, | ||
affinity: TextAffinity.upstream, | ||
); | ||
|
||
// Default affinity is downstream. | ||
final positionAtBeginningOfLine = TextPosition( | ||
offset: lineAtOffset.baseOffset, | ||
); | ||
|
||
final lineBoundaries = Rect.fromPoints( | ||
renderEditable.getLocalRectForCaret(positionAtBeginningOfLine).topCenter, | ||
renderEditable.getLocalRectForCaret(positionAtEndOfLine).bottomCenter, | ||
); | ||
|
||
return MagnifierInfo( | ||
fieldBounds: globalRenderEditableTopLeft & renderEditable.size, | ||
globalGesturePosition: globalGesturePosition, | ||
caretRect: localCaretRect.shift(globalRenderEditableTopLeft), | ||
currentLineBoundaries: lineBoundaries.shift(globalRenderEditableTopLeft), | ||
); | ||
} | ||
|
||
void _showMagnifier(MagnifierInfo initialMagnifierInfo) { | ||
// Hide toolbar | ||
if (toolbar != null) { | ||
_restoreToolbar = true; | ||
hideToolbar(); | ||
} else { | ||
_restoreToolbar = false; | ||
} | ||
|
||
// Update magnifier Info | ||
_magnifierInfo.value = initialMagnifierInfo; | ||
|
||
final builtMagnifier = magnifierConfiguration.magnifierBuilder( | ||
context, | ||
_magnifierController, | ||
_magnifierInfo, | ||
); | ||
|
||
if (builtMagnifier == null) return; | ||
|
||
_magnifierController.show( | ||
context: context, | ||
below: magnifierConfiguration.shouldDisplayHandlesInMagnifier | ||
? null | ||
: _handles?.elementAtOrNull(0), | ||
builder: (_) => builtMagnifier, | ||
); | ||
} | ||
|
||
void _updateMagnifier(MagnifierInfo magnifierInfo) { | ||
if (_magnifierController.overlayEntry == null) { | ||
return; | ||
} | ||
_magnifierInfo.value = magnifierInfo; | ||
} | ||
|
||
// TODO: Why we're having private and public methods for showMagnifier, and updateMagnifier? | ||
// Is this internal API that is for public use? | ||
// Once we know the reason, explain and document it. | ||
|
||
void showMagnifier( | ||
TextPosition position, Offset offset, RenderEditor editor) { | ||
_showMagnifier( | ||
_buildMagnifier( | ||
currentTextPosition: position, | ||
globalGesturePosition: offset, | ||
renderEditable: editor, | ||
), | ||
); | ||
} | ||
|
||
void updateMagnifier( | ||
TextPosition position, Offset offset, RenderEditor editor) { | ||
_updateMagnifier( | ||
_buildMagnifier( | ||
currentTextPosition: position, | ||
globalGesturePosition: offset, | ||
renderEditable: editor, | ||
), | ||
); | ||
} | ||
|
||
void hideMagnifier() { | ||
if (_magnifierController.overlayEntry == null) { | ||
return; | ||
} | ||
_magnifierController.hide(); | ||
if (_restoreToolbar) { | ||
_restoreToolbar = false; | ||
showToolbar(); | ||
} | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -43,6 +43,8 @@ import 'raw_editor_state_text_input_client_mixin.dart'; | |
import 'raw_editor_text_boundaries.dart'; | ||
import 'scribble_focusable.dart'; | ||
|
||
part '../magnifier/quill_raw_editor_state_magnifier_ext.dart'; | ||
|
||
class QuillRawEditorState extends EditorState | ||
with | ||
AutomaticKeepAliveClientMixin<QuillRawEditor>, | ||
|
@@ -1114,8 +1116,7 @@ class QuillRawEditorState extends EditorState | |
? null | ||
: (context) => | ||
widget.configurations.contextMenuBuilder!(context, this), | ||
magnifierConfiguration: widget.configurations.magnifierConfiguration ?? | ||
TextMagnifier.adaptiveMagnifierConfiguration, | ||
magnifierConfiguration: _magnifierConfiguration, | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The expression: widget.configurations.magnifierConfiguration ??
TextMagnifier.adaptiveMagnifierConfiguration has been extracted into The name is not quite descriptive and needs to be changed or at least documented. |
||
); | ||
} | ||
|
||
|
@@ -1505,26 +1506,13 @@ class QuillRawEditorState extends EditorState | |
bool get shareEnabled => false; | ||
|
||
@override | ||
void hideMagnifier() { | ||
if (_selectionOverlay == null) return; | ||
_selectionOverlay?.hideMagnifier(); | ||
} | ||
void hideMagnifier() => _hideMagnifier(); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The Same for |
||
|
||
@override | ||
void showMagnifier(ui.Offset positionToShow) { | ||
if (_hasFocus == false) return; | ||
if (_selectionOverlay == null) return; | ||
final position = renderEditor.getPositionForOffset(positionToShow); | ||
if (_selectionOverlay!.magnifierIsVisible) { | ||
_selectionOverlay! | ||
.updateMagnifier(position, positionToShow, renderEditor); | ||
} else { | ||
_selectionOverlay!.showMagnifier(position, positionToShow, renderEditor); | ||
} | ||
} | ||
void showMagnifier(ui.Offset positionToShow) => | ||
_showMagnifier(positionToShow); | ||
|
||
@override | ||
void updateMagnifier(ui.Offset positionToShow) { | ||
showMagnifier(positionToShow); | ||
} | ||
void updateMagnifier(ui.Offset positionToShow) => | ||
_updateMagnifier(positionToShow); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why those methods added here?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Probably bad design to be here