TabButton.cs 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190
  1. using System;
  2. using UnityEditor;
  3. using UnityEngine;
  4. namespace Unity.PlasticSCM.Editor.UI
  5. {
  6. internal class TabButton
  7. {
  8. internal bool DrawTabButton(
  9. string buttonText,
  10. bool wasActive,
  11. float width)
  12. {
  13. bool isCloseButtonClicked;
  14. return DrawClosableTabButton(
  15. buttonText,
  16. wasActive,
  17. false,
  18. width,
  19. null,
  20. out isCloseButtonClicked);
  21. }
  22. internal bool DrawClosableTabButton(
  23. string buttonText,
  24. bool wasActive,
  25. bool isClosable,
  26. float width,
  27. Action repaintAction,
  28. out bool isCloseButtonClicked)
  29. {
  30. isCloseButtonClicked = false;
  31. GUIContent buttonContent = new GUIContent(buttonText);
  32. GUIStyle buttonStyle = (wasActive) ?
  33. UnityStyles.PlasticWindow.ActiveTabButton :
  34. EditorStyles.toolbarButton;
  35. Rect toggleRect = GUILayoutUtility.GetRect(
  36. buttonContent, buttonStyle,
  37. GUILayout.Width(width));
  38. if (isClosable && Event.current.type == EventType.MouseMove)
  39. {
  40. if (mCloseButtonRect.Contains(Event.current.mousePosition))
  41. {
  42. SetCloseButtonState(
  43. CloseButtonState.Hovered,
  44. repaintAction);
  45. }
  46. else
  47. {
  48. SetCloseButtonState(
  49. CloseButtonState.Normal,
  50. repaintAction);
  51. }
  52. }
  53. if (isClosable && Event.current.type == EventType.MouseDown)
  54. {
  55. if (mCloseButtonRect.Contains(Event.current.mousePosition))
  56. {
  57. SetCloseButtonState(
  58. CloseButtonState.Clicked,
  59. repaintAction);
  60. Event.current.Use();
  61. }
  62. }
  63. if (isClosable && Event.current.type == EventType.MouseUp)
  64. {
  65. if (mCloseButtonRect.Contains(Event.current.mousePosition))
  66. {
  67. Event.current.Use();
  68. isCloseButtonClicked = true;
  69. }
  70. if (IsTabClickWithMiddleButton(toggleRect, Event.current))
  71. {
  72. Event.current.Use();
  73. isCloseButtonClicked = true;
  74. }
  75. SetCloseButtonState(
  76. CloseButtonState.Normal,
  77. repaintAction);
  78. }
  79. bool isActive = GUI.Toggle(
  80. toggleRect, wasActive, buttonText, buttonStyle);
  81. if (isClosable && toggleRect.height > 1)
  82. {
  83. mCloseButtonRect = DrawCloseButton(
  84. toggleRect,
  85. mCloseButtonState);
  86. }
  87. if (wasActive)
  88. {
  89. DrawUnderline(toggleRect);
  90. }
  91. return isActive;
  92. }
  93. static Rect DrawCloseButton(
  94. Rect toggleRect,
  95. CloseButtonState state)
  96. {
  97. int closeButtonSize = 15;
  98. GUIContent closeImage = new GUIContent(GetCloseImage(state));
  99. Rect closeTabRect = new Rect(
  100. toggleRect.xMax - closeButtonSize - 1,
  101. toggleRect.y + (toggleRect.height / 2 - closeButtonSize / 2),
  102. closeButtonSize,
  103. closeButtonSize);
  104. GUI.Button(closeTabRect, closeImage, EditorStyles.label);
  105. return new Rect(
  106. closeTabRect.x - 1,
  107. closeTabRect.y - 1,
  108. closeTabRect.width + 2,
  109. closeTabRect.height + 2);
  110. }
  111. static void DrawUnderline(Rect toggleRect)
  112. {
  113. GUIStyle activeTabStyle =
  114. UnityStyles.PlasticWindow.ActiveTabUnderline;
  115. Rect underlineRect = new Rect(
  116. toggleRect.x,
  117. toggleRect.yMax - activeTabStyle.fixedHeight,
  118. toggleRect.width,
  119. activeTabStyle.fixedHeight);
  120. GUI.Label(underlineRect, string.Empty, activeTabStyle);
  121. }
  122. static bool IsTabClickWithMiddleButton(Rect toggleRect, Event currentEvent)
  123. {
  124. if (currentEvent.button != 2)
  125. return false;
  126. return toggleRect.height > 1 &&
  127. toggleRect.Contains(Event.current.mousePosition);
  128. }
  129. static Texture GetCloseImage(CloseButtonState state)
  130. {
  131. if (state == CloseButtonState.Hovered)
  132. return Images.GetHoveredCloseIcon();
  133. if (state == CloseButtonState.Clicked)
  134. return Images.GetClickedCloseIcon();
  135. return Images.GetCloseIcon();
  136. }
  137. void SetCloseButtonState(
  138. CloseButtonState newState,
  139. Action repaintAction)
  140. {
  141. if (mCloseButtonState == newState)
  142. return;
  143. mCloseButtonState = newState;
  144. if (repaintAction != null)
  145. repaintAction();
  146. }
  147. Rect mCloseButtonRect;
  148. CloseButtonState mCloseButtonState;
  149. enum CloseButtonState
  150. {
  151. Normal,
  152. Clicked,
  153. Hovered,
  154. }
  155. }
  156. }