PopoverWrapper.cs 3.1 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495
  1. namespace Terminal.Gui.App;
  2. /// <summary>
  3. /// Wraps any <see cref="View"/> to make it a popover, similar to how
  4. /// <see cref="RunnableWrapper{TView, TResult}"/> wraps views to make them runnable.
  5. /// </summary>
  6. /// <typeparam name="TView">The type of view being wrapped.</typeparam>
  7. /// <remarks>
  8. /// <para>
  9. /// This class enables any View to be shown as a popover with
  10. /// <see cref="ApplicationPopover.Show"/>
  11. /// without requiring the View to implement <see cref="IPopover"/> or derive from
  12. /// <see cref="PopoverBaseImpl"/>.
  13. /// </para>
  14. /// <para>
  15. /// The wrapper automatically handles:
  16. /// <list type="bullet">
  17. /// <item>Setting proper viewport settings (transparent, transparent mouse)</item>
  18. /// <item>Configuring focus behavior</item>
  19. /// <item>Handling the quit command to hide the popover</item>
  20. /// <item>Sizing to fill the screen by default</item>
  21. /// </list>
  22. /// </para>
  23. /// <para>
  24. /// Use <see cref="ViewPopoverExtensions.AsPopover{TView}"/> for a fluent API approach.
  25. /// </para>
  26. /// <example>
  27. /// <code>
  28. /// // Wrap a custom view to make it a popover
  29. /// var myView = new View
  30. /// {
  31. /// X = Pos.Center (),
  32. /// Y = Pos.Center (),
  33. /// Width = 40,
  34. /// Height = 10,
  35. /// BorderStyle = LineStyle.Single
  36. /// };
  37. /// myView.Add (new Label { Text = "Hello Popover!" });
  38. ///
  39. /// var popover = new PopoverWrapper&lt;View&gt; { WrappedView = myView };
  40. /// app.Popover.Register (popover);
  41. /// app.Popover.Show (popover);
  42. /// </code>
  43. /// </example>
  44. /// </remarks>
  45. public class PopoverWrapper<TView> : PopoverBaseImpl where TView : View
  46. {
  47. /// <summary>
  48. /// Initializes a new instance of <see cref="PopoverWrapper{TView}"/>.
  49. /// </summary>
  50. public PopoverWrapper ()
  51. {
  52. Id = "popoverWrapper";
  53. Width = Dim.Auto ();
  54. Height = Dim.Auto ();
  55. }
  56. private TView? _wrappedView;
  57. /// <summary>
  58. /// Gets or sets the wrapped view that is being made into a popover.
  59. /// </summary>
  60. /// <remarks>
  61. /// <para>
  62. /// This property must be set before the wrapper is initialized.
  63. /// Access this property to interact with the original view or configure its behavior.
  64. /// </para>
  65. /// </remarks>
  66. /// <exception cref="InvalidOperationException">Thrown if the property is set after initialization.</exception>
  67. public required TView WrappedView
  68. {
  69. get => _wrappedView ?? throw new InvalidOperationException ("WrappedView must be set before use.");
  70. init
  71. {
  72. if (IsInitialized)
  73. {
  74. throw new InvalidOperationException ("WrappedView cannot be changed after initialization.");
  75. }
  76. _wrappedView = value;
  77. }
  78. }
  79. /// <inheritdoc/>
  80. public override void EndInit ()
  81. {
  82. base.EndInit ();
  83. // Add the wrapped view as a subview after initialization
  84. if (_wrappedView is { })
  85. {
  86. Add (_wrappedView);
  87. }
  88. }
  89. }