Example #1
0
        public bool OnKeyPressed(
            Key key,
            KeyState key_state,
            double speed_up,
            bool is_short_modifier_press,
            bool is_repetition,
            bool is_modifier,
            InputProvider input_provider)
        {
            // The application grabs control over cursor when modifier is pressed.
            if (key == Key.Modifier)
            {
                if (key_state == KeyState.Down)
                {
                    StartControlling();
                    return(true);
                }

                if (key_state == KeyState.Up)
                {
                    if (mouse_state == EyeTrackingMouse.MouseState.Idle)
                    {
                        return(false);
                    }

                    bool handled = true;
                    if (is_short_modifier_press)
                    {
                        input_provider.SendModifierDown();
                        input_provider.SendModifierUp();
                        handled = true;
                    }
                    StopControlling();
                    return(handled);
                }
            }

            if (mouse_state == EyeTrackingMouse.MouseState.Idle)
            {
                return(false);
            }

            if (key == Key.Unbound)
            {
                // The application intercepts modifier key presses. We do not want to lose modifier when handling unbound keys.
                // We stop controlling cursor when facing the first unbound key and send modifier keystroke to OS before handling pressed key.
                if (!is_modifier)
                {
                    input_provider.SendModifierDown();
                    StopControlling();
                }
                return(false);
            }

            var repetition_white_list = new SortedSet <Key> {
                Key.ScrollDown,
                Key.ScrollUp,
                Key.ScrollLeft,
                Key.ScrollRight,
                Key.CalibrateLeft,
                Key.CalibrateRight,
                Key.CalibrateUp,
                Key.CalibrateDown,
            };

            if (is_repetition && !repetition_white_list.Contains(key))
            {
                return(true);
            }

            if (key_state == KeyState.Down)
            {
                // Calibration
                int calibration_step = (int)(Options.Instance.calibration_step * speed_up);
                if (key == Key.CalibrateLeft)
                {
                    StartCalibration();
                    calibration_shift.X -= calibration_step;
                    freeze_until         = DateTime.Now.AddMilliseconds(Options.Instance.calibrate_freeze_time_ms);
                    statistics.OnCalibrate();
                }
                if (key == Key.CalibrateRight)
                {
                    StartCalibration();
                    calibration_shift.X += calibration_step;
                    freeze_until         = DateTime.Now.AddMilliseconds(Options.Instance.calibrate_freeze_time_ms);
                    statistics.OnCalibrate();
                }
                if (key == Key.CalibrateUp)
                {
                    StartCalibration();
                    calibration_shift.Y -= calibration_step;
                    freeze_until         = DateTime.Now.AddMilliseconds(Options.Instance.calibrate_freeze_time_ms);
                    statistics.OnCalibrate();
                }
                if (key == Key.CalibrateDown)
                {
                    StartCalibration();
                    calibration_shift.Y += calibration_step;
                    freeze_until         = DateTime.Now.AddMilliseconds(Options.Instance.calibrate_freeze_time_ms);
                    statistics.OnCalibrate();
                }

                // Scroll
                if (key == Key.ScrollDown)
                {
                    MouseButtons.WheelDown((int)(Options.Instance.vertical_scroll_step * speed_up));
                }
                if (key == Key.ScrollUp)
                {
                    MouseButtons.WheelUp((int)(Options.Instance.vertical_scroll_step * speed_up));
                }
                if (key == Key.ScrollLeft)
                {
                    MouseButtons.WheelLeft((int)(Options.Instance.horizontal_scroll_step * speed_up));
                }
                if (key == Key.ScrollRight)
                {
                    MouseButtons.WheelRight((int)(Options.Instance.horizontal_scroll_step * speed_up));
                }
            }

            // Mouse buttons
            if (mouse_state == MouseState.Calibrating &&
                (key == Key.LeftMouseButton || key == Key.RightMouseButton))
            {
                ShiftsStorage.Instance.AddShift(
                    new ShiftsStorage.Position(gaze_point.X, gaze_point.Y, left_eye, right_eye, head_position, head_direction),
                    calibration_shift);
                mouse_state = MouseState.Controlling;
            }

            if (key == Key.LeftMouseButton)
            {
                if (key_state == KeyState.Down)
                {
                    // Freeze cursor for a short period of time after mouse clicks to make double clicks esier.
                    MouseButtons.LeftDown();
                    freeze_until = DateTime.Now.AddMilliseconds(Options.Instance.click_freeze_time_ms);
                    statistics.OnClick();
                }
                else if (key_state == KeyState.Up)
                {
                    MouseButtons.LeftUp();
                }
            }

            if (key == Key.RightMouseButton)
            {
                if (key_state == KeyState.Down)
                {
                    // Freeze cursor for a short period of time after mouse clicks to make double clicks esier.
                    MouseButtons.RightDown();
                    freeze_until = DateTime.Now.AddMilliseconds(Options.Instance.click_freeze_time_ms);
                    statistics.OnClick();
                }
                else if (key_state == KeyState.Up)
                {
                    MouseButtons.RightUp();
                }
            }

            if (key == Key.ShowCalibrationView && key_state == KeyState.Down)
            {
                App.ToggleCalibrationWindow();
            }

            return(true);
        }
