private void ProcessTouch() { var touchCollection = TouchPanel.GetState(); if (touchCollection.Count > 0) { // convert list List<TouchPoint> touchPoints = ConvertTouchPoints(touchCollection); // can be zero if points are outside of bounds if (touchPoints.Count > 0) { _logger.Trace("Processing raw touch/gesture input"); lock (_activeDataTypes) { // report touch? if (_activeDataTypes.Contains(DataType.Touch)) { var data = new TouchData(touchPoints); // pass on data to the outside world _dataAcquiredCallback(data); } // report drag? if (_activeDataTypes.Contains(DataType.CustomDrag)) { // use the first touch point var touchPoint = touchPoints[0]; // create the data var data = new CustomDragData(); data.TouchPoint = touchPoint; data.Delta = new Vector2(touchPoint.Location.X - _lastDragTouchPoint.Location.X, touchPoint.Location.Y - _lastDragTouchPoint.Location.Y); // new reference _lastDragTouchPoint = touchPoint; // send _dataAcquiredCallback(data); } } } } }
/// <summary> /// Creates a data message from raw message data, starting at a given offset in the raw data. /// </summary> /// <param name="rawMessage">The raw message data.</param> /// <param name="start">The index the recreation of the data message should be started at.</param> /// <returns>A data message of correct type, recreated from the raw data.</returns> public static DataMessage CreateFromRawMessage(byte[] rawMessage, int start) { // result DataMessage result = null; // inspect type var dataType = (DataType)BitConverter.ToInt32(rawMessage, start + 1); // simple switch here switch (dataType) { case DataType.ControllerInfo: result = new ControllerInfoData(); break; case DataType.Accelerometer: result = new AccelerometerData(); break; case DataType.Compass: result = new CompassData(); break; case DataType.Gyroscope: result = new GyroscopeData(); break; case DataType.Motion: result = new MotionData(); break; case DataType.Touch: result = new TouchData(); break; case DataType.Tap: result = new TapData(); break; case DataType.DoubleTap: result = new DoubleTapData(); break; case DataType.Hold: result = new HoldData(); break; case DataType.Flick: result = new FlickData(); break; case DataType.FreeDrag: result = new FreeDragData(); break; case DataType.HorizontalDrag: result = new HorizontalDragData(); break; case DataType.VerticalDrag: result = new VerticalDragData(); break; case DataType.DragComplete: result = new DragCompleteData(); break; case DataType.CustomDrag: result = new CustomDragData(); break; case DataType.CustomDragComplete: result = new CustomDragCompleteData(); break; case DataType.Pinch: result = new PinchData(); break; case DataType.PinchComplete: result = new PinchCompleteData(); break; case DataType.Text: result = new TextData(); break; } // fill from raw data if (result != null) { result.FromByteArray(rawMessage, start); } else { if (Debugger.IsAttached) { Debugger.Break(); } } return result; }
private void Process(TouchData data) { Debug.WriteLine("InputEmulator: Processing raw touch input"); var touchPointCount = data.TouchPoints.Count; //should never happen if (touchPointCount < 1) { return; } //do not process the data if any of the points is invalid if (data.TouchPoints.Any(o => o.State == TouchPointState.Invalid)) { return; } //was a touch point released? => reset the reference point and done if (data.TouchPoints.Any(o => o.State == TouchPointState.Released)) { //reset the last references _lastTouchX = -1.0f; _lastTouchY = -1.0f; return; } //get the coordinates var x = data.TouchPoints.Sum(o => o.Location.X) / touchPointCount; var y = data.TouchPoints.Sum(o => o.Location.Y) / touchPointCount; //if any touch points are newly pressed, set new reference data if (data.TouchPoints.Any(o => o.State == TouchPointState.Pressed)) { _lastTouchX = x; _lastTouchY = y; return; } // at this point we know the touch point(s) state('s) is 'Moved' //get current computer's virtual screen width var screenWidth = SystemInformation.VirtualScreen.Width; var screenHeight = SystemInformation.VirtualScreen.Height; //decide what to do if (touchPointCount > 1) { //the user uses more than one finger => we use this for two-finger scrolling, // by emulating mouse wheel data var changeY = y - _lastTouchY; //change sign because the wheel works "the other way round" changeY *= -1; //conver to wheel ticks var ticks = (int)Math.Round(changeY / 15.0); if (ticks == 0) { //if the scrolling was too "slow" to cause any mouse wheel ticks // we simply return(not storing new reference coordinates!). //this allows "slow" scrolling because the next time this is invoked, //the difference is computed with regards to the old reference, //making a tick >=1 more likely return; } Win32Wrapper.SendMouseWheel(ticks); } else { //for only one finger touch data //we use the data for cursor movement if (UseRelativeTouchInput) { //calc the change var changeX = (int)Math.Ceiling(x - _lastTouchX); var changeY = (int)Math.Ceiling(y - _lastTouchY); if (changeX == 0 && changeY == 0) { //return without setting a new reference point (below) // to allow values to aggregate, but do not use small values (in particular zero) //to avoid rounding problems (=> "wandering" cursor) return; } //move mouse position var currentPosition = Win32Wrapper.GetCursorPosition(); var newPositionX = (int)Math.Round(currentPosition.X + changeX); var newPositionY = (int)Math.Round(currentPosition.Y + changeY); Win32Wrapper.SetCursorPosition(newPositionX, newPositionY); } else { //calculate new position depending on the controller's screen dimension var newX = (x / _controllerDisplayWidth) * screenWidth; var newY = (y / _controllerDisplayHeight) * screenHeight; //set absolute mouse position var newPositionX = (int)Math.Round(newX) + SystemInformation.VirtualScreen.Left; var newPositionY = (int)Math.Round(newY) + SystemInformation.VirtualScreen.Top; Win32Wrapper.SetCursorPosition(newPositionX, newPositionY); } } //set new references _lastTouchX = x; _lastTouchY = y; }