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

📄 dw_widget.c

📁 浏览器的源代码,可移植到嵌入式设备.
💻 C
📖 第 1 页 / 共 4 页
字号:
   child_area.x = widget->allocation.x;   child_area.y = widget->allocation.y;   child_area.width = widget->allocation.width;   child_area.height = DW_WIDGET_HEIGHT(widget);   if (p_Dw_rectangle_intersect (&parent_area, &child_area, intersection)) {      intersection->x -= widget->allocation.x;      intersection->y -= widget->allocation.y;      return TRUE;   } else      return FALSE;#else   intersection->x = 0;   intersection->y = 0;   intersection->width = widget->allocation.width;   intersection->height = DW_WIDGET_HEIGHT(widget);   return TRUE;#endif}void p_Dw_widget_set_parent (DwWidget *widget,                             DwWidget *parent){   gtk_object_ref (GTK_OBJECT (widget));   gtk_object_sink (GTK_OBJECT (widget));   widget->parent = parent;   widget->viewport = parent->viewport;   /*widget->window = parent->window;*/   if (!widget->button_sensitive_set)      widget->button_sensitive = parent->button_sensitive;   DBG_OBJ_ASSOC (widget, parent);   if (DW_WIDGET_REALIZED (parent))      a_Dw_widget_realize (widget);}/* * Converting between coordinates. */gint32 p_Dw_widget_x_viewport_to_world (DwWidget *widget,                                        gint16 viewport_x){   GtkAdjustment *adjustment;   g_return_val_if_fail (widget && widget->viewport, 0);   adjustment = gtk_layout_get_hadjustment (GTK_LAYOUT (widget->viewport));   g_return_val_if_fail (adjustment != NULL, 0);   return viewport_x + (gint32)adjustment->value;}gint32 p_Dw_widget_y_viewport_to_world (DwWidget *widget,                                        gint16 viewport_y){   GtkAdjustment *adjustment;   g_return_val_if_fail (widget && widget->viewport, 0);   adjustment = gtk_layout_get_vadjustment (GTK_LAYOUT (widget->viewport));   g_return_val_if_fail (adjustment != NULL, 0);   return viewport_y + (gint32)adjustment->value;}gint16 p_Dw_widget_x_world_to_viewport (DwWidget *widget,                                        gint32 world_x){   GtkAdjustment *adjustment;   g_return_val_if_fail (widget && widget->viewport, 0);   adjustment = gtk_layout_get_hadjustment (GTK_LAYOUT (widget->viewport));   g_return_val_if_fail (adjustment != NULL, 0);   return world_x - (gint32)adjustment->value;}gint16 p_Dw_widget_y_world_to_viewport (DwWidget *widget,                                        gint32 world_y){   GtkAdjustment *adjustment;   g_return_val_if_fail (widget && widget->viewport, 0);   adjustment = gtk_layout_get_vadjustment (GTK_LAYOUT (widget->viewport));   g_return_val_if_fail (adjustment != NULL, 0);   return world_y - (gint32)adjustment->value;}/* * Calculate the intersection of (x, y, width, height) (widget * coordinates) and the current viewport area. gdk_intersection has * (of course) viewport coordinates, the return value is TRUE iff the * intersection is not empty. */static gboolean Dw_widget_intersect_viewport (DwWidget *widget,                                              gint32 x,                                              gint32 y,                                              gint32 width,                                              gint32 height,                                              GdkRectangle *gdk_intersection){   GtkLayout *layout;   DwRectangle widget_area, viewport_area, intersection;   g_return_val_if_fail (widget && widget->viewport, FALSE);   layout = GTK_LAYOUT (widget->viewport);   widget_area.x = widget->allocation.x + x;   widget_area.y = widget->allocation.y + y;   widget_area.width = width;   widget_area.height = height;   viewport_area.x = layout->xoffset;   viewport_area.y = layout->yoffset;   viewport_area.width = widget->viewport->allocation.width;   viewport_area.height = widget->viewport->allocation.height;   if (p_Dw_rectangle_intersect (&widget_area, &viewport_area,                                 &intersection)) {      gdk_intersection->x = intersection.x - layout->xoffset;      gdk_intersection->y = intersection.y - layout->yoffset;      gdk_intersection->width = intersection.width;      gdk_intersection->height = intersection.height;      return TRUE;   } else      return FALSE;}/* * ... */void p_Dw_widget_queue_draw (DwWidget *widget){   p_Dw_widget_queue_draw_area (widget, 0, 0, widget->allocation.width,                                DW_WIDGET_HEIGHT(widget));}/* * ... */void p_Dw_widget_queue_draw_area (DwWidget *widget,                                  gint32 x,                                  gint32 y,                                  gint32 width,                                  gint32 height){   /* todo: maybe only the intersection? */   Dw_gtk_viewport_queue_draw (GTK_DW_VIEWPORT (widget->viewport),                               x + widget->allocation.x,                               y + widget->allocation.y, width, height);}/* * Resizing of Widgets. * The interface was adopted by Gtk+, but the implementation is far simpler, * since Gtk+ handles a lot of cases which are irrelevant to Dw. *//* * This function should be called, if the widget changed its size. */void p_Dw_widget_queue_resize (DwWidget *widget,                               gint ref,                               gboolean extremes_changed){   DwWidget *widget2, *child;   DwWidgetClass *klass;   DEBUG_MSG (DEBUG_SIZE,              "a %stop-level %s with parent_ref = %d has changed its size\n",              widget->parent ? "non-" : "",              gtk_type_name (GTK_OBJECT_TYPE (widget)), widget->parent_ref);   klass =  (DwWidgetClass*)(((GtkObject*)widget)->klass);   DW_WIDGET_SET_FLAGS (widget, DW_NEEDS_RESIZE);   if (klass->mark_size_change)      klass->mark_size_change (widget, ref);   if (extremes_changed) {      DW_WIDGET_SET_FLAGS (widget, DW_EXTREMES_CHANGED);      if (klass->mark_extremes_change)         klass->mark_extremes_change (widget, ref);   }   for (widget2 = widget->parent, child = widget;        widget2;        child = widget2, widget2 = widget2->parent) {      klass =  (DwWidgetClass*)(((GtkObject*)widget2)->klass);      DW_WIDGET_SET_FLAGS (widget2, DW_NEEDS_RESIZE);      if (klass->mark_size_change)         klass->mark_size_change (widget2, child->parent_ref);      DW_WIDGET_SET_FLAGS (widget2, DW_NEEDS_ALLOCATE);      DEBUG_MSG (DEBUG_ALLOC,                 "setting DW_NEEDS_ALLOCATE for a %stop-level %s "                 "with parent_ref = %d\n",                 widget2->parent ? "non-" : "",                 gtk_type_name (GTK_OBJECT_TYPE (widget2)),                 widget2->parent_ref);      if (extremes_changed) {         DW_WIDGET_SET_FLAGS (widget2, DW_EXTREMES_CHANGED);         if (klass->mark_extremes_change)            klass->mark_extremes_change (widget2, child->parent_ref);      }   }   if (widget->viewport)      Dw_gtk_viewport_queue_resize (GTK_DW_VIEWPORT (widget->viewport));}/* * If a widget might draw outside of its allocation, this function should be * called at the beginning of the draw method. It will cause drawings be done * in a temporary pixmap, which is later copied into the backing pixmap, so * that drawings outside of the allocation are later discarded. * * Clipping causes a bit overhead due to the second copying, so it should * only used when neccessary. */void p_Dw_widget_will_clip (DwWidget *widget){   DwWidget *widget2;   widget->clip_pixmap =      gdk_pixmap_new (widget->viewport->window,                      widget->viewport->allocation.width,                      widget->viewport->allocation.height,                      GTK_DW_VIEWPORT(widget->viewport)->depth);   /* Determine the effective background color. (There is a defined background    * at least for the top-level widget.) */   for (widget2 = widget;        widget2 != NULL && widget2->style->background_color == NULL;        widget2 = widget2->parent)      ;   g_return_if_fail (widget2 != NULL);   gdk_draw_rectangle (widget->clip_pixmap,                       widget2->style->background_color->gc,                       TRUE, 0, 0,                       widget->viewport->allocation.width,                       widget->viewport->allocation.height);}/* * Set the background "behind" the widget, if it is not the background of the * parent widget, e.g. the background of a table row. */void p_Dw_widget_set_bg_color (DwWidget *widget,                               DwStyleColor *color){   widget->bg_color = color;}/* * Get the actual background of a widget. */DwStyleColor* p_Dw_widget_get_bg_color (DwWidget *widget){   while (widget != NULL) {      if (widget->style->background_color)         return widget->style->background_color;      if (widget->bg_color)         return widget->bg_color;      widget = widget->parent;   }   g_warning ("No background color found!");   return NULL;}/* * Draw borders and background of a widget part, which allocation is * given by (x, y, width, height) (widget coordinates). */void p_Dw_widget_draw_box (DwWidget *widget,                           DwStyle *style,                           DwRectangle *area,                           gint32 x,                           gint32 y,                           gint32 width,                           gint32 height,                           gboolean inverse){   GdkRectangle gdk_area;   gint32 vx, vy;   if (Dw_widget_intersect_viewport (widget, area->x, area->y,                                     area->width, area->height, &gdk_area)) {      vx = p_Dw_widget_x_viewport_to_world (widget, 0);      vy = p_Dw_widget_y_viewport_to_world (widget, 0);      p_Dw_style_draw_border (DW_WIDGET_WINDOW (widget), &gdk_area,                              vx, vy,                              widget->allocation.x + x,                              widget->allocation.y + y,                              width, height,                              style, inverse);      if (style->background_color)         p_Dw_style_draw_background (DW_WIDGET_WINDOW (widget), &gdk_area,                                     vx, vy,                                     widget->allocation.x + x,                                     widget->allocation.y + y,                                     width, height,                                     style, inverse);   }}/* * Draw borders and background of a widget. */void p_Dw_widget_draw_widget_box (DwWidget *widget,                                  DwRectangle *area,                                  gboolean inverse){   GdkRectangle gdk_area;   gint32 vx, vy;   if (Dw_widget_intersect_viewport (widget, area->x, area->y,                                     area->width, area->height, &gdk_area)) {      vx = p_Dw_widget_x_viewport_to_world (widget, 0);      vy = p_Dw_widget_y_viewport_to_world (widget, 0);      p_Dw_style_draw_border (DW_WIDGET_WINDOW (widget), &gdk_area,                              vx, vy,                              widget->allocation.x,                              widget->allocation.y,                              widget->allocation.width,                              DW_WIDGET_HEIGHT(widget),                              widget->style, inverse);      /* - Toplevel widget background colors are set as viewport       *   background color. This is not crucial for the rendering, but       *   looks a bit nicer when scrolling. Furthermore, the viewport       *   does anything else in this case.       *       * - Since widgets are always drawn from top to bottom, it is       *   *not* necessary to draw the background if       *   widget->style->background_color is NULL (shining through).       */      if (widget->parent && widget->style->background_color)         p_Dw_style_draw_background (DW_WIDGET_WINDOW (widget), &gdk_area,                                     vx, vy,                                     widget->allocation.x,                                     widget->allocation.y,                                     widget->allocation.width,                                     DW_WIDGET_HEIGHT(widget),                                     widget->style, inverse);   }}/* * This function is used by some widgets, when they are selected (as a whole). * * todo: This could be accelerated by using clipping bitmaps. Two important * issues: * *     (i) There should always been a pixel in the upper-left corner of the *         *widget*, so probably two different clipping bitmaps have to be *         used (10/01 and 01/10). * *    (ii) Should a new GC always be created? */void p_Dw_widget_draw_selected (DwWidget *widget,                                DwRectangle *area){   GdkRectangle gdk_area;   /* All coordinates are widget coordinates. */   gint32 x, y, startxa, startya, startxb, startyb, endx, endy, ix, iy;   gint32 dx, dy; /* the difference between viewport and widget */   DwStyleColor *bg_color;   GdkWindow *window;   if (Dw_widget_intersect_viewport (widget, area->x, area->y,                                     area->width, area->height, &gdk_area)) {      /* Calculate from where to start the respective drawing loops below.       * There should always been a pixel in the upper-left corner of the       * *widget*, so the start depends on whether the drawing area (in widget       * coordinates) has even or odd offsets. */      /* the intersection in widget coordinates */      ix = p_Dw_widget_x_viewport_to_world (widget, gdk_area.x) -         widget->allocation.x;      iy = p_Dw_widget_y_viewport_to_world (widget, gdk_area.y) -         widget->allocation.y;      if (ix % 2 == 0) {         startxa = ix;         startxb = ix + 1;      } else {         startxa = ix + 1;         startxb = ix;      }      if (iy % 2 == 0) {         startya = iy;         startyb = iy + 1;      } else {         startya = iy + 1;         startyb = iy;      }      dx = p_Dw_widget_x_world_to_viewport (widget, widget->allocation.x);      dy = p_Dw_widget_y_world_to_viewport (widget, widget->allocation.y);      endx = ix + gdk_area.width;      endy = iy + gdk_area.height;      bg_color = p_Dw_widget_get_bg_color (widget);      window = DW_WIDGET_WINDOW (widget);      for (x = startxa; x < endx; x += 2)         for (y = startya; y < endy; y += 2)            gdk_draw_point (window, bg_color->inverse_gc, x + dx, y + dy);      for (x = startxb; x < endx; x += 2)         for (y = startyb; y < endy; y += 2)            gdk_draw_point (window, bg_color->inverse_gc, x + dx, y + dy);   }}

⌨️ 快捷键说明

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