public override bool OnFrameGroupInspectorGUI(tk2dSpriteAnimationClip selectedClip, List <ClipEditor.FrameGroup> frameGroups, TimelineEditor.State state) { if (selectedClip.wrapMode == tk2dSpriteAnimationClip.WrapMode.Single) { return(false); } bool changed = false; GUILayout.BeginHorizontal(); if (GUILayout.Button("Insert <", EditorStyles.miniButton)) { frameGroups.Insert(state.selectedFrame, AnimOperatorUtil.NewFrameGroup(frameGroups, state.selectedFrame)); state.selectedFrame++; changed = true; } if (GUILayout.Button("Insert >", EditorStyles.miniButton)) { frameGroups.Insert(state.selectedFrame + 1, AnimOperatorUtil.NewFrameGroup(frameGroups, state.selectedFrame)); changed = true; } GUILayout.EndHorizontal(); operations = changed ? AnimEditOperations.ClipContentChanged : AnimEditOperations.None; return(changed); }
// Check the AnimOperator class for the different supported operator types. // This sample simply deletes the frames after the currently selected clip. public override bool OnFrameGroupInspectorGUI(tk2dSpriteAnimationClip selectedClip, List <ClipEditor.FrameGroup> frameGroups, TimelineEditor.State state) { // WrapMode.Single is a special case - you are only allowed to have one frame in a "Single" clip. // If you don't handle this, tk2d will truncate the list when it is Committed. if (selectedClip.wrapMode == tk2dSpriteAnimationClip.WrapMode.Single) { return(false); } // Keep track of changes. // In a lot of cases, a simple bool will suffice. This is used later to // tell the system that something has changed. bool changed = false; GUILayout.BeginHorizontal(); if (GUILayout.Button("Ins <-", EditorStyles.miniButton)) { frameGroups.Insert(state.selectedFrame, AnimOperatorUtil.NewFrameGroup(frameGroups, state.selectedFrame)); // Make sure state is valid after performing your operation. // For instance, if the selected frame is deleted, ensure it isn't selected any more. state.selectedFrame++; changed = true; } if (GUILayout.Button("Ins ->", EditorStyles.miniButton)) { frameGroups.Insert(state.selectedFrame + 1, AnimOperatorUtil.NewFrameGroup(frameGroups, state.selectedFrame)); changed = true; } GUILayout.EndHorizontal(); // Tell the caller what has changed operations = changed ? AnimEditOperations.ClipContentChanged : AnimEditOperations.None; return(changed); }
bool AutoFill(List <ClipEditor.FrameGroup> frameGroups, int selectedFrame, bool reverse) { ClipEditor.FrameGroup selectedFrameGroup = frameGroups[selectedFrame]; if (selectedFrameGroup.spriteCollection != null && selectedFrameGroup.spriteId >= 0 && selectedFrameGroup.spriteId < selectedFrameGroup.spriteCollection.inst.Count) { string na = selectedFrameGroup.spriteCollection.inst.spriteDefinitions[selectedFrameGroup.spriteId].name; int numStartA = na.Length - 1; if (na[numStartA] >= '0' && na[numStartA] <= '9') { while (numStartA > 0 && na[numStartA - 1] >= '0' && na[numStartA - 1] <= '9') { numStartA--; } string baseName = na.Substring(0, numStartA).ToLower(); int baseNo = System.Convert.ToInt32(na.Substring(numStartA)); int maxAllowedMissing = 10; int allowedMissing = maxAllowedMissing; List <int> pendingFrames = new List <int>(); int startOffset = reverse ? -1 : 1; int frameInc = reverse ? -1 : 1; for (int frameNo = baseNo + startOffset; frameNo >= 0; frameNo += frameInc) { int frameIdx = FindFrameIndex(selectedFrameGroup.spriteCollection.inst.spriteDefinitions, baseName, frameNo); if (frameIdx == -1) { if (--allowedMissing <= 0) { break; } } else { pendingFrames.Add(frameIdx); allowedMissing = maxAllowedMissing; // reset } } int numInserted = 0; int insertIndex = selectedFrame + 1; ClipEditor.FrameGroup nextFrameGroup = (insertIndex >= frameGroups.Count) ? null : frameGroups[insertIndex]; while (pendingFrames.Count > 0) { int frameToInsert = pendingFrames[0]; pendingFrames.RemoveAt(0); if (nextFrameGroup != null && nextFrameGroup.spriteCollection == selectedFrameGroup.spriteCollection && nextFrameGroup.spriteId == frameToInsert) { break; } ClipEditor.FrameGroup fg = AnimOperatorUtil.NewFrameGroup(frameGroups, selectedFrame); fg.spriteId = frameToInsert; fg.Update(); frameGroups.Insert(insertIndex++, fg); numInserted++; } return(numInserted > 0); } } return(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; } }