void DeactivateTouchpad() { Vector3 saved = current_position; if (active_touchpad_state == ActiveTouchpadState.SmallDelay) { /* we are in the "small delay" state. Send the touchpad-touch event now */ active_touchpad_state = ActiveTouchpadState.Action3; current_position = touch_original_pos3; active_touchpad._Call(active_touchpad._i_onTouchDown, this); active_touchpad._Call(active_touchpad._i_onTouchDrag, this); } StopTouchpadAction(); current_position = saved; if (active_touchpad == tracker_hover) { tracker_hover_lock &= ~(1U << (int)EControllerButton.Touchpad); } active_touchpad = null; }
void StopTouchpadAction() { switch (active_touchpad_state) { case ActiveTouchpadState.Action1: /* stop pressing the touchpad */ active_touchpad._Call(active_touchpad._i_onTouchPressUp, this); break; case ActiveTouchpadState.Action2: /* stop scrolling (no event sent, for now) */ scrollWheelVisible &= ~SWV_SCROLLING; UpdateScrollWheel(); break; case ActiveTouchpadState.Action3: /* stop touching the touchpad */ active_touchpad._Call(active_touchpad._i_onTouchUp, this); break; } active_touchpad_state = ActiveTouchpadState.None; touch_original_pos2 = touchpadPosition; /* in case touchpadTouched is still true */ }
void CallButtonDown() { const float TOUCHPAD_CLICK_TIME = 0.25f; const EEventSet TouchpadAll = (EEventSet.TouchpadAction1 | EEventSet.TouchpadAction2 | EEventSet.TouchpadAction3); if (bitmask_buttons_down != 0) { if (active_trigger == null) { active_trigger = HandleButtonDown(EControllerButton.Trigger, EEventSet.Trigger); } if (active_grip == null) { active_grip = HandleButtonDown(EControllerButton.Grip, EEventSet.Grip); } HandleButtonDown(EControllerButton.Menu, EEventSet.Menu); /* == Handle the touchpad == */ if ((bitmask_buttons_down & (1U << (int)EControllerButton.TouchpadTouched)) != 0) { /* starting to touch: the only case is "released" => "small delay" */ touch_original_pos2 = touchpadPosition; if (active_touchpad_state == ActiveTouchpadState.None) { Debug.Assert(active_touchpad == null); active_touchpad = FindHandler(TouchpadAll); if (active_touchpad != null) { if (active_touchpad == tracker_hover) { tracker_hover_lock |= 1U << (int)EControllerButton.Touchpad; } EEventSet es = active_touchpad._event_sets; int count = ((es & EEventSet.TouchpadAction1) != 0 ? 1 : 0) + ((es & EEventSet.TouchpadAction2) != 0 ? 1 : 0) + ((es & EEventSet.TouchpadAction3) != 0 ? 1 : 0); float delay = count >= 2 ? TOUCHPAD_CLICK_TIME : 1e-20f; active_touchpad_state = ActiveTouchpadState.SmallDelay; active_touchpad_timeout = GetTime() + delay; touch_original_pos3 = position; } } } if ((bitmask_buttons_down & (1U << (int)EControllerButton.Touchpad)) != 0) { /* pressing: goes to "action 1" if the tracker handles it */ ControllerTracker cs = active_touchpad; if (cs == null) { cs = HandleButtonDown(EControllerButton.Touchpad, EEventSet.TouchpadAction1); } if (cs != null && (cs._event_sets & EEventSet.TouchpadAction1) != 0) { StopTouchpadAction(); active_touchpad_state = ActiveTouchpadState.Action1; active_touchpad = cs; active_touchpad._Call(active_touchpad._i_onTouchPressDown, this); } } } /* == More touchpad handling == */ if (touchpadTouched) { if (active_touchpad_state == ActiveTouchpadState.None || active_touchpad_state == ActiveTouchpadState.SmallDelay) { const float TOUCHPAD_SCROLL_DISTANCE = 0.22f; const float TOUCHPAD_DRAG_SPACE_DISTANCE = 0.08f; ControllerTracker cs = active_touchpad; if (cs == null) { cs = FindHandler(EEventSet.TouchpadAction2 | EEventSet.TouchpadAction3); } if (cs != null) { if ((cs._event_sets & EEventSet.TouchpadAction2) != 0) { /* detect finger movement */ if (Vector2.Distance(touch_original_pos2, touchpadPosition) > TOUCHPAD_SCROLL_DISTANCE) { active_touchpad_timeout = 0; active_touchpad_state = ActiveTouchpadState.Action2; active_touchpad = cs; if (active_touchpad == tracker_hover) { tracker_hover_lock |= 1U << (int)EControllerButton.Touchpad; } scrollWheelVisible |= SWV_SCROLLING; UpdateScrollWheel(); } } if (active_touchpad_state == ActiveTouchpadState.SmallDelay && (cs._event_sets & EEventSet.TouchpadAction3) != 0) { /* detect timeout or controller movement from the "small delay" state */ if (active_touchpad_timeout <= GetTime() || Vector3.Distance(touch_original_pos3, position) > TOUCHPAD_DRAG_SPACE_DISTANCE) { Vector3 saved = current_position; active_touchpad_state = ActiveTouchpadState.Action3; active_touchpad = cs; current_position = touch_original_pos3; active_touchpad._Call(active_touchpad._i_onTouchDown, this); current_position = saved; } } } } } }