private void NotifyUpdate(bool pointerAdded = false) { // Note: Make sure to update the _sumOfPublishedDelta before raising the event, so if an exception is raised // or if the manipulation is Completed, the Complete event args can use the updated _sumOfPublishedDelta. var cumulative = GetCumulative(); switch (_state) { case ManipulationState.Starting when pointerAdded: _state = ManipulationState.Started; _sumOfPublishedDelta = cumulative; _recognizer.ManipulationStarted?.Invoke( _recognizer, new ManipulationStartedEventArgs(_deviceType, _currents.Center, cumulative)); // No needs to publish an update when we start the manipulation due to an additional pointer as cumulative will be empty. break; case ManipulationState.Starting when cumulative.IsSignificant(_startThresholds): _state = ManipulationState.Started; _sumOfPublishedDelta = cumulative; // Note: We first start with an empty delta, then invoke Update. // This is required to patch a common issue in applications that are using only the // ManipulationUpdated.Delta property to track the pointer (like the WCT GridSplitter). // UWP seems to do that only for Touch and Pen (i.e. the Delta is not empty on start with a mouse), // but there is no side effect to use the same behavior for all pointer types. _recognizer.ManipulationStarted?.Invoke( _recognizer, new ManipulationStartedEventArgs(_deviceType, _origins.Center, ManipulationDelta.Empty)); _recognizer.ManipulationUpdated?.Invoke( _recognizer, new ManipulationUpdatedEventArgs(_deviceType, _currents.Center, cumulative, cumulative, isInertial: false)); break; case ManipulationState.Started: // Even if Scale and Angle are expected to be default when we add a pointer (i.e. forceUpdate == true), // the 'delta' and 'cumulative' might still contains some TranslateX|Y compared to the previous Pointer1 location. var delta = GetDelta(cumulative); if (pointerAdded || delta.IsSignificant(_deltaThresholds)) { _sumOfPublishedDelta = _sumOfPublishedDelta.Add(delta); _recognizer.ManipulationUpdated?.Invoke( _recognizer, new ManipulationUpdatedEventArgs(_deviceType, _currents.Center, delta, cumulative, isInertial: false)); } break; } }
/// <summary> /// Gets the cumulative delta, including the manipulation cumulative when this processor was started /// </summary> public ManipulationDelta GetCumulative() => _cumulative0.Add(_inertiaCumulative);
private void NotifyUpdate(bool pointerAdded = false) { // Note: Make sure to update the _sumOfPublishedDelta before raising the event, so if an exception is raised // or if the manipulation is Completed, the Complete event args can use the updated _sumOfPublishedDelta. var cumulative = GetCumulative(); switch (_state) { case ManipulationState.Starting when IsBeginningOfDragManipulation(): // On UWP if the element was configured to allow both Drag and Manipulations, // both events are going to be raised (... until the drag "content" is being render an captures all pointers). // This results as a manipulation started which is never completed. // If user uses double touch the manipulation will however start and complete when user adds / remove the 2nd finger. // On Uno, as allowing both Manipulations and drop on the same element is really a stretch case (and is bugish on UWP), // we accept as a known limitation that once dragging started no manipulation event would be fired. _state = ManipulationState.Started; IsDragManipulation = true; _recognizer.Dragging?.Invoke( _recognizer, new DraggingEventArgs(_currents.Pointer1, DraggingState.Started)); break; case ManipulationState.Starting when pointerAdded: _state = ManipulationState.Started; _sumOfPublishedDelta = cumulative; _recognizer.ManipulationStarted?.Invoke( _recognizer, new ManipulationStartedEventArgs(_deviceType, _currents.Center, cumulative)); // No needs to publish an update when we start the manipulation due to an additional pointer as cumulative will be empty. break; case ManipulationState.Starting when cumulative.IsSignificant(_startThresholds): _state = ManipulationState.Started; _sumOfPublishedDelta = cumulative; // Note: We first start with an empty delta, then invoke Update. // This is required to patch a common issue in applications that are using only the // ManipulationUpdated.Delta property to track the pointer (like the WCT GridSplitter). // UWP seems to do that only for Touch and Pen (i.e. the Delta is not empty on start with a mouse), // but there is no side effect to use the same behavior for all pointer types. _recognizer.ManipulationStarted?.Invoke( _recognizer, new ManipulationStartedEventArgs(_deviceType, _origins.Center, ManipulationDelta.Empty)); _recognizer.ManipulationUpdated?.Invoke( _recognizer, new ManipulationUpdatedEventArgs(_deviceType, _currents.Center, cumulative, cumulative, isInertial: false)); break; case ManipulationState.Started when IsDragManipulation: _recognizer.Dragging?.Invoke( _recognizer, new DraggingEventArgs(_currents.Pointer1, DraggingState.Continuing)); break; case ManipulationState.Started: // Even if Scale and Angle are expected to be default when we add a pointer (i.e. forceUpdate == true), // the 'delta' and 'cumulative' might still contains some TranslateX|Y compared to the previous Pointer1 location. var delta = GetDelta(cumulative); if (pointerAdded || delta.IsSignificant(_deltaThresholds)) { _sumOfPublishedDelta = _sumOfPublishedDelta.Add(delta); _recognizer.ManipulationUpdated?.Invoke( _recognizer, new ManipulationUpdatedEventArgs(_deviceType, _currents.Center, delta, cumulative, isInertial: false)); } break; } }