1 /****************************************************************************
3 ** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
4 ** Contact: http://www.qt-project.org/legal
6 ** This file is part of the QtGui module of the Qt Toolkit.
8 ** $QT_BEGIN_LICENSE:LGPL$
9 ** Commercial License Usage
10 ** Licensees holding valid commercial Qt licenses may use this file in
11 ** accordance with the commercial license agreement provided with the
12 ** Software or, alternatively, in accordance with the terms contained in
13 ** a written agreement between you and Digia. For licensing terms and
14 ** conditions see http://qt.digia.com/licensing. For further information
15 ** use the contact form at http://qt.digia.com/contact-us.
17 ** GNU Lesser General Public License Usage
18 ** Alternatively, this file may be used under the terms of the GNU Lesser
19 ** General Public License version 2.1 as published by the Free Software
20 ** Foundation and appearing in the file LICENSE.LGPL included in the
21 ** packaging of this file. Please review the following information to
22 ** ensure the GNU Lesser General Public License version 2.1 requirements
23 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
25 ** In addition, as a special exception, Digia gives you certain additional
26 ** rights. These rights are described in the Digia Qt LGPL Exception
27 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
29 ** GNU General Public License Usage
30 ** Alternatively, this file may be used under the terms of the GNU
31 ** General Public License version 3.0 as published by the Free Software
32 ** Foundation and appearing in the file LICENSE.GPL included in the
33 ** packaging of this file. Please review the following information to
34 ** ensure the GNU General Public License version 3.0 requirements will be
35 ** met: http://www.gnu.org/copyleft/gpl.html.
40 ****************************************************************************/
46 #include <qcoreapplication.h>
49 #include <qdatastream.h>
51 #include <private/qcursor_p.h>
59 \brief The QCursor class provides a mouse cursor with an arbitrary
67 This class is mainly used to create mouse cursors that are
68 associated with particular widgets and to get and set the position
71 Qt has a number of standard cursor shapes, but you can also make
72 custom cursor shapes based on a QBitmap, a mask and a hotspot.
74 To associate a cursor with a widget, use QWidget::setCursor(). To
75 associate a cursor with all widgets (normally for a short period
76 of time), use QGuiApplication::setOverrideCursor().
78 To set a cursor shape use QCursor::setShape() or use the QCursor
79 constructor which takes the shape as argument, or you can use one
80 of the predefined cursors defined in the \l Qt::CursorShape enum.
82 If you want to create a cursor with your own bitmap, either use
83 the QCursor constructor which takes a bitmap and a mask or the
84 constructor which takes a pixmap as arguments.
86 To set or get the position of the mouse cursor use the static
87 methods QCursor::pos() and QCursor::setPos().
89 \b{Note:} It is possible to create a QCursor before
90 QGuiApplication, but it is not useful except as a place-holder for a
91 real QCursor created after QGuiApplication. Attempting to use a
92 QCursor that was created before QGuiApplication will result in a
95 \section1 A Note for X11 Users
97 On X11, Qt supports the \l{Xcursor}{Xcursor}
98 library, which allows for full color icon themes. The table below
99 shows the cursor name used for each Qt::CursorShape value. If a
100 cursor cannot be found using the name shown below, a standard X11
101 cursor will be used instead. Note: X11 does not provide
102 appropriate cursors for all possible Qt::CursorShape values. It
103 is possible that some cursors will be taken from the Xcursor
104 theme, while others will use an internal bitmap cursor.
107 \header \li Shape \li Qt::CursorShape Value \li Cursor Name
108 \li Shape \li Qt::CursorShape Value \li Cursor Name
109 \row \li \inlineimage cursor-arrow.png
110 \li Qt::ArrowCursor \li \c left_ptr
111 \li \inlineimage cursor-sizev.png
112 \li Qt::SizeVerCursor \li \c size_ver
113 \row \li \inlineimage cursor-uparrow.png
114 \li Qt::UpArrowCursor \li \c up_arrow
115 \li \inlineimage cursor-sizeh.png
116 \li Qt::SizeHorCursor \li \c size_hor
117 \row \li \inlineimage cursor-cross.png
118 \li Qt::CrossCursor \li \c cross
119 \li \inlineimage cursor-sizeb.png
120 \li Qt::SizeBDiagCursor \li \c size_bdiag
121 \row \li \inlineimage cursor-ibeam.png
122 \li Qt::IBeamCursor \li \c ibeam
123 \li \inlineimage cursor-sizef.png
124 \li Qt::SizeFDiagCursor \li \c size_fdiag
125 \row \li \inlineimage cursor-wait.png
126 \li Qt::WaitCursor \li \c wait
127 \li \inlineimage cursor-sizeall.png
128 \li Qt::SizeAllCursor \li \c size_all
129 \row \li \inlineimage cursor-busy.png
130 \li Qt::BusyCursor \li \c left_ptr_watch
131 \li \inlineimage cursor-vsplit.png
132 \li Qt::SplitVCursor \li \c split_v
133 \row \li \inlineimage cursor-forbidden.png
134 \li Qt::ForbiddenCursor \li \c forbidden
135 \li \inlineimage cursor-hsplit.png
136 \li Qt::SplitHCursor \li \c split_h
137 \row \li \inlineimage cursor-hand.png
138 \li Qt::PointingHandCursor \li \c pointing_hand
139 \li \inlineimage cursor-openhand.png
140 \li Qt::OpenHandCursor \li \c openhand
141 \row \li \inlineimage cursor-whatsthis.png
142 \li Qt::WhatsThisCursor \li \c whats_this
143 \li \inlineimage cursor-closedhand.png
144 \li Qt::ClosedHandCursor \li \c closedhand
146 \li Qt::DragMoveCursor \li \c dnd-move or \c move
148 \li Qt::DragCopyCursor \li \c dnd-copy or \c copy
150 \li Qt::DragLinkCursor \li \c dnd-link or \c link
153 \sa QWidget, {fowler}{GUI Design Handbook: Cursors}
157 \fn QPoint QCursor::pos(const QScreen *screen)
159 Returns the position of the cursor (hot spot) of the \a screen
160 in global screen coordinates.
162 You can call QWidget::mapFromGlobal() to translate it to widget
165 \sa setPos(), QWidget::mapFromGlobal(), QWidget::mapToGlobal()
169 \fn QPoint QCursor::pos()
171 Returns the position of the cursor (hot spot) of
172 the primary screen in global screen coordinates.
174 You can call QWidget::mapFromGlobal() to translate it to widget
177 \note The position is queried from the windowing system. If mouse events are generated
178 via other means (e.g., via QWindowSystemInterface in a unit test), those fake mouse
179 moves will not be reflected in the returned value.
181 \note On platforms where there is no windowing system or cursors are not available, the returned
182 position is based on the mouse move events generated via QWindowSystemInterface.
184 \sa setPos(), QWidget::mapFromGlobal(), QWidget::mapToGlobal(), QGuiApplication::primaryScreen()
189 \fn void QCursor::setPos(QScreen *screen, int x, int y)
191 Moves the cursor (hot spot) of the \a screen to the global
192 screen position (\a x, \a y).
194 You can call QWidget::mapToGlobal() to translate widget
195 coordinates to global screen coordinates.
197 \note Calling this function results in changing the cursor position through the windowing
198 system. The windowing system will typically respond by sending mouse events to the application's
199 window. This means that the usage of this function should be avoided in unit tests and
200 everywhere where fake mouse events are being injected via QWindowSystemInterface because the
201 windowing system's mouse state (with regards to buttons for example) may not match the state in
202 the application-generated events.
204 \note On platforms where there is no windowing system or cursors are not available, this
205 function may do nothing.
207 \sa pos(), QWidget::mapFromGlobal(), QWidget::mapToGlobal()
211 \fn void QCursor::setPos(int x, int y)
213 Moves the cursor (hot spot) of the primary screen
214 to the global screen position (\a x, \a y).
216 You can call QWidget::mapToGlobal() to translate widget
217 coordinates to global screen coordinates.
219 \sa pos(), QWidget::mapFromGlobal(), QWidget::mapToGlobal(), QGuiApplication::primaryScreen()
223 \fn void QCursor::setPos (const QPoint &p)
227 Moves the cursor (hot spot) to the global screen position at point
232 \fn void QCursor::setPos (QScreen *screen,const QPoint &p)
236 Moves the cursor (hot spot) to the global screen position of the
237 \a screen at point \a p.
240 /*****************************************************************************
241 QCursor stream functions
242 *****************************************************************************/
244 #ifndef QT_NO_DATASTREAM
248 \fn QDataStream &operator<<(QDataStream &stream, const QCursor &cursor)
251 Writes the \a cursor to the \a stream.
253 \sa {Serializing Qt Data Types}
256 QDataStream &operator<<(QDataStream &s, const QCursor &c)
258 s << (qint16)c.shape(); // write shape id to stream
259 if (c.shape() == Qt::BitmapCursor) { // bitmap cursor
260 bool isPixmap = false;
261 if (s.version() >= 7) {
262 isPixmap = !c.pixmap().isNull();
268 s << *c.bitmap() << *c.mask();
275 \fn QDataStream &operator>>(QDataStream &stream, QCursor &cursor)
278 Reads the \a cursor from the \a stream.
280 \sa {Serializing Qt Data Types}
283 QDataStream &operator>>(QDataStream &s, QCursor &c)
286 s >> shape; // read shape id from stream
287 if (shape == Qt::BitmapCursor) { // read bitmap cursor
288 bool isPixmap = false;
289 if (s.version() >= 7)
295 c = QCursor(pm, hot.x(), hot.y());
299 s >> bm >> bmm >> hot;
300 c = QCursor(bm, bmm, hot.x(), hot.y());
303 c.setShape((Qt::CursorShape)shape); // create cursor with shape
307 #endif // QT_NO_DATASTREAM
311 Constructs a custom pixmap cursor.
313 \a pixmap is the image. It is usual to give it a mask (set using
314 QPixmap::setMask()). \a hotX and \a hotY define the cursor's hot
317 If \a hotX is negative, it is set to the \c{pixmap().width()/2}.
318 If \a hotY is negative, it is set to the \c{pixmap().height()/2}.
320 Valid cursor sizes depend on the display hardware (or the
321 underlying window system). We recommend using 32 x 32 cursors,
322 because this size is supported on all platforms. Some platforms
323 also support 16 x 16, 48 x 48, and 64 x 64 cursors.
325 \note On Windows CE, the cursor size is fixed. If the pixmap
326 is bigger than the system size, it will be scaled.
328 \sa QPixmap::QPixmap(), QPixmap::setMask()
331 QCursor::QCursor(const QPixmap &pixmap, int hotX, int hotY)
334 QImage img = pixmap.toImage().convertToFormat(QImage::Format_Indexed8, Qt::ThresholdDither|Qt::AvoidDither);
335 QBitmap bm = QBitmap::fromImage(img, Qt::ThresholdDither|Qt::AvoidDither);
336 QBitmap bmm = pixmap.mask();
341 else if (!pixmap.mask().isNull()) {
342 QImage mimg = pixmap.mask().toImage().convertToFormat(QImage::Format_Indexed8, Qt::ThresholdDither|Qt::AvoidDither);
343 bmm = QBitmap::fromImage(mimg, Qt::ThresholdDither|Qt::AvoidDither);
346 bmm = QBitmap(bm.size());
347 bmm.fill(Qt::color1);
350 d = QCursorData::setBitmap(bm, bmm, hotX, hotY);
357 Constructs a custom bitmap cursor.
360 \a mask make up the bitmap.
362 \a hotY define the cursor's hot spot.
364 If \a hotX is negative, it is set to the \c{bitmap().width()/2}.
365 If \a hotY is negative, it is set to the \c{bitmap().height()/2}.
367 The cursor \a bitmap (B) and \a mask (M) bits are combined like this:
369 \li B=1 and M=1 gives black.
370 \li B=0 and M=1 gives white.
371 \li B=0 and M=0 gives transparent.
372 \li B=1 and M=0 gives an XOR'd result under Windows, undefined
373 results on all other platforms.
376 Use the global Qt color Qt::color0 to draw 0-pixels and Qt::color1 to
377 draw 1-pixels in the bitmaps.
379 Valid cursor sizes depend on the display hardware (or the
380 underlying window system). We recommend using 32 x 32 cursors,
381 because this size is supported on all platforms. Some platforms
382 also support 16 x 16, 48 x 48, and 64 x 64 cursors.
384 \note On Windows CE, the cursor size is fixed. If the pixmap
385 is bigger than the system size, it will be scaled.
387 \sa QBitmap::QBitmap(), QBitmap::setMask()
390 QCursor::QCursor(const QBitmap &bitmap, const QBitmap &mask, int hotX, int hotY)
393 d = QCursorData::setBitmap(bitmap, mask, hotX, hotY);
396 QCursorData *qt_cursorTable[Qt::LastCursor + 1];
397 bool QCursorData::initialized = false;
400 void QCursorData::cleanup()
402 if(!QCursorData::initialized)
405 for (int shape = 0; shape <= Qt::LastCursor; ++shape) {
406 // In case someone has a static QCursor defined with this shape
407 if (!qt_cursorTable[shape]->ref.deref())
408 delete qt_cursorTable[shape];
409 qt_cursorTable[shape] = 0;
411 QCursorData::initialized = false;
415 void QCursorData::initialize()
417 if (QCursorData::initialized)
419 for (int shape = 0; shape <= Qt::LastCursor; ++shape)
420 qt_cursorTable[shape] = new QCursorData((Qt::CursorShape)shape);
421 QCursorData::initialized = true;
425 Constructs a cursor with the default arrow shape.
429 if (!QCursorData::initialized) {
430 if (QCoreApplication::startingUp()) {
434 QCursorData::initialize();
436 QCursorData *c = qt_cursorTable[0];
442 Constructs a cursor with the specified \a shape.
444 See \l Qt::CursorShape for a list of shapes.
448 QCursor::QCursor(Qt::CursorShape shape)
451 if (!QCursorData::initialized)
452 QCursorData::initialize();
458 Returns the cursor shape identifier. The return value is one of
459 the \l Qt::CursorShape enum values (cast to an int).
463 Qt::CursorShape QCursor::shape() const
465 if (!QCursorData::initialized)
466 QCursorData::initialize();
471 Sets the cursor to the shape identified by \a shape.
473 See \l Qt::CursorShape for the list of cursor shapes.
477 void QCursor::setShape(Qt::CursorShape shape)
479 if (!QCursorData::initialized)
480 QCursorData::initialize();
481 QCursorData *c = uint(shape) <= Qt::LastCursor ? qt_cursorTable[shape] : 0;
483 c = qt_cursorTable[0];
495 Returns the cursor bitmap, or 0 if it is one of the standard
498 const QBitmap *QCursor::bitmap() const
500 if (!QCursorData::initialized)
501 QCursorData::initialize();
506 Returns the cursor bitmap mask, or 0 if it is one of the standard
510 const QBitmap *QCursor::mask() const
512 if (!QCursorData::initialized)
513 QCursorData::initialize();
518 Returns the cursor pixmap. This is only valid if the cursor is a
522 QPixmap QCursor::pixmap() const
524 if (!QCursorData::initialized)
525 QCursorData::initialize();
530 Returns the cursor hot spot, or (0, 0) if it is one of the
534 QPoint QCursor::hotSpot() const
536 if (!QCursorData::initialized)
537 QCursorData::initialize();
538 return QPoint(d->hx, d->hy);
542 Constructs a copy of the cursor \a c.
545 QCursor::QCursor(const QCursor &c)
547 if (!QCursorData::initialized)
548 QCursorData::initialize();
559 if (d && !d->ref.deref())
565 Assigns \a c to this cursor and returns a reference to this
569 QCursor &QCursor::operator=(const QCursor &c)
571 if (!QCursorData::initialized)
572 QCursorData::initialize();
575 if (d && !d->ref.deref())
582 Returns the cursor as a QVariant.
584 QCursor::operator QVariant() const
586 return QVariant(QVariant::Cursor, this);
589 #ifndef QT_NO_DEBUG_STREAM
590 QDebug operator<<(QDebug dbg, const QCursor &c)
592 dbg.nospace() << "QCursor(Qt::CursorShape(" << c.shape() << "))";
598 #endif // QT_NO_CURSOR