On Wed, 2010-10-27 at 08:59 +0200, Kristian Rietveld wrote: > On Tue, Oct 26, 2010 at 6:34 PM, Tristan Van Berkom > <trista...@openismus.com> wrote: > > Depending on the GtkSizeRequestMode in use by the parenting > > layout widget (hfw of wfh), generally only allocate_width() > > or allocate_height() will be called. However there will be > > cases where we get to further reduce computing of sizes at > > ->event()/->render() time by having both width and height > > allocated on a GtkCellArea (i.e. GtkTreeView's fixed-height-mode > > will allow us to just always know the complete allocated > > size and position of each renderer before rendering or handling > > events). > > > > After implementing the allocation methods, I'll move on > > to write/implement the actual ->render() and ->event() methods > > (which is more or less just copying what GtkTreeViewColumn > > does already). > > As soon as you have implemented the allocation methods, I can also > take over and do the GtkTreeViewColumn migration, together with > merging in the refactorings I was talking about earlier. > > > And finally what is still missing is a ->get_bounds() method > > to return a GdkRectangle of the actual space used by cell > > renderers inside the space allocated to a GtkCellArea (i.e. > > to allow parent layout widgets to smartly do their focus > > painting). > > So I take it we will not be doing focus drawing in GtkCellArea, but > rather in the parent layout widget, right? The focus drawing code for > GtkTreeView is currently at several places, so I will also look into > properly migrating that. > > Another thing what get_bounds() will be useful for is to make it > possible to start rubber banding when clicking on an area that is not > covered by cell contents (and is thus "background"). See bug 350618. > > > And then will come the grimy situation of pushing this all > > into GtkTreeView/GtkTreeViewColumn, looking in depth at > > validate_row again etc. (I'm sure I'll have some more > > questions and be happy to get any help in that area). > > As soon as you have the allocate methods in place that you described > above, tell me and I can quickly do a tree view migration during the > evenings and see how far we can come with the current API. >
Ok so I'm pretty much finished the request/allocation code... I've got as far as having a list of renderers with allocated positions and sizes come time for ->render()/->event() etc. If I understand correctly about cell_area vs background_area, the difference is basically only the focus line width... the reason for this is that we want cells to be allowed to fill the whole background area with a possible background color before we go ahead and pain a dotted focus line over the possibly modified background area. so currently the api on the GtkCellArea only takes a single cell_area when rendering, I think thats going to be fine in general and make for a clearer API (let me know if I missed something). So for this I'd like to add a "focus-line-width" property to the base class GtkCellArea, and just make the cell area implementations always request space for focus-line-width around cells ... then come time to render we just create a background/cell_area based on the focus-line-width and pass both areas to gtk_cell_renderer_render()... I'll do that part presently. So as an overview of what I have in the branch, heres some outlines on how the API is expected to be used particularly in the case of treeview in the form of some pseudo code: ------------------------------------------------------------ /* First cells are configured and setup with these brand * of apis */ GtkCellArea *gtk_cell_area_box_new (void); /* Note the 'align' argument here denotes whether the position * of the added cell is to be aligned with adjacent rows * using the same iter. */ void gtk_cell_area_box_pack_start (GtkCellAreaBox *box, GtkCellRenderer *renderer, gboolean expand, gboolean align); gint gtk_cell_area_box_set_spacing (GtkCellAreaBox *box); (gint spacing); /* By default the box is horizontal anyway */ gtk_orientable_set_orientation (GTK_ORIENTABLE (box)); /* Then at least one GtkCellAreaIter is aquired, its possible * to use several iters if one wants to group rendering by * row data (for instance by treeview depth, or GtkComboBox * will probably want to use one per submenu). */ GtkCellAreaIter * gtk_cell_area_create_iter (GtkCellArea *area); At this point we have an unrequested/unallocated 'iter' so we should only be performing requests... for treeview it should generally look like this: while (looping over some rows) { /* Apply the row data for every consecutive call */ void gtk_cell_area_apply_attributes(GtkCellArea *area, GtkTreeModel *tree_model, GtkTreeIter *iter); /* Run the get_preferred_width, we ignore returned results * for each row as that is stored in the iter */ void gtk_cell_area_get_preferred_width (GtkCellArea *area, GtkCellAreaIter *iter, GtkWidget *widget, gint *minimum_size, gint *natural_size) } /* Now we've saved some processing to sum up the alignments of every * row, so its important to go ahead and call: */ void gtk_cell_area_iter_sum_preferred_width (GtkCellAreaIter *iter); /* Now that we have some alignments of cells stored, we can access our * proposed widths */ void gtk_cell_area_iter_get_preferred_width (GtkCellAreaIter *iter, gint *minimum_width, gint *natural_width); /* ... And then we can get the heights of each row for that width */ while (looping over some rows) { /* Apply the row data for every consecutive call */ void gtk_cell_area_apply_attributes(GtkCellArea *area, GtkTreeModel *tree_model, GtkTreeIter *iter); /* Run the get_preferred_height_width() on a series of rows * We can gather the collective heights here for variable * row heights... or... */ void gtk_cell_area_get_preferred_width (GtkCellArea *area, GtkCellAreaIter *iter, GtkWidget *widget, gint width, gint *minimum_height, gint *natural_height); } /* ... Or for fixed row heights we can at this point sum up the * heights for that with using: */ void gtk_cell_area_iter_sum_preferred_height_for_width (GtkCellAreaIter *iter, gint for_width); /* And then access it at any time using: */ void gtk_cell_area_iter_get_preferred_height_for_width (GtkCellAreaIter *iter, gint for_width, gint *minimum_height, gint *natural_height); /* Now, before we can operate on the GtkCellArea we need to allocate * the iter in at least the orientation of the GtkCellAreaBox (this * is a requirement of the GtkCellAreaBox itself but might not be * a requirement for others, still I think generally its optimal to * have areas orientable and demand an allocation in their orientation). */ void gtk_cell_area_iter_allocate_width (GtkCellAreaIter *iter, gint width); /* Now we can go ahead and render cells, the previous call to * allocate the iter has performed the natural allocation * among any cells that are to be aligned across rows, * when rendering cells, any unaligned cells leading up to * an aligned cell will be done on demand for every row: */ while (looping over some rows) { /* Apply the row data for every consecutive call */ void gtk_cell_area_apply_attributes(GtkCellArea *area, GtkTreeModel *tree_model, GtkTreeIter *iter); /* Render the GtkCellArea */ void gtk_cell_area_render (GtkCellArea *area, GtkCellAreaIter *iter, GtkWidget *widget, cairo_t *cr, const GdkRectangle *cell_area); } /* When an allocated width for a height for width treeview changes, * its important to flush out the previous results (or when we * allow the width of the treeview to shrink in consequence of * data updates and we may want to re-request the whole thing), * for this we have: */ void gtk_cell_area_iter_flush (GtkCellAreaIter *iter); void gtk_cell_area_iter_flush_preferred_width (GtkCellAreaIter *iter); void gtk_cell_area_iter_flush_preferred_height_for_width (GtkCellAreaIter *iter, gint for_width); void gtk_cell_area_iter_flush_preferred_height (GtkCellAreaIter *iter); void gtk_cell_area_iter_flush_preferred_width_for_height (GtkCellAreaIter *iter, gint for_height); /* The contextual height-for-width flushing can be useful if the * implementing layout widget wants to synchronously respond to * gtk_widget_height_for_width() calls, it would perform the request * for a said width, accumulate the results and flush the cache... * however for large treeviews this might not be interesting. */ /* Another thing that may or may not be advantageous, the * GtkCellAreaIter provides some notifications so one can * watch the base preferred widths/heights as properties * as well as trap some signals which tell of heights which * change for a given width... this may be interesting for * some layouts who want to request things in the background * and just find out when the overall sum of the required * width has grown. */ ------------------------------------------------------------ So it's not so vague anymore, probably a little rough around the edges but taking shape. There remains only to implement the actual render/event methods, add the focus area introspecting... and then we should be ready to try this out. Cheers, -Tristan _______________________________________________ gtk-devel-list mailing list gtk-devel-list@gnome.org http://mail.gnome.org/mailman/listinfo/gtk-devel-list