Browse Source

Table: improved repeating+paging support, added example

Marcin Ziąbek 4 years ago
parent
commit
8020cb30cb

+ 53 - 0
QuestPDF.Examples/DefaultTextStyleExamples.cs

@@ -0,0 +1,53 @@
+using System.Drawing;
+using System.Linq;
+using NUnit.Framework;
+using QuestPDF.Examples.Engine;
+using QuestPDF.Fluent;
+using QuestPDF.Helpers;
+using QuestPDF.Infrastructure;
+
+namespace QuestPDF.Examples
+{
+    public class DefaultTextStyleExamples
+    {
+        [Test]
+        public void Placeholder()
+        {
+            RenderingTest
+                .Create()
+                .PageSize(220, 270)
+                .ProduceImages()
+                .ShowResults()
+                .EnableDebugging()
+                .Render(container =>
+                {
+                    container
+                        .Padding(10)
+                        .DefaultTextStyle(TextStyle.Default.Bold().Underline())
+                        .Stack(stack =>
+                        { 
+                            stack.Item().Text("Default style applies to all children", TextStyle.Default);
+                            stack.Item().Text("You can override certain styles", TextStyle.Default.Underline(false).Color(Colors.Green.Darken2));
+                            
+                            stack.Item().PaddingTop(10).Border(1).Grid(grid =>
+                            {
+                                grid.Columns(4);
+
+                                foreach (var i in Enumerable.Range(1, 16))
+                                {
+                                    grid.Item()
+                                        .Border(1)
+                                        .BorderColor(Colors.Grey.Lighten1)
+                                        .Background(Colors.Grey.Lighten3)
+                                        .Width(50)
+                                        .Height(50)
+                                        .AlignCenter()
+                                        .AlignMiddle()
+                                        .Text(i, TextStyle.Default.Size(16 + i / 4));   
+                                }
+                            });
+                        });
+                });
+        }
+    }
+}

+ 90 - 27
QuestPDF.Examples/TableExamples.cs

@@ -17,43 +17,57 @@ namespace QuestPDF.Examples
     public class TableExamples
     {
         [Test]
-        public void Simple()
+        public void BasicPlacement()
         {
             RenderingTest
                 .Create()
                 .ProduceImages()
-                .PageSize(320, 100)
+                .PageSize(220, 220)
                 .ShowResults()
                 .Render(container =>
                 {
                     container
                         .Padding(10)
+                        .Box()
+                        .Border(1)
                         .Table(table =>
                         {
                             table.ColumnsDefinition(columns =>
                             {
-                                columns.ConstantColumn(50);
-                                columns.ConstantColumn(100);
-                                columns.RelativeColumn(2);
-                                columns.RelativeColumn(3);
+                                columns.RelativeColumn();
+                                columns.RelativeColumn();
+                                columns.RelativeColumn();
+                                columns.RelativeColumn();
                             });
 
-                            table.Cell().ColumnSpan(4).LabelCell("Total width: 300px");
-                            table.Cell().ValueCell("50px");
-                            table.Cell().ValueCell("100px");
-                            table.Cell().ValueCell("100px");
-                            table.Cell().ValueCell("150px");
+                            // by using the custom element, we can reuse the same style
+                            table.Cell().Row(1).Column(4).Element(x => TextContent(x, "A"));
+                            table.Cell().Row(2).Column(2).Element(x => TextContent(x, "A"));
+                            table.Cell().Row(3).Column(3).Element(x => TextContent(x, "A"));
+                            table.Cell().Row(4).Column(1).Element(x => TextContent(x, "A"));
+
+                            static void TextContent(IContainer container, string text)
+                            {
+                                container
+                                    .Border(1)
+                                    .Background(Colors.Grey.Lighten3)
+                                    .MinWidth(50)
+                                    .MinHeight(50)
+                                    .AlignCenter()
+                                    .AlignMiddle()
+                                    .Text(text);
+                            }
                         });
                 });
         }
         
         [Test]
-        public void BasicPlacement()
+        public void DefaultCellStyle()
         {
             RenderingTest
                 .Create()
                 .ProduceImages()
-                .PageSize(220, 220)
+                .PageSize(220, 120)
                 .ShowResults()
                 .Render(container =>
                 {
@@ -61,6 +75,7 @@ namespace QuestPDF.Examples
                         .Padding(10)
                         .Box()
                         .Border(1)
+                        .DefaultTextStyle(TextStyle.Default.Size(16))
                         .Table(table =>
                         {
                             table.ColumnsDefinition(columns =>
@@ -71,14 +86,56 @@ namespace QuestPDF.Examples
                                 columns.RelativeColumn();
                             });
 
-                            table.Cell().Row(1).Column(4).TextBox("A");
-                            table.Cell().Row(2).Column(2).TextBox("B");
-                            table.Cell().Row(3).Column(3).TextBox("C");
-                            table.Cell().Row(4).Column(1).TextBox("D");
+                            table.DefaultCellStyle(cell =>
+                            {
+                                return cell
+                                    .Border(1)
+                                    .Background(Colors.Grey.Lighten3)
+                                    .MinWidth(50)
+                                    .MinHeight(50)
+                                    .AlignCenter()
+                                    .AlignMiddle();
+                            });
+                            
+                            table.Cell().Row(1).Column(1).Text("A");
+                            table.Cell().Row(2).Column(2).Text("B");
+                            table.Cell().Row(1).Column(3).Text("C");
+                            table.Cell().Row(2).Column(4).Text("D");
                         });
                 });
         }
         
+        [Test]
+        public void ColumnsDefinition()
+        {
+            RenderingTest
+                .Create()
+                .ProduceImages()
+                .PageSize(320, 80)
+                .ShowResults()
+                .Render(container =>
+                {
+                    container
+                        .Padding(10)
+                        .Table(table =>
+                        {
+                            table.ColumnsDefinition(columns =>
+                            {
+                                columns.ConstantColumn(50);
+                                columns.ConstantColumn(100);
+                                columns.RelativeColumn(2);
+                                columns.RelativeColumn(3);
+                            });
+
+                            table.Cell().ColumnSpan(4).LabelCell("Total width: 300px");
+                            table.Cell().ValueCell("50px");
+                            table.Cell().ValueCell("100px");
+                            table.Cell().ValueCell("100px");
+                            table.Cell().ValueCell("150px");
+                        });
+                });
+        }
+
         [Test]
         public void PartialAutoPlacement()
         {
@@ -118,7 +175,7 @@ namespace QuestPDF.Examples
             RenderingTest
                 .Create()
                 .ProduceImages()
-                .PageSize(170, 300)
+                .PageSize(170, 170)
                 .ShowResults()
                 .Render(container =>
                 {
@@ -151,7 +208,7 @@ namespace QuestPDF.Examples
             RenderingTest
                 .Create()
                 .ProduceImages()
-                .PageSize(170, 300)
+                .PageSize(170, 120)
                 .ShowResults()
                 .Render(container =>
                 {
@@ -251,16 +308,20 @@ namespace QuestPDF.Examples
             RenderingTest
                 .Create()
                 .ProduceImages()
-                .PageSize(500, 300)
+                .PageSize(500, 200)
                 .ShowResults()
+                .EnableDebugging()
                 .Render(container =>
                 {
-                    var pageSizes = new List<(string name, float width, float height)>()
+                    var pageSizes = new List<(string name, double width, double height)>()
                     {
-                        ("Letter", 8.5f, 11),
+                        ("Letter (ANSI A)", 8.5f, 11),
                         ("Legal", 8.5f, 14),
-                        ("Ledger", 11, 17),
-                        ("Tabloid", 17, 11),
+                        ("Ledger (ANSI B)", 11, 17),
+                        ("Tabloid (ANSI B)", 17, 11),
+                        ("ANSI C", 22, 17),
+                        ("ANSI D", 34, 22),
+                        ("ANSI E", 44, 34)
                     };
 
                     const int inchesToPoints = 72;
@@ -311,7 +372,7 @@ namespace QuestPDF.Examples
                                         table.Cell().Text(page.height * inchesToPoints);
                                     }
                                 });
-
+   
                             void DefineTableColumns(TableColumnsDefinitionDescriptor columns)
                             {
                                 columns.RelativeColumn();
@@ -343,13 +404,13 @@ namespace QuestPDF.Examples
         {
             RenderingTest
                 .Create()
-                .ProducePdf()
+                .ProduceImages()
                 .PageSize(PageSizes.A4)
                 .MaxPages(10_000)
                 .EnableCaching()
                 .EnableDebugging(false)
                 .ShowResults()
-                .Render(container => GeneratePerformanceStructure(container, 100));
+                .Render(container => GeneratePerformanceStructure(container, 1));
         }
         
         public static void GeneratePerformanceStructure(IContainer container, int repeats)
@@ -369,6 +430,8 @@ namespace QuestPDF.Examples
                         columns.ConstantColumn(100);
                         columns.RelativeColumn();
                     });
+                    
+                    table.ExtendLastCellsToTableBottom();
 
                     foreach (var i in Enumerable.Range(0, repeats))
                     {

+ 12 - 4
QuestPDF/Elements/Table/Table.cs

@@ -92,6 +92,11 @@ namespace QuestPDF.Elements.Table
             }
 
             CurrentRow = FindLastRenderedRow(renderingCommands) + 1;
+            
+            var isFullRender = FindLastRenderedRow(renderingCommands) == StartingRowsCount;
+            
+            if (isFullRender)
+                ResetState();
         }
 
         private int FindLastRenderedRow(ICollection<TableCellRenderingCommand> commands)
@@ -184,7 +189,7 @@ namespace QuestPDF.Elements.Table
                     var topOffset = rowBottomOffsets[cell.Row - 1];
                     
                     var availableWidth = GetCellWidth(cell);
-                    var availableHeight = availableSpace.Height - topOffset + Size.Epsilon;
+                    var availableHeight = availableSpace.Height - topOffset;
                     var availableCellSize = new Size(availableWidth, availableHeight);
 
                     var cellSize = cell.Measure(availableCellSize);
@@ -221,9 +226,12 @@ namespace QuestPDF.Elements.Table
 
                 var maxRow = commands.Select(x => x.Cell).Max(x => x.Row + x.RowSpan);
 
-                foreach (var row in Enumerable.Range(currentRow + 1, maxRow - currentRow))
-                    rowBottomOffsets[row] = rowBottomOffsets[row - 1];
-                
+                if (maxRow > currentRow)
+                {
+                    foreach (var row in Enumerable.Range(currentRow + 1, maxRow - currentRow))
+                        rowBottomOffsets[row] = rowBottomOffsets[row - 1];   
+                }
+
                 AdjustCellSizes(commands, rowBottomOffsets);
                 
                 // corner case: reject cell if other cells within the same row are rejected

+ 2 - 2
QuestPDF/Helpers/Helpers.cs

@@ -46,10 +46,10 @@ namespace QuestPDF.Helpers
 
         internal static void VisitChildren(this Element? element, Action<Element?> handler)
         {
-            handler(element);
-
             foreach (var child in element.GetChildren().Where(x => x != null))
                 VisitChildren(child, handler);
+            
+            handler(element);
         }
     }
 }