Skip to content

Commit

Permalink
Support correct keyboards for multi-line text editing. (flutter#4115)
Browse files Browse the repository at this point in the history
This addresses part of flutter#8028, implementing the Engine-side support for it.
  • Loading branch information
gspencergoog authored Sep 26, 2017
1 parent 9c518cb commit faabc10
Show file tree
Hide file tree
Showing 5 changed files with 53 additions and 7 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
import android.text.Editable;
import android.text.Selection;
import android.view.inputmethod.BaseInputConnection;
import android.view.inputmethod.EditorInfo;
import android.view.inputmethod.InputMethodManager;
import android.view.KeyEvent;

Expand Down Expand Up @@ -92,7 +93,7 @@ public boolean commitText(CharSequence text, int newCursorPosition) {
public boolean deleteSurroundingText(int beforeLength, int afterLength) {
if (Selection.getSelectionStart(mEditable) == -1 ||
Selection.getSelectionStart(mEditable) == -1)
return true;
return true;9c518cb751e34b0

boolean result = super.deleteSurroundingText(beforeLength, afterLength);
updateEditingState();
Expand Down Expand Up @@ -162,8 +163,17 @@ public boolean sendKeyEvent(KeyEvent event) {
@Override
public boolean performEditorAction(int actionCode) {
// TODO(abarth): Support more actions.
mFlutterChannel.invokeMethod("TextInputClient.performAction",
Arrays.asList(mClient, "TextInputAction.done"));
switch (actionCode) {
case EditorInfo.IME_ACTION_NONE:
mFlutterChannel.invokeMethod("TextInputClient.performAction",
Arrays.asList(mClient, "TextInputAction.newline"));
break;
default:
case EditorInfo.IME_ACTION_DONE:
mFlutterChannel.invokeMethod("TextInputClient.performAction",
Arrays.asList(mClient, "TextInputAction.done"));
break;
}
return true;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,9 @@ private static int inputTypeFromTextInputType(String inputType,
return InputType.TYPE_CLASS_PHONE;

int textType = InputType.TYPE_CLASS_TEXT;
if (inputType.equals("TextInputType.emailAddress"))
if (inputType.equals("TextInputType.multiline"))
textType |= InputType.TYPE_TEXT_FLAG_MULTI_LINE;
else if (inputType.equals("TextInputType.emailAddress"))
textType |= InputType.TYPE_TEXT_VARIATION_EMAIL_ADDRESS;
else if (inputType.equals("TextInputType.url"))
textType |= InputType.TYPE_TEXT_VARIATION_URI;
Expand All @@ -102,6 +104,12 @@ else if (inputType.equals("TextInputType.url"))
return textType;
}

private static int inputActionFromTextInputAction(String inputAction) {
if (inputAction.equals("TextInputAction.newline"))
return EditorInfo.IME_ACTION_NONE;
return EditorInfo.IME_ACTION_DONE;
}

public InputConnection createInputConnection(FlutterView view, EditorInfo outAttrs)
throws JSONException {
if (mClient == 0)
Expand All @@ -111,9 +119,22 @@ public InputConnection createInputConnection(FlutterView view, EditorInfo outAtt
mConfiguration.getString("inputType"),
mConfiguration.optBoolean("obscureText"),
mConfiguration.optBoolean("autocorrect", true));
if (!mConfiguration.isNull("actionLabel"))
outAttrs.actionLabel = mConfiguration.getString("actionLabel");
outAttrs.imeOptions = EditorInfo.IME_ACTION_DONE | EditorInfo.IME_FLAG_NO_FULLSCREEN;
outAttrs.imeOptions = EditorInfo.IME_FLAG_NO_FULLSCREEN;
int enterAction;
if (mConfiguration.isNull("inputAction")) {
// If an explicit input action isn't set, then default to none for multi-line fields
// and done for single line fields.
enterAction = (InputType.TYPE_TEXT_FLAG_MULTI_LINE & outAttrs.inputType) != 0
? EditorInfo.IME_ACTION_NONE
: EditorInfo.IME_ACTION_DONE;
} else {
enterAction = inputActionFromTextInputAction(mConfiguration.getString("inputAction"));
}
if (!mConfiguration.isNull("actionLabel")) {
outAttrs.actionLabel = mConfiguration.getString("actionLabel");
outAttrs.actionId = enterAction;
}
outAttrs.imeOptions |= enterAction;

InputConnectionAdaptor connection = new InputConnectionAdaptor(view, mClient, mFlutterChannel, mEditable);
outAttrs.initialSelStart = Math.max(Selection.getSelectionStart(mEditable), 0);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@

typedef NS_ENUM(NSInteger, FlutterTextInputAction) {
FlutterTextInputActionDone,
FlutterTextInputActionNewline,
};

@protocol FlutterTextInputDelegate<NSObject>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@
static UIKeyboardType ToUIKeyboardType(NSString* inputType) {
if ([inputType isEqualToString:@"TextInputType.text"])
return UIKeyboardTypeDefault;
if ([inputType isEqualToString:@"TextInputType.multiline"])
return UIKeyboardTypeDefault;
if ([inputType isEqualToString:@"TextInputType.number"])
return UIKeyboardTypeDecimalPad;
if ([inputType isEqualToString:@"TextInputType.phone"])
Expand All @@ -23,6 +25,12 @@ static UIKeyboardType ToUIKeyboardType(NSString* inputType) {
return UIKeyboardTypeDefault;
}

static UIReturnKeyType ToUIReturnKeyType(NSString* inputType) {
if ([inputType isEqualToString:@"TextInputType.multiline"])
return UIReturnKeyDefault;
return UIReturnKeyDone;
}

static UITextAutocapitalizationType ToUITextAutocapitalizationType(NSString* inputType) {
if ([inputType isEqualToString:@"TextInputType.text"])
return UITextAutocapitalizationTypeSentences;
Expand Down Expand Up @@ -272,6 +280,8 @@ - (BOOL)shouldChangeTextInRange:(UITextRange*)range replacementText:(NSString*)t
[_textInputDelegate performAction:FlutterTextInputActionDone withClient:_textInputClient];
return NO;
}
if (self.returnKeyType == UIReturnKeyDefault && [text isEqualToString:@"\n"])
[_textInputDelegate performAction:FlutterTextInputActionNewline withClient:_textInputClient];
return YES;
}

Expand Down Expand Up @@ -569,6 +579,7 @@ - (void)hideTextInput {

- (void)setTextInputClient:(int)client withConfiguration:(NSDictionary*)configuration {
_view.keyboardType = ToUIKeyboardType(configuration[@"inputType"]);
_view.returnKeyType = ToUIReturnKeyType(configuration[@"inputType"]);
_view.autocapitalizationType = ToUITextAutocapitalizationType(configuration[@"inputType"]);
_view.secureTextEntry = [configuration[@"obscureText"] boolValue];
NSString* autocorrect = configuration[@"autocorrect"];
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -626,6 +626,9 @@ - (void)performAction:(FlutterTextInputAction)action withClient:(int)client {
case FlutterTextInputActionDone:
actionString = @"TextInputAction.done";
break;
case FlutterTextInputActionNewline:
actionString = @"TextInputAction.newline";
break;
}
[_textInputChannel.get() invokeMethod:@"TextInputClient.performAction"
arguments:@[ @(client), actionString ]];
Expand Down

0 comments on commit faabc10

Please sign in to comment.