From 64a645352c80246bcba2bb7d242e05cbf312e419 Mon Sep 17 00:00:00 2001 From: Adam Barth Date: Wed, 11 Nov 2015 09:37:01 -0800 Subject: [PATCH] Give loose contraints to text inside input widget The input widget scrolls, so it should give its text loose constraints. That way the text ends up being its intrinsic size even if put in a context with tight constraints. Fixes #298 --- packages/flutter/lib/src/material/input.dart | 4 +- .../lib/src/painting/text_painter.dart | 12 +++++- .../lib/src/rendering/editable_paragraph.dart | 41 ++++++++++--------- .../flutter/lib/src/rendering/paragraph.dart | 5 +-- 4 files changed, 34 insertions(+), 28 deletions(-) diff --git a/packages/flutter/lib/src/material/input.dart b/packages/flutter/lib/src/material/input.dart index ba327d0bef..a4ee40023f 100644 --- a/packages/flutter/lib/src/material/input.dart +++ b/packages/flutter/lib/src/material/input.dart @@ -167,7 +167,7 @@ class InputState extends ScrollableState { scrollTo(scrollBehavior.updateExtents( contentExtent: _contentWidth, containerExtent: _containerWidth, - scrollOffset: _contentWidth) - ); + scrollOffset: _contentWidth + )); } } diff --git a/packages/flutter/lib/src/painting/text_painter.dart b/packages/flutter/lib/src/painting/text_painter.dart index a22cc9b234..7f50a578c5 100644 --- a/packages/flutter/lib/src/painting/text_painter.dart +++ b/packages/flutter/lib/src/painting/text_painter.dart @@ -177,10 +177,18 @@ class TextPainter { return _applyFloatingPointHack(_paragraph.maxIntrinsicWidth); } + double get width { + assert(!_needsLayout); + return _applyFloatingPointHack(_paragraph.width); + } + + double get height { + assert(!_needsLayout); + return _applyFloatingPointHack(_paragraph.height); + } + Size get size { assert(!_needsLayout); - double height = _applyFloatingPointHack(_paragraph.height); - double width = _applyFloatingPointHack(_paragraph.width); return new Size(width, height); } diff --git a/packages/flutter/lib/src/rendering/editable_paragraph.dart b/packages/flutter/lib/src/rendering/editable_paragraph.dart index 2d3a9e8c46..3e94b39b21 100644 --- a/packages/flutter/lib/src/rendering/editable_paragraph.dart +++ b/packages/flutter/lib/src/rendering/editable_paragraph.dart @@ -60,15 +60,21 @@ class RenderEditableParagraph extends RenderParagraph { markNeedsPaint(); } - // Editable text does not support line wrap. - bool get allowLineWrap => false; + BoxConstraints _getTextContraints(BoxConstraints constraints) { + return new BoxConstraints( + minWidth: 0.0, + maxWidth: double.INFINITY, + minHeight: constraints.minHeight, + maxHeight: constraints.maxHeight + ); + } double _getIntrinsicWidth(BoxConstraints constraints) { // There should be no difference between the minimum and maximum width // because we only support single-line text. - layoutText(constraints); + layoutText(_getTextContraints(constraints)); return constraints.constrainWidth( - textPainter.size.width + _kCursorGap + _kCursorWidth + textPainter.width + _kCursorGap + _kCursorWidth ); } @@ -81,23 +87,21 @@ class RenderEditableParagraph extends RenderParagraph { } void performLayout() { - layoutText(constraints); + layoutText(_getTextContraints(constraints)); + Size contentSize = new Size(textPainter.width + _kCursorGap + _kCursorWidth, textPainter.height); + size = constraints.constrain(contentSize); - Offset cursorPadding = const Offset(_kCursorGap + _kCursorWidth, 0.0); - Size newContentSize = textPainter.size + cursorPadding; - size = constraints.constrain(newContentSize); - - if (_contentSize == null || _contentSize != newContentSize) { - _contentSize = newContentSize; + if (_contentSize == null || _contentSize != contentSize) { + _contentSize = contentSize; if (onContentSizeChanged != null) - onContentSizeChanged(newContentSize); + onContentSizeChanged(_contentSize); } } void paint(PaintingContext context, Offset offset) { - layoutText(constraints); + layoutText(_getTextContraints(constraints)); - bool needsClipping = (_contentSize.width > size.width); + final bool needsClipping = (_contentSize.width > size.width); if (needsClipping) { context.canvas.save(); context.canvas.clipRect(offset & size); @@ -107,15 +111,12 @@ class RenderEditableParagraph extends RenderParagraph { if (_showCursor) { Rect cursorRect = new Rect.fromLTWH( - textPainter.size.width + _kCursorGap, - _kCursorHeightOffset, + offset.dx + _contentSize.width - _kCursorWidth - _scrollOffset.dx, + offset.dy + _kCursorHeightOffset - _scrollOffset.dy, _kCursorWidth, size.height - 2.0 * _kCursorHeightOffset ); - context.canvas.drawRect( - cursorRect.shift(offset - _scrollOffset), - new Paint()..color = _cursorColor - ); + context.canvas.drawRect(cursorRect, new Paint()..color = _cursorColor); } if (needsClipping) diff --git a/packages/flutter/lib/src/rendering/paragraph.dart b/packages/flutter/lib/src/rendering/paragraph.dart index 72772067e2..7231e8f9a8 100644 --- a/packages/flutter/lib/src/rendering/paragraph.dart +++ b/packages/flutter/lib/src/rendering/paragraph.dart @@ -47,14 +47,11 @@ class RenderParagraph extends RenderBox { markNeedsLayout(); } - // Whether the text should be allowed to wrap to multiple lines. - bool get allowLineWrap => true; - void layoutText(BoxConstraints constraints) { assert(constraints != null); if (_constraintsForCurrentLayout == constraints) return; // already cached this layout - textPainter.maxWidth = allowLineWrap ? constraints.maxWidth : double.INFINITY; + textPainter.maxWidth = constraints.maxWidth; textPainter.minWidth = constraints.minWidth; textPainter.minHeight = constraints.minHeight; textPainter.maxHeight = constraints.maxHeight;