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 586458 - Allow prelighting of a separate cell on hover
Allow prelighting of a separate cell on hover
Status: RESOLVED OBSOLETE
Product: gtk+
Classification: Platform
Component: Widget: GtkTreeView
2.14.x
Other Linux
: Normal enhancement
: ---
Assigned To: gtktreeview-bugs
gtktreeview-bugs
Depends on:
Blocks: 544103
 
 
Reported: 2009-06-20 10:37 UTC by Milan Bouchet-Valat
Modified: 2018-02-10 03:21 UTC
See Also:
GNOME target: ---
GNOME version: 2.27/2.28


Attachments
[GtkTreeView] Allow per-cell prelighting (6.68 KB, patch)
2010-06-14 14:03 UTC, Milan Bouchet-Valat
none Details | Review
Updated patch (6.67 KB, patch)
2010-06-15 09:17 UTC, Milan Bouchet-Valat
none Details | Review

Description Milan Bouchet-Valat 2009-06-20 10:37:47 UTC
This is the GTK part of bug "584846: "Eject/Unmount icon in Nautilus sidebar should have hover and click states". Now that we sometimes use GtkCellRendererPixbuf's as clickable icons, we need a way to give the usual feedback to the user, i.e. color changes on hover and click.

From the comment I've posted there:
I've tried to implement this some time ago, and the prelight-on-hover part is
really tricky to get with the current design of GtkTreeView. We already have an
option to highlight a renderer when the mouse pointer enters the row, but the
tree view has no real concept of an independent button that would be a renderer
(a cell, as opposed to a whole row).

Signals about the pointer entering an area only get transmitted by the tree
view on a row basis. Thus, you cannot know from the renderer POV when the mouse
has entered your cell, only when it has entered your row. Clicks are
transmitted to cell renderers because some computation of coordinates takes
place when such an event occurs; this behavior should be replicated every time
the pointer moves.

What do maintainers think?
Comment 1 Matthias Clasen 2009-06-21 00:26:16 UTC
The joys of misusing the treeview in new ways...

Your best bet is probably to look how prelighting is handled for expander arrows, and see if that can be generalized for cells in general.
Comment 2 Shaun McCance 2009-10-05 01:49:06 UTC
Seems like this would also be useful to allow GtkCellRenderToggles to have a prelight state, just like normal check buttons and radio buttons do.
Comment 3 Milan Bouchet-Valat 2010-06-12 14:36:51 UTC
See do_prelight() in gtktreeview.c. GtkTreeView sets GTK_RBNODE_IS_PRELIT when a node (row) has the pointer on it, and this gets translated to GTK_CELL_RENDERER_PRELIT in gtk_tree_view_bin_expose(), which is the most scary function of the file. Once GtkTreeViewColumns are passed the GTK_CELL_RENDERER_PRELIT flag, they send it directly to their GtkCellRenderers.

So the fix should go into the hardest part: GtkTreeView. The idea of prelighting of whole row should be changed to allow prelighting only a cell. do_prelight() already detects whether the pointer is over the arrow (expander) of the row, to prelight it separately. So it should also check what cell has the pointer, and set a different property that is passed to the rendering function. And in case a new GtkTreeView (e.g. 'cell-prelight') is set, GTK_RBNODE_IS_PRELIT would be ignored, only the corresponding cell/column would get GTK_CELL_RENDERER_PRELIT.

So nice! ;-)
Comment 4 Kristian Rietveld 2010-06-12 18:33:39 UTC
On a first thought, having a new kind of property on GtkTreeView as is proposed in comment 3, seems to make the most sense.  The actual name of the property is still up for discussion.  The implementation of this property should actually be quite trivial.  I would leave setting/unsetting GTK_RBNODE_IS_PRELIT intact.  The only thing that needs changing is propagating the GTK_RBNODE_IS_PRELIT setting to GTK_CELL_RENDERER_PRELIT on the cell renderers.  This should then no longer be set on all cell renderers, but only on the one that has focus.

I agree that this has a use for GtkCellRendererToggle as well, like mentioned in comment 2.  However, I think an additional complication comes into play here.  If you look at the actual GtkCheckButton (and related widgets):

 [x] This is a label

