Revert "[Material] Implement TooltipTheme and Tooltip.textStyle, fix Tooltip debugLabel, update Tooltip defaults (#36030)" (#36851)

This reverts commit 62158a1bae83aedcc88d66694010911a98fff84a.
This commit is contained in:
Shi-Hao Hong 2019-07-24 08:55:51 -07:00 committed by GitHub
parent 62158a1bae
commit aa6384cbac
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 62 additions and 1585 deletions

View File

@ -116,7 +116,6 @@ export 'src/material/time.dart';
export 'src/material/time_picker.dart'; export 'src/material/time_picker.dart';
export 'src/material/toggleable.dart'; export 'src/material/toggleable.dart';
export 'src/material/tooltip.dart'; export 'src/material/tooltip.dart';
export 'src/material/tooltip_theme.dart';
export 'src/material/typography.dart'; export 'src/material/typography.dart';
export 'src/material/user_accounts_drawer_header.dart'; export 'src/material/user_accounts_drawer_header.dart';
export 'widgets.dart'; export 'widgets.dart';

View File

@ -27,7 +27,6 @@ import 'slider_theme.dart';
import 'snack_bar_theme.dart'; import 'snack_bar_theme.dart';
import 'tab_bar_theme.dart'; import 'tab_bar_theme.dart';
import 'text_theme.dart'; import 'text_theme.dart';
import 'tooltip_theme.dart';
import 'typography.dart'; import 'typography.dart';
export 'package:flutter/services.dart' show Brightness; export 'package:flutter/services.dart' show Brightness;
@ -156,7 +155,6 @@ class ThemeData extends Diagnosticable {
IconThemeData accentIconTheme, IconThemeData accentIconTheme,
SliderThemeData sliderTheme, SliderThemeData sliderTheme,
TabBarTheme tabBarTheme, TabBarTheme tabBarTheme,
TooltipThemeData tooltipTheme,
CardTheme cardTheme, CardTheme cardTheme,
ChipThemeData chipTheme, ChipThemeData chipTheme,
TargetPlatform platform, TargetPlatform platform,
@ -259,7 +257,6 @@ class ThemeData extends Diagnosticable {
sliderTheme ??= const SliderThemeData(); sliderTheme ??= const SliderThemeData();
tabBarTheme ??= const TabBarTheme(); tabBarTheme ??= const TabBarTheme();
tooltipTheme ??= const TooltipThemeData();
appBarTheme ??= const AppBarTheme(); appBarTheme ??= const AppBarTheme();
bottomAppBarTheme ??= const BottomAppBarTheme(); bottomAppBarTheme ??= const BottomAppBarTheme();
cardTheme ??= const CardTheme(); cardTheme ??= const CardTheme();
@ -316,7 +313,6 @@ class ThemeData extends Diagnosticable {
accentIconTheme: accentIconTheme, accentIconTheme: accentIconTheme,
sliderTheme: sliderTheme, sliderTheme: sliderTheme,
tabBarTheme: tabBarTheme, tabBarTheme: tabBarTheme,
tooltipTheme: tooltipTheme,
cardTheme: cardTheme, cardTheme: cardTheme,
chipTheme: chipTheme, chipTheme: chipTheme,
platform: platform, platform: platform,
@ -387,7 +383,6 @@ class ThemeData extends Diagnosticable {
@required this.accentIconTheme, @required this.accentIconTheme,
@required this.sliderTheme, @required this.sliderTheme,
@required this.tabBarTheme, @required this.tabBarTheme,
@required this.tooltipTheme,
@required this.cardTheme, @required this.cardTheme,
@required this.chipTheme, @required this.chipTheme,
@required this.platform, @required this.platform,
@ -443,7 +438,6 @@ class ThemeData extends Diagnosticable {
assert(accentIconTheme != null), assert(accentIconTheme != null),
assert(sliderTheme != null), assert(sliderTheme != null),
assert(tabBarTheme != null), assert(tabBarTheme != null),
assert(tooltipTheme != null),
assert(cardTheme != null), assert(cardTheme != null),
assert(chipTheme != null), assert(chipTheme != null),
assert(platform != null), assert(platform != null),
@ -664,17 +658,12 @@ class ThemeData extends Diagnosticable {
/// A theme for customizing the size, shape, and color of the tab bar indicator. /// A theme for customizing the size, shape, and color of the tab bar indicator.
final TabBarTheme tabBarTheme; final TabBarTheme tabBarTheme;
/// A theme for customizing the visual properties of [Tooltip]s.
///
/// This is the value returned from [TooltipTheme.of].
final TooltipThemeData tooltipTheme;
/// The colors and styles used to render [Card]. /// The colors and styles used to render [Card].
/// ///
/// This is the value returned from [CardTheme.of]. /// This is the value returned from [CardTheme.of].
final CardTheme cardTheme; final CardTheme cardTheme;
/// The colors and styles used to render [Chip]s. /// The colors and styles used to render [Chip], [
/// ///
/// This is the value returned from [ChipTheme.of]. /// This is the value returned from [ChipTheme.of].
final ChipThemeData chipTheme; final ChipThemeData chipTheme;
@ -822,7 +811,6 @@ class ThemeData extends Diagnosticable {
IconThemeData accentIconTheme, IconThemeData accentIconTheme,
SliderThemeData sliderTheme, SliderThemeData sliderTheme,
TabBarTheme tabBarTheme, TabBarTheme tabBarTheme,
TooltipThemeData tooltipTheme,
CardTheme cardTheme, CardTheme cardTheme,
ChipThemeData chipTheme, ChipThemeData chipTheme,
TargetPlatform platform, TargetPlatform platform,
@ -882,7 +870,6 @@ class ThemeData extends Diagnosticable {
accentIconTheme: accentIconTheme ?? this.accentIconTheme, accentIconTheme: accentIconTheme ?? this.accentIconTheme,
sliderTheme: sliderTheme ?? this.sliderTheme, sliderTheme: sliderTheme ?? this.sliderTheme,
tabBarTheme: tabBarTheme ?? this.tabBarTheme, tabBarTheme: tabBarTheme ?? this.tabBarTheme,
tooltipTheme: tooltipTheme ?? this.tooltipTheme,
cardTheme: cardTheme ?? this.cardTheme, cardTheme: cardTheme ?? this.cardTheme,
chipTheme: chipTheme ?? this.chipTheme, chipTheme: chipTheme ?? this.chipTheme,
platform: platform ?? this.platform, platform: platform ?? this.platform,
@ -1020,7 +1007,6 @@ class ThemeData extends Diagnosticable {
accentIconTheme: IconThemeData.lerp(a.accentIconTheme, b.accentIconTheme, t), accentIconTheme: IconThemeData.lerp(a.accentIconTheme, b.accentIconTheme, t),
sliderTheme: SliderThemeData.lerp(a.sliderTheme, b.sliderTheme, t), sliderTheme: SliderThemeData.lerp(a.sliderTheme, b.sliderTheme, t),
tabBarTheme: TabBarTheme.lerp(a.tabBarTheme, b.tabBarTheme, t), tabBarTheme: TabBarTheme.lerp(a.tabBarTheme, b.tabBarTheme, t),
tooltipTheme: TooltipThemeData.lerp(a.tooltipTheme, b.tooltipTheme, t),
cardTheme: CardTheme.lerp(a.cardTheme, b.cardTheme, t), cardTheme: CardTheme.lerp(a.cardTheme, b.cardTheme, t),
chipTheme: ChipThemeData.lerp(a.chipTheme, b.chipTheme, t), chipTheme: ChipThemeData.lerp(a.chipTheme, b.chipTheme, t),
platform: t < 0.5 ? a.platform : b.platform, platform: t < 0.5 ? a.platform : b.platform,
@ -1086,7 +1072,6 @@ class ThemeData extends Diagnosticable {
(otherData.accentIconTheme == accentIconTheme) && (otherData.accentIconTheme == accentIconTheme) &&
(otherData.sliderTheme == sliderTheme) && (otherData.sliderTheme == sliderTheme) &&
(otherData.tabBarTheme == tabBarTheme) && (otherData.tabBarTheme == tabBarTheme) &&
(otherData.tooltipTheme == tooltipTheme) &&
(otherData.cardTheme == cardTheme) && (otherData.cardTheme == cardTheme) &&
(otherData.chipTheme == chipTheme) && (otherData.chipTheme == chipTheme) &&
(otherData.platform == platform) && (otherData.platform == platform) &&
@ -1151,7 +1136,6 @@ class ThemeData extends Diagnosticable {
accentIconTheme, accentIconTheme,
sliderTheme, sliderTheme,
tabBarTheme, tabBarTheme,
tooltipTheme,
cardTheme, cardTheme,
chipTheme, chipTheme,
platform, platform,
@ -1214,7 +1198,6 @@ class ThemeData extends Diagnosticable {
properties.add(DiagnosticsProperty<IconThemeData>('accentIconTheme', accentIconTheme)); properties.add(DiagnosticsProperty<IconThemeData>('accentIconTheme', accentIconTheme));
properties.add(DiagnosticsProperty<SliderThemeData>('sliderTheme', sliderTheme)); properties.add(DiagnosticsProperty<SliderThemeData>('sliderTheme', sliderTheme));
properties.add(DiagnosticsProperty<TabBarTheme>('tabBarTheme', tabBarTheme)); properties.add(DiagnosticsProperty<TabBarTheme>('tabBarTheme', tabBarTheme));
properties.add(DiagnosticsProperty<TooltipThemeData>('tooltipTheme', tooltipTheme));
properties.add(DiagnosticsProperty<CardTheme>('cardTheme', cardTheme)); properties.add(DiagnosticsProperty<CardTheme>('cardTheme', cardTheme));
properties.add(DiagnosticsProperty<ChipThemeData>('chipTheme', chipTheme)); properties.add(DiagnosticsProperty<ChipThemeData>('chipTheme', chipTheme));
properties.add(DiagnosticsProperty<MaterialTapTargetSize>('materialTapTargetSize', materialTapTargetSize)); properties.add(DiagnosticsProperty<MaterialTapTargetSize>('materialTapTargetSize', materialTapTargetSize));

View File

@ -8,11 +8,9 @@ import 'package:flutter/gestures.dart';
import 'package:flutter/rendering.dart'; import 'package:flutter/rendering.dart';
import 'package:flutter/widgets.dart'; import 'package:flutter/widgets.dart';
import 'colors.dart';
import 'feedback.dart'; import 'feedback.dart';
import 'theme.dart'; import 'theme.dart';
import 'theme_data.dart'; import 'theme_data.dart';
import 'tooltip_theme.dart';
/// A material design tooltip. /// A material design tooltip.
/// ///
@ -34,54 +32,55 @@ import 'tooltip_theme.dart';
/// See also: /// See also:
/// ///
/// * <https://material.io/design/components/tooltips.html> /// * <https://material.io/design/components/tooltips.html>
/// * [TooltipTheme] or [ThemeData.tooltipTheme]
class Tooltip extends StatefulWidget { class Tooltip extends StatefulWidget {
/// Creates a tooltip. /// Creates a tooltip.
/// ///
/// By default, tooltips should adhere to the /// By default, tooltips prefer to appear below the [child] widget when the
/// [Material specification](https://material.io/design/components/tooltips.html#spec). /// user long presses on the widget.
/// If the optional constructor parameters are not defined, the values
/// provided by [TooltipTheme.of] will be used if a [TooltipTheme] is present
/// or specified in [ThemeData].
/// ///
/// All parameters that are defined in the constructor will /// All of the arguments except [child] and [decoration] must not be null.
/// override the default values _and_ the values in [TooltipTheme.of].
const Tooltip({ const Tooltip({
Key key, Key key,
@required this.message, @required this.message,
this.height, this.height = _defaultTooltipHeight,
this.padding, this.padding = _defaultPadding,
this.verticalOffset, this.verticalOffset = _defaultVerticalOffset,
this.preferBelow, this.preferBelow = true,
this.excludeFromSemantics, this.excludeFromSemantics = false,
this.decoration, this.decoration,
this.textStyle, this.waitDuration = _defaultWaitDuration,
this.waitDuration, this.showDuration = _defaultShowDuration,
this.showDuration,
this.child, this.child,
}) : assert(message != null), }) : assert(message != null),
assert(height != null),
assert(padding != null),
assert(verticalOffset != null),
assert(preferBelow != null),
assert(excludeFromSemantics != null),
assert(waitDuration != null),
assert(showDuration != null),
super(key: key); super(key: key);
static const Duration _defaultShowDuration = Duration(milliseconds: 1500);
static const Duration _defaultWaitDuration = Duration(milliseconds: 0);
static const double _defaultTooltipHeight = 32.0;
static const double _defaultVerticalOffset = 24.0;
static const EdgeInsetsGeometry _defaultPadding = EdgeInsets.symmetric(horizontal: 16.0);
/// The text to display in the tooltip. /// The text to display in the tooltip.
final String message; final String message;
/// The height of the tooltip's [child]. /// They height of the tooltip's [child].
/// ///
/// If the [child] is null, then this is the tooltip's intrinsic height. /// If the [child] is null, then this is the intrinsic height.
final double height; final double height;
/// The amount of space by which to inset the tooltip's [child]. /// The amount of space by which to inset the child.
/// ///
/// Defaults to 16.0 logical pixels in each direction. /// Defaults to 16.0 logical pixels in each direction.
final EdgeInsetsGeometry padding; final EdgeInsetsGeometry padding;
/// The vertical gap between the widget and the displayed tooltip. /// The vertical gap between the widget and the displayed tooltip.
///
/// When [preferBelow] is set to true and tooltips have sufficient space to
/// display themselves, this property defines how much vertical space
/// tooltips will position themselves under their corresponding widgets.
/// Otherwise, tooltips will position themselves above their corresponding
/// widgets with the given offset.
final double verticalOffset; final double verticalOffset;
/// Whether the tooltip defaults to being displayed below the widget. /// Whether the tooltip defaults to being displayed below the widget.
@ -93,10 +92,6 @@ class Tooltip extends StatefulWidget {
/// Whether the tooltip's [message] should be excluded from the semantics /// Whether the tooltip's [message] should be excluded from the semantics
/// tree. /// tree.
///
/// Defaults to false. A tooltip will add a [Semantics.label] that is set to
/// [Tooltip.message]. Set this property to true if the app is going to
/// provide its own custom semantics label.
final bool excludeFromSemantics; final bool excludeFromSemantics;
/// The widget below this widget in the tree. /// The widget below this widget in the tree.
@ -106,28 +101,18 @@ class Tooltip extends StatefulWidget {
/// Specifies the tooltip's shape and background color. /// Specifies the tooltip's shape and background color.
/// ///
/// The tooltip shape defaults to a rounded rectangle with a border radius of /// If not specified, defaults to a rounded rectangle with a border radius of
/// 4.0. Tooltips will also default to an opacity of 90% and with the color /// 4.0, and a color derived from the [ThemeData.textTheme] if the
/// [Colors.grey[700]] if [ThemeData.brightness] is [Brightness.dark], and /// [ThemeData.brightness] is dark, and [ThemeData.primaryTextTheme] if not.
/// [Colors.white] if it is [Brightness.light].
final Decoration decoration; final Decoration decoration;
/// The style to use for the message of the tooltip. /// The amount of time that a pointer must hover over the widget before it
/// will show a tooltip.
/// ///
/// If null, the message's [TextStyle] will be determined based on /// Defaults to 0 milliseconds (tooltips show immediately upon hover).
/// [ThemeData]. If [ThemeData.brightness] is set to [Brightness.dark],
/// [ThemeData.textTheme.body1] will be used with [Colors.white]. Otherwise,
/// if [ThemeData.brightness] is set to [Brightness.light],
/// [ThemeData.textTheme.body1] will be used with [Colors.black].
final TextStyle textStyle;
/// The length of time that a pointer must hover over a tooltip's widget
/// before the tooltip will be shown.
///
/// Defaults to 0 milliseconds (tooltips are shown immediately upon hover).
final Duration waitDuration; final Duration waitDuration;
/// The length of time that the tooltip will be shown once it has appeared. /// The amount of time that the tooltip will be shown once it has appeared.
/// ///
/// Defaults to 1.5 seconds. /// Defaults to 1.5 seconds.
final Duration showDuration; final Duration showDuration;
@ -139,40 +124,24 @@ class Tooltip extends StatefulWidget {
void debugFillProperties(DiagnosticPropertiesBuilder properties) { void debugFillProperties(DiagnosticPropertiesBuilder properties) {
super.debugFillProperties(properties); super.debugFillProperties(properties);
properties.add(StringProperty('message', message, showName: false)); properties.add(StringProperty('message', message, showName: false));
properties.add(DoubleProperty('height', height, defaultValue: null)); properties.add(DoubleProperty('height', height, defaultValue: _defaultTooltipHeight));
properties.add(DiagnosticsProperty<EdgeInsetsGeometry>('padding', padding, defaultValue: null)); properties.add(DiagnosticsProperty<EdgeInsetsGeometry>('padding', padding, defaultValue: _defaultPadding));
properties.add(DoubleProperty('vertical offset', verticalOffset, defaultValue: null)); properties.add(DoubleProperty('vertical offset', verticalOffset, defaultValue: _defaultVerticalOffset));
properties.add(FlagProperty('position', value: preferBelow, ifTrue: 'below', ifFalse: 'above', showName: true, defaultValue: null)); properties.add(FlagProperty('position', value: preferBelow, ifTrue: 'below', ifFalse: 'above', showName: true));
properties.add(FlagProperty('semantics', value: excludeFromSemantics, ifTrue: 'excluded', showName: true, defaultValue: null)); properties.add(FlagProperty('semantics', value: excludeFromSemantics, ifTrue: 'excluded', showName: true, defaultValue: false));
properties.add(DiagnosticsProperty<Duration>('wait duration', waitDuration, defaultValue: null)); properties.add(DiagnosticsProperty<Duration>('wait duration', waitDuration, defaultValue: _defaultWaitDuration));
properties.add(DiagnosticsProperty<Duration>('show duration', showDuration, defaultValue: null)); properties.add(DiagnosticsProperty<Duration>('show duration', showDuration, defaultValue: _defaultShowDuration));
} }
} }
class _TooltipState extends State<Tooltip> with SingleTickerProviderStateMixin { class _TooltipState extends State<Tooltip> with SingleTickerProviderStateMixin {
static const double _defaultTooltipHeight = 32.0;
static const double _defaultVerticalOffset = 24.0;
static const bool _defaultPreferBelow = true;
static const EdgeInsetsGeometry _defaultPadding = EdgeInsets.symmetric(horizontal: 16.0);
static const Duration _fadeInDuration = Duration(milliseconds: 150); static const Duration _fadeInDuration = Duration(milliseconds: 150);
static const Duration _fadeOutDuration = Duration(milliseconds: 75); static const Duration _fadeOutDuration = Duration(milliseconds: 75);
static const Duration _defaultShowDuration = Duration(milliseconds: 1500);
static const Duration _defaultWaitDuration = Duration(milliseconds: 0);
static const bool _defaultExcludeFromSemantics = false;
double height;
EdgeInsetsGeometry padding;
Decoration decoration;
TextStyle textStyle;
double verticalOffset;
bool preferBelow;
bool excludeFromSemantics;
AnimationController _controller; AnimationController _controller;
OverlayEntry _entry; OverlayEntry _entry;
Timer _hideTimer; Timer _hideTimer;
Timer _showTimer; Timer _showTimer;
Duration showDuration;
Duration waitDuration;
bool _mouseIsConnected; bool _mouseIsConnected;
bool _longPressActivated = false; bool _longPressActivated = false;
@ -221,7 +190,7 @@ class _TooltipState extends State<Tooltip> with SingleTickerProviderStateMixin {
} }
if (_longPressActivated) { if (_longPressActivated) {
// Tool tips activated by long press should stay around for 1.5s. // Tool tips activated by long press should stay around for 1.5s.
_hideTimer ??= Timer(showDuration, _controller.reverse); _hideTimer ??= Timer(widget.showDuration, _controller.reverse);
} else { } else {
// Tool tips activated by hover should disappear as soon as the mouse // Tool tips activated by hover should disappear as soon as the mouse
// leaves the control. // leaves the control.
@ -237,7 +206,7 @@ class _TooltipState extends State<Tooltip> with SingleTickerProviderStateMixin {
ensureTooltipVisible(); ensureTooltipVisible();
return; return;
} }
_showTimer ??= Timer(waitDuration, ensureTooltipVisible); _showTimer ??= Timer(widget.waitDuration, ensureTooltipVisible);
} }
/// Shows the tooltip if it is not already visible. /// Shows the tooltip if it is not already visible.
@ -267,17 +236,16 @@ class _TooltipState extends State<Tooltip> with SingleTickerProviderStateMixin {
// rebuilds. // rebuilds.
final Widget overlay = _TooltipOverlay( final Widget overlay = _TooltipOverlay(
message: widget.message, message: widget.message,
height: height, height: widget.height,
padding: padding, padding: widget.padding,
decoration: decoration, decoration: widget.decoration,
textStyle: textStyle,
animation: CurvedAnimation( animation: CurvedAnimation(
parent: _controller, parent: _controller,
curve: Curves.fastOutSlowIn, curve: Curves.fastOutSlowIn,
), ),
target: target, target: target,
verticalOffset: verticalOffset, verticalOffset: widget.verticalOffset,
preferBelow: preferBelow, preferBelow: widget.preferBelow,
); );
_entry = OverlayEntry(builder: (BuildContext context) => overlay); _entry = OverlayEntry(builder: (BuildContext context) => overlay);
Overlay.of(context, debugRequiredFor: widget).insert(_entry); Overlay.of(context, debugRequiredFor: widget).insert(_entry);
@ -332,46 +300,12 @@ class _TooltipState extends State<Tooltip> with SingleTickerProviderStateMixin {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
assert(Overlay.of(context, debugRequiredFor: widget) != null); assert(Overlay.of(context, debugRequiredFor: widget) != null);
final ThemeData theme = Theme.of(context);
final TooltipThemeData tooltipTheme = TooltipTheme.of(context);
TextStyle defaultTextStyle;
BoxDecoration defaultDecoration;
if (theme.brightness == Brightness.dark) {
defaultTextStyle = theme.textTheme.body1.copyWith(
color: Colors.black,
debugLabel: theme.textTheme.body1.debugLabel.replaceAll('white', 'black'),
);
defaultDecoration = BoxDecoration(
color: Colors.white.withOpacity(0.9),
borderRadius: const BorderRadius.all(Radius.circular(4)),
);
} else {
defaultTextStyle = theme.textTheme.body1.copyWith(
color: Colors.white,
debugLabel: theme.textTheme.body1.debugLabel.replaceAll('black', 'white')
);
defaultDecoration = BoxDecoration(
color: Colors.grey[700].withOpacity(0.9),
borderRadius: const BorderRadius.all(Radius.circular(4)),
);
}
height = widget.height ?? tooltipTheme.height ?? _defaultTooltipHeight;
padding = widget.padding ?? tooltipTheme.padding ?? _defaultPadding;
verticalOffset = widget.verticalOffset ?? tooltipTheme.verticalOffset ?? _defaultVerticalOffset;
preferBelow = widget.preferBelow ?? tooltipTheme.preferBelow ?? _defaultPreferBelow;
excludeFromSemantics = widget.excludeFromSemantics ?? tooltipTheme.excludeFromSemantics ?? _defaultExcludeFromSemantics;
decoration = widget.decoration ?? tooltipTheme.decoration ?? defaultDecoration;
textStyle = widget.textStyle ?? tooltipTheme.textStyle ?? defaultTextStyle;
waitDuration = widget.waitDuration ?? tooltipTheme.waitDuration ?? _defaultWaitDuration;
showDuration = widget.showDuration ?? tooltipTheme.showDuration ?? _defaultShowDuration;
Widget result = GestureDetector( Widget result = GestureDetector(
behavior: HitTestBehavior.opaque, behavior: HitTestBehavior.opaque,
onLongPress: _handleLongPress, onLongPress: _handleLongPress,
excludeFromSemantics: true, excludeFromSemantics: true,
child: Semantics( child: Semantics(
label: excludeFromSemantics ? null : widget.message, label: widget.excludeFromSemantics ? null : widget.message,
child: widget.child, child: widget.child,
), ),
); );
@ -411,7 +345,7 @@ class _TooltipPositionDelegate extends SingleChildLayoutDelegate {
/// tooltip. /// tooltip.
final double verticalOffset; final double verticalOffset;
/// Whether the tooltip is displayed below its widget by default. /// Whether the tooltip defaults to being displayed below the widget.
/// ///
/// If there is insufficient space to display the tooltip in the preferred /// If there is insufficient space to display the tooltip in the preferred
/// direction, the tooltip will be displayed in the opposite direction. /// direction, the tooltip will be displayed in the opposite direction.
@ -446,7 +380,6 @@ class _TooltipOverlay extends StatelessWidget {
this.height, this.height,
this.padding, this.padding,
this.decoration, this.decoration,
this.textStyle,
this.animation, this.animation,
this.target, this.target,
this.verticalOffset, this.verticalOffset,
@ -457,7 +390,6 @@ class _TooltipOverlay extends StatelessWidget {
final double height; final double height;
final EdgeInsetsGeometry padding; final EdgeInsetsGeometry padding;
final Decoration decoration; final Decoration decoration;
final TextStyle textStyle;
final Animation<double> animation; final Animation<double> animation;
final Offset target; final Offset target;
final double verticalOffset; final double verticalOffset;
@ -465,6 +397,12 @@ class _TooltipOverlay extends StatelessWidget {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
final ThemeData theme = Theme.of(context);
final ThemeData tooltipTheme = ThemeData(
brightness: Brightness.dark,
textTheme: theme.brightness == Brightness.dark ? theme.textTheme : theme.primaryTextTheme,
platform: theme.platform,
);
return Positioned.fill( return Positioned.fill(
child: IgnorePointer( child: IgnorePointer(
child: CustomSingleChildLayout( child: CustomSingleChildLayout(
@ -478,15 +416,15 @@ class _TooltipOverlay extends StatelessWidget {
child: ConstrainedBox( child: ConstrainedBox(
constraints: BoxConstraints(minHeight: height), constraints: BoxConstraints(minHeight: height),
child: Container( child: Container(
decoration: decoration, decoration: decoration ?? BoxDecoration(
color: tooltipTheme.backgroundColor.withOpacity(0.9),
borderRadius: BorderRadius.circular(4.0),
),
padding: padding, padding: padding,
child: Center( child: Center(
widthFactor: 1.0, widthFactor: 1.0,
heightFactor: 1.0, heightFactor: 1.0,
child: Text( child: Text(message, style: tooltipTheme.textTheme.body1),
message,
style: textStyle,
),
), ),
), ),
), ),

View File

@ -1,251 +0,0 @@
// Copyright 2019 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import 'dart:ui' show lerpDouble;
import 'package:flutter/foundation.dart';
import 'package:flutter/widgets.dart';
import 'theme.dart';
/// Defines the visual properties of [Tooltip] widgets.
///
/// Used by [TooltipTheme] to control the visual properties of tooltips in a
/// widget subtree.
///
/// To obtain this configuration, use [TooltipTheme.of] to access the closest
/// ancestor [TooltipTheme] of the current [BuildContext].
///
/// See also:
///
/// * [TooltipTheme], an [InheritedWidget] that propagates the theme down its
/// subtree.
/// * [TooltipThemeData], which describes the actual configuration of a
/// tooltip theme.
class TooltipThemeData extends Diagnosticable {
/// Creates the set of properties used to configure [Tooltip]s.
const TooltipThemeData({
this.height,
this.padding,
this.verticalOffset,
this.preferBelow,
this.excludeFromSemantics,
this.decoration,
this.textStyle,
this.waitDuration,
this.showDuration,
});
/// The height of [Tooltip.child].
final double height;
/// If provided, the amount of space by which to inset [Tooltip.child].
final EdgeInsetsGeometry padding;
/// The vertical gap between the widget and the displayed tooltip.
///
/// When [preferBelow] is set to true and tooltips have sufficient space to
/// display themselves, this property defines how much vertical space
/// tooltips will position themselves under their corresponding widgets.
/// Otherwise, tooltips will position themselves above their corresponding
/// widgets with the given offset.
final double verticalOffset;
/// Whether the tooltip is displayed below its widget by default.
///
/// If there is insufficient space to display the tooltip in the preferred
/// direction, the tooltip will be displayed in the opposite direction.
final bool preferBelow;
/// Whether the tooltip's [message] should be excluded from the semantics
/// tree.
///
/// By default, [Tooltip]s will add a [Semantics.label] that is set to
/// [Tooltip.message]. Set this property to true if the app is going to
/// provide its own custom semantics label.
final bool excludeFromSemantics;
/// The [Tooltip]'s shape and background color.
final Decoration decoration;
/// The style to use for the message of [Tooltip]s.
final TextStyle textStyle;
/// The length of time that a pointer must hover over a tooltip's widget
/// before the tooltip will be shown.
final Duration waitDuration;
/// The length of time that the tooltip will be shown once it has appeared.
final Duration showDuration;
/// Creates a copy of this object but with the given fields replaced with the
/// new values.
TooltipThemeData copyWith({
double height,
EdgeInsetsGeometry padding,
double verticalOffset,
bool preferBelow,
bool excludeFromSemantics,
Decoration decoration,
TextStyle textStyle,
Duration waitDuration,
Duration showDuration,
}) {
return TooltipThemeData(
height: height ?? this.height,
padding: padding ?? this.padding,
verticalOffset: verticalOffset ?? this.verticalOffset,
preferBelow: preferBelow ?? this.preferBelow,
excludeFromSemantics: excludeFromSemantics ?? this.excludeFromSemantics,
decoration: decoration ?? this.decoration,
textStyle: textStyle ?? this.textStyle,
waitDuration: waitDuration ?? this.waitDuration,
showDuration: showDuration ?? this.showDuration,
);
}
/// Linearly interpolate between two tooltip themes.
///
/// If both arguments are null, then null is returned.
///
/// {@macro dart.ui.shadow.lerp}
static TooltipThemeData lerp(TooltipThemeData a, TooltipThemeData b, double t) {
if (a == null && b == null)
return null;
assert(t != null);
return TooltipThemeData(
height: lerpDouble(a?.height, b?.height, t),
padding: EdgeInsets.lerp(a?.padding, b?.padding, t),
verticalOffset: lerpDouble(a?.verticalOffset, b?.verticalOffset, t),
preferBelow: t < 0.5 ? a.preferBelow: b.preferBelow,
excludeFromSemantics: t < 0.5 ? a.excludeFromSemantics : b.excludeFromSemantics,
decoration: Decoration.lerp(a?.decoration, b?.decoration, t),
textStyle: TextStyle.lerp(a?.textStyle, b?.textStyle, t),
);
}
@override
int get hashCode {
return hashValues(
height,
padding,
verticalOffset,
preferBelow,
excludeFromSemantics,
decoration,
textStyle,
waitDuration,
showDuration,
);
}
@override
bool operator==(Object other) {
if (identical(this, other))
return true;
if (other.runtimeType != runtimeType)
return false;
final TooltipThemeData typedOther = other;
return typedOther.height == height
&& typedOther.padding == padding
&& typedOther.verticalOffset == verticalOffset
&& typedOther.preferBelow == preferBelow
&& typedOther.excludeFromSemantics == excludeFromSemantics
&& typedOther.decoration == decoration
&& typedOther.textStyle == textStyle
&& typedOther.waitDuration == waitDuration
&& typedOther.showDuration == showDuration;
}
@override
void debugFillProperties(DiagnosticPropertiesBuilder properties) {
super.debugFillProperties(properties);
properties.add(DoubleProperty('height', height, defaultValue: null));
properties.add(DiagnosticsProperty<EdgeInsetsGeometry>('padding', padding, defaultValue: null));
properties.add(DoubleProperty('vertical offset', verticalOffset, defaultValue: null));
properties.add(FlagProperty('position', value: preferBelow, ifTrue: 'below', ifFalse: 'above', showName: true, defaultValue: null));
properties.add(FlagProperty('semantics', value: excludeFromSemantics, ifTrue: 'excluded', showName: true, defaultValue: null));
properties.add(DiagnosticsProperty<Decoration>('decoration', decoration, defaultValue: null));
properties.add(DiagnosticsProperty<TextStyle>('textStyle', textStyle, defaultValue: null));
properties.add(DiagnosticsProperty<Duration>('wait duration', waitDuration, defaultValue: null));
properties.add(DiagnosticsProperty<Duration>('show duration', showDuration, defaultValue: null));
}
}
/// An inherited widget that defines the configuration for
/// [Tooltip]s in this widget's subtree.
///
/// Values specified here are used for [Tooltip] properties that are not
/// given an explicit non-null value.
///
/// {@tool sample}
///
/// Here is an example of a tooltip theme that applies a blue foreground
/// with non-rounded corners.
///
/// ```dart
/// TooltipTheme(
/// decoration: BoxDecoration(
/// color: Colors.blue.withOpacity(0.9),
/// borderRadius: BorderRadius.zero,
/// ),
/// child: Tooltip(
/// message: 'Example tooltip',
/// child: IconButton(
/// iconSize: 36.0,
/// icon: Icon(Icons.touch_app),
/// onPressed: () {},
/// ),
/// ),
/// ),
/// ```
/// {@end-tool}
class TooltipTheme extends InheritedWidget {
/// Creates a tooltip theme that controls the configurations for
/// [Tooltip].
TooltipTheme({
Key key,
double height,
EdgeInsetsGeometry padding,
double verticalOffset,
bool preferBelow,
bool excludeFromSemantics,
Decoration decoration,
TextStyle textStyle,
Duration waitDuration,
Duration showDuration,
Widget child,
}) : data = TooltipThemeData(
height: height,
padding: padding,
verticalOffset: verticalOffset,
preferBelow: preferBelow,
excludeFromSemantics: excludeFromSemantics,
decoration: decoration,
textStyle: textStyle,
waitDuration: waitDuration,
showDuration: showDuration,
),
super(key: key, child: child);
/// The properties for descendant [Tooltip] widgets.
final TooltipThemeData data;
/// Returns the [data] from the closest [TooltipTheme] ancestor. If there is
/// no ancestor, it returns [ThemeData.tooltipTheme]. Applications can assume
/// that the returned value will not be null.
///
/// Typical usage is as follows:
///
/// ```dart
/// TooltipThemeData theme = TooltipTheme.of(context);
/// ```
static TooltipThemeData of(BuildContext context) {
final TooltipTheme tooltipTheme = context.inheritFromWidgetOfExactType(TooltipTheme);
return tooltipTheme?.data ?? Theme.of(context).tooltipTheme;
}
@override
bool updateShouldNotify(TooltipTheme oldWidget) => data != oldWidget.data;
}

View File

@ -423,81 +423,6 @@ void main() {
expect(tip.localToGlobal(tip.size.bottomRight(Offset.zero)).dy, equals(324.0)); expect(tip.localToGlobal(tip.size.bottomRight(Offset.zero)).dy, equals(324.0));
}, skip: isBrowser); }, skip: isBrowser);
testWidgets('Default tooltip message textStyle - light', (WidgetTester tester) async {
final GlobalKey key = GlobalKey();
await tester.pumpWidget(MaterialApp(
home: Tooltip(
key: key,
message: tooltipText,
child: Container(
width: 100.0,
height: 100.0,
color: Colors.green[500],
),
),
));
(key.currentState as dynamic).ensureTooltipVisible(); // Before using "as dynamic" in your code, see note at the top of the file.
await tester.pump(const Duration(seconds: 2)); // faded in, show timer started (and at 0.0)
final TextStyle textStyle = tester.widget<Text>(find.text(tooltipText)).style;
expect(textStyle.color, Colors.white);
expect(textStyle.fontFamily, 'Roboto');
expect(textStyle.decoration, TextDecoration.none);
expect(textStyle.debugLabel, '(englishLike body1 2014).merge(whiteMountainView body1)');
});
testWidgets('Default tooltip message textStyle - dark', (WidgetTester tester) async {
final GlobalKey key = GlobalKey();
await tester.pumpWidget(MaterialApp(
theme: ThemeData(
brightness: Brightness.dark,
),
home: Tooltip(
key: key,
message: tooltipText,
child: Container(
width: 100.0,
height: 100.0,
color: Colors.green[500],
),
),
));
(key.currentState as dynamic).ensureTooltipVisible(); // Before using "as dynamic" in your code, see note at the top of the file.
await tester.pump(const Duration(seconds: 2)); // faded in, show timer started (and at 0.0)
final TextStyle textStyle = tester.widget<Text>(find.text(tooltipText)).style;
expect(textStyle.color, Colors.black);
expect(textStyle.fontFamily, 'Roboto');
expect(textStyle.decoration, TextDecoration.none);
expect(textStyle.debugLabel, '(englishLike body1 2014).merge(blackMountainView body1)');
});
testWidgets('Custom tooltip message textStyle', (WidgetTester tester) async {
final GlobalKey key = GlobalKey();
await tester.pumpWidget(MaterialApp(
home: Tooltip(
key: key,
textStyle: const TextStyle(
color: Colors.orange,
decoration: TextDecoration.underline
),
message: tooltipText,
child: Container(
width: 100.0,
height: 100.0,
color: Colors.green[500],
),
),
));
(key.currentState as dynamic).ensureTooltipVisible(); // Before using "as dynamic" in your code, see note at the top of the file.
await tester.pump(const Duration(seconds: 2)); // faded in, show timer started (and at 0.0)
final TextStyle textStyle = tester.widget<Text>(find.text(tooltipText)).style;
expect(textStyle.color, Colors.orange);
expect(textStyle.fontFamily, null);
expect(textStyle.decoration, TextDecoration.underline);
});
testWidgets('Does tooltip end up with the right default size, shape, and color', (WidgetTester tester) async { testWidgets('Does tooltip end up with the right default size, shape, and color', (WidgetTester tester) async {
final GlobalKey key = GlobalKey(); final GlobalKey key = GlobalKey();
await tester.pumpWidget( await tester.pumpWidget(
@ -931,6 +856,7 @@ void main() {
expect(description, <String>[ expect(description, <String>[
'"message"', '"message"',
'position: below',
]); ]);
}); });
testWidgets('Tooltip implements debugFillProperties', (WidgetTester tester) async { testWidgets('Tooltip implements debugFillProperties', (WidgetTester tester) async {

File diff suppressed because it is too large Load Diff