⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 gtkcustom.c

📁 实现树形结构
💻 C
字号:
// custom container
// A simple container where size_request and size_allocate are left
// to the signal handlers

#include "gtkcustom.h"

static void gtk_custom_class_init    (GtkCustomClass    *klass);
static void gtk_custom_init          (GtkCustom         *custom);
static void gtk_custom_realize       (GtkWidget        *widget);
static void gtk_custom_add           (GtkContainer     *container,
				     GtkWidget        *widget);
static void gtk_custom_remove        (GtkContainer     *container,
				     GtkWidget        *widget);
static void gtk_custom_forall        (GtkContainer     *container,
				     gboolean 	       include_internals,
				     GtkCallback       callback,
				     gpointer          callback_data);
static GtkType gtk_custom_child_type (GtkContainer     *container);


static GtkContainerClass *parent_class = NULL;

///////////////////////////////////////////////////////////////////////////////
// type access
///////////////////////////////////////////////////////////////////////////////
GtkType gtk_custom_get_type (void)
{
	static GtkType custom_type = 0;
	
	if (!custom_type)
	{
		static const GtkTypeInfo custom_info =
		{
			"GtkCustom",
			sizeof (GtkCustom),
			sizeof (GtkCustomClass),
			(GtkClassInitFunc) gtk_custom_class_init,
			(GtkObjectInitFunc) gtk_custom_init,
			/* reserved_1 */ NULL,
			/* reserved_2 */ NULL,
			(GtkClassInitFunc) NULL,
		};
		
		custom_type = gtk_type_unique (GTK_TYPE_CONTAINER, &custom_info);
	}
	
	return custom_type;
}

///////////////////////////////////////////////////////////////////////////////
// Class Initialization
///////////////////////////////////////////////////////////////////////////////
static void gtk_custom_class_init (GtkCustomClass *class)
{
	GtkObjectClass *object_class;
	GtkWidgetClass *widget_class;
	GtkContainerClass *container_class;
	
	object_class = (GtkObjectClass*) class;
	widget_class = (GtkWidgetClass*) class;
	container_class = (GtkContainerClass*) class;
	
	parent_class = gtk_type_class (GTK_TYPE_CONTAINER);
	
	widget_class->realize = gtk_custom_realize;
	
	container_class->add = gtk_custom_add;
	container_class->remove = gtk_custom_remove;
	container_class->forall = gtk_custom_forall;
	container_class->child_type = gtk_custom_child_type;
}

///////////////////////////////////////////////////////////////////////////////
// return child type
///////////////////////////////////////////////////////////////////////////////
static GtkType gtk_custom_child_type (GtkContainer *container)
{
	return GTK_TYPE_WIDGET;
}

///////////////////////////////////////////////////////////////////////////////
// initialize
///////////////////////////////////////////////////////////////////////////////
static void gtk_custom_init (GtkCustom *custom)
{
	GTK_WIDGET_UNSET_FLAGS (custom, GTK_NO_WINDOW);
	custom->children = NULL;
}

///////////////////////////////////////////////////////////////////////////////
// instance creation
///////////////////////////////////////////////////////////////////////////////
GtkWidget* gtk_custom_new (void)
{
	return GTK_WIDGET (gtk_type_new (GTK_TYPE_CUSTOM));
}

///////////////////////////////////////////////////////////////////////////////
// realize
///////////////////////////////////////////////////////////////////////////////
static void gtk_custom_realize (GtkWidget *widget)
{
	GdkWindowAttr attributes;
	gint attributes_mask;
	
	GTK_WIDGET_SET_FLAGS (widget, GTK_REALIZED);
	
	attributes.window_type = GDK_WINDOW_CHILD;
	attributes.x = widget->allocation.x;
	attributes.y = widget->allocation.y;
	attributes.width = widget->allocation.width;
	attributes.height = widget->allocation.height;
	attributes.wclass = GDK_INPUT_OUTPUT;
	attributes.visual = gtk_widget_get_visual (widget);
	attributes.colormap = gtk_widget_get_colormap (widget);
	attributes.event_mask = gtk_widget_get_events (widget);
	attributes.event_mask |= GDK_EXPOSURE_MASK | GDK_BUTTON_PRESS_MASK;
	
	attributes_mask = GDK_WA_X | GDK_WA_Y | GDK_WA_VISUAL | GDK_WA_COLORMAP | GDK_WA_WMCLASS;
	
	widget->window = gdk_window_new (gtk_widget_get_parent_window (widget), &attributes, 
				   attributes_mask);
	gdk_window_set_user_data (widget->window, widget);
	
	widget->style = gtk_style_attach (widget->style, widget->window);
	gtk_style_set_background (widget->style, widget->window, GTK_STATE_NORMAL);
	gdk_window_set_back_pixmap (widget->window, NULL, FALSE);
}

///////////////////////////////////////////////////////////////////////////////
// add
///////////////////////////////////////////////////////////////////////////////
static void gtk_custom_add (GtkContainer *container, GtkWidget *widget)
{
	GtkCustom* custom;
	GtkCustomChild *child_info;
	
	g_return_if_fail (GTK_IS_CUSTOM (container));
	g_return_if_fail (GTK_IS_WIDGET (widget));
	
	custom = GTK_CUSTOM (container);
	
	child_info = g_new (GtkCustomChild, 1);
	child_info->widget = widget;
	
	gtk_widget_set_parent (widget, GTK_WIDGET (custom));
	
	custom->children = g_list_append (custom->children, child_info);
}

///////////////////////////////////////////////////////////////////////////////
// remove
///////////////////////////////////////////////////////////////////////////////
static void gtk_custom_remove (GtkContainer *container, GtkWidget *widget)
{
	GtkCustom *custom;
	GtkCustomChild *child;
	GList *children;
	
	custom = GTK_CUSTOM (container);
	
	children = custom->children;
	while (children)
	{
		child = children->data;
		
		if (child->widget == widget)
		{
			gboolean was_visible = GTK_WIDGET_VISIBLE (widget);
			
			gtk_widget_unparent (widget);
			
			custom->children = g_list_remove_link (custom->children, children);
			g_list_free (children);
			g_free (child);
			
			if (was_visible && GTK_WIDGET_VISIBLE (container))
			gtk_widget_queue_resize (GTK_WIDGET (container));
			
			break;
		}
		
		children = children->next;
	}
}

///////////////////////////////////////////////////////////////////////////////
// forall
///////////////////////////////////////////////////////////////////////////////
static void gtk_custom_forall (GtkContainer *container,
		  gboolean	include_internals,
		  GtkCallback   callback,
		  gpointer      callback_data)
{
	GtkCustom *custom;
	GtkCustomChild *child;
	GList *children;
	
	g_return_if_fail (callback != NULL);
	
	custom = GTK_CUSTOM (container);
	
	children = custom->children;
	while (children)
	{
		child = children->data;
		children = children->next;
		(* callback) (child->widget, callback_data);
	}
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -