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

📄 dw_widget.c

📁 微型浏览器
💻 C
📖 第 1 页 / 共 2 页
字号:
/* * File: dw_widget.c * * Copyright (C) 2001 Sebastian Geerken <S.Geerken@ping.de> *  * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. */#include <gtk/gtk.h>#include "dw_widget.h"#include "dw_container.h"#include "dw_gtk_viewport.h"static void Dw_widget_init(DwWidget * widget);static void Dw_widget_class_init(DwWidgetClass * klass);static void Dw_widget_shutdown(GtkObject * object);static void Dw_widget_destroy(GtkObject * object);static void Dw_widget_real_size_request(DwWidget * widget, DwRequisition * requisition);static void Dw_widget_real_size_allocate(DwWidget * widget, DwAllocation * allocation);static void Dw_widget_real_set_width(DwWidget * widget, gint32 width);static void Dw_widget_real_set_ascent(DwWidget * widget, gint32 ascent);static void Dw_widget_real_set_descent(DwWidget * widget, gint32 descent);static void Dw_widget_real_draw(DwWidget * widget, DwRectangle * area, GdkEventExpose * event);static void Dw_widget_real_realize(DwWidget * widget);static void Dw_widget_real_unrealize(DwWidget * widget);static gint Dw_widget_real_button_press(DwWidget * widget, gint32 x, gint32 y, GdkEventButton * event);static gint Dw_widget_real_button_release(DwWidget * widget, gint32 x, gint32 y, GdkEventButton * event);static gint Dw_widget_real_motion_notify(DwWidget * widget, gint32 x, gint32 y, GdkEventMotion * event);static gint Dw_widget_real_enter_notify(DwWidget * widget, GdkEventMotion * event);static gint Dw_widget_real_leave_notify(DwWidget * widget, GdkEventMotion * event);static void Dw_widget_update_cursor(DwWidget * widget);enum {	SIZE_REQUEST,	SIZE_ALLOCATE,	SET_WIDTH,	SET_ASCENT,	SET_DESCENT,	DRAW,	REALIZE,	UNREALIZE,	BUTTON_PRESS_EVENT,	BUTTON_RELEASE_EVENT,	MOTION_NOTIFY_EVENT,	ENTER_NOTIFY_EVENT,	LEAVE_NOTIFY_EVENT,	LAST_SIGNAL};static GtkObjectClass *parent_class;static guint widget_signals[LAST_SIGNAL] = { 0 };/* * Standard Gtk+ function */GtkType a_Dw_widget_get_type(void){	static GtkType type = 0;	if (!type) {		GtkTypeInfo info = {			"DwWidget",			sizeof(DwWidget),			sizeof(DwWidgetClass),			(GtkClassInitFunc) Dw_widget_class_init,			(GtkObjectInitFunc) Dw_widget_init,			(GtkArgSetFunc) NULL,			(GtkArgGetFunc) NULL,		};		type = gtk_type_unique(GTK_TYPE_OBJECT, &info);	}	return type;}/* * Standard Gtk+ function */static void Dw_widget_init(DwWidget * widget){	widget->flags = DW_NEEDS_RESIZE;	widget->parent = NULL;	widget->viewport = NULL;	widget->allocation.x = -1;	widget->allocation.y = -1;	widget->allocation.width = 1;	widget->allocation.ascent = 1;	widget->allocation.descent = 0;	widget->user_requisition.width = -1;	widget->user_requisition.ascent = -1;	widget->user_requisition.descent = -1;	/* todo: comment */	widget->anchors_table = NULL;	widget->cursor = NULL;	widget->style = NULL;}/* * Standard Gtk+ function */static void Dw_widget_class_init(DwWidgetClass * klass){	GtkObjectClass *object_class;	parent_class = gtk_type_class(gtk_object_get_type());	object_class = GTK_OBJECT_CLASS(klass);	widget_signals[SIZE_REQUEST] = gtk_signal_new("size_request", GTK_RUN_FIRST, object_class->type, GTK_SIGNAL_OFFSET(DwWidgetClass, size_request), gtk_marshal_NONE__POINTER, GTK_TYPE_NONE, 1, GTK_TYPE_POINTER);	widget_signals[SIZE_ALLOCATE] = gtk_signal_new("size_allocate", GTK_RUN_FIRST, object_class->type, GTK_SIGNAL_OFFSET(DwWidgetClass, size_allocate), gtk_marshal_NONE__POINTER, GTK_TYPE_NONE, 1, GTK_TYPE_POINTER);	widget_signals[SET_WIDTH] = gtk_signal_new("set_width", GTK_RUN_FIRST, object_class->type, GTK_SIGNAL_OFFSET(DwWidgetClass, set_width), gtk_marshal_NONE__POINTER, GTK_TYPE_NONE, 1, GTK_TYPE_UINT);	widget_signals[SET_ASCENT] = gtk_signal_new("set_ascent", GTK_RUN_FIRST, object_class->type, GTK_SIGNAL_OFFSET(DwWidgetClass, set_ascent), gtk_marshal_NONE__POINTER, GTK_TYPE_NONE, 1, GTK_TYPE_UINT);	widget_signals[SET_DESCENT] = gtk_signal_new("set_descent", GTK_RUN_FIRST, object_class->type, GTK_SIGNAL_OFFSET(DwWidgetClass, set_descent), gtk_marshal_NONE__POINTER, GTK_TYPE_NONE, 1, GTK_TYPE_UINT);	widget_signals[DRAW] = gtk_signal_new("draw", GTK_RUN_FIRST, object_class->type, GTK_SIGNAL_OFFSET(DwWidgetClass, draw), gtk_marshal_NONE__POINTER, GTK_TYPE_NONE, 2, GTK_TYPE_POINTER, GTK_TYPE_GDK_EVENT);	widget_signals[REALIZE] = gtk_signal_new("realize", GTK_RUN_FIRST, object_class->type, GTK_SIGNAL_OFFSET(DwWidgetClass, realize), gtk_marshal_NONE__NONE, GTK_TYPE_NONE, 0);	widget_signals[UNREALIZE] = gtk_signal_new("unrealize", GTK_RUN_FIRST, object_class->type, GTK_SIGNAL_OFFSET(DwWidgetClass, unrealize), gtk_marshal_NONE__NONE, GTK_TYPE_NONE, 0);	widget_signals[BUTTON_PRESS_EVENT] = gtk_signal_new("button_press_event", GTK_RUN_LAST, object_class->type, GTK_SIGNAL_OFFSET(DwWidgetClass, button_press_event), gtk_marshal_BOOL__POINTER, GTK_TYPE_BOOL, 3, GTK_TYPE_UINT, GTK_TYPE_UINT, GTK_TYPE_GDK_EVENT);	widget_signals[BUTTON_RELEASE_EVENT] = gtk_signal_new("button_release_event", GTK_RUN_LAST, object_class->type, GTK_SIGNAL_OFFSET(DwWidgetClass, button_release_event), gtk_marshal_BOOL__POINTER, GTK_TYPE_BOOL, 3, GTK_TYPE_UINT, GTK_TYPE_UINT, GTK_TYPE_GDK_EVENT);	widget_signals[MOTION_NOTIFY_EVENT] = gtk_signal_new("motion_notify_event", GTK_RUN_LAST, object_class->type, GTK_SIGNAL_OFFSET(DwWidgetClass, motion_notify_event), gtk_marshal_BOOL__POINTER, GTK_TYPE_BOOL, 3, GTK_TYPE_UINT, GTK_TYPE_UINT, GTK_TYPE_GDK_EVENT);	widget_signals[ENTER_NOTIFY_EVENT] = gtk_signal_new("enter_notify_event", GTK_RUN_LAST, object_class->type, GTK_SIGNAL_OFFSET(DwWidgetClass, enter_notify_event), gtk_marshal_BOOL__POINTER, GTK_TYPE_BOOL, 3, GTK_TYPE_UINT, GTK_TYPE_UINT, GTK_TYPE_GDK_EVENT);	widget_signals[LEAVE_NOTIFY_EVENT] = gtk_signal_new("leave_notify_event", GTK_RUN_LAST, object_class->type, GTK_SIGNAL_OFFSET(DwWidgetClass, leave_notify_event), gtk_marshal_BOOL__POINTER, GTK_TYPE_BOOL, 3, GTK_TYPE_UINT, GTK_TYPE_UINT, GTK_TYPE_GDK_EVENT);	object_class->shutdown = Dw_widget_shutdown;	object_class->destroy = Dw_widget_destroy;	klass->size_request = Dw_widget_real_size_request;	klass->size_allocate = Dw_widget_real_size_allocate;	klass->set_width = Dw_widget_real_set_width;	klass->set_ascent = Dw_widget_real_set_ascent;	klass->set_descent = Dw_widget_real_set_descent;	klass->draw = Dw_widget_real_draw;	klass->realize = Dw_widget_real_realize;	klass->unrealize = Dw_widget_real_unrealize;	klass->button_press_event = Dw_widget_real_button_press;	klass->button_release_event = Dw_widget_real_button_release;	klass->motion_notify_event = Dw_widget_real_motion_notify;	klass->enter_notify_event = Dw_widget_real_enter_notify;	klass->leave_notify_event = Dw_widget_real_leave_notify;}/* * Standard Gtk+ function */static void Dw_widget_shutdown(GtkObject * object){	DwWidget *widget;	widget = DW_WIDGET(object);	a_Dw_widget_unrealize(widget);	if (widget->parent)		Dw_container_remove(DW_CONTAINER(widget->parent), widget);	else		Dw_gtk_viewport_remove_dw(GTK_DW_VIEWPORT(widget->viewport));	parent_class->shutdown(object);}/* * Deallocate anchor positions inside the hash_table */void Dw_widget_free_anchor(gpointer key, gpointer value, gpointer data){	if (value)		g_free(value);}/* * Standard Gtk+ function */static void Dw_widget_destroy(GtkObject * object){	DwWidget *widget;	widget = DW_WIDGET(object);	if (widget->anchors_table) {		g_hash_table_foreach(widget->anchors_table, Dw_widget_free_anchor, NULL);		g_hash_table_destroy(widget->anchors_table);	}	/* The widget the pointer is in? */	if (widget->viewport != NULL && widget == GTK_DW_VIEWPORT(widget->viewport)->last_entered)		/* todo: perhaps call the leave_notify function? */		GTK_DW_VIEWPORT(widget->viewport)->last_entered = NULL;	if (widget->style)		a_Dw_style_unref(widget->style);	parent_class->destroy(object);}/* * Standard Dw function */static void Dw_widget_real_size_request(DwWidget * widget, DwRequisition * requisition){	g_warning("DwWidget::size_request not implemented for `%s'", gtk_type_name(GTK_OBJECT_TYPE(widget)));	/* return random size to prevent crashes */	requisition->width = 50;	requisition->ascent = 50;	requisition->descent = 50;}/* * Standard Dw function */static void Dw_widget_real_size_allocate(DwWidget * widget, DwAllocation * allocation){	/* ignored */}/* * Standard Dw function */static void Dw_widget_real_set_width(DwWidget * widget, gint32 width){	/* ignored */}/* * Standard Dw function */static void Dw_widget_real_set_ascent(DwWidget * widget, gint32 ascent){	/* ignored */}/* * Standard Dw function */static void Dw_widget_real_set_descent(DwWidget * widget, gint32 descent){	/* ignored */}/* * Standard Dw function */static void Dw_widget_real_draw(DwWidget * widget, DwRectangle * area, GdkEventExpose * event){	/* ignored */}/* * Standard Dw function */static void Dw_widget_real_realize(DwWidget * widget){	/* ignored */}/* * Standard Dw function */static void Dw_widget_real_unrealize(DwWidget * widget){	/* ignored */}/* * Standard Dw function */static gint Dw_widget_real_button_press(DwWidget * widget, gint32 x, gint32 y, GdkEventButton * event){	/* not handled */	return FALSE;}/* * Standard Dw function */static gint Dw_widget_real_button_release(DwWidget * widget, gint32 x, gint32 y, GdkEventButton * event){	/* not handled */	return FALSE;}/* * Standard Dw function */static gint Dw_widget_real_motion_notify(DwWidget * widget, gint32 x, gint32 y, GdkEventMotion * event){	/* not handled */	return FALSE;}/* * Standard Dw function */static gint Dw_widget_real_enter_notify(DwWidget * widget, GdkEventMotion * event){	/* not handled */	return FALSE;}/* * Standard Dw function */static gint Dw_widget_real_leave_notify(DwWidget * widget, GdkEventMotion * event){	/* not handled */	return FALSE;}/* * This function is a wrapper for DwWidget::size_request; it (1) calls * this method only when needed, (2) may be overridden my a previous call * of a_Dw_widget_set_usize. */void a_Dw_widget_size_request(DwWidget * widget, DwRequisition * requisition){	if (DW_WIDGET_NEEDS_RESIZE(widget)) {		/* todo: check requisition == &(widget->requisition) and do what? */		gtk_signal_emit(GTK_OBJECT(widget), widget_signals[SIZE_REQUEST], requisition);		if (widget->user_requisition.width != -1)			requisition->width = widget->user_requisition.width;		if (widget->user_requisition.ascent != -1)			requisition->ascent = widget->user_requisition.ascent;		if (widget->user_requisition.descent != -1)			requisition->descent = widget->user_requisition.descent;		widget->requisition = *requisition;		DW_WIDGET_UNSET_FLAGS(widget, DW_NEEDS_RESIZE);	} else		*requisition = widget->requisition;}/* * Wrapper for DwWidget::size_allocate, only called when needed. */void a_Dw_widget_size_allocate(DwWidget * widget, DwAllocation * allocation){	if (DW_WIDGET_NEEDS_ALLOCATE(widget) || allocation->x != widget->allocation.x || allocation->y != widget->allocation.y || allocation->width != widget->allocation.width || allocation->ascent != widget->allocation.ascent || allocation->descent != widget->allocation.descent) {		gtk_signal_emit(GTK_OBJECT(widget), widget_signals[SIZE_ALLOCATE], allocation);		widget->allocation = *allocation;	}	/*DW_WIDGET_UNSET_FLAGS (widget, DW_NEEDS_RESIZE); */}void a_Dw_widget_set_width(DwWidget * widget, gint32 width){	gtk_signal_emit(GTK_OBJECT(widget), widget_signals[SET_WIDTH], width);}void a_Dw_widget_set_ascent(DwWidget * widget, gint32 ascent){	gtk_signal_emit(GTK_OBJECT(widget), widget_signals[SET_ASCENT], ascent);}void a_Dw_widget_set_descent(DwWidget * widget, gint32 descent){	gtk_signal_emit(GTK_OBJECT(widget), widget_signals[SET_DESCENT], descent);}void a_Dw_widget_draw(DwWidget * widget, DwRectangle * area, GdkEventExpose * event){	gtk_signal_emit(GTK_OBJECT(widget), widget_signals[DRAW], area, event);}void a_Dw_widget_realize(DwWidget * widget){	if (!DW_WIDGET_REALIZED(widget)) {		gtk_signal_emit(GTK_OBJECT(widget), widget_signals[REALIZE]);		DW_WIDGET_SET_FLAGS(widget, DW_REALIZED);		if (DW_IS_CONTAINER(widget))			a_Dw_container_forall(DW_CONTAINER(widget), (DwCallback) a_Dw_widget_realize, NULL);		Dw_widget_update_cursor(widget);	}}void a_Dw_widget_unrealize(DwWidget * widget){	if (DW_WIDGET_REALIZED(widget)) {		a_Dw_widget_set_cursor(widget, NULL);		gtk_signal_emit(GTK_OBJECT(widget), widget_signals[UNREALIZE]);		DW_WIDGET_UNSET_FLAGS(widget, DW_REALIZED);		if (DW_IS_CONTAINER(widget))			a_Dw_container_forall(DW_CONTAINER(widget), (DwCallback) a_Dw_widget_unrealize, NULL);	}}/* * Handles a mouse event. *  * This function is called by Dw_gtk_viewport_mouse_event, the type of * the event is determined by event->type. x and y are world coordinates. * widget may be NULL (if the pointer is outside the top-level widget). *  * When event is NULL, GDK_MOTION_NOTIFY is used as the type. This will * soon be the case when GDK_MOTION_NOTIFY events are simulated as a * result of viewport changes (bug #94) */gint Dw_widget_mouse_event(DwWidget * widget, GtkWidget * viewwidget, gint32 x, gint32 y, GdkEvent * event){	/* todo: implement as signals */	gint(*function) ();	DwWidgetClass *klass;	GtkDwViewport *viewport = GTK_DW_VIEWPORT(viewwidget);	GdkEventType event_type;	/* simulate crossing events */	/* todo:	   1) perhaps more sophisticated (as in X)	   2) resizing/moving widgets	 */	if (widget != viewport->last_entered) {		if (viewport->last_entered) {			klass = DW_WIDGET_CLASS(GTK_OBJECT(viewport->last_entered)->klass);			(*(klass->leave_notify_event)) (viewport->last_entered, (GdkEventMotion *) event);		}		viewport->last_entered = widget;		if (widget) {			klass = DW_WIDGET_CLASS(GTK_OBJECT(widget)->klass);			(*(klass->enter_notify_event)) (widget, (GdkEventMotion *) event);			Dw_widget_update_cursor(widget);		} else

⌨️ 快捷键说明

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