Example #2
0
        bool InputProvider.IInputReceiver.OnKeyPressed(Key key, KeyState key_state, bool is_modifier)
        {
            lock (Helpers.locker)
            {
                // If you hold a key pressed for a second it will start to produce a sequence of rrrrrrrrrrepeated |KeyState.Down| events.
                // For some keys we don't want to handle such events and assume that a key stays pressed until |KeyState.Up| appears.
                bool is_repetition = interaction_history[0].Key == key &&
                                     interaction_history[0].State == key_state &&
                                     key_state == KeyState.Down;

                if (!is_repetition)
                {
                    interaction_history[2]       = interaction_history[1];
                    interaction_history[1]       = interaction_history[0];
                    interaction_history[0].Key   = key;
                    interaction_history[0].State = key_state;
                    interaction_history[0].Time  = DateTime.Now;
                }

                float speed_up = 1.0f;

                if (is_repetition)
                {
                    speed_up = 2.0f;
                }
                else if (key_state == KeyState.Down &&
                         interaction_history[1].Key == key &&
                         interaction_history[2].Key == key)
                {
                    if ((DateTime.Now - interaction_history[2].Time).TotalMilliseconds < Options.Instance.quadriple_speed_up_press_time_ms)
                    {
                        speed_up = 4.0f;
                    }
                    else if ((DateTime.Now - interaction_history[2].Time).TotalMilliseconds < Options.Instance.double_speedup_press_time_ms)
                    {
                        speed_up = 2.0f;
                    }
                }

                // Single and double modifier presses have different functions
                // Single press goes to OS (this allows using WINDOWS MENU)
                // Double press enables |always_on| mode.
                if (is_waiting_for_second_modifier_press)
                {
                    is_waiting_for_second_modifier_press = false;
                    if (key == Key.Modifier && key_state == KeyState.Down &&
                        (DateTime.Now - interaction_history[1].Time).TotalMilliseconds < 300)
                    {
                        always_on = true;
                        eye_tracking_mouse.StartControlling();
                        return(true);
                    }
                }

                // IF user pressed and released modifier key without pressing other buttons in between...
                if (key == Key.Modifier &&
                    key_state == KeyState.Up &&
                    interaction_history[1].Key == key &&
                    !always_on)
                {
                    double press_duration_ms = (DateTime.Now - interaction_history[1].Time).TotalMilliseconds;

                    // THEN it might be a beginning of a double press...
                    if (press_duration_ms < 300)
                    {
                        is_waiting_for_second_modifier_press = true;
                    }

                    // OR it might be a single modifier press that should go to OS.
                    if (press_duration_ms < Options.Instance.modifier_short_press_duration_ms &&
                        (DateTime.Now - always_on_disabled_time).TotalMilliseconds > 300)
                    {
                        is_waiting_for_second_modifier_press = true;
                        App.Current.Dispatcher.InvokeAsync((async() =>
                        {
                            await Task.Delay(300);
                            lock (Helpers.locker)
                            {
                                if (!is_waiting_for_second_modifier_press)
                                {
                                    return;
                                }
                                is_waiting_for_second_modifier_press = false;
                                input_provider.SendModifierDown();
                                input_provider.SendModifierUp();
                            }
                        }));
                    }
                }

                if (always_on)
                {
                    if (key == Key.Modifier && key_state == KeyState.Up)
                    {
                        return(true);
                    }

                    if (key == Key.Unbound ||
                        (key == Key.Modifier && key_state == KeyState.Down))
                    {
                        always_on = false;
                        always_on_disabled_time = DateTime.Now;
                        eye_tracking_mouse.StopControlling();
                    }
                }

                return(eye_tracking_mouse.OnKeyPressed(key, key_state, speed_up, is_repetition, is_modifier, input_provider));
            }
        }