diff options
author | Maciej Stachowiak <mstachow@src.gnome.org> | 2001-02-19 20:46:26 +0000 |
---|---|---|
committer | Maciej Stachowiak <mstachow@src.gnome.org> | 2001-02-19 20:46:26 +0000 |
commit | 9efcca800087241ed5c296789ff14a0c8c24cd02 (patch) | |
tree | 60bdcfc34c636895690b7541e5c462c7f920b965 | |
parent | 514928fdd24e7ee6fd39678a030dd6f43dbb1a10 (diff) | |
download | nautilus-9efcca800087241ed5c296789ff14a0c8c24cd02.tar.gz |
reviewed by: Gene Z. Ragan <gzr@eazel.com>
Added auto-prelighting feature to NautilusClickableImage, and
fixed a major bug that occurs for clickable images in scrolled
areas.
* libnautilus-extensions/nautilus-clickable-image.h,
libnautilus-extensions/nautilus-clickable-image.c:
(nautilus_clickable_image_set_prelight): New public API call that
allows for automatic prelight handling direct in
NautilusClickableImage; made it settable because some users of
this code want to manually prelight with an alternate image.
(nautilus_clickable_image_set_up_pixbufs): helper function for the
above that keeps track of the normal and prelit buffers.
(label_enter, label_leave): When in prelight mode, switch images
on enter and leave. Also, remove unnecessary queue_draw calls.
(adjust_coordinates_for_window, ancestor_enter_notify_event,
ancestor_leave_notify_event, ancestor_motion_notify_event): Do
some coordinate adjustments so that if the NautilusClickableImage
is in a scrolled area with NO_WINDOW widgets all the way in
between, we do an appropriate coordinate adjustment. This should
also handle other containers that put their children in a
different window than their own. This was breaking for the summary
view when I set it to use clickable images for the service icons.
* libnautilus/nautilus-view-standard-main.c
(nautilus_view_standard_main_multi): Do a g_thread_init to make
views that use gnome-vfs happy.
-rw-r--r-- | ChangeLog | 32 | ||||
-rw-r--r-- | libnautilus-extensions/nautilus-clickable-image.c | 136 | ||||
-rw-r--r-- | libnautilus-extensions/nautilus-clickable-image.h | 3 | ||||
-rw-r--r-- | libnautilus-private/nautilus-clickable-image.c | 136 | ||||
-rw-r--r-- | libnautilus-private/nautilus-clickable-image.h | 3 | ||||
-rw-r--r-- | libnautilus/nautilus-view-standard-main.c | 1 |
6 files changed, 295 insertions, 16 deletions
@@ -1,3 +1,35 @@ +2001-02-19 Maciej Stachowiak <mjs@eazel.com> + + reviewed by: Gene Z. Ragan <gzr@eazel.com> + + Added auto-prelighting feature to NautilusClickableImage, and + fixed a major bug that occurs for clickable images in scrolled + areas. + + * libnautilus-extensions/nautilus-clickable-image.h, + libnautilus-extensions/nautilus-clickable-image.c: + (nautilus_clickable_image_set_prelight): New public API call that + allows for automatic prelight handling direct in + NautilusClickableImage; made it settable because some users of + this code want to manually prelight with an alternate image. + (nautilus_clickable_image_set_up_pixbufs): helper function for the + above that keeps track of the normal and prelit buffers. + (label_enter, label_leave): When in prelight mode, switch images + on enter and leave. Also, remove unnecessary queue_draw calls. + + (adjust_coordinates_for_window, ancestor_enter_notify_event, + ancestor_leave_notify_event, ancestor_motion_notify_event): Do + some coordinate adjustments so that if the NautilusClickableImage + is in a scrolled area with NO_WINDOW widgets all the way in + between, we do an appropriate coordinate adjustment. This should + also handle other containers that put their children in a + different window than their own. This was breaking for the summary + view when I set it to use clickable images for the service icons. + + * libnautilus/nautilus-view-standard-main.c + (nautilus_view_standard_main_multi): Do a g_thread_init to make + views that use gnome-vfs happy. + 2001-02-18 Ian McKellar <ian@eazel.com> reviewed by: Robey Pointer <robey@eazel.com> diff --git a/libnautilus-extensions/nautilus-clickable-image.c b/libnautilus-extensions/nautilus-clickable-image.c index b5330e44c..705b63a63 100644 --- a/libnautilus-extensions/nautilus-clickable-image.c +++ b/libnautilus-extensions/nautilus-clickable-image.c @@ -29,6 +29,7 @@ #include "nautilus-gtk-macros.h" #include "nautilus-gtk-extensions.h" #include "nautilus-art-gtk-extensions.h" +#include "nautilus-graphic-effects.h" #include <gtk/gtkmain.h> @@ -55,6 +56,10 @@ static guint clickable_image_signals[LAST_SIGNAL] = { 0 }; struct _NautilusClickableImageDetails { gboolean pointer_inside; + gboolean prelight; + + GdkPixbuf *pixbuf; + GdkPixbuf *prelight_pixbuf; }; /* GtkObjectClass methods */ @@ -241,10 +246,14 @@ label_enter (NautilusClickableImage *clickable_image) { g_return_if_fail (NAUTILUS_IS_CLICKABLE_IMAGE (clickable_image)); - clickable_image->details->pointer_inside = TRUE; + clickable_image->details->pointer_inside = TRUE; + + if (clickable_image->details->prelight) { + nautilus_labeled_image_set_pixbuf (NAUTILUS_LABELED_IMAGE (clickable_image), + clickable_image->details->prelight_pixbuf); + } gtk_widget_set_state (GTK_WIDGET (clickable_image), GTK_STATE_PRELIGHT); - gtk_widget_queue_draw (GTK_WIDGET (clickable_image)); gtk_signal_emit (GTK_OBJECT (clickable_image), clickable_image_signals[ENTER], @@ -257,10 +266,14 @@ label_leave (NautilusClickableImage *clickable_image) { g_return_if_fail (NAUTILUS_IS_CLICKABLE_IMAGE (clickable_image)); - clickable_image->details->pointer_inside = FALSE; + clickable_image->details->pointer_inside = FALSE; + + if (clickable_image->details->prelight) { + nautilus_labeled_image_set_pixbuf (NAUTILUS_LABELED_IMAGE (clickable_image), + clickable_image->details->pixbuf); + } gtk_widget_set_state (GTK_WIDGET (clickable_image), GTK_STATE_NORMAL); - gtk_widget_queue_draw (GTK_WIDGET (clickable_image)); gtk_signal_emit (GTK_OBJECT (clickable_image), clickable_image_signals[LEAVE], @@ -275,7 +288,7 @@ label_handle_motion (NautilusClickableImage *clickable_image, ArtIRect bounds; g_return_if_fail (NAUTILUS_IS_CLICKABLE_IMAGE (clickable_image)); - + bounds = nautilus_gtk_widget_get_bounds (GTK_WIDGET (clickable_image)); if (nautilus_art_irect_contains_point (&bounds, x, y)) { @@ -313,16 +326,54 @@ label_handle_button_release (NautilusClickableImage *clickable_image) clickable_image); } +static void +adjust_coordinates_for_window (GdkWindow *widget_window, + GdkWindow *event_window, + int *x, + int *y) +{ + GdkWindow *window; + int wx, wy; + + /* Viewports place their children in a different GdkWindow + * than their own widget window (perhaps other containers do + * this to). Therefore if the event we got is on a different + * GdkWindow than our own, adjust the coordinates. + */ + + window = widget_window; + + while (window != event_window && window != NULL) { + gdk_window_get_position (window, + &wx, + &wy); + + *x -= wx; + *y -= wy; + + window = gdk_window_get_parent (window); + } +} + static int ancestor_enter_notify_event (GtkWidget *widget, GdkEventCrossing *event, gpointer event_data) { + int x, y; + g_return_val_if_fail (GTK_IS_WIDGET (widget), FALSE); g_return_val_if_fail (NAUTILUS_IS_CLICKABLE_IMAGE (event_data), FALSE); g_return_val_if_fail (event != NULL, FALSE); - label_handle_motion (NAUTILUS_CLICKABLE_IMAGE (event_data), event->x, event->y); + x = event->x; + y = event->y; + + adjust_coordinates_for_window (GTK_WIDGET (event_data)->window, + widget->window, + &x, &y); + + label_handle_motion (NAUTILUS_CLICKABLE_IMAGE (event_data), x, y); return FALSE; } @@ -332,11 +383,20 @@ ancestor_leave_notify_event (GtkWidget *widget, GdkEventCrossing *event, gpointer event_data) { + int x, y; + g_return_val_if_fail (GTK_IS_WIDGET (widget), FALSE); g_return_val_if_fail (NAUTILUS_IS_CLICKABLE_IMAGE (event_data), FALSE); g_return_val_if_fail (event != NULL, FALSE); - label_handle_motion (NAUTILUS_CLICKABLE_IMAGE (event_data), event->x, event->y); + x = event->x; + y = event->y; + + adjust_coordinates_for_window (GTK_WIDGET (event_data)->window, + widget->window, + &x, &y); + + label_handle_motion (NAUTILUS_CLICKABLE_IMAGE (event_data), x, y); return FALSE; } @@ -346,11 +406,20 @@ ancestor_motion_notify_event (GtkWidget *widget, GdkEventMotion *event, gpointer event_data) { + int x, y; + g_return_val_if_fail (GTK_IS_WIDGET (widget), FALSE); g_return_val_if_fail (NAUTILUS_IS_CLICKABLE_IMAGE (event_data), FALSE); g_return_val_if_fail (event != NULL, FALSE); - label_handle_motion (NAUTILUS_CLICKABLE_IMAGE (event_data), event->x, event->y); + x = event->x; + y = event->y; + + adjust_coordinates_for_window (GTK_WIDGET (event_data)->window, + widget->window, + &x, &y); + + label_handle_motion (NAUTILUS_CLICKABLE_IMAGE (event_data), x, y); return FALSE; } @@ -416,6 +485,16 @@ nautilus_clickable_image_expose_event (GtkWidget *widget, return NAUTILUS_CALL_PARENT_CLASS (GTK_WIDGET_CLASS, expose_event, (widget, event)); } +static void +nautilus_clickable_image_set_up_pixbufs (NautilusClickableImage *clickable_image) +{ + clickable_image->details->pixbuf = + nautilus_labeled_image_get_pixbuf (NAUTILUS_LABELED_IMAGE (clickable_image)); + + clickable_image->details->prelight_pixbuf = nautilus_create_spotlight_pixbuf + (clickable_image->details->pixbuf); +} + /* Public NautilusClickableImage methods */ /** @@ -529,4 +608,45 @@ nautilus_clickable_image_new_solid (const char *text, return GTK_WIDGET (clickable_image); } +/** + * nautilus_clickable_image_new: + * + * @clickable_image: A NautilusClickableImage + * @prelight: a gboolean specifying wether to prelight + * + * Enable or disable auto-prelight mode. You can't change the pixbuf + * while prelight mode is on; as a workaround, you can turn prelight + * off, change the pixbuf, and then turn it back on. + * + */ + +void +nautilus_clickable_image_set_prelight (NautilusClickableImage *clickable_image, + gboolean prelight) +{ + /* FIXME: you can't change the pixbuf with prelight mode on */ + + if (!clickable_image->details->prelight && prelight) { + nautilus_clickable_image_set_up_pixbufs (clickable_image); + clickable_image->details->prelight = TRUE; + if (clickable_image->details->pointer_inside) { + nautilus_labeled_image_set_pixbuf + (NAUTILUS_LABELED_IMAGE (clickable_image), + clickable_image->details->prelight_pixbuf); + } + } + + if (clickable_image->details->prelight && !prelight) { + if (clickable_image->details->pointer_inside) { + nautilus_labeled_image_set_pixbuf + (NAUTILUS_LABELED_IMAGE (clickable_image), + clickable_image->details->pixbuf); + } + gdk_pixbuf_unref (clickable_image->details->pixbuf); + clickable_image->details->pixbuf = NULL; + gdk_pixbuf_unref (clickable_image->details->prelight_pixbuf); + clickable_image->details->prelight_pixbuf = NULL; + clickable_image->details->prelight = FALSE; + } +} diff --git a/libnautilus-extensions/nautilus-clickable-image.h b/libnautilus-extensions/nautilus-clickable-image.h index f4c49efc2..7f1eb458d 100644 --- a/libnautilus-extensions/nautilus-clickable-image.h +++ b/libnautilus-extensions/nautilus-clickable-image.h @@ -89,6 +89,9 @@ GtkWidget *nautilus_clickable_image_new_solid (const char *text, guint32 background_color, GdkPixbuf *tile_pixbuf); +void nautilus_clickable_image_set_prelight (NautilusClickableImage *clickable_image, + gboolean prelight); + END_GNOME_DECLS #endif /* NAUTILUS_CLICKABLE_IMAGE_H */ diff --git a/libnautilus-private/nautilus-clickable-image.c b/libnautilus-private/nautilus-clickable-image.c index b5330e44c..705b63a63 100644 --- a/libnautilus-private/nautilus-clickable-image.c +++ b/libnautilus-private/nautilus-clickable-image.c @@ -29,6 +29,7 @@ #include "nautilus-gtk-macros.h" #include "nautilus-gtk-extensions.h" #include "nautilus-art-gtk-extensions.h" +#include "nautilus-graphic-effects.h" #include <gtk/gtkmain.h> @@ -55,6 +56,10 @@ static guint clickable_image_signals[LAST_SIGNAL] = { 0 }; struct _NautilusClickableImageDetails { gboolean pointer_inside; + gboolean prelight; + + GdkPixbuf *pixbuf; + GdkPixbuf *prelight_pixbuf; }; /* GtkObjectClass methods */ @@ -241,10 +246,14 @@ label_enter (NautilusClickableImage *clickable_image) { g_return_if_fail (NAUTILUS_IS_CLICKABLE_IMAGE (clickable_image)); - clickable_image->details->pointer_inside = TRUE; + clickable_image->details->pointer_inside = TRUE; + + if (clickable_image->details->prelight) { + nautilus_labeled_image_set_pixbuf (NAUTILUS_LABELED_IMAGE (clickable_image), + clickable_image->details->prelight_pixbuf); + } gtk_widget_set_state (GTK_WIDGET (clickable_image), GTK_STATE_PRELIGHT); - gtk_widget_queue_draw (GTK_WIDGET (clickable_image)); gtk_signal_emit (GTK_OBJECT (clickable_image), clickable_image_signals[ENTER], @@ -257,10 +266,14 @@ label_leave (NautilusClickableImage *clickable_image) { g_return_if_fail (NAUTILUS_IS_CLICKABLE_IMAGE (clickable_image)); - clickable_image->details->pointer_inside = FALSE; + clickable_image->details->pointer_inside = FALSE; + + if (clickable_image->details->prelight) { + nautilus_labeled_image_set_pixbuf (NAUTILUS_LABELED_IMAGE (clickable_image), + clickable_image->details->pixbuf); + } gtk_widget_set_state (GTK_WIDGET (clickable_image), GTK_STATE_NORMAL); - gtk_widget_queue_draw (GTK_WIDGET (clickable_image)); gtk_signal_emit (GTK_OBJECT (clickable_image), clickable_image_signals[LEAVE], @@ -275,7 +288,7 @@ label_handle_motion (NautilusClickableImage *clickable_image, ArtIRect bounds; g_return_if_fail (NAUTILUS_IS_CLICKABLE_IMAGE (clickable_image)); - + bounds = nautilus_gtk_widget_get_bounds (GTK_WIDGET (clickable_image)); if (nautilus_art_irect_contains_point (&bounds, x, y)) { @@ -313,16 +326,54 @@ label_handle_button_release (NautilusClickableImage *clickable_image) clickable_image); } +static void +adjust_coordinates_for_window (GdkWindow *widget_window, + GdkWindow *event_window, + int *x, + int *y) +{ + GdkWindow *window; + int wx, wy; + + /* Viewports place their children in a different GdkWindow + * than their own widget window (perhaps other containers do + * this to). Therefore if the event we got is on a different + * GdkWindow than our own, adjust the coordinates. + */ + + window = widget_window; + + while (window != event_window && window != NULL) { + gdk_window_get_position (window, + &wx, + &wy); + + *x -= wx; + *y -= wy; + + window = gdk_window_get_parent (window); + } +} + static int ancestor_enter_notify_event (GtkWidget *widget, GdkEventCrossing *event, gpointer event_data) { + int x, y; + g_return_val_if_fail (GTK_IS_WIDGET (widget), FALSE); g_return_val_if_fail (NAUTILUS_IS_CLICKABLE_IMAGE (event_data), FALSE); g_return_val_if_fail (event != NULL, FALSE); - label_handle_motion (NAUTILUS_CLICKABLE_IMAGE (event_data), event->x, event->y); + x = event->x; + y = event->y; + + adjust_coordinates_for_window (GTK_WIDGET (event_data)->window, + widget->window, + &x, &y); + + label_handle_motion (NAUTILUS_CLICKABLE_IMAGE (event_data), x, y); return FALSE; } @@ -332,11 +383,20 @@ ancestor_leave_notify_event (GtkWidget *widget, GdkEventCrossing *event, gpointer event_data) { + int x, y; + g_return_val_if_fail (GTK_IS_WIDGET (widget), FALSE); g_return_val_if_fail (NAUTILUS_IS_CLICKABLE_IMAGE (event_data), FALSE); g_return_val_if_fail (event != NULL, FALSE); - label_handle_motion (NAUTILUS_CLICKABLE_IMAGE (event_data), event->x, event->y); + x = event->x; + y = event->y; + + adjust_coordinates_for_window (GTK_WIDGET (event_data)->window, + widget->window, + &x, &y); + + label_handle_motion (NAUTILUS_CLICKABLE_IMAGE (event_data), x, y); return FALSE; } @@ -346,11 +406,20 @@ ancestor_motion_notify_event (GtkWidget *widget, GdkEventMotion *event, gpointer event_data) { + int x, y; + g_return_val_if_fail (GTK_IS_WIDGET (widget), FALSE); g_return_val_if_fail (NAUTILUS_IS_CLICKABLE_IMAGE (event_data), FALSE); g_return_val_if_fail (event != NULL, FALSE); - label_handle_motion (NAUTILUS_CLICKABLE_IMAGE (event_data), event->x, event->y); + x = event->x; + y = event->y; + + adjust_coordinates_for_window (GTK_WIDGET (event_data)->window, + widget->window, + &x, &y); + + label_handle_motion (NAUTILUS_CLICKABLE_IMAGE (event_data), x, y); return FALSE; } @@ -416,6 +485,16 @@ nautilus_clickable_image_expose_event (GtkWidget *widget, return NAUTILUS_CALL_PARENT_CLASS (GTK_WIDGET_CLASS, expose_event, (widget, event)); } +static void +nautilus_clickable_image_set_up_pixbufs (NautilusClickableImage *clickable_image) +{ + clickable_image->details->pixbuf = + nautilus_labeled_image_get_pixbuf (NAUTILUS_LABELED_IMAGE (clickable_image)); + + clickable_image->details->prelight_pixbuf = nautilus_create_spotlight_pixbuf + (clickable_image->details->pixbuf); +} + /* Public NautilusClickableImage methods */ /** @@ -529,4 +608,45 @@ nautilus_clickable_image_new_solid (const char *text, return GTK_WIDGET (clickable_image); } +/** + * nautilus_clickable_image_new: + * + * @clickable_image: A NautilusClickableImage + * @prelight: a gboolean specifying wether to prelight + * + * Enable or disable auto-prelight mode. You can't change the pixbuf + * while prelight mode is on; as a workaround, you can turn prelight + * off, change the pixbuf, and then turn it back on. + * + */ + +void +nautilus_clickable_image_set_prelight (NautilusClickableImage *clickable_image, + gboolean prelight) +{ + /* FIXME: you can't change the pixbuf with prelight mode on */ + + if (!clickable_image->details->prelight && prelight) { + nautilus_clickable_image_set_up_pixbufs (clickable_image); + clickable_image->details->prelight = TRUE; + if (clickable_image->details->pointer_inside) { + nautilus_labeled_image_set_pixbuf + (NAUTILUS_LABELED_IMAGE (clickable_image), + clickable_image->details->prelight_pixbuf); + } + } + + if (clickable_image->details->prelight && !prelight) { + if (clickable_image->details->pointer_inside) { + nautilus_labeled_image_set_pixbuf + (NAUTILUS_LABELED_IMAGE (clickable_image), + clickable_image->details->pixbuf); + } + gdk_pixbuf_unref (clickable_image->details->pixbuf); + clickable_image->details->pixbuf = NULL; + gdk_pixbuf_unref (clickable_image->details->prelight_pixbuf); + clickable_image->details->prelight_pixbuf = NULL; + clickable_image->details->prelight = FALSE; + } +} diff --git a/libnautilus-private/nautilus-clickable-image.h b/libnautilus-private/nautilus-clickable-image.h index f4c49efc2..7f1eb458d 100644 --- a/libnautilus-private/nautilus-clickable-image.h +++ b/libnautilus-private/nautilus-clickable-image.h @@ -89,6 +89,9 @@ GtkWidget *nautilus_clickable_image_new_solid (const char *text, guint32 background_color, GdkPixbuf *tile_pixbuf); +void nautilus_clickable_image_set_prelight (NautilusClickableImage *clickable_image, + gboolean prelight); + END_GNOME_DECLS #endif /* NAUTILUS_CLICKABLE_IMAGE_H */ diff --git a/libnautilus/nautilus-view-standard-main.c b/libnautilus/nautilus-view-standard-main.c index 424d46a42..88625723f 100644 --- a/libnautilus/nautilus-view-standard-main.c +++ b/libnautilus/nautilus-view-standard-main.c @@ -120,6 +120,7 @@ nautilus_view_standard_main_multi (const char *executable_name, gnome_init (executable_name, version, argc, argv); gdk_rgb_init (); + g_thread_init (NULL); gnome_vfs_init (); bonobo_init (orb, CORBA_OBJECT_NIL, CORBA_OBJECT_NIL); |