]> Pileus Git - ~andy/gtk/blob - gtk/gtkcellareacontext.c
Finally really support rendering of cells in an unallocated context.
[~andy/gtk] / gtk / gtkcellareacontext.c
1 /* gtkcellareacontext.c
2  *
3  * Copyright (C) 2010 Openismus GmbH
4  *
5  * Authors:
6  *      Tristan Van Berkom <tristanvb@openismus.com>
7  *
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.
12  *
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.
17  *
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.
22  */
23
24 #include "config.h"
25 #include "gtkintl.h"
26 #include "gtkmarshalers.h"
27 #include "gtkcellareacontext.h"
28 #include "gtkprivate.h"
29
30 /* GObjectClass */
31 static void      gtk_cell_area_context_dispose                        (GObject            *object);
32 static void      gtk_cell_area_context_get_property                   (GObject            *object,
33                                                                        guint               prop_id,
34                                                                        GValue             *value,
35                                                                        GParamSpec         *pspec);
36 static void      gtk_cell_area_context_set_property                   (GObject            *object,
37                                                                        guint               prop_id,
38                                                                        const GValue       *value,
39                                                                        GParamSpec         *pspec);
40
41 /* GtkCellAreaContextClass */
42 static void      gtk_cell_area_context_real_flush_preferred_width            (GtkCellAreaContext *context);
43 static void      gtk_cell_area_context_real_flush_preferred_height           (GtkCellAreaContext *context);
44 static void      gtk_cell_area_context_real_flush_allocation                 (GtkCellAreaContext *context);
45 static void      gtk_cell_area_context_real_allocate                         (GtkCellAreaContext *context,
46                                                                               gint                width,
47                                                                               gint                height);
48
49 struct _GtkCellAreaContextPrivate
50 {
51   GtkCellArea *cell_area;
52
53   gint         min_width;
54   gint         nat_width;
55   gint         min_height;
56   gint         nat_height;
57   gint         alloc_width;
58   gint         alloc_height;
59 };
60
61 enum {
62   PROP_0,
63   PROP_CELL_AREA,
64   PROP_MIN_WIDTH,
65   PROP_NAT_WIDTH,
66   PROP_MIN_HEIGHT,
67   PROP_NAT_HEIGHT
68 };
69
70 G_DEFINE_TYPE (GtkCellAreaContext, gtk_cell_area_context, G_TYPE_OBJECT);
71
72 static void
73 gtk_cell_area_context_init (GtkCellAreaContext *context)
74 {
75   GtkCellAreaContextPrivate *priv;
76
77   context->priv = G_TYPE_INSTANCE_GET_PRIVATE (context,
78                                                GTK_TYPE_CELL_AREA_CONTEXT,
79                                                GtkCellAreaContextPrivate);
80   priv = context->priv;
81
82   priv->min_width  = -1;
83   priv->nat_width  = -1;
84   priv->min_height = -1;
85   priv->nat_height = -1;
86 }
87
88 static void 
89 gtk_cell_area_context_class_init (GtkCellAreaContextClass *class)
90 {
91   GObjectClass     *object_class = G_OBJECT_CLASS (class);
92
93   /* GObjectClass */
94   object_class->dispose      = gtk_cell_area_context_dispose;
95   object_class->get_property = gtk_cell_area_context_get_property;
96   object_class->set_property = gtk_cell_area_context_set_property;
97
98   /* GtkCellAreaContextClass */
99   class->flush_preferred_width   = gtk_cell_area_context_real_flush_preferred_width;
100   class->flush_preferred_height  = gtk_cell_area_context_real_flush_preferred_height;
101   class->flush_allocation        = gtk_cell_area_context_real_flush_allocation;
102   class->sum_preferred_width     = NULL;
103   class->sum_preferred_height    = NULL;
104   class->allocate                = gtk_cell_area_context_real_allocate;
105
106   g_object_class_install_property (object_class,
107                                    PROP_CELL_AREA,
108                                    g_param_spec_object ("area",
109                                                         P_("Area"),
110                                                         P_("The Cell Area this context was created for"),
111                                                         GTK_TYPE_CELL_AREA,
112                                                         GTK_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
113
114   g_object_class_install_property (object_class,
115                                    PROP_MIN_WIDTH,
116                                    g_param_spec_int ("minimum-width",
117                                                      P_("Minimum Width"),
118                                                      P_("Minimum cached width"),
119                                                      -1,
120                                                      G_MAXINT,
121                                                      -1,
122                                                      G_PARAM_READABLE));
123
124   g_object_class_install_property (object_class,
125                                    PROP_NAT_WIDTH,
126                                    g_param_spec_int ("natural-width",
127                                                      P_("Minimum Width"),
128                                                      P_("Minimum cached width"),
129                                                      -1,
130                                                      G_MAXINT,
131                                                      -1,
132                                                      G_PARAM_READABLE));
133
134   g_object_class_install_property (object_class,
135                                    PROP_MIN_HEIGHT,
136                                    g_param_spec_int ("minimum-height",
137                                                      P_("Minimum Height"),
138                                                      P_("Minimum cached height"),
139                                                      -1,
140                                                      G_MAXINT,
141                                                      -1,
142                                                      G_PARAM_READABLE));
143
144   g_object_class_install_property (object_class,
145                                    PROP_NAT_HEIGHT,
146                                    g_param_spec_int ("natural-height",
147                                                      P_("Minimum Height"),
148                                                      P_("Minimum cached height"),
149                                                      -1,
150                                                      G_MAXINT,
151                                                      -1,
152                                                      G_PARAM_READABLE));
153
154   g_type_class_add_private (object_class, sizeof (GtkCellAreaContextPrivate));
155 }
156
157 /*************************************************************
158  *                      GObjectClass                         *
159  *************************************************************/
160 static void
161 gtk_cell_area_context_dispose (GObject *object)
162 {
163   GtkCellAreaContext        *context = GTK_CELL_AREA_CONTEXT (object);
164   GtkCellAreaContextPrivate *priv = context->priv;
165
166   if (priv->cell_area)
167     {
168       g_object_unref (priv->cell_area);
169
170       priv->cell_area = NULL;
171     }
172
173   G_OBJECT_CLASS (gtk_cell_area_context_parent_class)->dispose (object);
174 }
175
176 static void
177 gtk_cell_area_context_set_property (GObject      *object,
178                                     guint         prop_id,
179                                     const GValue *value,
180                                     GParamSpec   *pspec)
181 {
182   GtkCellAreaContext        *context = GTK_CELL_AREA_CONTEXT (object);
183   GtkCellAreaContextPrivate *priv = context->priv;
184
185   switch (prop_id)
186     {
187     case PROP_CELL_AREA:
188       priv->cell_area = g_value_dup_object (value);
189       break;
190     default:
191       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
192       break;
193     }
194 }
195
196 static void
197 gtk_cell_area_context_get_property (GObject     *object,
198                                     guint        prop_id,
199                                     GValue      *value,
200                                     GParamSpec  *pspec)
201 {
202   GtkCellAreaContext        *context = GTK_CELL_AREA_CONTEXT (object);
203   GtkCellAreaContextPrivate *priv = context->priv;
204
205   switch (prop_id)
206     {
207     case PROP_CELL_AREA:
208       g_value_set_object (value, priv->cell_area);
209       break;
210     case PROP_MIN_WIDTH:
211       g_value_set_int (value, priv->min_width);
212       break;
213     case PROP_NAT_WIDTH:
214       g_value_set_int (value, priv->nat_width);
215       break;
216     case PROP_MIN_HEIGHT:
217       g_value_set_int (value, priv->min_height);
218       break;
219     case PROP_NAT_HEIGHT:
220       g_value_set_int (value, priv->nat_height);
221       break;
222     default:
223       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
224       break;
225     }
226 }
227
228 /*************************************************************
229  *                    GtkCellAreaContextClass                   *
230  *************************************************************/
231 static void
232 gtk_cell_area_context_real_flush_preferred_width (GtkCellAreaContext *context)
233 {
234   GtkCellAreaContextPrivate *priv = context->priv;
235   
236   priv->min_width = -1;
237   priv->nat_width = -1;
238
239   g_object_freeze_notify (G_OBJECT (context));
240   g_object_notify (G_OBJECT (context), "minimum-width");
241   g_object_notify (G_OBJECT (context), "natural-width");
242   g_object_thaw_notify (G_OBJECT (context));
243 }
244
245 static void
246 gtk_cell_area_context_real_flush_preferred_height (GtkCellAreaContext *context)
247 {
248   GtkCellAreaContextPrivate *priv = context->priv;
249   
250   priv->min_height = -1;
251   priv->nat_height = -1;
252
253   g_object_freeze_notify (G_OBJECT (context));
254   g_object_notify (G_OBJECT (context), "minimum-height");
255   g_object_notify (G_OBJECT (context), "natural-height");
256   g_object_thaw_notify (G_OBJECT (context));
257 }
258
259 static void
260 gtk_cell_area_context_real_flush_allocation (GtkCellAreaContext *context)
261 {
262   GtkCellAreaContextPrivate *priv = context->priv;
263
264   priv->alloc_width  = 0;
265   priv->alloc_height = 0;
266 }
267
268 static void
269 gtk_cell_area_context_real_allocate (GtkCellAreaContext *context,
270                                      gint                width,
271                                      gint                height)
272 {
273   GtkCellAreaContextPrivate *priv = context->priv;
274
275   priv->alloc_width  = width;
276   priv->alloc_height = height;
277 }
278
279 /*************************************************************
280  *                            API                            *
281  *************************************************************/
282 GtkCellArea *
283 gtk_cell_area_context_get_area (GtkCellAreaContext *context)
284 {
285   GtkCellAreaContextPrivate *priv;
286
287   g_return_val_if_fail (GTK_IS_CELL_AREA_CONTEXT (context), NULL);
288
289   priv = context->priv;
290
291   return priv->cell_area;
292 }
293
294 void
295 gtk_cell_area_context_flush (GtkCellAreaContext *context)
296 {
297   g_return_if_fail (GTK_IS_CELL_AREA_CONTEXT (context));
298
299   gtk_cell_area_context_flush_preferred_width (context);
300   gtk_cell_area_context_flush_preferred_height (context);
301   gtk_cell_area_context_flush_allocation (context);
302 }
303
304 void
305 gtk_cell_area_context_flush_preferred_width (GtkCellAreaContext *context)
306 {
307   g_return_if_fail (GTK_IS_CELL_AREA_CONTEXT (context));
308
309   GTK_CELL_AREA_CONTEXT_GET_CLASS (context)->flush_preferred_width (context);
310 }
311
312 void
313 gtk_cell_area_context_flush_preferred_height (GtkCellAreaContext *context)
314 {
315   g_return_if_fail (GTK_IS_CELL_AREA_CONTEXT (context));
316
317   GTK_CELL_AREA_CONTEXT_GET_CLASS (context)->flush_preferred_height (context);
318 }
319
320 void
321 gtk_cell_area_context_flush_allocation (GtkCellAreaContext *context)
322 {
323   g_return_if_fail (GTK_IS_CELL_AREA_CONTEXT (context));
324
325   GTK_CELL_AREA_CONTEXT_GET_CLASS (context)->flush_allocation (context);
326 }
327
328 void
329 gtk_cell_area_context_sum_preferred_width (GtkCellAreaContext *context)
330 {
331   GtkCellAreaContextClass *class;
332
333   g_return_if_fail (GTK_IS_CELL_AREA_CONTEXT (context));
334
335   class = GTK_CELL_AREA_CONTEXT_GET_CLASS (context);
336
337   if (class->sum_preferred_width)
338     class->sum_preferred_width (context);
339 }
340
341 void
342 gtk_cell_area_context_sum_preferred_height (GtkCellAreaContext *context)
343 {
344   GtkCellAreaContextClass *class;
345
346   g_return_if_fail (GTK_IS_CELL_AREA_CONTEXT (context));
347
348   class = GTK_CELL_AREA_CONTEXT_GET_CLASS (context);
349
350   if (class->sum_preferred_height)
351     class->sum_preferred_height (context);
352 }
353
354 void
355 gtk_cell_area_context_allocate (GtkCellAreaContext *context,
356                                 gint                width,
357                                 gint                height)
358 {
359   GtkCellAreaContextClass *class;
360
361   g_return_if_fail (GTK_IS_CELL_AREA_CONTEXT (context));
362
363   class = GTK_CELL_AREA_CONTEXT_GET_CLASS (context);
364
365   class->allocate (context, width, height);
366 }
367
368 void
369 gtk_cell_area_context_get_preferred_width (GtkCellAreaContext *context,
370                                            gint               *minimum_width,
371                                            gint               *natural_width)
372 {
373   GtkCellAreaContextPrivate *priv;
374
375   g_return_if_fail (GTK_IS_CELL_AREA_CONTEXT (context));
376
377   priv = context->priv;
378
379   if (minimum_width)
380     *minimum_width = priv->min_width;
381
382   if (natural_width)
383     *natural_width = priv->nat_width;
384 }
385
386 void
387 gtk_cell_area_context_get_preferred_height (GtkCellAreaContext *context,
388                                             gint               *minimum_height,
389                                             gint               *natural_height)
390 {
391   GtkCellAreaContextPrivate *priv;
392
393   g_return_if_fail (GTK_IS_CELL_AREA_CONTEXT (context));
394
395   priv = context->priv;
396
397   if (minimum_height)
398     *minimum_height = priv->min_height;
399
400   if (natural_height)
401     *natural_height = priv->nat_height;
402 }
403
404 void
405 gtk_cell_area_context_get_allocation (GtkCellAreaContext *context,
406                                       gint               *width,
407                                       gint               *height)
408 {
409   GtkCellAreaContextPrivate *priv;
410
411   g_return_if_fail (GTK_IS_CELL_AREA_CONTEXT (context));
412
413   priv = context->priv;
414
415   if (width)
416     *width = priv->alloc_width;
417
418   if (height)
419     *height = priv->alloc_height;
420 }
421
422 void
423 gtk_cell_area_context_push_preferred_width (GtkCellAreaContext *context,
424                                             gint                minimum_width,
425                                             gint                natural_width)
426 {
427   GtkCellAreaContextPrivate *priv;
428
429   g_return_if_fail (GTK_IS_CELL_AREA_CONTEXT (context));
430
431   priv = context->priv;
432
433   g_object_freeze_notify (G_OBJECT (context));
434
435   if (minimum_width > priv->min_width)
436     {
437       priv->min_width = minimum_width;
438
439       g_object_notify (G_OBJECT (context), "minimum-width");
440     }
441
442   if (natural_width > priv->nat_width)
443     {
444       priv->nat_width = natural_width;
445
446       g_object_notify (G_OBJECT (context), "natural-width");
447     }
448
449   g_object_thaw_notify (G_OBJECT (context));
450 }
451
452 void
453 gtk_cell_area_context_push_preferred_height (GtkCellAreaContext *context,
454                                              gint                minimum_height,
455                                              gint                natural_height)
456 {
457   GtkCellAreaContextPrivate *priv;
458   
459   g_return_if_fail (GTK_IS_CELL_AREA_CONTEXT (context));
460
461   priv = context->priv;
462
463   g_object_freeze_notify (G_OBJECT (context));
464
465   if (minimum_height > priv->min_height)
466     {
467       priv->min_height = minimum_height;
468
469       g_object_notify (G_OBJECT (context), "minimum-height");
470     }
471
472   if (natural_height > priv->nat_height)
473     {
474       priv->nat_height = natural_height;
475
476       g_object_notify (G_OBJECT (context), "natural-height");
477     }
478
479   g_object_thaw_notify (G_OBJECT (context));
480 }