David PHAM-VAN

Implement InheritedWidget

... ... @@ -4,6 +4,7 @@
- Implement InlineSpan and WidgetSpan
- Fix Theme.withFont factory
- Implement InheritedWidget
## 1.3.17
... ...
... ... @@ -16,6 +16,7 @@
library widget;
import 'dart:collection';
import 'dart:math' as math;
import 'dart:typed_data';
... ...
... ... @@ -158,13 +158,11 @@ class Page {
maxHeight: pageFormat.height - _margin.vertical);
final Theme calculatedTheme = theme ?? document.theme ?? Theme.base();
final Map<Type, Inherited> inherited = <Type, Inherited>{};
inherited[calculatedTheme.runtimeType] = calculatedTheme;
final Context context = Context(
document: document.document,
page: _pdfPage,
canvas: canvas,
inherited: inherited);
).inheritFrom(calculatedTheme);
if (_build != null) {
final Widget child = _build(context);
layout(child, context, constraints);
... ...
... ... @@ -113,15 +113,13 @@ class MultiPage extends Page {
? (pageFormat.height - _margin.vertical)
: (pageFormat.width - _margin.horizontal));
final Theme calculatedTheme = theme ?? document.theme ?? Theme.base();
final Map<Type, Inherited> inherited = <Type, Inherited>{};
inherited[calculatedTheme.runtimeType] = calculatedTheme;
Context context;
double offsetEnd;
double offsetStart;
int index = 0;
int sameCount = 0;
final Context baseContext =
Context(document: document.document, inherited: inherited);
Context(document: document.document).inheritFrom(calculatedTheme);
final List<Widget> children = _buildList(baseContext);
WidgetContext widgetContext;
... ...
... ... @@ -18,7 +18,19 @@ part of widget;
@immutable
class Context {
const Context({
factory Context({
@required PdfDocument document,
PdfPage page,
PdfGraphics canvas,
}) =>
Context._(
document: document,
page: page,
canvas: canvas,
inherited: HashMap<Type, Inherited>(),
);
const Context._({
@required this.document,
this.page,
this.canvas,
... ... @@ -30,7 +42,7 @@ class Context {
final PdfGraphics canvas;
final Map<Type, Inherited> inherited;
final HashMap<Type, Inherited> inherited;
final PdfDocument document;
... ... @@ -45,8 +57,8 @@ class Context {
{PdfPage page,
PdfGraphics canvas,
Matrix4 ctm,
Map<Type, Inherited> inherited}) {
return Context(
HashMap<Type, Inherited> inherited}) {
return Context._(
document: document,
page: page ?? this.page,
canvas: canvas ?? this.canvas,
... ... @@ -54,7 +66,8 @@ class Context {
}
Context inheritFrom(Inherited object) {
final Map<Type, Inherited> inherited = this.inherited;
final HashMap<Type, Inherited> inherited =
HashMap<Type, Inherited>.of(this.inherited);
inherited[object.runtimeType] = object;
return copyWith(inherited: inherited);
}
... ... @@ -172,3 +185,53 @@ abstract class MultiChildWidget extends Widget {
final List<Widget> children;
}
class InheritedWidget extends Widget {
InheritedWidget({this.build, this.inherited});
final BuildCallback build;
final Inherited inherited;
Context _context;
Widget _child;
@override
void layout(Context context, BoxConstraints constraints,
{bool parentUsesSize = false}) {
if (_context == null) {
// final Inherited inherited = build(context);
if (inherited != null) {
_context = context.inheritFrom(inherited);
}
}
_context ??= context;
_child ??= build(_context);
if (_child != null) {
_child.layout(_context, constraints, parentUsesSize: parentUsesSize);
assert(_child.box != null);
box = _child.box;
} else {
box = PdfRect.fromPoints(PdfPoint.zero, constraints.smallest);
}
}
@override
void paint(Context context) {
assert(_context != null);
super.paint(_context);
if (_child != null) {
final Matrix4 mat = Matrix4.identity();
mat.translate(box.x, box.y);
context.canvas
..saveContext()
..setTransform(mat);
_child.paint(_context);
context.canvas.restoreContext();
}
}
}
... ...
... ... @@ -70,6 +70,53 @@ void main() {
));
});
test('Theme Page 1', () {
final Theme theme = Theme.withFont(base: roboto);
pdf.addPage(Page(
theme: theme,
build: (Context context) => Center(
child: Text('Hello'),
),
));
});
test('Theme Page 2', () {
final Theme theme = Theme.base().copyWith(
tableHeader: TextStyle(font: openSansBold),
tableCell: TextStyle(font: roboto),
);
pdf.addPage(Page(
theme: theme,
build: (Context context) => Center(
child: Table.fromTextArray(context: context, data: [
['Header', '123'],
['Cell', '456']
]),
),
));
});
test('Theme Page 3', () {
pdf.addPage(Page(
build: (Context context) => Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: <Widget>[
Text('Hello default'),
InheritedWidget(
inherited: Theme.withFont(
base: roboto,
),
build: (Context context) => Text('Hello themed'),
),
],
),
),
));
});
tearDownAll(() {
final File file = File('widgets-theme.pdf');
file.writeAsBytesSync(pdf.save());
... ...