Unverified Commit 99b6bd8c authored by Renzo Olivares's avatar Renzo Olivares Committed by GitHub

Add support for extending selection to paragraph on ctrl + shift + arrow...

Add support for extending selection to paragraph on ctrl + shift + arrow up/down on Non-Apple platforms (#120151)

* Add support for extending selection to paragraph on ctrl + shift + arrow up/down for common keyboard actions

* Add ctrl + shift + arrow up/down common text editing shortcuts/actions

* fix analyzer

---------
Co-authored-by: 's avatarRenzo Olivares <roliv@google.com>
parent f94fa7ea
...@@ -207,6 +207,9 @@ class DefaultTextEditingShortcuts extends StatelessWidget { ...@@ -207,6 +207,9 @@ class DefaultTextEditingShortcuts extends StatelessWidget {
const SingleActivator(LogicalKeyboardKey.arrowLeft, shift: true, control: true): const ExtendSelectionToNextWordBoundaryIntent(forward: false, collapseSelection: false), const SingleActivator(LogicalKeyboardKey.arrowLeft, shift: true, control: true): const ExtendSelectionToNextWordBoundaryIntent(forward: false, collapseSelection: false),
const SingleActivator(LogicalKeyboardKey.arrowRight, shift: true, control: true): const ExtendSelectionToNextWordBoundaryIntent(forward: true, collapseSelection: false), const SingleActivator(LogicalKeyboardKey.arrowRight, shift: true, control: true): const ExtendSelectionToNextWordBoundaryIntent(forward: true, collapseSelection: false),
const SingleActivator(LogicalKeyboardKey.arrowUp, shift: true, control: true): const ExtendSelectionToNextParagraphBoundaryIntent(forward: false, collapseSelection: false),
const SingleActivator(LogicalKeyboardKey.arrowDown, shift: true, control: true): const ExtendSelectionToNextParagraphBoundaryIntent(forward: true, collapseSelection: false),
// Page Up / Down: Move selection by page. // Page Up / Down: Move selection by page.
const SingleActivator(LogicalKeyboardKey.pageUp): const ExtendSelectionVerticallyToAdjacentPageIntent(forward: false, collapseSelection: true), const SingleActivator(LogicalKeyboardKey.pageUp): const ExtendSelectionVerticallyToAdjacentPageIntent(forward: false, collapseSelection: true),
const SingleActivator(LogicalKeyboardKey.pageDown): const ExtendSelectionVerticallyToAdjacentPageIntent(forward: true, collapseSelection: true), const SingleActivator(LogicalKeyboardKey.pageDown): const ExtendSelectionVerticallyToAdjacentPageIntent(forward: true, collapseSelection: true),
......
...@@ -4424,6 +4424,7 @@ class EditableTextState extends State<EditableText> with AutomaticKeepAliveClien ...@@ -4424,6 +4424,7 @@ class EditableTextState extends State<EditableText> with AutomaticKeepAliveClien
ExtendSelectionByCharacterIntent: _makeOverridable(_UpdateTextSelectionAction<ExtendSelectionByCharacterIntent>(this, _characterBoundary, _moveBeyondTextBoundary, ignoreNonCollapsedSelection: false)), ExtendSelectionByCharacterIntent: _makeOverridable(_UpdateTextSelectionAction<ExtendSelectionByCharacterIntent>(this, _characterBoundary, _moveBeyondTextBoundary, ignoreNonCollapsedSelection: false)),
ExtendSelectionByPageIntent: _makeOverridable(CallbackAction<ExtendSelectionByPageIntent>(onInvoke: _extendSelectionByPage)), ExtendSelectionByPageIntent: _makeOverridable(CallbackAction<ExtendSelectionByPageIntent>(onInvoke: _extendSelectionByPage)),
ExtendSelectionToNextWordBoundaryIntent: _makeOverridable(_UpdateTextSelectionAction<ExtendSelectionToNextWordBoundaryIntent>(this, _nextWordBoundary, _moveBeyondTextBoundary, ignoreNonCollapsedSelection: true)), ExtendSelectionToNextWordBoundaryIntent: _makeOverridable(_UpdateTextSelectionAction<ExtendSelectionToNextWordBoundaryIntent>(this, _nextWordBoundary, _moveBeyondTextBoundary, ignoreNonCollapsedSelection: true)),
ExtendSelectionToNextParagraphBoundaryIntent : _makeOverridable(_UpdateTextSelectionAction<ExtendSelectionToNextParagraphBoundaryIntent>(this, _paragraphBoundary, _moveBeyondTextBoundary, ignoreNonCollapsedSelection: true)),
ExtendSelectionToLineBreakIntent: _makeOverridable(_UpdateTextSelectionAction<ExtendSelectionToLineBreakIntent>(this, _linebreak, _moveToTextBoundary, ignoreNonCollapsedSelection: true)), ExtendSelectionToLineBreakIntent: _makeOverridable(_UpdateTextSelectionAction<ExtendSelectionToLineBreakIntent>(this, _linebreak, _moveToTextBoundary, ignoreNonCollapsedSelection: true)),
ExtendSelectionVerticallyToAdjacentLineIntent: _makeOverridable(_verticalSelectionUpdateAction), ExtendSelectionVerticallyToAdjacentLineIntent: _makeOverridable(_verticalSelectionUpdateAction),
ExtendSelectionVerticallyToAdjacentPageIntent: _makeOverridable(_verticalSelectionUpdateAction), ExtendSelectionVerticallyToAdjacentPageIntent: _makeOverridable(_verticalSelectionUpdateAction),
......
...@@ -221,12 +221,25 @@ class ExtendSelectionVerticallyToAdjacentPageIntent extends DirectionalCaretMove ...@@ -221,12 +221,25 @@ class ExtendSelectionVerticallyToAdjacentPageIntent extends DirectionalCaretMove
}) : super(forward, collapseSelection); }) : super(forward, collapseSelection);
} }
/// Extends, or moves the current selection from the current
/// [TextSelection.extent] position to the previous or the next paragraph
/// boundary.
class ExtendSelectionToNextParagraphBoundaryIntent extends DirectionalCaretMovementIntent {
/// Creates an [ExtendSelectionToNextParagraphBoundaryIntent].
const ExtendSelectionToNextParagraphBoundaryIntent({
required bool forward,
required bool collapseSelection,
}) : super(forward, collapseSelection);
}
/// Extends, or moves the current selection from the current /// Extends, or moves the current selection from the current
/// [TextSelection.extent] position to the previous or the next paragraph /// [TextSelection.extent] position to the previous or the next paragraph
/// boundary depending on the [forward] parameter. /// boundary depending on the [forward] parameter.
/// ///
/// This [Intent] collapses the selection when the order of [TextSelection.base] /// This [Intent] typically has the same effect as an
/// and [TextSelection.extent] would reverse. /// [ExtendSelectionToNextParagraphBoundaryIntent], except it collapses the selection
/// when the order of [TextSelection.base] and [TextSelection.extent] would
/// reverse.
/// ///
/// This is typically only used on MacOS. /// This is typically only used on MacOS.
class ExtendSelectionToNextParagraphBoundaryOrCaretLocationIntent extends DirectionalCaretMovementIntent { class ExtendSelectionToNextParagraphBoundaryOrCaretLocationIntent extends DirectionalCaretMovementIntent {
......
...@@ -6723,7 +6723,7 @@ void main() { ...@@ -6723,7 +6723,7 @@ void main() {
); );
expect(controller.text, equals(testText), reason: 'on $platform'); expect(controller.text, equals(testText), reason: 'on $platform');
final bool platformCanSelectByParagraph = defaultTargetPlatform == TargetPlatform.iOS || defaultTargetPlatform == TargetPlatform.macOS; final bool platformIsApple = defaultTargetPlatform == TargetPlatform.iOS || defaultTargetPlatform == TargetPlatform.macOS;
// Move down one paragraph. // Move down one paragraph.
await sendKeys( await sendKeys(
tester, tester,
...@@ -6738,9 +6738,9 @@ void main() { ...@@ -6738,9 +6738,9 @@ void main() {
expect( expect(
selection, selection,
equals( equals(
TextSelection( const TextSelection(
baseOffset: 10, baseOffset: 10,
extentOffset: platformCanSelectByParagraph ? 20 : 10, extentOffset: 20,
), ),
), ),
reason: 'on $platform', reason: 'on $platform',
...@@ -6760,9 +6760,9 @@ void main() { ...@@ -6760,9 +6760,9 @@ void main() {
expect( expect(
selection, selection,
equals( equals(
TextSelection( const TextSelection(
baseOffset: 10, baseOffset: 10,
extentOffset: platformCanSelectByParagraph ? 36 : 10, extentOffset: 36,
), ),
), ),
reason: 'on $platform', reason: 'on $platform',
...@@ -6782,9 +6782,9 @@ void main() { ...@@ -6782,9 +6782,9 @@ void main() {
expect( expect(
selection, selection,
equals( equals(
TextSelection( const TextSelection(
baseOffset: 10, baseOffset: 10,
extentOffset: platformCanSelectByParagraph ? 55 : 10, extentOffset: 55,
), ),
), ),
reason: 'on $platform', reason: 'on $platform',
...@@ -6804,9 +6804,9 @@ void main() { ...@@ -6804,9 +6804,9 @@ void main() {
expect( expect(
selection, selection,
equals( equals(
TextSelection( const TextSelection(
baseOffset: 10, baseOffset: 10,
extentOffset: platformCanSelectByParagraph ? 36 : 10, extentOffset: 36,
), ),
), ),
reason: 'on $platform', reason: 'on $platform',
...@@ -6826,15 +6826,16 @@ void main() { ...@@ -6826,15 +6826,16 @@ void main() {
expect( expect(
selection, selection,
equals( equals(
TextSelection( const TextSelection(
baseOffset: 10, baseOffset: 10,
extentOffset: platformCanSelectByParagraph ? 20 : 10, extentOffset: 20,
), ),
), ),
reason: 'on $platform', reason: 'on $platform',
); );
// Move up back to the origin. // Move up. This will collapse the selection to the origin on Apple platforms, and
// extend to the previous paragraph boundary on other platforms.
await sendKeys( await sendKeys(
tester, tester,
<LogicalKeyboardKey>[ <LogicalKeyboardKey>[
...@@ -6850,13 +6851,15 @@ void main() { ...@@ -6850,13 +6851,15 @@ void main() {
equals( equals(
TextSelection( TextSelection(
baseOffset: 10, baseOffset: 10,
extentOffset: platformCanSelectByParagraph ? 10 : 10, extentOffset: platformIsApple ? 10 : 0,
), ),
), ),
reason: 'on $platform', reason: 'on $platform',
); );
// Move up, extending the selection backwards to the next paragraph. // Move up, extending the selection backwards to the previous paragraph on Apple platforms.
// On other platforms this does nothing since our extent is already at 0 from the previous
// set of keys sent.
await sendKeys( await sendKeys(
tester, tester,
<LogicalKeyboardKey>[ <LogicalKeyboardKey>[
...@@ -6867,12 +6870,36 @@ void main() { ...@@ -6867,12 +6870,36 @@ void main() {
targetPlatform: defaultTargetPlatform, targetPlatform: defaultTargetPlatform,
); );
expect(
selection,
equals(
const TextSelection(
baseOffset: 10,
extentOffset: 0,
),
),
reason: 'on $platform',
);
// Move down, collapsing the selection to the origin on Apple platforms.
// On other platforms this moves the selection's extent to the next paragraph boundary.
await sendKeys(
tester,
<LogicalKeyboardKey>[
LogicalKeyboardKey.arrowDown,
],
shift: true,
wordModifier: true,
targetPlatform: defaultTargetPlatform,
);
expect( expect(
selection, selection,
equals( equals(
TextSelection( TextSelection(
baseOffset: 10, baseOffset: 10,
extentOffset: platformCanSelectByParagraph ? 0 : 10, extentOffset: platformIsApple ? 10 : 20,
affinity: platformIsApple ? TextAffinity.upstream : TextAffinity.downstream,
), ),
), ),
reason: 'on $platform', reason: 'on $platform',
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment