| // Copyright 2017 The Chromium 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:math' as math; |
| |
| import 'package:flutter/foundation.dart'; |
| |
| import 'basic.dart'; |
| import 'debug.dart'; |
| import 'framework.dart'; |
| import 'media_query.dart'; |
| |
| /// A widget that insets its child by sufficient padding to avoid intrusions by |
| /// the operating system. |
| /// |
| /// For example, this will indent the child by enough to avoid the status bar at |
| /// the top of the screen. |
| /// |
| /// It will also indent the child by the amount necessary to avoid The Notch on |
| /// the iPhone X, or other similar creative physical features of the display. |
| /// |
| /// When a [minimum] padding is specified, the greater of the minimum padding |
| /// or the safe area padding will be applied. |
| /// |
| /// See also: |
| /// |
| /// * [SliverSafeArea], for insetting slivers to avoid operating system |
| /// intrusions. |
| /// * [Padding], for insetting widgets in general. |
| /// * [MediaQuery], from which the window padding is obtained. |
| /// * [dart:ui.Window.padding], which reports the padding from the operating |
| /// system. |
| class SafeArea extends StatelessWidget { |
| /// Creates a widget that avoids operating system interfaces. |
| /// |
| /// The [left], [top], [right], [bottom], and [minimum] arguments must not be |
| /// null. |
| const SafeArea({ |
| Key key, |
| this.left: true, |
| this.top: true, |
| this.right: true, |
| this.bottom: true, |
| this.minimum: EdgeInsets.zero, |
| @required this.child, |
| }) : assert(left != null), |
| assert(top != null), |
| assert(right != null), |
| assert(bottom != null), |
| super(key: key); |
| |
| /// Whether to avoid system intrusions on the left. |
| final bool left; |
| |
| /// Whether to avoid system intrusions at the top of the screen, typically the |
| /// system status bar. |
| final bool top; |
| |
| /// Whether to avoid system intrusions on the right. |
| final bool right; |
| |
| /// Whether to avoid system intrusions on the bottom side of the screen. |
| final bool bottom; |
| |
| /// This minimum padding to apply. |
| /// |
| /// The greater of the minimum insets and the media padding will be applied. |
| final EdgeInsets minimum; |
| |
| /// The widget below this widget in the tree. |
| /// |
| /// The padding on the [MediaQuery] for the [child] will be suitably adjusted |
| /// to zero out any sides that were avoided by this widget. |
| /// |
| /// {@macro flutter.widgets.child} |
| final Widget child; |
| |
| @override |
| Widget build(BuildContext context) { |
| assert(debugCheckHasMediaQuery(context)); |
| final EdgeInsets padding = MediaQuery.of(context).padding; |
| return new Padding( |
| padding: new EdgeInsets.only( |
| left: math.max(left ? padding.left : 0.0, minimum.left), |
| top: math.max(top ? padding.top : 0.0, minimum.top), |
| right: math.max(right ? padding.right : 0.0, minimum.right), |
| bottom: math.max(bottom ? padding.bottom : 0.0, minimum.bottom), |
| ), |
| child: new MediaQuery.removePadding( |
| context: context, |
| removeLeft: left, |
| removeTop: top, |
| removeRight: right, |
| removeBottom: bottom, |
| child: child, |
| ), |
| ); |
| } |
| |
| @override |
| void debugFillProperties(DiagnosticPropertiesBuilder properties) { |
| super.debugFillProperties(properties); |
| properties.add(new FlagProperty('left', value: left, ifTrue: 'avoid left padding')); |
| properties.add(new FlagProperty('top', value: left, ifTrue: 'avoid top padding')); |
| properties.add(new FlagProperty('right', value: left, ifTrue: 'avoid right padding')); |
| properties.add(new FlagProperty('bottom', value: left, ifTrue: 'avoid bottom padding')); |
| } |
| } |
| |
| /// A sliver that insets another sliver by sufficient padding to avoid |
| /// intrusions by the operating system. |
| /// |
| /// For example, this will indent the sliver by enough to avoid the status bar |
| /// at the top of the screen. |
| /// |
| /// It will also indent the sliver by the amount necessary to avoid The Notch |
| /// on the iPhone X, or other similar creative physical features of the |
| /// display. |
| /// |
| /// When a [minimum] padding is specified, the greater of the minimum padding |
| /// or the safe area padding will be applied. |
| /// |
| /// See also: |
| /// |
| /// * [SafeArea], for insetting widgets to avoid operating system intrusions. |
| /// * [SliverPadding], for insetting slivers in general. |
| /// * [MediaQuery], from which the window padding is obtained. |
| /// * [dart:ui.Window.padding], which reports the padding from the operating |
| /// system. |
| class SliverSafeArea extends StatelessWidget { |
| /// Creates a sliver that avoids operating system interfaces. |
| /// |
| /// The [left], [top], [right], [bottom], and [minimum] arguments must not be null. |
| const SliverSafeArea({ |
| Key key, |
| this.left: true, |
| this.top: true, |
| this.right: true, |
| this.bottom: true, |
| this.minimum: EdgeInsets.zero, |
| @required this.sliver, |
| }) : assert(left != null), |
| assert(top != null), |
| assert(right != null), |
| assert(bottom != null), |
| super(key: key); |
| |
| /// Whether to avoid system intrusions on the left. |
| final bool left; |
| |
| /// Whether to avoid system intrusions at the top of the screen, typically the |
| /// system status bar. |
| final bool top; |
| |
| /// Whether to avoid system intrusions on the right. |
| final bool right; |
| |
| /// Whether to avoid system intrusions on the bottom side of the screen. |
| final bool bottom; |
| |
| /// This minimum padding to apply. |
| /// |
| /// The greater of the minimum padding and the media padding is be applied. |
| final EdgeInsets minimum; |
| |
| /// The sliver below this sliver in the tree. |
| /// |
| /// The padding on the [MediaQuery] for the [sliver] will be suitably adjusted |
| /// to zero out any sides that were avoided by this sliver. |
| final Widget sliver; |
| |
| @override |
| Widget build(BuildContext context) { |
| assert(debugCheckHasMediaQuery(context)); |
| final EdgeInsets padding = MediaQuery.of(context).padding; |
| return new SliverPadding( |
| padding: new EdgeInsets.only( |
| left: math.max(left ? padding.left : 0.0, minimum.left), |
| top: math.max(top ? padding.top : 0.0, minimum.top), |
| right: math.max(right ? padding.right : 0.0, minimum.right), |
| bottom: math.max(bottom ? padding.bottom : 0.0, minimum.bottom), |
| ), |
| sliver: new MediaQuery.removePadding( |
| context: context, |
| removeLeft: left, |
| removeTop: top, |
| removeRight: right, |
| removeBottom: bottom, |
| child: sliver, |
| ), |
| ); |
| } |
| |
| @override |
| void debugFillProperties(DiagnosticPropertiesBuilder properties) { |
| super.debugFillProperties(properties); |
| properties.add(new FlagProperty('left', value: left, ifTrue: 'avoid left padding')); |
| properties.add(new FlagProperty('top', value: left, ifTrue: 'avoid top padding')); |
| properties.add(new FlagProperty('right', value: left, ifTrue: 'avoid right padding')); |
| properties.add(new FlagProperty('bottom', value: left, ifTrue: 'avoid bottom padding')); |
| } |
| } |