drawer.dart 9.42 KB
Newer Older
1 2 3 4
// Copyright 2016 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:math' as math;

7
import 'package:flutter/gestures.dart';
8
import 'package:flutter/material.dart';
9 10 11 12 13 14 15 16 17 18 19
import 'package:flutter/services.dart';

class LinkTextSpan extends TextSpan {
  LinkTextSpan({ TextStyle style, String url, String text }) : super(
    style: style,
    text: text ?? url,
    recognizer: new TapGestureRecognizer()..onTap = () {
      UrlLauncher.launch(url);
    }
  );
}
20

21
class GalleryDrawerHeader extends StatefulWidget {
22 23 24
  const GalleryDrawerHeader({ Key key, this.light }) : super(key: key);

  final bool light;
25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45

  @override
  _GalleryDrawerHeaderState createState() => new _GalleryDrawerHeaderState();
}

class _GalleryDrawerHeaderState extends State<GalleryDrawerHeader> {
  bool _logoHasName = true;
  bool _logoHorizontal = true;
  Map<int, Color> _swatch = Colors.blue;

  @override
  Widget build(BuildContext context) {
    final double systemTopPadding = MediaQuery.of(context).padding.top;

    return new DrawerHeader(
      decoration: new FlutterLogoDecoration(
        margin: new EdgeInsets.fromLTRB(12.0, 12.0 + systemTopPadding, 12.0, 12.0),
        style: _logoHasName ? _logoHorizontal ? FlutterLogoStyle.horizontal
                                              : FlutterLogoStyle.stacked
                                              : FlutterLogoStyle.markOnly,
        swatch: _swatch,
46
        textColor: config.light ? const Color(0xFF616161) : const Color(0xFF9E9E9E),
47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86
      ),
      duration: const Duration(milliseconds: 750),
      child: new GestureDetector(
        onLongPress: () {
          setState(() {
            _logoHorizontal = !_logoHorizontal;
            if (!_logoHasName)
              _logoHasName = true;
          });
        },
        onTap: () {
          setState(() {
            _logoHasName = !_logoHasName;
          });
        },
        onDoubleTap: () {
          setState(() {
            final List<Map<int, Color>> options = <Map<int, Color>>[];
            if (_swatch != Colors.blue)
              options.addAll(<Map<int, Color>>[Colors.blue, Colors.blue, Colors.blue, Colors.blue, Colors.blue, Colors.blue, Colors.blue]);
            if (_swatch != Colors.amber)
              options.addAll(<Map<int, Color>>[Colors.amber, Colors.amber, Colors.amber]);
            if (_swatch != Colors.red)
              options.addAll(<Map<int, Color>>[Colors.red, Colors.red, Colors.red]);
            if (_swatch != Colors.indigo)
              options.addAll(<Map<int, Color>>[Colors.indigo, Colors.indigo, Colors.indigo]);
            if (_swatch != Colors.pink)
              options.addAll(<Map<int, Color>>[Colors.pink]);
            if (_swatch != Colors.purple)
              options.addAll(<Map<int, Color>>[Colors.purple]);
            if (_swatch != Colors.cyan)
              options.addAll(<Map<int, Color>>[Colors.cyan]);
            _swatch = options[new math.Random().nextInt(options.length)];
          });
        }
      )
    );
  }
}

87
class GalleryDrawer extends StatelessWidget {
88 89
  GalleryDrawer({
    Key key,
Eric Seidel's avatar
Eric Seidel committed
90
    this.useLightTheme,
91 92
    this.onThemeChanged,
    this.timeDilation,
Eric Seidel's avatar
Eric Seidel committed
93 94
    this.onTimeDilationChanged,
    this.showPerformanceOverlay,
95 96
    this.onShowPerformanceOverlayChanged,
    this.onPlatformChanged,
97 98 99
  }) : super(key: key) {
    assert(onThemeChanged != null);
    assert(onTimeDilationChanged != null);
100 101
  }

Eric Seidel's avatar
Eric Seidel committed
102
  final bool useLightTheme;
103 104 105 106
  final ValueChanged<bool> onThemeChanged;

