diff options
author | Andy Hertzfeld <andy@src.gnome.org> | 2001-04-12 07:26:37 +0000 |
---|---|---|
committer | Andy Hertzfeld <andy@src.gnome.org> | 2001-04-12 07:26:37 +0000 |
commit | c60a70bf37f92241e1d6c5ac8884aca47c4ebe86 (patch) | |
tree | d5b8f12b66efaf00512863a82236aa19e7d4d397 | |
parent | 466f3709b587ac71310449bf073ee77af69897a4 (diff) | |
download | nautilus-c60a70bf37f92241e1d6c5ac8884aca47c4ebe86.tar.gz |
keep showing an annotation as long as the mouse remains in the emblem or
keep showing an annotation as long as the mouse remains in
the emblem or in the annotation itself.
Also, consider the arrow shape when hit-testing
* libnautilus-extensions/nautilus-canvas-note-item.c:
(nautilus_canvas_note_item_class_init),
(nautilus_canvas_note_item_event), (get_arrow_half_width),
(nautilus_canvas_note_item_point),
(nautilus_canvas_note_item_set_owner),
(nautilus_canvas_note_item_update):
* libnautilus-extensions/nautilus-canvas-note-item.h:
* libnautilus-extensions/nautilus-icon-canvas-item.c:
(create_annotation), (nautilus_icon_canvas_item_set_note_state),
(nautilus_icon_canvas_item_event):
* libnautilus-extensions/nautilus-icon-canvas-item.h:
-rw-r--r-- | ChangeLog | 20 | ||||
-rw-r--r-- | libnautilus-extensions/nautilus-canvas-note-item.c | 76 | ||||
-rw-r--r-- | libnautilus-extensions/nautilus-canvas-note-item.h | 7 | ||||
-rw-r--r-- | libnautilus-extensions/nautilus-icon-canvas-item.c | 21 | ||||
-rw-r--r-- | libnautilus-extensions/nautilus-icon-canvas-item.h | 2 | ||||
-rw-r--r-- | libnautilus-private/nautilus-canvas-note-item.c | 76 | ||||
-rw-r--r-- | libnautilus-private/nautilus-canvas-note-item.h | 7 | ||||
-rw-r--r-- | libnautilus-private/nautilus-icon-canvas-item.c | 21 | ||||
-rw-r--r-- | libnautilus-private/nautilus-icon-canvas-item.h | 2 |
9 files changed, 212 insertions, 20 deletions
@@ -1,3 +1,23 @@ +2001-04-12 Andy Hertzfeld <andy@eazel.com> + + keep showing an annotation as long as the mouse remains in + the emblem or in the annotation itself. + + Also, consider the arrow shape when hit-testing + + * libnautilus-extensions/nautilus-canvas-note-item.c: + (nautilus_canvas_note_item_class_init), + (nautilus_canvas_note_item_event), (get_arrow_half_width), + (nautilus_canvas_note_item_point), + (nautilus_canvas_note_item_set_owner), + (nautilus_canvas_note_item_update): + + * libnautilus-extensions/nautilus-canvas-note-item.h: + * libnautilus-extensions/nautilus-icon-canvas-item.c: + (create_annotation), (nautilus_icon_canvas_item_set_note_state), + (nautilus_icon_canvas_item_event): + * libnautilus-extensions/nautilus-icon-canvas-item.h: + 2001-04-11 Andy Hertzfeld <andy@eazel.com> groundwork for supporting multiple annotations for file by diff --git a/libnautilus-extensions/nautilus-canvas-note-item.c b/libnautilus-extensions/nautilus-canvas-note-item.c index 6f3607090..d179d9de4 100644 --- a/libnautilus-extensions/nautilus-canvas-note-item.c +++ b/libnautilus-extensions/nautilus-canvas-note-item.c @@ -42,6 +42,8 @@ #include "nautilus-annotation.h" #include "nautilus-canvas-note-item.h" #include "nautilus-font-factory.h" +#include "nautilus-icon-canvas-item.h" + #include <eel/eel-gdk-extensions.h> #include <eel/eel-gdk-pixbuf-extensions.h> #include <eel/eel-gnome-extensions.h> @@ -92,6 +94,8 @@ static void nautilus_canvas_note_item_translate (GnomeCanvasItem *item, double static void nautilus_canvas_note_item_bounds (GnomeCanvasItem *item, double *x1, double *y1, double *x2, double *y2); static void nautilus_canvas_note_item_draw (GnomeCanvasItem *item, GdkDrawable *drawable, int x, int y, int width, int height); +static int nautilus_canvas_note_item_event (GnomeCanvasItem *item, GdkEvent *event); + static void nautilus_canvas_note_item_render (GnomeCanvasItem *item, GnomeCanvasBuf *buf); static void nautilus_canvas_note_item_update (GnomeCanvasItem *item, double *affine, ArtSVP *clip_path, int flags); static double nautilus_canvas_note_item_point (GnomeCanvasItem *item, double x, double y, int cx, int cy, GnomeCanvasItem **actual_item); @@ -162,6 +166,7 @@ nautilus_canvas_note_item_class_init (NautilusCanvasNoteItemClass *class) item_class->point = nautilus_canvas_note_item_point; item_class->update = nautilus_canvas_note_item_update; item_class->render = nautilus_canvas_note_item_render; + item_class->event = nautilus_canvas_note_item_event; } static void @@ -821,14 +826,55 @@ nautilus_canvas_note_item_draw (GnomeCanvasItem *item, GdkDrawable *drawable, in y2 - y1); } +/* handle events, to put away the annotation when necessary */ +static int +nautilus_canvas_note_item_event (GnomeCanvasItem *item, GdkEvent *event) +{ + NautilusCanvasNoteItem *note_item; + GnomeCanvasItem *mouse_over_item; + int x, y; + double world_x, world_y; + + switch (event->type) { + + case GDK_LEAVE_NOTIFY: + /* set the owner's note state to empty if we're leaving the note item + * and not returning to the owner + */ + gdk_window_get_pointer (GTK_WIDGET (item->canvas)->window, &x, &y, NULL); + gnome_canvas_window_to_world (item->canvas, x, y, &world_x, &world_y); + mouse_over_item = gnome_canvas_get_item_at (item->canvas, world_x, world_y); + + note_item = NAUTILUS_CANVAS_NOTE_ITEM (item); + if (mouse_over_item != note_item->owning_item) { + nautilus_icon_canvas_item_set_note_state (NAUTILUS_ICON_CANVAS_ITEM (note_item->owning_item), 0); + } + return TRUE; + + default: + /* Don't eat up other events; icon container might use them. */ + return FALSE; + } +} + +static double +get_arrow_half_width (double x0, double x1) +{ + double arrow_half_width; + arrow_half_width = (x1 - x0) / 16; + return CLAMP (arrow_half_width, MIN_ARROW_HALF_WIDTH, MAX_ARROW_HALF_WIDTH); + +} + static double nautilus_canvas_note_item_point (GnomeCanvasItem *item, double x, double y, int cx, int cy, GnomeCanvasItem **actual_item) { NautilusCanvasNoteItem *note_item; double x1, y1, x2, y2; - double hwidth; + double hwidth, old_top; double dx, dy; - + double arrow_half_width, midpoint; + note_item = NAUTILUS_CANVAS_NOTE_ITEM (item); *actual_item = item; @@ -850,7 +896,21 @@ nautilus_canvas_note_item_point (GnomeCanvasItem *item, double x, double y, int x2 += hwidth; y2 += hwidth; - /* Is point inside rectangle (which can be hollow if it has no fill set)? */ + /* handle the arrow if we're in aa mode */ + if (item->canvas->aa) { + old_top = y1; + y1 += ARROW_HEIGHT; + + if (y >= old_top && y <= y1) { + arrow_half_width = get_arrow_half_width (x1, x2); + midpoint = (x1 + x2) / 2; + if (x >= (midpoint - arrow_half_width) && x <= (midpoint + arrow_half_width)) { + return 0.0; + } + } + } + + /* Is point inside rectangle? */ if ((x >= x1) && (y >= y1) && (x <= x2) && (y <= y2)) { return 0.0; @@ -874,6 +934,13 @@ nautilus_canvas_note_item_point (GnomeCanvasItem *item, double x, double y, int return sqrt (dx * dx + dy * dy); } +void +nautilus_canvas_note_item_set_owner (NautilusCanvasNoteItem *note_item, + GnomeCanvasItem *owner) +{ + note_item->owning_item = owner; +} + static void nautilus_canvas_note_item_update (GnomeCanvasItem *item, double affine[6], ArtSVP *clip_path, gint flags) @@ -900,9 +967,8 @@ nautilus_canvas_note_item_update (GnomeCanvasItem *item, double affine[6], ArtSV round_off_amount = item->canvas->pixels_per_unit / 2; gnome_canvas_item_reset_bounds (item); + arrow_half_width = get_arrow_half_width (x0, x1); midpoint = (x1 + x0) / 2; - arrow_half_width = (x1 - x0) / 16; - arrow_half_width = CLAMP (arrow_half_width, MIN_ARROW_HALF_WIDTH, MAX_ARROW_HALF_WIDTH); vpath[0].code = ART_MOVETO; vpath[0].x = x0 - round_off_amount; diff --git a/libnautilus-extensions/nautilus-canvas-note-item.h b/libnautilus-extensions/nautilus-canvas-note-item.h index 3c763c3df..70347425e 100644 --- a/libnautilus-extensions/nautilus-canvas-note-item.h +++ b/libnautilus-extensions/nautilus-canvas-note-item.h @@ -66,6 +66,8 @@ struct _NautilusCanvasNoteItem { GdkGC *fill_gc; /* GC for filling */ GdkGC *outline_gc; /* GC for outline */ + GnomeCanvasItem *owning_item; /* canvas item owning this annotation */ + /* text message */ char *note_text; /* text for annotation */ @@ -82,8 +84,9 @@ struct _NautilusCanvasNoteItemClass { }; /* Standard Gtk function */ -GtkType nautilus_canvas_note_item_get_type (void); - +GtkType nautilus_canvas_note_item_get_type (void); +void nautilus_canvas_note_item_set_owner (NautilusCanvasNoteItem *note_item, + GnomeCanvasItem *owner); END_GNOME_DECLS diff --git a/libnautilus-extensions/nautilus-icon-canvas-item.c b/libnautilus-extensions/nautilus-icon-canvas-item.c index 58b729a95..83c4a4317 100644 --- a/libnautilus-extensions/nautilus-icon-canvas-item.c +++ b/libnautilus-extensions/nautilus-icon-canvas-item.c @@ -1899,6 +1899,8 @@ create_annotation (NautilusIconCanvasItem *icon_item, int emblem_index) g_free (note_text); + nautilus_canvas_note_item_set_owner (NAUTILUS_CANVAS_NOTE_ITEM (icon_item->details->annotation), item); + /* reposition the item now that it's had a chance to be properly sized */ if (canvas->aa) { get_emblem_rectangle (icon_item, emblem_index, &emblem_rect); @@ -1944,10 +1946,10 @@ create_annotation_timeout_callback (gpointer callback_data) } /* manage showing and hiding annotations, based on mouse-over the passed-in emblem */ -static void +void nautilus_icon_canvas_item_set_note_state (NautilusIconCanvasItem *icon_item, int new_state) { - /* nothing to do if nothing changed */ + /* nothing more to do if nothing changed */ if (new_state == icon_item->details->note_state) { return; } @@ -1982,11 +1984,14 @@ static int nautilus_icon_canvas_item_event (GnomeCanvasItem *item, GdkEvent *event) { NautilusIconCanvasItem *icon_item; + GnomeCanvasItem *mouse_over_item; GdkEventMotion *motion_event; ArtIRect hit_rect; ArtDRect world_rect; HitType hit_type; int hit_index, emblem_state; + int x, y; + double world_x, world_y; icon_item = NAUTILUS_ICON_CANVAS_ITEM (item); @@ -2035,7 +2040,17 @@ nautilus_icon_canvas_item_event (GnomeCanvasItem *item, GdkEvent *event) icon_item->details->is_active = 0; icon_item->details->is_highlighted_for_drop = FALSE; - nautilus_icon_canvas_item_set_note_state (icon_item, 0); + /* if the item has an annotation and the mouse is in it + * don't reset the note_state + */ + gdk_window_get_pointer (GTK_WIDGET (item->canvas)->window, &x, &y, NULL); + gnome_canvas_window_to_world (item->canvas, x, y, &world_x, &world_y); + mouse_over_item = gnome_canvas_get_item_at (item->canvas, world_x, world_y); + + if (mouse_over_item == NULL || mouse_over_item != icon_item->details->annotation) { + nautilus_icon_canvas_item_set_note_state (icon_item, 0); + } + gnome_canvas_item_request_update (item); } return TRUE; diff --git a/libnautilus-extensions/nautilus-icon-canvas-item.h b/libnautilus-extensions/nautilus-icon-canvas-item.h index 2f9f90a34..b56c9aefd 100644 --- a/libnautilus-extensions/nautilus-icon-canvas-item.h +++ b/libnautilus-extensions/nautilus-icon-canvas-item.h @@ -107,6 +107,8 @@ void nautilus_icon_canvas_item_invalidate_label_size (NautilusIconCanvasI void nautilus_icon_canvas_item_get_icon_rectangle (NautilusIconCanvasItem *item, ArtDRect *world_rectangle); void nautilus_icon_canvas_item_update_bounds (NautilusIconCanvasItem *item); +void nautilus_icon_canvas_item_set_note_state (NautilusIconCanvasItem *icon_item, int new_state); + void nautilus_icon_canvas_item_set_smooth_font (NautilusIconCanvasItem *item, EelScalableFont *font); void nautilus_icon_canvas_item_set_smooth_font_size (NautilusIconCanvasItem *item, diff --git a/libnautilus-private/nautilus-canvas-note-item.c b/libnautilus-private/nautilus-canvas-note-item.c index 6f3607090..d179d9de4 100644 --- a/libnautilus-private/nautilus-canvas-note-item.c +++ b/libnautilus-private/nautilus-canvas-note-item.c @@ -42,6 +42,8 @@ #include "nautilus-annotation.h" #include "nautilus-canvas-note-item.h" #include "nautilus-font-factory.h" +#include "nautilus-icon-canvas-item.h" + #include <eel/eel-gdk-extensions.h> #include <eel/eel-gdk-pixbuf-extensions.h> #include <eel/eel-gnome-extensions.h> @@ -92,6 +94,8 @@ static void nautilus_canvas_note_item_translate (GnomeCanvasItem *item, double static void nautilus_canvas_note_item_bounds (GnomeCanvasItem *item, double *x1, double *y1, double *x2, double *y2); static void nautilus_canvas_note_item_draw (GnomeCanvasItem *item, GdkDrawable *drawable, int x, int y, int width, int height); +static int nautilus_canvas_note_item_event (GnomeCanvasItem *item, GdkEvent *event); + static void nautilus_canvas_note_item_render (GnomeCanvasItem *item, GnomeCanvasBuf *buf); static void nautilus_canvas_note_item_update (GnomeCanvasItem *item, double *affine, ArtSVP *clip_path, int flags); static double nautilus_canvas_note_item_point (GnomeCanvasItem *item, double x, double y, int cx, int cy, GnomeCanvasItem **actual_item); @@ -162,6 +166,7 @@ nautilus_canvas_note_item_class_init (NautilusCanvasNoteItemClass *class) item_class->point = nautilus_canvas_note_item_point; item_class->update = nautilus_canvas_note_item_update; item_class->render = nautilus_canvas_note_item_render; + item_class->event = nautilus_canvas_note_item_event; } static void @@ -821,14 +826,55 @@ nautilus_canvas_note_item_draw (GnomeCanvasItem *item, GdkDrawable *drawable, in y2 - y1); } +/* handle events, to put away the annotation when necessary */ +static int +nautilus_canvas_note_item_event (GnomeCanvasItem *item, GdkEvent *event) +{ + NautilusCanvasNoteItem *note_item; + GnomeCanvasItem *mouse_over_item; + int x, y; + double world_x, world_y; + + switch (event->type) { + + case GDK_LEAVE_NOTIFY: + /* set the owner's note state to empty if we're leaving the note item + * and not returning to the owner + */ + gdk_window_get_pointer (GTK_WIDGET (item->canvas)->window, &x, &y, NULL); + gnome_canvas_window_to_world (item->canvas, x, y, &world_x, &world_y); + mouse_over_item = gnome_canvas_get_item_at (item->canvas, world_x, world_y); + + note_item = NAUTILUS_CANVAS_NOTE_ITEM (item); + if (mouse_over_item != note_item->owning_item) { + nautilus_icon_canvas_item_set_note_state (NAUTILUS_ICON_CANVAS_ITEM (note_item->owning_item), 0); + } + return TRUE; + + default: + /* Don't eat up other events; icon container might use them. */ + return FALSE; + } +} + +static double +get_arrow_half_width (double x0, double x1) +{ + double arrow_half_width; + arrow_half_width = (x1 - x0) / 16; + return CLAMP (arrow_half_width, MIN_ARROW_HALF_WIDTH, MAX_ARROW_HALF_WIDTH); + +} + static double nautilus_canvas_note_item_point (GnomeCanvasItem *item, double x, double y, int cx, int cy, GnomeCanvasItem **actual_item) { NautilusCanvasNoteItem *note_item; double x1, y1, x2, y2; - double hwidth; + double hwidth, old_top; double dx, dy; - + double arrow_half_width, midpoint; + note_item = NAUTILUS_CANVAS_NOTE_ITEM (item); *actual_item = item; @@ -850,7 +896,21 @@ nautilus_canvas_note_item_point (GnomeCanvasItem *item, double x, double y, int x2 += hwidth; y2 += hwidth; - /* Is point inside rectangle (which can be hollow if it has no fill set)? */ + /* handle the arrow if we're in aa mode */ + if (item->canvas->aa) { + old_top = y1; + y1 += ARROW_HEIGHT; + + if (y >= old_top && y <= y1) { + arrow_half_width = get_arrow_half_width (x1, x2); + midpoint = (x1 + x2) / 2; + if (x >= (midpoint - arrow_half_width) && x <= (midpoint + arrow_half_width)) { + return 0.0; + } + } + } + + /* Is point inside rectangle? */ if ((x >= x1) && (y >= y1) && (x <= x2) && (y <= y2)) { return 0.0; @@ -874,6 +934,13 @@ nautilus_canvas_note_item_point (GnomeCanvasItem *item, double x, double y, int return sqrt (dx * dx + dy * dy); } +void +nautilus_canvas_note_item_set_owner (NautilusCanvasNoteItem *note_item, + GnomeCanvasItem *owner) +{ + note_item->owning_item = owner; +} + static void nautilus_canvas_note_item_update (GnomeCanvasItem *item, double affine[6], ArtSVP *clip_path, gint flags) @@ -900,9 +967,8 @@ nautilus_canvas_note_item_update (GnomeCanvasItem *item, double affine[6], ArtSV round_off_amount = item->canvas->pixels_per_unit / 2; gnome_canvas_item_reset_bounds (item); + arrow_half_width = get_arrow_half_width (x0, x1); midpoint = (x1 + x0) / 2; - arrow_half_width = (x1 - x0) / 16; - arrow_half_width = CLAMP (arrow_half_width, MIN_ARROW_HALF_WIDTH, MAX_ARROW_HALF_WIDTH); vpath[0].code = ART_MOVETO; vpath[0].x = x0 - round_off_amount; diff --git a/libnautilus-private/nautilus-canvas-note-item.h b/libnautilus-private/nautilus-canvas-note-item.h index 3c763c3df..70347425e 100644 --- a/libnautilus-private/nautilus-canvas-note-item.h +++ b/libnautilus-private/nautilus-canvas-note-item.h @@ -66,6 +66,8 @@ struct _NautilusCanvasNoteItem { GdkGC *fill_gc; /* GC for filling */ GdkGC *outline_gc; /* GC for outline */ + GnomeCanvasItem *owning_item; /* canvas item owning this annotation */ + /* text message */ char *note_text; /* text for annotation */ @@ -82,8 +84,9 @@ struct _NautilusCanvasNoteItemClass { }; /* Standard Gtk function */ -GtkType nautilus_canvas_note_item_get_type (void); - +GtkType nautilus_canvas_note_item_get_type (void); +void nautilus_canvas_note_item_set_owner (NautilusCanvasNoteItem *note_item, + GnomeCanvasItem *owner); END_GNOME_DECLS diff --git a/libnautilus-private/nautilus-icon-canvas-item.c b/libnautilus-private/nautilus-icon-canvas-item.c index 58b729a95..83c4a4317 100644 --- a/libnautilus-private/nautilus-icon-canvas-item.c +++ b/libnautilus-private/nautilus-icon-canvas-item.c @@ -1899,6 +1899,8 @@ create_annotation (NautilusIconCanvasItem *icon_item, int emblem_index) g_free (note_text); + nautilus_canvas_note_item_set_owner (NAUTILUS_CANVAS_NOTE_ITEM (icon_item->details->annotation), item); + /* reposition the item now that it's had a chance to be properly sized */ if (canvas->aa) { get_emblem_rectangle (icon_item, emblem_index, &emblem_rect); @@ -1944,10 +1946,10 @@ create_annotation_timeout_callback (gpointer callback_data) } /* manage showing and hiding annotations, based on mouse-over the passed-in emblem */ -static void +void nautilus_icon_canvas_item_set_note_state (NautilusIconCanvasItem *icon_item, int new_state) { - /* nothing to do if nothing changed */ + /* nothing more to do if nothing changed */ if (new_state == icon_item->details->note_state) { return; } @@ -1982,11 +1984,14 @@ static int nautilus_icon_canvas_item_event (GnomeCanvasItem *item, GdkEvent *event) { NautilusIconCanvasItem *icon_item; + GnomeCanvasItem *mouse_over_item; GdkEventMotion *motion_event; ArtIRect hit_rect; ArtDRect world_rect; HitType hit_type; int hit_index, emblem_state; + int x, y; + double world_x, world_y; icon_item = NAUTILUS_ICON_CANVAS_ITEM (item); @@ -2035,7 +2040,17 @@ nautilus_icon_canvas_item_event (GnomeCanvasItem *item, GdkEvent *event) icon_item->details->is_active = 0; icon_item->details->is_highlighted_for_drop = FALSE; - nautilus_icon_canvas_item_set_note_state (icon_item, 0); + /* if the item has an annotation and the mouse is in it + * don't reset the note_state + */ + gdk_window_get_pointer (GTK_WIDGET (item->canvas)->window, &x, &y, NULL); + gnome_canvas_window_to_world (item->canvas, x, y, &world_x, &world_y); + mouse_over_item = gnome_canvas_get_item_at (item->canvas, world_x, world_y); + + if (mouse_over_item == NULL || mouse_over_item != icon_item->details->annotation) { + nautilus_icon_canvas_item_set_note_state (icon_item, 0); + } + gnome_canvas_item_request_update (item); } return TRUE; diff --git a/libnautilus-private/nautilus-icon-canvas-item.h b/libnautilus-private/nautilus-icon-canvas-item.h index 2f9f90a34..b56c9aefd 100644 --- a/libnautilus-private/nautilus-icon-canvas-item.h +++ b/libnautilus-private/nautilus-icon-canvas-item.h @@ -107,6 +107,8 @@ void nautilus_icon_canvas_item_invalidate_label_size (NautilusIconCanvasI void nautilus_icon_canvas_item_get_icon_rectangle (NautilusIconCanvasItem *item, ArtDRect *world_rectangle); void nautilus_icon_canvas_item_update_bounds (NautilusIconCanvasItem *item); +void nautilus_icon_canvas_item_set_note_state (NautilusIconCanvasItem *icon_item, int new_state); + void nautilus_icon_canvas_item_set_smooth_font (NautilusIconCanvasItem *item, EelScalableFont *font); void nautilus_icon_canvas_item_set_smooth_font_size (NautilusIconCanvasItem *item, |