IDynamicComponent.cs 3.3 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273
  1. using System;
  2. using QuestPDF.Elements;
  3. namespace QuestPDF.Infrastructure
  4. {
  5. internal sealed class DynamicComponentProxy
  6. {
  7. internal Action<object> SetState { get; private set; }
  8. internal Func<object> GetState { get; private set; }
  9. internal Func<DynamicContext, DynamicComponentComposeResult> Compose { get; private set; }
  10. internal static DynamicComponentProxy CreateFrom<TState>(IDynamicComponent<TState> component) where TState : struct
  11. {
  12. return new DynamicComponentProxy
  13. {
  14. GetState = () => component.State,
  15. SetState = x => component.State = (TState)x,
  16. Compose = component.Compose
  17. };
  18. }
  19. }
  20. /// <summary>
  21. /// Represents the output from the DynamicComponent describing what should be rendered on the current page.
  22. /// </summary>
  23. public class DynamicComponentComposeResult
  24. {
  25. /// <summary>
  26. /// Any content created with the <see cref="DynamicContext.CreateElement" /> method that should be drawn on the currently rendered page.
  27. /// </summary>
  28. public IElement Content { get; set; }
  29. /// <summary>
  30. /// Set to true if the dynamic component has additional content for the next page.
  31. /// Set to false if all content from the dynamic component has been rendered.
  32. /// </summary>
  33. public bool HasMoreContent { get; set; }
  34. }
  35. /// <summary>
  36. /// Represents a section of the document dynamically created based on its inner state.
  37. /// Components are page-aware, understand their positioning, can dynamically construct other content elements, and assess their dimensions, enabling complex layout creations.
  38. /// </summary>
  39. /// <remarks>
  40. /// Though dynamic components offer great flexibility, be cautious of potential performance impacts.
  41. /// </remarks>
  42. /// <typeparam name="TState">Structure type representing the internal state of the component.</typeparam>
  43. public interface IDynamicComponent<TState> where TState : struct
  44. {
  45. /// <summary>
  46. /// Represents the component's current state.
  47. /// </summary>
  48. /// <remarks>
  49. /// <para>
  50. /// The state should remain read-only.
  51. /// Avoid direct state modifications.
  52. /// For any alterations, generate a new struct instance and reassign the State property.
  53. /// </para>
  54. /// <para>Remember, the QuestPDF library can invoke the Compose method more than once for each page and might adjust the state internally.</para>
  55. /// </remarks>
  56. TState State { get; set; }
  57. /// <summary>
  58. /// Method invoked by the library to plan and create new content for each page.
  59. /// </summary>
  60. /// <remarks>
  61. /// Remember, the QuestPDF library can invoke the Compose method more than once for each page and might adjust the state internally.
  62. /// </remarks>
  63. /// <param name="context">Context offering additional information (like current page number, entire document size) and the capability to produce dynamic content elements.</param>
  64. /// <returns>Representation of content that should be placed on the current page.</returns>
  65. DynamicComponentComposeResult Compose(DynamicContext context);
  66. }
  67. }