public override bool Initialize(GameHost host)
        {
            host.Window.MouseEnter += window_MouseEnter;
            host.Window.MouseLeave += window_MouseLeave;

            mouseInWindow = host.Window.CursorInWindow;

            // Get the bindables we need to determine whether to confine the mouse to window or not
            DesktopGameWindow desktopWindow = host.Window as DesktopGameWindow;

            if (desktopWindow != null)
            {
                confineMode.BindTo(desktopWindow.ConfineMouseMode);
                windowMode.BindTo(desktopWindow.WindowMode);
            }

            Enabled.ValueChanged += enabled =>
            {
                if (enabled)
                {
                    host.InputThread.Scheduler.Add(scheduled = new ScheduledDelegate(delegate
                    {
                        if (!host.Window.Visible)
                        {
                            return;
                        }

                        bool useRawInput = mouseInWindow && host.Window.Focused;

                        var state = useRawInput ? OpenTK.Input.Mouse.GetState() : OpenTK.Input.Mouse.GetCursorState();

                        if (state.Equals(lastState))
                        {
                            return;
                        }

                        if (useRawInput)
                        {
                            if (!lastState.HasValue)
                            {
                                // when we return from being outside of the window, we want to set the new position of our game cursor
                                // to where the OS cursor is, just once.
                                var cursorState = OpenTK.Input.Mouse.GetCursorState();
                                var screenPoint = host.Window.PointToClient(new Point(cursorState.X, cursorState.Y));
                                currentPosition = new Vector2(screenPoint.X, screenPoint.Y);
                            }
                            else
                            {
                                currentPosition += new Vector2(state.X - lastState.Value.X, state.Y - lastState.Value.Y) * (float)sensitivity.Value;

                                // When confining, clamp to the window size.
                                if (confineMode.Value == ConfineMouseMode.Always || confineMode.Value == ConfineMouseMode.Fullscreen && windowMode.Value == WindowMode.Fullscreen)
                                {
                                    currentPosition = Vector2.Clamp(currentPosition, Vector2.Zero, new Vector2(host.Window.Width, host.Window.Height));
                                }

                                // update the windows cursor to match our raw cursor position.
                                // this is important when sensitivity is decreased below 1.0, where we need to ensure the cursor stays withing the window.
                                var screenPoint = host.Window.PointToScreen(new Point((int)currentPosition.X, (int)currentPosition.Y));
                                OpenTK.Input.Mouse.SetPosition(screenPoint.X, screenPoint.Y);
                            }
                        }
                        else
                        {
                            var screenPoint = host.Window.PointToClient(new Point(state.X, state.Y));
                            currentPosition = new Vector2(screenPoint.X, screenPoint.Y);
                        }

                        IMouseState newState;

                        // While not focused, let's silently ignore everything but position.
                        if (host.IsActive)
                        {
                            lastState = state;
                            newState  = new OpenTKPollMouseState(state, host.IsActive, currentPosition);
                        }
                        else
                        {
                            lastState = null;
                            newState  = new UnfocusedMouseState(new OpenTK.Input.MouseState(), host.IsActive, currentPosition);
                        }

                        PendingStates.Enqueue(new InputState {
                            Mouse = newState
                        });

                        FrameStatistics.Increment(StatisticsCounterType.MouseEvents);
                    }, 0, 0));
                }
                else
                {
                    scheduled?.Cancel();
                    lastState = null;
                }
            };
            Enabled.TriggerChange();
            return(true);
        }
