| // 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 'menu_anchor.dart'; |
| import 'menu_style.dart'; |
| import 'theme.dart'; |
| |
| // Examples can assume: |
| // late Widget child; |
| |
| /// Defines the configuration of the submenus created by the [SubmenuButton], |
| /// [MenuBar], or [MenuAnchor] widgets. |
| /// |
| /// Descendant widgets obtain the current [MenuThemeData] object using |
| /// `MenuTheme.of(context)`. |
| /// |
| /// Typically, a [MenuThemeData] is specified as part of the overall [Theme] |
| /// with [ThemeData.menuTheme]. Otherwise, [MenuTheme] can be used to configure |
| /// its own widget subtree. |
| /// |
| /// All [MenuThemeData] properties are `null` by default. If any of these |
| /// properties are null, the menu bar will provide its own defaults. |
| /// |
| /// See also: |
| /// |
| /// * [ThemeData], which describes the overall theme for the application. |
| /// * [MenuBarThemeData], which describes the theme for the menu bar itself in a |
| /// [MenuBar] widget. |
| @immutable |
| class MenuThemeData with Diagnosticable { |
| /// Creates a const set of properties used to configure [MenuTheme]. |
| const MenuThemeData({this.style}); |
| |
| /// The [MenuStyle] of a [SubmenuButton] menu. |
| /// |
| /// Any values not set in the [MenuStyle] will use the menu default for that |
| /// property. |
| final MenuStyle? style; |
| |
| /// Linearly interpolate between two menu button themes. |
| static MenuThemeData? lerp(MenuThemeData? a, MenuThemeData? b, double t) { |
| if (identical(a, b)) { |
| return a; |
| } |
| return MenuThemeData(style: MenuStyle.lerp(a?.style, b?.style, t)); |
| } |
| |
| @override |
| int get hashCode => style.hashCode; |
| |
| @override |
| bool operator ==(Object other) { |
| if (identical(this, other)) { |
| return true; |
| } |
| if (other.runtimeType != runtimeType) { |
| return false; |
| } |
| return other is MenuThemeData && other.style == style; |
| } |
| |
| @override |
| void debugFillProperties(DiagnosticPropertiesBuilder properties) { |
| super.debugFillProperties(properties); |
| properties.add(DiagnosticsProperty<MenuStyle>('style', style, defaultValue: null)); |
| } |
| } |
| |
| /// An inherited widget that defines the configuration in this widget's |
| /// descendants for menus created by the [SubmenuButton], [MenuBar], or |
| /// [MenuAnchor] widgets. |
| /// |
| /// Values specified here are used for [SubmenuButton]'s menu properties that |
| /// are not given an explicit non-null value. |
| /// |
| /// See also: |
| /// |
| /// * [MenuThemeData], a configuration object that holds attributes of a menu |
| /// used by this theme. |
| /// * [MenuBarTheme], which does the same thing for the [MenuBar] widget. |
| /// * [MenuBar], a widget that manages [MenuItemButton]s. |
| /// * [MenuAnchor], a widget that creates a region that has a submenu. |
| /// * [MenuItemButton], a widget that is a selectable item in a menu bar menu. |
| /// * [SubmenuButton], a widget that specifies an item with a cascading submenu |
| /// in a [MenuBar] menu. |
| class MenuTheme extends InheritedTheme { |
| /// Creates a const theme that controls the configurations for the menus |
| /// created by the [SubmenuButton] or [MenuAnchor] widgets. |
| const MenuTheme({ |
| super.key, |
| required this.data, |
| required super.child, |
| }); |
| |
| /// The properties for [MenuBar] and [MenuItemButton] in this widget's |
| /// descendants. |
| final MenuThemeData data; |
| |
| /// Returns the closest instance of this class's [data] value that encloses |
| /// the given context. If there is no ancestor, it returns |
| /// [ThemeData.menuTheme]. |
| /// |
| /// Typical usage is as follows: |
| /// |
| /// ```dart |
| /// Widget build(BuildContext context) { |
| /// return MenuTheme( |
| /// data: const MenuThemeData( |
| /// style: MenuStyle( |
| /// backgroundColor: MaterialStatePropertyAll<Color>(Colors.red), |
| /// ), |
| /// ), |
| /// child: child, |
| /// ); |
| /// } |
| /// ``` |
| static MenuThemeData of(BuildContext context) { |
| final MenuTheme? menuTheme = context.dependOnInheritedWidgetOfExactType<MenuTheme>(); |
| return menuTheme?.data ?? Theme.of(context).menuTheme; |
| } |
| |
| @override |
| Widget wrap(BuildContext context, Widget child) { |
| return MenuTheme(data: data, child: child); |
| } |
| |
| @override |
| bool updateShouldNotify(MenuTheme oldWidget) => data != oldWidget.data; |
| } |