| // 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 'package:flutter/foundation.dart'; |
| import 'package:flutter/widgets.dart'; |
| |
| import 'action_buttons.dart'; |
| import 'theme.dart'; |
| |
| // Examples can assume: |
| // late BuildContext context; |
| |
| /// A [ActionIconThemeData] that overrides the default icons of |
| /// [BackButton], [CloseButton], [DrawerButton], and [EndDrawerButton] with |
| /// [ActionIconTheme.of] or the overall [Theme]'s [ThemeData.actionIconTheme]. |
| @immutable |
| class ActionIconThemeData with Diagnosticable { |
| /// Creates an [ActionIconThemeData]. |
| /// |
| /// The builders [backButtonIconBuilder], [closeButtonIconBuilder], |
| /// [drawerButtonIconBuilder], [endDrawerButtonIconBuilder] may be null. |
| const ActionIconThemeData({ this.backButtonIconBuilder, this.closeButtonIconBuilder, this.drawerButtonIconBuilder, this.endDrawerButtonIconBuilder }); |
| |
| /// Overrides [BackButtonIcon]'s icon. |
| /// |
| /// If [backButtonIconBuilder] is null, then [BackButtonIcon] |
| /// fallbacks to the platform's default back button icon. |
| final WidgetBuilder? backButtonIconBuilder; |
| |
| /// Overrides [CloseButtonIcon]'s icon. |
| /// |
| /// If [closeButtonIconBuilder] is null, then [CloseButtonIcon] |
| /// fallbacks to the platform's default close button icon. |
| final WidgetBuilder? closeButtonIconBuilder; |
| |
| /// Overrides [DrawerButtonIcon]'s icon. |
| /// |
| /// If [drawerButtonIconBuilder] is null, then [DrawerButtonIcon] |
| /// fallbacks to the platform's default drawer button icon. |
| final WidgetBuilder? drawerButtonIconBuilder; |
| |
| /// Overrides [EndDrawerButtonIcon]'s icon. |
| /// |
| /// If [endDrawerButtonIconBuilder] is null, then [EndDrawerButtonIcon] |
| /// fallbacks to the platform's default end drawer button icon. |
| final WidgetBuilder? endDrawerButtonIconBuilder; |
| |
| /// Creates a copy of this object but with the given fields replaced with the |
| /// new values. |
| ActionIconThemeData copyWith({ |
| WidgetBuilder? backButtonIconBuilder, |
| WidgetBuilder? closeButtonIconBuilder, |
| WidgetBuilder? drawerButtonIconBuilder, |
| WidgetBuilder? endDrawerButtonIconBuilder, |
| }) { |
| return ActionIconThemeData( |
| backButtonIconBuilder: backButtonIconBuilder ?? backButtonIconBuilder, |
| closeButtonIconBuilder: closeButtonIconBuilder ?? closeButtonIconBuilder, |
| drawerButtonIconBuilder: drawerButtonIconBuilder ?? drawerButtonIconBuilder, |
| endDrawerButtonIconBuilder: endDrawerButtonIconBuilder ?? endDrawerButtonIconBuilder, |
| ); |
| } |
| |
| /// Linearly interpolate between two action icon themes. |
| static ActionIconThemeData? lerp(ActionIconThemeData? a, ActionIconThemeData? b, double t) { |
| if (a == null && b == null) { |
| return null; |
| } |
| return ActionIconThemeData( |
| backButtonIconBuilder: t < 0.5 ? a?.backButtonIconBuilder : b?.backButtonIconBuilder, |
| closeButtonIconBuilder: t < 0.5 ? a?.closeButtonIconBuilder : b?.closeButtonIconBuilder, |
| drawerButtonIconBuilder: t < 0.5 ? a?.drawerButtonIconBuilder : b?.drawerButtonIconBuilder, |
| endDrawerButtonIconBuilder: t < 0.5 ? a?.endDrawerButtonIconBuilder : b?.endDrawerButtonIconBuilder, |
| ); |
| } |
| |
| @override |
| int get hashCode { |
| final List<Object?> values = <Object?>[ |
| backButtonIconBuilder, |
| closeButtonIconBuilder, |
| drawerButtonIconBuilder, |
| endDrawerButtonIconBuilder, |
| ]; |
| return Object.hashAll(values); |
| } |
| |
| @override |
| bool operator ==(Object other) { |
| if (identical(this, other)) { |
| return true; |
| } |
| if (other.runtimeType != runtimeType) { |
| return false; |
| } |
| return other is ActionIconThemeData |
| && other.backButtonIconBuilder == backButtonIconBuilder |
| && other.closeButtonIconBuilder == closeButtonIconBuilder |
| && other.drawerButtonIconBuilder == drawerButtonIconBuilder |
| && other.endDrawerButtonIconBuilder == endDrawerButtonIconBuilder; |
| } |
| |
| @override |
| void debugFillProperties(DiagnosticPropertiesBuilder properties) { |
| super.debugFillProperties(properties); |
| properties.add(DiagnosticsProperty<WidgetBuilder>('backButtonIconBuilder', backButtonIconBuilder, defaultValue: null)); |
| properties.add(DiagnosticsProperty<WidgetBuilder>('closeButtonIconBuilder', closeButtonIconBuilder, defaultValue: null)); |
| properties.add(DiagnosticsProperty<WidgetBuilder>('drawerButtonIconBuilder', drawerButtonIconBuilder, defaultValue: null)); |
| properties.add(DiagnosticsProperty<WidgetBuilder>('endDrawerButtonIconBuilder', endDrawerButtonIconBuilder, defaultValue: null)); |
| } |
| } |
| |
| /// An inherited widget that overrides the default icon of [BackButtonIcon], |
| /// [CloseButtonIcon], [DrawerButtonIcon], and [EndDrawerButtonIcon] in this |
| /// widget's subtree. |
| class ActionIconTheme extends InheritedTheme { |
| /// Creates a theme that overrides the default icon of [BackButtonIcon], |
| /// [CloseButtonIcon], [DrawerButtonIcon], and [EndDrawerButtonIcon] in this |
| /// widget's subtree. |
| const ActionIconTheme({ |
| super.key, |
| required this.data, |
| required super.child, |
| }); |
| |
| /// Specifies the default icon overrides for descendant [BackButtonIcon], |
| /// [CloseButtonIcon], [DrawerButtonIcon], and [EndDrawerButtonIcon] widgets. |
| final ActionIconThemeData data; |
| |
| /// The closest instance of this class that encloses the given context. |
| /// |
| /// If there is no enclosing [ActionIconTheme] widget, then |
| /// [ThemeData.actionIconTheme] is used. |
| /// |
| /// Typical usage is as follows: |
| /// |
| /// ```dart |
| /// ActionIconThemeData? theme = ActionIconTheme.of(context); |
| /// ``` |
| static ActionIconThemeData? of(BuildContext context) { |
| final ActionIconTheme? actionIconTheme = context.dependOnInheritedWidgetOfExactType<ActionIconTheme>(); |
| return actionIconTheme?.data ?? Theme.of(context).actionIconTheme; |
| } |
| |
| @override |
| Widget wrap(BuildContext context, Widget child) { |
| return ActionIconTheme(data: data, child: child); |
| } |
| |
| @override |
| bool updateShouldNotify(ActionIconTheme oldWidget) => data != oldWidget.data; |
| } |