VisibilityTool.cs 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442
  1. using System;
  2. using UnityEngine.U2D.Common;
  3. using UnityEditor.U2D.Layout;
  4. using System.Collections.Generic;
  5. using UnityEngine;
  6. using UnityEngine.UIElements;
  7. namespace UnityEditor.U2D.Animation
  8. {
  9. internal class VisibilityToolWindow : VisualElement, IVisibilityToolWindow
  10. {
  11. public class CustomUxmlFactory : UxmlFactory<VisibilityToolWindow, UxmlTraits> {}
  12. VisualElement m_SelectorContainer;
  13. VisualElement m_Container;
  14. Slider m_BoneOpacitySlider;
  15. Slider m_MeshOpacitySlider;
  16. private LayoutOverlay m_Layout;
  17. List<Button> m_Tabs;
  18. int m_CurrentSelectedTab = 0;
  19. public event Action<float> onBoneOpacitySliderChange = (f) => {};
  20. public event Action<float> onMeshOpacitySliderChange = (f) => {};
  21. public event Action onBoneOpacitySliderChangeBegin = () => {};
  22. public event Action onBoneOpacitySliderChangeEnd = () => {};
  23. public event Action onMeshOpacitySliderChangeBegin = () => {};
  24. public event Action onMeshOpacitySliderChangeEnd = () => {};
  25. public static VisibilityToolWindow CreateFromUXML()
  26. {
  27. var visualTree = ResourceLoader.Load<VisualTreeAsset>("SkinningModule/VisibilityToolWindow.uxml");
  28. var ve = visualTree.CloneTree().Q("VisibilityToolWindow") as VisibilityToolWindow;
  29. var resizer = ve.Q("Resizer");
  30. resizer.AddManipulator(new VisibilityToolResizer());
  31. ve.styleSheets.Add(ResourceLoader.Load<StyleSheet>("SkinningModule/VisibilityTool.uss"));
  32. if (EditorGUIUtility.isProSkin)
  33. ve.AddToClassList("Dark");
  34. ve.BindElements();
  35. return ve;
  36. }
  37. public void BindElements()
  38. {
  39. m_SelectorContainer = this.Q("VisibilityToolSelection");
  40. m_Container = this.Q("VisibilityToolContainer");
  41. m_BoneOpacitySlider = this.Q<Slider>("BoneOpacitySlider");
  42. m_BoneOpacitySlider.RegisterValueChangedCallback(OnBoneOpacitySliderValueChangd);
  43. m_MeshOpacitySlider = this.Q<Slider>("MeshOpacitySlider");
  44. m_MeshOpacitySlider.RegisterValueChangedCallback(OnMeshOpacitySliderValueChangd);
  45. RegisterCallback<MouseDownEvent>(OpacityChangeBegin, TrickleDown.TrickleDown);
  46. RegisterCallback<MouseCaptureOutEvent>(OpacityChangeEnd, TrickleDown.TrickleDown);
  47. // case 1200857 StopPropagation when bubbling up so that main IMGUI doesn't get the event
  48. RegisterCallback<MouseDownEvent>(evt => evt.StopPropagation());
  49. m_Tabs = new List<Button>();
  50. m_SelectorContainer.Clear();
  51. }
  52. public void Initialize(LayoutOverlay layout)
  53. {
  54. m_Layout = layout;
  55. layout.rightOverlay.Add(this);
  56. Hide();
  57. }
  58. public void Show()
  59. {
  60. m_Container.Clear();
  61. this.SetHiddenFromLayout(false);
  62. m_Layout.VisibilityWindowOn(true);
  63. }
  64. public void Hide()
  65. {
  66. m_Container.Clear();
  67. this.SetHiddenFromLayout(true);
  68. m_Layout.VisibilityWindowOn(false);
  69. }
  70. bool IsOpacityTarget(IEventHandler target, VisualElement opacityTarget)
  71. {
  72. var ve = target as VisualElement;
  73. while (ve != null && ve != this)
  74. {
  75. if (ve == opacityTarget)
  76. return true;
  77. ve = ve.parent;
  78. }
  79. return false;
  80. }
  81. void OpacityChangeBegin(MouseDownEvent evt)
  82. {
  83. if (IsOpacityTarget(evt.target, m_BoneOpacitySlider))
  84. onBoneOpacitySliderChangeBegin();
  85. else if (IsOpacityTarget(evt.target, m_MeshOpacitySlider))
  86. onMeshOpacitySliderChangeBegin();
  87. }
  88. void OpacityChangeEnd(MouseCaptureOutEvent evt)
  89. {
  90. if (IsOpacityTarget(evt.target, m_BoneOpacitySlider))
  91. onBoneOpacitySliderChangeEnd();
  92. else if (IsOpacityTarget(evt.target, m_MeshOpacitySlider))
  93. onMeshOpacitySliderChangeEnd();
  94. }
  95. void OnBoneOpacitySliderValueChangd(ChangeEvent<float> evt)
  96. {
  97. onBoneOpacitySliderChange(evt.newValue);
  98. }
  99. void OnMeshOpacitySliderValueChangd(ChangeEvent<float> evt)
  100. {
  101. onMeshOpacitySliderChange(evt.newValue);
  102. }
  103. public void SetBoneOpacitySliderValue(float value)
  104. {
  105. m_BoneOpacitySlider.value = value;
  106. m_BoneOpacitySlider.MarkDirtyRepaint();
  107. }
  108. public void SetMeshOpacitySliderValue(float value)
  109. {
  110. m_MeshOpacitySlider.value = value;
  111. m_MeshOpacitySlider.MarkDirtyRepaint();
  112. }
  113. public void AddToolTab(string name, Action onClick)
  114. {
  115. var tab = new Button()
  116. {
  117. text = name
  118. };
  119. tab.AddToClassList("visibilityToolTab");
  120. if (EditorGUIUtility.isProSkin)
  121. tab.AddToClassList("visibilityToolTabDark");
  122. m_SelectorContainer.Add(tab);
  123. m_Tabs.Add(tab);
  124. tab.clickable.clicked += onClick;
  125. }
  126. public void SetActiveTab(int toolIndex)
  127. {
  128. if (m_Tabs.Count > toolIndex && toolIndex >= 0)
  129. {
  130. m_Tabs[m_CurrentSelectedTab].SetChecked(false);
  131. m_Tabs[toolIndex].SetChecked(true);
  132. m_CurrentSelectedTab = toolIndex;
  133. }
  134. }
  135. public void SetContent(VisualElement content)
  136. {
  137. m_Container.Clear();
  138. m_Container.Add(content);
  139. }
  140. public void SetToolAvailable(int toolIndex, bool available)
  141. {
  142. if (m_Tabs.Count > toolIndex && toolIndex >= 0)
  143. {
  144. m_Tabs[toolIndex].SetHiddenFromLayout(!available);
  145. if (available == false && toolIndex == m_CurrentSelectedTab)
  146. m_Container.Clear();
  147. }
  148. }
  149. }
  150. internal class VisibilityTool : BaseTool, IVisibilityToolModel
  151. {
  152. private VisibilityToolWindow m_ToolView;
  153. private MeshPreviewBehaviour m_MeshPreviewBehaviour = new MeshPreviewBehaviour();
  154. public SkeletonTool skeletonTool { set; private get; }
  155. VisibilityToolController m_Controller;
  156. internal override void OnCreate()
  157. {
  158. m_ToolView = VisibilityToolWindow.CreateFromUXML();
  159. m_Controller = new VisibilityToolController(this, new IVisibilityTool[]
  160. {
  161. new BoneVisibilityTool(skinningCache),
  162. new SpriteVisibilityTool(skinningCache)
  163. },
  164. () => skeletonTool,
  165. () => previewBehaviour);
  166. }
  167. public override IMeshPreviewBehaviour previewBehaviour
  168. {
  169. get { return m_MeshPreviewBehaviour; }
  170. }
  171. public override void Initialize(LayoutOverlay layout)
  172. {
  173. m_ToolView.Initialize(layout);
  174. }
  175. protected override void OnGUI()
  176. {
  177. skeletonTool.skeletonStyle = SkeletonStyles.WeightMap;
  178. skeletonTool.mode = SkeletonMode.EditPose;
  179. skeletonTool.editBindPose = false;
  180. skeletonTool.DoGUI();
  181. }
  182. protected override void OnActivate()
  183. {
  184. m_MeshPreviewBehaviour.showWeightMap = true;
  185. m_Controller.Activate();
  186. }
  187. protected override void OnDeactivate()
  188. {
  189. m_Controller.Deactivate();
  190. }
  191. int IVisibilityToolModel.currentToolIndex
  192. {
  193. get
  194. {
  195. return skinningCache.visibililtyToolIndex;
  196. }
  197. set
  198. {
  199. skinningCache.visibililtyToolIndex = value;
  200. }
  201. }
  202. float IVisibilityToolModel.boneOpacityValue
  203. {
  204. get
  205. {
  206. return VisibilityToolSettings.boneOpacity;
  207. }
  208. set
  209. {
  210. VisibilityToolSettings.boneOpacity = value;
  211. }
  212. }
  213. float IVisibilityToolModel.meshOpacityValue
  214. {
  215. get
  216. {
  217. return VisibilityToolSettings.meshOpacity;
  218. }
  219. set
  220. {
  221. VisibilityToolSettings.meshOpacity = value;
  222. }
  223. }
  224. UndoScope IVisibilityToolModel.UndoScope(string value)
  225. {
  226. return skinningCache.UndoScope(value);
  227. }
  228. void IVisibilityToolModel.BeginUndoOperation(string value)
  229. {
  230. skinningCache.BeginUndoOperation(value);
  231. }
  232. IVisibilityToolWindow IVisibilityToolModel.view { get { return m_ToolView;} }
  233. SkinningCache IVisibilityToolModel.skinningCache { get { return skinningCache;} }
  234. }
  235. internal interface IVisibilityToolModel
  236. {
  237. int currentToolIndex { get; set; }
  238. float meshOpacityValue { get; set; }
  239. float boneOpacityValue { get; set; }
  240. UndoScope UndoScope(string value);
  241. void BeginUndoOperation(string value);
  242. IVisibilityToolWindow view { get; }
  243. SkinningCache skinningCache { get; }
  244. }
  245. internal interface IVisibilityToolWindow
  246. {
  247. void AddToolTab(string name, Action callback);
  248. void SetToolAvailable(int i, bool available);
  249. void SetBoneOpacitySliderValue(float value);
  250. void SetMeshOpacitySliderValue(float value);
  251. event Action<float> onBoneOpacitySliderChange;
  252. event Action<float> onMeshOpacitySliderChange;
  253. event Action onBoneOpacitySliderChangeBegin;
  254. event Action onBoneOpacitySliderChangeEnd;
  255. event Action onMeshOpacitySliderChangeBegin;
  256. event Action onMeshOpacitySliderChangeEnd;
  257. void Show();
  258. void Hide();
  259. void SetActiveTab(int index);
  260. void SetContent(VisualElement content);
  261. }
  262. internal class VisibilityToolController
  263. {
  264. IVisibilityTool[] m_Tools;
  265. IVisibilityToolModel m_Model;
  266. Func<SkeletonTool> m_SkeletonTool;
  267. Func<IMeshPreviewBehaviour> m_MeshPreviewBehaviour;
  268. bool m_DeactivateBoneaTool = false;
  269. private IVisibilityTool currentTool
  270. {
  271. get { return m_Model.currentToolIndex == -1 ? null : m_Tools[m_Model.currentToolIndex]; }
  272. set { m_Model.currentToolIndex = value == null ? -1 : Array.FindIndex(m_Tools, x => x == value); }
  273. }
  274. private IVisibilityTool defaultTool
  275. {
  276. get { return Array.Find(m_Tools, t => t.isAvailable); }
  277. }
  278. public VisibilityToolController(IVisibilityToolModel model, IVisibilityTool[] tools, Func<SkeletonTool> skeletonTool = null, Func<IMeshPreviewBehaviour> meshPreviewBehaviour = null)
  279. {
  280. m_Model = model;
  281. m_Tools = tools;
  282. for (int i = 0; i < m_Tools.Length; ++i)
  283. {
  284. int index = i;
  285. var tool = m_Tools[i];
  286. tool.SetAvailabilityChangeCallback(() => OnToolAvailabilityChange(index));
  287. tool.Setup();
  288. model.view.AddToolTab(tool.name, () => ActivateToolWithUndo(tool));
  289. model.view.SetToolAvailable(i, tool.isAvailable);
  290. }
  291. m_SkeletonTool = skeletonTool;
  292. m_MeshPreviewBehaviour = meshPreviewBehaviour;
  293. }
  294. public void Activate()
  295. {
  296. m_Model.view.Show();
  297. if (currentTool == null)
  298. currentTool = defaultTool;
  299. ActivateTool(currentTool);
  300. m_Model.view.SetBoneOpacitySliderValue(m_Model.boneOpacityValue);
  301. m_Model.view.SetMeshOpacitySliderValue(m_Model.meshOpacityValue);
  302. m_Model.view.onBoneOpacitySliderChange -= OnBoneOpacityChange;
  303. m_Model.view.onMeshOpacitySliderChange -= OnMeshOpacityChange;
  304. m_Model.view.onBoneOpacitySliderChange += OnBoneOpacityChange;
  305. m_Model.view.onMeshOpacitySliderChange += OnMeshOpacityChange;
  306. m_Model.view.onBoneOpacitySliderChangeBegin -= OnBoneOpacityChangeBegin;
  307. m_Model.view.onBoneOpacitySliderChangeBegin += OnBoneOpacityChangeBegin;
  308. m_Model.view.onBoneOpacitySliderChangeEnd -= OnBoneOpacityChangeEnd;
  309. m_Model.view.onBoneOpacitySliderChangeEnd += OnBoneOpacityChangeEnd;
  310. m_Model.view.onMeshOpacitySliderChangeBegin -= OnMeshOpacityChangeBegin;
  311. m_Model.view.onMeshOpacitySliderChangeBegin += OnMeshOpacityChangeBegin;
  312. m_Model.view.onMeshOpacitySliderChangeEnd -= OnMeshOpacityChangeEnd;
  313. m_Model.view.onMeshOpacitySliderChangeEnd += OnMeshOpacityChangeEnd;
  314. }
  315. public void Deactivate()
  316. {
  317. m_Model.view.Hide();
  318. if (currentTool != null)
  319. currentTool.Deactivate();
  320. m_Model.view.onBoneOpacitySliderChange -= OnBoneOpacityChange;
  321. m_Model.view.onMeshOpacitySliderChange -= OnMeshOpacityChange;
  322. m_Model.view.onBoneOpacitySliderChangeBegin -= OnBoneOpacityChangeBegin;
  323. m_Model.view.onBoneOpacitySliderChangeEnd -= OnBoneOpacityChangeEnd;
  324. m_Model.view.onMeshOpacitySliderChangeBegin -= OnMeshOpacityChangeBegin;
  325. m_Model.view.onMeshOpacitySliderChangeEnd -= OnMeshOpacityChangeEnd;
  326. }
  327. void OnBoneOpacityChangeBegin()
  328. {
  329. if (m_SkeletonTool != null && m_SkeletonTool() != null && !m_SkeletonTool().isActive)
  330. {
  331. m_SkeletonTool().Activate();
  332. m_DeactivateBoneaTool = true;
  333. }
  334. }
  335. void OnBoneOpacityChangeEnd()
  336. {
  337. if (m_SkeletonTool != null && m_SkeletonTool() != null && m_SkeletonTool().isActive && m_DeactivateBoneaTool)
  338. m_SkeletonTool().Deactivate();
  339. }
  340. void OnMeshOpacityChangeBegin()
  341. {
  342. m_Model.skinningCache.events.meshPreviewBehaviourChange.Invoke(m_MeshPreviewBehaviour());
  343. }
  344. void OnMeshOpacityChangeEnd()
  345. {
  346. m_Model.skinningCache.events.meshPreviewBehaviourChange.Invoke(null);
  347. }
  348. private void OnBoneOpacityChange(float value)
  349. {
  350. m_Model.boneOpacityValue = value;
  351. }
  352. private void OnMeshOpacityChange(float value)
  353. {
  354. m_Model.meshOpacityValue = value;
  355. }
  356. private void OnToolAvailabilityChange(int toolIndex)
  357. {
  358. var toolChanged = m_Tools[toolIndex];
  359. m_Model.view.SetToolAvailable(toolIndex, toolChanged.isAvailable);
  360. if (toolChanged == currentTool && toolChanged.isAvailable == false)
  361. ActivateTool(defaultTool);
  362. }
  363. private void ActivateToolWithUndo(IVisibilityTool tool)
  364. {
  365. if (currentTool != tool && tool.isAvailable)
  366. {
  367. m_Model.BeginUndoOperation(TextContent.visibilityTab);
  368. ActivateTool(tool);
  369. }
  370. }
  371. private void ActivateTool(IVisibilityTool tool)
  372. {
  373. if (tool.isAvailable == false)
  374. return;
  375. if (currentTool != null)
  376. currentTool.Deactivate();
  377. currentTool = tool;
  378. currentTool.Activate();
  379. m_Model.view.SetActiveTab(m_Model.currentToolIndex);
  380. m_Model.view.SetContent(currentTool.view);
  381. }
  382. }
  383. }