Add seeing mr Cement photos in the album

This commit is contained in:
Michal Pikulski
2025-12-15 15:24:17 +01:00
parent de02394198
commit f72b8f3cf5
20 changed files with 2194 additions and 230 deletions

View 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);
}
}
}
}

View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: eb3200565b9f4a14b27f74ff9ec083c6
timeCreated: 1765801126

View File

@@ -20,6 +20,7 @@ namespace UI.CardSystem
[Header("Tab Configuration")]
[SerializeField] private int targetPage;
[Tooltip("Optional: Set this for card collection zone tabs. Leave unassigned for other tabs (e.g., photo pages).")]
[SerializeField] private CardZone zone;
[Header("Visual Settings")]

View File

@@ -1,5 +1,6 @@
using System.Collections.Generic;
using AppleHills.Data.CardSystem;
using CardSystem.Controllers;
using Core;
using Data.CardSystem;
using Pixelplacement;
@@ -8,6 +9,7 @@ using UI.DragAndDrop.Core;
using UnityEngine;
using UnityEngine.UI;
using UnityEngine.Serialization;
using Utils;
namespace UI.CardSystem
{
@@ -35,6 +37,11 @@ namespace UI.CardSystem
[SerializeField] private GameObject cardEnlargedBackdrop; // Backdrop to block interactions
[SerializeField] private Transform cardEnlargedContainer; // Container for enlarged cards (sits above backdrop)
[Header("Photo Gallery System")]
[SerializeField] private GameObject photoEnlargedBackdrop; // Backdrop for photo enlargement
[SerializeField] private Transform photoEnlargedContainer; // Container for enlarged photos
[SerializeField] private float photoAnimationDuration = 0.3f;
[Header("Booster Pack UI")]
[SerializeField] private GameObject[] boosterPackButtons;
[SerializeField] private BoosterOpeningPage boosterOpeningPage;
@@ -61,6 +68,13 @@ namespace UI.CardSystem
cardEnlargedContainer
);
private AlbumPhotoPageController _photoController;
private AlbumPhotoPageController PhotoController => _photoController ??= new AlbumPhotoPageController(
photoEnlargedBackdrop,
photoEnlargedContainer,
photoAnimationDuration
);
/// <summary>
/// Query method: Check if the book is currently flipping to a page.
/// Used by card states to know if they should wait before placing.
@@ -84,6 +98,12 @@ namespace UI.CardSystem
cardEnlargedBackdrop.SetActive(false);
}
// Hide photo backdrop initially
if (photoEnlargedBackdrop != null)
{
photoEnlargedBackdrop.SetActive(false);
}
// Set up exit button
if (exitButton != null)
{
@@ -283,6 +303,13 @@ namespace UI.CardSystem
Logging.Debug("[AlbumViewPage] Switched to UI-only input mode on first entry");
}
// Initialize photo controller if not already done
if (!PhotoController.IsInitialized)
{
PhotoController.Initialize();
Logging.Debug("[AlbumViewPage] Photo controller initialized");
}
// Only spawn pending cards if we're already on an album page (not the menu)
if (IsInAlbumProper())
{
@@ -305,6 +332,12 @@ namespace UI.CardSystem
// Clean up active pending cards to prevent duplicates on next opening
CleanupPendingCornerCards();
// Clean up photo controller
if (_photoController != null)
{
_photoController.Cleanup();
}
// Don't restore input mode here - only restore when actually exiting (in OnExitButtonClicked)
base.TransitionOut();
}
@@ -329,6 +362,12 @@ namespace UI.CardSystem
// Clean up any enlarged card state before closing
CleanupEnlargedCardState();
// Clean up photo controller
if (_photoController != null)
{
_photoController.Cleanup();
}
// Simple fade out animation
if (canvasGroup != null)
{
@@ -401,6 +440,34 @@ namespace UI.CardSystem
Enlarge.UnregisterCard(card);
}
#endregion
#region Photo Gallery System
/// <summary>
/// Refresh photos for a specific capture type after a new photo is taken
/// </summary>
public void RefreshPhotosForType(CaptureType captureType)
{
if (_photoController != null && _photoController.IsInitialized)
{
_photoController.RefreshPhotosForType(captureType);
Logging.Debug($"[AlbumViewPage] Refreshed photos for {captureType}");
}
}
/// <summary>
/// Get photo count for a specific capture type
/// </summary>
public int GetPhotoCount(CaptureType captureType)
{
if (_photoController != null && _photoController.IsInitialized)
{
return _photoController.GetPhotoCount(captureType);
}
return 0;
}
#endregion
/// <summary>