Commit 6bdd2883 authored by Jason Simmons's avatar Jason Simmons

Merge pull request #1615 from jason-simmons/edit_text_action_button_2

Implement better synchronization between the state of the input widget and the keyboard IME
parents 3c94991c 98b83e0c
......@@ -13,6 +13,7 @@ import 'theme.dart';
export 'package:flutter/services.dart' show KeyboardType;
typedef void StringValueChanged(String value);
typedef void StringValueSubmitted(String value);
// TODO(eseidel): This isn't right, it's 16px on the bottom:
// http://www.google.com/design/spec/components/text-fields.html#text-fields-single-line-text-field
......@@ -24,7 +25,8 @@ class Input extends Scrollable {
this.initialValue: '',
this.placeholder,
this.onChanged,
this.keyboardType: KeyboardType.TEXT
this.keyboardType: KeyboardType.TEXT,
this.onSubmitted
}) : super(
key: key,
initialScrollOffset: 0.0,
......@@ -35,6 +37,7 @@ class Input extends Scrollable {
final KeyboardType keyboardType;
final String placeholder;
final StringValueChanged onChanged;
final StringValueSubmitted onSubmitted;
_InputState createState() => new _InputState();
}
......@@ -52,7 +55,8 @@ class _InputState extends ScrollableState<Input> {
_value = config.initialValue;
_editableValue = new EditableString(
text: _value,
onUpdated: _handleTextUpdated
onUpdated: _handleTextUpdated,
onSubmitted: _handleTextSubmitted
);
}
......@@ -66,12 +70,20 @@ class _InputState extends ScrollableState<Input> {
}
}
void _handleTextSubmitted() {
if (config.onSubmitted != null)
config.onSubmitted(_value);
}
Widget buildContent(BuildContext context) {
ThemeData themeData = Theme.of(context);
bool focused = Focus.at(context, config);
if (focused && !_keyboardHandle.attached) {
_keyboardHandle = keyboard.show(_editableValue.stub, config.keyboardType);
_keyboardHandle.setText(_editableValue.text);
_keyboardHandle.setSelection(_editableValue.selection.start,
_editableValue.selection.end);
} else if (!focused && _keyboardHandle.attached) {
_keyboardHandle.release();
}
......
......@@ -77,6 +77,18 @@ class KeyboardHandle {
assert(_keyboard._currentHandle != this);
}
void setText(String text) {
assert(_attached);
assert(_keyboard._currentHandle == this);
_keyboard.service.setText(text);
}
void setSelection(int start, int end) {
assert(_attached);
assert(_keyboard._currentHandle == this);
_keyboard.service.setSelection(start, end);
}
}
final Keyboard keyboard = new Keyboard(_KeyboardConnection.instance.keyboardService);
......@@ -14,6 +14,7 @@ import 'framework.dart';
const _kCursorBlinkHalfPeriod = 500; // milliseconds
typedef void StringUpdated();
typedef void StringSubmitted();
class TextRange {
const TextRange({ this.start, this.end });
......@@ -32,18 +33,22 @@ class TextRange {
}
class EditableString implements KeyboardClient {
EditableString({this.text: '', this.onUpdated, this.onSubmitted}) {
assert(onUpdated != null);
assert(onSubmitted != null);
stub = new KeyboardClientStub.unbound()..impl = this;
selection = new TextRange(start: text.length, end: text.length);
}
String text;
TextRange composing = const TextRange.empty();
TextRange selection = const TextRange.empty();
TextRange selection;
final StringUpdated onUpdated;
final StringSubmitted onSubmitted;
KeyboardClientStub stub;
EditableString({this.text: '', this.onUpdated}) {
stub = new KeyboardClientStub.unbound()..impl = this;
}
String textBefore(TextRange range) {
return text.substring(0, range.start);
}
......@@ -129,7 +134,9 @@ class EditableString implements KeyboardClient {
onUpdated();
}
void submit(SubmitAction action) {}
void submit(SubmitAction action) {
onSubmitted();
}
}
class EditableText extends StatefulComponent {
......
......@@ -17,6 +17,10 @@ class MockKeyboard implements KeyboardService {
void showByRequest() {}
void hide() {}
void setText(String text) {}
void setSelection(int start, int end) {}
}
void main() {
......
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