Showing
8 changed files
with
141 additions
and
11 deletions
@@ -8,6 +8,7 @@ | @@ -8,6 +8,7 @@ | ||
8 | - Typo: rename "litteral" with "literal" | 8 | - Typo: rename "litteral" with "literal" |
9 | - Fix tabs and other spaces placeholder | 9 | - Fix tabs and other spaces placeholder |
10 | - Prevent modifying the document once saved | 10 | - Prevent modifying the document once saved |
11 | +- Improve Table Of Content | ||
11 | 12 | ||
12 | ## 3.7.4 | 13 | ## 3.7.4 |
13 | 14 |
@@ -58,7 +58,7 @@ class PdfOutline extends PdfObjectDict { | @@ -58,7 +58,7 @@ class PdfOutline extends PdfObjectDict { | ||
58 | this.color, | 58 | this.color, |
59 | this.destMode = PdfOutlineMode.fitPage, | 59 | this.destMode = PdfOutlineMode.fitPage, |
60 | this.style = PdfOutlineStyle.normal, | 60 | this.style = PdfOutlineStyle.normal, |
61 | - String? page, | 61 | + PdfPage? page, |
62 | }) : assert(anchor == null || (dest == null && rect == null)), | 62 | }) : assert(anchor == null || (dest == null && rect == null)), |
63 | _page = page, | 63 | _page = page, |
64 | super(pdfDocument); | 64 | super(pdfDocument); |
@@ -76,12 +76,20 @@ class PdfOutline extends PdfObjectDict { | @@ -76,12 +76,20 @@ class PdfOutline extends PdfObjectDict { | ||
76 | PdfPage? dest; | 76 | PdfPage? dest; |
77 | 77 | ||
78 | /// Page number | 78 | /// Page number |
79 | - String? get page => | ||
80 | - _page ?? | ||
81 | - (dest != null | ||
82 | - ? (pdfDocument.pdfPageList.pages.indexOf(dest!) + 1).toString() | ||
83 | - : null); | ||
84 | - final String? _page; | 79 | + String? get page { |
80 | + final int? num; | ||
81 | + if (_page != null) { | ||
82 | + num = pdfDocument.pdfPageList.pages.indexOf(_page!); | ||
83 | + } else if (dest != null) { | ||
84 | + num = pdfDocument.pdfPageList.pages.indexOf(dest!); | ||
85 | + } else { | ||
86 | + num = null; | ||
87 | + } | ||
88 | + | ||
89 | + return num == null ? null : (num + 1).toString(); | ||
90 | + } | ||
91 | + | ||
92 | + final PdfPage? _page; | ||
85 | 93 | ||
86 | /// The region on the destination page | 94 | /// The region on the destination page |
87 | final PdfRect? rect; | 95 | final PdfRect? rect; |
@@ -59,8 +59,8 @@ class Anchor extends SingleChildWidget { | @@ -59,8 +59,8 @@ class Anchor extends SingleChildWidget { | ||
59 | 59 | ||
60 | if (description != null) { | 60 | if (description != null) { |
61 | final rb = mat.transform3(Vector3(box!.right, box!.top, 0)); | 61 | final rb = mat.transform3(Vector3(box!.right, box!.top, 0)); |
62 | - final ibox = PdfRect.fromLTRB(lt.x, lt.y, rb.x, rb.y); | ||
63 | - PdfAnnot(context.page, PdfAnnotText(rect: ibox, content: description!)); | 62 | + final iBox = PdfRect.fromLTRB(lt.x, lt.y, rb.x, rb.y); |
63 | + PdfAnnot(context.page, PdfAnnotText(rect: iBox, content: description!)); | ||
64 | } | 64 | } |
65 | } | 65 | } |
66 | } | 66 | } |
@@ -622,7 +622,7 @@ class Outline extends Anchor { | @@ -622,7 +622,7 @@ class Outline extends Anchor { | ||
622 | anchor: name, | 622 | anchor: name, |
623 | color: color, | 623 | color: color, |
624 | style: style, | 624 | style: style, |
625 | - page: context.pageLabel, | 625 | + page: context.page, |
626 | )..effectiveLevel = level; | 626 | )..effectiveLevel = level; |
627 | 627 | ||
628 | final root = context.document.outline; | 628 | final root = context.document.outline; |
@@ -151,7 +151,7 @@ class TableOfContent extends StatelessWidget { | @@ -151,7 +151,7 @@ class TableOfContent extends StatelessWidget { | ||
151 | thickness: 0.2, | 151 | thickness: 0.2, |
152 | )), | 152 | )), |
153 | SizedBox(width: 8), | 153 | SizedBox(width: 8), |
154 | - Text('${c.page}'), | 154 | + DelayedWidget(build: (_) => Text('${c.page}')), |
155 | ], | 155 | ], |
156 | ), | 156 | ), |
157 | ), | 157 | ), |
@@ -380,3 +380,37 @@ class InheritedWidget extends SingleChildWidget { | @@ -380,3 +380,37 @@ class InheritedWidget extends SingleChildWidget { | ||
380 | paintChild(_context!); | 380 | paintChild(_context!); |
381 | } | 381 | } |
382 | } | 382 | } |
383 | + | ||
384 | +class DelayedWidget extends SingleChildWidget { | ||
385 | + DelayedWidget({required this.build}) : super(); | ||
386 | + | ||
387 | + final BuildCallback build; | ||
388 | + | ||
389 | + @override | ||
390 | + Widget? get child => _child; | ||
391 | + | ||
392 | + Widget? _child; | ||
393 | + | ||
394 | + @override | ||
395 | + void layout(Context context, BoxConstraints constraints, | ||
396 | + {bool parentUsesSize = false}) { | ||
397 | + _child = build(context); | ||
398 | + super.layout(context, constraints); | ||
399 | + } | ||
400 | + | ||
401 | + void delayedPaint(Context context) { | ||
402 | + _child = build(context); | ||
403 | + child!.layout( | ||
404 | + context, | ||
405 | + BoxConstraints.tight(box!.size), | ||
406 | + parentUsesSize: false, | ||
407 | + ); | ||
408 | + paintChild(context); | ||
409 | + } | ||
410 | + | ||
411 | + @override | ||
412 | + void paint(Context context) { | ||
413 | + delayedPaint(context); | ||
414 | + super.paint(context); | ||
415 | + } | ||
416 | +} |
@@ -48,6 +48,7 @@ import 'widget_table_test.dart' as widget_table; | @@ -48,6 +48,7 @@ import 'widget_table_test.dart' as widget_table; | ||
48 | import 'widget_test.dart' as widget; | 48 | import 'widget_test.dart' as widget; |
49 | import 'widget_text_test.dart' as widget_text; | 49 | import 'widget_text_test.dart' as widget_text; |
50 | import 'widget_theme_test.dart' as widget_theme; | 50 | import 'widget_theme_test.dart' as widget_theme; |
51 | +import 'widget_toc_test.dart' as widget_toc; | ||
51 | import 'widget_watermark_test.dart' as widget_watermark; | 52 | import 'widget_watermark_test.dart' as widget_watermark; |
52 | import 'widget_wrap_test.dart' as widget_wrap; | 53 | import 'widget_wrap_test.dart' as widget_wrap; |
53 | 54 | ||
@@ -83,6 +84,7 @@ void main() { | @@ -83,6 +84,7 @@ void main() { | ||
83 | widget_table.main(); | 84 | widget_table.main(); |
84 | widget_text.main(); | 85 | widget_text.main(); |
85 | widget_theme.main(); | 86 | widget_theme.main(); |
87 | + widget_toc.main(); | ||
86 | widget_watermark.main(); | 88 | widget_watermark.main(); |
87 | widget_wrap.main(); | 89 | widget_wrap.main(); |
88 | widget.main(); | 90 | widget.main(); |
pdf/test/widget_toc_test.dart
0 → 100644
1 | +/* | ||
2 | + * Copyright (C) 2017, David PHAM-VAN <dev.nfet.net@gmail.com> | ||
3 | + * | ||
4 | + * Licensed under the Apache License, Version 2.0 (the "License"); | ||
5 | + * you may not use this file except in compliance with the License. | ||
6 | + * You may obtain a copy of the License at | ||
7 | + * | ||
8 | + * http://www.apache.org/licenses/LICENSE-2.0 | ||
9 | + * | ||
10 | + * Unless required by applicable law or agreed to in writing, software | ||
11 | + * distributed under the License is distributed on an "AS IS" BASIS, | ||
12 | + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
13 | + * See the License for the specific language governing permissions and | ||
14 | + * limitations under the License. | ||
15 | + */ | ||
16 | + | ||
17 | +import 'dart:io'; | ||
18 | +import 'dart:math'; | ||
19 | + | ||
20 | +import 'package:pdf/widgets.dart'; | ||
21 | +import 'package:test/test.dart'; | ||
22 | + | ||
23 | +late Document pdf; | ||
24 | + | ||
25 | +void main() { | ||
26 | + setUpAll(() { | ||
27 | + Document.debug = true; | ||
28 | + pdf = Document(); | ||
29 | + }); | ||
30 | + | ||
31 | + test('Pdf Widgets TableOfContent', () { | ||
32 | + pdf.addPage( | ||
33 | + Page( | ||
34 | + build: (context) => | ||
35 | + Center(child: Text('Document', style: Theme.of(context).header0)), | ||
36 | + ), | ||
37 | + ); | ||
38 | + | ||
39 | + pdf.addPage( | ||
40 | + MultiPage( | ||
41 | + footer: (c) => Padding( | ||
42 | + padding: const EdgeInsets.only(top: 20), | ||
43 | + child: Align( | ||
44 | + alignment: Alignment.centerRight, child: Text(c.pageLabel))), | ||
45 | + build: (context) => [ | ||
46 | + ...Iterable<Widget>.generate(40, (index) { | ||
47 | + final level = (sin(index / 5) * 6).abs().toInt(); | ||
48 | + return Column( | ||
49 | + children: [ | ||
50 | + Header( | ||
51 | + child: Text('Hello $index level $level'), | ||
52 | + text: 'Hello $index', | ||
53 | + level: level, | ||
54 | + ), | ||
55 | + Lorem(length: 60), | ||
56 | + ], | ||
57 | + ); | ||
58 | + }), | ||
59 | + ], | ||
60 | + ), | ||
61 | + ); | ||
62 | + | ||
63 | + pdf.addPage( | ||
64 | + MultiPage( | ||
65 | + footer: (c) => Padding( | ||
66 | + padding: const EdgeInsets.only(top: 20), | ||
67 | + child: Align( | ||
68 | + alignment: Alignment.centerRight, child: Text(c.pageLabel))), | ||
69 | + build: (context) => [ | ||
70 | + Center( | ||
71 | + child: | ||
72 | + Text('Table of content', style: Theme.of(context).header0)), | ||
73 | + SizedBox(height: 20), | ||
74 | + TableOfContent(), | ||
75 | + ], | ||
76 | + ), | ||
77 | + index: 1, | ||
78 | + ); | ||
79 | + }); | ||
80 | + | ||
81 | + tearDownAll(() async { | ||
82 | + final file = File('widgets-toc.pdf'); | ||
83 | + await file.writeAsBytes(await pdf.save()); | ||
84 | + }); | ||
85 | +} |
test/golden/widgets-toc.pdf
0 → 100644
No preview for this file type
-
Please register or login to post a comment