private TouchStates GetTouchState(TouchStates touchState) { if (Input.touchCount != 0) { switch (touchState) { case TouchStates.Idle: touchState = TouchStates.Down; break; case TouchStates.Down: touchState = TouchStates.Hold; break; } } else { switch (touchState) { case TouchStates.Down: touchState = TouchStates.Up; break; case TouchStates.Hold: touchState = TouchStates.Up; break; case TouchStates.Up: touchState = TouchStates.Idle; break; } } return(touchState); }
/// <summary> /// Send a message out to any subcribed component that wants to receive an event trigger /// when a time threshold is exceeded for a finger being held down /// </summary> /// <param name="right">If true, it's a finger on the right hand, otherwise left</param> /// <param name="finger">Pointer, thumb, or index finger?</param> /// <param name="fingerIndex">A non-flag enumeration of the finger</param> /// <param name="startTime">The time in seconds when the hold began</param> /// <returns></returns> IEnumerator HoldThresholdTrigger(bool right, TouchStates finger, TouchStateIndex fingerIndex, float startTime) { yield return(new WaitUntil(() => (Time.time - startTime > holdActionThreshold))); if ((((right) ? rightHandState : leftHandState) & finger) != 0) { if (right) { rightHeldLong[(int)fingerIndex] = true; } else { leftHeldLong[(int)fingerIndex] = true; } HoldAction?.Invoke(right, fingerIndex); } }
// Update is called once per frame void Update () { if (Input.GetMouseButton(0) && GameManager.instance.m_CanPlay) { if (m_TouchStates == TouchStates.NOTOUCH) { m_TouchStates = TouchStates.TOUCHED; m_Trail = m_HypnoticPrefab.gameObject.GetComponent<PlaygroundTrails>(); m_Trail.lifetimeColor = Gradients[Random.Range(0, Gradients.Length + 1)]; m_HypnoticInstance = Instantiate(m_HypnoticPrefab, new Vector3(Input.mousePosition.x, Input.mousePosition.z,0), Quaternion.identity) as PlaygroundParticlesC; StartCoroutine(Effects()); Score.SetActive(true); } if(m_HypnoticInstance!=null) { Vector3 mousePos = Input.mousePosition; mousePos.z = +10; // we want 2m away from the camera position Vector3 objectPos = m_Camera.ScreenToWorldPoint(mousePos); m_HypnoticInstance.transform.position = objectPos; GameManager.instance.m_PlayerBusy = true; } } else { if(m_TouchStates == TouchStates.TOUCHED) { m_TouchStates = TouchStates.RELEASE; m_HypnoticInstance.gameObject.GetComponent<Animator>().SetTrigger("Destroy"); StartCoroutine(WaitForEnd()); } } }
private void Awake() { rightHandState = new TouchStates(); leftHandState = new TouchStates(); currentRightHandGestureState = HandGestureState.Neutral; currentLeftHandGestureState = HandGestureState.Neutral; currentRightRotationState = RotationState.lowerCase; currentLeftRotationState = RotationState.lowerCase; // track whether a currently held finger has passed the hold action threshold // index values match the order of the TouchStates enum rightHeldLong = new bool[3] { false, false, false }; leftHeldLong = new bool[3] { false, false, false }; _selectionRightStartingMarker = new GameObject("RightStartMarker"); _selectionLeftStartingMarker = new GameObject("LeftStartMarker"); }
void Update() { rawTouchXY = new Vector2(touchData.y, touchData.z); rawTouchState = (int)touchData.x; if ((prevRawTouchState == 0 || prevRawTouchState == 1) && rawTouchState == 2) { touchState = TouchStates.OnDown; } else if (prevRawTouchState == 2 && rawTouchState == 2) { touchState = TouchStates.Drag; } else if ((prevRawTouchState == 2 || prevRawTouchState == 1) && rawTouchState == 0) { touchState = TouchStates.OnUp; } else if (prevRawTouchState == 0 && rawTouchState == 0) { touchState = TouchStates.Up; } prevRawTouchState = rawTouchState; }
void Update() { //ADM.QLog("current right hand state: " + currentRightHandGestureState); //ADM.QLog("current left hand state: " + currentLeftHandGestureState); #region thumb if (OVRInput.GetDown(OVRInput.Touch.One, Controller.RTouch)) { ADM.QLog("Got right thumb touch."); rightHandState |= TouchStates.thumb; UpdateHandState(true); StartCoroutine(HoldThresholdTrigger(true, TouchStates.thumb, TouchStateIndex.thumb, Time.time)); } if (OVRInput.GetUp(OVRInput.Touch.One, Controller.RTouch)) { ADM.QLog("Got right thumb touch release."); rightHandState &= ~TouchStates.thumb; UpdateHandState(true); rightHeldLong[(int)TouchStateIndex.thumb] = false; RefreshHeldLongState?.Invoke(true, rightHeldLong); } if (OVRInput.GetDown(OVRInput.Touch.One, Controller.LTouch)) { ADM.QLog("Got left thumb touch."); leftHandState |= TouchStates.thumb; UpdateHandState(false); StartCoroutine(HoldThresholdTrigger(false, TouchStates.thumb, TouchStateIndex.thumb, Time.time)); } if (OVRInput.GetUp(OVRInput.Touch.One, Controller.LTouch)) { ADM.QLog("Got left thumb touch release."); leftHandState &= ~TouchStates.thumb; UpdateHandState(false); leftHeldLong[(int)TouchStateIndex.thumb] = false; RefreshHeldLongState?.Invoke(true, rightHeldLong); } #endregion thumb #region pointer if (OVRInput.GetDown(OVRInput.Touch.PrimaryIndexTrigger, Controller.LTouch)) { ADM.QLog("Got left index finger touch."); leftHandState |= TouchStates.pointer; UpdateHandState(false); StartCoroutine(HoldThresholdTrigger(false, TouchStates.pointer, TouchStateIndex.pointer, Time.time)); } if (OVRInput.GetUp(OVRInput.Touch.PrimaryIndexTrigger, Controller.LTouch)) { ADM.QLog("Got left index finger touch release."); leftHandState &= ~TouchStates.pointer; UpdateHandState(false); leftHeldLong[(int)TouchStateIndex.pointer] = false; RefreshHeldLongState?.Invoke(true, rightHeldLong); } if (OVRInput.GetDown(OVRInput.Touch.PrimaryIndexTrigger, Controller.RTouch)) { ADM.QLog("Got right index finger touch."); rightHandState |= TouchStates.pointer; UpdateHandState(true); StartCoroutine(HoldThresholdTrigger(true, TouchStates.pointer, TouchStateIndex.pointer, Time.time)); } if (OVRInput.GetUp(OVRInput.Touch.PrimaryIndexTrigger, Controller.RTouch)) { ADM.QLog("Got right index finger touch release."); rightHandState &= ~TouchStates.pointer; UpdateHandState(true); rightHeldLong[(int)TouchStateIndex.pointer] = false; RefreshHeldLongState?.Invoke(true, rightHeldLong); } #endregion pointer #region grip if (OVRInput.GetDown(OVRInput.Button.PrimaryHandTrigger, Controller.LTouch)) { ADM.QLog("Got left grip touch."); leftHandState |= TouchStates.middle; UpdateHandState(false); StartCoroutine(HoldThresholdTrigger(false, TouchStates.middle, TouchStateIndex.middle, Time.time)); } if (OVRInput.GetUp(OVRInput.Button.PrimaryHandTrigger, Controller.LTouch)) { ADM.QLog("Got left grip touch release."); leftHandState &= ~TouchStates.middle; UpdateHandState(false); leftHeldLong[(int)TouchStateIndex.middle] = false; RefreshHeldLongState?.Invoke(true, rightHeldLong); } if (OVRInput.GetDown(OVRInput.Button.PrimaryHandTrigger, Controller.RTouch)) { ADM.QLog("Got right grip touch."); rightHandState |= TouchStates.middle; UpdateHandState(true); StartCoroutine(HoldThresholdTrigger(true, TouchStates.middle, TouchStateIndex.middle, Time.time)); } if (OVRInput.GetUp(OVRInput.Button.PrimaryHandTrigger, Controller.RTouch)) { ADM.QLog("Got right grip touch release."); rightHandState &= ~TouchStates.middle; UpdateHandState(true); rightHeldLong[(int)TouchStateIndex.middle] = false; RefreshHeldLongState?.Invoke(true, rightHeldLong); } #endregion grip #region rotation if (currentRightHandGestureState == HandGestureState.DragSelection && ((Vector3.Dot(Vector3.up, RightMarker.Instance.transform.up) < 0.75f && currentRightRotationState == RotationState.lowerCase) || (Vector3.Dot(Vector3.up, RightMarker.Instance.transform.right) < 0.75f && currentRightRotationState == RotationState.upperCase) || (Vector3.Dot(Vector3.up, -1 * RightMarker.Instance.transform.right) < 0.75f && currentRightRotationState == RotationState.specialCharacters) || (Vector3.Dot(_selectionRightStartingMarker.transform.forward, RightMarker.Instance.transform.right) < 0.75f && currentRightRotationState == RotationState.numbers)) ) { // ADM.QLog("Right rotation state just changed."); UpdateRotationState(true); } if (currentLeftHandGestureState == HandGestureState.DragSelection && ((Vector3.Dot(Vector3.up, LeftMarker.Instance.transform.up) < 0.75f && currentLeftRotationState == RotationState.lowerCase) || (Vector3.Dot(Vector3.up, -1 * LeftMarker.Instance.transform.right) < 0.75f && currentLeftRotationState == RotationState.upperCase) || (Vector3.Dot(Vector3.up, LeftMarker.Instance.transform.right) < 0.75f && currentLeftRotationState == RotationState.specialCharacters) || (Vector3.Dot(_selectionLeftStartingMarker.transform.forward, -1 * LeftMarker.Instance.transform.right) < 0.75f && currentLeftRotationState == RotationState.numbers)) ) { // ADM.QLog("Left rotation state just changed."); UpdateRotationState(false); } #endregion rotation }
private IEnumerator InputUpdate() { while (true) { if (Input.GetKeyDown(jumpInput)) { rawTapInputEvent.Dispatch(); } if (Input.GetKeyDown(aimInput) && !InputHelper.CheckUICollision(Input.mousePosition)) { touchState = TouchStates.Tapped; startDownTime = Time.time; } if (touchState != TouchStates.None) { if (!Input.GetKeyUp(aimInput)) { if (Time.time - startDownTime > TimebeforeTappedExpired) { if (touchState == TouchStates.Tapped) { rawTappedExpiredInputEvent.Dispatch(); } if (Vector2.Distance(Camera.main.ScreenToWorldPoint(Input.mousePosition), transform.position) > minDistFromPlayer) { touchState = TouchStates.Dragging; Vector2 direction = ((Vector2)Camera.main.ScreenToWorldPoint(Input.mousePosition) - (Vector2)transform.position).normalized; rawDraggingInputEvent.Dispatch(direction); } else if (touchState != TouchStates.Holding) { if (touchState == TouchStates.Dragging) { rawCancelDragInputEvent.Dispatch(); } touchState = TouchStates.Holding; rawHoldingInputEvent.Dispatch(); } } } else { rawReleaseInputEvent.Dispatch(); if (touchState != TouchStates.Holding) { Vector2 direction = ((Vector2)Camera.main.ScreenToWorldPoint(Input.mousePosition) - (Vector2)transform.position).normalized; rawReleaseInDirectionInputEvent.Dispatch(direction); } touchState = TouchStates.None; } } yield return(null); } }
private IEnumerator InputUpdate() { while (true) { bool startedTouching = Input.touchCount > 0 && Input.GetTouch(0).phase == TouchPhase.Began; if (startedTouching && !InputHelper.CheckUICollision(Input.GetTouch(0).position)) { TouchState = TouchStates.Tapped; startTouchPosition = Input.GetTouch(0).position; touchDownTime = Time.time; } if (TouchState != TouchStates.None) { if (Input.GetTouch(0).phase != TouchPhase.Ended) { float timePassedSinceTouchDown = Time.time - touchDownTime; if (timePassedSinceTouchDown > TimebeforeTappedExpired) { if (TouchState == TouchStates.Tapped) { rawTappedExpiredInputEvent.Dispatch(); } Vector2 worldCurrentTouchPosition = Camera.main.ScreenToWorldPoint(Input.GetTouch(0).position); Vector2 worldStartTouchPosition = Camera.main.ScreenToWorldPoint(startTouchPosition); float dragDistance = Vector2.Distance(worldStartTouchPosition, worldCurrentTouchPosition); if (dragDistance > minimalDistanceToDrag) { joyStick.SetActive(true); joyStick.transform.position = new Vector3(worldStartTouchPosition.x, worldStartTouchPosition.y, -4); Vector2 direction = (Input.GetTouch(0).position - startTouchPosition).normalized; dragDirIndicator.SetDragDir(direction); TouchState = TouchStates.Dragging; rawDraggingInputEvent.Dispatch(direction); } else if (timePassedSinceTouchDown > TimebeforeTappedExpired && TouchState != TouchStates.Holding) { if (TouchState == TouchStates.Dragging) { rawCancelDragInputEvent.Dispatch(); } joyStick.SetActive(false); TouchState = TouchStates.Holding; rawHoldingInputEvent.Dispatch(); } } } else { rawReleaseInputEvent.Dispatch(); if (TouchState == TouchStates.Dragging) { joyStick.SetActive(false); Vector2 direction = (Input.GetTouch(0).position - startTouchPosition).normalized; rawReleaseInDirectionInputEvent.Dispatch(direction); } else if (TouchState == TouchStates.Tapped) { rawJumpInputEvent.Dispatch(); } TouchState = TouchStates.None; } } yield return(null); } }
public void Run(TouchEventArgs input, TouchStates touchState) { System.Diagnostics.Debug.WriteLine(string.Format("이전모드 : {0}, 터치포인트수 : {1}, 이미지 위에 있는가? : {2}", _PrevMode, _TouchCount, _IsOverImage)); switch (_PrevMode) { case InputMode.None: if (touchState == TouchStates.TU) { this.MoveToNext(InputMode.None); } else if ((_TouchCount == 1) && !this.IsPen && _IsOverImage && touchState != TouchStates.TU) { this.MoveToNext(InputMode.SelMovImg); } else if ((_TouchCount == 2) && !this.IsPen && _IsOverImage && touchState != TouchStates.TU) { this.MoveToNext(InputMode.TransImg); } else if ((_TouchCount == 1) && this.IsPen && touchState != TouchStates.TU) { this.MoveToNext(InputMode.Pen); } else if ((_TouchCount == 1) && !this.IsPen && !_IsOverImage && touchState != TouchStates.TU) { this.MoveToNext(InputMode.Erase); } else if ((_TouchCount == 2) && !this.IsPen && (!_IsOverImage || _IsOverLiner) && touchState != TouchStates.TU) { this.MoveToNext(InputMode.Ruler); } else if ((_TouchCount == 2) && this.IsPen && _IsOverLiner && touchState != TouchStates.TU) { this.MoveToNext(InputMode.Line); } else { Debug.WriteLine("Unexpected status change input"); } break; case InputMode.Pen: if (touchState == TouchStates.TU) { this.MoveToNext(InputMode.None); } else if ((_TouchCount == 1) && this.IsPen && touchState != TouchStates.TU) { this.MoveToNext(InputMode.Pen); } else if ((_TouchCount == 1) && !this.IsPen && _IsOverImage && touchState != TouchStates.TU) { this.MoveToNext(InputMode.SelMovImg); } else { Debug.WriteLine("Unexpected status change input"); } break; case InputMode.Erase: if (touchState == TouchStates.TU) { this.MoveToNext(InputMode.None); } else if ((_TouchCount == 1) && !this.IsPen && !_IsOverImage && touchState != TouchStates.TU) { this.MoveToNext(InputMode.Erase); } else if ((_TouchCount == 1) && !this.IsPen && _IsOverImage && touchState != TouchStates.TU) { this.MoveToNext(InputMode.SelMovImg); } else if ((_TouchCount == 2) && !this.IsPen && _IsOverImage && touchState != TouchStates.TU) { this.MoveToNext(InputMode.TransImg); } else if ((_TouchCount == 2) && !this.IsPen && (!_IsOverImage || _IsOverLiner) && touchState != TouchStates.TU) { this.MoveToNext(InputMode.Ruler); } else if ((_TouchCount == 2) && this.IsPen && _IsOverLiner && touchState != TouchStates.TU) { this.MoveToNext(InputMode.Line); } else { Debug.WriteLine("Unexpected status change input"); } break; case InputMode.SelMovImg: if (touchState == TouchStates.TU) { this.MoveToNext(InputMode.None); } //else if ((_TouchCount == 1) && this.IsPen && touchState != TouchStates.TU) //{ // this.MoveToNext(InputMode.Pen); //} else if ((_TouchCount == 1) && !this.IsPen && _IsOverImage && touchState != TouchStates.TU) { this.MoveToNext(InputMode.SelMovImg); } else if ((_TouchCount == 2) && !this.IsPen && _IsOverImage && touchState != TouchStates.TU) { this.MoveToNext(InputMode.TransImg); } else if ((_TouchCount == 2) && this.IsPen && _IsOverImage && touchState != TouchStates.TU) { this.MoveToNext(InputMode.Cut); } else { Debug.WriteLine("Unexpected status change input"); } break; case InputMode.TransImg: if (touchState == TouchStates.TU) { this.MoveToNext(InputMode.None); } else if ((_TouchCount == 1) && !this.IsPen && _IsOverImage && touchState != TouchStates.TU) { this.MoveToNext(InputMode.SelMovImg); } else if ((_TouchCount == 2) && !this.IsPen && _IsOverImage && touchState != TouchStates.TU) { this.MoveToNext(InputMode.TransImg); } else { Debug.WriteLine("Unexpected status change input"); } break; case InputMode.Cut: if (touchState == TouchStates.TU) { this.MoveToNext(InputMode.None); } else if ((_TouchCount == 2) && this.IsPen && _IsOverImage && touchState != TouchStates.TU) { this.MoveToNext(InputMode.Cut); } else { Debug.WriteLine("Unexpected status change input"); } break; case InputMode.Ruler: if (touchState == TouchStates.TU && !IsRuler) { this.MoveToNext(InputMode.None); } else if ((_TouchCount == 2) && !this.IsPen && (!_IsOverImage || _IsOverLiner) && touchState != TouchStates.TU) { this.MoveToNext(InputMode.Ruler); } else if (this.IsPen && touchState != TouchStates.TU) { // 직선 그리기 시작 this.MoveToNext(InputMode.Line); PenStartPoint = input.TouchDevice.GetTouchPoint(_Canvas); PenEndPoint = PenStartPoint; RaiseOnLineStarted(); } else { Debug.WriteLine("Unexpected status change input"); } break; case InputMode.Line: if (touchState == TouchStates.TU) { RaiseOnLineEnded(); this.MoveToNext(InputMode.Ruler); this.PenStartPoint = null; this.PenEndPoint = null; } else if (this.IsPen && touchState != TouchStates.TU && input.TouchDevice.Id == _modeRecognizer.PenDevID) { // 직선 움직이기 this.MoveToNext(InputMode.Line); PenEndPoint = input.TouchDevice.GetTouchPoint(_Canvas); Debug.WriteLine("End:({0},{1})", PenEndPoint.Position.X, PenEndPoint.Position.Y); RaiseOnLineMove(); } else { Debug.WriteLine("Unexpected status change input"); } break; default: break; } }
public void Update() { #if UNITY_EDITOR if (Input.GetKeyDown(KeyCode.A)) { ScaleMask(0.9f); } else if (Input.GetKeyDown(KeyCode.Z)) { ScaleMask(1.1f); } #endif /*if (Input.touchCount == 2) * { * var t1 = Input.GetTouch(0); * var p1 = new Vector2(t1.position.x, Screen.height - t1.position.y); * var t2 = Input.GetTouch(1); * var p2 = new Vector2(t2.position.x, Screen.height - t2.position.y); * if (_bounds.Contains(p1) && _bounds.Contains(p2)) * { * if (!_miDistanceInited) * { * _distanceBetweenFingers = Vector2.Distance(p1, p2); * _miDistanceInited = true; * } else * { * var newDistanse = Vector2.Distance(p1, p2); * ScaleMask(newDistanse/_distanceBetweenFingers); * _distanceBetweenFingers = newDistanse; * } * } * } else { * _miDistanceInited = false; * }*/ if (_state == TouchStates.none) { if (Input.touchCount == 1) { var t = Input.GetTouch(0); var p = new Vector2(t.position.x, Screen.height - t.position.y); if (t.phase == TouchPhase.Began && _bounds.Contains(p)) { _state = TouchStates.move; _startAngle = this.transform.localRotation.eulerAngles; _startPoint = p; _prev = p; _isRotating = true; } } else if (Input.touchCount == 2) { var t1 = Input.GetTouch(0); var p1 = new Vector2(t1.position.x, Screen.height - t1.position.y); var t2 = Input.GetTouch(1); var p2 = new Vector2(t2.position.x, Screen.height - t2.position.y); if ((t1.phase == TouchPhase.Began || t2.phase == TouchPhase.Began)) { _state = TouchStates.zoom; _distanceBetweenFingers = Vector2.Distance(p1, p2); } } } else if (_state == TouchStates.move) { if (Input.touchCount == 1) { var t = Input.GetTouch(0); var p = new Vector2(t.position.x, Screen.height - t.position.y); if (t.phase == TouchPhase.Ended) { _state = TouchStates.none; } else if (t.phase == TouchPhase.Moved && _bounds.Contains(p)) { RotateMask(p - _prev); _prev = p; } } else if (Input.touchCount == 2) { var t1 = Input.GetTouch(0); var p1 = new Vector2(t1.position.x, Screen.height - t1.position.y); var t2 = Input.GetTouch(1); var p2 = new Vector2(t2.position.x, Screen.height - t2.position.y); if ((t1.phase == TouchPhase.Began || t2.phase == TouchPhase.Began) && _bounds.Contains(p1) && _bounds.Contains(p2) ) { _state = TouchStates.zoom; _distanceBetweenFingers = Vector2.Distance(p1, p2); } } else { _state = TouchStates.none; } } else if (_state == TouchStates.zoom) { if (Input.touchCount == 2) { var t1 = Input.GetTouch(0); var p1 = new Vector2(t1.position.x, Screen.height - t1.position.y); var t2 = Input.GetTouch(1); var p2 = new Vector2(t2.position.x, Screen.height - t2.position.y); if (_bounds.Contains(p1) && _bounds.Contains(p2)) { var newDistanse = Vector2.Distance(p1, p2); ScaleMask(newDistanse / _distanceBetweenFingers); _distanceBetweenFingers = newDistanse; } } else { _state = TouchStates.none; } } }
IEnumerator WaitForEnd() { yield return new WaitForSeconds(6.5f); m_TouchStates = TouchStates.NOTOUCH; StopAllCoroutines(); GameManager.instance.m_PlayerBusy = false; }
public void Recognize(TouchEventArgs e, TouchStates touchState, bool isPen) { Debug.WriteLine("TOUCH mode : " + touchState); switch (_PrevTouchMode) { case TouchMode.None: if (touchState == TouchStates.TD) { MoveToNext(TouchMode.Single); if (isPen) { PenDevID = e.TouchDevice.Id; } } else { Debug.WriteLine("Unexpected TOUCH mode change from None: " + touchState); } break; case TouchMode.Single: if (touchState == TouchStates.TU) { MoveToNext(TouchMode.None); PenDevID = -1; } else if (touchState == TouchStates.TM) { MoveToNext(TouchMode.Single); } else if (touchState == TouchStates.TD) { MoveToNext(TouchMode.Multi); // pen started to input if (isPen && PenDevID == -1) { PenDevID = e.TouchDevice.Id; } } else { Debug.WriteLine("Unexpected TOUCH mode change from Single: " + touchState); } break; case TouchMode.Multi: if (touchState == TouchStates.TU) { MoveToNext(TouchMode.Single); // 펜 입력이 원래 없거나 중단된 경우 if (!isPen) { PenDevID = -1; } } else if (touchState == TouchStates.TM) { MoveToNext(TouchMode.Multi); } else { Debug.WriteLine("Unexpected TOUCH mode change from Multi: " + touchState); } break; default: break; } if (this.IsEnableCollect) { ////멀티터치 //if ((_prevDevID > 0) && (_prevDevID != e.TouchDevice.Id)) //{ // //펜을 캔버스에 대면 자동적으로 지우기모드 // this.IsMultiTouch = true; // System.Diagnostics.Debug.WriteLine(string.Format("Multitouch")); //} ////싱글터치 //else if ((_prevDevID > 0) && (_prevDevID == e.TouchDevice.Id)) //{ // //펜을 캔버스에 대면 자동적으로 지우기모드 // this.IsMultiTouch = false; // System.Diagnostics.Debug.WriteLine(string.Format("Singletouch")); //} //this._prevDevID = e.TouchDevice.Id; if (ModeChanged != null) { ModeChanged(this, new TouchModeChangedEventArgs() { IsMultitouch = this.IsMultiTouch }); } } }