1 /* gtkcellareacontext.c
3 * Copyright (C) 2010 Openismus GmbH
6 * Tristan Van Berkom <tristanvb@openismus.com>
8 * This library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Library General Public
10 * License as published by the Free Software Foundation; either
11 * version 2 of the License, or (at your option) any later version.
13 * This library is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Library General Public License for more details.
18 * You should have received a copy of the GNU Library General Public
19 * License along with this library; if not, write to the
20 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
21 * Boston, MA 02111-1307, USA.
25 * SECTION:gtkcellareacontext
26 * @Short_Description: An object for a #GtkCellArea to store geometrical information for a series of rows.
27 * @Title: GtkCellAreaContext
29 * The #GtkCellAreaContext object is created by a given #GtkCellArea implementation via it's
30 * #GtkCellAreaClass.create_context() virtual method and is used to store cell sizes and alignments
31 * for a series of #GtkTreeModel rows that are requested and rendered in the same context.
33 * #GtkCellLayout widgets can create any number of contexts in which to request and render
34 * groups of data rows. However its important that the same context which was used to
35 * request sizes for a given #GtkTreeModel row also be used for the same row when calling
36 * other #GtkCellArea apis such as gtk_cell_area_render() and gtk_cell_area_event().
40 #include "gtkmarshalers.h"
41 #include "gtkcellareacontext.h"
42 #include "gtkprivate.h"
45 static void gtk_cell_area_context_dispose (GObject *object);
46 static void gtk_cell_area_context_get_property (GObject *object,
50 static void gtk_cell_area_context_set_property (GObject *object,
55 /* GtkCellAreaContextClass */
56 static void gtk_cell_area_context_real_reset (GtkCellAreaContext *context);
57 static void gtk_cell_area_context_real_allocate (GtkCellAreaContext *context,
61 struct _GtkCellAreaContextPrivate
63 GtkCellArea *cell_area;
82 G_DEFINE_TYPE (GtkCellAreaContext, gtk_cell_area_context, G_TYPE_OBJECT);
85 gtk_cell_area_context_init (GtkCellAreaContext *context)
87 GtkCellAreaContextPrivate *priv;
89 context->priv = G_TYPE_INSTANCE_GET_PRIVATE (context,
90 GTK_TYPE_CELL_AREA_CONTEXT,
91 GtkCellAreaContextPrivate);
96 priv->min_height = -1;
97 priv->nat_height = -1;
101 gtk_cell_area_context_class_init (GtkCellAreaContextClass *class)
103 GObjectClass *object_class = G_OBJECT_CLASS (class);
106 object_class->dispose = gtk_cell_area_context_dispose;
107 object_class->get_property = gtk_cell_area_context_get_property;
108 object_class->set_property = gtk_cell_area_context_set_property;
110 /* GtkCellAreaContextClass */
111 class->reset = gtk_cell_area_context_real_reset;
112 class->allocate = gtk_cell_area_context_real_allocate;
115 * GtkCellAreaContext:area:
117 * The #GtkCellArea this context was created by
121 g_object_class_install_property (object_class,
123 g_param_spec_object ("area",
125 P_("The Cell Area this context was created for"),
127 GTK_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
130 * GtkCellAreaContext:minimum-width:
132 * The minimum width for the #GtkCellArea in this context
133 * for all #GtkTreeModel rows that this context was requested
134 * for using gtk_cell_area_get_preferred_width().
138 g_object_class_install_property (object_class,
140 g_param_spec_int ("minimum-width",
142 P_("Minimum cached width"),
149 * GtkCellAreaContext:natural-width:
151 * The natural width for the #GtkCellArea in this context
152 * for all #GtkTreeModel rows that this context was requested
153 * for using gtk_cell_area_get_preferred_width().
157 g_object_class_install_property (object_class,
159 g_param_spec_int ("natural-width",
161 P_("Minimum cached width"),
168 * GtkCellAreaContext:minimum-height:
170 * The minimum height for the #GtkCellArea in this context
171 * for all #GtkTreeModel rows that this context was requested
172 * for using gtk_cell_area_get_preferred_height().
176 g_object_class_install_property (object_class,
178 g_param_spec_int ("minimum-height",
179 P_("Minimum Height"),
180 P_("Minimum cached height"),
187 * GtkCellAreaContext:natural-height:
189 * The natural height for the #GtkCellArea in this context
190 * for all #GtkTreeModel rows that this context was requested
191 * for using gtk_cell_area_get_preferred_height().
195 g_object_class_install_property (object_class,
197 g_param_spec_int ("natural-height",
198 P_("Minimum Height"),
199 P_("Minimum cached height"),
205 g_type_class_add_private (object_class, sizeof (GtkCellAreaContextPrivate));
208 /*************************************************************
210 *************************************************************/
212 gtk_cell_area_context_dispose (GObject *object)
214 GtkCellAreaContext *context = GTK_CELL_AREA_CONTEXT (object);
215 GtkCellAreaContextPrivate *priv = context->priv;
219 g_object_unref (priv->cell_area);
221 priv->cell_area = NULL;
224 G_OBJECT_CLASS (gtk_cell_area_context_parent_class)->dispose (object);
228 gtk_cell_area_context_set_property (GObject *object,
233 GtkCellAreaContext *context = GTK_CELL_AREA_CONTEXT (object);
234 GtkCellAreaContextPrivate *priv = context->priv;
239 priv->cell_area = g_value_dup_object (value);
242 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
248 gtk_cell_area_context_get_property (GObject *object,
253 GtkCellAreaContext *context = GTK_CELL_AREA_CONTEXT (object);
254 GtkCellAreaContextPrivate *priv = context->priv;
259 g_value_set_object (value, priv->cell_area);
262 g_value_set_int (value, priv->min_width);
265 g_value_set_int (value, priv->nat_width);
267 case PROP_MIN_HEIGHT:
268 g_value_set_int (value, priv->min_height);
270 case PROP_NAT_HEIGHT:
271 g_value_set_int (value, priv->nat_height);
274 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
279 /*************************************************************
280 * GtkCellAreaContextClass *
281 *************************************************************/
283 gtk_cell_area_context_real_reset (GtkCellAreaContext *context)
285 GtkCellAreaContextPrivate *priv = context->priv;
287 priv->min_width = -1;
288 priv->nat_width = -1;
289 priv->min_height = -1;
290 priv->nat_height = -1;
291 priv->alloc_width = 0;
292 priv->alloc_height = 0;
294 g_object_freeze_notify (G_OBJECT (context));
295 g_object_notify (G_OBJECT (context), "minimum-width");
296 g_object_notify (G_OBJECT (context), "natural-width");
297 g_object_notify (G_OBJECT (context), "minimum-height");
298 g_object_notify (G_OBJECT (context), "natural-height");
299 g_object_thaw_notify (G_OBJECT (context));
303 gtk_cell_area_context_real_allocate (GtkCellAreaContext *context,
307 GtkCellAreaContextPrivate *priv = context->priv;
309 priv->alloc_width = width;
310 priv->alloc_height = height;
313 /*************************************************************
315 *************************************************************/
317 * gtk_cell_area_context_get_area:
318 * @context: a #GtkCellAreaContext
320 * Fetches the #GtkCellArea this @context was created by.
322 * This is generally unneeded by layouting widgets however
323 * its important for the context implementation itself to
324 * fetch information about the area it is being used for.
326 * For instance at #GtkCellAreaContextClass.allocate() time
327 * it's important to know details about any cell spacing
328 * that the #GtkCellArea is configured with in order to
329 * compute a proper allocation.
331 * Return value: the #GtkCellArea this context was created by.
336 gtk_cell_area_context_get_area (GtkCellAreaContext *context)
338 GtkCellAreaContextPrivate *priv;
340 g_return_val_if_fail (GTK_IS_CELL_AREA_CONTEXT (context), NULL);
342 priv = context->priv;
344 return priv->cell_area;
348 * gtk_cell_area_context_reset:
349 * @context: a #GtkCellAreaContext
351 * Resets any previously cached request and allocation
354 * When underlying #GtkTreeModel data changes it's
355 * important to reset the context if the content
356 * size is allowed to shrink. If the content size
357 * is only allowed to grow (this is usually an option
358 * for views rendering large data stores as a measure
359 * of optimization), then only the row that changed
360 * or was inserted needs to be (re)requested with
361 * gtk_cell_area_get_preferred_width().
363 * When the new overall size of the context requires
364 * that the allocated size changes (or whenever this
365 * allocation changes at all), the variable row
366 * sizes need to be re-requested for every row.
368 * For instance, if the rows are displayed all with
369 * the same width from top to bottom then a change
370 * in the allocated width necessitates a recalculation
371 * of all the displayed row heights using
372 * gtk_cell_area_get_preferred_height_for_width().
377 gtk_cell_area_context_reset (GtkCellAreaContext *context)
379 g_return_if_fail (GTK_IS_CELL_AREA_CONTEXT (context));
381 GTK_CELL_AREA_CONTEXT_GET_CLASS (context)->reset (context);
385 * gtk_cell_area_context_allocate:
386 * @context: a #GtkCellAreaContext
387 * @width: the allocated width for all #GtkTreeModel rows rendered with @context, or -1.
388 * @height: the allocated height for all #GtkTreeModel rows rendered with @context, or -1.
390 * Allocates a width and/or a height for all rows which are to be rendered with @context.
392 * Usually allocation is performed only horizontally or sometimes vertically since
393 * a group of rows are usually rendered side by side vertically or horizontally and
394 * share either the same width or the same hieght. Sometimes they are allocated in
395 * both horizontal and vertical orientations producing a homogenious effect of the
396 * rows. This is generally the case for #GtkTreeView when #GtkTreeView:fixed-height-mode
402 gtk_cell_area_context_allocate (GtkCellAreaContext *context,
406 g_return_if_fail (GTK_IS_CELL_AREA_CONTEXT (context));
408 GTK_CELL_AREA_CONTEXT_GET_CLASS (context)->allocate (context, width, height);
412 * gtk_cell_area_context_get_preferred_width:
413 * @context: a #GtkCellAreaContext
414 * @minimum_width: (out) (allow-none): location to store the minimum width, or %NULL
415 * @natural_width: (out) (allow-none): location to store the natural width, or %NULL
417 * Gets the accumulative preferred width for all rows which have been requested
420 * After gtk_cell_area_context_reset() is called and/or before ever requesting
421 * the size of a #GtkCellArea, the returned values are -1.
426 gtk_cell_area_context_get_preferred_width (GtkCellAreaContext *context,
430 GtkCellAreaContextPrivate *priv;
432 g_return_if_fail (GTK_IS_CELL_AREA_CONTEXT (context));
434 priv = context->priv;
437 *minimum_width = priv->min_width;
440 *natural_width = priv->nat_width;
444 * gtk_cell_area_context_get_preferred_height:
445 * @context: a #GtkCellAreaContext
446 * @minimum_height: (out) (allow-none): location to store the minimum height, or %NULL
447 * @natural_height: (out) (allow-none): location to store the natural height, or %NULL
449 * Gets the accumulative preferred height for all rows which have been requested
452 * After gtk_cell_area_context_reset() is called and/or before ever requesting
453 * the size of a #GtkCellArea, the returned values are -1.
458 gtk_cell_area_context_get_preferred_height (GtkCellAreaContext *context,
459 gint *minimum_height,
460 gint *natural_height)
462 GtkCellAreaContextPrivate *priv;
464 g_return_if_fail (GTK_IS_CELL_AREA_CONTEXT (context));
466 priv = context->priv;
469 *minimum_height = priv->min_height;
472 *natural_height = priv->nat_height;
476 * gtk_cell_area_context_get_allocation:
477 * @context: a #GtkCellAreaContext
478 * @width: (out) (allow-none): location to store the allocated width, or %NULL.
479 * @height: (out) (allow-none): location to store the allocated height, or %NULL.
481 * Fetches the current allocation size for @context.
483 * If the context was not allocated in width or height, or if the
484 * context was recently reset with gtk_cell_area_context_reset(),
485 * the returned value will be -1.
490 gtk_cell_area_context_get_allocation (GtkCellAreaContext *context,
494 GtkCellAreaContextPrivate *priv;
496 g_return_if_fail (GTK_IS_CELL_AREA_CONTEXT (context));
498 priv = context->priv;
501 *width = priv->alloc_width;
504 *height = priv->alloc_height;
508 * gtk_cell_area_context_push_preferred_width:
509 * @context: a #GtkCellAreaContext
510 * @minimum_width: the proposed new minimum width for @context.
511 * @natural_width: the proposed new natural width for @context.
513 * Causes the minimum and/or natural width to grow if the new
514 * proposed sizes exceed the current minimum and natural width.
516 * This is used by #GtkCellAreaContext implementations during
517 * the request process over a series of #GtkTreeModel rows to
518 * progressively push the requested width over a series of
519 * gtk_cell_area_get_preferred_width() requests.
524 gtk_cell_area_context_push_preferred_width (GtkCellAreaContext *context,
528 GtkCellAreaContextPrivate *priv;
530 g_return_if_fail (GTK_IS_CELL_AREA_CONTEXT (context));
532 priv = context->priv;
534 g_object_freeze_notify (G_OBJECT (context));
536 if (minimum_width > priv->min_width)
538 priv->min_width = minimum_width;
540 g_object_notify (G_OBJECT (context), "minimum-width");
543 if (natural_width > priv->nat_width)
545 priv->nat_width = natural_width;
547 g_object_notify (G_OBJECT (context), "natural-width");
550 g_object_thaw_notify (G_OBJECT (context));
554 * gtk_cell_area_context_push_preferred_height:
555 * @context: a #GtkCellAreaContext
556 * @minimum_height: the proposed new minimum height for @context.
557 * @natural_height: the proposed new natural height for @context.
559 * Causes the minimum and/or natural height to grow if the new
560 * proposed sizes exceed the current minimum and natural height.
562 * This is used by #GtkCellAreaContext implementations during
563 * the request process over a series of #GtkTreeModel rows to
564 * progressively push the requested height over a series of
565 * gtk_cell_area_get_preferred_height() requests.
570 gtk_cell_area_context_push_preferred_height (GtkCellAreaContext *context,
574 GtkCellAreaContextPrivate *priv;
576 g_return_if_fail (GTK_IS_CELL_AREA_CONTEXT (context));
578 priv = context->priv;
580 g_object_freeze_notify (G_OBJECT (context));
582 if (minimum_height > priv->min_height)
584 priv->min_height = minimum_height;
586 g_object_notify (G_OBJECT (context), "minimum-height");
589 if (natural_height > priv->nat_height)
591 priv->nat_height = natural_height;
593 g_object_notify (G_OBJECT (context), "natural-height");
596 g_object_thaw_notify (G_OBJECT (context));