Commit b7396ba1 authored by Adam Barth's avatar Adam Barth

Merge pull request #1379 from abarth/protect_editable_string

Hide EditableString implementation details
parents 7737117a f0ea0eaf
......@@ -109,7 +109,7 @@ class _InputState extends State<Input> {
_editableString.selection.end);
} else if (!focused && _keyboardHandle.attached) {
_keyboardHandle.release();
_editableString.composing = TextRange.empty;
_editableString.didDetachKeyboard();
}
}
......
......@@ -23,8 +23,10 @@ class _KeyboardConnection {
static final _KeyboardConnection instance = new _KeyboardConnection();
}
/// An interface to the system's keyboard.
///
/// Most clients will want to use the [keyboard] singleton instance.
class Keyboard {
Keyboard(this.service);
// The service is exposed in case you need direct access.
......
......@@ -26,11 +26,7 @@ class TextRange {
end = position;
/// A text range that contains nothing and is not in the text.
const TextRange._empty()
: start = -1,
end = -1;
static const TextRange empty = const TextRange._empty();
static const TextRange empty = const TextRange(start: -1, end: -1);
/// The index of the first character in the range.
final int start;
......@@ -43,11 +39,29 @@ class TextRange {
/// Whether this range is empty (but still potentially placed inside the text).
bool get isCollapsed => start == end;
/// The text before this range.
String textBefore(String text) {
return text.substring(0, start);
}
/// The text after this range.
String textAfter(String text) {
return text.substring(end);
}
/// The text inside this range.
String textInside(String text) {
return text.substring(start, end);
}
}
/// A string that can be manipulated by a keyboard.
class EditableString implements KeyboardClient {
EditableString({this.text: '', this.onUpdated, this.onSubmitted}) {
class _KeyboardClientImpl implements KeyboardClient {
_KeyboardClientImpl({
this.text: '',
this.onUpdated,
this.onSubmitted
}) {
assert(onUpdated != null);
assert(onSubmitted != null);
stub = new KeyboardClientStub.unbound()..impl = this;
......@@ -57,39 +71,24 @@ class EditableString implements KeyboardClient {
/// The current text being edited.
String text;
// The range of text that is still being composed.
TextRange composing = TextRange.empty;
/// The range of text that is currently selected.
TextRange selection;
/// Called whenever the text changes.
final VoidCallback onUpdated;
/// Called whenever the user indicates they are done editing the string.
final VoidCallback onSubmitted;
/// A keyboard client stub that can be attached to a keyboard service.
KeyboardClientStub stub;
/// The text before the given range.
String textBefore(TextRange range) {
return text.substring(0, range.start);
}
// The range of text that is still being composed.
TextRange composing = TextRange.empty;
/// The text after the given range.
String textAfter(TextRange range) {
return text.substring(range.end);
}
/// The range of text that is currently selected.
TextRange selection = TextRange.empty;
/// The text inside the given range.
String textInside(TextRange range) {
return text.substring(range.start, range.end);
}
/// A keyboard client stub that can be attached to a keyboard service.
KeyboardClientStub stub;
void _delete(TextRange range) {
if (range.isCollapsed || !range.isValid) return;
text = textBefore(range) + textAfter(range);
text = range.textBefore(text) + range.textAfter(text);
}
TextRange _append(String newText) {
......@@ -101,8 +100,8 @@ class EditableString implements KeyboardClient {
TextRange _replace(TextRange range, String newText) {
assert(range.isValid);
String before = textBefore(range);
String after = textAfter(range);
String before = range.textBefore(text);
String after = range.textAfter(text);
text = before + newText + after;
return new TextRange(
......@@ -168,6 +167,42 @@ class EditableString implements KeyboardClient {
}
}
/// A string that can be manipulated by a keyboard.
///
/// Can be displayed with [RawEditableLine]. For a more featureful input widget,
/// consider using [Input].
class EditableString {
EditableString({
String text: '',
VoidCallback onUpdated,
VoidCallback onSubmitted
}) : _client = new _KeyboardClientImpl(
text: text,
onUpdated: onUpdated,
onSubmitted: onSubmitted
);
final _KeyboardClientImpl _client;
/// The current text being edited.
String get text => _client.text;
// The range of text that is still being composed.
TextRange get composing => _client.composing;
/// The range of text that is currently selected.
TextRange get selection => _client.selection;
/// A keyboard client stub that can be attached to a keyboard service.
///
/// See [Keyboard].
KeyboardClientStub get stub => _client.stub;
void didDetachKeyboard() {
_client.composing = TextRange.empty;
}
}
/// A basic single-line input control.
///
/// This control is not intended to be used directly. Instead, consider using
......@@ -337,11 +372,11 @@ class _EditableLineWidget extends LeafRenderObjectWidget {
);
return new StyledTextSpan(style, <TextSpan>[
new PlainTextSpan(value.textBefore(value.composing)),
new PlainTextSpan(value.composing.textBefore(value.text)),
new StyledTextSpan(composingStyle, <TextSpan>[
new PlainTextSpan(value.textInside(value.composing))
new PlainTextSpan(value.composing.textInside(value.text))
]),
new PlainTextSpan(value.textAfter(value.composing))
new PlainTextSpan(value.composing.textAfter(value.text))
]);
}
......
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