Skip to content

Commit

Permalink
Let apps open and close the keyboard on demand, and let selection exi…
Browse files Browse the repository at this point in the history
…st when keyboard is closed (Resolves superlistapp#875) (superlistapp#876)

* Includes general refactoring and packaging of Super Editor IME behavior
  • Loading branch information
matthew-carroll authored and dxvid-pts committed Feb 11, 2024
1 parent 996f7b9 commit 09d0408
Show file tree
Hide file tree
Showing 35 changed files with 5,396 additions and 7,540 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -11,48 +11,41 @@ import 'keyboard_overlay_clipper.dart';
/// no matter which platform or form factor you use.
class MobileEditingAndroidDemo extends StatefulWidget {
@override
State<MobileEditingAndroidDemo> createState() => _MobileEditingAndroidDemoState();
_MobileEditingAndroidDemoState createState() => _MobileEditingAndroidDemoState();
}

class _MobileEditingAndroidDemoState extends State<MobileEditingAndroidDemo> {
final GlobalKey _docLayoutKey = GlobalKey();

late MutableDocument _doc;
final _docChangeSignal = SignalNotifier();
late Editor _docEditor;
late MutableDocumentComposer _composer;
late Document _doc;
late DocumentEditor _docEditor;
late DocumentComposer _composer;
late CommonEditorOperations _docOps;
late MagnifierAndToolbarController _overlayController;

FocusNode? _editorFocusNode;
SuperEditorImeConfiguration _imeConfiguration = const SuperEditorImeConfiguration();

@override
void initState() {
super.initState();
_doc = _createInitialDocument()..addListener(_onDocumentChange);
_composer = MutableDocumentComposer()..addListener(_configureImeActionButton);
_docEditor = createDefaultDocumentEditor(document: _doc, composer: _composer);
_doc = _createInitialDocument();
_docEditor = DocumentEditor(document: _doc as MutableDocument);
_composer = DocumentComposer()..addListener(_configureImeActionButton);
_docOps = CommonEditorOperations(
editor: _docEditor,
document: _doc,
composer: _composer,
documentLayoutResolver: () => _docLayoutKey.currentState as DocumentLayout,
);
_editorFocusNode = FocusNode();
_overlayController = MagnifierAndToolbarController();
}

@override
void dispose() {
_editorFocusNode!.dispose();
_composer.dispose();
_doc.removeListener(_onDocumentChange);
super.dispose();
}

void _onDocumentChange(_) => _docChangeSignal.notifyListeners();

void _configureImeActionButton() {
if (_composer.selection == null || !_composer.selection!.isCollapsed) {
setState(() {
Expand Down Expand Up @@ -80,21 +73,6 @@ class _MobileEditingAndroidDemoState extends State<MobileEditingAndroidDemo> {
});
}

void _cut() {
_docOps.cut();
_overlayController.hideToolbar();
}

void _copy() {
_docOps.copy();
_overlayController.hideToolbar();
}

void _paste() {
_docOps.paste();
_overlayController.hideToolbar();
}

@override
Widget build(BuildContext context) {
return _buildScaffold(
Expand All @@ -105,16 +83,14 @@ class _MobileEditingAndroidDemoState extends State<MobileEditingAndroidDemo> {
focusNode: _editorFocusNode,
documentLayoutKey: _docLayoutKey,
editor: _docEditor,
document: _doc,
composer: _composer,
overlayController: _overlayController,
gestureMode: DocumentGestureMode.android,
inputSource: TextInputSource.ime,
imeConfiguration: _imeConfiguration,
androidToolbarBuilder: (_) => AndroidTextEditingFloatingToolbar(
onCutPressed: _cut,
onCopyPressed: _copy,
onPastePressed: _paste,
onCutPressed: () => _docOps.cut(),
onCopyPressed: () => _docOps.copy(),
onPastePressed: () => _docOps.paste(),
onSelectAllPressed: () => _docOps.selectAll(),
),
stylesheet: defaultStylesheet.copyWith(
Expand All @@ -125,7 +101,7 @@ class _MobileEditingAndroidDemoState extends State<MobileEditingAndroidDemo> {
),
MultiListenableBuilder(
listenables: <Listenable>{
_docChangeSignal,
_doc,
_composer.selectionNotifier,
},
builder: (_) => _buildMountedToolbar(),
Expand All @@ -143,12 +119,10 @@ class _MobileEditingAndroidDemoState extends State<MobileEditingAndroidDemo> {
}

return KeyboardEditingToolbar(
editor: _docEditor,
document: _doc,
composer: _composer,
commonOps: CommonEditorOperations(
editor: _docEditor,
document: _doc,
composer: _composer,
documentLayoutResolver: () => _docLayoutKey.currentState as DocumentLayout,
),
Expand Down Expand Up @@ -213,70 +187,89 @@ MutableDocument _createInitialDocument() {
return MutableDocument(
nodes: [
ImageNode(
id: Editor.createNodeId(),
id: DocumentEditor.createNodeId(),
imageUrl: 'https://i.imgur.com/fSZwM7G.jpg',
),
ParagraphNode(
id: Editor.createNodeId(),
text: AttributedText('Example Document'),
id: DocumentEditor.createNodeId(),
text: AttributedText(
text: 'Example Document',
),
metadata: {
'blockType': header1Attribution,
},
),
HorizontalRuleNode(id: Editor.createNodeId()),
HorizontalRuleNode(id: DocumentEditor.createNodeId()),
ParagraphNode(
id: Editor.createNodeId(),
id: DocumentEditor.createNodeId(),
text: AttributedText(
'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Phasellus sed sagittis urna. Aenean mattis ante justo, quis sollicitudin metus interdum id. Aenean ornare urna ac enim consequat mollis. In aliquet convallis efficitur. Phasellus convallis purus in fringilla scelerisque. Ut ac orci a turpis egestas lobortis. Morbi aliquam dapibus sem, vitae sodales arcu ultrices eu. Duis vulputate mauris quam, eleifend pulvinar quam blandit eget.',
text:
'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Phasellus sed sagittis urna. Aenean mattis ante justo, quis sollicitudin metus interdum id. Aenean ornare urna ac enim consequat mollis. In aliquet convallis efficitur. Phasellus convallis purus in fringilla scelerisque. Ut ac orci a turpis egestas lobortis. Morbi aliquam dapibus sem, vitae sodales arcu ultrices eu. Duis vulputate mauris quam, eleifend pulvinar quam blandit eget.',
),
),
ParagraphNode(
id: Editor.createNodeId(),
text: AttributedText('This is a blockquote!'),
id: DocumentEditor.createNodeId(),
text: AttributedText(
text: 'This is a blockquote!',
),
metadata: {
'blockType': blockquoteAttribution,
},
),
ListItemNode.unordered(
id: Editor.createNodeId(),
text: AttributedText('This is an unordered list item'),
id: DocumentEditor.createNodeId(),
text: AttributedText(
text: 'This is an unordered list item',
),
),
ListItemNode.unordered(
id: Editor.createNodeId(),
text: AttributedText('This is another list item'),
id: DocumentEditor.createNodeId(),
text: AttributedText(
text: 'This is another list item',
),
),
ListItemNode.unordered(
id: Editor.createNodeId(),
text: AttributedText('This is a 3rd list item'),
id: DocumentEditor.createNodeId(),
text: AttributedText(
text: 'This is a 3rd list item',
),
),
ParagraphNode(
id: Editor.createNodeId(),
id: DocumentEditor.createNodeId(),
text: AttributedText(
'Cras vitae sodales nisi. Vivamus dignissim vel purus vel aliquet. Sed viverra diam vel nisi rhoncus pharetra. Donec gravida ut ligula euismod pharetra. Etiam sed urna scelerisque, efficitur mauris vel, semper arcu. Nullam sed vehicula sapien. Donec id tellus volutpat, eleifend nulla eget, rutrum mauris.',
),
text:
'Cras vitae sodales nisi. Vivamus dignissim vel purus vel aliquet. Sed viverra diam vel nisi rhoncus pharetra. Donec gravida ut ligula euismod pharetra. Etiam sed urna scelerisque, efficitur mauris vel, semper arcu. Nullam sed vehicula sapien. Donec id tellus volutpat, eleifend nulla eget, rutrum mauris.'),
),
ListItemNode.ordered(
id: Editor.createNodeId(),
text: AttributedText('First thing to do'),
id: DocumentEditor.createNodeId(),
text: AttributedText(
text: 'First thing to do',
),
),
ListItemNode.ordered(
id: Editor.createNodeId(),
text: AttributedText('Second thing to do'),
id: DocumentEditor.createNodeId(),
text: AttributedText(
text: 'Second thing to do',
),
),
ListItemNode.ordered(
id: Editor.createNodeId(),
text: AttributedText('Third thing to do'),
id: DocumentEditor.createNodeId(),
text: AttributedText(
text: 'Third thing to do',
),
),
ParagraphNode(
id: Editor.createNodeId(),
id: DocumentEditor.createNodeId(),
text: AttributedText(
'Nam hendrerit vitae elit ut placerat. Maecenas nec congue neque. Fusce eget tortor pulvinar, cursus neque vitae, sagittis lectus. Duis mollis libero eu scelerisque ullamcorper. Pellentesque eleifend arcu nec augue molestie, at iaculis dui rutrum. Etiam lobortis magna at magna pellentesque ornare. Sed accumsan, libero vel porta molestie, tortor lorem eleifend ante, at egestas leo felis sed nunc. Quisque mi neque, molestie vel dolor a, eleifend tempor odio.',
text:
'Nam hendrerit vitae elit ut placerat. Maecenas nec congue neque. Fusce eget tortor pulvinar, cursus neque vitae, sagittis lectus. Duis mollis libero eu scelerisque ullamcorper. Pellentesque eleifend arcu nec augue molestie, at iaculis dui rutrum. Etiam lobortis magna at magna pellentesque ornare. Sed accumsan, libero vel porta molestie, tortor lorem eleifend ante, at egestas leo felis sed nunc. Quisque mi neque, molestie vel dolor a, eleifend tempor odio.',
),
),
ParagraphNode(
id: Editor.createNodeId(),
id: DocumentEditor.createNodeId(),
text: AttributedText(
'Etiam id lacus interdum, efficitur ex convallis, accumsan ipsum. Integer faucibus mollis mauris, a suscipit ante mollis vitae. Fusce justo metus, congue non lectus ac, luctus rhoncus tellus. Phasellus vitae fermentum orci, sit amet sodales orci. Fusce at ante iaculis nunc aliquet pharetra. Nam placerat, nisl in gravida lacinia, nisl nibh feugiat nunc, in sagittis nisl sapien nec arcu. Nunc gravida faucibus massa, sit amet accumsan dolor feugiat in. Mauris ut elementum leo.',
text:
'Etiam id lacus interdum, efficitur ex convallis, accumsan ipsum. Integer faucibus mollis mauris, a suscipit ante mollis vitae. Fusce justo metus, congue non lectus ac, luctus rhoncus tellus. Phasellus vitae fermentum orci, sit amet sodales orci. Fusce at ante iaculis nunc aliquet pharetra. Nam placerat, nisl in gravida lacinia, nisl nibh feugiat nunc, in sagittis nisl sapien nec arcu. Nunc gravida faucibus massa, sit amet accumsan dolor feugiat in. Mauris ut elementum leo.',
),
),
],
Expand Down
Loading

0 comments on commit 09d0408

Please sign in to comment.