Esempio n. 2
0
        public override bool Initialize(GameHost host)
        {
            base.Initialize(host);

            // Get the bindables we need to determine whether to confine the mouse to window or not
            if (host.Window is DesktopGameWindow desktopWindow)
            {
                confineMode.BindTo(desktopWindow.ConfineMouseMode);
                windowMode.BindTo(desktopWindow.WindowMode);
                mapAbsoluteInputToWindow.BindTo(desktopWindow.MapAbsoluteInputToWindow);
            }

            Enabled.BindValueChanged(enabled =>
            {
                if (enabled)
                {
                    host.InputThread.Scheduler.Add(scheduled = new ScheduledDelegate(delegate
                    {
                        if (!host.Window.Visible || host.Window.WindowState == WindowState.Minimized)
                        {
                            return;
                        }

                        if ((MouseInWindow || lastEachDeviceStates.Any(s => s != null && s.Buttons.HasAnyButtonPressed)) && host.Window.Focused)
                        {
                            osuTK.Input.Mouse.GetStates(newRawStates);

                            while (lastEachDeviceStates.Count < newRawStates.Count)
                            {
                                lastEachDeviceStates.Add(null);
                            }

                            for (int i = 0; i < newRawStates.Count; i++)
                            {
                                if (newRawStates[i].IsConnected != true)
                                {
                                    lastEachDeviceStates[i] = null;
                                    continue;
                                }

                                var rawState  = newRawStates[i];
                                var lastState = lastEachDeviceStates[i];

                                if (lastState != null && rawState.Equals(lastState.RawState))
                                {
                                    continue;
                                }

                                var newState = new OsuTKPollMouseState(rawState, host.IsActive, getUpdatedPosition(rawState, lastState));

                                HandleState(newState, lastState, rawState.Flags.HasFlag(MouseStateFlags.MoveAbsolute));

                                lastEachDeviceStates[i] = newState;
                                lastUnfocusedState      = null;
                            }
                        }
                        else
                        {
                            var state       = osuTK.Input.Mouse.GetCursorState();
                            var screenPoint = host.Window.PointToClient(new Point(state.X, state.Y));

                            var newState = new UnfocusedMouseState(new MouseState(), host.IsActive, new Vector2(screenPoint.X, screenPoint.Y));

                            HandleState(newState, lastUnfocusedState, true);

                            lastUnfocusedState = newState;
                            lastEachDeviceStates.Clear();
                        }
                    }, 0, 0));
                }
                else
                {
                    scheduled?.Cancel();
                    lastEachDeviceStates.Clear();
                    lastUnfocusedState = null;
                }
            }, true);

            return(true);
        }
        public override bool Initialize(GameHost host)
        {
            host.Window.MouseEnter += window_MouseEnter;
            host.Window.MouseLeave += window_MouseLeave;

            this.host = host;

            mouseInWindow = host.Window.CursorInWindow;

            // Get the bindables we need to determine whether to confine the mouse to window or not
            if (host.Window is DesktopGameWindow desktopWindow)
            {
                confineMode.BindTo(desktopWindow.ConfineMouseMode);
                windowMode.BindTo(desktopWindow.WindowMode);
                mapAbsoluteInputToWindow.BindTo(desktopWindow.MapAbsoluteInputToWindow);
            }

            Enabled.ValueChanged += enabled =>
            {
                if (enabled)
                {
                    host.InputThread.Scheduler.Add(scheduled = new ScheduledDelegate(delegate
                    {
                        if (!host.Window.Visible || host.Window.WindowState == WindowState.Minimized)
                        {
                            return;
                        }

                        if ((mouseInWindow || lastStates.Any(s => s.HasAnyButtonPressed)) && host.Window.Focused)
                        {
                            var newStates = new List <OpenTK.Input.MouseState>(mostSeenStates + 1);

                            for (int i = 0; i <= mostSeenStates + 1; i++)
                            {
                                var s = OpenTK.Input.Mouse.GetState(i);
                                if (s.IsConnected || i < mostSeenStates)
                                {
                                    newStates.Add(s);
                                    mostSeenStates = i;
                                }
                            }

                            while (lastStates.Count < newStates.Count)
                            {
                                lastStates.Add(null);
                            }

                            for (int i = 0; i < newStates.Count; i++)
                            {
                                if (newStates[i].IsConnected != true)
                                {
                                    lastStates[i] = null;
                                    continue;
                                }

                                var state     = newStates[i];
                                var lastState = lastStates[i];

                                if (lastState != null && state.Equals(lastState.RawState))
                                {
                                    continue;
                                }

                                var newState = new OpenTKPollMouseState(state, host.IsActive, getUpdatedPosition(state, lastState));

                                lastStates[i] = newState;

                                if (lastState != null)
                                {
                                    handleState(lastRawState = newState);
                                }
                            }
                        }
                        else
                        {
                            var state       = OpenTK.Input.Mouse.GetCursorState();
                            var screenPoint = host.Window.PointToClient(new Point(state.X, state.Y));
                            handleState(lastUnfocusedState = new UnfocusedMouseState(new OpenTK.Input.MouseState(), host.IsActive, new Vector2(screenPoint.X, screenPoint.Y)));

                            lastStates.Clear();
                        }
                    }, 0, 0));
                }
                else
                {
                    scheduled?.Cancel();
                    lastStates.Clear();
                }
            };

            Enabled.TriggerChange();
            return(true);
        }