using System.Collections.Generic; using FairyGUI; using NBC; namespace NBF { public class Notices : INoticeComponent { public enum NoticeType { Info = 0, Success, Error, Warning, } class NoticeData { public NoticeType Type; public string Text; } private static bool _init; private const int Gap = 8; private const int ItemWidth = 330; private float _startY; private float _startX; private const int LimitCount = 6; //显示条数上限 private GObjectPool _noticePool; private static readonly Queue _msgArr = new(); protected GComponent ContentPane; public static void Info(string msg, NoticeType noticeType = NoticeType.Info) { if (string.IsNullOrEmpty(msg)) return; Log.Info($"显示一个notice={msg}"); if (!_init) { NoticesPanel.TryAddNoticeComponent(new Notices()); } _msgArr.Enqueue(new NoticeData { Type = noticeType, Text = msg }); } public static void Success(string msg) { Info(msg, NoticeType.Success); } public static void Warning(string msg) { Info(msg, NoticeType.Warning); } public static void Error(string msg) { Info(msg, NoticeType.Error); } public void OnInit(GComponent root) { _init = true; ContentPane = root; _noticePool = new GObjectPool(ContentPane.container.cachedTransform); _startY = Gap + 140; _startX = GRoot.inst.width - ItemWidth - Gap; } public void OnUpdate() { if (_msgArr.Count > 0) { var msg = _msgArr.Dequeue(); ShowOnceNotice(msg); //旧的向上移动 var count = ContentPane.numChildren - 1; for (int i = 0; i < count; i++) { GObject obj = ContentPane.GetChildAt(i); if (obj != null) { SetObjRise(obj); } } RemoveLimitMsg(); } } public void OnDestroy() { _noticePool.Clear(); } private void ShowOnceNotice(NoticeData notice) { var item = GetFromPool(NotificationItem.URL) as NotificationItem; if (item == null) return; item.SetData(notice.Text, notice.Type); item.x = _startX; item.y = _startY; item.alpha = 1; //显示在固定区域 两秒后消失 item.TweenFade(0, 0.5f).SetDelay(3).OnComplete(() => { ReturnToPool(item); }); } private void SetObjRise(GObject item) { item.TweenMoveY(item.y + item.height + Gap, 0.2f).SetEase(EaseType.QuintInOut); } private void RemoveLimitMsg() { var count = ContentPane.numChildren; if (count > LimitCount) { for (int i = 0; i < count - LimitCount; i++) { GObject obj = ContentPane.GetChildAt(i); if (obj != null) { if (GTween.IsTweening(obj)) { GTween.Kill(obj, true); } else { ReturnToPool(obj); } } } } } private GObject GetFromPool(string url) { var ret = _noticePool.GetObject(url); if (ret == null) return null; ret.visible = true; ContentPane.AddChild(ret); GTween.GetTween(ret, TweenPropType.Y)?.Kill(); return ret; } private void ReturnToPool(GObject obj) { ContentPane.RemoveChild(obj); _noticePool.ReturnObject(obj); } } }