  final double timeDilation;
  final ValueChanged<double> onTimeDilationChanged;
107

Eric Seidel's avatar
Eric Seidel committed
108 109 110
  final bool showPerformanceOverlay;
  final ValueChanged<bool> onShowPerformanceOverlayChanged;

111 112
  final ValueChanged<TargetPlatform> onPlatformChanged;

113
  @override
114
  Widget build(BuildContext context) {
115 116
    final ThemeData themeData = Theme.of(context);
    final TextStyle aboutTextStyle = themeData.textTheme.body2;
117
    final TextStyle linkStyle = themeData.textTheme.body2.copyWith(color: themeData.accentColor);
118

119 120 121 122 123
    final Widget lightThemeItem = new DrawerItem(
      icon: new Icon(Icons.brightness_5),
      onPressed: () { onThemeChanged(true); },
      selected: useLightTheme,
      child: new Row(
124
        children: <Widget>[
125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150
          new Flexible(child: new Text('Light')),
          new Radio<bool>(
            value: true,
            groupValue: useLightTheme,
            onChanged: onThemeChanged
          )
        ]
      )
    );

    final Widget darkThemeItem = new DrawerItem(
      icon: new Icon(Icons.brightness_7),
      onPressed: () { onThemeChanged(false); },
      selected: useLightTheme,
      child: new Row(
        children: <Widget>[
          new Flexible(child: new Text('Dark')),
          new Radio<bool>(
            value: false,
            groupValue: useLightTheme,
            onChanged: onThemeChanged
          )
        ]
      )
    );

151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184
    final Widget mountainViewItem = new DrawerItem(
      // on iOS, we don't want to show an Android phone icon
      icon: new Icon(defaultTargetPlatform == TargetPlatform.iOS ? Icons.star : Icons.phone_android),
      onPressed: () { onPlatformChanged(TargetPlatform.android); },
      selected: Theme.of(context).platform == TargetPlatform.android,
      child: new Row(
        children: <Widget>[
          new Flexible(child: new Text('Android')),
          new Radio<TargetPlatform>(
            value: TargetPlatform.android,
            groupValue: Theme.of(context).platform,
            onChanged: onPlatformChanged,
          )
        ]
      )
    );

    final Widget cupertinoItem = new DrawerItem(
      // on iOS, we don't want to show the iPhone icon
      icon: new Icon(defaultTargetPlatform == TargetPlatform.iOS ? Icons.star_border : Icons.phone_iphone),
      onPressed: () { onPlatformChanged(TargetPlatform.iOS); },
      selected: Theme.of(context).platform == TargetPlatform.iOS,
      child: new Row(
        children: <Widget>[
          new Flexible(child: new Text('iOS')),
          new Radio<TargetPlatform>(
            value: TargetPlatform.iOS,
            groupValue: Theme.of(context).platform,
            onChanged: onPlatformChanged,
          )
        ]
      )
    );

185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201
    final Widget animateSlowlyItem = new DrawerItem(
      icon: new Icon(Icons.hourglass_empty),
      selected: timeDilation != 1.0,
      onPressed: () { onTimeDilationChanged(timeDilation != 1.0 ? 1.0 : 20.0); },
      child: new Row(
        children: <Widget>[
          new Flexible(child: new Text('Animate Slowly')),
          new Checkbox(
            value: timeDilation != 1.0,
            onChanged: (bool value) { onTimeDilationChanged(value ? 20.0 : 1.0); }
          )
        ]
      )
    );

    final Widget fileAnIssueItem = new DrawerItem(
      icon: new Icon(Icons.report),
202 203 204 205
      onPressed: () {
        UrlLauncher.launch('https://github.com/flutter/flutter/issues/new');
      },
      child: new Text('File an issue')
206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242
    );

    final Widget aboutItem = new AboutDrawerItem(
      icon: new FlutterLogo(),
      applicationVersion: '2016 Q3 Preview',
      applicationIcon: new FlutterLogo(),
      applicationLegalese: '© 2016 The Chromium Authors',
      aboutBoxChildren: <Widget>[
        new Padding(
          padding: const EdgeInsets.only(top: 24.0),
          child: new RichText(
            text: new TextSpan(
              children: <TextSpan>[
                new TextSpan(
                  style: aboutTextStyle,
                  text: "Flutter is an early-stage, open-source project to help "
                  "developers build high-performance, high-fidelity, mobile "
                  "apps for iOS and Android from a single codebase. This "
                  "gallery is a preview of Flutter's many widgets, behaviors, "
                  "animations, layouts, and more. Learn more about Flutter at "
                ),
                new LinkTextSpan(
                  style: linkStyle,
                  url: 'https://flutter.io'
                ),
                new TextSpan(
                  style: aboutTextStyle,
                  text: ".\n\nTo see the source code for this app, please visit the "
                ),
                new LinkTextSpan(
                  style: linkStyle,
                  url: 'https://goo.gl/iv1p4G',
                  text: 'flutter github repo'
                ),
                new TextSpan(
                  style: aboutTextStyle,
                  text: "."
Eric Seidel's avatar
Eric Seidel committed
243 244 245
                )
              ]
            )
246
          )
247 248
        )
      ]
249
    );
250 251 252 253 254 255

    final List<Widget> allDrawerItems = <Widget>[
      new GalleryDrawerHeader(light: useLightTheme),
      lightThemeItem,
      darkThemeItem,
      new Divider(),
256 257 258
      mountainViewItem,
      cupertinoItem,
      new Divider(),
259
      animateSlowlyItem,
260
      // index 8, optional: Performance Overlay
261 262 263 264 265
      fileAnIssueItem,
      aboutItem
    ];

    if (onShowPerformanceOverlayChanged != null) {
266
      allDrawerItems.insert(8, new DrawerItem(
267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282
        icon: new Icon(Icons.assessment),
        onPressed: () { onShowPerformanceOverlayChanged(!showPerformanceOverlay); },
        selected: showPerformanceOverlay,
        child: new Row(
          children: <Widget>[
            new Flexible(child: new Text('Performance Overlay')),
            new Checkbox(
              value: showPerformanceOverlay,
              onChanged: (bool value) { onShowPerformanceOverlayChanged(!showPerformanceOverlay); }
            )
          ]
        )
      ));
    }

    return new Drawer(child: new Block(children: allDrawerItems));
283 284
  }
}