dialog.dart 4.04 KB
Newer Older
1 2 3 4
// Copyright 2015 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.

5 6
import 'dart:async';

7 8
import 'package:flutter/animation.dart';
import 'package:flutter/widgets.dart';
9

10
import 'colors.dart';
11
import 'material_button.dart';
12
import 'material.dart';
13
import 'theme.dart';
14

15
typedef Widget DialogBuilder(NavigatorState navigator);
16

17 18 19
/// A material design dialog
///
/// <https://www.google.com/design/spec/components/dialogs.html>
20
class Dialog extends StatelessComponent {
21
  Dialog({
22
    Key key,
23
    this.title,
24
    this.titlePadding,
25
    this.content,
26
    this.contentPadding,
27
    this.actions
28
  }) : super(key: key);
29 30 31 32 33

  /// The (optional) title of the dialog is displayed in a large font at the top
  /// of the dialog.
  final Widget title;

34 35 36 37
  // Padding around the title; uses material design default if none is supplied
  // If there is no title, no padding will be provided
  final EdgeDims titlePadding;

38 39 40 41
  /// The (optional) content of the dialog is displayed in the center of the
  /// dialog in a lighter font.
  final Widget content;

42 43 44
  // Padding around the content; uses material design default if none is supplied
  final EdgeDims contentPadding;

45 46 47 48
  /// The (optional) set of actions that are displayed at the bottom of the
  /// dialog.
  final List<Widget> actions;

49 50
  Color _getColor(BuildContext context) {
    switch (Theme.of(context).brightness) {
51
      case ThemeBrightness.light:
52
        return Colors.white;
53
      case ThemeBrightness.dark:
54
        return Colors.grey[800];
55 56 57
    }
  }

58
  Widget build(BuildContext context) {
59

60
    List<Widget> dialogBody = new List<Widget>();
61 62

    if (title != null) {
63 64
      EdgeDims padding = titlePadding;
      if (padding == null)
65
        padding = new EdgeDims.TRBL(24.0, 24.0, content == null ? 20.0 : 0.0, 24.0);
66
      dialogBody.add(new Padding(
67
        padding: padding,
68
        child: new DefaultTextStyle(
69
          style: Theme.of(context).text.title,
70 71 72 73 74 75
          child: title
        )
      ));
    }

    if (content != null) {
76 77
      EdgeDims padding = contentPadding;
      if (padding == null)
78
        padding = const EdgeDims.TRBL(20.0, 24.0, 24.0, 24.0);
79
      dialogBody.add(new Padding(
80
        padding: padding,
81
        child: new DefaultTextStyle(
82
          style: Theme.of(context).text.subhead,
83 84 85 86 87
          child: content
        )
      ));
    }

88
    if (actions != null) {
89 90 91 92 93 94
      dialogBody.add(new ButtonTheme(
        color: ButtonColor.accent,
        child: new Container(
          child: new Row(actions,
            justifyContent: FlexJustifyContent.end
          )
95 96
        )
      ));
97
    }
98

99 100 101 102 103 104
    return new Center(
      child: new Container(
        margin: new EdgeDims.symmetric(horizontal: 40.0, vertical: 24.0),
        child: new ConstrainedBox(
          constraints: new BoxConstraints(minWidth: 280.0),
          child: new Material(
Hans Muller's avatar
Hans Muller committed
105
            elevation: 24,
106 107 108 109
            color: _getColor(context),
            type: MaterialType.card,
            child: new IntrinsicWidth(
              child: new Block(dialogBody)
110 111 112 113
            )
          )
        )
      )
114
    );
115 116
  }
}
117

Hixie's avatar
Hixie committed
118 119 120 121 122
class _DialogRoute<T> extends PopupRoute<T> {
  _DialogRoute({
    Completer<T> completer,
    this.child
  }) : super(completer: completer);
123

Adam Barth's avatar
Adam Barth committed
124
  final Widget child;
125

126
  Duration get transitionDuration => const Duration(milliseconds: 150);
Hixie's avatar
Hixie committed
127
  bool get barrierDismissable => true;
128 129
  Color get barrierColor => Colors.black54;

130 131 132
  Widget buildPage(BuildContext context, PerformanceView performance, PerformanceView forwardPerformance) {
    return child;
  }
133

134
  Widget buildTransitions(BuildContext context, PerformanceView performance, PerformanceView forwardPerformance, Widget child) {
135 136 137 138 139
    return new FadeTransition(
      performance: performance,
      opacity: new AnimatedValue<double>(0.0, end: 1.0, curve: Curves.easeOut),
      child: child
    );
140 141 142
  }
}

Adam Barth's avatar
Adam Barth committed
143
Future showDialog({ BuildContext context, Widget child }) {
144
  Completer completer = new Completer();
Hixie's avatar
Hixie committed
145
  Navigator.push(context, new _DialogRoute(completer: completer, child: child));
146 147
  return completer.future;
}