]> git.saurik.com Git - wxWidgets.git/commitdiff
added support for colour cursors in wxGTK (patch 1655576)
authorVadim Zeitlin <vadim@wxwidgets.org>
Sun, 11 Feb 2007 03:02:34 +0000 (03:02 +0000)
committerVadim Zeitlin <vadim@wxwidgets.org>
Sun, 11 Feb 2007 03:02:34 +0000 (03:02 +0000)
git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@44462 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775

docs/changes.txt
docs/latex/wx/cursor.tex
src/gtk/cursor.cpp

index f74cf55783429c81f1fd7fab7b8c38ed61458009..ce23d8298a254758d6b6230a55c52dd440a7444c 100644 (file)
@@ -33,6 +33,7 @@ wxGTK:
 - wxTopLevelWindow::SetSizeHints size increments now work
 - wxTopLevelWindow::GetSize() returns the size including the WM decorations
 - wxTopLevelWindow::GetClientSize() returns 0x0 when the window is minimized
+- Added support for colour cursors (Pascal Monasse)
 
 wxMSW:
 
index 7a07cdd22939da19f997273b053e5ffd9665f840..a6f8fceed58ab438f6199baa63a9dd1e233649a9 100644 (file)
@@ -74,13 +74,20 @@ Constructs a cursor using a cursor identifier.
 
 \func{}{wxCursor}{\param{const wxImage\&}{ image}}
 
-Constructs a cursor from a wxImage. The cursor is monochrome, colors with the RGB elements all greater
-than 127 will be foreground, colors less than this background. The mask (if any) will be used as transparent.
+Constructs a cursor from a wxImage. If cursor are monochrome on the current
+platform, colors with the RGB elements all greater than 127 will be foreground,
+colors less than this background. The mask (if any) will be used to specify the
+transparent area.
 
-In MSW the foreground will be white and the background black. If the cursor is larger than 32x32 it is resized.
-In GTK, the two most frequent colors will be used for foreground and background. The cursor will be displayed
-at the size of the image.
-On MacOS if the cursor is larger than 16x16 it is resized and currently only shown as black/white (mask respected).
+In wxMSW the foreground will be white and the background black. If the cursor
+is larger than 32x32 it is resized.
+
+In wxGTK, colour cursors and alpha channel are supported (starting from GTK+
+2.2). Otherwise the two most frequent colors will be used for foreground and
+background. In any case, the cursor will be displayed at the size of the image.
+
+In wxMac, if the cursor is larger than 16x16 it is resized and currently only
+shown as black/white (mask respected).
 
 \func{}{wxCursor}{\param{const wxCursor\&}{ cursor}}
 
index aa71d2490f32355f32e4735bf2251d48a1cff1fb..56d699feb71025907baefc9ffcfd0c228ed09f68 100644 (file)
@@ -152,6 +152,24 @@ wxCursor::wxCursor(const char bits[], int width, int  height,
 
 #if wxUSE_IMAGE
 
+static void GetHotSpot(const wxImage& image, int& x, int& y)
+{
+    if (image.HasOption(wxIMAGE_OPTION_CUR_HOTSPOT_X))
+        x = image.GetOptionInt(wxIMAGE_OPTION_CUR_HOTSPOT_X);
+    else
+        x = 0;
+
+    if (image.HasOption(wxIMAGE_OPTION_CUR_HOTSPOT_Y))
+        y = image.GetOptionInt(wxIMAGE_OPTION_CUR_HOTSPOT_Y);
+    else
+        y = 0;
+
+    if (x < 0 || x >= image.GetWidth())
+        x = 0;
+    if (y < 0 || y >= image.GetHeight())
+        y = 0;
+}
+
 wxCursor::wxCursor( const wxImage & image )
 {
     unsigned char * rgbBits = image.GetData();
@@ -160,6 +178,55 @@ wxCursor::wxCursor( const wxImage & image )
     bool bHasMask = image.HasMask();
     int imagebitcount = (w*h)/8;
 
+#if GTK_CHECK_VERSION(2,2,0)
+    if ( gdk_display_supports_cursor_color(gdk_display_get_default()) )
+    {
+        unsigned char rMask = 0,
+                      gMask = 0,
+                      bMask = 0;
+        if (bHasMask)
+        {
+            rMask = image.GetMaskRed();
+            gMask = image.GetMaskGreen();
+            bMask = image.GetMaskBlue();
+        }
+
+        GdkPixbuf *pixbuf = gdk_pixbuf_new(GDK_COLORSPACE_RGB, true, 8, w, h);
+        unsigned char *alpha = image.HasAlpha() ? image.GetAlpha() : NULL;
+        unsigned char *out = gdk_pixbuf_get_pixels(pixbuf);
+        int rowpad = gdk_pixbuf_get_rowstride(pixbuf) - 4 * w;
+        for ( int y = 0; y < h; y++, out += rowpad )
+        {
+            for ( int x = 0; x < w; x++, out += 4, rgbBits += 3 )
+            {
+                out[0] = rgbBits[0];
+                out[1] = rgbBits[1];
+                out[2] = rgbBits[2];
+                if (bHasMask &&
+                    out[0] == rMask && out[1] == gMask && out[2] == bMask)
+                    out[3] = 0;
+                else
+                    out[3] = alpha ? *alpha : 255;
+                if ( alpha )
+                    ++alpha;
+            }
+        }
+
+        int hotSpotX, hotSpotY;
+        GetHotSpot(image, hotSpotX, hotSpotY);
+
+        m_refData = new wxCursorRefData;
+        M_CURSORDATA->m_cursor = gdk_cursor_new_from_pixbuf
+                                 (
+                                  gdk_display_get_default(),
+                                  pixbuf,
+                                  hotSpotX, hotSpotY
+                                 );
+        g_object_unref (pixbuf);
+        return;
+    }
+#endif // GTK+ 2.2+
+
     unsigned char * bits = new unsigned char [imagebitcount];
     unsigned char * maskBits = new unsigned char [imagebitcount];
 
@@ -266,23 +333,8 @@ wxCursor::wxCursor( const wxImage & image )
         bg = tmp;
     }
 
-    int hotSpotX;
-    int hotSpotY;
-
-    if (image.HasOption(wxIMAGE_OPTION_CUR_HOTSPOT_X))
-        hotSpotX = image.GetOptionInt(wxIMAGE_OPTION_CUR_HOTSPOT_X);
-    else
-        hotSpotX = 0;
-
-    if (image.HasOption(wxIMAGE_OPTION_CUR_HOTSPOT_Y))
-        hotSpotY = image.GetOptionInt(wxIMAGE_OPTION_CUR_HOTSPOT_Y);
-    else
-        hotSpotY = 0;
-
-    if (hotSpotX < 0 || hotSpotX >= w)
-        hotSpotX = 0;
-    if (hotSpotY < 0 || hotSpotY >= h)
-        hotSpotY = 0;
+    int hotSpotX, hotSpotY;
+    GetHotSpot(image, hotSpotX, hotSpotY);
 
     GdkBitmap *data = gdk_bitmap_create_from_data(wxGetRootWindow()->window,
                                                   (gchar *) bits, w, h);