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 > > > <trista...@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 _______________________________________________ gtk-devel-list mailing list gtk-devel-list@gnome.org http://mail.gnome.org/mailman/listinfo/gtk-devel-list