After an evaluation, GNOME has moved from Bugzilla to GitLab. Learn more about GitLab.
No new issues can be reported in GNOME Bugzilla anymore.
To report an issue in a GNOME project, go to GNOME GitLab.
Do not go to GNOME Gitlab for: Bluefish, Doxygen, GnuCash, GStreamer, java-gnome, LDTP, NetworkManager, Tomboy.
Bug 697645 - Better range selection
Better range selection
Status: RESOLVED FIXED
Product: gnome-documents
Classification: Core
Component: general
unspecified
Other Linux
: Normal normal
: ---
Assigned To: GNOME documents maintainer(s)
GNOME documents maintainer(s)
Depends on:
Blocks:
 
 
Reported: 2013-04-09 15:03 UTC by Alexander Larsson
Modified: 2013-04-29 13:13 UTC
See Also:
GNOME target: ---
GNOME version: ---


Attachments
Make multi range selection work right (7.61 KB, patch)
2013-04-09 15:03 UTC, Alexander Larsson
committed Details | Review
Support rubberband selection in selection mode (7.04 KB, patch)
2013-04-09 15:03 UTC, Alexander Larsson
reviewed Details | Review
Change SELECTED model row to int to allow new selection features (835 bytes, patch)
2013-04-09 15:03 UTC, Alexander Larsson
needs-work Details | Review
gd-main-view: Make selection_mode_do_select_range handle any order (1.22 KB, patch)
2013-04-11 09:21 UTC, Alexander Larsson
committed Details | Review
Make multi range selection work right (4.81 KB, patch)
2013-04-11 09:21 UTC, Alexander Larsson
committed Details | Review
gd-main-view: Add rubberband selection (20.47 KB, patch)
2013-04-11 20:31 UTC, Alexander Larsson
committed Details | Review
some drawing trouble (117.49 KB, image/png)
2013-04-12 01:20 UTC, Matthias Clasen
  Details
maybe the same ? (150.73 KB, image/png)
2013-04-12 01:21 UTC, Matthias Clasen
  Details
gtk3: Support .rubberband in .content-view (1009 bytes, patch)
2013-04-12 08:26 UTC, Alexander Larsson
committed Details | Review
main-view: Support ctrl-drag and right-drag to switch to selection mode (3.06 KB, patch)
2013-04-12 10:33 UTC, Alexander Larsson
committed Details | Review
main-view: Support CTRL/SHIFT-space/enter to select items (4.63 KB, patch)
2013-04-12 10:42 UTC, Alexander Larsson
committed Details | Review
gd-main-view: Fix "stuck drag" after rubberband selection (946 bytes, patch)
2013-04-15 11:26 UTC, Alexander Larsson
committed Details | Review

Description Alexander Larsson 2013-04-09 15:03:10 UTC
The range selection in gnome-documents is pretty weak atm. The shift-click range-selection is kinda broken wrt how it usually works (it picks the "nearest" selected item and ranges to it rather than the last non-range selected item.

Also, there is no support for rubberband selection.

This patchset is a RFC for how this could work better.
Comment 1 Alexander Larsson 2013-04-09 15:03:36 UTC
Created attachment 241064 [details] [review]
Make multi range selection work right

When you range select you want the range to start from the last
single selection you made, not from some random selected item. For instance
If you first select item 3-5 and then 9-7 you want 7,8,9 selected
not (like now) 6,7.

Instead of tracking just a boolean for the selection we keep
track of an integer (which is backwards API/ABI compatible with
a gboolean), where non-zero means selected. Any time we make an initial
(i.e. non-range) selection (which may be the start of a range) we
pick a new value for the selection, and this way we can find the
last initial selection when doing a range selection. We keep
the old code as a fallback if the user stiff uses boolean for
the list model column, as that always converts values to 0 or 1.
Comment 2 Alexander Larsson 2013-04-09 15:03:40 UTC
Created attachment 241065 [details] [review]
Support rubberband selection in selection mode
Comment 3 Alexander Larsson 2013-04-09 15:03:49 UTC
Created attachment 241066 [details] [review]
Change SELECTED model row to int to allow new selection features
Comment 4 Cosimo Cecchi 2013-04-10 14:07:21 UTC
Review of attachment 241064 [details] [review]:

Thanks for the patch. The behavior that your patch introduces is definitely better, and I think we should do something to this effect.
I am not sure about the approach: why do you need to store the "selection generation" in the model? Can't you save the GtkTreePath of the initial selection item in GdMainView's private struct and use that instead?

::: libgd/gd-main-view.c
@@ +485,3 @@
+	  self->priv->initial_selection_generation++;
+	  if (self->priv->initial_selection_generation < 0)
+	    self->priv->initial_selection_generation = INITIAL_SELECTION_GENERATION_START;

How could self->priv->initial_selection_generation < 0 happen here? Overflow?
Comment 5 Cosimo Cecchi 2013-04-10 14:20:06 UTC
Review of attachment 241065 [details] [review]:

I think being able to use rubberband selection while in selection mode would indeed be useful.
Some comments on the patch:
- it's missing the draw part of the rubberband
- as far as I can see, this should be possible to implement even if we don't change the model column to an integer; just toggle the selected values for any item inside the rubberband range (that's also how it works e.g. in Nautilus).

