Ver Fonte

Improvements

Marcin Ziąbek há 3 anos atrás
pai
commit
97e4572c39

+ 61 - 0
QuestPDF.Examples/ComponentExamples.cs

@@ -0,0 +1,61 @@
+using System.Linq;
+using NUnit.Framework;
+using QuestPDF.Examples.Engine;
+using QuestPDF.Fluent;
+using QuestPDF.Helpers;
+using QuestPDF.Infrastructure;
+
+namespace QuestPDF.Examples
+{
+    internal class MyComponent : IComponent
+    {
+        public ISlot Header { get; set; }
+        public ISlot<string> Content { get; set; }
+
+        public void Compose(IContainer container)
+        {
+            container
+                .Column(column =>
+                {
+                    column.Item().Slot(Header);
+
+                    foreach (var i in Enumerable.Range(1, 10))
+                        column.Item().Slot(Content, i.ToString());
+                });
+        }
+    }
+    
+    public class ComponentExamples
+    {
+        [Test]
+        public void ComplexLayout()
+        {
+            RenderingTest
+                .Create()
+                .PageSize(PageSizes.A4)
+                .ProducePdf()
+                .ShowResults()
+                .Render(content =>
+                {
+                    content
+                        .Padding(10)
+                        .Border(1)
+                        .BorderColor(Colors.Grey.Medium)
+                        .Component<MyComponent>(component =>
+                        {
+                            component
+                                .Slot(x => x.Header)
+                                .Text("This is my text");
+
+                            component.Slot(x => x.Content, (input, container) =>
+                            {
+                                container
+                                    .Background(Placeholders.BackgroundColor())
+                                    .Padding(5)
+                                    .Text(input);
+                            });
+                        });
+                });
+        }
+    }
+}

+ 41 - 23
QuestPDF/Fluent/ComponentExtentions.cs

@@ -1,41 +1,53 @@
 using System;
 using System;
 using System.Linq.Expressions;
 using System.Linq.Expressions;
 using QuestPDF.Drawing.Exceptions;
 using QuestPDF.Drawing.Exceptions;
+using QuestPDF.Elements;
 using QuestPDF.Helpers;
 using QuestPDF.Helpers;
 using QuestPDF.Infrastructure;
 using QuestPDF.Infrastructure;
 
 
 namespace QuestPDF.Fluent
 namespace QuestPDF.Fluent
 {
 {
-    class ComponentDescriptor<T> where T : IComponent
+    internal class ComponentDescriptor<TComponent> where TComponent : IComponent
     {
     {
-        public T Component { get; }
+        public TComponent Component { get; }
         
         
-        public ComponentDescriptor(T component)
+        public ComponentDescriptor(TComponent component)
         {
         {
             Component = component;
             Component = component;
         }
         }
 
 
-        public IContainer Slot(Expression<Func<T, ISlot>> selector)
+        public IContainer Slot(Expression<Func<TComponent, ISlot>> selector)
         {
         {
-            try
+            AssureThatTheSlotIsNotConfiguredYet(selector);
+                
+            var slot = new Slot();
+            Component.SetPropertyValue(selector, slot);
+            return slot;
+        }
+        
+        public void Slot<TArgument>(Expression<Func<TComponent, ISlot<TArgument>>> selector, Action<TArgument, IContainer> handler)
+        {
+            AssureThatTheSlotIsNotConfiguredYet(selector);
+            
+            var slot = new Slot<TArgument>
             {
             {
-                var existingValue = Component.GetPropertyValue(selector);
+                GetContent = argument =>
+                {
+                    var container = new Container();
+                    handler(argument, container);
+                    return container;
+                }
+            };
+            
+            Component.SetPropertyValue(selector, slot);
+        }
 
 
-                if (existingValue != null)
-                    throw new DocumentComposeException($"The slot {selector.GetPropertyName()} of the component {(typeof(T).Name)} was already used.");
+        private void AssureThatTheSlotIsNotConfiguredYet<TSlot>(Expression<Func<TComponent, TSlot>> selector) where TSlot : class
+        {
+            var existingValue = Component.GetPropertyValue(selector);
 
 
-                var slot = new Slot();
-                Component.SetPropertyValue(selector, slot);
-                return slot;
-            }
-            catch (DocumentComposeException)
-            {
-                throw;
-            }
-            catch
-            {
-                throw new DocumentComposeException("Every slot in a component should be a public property with getter and setter.");
-            }
+            if (existingValue != null)
+                throw new DocumentComposeException($"The slot {selector.GetPropertyName()} of the component {(typeof(TComponent).Name)} was already used.");
         }
         }
     }
     }
     
     
@@ -51,7 +63,7 @@ namespace QuestPDF.Fluent
             element.Component(new T(), null);
             element.Component(new T(), null);
         }
         }
 
 
-        static void Component<T>(this IContainer element, T component, Action<ComponentDescriptor<T>>? handler = null) where T : IComponent
+        internal static void Component<T>(this IContainer element, T component, Action<ComponentDescriptor<T>>? handler = null) where T : IComponent
         {
         {
             var descriptor = new ComponentDescriptor<T>(component);
             var descriptor = new ComponentDescriptor<T>(component);
             handler?.Invoke(descriptor);
             handler?.Invoke(descriptor);
@@ -62,15 +74,21 @@ namespace QuestPDF.Fluent
             component.Compose(element.Container());
             component.Compose(element.Container());
         }
         }
         
         
-        static void Component<T>(this IContainer element, Action<ComponentDescriptor<T>>? handler = null) where T : IComponent, new()
+        internal static void Component<T>(this IContainer element, Action<ComponentDescriptor<T>>? handler = null) where T : IComponent, new()
         {
         {
             element.Component(new T(), handler);
             element.Component(new T(), handler);
         }
         }
 
 
-        static void Slot(this IContainer element, ISlot slot)
+        internal static void Slot(this IContainer element, ISlot slot)
         {
         {
             var child = (slot as Slot)?.Child;
             var child = (slot as Slot)?.Child;
             element.Element(child);
             element.Element(child);
         }
         }
+        
+        internal static void Slot<TArgument>(this IContainer element, ISlot<TArgument> slot, TArgument argument)
+        {
+            var child = (slot as Slot<TArgument>)?.GetContent(argument) ?? Empty.Instance;
+            element.Element(child);
+        }
     }
     }
 }
 }

+ 12 - 1
QuestPDF/Infrastructure/IComponent.cs

@@ -1,3 +1,4 @@
+using System;
 using QuestPDF.Elements;
 using QuestPDF.Elements;
 
 
 namespace QuestPDF.Infrastructure
 namespace QuestPDF.Infrastructure
@@ -11,7 +12,17 @@ namespace QuestPDF.Infrastructure
     {
     {
         
         
     }
     }
-    
+
+    interface ISlot<T>
+    {
+        
+    }
+
+    class Slot<T> : ISlot<T>
+    {
+        public Func<T, IElement> GetContent { get; set; }
+    }
+
     public interface IComponent
     public interface IComponent
     {
     {
         void Compose(IContainer container);
         void Compose(IContainer container);