• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1// Copyright 2015 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5import 'package:flutter/material.dart';
6
7typedef _TextTransformer = Widget Function(String name, String text);
8
9// From https://en.wikiquote.org/wiki/2001:_A_Space_Odyssey_(film)
10const String _kDialogText = '''
11Dave: Open the pod bay doors, please, HAL. Open the pod bay doors, please, HAL. Hello, HAL. Do you read me? Hello, HAL. Do you read me? Do you read me, HAL?
12HAL: Affirmative, Dave. I read you.
13Dave: Open the pod bay doors, HAL.
14HAL: I'm sorry, Dave. I'm afraid I can't do that.
15Dave: What's the problem?
16HAL: I think you know what the problem is just as well as I do.
17Dave: What are you talking about, HAL?
18HAL: This mission is too important for me to allow you to jeopardize it.''';
19
20// [["Dave", "Open the pod bay..."] ...]
21final List<List<String>> _kNameLines = _kDialogText
22  .split('\n')
23  .map<List<String>>((String line) => line.split(':'))
24  .toList();
25
26final TextStyle _kDaveStyle = TextStyle(color: Colors.indigo.shade400, height: 1.8);
27final TextStyle _kHalStyle = TextStyle(color: Colors.red.shade400, fontFamily: 'monospace');
28const TextStyle _kBold = TextStyle(fontWeight: FontWeight.bold);
29const TextStyle _kUnderline = TextStyle(
30  decoration: TextDecoration.underline,
31  decorationColor: Color(0xFF000000),
32  decorationStyle: TextDecorationStyle.wavy,
33);
34
35Widget toStyledText(String name, String text) {
36  final TextStyle lineStyle = (name == 'Dave') ? _kDaveStyle : _kHalStyle;
37  return RichText(
38    key: Key(text),
39    text: TextSpan(
40      style: lineStyle,
41      children: <TextSpan>[
42        TextSpan(
43          style: _kBold,
44          children: <TextSpan>[
45            TextSpan(
46              style: _kUnderline,
47              text: name,
48            ),
49            const TextSpan(text: ':'),
50          ],
51        ),
52        TextSpan(text: text),
53      ],
54    ),
55  );
56}
57
58Widget toPlainText(String name, String text) => Text(name + ':' + text);
59
60class SpeakerSeparator extends StatelessWidget {
61  @override
62  Widget build(BuildContext context) {
63    return Container(
64      constraints: const BoxConstraints.expand(height: 0.0),
65      margin: const EdgeInsets.symmetric(vertical: 10.0, horizontal: 64.0),
66      decoration: const BoxDecoration(
67        border: Border(
68          bottom: BorderSide(color: Color.fromARGB(24, 0, 0, 0))
69        )
70      ),
71    );
72  }
73}
74
75class StyledTextDemo extends StatefulWidget {
76  @override
77  _StyledTextDemoState createState() => _StyledTextDemoState();
78}
79
80class _StyledTextDemoState extends State<StyledTextDemo> {
81  @override
82  void initState() {
83    super.initState();
84    _toText = toStyledText;
85  }
86
87  _TextTransformer _toText;
88
89  void _handleTap() {
90    setState(() {
91      _toText = (_toText == toPlainText) ? toStyledText : toPlainText;
92    });
93  }
94
95  @override
96  Widget build(BuildContext context) {
97    final List<Widget> lines = _kNameLines
98      .map<Widget>((List<String> nameAndText) => _toText(nameAndText[0], nameAndText[1]))
99      .toList();
100
101    final List<Widget> children = <Widget>[];
102    for (Widget line in lines) {
103      children.add(line);
104      if (line != lines.last)
105        children.add(SpeakerSeparator());
106    }
107
108    return GestureDetector(
109      onTap: _handleTap,
110      child: Container(
111        padding: const EdgeInsets.symmetric(horizontal: 8.0),
112        child: Column(
113          children: children,
114          mainAxisAlignment: MainAxisAlignment.center,
115          crossAxisAlignment: CrossAxisAlignment.start,
116        ),
117      ),
118    );
119  }
120}
121
122void main() {
123  runApp(MaterialApp(
124    theme: ThemeData.light(),
125    home: Scaffold(
126      appBar: AppBar(
127        title: const Text('Hal and Dave'),
128      ),
129      body: Material(
130        color: Colors.grey.shade50,
131        child: StyledTextDemo(),
132      ),
133    ),
134  ));
135}
136