namespace Terminal.Gui.ViewBase;
///
/// Wraps any to make it runnable with a typed result, similar to how
/// wraps .
///
/// The type of view being wrapped.
/// The type of result data returned when the session completes.
///
///
/// This class enables any View to be run as a blocking session with
///
/// without requiring the View to implement or derive from
/// .
///
///
/// Use for a fluent API approach,
/// or to run directly.
///
///
///
/// // Wrap a TextField to make it runnable with string result
/// var textField = new TextField { Width = 40 };
/// var runnable = new RunnableWrapper<TextField, string> { WrappedView = textField };
///
/// // Extract result when stopping
/// runnable.IsRunningChanging += (s, e) =>
/// {
/// if (!e.NewValue) // Stopping
/// {
/// runnable.Result = runnable.WrappedView.Text;
/// }
/// };
///
/// app.Run(runnable);
/// Console.WriteLine($"User entered: {runnable.Result}");
/// runnable.Dispose();
///
///
///
public class RunnableWrapper : Runnable where TView : View
{
///
/// Initializes a new instance of .
///
public RunnableWrapper ()
{
// Make the wrapper automatically size to fit the wrapped view
Width = Dim.Fill ();
Height = Dim.Fill ();
}
private TView? _wrappedView;
///
/// Gets or sets the wrapped view that is being made runnable.
///
///
///
/// This property must be set before the wrapper is initialized.
/// Access this property to interact with the original view, extract its state,
/// or configure result extraction logic.
///
///
/// Thrown if the property is set after initialization.
public required TView WrappedView
{
get => _wrappedView ?? throw new InvalidOperationException ("WrappedView must be set before use.");
init
{
if (IsInitialized)
{
throw new InvalidOperationException ("WrappedView cannot be changed after initialization.");
}
_wrappedView = value;
}
}
///
public override void EndInit ()
{
base.EndInit ();
// Add the wrapped view as a subview after initialization
if (_wrappedView is { })
{
Add (_wrappedView);
}
}
}