迁移剩下的 UI 到 Serialization 方式
This commit is contained in:
@@ -0,0 +1,188 @@
|
||||
using System;
|
||||
using Cysharp.Threading.Tasks;
|
||||
using SepCore.AsyncTask;
|
||||
using SepCore.Event;
|
||||
using UnityEngine;
|
||||
using UnityGameFramework.Runtime;
|
||||
|
||||
namespace SepCore.UI
|
||||
{
|
||||
public partial class ItemTooltipForm : UGuiForm
|
||||
{
|
||||
[SerializeField] private bool _autoResizeHeight = true;
|
||||
|
||||
[SerializeField] private float _fixedTopHeight = 150f;
|
||||
|
||||
[SerializeField] private float _fixedBottomHeight = 150f;
|
||||
|
||||
[SerializeField] private float _fixedWidth = 300f;
|
||||
|
||||
[SerializeField] private float _screenEdgePadding = 0f;
|
||||
|
||||
private ItemTooltipContext _context;
|
||||
|
||||
private Vector3 _targetPos;
|
||||
|
||||
private bool _listenersBound;
|
||||
|
||||
public async UniTaskVoid RefreshUI(ItemTooltipContext context)
|
||||
{
|
||||
EnsureListeners();
|
||||
|
||||
_context = context;
|
||||
|
||||
_targetPos = ConvertWorldToAnchored(_context.TargetPos);
|
||||
|
||||
View.contentRectTransform.anchoredPosition3D = _targetPos;
|
||||
|
||||
View.titleText.text = _context.Title;
|
||||
View.typeText.text = BuildTypeText(_context.ItemType);
|
||||
View.infoText.text = _context.Description;
|
||||
View.textFormatText.Set(_context.Price);
|
||||
|
||||
View.recycleButton.gameObject.SetActive(_context.ShowRecycleButton);
|
||||
|
||||
if (!string.IsNullOrEmpty(_context.IconAssetName))
|
||||
{
|
||||
string iconAssetName = _context.IconAssetName;
|
||||
var sprite = await SpriteLoader.LoadSpriteByKeyAsync(iconAssetName);
|
||||
if (_context != null && _context.IconAssetName == iconAssetName)
|
||||
{
|
||||
View.iconArea.OnInit(sprite, context.Rarity);
|
||||
ResizeToFitContent();
|
||||
ApplyClampedTargetPos();
|
||||
}
|
||||
}
|
||||
|
||||
ResizeToFitContent();
|
||||
ApplyClampedTargetPos();
|
||||
}
|
||||
|
||||
protected override void OnOpen(object userData)
|
||||
{
|
||||
base.OnOpen(userData);
|
||||
|
||||
if (userData is not ItemTooltipContext context)
|
||||
{
|
||||
Log.Error("ItemTooltipForm context is invalid.");
|
||||
return;
|
||||
}
|
||||
|
||||
RefreshUI(context).Forget();
|
||||
}
|
||||
|
||||
protected override void OnClose(bool isShutdown, object userData)
|
||||
{
|
||||
_context = null;
|
||||
base.OnClose(isShutdown, userData);
|
||||
}
|
||||
|
||||
public void OnRecycleButtonClick()
|
||||
{
|
||||
GameEntry.Event.Fire(this, ItemTooltipRecycleEventArgs.Create(_context.Index, _context.Price));
|
||||
}
|
||||
|
||||
public void OnCancelButtonClick()
|
||||
{
|
||||
GameEntry.Event.Fire(this, ItemTooltipHideEventArgs.Create());
|
||||
}
|
||||
|
||||
private void EnsureListeners()
|
||||
{
|
||||
if (_listenersBound)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
_listenersBound = true;
|
||||
|
||||
View.recycleButton.onClick.AddListener(OnRecycleButtonClick);
|
||||
View.cancelButton.onClick.AddListener(OnCancelButtonClick);
|
||||
}
|
||||
|
||||
private void ResizeToFitContent()
|
||||
{
|
||||
if (!_autoResizeHeight)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
View.infoText.ForceMeshUpdate();
|
||||
var descriptionSize = View.infoText.rectTransform.sizeDelta;
|
||||
descriptionSize.y = View.infoText.preferredHeight;
|
||||
View.infoText.rectTransform.sizeDelta = descriptionSize;
|
||||
float descriptionHeight = Mathf.Max(0f, View.infoText.preferredHeight);
|
||||
float targetHeight = _fixedTopHeight + descriptionHeight + _fixedBottomHeight;
|
||||
|
||||
Vector2 size = new Vector2(_fixedWidth, targetHeight);
|
||||
View.contentRectTransform.sizeDelta = size;
|
||||
}
|
||||
|
||||
private void ApplyClampedTargetPos()
|
||||
{
|
||||
RectTransform parent = View.contentRectTransform.parent as RectTransform;
|
||||
if (parent == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
Vector2 size = View.contentRectTransform.sizeDelta;
|
||||
if (size.x <= 0f || size.y <= 0f)
|
||||
{
|
||||
size = View.contentRectTransform.rect.size;
|
||||
}
|
||||
|
||||
Vector2 pivot = View.contentRectTransform.pivot;
|
||||
float halfWidth = parent.rect.width * 0.5f;
|
||||
float halfHeight = parent.rect.height * 0.5f;
|
||||
|
||||
float minX = -halfWidth + size.x * pivot.x + _screenEdgePadding;
|
||||
float maxX = halfWidth - size.x * (1f - pivot.x) - _screenEdgePadding;
|
||||
float minY = -halfHeight + size.y * pivot.y + _screenEdgePadding;
|
||||
float maxY = halfHeight - size.y * (1f - pivot.y) - _screenEdgePadding;
|
||||
|
||||
float clampedX = minX <= maxX ? Mathf.Clamp(_targetPos.x, minX, maxX) : 0f;
|
||||
float clampedY = minY <= maxY ? Mathf.Clamp(_targetPos.y, minY, maxY) : 0f;
|
||||
|
||||
View.contentRectTransform.anchoredPosition3D = new Vector3(clampedX, clampedY, _targetPos.z);
|
||||
}
|
||||
|
||||
private Vector3 ConvertWorldToAnchored(Vector3 worldPos)
|
||||
{
|
||||
RectTransform parent = View.contentRectTransform.parent as RectTransform;
|
||||
if (parent == null)
|
||||
{
|
||||
return worldPos;
|
||||
}
|
||||
|
||||
Canvas canvas = View.contentRectTransform.GetComponentInParent<Canvas>();
|
||||
Canvas rootCanvas = canvas != null ? canvas.rootCanvas : null;
|
||||
Camera uiCamera = null;
|
||||
if (rootCanvas != null && rootCanvas.renderMode != RenderMode.ScreenSpaceOverlay)
|
||||
{
|
||||
uiCamera = rootCanvas.worldCamera != null ? rootCanvas.worldCamera : Camera.main;
|
||||
}
|
||||
|
||||
Vector2 screenPoint = RectTransformUtility.WorldToScreenPoint(uiCamera, worldPos);
|
||||
if (!RectTransformUtility.ScreenPointToLocalPointInRectangle(parent, screenPoint, uiCamera,
|
||||
out Vector2 localPoint))
|
||||
{
|
||||
return worldPos;
|
||||
}
|
||||
|
||||
float z = View.contentRectTransform.anchoredPosition3D.z;
|
||||
return new Vector3(localPoint.x, localPoint.y, z);
|
||||
}
|
||||
|
||||
private string BuildTypeText(ItemType type)
|
||||
{
|
||||
return type switch
|
||||
{
|
||||
ItemType.None => "error",
|
||||
ItemType.Weapon => "武器",
|
||||
ItemType.Prop => "道具",
|
||||
_ => throw new ArgumentOutOfRangeException(nameof(type), type, null)
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user