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

📄 dw_widget.c

📁 浏览器的源代码,可移植到嵌入式设备.
💻 C
📖 第 1 页 / 共 4 页
字号:
      Dw_gtk_viewport_scroll_to (GTK_DW_VIEWPORT (it1->widget->viewport),                                 hpos, vpos, alloc.x, alloc.y,                                 alloc.width, alloc.ascent + alloc.descent);   } else {      /* First, determine the rectangle all iterators from it1 and it2       * allocate, i.e. the smallest rectangle containing all allocations of       * these iterators. */      eit1 = a_Dw_ext_iterator_new (it1);      eit2 = a_Dw_ext_iterator_new (it2);      x1 = DW_INFINITY;      x2 = - DW_INFINITY;      y1 = DW_INFINITY;      y2 = - DW_INFINITY;      DBG_MSG_START (it1->widget->viewport);      for (eit = a_Dw_ext_iterator_clone (eit1), at_start = TRUE;           (cmp = a_Dw_ext_iterator_compare (eit, eit2)) <= 0;           a_Dw_ext_iterator_next (eit), at_start = FALSE) {         if (at_start)            cur_start = start;         else            cur_start = 0;         if (cmp == 0)            cur_end = end;         else            cur_end = DW_INFINITY;         a_Dw_ext_iterator_get_allocation (eit, cur_start, cur_end, &alloc);         DBG_MSGF (it1->widget->viewport, "scrolling", 0,                   "allocation of %s, from %d to %d: [%d, %d, %d x %d x %d]\n",                   a_Dw_content_html (&eit->content), cur_start, cur_end,                   alloc.x, alloc.y, alloc.width, alloc.ascent, alloc.descent);         x1 = MIN (x1, alloc.x);         x2 = MAX (x2, alloc.x + alloc.width);         y1 = MIN (y1, alloc.y);         y2 = MAX (y2, alloc.y + alloc.ascent + alloc.descent);         DBG_MSGF (it1->widget->viewport, "scrolling", 0,                   "result is [%d, %d, %d x %d]", x1, y1, x2 - x1, y2 - y1);      }      DBG_MSG_END (it1->widget->viewport);      DBG_MSGF (it1->widget->viewport, "scrolling", 0,                "1. region is [%d, %d, %d x %d]", x1, y1, x2 - x1, y2 - y1);      a_Dw_iterator_get_allocation (it1, start, DW_INFINITY, &alloc1);      a_Dw_iterator_get_allocation (it2, 0, end, &alloc2);      DBG_MSGF (it1->widget->viewport, "scrolling", 0,                "alloc1 = [%d, %d, %d x %d x %d]",                alloc1.x, alloc1.y,                alloc1.width, alloc1.ascent, alloc1.descent);      DBG_MSGF (it2->widget->viewport, "scrolling", 0,                "alloc2 = [%d, %d, %d x %d x %d]",                alloc2.x, alloc2.y,                alloc2.width, alloc2.ascent, alloc2.descent);      if (alloc1.x > alloc2.x) {         /*          * This is due to a line break within the region. When the line is          * longer than the viewport, and the region is actually quite short,          * the user would not see anything of the region, as in this figure          * (with region marked as "#"):          *          *            +----------+   ,-- alloc1          *            |          |   V          *            |          |  ### ###          *   ### ###  |          |          *        ^   |          | <-- viewport          *        |   +----------+          *        `-- alloc2          *   |----------------------------|          *               width          *          * Therefor, we the region smaller, so that the region will be          * displayed like this:          *          *                           ,-- alloc1          *                      +----|-----+          *                      |    V     |          *                      |   ### ###|          *   ### ###            |          |          *        ^             |          | <-- viewport          *        `-- alloc2    +----------+          *                      |----------|          *                         width          *          * todo: Changes in the viewport size, until the idle function is          * called, are not regarded.          */         vp_width = it1->widget->viewport->allocation.width            - GTK_CONTAINER(it1->widget->viewport)->border_width;         DBG_MSGF (it2->widget->viewport, "scrolling", 0,                   "vp_width = %d", vp_width);         if (x2 - x1 > vp_width) {            x1 = x2 - vp_width;            x2 = x1 + vp_width;         }      }      if (alloc1.y > alloc2.y) {         /* This is similar to the case above, e.g. if the region ends in          * another table column. */         vp_height = it1->widget->viewport->allocation.height            - GTK_CONTAINER(it1->widget->viewport)->border_width;         DBG_MSGF (it2->widget->viewport, "scrolling", 0,                   "vp_height = %d", vp_height);         if (y2 - y1 > vp_height) {            y1 = y2 - vp_height;            y2 = y1 + vp_height;         }      }      DBG_MSGF (it1->widget->viewport, "scrolling", 0,                "2. region is [%d, %d, %d x %d]",  x1, y1, x2 - x1, y2 - y1);      Dw_gtk_viewport_scroll_to (GTK_DW_VIEWPORT (it1->widget->viewport),                                 hpos, vpos,  x1, y1, x2 - x1, y2 - y1);   }   DBG_MSG_END (it1->widget->viewport);}/* * For DwIteratorInt. */DwIterator* p_Dw_iterator_clone_std_int (DwIterator *it){   DwIteratorInt *it2 = g_new (DwIteratorInt, 1);   *it2 = *(DwIteratorInt*)it;   return (DwIterator*)it2;}/* * For DwIteratorInt. */gint p_Dw_iterator_compare_std_int (DwIterator *it1,                                    DwIterator *it2){   DwIteratorInt *ii1 = (DwIteratorInt*)it1;   DwIteratorInt *ii2 = (DwIteratorInt*)it2;   g_return_val_if_fail (it1->widget == it2->widget, 0);   if (ii1->pos == ii2->pos)      return 0;   if (ii1->pos < ii2->pos)      return -1;   else      return +1;}/* * This function returns a descriptive text for a piece of content, * useful for debugging. * NOTE: This function is not very reliable, and should really only * used for non-critical tasks like debugging. */gchar *a_Dw_content_text (DwContent *content){   /* We cycle through several buffers, so that printf should have    * no problems. */#define BUF_NUM     5#define BUF_SIZE 2048   static gchar buf[BUF_SIZE * BUF_NUM];   static int cur_buf = 0;   gchar *ptr;   ptr = buf + cur_buf * BUF_SIZE;   cur_buf = (cur_buf + 1) % BUF_NUM;   switch (content->type) {   case DW_CONTENT_START:      sprintf (ptr, "<start>");      break;   case DW_CONTENT_END:      sprintf (ptr, "<end>");      break;   case DW_CONTENT_TEXT:      sprintf (ptr, "\"%s\"", content->data.text);      break;   case DW_CONTENT_WIDGET:      sprintf (ptr, "the %s %p",               gtk_type_name (GTK_OBJECT_TYPE (content->data.widget)),               content->data.widget);      break;   case DW_CONTENT_ANCHOR:      sprintf (ptr, "#%s", content->data.anchor);      break;   case DW_CONTENT_BREAK:      sprintf (ptr, "<break(%d)>", content->data.break_space);      break;   default:      sprintf (ptr, "<unknown %d>", content->type);      break;   }   return ptr;}/* * Like a_Dw_content_text, but returns HTML. * NOTE: This function is not very reliable, and should really only * used for non-critical tasks like debugging. */gchar* a_Dw_content_html (DwContent *content){   /* We cycle through several buffers, so that printf should have    * no problems. */#define BUF_NUM     5#define BUF_SIZE 2048   static gchar buf[BUF_SIZE * BUF_NUM];   static int cur_buf = 0;   gchar *ptr, *ptr1, *ptr2;   ptr = buf + cur_buf * BUF_SIZE;   cur_buf = (cur_buf + 1) % BUF_NUM;   switch (content->type) {   case DW_CONTENT_START:      sprintf (ptr, "<i>&lt;start&gt;</i>");      break;   case DW_CONTENT_END:      sprintf (ptr, "<i>&lt;end&gt;</i>");      break;   case DW_CONTENT_TEXT:      *ptr = '"';      ptr2 = ptr + 1;      for (ptr1 = content->data.text; *ptr1; ptr1++) {         switch (*ptr1) {         case '<':            strcpy (ptr2, "&lt;");            ptr2 += 4;            break;         case '>':            strcpy (ptr2, "&gt;");            ptr2 += 4;            break;         case '&':            strcpy (ptr2, "&amp;");            ptr2 += 5;            break;         default:            *ptr2 = *ptr1;            ptr2++;         }      }      ptr2[0] = '"';      ptr2[1] = 0;      break;   case DW_CONTENT_WIDGET:      sprintf (ptr, "the %s %p",               gtk_type_name (GTK_OBJECT_TYPE (content->data.widget)),               content->data.widget);      break;   case DW_CONTENT_ANCHOR:      sprintf (ptr, "#%s", content->data.anchor);      break;   case DW_CONTENT_BREAK:      sprintf (ptr, "<i>&lt;break(%d)&gt;</i>", content->data.break_space);      break;   default:      sprintf (ptr, "<i>&lt;unknown %d&gt;</i>", content->type);      break;   }   return ptr;}/* * This function returns a descriptive text for an iterator, useful * for debugging. * NOTE: This function is not very reliable, and should really only * used for non-critical tasks like debugging. */gchar *a_Dw_iterator_text (DwIterator *it){   /* We cycle through several buffers, so that printf should have    * no problems. */#define BUF_NUM     5#define BUF_SIZE 2048   static gchar buf[BUF_SIZE * BUF_NUM];   static int cur_buf = 0;   gchar *ptr;   ptr = buf + cur_buf * BUF_SIZE;   cur_buf = (cur_buf + 1) % BUF_NUM;   if (it)      sprintf (ptr, "[%s in the %s %p]",               a_Dw_content_text (&it->content),               gtk_type_name (GTK_OBJECT_TYPE (it->widget)), it->widget);   else      strcpy (ptr, "[NULL]");   return ptr;}/* * This function prints the contents of a whole widget tree. * NOTE: This function is not very reliable, and should really only * used for non-critical tasks like debugging. */static void Dw_widget_print_tree0 (DwWidget *widget, int indent){   DwIterator *it;   MSG ("%*sthe %s %p, contains:\n",        indent, "", gtk_type_name (GTK_OBJECT_TYPE (widget)), widget);   it = a_Dw_widget_iterator (widget, 0xff, FALSE);   while (a_Dw_iterator_next (it)) {      if (it->content.type == DW_CONTENT_WIDGET)         Dw_widget_print_tree0 (it->content.data.widget, indent + 3);      else         MSG ("%*s%s\n", indent + 3, "", a_Dw_content_text (&it->content));   }}void a_Dw_widget_print_tree (DwWidget *widget){   MSG ("--- START OF WIDGET TREE ---\n");   Dw_widget_print_tree0 (widget, 0);   MSG ("--- END OF WIDGET TREE ---\n");}/* * The following is a standard implementation for iterators containing * exactly one piece of text. */DwIterator* p_Dw_widget_text_iterator (DwWidget *widget,                                       gint32 mask,                                       gboolean at_end,                                       gchar *text){   DwIteratorText *it;   if (mask & DW_CONTENT_TEXT) {      it = g_new (DwIteratorText, 1);      it->it.widget = widget;      it->it.mask = mask;      it->it.content.type = (at_end ? DW_CONTENT_END : DW_CONTENT_START);      it->it.next = p_Dw_iterator_text_next;      it->it.prev = p_Dw_iterator_text_prev;      it->it.clone = p_Dw_iterator_text_clone;      it->it.compare = p_Dw_iterator_text_compare;      it->it.free = p_Dw_iterator_free_std;      it->it.highlight = p_Dw_iterator_highlight_std;      it->it.get_allocation = p_Dw_iterator_text_get_allocation;      it->text = text;   } else      it = NULL;   return (DwIterator*)it;}gboolean p_Dw_iterator_text_next (DwIterator *it){   if (it->content.type == DW_CONTENT_START) {      it->content.type = DW_CONTENT_TEXT;      it->content.data.text = ((DwIteratorText*)it)->text;      return TRUE;   } else {      it->content.type = DW_CONTENT_END;      return FALSE;   }}gboolean p_Dw_iterator_text_prev (DwIterator *it){   if (it->content.type == DW_CONTENT_END) {      it->content.type = DW_CONTENT_TEXT;      it->content.data.text = ((DwIteratorText*)it)->text;      return TRUE;   } else {      it->content.type = DW_CONTENT_START;      return FALSE;   }}DwIterator* p_Dw_iterator_text_clone (DwIterator *it){   DwIteratorText *it2 = g_new (DwIteratorText, 1);   *it2 = *(DwIteratorText*)it;   return (DwIterator*)it2;}gint p_Dw_iterator_text_compare (DwIterator *it1,                                 DwIterator *it2){   if (it1->content.type == it2->content.type)      return 0;   switch (it1->content.type) {   case DW_CONTENT_START:      return -1;   case DW_CONTENT_TEXT:      if (it2->content.type == DW_CONTENT_START)         return +1;      else         return -1;   case DW_CONTENT_END:      return +1;   default:      return 0;   }}void p_Dw_iterator_text_get_allocation (DwIterator *it,                                        gint start,                                        gint end,                                        DwAllocation *allocation){   /*    * Return the allocation of the widget. This is a bit incorrect, since    * start and end are not regarded, but should be correct enough for most    * purposes.    */   *allocation = it->widget->allocation;}/* * Calculates the intersection of widget->allocation and area, returned in * intersection (in widget coordinates!). Typically used by containers when * drawing their children. Returns whether intersection is not empty. */gint p_Dw_widget_intersect (DwWidget *widget,                            DwRectangle *area,                            DwRectangle *intersection){#if 1   DwRectangle parent_area, child_area;   parent_area = *area;   parent_area.x += widget->parent->allocation.x;   parent_area.y += widget->parent->allocation.y;

⌨️ 快捷键说明

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