::: libgd/gd-main-view.c
@@ +382,3 @@
+      gtk_tree_path_free (path);
+      iter = *first_element;
+      iter = *last_element;

This looks like an optimization that could go in a separate patch.
Comment 6 Cosimo Cecchi 2013-04-10 14:20:29 UTC
Review of attachment 241066 [details] [review]:

I'd rather find a way to avoid this, as explained in previous comments.
Comment 7 Alexander Larsson 2013-04-10 18:57:43 UTC
Review of attachment 241064 [details] [review]:

For the same reason we store the selection in general in the model: The model can change over time, invalidating the tree paths. For instance, a new file may pop up at the first position, and now your tree path points to the item before the one you selected.
Comment 8 Alexander Larsson 2013-04-10 18:58:02 UTC
Review of attachment 241064 [details] [review]:

::: libgd/gd-main-view.c
@@ +485,3 @@
+	  self->priv->initial_selection_generation++;
+	  if (self->priv->initial_selection_generation < 0)
+	    self->priv->initial_selection_generation = INITIAL_SELECTION_GENERATION_START;

yes, overflow.
Comment 9 Alexander Larsson 2013-04-10 19:01:10 UTC
Review of attachment 241065 [details] [review]:

Do we really need to draw the rubberband? The selection is visible in the checkboxes.

toggling would work, i'm not sure that is expected behaviour in general though. Does other apps than nautilus do that?

::: libgd/gd-main-view.c
@@ +382,3 @@
+      gtk_tree_path_free (path);
+      iter = *first_element;
+    }

Its not an optimization. Its required because we now call do_select_range() without knowing the order of first_element and last_element, making it break when you rubberband to the left.
Comment 10 Alexander Larsson 2013-04-11 09:21:42 UTC
Created attachment 241230 [details] [review]
gd-main-view: Make selection_mode_do_select_range handle any order

This makes the function work no matter what order the two iters
are in the model, where previously it would break unless first_element
was before last_element.
Comment 11 Alexander Larsson 2013-04-11 09:21:46 UTC
Created attachment 241231 [details] [review]
Make multi range selection work right

When you range select you want the range to start from the last
single selection you made, not from some random selected item. For instance
If you first select item 3-5 and then 9-7 you want 7,8,9 selected
not (like now) 6,7.

We keep the column id of the last item we initially selected (i.e. no
range select). If this item disappears or something we fall back on the
old code.

We can also simplify the selection_mode_select_range code a bit
now that selection_mode_do_select_range handles ranges in any order.
Comment 12 Cosimo Cecchi 2013-04-11 16:00:48 UTC
Review of attachment 241230 [details] [review]:

Looks good, thanks!
Comment 13 Cosimo Cecchi 2013-04-11 16:03:50 UTC
Review of attachment 241231 [details] [review]:

Looks good to me, thanks!

