DrawContext.cs 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106
  1. namespace Terminal.Gui.ViewBase;
  2. /// <summary>
  3. /// Tracks the region that has been drawn during <see cref="View.Draw(DrawContext?)"/>. This is primarily
  4. /// in support of <see cref="ViewportSettingsFlags.Transparent"/>.
  5. /// </summary>
  6. /// <remarks>
  7. /// <para>
  8. /// When a <see cref="View"/> has <see cref="ViewportSettingsFlags.Transparent"/> set, the <see cref="DrawContext"/>
  9. /// is used to track exactly which areas of the screen have been drawn to. After drawing is complete, these drawn
  10. /// regions are excluded from the clip region, allowing views beneath the transparent view to show through in
  11. /// the areas that were not drawn.
  12. /// </para>
  13. /// <para>
  14. /// All coordinates tracked by <see cref="DrawContext"/> are in <b>screen-relative coordinates</b>. When reporting
  15. /// drawn areas from within <see cref="View.OnDrawingContent(DrawContext?)"/>, use <see cref="View.ViewportToScreen(in Rectangle)"/>
  16. /// or <see cref="View.ContentToScreen(in Point)"/> to convert viewport-relative or content-relative coordinates to
  17. /// screen-relative coordinates before calling <see cref="AddDrawnRectangle"/> or <see cref="AddDrawnRegion"/>.
  18. /// </para>
  19. /// <para>
  20. /// Example of reporting a non-rectangular drawn region for transparency:
  21. /// </para>
  22. /// <code>
  23. /// protected override bool OnDrawingContent (DrawContext? context)
  24. /// {
  25. /// // Draw some content in viewport-relative coordinates
  26. /// Rectangle rect1 = new Rectangle (5, 5, 10, 3);
  27. /// Rectangle rect2 = new Rectangle (8, 8, 4, 7);
  28. /// FillRect (rect1, Glyphs.BlackCircle);
  29. /// FillRect (rect2, Glyphs.BlackCircle);
  30. ///
  31. /// // Report the drawn region in screen-relative coordinates
  32. /// Region drawnRegion = new Region (ViewportToScreen (rect1));
  33. /// drawnRegion.Union (ViewportToScreen (rect2));
  34. /// context?.AddDrawnRegion (drawnRegion);
  35. ///
  36. /// return true;
  37. /// }
  38. /// </code>
  39. /// </remarks>
  40. public class DrawContext
  41. {
  42. private readonly Region _drawnRegion = new Region ();
  43. /// <summary>
  44. /// Gets a copy of the region drawn so far in this context.
  45. /// </summary>
  46. /// <remarks>
  47. /// The returned region contains all areas that have been reported as drawn via <see cref="AddDrawnRectangle"/>
  48. /// or <see cref="AddDrawnRegion"/>, in screen-relative coordinates.
  49. /// </remarks>
  50. public Region GetDrawnRegion () => _drawnRegion.Clone ();
  51. /// <summary>
  52. /// Reports that a rectangle has been drawn.
  53. /// </summary>
  54. /// <param name="rect">The rectangle that was drawn, in screen-relative coordinates.</param>
  55. /// <remarks>
  56. /// When called from within <see cref="View.OnDrawingContent(DrawContext?)"/>, ensure the rectangle is in
  57. /// screen-relative coordinates by using <see cref="View.ViewportToScreen(in Rectangle)"/> or similar methods.
  58. /// </remarks>
  59. public void AddDrawnRectangle (Rectangle rect)
  60. {
  61. _drawnRegion.Combine (rect, RegionOp.Union);
  62. }
  63. /// <summary>
  64. /// Reports that a region has been drawn.
  65. /// </summary>
  66. /// <param name="region">The region that was drawn, in screen-relative coordinates.</param>
  67. /// <remarks>
  68. /// <para>
  69. /// This method is useful for reporting non-rectangular drawn areas, which is important for
  70. /// proper transparency support with <see cref="ViewportSettingsFlags.Transparent"/>.
  71. /// </para>
  72. /// <para>
  73. /// When called from within <see cref="View.OnDrawingContent(DrawContext?)"/>, ensure the region is in
  74. /// screen-relative coordinates by using <see cref="View.ViewportToScreen(in Rectangle)"/> to convert each
  75. /// rectangle in the region.
  76. /// </para>
  77. /// </remarks>
  78. public void AddDrawnRegion (Region region)
  79. {
  80. _drawnRegion.Combine (region, RegionOp.Union);
  81. }
  82. /// <summary>
  83. /// Clips (intersects) the drawn region with the specified rectangle.
  84. /// This modifies the internal drawn region directly.
  85. /// </summary>
  86. /// <param name="clipRect">The clipping rectangle, in screen-relative coordinates.</param>
  87. public void ClipDrawnRegion (Rectangle clipRect)
  88. {
  89. _drawnRegion.Intersect (clipRect);
  90. }
  91. /// <summary>
  92. /// Clips (intersects) the drawn region with the specified region.
  93. /// This modifies the internal drawn region directly.
  94. /// </summary>
  95. /// <param name="clipRegion">The clipping region, in screen-relative coordinates.</param>
  96. public void ClipDrawnRegion (Region clipRegion)
  97. {
  98. _drawnRegion.Intersect (clipRegion);
  99. }
  100. }