// Initiate translational dragging. private void child_MouseLeftButtonDown(object sender, MouseButtonEventArgs e) { if (_manipulationState != ManipulationState.NONE) { return; } if (Keyboard.IsKeyDown(Key.LeftCtrl) || Keyboard.IsKeyDown(Key.RightCtrl)) { ZoomOut(e); } if (Keyboard.IsKeyDown(Key.LeftShift) || Keyboard.IsKeyDown(Key.RightShift)) { ZoomIn(e); } _manipulationState = ManipulationState.MOUSE_DRAG; var tt = GetTranslateTransform(_child); _mouseDragAbsoluteStart = e.GetPosition(this); _originalTranslation = new Point(tt.X, tt.Y); _thresholdExceeded = false; Cursor = Cursors.Hand; _child.CaptureMouse(); }
public void Complete() { // If the manipulation was not started, we just abort the manipulation without any event switch (_state) { case ManipulationState.Started when IsDragManipulation: _state = ManipulationState.Completed; _recognizer.Dragging?.Invoke( _recognizer, new DraggingEventArgs(_currents.Pointer1, DraggingState.Completed)); break; case ManipulationState.Started: _state = ManipulationState.Completed; _recognizer.ManipulationCompleted?.Invoke( _recognizer, new ManipulationCompletedEventArgs(_deviceType, _currents.Center, GetCumulative(), isInertial: false)); break; default: _state = ManipulationState.Completed; break; } // Self scavenge our self from the _recognizer ... yes it's a bit strange, // but it's the safest and easiest way to avoid invalid state. if (_recognizer._manipulation == this) { _recognizer._manipulation = null; } }
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; } }
// End touch dragging/pinching. private void child_ManipulationCompleted(object sender, ManipulationCompletedEventArgs e) { e.Handled = true; _manipulationState = ManipulationState.NONE; // If no real manipulation (zoom or translation) happened, cancel this // manipulation event. This results in equivalent mouse events being raised // instead which the other interaction code can handle. if (!_thresholdExceeded) { e.Cancel(); } }
// End either kind of dragging, consuming the event if the drag threshold was exceeded. private void child_MouseEitherButtonUp(object sender, MouseButtonEventArgs e) { _manipulationState = ManipulationState.NONE; _child.ReleaseMouseCapture(); Cursor = Cursors.Arrow; // If we dragged a distance larger than our threshold, handle the up event so that // it's not treated as a click on a skill node. if (_thresholdExceeded) { e.Handled = true; } }
/// <summary> /// Sets the manipulated object. /// </summary> /// <param name="obj">The object to be manipulated.</param> public void SetManipulatedObject(GameObject obj) { m_ManipulatedObject = obj; var collider = m_ManipulatedObject.GetComponentInChildren <Collider>(true); if (collider != null) { collider.enabled = true; } m_ManipulationState = ManipulationState.Placed; m_ObjectPlane = new Plane(Vector3.up, m_ManipulatedObject.transform.position); }
// Initiate zoom dragging. private void child_MouseRightButtonDown(object sender, MouseButtonEventArgs e) { if (_manipulationState != ManipulationState.NONE) { return; } _manipulationState = ManipulationState.MOUSE_ZOOM; _mouseZoomRelativeStart = e.GetPosition(_child); _mouseDragAbsoluteStart = e.GetPosition(this); _lastMouseAbsoluteY = _mouseDragAbsoluteStart.Y; _thresholdExceeded = false; Cursor = Cursors.Hand; _child.CaptureMouse(); }
public Manipulation(GestureRecognizer recognizer, PointerPoint pointer1) { _recognizer = recognizer; _deviceType = pointer1.PointerDevice.PointerDeviceType; _origins = _currents = pointer1; switch (_deviceType) { case PointerDeviceType.Mouse: _startThresholds = StartMouse; _deltaThresholds = DeltaMouse; break; case PointerDeviceType.Pen: _startThresholds = StartPen; _deltaThresholds = DeltaPen; break; default: case PointerDeviceType.Touch: _startThresholds = StartTouch; _deltaThresholds = DeltaTouch; break; } var args = new ManipulationStartingEventArgs(_recognizer._gestureSettings); _recognizer.ManipulationStarting?.Invoke(_recognizer, args); var settings = args.Settings; if ((settings & (GestureSettingsHelper.Manipulations | GestureSettingsHelper.DragAndDrop)) == 0) { _state = ManipulationState.Completed; } else { _isDraggingEnable = (settings & GestureSettings.Drag) != 0; _isTranslateXEnabled = (settings & (GestureSettings.ManipulationTranslateX | GestureSettings.ManipulationTranslateRailsX)) != 0; _isTranslateYEnabled = (settings & (GestureSettings.ManipulationTranslateY | GestureSettings.ManipulationTranslateRailsY)) != 0; _isRotateEnabled = (settings & (GestureSettings.ManipulationRotate | GestureSettings.ManipulationRotateInertia)) != 0; _isScaleEnabled = (settings & (GestureSettings.ManipulationScale | GestureSettings.ManipulationScaleInertia)) != 0; } }
// Initiate touch dragging/pinching. private void child_ManipulationStarting(object sender, ManipulationStartingEventArgs e) { if (_manipulationState != ManipulationState.NONE) { return; } _manipulationState = ManipulationState.TOUCH; _thresholdExceeded = false; // Things would be easier if we made the child the container to use as reference // for all calculations, but changing the child transformations while manipulation // events are coming in (and are calculated based on outdated transformation values) // apparently leads to oscillations. e.ManipulationContainer = this; e.Mode = ManipulationModes.Scale | ManipulationModes.Translate; e.IsSingleTouchEnabled = true; e.Handled = true; }
private void EndCurrentAction() { switch (m_ManipulationState) { case ManipulationState.Dragging: m_ManipulationState = ManipulationState.Placed; break; case ManipulationState.Rotating: m_ManipulationState = ManipulationState.Placed; break; case ManipulationState.Placed: break; case ManipulationState.Undefined: break; } }
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; } }
public void ResolveStatus() { //-------- Additions Made By Swenzi -------- //Purpose: Fixes bugs and adds better fuel consumption if the vehicle is refuelable //Logic: Better fuel consumption logic saves chemfuel, less bugs is good //Improvements: None I can think of. //Other Info: Changes marked with --- ADB Swenzi --- due to the dispersion of modifications in the method if (Pawn?.GetComp <CompRefuelable>() is CompRefuelable compRefuelable) { //------ ADB Swenzi ------ //If it isn't moving than it shouldn't use fuel if (Pawn.pather != null && !Pawn.pather.Moving || Pawn.GetCaravan() != null && Pawn.GetCaravan().CantMove) { compRefuelable.Props.fuelConsumptionRate = 0f; } else { //If it's moving than it should use fuel compRefuelable.Props.fuelConsumptionRate = fuelConsumptionRate; } //------ ADB Swenzi ------ if (!compRefuelable.HasFuel) { weaponStatus = WeaponState.frozen; movingStatus = MovingState.frozen; return; } } if (MovementHandlerAvailable && movingStatus == MovingState.frozen) { movingStatus = MovingState.able; } if (WeaponHandlerAvailable && weaponStatus == WeaponState.frozen) { weaponStatus = WeaponState.able; } if (!MovementHandlerAvailable && movingStatus == MovingState.able && Props.movementHandling != HandlingType.NoHandlerRequired) { movingStatus = MovingState.frozen; } if (!WeaponHandlerAvailable && weaponStatus == WeaponState.able && Props.weaponHandling != HandlingType.NoHandlerRequired) { weaponStatus = WeaponState.frozen; } if (!ManipulationHandlerAvailable && manipulationStatus == ManipulationState.able && Props.manipulationHandling != HandlingType.NoHandlerRequired) { manipulationStatus = ManipulationState.frozen; } // ------ ADB Swenzi ------- //If it can move and it's in a caravan wandering than it might be stuck //aka the movement thing hasn't kicked in. Change draft status just to be safe. //Fixes bug where weapon tries to fire even after gunner is removed if (weaponStatus != WeaponState.able) { if (this?.Pawn?.CurJob?.def == JobDefOf.WaitCombat || this?.Pawn?.CurJob?.def == JobDefOf.AttackStatic || this?.Pawn?.CurJob?.def == JobDefOf.AttackMelee) { if (!this?.Pawn?.pather?.Moving ?? false) { Pawn.jobs.EndCurrentJob(JobCondition.None, false); } else { Pawn.jobs.EndCurrentJob(JobCondition.None, true); } } } if (movingStatus == MovingState.able) { //Removed caravan member check as apparently pawns currently forming a caravan aren't part of one yet // if (this.Pawn.CurJob != null && this.Pawn.CurJob.def == JobDefOf.GotoWander) // { // if (!this.draftStatusChanged){ //this.Pawn.drafter.Drafted = !this.Pawn.Drafted; //this.draftStatusChanged = true; // } // } // else // { // //Safety to allow this for future caravans // this.draftStatusChanged = false; // } } else { //Vehicles that can't move shouldn't have Lords, it causes problems cause they never complete their jobs and toils if (this?.Pawn?.GetLord() != null) { Pawn.GetLord().lordManager.RemoveLord(Pawn.GetLord()); } if (Pawn.pather != null && Pawn.pather.Moving) { if (tickCount > Props.momentumTimeSeconds * 60) { //No more fake momentum, vehicle should stop //this.Pawn.jobs. if (Pawn.pather.Moving) { Pawn.jobs.EndCurrentJob(JobCondition.None, false); } Pawn.pather.StopDead(); tickCount = 0; } else { //Be cool, keep the momentum going tickCount++; } } } if (movingStatus != MovingState.able && weaponStatus != WeaponState.able && this?.Pawn?.mindState != null) { Pawn.mindState.lastJobTag = JobTag.Idle; } // ------ ADB Swenzi ------- if (Pawn.Drafted && movingStatus == MovingState.frozen) { Pawn.drafter.Drafted = false; } }
private void HandleTouchInput() { // Don't do anything if the object is not placed yet or no touch has been detected. if (m_ManipulationState == ManipulationState.Undefined || Input.touchCount == 0 || m_ManipulatedObject == null || !m_ManipulatedObject.activeInHierarchy) { EndCurrentAction(); return; } Touch touch = Input.GetTouch(0); // Screen ray and ray & plane intersection. Ray touchRay = Camera.main.ScreenPointToRay(touch.position); float enter = 0.0f; Vector3?planeHitPoint = null; if (m_ObjectPlane.Raycast(touchRay, out enter)) { planeHitPoint = touchRay.GetPoint(enter); } // Ends the current action when the touch is ended or cancelled. if (touch.phase == TouchPhase.Ended || touch.phase == TouchPhase.Canceled) { EndCurrentAction(); return; } else if (touch.phase == TouchPhase.Began) { if (m_ManipulationState != ManipulationState.Placed) { EndCurrentAction(); } // Checks for ray intersection with the bounding collider. bool colliderHitFound = false; RaycastHit colliderHitInfo; if (Physics.Raycast(touchRay, out colliderHitInfo)) { var hitTransform = colliderHitInfo.transform; // Activates the dragging state when the hit test was successful. (Dragging) m_ManipulatedObject = hitTransform.gameObject; m_ObjectPlane = new Plane(Vector3.up, m_ManipulatedObject.transform.position); colliderHitFound = true; m_ManipulationState = ManipulationState.Dragging; } // Checks for ray intersection with the object's plane. (Rotating) if (!colliderHitFound && planeHitPoint.HasValue) { m_ManipulationState = ManipulationState.Rotating; var touchVector = planeHitPoint.Value - transform.position; touchVector.y = 0; touchVector.Normalize(); m_InitialTouchVector = touchVector; m_InitialRotation = m_ManipulatedObject.transform.rotation; m_ManipulationState = ManipulationState.Rotating; } } else if (touch.phase == TouchPhase.Moved) { if (m_ManipulationState == ManipulationState.Dragging && planeHitPoint.HasValue) { Vector3 nextPosition = planeHitPoint.Value; // Check if next object position will make the object collide with the depth map. // If that's the case don't update the object's position. Matrix4x4 nextTransform = m_ManipulatedObject.transform.localToWorldMatrix; nextTransform.SetColumn(3, new Vector4(nextPosition.x, nextPosition.y, nextPosition.z, 1.0f)); float collisionPercentage = SimpleCollisionHelper.TestCollision( m_ManipulatedObject, nextTransform); if (collisionPercentage > 0.1f) { return; } // Sets the object's position to the plane hit point. m_ManipulatedObject.transform.position = nextPosition; } else if (m_ManipulationState == ManipulationState.Rotating) { var touchVector = planeHitPoint.Value - transform.position; touchVector.y = 0; touchVector.Normalize(); var newRotation = Quaternion.FromToRotation(touchVector, m_InitialTouchVector); float angle; Vector3 axis; newRotation.ToAngleAxis(out angle, out axis); newRotation = Quaternion.AngleAxis(angle * k_RotationMultiplier, axis); m_ManipulatedObject.transform.rotation = m_InitialRotation * newRotation; } } }