Beispiel #1
0
/**
 * Handle tablet proximity events. When the eraser is brought near
 * the tablet surface, switch to eraser tool on all windows.
 * When the tip leaves the surface, switch back to whatever tool
 * we were using before.
 *
 * Also, on MacOS we must also handle the Open File event.
 */
bool DrawpileApp::event(QEvent *e) {
    if(e->type() == QEvent::TabletEnterProximity || e->type() == QEvent::TabletLeaveProximity) {
        QTabletEvent *te = static_cast<QTabletEvent*>(e);
#if (QT_VERSION >= QT_VERSION_CHECK(5, 4, 0))
        if(te->pointerType()==QTabletEvent::Eraser)
            emit eraserNear(e->type() == QEvent::TabletEnterProximity);
#else
        if(e->type() == QEvent::TabletEnterProximity) {
            if(te->pointerType()==QTabletEvent::Eraser)
                emit eraserNear(true);
            else
                emit eraserNear(false);
        }
#endif
        return true;

    } else if(e->type() == QEvent::FileOpen) {
        QFileOpenEvent *fe = static_cast<QFileOpenEvent*>(e);

        // Note. This is currently broken in Qt 5.3.1:
        // https://bugreports.qt-project.org/browse/QTBUG-39972
        openUrl(fe->url());

        return true;
    }

    return QApplication::event(e);
}
Beispiel #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;
}
bool UBMousePressFilter::eventFilter(QObject *obj, QEvent *event)
{
    const bool isMousePress = event->type() == QEvent::MouseButtonPress;
    const bool isMouseRelease = event->type() == QEvent::MouseButtonRelease;
    const bool isMouseMove = event->type() == QEvent::MouseMove;

    if (isMousePress)
    {
        QMouseEvent * mouseEvent = static_cast<QMouseEvent *>(event);

        if (mouseEvent)
        {
            if (mPendingEvent)
            {
                delete mPendingEvent;
            }

            mPendingEvent = new QMouseEvent(QEvent::MouseButtonDblClick,
                mouseEvent->pos(), mouseEvent->globalPos(),
                mouseEvent->button(), mouseEvent->buttons(),
                mouseEvent->modifiers());

            mObject = obj;

            QTimer::singleShot(1000, this, SLOT(mouseDownElapsed()));
        }
    }
    else if (isMouseRelease || isMouseMove)
    {
        if (mPendingEvent)
        {
            QTabletEvent * tabletEvent = static_cast<QTabletEvent *>(event);
            QPoint point = tabletEvent->globalPos() - mPendingEvent->globalPos();
            if (isMouseRelease || point.manhattanLength() > QApplication::startDragDistance())
            {
                delete mPendingEvent;
                mPendingEvent = 0;
                mObject = 0;
            }
        }
    }

    return false;
}
void KisCanvasController::Private::emitPointerPositionChangedSignals(QEvent *event)
{
    if (!coordinatesConverter) return;

    QPoint pointerPos;
    QMouseEvent *mouseEvent = dynamic_cast<QMouseEvent*>(event);
    if (mouseEvent) {
        pointerPos = mouseEvent->pos();
    } else {
        QTabletEvent *tabletEvent = dynamic_cast<QTabletEvent*>(event);
        if (tabletEvent) {
            pointerPos = tabletEvent->pos();
        }
    }

    QPointF documentPos = coordinatesConverter->widgetToDocument(pointerPos);

    q->proxyObject->emitDocumentMousePositionChanged(documentPos);
    q->proxyObject->emitCanvasMousePositionChanged(pointerPos);
}
Beispiel #5
0
void KisToolProxy::forwardHoverEvent(QEvent *event)
{
    switch (event->type()) {
    case QEvent::TabletMove: {
        QTabletEvent *tabletEvent = static_cast<QTabletEvent*>(event);
        QPointF docPoint = widgetToDocument(tabletEvent->posF());
        this->tabletEvent(tabletEvent, docPoint);
        return;
    }

    case QEvent::MouseMove: {
        QMouseEvent *mouseEvent = static_cast<QMouseEvent*>(event);
        QPointF docPoint = widgetToDocument(mouseEvent->posF());
        mouseMoveEvent(mouseEvent, docPoint);
        return;
    }

    default: {
        qWarning() << "forwardHoverEvent encountered unknown event type.";
        return;
    }
    }
}
Beispiel #6
0
bool TabletWidget::eventFilter(QObject *, QEvent *ev)
{
    switch (ev->type()) {
    case QEvent::TabletEnterProximity:
    case QEvent::TabletLeaveProximity:
    case QEvent::TabletMove:
    case QEvent::TabletPress:
    case QEvent::TabletRelease:
        {
            QTabletEvent *event = static_cast<QTabletEvent*>(ev);
            mType = event->type();
            mPos = event->pos();
            mGPos = event->globalPos();
            mHiResGlobalPos = event->hiResGlobalPos();
            mDev = event->device();
            mPointerType = event->pointerType();
            mUnique = event->uniqueId();
            mXT = event->xTilt();
            mYT = event->yTilt();
            mZ = event->z();
            mPress = event->pressure();
            mTangential = event->tangentialPressure();
            mRot = event->rotation();
            mButton = event->button();
            mButtons = event->buttons();
            if (isVisible())
                update();
            break;
        }
    case QEvent::MouseMove:
        if (mMouseToo) {
            resetAttributes();
            QMouseEvent *event = static_cast<QMouseEvent*>(ev);
            mType = event->type();
            mPos = event->pos();
            mGPos = event->globalPos();
        }
    default:
        break;
    }
    return false;
}
// 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);
}
Beispiel #8
0
/**
 * Tablet events are handled here
 * @param event event info
 */
