using System; using UnityEngine; using System.Collections.Generic; using UnityEditor.U2D.Common; namespace UnityEditor.U2D.Animation { internal class SpriteSelectorWidget { class Styles { public GUIStyle gridListStyle; public Styles() { gridListStyle = new GUIStyle("GridList") { alignment = GUI.skin.button.alignment, padding = new RectOffset(k_GridCellPadding, k_GridCellPadding, k_GridCellPadding, k_GridCellPadding), fixedHeight = k_TargetPreviewSize, fixedWidth = k_TargetPreviewSize }; } } static Texture2D spriteLoadingThumbnail { get { if (s_LoadingSpriteTexture == null) s_LoadingSpriteTexture = AssetPreview.GetMiniTypeThumbnail(typeof(Sprite)); return s_LoadingSpriteTexture; } } static Texture2D s_LoadingSpriteTexture; const int k_TargetPreviewSize = 64; const int k_GridCellPadding = 2; const int k_ScrollbarWidthOffset = 10; List m_SpritePreviewNeedFetching = new(); Sprite[] m_SpriteList = Array.Empty(); Texture2D[] m_SpritePreviews = Array.Empty(); int m_ClientId = 0; int m_PreviewCacheSize = 0; Vector2 m_ScrollPos; Styles m_Style; public void Initialize(int clientId) { m_ClientId = clientId; } public void Dispose() { if (m_ClientId != 0) { InternalEditorBridge.ClearAssetPreviews(m_ClientId); m_ClientId = 0; } } public void UpdateContents(Sprite[] sprites) { m_SpritePreviewNeedFetching.Clear(); InternalEditorBridge.ClearAssetPreviews(m_ClientId); var spriteCount = sprites.Length; m_PreviewCacheSize = spriteCount + 1; InternalEditorBridge.SetAssetPreviewTextureCacheSize(m_PreviewCacheSize, m_ClientId); m_SpriteList = sprites; m_SpritePreviews = new Texture2D[spriteCount]; m_SpritePreviewNeedFetching.Capacity = spriteCount; for (var i = 0; i < spriteCount; ++i) m_SpritePreviewNeedFetching.Add(i); } public int ShowGUI(int selectedIndex) { if (m_Style == null) m_Style = new Styles(); var drawRect = EditorGUILayout.GetControlRect(false, k_TargetPreviewSize + 10f, new[] { GUILayout.ExpandWidth(true) }); if (Event.current.type == EventType.Repaint) GUI.skin.box.Draw(drawRect, false, false, false, false); if (m_SpriteList == null || m_SpriteList.Length == 0) { return selectedIndex; } selectedIndex = (selectedIndex > m_SpriteList.Length) ? 0 : selectedIndex; var widthMargin = (m_Style.gridListStyle.margin.left + m_Style.gridListStyle.margin.right) * 0.5f; var heightMargin = (m_Style.gridListStyle.margin.top + m_Style.gridListStyle.margin.bottom) * 0.5f; GetRowColumnCount(drawRect.width - k_ScrollbarWidthOffset, k_TargetPreviewSize + Mathf.RoundToInt(widthMargin), m_SpriteList.Length, out var columnCount, out var rowCount); if (columnCount > 0 && rowCount > 0) { var height = rowCount * (k_TargetPreviewSize + heightMargin); var width = columnCount * (k_TargetPreviewSize + widthMargin); var scrollViewRect = new Rect(drawRect.x - k_ScrollbarWidthOffset, drawRect.y, width, height); m_ScrollPos = GUI.BeginScrollView(drawRect, m_ScrollPos, scrollViewRect, false, false, GUIStyle.none, GUI.skin.verticalScrollbar); var gridRect = scrollViewRect; gridRect.x += (drawRect.width - width - k_ScrollbarWidthOffset) * 0.5f; selectedIndex = GUI.SelectionGrid(gridRect, selectedIndex, m_SpritePreviews, columnCount, m_Style.gridListStyle); GUI.EndScrollView(); } return selectedIndex; } static void GetRowColumnCount(float drawWidth, int size, int contentCount, out int columnCount, out int rowCount) { columnCount = (int)drawWidth / size; if (columnCount == 0) rowCount = 0; else rowCount = Math.Max(1, Mathf.CeilToInt((float)contentCount / columnCount)); } public bool UpdateSpritePreviews() { var remainingPreviewCount = m_SpritePreviewNeedFetching.Count; if (remainingPreviewCount == 0) return false; for (var i = remainingPreviewCount - 1; i >= 0; --i) { var index = m_SpritePreviewNeedFetching[i]; if (m_SpriteList[index] == null) { m_SpritePreviews[index] = EditorGUIUtility.Load("icons/console.warnicon.png") as Texture2D; m_SpritePreviewNeedFetching.RemoveAt(i); } else { var spriteId = m_SpriteList[index].GetInstanceID(); var spritePreview = InternalEditorBridge.GetAssetPreview(spriteId, m_ClientId); if (spritePreview != null) { m_SpritePreviews[index] = spritePreview; m_SpritePreviewNeedFetching.RemoveAt(i); } else { m_SpritePreviews[index] = spriteLoadingThumbnail; if (!InternalEditorBridge.IsLoadingAssetPreview(spriteId, m_ClientId)) m_SpritePreviewNeedFetching.RemoveAt(i); } } } return remainingPreviewCount != m_SpritePreviewNeedFetching.Count; } } }