using System.Collections.Generic; using System.IO; using UnityEditor; using UnityEngine; using Codice.LogWrapper; using Unity.PlasticSCM.Editor.AssetUtils; namespace Unity.PlasticSCM.Editor.UI { internal class Images { internal enum Name { None, IconPlastic, IconCloseButton, IconPressedCloseButton, IconAddedLocal, IconAddedOverlay, IconPrivateOverlay, IconCheckedOutLocalOverlay, IconDeleted, IconDeletedLocalOverlay, IconDeletedRemote, IconDeletedRemoteOverlay, IconOutOfSync, IconOutOfSyncOverlay, IconMoved, IconMergeLink, Ignored, IgnoredOverlay, IconConflicted, IconConflictedOverlay, IconConflictResolvedOverlay, IconLockedLocalOverlay, IconLockedRemoteOverlay, XLink, Ok, SecondaryTabClose, SecondaryTabCloseHover, NotOnDisk, IconRepository, IconPlasticView, IconPlasticNotifyIncoming, IconPlasticNotifyConflict, Loading, IconEmptyGravatar, Step1, Step2, Step3, StepOk, ButtonSsoSignInUnity, ButtonSsoSignInEmail, ButtonSsoSignInGoogle, IconBranch, IconUndo, Refresh } internal static Texture2D GetImage(Name image) { return LoadImage(image, false); } internal static Texture GetFileIcon(string path) { string relativePath = GetRelativePath.ToApplication(path); return GetFileIconFromRelativePath(relativePath); } internal static Texture GetFileIconFromCmPath(string path) { return GetFileIconFromRelativePath( path.Substring(1).Replace("/", Path.DirectorySeparatorChar.ToString())); } internal static Texture GetDropDownIcon() { return GetIconFromEditorGUI("icon dropdown"); } internal static Texture GetDirectoryIcon() { return GetIconFromEditorGUI("Folder Icon"); } internal static Texture GetPrivatedOverlayIcon() { if (mPrivatedOverlayIcon == null) mPrivatedOverlayIcon = GetOverlay(Name.IconPrivateOverlay); return mPrivatedOverlayIcon; } internal static Texture GetAddedOverlayIcon() { if (mAddedOverlayIcon == null) mAddedOverlayIcon = GetOverlay(Name.IconAddedOverlay); return mAddedOverlayIcon; } internal static Texture GetDeletedLocalOverlayIcon() { if (mDeletedLocalOverlayIcon == null) mDeletedLocalOverlayIcon = GetOverlay(Name.IconDeletedLocalOverlay); return mDeletedLocalOverlayIcon; } internal static Texture GetDeletedRemoteOverlayIcon() { if (mDeletedRemoteOverlayIcon == null) mDeletedRemoteOverlayIcon = GetOverlay(Name.IconDeletedRemoteOverlay); return mDeletedRemoteOverlayIcon; } internal static Texture GetCheckedOutOverlayIcon() { if (mCheckedOutOverlayIcon == null) mCheckedOutOverlayIcon = GetOverlay(Name.IconCheckedOutLocalOverlay); return mCheckedOutOverlayIcon; } internal static Texture GetOutOfSyncOverlayIcon() { if (mOutOfSyncOverlayIcon == null) mOutOfSyncOverlayIcon = GetOverlay(Name.IconOutOfSyncOverlay); return mOutOfSyncOverlayIcon; } internal static Texture GetConflictedOverlayIcon() { if (mConflictedOverlayIcon == null) mConflictedOverlayIcon = GetOverlay(Name.IconConflictedOverlay); return mConflictedOverlayIcon; } internal static Texture GetConflictResolvedOverlayIcon() { if (mConflictResolvedOverlayIcon == null) mConflictResolvedOverlayIcon = GetOverlay(Name.IconConflictResolvedOverlay); return mConflictResolvedOverlayIcon; } internal static Texture GetLockedLocalOverlayIcon() { if (mLockedLocalOverlayIcon == null) mLockedLocalOverlayIcon = GetOverlay(Name.IconLockedLocalOverlay); return mLockedLocalOverlayIcon; } internal static Texture GetLockedRemoteOverlayIcon() { if (mLockedRemoteOverlayIcon == null) mLockedRemoteOverlayIcon = GetOverlay(Name.IconLockedRemoteOverlay); return mLockedRemoteOverlayIcon; } internal static Texture GetIgnoredOverlayIcon() { if (mIgnoredverlayIcon == null) mIgnoredverlayIcon = GetOverlay(Name.IgnoredOverlay); return mIgnoredverlayIcon; } internal static Texture GetWarnIcon() { return GetIconFromEditorGUI("console.warnicon.sml"); } internal static Texture GetInfoIcon() { return GetIconFromEditorGUI("console.infoicon.sml"); } internal static Texture GetErrorDialogIcon() { return GetIconFromEditorGUI("console.erroricon"); } internal static Texture GetWarnDialogIcon() { return GetIconFromEditorGUI("console.warnicon"); } internal static Texture GetInfoDialogIcon() { return GetIconFromEditorGUI("console.infoicon"); } internal static Texture GetRefreshIcon() { if (mRefreshIcon == null) mRefreshIcon = GetImage(Name.Refresh); return mRefreshIcon; } internal static Texture GetSettingsIcon() { return GetIconFromEditorGUI("settings"); } internal static Texture GetCloseIcon() { if (mCloseIcon == null) mCloseIcon = GetImage(Name.SecondaryTabClose); return mCloseIcon; } internal static Texture GetClickedCloseIcon() { if (mClickedCloseIcon == null) mClickedCloseIcon = GetImage(Name.SecondaryTabCloseHover); return mClickedCloseIcon; } internal static Texture GetHoveredCloseIcon() { if (mHoveredCloseIcon == null) mHoveredCloseIcon = GetImage(Name.SecondaryTabCloseHover); return mHoveredCloseIcon; } internal static Texture2D GetUndoIcon() { if (mUndoIcon == null) mUndoIcon = GetImage(Name.IconUndo); return mUndoIcon; } internal static Texture2D GetPlasticIcon() { if (mPlasticIcon == null) mPlasticIcon = GetImage(Name.IconPlastic); return mPlasticIcon; } internal static Texture2D GetBranchIcon() { if (mBranchIcon == null) mBranchIcon = GetImage(Name.IconBranch); return mBranchIcon; } internal static Texture2D GetConflictedIcon() { if (mConflictedIcon == null) mConflictedIcon = GetImage(Name.IconConflicted); return mConflictedIcon; } internal static Texture2D GetOutOfSyncIcon() { if (mOutOfSyncIcon == null) mOutOfSyncIcon = GetImage(Name.IconOutOfSync); return mOutOfSyncIcon; } internal static Texture2D GetPlasticViewIcon() { if (mPlasticViewIcon == null) mPlasticViewIcon = GetImage(Name.IconPlasticView); return mPlasticViewIcon; } internal static Texture2D GePlasticNotifyIncomingIcon() { if (mPlasticNotifyIncomingIcon == null) mPlasticNotifyIncomingIcon = GetImage(Name.IconPlasticNotifyIncoming); return mPlasticNotifyIncomingIcon; } internal static Texture2D GetPlasticNotifyConflictIcon() { if (mPlasticNotifyConflictIcon == null) mPlasticNotifyConflictIcon = GetImage(Name.IconPlasticNotifyConflict); return mPlasticNotifyConflictIcon; } internal static Texture2D GetEmptyGravatar() { if (mEmptyGravatarIcon == null) mEmptyGravatarIcon = Images.GetImage(Images.Name.IconEmptyGravatar); return mEmptyGravatarIcon; } internal static Texture2D GetStepOkIcon() { if (mStepOkIcon == null) mStepOkIcon = Images.GetImage(Images.Name.StepOk); return mStepOkIcon; } internal static Texture2D GetStep1Icon() { if (mStep1Icon == null) mStep1Icon = Images.GetImage(Images.Name.Step1); return mStep1Icon; } internal static Texture2D GetStep2Icon() { if (mStep2Icon == null) mStep2Icon = Images.GetImage(Images.Name.Step2); return mStep2Icon; } internal static Texture2D GetMergeLinkIcon() { if (mMergeLinkIcon == null) mMergeLinkIcon = Images.GetImage(Images.Name.IconMergeLink); return mMergeLinkIcon; } internal static Texture2D GetAddedLocalIcon() { if (mAddedLocalIcon == null) mAddedLocalIcon = Images.GetImage(Images.Name.IconAddedLocal); return mAddedLocalIcon; } internal static Texture2D GetDeletedRemoteIcon() { if (mDeletedRemoteIcon == null) mDeletedRemoteIcon = Images.GetImage(Images.Name.IconDeletedRemote); return mDeletedRemoteIcon; } internal static Texture2D GetDeletedIcon() { if (mDeletedIcon == null) mDeletedIcon = Images.GetImage(Images.Name.IconDeleted); return mDeletedIcon; } internal static Texture2D GetMovedIcon() { if (mMovedIcon == null) mMovedIcon = Images.GetImage(Images.Name.IconMoved); return mMovedIcon; } internal static Texture2D GetRepositoryIcon() { if (mRepositoryIcon == null) mRepositoryIcon = Images.GetImage(Images.Name.IconRepository); return mRepositoryIcon; } internal static Texture GetFileIcon() { if (mFileIcon == null) mFileIcon = EditorGUIUtility.FindTexture("DefaultAsset Icon"); if (mFileIcon == null) mFileIcon = GetIconFromAssetPreview(typeof(DefaultAsset)); if (mFileIcon == null) mFileIcon = GetEmptyImage(); return mFileIcon; } internal static Texture2D GetLinkUnderlineImage() { if (mLinkUnderlineImage == null) { mLinkUnderlineImage = new Texture2D(1, 1); mLinkUnderlineImage.SetPixel(0, 0, UnityStyles.Colors.Link); mLinkUnderlineImage.Apply(); } return mLinkUnderlineImage; } internal static Texture2D GetTreeviewBackgroundTexture() { if (mTreeviewBackgroundTexture == null) mTreeviewBackgroundTexture = GetTextureFromColor(UnityStyles.Colors.TreeViewBackground); return mTreeviewBackgroundTexture; } internal static Texture2D GetCommentBackgroundTexture() { if (mCommentBackground == null) mCommentBackground = GetTextureFromColor(UnityStyles.Colors.CommentsBackground); return mCommentBackground; } internal static Texture2D GetColumnsBackgroundTexture() { if (mColumnsBackgroundTexture == null) mColumnsBackgroundTexture = GetTextureFromColor(UnityStyles.Colors.ColumnsBackground); return mColumnsBackgroundTexture; } internal static Texture2D GetNewTextureFromTexture(Texture2D texture) { Texture2D result = new Texture2D(texture.width, texture.height, TextureFormat.BGRA32, false); // To keep images consistent throughout the plugin, // manually set the filter mode result.filterMode = FilterMode.Bilinear; return result; } internal static Texture2D GetNewTextureFromBytes(int width, int height, byte[] bytes) { Texture2D result = new Texture2D(width, height, TextureFormat.RGBA32, false); result.LoadImage(bytes); // To keep images consistent throughout the plugin, // manually set the filter mode result.filterMode = FilterMode.Bilinear; return result; } static Texture2D GetNewTextureFromFile(string path) { return GetNewTextureFromBytes(1, 1, File.ReadAllBytes(path)); } static Texture2D GetOverlay(Name image) { return LoadImage(image, true); } static Texture2D LoadImage(Name image, bool preferFulResImage) { string imageFileName = image.ToString().ToLower() + ".png"; string imageFileName2x = image.ToString().ToLower() + "@2x.png"; string darkImageFileName = string.Format("d_{0}", imageFileName); string darkImageFileName2x = string.Format("d_{0}", imageFileName2x); string imageFileRelativePath = GetImageFileRelativePath(imageFileName); string imageFileRelativePath2x = GetImageFileRelativePath(imageFileName2x); string darkImageFileRelativePath = GetImageFileRelativePath(darkImageFileName); string darkImageFileRelativePath2x = GetImageFileRelativePath(darkImageFileName2x); Texture2D result = null; if (EditorGUIUtility.isProSkin) result = TryLoadImage(darkImageFileRelativePath, darkImageFileRelativePath2x, preferFulResImage); if (result != null) return result; result = TryLoadImage(imageFileRelativePath, imageFileRelativePath2x, preferFulResImage); if (result != null) return result; mLog.WarnFormat("Image not found: {0}", imageFileName); return GetEmptyImage(); } static Texture2D GetEmptyImage() { if (mEmptyImage == null) mEmptyImage = GetTextureFromColor(Color.clear); return mEmptyImage; } static Texture2D GetTextureFromColor(Color color) { Texture2D texture = new Texture2D(1, 1); texture.SetPixel(0, 0, color); texture.Apply(); return texture; } static Texture GetFileIconFromRelativePath(string relativePath) { Texture result = AssetDatabase.GetCachedIcon(relativePath); if (result != null) return result; result = GetFileIconFromKnownExtension(relativePath); if (result != null) return result; return GetFileIcon(); } static Texture GetFileIconFromKnownExtension(string relativePath) { if (relativePath.EndsWith(UnityConstants.TREEVIEW_META_LABEL)) { relativePath = relativePath.Substring(0, relativePath.Length- UnityConstants.TREEVIEW_META_LABEL.Length); } string extension = Path.GetExtension(relativePath).ToLower(); if (extension.Equals(".cs")) return GetIconFromEditorGUI("cs Script Icon"); if (extension.Equals(".png") || extension.Equals(".jpg") || extension.Equals(".jpeg") || extension.Equals(".gif") || extension.Equals(".tga") || extension.Equals(".bmp") || extension.Equals(".tif") || extension.Equals(".tiff")) return GetIconFromEditorGUI("d_Texture Icon"); if (extension.Equals(".mat")) return GetIconFromAssetPreview(typeof(UnityEngine.Material)); if (extension.Equals(".fbx") || extension.Equals(".ma") || extension.Equals(".mb") || extension.Equals(".blend") || extension.Equals(".max") ) return GetIconFromAssetPreview(typeof(UnityEngine.GameObject)); if (extension.Equals(".wav") || extension.Equals(".mp3")) return GetIconFromAssetPreview(typeof(UnityEngine.AudioClip)); if (extension.Equals(".anim")) return GetIconFromAssetPreview(typeof(UnityEngine.Animation)); if (extension.Equals(".animator")) return GetIconFromAssetPreview(typeof(UnityEngine.Animator)); if (extension.Equals(".shader")) return GetIconFromEditorGUI("d_Shader Icon"); if (extension.Equals(".asset") && relativePath.StartsWith("ProjectSettings\\")) return GetIconFromEditorGUI("EditorSettings Icon"); return null; } static Texture2D GetIconFromEditorGUI(string name) { Texture2D result; if (mImagesFromEditorGUICache.TryGetValue(name, out result)) { if (result != null) return result; mImagesFromEditorGUICache.Remove(name); } result = EditorGUIUtility.IconContent(name).image as Texture2D; mImagesFromEditorGUICache.Add(name, result); return result; } static Texture2D GetIconFromAssetPreview(System.Type type) { Texture2D result; if (mImagesFromAssetPreviewCache.TryGetValue(type.ToString(), out result)) { if (result != null) return result; mImagesFromAssetPreviewCache.Remove(type.ToString()); } result = AssetPreview.GetMiniTypeThumbnail(type); mImagesFromAssetPreviewCache.Add(type.ToString(), result); return result; } static string GetImageFileRelativePath(string imageFileName) { return Path.Combine( AssetsPath.GetImagesFolderRelativePath(), imageFileName); } static Texture2D TryLoadImage( string imageFileRelativePath, string image2xFilePath, bool preferFulResImage) { bool isImageAvailable = File.Exists(Path.GetFullPath(imageFileRelativePath)); bool isImage2XAvailable = File.Exists(Path.GetFullPath(image2xFilePath)); if ((EditorGUIUtility.pixelsPerPoint > 1f || !isImageAvailable || preferFulResImage) && isImage2XAvailable) return LoadTextureFromFile(image2xFilePath); if (isImageAvailable) return LoadTextureFromFile(imageFileRelativePath); return null; } static Texture2D LoadTextureFromFile(string path) { Texture2D result; if (mImagesByPathCache.TryGetValue(path, out result)) { if (result != null) return result; mImagesByPathCache.Remove(path); } // Don't use AssetDatabase to load as it will // pick filtering mode from the asset itself // which leads to inconsistent filtering between // images. result = GetNewTextureFromFile(path); mImagesByPathCache.Add(path, result); return result; } static Dictionary mImagesByPathCache = new Dictionary(); static Dictionary mImagesFromEditorGUICache = new Dictionary(); static Dictionary mImagesFromAssetPreviewCache = new Dictionary(); static Texture mFileIcon; static Texture mPrivatedOverlayIcon; static Texture mAddedOverlayIcon; static Texture mDeletedLocalOverlayIcon; static Texture mDeletedRemoteOverlayIcon; static Texture mCheckedOutOverlayIcon; static Texture mOutOfSyncOverlayIcon; static Texture mConflictedOverlayIcon; static Texture mConflictResolvedOverlayIcon; static Texture mLockedLocalOverlayIcon; static Texture mLockedRemoteOverlayIcon; static Texture mIgnoredverlayIcon; static Texture mRefreshIcon; static Texture mCloseIcon; static Texture mClickedCloseIcon; static Texture mHoveredCloseIcon; static Texture2D mLinkUnderlineImage; static Texture2D mEmptyImage; static Texture2D mTreeviewBackgroundTexture; static Texture2D mColumnsBackgroundTexture; static Texture2D mCommentBackground; static Texture2D mUndoIcon; static Texture2D mPlasticIcon; static Texture2D mBranchIcon; static Texture2D mConflictedIcon; static Texture2D mOutOfSyncIcon; static Texture2D mPlasticViewIcon; static Texture2D mPlasticNotifyIncomingIcon; static Texture2D mPlasticNotifyConflictIcon; static Texture2D mEmptyGravatarIcon; static Texture2D mStepOkIcon; static Texture2D mStep1Icon; static Texture2D mStep2Icon; static Texture2D mMergeLinkIcon; static Texture2D mAddedLocalIcon; static Texture2D mDeletedRemoteIcon; static Texture2D mDeletedIcon; static Texture2D mMovedIcon; static Texture2D mRepositoryIcon; static readonly ILog mLog = LogManager.GetLogger("Images"); } }