diff --git a/Scripts/Controls/Segment.cs b/Scripts/Controls/Segment.cs new file mode 100644 index 0000000..96598ee --- /dev/null +++ b/Scripts/Controls/Segment.cs @@ -0,0 +1,233 @@ +/// Credit David Gileadi +/// Sourced from - https://bitbucket.org/UnityUIExtensions/unity-ui-extensions/pull-requests/12 + +using System; +using System.Collections; +using UnityEngine.Events; +using UnityEngine.EventSystems; + +namespace UnityEngine.UI.Extensions +{ + [AddComponentMenu("UI/Extensions/Segmented Control/Segment")] + [RequireComponent(typeof(Selectable))] + public class Segment : + UIBehaviour, + IPointerClickHandler, + ISubmitHandler, + IPointerEnterHandler, IPointerExitHandler, + IPointerDownHandler, IPointerUpHandler, + ISelectHandler, IDeselectHandler + { + internal int index; + internal SegmentedControl segmentedControl; + + internal bool leftmost + { + get { return index == 0; } + } + internal bool rightmost + { + get { return index == segmentedControl.segments.Length - 1; } + } + + public bool selected + { + get { return segmentedControl.selectedSegment == this.button; } + set { SetSelected(value); } + } + + internal Selectable button + { + get { return GetComponent(); } + } + + [SerializeField] + Color textColor; + internal Sprite cutSprite; + + protected Segment() + { } + + public virtual void OnPointerClick(PointerEventData eventData) + { + if (eventData.button != PointerEventData.InputButton.Left) + return; + + selected = true; + } + + public virtual void OnPointerEnter(PointerEventData eventData) + { + MaintainSelection(); + } + + public virtual void OnPointerExit(PointerEventData eventData) + { + MaintainSelection(); + } + + public virtual void OnPointerDown(PointerEventData eventData) + { + MaintainSelection(); + } + + public virtual void OnPointerUp(PointerEventData eventData) + { + MaintainSelection(); + } + + public virtual void OnSelect(BaseEventData eventData) + { + MaintainSelection(); + } + + public virtual void OnDeselect(BaseEventData eventData) + { + MaintainSelection(); + } + + protected override void OnEnable() + { + base.OnEnable(); + if (segmentedControl) + MaintainSelection(); + } + + public virtual void OnSubmit(BaseEventData eventData) + { + selected = true; + } + + private void SetSelected(bool value) + { + if (value && button.IsActive() && button.IsInteractable()) + { + if (segmentedControl.selectedSegment == this.button) + { + if (segmentedControl.allowSwitchingOff) + { + Deselect(); + } + else + { + MaintainSelection(); + } + } + else + { + if (segmentedControl.selectedSegment) + { + var segment = segmentedControl.selectedSegment.GetComponent(); + segmentedControl.selectedSegment = null; + if (segment) + { + segment.TransitionButton(); + } + } + + segmentedControl.selectedSegment = this.button; + StoreTextColor(); + TransitionButton(); + segmentedControl.onValueChanged.Invoke(index); + } + } + else if (segmentedControl.selectedSegment == this.button) + { + Deselect(); + } + } + + private void Deselect() + { + segmentedControl.selectedSegment = null; + TransitionButton(); + segmentedControl.onValueChanged.Invoke(-1); + } + + void MaintainSelection() + { + if (button != segmentedControl.selectedSegment) + return; + + TransitionButton(true); + } + + internal void TransitionButton() + { + TransitionButton(false); + } + + internal void TransitionButton(bool instant) + { + Color tintColor = selected ? segmentedControl.selectedColor : button.colors.normalColor; + Color textColor = selected ? button.colors.normalColor : this.textColor; + Sprite transitionSprite = selected ? button.spriteState.pressedSprite : cutSprite; + string triggerName = selected ? button.animationTriggers.pressedTrigger : button.animationTriggers.normalTrigger; + + switch (button.transition) + { + case Selectable.Transition.ColorTint: + button.image.overrideSprite = cutSprite; + StartColorTween(tintColor * button.colors.colorMultiplier, instant); + ChangeTextColor(textColor * button.colors.colorMultiplier); + break; + case Selectable.Transition.SpriteSwap: + if (transitionSprite != cutSprite) + transitionSprite = SegmentedControl.CutSprite(transitionSprite, leftmost, rightmost); + DoSpriteSwap(transitionSprite); + break; + case Selectable.Transition.Animation: + button.image.overrideSprite = cutSprite; + TriggerAnimation(triggerName); + break; + } + } + + void StartColorTween(Color targetColor, bool instant) + { + if (button.targetGraphic == null) + return; + + button.targetGraphic.CrossFadeColor(targetColor, instant ? 0f : button.colors.fadeDuration, true, true); + } + + internal void StoreTextColor() + { + var text = GetComponentInChildren(); + if (!text) + return; + + textColor = text.color; + } + + void ChangeTextColor(Color targetColor) + { + var text = GetComponentInChildren(); + if (!text) + return; + + text.color = targetColor; + } + + void DoSpriteSwap(Sprite newSprite) + { + if (button.image == null) + return; + + button.image.overrideSprite = newSprite; + } + + void TriggerAnimation(string triggername) + { + if (button.animator == null || !button.animator.isActiveAndEnabled || !button.animator.hasBoundPlayables || string.IsNullOrEmpty(triggername)) + return; + + button.animator.ResetTrigger(button.animationTriggers.normalTrigger); + button.animator.ResetTrigger(button.animationTriggers.pressedTrigger); + button.animator.ResetTrigger(button.animationTriggers.highlightedTrigger); + button.animator.ResetTrigger(button.animationTriggers.disabledTrigger); + + button.animator.SetTrigger(triggername); + } + } +} \ No newline at end of file diff --git a/Scripts/Controls/Segment.cs.meta b/Scripts/Controls/Segment.cs.meta new file mode 100644 index 0000000..9914bff --- /dev/null +++ b/Scripts/Controls/Segment.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: b8ea9937637d64c6da52723c68267703 +timeCreated: 1503449008 +licenseType: Free +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Scripts/Controls/SegmentedControl.cs b/Scripts/Controls/SegmentedControl.cs index 2e1aba7..6b56cc8 100644 --- a/Scripts/Controls/SegmentedControl.cs +++ b/Scripts/Controls/SegmentedControl.cs @@ -2,13 +2,14 @@ /// Sourced from - https://bitbucket.org/UnityUIExtensions/unity-ui-extensions/pull-requests/12 using System; +using System.Collections; using UnityEngine.Events; using UnityEngine.EventSystems; namespace UnityEngine.UI.Extensions { // Segmented control, like a group of buttons - [AddComponentMenu("UI/Extensions/Segmented Control")] + [AddComponentMenu("UI/Extensions/Segmented Control/Segmented Control")] [RequireComponent(typeof(RectTransform))] public class SegmentedControl : UIBehaviour { @@ -28,7 +29,7 @@ namespace UnityEngine.UI.Extensions [Tooltip("Event to fire once the selection has been changed")] private SegmentSelectedEvent m_onValueChanged = new SegmentSelectedEvent(); - protected internal Selectable selectedSegment; + internal Selectable selectedSegment; protected float SeparatorWidth { @@ -74,8 +75,6 @@ namespace UnityEngine.UI.Extensions { value = Math.Max(value, -1); value = Math.Min(value, segments.Length - 1); - if (value == m_selectedSegmentIndex) - return; m_selectedSegmentIndex = value; @@ -117,6 +116,19 @@ namespace UnityEngine.UI.Extensions { base.Start(); + if (isActiveAndEnabled) + StartCoroutine(DelayedInit()); + } + + protected override void OnEnable() + { + StartCoroutine(DelayedInit()); + } + + IEnumerator DelayedInit() + { + yield return null; + LayoutSegments(); if (m_selectedSegmentIndex != -1) @@ -128,10 +140,8 @@ namespace UnityEngine.UI.Extensions { base.OnValidate(); - LayoutSegments(); - - if (m_selectedSegmentIndex != -1) - selectedSegmentIndex = m_selectedSegmentIndex; + if (isActiveAndEnabled) + StartCoroutine(DelayedInit()); if (m_selectedSegmentIndex > transform.childCount) { @@ -156,12 +166,11 @@ namespace UnityEngine.UI.Extensions for (int i = 0; i < buttons.Length; i++) { var segment = buttons[i].GetComponent(); - if (segment == null) + if (segment != null) { - segment = buttons[i].gameObject.AddComponent(); + segment.index = i; + segment.segmentedControl = this; } - segment.index = i; - segment.segmentedControl = this; } return buttons; @@ -239,226 +248,4 @@ namespace UnityEngine.UI.Extensions } } } - - [RequireComponent(typeof(Selectable))] - public class Segment : - UIBehaviour, - IPointerClickHandler, - ISubmitHandler, - IPointerEnterHandler, IPointerExitHandler, - IPointerDownHandler, IPointerUpHandler, - ISelectHandler, IDeselectHandler - { - internal int index; - internal SegmentedControl segmentedControl; - - internal bool leftmost - { - get { return index == 0; } - } - internal bool rightmost - { - get { return index == segmentedControl.segments.Length - 1; } - } - - public bool selected - { - get { return segmentedControl.selectedSegment == this.button; } - set { SetSelected(value); } - } - - internal Selectable button - { - get { return GetComponent(); } - } - - [SerializeField] - Color textColor; - internal Sprite cutSprite; - - protected Segment() - { } - - public virtual void OnPointerClick(PointerEventData eventData) - { - if (eventData.button != PointerEventData.InputButton.Left) - return; - - selected = true; - } - - public virtual void OnPointerEnter(PointerEventData eventData) - { - MaintainSelection(); - } - - public virtual void OnPointerExit(PointerEventData eventData) - { - MaintainSelection(); - } - - public virtual void OnPointerDown(PointerEventData eventData) - { - MaintainSelection(); - } - - public virtual void OnPointerUp(PointerEventData eventData) - { - MaintainSelection(); - } - - public virtual void OnSelect(BaseEventData eventData) - { - MaintainSelection(); - } - - public virtual void OnDeselect(BaseEventData eventData) - { - MaintainSelection(); - } - - protected override void OnEnable() - { - base.OnEnable(); - if (segmentedControl) - MaintainSelection(); - } - - public virtual void OnSubmit(BaseEventData eventData) - { - selected = true; - } - - private void SetSelected(bool value) - { - if (value && button.IsActive() && button.IsInteractable()) - { - if (segmentedControl.selectedSegment == this.button) - { - if (segmentedControl.allowSwitchingOff) - { - Deselect(); - } - else - { - MaintainSelection(); - } - } - else - { - if (segmentedControl.selectedSegment) - { - var segment = segmentedControl.selectedSegment.GetComponent(); - segmentedControl.selectedSegment = null; - if (segment) - { - segment.TransitionButton(); - } - } - - segmentedControl.selectedSegment = this.button; - StoreTextColor(); - TransitionButton(); - segmentedControl.onValueChanged.Invoke(index); - } - } - else if (segmentedControl.selectedSegment == this.button) - { - Deselect(); - } - } - - private void Deselect() - { - segmentedControl.selectedSegment = null; - TransitionButton(); - segmentedControl.onValueChanged.Invoke(-1); - } - - void MaintainSelection() - { - if (button != segmentedControl.selectedSegment) - return; - - TransitionButton(true); - } - - internal void TransitionButton() - { - TransitionButton(false); - } - - internal void TransitionButton(bool instant) - { - Color tintColor = selected ? segmentedControl.selectedColor : button.colors.normalColor; - Color textColor = selected ? button.colors.normalColor : this.textColor; - Sprite transitionSprite = selected ? button.spriteState.pressedSprite : cutSprite; - string triggerName = selected ? button.animationTriggers.pressedTrigger : button.animationTriggers.normalTrigger; - - switch (button.transition) - { - case Selectable.Transition.ColorTint: - button.image.overrideSprite = cutSprite; - StartColorTween(tintColor * button.colors.colorMultiplier, instant); - ChangeTextColor(textColor * button.colors.colorMultiplier); - break; - case Selectable.Transition.SpriteSwap: - if (transitionSprite != cutSprite) - transitionSprite = SegmentedControl.CutSprite(transitionSprite, leftmost, rightmost); - DoSpriteSwap(transitionSprite); - break; - case Selectable.Transition.Animation: - button.image.overrideSprite = cutSprite; - TriggerAnimation(triggerName); - break; - } - } - - void StartColorTween(Color targetColor, bool instant) - { - if (button.targetGraphic == null) - return; - - button.targetGraphic.CrossFadeColor(targetColor, instant ? 0f : button.colors.fadeDuration, true, true); - } - - internal void StoreTextColor() - { - var text = GetComponentInChildren(); - if (!text) - return; - - textColor = text.color; - } - - void ChangeTextColor(Color targetColor) - { - var text = GetComponentInChildren(); - if (!text) - return; - - text.color = targetColor; - } - - void DoSpriteSwap(Sprite newSprite) - { - if (button.image == null) - return; - - button.image.overrideSprite = newSprite; - } - - void TriggerAnimation(string triggername) - { - if (button.animator == null || !button.animator.isActiveAndEnabled || !button.animator.hasBoundPlayables || string.IsNullOrEmpty(triggername)) - return; - - button.animator.ResetTrigger(button.animationTriggers.normalTrigger); - button.animator.ResetTrigger(button.animationTriggers.pressedTrigger); - button.animator.ResetTrigger(button.animationTriggers.highlightedTrigger); - button.animator.ResetTrigger(button.animationTriggers.disabledTrigger); - - button.animator.SetTrigger(triggername); - } - } } \ No newline at end of file diff --git a/Scripts/Controls/Stepper.cs b/Scripts/Controls/Stepper.cs index 721b890..6d920d8 100644 --- a/Scripts/Controls/Stepper.cs +++ b/Scripts/Controls/Stepper.cs @@ -2,6 +2,7 @@ /// Sourced from - https://bitbucket.org/UnityUIExtensions/unity-ui-extensions/pull-requests/11 using System; +using System.Collections; using UnityEngine.Events; using UnityEngine.EventSystems; @@ -106,6 +107,19 @@ namespace UnityEngine.UI.Extensions protected override void Start() { + if (isActiveAndEnabled) + StartCoroutine(DelayedInit()); + } + + protected override void OnEnable() + { + StartCoroutine(DelayedInit()); + } + + IEnumerator DelayedInit() + { + yield return null; + RecreateSprites(sides); } @@ -117,15 +131,6 @@ namespace UnityEngine.UI.Extensions throw new InvalidOperationException("A stepper must have two Button children"); } - for (int i = 0; i < 2; i++) - { - var side = buttons[i].GetComponent(); - if (side == null) - { - side = buttons[i].gameObject.AddComponent(); - } - } - if (!wrap) { DisableAtExtremes(buttons); @@ -246,97 +251,4 @@ namespace UnityEngine.UI.Extensions } } } - - [RequireComponent(typeof(Selectable))] - public class StepperSide : - UIBehaviour, - IPointerClickHandler, - ISubmitHandler, - IPointerEnterHandler, IPointerExitHandler, - IPointerDownHandler, IPointerUpHandler, - ISelectHandler, IDeselectHandler - { - Selectable button { get { return GetComponent(); } } - - Stepper stepper { get { return GetComponentInParent(); } } - - bool leftmost { get { return button == stepper.sides[0]; } } - - internal Sprite cutSprite; - - protected StepperSide() - { } - - public virtual void OnPointerClick(PointerEventData eventData) - { - if (eventData.button != PointerEventData.InputButton.Left) - return; - - Press(); - AdjustSprite(false); - } - - public virtual void OnSubmit(BaseEventData eventData) - { - Press(); - AdjustSprite(true); - } - - public virtual void OnPointerEnter(PointerEventData eventData) - { - AdjustSprite(false); - } - - public virtual void OnPointerExit(PointerEventData eventData) - { - AdjustSprite(true); - } - - public virtual void OnPointerDown(PointerEventData eventData) - { - AdjustSprite(false); - } - - public virtual void OnPointerUp(PointerEventData eventData) - { - AdjustSprite(false); - } - - public virtual void OnSelect(BaseEventData eventData) - { - AdjustSprite(false); - } - - public virtual void OnDeselect(BaseEventData eventData) - { - AdjustSprite(true); - } - - private void Press() - { - if (!button.IsActive() || !button.IsInteractable()) - return; - - if (leftmost) - { - stepper.StepDown(); - } - else - { - stepper.StepUp(); - } - } - - private void AdjustSprite(bool restore) - { - var image = button.image; - if (!image || image.overrideSprite == cutSprite) - return; - - if (restore) - image.overrideSprite = cutSprite; - else - image.overrideSprite = Stepper.CutSprite(image.overrideSprite, leftmost); - } - } } \ No newline at end of file diff --git a/Scripts/Controls/StepperSide.cs b/Scripts/Controls/StepperSide.cs new file mode 100644 index 0000000..f509b35 --- /dev/null +++ b/Scripts/Controls/StepperSide.cs @@ -0,0 +1,103 @@ +/// Credit David Gileadi +/// Sourced from - https://bitbucket.org/UnityUIExtensions/unity-ui-extensions/pull-requests/11 + +using System; +using UnityEngine.Events; +using UnityEngine.EventSystems; + +namespace UnityEngine.UI.Extensions +{ + + [RequireComponent(typeof(Selectable))] + public class StepperSide : + UIBehaviour, + IPointerClickHandler, + ISubmitHandler, + IPointerEnterHandler, IPointerExitHandler, + IPointerDownHandler, IPointerUpHandler, + ISelectHandler, IDeselectHandler + { + Selectable button { get { return GetComponent(); } } + + Stepper stepper { get { return GetComponentInParent(); } } + + bool leftmost { get { return button == stepper.sides[0]; } } + + internal Sprite cutSprite; + + protected StepperSide() + { } + + public virtual void OnPointerClick(PointerEventData eventData) + { + if (eventData.button != PointerEventData.InputButton.Left) + return; + + Press(); + AdjustSprite(false); + } + + public virtual void OnSubmit(BaseEventData eventData) + { + Press(); + AdjustSprite(true); + } + + public virtual void OnPointerEnter(PointerEventData eventData) + { + AdjustSprite(false); + } + + public virtual void OnPointerExit(PointerEventData eventData) + { + AdjustSprite(true); + } + + public virtual void OnPointerDown(PointerEventData eventData) + { + AdjustSprite(false); + } + + public virtual void OnPointerUp(PointerEventData eventData) + { + AdjustSprite(false); + } + + public virtual void OnSelect(BaseEventData eventData) + { + AdjustSprite(false); + } + + public virtual void OnDeselect(BaseEventData eventData) + { + AdjustSprite(true); + } + + private void Press() + { + if (!button.IsActive() || !button.IsInteractable()) + return; + + if (leftmost) + { + stepper.StepDown(); + } + else + { + stepper.StepUp(); + } + } + + private void AdjustSprite(bool restore) + { + var image = button.image; + if (!image || image.overrideSprite == cutSprite) + return; + + if (restore) + image.overrideSprite = cutSprite; + else + image.overrideSprite = Stepper.CutSprite(image.overrideSprite, leftmost); + } + } +} \ No newline at end of file diff --git a/Scripts/Controls/StepperSide.cs.meta b/Scripts/Controls/StepperSide.cs.meta new file mode 100644 index 0000000..a35a2d0 --- /dev/null +++ b/Scripts/Controls/StepperSide.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: dd241e0d4a8de4fc9924c1dce285c587 +timeCreated: 1503449912 +licenseType: Free +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: