Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Sign in
Toggle navigation
F
Front-End
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
abdullh.alsoleman
Front-End
Commits
d081dc67
Commit
d081dc67
authored
Jan 22, 2016
by
Adam Barth
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #1347 from abarth/editable_line
Input widget shrinks when typing a space
parents
4357d087
bdef1038
Changes
7
Hide whitespace changes
Inline
Side-by-side
Showing
7 changed files
with
257 additions
and
80 deletions
+257
-80
rendering.dart
packages/flutter/lib/rendering.dart
+1
-1
input.dart
packages/flutter/lib/src/material/input.dart
+11
-11
editable_line.dart
packages/flutter/lib/src/rendering/editable_line.dart
+178
-0
paragraph.dart
packages/flutter/lib/src/rendering/paragraph.dart
+28
-27
editable.dart
packages/flutter/lib/src/widgets/editable.dart
+24
-30
widgets.dart
packages/flutter/lib/widgets.dart
+1
-1
input_test.dart
packages/flutter/test/widget/input_test.dart
+14
-10
No files found.
packages/flutter/lib/rendering.dart
View file @
d081dc67
...
@@ -12,7 +12,7 @@ export 'src/rendering/block.dart';
...
@@ -12,7 +12,7 @@ export 'src/rendering/block.dart';
export
'src/rendering/box.dart'
;
export
'src/rendering/box.dart'
;
export
'src/rendering/custom_layout.dart'
;
export
'src/rendering/custom_layout.dart'
;
export
'src/rendering/debug.dart'
;
export
'src/rendering/debug.dart'
;
export
'src/rendering/editable_
paragraph
.dart'
;
export
'src/rendering/editable_
line
.dart'
;
export
'src/rendering/error.dart'
;
export
'src/rendering/error.dart'
;
export
'src/rendering/flex.dart'
;
export
'src/rendering/flex.dart'
;
export
'src/rendering/grid.dart'
;
export
'src/rendering/grid.dart'
;
...
...
packages/flutter/lib/src/material/input.dart
View file @
d081dc67
...
@@ -61,18 +61,18 @@ class Input extends Scrollable {
...
@@ -61,18 +61,18 @@ class Input extends Scrollable {
class
InputState
extends
ScrollableState
<
Input
>
{
class
InputState
extends
ScrollableState
<
Input
>
{
String
_value
;
String
_value
;
EditableString
_editable
Value
;
EditableString
_editable
String
;
KeyboardHandle
_keyboardHandle
=
KeyboardHandle
.
unattached
;
KeyboardHandle
_keyboardHandle
=
KeyboardHandle
.
unattached
;
double
_contentWidth
=
0.0
;
double
_contentWidth
=
0.0
;
double
_containerWidth
=
0.0
;
double
_containerWidth
=
0.0
;
EditableString
get
editableValue
=>
_editable
Value
;
EditableString
get
editableValue
=>
_editable
String
;
void
initState
()
{
void
initState
()
{
super
.
initState
();
super
.
initState
();
_value
=
config
.
initialValue
;
_value
=
config
.
initialValue
;
_editable
Value
=
new
EditableString
(
_editable
String
=
new
EditableString
(
text:
_value
,
text:
_value
,
onUpdated:
_handleTextUpdated
,
onUpdated:
_handleTextUpdated
,
onSubmitted:
_handleTextSubmitted
onSubmitted:
_handleTextSubmitted
...
@@ -80,9 +80,9 @@ class InputState extends ScrollableState<Input> {
...
@@ -80,9 +80,9 @@ class InputState extends ScrollableState<Input> {
}
}
void
_handleTextUpdated
()
{
void
_handleTextUpdated
()
{
if
(
_value
!=
_editable
Value
.
text
)
{
if
(
_value
!=
_editable
String
.
text
)
{
setState
(()
{
setState
(()
{
_value
=
_editable
Value
.
text
;
_value
=
_editable
String
.
text
;
});
});
if
(
config
.
onChanged
!=
null
)
if
(
config
.
onChanged
!=
null
)
config
.
onChanged
(
_value
);
config
.
onChanged
(
_value
);
...
@@ -100,10 +100,10 @@ class InputState extends ScrollableState<Input> {
...
@@ -100,10 +100,10 @@ class InputState extends ScrollableState<Input> {
bool
focused
=
Focus
.
at
(
context
,
autofocus:
config
.
autofocus
);
bool
focused
=
Focus
.
at
(
context
,
autofocus:
config
.
autofocus
);
if
(
focused
&&
!
_keyboardHandle
.
attached
)
{
if
(
focused
&&
!
_keyboardHandle
.
attached
)
{
_keyboardHandle
=
keyboard
.
show
(
_editable
Value
.
stub
,
config
.
keyboardType
);
_keyboardHandle
=
keyboard
.
show
(
_editable
String
.
stub
,
config
.
keyboardType
);
_keyboardHandle
.
setText
(
_editable
Value
.
text
);
_keyboardHandle
.
setText
(
_editable
String
.
text
);
_keyboardHandle
.
setSelection
(
_editable
Value
.
selection
.
start
,
_keyboardHandle
.
setSelection
(
_editable
String
.
selection
.
start
,
_editable
Value
.
selection
.
end
);
_editable
String
.
selection
.
end
);
}
else
if
(!
focused
&&
_keyboardHandle
.
attached
)
{
}
else
if
(!
focused
&&
_keyboardHandle
.
attached
)
{
_keyboardHandle
.
release
();
_keyboardHandle
.
release
();
}
}
...
@@ -127,8 +127,8 @@ class InputState extends ScrollableState<Input> {
...
@@ -127,8 +127,8 @@ class InputState extends ScrollableState<Input> {
focusHighlightColor
=
focused
?
themeData
.
primarySwatch
[
400
]
:
themeData
.
hintColor
;
focusHighlightColor
=
focused
?
themeData
.
primarySwatch
[
400
]
:
themeData
.
hintColor
;
}
}
textChildren
.
add
(
new
EditableText
(
textChildren
.
add
(
new
RawEditableLine
(
value:
_editable
Value
,
value:
_editable
String
,
focused:
focused
,
focused:
focused
,
style:
textStyle
,
style:
textStyle
,
hideText:
config
.
hideText
,
hideText:
config
.
hideText
,
...
...
packages/flutter/lib/src/rendering/editable_
paragraph
.dart
→
packages/flutter/lib/src/rendering/editable_
line
.dart
View file @
d081dc67
...
@@ -2,6 +2,8 @@
...
@@ -2,6 +2,8 @@
// Use of this source code is governed by a BSD-style license that can be
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// found in the LICENSE file.
import
'dart:ui'
as
ui
;
import
'package:flutter/painting.dart'
;
import
'package:flutter/painting.dart'
;
import
'box.dart'
;
import
'box.dart'
;
...
@@ -13,24 +15,43 @@ const _kCursorGap = 1.0; // pixels
...
@@ -13,24 +15,43 @@ const _kCursorGap = 1.0; // pixels
const
_kCursorHeightOffset
=
2.0
;
// pixels
const
_kCursorHeightOffset
=
2.0
;
// pixels
const
_kCursorWidth
=
1.0
;
// pixels
const
_kCursorWidth
=
1.0
;
// pixels
/// A render object used by EditableText widgets. This is similar to
final
String
_kZeroWidthSpace
=
new
String
.
fromCharCode
(
0x200B
);
/// RenderParagraph but also renders a cursor and provides support for
/// scrolling.
class
RenderEditableParagraph
extends
RenderParagraph
{
RenderEditableParagraph
({
/// A single line of editable text.
TextSpan
text
,
class
RenderEditableLine
extends
RenderBox
{
RenderEditableLine
({
StyledTextSpan
text
,
Color
cursorColor
,
Color
cursorColor
,
bool
showCursor
,
bool
showCursor
,
this
.
onContentSizeChanged
,
this
.
onContentSizeChanged
,
Offset
scrollOffset
Offset
scrollOffset
})
:
_cursorColor
=
cursorColor
,
})
:
_textPainter
=
new
TextPainter
(
text
),
_cursorColor
=
cursorColor
,
_showCursor
=
showCursor
,
_showCursor
=
showCursor
,
_scrollOffset
=
scrollOffset
,
_scrollOffset
=
scrollOffset
{
super
(
text
);
// TODO(abarth): These min/max values should be the default for TextPainter.
_textPainter
..
minWidth
=
0.0
..
maxWidth
=
double
.
INFINITY
..
minHeight
=
0.0
..
maxHeight
=
double
.
INFINITY
;
}
SizeChangedCallback
onContentSizeChanged
;
SizeChangedCallback
onContentSizeChanged
;
Size
_contentSize
;
/// The text to display
StyledTextSpan
get
text
=>
_textPainter
.
text
;
final
TextPainter
_textPainter
;
void
set
text
(
StyledTextSpan
value
)
{
if
(
_textPainter
.
text
==
value
)
return
;
StyledTextSpan
oldStyledText
=
_textPainter
.
text
;
if
(
oldStyledText
.
style
!=
value
.
style
)
_layoutTemplate
=
null
;
_textPainter
.
text
=
value
;
_constraintsForCurrentLayout
=
null
;
markNeedsLayout
();
}
Color
get
cursorColor
=>
_cursorColor
;
Color
get
cursorColor
=>
_cursorColor
;
Color
_cursorColor
;
Color
_cursorColor
;
...
@@ -59,39 +80,74 @@ class RenderEditableParagraph extends RenderParagraph {
...
@@ -59,39 +80,74 @@ class RenderEditableParagraph extends RenderParagraph {
markNeedsPaint
();
markNeedsPaint
();
}
}
BoxConstraints
_getTextContraints
(
BoxConstraints
constraints
)
{
Size
_contentSize
;
assert
(
constraints
.
isNormalized
);
return
new
BoxConstraints
(
minWidth:
0.0
,
maxWidth:
double
.
INFINITY
,
minHeight:
constraints
.
minHeight
,
maxHeight:
constraints
.
maxHeight
);
}
double
_getIntrinsicWidth
(
BoxConstraints
constraints
)
{
ui
.
Paragraph
_layoutTemplate
;
// There should be no difference between the minimum and maximum width
double
get
_preferredHeight
{
// because we only support single-line text.
if
(
_layoutTemplate
==
null
)
{
layoutText
(
_getTextContraints
(
constraints
));
ui
.
ParagraphBuilder
builder
=
new
ui
.
ParagraphBuilder
()
return
constraints
.
constrainWidth
(
..
pushStyle
(
text
.
style
.
textStyle
)
textPainter
.
width
+
_kCursorGap
+
_kCursorWidth
..
addText
(
_kZeroWidthSpace
);
);
// TODO(abarth): ParagraphBuilder#build's argument should be optional.
// TODO(abarth): These min/max values should be the default for ui.Paragraph.
_layoutTemplate
=
builder
.
build
(
new
ui
.
ParagraphStyle
())
..
minWidth
=
0.0
..
maxWidth
=
double
.
INFINITY
..
minHeight
=
0.0
..
maxHeight
=
double
.
INFINITY
..
layout
();
}
return
_layoutTemplate
.
height
;
}
}
double
getMinIntrinsicWidth
(
BoxConstraints
constraints
)
{
double
getMinIntrinsicWidth
(
BoxConstraints
constraints
)
{
return
_getIntrinsicWidth
(
constraints
);
assert
(
constraints
.
isNormalized
);
return
constraints
.
constrainWidth
(
0.0
);
}
}
double
getMaxIntrinsicWidth
(
BoxConstraints
constraints
)
{
double
getMaxIntrinsicWidth
(
BoxConstraints
constraints
)
{
return
_getIntrinsicWidth
(
constraints
);
assert
(
constraints
.
isNormalized
);
return
constraints
.
constrainWidth
(
0.0
);
}
}
void
performLayout
()
{
double
getMinIntrinsicHeight
(
BoxConstraints
constraints
)
{
layoutText
(
_getTextContraints
(
constraints
));
assert
(
constraints
.
isNormalized
);
Size
contentSize
=
new
Size
(
textPainter
.
width
+
_kCursorGap
+
_kCursorWidth
,
textPainter
.
height
);
return
constraints
.
constrainHeight
(
_preferredHeight
);
size
=
constraints
.
constrain
(
contentSize
);
}
double
getMaxIntrinsicHeight
(
BoxConstraints
constraints
)
{
assert
(
constraints
.
isNormalized
);
return
constraints
.
constrainHeight
(
_preferredHeight
);
}
bool
hitTestSelf
(
Point
position
)
=>
true
;
if
(
_contentSize
==
null
||
_contentSize
!=
contentSize
)
{
BoxConstraints
_constraintsForCurrentLayout
;
// when null, we don't have a current layout
// TODO(abarth): This logic should live in TextPainter and be shared with RenderParagraph.
void
_layoutText
(
BoxConstraints
constraints
)
{
assert
(
constraints
!=
null
);
assert
(
constraints
.
isNormalized
);
if
(
_constraintsForCurrentLayout
==
constraints
)
return
;
// already cached this layout
_textPainter
.
maxWidth
=
constraints
.
maxWidth
;
_textPainter
.
minWidth
=
constraints
.
minWidth
;
_textPainter
.
minHeight
=
constraints
.
minHeight
;
_textPainter
.
maxHeight
=
constraints
.
maxHeight
;
_textPainter
.
layout
();
// By default, we shrinkwrap to the intrinsic width.
double
width
=
constraints
.
constrainWidth
(
_textPainter
.
maxIntrinsicWidth
);
_textPainter
.
minWidth
=
width
;
_textPainter
.
maxWidth
=
width
;
_textPainter
.
layout
();
_constraintsForCurrentLayout
=
constraints
;
}
void
performLayout
()
{
size
=
new
Size
(
constraints
.
maxWidth
,
constraints
.
constrainHeight
(
_preferredHeight
));
_layoutText
(
new
BoxConstraints
(
minHeight:
constraints
.
minHeight
,
maxHeight:
constraints
.
maxHeight
));
Size
contentSize
=
new
Size
(
_textPainter
.
width
+
_kCursorGap
+
_kCursorWidth
,
_textPainter
.
height
);
if
(
_contentSize
!=
contentSize
)
{
_contentSize
=
contentSize
;
_contentSize
=
contentSize
;
if
(
onContentSizeChanged
!=
null
)
if
(
onContentSizeChanged
!=
null
)
onContentSizeChanged
(
_contentSize
);
onContentSizeChanged
(
_contentSize
);
...
@@ -99,7 +155,7 @@ class RenderEditableParagraph extends RenderParagraph {
...
@@ -99,7 +155,7 @@ class RenderEditableParagraph extends RenderParagraph {
}
}
void
_paintContents
(
PaintingContext
context
,
Offset
offset
)
{
void
_paintContents
(
PaintingContext
context
,
Offset
offset
)
{
textPainter
.
paint
(
context
.
canvas
,
offset
-
_scrollOffset
);
_
textPainter
.
paint
(
context
.
canvas
,
offset
-
_scrollOffset
);
if
(
_showCursor
)
{
if
(
_showCursor
)
{
Rect
cursorRect
=
new
Rect
.
fromLTWH
(
Rect
cursorRect
=
new
Rect
.
fromLTWH
(
...
@@ -113,12 +169,10 @@ class RenderEditableParagraph extends RenderParagraph {
...
@@ -113,12 +169,10 @@ class RenderEditableParagraph extends RenderParagraph {
}
}
void
paint
(
PaintingContext
context
,
Offset
offset
)
{
void
paint
(
PaintingContext
context
,
Offset
offset
)
{
layoutText
(
_getTextContraints
(
constraints
));
final
bool
hasVisualOverflow
=
(
_contentSize
.
width
>
size
.
width
);
final
bool
hasVisualOverflow
=
(
_contentSize
.
width
>
size
.
width
);
if
(
hasVisualOverflow
)
if
(
hasVisualOverflow
)
context
.
pushClipRect
(
needsCompositing
,
offset
,
Point
.
origin
&
size
,
_paintContents
);
context
.
pushClipRect
(
needsCompositing
,
offset
,
Point
.
origin
&
size
,
_paintContents
);
else
else
_paintContents
(
context
,
offset
);
_paintContents
(
context
,
offset
);
}
}
}
}
packages/flutter/lib/src/rendering/paragraph.dart
View file @
d081dc67
...
@@ -24,55 +24,56 @@ class RenderParagraph extends RenderBox {
...
@@ -24,55 +24,56 @@ class RenderParagraph extends RenderBox {
RenderParagraph
(
RenderParagraph
(
TextSpan
text
TextSpan
text
)
:
textPainter
=
new
TextPainter
(
text
)
{
)
:
_
textPainter
=
new
TextPainter
(
text
)
{
assert
(
text
!=
null
);
assert
(
text
!=
null
);
}
}
final
TextPainter
textPainter
;
final
TextPainter
_
textPainter
;
BoxConstraints
_constraintsForCurrentLayout
;
// when null, we don't have a current layout
BoxConstraints
_constraintsForCurrentLayout
;
// when null, we don't have a current layout
/// The text to display
/// The text to display
TextSpan
get
text
=>
textPainter
.
text
;
TextSpan
get
text
=>
_
textPainter
.
text
;
void
set
text
(
TextSpan
value
)
{
void
set
text
(
TextSpan
value
)
{
if
(
textPainter
.
text
==
value
)
if
(
_
textPainter
.
text
==
value
)
return
;
return
;
textPainter
.
text
=
value
;
_
textPainter
.
text
=
value
;
_constraintsForCurrentLayout
=
null
;
_constraintsForCurrentLayout
=
null
;
markNeedsLayout
();
markNeedsLayout
();
}
}
void
layoutText
(
BoxConstraints
constraints
)
{
// TODO(abarth): This logic should live in TextPainter and be shared with RenderEditableLine.
void
_layoutText
(
BoxConstraints
constraints
)
{
assert
(
constraints
!=
null
);
assert
(
constraints
!=
null
);
assert
(
constraints
.
isNormalized
);
assert
(
constraints
.
isNormalized
);
if
(
_constraintsForCurrentLayout
==
constraints
)
if
(
_constraintsForCurrentLayout
==
constraints
)
return
;
// already cached this layout
return
;
// already cached this layout
textPainter
.
maxWidth
=
constraints
.
maxWidth
;
_
textPainter
.
maxWidth
=
constraints
.
maxWidth
;
textPainter
.
minWidth
=
constraints
.
minWidth
;
_
textPainter
.
minWidth
=
constraints
.
minWidth
;
textPainter
.
minHeight
=
constraints
.
minHeight
;
_
textPainter
.
minHeight
=
constraints
.
minHeight
;
textPainter
.
maxHeight
=
constraints
.
maxHeight
;
_
textPainter
.
maxHeight
=
constraints
.
maxHeight
;
textPainter
.
layout
();
_
textPainter
.
layout
();
// By default, we shrinkwrap to the intrinsic width.
// By default, we shrinkwrap to the intrinsic width.
double
width
=
constraints
.
constrainWidth
(
textPainter
.
maxIntrinsicWidth
);
double
width
=
constraints
.
constrainWidth
(
_
textPainter
.
maxIntrinsicWidth
);
textPainter
.
minWidth
=
width
;
_
textPainter
.
minWidth
=
width
;
textPainter
.
maxWidth
=
width
;
_
textPainter
.
maxWidth
=
width
;
textPainter
.
layout
();
_
textPainter
.
layout
();
_constraintsForCurrentLayout
=
constraints
;
_constraintsForCurrentLayout
=
constraints
;
}
}
double
getMinIntrinsicWidth
(
BoxConstraints
constraints
)
{
double
getMinIntrinsicWidth
(
BoxConstraints
constraints
)
{
layoutText
(
constraints
);
_
layoutText
(
constraints
);
return
constraints
.
constrainWidth
(
textPainter
.
minIntrinsicWidth
);
return
constraints
.
constrainWidth
(
_
textPainter
.
minIntrinsicWidth
);
}
}
double
getMaxIntrinsicWidth
(
BoxConstraints
constraints
)
{
double
getMaxIntrinsicWidth
(
BoxConstraints
constraints
)
{
layoutText
(
constraints
);
_
layoutText
(
constraints
);
return
constraints
.
constrainWidth
(
textPainter
.
maxIntrinsicWidth
);
return
constraints
.
constrainWidth
(
_
textPainter
.
maxIntrinsicWidth
);
}
}
double
_getIntrinsicHeight
(
BoxConstraints
constraints
)
{
double
_getIntrinsicHeight
(
BoxConstraints
constraints
)
{
layoutText
(
constraints
);
_
layoutText
(
constraints
);
return
constraints
.
constrainHeight
(
textPainter
.
size
.
height
);
return
constraints
.
constrainHeight
(
_
textPainter
.
size
.
height
);
}
}
double
getMinIntrinsicHeight
(
BoxConstraints
constraints
)
{
double
getMinIntrinsicHeight
(
BoxConstraints
constraints
)
{
...
@@ -87,15 +88,15 @@ class RenderParagraph extends RenderBox {
...
@@ -87,15 +88,15 @@ class RenderParagraph extends RenderBox {
double
computeDistanceToActualBaseline
(
TextBaseline
baseline
)
{
double
computeDistanceToActualBaseline
(
TextBaseline
baseline
)
{
assert
(!
needsLayout
);
assert
(!
needsLayout
);
layoutText
(
constraints
);
_
layoutText
(
constraints
);
return
textPainter
.
computeDistanceToActualBaseline
(
baseline
);
return
_
textPainter
.
computeDistanceToActualBaseline
(
baseline
);
}
}
bool
hitTestSelf
(
Point
position
)
=>
true
;
bool
hitTestSelf
(
Point
position
)
=>
true
;
void
performLayout
()
{
void
performLayout
()
{
layoutText
(
constraints
);
_
layoutText
(
constraints
);
size
=
constraints
.
constrain
(
textPainter
.
size
);
size
=
constraints
.
constrain
(
_
textPainter
.
size
);
}
}
void
paint
(
PaintingContext
context
,
Offset
offset
)
{
void
paint
(
PaintingContext
context
,
Offset
offset
)
{
...
@@ -106,8 +107,8 @@ class RenderParagraph extends RenderBox {
...
@@ -106,8 +107,8 @@ class RenderParagraph extends RenderBox {
//
//
// TODO(abarth): Make computing the min/max intrinsic width/height
// TODO(abarth): Make computing the min/max intrinsic width/height
// a non-destructive operation.
// a non-destructive operation.
layoutText
(
constraints
);
_
layoutText
(
constraints
);
textPainter
.
paint
(
context
.
canvas
,
offset
);
_
textPainter
.
paint
(
context
.
canvas
,
offset
);
}
}
// we should probably expose a way to do precise (inter-glpyh) hit testing
// we should probably expose a way to do precise (inter-glpyh) hit testing
...
...
packages/flutter/lib/src/widgets/editable
_text
.dart
→
packages/flutter/lib/src/widgets/editable.dart
View file @
d081dc67
...
@@ -140,8 +140,8 @@ class EditableString implements KeyboardClient {
...
@@ -140,8 +140,8 @@ class EditableString implements KeyboardClient {
}
}
}
}
class
EditableText
extends
StatefulComponent
{
class
RawEditableLine
extends
StatefulComponent
{
EditableText
({
RawEditableLine
({
Key
key
,
Key
key
,
this
.
value
,
this
.
value
,
this
.
focused
:
false
,
this
.
focused
:
false
,
...
@@ -160,10 +160,12 @@ class EditableText extends StatefulComponent {
...
@@ -160,10 +160,12 @@ class EditableText extends StatefulComponent {
final
SizeChangedCallback
onContentSizeChanged
;
final
SizeChangedCallback
onContentSizeChanged
;
final
Offset
scrollOffset
;
final
Offset
scrollOffset
;
EditableTextState
createState
()
=>
new
EditableTextState
();
RawEditableTextState
createState
()
=>
new
Raw
EditableTextState
();
}
}
class
EditableTextState
extends
State
<
EditableText
>
{
class
RawEditableTextState
extends
State
<
RawEditableLine
>
{
// TODO(abarth): Move the cursor timer into RenderEditableLine so we can
// remove this extra widget.
Timer
_cursorTimer
;
Timer
_cursorTimer
;
bool
_showCursor
=
false
;
bool
_showCursor
=
false
;
...
@@ -209,25 +211,20 @@ class EditableTextState extends State<EditableText> {
...
@@ -209,25 +211,20 @@ class EditableTextState extends State<EditableText> {
else
if
(!
config
.
focused
&&
_cursorTimer
!=
null
)
else
if
(!
config
.
focused
&&
_cursorTimer
!=
null
)
_stopCursorTimer
();
_stopCursorTimer
();
return
new
SizedBox
(
return
new
_EditableLineWidget
(
width:
double
.
INFINITY
,
value:
config
.
value
,
child:
new
_EditableTextWidget
(
style:
config
.
style
,
value:
config
.
value
,
cursorColor:
config
.
cursorColor
,
style:
config
.
style
,
showCursor:
_showCursor
,
cursorColor:
config
.
cursorColor
,
hideText:
config
.
hideText
,
showCursor:
_showCursor
,
onContentSizeChanged:
config
.
onContentSizeChanged
,
hideText:
config
.
hideText
,
scrollOffset:
config
.
scrollOffset
onContentSizeChanged:
config
.
onContentSizeChanged
,
scrollOffset:
config
.
scrollOffset
)
);
);
}
}
}
}
final
String
_kZeroWidthSpace
=
new
String
.
fromCharCode
(
0x200B
);
class
_EditableLineWidget
extends
LeafRenderObjectWidget
{
_EditableLineWidget
({
class
_EditableTextWidget
extends
LeafRenderObjectWidget
{
_EditableTextWidget
({
Key
key
,
Key
key
,
this
.
value
,
this
.
value
,
this
.
style
,
this
.
style
,
...
@@ -246,9 +243,9 @@ class _EditableTextWidget extends LeafRenderObjectWidget {
...
@@ -246,9 +243,9 @@ class _EditableTextWidget extends LeafRenderObjectWidget {
final
SizeChangedCallback
onContentSizeChanged
;
final
SizeChangedCallback
onContentSizeChanged
;
final
Offset
scrollOffset
;
final
Offset
scrollOffset
;
RenderEditable
Paragraph
createRenderObject
()
{
RenderEditable
Line
createRenderObject
()
{
return
new
RenderEditable
Paragraph
(
return
new
RenderEditable
Line
(
text:
_
buildTextSpan
()
,
text:
_
styledTextSpan
,
cursorColor:
cursorColor
,
cursorColor:
cursorColor
,
showCursor:
showCursor
,
showCursor:
showCursor
,
onContentSizeChanged:
onContentSizeChanged
,
onContentSizeChanged:
onContentSizeChanged
,
...
@@ -256,17 +253,16 @@ class _EditableTextWidget extends LeafRenderObjectWidget {
...
@@ -256,17 +253,16 @@ class _EditableTextWidget extends LeafRenderObjectWidget {
);
);
}
}
void
updateRenderObject
(
RenderEditable
Paragraph
renderObject
,
void
updateRenderObject
(
RenderEditable
Line
renderObject
,
_Editable
Text
Widget
oldWidget
)
{
_Editable
Line
Widget
oldWidget
)
{
renderObject
.
text
=
_
buildTextSpan
()
;
renderObject
.
text
=
_
styledTextSpan
;
renderObject
.
cursorColor
=
cursorColor
;
renderObject
.
cursorColor
=
cursorColor
;
renderObject
.
showCursor
=
showCursor
;
renderObject
.
showCursor
=
showCursor
;
renderObject
.
onContentSizeChanged
=
onContentSizeChanged
;
renderObject
.
onContentSizeChanged
=
onContentSizeChanged
;
renderObject
.
scrollOffset
=
scrollOffset
;
renderObject
.
scrollOffset
=
scrollOffset
;
}
}
// Construct a TextSpan that renders the EditableString using the chosen style.
StyledTextSpan
get
_styledTextSpan
{
TextSpan
_buildTextSpan
()
{
if
(!
hideText
&&
value
.
composing
.
isValid
)
{
if
(!
hideText
&&
value
.
composing
.
isValid
)
{
TextStyle
composingStyle
=
style
.
merge
(
TextStyle
composingStyle
=
style
.
merge
(
const
TextStyle
(
decoration:
TextDecoration
.
underline
)
const
TextStyle
(
decoration:
TextDecoration
.
underline
)
...
@@ -284,8 +280,6 @@ class _EditableTextWidget extends LeafRenderObjectWidget {
...
@@ -284,8 +280,6 @@ class _EditableTextWidget extends LeafRenderObjectWidget {
String
text
=
value
.
text
;
String
text
=
value
.
text
;
if
(
hideText
)
if
(
hideText
)
text
=
new
String
.
fromCharCodes
(
new
List
<
int
>.
filled
(
text
.
length
,
0x2022
));
text
=
new
String
.
fromCharCodes
(
new
List
<
int
>.
filled
(
text
.
length
,
0x2022
));
return
new
StyledTextSpan
(
style
,
<
TextSpan
>[
return
new
StyledTextSpan
(
style
,
<
TextSpan
>[
new
PlainTextSpan
(
text
)
]);
new
PlainTextSpan
(
text
.
isEmpty
?
_kZeroWidthSpace
:
text
)
]);
}
}
}
}
packages/flutter/lib/widgets.dart
View file @
d081dc67
...
@@ -9,7 +9,7 @@ export 'src/widgets/basic.dart';
...
@@ -9,7 +9,7 @@ export 'src/widgets/basic.dart';
export
'src/widgets/binding.dart'
;
export
'src/widgets/binding.dart'
;
export
'src/widgets/dismissable.dart'
;
export
'src/widgets/dismissable.dart'
;
export
'src/widgets/drag_target.dart'
;
export
'src/widgets/drag_target.dart'
;
export
'src/widgets/editable
_text
.dart'
;
export
'src/widgets/editable.dart'
;
export
'src/widgets/enter_exit_transition.dart'
;
export
'src/widgets/enter_exit_transition.dart'
;
export
'src/widgets/focus.dart'
;
export
'src/widgets/focus.dart'
;
export
'src/widgets/framework.dart'
;
export
'src/widgets/framework.dart'
;
...
...
packages/flutter/test/widget/input_test.dart
View file @
d081dc67
...
@@ -31,7 +31,7 @@ void main() {
...
@@ -31,7 +31,7 @@ void main() {
MockKeyboard
mockKeyboard
=
new
MockKeyboard
();
MockKeyboard
mockKeyboard
=
new
MockKeyboard
();
serviceMocker
.
registerMockService
(
KeyboardService
.
serviceName
,
mockKeyboard
);
serviceMocker
.
registerMockService
(
KeyboardService
.
serviceName
,
mockKeyboard
);
test
(
'Editable text has consistent
width
'
,
()
{
test
(
'Editable text has consistent
size
'
,
()
{
testWidgets
((
WidgetTester
tester
)
{
testWidgets
((
WidgetTester
tester
)
{
GlobalKey
inputKey
=
new
GlobalKey
();
GlobalKey
inputKey
=
new
GlobalKey
();
String
inputValue
;
String
inputValue
;
...
@@ -53,17 +53,21 @@ void main() {
...
@@ -53,17 +53,21 @@ void main() {
Element
input
=
tester
.
findElementByKey
(
inputKey
);
Element
input
=
tester
.
findElementByKey
(
inputKey
);
Size
emptyInputSize
=
(
input
.
renderObject
as
RenderBox
).
size
;
Size
emptyInputSize
=
(
input
.
renderObject
as
RenderBox
).
size
;
// Simulate entry of text through the keyboard.
void
enterText
(
String
testValue
)
{
expect
(
mockKeyboard
.
client
,
isNotNull
);
// Simulate entry of text through the keyboard.
const
String
testValue
=
'Test'
;
expect
(
mockKeyboard
.
client
,
isNotNull
)
;
mockKeyboard
.
client
.
setComposingText
(
testValue
,
testValue
.
length
);
mockKeyboard
.
client
.
setComposingText
(
testValue
,
testValue
.
length
);
// Check that the onChanged event handler fired.
// Check that the onChanged event handler fired.
expect
(
inputValue
,
equals
(
testValue
));
expect
(
inputValue
,
equals
(
testValue
));
tester
.
pumpWidget
(
builder
());
tester
.
pumpWidget
(
builder
());
}
enterText
(
' '
);
expect
((
input
.
renderObject
as
RenderBox
).
size
,
equals
(
emptyInputSize
));
// Check that the Input with text has the same size as the empty Input.
enterText
(
'Test'
);
expect
((
input
.
renderObject
as
RenderBox
).
size
,
equals
(
emptyInputSize
));
expect
((
input
.
renderObject
as
RenderBox
).
size
,
equals
(
emptyInputSize
));
});
});
});
});
...
@@ -85,7 +89,7 @@ void main() {
...
@@ -85,7 +89,7 @@ void main() {
tester
.
pumpWidget
(
builder
());
tester
.
pumpWidget
(
builder
());
EditableTextState
editableText
=
tester
.
findStateOfType
(
EditableTextState
);
RawEditableTextState
editableText
=
tester
.
findStateOfType
(
Raw
EditableTextState
);
// Check that the cursor visibility toggles after each blink interval.
// Check that the cursor visibility toggles after each blink interval.
void
checkCursorToggle
()
{
void
checkCursorToggle
()
{
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment