Skip to content

Commit 1545522

Browse files
committed
feat: Add ContainerNode
1 parent 1f9523c commit 1545522

File tree

11 files changed

+213
-111
lines changed

11 files changed

+213
-111
lines changed

src/Moss.NET.Sdk/LayoutEngine/Layout.cs

Lines changed: 20 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ protected Layout(YogaConfig config, PdfPageBuilder? page, PdfRectangle pageSize
2424
pageSize = page.PageSize;
2525
}
2626

27-
root = new YogaNode(config)
27+
root = new YogaNode(config, this)
2828
{
2929
Width = pageSize.Width,
3030
Height = pageSize.Height,
@@ -58,20 +58,28 @@ public static Layout CreateTemplate()
5858

5959
public YogaNode CreateNode(string? name = null)
6060
{
61-
return new YogaNode(config)
61+
return new YogaNode(config, this)
6262
{
63-
Name = name,
64-
ParentLayout = this
63+
Name = name
6564
};
6665
}
6766

6867
public TextNode CreateTextNode(string text, string? name = null)
6968
{
70-
return new TextNode(config)
69+
return new TextNode(config, this)
7170
{
7271
Name = name,
73-
Text = text,
74-
ParentLayout = this
72+
Text = text
73+
};
74+
}
75+
76+
public ContainerNode CreateContainerNode(string title, string copyright, string? name = null)
77+
{
78+
return new ContainerNode(config, this)
79+
{
80+
Name = name,
81+
Title = title,
82+
Copyright = copyright
7583
};
7684
}
7785

@@ -106,17 +114,16 @@ private static void ReCalculate(YogaNode root, PdfPageBuilder page)
106114
{
107115
foreach (var child in root.Children)
108116
{
109-
child.ReCalculate(page);
110-
111117
ReCalculate(child, page);
118+
119+
child.ReCalculate(page);
112120
}
113121
}
114122

115123
public HorizontalLineNode CreateHorizontalLine(string? name = null)
116124
{
117-
return new HorizontalLineNode(config){
118-
Name = name,
119-
ParentLayout = this
125+
return new HorizontalLineNode(config, this){
126+
Name = name
120127
};
121128
}
122129

@@ -171,10 +178,9 @@ public PdfDocumentBuilder.AddedFont GetFont(string fontFamily)
171178

172179
public ImageNode CreateImageNode(string url, string? name = null)
173180
{
174-
return new ImageNode(config)
181+
return new ImageNode(config, this)
175182
{
176183
Name = name,
177-
ParentLayout = this,
178184
Src = url
179185
};
180186
}

src/Moss.NET.Sdk/LayoutEngine/LayoutLoader.cs

Lines changed: 48 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,8 @@
11
using Moss.NET.Sdk.LayoutEngine.Nodes;
2+
using System.Xml.Linq;
23

34
namespace Moss.NET.Sdk.LayoutEngine;
45

5-
using System.Xml.Linq;
6-
76
public static class LayoutLoader
87
{
98
private static readonly Dictionary<string, IDataSource> DataSources = new();
@@ -23,6 +22,11 @@ public static Layout LoadLayoutFromXml(string xmlContent)
2322
var isLandscape = xml.Root.Attribute("isLandscape")?.Value == "true";
2423
var layout = Layout.Create(device, isLandscape);
2524

25+
if (xml.Root.Attribute("name") != null)
26+
{
27+
layout.Name = xml.Root.Attribute("name")!.Value;
28+
}
29+
2630
layout.GetRoot().SetAttributes(xml.Root);
2731

2832
foreach (var child in xml.Root.Elements())
@@ -77,10 +81,33 @@ public static YogaNode LoadFragmentFromXml(string xmlContent)
7781

7882
private static YogaNode? ParseNode(Layout layout, XElement element)
7983
{
80-
YogaNode? node;
84+
if (!CreateNode(layout, element, out var node) && node is null) return null;
85+
86+
node!.SetAttributes(element);
87+
88+
ParseChildren(layout, element, node);
89+
90+
ApplyDataSource(layout, element, node);
91+
92+
return node;
93+
}
94+
95+
private static void ApplyDataSource(Layout layout, XElement element, YogaNode node)
96+
{
97+
if (element.Attribute("datasource") is not null
98+
&& DataSources.TryGetValue(element.Attribute("datasource")!.Value, out var dataSource))
99+
{
100+
dataSource.ApplyData(node, layout.Page!, element);
101+
}
102+
}
103+
104+
private static bool CreateNode(Layout layout, XElement element, out YogaNode? node)
105+
{
81106
switch (element.Name.LocalName)
82107
{
83-
case "setter": return null;
108+
case "setter":
109+
node = null;
110+
return false;
84111
case "text":
85112
node = layout.CreateTextNode(element.Attribute("text")?.Value ?? string.Empty,
86113
element.Attribute("name")?.Value);
@@ -95,6 +122,11 @@ public static YogaNode LoadFragmentFromXml(string xmlContent)
95122
case "img":
96123
node = layout.CreateImageNode(element.Attribute("src")?.Value!, element.Attribute("name")?.Value);
97124
break;
125+
case "container":
126+
node = layout.CreateContainerNode(element.Attribute("title")?.Value ?? string.Empty,
127+
element.Attribute("copyright")?.Value ?? string.Empty,
128+
element.Attribute("name")?.Value);
129+
break;
98130
case "fragment":
99131
node = LoadFragment(element.Attribute("src")!.Value);
100132
ApplyFragmentSetter(element, node);
@@ -118,26 +150,26 @@ public static YogaNode LoadFragmentFromXml(string xmlContent)
118150
break;
119151
}
120152

121-
if (node == null) return null;
122-
123-
node.SetAttributes(element);
153+
return true;
154+
}
124155

156+
private static void ParseChildren(Layout layout, XElement element, YogaNode node)
157+
{
125158
foreach (var child in element.Elements())
126159
{
127160
var childNode = ParseNode(layout, child);
128161
if (childNode != null)
129162
{
130-
node.Add(childNode);
163+
if (node is ContainerNode container)
164+
{
165+
container.Content.Add(childNode);
166+
}
167+
else
168+
{
169+
node.Add(childNode);
170+
}
131171
}
132172
}
133-
134-
if (element.Attribute("datasource") is not null
135-
&& DataSources.TryGetValue(element.Attribute("datasource")!.Value, out var dataSource))
136-
{
137-
dataSource.ApplyData(node, layout.Page!, element);
138-
}
139-
140-
return node;
141173
}
142174

143175
private static void ApplyFragmentSetter(XElement element, YogaNode node)
Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
namespace Moss.NET.Sdk.LayoutEngine.Nodes;
2+
3+
public class ContainerNode : YogaNode
4+
{
5+
private readonly TextNode copyrightNode;
6+
private readonly TextNode titleNode;
7+
8+
public ContainerNode(YogaConfig config, Layout parentLayout) : base(config, parentLayout)
9+
{
10+
Content = ParentLayout!.CreateNode("content");
11+
FlexDirection = YogaFlexDirection.Column;
12+
13+
titleNode = ParentLayout.CreateTextNode("", "title");
14+
titleNode.AlignSelf = YogaAlign.Center;
15+
titleNode.PositionType = YogaPositionType.Relative;
16+
titleNode.Margin = 5;
17+
titleNode.AutoSize = true;
18+
19+
copyrightNode = ParentLayout.CreateTextNode("© ", "copyright");
20+
copyrightNode.AlignSelf = YogaAlign.FlexEnd;
21+
copyrightNode.PositionType = YogaPositionType.Relative;
22+
copyrightNode.FontFamily = "NoticiaText";
23+
copyrightNode.FontSize = 6;
24+
copyrightNode.AutoSize = true;
25+
copyrightNode.MarginTop = 5;
26+
27+
Content.FlexGrow = 1;
28+
Content.Margin= 5;
29+
30+
Margin = 5;
31+
32+
if (Title is not null)
33+
{
34+
Add(titleNode);
35+
}
36+
37+
Add(Content);
38+
39+
if (Copyright is not null)
40+
{
41+
Add(copyrightNode);
42+
}
43+
}
44+
45+
public required string Title
46+
{
47+
get => titleNode.Text;
48+
set => titleNode.Text = value;
49+
}
50+
51+
public required string Copyright
52+
{
53+
get => copyrightNode.Text;
54+
set => copyrightNode.Text = "© " + value;
55+
}
56+
57+
public YogaNode Content { get; }
58+
59+
internal override void SetAttribute(string name, string value)
60+
{
61+
switch (name)
62+
{
63+
case "title":
64+
Title = value;
65+
break;
66+
case "copyright":
67+
Copyright = value;
68+
break;
69+
}
70+
}
71+
}

src/Moss.NET.Sdk/LayoutEngine/Nodes/HorizontalLineNode.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33

44
namespace Moss.NET.Sdk.LayoutEngine.Nodes;
55

6-
public class HorizontalLineNode(YogaConfig config) : YogaNode(config)
6+
public class HorizontalLineNode(YogaConfig config, Layout parentLayout) : YogaNode(config, parentLayout)
77
{
88
public double LineThickness { get; set; } = 1.0;
99
public Color LineColor { get; set; } = Colors.Black;

src/Moss.NET.Sdk/LayoutEngine/Nodes/ImageNode.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ namespace Moss.NET.Sdk.LayoutEngine.Nodes;
55

66
public enum ImageFormat {Png, Jpeg}
77

8-
public class ImageNode(YogaConfig config) : YogaNode(config)
8+
public class ImageNode(YogaConfig config, Layout parentLayout) : YogaNode(config, parentLayout)
99
{
1010
public required string Src { get; set; }
1111
public bool AutoSize { get; set; }

src/Moss.NET.Sdk/LayoutEngine/Nodes/TextNode.cs

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,10 @@
33

44
namespace Moss.NET.Sdk.LayoutEngine.Nodes;
55

6-
public class TextNode(YogaConfig config) : YogaNode(config)
6+
public class TextNode(YogaConfig config, Layout parentLayout) : YogaNode(config, parentLayout)
77
{
88
public double FontSize { get; set; } = 10;
9-
public string Text { get; set; }
9+
public string? Text { get; set; }
1010
public string FontFamily { get; set; } = "Default";
1111

1212
public Color? Color { get; set; } = Colors.Black;
@@ -35,6 +35,11 @@ public bool AutoSize
3535

3636
public override void ReCalculate(PdfPageBuilder page)
3737
{
38+
if (string.IsNullOrEmpty(Text))
39+
{
40+
return;
41+
}
42+
3843
var text = GetActualString();
3944

4045
var measuredText = page.MeasureText(text, FontSize, PdfPoint.Origin, ParentLayout.GetFont(FontFamily));
@@ -64,7 +69,7 @@ private string GetActualString()
6469

6570
public override void Draw(PdfPageBuilder page, double absoluteX, double absoluteY)
6671
{
67-
if (Display == YogaDisplay.None)
72+
if (Display == YogaDisplay.None || string.IsNullOrEmpty(Text))
6873
{
6974
return;
7075
}

src/Moss.NET.Sdk/LayoutEngine/YogaNode.cs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ public partial class YogaNode : IEnumerable<YogaNode>
3737
private YogaConfig _config;
3838
private bool _isDirty;
3939
private YogaArray<YogaValue> _resolvedDimensions; // [2]
40-
public required Layout ParentLayout { get; set; }
40+
public Layout ParentLayout { get; set; }
4141
public Color? Background { get; set; }
4242
public BoxShadow? BoxShadow { get; set; }
4343

@@ -132,7 +132,7 @@ public YogaNode(
132132
Interlocked.Increment(ref _instanceCount);
133133
}
134134

135-
public YogaNode(YogaConfig config) : this()
135+
public YogaNode(YogaConfig config, Layout layout) : this()
136136
{
137137
_config = config ?? new YogaConfig();
138138

@@ -141,6 +141,8 @@ public YogaNode(YogaConfig config) : this()
141141
Style.FlexDirection = YogaFlexDirection.Row;
142142
Style.AlignContent = YogaAlign.Stretch;
143143
}
144+
145+
ParentLayout = layout;
144146
}
145147

146148
~YogaNode()

0 commit comments

Comments
 (0)