diff Orchestland/Assets/LeapMotion/Widgets/Scripts/Dial/DialGraphics.cs @ 1:f7675884f2a1

Add Orchestland project
author Daiki OYAKAWA <e135764@ie.u-ryukyu.ac.jp>
date Fri, 17 Jul 2015 23:09:20 +0900
parents
children
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Orchestland/Assets/LeapMotion/Widgets/Scripts/Dial/DialGraphics.cs	Fri Jul 17 23:09:20 2015 +0900
@@ -0,0 +1,253 @@
+using UnityEngine;
+using System;
+using System.Collections;
+using System.Collections.Generic;
+using UnityEngine.UI;
+
+namespace LMWidgets
+{
+	public class DialGraphics : MonoBehaviour, AnalogInteractionHandler<int>, IDataBoundWidget<DialGraphics, string>
+  {
+    // Events to implement for AnalogInteraction Handler.
+    public event EventHandler<EventArg<int>> ChangeHandler;
+    public event EventHandler<EventArg<int>> StartHandler;
+    public event EventHandler<EventArg<int>> EndHandler;
+
+    protected DataBinderDial m_dataBinder;
+
+		private string m_currentDialValue; 
+		public string CurrentDialValue   
+		{
+			get 
+			{
+				return m_currentDialValue; 
+			}
+			set
+			{
+        int dialIndex = 0;
+
+        try { 
+          dialIndex = parseDialString(value); 
+        }
+        catch (ArgumentException e) { // Thrown if 'value' isn't a valid label;
+          Debug.LogException(e);
+          return;
+        }
+
+        m_currentDialValue = value;
+        CurrentDialInt = dialIndex;
+				DebugDisplayString = value;
+			}
+		}
+
+    private int m_currentDialInt;
+    public int CurrentDialInt
+    {
+      get 
+      {
+        return m_currentDialInt; 
+      }
+			set
+			{
+				if(m_currentDialInt != value){
+					SetPhysicsStep(value);
+				}
+				m_currentDialInt = value;
+				DebugDisplayInt = value;
+
+        try { 
+          m_currentDialValue = DialLabels[m_currentDialInt];
+        }
+        catch (System.ArgumentOutOfRangeException e ){
+          Debug.LogException(e);
+        }
+			}
+		}
+		
+		public string DebugDisplayString;
+		public int DebugDisplayInt;
+		
+		public List<string> DialLabels;
+    [SerializeField]
+		private float DialRadius = .07f;
+    [SerializeField]
+		private float LabelAngleRangeStart = 0f;
+    [SerializeField]
+		private float LabelAngleRangeEnd = 360f;
+    [SerializeField]
+		private Transform LabelPrefab;
+    [SerializeField]
+		private Transform DialPhysicsOffset;
+    /// <summary>
+    /// How far forward should the dial protrude from the panel.
+    /// </summary>
+    public float DialProtrudenceDistance;
+    [SerializeField]
+		private Transform DialPhysics;
+    [SerializeField]
+		private DialModeBase m_dialModeBase;
+    [SerializeField]
+		private Transform DialCenter;
+		private List<float> LabelAngles = new List<float>();
+		public Dictionary<string, float> DialLabelAngles = new Dictionary<string, float>();
+
+   		private bool m_isEngaged = false;
+		
+		public Color PickerColorInActive;
+		public Color PickerColorActive;
+		public Image PickerBoxImage;
+		
+		public HilightTextVolume hilightTextVolume;
+		public Color TextColor;
+
+    private int parseDialString (string valueString){
+      int index = -1;
+      
+	  index = DialLabels.IndexOf( valueString);
+
+      if (index == -1) {
+        throw new System.ArgumentException("valueString \"" + valueString + "\" is not a valid label.");
+      }
+
+      return index;
+	}
+
+    // Wrapper on top of setting value for IDataBoundWidget implementation.
+    public void SetWidgetValue(string value) {
+      if ( m_isEngaged ) { return; } // Don't update if it's being interacted with.
+      CurrentDialValue = value;
+    }
+
+
+    // Stop listening to any previous data binder and start listening to the new one.
+    public void RegisterDataBinder(DataBinder<DialGraphics, string> dataBinder) {
+      if (dataBinder == null) {
+        return;
+      }
+      
+      UnregisterDataBinder ();
+      m_dataBinder = dataBinder as DataBinderDial;
+      CurrentDialValue = m_dataBinder.GetCurrentData ();
+    }
+    
+    // Stop listening to any previous data binder.
+    public void UnregisterDataBinder() {
+      m_dataBinder = null;
+    }
+
+    void Awake() {
+      if (m_dialModeBase == null) {
+        m_dialModeBase = DialPhysics.GetComponent<DialModeBase> ();
+      }
+
+      if (m_dialModeBase == null) {
+        throw new System.NullReferenceException("Could not find DialModeBase on DialPhysics Object.");
+      }
+    }
+
+    /// <summary>
+    /// Move the physics and graphics components into the proper positions.
+    /// </summary>
+    private void setInitialPositions() {
+
+      /// This is a bit hacky, but we're ignoring the positions of the dial elements 
+      /// in the editor and assigning them programatically.
+      /// 
+      /// This is how I found it, but I'm tempted to take a 
+      /// "respect the editor" viewpoint for initial positions
+      /// when it comes to widgets in the future. - @Daniel
+
+      DialCenter.localPosition = new Vector3(0f, 0f, DialRadius + DialProtrudenceDistance);
+      DialPhysicsOffset.localPosition = new Vector3(-(DialRadius + DialProtrudenceDistance) * 10f, 0f, 0f);
+      hilightTextVolume.transform.localPosition += new Vector3(0, 0, DialProtrudenceDistance);
+    }
+    		
+		void Start () {
+      setInitialPositions();
+			
+		    generateAndLayoutLabels ();
+
+			if( m_dataBinder != null ) {
+				//Set the Dial value based on a string
+        CurrentDialValue = m_dataBinder.GetCurrentData();
+				SetPhysicsStep(CurrentDialInt);
+			}
+		}
+
+    private void generateAndLayoutLabels() {
+      float currentLayoutXAngle = LabelAngleRangeStart;
+      
+      for( int i=1; i<=DialLabels.Count; i++ ) {
+        Transform labelPrefab = Instantiate(LabelPrefab, DialCenter.transform.position, transform.rotation) as Transform;
+        labelPrefab.Rotate(currentLayoutXAngle, 0f, 0f);
+        LabelAngles.Add (-currentLayoutXAngle);     
+        labelPrefab.parent = DialCenter;
+        labelPrefab.localScale = new Vector3(1f, 1f, 1f);
+        Text labelText = labelPrefab.GetComponentInChildren<Text>();
+        labelText.text = DialLabels[i - 1];
+        DialLabelAngles.Add(DialLabels[i - 1], -currentLayoutXAngle);
+        labelText.transform.localPosition = new Vector3(0f, 0f, -DialRadius);
+        currentLayoutXAngle = ((Mathf.Abs(LabelAngleRangeStart) + Mathf.Abs(LabelAngleRangeEnd))/(DialLabels.Count)) * -i;
+      }
+
+      LabelPrefab.gameObject.SetActive(false); // Turn off the original prefab that was copied.
+    }
+		
+		void Update () {
+      updateGraphicsFromPhysicsDial ();
+
+			if(m_isEngaged == true){
+				if(m_dataBinder != null){
+          m_dataBinder.SetCurrentData(CurrentDialValue); //Set the Dial value based on an int
+				}
+
+				if(ChangeHandler != null){
+					ChangeHandler(this, new EventArg<int>( CurrentDialInt));
+				}
+			}
+		}
+
+    private void updateGraphicsFromPhysicsDial() {
+      Vector3 physicsRotation = new Vector3 (DialPhysics.localRotation.eulerAngles.y, 0f, 0f);
+      DialCenter.localEulerAngles = physicsRotation;
+		CurrentDialInt = m_dialModeBase.CurrentStep;
+			
+    }
+
+		public void HilightDial () {
+			m_isEngaged = true;
+			
+      if( StartHandler != null )  {	
+				StartHandler(this, new EventArg<int>(CurrentDialInt));
+			}
+
+			PickerBoxImage.color = PickerColorActive;
+		}
+		
+		public void UpdateDial (){
+			CurrentDialInt = m_dialModeBase.CurrentStep;
+			
+			
+      if(m_dataBinder != null){
+				//Set the Dial value based on a string
+				//make sure we are what the program thinks we are
+        m_dataBinder.SetCurrentData(CurrentDialValue);
+			}
+
+			if(EndHandler != null){
+				EndHandler(this, new EventArg<int>(CurrentDialInt));
+      }
+
+			m_isEngaged = false;
+			PickerBoxImage.color = PickerColorInActive;
+    }
+		
+		public void SetPhysicsStep(int newInt){
+      if (m_dialModeBase == null) {
+        m_dialModeBase = DialPhysics.GetComponent<DialModeBase>();
+      }
+			m_dialModeBase.CurrentStep = newInt;
+			
+		}
+	}
+}