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); }
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); }
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); }
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); }
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); }
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); }
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(); }