David PHAM-VAN

Add PageTheme

... ... @@ -4,6 +4,7 @@
- Fix Transform.rotateBox
- Add Watermark widget
- Add PageTheme
## 1.3.19
... ...
... ... @@ -37,6 +37,7 @@ part 'widgets/grid_view.dart';
part 'widgets/image.dart';
part 'widgets/multi_page.dart';
part 'widgets/page.dart';
part 'widgets/page_theme.dart';
part 'widgets/placeholders.dart';
part 'widgets/progress.dart';
part 'widgets/stack.dart';
... ...
... ... @@ -40,27 +40,31 @@ class _MultiPageInstance {
const _MultiPageInstance(
{@required this.context,
@required this.constraints,
@required this.fullConstraints,
@required this.offsetStart});
final Context context;
final BoxConstraints constraints;
final BoxConstraints fullConstraints;
final double offsetStart;
}
class MultiPage extends Page {
MultiPage(
{PdfPageFormat pageFormat = PdfPageFormat.a4,
{PageTheme pageTheme,
PdfPageFormat pageFormat,
BuildListCallback build,
this.crossAxisAlignment = CrossAxisAlignment.start,
this.header,
this.footer,
Theme theme,
this.maxPages = 20,
PageOrientation orientation = PageOrientation.natural,
PageOrientation orientation,
EdgeInsets margin})
: _buildList = build,
assert(maxPages != null && maxPages > 0),
super(
pageTheme: pageTheme,
pageFormat: pageFormat,
margin: margin,
theme: theme,
... ... @@ -88,6 +92,7 @@ class MultiPage extends Page {
..rotateZ(-math.pi / 2)
..translate(x - pageHeight + _margin.top - _margin.left,
y + _margin.left - _margin.bottom));
child.paint(context);
context.canvas.restoreContext();
} else {
... ... @@ -112,6 +117,13 @@ class MultiPage extends Page {
maxWidth: _mustRotate
? (pageFormat.height - _margin.vertical)
: (pageFormat.width - _margin.horizontal));
final BoxConstraints fullConstraints = mustRotate
? BoxConstraints(
maxWidth: pageFormat.height - _margin.vertical,
maxHeight: pageFormat.width - _margin.horizontal)
: BoxConstraints(
maxWidth: pageFormat.width - _margin.horizontal,
maxHeight: pageFormat.height - _margin.vertical);
final Theme calculatedTheme = theme ?? document.theme ?? Theme.base();
Context context;
double offsetEnd;
... ... @@ -149,6 +161,16 @@ class MultiPage extends Page {
return true;
}());
if (pageTheme.buildBackground != null) {
final Widget child = pageTheme.buildBackground(context);
if (child != null) {
child.layout(context, fullConstraints, parentUsesSize: false);
assert(child.box != null);
_paintChild(context, child, _margin.left, _margin.bottom,
pageFormat.height);
}
}
offsetStart = pageHeight -
(_mustRotate ? pageHeightMargin - margin.bottom : _margin.top);
offsetEnd =
... ... @@ -157,6 +179,7 @@ class MultiPage extends Page {
_pages.add(_MultiPageInstance(
context: context,
constraints: constraints,
fullConstraints: fullConstraints,
offsetStart: offsetStart,
));
... ... @@ -262,6 +285,17 @@ class MultiPage extends Page {
pageFormat.height);
}
}
if (pageTheme.buildForeground != null) {
final Widget child = pageTheme.buildForeground(page.context);
if (child != null) {
child.layout(page.context, page.fullConstraints,
parentUsesSize: false);
assert(child.box != null);
_paintChild(page.context, child, _margin.left, _margin.bottom,
pageFormat.height);
}
}
}
}
}
... ...
... ... @@ -23,51 +23,43 @@ enum PageOrientation { natural, landscape, portrait }
class Page {
Page(
{this.pageFormat = PdfPageFormat.standard,
{PageTheme pageTheme,
PdfPageFormat pageFormat,
BuildCallback build,
this.theme,
this.orientation = PageOrientation.natural,
Theme theme,
PageOrientation orientation,
EdgeInsets margin})
: assert(pageFormat != null),
_margin = margin,
: assert(
pageTheme == null ||
(pageFormat == null &&
theme == null &&
orientation == null &&
margin == null),
'Don\'t set both pageTheme and other settings'),
pageTheme = pageTheme ??
PageTheme(
pageFormat: pageFormat,
orientation: orientation,
margin: margin,
theme: theme,
),
_build = build;
final PdfPageFormat pageFormat;
final PageTheme pageTheme;
final PageOrientation orientation;
PdfPageFormat get pageFormat => pageTheme.pageFormat;
final EdgeInsets _margin;
PageOrientation get orientation => pageTheme.orientation;
final BuildCallback _build;
final Theme theme;
Theme get theme => pageTheme.theme;
bool get mustRotate =>
(orientation == PageOrientation.landscape &&
pageFormat.height > pageFormat.width) ||
(orientation == PageOrientation.portrait &&
pageFormat.width > pageFormat.height);
bool get mustRotate => pageTheme.mustRotate;
PdfPage _pdfPage;
EdgeInsets get margin {
if (_margin != null) {
if (mustRotate) {
return EdgeInsets.fromLTRB(
_margin.bottom, _margin.left, _margin.top, _margin.right);
} else {
return _margin;
}
}
if (mustRotate) {
return EdgeInsets.fromLTRB(pageFormat.marginBottom, pageFormat.marginLeft,
pageFormat.marginTop, pageFormat.marginRight);
} else {
return EdgeInsets.fromLTRB(pageFormat.marginLeft, pageFormat.marginTop,
pageFormat.marginRight, pageFormat.marginBottom);
}
}
EdgeInsets get margin => pageTheme.margin;
@protected
void debugPaint(Context context) {
... ... @@ -109,10 +101,26 @@ class Page {
page: _pdfPage,
canvas: canvas,
).inheritFrom(calculatedTheme);
if (pageTheme.buildBackground != null) {
final Widget child = pageTheme.buildBackground(context);
if (child != null) {
layout(child, context, constraints);
paint(child, context);
}
}
if (_build != null) {
final Widget child = _build(context);
layout(child, context, constraints);
paint(child, context);
if (child != null) {
layout(child, context, constraints);
paint(child, context);
}
}
if (pageTheme.buildForeground != null) {
final Widget child = pageTheme.buildForeground(context);
if (child != null) {
layout(child, context, constraints);
paint(child, context);
}
}
}
... ...
/*
* Copyright (C) 2017, David PHAM-VAN <dev.nfet.net@gmail.com>
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
part of widget;
@immutable
class PageTheme {
const PageTheme(
{PdfPageFormat pageFormat,
this.buildBackground,
this.buildForeground,
this.theme,
PageOrientation orientation,
EdgeInsets margin})
: pageFormat = pageFormat ?? PdfPageFormat.standard,
orientation = orientation ?? PageOrientation.natural,
_margin = margin;
final PdfPageFormat pageFormat;
final PageOrientation orientation;
final EdgeInsets _margin;
final BuildCallback buildBackground;
final BuildCallback buildForeground;
final Theme theme;
bool get mustRotate =>
(orientation == PageOrientation.landscape &&
pageFormat.height > pageFormat.width) ||
(orientation == PageOrientation.portrait &&
pageFormat.width > pageFormat.height);
EdgeInsets get margin {
if (_margin != null) {
if (mustRotate) {
return EdgeInsets.fromLTRB(
_margin.bottom, _margin.left, _margin.top, _margin.right);
} else {
return _margin;
}
}
if (mustRotate) {
return EdgeInsets.fromLTRB(pageFormat.marginBottom, pageFormat.marginLeft,
pageFormat.marginTop, pageFormat.marginRight);
} else {
return EdgeInsets.fromLTRB(pageFormat.marginLeft, pageFormat.marginTop,
pageFormat.marginRight, pageFormat.marginBottom);
}
}
}
... ...
... ... @@ -34,6 +34,7 @@ import 'widget_table_test.dart' as widget_table;
import 'widget_test.dart' as widget;
import 'widget_text_test.dart' as widget_text;
import 'widget_theme_test.dart' as widget_theme;
import 'widget_watermark_test.dart' as widget_watermark;
import 'widget_wrap_test.dart' as widget_wrap;
void main() {
... ... @@ -54,6 +55,7 @@ void main() {
widget_table.main();
widget_text.main();
widget_theme.main();
widget_watermark.main();
widget_wrap.main();
widget.main();
}
... ...
/*
* Copyright (C) 2017, David PHAM-VAN <dev.nfet.net@gmail.com>
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import 'dart:io';
import 'package:pdf/widgets.dart';
import 'package:test/test.dart';
void main() {
test('Pdf Widgets Watermark', () {
Document.debug = true;
final Document pdf = Document();
final PageTheme pageTheme = PageTheme(
buildBackground: (Context context) => Watermark.text('DRAFT'),
buildForeground: (Context context) => Align(
alignment: Alignment.bottomLeft,
child: SizedBox(
width: 100,
height: 100,
child: PdfLogo(),
),
),
);
pdf.addPage(
Page(
pageTheme: pageTheme,
build: (Context context) => Center(
child: Text(
'Hello World',
),
),
),
);
pdf.addPage(
MultiPage(
pageTheme: pageTheme,
build: (Context context) => List<Widget>.filled(
100,
Text(
'Hello World',
),
),
),
);
final File file = File('widgets-watermark.pdf');
file.writeAsBytesSync(pdf.save());
});
}
... ...