Files
JuegoSim/Assets/_Project/Data/FolderIcons/Editor/FolderIconSettingsEditor.cs
T
2026-07-21 08:56:10 +03:00

445 lines
15 KiB
C#

using UnityEngine;
using UnityEditor;
using UnityEditorInternal;
using System.IO;
namespace FolderIcons
{
[CustomEditor (typeof (FolderIconSettings))]
internal class FolderIconSettingsEditor : Editor
{
// References
private FolderIconSettings settings;
private SerializedProperty serializedIcons;
// Settings
private bool showCustomFolders;
private bool showCustomOverlay;
private ReorderableList iconList;
// Texture
private Texture2D selectedTexture = null;
private Texture2D previewTexture = null;
private GUIContent previewContent = new GUIContent ();
private RenderTexture previewRender;
private Color replacementColour = Color.gray;
// Texture Save Settings
private string textureName = "New Texture";
private string savePath;
private int heightIndex;
// Sizing
private const float MAX_LABEL_WIDTH = 90f;
private const float MAX_FIELD_WIDTH = 150f;
private const float PROPERTY_HEIGHT = 19f;
private const float PROPERTY_PADDING = 4f;
private const float SETTINGS_PADDING = 1F;
// Styling
private GUIStyle elementStyle;
private GUIStyle propertyStyle;
private GUIStyle previewStyle;
private void OnEnable()
{
if (target == null)
return;
settings = target as FolderIconSettings;
serializedIcons = serializedObject.FindProperty ("icons");
showCustomFolders = settings.showCustomFolder;
showCustomOverlay = settings.showOverlay;
if (iconList == null)
{
iconList = new ReorderableList (serializedObject, serializedIcons)
{
drawHeaderCallback = OnHeaderDraw,
drawElementCallback = OnElementDraw,
drawElementBackgroundCallback = DrawElementBackground,
elementHeightCallback = GetPropertyHeight,
showDefaultBackground = false,
};
}
savePath = Application.dataPath;
if (selectedTexture != null)
UpdatePreview ();
}
private void OnDisable()
{
ClearPreviewData ();
}
public override void OnInspectorGUI()
{
//Create styles
if (previewStyle == null)
{
previewStyle = new GUIStyle (EditorStyles.label)
{
fixedHeight = 64,
//fixedWidth = 64,
//stretchWidth = false,
alignment = TextAnchor.MiddleCenter
};
elementStyle = new GUIStyle (GUI.skin.box)
{
};
}
// Draw Settings
EditorGUILayout.LabelField ("Settings", EditorStyles.boldLabel);
EditorGUI.BeginChangeCheck ();
{
showCustomFolders = EditorGUILayout.ToggleLeft ("Show Folder Textures", showCustomFolders);
showCustomOverlay = EditorGUILayout.ToggleLeft ("Show Overlay Textures", showCustomOverlay);
}
if (EditorGUI.EndChangeCheck ())
{
ApplySettings ();
}
EditorGUILayout.Space (16f);
EditorGUI.BeginChangeCheck ();
iconList.DoLayoutList ();
if (EditorGUI.EndChangeCheck ())
serializedObject.ApplyModifiedProperties ();
DrawTexturePreview ();
EditorGUI.BeginDisabledGroup (previewTexture == null);
{
EditorGUI.BeginChangeCheck ();
{
replacementColour = EditorGUILayout.ColorField (new GUIContent ("Replacement Colour"), replacementColour);
}
if (EditorGUI.EndChangeCheck ())
SetPreviewColour ();
DrawTextureSaving ();
}
EditorGUI.EndDisabledGroup ();
}
private void ApplySettings()
{
FolderIconsReplacer.showFolder = settings.showCustomFolder = showCustomFolders;
FolderIconsReplacer.showOverlay = settings.showOverlay = showCustomOverlay;
}
#region Reorderable Array Draw
private void OnHeaderDraw(Rect rect)
{
rect.y += 5f;
rect.x -= 6f;
rect.width += 12f;
Handles.BeginGUI ();
Handles.DrawSolidRectangleWithOutline (rect,
new Color (0.15f, 0.15f, 0.15f, 1f),
new Color (0.15f, 0.15f, 0.15f, 1f));
Handles.EndGUI ();
EditorGUI.LabelField (rect, "Folders", EditorStyles.boldLabel);
}
private void OnElementDraw( Rect rect, int index, bool isActive, bool isFocused)
{
SerializedProperty property = serializedIcons.GetArrayElementAtIndex (index);
float fullWidth = rect.width;
// Set sizes for correct draw
float originalLabelWidth = EditorGUIUtility.labelWidth;
float rectWidth = MAX_LABEL_WIDTH + MAX_FIELD_WIDTH;
EditorGUIUtility.labelWidth = Mathf.Min(EditorGUIUtility.labelWidth, MAX_LABEL_WIDTH);
rect.width = Mathf.Min(rect.width, rectWidth);
//Draw property and settings in a line
DrawPropertyNoDepth (rect, property);
// ==========================
// Draw Icon Example
// ==========================
rect.x += rect.width;
rect.width = fullWidth - rect.width;
// References
SerializedProperty folderTexture = property.FindPropertyRelative ("folderIcon");
SerializedProperty overlayTexture = property.FindPropertyRelative ("overlayIcon");
SerializedProperty overlayOffset = property.FindPropertyRelative ("overlayOffset");
// Object checks
Object folderObject = folderTexture.objectReferenceValue;
Object overlayObject = overlayTexture.objectReferenceValue;
FolderIconGUI.DrawFolderPreview (rect, folderObject as Texture, overlayObject as Texture);
// Revert width modification
EditorGUIUtility.labelWidth = originalLabelWidth;
}
private void DrawPropertyNoDepth(Rect rect, SerializedProperty property)
{
rect.width++;
Handles.BeginGUI ();
Handles.DrawSolidRectangleWithOutline (rect, Color.clear, new Color (0.15f, 0.15f, 0.15f, 1f));
Handles.EndGUI ();
rect.x++;
rect.width -= 3;
rect.y += PROPERTY_PADDING;
rect.height = PROPERTY_HEIGHT;
SerializedProperty copy = property.Copy ();
bool enterChildren = true;
while(copy.Next(enterChildren))
{
if (SerializedProperty.EqualContents (copy, property.GetEndProperty ()))
break;
EditorGUI.PropertyField (rect, copy, false);
rect.y += PROPERTY_HEIGHT + PROPERTY_PADDING;
enterChildren = false;
}
}
private void DrawElementBackground(Rect rect, int index, bool isActive, bool isFocused)
{
EditorGUI.LabelField (rect, "", elementStyle);
Color fill = (isFocused) ? FolderIconConstants.SelectedColor : Color.clear;
Handles.BeginGUI ();
Handles.DrawSolidRectangleWithOutline (rect, fill, new Color(0.15f, 0.15f, 0.15f, 1f));
Handles.EndGUI ();
}
// ========================
//
// ========================
private int GetPropertyCount(SerializedProperty property)
{
return property.CountInProperty () - 1;
}
private float GetPropertyHeight(SerializedProperty property)
{
if (heightIndex == 0)
heightIndex = property.CountInProperty ();
// return (PROPERTY_HEIGHT + PROPERTY_PADDING) * (heightIndex-1) + PROPERTY_PADDING;
//Property count returning wrong, so just supplying 3 for now
//TODO: Investigate GetPropertyCount and find issue with invalid value
return (PROPERTY_HEIGHT + PROPERTY_PADDING) * (3) + PROPERTY_PADDING;
}
private float GetPropertyHeight(int index)
{
return GetPropertyHeight (serializedIcons.GetArrayElementAtIndex (index));
}
#endregion
#region Texture Preview/Creation
/// <summary>
/// Draw the preview for the texture
/// </summary>
private void DrawTexturePreview()
{
EditorGUILayout.LabelField ("Texture Colour Replacement", EditorStyles.boldLabel);
// Draw selection
EditorGUI.BeginChangeCheck ();
{
// Headers
EditorGUILayout.BeginHorizontal ();
EditorGUILayout.LabelField ("Original Texture");
EditorGUILayout.LabelField ("Modified Texture");
EditorGUILayout.EndHorizontal ();
// Texture -- Preview
EditorGUILayout.BeginHorizontal ();
{
selectedTexture = EditorGUILayout.ObjectField ( selectedTexture, typeof (Texture2D),
false, GUILayout.ExpandWidth(false), GUILayout.ExpandHeight(true), GUILayout.Width(64f)) as Texture2D;
EditorGUILayout.LabelField (previewContent, previewStyle, GUILayout.Height(64));
}
EditorGUILayout.EndHorizontal ();
}
if (EditorGUI.EndChangeCheck ())
{
if (selectedTexture == null)
{
ClearPreviewData ();
previewTexture = null;
return;
}
UpdatePreview ();
}
EditorGUILayout.Space ();
}
/// <summary>
/// Display settings for saving the modified texture
/// </summary>
private void DrawTextureSaving()
{
EditorGUILayout.LabelField ("Save Created Texture", EditorStyles.boldLabel);
// Texture Name
GUILayout.BeginHorizontal ();
{
textureName = EditorGUILayout.TextField ("Texture Name", textureName);
EditorGUI.BeginDisabledGroup (true);
GUILayout.TextField (".png", GUILayout.Width(40f));
EditorGUI.EndDisabledGroup ();
}
GUILayout.EndHorizontal ();
// Save Path
GUILayout.BeginHorizontal ();
{
savePath = EditorGUILayout.TextField ("Save Path", savePath);
if (GUILayout.Button ("Select", GUILayout.MaxWidth(80f)))
{
savePath = EditorUtility.OpenFolderPanel ("Texture Save Path", "Assets", "");
GUIUtility.ExitGUI ();
}
}
GUILayout.EndHorizontal ();
if (GUILayout.Button ("Save Texture"))
{
string fullPath = $"{savePath}/{textureName}.png";
SaveTextureAsPNG (previewTexture, fullPath);
}
}
/// <summary>
/// Apply colour to preview texture
/// </summary>
private void SetPreviewColour()
{
for (int x = 0; x < previewTexture.width; x++)
{
for (int y = 0; y < previewTexture.height; y++)
{
Color oldCol = previewTexture.GetPixel (x, y);
Color newCol = replacementColour;
newCol.a = oldCol.a;
previewTexture.SetPixel (x, y, newCol);
}
}
previewTexture.Apply ();
}
/// <summary>
/// Save the preview texture at the given path
/// </summary>
/// <param name="texture">The preview texture</param>
/// <param name="path">The path to save the texture at</param>
private void SaveTextureAsPNG(Texture2D texture, string path)
{
if (string.IsNullOrWhiteSpace(path) || !path.Contains("Assets"))
{
Debug.LogWarning ("Cannot save texture to invalid path.");
return;
}
byte[] bytes = texture.EncodeToPNG ();
File.WriteAllBytes (path, bytes);
AssetDatabase.Refresh ();
int localPathIndex = path.IndexOf ("Assets");
path = path.Substring (localPathIndex, path.Length - localPathIndex);
TextureImporter importer = AssetImporter.GetAtPath (path) as TextureImporter;
importer.textureType = TextureImporterType.GUI;
importer.isReadable = true;
AssetDatabase.ImportAsset (path);
AssetDatabase.Refresh ();
//Texture2D textureAsset = AssetDatabase.LoadAssetAtPath<Texture2D> (path);
//textureAsset.alphaIsTransparency = true;
//textureAsset.Apply ();
}
/// <summary>
/// Clear preview render texture
/// </summary>
private void ClearPreviewData()
{
if (previewRender != null)
previewRender.Release ();
}
/// <summary>
/// Update the preview with new texture information
/// </summary>
private void UpdatePreview()
{
ClearPreviewData ();
//No real point having a huge texture so limit the size for efficency sake
int width = Mathf.Min (256, selectedTexture.width);
int height = Mathf.Min (256, selectedTexture.height);
//Create a new render texture and preview
previewRender = new RenderTexture (width, height, 16);
previewTexture = new Texture2D (previewRender.width, previewRender.height)
{
alphaIsTransparency = true
};
previewContent.image = previewTexture;
Graphics.Blit (selectedTexture, previewRender);
// Get pixels from current render texture and apply
previewTexture.ReadPixels (new Rect (0, 0, previewRender.width, previewRender.height), 0, 0);
SetPreviewColour ();
}
#endregion
}
}