bool CanvasView::viewportEvent(QEvent *event)
{
	if(event->type() == QEvent::TabletMove) {
		// Stylus moved
		QTabletEvent *tabev = static_cast<QTabletEvent*>(event);
		tabev->accept();
		const dpcore::Point point(mapToScene(tabev->pos()), tabev->pressure());

		if(!_prevpoint.intSame(point)) {
			if(_isdragging)
				moveDrag(tabev->x(), tabev->y());
			else {
				if(_pendown) {
					if(point.pressure()==0) {
						// Missed a release event
						_pendown = NOTDOWN;
						onPenUp();
					} else {
						onPenMove(point);
					}
				}
				updateOutline(point);
			}
			_prevpoint = point;
		}
	} else if(event->type() == QEvent::TabletPress) {
		// Stylus touches the tablet surface
		QTabletEvent *tabev = static_cast<QTabletEvent*>(event);
		tabev->accept();
		if(_dragbtndown) {
			startDrag(tabev->x(), tabev->y(), _dragbtndown);
		} else {
			if(_pendown == NOTDOWN) {
				const dpcore::Point point(mapToScene(tabev->pos()), tabev->pressure());

				_pendown = TABLETDOWN;
				onPenDown(point, false);
				updateOutline(point);
				_prevpoint = point;
			}
		}
	} else if(event->type() == QEvent::TabletRelease) {
		// Stylus lifted
		QTabletEvent *tabev = static_cast<QTabletEvent*>(event);
		tabev->accept();
		if(_isdragging) {
			stopDrag();
		} else if(_pendown == TABLETDOWN) {
			dpcore::Point point(mapToScene(tabev->pos()), 0);
			updateOutline(point);
			_prevpoint = point;
			_pendown = NOTDOWN;
			onPenUp();
		}
	} else {
		return QGraphicsView::viewportEvent(event);
	}
	
	return true;
}
Beispiel #9
0
/**
 * Tablet events are handled here
 * @param event event info
 */
