| OLD | NEW |
| 1 // Copyright 2015 The Chromium Authors. All rights reserved. | 1 // Copyright 2015 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 import '../painting/text_style.dart'; | 5 import '../painting/text_style.dart'; |
| 6 import '../theme/colors.dart'; | |
| 7 import '../theme/typography.dart' as typography; | |
| 8 import '../widgets/basic.dart'; | 6 import '../widgets/basic.dart'; |
| 7 import '../widgets/theme.dart'; |
| 9 import 'editable_string.dart'; | 8 import 'editable_string.dart'; |
| 10 import 'editable_text.dart'; | 9 import 'editable_text.dart'; |
| 11 import 'keyboard.dart'; | 10 import 'keyboard.dart'; |
| 12 | 11 |
| 13 typedef void ValueChanged(value); | 12 typedef void ValueChanged(value); |
| 14 | 13 |
| 14 const double _kHintOpacity = 0.26; |
| 15 const EdgeDims _kTextfieldPadding = const EdgeDims.symmetric(vertical: 8.0); |
| 16 |
| 15 class Input extends Component { | 17 class Input extends Component { |
| 16 | 18 |
| 17 Input({String key, | 19 Input({String key, |
| 18 this.placeholder, | 20 this.placeholder, |
| 19 this.onChanged, | 21 this.onChanged, |
| 20 this.focused}) | 22 this.focused}) |
| 21 : super(key: key, stateful: true) { | 23 : super(key: key, stateful: true) { |
| 22 _editableValue = new EditableString( | 24 _editableValue = new EditableString( |
| 23 text: _value, | 25 text: _value, |
| 24 onUpdated: _handleTextUpdated | 26 onUpdated: _handleTextUpdated |
| 25 ); | 27 ); |
| 26 } | 28 } |
| 27 | 29 |
| 28 static final TextStyle _placeholderStyle = typography.black.caption; | |
| 29 | |
| 30 String placeholder; | 30 String placeholder; |
| 31 ValueChanged onChanged; | 31 ValueChanged onChanged; |
| 32 bool focused = false; | 32 bool focused = false; |
| 33 | 33 |
| 34 void syncFields(Input source) { | 34 void syncFields(Input source) { |
| 35 placeholder = source.placeholder; | 35 placeholder = source.placeholder; |
| 36 onChanged = source.onChanged; | 36 onChanged = source.onChanged; |
| 37 focused = source.focused; | 37 focused = source.focused; |
| 38 } | 38 } |
| 39 | 39 |
| 40 String _value = ''; | 40 String _value = ''; |
| 41 bool _isAttachedToKeyboard = false; | 41 bool _isAttachedToKeyboard = false; |
| 42 EditableString _editableValue; | 42 EditableString _editableValue; |
| 43 | 43 |
| 44 void _handleTextUpdated() { | 44 void _handleTextUpdated() { |
| 45 scheduleBuild(); | 45 scheduleBuild(); |
| 46 if (_value != _editableValue.text) { | 46 if (_value != _editableValue.text) { |
| 47 _value = _editableValue.text; | 47 _value = _editableValue.text; |
| 48 if (onChanged != null) | 48 if (onChanged != null) |
| 49 onChanged(_value); | 49 onChanged(_value); |
| 50 } | 50 } |
| 51 } | 51 } |
| 52 | 52 |
| 53 Widget build() { | 53 Widget build() { |
| 54 if (focused && !_isAttachedToKeyboard) { | 54 if (focused && !_isAttachedToKeyboard) { |
| 55 keyboard.show(_editableValue.stub); | 55 keyboard.show(_editableValue.stub); |
| 56 _isAttachedToKeyboard = true; | 56 _isAttachedToKeyboard = true; |
| 57 } | 57 } |
| 58 | 58 |
| 59 TextStyle textStyle = Theme.of(this).text.subhead; |
| 59 List<Widget> textChildren = <Widget>[]; | 60 List<Widget> textChildren = <Widget>[]; |
| 61 |
| 60 if (placeholder != null && _value.isEmpty) { | 62 if (placeholder != null && _value.isEmpty) { |
| 61 textChildren.add(new Text(placeholder, style: _placeholderStyle)); | 63 Widget child = new Opacity( |
| 64 key: "placeholder", |
| 65 child: new Text(placeholder, style: textStyle), |
| 66 opacity: _kHintOpacity |
| 67 ); |
| 68 textChildren.add(child); |
| 62 } | 69 } |
| 63 textChildren.add( | 70 |
| 64 new EditableText(value: _editableValue, focused: focused) | 71 textChildren.add(new EditableText( |
| 65 ); | 72 value: _editableValue, |
| 73 focused: focused, |
| 74 style: textStyle, |
| 75 cursorColor: Theme.of(this).primary[200] |
| 76 )); |
| 66 | 77 |
| 67 Border focusHighlight = new Border(bottom: new BorderSide( | 78 Border focusHighlight = new Border(bottom: new BorderSide( |
| 68 color: focused ? Blue[400] : Grey[200], | 79 color: focused ? Theme.of(this).primary[400] : Theme.of(this).primary[200]
, |
| 69 width: focused ? 2.0 : 1.0 | 80 width: focused ? 2.0 : 1.0 |
| 70 )); | 81 )); |
| 71 | 82 |
| 72 // TODO(hansmuller): white-space: pre, height: 1.2em. | |
| 73 Container input = new Container( | 83 Container input = new Container( |
| 74 child: new Stack(textChildren), | 84 child: new Stack(textChildren), |
| 75 padding: const EdgeDims.only(left: 8.0, right: 8.0, bottom: 12.0), | 85 padding: _kTextfieldPadding, |
| 76 decoration: new BoxDecoration(border: focusHighlight) | 86 decoration: new BoxDecoration(border: focusHighlight) |
| 77 ); | 87 ); |
| 78 | 88 |
| 79 return new Listener( | 89 return new Listener( |
| 80 child: input, | 90 child: input, |
| 81 onPointerDown: (_) => keyboard.showByRequest() | 91 onPointerDown: (_) => keyboard.showByRequest() |
| 82 ); | 92 ); |
| 83 } | 93 } |
| 84 | 94 |
| 85 void didUnmount() { | 95 void didUnmount() { |
| 86 if (_isAttachedToKeyboard) | 96 if (_isAttachedToKeyboard) |
| 87 keyboard.hide(); | 97 keyboard.hide(); |
| 88 super.didUnmount(); | 98 super.didUnmount(); |
| 89 } | 99 } |
| 90 } | 100 } |
| OLD | NEW |