interface_level.dart 4.36 KB
Newer Older
Ian Hickson's avatar
Ian Hickson committed
1
// Copyright 2014 The Flutter Authors. All rights reserved.
2 3 4
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

5 6
import 'package:flutter/foundation.dart';

7 8 9 10 11 12 13
import '../widgets/framework.dart';

/// Indicates the visual level for a piece of content. Equivalent to `UIUserInterfaceLevel`
/// from `UIKit`.
///
/// See also:
///
14
///  * `UIUserInterfaceLevel`, the UIKit equivalent: https://developer.apple.com/documentation/uikit/uiuserinterfacelevel.
15 16 17 18 19 20 21 22 23
enum CupertinoUserInterfaceLevelData {
  /// The level for your window's main content.
  base,

  /// The level for content visually above [base].
  elevated,
}

/// Establishes a subtree in which [CupertinoUserInterfaceLevel.of] resolves to
24 25
/// the given visual elevation from the [CupertinoUserInterfaceLevelData]. This
/// can be used to apply style differences based on a widget's elevation.
26 27
///
/// Querying the current elevation status using [CupertinoUserInterfaceLevel.of]
28 29
/// will cause your widget to rebuild automatically whenever the
/// [CupertinoUserInterfaceLevelData] changes.
30
///
31 32 33 34 35
/// If no [CupertinoUserInterfaceLevel] is in scope then the
/// [CupertinoUserInterfaceLevel.of] method will throw an exception.
/// Alternatively, [CupertinoUserInterfaceLevel.maybeOf] can be used, which
/// returns null instead of throwing if no [CupertinoUserInterfaceLevel] is in
/// scope.
36 37 38
///
/// See also:
///
39 40
///  * [CupertinoUserInterfaceLevelData], specifies the visual level for the content
///    in the subtree [CupertinoUserInterfaceLevel] established.
41 42 43 44
class CupertinoUserInterfaceLevel extends InheritedWidget {
  /// Creates a [CupertinoUserInterfaceLevel] to change descendant Cupertino widget's
  /// visual level.
  const CupertinoUserInterfaceLevel({
45
    super.key,
46
    required CupertinoUserInterfaceLevelData data,
47
    required super.child,
48
  }) : _data = data;
49 50 51 52 53 54 55 56 57 58 59 60

  final CupertinoUserInterfaceLevelData _data;

  @override
  bool updateShouldNotify(CupertinoUserInterfaceLevel oldWidget) => oldWidget._data != _data;

  /// The data from the closest instance of this class that encloses the given
  /// context.
  ///
  /// You can use this function to query the user interface elevation level within
  /// the given [BuildContext]. When that information changes, your widget will
  /// be scheduled to be rebuilt, keeping your widget up-to-date.
61 62 63 64 65 66
  ///
  /// See also:
  ///
  ///  * [maybeOf], which is similar, but will return null if no
  ///    [CupertinoUserInterfaceLevel] encloses the given context.
  static CupertinoUserInterfaceLevelData of(BuildContext context) {
67
    final CupertinoUserInterfaceLevel? query = context.dependOnInheritedWidgetOfExactType<CupertinoUserInterfaceLevel>();
68
    if (query != null) {
69
      return query._data;
70
    }
71 72 73 74 75 76 77
    throw FlutterError(
      'CupertinoUserInterfaceLevel.of() called with a context that does not contain a CupertinoUserInterfaceLevel.\n'
      'No CupertinoUserInterfaceLevel ancestor could be found starting from the context that was passed '
      'to CupertinoUserInterfaceLevel.of(). This can happen because you do not have a WidgetsApp or '
      'MaterialApp widget (those widgets introduce a CupertinoUserInterfaceLevel), or it can happen '
      'if the context you use comes from a widget above those widgets.\n'
      'The context used was:\n'
78
      '  $context',
79 80
    );
  }
81

82 83 84 85 86 87 88 89 90 91 92 93 94 95 96
  /// The data from the closest instance of this class that encloses the given
  /// context, if there is one.
  ///
  /// Returns null if no [CupertinoUserInterfaceLevel] encloses the given context.
  ///
  /// You can use this function to query the user interface elevation level within
  /// the given [BuildContext]. When that information changes, your widget will
  /// be scheduled to be rebuilt, keeping your widget up-to-date.
  ///
  /// See also:
  ///
  ///  * [of], which is similar, but will throw an exception if no
  ///    [CupertinoUserInterfaceLevel] encloses the given context.
  static CupertinoUserInterfaceLevelData? maybeOf(BuildContext context) {
    final CupertinoUserInterfaceLevel? query = context.dependOnInheritedWidgetOfExactType<CupertinoUserInterfaceLevel>();
97
    if (query != null) {
98
      return query._data;
99
    }
100 101 102
    return null;
  }

103 104 105 106 107
  @override
  void debugFillProperties(DiagnosticPropertiesBuilder properties) {
    super.debugFillProperties(properties);
    properties.add(EnumProperty<CupertinoUserInterfaceLevelData>('user interface level', _data));
  }
108
}