::: libgd/gd-main-view.c
@@ +379,3 @@
+			      GD_MAIN_COLUMN_ID, &id,
+			      -1);
+	  if (id != NULL && strcmp (id, self->priv->last_selected_id) == 0)

Can use g_strcmp0 here instead.
Comment 14 Alexander Larsson 2013-04-11 20:29:51 UTC
Attachment 241064 [details] pushed as b82e4c3 - Make multi range selection work right
Attachment 241230 [details] pushed as 70f3b79 - gd-main-view: Make selection_mode_do_select_range handle any order
Attachment 241231 [details] pushed as b82e4c3 - Make multi range selection work right
Comment 15 Alexander Larsson 2013-04-11 20:31:37 UTC
Created attachment 241302 [details] [review]
gd-main-view: Add rubberband selection

We support a rubberband-like drag-selection when in selection
mode.
Comment 16 Matthias Clasen 2013-04-12 01:20:41 UTC
Created attachment 241316 [details]
some drawing trouble
Comment 17 Matthias Clasen 2013-04-12 01:21:11 UTC
Created attachment 241317 [details]
maybe the same ?
Comment 18 Matthias Clasen 2013-04-12 01:29:46 UTC
few observations on the rubberband selection (other than the drawing problem in those screenshots):

- need to scroll during selection

- it would feel much more natural if I could start the selection by click-and-drag, rather than manually switching to selection mode and then starting to drag

some observations on range selection:

- shift/control-click works as expected

- shift/control-space or enter doesn't. Would be nice to make these work the same as their mouse counterparts
Comment 19 Alexander Larsson 2013-04-12 08:26:28 UTC
Created attachment 241326 [details] [review]
gtk3: Support .rubberband in .content-view

This adds a .content-view.view.rubberband selector for the rubberband.
If this is not set then the ".view.rubberband" and ".content-view.view"
both match at the same specificity, and the later wins due to it
being listed after.
Comment 20 Alexander Larsson 2013-04-12 08:27:55 UTC
Sorry, i forgot this patch to gnome-themes-standard that is also needed. It should fix the first issue. I have not seen the second drawing issue though.
Comment 21 Alexander Larsson 2013-04-12 09:05:13 UTC
About the behaviour:

Yes, scrolling is needed.

non-selection-mode click-and-drag means initiation of DnD of the icon, so I don't think we can use that as is. However, we currently allow ctrl-click and right-click to mean select and switch to selection mode, so it makes sense to allow ctrl-drag and right-drag to initiate a drag selection even when not in selection mode. Another alternative is to allow drag to start if you click outside any icon and start dragging. However, this doesn't work in the list view, and is a bit fiddly, so I don't think its a good idea.

ctrl-click is need in the traditional icon view because the default operation of click there is to unselect the current and select the clicked item. This is not all that important in the selection mode because it is much more focused on selecting multiple items by default (i.e. click does not unselect anything). So, in selection mode ctrl-click is not very important. The same is true for ctrl-space/enter. We do however support ctrl-click in non-selection-mode to mean select and switch to selection mode. We should add the same behaviour for ctrl-space/enter (plus make it do normal select if already in selection mode).

shift-space/enter currently does nothing in selection mode, we should make it do the same thing as shift-click.

Another thing that would be nice to have is a standard keyboard shortcut to switch to selection mode. Currently the only way is to keynav to the button and activate it, although with the above ctrl-space/enter on an item would also work. Maybe we could pick one of the F1-F12 keys for this?
Comment 22 Alexander Larsson 2013-04-12 10:33:43 UTC
Created attachment 241336 [details] [review]
main-view: Support ctrl-drag and right-drag to switch to selection mode
Comment 23 Alexander Larsson 2013-04-12 10:42:55 UTC
Created attachment 241338 [details] [review]
main-view: Support CTRL/SHIFT-space/enter to select items

CTRL is ignored in selection mode, but means switch to selection mode
and select in non-selection mode.

SHIFT means range-select, like shift+click.
Comment 24 Matthias Clasen 2013-04-12 14:23:40 UTC
Works much better, thanks.

