Exemple #1
0
 private bool handleMouseMove(InputState state)
 {
     return(positionalInputQueue.Any(target => target.TriggerOnMouseMove(state)));
 }
Exemple #2
0
 protected virtual void TransformState(InputState inputState)
 {
 }
Exemple #3
0
        private void updateMouseEvents(InputState state)
        {
            MouseState mouse = (MouseState)state.Mouse;

            var last = state.Last?.Mouse as MouseState;

            if (last == null)
            {
                return;
            }

            if (mouse.Position != last.Position)
            {
                handleMouseMove(state);
                if (isDragging)
                {
                    handleMouseDrag(state);
                }
            }

            for (MouseButton b = 0; b < MouseButton.LastButton; b++)
            {
                var lastPressed = last.IsPressed(b);

                if (lastPressed != mouse.IsPressed(b))
                {
                    if (lastPressed)
                    {
                        handleMouseUp(state, b);
                    }
                    else
                    {
                        handleMouseDown(state, b);
                    }
                }
            }

            if (mouse.WheelDelta != 0)
            {
                handleWheel(state);
            }

            if (mouse.HasAnyButtonPressed)
            {
                if (!last.HasAnyButtonPressed)
                {
                    //stuff which only happens once after the mousedown state
                    mouse.PositionMouseDown = state.Mouse.Position;
                    LastActionTime          = Time.Current;

                    if (mouse.IsPressed(MouseButton.Left))
                    {
                        isValidClick = true;

                        if (Time.Current - lastClickTime < double_click_time)
                        {
                            if (handleMouseDoubleClick(state))
                            {
                                //when we handle a double-click we want to block a normal click from firing.
                                isValidClick = false;
                            }

                            lastClickTime = 0;
                        }

                        lastClickTime = Time.Current;
                    }
                }

                if (!isDragging && Vector2Extensions.Distance(mouse.PositionMouseDown ?? mouse.Position, mouse.Position) > drag_start_distance)
                {
                    isDragging = true;
                    handleMouseDragStart(state);
                }
            }
            else if (last.HasAnyButtonPressed)
            {
                if (isValidClick && (DraggedDrawable == null || Vector2Extensions.Distance(mouse.PositionMouseDown ?? mouse.Position, mouse.Position) < click_drag_distance))
                {
                    handleMouseClick(state);
                }

                mouseDownInputQueue     = null;
                mouse.PositionMouseDown = null;
                isValidClick            = false;

                if (isDragging)
                {
                    isDragging = false;
                    handleMouseDragEnd(state);
                }
            }
        }
 private bool handleMouseMove(InputState state)
 {
     return(mouseInputQueue.Any(target => target.TriggerMouseMove(state)));
 }
Exemple #5
0
        /// <summary>
        /// In order to provide a reliable event system to drawables, we want to ensure that we reprocess input queues (via the
        /// main loop in<see cref="updateInputQueues(InputState)"/> after each and every button or key change. This allows
        /// correct behaviour in a case where the input queues change based on triggered by a button or key.
        /// </summary>
        /// <param name="states">A list of <see cref="InputState"/>s</param>
        /// <returns>Processed states such that at most one button change occurs between any two consecutive states.</returns>
        private IEnumerable <InputState> createDistinctInputStates(List <InputState> states)
        {
            InputState last = CurrentState;

            foreach (var i in states)
            {
                //first we want to create a copy of ourselves without any button changes
                //we do this by updating our buttons to the state of the last frame.
                var iWithoutButtons = i.Clone();

                var iHasMouse    = iWithoutButtons.Mouse != null;
                var iHasKeyboard = iWithoutButtons.Keyboard != null;

                if (iHasMouse)
                {
                    for (MouseButton b = 0; b < MouseButton.LastButton; b++)
                    {
                        iWithoutButtons.Mouse.SetPressed(b, last.Mouse?.IsPressed(b) ?? false);
                    }
                }

                if (iHasKeyboard)
                {
                    iWithoutButtons.Keyboard.Keys = last.Keyboard?.Keys ?? new Key[] { }
                }
                ;

                //we start by adding this state to the processed list...
                yield return(iWithoutButtons);

                last = iWithoutButtons;

                //and then iterate over each button/key change, adding intermediate states along the way.
                if (iHasMouse)
                {
                    for (MouseButton b = 0; b < MouseButton.LastButton; b++)
                    {
                        if (i.Mouse.IsPressed(b) != (last.Mouse?.IsPressed(b) ?? false))
                        {
                            var intermediateState = last.Clone();
                            if (intermediateState.Mouse == null)
                            {
                                intermediateState.Mouse = new MouseState();
                            }

                            //add our single local change
                            intermediateState.Mouse.SetPressed(b, i.Mouse.IsPressed(b));

                            last = intermediateState;
                            yield return(intermediateState);
                        }
                    }
                }

                if (iHasKeyboard)
                {
                    foreach (var releasedKey in last.Keyboard?.Keys.Except(i.Keyboard.Keys) ?? new Key[] { })
                    {
                        var intermediateState = last.Clone();
                        if (intermediateState.Keyboard == null)
                        {
                            intermediateState.Keyboard = new KeyboardState();
                        }

                        intermediateState.Keyboard.Keys = intermediateState.Keyboard.Keys.Where(d => d != releasedKey);

                        last = intermediateState;
                        yield return(intermediateState);
                    }

                    foreach (var pressedKey in i.Keyboard.Keys.Except(last.Keyboard?.Keys ?? new Key[] { }))
                    {
                        var intermediateState = last.Clone();
                        if (intermediateState.Keyboard == null)
                        {
                            intermediateState.Keyboard = new KeyboardState();
                        }

                        intermediateState.Keyboard.Keys = intermediateState.Keyboard.Keys.Union(new[] { pressedKey });

                        last = intermediateState;
                        yield return(intermediateState);
                    }
                }
            }
        }
