📄 gtkcontainer.c
字号:
/* GTK - The GIMP Toolkit * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Library General Public License for more details. * * You should have received a copy of the GNU Library General Public * License along with this library; if not, write to the * Free Software Foundation, Inc., 59 Temple Place - Suite 330, * Boston, MA 02111-1307, USA. *//* * Modified by the GTK+ Team and others 1997-1999. See the AUTHORS * file for a list of people on the GTK+ Team. See the ChangeLog * files for a list of changes. These files are distributed with * GTK+ at ftp://ftp.gtk.org/pub/gtk/. */#include <string.h>#include "gtkcontainer.h"#include "gtkprivate.h"#include "gtksignal.h"#include "gtkmain.h"#include <stdarg.h>enum { ADD, REMOVE, CHECK_RESIZE, FOCUS, SET_FOCUS_CHILD, LAST_SIGNAL};enum { ARG_0, ARG_BORDER_WIDTH, ARG_RESIZE_MODE, ARG_CHILD, ARG_REALLOCATE_REDRAWS};typedef struct _GtkChildArgInfo GtkChildArgInfo;struct _GtkChildArgInfo{ gchar *name; GtkType type; GtkType class_type; guint arg_flags; guint arg_id; guint seq_id;};/* The global list of toplevel windows */static GList *toplevel_list = NULL;static void gtk_container_base_class_init (GtkContainerClass *klass);static void gtk_container_class_init (GtkContainerClass *klass);static void gtk_container_init (GtkContainer *container);static void gtk_container_destroy (GtkObject *object);static void gtk_container_get_arg (GtkObject *object, GtkArg *arg, guint arg_id);static void gtk_container_set_arg (GtkObject *object, GtkArg *arg, guint arg_id);static void gtk_container_add_unimplemented (GtkContainer *container, GtkWidget *widget);static void gtk_container_remove_unimplemented (GtkContainer *container, GtkWidget *widget);static void gtk_container_real_check_resize (GtkContainer *container);static gint gtk_container_real_focus (GtkContainer *container, GtkDirectionType direction);static void gtk_container_real_set_focus_child (GtkContainer *container, GtkWidget *widget);static gint gtk_container_focus_tab (GtkContainer *container, GList *children, GtkDirectionType direction);static gint gtk_container_focus_up_down (GtkContainer *container, GList *children, GtkDirectionType direction);static gint gtk_container_focus_left_right (GtkContainer *container, GList *children, GtkDirectionType direction);static gint gtk_container_focus_move (GtkContainer *container, GList *children, GtkDirectionType direction);static void gtk_container_children_callback (GtkWidget *widget, gpointer client_data);static void gtk_container_show_all (GtkWidget *widget);static void gtk_container_hide_all (GtkWidget *widget);static gchar* gtk_container_child_default_composite_name (GtkContainer *container, GtkWidget *child);static guint container_signals[LAST_SIGNAL] = { 0 };static GHashTable *container_child_arg_info_ht = NULL;static GtkWidgetClass *parent_class = NULL;static const gchar *vadjustment_key = "gtk-vadjustment";static guint vadjustment_key_id = 0;static const gchar *hadjustment_key = "gtk-hadjustment";static guint hadjustment_key_id = 0;static GSList *container_resize_queue = NULL;GtkTypegtk_container_get_type (void){ static GtkType container_type = 0; if (!container_type) { static const GtkTypeInfo container_info = { "GtkContainer", sizeof (GtkContainer), sizeof (GtkContainerClass), (GtkClassInitFunc) gtk_container_class_init, (GtkObjectInitFunc) gtk_container_init, /* reserved_1 */ NULL, /* reserved_2 */ NULL, (GtkClassInitFunc) gtk_container_base_class_init, }; container_type = gtk_type_unique (gtk_widget_get_type (), &container_info); } return container_type;}static voidgtk_container_base_class_init (GtkContainerClass *class){ /* reset instance specifc class fields that don't get inherited */ class->n_child_args = 0; class->set_child_arg = NULL; class->get_child_arg = NULL;}static voidgtk_container_class_init (GtkContainerClass *class){ GtkObjectClass *object_class; GtkWidgetClass *widget_class; object_class = (GtkObjectClass*) class; widget_class = (GtkWidgetClass*) class; parent_class = gtk_type_class (gtk_widget_get_type ()); container_child_arg_info_ht = g_hash_table_new (gtk_arg_info_hash, gtk_arg_info_equal); vadjustment_key_id = g_quark_from_static_string (vadjustment_key); hadjustment_key_id = g_quark_from_static_string (hadjustment_key); gtk_object_add_arg_type ("GtkContainer::border_width", GTK_TYPE_ULONG, GTK_ARG_READWRITE, ARG_BORDER_WIDTH); gtk_object_add_arg_type ("GtkContainer::resize_mode", GTK_TYPE_RESIZE_MODE, GTK_ARG_READWRITE, ARG_RESIZE_MODE); gtk_object_add_arg_type ("GtkContainer::child", GTK_TYPE_WIDGET, GTK_ARG_WRITABLE, ARG_CHILD); gtk_object_add_arg_type ("GtkContainer::reallocate_redraws", GTK_TYPE_BOOL, GTK_ARG_READWRITE, ARG_REALLOCATE_REDRAWS); container_signals[ADD] = gtk_signal_new ("add", GTK_RUN_FIRST, object_class->type, GTK_SIGNAL_OFFSET (GtkContainerClass, add), gtk_marshal_NONE__POINTER, GTK_TYPE_NONE, 1, GTK_TYPE_WIDGET); container_signals[REMOVE] = gtk_signal_new ("remove", GTK_RUN_FIRST, object_class->type, GTK_SIGNAL_OFFSET (GtkContainerClass, remove), gtk_marshal_NONE__POINTER, GTK_TYPE_NONE, 1, GTK_TYPE_WIDGET); container_signals[CHECK_RESIZE] = gtk_signal_new ("check_resize", GTK_RUN_LAST, object_class->type, GTK_SIGNAL_OFFSET (GtkContainerClass, check_resize), gtk_marshal_NONE__NONE, GTK_TYPE_NONE, 0); container_signals[FOCUS] = gtk_signal_new ("focus", GTK_RUN_LAST, object_class->type, GTK_SIGNAL_OFFSET (GtkContainerClass, focus), gtk_marshal_ENUM__ENUM, GTK_TYPE_DIRECTION_TYPE, 1, GTK_TYPE_DIRECTION_TYPE); container_signals[SET_FOCUS_CHILD] = gtk_signal_new ("set-focus-child", GTK_RUN_FIRST, object_class->type, GTK_SIGNAL_OFFSET (GtkContainerClass, set_focus_child), gtk_marshal_NONE__POINTER, GTK_TYPE_NONE, 1, GTK_TYPE_WIDGET); gtk_object_class_add_signals (object_class, container_signals, LAST_SIGNAL); object_class->get_arg = gtk_container_get_arg; object_class->set_arg = gtk_container_set_arg; object_class->destroy = gtk_container_destroy; widget_class->show_all = gtk_container_show_all; widget_class->hide_all = gtk_container_hide_all; class->add = gtk_container_add_unimplemented; class->remove = gtk_container_remove_unimplemented; class->check_resize = gtk_container_real_check_resize; class->forall = NULL; class->focus = gtk_container_real_focus; class->set_focus_child = gtk_container_real_set_focus_child; class->child_type = NULL; class->composite_name = gtk_container_child_default_composite_name;}GtkTypegtk_container_child_type (GtkContainer *container){ GtkType slot; GtkContainerClass *class; g_return_val_if_fail (container != NULL, 0); g_return_val_if_fail (GTK_IS_CONTAINER (container), 0); class = GTK_CONTAINER_CLASS (GTK_OBJECT (container)->klass); if (class->child_type) slot = class->child_type (container); else slot = GTK_TYPE_NONE; return slot;}/**************************************************** * GtkContainer child argument mechanism * ****************************************************/voidgtk_container_add_with_args (GtkContainer *container, GtkWidget *widget, const gchar *first_arg_name, ...){ g_return_if_fail (container != NULL); g_return_if_fail (GTK_IS_CONTAINER (container)); g_return_if_fail (widget != NULL); g_return_if_fail (GTK_IS_WIDGET (widget)); g_return_if_fail (widget->parent == NULL); gtk_widget_ref (GTK_WIDGET (container)); gtk_widget_ref (widget); if (!GTK_OBJECT_CONSTRUCTED (widget)) gtk_object_default_construct (GTK_OBJECT (widget)); gtk_signal_emit (GTK_OBJECT (container), container_signals[ADD], widget); if (widget->parent) { va_list var_args; GSList *arg_list = NULL; GSList *info_list = NULL; gchar *error; va_start (var_args, first_arg_name); error = gtk_container_child_args_collect (GTK_OBJECT_TYPE (container), &arg_list, &info_list, first_arg_name, var_args); va_end (var_args); if (error) { g_warning ("gtk_container_add_with_args(): %s", error); g_free (error); } else { GSList *slist_arg; GSList *slist_info; slist_arg = arg_list; slist_info = info_list; while (slist_arg) { gtk_container_arg_set (container, widget, slist_arg->data, slist_info->data); slist_arg = slist_arg->next; slist_info = slist_info->next; } gtk_args_collect_cleanup (arg_list, info_list); } } gtk_widget_unref (widget); gtk_widget_unref (GTK_WIDGET (container));}voidgtk_container_addv (GtkContainer *container, GtkWidget *widget, guint n_args, GtkArg *args){ g_return_if_fail (container != NULL); g_return_if_fail (GTK_IS_CONTAINER (container)); g_return_if_fail (widget != NULL); g_return_if_fail (GTK_IS_WIDGET (widget)); g_return_if_fail (widget->parent == NULL); gtk_widget_ref (GTK_WIDGET (container)); gtk_widget_ref (widget); if (!GTK_OBJECT_CONSTRUCTED (widget)) gtk_object_default_construct (GTK_OBJECT (widget)); gtk_signal_emit (GTK_OBJECT (container), container_signals[ADD], widget); if (widget->parent) { GtkArg *max_args; for (max_args = args + n_args; args < max_args; args++) gtk_container_arg_set (container, widget, args, NULL); } gtk_widget_unref (widget); gtk_widget_unref (GTK_WIDGET (container));}voidgtk_container_child_setv (GtkContainer *container, GtkWidget *child, guint n_args, GtkArg *args){ GtkArg *max_args; g_return_if_fail (container != NULL); g_return_if_fail (GTK_IS_CONTAINER (container)); g_return_if_fail (child != NULL); g_return_if_fail (GTK_IS_WIDGET (child)); g_return_if_fail (child->parent != NULL); if (n_args) g_return_if_fail (args != NULL); for (max_args = args + n_args; args < max_args; args++) gtk_container_arg_set (container, child, args, NULL);}voidgtk_container_child_getv (GtkContainer *container, GtkWidget *child, guint n_args, GtkArg *args){ GtkArg *max_args; g_return_if_fail (container != NULL); g_return_if_fail (GTK_IS_CONTAINER (container)); g_return_if_fail (child != NULL); g_return_if_fail (GTK_IS_WIDGET (child)); g_return_if_fail (child->parent != NULL); if (n_args) g_return_if_fail (args != NULL); for (max_args = args + n_args; args < max_args; args++) gtk_container_arg_get (container, child, args, NULL);}voidgtk_container_child_set (GtkContainer *container, GtkWidget *child, const gchar *first_arg_name, ...){ va_list var_args; GSList *arg_list = NULL; GSList *info_list = NULL; gchar *error; g_return_if_fail (container != NULL); g_return_if_fail (GTK_IS_CONTAINER (container)); g_return_if_fail (child != NULL); g_return_if_fail (GTK_IS_WIDGET (child)); g_return_if_fail (child->parent != NULL); va_start (var_args, first_arg_name); error = gtk_container_child_args_collect (GTK_OBJECT_TYPE (container), &arg_list, &info_list, first_arg_name, var_args); va_end (var_args); if (error) { g_warning ("gtk_container_child_set(): %s", error); g_free (error); } else { GSList *slist_arg; GSList *slist_info; slist_arg = arg_list; slist_info = info_list; while (slist_arg) { gtk_container_arg_set (container, child, slist_arg->data, slist_info->data); slist_arg = slist_arg->next; slist_info = slist_info->next; } gtk_args_collect_cleanup (arg_list, info_list); }}voidgtk_container_arg_set (GtkContainer *container, GtkWidget *child, GtkArg *arg, GtkArgInfo *info){ GtkContainerClass *class; g_return_if_fail (container != NULL); g_return_if_fail (GTK_IS_CONTAINER (container)); g_return_if_fail (child != NULL); g_return_if_fail (GTK_IS_WIDGET (child)); g_return_if_fail (arg != NULL); if (!info) { gchar *error; error = gtk_arg_get_info (GTK_OBJECT_TYPE (container), container_child_arg_info_ht, arg->name, &info); if (error) { g_warning ("gtk_container_arg_set(): %s", error); g_free (error); return; } } g_return_if_fail (info->arg_flags & GTK_ARG_CHILD_ARG); if (! (info->arg_flags & GTK_ARG_WRITABLE)) { g_warning ("gtk_container_arg_set(): argument \"%s\" is not writable", info->full_name); return; } if (info->type != arg->type)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -