Re: GtkTreeView Refactoring Considerations [was Re: Private types inside GTK+]
- From: Tristan Van Berkom <tristanvb openismus com>
- To: Kristian Rietveld <kris gtk org>
- Cc: gtk-devel-list gnome org
- Subject: Re: GtkTreeView Refactoring Considerations [was Re: Private types inside GTK+]
- Date: Mon, 01 Nov 2010 17:37:31 +0900
On Mon, 2010-11-01 at 15:15 +0900, Tristan Van Berkom wrote:
> On Mon, 2010-11-01 at 12:15 +0900, Tristan Van Berkom wrote:
> > On Sun, 2010-10-31 at 17:45 +0100, Kristian Rietveld wrote:
> > > On Sun, Oct 31, 2010 at 3:17 PM, Tristan Van Berkom
> > > <tristanvb openismus com> wrote:
> > > > Whew, ok I implemented GtkCellArea->render for GtkCellAreaBox for the
> > > > most part, however I'm still missing the GtkCellRendererState flags ;-)
> > > >
> > > > So for this part I was thinking it might make more sense to create
> > > > a new GtkCellAreaStateFlags type with just per-row states (and add that
> > > > as an argument to GtkCellArea->render() and also GtkCellArea->event())
> > >
> > > Most of the states in GtkCellRendererState are actually per-row states
> > > already (selected, focused, etc.) and are toggled by GtkTreeView and
> > > GtkTreeViewColumn when rendering the cells. Though one state,
> > > "sorted", is obviously per-column. Did you mean to have a new
> > > GtkCellAreaStateFlags that will have flags per *cell area* and thus
> > > per *column*?
> >
> > Ah no I meant per row, I was just seeing how treeviewcolumn does
> > some hackery around the FOCUS flag (i.e. when treeview column
> > receives the focus flag at render time, it immediately unflags
> > that and then re-applies the FOCUS bit to the renderer flags
> > for actual renderers it decided were to be passed the focus
> > flag).
> >
> > I suppose that the "sorted" flag also spans the whole column
> > and not a single cell... since a column can be composed of
> > one cell area (or even potentially more than one, but lets just
> > consider one area per column)... I suppose that all of the flags
> > defined by GtkCellAreaStateFlags are interesting to pass along
> > to the cell area at render/event time.
> >
> > >
> > > > and then somehow tidy up the code that in GtkTreeViewColumn is
> > > > currently:
> > > >
> > > > _gtk_tree_view_column_count_special_cells (tree_column)
> > >
> > > This function is part of implementing the key navigation behavior. A
> > > "special" cell is one that is editable or activatable. The rule is
> > > that if there's a single special cell in a column, a focus rectangle
> > > is drawn spanning all cells in that column. If there is more than one
> > > than the focus rectangle will be drawn around single cells. This
> > > works fine in many cases, but can of course be awkward in a few
> > > situations, so perhaps we want to make this configurable in the
> > > future. The same likely holds for a situation where you have a check
> > > box cell renderer and text cell renderer next to each other in a
> > > column:
> > >
> > > [x] [my label in a text renderer]
> > >
> > > Akin to a GtkCheckButton, you would want the check to toggle when the
> > > text renderer is clicked. And it would be natural if the focus
> > > rectangle spans the check box and the text renderer. But in other
> > > situations, with different cell renderers, you do not want this. This
> > > is also something to think about and improve for the future.
> > >
> >
> > Ah ok this clarifies things... I suppose if cell is activatable
> > or editable then it CAN_FOCUS :)
> >
> > I'll look into this ... I guess the treeview itself will have
> > to (and already does) I'll look into how cell areas can handle
> > their own internal focus chaining... probably they have to
> > notify the caller (treeview/column) that focus should be passed
> > to a leading or following column (or cell area), track the
> > currently focused cell etc.
>
> Ok I've ironed out some API for focus handling in the cell area.
>
> However there's one problem which I was still unable to come
> up with a solution for, it's kindof corner case and admittedly
> it wont be an issue for the initial refactor but for perfectionism's
> sake would be really nice to get right.
>
> First I'll present the api I've come up with so far:
>
>
> /* Grab focus comes with a "direction" parameter to tell
> * the area "from where" the focus is coming from,
> * the ->grab_focus() vfunc should be implemented by
> * subclasses so that they can set focus on the appropriate
> * cell (top/bottom/left or right cell depending on the
> * cell areas type of layout and "direction" were moving
> * focus from).
> */
> void gtk_cell_area_grab_focus (GtkCellArea *area,
> GtkDirectionType direction);
>
> /* This fires a signal on the GtkCellArea telling the owning
> * layout widget that focus should leave the cell for the
> * row indicated by "path", and that it should leave in the
> * indicated "direction".
> *
> * GtkCellLayout implementations should fire this signal when
> * handling key events for a given row, when there are no more
> * focusable cells and a keystroke would indicate a focus change.
> *
> * Then parent cell layouting widgets can trap this signal and move
> * focus along to another adjacent area... or to the same area and
> * move the cursor_row to the next treerow.
> */
> void gtk_cell_area_focus_leave (GtkCellArea *area,
> GtkDirectionType direction,
> gchar *path);
>
>
>
> /* set_can_focus() should be set by implementing classes such as
> * GtkCellAreaBox while renderers are added/removed.
> */
> void gtk_cell_area_set_can_focus (GtkCellArea *area,
> gboolean can_focus);
>
> /* This can be consulted by cell layouting widgets to see if it's
> * appropriate to call grab_focus() for this area or not.
> */
> gboolean gtk_cell_area_get_can_focus (GtkCellArea *area);
>
> /* Set/Get focus cell is mostly an internal thing, the focused cell
> * is set by a subclass like GtkCellAreaBox while it handles key
> * events that move the focus
> */
> void gtk_cell_area_set_focus_cell (GtkCellArea *area,
> GtkCellRenderer *renderer);
>
> /* Get the focused cell can be accessed by the superclass GtkCellArea
> * to activate/start-editing cells that have focus when processing
> * a key event that indicates activate/start-editing (i.e. ENTER key).
> */
> GtkCellRenderer *gtk_cell_area_get_focus_cell (GtkCellArea *area);
>
Gah, I just realized that these apis also have to depend on the
currently set row-data, since the same cell can be editable
in one row but not editable in the next (or even visible for
that matter).
Need to put a bit more thought into this... I'll come up with
something further thought out soon.
> -----------------------------------------------------------------
>
> Now, the interesting problem lies in the grab_focus()/focus_leave()
> semantics... I'm thinking tabular cell layouts here... imagine two
> possible GtkCellAreaTable's placed side by side and rendered for
> multiple rows in a treeview:
>
> Area A Area B
> +------------+--------------------------+ +------------------------+
> | 1 [A Single| 2[ Some editable text ] | |1[ Toggle | static text]|
> | activatable| 3[ More editable text ] | |2[ Editable text ]|
> | Icon] | 4[ Toggle | static text ]| |3[ Editable text ]|
> +------------+--------------------------+ +------------------------+
> (consider the activatable icon in area A as cell "A1", the toggle
> with static text in area B is a single focusable area... I'll refer
> to that as "B1")
>
> The problem here is that when transitioning focus from one area to
> another we would need some more, possibly geometric context to do
> it properly.
>
> So in the above picture, consider that for "Area A", if cell A1 or
> A2 has focus and we hit the UP arrow key... it will generate
> a GtkCellArea::focus-leave signal with the direction GTK_DIR_UP.
>
> Then logically the treeview(or column) would move the cursor
> row to the preceding visible row and call:
>
> gtk_cell_area_grab_focus(Area A, GTK_DIR_UP);
>
> The GtkCellArea "Area A" would then have to decide whether
> to give focus to A1, or to A4.
>
> The desirable thing would be to transition from:
> A1 --> A1
> A2 --> A4
>
> The same problem presents itself when we have a
> "focus-leave" signal generated for GTK_DIR_RIGHT,
>
> We would want to make the transitions:
> A2 --> B1
> A3 --> B2
> A4 --> B3
>
> Well... as I've already said I havent figured out a
> solution for this... I'm all ears.
>
> Other than that I think it will be simple enough
> to draw focus around "some but not all" cells
> in a single cell area.
>
> For instance if you have an area such as the area B above:
> +------------------------+
> |1[ Toggle | static text]|
> |2[ Editable text ]|
> |3[ Editable text ]|
> +------------------------+
>
> One would want to paint focus around the toggle renderer
> and the static text beside it, even it there are other
> focusable cells in the same GtkCellArea... this could
> be achieved easily enough by adding some semantics
> to set some "focus siblings" (I.e. above "static text"
> becomes a "focus sibling" of "Toggle").
>
> Cheers,
> -Tristan
>
> >
> >
> > > I think the GtkCellArea will also allow us to get rid of
> > > _gtk_tree_view_column_get_cell_at_pos(), which I have never really
> > > liked for some reason.
> > >
> > >
> > > > For focus handling and such I guess it will probably make sense to add:
> > > >
> > > > GtkCellArea->set/get_focus_cell()
> > >
> > > That could work if there is the possibility to set focus around all
> > > cells in the GtkCellArea as well and to disable focus for a given row
> > > (if there are no "special" cells in a row, then a focus rectangle is
> > > drawn around the entire row).
> >
> > Right, I think that the "focused cell" only needs to be called once
> > and is a global state for all rows, however at ->render() and ->event()
> > time the focus handling is ignored for 'flags' that dont contain
> > the FOCUS bit.
> >
> > The cell area itself should be smart enough to flag all the appropriate
> > cells with the FOCUS bit when rendering for a row (in other words things
> > dont really change too much from how treeview column processes this,
> > only that we have some added focus handling).
> >
> > > > Which is currently missing... then I suppose from ->event() if the row
> > > > for which an event is handled itself has focus, it will make sense to
> > > > activate the focused cell.
> > >
> > > I would follow the way GtkTreeViewColumn is currently handling this
> > > for now. Because when clicking on a check box renderer on a row that
> > > does not have focus (and focus in tree view only really plays when you
> > > are using key navigation), the click should likely activate the check
> > > box renderer anyway.
> >
> > Ah yes I was not so clear, I meant specifically for handling key
> > events... the base GtkCellAreaClass would be responsible for
> > activating a focused cell if present, when processing the ENTER
> > key on a focused row... if the base class did not do anything;
> > the subclass GtkCellAreaBox will go ahead and process mouse events,
> > thus activating the right renderer directly (as well as giving the
> > appropriate cell "focus").
> >
> > Thanks a lot for your insights and help !
> >
> > Cheers,
> > -Tristan
> >
> >
> > _______________________________________________
> > gtk-devel-list mailing list
> > gtk-devel-list gnome org
> > http://mail.gnome.org/mailman/listinfo/gtk-devel-list
>
>
> _______________________________________________
> gtk-devel-list mailing list
> gtk-devel-list gnome org
> http://mail.gnome.org/mailman/listinfo/gtk-devel-list
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]