Skip to content
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

Paint multiple user selections (Resolves #631) #633

Open
wants to merge 20 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
8cfab36
[super_editor_markdown] - serialization fixes (Resolves #712) (#713)
matthew-carroll Jul 25, 2022
33537ee
Release super_editor v0.2.2, super_editor_markdown v0.1.3 (#715)
matthew-carroll Jul 25, 2022
f8aec2e
[SuperEditor] Fix scrolling issue when the editor is inside a horizon…
angelosilvestre Jul 26, 2022
2e81bdc
Added tests for text entry on mobile using an IME simulator in flutte…
matthew-carroll Aug 12, 2022
f31fe20
[SuperTextField] [Desktop] Fix text behaving scrollable when maxLines…
angelosilvestre Aug 13, 2022
84bd321
Updated Flutter test registry scripts to exit on failure (Resolves #7…
matthew-carroll Aug 13, 2022
c248522
[SuperEditor] Fix content jumping when typing close to the editor's e…
angelosilvestre Aug 13, 2022
574bc21
Fix hint component and example app toolbar focus (Resolves #726) (#730)
matthew-carroll Aug 13, 2022
6704f8e
[SuperTextField] Fix horizontal aligment (Resolves #668) (#716)
angelosilvestre Aug 14, 2022
98afa74
Paint multiple user selections in SuperEditor (Resolves #631)
Jun 20, 2022
2ea1200
WIP: Implemented painting non-primary text selections in SuperEditor
matthew-carroll Jun 20, 2022
e0d90e1
Brought back DocumentNodeSelection after accidentally deleting it dur…
matthew-carroll Jul 19, 2022
eb6c6f2
Resolved rebasing compilation issues, also fixed non-primary selectio…
matthew-carroll Jul 23, 2022
7b8a551
Never show caret in TextComponent because we moved the caret to the d…
matthew-carroll Jul 23, 2022
2229693
Added non-primary selection painting to images and HRs, also removed …
matthew-carroll Aug 14, 2022
510f1fa
Removed caret from text components
matthew-carroll Aug 14, 2022
9e2cb59
Removed caret from SelectionStyle because the caret was moved into an…
matthew-carroll Aug 14, 2022
b109183
Small adjustment to text component because carets are painted in overlay
matthew-carroll Aug 14, 2022
beaa51d
Fixed issues after rebase
matthew-carroll Aug 14, 2022
bf3787f
Trying to get GitHub to see latest branch version
matthew-carroll Aug 14, 2022
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 14 additions & 3 deletions flutter_test_registry/flutter_test_repo_test.bat
Original file line number Diff line number Diff line change
@@ -1,11 +1,22 @@
PUSHD attributed_text
CALL flutter test
CALL flutter test || GOTO :END
POPD

PUSHD super_editor
CALL flutter test
CALL flutter test || GOTO :END
POPD

PUSHD super_text_layout
CALL flutter test
CALL flutter test || GOTO :END
POPD

@ECHO.
@ECHO.
@ECHO Testing complete.
GOTO :EOF

:END
@ECHO.
@ECHO.
@ECHO Testing failed.
EXIT /B 1
2 changes: 2 additions & 0 deletions flutter_test_registry/flutter_test_repo_test.sh
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
set -e

(cd ./attributed_text; flutter test)
(cd ./super_editor; flutter test)
(cd ./super_text_layout; flutter test)
8 changes: 8 additions & 0 deletions super_editor/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,11 @@
## [0.2.2] - July, 2022: Desktop IME
* Use the input method engine (IME) on Desktop (previously only available on mobile)
* A number of `SuperTextField` fixes and improvements. These changes are part of the path to the next release, which is focused on stabilizing `SuperTextField`.

## [0.2.1] - ~July, 2022: Desktop IME~ (Removed from pub)
* Use the input method engine (IME) on Desktop (previously only available on mobile)
* A number of `SuperTextField` fixes and improvements. These changes are part of the path to the next release, which is focused on stabilizing `SuperTextField`.

## [0.2.0] - Feb, 2022: Mobile Support
* Mobile document editing
* Mobile text field editing
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -163,8 +163,6 @@ class HeaderWithHintComponentBuilder implements ComponentBuilder {
return null;
}

final textSelection = componentViewModel.selection;

return TextWithHintComponent(
key: componentContext.componentKey,
text: componentViewModel.text,
Expand All @@ -188,8 +186,7 @@ class HeaderWithHintComponentBuilder implements ComponentBuilder {
hintStyleBuilder: (Set<Attribution> attributions) => _textStyleBuilder(attributions).copyWith(
color: const Color(0xFFDDDDDD),
),
textSelection: textSelection,
selectionColor: componentViewModel.selectionColor,
styledSelections: componentViewModel.styledSelections,
);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,12 @@ Document createInitialDocument() {
"Super Editor is a toolkit to help you build document editors, document layouts, text fields, and more.",
),
),
ParagraphNode(
id: DocumentEditor.createNodeId(),
text: AttributedText(
text: "",
),
),
ParagraphNode(
id: DocumentEditor.createNodeId(),
text: AttributedText(
Expand Down
40 changes: 20 additions & 20 deletions super_editor/example/lib/demos/example_editor/_task.dart
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import 'package:collection/collection.dart';
import 'package:flutter/material.dart';
import 'package:super_editor/super_editor.dart';

Expand Down Expand Up @@ -96,7 +97,7 @@ class TaskComponentBuilder implements ComponentBuilder {
},
text: node.text,
textStyleBuilder: noStyleBuilder,
selectionColor: const Color(0x00000000),
caretColor: const Color(0x00000000),
);
}

Expand Down Expand Up @@ -131,10 +132,11 @@ class TaskComponentViewModel extends SingleColumnLayoutComponentViewModel with T
required this.textStyleBuilder,
this.textDirection = TextDirection.ltr,
this.textAlignment = TextAlign.left,
this.selection,
required this.selectionColor,
this.highlightWhenEmpty = false,
}) : super(nodeId: nodeId, maxWidth: maxWidth, padding: padding);
List<StyledSelection<TextSelection>>? styledSelections,
required this.caretColor,
this.caret,
}) : styledSelections = styledSelections ?? [],
super(nodeId: nodeId, maxWidth: maxWidth, padding: padding);

bool isComplete;
void Function(bool) setComplete;
Expand All @@ -147,11 +149,11 @@ class TaskComponentViewModel extends SingleColumnLayoutComponentViewModel with T
@override
TextAlign textAlignment;
@override
TextSelection? selection;
List<StyledSelection<TextSelection>> styledSelections;
@override
Color selectionColor;
TextPosition? caret;
@override
bool highlightWhenEmpty;
Color caretColor;

@override
TaskComponentViewModel copy() {
Expand All @@ -164,9 +166,9 @@ class TaskComponentViewModel extends SingleColumnLayoutComponentViewModel with T
text: text,
textStyleBuilder: textStyleBuilder,
textDirection: textDirection,
selection: selection,
selectionColor: selectionColor,
highlightWhenEmpty: highlightWhenEmpty,
styledSelections: List.from(styledSelections),
caret: caret,
caretColor: caretColor,
);
}

Expand All @@ -182,9 +184,9 @@ class TaskComponentViewModel extends SingleColumnLayoutComponentViewModel with T
textStyleBuilder == other.textStyleBuilder &&
textDirection == other.textDirection &&
textAlignment == other.textAlignment &&
selection == other.selection &&
selectionColor == other.selectionColor &&
highlightWhenEmpty == other.highlightWhenEmpty;
caret == other.caret &&
caretColor == other.caretColor &&
const DeepCollectionEquality().equals(styledSelections, other.styledSelections);

@override
int get hashCode =>
Expand All @@ -195,9 +197,9 @@ class TaskComponentViewModel extends SingleColumnLayoutComponentViewModel with T
textStyleBuilder.hashCode ^
textDirection.hashCode ^
textAlignment.hashCode ^
selection.hashCode ^
selectionColor.hashCode ^
highlightWhenEmpty.hashCode;
styledSelections.hashCode ^
caret.hashCode ^
caretColor.hashCode;
}

/// A document component that displays a complete-able task.
Expand Down Expand Up @@ -249,9 +251,7 @@ class TaskComponent extends StatelessWidget {
)
: style;
},
textSelection: viewModel.selection,
selectionColor: viewModel.selectionColor,
highlightWhenEmpty: viewModel.highlightWhenEmpty,
styledSelections: viewModel.styledSelections,
showDebugPaint: showDebugPaint,
),
),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@ import 'dart:math';

