QVariant Util::decorationForVariant(const QVariant &value) { switch (value.type()) { case QVariant::Brush: { const QBrush b = value.value<QBrush>(); if (b.style() != Qt::NoBrush) { QPixmap p(16, 16); p.fill(QColor(0, 0, 0, 0)); QPainter painter(&p); painter.setBrush(b); painter.drawRect(0, 0, p.width() - 1, p.height() - 1); return p; } } case QVariant::Color: { const QColor c = value.value<QColor>(); if (c.isValid()) { QPixmap p(16, 16); QPainter painter(&p); painter.setBrush(QBrush(c)); painter.drawRect(0, 0, p.width() - 1, p.height() - 1); return p; } } case QVariant::Cursor: { const QCursor c = value.value<QCursor>(); if (!c.pixmap().isNull()) { return c.pixmap().scaled(16, 16, Qt::KeepAspectRatio, Qt::FastTransformation); } } case QVariant::Icon: { return value; } case QVariant::Pen: { const QPen pen = value.value<QPen>(); if (pen.style() != Qt::NoPen) { QPixmap p(16, 16); p.fill(QColor(0, 0, 0, 0)); QPainter painter(&p); painter.setPen(pen); painter.translate(0, 8 - pen.width() / 2); painter.drawLine(0, 0, p.width(), 0); return p; } } case QVariant::Pixmap: { const QPixmap p = value.value<QPixmap>(); return QVariant::fromValue(p.scaled(16, 16, Qt::KeepAspectRatio, Qt::FastTransformation)); } default: break; } return QVariant(); }
QXcbCursorCacheKey::QXcbCursorCacheKey(const QCursor &c) : shape(c.shape()), bitmapCacheKey(0), maskCacheKey(0) { if (shape == Qt::BitmapCursor) { const qint64 pixmapCacheKey = c.pixmap().cacheKey(); if (pixmapCacheKey) { bitmapCacheKey = pixmapCacheKey; } else { Q_ASSERT(c.bitmap()); Q_ASSERT(c.mask()); bitmapCacheKey = c.bitmap()->cacheKey(); maskCacheKey = c.mask()->cacheKey(); } } }
// static QCursor MapEditorTool::scaledToScreen(const QCursor& unscaled_cursor) { auto scale = Settings::getInstance().getSetting(Settings::General_PixelsPerInch).toReal() / 96.0; if (unscaled_cursor.shape() == Qt::BitmapCursor && scale > 1.5) { // Need to scale our low res image for high DPI screen const auto unscaled_pixmap = unscaled_cursor.pixmap(); const auto scaled_hotspot = QPointF{ unscaled_cursor.hotSpot() } * scale; return QCursor{ unscaled_pixmap.scaledToWidth(unscaled_pixmap.width() * scale, Qt::SmoothTransformation), qRound(scaled_hotspot.x()), qRound(scaled_hotspot.y()) }; } else { return unscaled_cursor; } }
void QBasicDrag::updateCursor(Qt::DropAction action) { #ifndef QT_NO_CURSOR Qt::CursorShape cursorShape = Qt::ForbiddenCursor; if (canDrop()) { switch (action) { case Qt::CopyAction: cursorShape = Qt::DragCopyCursor; break; case Qt::LinkAction: cursorShape = Qt::DragLinkCursor; break; default: cursorShape = Qt::DragMoveCursor; break; } } QCursor *cursor = QGuiApplication::overrideCursor(); QPixmap pixmap = m_drag->dragCursor(action); if (!cursor) { QGuiApplication::changeOverrideCursor((pixmap.isNull()) ? QCursor(cursorShape) : QCursor(pixmap)); } else { if (!pixmap.isNull()) { if ((cursor->pixmap().cacheKey() != pixmap.cacheKey())) { QGuiApplication::changeOverrideCursor(QCursor(pixmap)); } } else { if (cursorShape != cursor->shape()) { QGuiApplication::changeOverrideCursor(QCursor(cursorShape)); } } } #endif updateAction(action); }
HCURSOR QWindowsCursor::createSystemCursor(const QCursor &c) { int hx = c.hotSpot().x(); int hy = c.hotSpot().y(); const Qt::CursorShape cshape = c.shape(); if (cshape == Qt::BitmapCursor) { const QPixmap pixmap = c.pixmap(); if (!pixmap.isNull()) if (const HCURSOR hc = createPixmapCursor(pixmap, hx, hy)) return hc; } // Non-standard Windows cursors are created from bitmaps static const uchar vsplit_bits[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0xc0, 0x01, 0x00, 0x00, 0xe0, 0x03, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0xff, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x7f, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0xe0, 0x03, 0x00, 0x00, 0xc0, 0x01, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; static const uchar vsplitm_bits[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0xc0, 0x01, 0x00, 0x00, 0xe0, 0x03, 0x00, 0x00, 0xf0, 0x07, 0x00, 0x00, 0xf8, 0x0f, 0x00, 0x00, 0xc0, 0x01, 0x00, 0x00, 0xc0, 0x01, 0x00, 0x00, 0xc0, 0x01, 0x00, 0x80, 0xff, 0xff, 0x00, 0x80, 0xff, 0xff, 0x00, 0x80, 0xff, 0xff, 0x00, 0x80, 0xff, 0xff, 0x00, 0x80, 0xff, 0xff, 0x00, 0x80, 0xff, 0xff, 0x00, 0x00, 0xc0, 0x01, 0x00, 0x00, 0xc0, 0x01, 0x00, 0x00, 0xc0, 0x01, 0x00, 0x00, 0xf8, 0x0f, 0x00, 0x00, 0xf0, 0x07, 0x00, 0x00, 0xe0, 0x03, 0x00, 0x00, 0xc0, 0x01, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; static const uchar hsplit_bits[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x02, 0x00, 0x00, 0x40, 0x02, 0x00, 0x00, 0x40, 0x02, 0x00, 0x00, 0x40, 0x02, 0x00, 0x00, 0x40, 0x02, 0x00, 0x00, 0x41, 0x82, 0x00, 0x80, 0x41, 0x82, 0x01, 0xc0, 0x7f, 0xfe, 0x03, 0x80, 0x41, 0x82, 0x01, 0x00, 0x41, 0x82, 0x00, 0x00, 0x40, 0x02, 0x00, 0x00, 0x40, 0x02, 0x00, 0x00, 0x40, 0x02, 0x00, 0x00, 0x40, 0x02, 0x00, 0x00, 0x40, 0x02, 0x00, 0x00, 0x40, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; static const uchar hsplitm_bits[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x07, 0x00, 0x00, 0xe0, 0x07, 0x00, 0x00, 0xe0, 0x07, 0x00, 0x00, 0xe0, 0x07, 0x00, 0x00, 0xe2, 0x47, 0x00, 0x00, 0xe3, 0xc7, 0x00, 0x80, 0xe3, 0xc7, 0x01, 0xc0, 0xff, 0xff, 0x03, 0xe0, 0xff, 0xff, 0x07, 0xc0, 0xff, 0xff, 0x03, 0x80, 0xe3, 0xc7, 0x01, 0x00, 0xe3, 0xc7, 0x00, 0x00, 0xe2, 0x47, 0x00, 0x00, 0xe0, 0x07, 0x00, 0x00, 0xe0, 0x07, 0x00, 0x00, 0xe0, 0x07, 0x00, 0x00, 0xe0, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; static const uchar openhand_bits[] = { 0x80,0x01,0x58,0x0e,0x64,0x12,0x64,0x52,0x48,0xb2,0x48,0x92, 0x16,0x90,0x19,0x80,0x11,0x40,0x02,0x40,0x04,0x40,0x04,0x20, 0x08,0x20,0x10,0x10,0x20,0x10,0x00,0x00}; static const uchar openhandm_bits[] = { 0x80,0x01,0xd8,0x0f,0xfc,0x1f,0xfc,0x5f,0xf8,0xff,0xf8,0xff, 0xf6,0xff,0xff,0xff,0xff,0x7f,0xfe,0x7f,0xfc,0x7f,0xfc,0x3f, 0xf8,0x3f,0xf0,0x1f,0xe0,0x1f,0x00,0x00}; static const uchar closedhand_bits[] = { 0x00,0x00,0x00,0x00,0x00,0x00,0xb0,0x0d,0x48,0x32,0x08,0x50, 0x10,0x40,0x18,0x40,0x04,0x40,0x04,0x20,0x08,0x20,0x10,0x10, 0x20,0x10,0x20,0x10,0x00,0x00,0x00,0x00}; static const uchar closedhandm_bits[] = { 0x00,0x00,0x00,0x00,0x00,0x00,0xb0,0x0d,0xf8,0x3f,0xf8,0x7f, 0xf0,0x7f,0xf8,0x7f,0xfc,0x7f,0xfc,0x3f,0xf8,0x3f,0xf0,0x1f, 0xe0,0x1f,0xe0,0x1f,0x00,0x00,0x00,0x00}; wchar_t *sh = 0; switch (c.shape()) { // map to windows cursor case Qt::ArrowCursor: sh = IDC_ARROW; break; case Qt::UpArrowCursor: sh = IDC_UPARROW; break; case Qt::CrossCursor: sh = IDC_CROSS; break; case Qt::WaitCursor: sh = IDC_WAIT; break; case Qt::IBeamCursor: sh = IDC_IBEAM; break; case Qt::SizeVerCursor: sh = IDC_SIZENS; break; case Qt::SizeHorCursor: sh = IDC_SIZEWE; break; case Qt::SizeBDiagCursor: sh = IDC_SIZENESW; break; case Qt::SizeFDiagCursor: sh = IDC_SIZENWSE; break; case Qt::SizeAllCursor: sh = IDC_SIZEALL; break; case Qt::ForbiddenCursor: sh = IDC_NO; break; case Qt::WhatsThisCursor: sh = IDC_HELP; break; case Qt::BusyCursor: sh = IDC_APPSTARTING; break; case Qt::PointingHandCursor: sh = IDC_HAND; break; case Qt::BlankCursor: case Qt::SplitVCursor: case Qt::SplitHCursor: case Qt::OpenHandCursor: case Qt::ClosedHandCursor: case Qt::BitmapCursor: { QImage bbits, mbits; bool invb, invm; if (cshape == Qt::BlankCursor) { bbits = QImage(32, 32, QImage::Format_Mono); bbits.fill(0); // ignore color table mbits = bbits.copy(); hx = hy = 16; invb = invm = false; } else if (cshape == Qt::OpenHandCursor || cshape == Qt::ClosedHandCursor) { bool open = cshape == Qt::OpenHandCursor; QBitmap cb = QBitmap::fromData(QSize(16, 16), open ? openhand_bits : closedhand_bits); QBitmap cm = QBitmap::fromData(QSize(16, 16), open ? openhandm_bits : closedhandm_bits); bbits = cb.toImage().convertToFormat(QImage::Format_Mono); mbits = cm.toImage().convertToFormat(QImage::Format_Mono); hx = hy = 8; invb = invm = false; } else if (cshape == Qt::BitmapCursor) { bbits = c.bitmap()->toImage().convertToFormat(QImage::Format_Mono); mbits = c.mask()->toImage().convertToFormat(QImage::Format_Mono); invb = bbits.colorCount() > 1 && qGray(bbits.color(0)) < qGray(bbits.color(1)); invm = mbits.colorCount() > 1 && qGray(mbits.color(0)) < qGray(mbits.color(1)); } else { // Qt::SplitVCursor, Qt::SplitHCursor const QBitmap cb = QBitmap::fromData(QSize(32, 32), cshape == Qt::SplitVCursor ? vsplit_bits : hsplit_bits); const QBitmap cm = QBitmap::fromData(QSize(32, 32), cshape == Qt::SplitVCursor ? vsplitm_bits : hsplitm_bits); bbits = cb.toImage().convertToFormat(QImage::Format_Mono); mbits = cm.toImage().convertToFormat(QImage::Format_Mono); hx = hy = 16; invb = invm = false; } const int n = qMax(1, bbits.width() / 8); const int h = bbits.height(); #if !defined(Q_OS_WINCE) QScopedArrayPointer<uchar> xBits(new uchar[h * n]); QScopedArrayPointer<uchar> xMask(new uchar[h * n]); int x = 0; for (int i = 0; i < h; ++i) { uchar *bits = bbits.scanLine(i); uchar *mask = mbits.scanLine(i); for (int j = 0; j < n; ++j) { uchar b = bits[j]; uchar m = mask[j]; if (invb) b ^= 0xff; if (invm) m ^= 0xff; xBits[x] = ~m; xMask[x] = b ^ m; ++x; } } return CreateCursor(GetModuleHandle(0), hx, hy, bbits.width(), bbits.height(), xBits.data(), xMask.data()); #elif defined(GWES_ICONCURS) // Q_WS_WINCE // Windows CE only supports fixed cursor size. int sysW = GetSystemMetrics(SM_CXCURSOR); int sysH = GetSystemMetrics(SM_CYCURSOR); int sysN = qMax(1, sysW / 8); uchar* xBits = new uchar[sysH * sysN]; uchar* xMask = new uchar[sysH * sysN]; int x = 0; for (int i = 0; i < sysH; ++i) { if (i >= h) { memset(&xBits[x] , 255, sysN); memset(&xMask[x] , 0, sysN); x += sysN; } else { int fillWidth = n > sysN ? sysN : n; uchar *bits = bbits.scanLine(i); uchar *mask = mbits.scanLine(i); for (int j = 0; j < fillWidth; ++j) { uchar b = bits[j]; uchar m = mask[j]; if (invb) b ^= 0xFF; if (invm) m ^= 0xFF; xBits[x] = ~m; xMask[x] = b ^ m; ++x; } for (int j = fillWidth; j < sysN; ++j ) { xBits[x] = 255; xMask[x] = 0; ++x; } } } HCURSOR hcurs = CreateCursor(qWinAppInst(), hx, hy, sysW, sysH, xBits, xMask); delete [] xBits; delete [] xMask; return hcurs; #else Q_UNUSED(n); Q_UNUSED(h); return 0; #endif } case Qt::DragCopyCursor: case Qt::DragMoveCursor: case Qt::DragLinkCursor: { const QPixmap pixmap = QGuiApplicationPrivate::instance()->getPixmapCursor(cshape); return createPixmapCursor(pixmap, hx, hy); } default: qWarning("%s: Invalid cursor shape %d", __FUNCTION__, cshape); return 0; } #ifdef Q_OS_WINCE return LoadCursor(0, sh); #else return (HCURSOR)LoadImage(0, sh, IMAGE_CURSOR, 0, 0, LR_DEFAULTSIZE | LR_SHARED); #endif }