GtkComboBox design -- first draft

After the discussion on gtk-devel-list and a discussion with Owen on
IRC, I decided to write something down and post it to the list. This is
just something to start with and far from perfect. Though I hope it's a
step in the right direction.

Suggestions/comments/etc are very welcome.




Design & API

The base combo box, GtkComboBox, will become the base of the new combo
box/option menu framework. The "click widget and "drop down widget" will be
construct-only properties, so subclasses of GtkComboBox are able to replace

GtkComboBox will be a non-editable combo box. A style property will be
provided to switch between "Windows-style" (using a list) and "UNIX-style"
(using a menu). The API will of course be the same and the style property
is meant to be used by themes only. This way we support both Windows-like and
UNIX-like themes, while providing the same API for the programmer.

In order to provide the combo box with data, we use the following functions to
hook up a model:

    void gtk_combo_box_set_model          (GtkComboBox      *combo_box,
                                           GtkTreeModel     *model);
    void gtk_combo_box_pack_start         (GtkComboBox      *combo_box,
                                           GtkCellRenderer  *renderer,
                                           gboolean          expand);
    void gtk_combo_box_pack_end           (GtkComboBox      *combo_box,
                                           GtkCellRenderer  *cell,
                                           gboolean          expand);
    void gtk_combo_box_clear              (GtkComboBox      *combo_box);
    void gtk_combo_box_get_cell_renderers (GtkComboBox      *combo_box);
    void gtk_combo_box_set_attributes     (GtkComboBox      *combo_box,
                                           GtkCellRenderer  *renderer,
    void gtk_combo_box_add_attribute      (GtkComboBox      *combo_box,
                                           GtkCellRenderer  *renderer,
                                           const gchar      *attribute,
                                           gint              column);
    void gtk_combo_box_clear_attributes   (GtkComboBox      *combo_box,
                                           GtkCellRenderer  *renderer);
    void gtk_combo_box_set_spacing        (GtkComboBox      *combo_box,
                                           gint              spacing);
    void gtk_combo_box_get_spacing        (GtkComboBox      *combo_box);

These functions will just work like their counterparts in GtkTreeViewColumn.
In the list-mode we will use a GtkTreeView displaying the list as "drop down
widget", and a widget rendering the cell as "click widget". In the menu-mode,
we will use a special GtkMenuItem (which renders the cell) in a menu and a
widget rendering the cell as "click widget".

We can use something like this to get the selected item:

    GtkTreePath *gtk_combo_box_get_selected (GtkComboBox  *combo_box);

The only useful signal I can think of at this moment is ::item_selected. I
don't see much use in providing signals like ::dropped_down.

Recent discussions at gtk-devel-list indicated that there's a need to support
grids of items, including row/column spanning. This is doable for the
menu-style, but nearly impossible for the list-style. Because of that I think
it's better to provide a GtkComboBoxGrid. Advantages:

* we don't have to deal with the gridding-in-menus-and-lists problem
* we move the gridding API out of the base class

This combo box can support arbitrary widgets. The idea is to use a GtkTable
as "drop down widget" and the selected GtkWidget as "click widget". Because of
the arbitrary widget support, this widget will have to disable the
drag-and-release selection method in the base GtkComboBox.

Possible API:

    void gtk_combo_box_grid_set_size (GtkComboBoxGrid  *combo_grid,
                                      guint             row,
                                      guint             columns);
    void gtk_combo_box_grid_attach   (GtkComboBoxGrid  *combo_grid,
                                      GtkWidget        *child,
                                      gboolean          selectable,
                                      guint             left_attach,
                                      guint             right_attach,
                                      guint             top_attach,
                                      guint             bottom_attach,
                                      GtkAttachOptions  xoptions,
                                      GtkAttachOptions  yoptions);
    void gtk_combo_box_grid_remove   (GtkComboBoxGrid  *combo_grid,
                                      GtkWidget        *child);

    GtkWidget *gtk_combo_box_grid_get_selected (GtkComboBoxGrid *combo_grid);

We don't use a GtkTreeModel here to fill the combo box. This is in fact
possible with a custom GtkTreeModel, but you would have to fill about 8
columns, which isn't very convenient to use.

There may be a use here for more functions from GtkTable, like
_set/get_homogeneous. Of course programmers can get a reference to the
GtkTable widget the combo uses, but we want to keep programmers from poking
in the internals.

Another useful combo box is a GtkComboBoxText. This one uses a menu or list as
"drop down widget" depending on the style property and uses a GtkEntry (or a
GtkEntryCompletion, with completion/history support?) as child widget.

This combo box doesn't need much other API, as you can add entries through the
GtkTreeModel. Though we need some API for the history/completion code, or to
interface with a 'GtkEntryCompletion' if we decide to put the
history/completion code directly into a special entry.

GAL's stack combo box is another candidate. Though I think this is a
specialized case and won't be used much, so it shouldn't be in GTK+. Please
correct me if I'm wrong here :).


The UI for the UNIX-style menu-like combo box is pretty clear. I think it
should just look like the current GtkOptionMenu. The Windows-style combo box
looks like an entry with an arrow pointing downwards. Though the "entry"
renders the selected cell. Both styles need some kind of widget to render the
cells. We can just put that code in gtkcombobox.c, though it may be useful to
create a new, public widget to do this.

Another issue is whether the drop-down widget should be tearable. Yes, no or

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