private bool canFireClickEvent( TouchRaycast info, TouchRaycast touch )
            {

                #region Should not fire click event if control has been moved

                var p2u = control.PixelsToUnits();
                var startPosition = controlStartPosition / p2u;
                var currentPosition = control.transform.position / p2u;

                if( Vector3.Distance( startPosition, currentPosition ) > 1f )
                    return false;

                #endregion

                return true;

            }
        internal void Process( Transform transform, Camera renderCamera, IDFTouchInputSource input, bool retainFocusSetting )
        {
            controlUnderMouse = null;

            var touches = input.Touches;
            for( int i = 0; i < touches.Count; i++ )
            {

                // Dereference Touch information
                var touch = touches[ i ];

                // Keep track of the last control under the "mouse"
                var touchedControl = dfGUIManager.HitTestAll( touch.position );
                if( touchedControl != null && touchedControl.transform.IsChildOf( manager.transform ) )
                {
                    controlUnderMouse = touchedControl;
                }

                #region Don't track touches on empty space

                if( controlUnderMouse == null )
                {
                    if( touch.phase == TouchPhase.Began )
                    {

                        if( !retainFocusSetting && untracked.Count == 0 )
                        {
                            var focusControl = dfGUIManager.ActiveControl;
                            if( focusControl != null && focusControl.transform.IsChildOf( manager.transform ) )
                            {
                                focusControl.Unfocus();
                            }
                        }

                        untracked.Add( touch.fingerId );

                        continue;

                    }
                }

                if( untracked.Contains( touch.fingerId ) )
                {

                    if( touch.phase == TouchPhase.Ended )
                        untracked.Remove( touch.fingerId );

                    continue;

                }

                #endregion

                var ray = renderCamera.ScreenPointToRay( touch.position );
                var info = new TouchRaycast( controlUnderMouse, touch, ray );

                var captured = tracked.FirstOrDefault( x => x.IsTrackingFinger( info.FingerID ) );
                if( captured != null )
                {
                    captured.Process( info );
                    continue;
                }

                var processed = false;
                for( int x = 0; x < tracked.Count; x++ )
                {
                    if( tracked[ x ].Process( info ) )
                    {
                        processed = true;
                        break;
                    }
                }

                if( !processed && controlUnderMouse != null )
                {

                    if( !tracked.Any( x => x.control == controlUnderMouse ) )
                    {

                        var newTracker = new ControlTouchTracker( manager, controlUnderMouse );

                        tracked.Add( newTracker );
                        newTracker.Process( info );

                    }

                }

            }

            }
            /// <summary>
            /// Processes touch information for a single control
            /// </summary>
            /// <param name="info">The touch/raycast data to be processed</param>
            /// <returns>Returns TRUE if the touch information was processed</returns>
            public bool Process( TouchRaycast info )
            {

                #region Drag / Drop

                if( IsDragging )
                {

                    // Not interested in any fingers other than the one that
                    // started the drag operation
                    if( !capture.Contains( info.FingerID ) )
                        return false;

                    // Nothing to do if there's no user action
                    if( info.Phase == TouchPhase.Stationary )
                        return true;

                    // If the touch was cancelled, raise OnDragEnd event
                    if( info.Phase == TouchPhase.Canceled )
                    {

                        control.OnDragEnd( new dfDragEventArgs( control, dfDragDropState.Cancelled, dragData, info.ray, info.position ) );
                        dragState = dfDragDropState.None;

                        touches.Clear();
                        capture.Clear();

                        return true;
                    }

                    // If the finger was lifted, attempt drop
                    if( info.Phase == TouchPhase.Ended )
                    {

                        // Dropped on nothing
                        if( info.control == null || info.control == control )
                        {

                            control.OnDragEnd( new dfDragEventArgs( control, dfDragDropState.CancelledNoTarget, dragData, info.ray, info.position ) );
                            dragState = dfDragDropState.None;

                            touches.Clear();
                            capture.Clear();

                            return true;

                        }

                        // Dropped on another control
                        var dropArgs = new dfDragEventArgs( info.control, dfDragDropState.Dragging, dragData, info.ray, info.position );
                        info.control.OnDragDrop( dropArgs );

                        // If there was no event consumer, or if the event consumer did not
                        // change the state from Dragging (which is not a valid state for
                        // a drop event) then just cancel the operation
                        if( !dropArgs.Used || dropArgs.State != dfDragDropState.Dropped )
                        {
                            dropArgs.State = dfDragDropState.Cancelled;
                        }

                        // Let the control know that it is no longer being dragged
                        var endArgs = new dfDragEventArgs( control, dropArgs.State, dragData, info.ray, info.position );
                        endArgs.Target = info.control;
                        control.OnDragEnd( endArgs );

                        // Clear state
                        dragState = dfDragDropState.None;
                        touches.Clear();
                        capture.Clear();

                        return true;

                    }

                    return true;

                }

                #endregion

                #region New touch for this control

                if( !touches.ContainsKey( info.FingerID ) )
                {

                    // Touch is not over control, and is not "captured" by control
                    if( info.control != control )
                        return false;

                    // Start tracking this finger
                    touches[ info.FingerID ] = info;

                    // See if this is the first touch to be tracked for this control
                    if( touches.Count == 1 )
                    {

                        // This is the first Touch to be associated with the control
                        control.OnMouseEnter( info );

                        // If the touch was also started while over the control,
                        // then raise the OnMouseDown event
                        if( info.Phase == TouchPhase.Began )
                        {

                            capture.Add( info.FingerID );
                            controlStartPosition = control.transform.position;

                            control.OnMouseDown( info );

                            // Prevent "click-through"
                            if( Event.current != null )
                                Event.current.Use();

                        }

                        return true;

                    }

                    // Switch control to "multi-touch" mode if touch began on control,
                    // otherwise ignore the new touch info
                    if( info.Phase == TouchPhase.Began )
                    {

                        // Send multi-touch event
                        var activeTouches = getActiveTouches();
                        var multiTouchArgs = new dfTouchEventArgs( control, activeTouches, info.ray );
                        control.OnMultiTouch( multiTouchArgs );

                    }

                    return true;

                }

                #endregion

                #region Previously tracked touch has now ended

                if( info.Phase == TouchPhase.Canceled || info.Phase == TouchPhase.Ended )
                {

                    var phase = info.Phase;
                    var touch = touches[ info.FingerID ];

                    // Remove the finger from the list of touches
                    touches.Remove( info.FingerID );

                    if( touches.Count == 0 && phase != TouchPhase.Canceled )
                    {

                        if( capture.Contains( info.FingerID ) )
                        {

                            if( canFireClickEvent( info, touch ) )
                            {

                                if( info.control == this.control )
                                {
                                    if( info.touch.tapCount > 1 )
                                        control.OnDoubleClick( info );
                                    else
                                        control.OnClick( info );
                                }

                            }

                            info.control = this.control;
                            this.control.OnMouseUp( info );

                        }

                        capture.Remove( info.FingerID );

                        return true;

                    }
                    else
                    {
                        capture.Remove( info.FingerID );
                    }

                    if( touches.Count == 1 )
                    {

                        // Explicitly notify control that multi-touch state has ended
                        control.OnMultiTouchEnd();

                        return true;

                    }

                }

                #endregion

                #region Multi-touch events

                // If there is more than one touch active for this control,
                // then raise the OnMultiTouch event instead of converting
                // the touch info to mouse events
                if( touches.Count > 1 )
                {

                    var activeTouches = getActiveTouches();
                    var multiTouchArgs = new dfTouchEventArgs( control, activeTouches, info.ray );

                    control.OnMultiTouch( multiTouchArgs );

                    return true;

                }

                #endregion

                // If the touch has not moved, send hover message
                if( !IsDragging && info.Phase == TouchPhase.Stationary )
                {
                    if( info.control == this.control )
                    {
                        control.OnMouseHover( info );
                        return true;
                    }
                    return false;
                }

                #region See if the control supports (and allows) drag-and-drop

                var canStartDrag =
                    capture.Contains( info.FingerID ) &&
                    dragState == dfDragDropState.None &&
                    info.Phase == TouchPhase.Moved;

                if( canStartDrag )
                {

                    // Query the control to see if drag-and-drop is allowed
                    var dragStartArgs = (dfDragEventArgs)info;
                    control.OnDragStart( dragStartArgs );

                    // If control set State and Used properties to the correct values,
                    // enter drag-and-drop mode
                    if( dragStartArgs.State == dfDragDropState.Dragging && dragStartArgs.Used )
                    {

                        this.dragState = dfDragDropState.Dragging;
                        this.dragData = dragStartArgs.Data;

                        return true;

                    }

                    // Flag that we've already tried drag and drop
                    this.dragState = dfDragDropState.Denied;

                }

                #endregion

                // Check for mouse leave
                if( info.control != this.control )
                {

                    // If "capture" is not active, fire the OnMouseLeave event
                    if( !capture.Contains( info.FingerID ) )
                    {

                        info.control = this.control;
                        this.control.OnMouseLeave( info );

                        this.touches.Remove( info.FingerID );

                        return true;

                    }

                }

                // At this point, the only remaining option is to send OnMouseMove event
                info.control = this.control;
                this.control.OnMouseMove( info );

                return true;

            }
