Drop shadow madness
- From: iain <iain prettypeople org>
- To: desktop-devel-list gnome org
- Subject: Drop shadow madness
- Date: 16 Feb 2003 14:40:39 +0000
Okay,
First off
I don't expect to see this committed.
Ever.
It's a hack.
There's even a hack inside the hack
Thats how hacky this hacky hack is.
But I've been using it for a week now
And I love it.
It seems to add a modicum of class
And style to my otherwise dreery drab desktop.
So I am sharing it with the rest of the world.
But, like I say
It's a hack.
There's occasions where it won't look right.
And those occasions will never look right
With this hack.
I know about them
I don't care about them.
If it breaks -
Congratulations, you get to keep all the bits.
And so, without further ado...
I give you
the gtkmenu drop shadow hack
Taadaa!
(and yes, I nicked the arrays of values off of kde-look.org
which means that if you apply that patch to your KDE, then
the two drop shadows will look the same)
Enjoy
iain
--
Index: gtkmenu.c
===================================================================
RCS file: /cvs/gnome/gtk+/gtk/gtkmenu.c,v
retrieving revision 1.129
diff -U2 -r1.129 gtkmenu.c
--- gtkmenu.c 5 Feb 2003 23:48:09 -0000 1.129
+++ gtkmenu.c 16 Feb 2003 14:35:07 -0000
@@ -75,4 +75,7 @@
gint x;
gint y;
+ GdkPixbuf *west, *east, *south;
+ GdkWindow *west_shadow, *east_shadow, *south_shadow;
+ guint32 timeout_id;
};
@@ -182,4 +185,24 @@
static guint menu_signals[LAST_SIGNAL] = { 0 };
+static void
+free_private_data (gpointer data)
+{
+ GtkMenuPrivate *priv = (GtkMenuPrivate *) data;
+
+ if (priv->timeout_id > 0)
+ g_source_remove (priv->timeout_id);
+
+ if (priv->west)
+ g_object_unref (G_OBJECT (priv->west));
+
+ if (priv->east)
+ g_object_unref (G_OBJECT (priv->east));
+
+ if (priv->south)
+ g_object_unref (G_OBJECT (priv->south));
+
+ g_free (data);
+}
+
GtkMenuPrivate *
gtk_menu_get_private (GtkMenu *menu)
@@ -199,5 +222,5 @@
g_object_set_qdata_full (G_OBJECT (menu), private_quark,
- private, g_free);
+ private, free_private_data);
}
@@ -232,4 +255,349 @@
}
+static GdkPixbuf *
+get_pixbuf (GdkDrawable *window,
+ int x,
+ int y,
+ int width,
+ int height)
+{
+ GdkPixbuf *dest, *src;
+ int ow, oh;
+
+ dest = gdk_pixbuf_new (GDK_COLORSPACE_RGB, FALSE, 8, width, height);
+
+ ow = width;
+ oh = height;
+
+ if (x < 0) {
+ width += x;
+ x = 0;
+ }
+
+ if (y < 0) {
+ height += y;
+ y = 0;
+ }
+
+ if (width <= 0 || height <= 0)
+ return NULL;
+
+ window = gdk_get_default_root_window ();
+
+ src = gdk_pixbuf_get_from_drawable (NULL, window, NULL, x, y, 0, 0, width, height);
+
+ /* Copy the src into the dest at the right place */
+ gdk_pixbuf_copy_area (src, 0, 0, width, height,
+ dest, ow - width, oh - height);
+
+ g_object_unref (G_OBJECT (src));
+
+ return dest;
+}
+
+enum side {
+ WEST_SIDE,
+ EAST_SIDE,
+ SOUTH_SIDE
+};
+
+const double shadow_strip_l[16] = {
+ .996, .996, .992, .988, .980, .972, .956, .941, .917, .890, .858, .819, .776, .729, .678, .627
+};
+
+const double bottom_left_corner[256] = {
+ .996, .996, .992, .988, .980, .972, .956, .941, .917, .890, .858, .819, .776, .729, .678, .627,
+ .996, .996, .992, .988, .980, .972, .956, .941, .917, .890, .858, .819, .776, .729, .678, .627,
+ .996, .996, .992, .988, .980, .972, .956, .941, .917, .890, .858, .819, .776, .729, .678, .627,
+ .996, .996, .992, .988, .980, .972, .956, .941, .917, .890, .858, .819, .776, .729, .678, .627,
+ .996, .996, .992, .988, .980, .972, .956, .941, .917, .890, .858, .819, .776, .729, .678, .627,
+ 1.00, .996, .992, .988, .980, .972, .960, .941, .917, .890, .858, .819, .780, .733, .670, .643,
+ 1.00, .996, .992, .988, .980, .972, .960, .941, .917, .894, .858, .819, .780, .733, .670, .643,
+ 1.00, .996, .992, .988, .980, .972, .960, .941, .921, .894, .862, .827, .784, .737, .690, .639,
+ 1.00, .996, .992, .988, .980, .972, .960, .945, .925, .898, .870, .831, .796, .749, .701, .654,
+ 1.00, .996, .992, .992, .984, .976, .964, .949, .933, .909, .882, .847, .815, .776, .733, .686,
+ 1.00, .996, .992, .992, .988, .980, .972, .956, .941, .925, .901, .874, .847, .811, .780, .741,
+ 1.00, 1.00, .996, .992, .992, .988, .980, .968, .956, .945, .925, .909, .886, .901, .874, .811,
+ 1.00, 1.00, 1.00, .996, .992, .992, .988, .980, .976, .964, .952, .941, .929, .913, .898, .878,
+ 1.00, 1.00, 1.00, 1.00, .996, .996, .996, .992, .988, .984, .976, .968, .964, .952, .945, .937,
+ 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, .996, .996, .992, .988, .984, .980, .976, .972,
+ 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, .996, .996, .996, .992, .992, .992 };
+
+const double bottom_right_corner[256] = {
+ .627, .678, .729, .776, .819, .858, .890, .917, .941, .956, .972, .980, .988, .992, .996, .996,
+ .627, .678, .729, .776, .819, .858, .890, .917, .941, .956, .972, .980, .988, .992, .996, .996,
+ .627, .678, .729, .776, .819, .858, .890, .917, .941, .956, .972, .980, .988, .992, .996, .996,
+ .627, .678, .729, .776, .819, .858, .890, .917, .941, .956, .972, .980, .988, .992, .996, .996,
+ .627, .678, .729, .776, .819, .858, .890, .917, .941, .956, .972, .980, .988, .992, .996, .996,
+ .643, .670, .733, .780, .819, .858, .890, .917, .941, .960, .972, .980, .988, .992, .996, 1.00,
+ .643, .670, .733, .780, .819, .858, .894, .917, .941, .960, .972, .980, .988, .992, .996, 1.00,
+ .639, .690, .737, .784, .827, .862, .894, .921, .941, .960, .972, .980, .988, .992, .996, 1.00,
+ .654, .701, .749, .796, .831, .870, .898, .925, .945, .960, .972, .980, .988, .992, .996, 1.00,
+ .686, .733, .776, .815, .847, .882, .909, .933, .949, .964, .976, .984, .992, .992, .996, 1.00,
+ .741, .780, .811, .847, .874, .901, .925, .941, .956, .972, .980, .988, .992, .992, .996, 1.00,
+ .811, .874, .901, .886, .909, .925, .945, .956, .968, .980, .988, .992, .992, .996, 1.00, 1.00,
+ .878, .898, .913, .929, .941, .952, .964, .976, .980, .988, .992, .992, .996, 1.00, 1.00, 1.00,
+ .937, .945, .952, .964, .968, .976, .984, .988, .992, .996, .996, .996, 1.00, 1.00, 1.00, 1.00,
+ .972, .976, .980, .984, .988, .992, .996, .996, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00,
+ .992, .992, .992, .996, .996, .996, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00 };
+
+const double top_right_corner[256] = {
+ .992, .992, .992, .996, .996, .996, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00,
+ .972, .976, .980, .984, .988, .992, .996, .996, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00,
+ .937, .945, .952, .964, .968, .976, .984, .988, .992, .996, .996, .996, 1.00, 1.00, 1.00, 1.00,
+ .878, .898, .913, .929, .941, .952, .964, .976, .980, .988, .992, .992, .996, 1.00, 1.00, 1.00,
+ .811, .874, .901, .886, .909, .925, .945, .956, .968, .980, .988, .992, .992, .996, 1.00, 1.00,
+ .741, .780, .811, .847, .874, .901, .925, .941, .956, .972, .980, .988, .992, .992, .996, 1.00,
+ .686, .733, .776, .815, .847, .882, .909, .933, .949, .964, .976, .984, .992, .992, .996, 1.00,
+ .654, .701, .749, .796, .831, .870, .898, .925, .945, .960, .972, .980, .988, .992, .996, 1.00,
+ .639, .690, .737, .784, .827, .862, .894, .921, .941, .960, .972, .980, .988, .992, .996, 1.00,
+ .643, .670, .733, .780, .819, .858, .894, .917, .941, .960, .972, .980, .988, .992, .996, 1.00,
+ .643, .670, .733, .780, .819, .858, .890, .917, .941, .960, .972, .980, .988, .992, .996, 1.00,
+ .627, .678, .729, .776, .819, .858, .890, .917, .941, .956, .972, .980, .988, .992, .996, .996,
+ .627, .678, .729, .776, .819, .858, .890, .917, .941, .956, .972, .980, .988, .992, .996, .996,
+ .627, .678, .729, .776, .819, .858, .890, .917, .941, .956, .972, .980, .988, .992, .996, .996,
+ .627, .678, .729, .776, .819, .858, .890, .917, .941, .956, .972, .980, .988, .992, .996, .996,
+ .627, .678, .729, .776, .819, .858, .890, .917, .941, .956, .972, .980, .988, .992, .996, .996 };
+
+const double top_left_corner[256] = {
+ 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, .996, .996, .996, .992, .992, .992,
+ 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, .996, .996, .992, .988, .984, .980, .976, .972,
+ 1.00, 1.00, 1.00, 1.00, .996, .996, .996, .992, .988, .984, .976, .968, .964, .952, .945, .937,
+ 1.00, 1.00, 1.00, .996, .992, .992, .988, .980, .976, .964, .952, .941, .929, .913, .898, .878,
+ 1.00, 1.00, .996, .992, .992, .988, .980, .968, .956, .945, .925, .909, .886, .901, .874, .811,
+ 1.00, .996, .992, .992, .988, .980, .972, .956, .941, .925, .901, .874, .847, .811, .780, .741,
+ 1.00, .996, .992, .992, .984, .976, .964, .949, .933, .909, .882, .847, .815, .776, .733, .686,
+ 1.00, .996, .992, .988, .980, .972, .960, .945, .925, .898, .870, .831, .796, .749, .701, .654,
+ 1.00, .996, .992, .988, .980, .972, .960, .941, .921, .894, .862, .827, .784, .737, .690, .639,
+ 1.00, .996, .992, .988, .980, .972, .960, .941, .917, .894, .858, .819, .780, .733, .670, .643,
+ 1.00, .996, .992, .988, .980, .972, .960, .941, .917, .890, .858, .819, .780, .733, .670, .643,
+ .996, .996, .992, .988, .980, .972, .956, .941, .917, .890, .858, .819, .776, .729, .678, .627,
+ .996, .996, .992, .988, .980, .972, .956, .941, .917, .890, .858, .819, .776, .729, .678, .627,
+ .996, .996, .992, .988, .980, .972, .956, .941, .917, .890, .858, .819, .776, .729, .678, .627,
+ .996, .996, .992, .988, .980, .972, .956, .941, .917, .890, .858, .819, .776, .729, .678, .627,
+ .996, .996, .992, .988, .980, .972, .956, .941, .917, .890, .858, .819, .776, .729, .678, .627 };
+
+static void
+adjust_pixbuf (GdkPixbuf *pb,
+ enum side shadow)
+{
+ int width, rowstride, height;
+ int i;
+ guchar *pixels, *p;
+
+ width = gdk_pixbuf_get_width (pb);
+ height = gdk_pixbuf_get_height (pb);
+ rowstride = gdk_pixbuf_get_rowstride (pb);
+ pixels = gdk_pixbuf_get_pixels (pb);
+
+ switch (shadow) {
+ case WEST_SIDE:
+ if (height > 16) {
+ for (i = 0; i < 16; i++) {
+ int j, k;
+
+ p = pixels + (i * rowstride);
+
+ for (j = 0, k = 0; j < 48; j += 3, k++) {
+ p[j] = (guchar) (p[j] * top_left_corner [i * 16 + k]);
+ p[j + 1] = (guchar) (p[j + 1] * top_left_corner [i * 16 + k]);
+ p[j + 2] = (guchar) (p[j + 2] * top_left_corner [i * 16 + k]);
+ }
+ }
+
+ i = 16;
+ } else {
+ i = 0;
+ }
+
+ for (; i < height; i++) {
+ int j, k;
+
+ p = pixels + (i * rowstride);
+
+ for (j = 0, k = 0; j < 48; j += 3, k++) {
+ p[j] = (guchar) (p[j] * shadow_strip_l[k]);
+ p[j + 1] = (guchar) (p[j + 1] * shadow_strip_l[k]);
+ p[j + 2] = (guchar) (p[j + 2] * shadow_strip_l[k]);
+ }
+ }
+
+ break;
+
+ case EAST_SIDE:
+ if (height > 16) {
+ for (i = 0; i < 16; i++) {
+ int j, k;
+
+ p = pixels + (i * rowstride);
+
+ for (j = 0, k = 0; j < 48; j += 3, k++) {
+ p[j] = (guchar) (p[j] * top_right_corner [i * 16 + k]);
+ p[j + 1] = (guchar) (p[j + 1] * top_right_corner [i * 16 + k]);
+ p[j + 2] = (guchar) (p[j + 2] * top_right_corner [i * 16 + k]);
+ }
+ }
+
+ i = 16;
+ } else {
+ i = 0;
+ }
+
+ for (;i < height; i++) {
+ int j, k;
+
+ p = pixels + (i * rowstride);
+
+ for (j = 0, k = 0; j < 48; j += 3, k++) {
+ p[j] = (guchar) (p[j] * shadow_strip_l[15 - k]);
+ p[j + 1] = (guchar) (p[j + 1] * shadow_strip_l[15 - k]);
+ p[j + 2] = (guchar) (p[j + 2] * shadow_strip_l[15 - k]);
+ }
+ }
+
+ break;
+
+ case SOUTH_SIDE:
+ for (i = 0; i < 16; i++) {
+ int j, k;
+
+ p = pixels + (i * rowstride);
+
+ for (j = 0, k = 0; j < 48; j += 3, k++) {
+
+ p[j] = (guchar) (p[j] * bottom_left_corner[i * 16 + k]);
+ p[j + 1] = (guchar) (p[j + 1] * bottom_left_corner[i * 16 + k]);
+ p[j + 2] = (guchar) (p[j + 2] * bottom_left_corner[i * 16 + k]);
+ }
+
+ p = pixels + (i * rowstride) + 48;
+
+ for (j = 0, k = 0; j < (width * 3) - 96; j += 3, k++) {
+ p[j] = (guchar) (p[j] * bottom_right_corner [i * 16]);
+ p[j + 1] = (guchar) (p[j + 1] * bottom_right_corner [i * 16]);
+ p[j + 2] = (guchar) (p[j + 2] * bottom_right_corner [i * 16]);
+ }
+
+ p = pixels + (i * rowstride) + ((width * 3) - 48);
+ for (j = 0, k = 0; j < 48; j += 3, k++) {
+ p[j] = (guchar) (p[j] * bottom_right_corner[i * 16 + k]);
+ p[j + 1] = (guchar) (p[j + 1] * bottom_right_corner[i * 16 + k]);
+ p[j + 2] = (guchar) (p[j + 2] * bottom_right_corner[i * 16 + k]);
+ }
+ }
+
+ break;
+
+ default:
+ break;
+ }
+}
+
+static gboolean
+map_shadow_windows (gpointer data)
+{
+ GtkMenu *menu = GTK_MENU (data);
+ GtkWidget *widget = GTK_WIDGET (data);
+ GtkMenuPrivate *priv = gtk_menu_get_private (menu);
+ GdkPixbuf *pixbuf;
+ int tlx, tly;
+
+ gtk_window_get_position (gtk_widget_get_toplevel (widget), &tlx, &tly);
+ pixbuf = get_pixbuf (priv->west_shadow, tlx - 16, tly,
+ 16, widget->allocation.height);
+
+ if (pixbuf != NULL) {
+ adjust_pixbuf (pixbuf, WEST_SIDE);
+ if (priv->west != NULL) {
+ g_object_unref (G_OBJECT (priv->west));
+ }
+ priv->west = pixbuf;
+ }
+
+ pixbuf = get_pixbuf (priv->east_shadow, tlx + widget->allocation.width,
+ tly,
+ 16, widget->allocation.height);
+ if (pixbuf != NULL) {
+ adjust_pixbuf (pixbuf, EAST_SIDE);
+ if (priv->east != NULL) {
+ g_object_unref (G_OBJECT (priv->east));
+ }
+ priv->east = pixbuf;
+ }
+
+ pixbuf = get_pixbuf (priv->south_shadow, tlx - 16,
+ tly + widget->allocation.height,
+ widget->allocation.width + 32, 16);
+ if (pixbuf != NULL) {
+ adjust_pixbuf (pixbuf, SOUTH_SIDE);
+ if (priv->south != NULL) {
+ g_object_unref (G_OBJECT (priv->south));
+ }
+ priv->south = pixbuf;
+ }
+
+ gdk_window_show (priv->west_shadow);
+ gdk_window_show (priv->east_shadow);
+ gdk_window_show (priv->south_shadow);
+
+ priv->timeout_id = 0;
+ return FALSE;
+}
+
+static void
+gtk_menu_map (GtkWidget *widget)
+{
+ GtkMenuPrivate *priv = gtk_menu_get_private (GTK_MENU (widget));
+ /* What is this timeout for?
+ Well, its a hack inside a hack really.
+ Sometimes the parent window hasn't had time to redraw fully
+ so you get an ugly drop shadow on a half exposed window.
+ This timeout is an attempt to give the parent window a change
+ to redraw itself fully, so that the drop shadow doesn't look
+ just so ugly... */
+ priv->timeout_id = g_timeout_add (20, map_shadow_windows, widget);
+
+ GTK_WIDGET_CLASS (parent_class)->map (widget);
+}
+
+static void
+gtk_menu_unmap (GtkWidget *widget)
+{
+ GtkMenu *menu = GTK_MENU (widget);
+ GtkMenuPrivate *priv = gtk_menu_get_private (menu);
+
+ if (priv->timeout_id > 0) {
+ g_source_remove (priv->timeout_id);
+ priv->timeout_id = 0;
+ } else {
+ gdk_window_hide (priv->west_shadow);
+ gdk_window_hide (priv->east_shadow);
+ gdk_window_hide (priv->south_shadow);
+ }
+
+ GTK_WIDGET_CLASS (parent_class)->unmap (widget);
+}
+
+static gboolean
+gtk_menu_configure (GtkWidget *widget,
+ GdkEventConfigure *event)
+{
+ GtkMenu *menu;
+ GtkMenuPrivate *priv;
+ int tlx, tly;
+
+ menu = GTK_MENU (widget);
+ priv = gtk_menu_get_private (menu);
+
+ /* Move shadows */
+ gtk_window_get_position (gtk_widget_get_toplevel (widget), &tlx, &tly);
+
+ gdk_window_move (priv->west_shadow, tlx - 16, tly);
+ gdk_window_move (priv->east_shadow, tlx + widget->allocation.width, tly);
+ gdk_window_move (priv->south_shadow, tlx - 16, tly + widget->allocation.height);
+
+ return FALSE;
+}
+
static void
gtk_menu_class_init (GtkMenuClass *class)
@@ -280,6 +648,9 @@
widget_class->show_all = gtk_menu_show_all;
widget_class->hide_all = gtk_menu_hide_all;
+ widget_class->map = gtk_menu_map;
+ widget_class->unmap = gtk_menu_unmap;
widget_class->enter_notify_event = gtk_menu_enter_notify;
widget_class->leave_notify_event = gtk_menu_leave_notify;
+ widget_class->configure_event = gtk_menu_configure;
widget_class->motion_notify_event = gtk_menu_motion_notify;
widget_class->style_set = gtk_menu_style_set;
@@ -1005,5 +1376,5 @@
g_return_if_fail (GTK_IS_MENU (menu));
-
+
menu_shell = GTK_MENU_SHELL (menu);
private = gtk_menu_get_private (menu);
@@ -1488,10 +1859,13 @@
gint border_width;
GtkMenu *menu;
+ GtkMenuPrivate *priv;
GtkWidget *child;
GList *children;
-
+ int tlx, tly;
+
g_return_if_fail (GTK_IS_MENU (widget));
menu = GTK_MENU (widget);
+ priv = gtk_menu_get_private (menu);
GTK_WIDGET_SET_FLAGS (widget, GTK_REALIZED);
@@ -1559,4 +1933,43 @@
gdk_window_show (menu->bin_window);
gdk_window_show (menu->view_window);
+
+ /* Drop shadow */
+
+ gtk_window_get_position (gtk_widget_get_toplevel (widget), &tlx, &tly);
+
+ /* The West drop shadow window */
+ attributes.x = tlx - 16;
+ attributes.y = tly;
+ attributes.width = 16;
+ attributes.height = widget->allocation.height;
+ attributes.window_type = GDK_WINDOW_TEMP;
+ attributes.override_redirect = TRUE;
+
+ attributes_mask |= GDK_WA_NOREDIR;
+
+ priv->west_shadow = gdk_window_new (NULL, &attributes, attributes_mask);
+ gdk_window_set_user_data (priv->west_shadow, menu);
+
+ /* East drop shadow */
+ attributes.x = tlx + widget->allocation.width;
+ attributes.y = tly;
+ attributes.width = 16;
+ attributes.height = widget->allocation.height;
+
+ priv->east_shadow = gdk_window_new (NULL, &attributes, attributes_mask);
+ gdk_window_set_user_data (priv->east_shadow, menu);
+
+ /* South drop shadow */
+ attributes.x = tlx - 16;
+ attributes.y = tly + widget->allocation.height;
+ attributes.width = widget->allocation.width + 32;
+ attributes.height = 16;
+
+ priv->south_shadow = gdk_window_new (NULL, &attributes, attributes_mask);
+ gdk_window_set_user_data (priv->south_shadow, menu);
+
+ gdk_window_set_back_pixmap (priv->west_shadow, NULL, FALSE);
+ gdk_window_set_back_pixmap (priv->east_shadow, NULL, FALSE);
+ gdk_window_set_back_pixmap (priv->south_shadow, NULL, FALSE);
}
@@ -1621,8 +2034,10 @@
{
GtkMenu *menu;
+ GtkMenuPrivate *priv;
g_return_if_fail (GTK_IS_MENU (widget));
menu = GTK_MENU (widget);
+ priv = gtk_menu_get_private (menu);
menu_grab_transfer_window_destroy (menu);
@@ -1636,4 +2051,9 @@
menu->bin_window = NULL;
+ /* Shadows */
+ gdk_window_destroy (priv->west_shadow);
+ gdk_window_destroy (priv->east_shadow);
+ gdk_window_destroy (priv->south_shadow);
+
(* GTK_WIDGET_CLASS (parent_class)->unrealize) (widget);
}
@@ -1745,4 +2165,6 @@
if (GTK_WIDGET_REALIZED (widget))
{
+ GtkMenuPrivate *priv = gtk_menu_get_private (menu);
+
gdk_window_move_resize (widget->window,
allocation->x, allocation->y,
@@ -1754,4 +2176,8 @@
width,
height);
+
+ gdk_window_resize (priv->west_shadow, 16, allocation->height);
+ gdk_window_resize (priv->east_shadow, 16, allocation->height);
+ gdk_window_resize (priv->south_shadow, 32 + allocation->width, 16);
}
@@ -1909,4 +2335,59 @@
MENU_SCROLL_ARROW_HEIGHT - 2 * border_y - 2);
}
+ } else {
+ int width, height;
+ GdkGC *gc = widget->style->black_gc;
+ GtkMenuPrivate *priv = gtk_menu_get_private (menu);
+
+ if (event->window == priv->west_shadow) {
+ if (priv->west == NULL)
+ return;
+
+ gdk_gc_set_clip_rectangle (gc, &event->area);
+
+ width = gdk_pixbuf_get_width (priv->west);
+ height = gdk_pixbuf_get_height (priv->west);
+
+ gdk_draw_pixbuf (priv->west_shadow, gc, priv->west, 0, 0, 0, 0,
+ width, height, GDK_RGB_DITHER_NONE, 0, 0);
+
+ gdk_gc_set_clip_rectangle (gc, NULL);
+
+ return;
+ }
+
+ if (event->window == priv->east_shadow) {
+ if (priv->east == NULL)
+ return;
+
+ gdk_gc_set_clip_rectangle (gc, &event->area);
+
+ width = gdk_pixbuf_get_width (priv->east);
+ height = gdk_pixbuf_get_height (priv->east);
+
+ gdk_draw_pixbuf (priv->east_shadow, gc, priv->east, 0, 0, 0, 0,
+ width, height, GDK_RGB_DITHER_NONE, 0, 0);
+
+ gdk_gc_set_clip_rectangle (gc, NULL);
+ return;
+ }
+
+ if (event->window == priv->south_shadow) {
+ if (priv->south == NULL)
+ return;
+
+ gdk_gc_set_clip_rectangle (gc, &event->area);
+
+ width = gdk_pixbuf_get_width (priv->south);
+ height = gdk_pixbuf_get_height (priv->south);
+
+ gdk_draw_pixbuf (priv->south_shadow, gc, priv->south, 0, 0, 0, 0,
+ width, height, GDK_RGB_DITHER_NONE, 0, 0);
+
+ gdk_gc_set_clip_rectangle (gc, NULL);
+
+ return;
+ }
+
}
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]