Brak opisu
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.

TilePaletteBrushPickOverlay.cs 12KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350
  1. using System;
  2. using UnityEngine;
  3. using UnityEditor.Overlays;
  4. using UnityEditor.ShortcutManagement;
  5. using UnityEditor.Toolbars;
  6. using UnityEngine.UIElements;
  7. namespace UnityEditor.Tilemaps
  8. {
  9. [Overlay(typeof(SceneView), k_OverlayId, k_DisplayName
  10. , defaultDockZone = DockZone.RightColumn
  11. , defaultDockPosition = DockPosition.Bottom
  12. , defaultDockIndex = 1
  13. , defaultLayout = Layout.Panel
  14. , defaultWidth = k_DefaultWidth
  15. , defaultHeight = k_DefaultHeight)]
  16. internal class TilePaletteBrushPickOverlay : Overlay, ICreateHorizontalToolbar, ICreateVerticalToolbar, ITransientOverlay
  17. {
  18. public const string k_OverlayId = "Scene View/Tile Palette Brush Pick";
  19. internal const string k_DisplayName = "Tile Palette Brush Pick";
  20. internal readonly static string[] k_ElementIds = new[] { TilePaletteBrushPickButton.k_ToolbarId };
  21. private SceneView sceneView => containerWindow as SceneView;
  22. private bool m_DisplayAsPanel = false;
  23. private TilePaletteBrushPickElement m_BrushPickElement;
  24. public bool visible => GridPaintPaletteWindow.isActive && m_DisplayAsPanel;
  25. private const float k_DefaultWidth = 390;
  26. private const float k_DefaultHeight = 300;
  27. public TilePaletteBrushPickOverlay()
  28. {
  29. minSize = new Vector2(k_DefaultWidth, k_DefaultHeight);
  30. maxSize = new Vector2(k_DefaultWidth * 3, k_DefaultHeight * 3);
  31. collapsedIcon = EditorGUIUtility.LoadIcon(TilePaletteBrushPickToggle.k_IconPath);
  32. }
  33. public override void OnWillBeDestroyed()
  34. {
  35. if (m_BrushPickElement != null)
  36. {
  37. m_BrushPickElement.onBrushPicked -= TogglePopup;
  38. m_BrushPickElement = null;
  39. }
  40. base.OnWillBeDestroyed();
  41. }
  42. public void Hide()
  43. {
  44. m_DisplayAsPanel = false;
  45. }
  46. public void Show()
  47. {
  48. m_DisplayAsPanel = true;
  49. }
  50. public void TogglePopup()
  51. {
  52. m_DisplayAsPanel = !m_DisplayAsPanel;
  53. }
  54. public void TogglePopup(Vector2 mousePosition)
  55. {
  56. m_DisplayAsPanel = !m_DisplayAsPanel;
  57. if (m_DisplayAsPanel)
  58. MoveToMousePosition(mousePosition);
  59. }
  60. private void MoveToMousePosition(Vector2 mousePosition)
  61. {
  62. if (m_BrushPickElement == null)
  63. return;
  64. var width = m_BrushPickElement.rect.width;
  65. var height = m_BrushPickElement.rect.height;
  66. // Try to position middle on the panel on mouse position
  67. mousePosition.x -= width / 2;
  68. mousePosition.y -= height / 2;
  69. floatingPosition = mousePosition;
  70. }
  71. public void Repaint()
  72. {
  73. if (sceneView != null)
  74. sceneView.Repaint();
  75. }
  76. public override VisualElement CreatePanelContent()
  77. {
  78. m_BrushPickElement = new TilePaletteBrushPickElement();
  79. m_BrushPickElement.onBrushPicked += TogglePopup;
  80. return m_BrushPickElement;
  81. }
  82. public OverlayToolbar CreateHorizontalToolbarContent()
  83. {
  84. var content = EditorToolbar.CreateOverlay(k_ElementIds, containerWindow);
  85. return content;
  86. }
  87. public OverlayToolbar CreateVerticalToolbarContent()
  88. {
  89. var content = EditorToolbar.CreateOverlay(k_ElementIds, containerWindow);
  90. return content;
  91. }
  92. }
  93. [TilePaletteOverlayToolbarElement]
  94. [EditorToolbarElement(k_ToolbarId)]
  95. internal class TilePaletteBrushPickToggle : EditorToolbarToggle
  96. {
  97. internal const string k_ToolbarId = "Tile Palette/Brush Pick Toggle";
  98. private new static readonly string ussClassName = "unity-tilepalette-brushpick-toggle";
  99. internal static readonly string k_IconPath = "Packages/com.unity.2d.tilemap/Editor/Icons/Tilemap.BrushPicks.png";
  100. private static readonly string k_Tooltip = L10n.Tr("Toggles the visibility of the Tile Palette Brush Picks Overlay ({0})");
  101. private static readonly string k_ShortcutId = GridPaintPaletteWindow.ShortcutIds.k_ToggleSceneViewBrushPick;
  102. private SceneView m_SceneView;
  103. private TilePaletteBrushPickOverlay m_BrushPickOverlay;
  104. public TilePaletteBrushPickToggle()
  105. {
  106. AddToClassList(ussClassName);
  107. TilePaletteOverlayUtility.SetStyleSheet(this);
  108. RegisterCallback<AttachToPanelEvent>(OnAttachToPanel);
  109. RegisterCallback<DetachFromPanelEvent>(OnDetachFromPanel);
  110. icon = EditorGUIUtility.LoadIcon(k_IconPath);
  111. tooltip = GetTooltipText();
  112. }
  113. private TilePaletteBrushPickOverlay GetOverlayFromSceneView(SceneView sceneView)
  114. {
  115. if (sceneView == null)
  116. return null;
  117. if (sceneView.TryGetOverlay(TilePaletteBrushPickOverlay.k_OverlayId, out var overlay)
  118. && overlay is TilePaletteBrushPickOverlay brushPickOverlay)
  119. {
  120. return brushPickOverlay;
  121. }
  122. return null;
  123. }
  124. private static string GetTooltipText()
  125. {
  126. return String.Format(k_Tooltip, ShortcutIntegration.instance.GetKeyCombinationFor(k_ShortcutId));
  127. }
  128. private void OnAttachToPanel(AttachToPanelEvent evt)
  129. {
  130. SceneView.lastActiveSceneViewChanged += LastActiveSceneViewChanged;
  131. if (SceneView.lastActiveSceneView != null)
  132. {
  133. m_SceneView = SceneView.lastActiveSceneView;
  134. }
  135. else
  136. {
  137. if (SceneView.sceneViews.Count > 0)
  138. {
  139. m_SceneView = SceneView.sceneViews[0] as SceneView;
  140. }
  141. }
  142. ShortcutIntegration.instance.profileManager.shortcutBindingChanged += UpdateTooltips;
  143. UpdateBrushPickOverlay();
  144. }
  145. private void UpdateBrushPickOverlay()
  146. {
  147. m_BrushPickOverlay = GetOverlayFromSceneView(m_SceneView);
  148. if (m_BrushPickOverlay != null)
  149. {
  150. SetValueWithoutNotify(m_BrushPickOverlay.visible);
  151. m_BrushPickOverlay.displayedChanged += BrushPickOnDisplayChanged;
  152. }
  153. }
  154. private void LastActiveSceneViewChanged(SceneView oldSceneView, SceneView newSceneView)
  155. {
  156. if (m_BrushPickOverlay != null)
  157. {
  158. m_BrushPickOverlay.displayedChanged -= BrushPickOnDisplayChanged;
  159. }
  160. m_SceneView = newSceneView;
  161. UpdateBrushPickOverlay();
  162. }
  163. private void BrushPickOnDisplayChanged(bool _)
  164. {
  165. SetValueWithoutNotify(m_BrushPickOverlay.visible);
  166. }
  167. public override bool value
  168. {
  169. get => base.value;
  170. set
  171. {
  172. if (m_SceneView == null || m_BrushPickOverlay == null)
  173. return;
  174. if (value != base.value)
  175. {
  176. if (value)
  177. {
  178. m_BrushPickOverlay.Show();
  179. }
  180. else
  181. {
  182. m_BrushPickOverlay.Hide();
  183. }
  184. base.value = value;
  185. m_SceneView.RepaintImmediately();
  186. }
  187. }
  188. }
  189. public override void SetValueWithoutNotify(bool newValue)
  190. {
  191. // Force value to be tied to m_BrushSettingsOverlay.visible
  192. // As there is a bug where the arrow toggle affects the value
  193. base.SetValueWithoutNotify(m_BrushPickOverlay.visible);
  194. }
  195. private void OnDetachFromPanel(DetachFromPanelEvent evt)
  196. {
  197. if (m_BrushPickOverlay != null)
  198. {
  199. m_BrushPickOverlay.displayedChanged -= BrushPickOnDisplayChanged;
  200. }
  201. ShortcutIntegration.instance.profileManager.shortcutBindingChanged -= UpdateTooltips;
  202. SceneView.lastActiveSceneViewChanged -= LastActiveSceneViewChanged;
  203. }
  204. private void UpdateTooltips(IShortcutProfileManager obj, Identifier identifier, ShortcutBinding oldBinding, ShortcutBinding newBinding)
  205. {
  206. tooltip = GetTooltipText();
  207. }
  208. }
  209. [EditorToolbarElement(k_ToolbarId)]
  210. internal class TilePaletteBrushPickDropdownToggle : EditorToolbarDropdownToggle
  211. {
  212. internal const string k_ToolbarId = "Tile Palette/Brush Selection Dropdown Toggle";
  213. private new static readonly string ussClassName = "unity-tilepalettebrushPickdropdown-toggle";
  214. private static readonly string k_IconPath = "Packages/com.unity.2d.tilemap/Editor/Icons/Tilemap.BrushPicks.png";
  215. private static readonly string k_Tooltip = L10n.Tr("Toggles the visiblity of the Tile Palette Brush Selection Overlay");
  216. private SceneView m_SceneView;
  217. private TilePaletteBrushPickOverlay m_BrushPickOverlay;
  218. public TilePaletteBrushPickDropdownToggle()
  219. {
  220. AddToClassList(ussClassName);
  221. TilePaletteOverlayUtility.SetStyleSheet(this);
  222. RegisterCallback<AttachToPanelEvent>(OnAttachToPanel);
  223. RegisterCallback<DetachFromPanelEvent>(OnDetachFromPanel);
  224. icon = EditorGUIUtility.LoadIcon(k_IconPath);
  225. tooltip = k_Tooltip;
  226. dropdownClicked += ClickEvent;
  227. }
  228. private void OnAttachToPanel(AttachToPanelEvent evt)
  229. {
  230. foreach (var sceneViewObj in SceneView.sceneViews)
  231. {
  232. var sceneView = sceneViewObj as SceneView;
  233. if (sceneView == null)
  234. continue;
  235. var common = this.FindCommonAncestor(sceneView.rootVisualElement);
  236. if (common == null)
  237. continue;
  238. m_SceneView = sceneView;
  239. if (m_SceneView.TryGetOverlay(TilePaletteBrushPickOverlay.k_OverlayId, out var overlay)
  240. && overlay is TilePaletteBrushPickOverlay brushPickOverlay)
  241. {
  242. m_BrushPickOverlay = brushPickOverlay;
  243. SetValueWithoutNotify(m_BrushPickOverlay.visible);
  244. m_BrushPickOverlay.displayedChanged += BrushPickOnDisplayChanged;
  245. }
  246. break;
  247. }
  248. }
  249. private void BrushPickOnDisplayChanged(bool _)
  250. {
  251. SetValueWithoutNotify(m_BrushPickOverlay.visible);
  252. }
  253. public override bool value
  254. {
  255. get => base.value;
  256. set
  257. {
  258. if (value != base.value)
  259. {
  260. if (value)
  261. {
  262. m_BrushPickOverlay.Show();
  263. }
  264. else
  265. {
  266. m_BrushPickOverlay.Hide();
  267. }
  268. base.value = value;
  269. }
  270. }
  271. }
  272. public override void SetValueWithoutNotify(bool newValue)
  273. {
  274. // Force value to be tied to m_BrushSettingsOverlay.visible
  275. // As there is a bug where the arrow toggle affects the value
  276. base.SetValueWithoutNotify(m_BrushPickOverlay.visible);
  277. }
  278. private void ClickEvent()
  279. {
  280. BoolFieldOverlayPopupWindow.ShowOverlayPopup<TilePaletteBrushPickPanelPopup>(this, new Vector2(370, 260), false);
  281. }
  282. private void CloseEvent()
  283. {
  284. BoolFieldOverlayPopupWindow.CloseAllWindows<TilePaletteBrushPickPanelPopup>();
  285. }
  286. private void OnDetachFromPanel(DetachFromPanelEvent evt)
  287. {
  288. if (m_BrushPickOverlay != null)
  289. m_BrushPickOverlay.displayedChanged -= BrushPickOnDisplayChanged;
  290. CloseEvent();
  291. }
  292. }
  293. }