Ejemplo n.º 4
0
        internal void Process( Transform transform, Camera renderCamera, dfList<Touch> touches, bool retainFocus )
        {
            for( int i = 0; i < touches.Count; i++ )
            {

                // Dereference Touch information
                var touch = touches[ i ];

                // Raycast from touch position to find the top-most control under the touch
                var ray = renderCamera.ScreenPointToRay( touch.position );
                var maxDistance = renderCamera.farClipPlane - renderCamera.nearClipPlane;
                var hits = Physics.RaycastAll( ray, maxDistance, renderCamera.cullingMask );

                // Keep track of the last control under the "mouse"
                controlUnderMouse = clipCast( transform, hits );

                #region Don't track touches on empty space

                if( controlUnderMouse == null )
                {
                    if( touch.phase == TouchPhase.Began )
                    {
                        untracked.Add( touch.fingerId );
                        continue;
                    }
                }

                if( untracked.Contains( touch.fingerId ) )
                {

                    if( touch.phase == TouchPhase.Ended )
                        untracked.Remove( touch.fingerId );

                    continue;

                }

                #endregion

                var info = new TouchRaycast( controlUnderMouse, touch, ray );

                var captured = tracked.FirstOrDefault( x => x.IsTrackingFinger( info.FingerID ) );
                if( captured != null )
                {
                    captured.Process( info );
                    continue;
                }

                var processed = false;
                for( int x = 0; x < tracked.Count; x++ )
                {
                    if( tracked[ x ].Process( info ) )
                    {
                        processed = true;
                        break;
                    }
                }

                if( !processed && controlUnderMouse != null )
                {

                    if( !tracked.Any( x => x.control == controlUnderMouse ) )
                    {

                        if( controlUnderMouse == null )
                            Debug.Log( "Tracking touch with no control: " + touch.fingerId );

                        var newTracker = new ControlTouchTracker( manager, controlUnderMouse );

                        tracked.Add( newTracker );
                        newTracker.Process( info );

                    }

                }

            }

            }
