-
Notifications
You must be signed in to change notification settings - Fork 26.7k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add a maxLines parameter for multiline Input. #6310
Changes from 1 commit
7a144b1
77a8f1b
845c845
ca3a70c
12de04a
b03e8f1
85b41ff
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -37,14 +37,16 @@ class TextSelectionPoint { | |
final TextDirection direction; | ||
} | ||
|
||
typedef Offset RenderEditableLinePaintOffsetNeededCallback(ViewportDimensions dimensions, Rect caretRect); | ||
|
||
/// A single line of editable text. | ||
class RenderEditableLine extends RenderBox { | ||
/// Creates a render object for a single line of editable text. | ||
RenderEditableLine({ | ||
TextSpan text, | ||
Color cursorColor, | ||
bool showCursor: false, | ||
bool multiline: false, | ||
int maxLines: 1, | ||
Color selectionColor, | ||
double textScaleFactor: 1.0, | ||
TextSelection selection, | ||
|
@@ -54,7 +56,7 @@ class RenderEditableLine extends RenderBox { | |
}) : _textPainter = new TextPainter(text: text, textScaleFactor: textScaleFactor), | ||
_cursorColor = cursorColor, | ||
_showCursor = showCursor, | ||
_multiline = multiline, | ||
_maxLines = maxLines, | ||
_selection = selection, | ||
_paintOffset = paintOffset { | ||
assert(!showCursor || cursorColor != null); | ||
|
@@ -70,7 +72,7 @@ class RenderEditableLine extends RenderBox { | |
SelectionChangedHandler onSelectionChanged; | ||
|
||
/// Called when the inner or outer dimensions of this render object change. | ||
ViewportDimensionsChangeCallback onPaintOffsetUpdateNeeded; | ||
RenderEditableLinePaintOffsetNeededCallback onPaintOffsetUpdateNeeded; | ||
|
||
/// The text to display | ||
TextSpan get text => _textPainter.text; | ||
|
@@ -173,7 +175,7 @@ class RenderEditableLine extends RenderBox { | |
if (selection.isCollapsed) { | ||
// TODO(mpcomplete): This doesn't work well at an RTL/LTR boundary. | ||
Offset caretOffset = _textPainter.getOffsetForCaret(selection.extent, _caretPrototype); | ||
Point start = new Point(0.0, constraints.constrainHeight(_preferredHeight)) + caretOffset + offset; | ||
Point start = new Point(0.0, constraints.constrainHeight(_preferredLineHeight)) + caretOffset + offset; | ||
return <TextSelectionPoint>[new TextSelectionPoint(localToGlobal(start), null)]; | ||
} else { | ||
List<ui.TextBox> boxes = _textPainter.getBoxesForSelection(selection); | ||
|
@@ -192,10 +194,17 @@ class RenderEditableLine extends RenderBox { | |
return _textPainter.getPositionForOffset(globalToLocal(globalPosition).toOffset()); | ||
} | ||
|
||
/// Returns the Rect in local coordinates for the caret at the given text | ||
/// position. | ||
Rect getLocalRectForCaret(TextPosition caretPosition) { | ||
Offset caretOffset = _textPainter.getOffsetForCaret(caretPosition, _caretPrototype); | ||
return _caretPrototype.shift(caretOffset + _paintOffset); | ||
} | ||
|
||
Size _contentSize; | ||
|
||
ui.Paragraph _layoutTemplate; | ||
double get _preferredHeight { | ||
double get _preferredLineHeight { | ||
if (_layoutTemplate == null) { | ||
ui.ParagraphBuilder builder = new ui.ParagraphBuilder() | ||
..pushStyle(text.style.getTextStyle(textScaleFactor: textScaleFactor)) | ||
|
@@ -208,21 +217,21 @@ class RenderEditableLine extends RenderBox { | |
return _layoutTemplate.height; | ||
} | ||
|
||
bool _multiline; | ||
int _maxLines; | ||
double get _maxContentWidth { | ||
return _multiline ? | ||
return _maxLines > 1 ? | ||
constraints.maxWidth - (_kCaretGap + _kCaretWidth) : | ||
double.INFINITY; | ||
} | ||
|
||
@override | ||
double computeMinIntrinsicHeight(double width) { | ||
return _preferredHeight; | ||
return _preferredLineHeight; | ||
} | ||
|
||
@override | ||
double computeMaxIntrinsicHeight(double width) { | ||
return _preferredHeight; | ||
return _preferredLineHeight; | ||
} | ||
|
||
@override | ||
|
@@ -284,17 +293,26 @@ class RenderEditableLine extends RenderBox { | |
@override | ||
void performLayout() { | ||
Size oldSize = hasSize ? size : null; | ||
double lineHeight = constraints.constrainHeight(_preferredHeight); | ||
double lineHeight = constraints.constrainHeight(_preferredLineHeight); | ||
_caretPrototype = new Rect.fromLTWH(0.0, _kCaretHeightOffset, _kCaretWidth, lineHeight - 2.0 * _kCaretHeightOffset); | ||
_selectionRects = null; | ||
_textPainter.layout(maxWidth: _maxContentWidth); | ||
size = new Size(constraints.maxWidth, constraints.constrainHeight(math.max(lineHeight, _textPainter.height))); | ||
size = new Size(constraints.maxWidth, constraints.constrainHeight( | ||
_textPainter.height.clamp(lineHeight, lineHeight * _maxLines))); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. newline before final ) |
||
Size contentSize = new Size(_textPainter.width + _kCaretGap + _kCaretWidth, _textPainter.height); | ||
if (onPaintOffsetUpdateNeeded != null && (size != oldSize || contentSize != _contentSize)) | ||
onPaintOffsetUpdateNeeded(new ViewportDimensions(containerSize: size, contentSize: contentSize)); | ||
assert(_selection != null); // valid assumption? | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. we should determine if it is before checkin There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. (one option is to just say that it is, and treat it as a bug if we find it isn't later) |
||
Offset caretOffset = _textPainter.getOffsetForCaret(_selection.extent, _caretPrototype); | ||
Rect caretRect = _caretPrototype.shift(caretOffset + _paintOffset); | ||
if (onPaintOffsetUpdateNeeded != null && (size != oldSize || contentSize != _contentSize || !_withinBounds(caretRect))) | ||
onPaintOffsetUpdateNeeded(new ViewportDimensions(containerSize: size, contentSize: contentSize), caretRect); | ||
_contentSize = contentSize; | ||
} | ||
|
||
bool _withinBounds(Rect caretRect) { | ||
Rect bounds = new Rect.fromLTWH(0.0, 0.0, size.width, size.height); | ||
return (bounds.contains(caretRect.topLeft) && bounds.contains(caretRect.bottomRight)); | ||
} | ||
|
||
void _paintCaret(Canvas canvas, Offset effectiveOffset) { | ||
Offset caretOffset = _textPainter.getOffsetForCaret(_selection.extent, _caretPrototype); | ||
Paint paint = new Paint()..color = _cursorColor; | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
changed the caret rect I use here, dropping the vertical padding so that we scroll all the way to the edge when it moves.