Then both the check and the label are highlighted.  Do we want to have the same behavior in GtkTreeView?  If yes, then we will need a way to relate two (or more) cells to each other.  It might be possible to re-use the keynav code for this, but that code has its limitations as well and does not work cross-column (unless there's only a single editable cell per row).  The keynav code might actually benefit from such "cell relations" as well I think.
Comment 5 Milan Bouchet-Valat 2010-06-13 09:01:01 UTC
(In reply to comment #4)
> On a first thought, having a new kind of property on GtkTreeView as is proposed
> in comment 3, seems to make the most sense.  The actual name of the property is
> still up for discussion.  The implementation of this property should actually
> be quite trivial.  I would leave setting/unsetting GTK_RBNODE_IS_PRELIT intact.
>  The only thing that needs changing is propagating the GTK_RBNODE_IS_PRELIT
> setting to GTK_CELL_RENDERER_PRELIT on the cell renderers.  This should then no
> longer be set on all cell renderers, but only on the one that has focus.
Actually, we have (re)started investigating this with Marcus Carlson yesterday, and this is the kind of solution we have. To be more precise, the current way of doings things is:
- tree view checks where cursor is
- if it notices cursor is on a given row, it marks the node with the GTK_RBNODE_IS_PRELIT flag
- the GTK_CELL_RENDERER_PRELIT flag is passed on next rendering to all columns, so that they each prelight the cell on the corresponding row

So our idea for now is to have a field in GtkTreeViewPrivate indicating with row the cursor is on. When our new property is TRUE, we would only pass GTK_CELL_RENDERER_PRELIT to the column that has the cursor.

> I agree that this has a use for GtkCellRendererToggle as well, like mentioned
> in comment 2.  However, I think an additional complication comes into play
> here.  If you look at the actual GtkCheckButton (and related widgets):
> 
>  [x] This is a label
> 
> Then both the check and the label are highlighted.  Do we want to have the same
> behavior in GtkTreeView?  If yes, then we will need a way to relate two (or
> more) cells to each other.  It might be possible to re-use the keynav code for
> this, but that code has its limitations as well and does not work cross-column
> (unless there's only a single editable cell per row).  The keynav code might
> actually benefit from such "cell relations" as well I think.
If there only are two columns in the tree view, then this is already possible setting the 'follow-state' property on the cell renderers. If not, I can't find what prevents you from packing two cell renderers in the same column, in which case with our solution they would both get prelit. Am I wrong?
Comment 6 Milan Bouchet-Valat 2010-06-13 09:06:14 UTC
(In reply to comment #5)
> So our idea for now is to have a field in GtkTreeViewPrivate indicating with
> row the cursor is on. When our new property is TRUE, we would only pass
> GTK_CELL_RENDERER_PRELIT to the column that has the cursor.
I meant "indicating which *COLUMN* the cursor is on", of course... ;-)
Comment 7 Milan Bouchet-Valat 2010-06-14 14:03:17 UTC
Created attachment 163592 [details] [review]
[GtkTreeView] Allow per-cell prelighting

Util now, prelighting was only possible for a whole row:
do_prelight() was detecting what node the pointer was in,
and gtk_tree_view_bin_expose() was passing to all columns
the GTK_CELL_RENDERER_PRELIT flag on the corresponding
renderers.

Add a new 'cell-prelight' property that allows prelighting
only the cell on the column where the pointer is. We detect
this column in do_prelight(), and store it as a new member
of GtkTreePrivate. It's then used in gtk_tree_view_bin_expose()
to only set the flag on renderers of this column.

Update tests/testtreeview so that the tree view uses this
behavior, and have a cell render colorize in response
to prelighting to test it. Note it's not visible with default
GTK theme.
Comment 8 Milan Bouchet-Valat 2010-06-14 14:14:02 UTC
So here's the result of Marcus's work on this. It works fine and seems to be a simple solution, fitting well in the general model of the tree view.

For some reason the default theme doesn't colorize pixbufs (even if the code seems to do this), so you have to install gtk-engines for your development version, and use something like:
GTK2_RC_FILES=/opt/gnome/share/themes/Clearlooks/gtk-3.0/gtkrc tests/testtreeview
But I'm sure you know this better than I do. ;-)

Feedback wanted! Two points of discussion are:
- I think this could be a nice default for 3.0, since I've yet to see a program using the old behavior of prelighting a whole row. Not a big deal in any sense, though.
- I've removed direct accessors to set the function since this property is rarely used.


And Marcus, I've changed
guint cell_prelight : 1;
to
gboolean cell_prelight : 1;
I think that was just a typo, but...

BTW, I need a better e-mail address for the Author field...
Comment 9 Matthias Clasen 2010-06-14 21:54:23 UTC
guint is right there, since gboolean is signed and not what you want in a bitfield.
Comment 10 Milan Bouchet-Valat 2010-06-15 09:17:15 UTC
Created attachment 163664 [details] [review]
Updated patch

It seems sometimes one should check before assuming others are mistaken... :-p

New patch brings back the guint. Comments on the core idea?
Comment 11 Tristan Van Berkom 2011-09-07 12:13:50 UTC
Since I saw this come up on the mailing list... and since these bug reports are just just old enough to predate GtkCellArea... better just leave a comment.

I did not look over the patch in detail but saw that it adds a saved
'prelight column' and 'prelight cell'.

General idea of how to implement this in 3.0 is:

  o GtkCellArea now handles 'events' in an abstract way, it's important
    that all the correct motion events are sent by the treeview to the
    GtkCellArea for the cell area to generate the enter/leave events
    properly (or just maintain a proper 'prelight' cellrenderer state).

  o Look at how GtkCellArea handles focus, as the cell area handles
    focus by listening to keyboard events, the GtkCellArea should also
    probably be responsable for driving the 'prelight cell' by handling
    the motion events

  o When rendering cells, the GtkCellArea adds the pseudo class for
    focused cells, it should also do so for the prelight cell.


Now this following part I'm not 100% sure about, but... if the GtkTreeView
already handles the prelight row that's great... the GtkTreeView still needs
to remember the prelight row (as it does remember the focus row) so that
the GtkCellArea can be told that it should be rendering the prelight
row (this is done iirc by passing a flag through the GtkCellRendererState
in gtk_cell_area_render()).
Comment 12 Matthias Clasen 2018-02-10 03:21:41 UTC
We're moving to gitlab! As part of this move, we are closing bugs that haven't seen activity in more than 5 years. If this issue is still imporant to you and
still relevant with GTK+ 3.22 or master, please consider creating a gitlab issue
for it.