diff options
author | Darin Adler <darin@src.gnome.org> | 2000-03-17 23:03:39 +0000 |
---|---|---|
committer | Darin Adler <darin@src.gnome.org> | 2000-03-17 23:03:39 +0000 |
commit | e8fcc82dffcfbe084538831a0992307626e24914 (patch) | |
tree | 842cb076ec93e1df41f1c9cfa10461b2f08e2db8 | |
parent | bf66a469cc037be0530f728eddb8959738d724bf (diff) | |
download | nautilus-e8fcc82dffcfbe084538831a0992307626e24914.tar.gz |
Simplified the grid a bit and did some redesign. The grid now takes into
* libnautilus/gnome-icon-container-grid.h:
* libnautilus/gnome-icon-container-grid.c:
* libnautilus/gnome-icon-container-private.h:
* libnautilus/gnome-icon-container.c:
* libnautilus/nautilus-icons-view-icon-item.c:
* libnautilus/nautilus-icons-view-icon-item.h:
Simplified the grid a bit and did some redesign. The grid now
takes into account the height and width of the icons. More work
to come.
* libnautilus/nautilus-global-preferences.c:
* nautilus-widgets/nautilus-preferences.h:
Some cleanup, including types for constants.
* libnautilus/nautilus-gnome-extensions.h:
* libnautilus/nautilus-gnome-extensions.c:
(nautilus_art_irect_equal), (nautilus_art_drect_equal),
(nautilus_gnome_canvas_item_get_current_canvas_bounds),
(nautilus_gnome_canvas_item_request_redraw),
(nautilus_gnome_canvas_request_redraw_rectangle),
(nautilus_gnome_canvas_item_get_world_bounds):
More useful canvas and libart routines.
* RENAMING: More renaming ideas.
31 files changed, 1571 insertions, 1170 deletions
@@ -15,3 +15,5 @@ NautilusIconsViewIconItem -> NautilusIconCanvasItem GtkFList -> NautilusList GtkScrollFrame -> NautilusScrollFrame + +*_cb -> *_callback diff --git a/libnautilus-extensions/gnome-icon-container-grid.c b/libnautilus-extensions/gnome-icon-container-grid.c index 601b7e36b..004b37f36 100644 --- a/libnautilus-extensions/gnome-icon-container-grid.c +++ b/libnautilus-extensions/gnome-icon-container-grid.c @@ -24,13 +24,18 @@ */ #include <config.h> -#include <string.h> - #include "gnome-icon-container-grid.h" +#include <string.h> +#include <math.h> +#include "nautilus-gnome-extensions.h" + #define INITIAL_GRID_WIDTH 64 #define INITIAL_GRID_HEIGHT 64 +#define GRID_CELL_WIDTH 80 +#define GRID_CELL_HEIGHT 80 + GnomeIconContainerGrid * gnome_icon_container_grid_new (void) { @@ -54,7 +59,7 @@ void gnome_icon_container_grid_clear (GnomeIconContainerGrid *grid) { GList **p; - guint i, j; + int i, j; p = grid->elems; for (j = 0; j < grid->height; j++) { @@ -82,22 +87,11 @@ gnome_icon_container_grid_destroy (GnomeIconContainerGrid *grid) GList ** gnome_icon_container_grid_get_element_ptr (GnomeIconContainerGrid *grid, - guint x, guint y) + int x, int y) { return &grid->elems[y * grid->alloc_width + x]; } -#if 0 - -GList * -gnome_icon_container_grid_get_element (GnomeIconContainerGrid *grid, - guint x, guint y) -{ - return *gnome_icon_container_grid_get_element_ptr (grid, x, y); -} - -#endif - /* This is admittedly a bit lame. * * Instead of re-allocating the grid from scratch and copying the values, we @@ -106,12 +100,12 @@ gnome_icon_container_grid_get_element (GnomeIconContainerGrid *grid, */ static void resize_allocation (GnomeIconContainerGrid *grid, - guint new_alloc_width, - guint new_alloc_height) + int new_alloc_width, + int new_alloc_height) { GList **new_elems; - guint i, j; - guint new_alloc_size; + int i, j; + int new_alloc_size; if (new_alloc_width == 0 || new_alloc_height == 0) { g_free (grid->elems); @@ -129,7 +123,7 @@ resize_allocation (GnomeIconContainerGrid *grid, memset (new_elems, 0, sizeof (*new_elems) * new_alloc_size); } else { GList **sp, **dp; - guint copy_width, copy_height; + int copy_width, copy_height; /* Copy existing elements into the new array. */ @@ -155,7 +149,7 @@ resize_allocation (GnomeIconContainerGrid *grid, /* If there are other lines left, zero them as well. */ if (i < new_alloc_height) { - guint elems_left; + int elems_left; elems_left = new_alloc_size - (dp - new_elems); memset (dp, 0, sizeof (*new_elems) * elems_left); @@ -173,8 +167,8 @@ static void update_first_free_forward (GnomeIconContainerGrid *grid) { GList **p; - guint start_x, start_y; - guint x, y; + int start_x, start_y; + int x, y; if (grid->first_free_x == -1) { start_x = start_y = 0; @@ -211,7 +205,7 @@ update_first_free_forward (GnomeIconContainerGrid *grid) void gnome_icon_container_grid_set_visible_width (GnomeIconContainerGrid *grid, - guint visible_width) + int visible_width) { if (visible_width > grid->visible_width && grid->height > 0 @@ -234,9 +228,9 @@ gnome_icon_container_grid_set_visible_width (GnomeIconContainerGrid *grid, void gnome_icon_container_grid_resize (GnomeIconContainerGrid *grid, - guint width, guint height) + int width, int height) { - guint new_alloc_width, new_alloc_height; + int new_alloc_width, new_alloc_height; if (width > grid->alloc_width || height > grid->alloc_height) { if (grid->alloc_width > 0) @@ -260,15 +254,16 @@ gnome_icon_container_grid_resize (GnomeIconContainerGrid *grid, grid->width = width; grid->height = height; - if (grid->visible_width != grid->width) + if (grid->visible_width != grid->width) { gnome_icon_container_grid_set_visible_width (grid, grid->width); + } } static void maybe_resize (GnomeIconContainerGrid *grid, - guint x, guint y) + int x, int y) { - guint new_width, new_height; + int new_width, new_height; if (x < grid->width && y < grid->height) return; @@ -286,33 +281,43 @@ maybe_resize (GnomeIconContainerGrid *grid, gnome_icon_container_grid_resize (grid, new_width, new_height); } -void -gnome_icon_container_grid_add (GnomeIconContainerGrid *grid, - GnomeIconContainerIcon *icon, - guint x, guint y) +static void +grid_add_one (GnomeIconContainerGrid *grid, + GnomeIconContainerIcon *icon, + int x, int y) { GList **elem_ptr; + if (x < 0 || y < 0) { + /* FIXME: Can't handle negative coordinates. */ + return; + } + maybe_resize (grid, x, y); elem_ptr = gnome_icon_container_grid_get_element_ptr (grid, x, y); + g_assert (g_list_find (*elem_ptr, icon) == NULL); *elem_ptr = g_list_prepend (*elem_ptr, icon); - if (x == grid->first_free_x && y == grid->first_free_y) + if (x == grid->first_free_x && y == grid->first_free_y) { update_first_free_forward (grid); + } } -void -gnome_icon_container_grid_remove (GnomeIconContainerGrid *grid, - GnomeIconContainerIcon *icon, - guint x, guint y) +static void +grid_remove_one (GnomeIconContainerGrid *grid, + GnomeIconContainerIcon *icon, + int x, int y) { GList **elem_ptr; + + if (x < 0 || y < 0) { + /* FIXME: Can't handle negative coordinates. */ + return; + } elem_ptr = gnome_icon_container_grid_get_element_ptr (grid, x, y); - - g_return_if_fail (*elem_ptr != NULL); - + g_assert (g_list_find (*elem_ptr, icon) != NULL); *elem_ptr = g_list_remove (*elem_ptr, icon); if (*elem_ptr == NULL) { @@ -325,46 +330,83 @@ gnome_icon_container_grid_remove (GnomeIconContainerGrid *grid, } } +static void +add_or_remove (GnomeIconContainerGrid *grid, + GnomeIconContainerIcon *icon, + gboolean add) +{ + int x, y; + + /* Add/remove to all the overlapped grid squares. */ + for (x = icon->grid_rectangle.x0; x < icon->grid_rectangle.x1; x++) { + for (y = icon->grid_rectangle.y0; y < icon->grid_rectangle.y1; y++) { + if (add) { + grid_add_one (grid, icon, x, y); + } else { + grid_remove_one (grid, icon, x, y); + } + } + } +} + void -gnome_icon_container_grid_add_auto (GnomeIconContainerGrid *grid, - GnomeIconContainerIcon *icon, - guint *x_return, guint *y_return) +gnome_icon_container_grid_add (GnomeIconContainerGrid *grid, + GnomeIconContainerIcon *icon) { - GList **empty_elem_ptr; + ArtDRect world_bounds; + + /* Figure out how big the icon is. */ + nautilus_gnome_canvas_item_get_world_bounds + (GNOME_CANVAS_ITEM (icon->item), &world_bounds); + + /* Compute grid bounds for the icon. */ + icon->grid_rectangle.x0 = floor (world_bounds.x0 / GRID_CELL_WIDTH); + icon->grid_rectangle.y0 = floor (world_bounds.y0 / GRID_CELL_HEIGHT); + icon->grid_rectangle.x1 = ceil (world_bounds.x1 / GRID_CELL_WIDTH); + icon->grid_rectangle.y1 = ceil (world_bounds.y1 / GRID_CELL_HEIGHT); + + add_or_remove (grid, icon, TRUE); +} - if (grid->first_free_x < 0 || grid->first_free_y < 0 - || grid->height == 0 || grid->width == 0) { - /* No empty element: add a row. */ - gnome_icon_container_grid_resize (grid, MAX (grid->width, 1), grid->height + 1); - grid->first_free_x = 0; - grid->first_free_y = grid->height - 1; - } +void +gnome_icon_container_grid_remove (GnomeIconContainerGrid *grid, + GnomeIconContainerIcon *icon) +{ + add_or_remove (grid, icon, FALSE); +} - empty_elem_ptr = gnome_icon_container_grid_get_element_ptr (grid, - grid->first_free_x, - grid->first_free_y); +void +gnome_icon_container_grid_get_position (GnomeIconContainerGrid *grid, + GnomeIconContainerIcon *icon, + int *x_return, int *y_return) +{ + int grid_x, grid_y; - *empty_elem_ptr = g_list_prepend (*empty_elem_ptr, icon); + g_return_if_fail (grid != NULL); + g_return_if_fail (x_return != NULL); + g_return_if_fail (y_return != NULL); - if (x_return != NULL) - *x_return = grid->first_free_x; - if (y_return != NULL) - *y_return = grid->first_free_y; + if (grid->first_free_x < 0 || grid->first_free_y < 0 + || grid->height == 0 || grid->width == 0) { + grid_x = 0; + grid_y = grid->height; + } else { + grid_x = grid->first_free_x; + grid_y = grid->first_free_y; + } - update_first_free_forward (grid); + gnome_icon_container_grid_to_world (grid, + grid_x, grid_y, + x_return, y_return); } void -gnome_icon_container_world_to_grid (GnomeIconContainer *container, +gnome_icon_container_world_to_grid (GnomeIconContainerGrid *grid, int world_x, int world_y, - guint *grid_x_return, guint *grid_y_return) + int *grid_x_return, int *grid_y_return) { - GnomeIconContainerDetails *details; - - details = container->details; - if (grid_x_return != NULL) { if (world_x < 0) *grid_x_return = 0; @@ -381,14 +423,10 @@ gnome_icon_container_world_to_grid (GnomeIconContainer *container, } void -gnome_icon_container_grid_to_world (GnomeIconContainer *container, - guint grid_x, guint grid_y, +gnome_icon_container_grid_to_world (GnomeIconContainerGrid *grid, + int grid_x, int grid_y, int *world_x_return, int *world_y_return) { - GnomeIconContainerDetails *details; - - details = container->details; - if (world_x_return != NULL) *world_x_return = grid_x * GNOME_ICON_CONTAINER_CELL_WIDTH (container); @@ -401,17 +439,12 @@ gnome_icon_container_grid_to_world (GnomeIconContainer *container, /* Find the "first" icon (in left-to-right, top-to-bottom order) in `container'. */ GnomeIconContainerIcon * -gnome_icon_container_grid_find_first (GnomeIconContainer *container, +gnome_icon_container_grid_find_first (GnomeIconContainerGrid *grid, gboolean selected_only) { - GnomeIconContainerDetails *details; - GnomeIconContainerGrid *grid; GnomeIconContainerIcon *first; GList **p; - guint i, j; - - details = container->details; - grid = details->grid; + int i, j; if (grid->width == 0 || grid->height == 0) return NULL; @@ -445,17 +478,13 @@ gnome_icon_container_grid_find_first (GnomeIconContainer *container, } GnomeIconContainerIcon * -gnome_icon_container_grid_find_last (GnomeIconContainer *container, gboolean selected_only) +gnome_icon_container_grid_find_last (GnomeIconContainerGrid *grid, + gboolean selected_only) { - GnomeIconContainerDetails *details; - GnomeIconContainerGrid *grid; GnomeIconContainerIcon *last; GList **p; int i, j; - details = container->details; - grid = details->grid; - last = NULL; if (grid->height == 0 || grid->width == 0) diff --git a/libnautilus-extensions/gnome-icon-container-grid.h b/libnautilus-extensions/gnome-icon-container-grid.h index 6be050684..6dc859605 100644 --- a/libnautilus-extensions/gnome-icon-container-grid.h +++ b/libnautilus-extensions/gnome-icon-container-grid.h @@ -27,18 +27,18 @@ struct GnomeIconContainerGrid { /* Size of the grid. */ - guint width, height; + int width, height; /* This is the width that we can actually use for finding an empty * position. */ - guint visible_width; + int visible_width; /* Array of grid elements. */ GList **elems; /* Size of the allocated array. */ - guint alloc_width, alloc_height; + int alloc_width, alloc_height; /* Position of the first free cell (used to speed up progressive * updates). If negative, there is no free cell. @@ -47,39 +47,41 @@ struct GnomeIconContainerGrid { }; -GnomeIconContainerGrid *gnome_icon_container_grid_new (void); -void gnome_icon_container_grid_destroy (GnomeIconContainerGrid *grid); -void gnome_icon_container_grid_clear (GnomeIconContainerGrid *grid); -void gnome_icon_container_grid_add (GnomeIconContainerGrid *grid, - GnomeIconContainerIcon *icon, - guint x, - guint y); -void gnome_icon_container_grid_add_auto (GnomeIconContainerGrid *grid, - GnomeIconContainerIcon *icon, - guint *x_return, guint *y_return); -void gnome_icon_container_grid_remove (GnomeIconContainerGrid *grid, - GnomeIconContainerIcon *icon, - guint x, - guint y); -void gnome_icon_container_grid_set_visible_width (GnomeIconContainerGrid *grid, - guint visible_width); -void gnome_icon_container_grid_resize (GnomeIconContainerGrid *grid, - guint width, guint height); - -GList ** gnome_icon_container_grid_get_element_ptr (GnomeIconContainerGrid *grid, - guint x, - guint y); -GnomeIconContainerIcon *gnome_icon_container_grid_find_first (GnomeIconContainer *container, - gboolean selected_only); -GnomeIconContainerIcon *gnome_icon_container_grid_find_last (GnomeIconContainer *container, - gboolean selected_only); -void gnome_icon_container_world_to_grid (GnomeIconContainer *container, - int world_x, - int world_y, - guint *grid_x, - guint *grid_y); -void gnome_icon_container_grid_to_world (GnomeIconContainer *container, - guint grid_x, - guint grid_y, - int *world_x, - int *world_y); +GnomeIconContainerGrid *gnome_icon_container_grid_new (void); +void gnome_icon_container_grid_destroy (GnomeIconContainerGrid *grid); +void gnome_icon_container_grid_clear (GnomeIconContainerGrid *grid); + +/* getting icons in and out of the grid */ +void gnome_icon_container_grid_add (GnomeIconContainerGrid *grid, + GnomeIconContainerIcon *icon); +void gnome_icon_container_grid_remove (GnomeIconContainerGrid *grid, + GnomeIconContainerIcon *icon); + +void gnome_icon_container_grid_get_position (GnomeIconContainerGrid *grid, + GnomeIconContainerIcon *icon, + int *world_x, + int *world_y); + +void gnome_icon_container_grid_set_visible_width (GnomeIconContainerGrid *grid, + int visible_width); +void gnome_icon_container_grid_resize (GnomeIconContainerGrid *grid, + int width, + int height); +GList ** gnome_icon_container_grid_get_element_ptr (GnomeIconContainerGrid *grid, + int grid_x, + int grid_y); +GnomeIconContainerIcon *gnome_icon_container_grid_find_first (GnomeIconContainerGrid *grid, + gboolean selected_only); +GnomeIconContainerIcon *gnome_icon_container_grid_find_last (GnomeIconContainerGrid *grid, + gboolean selected_only); + +void gnome_icon_container_world_to_grid (GnomeIconContainerGrid *container, + int world_x, + int world_y, + int *grid_x, + int *grid_y); +void gnome_icon_container_grid_to_world (GnomeIconContainerGrid *grid, + int grid_x, + int grid_y, + int *world_x, + int *world_y); diff --git a/libnautilus-extensions/gnome-icon-container-private.h b/libnautilus-extensions/gnome-icon-container-private.h index 19252add2..e253c3b99 100644 --- a/libnautilus-extensions/gnome-icon-container-private.h +++ b/libnautilus-extensions/gnome-icon-container-private.h @@ -33,6 +33,9 @@ /* An Icon. */ typedef struct { + /* Object represented by this icon. */ + GnomeIconContainerIconData *data; + /* Canvas item for the icon. */ NautilusIconsViewIconItem *item; @@ -54,7 +57,8 @@ typedef struct { /* Whether this item was selected before rubberbanding. */ gboolean was_selected_before_rubberband : 1; - GnomeIconContainerIconData *data; + /* Grid space occupied by this icon. */ + ArtIRect grid_rectangle; } GnomeIconContainerIcon; diff --git a/libnautilus-extensions/gnome-icon-container.c b/libnautilus-extensions/gnome-icon-container.c index bb69377e1..6cdea9740 100644 --- a/libnautilus-extensions/gnome-icon-container.c +++ b/libnautilus-extensions/gnome-icon-container.c @@ -367,7 +367,7 @@ make_icon_visible (GnomeIconContainer *container, } static gboolean -kbd_icon_visibility_timeout_cb (gpointer data) +kbd_icon_visibility_timeout_callback (gpointer data) { GnomeIconContainer *container; @@ -408,7 +408,7 @@ schedule_kbd_icon_visibility (GnomeIconContainer *container) details->kbd_icon_visibility_timer_id = gtk_timeout_add (KBD_ICON_VISIBILITY_TIMEOUT, - kbd_icon_visibility_timeout_cb, + kbd_icon_visibility_timeout_callback, container); } @@ -623,14 +623,12 @@ unselect_all (GnomeIconContainer *container) void gnome_icon_container_move_icon (GnomeIconContainer *container, - GnomeIconContainerIcon *icon, - int x, int y, double scale_x, double scale_y, gboolean raise) + GnomeIconContainerIcon *icon, + int x, int y, + double scale_x, double scale_y, + gboolean raise) { GnomeIconContainerDetails *details; - guint old_grid_x, old_grid_y; - int old_x_offset, old_y_offset; - guint new_grid_x, new_grid_y; - int new_x_offset, new_y_offset; gboolean emit_signal; details = container->details; @@ -638,39 +636,6 @@ gnome_icon_container_move_icon (GnomeIconContainer *container, emit_signal = FALSE; if (x != icon->x || y != icon->y) { - gnome_icon_container_world_to_grid (container, icon->x, icon->y, &old_grid_x, &old_grid_y); - old_x_offset = (int)icon->x % GNOME_ICON_CONTAINER_CELL_WIDTH (container); - old_y_offset = (int)icon->y % GNOME_ICON_CONTAINER_CELL_HEIGHT (container); - - gnome_icon_container_world_to_grid (container, x, y, &new_grid_x, &new_grid_y); - new_x_offset = x % GNOME_ICON_CONTAINER_CELL_WIDTH (container); - new_y_offset = y % GNOME_ICON_CONTAINER_CELL_HEIGHT (container); - - gnome_icon_container_grid_remove (details->grid, icon, old_grid_x, old_grid_y); - if (old_x_offset > 0) { - gnome_icon_container_grid_remove (details->grid, icon, - old_grid_x + 1, old_grid_y); - } - if (old_y_offset > 0) { - gnome_icon_container_grid_remove (details->grid, icon, - old_grid_x, old_grid_y + 1); - } - if (old_x_offset > 0 && old_y_offset > 0) { - gnome_icon_container_grid_remove (details->grid, icon, - old_grid_x + 1, old_grid_y + 1); - } - - gnome_icon_container_grid_add (details->grid, icon, new_grid_x, new_grid_y); - if (new_x_offset > 0) { - gnome_icon_container_grid_add (details->grid, icon, new_grid_x + 1, new_grid_y); - } - if (new_y_offset > 0) { - gnome_icon_container_grid_add (details->grid, icon, new_grid_x, new_grid_y + 1); - } - if (new_x_offset > 0 && new_y_offset > 0) { - gnome_icon_container_grid_add (details->grid, icon, new_grid_x + 1, new_grid_y + 1); - } - icon_set_position (icon, x, y); /* Update the keyboard selection indicator. */ @@ -750,21 +715,21 @@ rubberband_select (GnomeIconContainer *container, { GList **p; GnomeIconContainerGrid *grid; - guint curr_grid_x1, curr_grid_y1; - guint curr_grid_x2, curr_grid_y2; - guint prev_grid_x1, prev_grid_y1; - guint prev_grid_x2, prev_grid_y2; - guint grid_x1, grid_y1; - guint grid_x2, grid_y2; - guint i, j; + int curr_grid_x1, curr_grid_y1; + int curr_grid_x2, curr_grid_y2; + int prev_grid_x1, prev_grid_y1; + int prev_grid_x2, prev_grid_y2; + int grid_x1, grid_y1; + int grid_x2, grid_y2; + int i, j; gboolean selection_changed; grid = container->details->grid; - gnome_icon_container_world_to_grid (container, curr_x1, curr_y1, &curr_grid_x1, &curr_grid_y1); - gnome_icon_container_world_to_grid (container, curr_x2, curr_y2, &curr_grid_x2, &curr_grid_y2); - gnome_icon_container_world_to_grid (container, prev_x1, prev_y1, &prev_grid_x1, &prev_grid_y1); - gnome_icon_container_world_to_grid (container, prev_x2, prev_y2, &prev_grid_x2, &prev_grid_y2); + gnome_icon_container_world_to_grid (container->details->grid, curr_x1, curr_y1, &curr_grid_x1, &curr_grid_y1); + gnome_icon_container_world_to_grid (container->details->grid, curr_x2, curr_y2, &curr_grid_x2, &curr_grid_y2); + gnome_icon_container_world_to_grid (container->details->grid, prev_x1, prev_y1, &prev_grid_x1, &prev_grid_y1); + gnome_icon_container_world_to_grid (container->details->grid, prev_x2, prev_y2, &prev_grid_x2, &prev_grid_y2); grid_x1 = MIN (curr_grid_x1, prev_grid_x1); grid_x2 = MAX (curr_grid_x2, prev_grid_x2); @@ -794,7 +759,7 @@ rubberband_select (GnomeIconContainer *container, } static int -rubberband_timeout_cb (gpointer data) +rubberband_timeout_callback (gpointer data) { GnomeIconContainer *container; GtkWidget *widget; @@ -928,7 +893,7 @@ start_rubberbanding (GnomeIconContainer *container, if (band_info->timer_id == 0) { band_info->timer_id = gtk_timeout_add (RUBBERBAND_TIMEOUT_INTERVAL, - rubberband_timeout_cb, + rubberband_timeout_callback, container); } @@ -990,7 +955,7 @@ kbd_home (GnomeIconContainer *container, { GnomeIconContainerIcon *first; - first = gnome_icon_container_grid_find_first (container, FALSE); + first = gnome_icon_container_grid_find_first (container->details->grid, FALSE); if (first != NULL) { kbd_move_to (container, first, event); } @@ -1002,7 +967,7 @@ kbd_end (GnomeIconContainer *container, { GnomeIconContainerIcon *last; - last = gnome_icon_container_grid_find_last (container, FALSE); + last = gnome_icon_container_grid_find_last (container->details->grid, FALSE); if (last != NULL) { kbd_move_to (container, last, event); } @@ -1035,7 +1000,7 @@ kbd_left (GnomeIconContainer *container, GnomeIconContainerGrid *grid; GnomeIconContainerIcon *nearmost; GList **e; - guint grid_x, grid_y; + int grid_x, grid_y; int x, y; int max_x; @@ -1048,18 +1013,18 @@ kbd_left (GnomeIconContainer *container, GnomeIconContainerIcon *first; first = gnome_icon_container_grid_find_first - (container, has_multiple_selection (container)); + (container->details->grid, has_multiple_selection (container)); if (first != NULL) { kbd_move_to (container, first, event); } return; } - gnome_icon_container_world_to_grid (container, + gnome_icon_container_world_to_grid (container->details->grid, details->kbd_current->x, details->kbd_current->y, &grid_x, &grid_y); - gnome_icon_container_grid_to_world (container, grid_x, grid_y, &x, &y); + gnome_icon_container_grid_to_world (container->details->grid, grid_x, grid_y, &x, &y); e = gnome_icon_container_grid_get_element_ptr (grid, 0, grid_y); nearmost = NULL; @@ -1106,7 +1071,7 @@ kbd_left (GnomeIconContainer *container, grid_x = grid->width - 1; max_x = G_MAXINT; - gnome_icon_container_grid_to_world (container, grid_x, 0, &x, NULL); + gnome_icon_container_grid_to_world (container->details->grid, grid_x, 0, &x, NULL); e -= grid->alloc_width; grid_y--; @@ -1122,7 +1087,7 @@ kbd_up (GnomeIconContainer *container, GnomeIconContainerGrid *grid; GnomeIconContainerIcon *nearmost; GList **e; - guint grid_x, grid_y; + int grid_x, grid_y; int x, y; details = container->details; @@ -1134,18 +1099,18 @@ kbd_up (GnomeIconContainer *container, GnomeIconContainerIcon *first; first = gnome_icon_container_grid_find_first - (container, has_multiple_selection (container)); + (container->details->grid, has_multiple_selection (container)); if (first != NULL) { kbd_move_to (container, first, event); } return; } - gnome_icon_container_world_to_grid (container, + gnome_icon_container_world_to_grid (container->details->grid, details->kbd_current->x, details->kbd_current->y, &grid_x, &grid_y); - gnome_icon_container_grid_to_world (container, grid_x, grid_y, &x, &y); + gnome_icon_container_grid_to_world (container->details->grid, grid_x, grid_y, &x, &y); e = gnome_icon_container_grid_get_element_ptr (grid, grid_x, grid_y); nearmost = NULL; @@ -1197,7 +1162,7 @@ kbd_right (GnomeIconContainer *container, GnomeIconContainerGrid *grid; GnomeIconContainerIcon *nearmost; GList **e; - guint grid_x, grid_y; + int grid_x, grid_y; int x, y; int min_x; @@ -1210,18 +1175,18 @@ kbd_right (GnomeIconContainer *container, GnomeIconContainerIcon *last; last = gnome_icon_container_grid_find_last - (container, has_multiple_selection (container)); + (container->details->grid, has_multiple_selection (container)); if (last != NULL) { kbd_move_to (container, last, event); } return; } - gnome_icon_container_world_to_grid (container, + gnome_icon_container_world_to_grid (container->details->grid, details->kbd_current->x, details->kbd_current->y, &grid_x, &grid_y); - gnome_icon_container_grid_to_world (container, grid_x, grid_y, &x, &y); + gnome_icon_container_grid_to_world (container->details->grid, grid_x, grid_y, &x, &y); e = gnome_icon_container_grid_get_element_ptr (grid, 0, grid_y); nearmost = NULL; @@ -1276,7 +1241,7 @@ kbd_down (GnomeIconContainer *container, GnomeIconContainerGrid *grid; GnomeIconContainerIcon *nearmost; GList **e; - guint grid_x, grid_y; + int grid_x, grid_y; int x, y; details = container->details; @@ -1288,18 +1253,18 @@ kbd_down (GnomeIconContainer *container, GnomeIconContainerIcon *last; last = gnome_icon_container_grid_find_last - (container, has_multiple_selection (container)); + (container->details->grid, has_multiple_selection (container)); if (last != NULL) { kbd_move_to (container, last, event); } return; } - gnome_icon_container_world_to_grid (container, + gnome_icon_container_world_to_grid (container->details->grid, details->kbd_current->x, details->kbd_current->y, &grid_x, &grid_y); - gnome_icon_container_grid_to_world (container, grid_x, grid_y, &x, &y); + gnome_icon_container_grid_to_world (container->details->grid, grid_x, grid_y, &x, &y); e = gnome_icon_container_grid_get_element_ptr (grid, grid_x, grid_y); nearmost = NULL; @@ -1350,7 +1315,7 @@ kbd_space (GnomeIconContainer *container, GnomeIconContainerIcon *icon; icon = gnome_icon_container_grid_find_first - (container, + (container->details->grid, get_first_selected_icon (container) != NULL); set_kbd_current (container, icon, TRUE); } @@ -1425,7 +1390,7 @@ size_allocate (GtkWidget *widget, container = GNOME_ICON_CONTAINER (widget); grid = container->details->grid; - gnome_icon_container_world_to_grid (container, + gnome_icon_container_world_to_grid (container->details->grid, allocation->width, 0, &visible_width, &visible_height); @@ -2048,7 +2013,7 @@ handle_icon_button_press (GnomeIconContainer *container, } static int -item_event_cb (GnomeCanvasItem *item, +item_event_callback (GnomeCanvasItem *item, GdkEvent *event, gpointer data) { @@ -2123,12 +2088,9 @@ gnome_icon_container_clear (GnomeIconContainer *container) static void icon_destroy (GnomeIconContainer *container, - GnomeIconContainerIcon *icon) + GnomeIconContainerIcon *icon) { GnomeIconContainerDetails *details; - gint icon_x, icon_y; - gint grid_x, grid_y; - gint x_offset, y_offset; gboolean was_selected; details = container->details; @@ -2142,27 +2104,7 @@ icon_destroy (GnomeIconContainer *container, set_kbd_current (container, NULL, FALSE); } - icon_x = icon->x; - icon_y = icon->y; - gnome_icon_container_world_to_grid (container, icon_x, icon_y, &grid_x, &grid_y); - gnome_icon_container_grid_remove(details->grid, icon, grid_x, grid_y); - - x_offset = icon_x % GNOME_ICON_CONTAINER_CELL_WIDTH (container); - y_offset = icon_y % GNOME_ICON_CONTAINER_CELL_HEIGHT (container); - - if (x_offset > 0) { - gnome_icon_container_grid_remove (details->grid, icon, - grid_x + 1, grid_y); - } - if (y_offset > 0) { - gnome_icon_container_grid_remove (details->grid, icon, - grid_x, grid_y + 1); - } - if (x_offset > 0 && y_offset > 0) { - gnome_icon_container_grid_remove (details->grid, icon, - grid_x + 1, grid_y + 1); - } - + gnome_icon_container_grid_remove (details->grid, icon); g_hash_table_remove (details->canvas_item_to_icon, icon->item); icon_free (icon); @@ -2193,6 +2135,24 @@ activate_selected_items (GnomeIconContainer *container) } static void +bounds_changed_callback (NautilusIconsViewIconItem *item, + const ArtDRect *old_bounds, + GnomeIconContainer *container) +{ + GnomeIconContainerIcon *icon; + + g_assert (NAUTILUS_IS_ICONS_VIEW_ICON_ITEM (item)); + g_assert (old_bounds != NULL); + g_assert (GNOME_IS_ICON_CONTAINER (container)); + + icon = g_hash_table_lookup (container->details->canvas_item_to_icon, item); + g_assert (icon != NULL); + + gnome_icon_container_grid_remove (container->details->grid, icon); + gnome_icon_container_grid_add (container->details->grid, icon); +} + +static void setup_icon_in_container (GnomeIconContainer *container, GnomeIconContainerIcon *icon) { @@ -2204,10 +2164,16 @@ setup_icon_in_container (GnomeIconContainer *container, details->num_icons++; g_hash_table_insert (details->canvas_item_to_icon, icon->item, icon); + + nautilus_icons_view_icon_item_update_bounds (icon->item); + gnome_icon_container_grid_add (details->grid, icon); + icon_show (icon); gtk_signal_connect (GTK_OBJECT (icon->item), "event", - GTK_SIGNAL_FUNC (item_event_cb), container); + GTK_SIGNAL_FUNC (item_event_callback), container); + gtk_signal_connect (GTK_OBJECT (icon->item), "bounds_changed", + GTK_SIGNAL_FUNC (bounds_changed_callback), container); } static void @@ -2294,11 +2260,11 @@ update_icon (GnomeIconContainer *container, GnomeIconContainerIcon *icon) void gnome_icon_container_add (GnomeIconContainer *container, GnomeIconContainerIconData *data, - int x, int y, double scale_x, double scale_y) + int x, int y, + double scale_x, double scale_y) { GnomeIconContainerDetails *details; GnomeIconContainerIcon *new_icon; - guint grid_x, grid_y; g_return_if_fail (GNOME_IS_ICON_CONTAINER (container)); g_return_if_fail (data != NULL); @@ -2310,20 +2276,6 @@ gnome_icon_container_add (GnomeIconContainer *container, new_icon->scale_x = scale_x; new_icon->scale_y = scale_y; - gnome_icon_container_world_to_grid (container, x, y, &grid_x, &grid_y); - gnome_icon_container_grid_add (details->grid, new_icon, grid_x, grid_y); - - if (x % GNOME_ICON_CONTAINER_CELL_WIDTH (container) > 0) { - gnome_icon_container_grid_add (details->grid, new_icon, grid_x + 1, grid_y); - } - if (y % GNOME_ICON_CONTAINER_CELL_HEIGHT (container) > 0) { - gnome_icon_container_grid_add (details->grid, new_icon, grid_x, grid_y + 1); - } - if (x % GNOME_ICON_CONTAINER_CELL_WIDTH (container) > 0 - && y % GNOME_ICON_CONTAINER_CELL_HEIGHT (container) > 0) { - gnome_icon_container_grid_add (details->grid, new_icon, grid_x + 1, grid_y + 1); - } - setup_icon_in_container (container, new_icon); request_idle (container); @@ -2344,7 +2296,6 @@ gnome_icon_container_add_auto (GnomeIconContainer *container, GnomeIconContainerIconData *data) { GnomeIconContainerIcon *new_icon; - guint grid_x, grid_y; int x, y; g_return_if_fail (GNOME_IS_ICON_CONTAINER (container)); @@ -2352,10 +2303,9 @@ gnome_icon_container_add_auto (GnomeIconContainer *container, new_icon = icon_new (container, data); - gnome_icon_container_grid_add_auto (container->details->grid, - new_icon, - &grid_x, &grid_y); - gnome_icon_container_grid_to_world (container, grid_x, grid_y, &x, &y); + gnome_icon_container_grid_get_position (container->details->grid, + new_icon, + &x, &y); icon_set_position (new_icon, x, y); @@ -2501,11 +2451,11 @@ gnome_icon_container_relayout (GnomeIconContainer *container) GnomeIconContainerDetails *details; GnomeIconContainerGrid *old_grid, *new_grid; GList **sp, **dp; - guint i, j; - guint dx, dy; - guint sx, sy; - guint cols; - guint lines; + int i, j; + int dx, dy; + int sx, sy; + int cols; + int lines; g_return_if_fail (GNOME_IS_ICON_CONTAINER (container)); @@ -2615,8 +2565,8 @@ gnome_icon_container_line_up (GnomeIconContainer *container) GnomeIconContainerGrid *grid; GnomeIconContainerGrid *new_grid; GList **p, **q; - guint new_grid_width; - guint i, j, k, m; + int new_grid_width; + int i, j, k, m; int x, y, dx; g_return_if_fail (GNOME_IS_ICON_CONTAINER (container)); @@ -2635,12 +2585,12 @@ gnome_icon_container_line_up (GnomeIconContainer *container) p = grid->elems; x = y = 0; for (i = 0; i < grid->height; i++) { - guint line_width; + int line_width; line_width = grid->width; for (j = 0; j < grid->width; j++) { GList *e; - guint count; + int count; count = 0; for (e = p[j]; e != NULL; e = e->next) { @@ -2682,7 +2632,7 @@ gnome_icon_container_line_up (GnomeIconContainer *container) m = 0; for (j = 0; j < grid->width; j++) { GList *e; - guint count; + int count; /* Make sure the icons are sorted by increasing X position. */ diff --git a/libnautilus-extensions/nautilus-global-preferences.c b/libnautilus-extensions/nautilus-global-preferences.c index a08ff9836..79fca8ca1 100644 --- a/libnautilus-extensions/nautilus-global-preferences.c +++ b/libnautilus-extensions/nautilus-global-preferences.c @@ -22,7 +22,9 @@ Authors: Ramiro Estrugo <ramiro@eazel.com> */ +#include <config.h> #include "nautilus-global-preferences.h" + #include <nautilus-widgets/nautilus-preferences-group.h> #include <nautilus-widgets/nautilus-preferences-item.h> #include <nautilus-widgets/nautilus-preferences-dialog.h> @@ -35,24 +37,24 @@ /* Private stuff */ static GtkWidget *global_preferences_create_dialog (void); -static GtkWidget *global_prefernces_create_enum_group (GtkWidget *pane, - const gchar *group_title, - const gchar *pref_name); -static GtkWidget *global_preferences_create_check_group (GtkWidget *pane, - const gchar *group_title, - const gchar *pref_names[], - guint num_prefs); +static GtkWidget *global_preferences_create_enum_group (GtkWidget *pane, + const char *group_title, + const char *pref_name); +static GtkWidget *global_preferences_create_check_group (GtkWidget *pane, + const char *group_title, + const char * const pref_names[], + guint num_prefs); static GtkWidget *global_preferences_get_dialog (void); static void global_preferences_register_static (NautilusPreferences *prefs); static void global_preferences_register_dynamic (NautilusPreferences *prefs); -static const gchar *global_preferences_window_option_pref_names[] = +static const char * const global_preferences_window_option_pref_names[] = { NAUTILUS_PREFERENCES_WINDOW_ALWAYS_NEW, NAUTILUS_PREFERENCES_WINDOW_SEARCH_EXISTING }; -static const gchar *global_preferences_meta_view_names[] = +static const char * const global_preferences_meta_view_names[] = { NAUTILUS_PREFERENCES_META_VIEWS_SHOW_ANNOTATIONS, NAUTILUS_PREFERENCES_META_VIEWS_SHOW_HELP_CONTENTS, @@ -62,7 +64,7 @@ static const gchar *global_preferences_meta_view_names[] = NAUTILUS_PREFERENCES_META_VIEWS_SHOW_WEB_SEARCH }; -static const gchar * global_preferences_user_level_names[] = +static const char * const global_preferences_user_level_names[] = { "novice", "intermediate", @@ -70,7 +72,7 @@ static const gchar * global_preferences_user_level_names[] = "ettore" }; -static const gchar * global_preferences_user_level_descriptions[] = +static const char * const global_preferences_user_level_descriptions[] = { "Novice", "Intermediate", @@ -86,7 +88,7 @@ static const gint global_preferences_user_level_values[] = NAUTILUS_USER_LEVEL_ETTORE }; -static NautilusPreferencesEnumData global_preferences_user_level_data = +static const NautilusPreferencesEnumData global_preferences_user_level_data = { global_preferences_user_level_names, global_preferences_user_level_descriptions, @@ -94,7 +96,7 @@ static NautilusPreferencesEnumData global_preferences_user_level_data = NAUTILUS_N_ELEMENTS (global_preferences_user_level_names) }; -static NautilusPreferencesInfo global_preferences_static_info[] = +static const NautilusPreferencesInfo global_preferences_static_info[] = { { NAUTILUS_PREFERENCES_USER_LEVEL, @@ -151,7 +153,7 @@ global_preferences_create_dialog (void) "User Level", "User Level Something"); - global_prefernces_create_enum_group (panes[0], + global_preferences_create_enum_group (panes[0], "User Level", NAUTILUS_PREFERENCES_USER_LEVEL); @@ -177,10 +179,10 @@ global_preferences_create_dialog (void) } static GtkWidget * -global_preferences_create_check_group (GtkWidget *pane, - const gchar *group_title, - const gchar *pref_names[], - guint num_prefs) +global_preferences_create_check_group (GtkWidget *pane, + const char *group_title, + const char * const pref_names[], + guint num_prefs) { GtkWidget *group; guint i; @@ -209,9 +211,9 @@ global_preferences_create_check_group (GtkWidget *pane, } static GtkWidget * -global_prefernces_create_enum_group (GtkWidget *pane, - const gchar *group_title, - const gchar *pref_name) +global_preferences_create_enum_group (GtkWidget *pane, + const char *group_title, + const char *pref_name) { GtkWidget *group; GtkWidget *item; diff --git a/libnautilus-extensions/nautilus-gnome-extensions.c b/libnautilus-extensions/nautilus-gnome-extensions.c index 54749922b..b0d5c7ac3 100644 --- a/libnautilus-extensions/nautilus-gnome-extensions.c +++ b/libnautilus-extensions/nautilus-gnome-extensions.c @@ -86,3 +86,82 @@ nautilus_art_irect_hits_irect (const ArtIRect *rect_a, art_irect_intersect (&intersection, rect_a, rect_b); return !art_irect_empty (&intersection); } + +gboolean +nautilus_art_irect_equal (const ArtIRect *rect_a, + const ArtIRect *rect_b) +{ + g_return_val_if_fail (rect_a != NULL, FALSE); + g_return_val_if_fail (rect_b != NULL, FALSE); + + return rect_a->x0 == rect_b->x0 + && rect_a->y0 == rect_b->y0 + && rect_a->x1 == rect_b->x1 + && rect_a->y1 == rect_b->y1; +} + +gboolean +nautilus_art_drect_equal (const ArtDRect *rect_a, + const ArtDRect *rect_b) +{ + g_return_val_if_fail (rect_a != NULL, FALSE); + g_return_val_if_fail (rect_b != NULL, FALSE); + + return rect_a->x0 == rect_b->x0 + && rect_a->y0 == rect_b->y0 + && rect_a->x1 == rect_b->x1 + && rect_a->y1 == rect_b->y1; +} + +void +nautilus_gnome_canvas_item_get_current_canvas_bounds (GnomeCanvasItem *item, + ArtIRect *bounds) +{ + g_return_if_fail (GNOME_IS_CANVAS_ITEM (item)); + g_return_if_fail (bounds != NULL); + + bounds->x0 = item->x1; + bounds->y0 = item->y1; + bounds->x1 = item->x2; + bounds->y1 = item->y2; +} + +void +nautilus_gnome_canvas_item_request_redraw (GnomeCanvasItem *item) +{ + g_return_if_fail (GNOME_IS_CANVAS_ITEM (item)); + + gnome_canvas_request_redraw (item->canvas, + item->x1, item->y1, + item->x2, item->y2); +} + +void +nautilus_gnome_canvas_request_redraw_rectangle (GnomeCanvas *canvas, + const ArtIRect *canvas_rectangle) +{ + g_return_if_fail (GNOME_IS_CANVAS (canvas)); + + gnome_canvas_request_redraw (canvas, + canvas_rectangle->x0, canvas_rectangle->y0, + canvas_rectangle->x1, canvas_rectangle->y1); +} + +void +nautilus_gnome_canvas_item_get_world_bounds (GnomeCanvasItem *item, + ArtDRect *world_bounds) +{ + gnome_canvas_item_get_bounds (item, + &world_bounds->x0, + &world_bounds->y0, + &world_bounds->x1, + &world_bounds->y1); + if (item->parent != NULL) { + gnome_canvas_item_i2w (item->parent, + &world_bounds->x0, + &world_bounds->y0); + gnome_canvas_item_i2w (item->parent, + &world_bounds->x1, + &world_bounds->y1); + } +} diff --git a/libnautilus-extensions/nautilus-gnome-extensions.h b/libnautilus-extensions/nautilus-gnome-extensions.h index 3c3d40af9..df921e08f 100644 --- a/libnautilus-extensions/nautilus-gnome-extensions.h +++ b/libnautilus-extensions/nautilus-gnome-extensions.h @@ -29,13 +29,42 @@ #include <libgnomeui/gnome-canvas.h> -void nautilus_gnome_canvas_world_to_canvas_rectangle (GnomeCanvas *canvas, - const ArtDRect *world_rectangle, - ArtIRect *canvas_rectangle); -void nautilus_gnome_canvas_world_to_window_rectangle (GnomeCanvas *canvas, - const ArtDRect *world_rectangle, - ArtIRect *window_rectangle); -gboolean nautilus_art_irect_hits_irect (const ArtIRect *rect_a, - const ArtIRect *rect_b); +/* This is more handy than gnome_canvas_item_get_bounds because it + * always returns the bounds * in world coordinates and it returns + * them in a single rectangle. + */ +void nautilus_gnome_canvas_item_get_world_bounds (GnomeCanvasItem *item, + ArtDRect *world_bounds); + +/* This returns the current canvas bounds as computed by update. + * It's not as "up to date" as get_bounds, which is accurate even + * before an update happens. + */ +void nautilus_gnome_canvas_item_get_current_canvas_bounds (GnomeCanvasItem *item, + ArtIRect *canvas_bounds); + +/* Convenience functions for doing things with whole rectangles. */ +void nautilus_gnome_canvas_world_to_canvas_rectangle (GnomeCanvas *canvas, + const ArtDRect *world_rectangle, + ArtIRect *canvas_rectangle); +void nautilus_gnome_canvas_world_to_window_rectangle (GnomeCanvas *canvas, + const ArtDRect *world_rectangle, + ArtIRect *window_rectangle); +void nautilus_gnome_canvas_request_redraw_rectangle (GnomeCanvas *canvas, + const ArtIRect *canvas_rectangle); + +/* Requests the entire object be redrawn. + * Normally, you use request_update when calling from outside the canvas item + * code. This is for within canvas item code. + */ +void nautilus_gnome_canvas_item_request_redraw (GnomeCanvasItem *item); + +/* More functions for ArtIRect and ArtDRect. */ +gboolean nautilus_art_irect_hits_irect (const ArtIRect *rect_a, + const ArtIRect *rect_b); +gboolean nautilus_art_irect_equal (const ArtIRect *rect_a, + const ArtIRect *rect_b); +gboolean nautilus_art_drect_equal (const ArtDRect *rect_a, + const ArtDRect *rect_b); #endif /* NAUTILUS_GNOME_EXTENSIONS_H */ diff --git a/libnautilus-extensions/nautilus-icons-view-icon-item.c b/libnautilus-extensions/nautilus-icons-view-icon-item.c index b56c4a41c..1ba9febe2 100644 --- a/libnautilus-extensions/nautilus-icons-view-icon-item.c +++ b/libnautilus-extensions/nautilus-icons-view-icon-item.c @@ -28,6 +28,7 @@ #include <math.h> #include <string.h> #include <stdio.h> +#include <gtk/gtksignal.h> #include <gdk-pixbuf/gdk-pixbuf.h> #include <libart_lgpl/art_rgb_pixbuf_affine.h> #include <libgnomeui/gnome-canvas-util.h> @@ -90,6 +91,12 @@ typedef struct { GList *emblem; } EmblemLayout; +enum { + BOUNDS_CHANGED, + LAST_SIGNAL +}; +static guint signals[LAST_SIGNAL]; + /* constants */ #define MAX_TEXT_WIDTH 80 @@ -100,65 +107,65 @@ static char stipple_bits[] = { 0x02, 0x01 }; static GdkFont *embedded_text_font; /* GtkObject */ -static void nautilus_icons_view_icon_item_initialize_class (NautilusIconsViewIconItemClass *class); -static void nautilus_icons_view_icon_item_initialize (NautilusIconsViewIconItem *item); -static void nautilus_icons_view_icon_item_destroy (GtkObject *object); -static int nautilus_icons_view_icon_item_event (GnomeCanvasItem *item, - GdkEvent *event); -static void nautilus_icons_view_icon_item_set_arg (GtkObject *object, - GtkArg *arg, - guint arg_id); -static void nautilus_icons_view_icon_item_get_arg (GtkObject *object, - GtkArg *arg, - guint arg_id); +static void nautilus_icons_view_icon_item_initialize_class (NautilusIconsViewIconItemClass *class); +static void nautilus_icons_view_icon_item_initialize (NautilusIconsViewIconItem *item); +static void nautilus_icons_view_icon_item_destroy (GtkObject *object); +static int nautilus_icons_view_icon_item_event (GnomeCanvasItem *item, + GdkEvent *event); +static void nautilus_icons_view_icon_item_set_arg (GtkObject *object, + GtkArg *arg, + guint arg_id); +static void nautilus_icons_view_icon_item_get_arg (GtkObject *object, + GtkArg *arg, + guint arg_id); /* GnomeCanvasItem */ -static void nautilus_icons_view_icon_item_update (GnomeCanvasItem *item, - double *affine, - ArtSVP *clip_path, - int flags); -static void nautilus_icons_view_icon_item_draw (GnomeCanvasItem *item, - GdkDrawable *drawable, - int x, - int y, - int width, - int height); -static double nautilus_icons_view_icon_item_point (GnomeCanvasItem *item, - double x, - double y, - int cx, - int cy, - GnomeCanvasItem **actual_item); -static void nautilus_icons_view_icon_item_bounds (GnomeCanvasItem *item, - double *x1, - double *y1, - double *x2, - double *y2); +static void nautilus_icons_view_icon_item_update (GnomeCanvasItem *item, + double *affine, + ArtSVP *clip_path, + int flags); +static void nautilus_icons_view_icon_item_draw (GnomeCanvasItem *item, + GdkDrawable *drawable, + int x, + int y, + int width, + int height); +static double nautilus_icons_view_icon_item_point (GnomeCanvasItem *item, + double x, + double y, + int cx, + int cy, + GnomeCanvasItem **actual_item); +static void nautilus_icons_view_icon_item_bounds (GnomeCanvasItem *item, + double *x1, + double *y1, + double *x2, + double *y2); /* private */ -static void draw_or_measure_text_box (GnomeCanvasItem *item, - GdkDrawable *drawable, - int icon_left, - int icon_bottom); -static void nautilus_icons_view_draw_text_box (GnomeCanvasItem *item, - GdkDrawable *drawable, - int icon_left, - int icon_bottom); -static void nautilus_icons_view_measure_text_box (GnomeCanvasItem *item); -static void nautilus_icons_view_icon_item_get_icon_canvas_rectangle (NautilusIconsViewIconItem *item, - ArtIRect *rect); -static void emblem_layout_reset (EmblemLayout *layout, - NautilusIconsViewIconItem *icon_item, - const ArtIRect *icon_rect); -static gboolean emblem_layout_next (EmblemLayout *layout, - GdkPixbuf **emblem_pixbuf, - ArtIRect *emblem_rect); -static void draw_pixbuf (GdkPixbuf *pixbuf, - GdkDrawable *drawable, - int x, - int y); -static gboolean hit_stretch_handle (NautilusIconsViewIconItem *item, - const ArtIRect *canvas_rect); +static void draw_or_measure_label_text (NautilusIconsViewIconItem *item, + GdkDrawable *drawable, + int icon_left, + int icon_bottom); +static void draw_label_text (NautilusIconsViewIconItem *item, + GdkDrawable *drawable, + int icon_left, + int icon_bottom); +static void measure_label_text (NautilusIconsViewIconItem *item); +static void get_icon_canvas_rectangle (NautilusIconsViewIconItem *item, + ArtIRect *rect); +static void emblem_layout_reset (EmblemLayout *layout, + NautilusIconsViewIconItem *icon_item, + const ArtIRect *icon_rect); +static gboolean emblem_layout_next (EmblemLayout *layout, + GdkPixbuf **emblem_pixbuf, + ArtIRect *emblem_rect); +static void draw_pixbuf (GdkPixbuf *pixbuf, + GdkDrawable *drawable, + int x, + int y); +static gboolean hit_stretch_handle (NautilusIconsViewIconItem *item, + const ArtIRect *canvas_rect); NAUTILUS_DEFINE_CLASS_BOILERPLATE (NautilusIconsViewIconItem, nautilus_icons_view_icon_item, GNOME_TYPE_CANVAS_ITEM) @@ -172,30 +179,43 @@ nautilus_icons_view_icon_item_initialize_class (NautilusIconsViewIconItemClass * object_class = GTK_OBJECT_CLASS (class); item_class = GNOME_CANVAS_ITEM_CLASS (class); - gtk_object_add_arg_type ("NautilusIconsViewIconItem::text", + gtk_object_add_arg_type ("NautilusIconsViewIconItem::text", GTK_TYPE_STRING, GTK_ARG_READWRITE, ARG_TEXT); - gtk_object_add_arg_type ("NautilusIconsViewIconItem::font", + gtk_object_add_arg_type ("NautilusIconsViewIconItem::font", GTK_TYPE_BOXED, GTK_ARG_READWRITE, ARG_FONT); - gtk_object_add_arg_type ("NautilusIconsViewIconItem::highlighted_for_selection", + gtk_object_add_arg_type ("NautilusIconsViewIconItem::highlighted_for_selection", GTK_TYPE_BOOL, GTK_ARG_READWRITE, ARG_HIGHLIGHTED_FOR_SELECTION); - gtk_object_add_arg_type ("NautilusIconsViewIconItem::highlighted_for_keyboard_selection", + gtk_object_add_arg_type ("NautilusIconsViewIconItem::highlighted_for_keyboard_selection", GTK_TYPE_BOOL, GTK_ARG_READWRITE, ARG_HIGHLIGHTED_FOR_KEYBOARD_SELECTION); - gtk_object_add_arg_type ("NautilusIconsViewIconItem::highlighted_for_drop", + gtk_object_add_arg_type ("NautilusIconsViewIconItem::highlighted_for_drop", GTK_TYPE_BOOL, GTK_ARG_READWRITE, ARG_HIGHLIGHTED_FOR_DROP); - gtk_object_add_arg_type ("NautilusIconsViewIconItem::text_source", + gtk_object_add_arg_type ("NautilusIconsViewIconItem::text_source", GTK_TYPE_STRING, GTK_ARG_READWRITE, ARG_TEXT_SOURCE); object_class->destroy = nautilus_icons_view_icon_item_destroy; object_class->set_arg = nautilus_icons_view_icon_item_set_arg; object_class->get_arg = nautilus_icons_view_icon_item_get_arg; + signals[BOUNDS_CHANGED] + = gtk_signal_new ("bounds_changed", + GTK_RUN_LAST, + object_class->type, + GTK_SIGNAL_OFFSET (NautilusIconsViewIconItemClass, + bounds_changed), + gtk_marshal_NONE__POINTER, + GTK_TYPE_NONE, 1, + GTK_TYPE_POINTER); + + gtk_object_class_add_signals (object_class, signals, LAST_SIGNAL); + item_class->update = nautilus_icons_view_icon_item_update; item_class->draw = nautilus_icons_view_icon_item_draw; item_class->point = nautilus_icons_view_icon_item_point; item_class->bounds = nautilus_icons_view_icon_item_bounds; item_class->event = nautilus_icons_view_icon_item_event; - + stipple = gdk_bitmap_create_from_data (NULL, stipple_bits, 2, 2); + /* FIXME: the font shouldn't be hard-wired like this */ embedded_text_font = gdk_font_load("-bitstream-charter-medium-r-normal-*-9-*-*-*-*-*-*-*"); } @@ -483,36 +503,52 @@ recompute_bounding_box (NautilusIconsViewIconItem *icon_item) item->y2 = bottom_right.y; } -/* Update handler for the icon canvas item. */ -static void -nautilus_icons_view_icon_item_update (GnomeCanvasItem *item, double *affine, ArtSVP *clip_path, int flags) +void +nautilus_icons_view_icon_item_update_bounds (NautilusIconsViewIconItem *item) { - NautilusIconsViewIconItem *icon_item; - NautilusIconsViewIconItemDetails *details; + ArtIRect before, after; - icon_item = NAUTILUS_ICONS_VIEW_ICON_ITEM (item); - details = icon_item->details; + /* Compute new bounds. */ + nautilus_gnome_canvas_item_get_current_canvas_bounds + (GNOME_CANVAS_ITEM (item), &before); + recompute_bounding_box (item); + nautilus_gnome_canvas_item_get_current_canvas_bounds + (GNOME_CANVAS_ITEM (item), &after); - /* Make sure the text box measurements are set up - * before recalculating the bounding box. - */ - gnome_canvas_request_redraw (item->canvas, item->x1, item->y1, item->x2, item->y2); - nautilus_icons_view_measure_text_box (item); - recompute_bounding_box (icon_item); - gnome_canvas_request_redraw (item->canvas, item->x1, item->y1, item->x2, item->y2); - - NAUTILUS_CALL_PARENT_CLASS (GNOME_CANVAS_ITEM_CLASS, update, (item, affine, clip_path, flags)); + /* If the bounds didn't change, we are done. */ + if (nautilus_art_irect_equal (&before, &after)) { + return; + } + + /* Send out the bounds_changed signal and queue a redraw. */ + nautilus_gnome_canvas_request_redraw_rectangle + (GNOME_CANVAS_ITEM (item)->canvas, &before); + gtk_signal_emit (GTK_OBJECT (item), + signals[BOUNDS_CHANGED]); + nautilus_gnome_canvas_item_request_redraw + (GNOME_CANVAS_ITEM (item)); } +/* Update handler for the icon canvas item. */ +static void +nautilus_icons_view_icon_item_update (GnomeCanvasItem *item, + double *affine, + ArtSVP *clip_path, + int flags) +{ + nautilus_icons_view_icon_item_update_bounds (NAUTILUS_ICONS_VIEW_ICON_ITEM (item)); + nautilus_gnome_canvas_item_request_redraw (item); + NAUTILUS_CALL_PARENT_CLASS (GNOME_CANVAS_ITEM_CLASS, update, (item, affine, clip_path, flags)); +} /* Rendering */ /* Draw the text in a box, using gnomelib routines. */ static void -draw_or_measure_text_box (GnomeCanvasItem* item, - GdkDrawable *drawable, - int icon_left, - int icon_bottom) +draw_or_measure_label_text (NautilusIconsViewIconItem *item, + GdkDrawable *drawable, + int icon_left, + int icon_bottom) { NautilusIconsViewIconItemDetails *details; int width_so_far, height_so_far; @@ -524,7 +560,7 @@ draw_or_measure_text_box (GnomeCanvasItem* item, const char *text_piece; int i; - details = NAUTILUS_ICONS_VIEW_ICON_ITEM (item)->details; + details = item->details; if (details->font == NULL || details->text == NULL || details->text[0] == '\0') { details->text_height = 0; @@ -537,10 +573,10 @@ draw_or_measure_text_box (GnomeCanvasItem* item, if (drawable != NULL) { icon_width = details->pixbuf == NULL ? 0 : gdk_pixbuf_get_width (details->pixbuf); - gc = gdk_gc_new (item->canvas->layout.bin_window); + gc = gdk_gc_new (GNOME_CANVAS_ITEM (item)->canvas->layout.bin_window); } - max_text_width = floor (MAX_TEXT_WIDTH * item->canvas->pixels_per_unit); + max_text_width = floor (MAX_TEXT_WIDTH * GNOME_CANVAS_ITEM (item)->canvas->pixels_per_unit); pieces = g_strsplit (details->text, "\n", 0); for (i = 0; (text_piece = pieces[i]) != NULL; i++) { @@ -610,16 +646,16 @@ draw_or_measure_text_box (GnomeCanvasItem* item, } static void -nautilus_icons_view_measure_text_box (GnomeCanvasItem* item) +measure_label_text (NautilusIconsViewIconItem *item) { - draw_or_measure_text_box (item, NULL, 0, 0); + draw_or_measure_label_text (item, NULL, 0, 0); } static void -nautilus_icons_view_draw_text_box (GnomeCanvasItem* item, GdkDrawable *drawable, +draw_label_text (NautilusIconsViewIconItem *item, GdkDrawable *drawable, int icon_left, int icon_bottom) { - draw_or_measure_text_box (item, drawable, icon_left, icon_bottom); + draw_or_measure_label_text (item, drawable, icon_left, icon_bottom); } /* utility routine to draw the mini-text inside text files */ @@ -958,8 +994,7 @@ nautilus_icons_view_icon_item_draw (GnomeCanvasItem *item, GdkDrawable *drawable } /* Compute icon rectangle in drawable coordinates. */ - nautilus_icons_view_icon_item_get_icon_canvas_rectangle - (icon_item, &icon_rect); + get_icon_canvas_rectangle (icon_item, &icon_rect); icon_rect.x0 -= x; icon_rect.y0 -= y; icon_rect.x1 -= x; @@ -988,7 +1023,7 @@ nautilus_icons_view_icon_item_draw (GnomeCanvasItem *item, GdkDrawable *drawable draw_embedded_text (item, drawable, &icon_rect); /* Draw the label text. */ - nautilus_icons_view_draw_text_box (item, drawable, icon_rect.x0, icon_rect.y1); + draw_label_text (icon_item, drawable, icon_rect.x0, icon_rect.y1); } /* handle events */ @@ -1093,8 +1128,7 @@ hit_test (NautilusIconsViewIconItem *icon_item, const ArtIRect *canvas_rect) } /* Check for hit in the icon. */ - nautilus_icons_view_icon_item_get_icon_canvas_rectangle - (icon_item, &icon_rect); + get_icon_canvas_rectangle (icon_item, &icon_rect); if (hit_test_pixbuf (details->pixbuf, &icon_rect, canvas_rect)) { return TRUE; } @@ -1157,6 +1191,8 @@ nautilus_icons_view_icon_item_bounds (GnomeCanvasItem *item, double *x1, double icon_item = NAUTILUS_ICONS_VIEW_ICON_ITEM (item); details = icon_item->details; + measure_label_text (icon_item); + /* Compute icon rectangle. */ icon_rect.x0 = 0; icon_rect.y0 = 0; @@ -1177,7 +1213,6 @@ nautilus_icons_view_icon_item_bounds (GnomeCanvasItem *item, double *x1, double while (emblem_layout_next (&emblem_layout, &emblem_pixbuf, &emblem_rect)) { art_irect_union (&total_rect, &total_rect, &emblem_rect); } - /* Add 2 pixels slop to each side. */ total_rect.x0 -= 2; @@ -1224,7 +1259,7 @@ nautilus_icons_view_icon_item_get_icon_rectangle (NautilusIconsViewIconItem *ite /* Get the rectangle of the icon only, in canvas coordinates. */ void -nautilus_icons_view_icon_item_get_icon_canvas_rectangle (NautilusIconsViewIconItem *item, +get_icon_canvas_rectangle (NautilusIconsViewIconItem *item, ArtIRect *rect) { double i2c[6]; @@ -1279,8 +1314,7 @@ hit_stretch_handle (NautilusIconsViewIconItem *item, } /* Quick check to see if the rect hits the icon at all. */ - nautilus_icons_view_icon_item_get_icon_canvas_rectangle - (item, &icon_rect); + get_icon_canvas_rectangle (item, &icon_rect); if (!nautilus_art_irect_hits_irect (probe_canvas_rect, &icon_rect)) { return FALSE; } diff --git a/libnautilus-extensions/nautilus-icons-view-icon-item.h b/libnautilus-extensions/nautilus-icons-view-icon-item.h index 51ef93641..a509cc9c6 100644 --- a/libnautilus-extensions/nautilus-icons-view-icon-item.h +++ b/libnautilus-extensions/nautilus-icons-view-icon-item.h @@ -53,6 +53,9 @@ struct NautilusIconsViewIconItem { struct NautilusIconsViewIconItemClass { GnomeCanvasItemClass parent_class; + + void (* bounds_changed) (NautilusIconsViewIconItem *item, + const ArtDRect *old_world_bounds); }; /* GtkObject */ @@ -77,6 +80,7 @@ gboolean nautilus_icons_view_icon_item_hit_test_stretch_handles (NautilusIcons const ArtPoint *world_point); void nautilus_icons_view_icon_item_get_icon_rectangle (NautilusIconsViewIconItem *item, ArtDRect *world_rectangle); +void nautilus_icons_view_icon_item_update_bounds (NautilusIconsViewIconItem *item); END_GNOME_DECLS diff --git a/libnautilus-extensions/nautilus-preferences.h b/libnautilus-extensions/nautilus-preferences.h index 779db6e95..1fa560e20 100644 --- a/libnautilus-extensions/nautilus-preferences.h +++ b/libnautilus-extensions/nautilus-preferences.h @@ -82,10 +82,10 @@ typedef struct typedef struct { - const char **enum_names; - const char **enum_descriptions; - const int *enum_values; - guint num_entries; + const char * const *enum_names; + const char * const *enum_descriptions; + const int *enum_values; + guint num_entries; } NautilusPreferencesEnumData; GtkType nautilus_preferences_get_type (void); diff --git a/libnautilus-private/gnome-icon-container-grid.c b/libnautilus-private/gnome-icon-container-grid.c index 601b7e36b..004b37f36 100644 --- a/libnautilus-private/gnome-icon-container-grid.c +++ b/libnautilus-private/gnome-icon-container-grid.c @@ -24,13 +24,18 @@ */ #include <config.h> -#include <string.h> - #include "gnome-icon-container-grid.h" +#include <string.h> +#include <math.h> +#include "nautilus-gnome-extensions.h" + #define INITIAL_GRID_WIDTH 64 #define INITIAL_GRID_HEIGHT 64 +#define GRID_CELL_WIDTH 80 +#define GRID_CELL_HEIGHT 80 + GnomeIconContainerGrid * gnome_icon_container_grid_new (void) { @@ -54,7 +59,7 @@ void gnome_icon_container_grid_clear (GnomeIconContainerGrid *grid) { GList **p; - guint i, j; + int i, j; p = grid->elems; for (j = 0; j < grid->height; j++) { @@ -82,22 +87,11 @@ gnome_icon_container_grid_destroy (GnomeIconContainerGrid *grid) GList ** gnome_icon_container_grid_get_element_ptr (GnomeIconContainerGrid *grid, - guint x, guint y) + int x, int y) { return &grid->elems[y * grid->alloc_width + x]; } -#if 0 - -GList * -gnome_icon_container_grid_get_element (GnomeIconContainerGrid *grid, - guint x, guint y) -{ - return *gnome_icon_container_grid_get_element_ptr (grid, x, y); -} - -#endif - /* This is admittedly a bit lame. * * Instead of re-allocating the grid from scratch and copying the values, we @@ -106,12 +100,12 @@ gnome_icon_container_grid_get_element (GnomeIconContainerGrid *grid, */ static void resize_allocation (GnomeIconContainerGrid *grid, - guint new_alloc_width, - guint new_alloc_height) + int new_alloc_width, + int new_alloc_height) { GList **new_elems; - guint i, j; - guint new_alloc_size; + int i, j; + int new_alloc_size; if (new_alloc_width == 0 || new_alloc_height == 0) { g_free (grid->elems); @@ -129,7 +123,7 @@ resize_allocation (GnomeIconContainerGrid *grid, memset (new_elems, 0, sizeof (*new_elems) * new_alloc_size); } else { GList **sp, **dp; - guint copy_width, copy_height; + int copy_width, copy_height; /* Copy existing elements into the new array. */ @@ -155,7 +149,7 @@ resize_allocation (GnomeIconContainerGrid *grid, /* If there are other lines left, zero them as well. */ if (i < new_alloc_height) { - guint elems_left; + int elems_left; elems_left = new_alloc_size - (dp - new_elems); memset (dp, 0, sizeof (*new_elems) * elems_left); @@ -173,8 +167,8 @@ static void update_first_free_forward (GnomeIconContainerGrid *grid) { GList **p; - guint start_x, start_y; - guint x, y; + int start_x, start_y; + int x, y; if (grid->first_free_x == -1) { start_x = start_y = 0; @@ -211,7 +205,7 @@ update_first_free_forward (GnomeIconContainerGrid *grid) void gnome_icon_container_grid_set_visible_width (GnomeIconContainerGrid *grid, - guint visible_width) + int visible_width) { if (visible_width > grid->visible_width && grid->height > 0 @@ -234,9 +228,9 @@ gnome_icon_container_grid_set_visible_width (GnomeIconContainerGrid *grid, void gnome_icon_container_grid_resize (GnomeIconContainerGrid *grid, - guint width, guint height) + int width, int height) { - guint new_alloc_width, new_alloc_height; + int new_alloc_width, new_alloc_height; if (width > grid->alloc_width || height > grid->alloc_height) { if (grid->alloc_width > 0) @@ -260,15 +254,16 @@ gnome_icon_container_grid_resize (GnomeIconContainerGrid *grid, grid->width = width; grid->height = height; - if (grid->visible_width != grid->width) + if (grid->visible_width != grid->width) { gnome_icon_container_grid_set_visible_width (grid, grid->width); + } } static void maybe_resize (GnomeIconContainerGrid *grid, - guint x, guint y) + int x, int y) { - guint new_width, new_height; + int new_width, new_height; if (x < grid->width && y < grid->height) return; @@ -286,33 +281,43 @@ maybe_resize (GnomeIconContainerGrid *grid, gnome_icon_container_grid_resize (grid, new_width, new_height); } -void -gnome_icon_container_grid_add (GnomeIconContainerGrid *grid, - GnomeIconContainerIcon *icon, - guint x, guint y) +static void +grid_add_one (GnomeIconContainerGrid *grid, + GnomeIconContainerIcon *icon, + int x, int y) { GList **elem_ptr; + if (x < 0 || y < 0) { + /* FIXME: Can't handle negative coordinates. */ + return; + } + maybe_resize (grid, x, y); elem_ptr = gnome_icon_container_grid_get_element_ptr (grid, x, y); + g_assert (g_list_find (*elem_ptr, icon) == NULL); *elem_ptr = g_list_prepend (*elem_ptr, icon); - if (x == grid->first_free_x && y == grid->first_free_y) + if (x == grid->first_free_x && y == grid->first_free_y) { update_first_free_forward (grid); + } } -void -gnome_icon_container_grid_remove (GnomeIconContainerGrid *grid, - GnomeIconContainerIcon *icon, - guint x, guint y) +static void +grid_remove_one (GnomeIconContainerGrid *grid, + GnomeIconContainerIcon *icon, + int x, int y) { GList **elem_ptr; + + if (x < 0 || y < 0) { + /* FIXME: Can't handle negative coordinates. */ + return; + } elem_ptr = gnome_icon_container_grid_get_element_ptr (grid, x, y); - - g_return_if_fail (*elem_ptr != NULL); - + g_assert (g_list_find (*elem_ptr, icon) != NULL); *elem_ptr = g_list_remove (*elem_ptr, icon); if (*elem_ptr == NULL) { @@ -325,46 +330,83 @@ gnome_icon_container_grid_remove (GnomeIconContainerGrid *grid, } } +static void +add_or_remove (GnomeIconContainerGrid *grid, + GnomeIconContainerIcon *icon, + gboolean add) +{ + int x, y; + + /* Add/remove to all the overlapped grid squares. */ + for (x = icon->grid_rectangle.x0; x < icon->grid_rectangle.x1; x++) { + for (y = icon->grid_rectangle.y0; y < icon->grid_rectangle.y1; y++) { + if (add) { + grid_add_one (grid, icon, x, y); + } else { + grid_remove_one (grid, icon, x, y); + } + } + } +} + void -gnome_icon_container_grid_add_auto (GnomeIconContainerGrid *grid, - GnomeIconContainerIcon *icon, - guint *x_return, guint *y_return) +gnome_icon_container_grid_add (GnomeIconContainerGrid *grid, + GnomeIconContainerIcon *icon) { - GList **empty_elem_ptr; + ArtDRect world_bounds; + + /* Figure out how big the icon is. */ + nautilus_gnome_canvas_item_get_world_bounds + (GNOME_CANVAS_ITEM (icon->item), &world_bounds); + + /* Compute grid bounds for the icon. */ + icon->grid_rectangle.x0 = floor (world_bounds.x0 / GRID_CELL_WIDTH); + icon->grid_rectangle.y0 = floor (world_bounds.y0 / GRID_CELL_HEIGHT); + icon->grid_rectangle.x1 = ceil (world_bounds.x1 / GRID_CELL_WIDTH); + icon->grid_rectangle.y1 = ceil (world_bounds.y1 / GRID_CELL_HEIGHT); + + add_or_remove (grid, icon, TRUE); +} - if (grid->first_free_x < 0 || grid->first_free_y < 0 - || grid->height == 0 || grid->width == 0) { - /* No empty element: add a row. */ - gnome_icon_container_grid_resize (grid, MAX (grid->width, 1), grid->height + 1); - grid->first_free_x = 0; - grid->first_free_y = grid->height - 1; - } +void +gnome_icon_container_grid_remove (GnomeIconContainerGrid *grid, + GnomeIconContainerIcon *icon) +{ + add_or_remove (grid, icon, FALSE); +} - empty_elem_ptr = gnome_icon_container_grid_get_element_ptr (grid, - grid->first_free_x, - grid->first_free_y); +void +gnome_icon_container_grid_get_position (GnomeIconContainerGrid *grid, + GnomeIconContainerIcon *icon, + int *x_return, int *y_return) +{ + int grid_x, grid_y; - *empty_elem_ptr = g_list_prepend (*empty_elem_ptr, icon); + g_return_if_fail (grid != NULL); + g_return_if_fail (x_return != NULL); + g_return_if_fail (y_return != NULL); - if (x_return != NULL) - *x_return = grid->first_free_x; - if (y_return != NULL) - *y_return = grid->first_free_y; + if (grid->first_free_x < 0 || grid->first_free_y < 0 + || grid->height == 0 || grid->width == 0) { + grid_x = 0; + grid_y = grid->height; + } else { + grid_x = grid->first_free_x; + grid_y = grid->first_free_y; + } - update_first_free_forward (grid); + gnome_icon_container_grid_to_world (grid, + grid_x, grid_y, + x_return, y_return); } void -gnome_icon_container_world_to_grid (GnomeIconContainer *container, +gnome_icon_container_world_to_grid (GnomeIconContainerGrid *grid, int world_x, int world_y, - guint *grid_x_return, guint *grid_y_return) + int *grid_x_return, int *grid_y_return) { - GnomeIconContainerDetails *details; - - details = container->details; - if (grid_x_return != NULL) { if (world_x < 0) *grid_x_return = 0; @@ -381,14 +423,10 @@ gnome_icon_container_world_to_grid (GnomeIconContainer *container, } void -gnome_icon_container_grid_to_world (GnomeIconContainer *container, - guint grid_x, guint grid_y, +gnome_icon_container_grid_to_world (GnomeIconContainerGrid *grid, + int grid_x, int grid_y, int *world_x_return, int *world_y_return) { - GnomeIconContainerDetails *details; - - details = container->details; - if (world_x_return != NULL) *world_x_return = grid_x * GNOME_ICON_CONTAINER_CELL_WIDTH (container); @@ -401,17 +439,12 @@ gnome_icon_container_grid_to_world (GnomeIconContainer *container, /* Find the "first" icon (in left-to-right, top-to-bottom order) in `container'. */ GnomeIconContainerIcon * -gnome_icon_container_grid_find_first (GnomeIconContainer *container, +gnome_icon_container_grid_find_first (GnomeIconContainerGrid *grid, gboolean selected_only) { - GnomeIconContainerDetails *details; - GnomeIconContainerGrid *grid; GnomeIconContainerIcon *first; GList **p; - guint i, j; - - details = container->details; - grid = details->grid; + int i, j; if (grid->width == 0 || grid->height == 0) return NULL; @@ -445,17 +478,13 @@ gnome_icon_container_grid_find_first (GnomeIconContainer *container, } GnomeIconContainerIcon * -gnome_icon_container_grid_find_last (GnomeIconContainer *container, gboolean selected_only) +gnome_icon_container_grid_find_last (GnomeIconContainerGrid *grid, + gboolean selected_only) { - GnomeIconContainerDetails *details; - GnomeIconContainerGrid *grid; GnomeIconContainerIcon *last; GList **p; int i, j; - details = container->details; - grid = details->grid; - last = NULL; if (grid->height == 0 || grid->width == 0) diff --git a/libnautilus-private/gnome-icon-container-grid.h b/libnautilus-private/gnome-icon-container-grid.h index 6be050684..6dc859605 100644 --- a/libnautilus-private/gnome-icon-container-grid.h +++ b/libnautilus-private/gnome-icon-container-grid.h @@ -27,18 +27,18 @@ struct GnomeIconContainerGrid { /* Size of the grid. */ - guint width, height; + int width, height; /* This is the width that we can actually use for finding an empty * position. */ - guint visible_width; + int visible_width; /* Array of grid elements. */ GList **elems; /* Size of the allocated array. */ - guint alloc_width, alloc_height; + int alloc_width, alloc_height; /* Position of the first free cell (used to speed up progressive * updates). If negative, there is no free cell. @@ -47,39 +47,41 @@ struct GnomeIconContainerGrid { }; -GnomeIconContainerGrid *gnome_icon_container_grid_new (void); -void gnome_icon_container_grid_destroy (GnomeIconContainerGrid *grid); -void gnome_icon_container_grid_clear (GnomeIconContainerGrid *grid); -void gnome_icon_container_grid_add (GnomeIconContainerGrid *grid, - GnomeIconContainerIcon *icon, - guint x, - guint y); -void gnome_icon_container_grid_add_auto (GnomeIconContainerGrid *grid, - GnomeIconContainerIcon *icon, - guint *x_return, guint *y_return); -void gnome_icon_container_grid_remove (GnomeIconContainerGrid *grid, - GnomeIconContainerIcon *icon, - guint x, - guint y); -void gnome_icon_container_grid_set_visible_width (GnomeIconContainerGrid *grid, - guint visible_width); -void gnome_icon_container_grid_resize (GnomeIconContainerGrid *grid, - guint width, guint height); - -GList ** gnome_icon_container_grid_get_element_ptr (GnomeIconContainerGrid *grid, - guint x, - guint y); -GnomeIconContainerIcon *gnome_icon_container_grid_find_first (GnomeIconContainer *container, - gboolean selected_only); -GnomeIconContainerIcon *gnome_icon_container_grid_find_last (GnomeIconContainer *container, - gboolean selected_only); -void gnome_icon_container_world_to_grid (GnomeIconContainer *container, - int world_x, - int world_y, - guint *grid_x, - guint *grid_y); -void gnome_icon_container_grid_to_world (GnomeIconContainer *container, - guint grid_x, - guint grid_y, - int *world_x, - int *world_y); +GnomeIconContainerGrid *gnome_icon_container_grid_new (void); +void gnome_icon_container_grid_destroy (GnomeIconContainerGrid *grid); +void gnome_icon_container_grid_clear (GnomeIconContainerGrid *grid); + +/* getting icons in and out of the grid */ +void gnome_icon_container_grid_add (GnomeIconContainerGrid *grid, + GnomeIconContainerIcon *icon); +void gnome_icon_container_grid_remove (GnomeIconContainerGrid *grid, + GnomeIconContainerIcon *icon); + +void gnome_icon_container_grid_get_position (GnomeIconContainerGrid *grid, + GnomeIconContainerIcon *icon, + int *world_x, + int *world_y); + +void gnome_icon_container_grid_set_visible_width (GnomeIconContainerGrid *grid, + int visible_width); +void gnome_icon_container_grid_resize (GnomeIconContainerGrid *grid, + int width, + int height); +GList ** gnome_icon_container_grid_get_element_ptr (GnomeIconContainerGrid *grid, + int grid_x, + int grid_y); +GnomeIconContainerIcon *gnome_icon_container_grid_find_first (GnomeIconContainerGrid *grid, + gboolean selected_only); +GnomeIconContainerIcon *gnome_icon_container_grid_find_last (GnomeIconContainerGrid *grid, + gboolean selected_only); + +void gnome_icon_container_world_to_grid (GnomeIconContainerGrid *container, + int world_x, + int world_y, + int *grid_x, + int *grid_y); +void gnome_icon_container_grid_to_world (GnomeIconContainerGrid *grid, + int grid_x, + int grid_y, + int *world_x, + int *world_y); diff --git a/libnautilus-private/gnome-icon-container-private.h b/libnautilus-private/gnome-icon-container-private.h index 19252add2..e253c3b99 100644 --- a/libnautilus-private/gnome-icon-container-private.h +++ b/libnautilus-private/gnome-icon-container-private.h @@ -33,6 +33,9 @@ /* An Icon. */ typedef struct { + /* Object represented by this icon. */ + GnomeIconContainerIconData *data; + /* Canvas item for the icon. */ NautilusIconsViewIconItem *item; @@ -54,7 +57,8 @@ typedef struct { /* Whether this item was selected before rubberbanding. */ gboolean was_selected_before_rubberband : 1; - GnomeIconContainerIconData *data; + /* Grid space occupied by this icon. */ + ArtIRect grid_rectangle; } GnomeIconContainerIcon; diff --git a/libnautilus-private/gnome-icon-container.c b/libnautilus-private/gnome-icon-container.c index bb69377e1..6cdea9740 100644 --- a/libnautilus-private/gnome-icon-container.c +++ b/libnautilus-private/gnome-icon-container.c @@ -367,7 +367,7 @@ make_icon_visible (GnomeIconContainer *container, } static gboolean -kbd_icon_visibility_timeout_cb (gpointer data) +kbd_icon_visibility_timeout_callback (gpointer data) { GnomeIconContainer *container; @@ -408,7 +408,7 @@ schedule_kbd_icon_visibility (GnomeIconContainer *container) details->kbd_icon_visibility_timer_id = gtk_timeout_add (KBD_ICON_VISIBILITY_TIMEOUT, - kbd_icon_visibility_timeout_cb, + kbd_icon_visibility_timeout_callback, container); } @@ -623,14 +623,12 @@ unselect_all (GnomeIconContainer *container) void gnome_icon_container_move_icon (GnomeIconContainer *container, - GnomeIconContainerIcon *icon, - int x, int y, double scale_x, double scale_y, gboolean raise) + GnomeIconContainerIcon *icon, + int x, int y, + double scale_x, double scale_y, + gboolean raise) { GnomeIconContainerDetails *details; - guint old_grid_x, old_grid_y; - int old_x_offset, old_y_offset; - guint new_grid_x, new_grid_y; - int new_x_offset, new_y_offset; gboolean emit_signal; details = container->details; @@ -638,39 +636,6 @@ gnome_icon_container_move_icon (GnomeIconContainer *container, emit_signal = FALSE; if (x != icon->x || y != icon->y) { - gnome_icon_container_world_to_grid (container, icon->x, icon->y, &old_grid_x, &old_grid_y); - old_x_offset = (int)icon->x % GNOME_ICON_CONTAINER_CELL_WIDTH (container); - old_y_offset = (int)icon->y % GNOME_ICON_CONTAINER_CELL_HEIGHT (container); - - gnome_icon_container_world_to_grid (container, x, y, &new_grid_x, &new_grid_y); - new_x_offset = x % GNOME_ICON_CONTAINER_CELL_WIDTH (container); - new_y_offset = y % GNOME_ICON_CONTAINER_CELL_HEIGHT (container); - - gnome_icon_container_grid_remove (details->grid, icon, old_grid_x, old_grid_y); - if (old_x_offset > 0) { - gnome_icon_container_grid_remove (details->grid, icon, - old_grid_x + 1, old_grid_y); - } - if (old_y_offset > 0) { - gnome_icon_container_grid_remove (details->grid, icon, - old_grid_x, old_grid_y + 1); - } - if (old_x_offset > 0 && old_y_offset > 0) { - gnome_icon_container_grid_remove (details->grid, icon, - old_grid_x + 1, old_grid_y + 1); - } - - gnome_icon_container_grid_add (details->grid, icon, new_grid_x, new_grid_y); - if (new_x_offset > 0) { - gnome_icon_container_grid_add (details->grid, icon, new_grid_x + 1, new_grid_y); - } - if (new_y_offset > 0) { - gnome_icon_container_grid_add (details->grid, icon, new_grid_x, new_grid_y + 1); - } - if (new_x_offset > 0 && new_y_offset > 0) { - gnome_icon_container_grid_add (details->grid, icon, new_grid_x + 1, new_grid_y + 1); - } - icon_set_position (icon, x, y); /* Update the keyboard selection indicator. */ @@ -750,21 +715,21 @@ rubberband_select (GnomeIconContainer *container, { GList **p; GnomeIconContainerGrid *grid; - guint curr_grid_x1, curr_grid_y1; - guint curr_grid_x2, curr_grid_y2; - guint prev_grid_x1, prev_grid_y1; - guint prev_grid_x2, prev_grid_y2; - guint grid_x1, grid_y1; - guint grid_x2, grid_y2; - guint i, j; + int curr_grid_x1, curr_grid_y1; + int curr_grid_x2, curr_grid_y2; + int prev_grid_x1, prev_grid_y1; + int prev_grid_x2, prev_grid_y2; + int grid_x1, grid_y1; + int grid_x2, grid_y2; + int i, j; gboolean selection_changed; grid = container->details->grid; - gnome_icon_container_world_to_grid (container, curr_x1, curr_y1, &curr_grid_x1, &curr_grid_y1); - gnome_icon_container_world_to_grid (container, curr_x2, curr_y2, &curr_grid_x2, &curr_grid_y2); - gnome_icon_container_world_to_grid (container, prev_x1, prev_y1, &prev_grid_x1, &prev_grid_y1); - gnome_icon_container_world_to_grid (container, prev_x2, prev_y2, &prev_grid_x2, &prev_grid_y2); + gnome_icon_container_world_to_grid (container->details->grid, curr_x1, curr_y1, &curr_grid_x1, &curr_grid_y1); + gnome_icon_container_world_to_grid (container->details->grid, curr_x2, curr_y2, &curr_grid_x2, &curr_grid_y2); + gnome_icon_container_world_to_grid (container->details->grid, prev_x1, prev_y1, &prev_grid_x1, &prev_grid_y1); + gnome_icon_container_world_to_grid (container->details->grid, prev_x2, prev_y2, &prev_grid_x2, &prev_grid_y2); grid_x1 = MIN (curr_grid_x1, prev_grid_x1); grid_x2 = MAX (curr_grid_x2, prev_grid_x2); @@ -794,7 +759,7 @@ rubberband_select (GnomeIconContainer *container, } static int -rubberband_timeout_cb (gpointer data) +rubberband_timeout_callback (gpointer data) { GnomeIconContainer *container; GtkWidget *widget; @@ -928,7 +893,7 @@ start_rubberbanding (GnomeIconContainer *container, if (band_info->timer_id == 0) { band_info->timer_id = gtk_timeout_add (RUBBERBAND_TIMEOUT_INTERVAL, - rubberband_timeout_cb, + rubberband_timeout_callback, container); } @@ -990,7 +955,7 @@ kbd_home (GnomeIconContainer *container, { GnomeIconContainerIcon *first; - first = gnome_icon_container_grid_find_first (container, FALSE); + first = gnome_icon_container_grid_find_first (container->details->grid, FALSE); if (first != NULL) { kbd_move_to (container, first, event); } @@ -1002,7 +967,7 @@ kbd_end (GnomeIconContainer *container, { GnomeIconContainerIcon *last; - last = gnome_icon_container_grid_find_last (container, FALSE); + last = gnome_icon_container_grid_find_last (container->details->grid, FALSE); if (last != NULL) { kbd_move_to (container, last, event); } @@ -1035,7 +1000,7 @@ kbd_left (GnomeIconContainer *container, GnomeIconContainerGrid *grid; GnomeIconContainerIcon *nearmost; GList **e; - guint grid_x, grid_y; + int grid_x, grid_y; int x, y; int max_x; @@ -1048,18 +1013,18 @@ kbd_left (GnomeIconContainer *container, GnomeIconContainerIcon *first; first = gnome_icon_container_grid_find_first - (container, has_multiple_selection (container)); + (container->details->grid, has_multiple_selection (container)); if (first != NULL) { kbd_move_to (container, first, event); } return; } - gnome_icon_container_world_to_grid (container, + gnome_icon_container_world_to_grid (container->details->grid, details->kbd_current->x, details->kbd_current->y, &grid_x, &grid_y); - gnome_icon_container_grid_to_world (container, grid_x, grid_y, &x, &y); + gnome_icon_container_grid_to_world (container->details->grid, grid_x, grid_y, &x, &y); e = gnome_icon_container_grid_get_element_ptr (grid, 0, grid_y); nearmost = NULL; @@ -1106,7 +1071,7 @@ kbd_left (GnomeIconContainer *container, grid_x = grid->width - 1; max_x = G_MAXINT; - gnome_icon_container_grid_to_world (container, grid_x, 0, &x, NULL); + gnome_icon_container_grid_to_world (container->details->grid, grid_x, 0, &x, NULL); e -= grid->alloc_width; grid_y--; @@ -1122,7 +1087,7 @@ kbd_up (GnomeIconContainer *container, GnomeIconContainerGrid *grid; GnomeIconContainerIcon *nearmost; GList **e; - guint grid_x, grid_y; + int grid_x, grid_y; int x, y; details = container->details; @@ -1134,18 +1099,18 @@ kbd_up (GnomeIconContainer *container, GnomeIconContainerIcon *first; first = gnome_icon_container_grid_find_first - (container, has_multiple_selection (container)); + (container->details->grid, has_multiple_selection (container)); if (first != NULL) { kbd_move_to (container, first, event); } return; } - gnome_icon_container_world_to_grid (container, + gnome_icon_container_world_to_grid (container->details->grid, details->kbd_current->x, details->kbd_current->y, &grid_x, &grid_y); - gnome_icon_container_grid_to_world (container, grid_x, grid_y, &x, &y); + gnome_icon_container_grid_to_world (container->details->grid, grid_x, grid_y, &x, &y); e = gnome_icon_container_grid_get_element_ptr (grid, grid_x, grid_y); nearmost = NULL; @@ -1197,7 +1162,7 @@ kbd_right (GnomeIconContainer *container, GnomeIconContainerGrid *grid; GnomeIconContainerIcon *nearmost; GList **e; - guint grid_x, grid_y; + int grid_x, grid_y; int x, y; int min_x; @@ -1210,18 +1175,18 @@ kbd_right (GnomeIconContainer *container, GnomeIconContainerIcon *last; last = gnome_icon_container_grid_find_last - (container, has_multiple_selection (container)); + (container->details->grid, has_multiple_selection (container)); if (last != NULL) { kbd_move_to (container, last, event); } return; } - gnome_icon_container_world_to_grid (container, + gnome_icon_container_world_to_grid (container->details->grid, details->kbd_current->x, details->kbd_current->y, &grid_x, &grid_y); - gnome_icon_container_grid_to_world (container, grid_x, grid_y, &x, &y); + gnome_icon_container_grid_to_world (container->details->grid, grid_x, grid_y, &x, &y); e = gnome_icon_container_grid_get_element_ptr (grid, 0, grid_y); nearmost = NULL; @@ -1276,7 +1241,7 @@ kbd_down (GnomeIconContainer *container, GnomeIconContainerGrid *grid; GnomeIconContainerIcon *nearmost; GList **e; - guint grid_x, grid_y; + int grid_x, grid_y; int x, y; details = container->details; @@ -1288,18 +1253,18 @@ kbd_down (GnomeIconContainer *container, GnomeIconContainerIcon *last; last = gnome_icon_container_grid_find_last - (container, has_multiple_selection (container)); + (container->details->grid, has_multiple_selection (container)); if (last != NULL) { kbd_move_to (container, last, event); } return; } - gnome_icon_container_world_to_grid (container, + gnome_icon_container_world_to_grid (container->details->grid, details->kbd_current->x, details->kbd_current->y, &grid_x, &grid_y); - gnome_icon_container_grid_to_world (container, grid_x, grid_y, &x, &y); + gnome_icon_container_grid_to_world (container->details->grid, grid_x, grid_y, &x, &y); e = gnome_icon_container_grid_get_element_ptr (grid, grid_x, grid_y); nearmost = NULL; @@ -1350,7 +1315,7 @@ kbd_space (GnomeIconContainer *container, GnomeIconContainerIcon *icon; icon = gnome_icon_container_grid_find_first - (container, + (container->details->grid, get_first_selected_icon (container) != NULL); set_kbd_current (container, icon, TRUE); } @@ -1425,7 +1390,7 @@ size_allocate (GtkWidget *widget, container = GNOME_ICON_CONTAINER (widget); grid = container->details->grid; - gnome_icon_container_world_to_grid (container, + gnome_icon_container_world_to_grid (container->details->grid, allocation->width, 0, &visible_width, &visible_height); @@ -2048,7 +2013,7 @@ handle_icon_button_press (GnomeIconContainer *container, } static int -item_event_cb (GnomeCanvasItem *item, +item_event_callback (GnomeCanvasItem *item, GdkEvent *event, gpointer data) { @@ -2123,12 +2088,9 @@ gnome_icon_container_clear (GnomeIconContainer *container) static void icon_destroy (GnomeIconContainer *container, - GnomeIconContainerIcon *icon) + GnomeIconContainerIcon *icon) { GnomeIconContainerDetails *details; - gint icon_x, icon_y; - gint grid_x, grid_y; - gint x_offset, y_offset; gboolean was_selected; details = container->details; @@ -2142,27 +2104,7 @@ icon_destroy (GnomeIconContainer *container, set_kbd_current (container, NULL, FALSE); } - icon_x = icon->x; - icon_y = icon->y; - gnome_icon_container_world_to_grid (container, icon_x, icon_y, &grid_x, &grid_y); - gnome_icon_container_grid_remove(details->grid, icon, grid_x, grid_y); - - x_offset = icon_x % GNOME_ICON_CONTAINER_CELL_WIDTH (container); - y_offset = icon_y % GNOME_ICON_CONTAINER_CELL_HEIGHT (container); - - if (x_offset > 0) { - gnome_icon_container_grid_remove (details->grid, icon, - grid_x + 1, grid_y); - } - if (y_offset > 0) { - gnome_icon_container_grid_remove (details->grid, icon, - grid_x, grid_y + 1); - } - if (x_offset > 0 && y_offset > 0) { - gnome_icon_container_grid_remove (details->grid, icon, - grid_x + 1, grid_y + 1); - } - + gnome_icon_container_grid_remove (details->grid, icon); g_hash_table_remove (details->canvas_item_to_icon, icon->item); icon_free (icon); @@ -2193,6 +2135,24 @@ activate_selected_items (GnomeIconContainer *container) } static void +bounds_changed_callback (NautilusIconsViewIconItem *item, + const ArtDRect *old_bounds, + GnomeIconContainer *container) +{ + GnomeIconContainerIcon *icon; + + g_assert (NAUTILUS_IS_ICONS_VIEW_ICON_ITEM (item)); + g_assert (old_bounds != NULL); + g_assert (GNOME_IS_ICON_CONTAINER (container)); + + icon = g_hash_table_lookup (container->details->canvas_item_to_icon, item); + g_assert (icon != NULL); + + gnome_icon_container_grid_remove (container->details->grid, icon); + gnome_icon_container_grid_add (container->details->grid, icon); +} + +static void setup_icon_in_container (GnomeIconContainer *container, GnomeIconContainerIcon *icon) { @@ -2204,10 +2164,16 @@ setup_icon_in_container (GnomeIconContainer *container, details->num_icons++; g_hash_table_insert (details->canvas_item_to_icon, icon->item, icon); + + nautilus_icons_view_icon_item_update_bounds (icon->item); + gnome_icon_container_grid_add (details->grid, icon); + icon_show (icon); gtk_signal_connect (GTK_OBJECT (icon->item), "event", - GTK_SIGNAL_FUNC (item_event_cb), container); + GTK_SIGNAL_FUNC (item_event_callback), container); + gtk_signal_connect (GTK_OBJECT (icon->item), "bounds_changed", + GTK_SIGNAL_FUNC (bounds_changed_callback), container); } static void @@ -2294,11 +2260,11 @@ update_icon (GnomeIconContainer *container, GnomeIconContainerIcon *icon) void gnome_icon_container_add (GnomeIconContainer *container, GnomeIconContainerIconData *data, - int x, int y, double scale_x, double scale_y) + int x, int y, + double scale_x, double scale_y) { GnomeIconContainerDetails *details; GnomeIconContainerIcon *new_icon; - guint grid_x, grid_y; g_return_if_fail (GNOME_IS_ICON_CONTAINER (container)); g_return_if_fail (data != NULL); @@ -2310,20 +2276,6 @@ gnome_icon_container_add (GnomeIconContainer *container, new_icon->scale_x = scale_x; new_icon->scale_y = scale_y; - gnome_icon_container_world_to_grid (container, x, y, &grid_x, &grid_y); - gnome_icon_container_grid_add (details->grid, new_icon, grid_x, grid_y); - - if (x % GNOME_ICON_CONTAINER_CELL_WIDTH (container) > 0) { - gnome_icon_container_grid_add (details->grid, new_icon, grid_x + 1, grid_y); - } - if (y % GNOME_ICON_CONTAINER_CELL_HEIGHT (container) > 0) { - gnome_icon_container_grid_add (details->grid, new_icon, grid_x, grid_y + 1); - } - if (x % GNOME_ICON_CONTAINER_CELL_WIDTH (container) > 0 - && y % GNOME_ICON_CONTAINER_CELL_HEIGHT (container) > 0) { - gnome_icon_container_grid_add (details->grid, new_icon, grid_x + 1, grid_y + 1); - } - setup_icon_in_container (container, new_icon); request_idle (container); @@ -2344,7 +2296,6 @@ gnome_icon_container_add_auto (GnomeIconContainer *container, GnomeIconContainerIconData *data) { GnomeIconContainerIcon *new_icon; - guint grid_x, grid_y; int x, y; g_return_if_fail (GNOME_IS_ICON_CONTAINER (container)); @@ -2352,10 +2303,9 @@ gnome_icon_container_add_auto (GnomeIconContainer *container, new_icon = icon_new (container, data); - gnome_icon_container_grid_add_auto (container->details->grid, - new_icon, - &grid_x, &grid_y); - gnome_icon_container_grid_to_world (container, grid_x, grid_y, &x, &y); + gnome_icon_container_grid_get_position (container->details->grid, + new_icon, + &x, &y); icon_set_position (new_icon, x, y); @@ -2501,11 +2451,11 @@ gnome_icon_container_relayout (GnomeIconContainer *container) GnomeIconContainerDetails *details; GnomeIconContainerGrid *old_grid, *new_grid; GList **sp, **dp; - guint i, j; - guint dx, dy; - guint sx, sy; - guint cols; - guint lines; + int i, j; + int dx, dy; + int sx, sy; + int cols; + int lines; g_return_if_fail (GNOME_IS_ICON_CONTAINER (container)); @@ -2615,8 +2565,8 @@ gnome_icon_container_line_up (GnomeIconContainer *container) GnomeIconContainerGrid *grid; GnomeIconContainerGrid *new_grid; GList **p, **q; - guint new_grid_width; - guint i, j, k, m; + int new_grid_width; + int i, j, k, m; int x, y, dx; g_return_if_fail (GNOME_IS_ICON_CONTAINER (container)); @@ -2635,12 +2585,12 @@ gnome_icon_container_line_up (GnomeIconContainer *container) p = grid->elems; x = y = 0; for (i = 0; i < grid->height; i++) { - guint line_width; + int line_width; line_width = grid->width; for (j = 0; j < grid->width; j++) { GList *e; - guint count; + int count; count = 0; for (e = p[j]; e != NULL; e = e->next) { @@ -2682,7 +2632,7 @@ gnome_icon_container_line_up (GnomeIconContainer *container) m = 0; for (j = 0; j < grid->width; j++) { GList *e; - guint count; + int count; /* Make sure the icons are sorted by increasing X position. */ diff --git a/libnautilus-private/nautilus-global-preferences.c b/libnautilus-private/nautilus-global-preferences.c index a08ff9836..79fca8ca1 100644 --- a/libnautilus-private/nautilus-global-preferences.c +++ b/libnautilus-private/nautilus-global-preferences.c @@ -22,7 +22,9 @@ Authors: Ramiro Estrugo <ramiro@eazel.com> */ +#include <config.h> #include "nautilus-global-preferences.h" + #include <nautilus-widgets/nautilus-preferences-group.h> #include <nautilus-widgets/nautilus-preferences-item.h> #include <nautilus-widgets/nautilus-preferences-dialog.h> @@ -35,24 +37,24 @@ /* Private stuff */ static GtkWidget *global_preferences_create_dialog (void); -static GtkWidget *global_prefernces_create_enum_group (GtkWidget *pane, - const gchar *group_title, - const gchar *pref_name); -static GtkWidget *global_preferences_create_check_group (GtkWidget *pane, - const gchar *group_title, - const gchar *pref_names[], - guint num_prefs); +static GtkWidget *global_preferences_create_enum_group (GtkWidget *pane, + const char *group_title, + const char *pref_name); +static GtkWidget *global_preferences_create_check_group (GtkWidget *pane, + const char *group_title, + const char * const pref_names[], + guint num_prefs); static GtkWidget *global_preferences_get_dialog (void); static void global_preferences_register_static (NautilusPreferences *prefs); static void global_preferences_register_dynamic (NautilusPreferences *prefs); -static const gchar *global_preferences_window_option_pref_names[] = +static const char * const global_preferences_window_option_pref_names[] = { NAUTILUS_PREFERENCES_WINDOW_ALWAYS_NEW, NAUTILUS_PREFERENCES_WINDOW_SEARCH_EXISTING }; -static const gchar *global_preferences_meta_view_names[] = +static const char * const global_preferences_meta_view_names[] = { NAUTILUS_PREFERENCES_META_VIEWS_SHOW_ANNOTATIONS, NAUTILUS_PREFERENCES_META_VIEWS_SHOW_HELP_CONTENTS, @@ -62,7 +64,7 @@ static const gchar *global_preferences_meta_view_names[] = NAUTILUS_PREFERENCES_META_VIEWS_SHOW_WEB_SEARCH }; -static const gchar * global_preferences_user_level_names[] = +static const char * const global_preferences_user_level_names[] = { "novice", "intermediate", @@ -70,7 +72,7 @@ static const gchar * global_preferences_user_level_names[] = "ettore" }; -static const gchar * global_preferences_user_level_descriptions[] = +static const char * const global_preferences_user_level_descriptions[] = { "Novice", "Intermediate", @@ -86,7 +88,7 @@ static const gint global_preferences_user_level_values[] = NAUTILUS_USER_LEVEL_ETTORE }; -static NautilusPreferencesEnumData global_preferences_user_level_data = +static const NautilusPreferencesEnumData global_preferences_user_level_data = { global_preferences_user_level_names, global_preferences_user_level_descriptions, @@ -94,7 +96,7 @@ static NautilusPreferencesEnumData global_preferences_user_level_data = NAUTILUS_N_ELEMENTS (global_preferences_user_level_names) }; -static NautilusPreferencesInfo global_preferences_static_info[] = +static const NautilusPreferencesInfo global_preferences_static_info[] = { { NAUTILUS_PREFERENCES_USER_LEVEL, @@ -151,7 +153,7 @@ global_preferences_create_dialog (void) "User Level", "User Level Something"); - global_prefernces_create_enum_group (panes[0], + global_preferences_create_enum_group (panes[0], "User Level", NAUTILUS_PREFERENCES_USER_LEVEL); @@ -177,10 +179,10 @@ global_preferences_create_dialog (void) } static GtkWidget * -global_preferences_create_check_group (GtkWidget *pane, - const gchar *group_title, - const gchar *pref_names[], - guint num_prefs) +global_preferences_create_check_group (GtkWidget *pane, + const char *group_title, + const char * const pref_names[], + guint num_prefs) { GtkWidget *group; guint i; @@ -209,9 +211,9 @@ global_preferences_create_check_group (GtkWidget *pane, } static GtkWidget * -global_prefernces_create_enum_group (GtkWidget *pane, - const gchar *group_title, - const gchar *pref_name) +global_preferences_create_enum_group (GtkWidget *pane, + const char *group_title, + const char *pref_name) { GtkWidget *group; GtkWidget *item; diff --git a/libnautilus-private/nautilus-gnome-extensions.c b/libnautilus-private/nautilus-gnome-extensions.c index 54749922b..b0d5c7ac3 100644 --- a/libnautilus-private/nautilus-gnome-extensions.c +++ b/libnautilus-private/nautilus-gnome-extensions.c @@ -86,3 +86,82 @@ nautilus_art_irect_hits_irect (const ArtIRect *rect_a, art_irect_intersect (&intersection, rect_a, rect_b); return !art_irect_empty (&intersection); } + +gboolean +nautilus_art_irect_equal (const ArtIRect *rect_a, + const ArtIRect *rect_b) +{ + g_return_val_if_fail (rect_a != NULL, FALSE); + g_return_val_if_fail (rect_b != NULL, FALSE); + + return rect_a->x0 == rect_b->x0 + && rect_a->y0 == rect_b->y0 + && rect_a->x1 == rect_b->x1 + && rect_a->y1 == rect_b->y1; +} + +gboolean +nautilus_art_drect_equal (const ArtDRect *rect_a, + const ArtDRect *rect_b) +{ + g_return_val_if_fail (rect_a != NULL, FALSE); + g_return_val_if_fail (rect_b != NULL, FALSE); + + return rect_a->x0 == rect_b->x0 + && rect_a->y0 == rect_b->y0 + && rect_a->x1 == rect_b->x1 + && rect_a->y1 == rect_b->y1; +} + +void +nautilus_gnome_canvas_item_get_current_canvas_bounds (GnomeCanvasItem *item, + ArtIRect *bounds) +{ + g_return_if_fail (GNOME_IS_CANVAS_ITEM (item)); + g_return_if_fail (bounds != NULL); + + bounds->x0 = item->x1; + bounds->y0 = item->y1; + bounds->x1 = item->x2; + bounds->y1 = item->y2; +} + +void +nautilus_gnome_canvas_item_request_redraw (GnomeCanvasItem *item) +{ + g_return_if_fail (GNOME_IS_CANVAS_ITEM (item)); + + gnome_canvas_request_redraw (item->canvas, + item->x1, item->y1, + item->x2, item->y2); +} + +void +nautilus_gnome_canvas_request_redraw_rectangle (GnomeCanvas *canvas, + const ArtIRect *canvas_rectangle) +{ + g_return_if_fail (GNOME_IS_CANVAS (canvas)); + + gnome_canvas_request_redraw (canvas, + canvas_rectangle->x0, canvas_rectangle->y0, + canvas_rectangle->x1, canvas_rectangle->y1); +} + +void +nautilus_gnome_canvas_item_get_world_bounds (GnomeCanvasItem *item, + ArtDRect *world_bounds) +{ + gnome_canvas_item_get_bounds (item, + &world_bounds->x0, + &world_bounds->y0, + &world_bounds->x1, + &world_bounds->y1); + if (item->parent != NULL) { + gnome_canvas_item_i2w (item->parent, + &world_bounds->x0, + &world_bounds->y0); + gnome_canvas_item_i2w (item->parent, + &world_bounds->x1, + &world_bounds->y1); + } +} diff --git a/libnautilus-private/nautilus-gnome-extensions.h b/libnautilus-private/nautilus-gnome-extensions.h index 3c3d40af9..df921e08f 100644 --- a/libnautilus-private/nautilus-gnome-extensions.h +++ b/libnautilus-private/nautilus-gnome-extensions.h @@ -29,13 +29,42 @@ #include <libgnomeui/gnome-canvas.h> -void nautilus_gnome_canvas_world_to_canvas_rectangle (GnomeCanvas *canvas, - const ArtDRect *world_rectangle, - ArtIRect *canvas_rectangle); -void nautilus_gnome_canvas_world_to_window_rectangle (GnomeCanvas *canvas, - const ArtDRect *world_rectangle, - ArtIRect *window_rectangle); -gboolean nautilus_art_irect_hits_irect (const ArtIRect *rect_a, - const ArtIRect *rect_b); +/* This is more handy than gnome_canvas_item_get_bounds because it + * always returns the bounds * in world coordinates and it returns + * them in a single rectangle. + */ +void nautilus_gnome_canvas_item_get_world_bounds (GnomeCanvasItem *item, + ArtDRect *world_bounds); + +/* This returns the current canvas bounds as computed by update. + * It's not as "up to date" as get_bounds, which is accurate even + * before an update happens. + */ +void nautilus_gnome_canvas_item_get_current_canvas_bounds (GnomeCanvasItem *item, + ArtIRect *canvas_bounds); + +/* Convenience functions for doing things with whole rectangles. */ +void nautilus_gnome_canvas_world_to_canvas_rectangle (GnomeCanvas *canvas, + const ArtDRect *world_rectangle, + ArtIRect *canvas_rectangle); +void nautilus_gnome_canvas_world_to_window_rectangle (GnomeCanvas *canvas, + const ArtDRect *world_rectangle, + ArtIRect *window_rectangle); +void nautilus_gnome_canvas_request_redraw_rectangle (GnomeCanvas *canvas, + const ArtIRect *canvas_rectangle); + +/* Requests the entire object be redrawn. + * Normally, you use request_update when calling from outside the canvas item + * code. This is for within canvas item code. + */ +void nautilus_gnome_canvas_item_request_redraw (GnomeCanvasItem *item); + +/* More functions for ArtIRect and ArtDRect. */ +gboolean nautilus_art_irect_hits_irect (const ArtIRect *rect_a, + const ArtIRect *rect_b); +gboolean nautilus_art_irect_equal (const ArtIRect *rect_a, + const ArtIRect *rect_b); +gboolean nautilus_art_drect_equal (const ArtDRect *rect_a, + const ArtDRect *rect_b); #endif /* NAUTILUS_GNOME_EXTENSIONS_H */ diff --git a/libnautilus-private/nautilus-icons-view-icon-item.c b/libnautilus-private/nautilus-icons-view-icon-item.c index b56c4a41c..1ba9febe2 100644 --- a/libnautilus-private/nautilus-icons-view-icon-item.c +++ b/libnautilus-private/nautilus-icons-view-icon-item.c @@ -28,6 +28,7 @@ #include <math.h> #include <string.h> #include <stdio.h> +#include <gtk/gtksignal.h> #include <gdk-pixbuf/gdk-pixbuf.h> #include <libart_lgpl/art_rgb_pixbuf_affine.h> #include <libgnomeui/gnome-canvas-util.h> @@ -90,6 +91,12 @@ typedef struct { GList *emblem; } EmblemLayout; +enum { + BOUNDS_CHANGED, + LAST_SIGNAL +}; +static guint signals[LAST_SIGNAL]; + /* constants */ #define MAX_TEXT_WIDTH 80 @@ -100,65 +107,65 @@ static char stipple_bits[] = { 0x02, 0x01 }; static GdkFont *embedded_text_font; /* GtkObject */ -static void nautilus_icons_view_icon_item_initialize_class (NautilusIconsViewIconItemClass *class); -static void nautilus_icons_view_icon_item_initialize (NautilusIconsViewIconItem *item); -static void nautilus_icons_view_icon_item_destroy (GtkObject *object); -static int nautilus_icons_view_icon_item_event (GnomeCanvasItem *item, - GdkEvent *event); -static void nautilus_icons_view_icon_item_set_arg (GtkObject *object, - GtkArg *arg, - guint arg_id); -static void nautilus_icons_view_icon_item_get_arg (GtkObject *object, - GtkArg *arg, - guint arg_id); +static void nautilus_icons_view_icon_item_initialize_class (NautilusIconsViewIconItemClass *class); +static void nautilus_icons_view_icon_item_initialize (NautilusIconsViewIconItem *item); +static void nautilus_icons_view_icon_item_destroy (GtkObject *object); +static int nautilus_icons_view_icon_item_event (GnomeCanvasItem *item, + GdkEvent *event); +static void nautilus_icons_view_icon_item_set_arg (GtkObject *object, + GtkArg *arg, + guint arg_id); +static void nautilus_icons_view_icon_item_get_arg (GtkObject *object, + GtkArg *arg, + guint arg_id); /* GnomeCanvasItem */ -static void nautilus_icons_view_icon_item_update (GnomeCanvasItem *item, - double *affine, - ArtSVP *clip_path, - int flags); -static void nautilus_icons_view_icon_item_draw (GnomeCanvasItem *item, - GdkDrawable *drawable, - int x, - int y, - int width, - int height); -static double nautilus_icons_view_icon_item_point (GnomeCanvasItem *item, - double x, - double y, - int cx, - int cy, - GnomeCanvasItem **actual_item); -static void nautilus_icons_view_icon_item_bounds (GnomeCanvasItem *item, - double *x1, - double *y1, - double *x2, - double *y2); +static void nautilus_icons_view_icon_item_update (GnomeCanvasItem *item, + double *affine, + ArtSVP *clip_path, + int flags); +static void nautilus_icons_view_icon_item_draw (GnomeCanvasItem *item, + GdkDrawable *drawable, + int x, + int y, + int width, + int height); +static double nautilus_icons_view_icon_item_point (GnomeCanvasItem *item, + double x, + double y, + int cx, + int cy, + GnomeCanvasItem **actual_item); +static void nautilus_icons_view_icon_item_bounds (GnomeCanvasItem *item, + double *x1, + double *y1, + double *x2, + double *y2); /* private */ -static void draw_or_measure_text_box (GnomeCanvasItem *item, - GdkDrawable *drawable, - int icon_left, - int icon_bottom); -static void nautilus_icons_view_draw_text_box (GnomeCanvasItem *item, - GdkDrawable *drawable, - int icon_left, - int icon_bottom); -static void nautilus_icons_view_measure_text_box (GnomeCanvasItem *item); -static void nautilus_icons_view_icon_item_get_icon_canvas_rectangle (NautilusIconsViewIconItem *item, - ArtIRect *rect); -static void emblem_layout_reset (EmblemLayout *layout, - NautilusIconsViewIconItem *icon_item, - const ArtIRect *icon_rect); -static gboolean emblem_layout_next (EmblemLayout *layout, - GdkPixbuf **emblem_pixbuf, - ArtIRect *emblem_rect); -static void draw_pixbuf (GdkPixbuf *pixbuf, - GdkDrawable *drawable, - int x, - int y); -static gboolean hit_stretch_handle (NautilusIconsViewIconItem *item, - const ArtIRect *canvas_rect); +static void draw_or_measure_label_text (NautilusIconsViewIconItem *item, + GdkDrawable *drawable, + int icon_left, + int icon_bottom); +static void draw_label_text (NautilusIconsViewIconItem *item, + GdkDrawable *drawable, + int icon_left, + int icon_bottom); +static void measure_label_text (NautilusIconsViewIconItem *item); +static void get_icon_canvas_rectangle (NautilusIconsViewIconItem *item, + ArtIRect *rect); +static void emblem_layout_reset (EmblemLayout *layout, + NautilusIconsViewIconItem *icon_item, + const ArtIRect *icon_rect); +static gboolean emblem_layout_next (EmblemLayout *layout, + GdkPixbuf **emblem_pixbuf, + ArtIRect *emblem_rect); +static void draw_pixbuf (GdkPixbuf *pixbuf, + GdkDrawable *drawable, + int x, + int y); +static gboolean hit_stretch_handle (NautilusIconsViewIconItem *item, + const ArtIRect *canvas_rect); NAUTILUS_DEFINE_CLASS_BOILERPLATE (NautilusIconsViewIconItem, nautilus_icons_view_icon_item, GNOME_TYPE_CANVAS_ITEM) @@ -172,30 +179,43 @@ nautilus_icons_view_icon_item_initialize_class (NautilusIconsViewIconItemClass * object_class = GTK_OBJECT_CLASS (class); item_class = GNOME_CANVAS_ITEM_CLASS (class); - gtk_object_add_arg_type ("NautilusIconsViewIconItem::text", + gtk_object_add_arg_type ("NautilusIconsViewIconItem::text", GTK_TYPE_STRING, GTK_ARG_READWRITE, ARG_TEXT); - gtk_object_add_arg_type ("NautilusIconsViewIconItem::font", + gtk_object_add_arg_type ("NautilusIconsViewIconItem::font", GTK_TYPE_BOXED, GTK_ARG_READWRITE, ARG_FONT); - gtk_object_add_arg_type ("NautilusIconsViewIconItem::highlighted_for_selection", + gtk_object_add_arg_type ("NautilusIconsViewIconItem::highlighted_for_selection", GTK_TYPE_BOOL, GTK_ARG_READWRITE, ARG_HIGHLIGHTED_FOR_SELECTION); - gtk_object_add_arg_type ("NautilusIconsViewIconItem::highlighted_for_keyboard_selection", + gtk_object_add_arg_type ("NautilusIconsViewIconItem::highlighted_for_keyboard_selection", GTK_TYPE_BOOL, GTK_ARG_READWRITE, ARG_HIGHLIGHTED_FOR_KEYBOARD_SELECTION); - gtk_object_add_arg_type ("NautilusIconsViewIconItem::highlighted_for_drop", + gtk_object_add_arg_type ("NautilusIconsViewIconItem::highlighted_for_drop", GTK_TYPE_BOOL, GTK_ARG_READWRITE, ARG_HIGHLIGHTED_FOR_DROP); - gtk_object_add_arg_type ("NautilusIconsViewIconItem::text_source", + gtk_object_add_arg_type ("NautilusIconsViewIconItem::text_source", GTK_TYPE_STRING, GTK_ARG_READWRITE, ARG_TEXT_SOURCE); object_class->destroy = nautilus_icons_view_icon_item_destroy; object_class->set_arg = nautilus_icons_view_icon_item_set_arg; object_class->get_arg = nautilus_icons_view_icon_item_get_arg; + signals[BOUNDS_CHANGED] + = gtk_signal_new ("bounds_changed", + GTK_RUN_LAST, + object_class->type, + GTK_SIGNAL_OFFSET (NautilusIconsViewIconItemClass, + bounds_changed), + gtk_marshal_NONE__POINTER, + GTK_TYPE_NONE, 1, + GTK_TYPE_POINTER); + + gtk_object_class_add_signals (object_class, signals, LAST_SIGNAL); + item_class->update = nautilus_icons_view_icon_item_update; item_class->draw = nautilus_icons_view_icon_item_draw; item_class->point = nautilus_icons_view_icon_item_point; item_class->bounds = nautilus_icons_view_icon_item_bounds; item_class->event = nautilus_icons_view_icon_item_event; - + stipple = gdk_bitmap_create_from_data (NULL, stipple_bits, 2, 2); + /* FIXME: the font shouldn't be hard-wired like this */ embedded_text_font = gdk_font_load("-bitstream-charter-medium-r-normal-*-9-*-*-*-*-*-*-*"); } @@ -483,36 +503,52 @@ recompute_bounding_box (NautilusIconsViewIconItem *icon_item) item->y2 = bottom_right.y; } -/* Update handler for the icon canvas item. */ -static void -nautilus_icons_view_icon_item_update (GnomeCanvasItem *item, double *affine, ArtSVP *clip_path, int flags) +void +nautilus_icons_view_icon_item_update_bounds (NautilusIconsViewIconItem *item) { - NautilusIconsViewIconItem *icon_item; - NautilusIconsViewIconItemDetails *details; + ArtIRect before, after; - icon_item = NAUTILUS_ICONS_VIEW_ICON_ITEM (item); - details = icon_item->details; + /* Compute new bounds. */ + nautilus_gnome_canvas_item_get_current_canvas_bounds + (GNOME_CANVAS_ITEM (item), &before); + recompute_bounding_box (item); + nautilus_gnome_canvas_item_get_current_canvas_bounds + (GNOME_CANVAS_ITEM (item), &after); - /* Make sure the text box measurements are set up - * before recalculating the bounding box. - */ - gnome_canvas_request_redraw (item->canvas, item->x1, item->y1, item->x2, item->y2); - nautilus_icons_view_measure_text_box (item); - recompute_bounding_box (icon_item); - gnome_canvas_request_redraw (item->canvas, item->x1, item->y1, item->x2, item->y2); - - NAUTILUS_CALL_PARENT_CLASS (GNOME_CANVAS_ITEM_CLASS, update, (item, affine, clip_path, flags)); + /* If the bounds didn't change, we are done. */ + if (nautilus_art_irect_equal (&before, &after)) { + return; + } + + /* Send out the bounds_changed signal and queue a redraw. */ + nautilus_gnome_canvas_request_redraw_rectangle + (GNOME_CANVAS_ITEM (item)->canvas, &before); + gtk_signal_emit (GTK_OBJECT (item), + signals[BOUNDS_CHANGED]); + nautilus_gnome_canvas_item_request_redraw + (GNOME_CANVAS_ITEM (item)); } +/* Update handler for the icon canvas item. */ +static void +nautilus_icons_view_icon_item_update (GnomeCanvasItem *item, + double *affine, + ArtSVP *clip_path, + int flags) +{ + nautilus_icons_view_icon_item_update_bounds (NAUTILUS_ICONS_VIEW_ICON_ITEM (item)); + nautilus_gnome_canvas_item_request_redraw (item); + NAUTILUS_CALL_PARENT_CLASS (GNOME_CANVAS_ITEM_CLASS, update, (item, affine, clip_path, flags)); +} /* Rendering */ /* Draw the text in a box, using gnomelib routines. */ static void -draw_or_measure_text_box (GnomeCanvasItem* item, - GdkDrawable *drawable, - int icon_left, - int icon_bottom) +draw_or_measure_label_text (NautilusIconsViewIconItem *item, + GdkDrawable *drawable, + int icon_left, + int icon_bottom) { NautilusIconsViewIconItemDetails *details; int width_so_far, height_so_far; @@ -524,7 +560,7 @@ draw_or_measure_text_box (GnomeCanvasItem* item, const char *text_piece; int i; - details = NAUTILUS_ICONS_VIEW_ICON_ITEM (item)->details; + details = item->details; if (details->font == NULL || details->text == NULL || details->text[0] == '\0') { details->text_height = 0; @@ -537,10 +573,10 @@ draw_or_measure_text_box (GnomeCanvasItem* item, if (drawable != NULL) { icon_width = details->pixbuf == NULL ? 0 : gdk_pixbuf_get_width (details->pixbuf); - gc = gdk_gc_new (item->canvas->layout.bin_window); + gc = gdk_gc_new (GNOME_CANVAS_ITEM (item)->canvas->layout.bin_window); } - max_text_width = floor (MAX_TEXT_WIDTH * item->canvas->pixels_per_unit); + max_text_width = floor (MAX_TEXT_WIDTH * GNOME_CANVAS_ITEM (item)->canvas->pixels_per_unit); pieces = g_strsplit (details->text, "\n", 0); for (i = 0; (text_piece = pieces[i]) != NULL; i++) { @@ -610,16 +646,16 @@ draw_or_measure_text_box (GnomeCanvasItem* item, } static void -nautilus_icons_view_measure_text_box (GnomeCanvasItem* item) +measure_label_text (NautilusIconsViewIconItem *item) { - draw_or_measure_text_box (item, NULL, 0, 0); + draw_or_measure_label_text (item, NULL, 0, 0); } static void -nautilus_icons_view_draw_text_box (GnomeCanvasItem* item, GdkDrawable *drawable, +draw_label_text (NautilusIconsViewIconItem *item, GdkDrawable *drawable, int icon_left, int icon_bottom) { - draw_or_measure_text_box (item, drawable, icon_left, icon_bottom); + draw_or_measure_label_text (item, drawable, icon_left, icon_bottom); } /* utility routine to draw the mini-text inside text files */ @@ -958,8 +994,7 @@ nautilus_icons_view_icon_item_draw (GnomeCanvasItem *item, GdkDrawable *drawable } /* Compute icon rectangle in drawable coordinates. */ - nautilus_icons_view_icon_item_get_icon_canvas_rectangle - (icon_item, &icon_rect); + get_icon_canvas_rectangle (icon_item, &icon_rect); icon_rect.x0 -= x; icon_rect.y0 -= y; icon_rect.x1 -= x; @@ -988,7 +1023,7 @@ nautilus_icons_view_icon_item_draw (GnomeCanvasItem *item, GdkDrawable *drawable draw_embedded_text (item, drawable, &icon_rect); /* Draw the label text. */ - nautilus_icons_view_draw_text_box (item, drawable, icon_rect.x0, icon_rect.y1); + draw_label_text (icon_item, drawable, icon_rect.x0, icon_rect.y1); } /* handle events */ @@ -1093,8 +1128,7 @@ hit_test (NautilusIconsViewIconItem *icon_item, const ArtIRect *canvas_rect) } /* Check for hit in the icon. */ - nautilus_icons_view_icon_item_get_icon_canvas_rectangle - (icon_item, &icon_rect); + get_icon_canvas_rectangle (icon_item, &icon_rect); if (hit_test_pixbuf (details->pixbuf, &icon_rect, canvas_rect)) { return TRUE; } @@ -1157,6 +1191,8 @@ nautilus_icons_view_icon_item_bounds (GnomeCanvasItem *item, double *x1, double icon_item = NAUTILUS_ICONS_VIEW_ICON_ITEM (item); details = icon_item->details; + measure_label_text (icon_item); + /* Compute icon rectangle. */ icon_rect.x0 = 0; icon_rect.y0 = 0; @@ -1177,7 +1213,6 @@ nautilus_icons_view_icon_item_bounds (GnomeCanvasItem *item, double *x1, double while (emblem_layout_next (&emblem_layout, &emblem_pixbuf, &emblem_rect)) { art_irect_union (&total_rect, &total_rect, &emblem_rect); } - /* Add 2 pixels slop to each side. */ total_rect.x0 -= 2; @@ -1224,7 +1259,7 @@ nautilus_icons_view_icon_item_get_icon_rectangle (NautilusIconsViewIconItem *ite /* Get the rectangle of the icon only, in canvas coordinates. */ void -nautilus_icons_view_icon_item_get_icon_canvas_rectangle (NautilusIconsViewIconItem *item, +get_icon_canvas_rectangle (NautilusIconsViewIconItem *item, ArtIRect *rect) { double i2c[6]; @@ -1279,8 +1314,7 @@ hit_stretch_handle (NautilusIconsViewIconItem *item, } /* Quick check to see if the rect hits the icon at all. */ - nautilus_icons_view_icon_item_get_icon_canvas_rectangle - (item, &icon_rect); + get_icon_canvas_rectangle (item, &icon_rect); if (!nautilus_art_irect_hits_irect (probe_canvas_rect, &icon_rect)) { return FALSE; } diff --git a/libnautilus-private/nautilus-icons-view-icon-item.h b/libnautilus-private/nautilus-icons-view-icon-item.h index 51ef93641..a509cc9c6 100644 --- a/libnautilus-private/nautilus-icons-view-icon-item.h +++ b/libnautilus-private/nautilus-icons-view-icon-item.h @@ -53,6 +53,9 @@ struct NautilusIconsViewIconItem { struct NautilusIconsViewIconItemClass { GnomeCanvasItemClass parent_class; + + void (* bounds_changed) (NautilusIconsViewIconItem *item, + const ArtDRect *old_world_bounds); }; /* GtkObject */ @@ -77,6 +80,7 @@ gboolean nautilus_icons_view_icon_item_hit_test_stretch_handles (NautilusIcons const ArtPoint *world_point); void nautilus_icons_view_icon_item_get_icon_rectangle (NautilusIconsViewIconItem *item, ArtDRect *world_rectangle); +void nautilus_icons_view_icon_item_update_bounds (NautilusIconsViewIconItem *item); END_GNOME_DECLS diff --git a/libnautilus-private/nautilus-preferences.h b/libnautilus-private/nautilus-preferences.h index 779db6e95..1fa560e20 100644 --- a/libnautilus-private/nautilus-preferences.h +++ b/libnautilus-private/nautilus-preferences.h @@ -82,10 +82,10 @@ typedef struct typedef struct { - const char **enum_names; - const char **enum_descriptions; - const int *enum_values; - guint num_entries; + const char * const *enum_names; + const char * const *enum_descriptions; + const int *enum_values; + guint num_entries; } NautilusPreferencesEnumData; GtkType nautilus_preferences_get_type (void); diff --git a/libnautilus/gnome-icon-container-grid.c b/libnautilus/gnome-icon-container-grid.c index 601b7e36b..004b37f36 100644 --- a/libnautilus/gnome-icon-container-grid.c +++ b/libnautilus/gnome-icon-container-grid.c @@ -24,13 +24,18 @@ */ #include <config.h> -#include <string.h> - #include "gnome-icon-container-grid.h" +#include <string.h> +#include <math.h> +#include "nautilus-gnome-extensions.h" + #define INITIAL_GRID_WIDTH 64 #define INITIAL_GRID_HEIGHT 64 +#define GRID_CELL_WIDTH 80 +#define GRID_CELL_HEIGHT 80 + GnomeIconContainerGrid * gnome_icon_container_grid_new (void) { @@ -54,7 +59,7 @@ void gnome_icon_container_grid_clear (GnomeIconContainerGrid *grid) { GList **p; - guint i, j; + int i, j; p = grid->elems; for (j = 0; j < grid->height; j++) { @@ -82,22 +87,11 @@ gnome_icon_container_grid_destroy (GnomeIconContainerGrid *grid) GList ** gnome_icon_container_grid_get_element_ptr (GnomeIconContainerGrid *grid, - guint x, guint y) + int x, int y) { return &grid->elems[y * grid->alloc_width + x]; } -#if 0 - -GList * -gnome_icon_container_grid_get_element (GnomeIconContainerGrid *grid, - guint x, guint y) -{ - return *gnome_icon_container_grid_get_element_ptr (grid, x, y); -} - -#endif - /* This is admittedly a bit lame. * * Instead of re-allocating the grid from scratch and copying the values, we @@ -106,12 +100,12 @@ gnome_icon_container_grid_get_element (GnomeIconContainerGrid *grid, */ static void resize_allocation (GnomeIconContainerGrid *grid, - guint new_alloc_width, - guint new_alloc_height) + int new_alloc_width, + int new_alloc_height) { GList **new_elems; - guint i, j; - guint new_alloc_size; + int i, j; + int new_alloc_size; if (new_alloc_width == 0 || new_alloc_height == 0) { g_free (grid->elems); @@ -129,7 +123,7 @@ resize_allocation (GnomeIconContainerGrid *grid, memset (new_elems, 0, sizeof (*new_elems) * new_alloc_size); } else { GList **sp, **dp; - guint copy_width, copy_height; + int copy_width, copy_height; /* Copy existing elements into the new array. */ @@ -155,7 +149,7 @@ resize_allocation (GnomeIconContainerGrid *grid, /* If there are other lines left, zero them as well. */ if (i < new_alloc_height) { - guint elems_left; + int elems_left; elems_left = new_alloc_size - (dp - new_elems); memset (dp, 0, sizeof (*new_elems) * elems_left); @@ -173,8 +167,8 @@ static void update_first_free_forward (GnomeIconContainerGrid *grid) { GList **p; - guint start_x, start_y; - guint x, y; + int start_x, start_y; + int x, y; if (grid->first_free_x == -1) { start_x = start_y = 0; @@ -211,7 +205,7 @@ update_first_free_forward (GnomeIconContainerGrid *grid) void gnome_icon_container_grid_set_visible_width (GnomeIconContainerGrid *grid, - guint visible_width) + int visible_width) { if (visible_width > grid->visible_width && grid->height > 0 @@ -234,9 +228,9 @@ gnome_icon_container_grid_set_visible_width (GnomeIconContainerGrid *grid, void gnome_icon_container_grid_resize (GnomeIconContainerGrid *grid, - guint width, guint height) + int width, int height) { - guint new_alloc_width, new_alloc_height; + int new_alloc_width, new_alloc_height; if (width > grid->alloc_width || height > grid->alloc_height) { if (grid->alloc_width > 0) @@ -260,15 +254,16 @@ gnome_icon_container_grid_resize (GnomeIconContainerGrid *grid, grid->width = width; grid->height = height; - if (grid->visible_width != grid->width) + if (grid->visible_width != grid->width) { gnome_icon_container_grid_set_visible_width (grid, grid->width); + } } static void maybe_resize (GnomeIconContainerGrid *grid, - guint x, guint y) + int x, int y) { - guint new_width, new_height; + int new_width, new_height; if (x < grid->width && y < grid->height) return; @@ -286,33 +281,43 @@ maybe_resize (GnomeIconContainerGrid *grid, gnome_icon_container_grid_resize (grid, new_width, new_height); } -void -gnome_icon_container_grid_add (GnomeIconContainerGrid *grid, - GnomeIconContainerIcon *icon, - guint x, guint y) +static void +grid_add_one (GnomeIconContainerGrid *grid, + GnomeIconContainerIcon *icon, + int x, int y) { GList **elem_ptr; + if (x < 0 || y < 0) { + /* FIXME: Can't handle negative coordinates. */ + return; + } + maybe_resize (grid, x, y); elem_ptr = gnome_icon_container_grid_get_element_ptr (grid, x, y); + g_assert (g_list_find (*elem_ptr, icon) == NULL); *elem_ptr = g_list_prepend (*elem_ptr, icon); - if (x == grid->first_free_x && y == grid->first_free_y) + if (x == grid->first_free_x && y == grid->first_free_y) { update_first_free_forward (grid); + } } -void -gnome_icon_container_grid_remove (GnomeIconContainerGrid *grid, - GnomeIconContainerIcon *icon, - guint x, guint y) +static void +grid_remove_one (GnomeIconContainerGrid *grid, + GnomeIconContainerIcon *icon, + int x, int y) { GList **elem_ptr; + + if (x < 0 || y < 0) { + /* FIXME: Can't handle negative coordinates. */ + return; + } elem_ptr = gnome_icon_container_grid_get_element_ptr (grid, x, y); - - g_return_if_fail (*elem_ptr != NULL); - + g_assert (g_list_find (*elem_ptr, icon) != NULL); *elem_ptr = g_list_remove (*elem_ptr, icon); if (*elem_ptr == NULL) { @@ -325,46 +330,83 @@ gnome_icon_container_grid_remove (GnomeIconContainerGrid *grid, } } +static void +add_or_remove (GnomeIconContainerGrid *grid, + GnomeIconContainerIcon *icon, + gboolean add) +{ + int x, y; + + /* Add/remove to all the overlapped grid squares. */ + for (x = icon->grid_rectangle.x0; x < icon->grid_rectangle.x1; x++) { + for (y = icon->grid_rectangle.y0; y < icon->grid_rectangle.y1; y++) { + if (add) { + grid_add_one (grid, icon, x, y); + } else { + grid_remove_one (grid, icon, x, y); + } + } + } +} + void -gnome_icon_container_grid_add_auto (GnomeIconContainerGrid *grid, - GnomeIconContainerIcon *icon, - guint *x_return, guint *y_return) +gnome_icon_container_grid_add (GnomeIconContainerGrid *grid, + GnomeIconContainerIcon *icon) { - GList **empty_elem_ptr; + ArtDRect world_bounds; + + /* Figure out how big the icon is. */ + nautilus_gnome_canvas_item_get_world_bounds + (GNOME_CANVAS_ITEM (icon->item), &world_bounds); + + /* Compute grid bounds for the icon. */ + icon->grid_rectangle.x0 = floor (world_bounds.x0 / GRID_CELL_WIDTH); + icon->grid_rectangle.y0 = floor (world_bounds.y0 / GRID_CELL_HEIGHT); + icon->grid_rectangle.x1 = ceil (world_bounds.x1 / GRID_CELL_WIDTH); + icon->grid_rectangle.y1 = ceil (world_bounds.y1 / GRID_CELL_HEIGHT); + + add_or_remove (grid, icon, TRUE); +} - if (grid->first_free_x < 0 || grid->first_free_y < 0 - || grid->height == 0 || grid->width == 0) { - /* No empty element: add a row. */ - gnome_icon_container_grid_resize (grid, MAX (grid->width, 1), grid->height + 1); - grid->first_free_x = 0; - grid->first_free_y = grid->height - 1; - } +void +gnome_icon_container_grid_remove (GnomeIconContainerGrid *grid, + GnomeIconContainerIcon *icon) +{ + add_or_remove (grid, icon, FALSE); +} - empty_elem_ptr = gnome_icon_container_grid_get_element_ptr (grid, - grid->first_free_x, - grid->first_free_y); +void +gnome_icon_container_grid_get_position (GnomeIconContainerGrid *grid, + GnomeIconContainerIcon *icon, + int *x_return, int *y_return) +{ + int grid_x, grid_y; - *empty_elem_ptr = g_list_prepend (*empty_elem_ptr, icon); + g_return_if_fail (grid != NULL); + g_return_if_fail (x_return != NULL); + g_return_if_fail (y_return != NULL); - if (x_return != NULL) - *x_return = grid->first_free_x; - if (y_return != NULL) - *y_return = grid->first_free_y; + if (grid->first_free_x < 0 || grid->first_free_y < 0 + || grid->height == 0 || grid->width == 0) { + grid_x = 0; + grid_y = grid->height; + } else { + grid_x = grid->first_free_x; + grid_y = grid->first_free_y; + } - update_first_free_forward (grid); + gnome_icon_container_grid_to_world (grid, + grid_x, grid_y, + x_return, y_return); } void -gnome_icon_container_world_to_grid (GnomeIconContainer *container, +gnome_icon_container_world_to_grid (GnomeIconContainerGrid *grid, int world_x, int world_y, - guint *grid_x_return, guint *grid_y_return) + int *grid_x_return, int *grid_y_return) { - GnomeIconContainerDetails *details; - - details = container->details; - if (grid_x_return != NULL) { if (world_x < 0) *grid_x_return = 0; @@ -381,14 +423,10 @@ gnome_icon_container_world_to_grid (GnomeIconContainer *container, } void -gnome_icon_container_grid_to_world (GnomeIconContainer *container, - guint grid_x, guint grid_y, +gnome_icon_container_grid_to_world (GnomeIconContainerGrid *grid, + int grid_x, int grid_y, int *world_x_return, int *world_y_return) { - GnomeIconContainerDetails *details; - - details = container->details; - if (world_x_return != NULL) *world_x_return = grid_x * GNOME_ICON_CONTAINER_CELL_WIDTH (container); @@ -401,17 +439,12 @@ gnome_icon_container_grid_to_world (GnomeIconContainer *container, /* Find the "first" icon (in left-to-right, top-to-bottom order) in `container'. */ GnomeIconContainerIcon * -gnome_icon_container_grid_find_first (GnomeIconContainer *container, +gnome_icon_container_grid_find_first (GnomeIconContainerGrid *grid, gboolean selected_only) { - GnomeIconContainerDetails *details; - GnomeIconContainerGrid *grid; GnomeIconContainerIcon *first; GList **p; - guint i, j; - - details = container->details; - grid = details->grid; + int i, j; if (grid->width == 0 || grid->height == 0) return NULL; @@ -445,17 +478,13 @@ gnome_icon_container_grid_find_first (GnomeIconContainer *container, } GnomeIconContainerIcon * -gnome_icon_container_grid_find_last (GnomeIconContainer *container, gboolean selected_only) +gnome_icon_container_grid_find_last (GnomeIconContainerGrid *grid, + gboolean selected_only) { - GnomeIconContainerDetails *details; - GnomeIconContainerGrid *grid; GnomeIconContainerIcon *last; GList **p; int i, j; - details = container->details; - grid = details->grid; - last = NULL; if (grid->height == 0 || grid->width == 0) diff --git a/libnautilus/gnome-icon-container-grid.h b/libnautilus/gnome-icon-container-grid.h index 6be050684..6dc859605 100644 --- a/libnautilus/gnome-icon-container-grid.h +++ b/libnautilus/gnome-icon-container-grid.h @@ -27,18 +27,18 @@ struct GnomeIconContainerGrid { /* Size of the grid. */ - guint width, height; + int width, height; /* This is the width that we can actually use for finding an empty * position. */ - guint visible_width; + int visible_width; /* Array of grid elements. */ GList **elems; /* Size of the allocated array. */ - guint alloc_width, alloc_height; + int alloc_width, alloc_height; /* Position of the first free cell (used to speed up progressive * updates). If negative, there is no free cell. @@ -47,39 +47,41 @@ struct GnomeIconContainerGrid { }; -GnomeIconContainerGrid *gnome_icon_container_grid_new (void); -void gnome_icon_container_grid_destroy (GnomeIconContainerGrid *grid); -void gnome_icon_container_grid_clear (GnomeIconContainerGrid *grid); -void gnome_icon_container_grid_add (GnomeIconContainerGrid *grid, - GnomeIconContainerIcon *icon, - guint x, - guint y); -void gnome_icon_container_grid_add_auto (GnomeIconContainerGrid *grid, - GnomeIconContainerIcon *icon, - guint *x_return, guint *y_return); -void gnome_icon_container_grid_remove (GnomeIconContainerGrid *grid, - GnomeIconContainerIcon *icon, - guint x, - guint y); -void gnome_icon_container_grid_set_visible_width (GnomeIconContainerGrid *grid, - guint visible_width); -void gnome_icon_container_grid_resize (GnomeIconContainerGrid *grid, - guint width, guint height); - -GList ** gnome_icon_container_grid_get_element_ptr (GnomeIconContainerGrid *grid, - guint x, - guint y); -GnomeIconContainerIcon *gnome_icon_container_grid_find_first (GnomeIconContainer *container, - gboolean selected_only); -GnomeIconContainerIcon *gnome_icon_container_grid_find_last (GnomeIconContainer *container, - gboolean selected_only); -void gnome_icon_container_world_to_grid (GnomeIconContainer *container, - int world_x, - int world_y, - guint *grid_x, - guint *grid_y); -void gnome_icon_container_grid_to_world (GnomeIconContainer *container, - guint grid_x, - guint grid_y, - int *world_x, - int *world_y); +GnomeIconContainerGrid *gnome_icon_container_grid_new (void); +void gnome_icon_container_grid_destroy (GnomeIconContainerGrid *grid); +void gnome_icon_container_grid_clear (GnomeIconContainerGrid *grid); + +/* getting icons in and out of the grid */ +void gnome_icon_container_grid_add (GnomeIconContainerGrid *grid, + GnomeIconContainerIcon *icon); +void gnome_icon_container_grid_remove (GnomeIconContainerGrid *grid, + GnomeIconContainerIcon *icon); + +void gnome_icon_container_grid_get_position (GnomeIconContainerGrid *grid, + GnomeIconContainerIcon *icon, + int *world_x, + int *world_y); + +void gnome_icon_container_grid_set_visible_width (GnomeIconContainerGrid *grid, + int visible_width); +void gnome_icon_container_grid_resize (GnomeIconContainerGrid *grid, + int width, + int height); +GList ** gnome_icon_container_grid_get_element_ptr (GnomeIconContainerGrid *grid, + int grid_x, + int grid_y); +GnomeIconContainerIcon *gnome_icon_container_grid_find_first (GnomeIconContainerGrid *grid, + gboolean selected_only); +GnomeIconContainerIcon *gnome_icon_container_grid_find_last (GnomeIconContainerGrid *grid, + gboolean selected_only); + +void gnome_icon_container_world_to_grid (GnomeIconContainerGrid *container, + int world_x, + int world_y, + int *grid_x, + int *grid_y); +void gnome_icon_container_grid_to_world (GnomeIconContainerGrid *grid, + int grid_x, + int grid_y, + int *world_x, + int *world_y); diff --git a/libnautilus/gnome-icon-container-private.h b/libnautilus/gnome-icon-container-private.h index 19252add2..e253c3b99 100644 --- a/libnautilus/gnome-icon-container-private.h +++ b/libnautilus/gnome-icon-container-private.h @@ -33,6 +33,9 @@ /* An Icon. */ typedef struct { + /* Object represented by this icon. */ + GnomeIconContainerIconData *data; + /* Canvas item for the icon. */ NautilusIconsViewIconItem *item; @@ -54,7 +57,8 @@ typedef struct { /* Whether this item was selected before rubberbanding. */ gboolean was_selected_before_rubberband : 1; - GnomeIconContainerIconData *data; + /* Grid space occupied by this icon. */ + ArtIRect grid_rectangle; } GnomeIconContainerIcon; diff --git a/libnautilus/gnome-icon-container.c b/libnautilus/gnome-icon-container.c index bb69377e1..6cdea9740 100644 --- a/libnautilus/gnome-icon-container.c +++ b/libnautilus/gnome-icon-container.c @@ -367,7 +367,7 @@ make_icon_visible (GnomeIconContainer *container, } static gboolean -kbd_icon_visibility_timeout_cb (gpointer data) +kbd_icon_visibility_timeout_callback (gpointer data) { GnomeIconContainer *container; @@ -408,7 +408,7 @@ schedule_kbd_icon_visibility (GnomeIconContainer *container) details->kbd_icon_visibility_timer_id = gtk_timeout_add (KBD_ICON_VISIBILITY_TIMEOUT, - kbd_icon_visibility_timeout_cb, + kbd_icon_visibility_timeout_callback, container); } @@ -623,14 +623,12 @@ unselect_all (GnomeIconContainer *container) void gnome_icon_container_move_icon (GnomeIconContainer *container, - GnomeIconContainerIcon *icon, - int x, int y, double scale_x, double scale_y, gboolean raise) + GnomeIconContainerIcon *icon, + int x, int y, + double scale_x, double scale_y, + gboolean raise) { GnomeIconContainerDetails *details; - guint old_grid_x, old_grid_y; - int old_x_offset, old_y_offset; - guint new_grid_x, new_grid_y; - int new_x_offset, new_y_offset; gboolean emit_signal; details = container->details; @@ -638,39 +636,6 @@ gnome_icon_container_move_icon (GnomeIconContainer *container, emit_signal = FALSE; if (x != icon->x || y != icon->y) { - gnome_icon_container_world_to_grid (container, icon->x, icon->y, &old_grid_x, &old_grid_y); - old_x_offset = (int)icon->x % GNOME_ICON_CONTAINER_CELL_WIDTH (container); - old_y_offset = (int)icon->y % GNOME_ICON_CONTAINER_CELL_HEIGHT (container); - - gnome_icon_container_world_to_grid (container, x, y, &new_grid_x, &new_grid_y); - new_x_offset = x % GNOME_ICON_CONTAINER_CELL_WIDTH (container); - new_y_offset = y % GNOME_ICON_CONTAINER_CELL_HEIGHT (container); - - gnome_icon_container_grid_remove (details->grid, icon, old_grid_x, old_grid_y); - if (old_x_offset > 0) { - gnome_icon_container_grid_remove (details->grid, icon, - old_grid_x + 1, old_grid_y); - } - if (old_y_offset > 0) { - gnome_icon_container_grid_remove (details->grid, icon, - old_grid_x, old_grid_y + 1); - } - if (old_x_offset > 0 && old_y_offset > 0) { - gnome_icon_container_grid_remove (details->grid, icon, - old_grid_x + 1, old_grid_y + 1); - } - - gnome_icon_container_grid_add (details->grid, icon, new_grid_x, new_grid_y); - if (new_x_offset > 0) { - gnome_icon_container_grid_add (details->grid, icon, new_grid_x + 1, new_grid_y); - } - if (new_y_offset > 0) { - gnome_icon_container_grid_add (details->grid, icon, new_grid_x, new_grid_y + 1); - } - if (new_x_offset > 0 && new_y_offset > 0) { - gnome_icon_container_grid_add (details->grid, icon, new_grid_x + 1, new_grid_y + 1); - } - icon_set_position (icon, x, y); /* Update the keyboard selection indicator. */ @@ -750,21 +715,21 @@ rubberband_select (GnomeIconContainer *container, { GList **p; GnomeIconContainerGrid *grid; - guint curr_grid_x1, curr_grid_y1; - guint curr_grid_x2, curr_grid_y2; - guint prev_grid_x1, prev_grid_y1; - guint prev_grid_x2, prev_grid_y2; - guint grid_x1, grid_y1; - guint grid_x2, grid_y2; - guint i, j; + int curr_grid_x1, curr_grid_y1; + int curr_grid_x2, curr_grid_y2; + int prev_grid_x1, prev_grid_y1; + int prev_grid_x2, prev_grid_y2; + int grid_x1, grid_y1; + int grid_x2, grid_y2; + int i, j; gboolean selection_changed; grid = container->details->grid; - gnome_icon_container_world_to_grid (container, curr_x1, curr_y1, &curr_grid_x1, &curr_grid_y1); - gnome_icon_container_world_to_grid (container, curr_x2, curr_y2, &curr_grid_x2, &curr_grid_y2); - gnome_icon_container_world_to_grid (container, prev_x1, prev_y1, &prev_grid_x1, &prev_grid_y1); - gnome_icon_container_world_to_grid (container, prev_x2, prev_y2, &prev_grid_x2, &prev_grid_y2); + gnome_icon_container_world_to_grid (container->details->grid, curr_x1, curr_y1, &curr_grid_x1, &curr_grid_y1); + gnome_icon_container_world_to_grid (container->details->grid, curr_x2, curr_y2, &curr_grid_x2, &curr_grid_y2); + gnome_icon_container_world_to_grid (container->details->grid, prev_x1, prev_y1, &prev_grid_x1, &prev_grid_y1); + gnome_icon_container_world_to_grid (container->details->grid, prev_x2, prev_y2, &prev_grid_x2, &prev_grid_y2); grid_x1 = MIN (curr_grid_x1, prev_grid_x1); grid_x2 = MAX (curr_grid_x2, prev_grid_x2); @@ -794,7 +759,7 @@ rubberband_select (GnomeIconContainer *container, } static int -rubberband_timeout_cb (gpointer data) +rubberband_timeout_callback (gpointer data) { GnomeIconContainer *container; GtkWidget *widget; @@ -928,7 +893,7 @@ start_rubberbanding (GnomeIconContainer *container, if (band_info->timer_id == 0) { band_info->timer_id = gtk_timeout_add (RUBBERBAND_TIMEOUT_INTERVAL, - rubberband_timeout_cb, + rubberband_timeout_callback, container); } @@ -990,7 +955,7 @@ kbd_home (GnomeIconContainer *container, { GnomeIconContainerIcon *first; - first = gnome_icon_container_grid_find_first (container, FALSE); + first = gnome_icon_container_grid_find_first (container->details->grid, FALSE); if (first != NULL) { kbd_move_to (container, first, event); } @@ -1002,7 +967,7 @@ kbd_end (GnomeIconContainer *container, { GnomeIconContainerIcon *last; - last = gnome_icon_container_grid_find_last (container, FALSE); + last = gnome_icon_container_grid_find_last (container->details->grid, FALSE); if (last != NULL) { kbd_move_to (container, last, event); } @@ -1035,7 +1000,7 @@ kbd_left (GnomeIconContainer *container, GnomeIconContainerGrid *grid; GnomeIconContainerIcon *nearmost; GList **e; - guint grid_x, grid_y; + int grid_x, grid_y; int x, y; int max_x; @@ -1048,18 +1013,18 @@ kbd_left (GnomeIconContainer *container, GnomeIconContainerIcon *first; first = gnome_icon_container_grid_find_first - (container, has_multiple_selection (container)); + (container->details->grid, has_multiple_selection (container)); if (first != NULL) { kbd_move_to (container, first, event); } return; } - gnome_icon_container_world_to_grid (container, + gnome_icon_container_world_to_grid (container->details->grid, details->kbd_current->x, details->kbd_current->y, &grid_x, &grid_y); - gnome_icon_container_grid_to_world (container, grid_x, grid_y, &x, &y); + gnome_icon_container_grid_to_world (container->details->grid, grid_x, grid_y, &x, &y); e = gnome_icon_container_grid_get_element_ptr (grid, 0, grid_y); nearmost = NULL; @@ -1106,7 +1071,7 @@ kbd_left (GnomeIconContainer *container, grid_x = grid->width - 1; max_x = G_MAXINT; - gnome_icon_container_grid_to_world (container, grid_x, 0, &x, NULL); + gnome_icon_container_grid_to_world (container->details->grid, grid_x, 0, &x, NULL); e -= grid->alloc_width; grid_y--; @@ -1122,7 +1087,7 @@ kbd_up (GnomeIconContainer *container, GnomeIconContainerGrid *grid; GnomeIconContainerIcon *nearmost; GList **e; - guint grid_x, grid_y; + int grid_x, grid_y; int x, y; details = container->details; @@ -1134,18 +1099,18 @@ kbd_up (GnomeIconContainer *container, GnomeIconContainerIcon *first; first = gnome_icon_container_grid_find_first - (container, has_multiple_selection (container)); + (container->details->grid, has_multiple_selection (container)); if (first != NULL) { kbd_move_to (container, first, event); } return; } - gnome_icon_container_world_to_grid (container, + gnome_icon_container_world_to_grid (container->details->grid, details->kbd_current->x, details->kbd_current->y, &grid_x, &grid_y); - gnome_icon_container_grid_to_world (container, grid_x, grid_y, &x, &y); + gnome_icon_container_grid_to_world (container->details->grid, grid_x, grid_y, &x, &y); e = gnome_icon_container_grid_get_element_ptr (grid, grid_x, grid_y); nearmost = NULL; @@ -1197,7 +1162,7 @@ kbd_right (GnomeIconContainer *container, GnomeIconContainerGrid *grid; GnomeIconContainerIcon *nearmost; GList **e; - guint grid_x, grid_y; + int grid_x, grid_y; int x, y; int min_x; @@ -1210,18 +1175,18 @@ kbd_right (GnomeIconContainer *container, GnomeIconContainerIcon *last; last = gnome_icon_container_grid_find_last - (container, has_multiple_selection (container)); + (container->details->grid, has_multiple_selection (container)); if (last != NULL) { kbd_move_to (container, last, event); } return; } - gnome_icon_container_world_to_grid (container, + gnome_icon_container_world_to_grid (container->details->grid, details->kbd_current->x, details->kbd_current->y, &grid_x, &grid_y); - gnome_icon_container_grid_to_world (container, grid_x, grid_y, &x, &y); + gnome_icon_container_grid_to_world (container->details->grid, grid_x, grid_y, &x, &y); e = gnome_icon_container_grid_get_element_ptr (grid, 0, grid_y); nearmost = NULL; @@ -1276,7 +1241,7 @@ kbd_down (GnomeIconContainer *container, GnomeIconContainerGrid *grid; GnomeIconContainerIcon *nearmost; GList **e; - guint grid_x, grid_y; + int grid_x, grid_y; int x, y; details = container->details; @@ -1288,18 +1253,18 @@ kbd_down (GnomeIconContainer *container, GnomeIconContainerIcon *last; last = gnome_icon_container_grid_find_last - (container, has_multiple_selection (container)); + (container->details->grid, has_multiple_selection (container)); if (last != NULL) { kbd_move_to (container, last, event); } return; } - gnome_icon_container_world_to_grid (container, + gnome_icon_container_world_to_grid (container->details->grid, details->kbd_current->x, details->kbd_current->y, &grid_x, &grid_y); - gnome_icon_container_grid_to_world (container, grid_x, grid_y, &x, &y); + gnome_icon_container_grid_to_world (container->details->grid, grid_x, grid_y, &x, &y); e = gnome_icon_container_grid_get_element_ptr (grid, grid_x, grid_y); nearmost = NULL; @@ -1350,7 +1315,7 @@ kbd_space (GnomeIconContainer *container, GnomeIconContainerIcon *icon; icon = gnome_icon_container_grid_find_first - (container, + (container->details->grid, get_first_selected_icon (container) != NULL); set_kbd_current (container, icon, TRUE); } @@ -1425,7 +1390,7 @@ size_allocate (GtkWidget *widget, container = GNOME_ICON_CONTAINER (widget); grid = container->details->grid; - gnome_icon_container_world_to_grid (container, + gnome_icon_container_world_to_grid (container->details->grid, allocation->width, 0, &visible_width, &visible_height); @@ -2048,7 +2013,7 @@ handle_icon_button_press (GnomeIconContainer *container, } static int -item_event_cb (GnomeCanvasItem *item, +item_event_callback (GnomeCanvasItem *item, GdkEvent *event, gpointer data) { @@ -2123,12 +2088,9 @@ gnome_icon_container_clear (GnomeIconContainer *container) static void icon_destroy (GnomeIconContainer *container, - GnomeIconContainerIcon *icon) + GnomeIconContainerIcon *icon) { GnomeIconContainerDetails *details; - gint icon_x, icon_y; - gint grid_x, grid_y; - gint x_offset, y_offset; gboolean was_selected; details = container->details; @@ -2142,27 +2104,7 @@ icon_destroy (GnomeIconContainer *container, set_kbd_current (container, NULL, FALSE); } - icon_x = icon->x; - icon_y = icon->y; - gnome_icon_container_world_to_grid (container, icon_x, icon_y, &grid_x, &grid_y); - gnome_icon_container_grid_remove(details->grid, icon, grid_x, grid_y); - - x_offset = icon_x % GNOME_ICON_CONTAINER_CELL_WIDTH (container); - y_offset = icon_y % GNOME_ICON_CONTAINER_CELL_HEIGHT (container); - - if (x_offset > 0) { - gnome_icon_container_grid_remove (details->grid, icon, - grid_x + 1, grid_y); - } - if (y_offset > 0) { - gnome_icon_container_grid_remove (details->grid, icon, - grid_x, grid_y + 1); - } - if (x_offset > 0 && y_offset > 0) { - gnome_icon_container_grid_remove (details->grid, icon, - grid_x + 1, grid_y + 1); - } - + gnome_icon_container_grid_remove (details->grid, icon); g_hash_table_remove (details->canvas_item_to_icon, icon->item); icon_free (icon); @@ -2193,6 +2135,24 @@ activate_selected_items (GnomeIconContainer *container) } static void +bounds_changed_callback (NautilusIconsViewIconItem *item, + const ArtDRect *old_bounds, + GnomeIconContainer *container) +{ + GnomeIconContainerIcon *icon; + + g_assert (NAUTILUS_IS_ICONS_VIEW_ICON_ITEM (item)); + g_assert (old_bounds != NULL); + g_assert (GNOME_IS_ICON_CONTAINER (container)); + + icon = g_hash_table_lookup (container->details->canvas_item_to_icon, item); + g_assert (icon != NULL); + + gnome_icon_container_grid_remove (container->details->grid, icon); + gnome_icon_container_grid_add (container->details->grid, icon); +} + +static void setup_icon_in_container (GnomeIconContainer *container, GnomeIconContainerIcon *icon) { @@ -2204,10 +2164,16 @@ setup_icon_in_container (GnomeIconContainer *container, details->num_icons++; g_hash_table_insert (details->canvas_item_to_icon, icon->item, icon); + + nautilus_icons_view_icon_item_update_bounds (icon->item); + gnome_icon_container_grid_add (details->grid, icon); + icon_show (icon); gtk_signal_connect (GTK_OBJECT (icon->item), "event", - GTK_SIGNAL_FUNC (item_event_cb), container); + GTK_SIGNAL_FUNC (item_event_callback), container); + gtk_signal_connect (GTK_OBJECT (icon->item), "bounds_changed", + GTK_SIGNAL_FUNC (bounds_changed_callback), container); } static void @@ -2294,11 +2260,11 @@ update_icon (GnomeIconContainer *container, GnomeIconContainerIcon *icon) void gnome_icon_container_add (GnomeIconContainer *container, GnomeIconContainerIconData *data, - int x, int y, double scale_x, double scale_y) + int x, int y, + double scale_x, double scale_y) { GnomeIconContainerDetails *details; GnomeIconContainerIcon *new_icon; - guint grid_x, grid_y; g_return_if_fail (GNOME_IS_ICON_CONTAINER (container)); g_return_if_fail (data != NULL); @@ -2310,20 +2276,6 @@ gnome_icon_container_add (GnomeIconContainer *container, new_icon->scale_x = scale_x; new_icon->scale_y = scale_y; - gnome_icon_container_world_to_grid (container, x, y, &grid_x, &grid_y); - gnome_icon_container_grid_add (details->grid, new_icon, grid_x, grid_y); - - if (x % GNOME_ICON_CONTAINER_CELL_WIDTH (container) > 0) { - gnome_icon_container_grid_add (details->grid, new_icon, grid_x + 1, grid_y); - } - if (y % GNOME_ICON_CONTAINER_CELL_HEIGHT (container) > 0) { - gnome_icon_container_grid_add (details->grid, new_icon, grid_x, grid_y + 1); - } - if (x % GNOME_ICON_CONTAINER_CELL_WIDTH (container) > 0 - && y % GNOME_ICON_CONTAINER_CELL_HEIGHT (container) > 0) { - gnome_icon_container_grid_add (details->grid, new_icon, grid_x + 1, grid_y + 1); - } - setup_icon_in_container (container, new_icon); request_idle (container); @@ -2344,7 +2296,6 @@ gnome_icon_container_add_auto (GnomeIconContainer *container, GnomeIconContainerIconData *data) { GnomeIconContainerIcon *new_icon; - guint grid_x, grid_y; int x, y; g_return_if_fail (GNOME_IS_ICON_CONTAINER (container)); @@ -2352,10 +2303,9 @@ gnome_icon_container_add_auto (GnomeIconContainer *container, new_icon = icon_new (container, data); - gnome_icon_container_grid_add_auto (container->details->grid, - new_icon, - &grid_x, &grid_y); - gnome_icon_container_grid_to_world (container, grid_x, grid_y, &x, &y); + gnome_icon_container_grid_get_position (container->details->grid, + new_icon, + &x, &y); icon_set_position (new_icon, x, y); @@ -2501,11 +2451,11 @@ gnome_icon_container_relayout (GnomeIconContainer *container) GnomeIconContainerDetails *details; GnomeIconContainerGrid *old_grid, *new_grid; GList **sp, **dp; - guint i, j; - guint dx, dy; - guint sx, sy; - guint cols; - guint lines; + int i, j; + int dx, dy; + int sx, sy; + int cols; + int lines; g_return_if_fail (GNOME_IS_ICON_CONTAINER (container)); @@ -2615,8 +2565,8 @@ gnome_icon_container_line_up (GnomeIconContainer *container) GnomeIconContainerGrid *grid; GnomeIconContainerGrid *new_grid; GList **p, **q; - guint new_grid_width; - guint i, j, k, m; + int new_grid_width; + int i, j, k, m; int x, y, dx; g_return_if_fail (GNOME_IS_ICON_CONTAINER (container)); @@ -2635,12 +2585,12 @@ gnome_icon_container_line_up (GnomeIconContainer *container) p = grid->elems; x = y = 0; for (i = 0; i < grid->height; i++) { - guint line_width; + int line_width; line_width = grid->width; for (j = 0; j < grid->width; j++) { GList *e; - guint count; + int count; count = 0; for (e = p[j]; e != NULL; e = e->next) { @@ -2682,7 +2632,7 @@ gnome_icon_container_line_up (GnomeIconContainer *container) m = 0; for (j = 0; j < grid->width; j++) { GList *e; - guint count; + int count; /* Make sure the icons are sorted by increasing X position. */ diff --git a/libnautilus/nautilus-global-preferences.c b/libnautilus/nautilus-global-preferences.c index a08ff9836..79fca8ca1 100644 --- a/libnautilus/nautilus-global-preferences.c +++ b/libnautilus/nautilus-global-preferences.c @@ -22,7 +22,9 @@ Authors: Ramiro Estrugo <ramiro@eazel.com> */ +#include <config.h> #include "nautilus-global-preferences.h" + #include <nautilus-widgets/nautilus-preferences-group.h> #include <nautilus-widgets/nautilus-preferences-item.h> #include <nautilus-widgets/nautilus-preferences-dialog.h> @@ -35,24 +37,24 @@ /* Private stuff */ static GtkWidget *global_preferences_create_dialog (void); -static GtkWidget *global_prefernces_create_enum_group (GtkWidget *pane, - const gchar *group_title, - const gchar *pref_name); -static GtkWidget *global_preferences_create_check_group (GtkWidget *pane, - const gchar *group_title, - const gchar *pref_names[], - guint num_prefs); +static GtkWidget *global_preferences_create_enum_group (GtkWidget *pane, + const char *group_title, + const char *pref_name); +static GtkWidget *global_preferences_create_check_group (GtkWidget *pane, + const char *group_title, + const char * const pref_names[], + guint num_prefs); static GtkWidget *global_preferences_get_dialog (void); static void global_preferences_register_static (NautilusPreferences *prefs); static void global_preferences_register_dynamic (NautilusPreferences *prefs); -static const gchar *global_preferences_window_option_pref_names[] = +static const char * const global_preferences_window_option_pref_names[] = { NAUTILUS_PREFERENCES_WINDOW_ALWAYS_NEW, NAUTILUS_PREFERENCES_WINDOW_SEARCH_EXISTING }; -static const gchar *global_preferences_meta_view_names[] = +static const char * const global_preferences_meta_view_names[] = { NAUTILUS_PREFERENCES_META_VIEWS_SHOW_ANNOTATIONS, NAUTILUS_PREFERENCES_META_VIEWS_SHOW_HELP_CONTENTS, @@ -62,7 +64,7 @@ static const gchar *global_preferences_meta_view_names[] = NAUTILUS_PREFERENCES_META_VIEWS_SHOW_WEB_SEARCH }; -static const gchar * global_preferences_user_level_names[] = +static const char * const global_preferences_user_level_names[] = { "novice", "intermediate", @@ -70,7 +72,7 @@ static const gchar * global_preferences_user_level_names[] = "ettore" }; -static const gchar * global_preferences_user_level_descriptions[] = +static const char * const global_preferences_user_level_descriptions[] = { "Novice", "Intermediate", @@ -86,7 +88,7 @@ static const gint global_preferences_user_level_values[] = NAUTILUS_USER_LEVEL_ETTORE }; -static NautilusPreferencesEnumData global_preferences_user_level_data = +static const NautilusPreferencesEnumData global_preferences_user_level_data = { global_preferences_user_level_names, global_preferences_user_level_descriptions, @@ -94,7 +96,7 @@ static NautilusPreferencesEnumData global_preferences_user_level_data = NAUTILUS_N_ELEMENTS (global_preferences_user_level_names) }; -static NautilusPreferencesInfo global_preferences_static_info[] = +static const NautilusPreferencesInfo global_preferences_static_info[] = { { NAUTILUS_PREFERENCES_USER_LEVEL, @@ -151,7 +153,7 @@ global_preferences_create_dialog (void) "User Level", "User Level Something"); - global_prefernces_create_enum_group (panes[0], + global_preferences_create_enum_group (panes[0], "User Level", NAUTILUS_PREFERENCES_USER_LEVEL); @@ -177,10 +179,10 @@ global_preferences_create_dialog (void) } static GtkWidget * -global_preferences_create_check_group (GtkWidget *pane, - const gchar *group_title, - const gchar *pref_names[], - guint num_prefs) +global_preferences_create_check_group (GtkWidget *pane, + const char *group_title, + const char * const pref_names[], + guint num_prefs) { GtkWidget *group; guint i; @@ -209,9 +211,9 @@ global_preferences_create_check_group (GtkWidget *pane, } static GtkWidget * -global_prefernces_create_enum_group (GtkWidget *pane, - const gchar *group_title, - const gchar *pref_name) +global_preferences_create_enum_group (GtkWidget *pane, + const char *group_title, + const char *pref_name) { GtkWidget *group; GtkWidget *item; diff --git a/libnautilus/nautilus-gnome-extensions.c b/libnautilus/nautilus-gnome-extensions.c index 54749922b..b0d5c7ac3 100644 --- a/libnautilus/nautilus-gnome-extensions.c +++ b/libnautilus/nautilus-gnome-extensions.c @@ -86,3 +86,82 @@ nautilus_art_irect_hits_irect (const ArtIRect *rect_a, art_irect_intersect (&intersection, rect_a, rect_b); return !art_irect_empty (&intersection); } + +gboolean +nautilus_art_irect_equal (const ArtIRect *rect_a, + const ArtIRect *rect_b) +{ + g_return_val_if_fail (rect_a != NULL, FALSE); + g_return_val_if_fail (rect_b != NULL, FALSE); + + return rect_a->x0 == rect_b->x0 + && rect_a->y0 == rect_b->y0 + && rect_a->x1 == rect_b->x1 + && rect_a->y1 == rect_b->y1; +} + +gboolean +nautilus_art_drect_equal (const ArtDRect *rect_a, + const ArtDRect *rect_b) +{ + g_return_val_if_fail (rect_a != NULL, FALSE); + g_return_val_if_fail (rect_b != NULL, FALSE); + + return rect_a->x0 == rect_b->x0 + && rect_a->y0 == rect_b->y0 + && rect_a->x1 == rect_b->x1 + && rect_a->y1 == rect_b->y1; +} + +void +nautilus_gnome_canvas_item_get_current_canvas_bounds (GnomeCanvasItem *item, + ArtIRect *bounds) +{ + g_return_if_fail (GNOME_IS_CANVAS_ITEM (item)); + g_return_if_fail (bounds != NULL); + + bounds->x0 = item->x1; + bounds->y0 = item->y1; + bounds->x1 = item->x2; + bounds->y1 = item->y2; +} + +void +nautilus_gnome_canvas_item_request_redraw (GnomeCanvasItem *item) +{ + g_return_if_fail (GNOME_IS_CANVAS_ITEM (item)); + + gnome_canvas_request_redraw (item->canvas, + item->x1, item->y1, + item->x2, item->y2); +} + +void +nautilus_gnome_canvas_request_redraw_rectangle (GnomeCanvas *canvas, + const ArtIRect *canvas_rectangle) +{ + g_return_if_fail (GNOME_IS_CANVAS (canvas)); + + gnome_canvas_request_redraw (canvas, + canvas_rectangle->x0, canvas_rectangle->y0, + canvas_rectangle->x1, canvas_rectangle->y1); +} + +void +nautilus_gnome_canvas_item_get_world_bounds (GnomeCanvasItem *item, + ArtDRect *world_bounds) +{ + gnome_canvas_item_get_bounds (item, + &world_bounds->x0, + &world_bounds->y0, + &world_bounds->x1, + &world_bounds->y1); + if (item->parent != NULL) { + gnome_canvas_item_i2w (item->parent, + &world_bounds->x0, + &world_bounds->y0); + gnome_canvas_item_i2w (item->parent, + &world_bounds->x1, + &world_bounds->y1); + } +} diff --git a/libnautilus/nautilus-gnome-extensions.h b/libnautilus/nautilus-gnome-extensions.h index 3c3d40af9..df921e08f 100644 --- a/libnautilus/nautilus-gnome-extensions.h +++ b/libnautilus/nautilus-gnome-extensions.h @@ -29,13 +29,42 @@ #include <libgnomeui/gnome-canvas.h> -void nautilus_gnome_canvas_world_to_canvas_rectangle (GnomeCanvas *canvas, - const ArtDRect *world_rectangle, - ArtIRect *canvas_rectangle); -void nautilus_gnome_canvas_world_to_window_rectangle (GnomeCanvas *canvas, - const ArtDRect *world_rectangle, - ArtIRect *window_rectangle); -gboolean nautilus_art_irect_hits_irect (const ArtIRect *rect_a, - const ArtIRect *rect_b); +/* This is more handy than gnome_canvas_item_get_bounds because it + * always returns the bounds * in world coordinates and it returns + * them in a single rectangle. + */ +void nautilus_gnome_canvas_item_get_world_bounds (GnomeCanvasItem *item, + ArtDRect *world_bounds); + +/* This returns the current canvas bounds as computed by update. + * It's not as "up to date" as get_bounds, which is accurate even + * before an update happens. + */ +void nautilus_gnome_canvas_item_get_current_canvas_bounds (GnomeCanvasItem *item, + ArtIRect *canvas_bounds); + +/* Convenience functions for doing things with whole rectangles. */ +void nautilus_gnome_canvas_world_to_canvas_rectangle (GnomeCanvas *canvas, + const ArtDRect *world_rectangle, + ArtIRect *canvas_rectangle); +void nautilus_gnome_canvas_world_to_window_rectangle (GnomeCanvas *canvas, + const ArtDRect *world_rectangle, + ArtIRect *window_rectangle); +void nautilus_gnome_canvas_request_redraw_rectangle (GnomeCanvas *canvas, + const ArtIRect *canvas_rectangle); + +/* Requests the entire object be redrawn. + * Normally, you use request_update when calling from outside the canvas item + * code. This is for within canvas item code. + */ +void nautilus_gnome_canvas_item_request_redraw (GnomeCanvasItem *item); + +/* More functions for ArtIRect and ArtDRect. */ +gboolean nautilus_art_irect_hits_irect (const ArtIRect *rect_a, + const ArtIRect *rect_b); +gboolean nautilus_art_irect_equal (const ArtIRect *rect_a, + const ArtIRect *rect_b); +gboolean nautilus_art_drect_equal (const ArtDRect *rect_a, + const ArtDRect *rect_b); #endif /* NAUTILUS_GNOME_EXTENSIONS_H */ diff --git a/libnautilus/nautilus-icons-view-icon-item.c b/libnautilus/nautilus-icons-view-icon-item.c index b56c4a41c..1ba9febe2 100644 --- a/libnautilus/nautilus-icons-view-icon-item.c +++ b/libnautilus/nautilus-icons-view-icon-item.c @@ -28,6 +28,7 @@ #include <math.h> #include <string.h> #include <stdio.h> +#include <gtk/gtksignal.h> #include <gdk-pixbuf/gdk-pixbuf.h> #include <libart_lgpl/art_rgb_pixbuf_affine.h> #include <libgnomeui/gnome-canvas-util.h> @@ -90,6 +91,12 @@ typedef struct { GList *emblem; } EmblemLayout; +enum { + BOUNDS_CHANGED, + LAST_SIGNAL +}; +static guint signals[LAST_SIGNAL]; + /* constants */ #define MAX_TEXT_WIDTH 80 @@ -100,65 +107,65 @@ static char stipple_bits[] = { 0x02, 0x01 }; static GdkFont *embedded_text_font; /* GtkObject */ -static void nautilus_icons_view_icon_item_initialize_class (NautilusIconsViewIconItemClass *class); -static void nautilus_icons_view_icon_item_initialize (NautilusIconsViewIconItem *item); -static void nautilus_icons_view_icon_item_destroy (GtkObject *object); -static int nautilus_icons_view_icon_item_event (GnomeCanvasItem *item, - GdkEvent *event); -static void nautilus_icons_view_icon_item_set_arg (GtkObject *object, - GtkArg *arg, - guint arg_id); -static void nautilus_icons_view_icon_item_get_arg (GtkObject *object, - GtkArg *arg, - guint arg_id); +static void nautilus_icons_view_icon_item_initialize_class (NautilusIconsViewIconItemClass *class); +static void nautilus_icons_view_icon_item_initialize (NautilusIconsViewIconItem *item); +static void nautilus_icons_view_icon_item_destroy (GtkObject *object); +static int nautilus_icons_view_icon_item_event (GnomeCanvasItem *item, + GdkEvent *event); +static void nautilus_icons_view_icon_item_set_arg (GtkObject *object, + GtkArg *arg, + guint arg_id); +static void nautilus_icons_view_icon_item_get_arg (GtkObject *object, + GtkArg *arg, + guint arg_id); /* GnomeCanvasItem */ -static void nautilus_icons_view_icon_item_update (GnomeCanvasItem *item, - double *affine, - ArtSVP *clip_path, - int flags); -static void nautilus_icons_view_icon_item_draw (GnomeCanvasItem *item, - GdkDrawable *drawable, - int x, - int y, - int width, - int height); -static double nautilus_icons_view_icon_item_point (GnomeCanvasItem *item, - double x, - double y, - int cx, - int cy, - GnomeCanvasItem **actual_item); -static void nautilus_icons_view_icon_item_bounds (GnomeCanvasItem *item, - double *x1, - double *y1, - double *x2, - double *y2); +static void nautilus_icons_view_icon_item_update (GnomeCanvasItem *item, + double *affine, + ArtSVP *clip_path, + int flags); +static void nautilus_icons_view_icon_item_draw (GnomeCanvasItem *item, + GdkDrawable *drawable, + int x, + int y, + int width, + int height); +static double nautilus_icons_view_icon_item_point (GnomeCanvasItem *item, + double x, + double y, + int cx, + int cy, + GnomeCanvasItem **actual_item); +static void nautilus_icons_view_icon_item_bounds (GnomeCanvasItem *item, + double *x1, + double *y1, + double *x2, + double *y2); /* private */ -static void draw_or_measure_text_box (GnomeCanvasItem *item, - GdkDrawable *drawable, - int icon_left, - int icon_bottom); -static void nautilus_icons_view_draw_text_box (GnomeCanvasItem *item, - GdkDrawable *drawable, - int icon_left, - int icon_bottom); -static void nautilus_icons_view_measure_text_box (GnomeCanvasItem *item); -static void nautilus_icons_view_icon_item_get_icon_canvas_rectangle (NautilusIconsViewIconItem *item, - ArtIRect *rect); -static void emblem_layout_reset (EmblemLayout *layout, - NautilusIconsViewIconItem *icon_item, - const ArtIRect *icon_rect); -static gboolean emblem_layout_next (EmblemLayout *layout, - GdkPixbuf **emblem_pixbuf, - ArtIRect *emblem_rect); -static void draw_pixbuf (GdkPixbuf *pixbuf, - GdkDrawable *drawable, - int x, - int y); -static gboolean hit_stretch_handle (NautilusIconsViewIconItem *item, - const ArtIRect *canvas_rect); +static void draw_or_measure_label_text (NautilusIconsViewIconItem *item, + GdkDrawable *drawable, + int icon_left, + int icon_bottom); +static void draw_label_text (NautilusIconsViewIconItem *item, + GdkDrawable *drawable, + int icon_left, + int icon_bottom); +static void measure_label_text (NautilusIconsViewIconItem *item); +static void get_icon_canvas_rectangle (NautilusIconsViewIconItem *item, + ArtIRect *rect); +static void emblem_layout_reset (EmblemLayout *layout, + NautilusIconsViewIconItem *icon_item, + const ArtIRect *icon_rect); +static gboolean emblem_layout_next (EmblemLayout *layout, + GdkPixbuf **emblem_pixbuf, + ArtIRect *emblem_rect); +static void draw_pixbuf (GdkPixbuf *pixbuf, + GdkDrawable *drawable, + int x, + int y); +static gboolean hit_stretch_handle (NautilusIconsViewIconItem *item, + const ArtIRect *canvas_rect); NAUTILUS_DEFINE_CLASS_BOILERPLATE (NautilusIconsViewIconItem, nautilus_icons_view_icon_item, GNOME_TYPE_CANVAS_ITEM) @@ -172,30 +179,43 @@ nautilus_icons_view_icon_item_initialize_class (NautilusIconsViewIconItemClass * object_class = GTK_OBJECT_CLASS (class); item_class = GNOME_CANVAS_ITEM_CLASS (class); - gtk_object_add_arg_type ("NautilusIconsViewIconItem::text", + gtk_object_add_arg_type ("NautilusIconsViewIconItem::text", GTK_TYPE_STRING, GTK_ARG_READWRITE, ARG_TEXT); - gtk_object_add_arg_type ("NautilusIconsViewIconItem::font", + gtk_object_add_arg_type ("NautilusIconsViewIconItem::font", GTK_TYPE_BOXED, GTK_ARG_READWRITE, ARG_FONT); - gtk_object_add_arg_type ("NautilusIconsViewIconItem::highlighted_for_selection", + gtk_object_add_arg_type ("NautilusIconsViewIconItem::highlighted_for_selection", GTK_TYPE_BOOL, GTK_ARG_READWRITE, ARG_HIGHLIGHTED_FOR_SELECTION); - gtk_object_add_arg_type ("NautilusIconsViewIconItem::highlighted_for_keyboard_selection", + gtk_object_add_arg_type ("NautilusIconsViewIconItem::highlighted_for_keyboard_selection", GTK_TYPE_BOOL, GTK_ARG_READWRITE, ARG_HIGHLIGHTED_FOR_KEYBOARD_SELECTION); - gtk_object_add_arg_type ("NautilusIconsViewIconItem::highlighted_for_drop", + gtk_object_add_arg_type ("NautilusIconsViewIconItem::highlighted_for_drop", GTK_TYPE_BOOL, GTK_ARG_READWRITE, ARG_HIGHLIGHTED_FOR_DROP); - gtk_object_add_arg_type ("NautilusIconsViewIconItem::text_source", + gtk_object_add_arg_type ("NautilusIconsViewIconItem::text_source", GTK_TYPE_STRING, GTK_ARG_READWRITE, ARG_TEXT_SOURCE); object_class->destroy = nautilus_icons_view_icon_item_destroy; object_class->set_arg = nautilus_icons_view_icon_item_set_arg; object_class->get_arg = nautilus_icons_view_icon_item_get_arg; + signals[BOUNDS_CHANGED] + = gtk_signal_new ("bounds_changed", + GTK_RUN_LAST, + object_class->type, + GTK_SIGNAL_OFFSET (NautilusIconsViewIconItemClass, + bounds_changed), + gtk_marshal_NONE__POINTER, + GTK_TYPE_NONE, 1, + GTK_TYPE_POINTER); + + gtk_object_class_add_signals (object_class, signals, LAST_SIGNAL); + item_class->update = nautilus_icons_view_icon_item_update; item_class->draw = nautilus_icons_view_icon_item_draw; item_class->point = nautilus_icons_view_icon_item_point; item_class->bounds = nautilus_icons_view_icon_item_bounds; item_class->event = nautilus_icons_view_icon_item_event; - + stipple = gdk_bitmap_create_from_data (NULL, stipple_bits, 2, 2); + /* FIXME: the font shouldn't be hard-wired like this */ embedded_text_font = gdk_font_load("-bitstream-charter-medium-r-normal-*-9-*-*-*-*-*-*-*"); } @@ -483,36 +503,52 @@ recompute_bounding_box (NautilusIconsViewIconItem *icon_item) item->y2 = bottom_right.y; } -/* Update handler for the icon canvas item. */ -static void -nautilus_icons_view_icon_item_update (GnomeCanvasItem *item, double *affine, ArtSVP *clip_path, int flags) +void +nautilus_icons_view_icon_item_update_bounds (NautilusIconsViewIconItem *item) { - NautilusIconsViewIconItem *icon_item; - NautilusIconsViewIconItemDetails *details; + ArtIRect before, after; - icon_item = NAUTILUS_ICONS_VIEW_ICON_ITEM (item); - details = icon_item->details; + /* Compute new bounds. */ + nautilus_gnome_canvas_item_get_current_canvas_bounds + (GNOME_CANVAS_ITEM (item), &before); + recompute_bounding_box (item); + nautilus_gnome_canvas_item_get_current_canvas_bounds + (GNOME_CANVAS_ITEM (item), &after); - /* Make sure the text box measurements are set up - * before recalculating the bounding box. - */ - gnome_canvas_request_redraw (item->canvas, item->x1, item->y1, item->x2, item->y2); - nautilus_icons_view_measure_text_box (item); - recompute_bounding_box (icon_item); - gnome_canvas_request_redraw (item->canvas, item->x1, item->y1, item->x2, item->y2); - - NAUTILUS_CALL_PARENT_CLASS (GNOME_CANVAS_ITEM_CLASS, update, (item, affine, clip_path, flags)); + /* If the bounds didn't change, we are done. */ + if (nautilus_art_irect_equal (&before, &after)) { + return; + } + + /* Send out the bounds_changed signal and queue a redraw. */ + nautilus_gnome_canvas_request_redraw_rectangle + (GNOME_CANVAS_ITEM (item)->canvas, &before); + gtk_signal_emit (GTK_OBJECT (item), + signals[BOUNDS_CHANGED]); + nautilus_gnome_canvas_item_request_redraw + (GNOME_CANVAS_ITEM (item)); } +/* Update handler for the icon canvas item. */ +static void +nautilus_icons_view_icon_item_update (GnomeCanvasItem *item, + double *affine, + ArtSVP *clip_path, + int flags) +{ + nautilus_icons_view_icon_item_update_bounds (NAUTILUS_ICONS_VIEW_ICON_ITEM (item)); + nautilus_gnome_canvas_item_request_redraw (item); + NAUTILUS_CALL_PARENT_CLASS (GNOME_CANVAS_ITEM_CLASS, update, (item, affine, clip_path, flags)); +} /* Rendering */ /* Draw the text in a box, using gnomelib routines. */ static void -draw_or_measure_text_box (GnomeCanvasItem* item, - GdkDrawable *drawable, - int icon_left, - int icon_bottom) +draw_or_measure_label_text (NautilusIconsViewIconItem *item, + GdkDrawable *drawable, + int icon_left, + int icon_bottom) { NautilusIconsViewIconItemDetails *details; int width_so_far, height_so_far; @@ -524,7 +560,7 @@ draw_or_measure_text_box (GnomeCanvasItem* item, const char *text_piece; int i; - details = NAUTILUS_ICONS_VIEW_ICON_ITEM (item)->details; + details = item->details; if (details->font == NULL || details->text == NULL || details->text[0] == '\0') { details->text_height = 0; @@ -537,10 +573,10 @@ draw_or_measure_text_box (GnomeCanvasItem* item, if (drawable != NULL) { icon_width = details->pixbuf == NULL ? 0 : gdk_pixbuf_get_width (details->pixbuf); - gc = gdk_gc_new (item->canvas->layout.bin_window); + gc = gdk_gc_new (GNOME_CANVAS_ITEM (item)->canvas->layout.bin_window); } - max_text_width = floor (MAX_TEXT_WIDTH * item->canvas->pixels_per_unit); + max_text_width = floor (MAX_TEXT_WIDTH * GNOME_CANVAS_ITEM (item)->canvas->pixels_per_unit); pieces = g_strsplit (details->text, "\n", 0); for (i = 0; (text_piece = pieces[i]) != NULL; i++) { @@ -610,16 +646,16 @@ draw_or_measure_text_box (GnomeCanvasItem* item, } static void -nautilus_icons_view_measure_text_box (GnomeCanvasItem* item) +measure_label_text (NautilusIconsViewIconItem *item) { - draw_or_measure_text_box (item, NULL, 0, 0); + draw_or_measure_label_text (item, NULL, 0, 0); } static void -nautilus_icons_view_draw_text_box (GnomeCanvasItem* item, GdkDrawable *drawable, +draw_label_text (NautilusIconsViewIconItem *item, GdkDrawable *drawable, int icon_left, int icon_bottom) { - draw_or_measure_text_box (item, drawable, icon_left, icon_bottom); + draw_or_measure_label_text (item, drawable, icon_left, icon_bottom); } /* utility routine to draw the mini-text inside text files */ @@ -958,8 +994,7 @@ nautilus_icons_view_icon_item_draw (GnomeCanvasItem *item, GdkDrawable *drawable } /* Compute icon rectangle in drawable coordinates. */ - nautilus_icons_view_icon_item_get_icon_canvas_rectangle - (icon_item, &icon_rect); + get_icon_canvas_rectangle (icon_item, &icon_rect); icon_rect.x0 -= x; icon_rect.y0 -= y; icon_rect.x1 -= x; @@ -988,7 +1023,7 @@ nautilus_icons_view_icon_item_draw (GnomeCanvasItem *item, GdkDrawable *drawable draw_embedded_text (item, drawable, &icon_rect); /* Draw the label text. */ - nautilus_icons_view_draw_text_box (item, drawable, icon_rect.x0, icon_rect.y1); + draw_label_text (icon_item, drawable, icon_rect.x0, icon_rect.y1); } /* handle events */ @@ -1093,8 +1128,7 @@ hit_test (NautilusIconsViewIconItem *icon_item, const ArtIRect *canvas_rect) } /* Check for hit in the icon. */ - nautilus_icons_view_icon_item_get_icon_canvas_rectangle - (icon_item, &icon_rect); + get_icon_canvas_rectangle (icon_item, &icon_rect); if (hit_test_pixbuf (details->pixbuf, &icon_rect, canvas_rect)) { return TRUE; } @@ -1157,6 +1191,8 @@ nautilus_icons_view_icon_item_bounds (GnomeCanvasItem *item, double *x1, double icon_item = NAUTILUS_ICONS_VIEW_ICON_ITEM (item); details = icon_item->details; + measure_label_text (icon_item); + /* Compute icon rectangle. */ icon_rect.x0 = 0; icon_rect.y0 = 0; @@ -1177,7 +1213,6 @@ nautilus_icons_view_icon_item_bounds (GnomeCanvasItem *item, double *x1, double while (emblem_layout_next (&emblem_layout, &emblem_pixbuf, &emblem_rect)) { art_irect_union (&total_rect, &total_rect, &emblem_rect); } - /* Add 2 pixels slop to each side. */ total_rect.x0 -= 2; @@ -1224,7 +1259,7 @@ nautilus_icons_view_icon_item_get_icon_rectangle (NautilusIconsViewIconItem *ite /* Get the rectangle of the icon only, in canvas coordinates. */ void -nautilus_icons_view_icon_item_get_icon_canvas_rectangle (NautilusIconsViewIconItem *item, +get_icon_canvas_rectangle (NautilusIconsViewIconItem *item, ArtIRect *rect) { double i2c[6]; @@ -1279,8 +1314,7 @@ hit_stretch_handle (NautilusIconsViewIconItem *item, } /* Quick check to see if the rect hits the icon at all. */ - nautilus_icons_view_icon_item_get_icon_canvas_rectangle - (item, &icon_rect); + get_icon_canvas_rectangle (item, &icon_rect); if (!nautilus_art_irect_hits_irect (probe_canvas_rect, &icon_rect)) { return FALSE; } diff --git a/libnautilus/nautilus-icons-view-icon-item.h b/libnautilus/nautilus-icons-view-icon-item.h index 51ef93641..a509cc9c6 100644 --- a/libnautilus/nautilus-icons-view-icon-item.h +++ b/libnautilus/nautilus-icons-view-icon-item.h @@ -53,6 +53,9 @@ struct NautilusIconsViewIconItem { struct NautilusIconsViewIconItemClass { GnomeCanvasItemClass parent_class; + + void (* bounds_changed) (NautilusIconsViewIconItem *item, + const ArtDRect *old_world_bounds); }; /* GtkObject */ @@ -77,6 +80,7 @@ gboolean nautilus_icons_view_icon_item_hit_test_stretch_handles (NautilusIcons const ArtPoint *world_point); void nautilus_icons_view_icon_item_get_icon_rectangle (NautilusIconsViewIconItem *item, ArtDRect *world_rectangle); +void nautilus_icons_view_icon_item_update_bounds (NautilusIconsViewIconItem *item); END_GNOME_DECLS diff --git a/nautilus-widgets/nautilus-preferences.h b/nautilus-widgets/nautilus-preferences.h index 779db6e95..1fa560e20 100644 --- a/nautilus-widgets/nautilus-preferences.h +++ b/nautilus-widgets/nautilus-preferences.h @@ -82,10 +82,10 @@ typedef struct typedef struct { - const char **enum_names; - const char **enum_descriptions; - const int *enum_values; - guint num_entries; + const char * const *enum_names; + const char * const *enum_descriptions; + const int *enum_values; + guint num_entries; } NautilusPreferencesEnumData; GtkType nautilus_preferences_get_type (void); |