David PHAM-VAN

Passthrough SpanningWidget on SingleChildWidget and StatelessWidget

... ... @@ -26,8 +26,8 @@ Future<Uint8List> generateDocument(
final doc = pw.Document(pageMode: PdfPageMode.outlines);
doc.addPage(pw.MultiPage(
pageFormat:
PdfPageFormat.letter.copyWith(marginBottom: 1.5 * PdfPageFormat.cm),
pageFormat: format.copyWith(marginBottom: 1.5 * PdfPageFormat.cm),
orientation: pw.PageOrientation.portrait,
crossAxisAlignment: pw.CrossAxisAlignment.start,
header: (pw.Context context) {
if (context.pageNumber == 1) {
... ...
... ... @@ -10,6 +10,7 @@
- ImageProvider.resolve returns non-null object
- Fix textScalingFactor with lineSpacing
- Implement SpanningWidget on RichText
- Passthrough SpanningWidget on SingleChildWidget and StatelessWidget
## 3.2.0
... ...
... ... @@ -133,12 +133,13 @@ class Header extends StatelessWidget {
}
class Paragraph extends StatelessWidget {
Paragraph(
{this.text,
Paragraph({
this.text,
this.textAlign = TextAlign.justify,
this.style,
this.margin = const EdgeInsets.only(bottom: 5.0 * PdfPageFormat.mm),
this.padding});
this.padding,
});
final String? text;
... ... @@ -159,6 +160,7 @@ class Paragraph extends StatelessWidget {
text!,
textAlign: textAlign,
style: style ?? Theme.of(context).paragraphStyle,
overflow: TextOverflow.span,
),
);
}
... ...
... ... @@ -81,7 +81,7 @@ class _FlexContext extends WidgetContext {
String toString() => '$runtimeType first:$firstChild last:$lastChild';
}
class Flex extends MultiChildWidget implements SpanningWidget {
class Flex extends MultiChildWidget with SpanningWidget {
Flex({
required this.direction,
this.mainAxisAlignment = MainAxisAlignment.start,
... ...
... ... @@ -53,7 +53,7 @@ class _GridViewContext extends WidgetContext {
'$runtimeType first:$firstChild last:$lastChild size:${childCrossAxis}x$childMainAxis';
}
class GridView extends MultiChildWidget implements SpanningWidget {
class GridView extends MultiChildWidget with SpanningWidget {
GridView(
{this.direction = Axis.vertical,
this.padding = EdgeInsets.zero,
... ...
... ... @@ -37,7 +37,7 @@ abstract class WidgetContext {
void apply(covariant WidgetContext other);
}
abstract class SpanningWidget extends Widget {
mixin SpanningWidget on Widget {
bool get canSpan;
bool get hasMoreWidgets;
... ... @@ -46,7 +46,7 @@ abstract class SpanningWidget extends Widget {
@protected
WidgetContext saveContext();
/// Aplpy the context for next layout
/// Apply the context for next layout
@protected
void restoreContext(covariant WidgetContext context);
}
... ... @@ -230,10 +230,6 @@ class MultiPage extends Page {
while (_index < children.length) {
final child = children[_index];
var canSpan = false;
if (child is SpanningWidget) {
canSpan = child.canSpan;
}
assert(() {
// Detect too big widgets
... ... @@ -292,7 +288,7 @@ class MultiPage extends Page {
}
// If we are processing a multi-page widget, we restore its context
if (widgetContext != null && canSpan && child is SpanningWidget) {
if (widgetContext != null && child is SpanningWidget) {
child.restoreContext(widgetContext);
widgetContext = null;
}
... ... @@ -300,6 +296,8 @@ class MultiPage extends Page {
child.layout(context, constraints, parentUsesSize: false);
assert(child.box != null);
final canSpan = child is SpanningWidget && child.canSpan;
// What to do if the widget is too big for the page?
if (offsetStart! - child.box!.height < offsetEnd) {
// If it is not a multi-page widget and its height
... ... @@ -475,7 +473,8 @@ class MultiPage extends Page {
final flex = child is Flexible ? child.flex : 0;
final fit = child is Flexible ? child.fit : FlexFit.loose;
if (flex > 0) {
assert(child is! SpanningWidget);
assert(child is! SpanningWidget || child.canSpan == false,
'Cannot have a spanning widget flexible');
final maxChildExtent = child == lastFlexChild
? (freeSpace - allocatedFlexSpace)
: spacePerFlex * flex;
... ...
... ... @@ -24,7 +24,7 @@ import 'geometry.dart';
import 'multi_page.dart';
import 'widget.dart';
class Partition implements SpanningWidget {
class Partition extends Widget with SpanningWidget {
Partition({
required this.child,
this.width,
... ... @@ -59,6 +59,7 @@ class Partition implements SpanningWidget {
@override
void paint(Context context) {
super.paint(context);
child.paint(context);
}
... ... @@ -102,7 +103,7 @@ class _PartitionsContext extends WidgetContext {
}
}
class Partitions extends Widget implements SpanningWidget {
class Partitions extends Widget with SpanningWidget {
Partitions({
required this.children,
this.mainAxisSize = MainAxisSize.max,
... ...
... ... @@ -236,7 +236,7 @@ typedef OnCellDecoration = BoxDecoration Function(
int index, dynamic data, int rowNum);
/// A widget that uses the table layout algorithm for its children.
class Table extends Widget implements SpanningWidget {
class Table extends Widget with SpanningWidget {
Table({
this.children = const <TableRow>[],
this.border,
... ...
... ... @@ -575,7 +575,7 @@ class _RichTextContext extends WidgetContext {
'$runtimeType Offset: $startOffset -> $endOffset Span: $spanStart -> $spanEnd';
}
class RichText extends Widget implements SpanningWidget {
class RichText extends Widget with SpanningWidget {
RichText({
required this.text,
this.textAlign,
... ...
... ... @@ -19,6 +19,7 @@ import 'dart:math' as math;
import 'package:meta/meta.dart';
import 'package:pdf/pdf.dart';
import 'package:pdf/widgets.dart';
import 'package:vector_math/vector_math_64.dart';
import 'document.dart';
... ... @@ -210,7 +211,7 @@ abstract class Widget {
}
}
abstract class StatelessWidget extends Widget {
abstract class StatelessWidget extends Widget with SpanningWidget {
StatelessWidget() : super();
Widget? _child;
... ... @@ -246,9 +247,33 @@ abstract class StatelessWidget extends Widget {
@protected
Widget build(Context context);
@override
bool get canSpan =>
_child is SpanningWidget && (_child as SpanningWidget).canSpan;
@override
bool get hasMoreWidgets =>
_child is SpanningWidget && (_child as SpanningWidget).hasMoreWidgets;
@override
void restoreContext(covariant WidgetContext context) {
if (_child is SpanningWidget) {
(_child as SpanningWidget).restoreContext(context);
}
}
@override
WidgetContext saveContext() {
if (_child is SpanningWidget) {
return (_child as SpanningWidget).saveContext();
}
throw UnimplementedError();
}
}
abstract class SingleChildWidget extends Widget {
abstract class SingleChildWidget extends Widget with SpanningWidget {
SingleChildWidget({this.child}) : super();
final Widget? child;
... ... @@ -277,6 +302,30 @@ abstract class SingleChildWidget extends Widget {
context.canvas.restoreContext();
}
}
@override
bool get canSpan =>
child is SpanningWidget && (child as SpanningWidget).canSpan;
@override
bool get hasMoreWidgets =>
child is SpanningWidget && (child as SpanningWidget).hasMoreWidgets;
@override
void restoreContext(covariant WidgetContext context) {
if (child is SpanningWidget) {
(child as SpanningWidget).restoreContext(context);
}
}
@override
WidgetContext saveContext() {
if (child is SpanningWidget) {
return (child as SpanningWidget).saveContext();
}
throw UnimplementedError();
}
}
abstract class MultiChildWidget extends Widget {
... ... @@ -285,8 +334,8 @@ abstract class MultiChildWidget extends Widget {
final List<Widget> children;
}
class InheritedWidget extends Widget {
InheritedWidget({this.build, this.inherited});
class InheritedWidget extends SingleChildWidget {
InheritedWidget({this.build, this.inherited}) : super();
final BuildCallback? build;
... ... @@ -294,6 +343,9 @@ class InheritedWidget extends Widget {
Context? _context;
@override
Widget? get child => _child;
Widget? _child;
@override
... ... @@ -301,29 +353,13 @@ class InheritedWidget extends Widget {
{bool parentUsesSize = false}) {
_context = inherited != null ? context.inheritFrom(inherited!) : 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);
}
super.layout(_context!, constraints);
}
@override
void paint(Context context) {
assert(_context != null);
super.paint(_context!);
if (_child != null) {
final mat = Matrix4.identity();
mat.translate(box!.x, box!.y);
context.canvas
..saveContext()
..setTransform(mat);
_child!.paint(_context!);
context.canvas.restoreContext();
}
paintChild(_context!);
}
}
... ...
... ... @@ -67,7 +67,7 @@ class _WrapContext extends WidgetContext {
}
/// A widget that displays its children in multiple horizontal or vertical runs.
class Wrap extends MultiChildWidget implements SpanningWidget {
class Wrap extends MultiChildWidget with SpanningWidget {
/// Creates a wrap layout.
Wrap({
... ...