Showing
4 changed files
with
148 additions
and
0 deletions
1 | # 1.3.10 | 1 | # 1.3.10 |
2 | * Deprecate the document argument in Printing.sharePdf() | 2 | * Deprecate the document argument in Printing.sharePdf() |
3 | * Add default value to alpha in PdfColor variants | 3 | * Add default value to alpha in PdfColor variants |
4 | +* Fix Table Widget | ||
4 | 5 | ||
5 | # 1.3.9 | 6 | # 1.3.9 |
6 | * Fix Transform Widget alignment | 7 | * Fix Transform Widget alignment |
@@ -182,6 +182,11 @@ class Table extends Widget implements SpanningWidget { | @@ -182,6 +182,11 @@ class Table extends Widget implements SpanningWidget { | ||
182 | } | 182 | } |
183 | } | 183 | } |
184 | 184 | ||
185 | + if (_widths.isEmpty) { | ||
186 | + box = PdfRect.fromPoints(PdfPoint.zero, constraints.smallest); | ||
187 | + return; | ||
188 | + } | ||
189 | + | ||
185 | final double maxWidth = _widths.reduce((double a, double b) => a + b); | 190 | final double maxWidth = _widths.reduce((double a, double b) => a + b); |
186 | 191 | ||
187 | // Compute column widths using flex and estimated width | 192 | // Compute column widths using flex and estimated width |
@@ -277,6 +282,10 @@ class Table extends Widget implements SpanningWidget { | @@ -277,6 +282,10 @@ class Table extends Widget implements SpanningWidget { | ||
277 | ..saveContext() | 282 | ..saveContext() |
278 | ..setTransform(mat); | 283 | ..setTransform(mat); |
279 | 284 | ||
285 | + if (_context.lastLine == 0) { | ||
286 | + return; | ||
287 | + } | ||
288 | + | ||
280 | int index = 0; | 289 | int index = 0; |
281 | for (TableRow row in children) { | 290 | for (TableRow row in children) { |
282 | if (index++ < _context.firstLine && !row.repeat) { | 291 | if (index++ < _context.firstLine && !row.repeat) { |
@@ -28,6 +28,7 @@ import 'type1_test.dart' as type1; | @@ -28,6 +28,7 @@ import 'type1_test.dart' as type1; | ||
28 | import 'widget_basic_test.dart' as widget_basic; | 28 | import 'widget_basic_test.dart' as widget_basic; |
29 | import 'widget_clip_test.dart' as widget_clip; | 29 | import 'widget_clip_test.dart' as widget_clip; |
30 | import 'widget_container_test.dart' as widget_container; | 30 | import 'widget_container_test.dart' as widget_container; |
31 | +import 'widget_table_test.dart' as widget_table; | ||
31 | import 'widget_test.dart' as widget; | 32 | import 'widget_test.dart' as widget; |
32 | 33 | ||
33 | void main() { | 34 | void main() { |
@@ -42,6 +43,7 @@ void main() { | @@ -42,6 +43,7 @@ void main() { | ||
42 | widget_basic.main(); | 43 | widget_basic.main(); |
43 | widget_clip.main(); | 44 | widget_clip.main(); |
44 | widget_container.main(); | 45 | widget_container.main(); |
46 | + widget_table.main(); | ||
45 | widget.main(); | 47 | widget.main(); |
46 | example.main(); | 48 | example.main(); |
47 | } | 49 | } |
pdf/test/widget_table_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' as math; | ||
19 | + | ||
20 | +import 'package:meta/meta.dart'; | ||
21 | +import 'package:test/test.dart'; | ||
22 | +import 'package:pdf/pdf.dart'; | ||
23 | +import 'package:pdf/widgets.dart'; | ||
24 | + | ||
25 | +Document pdf; | ||
26 | + | ||
27 | +List<TableRow> buildTable( | ||
28 | + {@required Context context, int count = 10, bool repeatHeader = false}) { | ||
29 | + final List<TableRow> rows = <TableRow>[]; | ||
30 | + { | ||
31 | + final List<Widget> tableRow = <Widget>[]; | ||
32 | + for (String cell in <String>['Hue', 'Color', 'ARGB']) { | ||
33 | + tableRow.add(Container( | ||
34 | + alignment: Alignment.center, | ||
35 | + margin: const EdgeInsets.all(5), | ||
36 | + child: Text(cell, style: Theme.of(context).tableHeader))); | ||
37 | + } | ||
38 | + rows.add(TableRow(children: tableRow, repeat: repeatHeader)); | ||
39 | + } | ||
40 | + | ||
41 | + for (int y = 0; y < count; y++) { | ||
42 | + final double h = math.sin(y / count) * 365; | ||
43 | + final PdfColor color = PdfColorHsv(h, 1.0, 1.0); | ||
44 | + final List<Widget> tableRow = <Widget>[ | ||
45 | + Container( | ||
46 | + margin: const EdgeInsets.all(5), | ||
47 | + child: Text('${h.toInt()}°', style: Theme.of(context).tableCell)), | ||
48 | + Container( | ||
49 | + margin: const EdgeInsets.all(5), | ||
50 | + decoration: BoxDecoration(color: color, borderRadius: 5), | ||
51 | + height: Theme.of(context).tableCell.fontSize), | ||
52 | + Container( | ||
53 | + margin: const EdgeInsets.all(5), | ||
54 | + child: Text('${color.toHex()}', style: Theme.of(context).tableCell)), | ||
55 | + ]; | ||
56 | + rows.add(TableRow(children: tableRow)); | ||
57 | + } | ||
58 | + | ||
59 | + return rows; | ||
60 | +} | ||
61 | + | ||
62 | +void main() { | ||
63 | + setUpAll(() { | ||
64 | + Document.debug = true; | ||
65 | + pdf = Document(); | ||
66 | + }); | ||
67 | + | ||
68 | + test('Table Widget empty', () { | ||
69 | + pdf.addPage(Page( | ||
70 | + build: (Context context) => Table(), | ||
71 | + )); | ||
72 | + }); | ||
73 | + | ||
74 | + test('Table Widget filled', () { | ||
75 | + pdf.addPage(Page( | ||
76 | + build: (Context context) => Table( | ||
77 | + children: buildTable(context: context, count: 20), | ||
78 | + border: const TableBorder(), | ||
79 | + tableWidth: TableWidth.max, | ||
80 | + ), | ||
81 | + )); | ||
82 | + }); | ||
83 | + | ||
84 | + test('Table Widget multi-pages', () { | ||
85 | + pdf.addPage(MultiPage( | ||
86 | + build: (Context context) => <Widget>[ | ||
87 | + Table( | ||
88 | + children: buildTable(context: context, count: 200), | ||
89 | + border: const TableBorder(), | ||
90 | + tableWidth: TableWidth.max, | ||
91 | + ), | ||
92 | + ])); | ||
93 | + }); | ||
94 | + | ||
95 | + test('Table Widget multi-pages with header', () { | ||
96 | + pdf.addPage(MultiPage( | ||
97 | + build: (Context context) => <Widget>[ | ||
98 | + Table( | ||
99 | + children: buildTable( | ||
100 | + context: context, count: 200, repeatHeader: true), | ||
101 | + border: const TableBorder(), | ||
102 | + tableWidth: TableWidth.max, | ||
103 | + ), | ||
104 | + ])); | ||
105 | + }); | ||
106 | + | ||
107 | + test('Table Widget multi-pages short', () { | ||
108 | + pdf.addPage(MultiPage( | ||
109 | + build: (Context context) => <Widget>[ | ||
110 | + SizedBox(height: 710), | ||
111 | + Table( | ||
112 | + children: buildTable(context: context, count: 4), | ||
113 | + border: const TableBorder(), | ||
114 | + tableWidth: TableWidth.max, | ||
115 | + ), | ||
116 | + ])); | ||
117 | + }); | ||
118 | + | ||
119 | + test('Table Widget multi-pages short header', () { | ||
120 | + pdf.addPage(MultiPage( | ||
121 | + build: (Context context) => <Widget>[ | ||
122 | + SizedBox(height: 710), | ||
123 | + Table( | ||
124 | + children: | ||
125 | + buildTable(context: context, count: 4, repeatHeader: true), | ||
126 | + border: const TableBorder(), | ||
127 | + tableWidth: TableWidth.max, | ||
128 | + ), | ||
129 | + ])); | ||
130 | + }); | ||
131 | + | ||
132 | + tearDownAll(() { | ||
133 | + final File file = File('widgets-table.pdf'); | ||
134 | + file.writeAsBytesSync(pdf.save()); | ||
135 | + }); | ||
136 | +} |
-
Please register or login to post a comment