AR Design
UBC EML collab with UBC SALA - visualizing IoT data in AR
CompoundButtonToggle.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 System;
5 using System.Reflection;
6 using UnityEngine;
7 using HoloToolkit.Unity;
8 
9 namespace HoloToolkit.Unity.Buttons
10 {
14  [RequireComponent(typeof(CompoundButton))]
15  public class CompoundButtonToggle : MonoBehaviour
16  {
17  [Tooltip("Toggle behavior")]
18  public ToggleBehaviorEnum Behavior = ToggleBehaviorEnum.OnTapped;
19 
20  [Tooltip("Profile to use when State is TRUE")]
23 
24  [Tooltip("Profile to use when State is FALSE")]
27 
28  [DropDownComponent(true)]
29  [Tooltip("Component to target - must inherit from ProfileButtonBase")]
30  public Component Target;
31 
35  private CompoundButton m_compButton;
36 
37  public bool State {
38  get {
39  return state;
40  }
41  set {
42  SetState(value);
43  }
44  }
45 
46  [SerializeField]
47  private bool state;
48 
52  private void OnEnable() {
53  m_compButton = GetComponent<CompoundButton>();
54 
55  // Force initial state setting
56  SetState(state, true);
57 
58  if (m_compButton != null)
59  m_compButton.StateChange += ButtonStateChange;
60  }
61 
65  private void OnDisable()
66  {
67  if (m_compButton != null)
68  m_compButton.StateChange -= ButtonStateChange;
69  }
70 
75  public void ButtonStateChange(ButtonStateEnum newState) {
76  if(newState == ButtonStateEnum.Pressed)
77  {
78  switch (Behavior)
79  {
80  default:
81  break;
82 
83  case ToggleBehaviorEnum.OnTapped:
84  State = !State;
85  break;
86 
87  }
88  }
89  else if(newState == ButtonStateEnum.ObservationTargeted || newState == ButtonStateEnum.Targeted)
90  {
91  switch (Behavior)
92  {
93  default:
94  break;
95 
96  case ToggleBehaviorEnum.OnFocus:
97  State = !State;
98  break;
99  }
100  }
101  }
102 
103  private void SetState (bool newState, bool force = false) {
104  if ((!force || !Application.isPlaying) && state == newState)
105  return;
106 
107  if (Target == null || OnProfile == null || OffProfile == null)
108  return;
109 
110  state = newState;
111 
112  // Get the profile field of the target component and set it to the on profile
113  // Store all icons in iconLookup via reflection
114 #if USE_WINRT
115  FieldInfo fieldInfo = Target.GetType().GetTypeInfo().GetField("Profile");
116 #else
117  FieldInfo fieldInfo = Target.GetType().GetField("Profile");
118 #endif
119  if (fieldInfo == null) {
120  Debug.LogError("Target component had no field type profile in CompoundButtonToggle");
121  return;
122  }
123 
124  fieldInfo.SetValue(Target, state ? OnProfile : OffProfile);
125 
126  if (Application.isPlaying) {
127  // Disable, then re-enable the target
128  // This will force the component to update itself
129  ((MonoBehaviour)Target).enabled = false;
130  ((MonoBehaviour)Target).enabled = true;
131  }
132  }
133 
134 #if UNITY_EDITOR
135  [UnityEditor.CustomEditor(typeof(CompoundButtonToggle))]
136  public class CustomEditor : MRTKEditor
137  {
138  protected override void DrawCustomFooter() {
140 
141  FieldInfo fieldInfo = null;
142  Type profileType = null;
143  if (toggle.Target == null) {
144  DrawError("Target must be set.");
145  return;
146  } else {
147 
148  fieldInfo = toggle.Target.GetType().GetField("Profile");
149 
150  if (fieldInfo == null) {
151  DrawError("Target component has no 'Profile' field - are you use this class inherits from ProfileButtonBase?");
152  return;
153  }
154 
155  GUIStyle labelStyle = new GUIStyle(UnityEditor.EditorStyles.label);
156  labelStyle.fontSize = 18;
157  labelStyle.fontStyle = FontStyle.Bold;
158 
159  profileType = fieldInfo.FieldType;
160  UnityEditor.EditorGUILayout.LabelField("Type: " + toggle.Target.GetType().Name + " / " + fieldInfo.FieldType.Name, labelStyle, GUILayout.MinHeight(24));
161 
162  }
163 
164  UnityEditor.EditorGUILayout.LabelField("Select on/off profiles of the type " + profileType.Name);
165  if (toggle.OnProfile == null) {
166  toggle.OnProfile = (ButtonProfile)fieldInfo.GetValue(toggle.Target);
167  }
168  if (toggle.OffProfile == null) {
169  toggle.OffProfile = toggle.OnProfile;
170  }
171  ButtonProfile onProfile = (ButtonProfile)UnityEditor.EditorGUILayout.ObjectField("On Profile", toggle.OnProfile, typeof(ButtonProfile), false);
172  ButtonProfile offProfile = (ButtonProfile)UnityEditor.EditorGUILayout.ObjectField("Off Profile", toggle.OffProfile, typeof(ButtonProfile), false);
173  if (onProfile.GetType() == profileType) {
174  toggle.OnProfile = onProfile;
175  }
176  if (offProfile.GetType() == profileType) {
177  toggle.OffProfile = offProfile;
178  }
179 
180  if (toggle.OnProfile.GetType() != profileType) {
181  DrawError("On profile object does not match type " + profileType.Name);
182  }
183  if (toggle.OffProfile.GetType() != profileType) {
184  DrawError("Off profile object does not match type " + profileType.Name);
185  }
186 
187  if (onProfile == offProfile) {
188  DrawWarning("Profiles are the same - toggle will have no effect");
189  }
190 
191  toggle.Behavior = (ToggleBehaviorEnum)UnityEditor.EditorGUILayout.EnumPopup("Toggle behavior", toggle.Behavior);
192  }
193  }
194 #endif
195  }
196 }
ButtonStateEnum
State enum for buttons.
Action< ButtonStateEnum > StateChange
Event to receive button state change.
Definition: Button.cs:61
Concrete version of Button class used with other CompoundButton scripts (e.g., CompoundButtonMesh) Al...
void ButtonStateChange(ButtonStateEnum newState)
Handle button pressed callback from button
The base class for all button profiles Inherit from this to create new button profile types ...
Class that can be used to toggle between to button profiles for any target component inheriting from ...