| // Copyright 2014 The Flutter 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/rendering.dart'; |
| import 'package:flutter/widgets.dart'; |
| |
| import 'theme.dart'; |
| |
| // Examples can assume: |
| // late BuildContext context; |
| |
| /// Defines the configuration of the search views created by the [SearchAnchor] |
| /// widget. |
| /// |
| /// Descendant widgets obtain the current [SearchViewThemeData] object using |
| /// `SearchViewTheme.of(context)`. |
| /// |
| /// Typically, a [SearchViewThemeData] is specified as part of the overall [Theme] |
| /// with [ThemeData.searchViewTheme]. Otherwise, [SearchViewTheme] can be used |
| /// to configure its own widget subtree. |
| /// |
| /// All [SearchViewThemeData] properties are `null` by default. If any of these |
| /// properties are null, the search view will provide its own defaults. |
| /// |
| /// See also: |
| /// |
| /// * [ThemeData], which describes the overall theme for the application. |
| /// * [SearchBarThemeData], which describes the theme for the search bar itself in a |
| /// [SearchBar] widget. |
| /// * [SearchAnchor], which is used to open a search view route. |
| @immutable |
| class SearchViewThemeData with Diagnosticable { |
| /// Creates a theme that can be used for [ThemeData.searchViewTheme]. |
| const SearchViewThemeData({ |
| this.backgroundColor, |
| this.elevation, |
| this.surfaceTintColor, |
| this.constraints, |
| this.side, |
| this.shape, |
| this.headerTextStyle, |
| this.headerHintStyle, |
| this.dividerColor, |
| }); |
| |
| /// Overrides the default value of the [SearchAnchor.viewBackgroundColor]. |
| final Color? backgroundColor; |
| |
| /// Overrides the default value of the [SearchAnchor.viewElevation]. |
| final double? elevation; |
| |
| /// Overrides the default value of the [SearchAnchor.viewSurfaceTintColor]. |
| final Color? surfaceTintColor; |
| |
| /// Overrides the default value of the [SearchAnchor.viewSide]. |
| final BorderSide? side; |
| |
| /// Overrides the default value of the [SearchAnchor.viewShape]. |
| final OutlinedBorder? shape; |
| |
| /// Overrides the default value for [SearchAnchor.headerTextStyle]. |
| final TextStyle? headerTextStyle; |
| |
| /// Overrides the default value for [SearchAnchor.headerHintStyle]. |
| final TextStyle? headerHintStyle; |
| |
| /// Overrides the value of size constraints for [SearchAnchor.viewConstraints]. |
| final BoxConstraints? constraints; |
| |
| /// Overrides the value of the divider color for [SearchAnchor.dividerColor]. |
| final Color? dividerColor; |
| |
| /// Creates a copy of this object but with the given fields replaced with the |
| /// new values. |
| SearchViewThemeData copyWith({ |
| Color? backgroundColor, |
| double? elevation, |
| Color? surfaceTintColor, |
| BorderSide? side, |
| OutlinedBorder? shape, |
| TextStyle? headerTextStyle, |
| TextStyle? headerHintStyle, |
| BoxConstraints? constraints, |
| Color? dividerColor, |
| }) { |
| return SearchViewThemeData( |
| backgroundColor: backgroundColor ?? this.backgroundColor, |
| elevation: elevation ?? this.elevation, |
| surfaceTintColor: surfaceTintColor ?? this.surfaceTintColor, |
| side: side ?? this.side, |
| shape: shape ?? this.shape, |
| headerTextStyle: headerTextStyle ?? this.headerTextStyle, |
| headerHintStyle: headerHintStyle ?? this.headerHintStyle, |
| constraints: constraints ?? this.constraints, |
| dividerColor: dividerColor ?? this.dividerColor, |
| ); |
| } |
| |
| /// Linearly interpolate between two [SearchViewThemeData]s. |
| static SearchViewThemeData? lerp(SearchViewThemeData? a, SearchViewThemeData? b, double t) { |
| if (identical(a, b)) { |
| return a; |
| } |
| return SearchViewThemeData( |
| backgroundColor: Color.lerp(a?.backgroundColor, b?.backgroundColor, t), |
| elevation: lerpDouble(a?.elevation, b?.elevation, t), |
| surfaceTintColor: Color.lerp(a?.surfaceTintColor, b?.surfaceTintColor, t), |
| side: _lerpSides(a?.side, b?.side, t), |
| shape: OutlinedBorder.lerp(a?.shape, b?.shape, t), |
| headerTextStyle: TextStyle.lerp(a?.headerTextStyle, b?.headerTextStyle, t), |
| headerHintStyle: TextStyle.lerp(a?.headerTextStyle, b?.headerTextStyle, t), |
| constraints: BoxConstraints.lerp(a?.constraints, b?.constraints, t), |
| dividerColor: Color.lerp(a?.dividerColor, b?.dividerColor, t), |
| ); |
| } |
| |
| @override |
| int get hashCode => Object.hash( |
| backgroundColor, |
| elevation, |
| surfaceTintColor, |
| side, |
| shape, |
| headerTextStyle, |
| headerHintStyle, |
| constraints, |
| dividerColor, |
| ); |
| |
| @override |
| bool operator ==(Object other) { |
| if (identical(this, other)) { |
| return true; |
| } |
| if (other.runtimeType != runtimeType) { |
| return false; |
| } |
| return other is SearchViewThemeData |
| && other.backgroundColor == backgroundColor |
| && other.elevation == elevation |
| && other.surfaceTintColor == surfaceTintColor |
| && other.side == side |
| && other.shape == shape |
| && other.headerTextStyle == headerTextStyle |
| && other.headerHintStyle == headerHintStyle |
| && other.constraints == constraints |
| && other.dividerColor == dividerColor; |
| } |
| |
| @override |
| void debugFillProperties(DiagnosticPropertiesBuilder properties) { |
| super.debugFillProperties(properties); |
| properties.add(DiagnosticsProperty<Color?>('backgroundColor', backgroundColor, defaultValue: null)); |
| properties.add(DiagnosticsProperty<double?>('elevation', elevation, defaultValue: null)); |
| properties.add(DiagnosticsProperty<Color?>('surfaceTintColor', surfaceTintColor, defaultValue: null)); |
| properties.add(DiagnosticsProperty<BorderSide?>('side', side, defaultValue: null)); |
| properties.add(DiagnosticsProperty<OutlinedBorder?>('shape', shape, defaultValue: null)); |
| properties.add(DiagnosticsProperty<TextStyle?>('headerTextStyle', headerTextStyle, defaultValue: null)); |
| properties.add(DiagnosticsProperty<TextStyle?>('headerHintStyle', headerHintStyle, defaultValue: null)); |
| properties.add(DiagnosticsProperty<BoxConstraints>('constraints', constraints, defaultValue: null)); |
| properties.add(DiagnosticsProperty<Color?>('dividerColor', dividerColor, defaultValue: null)); |
| } |
| |
| // Special case because BorderSide.lerp() doesn't support null arguments |
| static BorderSide? _lerpSides(BorderSide? a, BorderSide? b, double t) { |
| if (a == null || b == null) { |
| return null; |
| } |
| if (identical(a, b)) { |
| return a; |
| } |
| return BorderSide.lerp(a, b, t); |
| } |
| } |
| |
| /// An inherited widget that defines the configuration in this widget's |
| /// descendants for search view created by the [SearchAnchor] widget. |
| /// |
| /// A search view theme can be specified as part of the overall Material theme using |
| /// [ThemeData.searchViewTheme]. |
| /// |
| /// See also: |
| /// |
| /// * [SearchViewThemeData], which describes the actual configuration of a search view |
| /// theme. |
| class SearchViewTheme extends InheritedWidget { |
| /// Creates a const theme that controls the configurations for the search view |
| /// created by the [SearchAnchor] widget. |
| const SearchViewTheme({ |
| super.key, |
| required this.data, |
| required super.child, |
| }); |
| |
| /// The properties used for all descendant [SearchAnchor] widgets. |
| final SearchViewThemeData data; |
| |
| /// Returns the configuration [data] from the closest [SearchViewTheme] ancestor. |
| /// If there is no ancestor, it returns [ThemeData.searchViewTheme]. |
| /// |
| /// Typical usage is as follows: |
| /// |
| /// ```dart |
| /// SearchViewThemeData theme = SearchViewTheme.of(context); |
| /// ``` |
| static SearchViewThemeData of(BuildContext context) { |
| final SearchViewTheme? searchViewTheme = context.dependOnInheritedWidgetOfExactType<SearchViewTheme>(); |
| return searchViewTheme?.data ?? Theme.of(context).searchViewTheme; |
| } |
| |
| @override |
| bool updateShouldNotify(SearchViewTheme oldWidget) => data != oldWidget.data; |
| } |