No issues found
1 /* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
2 /*
3 * st-table-child.h: Table child implementation
4 *
5 * Copyright 2008, 2009 Intel Corporation.
6 * Copyright 2010 Red Hat, Inc.
7 *
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms and conditions of the GNU Lesser General Public License,
10 * version 2.1, as published by the Free Software Foundation.
11 *
12 * This program is distributed in the hope it will be useful, but WITHOUT ANY
13 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
14 * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for
15 * more details.
16 *
17 * You should have received a copy of the GNU Lesser General Public License
18 * along with this program. If not, see <http://www.gnu.org/licenses/>.
19 */
20
21 #include "st-private.h"
22 #include "st-table-child.h"
23 #include "st-table-private.h"
24 #include "st-enum-types.h"
25 #include <st/st-widget.h>
26 #include <st/st-table.h>
27
28 /*
29 * ClutterChildMeta Implementation
30 */
31
32 /**
33 * SECTION:st-table-child
34 * @short_description: The child property store for #StTable
35 *
36 * The #ClutterChildMeta implementation for the #StTable container widget.
37 *
38 */
39
40 enum {
41 CHILD_PROP_0,
42
43 CHILD_PROP_COL,
44 CHILD_PROP_ROW,
45 CHILD_PROP_COL_SPAN,
46 CHILD_PROP_ROW_SPAN,
47 CHILD_PROP_X_EXPAND,
48 CHILD_PROP_Y_EXPAND,
49 CHILD_PROP_X_ALIGN,
50 CHILD_PROP_Y_ALIGN,
51 CHILD_PROP_X_FILL,
52 CHILD_PROP_Y_FILL,
53 CHILD_PROP_ALLOCATE_HIDDEN,
54 };
55
56 G_DEFINE_TYPE (StTableChild, st_table_child, CLUTTER_TYPE_CHILD_META);
57
58 static void
59 table_child_set_property (GObject *gobject,
60 guint prop_id,
61 const GValue *value,
62 GParamSpec *pspec)
63 {
64 StTableChild *child = ST_TABLE_CHILD (gobject);
65 StTable *table = ST_TABLE (CLUTTER_CHILD_META(gobject)->container);
66
67 switch (prop_id)
68 {
69 case CHILD_PROP_COL:
70 child->col = g_value_get_int (value);
71 _st_table_update_row_col (table, -1, child->col);
72 clutter_actor_queue_relayout (CLUTTER_ACTOR (table));
73 break;
74 case CHILD_PROP_ROW:
75 child->row = g_value_get_int (value);
76 _st_table_update_row_col (table, child->row, -1);
77 clutter_actor_queue_relayout (CLUTTER_ACTOR (table));
78 break;
79 case CHILD_PROP_COL_SPAN:
80 child->col_span = g_value_get_int (value);
81 clutter_actor_queue_relayout (CLUTTER_ACTOR (table));
82 break;
83 case CHILD_PROP_ROW_SPAN:
84 child->row_span = g_value_get_int (value);
85 clutter_actor_queue_relayout (CLUTTER_ACTOR (table));
86 break;
87 case CHILD_PROP_X_EXPAND:
88 child->x_expand = g_value_get_boolean (value);
89 clutter_actor_queue_relayout (CLUTTER_ACTOR (table));
90 break;
91 case CHILD_PROP_Y_EXPAND:
92 child->y_expand = g_value_get_boolean (value);
93 clutter_actor_queue_relayout (CLUTTER_ACTOR (table));
94 break;
95 case CHILD_PROP_X_ALIGN:
96 child->x_align = g_value_get_enum (value);
97 clutter_actor_queue_relayout (CLUTTER_ACTOR (table));
98 break;
99 case CHILD_PROP_Y_ALIGN:
100 child->y_align = g_value_get_enum (value);
101 clutter_actor_queue_relayout (CLUTTER_ACTOR (table));
102 break;
103 case CHILD_PROP_X_FILL:
104 child->x_fill = g_value_get_boolean (value);
105 clutter_actor_queue_relayout (CLUTTER_ACTOR (table));
106 break;
107 case CHILD_PROP_Y_FILL:
108 child->y_fill = g_value_get_boolean (value);
109 clutter_actor_queue_relayout (CLUTTER_ACTOR (table));
110 break;
111 case CHILD_PROP_ALLOCATE_HIDDEN:
112 child->allocate_hidden = g_value_get_boolean (value);
113 clutter_actor_queue_relayout (CLUTTER_ACTOR (table));
114 break;
115
116 default:
117 G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec);
118 break;
119 }
120 }
121
122 static void
123 table_child_get_property (GObject *gobject,
124 guint prop_id,
125 GValue *value,
126 GParamSpec *pspec)
127 {
128 StTableChild *child = ST_TABLE_CHILD (gobject);
129
130 switch (prop_id)
131 {
132 case CHILD_PROP_COL:
133 g_value_set_int (value, child->col);
134 break;
135 case CHILD_PROP_ROW:
136 g_value_set_int (value, child->row);
137 break;
138 case CHILD_PROP_COL_SPAN:
139 g_value_set_int (value, child->col_span);
140 break;
141 case CHILD_PROP_ROW_SPAN:
142 g_value_set_int (value, child->row_span);
143 break;
144 case CHILD_PROP_X_EXPAND:
145 g_value_set_boolean (value, child->x_expand);
146 break;
147 case CHILD_PROP_Y_EXPAND:
148 g_value_set_boolean (value, child->y_expand);
149 break;
150 case CHILD_PROP_X_ALIGN:
151 g_value_set_enum (value, child->x_align);
152 break;
153 case CHILD_PROP_Y_ALIGN:
154 g_value_set_enum (value, child->y_align);
155 break;
156 case CHILD_PROP_X_FILL:
157 g_value_set_boolean (value, child->x_fill);
158 break;
159 case CHILD_PROP_Y_FILL:
160 g_value_set_boolean (value, child->y_fill);
161 break;
162 case CHILD_PROP_ALLOCATE_HIDDEN:
163 g_value_set_boolean (value, child->allocate_hidden);
164 break;
165
166 default:
167 G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec);
168 break;
169 }
170 }
171
172 static void
173 st_table_child_class_init (StTableChildClass *klass)
174 {
175 GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
176 GParamSpec *pspec;
177
178 gobject_class->set_property = table_child_set_property;
179 gobject_class->get_property = table_child_get_property;
180
181 pspec = g_param_spec_int ("col",
182 "Column Number",
183 "The column the widget resides in",
184 0, G_MAXINT,
185 0,
186 ST_PARAM_READWRITE);
187
188 g_object_class_install_property (gobject_class, CHILD_PROP_COL, pspec);
189
190 pspec = g_param_spec_int ("row",
191 "Row Number",
192 "The row the widget resides in",
193 0, G_MAXINT,
194 0,
195 ST_PARAM_READWRITE);
196
197 g_object_class_install_property (gobject_class, CHILD_PROP_ROW, pspec);
198
199 pspec = g_param_spec_int ("row-span",
200 "Row Span",
201 "The number of rows the widget should span",
202 1, G_MAXINT,
203 1,
204 ST_PARAM_READWRITE);
205
206 g_object_class_install_property (gobject_class, CHILD_PROP_ROW_SPAN, pspec);
207
208 pspec = g_param_spec_int ("col-span",
209 "Column Span",
210 "The number of columns the widget should span",
211 1, G_MAXINT,
212 1,
213 ST_PARAM_READWRITE);
214
215 g_object_class_install_property (gobject_class, CHILD_PROP_COL_SPAN, pspec);
216
217 pspec = g_param_spec_boolean ("x-expand",
218 "X Expand",
219 "Whether the child should receive priority "
220 "when the container is allocating spare space "
221 "on the horizontal axis",
222 TRUE,
223 ST_PARAM_READWRITE);
224
225 g_object_class_install_property (gobject_class, CHILD_PROP_X_EXPAND, pspec);
226
227 pspec = g_param_spec_boolean ("y-expand",
228 "Y Expand",
229 "Whether the child should receive priority "
230 "when the container is allocating spare space "
231 "on the vertical axis",
232 TRUE,
233 ST_PARAM_READWRITE);
234
235 g_object_class_install_property (gobject_class, CHILD_PROP_Y_EXPAND, pspec);
236
237 pspec = g_param_spec_enum ("x-align",
238 "X Alignment",
239 "X alignment of the widget within the cell",
240 ST_TYPE_ALIGN,
241 ST_ALIGN_MIDDLE,
242 ST_PARAM_READWRITE);
243
244 g_object_class_install_property (gobject_class, CHILD_PROP_X_ALIGN, pspec);
245
246 pspec = g_param_spec_enum ("y-align",
247 "Y Alignment",
248 "Y alignment of the widget within the cell",
249 ST_TYPE_ALIGN,
250 ST_ALIGN_MIDDLE,
251 ST_PARAM_READWRITE);
252
253 g_object_class_install_property (gobject_class, CHILD_PROP_Y_ALIGN, pspec);
254
255 pspec = g_param_spec_boolean ("x-fill",
256 "X Fill",
257 "Whether the child should be allocated its "
258 "entire available space, or whether it should "
259 "be squashed and aligned.",
260 TRUE,
261 ST_PARAM_READWRITE);
262
263 g_object_class_install_property (gobject_class, CHILD_PROP_X_FILL, pspec);
264
265 pspec = g_param_spec_boolean ("y-fill",
266 "Y Fill",
267 "Whether the child should be allocated its "
268 "entire available space, or whether it should "
269 "be squashed and aligned.",
270 TRUE,
271 ST_PARAM_READWRITE);
272
273 g_object_class_install_property (gobject_class, CHILD_PROP_Y_FILL, pspec);
274
275 pspec = g_param_spec_boolean ("allocate-hidden",
276 "Allocate Hidden",
277 "Whether the child should be allocate even "
278 "if it is hidden",
279 TRUE,
280 ST_PARAM_READWRITE);
281
282 g_object_class_install_property (gobject_class, CHILD_PROP_ALLOCATE_HIDDEN, pspec);
283 }
284
285 static void
286 st_table_child_init (StTableChild *self)
287 {
288 self->col_span = 1;
289 self->row_span = 1;
290
291 self->x_align = ST_ALIGN_MIDDLE;
292 self->y_align = ST_ALIGN_MIDDLE;
293
294 self->x_expand = TRUE;
295 self->y_expand = TRUE;
296
297 self->x_fill = TRUE;
298 self->y_fill = TRUE;
299
300 self->allocate_hidden = TRUE;
301 }
302
303 static StTableChild*
304 get_child_meta (StTable *table,
305 ClutterActor *child)
306 {
307 StTableChild *meta;
308
309 meta = (StTableChild*) clutter_container_get_child_meta (CLUTTER_CONTAINER (table), child);
310
311 return meta;
312 }
313
314 /**
315 * st_table_child_get_col_span:
316 * @table: an #StTable
317 * @child: a #ClutterActor
318 *
319 * Get the column span of the child. Defaults to 1.
320 *
321 * Returns: the column span of the child
322 */
323 gint
324 st_table_child_get_col_span (StTable *table,
325 ClutterActor *child)
326 {
327 StTableChild *meta;
328
329 g_return_val_if_fail (ST_IS_TABLE (table), 0);
330 g_return_val_if_fail (CLUTTER_IS_ACTOR (child), 0);
331
332 meta = get_child_meta (table, child);
333
334 return meta->col_span;
335 }
336
337 /**
338 * st_table_child_set_col_span:
339 * @table: An #StTable
340 * @child: An #ClutterActor
341 * @span: The number of columns to span
342 *
343 * Set the column span of the child.
344 *
345 */
346 void
347 st_table_child_set_col_span (StTable *table,
348 ClutterActor *child,
349 gint span)
350 {
351 StTableChild *meta;
352
353 g_return_if_fail (ST_IS_TABLE (table));
354 g_return_if_fail (CLUTTER_IS_ACTOR (child));
355 g_return_if_fail (span > 1);
356
357 meta = get_child_meta (table, child);
358
359 meta->col_span = span;
360
361 clutter_actor_queue_relayout (child);
362 }
363
364 /**
365 * st_table_child_get_row_span:
366 * @table: A #StTable
367 * @child: A #ClutterActor
368 *
369 * Get the row span of the child. Defaults to 1.
370 *
371 * Returns: the row span of the child
372 */
373 gint
374 st_table_child_get_row_span (StTable *table,
375 ClutterActor *child)
376 {
377 StTableChild *meta;
378
379 g_return_val_if_fail (ST_IS_TABLE (table), 0);
380 g_return_val_if_fail (CLUTTER_IS_ACTOR (child), 0);
381
382 meta = get_child_meta (table, child);
383
384 return meta->row_span;
385 }
386
387 /**
388 * st_table_child_set_row_span:
389 * @table: A #StTable
390 * @child: A #ClutterActor
391 * @span: the number of rows to span
392 *
393 * Set the row span of the child.
394 *
395 */
396 void
397 st_table_child_set_row_span (StTable *table,
398 ClutterActor *child,
399 gint span)
400 {
401 StTableChild *meta;
402
403 g_return_if_fail (ST_IS_TABLE (table));
404 g_return_if_fail (CLUTTER_IS_ACTOR (child));
405 g_return_if_fail (span > 1);
406
407 meta = get_child_meta (table, child);
408
409 meta->row_span = span;
410
411 clutter_actor_queue_relayout (child);
412 }
413
414 /**
415 * st_table_child_get_x_fill:
416 * @table: A #StTable
417 * @child: A #ClutterActor
418 *
419 * Get the x-fill state of the child
420 *
421 * Returns: %TRUE if the child is set to x-fill
422 */
423 gboolean
424 st_table_child_get_x_fill (StTable *table,
425 ClutterActor *child)
426 {
427 StTableChild *meta;
428
429 g_return_val_if_fail (ST_IS_TABLE (table), 0);
430 g_return_val_if_fail (CLUTTER_IS_ACTOR (child), 0);
431
432 meta = get_child_meta (table, child);
433
434 return meta->x_fill;
435 }
436
437 /**
438 * st_table_child_set_x_fill:
439 * @table: A #StTable
440 * @child: A #ClutterActor
441 * @fill: the fill state
442 *
443 * Set the fill state of the child on the x-axis. This will cause the child to
444 * be allocated the maximum available space.
445 *
446 */
447 void
448 st_table_child_set_x_fill (StTable *table,
449 ClutterActor *child,
450 gboolean fill)
451 {
452 StTableChild *meta;
453
454 g_return_if_fail (ST_IS_TABLE (table));
455 g_return_if_fail (CLUTTER_IS_ACTOR (child));
456
457 meta = get_child_meta (table, child);
458
459 meta->x_fill = fill;
460
461 clutter_actor_queue_relayout (child);
462 }
463
464
465 /**
466 * st_table_child_get_y_fill:
467 * @table: A #StTable
468 * @child: A #ClutterActor
469 *
470 * Get the y-fill state of the child
471 *
472 * Returns: %TRUE if the child is set to y-fill
473 */
474 gboolean
475 st_table_child_get_y_fill (StTable *table,
476 ClutterActor *child)
477 {
478 StTableChild *meta;
479
480 g_return_val_if_fail (ST_IS_TABLE (table), 0);
481 g_return_val_if_fail (CLUTTER_IS_ACTOR (child), 0);
482
483 meta = get_child_meta (table, child);
484
485 return meta->y_fill;
486 }
487
488 /**
489 * st_table_child_set_y_fill:
490 * @table: A #StTable
491 * @child: A #ClutterActor
492 * @fill: the fill state
493 *
494 * Set the fill state of the child on the y-axis. This will cause the child to
495 * be allocated the maximum available space.
496 *
497 */
498 void
499 st_table_child_set_y_fill (StTable *table,
500 ClutterActor *child,
501 gboolean fill)
502 {
503 StTableChild *meta;
504
505 g_return_if_fail (ST_IS_TABLE (table));
506 g_return_if_fail (CLUTTER_IS_ACTOR (child));
507
508 meta = get_child_meta (table, child);
509
510 meta->y_fill = fill;
511
512 clutter_actor_queue_relayout (child);
513 }
514
515 /**
516 * st_table_child_get_x_expand:
517 * @table: A #StTable
518 * @child: A #ClutterActor
519 *
520 * Get the x-expand property of the child
521 *
522 * Returns: %TRUE if the child is set to x-expand
523 */
524 gboolean
525 st_table_child_get_x_expand (StTable *table,
526 ClutterActor *child)
527 {
528 StTableChild *meta;
529
530 g_return_val_if_fail (ST_IS_TABLE (table), 0);
531 g_return_val_if_fail (CLUTTER_IS_ACTOR (child), 0);
532
533 meta = get_child_meta (table, child);
534
535 return meta->x_expand;
536 }
537
538 /**
539 * st_table_child_set_x_expand:
540 * @table: A #StTable
541 * @child: A #ClutterActor
542 * @expand: the new value of the x expand child property
543 *
544 * Set x-expand on the child. This causes the column which the child
545 * resides in to be allocated any extra space if the allocation of the table is
546 * larger than the preferred size.
547 *
548 */
549 void
550 st_table_child_set_x_expand (StTable *table,
551 ClutterActor *child,
552 gboolean expand)
553 {
554 StTableChild *meta;
555
556 g_return_if_fail (ST_IS_TABLE (table));
557 g_return_if_fail (CLUTTER_IS_ACTOR (child));
558
559 meta = get_child_meta (table, child);
560
561 meta->x_expand = expand;
562
563 clutter_actor_queue_relayout (child);
564 }
565
566 /**
567 * st_table_child_set_y_expand:
568 * @table: A #StTable
569 * @child: A #ClutterActor
570 * @expand: the new value of the y-expand child property
571 *
572 * Set y-expand on the child. This causes the row which the child
573 * resides in to be allocated any extra space if the allocation of the table is
574 * larger than the preferred size.
575 *
576 */
577 void
578 st_table_child_set_y_expand (StTable *table,
579 ClutterActor *child,
580 gboolean expand)
581 {
582 StTableChild *meta;
583
584 g_return_if_fail (ST_IS_TABLE (table));
585 g_return_if_fail (CLUTTER_IS_ACTOR (child));
586
587 meta = get_child_meta (table, child);
588
589 meta->y_expand = expand;
590
591 clutter_actor_queue_relayout (child);
592 }
593
594 /**
595 * st_table_child_get_y_expand:
596 * @table: A #StTable
597 * @child: A #ClutterActor
598 *
599 * Get the y-expand property of the child.
600 *
601 * Returns: %TRUE if the child is set to y-expand
602 */
603 gboolean
604 st_table_child_get_y_expand (StTable *table,
605 ClutterActor *child)
606 {
607 StTableChild *meta;
608
609 g_return_val_if_fail (ST_IS_TABLE (table), 0);
610 g_return_val_if_fail (CLUTTER_IS_ACTOR (child), 0);
611
612 meta = get_child_meta (table, child);
613
614 return meta->y_expand;
615 }
616
617 /**
618 * st_table_child_get_x_align:
619 * @table: A #StTable
620 * @child: A #ClutterActor
621 *
622 * Get the x-align value of the child
623 *
624 * Returns: An #StAlign value
625 */
626 StAlign
627 st_table_child_get_x_align (StTable *table,
628 ClutterActor *child)
629 {
630 StTableChild *meta;
631
632 g_return_val_if_fail (ST_IS_TABLE (table), 0);
633 g_return_val_if_fail (CLUTTER_IS_ACTOR (child), 0);
634
635 meta = get_child_meta (table, child);
636
637 return meta->x_align;
638
639 }
640
641 /**
642 * st_table_child_set_x_align:
643 * @table: A #StTable
644 * @child: A #ClutterActor
645 * @align: A #StAlign value
646 *
647 * Set the alignment of the child within its cell. This will only have an effect
648 * if the the x-fill property is FALSE.
649 *
650 */
651 void
652 st_table_child_set_x_align (StTable *table,
653 ClutterActor *child,
654 StAlign align)
655 {
656 StTableChild *meta;
657
658 g_return_if_fail (ST_IS_TABLE (table));
659 g_return_if_fail (CLUTTER_IS_ACTOR (child));
660
661 meta = get_child_meta (table, child);
662
663 meta->x_align = align;
664 clutter_actor_queue_relayout (child);
665 }
666
667 /**
668 * st_table_child_get_y_align:
669 * @table: A #StTable
670 * @child: A #ClutterActor
671 *
672 * Get the y-align value of the child
673 *
674 * Returns: An #StAlign value
675 */
676 StAlign
677 st_table_child_get_y_align (StTable *table,
678 ClutterActor *child)
679 {
680 StTableChild *meta;
681
682 g_return_val_if_fail (ST_IS_TABLE (table), 0);
683 g_return_val_if_fail (CLUTTER_IS_ACTOR (child), 0);
684
685 meta = get_child_meta (table, child);
686
687 return meta->y_align;
688 }
689
690 /**
691 * st_table_child_set_y_align:
692 * @table: A #StTable
693 * @child: A #ClutterActor
694 * @align: A #StAlign value
695 *
696 * Set the value of the y-align property. This will only have an effect if
697 * y-fill value is set to FALSE.
698 *
699 */
700 void
701 st_table_child_set_y_align (StTable *table,
702 ClutterActor *child,
703 StAlign align)
704 {
705 StTableChild *meta;
706
707 g_return_if_fail (ST_IS_TABLE (table));
708 g_return_if_fail (CLUTTER_IS_ACTOR (child));
709
710 meta = get_child_meta (table, child);
711
712 meta->y_align = align;
713 clutter_actor_queue_relayout (child);
714 }
715
716 /**
717 * st_table_child_set_allocate_hidden:
718 * @table: A #StTable
719 * @child: A #ClutterActor
720 * @value: %TRUE if the actor should be allocated when hidden
721 *
722 * Set whether the child should be allocate even if it is hidden
723 */
724 void
725 st_table_child_set_allocate_hidden (StTable *table,
726 ClutterActor *child,
727 gboolean value)
728 {
729 StTableChild *meta;
730
731 g_return_if_fail (ST_IS_TABLE (table));
732 g_return_if_fail (CLUTTER_IS_ACTOR (child));
733
734 meta = get_child_meta (table, child);
735
736 if (meta->allocate_hidden != value)
737 {
738 meta->allocate_hidden = value;
739
740 clutter_actor_queue_relayout (child);
741
742 g_object_notify (G_OBJECT (meta), "allocate-hidden");
743 }
744 }
745
746 /**
747 * st_table_child_get_allocate_hidden:
748 * @table: A #StTable
749 * @child: A #ClutterActor
750 *
751 * Determine if the child is allocated even if it is hidden
752 *
753 * Returns: %TRUE if the actor is allocated when hidden
754 */
755 gboolean
756 st_table_child_get_allocate_hidden (StTable *table,
757 ClutterActor *child)
758 {
759 StTableChild *meta;
760
761 g_return_val_if_fail (ST_IS_TABLE (table), TRUE);
762 g_return_val_if_fail (CLUTTER_IS_ACTOR (child), TRUE);
763
764 meta = get_child_meta (table, child);
765
766 return meta->allocate_hidden;
767 }