Add seeing mr Cement photos in the album
This commit is contained in:
257
Assets/Scripts/CardSystem/UI/Component/AlbumPhotoSlot.cs
Normal file
257
Assets/Scripts/CardSystem/UI/Component/AlbumPhotoSlot.cs
Normal file
@@ -0,0 +1,257 @@
|
||||
using System.Collections;
|
||||
using CardSystem.Controllers;
|
||||
using Core;
|
||||
using UnityEngine;
|
||||
using UnityEngine.EventSystems;
|
||||
using UnityEngine.UI;
|
||||
using Utils;
|
||||
|
||||
namespace CardSystem.UI.Component
|
||||
{
|
||||
/// <summary>
|
||||
/// Photo display slot for the album book pages.
|
||||
/// Pre-placed prefab that displays photos from a specific minigame category.
|
||||
/// Supports click-to-enlarge functionality.
|
||||
/// </summary>
|
||||
public class AlbumPhotoSlot : MonoBehaviour, IPointerClickHandler
|
||||
{
|
||||
[Header("Configuration")]
|
||||
[Tooltip("Which minigame category this slot displays photos from")]
|
||||
[SerializeField] private CaptureType captureType = CaptureType.StatueMinigame;
|
||||
|
||||
[Header("References")]
|
||||
[SerializeField] private Image photoImage;
|
||||
[SerializeField] private GameObject loadingIndicator;
|
||||
[SerializeField] private GameObject emptyPlaceholder;
|
||||
|
||||
[Header("Visual Settings")]
|
||||
[SerializeField] private int thumbnailSize = 256;
|
||||
|
||||
private string _photoId;
|
||||
private Texture2D _currentTexture;
|
||||
private Texture2D _fullSizeTexture;
|
||||
private AlbumPhotoPageController _controller;
|
||||
private bool _isPopulated;
|
||||
|
||||
public CaptureType CaptureType => captureType;
|
||||
public bool IsPopulated => _isPopulated;
|
||||
public string PhotoId => _photoId;
|
||||
|
||||
/// <summary>
|
||||
/// Initialize the slot with controller reference
|
||||
/// </summary>
|
||||
public void Initialize(AlbumPhotoPageController controller)
|
||||
{
|
||||
_controller = controller;
|
||||
Logging.Debug($"[AlbumPhotoSlot] {gameObject.name} initialized with controller");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// When slot becomes active, request and load assigned photo from controller
|
||||
/// </summary>
|
||||
private void OnEnable()
|
||||
{
|
||||
// Only auto-load if we have a controller and haven't already populated
|
||||
if (_controller != null && !_isPopulated && string.IsNullOrEmpty(_photoId))
|
||||
{
|
||||
Logging.Debug($"[AlbumPhotoSlot] {gameObject.name} became active, requesting assigned photo");
|
||||
|
||||
// Request our assigned photo ID from controller
|
||||
string assignedPhotoId = _controller.GetAssignedPhotoId(this);
|
||||
|
||||
if (!string.IsNullOrEmpty(assignedPhotoId))
|
||||
{
|
||||
Logging.Debug($"[AlbumPhotoSlot] {gameObject.name} assigned photoId: {assignedPhotoId}");
|
||||
PopulateWithPhoto(assignedPhotoId);
|
||||
}
|
||||
else
|
||||
{
|
||||
Logging.Debug($"[AlbumPhotoSlot] {gameObject.name} has no assigned photo, showing empty state");
|
||||
ShowEmptyState();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Populate this slot with a photo from the minigame
|
||||
/// </summary>
|
||||
/// <param name="photoId">Photo ID to load</param>
|
||||
public void PopulateWithPhoto(string photoId)
|
||||
{
|
||||
Logging.Debug($"[AlbumPhotoSlot] PopulateWithPhoto called: photoId='{photoId}', captureType={captureType}");
|
||||
|
||||
if (string.IsNullOrEmpty(photoId))
|
||||
{
|
||||
Logging.Debug($"[AlbumPhotoSlot] Photo ID is null or empty, showing empty state");
|
||||
ShowEmptyState();
|
||||
return;
|
||||
}
|
||||
|
||||
_photoId = photoId;
|
||||
StartCoroutine(LoadPhotoAsync(photoId));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Load photo asynchronously to avoid frame hitches
|
||||
/// </summary>
|
||||
private IEnumerator LoadPhotoAsync(string photoId)
|
||||
{
|
||||
ShowLoadingState();
|
||||
|
||||
Logging.Debug($"[AlbumPhotoSlot] LoadPhotoAsync started for photoId: {photoId}, captureType: {captureType}");
|
||||
|
||||
// Yield to avoid loading all photos in one frame
|
||||
yield return null;
|
||||
|
||||
// Load full photo
|
||||
Logging.Debug($"[AlbumPhotoSlot] Calling PhotoManager.LoadPhoto({captureType}, {photoId})");
|
||||
Texture2D fullPhoto = PhotoManager.LoadPhoto(captureType, photoId);
|
||||
|
||||
if (fullPhoto == null)
|
||||
{
|
||||
Logging.Warning($"[AlbumPhotoSlot] Failed to load photo: {photoId} for {captureType}");
|
||||
ShowEmptyState();
|
||||
yield break;
|
||||
}
|
||||
|
||||
Logging.Debug($"[AlbumPhotoSlot] Photo loaded successfully! Size: {fullPhoto.width}x{fullPhoto.height}");
|
||||
|
||||
// Create thumbnail for display
|
||||
Texture2D thumbnail = PhotoManager.CreateThumbnail(fullPhoto, thumbnailSize);
|
||||
Logging.Debug($"[AlbumPhotoSlot] Thumbnail created: {thumbnail.width}x{thumbnail.height}");
|
||||
|
||||
// Store full size for enlargement
|
||||
_fullSizeTexture = fullPhoto;
|
||||
_currentTexture = thumbnail;
|
||||
|
||||
// Display thumbnail
|
||||
DisplayPhoto(thumbnail);
|
||||
|
||||
_isPopulated = true;
|
||||
Logging.Debug($"[AlbumPhotoSlot] Photo display complete for {photoId}");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Display photo texture on the image component
|
||||
/// </summary>
|
||||
private void DisplayPhoto(Texture2D texture)
|
||||
{
|
||||
if (texture == null || photoImage == null) return;
|
||||
|
||||
// Create sprite from texture
|
||||
Sprite photoSprite = Sprite.Create(
|
||||
texture,
|
||||
new Rect(0, 0, texture.width, texture.height),
|
||||
new Vector2(0.5f, 0.5f)
|
||||
);
|
||||
|
||||
photoImage.sprite = photoSprite;
|
||||
photoImage.enabled = true;
|
||||
|
||||
HideLoadingState();
|
||||
HideEmptyState();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Handle click to enlarge photo
|
||||
/// </summary>
|
||||
public void OnPointerClick(PointerEventData eventData)
|
||||
{
|
||||
if (!_isPopulated || string.IsNullOrEmpty(_photoId) || _controller == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
Logging.Debug($"[AlbumPhotoSlot] Clicked photo: {_photoId} from {captureType}");
|
||||
|
||||
// Request enlargement from controller
|
||||
_controller.EnlargePhoto(this, _fullSizeTexture);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Clear the slot
|
||||
/// </summary>
|
||||
public void Clear()
|
||||
{
|
||||
_photoId = null;
|
||||
_isPopulated = false;
|
||||
|
||||
if (_currentTexture != null)
|
||||
{
|
||||
Destroy(_currentTexture);
|
||||
_currentTexture = null;
|
||||
}
|
||||
|
||||
if (_fullSizeTexture != null)
|
||||
{
|
||||
Destroy(_fullSizeTexture);
|
||||
_fullSizeTexture = null;
|
||||
}
|
||||
|
||||
if (photoImage != null)
|
||||
{
|
||||
photoImage.sprite = null;
|
||||
photoImage.enabled = false;
|
||||
}
|
||||
|
||||
ShowEmptyState();
|
||||
}
|
||||
|
||||
#region Visual States
|
||||
|
||||
private void ShowLoadingState()
|
||||
{
|
||||
if (loadingIndicator != null)
|
||||
loadingIndicator.SetActive(true);
|
||||
|
||||
if (photoImage != null)
|
||||
photoImage.enabled = false;
|
||||
|
||||
if (emptyPlaceholder != null)
|
||||
emptyPlaceholder.SetActive(false);
|
||||
}
|
||||
|
||||
private void HideLoadingState()
|
||||
{
|
||||
if (loadingIndicator != null)
|
||||
loadingIndicator.SetActive(false);
|
||||
}
|
||||
|
||||
private void ShowEmptyState()
|
||||
{
|
||||
if (emptyPlaceholder != null)
|
||||
emptyPlaceholder.SetActive(true);
|
||||
|
||||
if (loadingIndicator != null)
|
||||
loadingIndicator.SetActive(false);
|
||||
|
||||
if (photoImage != null)
|
||||
photoImage.enabled = false;
|
||||
|
||||
_isPopulated = false;
|
||||
}
|
||||
|
||||
private void HideEmptyState()
|
||||
{
|
||||
if (emptyPlaceholder != null)
|
||||
emptyPlaceholder.SetActive(false);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
private void OnDestroy()
|
||||
{
|
||||
// Cleanup textures
|
||||
if (_currentTexture != null)
|
||||
{
|
||||
Destroy(_currentTexture);
|
||||
}
|
||||
|
||||
if (_fullSizeTexture != null)
|
||||
{
|
||||
Destroy(_fullSizeTexture);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user