mirror of
https://github.com/flutter/flutter.git
synced 2026-02-20 02:29:02 +08:00
140 lines
5.0 KiB
Dart
140 lines
5.0 KiB
Dart
// 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 'button_style.dart';
|
|
import 'material_state.dart';
|
|
import 'menu_anchor.dart';
|
|
import 'theme.dart';
|
|
|
|
// Examples can assume:
|
|
// late BuildContext context;
|
|
|
|
/// A [ButtonStyle] theme that overrides the default appearance of
|
|
/// [SubmenuButton]s and [MenuItemButton]s when it's used with a
|
|
/// [MenuButtonTheme] or with the overall [Theme]'s [ThemeData.menuTheme].
|
|
///
|
|
/// The [style]'s properties override [MenuItemButton]'s and [SubmenuButton]'s
|
|
/// default style, i.e. the [ButtonStyle] returned by
|
|
/// [MenuItemButton.defaultStyleOf] and [SubmenuButton.defaultStyleOf]. Only the
|
|
/// style's non-null property values or resolved non-null
|
|
/// [MaterialStateProperty] values are used.
|
|
///
|
|
/// See also:
|
|
///
|
|
/// * [MenuButtonTheme], the theme which is configured with this class.
|
|
/// * [MenuTheme], the theme used to configure the look of the menus these
|
|
/// buttons reside in.
|
|
/// * [MenuItemButton.defaultStyleOf] and [SubmenuButton.defaultStyleOf] which
|
|
/// return the default [ButtonStyle]s for menu buttons.
|
|
/// * [MenuItemButton.styleFrom] and [SubmenuButton.styleFrom], which converts
|
|
/// simple values into a [ButtonStyle] that's consistent with their respective
|
|
/// defaults.
|
|
/// * [MaterialStateProperty.resolve], "resolve" a material state property to a
|
|
/// simple value based on a set of [MaterialState]s.
|
|
/// * [ThemeData.menuButtonTheme], which can be used to override the default
|
|
/// [ButtonStyle] for [MenuItemButton]s and [SubmenuButton]s below the overall
|
|
/// [Theme].
|
|
/// * [MenuAnchor], a widget which hosts cascading menus.
|
|
/// * [MenuBar], a widget which defines a menu bar of buttons hosting cascading
|
|
/// menus.
|
|
@immutable
|
|
class MenuButtonThemeData with Diagnosticable {
|
|
/// Creates a [MenuButtonThemeData].
|
|
///
|
|
/// The [style] may be null.
|
|
const MenuButtonThemeData({this.style});
|
|
|
|
/// Overrides for [SubmenuButton] and [MenuItemButton]'s default style.
|
|
///
|
|
/// Non-null properties or non-null resolved [MaterialStateProperty] values
|
|
/// override the [ButtonStyle] returned by [SubmenuButton.defaultStyleOf] or
|
|
/// [MenuItemButton.defaultStyleOf].
|
|
///
|
|
/// If [style] is null, then this theme doesn't override anything.
|
|
final ButtonStyle? style;
|
|
|
|
/// Linearly interpolate between two menu button themes.
|
|
static MenuButtonThemeData? lerp(MenuButtonThemeData? a, MenuButtonThemeData? b, double t) {
|
|
if (identical(a, b)) {
|
|
return a;
|
|
}
|
|
return MenuButtonThemeData(style: ButtonStyle.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 MenuButtonThemeData && other.style == style;
|
|
}
|
|
|
|
@override
|
|
void debugFillProperties(DiagnosticPropertiesBuilder properties) {
|
|
super.debugFillProperties(properties);
|
|
properties.add(DiagnosticsProperty<ButtonStyle>('style', style, defaultValue: null));
|
|
}
|
|
}
|
|
|
|
/// Overrides the default [ButtonStyle] of its [MenuItemButton] and
|
|
/// [SubmenuButton] descendants.
|
|
///
|
|
/// See also:
|
|
///
|
|
/// * [MenuButtonThemeData], which is used to configure this theme.
|
|
/// * [MenuTheme], the theme used to configure the look of the menus themselves.
|
|
/// * [MenuItemButton.defaultStyleOf] and [SubmenuButton.defaultStyleOf] which
|
|
/// return the default [ButtonStyle]s for menu buttons.
|
|
/// * [MenuItemButton.styleFrom] and [SubmenuButton.styleFrom], which converts
|
|
/// simple values into a [ButtonStyle] that's consistent with their respective
|
|
/// defaults.
|
|
/// * [ThemeData.menuButtonTheme], which can be used to override the default
|
|
/// [ButtonStyle] for [MenuItemButton]s and [SubmenuButton]s below the overall
|
|
/// [Theme].
|
|
class MenuButtonTheme extends InheritedTheme {
|
|
/// Create a [MenuButtonTheme].
|
|
///
|
|
/// The [data] parameter must not be null.
|
|
const MenuButtonTheme({
|
|
super.key,
|
|
required this.data,
|
|
required super.child,
|
|
});
|
|
|
|
/// The configuration of this theme.
|
|
final MenuButtonThemeData data;
|
|
|
|
/// The closest instance of this class that encloses the given context.
|
|
///
|
|
/// If there is no enclosing [MenuButtonTheme] widget, then
|
|
/// [ThemeData.menuButtonTheme] is used.
|
|
///
|
|
/// Typical usage is as follows:
|
|
///
|
|
/// ```dart
|
|
/// MenuButtonThemeData theme = MenuButtonTheme.of(context);
|
|
/// ```
|
|
static MenuButtonThemeData of(BuildContext context) {
|
|
final MenuButtonTheme? buttonTheme = context.dependOnInheritedWidgetOfExactType<MenuButtonTheme>();
|
|
return buttonTheme?.data ?? Theme.of(context).menuButtonTheme;
|
|
}
|
|
|
|
@override
|
|
Widget wrap(BuildContext context, Widget child) {
|
|
return MenuButtonTheme(data: data, child: child);
|
|
}
|
|
|
|
@override
|
|
bool updateShouldNotify(MenuButtonTheme oldWidget) => data != oldWidget.data;
|
|
}
|