コード例 #1
0
ファイル: InputAPI.cpp プロジェクト: aoighost/tundra-urho3d
void InputAPI::SceneReleaseMouseButtons()
{
    for(int i = 1; i < MouseEvent::MaxButtonMask; i <<= 1)
        if ((heldMouseButtons & i) != 0)
        {
            // Just like with key release events, we send a very bare-bone release message here as well.
            MouseEvent mouseEvent(this);
            mouseEvent.eventType = MouseEvent::MouseReleased;
            mouseEvent.button = (MouseEvent::MouseButton)i;
            mouseEvent.x = lastMouseX;
            mouseEvent.y = lastMouseY;
            mouseEvent.z = 0;
            mouseEvent.relativeX = 0;
            mouseEvent.relativeY = 0;
            mouseEvent.relativeZ = 0;

            mouseEvent.globalX = 0;
            mouseEvent.globalY = 0;

            mouseEvent.otherButtons = 0;

            mouseEvent.timestamp = framework->Frame()->WallClockTime();

            TriggerMouseEvent(mouseEvent);
        }
}
コード例 #2
0
ファイル: InputAPI.cpp プロジェクト: aoighost/tundra-urho3d
//bool InputAPI::eventFilter(Object *obj, QEvent *event)
void InputAPI::EventFilter(StringHash eventType, VariantMap& eventData)
{
    Urho3D::Input* input = GetSubsystem<Urho3D::Input>();

    if (eventType == Urho3D::E_KEYDOWN)
    {
        KeyEvent keyEvent(this);
        keyEvent.urhoEvent = eventData;
        keyEvent.keyCode = eventData[Urho3D::KeyDown::P_KEY].GetInt();// StripModifiersFromKey(e->key());
        keyEvent.sequence = KeySequence(eventData[Urho3D::KeyDown::P_KEY].GetInt() | eventData[Urho3D::KeyDown::P_QUALIFIERS].GetInt());
        keyEvent.keyPressCount = 1;
        keyEvent.modifiers = eventData[Urho3D::KeyDown::P_QUALIFIERS].GetInt();
        //keyEvent.text = e->text(); ///\todo
        keyEvent.eventType = KeyEvent::KeyPressed;
        keyEvent.timestamp = framework->Frame()->WallClockTime();
        // Assign the keys from the heldKeys map to the keyEvent.otherHeldKeys vector
        for (auto current = heldKeys.Begin(); current != heldKeys.End(); ++ current)
            keyEvent.otherHeldKeys.Push((*current).first_);

        keyEvent.handled = false;

        currentModifiers = eventData[Urho3D::KeyDown::P_QUALIFIERS].GetInt(); // local tracking for mouse events

        auto keyRecord = heldKeys.Find(keyEvent.keyCode);
        if (keyRecord == heldKeys.End())
        {
            KeyPressInformation info;
            info.keyPressCount = 1;
            info.keyState = KeyEvent::KeyPressed;
            //info.firstPressTime = now; ///\todo
            heldKeys[keyEvent.keyCode] = info;
        }

        // Queue up the press event for the polling API
        if (keyEvent.keyPressCount == 1) /// \todo The polling API does not get key repeats at all. Should it?
            newKeysPressedQueue.Push(eventData[Urho3D::KeyDown::P_KEY].GetInt());

        TriggerKeyEvent(keyEvent);

        return; // If we got true here, need to suppress this event from going to Qt.
    }

    else if (eventType == Urho3D::E_KEYUP)
    {
        HeldKeysMap::Iterator existingKey = heldKeys.Find(eventData[Urho3D::KeyDown::P_KEY].GetInt());

        // If we received a release on an unknown key we haven't received a press for, don't pass it to the scene,
        // since we didn't pass the press to the scene either (or we've already passed the release before, so don't 
        // pass duplicate releases).
        if (existingKey == heldKeys.End())
            return;

        KeyEvent keyEvent(this);
        keyEvent.urhoEvent = eventData;
        keyEvent.keyCode = eventData[Urho3D::KeyDown::P_KEY].GetInt();
        keyEvent.keyPressCount = existingKey->second_.keyPressCount;
        keyEvent.modifiers = eventData[Urho3D::KeyDown::P_QUALIFIERS].GetInt();
        //keyEvent.text = e->text(); ///\todo
        keyEvent.eventType = KeyEvent::KeyReleased;
        //keyEvent.otherHeldKeys = heldKeys; ///\todo
        keyEvent.handled = false;
        keyEvent.timestamp = framework->Frame()->WallClockTime();

        heldKeys.Erase(existingKey);
        currentModifiers = eventData[Urho3D::KeyDown::P_QUALIFIERS].GetInt(); // local tracking for mouse events

        // Queue up the release event for the polling API, independent of whether any Qt widget has keyboard focus.
        if (keyEvent.keyPressCount == 1) /// \todo The polling API does not get key repeats at all. Should it?
            newKeysReleasedQueue.Push(eventData[Urho3D::KeyDown::P_KEY].GetInt());

        TriggerKeyEvent(keyEvent);
        
        return; // Suppress this event from going forward.
    }

    else if (eventType == Urho3D::E_MOUSEBUTTONDOWN || eventType == Urho3D::E_MOUSEBUTTONUP)
    {
        // We always update the global polled input states, independent of whether any the mouse cursor is
        // on top of any Qt widget.
        if (eventType == Urho3D::E_MOUSEBUTTONDOWN)
        {
            heldMouseButtons |= eventData[Urho3D::MouseButtonDown::P_BUTTON].GetInt();  //(MouseEvent::MouseButton)e->button();
            newMouseButtonsPressedQueue |= eventData[Urho3D::MouseButtonDown::P_BUTTON].GetInt();
        }
        else
        {
            heldMouseButtons &= ~eventData[Urho3D::MouseButtonDown::P_BUTTON].GetInt();
            newMouseButtonsReleasedQueue |= eventData[Urho3D::MouseButtonDown::P_BUTTON].GetInt();
        }

        // The mouse coordinates we receive can come from different widgets, and we are interested only in the coordinates
        // in the QGraphicsView client area, so we need to remap them.
        Point mousePos(input->GetMousePosition().x_, input->GetMousePosition().y_);//MapPointToMainGraphicsView(obj, e->pos());

        MouseEvent mouseEvent(this);
        mouseEvent.eventType = (eventType == Urho3D::E_MOUSEBUTTONDOWN) ? MouseEvent::MousePressed : MouseEvent::MouseReleased;

        mouseEvent.button = (MouseEvent::MouseButton)eventData[Urho3D::MouseButtonDown::P_BUTTON].GetInt();
        mouseEvent.x = mousePos.x;
        mouseEvent.y = mousePos.y;
        mouseEvent.z = 0;
        // Mouse presses do not carry relative mouse movement information at the same time.
        // (separate relative movement messages are passed for first-person mode moves)
        mouseEvent.relativeX = 0;
        mouseEvent.relativeY = 0;
        
        mouseEvent.relativeZ = 0;
        mouseEvent.modifiers = eventData[Urho3D::MouseButtonDown::P_QUALIFIERS].GetInt();//currentModifiers;

        lastMouseX = mouseEvent.x;
        lastMouseY = mouseEvent.y;

        mouseEvent.globalX = mouseEvent.x;
        mouseEvent.globalY = mouseEvent.y;

        mouseEvent.otherButtons = eventData[Urho3D::MouseButtonDown::P_BUTTONS].GetUInt();
        mouseEvent.modifiers = eventData[Urho3D::MouseButtonDown::P_QUALIFIERS].GetInt();
        for (auto current = heldKeys.Begin(); current != heldKeys.End(); ++ current)
            mouseEvent.heldKeys.Push((*current).first_);
        mouseEvent.handled = false;
        mouseEvent.timestamp = framework->Frame()->WallClockTime();

        TriggerMouseEvent(mouseEvent);
        return;
    }

    //case Urho3D::E_MOUSEMOVE:
    else if (eventType == Urho3D::E_MOUSEMOVE)
    {
        MouseEvent mouseEvent(this);
        mouseEvent.eventType = MouseEvent::MouseMove;
        mouseEvent.button = (MouseEvent::MouseButton)eventData[Urho3D::MouseMove::P_BUTTONS].GetInt();

        // The mouse coordinates we receive can come from different widgets, and we are interested only in the coordinates
        // in the QGraphicsView client area, so we need to remap them.
        Point mousePos(input->GetMousePosition().x_, input->GetMousePosition().y_);

        mouseEvent.z = 0;
        mouseEvent.relativeX = eventData[Urho3D::MouseMove::P_DX].GetInt();
        mouseEvent.relativeY = eventData[Urho3D::MouseMove::P_DY].GetInt();
        mouseEvent.relativeZ = 0;

        mouseEvent.x = mousePos.x;
        mouseEvent.y = mousePos.y;

        // If there wasn't any change to the mouse relative coords in FPS mode, ignore this event.
        if (mouseEvent.relativeX == 0 && mouseEvent.relativeY == 0)
            return;
        
        mouseEvent.globalX = mousePos.x;
        mouseEvent.globalY = mousePos.y;
        mouseEvent.otherButtons = eventData[Urho3D::MouseMove::P_BUTTONS].GetInt();
        for (auto current = heldKeys.Begin(); current != heldKeys.End(); ++ current)
            mouseEvent.heldKeys.Push((*current).first_);
        mouseEvent.handled = false;
        mouseEvent.timestamp = framework->Frame()->WallClockTime();

        // Save the absolute coordinates to be able to compute the proper relative movement values in the next
        // mouse event.
        lastMouseX = mouseEvent.x;
        lastMouseY = mouseEvent.y;

        TriggerMouseEvent(mouseEvent);

        return;
    }

    else if (eventType == Urho3D::E_MOUSEWHEEL)
    {
        MouseEvent mouseEvent(this);
        mouseEvent.eventType = MouseEvent::MouseScroll;
        
        mouseEvent.button = MouseEvent::NoButton;
        mouseEvent.otherButtons = eventData[Urho3D::MouseWheel::P_BUTTONS].GetInt();
        mouseEvent.x = input->GetMousePosition().x_;
        mouseEvent.y = input->GetMousePosition().y_;
        mouseEvent.z = 0; // Mouse wheel does not have an absolute z position, only relative.
        mouseEvent.relativeX = 0;
        mouseEvent.relativeY = 0;
        mouseEvent.relativeZ = eventData[Urho3D::MouseWheel::P_WHEEL].GetInt();
        mouseEvent.globalX = input->GetMousePosition().x_;
        mouseEvent.globalY = input->GetMousePosition().y_;

        mouseEvent.modifiers = eventData[Urho3D::MouseWheel::P_QUALIFIERS].GetInt();
        for (auto current = heldKeys.Begin(); current != heldKeys.End(); ++ current)
            mouseEvent.heldKeys.Push((*current).first_);
        mouseEvent.handled = false;
        mouseEvent.timestamp = framework->Frame()->WallClockTime();

        TriggerMouseEvent(mouseEvent);
        return;
    }
    else if (eventType == Urho3D::E_TOUCHBEGIN)
    {
        UpdateTouchPoints();
        TouchBegin.Emit(eventData);
        return;
    }
    else if (eventType == Urho3D::E_TOUCHMOVE)
    {
        UpdateTouchPoints();
        TouchUpdate.Emit(eventData);
        return;
    }

    else if (eventType == Urho3D::E_TOUCHEND)
    {
        UpdateTouchPoints();
        TouchEnd.Emit(eventData);
        return;
        
    } // ~switch
}
コード例 #3
0
ファイル: QtInputService.cpp プロジェクト: joni-mikkola/naali
bool QtInputService::eventFilter(QObject *obj, QEvent *event)
{
    switch(event->type())
    {
    case QEvent::KeyPress:
    {
        QKeyEvent *e = static_cast<QKeyEvent*>(event);

        KeyEvent keyEvent;
        keyEvent.keyCode = StripModifiersFromKey(e->key());
        keyEvent.keyPressCount = 1;
        keyEvent.modifiers = e->modifiers();
        keyEvent.text = e->text();
        keyEvent.sequence = QKeySequence(e->key() | e->modifiers()); ///\todo Track multi-key sequences.
        keyEvent.eventType = KeyEvent::KeyPressed;
//		keyEvent.otherHeldKeys = heldKeys; ///\todo
        keyEvent.handled = false;

        current_modifiers_ = e->modifiers(); // local tracking for mouse events

        // We only take key events from the main QGraphicsView.
        if (obj != qobject_cast<QObject*>(mainView))
            return false;

        std::map<Qt::Key, KeyPressInformation>::iterator keyRecord = heldKeys.find(keyEvent.keyCode);
        if (keyRecord != heldKeys.end())
        {
            if (e->isAutoRepeat()) // If this is a repeat, track the proper keyPressCount.
            {
                keyEvent.keyPressCount = ++keyRecord->second.keyPressCount;
                keyEvent.sequence = QKeySequence(); // Repeated keys do not trigger keysequences.
            }
        }
        else
        {
            KeyPressInformation info;
            info.keyPressCount = 1;
            info.keyState = KeyEvent::KeyPressed;
//            info.firstPressTime = now; ///\todo
            heldKeys[keyEvent.keyCode] = info;
        }

        // Queue up the press event for the polling API, independent of whether any Qt widget has keyboard focus.
        if (keyEvent.keyPressCount == 1) /// \todo The polling API does not get key repeats at all. Should it?
            newKeysPressedQueue.push_back(StripModifiersFromKey(e->key()));

        TriggerKeyEvent(keyEvent);

        return keyEvent.handled; // If we got true here, need to suppress this event from going to Qt.
    }

    case QEvent::KeyRelease:
    {
        // We only take key events from the main window.
        if (obj != qobject_cast<QObject*>(mainWindow))
            return false;

        QKeyEvent *e = static_cast<QKeyEvent *>(event);

        // Our input system policy: Key releases on repeated keys are not transmitted. This means
        // that the client gets always a sequences like "press (first), press(1st repeat), press(2nd repeat), release",
        // instead of "press(first), release, press(1st repeat), release, press(2nd repeat), release".
        if (e->isAutoRepeat())
            return false;

        HeldKeysMap::iterator existingKey = heldKeys.find(StripModifiersFromKey(e->key()));

        // If we received a release on an unknown key we haven't received a press for, don't pass it to the scene,
        // since we didn't pass the press to the scene either (or we've already passed the release before, so don't
        // pass duplicate releases).
        if (existingKey == heldKeys.end())
            return false;

        KeyEvent keyEvent;
        keyEvent.keyCode = StripModifiersFromKey(e->key());
        keyEvent.keyPressCount = existingKey->second.keyPressCount;
        keyEvent.modifiers = e->modifiers();
        keyEvent.text = e->text();
        keyEvent.eventType = KeyEvent::KeyReleased;
//		keyEvent.otherHeldKeys = heldKeys; ///\todo
        keyEvent.handled = false;

        heldKeys.erase(existingKey);
        current_modifiers_ = e->modifiers(); // local tracking for mouse events

        // Queue up the release event for the polling API, independent of whether any Qt widget has keyboard focus.
        if (keyEvent.keyPressCount == 1) /// \todo The polling API does not get key repeats at all. Should it?
            newKeysReleasedQueue.push_back(StripModifiersFromKey(e->key()));

        TriggerKeyEvent(keyEvent);

        return keyEvent.handled; // Suppress this event from going forward.
    }

    case QEvent::MouseButtonPress:
    case QEvent::MouseButtonRelease:
    {
        // We only take mouse button press and release events from the main QGraphicsView viewport.
        if (obj != qobject_cast<QObject*>(mainView->viewport()))
            return false;

        QMouseEvent *e = static_cast<QMouseEvent *>(event);
//		QGraphicsItem *itemUnderMouse = GetVisibleItemAtCoords(e->x(), e->y());
        /*
                // Update the flag that tracks whether the inworld scene or QGraphicsScene is grabbing mouse movement.
                if (event->type() == QEvent::MouseButtonPress)
                    sceneMouseCapture = (itemUnderMouse ? QtMouseCapture : SceneMouseCapture);
                else // event type == MouseButtonRelease
                    sceneMouseCapture = NoMouseCapture;
        */
        // We always update the global polled input states, independent of whether any the mouse cursor is
        // on top of any Qt widget.
        if (event->type() == QEvent::MouseButtonPress)
        {
            heldMouseButtons |= (MouseEvent::MouseButton)e->button();
            newMouseButtonsPressedQueue |= (MouseEvent::MouseButton)e->button();
        }
        else
        {
            if (lastMouseButtonReleaseTime.msecsTo(QTime::currentTime()) < 300)
            {
                doubleClickDetected = true;
            }
            heldMouseButtons &= ~(MouseEvent::MouseButton)e->button();
            newMouseButtonsReleasedQueue |= (MouseEvent::MouseButton)e->button();
            lastMouseButtonReleaseTime = QTime::currentTime();
        }

        // If there's a visible QGraphicsItem under the mouse and mouse is not in FPS mode,
        // the click's supposed to go there - don't send it at all to inworld scene.
//		if (itemUnderMouse && mouseCursorVisible)
//			return false;

        // The mouse coordinates we receive can come from different widgets, and we are interested only in the coordinates
        // in the QGraphicsView client area, so we need to remap them.
        QPoint mousePos = MapPointToMainGraphicsView(obj, e->pos());

        MouseEvent mouseEvent;
        mouseEvent.itemUnderMouse = GetVisibleItemAtCoords(e->x(), e->y());
        mouseEvent.origin = mouseEvent.itemUnderMouse ? MouseEvent::PressOriginQtWidget : MouseEvent::PressOriginScene;
        if ( !doubleClickDetected)
        {
            mouseEvent.eventType = (event->type() == QEvent::MouseButtonPress) ? MouseEvent::MousePressed : MouseEvent::MouseReleased;
        } else
        {
            mouseEvent.eventType = MouseEvent::MouseDoubleClicked;
        }
        mouseEvent.button = (MouseEvent::MouseButton)e->button();
        mouseEvent.x = mousePos.x();
        mouseEvent.y = mousePos.y();
        mouseEvent.z = 0;
        mouseEvent.relativeX = mouseEvent.x - lastMouseX;
        mouseEvent.relativeY = mouseEvent.y - lastMouseY;
        mouseEvent.modifiers = current_modifiers_;

        lastMouseX = mouseEvent.x;
        lastMouseY = mouseEvent.y;

        mouseEvent.globalX = e->globalX();
        mouseEvent.globalY = e->globalY();

        mouseEvent.otherButtons = e->buttons();

//		mouseEvent.heldKeys = heldKeys; ///\todo
        mouseEvent.handled = false;

        // The mouse press is going to the inworld scene - clear keyboard focus from the QGraphicsScene widget, if any had it so key events also go to inworld scene.
        if (event->type() == QEvent::MouseButtonPress && !mouseEvent.itemUnderMouse && mouseCursorVisible)
            mainView->scene()->clearFocus();

        TriggerMouseEvent(mouseEvent);

        return mouseEvent.handled;
    }

    case QEvent::MouseMove:
    {
        // If a mouse button is held down, we get the mouse drag events from the viewport widget.
        // If a mouse button is not held down, the application main window will get the events.
        // Duplicate events are not received, so no need to worry about filtering them here.

        QMouseEvent *e = static_cast<QMouseEvent *>(event);

        //QGraphicsItem *itemUnderMouse = GetVisibleItemAtCoords(e->x(), e->y());
        // If there is a graphicsItem under the mouse, don't pass the move message to the inworld scene, unless the inworld scene has captured it.
//        if (mouseCursorVisible)
//		    if ((itemUnderMouse && sceneMouseCapture != SceneMouseCapture) || sceneMouseCapture == QtMouseCapture)
//			    return false;

//        if (mouseCursorVisible && itemUnderMouse)
//            return false;

        MouseEvent mouseEvent;
        mouseEvent.eventType = MouseEvent::MouseMove;
        mouseEvent.button = (MouseEvent::MouseButton)e->button();
        mouseEvent.itemUnderMouse = GetVisibleItemAtCoords(e->x(), e->y());
        ///\todo Set whether the previous press originated over a Qt widget or scene.
        mouseEvent.origin = mouseEvent.itemUnderMouse ? MouseEvent::PressOriginQtWidget : MouseEvent::PressOriginScene;

        QWidget *sender = qobject_cast<QWidget*>(obj);
        assert(sender);

        // The mouse coordinates we receive can come from different widgets, and we are interested only in the coordinates
        // in the QGraphicsView client area, so we need to remap them.
        QPoint mousePos = MapPointToMainGraphicsView(obj, e->pos());

        if (mouseCursorVisible)
        {
            mouseEvent.x = mousePos.x();
            mouseEvent.y = mousePos.y();
        }
        else
        {
            // If mouse cursor is hidden, we're in relative "crosshair" mode. In this mode,
            // the mouse absolute coordinates are restricted to stay in the center of the screen.
            mouseEvent.x = mainView->size().width()/2;
            mouseEvent.y = mainView->size().height()/2;
        }
        mouseEvent.z = 0;
        mouseEvent.relativeX = mousePos.x() - lastMouseX;
        mouseEvent.relativeY = mousePos.y() - lastMouseY;

        // If there wasn't any change to the mouse relative coords in FPS mode, ignore this event.
        if (!mouseCursorVisible && mouseEvent.relativeX == 0 && mouseEvent.relativeY == 0)
            return true;

        mouseEvent.globalX = e->globalX(); // Note that these may "jitter" when mouse is in relative movement mode.
        mouseEvent.globalY = e->globalY();
        mouseEvent.otherButtons = e->buttons();
//		mouseEvent.heldKeys = heldKeys; ///\todo
        mouseEvent.handled = false;

        // Save the absolute coordinates to be able to compute the proper relative movement values in the next
        // mouse event.
        lastMouseX = mouseEvent.x;
        lastMouseY = mouseEvent.y;

        TriggerMouseEvent(mouseEvent);

        // In relative mouse movement mode, keep the mouse cursor hidden at screen center at all times.
        if (!mouseCursorVisible)
        {
            RecenterMouse();
            return true; // In relative mouse movement mode, the QGraphicsScene does not receive mouse movement at all.
        }

        return mouseEvent.handled;
    }

    case QEvent::Wheel:
    {
        // If this event did not originate from the application main window, we are not interested in it.
        if (obj != qobject_cast<QObject*>(mainWindow))
            return false;

        QObject *mv = qobject_cast<QObject*>(mainView);
        QObject *mw = qobject_cast<QObject*>(mainWindow);
        QWheelEvent *e = static_cast<QWheelEvent *>(event);
//		QGraphicsItem *itemUnderMouse = GetVisibleItemAtCoords(e->x(), e->y());
//		if (itemUnderMouse)
//			return false;

        MouseEvent mouseEvent;
        mouseEvent.eventType = MouseEvent::MouseScroll;
        mouseEvent.itemUnderMouse = GetVisibleItemAtCoords(e->x(), e->y());
        mouseEvent.origin = mouseEvent.itemUnderMouse ? MouseEvent::PressOriginQtWidget : MouseEvent::PressOriginScene;
        mouseEvent.button = MouseEvent::NoButton;
        mouseEvent.otherButtons = e->buttons();
        mouseEvent.x = e->x();
        mouseEvent.y = e->y();
        mouseEvent.z = 0; // Mouse wheel does not have an absolute z position, only relative.
        mouseEvent.relativeX = 0;
        mouseEvent.relativeY = 0;
        mouseEvent.relativeZ = e->delta();
        mouseEvent.globalX = e->globalX();
        mouseEvent.globalY = e->globalY();

        mouseEvent.otherButtons = e->buttons(); ///\todo Can this be trusted?

//		mouseEvent.heldKeys = heldKeys; ///\todo
        mouseEvent.handled = false;

        TriggerMouseEvent(mouseEvent);

        return mouseEvent.handled;
    }

    } // ~switch

    return QObject::eventFilter(obj, event);
}