cool
This commit is contained in:
@@ -13,7 +13,7 @@ namespace BITKit.Physics
|
||||
public string Name="Default";
|
||||
public readonly Transform Transform;
|
||||
public Vector3 Offset = default;
|
||||
public LayerMask LayerMask=LayerMask.NameToLayer("Default");
|
||||
public LayerMask LayerMask=LayerMask.GetMask("Default");
|
||||
public float Distance=1.6f;
|
||||
public float MinHeight=0.32f;
|
||||
public float MaxHeight = 1f;
|
||||
|
8
Src/Unity/Scripts/SignalR.meta
Normal file
8
Src/Unity/Scripts/SignalR.meta
Normal file
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 5e0aa9ddf175a2248af24307391f860f
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
19
Src/Unity/Scripts/SignalR/Net.BITKit.SignalR.Unity.asmdef
Normal file
19
Src/Unity/Scripts/SignalR/Net.BITKit.SignalR.Unity.asmdef
Normal file
@@ -0,0 +1,19 @@
|
||||
{
|
||||
"name": "Net.BITKit.SignalR.Unity",
|
||||
"rootNamespace": "",
|
||||
"references": [
|
||||
"GUID:14fe60d984bf9f84eac55c6ea033a8f4",
|
||||
"GUID:f51ebe6a0ceec4240a699833d6309b23"
|
||||
],
|
||||
"includePlatforms": [],
|
||||
"excludePlatforms": [],
|
||||
"allowUnsafeCode": false,
|
||||
"overrideReferences": false,
|
||||
"precompiledReferences": [],
|
||||
"autoReferenced": true,
|
||||
"defineConstraints": [
|
||||
"Disabled"
|
||||
],
|
||||
"versionDefines": [],
|
||||
"noEngineReferences": false
|
||||
}
|
@@ -0,0 +1,7 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 032072f82da34ae4895a3c477957e594
|
||||
AssemblyDefinitionImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
68
Src/Unity/Scripts/SignalR/SignalRClient.cs
Normal file
68
Src/Unity/Scripts/SignalR/SignalRClient.cs
Normal file
@@ -0,0 +1,68 @@
|
||||
using System;
|
||||
using Microsoft.AspNetCore.SignalR.Client;
|
||||
using UnityEngine;
|
||||
using System.Threading.Tasks;
|
||||
using BITKit;
|
||||
using Cysharp.Threading.Tasks;
|
||||
using Microsoft.Extensions.Logging;
|
||||
|
||||
public class SignalRClient : MonoBehaviour
|
||||
{
|
||||
[SerializeField] private string url = @"https://yourserver.com/chathub";
|
||||
|
||||
private HubConnection _connection;
|
||||
|
||||
private ILogger<SignalRClient> _logger;
|
||||
|
||||
private StopWatcher _stopWatcher;
|
||||
// 用于与 SignalR 服务器进行通信
|
||||
private async void Start()
|
||||
{
|
||||
await UniTask.Delay(300);
|
||||
|
||||
if(destroyCancellationToken.IsCancellationRequested)return;
|
||||
|
||||
_connection = new HubConnectionBuilder()
|
||||
.WithUrl(url)
|
||||
.Build();
|
||||
|
||||
BITApp.ServiceProvider.QueryComponents(out _logger);
|
||||
|
||||
_connection.On<string, string>("ReceiveMessage", (user, message) =>
|
||||
{
|
||||
_stopWatcher?.Dispose();
|
||||
_logger.LogInformation($"Received from Blazor/Server: {user} - {message}");
|
||||
});
|
||||
|
||||
destroyCancellationToken.Register(Dispose);
|
||||
|
||||
await _connection.StartAsync();
|
||||
_logger.LogInformation("Unity connected to SignalR server!");
|
||||
|
||||
// 发送消息给 Blazor
|
||||
await SendMessageToBlazor("Unity", "Hello from Unity!");
|
||||
|
||||
for (var i = 0; i < 16; i++)
|
||||
{
|
||||
_stopWatcher = new StopWatcher(_logger, $"SignalR延迟 at {i}");
|
||||
|
||||
await SendMessageToBlazor("Unity", "OK,Let's Count!");
|
||||
}
|
||||
|
||||
var id = await _connection.InvokeAsync<string>("GetMessage");
|
||||
|
||||
_logger.LogInformation($"获取用户ID:{id}");
|
||||
|
||||
}
|
||||
|
||||
private async void Dispose()
|
||||
{
|
||||
await _connection.StopAsync();
|
||||
}
|
||||
|
||||
private async Task SendMessageToBlazor(string user, string message)
|
||||
{
|
||||
await _connection.InvokeAsync("SendMessage", user, message);
|
||||
}
|
||||
|
||||
}
|
11
Src/Unity/Scripts/SignalR/SignalRClient.cs.meta
Normal file
11
Src/Unity/Scripts/SignalR/SignalRClient.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: b3430c184bfccd9468f9c938ed99ae48
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@@ -20,7 +20,8 @@
|
||||
"GUID:a11ff146d38b27a44af87b4b4d9c4ecb",
|
||||
"GUID:e4d11af1289097a4d9d8987f332a2ae8",
|
||||
"GUID:3abaaefa7af558d44ba20cea1c43d602",
|
||||
"GUID:d8b63aba1907145bea998dd612889d6b"
|
||||
"GUID:d8b63aba1907145bea998dd612889d6b",
|
||||
"GUID:a3cd7886d0941284aa4f5e020270c73a"
|
||||
],
|
||||
"includePlatforms": [],
|
||||
"excludePlatforms": [],
|
||||
|
@@ -19,6 +19,11 @@ namespace BITKit.UX
|
||||
{
|
||||
name = "ReleasePress"
|
||||
};
|
||||
|
||||
private readonly UxmlStringAttributeDescription m_TextAttribute = new()
|
||||
{
|
||||
name = "Text"
|
||||
};
|
||||
|
||||
public override void Init(VisualElement ve, IUxmlAttributes bag, CreationContext cc)
|
||||
{
|
||||
@@ -26,12 +31,19 @@ namespace BITKit.UX
|
||||
var table = (OnScreenButton)ve;
|
||||
table.PressedValue = m_PressedValueAttribute.GetValueFromBag(bag, cc);
|
||||
table.ReleasePress = m_ReleasePressAttribute.GetValueFromBag(bag, cc);
|
||||
table.Text = m_TextAttribute.GetValueFromBag(bag, cc);
|
||||
}
|
||||
}
|
||||
public new class UxmlFactory : UxmlFactory<OnScreenButton, UxmlTraits> { }
|
||||
public float PressedValue { get; set; }= 1f;
|
||||
public bool ReleasePress { get; set; }
|
||||
|
||||
public string Text
|
||||
{
|
||||
get => _label.text;
|
||||
set => _label.text = value;
|
||||
}
|
||||
|
||||
private bool _isPressed;
|
||||
private int _pointerId=-1;
|
||||
private Label _label;
|
||||
@@ -44,6 +56,7 @@ namespace BITKit.UX
|
||||
RegisterCallback<PointerMoveEvent>(OnPointerMove);
|
||||
this.AddManipulator(new Clickable(OnClick));
|
||||
_label = this.Create<Label>();
|
||||
_label.pickingMode = PickingMode.Ignore;
|
||||
|
||||
_isTriggered.AddListener(x =>
|
||||
{
|
||||
|
@@ -64,10 +64,18 @@ namespace BITKit.UX
|
||||
button.RegisterCallback<PointerOverEvent>(_ =>
|
||||
{
|
||||
SendValueToControl((Vector2)value);
|
||||
|
||||
button.AddToClassList("selected");
|
||||
});
|
||||
button.RegisterCallback<PointerUpEvent>(_ =>
|
||||
{
|
||||
SendValueToControl((Vector2)default);
|
||||
|
||||
button.RemoveFromClassList("selected");
|
||||
});
|
||||
button.RegisterCallback<PointerCancelEvent>(_ =>
|
||||
{
|
||||
button.RemoveFromClassList("selected");
|
||||
});
|
||||
|
||||
// var label = button.Create<Label>();
|
||||
|
@@ -45,12 +45,16 @@ namespace BITKit.UX
|
||||
SendValueToControl(Vector2.zero);
|
||||
_startPosition = evt.position;
|
||||
_ignoreFrame = 1;
|
||||
|
||||
this.ReleasePointer(evt.pointerId);
|
||||
}
|
||||
|
||||
private void OnPointerDown(PointerDownEvent evt)
|
||||
{
|
||||
_ignoreFrame = 1;
|
||||
_startPosition = evt.position;
|
||||
|
||||
this.CapturePointer(evt.pointerId);
|
||||
}
|
||||
|
||||
private void OnPointerMove(PointerMoveEvent evt)
|
||||
|
@@ -81,7 +81,10 @@ namespace BITKit.UX
|
||||
else
|
||||
{
|
||||
var label = instance.Create<Label>();
|
||||
label.text = array[x].ToString();
|
||||
|
||||
var text = array[x].ToString().Replace(@"\r\n", @"\n").Replace(@"\r", @"\n");
|
||||
|
||||
label.text = text;
|
||||
}
|
||||
|
||||
}
|
||||
|
@@ -107,7 +107,8 @@ namespace BITKit.UX
|
||||
var index = i;
|
||||
var button = _buttons[i] = this.Create<Button>();
|
||||
button.AddToClassList("v"+i);
|
||||
button.text = tabName;
|
||||
button.AddToClassList("localized");
|
||||
button.text = button.viewDataKey = tabName;
|
||||
button.focusable = allowFocus;
|
||||
button.clicked += () => CurrentTab = index;
|
||||
}
|
||||
|
@@ -1,78 +1,207 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using BITKit;
|
||||
using BITKit.UX;
|
||||
using Cysharp.Threading.Tasks;
|
||||
using Net.BITKit.Localization;
|
||||
using UnityEngine;
|
||||
using UnityEngine.InputSystem;
|
||||
using UnityEngine.UIElements;
|
||||
|
||||
namespace Net.BITKit.UX
|
||||
{
|
||||
public class UXLocalization
|
||||
public class UXLocalization:IDisposable
|
||||
{
|
||||
public string USS { get; set; } = "localized";
|
||||
public string[] Lang { get; set; } =
|
||||
{
|
||||
"zh-CN",
|
||||
"en-US",
|
||||
"ja-JP",
|
||||
};
|
||||
public static string USS { get; set; } = "localized";
|
||||
private readonly IUXService _uxService;
|
||||
private readonly ILocalizationService _localizationService;
|
||||
private readonly IMainTicker _ticker;
|
||||
|
||||
public UXLocalization(IUXService uxService, ILocalizationService localizationService)
|
||||
public UXLocalization(IUXService uxService, ILocalizationService localizationService, IMainTicker ticker)
|
||||
{
|
||||
_uxService = uxService;
|
||||
_localizationService = localizationService;
|
||||
_ticker = ticker;
|
||||
|
||||
_localizationService.OnLanguageChanged += OnLanguageChanged;
|
||||
_localizationService.OnLocalizeAsync += OnLocalizeAsync;
|
||||
|
||||
_ticker.Add(OnTick);
|
||||
}
|
||||
|
||||
private void OnTick(float obj)
|
||||
{
|
||||
if (Mouse.current.rightButton.wasPressedThisFrame is false) return;
|
||||
if (_uxService.TryPick(Mouse.current.position.ReadValue(), out var o) is false) return;
|
||||
if (o is not VisualElement visualElement) return;
|
||||
if (visualElement.ClassListContains(USS) is false) return;
|
||||
var builder =
|
||||
ContextMenuBuilder
|
||||
.Create()
|
||||
.BuildText(_localizationService.GetLocalizedString("Translate"));
|
||||
|
||||
foreach (var lang in Lang)
|
||||
{
|
||||
builder.BuildAction(lang, () => Localize(visualElement, lang));
|
||||
}
|
||||
/*
|
||||
foreach (var lang in Enum.GetValues(typeof(Lang)))
|
||||
{
|
||||
var code = lang.GetType().GetMember(lang.ToString())[0].GetCustomAttribute<DescriptionAttribute>()
|
||||
.Description;
|
||||
builder.BuildAction(code, () => Localize(visualElement, code));
|
||||
}
|
||||
*/
|
||||
|
||||
builder.BuildAction("Default", () => Localize(visualElement, _localizationService.CurrentLanguage));
|
||||
builder.Build();
|
||||
}
|
||||
|
||||
private UniTask<bool> OnLocalizeAsync(string arg1, object arg2)
|
||||
{
|
||||
if (arg2 is not VisualElement visualElement) return UniTask.FromResult(false);
|
||||
|
||||
Localize((object)visualElement);
|
||||
return UniTask.FromResult(true);
|
||||
}
|
||||
|
||||
private void Localize(VisualElement visualElement, string lang = null)
|
||||
{
|
||||
if (string.IsNullOrEmpty(lang))
|
||||
{
|
||||
lang = _localizationService.CurrentLanguage;
|
||||
}
|
||||
|
||||
var currentLang = _localizationService.GetLocalizedString('#' + visualElement.viewDataKey,
|
||||
_localizationService.CurrentLanguage);
|
||||
|
||||
var translate = _localizationService.GetLocalizedString('#' + visualElement.viewDataKey, lang);
|
||||
|
||||
if (string.Equals(visualElement.tooltip, currentLang))
|
||||
{
|
||||
visualElement.tooltip = translate;
|
||||
foreach (var child in visualElement.Children())
|
||||
{
|
||||
if (child.pickingMode is PickingMode.Position)
|
||||
{
|
||||
child.tooltip = translate;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
switch (visualElement)
|
||||
{
|
||||
case Label label:
|
||||
{
|
||||
label.text = translate;
|
||||
}
|
||||
break;
|
||||
case Button button:
|
||||
{
|
||||
button.text = translate;
|
||||
}
|
||||
break;
|
||||
case ProgressBar progressBar:
|
||||
{
|
||||
progressBar.title = translate;
|
||||
}
|
||||
break;
|
||||
case Foldout foldout:
|
||||
{
|
||||
foldout.text = translate;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
{
|
||||
ContinueWithBaseType(visualElement.GetType());
|
||||
void ContinueWithBaseType(Type type)
|
||||
{
|
||||
while (true)
|
||||
{
|
||||
if (type is not null)
|
||||
{
|
||||
if (type.GetProperty("label", ReflectionHelper.Flags) is { } propertyInfo)
|
||||
{
|
||||
//Debug.Log($"{x.name}:#{x.viewDataKey}");
|
||||
propertyInfo.SetValue(visualElement,translate);
|
||||
}
|
||||
else
|
||||
{
|
||||
type = type.BaseType;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if (type == null || type == typeof(object))
|
||||
{
|
||||
break;
|
||||
//throw new NotImplementedException($"{visualElement.GetType().Name} is not translatable");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
private void Localize(object obj)
|
||||
{
|
||||
switch (obj)
|
||||
{
|
||||
case VisualElement visualElement:
|
||||
{
|
||||
foreach (var x in visualElement.Query(className:USS).Build())
|
||||
{
|
||||
Localize(x);
|
||||
}
|
||||
/*
|
||||
foreach (var x in visualElement.Query<Label>(className:USS).ToList())
|
||||
{
|
||||
if (string.IsNullOrEmpty(x.viewDataKey))continue;
|
||||
x.text = _localizationService.GetLocalizedString('#'+x.viewDataKey);
|
||||
}
|
||||
|
||||
foreach (var x in visualElement.Query<Button>(className:USS).ToList())
|
||||
{
|
||||
if(string.IsNullOrEmpty(x.viewDataKey))continue;
|
||||
x.text = _localizationService.GetLocalizedString('#'+x.viewDataKey);
|
||||
}
|
||||
|
||||
foreach (var x in visualElement.Query<ProgressBar>(className:USS).ToList())
|
||||
{
|
||||
if(string.IsNullOrEmpty(x.viewDataKey))continue;
|
||||
x.title = _localizationService.GetLocalizedString('#'+x.viewDataKey);
|
||||
}
|
||||
|
||||
foreach (var x in visualElement.Query(className:USS).ToList())
|
||||
{
|
||||
if(string.IsNullOrEmpty(x.viewDataKey))continue;
|
||||
continue;
|
||||
}
|
||||
*/
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private void OnLanguageChanged(string arg1, string arg2)
|
||||
{
|
||||
if(_uxService.Root is not VisualElement visualElement)return;
|
||||
if (_uxService.Root is not VisualElement visualElement) return;
|
||||
|
||||
foreach (var x in visualElement.Query<Label>(className:USS).ToList())
|
||||
{
|
||||
if (string.IsNullOrEmpty(x.viewDataKey))continue;
|
||||
x.text = _localizationService.GetLocalizedString('#'+x.viewDataKey);
|
||||
}
|
||||
Localize(visualElement);
|
||||
}
|
||||
|
||||
foreach (var x in visualElement.Query<Button>(className:USS).ToList())
|
||||
{
|
||||
if(string.IsNullOrEmpty(x.viewDataKey))continue;
|
||||
x.text = _localizationService.GetLocalizedString('#'+x.viewDataKey);
|
||||
}
|
||||
|
||||
foreach (var x in visualElement.Query<ProgressBar>(className:USS).ToList())
|
||||
{
|
||||
if(string.IsNullOrEmpty(x.viewDataKey))continue;
|
||||
x.title = _localizationService.GetLocalizedString('#'+x.viewDataKey);
|
||||
}
|
||||
|
||||
foreach (var x in visualElement.Query(className:USS).ToList())
|
||||
{
|
||||
if(string.IsNullOrEmpty(x.viewDataKey))continue;
|
||||
|
||||
ContinueWithBaseType(x.GetType());
|
||||
continue;
|
||||
|
||||
void ContinueWithBaseType(Type type)
|
||||
{
|
||||
while (true)
|
||||
{
|
||||
if (type == null || type == typeof(object)) return;
|
||||
if (type.GetProperty("label", ReflectionHelper.Flags) is { } propertyInfo)
|
||||
{
|
||||
//Debug.Log($"{x.name}:#{x.viewDataKey}");
|
||||
propertyInfo.SetValue(x, _localizationService.GetLocalizedString('#' + x.viewDataKey));
|
||||
}
|
||||
else
|
||||
{
|
||||
type = type.BaseType;
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
public void Dispose()
|
||||
{
|
||||
_ticker.Remove(OnTick);
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -10,6 +10,7 @@ namespace BITKit.UX
|
||||
{
|
||||
public class UXRadialMenu : UIToolKitPanel,IUXHotKey
|
||||
{
|
||||
private static UXRadialMenu _singleton;
|
||||
protected override string DocumentPath => "ui_radial_menu";
|
||||
public override bool CloseWhenClickOutside => true;
|
||||
public override bool AllowCursor => true;
|
||||
@@ -27,6 +28,13 @@ namespace BITKit.UX
|
||||
public UXRadialMenu(IUXService uxService) : base(uxService)
|
||||
{
|
||||
OnInitiatedAsync += InitiatedAsync;
|
||||
|
||||
if (_singleton is not null)
|
||||
{
|
||||
throw new InvalidOperationException($"{nameof(UXRadialMenu)} only can be one singleton");
|
||||
}
|
||||
|
||||
_singleton = this;
|
||||
}
|
||||
|
||||
private async UniTask InitiatedAsync()
|
||||
@@ -131,6 +139,13 @@ var button = container.Get<Button>();
|
||||
}
|
||||
UXService.Entry(this);
|
||||
}
|
||||
|
||||
|
||||
public override void Dispose()
|
||||
{
|
||||
base.Dispose();
|
||||
_singleton = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -6,6 +6,7 @@ using System.Threading;
|
||||
using BITKit.Mod;
|
||||
using BITKit.StateMachine;
|
||||
using Cysharp.Threading.Tasks;
|
||||
using Net.BITKit.Localization;
|
||||
using UnityEngine;
|
||||
using UnityEngine.Serialization;
|
||||
using UnityEngine.InputSystem;
|
||||
@@ -107,10 +108,17 @@ namespace BITKit.UX
|
||||
RootVisualElement.RegisterCallback<TransitionEndEvent>(OnTransitionEnd);
|
||||
RootVisualElement.RegisterCallback<TransitionCancelEvent>(OnTransitionEnd);
|
||||
|
||||
if (BITApp.ServiceProvider.QueryComponents(out ILocalizationService localizationService))
|
||||
{
|
||||
await localizationService.LocalizeAsync(RootVisualElement);
|
||||
}
|
||||
|
||||
|
||||
WaitUtilTransitionCompleted.TrySetResult();
|
||||
|
||||
WaitUtilInitialized.TrySetResult();
|
||||
|
||||
|
||||
OnInitiated?.Invoke();
|
||||
}
|
||||
}
|
||||
@@ -206,6 +214,8 @@ namespace BITKit.UX
|
||||
|
||||
RootVisualElement.RemoveFromClassList(USSEntry);
|
||||
RootVisualElement.RemoveFromClassList(USSEntryAsync);
|
||||
|
||||
IsEntered = true;
|
||||
}
|
||||
private void OnTransitionEnd<TChangeEvent>(TChangeEvent evt)
|
||||
{
|
||||
@@ -219,6 +229,8 @@ namespace BITKit.UX
|
||||
|
||||
public override void OnStateExit(IState old, IState newState)
|
||||
{
|
||||
IsEntered = false;
|
||||
|
||||
OnPanelExit();
|
||||
InputActionGroup.allowInput.RemoveElement(this);
|
||||
OnExit?.Invoke();
|
||||
|
@@ -4,6 +4,7 @@ using System.Collections.Generic;
|
||||
using BITKit.StateMachine;
|
||||
using Cysharp.Threading.Tasks;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Net.BITKit.Localization;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UIElements;
|
||||
|
||||
@@ -11,16 +12,13 @@ namespace BITKit.UX
|
||||
{
|
||||
public class UIToolkitSubPanel<T> :IUXPanel where T : IUXPanel
|
||||
{
|
||||
private readonly IServiceProvider _serviceProvider;
|
||||
protected readonly T Panel;
|
||||
|
||||
protected readonly ValidHandle IsVisible=new();
|
||||
private readonly ValidHandle _busy = new();
|
||||
|
||||
public UIToolkitSubPanel(IServiceProvider serviceProvider)
|
||||
{
|
||||
_serviceProvider = serviceProvider;
|
||||
|
||||
protected UIToolkitSubPanel(IServiceProvider serviceProvider)
|
||||
{
|
||||
Panel = serviceProvider.GetRequiredService<T>();
|
||||
|
||||
Panel.OnInitiated += OnInitiated;
|
||||
|
@@ -72,7 +72,7 @@ namespace BITKit.UX.Settings
|
||||
slider.label = _localizationService.GetLocalizedString(name);
|
||||
slider.showInputField = true;
|
||||
slider.showMixedValue = true;
|
||||
slider.lowValue = 1;
|
||||
slider.lowValue = 0.01f;
|
||||
slider.highValue = 100;
|
||||
slider.SetValueWithoutNotify(value.As<float>());
|
||||
slider.RegisterValueChangedCallback(x =>
|
||||
|
@@ -10,16 +10,27 @@ using UnityEngine.UIElements;
|
||||
|
||||
namespace Net.BITKit.UX.SnackBar
|
||||
{
|
||||
public class UXSnackBar<TPanel> : UIToolkitSubPanel<TPanel>,ISnackBar where TPanel :IUXPanel
|
||||
public static class UXSnackBarStatic
|
||||
{
|
||||
public static int Count;
|
||||
}
|
||||
public class UXSnackBar<TPanel> : UIToolkitSubPanel<TPanel>,IDisposable,ISnackBar where TPanel :IUXPanel
|
||||
{
|
||||
[UXBindPath("snack_bar-container")] private VisualElement _snackBarContainer;
|
||||
|
||||
private VisualTreeAsset _template;
|
||||
|
||||
private readonly ValidHandle _waitHandle = new ValidHandle();
|
||||
|
||||
private readonly Queue<(string message,Severity severity)> _queue=new();
|
||||
|
||||
public UXSnackBar(IServiceProvider serviceProvider) : base(serviceProvider)
|
||||
{
|
||||
if (UXSnackBarStatic.Count > 0)
|
||||
{
|
||||
throw new Exception("SnackBar can only be created once");
|
||||
}
|
||||
UXSnackBarStatic.Count++;
|
||||
}
|
||||
|
||||
protected override void OnInitiated()
|
||||
@@ -30,6 +41,11 @@ namespace Net.BITKit.UX.SnackBar
|
||||
_snackBarContainer.Clear();
|
||||
|
||||
BITAppForUnity.AllowCursor.AddListener(OnAllowCursor);
|
||||
|
||||
while (_queue.TryDequeue(out var temp ))
|
||||
{
|
||||
Add(temp.message,temp.severity);
|
||||
}
|
||||
}
|
||||
|
||||
private void OnAllowCursor(bool obj)
|
||||
@@ -44,26 +60,43 @@ namespace Net.BITKit.UX.SnackBar
|
||||
}
|
||||
}
|
||||
|
||||
public async void Add(string message, Severity severity = Severity.Normal)
|
||||
public void Add(string message, Severity severity = Severity.Normal)
|
||||
{
|
||||
if (_snackBarContainer is null)
|
||||
{
|
||||
_queue.Enqueue(new ValueTuple<string, Severity>(message,severity));
|
||||
return;
|
||||
}
|
||||
|
||||
var ve = _snackBarContainer.Create(_template);
|
||||
|
||||
ve.AddToClassList($"severity-{severity.ToString().ToLower()}");
|
||||
|
||||
ve.Get<Label>().text = message;
|
||||
|
||||
if (ve.Q("VisualElement--1") is { } bar)
|
||||
{
|
||||
await BITween.Lerp(x => bar.style.width = new StyleLength(Length.Percent(x)), 0f, 100, 5, Mathf.Lerp);
|
||||
}
|
||||
else
|
||||
{
|
||||
await UniTask.Delay(5000);
|
||||
}
|
||||
Continue();
|
||||
|
||||
await _waitHandle;
|
||||
return;
|
||||
async void Continue()
|
||||
{
|
||||
if (ve.Q("VisualElement--1") is { } bar)
|
||||
{
|
||||
await BITween.Lerp(x => bar.style.width = new StyleLength(Length.Percent(x)), 0f, 100, 5, Mathf.Lerp);
|
||||
}
|
||||
else
|
||||
{
|
||||
await UniTask.Delay(5000);
|
||||
}
|
||||
|
||||
await _waitHandle;
|
||||
|
||||
ve.RemoveFromHierarchy();
|
||||
ve.RemoveFromHierarchy();
|
||||
}
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
UXSnackBarStatic.Count--;
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -48,6 +48,9 @@ namespace BITKit.UX
|
||||
Hovering = null;
|
||||
return;
|
||||
}
|
||||
|
||||
if(_rootVisualElement is not {panel:not null})return;
|
||||
|
||||
var tooltip = CurrentToolTip(_rootVisualElement.panel);
|
||||
if (tooltip != "")
|
||||
{
|
||||
|
@@ -71,10 +71,9 @@ namespace BITKit.UX
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
foreach (var fieldInfo in self.GetType()
|
||||
.GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.DeclaredOnly)
|
||||
foreach (var fieldInfo in BITSharp.GetAllBaseType(self.GetType()).SelectMany(x=>x.GetFields(ReflectionHelper.Flags))
|
||||
.Where(x => x.GetCustomAttribute<UXBindPathAttribute>() is not null)
|
||||
)
|
||||
{
|
||||
@@ -100,9 +99,10 @@ namespace BITKit.UX
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
BIT4Log.Warning<UXUtils>(fieldInfo!.Name);
|
||||
BIT4Log.Warning<UXUtils>($"{fieldInfo!.Name}:{e.Message}");
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -668,6 +668,7 @@ namespace BITKit
|
||||
{
|
||||
self.style.display = new(active ? DisplayStyle.Flex : DisplayStyle.None);
|
||||
}
|
||||
|
||||
public static void SetVisible(this VisualElement self, bool visible)
|
||||
{
|
||||
self.style.visibility = new(visible ? Visibility.Visible : Visibility.Hidden);
|
||||
|
Reference in New Issue
Block a user