Exemple #6
0
 private bool handleWheel(InputState state)
 {
     return(PropagateWheel(positionalInputQueue, state));
 }
Exemple #7
0
 /// <summary>
 /// Handles the button being released.
 /// </summary>
 /// <param name="state">The current <see cref="InputState"/>.</param>
 /// <param name="targets">The list of targets that must handle the event. This will contain targets up to the target that handled the button down event.</param>
 protected abstract void HandleButtonUp(InputState state, List <Drawable> targets);
Exemple #8
0
 private bool handleMouseMove(InputState state, Vector2 lastPosition)
 {
     return(PropagateBlockableEvent(PositionalInputQueue, new MouseMoveEvent(state, lastPosition)));
 }
Exemple #9
0
 private bool handleScroll(InputState state, Vector2 lastScroll, bool isPrecise)
 {
     return(PropagateBlockableEvent(PositionalInputQueue, new ScrollEvent(state, state.Mouse.Scroll - lastScroll, isPrecise)));
 }
 private void focusTopMostRequestingDrawable(InputState state) => keyboardInputQueue.FirstOrDefault(target => target.RequestingFocus)?.TriggerFocus(state, true);
Exemple #11
0
 // set PositionMouseDown right before the event is invoked so it can be used as the mouse down position for each button
 private void setPositionMouseDown(InputState state)
 {
     state.Mouse.PositionMouseDown = MouseDownPosition;
 }
 private bool handleWheel(InputState state)
 {
     return(mouseInputQueue.Any(target => target.TriggerWheel(state)));
 }
 private bool handleMouseDragStart(InputState state)
 {
     draggingDrawable = mouseDownInputQueue?.FirstOrDefault(target => target.IsAlive && target.TriggerDragStart(state));
     return(draggingDrawable != null);
 }
 private bool handleMouseDoubleClick(InputState state)
 {
     return(mouseInputQueue.Any(target => target.TriggerDoubleClick(state)));
 }
Exemple #15
0
 private bool handleMouseDoubleClick(InputState state)
 {
     return(positionalInputQueue.Any(target => target.TriggerOnDoubleClick(state)));
 }
Exemple #16
0
 private bool handleKeyDown(InputState state, Key key, bool repeat)
 {
     return(PropagateBlockableEvent(NonPositionalInputQueue, new KeyDownEvent(state, key, repeat)));
 }
Exemple #17
0
 private bool handleMouseDrag(InputState state)
 {
     //Once a drawable is dragged, it remains in a dragged state until the drag is finished.
     return(DraggedDrawable?.TriggerOnDrag(state) ?? false);
 }
Exemple #18
0
 private bool handleKeyUp(InputState state, Key key)
 {
     return(PropagateBlockableEvent(NonPositionalInputQueue, new KeyUpEvent(state, key)));
 }
Exemple #19
0
 /// <summary>
 /// Handles the button being released.
 /// </summary>
 /// <param name="state">The current <see cref="InputState"/>.</param>
 private void handleButtonUp(InputState state)
 {
     HandleButtonUp(state, ButtonDownInputQueue);
     ButtonDownInputQueue = null;
 }
Exemple #20
0
 private bool handleJoystickRelease(InputState state, JoystickButton button)
 {
     return(PropagateBlockableEvent(NonPositionalInputQueue, new JoystickReleaseEvent(state, button)));
 }
Exemple #21
0
 /// <summary>
 /// Handles the button being pressed.
 /// </summary>
 /// <param name="state">The current <see cref="InputState"/>.</param>
 /// <param name="targets">The list of possible targets that can handle the event.</param>
 /// <returns>The <see cref="Drawable"/> that handled the event.</returns>
 protected abstract Drawable HandleButtonDown(InputState state, List <Drawable> targets);
        protected override void Update()
        {
            var pendingStates = createDistinctInputStates(GetPendingStates()).ToArray();

            unfocusIfNoLongerValid(CurrentState);

            //we need to make sure the code in the foreach below is run at least once even if we have no new pending states.
            if (pendingStates.Length == 0)
            {
                pendingStates = new[] { CurrentState }
            }
            ;

            foreach (InputState s in pendingStates)
            {
                bool hasKeyboard = s.Keyboard != null;
                bool hasMouse    = s.Mouse != null;

                if (!hasKeyboard && !hasMouse)
                {
                    continue;
                }

                var last = CurrentState;

                //avoid lingering references that would stay forever.
                last.Last = null;

                CurrentState      = s;
                CurrentState.Last = last;

                if (CurrentState.Keyboard == null)
                {
                    CurrentState.Keyboard = last.Keyboard ?? new KeyboardState();
                }
                if (CurrentState.Mouse == null)
                {
                    CurrentState.Mouse = last.Mouse ?? new MouseState();
                }

                TransformState(CurrentState);

                //move above?
                updateInputQueues(CurrentState);

                if (hasMouse)
                {
                    (s.Mouse as MouseState)?.SetLast(last.Mouse); //necessary for now as last state is used internally for stuff
                    updateHoverEvents(CurrentState);
                    updateMouseEvents(CurrentState);
                }

                if (hasKeyboard)
                {
                    updateKeyboardEvents(CurrentState);
                }
            }

            if (CurrentState.Mouse != null)
            {
                foreach (var d in mouseInputQueue)
                {
                    if (d is IRequireHighFrequencyMousePosition)
                    {
                        if (d.TriggerMouseMove(CurrentState))
                        {
                            break;
                        }
                    }
                }
            }

            keyboardRepeatTime -= Time.Elapsed;

            if (FocusedDrawable == null)
            {
                focusTopMostRequestingDrawable(CurrentState);
            }

            base.Update();
        }