On Tue, 2010-09-14 at 15:00 +0200, Kristian Rietveld wrote: [...] > As I also noted in the bug, I would not make GtkTreeViewColumn a stand-alone > class, rather, I would work on getting the algorithms that do the cell and > column layouting in separate classes and then have GtkTreeView, > GtkTreeViewColumn and GtkComboBoxMenu re-use this. Note that even though > cell layouting is done in GtkTreeViewColumn, the column layouting is done in > GtkTreeView. > > I think that these layouting algorithms in separate classes might actually be > useful public API, to reflect on the comment I made at the start of this > e-mail. > > There might be more "components" of GtkTreeView that could be useful to > refactor into new separate classes, for example the rendering loop, selection > handling, input event handling etc. My goal would be to refactor GtkTreeView > in such a way so that it (the original functionality) can be composed from > these separate classes. And also so that GtkIconView (and new kinds of such > views, Windows-style columnary perhaps?) could also be re-written by a > composition of these classes. This will reduce the amount of code that is > duplicated between GtkTreeView and GtkIconView, and in this case you can also > add GtkComboBox and GtkCellView to that list. Furthermore, the road for > creating variations of these "view" widgets with more flexible and special > layouting has then been opened.
Ok I've been giving this some real thought, considering the long list of requirements and scribbling things down on white papers. Before jumping straight into writing code I'd like to share these ideas with you and the list and see what I may have missed and what we can do to improve the plan. So to help stay on track without straying too too much, these are (my perceived) reasons for the said refactoring work: - Code sharing: A good refactoring of cell layouting logic into some classes that can be (more) easily reused by the major candidates GtkTreeView, GtkIconView and GtkComboBox[Menu]. - Adaptation for height-for-width support (currently only the GtkComboBox uses hfw'ness of cell renderers, big patch pending on treeviews could be better written based on the refactored code). - Alignment of GtkComboBox menu renderers currently cant be done as described in bug 629133. - While we're on the topic of refactoring the cell layouting code, I'd personally like to open up new avenues for rendering cell layouts in more dynamic ways (as I'll describe in more detail below); Rationale for this is if we're going to give this a go at all, we better be ambitious and awesome about it. Here's the big abstract picture I've come up with so far to address the above issues and come up with a more dynamic and reusable code base for cell rendering. I'll just go ahead and enumerate the classes and what they are intended for: ------------------------------------------------------------------ GtkCellArea ----------- A GtkCellArea would be an abstract class which implements GtkCellLayout and acts as a collection of cells which are rendered in a completely undefined way, GtkCellArea classes would be responsible for handling all geometric tasks in the laying out of cells: - Allocation of cell positions inside the area - Returning overall bounderies that the cells take up inside an area as well as returning the bountries of a single cell inside the area. This is important for widgets like TreeView and IconView who want to draw focus around a cell, a column or an entire row. - Returning the cell at a specified coordinate inside the area for a given treemodel row. This is needed for the sake of handling mouse-clicks so that the owner of the CellArea can go on to start editing a given cell, or activate an icon in a given cell. - Responding to height-for-width/width-for-height apis for a collection of cells for a given treemodel row. - Actually render the GtkCellArea for a given row into a given space/GdkRectangle. Conceptually, the GtkCellArea is for a cell renderer what a GtkContainer is for a GtkWidget. The main bonus of keeping the GtkCellArea as an abstract class and responding to some generalized apis is it opens up avenues for more complex implementations such as a tabular CellArea, or a cell-wrapping CellArea which could be more easily implemented in the future. GtkCellAreaBox -------------- A CellAreaBox would be the first concrete class implementation of the GtkCellArea, it would be orientable and when oriented horizontally it would pretty much act like how a GtkTreeViewColumn acts today. GtkCellAlignment ---------------- A GtkCellAlignment would be a very simple object class that is responsible for taking a collection of sizes into account. A GtkCellAlignment would be used as a GtkCellAreaBox delegate to achieve the horizontal alignment of cells across rows that the GtkTreeViewColumn does today. The CellAlignment helps in general to optimize the overall size requests of treeview rows, however where performance is not an issue; the use of CellAlignment by the GtkCellAreaBox can be optional, in this way allowing cell renderers to "flow naturally" across a GtkTreeView column (for instance, I would like to append an icon at the end of a text renderer and not have the annoying alignment/gap between the dynamic text length and the icon). For possible future tabular GtkCellArea classes (GtkCellAreaTable anyone ?) ; two GtkCellAlignments could be optionally used to aid in the alignment its child cells vertically and horizontally). GtkCellAreaManager ------------------ This would essentially be a cleaned up API and refactored version of the current GtkRBTree. The rbtree currently caches information about how a GtkTreeView is currently rendering a given model, it caches things such as which rows are expanded; the indentation level used by the treeview and most notably the variable height of rows. Some things that would change in the GtkCellAreaManager would be: - Rip out GtkTreeView specific information such as expanded rows and indentation. - Add a client data pointer to be defined by the user which describes what kind of data is cached in a row (all the treeview specific row cached stuff comes back here) - Add a callback to be defined by the user when the GtkCellAreaManager wants to update the cache for a given row. - Provide a way to invalidate the cache on a per-cache and per-row basis - Provide a configurable iterative process for updating the cache, this would be performed synchronously for all the visible rows and then fall off into the background only updating a configurable ~1000 rows at at time and then marking them "validated" for access. How does this all map to current GtkCellLayout implementations ? Most of the above text referrs to GtkTreeView, being the most complex configuration making use of these classes. The GtkIconView could most certainly reuse the GtkCellAreaBox object and orient it vertically or horizontally (text below or beside icon). The GtkComboBoxMenu solution for bug 629133, could simply use the GtkCellAreaBox oriented horizontally to draw the menu-items; the menu-items themselves would simply contain a single GtkDrawingArea and then call the GtkCellArea->render() method when the drawing area's expose themselves. Conclusion: There is a plethora of requirements relating to GtkTreeView in general, some of which I'm sure to have missed, some of which will surely present themselves as road-blocks while implementing the said refactoring. However the nature of code is that it doesn't all fit in a single brain at once, time runs thin and we have to start writing code soon ;-) So please, any thoughts, considerations, things I've missed will be great to share here. Thanks ! -Tristan _______________________________________________ gtk-devel-list mailing list gtk-devel-list@gnome.org http://mail.gnome.org/mailman/listinfo/gtk-devel-list