summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMaciej Stachowiak <mstachow@src.gnome.org>2001-02-19 20:46:26 +0000
committerMaciej Stachowiak <mstachow@src.gnome.org>2001-02-19 20:46:26 +0000
commit9efcca800087241ed5c296789ff14a0c8c24cd02 (patch)
tree60bdcfc34c636895690b7541e5c462c7f920b965
parent514928fdd24e7ee6fd39678a030dd6f43dbb1a10 (diff)
downloadnautilus-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--ChangeLog32
-rw-r--r--libnautilus-extensions/nautilus-clickable-image.c136
-rw-r--r--libnautilus-extensions/nautilus-clickable-image.h3
-rw-r--r--libnautilus-private/nautilus-clickable-image.c136
-rw-r--r--libnautilus-private/nautilus-clickable-image.h3
-rw-r--r--libnautilus/nautilus-view-standard-main.c1
6 files changed, 295 insertions, 16 deletions
diff --git a/ChangeLog b/ChangeLog
index bd172abc4..f2d01ab45 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -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);