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

📄 dw_gtk_viewport.c

📁 浏览器的源代码,可移植到嵌入式设备.
💻 C
📖 第 1 页 / 共 3 页
字号:
/* * File: dw_gtk_viewport.c * * Copyright (C) 2001-2003  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 "msg.h"#include "dw_gtk_viewport.h"#include "dw_container.h"#include "list.h"/*#define DEBUG_LEVEL 1*/#include "debug.h"#include "msg.h"typedef struct{   DwWidget *widget;   gint32 y;} GtkDwViewportAnchor;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_size_allocate (GtkWidget *widget,                                           GtkAllocation *allocation);static void Dw_gtk_viewport_realize       (GtkWidget *widget);static void Dw_gtk_viewport_unrealize     (GtkWidget *widget);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,         (GtkClassInitFunc) 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){   DBG_OBJ_CREATE (viewport, "GtkDwViewport");   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->back_pixmap = NULL;   viewport->child = NULL;   viewport->last_entered = NULL;   viewport->draw_resize_idle_id = 0;   viewport->anchor = NULL;   viewport->anchor_idle_id = 0;   viewport->findtext_state = a_Findtext_state_new ();   viewport->selection = a_Selection_new ();   viewport->anchors_table = g_hash_table_new (g_str_hash, g_str_equal);   viewport->draw_areas = NULL;   viewport->num_draw_areas = 0;   viewport->num_draw_areas_max = 4;   DBG_OBJ_ASSOC (viewport->findtext_state, viewport);   DBG_OBJ_ASSOC (viewport->selection, viewport);}/* * 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->size_allocate = Dw_gtk_viewport_size_allocate;   widget_class->realize = Dw_gtk_viewport_realize;   widget_class->unrealize = Dw_gtk_viewport_unrealize;   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  * *                     * ***********************/static gboolean Dw_gtk_viewport_destroy_anchor (gpointer key,                                                gpointer value,                                                gpointer user_data){   g_free (value);   return TRUE;}/* * Standard Gtk+ function */static void Dw_gtk_viewport_destroy (GtkObject *object){   GtkDwViewport *viewport;   viewport = GTK_DW_VIEWPORT (object);   if (viewport->back_pixmap)      gdk_pixmap_unref (viewport->back_pixmap);   if (viewport->child)      gtk_object_destroy (GTK_OBJECT (viewport->child));   if (viewport->draw_resize_idle_id != 0)      gtk_idle_remove (viewport->draw_resize_idle_id);   if (viewport->anchor_idle_id != 0)      gtk_idle_remove (viewport->anchor_idle_id);   g_free (viewport->anchor);   g_hash_table_foreach_remove (viewport->anchors_table,                                Dw_gtk_viewport_destroy_anchor, NULL);   g_hash_table_destroy (viewport->anchors_table);   g_free (viewport->draw_areas);   a_Findtext_state_destroy (viewport->findtext_state);   a_Selection_free (viewport->selection);   GTK_OBJECT_CLASS(parent_class)->destroy (object);}/*********************** *                     * *  GtkWidget methods  * *                     * ***********************//* * Standard Gtk+ function */static void Dw_gtk_viewport_size_allocate (GtkWidget *widget,                                           GtkAllocation *allocation){   GTK_WIDGET_CLASS(parent_class)->size_allocate (widget, allocation);   /* gtk_layout_size_allocate() sets them to different values. */   GTK_LAYOUT(widget)->hadjustment->page_increment = allocation->width;   GTK_LAYOUT(widget)->vadjustment->page_increment = 0.96 * allocation->height;}/* * 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);   gdk_window_get_geometry (widget->window, NULL, NULL, NULL, NULL,                            &viewport->depth);}/* * 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);}/* * (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;   gboolean new_back_pixmap;   if (GTK_WIDGET_DRAWABLE (widget)) {      layout = GTK_LAYOUT (widget);      viewport = GTK_DW_VIEWPORT (widget);      DEBUG_MSG (2, "Drawing (%d, %d), %d x %d\n",                 area->x, area->y, area->width, area->height);      /* Make sure the backing pixmap is large enough. */      if (viewport->child) {         if (viewport->back_pixmap)            new_back_pixmap =               (widget->allocation.width > viewport->back_width ||                widget->allocation.height > viewport->back_height);         else            new_back_pixmap = TRUE;         if (new_back_pixmap) {            if (viewport->back_pixmap)               gdk_pixmap_unref (viewport->back_pixmap);            viewport->back_pixmap = gdk_pixmap_new (widget->window,                                                    widget->allocation.width,                                                    widget->allocation.height,                                                    viewport->depth);            viewport->back_width = widget->allocation.width;            viewport->back_height = widget->allocation.height;            DEBUG_MSG (1, "   Creating new pixmap, size = %d x %d\n",                       widget->allocation.width, widget->allocation.height);         }         /* Draw top-level Dw widget. */         parent_area.x =            p_Dw_widget_x_viewport_to_world (viewport->child, area->x);         parent_area.y =            p_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 = DW_WIDGET_HEIGHT(viewport->child);         if (p_Dw_rectangle_intersect (&parent_area, &child_area,                                       &intersection)) {            intersection.x -= viewport->child->allocation.x;            intersection.y -= viewport->child->allocation.y;            /* "Clear" backing pixmap. */            gdk_draw_rectangle (viewport->back_pixmap,                                viewport->child->style->background_color->gc,                                TRUE, area->x, area->y,                                area->width, area->height);            /* Widgets draw in backing pixmap. */            a_Dw_widget_draw (viewport->child, &intersection, event);            /* Copy backing pixmap into window. */            gdk_draw_pixmap (layout->bin_window, widget->style->black_gc,                             viewport->back_pixmap, area->x, area->y,                             area->x, area->y, area->width, area->height);         }      } else         gdk_window_clear_area (layout->bin_window,                                area->x, area->y, area->width, area->height);   }}/* * 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. * Most is done in a_Dw_widget_mouse_event. */static gint Dw_gtk_viewport_mouse_event (GtkWidget *widget,                                         gint32 x,                                         gint32 y,                                         GdkEvent *event){   GtkDwViewport *viewport;   DwWidget *dw_widget;   gint32 world_x, world_y;   if (event == NULL || event->any.window == widget->window) {      viewport = GTK_DW_VIEWPORT (widget);      if (viewport->child) {         world_x = x + gtk_layout_get_hadjustment(GTK_LAYOUT(viewport))->value;

⌨️ 快捷键说明

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