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; } } private Toplevel? _current; /// public Toplevel? Current { get => _current; set { _current = value; App ??= _current?.App; } } /// /// 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 if (App is { }) { Layout (App.Screen.Size); } } else { // Whenever visible is changing to false, we need to reset the focus if (ApplicationNavigation.IsInHierarchy (this, App?.Navigation?.GetFocused ())) { App?.Navigation?.SetFocused (App?.Current?.MostFocused); } } return ret; } }