Assignment for RMIT Mixed Reality in 2020
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.

451 lines
12 KiB

  1. // Amplify Shader Editor - Visual Shader Editing Tool
  2. // Copyright (c) Amplify Creations, Lda <info@amplify.pt>
  3. using UnityEngine;
  4. using UnityEditor;
  5. namespace AmplifyShaderEditor
  6. {
  7. public enum MenuAnchor
  8. {
  9. TOP_LEFT = 0,
  10. TOP_CENTER,
  11. TOP_RIGHT,
  12. MIDDLE_LEFT,
  13. MIDDLE_CENTER,
  14. MIDDLE_RIGHT,
  15. BOTTOM_LEFT,
  16. BOTTOM_CENTER,
  17. BOTTOM_RIGHT,
  18. NONE
  19. }
  20. public enum MenuAutoSize
  21. {
  22. MATCH_VERTICAL = 0,
  23. MATCH_HORIZONTAL,
  24. NONE
  25. }
  26. public class MenuParent
  27. {
  28. protected AmplifyShaderEditorWindow m_parentWindow = null;
  29. protected const float MinimizeButtonXSpacing = 5;
  30. protected const float MinimizeButtonYSpacing = 5.5f;
  31. protected const float ResizeAreaWidth = 5;
  32. protected const float MinimizeCollisionAdjust = 5;
  33. protected GUIStyle m_style;
  34. protected GUIContent m_content;
  35. protected Rect m_maximizedArea;
  36. protected Rect m_transformedArea;
  37. protected Rect m_resizeArea;
  38. protected MenuAnchor m_anchor;
  39. protected MenuAutoSize m_autoSize;
  40. protected bool m_isActive = true;
  41. protected bool m_isMaximized = true;
  42. protected bool m_lockOnMinimize = false;
  43. protected bool m_preLockState = false;
  44. protected Rect m_minimizedArea;
  45. protected Rect m_minimizeButtonPos;
  46. protected float m_realWidth;
  47. protected GUIStyle m_empty = new GUIStyle();
  48. protected float m_resizeDelta;
  49. protected bool m_isResizing = false;
  50. protected bool m_resizable = false;
  51. protected GUIStyle m_resizeAreaStyle;
  52. protected bool m_isMouseInside = false;
  53. protected Vector2 m_currentScrollPos;
  54. public MenuParent( AmplifyShaderEditorWindow parentWindow, float x, float y, float width, float height, string name, MenuAnchor anchor = MenuAnchor.NONE, MenuAutoSize autoSize = MenuAutoSize.NONE )
  55. {
  56. m_parentWindow = parentWindow;
  57. m_anchor = anchor;
  58. m_autoSize = autoSize;
  59. m_maximizedArea = new Rect( x, y, width, height );
  60. m_content = new GUIContent( GUIContent.none );
  61. m_content.text = name;
  62. m_transformedArea = new Rect();
  63. m_resizeArea = new Rect();
  64. m_resizeArea.width = ResizeAreaWidth;
  65. m_resizeAreaStyle = GUIStyle.none;
  66. m_currentScrollPos = Vector2.zero;
  67. }
  68. public void SetMinimizedArea( float x, float y, float width, float height )
  69. {
  70. m_minimizedArea = new Rect( x, y, width, height );
  71. }
  72. protected void InitDraw( Rect parentPosition, Vector2 mousePosition, int mouseButtonId )
  73. {
  74. if ( m_style == null )
  75. {
  76. m_style = new GUIStyle( UIUtils.TextArea );
  77. #if UNITY_2019_3_OR_NEWER
  78. m_style.normal.background = m_style.normal.scaledBackgrounds[ 0 ];
  79. m_style.normal.scaledBackgrounds = null;
  80. m_style.border = new RectOffset( 4, 4, 4, 4 );
  81. #endif
  82. m_style.stretchHeight = true;
  83. m_style.stretchWidth = true;
  84. m_style.fontSize = ( int ) Constants.DefaultTitleFontSize;
  85. m_style.fontStyle = FontStyle.Normal;
  86. Texture minimizeTex = UIUtils.GetCustomStyle( CustomStyle.MaximizeButton ).normal.background;
  87. m_minimizeButtonPos = new Rect( 0, 0, minimizeTex.width, minimizeTex.height );
  88. }
  89. Rect currentArea = m_isMaximized ? m_maximizedArea : m_minimizedArea;
  90. if ( m_isMaximized )
  91. {
  92. if ( m_resizable )
  93. {
  94. if ( m_isResizing )
  95. {
  96. if ( m_anchor == MenuAnchor.TOP_LEFT )
  97. m_resizeDelta = ( ParentWindow.CurrentEvent.mousePosition.x - m_maximizedArea.width );
  98. else if ( m_anchor == MenuAnchor.TOP_RIGHT )
  99. m_resizeDelta = ParentWindow.CurrentEvent.mousePosition.x - ( parentPosition.width - m_maximizedArea.width);
  100. }
  101. }
  102. m_realWidth = m_maximizedArea.width;
  103. if ( m_resizable )
  104. {
  105. if ( m_anchor == MenuAnchor.TOP_LEFT )
  106. {
  107. currentArea.width += m_resizeDelta;
  108. m_realWidth += m_resizeDelta;
  109. }
  110. else if ( m_anchor == MenuAnchor.TOP_RIGHT )
  111. {
  112. currentArea.width -= m_resizeDelta;
  113. m_realWidth -= m_resizeDelta;
  114. }
  115. }
  116. }
  117. else
  118. {
  119. if ( currentArea.x < 0 )
  120. {
  121. m_realWidth = currentArea.width + currentArea.x;
  122. }
  123. else if ( ( currentArea.x + currentArea.width ) > parentPosition.width )
  124. {
  125. m_realWidth = parentPosition.width - currentArea.x;
  126. }
  127. if ( m_realWidth < 0 )
  128. m_realWidth = 0;
  129. }
  130. switch ( m_anchor )
  131. {
  132. case MenuAnchor.TOP_LEFT:
  133. {
  134. m_transformedArea.x = currentArea.x;
  135. m_transformedArea.y = currentArea.y;
  136. if ( m_isMaximized )
  137. {
  138. m_minimizeButtonPos.x = m_transformedArea.x + m_transformedArea.width - m_minimizeButtonPos.width - MinimizeButtonXSpacing;
  139. m_minimizeButtonPos.y = m_transformedArea.y + MinimizeButtonYSpacing;
  140. m_resizeArea.x = m_transformedArea.x + m_transformedArea.width;
  141. m_resizeArea.y = m_minimizeButtonPos.y;
  142. m_resizeArea.height = m_transformedArea.height;
  143. }
  144. else
  145. {
  146. float width = ( m_transformedArea.width - m_transformedArea.x );
  147. m_minimizeButtonPos.x = m_transformedArea.x + width * 0.5f - m_minimizeButtonPos.width * 0.5f;
  148. m_minimizeButtonPos.y = m_transformedArea.height * 0.5f - m_minimizeButtonPos.height * 0.5f;
  149. }
  150. }
  151. break;
  152. case MenuAnchor.TOP_CENTER:
  153. {
  154. m_transformedArea.x = parentPosition.width * 0.5f + currentArea.x;
  155. m_transformedArea.y = currentArea.y;
  156. }
  157. break;
  158. case MenuAnchor.TOP_RIGHT:
  159. {
  160. m_transformedArea.x = parentPosition.width - currentArea.x - currentArea.width;
  161. m_transformedArea.y = currentArea.y;
  162. if ( m_isMaximized )
  163. {
  164. m_minimizeButtonPos.x = m_transformedArea.x + MinimizeButtonXSpacing;
  165. m_minimizeButtonPos.y = m_transformedArea.y + MinimizeButtonYSpacing;
  166. m_resizeArea.x = m_transformedArea.x - ResizeAreaWidth;
  167. m_resizeArea.y = m_minimizeButtonPos.y;
  168. m_resizeArea.height = m_transformedArea.height;
  169. }
  170. else
  171. {
  172. float width = ( parentPosition.width - m_transformedArea.x );
  173. m_minimizeButtonPos.x = m_transformedArea.x + width * 0.5f - m_minimizeButtonPos.width * 0.5f;
  174. m_minimizeButtonPos.y = m_transformedArea.height * 0.5f - m_minimizeButtonPos.height * 0.5f;
  175. }
  176. }
  177. break;
  178. case MenuAnchor.MIDDLE_LEFT:
  179. {
  180. m_transformedArea.x = currentArea.x;
  181. m_transformedArea.y = parentPosition.height * 0.5f + currentArea.y;
  182. }
  183. break;
  184. case MenuAnchor.MIDDLE_CENTER:
  185. {
  186. m_transformedArea.x = parentPosition.width * 0.5f + currentArea.x;
  187. m_transformedArea.y = parentPosition.height * 0.5f + currentArea.y;
  188. }
  189. break;
  190. case MenuAnchor.MIDDLE_RIGHT:
  191. {
  192. m_transformedArea.x = parentPosition.width - currentArea.x - currentArea.width;
  193. m_transformedArea.y = parentPosition.height * 0.5f + currentArea.y;
  194. }
  195. break;
  196. case MenuAnchor.BOTTOM_LEFT:
  197. {
  198. m_transformedArea.x = currentArea.x;
  199. m_transformedArea.y = parentPosition.height - currentArea.y - currentArea.height;
  200. }
  201. break;
  202. case MenuAnchor.BOTTOM_CENTER:
  203. {
  204. m_transformedArea.x = parentPosition.width * 0.5f + currentArea.x;
  205. m_transformedArea.y = parentPosition.height - currentArea.y - currentArea.height;
  206. }
  207. break;
  208. case MenuAnchor.BOTTOM_RIGHT:
  209. {
  210. m_transformedArea.x = parentPosition.width - currentArea.x - currentArea.width;
  211. m_transformedArea.y = parentPosition.height - currentArea.y - currentArea.height;
  212. }
  213. break;
  214. case MenuAnchor.NONE:
  215. {
  216. m_transformedArea.x = currentArea.x;
  217. m_transformedArea.y = currentArea.y;
  218. }
  219. break;
  220. }
  221. switch ( m_autoSize )
  222. {
  223. case MenuAutoSize.MATCH_HORIZONTAL:
  224. {
  225. m_transformedArea.width = parentPosition.width - m_transformedArea.x;
  226. m_transformedArea.height = currentArea.height;
  227. }
  228. break;
  229. case MenuAutoSize.MATCH_VERTICAL:
  230. {
  231. m_transformedArea.width = currentArea.width;
  232. m_transformedArea.height = parentPosition.height - m_transformedArea.y;
  233. }
  234. break;
  235. case MenuAutoSize.NONE:
  236. {
  237. m_transformedArea.width = currentArea.width;
  238. m_transformedArea.height = currentArea.height;
  239. }
  240. break;
  241. }
  242. }
  243. public virtual void Draw( Rect parentPosition, Vector2 mousePosition, int mouseButtonId, bool hasKeyboadFocus )
  244. {
  245. InitDraw( parentPosition, mousePosition, mouseButtonId );
  246. if ( ParentWindow.CurrentEvent.type == EventType.MouseDrag && ParentWindow.CurrentEvent.button > 0 /*catches both middle and right mouse button*/ )
  247. {
  248. m_isMouseInside = IsInside( mousePosition );
  249. if ( m_isMouseInside )
  250. {
  251. m_currentScrollPos.x += Constants.MenuDragSpeed * ParentWindow.CurrentEvent.delta.x;
  252. if ( m_currentScrollPos.x < 0 )
  253. m_currentScrollPos.x = 0;
  254. m_currentScrollPos.y += Constants.MenuDragSpeed * ParentWindow.CurrentEvent.delta.y;
  255. if ( m_currentScrollPos.y < 0 )
  256. m_currentScrollPos.y = 0;
  257. }
  258. }
  259. }
  260. public void PostDraw()
  261. {
  262. if ( !m_isMaximized )
  263. {
  264. m_transformedArea.height = 35;
  265. GUI.Label( m_transformedArea, m_content, m_style );
  266. }
  267. Color colorBuffer = GUI.color;
  268. GUI.color = EditorGUIUtility.isProSkin ? Color.white : Color.black;
  269. bool guiEnabledBuffer = GUI.enabled;
  270. GUI.enabled = !m_lockOnMinimize;
  271. Rect buttonArea = m_minimizeButtonPos;
  272. buttonArea.x -= MinimizeCollisionAdjust;
  273. buttonArea.width += 2 * MinimizeCollisionAdjust;
  274. buttonArea.y -= MinimizeCollisionAdjust;
  275. buttonArea.height += 2 * MinimizeCollisionAdjust;
  276. if ( m_parentWindow.CameraDrawInfo.CurrentEventType == EventType.Repaint )
  277. GUI.Label( m_minimizeButtonPos, string.Empty, UIUtils.GetCustomStyle( m_isMaximized ? CustomStyle.MinimizeButton : CustomStyle.MaximizeButton ) );
  278. if( m_parentWindow.CameraDrawInfo.CurrentEventType == EventType.MouseDown && buttonArea.Contains( m_parentWindow.CameraDrawInfo.MousePosition ) )
  279. //if ( GUI.Button( buttonArea, string.Empty, m_empty ) )
  280. {
  281. m_isMaximized = !m_isMaximized;
  282. m_resizeDelta = 0;
  283. }
  284. if ( m_resizable && m_isMaximized )
  285. {
  286. EditorGUIUtility.AddCursorRect( m_resizeArea, MouseCursor.ResizeHorizontal );
  287. if ( !m_isResizing && GUI.RepeatButton( m_resizeArea, string.Empty, m_resizeAreaStyle ) )
  288. {
  289. m_isResizing = true;
  290. }
  291. else
  292. {
  293. if ( m_isResizing )
  294. {
  295. if ( ParentWindow.CurrentEvent.isMouse && ParentWindow.CurrentEvent.type != EventType.MouseDrag )
  296. {
  297. m_isResizing = false;
  298. }
  299. }
  300. }
  301. if ( m_realWidth < buttonArea.width )
  302. {
  303. // Auto-minimize
  304. m_isMaximized = false;
  305. m_resizeDelta = 0;
  306. m_isResizing = false;
  307. }
  308. else
  309. {
  310. float halfSizeWindow = 0.5f * ParentWindow.position.width;
  311. if ( m_realWidth > halfSizeWindow )
  312. {
  313. m_realWidth = 0.5f * ParentWindow.position.width;
  314. if ( m_resizeDelta > 0 )
  315. {
  316. m_resizeDelta = m_realWidth - m_maximizedArea.width;
  317. }
  318. else
  319. {
  320. m_resizeDelta = m_maximizedArea.width - m_realWidth;
  321. }
  322. }
  323. }
  324. }
  325. GUI.enabled = guiEnabledBuffer;
  326. GUI.color = colorBuffer;
  327. }
  328. public void OnLostFocus()
  329. {
  330. if ( m_isResizing )
  331. {
  332. m_isResizing = false;
  333. }
  334. }
  335. virtual public void Destroy()
  336. {
  337. m_empty = null;
  338. m_resizeAreaStyle = null;
  339. }
  340. public float InitialX
  341. {
  342. get { return m_maximizedArea.x; }
  343. set { m_maximizedArea.x = value; }
  344. }
  345. public float Width
  346. {
  347. get { return m_maximizedArea.width; }
  348. set { m_maximizedArea.width = value; }
  349. }
  350. public float RealWidth
  351. {
  352. get { return m_realWidth; }
  353. }
  354. public float Height
  355. {
  356. get { return m_maximizedArea.height; }
  357. set { m_maximizedArea.height = value; }
  358. }
  359. public Rect Size
  360. {
  361. get { return m_maximizedArea; }
  362. }
  363. public virtual bool IsInside( Vector2 position )
  364. {
  365. if ( !m_isActive )
  366. return false;
  367. return m_transformedArea.Contains( position );
  368. }
  369. public bool IsMaximized
  370. {
  371. get { return m_isMaximized; }
  372. set { m_isMaximized = value; }
  373. }
  374. public Rect TransformedArea
  375. {
  376. get { return m_transformedArea; }
  377. }
  378. public bool Resizable { set { m_resizable = value; } }
  379. public bool IsResizing { get { return m_isResizing; } }
  380. public bool LockOnMinimize
  381. {
  382. set
  383. {
  384. if ( m_lockOnMinimize == value )
  385. return;
  386. m_lockOnMinimize = value;
  387. if ( value )
  388. {
  389. m_preLockState = m_isMaximized;
  390. m_isMaximized = false;
  391. }
  392. else
  393. {
  394. m_isMaximized = m_preLockState;
  395. }
  396. }
  397. }
  398. public bool IsActive
  399. {
  400. get { return m_isActive; }
  401. }
  402. public AmplifyShaderEditorWindow ParentWindow { get { return m_parentWindow; } set { m_parentWindow = value; } }
  403. }
  404. }