/************************************************************************* Method that injects a mouse button up event into the system. *************************************************************************/ bool System::injectMouseButtonUp(MouseButton button) { // update system keys d_sysKeys &= ~mouseButtonToSyskey(button); MouseEventArgs ma(0); ma.position = MouseCursor::getSingleton().getPosition(); ma.moveDelta = Vector2(0.0f, 0.0f); ma.button = button; ma.sysKeys = d_sysKeys; ma.wheelChange = 0; // get the tracker that holds the number of down events seen so far for this button MouseClickTracker& tkr = d_clickTrackerPimpl->click_trackers[button]; // set click count in the event args ma.clickCount = tkr.d_click_count; Window* const initial_dest_window = getTargetWindow(ma.position); Window* dest_window = initial_dest_window; // loop backwards until event is handled or we run out of windows. while ((!ma.handled) && (dest_window != 0)) { ma.window = dest_window; dest_window->onMouseButtonUp(ma); dest_window = getNextTargetWindow(dest_window); } bool wasUpHandled = ma.handled; // if requirements for click events are met if (((d_click_timeout == 0) || (tkr.d_timer.elapsed() <= d_click_timeout)) && (tkr.d_click_area.isPointInRect(ma.position)) && (tkr.d_target_window == initial_dest_window)) { ma.handled = false; dest_window = initial_dest_window; // loop backwards until event is handled or we run out of windows. while ((!ma.handled) && (dest_window != 0)) { ma.window = dest_window; dest_window->onMouseClicked(ma); dest_window = getNextTargetWindow(dest_window); } } return (ma.handled | wasUpHandled); }
/************************************************************************* Method that injects a key up event into the system. *************************************************************************/ bool System::injectKeyUp(uint key_code) { // update system keys d_sysKeys &= ~keyCodeToSyskey((Key::Scan)key_code, false); KeyEventArgs args(0); if (d_activeSheet) { args.scancode = (Key::Scan)key_code; args.sysKeys = d_sysKeys; Window* dest = getKeyboardTargetWindow(); // loop backwards until event is handled or we run out of windows. while ((dest != 0) && (!args.handled)) { args.window = dest; dest->onKeyUp(args); dest = getNextTargetWindow(dest); } } return args.handled; }
/************************************************************************* Method that injects a mouse movement event into the system *************************************************************************/ bool System::injectMouseMove(float delta_x, float delta_y) { MouseEventArgs ma(NULL); MouseCursor& mouse = MouseCursor::getSingleton(); ma.moveDelta.d_x = delta_x * d_mouseScalingFactor; ma.moveDelta.d_y = delta_y * d_mouseScalingFactor; ma.sysKeys = d_sysKeys; ma.wheelChange = 0; ma.clickCount = 0; // move the mouse cursor & update position in args. mouse.offsetPosition(ma.moveDelta); ma.position = mouse.getPosition(); Window* dest_window = getTargetWindow(ma.position); // if there is no GUI sheet, then there is nowhere to send input if (dest_window != NULL) { if (dest_window != d_wndWithMouse) { if (d_wndWithMouse != NULL) { ma.window = d_wndWithMouse; d_wndWithMouse->onMouseLeaves(ma); } d_wndWithMouse = dest_window; ma.window = dest_window; dest_window->onMouseEnters(ma); } // ensure event starts as 'not handled' ma.handled = false; // loop backwards until event is handled or we run out of windows. while ((!ma.handled) && (dest_window != NULL)) { ma.window = dest_window; dest_window->onMouseMove(ma); dest_window = getNextTargetWindow(dest_window); } } return ma.handled; }
//----------------------------------------------------------------------------// bool System::mouseMoveInjection_impl(MouseEventArgs& ma) { Window* dest_window = getTargetWindow(ma.position); // has window containing mouse changed? if (dest_window != d_wndWithMouse) { // store previous window that contained mouse Window* oldWindow = d_wndWithMouse; // set the new window that contains the mouse. d_wndWithMouse = dest_window; // inform previous window the mouse has left it if (oldWindow) { ma.window = oldWindow; oldWindow->onMouseLeaves(ma); } // inform window containing mouse that mouse has entered it if (d_wndWithMouse) { ma.window = d_wndWithMouse; ma.handled = false; d_wndWithMouse->onMouseEnters(ma); } } // inform appropriate window of the mouse movement event if (dest_window) { // ensure event starts as 'not handled' ma.handled = false; // loop backwards until event is handled or we run out of windows. while ((!ma.handled) && (dest_window != 0)) { ma.window = dest_window; dest_window->onMouseMove(ma); dest_window = getNextTargetWindow(dest_window); } } return ma.handled; }
/************************************************************************* Method that injects a mouse-wheel / scroll-wheel event into the system. *************************************************************************/ bool System::injectMouseWheelChange(float delta) { MouseEventArgs ma(0); ma.position = MouseCursor::getSingleton().getPosition(); ma.moveDelta = Vector2(0.0f, 0.0f); ma.button = NoButton; ma.sysKeys = d_sysKeys; ma.wheelChange = delta; ma.clickCount = 0; Window* dest_window = getTargetWindow(ma.position); // loop backwards until event is handled or we run out of windows. while ((!ma.handled) && (dest_window != 0)) { ma.window = dest_window; dest_window->onMouseWheel(ma); dest_window = getNextTargetWindow(dest_window); } return ma.handled; }
/************************************************************************* Method that injects a typed character event into the system. *************************************************************************/ bool System::injectChar(utf32 code_point) { KeyEventArgs args(0); if (d_activeSheet) { args.codepoint = code_point; args.sysKeys = d_sysKeys; Window* dest = getKeyboardTargetWindow(); // loop backwards until event is handled or we run out of windows. while ((dest != 0) && (!args.handled)) { args.window = dest; dest->onCharacter(args); dest = getNextTargetWindow(dest); } } return args.handled; }
/************************************************************************* Method that injects a mouse button down event into the system. *************************************************************************/ bool System::injectMouseButtonDown(MouseButton button) { // update system keys d_sysKeys |= mouseButtonToSyskey(button); MouseEventArgs ma(0); ma.position = MouseCursor::getSingleton().getPosition(); ma.moveDelta = Vector2(0.0f, 0.0f); ma.button = button; ma.sysKeys = d_sysKeys; ma.wheelChange = 0; // find the likely destination for generated events. Window* dest_window = getTargetWindow(ma.position); // // Handling for multi-click generation // MouseClickTracker& tkr = d_clickTrackerPimpl->click_trackers[button]; tkr.d_click_count++; // if multi-click requirements are not met if (((d_dblclick_timeout > 0) && (tkr.d_timer.elapsed() > d_dblclick_timeout)) || (!tkr.d_click_area.isPointInRect(ma.position)) || (tkr.d_target_window != dest_window) || (tkr.d_click_count > 3)) { // reset to single down event. tkr.d_click_count = 1; // build new allowable area for multi-clicks tkr.d_click_area.setPosition(ma.position); tkr.d_click_area.setSize(d_dblclick_size); tkr.d_click_area.offset(Point(-(d_dblclick_size.d_width / 2), -(d_dblclick_size.d_height / 2))); // set target window for click events on this tracker tkr.d_target_window = dest_window; } // set click count in the event args ma.clickCount = tkr.d_click_count; // loop backwards until event is handled or we run out of windows. while ((!ma.handled) && (dest_window != 0)) { ma.window = dest_window; if (dest_window->wantsMultiClickEvents()) { switch (tkr.d_click_count) { case 1: dest_window->onMouseButtonDown(ma); break; case 2: dest_window->onMouseDoubleClicked(ma); break; case 3: dest_window->onMouseTripleClicked(ma); break; } } // current target window does not want multi-clicks, // so just send a mouse down event instead. else { dest_window->onMouseButtonDown(ma); } dest_window = getNextTargetWindow(dest_window); } // reset timer for this tracker. tkr.d_timer.restart(); return ma.handled; }