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

This adds multiline text widget support. #12120

Merged
merged 2 commits into from
Sep 27, 2017

Conversation

gspencergoog
Copy link
Contributor

@gspencergoog gspencergoog commented Sep 15, 2017

This adds support for multi-line text widgets, making a new TextInputAction.newline enum, and supporting a new TextInputType.multiline enum value.

There are still some issues with cursor placement in multi-line input, but those may go away when we switch to a non-Blink text renderer.

Fixes #8028

@@ -56,6 +63,9 @@ enum TextInputType {
enum TextInputAction {
/// Complete the text input operation.
done,
/// The action to take when the enter button is pressed in a multi-line
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: missing newline

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed.

@@ -93,13 +106,17 @@ class TextInputConfiguration {
/// What text to display in the text input control's action button.
final String actionLabel;

/// What kind of action to request for the action button on the IME.
final TextInputAction inputAction;

/// Returns a representation of this object as a JSON object.
Map<String, dynamic> toJSON() {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this isn't a JSON object, it's a Map...

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(no need to fix this unless you want to go on a rampage and fix all of them)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think I'll leave that for another rampage. But I agree with you.

@@ -276,6 +293,8 @@ class TextInputConnection {

TextInputAction _toTextInputAction(String action) {
switch (action) {
case 'TextInputAction.newline':
return TextInputAction.newline;
case 'TextInputAction.done':
return TextInputAction.done;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

you should keep the switch and the enum definition in the same order unless the order matters

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed.

/// the number of lines. By default, it is 1, meaning this is a single-line
/// text field. If it is not null, it must be greater than zero.
/// the number of lines. By default, it is one, meaning this is a single-line
/// text field. [maxLines] must not be set to zero.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

According to your change here, it's now allowed to be negative, which I doubt is what you intended.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yikes. Yes, you're correct. Fixed.

/// The [controller], [focusNode], [style], [cursorColor], and [textAlign]
/// arguments must not be null.
/// If [maxLines] is not one, then [keyboardType] will be ignored, and the
/// keyboard type [TextInputType.multiline] will be used.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it'd be cleaner if the default for keyboardType depended on maxLines, but if it was set, it was honoured regardless.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

+1. I can't imagine much use for a multi-line phone number, but it does seem fair that if someone adds a multi-line text field and request a phone keyboard, that we give them one.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

OK, I'll honor the setting then. Each of our existing keyboard types is for single-line input, so it didn't seem to make sense for multiline fields to use a single-line keyboard, but I guess they should get what they ask for.

Note that if I do it this way, then it won't assert if they pass an explicit null for keyboardType, it'll just use the default value (since I have to use null to tell if we are in a default state or not).

@@ -194,7 +199,7 @@ class EditableText extends StatefulWidget {
/// Defaults to false.
final bool obscureText;

/// Whether to enable autocorrection.
/// Whether to enable auto-correction.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Wikipedia says "autocorrection" is correct.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reverted.

inputAction: widget.keyboardType == TextInputType.multiline
? TextInputAction.newline
: TextInputAction.done
))
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the formatting is off somehow here. There's two closing parens on the same line, but I don't see any lines with two opening parens.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

OK, I think I fixed it.

@@ -28,6 +28,9 @@ class TestTextInput {

int _client = 0;

/// Arguments supplied to setCient.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

typo?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed.

@Hixie
Copy link
Contributor

Hixie commented Sep 20, 2017

LGTM modulo comments

/// Requests the default platform keyboard, but accepts newlines when the
/// enter key is pressed. This is the input type used for all multi-line text
/// fields.
multiline,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would multilineText be better, or just more pedantic?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it would be redundant. I like multiline because we're already talking about "TextInputType", so it's already clear that it's text.

@@ -56,6 +63,9 @@ enum TextInputType {
enum TextInputAction {
/// Complete the text input operation.
done,
/// The action to take when the enter button is pressed in a multi-line
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: s/button/key/ also covers physical keyboards.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Funny, I chose 'button' because I felt it covered both, whereas 'key' just covered physical keyboards. Mind if I keep it as 'button'?

controller: controller,
focusNode: focusNode,
style: textStyle,
cursorColor: cursorColor)));
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Here and below: trailing commas.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

tester.firstWidget(find.byType(EditableText));
expect(editableText.maxLines, equals(1));
expect(editableText.obscureText, equals(false));
expect(editableText.autocorrect, equals(true));
Copy link
Member

@cbracken cbracken Sep 20, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

isFalse, isTrue.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.

await tester.showKeyboard(find.byType(EditableText));
controller.text = 'test';
await tester.idle();
print(tester.testTextInput.editingState.toString());
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Delete this line.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Whoops. Debug print snuck in.

print(tester.testTextInput.editingState.toString());
expect(tester.testTextInput.editingState['text'], equals('test'));
expect(tester.testTextInput.setClientArgs['inputType'],
equals('TextInputType.multiline'));
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fine to wrap up to prev line. Even though it's a little over 80, it reads a teensy bit better.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done, although I'm not really seeing an algorithm for the line wraps here...

await tester.showKeyboard(find.byType(EditableText));
controller.text = 'test';
await tester.idle();
print(tester.testTextInput.editingState.toString());
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Drop this line.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Dropped all prints.

await tester.showKeyboard(find.byType(EditableText));
controller.text = 'test';
await tester.idle();
print(tester.testTextInput.editingState.toString());
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Drop this one too :)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

await tester.showKeyboard(find.byType(EditableText));
controller.text = 'test';
await tester.idle();
print(tester.testTextInput.editingState.toString());
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

And this one.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Die print, die!

@cbracken
Copy link
Member

Nice!
lgtm
modulo comments too.

@github-actions github-actions bot locked as resolved and limited conversation to collaborators Aug 12, 2021
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Support specifying system keyboard with carriage return for multiline text editing
4 participants