DragAndDropHandler.cs 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127
  1. // Animancer // https://kybernetik.com.au/animancer // Copyright 2018-2024 Kybernetik //
  2. #if UNITY_EDITOR
  3. using System;
  4. using System.Collections;
  5. using UnityEditor;
  6. using UnityEngine;
  7. namespace Animancer.Editor
  8. {
  9. /// <summary>[Editor-Only]
  10. /// Delegate for validating and responding to <see cref="DragAndDrop"/> operations.
  11. /// </summary>
  12. /// <remarks>
  13. ///
  14. /// <strong>Example:</strong>
  15. /// <code>
  16. /// private DragAndDropHandler&lt;AnimationClip&gt; _AnimationDropHandler;
  17. ///
  18. /// void OnGUI(Rect area)
  19. /// {
  20. /// _AnimationDropHandler ??= (clip, isDrop) =>
  21. /// {
  22. /// if (clip.legacy)// Reject legacy animations
  23. /// return false;
  24. ///
  25. /// if (isDrop)// Only act when dropping.
  26. /// Debug.Log(clip + " was dropped");
  27. ///
  28. /// return true;// Drag or drop is accepted.
  29. /// };
  30. ///
  31. /// _AnimationDropHandler.Handle(area);
  32. /// }
  33. /// </code></remarks>
  34. /// https://kybernetik.com.au/animancer/api/Animancer.Editor/DragAndDropHandler_1
  35. public delegate bool DragAndDropHandler<T>(
  36. T dragging,
  37. bool isDrop)
  38. where T : class;
  39. /// https://kybernetik.com.au/animancer/api/Animancer.Editor/AnimancerGUI
  40. public static partial class AnimancerGUI
  41. {
  42. /************************************************************************************************************************/
  43. /// <summary>Handles the current event.</summary>
  44. /// <remarks>See <see cref="DragAndDropHandler{T}"/> for a usage example.</remarks>
  45. public static bool Handle<T>(
  46. this DragAndDropHandler<T> handler,
  47. Rect area,
  48. DragAndDropVisualMode mode = DragAndDropVisualMode.Link)
  49. where T : class
  50. {
  51. var currentEvent = Event.current;
  52. bool isDrop;
  53. switch (currentEvent.type)
  54. {
  55. case EventType.DragUpdated:
  56. isDrop = false;
  57. break;
  58. case EventType.DragPerform:
  59. isDrop = true;
  60. break;
  61. default:
  62. return false;
  63. }
  64. if (!area.Contains(currentEvent.mousePosition))
  65. return false;
  66. return handler.Handle(DragAndDrop.objectReferences, isDrop, mode);
  67. }
  68. /************************************************************************************************************************/
  69. /// <summary>Handles the current event.</summary>
  70. /// <remarks>See <see cref="DragAndDropHandler{T}"/> for a usage example.</remarks>
  71. public static bool Handle<T>(
  72. this DragAndDropHandler<T> handler,
  73. IEnumerable dragging,
  74. bool isDrop,
  75. DragAndDropVisualMode mode = DragAndDropVisualMode.Link)
  76. where T : class
  77. {
  78. if (dragging == null)
  79. return false;
  80. var droppedAny = false;
  81. foreach (var obj in dragging)
  82. {
  83. if (obj is not T t ||
  84. !handler(t, isDrop))
  85. continue;
  86. Deselect();
  87. Event.current.Use();
  88. if (isDrop)
  89. {
  90. droppedAny = true;
  91. }
  92. else
  93. {
  94. DragAndDrop.visualMode = mode;
  95. return true;
  96. }
  97. }
  98. if (!droppedAny)
  99. return false;
  100. DragAndDrop.AcceptDrag();
  101. return true;
  102. }
  103. /************************************************************************************************************************/
  104. }
  105. }
  106. #endif