Simplified implementation for Section and Page elements
This commit is contained in:
Родитель
500cea1fbf
Коммит
a83ebe2fed
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
Загрузка…
Ссылка в новой задаче