using System; using UnityEditor.U2D.Common; using UnityEditor.U2D.Layout; using UnityEngine; using UnityEditor.ShortcutManagement; using UnityEngine.UIElements; namespace UnityEditor.U2D.Animation { internal partial class SkinningModule { private LayoutOverlay m_LayoutOverlay; private PoseToolbar m_PoseToolbar; private BoneToolbar m_BoneToolbar; private MeshToolbar m_MeshToolbar; private WeightToolbar m_WeightToolbar; private RigToolbar m_RigToolbar; private InternalEditorBridge.ShortcutContext m_ShortcutContext; private static SkinningModule GetModuleFromContext(ShortcutArguments args) { var sc = args.context as InternalEditorBridge.ShortcutContext; if (sc == null) return null; return sc.context as SkinningModule; } [Shortcut(ShortcutIds.toggleToolText, typeof(InternalEditorBridge.ShortcutContext), KeyCode.BackQuote, ShortcutModifiers.Shift)] private static void CollapseToolbar(ShortcutArguments args) { var sm = GetModuleFromContext(args); if (sm != null) { SkinningModuleSettings.compactToolBar = !SkinningModuleSettings.compactToolBar; } } [Shortcut(ShortcutIds.restoreBindPose, typeof(InternalEditorBridge.ShortcutContext), KeyCode.Alpha1, ShortcutModifiers.Shift)] private static void DisablePoseModeKey(ShortcutArguments args) { var sm = GetModuleFromContext(args); if (sm != null && !sm.spriteEditor.editingDisabled) { var effectiveSkeleton = sm.skinningCache.GetEffectiveSkeleton(sm.skinningCache.selectedSprite); if (effectiveSkeleton != null && effectiveSkeleton.isPosePreview) { using (sm.skinningCache.UndoScope(TextContent.restorePose)) { sm.skinningCache.RestoreBindPose(); sm.skinningCache.events.shortcut.Invoke("#1"); } } } } [Shortcut(ShortcutIds.toggleCharacterMode, typeof(InternalEditorBridge.ShortcutContext), KeyCode.Alpha2, ShortcutModifiers.Shift)] private static void ToggleCharacterModeKey(ShortcutArguments args) { var sm = GetModuleFromContext(args); if (sm != null && !sm.spriteEditor.editingDisabled && sm.skinningCache.hasCharacter) { var tool = sm.skinningCache.GetTool(Tools.SwitchMode); using (sm.skinningCache.UndoScope(TextContent.setMode)) { if (tool.isActive) tool.Deactivate(); else tool.Activate(); } sm.skinningCache.events.shortcut.Invoke("#2"); } } [Shortcut(ShortcutIds.previewPose, typeof(InternalEditorBridge.ShortcutContext), KeyCode.Q, ShortcutModifiers.Shift)] private static void EditPoseKey(ShortcutArguments args) { var sm = GetModuleFromContext(args); if (sm != null && !sm.spriteEditor.editingDisabled) { sm.SetSkeletonTool(Tools.EditPose); sm.skinningCache.events.shortcut.Invoke("#q"); } } [Shortcut(ShortcutIds.editBone, typeof(InternalEditorBridge.ShortcutContext), KeyCode.W, ShortcutModifiers.Shift)] private static void EditJointsKey(ShortcutArguments args) { var sm = GetModuleFromContext(args); if (sm != null && !sm.spriteEditor.editingDisabled) { sm.SetSkeletonTool(Tools.EditJoints); sm.skinningCache.events.shortcut.Invoke("#w"); } } [Shortcut(ShortcutIds.createBone, typeof(InternalEditorBridge.ShortcutContext), KeyCode.E, ShortcutModifiers.Shift)] private static void CreateBoneKey(ShortcutArguments args) { var sm = GetModuleFromContext(args); if (sm != null && !sm.spriteEditor.editingDisabled) { sm.SetSkeletonTool(Tools.CreateBone); sm.skinningCache.events.shortcut.Invoke("#e"); } } [Shortcut(ShortcutIds.splitBone, typeof(InternalEditorBridge.ShortcutContext), KeyCode.R, ShortcutModifiers.Shift)] private static void SplitBoneKey(ShortcutArguments args) { var sm = GetModuleFromContext(args); if (sm != null && !sm.spriteEditor.editingDisabled) { sm.SetSkeletonTool(Tools.SplitBone); sm.skinningCache.events.shortcut.Invoke("#r"); } } [Shortcut(ShortcutIds.autoGeometry, typeof(InternalEditorBridge.ShortcutContext), KeyCode.A, ShortcutModifiers.Shift)] private static void GenerateGeometryKey(ShortcutArguments args) { var sm = GetModuleFromContext(args); if (sm != null && !sm.spriteEditor.editingDisabled) { sm.SetMeshTool(Tools.GenerateGeometry); sm.skinningCache.events.shortcut.Invoke("#a"); } } [Shortcut(ShortcutIds.editGeometry, typeof(InternalEditorBridge.ShortcutContext), KeyCode.S, ShortcutModifiers.Shift)] private static void MeshSelectionKey(ShortcutArguments args) { var sm = GetModuleFromContext(args); if (sm != null && !sm.spriteEditor.editingDisabled) { sm.SetMeshTool(Tools.EditGeometry); sm.skinningCache.events.shortcut.Invoke("#s"); } } [Shortcut(ShortcutIds.createVertex, typeof(InternalEditorBridge.ShortcutContext), KeyCode.J, ShortcutModifiers.Shift)] private static void CreateVertex(ShortcutArguments args) { var sm = GetModuleFromContext(args); if (sm != null && !sm.spriteEditor.editingDisabled) { sm.SetMeshTool(Tools.CreateVertex); sm.skinningCache.events.shortcut.Invoke("#d"); } } [Shortcut(ShortcutIds.createEdge, typeof(InternalEditorBridge.ShortcutContext), KeyCode.G, ShortcutModifiers.Shift)] private static void CreateEdgeKey(ShortcutArguments args) { var sm = GetModuleFromContext(args); if (sm != null && !sm.spriteEditor.editingDisabled) { sm.SetMeshTool(Tools.CreateEdge); sm.skinningCache.events.shortcut.Invoke("#g"); } } [Shortcut(ShortcutIds.splitEdge, typeof(InternalEditorBridge.ShortcutContext), KeyCode.H, ShortcutModifiers.Shift)] private static void SplitEdge(ShortcutArguments args) { var sm = GetModuleFromContext(args); if (sm != null && !sm.spriteEditor.editingDisabled) { sm.SetMeshTool(Tools.SplitEdge); sm.skinningCache.events.shortcut.Invoke("#h"); } } [Shortcut(ShortcutIds.autoWeights, typeof(InternalEditorBridge.ShortcutContext), KeyCode.Z, ShortcutModifiers.Shift)] private static void GenerateWeightsKey(ShortcutArguments args) { var sm = GetModuleFromContext(args); if (sm != null && !sm.spriteEditor.editingDisabled) { sm.SetWeightTool(Tools.GenerateWeights); sm.skinningCache.events.shortcut.Invoke("#z"); } } [Shortcut(ShortcutIds.weightSlider, typeof(InternalEditorBridge.ShortcutContext), KeyCode.X, ShortcutModifiers.Shift)] private static void WeightSliderKey(ShortcutArguments args) { var sm = GetModuleFromContext(args); if (sm != null && !sm.spriteEditor.editingDisabled) { sm.SetWeightTool(Tools.WeightSlider); sm.skinningCache.events.shortcut.Invoke("#x"); } } [Shortcut(ShortcutIds.weightBrush, typeof(InternalEditorBridge.ShortcutContext), KeyCode.N, ShortcutModifiers.Shift)] private static void WeightBrushKey(ShortcutArguments args) { var sm = GetModuleFromContext(args); if (sm != null && !sm.spriteEditor.editingDisabled) { sm.SetWeightTool(Tools.WeightBrush); sm.skinningCache.events.shortcut.Invoke("#c"); } } [Shortcut(ShortcutIds.boneInfluence, typeof(InternalEditorBridge.ShortcutContext), KeyCode.V, ShortcutModifiers.Shift)] private static void BoneInfluenceKey(ShortcutArguments args) { var sm = GetModuleFromContext(args); if (sm != null && !sm.spriteEditor.editingDisabled && sm.skinningCache.mode == SkinningMode.Character) { sm.SetWeightTool(Tools.BoneInfluence); sm.skinningCache.events.shortcut.Invoke("#v"); } } [Shortcut(ShortcutIds.spriteInfluence, typeof(InternalEditorBridge.ShortcutContext), KeyCode.M, ShortcutModifiers.Shift)] private static void SpriteInfluenceKey(ShortcutArguments args) { var sm = GetModuleFromContext(args); if (sm != null && !sm.spriteEditor.editingDisabled && sm.skinningCache.mode == SkinningMode.Character) { sm.SetWeightTool(Tools.SpriteInfluence); sm.skinningCache.events.shortcut.Invoke("#m"); } } [Shortcut(ShortcutIds.pastePanelWeights, typeof(InternalEditorBridge.ShortcutContext), KeyCode.B, ShortcutModifiers.Shift)] private static void PastePanelKey(ShortcutArguments args) { var sm = GetModuleFromContext(args); if (sm != null && !sm.spriteEditor.editingDisabled) { sm.TogglePasteTool(); sm.skinningCache.events.shortcut.Invoke("#b"); } } [Shortcut(ShortcutIds.visibilityPanel, typeof(InternalEditorBridge.ShortcutContext), KeyCode.P, ShortcutModifiers.Shift)] private static void VisibilityPanelKey(ShortcutArguments args) { var sm = GetModuleFromContext(args); if (sm != null && !sm.spriteEditor.editingDisabled) { sm.m_HorizontalToggleTools.ToggleVisibilityTool(sm.currentTool); sm.skinningCache.events.shortcut.Invoke("#p"); } } private void AddMainUI(VisualElement mainView) { var visualTree = ResourceLoader.Load("LayoutOverlay/LayoutOverlay.uxml"); VisualElement clone = visualTree.CloneTree(); m_LayoutOverlay = clone.Q("LayoutOverlay"); mainView.Add(m_LayoutOverlay); m_LayoutOverlay.hasScrollbar = true; m_LayoutOverlay.verticalToolbar.verticalScrollerVisibility = ScrollerVisibility.Hidden; m_LayoutOverlay.StretchToParentSize(); CreatePoseToolbar(); CreateBoneToolbar(); CreateMeshToolbar(); CreateWeightToolbar(); CreateRigToolbar(); m_ShortcutContext = new InternalEditorBridge.ShortcutContext() { isActive = isFocused, context = this }; InternalEditorBridge.RegisterShortcutContext(m_ShortcutContext); InternalEditorBridge.AddEditorApplicationProjectLoadedCallback(OnProjectLoaded); } private void OnProjectLoaded() { if (m_ShortcutContext != null) InternalEditorBridge.RegisterShortcutContext(m_ShortcutContext); } private void DoViewGUI() { if (spriteEditor.editingDisabled == m_BoneToolbar.enabledSelf) { m_BoneToolbar.SetEnabled(!spriteEditor.editingDisabled); m_MeshToolbar.SetEnabled(!spriteEditor.editingDisabled); m_WeightToolbar.SetEnabled(!spriteEditor.editingDisabled); } if (spriteEditor.editingDisabled == m_LayoutOverlay.rightOverlay.enabledSelf) { m_LayoutOverlay.rightOverlay.SetEnabled(!spriteEditor.editingDisabled); m_LayoutOverlay.rightOverlay.visible = !spriteEditor.editingDisabled; } m_PoseToolbar.UpdateResetButtonState(); m_RigToolbar.UpdatePasteButtonEnabledState(); } private bool isFocused() { return spriteEditor != null && (EditorWindow.focusedWindow == spriteEditor as EditorWindow); } private void CreatePoseToolbar() { m_PoseToolbar = PoseToolbar.GenerateFromUXML(); m_PoseToolbar.skinningCache = skinningCache; m_LayoutOverlay.verticalToolbar.AddToContainer(m_PoseToolbar); m_PoseToolbar.ActivateEditPoseTool += ActivateEditPoseTool; m_PoseToolbar.SetEnabled(!spriteEditor.editingDisabled); } private void CreateBoneToolbar() { m_BoneToolbar = BoneToolbar.GenerateFromUXML(); m_BoneToolbar.Setup(skinningCache); m_LayoutOverlay.verticalToolbar.AddToContainer(m_BoneToolbar); m_BoneToolbar.SetSkeletonTool += SetSkeletonTool; m_BoneToolbar.SetEnabled(!spriteEditor.editingDisabled); } private void CreateMeshToolbar() { m_MeshToolbar = MeshToolbar.GenerateFromUXML(); m_MeshToolbar.skinningCache = skinningCache; m_LayoutOverlay.verticalToolbar.AddToContainer(m_MeshToolbar); m_MeshToolbar.SetMeshTool += SetMeshTool; m_MeshToolbar.SetEnabled(!spriteEditor.editingDisabled); } private void CreateWeightToolbar() { m_WeightToolbar = WeightToolbar.GenerateFromUXML(); m_WeightToolbar.skinningCache = skinningCache; m_LayoutOverlay.verticalToolbar.AddToContainer(m_WeightToolbar); m_WeightToolbar.SetWeightTool += SetWeightTool; m_WeightToolbar.SetEnabled(!spriteEditor.editingDisabled); } private void CreateRigToolbar() { m_RigToolbar = RigToolbar.GenerateFromUXML(); m_RigToolbar.skinningCache = skinningCache; m_LayoutOverlay.verticalToolbar.AddToContainer(m_RigToolbar); m_RigToolbar.ActivateCopyTool += ActivateCopyTool; m_RigToolbar.TogglePasteTool += TogglePasteTool; m_RigToolbar.SetEnabled(!spriteEditor.editingDisabled); } private void ActivateEditPoseTool() { var tool = skinningCache.GetTool(Tools.EditPose); if (currentTool == tool) return; using (skinningCache.UndoScope(TextContent.setTool)) { ActivateTool(tool); } } private void SetSkeletonTool(Tools toolType) { var tool = skinningCache.GetTool(toolType) as SkeletonToolWrapper; if (currentTool == tool) return; using (skinningCache.UndoScope(TextContent.setTool)) { ActivateTool(tool); if (tool.editBindPose) skinningCache.RestoreBindPose(); } } private void SetMeshTool(Tools toolType) { var tool = skinningCache.GetTool(toolType); if (currentTool == tool) return; using (skinningCache.UndoScope(TextContent.setTool)) { ActivateTool(tool); skinningCache.RestoreBindPose(); UnselectBones(); } } private void SetWeightTool(Tools toolType) { var tool = skinningCache.GetTool(toolType); if (currentTool == tool) return; using (skinningCache.UndoScope(TextContent.setTool)) { ActivateTool(tool); } } private void ActivateCopyTool() { var tool = skinningCache.GetTool(Tools.CopyPaste) as CopyTool; tool.OnCopyActivated(); } private void TogglePasteTool() { var tool = skinningCache.GetTool(Tools.CopyPaste) as CopyTool; if (!tool.isActive) ActivateTool(tool); else if (previousTool != null) ActivateTool(previousTool); } private void StorePreviousTool() { if (currentTool is CopyTool || currentTool is VisibilityTool) return; previousTool = currentTool; } private void ActivateTool(BaseTool tool) { StorePreviousTool(); m_ModuleToolGroup.ActivateTool(tool); UpdateToggleState(); skinningCache.events.toolChanged.Invoke(tool); } private void UnselectBones() { skinningCache.skeletonSelection.Clear(); skinningCache.events.boneSelectionChanged.Invoke(); } private void UpdateToggleState() { Debug.Assert(m_PoseToolbar != null); Debug.Assert(m_BoneToolbar != null); Debug.Assert(m_MeshToolbar != null); Debug.Assert(m_WeightToolbar != null); m_PoseToolbar.UpdatePreviewButtonCheckedState(); m_BoneToolbar.UpdateToggleState(); m_MeshToolbar.UpdateToggleState(); m_WeightToolbar.UpdateToggleState(); m_RigToolbar.UpdatePasteButtonCheckedState(); } private void RemoveMainUI(VisualElement mainView) { InternalEditorBridge.RemoveEditorApplicationProjectLoadedCallback(OnProjectLoaded); InternalEditorBridge.UnregisterShortcutContext(m_ShortcutContext); } } }