Thoughts on combo replacement



At Kris's request, here is a writeup of what I remember of the
thinking I did a year or so about a GtkCombo and GtkOptionMenu
replacement.  This is nothing as elaborate as Havoc's file selection
research, just a dump of some ideas into an email. (Cc'ing Jody in
case he has any thoughts to add from the perspective of having used
the Gal widgets in Gnumeric.)

Regards,
                                        Owen

Basic ideas:
============

 * There should be no API difference between:

    Non-editable combobox
    Option-Menu

   The choice between the two styles of display, if we offer it at all, should
   be a theme preference.

 * The same choice of menu or drop down list should also exist if you
   are implementing a history for an editable entry. That is, if you
   have option menus, the history on an entry should appear as something like:


    +-------------------------+----+
    |                         | /\ |
    |                         | == |
    |                         | \/ |
    +-------------------------+----+

  With the option-menu double arrow, and clicking on it should give you a 
  drop down menu. I believe the Macintosh equivalent of a combobox
  works this way.

 * While the gal combobox code supports arbitrary widgets in the drop down
   portion, I don't think that is actually useful. The only use of it I've
   seen is in the color-combo, where you have a bunch of colors and a 
   GnomeColorPicker for a custom color. But the GnomeColorPicker effectively
   acts like just another menu item, so I don't see any requirement to have
   a widget for it.

   Supporting arbitrary widgets causes problems:

    - It will compromise the ability to control the exact behavior of navigation
      (especially keynav) in the drop down portion.

    - It means you can't make switching between menus and "lists' a theme option.

   So, if we can avoid this (and I think we can) we should.

 * On the other hand, supporting grids of items (colors, patterns, tools, symbols)
   is definitely a necessary feature. 

   There are two levels of grid support... supporting regular grids, and supporting
   grids with row/column spanning. (The color combo used by gnumeric uses
   has the color-picker item span multiple columns.)

   There are probably legitimate uses for row/column spanning, but I'm not sure
   that it is worth the considerable extra complexity that it would add to the
   API.

   To support the menu style of display with gridded items, we'll have to add
   gridding support to GtkMenu, which won't be particularly fun. (Nothing with
   GtkMenu* is.) But is potentially useful in general.

 * One thing that we probably should support is items in the dropdown that 
   are combinations of, say, text and pictures. A typical example of this
   people do is a dropdown country list with flags next to each country.
   (I don't think this is a good idea ui-wise, but people want to do it.)

 * As far as the non-menu part of the combo goes, the possibilities I'm aware
   of are:
 
    1a) Display of the currently selected item in the list, not a separate control.
    1b) Display of the currently selected item in the list,
        as a button you can click on that does something other than pop down
        the menu/list.

    2a) An independent view-only widget, not a separate control
    2b) An independent interactive widget.

   An important special case of 2b) is an entry, which you may want to interact
   with the items in the drop-down list - possibilities include:
 
    - Non-editable entry, selects items from the list in response to input 
      (quite possibly be keynav features for 1a?)

    - Allow the user to enter arbitrary text, but then restrict it to an
      item in the list on focus out. (GtkCombo supports this somewhat
      dubious functionality.)

    - Completion against items in the list (but note that completion is really
      a separate and more complex issue... both Mozilla and IE make
      the completion dropdown different from the history dropdown; the completion
      dropdown displays only current completions, will complete match
      www.gtk.org against http://www.gtk.org in the history list and so forth.)
      
API thoughts
============

 * There is a temptation to use cell renderers to represent the contents of the
   list; advantages of this:
 
    - API reuse.
    - Some code reuse. (Though you'd have to duplicate most of GtkTreeViewColumn)
    - Quite flexible.
 
   To handle the menu part, you would create a menu item that used GtkCellRenderers
   to render its contents ... there is nothing in GtkCellRenderer
   that I know of that is particularly tied to renderering in text/base
   contexts rather than in a fg/bg context.

   And (as long as you didn't want to support row-spanning) you could just use
   a GtkTreeView to display the contents when in list mode.

   The API would presumably consist of something like:

    void gtk_combo_view_set_model      (GtkComboView     *combo_view,
                                        GtkTreeModel     *model);
    void gtk_combo_view_pack_start     (GtkComboView     *combo_view,
                                        GtkCellRenderer  *renderer,
                                        gboolean          expand);
    void gtk_combo_view_set_attributes (GtkComboView     *combo_view,
                                        GtkCellRenderer  *renderer,
                                        ...);
    void gtk_combo_view_set_n_cols     (GtkComboView     *combo_view,
                                        gint              n_cols);

   This API is not really amenable to row/column spanning, though you
   could imagine making one of the columns of the model be the number
   of columns for the item to allow for the simplest cases.

 * The main alternative to using cell renderers would be a simple clist-like
   text, image, or image-and-combo design. A straw man API might be:

    GtkComboItem *gtk_combo_item_new        (void);
    void          gtk_combo_item_set_text   (GtkComboItem *item, const char *text);
    void          gtk_combo_item_set_markup (GtkComboItem *item, const char *markup);
    void          gtk_combo_item_set_image  (GtkComboItem *item, GdkPixbuf *image);

    void gtk_combo_box_append (GtkComboBox     *combo_box,
			       GtkComboItem    *item);
    void gtk_combo_box_attach (GtkComboBox     *combo_box,
			       GtkComboItem    *item,
			       guint		left_attach,
			       guint		right_attach,
			       guint		top_attach,
			       guint		bottom_attach,
			       GtkAttachOptions xoptions,
			       GtkAttachOptions yoptions);
    void gtk_combo_box_remove (GtkComboBox     *combo_box, 
                               GtkComboItem    *item);

   Row/column spanning is more natural here, but would still pose problems
   for using a GtkTreeView to implement the list mode.

 * With either possibility there would be a ::item-selected signal when the
   user chose an item from the combo, it would presumably take a GtkTreePath
   for the tree-view API and a GtkComboItem * for the second API.

 * The base combo widget should support probably support all of the 1a), 1b), 2a), 2b) 
   possibilities for the non-menu widget. 

   If we want text-combo or color-combo widgets, it would make sense for them
   to be subclasses of the base widget, as in the gal API.

Questions
=========

 * Is the idea that "every thing acts like a menu item" sufficient?

 * Is row/column spanning for gridded items necessary?

 * What are the relevant widgets in the competing toolkits (WinForms, Swing, Qt)?
   what do they support?



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