X-Git-Url: http://pileus.org/git/?a=blobdiff_plain;f=gtk%2Fgtkcellarea.c;h=df9c70968a0ce52235da79cda714a05ea0c76a60;hb=HEAD;hp=166546bc45eb360dbf32ad26b4a257368300f0aa;hpb=2588165bfb50dcdf81e08b3e0126044ade1e98bb;p=~andy%2Fgtk diff --git a/gtk/gtkcellarea.c b/gtk/gtkcellarea.c index 166546bc4..df9c70968 100644 --- a/gtk/gtkcellarea.c +++ b/gtk/gtkcellarea.c @@ -16,45 +16,44 @@ * Library General Public License for more details. * * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. + * License along with this library. If not, see . */ /** * SECTION:gtkcellarea - * @Short_Description: An abstract class for laying out #GtkCellRenderers + * @Short_Description: An abstract class for laying out GtkCellRenderers * @Title: GtkCellArea * - * The #GtkCellArea is an abstract class for #GtkCellLayout widgets (also referred - * to as "layouting widgets") to interface with an arbitrary number of #GtkCellRenderers - * and interact with the user for a given #GtkTreeModel row. + * The #GtkCellArea is an abstract class for #GtkCellLayout widgets + * (also referred to as "layouting widgets") to interface with an + * arbitrary number of #GtkCellRenderers and interact with the user + * for a given #GtkTreeModel row. * - * The cell area handles events, focus navigation, drawing and wraps geometrical + * The cell area handles events, focus navigation, drawing and * size requests and allocations for a given row of data. * - * Usually users dont have to interact with the #GtkCellArea directly unless they - * are implementing a cell layouting widget themselves. + * Usually users dont have to interact with the #GtkCellArea directly + * unless they are implementing a cell-layouting widget themselves. * * * Requesting area sizes * * As outlined in GtkWidget's * geometry management section, GTK+ uses a height-for-width - * geometry managemen system to compute the sizes of widgets and user + * geometry management system to compute the sizes of widgets and user * interfaces. #GtkCellArea uses the same semantics to calculate the * size of an area for an arbitrary number of #GtkTreeModel rows. * * When requesting the size of a cell area one needs to calculate - * the size for a handful of rows, this will be done differently by + * the size for a handful of rows, and this will be done differently by * different layouting widgets. For instance a #GtkTreeViewColumn * always lines up the areas from top to bottom while a #GtkIconView * on the other hand might enforce that all areas received the same - * width and wrap the areas around, requesting height for more cell + * width and wrap the areas around, requesting height for more cell * areas when allocated less width. * - * It's also important for areas to maintain some cell - * alignments with areas rendered for adjacent rows (cells can + * It's also important for areas to maintain some cell + * alignments with areas rendered for adjacent rows (cells can * appear "columnized" inside an area even when the size of * cells are different in each row). For this reason the #GtkCellArea * uses a #GtkCellAreaContext object to store the alignments @@ -64,17 +63,17 @@ * * The #GtkCellAreaContext is an opaque object specific to the * #GtkCellArea which created it (see gtk_cell_area_create_context()). - * The owning cell layouting widget can create as many contexts as + * The owning cell-layouting widget can create as many contexts as * it wishes to calculate sizes of rows which should receive the - * same size in at least one orientation (horizontally or vertically), - * however it's important that the same #GtkCellAreaContext which + * same size in at least one orientation (horizontally or vertically), + * However, it's important that the same #GtkCellAreaContext which * was used to request the sizes for a given #GtkTreeModel row be * used when rendering or processing events for that row. * * In order to request the width of all the rows at the root level * of a #GtkTreeModel one would do the following: * - * Requesting the width of a hand full of GtkTreeModel rows. + * Requesting the width of a handful of GtkTreeModel rows * * GtkTreeIter iter; * gint minimum_width; @@ -91,22 +90,26 @@ * gtk_cell_area_context_get_preferred_width (context, &minimum_width, &natural_width); * * - * Note that in this example it's not important to observe the returned minimum and - * natural width of the area for each row unless the cell layouting object is actually - * interested in the widths of individual rows. The overall width is however stored - * in the accompanying #GtkCellAreaContext object and can be consulted at any time. - * - * This can be useful since #GtkCellLayout widgets usually have to support requesting - * and rendering rows in treemodels with an exceedingly large amount of rows. The - * #GtkCellLayout widget in that case would calculate the required width of the rows - * in an idle or timeout source (see g_timeout_add()) and when the widget is requested - * its actual width in #GtkWidgetClass.get_preferred_width() it can simply consult the - * width accumulated so far in the #GtkCellAreaContext object. - * - * A simple example where rows are rendered from top to bottom and take up the full - * width of the layouting widget would look like: + * Note that in this example it's not important to observe the + * returned minimum and natural width of the area for each row + * unless the cell-layouting object is actually interested in the + * widths of individual rows. The overall width is however stored + * in the accompanying #GtkCellAreaContext object and can be consulted + * at any time. + * + * This can be useful since #GtkCellLayout widgets usually have to + * support requesting and rendering rows in treemodels with an + * exceedingly large amount of rows. The #GtkCellLayout widget in + * that case would calculate the required width of the rows in an + * idle or timeout source (see g_timeout_add()) and when the widget + * is requested its actual width in #GtkWidgetClass.get_preferred_width() + * it can simply consult the width accumulated so far in the + * #GtkCellAreaContext object. + * + * A simple example where rows are rendered from top to bottom and + * take up the full width of the layouting widget would look like: * - * A typical #GtkWidgetClass.get_preferred_width() for a layouting widget. + * A typical get_preferred_width() implementation * * static void * foo_get_preferred_width (GtkWidget *widget, @@ -122,22 +125,23 @@ * } * * - * - * In the above example the Foo widget has to make sure that some row sizes have - * been calculated (the amount of rows that Foo judged was appropriate to request - * space for in a single timeout iteration) before simply returning the amount - * of space required by the area via the #GtkCellAreaContext. - * - * Requesting the height for width (or width for height) of an area is a similar - * task except in this case the #GtkCellAreaContext does not store the data (actually - * it does not know how much space the layouting widget plans to allocate it for - * every row, it's up to the layouting widget to render each row of data with - * the appropriate height and width which was requested by the #GtkCellArea). - * - * In order to request the height for width of all the rows at the root level - * of a #GtkTreeModel one would do the following: + * In the above example the Foo widget has to make sure that some + * row sizes have been calculated (the amount of rows that Foo judged + * was appropriate to request space for in a single timeout iteration) + * before simply returning the amount of space required by the area via + * the #GtkCellAreaContext. + * + * Requesting the height for width (or width for height) of an area is + * a similar task except in this case the #GtkCellAreaContext does not + * store the data (actually, it does not know how much space the layouting + * widget plans to allocate it for every row. It's up to the layouting + * widget to render each row of data with the appropriate height and + * width which was requested by the #GtkCellArea). + * + * In order to request the height for width of all the rows at the + * root level of a #GtkTreeModel one would do the following: * - * Requesting the height for width of a hand full of GtkTreeModel rows. + * Requesting the height for width of a handful of GtkTreeModel rows * * GtkTreeIter iter; * gint minimum_height; @@ -149,7 +153,7 @@ * while (valid) * { * gtk_cell_area_apply_attributes (area, model, &iter, FALSE, FALSE); - * gtk_cell_area_get_preferred_height_for_width (area, context, widget, + * gtk_cell_area_get_preferred_height_for_width (area, context, widget, * width, &minimum_height, &natural_height); * * if (width_is_for_allocation) @@ -162,34 +166,39 @@ * } * * - * - * Note that in the above example we would need to cache the heights returned for each - * treemodel row so that we would know what sizes to render the areas for each row. However - * we would only want to really cache the heights if the request is intended for the - * layouting widgets real allocation. - * - * In some cases the layouting widget is requested the height for an arbitrary for_width, - * this is a special case for layouting widgets who need to request size for tens of thousands - * of treemodel rows. For this case it's only important that the layouting widget calculate - * one reasonably sized chunk of rows and return that height synchronously. The reasoning here - * is that any layouting widget is at least capable of synchronously calculating enough - * height to fill the screen height (or scrolled window height) in response to a single call to - * #GtkWidgetClass.get_preferred_height_for_width(). Returning a perfect height for width that - * is larger than the screen area is inconsequential since after the layouting receives an - * allocation from a scrolled window it simply continues to drive the the scrollbar - * values while more and mode height is required for the row heights that are calculated - * in the background. + * Note that in the above example we would need to cache the heights + * returned for each row so that we would know what sizes to render the + * areas for each row. However we would only want to really cache the + * heights if the request is intended for the layouting widgets real + * allocation. + * + * In some cases the layouting widget is requested the height for an + * arbitrary for_width, this is a special case for layouting widgets + * who need to request size for tens of thousands of rows. For this + * case it's only important that the layouting widget calculate + * one reasonably sized chunk of rows and return that height + * synchronously. The reasoning here is that any layouting widget is + * at least capable of synchronously calculating enough height to fill + * the screen height (or scrolled window height) in response to a single + * call to #GtkWidgetClass.get_preferred_height_for_width(). Returning + * a perfect height for width that is larger than the screen area is + * inconsequential since after the layouting receives an allocation + * from a scrolled window it simply continues to drive the scrollbar + * values while more and more height is required for the row heights + * that are calculated in the background. * * * * Rendering Areas * - * Once area sizes have been aquired at least for the rows in the visible area of the - * layouting widget they can be rendered at #GtkWidgetClass.draw() time. + * Once area sizes have been aquired at least for the rows in the + * visible area of the layouting widget they can be rendered at + * #GtkWidgetClass.draw() time. * - * A crued example of how to render all the rows at the root level runs as follows: + * A crude example of how to render all the rows at the root level + * runs as follows: * - * Requesting the width of a hand full of GtkTreeModel rows. + * Requesting the width of a handful of GtkTreeModel rows * * GtkAllocation allocation; * GdkRectangle cell_area = { 0, }; @@ -206,7 +215,7 @@ * cell_area.height = get_cached_height_for_row (&iter); * * gtk_cell_area_apply_attributes (area, model, &iter, FALSE, FALSE); - * gtk_cell_area_render (area, context, widget, cr, + * gtk_cell_area_render (area, context, widget, cr, * &cell_area, &cell_area, state_flags, FALSE); * * cell_area.y += cell_area.height; @@ -215,42 +224,46 @@ * } * * - * Note that the cached height in this example really depends on how the layouting - * widget works. The layouting widget might decide to give every row it's minimum - * or natural height or if the model content is expected to fit inside the layouting - * widget with no scrolled window it would make sense to calculate the allocation - * for each row at #GtkWidget.size_allocate() time using gtk_distribute_natural_allocation(). + * Note that the cached height in this example really depends on how + * the layouting widget works. The layouting widget might decide to + * give every row its minimum or natural height or, if the model content + * is expected to fit inside the layouting widget without scrolling, it + * would make sense to calculate the allocation for each row at + * #GtkWidget::size-allocate time using gtk_distribute_natural_allocation(). * * * * Handling Events and Driving Keyboard Focus * - * Passing events to the area is as simple as handling events on any normal - * widget and then passing them to the gtk_cell_area_event() api as they come - * in. Usually #GtkCellArea is only interested in button events, however some - * customized derived areas can be implemented who are interested in handling - * other events. Handling an event can trigger the #GtkCellArea::focus-changed - * signal to fire as well as #GtkCellArea::add-editable in the case that - * an editable cell was clicked and needs to start editing. You can call + * Passing events to the area is as simple as handling events on any + * normal widget and then passing them to the gtk_cell_area_event() + * API as they come in. Usually #GtkCellArea is only interested in + * button events, however some customized derived areas can be implemented + * who are interested in handling other events. Handling an event can + * trigger the #GtkCellArea::focus-changed signal to fire; as well as + * #GtkCellArea::add-editable in the case that an editable cell was + * clicked and needs to start editing. You can call * gtk_cell_area_stop_editing() at any time to cancel any cell editing * that is currently in progress. * - * The #GtkCellArea drives keyboard focus from cell to cell in a way similar - * to #GtkWidget. For layouting widgets that support giving focus to cells it's - * important to remember to pass %GTK_CELL_RENDERER_FOCUSED to the area functions - * for the row that has focus and to tell the area to paint the focus at render - * time. - * - * Layouting widgets that accept focus on cells should implement the #GtkWidgetClass.focus() - * virtual method. The layouting widget is always responsible for knowing where - * #GtkTreeModel rows are rendered inside the widget, so at #GtkWidgetClass.focus() time - * the layouting widget should use the #GtkCellArea methods to navigate focus inside the - * area and then observe the GtkDirectionType to pass the focus to adjacent rows and - * areas. - * - * A basic example of how the #GtkWidgetClass.focus() virtual method should be implemented: + * The #GtkCellArea drives keyboard focus from cell to cell in a way + * similar to #GtkWidget. For layouting widgets that support giving + * focus to cells it's important to remember to pass %GTK_CELL_RENDERER_FOCUSED + * to the area functions for the row that has focus and to tell the + * area to paint the focus at render time. + * + * Layouting widgets that accept focus on cells should implement the + * #GtkWidgetClass.focus() virtual method. The layouting widget is always + * responsible for knowing where #GtkTreeModel rows are rendered inside + * the widget, so at #GtkWidgetClass.focus() time the layouting widget + * should use the #GtkCellArea methods to navigate focus inside the area + * and then observe the GtkDirectionType to pass the focus to adjacent + * rows and areas. + * + * A basic example of how the #GtkWidgetClass.focus() virtual method + * should be implemented: * - * Implementing keyboard focus navigation when displaying rows from top to bottom. + * Implementing keyboard focus navigation * * static gboolean * foo_focus (GtkWidget *widget, @@ -309,31 +322,34 @@ * } * * + * Note that the layouting widget is responsible for matching the + * GtkDirectionType values to the way it lays out its cells. * * * * Cell Properties * - * The #GtkCellArea introduces cell properties for #GtkCellRenderers in very - * much the same way that #GtkContainer introduces child properties - * for #GtkWidgets. This provides some general interfaces for defining the relationship cell areas - * have with thier cells. For instance in a #GtkCellAreaBox a cell might "expand" and recieve extra - * space when the area is allocated more than it's full natural request, or a cell might be configured - * to "align" with adjacent rows which were requested and rendered with the same #GtkCellAreaContext. - * - * Use gtk_cell_area_class_install_cell_property() to install cell properties - * for a cell area class and gtk_cell_area_class_find_cell_property() or - * gtk_cell_area_class_list_cell_properties() to get information about existing - * cell properties. + * The #GtkCellArea introduces cell properties + * for #GtkCellRenderers in very much the same way that #GtkContainer + * introduces child properties + * for #GtkWidgets. This provides some general interfaces for defining + * the relationship cell areas have with their cells. For instance in a + * #GtkCellAreaBox a cell might "expand" and receive extra space when + * the area is allocated more than its full natural request, or a cell + * might be configured to "align" with adjacent rows which were requested + * and rendered with the same #GtkCellAreaContext. + * + * Use gtk_cell_area_class_install_cell_property() to install cell + * properties for a cell area class and gtk_cell_area_class_find_cell_property() + * or gtk_cell_area_class_list_cell_properties() to get information about + * existing cell properties. * * To set the value of a cell property, use gtk_cell_area_cell_set_property(), - * gtk_cell_area_cell_set() or gtk_cell_area_cell_set_valist(). - * To obtain the value of a cell property, use - * gtk_cell_area_cell_get_property(), gtk_cell_area_cell_get() or - * gtk_cell_area_cell_get_valist(). + * gtk_cell_area_cell_set() or gtk_cell_area_cell_set_valist(). To obtain + * the value of a cell property, use gtk_cell_area_cell_get_property(), + * gtk_cell_area_cell_get() or gtk_cell_area_cell_get_valist(). * * - * */ #include "config.h" @@ -356,67 +372,115 @@ static void gtk_cell_area_dispose (GObject *object); static void gtk_cell_area_finalize (GObject *object); static void gtk_cell_area_set_property (GObject *object, - guint prop_id, - const GValue *value, - GParamSpec *pspec); + guint prop_id, + const GValue *value, + GParamSpec *pspec); static void gtk_cell_area_get_property (GObject *object, - guint prop_id, - GValue *value, - GParamSpec *pspec); + guint prop_id, + GValue *value, + GParamSpec *pspec); /* GtkCellAreaClass */ +static void gtk_cell_area_real_add (GtkCellArea *area, + GtkCellRenderer *renderer); +static void gtk_cell_area_real_remove (GtkCellArea *area, + GtkCellRenderer *renderer); +static void gtk_cell_area_real_foreach (GtkCellArea *area, + GtkCellCallback callback, + gpointer callback_data); +static void gtk_cell_area_real_foreach_alloc (GtkCellArea *area, + GtkCellAreaContext *context, + GtkWidget *widget, + const GdkRectangle *cell_area, + const GdkRectangle *background_area, + GtkCellAllocCallback callback, + gpointer callback_data); static gint gtk_cell_area_real_event (GtkCellArea *area, - GtkCellAreaContext *context, - GtkWidget *widget, - GdkEvent *event, - const GdkRectangle *cell_area, - GtkCellRendererState flags); + GtkCellAreaContext *context, + GtkWidget *widget, + GdkEvent *event, + const GdkRectangle *cell_area, + GtkCellRendererState flags); +static void gtk_cell_area_real_render (GtkCellArea *area, + GtkCellAreaContext *context, + GtkWidget *widget, + cairo_t *cr, + const GdkRectangle *background_area, + const GdkRectangle *cell_area, + GtkCellRendererState flags, + gboolean paint_focus); static void gtk_cell_area_real_apply_attributes (GtkCellArea *area, - GtkTreeModel *tree_model, - GtkTreeIter *iter, - gboolean is_expander, - gboolean is_expanded); -static void gtk_cell_area_real_get_preferred_height_for_width (GtkCellArea *area, + GtkTreeModel *tree_model, + GtkTreeIter *iter, + gboolean is_expander, + gboolean is_expanded); + +static GtkCellAreaContext *gtk_cell_area_real_create_context (GtkCellArea *area); +static GtkCellAreaContext *gtk_cell_area_real_copy_context (GtkCellArea *area, + GtkCellAreaContext *context); +static GtkSizeRequestMode gtk_cell_area_real_get_request_mode (GtkCellArea *area); +static void gtk_cell_area_real_get_preferred_width (GtkCellArea *area, + GtkCellAreaContext *context, + GtkWidget *widget, + gint *minimum_width, + gint *natural_width); +static void gtk_cell_area_real_get_preferred_height (GtkCellArea *area, GtkCellAreaContext *context, GtkWidget *widget, - gint width, gint *minimum_height, gint *natural_height); +static void gtk_cell_area_real_get_preferred_height_for_width (GtkCellArea *area, + GtkCellAreaContext *context, + GtkWidget *widget, + gint width, + gint *minimum_height, + gint *natural_height); static void gtk_cell_area_real_get_preferred_width_for_height (GtkCellArea *area, - GtkCellAreaContext *context, - GtkWidget *widget, - gint height, - gint *minimum_width, - gint *natural_width); + GtkCellAreaContext *context, + GtkWidget *widget, + gint height, + gint *minimum_width, + gint *natural_width); static gboolean gtk_cell_area_real_is_activatable (GtkCellArea *area); static gboolean gtk_cell_area_real_activate (GtkCellArea *area, - GtkCellAreaContext *context, - GtkWidget *widget, - const GdkRectangle *cell_area, - GtkCellRendererState flags); + GtkCellAreaContext *context, + GtkWidget *widget, + const GdkRectangle *cell_area, + GtkCellRendererState flags, + gboolean edit_only); +static gboolean gtk_cell_area_real_focus (GtkCellArea *area, + GtkDirectionType direction); /* GtkCellLayoutIface */ static void gtk_cell_area_cell_layout_init (GtkCellLayoutIface *iface); static void gtk_cell_area_pack_default (GtkCellLayout *cell_layout, - GtkCellRenderer *renderer, - gboolean expand); + GtkCellRenderer *renderer, + gboolean expand); static void gtk_cell_area_clear (GtkCellLayout *cell_layout); static void gtk_cell_area_add_attribute (GtkCellLayout *cell_layout, - GtkCellRenderer *renderer, - const gchar *attribute, - gint column); + GtkCellRenderer *renderer, + const gchar *attribute, + gint column); static void gtk_cell_area_set_cell_data_func (GtkCellLayout *cell_layout, - GtkCellRenderer *cell, - GtkCellLayoutDataFunc func, - gpointer func_data, - GDestroyNotify destroy); + GtkCellRenderer *cell, + GtkCellLayoutDataFunc func, + gpointer func_data, + GDestroyNotify destroy); static void gtk_cell_area_clear_attributes (GtkCellLayout *cell_layout, - GtkCellRenderer *renderer); + GtkCellRenderer *renderer); static void gtk_cell_area_reorder (GtkCellLayout *cell_layout, - GtkCellRenderer *cell, - gint position); + GtkCellRenderer *cell, + gint position); static GList *gtk_cell_area_get_cells (GtkCellLayout *cell_layout); +static GtkCellArea *gtk_cell_area_get_area (GtkCellLayout *cell_layout); +/* GtkBuildableIface */ +static void gtk_cell_area_buildable_init (GtkBuildableIface *iface); +static void gtk_cell_area_buildable_custom_tag_end (GtkBuildable *buildable, + GtkBuilder *builder, + GObject *child, + const gchar *tagname, + gpointer *data); /* Used in foreach loop to check if a child renderer is present */ typedef struct { @@ -430,6 +494,18 @@ typedef struct { GdkRectangle allocation; } RendererAllocationData; +/* Used in foreach loop to render cells */ +typedef struct { + GtkCellArea *area; + GtkWidget *widget; + cairo_t *cr; + GdkRectangle focus_rect; + GtkCellRendererState render_flags; + guint paint_focus : 1; + guint focus_all : 1; + guint first_focus : 1; +} CellRenderData; + /* Used in foreach loop to get a cell by position */ typedef struct { gint x; @@ -450,34 +526,35 @@ typedef struct { GtkCellLayoutDataFunc func; gpointer data; GDestroyNotify destroy; + GtkCellLayout *proxy; } CellInfo; static CellInfo *cell_info_new (GtkCellLayoutDataFunc func, - gpointer data, - GDestroyNotify destroy); + gpointer data, + GDestroyNotify destroy); static void cell_info_free (CellInfo *info); static CellAttribute *cell_attribute_new (GtkCellRenderer *renderer, - const gchar *attribute, - gint column); + const gchar *attribute, + gint column); static void cell_attribute_free (CellAttribute *attribute); static gint cell_attribute_find (CellAttribute *cell_attribute, - const gchar *attribute); + const gchar *attribute); /* Internal functions/signal emissions */ static void gtk_cell_area_add_editable (GtkCellArea *area, - GtkCellRenderer *renderer, - GtkCellEditable *editable, - GdkRectangle *cell_area); + GtkCellRenderer *renderer, + GtkCellEditable *editable, + const GdkRectangle *cell_area); static void gtk_cell_area_remove_editable (GtkCellArea *area, - GtkCellRenderer *renderer, - GtkCellEditable *editable); + GtkCellRenderer *renderer, + GtkCellEditable *editable); static void gtk_cell_area_set_edit_widget (GtkCellArea *area, - GtkCellEditable *editable); + GtkCellEditable *editable); static void gtk_cell_area_set_edited_cell (GtkCellArea *area, - GtkCellRenderer *renderer); + GtkCellRenderer *renderer); -/* Struct to pass data along while looping over +/* Struct to pass data along while looping over * cell renderers to apply attributes */ typedef struct { @@ -490,13 +567,14 @@ typedef struct { struct _GtkCellAreaPrivate { - /* The GtkCellArea bookkeeps any connected + /* The GtkCellArea bookkeeps any connected * attributes in this hash table. */ GHashTable *cell_info; /* Current path is saved as a side-effect - * of gtk_cell_area_apply_attributes() */ + * of gtk_cell_area_apply_attributes() + */ gchar *current_path; /* Current cell being edited and editable widget used */ @@ -511,9 +589,6 @@ struct _GtkCellAreaPrivate /* Tracking which cells are focus siblings of focusable cells */ GHashTable *focus_siblings; - - /* Detail string to pass to gtk_paint_*() functions */ - gchar *style_detail; }; enum { @@ -532,17 +607,19 @@ enum { }; /* Keep the paramspec pool internal, no need to deliver notifications - * on cells. at least no percieved need for now */ + * on cells. at least no perceived need for now + */ static GParamSpecPool *cell_property_pool = NULL; static guint cell_area_signals[LAST_SIGNAL] = { 0 }; #define PARAM_SPEC_PARAM_ID(pspec) ((pspec)->param_id) #define PARAM_SPEC_SET_PARAM_ID(pspec, id) ((pspec)->param_id = (id)) - G_DEFINE_ABSTRACT_TYPE_WITH_CODE (GtkCellArea, gtk_cell_area, G_TYPE_INITIALLY_UNOWNED, - G_IMPLEMENT_INTERFACE (GTK_TYPE_CELL_LAYOUT, - gtk_cell_area_cell_layout_init)); + G_IMPLEMENT_INTERFACE (GTK_TYPE_CELL_LAYOUT, + gtk_cell_area_cell_layout_init) + G_IMPLEMENT_INTERFACE (GTK_TYPE_BUILDABLE, + gtk_cell_area_buildable_init)) static void gtk_cell_area_init (GtkCellArea *area) @@ -550,19 +627,19 @@ gtk_cell_area_init (GtkCellArea *area) GtkCellAreaPrivate *priv; area->priv = G_TYPE_INSTANCE_GET_PRIVATE (area, - GTK_TYPE_CELL_AREA, - GtkCellAreaPrivate); + GTK_TYPE_CELL_AREA, + GtkCellAreaPrivate); priv = area->priv; - priv->cell_info = g_hash_table_new_full (g_direct_hash, - g_direct_equal, - NULL, - (GDestroyNotify)cell_info_free); + priv->cell_info = g_hash_table_new_full (g_direct_hash, + g_direct_equal, + NULL, + (GDestroyNotify)cell_info_free); - priv->focus_siblings = g_hash_table_new_full (g_direct_hash, - g_direct_equal, - NULL, - (GDestroyNotify)g_list_free); + priv->focus_siblings = g_hash_table_new_full (g_direct_hash, + g_direct_equal, + NULL, + (GDestroyNotify)g_list_free); priv->focus_cell = NULL; priv->edited_cell = NULL; @@ -571,11 +648,11 @@ gtk_cell_area_init (GtkCellArea *area) priv->remove_widget_id = 0; } -static void +static void gtk_cell_area_class_init (GtkCellAreaClass *class) { GObjectClass *object_class = G_OBJECT_CLASS (class); - + /* GObjectClass */ object_class->dispose = gtk_cell_area_dispose; object_class->finalize = gtk_cell_area_finalize; @@ -583,25 +660,27 @@ gtk_cell_area_class_init (GtkCellAreaClass *class) object_class->set_property = gtk_cell_area_set_property; /* general */ - class->add = NULL; - class->remove = NULL; - class->foreach = NULL; + class->add = gtk_cell_area_real_add; + class->remove = gtk_cell_area_real_remove; + class->foreach = gtk_cell_area_real_foreach; + class->foreach_alloc = gtk_cell_area_real_foreach_alloc; class->event = gtk_cell_area_real_event; - class->render = NULL; + class->render = gtk_cell_area_real_render; class->apply_attributes = gtk_cell_area_real_apply_attributes; /* geometry */ - class->create_context = NULL; - class->get_request_mode = NULL; - class->get_preferred_width = NULL; - class->get_preferred_height = NULL; + class->create_context = gtk_cell_area_real_create_context; + class->copy_context = gtk_cell_area_real_copy_context; + class->get_request_mode = gtk_cell_area_real_get_request_mode; + class->get_preferred_width = gtk_cell_area_real_get_preferred_width; + class->get_preferred_height = gtk_cell_area_real_get_preferred_height; class->get_preferred_height_for_width = gtk_cell_area_real_get_preferred_height_for_width; class->get_preferred_width_for_height = gtk_cell_area_real_get_preferred_width_for_height; /* focus */ class->is_activatable = gtk_cell_area_real_is_activatable; class->activate = gtk_cell_area_real_activate; - class->focus = NULL; + class->focus = gtk_cell_area_real_focus; /* Signals */ /** @@ -618,16 +697,18 @@ gtk_cell_area_class_init (GtkCellAreaClass *class) */ cell_area_signals[SIGNAL_APPLY_ATTRIBUTES] = g_signal_new (I_("apply-attributes"), - G_OBJECT_CLASS_TYPE (object_class), - G_SIGNAL_RUN_FIRST, - G_STRUCT_OFFSET (GtkCellAreaClass, apply_attributes), - NULL, NULL, - _gtk_marshal_VOID__OBJECT_BOXED_BOOLEAN_BOOLEAN, - G_TYPE_NONE, 4, - GTK_TYPE_TREE_MODEL, - GTK_TYPE_TREE_ITER, - G_TYPE_BOOLEAN, - G_TYPE_BOOLEAN); + G_OBJECT_CLASS_TYPE (object_class), + G_SIGNAL_RUN_FIRST, + G_STRUCT_OFFSET (GtkCellAreaClass, apply_attributes), + NULL, NULL, + _gtk_marshal_VOID__OBJECT_BOXED_BOOLEAN_BOOLEAN, + G_TYPE_NONE, 4, + GTK_TYPE_TREE_MODEL, + GTK_TYPE_TREE_ITER, + G_TYPE_BOOLEAN, + G_TYPE_BOOLEAN); + g_signal_set_va_marshaller (cell_area_signals[SIGNAL_APPLY_ATTRIBUTES], G_TYPE_FROM_CLASS (class), + _gtk_marshal_VOID__OBJECT_BOXED_BOOLEAN_BOOLEANv); /** * GtkCellArea::add-editable: @@ -639,22 +720,22 @@ gtk_cell_area_class_init (GtkCellAreaClass *class) * @path: the #GtkTreePath string this edit was initiated for * * Indicates that editing has started on @renderer and that @editable - * should be added to the owning cell layouting widget at @cell_area. + * should be added to the owning cell-layouting widget at @cell_area. * * Since: 3.0 */ cell_area_signals[SIGNAL_ADD_EDITABLE] = g_signal_new (I_("add-editable"), - G_OBJECT_CLASS_TYPE (object_class), - G_SIGNAL_RUN_FIRST, - 0, /* No class closure here */ - NULL, NULL, - _gtk_marshal_VOID__OBJECT_OBJECT_BOXED_STRING, - G_TYPE_NONE, 4, - GTK_TYPE_CELL_RENDERER, - GTK_TYPE_CELL_EDITABLE, - GDK_TYPE_RECTANGLE, - G_TYPE_STRING); + G_OBJECT_CLASS_TYPE (object_class), + G_SIGNAL_RUN_FIRST, + 0, /* No class closure here */ + NULL, NULL, + _gtk_marshal_VOID__OBJECT_OBJECT_BOXED_STRING, + G_TYPE_NONE, 4, + GTK_TYPE_CELL_RENDERER, + GTK_TYPE_CELL_EDITABLE, + GDK_TYPE_RECTANGLE, + G_TYPE_STRING); /** @@ -664,20 +745,20 @@ gtk_cell_area_class_init (GtkCellAreaClass *class) * @editable: the #GtkCellEditable widget to remove * * Indicates that editing finished on @renderer and that @editable - * should be removed from the owning cell layouting widget. + * should be removed from the owning cell-layouting widget. * * Since: 3.0 */ cell_area_signals[SIGNAL_REMOVE_EDITABLE] = g_signal_new (I_("remove-editable"), - G_OBJECT_CLASS_TYPE (object_class), - G_SIGNAL_RUN_FIRST, - 0, /* No class closure here */ - NULL, NULL, - _gtk_marshal_VOID__OBJECT_OBJECT, - G_TYPE_NONE, 2, - GTK_TYPE_CELL_RENDERER, - GTK_TYPE_CELL_EDITABLE); + G_OBJECT_CLASS_TYPE (object_class), + G_SIGNAL_RUN_FIRST, + 0, /* No class closure here */ + NULL, NULL, + _gtk_marshal_VOID__OBJECT_OBJECT, + G_TYPE_NONE, 2, + GTK_TYPE_CELL_RENDERER, + GTK_TYPE_CELL_EDITABLE); /** * GtkCellArea::focus-changed: @@ -698,14 +779,14 @@ gtk_cell_area_class_init (GtkCellAreaClass *class) */ cell_area_signals[SIGNAL_FOCUS_CHANGED] = g_signal_new (I_("focus-changed"), - G_OBJECT_CLASS_TYPE (object_class), - G_SIGNAL_RUN_FIRST, - 0, /* No class closure here */ - NULL, NULL, - _gtk_marshal_VOID__OBJECT_STRING, - G_TYPE_NONE, 2, - GTK_TYPE_CELL_RENDERER, - G_TYPE_STRING); + G_OBJECT_CLASS_TYPE (object_class), + G_SIGNAL_RUN_FIRST, + 0, /* No class closure here */ + NULL, NULL, + _gtk_marshal_VOID__OBJECT_STRING, + G_TYPE_NONE, 2, + GTK_TYPE_CELL_RENDERER, + G_TYPE_STRING); /* Properties */ /** @@ -718,11 +799,11 @@ gtk_cell_area_class_init (GtkCellAreaClass *class) g_object_class_install_property (object_class, PROP_FOCUS_CELL, g_param_spec_object - ("focus-cell", - P_("Focus Cell"), - P_("The cell which currently has focus"), - GTK_TYPE_CELL_RENDERER, - GTK_PARAM_READWRITE)); + ("focus-cell", + P_("Focus Cell"), + P_("The cell which currently has focus"), + GTK_TYPE_CELL_RENDERER, + GTK_PARAM_READWRITE)); /** * GtkCellArea:edited-cell: @@ -737,11 +818,11 @@ gtk_cell_area_class_init (GtkCellAreaClass *class) g_object_class_install_property (object_class, PROP_EDITED_CELL, g_param_spec_object - ("edited-cell", - P_("Edited Cell"), - P_("The cell which is currently being edited"), - GTK_TYPE_CELL_RENDERER, - G_PARAM_READABLE)); + ("edited-cell", + P_("Edited Cell"), + P_("The cell which is currently being edited"), + GTK_TYPE_CELL_RENDERER, + G_PARAM_READABLE)); /** * GtkCellArea:edit-widget: @@ -756,11 +837,11 @@ gtk_cell_area_class_init (GtkCellAreaClass *class) g_object_class_install_property (object_class, PROP_EDIT_WIDGET, g_param_spec_object - ("edit-widget", - P_("Edit Widget"), - P_("The widget currently editing the edited cell"), - GTK_TYPE_CELL_RENDERER, - G_PARAM_READABLE)); + ("edit-widget", + P_("Edit Widget"), + P_("The widget currently editing the edited cell"), + GTK_TYPE_CELL_EDITABLE, + G_PARAM_READABLE)); /* Pool for Cell Properties */ if (!cell_property_pool) @@ -774,8 +855,8 @@ gtk_cell_area_class_init (GtkCellAreaClass *class) *************************************************************/ static CellInfo * cell_info_new (GtkCellLayoutDataFunc func, - gpointer data, - GDestroyNotify destroy) + gpointer data, + GDestroyNotify destroy) { CellInfo *info = g_slice_new0 (CellInfo); @@ -800,14 +881,14 @@ cell_info_free (CellInfo *info) static CellAttribute * cell_attribute_new (GtkCellRenderer *renderer, - const gchar *attribute, - gint column) + const gchar *attribute, + gint column) { GParamSpec *pspec; /* Check if the attribute really exists and point to * the property string installed on the cell renderer - * class (dont dup the string) + * class (dont dup the string) */ pspec = g_object_class_find_property (G_OBJECT_GET_CLASS (renderer), attribute); @@ -833,7 +914,7 @@ cell_attribute_free (CellAttribute *attribute) /* GCompareFunc for g_slist_find_custom() */ static gint cell_attribute_find (CellAttribute *cell_attribute, - const gchar *attribute) + const gchar *attribute) { return g_strcmp0 (cell_attribute->attribute, attribute); } @@ -848,7 +929,7 @@ gtk_cell_area_finalize (GObject *object) GtkCellAreaPrivate *priv = area->priv; /* All cell renderers should already be removed at this point, - * just kill our (empty) hash tables here. + * just kill our (empty) hash tables here. */ g_hash_table_destroy (priv->cell_info); g_hash_table_destroy (priv->focus_siblings); @@ -863,7 +944,7 @@ static void gtk_cell_area_dispose (GObject *object) { /* This removes every cell renderer that may be added to the GtkCellArea, - * subclasses should be breaking references to the GtkCellRenderers + * subclasses should be breaking references to the GtkCellRenderers * at this point. */ gtk_cell_layout_clear (GTK_CELL_LAYOUT (object)); @@ -878,9 +959,9 @@ gtk_cell_area_dispose (GObject *object) static void gtk_cell_area_set_property (GObject *object, - guint prop_id, - const GValue *value, - GParamSpec *pspec) + guint prop_id, + const GValue *value, + GParamSpec *pspec) { GtkCellArea *area = GTK_CELL_AREA (object); @@ -897,9 +978,9 @@ gtk_cell_area_set_property (GObject *object, static void gtk_cell_area_get_property (GObject *object, - guint prop_id, - GValue *value, - GParamSpec *pspec) + guint prop_id, + GValue *value, + GParamSpec *pspec) { GtkCellArea *area = GTK_CELL_AREA (object); GtkCellAreaPrivate *priv = area->priv; @@ -924,13 +1005,51 @@ gtk_cell_area_get_property (GObject *object, /************************************************************* * GtkCellAreaClass * *************************************************************/ +static void +gtk_cell_area_real_add (GtkCellArea *area, + GtkCellRenderer *renderer) +{ + g_warning ("GtkCellAreaClass::add not implemented for `%s'", + g_type_name (G_TYPE_FROM_INSTANCE (area))); +} + +static void +gtk_cell_area_real_remove (GtkCellArea *area, + GtkCellRenderer *renderer) +{ + g_warning ("GtkCellAreaClass::remove not implemented for `%s'", + g_type_name (G_TYPE_FROM_INSTANCE (area))); +} + +static void +gtk_cell_area_real_foreach (GtkCellArea *area, + GtkCellCallback callback, + gpointer callback_data) +{ + g_warning ("GtkCellAreaClass::foreach not implemented for `%s'", + g_type_name (G_TYPE_FROM_INSTANCE (area))); +} + +static void +gtk_cell_area_real_foreach_alloc (GtkCellArea *area, + GtkCellAreaContext *context, + GtkWidget *widget, + const GdkRectangle *cell_area, + const GdkRectangle *background_area, + GtkCellAllocCallback callback, + gpointer callback_data) +{ + g_warning ("GtkCellAreaClass::foreach_alloc not implemented for `%s'", + g_type_name (G_TYPE_FROM_INSTANCE (area))); +} + static gint gtk_cell_area_real_event (GtkCellArea *area, - GtkCellAreaContext *context, - GtkWidget *widget, - GdkEvent *event, - const GdkRectangle *cell_area, - GtkCellRendererState flags) + GtkCellAreaContext *context, + GtkWidget *widget, + GdkEvent *event, + const GdkRectangle *cell_area, + GtkCellRendererState flags) { GtkCellAreaPrivate *priv = area->priv; gboolean retval = FALSE; @@ -941,88 +1060,210 @@ gtk_cell_area_real_event (GtkCellArea *area, /* Cancel any edits in progress */ if (priv->edited_cell && (key_event->keyval == GDK_KEY_Escape)) - { - gtk_cell_area_stop_editing (area, TRUE); - retval = TRUE; - } + { + gtk_cell_area_stop_editing (area, TRUE); + retval = TRUE; + } } else if (event->type == GDK_BUTTON_PRESS) { GdkEventButton *button_event = (GdkEventButton *)event; - if (button_event->button == 1) - { - GtkCellRenderer *renderer; - GtkCellRenderer *focus_renderer; - GdkRectangle alloc_area, inner_area; - gint event_x, event_y; - - /* We may need some semantics to tell us the offset of the event - * window we are handling events for (i.e. GtkTreeView has a bin_window) */ - event_x = button_event->x; - event_y = button_event->y; - - renderer = - gtk_cell_area_get_cell_at_position (area, context, widget, - cell_area, event_x, event_y, - &alloc_area); - - if (renderer) - { - focus_renderer = gtk_cell_area_get_focus_from_sibling (area, renderer); - if (!focus_renderer) - focus_renderer = renderer; - - /* If we're already editing, cancel it and set focus */ - if (gtk_cell_area_get_edited_cell (area)) - { - /* XXX Was it really canceled in this case ? */ - gtk_cell_area_stop_editing (area, TRUE); - gtk_cell_area_set_focus_cell (area, focus_renderer); - retval = TRUE; - } - else - { - /* If we are activating via a focus sibling, - * we need to fetch the right cell area for the real event renderer */ - if (focus_renderer != renderer) - gtk_cell_area_get_cell_allocation (area, context, widget, focus_renderer, - cell_area, &alloc_area); - - gtk_cell_area_inner_cell_area (area, widget, &alloc_area, &inner_area); - - gtk_cell_area_set_focus_cell (area, focus_renderer); - retval = gtk_cell_area_activate_cell (area, widget, focus_renderer, - event, &inner_area, flags); - } - } - } + if (button_event->button == GDK_BUTTON_PRIMARY) + { + GtkCellRenderer *renderer = NULL; + GtkCellRenderer *focus_renderer; + GdkRectangle alloc_area; + gint event_x, event_y; + + /* We may need some semantics to tell us the offset of the event + * window we are handling events for (i.e. GtkTreeView has a bin_window) */ + event_x = button_event->x; + event_y = button_event->y; + + /* Dont try to search for an event coordinate that is not in the area, that will + * trigger a runtime warning. + */ + if (event_x >= cell_area->x && event_x <= cell_area->x + cell_area->width && + event_y >= cell_area->y && event_y <= cell_area->y + cell_area->height) + renderer = + gtk_cell_area_get_cell_at_position (area, context, widget, + cell_area, event_x, event_y, + &alloc_area); + + if (renderer) + { + focus_renderer = gtk_cell_area_get_focus_from_sibling (area, renderer); + if (!focus_renderer) + focus_renderer = renderer; + + /* If we're already editing, cancel it and set focus */ + if (gtk_cell_area_get_edited_cell (area)) + { + /* XXX Was it really canceled in this case ? */ + gtk_cell_area_stop_editing (area, TRUE); + gtk_cell_area_set_focus_cell (area, focus_renderer); + retval = TRUE; + } + else + { + /* If we are activating via a focus sibling, + * we need to fetch the right cell area for the real event renderer */ + if (focus_renderer != renderer) + gtk_cell_area_get_cell_allocation (area, context, widget, focus_renderer, + cell_area, &alloc_area); + + gtk_cell_area_set_focus_cell (area, focus_renderer); + retval = gtk_cell_area_activate_cell (area, widget, focus_renderer, + event, &alloc_area, flags); + } + } + } } return retval; } +static gboolean +render_cell (GtkCellRenderer *renderer, + const GdkRectangle *cell_area, + const GdkRectangle *cell_background, + CellRenderData *data) +{ + GtkCellRenderer *focus_cell; + GtkCellRendererState flags; + GdkRectangle inner_area; + + focus_cell = gtk_cell_area_get_focus_cell (data->area); + flags = data->render_flags; + + gtk_cell_area_inner_cell_area (data->area, data->widget, cell_area, &inner_area); + + if ((flags & GTK_CELL_RENDERER_FOCUSED) && + (data->focus_all || + (focus_cell && + (renderer == focus_cell || + gtk_cell_area_is_focus_sibling (data->area, focus_cell, renderer))))) + { + gint focus_line_width; + GdkRectangle cell_focus; + + gtk_cell_renderer_get_aligned_area (renderer, data->widget, flags, &inner_area, &cell_focus); + + gtk_widget_style_get (data->widget, + "focus-line-width", &focus_line_width, + NULL); + + /* The focus rectangle is located around the aligned area of the cell */ + cell_focus.x -= focus_line_width; + cell_focus.y -= focus_line_width; + cell_focus.width += 2 * focus_line_width; + cell_focus.height += 2 * focus_line_width; + + if (data->first_focus) + { + data->first_focus = FALSE; + data->focus_rect = cell_focus; + } + else + { + gdk_rectangle_union (&data->focus_rect, &cell_focus, &data->focus_rect); + } + } + + gtk_cell_renderer_render (renderer, data->cr, data->widget, + cell_background, &inner_area, flags); + + return FALSE; +} + +static void +gtk_cell_area_real_render (GtkCellArea *area, + GtkCellAreaContext *context, + GtkWidget *widget, + cairo_t *cr, + const GdkRectangle *background_area, + const GdkRectangle *cell_area, + GtkCellRendererState flags, + gboolean paint_focus) +{ + CellRenderData render_data = + { + area, + widget, + cr, + { 0, }, + flags, + paint_focus, + FALSE, TRUE + }; + + /* Make sure we dont paint a focus rectangle while there + * is an editable widget in play + */ + if (gtk_cell_area_get_edited_cell (area)) + render_data.paint_focus = FALSE; + + if (!gtk_widget_has_visible_focus (widget)) + render_data.paint_focus = FALSE; + + /* If no cell can activate but the caller wants focus painted, + * then we paint focus around all cells */ + if ((flags & GTK_CELL_RENDERER_FOCUSED) != 0 && paint_focus && + !gtk_cell_area_is_activatable (area)) + render_data.focus_all = TRUE; + + gtk_cell_area_foreach_alloc (area, context, widget, cell_area, background_area, + (GtkCellAllocCallback)render_cell, &render_data); + + if (render_data.paint_focus && + render_data.focus_rect.width != 0 && + render_data.focus_rect.height != 0) + { + GtkStyleContext *style_context; + GtkStateFlags renderer_state = 0; + + style_context = gtk_widget_get_style_context (widget); + gtk_style_context_save (style_context); + + renderer_state = gtk_cell_renderer_get_state (NULL, widget, flags); + gtk_style_context_set_state (style_context, renderer_state); + + cairo_save (cr); + + gdk_cairo_rectangle (cr, background_area); + cairo_clip (cr); + + gtk_render_focus (style_context, cr, + render_data.focus_rect.x, render_data.focus_rect.y, + render_data.focus_rect.width, render_data.focus_rect.height); + + gtk_style_context_restore (style_context); + cairo_restore (cr); + } +} + static void apply_cell_attributes (GtkCellRenderer *renderer, - CellInfo *info, - AttributeData *data) + CellInfo *info, + AttributeData *data) { CellAttribute *attribute; GSList *list; - GValue value = { 0, }; + GValue value = G_VALUE_INIT; gboolean is_expander; gboolean is_expanded; g_object_freeze_notify (G_OBJECT (renderer)); - /* Whether a row expands or is presently expanded can only be + /* Whether a row expands or is presently expanded can only be * provided by the view (as these states can vary across views * accessing the same model). */ g_object_get (renderer, "is-expander", &is_expander, NULL); if (is_expander != data->is_expander) g_object_set (renderer, "is-expander", data->is_expander, NULL); - + g_object_get (renderer, "is-expanded", &is_expanded, NULL); if (is_expanded != data->is_expanded) g_object_set (renderer, "is-expanded", data->is_expanded, NULL); @@ -1040,7 +1281,7 @@ apply_cell_attributes (GtkCellRenderer *renderer, /* Call any GtkCellLayoutDataFunc that may have been set by the user */ if (info->func) - info->func (GTK_CELL_LAYOUT (data->area), renderer, + info->func (info->proxy ? info->proxy : GTK_CELL_LAYOUT (data->area), renderer, data->model, data->iter, info->data); g_object_thaw_notify (G_OBJECT (renderer)); @@ -1048,10 +1289,10 @@ apply_cell_attributes (GtkCellRenderer *renderer, static void gtk_cell_area_real_apply_attributes (GtkCellArea *area, - GtkTreeModel *tree_model, - GtkTreeIter *iter, - gboolean is_expander, - gboolean is_expanded) + GtkTreeModel *tree_model, + GtkTreeIter *iter, + gboolean is_expander, + gboolean is_expanded) { GtkCellAreaPrivate *priv; @@ -1078,25 +1319,73 @@ gtk_cell_area_real_apply_attributes (GtkCellArea *area, gtk_tree_path_free (path); } +static GtkCellAreaContext * +gtk_cell_area_real_create_context (GtkCellArea *area) +{ + g_warning ("GtkCellAreaClass::create_context not implemented for `%s'", + g_type_name (G_TYPE_FROM_INSTANCE (area))); + + return NULL; +} + +static GtkCellAreaContext * +gtk_cell_area_real_copy_context (GtkCellArea *area, + GtkCellAreaContext *context) +{ + g_warning ("GtkCellAreaClass::copy_context not implemented for `%s'", + g_type_name (G_TYPE_FROM_INSTANCE (area))); + + return NULL; +} + +static GtkSizeRequestMode +gtk_cell_area_real_get_request_mode (GtkCellArea *area) +{ + /* By default cell areas are height-for-width. */ + return GTK_SIZE_REQUEST_HEIGHT_FOR_WIDTH; +} + +static void +gtk_cell_area_real_get_preferred_width (GtkCellArea *area, + GtkCellAreaContext *context, + GtkWidget *widget, + gint *minimum_width, + gint *natural_width) +{ + g_warning ("GtkCellAreaClass::get_preferred_width not implemented for `%s'", + g_type_name (G_TYPE_FROM_INSTANCE (area))); +} + +static void +gtk_cell_area_real_get_preferred_height (GtkCellArea *area, + GtkCellAreaContext *context, + GtkWidget *widget, + gint *minimum_height, + gint *natural_height) +{ + g_warning ("GtkCellAreaClass::get_preferred_height not implemented for `%s'", + g_type_name (G_TYPE_FROM_INSTANCE (area))); +} + static void gtk_cell_area_real_get_preferred_height_for_width (GtkCellArea *area, - GtkCellAreaContext *context, - GtkWidget *widget, + GtkCellAreaContext *context, + GtkWidget *widget, gint width, - gint *minimum_height, - gint *natural_height) + gint *minimum_height, + gint *natural_height) { /* If the area doesnt do height-for-width, fallback on base preferred height */ - GTK_CELL_AREA_GET_CLASS (area)->get_preferred_width (area, context, widget, minimum_height, natural_height); + GTK_CELL_AREA_GET_CLASS (area)->get_preferred_height (area, context, widget, minimum_height, natural_height); } static void gtk_cell_area_real_get_preferred_width_for_height (GtkCellArea *area, - GtkCellAreaContext *context, - GtkWidget *widget, - gint height, - gint *minimum_width, - gint *natural_width) + GtkCellAreaContext *context, + GtkWidget *widget, + gint height, + gint *minimum_width, + gint *natural_width) { /* If the area doesnt do width-for-height, fallback on base preferred width */ GTK_CELL_AREA_GET_CLASS (area)->get_preferred_width (area, context, widget, minimum_width, natural_width); @@ -1104,7 +1393,7 @@ gtk_cell_area_real_get_preferred_width_for_height (GtkCellArea *area, static gboolean get_is_activatable (GtkCellRenderer *renderer, - gboolean *activatable) + gboolean *activatable) { if (gtk_cell_renderer_is_activatable (renderer)) @@ -1131,17 +1420,26 @@ gtk_cell_area_real_is_activatable (GtkCellArea *area) static gboolean gtk_cell_area_real_activate (GtkCellArea *area, - GtkCellAreaContext *context, - GtkWidget *widget, - const GdkRectangle *cell_area, - GtkCellRendererState flags) + GtkCellAreaContext *context, + GtkWidget *widget, + const GdkRectangle *cell_area, + GtkCellRendererState flags, + gboolean edit_only) { GtkCellAreaPrivate *priv = area->priv; - GdkRectangle background_area; + GdkRectangle renderer_area; GtkCellRenderer *activate_cell = NULL; + GtkCellRendererMode mode; if (priv->focus_cell) - activate_cell = priv->focus_cell; + { + g_object_get (priv->focus_cell, "mode", &mode, NULL); + + if (gtk_cell_renderer_get_visible (priv->focus_cell) && + (edit_only ? mode == GTK_CELL_RENDERER_MODE_EDITABLE : + mode != GTK_CELL_RENDERER_MODE_INERT)) + activate_cell = priv->focus_cell; + } else { GList *cells, *l; @@ -1151,36 +1449,48 @@ gtk_cell_area_real_activate (GtkCellArea *area, */ cells = gtk_cell_layout_get_cells (GTK_CELL_LAYOUT (area)); for (l = cells; l && !activate_cell; l = l->next) - { - GtkCellRenderer *renderer = l->data; + { + GtkCellRenderer *renderer = l->data; - if (gtk_cell_renderer_is_activatable (renderer)) - activate_cell = renderer; - } + g_object_get (renderer, "mode", &mode, NULL); + + if (gtk_cell_renderer_get_visible (renderer) && + (edit_only ? mode == GTK_CELL_RENDERER_MODE_EDITABLE : + mode != GTK_CELL_RENDERER_MODE_INERT)) + activate_cell = renderer; + } g_list_free (cells); } - if (activate_cell) { /* Get the allocation of the focused cell. */ gtk_cell_area_get_cell_allocation (area, context, widget, activate_cell, - cell_area, &background_area); - + cell_area, &renderer_area); + /* Activate or Edit the cell * * Currently just not sending an event, renderers afaics dont use * the event argument anyway, worst case is we can synthesize one. */ if (gtk_cell_area_activate_cell (area, widget, activate_cell, NULL, - &background_area, flags)) - return TRUE; + &renderer_area, flags)) + return TRUE; } return FALSE; } +static gboolean +gtk_cell_area_real_focus (GtkCellArea *area, + GtkDirectionType direction) +{ + g_warning ("GtkCellAreaClass::focus not implemented for `%s'", + g_type_name (G_TYPE_FROM_INSTANCE (area))); + return FALSE; +} + /************************************************************* * GtkCellLayoutIface * *************************************************************/ @@ -1195,12 +1505,13 @@ gtk_cell_area_cell_layout_init (GtkCellLayoutIface *iface) iface->clear_attributes = gtk_cell_area_clear_attributes; iface->reorder = gtk_cell_area_reorder; iface->get_cells = gtk_cell_area_get_cells; + iface->get_area = gtk_cell_area_get_area; } static void gtk_cell_area_pack_default (GtkCellLayout *cell_layout, - GtkCellRenderer *renderer, - gboolean expand) + GtkCellRenderer *renderer, + gboolean expand) { gtk_cell_area_add (GTK_CELL_AREA (cell_layout), renderer); } @@ -1223,56 +1534,29 @@ gtk_cell_area_clear (GtkCellLayout *cell_layout) static void gtk_cell_area_add_attribute (GtkCellLayout *cell_layout, - GtkCellRenderer *renderer, - const gchar *attribute, - gint column) + GtkCellRenderer *renderer, + const gchar *attribute, + gint column) { gtk_cell_area_attribute_connect (GTK_CELL_AREA (cell_layout), - renderer, attribute, column); + renderer, attribute, column); } static void gtk_cell_area_set_cell_data_func (GtkCellLayout *cell_layout, - GtkCellRenderer *renderer, - GtkCellLayoutDataFunc func, - gpointer func_data, - GDestroyNotify destroy) + GtkCellRenderer *renderer, + GtkCellLayoutDataFunc func, + gpointer func_data, + GDestroyNotify destroy) { - GtkCellArea *area = GTK_CELL_AREA (cell_layout); - GtkCellAreaPrivate *priv = area->priv; - CellInfo *info; - - info = g_hash_table_lookup (priv->cell_info, renderer); - - if (info) - { - if (info->destroy && info->data) - info->destroy (info->data); + GtkCellArea *area = GTK_CELL_AREA (cell_layout); - if (func) - { - info->func = func; - info->data = func_data; - info->destroy = destroy; - } - else - { - info->func = NULL; - info->data = NULL; - info->destroy = NULL; - } - } - else - { - info = cell_info_new (func, func_data, destroy); - - g_hash_table_insert (priv->cell_info, renderer, info); - } + _gtk_cell_area_set_cell_data_func_with_proxy (area, renderer, (GFunc)func, func_data, destroy, NULL); } static void gtk_cell_area_clear_attributes (GtkCellLayout *cell_layout, - GtkCellRenderer *renderer) + GtkCellRenderer *renderer) { GtkCellArea *area = GTK_CELL_AREA (cell_layout); GtkCellAreaPrivate *priv = area->priv; @@ -1289,18 +1573,18 @@ gtk_cell_area_clear_attributes (GtkCellLayout *cell_layout, } } -static void +static void gtk_cell_area_reorder (GtkCellLayout *cell_layout, - GtkCellRenderer *cell, - gint position) + GtkCellRenderer *cell, + gint position) { - g_warning ("GtkCellLayout::reorder not implemented for `%s'", - g_type_name (G_TYPE_FROM_INSTANCE (cell_layout))); + g_warning ("GtkCellLayout::reorder not implemented for `%s'", + g_type_name (G_TYPE_FROM_INSTANCE (cell_layout))); } static gboolean accum_cells (GtkCellRenderer *renderer, - GList **accum) + GList **accum) { *accum = g_list_prepend (*accum, renderer); @@ -1312,13 +1596,40 @@ gtk_cell_area_get_cells (GtkCellLayout *cell_layout) { GList *cells = NULL; - gtk_cell_area_foreach (GTK_CELL_AREA (cell_layout), - (GtkCellCallback)accum_cells, - &cells); + gtk_cell_area_foreach (GTK_CELL_AREA (cell_layout), + (GtkCellCallback)accum_cells, + &cells); return g_list_reverse (cells); } +static GtkCellArea * +gtk_cell_area_get_area (GtkCellLayout *cell_layout) +{ + return GTK_CELL_AREA (cell_layout); +} + +/************************************************************* + * GtkBuildableIface * + *************************************************************/ +static void +gtk_cell_area_buildable_init (GtkBuildableIface *iface) +{ + iface->add_child = _gtk_cell_layout_buildable_add_child; + iface->custom_tag_start = _gtk_cell_layout_buildable_custom_tag_start; + iface->custom_tag_end = gtk_cell_area_buildable_custom_tag_end; +} + +static void +gtk_cell_area_buildable_custom_tag_end (GtkBuildable *buildable, + GtkBuilder *builder, + GObject *child, + const gchar *tagname, + gpointer *data) +{ + /* Just ignore the boolean return from here */ + _gtk_cell_layout_buildable_custom_tag_end (buildable, builder, child, tagname, data); +} /************************************************************* * API * @@ -1335,20 +1646,12 @@ gtk_cell_area_get_cells (GtkCellLayout *cell_layout) */ void gtk_cell_area_add (GtkCellArea *area, - GtkCellRenderer *renderer) + GtkCellRenderer *renderer) { - GtkCellAreaClass *class; - g_return_if_fail (GTK_IS_CELL_AREA (area)); g_return_if_fail (GTK_IS_CELL_RENDERER (renderer)); - class = GTK_CELL_AREA_GET_CLASS (area); - - if (class->add) - class->add (area, renderer); - else - g_warning ("GtkCellAreaClass::add not implemented for `%s'", - g_type_name (G_TYPE_FROM_INSTANCE (area))); + GTK_CELL_AREA_GET_CLASS (area)->add (area, renderer); } /** @@ -1362,16 +1665,14 @@ gtk_cell_area_add (GtkCellArea *area, */ void gtk_cell_area_remove (GtkCellArea *area, - GtkCellRenderer *renderer) + GtkCellRenderer *renderer) { - GtkCellAreaClass *class; GtkCellAreaPrivate *priv; GList *renderers, *l; g_return_if_fail (GTK_IS_CELL_AREA (area)); g_return_if_fail (GTK_IS_CELL_RENDERER (renderer)); - class = GTK_CELL_AREA_GET_CLASS (area); priv = area->priv; /* Remove any custom attributes and custom cell data func here first */ @@ -1380,7 +1681,7 @@ gtk_cell_area_remove (GtkCellArea *area, /* Remove focus siblings of this renderer */ g_hash_table_remove (priv->focus_siblings, renderer); - /* Remove this renderer from any focus renderer's sibling list */ + /* Remove this renderer from any focus renderer's sibling list */ renderers = gtk_cell_layout_get_cells (GTK_CELL_LAYOUT (area)); for (l = renderers; l; l = l->next) @@ -1388,24 +1689,20 @@ gtk_cell_area_remove (GtkCellArea *area, GtkCellRenderer *focus_renderer = l->data; if (gtk_cell_area_is_focus_sibling (area, focus_renderer, renderer)) - { - gtk_cell_area_remove_focus_sibling (area, focus_renderer, renderer); - break; - } + { + gtk_cell_area_remove_focus_sibling (area, focus_renderer, renderer); + break; + } } g_list_free (renderers); - if (class->remove) - class->remove (area, renderer); - else - g_warning ("GtkCellAreaClass::remove not implemented for `%s'", - g_type_name (G_TYPE_FROM_INSTANCE (area))); + GTK_CELL_AREA_GET_CLASS (area)->remove (area, renderer); } static gboolean get_has_renderer (GtkCellRenderer *renderer, - HasRendererCheck *check) + HasRendererCheck *check) { if (renderer == check->renderer) check->has_renderer = TRUE; @@ -1426,7 +1723,7 @@ get_has_renderer (GtkCellRenderer *renderer, */ gboolean gtk_cell_area_has_renderer (GtkCellArea *area, - GtkCellRenderer *renderer) + GtkCellRenderer *renderer) { HasRendererCheck check = { renderer, FALSE }; @@ -1441,7 +1738,7 @@ gtk_cell_area_has_renderer (GtkCellArea *area, /** * gtk_cell_area_foreach: * @area: a #GtkCellArea - * @callback: the #GtkCellCallback to call + * @callback: (scope call): the #GtkCellCallback to call * @callback_data: user provided data pointer * * Calls @callback for every #GtkCellRenderer in @area. @@ -1450,21 +1747,13 @@ gtk_cell_area_has_renderer (GtkCellArea *area, */ void gtk_cell_area_foreach (GtkCellArea *area, - GtkCellCallback callback, - gpointer callback_data) + GtkCellCallback callback, + gpointer callback_data) { - GtkCellAreaClass *class; - g_return_if_fail (GTK_IS_CELL_AREA (area)); g_return_if_fail (callback != NULL); - class = GTK_CELL_AREA_GET_CLASS (area); - - if (class->foreach) - class->foreach (area, callback, callback_data); - else - g_warning ("GtkCellAreaClass::foreach not implemented for `%s'", - g_type_name (G_TYPE_FROM_INSTANCE (area))); + GTK_CELL_AREA_GET_CLASS (area)->foreach (area, callback, callback_data); } /** @@ -1473,7 +1762,8 @@ gtk_cell_area_foreach (GtkCellArea *area, * @context: the #GtkCellAreaContext for this row of data. * @widget: the #GtkWidget that @area is rendering to * @cell_area: the @widget relative coordinates and size for @area - * @callback: the #GtkCellAllocCallback to call + * @background_area: the @widget relative coordinates of the background area + * @callback: (scope call): the #GtkCellAllocCallback to call * @callback_data: user provided data pointer * * Calls @callback for every #GtkCellRenderer in @area with the @@ -1483,27 +1773,22 @@ gtk_cell_area_foreach (GtkCellArea *area, */ void gtk_cell_area_foreach_alloc (GtkCellArea *area, - GtkCellAreaContext *context, - GtkWidget *widget, - const GdkRectangle *cell_area, - GtkCellAllocCallback callback, - gpointer callback_data) + GtkCellAreaContext *context, + GtkWidget *widget, + const GdkRectangle *cell_area, + const GdkRectangle *background_area, + GtkCellAllocCallback callback, + gpointer callback_data) { - GtkCellAreaClass *class; - g_return_if_fail (GTK_IS_CELL_AREA (area)); g_return_if_fail (GTK_IS_CELL_AREA_CONTEXT (context)); g_return_if_fail (GTK_IS_WIDGET (widget)); g_return_if_fail (cell_area != NULL); g_return_if_fail (callback != NULL); - class = GTK_CELL_AREA_GET_CLASS (area); - - if (class->foreach_alloc) - class->foreach_alloc (area, context, widget, cell_area, callback, callback_data); - else - g_warning ("GtkCellAreaClass::foreach_alloc not implemented for `%s'", - g_type_name (G_TYPE_FROM_INSTANCE (area))); + GTK_CELL_AREA_GET_CLASS (area)->foreach_alloc (area, context, widget, + cell_area, background_area, + callback, callback_data); } /** @@ -1523,11 +1808,11 @@ gtk_cell_area_foreach_alloc (GtkCellArea *area, */ gint gtk_cell_area_event (GtkCellArea *area, - GtkCellAreaContext *context, - GtkWidget *widget, - GdkEvent *event, - const GdkRectangle *cell_area, - GtkCellRendererState flags) + GtkCellAreaContext *context, + GtkWidget *widget, + GdkEvent *event, + const GdkRectangle *cell_area, + GtkCellRendererState flags) { GtkCellAreaClass *class; @@ -1542,8 +1827,8 @@ gtk_cell_area_event (GtkCellArea *area, if (class->event) return class->event (area, context, widget, event, cell_area, flags); - g_warning ("GtkCellAreaClass::event not implemented for `%s'", - g_type_name (G_TYPE_FROM_INSTANCE (area))); + g_warning ("GtkCellAreaClass::event not implemented for `%s'", + g_type_name (G_TYPE_FROM_INSTANCE (area))); return 0; } @@ -1565,13 +1850,13 @@ gtk_cell_area_event (GtkCellArea *area, */ void gtk_cell_area_render (GtkCellArea *area, - GtkCellAreaContext *context, - GtkWidget *widget, - cairo_t *cr, - const GdkRectangle *background_area, - const GdkRectangle *cell_area, - GtkCellRendererState flags, - gboolean paint_focus) + GtkCellAreaContext *context, + GtkWidget *widget, + cairo_t *cr, + const GdkRectangle *background_area, + const GdkRectangle *cell_area, + GtkCellRendererState flags, + gboolean paint_focus) { GtkCellAreaClass *class; @@ -1587,64 +1872,15 @@ gtk_cell_area_render (GtkCellArea *area, if (class->render) class->render (area, context, widget, cr, background_area, cell_area, flags, paint_focus); else - g_warning ("GtkCellAreaClass::render not implemented for `%s'", - g_type_name (G_TYPE_FROM_INSTANCE (area))); -} - -/** - * gtk_cell_area_set_style_detail: - * @area: a #GtkCellArea - * @detail: the #GtkStyle detail string to set - * - * Sets the detail string used in any gtk_paint_*() functions - * used by @area. - * - * Since: 3.0 - */ -void -gtk_cell_area_set_style_detail (GtkCellArea *area, - const gchar *detail) -{ - GtkCellAreaPrivate *priv; - - g_return_if_fail (GTK_IS_CELL_AREA (area)); - - priv = area->priv; - - if (g_strcmp0 (priv->style_detail, detail) != 0) - { - g_free (priv->style_detail); - priv->style_detail = g_strdup (detail); - } -} - -/** - * gtk_cell_area_get_style_detail: - * @area: a #GtkCellArea - * - * Gets the detail string used in any gtk_paint_*() functions - * used by @area. - * - * Return value: the detail string, the string belongs to the area and should not be freed. - * - * Since: 3.0 - */ -G_CONST_RETURN gchar * -gtk_cell_area_get_style_detail (GtkCellArea *area) -{ - GtkCellAreaPrivate *priv; - - g_return_val_if_fail (GTK_IS_CELL_AREA (area), NULL); - - priv = area->priv; - - return priv->style_detail; + g_warning ("GtkCellAreaClass::render not implemented for `%s'", + g_type_name (G_TYPE_FROM_INSTANCE (area))); } static gboolean get_cell_allocation (GtkCellRenderer *renderer, - const GdkRectangle *cell_area, - RendererAllocationData *data) + const GdkRectangle *cell_area, + const GdkRectangle *cell_background, + RendererAllocationData *data) { if (data->renderer == renderer) data->allocation = *cell_area; @@ -1669,11 +1905,11 @@ get_cell_allocation (GtkCellRenderer *renderer, */ void gtk_cell_area_get_cell_allocation (GtkCellArea *area, - GtkCellAreaContext *context, - GtkWidget *widget, - GtkCellRenderer *renderer, - const GdkRectangle *cell_area, - GdkRectangle *allocation) + GtkCellAreaContext *context, + GtkWidget *widget, + GtkCellRenderer *renderer, + const GdkRectangle *cell_area, + GdkRectangle *allocation) { RendererAllocationData data = { renderer, { 0, } }; @@ -1684,16 +1920,17 @@ gtk_cell_area_get_cell_allocation (GtkCellArea *area, g_return_if_fail (cell_area != NULL); g_return_if_fail (allocation != NULL); - gtk_cell_area_foreach_alloc (area, context, widget, cell_area, - (GtkCellAllocCallback)get_cell_allocation, &data); + gtk_cell_area_foreach_alloc (area, context, widget, cell_area, cell_area, + (GtkCellAllocCallback)get_cell_allocation, &data); *allocation = data.allocation; } static gboolean get_cell_by_position (GtkCellRenderer *renderer, - const GdkRectangle *cell_area, - CellByPositionData *data) + const GdkRectangle *cell_area, + const GdkRectangle *cell_background, + CellByPositionData *data) { if (data->x >= cell_area->x && data->x < cell_area->x + cell_area->width && data->y >= cell_area->y && data->y < cell_area->y + cell_area->height) @@ -1714,24 +1951,24 @@ get_cell_by_position (GtkCellRenderer *renderer, * for this row * @x: the x position * @y: the y position - * @alloc_area: (out) (allow-none): where to store the inner allocated area of the + * @alloc_area: (out) (allow-none): where to store the inner allocated area of the * returned cell renderer, or %NULL. * * Gets the #GtkCellRenderer at @x and @y coordinates inside @area and optionally * returns the full cell allocation for it inside @cell_area. * - * Returns: the #GtkCellRenderer at @x and @y. + * Return value: (transfer none): the #GtkCellRenderer at @x and @y. * * Since: 3.0 */ GtkCellRenderer * gtk_cell_area_get_cell_at_position (GtkCellArea *area, - GtkCellAreaContext *context, - GtkWidget *widget, - const GdkRectangle *cell_area, - gint x, - gint y, - GdkRectangle *alloc_area) + GtkCellAreaContext *context, + GtkWidget *widget, + const GdkRectangle *cell_area, + gint x, + gint y, + GdkRectangle *alloc_area) { CellByPositionData data = { x, y, NULL, { 0, } }; @@ -1742,8 +1979,8 @@ gtk_cell_area_get_cell_at_position (GtkCellArea *area, g_return_val_if_fail (x >= cell_area->x && x <= cell_area->x + cell_area->width, NULL); g_return_val_if_fail (y >= cell_area->y && y <= cell_area->y + cell_area->height, NULL); - gtk_cell_area_foreach_alloc (area, context, widget, cell_area, - (GtkCellAllocCallback)get_cell_by_position, &data); + gtk_cell_area_foreach_alloc (area, context, widget, cell_area, cell_area, + (GtkCellAllocCallback)get_cell_by_position, &data); if (alloc_area) *alloc_area = data.cell_area; @@ -1751,7 +1988,6 @@ gtk_cell_area_get_cell_at_position (GtkCellArea *area, return data.renderer; } - /************************************************************* * API: Geometry * *************************************************************/ @@ -1773,22 +2009,42 @@ gtk_cell_area_get_cell_at_position (GtkCellArea *area, GtkCellAreaContext * gtk_cell_area_create_context (GtkCellArea *area) { - GtkCellAreaClass *class; - g_return_val_if_fail (GTK_IS_CELL_AREA (area), NULL); - class = GTK_CELL_AREA_GET_CLASS (area); + return GTK_CELL_AREA_GET_CLASS (area)->create_context (area); +} - if (class->create_context) - return class->create_context (area); +/** + * gtk_cell_area_copy_context: + * @area: a #GtkCellArea + * @context: the #GtkCellAreaContext to copy + * + * This is sometimes needed for cases where rows need to share + * alignments in one orientation but may be separately grouped + * in the opposing orientation. + * + * For instance, #GtkIconView creates all icons (rows) to have + * the same width and the cells theirin to have the same + * horizontal alignments. However each row of icons may have + * a separate collective height. #GtkIconView uses this to + * request the heights of each row based on a context which + * was already used to request all the row widths that are + * to be displayed. + * + * Return value: (transfer full): a newly created #GtkCellAreaContext copy of @context. + * + * Since: 3.0 + */ +GtkCellAreaContext * +gtk_cell_area_copy_context (GtkCellArea *area, + GtkCellAreaContext *context) +{ + g_return_val_if_fail (GTK_IS_CELL_AREA (area), NULL); + g_return_val_if_fail (GTK_IS_CELL_AREA_CONTEXT (context), NULL); - g_warning ("GtkCellAreaClass::create_context not implemented for `%s'", - g_type_name (G_TYPE_FROM_INSTANCE (area))); - - return NULL; + return GTK_CELL_AREA_GET_CLASS (area)->copy_context (area, context); } - /** * gtk_cell_area_get_request_mode: * @area: a #GtkCellArea @@ -1800,23 +2056,13 @@ gtk_cell_area_create_context (GtkCellArea *area) * * Since: 3.0 */ -GtkSizeRequestMode +GtkSizeRequestMode gtk_cell_area_get_request_mode (GtkCellArea *area) { - GtkCellAreaClass *class; - - g_return_val_if_fail (GTK_IS_CELL_AREA (area), - GTK_SIZE_REQUEST_HEIGHT_FOR_WIDTH); - - class = GTK_CELL_AREA_GET_CLASS (area); - - if (class->get_request_mode) - return class->get_request_mode (area); + g_return_val_if_fail (GTK_IS_CELL_AREA (area), + GTK_SIZE_REQUEST_HEIGHT_FOR_WIDTH); - g_warning ("GtkCellAreaClass::get_request_mode not implemented for `%s'", - g_type_name (G_TYPE_FROM_INSTANCE (area))); - - return GTK_SIZE_REQUEST_HEIGHT_FOR_WIDTH; + return GTK_CELL_AREA_GET_CLASS (area)->get_request_mode (area); } /** @@ -1829,8 +2075,8 @@ gtk_cell_area_get_request_mode (GtkCellArea *area) * * Retrieves a cell area's initial minimum and natural width. * - * @area will store some geometrical information in @context along the way, - * when requesting sizes over an arbitrary number of rows, its not important + * @area will store some geometrical information in @context along the way; + * when requesting sizes over an arbitrary number of rows, it's not important * to check the @minimum_width and @natural_width of this call but rather to * consult gtk_cell_area_context_get_preferred_width() after a series of * requests. @@ -1839,23 +2085,16 @@ gtk_cell_area_get_request_mode (GtkCellArea *area) */ void gtk_cell_area_get_preferred_width (GtkCellArea *area, - GtkCellAreaContext *context, - GtkWidget *widget, - gint *minimum_width, - gint *natural_width) + GtkCellAreaContext *context, + GtkWidget *widget, + gint *minimum_width, + gint *natural_width) { - GtkCellAreaClass *class; - g_return_if_fail (GTK_IS_CELL_AREA (area)); g_return_if_fail (GTK_IS_WIDGET (widget)); - class = GTK_CELL_AREA_GET_CLASS (area); - - if (class->get_preferred_width) - class->get_preferred_width (area, context, widget, minimum_width, natural_width); - else - g_warning ("GtkCellAreaClass::get_preferred_width not implemented for `%s'", - g_type_name (G_TYPE_FROM_INSTANCE (area))); + GTK_CELL_AREA_GET_CLASS (area)->get_preferred_width (area, context, widget, + minimum_width, natural_width); } /** @@ -1871,7 +2110,7 @@ gtk_cell_area_get_preferred_width (GtkCellArea *area, * the specified @width. * * @area stores some geometrical information in @context along the way - * while calling gtk_cell_area_get_preferred_width(), it's important to + * while calling gtk_cell_area_get_preferred_width(). It's important to * perform a series of gtk_cell_area_get_preferred_width() requests with * @context first and then call gtk_cell_area_get_preferred_height_for_width() * on each cell area individually to get the height for width of each @@ -1886,11 +2125,11 @@ gtk_cell_area_get_preferred_width (GtkCellArea *area, */ void gtk_cell_area_get_preferred_height_for_width (GtkCellArea *area, - GtkCellAreaContext *context, - GtkWidget *widget, - gint width, - gint *minimum_height, - gint *natural_height) + GtkCellAreaContext *context, + GtkWidget *widget, + gint width, + gint *minimum_height, + gint *natural_height) { GtkCellAreaClass *class; @@ -1912,8 +2151,8 @@ gtk_cell_area_get_preferred_height_for_width (GtkCellArea *area, * * Retrieves a cell area's initial minimum and natural height. * - * @area will store some geometrical information in @context along the way, - * when requesting sizes over an arbitrary number of rows, its not important + * @area will store some geometrical information in @context along the way; + * when requesting sizes over an arbitrary number of rows, it's not important * to check the @minimum_height and @natural_height of this call but rather to * consult gtk_cell_area_context_get_preferred_height() after a series of * requests. @@ -1922,23 +2161,16 @@ gtk_cell_area_get_preferred_height_for_width (GtkCellArea *area, */ void gtk_cell_area_get_preferred_height (GtkCellArea *area, - GtkCellAreaContext *context, - GtkWidget *widget, - gint *minimum_height, - gint *natural_height) + GtkCellAreaContext *context, + GtkWidget *widget, + gint *minimum_height, + gint *natural_height) { - GtkCellAreaClass *class; - g_return_if_fail (GTK_IS_CELL_AREA (area)); g_return_if_fail (GTK_IS_WIDGET (widget)); - class = GTK_CELL_AREA_GET_CLASS (area); - - if (class->get_preferred_height) - class->get_preferred_height (area, context, widget, minimum_height, natural_height); - else - g_warning ("GtkCellAreaClass::get_preferred_height not implemented for `%s'", - g_type_name (G_TYPE_FROM_INSTANCE (area))); + GTK_CELL_AREA_GET_CLASS (area)->get_preferred_height (area, context, widget, + minimum_height, natural_height); } /** @@ -1954,7 +2186,7 @@ gtk_cell_area_get_preferred_height (GtkCellArea *area, * the specified @height. * * @area stores some geometrical information in @context along the way - * while calling gtk_cell_area_get_preferred_height(), it's important to + * while calling gtk_cell_area_get_preferred_height(). It's important to * perform a series of gtk_cell_area_get_preferred_height() requests with * @context first and then call gtk_cell_area_get_preferred_width_for_height() * on each cell area individually to get the height for width of each @@ -1969,11 +2201,11 @@ gtk_cell_area_get_preferred_height (GtkCellArea *area, */ void gtk_cell_area_get_preferred_width_for_height (GtkCellArea *area, - GtkCellAreaContext *context, - GtkWidget *widget, - gint height, - gint *minimum_width, - gint *natural_width) + GtkCellAreaContext *context, + GtkWidget *widget, + gint height, + gint *minimum_width, + gint *natural_width) { GtkCellAreaClass *class; @@ -2002,10 +2234,10 @@ gtk_cell_area_get_preferred_width_for_height (GtkCellArea *area, */ void gtk_cell_area_attribute_connect (GtkCellArea *area, - GtkCellRenderer *renderer, - const gchar *attribute, - gint column) -{ + GtkCellRenderer *renderer, + const gchar *attribute, + gint column) +{ GtkCellAreaPrivate *priv; CellInfo *info; CellAttribute *cell_attribute; @@ -2030,17 +2262,17 @@ gtk_cell_area_attribute_connect (GtkCellArea *area, /* Check we are not adding the same attribute twice */ if ((node = g_slist_find_custom (info->attributes, attribute, - (GCompareFunc)cell_attribute_find)) != NULL) - { - cell_attribute = node->data; - - g_warning ("Cannot connect attribute `%s' for cell renderer class `%s' " - "since `%s' is already attributed to column %d", - attribute, - g_type_name (G_TYPE_FROM_INSTANCE (area)), - attribute, cell_attribute->column); - return; - } + (GCompareFunc)cell_attribute_find)) != NULL) + { + cell_attribute = node->data; + + g_warning ("Cannot connect attribute `%s' for cell renderer class `%s' " + "since `%s' is already attributed to column %d", + attribute, + G_OBJECT_TYPE_NAME (renderer), + attribute, cell_attribute->column); + return; + } } cell_attribute = cell_attribute_new (renderer, attribute, column); @@ -2048,9 +2280,9 @@ gtk_cell_area_attribute_connect (GtkCellArea *area, if (!cell_attribute) { g_warning ("Cannot connect attribute `%s' for cell renderer class `%s' " - "since attribute does not exist", - attribute, - g_type_name (G_TYPE_FROM_INSTANCE (area))); + "since attribute does not exist", + attribute, + G_OBJECT_TYPE_NAME (renderer)); return; } @@ -2069,10 +2301,10 @@ gtk_cell_area_attribute_connect (GtkCellArea *area, * * Since: 3.0 */ -void +void gtk_cell_area_attribute_disconnect (GtkCellArea *area, - GtkCellRenderer *renderer, - const gchar *attribute) + GtkCellRenderer *renderer, + const gchar *attribute) { GtkCellAreaPrivate *priv; CellInfo *info; @@ -2090,20 +2322,20 @@ gtk_cell_area_attribute_disconnect (GtkCellArea *area, if (info) { node = g_slist_find_custom (info->attributes, attribute, - (GCompareFunc)cell_attribute_find); + (GCompareFunc)cell_attribute_find); if (node) - { - cell_attribute = node->data; + { + cell_attribute = node->data; - cell_attribute_free (cell_attribute); + cell_attribute_free (cell_attribute); - info->attributes = g_slist_delete_link (info->attributes, node); - } + info->attributes = g_slist_delete_link (info->attributes, node); + } } } /** - * gtk_cell_area_apply_attributes + * gtk_cell_area_apply_attributes: * @area: a #GtkCellArea * @tree_model: the #GtkTreeModel to pull values from * @iter: the #GtkTreeIter in @tree_model to apply values for @@ -2111,24 +2343,24 @@ gtk_cell_area_attribute_disconnect (GtkCellArea *area, * @is_expanded: whether @iter is expanded in the view and * children are visible * - * Applies any connected attributes to the renderers in + * Applies any connected attributes to the renderers in * @area by pulling the values from @tree_model. * * Since: 3.0 */ void gtk_cell_area_apply_attributes (GtkCellArea *area, - GtkTreeModel *tree_model, - GtkTreeIter *iter, - gboolean is_expander, - gboolean is_expanded) + GtkTreeModel *tree_model, + GtkTreeIter *iter, + gboolean is_expander, + gboolean is_expanded) { g_return_if_fail (GTK_IS_CELL_AREA (area)); g_return_if_fail (GTK_IS_TREE_MODEL (tree_model)); g_return_if_fail (iter != NULL); - g_signal_emit (area, cell_area_signals[SIGNAL_APPLY_ATTRIBUTES], 0, - tree_model, iter, is_expander, is_expanded); + g_signal_emit (area, cell_area_signals[SIGNAL_APPLY_ATTRIBUTES], 0, + tree_model, iter, is_expander, is_expanded); } /** @@ -2147,7 +2379,7 @@ gtk_cell_area_apply_attributes (GtkCellArea *area, * * Since: 3.0 */ -G_CONST_RETURN gchar * +const gchar * gtk_cell_area_get_current_path_string (GtkCellArea *area) { GtkCellAreaPrivate *priv; @@ -2175,8 +2407,8 @@ gtk_cell_area_get_current_path_string (GtkCellArea *area) */ void gtk_cell_area_class_install_cell_property (GtkCellAreaClass *aclass, - guint property_id, - GParamSpec *pspec) + guint property_id, + GParamSpec *pspec) { g_return_if_fail (GTK_IS_CELL_AREA_CLASS (aclass)); g_return_if_fail (G_IS_PARAM_SPEC (pspec)); @@ -2191,7 +2423,7 @@ gtk_cell_area_class_install_cell_property (GtkCellAreaClass *aclass, if (g_param_spec_pool_lookup (cell_property_pool, pspec->name, G_OBJECT_CLASS_TYPE (aclass), TRUE)) { g_warning (G_STRLOC ": class `%s' already contains a cell property named `%s'", - G_OBJECT_CLASS_NAME (aclass), pspec->name); + G_OBJECT_CLASS_NAME (aclass), pspec->name); return; } g_param_spec_ref (pspec); @@ -2207,22 +2439,22 @@ gtk_cell_area_class_install_cell_property (GtkCellAreaClass *aclass, * * Finds a cell property of a cell area class by name. * - * Return value: (allow-none): the #GParamSpec of the child property or %NULL if @aclass has no - * child property with that name. + * Return value: (transfer none): the #GParamSpec of the child property + * or %NULL if @aclass has no child property with that name. * * Since: 3.0 */ GParamSpec* gtk_cell_area_class_find_cell_property (GtkCellAreaClass *aclass, - const gchar *property_name) + const gchar *property_name) { g_return_val_if_fail (GTK_IS_CELL_AREA_CLASS (aclass), NULL); g_return_val_if_fail (property_name != NULL, NULL); return g_param_spec_pool_lookup (cell_property_pool, - property_name, - G_OBJECT_CLASS_TYPE (aclass), - TRUE); + property_name, + G_OBJECT_CLASS_TYPE (aclass), + TRUE); } /** @@ -2232,14 +2464,15 @@ gtk_cell_area_class_find_cell_property (GtkCellAreaClass *aclass, * * Returns all cell properties of a cell area class. * - * Return value: a newly allocated %NULL-terminated array of #GParamSpec*. - * The array must be freed with g_free(). + * Return value: (array length=n_properties) (transfer container): a newly + * allocated %NULL-terminated array of #GParamSpec*. The array + * must be freed with g_free(). * * Since: 3.0 */ GParamSpec** gtk_cell_area_class_list_cell_properties (GtkCellAreaClass *aclass, - guint *n_properties) + guint *n_properties) { GParamSpec **pspecs; guint n; @@ -2247,8 +2480,8 @@ gtk_cell_area_class_list_cell_properties (GtkCellAreaClass *aclass, g_return_val_if_fail (GTK_IS_CELL_AREA_CLASS (aclass), NULL); pspecs = g_param_spec_pool_list (cell_property_pool, - G_OBJECT_CLASS_TYPE (aclass), - &n); + G_OBJECT_CLASS_TYPE (aclass), + &n); if (n_properties) *n_properties = n; @@ -2260,19 +2493,19 @@ gtk_cell_area_class_list_cell_properties (GtkCellAreaClass *aclass, * @area: a #GtkCellArea * @renderer: a #GtkCellRenderer to be placed inside @area * @first_prop_name: the name of the first cell property to set - * @Varargs: a %NULL-terminated list of property names and values, starting - * with @first_prop_name + * @...: a %NULL-terminated list of property names and values, starting + * with @first_prop_name * * Adds @renderer to @area, setting cell properties at the same time. - * See gtk_cell_area_add() and gtk_cell_area_child_set() for more details. + * See gtk_cell_area_add() and gtk_cell_area_cell_set() for more details. * * Since: 3.0 */ void gtk_cell_area_add_with_properties (GtkCellArea *area, - GtkCellRenderer *renderer, - const gchar *first_prop_name, - ...) + GtkCellRenderer *renderer, + const gchar *first_prop_name, + ...) { GtkCellAreaClass *class; @@ -2292,8 +2525,8 @@ gtk_cell_area_add_with_properties (GtkCellArea *area, va_end (var_args); } else - g_warning ("GtkCellAreaClass::add not implemented for `%s'", - g_type_name (G_TYPE_FROM_INSTANCE (area))); + g_warning ("GtkCellAreaClass::add not implemented for `%s'", + g_type_name (G_TYPE_FROM_INSTANCE (area))); } /** @@ -2301,7 +2534,7 @@ gtk_cell_area_add_with_properties (GtkCellArea *area, * @area: a #GtkCellArea * @renderer: a #GtkCellRenderer which is a cell inside @area * @first_prop_name: the name of the first cell property to set - * @Varargs: a %NULL-terminated list of property names and values, starting + * @...: a %NULL-terminated list of property names and values, starting * with @first_prop_name * * Sets one or more cell properties for @cell in @area. @@ -2310,9 +2543,9 @@ gtk_cell_area_add_with_properties (GtkCellArea *area, */ void gtk_cell_area_cell_set (GtkCellArea *area, - GtkCellRenderer *renderer, - const gchar *first_prop_name, - ...) + GtkCellRenderer *renderer, + const gchar *first_prop_name, + ...) { va_list var_args; @@ -2329,7 +2562,7 @@ gtk_cell_area_cell_set (GtkCellArea *area, * @area: a #GtkCellArea * @renderer: a #GtkCellRenderer which is inside @area * @first_prop_name: the name of the first cell property to get - * @Varargs: return location for the first cell property, followed + * @...: return location for the first cell property, followed * optionally by more name/return location pairs, followed by %NULL * * Gets the values of one or more cell properties for @renderer in @area. @@ -2338,9 +2571,9 @@ gtk_cell_area_cell_set (GtkCellArea *area, */ void gtk_cell_area_cell_get (GtkCellArea *area, - GtkCellRenderer *renderer, - const gchar *first_prop_name, - ...) + GtkCellRenderer *renderer, + const gchar *first_prop_name, + ...) { va_list var_args; @@ -2354,40 +2587,40 @@ gtk_cell_area_cell_get (GtkCellArea *area, static inline void area_get_cell_property (GtkCellArea *area, - GtkCellRenderer *renderer, - GParamSpec *pspec, - GValue *value) + GtkCellRenderer *renderer, + GParamSpec *pspec, + GValue *value) { GtkCellAreaClass *class = g_type_class_peek (pspec->owner_type); - + class->get_cell_property (area, renderer, PARAM_SPEC_PARAM_ID (pspec), value, pspec); } static inline void area_set_cell_property (GtkCellArea *area, - GtkCellRenderer *renderer, - GParamSpec *pspec, - const GValue *value) + GtkCellRenderer *renderer, + GParamSpec *pspec, + const GValue *value) { - GValue tmp_value = { 0, }; + GValue tmp_value = G_VALUE_INIT; GtkCellAreaClass *class = g_type_class_peek (pspec->owner_type); /* provide a copy to work from, convert (if necessary) and validate */ g_value_init (&tmp_value, G_PARAM_SPEC_VALUE_TYPE (pspec)); if (!g_value_transform (value, &tmp_value)) g_warning ("unable to set cell property `%s' of type `%s' from value of type `%s'", - pspec->name, - g_type_name (G_PARAM_SPEC_VALUE_TYPE (pspec)), - G_VALUE_TYPE_NAME (value)); + pspec->name, + g_type_name (G_PARAM_SPEC_VALUE_TYPE (pspec)), + G_VALUE_TYPE_NAME (value)); else if (g_param_value_validate (pspec, &tmp_value) && !(pspec->flags & G_PARAM_LAX_VALIDATION)) { gchar *contents = g_strdup_value_contents (value); g_warning ("value \"%s\" of type `%s' is invalid for property `%s' of type `%s'", - contents, - G_VALUE_TYPE_NAME (value), - pspec->name, - g_type_name (G_PARAM_SPEC_VALUE_TYPE (pspec))); + contents, + G_VALUE_TYPE_NAME (value), + pspec->name, + g_type_name (G_PARAM_SPEC_VALUE_TYPE (pspec))); g_free (contents); } else @@ -2411,9 +2644,9 @@ area_set_cell_property (GtkCellArea *area, */ void gtk_cell_area_cell_set_valist (GtkCellArea *area, - GtkCellRenderer *renderer, - const gchar *first_property_name, - va_list var_args) + GtkCellRenderer *renderer, + const gchar *first_property_name, + va_list var_args) { const gchar *name; @@ -2423,36 +2656,36 @@ gtk_cell_area_cell_set_valist (GtkCellArea *area, name = first_property_name; while (name) { - GValue value = { 0, }; + GValue value = G_VALUE_INIT; gchar *error = NULL; - GParamSpec *pspec = - g_param_spec_pool_lookup (cell_property_pool, name, - G_OBJECT_TYPE (area), TRUE); + GParamSpec *pspec = + g_param_spec_pool_lookup (cell_property_pool, name, + G_OBJECT_TYPE (area), TRUE); if (!pspec) - { - g_warning ("%s: cell area class `%s' has no cell property named `%s'", - G_STRLOC, G_OBJECT_TYPE_NAME (area), name); - break; - } + { + g_warning ("%s: cell area class `%s' has no cell property named `%s'", + G_STRLOC, G_OBJECT_TYPE_NAME (area), name); + break; + } if (!(pspec->flags & G_PARAM_WRITABLE)) - { - g_warning ("%s: cell property `%s' of cell area class `%s' is not writable", - G_STRLOC, pspec->name, G_OBJECT_TYPE_NAME (area)); - break; - } - - g_value_init (&value, G_PARAM_SPEC_VALUE_TYPE (pspec)); - G_VALUE_COLLECT (&value, var_args, 0, &error); + { + g_warning ("%s: cell property `%s' of cell area class `%s' is not writable", + G_STRLOC, pspec->name, G_OBJECT_TYPE_NAME (area)); + break; + } + + G_VALUE_COLLECT_INIT (&value, G_PARAM_SPEC_VALUE_TYPE (pspec), + var_args, 0, &error); if (error) - { - g_warning ("%s: %s", G_STRLOC, error); - g_free (error); - - /* we purposely leak the value here, it might not be - * in a sane state if an error condition occoured - */ - break; - } + { + g_warning ("%s: %s", G_STRLOC, error); + g_free (error); + + /* we purposely leak the value here, it might not be + * in a sane state if an error condition occoured + */ + break; + } area_set_cell_property (area, renderer, pspec, &value); g_value_unset (&value); name = va_arg (var_args, gchar*); @@ -2473,9 +2706,9 @@ gtk_cell_area_cell_set_valist (GtkCellArea *area, */ void gtk_cell_area_cell_get_valist (GtkCellArea *area, - GtkCellRenderer *renderer, - const gchar *first_property_name, - va_list var_args) + GtkCellRenderer *renderer, + const gchar *first_property_name, + va_list var_args) { const gchar *name; @@ -2485,35 +2718,35 @@ gtk_cell_area_cell_get_valist (GtkCellArea *area, name = first_property_name; while (name) { - GValue value = { 0, }; + GValue value = G_VALUE_INIT; GParamSpec *pspec; gchar *error; pspec = g_param_spec_pool_lookup (cell_property_pool, name, - G_OBJECT_TYPE (area), TRUE); + G_OBJECT_TYPE (area), TRUE); if (!pspec) - { - g_warning ("%s: cell area class `%s' has no cell property named `%s'", - G_STRLOC, G_OBJECT_TYPE_NAME (area), name); - break; - } + { + g_warning ("%s: cell area class `%s' has no cell property named `%s'", + G_STRLOC, G_OBJECT_TYPE_NAME (area), name); + break; + } if (!(pspec->flags & G_PARAM_READABLE)) - { - g_warning ("%s: cell property `%s' of cell area class `%s' is not readable", - G_STRLOC, pspec->name, G_OBJECT_TYPE_NAME (area)); - break; - } + { + g_warning ("%s: cell property `%s' of cell area class `%s' is not readable", + G_STRLOC, pspec->name, G_OBJECT_TYPE_NAME (area)); + break; + } g_value_init (&value, G_PARAM_SPEC_VALUE_TYPE (pspec)); area_get_cell_property (area, renderer, pspec, &value); G_VALUE_LCOPY (&value, var_args, 0, &error); if (error) - { - g_warning ("%s: %s", G_STRLOC, error); - g_free (error); - g_value_unset (&value); - break; - } + { + g_warning ("%s: %s", G_STRLOC, error); + g_free (error); + g_value_unset (&value); + break; + } g_value_unset (&value); name = va_arg (var_args, gchar*); } @@ -2532,9 +2765,9 @@ gtk_cell_area_cell_get_valist (GtkCellArea *area, */ void gtk_cell_area_cell_set_property (GtkCellArea *area, - GtkCellRenderer *renderer, - const gchar *property_name, - const GValue *value) + GtkCellRenderer *renderer, + const gchar *property_name, + const GValue *value) { GParamSpec *pspec; @@ -2542,15 +2775,15 @@ gtk_cell_area_cell_set_property (GtkCellArea *area, g_return_if_fail (GTK_IS_CELL_RENDERER (renderer)); g_return_if_fail (property_name != NULL); g_return_if_fail (G_IS_VALUE (value)); - + pspec = g_param_spec_pool_lookup (cell_property_pool, property_name, - G_OBJECT_TYPE (area), TRUE); + G_OBJECT_TYPE (area), TRUE); if (!pspec) g_warning ("%s: cell area class `%s' has no cell property named `%s'", - G_STRLOC, G_OBJECT_TYPE_NAME (area), property_name); + G_STRLOC, G_OBJECT_TYPE_NAME (area), property_name); else if (!(pspec->flags & G_PARAM_WRITABLE)) g_warning ("%s: cell property `%s' of cell area class `%s' is not writable", - G_STRLOC, pspec->name, G_OBJECT_TYPE_NAME (area)); + G_STRLOC, pspec->name, G_OBJECT_TYPE_NAME (area)); else { area_set_cell_property (area, renderer, pspec, value); @@ -2570,9 +2803,9 @@ gtk_cell_area_cell_set_property (GtkCellArea *area, */ void gtk_cell_area_cell_get_property (GtkCellArea *area, - GtkCellRenderer *renderer, - const gchar *property_name, - GValue *value) + GtkCellRenderer *renderer, + const gchar *property_name, + GValue *value) { GParamSpec *pspec; @@ -2580,47 +2813,47 @@ gtk_cell_area_cell_get_property (GtkCellArea *area, g_return_if_fail (GTK_IS_CELL_RENDERER (renderer)); g_return_if_fail (property_name != NULL); g_return_if_fail (G_IS_VALUE (value)); - + pspec = g_param_spec_pool_lookup (cell_property_pool, property_name, - G_OBJECT_TYPE (area), TRUE); + G_OBJECT_TYPE (area), TRUE); if (!pspec) g_warning ("%s: cell area class `%s' has no cell property named `%s'", - G_STRLOC, G_OBJECT_TYPE_NAME (area), property_name); + G_STRLOC, G_OBJECT_TYPE_NAME (area), property_name); else if (!(pspec->flags & G_PARAM_READABLE)) g_warning ("%s: cell property `%s' of cell area class `%s' is not readable", - G_STRLOC, pspec->name, G_OBJECT_TYPE_NAME (area)); + G_STRLOC, pspec->name, G_OBJECT_TYPE_NAME (area)); else { - GValue *prop_value, tmp_value = { 0, }; + GValue *prop_value, tmp_value = G_VALUE_INIT; /* auto-conversion of the callers value type */ if (G_VALUE_TYPE (value) == G_PARAM_SPEC_VALUE_TYPE (pspec)) - { - g_value_reset (value); - prop_value = value; - } + { + g_value_reset (value); + prop_value = value; + } else if (!g_value_type_transformable (G_PARAM_SPEC_VALUE_TYPE (pspec), G_VALUE_TYPE (value))) - { - g_warning ("can't retrieve cell property `%s' of type `%s' as value of type `%s'", - pspec->name, - g_type_name (G_PARAM_SPEC_VALUE_TYPE (pspec)), - G_VALUE_TYPE_NAME (value)); - return; - } + { + g_warning ("can't retrieve cell property `%s' of type `%s' as value of type `%s'", + pspec->name, + g_type_name (G_PARAM_SPEC_VALUE_TYPE (pspec)), + G_VALUE_TYPE_NAME (value)); + return; + } else - { - g_value_init (&tmp_value, G_PARAM_SPEC_VALUE_TYPE (pspec)); - prop_value = &tmp_value; - } + { + g_value_init (&tmp_value, G_PARAM_SPEC_VALUE_TYPE (pspec)); + prop_value = &tmp_value; + } area_get_cell_property (area, renderer, pspec, prop_value); if (prop_value != value) - { - g_value_transform (prop_value, value); - g_value_unset (&tmp_value); - } + { + g_value_transform (prop_value, value); + g_value_unset (&tmp_value); + } } } @@ -2657,7 +2890,7 @@ gtk_cell_area_is_activatable (GtkCellArea *area) * for a given @direction and row data. * * Implementing #GtkCellArea classes should implement this - * method to receive and navigate focus in it's own way particular + * method to receive and navigate focus in its own way particular * to how it lays out cells. * * Return value: %TRUE if focus remains inside @area as a result of this call. @@ -2666,21 +2899,11 @@ gtk_cell_area_is_activatable (GtkCellArea *area) */ gboolean gtk_cell_area_focus (GtkCellArea *area, - GtkDirectionType direction) + GtkDirectionType direction) { - GtkCellAreaClass *class; - g_return_val_if_fail (GTK_IS_CELL_AREA (area), FALSE); - class = GTK_CELL_AREA_GET_CLASS (area); - - if (class->focus) - return class->focus (area, direction); - - g_warning ("GtkCellAreaClass::focus not implemented for `%s'", - g_type_name (G_TYPE_FROM_INSTANCE (area))); - - return FALSE; + return GTK_CELL_AREA_GET_CLASS (area)->focus (area, direction); } /** @@ -2690,6 +2913,8 @@ gtk_cell_area_focus (GtkCellArea *area, * @widget: the #GtkWidget that @area is rendering on * @cell_area: the size and location of @area relative to @widget's allocation * @flags: the #GtkCellRendererState flags for @area for this row of data. + * @edit_only: if %TRUE then only cell renderers that are %GTK_CELL_RENDERER_MODE_EDITABLE + * will be activated. * * Activates @area, usually by activating the currently focused * cell, however some subclasses which embed widgets in the area @@ -2701,33 +2926,35 @@ gtk_cell_area_focus (GtkCellArea *area, */ gboolean gtk_cell_area_activate (GtkCellArea *area, - GtkCellAreaContext *context, - GtkWidget *widget, - const GdkRectangle *cell_area, - GtkCellRendererState flags) + GtkCellAreaContext *context, + GtkWidget *widget, + const GdkRectangle *cell_area, + GtkCellRendererState flags, + gboolean edit_only) { g_return_val_if_fail (GTK_IS_CELL_AREA (area), FALSE); - return GTK_CELL_AREA_GET_CLASS (area)->activate (area, context, widget, cell_area, flags); + return GTK_CELL_AREA_GET_CLASS (area)->activate (area, context, widget, cell_area, flags, edit_only); } /** * gtk_cell_area_set_focus_cell: * @area: a #GtkCellArea - * @focus_cell: the #GtkCellRenderer to give focus to + * @renderer: the #GtkCellRenderer to give focus to + * + * Explicitly sets the currently focused cell to @renderer. * - * This is generally called from #GtkCellArea implementations - * either gtk_cell_area_grab_focus() or gtk_cell_area_update_focus() - * is called. It's also up to the #GtkCellArea implementation - * to update the focused cell when receiving events from - * gtk_cell_area_event() appropriately. + * This is generally called by implementations of + * #GtkCellAreaClass.focus() or #GtkCellAreaClass.event(), + * however it can also be used to implement functions such + * as gtk_tree_view_set_cursor_on_cell(). * * Since: 3.0 */ void gtk_cell_area_set_focus_cell (GtkCellArea *area, - GtkCellRenderer *renderer) + GtkCellRenderer *renderer) { GtkCellAreaPrivate *priv; @@ -2739,12 +2966,12 @@ gtk_cell_area_set_focus_cell (GtkCellArea *area, if (priv->focus_cell != renderer) { if (priv->focus_cell) - g_object_unref (priv->focus_cell); + g_object_unref (priv->focus_cell); priv->focus_cell = renderer; if (priv->focus_cell) - g_object_ref (priv->focus_cell); + g_object_ref (priv->focus_cell); g_object_notify (G_OBJECT (area), "focus-cell"); } @@ -2752,8 +2979,8 @@ gtk_cell_area_set_focus_cell (GtkCellArea *area, /* Signal that the current focus renderer for this path changed * (it may be that the focus cell did not change, but the row * may have changed so we need to signal it) */ - g_signal_emit (area, cell_area_signals[SIGNAL_FOCUS_CHANGED], 0, - priv->focus_cell, priv->current_path); + g_signal_emit (area, cell_area_signals[SIGNAL_FOCUS_CHANGED], 0, + priv->focus_cell, priv->current_path); } @@ -2763,7 +2990,7 @@ gtk_cell_area_set_focus_cell (GtkCellArea *area, * * Retrieves the currently focused cell for @area * - * Return value: the currently focused cell in @area. + * Return value: (transfer none): the currently focused cell in @area. * * Since: 3.0 */ @@ -2791,7 +3018,7 @@ gtk_cell_area_get_focus_cell (GtkCellArea *area) * @sibling: the #GtkCellRenderer to add to @renderer's focus area * * Adds @sibling to @renderer's focusable area, focus will be drawn - * around @renderer and all of it's siblings if @renderer can + * around @renderer and all of its siblings if @renderer can * focus for a given row. * * Events handled by focus siblings can also activate the given @@ -2801,8 +3028,8 @@ gtk_cell_area_get_focus_cell (GtkCellArea *area) */ void gtk_cell_area_add_focus_sibling (GtkCellArea *area, - GtkCellRenderer *renderer, - GtkCellRenderer *sibling) + GtkCellRenderer *renderer, + GtkCellRenderer *sibling) { GtkCellAreaPrivate *priv; GList *siblings; @@ -2838,16 +3065,16 @@ gtk_cell_area_add_focus_sibling (GtkCellArea *area, * @area: a #GtkCellArea * @renderer: the #GtkCellRenderer expected to have focus * @sibling: the #GtkCellRenderer to remove from @renderer's focus area - * - * Removes @sibling from @renderer's focus sibling list + * + * Removes @sibling from @renderer's focus sibling list * (see gtk_cell_area_add_focus_sibling()). * * Since: 3.0 */ void gtk_cell_area_remove_focus_sibling (GtkCellArea *area, - GtkCellRenderer *renderer, - GtkCellRenderer *sibling) + GtkCellRenderer *renderer, + GtkCellRenderer *sibling) { GtkCellAreaPrivate *priv; GList *siblings; @@ -2875,16 +3102,18 @@ gtk_cell_area_remove_focus_sibling (GtkCellArea *area, * @area: a #GtkCellArea * @renderer: the #GtkCellRenderer expected to have focus * @sibling: the #GtkCellRenderer to check against @renderer's sibling list - * - * Returns %TRUE if @sibling is one of @renderer's focus siblings + * + * Returns whether @sibling is one of @renderer's focus siblings * (see gtk_cell_area_add_focus_sibling()). * + * Return value: %TRUE if @sibling is a focus sibling of @renderer + * * Since: 3.0 */ gboolean gtk_cell_area_is_focus_sibling (GtkCellArea *area, - GtkCellRenderer *renderer, - GtkCellRenderer *sibling) + GtkCellRenderer *renderer, + GtkCellRenderer *sibling) { GtkCellAreaPrivate *priv; GList *siblings, *l; @@ -2902,7 +3131,7 @@ gtk_cell_area_is_focus_sibling (GtkCellArea *area, GtkCellRenderer *a_sibling = l->data; if (a_sibling == sibling) - return TRUE; + return TRUE; } return FALSE; @@ -2915,14 +3144,14 @@ gtk_cell_area_is_focus_sibling (GtkCellArea *area, * * Gets the focus sibling cell renderers for @renderer. * - * Return value: (element-type GtkCellRenderer) (transfer none): A #GList of #GtkCellRenderers. + * Return value: (element-type GtkCellRenderer) (transfer none): A #GList of #GtkCellRenderers. * The returned list is internal and should not be freed. * * Since: 3.0 */ const GList * gtk_cell_area_get_focus_siblings (GtkCellArea *area, - GtkCellRenderer *renderer) + GtkCellRenderer *renderer) { GtkCellAreaPrivate *priv; @@ -2931,7 +3160,7 @@ gtk_cell_area_get_focus_siblings (GtkCellArea *area, priv = area->priv; - return g_hash_table_lookup (priv->focus_siblings, renderer); + return g_hash_table_lookup (priv->focus_siblings, renderer); } /** @@ -2947,13 +3176,14 @@ gtk_cell_area_get_focus_siblings (GtkCellArea *area, * then chose to activate the focus cell for which the event * cell may have been a sibling. * - * Return value: the #GtkCellRenderer for which @renderer is a sibling, or %NULL. + * Return value: (transfer none): the #GtkCellRenderer for which @renderer + * is a sibling, or %NULL. * * Since: 3.0 */ GtkCellRenderer * gtk_cell_area_get_focus_from_sibling (GtkCellArea *area, - GtkCellRenderer *renderer) + GtkCellRenderer *renderer) { GtkCellRenderer *ret_renderer = NULL; GList *renderers, *l; @@ -2968,17 +3198,17 @@ gtk_cell_area_get_focus_from_sibling (GtkCellArea *area, GtkCellRenderer *a_renderer = l->data; const GList *list; - for (list = gtk_cell_area_get_focus_siblings (area, a_renderer); - list; list = list->next) - { - GtkCellRenderer *sibling_renderer = list->data; - - if (sibling_renderer == renderer) - { - ret_renderer = a_renderer; - break; - } - } + for (list = gtk_cell_area_get_focus_siblings (area, a_renderer); + list; list = list->next) + { + GtkCellRenderer *sibling_renderer = list->data; + + if (sibling_renderer == renderer) + { + ret_renderer = a_renderer; + break; + } + } } g_list_free (renderers); @@ -2990,25 +3220,25 @@ gtk_cell_area_get_focus_from_sibling (GtkCellArea *area, *************************************************************/ static void gtk_cell_area_add_editable (GtkCellArea *area, - GtkCellRenderer *renderer, - GtkCellEditable *editable, - GdkRectangle *cell_area) + GtkCellRenderer *renderer, + GtkCellEditable *editable, + const GdkRectangle *cell_area) { - g_signal_emit (area, cell_area_signals[SIGNAL_ADD_EDITABLE], 0, - renderer, editable, cell_area, area->priv->current_path); + g_signal_emit (area, cell_area_signals[SIGNAL_ADD_EDITABLE], 0, + renderer, editable, cell_area, area->priv->current_path); } static void gtk_cell_area_remove_editable (GtkCellArea *area, - GtkCellRenderer *renderer, - GtkCellEditable *editable) + GtkCellRenderer *renderer, + GtkCellEditable *editable) { g_signal_emit (area, cell_area_signals[SIGNAL_REMOVE_EDITABLE], 0, renderer, editable); } static void cell_area_remove_widget_cb (GtkCellEditable *editable, - GtkCellArea *area) + GtkCellArea *area) { GtkCellAreaPrivate *priv = area->priv; @@ -3025,7 +3255,7 @@ cell_area_remove_widget_cb (GtkCellEditable *editable, static void gtk_cell_area_set_edited_cell (GtkCellArea *area, - GtkCellRenderer *renderer) + GtkCellRenderer *renderer) { GtkCellAreaPrivate *priv; @@ -3037,12 +3267,12 @@ gtk_cell_area_set_edited_cell (GtkCellArea *area, if (priv->edited_cell != renderer) { if (priv->edited_cell) - g_object_unref (priv->edited_cell); + g_object_unref (priv->edited_cell); priv->edited_cell = renderer; if (priv->edited_cell) - g_object_ref (priv->edited_cell); + g_object_ref (priv->edited_cell); g_object_notify (G_OBJECT (area), "edited-cell"); } @@ -3050,7 +3280,7 @@ gtk_cell_area_set_edited_cell (GtkCellArea *area, static void gtk_cell_area_set_edit_widget (GtkCellArea *area, - GtkCellEditable *editable) + GtkCellEditable *editable) { GtkCellAreaPrivate *priv; @@ -3062,22 +3292,22 @@ gtk_cell_area_set_edit_widget (GtkCellArea *area, if (priv->edit_widget != editable) { if (priv->edit_widget) - { - g_signal_handler_disconnect (priv->edit_widget, priv->remove_widget_id); + { + g_signal_handler_disconnect (priv->edit_widget, priv->remove_widget_id); - g_object_unref (priv->edit_widget); - } + g_object_unref (priv->edit_widget); + } priv->edit_widget = editable; if (priv->edit_widget) - { - priv->remove_widget_id = - g_signal_connect (priv->edit_widget, "remove-widget", - G_CALLBACK (cell_area_remove_widget_cb), area); + { + priv->remove_widget_id = + g_signal_connect (priv->edit_widget, "remove-widget", + G_CALLBACK (cell_area_remove_widget_cb), area); - g_object_ref (priv->edit_widget); - } + g_object_ref (priv->edit_widget); + } g_object_notify (G_OBJECT (area), "edit-widget"); } @@ -3090,7 +3320,7 @@ gtk_cell_area_set_edit_widget (GtkCellArea *area, * Gets the #GtkCellRenderer in @area that is currently * being edited. * - * Return value: The currently edited #GtkCellRenderer + * Return value: (transfer none): The currently edited #GtkCellRenderer * * Since: 3.0 */ @@ -3113,7 +3343,7 @@ gtk_cell_area_get_edited_cell (GtkCellArea *area) * Gets the #GtkCellEditable widget currently used * to edit the currently edited cell. * - * Return value: The currently active #GtkCellEditable widget + * Return value: (transfer none): The currently active #GtkCellEditable widget * * Since: 3.0 */ @@ -3141,7 +3371,7 @@ gtk_cell_area_get_edit_widget (GtkCellArea *area) * * This is used by #GtkCellArea subclasses when handling events * to activate cells, the base #GtkCellArea class activates cells - * for keyboard events for free in it's own GtkCellArea->activate() + * for keyboard events for free in its own GtkCellArea->activate() * implementation. * * Return value: whether cell activation was successful @@ -3150,16 +3380,15 @@ gtk_cell_area_get_edit_widget (GtkCellArea *area) */ gboolean gtk_cell_area_activate_cell (GtkCellArea *area, - GtkWidget *widget, - GtkCellRenderer *renderer, - GdkEvent *event, - const GdkRectangle *cell_area, - GtkCellRendererState flags) + GtkWidget *widget, + GtkCellRenderer *renderer, + GdkEvent *event, + const GdkRectangle *cell_area, + GtkCellRendererState flags) { GtkCellRendererMode mode; - GdkRectangle inner_area; GtkCellAreaPrivate *priv; - + g_return_val_if_fail (GTK_IS_CELL_AREA (area), FALSE); g_return_val_if_fail (GTK_IS_WIDGET (widget), FALSE); g_return_val_if_fail (GTK_IS_CELL_RENDERER (renderer), FALSE); @@ -3167,62 +3396,64 @@ gtk_cell_area_activate_cell (GtkCellArea *area, priv = area->priv; - /* Remove margins from the background area to produce the cell area. - */ - gtk_cell_area_inner_cell_area (area, widget, cell_area, &inner_area); + if (!gtk_cell_renderer_get_sensitive (renderer)) + return FALSE; g_object_get (renderer, "mode", &mode, NULL); if (mode == GTK_CELL_RENDERER_MODE_ACTIVATABLE) { if (gtk_cell_renderer_activate (renderer, - event, widget, - priv->current_path, - cell_area, - &inner_area, - flags)) - return TRUE; + event, widget, + priv->current_path, + cell_area, + cell_area, + flags)) + return TRUE; } else if (mode == GTK_CELL_RENDERER_MODE_EDITABLE) { GtkCellEditable *editable_widget; - + GdkRectangle inner_area; + + gtk_cell_area_inner_cell_area (area, widget, cell_area, &inner_area); + editable_widget = - gtk_cell_renderer_start_editing (renderer, - event, widget, - priv->current_path, - cell_area, - &inner_area, - flags); - + gtk_cell_renderer_start_editing (renderer, + event, widget, + priv->current_path, + &inner_area, + &inner_area, + flags); + if (editable_widget != NULL) - { - g_return_val_if_fail (GTK_IS_CELL_EDITABLE (editable_widget), FALSE); - - gtk_cell_area_set_edited_cell (area, renderer); - gtk_cell_area_set_edit_widget (area, editable_widget); - - /* Signal that editing started so that callers can get - * a handle on the editable_widget */ - gtk_cell_area_add_editable (area, priv->focus_cell, editable_widget, &inner_area); - - /* If the signal was successfully handled start the editing */ - if (gtk_widget_get_parent (GTK_WIDGET (editable_widget))) - { - gtk_cell_editable_start_editing (editable_widget, NULL); - gtk_widget_grab_focus (GTK_WIDGET (editable_widget)); - } - else - { - /* Otherwise clear the editing state and fire a warning */ - gtk_cell_area_set_edited_cell (area, NULL); - gtk_cell_area_set_edit_widget (area, NULL); - - g_warning ("GtkCellArea::add-editable fired in the dark, no cell editing was started."); - } - - return TRUE; - } + { + g_return_val_if_fail (GTK_IS_CELL_EDITABLE (editable_widget), FALSE); + + gtk_cell_area_set_edited_cell (area, renderer); + gtk_cell_area_set_edit_widget (area, editable_widget); + + /* Signal that editing started so that callers can get + * a handle on the editable_widget */ + gtk_cell_area_add_editable (area, priv->focus_cell, editable_widget, cell_area); + + /* If the signal was successfully handled start the editing */ + if (gtk_widget_get_parent (GTK_WIDGET (editable_widget))) + { + gtk_cell_editable_start_editing (editable_widget, NULL); + gtk_widget_grab_focus (GTK_WIDGET (editable_widget)); + } + else + { + /* Otherwise clear the editing state and fire a warning */ + gtk_cell_area_set_edited_cell (area, NULL); + gtk_cell_area_set_edit_widget (area, NULL); + + g_warning ("GtkCellArea::add-editable fired in the dark, no cell editing was started."); + } + + return TRUE; + } } return FALSE; @@ -3233,17 +3464,20 @@ gtk_cell_area_activate_cell (GtkCellArea *area, * @area: a #GtkCellArea * @canceled: whether editing was canceled. * - * Explicitly stops the editing of the currently - * edited cell (see gtk_cell_area_get_edited_cell()). + * Explicitly stops the editing of the currently edited cell. + * + * If @canceled is %TRUE, the currently edited cell renderer + * will emit the ::editing-canceled signal, otherwise the + * the ::editing-done signal will be emitted on the current + * edit widget. * - * If @canceled is %TRUE, the cell renderer will emit - * the ::editing-canceled signal. + * See gtk_cell_area_get_edited_cell() and gtk_cell_area_get_edit_widget(). * * Since: 3.0 */ void gtk_cell_area_stop_editing (GtkCellArea *area, - gboolean canceled) + gboolean canceled) { GtkCellAreaPrivate *priv; @@ -3258,7 +3492,14 @@ gtk_cell_area_stop_editing (GtkCellArea *area, /* Stop editing of the cell renderer */ gtk_cell_renderer_stop_editing (priv->edited_cell, canceled); - + + /* When editing is explicitly halted either + * the "editing-canceled" signal is emitted on the cell + * renderer or the "editing-done" signal on the GtkCellEditable widget + */ + if (!canceled) + gtk_cell_editable_editing_done (edit_widget); + /* Remove any references to the editable widget */ gtk_cell_area_set_edited_cell (area, NULL); gtk_cell_area_set_edit_widget (area, NULL); @@ -3280,7 +3521,7 @@ gtk_cell_area_stop_editing (GtkCellArea *area, * gtk_cell_area_inner_cell_area: * @area: a #GtkCellArea * @widget: the #GtkWidget that @area is rendering onto - * @cell_area: the @widget relative coordinates where one of @area's cells + * @cell_area: the @widget relative coordinates where one of @area's cells * is to be placed * @inner_area: (out): the return location for the inner cell area * @@ -3292,9 +3533,9 @@ gtk_cell_area_stop_editing (GtkCellArea *area, */ void gtk_cell_area_inner_cell_area (GtkCellArea *area, - GtkWidget *widget, - const GdkRectangle *cell_area, - GdkRectangle *inner_area) + GtkWidget *widget, + const GdkRectangle *cell_area, + GdkRectangle *inner_area) { gint focus_line_width; @@ -3334,15 +3575,14 @@ gtk_cell_area_inner_cell_area (GtkCellArea *area, */ void gtk_cell_area_request_renderer (GtkCellArea *area, - GtkCellRenderer *renderer, - GtkOrientation orientation, - GtkWidget *widget, - gint for_size, - gint *minimum_size, - gint *natural_size) + GtkCellRenderer *renderer, + GtkOrientation orientation, + GtkWidget *widget, + gint for_size, + gint *minimum_size, + gint *natural_size) { - GtkCellAreaPrivate *priv; - gint focus_line_width; + gint focus_line_width; g_return_if_fail (GTK_IS_CELL_AREA (area)); g_return_if_fail (GTK_IS_CELL_RENDERER (renderer)); @@ -3350,8 +3590,6 @@ gtk_cell_area_request_renderer (GtkCellArea *area, g_return_if_fail (minimum_size != NULL); g_return_if_fail (natural_size != NULL); - priv = area->priv; - gtk_widget_style_get (widget, "focus-line-width", &focus_line_width, NULL); focus_line_width *= 2; @@ -3359,28 +3597,79 @@ gtk_cell_area_request_renderer (GtkCellArea *area, if (orientation == GTK_ORIENTATION_HORIZONTAL) { if (for_size < 0) - gtk_cell_renderer_get_preferred_width (renderer, widget, minimum_size, natural_size); + gtk_cell_renderer_get_preferred_width (renderer, widget, minimum_size, natural_size); else - { - for_size = MAX (0, for_size - focus_line_width); + { + for_size = MAX (0, for_size - focus_line_width); - gtk_cell_renderer_get_preferred_width_for_height (renderer, widget, for_size, - minimum_size, natural_size); - } + gtk_cell_renderer_get_preferred_width_for_height (renderer, widget, for_size, + minimum_size, natural_size); + } } else /* GTK_ORIENTATION_VERTICAL */ { if (for_size < 0) - gtk_cell_renderer_get_preferred_height (renderer, widget, minimum_size, natural_size); + gtk_cell_renderer_get_preferred_height (renderer, widget, minimum_size, natural_size); else - { - for_size = MAX (0, for_size - focus_line_width); + { + for_size = MAX (0, for_size - focus_line_width); - gtk_cell_renderer_get_preferred_height_for_width (renderer, widget, for_size, - minimum_size, natural_size); - } + gtk_cell_renderer_get_preferred_height_for_width (renderer, widget, for_size, + minimum_size, natural_size); + } } *minimum_size += focus_line_width; *natural_size += focus_line_width; } + +void +_gtk_cell_area_set_cell_data_func_with_proxy (GtkCellArea *area, + GtkCellRenderer *cell, + GFunc func, + gpointer func_data, + GDestroyNotify destroy, + gpointer proxy) +{ + GtkCellAreaPrivate *priv; + CellInfo *info; + + g_return_if_fail (GTK_IS_CELL_AREA (area)); + g_return_if_fail (GTK_IS_CELL_RENDERER (cell)); + + priv = area->priv; + + info = g_hash_table_lookup (priv->cell_info, cell); + + /* Note we do not take a reference to the proxy, the proxy is a GtkCellLayout + * that is forwarding its implementation to a delegate GtkCellArea therefore + * its life-cycle is longer than the area's life cycle. + */ + if (info) + { + if (info->destroy && info->data) + info->destroy (info->data); + + if (func) + { + info->func = (GtkCellLayoutDataFunc)func; + info->data = func_data; + info->destroy = destroy; + info->proxy = proxy; + } + else + { + info->func = NULL; + info->data = NULL; + info->destroy = NULL; + info->proxy = NULL; + } + } + else + { + info = cell_info_new ((GtkCellLayoutDataFunc)func, func_data, destroy); + info->proxy = proxy; + + g_hash_table_insert (priv->cell_info, cell, info); + } +}