示例#1
0
文件: wwidget.cpp 项目: Alppasa/mixxx
bool WWidget::event(QEvent* e) {
    if (e->type() == QEvent::ToolTip) {
        updateTooltip();
    } else if (isEnabled()) {
        switch(e->type()) {
        case QEvent::TouchBegin:
        case QEvent::TouchUpdate:
        case QEvent::TouchEnd:
        {
            QTouchEvent* touchEvent = dynamic_cast<QTouchEvent*>(e);
            if (touchEvent->deviceType() !=  QTouchEvent::TouchScreen) {
                break;
            }

            // fake a mouse event!
            QEvent::Type eventType = QEvent::None;
            switch (touchEvent->type()) {
            case QEvent::TouchBegin:
                eventType = QEvent::MouseButtonPress;
                if (touchIsRightButton()) {
                    // touch is right click
                    m_activeTouchButton = Qt::RightButton;
                } else {
                    m_activeTouchButton = Qt::LeftButton;
                }
                break;
            case QEvent::TouchUpdate:
                eventType = QEvent::MouseMove;
                break;
            case QEvent::TouchEnd:
                eventType = QEvent::MouseButtonRelease;
                break;
            default:
                DEBUG_ASSERT(false);
                break;
            }

            const QTouchEvent::TouchPoint &touchPoint =
                    touchEvent->touchPoints().first();
            QMouseEvent mouseEvent(eventType,
                    touchPoint.pos().toPoint(),
                    touchPoint.screenPos().toPoint(),
                    m_activeTouchButton, // Button that causes the event
                    Qt::NoButton, // Not used, so no need to fake a proper value.
                    touchEvent->modifiers());

            return QWidget::event(&mouseEvent);
        }
        default:
            break;
        }
    }

    return QWidget::event(e);
}
示例#2
0
bool KisToolProxy::forwardEvent(ActionState state, KisTool::ToolAction action, QEvent *event, QEvent *originalEvent, QTabletEvent *lastTabletEvent, const QPoint &canvasOriginWorkaround)
{
    bool retval = true;

    QTabletEvent *tabletEvent = dynamic_cast<QTabletEvent*>(event);
    QTouchEvent *touchEvent = dynamic_cast<QTouchEvent*>(event);
    QMouseEvent *mouseEvent = dynamic_cast<QMouseEvent*>(event);

    if (tabletEvent) {
        QPointF docPoint = tabletToDocument(tabletEvent->hiResGlobalPos(), canvasOriginWorkaround);
        tabletEvent->accept();
        this->tabletEvent(tabletEvent, docPoint);
        forwardToTool(state, action, tabletEvent, docPoint);
        retval = tabletEvent->isAccepted();
    } else if (touchEvent) {
        if (state == END && touchEvent->type() != QEvent::TouchEnd) {
            //Fake a touch end if we are "upgrading" a single-touch gesture to a multi-touch gesture.
            QTouchEvent fakeEvent(QEvent::TouchEnd, touchEvent->deviceType(), touchEvent->modifiers(), touchEvent->touchPointStates(), touchEvent->touchPoints());
            this->touchEvent(&fakeEvent);
        } else {
            this->touchEvent(touchEvent);
        }
    } else if (mouseEvent) {
        if (lastTabletEvent) {
            QPointF docPoint = tabletToDocument(lastTabletEvent->hiResGlobalPos(), canvasOriginWorkaround);
            lastTabletEvent->accept();
            this->tabletEvent(lastTabletEvent, docPoint);
            forwardToTool(state, action, lastTabletEvent, docPoint);
            retval = lastTabletEvent->isAccepted();
        } else {
            QPointF docPoint = widgetToDocument(mouseEvent->posF());
            mouseEvent->accept();
            if (mouseEvent->type() == QEvent::MouseButtonPress) {
                mousePressEvent(mouseEvent, docPoint);
            } else if (mouseEvent->type() == QEvent::MouseButtonDblClick) {
                mouseDoubleClickEvent(mouseEvent, docPoint);
            } else if (mouseEvent->type() == QEvent::MouseButtonRelease) {
                mouseReleaseEvent(mouseEvent, docPoint);
            } else if (mouseEvent->type() == QEvent::MouseMove) {
                mouseMoveEvent(mouseEvent, docPoint);
            }
            forwardToTool(state, action, originalEvent, docPoint);
            retval = mouseEvent->isAccepted();
        }
    } else if(event->type() == QEvent::KeyPress) {
        QKeyEvent* kevent = static_cast<QKeyEvent*>(event);
        keyPressEvent(kevent);
    } else if(event->type() == QEvent::KeyRelease) {
        QKeyEvent* kevent = static_cast<QKeyEvent*>(event);
        keyReleaseEvent(kevent);
    }

    return retval;
}
示例#3
0
// override QApplication::notify() for greatest control over event handling
bool TouchApplication::notify(QObject* receiver, QEvent* event)
{
  //DebugEventFilter::printEvent(receiver, event);
  QEvent::Type evtype = event->type();
  // first, try to pass TabletPress/TouchBegin event and see if anyone accepts it
  // In Qt, events are first sent to a QWindow, which then figures out what widget they should be sent to.
  // Unfortunately, QWindow event handler always returns true and doesn't change accepted state of event (it
  //  sends a copy of the event and discards the accepted state of the copy), so we must save result from
  //  sending event to final widget (by incrementing acceptCount)
  // When faking mouse events, we must send them to the QWindow instead of a widget, since some of the
  //  routing logic is there, e.g., for handling popup windows
  if((evtype == QEvent::TabletPress || evtype == QEvent::TouchBegin) && inputState == None) {
    if(receiver->isWindowType()) {
      int prevacceptcount = acceptCount;
      receiver = getRecvWindow(receiver);
      QApplication::notify(receiver, event);
      if(acceptCount > prevacceptcount) {
        acceptCount = prevacceptcount;
        inputState = PassThru;
        return true;
      }
      // else, fall through and resend as mouse event
      // we must send a tablet release to put QWidgetWindow in consistent state
      //  doesn't appear to be necessary for TouchBegin
      if(evtype == QEvent::TabletPress) {
        QTabletEvent* tev = static_cast<QTabletEvent*>(event);
        QTabletEvent rlev(QEvent::TabletRelease, tev->posF(), tev->globalPosF(), tev->device(),
                                 tev->pointerType(), 0, 0, 0, 0, 0, 0, tev->modifiers(), tev->uniqueId());
        QApplication::notify(receiver, &rlev);
      }
    }
    else {
      event->setAccepted(false);
      bool res = QApplication::notify(receiver, event);
      if(event->isAccepted())
        acceptCount++;
      return res;
    }
  }

  switch(evtype) {
  // reject external mouse events if we are translating touch or tablet input
  case QEvent::MouseButtonRelease:
  case QEvent::MouseMove:
  case QEvent::MouseButtonPress:
    // QWidgetWindow always forwards mouse event to widget as spontaneous event (why?)
    if(inputState != None && event->spontaneous() && receiver->isWindowType())
      return true;   // qDebug("This event should be rejected!");
    break;
  case QEvent::TabletRelease:
    if(inputState == PassThru)
      inputState = None;
  case QEvent::TabletMove:
  case QEvent::TabletPress:
  {
    // TODO: should this only be done if inputState == TabletInput?
    receiver = getRecvWindow(receiver);
    QTabletEvent* tabletevent = static_cast<QTabletEvent*>(event);
    QEvent::Type mevtype = QEvent::MouseMove;
    if(inputState == None && evtype == QEvent::TabletPress) {
      mevtype = QEvent::MouseButtonPress;
      inputState = TabletInput;
    }
    else if(inputState != TabletInput)  // this covers PassThru
      break;
    if(evtype == QEvent::TabletRelease) {
      mevtype = QEvent::MouseButtonRelease;
      inputState = None;
    }
    return sendMouseEvent(receiver, mevtype, tabletevent->globalPos(), tabletevent->modifiers());
  }
#ifdef QT_5
  case QEvent::TouchCancel:
    evtype = QEvent::TouchEnd;
#endif
  case QEvent::TouchEnd:
    if(inputState == PassThru) // && touchPoints.count() == 1)
      inputState = None;
  case QEvent::TouchUpdate:
  case QEvent::TouchBegin:
  {
    receiver = getRecvWindow(receiver);
    QTouchEvent* touchevent = static_cast<QTouchEvent*>(event);
    QEvent::Type mevtype = QEvent::MouseMove;
    if(inputState == None && evtype == QEvent::TouchBegin
        && touchevent->touchPoints().size() == 1 && touchevent->device()->type() != QTouchDevice::TouchPad) {
      activeTouchId = touchevent->touchPoints().first().id();
      mevtype = QEvent::MouseButtonPress;
      inputState = TouchInput;
    }
    else if(inputState != TouchInput)  // this covers PassThru
      break;
    if(evtype == QEvent::TouchEnd)
      inputState = None;
    event->setAccepted(true);
    QList<QTouchEvent::TouchPoint> touchPoints = touchevent->touchPoints();
    for(int ii = 0; ii < touchPoints.count(); ++ii) {
      const QTouchEvent::TouchPoint& touchpt = touchPoints.at(ii);
      if(touchpt.id() == activeTouchId) {
        if(touchpt.state() == Qt::TouchPointReleased) {
          mevtype = QEvent::MouseButtonRelease;
          activeTouchId = -1;
        }
        return sendMouseEvent(receiver, mevtype, touchpt.screenPos().toPoint(), touchevent->modifiers());
      }
    }
    // swallow all touch events until TouchEnd
    // another option would be to propagate the touch event with the activeTouchId point removed, if >1 point
    return true;
  }
  default:
    break;
  }
  return QApplication::notify(receiver, event);
}
示例#4
0
bool MixxxApplication::notify(QObject* target, QEvent* event) {
    switch (event->type()) {
    case QEvent::TouchBegin:
    case QEvent::TouchUpdate:
    case QEvent::TouchEnd:
    {
        QTouchEvent* touchEvent = static_cast<QTouchEvent*>(event);
        QList<QTouchEvent::TouchPoint> touchPoints = touchEvent->touchPoints();
        QEvent::Type eventType = QEvent::None;
        Qt::MouseButtons buttons = Qt::NoButton;
        QWidget* fakeMouseWidget = NULL;
        bool baseReturn;

        //qDebug() << "&" << touchEvent->type() << target;

        if (touchEvent->deviceType() !=  QTouchEvent::TouchScreen) {
            break;
        }

        switch (event->type()) {
        case QEvent::TouchBegin:
            // try to deliver as touch event
            baseReturn = QApplication::notify(target, event);
            if (dynamic_cast<MixxxMainWindow*>(touchEvent->widget())) {
                // the touchEvent has fallen trough to the MixxxMainWindow, because there
                // was no touch enabled widget found.
                // Now we resent this event and all following events for this touch point
                // as Mouse events.
                eventType = QEvent::MouseButtonPress;
                if (touchIsRightButton()) {
                    // touch is right click
                    m_activeTouchButton = Qt::RightButton;
                    buttons = Qt::RightButton;
                } else {
                    m_activeTouchButton = Qt::LeftButton;
                    buttons = Qt::LeftButton;
                }
                m_fakeMouseSourcePointId = touchPoints.first().id();
                m_fakeMouseWidget = dynamic_cast<QWidget*>(target);
                fakeMouseWidget = m_fakeMouseWidget;
                break;
            }
            return baseReturn;
        case QEvent::TouchUpdate:
            if (m_fakeMouseWidget) {
                eventType = QEvent::MouseMove;
                buttons = m_activeTouchButton;
                fakeMouseWidget = m_fakeMouseWidget;
                break;
            }
            return QApplication::notify(target, event);
        case QEvent::TouchEnd:
            if (m_fakeMouseWidget) {
                eventType = QEvent::MouseButtonRelease;
                m_fakeMouseSourcePointId = touchPoints.first().id();
                fakeMouseWidget = m_fakeMouseWidget;
                m_fakeMouseWidget = NULL;
                break;
            }
            return QApplication::notify(target, event);
        default:
            return QApplication::notify(target, event);
        }

        for (int i = 0; i < touchPoints.count(); ++i) {
             const QTouchEvent::TouchPoint& touchPoint = touchPoints.at(i);
             if (touchPoint.id() == m_fakeMouseSourcePointId) {
                 QMouseEvent mouseEvent(eventType,
                                        fakeMouseWidget->mapFromGlobal(touchPoint.screenPos().toPoint()),
                                        touchPoint.screenPos().toPoint(),
                                        m_activeTouchButton, // Button that causes the event
                                        buttons,
                                        touchEvent->modifiers());

                 //qDebug() << "#" << mouseEvent.type() << mouseEvent.button() << mouseEvent.buttons() << mouseEvent.pos() << mouseEvent.globalPos();

                 //if (m_fakeMouseWidget->focusPolicy() & Qt::ClickFocus) {
                 //    fakeMouseWidget->setFocus();
                 //}
                 QApplication::notify(fakeMouseWidget, &mouseEvent);
                 return true;
             }
        }
        //qDebug() << "return false";
        return false;
        break;
    }
    case QEvent::MouseButtonRelease:
    {
        bool ret = QApplication::notify(target, event);
        if (m_fakeMouseWidget) {
            // It may happen the faked mouse event was grabbed by a non touch window.
            // eg.: if we have started to drag by touch.
            // In this case X11 generates a MouseButtonRelease instead of a TouchPointReleased Event.
            // QApplication still tracks the Touch point and prevent touch to other widgets
            // So we need to fake the Touch release event as well to clean up
            // QApplicationPrivate::widgetForTouchPointId and QApplicationPrivate::appCurrentTouchPoints;
            m_fakeMouseWidget = NULL; // Disable MouseButtonRelease fake
            QList<QTouchEvent::TouchPoint> touchPoints;
            QTouchEvent::TouchPoint tp;
            tp.setId(m_fakeMouseSourcePointId);
            tp.setState(Qt::TouchPointReleased);
            touchPoints.append(tp);
            qt_translateRawTouchEvent(NULL, QTouchEvent::TouchScreen, touchPoints);
        }
        return ret;
    }
    default:
        break;
    }
    // No touch event
    bool ret = QApplication::notify(target, event);
    return ret;
}