42 public event EventHandler OnTextSubmitted = delegate { };
48 public event Action<string> OnTextUpdated = delegate { };
54 public event EventHandler OnClosed = delegate { };
61 public event EventHandler OnPrevious = delegate { };
68 public event EventHandler OnNext = delegate { };
73 public event EventHandler OnPlacement = delegate { };
82 public InputField InputField = null;
92 public bool SliderEnabled =
true;
97 public bool SubmitOnEnter =
true;
102 public Image AlphaKeyboard = null;
112 public Image AlphaSubKeys = null;
117 public Image AlphaWebKeys = null;
122 public Image AlphaMailKeys = null;
129 [Header(
"Positioning")]
131 private float m_MaxScale = 1.0f;
137 private float m_MinScale = 1.0f;
143 private float m_MaxDistance = 3.5f;
149 private float m_MinDistance = 0.25f;
154 public bool CloseOnInactivity =
true;
159 public float CloseOnInactivityTime = 15;
164 private float _closingTime;
169 public event Action<bool> OnKeyboardShifted = delegate { };
174 private bool m_IsShifted =
false;
179 private bool m_IsCapslocked =
false;
184 public bool IsShifted
186 get {
return m_IsShifted; }
192 public bool IsCapsLocked
194 get {
return m_IsCapslocked; }
200 private int m_CaretPosition = 0;
205 private Vector3 m_StartingScale = Vector3.one;
210 private Vector3 m_ObjectBounds;
215 private Color _defaultColor;
220 private Image _recordImage;
225 private AudioSource _audioSource;
234 m_StartingScale = transform.localScale;
235 Bounds canvasBounds = RectTransformUtility.CalculateRelativeRectTransformBounds(transform);
237 RectTransform rect = GetComponent<RectTransform>();
238 m_ObjectBounds =
new Vector3(canvasBounds.size.x * rect.localScale.x, canvasBounds.size.y * rect.localScale.y, canvasBounds.size.z * rect.localScale.z);
242 if (dictationButton != null)
244 var dictationIcon = dictationButton.Find(
"keyboard_closeIcon");
245 if (dictationIcon != null)
247 _recordImage = dictationIcon.GetComponentInChildren<Image>();
248 var material =
new Material(_recordImage.material);
249 _defaultColor = material.color;
250 _recordImage.material = material;
256 InputField.keyboardType = (TouchScreenKeyboardType)(
int.MaxValue);
259 gameObject.SetActive(
false);
269 InputField.onValueChanged.AddListener(DoTextUpdated);
277 private void DoTextUpdated(
string value)
279 if (OnTextUpdated != null)
281 OnTextUpdated(value);
288 private void LateUpdate()
293 Vector3 nearPoint = Vector3.ProjectOnPlane(
CameraCache.
Main.transform.forward, transform.forward);
294 Vector3 relPos = transform.InverseTransformPoint(nearPoint);
297 CheckForCloseOnInactivityTimeExpired();
300 private void UpdateCaretPosition(
int newPos)
302 InputField.caretPosition = newPos;
308 private void OnDisable()
337 m_CaretPosition = InputField.caretPosition;
339 InputField.text = InputField.text.Insert(m_CaretPosition, text);
340 m_CaretPosition += text.Length;
342 UpdateCaretPosition(m_CaretPosition);
354 SetMicrophoneDefault();
370 if (IsMicrophoneActive())
377 #region Present Functions 385 gameObject.SetActive(
true);
388 OnPlacement(
this, EventArgs.Empty);
391 InputField.ActivateInputField();
393 SetMicrophoneDefault();
405 InputField.text = startText;
415 ActivateSpecificKeyboard(keyboardType);
425 PresentKeyboard(startText);
426 ActivateSpecificKeyboard(keyboardType);
429 #endregion Present Functions 430 public void RepositionKeyboard(Vector3 kbPos,
float verticalOffset = 0.0f)
437 transform.position = kbPos;
439 LookAtTargetOrigin();
448 public void RepositionKeyboard(Transform objectTransform, BoxCollider aCollider = null,
float verticalOffset = 0.0f)
450 transform.position = objectTransform.position;
452 if (aCollider != null)
454 float yTranslation = -((aCollider.bounds.size.y * 0.5f) + verticalOffset);
455 transform.Translate(0.0f, yTranslation, -0.6f, objectTransform);
459 float yTranslation = -((m_ObjectBounds.y * 0.5f) + verticalOffset);
460 transform.Translate(0.0f, yTranslation, -0.6f, objectTransform);
464 LookAtTargetOrigin();
470 private void ScaleToSize()
472 float distance = (transform.position -
CameraCache.
Main.transform.position).magnitude;
473 float distancePercent = (distance - m_MinDistance) / (m_MaxDistance - m_MinDistance);
474 float scale = m_MinScale + (m_MaxScale - m_MinScale) * distancePercent;
476 scale = Mathf.Clamp(scale, m_MinScale, m_MaxScale);
477 transform.localScale = m_StartingScale * scale;
479 Debug.LogFormat(
"Setting scale: {0} for distance: {1}", scale, distance);
485 private void LookAtTargetOrigin()
488 transform.Rotate(Vector3.up, 180.0f);
495 private void ActivateSpecificKeyboard(
LayoutType keyboardType)
497 DisableAllKeyboards();
498 ResetKeyboardState();
500 switch (keyboardType)
505 TryToShowURLSubkeys();
512 TryToShowEmailSubkeys();
518 ShowSymbolKeyboard();
526 TryToShowAlphaSubkeys();
532 #region Keyboard Functions 539 private void BeginDictation()
543 SetMicrophoneRecording();
546 private bool IsMicrophoneActive()
548 var result = _recordImage.color != _defaultColor;
555 private void SetMicrophoneDefault()
557 _recordImage.color = _defaultColor;
563 private void SetMicrophoneRecording()
565 _recordImage.color = Color.red;
574 SetMicrophoneDefault();
589 if (m_IsShifted && !
string.IsNullOrEmpty(valueKey.
ShiftValue))
595 value = valueKey.
Value;
603 m_CaretPosition = InputField.caretPosition;
605 InputField.text = InputField.text.Insert(m_CaretPosition, value);
606 m_CaretPosition += value.Length;
608 UpdateCaretPosition(m_CaretPosition);
634 ActivateSpecificKeyboard(m_LastKeyboardLayout);
664 if (IsMicrophoneActive())
683 CapsLock(!m_IsCapslocked);
701 Debug.LogErrorFormat(
"The {0} key on this keyboard hasn't been assigned a function.", functionKey.name);
706 throw new ArgumentOutOfRangeException();
716 if (InputField.selectionFocusPosition != InputField.caretPosition || InputField.selectionAnchorPosition != InputField.caretPosition)
718 if (InputField.selectionAnchorPosition > InputField.selectionFocusPosition)
720 InputField.text = InputField.text.Substring(0, InputField.selectionFocusPosition) + InputField.text.Substring(InputField.selectionAnchorPosition);
721 InputField.caretPosition = InputField.selectionFocusPosition;
725 InputField.text = InputField.text.Substring(0, InputField.selectionAnchorPosition) + InputField.text.Substring(InputField.selectionFocusPosition);
726 InputField.caretPosition = InputField.selectionAnchorPosition;
729 m_CaretPosition = InputField.caretPosition;
730 InputField.selectionAnchorPosition = m_CaretPosition;
731 InputField.selectionFocusPosition = m_CaretPosition;
735 m_CaretPosition = InputField.caretPosition;
737 if (m_CaretPosition > 0)
740 InputField.text = InputField.text.Remove(m_CaretPosition, 1);
741 UpdateCaretPosition(m_CaretPosition);
751 OnPrevious(
this, EventArgs.Empty);
759 OnNext(
this, EventArgs.Empty);
771 if (OnTextSubmitted != null)
773 OnTextSubmitted(
this, EventArgs.Empty);
780 string enterString =
"\n";
782 m_CaretPosition = InputField.caretPosition;
784 InputField.text = InputField.text.Insert(m_CaretPosition, enterString);
785 m_CaretPosition += enterString.Length;
787 UpdateCaretPosition(m_CaretPosition);
796 public void Shift(
bool newShiftState)
798 m_IsShifted = newShiftState;
799 OnKeyboardShifted(m_IsShifted);
801 if (m_IsCapslocked && !newShiftState)
803 m_IsCapslocked =
false;
813 m_IsCapslocked = newCapsLockState;
814 Shift(newCapsLockState);
822 m_CaretPosition = InputField.caretPosition;
823 InputField.text = InputField.text.Insert(m_CaretPosition++,
" ");
825 UpdateCaretPosition(m_CaretPosition);
833 string tabString =
"\t";
835 m_CaretPosition = InputField.caretPosition;
837 InputField.text = InputField.text.Insert(m_CaretPosition, tabString);
838 m_CaretPosition += tabString.Length;
840 UpdateCaretPosition(m_CaretPosition);
848 m_CaretPosition = InputField.caretPosition;
850 if (m_CaretPosition > 0)
853 UpdateCaretPosition(m_CaretPosition);
862 m_CaretPosition = InputField.caretPosition;
864 if (m_CaretPosition < InputField.text.Length)
867 UpdateCaretPosition(m_CaretPosition);
877 if (IsMicrophoneActive())
881 SetMicrophoneDefault();
882 OnClosed(
this, EventArgs.Empty);
883 gameObject.SetActive(
false);
891 ResetKeyboardState();
892 InputField.MoveTextStart(
false);
893 InputField.text =
"";
894 m_CaretPosition = InputField.caretPosition;
910 m_MinScale = minScale;
911 m_MaxScale = maxScale;
912 m_MinDistance = minDistance;
913 m_MaxDistance = maxDistance;
916 #region Keyboard Layout Modes 923 AlphaKeyboard.gameObject.SetActive(
true);
931 private bool TryToShowAlphaSubkeys()
933 if (AlphaKeyboard.IsActive())
935 AlphaSubKeys.gameObject.SetActive(
true);
948 private bool TryToShowEmailSubkeys()
950 if (AlphaKeyboard.IsActive())
952 AlphaMailKeys.gameObject.SetActive(
true);
966 private bool TryToShowURLSubkeys()
968 if (AlphaKeyboard.IsActive())
970 AlphaWebKeys.gameObject.SetActive(
true);
985 SymbolKeyboard.gameObject.SetActive(
true);
991 private void DisableAllKeyboards()
993 AlphaKeyboard.gameObject.SetActive(
false);
994 SymbolKeyboard.gameObject.SetActive(
false);
996 AlphaWebKeys.gameObject.SetActive(
false);
997 AlphaMailKeys.gameObject.SetActive(
false);
998 AlphaSubKeys.gameObject.SetActive(
false);
1004 private void ResetKeyboardState()
1009 #endregion Keyboard Layout Modes 1014 private void IndicateActivity()
1017 if (_audioSource == null)
1019 _audioSource = GetComponent<AudioSource>();
1021 if (_audioSource != null)
1023 _audioSource.Play();
1030 private void ResetClosingTime()
1032 if (CloseOnInactivity)
1034 _closingTime = Time.time + CloseOnInactivityTime;
1041 private void CheckForCloseOnInactivityTimeExpired()
1043 if (Time.time > _closingTime && CloseOnInactivity)