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 CanvasGL::renderNoise() { if (!noiseShader_) return; activate(); glViewport(0, 0, getScreenDimensions().x, getScreenDimensions().y); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); noiseShader_->activate(); drawRect(); noiseShader_->deactivate(); glSwapBuffers(); activateDefaultRenderContext(); }
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 CanvasGL::renderTexture(int unitNumber) { if (!shader_) return; activate(); glViewport(0, 0, getScreenDimensions().x, getScreenDimensions().y); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); shader_->activate(); shader_->setUniform("tex_", unitNumber); drawRect(); shader_->deactivate(); glDisable(GL_BLEND); glSwapBuffers(); activateDefaultRenderContext(); }
void CanvasQt::panTriggered(QPanGesture* gesture) { #ifndef QT_NO_CURSOR switch (gesture->state()) { case Qt::GestureStarted: case Qt::GestureUpdated: setCursor(Qt::SizeAllCursor); break; default: setCursor(Qt::ArrowCursor); } #endif // Mouse events will be triggered for touch events by Qt 5.3.1 (even though we specify that the touch event is handled) // http://www.qtcentre.org/archive/index.php/t-52367.html // Therefore keep track of if we are performing and disallow mouse events while performing a gesture ( see CanvasQt::event(QEvent *e) ) switch (gesture->state()) { case Qt::GestureStarted: case Qt::GestureUpdated: gestureMode_ = true; break; default: gestureMode_ = false; } vec2 deltaPos = vec2((gesture->lastOffset().x()-gesture->offset().x())/getScreenDimensions().x, (gesture->offset().y()-gesture->lastOffset().y())/getScreenDimensions().y); if(deltaPos == vec2(0.f)) return; //std::cout << "PAN: " << deltaPos.x << ":" << deltaPos.y << std::endl; GestureEvent gestureEvent(deltaPos, 0.0, GestureEvent::PAN, EventConverterQt::getGestureState(gesture), lastNumFingers_, screenPositionNormalized_, getScreenDimensions()); Canvas::gestureEvent(&gestureEvent); }
CanvasGLFW::CanvasGLFW(std::string windowTitle, uvec2 dimensions) : CanvasGL(dimensions) , windowTitle_(windowTitle) , glWindow_(nullptr) , mouseButton_(MouseEvent::MOUSE_BUTTON_NONE) , mouseState_(MouseEvent::MOUSE_STATE_NONE) , mouseModifiers_(InteractionEvent::MODIFIER_NONE) { glfwWindowHint(GLFW_FLOATING, alwaysOnTop_ ? GL_TRUE : GL_FALSE); glfwWindowHint(GLFW_VISIBLE, GL_FALSE); #ifdef __APPLE__ if (!sharedContext_ && OpenGLCapabilities::getPreferredProfile() == "core") { glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3); glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 2); glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE); glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); } #endif glWindow_ = glfwCreateWindow(getScreenDimensions().x, getScreenDimensions().y, windowTitle_.c_str(), nullptr, sharedContext_); if (!glWindow_) { glfwTerminate(); throw Exception("Could not create GLFW window.", IvwContext); } if (!sharedContext_) sharedContext_ = glWindow_; // register callbacks glfwSetKeyCallback(glWindow_, keyboard); glfwSetMouseButtonCallback(glWindow_, mouseButton); glfwSetCursorPosCallback(glWindow_, mouseMotion); glfwSetScrollCallback(glWindow_, scroll); glfwSetWindowCloseCallback(glWindow_, closeWindow); glfwSetWindowUserPointer(glWindow_, this); glfwSetWindowSizeCallback(glWindow_, reshape); glfwSetWindowPosCallback(glWindow_, move); }
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::mouseReleaseEvent(QMouseEvent* e) { #if !defined(QT_NO_GESTURES) && defined(USING_QT4) if (gestureMode_){ gestureMode_ = false; return; } #endif uvec2 screenPos(static_cast<unsigned int>(e->pos().x()), static_cast<unsigned int>(e->pos().y())); MouseEvent mouseEvent(screenPos, EventConverterQt::getMouseButtonCausingEvent(e), MouseEvent::MOUSE_STATE_RELEASE, EventConverterQt::getModifier(e), getScreenDimensions(), getDepthValueAtCoord(screenPos)); e->accept(); Canvas::mouseReleaseEvent(&mouseEvent); }
void CanvasQt::pinchTriggered(QPinchGesture* gesture) { //std::cout << "PINCH: " << gesture->scaleFactor() << std::endl; // Mouse events will be triggered for touch events by Qt 5.3.1 (even though we specify that the touch event is handled) // http://www.qtcentre.org/archive/index.php/t-52367.html // Therefore keep track of if we are performing and disallow mouse events while performing a gesture ( see CanvasQt::event(QEvent *e) ) switch (gesture->state()) { case Qt::GestureStarted: case Qt::GestureUpdated: gestureMode_ = true; break; default: gestureMode_ = false; } GestureEvent gestureEvent(vec2(gesture->centerPoint().x(), gesture->centerPoint().y()), static_cast<double>(gesture->scaleFactor())-1.0, GestureEvent::PINCH, EventConverterQt::getGestureState(gesture), lastNumFingers_, screenPositionNormalized_, getScreenDimensions()); Canvas::gestureEvent(&gestureEvent); }
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(); }