1 /* GTK - The GIMP Toolkit
2 * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Library General Public
6 * License as published by the Free Software Foundation; either
7 * version 2 of the License, or (at your option) any later version.
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Library General Public License for more details.
14 * You should have received a copy of the GNU Library General Public
15 * License along with this library; if not, write to the
16 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
17 * Boston, MA 02111-1307, USA.
20 #include "gtkcontainer.h"
21 #include "gtkprivate.h"
22 #include "gtksignal.h"
43 typedef void (*GtkContainerSignal1) (GtkObject *object,
46 typedef void (*GtkContainerSignal2) (GtkObject *object,
50 typedef gint (*GtkContainerSignal3) (GtkObject *object,
53 typedef gint (*GtkContainerSignal4) (GtkObject *object,
57 static void gtk_container_marshal_signal_1 (GtkObject *object,
61 static void gtk_container_marshal_signal_2 (GtkObject *object,
65 static void gtk_container_marshal_signal_3 (GtkObject *object,
69 static void gtk_container_marshal_signal_4 (GtkObject *object,
75 static void gtk_container_class_init (GtkContainerClass *klass);
76 static void gtk_container_init (GtkContainer *container);
77 static void gtk_container_destroy (GtkObject *object);
78 static void gtk_container_get_arg (GtkContainer *container,
81 static void gtk_container_set_arg (GtkContainer *container,
84 static void gtk_container_add_unimplemented (GtkContainer *container,
86 static void gtk_container_remove_unimplemented (GtkContainer *container,
88 static gint gtk_container_real_need_resize (GtkContainer *container);
89 static gint gtk_container_real_focus (GtkContainer *container,
90 GtkDirectionType direction);
91 static void gtk_container_real_set_focus_child (GtkContainer *container,
93 static gint gtk_container_focus_tab (GtkContainer *container,
95 GtkDirectionType direction);
96 static gint gtk_container_focus_up_down (GtkContainer *container,
98 GtkDirectionType direction);
99 static gint gtk_container_focus_left_right (GtkContainer *container,
101 GtkDirectionType direction);
102 static gint gtk_container_focus_move (GtkContainer *container,
104 GtkDirectionType direction);
105 static void gtk_container_children_callback (GtkWidget *widget,
106 gpointer client_data);
107 static void gtk_container_show_all (GtkWidget *widget);
108 static void gtk_container_hide_all (GtkWidget *widget);
112 static guint container_signals[LAST_SIGNAL] = { 0 };
114 static GtkWidgetClass *parent_class = NULL;
116 static const gchar *vadjustment_key = "gtk-vadjustment";
117 static guint vadjustment_key_id = 0;
118 static const gchar *hadjustment_key = "gtk-hadjustment";
119 static guint hadjustment_key_id = 0;
122 gtk_container_get_type (void)
124 static GtkType container_type = 0;
128 GtkTypeInfo container_info =
131 sizeof (GtkContainer),
132 sizeof (GtkContainerClass),
133 (GtkClassInitFunc) gtk_container_class_init,
134 (GtkObjectInitFunc) gtk_container_init,
135 (GtkArgSetFunc) gtk_container_set_arg,
136 (GtkArgGetFunc) gtk_container_get_arg,
139 container_type = gtk_type_unique (gtk_widget_get_type (), &container_info);
142 return container_type;
146 gtk_container_class_init (GtkContainerClass *class)
148 GtkObjectClass *object_class;
149 GtkWidgetClass *widget_class;
151 object_class = (GtkObjectClass*) class;
152 widget_class = (GtkWidgetClass*) class;
154 parent_class = gtk_type_class (gtk_widget_get_type ());
156 vadjustment_key_id = gtk_object_data_force_id (vadjustment_key);
157 hadjustment_key_id = gtk_object_data_force_id (hadjustment_key);
159 gtk_object_add_arg_type ("GtkContainer::border_width", GTK_TYPE_LONG, GTK_ARG_READWRITE, ARG_BORDER_WIDTH);
160 gtk_object_add_arg_type ("GtkContainer::auto_resize", GTK_TYPE_BOOL, GTK_ARG_READWRITE, ARG_AUTO_RESIZE);
161 gtk_object_add_arg_type ("GtkContainer::block_resize", GTK_TYPE_BOOL, GTK_ARG_READWRITE, ARG_BLOCK_RESIZE);
162 gtk_object_add_arg_type ("GtkContainer::child", GTK_TYPE_WIDGET, GTK_ARG_WRITABLE, ARG_CHILD);
164 container_signals[ADD] =
165 gtk_signal_new ("add",
168 GTK_SIGNAL_OFFSET (GtkContainerClass, add),
169 gtk_container_marshal_signal_1,
172 container_signals[REMOVE] =
173 gtk_signal_new ("remove",
176 GTK_SIGNAL_OFFSET (GtkContainerClass, remove),
177 gtk_container_marshal_signal_1,
180 container_signals[NEED_RESIZE] =
181 gtk_signal_new ("need_resize",
184 GTK_SIGNAL_OFFSET (GtkContainerClass, need_resize),
185 gtk_container_marshal_signal_4,
187 container_signals[FOREACH] =
188 gtk_signal_new ("foreach",
191 GTK_SIGNAL_OFFSET (GtkContainerClass, foreach),
192 gtk_container_marshal_signal_2,
194 GTK_TYPE_C_CALLBACK);
195 container_signals[FOCUS] =
196 gtk_signal_new ("focus",
199 GTK_SIGNAL_OFFSET (GtkContainerClass, focus),
200 gtk_container_marshal_signal_3,
201 GTK_TYPE_DIRECTION_TYPE, 1,
202 GTK_TYPE_DIRECTION_TYPE);
203 container_signals[SET_FOCUS_CHILD] =
204 gtk_signal_new ("set-focus-child",
207 GTK_SIGNAL_OFFSET (GtkContainerClass, set_focus_child),
208 gtk_container_marshal_signal_1,
211 gtk_object_class_add_signals (object_class, container_signals, LAST_SIGNAL);
213 object_class->destroy = gtk_container_destroy;
215 /* Other container classes should overwrite show_all and hide_all,
216 * for the purpose of showing internal children also, which are not
217 * accessable through gtk_container_foreach.
219 widget_class->show_all = gtk_container_show_all;
220 widget_class->hide_all = gtk_container_hide_all;
222 class->add = gtk_container_add_unimplemented;
223 class->remove = gtk_container_remove_unimplemented;
224 class->need_resize = gtk_container_real_need_resize;
225 class->foreach = NULL;
226 class->focus = gtk_container_real_focus;
227 class->set_focus_child = gtk_container_real_set_focus_child;
231 gtk_container_add_unimplemented (GtkContainer *container,
234 g_warning ("GtkContainerClass::add not implemented for `%s'", gtk_type_name (GTK_OBJECT_TYPE (container)));
238 gtk_container_remove_unimplemented (GtkContainer *container,
241 g_warning ("GtkContainerClass::remove not implemented for `%s'", gtk_type_name (GTK_OBJECT_TYPE (container)));
245 gtk_container_init (GtkContainer *container)
247 container->focus_child = NULL;
248 container->border_width = 0;
249 container->auto_resize = TRUE;
250 container->need_resize = FALSE;
251 container->block_resize = FALSE;
252 container->resize_widgets = NULL;
256 gtk_container_destroy (GtkObject *object)
260 g_return_if_fail (object != NULL);
261 g_return_if_fail (GTK_IS_CONTAINER (object));
263 for (node = GTK_CONTAINER (object)->resize_widgets; node; node = node->next)
267 child = (GtkWidget*) node->data;
268 GTK_PRIVATE_UNSET_FLAG (child, GTK_RESIZE_NEEDED);
270 g_slist_free (GTK_CONTAINER (object)->resize_widgets);
271 GTK_CONTAINER (object)->resize_widgets = NULL;
273 gtk_container_foreach (GTK_CONTAINER (object),
274 (GtkCallback) gtk_widget_destroy, NULL);
276 if (GTK_OBJECT_CLASS (parent_class)->destroy)
277 (* GTK_OBJECT_CLASS (parent_class)->destroy) (object);
281 gtk_container_set_arg (GtkContainer *container,
287 case ARG_BORDER_WIDTH:
288 gtk_container_border_width (container, GTK_VALUE_LONG (*arg));
290 case ARG_AUTO_RESIZE:
291 if (GTK_VALUE_BOOL (*arg))
292 gtk_container_enable_resize (container);
294 gtk_container_disable_resize (container);
296 case ARG_BLOCK_RESIZE:
297 if (GTK_VALUE_BOOL (*arg))
298 gtk_container_block_resize (container);
300 gtk_container_unblock_resize (container);
303 gtk_container_add (container, GTK_WIDGET (GTK_VALUE_OBJECT (*arg)));
306 arg->type = GTK_TYPE_INVALID;
312 gtk_container_get_arg (GtkContainer *container,
318 case ARG_BORDER_WIDTH:
319 GTK_VALUE_LONG (*arg) = container->border_width;
321 case ARG_AUTO_RESIZE:
322 GTK_VALUE_BOOL (*arg) = container->auto_resize;
324 case ARG_BLOCK_RESIZE:
325 GTK_VALUE_BOOL (*arg) = container->block_resize;
328 arg->type = GTK_TYPE_INVALID;
334 gtk_container_border_width (GtkContainer *container,
337 g_return_if_fail (container != NULL);
338 g_return_if_fail (GTK_IS_CONTAINER (container));
340 if (container->border_width != border_width)
342 container->border_width = border_width;
344 if (GTK_WIDGET_REALIZED (container))
345 gtk_widget_queue_resize (GTK_WIDGET (container));
350 gtk_container_add (GtkContainer *container,
353 g_return_if_fail (container != NULL);
354 g_return_if_fail (GTK_IS_CONTAINER (container));
355 g_return_if_fail (widget != NULL);
356 g_return_if_fail (GTK_IS_WIDGET (widget));
357 g_return_if_fail (widget->parent == NULL);
359 gtk_signal_emit (GTK_OBJECT (container), container_signals[ADD], widget);
363 gtk_container_remove (GtkContainer *container,
366 g_return_if_fail (container != NULL);
367 g_return_if_fail (GTK_IS_CONTAINER (container));
368 g_return_if_fail (widget != NULL);
369 g_return_if_fail (GTK_IS_WIDGET (widget));
370 g_return_if_fail (widget->parent == GTK_WIDGET (container));
372 gtk_signal_emit (GTK_OBJECT (container), container_signals[REMOVE], widget);
376 gtk_container_disable_resize (GtkContainer *container)
378 g_return_if_fail (container != NULL);
379 g_return_if_fail (GTK_IS_CONTAINER (container));
381 container->auto_resize = FALSE;
385 gtk_container_enable_resize (GtkContainer *container)
387 g_return_if_fail (container != NULL);
388 g_return_if_fail (GTK_IS_CONTAINER (container));
390 container->auto_resize = TRUE;
391 if (container->need_resize)
393 container->need_resize = FALSE;
394 gtk_widget_queue_resize (GTK_WIDGET (container));
399 gtk_container_block_resize (GtkContainer *container)
401 g_return_if_fail (container != NULL);
402 g_return_if_fail (GTK_IS_CONTAINER (container));
404 container->block_resize = TRUE;
408 gtk_container_unblock_resize (GtkContainer *container)
410 g_return_if_fail (container != NULL);
411 g_return_if_fail (GTK_IS_CONTAINER (container));
413 container->block_resize = FALSE;
417 gtk_container_need_resize (GtkContainer *container)
421 g_return_val_if_fail (container != NULL, FALSE);
422 g_return_val_if_fail (GTK_IS_CONTAINER (container), FALSE);
426 if (!container->block_resize)
428 if (container->auto_resize)
429 gtk_signal_emit (GTK_OBJECT (container),
430 container_signals[NEED_RESIZE],
433 container->need_resize = TRUE;
440 gtk_container_foreach (GtkContainer *container,
441 GtkCallback callback,
442 gpointer callback_data)
444 g_return_if_fail (container != NULL);
445 g_return_if_fail (GTK_IS_CONTAINER (container));
446 g_return_if_fail (callback != NULL);
448 gtk_signal_emit (GTK_OBJECT (container),
449 container_signals[FOREACH],
450 callback, callback_data);
453 typedef struct _GtkForeachData GtkForeachData;
454 struct _GtkForeachData
456 GtkObject *container;
457 GtkCallbackMarshal callback;
458 gpointer callback_data;
462 gtk_container_foreach_unmarshal (GtkWidget *child,
465 GtkForeachData *fdata = (GtkForeachData*) data;
470 args[0].type = GTK_OBJECT(child)->klass->type;
471 GTK_VALUE_OBJECT(args[0]) = GTK_OBJECT (child);
473 /* location for return value */
475 args[1].type = GTK_TYPE_NONE;
477 fdata->callback (fdata->container, fdata->callback_data, 1, args);
481 gtk_container_foreach_interp (GtkContainer *container,
482 GtkCallbackMarshal marshal,
483 gpointer callback_data,
484 GtkDestroyNotify notify)
486 gtk_container_foreach_full (container, NULL, marshal,
487 callback_data, notify);
491 gtk_container_foreach_full (GtkContainer *container,
492 GtkCallback callback,
493 GtkCallbackMarshal marshal,
494 gpointer callback_data,
495 GtkDestroyNotify notify)
497 g_return_if_fail (container != NULL);
498 g_return_if_fail (GTK_IS_CONTAINER (container));
502 GtkForeachData fdata;
504 fdata.container = GTK_OBJECT (container);
505 fdata.callback = marshal;
506 fdata.callback_data = callback_data;
508 gtk_container_foreach (container, gtk_container_foreach_unmarshal, &fdata);
512 g_return_if_fail (callback != NULL);
514 gtk_container_foreach (container, callback, &callback_data);
518 notify (callback_data);
522 gtk_container_focus (GtkContainer *container,
523 GtkDirectionType direction)
527 g_return_val_if_fail (container != NULL, FALSE);
528 g_return_val_if_fail (GTK_IS_CONTAINER (container), FALSE);
530 gtk_signal_emit (GTK_OBJECT (container),
531 container_signals[FOCUS],
532 direction, &return_val);
538 gtk_container_set_focus_child (GtkContainer *container,
541 g_return_if_fail (container != NULL);
542 g_return_if_fail (GTK_IS_CONTAINER (container));
544 g_return_if_fail (GTK_IS_WIDGET (container));
546 gtk_signal_emit (GTK_OBJECT (container), container_signals[SET_FOCUS_CHILD], widget);
550 gtk_container_children (GtkContainer *container)
556 gtk_container_foreach (container,
557 gtk_container_children_callback,
560 return g_list_reverse (children);
564 gtk_container_register_toplevel (GtkContainer *container)
566 gtk_widget_ref (GTK_WIDGET (container));
567 gtk_object_sink (GTK_OBJECT (container));
571 gtk_container_unregister_toplevel (GtkContainer *container)
573 gtk_widget_unref (GTK_WIDGET (container));
577 gtk_container_real_set_focus_child (GtkContainer *container,
580 g_return_if_fail (container != NULL);
581 g_return_if_fail (GTK_IS_CONTAINER (container));
583 g_return_if_fail (GTK_IS_WIDGET (child));
585 if (child != container->focus_child)
587 if (container->focus_child)
588 gtk_widget_unref (container->focus_child);
589 container->focus_child = child;
590 if (container->focus_child)
591 gtk_widget_ref (container->focus_child);
595 /* check for h/v adjustments
597 if (container->focus_child)
599 GtkAdjustment *adjustment;
601 adjustment = gtk_object_get_data_by_id (GTK_OBJECT (container), vadjustment_key_id);
603 gtk_adjustment_clamp_page (adjustment,
604 container->focus_child->allocation.y,
605 (container->focus_child->allocation.y +
606 container->focus_child->allocation.height));
608 adjustment = gtk_object_get_data_by_id (GTK_OBJECT (container), hadjustment_key_id);
610 gtk_adjustment_clamp_page (adjustment,
611 container->focus_child->allocation.x,
612 (container->focus_child->allocation.x +
613 container->focus_child->allocation.width));
618 gtk_container_marshal_signal_1 (GtkObject *object,
623 GtkContainerSignal1 rfunc;
625 rfunc = (GtkContainerSignal1) func;
627 (* rfunc) (object, GTK_VALUE_OBJECT (args[0]), func_data);
631 gtk_container_marshal_signal_2 (GtkObject *object,
636 GtkContainerSignal2 rfunc;
638 rfunc = (GtkContainerSignal2) func;
641 GTK_VALUE_C_CALLBACK(args[0]).func,
642 GTK_VALUE_C_CALLBACK(args[0]).func_data,
647 gtk_container_marshal_signal_3 (GtkObject *object,
652 GtkContainerSignal3 rfunc;
655 rfunc = (GtkContainerSignal3) func;
656 return_val = GTK_RETLOC_ENUM (args[1]);
658 *return_val = (* rfunc) (object, GTK_VALUE_ENUM(args[0]), func_data);
662 gtk_container_marshal_signal_4 (GtkObject *object,
667 GtkContainerSignal4 rfunc;
670 rfunc = (GtkContainerSignal4) func;
671 return_val = GTK_RETLOC_BOOL (args[0]);
673 *return_val = (* rfunc) (object, func_data);
677 gtk_container_real_need_resize (GtkContainer *container)
679 g_return_val_if_fail (container != NULL, FALSE);
680 g_return_val_if_fail (GTK_IS_CONTAINER (container), FALSE);
682 if (GTK_WIDGET_VISIBLE (container) && container->widget.parent)
683 return gtk_container_need_resize (GTK_CONTAINER (container->widget.parent));
689 gtk_container_real_focus (GtkContainer *container,
690 GtkDirectionType direction)
697 g_return_val_if_fail (container != NULL, FALSE);
698 g_return_val_if_fail (GTK_IS_CONTAINER (container), FALSE);
700 /* Fail if the container is insensitive
702 if (!GTK_WIDGET_SENSITIVE (container))
707 if (GTK_WIDGET_CAN_FOCUS (container))
709 gtk_widget_grab_focus (GTK_WIDGET (container));
714 /* Get a list of the containers children
716 children = gtk_container_children (container);
720 /* Remove any children which are insensitive
725 if (!GTK_WIDGET_SENSITIVE (tmp_list->data))
727 tmp_list2 = tmp_list;
728 tmp_list = tmp_list->next;
730 children = g_list_remove_link (children, tmp_list2);
731 g_list_free_1 (tmp_list2);
734 tmp_list = tmp_list->next;
739 case GTK_DIR_TAB_FORWARD:
740 case GTK_DIR_TAB_BACKWARD:
741 return_val = gtk_container_focus_tab (container, children, direction);
745 return_val = gtk_container_focus_up_down (container, children, direction);
749 return_val = gtk_container_focus_left_right (container, children, direction);
753 g_list_free (children);
761 gtk_container_focus_tab (GtkContainer *container,
763 GtkDirectionType direction)
771 length = g_list_length (children);
773 /* sort the children in the y direction */
774 for (i = 1; i < length; i++)
777 tmp_list = g_list_nth (children, j);
778 child = tmp_list->data;
782 child2 = tmp_list->prev->data;
783 if (child->allocation.y < child2->allocation.y)
785 tmp_list->data = tmp_list->prev->data;
786 tmp_list = tmp_list->prev;
793 tmp_list->data = child;
796 /* sort the children in the x direction while
797 * maintaining the y direction sort.
799 for (i = 1; i < length; i++)
802 tmp_list = g_list_nth (children, j);
803 child = tmp_list->data;
807 child2 = tmp_list->prev->data;
808 if ((child->allocation.x < child2->allocation.x) &&
809 (child->allocation.y == child2->allocation.y))
811 tmp_list->data = tmp_list->prev->data;
812 tmp_list = tmp_list->prev;
819 tmp_list->data = child;
822 /* if we are going backwards then reverse the order
825 if (direction == GTK_DIR_TAB_BACKWARD)
826 children = g_list_reverse (children);
828 return gtk_container_focus_move (container, children, direction);
832 gtk_container_focus_up_down (GtkContainer *container,
834 GtkDirectionType direction)
845 /* return failure if there isn't a focus child */
846 if (container->focus_child)
848 focus_width = container->focus_child->allocation.width / 2;
849 focus_x = container->focus_child->allocation.x + focus_width;
853 focus_width = GTK_WIDGET (container)->allocation.width;
854 if (GTK_WIDGET_NO_WINDOW (container))
855 focus_x = GTK_WIDGET (container)->allocation.x;
860 length = g_list_length (children);
862 /* sort the children in the y direction */
863 for (i = 1; i < length; i++)
866 tmp_list = g_list_nth (children, j);
867 child = tmp_list->data;
871 child2 = tmp_list->prev->data;
872 if (child->allocation.y < child2->allocation.y)
874 tmp_list->data = tmp_list->prev->data;
875 tmp_list = tmp_list->prev;
882 tmp_list->data = child;
885 /* sort the children in distance in the x direction
886 * in distance from the current focus child while maintaining the
887 * sort in the y direction
889 for (i = 1; i < length; i++)
892 tmp_list = g_list_nth (children, j);
893 child = tmp_list->data;
894 dist1 = (child->allocation.x + child->allocation.width / 2) - focus_x;
898 child2 = tmp_list->prev->data;
899 dist2 = (child2->allocation.x + child2->allocation.width / 2) - focus_x;
901 if ((dist1 < dist2) &&
902 (child->allocation.y >= child2->allocation.y))
904 tmp_list->data = tmp_list->prev->data;
905 tmp_list = tmp_list->prev;
912 tmp_list->data = child;
915 /* go and invalidate any widget which is too
916 * far from the focus widget.
918 if (!container->focus_child &&
919 (direction == GTK_DIR_UP))
920 focus_x += focus_width;
925 child = tmp_list->data;
927 dist1 = (child->allocation.x + child->allocation.width / 2) - focus_x;
928 if (((direction == GTK_DIR_DOWN) && (dist1 < 0)) ||
929 ((direction == GTK_DIR_UP) && (dist1 > 0)))
930 tmp_list->data = NULL;
932 tmp_list = tmp_list->next;
935 if (direction == GTK_DIR_UP)
936 children = g_list_reverse (children);
938 return gtk_container_focus_move (container, children, direction);
942 gtk_container_focus_left_right (GtkContainer *container,
944 GtkDirectionType direction)
955 /* return failure if there isn't a focus child */
956 if (container->focus_child)
958 focus_height = container->focus_child->allocation.height / 2;
959 focus_y = container->focus_child->allocation.y + focus_height;
963 focus_height = GTK_WIDGET (container)->allocation.height;
964 if (GTK_WIDGET_NO_WINDOW (container))
965 focus_y = GTK_WIDGET (container)->allocation.y;
970 length = g_list_length (children);
972 /* sort the children in the x direction */
973 for (i = 1; i < length; i++)
976 tmp_list = g_list_nth (children, j);
977 child = tmp_list->data;
981 child2 = tmp_list->prev->data;
982 if (child->allocation.x < child2->allocation.x)
984 tmp_list->data = tmp_list->prev->data;
985 tmp_list = tmp_list->prev;
992 tmp_list->data = child;
995 /* sort the children in distance in the y direction
996 * in distance from the current focus child while maintaining the
997 * sort in the x direction
999 for (i = 1; i < length; i++)
1002 tmp_list = g_list_nth (children, j);
1003 child = tmp_list->data;
1004 dist1 = (child->allocation.y + child->allocation.height / 2) - focus_y;
1008 child2 = tmp_list->prev->data;
1009 dist2 = (child2->allocation.y + child2->allocation.height / 2) - focus_y;
1011 if ((dist1 < dist2) &&
1012 (child->allocation.x >= child2->allocation.x))
1014 tmp_list->data = tmp_list->prev->data;
1015 tmp_list = tmp_list->prev;
1022 tmp_list->data = child;
1025 /* go and invalidate any widget which is too
1026 * far from the focus widget.
1028 if (!container->focus_child &&
1029 (direction == GTK_DIR_LEFT))
1030 focus_y += focus_height;
1032 tmp_list = children;
1035 child = tmp_list->data;
1037 dist1 = (child->allocation.y + child->allocation.height / 2) - focus_y;
1038 if (((direction == GTK_DIR_RIGHT) && (dist1 < 0)) ||
1039 ((direction == GTK_DIR_LEFT) && (dist1 > 0)))
1040 tmp_list->data = NULL;
1042 tmp_list = tmp_list->next;
1045 if (direction == GTK_DIR_LEFT)
1046 children = g_list_reverse (children);
1048 return gtk_container_focus_move (container, children, direction);
1052 gtk_container_focus_move (GtkContainer *container,
1054 GtkDirectionType direction)
1056 GtkWidget *focus_child;
1059 focus_child = container->focus_child;
1060 gtk_container_set_focus_child (container, NULL);
1064 child = children->data;
1065 children = children->next;
1072 if (focus_child == child)
1076 if (GTK_WIDGET_VISIBLE (child) &&
1077 GTK_IS_CONTAINER (child) &&
1078 !GTK_WIDGET_HAS_FOCUS (child))
1079 if (gtk_container_focus (GTK_CONTAINER (child), direction))
1083 else if (GTK_WIDGET_VISIBLE (child))
1085 if (GTK_IS_CONTAINER (child))
1087 if (gtk_container_focus (GTK_CONTAINER (child), direction))
1090 else if (GTK_WIDGET_CAN_FOCUS (child))
1092 gtk_widget_grab_focus (child);
1103 gtk_container_children_callback (GtkWidget *widget,
1104 gpointer client_data)
1108 children = (GList**) client_data;
1109 *children = g_list_prepend (*children, widget);
1113 gtk_container_show_all (GtkWidget *widget)
1115 GtkContainer *container;
1117 g_return_if_fail (widget != NULL);
1118 g_return_if_fail (GTK_IS_CONTAINER (widget));
1119 container = GTK_CONTAINER (widget);
1121 /* First show children, then self.
1122 This makes sure that toplevel windows get shown as last widget.
1123 Otherwise the user would see the widgets get
1124 visible one after another.
1126 gtk_container_foreach (container, (GtkCallback) gtk_widget_show_all, NULL);
1127 gtk_widget_show (widget);
1132 gtk_container_hide_all (GtkWidget *widget)
1134 GtkContainer *container;
1136 g_return_if_fail (widget != NULL);
1137 g_return_if_fail (GTK_IS_CONTAINER (widget));
1138 container = GTK_CONTAINER (widget);
1140 /* First hide self, then children.
1141 This is the reverse order of gtk_container_show_all.
1143 gtk_widget_hide (widget);
1144 gtk_container_foreach (container, (GtkCallback) gtk_widget_hide_all, NULL);
1148 gtk_container_set_focus_vadjustment (GtkContainer *container,
1149 GtkAdjustment *adjustment)
1151 g_return_if_fail (container != NULL);
1152 g_return_if_fail (GTK_IS_CONTAINER (container));
1154 g_return_if_fail (GTK_IS_ADJUSTMENT (adjustment));
1157 gtk_object_ref (GTK_OBJECT(adjustment));
1159 gtk_object_set_data_by_id_full (GTK_OBJECT (container),
1162 (GtkDestroyNotify) gtk_object_unref);
1166 gtk_container_set_focus_hadjustment (GtkContainer *container,
1167 GtkAdjustment *adjustment)
1169 g_return_if_fail (container != NULL);
1170 g_return_if_fail (GTK_IS_CONTAINER (container));
1172 g_return_if_fail (GTK_IS_ADJUSTMENT (adjustment));
1175 gtk_object_ref (GTK_OBJECT (adjustment));
1177 gtk_object_set_data_by_id_full (GTK_OBJECT (container),
1180 (GtkDestroyNotify) gtk_object_unref);