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

📄 dw_gtk_viewport.c

📁 嵌入式浏览器Dillo源码
💻 C
📖 第 1 页 / 共 2 页
字号:
   /* 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;   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);}/************************************************** *                                                * *  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){   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;   if (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 + (widget->allocation.ascent +                                                  widget->allocation.descent))      {         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  * *           * *************//* * See Dw_gtk_viewport_scroll_to. */static gint Dw_gtk_viewport_update_anchor_idle (gpointer data){   GtkDwViewport *viewport;   GtkAdjustment *adj;   viewport = GTK_DW_VIEWPORT (data);   adj = GTK_LAYOUT(viewport)->vadjustment;   if (viewport->anchor_y > adj->upper - adj->page_size)      gtk_adjustment_set_value (adj, adj->upper - adj->page_size);   else      gtk_adjustment_set_value (adj, viewport->anchor_y);   viewport->anchor_idle_id = -1;   return FALSE;}/* * Called by Dw_gtk_viewport_update_anchor. */static void Dw_gtk_viewport_update_anchor_rec (DwWidget *widget){   gpointer p;   GtkDwViewport *viewport;   viewport = GTK_DW_VIEWPORT (widget->viewport);   if (widget->anchors_table &&       g_hash_table_lookup_extended (widget->anchors_table, viewport->anchor,                                     NULL, &p))      Dw_gtk_viewport_scroll_to (viewport,                                 GPOINTER_TO_INT(p) + widget->allocation.y);   else {      if (DW_IS_CONTAINER (widget))         a_Dw_container_forall (DW_CONTAINER (widget),                                (DwCallback)Dw_gtk_viewport_update_anchor_rec,                                NULL);   }}/* * Called when possibly the scroll position has to be changed because * of anchors. */void Dw_gtk_viewport_update_anchor (GtkDwViewport *viewport){   if (viewport->anchor && viewport->child)      Dw_gtk_viewport_update_anchor_rec (viewport->child);}/* * Sets the anchor to scroll to. */void a_Dw_gtk_viewport_set_anchor (GtkDwViewport *viewport,                                   const gchar *anchor){   Dw_gtk_viewport_remove_anchor (viewport);   if (anchor) {      viewport->anchor = g_strdup(anchor);      Dw_gtk_viewport_update_anchor (viewport);   } else {      viewport->anchor = NULL;      gtk_adjustment_set_value (GTK_LAYOUT(viewport)->vadjustment, 0);   }}/* * Sets the position to scroll to. The current anchor will be removed. */void a_Dw_gtk_viewport_set_scrolling_position (GtkDwViewport *viewport,                                               gint pos){   Dw_gtk_viewport_remove_anchor (viewport);   Dw_gtk_viewport_scroll_to (viewport, pos);}/* * Scrolls the viewport to position y. * This is done in an idle function. */void Dw_gtk_viewport_scroll_to (GtkDwViewport *viewport,                                gint32 y){   viewport->anchor_y = y;   if (viewport->anchor_idle_id == -1)      viewport->anchor_idle_id = gtk_idle_add         (Dw_gtk_viewport_update_anchor_idle, (gpointer)viewport);}/* * Remove anchor and idle function. */void Dw_gtk_viewport_remove_anchor (GtkDwViewport *viewport){   if (viewport->anchor) {      g_free (viewport->anchor);      viewport->anchor = NULL;   }   if (viewport->anchor_idle_id != -1) {      gtk_idle_remove (viewport->anchor_idle_id);      viewport->anchor_idle_id = -1;   }}

⌨️ 快捷键说明

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