bool CanvasView::viewportEvent(QEvent *event)
{
	if(event->type() == QEvent::Gesture) {
		gestureEvent(static_cast<QGestureEvent*>(event));

	} else if(event->type() == QEvent::TabletMove && _enableTabletEvents) {
		// Stylus moved
		QTabletEvent *tabev = static_cast<QTabletEvent*>(event);
		tabev->accept();

		paintcore::Point point = mapToScene(tabev->posF(), tabev->pressure());
		updateOutline(point);

		if(!_prevpoint.intSame(point)) {
			if(_isdragging)
				moveDrag(tabev->x(), tabev->y());
			else {
				if(_pendown) {
					_pointervelocity = point.distance(_prevpoint);
					_pointerdistance += _pointervelocity;
					point.setPressure(mapPressure(point.pressure(), true));
					onPenMove(point, false, tabev->modifiers() & Qt::ShiftModifier, tabev->modifiers() & Qt::AltModifier);
				}
			}
			_prevpoint = point;
		}
	} else if(event->type() == QEvent::TabletPress && _enableTabletEvents) {
		// Stylus touches the tablet surface
		QTabletEvent *tabev = static_cast<QTabletEvent*>(event);
		tabev->accept();

		if(_dragbtndown) {
			startDrag(tabev->x(), tabev->y(), _dragbtndown);
		} else {
			if(_pendown == NOTDOWN) {
				_pointerdistance = 0;
				_pointervelocity = 0;

				const paintcore::Point point = mapToScene(tabev->posF(), mapPressure(tabev->pressure(), true));

				_specialpenmode = tabev->modifiers() & Qt::ControlModifier; /* note: modifiers doesn't seem to work, at least on Qt 5.2.0 */
				_pendown = TABLETDOWN;
				onPenDown(point, false);
				updateOutline(point);
				_prevpoint = point;

			}
		}
	} else if(event->type() == QEvent::TabletRelease && _enableTabletEvents) {
		// Stylus lifted
		// Ignore this event: a mouseRelease event is also generated, so we let
		// the mouseRleaseEvent function handle this.
	} else {
		return QGraphicsView::viewportEvent(event);
	}
	
	return true;
}
Beispiel #10
0
bool KisMirrorAxis::eventFilter(QObject* target, QEvent* event)
{
    if (!visible()) return false;

    QObject *expectedCanvasWidget = view() ?
        view()->canvasBase()->canvasWidget() : 0;

    if (!expectedCanvasWidget || target != expectedCanvasWidget) return false;

    if(event->type() == QEvent::MouseButtonPress || event->type() == QEvent::TabletPress) {
        QMouseEvent *me = dynamic_cast<QMouseEvent*>(event);
        QTabletEvent *te = dynamic_cast<QTabletEvent*>(event);
        QPoint pos = me ? me->pos() : (te ? te->pos() : QPoint(77,77));

        if(d->mirrorHorizontal && d->horizontalHandle.contains(pos)) {
            d->xActive = true;
            QApplication::setOverrideCursor(Qt::ClosedHandCursor);
            event->accept();
            return true;
        }

        if(d->mirrorVertical && d->verticalHandle.contains(pos)) {
            d->yActive = true;
            QApplication::setOverrideCursor(Qt::ClosedHandCursor);
            event->accept();
            return true;
        }
    }
    if(event->type() == QEvent::MouseMove || event->type() == QEvent::TabletMove) {
        QMouseEvent *me = dynamic_cast<QMouseEvent*>(event);
        QTabletEvent *te = dynamic_cast<QTabletEvent*>(event);

        QPoint pos = me ? me->pos() : (te ? te->pos() : QPoint(77,77));

        if(d->xActive) {
            float axisX = view()->viewConverter()->widgetToImage<QPoint>(pos).x();

            d->setAxisPosition(axisX, d->axisPosition.y());
            d->horizontalHandlePosition = KisAlgebra2D::dotProduct<QPointF>(pos - d->horizontalAxis.p1(), d->horizontalAxis.unitVector().p2() - d->horizontalAxis.p1());

            event->accept();
            return true;
        }
        if(d->yActive) {
            float axisY = view()->viewConverter()->widgetToImage<QPoint>(pos).y();

            d->setAxisPosition(d->axisPosition.x(), axisY);
            d->verticalHandlePosition = KisAlgebra2D::dotProduct<QPointF>(pos - d->verticalAxis.p1(), d->verticalAxis.unitVector().p2() - d->verticalAxis.p1());

            event->accept();
            return true;
        }
        if(d->mirrorHorizontal) {
            if(d->horizontalHandle.contains(pos)) {
                if(!d->horizontalContainsCursor) {
                    QApplication::setOverrideCursor(Qt::OpenHandCursor);
                    d->horizontalContainsCursor = true;
                }
            } else if(d->horizontalContainsCursor) {
                QApplication::restoreOverrideCursor();
                d->horizontalContainsCursor = false;
            }
        }
        if(d->mirrorVertical) {
            if(d->verticalHandle.contains(pos)) {
                if(!d->verticalContainsCursor) {
                    QApplication::setOverrideCursor(Qt::OpenHandCursor);
                    d->verticalContainsCursor = true;
                }
            } else if(d->verticalContainsCursor) {
                QApplication::restoreOverrideCursor();
                d->verticalContainsCursor = false;
            }
        }
    }
    if(event->type() == QEvent::MouseButtonRelease || event->type() == QEvent::TabletRelease) {

        if(d->xActive) {
            QApplication::restoreOverrideCursor();
            d->xActive = false;
            event->accept();
            return true;
        }
        if(d->yActive) {
            QApplication::restoreOverrideCursor();
            d->yActive = false;
            event->accept();
            return true;
        }
    }

    return QObject::eventFilter(target, event);
}
Beispiel #11
0
RTabletEvent::RTabletEvent(const QTabletEvent& tabletEvent, RGraphicsScene& s,
        RGraphicsView& v) :
    QTabletEvent(tabletEvent), screenPosition(tabletEvent.pos().x(),
            tabletEvent.pos().y()), scene(s), view(v) {

}
Beispiel #12
0
/**
 * Tablet events are handled here
 * @param event event info
 */
