Commit e843d9d0 authored by Ian Hickson's avatar Ian Hickson

Merge pull request #2207 from Hixie/size-obs-5

SizeObserver crusade: RawInputLine
parents 6757515d be865e1e
...@@ -9,6 +9,7 @@ import 'package:flutter/gestures.dart'; ...@@ -9,6 +9,7 @@ import 'package:flutter/gestures.dart';
import 'basic_types.dart'; import 'basic_types.dart';
import 'box.dart'; import 'box.dart';
import 'object.dart'; import 'object.dart';
import 'viewport.dart';
const _kCaretGap = 1.0; // pixels const _kCaretGap = 1.0; // pixels
const _kCaretHeightOffset = 2.0; // pixels const _kCaretHeightOffset = 2.0; // pixels
...@@ -24,9 +25,9 @@ class RenderEditableLine extends RenderBox { ...@@ -24,9 +25,9 @@ class RenderEditableLine extends RenderBox {
bool showCursor: false, bool showCursor: false,
Color selectionColor, Color selectionColor,
TextSelection selection, TextSelection selection,
Offset paintOffset: Offset.zero,
this.onSelectionChanged, this.onSelectionChanged,
this.onContentSizeChanged Offset paintOffset: Offset.zero,
this.onPaintOffsetUpdateNeeded
}) : _textPainter = new TextPainter(text), }) : _textPainter = new TextPainter(text),
_cursorColor = cursorColor, _cursorColor = cursorColor,
_showCursor = showCursor, _showCursor = showCursor,
...@@ -45,8 +46,8 @@ class RenderEditableLine extends RenderBox { ...@@ -45,8 +46,8 @@ class RenderEditableLine extends RenderBox {
..onTapCancel = _handleTapCancel; ..onTapCancel = _handleTapCancel;
} }
ValueChanged<Size> onContentSizeChanged;
ValueChanged<TextSelection> onSelectionChanged; ValueChanged<TextSelection> onSelectionChanged;
ViewportDimensionsChangeCallback onPaintOffsetUpdateNeeded;
/// The text to display /// The text to display
TextSpan get text => _textPainter.text; TextSpan get text => _textPainter.text;
...@@ -201,16 +202,15 @@ class RenderEditableLine extends RenderBox { ...@@ -201,16 +202,15 @@ class RenderEditableLine extends RenderBox {
Rect _caretPrototype; Rect _caretPrototype;
void performLayout() { void performLayout() {
Size oldSize = hasSize ? size : null;
size = new Size(constraints.maxWidth, constraints.constrainHeight(_preferredHeight)); size = new Size(constraints.maxWidth, constraints.constrainHeight(_preferredHeight));
_caretPrototype = new Rect.fromLTWH(0.0, _kCaretHeightOffset, _kCaretWidth, size.height - 2.0 * _kCaretHeightOffset); _caretPrototype = new Rect.fromLTWH(0.0, _kCaretHeightOffset, _kCaretWidth, size.height - 2.0 * _kCaretHeightOffset);
_selectionRects = null; _selectionRects = null;
_layoutText(new BoxConstraints(minHeight: constraints.minHeight, maxHeight: constraints.maxHeight)); _layoutText(new BoxConstraints(minHeight: constraints.minHeight, maxHeight: constraints.maxHeight));
Size contentSize = new Size(_textPainter.width + _kCaretGap + _kCaretWidth, _textPainter.height); Size contentSize = new Size(_textPainter.width + _kCaretGap + _kCaretWidth, _textPainter.height);
if (_contentSize != contentSize) { if (onPaintOffsetUpdateNeeded != null && (size != oldSize || contentSize != _contentSize))
_contentSize = contentSize; onPaintOffsetUpdateNeeded(new ViewportDimensions(containerSize: size, contentSize: contentSize));
if (onContentSizeChanged != null) _contentSize = contentSize;
onContentSizeChanged(_contentSize);
}
} }
void _paintCaret(Canvas canvas, Offset effectiveOffset) { void _paintCaret(Canvas canvas, Offset effectiveOffset) {
......
...@@ -189,9 +189,6 @@ class RawInputLineState extends ScrollableState<RawInputLine> { ...@@ -189,9 +189,6 @@ class RawInputLineState extends ScrollableState<RawInputLine> {
Timer _cursorTimer; Timer _cursorTimer;
bool _showCursor = false; bool _showCursor = false;
double _contentWidth = 0.0;
double _containerWidth = 0.0;
_KeyboardClientImpl _keyboardClient; _KeyboardClientImpl _keyboardClient;
KeyboardHandle _keyboardHandle; KeyboardHandle _keyboardHandle;
...@@ -218,24 +215,28 @@ class RawInputLineState extends ScrollableState<RawInputLine> { ...@@ -218,24 +215,28 @@ class RawInputLineState extends ScrollableState<RawInputLine> {
bool get _isAttachedToKeyboard => _keyboardHandle != null && _keyboardHandle.attached; bool get _isAttachedToKeyboard => _keyboardHandle != null && _keyboardHandle.attached;
void _handleContainerSizeChanged(Size newSize) { double _contentWidth = 0.0;
_containerWidth = newSize.width; double _containerWidth = 0.0;
_updateScrollBehavior();
}
void _handleContentSizeChanged(Size newSize) {
_contentWidth = newSize.width;
_updateScrollBehavior();
}
void _updateScrollBehavior() { Offset _handlePaintOffsetUpdateNeeded(ViewportDimensions dimensions) {
// Set the scroll offset to match the content width so that the cursor // We make various state changes here but don't have to do so in a
// (which is always at the end of the text) will be visible. // setState() callback because we are called during layout and all
// we're updating is the new offset, which we are providing to the
// render object via our return value.
_containerWidth = dimensions.containerSize.width;
_contentWidth = dimensions.contentSize.width;
scrollTo(scrollBehavior.updateExtents( scrollTo(scrollBehavior.updateExtents(
contentExtent: _contentWidth, contentExtent: _contentWidth,
containerExtent: _containerWidth, containerExtent: _containerWidth,
scrollOffset: _contentWidth // Set the scroll offset to match the content width so that the
// cursor (which is always at the end of the text) will be
// visible.
// TODO(ianh): We should really only do this when text is added,
// not generally any time the size changes.
scrollOffset: pixelOffsetToScrollOffset(-_contentWidth)
)); ));
updateGestureDetector();
return scrollOffsetToPixelDelta(scrollOffset);
} }
void _attachOrDetachKeyboard(bool focused) { void _attachOrDetachKeyboard(bool focused) {
...@@ -327,19 +328,16 @@ class RawInputLineState extends ScrollableState<RawInputLine> { ...@@ -327,19 +328,16 @@ class RawInputLineState extends ScrollableState<RawInputLine> {
else if (_cursorTimer != null && (!focused || !config.value.selection.isCollapsed)) else if (_cursorTimer != null && (!focused || !config.value.selection.isCollapsed))
_stopCursorTimer(); _stopCursorTimer();
return new SizeObserver( return new _EditableLineWidget(
onSizeChanged: _handleContainerSizeChanged, value: config.value,
child: new _EditableLineWidget( style: config.style,
value: config.value, cursorColor: config.cursorColor,
style: config.style, showCursor: _showCursor,
cursorColor: config.cursorColor, selectionColor: config.selectionColor,
showCursor: _showCursor, hideText: config.hideText,
selectionColor: config.selectionColor, onSelectionChanged: _handleSelectionChanged,
hideText: config.hideText, paintOffset: scrollOffsetToPixelDelta(scrollOffset),
onContentSizeChanged: _handleContentSizeChanged, onPaintOffsetUpdateNeeded: _handlePaintOffsetUpdateNeeded
onSelectionChanged: _handleSelectionChanged,
paintOffset: new Offset(-scrollOffset, 0.0)
)
); );
} }
} }
...@@ -353,9 +351,9 @@ class _EditableLineWidget extends LeafRenderObjectWidget { ...@@ -353,9 +351,9 @@ class _EditableLineWidget extends LeafRenderObjectWidget {
this.showCursor, this.showCursor,
this.selectionColor, this.selectionColor,
this.hideText, this.hideText,
this.onContentSizeChanged,
this.onSelectionChanged, this.onSelectionChanged,
this.paintOffset this.paintOffset,
this.onPaintOffsetUpdateNeeded
}) : super(key: key); }) : super(key: key);
final InputValue value; final InputValue value;
...@@ -364,9 +362,9 @@ class _EditableLineWidget extends LeafRenderObjectWidget { ...@@ -364,9 +362,9 @@ class _EditableLineWidget extends LeafRenderObjectWidget {
final bool showCursor; final bool showCursor;
final Color selectionColor; final Color selectionColor;
final bool hideText; final bool hideText;
final ValueChanged<Size> onContentSizeChanged;
final ValueChanged<TextSelection> onSelectionChanged; final ValueChanged<TextSelection> onSelectionChanged;
final Offset paintOffset; final Offset paintOffset;
final ViewportDimensionsChangeCallback onPaintOffsetUpdateNeeded;
RenderEditableLine createRenderObject() { RenderEditableLine createRenderObject() {
return new RenderEditableLine( return new RenderEditableLine(
...@@ -375,9 +373,9 @@ class _EditableLineWidget extends LeafRenderObjectWidget { ...@@ -375,9 +373,9 @@ class _EditableLineWidget extends LeafRenderObjectWidget {
showCursor: showCursor, showCursor: showCursor,
selectionColor: selectionColor, selectionColor: selectionColor,
selection: value.selection, selection: value.selection,
onContentSizeChanged: onContentSizeChanged,
onSelectionChanged: onSelectionChanged, onSelectionChanged: onSelectionChanged,
paintOffset: paintOffset paintOffset: paintOffset,
onPaintOffsetUpdateNeeded: onPaintOffsetUpdateNeeded
); );
} }
...@@ -389,9 +387,9 @@ class _EditableLineWidget extends LeafRenderObjectWidget { ...@@ -389,9 +387,9 @@ class _EditableLineWidget extends LeafRenderObjectWidget {
..showCursor = showCursor ..showCursor = showCursor
..selectionColor = selectionColor ..selectionColor = selectionColor
..selection = value.selection ..selection = value.selection
..onContentSizeChanged = onContentSizeChanged
..onSelectionChanged = onSelectionChanged ..onSelectionChanged = onSelectionChanged
..paintOffset = paintOffset; ..paintOffset = paintOffset
..onPaintOffsetUpdateNeeded = onPaintOffsetUpdateNeeded;
} }
TextSpan get _styledTextSpan { TextSpan get _styledTextSpan {
......
...@@ -380,6 +380,10 @@ abstract class ScrollableState<T extends Scrollable> extends State<T> { ...@@ -380,6 +380,10 @@ abstract class ScrollableState<T extends Scrollable> extends State<T> {
/// ///
/// If a non-null [duration] is provided, the widget will animate to the new /// If a non-null [duration] is provided, the widget will animate to the new
/// scroll offset over the given duration with the given curve. /// scroll offset over the given duration with the given curve.
///
/// This function does not accept a zero duration. To jump-scroll to
/// the new offset, do not provide a duration, rather than providing
/// a zero duration.
Future scrollTo(double newScrollOffset, { Duration duration, Curve curve: Curves.ease }) { Future scrollTo(double newScrollOffset, { Duration duration, Curve curve: Curves.ease }) {
if (newScrollOffset == _scrollOffset) if (newScrollOffset == _scrollOffset)
return new Future.value(); return new Future.value();
...@@ -390,6 +394,7 @@ abstract class ScrollableState<T extends Scrollable> extends State<T> { ...@@ -390,6 +394,7 @@ abstract class ScrollableState<T extends Scrollable> extends State<T> {
return new Future.value(); return new Future.value();
} }
assert(duration > Duration.ZERO);
return _animateTo(newScrollOffset, duration, curve); return _animateTo(newScrollOffset, duration, curve);
} }
......
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