BITKit/Src/Unity/Scripts/UX/RadialMenu/UXRadialMenu.cs

112 lines
2.5 KiB
C#

using System;
using System.Linq;
using BITKit.Mod;
using BITKit.UX.Hotkey;
using Cysharp.Threading.Tasks;
using UnityEngine;
using UnityEngine.UIElements;
namespace BITKit.UX
{
public class UXRadialMenu : UIToolKitPanel
{
protected override string DocumentPath => "ui_radial_menu";
public override bool CloseWhenClickOutside => true;
public override bool AllowCursor => true;
private VisualTreeAsset _template;
[UXBindPath("radialMenu-container")]
private VisualElement _container;
[UXBindPath("info-label")]
private Label _infoLabel;
public IHotkeyCollection HotkeyCollection { get; set; }
public UXRadialMenu(IUXService uxService) : base(uxService)
{
OnInitiatedAsync += InitiatedAsync;
}
private async UniTask InitiatedAsync()
{
_container.Clear();
_template =await ModService.LoadAsset<VisualTreeAsset>("ui_radial_menu-template");
RootVisualElement.RegisterCallback<PointerDownEvent>(x =>
{
UXService.Return();
});
}
protected override void OnPanelEntry()
{
base.OnPanelEntry();
_infoLabel.text = "选择快速动作";
if (HotkeyCollection is null)
{
_infoLabel.text = "<color=yellow>没有快速动作</color>";
return;
}
var count = HotkeyCollection.Hotkeys.Count();
if (count is 0)
{
_infoLabel.text = "<color=yellow>目前没有快速动作</color>";
}
for (var i = 0; i < count; i++)
{
var hotkey = HotkeyCollection.Hotkeys.ElementAt(i);
var angle = 360 / count * i;
var pos = Quaternion.Euler(0, 0, angle) * Vector3.up * 384;
pos.y *= 0.64f;
var container = _container.Create<VisualElement>(_template.CloneTree);
var button = container.Get<Button>();
button.text = hotkey.Name;
button.focusable = false;
button.clickable = hotkey.HoldDuration is 0 ? new Clickable(OnClick) : null;
container.style.position = Position.Absolute;
container.transform.position = pos;
container.SetEnabled(hotkey.Enabled);
container.RegisterCallback<PointerOverEvent>(OnMouseOver);
continue;
void OnClick()
{
if (!hotkey.Enabled) return;
if (hotkey.OnPerform is not null)
{
try
{
hotkey.OnPerform();
}
catch (Exception e)
{
Debug.LogException(e);
}
}
UXService.Return();
}
void OnMouseOver(PointerOverEvent evt)
{
_infoLabel.text = hotkey.Description;
}
}
}
protected override void OnPanelExit()
{
base.OnPanelExit();
_container.Clear();
}
}
}