172 lines
4.4 KiB
C#
172 lines
4.4 KiB
C#
using System;
|
|
using System.Collections;
|
|
using System.Collections.Concurrent;
|
|
using System.Collections.Generic;
|
|
using System.IO;
|
|
using System.Linq;
|
|
using System.Reflection;
|
|
using System.Threading;
|
|
#if UNITY_5_3_OR_NEWER && UNITY_WINDOW
|
|
using AnotherFileBrowser.Windows;
|
|
#endif
|
|
using BITKit.Mod;
|
|
using Cysharp.Threading.Tasks;
|
|
using UnityEngine;
|
|
using UnityEngine.InputSystem;
|
|
using UnityEngine.UIElements;
|
|
using Pointer = UnityEngine.InputSystem.Pointer;
|
|
|
|
namespace BITKit.UX
|
|
{
|
|
public class UXModService:UIToolKitPanel
|
|
{
|
|
protected override string DocumentPath => "ux_mod_Service";
|
|
private const string TemplatePath = "ux_mod_service_template";
|
|
public override bool AllowCursor => true;
|
|
|
|
|
|
private VisualTreeAsset _modTemplate;
|
|
[UXBindPath("open_folder-button")]
|
|
private Button _openFolderButton;
|
|
[UXBindPath("open-mod-button")]
|
|
private Button _openModButton;
|
|
[UXBindPath("mods-container")]
|
|
private VisualElement _modsContainer;
|
|
[UXBindPath("return-button")]
|
|
private Button _returnButton;
|
|
[UXBindPath("mod-name-label")]
|
|
private Label _modNameLabel;
|
|
[UXBindPath("mod-description-label")]
|
|
private Label _modDescriptionLabel;
|
|
[UXBindPath("reload-mod-button",true)]
|
|
private Button _reloadModButton;
|
|
|
|
|
|
private readonly ConcurrentDictionary<string,VisualElement> _modContainers=new();
|
|
public UXModService(IUXService uxService) : base(uxService)
|
|
{
|
|
ModService.OnModInstalled+=OnModInstalled;
|
|
ModService.OnModUnInstalled+=OnModUnInstalled;
|
|
ModService.OnModLoaded+=OnModLoaded;
|
|
ModService.OnModUnLoaded+=OnModUnLoaded;
|
|
ModService.IsBusy.AddListener(OnLocked);
|
|
|
|
OnInitiatedAsync += InitializeAsync;
|
|
}
|
|
|
|
private async UniTask InitializeAsync()
|
|
{
|
|
_modTemplate =await ModService.LoadAsset<VisualTreeAsset>(TemplatePath);
|
|
UXUtils.Inject(this);
|
|
|
|
if (_returnButton is not null)
|
|
{
|
|
_returnButton.clicked += UXService.Return;
|
|
}
|
|
|
|
_modsContainer.Clear();
|
|
foreach (var x in ModService.Mods)
|
|
{
|
|
OnModInstalled(x);
|
|
}
|
|
|
|
if (_reloadModButton is not null)
|
|
_reloadModButton.clicked += async () =>
|
|
{
|
|
_reloadModButton.SetEnabled(false);
|
|
await ModService.Reload();
|
|
await UniTask.SwitchToMainThread();
|
|
_reloadModButton.SetEnabled(true);
|
|
};
|
|
|
|
_openFolderButton.clicked += () =>
|
|
{
|
|
new BITApp.OpenPath()
|
|
{
|
|
path = Path.Combine(Environment.CurrentDirectory, "Mods")
|
|
}.Execute();
|
|
};
|
|
|
|
}
|
|
|
|
private void OnLocked(bool obj)
|
|
{
|
|
RootVisualElement?.SetEnabled(!obj);
|
|
}
|
|
|
|
private async void OnModUnInstalled(IMod obj)
|
|
{
|
|
await UniTask.SwitchToMainThread();
|
|
_modContainers.TryRemove(obj.Name, out var container);
|
|
container.RemoveFromHierarchy();
|
|
}
|
|
|
|
private async void OnModInstalled(IMod obj)
|
|
{
|
|
await UniTask.SwitchToMainThread();
|
|
var container = _modContainers.GetOrAdd(obj.Name,_=> Create(obj));
|
|
container.RegisterCallback<MouseDownEvent>(x =>
|
|
{
|
|
if (x.button != 1) return;
|
|
ContextMenuBuilder.Create().BuildAction("卸载", () =>
|
|
{
|
|
ModService.UnLoad(obj);
|
|
ModService.UnInstall(obj);
|
|
}).Build();
|
|
});
|
|
}
|
|
private async void OnModUnLoaded(IMod obj)
|
|
{
|
|
await UniTask.SwitchToMainThread();
|
|
//var container = _modContainers.GetOrAdd(obj.Name,_=> Create(obj));
|
|
if(_modContainers.TryGetValue(obj.Name,out var container))
|
|
{
|
|
container.Get<Toggle>().SetValueWithoutNotify(false);
|
|
}
|
|
}
|
|
|
|
private async void OnModLoaded(IMod obj)
|
|
{
|
|
await UniTask.SwitchToMainThread();
|
|
var container = _modContainers.GetOrAdd(obj.Name,_=> Create(obj));
|
|
container.Get<Toggle>().SetValueWithoutNotify(true);
|
|
}
|
|
private VisualElement Create(IMod mod)
|
|
{
|
|
var container =_modsContainer.Create(_modTemplate);
|
|
container.Get<Toggle>().SetValueWithoutNotify(ModService.Mods.Contains(mod));
|
|
container.Get<Toggle>().RegisterValueChangedCallback(evt =>
|
|
{
|
|
if (evt.newValue)
|
|
{
|
|
ModService.Load(mod);
|
|
}
|
|
else
|
|
{
|
|
ModService.UnLoad(mod);
|
|
}
|
|
});
|
|
container.Get<Label>().text = mod.Name +"@"+mod.PackageName;
|
|
container.tooltip = mod.Name+"\n"+mod.Description;
|
|
|
|
container.Get<Button>().clicked += () =>
|
|
{
|
|
_modNameLabel.text = mod.Name;
|
|
_modDescriptionLabel.text = mod.Description;
|
|
};
|
|
return container;
|
|
}
|
|
|
|
public override void Dispose()
|
|
{
|
|
base.Dispose();
|
|
ModService.OnModInstalled-=OnModInstalled;
|
|
ModService.OnModUnInstalled-=OnModUnInstalled;
|
|
ModService.OnModLoaded-=OnModLoaded;
|
|
ModService.OnModUnLoaded-=OnModUnLoaded;
|
|
ModService.IsBusy.RemoveListener(OnLocked);
|
|
}
|
|
}
|
|
|
|
}
|