void OnEnable() { // Detect animOps List <tk2dEditor.SpriteAnimationEditor.AnimOperator> animOpList = new List <tk2dEditor.SpriteAnimationEditor.AnimOperator>(); foreach (var assembly in System.AppDomain.CurrentDomain.GetAssemblies()) { try { System.Type[] types = assembly.GetTypes(); foreach (var type in types) { if (type.BaseType == typeof(tk2dEditor.SpriteAnimationEditor.AnimOperator)) { tk2dEditor.SpriteAnimationEditor.AnimOperator inst = (tk2dEditor.SpriteAnimationEditor.AnimOperator)System.Activator.CreateInstance(type); if (inst != null) { animOpList.Add(inst); } } } } catch { } } animOpList.Sort((a, b) => a.SortId.CompareTo(b.SortId)); animOps = animOpList.ToArray(); // Create menu items List <GUIContent> menuItems = new List <GUIContent>(); List <tk2dEditor.SpriteAnimationEditor.AnimOperator> menuTargets = new List <tk2dEditor.SpriteAnimationEditor.AnimOperator>(); menuItems.Add(new GUIContent("Clip")); menuTargets.Add(null); foreach (tk2dEditor.SpriteAnimationEditor.AnimOperator animOp in animOps) { for (int i = 0; i < animOp.AnimToolsMenu.Length; ++i) { menuItems.Add(new GUIContent(animOp.AnimToolsMenu[i])); menuTargets.Add(animOp); } } this.menuItems = menuItems.ToArray(); this.menuTargets = menuTargets.ToArray(); // Create clip editor if (clipEditor == null) { clipEditor = new tk2dEditor.SpriteAnimationEditor.ClipEditor(); clipEditor.clipNameChangedEvent += ClipNameChanged; clipEditor.clipDeletedEvent += ClipDeleted; clipEditor.clipSelectionChangedEvent += ClipSelectionChanged; clipEditor.hostEditorWindow = this; } clipEditor.animOps = animOps; FilterClips(); if (selectedClipId != -1 && selectedClipId < allClips.Count) { selectedClip = allClips[selectedClipId]; } else { selectedClip = null; } }
void DrawClipInspector() { GUILayout.BeginHorizontal(); GUILayout.Label("Clip", EditorStyles.largeLabel); if (GUILayout.Button("Delete", GUILayout.Width(46)) && EditorUtility.DisplayDialog("Delete clip", "Are you sure you want to delete the selected clip?", "Yes", "No")) { OnClipDeleted(); } GUILayout.EndHorizontal(); GUI.SetNextControlName("tk2dAnimName"); string changedName = EditorGUILayout.TextField("Name", clip.name).Trim(); if (selectClipNameField) { GUI.FocusControl("tk2dAnimName"); selectClipNameField = false; } if (changedName != clip.name && changedName.Length > 0) { clip.name = changedName; OnClipNameChanged(); } EditorGUILayout.IntField("Frames", clip.frames.Length); float fps = EditorGUILayout.FloatField("Frame rate", clip.fps); if (fps > 0) { clip.fps = fps; } float clipTime = clip.frames.Length / fps; float newClipTime = EditorGUILayout.FloatField("Clip time", clipTime); if (newClipTime > 0 && newClipTime != clipTime) { clip.fps = clip.frames.Length / newClipTime; } tk2dSpriteAnimationClip.WrapMode newWrapMode = (tk2dSpriteAnimationClip.WrapMode)EditorGUILayout.EnumPopup("Wrap Mode", clip.wrapMode); if (clip.wrapMode == tk2dSpriteAnimationClip.WrapMode.LoopSection) { clip.loopStart = EditorGUILayout.IntField("Loop Start", clip.loopStart); clip.loopStart = Mathf.Clamp(clip.loopStart, 0, clip.frames.Length - 1); } if (newWrapMode != clip.wrapMode) { if (newWrapMode == tk2dSpriteAnimationClip.WrapMode.Single && clip.frames.Length > 1) { // Will we be truncating the animation? if (EditorUtility.DisplayDialog("Wrap mode -> Single", "This will truncate your clip to a single frame. Do you want to continue?", "Yes", "No")) { clip.wrapMode = newWrapMode; frameGroups.RemoveRange(1, frameGroups.Count - 1); frameGroups[0].SetFrameCount(1); ClipEditor.RecalculateFrames(clip, frameGroups); } } else { clip.wrapMode = newWrapMode; } } // Tools GUILayout.Space(8); GUILayout.BeginHorizontal(); EditorGUILayout.PrefixLabel(" "); GUILayout.BeginVertical(); bool changed = false; foreach (tk2dEditor.SpriteAnimationEditor.AnimOperator animOp in animOps) { changed = animOp.OnClipInspectorGUI(clip, frameGroups, timelineEditor.CurrentState); if ((animOp.AnimEditOperations & tk2dEditor.SpriteAnimationEditor.AnimEditOperations.ClipContentChanged) != tk2dEditor.SpriteAnimationEditor.AnimEditOperations.None) { RecalculateFrames(); changed = true; } if ((animOp.AnimEditOperations & tk2dEditor.SpriteAnimationEditor.AnimEditOperations.ClipNameChanged) != tk2dEditor.SpriteAnimationEditor.AnimEditOperations.None) { OnClipNameChanged(); changed = true; } } if (changed) { Repaint(); } GUILayout.EndVertical(); GUILayout.EndHorizontal(); GUILayout.Space(8); }
// Internal convenience function void RecalculateFrames() { ClipEditor.RecalculateFrames(clip, frameGroups); }
void OnEnable() { // Detect animOps List<tk2dEditor.SpriteAnimationEditor.AnimOperator> animOpList = new List<tk2dEditor.SpriteAnimationEditor.AnimOperator>(); foreach (var assembly in System.AppDomain.CurrentDomain.GetAssemblies()) { try { System.Type[] types = assembly.GetTypes(); foreach (var type in types) { if (type.BaseType == typeof(tk2dEditor.SpriteAnimationEditor.AnimOperator)) { tk2dEditor.SpriteAnimationEditor.AnimOperator inst = (tk2dEditor.SpriteAnimationEditor.AnimOperator)System.Activator.CreateInstance(type); if (inst != null) animOpList.Add(inst); } } } catch { } } animOpList.Sort((a, b) => a.SortId.CompareTo(b.SortId)); animOps = animOpList.ToArray(); // Create menu items List<GUIContent> menuItems = new List<GUIContent>(); List<tk2dEditor.SpriteAnimationEditor.AnimOperator> menuTargets = new List<tk2dEditor.SpriteAnimationEditor.AnimOperator>(); menuItems.Add(new GUIContent("Clip")); menuTargets.Add(null); foreach (tk2dEditor.SpriteAnimationEditor.AnimOperator animOp in animOps) { for (int i = 0; i < animOp.AnimToolsMenu.Length; ++i) { menuItems.Add(new GUIContent(animOp.AnimToolsMenu[i])); menuTargets.Add(animOp); } } this.menuItems = menuItems.ToArray(); this.menuTargets = menuTargets.ToArray(); // Create clip editor if (clipEditor == null) { clipEditor = new tk2dEditor.SpriteAnimationEditor.ClipEditor(); clipEditor.clipNameChangedEvent += ClipNameChanged; clipEditor.clipDeletedEvent += ClipDeleted; clipEditor.clipSelectionChangedEvent += ClipSelectionChanged; clipEditor.hostEditorWindow = this; } clipEditor.animOps = animOps; FilterClips(); if (selectedClipId != -1 && selectedClipId < allClips.Count) { selectedClip = allClips[selectedClipId]; } else { selectedClip = null; } }
Rect GetRectForFrameGroup(Rect fgRect, ClipEditor.FrameGroup frameGroup) { return new Rect(fgRect.x + clipLeftHeaderSpace + frameWidth * frameGroup.startFrame, fgRect.y, frameGroup.frames.Count * frameWidth, fgRect.height); }
void DrawFrameGroupEx(Rect r, tk2dSpriteAnimationClip clip, ClipEditor.FrameGroup fg, bool highlighted, bool showTime, bool playHighlight) { if (highlighted && playHighlight) GUI.color = new Color(1.0f, 0.8f, 1.0f, 1.0f); else if (playHighlight) GUI.color = new Color(1.0f, 0.8f, 0.8f, 1.0f); else if (highlighted) GUI.color = new Color(0.8f, 0.8f, 1.0f, 1.0f); tk2dSpriteCollectionData sc = fg.spriteCollection; int spriteId = fg.spriteId; string name = sc.inst.spriteDefinitions[spriteId].name; string label = name; if (showTime) { string numFrames = (fg.frames.Count == 1) ? "1 frame" : (fg.frames.Count.ToString() + " frames"); string time = (fg.frames.Count / clip.fps).ToString("0.000") + "s"; label = label + "\n" + numFrames + "\n" + time; } GUI.Label(r, label, "button"); if (highlighted || playHighlight) GUI.color = Color.white; }
void DrawFrameGroup(Rect r, tk2dSpriteAnimationClip clip, ClipEditor.FrameGroup fg) { DrawFrameGroupEx(r, clip, fg, false, false, false); }
void DrawFrameGroups(int controlId, Rect frameGroupRect, tk2dSpriteAnimationClip clip, List <ClipEditor.FrameGroup> frameGroups, float clipTimeMarker) { bool singleFrameMode = clip.wrapMode == tk2dSpriteAnimationClip.WrapMode.Single; // Initialize startframe in framegroups int numFrames = 0; foreach (ClipEditor.FrameGroup fg in frameGroups) { fg.startFrame = numFrames; numFrames += fg.frames.Count; } // Draw frames int currrentFrameGroup = 0; foreach (ClipEditor.FrameGroup fg in frameGroups) { Rect r = GetRectForFrameGroup(frameGroupRect, fg); DrawFrameGroupEx(r, clip, fg, /* highlighted: */ currrentFrameGroup == state.selectedFrame, /* showTime: */ currrentFrameGroup == state.selectedFrame, /* playHighlight: */ clipTimeMarker >= fg.startFrame && clipTimeMarker < fg.startFrame + fg.frames.Count); if (!singleFrameMode) { EditorGUIUtility.AddCursorRect(GetResizeRectFromFrameRect(r), MouseCursor.ResizeHorizontal); } currrentFrameGroup++; } // Add frame button if ((int)state.type < (int)State.Type.Action) { Rect addFrameButonRect = GetRectForFrame(frameGroupRect, clip.frames.Length, 1); addFrameButonRect = new Rect(addFrameButonRect.x + addFrameButonRect.width * 0.25f, addFrameButonRect.y + addFrameButonRect.height * 0.25f, addFrameButonRect.height * 0.5f, addFrameButonRect.height * 0.5f); if (!singleFrameMode && GUI.Button(addFrameButonRect, "+")) { frameGroups.Add(AnimOperatorUtil.NewFrameGroup(frameGroups, frameGroups.Count - 1)); ClipEditor.RecalculateFrames(clip, frameGroups); state.selectedFrame = frameGroups.Count - 1; Repaint(); } } // Draw insert marker if (GUIUtility.hotControl == controlId && state.type == State.Type.Move && state.activeFrame != -1 && state.insertMarker != -1) { Vector2 v = GetInsertMarkerPositionForFrameGroup(frameGroupRect, state.insertMarker, frameGroups); GUI.color = Color.green; GUI.Box(new Rect(v.x, v.y, 2, frameGroupRect.height), "", tk2dEditorSkin.WhiteBox); GUI.color = Color.white; } // Keyboard shortcuts Event ev = Event.current; if (ev.type == EventType.KeyDown && GUIUtility.keyboardControl == 0 && state.type == State.Type.None && state.selectedFrame != -1) { int newFrame = state.selectedFrame; switch (ev.keyCode) { case KeyCode.LeftArrow: case KeyCode.Comma: newFrame--; break; case KeyCode.RightArrow: case KeyCode.Period: newFrame++; break; case KeyCode.Home: newFrame = 0; break; case KeyCode.End: newFrame = frameGroups.Count - 1; break; case KeyCode.Escape: state.selectedFrame = -1; Repaint(); ev.Use(); break; } if (ev.type != EventType.Used && frameGroups.Count > 0) { newFrame = Mathf.Clamp(newFrame, 0, frameGroups.Count - 1); if (newFrame != state.selectedFrame) { state.selectedFrame = newFrame; Repaint(); ev.Use(); } } } if (state.selectedFrame != -1 && (GUIUtility.hotControl == controlId || (GUIUtility.keyboardControl == 0 && state.type == State.Type.None))) { if (ev.type == EventType.KeyDown && (ev.keyCode == KeyCode.Delete || ev.keyCode == KeyCode.Backspace) && frameGroups.Count > 1) { frameGroups.RemoveAt(state.selectedFrame); ClipEditor.RecalculateFrames(clip, frameGroups); GUIUtility.hotControl = 0; state.Reset(); Repaint(); ev.Use(); } } if (ev.type == EventType.MouseDown || GUIUtility.hotControl == controlId) { switch (ev.GetTypeForControl(controlId)) { case EventType.MouseDown: if (frameGroupRect.Contains(ev.mousePosition)) { int frameGroup = GetSelectedFrameGroup(frameGroupRect, ev.mousePosition, frameGroups, false); if (frameGroup != state.selectedFrame) { Repaint(); state.selectedFrame = frameGroup; } if (frameGroup != -1) { Rect r = GetRectForFrameGroup(frameGroupRect, frameGroups[frameGroup]); Rect resizeRect = GetResizeRectFromFrameRect(r); state.frameSelectionOffset = ev.mousePosition - new Vector2(r.x, 0); state.type = resizeRect.Contains(ev.mousePosition) ? State.Type.Resize : State.Type.MoveHandle; if (state.type == State.Type.Resize) { if (singleFrameMode) { state.ResetState(); // disallow resize in single frame mode } else { state.backupFrames = new List <tk2dSpriteAnimationFrame>(frameGroups[frameGroup].frames); // make a backup of frames for triggers state.activeFrame = frameGroup; state.insertMarker = state.activeFrame; } } else { state.activeFrame = frameGroup; state.insertMarker = state.activeFrame; } } GUIUtility.hotControl = controlId; } GUIUtility.keyboardControl = 0; break; case EventType.MouseDrag: { switch (state.type) { case State.Type.MoveHandle: case State.Type.Move: { state.type = State.Type.Move; state.insertMarker = GetSelectedFrameGroup(frameGroupRect, ev.mousePosition, frameGroups, true); } break; case State.Type.Resize: { int frame = GetSelectedFrame(frameGroupRect, ev.mousePosition + new Vector2(frameWidth * 0.5f, 0.0f)); ClipEditor.FrameGroup fg = frameGroups[state.activeFrame]; int frameCount = Mathf.Max(1, frame - fg.startFrame); bool changed = frameCount != fg.frames.Count; if (changed) { fg.frames = new List <tk2dSpriteAnimationFrame>(state.backupFrames); fg.SetFrameCount(frameCount); Repaint(); ClipEditor.RecalculateFrames(clip, frameGroups); } } break; } } break; case EventType.MouseUp: switch (state.type) { case State.Type.Move: { int finalInsertMarker = (state.insertMarker > state.activeFrame) ? (state.insertMarker - 1) : state.insertMarker; if (state.activeFrame != finalInsertMarker) { ClipEditor.FrameGroup tmpFrameGroup = frameGroups[state.activeFrame]; frameGroups.RemoveAt(state.activeFrame); frameGroups.Insert(finalInsertMarker, tmpFrameGroup); state.selectedFrame = finalInsertMarker; ClipEditor.RecalculateFrames(clip, frameGroups); Repaint(); } } break; } if (state.type != State.Type.None) { Repaint(); } state.ResetState(); GUIUtility.keyboardControl = 0; GUIUtility.hotControl = 0; break; } } if (clipTimeMarker >= 0.0f) { float x = clipLeftHeaderSpace + frameWidth * clipTimeMarker; GUI.color = Color.red; GUI.Box(new Rect(frameGroupRect.x + x, frameGroupRect.y, 2, frameGroupRect.height), "", tk2dEditorSkin.WhiteBox); GUI.color = Color.white; } }