diff options
| author | yum <yum.food.vr@gmail.com> | 2026-02-17 21:03:24 -0800 |
|---|---|---|
| committer | yum <yum.food.vr@gmail.com> | 2026-02-17 21:03:24 -0800 |
| commit | 6cefb137d8b0d68721fcf650c9da5fda237ee5b4 (patch) | |
| tree | ada165c6f011d6d7eb778e13bf4b91388c296ec9 /Scripts | |
| parent | e7e681b82b9f5bd492d3975560d4939c5b03be32 (diff) | |
Fold: ui tweaks
Diffstat (limited to 'Scripts')
| -rwxr-xr-x | Scripts/Fold/Editor/FoldEditorWindow.cs | 267 |
1 files changed, 192 insertions, 75 deletions
diff --git a/Scripts/Fold/Editor/FoldEditorWindow.cs b/Scripts/Fold/Editor/FoldEditorWindow.cs index 7cfb8aa..9c4cd2f 100755 --- a/Scripts/Fold/Editor/FoldEditorWindow.cs +++ b/Scripts/Fold/Editor/FoldEditorWindow.cs @@ -10,7 +10,6 @@ public class FoldEditorWindow : EditorWindow [SerializeField] Vector2 scrollPos; [SerializeReference] List<DeformOperation> operations = new(); [SerializeField] List<int> expandedOps = new(); - [SerializeField] bool liveUpdate = true; [SerializeField] GameObject targetObject; int frameStep; bool wasInAnimationMode; @@ -22,6 +21,78 @@ public class FoldEditorWindow : EditorWindow static Type s_animWindowType; static PropertyInfo s_clipProp, s_timeProp; + static class Styles + { + public static GUIStyle card; + public static GUIStyle cardHeader; + public static GUIStyle cardBody; + public static GUIStyle miniButtonLeft; + public static GUIStyle miniButtonMid; + public static GUIStyle miniButtonRight; + public static GUIStyle footerButton; + public static GUIStyle footerTextButton; + + public static GUIContent iconUp; + public static GUIContent iconDown; + public static GUIContent iconRemove; + public static GUIContent iconAdd; + public static GUIContent iconKey; + public static GUIContent iconRead; + public static GUIContent iconDeleteKey; + public static GUIContent iconClear; + public static GUIContent iconPrev; + public static GUIContent iconNext; + + public static void Init() + { + if (card != null) return; + + card = new GUIStyle(EditorStyles.helpBox); + card.padding = new RectOffset(1, 1, 1, 1); + card.margin = new RectOffset(4, 4, 4, 4); + + cardHeader = new GUIStyle(EditorStyles.toolbar); + cardHeader.fontStyle = FontStyle.Bold; + cardHeader.alignment = TextAnchor.MiddleLeft; + cardHeader.padding = new RectOffset(5, 5, 0, 0); + cardHeader.fixedHeight = 24; + + cardBody = new GUIStyle(EditorStyles.inspectorDefaultMargins); + cardBody.padding = new RectOffset(10, 10, 10, 10); + + miniButtonLeft = EditorStyles.miniButtonLeft; + miniButtonMid = EditorStyles.miniButtonMid; + miniButtonRight = EditorStyles.miniButtonRight; + + footerButton = new GUIStyle(EditorStyles.miniButton); + footerButton.fixedHeight = 24; + footerButton.fixedWidth = 32; + + footerTextButton = new GUIStyle(EditorStyles.miniButton); + footerTextButton.fixedHeight = 24; + + iconUp = EditorGUIUtility.IconContent("d_scrollup@2x"); + iconDown = EditorGUIUtility.IconContent("d_scrolldown@2x"); + iconRemove = EditorGUIUtility.IconContent("TreeEditor.Trash"); + iconAdd = EditorGUIUtility.IconContent("Toolbar Plus"); + + iconKey = EditorGUIUtility.IconContent("Animation.Record"); + iconRead = EditorGUIUtility.IconContent("d_Import"); + iconDeleteKey = EditorGUIUtility.IconContent("d_Toolbar Minus"); + iconClear = EditorGUIUtility.IconContent("TreeEditor.Trash"); + + iconPrev = EditorGUIUtility.IconContent("Animation.PrevKey"); + iconNext = EditorGUIUtility.IconContent("Animation.NextKey"); + + // Fallbacks if icons are missing + if (iconUp.image == null) iconUp.text = "▲"; + if (iconDown.image == null) iconDown.text = "▼"; + if (iconKey.image == null) iconKey.text = "Rec"; + if (iconRead.image == null) iconRead.text = "Load"; + if (iconDeleteKey.image == null) iconDeleteKey.text = "-"; + } + } + static void CacheAnimWindowReflection() { if (s_animWindowType != null) return; @@ -35,7 +106,7 @@ public class FoldEditorWindow : EditorWindow static void ShowWindow() { var window = GetWindow<FoldEditorWindow>("Fold"); - window.minSize = new Vector2(400, 300); + window.minSize = new Vector2(350, 400); } void OnEnable() @@ -77,6 +148,8 @@ public class FoldEditorWindow : EditorWindow void OnGUI() { + Styles.Init(); + bool inAnimMode = AnimationMode.InAnimationMode(); if (wasInAnimationMode && !inAnimMode) ClearPropertyBlock(); @@ -85,7 +158,7 @@ public class FoldEditorWindow : EditorWindow EditorGUILayout.Space(5); DrawHeader(); - EditorGUILayout.Space(10); + EditorGUILayout.Space(5); if (targetMaterial == null) { @@ -94,26 +167,26 @@ public class FoldEditorWindow : EditorWindow } DrawToolbar(); - EditorGUILayout.Space(5); - + EditorGUI.BeginChangeCheck(); scrollPos = EditorGUILayout.BeginScrollView(scrollPos); DrawOperationsList(); EditorGUILayout.EndScrollView(); - if (EditorGUI.EndChangeCheck() && liveUpdate && targetMaterial != null) + if (EditorGUI.EndChangeCheck() && targetMaterial != null) ApplyToMaterial(); - EditorGUILayout.Space(5); DrawFooter(); + EditorGUILayout.Space(5); } void DrawHeader() { + EditorGUILayout.BeginVertical(EditorStyles.inspectorDefaultMargins); + EditorGUILayout.BeginHorizontal(); EditorGUILayout.LabelField("Target Material", EditorStyles.boldLabel, GUILayout.Width(100)); - var newMat = EditorGUILayout.ObjectField(targetMaterial, typeof(Material), false) as Material; if (newMat != targetMaterial) { @@ -121,13 +194,14 @@ public class FoldEditorWindow : EditorWindow if (targetMaterial != null) LoadFromMaterial(); } - EditorGUILayout.EndHorizontal(); EditorGUILayout.BeginHorizontal(); EditorGUILayout.LabelField("Target Object", EditorStyles.boldLabel, GUILayout.Width(100)); targetObject = EditorGUILayout.ObjectField(targetObject, typeof(GameObject), true) as GameObject; EditorGUILayout.EndHorizontal(); + + EditorGUILayout.EndVertical(); } void DrawToolbar() @@ -138,16 +212,15 @@ public class FoldEditorWindow : EditorWindow using (new EditorGUI.DisabledScope(pipelineFull)) { var content = pipelineFull - ? new GUIContent("Add Operation", "Pipeline full (16/16)") - : new GUIContent("Add Operation"); - if (GUILayout.Button(content, EditorStyles.toolbarDropDown, GUILayout.Width(120))) + ? new GUIContent("Add Operation (Full)", "Pipeline full (16/16)") + : new GUIContent(" Add Operation", Styles.iconAdd.image); + + if (GUILayout.Button(content, EditorStyles.toolbarDropDown, GUILayout.Width(130))) ShowAddOperationMenu(); } GUILayout.FlexibleSpace(); - liveUpdate = GUILayout.Toggle(liveUpdate, "Live", EditorStyles.toolbarButton, GUILayout.Width(40)); - EditorGUILayout.EndHorizontal(); } @@ -155,14 +228,15 @@ public class FoldEditorWindow : EditorWindow { if (operations.Count == 0) { - EditorGUILayout.HelpBox("No operations. Click 'Add Operation' to begin.", MessageType.Info); + GUILayout.BeginVertical(Styles.card); + GUILayout.Label("Pipeline is empty.", EditorStyles.centeredGreyMiniLabel); + GUILayout.EndVertical(); return; } for (int i = 0; i < operations.Count; i++) { DrawOperation(i); - EditorGUILayout.Space(3); } } @@ -171,94 +245,126 @@ public class FoldEditorWindow : EditorWindow var op = operations[index]; bool isExpanded = expandedOps.Contains(index); - var bgColor = isExpanded ? new Color(0.3f, 0.5f, 0.8f, 0.3f) : new Color(0.2f, 0.2f, 0.2f, 0.3f); - - EditorGUILayout.BeginVertical(GUI.skin.box); - GUI.backgroundColor = bgColor; - - // Header with drag handle and delete button - EditorGUILayout.BeginHorizontal(); - - // Drag handle - GUILayout.Label($"#{index}", GUILayout.Width(30)); + // Tint background if expanded + var defaultColor = GUI.backgroundColor; + if (isExpanded) GUI.backgroundColor = new Color(0.9f, 0.95f, 1f); // Light blue tint + + EditorGUILayout.BeginVertical(Styles.card); + GUI.backgroundColor = defaultColor; // Reset for content + + // Header Rect + Rect headerRect = EditorGUILayout.GetControlRect(false, 24); + + // Background for header + if (Event.current.type == EventType.Repaint) + { + Styles.cardHeader.Draw(headerRect, GUIContent.none, false, false, false, false); + } - // Operation name (clickable to expand/collapse) - if (GUILayout.Button(op.GetDisplayName(), EditorStyles.boldLabel)) + // Calculate rects for controls inside the header + float btnWidth = 24; + float btnHeight = 18; + float btnSpacing = 0; + float rightPadding = 5; + float rightX = headerRect.xMax - rightPadding; + float btnY = headerRect.y + (headerRect.height - btnHeight) / 2; + + Rect removeRect = new Rect(rightX - btnWidth, btnY, btnWidth, btnHeight); + Rect downRect = new Rect(removeRect.x - btnWidth - btnSpacing, btnY, btnWidth, btnHeight); + Rect upRect = new Rect(downRect.x - btnWidth - btnSpacing, btnY, btnWidth, btnHeight); + + // Labels + Rect arrowRect = new Rect(headerRect.x + 5, headerRect.y + 4, 15, 16); + Rect indexRect = new Rect(headerRect.x + 20, headerRect.y + 4, 30, 16); + Rect labelRect = new Rect(headerRect.x + 50, headerRect.y + 4, upRect.x - (headerRect.x + 50), 16); + + // Foldout Click Area (covers everything except buttons) + Rect clickRect = new Rect(headerRect.x, headerRect.y, upRect.x - headerRect.x, headerRect.height); + if (GUI.Button(clickRect, GUIContent.none, GUIStyle.none)) { if (isExpanded) expandedOps.Remove(index); else expandedOps.Add(index); } - GUILayout.FlexibleSpace(); + // Draw Labels + GUI.Label(arrowRect, isExpanded ? "▼" : "▶", EditorStyles.label); + GUI.Label(indexRect, $"#{index}", EditorStyles.miniLabel); + GUI.Label(labelRect, op.GetDisplayName(), EditorStyles.boldLabel); - // Move up/down - GUI.enabled = index > 0; - if (GUILayout.Button("▲", GUILayout.Width(25))) + // Draw Buttons + if (GUI.Button(upRect, Styles.iconUp, Styles.miniButtonLeft)) { - operations.RemoveAt(index); - operations.Insert(index - 1, op); - if (expandedOps.Contains(index)) + if (index > 0) { - expandedOps.Remove(index); - expandedOps.Add(index - 1); + operations.RemoveAt(index); + operations.Insert(index - 1, op); + if (expandedOps.Contains(index)) + { + expandedOps.Remove(index); + expandedOps.Add(index - 1); + } } } - - GUI.enabled = index < operations.Count - 1; - if (GUILayout.Button("▼", GUILayout.Width(25))) + if (GUI.Button(downRect, Styles.iconDown, Styles.miniButtonMid)) { - operations.RemoveAt(index); - operations.Insert(index + 1, op); - if (expandedOps.Contains(index)) + if (index < operations.Count - 1) { - expandedOps.Remove(index); - expandedOps.Add(index + 1); + operations.RemoveAt(index); + operations.Insert(index + 1, op); + if (expandedOps.Contains(index)) + { + expandedOps.Remove(index); + expandedOps.Add(index + 1); + } } } - - GUI.enabled = true; - - // Delete button - if (GUILayout.Button("×", GUILayout.Width(25))) + if (GUI.Button(removeRect, Styles.iconRemove, Styles.miniButtonRight)) { - operations.RemoveAt(index); - expandedOps.Remove(index); - // Adjust indices in expandedOps - for (int i = 0; i < expandedOps.Count; i++) + if (EditorUtility.DisplayDialog("Remove Operation", $"Remove {op.GetDisplayName()}?", "Yes", "Cancel")) { - if (expandedOps[i] > index) expandedOps[i]--; + operations.RemoveAt(index); + expandedOps.Remove(index); + for (int i = 0; i < expandedOps.Count; i++) + if (expandedOps[i] > index) expandedOps[i]--; } } - EditorGUILayout.EndHorizontal(); - - // Draw parameters when expanded + // Parameters Body if (isExpanded) { - EditorGUILayout.Space(5); - EditorGUI.indentLevel++; + EditorGUILayout.BeginVertical(Styles.cardBody); + EditorGUIUtility.labelWidth = 140; op.DrawParameters(); - EditorGUI.indentLevel--; + EditorGUIUtility.labelWidth = 0; + EditorGUILayout.EndVertical(); } - GUI.backgroundColor = Color.white; EditorGUILayout.EndVertical(); } void DrawFooter() { + EditorGUILayout.BeginVertical(EditorStyles.inspectorDefaultMargins); + EditorGUILayout.Space(5); + + // Row 1: Keyframe & Animation Tools EditorGUILayout.BeginHorizontal(); + + if (GUILayout.Button(new GUIContent(Styles.iconRead.image, "Read from Playhead"), Styles.miniButtonLeft, GUILayout.Width(35), GUILayout.Height(24))) + ReadFromPlayhead(); - if (GUILayout.Button(new GUIContent("W", "Write keyframe at playhead"), GUILayout.Width(36), GUILayout.Height(36))) + if (GUILayout.Button(new GUIContent(Styles.iconKey.image, "Record Keyframe"), Styles.miniButtonMid, GUILayout.Width(35), GUILayout.Height(24))) ApplyToMaterial(recordKeyframes: true); - if (GUILayout.Button(new GUIContent("R", "Read animation values at playhead into editor"), GUILayout.Width(36), GUILayout.Height(36))) - ReadFromPlayhead(); - - if (GUILayout.Button(new GUIContent("X", "Delete keyframe at playhead"), GUILayout.Width(36), GUILayout.Height(36))) + if (GUILayout.Button(new GUIContent(Styles.iconDeleteKey.image, "Delete Keyframe"), Styles.miniButtonMid, GUILayout.Width(35), GUILayout.Height(24))) DeleteKeyframeAtCurrentTime(); + + if (GUILayout.Button(new GUIContent("Snap", "Snap to nearest keyframe"), Styles.miniButtonRight, GUILayout.Width(50), GUILayout.Height(24))) + SnapToNearestKeyframe(); + + GUILayout.FlexibleSpace(); - if (GUILayout.Button(new GUIContent("C", "Clear all operations"), GUILayout.Width(36), GUILayout.Height(36))) + if (GUILayout.Button(new GUIContent(Styles.iconClear.image, "Clear All"), Styles.footerButton)) { if (EditorUtility.DisplayDialog("Clear All Operations", "Remove all operations from the pipeline?", "Clear", "Cancel")) @@ -272,20 +378,31 @@ public class FoldEditorWindow : EditorWindow EditorGUILayout.EndHorizontal(); - EditorGUILayout.Space(3); + EditorGUILayout.Space(4); + // Row 2: Timeline Tools EditorGUILayout.BeginHorizontal(); - if (GUILayout.Button(new GUIContent("<", "Retreat playhead"), GUILayout.Width(36), GUILayout.Height(36))) + + if (GUILayout.Button(new GUIContent(Styles.iconPrev.image, "Step Back"), Styles.miniButtonLeft, GUILayout.Width(35), GUILayout.Height(24))) AdvancePlayhead(-frameStep); - frameStep = EditorGUILayout.IntField(frameStep, GUILayout.Width(40), GUILayout.Height(36)); + + var centerField = new GUIStyle(EditorStyles.numberField); + centerField.alignment = TextAnchor.MiddleCenter; + centerField.fixedHeight = 24; + frameStep = EditorGUILayout.IntField(frameStep, centerField, GUILayout.Width(40)); if (frameStep < 1) frameStep = 1; - if (GUILayout.Button(new GUIContent(">", "Advance playhead"), GUILayout.Width(36), GUILayout.Height(36))) + + if (GUILayout.Button(new GUIContent(Styles.iconNext.image, "Step Forward"), Styles.miniButtonRight, GUILayout.Width(35), GUILayout.Height(24))) AdvancePlayhead(frameStep); - if (GUILayout.Button(new GUIContent("Q", "Quantize: snap to nearest keyframe"), GUILayout.Width(36), GUILayout.Height(36))) - SnapToNearestKeyframe(); + GUILayout.FlexibleSpace(); - EditorGUILayout.LabelField($"Operations: {operations.Count}/16", EditorStyles.miniLabel); EditorGUILayout.EndHorizontal(); + + // Row 3: Info + EditorGUILayout.Space(5); + EditorGUILayout.LabelField($"{operations.Count} / 16 Operations", EditorStyles.centeredGreyMiniLabel); + + EditorGUILayout.EndVertical(); } void ShowAddOperationMenu() |
