A game about forced loneliness, made by TACStudios
at master 308 lines 13 kB view raw
1using System; 2using UnityEditor.U2D.Layout; 3using UnityEditor.U2D.Common; 4using UnityEngine; 5using UnityEngine.UIElements; 6 7namespace UnityEditor.U2D.Animation 8{ 9#if ENABLE_UXML_SERIALIZED_DATA 10 [UxmlElement] 11#endif 12 internal partial class PivotInspectorPanel : VisualElement 13 { 14 EnumField m_PivotAlignment; 15 Vector2Field m_PivotPosition; 16 17#if ENABLE_UXML_TRAITS 18 public class CustomUxmlFactory : UxmlFactory<PivotInspectorPanel, UxmlTraits> { } 19#endif 20 21 internal static PivotInspectorPanel CreateFromUxml() 22 { 23 var visualTree = ResourceLoader.Load<VisualTreeAsset>("SkinningModule/PivotInspectorPanel.uxml"); 24 var ve = (PivotInspectorPanel)visualTree.CloneTree().Q("PivotInspectorPanel"); 25 ve.styleSheets.Add(ResourceLoader.Load<StyleSheet>("SkinningModule/PivotInspectorPanelStyle.uss")); 26 if (EditorGUIUtility.isProSkin) 27 ve.AddToClassList("Dark"); 28 ve.LocalizeTextInChildren(); 29 ve.BindElements(); 30 return ve; 31 } 32 33 private void BindElements() 34 { 35 m_PivotPosition = this.Q<Vector2Field>("PivotPositionField"); 36 m_PivotAlignment = this.Q<EnumField>("pivotField"); 37 m_PivotAlignment.Init(SpriteAlignment.Center); 38 m_PivotAlignment.label = TextContent.pivot; 39 } 40 41 public EnumField pivotAlignment 42 { 43 get => m_PivotAlignment; 44 set => m_PivotAlignment = value; 45 } 46 47 public Vector2Field pivotPosition 48 { 49 get => m_PivotPosition; 50 set => m_PivotPosition = value; 51 } 52 } 53 54 internal class PivotTool : SkeletonToolWrapper 55 { 56 static class Styles 57 { 58 public static GUIStyle pivotdotactive = "U2D.pivotDotActive"; 59 public static GUIStyle pivotdot = "U2D.pivotDot"; 60 } 61 62 Vector2 m_Pivot = Vector2.zero; 63 Vector2 m_CurrentMousePosition; 64 Vector2 m_DragScreenOffset; 65 Vector2 m_DragStartScreenPosition; 66 SpriteCache m_LastSelectedSprite; 67 PivotInspectorPanel m_InspectorPanel; 68 int m_SlideHashCode = "PivotTool_Slider1D".GetHashCode(); 69 readonly Rect k_PivotNormalizedRect = Rect.MinMaxRect(0, 0, 1, 1); 70 Rect m_PivotRect = Rect.zero; 71 72 static bool CanSelectWhileInPivotTool() => false; 73 74 public override void Initialize(LayoutOverlay layout) 75 { 76 base.Initialize(layout); 77 m_InspectorPanel = PivotInspectorPanel.CreateFromUxml(); 78 layout.rightOverlay.Add(m_InspectorPanel); 79 m_InspectorPanel.SetHiddenFromLayout(true); 80 m_InspectorPanel.pivotAlignment.RegisterValueChangedCallback(PivotAlignmentValueChange); 81 m_InspectorPanel.pivotPosition.RegisterValueChangedCallback(PivotPositionValueChange); 82 } 83 84 void PivotAlignmentValueChange(ChangeEvent<Enum> evt) 85 { 86 m_Pivot = GetPivotPoint((SpriteAlignment)m_InspectorPanel.pivotAlignment.value, m_Pivot); 87 m_InspectorPanel.pivotPosition.SetValueWithoutNotify(m_Pivot); 88 UpdateCharacterPivot(); 89 } 90 91 void PivotPositionValueChange(ChangeEvent<Vector2> evt) 92 { 93 m_Pivot = m_InspectorPanel.pivotPosition.value; 94 m_InspectorPanel.pivotAlignment.SetValueWithoutNotify(SpriteAlignment.Custom); 95 UpdateCharacterPivot(); 96 } 97 98 99 protected override void OnGUI() 100 { 101 base.OnGUI(); 102 var pivot = PivotSlider(m_PivotRect, m_Pivot, Styles.pivotdot, Styles.pivotdotactive); 103 if (m_Pivot != pivot) 104 { 105 UpdateViewFields(); 106 m_Pivot = pivot; 107 UpdateCharacterPivot(); 108 } 109 } 110 111 void UpdateCharacterPivot() 112 { 113 using (skinningCache.UndoScope(TextContent.pivotChanged)) 114 { 115 skinningCache.character.pivot = m_Pivot; 116 skinningCache.events.pivotChange.Invoke(); 117 } 118 } 119 120 protected override void OnActivate() 121 { 122 if (skinningCache.hasCharacter) 123 { 124 base.OnActivate(); 125 m_PivotRect = new Rect(0, 0, skinningCache.character.dimension.x, skinningCache.character.dimension.y); 126 m_LastSelectedSprite = skinningCache.selectedSprite; 127 m_InspectorPanel.SetHiddenFromLayout(false); 128 m_Pivot = skinningCache.character.pivot; 129 UpdateViewFields(); 130 131 skinningCache.selectionTool.CanSelect += CanSelectWhileInPivotTool; 132 skinningCache.selectedSprite = null; 133 } 134 else 135 { 136 m_InspectorPanel.SetHiddenFromLayout(true); 137 } 138 } 139 140 void UpdateViewFields() 141 { 142 SpriteAlignment alignment; 143 TranslatePivotPoint(m_Pivot, out alignment); 144 m_InspectorPanel.pivotAlignment.SetValueWithoutNotify(alignment); 145 m_InspectorPanel.pivotPosition.SetValueWithoutNotify(m_Pivot); 146 } 147 148 protected override void OnDeactivate() 149 { 150 if (skinningCache.hasCharacter) 151 { 152 base.OnDeactivate(); 153 m_InspectorPanel.SetHiddenFromLayout(true); 154 155 skinningCache.selectionTool.CanSelect -= CanSelectWhileInPivotTool; 156 if (isActive) 157 skinningCache.selectedSprite = m_LastSelectedSprite; 158 } 159 } 160 161 void TranslatePivotPoint(Vector2 pivot, out SpriteAlignment alignment) 162 { 163 if (new Vector2(k_PivotNormalizedRect.xMin, k_PivotNormalizedRect.yMax) == pivot) 164 alignment = SpriteAlignment.TopLeft; 165 else if (new Vector2(k_PivotNormalizedRect.center.x, k_PivotNormalizedRect.yMax) == pivot) 166 alignment = SpriteAlignment.TopCenter; 167 else if (new Vector2(k_PivotNormalizedRect.xMax, k_PivotNormalizedRect.yMax) == pivot) 168 alignment = SpriteAlignment.TopRight; 169 else if (new Vector2(k_PivotNormalizedRect.xMin, k_PivotNormalizedRect.center.y) == pivot) 170 alignment = SpriteAlignment.LeftCenter; 171 else if (new Vector2(k_PivotNormalizedRect.center.x, k_PivotNormalizedRect.center.y) == pivot) 172 alignment = SpriteAlignment.Center; 173 else if (new Vector2(k_PivotNormalizedRect.xMax, k_PivotNormalizedRect.center.y) == pivot) 174 alignment = SpriteAlignment.RightCenter; 175 else if (new Vector2(k_PivotNormalizedRect.xMin, k_PivotNormalizedRect.yMin) == pivot) 176 alignment = SpriteAlignment.BottomLeft; 177 else if (new Vector2(k_PivotNormalizedRect.center.x, k_PivotNormalizedRect.yMin) == pivot) 178 alignment = SpriteAlignment.BottomCenter; 179 else if (new Vector2(k_PivotNormalizedRect.xMax, k_PivotNormalizedRect.yMin) == pivot) 180 alignment = SpriteAlignment.BottomRight; 181 else 182 alignment = SpriteAlignment.Custom; 183 } 184 185 Vector2 GetPivotPoint(SpriteAlignment alignment, Vector2 customPivot) 186 { 187 switch (alignment) 188 { 189 case SpriteAlignment.TopLeft: 190 return new Vector2(k_PivotNormalizedRect.xMin, k_PivotNormalizedRect.yMax); 191 192 case SpriteAlignment.TopCenter: 193 return new Vector2(k_PivotNormalizedRect.center.x, k_PivotNormalizedRect.yMax); 194 195 case SpriteAlignment.TopRight: 196 return new Vector2(k_PivotNormalizedRect.xMax, k_PivotNormalizedRect.yMax); 197 198 case SpriteAlignment.LeftCenter: 199 return new Vector2(k_PivotNormalizedRect.xMin, k_PivotNormalizedRect.center.y); 200 201 case SpriteAlignment.Center: 202 return new Vector2(k_PivotNormalizedRect.center.x, k_PivotNormalizedRect.center.y); 203 204 case SpriteAlignment.RightCenter: 205 return new Vector2(k_PivotNormalizedRect.xMax, k_PivotNormalizedRect.center.y); 206 207 case SpriteAlignment.BottomLeft: 208 return new Vector2(k_PivotNormalizedRect.xMin, k_PivotNormalizedRect.yMin); 209 210 case SpriteAlignment.BottomCenter: 211 return new Vector2(k_PivotNormalizedRect.center.x, k_PivotNormalizedRect.yMin); 212 213 case SpriteAlignment.BottomRight: 214 return new Vector2(k_PivotNormalizedRect.xMax, k_PivotNormalizedRect.yMin); 215 216 case SpriteAlignment.Custom: 217 return new Vector2(customPivot.x * k_PivotNormalizedRect.width, customPivot.y * k_PivotNormalizedRect.height); 218 } 219 220 return Vector2.zero; 221 } 222 223 Vector2 PivotSlider(Rect sprite, Vector2 pos, GUIStyle pivotDot, GUIStyle pivotDotActive) 224 { 225 int id = GUIUtility.GetControlID(m_SlideHashCode, FocusType.Keyboard); 226 227 // Convert from normalized space to texture space 228 pos = new Vector2(sprite.xMin + sprite.width * pos.x, sprite.yMin + sprite.height * pos.y); 229 230 Vector2 screenVal = Handles.matrix.MultiplyPoint(pos); 231 232 Rect handleScreenPos = new Rect( 233 screenVal.x - pivotDot.fixedWidth * .5f, 234 screenVal.y - pivotDot.fixedHeight * .5f, 235 pivotDotActive.fixedWidth, 236 pivotDotActive.fixedHeight 237 ); 238 239 var evt = Event.current; 240 switch (evt.GetTypeForControl(id)) 241 { 242 case EventType.MouseDown: 243 // am I closest to the thingy? 244 if (evt.button == 0 && handleScreenPos.Contains(Event.current.mousePosition) && !evt.alt) 245 { 246 GUIUtility.hotControl = GUIUtility.keyboardControl = id; // Grab mouse focus 247 m_CurrentMousePosition = evt.mousePosition; 248 m_DragStartScreenPosition = evt.mousePosition; 249 Vector2 rectScreenCenter = Handles.matrix.MultiplyPoint(pos); 250 m_DragScreenOffset = m_CurrentMousePosition - rectScreenCenter; 251 evt.Use(); 252 EditorGUIUtility.SetWantsMouseJumping(1); 253 } 254 255 break; 256 case EventType.MouseDrag: 257 if (GUIUtility.hotControl == id) 258 { 259 m_CurrentMousePosition += evt.delta; 260 Vector2 oldPos = pos; 261 Vector3 scrPos = Handles.inverseMatrix.MultiplyPoint(m_CurrentMousePosition - m_DragScreenOffset); 262 pos = new Vector2(scrPos.x, scrPos.y); 263 if (!Mathf.Approximately((oldPos - pos).magnitude, 0f)) 264 GUI.changed = true; 265 evt.Use(); 266 } 267 268 break; 269 case EventType.MouseUp: 270 if (GUIUtility.hotControl == id && (evt.button == 0 || evt.button == 2)) 271 { 272 GUIUtility.hotControl = 0; 273 evt.Use(); 274 EditorGUIUtility.SetWantsMouseJumping(0); 275 } 276 277 break; 278 case EventType.KeyDown: 279 if (GUIUtility.hotControl == id) 280 { 281 if (evt.keyCode == KeyCode.Escape) 282 { 283 pos = Handles.inverseMatrix.MultiplyPoint(m_DragStartScreenPosition - m_DragScreenOffset); 284 GUIUtility.hotControl = 0; 285 GUI.changed = true; 286 evt.Use(); 287 } 288 } 289 290 break; 291 case EventType.Repaint: 292 EditorGUIUtility.AddCursorRect(handleScreenPos, MouseCursor.Arrow, id); 293 294 if (GUIUtility.hotControl == id) 295 pivotDotActive.Draw(handleScreenPos, GUIContent.none, id); 296 else 297 pivotDot.Draw(handleScreenPos, GUIContent.none, id); 298 299 break; 300 } 301 302 // Convert from texture space back to normalized space 303 pos = new Vector2((pos.x - sprite.xMin) / sprite.width, (pos.y - sprite.yMin) / sprite.height); 304 305 return pos; 306 } 307 } 308}