ContextMenu (#3286)
* ContextMenu * Updating to WPF. * Updating to WPF. * Margins
This commit is contained in:
committed by
GitHub
parent
51182c8469
commit
f30a4d8a52
233
Content.Client/UserInterface/ContextMenu/ContextMenuElement.cs
Normal file
233
Content.Client/UserInterface/ContextMenu/ContextMenuElement.cs
Normal file
@@ -0,0 +1,233 @@
|
||||
#nullable enable
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Content.Client.GameObjects.Components;
|
||||
using Content.Client.UserInterface.Stylesheets;
|
||||
using Content.Client.Utility;
|
||||
using Robust.Client.GameObjects;
|
||||
using Robust.Client.Graphics;
|
||||
using Robust.Client.ResourceManagement;
|
||||
using Robust.Client.UserInterface;
|
||||
using Robust.Client.UserInterface.Controls;
|
||||
using Robust.Shared.GameObjects;
|
||||
using Robust.Shared.IoC;
|
||||
using Robust.Shared.Localization;
|
||||
using Robust.Shared.Maths;
|
||||
using Vector2 = Robust.Shared.Maths.Vector2;
|
||||
|
||||
namespace Content.Client.UserInterface.ContextMenu
|
||||
{
|
||||
public abstract class ContextMenuElement : Control
|
||||
{
|
||||
private static readonly Color HoverColor = Color.DarkSlateGray;
|
||||
protected internal readonly ContextMenuPopup? ParentMenu;
|
||||
|
||||
protected ContextMenuElement(ContextMenuPopup? parentMenu)
|
||||
{
|
||||
ParentMenu = parentMenu;
|
||||
MouseFilter = MouseFilterMode.Stop;
|
||||
}
|
||||
protected override void Draw(DrawingHandleScreen handle)
|
||||
{
|
||||
base.Draw(handle);
|
||||
|
||||
if (UserInterfaceManager.CurrentlyHovered == this)
|
||||
{
|
||||
handle.DrawRect(PixelSizeBox, HoverColor);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public sealed class SingleContextElement : ContextMenuElement
|
||||
{
|
||||
public event Action? OnMouseHovering;
|
||||
public event Action? OnExitedTree;
|
||||
|
||||
public IEntity ContextEntity{ get; }
|
||||
public readonly StackContextElement? Pre;
|
||||
|
||||
public ISpriteComponent? SpriteComp { get; }
|
||||
public InteractionOutlineComponent? OutlineComponent { get; }
|
||||
public int OriginalDrawDepth { get; }
|
||||
public bool DrawOutline { get; set; }
|
||||
|
||||
public SingleContextElement(IEntity entity, StackContextElement? pre, ContextMenuPopup? parentMenu) : base(parentMenu)
|
||||
{
|
||||
Pre = pre;
|
||||
ContextEntity = entity;
|
||||
if (ContextEntity.TryGetComponent(out ISpriteComponent? sprite))
|
||||
{
|
||||
SpriteComp = sprite;
|
||||
OriginalDrawDepth = SpriteComp.DrawDepth;
|
||||
}
|
||||
OutlineComponent = ContextEntity.GetComponentOrNull<InteractionOutlineComponent>();
|
||||
|
||||
AddChild(
|
||||
new HBoxContainer
|
||||
{
|
||||
SeparationOverride = 6,
|
||||
Children =
|
||||
{
|
||||
new LayoutContainer
|
||||
{
|
||||
Children = { new SpriteView { Sprite = SpriteComp } }
|
||||
},
|
||||
new Label
|
||||
{
|
||||
Text = Loc.GetString(UserInterfaceManager.DebugMonitors.Visible ? $"{ContextEntity.Name} ({ContextEntity.Uid})" : ContextEntity.Name)
|
||||
}
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
protected override void Draw(DrawingHandleScreen handle)
|
||||
{
|
||||
base.Draw(handle);
|
||||
if (UserInterfaceManager.CurrentlyHovered == this)
|
||||
{
|
||||
OnMouseHovering?.Invoke();
|
||||
}
|
||||
}
|
||||
|
||||
protected override void ExitedTree()
|
||||
{
|
||||
OnExitedTree?.Invoke();
|
||||
base.ExitedTree();
|
||||
}
|
||||
}
|
||||
|
||||
public sealed class StackContextElement : ContextMenuElement
|
||||
{
|
||||
public event Action? OnExitedTree;
|
||||
public readonly TimeSpan HoverDelay = TimeSpan.FromSeconds(0.2);
|
||||
|
||||
public HashSet<IEntity> ContextEntities { get; }
|
||||
public readonly StackContextElement? Pre;
|
||||
|
||||
private readonly SpriteView _spriteView;
|
||||
private readonly Label _label;
|
||||
|
||||
public int EntitiesCount => ContextEntities.Count;
|
||||
|
||||
public StackContextElement(IEnumerable<IEntity> entities, StackContextElement? pre, ContextMenuPopup? parentMenu)
|
||||
: base(parentMenu)
|
||||
{
|
||||
Pre = pre;
|
||||
ContextEntities = new(entities);
|
||||
_spriteView = new SpriteView
|
||||
{
|
||||
Sprite = ContextEntities.First().GetComponent<ISpriteComponent>()
|
||||
};
|
||||
_label = new Label
|
||||
{
|
||||
Text = Loc.GetString(ContextEntities.Count.ToString()),
|
||||
StyleClasses = { StyleNano.StyleClassContextMenuCount }
|
||||
};
|
||||
|
||||
LayoutContainer.SetAnchorPreset(_label, LayoutContainer.LayoutPreset.BottomRight);
|
||||
LayoutContainer.SetGrowHorizontal(_label, LayoutContainer.GrowDirection.Begin);
|
||||
LayoutContainer.SetGrowVertical(_label, LayoutContainer.GrowDirection.Begin);
|
||||
|
||||
AddChild(
|
||||
new HBoxContainer()
|
||||
{
|
||||
SeparationOverride = 6,
|
||||
Children =
|
||||
{
|
||||
new LayoutContainer { Children = { _spriteView, _label } },
|
||||
new HBoxContainer()
|
||||
{
|
||||
SeparationOverride = 6,
|
||||
Children =
|
||||
{
|
||||
new Label
|
||||
{
|
||||
Text = Loc.GetString(ContextEntities.First().Name)
|
||||
},
|
||||
new TextureRect
|
||||
{
|
||||
Texture = IoCManager.Resolve<IResourceCache>().GetTexture("/Textures/Interface/VerbIcons/group.svg.96dpi.png"),
|
||||
Stretch = TextureRect.StretchMode.KeepCentered,
|
||||
}
|
||||
},
|
||||
}
|
||||
},
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
protected override void ExitedTree()
|
||||
{
|
||||
OnExitedTree?.Invoke();
|
||||
base.ExitedTree();
|
||||
}
|
||||
|
||||
public void RemoveEntity(IEntity entity)
|
||||
{
|
||||
ContextEntities.Remove(entity);
|
||||
|
||||
_label.Text = Loc.GetString(ContextEntities.Count.ToString());
|
||||
_spriteView.Sprite = ContextEntities.FirstOrDefault(e => !e.Deleted)?.GetComponent<ISpriteComponent>();
|
||||
}
|
||||
}
|
||||
|
||||
public sealed class ContextMenuPopup : Popup
|
||||
{
|
||||
private static readonly Color DefaultColor = Color.FromHex("#1116");
|
||||
private static readonly Color MarginColor = Color.FromHex("#222E");
|
||||
private const int MaxItemsBeforeScroll = 10;
|
||||
|
||||
public VBoxContainer List { get; }
|
||||
public int Depth { get; }
|
||||
|
||||
public ContextMenuPopup(int depth = 0)
|
||||
{
|
||||
Depth = depth;
|
||||
AddChild(new ScrollContainer
|
||||
{
|
||||
HScrollEnabled = false,
|
||||
Children = { new PanelContainer
|
||||
{
|
||||
Children = { (List = new VBoxContainer()) },
|
||||
PanelOverride = new StyleBoxFlat { BackgroundColor = MarginColor }
|
||||
}}
|
||||
});
|
||||
}
|
||||
|
||||
public void AddToMenu(ContextMenuElement element)
|
||||
{
|
||||
List.AddChild(new PanelContainer
|
||||
{
|
||||
Children = { element },
|
||||
Margin = new Thickness(0,0,0, 2),
|
||||
PanelOverride = new StyleBoxFlat {BackgroundColor = DefaultColor}
|
||||
});
|
||||
}
|
||||
|
||||
public void RemoveFromMenu(ContextMenuElement element)
|
||||
{
|
||||
List.RemoveChild(element.Parent!);
|
||||
InvalidateMeasure();
|
||||
}
|
||||
|
||||
protected override Vector2 MeasureOverride(Vector2 availableSize)
|
||||
{
|
||||
if (List.ChildCount == 0)
|
||||
{
|
||||
return Vector2.Zero;
|
||||
}
|
||||
|
||||
List.Measure(availableSize);
|
||||
var listSize = List.DesiredSize;
|
||||
|
||||
if (List.ChildCount < MaxItemsBeforeScroll)
|
||||
{
|
||||
return listSize;
|
||||
}
|
||||
listSize.Y = MaxItemsBeforeScroll * 32 + MaxItemsBeforeScroll * 2;
|
||||
return listSize;
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user