Esempio n. 1
0
        // 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();
        }
Esempio n. 2
0
            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;
                }
            }
Esempio n. 4
0
        // 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();
            }
        }
Esempio n. 5
0
        // 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;
            }
        }
Esempio n. 6
0
    /// <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);
    }
Esempio n. 7
0
        // 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();
        }
Esempio n. 8
0
            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;
                }
            }
Esempio n. 9
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;
        }
Esempio n. 10
0
    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;
        }
    }
Esempio n. 11
0
            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;
                }
            }
Esempio n. 12
0
        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;
            }
        }
Esempio n. 13
0
    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;
            }
        }
    }