/// Modded by JCxYIS /// 20220328 using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.UI; using System; using UnityEngine.EventSystems; using Pvr_UnitySDKAPI; public class ImeDelegateImpl : ImeDelegateBase { public class TextComponent { public string text { get { return TextGetter.Invoke(); } set { TextSetter.Invoke(value); } } private Func TextGetter; private Action TextSetter; public static explicit operator TextComponent(InputField inputField) { TextComponent tc = new TextComponent(); tc.TextGetter = () => inputField.text; tc.TextSetter = str => inputField.text = str; return tc; } public static explicit operator TextComponent(Text text) { TextComponent tc = new TextComponent(); tc.TextGetter = () => text.text; tc.TextSetter = str => text.text = str; return tc; } } public TextComponent mText; public GameObject[] mKbdViews; public SGViewGather mKbdView; public ImeManager mManager; private Texture2D mTexture; private Vector2 mTextureSize = new Vector2(780,390); private Vector2 mPtKbd = new Vector2(); private SGClickTracker mTracker = new SGClickTracker(); //ImeDelegateBase public override void OnIMEShow(Vector2 vSize) { Debug.Log("sogou DelegateImpl OnIMEShow"); mTextureSize = vSize; Debug.Log("sogou DelegateImpl OnIMEShow, size = " + mTextureSize[0] + ":" + mTextureSize[1]); CreateTexture(vSize); mManager.Draw(mTexture); mKbdView.SetActive(true); } public override void OnIMEHide() { Debug.Log("sogou DelegateImpl OnIMEHide"); mKbdView.SetActive(false); } public override void OnIMECommit(string strCommit) { mText.text += strCommit; } public override void OnIMEKey(SGImeKey key) { switch (key) { case SGImeKey.KEYCODE_DEL: String strText = mText.text; mText.text = strText.Remove(strText.Length - 1); break; case SGImeKey.KEYCODE_ENTER: mText.text = ""; break; } } public override void OnIMEError(SGImeError nType, string strErr) { } //MonoBehaviour void Start() { mKbdView = new SGViewGather(mKbdViews); CreateTexture(mTextureSize); #if UNITY_EDITOR #else mKbdView.SetActive(false); #endif } void Update() { //Debug.Log("panel update"); CheckMouseEvent(); mManager.Draw(mTexture); } //other private void CreateTexture(Vector2 vSize) { if (mTexture) { return; } #if UNITY_EDITOR #else // Create a texture mTexture = new Texture2D((int)vSize.x, (int)vSize.y, TextureFormat.RGBA32, false); // Set point filtering just so we can see the pixels clearly mTexture.filterMode = FilterMode.Trilinear; // Call Apply() so it's actually uploaded to the GPU mTexture.Apply(); Debug.Log(" sogou DelegateImpl_kbd CreateTexture: texture created"); // Set texture onto cube //GameObject cube = GameObject.Find("Cube"); //cube.GetComponent().material.mainTexture = mTexture; // Set texture onto kbdview mKbdView.SetTexture(mTexture); #endif } private void DispatchMessageToAndroid(SGImeMotionEventType type, Vector2 pt) { if (null != mManager) { mManager.OnTouch(pt.x, pt.y, type); } } private void LogEvent(string prefix, PointerEventData eventData) { Debug.Log(prefix + ": " + eventData.pointerCurrentRaycast.gameObject.name + " x=" + eventData.position.x + ",y=" + eventData.position.y); } private void CheckMouseEvent() { if (Point2UV(mRay, ref mPtKbd)) { if (mTracker.Track(mPtKbd, Input.GetKeyDown(KeyCode.JoystickButton0) || Controller.UPvr_GetKeyClick(0, Pvr_KeyCode.TOUCHPAD) || Controller.UPvr_GetKeyClick(0, Pvr_KeyCode.TRIGGER) || Controller.UPvr_GetKeyClick(0, Pvr_KeyCode.X) || Controller.UPvr_GetKeyClick(1, Pvr_KeyCode.TOUCHPAD) || Controller.UPvr_GetKeyClick(1, Pvr_KeyCode.TRIGGER) || Controller.UPvr_GetKeyClick(1, Pvr_KeyCode.A))) { DispatchMessageToAndroid(mTracker.GetEvent(), mTracker.GetPoint()); } else if (mTracker.Track(mPtKbd, Controller.UPvr_GetKeyClick(0, Pvr_KeyCode.Y) || Controller.UPvr_GetKeyClick(1, Pvr_KeyCode.B) || Controller.UPvr_GetKeyClick(0, Pvr_KeyCode.APP) || Controller.UPvr_GetKeyClick(1, Pvr_KeyCode.APP))) { mManager.Hide(); } } else if (mTracker.TrackOuter() ) { DispatchMessageToAndroid(mTracker.GetEvent(), mTracker.GetPoint()); } } public Pvr_ControllerDemo_VRInput controller; private Ray mRay => controller ? controller.ray : PicoVRcontroller.Instance?.Ray ?? new Ray(); private bool Point2UV(Ray ray, ref Vector2 ptUV) { RaycastHit hitInfo; bool bRes = false; if (Physics.Raycast(ray, out hitInfo)) { string name = hitInfo.collider.gameObject.name; if (mKbdView.FindName(name)) { GameObject kbd = hitInfo.collider.gameObject; Vector3 vecKbd = kbd.transform.InverseTransformPoint(hitInfo.point); Vector2 pixelUV = hitInfo.textureCoord; Renderer rend = hitInfo.transform.GetComponent(); ptUV.x = pixelUV.x * mTextureSize.x; ptUV.y = (1 - pixelUV.y) * mTextureSize.y; //Debug.Log("ray click " + name + ": 3d point=" + vecKbd.ToString() + " uv=(" + pixelUV.x + "," + pixelUV.y + ") org=(" + ptUV.ToString() + ")" + " w=" + texSize.x + ",h=" + texSize.y); bRes = true; } } return bRes; } } public class SGViewGather { private GameObject[] mViews; public SGViewGather(GameObject[] param) { mViews = param; } public void SetActive(bool bActive) { foreach (GameObject view in mViews) { view.SetActive(bActive); } } public bool FindName(string name) { foreach (GameObject view in mViews) { if (view.name == name) { return true; } } return false; } public void SetTexture(Texture2D tex) { foreach (GameObject view in mViews) { Renderer rend = view.GetComponent(); rend.material.mainTexture = tex; } } } public class SGClickTracker { private bool mDownOld = false; private Vector2 mPtOld = new Vector2(); private SGImeMotionEventType mEvent; private const float mTrackRadius = 10.0f; private long mTimeDown; private bool mLongPressed = false; private long mIntervelLongPress = 100; public bool Track(Vector2 pt, bool bDown) { bool bRes = false; if (bDown) { if (mDownOld) { mEvent = SGImeMotionEventType.ACTION_MOVE; if (!mLongPressed) { long timeDiff = DateTime.Now.Ticks - mTimeDown; if (timeDiff > mIntervelLongPress) { mLongPressed = true; mEvent = SGImeMotionEventType.ACTION_LONGPRESS; bRes = true; //force sendmessage } } } else { mEvent = SGImeMotionEventType.ACTION_DOWN; mTimeDown = DateTime.Now.Ticks; mLongPressed = false; } } else { if (mDownOld) { mEvent = SGImeMotionEventType.ACTION_UP; } else { //mEvent = SGImeMotionEventType.ACTION_HOVER_MOVE; mEvent = SGImeMotionEventType.ACTION_MOVE; //c++代码只识别move事件 } } if (mDownOld != bDown) { bRes = true; } else if (PointDist(mPtOld, pt) > mTrackRadius) { bRes = true; } mDownOld = bDown; if (bRes) { mPtOld = pt; } return bRes; } public bool TrackOuter() { bool bRes = false; if (mEvent != SGImeMotionEventType.ACTION_OUTSIDE) { SGImeMotionEventType eventOld = mEvent; mEvent = SGImeMotionEventType.ACTION_OUTSIDE; } return bRes; } public Vector2 GetPoint() { return mPtOld; } public SGImeMotionEventType GetEvent() { return mEvent; } private float PointDist(Vector2 ptNew, Vector2 ptOld) { return Math.Abs(ptNew[0] - ptOld[0]) + Math.Abs(ptNew[1] - ptOld[1]); } }