summaryrefslogtreecommitdiffstats
path: root/Scripts/Fold/Editor/FoldEditorWindow.cs
diff options
context:
space:
mode:
Diffstat (limited to 'Scripts/Fold/Editor/FoldEditorWindow.cs')
-rwxr-xr-xScripts/Fold/Editor/FoldEditorWindow.cs267
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()