Ian Hickson | 449f4a6 | 2019-11-27 15:04:02 -0800 | [diff] [blame] | 1 | // Copyright 2014 The Flutter Authors. All rights reserved. |
Adam Barth | 948ae15 | 2016-02-13 00:52:56 -0800 | [diff] [blame] | 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), |
Alexandre Ardhuin | 387f885 | 2019-03-01 08:17:55 +0100 | [diff] [blame] | 32 | decorationStyle: TextDecorationStyle.wavy, |
Adam Barth | 948ae15 | 2016-02-13 00:52:56 -0800 | [diff] [blame] | 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, |
Alexandre Ardhuin | 387f885 | 2019-03-01 08:17:55 +0100 | [diff] [blame] | 47 | text: name, |
Adam Barth | fb4dbf4 | 2016-02-24 13:48:56 -0800 | [diff] [blame] | 48 | ), |
Alexandre Ardhuin | 387f885 | 2019-03-01 08:17:55 +0100 | [diff] [blame] | 49 | const TextSpan(text: ':'), |
| 50 | ], |
Adam Barth | fb4dbf4 | 2016-02-24 13:48:56 -0800 | [diff] [blame] | 51 | ), |
Alexandre Ardhuin | 387f885 | 2019-03-01 08:17:55 +0100 | [diff] [blame] | 52 | TextSpan(text: text), |
| 53 | ], |
| 54 | ), |
Adam Barth | 948ae15 | 2016-02-13 00:52:56 -0800 | [diff] [blame] | 55 | ); |
| 56 | } |
| 57 | |
Alexandre Ardhuin | 34059ee | 2021-06-01 20:14:06 +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 { |
Michael Goderbauer | 91bcf42 | 2022-03-29 12:53:08 -0700 | [diff] [blame] | 61 | const SpeakerSeparator({super.key}); |
Michael Goderbauer | 0f56829 | 2021-03-02 10:14:02 -0800 | [diff] [blame] | 62 | |
Hixie | 797e27e | 2016-03-14 13:31:43 -0700 | [diff] [blame] | 63 | @override |
Adam Barth | 948ae15 | 2016-02-13 00:52:56 -0800 | [diff] [blame] | 64 | Widget build(BuildContext context) { |
Alexandre Ardhuin | d927c93 | 2018-09-12 08:29:29 +0200 | [diff] [blame] | 65 | return Container( |
Adam Barth | 948ae15 | 2016-02-13 00:52:56 -0800 | [diff] [blame] | 66 | constraints: const BoxConstraints.expand(height: 0.0), |
Adam Barth | e71bd77 | 2016-03-12 11:43:18 -0800 | [diff] [blame] | 67 | margin: const EdgeInsets.symmetric(vertical: 10.0, horizontal: 64.0), |
Adam Barth | 948ae15 | 2016-02-13 00:52:56 -0800 | [diff] [blame] | 68 | decoration: const BoxDecoration( |
Alexandre Ardhuin | eda03e2 | 2018-08-02 12:02:32 +0200 | [diff] [blame] | 69 | border: Border( |
Alexandre Ardhuin | 7f31861 | 2021-04-28 22:54:49 +0200 | [diff] [blame] | 70 | bottom: BorderSide(color: Color.fromARGB(24, 0, 0, 0)), |
| 71 | ), |
Alexandre Ardhuin | 387f885 | 2019-03-01 08:17:55 +0100 | [diff] [blame] | 72 | ), |
Adam Barth | 948ae15 | 2016-02-13 00:52:56 -0800 | [diff] [blame] | 73 | ); |
| 74 | } |
| 75 | } |
| 76 | |
Adam Barth | 95fc5ae | 2016-03-12 12:13:16 -0800 | [diff] [blame] | 77 | class StyledTextDemo extends StatefulWidget { |
Michael Goderbauer | 91bcf42 | 2022-03-29 12:53:08 -0700 | [diff] [blame] | 78 | const StyledTextDemo({super.key}); |
Michael Goderbauer | 0f56829 | 2021-03-02 10:14:02 -0800 | [diff] [blame] | 79 | |
Hixie | 797e27e | 2016-03-14 13:31:43 -0700 | [diff] [blame] | 80 | @override |
Michael Goderbauer | b8a2456 | 2021-05-10 16:26:16 -0700 | [diff] [blame] | 81 | State<StyledTextDemo> createState() => _StyledTextDemoState(); |
Adam Barth | 948ae15 | 2016-02-13 00:52:56 -0800 | [diff] [blame] | 82 | } |
| 83 | |
| 84 | class _StyledTextDemoState extends State<StyledTextDemo> { |
Michael Goderbauer | dd2ea7c | 2020-10-22 13:33:07 -0700 | [diff] [blame] | 85 | _TextTransformer _toText = toStyledText; |
Adam Barth | 948ae15 | 2016-02-13 00:52:56 -0800 | [diff] [blame] | 86 | |
| 87 | void _handleTap() { |
| 88 | setState(() { |
| 89 | _toText = (_toText == toPlainText) ? toStyledText : toPlainText; |
| 90 | }); |
| 91 | } |
| 92 | |
Hixie | 797e27e | 2016-03-14 13:31:43 -0700 | [diff] [blame] | 93 | @override |
Adam Barth | 948ae15 | 2016-02-13 00:52:56 -0800 | [diff] [blame] | 94 | Widget build(BuildContext context) { |
Alexandre Ardhuin | d927c93 | 2018-09-12 08:29:29 +0200 | [diff] [blame] | 95 | return GestureDetector( |
Adam Barth | 948ae15 | 2016-02-13 00:52:56 -0800 | [diff] [blame] | 96 | onTap: _handleTap, |
Alexandre Ardhuin | d927c93 | 2018-09-12 08:29:29 +0200 | [diff] [blame] | 97 | child: Container( |
Alexandre Ardhuin | e9a775b | 2017-02-21 23:54:29 +0100 | [diff] [blame] | 98 | padding: const EdgeInsets.symmetric(horizontal: 8.0), |
Alexandre Ardhuin | d927c93 | 2018-09-12 08:29:29 +0200 | [diff] [blame] | 99 | child: Column( |
Adam Barth | d5b2e2a | 2016-03-12 18:28:42 -0800 | [diff] [blame] | 100 | mainAxisAlignment: MainAxisAlignment.center, |
Alexandre Ardhuin | 387f885 | 2019-03-01 08:17:55 +0100 | [diff] [blame] | 101 | crossAxisAlignment: CrossAxisAlignment.start, |
Alexandre Ardhuin | df4bf45 | 2019-09-17 16:23:44 +0200 | [diff] [blame] | 102 | children: _kNameLines |
| 103 | .map<Widget>((List<String> nameAndText) => _toText(nameAndText[0], nameAndText[1])) |
| 104 | .expand((Widget line) => <Widget>[ |
| 105 | line, |
Michael Goderbauer | 0f56829 | 2021-03-02 10:14:02 -0800 | [diff] [blame] | 106 | const SpeakerSeparator(), |
Alexandre Ardhuin | df4bf45 | 2019-09-17 16:23:44 +0200 | [diff] [blame] | 107 | ]) |
| 108 | .toList()..removeLast(), |
Alexandre Ardhuin | 387f885 | 2019-03-01 08:17:55 +0100 | [diff] [blame] | 109 | ), |
| 110 | ), |
Adam Barth | 948ae15 | 2016-02-13 00:52:56 -0800 | [diff] [blame] | 111 | ); |
| 112 | } |
| 113 | } |
| 114 | |
| 115 | void main() { |
Alexandre Ardhuin | d927c93 | 2018-09-12 08:29:29 +0200 | [diff] [blame] | 116 | runApp(MaterialApp( |
| 117 | theme: ThemeData.light(), |
| 118 | home: Scaffold( |
| 119 | appBar: AppBar( |
Alexandre Ardhuin | 387f885 | 2019-03-01 08:17:55 +0100 | [diff] [blame] | 120 | title: const Text('Hal and Dave'), |
Ian Hickson | 1b9476c | 2016-04-20 09:33:28 -0700 | [diff] [blame] | 121 | ), |
Alexandre Ardhuin | d927c93 | 2018-09-12 08:29:29 +0200 | [diff] [blame] | 122 | body: Material( |
Alexandre Ardhuin | 578ca0a | 2017-03-21 23:14:55 +0100 | [diff] [blame] | 123 | color: Colors.grey.shade50, |
Michael Goderbauer | 0f56829 | 2021-03-02 10:14:02 -0800 | [diff] [blame] | 124 | child: const StyledTextDemo(), |
Alexandre Ardhuin | 387f885 | 2019-03-01 08:17:55 +0100 | [diff] [blame] | 125 | ), |
| 126 | ), |
Adam Barth | 948ae15 | 2016-02-13 00:52:56 -0800 | [diff] [blame] | 127 | )); |
| 128 | } |