diff --git a/Editor/UIExtensionsMenuOptions.cs b/Editor/UIExtensionsMenuOptions.cs index ec94484..8e2e97f 100644 --- a/Editor/UIExtensionsMenuOptions.cs +++ b/Editor/UIExtensionsMenuOptions.cs @@ -1652,6 +1652,32 @@ namespace UnityEditor.UI #endregion + #region Segmented Control + [MenuItem("GameObject/UI/Extensions/Segmented Control", false)] + static public void AddSegmentedControl(MenuCommand menuCommand) + { + GameObject go = CreateUIElementRoot("Segmented Control", menuCommand, s_ThinGUIElementSize); + SegmentedControl control = go.AddComponent(); + + Color selectedColor = new Color(0f, 0.455f, 0.894f); + control.selectedColor = selectedColor; + + var labels = new string[] { "This", "That", "Other" }; + for (int i = 0; i < 3; i++) + { + var button = AddButtonAsChild(go); + button.name = "Segment " + (i + 1); + var text = button.GetComponentInChildren(); + text.text = labels[i]; + text.color = selectedColor; + } + + control.LayoutSegments(); + + Selection.activeGameObject = go; + } + #endregion + #region UI Knob [MenuItem("GameObject/UI/Extensions/UI Knob", false)] static public void AddUIKnob(MenuCommand menuCommand) diff --git a/Scripts/Controls/SegmentedControl.cs b/Scripts/Controls/SegmentedControl.cs new file mode 100644 index 0000000..cc73298 --- /dev/null +++ b/Scripts/Controls/SegmentedControl.cs @@ -0,0 +1,422 @@ +using System; +using System.Collections; +using System.Collections.Generic; +using UnityEngine.Events; +using UnityEngine.EventSystems; +using UnityEngine.Serialization; + +namespace UnityEngine.UI.Extensions +{ + // Segmented control, like a group of buttons + [AddComponentMenu("UI/Extensions/Segmented Control")] + [RequireComponent(typeof(RectTransform))] + public class SegmentedControl : UIBehaviour + { + public Button[] segments + { + get + { + if (_segments == null || _segments.Length == 0) + { + _segments = GetChildSegments(); + } + return _segments; + } + } + private Button[] _segments; + + [SerializeField] + public Color selectedColor; + + [SerializeField] + private Graphic _separator; + public Graphic separator { get { return _separator; } set { _separator = value; _separatorWidth = 0; LayoutSegments(); } } + + private float _separatorWidth = 0; + private float separatorWidth + { + get + { + if (_separatorWidth == 0 && separator) + { + _separatorWidth = separator.rectTransform.rect.width; + var image = separator.GetComponent(); + if (image) + _separatorWidth /= image.pixelsPerUnit; + } + return _separatorWidth; + } + } + + [SerializeField] private bool _allowSwitchingOff = false; + public bool allowSwitchingOff { get { return _allowSwitchingOff; } set { _allowSwitchingOff = value; } } + + protected internal Button selectedSegment; + + [SerializeField] + private int _selectedSegmentIndex = -1; + public int selectedSegmentIndex + { + get { return Array.IndexOf(segments, selectedSegment); } + set + { + value = Math.Max(value, -1); + value = Math.Min(value, segments.Length - 1); + _selectedSegmentIndex = value; + if (value == -1) + { + if (selectedSegment) + { + selectedSegment.GetComponent().selected = false; + selectedSegment = null; + } + } + else + { +#if UNITY_EDITOR + segments[value].GetComponent().StoreTextColor(); +#endif + segments[value].GetComponent().selected = true; + } + } + } + + [Serializable] + public class SegmentSelectedEvent : UnityEvent { } + + // Event delegates triggered on click. + [SerializeField] + private SegmentSelectedEvent _onValueChanged = new SegmentSelectedEvent(); + + public SegmentSelectedEvent onValueChanged + { + get { return _onValueChanged; } + set { _onValueChanged = value; } + } + + protected SegmentedControl() + { } + + protected override void Start() + { + base.Start(); + + LayoutSegments(); + + if (_selectedSegmentIndex != -1) + selectedSegmentIndex = _selectedSegmentIndex; + } + +#if UNITY_EDITOR + protected override void OnValidate() + { + base.OnValidate(); + + if (separator) + LayoutSegments(); + + if (_selectedSegmentIndex != -1) + selectedSegmentIndex = _selectedSegmentIndex; + } +#endif + + private Button[] GetChildSegments() + { + var buttons = GetComponentsInChildren