Simplified implementation for Section and Page elements

This commit is contained in:
Marcin Ziąbek 2021-04-03 00:13:14 +02:00
Родитель 500cea1fbf
Коммит a83ebe2fed
9 изменённых файлов: 127 добавлений и 132 удалений

Просмотреть файл

@ -17,7 +17,7 @@ namespace QuestPDF.Examples
.Placeholder();
}
//[ShowResult]
[ShowResult]
[ImageSize(300, 300)]
public void Section(IContainer container)
{
@ -167,7 +167,7 @@ namespace QuestPDF.Examples
});
}
[ShowResult]
//[ShowResult]
[ImageSize(300, 200)]
public void GridExample(IContainer container)
{

Просмотреть файл

@ -15,19 +15,6 @@ namespace QuestPDF.UnitTests
[Test]
public void Draw_ShouldHandleNullChild() => new Alignment().DrawWithoutChild();
[Test]
public void Measure_ShouldReturnWrap_WhenChildReturnsWrap()
{
TestPlan
.For(x => new Alignment
{
Child = x.CreateChild()
})
.MeasureElement(new Size(1000, 500))
.ExpectChildMeasure(expectedInput: new Size(1000, 500), returns: new Wrap())
.CheckMeasureResult(new Wrap());
}
[Test]
public void Draw_HorizontalCenter_VerticalCenter()
{

Просмотреть файл

@ -0,0 +1,63 @@
using System;
using System.Collections.Generic;
using QuestPDF.Drawing.SpacePlan;
using QuestPDF.Infrastructure;
namespace QuestPDF.Elements
{
internal enum DecorationType
{
Prepend,
Append
}
internal class Decoration : Element
{
public Element? DecorationElement { get; set; }
public Element? ContentElement { get; set; }
public DecorationType Type { get; set; }
internal override ISpacePlan Measure(Size availableSpace)
{
var decorationMeasure = DecorationElement?.Measure(availableSpace);
if (decorationMeasure is Wrap || decorationMeasure is PartialRender)
return new Wrap();
var decorationSize = decorationMeasure as Size ?? Size.Zero;
var contentMeasure = ContentElement?.Measure(new Size(availableSpace.Width, availableSpace.Height - decorationSize.Height)) ?? new FullRender(Size.Zero);
if (contentMeasure is Wrap)
return new Wrap();
var contentSize = contentMeasure as Size ?? Size.Zero;
var resultSize = new Size(availableSpace.Width, decorationSize.Height + contentSize.Height);
if (contentSize is PartialRender)
return new PartialRender(resultSize);
if (contentSize is FullRender)
return new FullRender(resultSize);
throw new NotSupportedException();
}
internal override void Draw(ICanvas canvas, Size availableSpace)
{
var decorationSize = DecorationElement?.Measure(availableSpace) as Size ?? Size.Zero;
var contentSize = new Size(availableSpace.Width, availableSpace.Height - decorationSize.Height);
var translateHeight = Type == DecorationType.Prepend ? decorationSize.Height : contentSize.Height;
Action drawDecoration = () => DecorationElement?.Draw(canvas, new Size(availableSpace.Width, decorationSize.Height));
Action drawContent = () => ContentElement?.Draw(canvas, new Size (availableSpace.Width, contentSize.Height));
var first = Type == DecorationType.Prepend ? drawDecoration : drawContent;
var second = Type == DecorationType.Prepend ? drawContent : drawDecoration;
first();
canvas.Translate(new Position(0, translateHeight));
second();
canvas.Translate(new Position(0, -translateHeight));
}
}
}

Просмотреть файл

@ -15,7 +15,8 @@ namespace QuestPDF.Elements
public int ColumnsCount { get; set; } = DefaultColumnsCount;
public HorizontalAlignment Alignment { get; set; } = Left;
public float Spacing { get; set; } = 0;
public float VerticalSpacing { get; set; } = 0;
public float HorizontalSpacing { get; set; } = 0;
public void Compose(IContainer container)
{
@ -23,7 +24,7 @@ namespace QuestPDF.Elements
container.Stack(stack =>
{
stack.Spacing(Spacing);
stack.Spacing(HorizontalSpacing);
while (ChildrenQueue.Any())
stack.Element().Row(BuildRow);
@ -48,7 +49,7 @@ namespace QuestPDF.Elements
void BuildRow(RowDescriptor row)
{
row.Spacing(Spacing);
row.Spacing(HorizontalSpacing);
var elements = GetRowElements().ToList();
var columnsWidth = elements.Sum(x => x.Columns);

Просмотреть файл

@ -1,57 +1,24 @@
using System;
using QuestPDF.Drawing.SpacePlan;
using QuestPDF.Fluent;
using QuestPDF.Infrastructure;
namespace QuestPDF.Elements
{
internal class Page : Element
internal class Page : IComponent
{
public Element? Header { get; set; }
public Element? Content { get; set; }
public Element? Footer { get; set; }
internal override ISpacePlan Measure(Size availableSpace)
public void Compose(IContainer container)
{
var headerSize = Header?.Measure(availableSpace) as Size;
var footerSize = Footer?.Measure(availableSpace) as Size;
var contentHeight = availableSpace.Height - (headerSize?.Height ?? 0) - (footerSize?.Height ?? 0);
var required = Content.Measure(new Size(availableSpace.Width, contentHeight));
if (required is FullRender)
return new FullRender(availableSpace);
if (required is PartialRender)
return new PartialRender(availableSpace);
if (required is Wrap)
return new Wrap();
throw new NotSupportedException();
}
internal override void Draw(ICanvas canvas, Size availableSpace)
{
var headerHeight = (Header?.Measure(availableSpace) as Size)?.Height ?? 0;
var footerHeight = (Footer?.Measure(availableSpace) as Size)?.Height ?? 0;
var contentHeight = availableSpace.Height - headerHeight - footerHeight;
var contentSize = new Size(availableSpace.Width, contentHeight);
if (headerHeight > 0)
container.Section(section =>
{
Header?.Draw(canvas, new Size(availableSpace.Width, headerHeight));
canvas.Translate(new Position(0, headerHeight));
}
Content.Draw(canvas, new Size(availableSpace.Width, contentSize.Height));
canvas.Translate(new Position(0, contentSize.Height));
if (footerHeight > 0)
{
Footer?.Draw(canvas, new Size(availableSpace.Width, footerHeight));
}
section.Header().Element(Header ?? new Empty());
section.Content().Extend().Element(Content ?? new Empty());
section.Footer().Element(Footer ?? new Empty());
});
}
}
}

Просмотреть файл

@ -1,62 +1,29 @@
using System;
using QuestPDF.Drawing.SpacePlan;
using QuestPDF.Fluent;
using QuestPDF.Infrastructure;
namespace QuestPDF.Elements
{
internal class Section : Element
internal class Section : IComponent
{
public ContainerElement? Header { get; set; }
public ContainerElement? Content { get; set; }
public Element Header { get; set; } = new Empty();
public Element Content { get; set; } = new Empty();
public Element Footer { get; set; } = new Empty();
internal override ISpacePlan Measure(Size availableSpace)
public void Compose(IContainer container)
{
var headerMeasure = Header?.Measure(availableSpace);
if (headerMeasure is Wrap || headerMeasure is PartialRender)
return new Wrap();
var headerSize = headerMeasure as Size ?? Size.Zero;
var contentMeasure = Content?.Measure(new Size(availableSpace.Width, availableSpace.Height - headerSize.Height)) ?? new FullRender(Size.Zero);
if (contentMeasure is Wrap)
return new Wrap();
var contentSize = contentMeasure as Size ?? Size.Zero;
var newSize = new Size(
availableSpace.Width,
headerSize.Height + contentSize.Height);
if (contentSize is PartialRender)
return new PartialRender(newSize);
if (contentSize is FullRender)
return new FullRender(newSize);
throw new NotSupportedException();
}
internal override void Draw(ICanvas canvas, Size availableSpace)
{
var measurement = Measure(availableSpace);
if (measurement is Wrap)
return;
var headerSize = Header?.Measure(availableSpace) as Size ?? Size.Zero;
var contentAvailableSize = new Size(availableSpace.Width, availableSpace.Height - headerSize.Height);
var contentSize = Content?.Measure(contentAvailableSize) as Size;
Header?.Draw(canvas, new Size(availableSpace.Width, headerSize.Height));
canvas.Translate(new Position(0, headerSize.Height));
if (contentSize != null)
Content?.Draw(canvas, new Size(availableSpace.Width, contentSize.Height));
canvas.Translate(new Position(0, -headerSize.Height));
container.Element(new Decoration
{
Type = DecorationType.Prepend,
DecorationElement = Header,
ContentElement = new Decoration
{
Type = DecorationType.Append,
ContentElement = Content,
DecorationElement = Footer
}
});
}
}
}

Просмотреть файл

@ -11,7 +11,18 @@ namespace QuestPDF.Fluent
public void Spacing(float value)
{
Grid.Spacing = value;
VerticalSpacing(value);
HorizontalSpacing(value);
}
public void VerticalSpacing(float value)
{
Grid.VerticalSpacing = value;
}
public void HorizontalSpacing(float value)
{
Grid.HorizontalSpacing = value;
}
public void Columns(int value = Grid.DefaultColumnsCount)

Просмотреть файл

@ -6,13 +6,8 @@ namespace QuestPDF.Fluent
{
public class PageDescriptor
{
private Page Page { get; }
internal PageDescriptor(Page page)
{
Page = page;
}
internal Page Page { get; } = new Page();
public IContainer Header()
{
var container = new Container();
@ -54,11 +49,9 @@ namespace QuestPDF.Fluent
{
public static void Page(this IContainer document, Action<PageDescriptor> handler)
{
var page = new Page();
document.Element(page);
var descriptor = new PageDescriptor(page);
var descriptor = new PageDescriptor();
handler(descriptor);
document.Component(descriptor.Page);
}
}
}

Просмотреть файл

@ -6,12 +6,7 @@ namespace QuestPDF.Fluent
{
public class SectionDescriptor
{
private Section Section { get; }
internal SectionDescriptor(Section section)
{
Section = section;
}
internal Section Section { get; } = new Section();
public IContainer Header()
{
@ -36,17 +31,28 @@ namespace QuestPDF.Fluent
{
handler?.Invoke(Content());
}
public IContainer Footer()
{
var container = new Container();
Section.Footer = container;
return container;
}
public void Footer(Action<IContainer> handler)
{
handler?.Invoke(Footer());
}
}
public static class SectionExtensions
{
public static void Section(this IContainer element, Action<SectionDescriptor> handler)
{
var section = new Section();
element.Element(section);
var descriptor = new SectionDescriptor(section);
var descriptor = new SectionDescriptor();
handler(descriptor);
element.Component(descriptor.Section);
}
}
}