Unverified Commit 65388ee2 authored by Pedro Massango's avatar Pedro Massango Committed by GitHub

Add TextOverflow into TextStyle (#78927)

parent dba71259
...@@ -21,6 +21,24 @@ export 'package:flutter/services.dart' show TextRange, TextSelection; ...@@ -21,6 +21,24 @@ export 'package:flutter/services.dart' show TextRange, TextSelection;
// defaults set in the engine (eg, LibTxt's text_style.h, paragraph_style.h). // defaults set in the engine (eg, LibTxt's text_style.h, paragraph_style.h).
const double _kDefaultFontSize = 14.0; const double _kDefaultFontSize = 14.0;
/// How overflowing text should be handled.
///
/// A [TextOverflow] can be passed to [Text] and [RichText] via their
/// [Text.overflow] and [RichText.overflow] properties respectively.
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,
/// Render overflowing text outside of its container.
visible,
}
/// Holds the [Size] and baseline required to represent the dimensions of /// Holds the [Size] and baseline required to represent the dimensions of
/// a placeholder in text. /// a placeholder in text.
/// ///
......
...@@ -10,6 +10,7 @@ import 'package:flutter/foundation.dart'; ...@@ -10,6 +10,7 @@ import 'package:flutter/foundation.dart';
import 'basic_types.dart'; import 'basic_types.dart';
import 'colors.dart'; import 'colors.dart';
import 'strut_style.dart'; import 'strut_style.dart';
import 'text_painter.dart';
const String _kDefaultDebugLabel = 'unknown'; const String _kDefaultDebugLabel = 'unknown';
...@@ -480,6 +481,7 @@ class TextStyle with Diagnosticable { ...@@ -480,6 +481,7 @@ class TextStyle with Diagnosticable {
String? fontFamily, String? fontFamily,
List<String>? fontFamilyFallback, List<String>? fontFamilyFallback,
String? package, String? package,
this.overflow,
}) : fontFamily = package == null ? fontFamily : 'packages/$package/$fontFamily', }) : fontFamily = package == null ? fontFamily : 'packages/$package/$fontFamily',
_fontFamilyFallback = fontFamilyFallback, _fontFamilyFallback = fontFamilyFallback,
_package = package, _package = package,
...@@ -758,6 +760,9 @@ class TextStyle with Diagnosticable { ...@@ -758,6 +760,9 @@ class TextStyle with Diagnosticable {
/// these variants will be used for rendering. /// these variants will be used for rendering.
final List<ui.FontFeature>? fontFeatures; final List<ui.FontFeature>? fontFeatures;
/// How visual text overflow should be handled.
final TextOverflow? overflow;
/// Creates a copy of this text style but with the given fields replaced with /// Creates a copy of this text style but with the given fields replaced with
/// the new values. /// the new values.
/// ///
...@@ -791,6 +796,7 @@ class TextStyle with Diagnosticable { ...@@ -791,6 +796,7 @@ class TextStyle with Diagnosticable {
TextDecorationStyle? decorationStyle, TextDecorationStyle? decorationStyle,
double? decorationThickness, double? decorationThickness,
String? debugLabel, String? debugLabel,
TextOverflow? overflow,
}) { }) {
assert(color == null || foreground == null, _kColorForegroundWarning); assert(color == null || foreground == null, _kColorForegroundWarning);
assert(backgroundColor == null || background == null, _kColorBackgroundWarning); assert(backgroundColor == null || background == null, _kColorBackgroundWarning);
...@@ -824,6 +830,7 @@ class TextStyle with Diagnosticable { ...@@ -824,6 +830,7 @@ class TextStyle with Diagnosticable {
decorationStyle: decorationStyle ?? this.decorationStyle, decorationStyle: decorationStyle ?? this.decorationStyle,
decorationThickness: decorationThickness ?? this.decorationThickness, decorationThickness: decorationThickness ?? this.decorationThickness,
debugLabel: newDebugLabel, debugLabel: newDebugLabel,
overflow: overflow ?? this.overflow
); );
} }
...@@ -881,6 +888,7 @@ class TextStyle with Diagnosticable { ...@@ -881,6 +888,7 @@ class TextStyle with Diagnosticable {
Locale? locale, Locale? locale,
List<ui.Shadow>? shadows, List<ui.Shadow>? shadows,
List<ui.FontFeature>? fontFeatures, List<ui.FontFeature>? fontFeatures,
TextOverflow? overflow,
}) { }) {
assert(fontSizeFactor != null); assert(fontSizeFactor != null);
assert(fontSizeDelta != null); assert(fontSizeDelta != null);
...@@ -929,6 +937,7 @@ class TextStyle with Diagnosticable { ...@@ -929,6 +937,7 @@ class TextStyle with Diagnosticable {
decorationColor: decorationColor ?? this.decorationColor, decorationColor: decorationColor ?? this.decorationColor,
decorationStyle: decorationStyle ?? this.decorationStyle, decorationStyle: decorationStyle ?? this.decorationStyle,
decorationThickness: decorationThickness == null ? null : decorationThickness! * decorationThicknessFactor + decorationThicknessDelta, decorationThickness: decorationThickness == null ? null : decorationThickness! * decorationThicknessFactor + decorationThicknessDelta,
overflow: overflow ?? this.overflow,
debugLabel: modifiedDebugLabel, debugLabel: modifiedDebugLabel,
); );
} }
...@@ -989,6 +998,7 @@ class TextStyle with Diagnosticable { ...@@ -989,6 +998,7 @@ class TextStyle with Diagnosticable {
decorationColor: other.decorationColor, decorationColor: other.decorationColor,
decorationStyle: other.decorationStyle, decorationStyle: other.decorationStyle,
decorationThickness: other.decorationThickness, decorationThickness: other.decorationThickness,
overflow: other.overflow,
debugLabel: mergedDebugLabel, debugLabel: mergedDebugLabel,
); );
} }
...@@ -1043,6 +1053,7 @@ class TextStyle with Diagnosticable { ...@@ -1043,6 +1053,7 @@ class TextStyle with Diagnosticable {
decorationColor: Color.lerp(null, b.decorationColor, t), decorationColor: Color.lerp(null, b.decorationColor, t),
decorationStyle: t < 0.5 ? null : b.decorationStyle, decorationStyle: t < 0.5 ? null : b.decorationStyle,
decorationThickness: t < 0.5 ? null : b.decorationThickness, decorationThickness: t < 0.5 ? null : b.decorationThickness,
overflow: t < 0.5 ? null : b.overflow,
debugLabel: lerpDebugLabel, debugLabel: lerpDebugLabel,
); );
} }
...@@ -1071,6 +1082,7 @@ class TextStyle with Diagnosticable { ...@@ -1071,6 +1082,7 @@ class TextStyle with Diagnosticable {
decorationColor: Color.lerp(a.decorationColor, null, t), decorationColor: Color.lerp(a.decorationColor, null, t),
decorationStyle: t < 0.5 ? a.decorationStyle : null, decorationStyle: t < 0.5 ? a.decorationStyle : null,
decorationThickness: t < 0.5 ? a.decorationThickness : null, decorationThickness: t < 0.5 ? a.decorationThickness : null,
overflow: t < 0.5 ? a.overflow : null,
debugLabel: lerpDebugLabel, debugLabel: lerpDebugLabel,
); );
} }
...@@ -1106,6 +1118,7 @@ class TextStyle with Diagnosticable { ...@@ -1106,6 +1118,7 @@ class TextStyle with Diagnosticable {
decorationColor: Color.lerp(a.decorationColor, b.decorationColor, t), decorationColor: Color.lerp(a.decorationColor, b.decorationColor, t),
decorationStyle: t < 0.5 ? a.decorationStyle : b.decorationStyle, decorationStyle: t < 0.5 ? a.decorationStyle : b.decorationStyle,
decorationThickness: ui.lerpDouble(a.decorationThickness ?? b.decorationThickness, b.decorationThickness ?? a.decorationThickness, t), decorationThickness: ui.lerpDouble(a.decorationThickness ?? b.decorationThickness, b.decorationThickness ?? a.decorationThickness, t),
overflow: t < 0.5 ? a.overflow : b.overflow,
debugLabel: lerpDebugLabel, debugLabel: lerpDebugLabel,
); );
} }
...@@ -1218,7 +1231,8 @@ class TextStyle with Diagnosticable { ...@@ -1218,7 +1231,8 @@ class TextStyle with Diagnosticable {
background != other.background || background != other.background ||
!listEquals(shadows, other.shadows) || !listEquals(shadows, other.shadows) ||
!listEquals(fontFeatures, other.fontFeatures) || !listEquals(fontFeatures, other.fontFeatures) ||
!listEquals(fontFamilyFallback, other.fontFamilyFallback)) !listEquals(fontFamilyFallback, other.fontFamilyFallback) ||
overflow != other.overflow)
return RenderComparison.layout; return RenderComparison.layout;
if (color != other.color || if (color != other.color ||
backgroundColor != other.backgroundColor || backgroundColor != other.backgroundColor ||
...@@ -1258,7 +1272,8 @@ class TextStyle with Diagnosticable { ...@@ -1258,7 +1272,8 @@ class TextStyle with Diagnosticable {
&& other.decorationThickness == decorationThickness && other.decorationThickness == decorationThickness
&& listEquals(other.shadows, shadows) && listEquals(other.shadows, shadows)
&& listEquals(other.fontFeatures, fontFeatures) && listEquals(other.fontFeatures, fontFeatures)
&& listEquals(other.fontFamilyFallback, fontFamilyFallback); && listEquals(other.fontFamilyFallback, fontFamilyFallback)
&& other.overflow == overflow;
} }
@override @override
...@@ -1285,6 +1300,7 @@ class TextStyle with Diagnosticable { ...@@ -1285,6 +1300,7 @@ class TextStyle with Diagnosticable {
hashList(shadows), hashList(shadows),
hashList(fontFeatures), hashList(fontFeatures),
hashList(fontFamilyFallback), hashList(fontFamilyFallback),
overflow,
]); ]);
} }
...@@ -1355,5 +1371,7 @@ class TextStyle with Diagnosticable { ...@@ -1355,5 +1371,7 @@ class TextStyle with Diagnosticable {
if (!styleSpecified) if (!styleSpecified)
properties.add(FlagProperty('inherit', value: inherit, ifTrue: '$prefix<all styles inherited>', ifFalse: '$prefix<no style specified>')); properties.add(FlagProperty('inherit', value: inherit, ifTrue: '$prefix<all styles inherited>', ifFalse: '$prefix<no style specified>'));
styles.add(EnumProperty<TextOverflow>('${prefix}overflow', overflow, defaultValue: null));
} }
} }
...@@ -16,24 +16,6 @@ import 'box.dart'; ...@@ -16,24 +16,6 @@ import 'box.dart';
import 'debug.dart'; import 'debug.dart';
import 'object.dart'; import 'object.dart';
/// How overflowing text should be handled.
///
/// A [TextOverflow] can be passed to [Text] and [RichText] via their
/// [Text.overflow] and [RichText.overflow] properties respectively.
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,
/// Render overflowing text outside of its container.
visible,
}
const String _kEllipsis = '\u2026'; const String _kEllipsis = '\u2026';
/// Parent data for use with [RenderParagraph]. /// Parent data for use with [RenderParagraph].
......
...@@ -467,7 +467,8 @@ class Text extends StatelessWidget { ...@@ -467,7 +467,8 @@ class Text extends StatelessWidget {
/// How visual overflow should be handled. /// How visual overflow should be handled.
/// ///
/// Defaults to retrieving the value from the nearest [DefaultTextStyle] ancestor. /// If this is null [TextStyle.overflow] will be used, otherwise the value
/// from the nearest [DefaultTextStyle] ancestor will be used.
final TextOverflow? overflow; final TextOverflow? overflow;
/// The number of font pixels for each logical pixel. /// The number of font pixels for each logical pixel.
...@@ -526,7 +527,7 @@ class Text extends StatelessWidget { ...@@ -526,7 +527,7 @@ class Text extends StatelessWidget {
textDirection: textDirection, // RichText uses Directionality.of to obtain a default if this is null. textDirection: textDirection, // RichText uses Directionality.of to obtain a default if this is null.
locale: locale, // RichText uses Localizations.localeOf to obtain a default if this is null locale: locale, // RichText uses Localizations.localeOf to obtain a default if this is null
softWrap: softWrap ?? defaultTextStyle.softWrap, softWrap: softWrap ?? defaultTextStyle.softWrap,
overflow: overflow ?? defaultTextStyle.overflow, overflow: overflow ?? effectiveTextStyle?.overflow ?? defaultTextStyle.overflow,
textScaleFactor: textScaleFactor ?? MediaQuery.textScaleFactorOf(context), textScaleFactor: textScaleFactor ?? MediaQuery.textScaleFactorOf(context),
maxLines: maxLines ?? defaultTextStyle.maxLines, maxLines: maxLines ?? defaultTextStyle.maxLines,
strutStyle: strutStyle, strutStyle: strutStyle,
......
...@@ -744,6 +744,8 @@ class _TextStyleProxy implements TextStyle { ...@@ -744,6 +744,8 @@ class _TextStyleProxy implements TextStyle {
List<Shadow>? get shadows => _delegate.shadows; List<Shadow>? get shadows => _delegate.shadows;
@override @override
List<ui.FontFeature>? get fontFeatures => _delegate.fontFeatures; List<ui.FontFeature>? get fontFeatures => _delegate.fontFeatures;
@override
TextOverflow? get overflow => _delegate.overflow;
@override @override
String toString({ DiagnosticLevel minLevel = DiagnosticLevel.info }) => String toString({ DiagnosticLevel minLevel = DiagnosticLevel.info }) =>
...@@ -785,6 +787,7 @@ class _TextStyleProxy implements TextStyle { ...@@ -785,6 +787,7 @@ class _TextStyleProxy implements TextStyle {
Locale? locale, Locale? locale,
List<ui.Shadow>? shadows, List<ui.Shadow>? shadows,
List<ui.FontFeature>? fontFeatures, List<ui.FontFeature>? fontFeatures,
TextOverflow? overflow,
}) { }) {
throw UnimplementedError(); throw UnimplementedError();
} }
...@@ -819,6 +822,7 @@ class _TextStyleProxy implements TextStyle { ...@@ -819,6 +822,7 @@ class _TextStyleProxy implements TextStyle {
TextDecorationStyle? decorationStyle, TextDecorationStyle? decorationStyle,
double? decorationThickness, double? decorationThickness,
String? debugLabel, String? debugLabel,
TextOverflow? overflow,
}) { }) {
throw UnimplementedError(); throw UnimplementedError();
} }
......
...@@ -1248,6 +1248,21 @@ void main() { ...@@ -1248,6 +1248,21 @@ void main() {
// The inline spans are rendered in one vertical run, the widest one determines the min intrinsic width. // The inline spans are rendered in one vertical run, the widest one determines the min intrinsic width.
expect(paragraph.getMinIntrinsicWidth(0.0), 200); expect(paragraph.getMinIntrinsicWidth(0.0), 200);
}); });
testWidgets('Text uses TextStyle.overflow', (WidgetTester tester) async {
const TextOverflow overflow = TextOverflow.fade;
await tester.pumpWidget( const Text(
'Hello World',
textDirection: TextDirection.ltr,
style: TextStyle(overflow: overflow),
));
final RichText richText = tester.firstWidget(find.byType(RichText));
expect(richText.overflow, overflow);
expect(richText.text.style!.overflow, overflow);
});
} }
Future<void> _pumpTextWidget({ Future<void> _pumpTextWidget({
......
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