using Robust.Client.AutoGenerated;
using Robust.Client.Graphics;
using Robust.Client.UserInterface.Controls;
using Robust.Client.UserInterface.XAML;
using Robust.Shared.Maths;
using Robust.Shared.Utility;
using static Robust.Client.UserInterface.Controls.BoxContainer;
namespace Content.Client.ContextMenu.UI
{
///
/// The base context-menu pop-up window used for both the entity and verb menus.
///
[GenerateTypedNameReferences]
public sealed partial class ContextMenuPopup : Popup
{
public const string StyleClassContextMenuPopup = "contextMenuPopup";
///
/// How many items to list before limiting the size and adding a scroll bar.
///
public const int MaxItemsBeforeScroll = 10;
///
/// If this pop-up is created by hovering over some element in another pop-up, this is that element.
///
public ContextMenuElement? ParentElement;
///
/// This is the main body of the menu. The menu entries should be added to this object.
///
public BoxContainer MenuBody = new() { Orientation = LayoutOrientation.Vertical };
private ContextMenuPresenter _presenter;
public ContextMenuPopup (ContextMenuPresenter presenter, ContextMenuElement? parentElement) : base()
{
RobustXamlLoader.Load(this);
MenuPanel.SetOnlyStyleClass(StyleClassContextMenuPopup);
_presenter = presenter;
ParentElement = parentElement;
//XAML controls are private. So defining and adding MenuBody here instead.
Scroll.AddChild(MenuBody);
// Set Max Height based on MaxItemsBeforeScroll and the panel's style box
MenuPanel.ForceRunStyleUpdate();
MenuPanel.TryGetStyleProperty(PanelContainer.StylePropertyPanel, out var box);
var styleSize = (box?.MinimumSize ?? Vector2.Zero) / UIScale;
MenuPanel.MaxHeight = MaxItemsBeforeScroll * (ContextMenuElement.ElementHeight + 2 * ContextMenuElement.ElementMargin) + styleSize.Y;
UserInterfaceManager.ModalRoot.AddChild(this);
MenuBody.OnChildRemoved += ctrl => _presenter.OnRemoveElement(this, ctrl);
if (ParentElement != null)
{
DebugTools.Assert(ParentElement.SubMenu == null);
ParentElement.SubMenu = this;
}
// ensure the menu-stack is properly updated when a pop-up looses focus or otherwise closes without going
// through the menu presenter.
OnPopupHide += () =>
{
if (ParentElement != null)
_presenter.CloseSubMenus(ParentElement.ParentMenu);
};
}
protected override void Dispose(bool disposing)
{
MenuBody.OnChildRemoved -= ctrl => _presenter.OnRemoveElement(this, ctrl);
ParentElement = null;
base.Dispose(disposing);
}
}
}