Tanoda
ExtensionsToggle.cs
Go to the documentation of this file.
1using System;
4using UnityEngine.Serialization;
5
6namespace UnityEngine.UI
7{
11 [AddComponentMenu("UI/Extensions/Extensions Toggle", 31)]
12 [RequireComponent(typeof(RectTransform))]
13 public class ExtensionsToggle : Selectable, IPointerClickHandler, ISubmitHandler, ICanvasElement
14 {
18 public string UniqueID;
19
20 public enum ToggleTransition
21 {
22 None,
23 Fade
24 }
25
26 [Serializable]
27 public class ToggleEvent : UnityEvent<bool>
28 { }
29
30 [Serializable]
31 public class ToggleEventObject : UnityEvent<ExtensionsToggle>
32 { }
33
38
42 public Graphic graphic;
43
44 // group that this toggle can belong to
45 [SerializeField]
46 private ExtensionsToggleGroup m_Group;
47
49 {
50 get { return m_Group; }
51 set
52 {
53 m_Group = value;
54#if UNITY_EDITOR
55 if (Application.isPlaying)
56#endif
57 {
58 SetToggleGroup(m_Group, true);
59 PlayEffect(true);
60 }
61 }
62 }
63
67 [Tooltip("Use this event if you only need the bool state of the toggle that was changed")]
69
70
74 [Tooltip("Use this event if you need access to the toggle that was changed")]
76
77 // Whether the toggle is on
78 [FormerlySerializedAs("m_IsActive")]
79 [Tooltip("Is the toggle currently on or off?")]
80 [SerializeField]
81 private bool m_IsOn;
82
83 protected ExtensionsToggle()
84 { }
85
86#if UNITY_EDITOR
87 protected override void OnValidate()
88 {
89 base.OnValidate();
90 Set(m_IsOn, false);
91 PlayEffect(toggleTransition == ToggleTransition.None);
92#if UNITY_2018_3_OR_NEWER
93 if (!Application.isPlaying)
94#else
95 var prefabType = UnityEditor.PrefabUtility.GetPrefabType(this);
96 if (prefabType != UnityEditor.PrefabType.Prefab && !Application.isPlaying)
97#endif
98 {
99 CanvasUpdateRegistry.RegisterCanvasElementForLayoutRebuild(this);
100 }
101 }
102
103#endif // if UNITY_EDITOR
104
105 public virtual void Rebuild(CanvasUpdate executing)
106 {
107#if UNITY_EDITOR
108 if (executing == CanvasUpdate.Prelayout)
109 {
110 onValueChanged.Invoke(m_IsOn);
111 onToggleChanged.Invoke(this);
112 }
113#endif
114 }
115
116 public virtual void LayoutComplete()
117 { }
118
119 public virtual void GraphicUpdateComplete()
120 { }
121
122 protected override void OnEnable()
123 {
124 base.OnEnable();
125 SetToggleGroup(m_Group, false);
126 PlayEffect(true);
127 }
128
129 protected override void OnDisable()
130 {
131 SetToggleGroup(null, false);
132 base.OnDisable();
133 }
134
135 protected override void OnDidApplyAnimationProperties()
136 {
137 // Check if isOn has been changed by the animation.
138 // Unfortunately there is no way to check if we don't have a graphic.
139 if (graphic != null)
140 {
141 bool oldValue = !Mathf.Approximately(graphic.canvasRenderer.GetColor().a, 0);
142 if (m_IsOn != oldValue)
143 {
144 m_IsOn = oldValue;
145 Set(!oldValue);
146 }
147 }
148
149 base.OnDidApplyAnimationProperties();
150 }
151
152 private void SetToggleGroup(ExtensionsToggleGroup newGroup, bool setMemberValue)
153 {
154 ExtensionsToggleGroup oldGroup = m_Group;
155
156 // Sometimes IsActive returns false in OnDisable so don't check for it.
157 // Rather remove the toggle too often than too little.
158 if (m_Group != null)
159 m_Group.UnregisterToggle(this);
160
161 // At runtime the group variable should be set but not when calling this method from OnEnable or OnDisable.
162 // That's why we use the setMemberValue parameter.
163 if (setMemberValue)
164 m_Group = newGroup;
165
166 // Only register to the new group if this Toggle is active.
167 if (m_Group != null && IsActive())
168 m_Group.RegisterToggle(this);
169
170 // If we are in a new group, and this toggle is on, notify group.
171 // Note: Don't refer to m_Group here as it's not guaranteed to have been set.
172 if (newGroup != null && newGroup != oldGroup && IsOn && IsActive())
173 m_Group.NotifyToggleOn(this);
174 }
175
179 public bool IsOn
180 {
181 get { return m_IsOn; }
182 set
183 {
184 Set(value);
185 }
186 }
187
188 void Set(bool value)
189 {
190 Set(value, true);
191 }
192
193 void Set(bool value, bool sendCallback)
194 {
195 if (m_IsOn == value)
196 return;
197
198 // if we are in a group and set to true, do group logic
199 m_IsOn = value;
200 if (m_Group != null && IsActive())
201 {
202 if (m_IsOn || (!m_Group.AnyTogglesOn() && !m_Group.AllowSwitchOff))
203 {
204 m_IsOn = true;
205 m_Group.NotifyToggleOn(this);
206 }
207 }
208
209 // Always send event when toggle is clicked, even if value didn't change
210 // due to already active toggle in a toggle group being clicked.
211 // Controls like Dropdown rely on this.
212 // It's up to the user to ignore a selection being set to the same value it already was, if desired.
213 PlayEffect(toggleTransition == ToggleTransition.None);
214 if (sendCallback)
215 {
216 onValueChanged.Invoke(m_IsOn);
217 onToggleChanged.Invoke(this);
218 }
219 }
220
224 private void PlayEffect(bool instant)
225 {
226 if (graphic == null)
227 return;
228
229#if UNITY_EDITOR
230 if (!Application.isPlaying)
231 graphic.canvasRenderer.SetAlpha(m_IsOn ? 1f : 0f);
232 else
233#endif
234 graphic.CrossFadeAlpha(m_IsOn ? 1f : 0f, instant ? 0f : 0.1f, true);
235 }
236
240 protected override void Start()
241 {
242 PlayEffect(true);
243 }
244
245 private void InternalToggle()
246 {
247 if (!IsActive() || !IsInteractable())
248 return;
249
250 IsOn = !IsOn;
251 }
252
256 public virtual void OnPointerClick(PointerEventData eventData)
257 {
258 if (eventData.button != PointerEventData.InputButton.Left)
259 return;
260
261 InternalToggle();
262 }
263
264 public virtual void OnSubmit(BaseEventData eventData)
265 {
266 InternalToggle();
267 }
268 }
269}
void NotifyToggleOn(ExtensionsToggle toggle)
void UnregisterToggle(ExtensionsToggle toggle)
void RegisterToggle(ExtensionsToggle toggle)
Simple toggle – something that has an 'on' and 'off' states: checkbox, toggle button,...
bool IsOn
Whether the toggle is currently active.
override void OnDidApplyAnimationProperties()
virtual void OnSubmit(BaseEventData eventData)
string UniqueID
Variable to identify this script, change the datatype if needed to fit your use case
override void Start()
Assume the correct visual state.
Graphic graphic
Graphic the toggle should be working with.
virtual void Rebuild(CanvasUpdate executing)
virtual void OnPointerClick(PointerEventData eventData)
React to clicks.
ToggleTransition toggleTransition
Transition type.
ToggleEventObject onToggleChanged
Allow for delegate-based subscriptions for faster events than 'eventReceiver', and allowing for multi...
ToggleEvent onValueChanged
Allow for delegate-based subscriptions for faster events than 'eventReceiver', and allowing for multi...