Showing
5 changed files
with
73 additions
and
11 deletions
| @@ -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( |
-
Please register or login to post a comment