|
1 | 1 | /// Solid About Button. |
2 | 2 | /// |
3 | | -// Time-stamp: <Monday 2025-08-25 09:43:05 +1000 Graham Williams> |
| 3 | +// Time-stamp: <Thursday 2026-04-09 11:51:44 +1000 Graham Williams> |
4 | 4 | /// |
5 | 5 | /// Copyright (C) 2025, Software Innovation Institute, ANU. |
6 | 6 | /// |
@@ -42,6 +42,44 @@ import 'package:solidui/src/constants/about.dart'; |
42 | 42 | import 'package:solidui/src/widgets/solid_about_models.dart'; |
43 | 43 | import 'package:solidui/src/widgets/solid_preferences_dialog.dart'; |
44 | 44 |
|
| 45 | +/// Collapses single newlines (source-code soft wraps) into spaces so the |
| 46 | +/// Markdown renderer can reflow text to fit the dialog width. |
| 47 | +/// |
| 48 | +/// Double newlines (paragraph breaks) and Markdown syntax lines (headings, |
| 49 | +/// links, bold, etc.) are preserved verbatim. |
| 50 | +
|
| 51 | +String wordWrap(String text) { |
| 52 | + // Normalise Windows line endings. |
| 53 | + final s = text.replaceAll('\r\n', '\n'); |
| 54 | + final lines = s.split('\n'); |
| 55 | + final out = StringBuffer(); |
| 56 | + |
| 57 | + for (int i = 0; i < lines.length; i++) { |
| 58 | + final line = lines[i]; |
| 59 | + final next = i + 1 < lines.length ? lines[i + 1] : null; |
| 60 | + |
| 61 | + // Empty line = paragraph break — preserve as-is. |
| 62 | + if (line.trim().isEmpty) { |
| 63 | + out.writeln(); |
| 64 | + continue; |
| 65 | + } |
| 66 | + |
| 67 | + // Markdown structural lines (headings, list items, links, bold starts) |
| 68 | + // must stay on their own line. |
| 69 | + final isMdLine = |
| 70 | + RegExp(r'^(#{1,6} |\*\*|\* |- |\[|\!)').hasMatch(line.trim()); |
| 71 | + |
| 72 | + if (isMdLine || next == null || next.trim().isEmpty) { |
| 73 | + out.writeln(line); |
| 74 | + } else { |
| 75 | + // Soft wrap: join to next line with a space instead of a newline. |
| 76 | + out.write('$line '); |
| 77 | + } |
| 78 | + } |
| 79 | + |
| 80 | + return out.toString().trimRight(); |
| 81 | +} |
| 82 | + |
45 | 83 | /// A button that shows an About dialogue when pressed. |
46 | 84 |
|
47 | 85 | class SolidAboutButton extends StatefulWidget { |
@@ -316,7 +354,7 @@ class SolidAbout { |
316 | 354 | alignment: Alignment.centerLeft, |
317 | 355 | child: TextButton.icon( |
318 | 356 | icon: const Icon(Icons.tune), |
319 | | - label: const Text('AppBar Layout Preferences'), |
| 357 | + label: const Text('AppBar Preferences'), |
320 | 358 | onPressed: () { |
321 | 359 | Navigator.of(dialogContext).pop(); |
322 | 360 | SolidPreferencesDialog.show(context); |
|
0 commit comments