No Description
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

GridPaintTargetsDropdown.cs 13KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334
  1. using System;
  2. using UnityEditor.Experimental;
  3. using UnityEngine;
  4. namespace UnityEditor.Tilemaps
  5. {
  6. internal class GridPaintTargetsDropdown : PopupWindowContent
  7. {
  8. class Styles
  9. {
  10. public class IconState
  11. {
  12. public GUIContent visible;
  13. public GUIContent hidden;
  14. public GUIContent ping;
  15. }
  16. public GUIStyle menuItem = "MenuItem";
  17. public static readonly Color backgroundColor = EditorResources.GetStyle("game-object-tree-view-scene-visibility")
  18. .GetColor("background-color");
  19. public static readonly Color hoveredBackgroundColor = EditorResources.GetStyle("game-object-tree-view-scene-visibility")
  20. .GetColor("-unity-object-hovered-color");
  21. public static readonly Color selectedBackgroundColor = EditorResources.GetStyle("game-object-tree-view-scene-visibility")
  22. .GetColor("-unity-object-selected-color");
  23. public static readonly Color selectedNoFocusBackgroundColor = EditorResources.GetStyle("game-object-tree-view-scene-visibility")
  24. .GetColor("-unity-object-selected-no-focus-color");
  25. public static readonly GUIStyle sceneVisibilityStyle = "SceneVisibility";
  26. public static readonly IconState iconNormal = new()
  27. {
  28. visible = EditorGUIUtility.TrIconContent("scenevis_visible"),
  29. hidden = EditorGUIUtility.TrIconContent("scenevis_hidden"),
  30. ping = EditorGUIUtility.TrIconContent("Packages/com.unity.2d.tilemap/Editor/Icons/EditorUI.Target.png"),
  31. };
  32. public static readonly IconState iconHovered = new()
  33. {
  34. visible = EditorGUIUtility.TrIconContent("scenevis_visible_hover"),
  35. hidden = EditorGUIUtility.TrIconContent("scenevis_hidden_hover"),
  36. ping = EditorGUIUtility.TrIconContent("Packages/com.unity.2d.tilemap/Editor/Icons/EditorUI.TargetHover.png"),
  37. };
  38. public static Color GetItemBackgroundColor(bool isHovered, bool isSelected, bool isFocused)
  39. {
  40. if (isSelected)
  41. {
  42. if (isFocused)
  43. return selectedBackgroundColor;
  44. return selectedNoFocusBackgroundColor;
  45. }
  46. if (isHovered)
  47. return hoveredBackgroundColor;
  48. return backgroundColor;
  49. }
  50. }
  51. static Styles s_Styles;
  52. IFlexibleMenuItemProvider m_ItemProvider;
  53. FlexibleMenuModifyItemUI m_ModifyItemUI;
  54. readonly Action<int, object> m_ItemClickedCallback;
  55. Vector2 m_ScrollPosition = Vector2.zero;
  56. bool m_ShowAddNewPresetItem;
  57. int m_HoverIndex;
  58. int[] m_SeperatorIndices;
  59. float m_CachedWidth = -1f;
  60. float m_MinTextWidth;
  61. const float LineHeight = 18f;
  62. const float SeparatorHeight = 8f;
  63. int maxIndex { get { return m_ShowAddNewPresetItem ? m_ItemProvider.Count() : m_ItemProvider.Count() - 1; } }
  64. public int selectedIndex { get; set; }
  65. protected float minTextWidth { get { return m_MinTextWidth; } set { m_MinTextWidth = value; ClearCachedWidth(); } }
  66. internal class MenuItemProvider : IFlexibleMenuItemProvider
  67. {
  68. public int Count()
  69. {
  70. return GridPaintingState.validTargets != null ? GridPaintingState.validTargets.Length : 0;
  71. }
  72. public object GetItem(int index)
  73. {
  74. return GridPaintingState.validTargets != null ? GridPaintingState.validTargets[index] : GridPaintingState.scenePaintTarget;
  75. }
  76. public int Add(object obj)
  77. {
  78. throw new NotImplementedException();
  79. }
  80. public void Replace(int index, object newPresetObject)
  81. {
  82. throw new NotImplementedException();
  83. }
  84. public void Remove(int index)
  85. {
  86. throw new NotImplementedException();
  87. }
  88. public object Create()
  89. {
  90. throw new NotImplementedException();
  91. }
  92. public void Move(int index, int destIndex, bool insertAfterDestIndex)
  93. {
  94. throw new NotImplementedException();
  95. }
  96. public string GetName(int index)
  97. {
  98. return GridPaintingState.validTargets != null ? GridPaintingState.validTargets[index].name : GridPaintingState.scenePaintTarget.name;
  99. }
  100. public bool IsModificationAllowed(int index)
  101. {
  102. return false;
  103. }
  104. public int[] GetSeperatorIndices()
  105. {
  106. return new int[0];
  107. }
  108. }
  109. // itemClickedCallback arguments is clicked index, clicked item object
  110. public GridPaintTargetsDropdown(IFlexibleMenuItemProvider itemProvider, int selectionIndex, FlexibleMenuModifyItemUI modifyItemUi, Action<int, object> itemClickedCallback, float minWidth)
  111. {
  112. m_ItemProvider = itemProvider;
  113. m_ModifyItemUI = modifyItemUi;
  114. m_ItemClickedCallback = itemClickedCallback;
  115. m_SeperatorIndices = m_ItemProvider.GetSeperatorIndices();
  116. selectedIndex = selectionIndex;
  117. m_ShowAddNewPresetItem = m_ModifyItemUI != null;
  118. m_MinTextWidth = minWidth;
  119. }
  120. public override Vector2 GetWindowSize()
  121. {
  122. return CalcSize();
  123. }
  124. public override void OnGUI(Rect rect)
  125. {
  126. if (s_Styles == null)
  127. s_Styles = new Styles();
  128. Event evt = Event.current;
  129. Rect contentRect = new Rect(0, 0, 1, CalcSize().y);
  130. m_ScrollPosition = GUI.BeginScrollView(rect, m_ScrollPosition, contentRect);
  131. {
  132. float curY = 0f;
  133. for (int i = 0; i <= maxIndex; ++i)
  134. {
  135. int itemControlID = i + 1000000;
  136. Rect fullRect = new Rect(0, curY, rect.width, LineHeight);
  137. Rect visRect = new Rect(0, curY, 16, LineHeight);
  138. Rect pingRect = new Rect(16, curY, 16, LineHeight);
  139. Rect backRect = new Rect(0, curY, 32, LineHeight);
  140. Rect itemRect = new Rect(16 + 16, curY, rect.width - 16 - 16, LineHeight);
  141. bool addSeparator = Array.IndexOf(m_SeperatorIndices, i) >= 0;
  142. // Handle event
  143. switch (evt.type)
  144. {
  145. case EventType.Repaint:
  146. bool hover = false;
  147. if (m_HoverIndex == i)
  148. {
  149. if (fullRect.Contains(evt.mousePosition))
  150. hover = true;
  151. else
  152. m_HoverIndex = -1;
  153. }
  154. var isItemVisible = IsVisible(i);
  155. using (new GUI.BackgroundColorScope(Styles.GetItemBackgroundColor(hover, hover, hover)))
  156. {
  157. GUI.Label(backRect, GUIContent.none, GameObjectTreeViewGUI.GameObjectStyles.hoveredItemBackgroundStyle);
  158. }
  159. if (hover || !isItemVisible)
  160. {
  161. var isVisHover = visRect.Contains(evt.mousePosition);
  162. var visIconState = isVisHover
  163. ? Styles.iconHovered
  164. : Styles.iconNormal;
  165. var visIcon = isItemVisible ? visIconState.visible : visIconState.hidden;
  166. GUI.Button(visRect, visIcon, Styles.sceneVisibilityStyle);
  167. }
  168. if (hover)
  169. {
  170. var isPingHover = pingRect.Contains(evt.mousePosition);
  171. var pingIconState = isPingHover
  172. ? Styles.iconHovered
  173. : Styles.iconNormal;
  174. GUI.Button(pingRect, pingIconState.ping, Styles.sceneVisibilityStyle);
  175. }
  176. using (new EditorGUI.DisabledScope(!isItemVisible))
  177. s_Styles.menuItem.Draw(itemRect, GUIContent.Temp(m_ItemProvider.GetName(i)), hover, false, i == selectedIndex, false);
  178. break;
  179. case EventType.MouseDown:
  180. if (evt.button == 0 && visRect.Contains(evt.mousePosition))
  181. {
  182. GUIUtility.hotControl = itemControlID;
  183. if (evt.clickCount == 1)
  184. {
  185. GUIUtility.hotControl = 0;
  186. ToggleVisibility(i, !evt.alt);
  187. evt.Use();
  188. }
  189. }
  190. if (evt.button == 0 && pingRect.Contains(evt.mousePosition))
  191. {
  192. GUIUtility.hotControl = itemControlID;
  193. if (evt.clickCount == 1)
  194. {
  195. GUIUtility.hotControl = 0;
  196. PingItem(i);
  197. evt.Use();
  198. }
  199. }
  200. if (evt.button == 0 && itemRect.Contains(evt.mousePosition) && IsVisible(i))
  201. {
  202. GUIUtility.hotControl = itemControlID;
  203. if (evt.clickCount == 1)
  204. {
  205. GUIUtility.hotControl = 0;
  206. SelectItem(i);
  207. editorWindow.Close();
  208. evt.Use();
  209. }
  210. }
  211. break;
  212. case EventType.MouseUp:
  213. if (GUIUtility.hotControl == itemControlID)
  214. {
  215. GUIUtility.hotControl = 0;
  216. }
  217. break;
  218. case EventType.MouseMove:
  219. if (fullRect.Contains(evt.mousePosition))
  220. {
  221. m_HoverIndex = i;
  222. }
  223. else if (m_HoverIndex == i)
  224. {
  225. m_HoverIndex = -1;
  226. }
  227. Repaint();
  228. break;
  229. }
  230. curY += LineHeight;
  231. if (addSeparator)
  232. curY += SeparatorHeight;
  233. } // end foreach item
  234. } GUI.EndScrollView();
  235. }
  236. void SelectItem(int index)
  237. {
  238. selectedIndex = index;
  239. if (m_ItemClickedCallback != null && index >= 0)
  240. m_ItemClickedCallback(index, m_ItemProvider.GetItem(index));
  241. }
  242. bool IsVisible(int index)
  243. {
  244. var obj = m_ItemProvider.GetItem(index) as GameObject;
  245. if (obj != null)
  246. return !SceneVisibilityManager.instance.IsHidden(obj);
  247. return false;
  248. }
  249. void ToggleVisibility(int index, bool includeDescendants)
  250. {
  251. var obj = m_ItemProvider.GetItem(index) as GameObject;
  252. if (obj != null)
  253. SceneVisibilityManager.instance.ToggleVisibility(obj, includeDescendants);
  254. }
  255. void PingItem(int index)
  256. {
  257. var obj = m_ItemProvider.GetItem(index) as UnityEngine.Object;
  258. if (obj != null)
  259. EditorGUIUtility.PingObject(obj);
  260. }
  261. protected Vector2 CalcSize()
  262. {
  263. float height = (maxIndex + 1) * LineHeight + m_SeperatorIndices.Length * SeparatorHeight;
  264. if (m_CachedWidth < 0)
  265. m_CachedWidth = Math.Max(m_MinTextWidth, CalcWidth());
  266. return new Vector2(m_CachedWidth, height);
  267. }
  268. void ClearCachedWidth()
  269. {
  270. m_CachedWidth = -1f;
  271. }
  272. float CalcWidth()
  273. {
  274. if (s_Styles == null)
  275. s_Styles = new Styles();
  276. float maxWidth = 0;
  277. for (int i = 0; i < m_ItemProvider.Count(); ++i)
  278. {
  279. float w = s_Styles.menuItem.CalcSize(GUIContent.Temp(m_ItemProvider.GetName(i))).x;
  280. maxWidth = Mathf.Max(w, maxWidth);
  281. }
  282. const float rightMargin = 6f;
  283. return maxWidth + rightMargin;
  284. }
  285. void Repaint()
  286. {
  287. HandleUtility.Repaint(); // repaints current guiview (needs rename)
  288. }
  289. }
  290. }