@@ -1,5 +1,5 @@
2− * Copyright (C) 2015 Canonical, Ltd.
2+ * Copyright (C) 2015-2016 Canonical, Ltd.
4 * This program is free software: you can redistribute it and/or modify it under
4 * This program is free software: you can redistribute it and/or modify it under
5 * the terms of the GNU Lesser General Public License version 3, as published by
5 * the terms of the GNU Lesser General Public License version 3, as published by
@@ -46,6 +46,9 @@ BuiltInCursorImage::BuiltInCursorImage()
46 qimage.fill(Qt::transparent);
46 qimage.fill(Qt::transparent);
47 QPainter imagePainter(&qimage);
47 QPainter imagePainter(&qimage);
49+ frameWidth = qimage.width();
50+ frameHeight = qimage.height();
49 QSvgRenderer *svgRenderer = new QSvgRenderer(QByteArray(svgString));
52 QSvgRenderer *svgRenderer = new QSvgRenderer(QByteArray(svgString));
50 svgRenderer->render(&imagePainter);
53 svgRenderer->render(&imagePainter);
51 delete svgRenderer;
54 delete svgRenderer;
@@ -59,6 +62,8 @@ BlankCursorImage::BlankCursorImage()
60 qimage = QImage(1, 1, QImage::Format_ARGB32);
63 qimage = QImage(1, 1, QImage::Format_ARGB32);
61 qimage.fill(Qt::transparent);
64 qimage.fill(Qt::transparent);
65+ frameWidth = qimage.width();
66+ frameHeight = qimage.height();
@@ -69,40 +74,74 @@ CustomCursorImage::CustomCursorImage(const QCursor &cursor)
70 qimage = cursor.pixmap().toImage();
75 qimage = cursor.pixmap().toImage();
71 hotspot = cursor.hotSpot();
76 hotspot = cursor.hotSpot();
77+ frameWidth = qimage.width();
78+ frameHeight = qimage.height();
75// XCursorImage
82// XCursorImage
77XCursorImage::XCursorImage(const QString &theme, const QString &file)
84XCursorImage::XCursorImage(const QString &theme, const QString &file)
78− : xcursorImages(nullptr)
80 // TODO: Consider grid unit value
86 // TODO: Consider grid unit value
81 // Hardcoding to a medium size for now
87 // Hardcoding to a medium size for now
82 int preferredCursorHeightPx = 32;
88 int preferredCursorHeightPx = 32;
84− xcursorImages = XcursorLibraryLoadImages(QFile::encodeName(file), QFile::encodeName(theme),
90+ XcursorImages *xcursorImages = XcursorLibraryLoadImages(QFile::encodeName(file), QFile::encodeName(theme),
85 preferredCursorHeightPx);
91 preferredCursorHeightPx);
86− if (!xcursorImages) {
92+ if (!xcursorImages || xcursorImages->nimage == 0) {
90− // Just take the first one. It will have multiple images in case of an animated cursor.
96+ frameCount = xcursorImages->nimage;
91− // TODO: Support animated cursors
92− if ( xcursorImages->nimage > 0) {
93− XcursorImage *xcursorImage = xcursorImages->images[0];
95− qimage = QImage((uchar*)xcursorImage->pixels,
98+ for (int i = 0; i < xcursorImages->nimage; ++i) {
96− xcursorImage->width, xcursorImage->height, QImage::Format_ARGB32);
99+ XcursorImage *xcursorImage = xcursorImages->images[0];
100+ if (frameWidth < (int)xcursorImage->width) {
101+ frameWidth = xcursorImage->width;
103+ if (frameHeight < (int)xcursorImage->height) {
104+ frameHeight = xcursorImage->height;
107+ frameDuration = (int)xcursorImage->delay;
109+ if (frameDuration != (int)xcursorImage->delay) {
110+ qWarning().nospace() << "CursorImageProvider: XCursorImage("<<theme<<","<<file<<") has"
111+ " varying delays in its animation. Animation won't look right.";
117+ // Assume that the hotspot position does not animate
118+ XcursorImage *xcursorImage = xcursorImages->images[0];
98 hotspot.setX(xcursorImage->xhot);
119 hotspot.setX(xcursorImage->xhot);
99 hotspot.setY(xcursorImage->yhot);
120 hotspot.setY(xcursorImage->yhot);
123+ // Build the sprite as a single row of frames
124+ qimage = QImage(frameWidth*frameCount, frameHeight, QImage::Format_ARGB32);
125+ qimage.fill(Qt::transparent);
128+ QPainter painter(&qimage);
130+ for (int i = 0; i < xcursorImages->nimage; ++i) {
131+ XcursorImage *xcursorImage = xcursorImages->images[i];
133+ auto frameImage = QImage((uchar*)xcursorImage->pixels,
134+ xcursorImage->width, xcursorImage->height, QImage::Format_ARGB32);
136+ painter.drawImage(QPoint(i*frameWidth, 0), frameImage);
140+ XcursorImagesDestroy(xcursorImages);
103XCursorImage::~XCursorImage()
143XCursorImage::~XCursorImage()
105− XcursorImagesDestroy(xcursorImages);
@@ -205,16 +244,6 @@ QImage CursorImageProvider::requestImage(const QString &cursorThemeAndName, QSiz
205 return cursorImage->qimage;
244 return cursorImage->qimage;
208−QPoint CursorImageProvider::hotspot(const QString &themeName, const QString &cursorName)
210− CursorImage *cursorImage = fetchCursor(themeName, cursorName);
212− return cursorImage->hotspot;
218CursorImage *CursorImageProvider::fetchCursor(const QString &cursorThemeAndName)
247CursorImage *CursorImageProvider::fetchCursor(const QString &cursorThemeAndName)
220 QString themeName;
249 QString themeName;