bool EditorView::viewportEvent(QEvent *event)
{
    if(event->type() == QEvent::TabletMove) {
        // Stylus moved
        QTabletEvent *tabev = static_cast<QTabletEvent*>(event);
        tabev->accept();
        const dpcore::Point point(mapToScene(tabev->pos()), tabev->pressure());

        if(!prevpoint_.intSame(point)) {
            if(isdragging_)
                moveDrag(tabev->x(), tabev->y());
            else {
                if(pendown_) {
                    if(point.pressure()==0) {
                        // Missed a release event
                        pendown_ = NOTDOWN;
                        emit penUp();
                    } else {
                        emit penMove(point);
                    }
                }
                updateOutline(point);
            }
            prevpoint_ = point;
        }
    } else if(event->type() == QEvent::TabletPress) {
        // Stylus touches the tablet surface
        QTabletEvent *tabev = static_cast<QTabletEvent*>(event);
        tabev->accept();
        if(dragbtndown_) {
            startDrag(tabev->x(), tabev->y(), dragbtndown_);
        } else {
            if(pendown_ == NOTDOWN) {
                const dpcore::Point point(mapToScene(tabev->pos()), tabev->pressure());

                pendown_ = TABLETDOWN;
                emit penDown(point);
                updateOutline(point);
                prevpoint_ = point;
            }
        }
    } else if(event->type() == QEvent::TabletRelease) {
        // Stylus lifted
        QTabletEvent *tabev = static_cast<QTabletEvent*>(event);
        tabev->accept();
        if(isdragging_) {
            stopDrag();
        } else if(pendown_ == TABLETDOWN) {
            dpcore::Point point(mapToScene(tabev->pos()), 0);
            updateOutline(point);
            prevpoint_ = point;
            pendown_ = NOTDOWN;
            emit penUp();
        }
    } else {
        return QGraphicsView::viewportEvent(event);
    }

    return true;
}