David PHAM-VAN

Set a proper value to context.pagesCount

@@ -6,6 +6,7 @@ @@ -6,6 +6,7 @@
6 * Fix RichText Widget word spacing 6 * Fix RichText Widget word spacing
7 * Improve Theme and TextStyle 7 * Improve Theme and TextStyle
8 * Implement properly RichText.softWrap 8 * Implement properly RichText.softWrap
  9 +* Set a proper value to context.pagesCount
9 10
10 # 1.3.7 11 # 1.3.7
11 * Add Pdf Creation date 12 * Add Pdf Creation date
@@ -30,7 +30,7 @@ void main() { @@ -30,7 +30,7 @@ void main() {
30 return Container( 30 return Container(
31 alignment: Alignment.centerRight, 31 alignment: Alignment.centerRight,
32 margin: const EdgeInsets.only(top: 1.0 * PdfPageFormat.cm), 32 margin: const EdgeInsets.only(top: 1.0 * PdfPageFormat.cm),
33 - child: Text('Page ${context.pageNumber}', 33 + child: Text('Page ${context.pageNumber} of ${context.pagesCount}',
34 style: Theme.of(context) 34 style: Theme.of(context)
35 .defaultTextStyle 35 .defaultTextStyle
36 .copyWith(color: PdfColors.grey))); 36 .copyWith(color: PdfColors.grey)));
@@ -50,11 +50,19 @@ class Document { @@ -50,11 +50,19 @@ class Document {
50 50
51 final Theme theme; 51 final Theme theme;
52 52
  53 + final List<Page> _pages = <Page>[];
  54 +
53 void addPage(Page page) { 55 void addPage(Page page) {
54 page.generate(this); 56 page.generate(this);
  57 + _pages.add(page);
55 } 58 }
56 59
57 - List<int> save() => document.save(); 60 + List<int> save() {
  61 + for (Page page in _pages) {
  62 + page.postProcess(this);
  63 + }
  64 + return document.save();
  65 + }
58 } 66 }
59 67
60 typedef BuildCallback = Widget Function(Context context); 68 typedef BuildCallback = Widget Function(Context context);
@@ -63,7 +71,7 @@ typedef BuildListCallback = List<Widget> Function(Context context); @@ -63,7 +71,7 @@ typedef BuildListCallback = List<Widget> Function(Context context);
63 enum PageOrientation { natural, landscape, portrait } 71 enum PageOrientation { natural, landscape, portrait }
64 72
65 class Page { 73 class Page {
66 - const Page( 74 + Page(
67 {this.pageFormat = PdfPageFormat.standard, 75 {this.pageFormat = PdfPageFormat.standard,
68 BuildCallback build, 76 BuildCallback build,
69 this.theme, 77 this.theme,
@@ -89,6 +97,8 @@ class Page { @@ -89,6 +97,8 @@ class Page {
89 (orientation == PageOrientation.portrait && 97 (orientation == PageOrientation.portrait &&
90 pageFormat.width > pageFormat.height); 98 pageFormat.width > pageFormat.height);
91 99
  100 + PdfPage _pdfPage;
  101 +
92 EdgeInsets get margin { 102 EdgeInsets get margin {
93 if (_margin != null) { 103 if (_margin != null) {
94 if (mustRotate) { 104 if (mustRotate) {
@@ -127,8 +137,12 @@ class Page { @@ -127,8 +137,12 @@ class Page {
127 137
128 @protected 138 @protected
129 void generate(Document document) { 139 void generate(Document document) {
130 - final PdfPage pdfPage = PdfPage(document.document, pageFormat: pageFormat);  
131 - final PdfGraphics canvas = pdfPage.getGraphics(); 140 + _pdfPage = PdfPage(document.document, pageFormat: pageFormat);
  141 + }
  142 +
  143 + @protected
  144 + void postProcess(Document document) {
  145 + final PdfGraphics canvas = _pdfPage.getGraphics();
132 final EdgeInsets _margin = margin; 146 final EdgeInsets _margin = margin;
133 final BoxConstraints constraints = mustRotate 147 final BoxConstraints constraints = mustRotate
134 ? BoxConstraints( 148 ? BoxConstraints(
@@ -143,7 +157,7 @@ class Page { @@ -143,7 +157,7 @@ class Page {
143 inherited[calculatedTheme.runtimeType] = calculatedTheme; 157 inherited[calculatedTheme.runtimeType] = calculatedTheme;
144 final Context context = Context( 158 final Context context = Context(
145 document: document.document, 159 document: document.document,
146 - page: pdfPage, 160 + page: _pdfPage,
147 canvas: canvas, 161 canvas: canvas,
148 inherited: inherited); 162 inherited: inherited);
149 if (_build != null) { 163 if (_build != null) {
@@ -36,8 +36,19 @@ class NewPage extends Widget { @@ -36,8 +36,19 @@ class NewPage extends Widget {
36 } 36 }
37 } 37 }
38 38
  39 +class _MultiPageInstance {
  40 + const _MultiPageInstance(
  41 + {@required this.context,
  42 + @required this.constraints,
  43 + @required this.offsetStart});
  44 +
  45 + final Context context;
  46 + final BoxConstraints constraints;
  47 + final double offsetStart;
  48 +}
  49 +
39 class MultiPage extends Page { 50 class MultiPage extends Page {
40 - const MultiPage( 51 + MultiPage(
41 {PdfPageFormat pageFormat = PdfPageFormat.a4, 52 {PdfPageFormat pageFormat = PdfPageFormat.a4,
42 BuildListCallback build, 53 BuildListCallback build,
43 this.crossAxisAlignment = CrossAxisAlignment.start, 54 this.crossAxisAlignment = CrossAxisAlignment.start,
@@ -61,6 +72,8 @@ class MultiPage extends Page { @@ -61,6 +72,8 @@ class MultiPage extends Page {
61 72
62 final BuildCallback footer; 73 final BuildCallback footer;
63 74
  75 + final List<_MultiPageInstance> _pages = <_MultiPageInstance>[];
  76 +
64 void _paintChild( 77 void _paintChild(
65 Context context, Widget child, double x, double y, double pageHeight) { 78 Context context, Widget child, double x, double y, double pageHeight) {
66 if (mustRotate) { 79 if (mustRotate) {
@@ -139,13 +152,17 @@ class MultiPage extends Page { @@ -139,13 +152,17 @@ class MultiPage extends Page {
139 offsetEnd = 152 offsetEnd =
140 _mustRotate ? pageHeightMargin - _margin.left : _margin.bottom; 153 _mustRotate ? pageHeightMargin - _margin.left : _margin.bottom;
141 154
  155 + _pages.add(_MultiPageInstance(
  156 + context: context,
  157 + constraints: constraints,
  158 + offsetStart: offsetStart,
  159 + ));
  160 +
142 if (header != null) { 161 if (header != null) {
143 final Widget headerWidget = header(context); 162 final Widget headerWidget = header(context);
144 if (headerWidget != null) { 163 if (headerWidget != null) {
145 headerWidget.layout(context, constraints, parentUsesSize: false); 164 headerWidget.layout(context, constraints, parentUsesSize: false);
146 assert(headerWidget.box != null); 165 assert(headerWidget.box != null);
147 - _paintChild(context, headerWidget, _margin.left,  
148 - offsetStart - headerWidget.box.height, pageFormat.height);  
149 offsetStart -= headerWidget.box.height; 166 offsetStart -= headerWidget.box.height;
150 } 167 }
151 } 168 }
@@ -155,8 +172,6 @@ class MultiPage extends Page { @@ -155,8 +172,6 @@ class MultiPage extends Page {
155 if (footerWidget != null) { 172 if (footerWidget != null) {
156 footerWidget.layout(context, constraints, parentUsesSize: false); 173 footerWidget.layout(context, constraints, parentUsesSize: false);
157 assert(footerWidget.box != null); 174 assert(footerWidget.box != null);
158 - _paintChild(context, footerWidget, _margin.left, _margin.bottom,  
159 - pageFormat.height);  
160 offsetEnd += footerWidget.box.height; 175 offsetEnd += footerWidget.box.height;
161 } 176 }
162 } 177 }
@@ -218,4 +233,33 @@ class MultiPage extends Page { @@ -218,4 +233,33 @@ class MultiPage extends Page {
218 index++; 233 index++;
219 } 234 }
220 } 235 }
  236 +
  237 + @override
  238 + void postProcess(Document document) {
  239 + final EdgeInsets _margin = margin;
  240 +
  241 + for (_MultiPageInstance page in _pages) {
  242 + if (header != null) {
  243 + final Widget headerWidget = header(page.context);
  244 + if (headerWidget != null) {
  245 + headerWidget.layout(page.context, page.constraints,
  246 + parentUsesSize: false);
  247 + assert(headerWidget.box != null);
  248 + _paintChild(page.context, headerWidget, _margin.left,
  249 + page.offsetStart - headerWidget.box.height, pageFormat.height);
  250 + }
  251 + }
  252 +
  253 + if (footer != null) {
  254 + final Widget footerWidget = footer(page.context);
  255 + if (footerWidget != null) {
  256 + footerWidget.layout(page.context, page.constraints,
  257 + parentUsesSize: false);
  258 + assert(footerWidget.box != null);
  259 + _paintChild(page.context, footerWidget, _margin.left, _margin.bottom,
  260 + pageFormat.height);
  261 + }
  262 + }
  263 + }
  264 + }
221 } 265 }
@@ -36,6 +36,9 @@ class Context { @@ -36,6 +36,9 @@ class Context {
36 36
37 int get pageNumber => document.pdfPageList.pages.indexOf(page) + 1; 37 int get pageNumber => document.pdfPageList.pages.indexOf(page) + 1;
38 38
  39 + /// Number of pages in the document.
  40 + /// This value is not available in a MultiPage body and will be equal to pageNumber.
  41 + /// But can be used in Header and Footer.
39 int get pagesCount => document.pdfPageList.pages.length; 42 int get pagesCount => document.pdfPageList.pages.length;
40 43
41 Context copyWith( 44 Context copyWith(