import 'package:example/logging.dart';
import 'package:flutter/material.dart';
import 'package:super_editor/super_editor.dart';
import 'package:flutter_gen/gen_l10n/app_localizations.dart';
import 'package:super_editor/super_editor.dart';

/// Small toolbar that is intended to display near some selected
/// text and offer a few text formatting controls.
Expand Down
54 changes: 47 additions & 7 deletions super_editor/example/lib/demos/example_editor/example_editor.dart
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import 'package:example/demos/example_editor/_task.dart';
import 'package:flutter/foundation.dart';
import 'package:example/logging.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:super_editor/super_editor.dart';

Expand Down Expand Up @@ -43,7 +43,38 @@ class _ExampleEditorState extends State<ExampleEditor> {
super.initState();
_doc = createInitialDocument()..addListener(_hideOrShowToolbar);
_docEditor = DocumentEditor(document: _doc as MutableDocument);
_composer = DocumentComposer()..addListener(_hideOrShowToolbar);
final nodeId = _doc.nodes[2].id;
_composer = DocumentComposer()
..addListener(_hideOrShowToolbar)
..setNonPrimarySelection(
"john",
DocumentSelection(
base: DocumentPosition(
nodeId: nodeId,
nodePosition: TextNodePosition.fromTextPosition(TextPosition(offset: 10)),
),
// extent: DocumentPosition(
// nodeId: nodeId,
// nodePosition: TextNodePosition.fromTextPosition(TextPosition(offset: 50)),
// ),
extent: DocumentPosition(
nodeId: _doc.nodes[4].id,
nodePosition: TextNodePosition.fromTextPosition(TextPosition(offset: 10)),
),
))
..setNonPrimarySelection(
"sally",
DocumentSelection(
base: DocumentPosition(
nodeId: _doc.nodes[0].id,
nodePosition: _doc.nodes[0].beginningPosition,
),
extent: DocumentPosition(
nodeId: _doc.nodes[0].id,
nodePosition: _doc.nodes[0].endPosition,
),
));
;
_docOps = CommonEditorOperations(
editor: _docEditor,
composer: _composer,
Expand Down Expand Up @@ -341,17 +372,26 @@ class _ExampleEditorState extends State<ExampleEditor> {
CaretStyle().copyWith(color: _isLight ? Colors.black : Colors.redAccent),
),
],
selectionStyle: _isLight
? defaultSelectionStyle
: SelectionStyles(
selectionColor: Colors.red.withOpacity(0.3),
),
selectionStyle: _isLight ? defaultSelectionStyle : SelectionStyles(selectionColor: Colors.red.withOpacity(0.3)),
stylesheet: defaultStylesheet.copyWith(
addRulesAfter: [
if (!_isLight) ..._darkModeStyles,
taskStyles,
],
),
nonPrimarySelectionStyler: (NonPrimarySelection selection) {
if (selection.id == "john") {
return SelectionStyles(
selectionColor: Colors.purpleAccent,
);
} else if (selection.id == "sally") {
return SelectionStyles(
selectionColor: Colors.yellow,
);
}

return SelectionStyles(selectionColor: Colors.transparent);
},
componentBuilders: [
...defaultComponentBuilders,
TaskComponentBuilder(_docEditor),
Expand Down
52 changes: 28 additions & 24 deletions super_editor/example/lib/main.dart
Original file line number Diff line number Diff line change
Expand Up @@ -3,22 +3,21 @@ import 'package:example/demos/components/demo_unselectable_hr.dart';
import 'package:example/demos/debugging/simple_deltas_input.dart';
import 'package:example/demos/demo_app_shortcuts.dart';
import 'package:example/demos/demo_empty_document.dart';
import 'package:example/demos/demo_rtl.dart';
import 'package:example/demos/demo_markdown_serialization.dart';
import 'package:example/demos/demo_paragraphs.dart';
import 'package:example/demos/demo_rtl.dart';
import 'package:example/demos/demo_selectable_text.dart';
import 'package:example/demos/editor_configs/demo_mobile_editing_android.dart';
import 'package:example/demos/editor_configs/demo_mobile_editing_ios.dart';
import 'package:example/demos/example_editor/example_editor.dart';
import 'package:example/demos/flutter_features/demo_inline_widgets.dart';
import 'package:example/demos/flutter_features/textinputclient/basic_text_input_client.dart';
import 'package:example/demos/scrolling/demo_task_and_chat_with_customscrollview.dart';
import 'package:example/demos/styles/demo_doc_styles.dart';
import 'package:example/demos/supertextfield/ios/demo_superiostextfield.dart';
import 'package:example/demos/flutter_features/textinputclient/textfield.dart';
import 'package:example/demos/scrolling/demo_task_and_chat_with_customscrollview.dart';
import 'package:example/demos/sliver_example_editor.dart';
import 'package:example/demos/styles/demo_doc_styles.dart';
import 'package:example/demos/supertextfield/demo_textfield.dart';
import 'package:example/logging.dart';
import 'package:example/demos/supertextfield/ios/demo_superiostextfield.dart';
import 'package:flutter/material.dart';
import 'package:flutter_gen/gen_l10n/app_localizations.dart';
import 'package:flutter_localizations/flutter_localizations.dart';
Expand All @@ -31,6 +30,7 @@ import 'demos/demo_switch_document_content.dart';
import 'demos/scrolling/demo_task_and_chat_with_renderobject.dart';
import 'demos/super_document/demo_read_only_scrolling_document.dart';
import 'demos/supertextfield/android/demo_superandroidtextfield.dart';
import 'logging.dart';

/// Demo of a basic text editor, as well as various widgets that
/// are available in this package.
Expand Down Expand Up @@ -117,25 +117,29 @@ class _HomeScreenState extends State<HomeScreen> {

@override
Widget build(BuildContext context) {
// We need our own [Overlay] instead of the one created by the navigator
// because overlay entries added to navigator's [Overlay] are always
// displayed above all routes.
//
// We display the editor's toolbar in an [OverlayEntry], so inserting it
// at the navigator's [Overlay] causes widgets that are displayed in routes,
// e.g. [DropdownButton] items, to be displayed beneath the toolbar.
return Overlay(
initialEntries: [
OverlayEntry(builder: (context) {
return Scaffold(
key: _scaffoldKey,
appBar: _buildAppBar(context),
extendBodyBehindAppBar: true,
body: _selectedMenuItem!.pageBuilder(context),
drawer: _buildDrawer(),
);
})
],
// We need a FocusScope above the Overlay so that focus can be shared between
// SuperEditor in one OverlayEntry, and the popover toolbar in another OverlayEntry.
return FocusScope(
// We need our own [Overlay] instead of the one created by the navigator
// because overlay entries added to navigator's [Overlay] are always
// displayed above all routes.
//
// We display the editor's toolbar in an [OverlayEntry], so inserting it
// at the navigator's [Overlay] causes widgets that are displayed in routes,
// e.g. [DropdownButton] items, to be displayed beneath the toolbar.
child: Overlay(
initialEntries: [
OverlayEntry(builder: (context) {
return Scaffold(
key: _scaffoldKey,
appBar: _buildAppBar(context),
extendBodyBehindAppBar: true,
body: _selectedMenuItem!.pageBuilder(context),
drawer: _buildDrawer(),
);
})
],
),
);
}

Expand Down
10 changes: 5 additions & 5 deletions super_editor/example/pubspec.lock
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ packages:
name: attributed_text
url: "https://pub.dartlang.org"
source: hosted
version: "0.1.3"
version: "0.2.0"
boolean_selector:
dependency: transitive
description:
Expand Down Expand Up @@ -65,7 +65,7 @@ packages:
source: hosted
version: "1.1.0"
collection:
dependency: transitive
dependency: "direct main"
description:
name: collection
url: "https://pub.dartlang.org"
Expand Down Expand Up @@ -459,21 +459,21 @@ packages:
path: ".."
relative: true
source: path
version: "0.2.0"
version: "0.2.2"
super_editor_markdown:
dependency: "direct main"
description:
path: "../../super_editor_markdown"
relative: true
source: path
version: "0.1.0"
version: "0.1.3"
super_text_layout:
dependency: "direct main"
description:
path: "../../super_text_layout"
relative: true
source: path
version: "0.1.0"
version: "0.1.3"
term_glyph:
dependency: transitive
description:
Expand Down
1 change: 1 addition & 0 deletions super_editor/example/pubspec.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ dependencies:
cupertino_icons: ^1.0.1

charcode: ^1.1.3
collection: ^1.15.0
flutter_keyboard_visibility: ^5.0.3
google_fonts: ^2.0.0
http: ^0.13.1
Expand Down
Loading