Ejemplo n.º 5
0
            private bool canFireClickEvent( TouchRaycast info, TouchRaycast touch )
            {

                if( manager.TouchClickRadius <= 0 )
                    return true;

                var distanceFromStart = Vector2.Distance( info.position, touch.position );

                return distanceFromStart < manager.TouchClickRadius;

            }
Ejemplo n.º 6
0
            private bool canFireClickEvent( TouchRaycast info, TouchRaycast touch )
            {

                #region Should not fire click event if control has been moved

                var p2u = control.PixelsToUnits();
                var startPosition = controlStartPosition / p2u;
                var currentPosition = control.transform.position / p2u;

                if( Vector3.Distance( startPosition, currentPosition ) > 1f )
                    return false;

                #endregion

                if( manager.TouchClickRadius <= 0 )
                    return true;

                var distanceFromStart = Vector2.Distance( info.position, touch.position );

                return distanceFromStart <= manager.TouchClickRadius;

            }
            private bool canFireClickEvent( TouchRaycast info, TouchRaycast touch )
            {

                // It is possible that a control could have been deleted during event processing.
                if( this.control == null )
                    return false;

                #region Should not fire click event if control has been moved

                var p2u = control.PixelsToUnits();
                var startPosition = controlStartPosition / p2u;
                var currentPosition = control.transform.position / p2u;

                if( Vector3.Distance( startPosition, currentPosition ) > 1f )
                    return false;

                #endregion

                return true;

            }