using System; using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.EventSystems; using UnityEngine.UI; namespace SC.XR.Unity.Module_Keyboard { public class SCKeyboard3DMono : SCKeyboardMono { #region Initialize public override void Initialize(SCKeyboardType keyboardType = SCKeyboardType.Default) { base.Initialize(keyboardType); ActiveKeyboard(KeyboardEnum.ABC,KeyboardState.Cn); } #endregion #region Keyboards protected SCKeyboard3DPrompt Keyboard3DPrompt { get { return keyboard_prompt as SCKeyboard3DPrompt; } } public GameObject keyboard_number; #endregion #region Key Clicks public override void OnPinyinKeyClick(string value) { preInputStringBuilder.Append(value); ActiveKeyboard(KeyboardEnum.Prompt); Keyboard3DPrompt.SetEnteredText(preInputStringBuilder.ToString()); PinyinKeyHandler(preInputStringBuilder.ToString()); } public override void OnPromptKeyClick(string value) { base.OnPromptKeyClick(value); HideKeyboardPrompt(false); } #endregion #region SpecialKeyClickEvents public override void OnABCClick() { ActiveKeyboard(KeyboardEnum.ABC, presentKeyboardState); } public override void OnDeleteClick() { OnWebKeyClick?.Invoke("Backspace"); if (keyboard_prompt.isActiveAndEnabled) { preInputStringBuilder.Remove(preInputStringBuilder.Length - 1, 1); if (preInputStringBuilder.Length == 0) { Keyboard3DPrompt.gameObject.SetActive(false); preInputStringBuilder.Clear(); return; } Keyboard3DPrompt.SetEnteredText(preInputStringBuilder.ToString()); PinyinKeyHandler(preInputStringBuilder.ToString()); } else { OnDeleteKeyClick?.Invoke(); } } public override void OnLanguageClick() { } private string[] cnSymbols = new string[40] { ",", "。", "?", "”" , "!", "@", "#", "¥", "%", "&", "(", ")", "-", "_", "=", "+", "\\", ";", ":", "、", "*", "/", "“", "”", "...", "·", "μ", "Σ", "《", "》", "【", "】", "{", "}", "|", "¢", "η", "°", "~", "……"}; private string[] enSymbols = new string[40] { ",", ".", "?", "'" , "!","@","#","$","%","&","(",")","-","_","=","+","\\",";",":","\"","*","/", "·", "¢", "∈", "£", "μ", "Σ", "<", ">", "[", "]", "{", "}", "|", "", "η", "°", "~", "^"}; public override void OnCnClick() { HideKeyboardPrompt(); //presentKeyboardState = KeyboardState.En; for (int i = 0; i < 4; i++) { if (symbolKeysDic.ContainsKey(cnSymbols[i])) { for (int j = 0; j < symbolKeysDic[cnSymbols[i]].Count; j++) { symbolKeysDic[cnSymbols[i]][j].Value = enSymbols[i]; symbolKeysDic[cnSymbols[i]][j].GetComponentInChildren().text = enSymbols[i]; } } } for (int i = 4; i < 22; i++) { if (symbolKeysDic.ContainsKey(cnSymbols[i])) { for (int j = 0; j < symbolKeysDic[cnSymbols[i]].Count; j++) { symbolKeysDic[cnSymbols[i]][j].Value = enSymbols[i]; symbolKeysDic[cnSymbols[i]][j].GetComponentInChildren().text = enSymbols[i]; } } } } public override void OnEnClick() { //presentKeyboardState = KeyboardState.Cn; for (int i = 0; i < 4; i++) { if (symbolKeysDic.ContainsKey(cnSymbols[i])) { for (int j = 0; j < symbolKeysDic[cnSymbols[i]].Count; j++) { symbolKeysDic[cnSymbols[i]][j].Value = cnSymbols[i]; symbolKeysDic[cnSymbols[i]][j].GetComponentInChildren().text = cnSymbols[i]; } } } for (int i = 4; i < 22; i++) { if (symbolKeysDic.ContainsKey(cnSymbols[i])) { for (int j = 0; j < symbolKeysDic[cnSymbols[i]].Count; j++) { symbolKeysDic[cnSymbols[i]][j].Value = cnSymbols[i]; symbolKeysDic[cnSymbols[i]][j].GetComponentInChildren().text = cnSymbols[i]; } } } } public override void OnPageDownClick() { if (presentKeyboard == keyboard_number) { switch (presentKeyboardState) { case KeyboardState.Cn: for (int i = 4; i < 22; i++) { if (symbolKeysDic.ContainsKey(cnSymbols[i])) { for (int j = 0; j < symbolKeysDic[cnSymbols[i]].Count; j++) { symbolKeysDic[cnSymbols[i]][j].Value = cnSymbols[i + 18]; symbolKeysDic[cnSymbols[i]][j].GetComponentInChildren().text = cnSymbols[i + 18]; } } } break; case KeyboardState.En: for (int i = 4; i < 22; i++) { if (symbolKeysDic.ContainsKey(cnSymbols[i])) { for (int j = 0; j < symbolKeysDic[cnSymbols[i]].Count; j++) { symbolKeysDic[cnSymbols[i]][j].Value = enSymbols[i]; symbolKeysDic[cnSymbols[i]][j].GetComponentInChildren().text = enSymbols[i + 18]; } } } break; } } } public override void OnPageUpClick() { if (presentKeyboard == keyboard_number) { switch (presentKeyboardState) { case KeyboardState.Cn: for (int i = 4; i < 22; i++) { if (symbolKeysDic.ContainsKey(cnSymbols[i])) { for (int j = 0; j < symbolKeysDic[cnSymbols[i]].Count; j++) { symbolKeysDic[cnSymbols[i]][j].Value = cnSymbols[i]; symbolKeysDic[cnSymbols[i]][j].GetComponentInChildren().text = cnSymbols[i]; } } } break; case KeyboardState.En: for (int i = 4; i < 22; i++) { if (symbolKeysDic.ContainsKey(cnSymbols[i])) { for (int j = 0; j < symbolKeysDic[cnSymbols[i]].Count; j++) { symbolKeysDic[cnSymbols[i]][j].Value = enSymbols[i]; symbolKeysDic[cnSymbols[i]][j].GetComponentInChildren().text = enSymbols[i]; } } } break; } } } #endregion #region Language Key Click Events public override void OnChineseClick() { } public override void OnEnglishClick() { ActiveKeyboard(KeyboardEnum.ABC,KeyboardState.En); } public override void OnMoreClick() { } #endregion #region Key Handlers private Text m_font; private RectTransform m_PromptPage; private RectTransform m_MorePromptPage; public Text Font { get { if (m_font == null) { m_font = Resources.Load(keyPath).GetComponentInChildren(); } return m_font; } } public RectTransform PromptPage { get { if (m_PromptPage == null) { m_PromptPage = Keyboard3DPrompt.promptInput; } return m_PromptPage; } } private int maxChineseWordCount; private static int currentChineseWordIndex = 0; public virtual void GenerateChinesePages(int page) { if (chinesePagesDic.ContainsKey(page)) { HideAllPromptPages(); foreach (int row in chinesePagesDic[page].Keys) { foreach (int word in chinesePagesDic[page][row].Keys) { SCKeyboardBaseKey key = promptPagesDic[0][row][word]; string text = chinesePagesDic[page][row][word]; key.Value = text; key.gameObject.SetActive(true); } } StartCoroutine(RebuildLayout(PromptPage)); } else { GenerateChineseKeys(); } } private void GenerateChineseKeys() { HideAllPromptPages(); maxChineseWordCount = Keyboard3DPrompt.GetChinese(preInputStringBuilder.ToString()); currentChineseWordIndex = 0; GenerateChineseKeys(0, PromptPage, new List()); StartCoroutine(RebuildLayout(PromptPage)); } private void GenerateChineseKeys(int keyIndex, RectTransform promptRow, List messages) { if (currentChineseWordIndex > maxChineseWordCount - 1) { return; } if (!promptPagesDic.ContainsKey(0)) promptPagesDic[0] = new Dictionary>(); if (!promptPagesDic[0].ContainsKey(0)) promptPagesDic[0][0] = new Dictionary(); if (!chinesePagesDic.ContainsKey(0)) chinesePagesDic[0] = new Dictionary>(); if (!chinesePagesDic[0].ContainsKey(0)) chinesePagesDic[0][0] = new Dictionary(); SCKeyboard2DKey promptKey; string text = Keyboard3DPrompt.GetChinese(currentChineseWordIndex); if (promptPagesDic[0][0].ContainsKey(keyIndex)) { promptKey = promptPagesDic[0][0][keyIndex] as SCKeyboard2DKey; promptKey.Value = text; messages.Add(promptKey.Value); if (!WithinTheLimits(messages, promptRow.GetComponent(), promptRow.sizeDelta.x)) { promptKey.gameObject.SetActive(false); return; } promptKey.gameObject.SetActive(true); chinesePagesDic[0][0][keyIndex] = text; } else { promptKey = InstantiateKey(keyPath, promptRow, text); messages.Add(promptKey.Value); promptPagesDic[0][0][keyIndex] = promptKey; if (!WithinTheLimits(messages, promptRow.GetComponent(), promptRow.sizeDelta.x)) { promptKey.gameObject.SetActive(false); return; } promptKey.gameObject.SetActive(true); chinesePagesDic[0][0][keyIndex] = text; } //Debug.Log("promptKey [ " + promptKey.Value + " ] :" + currentChineseWordIndex); currentChineseWordIndex++; GenerateChineseKeys(keyIndex + 1, promptRow, messages); } private void HidePromptPage(int page) { if (promptPagesDic.ContainsKey(page)) { foreach (var rowIndex in promptPagesDic[page].Keys) { foreach (var keyIndex in promptPagesDic[page][rowIndex].Keys) { promptPagesDic[page][rowIndex][keyIndex].gameObject.SetActive(false); } } } } private void HideAllPromptPages() { HidePromptPage(0); } IEnumerator RebuildLayout(RectTransform rect) { yield return new WaitForEndOfFrame(); LayoutRebuilder.ForceRebuildLayoutImmediate(rect); } public override void PinyinKeyHandler(string preInput) { chinesePagesDic = new Dictionary>>(); GenerateChinesePages(0); } private SCKeyboard2DKey InstantiateKey(string path, Transform parent, string value) { SCKeyboard2DKey prefab = Resources.Load(path); SCKeyboard2DKey promptKey = GameObject.Instantiate(prefab); promptKey.transform.SetParent(parent); promptKey.transform.localPosition = Vector3.zero; promptKey.transform.localRotation = Quaternion.identity; promptKey.transform.localScale = Vector3.one; promptKey.Value = value; return promptKey; } private bool WithinTheLimits(List messages, HorizontalLayoutGroup group, float LimitWidth) { float rectWidth = LimitWidth; float totalWidth = 0; float left = group.padding.left; float right = group.padding.right; float space = group.spacing; float width = 0; int wordCount = messages.Count; string message = ""; for (int i = 0; i < messages.Count; i++) { message += messages[i]; width += 12; } width += KeyboardUtils.CaculateTextLength(message, Font) / 10; totalWidth = (wordCount - 1) * space + left + width; return totalWidth <= rectWidth; } #endregion #region Active Keyboards protected override void ActiveKeyboard(KeyboardEnum keyboardEnum,KeyboardState keyboardState = KeyboardState.En) { base.ActiveKeyboard(keyboardEnum, keyboardState); switch (keyboardEnum) { case KeyboardEnum.ABC: OnActiveABCKeyboard(keyboardState); break; case KeyboardEnum.Number: OnActiveNumberKeyboard(); break; case KeyboardEnum.Prompt: OnActivePromptKeyboard(); break; } } public void OnActiveABCKeyboard(KeyboardState keyboardState) { if (presentKeyboard != null) previousKeyboard = presentKeyboard; keyboard_abc.SetActive(true); HideKeyboardPrompt(); presentKeyboard = keyboard_abc; if (previousKeyboard != null && previousKeyboard != presentKeyboard) previousKeyboard.SetActive(false); presentKeyboardState = keyboardState; } public void OnActiveNumberKeyboard() { if (presentKeyboard != null) previousKeyboard = presentKeyboard; keyboard_number.SetActive(true); HideKeyboardPrompt(); presentKeyboard = keyboard_number; if (previousKeyboard != null && previousKeyboard != presentKeyboard) previousKeyboard.SetActive(false); } public void OnActivePromptKeyboard() { Keyboard3DPrompt.gameObject.SetActive(true); } protected override void HideKeyboardPrompt(bool inputPreString = true) { if (keyboard_prompt.isActiveAndEnabled) { if (inputPreString) OnNormalKeyClick(preInputStringBuilder.ToString()); preInputStringBuilder.Clear(); Keyboard3DPrompt.gameObject.SetActive(false); } } #endregion } }