summaryrefslogtreecommitdiff
path: root/libnautilus/gnome-icon-container-grid.c
diff options
context:
space:
mode:
Diffstat (limited to 'libnautilus/gnome-icon-container-grid.c')
-rw-r--r--libnautilus/gnome-icon-container-grid.c201
1 files changed, 115 insertions, 86 deletions
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)