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

📄 dw_gtk_viewport.c

📁 微型浏览器
💻 C
📖 第 1 页 / 共 2 页
字号:
/* * File: dw_gtk_viewport.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_gtk_viewport.h"#include "dw_container.h"static GtkLayoutClass *parent_class = NULL;/* object/class initialisation */static void Dw_gtk_viewport_init(GtkDwViewport * viewport);static void Dw_gtk_viewport_class_init(GtkDwViewportClass * klass);/* GtkObject methods */static void Dw_gtk_viewport_destroy(GtkObject * object);/* GtkWidget methods */static void Dw_gtk_viewport_realize(GtkWidget * widget);static void Dw_gtk_viewport_unrealize(GtkWidget * widget);static void Dw_gtk_viewport_size_allocate(GtkWidget * widget, GtkAllocation * allocation);static void Dw_gtk_viewport_draw(GtkWidget * widget, GdkRectangle * area);static gint Dw_gtk_viewport_expose(GtkWidget * widget, GdkEventExpose * event);static gint Dw_gtk_viewport_button_press(GtkWidget * widget, GdkEventButton * event);static gint Dw_gtk_viewport_button_release(GtkWidget * widget, GdkEventButton * event);static gint Dw_gtk_viewport_motion_notify(GtkWidget * widget, GdkEventMotion * event);static gint Dw_gtk_viewport_enter_notify(GtkWidget * widget, GdkEventCrossing * event);static gint Dw_gtk_viewport_leave_notify(GtkWidget * widget, GdkEventCrossing * event);static void Dw_gtk_viewport_adj_changed(GtkAdjustment * adj, GtkDwViewport * viewport);/* * Standard Gtk+ function */GtkType a_Dw_gtk_viewport_get_type(void){	static GtkType type = 0;	if (!type) {		GtkTypeInfo info = {			"GtkDwViewport",			sizeof(GtkDwViewport),			sizeof(GtkDwViewportClass),			(GtkClassInitFunc) Dw_gtk_viewport_class_init,			(GtkObjectInitFunc) Dw_gtk_viewport_init,			(GtkArgSetFunc) NULL,			(GtkArgGetFunc) NULL,		};		type = gtk_type_unique(GTK_TYPE_LAYOUT, &info);	}	return type;}/* * Standard Gtk+ function */GtkWidget *a_Dw_gtk_viewport_new(GtkAdjustment * hadjustment, GtkAdjustment * vadjustment){	GtkWidget *widget;	widget = gtk_widget_new(GTK_TYPE_DW_VIEWPORT, NULL);	gtk_layout_set_hadjustment(GTK_LAYOUT(widget), hadjustment);	gtk_layout_set_vadjustment(GTK_LAYOUT(widget), vadjustment);	/* Following two statements expect that the adjustments are passed as	 * arguments (!= NULL), and don't change. This is the case in dillo,	 * however, for more general perposes, the signal function	 * "set_scroll_adjustments" had to be redefined.	 */	gtk_signal_connect(GTK_OBJECT(hadjustment), "value_changed", GTK_SIGNAL_FUNC(Dw_gtk_viewport_adj_changed), (gpointer) widget);	gtk_signal_connect(GTK_OBJECT(vadjustment), "value_changed", GTK_SIGNAL_FUNC(Dw_gtk_viewport_adj_changed), (gpointer) widget);	return widget;}/********************************* *                               * *  object/class initialisation  * *                               * *********************************//* * Standard Gtk+ function */static void Dw_gtk_viewport_init(GtkDwViewport * viewport){	GTK_WIDGET_UNSET_FLAGS(viewport, GTK_NO_WINDOW);	GTK_WIDGET_UNSET_FLAGS(viewport, GTK_CAN_FOCUS);	/* Without this, gtk_layout_{draw|expose} will clear the window.	   Look at gtklayout.c */	GTK_WIDGET_SET_FLAGS(viewport, GTK_APP_PAINTABLE);	viewport->child = NULL;	viewport->last_entered = NULL;	viewport->resize_idle_id = -1;	viewport->back_pixmap = NULL;	viewport->back_gc = NULL;	viewport->anchor = NULL;	viewport->queued_anchor = NULL;	viewport->anchor_idle_id = -1;}/* * Standard Gtk+ function */static void Dw_gtk_viewport_class_init(GtkDwViewportClass * klass){	GtkObjectClass *object_class;	GtkWidgetClass *widget_class;	parent_class = gtk_type_class(gtk_layout_get_type());	object_class = (GtkObjectClass *) klass;	widget_class = (GtkWidgetClass *) klass;	object_class->destroy = Dw_gtk_viewport_destroy;	widget_class->realize = Dw_gtk_viewport_realize;	widget_class->unrealize = Dw_gtk_viewport_unrealize;	widget_class->size_allocate = Dw_gtk_viewport_size_allocate;	widget_class->draw = Dw_gtk_viewport_draw;	widget_class->expose_event = Dw_gtk_viewport_expose;	widget_class->button_press_event = Dw_gtk_viewport_button_press;	widget_class->button_release_event = Dw_gtk_viewport_button_release;	widget_class->motion_notify_event = Dw_gtk_viewport_motion_notify;	widget_class->enter_notify_event = Dw_gtk_viewport_enter_notify;	widget_class->leave_notify_event = Dw_gtk_viewport_leave_notify;}/*********************** *                     * *  GtkObject methods  * *                     * ***********************//* * Standard Gtk+ function */static void Dw_gtk_viewport_destroy(GtkObject * object){	GtkDwViewport *viewport;	viewport = GTK_DW_VIEWPORT(object);	if (viewport->child)		gtk_object_destroy(GTK_OBJECT(viewport->child));	if (viewport->resize_idle_id)		gtk_idle_remove(viewport->resize_idle_id);	if (viewport->anchor)		g_free(viewport->anchor);	if (viewport->queued_anchor)		g_free(viewport->queued_anchor);	if (viewport->anchor_idle_id != -1)		gtk_idle_remove(viewport->anchor_idle_id);	(*(GTK_OBJECT_CLASS(parent_class)->destroy)) (object);}/*********************** *                     * *  GtkWidget methods  * *                     * ***********************//* * Standard Gtk+ function */static void Dw_gtk_viewport_realize(GtkWidget * widget){	GtkDwViewport *viewport;	(*(GTK_WIDGET_CLASS(parent_class)->realize)) (widget);	gdk_window_set_events(widget->window, gdk_window_get_events(widget->window)			      | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK | GDK_POINTER_MOTION_MASK | GDK_ENTER_NOTIFY_MASK | GDK_LEAVE_NOTIFY_MASK);	viewport = GTK_DW_VIEWPORT(widget);	if (viewport->child)		a_Dw_widget_realize(viewport->child);}/* * Standard Gtk+ function */static void Dw_gtk_viewport_unrealize(GtkWidget * widget){	GtkDwViewport *viewport;	(*(GTK_WIDGET_CLASS(parent_class)->unrealize)) (widget);	viewport = GTK_DW_VIEWPORT(widget);	if (viewport->child)		a_Dw_widget_unrealize(viewport->child);}/* * Standard Gtk+ function */static void Dw_gtk_viewport_size_allocate(GtkWidget * widget, GtkAllocation * allocation){	gint32 child_width, child_height;	GtkDwViewport *viewport;	gint border_width;	(*(GTK_WIDGET_CLASS(parent_class)->size_allocate)) (widget, allocation);	viewport = GTK_DW_VIEWPORT(widget);	if (viewport->child) {		border_width = GTK_CONTAINER(viewport)->border_width;		child_width = allocation->width - 2 * border_width;		if (child_width < 0)			child_width = 0;		child_height = allocation->height - 2 * border_width;		if (child_height < 0)			child_height = 0;		a_Dw_widget_set_width(viewport->child, child_width);		a_Dw_widget_set_ascent(viewport->child, child_height);		a_Dw_widget_set_descent(viewport->child, 0);		/* This is also done in the idle function a bit later, but without		   the following two lines, you'll see the page wrapped at 100 pixel */		if (DW_WIDGET_NEEDS_RESIZE(viewport->child))			Dw_gtk_viewport_calc_size(viewport);	}}/* * (Nearly) standard Gtk+ function */static void Dw_gtk_viewport_paint(GtkWidget * widget, GdkRectangle * area, GdkEventExpose * event){	GtkLayout *layout;	DwRectangle parent_area, child_area, intersection;	GtkDwViewport *viewport;	gint32 vx, vy;	if (GTK_WIDGET_DRAWABLE(widget)) {		layout = GTK_LAYOUT(widget);		viewport = GTK_DW_VIEWPORT(widget);		if (viewport->back_pixmap) {			/* draw background pixmap */			/* This is intended for supporting background pixmaps in future.			   Quite much other code has to be added. */			g_return_if_fail(layout->hadjustment != NULL);			g_return_if_fail(layout->vadjustment != NULL);			vx = ((gint32) (layout->hadjustment->value)) % viewport->back_width;			vy = ((gint32) (layout->vadjustment->value)) % viewport->back_height;			gdk_gc_set_ts_origin(viewport->back_gc, -vx, -vy);			gdk_draw_rectangle(GTK_LAYOUT(widget)->bin_window, viewport->back_gc, TRUE, area->x, area->y, area->width, area->height);		} else			gdk_window_clear_area(layout->bin_window, area->x, area->y, area->width, area->height);		if (viewport->child) {			/* draw top-level Dw widget */			parent_area.x = Dw_widget_x_viewport_to_world(viewport->child, area->x);			parent_area.y = Dw_widget_y_viewport_to_world(viewport->child, area->y);			parent_area.width = area->width;			parent_area.height = area->height;			child_area.x = viewport->child->allocation.x;			child_area.y = viewport->child->allocation.y;			child_area.width = viewport->child->allocation.width;			child_area.height = (viewport->child->allocation.ascent + viewport->child->allocation.descent);			if (Dw_rectangle_intersect(&parent_area, &child_area, &intersection)) {				intersection.x -= viewport->child->allocation.x;				intersection.y -= viewport->child->allocation.y;				a_Dw_widget_draw(viewport->child, &intersection, event);			}		}	}}/* * Standard Gtk+ function */static void Dw_gtk_viewport_draw(GtkWidget * widget, GdkRectangle * area){	Dw_gtk_viewport_paint(widget, area, NULL);	(*(GTK_WIDGET_CLASS(parent_class)->draw)) (widget, area);}/* * Standard Gtk+ function */static gint Dw_gtk_viewport_expose(GtkWidget * widget, GdkEventExpose * event){	Dw_gtk_viewport_paint(widget, &(event->area), event);	return (*(GTK_WIDGET_CLASS(parent_class)->expose_event)) (widget, event);}/* * Handle the mouse event and deliver it to the Dw widget. 

⌨️ 快捷键说明

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