diff --git a/ChangeLog b/ChangeLog index 01b82568cb..0ce1be66e9 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,18 @@ +Wed Oct 1 22:43:40 2003 Kristian Rietveld + + * gtk/gtkcellview.[ch]: implement the GtkCellLayout interface, drop + packing/attribute/cell data functions from the header, + (gtk_cell_view_set_cell_data): added support for cell data funcs. + + * gtk/gtkcombobox.[ch]: implement the GtkCellLayout interface, drop + packing/attribute/cell data functions from the header, implemented + cell data func support. + + * gtk/gtkcomboboxentry.c (gtk_combo_box_entry_new): updated + for the move to GtkCellLayout. + + * tests/testcombo.c (create_combo_box_grid_demo), (main): ditto. + 2003-10-01 Matthias Clasen * gtk/gtkaction.c (gtk_action_class_init): diff --git a/ChangeLog.pre-2-10 b/ChangeLog.pre-2-10 index 01b82568cb..0ce1be66e9 100644 --- a/ChangeLog.pre-2-10 +++ b/ChangeLog.pre-2-10 @@ -1,3 +1,18 @@ +Wed Oct 1 22:43:40 2003 Kristian Rietveld + + * gtk/gtkcellview.[ch]: implement the GtkCellLayout interface, drop + packing/attribute/cell data functions from the header, + (gtk_cell_view_set_cell_data): added support for cell data funcs. + + * gtk/gtkcombobox.[ch]: implement the GtkCellLayout interface, drop + packing/attribute/cell data functions from the header, implemented + cell data func support. + + * gtk/gtkcomboboxentry.c (gtk_combo_box_entry_new): updated + for the move to GtkCellLayout. + + * tests/testcombo.c (create_combo_box_grid_demo), (main): ditto. + 2003-10-01 Matthias Clasen * gtk/gtkaction.c (gtk_action_class_init): diff --git a/ChangeLog.pre-2-4 b/ChangeLog.pre-2-4 index 01b82568cb..0ce1be66e9 100644 --- a/ChangeLog.pre-2-4 +++ b/ChangeLog.pre-2-4 @@ -1,3 +1,18 @@ +Wed Oct 1 22:43:40 2003 Kristian Rietveld + + * gtk/gtkcellview.[ch]: implement the GtkCellLayout interface, drop + packing/attribute/cell data functions from the header, + (gtk_cell_view_set_cell_data): added support for cell data funcs. + + * gtk/gtkcombobox.[ch]: implement the GtkCellLayout interface, drop + packing/attribute/cell data functions from the header, implemented + cell data func support. + + * gtk/gtkcomboboxentry.c (gtk_combo_box_entry_new): updated + for the move to GtkCellLayout. + + * tests/testcombo.c (create_combo_box_grid_demo), (main): ditto. + 2003-10-01 Matthias Clasen * gtk/gtkaction.c (gtk_action_class_init): diff --git a/ChangeLog.pre-2-6 b/ChangeLog.pre-2-6 index 01b82568cb..0ce1be66e9 100644 --- a/ChangeLog.pre-2-6 +++ b/ChangeLog.pre-2-6 @@ -1,3 +1,18 @@ +Wed Oct 1 22:43:40 2003 Kristian Rietveld + + * gtk/gtkcellview.[ch]: implement the GtkCellLayout interface, drop + packing/attribute/cell data functions from the header, + (gtk_cell_view_set_cell_data): added support for cell data funcs. + + * gtk/gtkcombobox.[ch]: implement the GtkCellLayout interface, drop + packing/attribute/cell data functions from the header, implemented + cell data func support. + + * gtk/gtkcomboboxentry.c (gtk_combo_box_entry_new): updated + for the move to GtkCellLayout. + + * tests/testcombo.c (create_combo_box_grid_demo), (main): ditto. + 2003-10-01 Matthias Clasen * gtk/gtkaction.c (gtk_action_class_init): diff --git a/ChangeLog.pre-2-8 b/ChangeLog.pre-2-8 index 01b82568cb..0ce1be66e9 100644 --- a/ChangeLog.pre-2-8 +++ b/ChangeLog.pre-2-8 @@ -1,3 +1,18 @@ +Wed Oct 1 22:43:40 2003 Kristian Rietveld + + * gtk/gtkcellview.[ch]: implement the GtkCellLayout interface, drop + packing/attribute/cell data functions from the header, + (gtk_cell_view_set_cell_data): added support for cell data funcs. + + * gtk/gtkcombobox.[ch]: implement the GtkCellLayout interface, drop + packing/attribute/cell data functions from the header, implemented + cell data func support. + + * gtk/gtkcomboboxentry.c (gtk_combo_box_entry_new): updated + for the move to GtkCellLayout. + + * tests/testcombo.c (create_combo_box_grid_demo), (main): ditto. + 2003-10-01 Matthias Clasen * gtk/gtkaction.c (gtk_action_class_init): diff --git a/gtk/gtkcellview.c b/gtk/gtkcellview.c index 448851f59b..65d4d5b532 100644 --- a/gtk/gtkcellview.c +++ b/gtk/gtkcellview.c @@ -18,6 +18,7 @@ */ #include +#include #include #include #include @@ -35,6 +36,10 @@ struct _GtkCellViewCellInfo guint pack : 1; GSList *attributes; + + GtkCellLayoutDataFunc func; + gpointer func_data; + GDestroyNotify destroy; }; struct _GtkCellViewPrivate @@ -50,6 +55,7 @@ struct _GtkCellViewPrivate static void gtk_cell_view_class_init (GtkCellViewClass *klass); +static void gtk_cell_view_cell_layout_init (GtkCellLayoutIface *iface); static void gtk_cell_view_get_property (GObject *object, guint param_id, GValue *value, @@ -68,15 +74,34 @@ static void gtk_cell_view_size_allocate (GtkWidget *wid GtkAllocation *allocation); static gboolean gtk_cell_view_expose (GtkWidget *widget, GdkEventExpose *event); -static void gtk_cell_view_set_attributesv (GtkCellView *cellview, - GtkCellRenderer *renderer, - va_list args); static void gtk_cell_view_set_valuesv (GtkCellView *cellview, GtkCellRenderer *renderer, va_list args); +static GtkCellViewCellInfo *gtk_cell_view_get_cell_info (GtkCellView *cellview, + GtkCellRenderer *renderer); static void gtk_cell_view_set_cell_data (GtkCellView *cellview); +static void gtk_cell_view_cell_layout_pack_start (GtkCellLayout *layout, + GtkCellRenderer *renderer, + gboolean expand); +static void gtk_cell_view_cell_layout_pack_end (GtkCellLayout *layout, + GtkCellRenderer *renderer, + gboolean expand); +static void gtk_cell_view_cell_layout_add_attribute (GtkCellLayout *layout, + GtkCellRenderer *renderer, + const gchar *attribute, + gint column); +static void gtk_cell_view_cell_layout_clear (GtkCellLayout *layout); +static void gtk_cell_view_cell_layout_clear_attributes (GtkCellLayout *layout, + GtkCellRenderer *renderer); +static void gtk_cell_view_cell_layout_set_cell_data_func (GtkCellLayout *layout, + GtkCellRenderer *cell, + GtkCellLayoutDataFunc func, + gpointer func_data, + GDestroyNotify destroy); + + enum { PROP_0, @@ -108,8 +133,18 @@ gtk_cell_view_get_type (void) (GInstanceInitFunc) gtk_cell_view_init }; + static const GInterfaceInfo cell_layout_info = + { + (GInterfaceInitFunc) gtk_cell_view_cell_layout_init, + NULL, + NULL + }; + cell_view_type = g_type_register_static (GTK_TYPE_WIDGET, "GtkCellView", &cell_view_info, 0); + + g_type_add_interface_static (cell_view_type, GTK_TYPE_CELL_LAYOUT, + &cell_layout_info); } return cell_view_type; @@ -157,6 +192,17 @@ gtk_cell_view_class_init (GtkCellViewClass *klass) g_type_class_add_private (gobject_class, sizeof (GtkCellViewPrivate)); } +static void +gtk_cell_view_cell_layout_init (GtkCellLayoutIface *iface) +{ + iface->pack_start = gtk_cell_view_cell_layout_pack_start; + iface->pack_end = gtk_cell_view_cell_layout_pack_end; + iface->clear = gtk_cell_view_cell_layout_clear; + iface->add_attribute = gtk_cell_view_cell_layout_add_attribute; + iface->set_cell_data_func = gtk_cell_view_cell_layout_set_cell_data_func; + iface->clear_attributes = gtk_cell_view_cell_layout_clear_attributes; +} + static void gtk_cell_view_get_property (GObject *object, guint param_id, @@ -447,6 +493,209 @@ gtk_cell_view_expose (GtkWidget *widget, return FALSE; } +static GtkCellViewCellInfo * +gtk_cell_view_get_cell_info (GtkCellView *cellview, + GtkCellRenderer *renderer) +{ + GList *i; + + for (i = cellview->priv->cell_list; i; i = i->next) + { + GtkCellViewCellInfo *info = (GtkCellViewCellInfo *)i->data; + + if (info->cell == renderer) + return info; + } + + return NULL; +} + +static void +gtk_cell_view_set_cell_data (GtkCellView *cellview) +{ + GList *i; + GtkTreeIter iter; + GtkTreePath *path; + + g_return_if_fail (cellview->priv->displayed_row != NULL); + + path = gtk_tree_row_reference_get_path (cellview->priv->displayed_row); + gtk_tree_model_get_iter (cellview->priv->model, &iter, path); + gtk_tree_path_free (path); + + for (i = cellview->priv->cell_list; i; i = i->next) + { + GSList *j; + GtkCellViewCellInfo *info = i->data; + + if (info->func) + { + (* info->func) (GTK_CELL_LAYOUT (cellview), + info->cell, + cellview->priv->model, + &iter, + info->func_data); + continue; + } + + for (j = info->attributes; j && j->next; j = j->next->next) + { + gchar *property = j->data; + gint column = GPOINTER_TO_INT (j->next->data); + GValue value = {0, }; + + gtk_tree_model_get_value (cellview->priv->model, &iter, + column, &value); + g_object_set_property (G_OBJECT (info->cell), + property, &value); + g_value_unset (&value); + } + } +} + +/* GtkCellLayout implementation */ +static void +gtk_cell_view_cell_layout_pack_start (GtkCellLayout *layout, + GtkCellRenderer *renderer, + gboolean expand) +{ + GtkCellViewCellInfo *info; + GtkCellView *cellview = GTK_CELL_VIEW (layout); + + g_return_if_fail (GTK_IS_CELL_VIEW (cellview)); + g_return_if_fail (GTK_IS_CELL_RENDERER (renderer)); + g_return_if_fail (!gtk_cell_view_get_cell_info (cellview, renderer)); + + g_object_ref (G_OBJECT (renderer)); + gtk_object_sink (GTK_OBJECT (renderer)); + + info = g_new0 (GtkCellViewCellInfo, 1); + info->cell = renderer; + info->expand = expand ? TRUE : FALSE; + info->pack = GTK_PACK_START; + + cellview->priv->cell_list = g_list_append (cellview->priv->cell_list, info); +} + +static void +gtk_cell_view_cell_layout_pack_end (GtkCellLayout *layout, + GtkCellRenderer *renderer, + gboolean expand) +{ + GtkCellViewCellInfo *info; + GtkCellView *cellview = GTK_CELL_VIEW (layout); + + g_return_if_fail (GTK_IS_CELL_VIEW (cellview)); + g_return_if_fail (GTK_IS_CELL_RENDERER (renderer)); + g_return_if_fail (!gtk_cell_view_get_cell_info (cellview, renderer)); + + g_object_ref (G_OBJECT (renderer)); + gtk_object_sink (GTK_OBJECT (renderer)); + + info = g_new0 (GtkCellViewCellInfo, 1); + info->cell = renderer; + info->expand = expand ? TRUE : FALSE; + info->pack = GTK_PACK_END; + + cellview->priv->cell_list = g_list_append (cellview->priv->cell_list, info); +} + +static void +gtk_cell_view_cell_layout_add_attribute (GtkCellLayout *layout, + GtkCellRenderer *renderer, + const gchar *attribute, + gint column) +{ + GtkCellViewCellInfo *info; + GtkCellView *cellview = GTK_CELL_VIEW (layout); + + g_return_if_fail (GTK_IS_CELL_VIEW (cellview)); + info = gtk_cell_view_get_cell_info (cellview, renderer); + g_return_if_fail (info != NULL); + + info->attributes = g_slist_prepend (info->attributes, + GINT_TO_POINTER (column)); + info->attributes = g_slist_prepend (info->attributes, + g_strdup (attribute)); +} + +static void +gtk_cell_view_cell_layout_clear (GtkCellLayout *layout) +{ + GList *i; + GtkCellView *cellview = GTK_CELL_VIEW (layout); + + g_return_if_fail (GTK_IS_CELL_VIEW (cellview)); + + for (i = cellview->priv->cell_list; i; i = i->next) + { + GtkCellViewCellInfo *info = (GtkCellViewCellInfo *)i->data; + + gtk_cell_view_cell_layout_clear_attributes (layout, info->cell); + g_object_unref (G_OBJECT (info->cell)); + g_free (info); + } + + g_list_free (cellview->priv->cell_list); + cellview->priv->cell_list = NULL; +} + +static void +gtk_cell_view_cell_layout_set_cell_data_func (GtkCellLayout *layout, + GtkCellRenderer *cell, + GtkCellLayoutDataFunc func, + gpointer func_data, + GDestroyNotify destroy) +{ + GtkCellView *cellview = GTK_CELL_VIEW (layout); + GtkCellViewCellInfo *info; + + g_return_if_fail (GTK_IS_CELL_VIEW (cellview)); + + info = gtk_cell_view_get_cell_info (cellview, cell); + g_return_if_fail (info != NULL); + + if (info->destroy) + { + GDestroyNotify d = info->destroy; + + info->destroy = NULL; + d (info->func_data); + } + + info->func = func; + info->func_data = func_data; + info->destroy = destroy; +} + +static void +gtk_cell_view_cell_layout_clear_attributes (GtkCellLayout *layout, + GtkCellRenderer *renderer) +{ + GtkCellViewCellInfo *info; + GtkCellView *cellview = GTK_CELL_VIEW (layout); + GSList *list; + + g_return_if_fail (GTK_IS_CELL_VIEW (cellview)); + g_return_if_fail (GTK_IS_CELL_RENDERER (renderer)); + + info = gtk_cell_view_get_cell_info (cellview, renderer); + g_return_if_fail (info != NULL); + + list = info->attributes; + + while (list && list->next) + { + g_free (list->data); + list = list->next->next; + } + g_slist_free (list); + + info->attributes = NULL; +} + + +/* public API */ GtkWidget * gtk_cell_view_new (void) { @@ -467,7 +716,8 @@ gtk_cell_view_new_with_text (const gchar *text) cellview = GTK_CELL_VIEW (gtk_cell_view_new ()); renderer = gtk_cell_renderer_text_new (); - gtk_cell_view_pack_start (cellview, renderer, TRUE); + gtk_cell_view_cell_layout_pack_start (GTK_CELL_LAYOUT (cellview), + renderer, TRUE); g_value_init (&value, G_TYPE_STRING); g_value_set_string (&value, text); @@ -487,7 +737,8 @@ gtk_cell_view_new_with_markup (const gchar *markup) cellview = GTK_CELL_VIEW (gtk_cell_view_new ()); renderer = gtk_cell_renderer_text_new (); - gtk_cell_view_pack_start (cellview, renderer, TRUE); + gtk_cell_view_cell_layout_pack_start (GTK_CELL_LAYOUT (cellview), + renderer, TRUE); g_value_init (&value, G_TYPE_STRING); g_value_set_string (&value, markup); @@ -507,7 +758,8 @@ gtk_cell_view_new_with_pixbuf (GdkPixbuf *pixbuf) cellview = GTK_CELL_VIEW (gtk_cell_view_new ()); renderer = gtk_cell_renderer_pixbuf_new (); - gtk_cell_view_pack_start (cellview, renderer, TRUE); + gtk_cell_view_cell_layout_pack_start (GTK_CELL_LAYOUT (cellview), + renderer, TRUE); g_value_init (&value, GDK_TYPE_PIXBUF); g_value_set_object (&value, pixbuf); @@ -517,163 +769,6 @@ gtk_cell_view_new_with_pixbuf (GdkPixbuf *pixbuf) return GTK_WIDGET (cellview); } -static GtkCellViewCellInfo * -gtk_cell_view_get_cell_info (GtkCellView *cellview, - GtkCellRenderer *renderer) -{ - GList *i; - - for (i = cellview->priv->cell_list; i; i = i->next) - { - GtkCellViewCellInfo *info = (GtkCellViewCellInfo *)i->data; - - if (info->cell == renderer) - return info; - } - - return NULL; -} - -void -gtk_cell_view_pack_start (GtkCellView *cellview, - GtkCellRenderer *renderer, - gboolean expand) -{ - GtkCellViewCellInfo *info; - - g_return_if_fail (GTK_IS_CELL_VIEW (cellview)); - g_return_if_fail (GTK_IS_CELL_RENDERER (renderer)); - g_return_if_fail (!gtk_cell_view_get_cell_info (cellview, renderer)); - - g_object_ref (G_OBJECT (renderer)); - gtk_object_sink (GTK_OBJECT (renderer)); - - info = g_new0 (GtkCellViewCellInfo, 1); - info->cell = renderer; - info->expand = expand ? TRUE : FALSE; - info->pack = GTK_PACK_START; - - cellview->priv->cell_list = g_list_append (cellview->priv->cell_list, info); -} - -void -gtk_cell_view_pack_end (GtkCellView *cellview, - GtkCellRenderer *renderer, - gboolean expand) -{ - GtkCellViewCellInfo *info; - - g_return_if_fail (GTK_IS_CELL_VIEW (cellview)); - g_return_if_fail (GTK_IS_CELL_RENDERER (renderer)); - g_return_if_fail (!gtk_cell_view_get_cell_info (cellview, renderer)); - - g_object_ref (G_OBJECT (renderer)); - gtk_object_sink (GTK_OBJECT (renderer)); - - info = g_new0 (GtkCellViewCellInfo, 1); - info->cell = renderer; - info->expand = expand ? TRUE : FALSE; - info->pack = GTK_PACK_END; - - cellview->priv->cell_list = g_list_append (cellview->priv->cell_list, info); -} - -void -gtk_cell_view_add_attribute (GtkCellView *cellview, - GtkCellRenderer *renderer, - const gchar *attribute, - gint column) -{ - GtkCellViewCellInfo *info; - - g_return_if_fail (GTK_IS_CELL_VIEW (cellview)); - info = gtk_cell_view_get_cell_info (cellview, renderer); - g_return_if_fail (info != NULL); - - info->attributes = g_slist_prepend (info->attributes, - GINT_TO_POINTER (column)); - info->attributes = g_slist_prepend (info->attributes, - g_strdup (attribute)); -} - -void -gtk_cell_view_clear (GtkCellView *cellview) -{ - GList *i; - - for (i = cellview->priv->cell_list; i; i = i->next) - { - GtkCellViewCellInfo *info = (GtkCellViewCellInfo *)i->data; - - gtk_cell_view_clear_attributes (cellview, info->cell); - g_object_unref (G_OBJECT (info->cell)); - g_free (info); - } - - g_list_free (cellview->priv->cell_list); - cellview->priv->cell_list = NULL; -} - -void -gtk_cell_view_clear_attributes (GtkCellView *cellview, - GtkCellRenderer *renderer) -{ - GtkCellViewCellInfo *info; - GSList *list; - - g_return_if_fail (GTK_IS_CELL_VIEW (cellview)); - g_return_if_fail (GTK_IS_CELL_RENDERER (renderer)); - - info = gtk_cell_view_get_cell_info (cellview, renderer); - - list = info->attributes; - - while (list && list->next) - { - g_free (list->data); - list = list->next->next; - } - g_slist_free (list); - - info->attributes = NULL; -} - -static void -gtk_cell_view_set_attributesv (GtkCellView *cellview, - GtkCellRenderer *renderer, - va_list args) -{ - gchar *attribute; - gint column; - - attribute = va_arg (args, gchar *); - - gtk_cell_view_clear_attributes (cellview, renderer); - - while (attribute) - { - column = va_arg (args, gint); - gtk_cell_view_add_attribute (cellview, renderer, attribute, column); - attribute = va_arg (args, gchar *); - } -} - -void -gtk_cell_view_set_attributes (GtkCellView *cellview, - GtkCellRenderer *renderer, - ...) -{ - va_list args; - - g_return_if_fail (GTK_IS_CELL_VIEW (cellview)); - g_return_if_fail (GTK_IS_CELL_RENDERER (renderer)); - g_return_if_fail (gtk_cell_view_get_cell_info (cellview, renderer)); - - va_start (args, renderer); - gtk_cell_view_set_attributesv (cellview, renderer, args); - va_end (args); -} - void gtk_cell_view_set_value (GtkCellView *cellview, GtkCellRenderer *renderer, @@ -746,39 +841,6 @@ gtk_cell_view_set_model (GtkCellView *cellview, g_object_ref (G_OBJECT (cellview->priv->model)); } -static void -gtk_cell_view_set_cell_data (GtkCellView *cellview) -{ - GList *i; - GtkTreeIter iter; - GtkTreePath *path; - - g_return_if_fail (cellview->priv->displayed_row != NULL); - - path = gtk_tree_row_reference_get_path (cellview->priv->displayed_row); - gtk_tree_model_get_iter (cellview->priv->model, &iter, path); - gtk_tree_path_free (path); - - for (i = cellview->priv->cell_list; i; i = i->next) - { - GSList *j; - GtkCellViewCellInfo *info = i->data; - - for (j = info->attributes; j && j->next; j = j->next->next) - { - gchar *property = j->data; - gint column = GPOINTER_TO_INT (j->next->data); - GValue value = {0, }; - - gtk_tree_model_get_value (cellview->priv->model, &iter, - column, &value); - g_object_set_property (G_OBJECT (info->cell), - property, &value); - g_value_unset (&value); - } - } -} - void gtk_cell_view_set_displayed_row (GtkCellView *cellview, GtkTreePath *path) diff --git a/gtk/gtkcellview.h b/gtk/gtkcellview.h index 523e921cc4..e71dabd6ed 100644 --- a/gtk/gtkcellview.h +++ b/gtk/gtkcellview.h @@ -58,22 +58,6 @@ GtkWidget *gtk_cell_view_new_with_markup (const gchar *markup) GtkWidget *gtk_cell_view_new_with_pixbuf (GdkPixbuf *pixbuf); -void gtk_cell_view_pack_start (GtkCellView *cell_view, - GtkCellRenderer *renderer, - gboolean expand); -void gtk_cell_view_pack_end (GtkCellView *cell_view, - GtkCellRenderer *renderer, - gboolean expand); -void gtk_cell_view_clear (GtkCellView *cell_view); -void gtk_cell_view_add_attribute (GtkCellView *cell_view, - GtkCellRenderer *renderer, - const gchar *attribute, - gint column); -void gtk_cell_view_clear_attributes (GtkCellView *cell_view, - GtkCellRenderer *attribute); -void gtk_cell_view_set_attributes (GtkCellView *cell_view, - GtkCellRenderer *renderer, - ...); void gtk_cell_view_set_value (GtkCellView *cell_view, GtkCellRenderer *renderer, gchar *property, diff --git a/gtk/gtkcombobox.c b/gtk/gtkcombobox.c index 332dfa3b85..d54da472be 100644 --- a/gtk/gtkcombobox.c +++ b/gtk/gtkcombobox.c @@ -18,6 +18,7 @@ */ #include +#include #include #include @@ -54,6 +55,10 @@ struct _ComboCellInfo GtkCellRenderer *cell; GSList *attributes; + GtkCellLayoutDataFunc func; + gpointer func_data; + GDestroyNotify destroy; + guint expand : 1; guint pack : 1; }; @@ -119,6 +124,7 @@ static guint combo_box_signals[LAST_SIGNAL] = {0,}; /* common */ static void gtk_combo_box_class_init (GtkComboBoxClass *klass); +static void gtk_combo_box_cell_layout_init (GtkCellLayoutIface *iface); static void gtk_combo_box_init (GtkComboBox *combo_box); static void gtk_combo_box_set_property (GObject *object, @@ -223,6 +229,26 @@ static void gtk_combo_box_menu_row_changed (GtkTreeModel *model, GtkTreeIter *iter, gpointer data); +/* cell layout */ +static void gtk_combo_box_cell_layout_pack_start (GtkCellLayout *layout, + GtkCellRenderer *cell, + gboolean expand); +static void gtk_combo_box_cell_layout_pack_end (GtkCellLayout *layout, + GtkCellRenderer *cell, + gboolean expand); +static void gtk_combo_box_cell_layout_clear (GtkCellLayout *layout); +static void gtk_combo_box_cell_layout_add_attribute (GtkCellLayout *layout, + GtkCellRenderer *cell, + const gchar *attribute, + gint column); +static void gtk_combo_box_cell_layout_set_cell_data_func (GtkCellLayout *layout, + GtkCellRenderer *cell, + GtkCellLayoutDataFunc func, + gpointer func_data, + GDestroyNotify destroy); +static void gtk_combo_box_cell_layout_clear_attributes (GtkCellLayout *layout, + GtkCellRenderer *cell); + GType gtk_combo_box_get_type (void) @@ -244,10 +270,21 @@ gtk_combo_box_get_type (void) (GInstanceInitFunc) gtk_combo_box_init }; + static const GInterfaceInfo cell_layout_info = + { + (GInterfaceInitFunc) gtk_combo_box_cell_layout_init, + NULL, + NULL + }; + combo_box_type = g_type_register_static (GTK_TYPE_BIN, "GtkComboBox", &combo_box_info, 0); + + g_type_add_interface_static (combo_box_type, + GTK_TYPE_CELL_LAYOUT, + &cell_layout_info); } return combo_box_type; @@ -348,6 +385,17 @@ gtk_combo_box_class_init (GtkComboBoxClass *klass) g_type_class_add_private (object_class, sizeof (GtkComboBoxPrivate)); } +static void +gtk_combo_box_cell_layout_init (GtkCellLayoutIface *iface) +{ + iface->pack_start = gtk_combo_box_cell_layout_pack_start; + iface->pack_end = gtk_combo_box_cell_layout_pack_end; + iface->clear = gtk_combo_box_cell_layout_clear; + iface->add_attribute = gtk_combo_box_cell_layout_add_attribute; + iface->set_cell_data_func = gtk_combo_box_cell_layout_set_cell_data_func; + iface->clear_attributes = gtk_combo_box_cell_layout_clear_attributes; +} + static void gtk_combo_box_init (GtkComboBox *combo_box) { @@ -1097,18 +1145,22 @@ cell_view_sync_cells (GtkComboBox *combo_box, ComboCellInfo *info = (ComboCellInfo *)k->data; if (info->pack == GTK_PACK_START) - gtk_cell_view_pack_start (cell_view, - info->cell, info->expand); + gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (cell_view), + info->cell, info->expand); else if (info->pack == GTK_PACK_END) - gtk_cell_view_pack_end (cell_view, - info->cell, info->expand); + gtk_cell_layout_pack_end (GTK_CELL_LAYOUT (cell_view), + info->cell, info->expand); + + gtk_cell_layout_set_cell_data_func (GTK_CELL_LAYOUT (cell_view), + info->cell, + info->func, info->func_data, NULL); for (j = info->attributes; j; j = j->next->next) { - gtk_cell_view_add_attribute (cell_view, - info->cell, - j->data, - GPOINTER_TO_INT (j->next->data)); + gtk_cell_layout_add_attribute (GTK_CELL_LAYOUT (cell_view), + info->cell, + j->data, + GPOINTER_TO_INT (j->next->data)); } } } @@ -1856,29 +1908,15 @@ gtk_combo_box_list_row_changed (GtkTreeModel *model, } /* - * public API + * GtkCellLayout implementation */ - -GtkWidget * -gtk_combo_box_new (GtkTreeModel *model) -{ - GtkComboBox *combo_box; - - g_return_val_if_fail (GTK_IS_TREE_MODEL (model), NULL); - - combo_box = GTK_COMBO_BOX (g_object_new (gtk_combo_box_get_type (), - "model", model, - NULL)); - - return GTK_WIDGET (combo_box); -} - -void -gtk_combo_box_pack_start (GtkComboBox *combo_box, - GtkCellRenderer *cell, - gboolean expand) +static void +gtk_combo_box_cell_layout_pack_start (GtkCellLayout *layout, + GtkCellRenderer *cell, + gboolean expand) { ComboCellInfo *info; + GtkComboBox *combo_box = GTK_COMBO_BOX (layout); GtkWidget *menu; g_return_if_fail (GTK_IS_COMBO_BOX (combo_box)); @@ -1892,11 +1930,11 @@ gtk_combo_box_pack_start (GtkComboBox *combo_box, combo_box->priv->cells = g_slist_append (combo_box->priv->cells, info); if (combo_box->priv->cell_view) - gtk_cell_view_pack_start (GTK_CELL_VIEW (combo_box->priv->cell_view), - cell, expand); + gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (combo_box->priv->cell_view), + cell, expand); - gtk_cell_view_pack_start (GTK_CELL_VIEW (combo_box->priv->measurer), - cell, expand); + gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (combo_box->priv->measurer), + cell, expand); if (combo_box->priv->column) gtk_tree_view_column_pack_start (combo_box->priv->column, cell, expand); @@ -1916,18 +1954,19 @@ gtk_combo_box_pack_start (GtkComboBox *combo_box, else view = GTK_CELL_VIEW (i->data); - gtk_cell_view_pack_start (view, cell, expand); + gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (view), cell, expand); } g_list_free (list); } } -void -gtk_combo_box_pack_end (GtkComboBox *combo_box, - GtkCellRenderer *cell, - gboolean expand) +static void +gtk_combo_box_cell_layout_pack_end (GtkCellLayout *layout, + GtkCellRenderer *cell, + gboolean expand) { ComboCellInfo *info; + GtkComboBox *combo_box = GTK_COMBO_BOX (layout); GtkWidget *menu; g_return_if_fail (GTK_IS_COMBO_BOX (combo_box)); @@ -1939,11 +1978,11 @@ gtk_combo_box_pack_end (GtkComboBox *combo_box, info->pack = GTK_PACK_END; if (combo_box->priv->cell_view) - gtk_cell_view_pack_end (GTK_CELL_VIEW (combo_box->priv->cell_view), - cell, expand); + gtk_cell_layout_pack_end (GTK_CELL_LAYOUT (combo_box->priv->cell_view), + cell, expand); - gtk_cell_view_pack_end (GTK_CELL_VIEW (combo_box->priv->measurer), - cell, expand); + gtk_cell_layout_pack_end (GTK_CELL_LAYOUT (combo_box->priv->measurer), + cell, expand); if (combo_box->priv->column) gtk_tree_view_column_pack_end (combo_box->priv->column, cell, expand); @@ -1963,103 +2002,25 @@ gtk_combo_box_pack_end (GtkComboBox *combo_box, else view = GTK_CELL_VIEW (i->data); - gtk_cell_view_pack_end (view, cell, expand); + gtk_cell_layout_pack_end (GTK_CELL_LAYOUT (view), cell, expand); } g_list_free (list); } } -void -gtk_combo_box_set_attributes (GtkComboBox *combo_box, - GtkCellRenderer *cell, - ...) -{ - va_list args; - gchar *attribute; - gint column; - gint attributes = 0; - ComboCellInfo *info; - GtkWidget *menu; - - g_return_if_fail (GTK_IS_COMBO_BOX (combo_box)); - g_return_if_fail (GTK_IS_CELL_RENDERER (cell)); - - info = gtk_combo_box_get_cell_info (combo_box, cell); - - va_start (args, cell); - - attribute = va_arg (args, gchar *); - - while (attribute) - { - column = va_arg (args, gint); - - info->attributes = g_slist_prepend (info->attributes, - GINT_TO_POINTER (column)); - info->attributes = g_slist_prepend (info->attributes, - g_strdup (attribute)); - - attributes++; - - if (combo_box->priv->cell_view) - gtk_cell_view_add_attribute (GTK_CELL_VIEW (combo_box->priv->cell_view), - cell, attribute, column); - - gtk_cell_view_add_attribute (GTK_CELL_VIEW (combo_box->priv->measurer), - cell, attribute, column); - - if (combo_box->priv->column) - gtk_tree_view_column_add_attribute (combo_box->priv->column, cell, - attribute, column); - - attribute = va_arg (args, gchar *); - } - - va_end (args); - - menu = combo_box->priv->popup_widget; - if (GTK_IS_MENU (menu)) - { - GList *i, *list; - - list = gtk_container_get_children (GTK_CONTAINER (menu)); - for (i = list; i; i = i->next) - { - gint k; - GSList *j; - GtkCellView *view; - - if (GTK_IS_CELL_VIEW_MENU_ITEM (i->data)) - view = GTK_CELL_VIEW (GTK_BIN (i->data)->child); - else - view = GTK_CELL_VIEW (i->data); - - for (j = info->attributes, k = 0; k < attributes; k++) - { - gtk_cell_view_add_attribute (view, cell, - (gchar *)j->data, - GPOINTER_TO_INT (j->next->data)); - j = j->next->next; - } - } - g_list_free (list); - } - - gtk_combo_box_remeasure (combo_box); -} - -void -gtk_combo_box_clear (GtkComboBox *combo_box) +static void +gtk_combo_box_cell_layout_clear (GtkCellLayout *layout) { GtkWidget *menu; + GtkComboBox *combo_box = GTK_COMBO_BOX (layout); g_return_if_fail (GTK_IS_COMBO_BOX (combo_box)); if (combo_box->priv->cell_view) - gtk_cell_view_clear (GTK_CELL_VIEW (combo_box->priv->cell_view)); + gtk_cell_layout_clear (GTK_CELL_LAYOUT (combo_box->priv->cell_view)); if (combo_box->priv->measurer) - gtk_cell_view_clear (GTK_CELL_VIEW (combo_box->priv->measurer)); + gtk_cell_layout_clear (GTK_CELL_LAYOUT (combo_box->priv->measurer)); if (combo_box->priv->column) gtk_tree_view_column_clear (combo_box->priv->column); @@ -2079,11 +2040,208 @@ gtk_combo_box_clear (GtkComboBox *combo_box) else view = GTK_CELL_VIEW (i->data); - gtk_cell_view_clear (view); + gtk_cell_layout_clear (GTK_CELL_LAYOUT (view)); } } } +static void +gtk_combo_box_cell_layout_add_attribute (GtkCellLayout *layout, + GtkCellRenderer *cell, + const gchar *attribute, + gint column) +{ + ComboCellInfo *info; + GtkComboBox *combo_box = GTK_COMBO_BOX (layout); + GtkWidget *menu; + + g_return_if_fail (GTK_IS_COMBO_BOX (combo_box)); + g_return_if_fail (GTK_IS_CELL_RENDERER (cell)); + + info = gtk_combo_box_get_cell_info (combo_box, cell); + + info->attributes = g_slist_prepend (info->attributes, + GINT_TO_POINTER (column)); + info->attributes = g_slist_prepend (info->attributes, + g_strdup (attribute)); + + if (combo_box->priv->cell_view) + gtk_cell_layout_add_attribute (GTK_CELL_LAYOUT (combo_box->priv->cell_view), + cell, attribute, column); + + gtk_cell_layout_add_attribute (GTK_CELL_LAYOUT (combo_box->priv->measurer), + cell, attribute, column); + + if (combo_box->priv->column) + gtk_cell_layout_add_attribute (GTK_CELL_LAYOUT (combo_box->priv->column), + cell, attribute, column); + + menu = combo_box->priv->popup_widget; + if (GTK_IS_MENU (menu)) + { + GList *i, *list; + + list = gtk_container_get_children (GTK_CONTAINER (menu)); + for (i = list; i; i = i->next) + { + GtkCellView *view; + + if (GTK_IS_CELL_VIEW_MENU_ITEM (i->data)) + view = GTK_CELL_VIEW (GTK_BIN (i->data)->child); + else + view = GTK_CELL_VIEW (i->data); + + gtk_cell_layout_add_attribute (GTK_CELL_LAYOUT (view), cell, + attribute, column); + } + g_list_free (list); + } + + gtk_combo_box_remeasure (combo_box); +} + +static void +gtk_combo_box_cell_layout_set_cell_data_func (GtkCellLayout *layout, + GtkCellRenderer *cell, + GtkCellLayoutDataFunc func, + gpointer func_data, + GDestroyNotify destroy) +{ + ComboCellInfo *info; + GtkComboBox *combo_box = GTK_COMBO_BOX (layout); + GtkWidget *menu; + + g_return_if_fail (GTK_IS_COMBO_BOX (combo_box)); + + info = gtk_combo_box_get_cell_info (combo_box, cell); + g_return_if_fail (info != NULL); + + if (info->destroy) + { + GDestroyNotify d = info->destroy; + + info->destroy = NULL; + d (info->func_data); + } + + info->func = func; + info->func_data = func_data; + info->destroy = destroy; + + if (combo_box->priv->cell_view) + gtk_cell_layout_set_cell_data_func (GTK_CELL_LAYOUT (combo_box->priv->cell_view), cell, func, func_data, NULL); + + gtk_cell_layout_set_cell_data_func (GTK_CELL_LAYOUT (combo_box->priv->measurer), cell, func, func_data, NULL); + + if (combo_box->priv->column) + gtk_cell_layout_set_cell_data_func (GTK_CELL_LAYOUT (combo_box->priv->column), cell, func, func_data, NULL); + + menu = combo_box->priv->popup_widget; + if (GTK_IS_MENU (menu)) + { + GList *i, *list; + + list = gtk_container_get_children (GTK_CONTAINER (menu)); + for (i = list; i; i = i->next) + { + GtkCellView *view; + + if (GTK_IS_CELL_VIEW_MENU_ITEM (i->data)) + view = GTK_CELL_VIEW (GTK_BIN (i->data)->child); + else + view = GTK_CELL_VIEW (i->data); + + gtk_cell_layout_set_cell_data_func (GTK_CELL_LAYOUT (view), cell, + func, func_data, NULL); + } + g_list_free (list); + } + + gtk_combo_box_remeasure (combo_box); +} + +static void +gtk_combo_box_cell_layout_clear_attributes (GtkCellLayout *layout, + GtkCellRenderer *cell) +{ + ComboCellInfo *info; + GtkComboBox *combo_box = GTK_COMBO_BOX (layout); + GtkWidget *menu; + GSList *list; + + g_return_if_fail (GTK_IS_COMBO_BOX (layout)); + g_return_if_fail (GTK_IS_CELL_RENDERER (cell)); + + info = gtk_combo_box_get_cell_info (combo_box, cell); + g_return_if_fail (info != NULL); + + list = info->attributes; + while (list && list->next) + { + g_free (list->data); + list = list->next->next; + } + g_slist_free (list); + + info->attributes = NULL; + + if (combo_box->priv->cell_view) + gtk_cell_layout_clear_attributes (GTK_CELL_LAYOUT (combo_box->priv->cell_view), cell); + + gtk_cell_layout_clear_attributes (GTK_CELL_LAYOUT (combo_box->priv->measurer), cell); + + if (combo_box->priv->column) + gtk_cell_layout_clear_attributes (GTK_CELL_LAYOUT (combo_box->priv->column), cell); + + menu = combo_box->priv->popup_widget; + if (GTK_IS_MENU (menu)) + { + GList *i, *list; + + list = gtk_container_get_children (GTK_CONTAINER (menu)); + for (i = list; i; i = i->next) + { + GtkCellView *view; + + if (GTK_IS_CELL_VIEW_MENU_ITEM (i->data)) + view = GTK_CELL_VIEW (GTK_BIN (i->data)->child); + else + view = GTK_CELL_VIEW (i->data); + + gtk_cell_layout_clear_attributes (GTK_CELL_LAYOUT (view), cell); + } + g_list_free (list); + } + + gtk_combo_box_remeasure (combo_box); +} + +/* + * public API + */ + +/** + * gtk_combo_box_new: + * @model: A #GtkTreeModel. + * + * Creates a new #GtkComboBox with the model initialized to @model. + * + * Return value: A new #GtkComboBox. + */ +GtkWidget * +gtk_combo_box_new (GtkTreeModel *model) +{ + GtkComboBox *combo_box; + + g_return_val_if_fail (GTK_IS_TREE_MODEL (model), NULL); + + combo_box = GTK_COMBO_BOX (g_object_new (gtk_combo_box_get_type (), + "model", model, + NULL)); + + return GTK_WIDGET (combo_box); +} + void gtk_combo_box_set_wrap_width (GtkComboBox *combo_box, gint width) @@ -2198,6 +2356,7 @@ gtk_combo_box_get_model (GtkComboBox *combo_box) } +/* convenience API for simple text combos */ GtkWidget * gtk_combo_box_new_text (void) { @@ -2210,12 +2369,10 @@ gtk_combo_box_new_text (void) combo_box = gtk_combo_box_new (GTK_TREE_MODEL (store)); cell = gtk_cell_renderer_text_new (); - gtk_combo_box_pack_start (GTK_COMBO_BOX (combo_box), - cell, TRUE); - gtk_combo_box_set_attributes (GTK_COMBO_BOX (combo_box), - cell, - "text", 0, - NULL); + gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (combo_box), cell, TRUE); + gtk_cell_layout_set_attributes (GTK_CELL_LAYOUT (combo_box), cell, + "text", 0, + NULL); return combo_box; } diff --git a/gtk/gtkcombobox.h b/gtk/gtkcombobox.h index b724f7a9d6..17892b0401 100644 --- a/gtk/gtkcombobox.h +++ b/gtk/gtkcombobox.h @@ -59,18 +59,6 @@ struct _GtkComboBoxClass GType gtk_combo_box_get_type (void); GtkWidget *gtk_combo_box_new (GtkTreeModel *model); -/* manipulate list of cell renderers */ -void gtk_combo_box_pack_start (GtkComboBox *combo_box, - GtkCellRenderer *cell, - gboolean expand); -void gtk_combo_box_pack_end (GtkComboBox *combo_box, - GtkCellRenderer *cell, - gboolean expand); -void gtk_combo_box_set_attributes (GtkComboBox *combo_box, - GtkCellRenderer *cell, - ...); -void gtk_combo_box_clear (GtkComboBox *combo_box); - /* grids */ void gtk_combo_box_set_wrap_width (GtkComboBox *combo_box, gint width); diff --git a/gtk/gtkcomboboxentry.c b/gtk/gtkcomboboxentry.c index 7bba0e11b3..d2e907e6fa 100644 --- a/gtk/gtkcomboboxentry.c +++ b/gtk/gtkcomboboxentry.c @@ -18,6 +18,7 @@ */ #include +#include #include #include @@ -156,10 +157,10 @@ gtk_combo_box_entry_new (GtkTreeModel *model, GTK_COMBO_BOX_ENTRY (ret)->priv->text_column = text_column; renderer = gtk_cell_renderer_text_new (); - gtk_combo_box_pack_start (GTK_COMBO_BOX (ret), renderer, TRUE); - gtk_combo_box_set_attributes (GTK_COMBO_BOX (ret), renderer, - "text", text_column, - NULL); + gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (ret), renderer, TRUE); + gtk_cell_layout_set_attributes (GTK_CELL_LAYOUT (ret), renderer, + "text", text_column, + NULL); g_signal_connect (GTK_COMBO_BOX_ENTRY (ret)->priv->entry, "changed", G_CALLBACK (gtk_combo_box_entry_contents_changed), ret); diff --git a/tests/testcombo.c b/tests/testcombo.c index f3ff6f8385..b5e105bd85 100644 --- a/tests/testcombo.c +++ b/tests/testcombo.c @@ -55,10 +55,10 @@ create_combo_box_grid_demo () store = gtk_list_store_new (1, GDK_TYPE_PIXBUF); combo = gtk_combo_box_new (GTK_TREE_MODEL (store)); - gtk_combo_box_pack_start (GTK_COMBO_BOX (combo), - cell, TRUE); - gtk_combo_box_set_attributes (GTK_COMBO_BOX (combo), - cell, "pixbuf", 0, NULL); + gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (combo), + cell, TRUE); + gtk_cell_layout_set_attributes (GTK_CELL_LAYOUT (combo), + cell, "pixbuf", 0, NULL); gtk_combo_box_set_wrap_width (GTK_COMBO_BOX (combo), 3); @@ -227,9 +227,9 @@ main (int argc, char **argv) pixbuf = gtk_widget_render_icon (cellview, GTK_STOCK_DIALOG_WARNING, GTK_ICON_SIZE_BUTTON, NULL); - gtk_cell_view_pack_start (GTK_CELL_VIEW (cellview), - renderer, - FALSE); + gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (cellview), + renderer, + FALSE); g_value_init (&value, GDK_TYPE_PIXBUF); g_value_set_instance (&value, pixbuf); gtk_cell_view_set_values (GTK_CELL_VIEW (cellview), @@ -239,9 +239,9 @@ main (int argc, char **argv) g_value_unset (&value); renderer = gtk_cell_renderer_text_new (); - gtk_cell_view_pack_start (GTK_CELL_VIEW (cellview), - renderer, - TRUE); + gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (cellview), + renderer, + TRUE); g_value_init (&value, G_TYPE_STRING); g_value_set_string (&value, "la la la"); gtk_cell_view_set_values (GTK_CELL_VIEW (cellview), @@ -264,16 +264,20 @@ main (int argc, char **argv) gtk_container_add (GTK_CONTAINER (boom), combobox); renderer = gtk_cell_renderer_pixbuf_new (); - gtk_combo_box_pack_start (GTK_COMBO_BOX (combobox), - renderer, - FALSE); - gtk_combo_box_set_attributes (GTK_COMBO_BOX (combobox), renderer, "pixbuf", 0, NULL); + gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (combobox), + renderer, + FALSE); + gtk_cell_layout_set_attributes (GTK_CELL_LAYOUT (combobox), renderer, + "pixbuf", 0, + NULL); renderer = gtk_cell_renderer_text_new (); - gtk_combo_box_pack_start (GTK_COMBO_BOX (combobox), - renderer, - TRUE); - gtk_combo_box_set_attributes (GTK_COMBO_BOX (combobox), renderer, "text", 1, NULL); + gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (combobox), + renderer, + TRUE); + gtk_cell_layout_set_attributes (GTK_CELL_LAYOUT (combobox), renderer, + "text", 1, + NULL); gtk_combo_box_set_active (GTK_COMBO_BOX (combobox), 1);