A game about forced loneliness, made by TACStudios
1using System;
2using System.Collections.Generic;
3using UnityEngine.UIElements;
4using UnityEngine;
5
6namespace UnityEditor.U2D.Sprites
7{
8 internal abstract partial class SpriteFrameModuleBase : SpriteEditorModuleModeSupportBase
9 {
10 protected enum GizmoMode
11 {
12 BorderEditing,
13 RectEditing
14 }
15
16 protected class Styles
17 {
18 public readonly GUIStyle dragdot = "U2D.dragDot";
19 public readonly GUIStyle dragdotactive = "U2D.dragDotActive";
20 public readonly GUIStyle createRect = "U2D.createRect";
21 public readonly GUIStyle pivotdotactive = "U2D.pivotDotActive";
22 public readonly GUIStyle pivotdot = "U2D.pivotDot";
23
24 public readonly GUIStyle dragBorderdot = new GUIStyle();
25 public readonly GUIStyle dragBorderDotActive = new GUIStyle();
26
27 public readonly GUIStyle toolbar;
28
29 public Styles()
30 {
31 toolbar = new GUIStyle(EditorStyles.inspectorBig);
32 toolbar.margin.top = 0;
33 toolbar.margin.bottom = 0;
34 createRect.border = new RectOffset(3, 3, 3, 3);
35
36 dragBorderdot.fixedHeight = 5f;
37 dragBorderdot.fixedWidth = 5f;
38 dragBorderdot.normal.background = EditorGUIUtility.whiteTexture;
39
40 dragBorderDotActive.fixedHeight = dragBorderdot.fixedHeight;
41 dragBorderDotActive.fixedWidth = dragBorderdot.fixedWidth;
42 dragBorderDotActive.normal.background = EditorGUIUtility.whiteTexture;
43 }
44 }
45
46 private static Styles s_Styles;
47
48 protected static Styles styles
49 {
50 get
51 {
52 if (s_Styles == null)
53 s_Styles = new Styles();
54 return s_Styles;
55 }
56 }
57
58 private const float kInspectorWidth = 330f;
59 private const float kInspectorHeight = 170;
60 private const float kPivotFieldPrecision = 0.0001f;
61 private float m_Zoom = 1.0f;
62 private GizmoMode m_GizmoMode;
63
64 private VisualElement m_NameElement;
65 private TextField m_NameField;
66 private VisualElement m_PositionElement;
67 private IntegerField m_PositionFieldX;
68 private IntegerField m_PositionFieldY;
69 private IntegerField m_PositionFieldW;
70 private IntegerField m_PositionFieldH;
71 private IntegerField m_BorderFieldL;
72 private IntegerField m_BorderFieldT;
73 private IntegerField m_BorderFieldR;
74 private IntegerField m_BorderFieldB;
75 private EnumField m_PivotField;
76 private EnumField m_PivotUnitModeField;
77 private VisualElement m_CustomPivotElement;
78 private FloatField m_CustomPivotFieldX;
79 private FloatField m_CustomPivotFieldY;
80 private VisualElement m_SelectedFrameInspector;
81 bool m_EnableInspector = true;
82
83 private bool ShouldShowRectScaling()
84 {
85 return hasSelected && m_GizmoMode == GizmoMode.RectEditing;
86 }
87
88 private static Rect inspectorRect
89 {
90 get
91 {
92 return new Rect(
93 0, 0,
94 kInspectorWidth,
95 kInspectorHeight);
96 }
97 }
98
99 private void RemoveMainUI(VisualElement mainView)
100 {
101 if (mainView.Contains(m_SelectedFrameInspector))
102 mainView.Remove(m_SelectedFrameInspector);
103 mainView.UnregisterCallback<SpriteSelectionChangeEvent>(SelectionChange);
104 }
105
106 protected void UpdatePositionField(FocusOutEvent evt)
107 {
108 if (hasSelected)
109 {
110 m_PositionFieldX.SetValueWithoutNotify((int)selectedSpriteRect_Rect.x);
111 m_PositionFieldY.SetValueWithoutNotify((int)selectedSpriteRect_Rect.y);
112 m_PositionFieldW.SetValueWithoutNotify((int)selectedSpriteRect_Rect.width);
113 m_PositionFieldH.SetValueWithoutNotify((int)selectedSpriteRect_Rect.height);
114 }
115 }
116
117 private void UpdateBorderField(FocusOutEvent evt)
118 {
119 if (hasSelected)
120 {
121 m_BorderFieldL.SetValueWithoutNotify((int)selectedSpriteBorder.x);
122 m_BorderFieldB.SetValueWithoutNotify((int)selectedSpriteBorder.y);
123 m_BorderFieldR.SetValueWithoutNotify((int)selectedSpriteBorder.z);
124 m_BorderFieldT.SetValueWithoutNotify((int)selectedSpriteBorder.w);
125 }
126 }
127
128 void SetupIntegerField(IntegerField field, EventCallback<FocusOutEvent> onFocusOutEvent, EventCallback<ChangeEvent<int>> onChangeEvent)
129 {
130 field.RegisterCallback(onFocusOutEvent);
131 field.RegisterValueChangedCallback(onChangeEvent);
132 }
133
134 void SetDragFieldLimit(IntegerField field, int value)
135 {
136 // The only way to know if value change is due to dragger or text input
137 var t = field.Q("unity-text-input");
138 if (!t.focusController.IsFocused(t))
139 {
140 // Value changed due to drag. We set back the field so to show the drag limit
141 field.SetValueWithoutNotify(value);
142 }
143 }
144
145 void OnPositionIntXChange(ChangeEvent<int> evt)
146 {
147 if (hasSelected)
148 {
149 var rect = selectedSpriteRect_Rect;
150 rect.x = evt.newValue;
151 selectedSpriteRect_Rect = rect;
152 SetDragFieldLimit(m_PositionFieldX, (int)selectedSpriteRect_Rect.x);
153 m_PositionFieldW.SetValueWithoutNotify((int)selectedSpriteRect_Rect.width);
154 }
155 }
156
157 void OnPositionIntYChange(ChangeEvent<int> evt)
158 {
159 if (hasSelected)
160 {
161 var rect = selectedSpriteRect_Rect;
162 rect.y = evt.newValue;
163 selectedSpriteRect_Rect = rect;
164 SetDragFieldLimit(m_PositionFieldY, (int)selectedSpriteRect_Rect.y);
165 m_PositionFieldH.SetValueWithoutNotify((int)selectedSpriteRect_Rect.height);
166 }
167 }
168
169 void OnPositionIntWChange(ChangeEvent<int> evt)
170 {
171 if (hasSelected)
172 {
173 var rect = selectedSpriteRect_Rect;
174 rect.width = evt.newValue;
175 selectedSpriteRect_Rect = rect;
176 SetDragFieldLimit(m_PositionFieldW, (int)selectedSpriteRect_Rect.width);
177 m_PositionFieldX.SetValueWithoutNotify((int)selectedSpriteRect_Rect.x);
178 }
179 }
180
181 void OnPositionIntHChange(ChangeEvent<int> evt)
182 {
183 if (hasSelected)
184 {
185 var rect = selectedSpriteRect_Rect;
186 rect.height = evt.newValue;
187 selectedSpriteRect_Rect = rect;
188 SetDragFieldLimit(m_PositionFieldH, (int)selectedSpriteRect_Rect.height);
189 m_PositionFieldY.SetValueWithoutNotify((int)selectedSpriteRect_Rect.y);
190 }
191 }
192
193 void OnBorderIntLChange(ChangeEvent<int> evt)
194 {
195 if (hasSelected)
196 {
197 var border = selectedSpriteBorder;
198 border.x = evt.newValue;
199 selectedSpriteBorder = border;
200 SetDragFieldLimit(m_BorderFieldL, (int)selectedSpriteBorder.x);
201 }
202 }
203
204 void OnBorderIntBChange(ChangeEvent<int> evt)
205 {
206 if (hasSelected)
207 {
208 var border = selectedSpriteBorder;
209 border.y = evt.newValue;
210 selectedSpriteBorder = border;
211 SetDragFieldLimit(m_BorderFieldB, (int)selectedSpriteBorder.y);
212 }
213 }
214
215 void OnBorderIntRChange(ChangeEvent<int> evt)
216 {
217 if (hasSelected)
218 {
219 var border = selectedSpriteBorder;
220 border.z = (evt.newValue + border.x) <= selectedSpriteRect_Rect.width ? evt.newValue : selectedSpriteRect_Rect.width - border.x;
221 selectedSpriteBorder = border;
222 SetDragFieldLimit(m_BorderFieldR, (int)selectedSpriteBorder.z);
223 }
224 }
225
226 void OnBorderIntTChange(ChangeEvent<int> evt)
227 {
228 if (hasSelected)
229 {
230 var border = selectedSpriteBorder;
231 border.w = (evt.newValue + border.y) <= selectedSpriteRect_Rect.height ? evt.newValue : selectedSpriteRect_Rect.height - border.y;
232 selectedSpriteBorder = border;
233 SetDragFieldLimit(m_BorderFieldT, (int)selectedSpriteBorder.w);
234 }
235 }
236
237 private void AddMainUI(VisualElement mainView)
238 {
239 var visualTree = AssetDatabase.LoadAssetAtPath<VisualTreeAsset>("Packages/com.unity.2d.sprite/Editor/UI/SpriteEditor/SpriteFrameModuleInspector.uxml") as VisualTreeAsset;
240 m_SelectedFrameInspector = visualTree.CloneTree().Q("spriteFrameModuleInspector");
241
242 m_NameElement = m_SelectedFrameInspector.Q("name");
243 m_NameField = m_SelectedFrameInspector.Q<TextField>("spriteName");
244 m_NameField.RegisterValueChangedCallback((evt) =>
245 {
246 if (hasSelected)
247 {
248 selectedSpriteName = evt.newValue;
249 }
250 });
251
252 m_NameField.RegisterCallback<FocusOutEvent>((focus) =>
253 {
254 if (hasSelected)
255 {
256 m_NameField.SetValueWithoutNotify(selectedSpriteName);
257 }
258 });
259
260
261 m_PositionElement = m_SelectedFrameInspector.Q("position");
262 m_PositionFieldX = m_PositionElement.Q<IntegerField>("positionX");
263 SetupIntegerField(m_PositionFieldX, UpdatePositionField, OnPositionIntXChange);
264
265 m_PositionFieldY = m_PositionElement.Q<IntegerField>("positionY");
266 SetupIntegerField(m_PositionFieldY, UpdatePositionField, OnPositionIntYChange);
267
268 m_PositionFieldW = m_PositionElement.Q<IntegerField>("positionW");
269 SetupIntegerField(m_PositionFieldW, UpdatePositionField, OnPositionIntWChange);
270
271 m_PositionFieldH = m_PositionElement.Q<IntegerField>("positionH");
272 SetupIntegerField(m_PositionFieldH, UpdatePositionField, OnPositionIntHChange);
273
274 var borderElement = m_SelectedFrameInspector.Q("border");
275 m_BorderFieldL = borderElement.Q<IntegerField>("borderL");
276 SetupIntegerField(m_BorderFieldL, UpdateBorderField, OnBorderIntLChange);
277
278 m_BorderFieldT = borderElement.Q<IntegerField>("borderT");
279 SetupIntegerField(m_BorderFieldT, UpdateBorderField, OnBorderIntTChange);
280
281 m_BorderFieldR = borderElement.Q<IntegerField>("borderR");
282 SetupIntegerField(m_BorderFieldR, UpdateBorderField, OnBorderIntRChange);
283
284 m_BorderFieldB = borderElement.Q<IntegerField>("borderB");
285 SetupIntegerField(m_BorderFieldB, UpdateBorderField, OnBorderIntBChange);
286
287 m_PivotField = m_SelectedFrameInspector.Q<EnumField>("pivotField");
288 m_PivotField.Init(SpriteAlignment.Center);
289 m_PivotField.label = L10n.Tr("Pivot");
290 m_PivotField.RegisterValueChangedCallback((evt) =>
291 {
292 if (hasSelected)
293 {
294 SpriteAlignment alignment = (SpriteAlignment)evt.newValue;
295 SetSpritePivotAndAlignment(selectedSpritePivot, alignment);
296 m_CustomPivotElement.SetEnabled(selectedSpriteAlignment == SpriteAlignment.Custom);
297 Vector2 pivot = selectedSpritePivotInCurUnitMode;
298 m_CustomPivotFieldX.SetValueWithoutNotify(pivot.x);
299 m_CustomPivotFieldY.SetValueWithoutNotify(pivot.y);
300 }
301 });
302
303
304 m_PivotUnitModeField = m_SelectedFrameInspector.Q<EnumField>("pivotUnitModeField");
305 m_PivotUnitModeField.Init(PivotUnitMode.Normalized);
306 m_PivotUnitModeField.label = L10n.Tr("Pivot Unit Mode");
307 m_PivotUnitModeField.RegisterValueChangedCallback((evt) =>
308 {
309 if (hasSelected)
310 {
311 pivotUnitMode = (PivotUnitMode)evt.newValue;
312
313 Vector2 pivot = selectedSpritePivotInCurUnitMode;
314 m_CustomPivotFieldX.SetValueWithoutNotify(pivot.x);
315 m_CustomPivotFieldY.SetValueWithoutNotify(pivot.y);
316 }
317 });
318
319
320 m_CustomPivotElement = m_SelectedFrameInspector.Q("customPivot");
321 m_CustomPivotFieldX = m_CustomPivotElement.Q<FloatField>("customPivotX");
322 m_CustomPivotFieldX.RegisterValueChangedCallback((evt) =>
323 {
324 if (hasSelected)
325 {
326 float newValue = (float)evt.newValue;
327 float pivotX = pivotUnitMode == PivotUnitMode.Pixels
328 ? ConvertFromRectToNormalizedSpace(new Vector2(newValue, 0.0f), selectedSpriteRect_Rect).x
329 : newValue;
330
331 var pivot = selectedSpritePivot;
332 pivot.x = pivotX;
333 SetSpritePivotAndAlignment(pivot, selectedSpriteAlignment);
334 }
335 });
336
337 m_CustomPivotFieldY = m_CustomPivotElement.Q<FloatField>("customPivotY");
338 m_CustomPivotFieldY.RegisterValueChangedCallback((evt) =>
339 {
340 if (hasSelected)
341 {
342 float newValue = (float)evt.newValue;
343 float pivotY = pivotUnitMode == PivotUnitMode.Pixels
344 ? ConvertFromRectToNormalizedSpace(new Vector2(0.0f, newValue), selectedSpriteRect_Rect).y
345 : newValue;
346
347 var pivot = selectedSpritePivot;
348 pivot.y = pivotY;
349 SetSpritePivotAndAlignment(pivot, selectedSpriteAlignment);
350 }
351 });
352
353 //// Force an update of all the fields.
354 PopulateSpriteFrameInspectorField();
355
356 mainView.RegisterCallback<SpriteSelectionChangeEvent>(SelectionChange);
357
358 // Stop mouse events from reaching the main view.
359 m_SelectedFrameInspector.pickingMode = PickingMode.Ignore;
360 m_SelectedFrameInspector.RegisterCallback<MouseDownEvent>((e) => { e.StopPropagation(); });
361 m_SelectedFrameInspector.RegisterCallback<MouseUpEvent>((e) => { e.StopPropagation(); });
362 m_SelectedFrameInspector.AddToClassList("moduleWindow");
363 m_SelectedFrameInspector.AddToClassList("bottomRightFloating");
364 mainView.Add(m_SelectedFrameInspector);
365 }
366
367 protected void EnableInspector(bool value)
368 {
369 m_EnableInspector = value;
370 SelectionChange(new SpriteSelectionChangeEvent());
371 }
372
373 private void SelectionChange(SpriteSelectionChangeEvent evt)
374 {
375 m_SelectedFrameInspector.style.display = hasSelected && m_EnableInspector ? DisplayStyle.Flex : DisplayStyle.None;
376 PopulateSpriteFrameInspectorField();
377 }
378
379 private void UIUndoCallback()
380 {
381 PopulateSpriteFrameInspectorField();
382 }
383
384 protected void PopulateSpriteFrameInspectorField()
385 {
386 m_SelectedFrameInspector.style.display = hasSelected && m_EnableInspector ? DisplayStyle.Flex : DisplayStyle.None;
387 if (!hasSelected)
388 return;
389 m_NameElement.SetEnabled(containsMultipleSprites);
390 m_NameField.SetValueWithoutNotify(selectedSpriteName);
391 m_PositionElement.SetEnabled(containsMultipleSprites);
392 var spriteRect = selectedSpriteRect_Rect;
393 m_PositionFieldX.SetValueWithoutNotify(Mathf.RoundToInt(spriteRect.x));
394 m_PositionFieldY.SetValueWithoutNotify(Mathf.RoundToInt(spriteRect.y));
395 m_PositionFieldW.SetValueWithoutNotify(Mathf.RoundToInt(spriteRect.width));
396 m_PositionFieldH.SetValueWithoutNotify(Mathf.RoundToInt(spriteRect.height));
397 var spriteBorder = selectedSpriteBorder;
398 m_BorderFieldL.SetValueWithoutNotify(Mathf.RoundToInt(spriteBorder.x));
399 m_BorderFieldT.SetValueWithoutNotify(Mathf.RoundToInt(spriteBorder.w));
400 m_BorderFieldR.SetValueWithoutNotify(Mathf.RoundToInt(spriteBorder.z));
401 m_BorderFieldB.SetValueWithoutNotify(Mathf.RoundToInt(spriteBorder.y));
402 m_PivotField.SetValueWithoutNotify(selectedSpriteAlignment);
403 m_PivotUnitModeField.SetValueWithoutNotify(pivotUnitMode);
404 Vector2 pivot = selectedSpritePivotInCurUnitMode;
405 m_CustomPivotFieldX.SetValueWithoutNotify(pivot.x);
406 m_CustomPivotFieldY.SetValueWithoutNotify(pivot.y);
407
408 m_CustomPivotElement.SetEnabled(hasSelected && selectedSpriteAlignment == SpriteAlignment.Custom);
409 }
410
411 private static Vector2 ApplySpriteAlignmentToPivot(Vector2 pivot, Rect rect, SpriteAlignment alignment)
412 {
413 if (alignment != SpriteAlignment.Custom)
414 {
415 Vector2[] snapPoints = GetSnapPointsArray(rect);
416 Vector2 texturePos = snapPoints[(int)alignment];
417 return ConvertFromTextureToNormalizedSpace(texturePos, rect);
418 }
419 return pivot;
420 }
421
422 private static Vector2 ConvertFromTextureToNormalizedSpace(Vector2 texturePos, Rect rect)
423 {
424 return new Vector2((texturePos.x - rect.xMin) / rect.width, (texturePos.y - rect.yMin) / rect.height);
425 }
426
427 private static Vector2 ConvertFromNormalizedToRectSpace(Vector2 normalizedPos, Rect rect)
428 {
429 Vector2 rectPos = new Vector2(rect.width * normalizedPos.x, rect.height * normalizedPos.y);
430
431 // This is to combat the lack of precision formating on the UI controls.
432 rectPos.x = Mathf.Round(rectPos.x / kPivotFieldPrecision) * kPivotFieldPrecision;
433 rectPos.y = Mathf.Round(rectPos.y / kPivotFieldPrecision) * kPivotFieldPrecision;
434
435 return rectPos;
436 }
437
438 private static Vector2 ConvertFromRectToNormalizedSpace(Vector2 rectPos, Rect rect)
439 {
440 return new Vector2(rectPos.x / rect.width, rectPos.y / rect.height);
441 }
442
443 private static Vector2[] GetSnapPointsArray(Rect rect)
444 {
445 Vector2[] snapPoints = new Vector2[9];
446 snapPoints[(int)SpriteAlignment.TopLeft] = new Vector2(rect.xMin, rect.yMax);
447 snapPoints[(int)SpriteAlignment.TopCenter] = new Vector2(rect.center.x, rect.yMax);
448 snapPoints[(int)SpriteAlignment.TopRight] = new Vector2(rect.xMax, rect.yMax);
449 snapPoints[(int)SpriteAlignment.LeftCenter] = new Vector2(rect.xMin, rect.center.y);
450 snapPoints[(int)SpriteAlignment.Center] = new Vector2(rect.center.x, rect.center.y);
451 snapPoints[(int)SpriteAlignment.RightCenter] = new Vector2(rect.xMax, rect.center.y);
452 snapPoints[(int)SpriteAlignment.BottomLeft] = new Vector2(rect.xMin, rect.yMin);
453 snapPoints[(int)SpriteAlignment.BottomCenter] = new Vector2(rect.center.x, rect.yMin);
454 snapPoints[(int)SpriteAlignment.BottomRight] = new Vector2(rect.xMax, rect.yMin);
455 return snapPoints;
456 }
457
458 protected void Repaint()
459 {
460 spriteEditor.RequestRepaint();
461 }
462
463 protected void HandleGizmoMode()
464 {
465 GizmoMode oldGizmoMode = m_GizmoMode;
466 var evt = eventSystem.current;
467 if (evt.control)
468 m_GizmoMode = GizmoMode.BorderEditing;
469 else
470 m_GizmoMode = GizmoMode.RectEditing;
471
472 if (oldGizmoMode != m_GizmoMode && (evt.type == EventType.KeyDown || evt.type == EventType.KeyUp) && (evt.keyCode == KeyCode.LeftControl || evt.keyCode == KeyCode.RightControl || evt.keyCode == KeyCode.LeftAlt || evt.keyCode == KeyCode.RightAlt))
473 Repaint();
474 }
475
476 protected bool MouseOnTopOfInspector()
477 {
478 if (hasSelected == false)
479 return false;
480
481 var point = GUIClip.Unclip(eventSystem.current.mousePosition);
482 point = m_SelectedFrameInspector.parent.LocalToWorld(point);
483
484 var selectedElement = m_SelectedFrameInspector.panel.Pick(point);
485 if (selectedElement != null
486 && selectedElement.pickingMode != PickingMode.Ignore
487 && selectedElement.FindCommonAncestor(m_SelectedFrameInspector) == m_SelectedFrameInspector)
488 return true;
489
490 return false;
491 }
492
493 protected void HandlePivotHandle()
494 {
495 if (!hasSelected)
496 return;
497
498 EditorGUI.BeginChangeCheck();
499
500 SpriteAlignment alignment = selectedSpriteAlignment;
501 Vector2 pivot = selectedSpritePivot;
502 Rect rect = selectedSpriteRect_Rect;
503 pivot = ApplySpriteAlignmentToPivot(pivot, rect, alignment);
504 Vector2 pivotHandlePosition = SpriteEditorHandles.PivotSlider(rect, pivot, styles.pivotdot, styles.pivotdotactive);
505
506 if (EditorGUI.EndChangeCheck())
507 {
508 // Pivot snapping only happen when ctrl is press. Same as scene view snapping move
509 if (eventSystem.current.control)
510 SnapPivotToSnapPoints(pivotHandlePosition, out pivot, out alignment);
511 else if (pivotUnitMode == PivotUnitMode.Pixels)
512 SnapPivotToPixels(pivotHandlePosition, out pivot, out alignment);
513 else
514 {
515 pivot = pivotHandlePosition;
516 alignment = SpriteAlignment.Custom;
517 }
518 SetSpritePivotAndAlignment(pivot, alignment);
519 PopulateSpriteFrameInspectorField();
520 }
521 }
522
523 protected void HandleBorderSidePointScalingSliders()
524 {
525 if (!hasSelected)
526 return;
527
528 GUIStyle dragDot = styles.dragBorderdot;
529 GUIStyle dragDotActive = styles.dragBorderDotActive;
530 var color = new Color(0f, 1f, 0f);
531
532 Rect rect = selectedSpriteRect_Rect;
533 Vector4 border = selectedSpriteBorder;
534
535 float left = rect.xMin + border.x;
536 float right = rect.xMax - border.z;
537 float top = rect.yMax - border.w;
538 float bottom = rect.yMin + border.y;
539
540 EditorGUI.BeginChangeCheck();
541
542 float horizontal = bottom - (bottom - top) / 2;
543 float vertical = left - (left - right) / 2;
544
545 float center = horizontal;
546 HandleBorderPointSlider(ref left, ref center, MouseCursor.ResizeHorizontal, false, dragDot, dragDotActive, color);
547
548 center = horizontal;
549 HandleBorderPointSlider(ref right, ref center, MouseCursor.ResizeHorizontal, false, dragDot, dragDotActive, color);
550
551 center = vertical;
552 HandleBorderPointSlider(ref center, ref top, MouseCursor.ResizeVertical, false, dragDot, dragDotActive, color);
553
554 center = vertical;
555 HandleBorderPointSlider(ref center, ref bottom, MouseCursor.ResizeVertical, false, dragDot, dragDotActive, color);
556
557 if (EditorGUI.EndChangeCheck())
558 {
559 border.x = left - rect.xMin;
560 border.z = rect.xMax - right;
561 border.w = rect.yMax - top;
562 border.y = bottom - rect.yMin;
563 selectedSpriteBorder = border;
564 PopulateSpriteFrameInspectorField();
565 }
566 }
567
568 protected void HandleBorderCornerScalingHandles()
569 {
570 if (!hasSelected)
571 return;
572
573 GUIStyle dragDot = styles.dragBorderdot;
574 GUIStyle dragDotActive = styles.dragBorderDotActive;
575 var color = new Color(0f, 1f, 0f);
576
577 Rect rect = selectedSpriteRect_Rect;
578 Vector4 border = selectedSpriteBorder;
579
580 float left = rect.xMin + border.x;
581 float right = rect.xMax - border.z;
582 float top = rect.yMax - border.w;
583 float bottom = rect.yMin + border.y;
584
585 EditorGUI.BeginChangeCheck();
586
587 // Handle corner points, but hide them if border values are below 1
588 HandleBorderPointSlider(ref left, ref top, MouseCursor.ResizeUpLeft, border.x < 1 && border.w < 1, dragDot, dragDotActive, color);
589 HandleBorderPointSlider(ref right, ref top, MouseCursor.ResizeUpRight, border.z < 1 && border.w < 1, dragDot, dragDotActive, color);
590 HandleBorderPointSlider(ref left, ref bottom, MouseCursor.ResizeUpRight, border.x < 1 && border.y < 1, dragDot, dragDotActive, color);
591 HandleBorderPointSlider(ref right, ref bottom, MouseCursor.ResizeUpLeft, border.z < 1 && border.y < 1, dragDot, dragDotActive, color);
592
593 if (EditorGUI.EndChangeCheck())
594 {
595 border.x = left - rect.xMin;
596 border.z = rect.xMax - right;
597 border.w = rect.yMax - top;
598 border.y = bottom - rect.yMin;
599 selectedSpriteBorder = border;
600 PopulateSpriteFrameInspectorField();
601 }
602 }
603
604 protected void HandleBorderSideScalingHandles()
605 {
606 if (hasSelected == false)
607 return;
608
609 Rect rect = new Rect(selectedSpriteRect_Rect);
610 Vector4 border = selectedSpriteBorder;
611
612 float left = rect.xMin + border.x;
613 float right = rect.xMax - border.z;
614 float top = rect.yMax - border.w;
615 float bottom = rect.yMin + border.y;
616
617 Vector2 screenRectTopLeft = Handles.matrix.MultiplyPoint(new Vector3(rect.xMin, rect.yMin));
618 Vector2 screenRectBottomRight = Handles.matrix.MultiplyPoint(new Vector3(rect.xMax, rect.yMax));
619
620 float screenRectWidth = Mathf.Abs(screenRectBottomRight.x - screenRectTopLeft.x);
621 float screenRectHeight = Mathf.Abs(screenRectBottomRight.y - screenRectTopLeft.y);
622
623 EditorGUI.BeginChangeCheck();
624
625 left = HandleBorderScaleSlider(left, rect.yMax, screenRectWidth, screenRectHeight, true);
626 right = HandleBorderScaleSlider(right, rect.yMax, screenRectWidth, screenRectHeight, true);
627
628 top = HandleBorderScaleSlider(rect.xMin, top, screenRectWidth, screenRectHeight, false);
629 bottom = HandleBorderScaleSlider(rect.xMin, bottom, screenRectWidth, screenRectHeight, false);
630
631 if (EditorGUI.EndChangeCheck())
632 {
633 border.x = left - rect.xMin;
634 border.z = rect.xMax - right;
635 border.w = rect.yMax - top;
636 border.y = bottom - rect.yMin;
637
638 selectedSpriteBorder = border;
639 PopulateSpriteFrameInspectorField();
640 }
641 }
642
643 protected void HandleBorderPointSlider(ref float x, ref float y, MouseCursor mouseCursor, bool isHidden, GUIStyle dragDot, GUIStyle dragDotActive, Color color)
644 {
645 var originalColor = GUI.color;
646
647 if (isHidden)
648 GUI.color = new Color(0, 0, 0, 0);
649 else
650 GUI.color = color;
651
652 Vector2 point = SpriteEditorHandles.PointSlider(new Vector2(x, y), mouseCursor, dragDot, dragDotActive);
653 x = point.x;
654 y = point.y;
655
656 GUI.color = originalColor;
657 }
658
659 protected float HandleBorderScaleSlider(float x, float y, float width, float height, bool isHorizontal)
660 {
661 float handleSize = styles.dragBorderdot.fixedWidth;
662 Vector2 point = Handles.matrix.MultiplyPoint(new Vector2(x, y));
663 float result;
664
665 EditorGUI.BeginChangeCheck();
666
667 if (isHorizontal)
668 {
669 Rect newRect = new Rect(point.x - handleSize * .5f, point.y, handleSize, height);
670 result = SpriteEditorHandles.ScaleSlider(point, MouseCursor.ResizeHorizontal, newRect).x;
671 }
672 else
673 {
674 Rect newRect = new Rect(point.x, point.y - handleSize * .5f, width, handleSize);
675 result = SpriteEditorHandles.ScaleSlider(point, MouseCursor.ResizeVertical, newRect).y;
676 }
677
678 if (EditorGUI.EndChangeCheck())
679 return result;
680
681 return isHorizontal ? x : y;
682 }
683
684 protected void DrawSpriteRectGizmos()
685 {
686 if (eventSystem.current.type != EventType.Repaint)
687 return;
688
689 SpriteEditorUtility.BeginLines(new Color(0f, 1f, 0f, 0.7f));
690 var selectedGUID = selected != null ? selected.spriteID : new GUID();
691 for (int i = 0; i < spriteCount; i++)
692 {
693 Vector4 border = GetSpriteBorderAt(i);
694 if (m_GizmoMode != GizmoMode.BorderEditing && (m_RectsCache != null && m_RectsCache.spriteRects[i].spriteID != selectedGUID))
695 {
696 // border does not contain negative values
697 if (border.sqrMagnitude < Mathf.Epsilon * 8)
698 continue;
699 }
700
701 var rect = GetSpriteRectAt(i);
702 SpriteEditorUtility.DrawLine(new Vector3(rect.xMin + border.x, rect.yMin), new Vector3(rect.xMin + border.x, rect.yMax));
703 SpriteEditorUtility.DrawLine(new Vector3(rect.xMax - border.z, rect.yMin), new Vector3(rect.xMax - border.z, rect.yMax));
704
705 SpriteEditorUtility.DrawLine(new Vector3(rect.xMin, rect.yMin + border.y), new Vector3(rect.xMax, rect.yMin + border.y));
706 SpriteEditorUtility.DrawLine(new Vector3(rect.xMin, rect.yMax - border.w), new Vector3(rect.xMax, rect.yMax - border.w));
707 }
708 SpriteEditorUtility.EndLines();
709
710 if (ShouldShowRectScaling())
711 {
712 Rect r = selectedSpriteRect_Rect;
713 SpriteEditorUtility.BeginLines(new Color(0f, 0.1f, 0.3f, 0.25f));
714 SpriteEditorUtility.DrawBox(new Rect(r.xMin + 1f / m_Zoom, r.yMin + 1f / m_Zoom, r.width, r.height));
715 SpriteEditorUtility.EndLines();
716 SpriteEditorUtility.BeginLines(new Color(0.25f, 0.5f, 1f, 0.75f));
717 SpriteEditorUtility.DrawBox(r);
718 SpriteEditorUtility.EndLines();
719 }
720 }
721
722 protected void DrawRectGizmos(IEnumerable<Rect> rects, Color color)
723 {
724 if (eventSystem.current.type != EventType.Repaint)
725 return;
726
727 SpriteEditorUtility.BeginLines(color);
728 foreach (var rect in rects)
729 {
730 SpriteEditorUtility.DrawLine(new Vector3(rect.xMin, rect.yMin), new Vector3(rect.xMin, rect.yMax));
731 SpriteEditorUtility.DrawLine(new Vector3(rect.xMax, rect.yMin), new Vector3(rect.xMax, rect.yMax));
732
733 SpriteEditorUtility.DrawLine(new Vector3(rect.xMin, rect.yMin), new Vector3(rect.xMax, rect.yMin));
734 SpriteEditorUtility.DrawLine(new Vector3(rect.xMin, rect.yMax), new Vector3(rect.xMax, rect.yMax));
735 }
736 SpriteEditorUtility.EndLines();
737 }
738
739 // implements ISpriteEditorModule
740
741 public override void DoMainGUI()
742 {
743 m_Zoom = Handles.matrix.GetColumn(0).magnitude;
744 }
745
746 public override void DoPostGUI()
747 {
748 }
749 }
750}