示例#1
0
void CanvasQt::wheelEvent(QWheelEvent* e){
    MouseEvent::MouseWheelOrientation orientation;
    if (e->orientation() == Qt::Horizontal) {
        orientation = MouseEvent::MOUSE_WHEEL_HORIZONTAL;
    } else {
        orientation = MouseEvent::MOUSE_WHEEL_VERTICAL;
    }

#if (QT_VERSION >= QT_VERSION_CHECK(5, 0, 0))
    QPoint numPixels = e->pixelDelta();
    QPoint numDegrees = e->angleDelta() / 8 / 15;
#else
    QPoint numPixels;
    QPoint numDegrees = QPoint(0, e->delta() / 8 / 15);
#endif

    int numSteps = 0;
    if (!numPixels.isNull()) {
        numSteps = (orientation==MouseEvent::MOUSE_WHEEL_HORIZONTAL? numPixels.x() : numPixels.y()) / 5;
    } else if (!numDegrees.isNull()) {
        numSteps = (orientation==MouseEvent::MOUSE_WHEEL_HORIZONTAL? numDegrees.x() : numDegrees.y());
    }
    ivec2 screenPos(e->pos().x(), e->pos().y());
    ivec2 screenPosInvY(screenPos.x, static_cast<int>(getScreenDimensions().y) - 1 - screenPos.y);
    MouseEvent mouseEvent(screenPos, numSteps,
        EventConverterQt::getMouseWheelButton(e), MouseEvent::MOUSE_STATE_WHEEL, orientation,
        EventConverterQt::getModifier(e), getScreenDimensions(),
        getDepthValueAtCoord(screenPosInvY));
    e->accept();
    Canvas::mouseWheelEvent(&mouseEvent);
}
示例#2
0
void CanvasQt::mousePressEvent(QMouseEvent* e) {

#if !defined(QT_NO_GESTURES) && defined(USING_QT4)
    if (gestureMode_) return;
#endif
    ivec2 screenPos(e->pos().x(), e->pos().y());
    ivec2 screenPosInvY(screenPos.x, static_cast<int>(getScreenDimensions().y) - 1 - screenPos.y);
    MouseEvent mouseEvent(screenPos,
                           EventConverterQt::getMouseButton(e), MouseEvent::MOUSE_STATE_PRESS,
                           EventConverterQt::getModifier(e), getScreenDimensions(), 
                           getDepthValueAtCoord(screenPosInvY));
    e->accept();
    Canvas::mousePressEvent(&mouseEvent);
}
示例#3
0
void CanvasGLFW::mouseMotion(GLFWwindow* window, double x, double y) {
    CanvasGLFW* thisCanvas = getCanvasGLFW(window);
    ivec2 screenPos(floor(x), floor(y));
    ivec2 screenPosInvY(screenPos.x,
                        static_cast<int>(thisCanvas->getScreenDimensions().y) - 1 - screenPos.y);

    MouseEvent::MouseState state =
        (thisCanvas->mouseState_ == MouseEvent::MOUSE_STATE_PRESS ? MouseEvent::MOUSE_STATE_MOVE
                                                                  : thisCanvas->mouseState_);
    MouseEvent mouseEvent(screenPos, thisCanvas->mouseButton_, state, thisCanvas->mouseModifiers_,
                          thisCanvas->getScreenDimensions(),
                          thisCanvas->getDepthValueAtCoord(screenPosInvY));

    if (state == MouseEvent::MOUSE_STATE_MOVE)
        thisCanvas->mouseMoveEvent(&mouseEvent);
    else if (state == MouseEvent::MOUSE_STATE_RELEASE)
        thisCanvas->mouseReleaseEvent(&mouseEvent);
}
示例#4
0
void CanvasGLFW::scroll(GLFWwindow* window, double xoffset, double yoffset) {
    CanvasGLFW* thisCanvas = getCanvasGLFW(window);
    thisCanvas->mouseButton_ = MouseEvent::MOUSE_BUTTON_MIDDLE;
    thisCanvas->mouseState_ = MouseEvent::MOUSE_STATE_WHEEL;
    thisCanvas->mouseModifiers_ = KeyboardEvent::MODIFIER_NONE;
    double x;
    double y;
    glfwGetCursorPos(window, &x, &y);
    ivec2 screenPos(floor(x), floor(y));
    ivec2 screenPosInvY(screenPos.x,
                        static_cast<int>(thisCanvas->getScreenDimensions().y) - 1 - screenPos.y);
    int delta = static_cast<int>(yoffset < 0.0 ? floor(yoffset) : ceil(yoffset));

    MouseEvent mouseEvent(screenPos, delta, thisCanvas->mouseButton_, thisCanvas->mouseState_,
                          MouseEvent::MOUSE_WHEEL_VERTICAL, thisCanvas->mouseModifiers_,
                          thisCanvas->getScreenDimensions(),
                          thisCanvas->getDepthValueAtCoord(screenPosInvY));

    thisCanvas->mouseWheelEvent(&mouseEvent);
}
示例#5
0
void CanvasGLFW::mouseButton(GLFWwindow* window, int button, int action, int mods) {
    CanvasGLFW* thisCanvas = getCanvasGLFW(window);
    thisCanvas->mouseButton_ = mapMouseButton(button);
    thisCanvas->mouseState_ = mapMouseState(action);
    thisCanvas->mouseModifiers_ = mapModifiers(mods);
    double x;
    double y;
    glfwGetCursorPos(window, &x, &y);
    ivec2 screenPos(floor(x), floor(y));
    ivec2 screenPosInvY(screenPos.x,
                        static_cast<int>(thisCanvas->getScreenDimensions().y) - 1 - screenPos.y);
    MouseEvent mouseEvent(screenPos, thisCanvas->mouseButton_, thisCanvas->mouseState_,
                          thisCanvas->mouseModifiers_, thisCanvas->getScreenDimensions(),
                          thisCanvas->getDepthValueAtCoord(screenPosInvY));

    if (thisCanvas->mouseState_ == MouseEvent::MOUSE_STATE_PRESS)
        thisCanvas->mousePressEvent(&mouseEvent);
    else if (thisCanvas->mouseState_ == MouseEvent::MOUSE_STATE_RELEASE)
        thisCanvas->mouseReleaseEvent(&mouseEvent);
}
示例#6
0
void CanvasQt::mouseMoveEvent(QMouseEvent* e) {

#if !defined(QT_NO_GESTURES)
    if (gestureMode_) return;
#endif


    ivec2 screenPos(e->pos().x(), e->pos().y());
    ivec2 screenPosInvY(screenPos.x, static_cast<int>(getScreenDimensions().y) - 1 - screenPos.y);

    // Optimization, do not sample depth value when hovering, i.e. move without holding a mouse button
    int button = EventConverterQt::getMouseButton(e);
    double depth = 1.0;
    if (button != MouseEvent::MOUSE_BUTTON_NONE)
        depth = getDepthValueAtCoord(screenPosInvY);

    MouseEvent mouseEvent(screenPos, button, MouseEvent::MOUSE_STATE_MOVE,
                            EventConverterQt::getModifier(e), getScreenDimensions(),
                            depth);
    e->accept();
    Canvas::mouseMoveEvent(&mouseEvent);
}
示例#7
0
void CanvasQt::touchEvent(QTouchEvent* touch) {
    size_t nTouchPoints = touch->touchPoints().size();
    if (nTouchPoints < 1) {
        return;
    }

    QTouchEvent::TouchPoint firstPoint = touch->touchPoints()[0];
    
    switch (firstPoint.state())
    {
    case Qt::TouchPointPressed:
        gestureMode_ = nTouchPoints > 1; // Treat single touch point as mouse event
        break;
    case Qt::TouchPointMoved:
        gestureMode_ = nTouchPoints > 1; // Treat single touch point as mouse event
        break;
    case Qt::TouchPointStationary:
        gestureMode_ = nTouchPoints > 1; // Treat single touch point as mouse event
        break;
    case Qt::TouchPointReleased:
        gestureMode_ = false;
        break;
    default:
        gestureMode_ = false;
    }
    // Copy touch points
    std::vector<TouchPoint> touchPoints;
    touchPoints.reserve(touch->touchPoints().size());
    // Fetch layer before loop (optimization)
    const LayerRAM* depthLayerRAM = getDepthLayerRAM();
    vec2 screenSize(getScreenDimensions());

    std::vector<int> endedTouchIds;

    for (auto& touchPoint : touch->touchPoints()) {
        vec2 screenTouchPos(touchPoint.pos().x(), touchPoint.pos().y());
        vec2 prevScreenTouchPos(touchPoint.lastPos().x(), touchPoint.lastPos().y());
        TouchPoint::TouchState touchState;
        switch (touchPoint.state())
        {
        case Qt::TouchPointPressed:
            touchState = TouchPoint::TOUCH_STATE_STARTED;
            break;
        case Qt::TouchPointMoved:
            touchState = TouchPoint::TOUCH_STATE_UPDATED;
            break;
        case Qt::TouchPointStationary:
            touchState = TouchPoint::TOUCH_STATE_STATIONARY;
            break;
        case Qt::TouchPointReleased:
            touchState = TouchPoint::TOUCH_STATE_ENDED;
            break;
        default:
            touchState = TouchPoint::TOUCH_STATE_NONE;
        }

        ivec2 pixelCoord = ivec2(static_cast<int>(screenTouchPos.x),
            screenSize.y - 1 - static_cast<int>(screenTouchPos.y));
        
        // Note that screenTouchPos/prevScreenTouchPos are in [0 screenDim] and does not need to be 
        // adjusted to become centered in the pixel (+0.5)
        
        // Saving id order to preserve order of touch points at next touch event
        
        const auto lastIdIdx = std::find(lastTouchIds_.begin(), lastTouchIds_.end(), touchPoint.id());

        if (lastIdIdx != lastTouchIds_.end()) {
            if (touchState == TouchPoint::TOUCH_STATE_ENDED){
                endedTouchIds.push_back(touchPoint.id());
            }
        }
        else{
            lastTouchIds_.push_back(touchPoint.id());


        }
        touchPoints.emplace_back(touchPoint.id(), screenTouchPos,
            (screenTouchPos) / screenSize,
            prevScreenTouchPos,
            (prevScreenTouchPos) / screenSize,
            touchState, getDepthValueAtCoord(pixelCoord, depthLayerRAM));
    }
    // Ensure that the order to the touch points are the same as last touch event.
    // Note that the ID of a touch point is always the same but the order in which
    // they are given can vary.
    // Example
    // lastTouchIds_    touchPoints
    //     0                 0
    //     3                 1 
    //     2                 2
    //     4
    // Will result in:
    //                  touchPoints
    //                       0 (no swap)
    //                       2 (2 will swap with 1)
    //                       1

    auto touchIndex = 0; // Index to first unsorted element in touchPoints array
    for (const auto& lastTouchPointId : lastTouchIds_) {
        const auto touchPointIt = std::find_if(touchPoints.begin(), touchPoints.end(), [lastTouchPointId](const TouchPoint& p) { return p.getId() == lastTouchPointId; });
        // Swap current location in the container with the location it was in last touch event.
        if (touchPointIt != touchPoints.end() && std::distance(touchPoints.begin(), touchPointIt) != touchIndex) {
            std::swap(*(touchPoints.begin() + touchIndex), *touchPointIt);
            ++touchIndex;
        }
    }

    for (auto& endedId : endedTouchIds) {
        std::vector<int>::iterator foundIdx = std::find(lastTouchIds_.begin(), lastTouchIds_.end(), endedId);
        if (foundIdx != lastTouchIds_.end())
            lastTouchIds_.erase(foundIdx);
    }

    TouchEvent touchEvent(touchPoints, getScreenDimensions());
    touch->accept();

    // We need to send out touch event all the time to support one -> two finger touch switch
    Canvas::touchEvent(&touchEvent);

    // Mouse events will be triggered for touch events by Qt4 and Qt >= 5.3.0
    // https://bugreports.qt.io/browse/QTBUG-40038
#if defined(USING_QT5) && (QT_VERSION < QT_VERSION_CHECK(5, 3, 0))
    if(touch->touchPoints().size() == 1 && lastNumFingers_ < 2){
        MouseEvent* mouseEvent = nullptr;
        ivec2 pos = ivec2(static_cast<int>(firstPoint.pos().x()), static_cast<int>(firstPoint.pos().y()));
        uvec2 screenPosInvY(static_cast<unsigned int>(pos.x), static_cast<unsigned int>(getScreenDimensions().y-1-pos.y));
        double depth = getDepthValueAtCoord(screenPosInvY);
        switch (touchPoints.front().state())
        {
        case TouchPoint::TOUCH_STATE_STARTED:
            mouseEvent = new MouseEvent(pos, MouseEvent::MOUSE_BUTTON_LEFT, MouseEvent::MOUSE_STATE_PRESS, 
                EventConverterQt::getModifier(touch), getScreenDimensions(), depth);
            Canvas::mousePressEvent(mouseEvent);
            break;
        case TouchPoint::TOUCH_STATE_UPDATED:
            mouseEvent = new MouseEvent(pos, MouseEvent::MOUSE_BUTTON_LEFT, MouseEvent::MOUSE_STATE_MOVE, 
                EventConverterQt::getModifier(touch), getScreenDimensions(), depth);
            Canvas::mouseMoveEvent(mouseEvent);
            break;
        case TouchPoint::TOUCH_STATE_STATIONARY:
            break; // Do not fire event while standing still.
        case TouchPoint::TOUCH_STATE_ENDED:
            mouseEvent = new MouseEvent(pos, MouseEvent::MOUSE_BUTTON_LEFT, MouseEvent::MOUSE_STATE_RELEASE, 
                EventConverterQt::getModifier(touch), getScreenDimensions(), depth);
            Canvas::mouseReleaseEvent(mouseEvent);
            break;
        default:
            break;
        }
        delete mouseEvent;
    }
#endif

    lastNumFingers_ = static_cast<int>(touch->touchPoints().size());
    screenPositionNormalized_ = touchEvent.getCenterPointNormalized();
}