2
0

Segment.cs 7.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236
  1. /// Credit David Gileadi
  2. /// Sourced from - https://bitbucket.org/UnityUIExtensions/unity-ui-extensions/pull-requests/12
  3. using System;
  4. using System.Collections;
  5. using UnityEngine.Events;
  6. using UnityEngine.EventSystems;
  7. namespace UnityEngine.UI.Extensions
  8. {
  9. [AddComponentMenu("UI/Extensions/Segmented Control/Segment")]
  10. [RequireComponent(typeof(Selectable))]
  11. public class Segment :
  12. UIBehaviour,
  13. IPointerClickHandler,
  14. ISubmitHandler,
  15. IPointerEnterHandler, IPointerExitHandler,
  16. IPointerDownHandler, IPointerUpHandler,
  17. ISelectHandler, IDeselectHandler
  18. {
  19. internal int index;
  20. internal SegmentedControl segmentedControl;
  21. internal bool leftmost
  22. {
  23. get { return index == 0; }
  24. }
  25. internal bool rightmost
  26. {
  27. get { return index == segmentedControl.segments.Length - 1; }
  28. }
  29. public bool selected
  30. {
  31. get { return segmentedControl.selectedSegment == this.button; }
  32. set { SetSelected(value); }
  33. }
  34. internal Selectable button
  35. {
  36. get { return GetComponent<Selectable>(); }
  37. }
  38. internal Sprite cutSprite;
  39. protected Segment()
  40. { }
  41. protected override void Start()
  42. {
  43. StartCoroutine(DelayedInit());
  44. }
  45. IEnumerator DelayedInit()
  46. {
  47. yield return null;
  48. yield return null;
  49. button.image.overrideSprite = cutSprite;
  50. if (selected)
  51. MaintainSelection();
  52. }
  53. public virtual void OnPointerClick(PointerEventData eventData)
  54. {
  55. if (eventData.button != PointerEventData.InputButton.Left)
  56. return;
  57. selected = true;
  58. }
  59. public virtual void OnPointerEnter(PointerEventData eventData)
  60. {
  61. MaintainSelection();
  62. }
  63. public virtual void OnPointerExit(PointerEventData eventData)
  64. {
  65. MaintainSelection();
  66. }
  67. public virtual void OnPointerDown(PointerEventData eventData)
  68. {
  69. MaintainSelection();
  70. }
  71. public virtual void OnPointerUp(PointerEventData eventData)
  72. {
  73. MaintainSelection();
  74. }
  75. public virtual void OnSelect(BaseEventData eventData)
  76. {
  77. MaintainSelection();
  78. }
  79. public virtual void OnDeselect(BaseEventData eventData)
  80. {
  81. MaintainSelection();
  82. }
  83. protected override void OnEnable()
  84. {
  85. base.OnEnable();
  86. if (segmentedControl)
  87. MaintainSelection();
  88. }
  89. public virtual void OnSubmit(BaseEventData eventData)
  90. {
  91. selected = true;
  92. }
  93. private void SetSelected(bool value)
  94. {
  95. if (value && button.IsActive() && button.IsInteractable())
  96. {
  97. if (segmentedControl.selectedSegment == this.button)
  98. {
  99. if (segmentedControl.allowSwitchingOff)
  100. {
  101. Deselect();
  102. }
  103. else
  104. {
  105. MaintainSelection();
  106. }
  107. }
  108. else
  109. {
  110. if (segmentedControl.selectedSegment)
  111. {
  112. var segment = segmentedControl.selectedSegment.GetComponent<Segment>();
  113. segmentedControl.selectedSegment = null;
  114. if (segment)
  115. {
  116. segment.TransitionButton();
  117. }
  118. }
  119. segmentedControl.selectedSegment = this.button;
  120. TransitionButton();
  121. segmentedControl.onValueChanged.Invoke(index);
  122. }
  123. }
  124. else if (segmentedControl.selectedSegment == this.button)
  125. {
  126. Deselect();
  127. }
  128. }
  129. private void Deselect()
  130. {
  131. segmentedControl.selectedSegment = null;
  132. TransitionButton();
  133. segmentedControl.onValueChanged.Invoke(-1);
  134. }
  135. void MaintainSelection()
  136. {
  137. if (button != segmentedControl.selectedSegment)
  138. return;
  139. TransitionButton(true);
  140. }
  141. internal void TransitionButton()
  142. {
  143. TransitionButton(false);
  144. }
  145. internal void TransitionButton(bool instant)
  146. {
  147. Color tintColor = selected ? button.colors.pressedColor : button.colors.normalColor;
  148. Color textColor = selected ? button.colors.normalColor : button.colors.pressedColor;
  149. Sprite transitionSprite = selected ? button.spriteState.pressedSprite : cutSprite;
  150. string triggerName = selected ? button.animationTriggers.pressedTrigger : button.animationTriggers.normalTrigger;
  151. switch (button.transition)
  152. {
  153. case Selectable.Transition.ColorTint:
  154. button.image.overrideSprite = cutSprite;
  155. StartColorTween(tintColor * button.colors.colorMultiplier, instant);
  156. ChangeTextColor(textColor * button.colors.colorMultiplier);
  157. break;
  158. case Selectable.Transition.SpriteSwap:
  159. if (transitionSprite != cutSprite)
  160. transitionSprite = SegmentedControl.CutSprite(transitionSprite, leftmost, rightmost);
  161. DoSpriteSwap(transitionSprite);
  162. break;
  163. case Selectable.Transition.Animation:
  164. button.image.overrideSprite = cutSprite;
  165. TriggerAnimation(triggerName);
  166. break;
  167. }
  168. }
  169. void StartColorTween(Color targetColor, bool instant)
  170. {
  171. if (button.targetGraphic == null)
  172. return;
  173. button.targetGraphic.CrossFadeColor(targetColor, instant ? 0f : button.colors.fadeDuration, true, true);
  174. }
  175. void ChangeTextColor(Color targetColor)
  176. {
  177. var text = GetComponentInChildren<Text>();
  178. if (!text)
  179. return;
  180. text.color = targetColor;
  181. }
  182. void DoSpriteSwap(Sprite newSprite)
  183. {
  184. if (button.image == null)
  185. return;
  186. button.image.overrideSprite = newSprite;
  187. }
  188. void TriggerAnimation(string triggername)
  189. {
  190. if (button.animator == null || !button.animator.isActiveAndEnabled || !button.animator.hasBoundPlayables || string.IsNullOrEmpty(triggername))
  191. return;
  192. button.animator.ResetTrigger(button.animationTriggers.normalTrigger);
  193. button.animator.ResetTrigger(button.animationTriggers.pressedTrigger);
  194. button.animator.ResetTrigger(button.animationTriggers.highlightedTrigger);
  195. button.animator.ResetTrigger(button.animationTriggers.disabledTrigger);
  196. button.animator.SetTrigger(triggername);
  197. }
  198. }
  199. }