diff options
Diffstat (limited to 'src/gui/kernel/qevent.cpp')
-rw-r--r-- | src/gui/kernel/qevent.cpp | 308 |
1 files changed, 262 insertions, 46 deletions
diff --git a/src/gui/kernel/qevent.cpp b/src/gui/kernel/qevent.cpp index d6741af152..492f2a11c9 100644 --- a/src/gui/kernel/qevent.cpp +++ b/src/gui/kernel/qevent.cpp @@ -287,6 +287,8 @@ QMouseEvent::~QMouseEvent() \l Qt::MouseEventNotSynthesized is returned always. \sa Qt::MouseEventSource + \sa QGraphicsSceneMouseEvent::source() + \sa QGraphicsSceneMouseEvent::setSource() */ Qt::MouseEventSource QMouseEvent::source() const { @@ -301,6 +303,8 @@ Qt::MouseEventSource QMouseEvent::source() const The mouse event flags provide additional information about a mouse event. \sa Qt::MouseEventFlag + \sa QGraphicsSceneMouseEvent::flags() + \sa QGraphicsSceneMouseEvent::setFlags() */ Qt::MouseEventFlags QMouseEvent::flags() const { @@ -1185,7 +1189,7 @@ Qt::FocusReason QFocusEvent::reason() const The event contains a region() that needs to be updated, and a rect() that is the bounding rectangle of that region. Both are - provided because many widgets can't make much use of region(), + provided because many widgets cannot make much use of region(), and rect() can be much faster than region().boundingRect(). \section1 Automatic Clipping @@ -1977,40 +1981,63 @@ QVariant QInputMethodQueryEvent::value(Qt::InputMethodQuery query) const \ingroup events - Tablet Events are generated from a Wacom tablet. Most of the time you will - want to deal with events from the tablet as if they were events from a - mouse; for example, you would retrieve the cursor position with x(), y(), - pos(), globalX(), globalY(), and globalPos(). In some situations you may - wish to retrieve the extra information provided by the tablet device - driver; for example, you might want to do subpixeling with higher - resolution coordinates or you may want to adjust color brightness based on - pressure. QTabletEvent allows you to read the pressure(), the xTilt(), and - yTilt(), as well as the type of device being used with device() (see - \l{TabletDevice}). It can also give you the minimum and maximum values for - each device's pressure and high resolution coordinates. - - A tablet event contains a special accept flag that indicates whether the - receiver wants the event. You should call QTabletEvent::accept() if you - handle the tablet event; otherwise it will be sent to the parent widget. - The exception are TabletEnterProximity and TabletLeaveProximity events, - these are only sent to QApplication and don't check whether or not they are - accepted. - - The QWidget::setEnabled() function can be used to enable or - disable mouse and keyboard events for a widget. - - The event handler QWidget::tabletEvent() receives all three types of - tablet events. Qt will first send a tabletEvent then, if it is not - accepted, it will send a mouse event. This allows applications that - don't utilize tablets to use a tablet like a mouse, while also - enabling those who want to use both tablets and mouses differently. + \e{Tablet events} are generated from tablet peripherals such as Wacom + tablets and various other brands, and electromagnetic stylus devices + included with some types of tablet computers. (It is not the same as + \l QTouchEvent which a touchscreen generates, even when a passive stylus is + used on a touchscreen.) + + Tablet events are similar to mouse events; for example, the \l x(), \l y(), + \l pos(), \l globalX(), \l globalY(), and \l globalPos() accessors provide + the cursor position, and you can see which \l buttons() are pressed + (pressing the stylus tip against the tablet surface is equivalent to a left + mouse button). But tablet events also pass through some extra information + that the tablet device driver provides; for example, you might want to do + subpixel rendering with higher resolution coordinates (\l hiResGlobalX() + and \l hiResGlobalY()), adjust color brightness based on the \l pressure() + of the tool against the tablet surface, use different brushes depending on + the type of tool in use (\l device()), modulate the brush shape in some way + according to the X-axis and Y-axis tilt of the tool with respect to the + tablet surface (\l xTilt() and \l yTilt()), and use a virtual eraser + instead of a brush if the user switches to the other end of a double-ended + stylus (\l pointerType()). + + Every event contains an accept flag that indicates whether the receiver + wants the event. You should call QTabletEvent::accept() if you handle the + tablet event; otherwise it will be sent to the parent widget. The exception + are TabletEnterProximity and TabletLeaveProximity events: these are only + sent to QApplication and do not check whether or not they are accepted. + + The QWidget::setEnabled() function can be used to enable or disable + mouse, tablet and keyboard events for a widget. + + The event handler QWidget::tabletEvent() receives TabletPress, + TabletRelease and TabletMove events. Qt will first send a + tablet event, then if it is not accepted by any widget, it will send a + mouse event. This allows users of applications that are not designed for + tablets to use a tablet like a mouse. However high-resolution drawing + applications should handle the tablet events, because they can occur at a + higher frequency, which is a benefit for smooth and accurate drawing. + If the tablet events are rejected, the synthetic mouse events may be + compressed for efficiency. + + New in Qt 5.4: QTabletEvent includes all information available from the + device, including \l QTabletEvent::buttons(). Previously it was not + possible to accept all tablet events and also know which stylus buttons + were pressed. + + Note that pressing the stylus button while the stylus hovers over the + tablet will generate a button press on some types of tablets, while on + other types it will be necessary to press the stylus against the tablet + surface in order to register the simultaneous stylus button press. \section1 Notes for X11 Users - Qt uses the following hard-coded names to identify tablet - devices from the xorg.conf file on X11 (apart from IRIX): - 'stylus', 'pen', and 'eraser'. If the devices have other names, - they will not be picked up Qt. + If the tablet is configured in xorg.conf to use the Wacom driver, there + will be separate XInput "devices" for the stylus, eraser, and (optionally) + cursor and touchpad. Qt recognizes these by their names. Otherwise, if the + tablet is configured to use the evdev driver, there will be only one device + and applications may not be able to distinguish the stylus from the eraser. */ /*! @@ -2068,11 +2095,73 @@ QVariant QInputMethodQueryEvent::value(Qt::InputMethodQuery query) const The \a tangentialPressure parameter contins the tangential pressure of an air brush. If the device does not support tangential pressure, pass 0 here. + \a rotation contains the device's rotation in degrees. 4D mice and the Wacom + Art Pen support rotation. If the device does not support rotation, pass 0 here. + + The \a button that caused the event is given as a value from the + \l Qt::MouseButton enum. If the event \a type is not \l TabletPress or + \l TabletRelease, the appropriate button for this event is \l Qt::NoButton. + + \a buttons is the state of all buttons at the time of the event. + + \sa pos(), globalPos(), device(), pressure(), xTilt(), yTilt(), uniqueId(), rotation(), + tangentialPressure(), z() +*/ + +QTabletEvent::QTabletEvent(Type type, const QPointF &pos, const QPointF &globalPos, + int device, int pointerType, + qreal pressure, int xTilt, int yTilt, qreal tangentialPressure, + qreal rotation, int z, Qt::KeyboardModifiers keyState, qint64 uniqueID, + Qt::MouseButton button, Qt::MouseButtons buttons) + : QInputEvent(type, keyState), + mPos(pos), + mGPos(globalPos), + mDev(device), + mPointerType(pointerType), + mXT(xTilt), + mYT(yTilt), + mZ(z), + mPress(pressure), + mTangential(tangentialPressure), + mRot(rotation), + mUnique(uniqueID), + mExtra(new QTabletEventPrivate(button, buttons)) +{ +} + +/*! + Construct a tablet event of the given \a type. + + The \a pos parameter indicates where the event occurred in the + widget; \a globalPos is the corresponding position in absolute + coordinates. + + \a pressure contains the pressure exerted on the \a device. + + \a pointerType describes the type of pen that is being used. + + \a xTilt and \a yTilt contain the device's degree of tilt from the + x and y axes respectively. + + \a keyState specifies which keyboard modifiers are pressed (e.g., + \uicontrol{Ctrl}). + + The \a uniqueID parameter contains the unique ID for the current device. + + The \a z parameter contains the coordinate of the device on the tablet, this + is usually given by a wheel on 4D mouse. If the device does not support a + Z-axis, pass zero here. + + The \a tangentialPressure parameter contins the tangential pressure of an air + brush. If the device does not support tangential pressure, pass 0 here. + \a rotation contains the device's rotation in degrees. 4D mice support rotation. If the device does not support rotation, pass 0 here. \sa pos(), globalPos(), device(), pressure(), xTilt(), yTilt(), uniqueId(), rotation(), tangentialPressure(), z() + + \deprecated in 5.4: use the constructor with MouseButton status */ QTabletEvent::QTabletEvent(Type type, const QPointF &pos, const QPointF &globalPos, @@ -2091,7 +2180,7 @@ QTabletEvent::QTabletEvent(Type type, const QPointF &pos, const QPointF &globalP mTangential(tangentialPressure), mRot(rotation), mUnique(uniqueID), - mExtra(0) + mExtra(new QTabletEventPrivate(Qt::NoButton, Qt::NoButton)) { } @@ -2103,6 +2192,34 @@ QTabletEvent::~QTabletEvent() } /*! + Returns the button that caused the event. + + Note that the returned value is always Qt::NoButton for \l TabletMove, + \l TabletEnterProximity and \l TabletLeaveProximity events. + + \sa buttons(), Qt::MouseButton +*/ +Qt::MouseButton QTabletEvent::button() const +{ + return static_cast<QTabletEventPrivate *>(mExtra)->b; +} + +/*! + Returns the button state when the event was generated. The button state is + a combination of buttons from the \l Qt::MouseButton enum using the OR + operator. For \l TabletMove events, this is all buttons that are pressed + down. For \l TabletPress events this includes the button that caused the + event. For \l TabletRelease events this excludes the button that caused the + event. + + \sa button(), Qt::MouseButton +*/ +Qt::MouseButtons QTabletEvent::buttons() const +{ + return static_cast<QTabletEventPrivate *>(mExtra)->buttonState; +} + +/*! \fn TabletDevices QTabletEvent::device() const Returns the type of device that generated the event. @@ -2132,7 +2249,7 @@ QTabletEvent::~QTabletEvent() \fn qreal QTabletEvent::rotation() const Returns the rotation of the current device in degress. This is usually - given by a 4D Mouse. If the device doesn't support rotation this value is + given by a 4D Mouse. If the device does not support rotation this value is always 0.0. */ @@ -3036,7 +3153,7 @@ QActionEvent::~QActionEvent() If spontaneous() is true, the event originated outside the application. In this case, the user hid the window using the window manager controls, either by iconifying the window or by - switching to another virtual desktop where the window isn't + switching to another virtual desktop where the window is not visible. The window will become hidden but not withdrawn. If the window was iconified, QWidget::isMinimized() returns \c true. @@ -3265,6 +3382,61 @@ static inline void formatTouchEvent(QDebug d, const char *name, const QTouchEven d << ')'; } +static void formatUnicodeString(QDebug d, const QString &s) +{ + d << '"' << hex; + for (int i = 0; i < s.size(); ++i) { + if (i) + d << ','; + d << "U+" << s.at(i).unicode(); + } + d << dec << '"'; +} + +static inline void formatInputMethodEvent(QDebug d, const QInputMethodEvent *e) +{ + d << "QInputMethodEvent("; + if (!e->preeditString().isEmpty()) { + d << "preedit="; + formatUnicodeString(d, e->preeditString()); + } + if (!e->commitString().isEmpty()) { + d << ", commit="; + formatUnicodeString(d, e->commitString()); + } + if (e->replacementLength()) { + d << ", replacementStart=" << e->replacementStart() << ", replacementLength=" + << e->replacementLength(); + } + if (const int attributeCount = e->attributes().size()) { + d << ", attributes= {"; + for (int a = 0; a < attributeCount; ++a) { + const QInputMethodEvent::Attribute &at = e->attributes().at(a); + if (a) + d << ','; + d << "[type= " << at.type << ", start=" << at.start << ", length=" << at.length + << ", value=" << at.value << ']'; + } + d << '}'; + } + d << ')'; +} + +static inline void formatInputMethodQueryEvent(QDebug d, const QInputMethodQueryEvent *e) +{ + const Qt::InputMethodQueries queries = e->queries(); + d << "QInputMethodQueryEvent(queries=" << showbase << hex << int(queries) + << noshowbase << dec << ", {"; + for (unsigned mask = 1; mask <= Qt::ImTextAfterCursor; mask<<=1) { + if (queries & mask) { + const QVariant value = e->value(static_cast<Qt::InputMethodQuery>(mask)); + if (value.isValid()) + d << '[' << showbase << hex << mask << noshowbase << dec << '=' << value << "],"; + } + } + d << "})"; +} + QDebug operator<<(QDebug dbg, const QEvent *e) { // More useful event output could be added here if (!e) @@ -3302,6 +3474,8 @@ QDebug operator<<(QDebug dbg, const QEvent *e) { << ", " << hex << (int)me->modifiers() << dec; if (const Qt::MouseEventSource source = me->source()) nsp << ", source = " << source; + if (const Qt::MouseEventFlags flags = me->flags()) + nsp << ", flags = " << hex << int(flags) << dec; nsp << ')'; } return dbg.space(); @@ -3355,11 +3529,13 @@ QDebug operator<<(QDebug dbg, const QEvent *e) { } return dbg.space(); case QEvent::FocusIn: - n = "FocusIn"; - break; + dbg.nospace() << "QFocusEvent(FocusIn, reason=" + << static_cast<const QFocusEvent *>(e)->reason() << ')'; + return dbg.space(); case QEvent::FocusOut: - n = "FocusOut"; - break; + dbg.nospace() << "QFocusEvent(FocusOut, reason=" + << static_cast<const QFocusEvent *>(e)->reason() << ')'; + return dbg.space(); case QEvent::Enter: n = "Enter"; break; @@ -3381,12 +3557,24 @@ QDebug operator<<(QDebug dbg, const QEvent *e) { case QEvent::Paint: n = "Paint"; break; - case QEvent::Move: - n = "Move"; - break; - case QEvent::Resize: - n = "Resize"; - break; + case QEvent::Move: { + const QMoveEvent *me = static_cast<const QMoveEvent *>(e); + QDebug nospace = dbg.nospace(); + nospace << "QMoveEvent(" << me->pos(); + if (!me->spontaneous()) + nospace << ", non-spontaneous"; + nospace << ')'; + } + return dbg.space(); + case QEvent::Resize: { + const QResizeEvent *re = static_cast<const QResizeEvent *>(e); + QDebug nospace = dbg.nospace(); + nospace << "QResizeEvent(" << re->size(); + if (!re->spontaneous()) + nospace << ", non-spontaneous"; + nospace << ')'; + } + return dbg.space(); case QEvent::Create: n = "Create"; break; @@ -3498,6 +3686,18 @@ QDebug operator<<(QDebug dbg, const QEvent *e) { case QEvent::GraphicsSceneMove: n = "GraphicsSceneMove"; break; + case QEvent::InputMethod: { + QDebugStateSaver saver(dbg); + dbg.nospace(); + formatInputMethodEvent(dbg, static_cast<const QInputMethodEvent *>(e)); + } + return dbg; + case QEvent::InputMethodQuery: { + QDebugStateSaver saver(dbg); + dbg.nospace(); + formatInputMethodQueryEvent(dbg, static_cast<const QInputMethodQueryEvent *>(e)); + } + return dbg; case QEvent::CursorChange: n = "CursorChange"; break; @@ -3551,7 +3751,23 @@ QDebug operator<<(QDebug dbg, const QEvent *e) { case QEvent::Gesture: n = "Gesture"; break; + case QEvent::GestureOverride: + n = "GestureOverride"; + break; #endif + case QEvent::MetaCall: + n = "MetaCall"; + break; + case QEvent::ApplicationStateChange: + dbg.nospace() << "QApplicationStateChangeEvent(" + << static_cast<const QApplicationStateChangeEvent *>(e)->applicationState() << ')'; + return dbg.space(); + case QEvent::WindowTitleChange: + n = "WindowTitleChange"; + break; + case QEvent::Expose: + n = "Expose"; + break; default: dbg.nospace() << "QEvent(" << (const void *)e << ", type = " << e->type() << ')'; return dbg.space(); @@ -3570,7 +3786,7 @@ QDebug operator<<(QDebug dbg, const QEvent *e) { \ingroup events \inmodule QtGui - Normally you don't need to use this class directly; QShortcut + Normally you do not need to use this class directly; QShortcut provides a higher-level interface to handle shortcut keys. \sa QShortcut |