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
36d437d6
Commit
36d437d6
authored
May 09, 2016
by
Adam Barth
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Add support for TextOverflow.ellipsis (#3818)
Fixes #417
parent
4d8f38e5
Changes
4
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
199 additions
and
25 deletions
+199
-25
app_bar.dart
packages/flutter/lib/src/material/app_bar.dart
+7
-1
tabs.dart
packages/flutter/lib/src/material/tabs.dart
+9
-4
paragraph.dart
packages/flutter/lib/src/rendering/paragraph.dart
+116
-5
basic.dart
packages/flutter/lib/src/widgets/basic.dart
+67
-15
No files found.
packages/flutter/lib/src/material/app_bar.dart
View file @
36d437d6
...
...
@@ -209,7 +209,13 @@ class AppBar extends StatelessWidget {
toolBarRow
.
add
(
new
Flexible
(
child:
new
Padding
(
padding:
new
EdgeInsets
.
only
(
left:
8.0
),
child:
title
!=
null
?
new
DefaultTextStyle
(
style:
centerStyle
,
child:
title
)
:
null
child:
title
!=
null
?
new
DefaultTextStyle
(
style:
centerStyle
,
softWrap:
false
,
overflow:
TextOverflow
.
ellipsis
,
child:
title
)
:
null
)
));
if
(
actions
!=
null
)
...
...
packages/flutter/lib/src/material/tabs.dart
View file @
36d437d6
...
...
@@ -345,7 +345,12 @@ class _Tab extends StatelessWidget {
Widget
_buildLabelText
()
{
assert
(
label
.
text
!=
null
);
TextStyle
style
=
new
TextStyle
(
color:
color
);
return
new
Text
(
label
.
text
,
style:
style
);
return
new
Text
(
label
.
text
,
style:
style
,
softWrap:
false
,
overflow:
TextOverflow
.
fade
);
}
Widget
_buildLabelIcon
(
BuildContext
context
)
{
...
...
@@ -371,15 +376,15 @@ class _Tab extends StatelessWidget {
labelContent
=
_buildLabelIcon
(
context
);
}
else
{
labelContent
=
new
Column
(
mainAxisAlignment:
MainAxisAlignment
.
center
,
crossAxisAlignment:
CrossAxisAlignment
.
center
,
children:
<
Widget
>[
new
Container
(
child:
_buildLabelIcon
(
context
),
margin:
const
EdgeInsets
.
only
(
bottom:
10.0
)
),
_buildLabelText
()
],
mainAxisAlignment:
MainAxisAlignment
.
center
,
crossAxisAlignment:
CrossAxisAlignment
.
center
]
);
}
...
...
packages/flutter/lib/src/rendering/paragraph.dart
View file @
36d437d6
...
...
@@ -2,20 +2,42 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import
'dart:ui'
as
ui
;
import
'package:flutter/gestures.dart'
;
import
'box.dart'
;
import
'object.dart'
;
import
'semantics.dart'
;
/// How overflowing text should be handled.
enum
TextOverflow
{
/// Clip the overflowing text to fix its container.
clip
,
/// Fade the overflowing text to transparent.
fade
,
/// Use an ellipsis to indicate that the text has overflowed.
ellipsis
,
}
/// A render object that displays a paragraph of text
class
RenderParagraph
extends
RenderBox
{
/// Creates a paragraph render object.
///
/// The [text], [overflow], and [softWrap] arguments must not be null.
RenderParagraph
(
TextSpan
text
,
{
TextAlign
textAlign
})
:
_textPainter
=
new
TextPainter
(
text:
text
,
textAlign:
textAlign
)
{
TextAlign
textAlign
,
TextOverflow
overflow:
TextOverflow
.
clip
,
bool
softWrap:
true
})
:
_softWrap
=
softWrap
,
_overflow
=
overflow
,
_textPainter
=
new
TextPainter
(
text:
text
,
textAlign:
textAlign
)
{
assert
(
text
!=
null
);
assert
(
text
.
debugAssertValid
());
assert
(
overflow
!=
null
);
assert
(
softWrap
!=
null
);
}
final
TextPainter
_textPainter
;
...
...
@@ -27,6 +49,8 @@ class RenderParagraph extends RenderBox {
if
(
_textPainter
.
text
==
value
)
return
;
_textPainter
.
text
=
value
;
_overflowPainter
=
null
;
_overflowShader
=
null
;
markNeedsLayout
();
}
...
...
@@ -39,10 +63,34 @@ class RenderParagraph extends RenderBox {
markNeedsPaint
();
}
/// Whether the text should break at soft line breaks.
///
/// If false, the glyphs in the text will be positioned as if there was unlimited horizontal space.
bool
get
softWrap
=>
_softWrap
;
bool
_softWrap
;
void
set
softWrap
(
bool
value
)
{
assert
(
value
!=
null
);
if
(
_softWrap
==
value
)
return
;
_softWrap
=
value
;
markNeedsLayout
();
}
/// How visual overflow should be handled.
TextOverflow
get
overflow
=>
_overflow
;
TextOverflow
_overflow
;
void
set
overflow
(
TextOverflow
value
)
{
assert
(
value
!=
null
);
if
(
_overflow
==
value
)
return
;
_overflow
=
value
;
markNeedsPaint
();
}
void
_layoutText
(
BoxConstraints
constraints
)
{
assert
(
constraints
!=
null
);
assert
(
constraints
.
debugAssertIsValid
());
_textPainter
.
layout
(
minWidth:
constraints
.
minWidth
,
maxWidth:
constraints
.
maxWidth
);
_textPainter
.
layout
(
minWidth:
constraints
.
minWidth
,
maxWidth:
_softWrap
?
constraints
.
maxWidth
:
double
.
INFINITY
);
}
@override
...
...
@@ -95,10 +143,49 @@ class RenderParagraph extends RenderBox {
span
?.
recognizer
?.
addPointer
(
event
);
}
bool
_hasVisualOverflow
=
false
;
TextPainter
_overflowPainter
;
ui
.
Shader
_overflowShader
;
@override
void
performLayout
()
{
_layoutText
(
constraints
);
size
=
constraints
.
constrain
(
_textPainter
.
size
);
final
bool
didOverflowWidth
=
size
.
width
<
_textPainter
.
width
;
// TODO(abarth): We're only measuring the sizes of the line boxes here. If
// the glyphs draw outside the line boxes, we might think that there isn't
// visual overflow when there actually is visual overflow. This can become
// a problem if we start having horizontal overflow and introduce a clip
// that affects the actual (but undetected) vertical overflow.
_hasVisualOverflow
=
didOverflowWidth
||
size
.
height
<
_textPainter
.
height
;
if
(
didOverflowWidth
)
{
switch
(
_overflow
)
{
case
TextOverflow
.
clip
:
_overflowPainter
=
null
;
_overflowShader
=
null
;
break
;
case
TextOverflow
.
fade
:
case
TextOverflow
.
ellipsis
:
_overflowPainter
??=
new
TextPainter
(
text:
new
TextSpan
(
style:
_textPainter
.
text
.
style
,
text:
'
\
u2026'
)
)..
layout
();
final
double
overflowUnit
=
_overflowPainter
.
width
;
double
fadeEnd
=
size
.
width
;
if
(
_overflow
==
TextOverflow
.
ellipsis
)
fadeEnd
-=
overflowUnit
/
2.0
;
final
double
fadeStart
=
fadeEnd
-
_overflowPainter
.
width
;
// TODO(abarth): This shader has an LTR bias.
_overflowShader
=
new
ui
.
Gradient
.
linear
(
<
Point
>[
new
Point
(
fadeStart
,
0.0
),
new
Point
(
fadeEnd
,
0.0
)],
<
Color
>[
const
Color
(
0xFFFFFFFF
),
const
Color
(
0x00FFFFFF
)]
);
break
;
}
}
else
{
_overflowPainter
=
null
;
_overflowShader
=
null
;
}
}
@override
...
...
@@ -114,7 +201,31 @@ class RenderParagraph extends RenderBox {
// If you remove this call, make sure that changing the textAlign still
// works properly.
_layoutText
(
constraints
);
_textPainter
.
paint
(
context
.
canvas
,
offset
);
final
Canvas
canvas
=
context
.
canvas
;
if
(
_hasVisualOverflow
)
{
final
Rect
bounds
=
offset
&
size
;
if
(
_overflowPainter
!=
null
)
canvas
.
saveLayer
(
bounds
,
new
Paint
());
else
canvas
.
save
();
canvas
.
clipRect
(
bounds
);
}
_textPainter
.
paint
(
canvas
,
offset
);
if
(
_hasVisualOverflow
)
{
if
(
_overflowShader
!=
null
)
{
canvas
.
translate
(
offset
.
dx
,
offset
.
dy
);
Paint
paint
=
new
Paint
()
..
transferMode
=
TransferMode
.
modulate
..
shader
=
_overflowShader
;
canvas
.
drawRect
(
Point
.
origin
&
size
,
paint
);
if
(
_overflow
==
TextOverflow
.
ellipsis
)
{
// TODO(abarth): This paint offset has an LTR bias.
Offset
ellipseOffset
=
new
Offset
(
size
.
width
-
_overflowPainter
.
width
,
0.0
);
_overflowPainter
.
paint
(
canvas
,
ellipseOffset
);
}
}
canvas
.
restore
();
}
}
@override
...
...
packages/flutter/lib/src/widgets/basic.dart
View file @
36d437d6
...
...
@@ -45,6 +45,7 @@ export 'package:flutter/rendering.dart' show
RenderObjectPainter
,
ShaderCallback
,
SingleChildLayoutDelegate
,
TextOverflow
,
ValueChanged
,
ViewportAnchor
,
ViewportDimensions
,
...
...
@@ -1904,8 +1905,16 @@ class RichText extends LeafRenderObjectWidget {
/// Creates a paragraph of rich text.
///
/// The [text] argument is required to be non-null.
RichText
({
Key
key
,
this
.
text
,
this
.
textAlign
})
:
super
(
key:
key
)
{
RichText
({
Key
key
,
this
.
text
,
this
.
textAlign
,
this
.
softWrap
:
true
,
this
.
overflow
:
TextOverflow
.
clip
})
:
super
(
key:
key
)
{
assert
(
text
!=
null
);
assert
(
softWrap
!=
null
);
assert
(
overflow
!=
null
);
}
/// The text to display in this widget.
...
...
@@ -1914,16 +1923,30 @@ class RichText extends LeafRenderObjectWidget {
/// How the text should be aligned horizontally.
final
TextAlign
textAlign
;
/// Whether the text should break at soft line breaks.
///
/// If false, the glyphs in the text will be positioned as if there was unlimited horizontal space.
final
bool
softWrap
;
/// How visual overflow should be handled.
final
TextOverflow
overflow
;
@override
RenderParagraph
createRenderObject
(
BuildContext
context
)
{
return
new
RenderParagraph
(
text
,
textAlign:
textAlign
);
return
new
RenderParagraph
(
text
,
textAlign:
textAlign
,
softWrap:
softWrap
,
overflow:
overflow
);
}
@override
void
updateRenderObject
(
BuildContext
context
,
RenderParagraph
renderObject
)
{
renderObject
..
text
=
text
..
textAlign
=
textAlign
;
..
textAlign
=
textAlign
..
softWrap
=
softWrap
..
overflow
=
overflow
;
}
}
...
...
@@ -1937,16 +1960,24 @@ class DefaultTextStyle extends InheritedWidget {
Key
key
,
this
.
style
,
this
.
textAlign
,
this
.
softWrap
:
true
,
this
.
overflow
:
TextOverflow
.
clip
,
Widget
child
})
:
super
(
key:
key
,
child:
child
)
{
assert
(
style
!=
null
);
assert
(
softWrap
!=
null
);
assert
(
overflow
!=
null
);
assert
(
child
!=
null
);
}
/// A const-constructible default text style that provides fallback values.
///
/// Returned from [of] when the given [BuildContext] doesn't have an enclosing default text style.
const
DefaultTextStyle
.
fallback
()
:
style
=
const
TextStyle
(),
textAlign
=
null
;
const
DefaultTextStyle
.
fallback
()
:
style
=
const
TextStyle
(),
textAlign
=
null
,
softWrap
=
true
,
overflow
=
TextOverflow
.
clip
;
/// Creates a default text style that inherits from the given [BuildContext].
///
...
...
@@ -1959,6 +1990,8 @@ class DefaultTextStyle extends InheritedWidget {
BuildContext
context
,
TextStyle
style
,
TextAlign
textAlign
,
bool
softWrap
,
TextOverflow
overflow
,
Widget
child
})
{
DefaultTextStyle
parent
=
DefaultTextStyle
.
of
(
context
);
...
...
@@ -1966,6 +1999,8 @@ class DefaultTextStyle extends InheritedWidget {
key:
key
,
style:
parent
.
style
.
merge
(
style
),
textAlign:
textAlign
??
parent
.
textAlign
,
softWrap:
softWrap
??
parent
.
softWrap
,
overflow:
overflow
??
parent
.
overflow
,
child:
child
);
}
...
...
@@ -1976,6 +2011,14 @@ class DefaultTextStyle extends InheritedWidget {
/// How the text should be aligned horizontally.
final
TextAlign
textAlign
;
/// Whether the text should break at soft line breaks.
///
/// If false, the glyphs in the text will be positioned as if there was unlimited horizontal space.
final
bool
softWrap
;
/// How visual overflow should be handled.
final
TextOverflow
overflow
;
/// The closest instance of this class that encloses the given context.
///
/// If no such instance exists, returns an instance created by
...
...
@@ -2019,7 +2062,13 @@ class Text extends StatelessWidget {
///
/// If the [style] argument is null, the text will use the style from the
/// closest enclosing [DefaultTextStyle].
Text
(
this
.
data
,
{
Key
key
,
this
.
style
,
this
.
textAlign
})
:
super
(
key:
key
)
{
Text
(
this
.
data
,
{
Key
key
,
this
.
style
,
this
.
textAlign
,
this
.
softWrap
,
this
.
overflow
})
:
super
(
key:
key
)
{
assert
(
data
!=
null
);
}
...
...
@@ -2036,21 +2085,24 @@ class Text extends StatelessWidget {
/// How the text should be aligned horizontally.
final
TextAlign
textAlign
;
/// Whether the text should break at soft line breaks.
///
/// If false, the glyphs in the text will be positioned as if there was unlimited horizontal space.
final
bool
softWrap
;
/// How visual overflow should be handled.
final
TextOverflow
overflow
;
@override
Widget
build
(
BuildContext
context
)
{
DefaultTextStyle
defaultTextStyle
;
DefaultTextStyle
defaultTextStyle
=
DefaultTextStyle
.
of
(
context
)
;
TextStyle
effectiveTextStyle
=
style
;
if
(
style
==
null
||
style
.
inherit
)
{
defaultTextStyle
??=
DefaultTextStyle
.
of
(
context
);
if
(
style
==
null
||
style
.
inherit
)
effectiveTextStyle
=
defaultTextStyle
.
style
.
merge
(
style
);
}
TextAlign
effectiveTextAlign
=
textAlign
;
if
(
effectiveTextAlign
==
null
)
{
defaultTextStyle
??=
DefaultTextStyle
.
of
(
context
);
effectiveTextAlign
=
defaultTextStyle
.
textAlign
;
}
return
new
RichText
(
textAlign:
effectiveTextAlign
,
textAlign:
textAlign
??
defaultTextStyle
.
textAlign
,
softWrap:
softWrap
??
defaultTextStyle
.
softWrap
,
overflow:
overflow
??
defaultTextStyle
.
overflow
,
text:
new
TextSpan
(
style:
effectiveTextStyle
,
text:
data
...
...
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