Adam Barth | 948ae15 | 2016-02-13 00:52:56 -0800 | [diff] [blame] | 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 | |
| 5 | import 'package:flutter/material.dart'; |
| 6 | |
Alexandre Ardhuin | a07d371 | 2018-09-14 21:06:19 +0200 | [diff] [blame] | 7 | typedef _TextTransformer = Widget Function(String name, String text); |
Adam Barth | 948ae15 | 2016-02-13 00:52:56 -0800 | [diff] [blame] | 8 | |
| 9 | // From https://en.wikiquote.org/wiki/2001:_A_Space_Odyssey_(film) |
| 10 | const String _kDialogText = ''' |
| 11 | Dave: 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? |
| 12 | HAL: Affirmative, Dave. I read you. |
| 13 | Dave: Open the pod bay doors, HAL. |
| 14 | HAL: I'm sorry, Dave. I'm afraid I can't do that. |
| 15 | Dave: What's the problem? |
| 16 | HAL: I think you know what the problem is just as well as I do. |
| 17 | Dave: What are you talking about, HAL? |
| 18 | HAL: This mission is too important for me to allow you to jeopardize it.'''; |
| 19 | |
| 20 | // [["Dave", "Open the pod bay..."] ...] |
| 21 | final List<List<String>> _kNameLines = _kDialogText |
| 22 | .split('\n') |
Alexandre Ardhuin | f62afdc | 2018-10-01 21:29:08 +0200 | [diff] [blame] | 23 | .map<List<String>>((String line) => line.split(':')) |
Adam Barth | 948ae15 | 2016-02-13 00:52:56 -0800 | [diff] [blame] | 24 | .toList(); |
| 25 | |
Alexandre Ardhuin | d927c93 | 2018-09-12 08:29:29 +0200 | [diff] [blame] | 26 | final TextStyle _kDaveStyle = TextStyle(color: Colors.indigo.shade400, height: 1.8); |
| 27 | final TextStyle _kHalStyle = TextStyle(color: Colors.red.shade400, fontFamily: 'monospace'); |
Alexandre Ardhuin | eda03e2 | 2018-08-02 12:02:32 +0200 | [diff] [blame] | 28 | const TextStyle _kBold = TextStyle(fontWeight: FontWeight.bold); |
| 29 | const TextStyle _kUnderline = TextStyle( |
Adam Barth | 948ae15 | 2016-02-13 00:52:56 -0800 | [diff] [blame] | 30 | decoration: TextDecoration.underline, |
Alexandre Ardhuin | eda03e2 | 2018-08-02 12:02:32 +0200 | [diff] [blame] | 31 | decorationColor: Color(0xFF000000), |
Adam Barth | 948ae15 | 2016-02-13 00:52:56 -0800 | [diff] [blame] | 32 | decorationStyle: TextDecorationStyle.wavy |
| 33 | ); |
| 34 | |
| 35 | Widget toStyledText(String name, String text) { |
Alexandre Ardhuin | 1fce14a | 2017-10-22 18:11:36 +0200 | [diff] [blame] | 36 | final TextStyle lineStyle = (name == 'Dave') ? _kDaveStyle : _kHalStyle; |
Alexandre Ardhuin | d927c93 | 2018-09-12 08:29:29 +0200 | [diff] [blame] | 37 | return RichText( |
| 38 | key: Key(text), |
| 39 | text: TextSpan( |
Adam Barth | fb4dbf4 | 2016-02-24 13:48:56 -0800 | [diff] [blame] | 40 | style: lineStyle, |
| 41 | children: <TextSpan>[ |
Alexandre Ardhuin | d927c93 | 2018-09-12 08:29:29 +0200 | [diff] [blame] | 42 | TextSpan( |
Adam Barth | fb4dbf4 | 2016-02-24 13:48:56 -0800 | [diff] [blame] | 43 | style: _kBold, |
| 44 | children: <TextSpan>[ |
Alexandre Ardhuin | d927c93 | 2018-09-12 08:29:29 +0200 | [diff] [blame] | 45 | TextSpan( |
Adam Barth | fb4dbf4 | 2016-02-24 13:48:56 -0800 | [diff] [blame] | 46 | style: _kUnderline, |
| 47 | text: name |
| 48 | ), |
Alexandre Ardhuin | e9a775b | 2017-02-21 23:54:29 +0100 | [diff] [blame] | 49 | const TextSpan(text: ':') |
Adam Barth | fb4dbf4 | 2016-02-24 13:48:56 -0800 | [diff] [blame] | 50 | ] |
| 51 | ), |
Alexandre Ardhuin | d927c93 | 2018-09-12 08:29:29 +0200 | [diff] [blame] | 52 | TextSpan(text: text) |
Adam Barth | fb4dbf4 | 2016-02-24 13:48:56 -0800 | [diff] [blame] | 53 | ] |
| 54 | ) |
Adam Barth | 948ae15 | 2016-02-13 00:52:56 -0800 | [diff] [blame] | 55 | ); |
| 56 | } |
| 57 | |
Alexandre Ardhuin | d927c93 | 2018-09-12 08:29:29 +0200 | [diff] [blame] | 58 | Widget toPlainText(String name, String text) => Text(name + ':' + text); |
Adam Barth | 948ae15 | 2016-02-13 00:52:56 -0800 | [diff] [blame] | 59 | |
Adam Barth | 95fc5ae | 2016-03-12 12:13:16 -0800 | [diff] [blame] | 60 | class SpeakerSeparator extends StatelessWidget { |
Hixie | 797e27e | 2016-03-14 13:31:43 -0700 | [diff] [blame] | 61 | @override |
Adam Barth | 948ae15 | 2016-02-13 00:52:56 -0800 | [diff] [blame] | 62 | Widget build(BuildContext context) { |
Alexandre Ardhuin | d927c93 | 2018-09-12 08:29:29 +0200 | [diff] [blame] | 63 | return Container( |
Adam Barth | 948ae15 | 2016-02-13 00:52:56 -0800 | [diff] [blame] | 64 | constraints: const BoxConstraints.expand(height: 0.0), |
Adam Barth | e71bd77 | 2016-03-12 11:43:18 -0800 | [diff] [blame] | 65 | margin: const EdgeInsets.symmetric(vertical: 10.0, horizontal: 64.0), |
Adam Barth | 948ae15 | 2016-02-13 00:52:56 -0800 | [diff] [blame] | 66 | decoration: const BoxDecoration( |
Alexandre Ardhuin | eda03e2 | 2018-08-02 12:02:32 +0200 | [diff] [blame] | 67 | border: Border( |
| 68 | bottom: BorderSide(color: Color.fromARGB(24, 0, 0, 0)) |
Adam Barth | 948ae15 | 2016-02-13 00:52:56 -0800 | [diff] [blame] | 69 | ) |
| 70 | ) |
| 71 | ); |
| 72 | } |
| 73 | } |
| 74 | |
Adam Barth | 95fc5ae | 2016-03-12 12:13:16 -0800 | [diff] [blame] | 75 | class StyledTextDemo extends StatefulWidget { |
Hixie | 797e27e | 2016-03-14 13:31:43 -0700 | [diff] [blame] | 76 | @override |
Alexandre Ardhuin | d927c93 | 2018-09-12 08:29:29 +0200 | [diff] [blame] | 77 | _StyledTextDemoState createState() => _StyledTextDemoState(); |
Adam Barth | 948ae15 | 2016-02-13 00:52:56 -0800 | [diff] [blame] | 78 | } |
| 79 | |
| 80 | class _StyledTextDemoState extends State<StyledTextDemo> { |
Hixie | 797e27e | 2016-03-14 13:31:43 -0700 | [diff] [blame] | 81 | @override |
Adam Barth | 948ae15 | 2016-02-13 00:52:56 -0800 | [diff] [blame] | 82 | void initState() { |
| 83 | super.initState(); |
| 84 | _toText = toStyledText; |
| 85 | } |
| 86 | |
Ian Hickson | 63aa139 | 2017-01-23 01:04:31 -0800 | [diff] [blame] | 87 | _TextTransformer _toText; |
Adam Barth | 948ae15 | 2016-02-13 00:52:56 -0800 | [diff] [blame] | 88 | |
| 89 | void _handleTap() { |
| 90 | setState(() { |
| 91 | _toText = (_toText == toPlainText) ? toStyledText : toPlainText; |
| 92 | }); |
| 93 | } |
| 94 | |
Hixie | 797e27e | 2016-03-14 13:31:43 -0700 | [diff] [blame] | 95 | @override |
Adam Barth | 948ae15 | 2016-02-13 00:52:56 -0800 | [diff] [blame] | 96 | Widget build(BuildContext context) { |
Chris Bracken | 4c8c420 | 2017-03-03 18:04:27 -0800 | [diff] [blame] | 97 | final List<Widget> lines = _kNameLines |
Ian Hickson | 63aa139 | 2017-01-23 01:04:31 -0800 | [diff] [blame] | 98 | .map<Widget>((List<String> nameAndText) => _toText(nameAndText[0], nameAndText[1])) |
Adam Barth | 948ae15 | 2016-02-13 00:52:56 -0800 | [diff] [blame] | 99 | .toList(); |
| 100 | |
Chris Bracken | 4c8c420 | 2017-03-03 18:04:27 -0800 | [diff] [blame] | 101 | final List<Widget> children = <Widget>[]; |
Adam Barth | 948ae15 | 2016-02-13 00:52:56 -0800 | [diff] [blame] | 102 | for (Widget line in lines) { |
| 103 | children.add(line); |
| 104 | if (line != lines.last) |
Alexandre Ardhuin | d927c93 | 2018-09-12 08:29:29 +0200 | [diff] [blame] | 105 | children.add(SpeakerSeparator()); |
Adam Barth | 948ae15 | 2016-02-13 00:52:56 -0800 | [diff] [blame] | 106 | } |
| 107 | |
Alexandre Ardhuin | d927c93 | 2018-09-12 08:29:29 +0200 | [diff] [blame] | 108 | return GestureDetector( |
Adam Barth | 948ae15 | 2016-02-13 00:52:56 -0800 | [diff] [blame] | 109 | onTap: _handleTap, |
Alexandre Ardhuin | d927c93 | 2018-09-12 08:29:29 +0200 | [diff] [blame] | 110 | child: Container( |
Alexandre Ardhuin | e9a775b | 2017-02-21 23:54:29 +0100 | [diff] [blame] | 111 | padding: const EdgeInsets.symmetric(horizontal: 8.0), |
Alexandre Ardhuin | d927c93 | 2018-09-12 08:29:29 +0200 | [diff] [blame] | 112 | child: Column( |
Adam Barth | 948ae15 | 2016-02-13 00:52:56 -0800 | [diff] [blame] | 113 | children: children, |
Adam Barth | d5b2e2a | 2016-03-12 18:28:42 -0800 | [diff] [blame] | 114 | mainAxisAlignment: MainAxisAlignment.center, |
| 115 | crossAxisAlignment: CrossAxisAlignment.start |
Adam Barth | 948ae15 | 2016-02-13 00:52:56 -0800 | [diff] [blame] | 116 | ) |
| 117 | ) |
| 118 | ); |
| 119 | } |
| 120 | } |
| 121 | |
| 122 | void main() { |
Alexandre Ardhuin | d927c93 | 2018-09-12 08:29:29 +0200 | [diff] [blame] | 123 | runApp(MaterialApp( |
| 124 | theme: ThemeData.light(), |
| 125 | home: Scaffold( |
| 126 | appBar: AppBar( |
Ian Hickson | 3eb8783 | 2017-04-07 12:24:32 -0700 | [diff] [blame] | 127 | title: const Text('Hal and Dave') |
Ian Hickson | 1b9476c | 2016-04-20 09:33:28 -0700 | [diff] [blame] | 128 | ), |
Alexandre Ardhuin | d927c93 | 2018-09-12 08:29:29 +0200 | [diff] [blame] | 129 | body: Material( |
Alexandre Ardhuin | 578ca0a | 2017-03-21 23:14:55 +0100 | [diff] [blame] | 130 | color: Colors.grey.shade50, |
Alexandre Ardhuin | d927c93 | 2018-09-12 08:29:29 +0200 | [diff] [blame] | 131 | child: StyledTextDemo() |
Ian Hickson | 1b9476c | 2016-04-20 09:33:28 -0700 | [diff] [blame] | 132 | ) |
| 133 | ) |
Adam Barth | 948ae15 | 2016-02-13 00:52:56 -0800 | [diff] [blame] | 134 | )); |
| 135 | } |