Am Freitag, den 15.07.2005, 11:40 +0200 schrieb Alexander Larsson: > On Thu, 2005-07-14 at 22:41 +0200, Christian Neumair wrote: > > Am Donnerstag, den 14.07.2005, 10:50 +0200 schrieb Alexander Larsson: > > > On Thu, 2005-07-14 at 10:34 +0200, Christian Neumair wrote: > > > > Am Mittwoch, den 13.07.2005, 14:09 +0200 schrieb Alexander Larsson: > > > > > On Wed, 2005-07-13 at 13:51 +0200, Christian Neumair wrote: > > > > > > Am Mittwoch, den 13.07.2005, 13:45 +0200 schrieb Alexander Larsson: > > > > > > > On Tue, 2005-07-12 at 18:19 +0200, Christian Neumair wrote: > > > > > > > > From bug 150116 [1]: > > > > > > > > > > > > > > > > "When trying to select a range of files if ordering is set to manual, > > > > > > > > the range of files is determined by file names instead of spatial > > > > > > > > location. > > > > > > > > > > > > > > > > This is especially obvious on the desktop where there is no auto-sort." > > > > > > > > > > > > > > > > Proposed patch attached. > > > > > > > > > > > > > > > > [1] http://bugzilla.gnome.org/show_bug.cgi?id=150116 > > > > > > > > > > > > > > > > > > > > > > + x0 = MIN (icon1->x, icon2->x); > > > > > > > + x1 = MAX (icon1->x, icon2->x); > > > > > > > + y0 = MIN (icon1->y, icon2->y); > > > > > > > + y1 = MAX (icon1->y, icon2->y); > > > > > > > > > > > > > > This doesn't look entierly right. Surely you want the whole part of the > > > > > > > icons, not just its position (which i think is the corner? don't > > > > > > > remember exactly). > > > > > > > > > > > > Yes, as far as I know it's the upper-left corner. What's wrong with it? > > > > > > You think we should also select items which just "touch"/intersect the > > > > > > range to be selected instead of matching only those that are actually > > > > > > contained within the range? > > > > > > > > > > consider this case: > > > > > > > > > > a > > > > > bc > > > > > > > > > > where b and c really overlap vertically, except c is one pixel above b. > > > > > [...] > > > > > [...] > > > > > > In the attached image of my desktop, your range select algorithm doesn't > > > include the middle icon. I'm pretty sure this is not what most people > > > expect. > > > > The attached patch produces acceptable results at least on my desktop, > > since the vertical grid space is 20 px. 25 px should also be enough to > > handle some additional icon height-related displacement. > > Its still extremely weird. It allows 25 pixel above the highest icon, > but only the top 25 pixels of the lowest icon. Just either use the full > extent of both icons to calculate the max/min position, or use the > middle of the icon. New proposed patch which takes into account the center of all selection candidates. I also tried to only use the image rectangle but throwed away this idea since it proved to feel a bit weird. -- Christian Neumair <chris gnome-de org>
Index: libnautilus-private/nautilus-icon-container.c =================================================================== RCS file: /cvs/gnome/nautilus/libnautilus-private/nautilus-icon-container.c,v retrieving revision 1.393 diff -u -p -r1.393 nautilus-icon-container.c --- libnautilus-private/nautilus-icon-container.c 12 Aug 2005 18:11:29 -0000 1.393 +++ libnautilus-private/nautilus-icon-container.c 26 Aug 2005 21:12:26 -0000 @@ -1771,26 +1778,63 @@ select_range (NautilusIconContainer *con unmatched_icon = NULL; select = FALSE; - for (p = container->details->icons; p != NULL; p = p->next) { - icon = p->data; + if (container->details->auto_layout) { + for (p = container->details->icons; p != NULL; p = p->next) { + icon = p->data; + + if (unmatched_icon == NULL) { + if (icon == icon1) { + unmatched_icon = icon2; + select = TRUE; + } else if (icon == icon2) { + unmatched_icon = icon1; + select = TRUE; + } + } + + selection_changed |= icon_set_selected + (container, icon, select); - if (unmatched_icon == NULL) { - if (icon == icon1) { - unmatched_icon = icon2; - select = TRUE; - } else if (icon == icon2) { - unmatched_icon = icon1; - select = TRUE; + if (unmatched_icon != NULL && icon == unmatched_icon) { + select = FALSE; } + } - - selection_changed |= icon_set_selected - (container, icon, select); + } else { + ArtIRect icon1_rect, icon2_rect; + ArtIRect icon_rect; + int x0, x1, y0, y1; + int x, y; + + icon_get_bounding_box (icon1, + &icon1_rect.x0, &icon1_rect.y0, + &icon1_rect.x1, &icon1_rect.y1); + icon_get_bounding_box (icon2, + &icon2_rect.x0, &icon2_rect.y0, + &icon2_rect.x1, &icon2_rect.y1); + + x0 = MIN (icon1_rect.x0, icon2_rect.x0); + x1 = MAX (icon1_rect.x1, icon2_rect.x1); + y0 = MIN (icon1_rect.y0, icon2_rect.y0); + y1 = MAX (icon1_rect.y1, icon2_rect.y1); + - if (unmatched_icon != NULL && icon == unmatched_icon) { - select = FALSE; + for (p = container->details->icons; p != NULL; p = p->next) { + icon = p->data; + + /* select all items whose center is inside the selection rectangle */ + icon_get_bounding_box (icon, + &icon_rect.x0, &icon_rect.y0, + &icon_rect.x1, &icon_rect.y1); + + x = (icon_rect.x0 + icon_rect.x1) / 2; + y = (icon_rect.y0 + icon_rect.y1) / 2; + + select = (x > x0 && x < x1 && y > y0 && y < y1); + selection_changed |= icon_set_selected + (container, icon, select); } - + } if (selection_changed && icon2 != NULL) { @@ -4635,10 +4679,11 @@ NautilusIconData * nautilus_icon_container_get_first_visible_icon (NautilusIconContainer *container) { GList *l; - NautilusIcon *icon; + NautilusIcon *icon, *best_icon; GtkAdjustment *vadj; double x, y; double x1, y1, x2, y2; + double best_y1; vadj = gtk_layout_get_vadjustment (GTK_LAYOUT (container)); @@ -4647,6 +4692,8 @@ nautilus_icon_container_get_first_visibl &x, &y); l = container->details->icons; + best_icon = NULL; + best_y1 = 0; while (l != NULL) { icon = l->data; @@ -4654,13 +4701,22 @@ nautilus_icon_container_get_first_visibl eel_canvas_item_get_bounds (EEL_CANVAS_ITEM (icon->item), &x1, &y1, &x2, &y2); if (y2 > y) { - return icon->data; + if (best_icon != NULL) { + if (best_y1 > y1) { + best_icon = icon; + best_y1 = y1; + } + } else { + best_icon = icon; + best_y1 = y1; + } } } l = l->next; } - return NULL; + + return best_icon->data; } /* puts the icon at the top of the screen */ @@ -5152,7 +5208,7 @@ finish_adding_icon (NautilusIconContaine static void finish_adding_new_icons (NautilusIconContainer *container) { - GList *p, *new_icons, *no_position_icons; + GList *p, *new_icons, *no_position_icons, *semi_position_icons; NautilusIcon *icon; double bottom; @@ -5161,16 +5217,61 @@ finish_adding_new_icons (NautilusIconCon /* Position most icons (not unpositioned manual-layout icons). */ new_icons = g_list_reverse (new_icons); - no_position_icons = NULL; + no_position_icons = semi_position_icons = NULL; for (p = new_icons; p != NULL; p = p->next) { icon = p->data; if (!assign_icon_position (container, icon)) { no_position_icons = g_list_prepend (no_position_icons, icon); + } else if (!container->details->auto_layout && + icon->has_lazy_position) { + semi_position_icons = g_list_prepend (semi_position_icons, icon); } finish_adding_icon (container, icon); } g_list_free (new_icons); + if (semi_position_icons != NULL) { + PlacementGrid *grid; + + g_assert (!container->details->auto_layout); + + semi_position_icons = g_list_reverse (semi_position_icons); + + grid = placement_grid_new (container, TRUE); + + for (p = container->details->icons; p != NULL; p = p->next) { + icon = p->data; + + if (icon_is_positioned (icon) && !icon->has_lazy_position) { + placement_grid_mark_icon (grid, icon); + } + } + + for (p = semi_position_icons; p != NULL; p = p->next) { + NautilusIcon *icon; + int x, y; + + icon = p->data; + x = icon->x; + y = icon->y; + + find_empty_location (container, grid, + icon, x, y, &x, &y); + + icon_set_position (icon, x, y); + + placement_grid_mark_icon (grid, icon); + + /* ensure that next time we run this code, the formerly semi-positioned + * icons are treated as being positioned. */ + icon->has_lazy_position = FALSE; + } + + placement_grid_free (grid); + + g_list_free (semi_position_icons); + } + /* Position the unpositioned manual layout icons. */ if (no_position_icons != NULL) { g_assert (!container->details->auto_layout); @@ -5186,13 +5287,18 @@ finish_adding_new_icons (NautilusIconCon * nautilus_icon_container_add: * @container: A NautilusIconContainer * @data: Icon data. + * @has_lazy_position: Whether the saved icon position should only be used + * if the previous icon position is free. If the position + * is occupied, another position near the last one will + * be used. * * Add icon to represent @data to container. * Returns FALSE if there was already such an icon. **/ gboolean nautilus_icon_container_add (NautilusIconContainer *container, - NautilusIconData *data) + NautilusIconData *data, + gboolean has_lazy_position) { NautilusIconContainerDetails *details; NautilusIcon *icon; @@ -5212,6 +5318,7 @@ nautilus_icon_container_add (NautilusIco icon->data = data; icon->x = ICON_UNPOSITIONED_VALUE; icon->y = ICON_UNPOSITIONED_VALUE; + icon->has_lazy_position = has_lazy_position; icon->scale_x = 1.0; icon->scale_y = 1.0; icon->item = NAUTILUS_ICON_CANVAS_ITEM
Attachment:
signature.asc
Description: This is a digitally signed message part