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

📄 dw_gtk_viewport.c

📁 浏览器的源代码,可移植到嵌入式设备.
💻 C
📖 第 1 页 / 共 3 页
字号:
         world_y = y + gtk_layout_get_vadjustment(GTK_LAYOUT(viewport))->value;         dw_widget =            Dw_gtk_viewport_widget_at_point (viewport, world_x, world_y);         return Dw_widget_mouse_event (dw_widget, widget,                                       world_x, world_y, event);      }   }   return FALSE;}/* * Standard Gtk+ function */static gint Dw_gtk_viewport_button_press (GtkWidget *widget,                                          GdkEventButton *event){   /* We focus always the viewport window (i.e., more precisely, the    * GktDwScrolledFrame). */   if (widget->parent)      gtk_widget_grab_focus(widget->parent);   return Dw_gtk_viewport_mouse_event (widget, event->x, event->y,                                       (GdkEvent*) event);}/* * Standard Gtk+ function */static gint Dw_gtk_viewport_button_release (GtkWidget *widget,                                            GdkEventButton *event){   return Dw_gtk_viewport_mouse_event (widget, event->x, event->y,                                       (GdkEvent*) event);}/* * Standard Gtk+ function */static gint Dw_gtk_viewport_motion_notify (GtkWidget *widget,                                           GdkEventMotion *event){   GtkDwViewport *viewport = GTK_DW_VIEWPORT (widget);   viewport->mouse_x = event->x;   viewport->mouse_y = event->y;   return Dw_gtk_viewport_mouse_event (widget, event->x, event->y,                                       (GdkEvent*) event);}/* * Standard Gtk+ function */static gint Dw_gtk_viewport_enter_notify (GtkWidget *widget,                                          GdkEventCrossing *event){   return Dw_gtk_viewport_mouse_event (widget, event->x, event->y, NULL);}/* * Standard Gtk+ function */static gint Dw_gtk_viewport_leave_notify (GtkWidget *widget,                                          GdkEventCrossing *event){   /* There will anyway be no Dw widget, thus this simple call */   return Dw_widget_mouse_event (NULL, widget, 0, 0, NULL);}/* * This function is called when the viewport changes, and causes * motion_notify events to be simulated. */static void Dw_gtk_viewport_adj_changed (GtkAdjustment *adj,                                         GtkDwViewport *viewport){   Dw_gtk_viewport_mouse_event (GTK_WIDGET (viewport),                                viewport->mouse_x, viewport->mouse_y, NULL);}/********************** *                    * *  public functions  * *                    * **********************//* * Set the top-level Dw widget. * If there is already one, you must destroy it before, otherwise the * function will fail. */void a_Dw_gtk_viewport_add_dw (GtkDwViewport *viewport,                               DwWidget *widget){   g_return_if_fail (viewport->child == NULL);   viewport->child = widget;   DBG_OBJ_ASSOC(widget, viewport);   widget->parent = NULL;   widget->viewport = GTK_WIDGET (viewport);   /*widget->window = viewport->back_pixmap;*/   if (GTK_WIDGET_REALIZED (viewport))      a_Dw_widget_realize (widget);   Dw_gtk_viewport_calc_size (viewport);   Dw_gtk_viewport_remove_anchor (viewport);   a_Findtext_state_set_widget (viewport->findtext_state, widget);   a_Selection_reset (viewport->selection);}/************************************************** *                                                * *  Functions used by GtkDwViewport and DwWidget  * *                                                * **************************************************//* * This function only *recognizes* that the top-level Dw widget is to * be removed. It is called by Dw_widget_shutdown. * Don't use this function directly! */void Dw_gtk_viewport_remove_dw (GtkDwViewport *viewport){   a_Findtext_state_set_widget (viewport->findtext_state, NULL);   viewport->child = NULL;   Dw_gtk_viewport_remove_anchor (viewport);   Dw_gtk_viewport_calc_size (viewport);}/* * Used by Dw_gtk_viewport_calc_size. */static void Dw_gtk_viewport_calc_child_size (GtkDwViewport *viewport,                                             gint32 child_width,                                             gint32 child_height,                                             DwRequisition *child_requisition){   if (child_width < 0) child_width = 0;   if (child_height < 0) child_height = 0;   DEBUG_MSG (2, "   width = %d, height = %d ...\n",              child_width, child_height);   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);   a_Dw_widget_size_request (viewport->child, child_requisition);}/* * Calculate the size of the scrolled area and allocate the top-level * widget. This function is called when the top-level Dw widget has * changed its size etc. */void Dw_gtk_viewport_calc_size (GtkDwViewport *viewport){   GtkWidget *widget;   GtkScrolledWindow *scrolled;   DwRequisition child_requisition;   DwAllocation child_allocation;   gint border_width,  space;   GtkRequisition bar_requisition;   gint max_width, max_height, bar_width_diff, bar_height_diff, child_height;   if (viewport->calc_size_blocked)      return;   viewport->calc_size_blocked = TRUE;   if (viewport->child) {      /*       * Determine the size hints for the Dw widget. This is a bit       * tricky, because you must know if scrollbars are visible or       * not, which depends on the size of the Dw widget, which then       * depends on the hints. The idea is to test several       * configurations, there are four of them, from combining the       * cases horizontal/vertical scrollbar visible/invisible.       *       * For optimization, the horizontal scrollbar is currently not       * regarded, the height hint is always the same, as if the       * scrollbar was allways visible. In future, this may be       * implemented correctly, by using the minimal width to optimize       * most cases. (Minimal widths will also be used by tables.)       *       * Furthermore, the last result (vertical scrollbar visible or       * not) is stored in the viewport, and tested first. This will       * make a second test only necessary when the visibility       * switches, which normally happens only once when filling the       * page with text. (Actually, this assumes that the page size is       * always *growing*, but this is nevertheless true in dillo.)       */      widget = GTK_WIDGET (viewport);      scrolled = GTK_SCROLLED_WINDOW (widget->parent->parent);      space = GTK_SCROLLED_WINDOW_CLASS(GTK_OBJECT(scrolled)->klass)         ->scrollbar_spacing;      border_width = GTK_CONTAINER(viewport)->border_width;      gtk_widget_size_request (scrolled->vscrollbar, &bar_requisition);      bar_width_diff = bar_requisition.width + space;      max_width = widget->allocation.width - 2 * border_width;      if (scrolled->vscrollbar_visible)         max_width += bar_width_diff;      gtk_widget_size_request (scrolled->hscrollbar, &bar_requisition);      bar_height_diff = bar_requisition.height + space;      max_height = widget->allocation.height - 2 * border_width;      if (scrolled->hscrollbar_visible)         max_height += bar_height_diff;      DEBUG_MSG (2, "------------------------------------------------->\n");      DEBUG_MSG (2, "Dw_gtk_viewport_calc_size: %d x %d (%c/%c) -> %d x %d\n",                 widget->allocation.width, widget->allocation.height,                 scrolled->vscrollbar_visible ? 't' : 'f',                 scrolled->hscrollbar_visible ? 't' : 'f',                 max_width, max_height);      if (scrolled->vscrollbar_policy == GTK_POLICY_NEVER)         child_height = max_height;      else         child_height = max_height - bar_height_diff;      switch (scrolled->vscrollbar_policy) {      case GTK_POLICY_ALWAYS:         Dw_gtk_viewport_calc_child_size (viewport, max_width - bar_width_diff,                                          child_height,                                          &child_requisition);         break;      case GTK_POLICY_AUTOMATIC:         if (viewport->vscrollbar_used) {            DEBUG_MSG (2, "Testing with vertical scrollbar ...\n");            Dw_gtk_viewport_calc_child_size (viewport,                                             max_width - bar_width_diff,                                             child_height,                                             &child_requisition);            if (child_requisition.ascent                + child_requisition.descent <= child_height) {               DEBUG_MSG (2, "   failed!\n");               Dw_gtk_viewport_calc_child_size (viewport, max_width,                                                child_height,                                                &child_requisition);               viewport->vscrollbar_used = TRUE;            }         } else {            DEBUG_MSG (2, "Testing without vertical scrollbar ...\n");            Dw_gtk_viewport_calc_child_size (viewport, max_width,                                             child_height,                                             &child_requisition);            /* todo: see above */            if (child_requisition.ascent                + child_requisition.descent > child_height) {               DEBUG_MSG (2, "   failed!\n");               Dw_gtk_viewport_calc_child_size (viewport,                                                max_width - bar_width_diff,                                                child_height,                                                &child_requisition);               viewport->vscrollbar_used = TRUE;            }         }         break;      case GTK_POLICY_NEVER:         Dw_gtk_viewport_calc_child_size (viewport, max_width,                                          child_height,                                          &child_requisition);      }      child_allocation.x = border_width;      child_allocation.y = border_width;      child_allocation.width = child_requisition.width;      child_allocation.ascent = child_requisition.ascent;      child_allocation.descent = child_requisition.descent;      a_Dw_widget_size_allocate (viewport->child, &child_allocation);      gtk_layout_set_size (GTK_LAYOUT (viewport),                           child_requisition.width + 2 * border_width,                           child_requisition.ascent + child_requisition.descent                           + 2 * border_width);      DEBUG_MSG (1, "Setting size to %d x %d\n",                 child_requisition.width + 2 * border_width,                 child_requisition.ascent + child_requisition.descent                 + 2 * border_width);      DEBUG_MSG (2, "<-------------------------------------------------\n");   } else {      gtk_layout_set_size (GTK_LAYOUT (viewport), 1, 1);      viewport->hscrollbar_used = FALSE;      viewport->vscrollbar_used = FALSE;   }   Dw_gtk_viewport_update_anchor (viewport);   gtk_widget_queue_draw (GTK_WIDGET (viewport));   viewport->calc_size_blocked = FALSE;}/* used by Dw_gtk_viewport_widget_at_point */typedef struct{   gint32 x;   gint32 y;   DwWidget *widget;} WidgetAtPointData;/* used by Dw_gtk_viewport_widget_at_point */static void Dw_gtk_viewport_widget_at_point_callback (DwWidget *widget,                                                      gpointer data){   WidgetAtPointData *callback_data;   callback_data = (WidgetAtPointData*) data;   DEBUG_MSG (1, "  Checking %p ...\n", widget);   if (/* As a special exception, for the top-level widget, not the        * allocation is regarded, but the whole viewport. This makes        * selections more useful, since so the user can start the        * selection outside of the allocation. */       widget->parent == NULL ||       /* Otherwise, check whether pointer is in the allocation. */       (callback_data->x >= widget->allocation.x &&        callback_data->y >= widget->allocation.y &&        callback_data->x < widget->allocation.x + widget->allocation.width &&        callback_data->y < widget->allocation.y + DW_WIDGET_HEIGHT(widget))) {      DEBUG_MSG (1, "    yes\n");      if (DW_IS_CONTAINER (widget))         a_Dw_container_forall (DW_CONTAINER (widget),                                Dw_gtk_viewport_widget_at_point_callback,                                data);      if (callback_data->widget == NULL)         callback_data->widget = widget;   }}/* * Return the widget at point (x, y) (world coordinates). */DwWidget* Dw_gtk_viewport_widget_at_point (GtkDwViewport *viewport,                                           gint32 x,                                           gint32 y){   WidgetAtPointData callback_data;   callback_data.x = x;   callback_data.y = y;   callback_data.widget = NULL;   if (viewport->child)      Dw_gtk_viewport_widget_at_point_callback (viewport->child,                                                &callback_data);   return callback_data.widget;}/************* *           * *  Anchors  * *           * *************//* * Add or change an anchor. * The widget is responsible for storing a copy of name. * * todo: Currently, no horizontal scrolling is done. This is generally * possible, DW_HPOS_INTO_VIEW should be used for this, but it is * rather complicated to determine the width of an anchor. This would * be the lenght of the region between <a> and </a>, the page widget * would have to have two kinds of content types (opening and closing * anchor), and some changes in the HTML parser are necessary. */void p_Dw_gtk_viewport_put_anchor (DwWidget *widget,                                   gchar *name,                                   gint32 y){   GtkDwViewport *viewport;   GtkDwViewportAnchor *anchor;

⌨️ 快捷键说明

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