AR Design
UBC EML collab with UBC SALA - visualizing IoT data in AR
TestButton.cs
Go to the documentation of this file.
1 // Copyright (c) Microsoft Corporation. All rights reserved.
2 // Licensed under the MIT License. See LICENSE in the project root for license information.
3 
4 using UnityEngine;
5 
6 namespace HoloToolkit.Unity.InputModule.Tests
7 {
13  public class TestButton : MonoBehaviour, IInputClickHandler, IFocusable
14  {
15  public Transform ToolTip;
16  public Renderer ToolTipRenderer;
17 
18  private float toolTipTimer = 0.0f;
19  public float ToolTipFadeTime = 0.25f;
20  public float ToolTipDelayTime = 0.5f;
21 
22  [SerializeField]
23  protected Animator ButtonAnimator;
24 
25  private int focusedButtonId;
26  private int selectedButtonId;
27  private int dehydrateButtonId;
28  private int stayFocusedButtonId;
29  private int colorPropertyId;
30 
31  public delegate void ActivateDelegate(TestButton source);
32  public event ActivateDelegate Activated;
33 
34  public bool EnableActivation = true;
35 
36  private AnimatorControllerParameter[] animatorHashes;
37  private Material cachedToolTipMaterial;
38 
39  private bool focused;
40  public bool Focused
41  {
42  get { return focused; }
43  set
44  {
45  if (focused != value)
46  {
47  focused = value;
48  UpdateButtonAnimation();
49  }
50  }
51  }
52 
53  private bool stayFocused;
54  public bool StayFocused
55  {
56  get { return stayFocused; }
57  set
58  {
59  if (stayFocused != value)
60  {
61  stayFocused = value;
62  UpdateButtonAnimation();
63  }
64  }
65  }
66 
67  private bool selected;
68  public bool Selected
69  {
70  get { return selected; }
71  set
72  {
73  if (selected != value)
74  {
75  selected = value;
76  UpdateButtonAnimation();
77  }
78  }
79  }
80 
81  protected virtual void Awake()
82  {
83  if (focusedButtonId == 0)
84  {
85  focusedButtonId = Animator.StringToHash("Focused");
86  }
87 
88  if (selectedButtonId == 0)
89  {
90  selectedButtonId = Animator.StringToHash("Selected");
91  }
92 
93  if (dehydrateButtonId == 0)
94  {
95  dehydrateButtonId = Animator.StringToHash("Dehydrate");
96  }
97 
98  if (stayFocusedButtonId == 0)
99  {
100  stayFocusedButtonId = Animator.StringToHash("StayFocused");
101  }
102 
103  if (colorPropertyId == 0)
104  {
105  colorPropertyId = Shader.PropertyToID("_Color");
106  }
107  }
108 
109  protected virtual void OnEnable()
110  {
111  Focused = false;
112 
113  // Set the initial alpha
114  if (ToolTipRenderer != null)
115  {
116  cachedToolTipMaterial = ToolTipRenderer.material;
117 
118  Color tipColor = cachedToolTipMaterial.GetColor(colorPropertyId);
119  tipColor.a = 0.0f;
120  cachedToolTipMaterial.SetColor(colorPropertyId, tipColor);
121  toolTipTimer = 0.0f;
122  }
123 
124  UpdateVisuals();
125  UpdateButtonAnimation();
126  }
127 
128  private void Update()
129  {
130  if (ToolTipRenderer != null && (Focused && toolTipTimer < ToolTipFadeTime) || (!Focused && toolTipTimer > 0.0f))
131  {
132  // Calculate the new time delta
133  toolTipTimer = toolTipTimer + (Focused ? Time.deltaTime : -Time.deltaTime);
134 
135  // Stop the timer if it exceeds the limit. Clamp doesn't work here since time can be outside the normal range in some situations
136  if (Focused && toolTipTimer > ToolTipFadeTime)
137  {
138  toolTipTimer = ToolTipFadeTime;
139  }
140  else if (!Focused && toolTipTimer < 0.0f)
141  {
142  toolTipTimer = 0.0f;
143  }
144 
145  // Update the new opacity
146  if (ToolTipRenderer != null)
147  {
148  Color tipColor = cachedToolTipMaterial.GetColor(colorPropertyId);
149  tipColor.a = Mathf.Clamp(toolTipTimer, 0, ToolTipFadeTime) / ToolTipFadeTime;
150  cachedToolTipMaterial.SetColor(colorPropertyId, tipColor);
151  }
152  }
153  }
154 
155  public void DehydrateButton()
156  {
157  if (ButtonAnimator != null && ButtonAnimator.isInitialized)
158  {
159  if (animatorHashes == null)
160  {
161  animatorHashes = ButtonAnimator.parameters;
162  }
163 
164  for (int i = 0; i < animatorHashes.Length; i++)
165  {
166  if (animatorHashes[i].nameHash == dehydrateButtonId)
167  {
168  ButtonAnimator.SetTrigger(dehydrateButtonId);
169  }
170  }
171  }
172  }
173 
174  // Child classes can override to update button visuals
175  protected virtual void UpdateVisuals()
176  {
177  }
178 
179  private void UpdateButtonAnimation()
180  {
181  if (ButtonAnimator != null && ButtonAnimator.gameObject.activeInHierarchy)
182  {
183  if (animatorHashes == null)
184  {
185  animatorHashes = ButtonAnimator.parameters;
186  }
187 
188  for (int i = 0; i < animatorHashes.Length; i++)
189  {
190  if (animatorHashes[i].nameHash == focusedButtonId)
191  {
192  ButtonAnimator.SetBool(focusedButtonId, Focused);
193  }
194 
195  if (animatorHashes[i].nameHash == selectedButtonId)
196  {
197  ButtonAnimator.SetBool(selectedButtonId, Selected);
198  }
199 
200  if (animatorHashes[i].nameHash == stayFocusedButtonId)
201  {
202  ButtonAnimator.SetBool(stayFocusedButtonId, StayFocused);
203  }
204  }
205  }
206  }
207 
208  public void OnInputClicked(InputClickedEventData eventData)
209  {
210  if (!EnableActivation)
211  {
212  return;
213  }
214 
215  Selected = !Selected;
216 
217  if (Activated != null)
218  {
219  Activated(this);
220  }
221 
222  eventData.Use(); // Mark the event as used, so it doesn't fall through to other handlers.
223  }
224 
225  public void OnFocusEnter()
226  {
227  Focused = true;
228 
229  // The first time the button is focused and the timer hasn't started, start the timer in a delayed mode
230  if (Focused && toolTipTimer == 0.0f)
231  {
232  toolTipTimer = -ToolTipDelayTime;
233  }
234 
235  UpdateVisuals();
236  }
237 
238  public void OnFocusExit()
239  {
240  Focused = false;
241 
242  UpdateVisuals();
243  }
244 
245  private void OnDestroy()
246  {
247  DestroyImmediate(cachedToolTipMaterial);
248  }
249  }
250 }
void OnInputClicked(InputClickedEventData eventData)
Definition: TestButton.cs:208
Interface to implement to react to simple click input.
Test button that can be added to any object to make it gaze interactable and receive pressed and rele...
Definition: TestButton.cs:13
Interface to implement to react to focus enter/exit.
Definition: IFocusable.cs:11
Describes an input event that involves a tap.