// 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. import 'dart:math' as math; import 'package:flutter/gestures.dart'; import 'package:flutter/material.dart'; 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); } ); } class GalleryDrawerHeader extends StatefulWidget { const GalleryDrawerHeader({ Key key, this.light }) : super(key: key); final bool light; @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, textColor: config.light ? const Color(0xFF616161) : const Color(0xFF9E9E9E), ), 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)]; }); } ) ); } } class GalleryDrawer extends StatelessWidget { GalleryDrawer({ Key key, this.useLightTheme, this.onThemeChanged, this.timeDilation, this.onTimeDilationChanged, this.showPerformanceOverlay, this.onShowPerformanceOverlayChanged, this.checkerboardRasterCacheImages, this.onCheckerboardRasterCacheImagesChanged, this.onPlatformChanged, }) : super(key: key) { assert(onThemeChanged != null); assert(onTimeDilationChanged != null); } final bool useLightTheme; final ValueChanged<bool> onThemeChanged; final double timeDilation; final ValueChanged<double> onTimeDilationChanged; final bool showPerformanceOverlay; final ValueChanged<bool> onShowPerformanceOverlayChanged; final bool checkerboardRasterCacheImages; final ValueChanged<bool> onCheckerboardRasterCacheImagesChanged; final ValueChanged<TargetPlatform> onPlatformChanged; @override Widget build(BuildContext context) { final ThemeData themeData = Theme.of(context); final TextStyle aboutTextStyle = themeData.textTheme.body2; final TextStyle linkStyle = themeData.textTheme.body2.copyWith(color: themeData.accentColor); final Widget lightThemeItem = new DrawerItem( icon: new Icon(Icons.brightness_5), onPressed: () { onThemeChanged(true); }, selected: useLightTheme, child: new Row( children: <Widget>[ 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 ) ] ) ); 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, ) ] ) ); 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), onPressed: () { UrlLauncher.launch('https://github.com/flutter/flutter/issues/new'); }, child: new Text('File an issue') ); 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: "." ) ] ) ) ) ] ); final List<Widget> allDrawerItems = <Widget>[ new GalleryDrawerHeader(light: useLightTheme), lightThemeItem, darkThemeItem, new Divider(), mountainViewItem, cupertinoItem, new Divider(), animateSlowlyItem, // index 8, optional: Performance Overlay fileAnIssueItem, aboutItem ]; if (onShowPerformanceOverlayChanged != null) { allDrawerItems.insert(8, new DrawerItem( 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); } ) ] ) )); } if (onCheckerboardRasterCacheImagesChanged != null) { allDrawerItems.insert(8, new DrawerItem( icon: new Icon(Icons.assessment), onPressed: () { onCheckerboardRasterCacheImagesChanged(!checkerboardRasterCacheImages); }, selected: checkerboardRasterCacheImages, child: new Row( children: <Widget>[ new Flexible(child: new Text('Checkerboard Raster Cache Images')), new Checkbox( value: checkerboardRasterCacheImages, onChanged: (bool value) { onCheckerboardRasterCacheImagesChanged(!checkerboardRasterCacheImages); } ) ] ) )); } return new Drawer(child: new Block(children: allDrawerItems)); } }