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: Stores geometrical information for a series of rows in a GtkCellArea
27 * @Title: GtkCellAreaContext
29 * The #GtkCellAreaContext object is created by a given #GtkCellArea
30 * implementation via its #GtkCellAreaClass.create_context() virtual
31 * method and is used to store cell sizes and alignments for a series of
32 * #GtkTreeModel rows that are requested and rendered in the same context.
34 * #GtkCellLayout widgets can create any number of contexts in which to
35 * request and render groups of data rows. However its important that the
36 * same context which was used to request sizes for a given #GtkTreeModel
37 * row also be used for the same row when calling other #GtkCellArea APIs
38 * such as gtk_cell_area_render() and gtk_cell_area_event().
43 #include "gtkmarshalers.h"
44 #include "gtkcellareacontext.h"
45 #include "gtkprivate.h"
48 static void gtk_cell_area_context_dispose (GObject *object);
49 static void gtk_cell_area_context_get_property (GObject *object,
53 static void gtk_cell_area_context_set_property (GObject *object,
58 /* GtkCellAreaContextClass */
59 static void gtk_cell_area_context_real_reset (GtkCellAreaContext *context);
60 static void gtk_cell_area_context_real_allocate (GtkCellAreaContext *context,
64 struct _GtkCellAreaContextPrivate
66 GtkCellArea *cell_area;
85 G_DEFINE_TYPE (GtkCellAreaContext, gtk_cell_area_context, G_TYPE_OBJECT);
88 gtk_cell_area_context_init (GtkCellAreaContext *context)
90 GtkCellAreaContextPrivate *priv;
92 context->priv = G_TYPE_INSTANCE_GET_PRIVATE (context,
93 GTK_TYPE_CELL_AREA_CONTEXT,
94 GtkCellAreaContextPrivate);
99 priv->min_height = -1;
100 priv->nat_height = -1;
104 gtk_cell_area_context_class_init (GtkCellAreaContextClass *class)
106 GObjectClass *object_class = G_OBJECT_CLASS (class);
109 object_class->dispose = gtk_cell_area_context_dispose;
110 object_class->get_property = gtk_cell_area_context_get_property;
111 object_class->set_property = gtk_cell_area_context_set_property;
113 /* GtkCellAreaContextClass */
114 class->reset = gtk_cell_area_context_real_reset;
115 class->allocate = gtk_cell_area_context_real_allocate;
118 * GtkCellAreaContext:area:
120 * The #GtkCellArea this context was created by
124 g_object_class_install_property (object_class,
126 g_param_spec_object ("area",
128 P_("The Cell Area this context was created for"),
130 GTK_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
133 * GtkCellAreaContext:minimum-width:
135 * The minimum width for the #GtkCellArea in this context
136 * for all #GtkTreeModel rows that this context was requested
137 * for using gtk_cell_area_get_preferred_width().
141 g_object_class_install_property (object_class,
143 g_param_spec_int ("minimum-width",
145 P_("Minimum cached width"),
152 * GtkCellAreaContext:natural-width:
154 * The natural width for the #GtkCellArea in this context
155 * for all #GtkTreeModel rows that this context was requested
156 * for using gtk_cell_area_get_preferred_width().
160 g_object_class_install_property (object_class,
162 g_param_spec_int ("natural-width",
164 P_("Minimum cached width"),
171 * GtkCellAreaContext:minimum-height:
173 * The minimum height for the #GtkCellArea in this context
174 * for all #GtkTreeModel rows that this context was requested
175 * for using gtk_cell_area_get_preferred_height().
179 g_object_class_install_property (object_class,
181 g_param_spec_int ("minimum-height",
182 P_("Minimum Height"),
183 P_("Minimum cached height"),
190 * GtkCellAreaContext:natural-height:
192 * The natural height for the #GtkCellArea in this context
193 * for all #GtkTreeModel rows that this context was requested
194 * for using gtk_cell_area_get_preferred_height().
198 g_object_class_install_property (object_class,
200 g_param_spec_int ("natural-height",
201 P_("Minimum Height"),
202 P_("Minimum cached height"),
208 g_type_class_add_private (object_class, sizeof (GtkCellAreaContextPrivate));
211 /*************************************************************
213 *************************************************************/
215 gtk_cell_area_context_dispose (GObject *object)
217 GtkCellAreaContext *context = GTK_CELL_AREA_CONTEXT (object);
218 GtkCellAreaContextPrivate *priv = context->priv;
222 g_object_unref (priv->cell_area);
224 priv->cell_area = NULL;
227 G_OBJECT_CLASS (gtk_cell_area_context_parent_class)->dispose (object);
231 gtk_cell_area_context_set_property (GObject *object,
236 GtkCellAreaContext *context = GTK_CELL_AREA_CONTEXT (object);
237 GtkCellAreaContextPrivate *priv = context->priv;
242 priv->cell_area = g_value_dup_object (value);
245 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
251 gtk_cell_area_context_get_property (GObject *object,
256 GtkCellAreaContext *context = GTK_CELL_AREA_CONTEXT (object);
257 GtkCellAreaContextPrivate *priv = context->priv;
262 g_value_set_object (value, priv->cell_area);
265 g_value_set_int (value, priv->min_width);
268 g_value_set_int (value, priv->nat_width);
270 case PROP_MIN_HEIGHT:
271 g_value_set_int (value, priv->min_height);
273 case PROP_NAT_HEIGHT:
274 g_value_set_int (value, priv->nat_height);
277 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
282 /*************************************************************
283 * GtkCellAreaContextClass *
284 *************************************************************/
286 gtk_cell_area_context_real_reset (GtkCellAreaContext *context)
288 GtkCellAreaContextPrivate *priv = context->priv;
290 g_object_freeze_notify (G_OBJECT (context));
292 if (priv->min_width != -1)
294 priv->min_width = -1;
295 g_object_notify (G_OBJECT (context), "minimum-width");
298 if (priv->nat_width != -1)
300 priv->nat_width = -1;
301 g_object_notify (G_OBJECT (context), "natural-width");
304 if (priv->min_height != -1)
306 priv->min_height = -1;
307 g_object_notify (G_OBJECT (context), "minimum-height");
310 if (priv->nat_height != -1)
312 priv->nat_height = -1;
313 g_object_notify (G_OBJECT (context), "natural-height");
316 priv->alloc_width = 0;
317 priv->alloc_height = 0;
319 g_object_thaw_notify (G_OBJECT (context));
323 gtk_cell_area_context_real_allocate (GtkCellAreaContext *context,
327 GtkCellAreaContextPrivate *priv = context->priv;
329 priv->alloc_width = width;
330 priv->alloc_height = height;
333 /*************************************************************
335 *************************************************************/
337 * gtk_cell_area_context_get_area:
338 * @context: a #GtkCellAreaContext
340 * Fetches the #GtkCellArea this @context was created by.
342 * This is generally unneeded by layouting widgets; however
343 * it is important for the context implementation itself to
344 * fetch information about the area it is being used for.
346 * For instance at #GtkCellAreaContextClass.allocate() time
347 * its important to know details about any cell spacing
348 * that the #GtkCellArea is configured with in order to
349 * compute a proper allocation.
351 * Return value: (transfer none): the #GtkCellArea this context was created by.
356 gtk_cell_area_context_get_area (GtkCellAreaContext *context)
358 GtkCellAreaContextPrivate *priv;
360 g_return_val_if_fail (GTK_IS_CELL_AREA_CONTEXT (context), NULL);
362 priv = context->priv;
364 return priv->cell_area;
368 * gtk_cell_area_context_reset:
369 * @context: a #GtkCellAreaContext
371 * Resets any previously cached request and allocation
374 * When underlying #GtkTreeModel data changes its
375 * important to reset the context if the content
376 * size is allowed to shrink. If the content size
377 * is only allowed to grow (this is usually an option
378 * for views rendering large data stores as a measure
379 * of optimization), then only the row that changed
380 * or was inserted needs to be (re)requested with
381 * gtk_cell_area_get_preferred_width().
383 * When the new overall size of the context requires
384 * that the allocated size changes (or whenever this
385 * allocation changes at all), the variable row
386 * sizes need to be re-requested for every row.
388 * For instance, if the rows are displayed all with
389 * the same width from top to bottom then a change
390 * in the allocated width necessitates a recalculation
391 * of all the displayed row heights using
392 * gtk_cell_area_get_preferred_height_for_width().
397 gtk_cell_area_context_reset (GtkCellAreaContext *context)
399 g_return_if_fail (GTK_IS_CELL_AREA_CONTEXT (context));
401 GTK_CELL_AREA_CONTEXT_GET_CLASS (context)->reset (context);
405 * gtk_cell_area_context_allocate:
406 * @context: a #GtkCellAreaContext
407 * @width: the allocated width for all #GtkTreeModel rows rendered
408 * with @context, or -1.
409 * @height: the allocated height for all #GtkTreeModel rows rendered
410 * with @context, or -1.
412 * Allocates a width and/or a height for all rows which are to be
413 * rendered with @context.
415 * Usually allocation is performed only horizontally or sometimes
416 * vertically since a group of rows are usually rendered side by
417 * side vertically or horizontally and share either the same width
418 * or the same height. Sometimes they are allocated in both horizontal
419 * and vertical orientations producing a homogeneous effect of the
420 * rows. This is generally the case for #GtkTreeView when
421 * #GtkTreeView:fixed-height-mode is enabled.
426 gtk_cell_area_context_allocate (GtkCellAreaContext *context,
430 g_return_if_fail (GTK_IS_CELL_AREA_CONTEXT (context));
432 GTK_CELL_AREA_CONTEXT_GET_CLASS (context)->allocate (context, width, height);
436 * gtk_cell_area_context_get_preferred_width:
437 * @context: a #GtkCellAreaContext
438 * @minimum_width: (out) (allow-none): location to store the minimum width,
440 * @natural_width: (out) (allow-none): location to store the natural width,
443 * Gets the accumulative preferred width for all rows which have been
444 * requested with this context.
446 * After gtk_cell_area_context_reset() is called and/or before ever
447 * requesting the size of a #GtkCellArea, the returned values are -1.
452 gtk_cell_area_context_get_preferred_width (GtkCellAreaContext *context,
456 GtkCellAreaContextPrivate *priv;
458 g_return_if_fail (GTK_IS_CELL_AREA_CONTEXT (context));
460 priv = context->priv;
463 *minimum_width = priv->min_width;
466 *natural_width = priv->nat_width;
470 * gtk_cell_area_context_get_preferred_height:
471 * @context: a #GtkCellAreaContext
472 * @minimum_height: (out) (allow-none): location to store the minimum height,
474 * @natural_height: (out) (allow-none): location to store the natural height,
477 * Gets the accumulative preferred height for all rows which have been
478 * requested with this context.
480 * After gtk_cell_area_context_reset() is called and/or before ever
481 * requesting the size of a #GtkCellArea, the returned values are -1.
486 gtk_cell_area_context_get_preferred_height (GtkCellAreaContext *context,
487 gint *minimum_height,
488 gint *natural_height)
490 GtkCellAreaContextPrivate *priv;
492 g_return_if_fail (GTK_IS_CELL_AREA_CONTEXT (context));
494 priv = context->priv;
497 *minimum_height = priv->min_height;
500 *natural_height = priv->nat_height;
504 * gtk_cell_area_context_get_preferred_height_for_width:
505 * @context: a #GtkCellAreaContext
506 * @width: a proposed width for allocation
507 * @minimum_height: (out) (allow-none): location to store the minimum height,
509 * @natural_height: (out) (allow-none): location to store the natural height,
512 * Gets the accumulative preferred height for @width for all rows
513 * which have been requested for the same said @width with this context.
515 * After gtk_cell_area_context_reset() is called and/or before ever
516 * requesting the size of a #GtkCellArea, the returned values are -1.
521 gtk_cell_area_context_get_preferred_height_for_width (GtkCellAreaContext *context,
523 gint *minimum_height,
524 gint *natural_height)
526 g_return_if_fail (GTK_IS_CELL_AREA_CONTEXT (context));
528 if (GTK_CELL_AREA_CONTEXT_GET_CLASS (context)->get_preferred_height_for_width)
529 GTK_CELL_AREA_CONTEXT_GET_CLASS (context)->get_preferred_height_for_width (context,
536 * gtk_cell_area_context_get_preferred_width_for_height:
537 * @context: a #GtkCellAreaContext
538 * @height: a proposed height for allocation
539 * @minimum_width: (out) (allow-none): location to store the minimum width,
541 * @natural_width: (out) (allow-none): location to store the natural width,
544 * Gets the accumulative preferred width for @height for all rows which
545 * have been requested for the same said @height with this context.
547 * After gtk_cell_area_context_reset() is called and/or before ever
548 * requesting the size of a #GtkCellArea, the returned values are -1.
553 gtk_cell_area_context_get_preferred_width_for_height (GtkCellAreaContext *context,
558 g_return_if_fail (GTK_IS_CELL_AREA_CONTEXT (context));
560 if (GTK_CELL_AREA_CONTEXT_GET_CLASS (context)->get_preferred_width_for_height)
561 GTK_CELL_AREA_CONTEXT_GET_CLASS (context)->get_preferred_width_for_height (context,
568 * gtk_cell_area_context_get_allocation:
569 * @context: a #GtkCellAreaContext
570 * @width: (out) (allow-none): location to store the allocated width, or %NULL
571 * @height: (out) (allow-none): location to store the allocated height, or %NULL
573 * Fetches the current allocation size for @context.
575 * If the context was not allocated in width or height, or if the
576 * context was recently reset with gtk_cell_area_context_reset(),
577 * the returned value will be -1.
582 gtk_cell_area_context_get_allocation (GtkCellAreaContext *context,
586 GtkCellAreaContextPrivate *priv;
588 g_return_if_fail (GTK_IS_CELL_AREA_CONTEXT (context));
590 priv = context->priv;
593 *width = priv->alloc_width;
596 *height = priv->alloc_height;
600 * gtk_cell_area_context_push_preferred_width:
601 * @context: a #GtkCellAreaContext
602 * @minimum_width: the proposed new minimum width for @context
603 * @natural_width: the proposed new natural width for @context
605 * Causes the minimum and/or natural width to grow if the new
606 * proposed sizes exceed the current minimum and natural width.
608 * This is used by #GtkCellAreaContext implementations during
609 * the request process over a series of #GtkTreeModel rows to
610 * progressively push the requested width over a series of
611 * gtk_cell_area_get_preferred_width() requests.
616 gtk_cell_area_context_push_preferred_width (GtkCellAreaContext *context,
620 GtkCellAreaContextPrivate *priv;
622 g_return_if_fail (GTK_IS_CELL_AREA_CONTEXT (context));
624 priv = context->priv;
626 g_object_freeze_notify (G_OBJECT (context));
628 if (minimum_width > priv->min_width)
630 priv->min_width = minimum_width;
632 g_object_notify (G_OBJECT (context), "minimum-width");
635 if (natural_width > priv->nat_width)
637 priv->nat_width = natural_width;
639 g_object_notify (G_OBJECT (context), "natural-width");
642 g_object_thaw_notify (G_OBJECT (context));
646 * gtk_cell_area_context_push_preferred_height:
647 * @context: a #GtkCellAreaContext
648 * @minimum_height: the proposed new minimum height for @context
649 * @natural_height: the proposed new natural height for @context
651 * Causes the minimum and/or natural height to grow if the new
652 * proposed sizes exceed the current minimum and natural height.
654 * This is used by #GtkCellAreaContext implementations during
655 * the request process over a series of #GtkTreeModel rows to
656 * progressively push the requested height over a series of
657 * gtk_cell_area_get_preferred_height() requests.
662 gtk_cell_area_context_push_preferred_height (GtkCellAreaContext *context,
666 GtkCellAreaContextPrivate *priv;
668 g_return_if_fail (GTK_IS_CELL_AREA_CONTEXT (context));
670 priv = context->priv;
672 g_object_freeze_notify (G_OBJECT (context));
674 if (minimum_height > priv->min_height)
676 priv->min_height = minimum_height;
678 g_object_notify (G_OBJECT (context), "minimum-height");
681 if (natural_height > priv->nat_height)
683 priv->nat_height = natural_height;
685 g_object_notify (G_OBJECT (context), "natural-height");
688 g_object_thaw_notify (G_OBJECT (context));