demo.dart 4.52 KB
Newer Older
1 2 3 4 5 6
// 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 'package:flutter/material.dart';

7
import 'example_code_parser.dart';
8
import 'syntax_highlighter.dart';
9

10 11
class ComponentDemoTabData {
  ComponentDemoTabData({
12
    this.widget,
13
    this.exampleCodeTag,
14
    this.description,
15
    this.tabName
16 17 18
  });

  final Widget widget;
19
  final String exampleCodeTag;
20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50
  final String description;
  final String tabName;

  static Map<ComponentDemoTabData, TabLabel> buildTabLabels(List<ComponentDemoTabData> demos) {
    return new Map<ComponentDemoTabData, TabLabel>.fromIterable(
      demos,
      value: (ComponentDemoTabData demo) => new TabLabel(text: demo.tabName)
    );
  }

  @override
  bool operator==(Object other) {
    if (other.runtimeType != runtimeType)
      return false;
    ComponentDemoTabData typedOther = other;
    return typedOther.tabName == tabName && typedOther.description == description;
  }

  @override
  int get hashCode => hashValues(tabName.hashCode, description.hashCode);
}

class TabbedComponentDemoScaffold extends StatelessWidget {
  TabbedComponentDemoScaffold({
    this.title,
    this.demos
  });

  final List<ComponentDemoTabData> demos;
  final String title;

51 52 53 54 55 56 57 58 59 60
  void _showExampleCode(BuildContext context) {
    TabBarSelectionState<ComponentDemoTabData> selection = TabBarSelection.of(context);
    String tag = selection.value?.exampleCodeTag;
    if (tag != null) {
      Navigator.push(context, new MaterialPageRoute<FullScreenCodeDialog>(
        builder: (BuildContext context) => new FullScreenCodeDialog(exampleCodeTag: tag)
      ));
    }
  }

61 62 63 64 65 66 67
  @override
  Widget build(BuildContext context) {
    return new TabBarSelection<ComponentDemoTabData>(
      values: demos,
      child: new Scaffold(
        appBar: new AppBar(
          title: new Text(title),
68 69 70 71 72 73 74 75 76 77 78
          actions: <Widget>[
            new Builder(
              builder: (BuildContext context) {
                return new IconButton(
                  icon: new Icon(Icons.description),
                  tooltip: 'Show example code',
                  onPressed: () { _showExampleCode(context); }
                );
              }
            )
          ],
79
          bottom: new TabBar<ComponentDemoTabData>(
80 81 82 83
            isScrollable: true,
            labels: ComponentDemoTabData.buildTabLabels(demos)
          )
        ),
84 85 86 87 88 89
        body: new TabBarView<ComponentDemoTabData>(
          children: demos.map((ComponentDemoTabData demo) {
            return new Column(
              children: <Widget>[
                new Padding(
                  padding: const EdgeInsets.all(16.0),
90 91 92
                  child: new Text(demo.description,
                    style: Theme.of(context).textTheme.subhead
                  )
93
                ),
94 95 96 97
                new Flexible(child: demo.widget)
              ]
            );
          }).toList()
98
        )
99
      )
100 101 102 103
    );
  }
}

104 105 106 107 108 109 110 111 112 113
class FullScreenCodeDialog extends StatefulWidget {
  FullScreenCodeDialog({ this.exampleCodeTag });

  final String exampleCodeTag;

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

class FullScreenCodeDialogState extends State<FullScreenCodeDialog> {
114

115 116 117 118 119 120 121 122 123 124 125 126
  String _exampleCode;

  @override
  void initState() {
    super.initState();

    getExampleCode(config.exampleCodeTag, DefaultAssetBundle.of(context)).then((String code) {
      setState(() {
        _exampleCode = code;
      });
    });
  }
127 128 129

  @override
  Widget build(BuildContext context) {
130 131 132 133
    final SyntaxHighlighterStyle style = Theme.of(context).brightness == Brightness.dark
      ? SyntaxHighlighterStyle.darkThemeStyle()
      : SyntaxHighlighterStyle.lightThemeStyle();

134 135 136 137 138 139 140 141 142
    Widget body;
    if (_exampleCode == null) {
      body = new Center(
        child: new CircularProgressIndicator()
      );
    } else {
      body = new ScrollableViewport(
        child: new Padding(
          padding: new EdgeInsets.all(16.0),
143 144 145 146 147 148 149 150
          child: new RichText(
            text: new TextSpan(
              style: new TextStyle(fontFamily: 'monospace', fontSize: 10.0),
              children: <TextSpan>[
                new DartSyntaxHighlighter(style).format(_exampleCode)
              ]
            )
          )
151 152 153 154
        )
      );
    }

155 156 157
    return new Scaffold(
      appBar: new AppBar(
        leading: new IconButton(
Ian Hickson's avatar
Ian Hickson committed
158
          icon: new Icon(Icons.clear),
159 160
          onPressed: () { Navigator.pop(context); }
        ),
161
        title: new Text('Example code')
162
      ),
163
      body: body
164 165 166
    );
  }
}