GtkGrid design document


I'm very glad to hear that GTK+ gurus are having a look to my grid
widget and as some of them suggested to me, I've written a small design
document to explain what this GtkGrid is.

I hope people have a clearer view at it after reading this document but
as I don't have much experience writting this kind of stuff I may have
forgotten to speak about important points. Fell free to yell at me in
this case.

Here it is:

GtkGrid widget design document
First draft: 2004/04/15

In this document I will try to explain the design goals of the Grid
widget, what it looks like and how it feels like, the implementation
done so far and the things that still need to be done.

* Design goals

- To have a widget to view and *edit* large amounts of data like
  database tables or scientific input/output data.
- Reuse as much code as possible from GtkTreeView
- Have an API as closer as possible to the GtkTreeView API to minimize
  the learning curve for this widget

* Comparison with other similar widgets

First of all, I'll try to explain the main difference between a sheet
like widget and a grid like widget. In a grid like widget every cell in
the same column has the same data type (e.g. all the cells are integer,
or strings, or images). In a sheet like widet this is not true.

We can see an (infamous) example of sheet like widget in Microsoft Excel
and in spreadsheet programas in general like OpenOffice calc program or 
Gnumeric. We can see an example of a grid like widget in Microsoft
Access (I don't know if we have an open source alternative to this one).
They both look like a table but they are not the same.

- GtkSheet. This is a widget in the gtkextra library that belongs to the
  sheet like widgets category. It works pretty well but uses its own
  combo and entry widgets for the cells. In other words, it duplicate a
  lot of work from GTK+

- QTable. This is a Qt widget that belongs to the sheet like widgets
  category. By default all the cells use a Text Renderer unless
  otherwise specified. As far as I know it is not a Model-View widget
  but I may be wrong.

- JTable. This is a Swing widget that belongs to the grid like widgets
  category. It has a model component and it uses renderers. This is the
  closest example to GtkGrid.

- GtkTreeView. This is a GTK+ widget that belongs to the grid like
  widgets category. GtkGrid has stolen *a lot* of code from it.

So why make another grid like widget for GTK+ if we already have the
GtkTreeView. Well, this leads us to the next point:

* Differences with GtkTreeView

- GtkGrid is designed for *fast* editing of the model. This means you
  don't have to go to a cell, activate it to enter the edit mode, edit
  the cell, press enter again to commit your changes and repeat all
  these keystrokes in the next cell. This behavior is fine if you just
  need to edit a few cells in your TreeView but if you want to edit
  almost every cell this is a pain.

- GtkGrid looks like a table (e.g. it paints horizontal and vertical
  lines to separate cells).

- You can not pack more than one CellRenderer in a GridColumn. I'm not
  sure about this design decision but to me it doesn't make sense to
  have more than one renderer by cell since the purpose of the grid is
  to edit data.

* Common architecture with GtkTreeView

GtkGrid and GtkTreeView have both a GtkTreeModel as its data model. In
the begining GtkGrid had a GtkListStore since it was not designed to
have tree like data. But Federico Mena convinced me that it would be
more flexible to use a GtkTreeModel and check for the
GTK_TREE_MODEL_LIST_ONLY flag. This way the user can implement the
GtkTreeModel interface and don't need to inherit from GtkListStore.

GtkGrid and GtkTreeView use both the GtkCellRenderer architecture. In
fact, GtkGrid is implementing some more renderers (GtkCellRendererSpin
and GtkCellRendererCombo) that are directly usable in the GtkTreeView.

GtkGrid does not use GtkTreeViewColumn but has its own GtkGridColumn.

* Work done so far

- We have a working grid with several different renderers.
- A pretty neat demo program that can switch between a Grid or a
  TreeView with just one line of code.
- We also have a small (10) test suit which is what I usually use to fix
  bugs and to make sure I don't add new bugs while fixings old ones.
- Finally we also have Python bindings but I guess this is not really
  interesting here.

* What need to be done

- Drag and drop of columns
- Drag and resize of columns
- Integrated popup menu to add and remove rows and to show and hide
- Gettext support
- Selection stuff (I haven't think a lot about this issue)
- Documentation: API Documentation and a short tutorial.

* API proposal for GtkGrid

GType          gtk_grid_get_type            (void);
GtkWidget     *gtk_grid_new                 (void);
GtkWidget     *gtk_grid_new_with_model      (GtkTreeModel  *model);
gint           gtk_grid_append_column       (GtkGrid       *grid,
					     GtkGridColumn *column);
gint           gtk_grid_insert_column       (GtkGrid       *grid,
					     GtkGridColumn *column,
					     gint           position);
gint           gtk_grid_remove_column       (GtkGrid       *grid,
					     GtkGridColumn *column);
void           gtk_grid_set_model           (GtkGrid       *grid,
					     GtkTreeModel  *model);
void           gtk_grid_get_background_area (GtkGrid       *grid,
					     GdkRectangle  *rect,
					     gint           col,
					     gint           row);
void           gtk_grid_get_cell_area       (GtkGrid       *grid,
					     GdkRectangle  *rect,
					     gint           col,
					     gint           row);
GtkAdjustment *gtk_grid_get_hadjustment     (GtkGrid       *grid);
void           gtk_grid_set_hadjustment     (GtkGrid       *grid,
					     GtkAdjustment *adjustment);
GtkAdjustment *gtk_grid_get_vadjustment     (GtkGrid       *grid);
void           gtk_grid_set_vadjustment     (GtkGrid       *grid,
					     GtkAdjustment *adjustment);
void           gtk_grid_get_visible_rect    (GtkGrid       *grid,
					     GdkRectangle  *visible_rect);
void           gtk_grid_scroll_to_cell      (GtkGrid       *grid,
					     gint           col,
					     gint           row);
void           gtk_grid_scroll_to_point     (GtkGrid       *grid,
					     gint           x,
					     gint           y);
GtkGridColumn *gtk_grid_get_column          (GtkGrid       *grid,
					     gint           n);
GList *        gtk_grid_get_columns         (GtkGrid       *grid);
gint           gtk_grid_get_current_col     (GtkGrid       *grid);
gint           gtk_grid_get_current_row     (GtkGrid       *grid);

gint           gtk_grid_get_row_height      (GtkGrid       *grid);
gint           gtk_grid_get_header_height   (GtkGrid       *grid);

* API proposal for GtkGridColumn

GType            gtk_grid_column_get_type            (void);
GtkGridColumn   *gtk_grid_column_new                 (void);
GtkGridColumn   *gtk_grid_column_new_with_attributes (const gchar
						      GtkCellRenderer *cell,
void             gtk_grid_column_set_title           (GtkGridColumn
						      const gchar   *title);
G_CONST_RETURN gchar * gtk_grid_column_get_title     (GtkGridColumn
void             gtk_grid_column_set_cell            (GtkGridColumn
						      GtkCellRenderer *cell);
GtkCellRenderer *gtk_grid_column_get_cell            (GtkGridColumn
void             gtk_grid_column_add_attribute       (GtkGridColumn
						      const gchar   *attribute,
						      gint           index);
void             gtk_grid_column_clear               (GtkGridColumn
gint             gtk_grid_column_get_width           (GtkGridColumn
void             gtk_grid_column_set_cell_data       (GtkGridColumn
						      GtkTreeModel  *model,
						      GtkTreeIter   *iter);
void             gtk_grid_column_cell_render         (GtkGridColumn
						      GdkWindow     *window,
						      GtkWidget     *widget,
						      GdkRectangle  *bground,
						      GdkRectangle  *cell_a,
						      GdkRectangle  *expose_a,
						      guint          flags);
void             gtk_grid_column_cell_event          (GtkGridColumn
						      GtkCellEditable **edit,
						      GdkEvent      *event,
						      gchar         *path_str,
						      GtkWidget     *widget,
						      GdkRectangle  *bground,
						      GdkRectangle  *cell_area,
						      guint          flags);
void             gtk_grid_column_cell_get_size       (GtkGridColumn
						      GtkWidget     *widget,
						      GdkRectangle  *cell_area,
						      gint          *x_offset,
						      gint          *y_offset,
						      gint          *width,
						      gint          *height);

GtkWidget       *gtk_grid_column_get_widget          (GtkGridColumn

/* Private functions, only GtkGrid is allowed to call them */
void _gtk_grid_column_realize_button   (GtkGridColumn *column,
				        GtkWidget     *grid);
void _gtk_grid_column_unrealize_button (GtkGridColumn *column,
					GtkWidget     *grid);

[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]