#nullable enable
namespace Terminal.Gui.App;
///
/// Abstract base class for popover views in Terminal.Gui.
///
///
///
/// Popover Lifecycle:
/// To display a popover, use . To hide a popover, either call
/// ,
/// set to , or show another popover.
///
///
/// Focus and Input:
/// When visible, a popover receives focus and input events. If the user clicks outside the popover (and not on a
/// subview),
/// presses , or another popover is shown, the popover will be hidden
/// automatically.
///
///
/// Layout:
/// When the popover becomes visible, it is automatically laid out to fill the screen by default. You can override
/// this behavior
/// by setting and in your derived class.
///
///
/// Mouse:
/// Popovers are transparent to mouse events (see ),
/// meaning mouse events in a popover that are not also within a subview of the popover will not be captured.
///
///
/// Custom Popovers:
/// To create a custom popover, inherit from and add your own content and logic.
///
///
public abstract class PopoverBaseImpl : View, IPopover
{
///
/// Initializes a new instance of the class.
///
///
/// By default, the popover fills the available screen area and is focusable.
///
protected PopoverBaseImpl ()
{
Id = "popoverBaseImpl";
CanFocus = true;
Width = Dim.Fill ();
Height = Dim.Fill ();
ViewportSettings = ViewportSettingsFlags.Transparent | ViewportSettingsFlags.TransparentMouse;
// TODO: Add a diagnostic setting for this?
//TextFormatter.VerticalAlignment = Alignment.End;
//TextFormatter.Alignment = Alignment.End;
//base.Text = "popover";
AddCommand (Command.Quit, Quit);
KeyBindings.Add (Application.QuitKey, Command.Quit);
return;
bool? Quit (ICommandContext? ctx)
{
if (!Visible)
{
return false;
}
Visible = false;
return true;
}
}
///
public Toplevel? Toplevel { get; set; }
///
/// Called when the property is changing.
///
///
/// When becoming visible, the popover is laid out to fit the screen.
/// When becoming hidden, focus is restored to the previous view.
///
///
/// to cancel the visibility change; otherwise, .
///
protected override bool OnVisibleChanging ()
{
bool ret = base.OnVisibleChanging ();
if (ret)
{
return ret;
}
if (!Visible)
{
// Whenever visible is changing to true, we need to resize;
// it's our only chance because we don't get laid out until we're visible
Layout (Application.Screen.Size);
}
else
{
// Whenever visible is changing to false, we need to reset the focus
if (ApplicationNavigation.IsInHierarchy (this, Application.Navigation?.GetFocused ()))
{
Application.Navigation?.SetFocused (Application.Top?.MostFocused);
}
}
return ret;
}
}