dialog.dart 4.01 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
import 'package:flutter/widgets.dart';
8

9
import 'button.dart';
10 11
import 'colors.dart';
import 'material.dart';
12
import 'theme.dart';
13

14
typedef Widget DialogBuilder(NavigatorState navigator);
15

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

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

33 34 35 36
  // 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;

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

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

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

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

57
  Widget build(BuildContext context) {
58

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

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

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

87
    if (actions != null) {
88 89 90
      dialogBody.add(new ButtonTheme(
        color: ButtonColor.accent,
        child: new Container(
91 92
          child: new Row(
            children: actions,
93 94
            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
            color: _getColor(context),
            type: MaterialType.card,
            child: new IntrinsicWidth(
109
              child: new Block(children: 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
  Widget buildPage(BuildContext context, Animation<double> animation, Animation<double> forwardAnimation) {
131 132
    return child;
  }
133

134
  Widget buildTransitions(BuildContext context, Animation<double> animation, Animation<double> forwardAnimation, Widget child) {
135 136 137 138 139
    return new FadeTransition(
      opacity: new CurvedAnimation(
        parent: animation,
        curve: Curves.easeOut
      ),
140 141
      child: child
    );
142 143 144
  }
}

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