One unrelated oddity that I notice in passing: In list view, you can select a row by hitting space or enter. But only if the focus is _not_ on the checkbox itself.
Comment 25 Cosimo Cecchi 2013-04-12 15:28:26 UTC
Review of attachment 241326 [details] [review]:

This looks good to me.
Comment 26 Cosimo Cecchi 2013-04-12 16:07:09 UTC
Review of attachment 241302 [details] [review]:

Thanks, this looks mostly good, with some (mostly stylistic) comments below.

::: libgd/gd-main-icon-view.c
@@ +272,3 @@
+	  gtk_style_context_get (context, state,
+				 "border-top-width", &border_width,
+  GTK_WIDGET_CLASS (gd_main_icon_view_parent_class)->draw (widget, cr);

Doesn't really matter, but I'd rather you used gtk_style_context_get_border()

::: libgd/gd-main-list-view.c
@@ +216,3 @@
+  if (self->priv->rubberband_start)
+    {
+  GdkRectangle lines_rect;

I don't think you need to save and restore the cairo context here; you only call gtk_render_* methods below and they all should save/restore the context already.

@@ +258,3 @@
+gd_main_list_view_set_rubberband_range (GdMainViewGeneric *mv,
+					GtkTreePath *start,
+	  gtk_tree_view_get_cell_area (GTK_TREE_VIEW (self),

As this is identical between the list and icon views, I wonder if you could move it to GdMainViewGeneric - you could e.g. store the rubberband paths using g_object_set_data() and/or have a private method that returns them from the generic if you don't want to do g_object_get_data() internally from the subclass.

::: libgd/gd-main-view.c
@@ +87,3 @@
 
+  if (self->priv->rubberband_select_first_path)
+    gtk_tree_path_free (self->priv->rubberband_select_first_path);

You can change all of these checks with calls to g_clear_pointer (also below and in the generic subclasses).
Comment 27 Cosimo Cecchi 2013-04-12 16:12:29 UTC
Review of attachment 241336 [details] [review]:

Looks good with the following comment fixed

::: libgd/gd-main-view.c
@@ +666,3 @@
+  force_selection =
+    (event->button == 3) ||
+    ((event->button == 1) && (event->state & GDK_CONTROL_MASK));

Can you please split this into a helper event_triggers_selection_mode() function? We also have a similar check in on_button_release_event().
Comment 28 Cosimo Cecchi 2013-04-12 16:17:47 UTC
Review of attachment 241338 [details] [review]:

Looks good to me.
Comment 29 Alexander Larsson 2013-04-15 09:19:54 UTC
Attachment 241302 [details] pushed as 700f73a - gd-main-view: Add rubberband selection
Attachment 241338 [details] pushed as f5388cb - main-view: Support CTRL/SHIFT-space/enter to select items
Comment 30 Alexander Larsson 2013-04-15 09:21:27 UTC
Actually, this is not fixed until libgd is revved in gnome-documents.
Comment 31 Alexander Larsson 2013-04-15 09:22:00 UTC
Comment on attachment 241326 [details] [review]
gtk3: Support .rubberband in .content-view

Attachment 241326 [details] pushed as 5adac13 - gtk3: Support .rubberband in .content-view
Comment 32 Alexander Larsson 2013-04-15 11:26:31 UTC
Created attachment 241556 [details] [review]
gd-main-view: Fix "stuck drag" after rubberband selection

We need to unset rubberband_select when we handle it or it will
cause us to not correctly handle later buttton releases.
Comment 33 Alexander Larsson 2013-04-15 11:26:59 UTC
Comment on attachment 241556 [details] [review]
gd-main-view: Fix "stuck drag" after rubberband selection

Attachment 241556 [details] pushed as e6117cf - gd-main-view: Fix "stuck drag" after rubberband selection
Comment 34 Cosimo Cecchi 2013-04-27 22:18:27 UTC
This was committed.
Comment 35 Alexander Larsson 2013-04-29 13:13:31 UTC
Scrolling is still needed, filed that as bug 699221