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

📄 dw_widget.c

📁 浏览器的源代码,可移植到嵌入式设备.
💻 C
📖 第 1 页 / 共 4 页
字号:
    * all other draw calls are done for children. */   GtkDwViewport *viewport;   GdkDrawable *orig_pixmap, *dest;   gint x, y;   orig_pixmap = widget->parent ? widget->parent->clip_pixmap : NULL;   widget->clip_pixmap = orig_pixmap;   gtk_signal_emit (GTK_OBJECT (widget), widget_signals[DRAW],                    area, event);   if (widget->clip_pixmap &&       (widget->parent == NULL ||        widget->clip_pixmap != widget->parent->clip_pixmap)) {      /* Copy clipping pixmap into backing pixmap, when this widget has called       * p_Dw_widget_will_clip(). */      viewport = GTK_DW_VIEWPORT (widget->viewport);      dest = orig_pixmap ? orig_pixmap : viewport->back_pixmap;      x = area->x + widget->allocation.x -         gtk_layout_get_hadjustment(GTK_LAYOUT(viewport))->value;      y = area->y + widget->allocation.y -         gtk_layout_get_vadjustment(GTK_LAYOUT(viewport))->value;      gdk_draw_pixmap (dest, widget->viewport->style->black_gc,                       widget->clip_pixmap, x, y,                       x, y, area->width, area->height);      gdk_pixmap_unref (widget->clip_pixmap);   }}void a_Dw_widget_realize (DwWidget *widget){   if (!DW_WIDGET_REALIZED (widget)) {      gtk_signal_emit (GTK_OBJECT (widget), widget_signals[REALIZE]);      DW_WIDGET_SET_FLAGS (widget, DW_REALIZED);      if (DW_IS_CONTAINER (widget))         a_Dw_container_forall (DW_CONTAINER (widget),                                (DwCallback) a_Dw_widget_realize,                                NULL);      Dw_widget_update_cursor (widget);      if (widget->parent == NULL && widget->style->background_color != NULL)         gdk_window_set_background (GTK_LAYOUT(widget->viewport)->bin_window,                                    &widget->style->background_color->color);   }}void a_Dw_widget_unrealize (DwWidget *widget){   if (DW_WIDGET_REALIZED (widget)) {      a_Dw_widget_set_cursor (widget, NULL);      gtk_signal_emit (GTK_OBJECT (widget), widget_signals[UNREALIZE]);      DW_WIDGET_UNSET_FLAGS (widget, DW_REALIZED);      if (DW_IS_CONTAINER (widget))         a_Dw_container_forall (DW_CONTAINER (widget),                                (DwCallback) a_Dw_widget_unrealize,                                NULL);   }}/* * Handles a mouse event. * * This function is called by Dw_gtk_viewport_mouse_event, the type of * the event is determined by event->type. x and y are world coordinates. * widget may be NULL (if the pointer is outside the top-level widget). * * When event is NULL, GDK_MOTION_NOTIFY is used as the type. This will * soon be the case when GDK_MOTION_NOTIFY events are simulated as a * result of viewport changes (bug #94) */gint Dw_widget_mouse_event (DwWidget *widget,                            GtkWidget *viewwidget,                            gint32 x,                            gint32 y,                            GdkEvent *event){   gint signal_no;   gboolean return_val;   DwWidgetClass *klass;   GtkDwViewport *viewport = GTK_DW_VIEWPORT (viewwidget);   GdkEventType event_type;   DwWidget *ancestor, *w1, *w2, **track;   gint track_len, i;   DEBUG_MSG(DEBUG_EVENT,             "------------------------- EVENT -------------------------\n");   /* simulate crossing events */   /* todo: resizing/moving widgets */   if (widget != viewport->last_entered) {      DEBUG_MSG (DEBUG_EVENT, "----------> crossing event\n");      DEBUG_MSG (DEBUG_EVENT, "  last = %p, now = %p\n",                 viewport->last_entered, widget);      /* Determine the next common ancestor of the widgets. */      if (viewport->last_entered == NULL || widget == NULL)         ancestor = NULL;      else {         /* There is probably a faster algorithm. ;-) */         ancestor = NULL;         for (w1 = viewport->last_entered; ancestor == NULL && w1 != NULL;              w1 = w1->parent)            for (w2 = widget; ancestor == NULL && w2 != NULL; w2 = w2->parent)               if (w1 == w2)                  ancestor = w1;      }      /* Construct the track:       * viewport->last_entered => anchestor => (current) widget */      DEBUG_MSG (DEBUG_EVENT, "common ancestor: %s %p\n",                 (ancestor ?                  gtk_type_name (GTK_OBJECT_TYPE (ancestor)) : "(none)"),                 ancestor);      track_len = 0;      if (viewport->last_entered)         for (w1 = viewport->last_entered; w1 != ancestor; w1 = w1->parent)            track_len++;      if (ancestor)         track_len++; /* for the ancestor */      if (widget)         for (w1 = widget; w1 != ancestor; w1 = w1->parent)            track_len++;      track = g_new (DwWidget*, track_len);      i = 0;      if (viewport->last_entered)         for (w1 = viewport->last_entered; w1 != ancestor; w1 = w1->parent)            track[i++] = w1;      if (ancestor)         track[i++] = ancestor;      if (widget) {         i = track_len - 1;         for (w1 = widget; w1 != ancestor; w1 = w1->parent)            track[i--] = w1;      }      /* Send events to all events on the track */      /* todo: emit signals */      for (i = 0; i < track_len; i++) {         klass = DW_WIDGET_CLASS (GTK_OBJECT(track[i])->klass);         if (i != 0) {            if (klass->enter_notify_event)               klass->enter_notify_event (track[i], track[i - 1],                                          (GdkEventMotion*) event);            DEBUG_MSG (DEBUG_EVENT, "entering %s %p\n",                       gtk_type_name (GTK_OBJECT_TYPE (track[i])), track[i]);         }         if (i != track_len - 1) {            if (klass->leave_notify_event)               klass->leave_notify_event (track[i], track[i + 1],                                          (GdkEventMotion*) event);            DEBUG_MSG (DEBUG_EVENT, "leaving %s %p\n",                       gtk_type_name (GTK_OBJECT_TYPE (track[i])), track[i]);         }      }      DEBUG_MSG (DEBUG_EVENT, "<----------\n");      g_free (track);      viewport->last_entered = widget;      if (widget)         Dw_widget_update_cursor(widget);      else         gdk_window_set_cursor (GTK_LAYOUT(viewport)->bin_window, NULL);   }   /* other events */   event_type = event ? event->type : GDK_MOTION_NOTIFY;   while (widget) {      switch (event_type) {      case GDK_BUTTON_PRESS:      case GDK_2BUTTON_PRESS:      case GDK_3BUTTON_PRESS:         if (widget->button_sensitive)            signal_no = widget_signals[BUTTON_PRESS_EVENT];         else            signal_no = -1;         break;      case GDK_BUTTON_RELEASE:         if (widget->button_sensitive)            signal_no = widget_signals[BUTTON_RELEASE_EVENT];         else            signal_no = -1;         break;      case GDK_MOTION_NOTIFY:         signal_no = widget_signals[MOTION_NOTIFY_EVENT];         break;      default:         signal_no = -1;         break;      }      DEBUG_MSG (DEBUG_EVENT, "Sending %s event to %p, a %s.\n",                 (event_type == GDK_MOTION_NOTIFY ? "motion notify" :                  event_type == GDK_BUTTON_RELEASE ? "button release" :                  "button press"),                 widget, gtk_type_name (GTK_OBJECT_TYPE (widget)));      if (signal_no != -1) {         return_val = FALSE;         gtk_signal_emit (GTK_OBJECT (widget), signal_no,                          x - widget->allocation.x, y - widget->allocation.y,                          event, &return_val);         if (return_val) {            DEBUG_MSG (DEBUG_EVENT, "-> Processed.\n");            return TRUE;         }      }      widget = widget->parent;   }   DEBUG_MSG (DEBUG_EVENT, "-> Not processed at all.\n");   return FALSE;}/* *  Change the style of a widget. The old style is automatically *  unreferred, the new is referred. If this call causes the widget to *  change its size, Dw_widget_queue_resize is called. */void a_Dw_widget_set_style (DwWidget *widget,                            DwStyle *style){   gboolean size_changed;   if (widget->style) {      a_Dw_style_unref (widget->style);      size_changed = a_Dw_style_size_diffs (widget->style, style);   } else      size_changed = TRUE;   a_Dw_style_ref (style);   widget->style = style;   if (widget->parent == NULL &&       DW_WIDGET_REALIZED (widget) &&       widget->style->background_color != NULL)      gdk_window_set_background (GTK_LAYOUT(widget->viewport)->bin_window,                                 &widget->style->background_color->color);   if (DW_WIDGET_REALIZED (widget)) {      if (size_changed)         p_Dw_widget_queue_resize (widget, 0, TRUE);      else         p_Dw_widget_queue_draw (widget);   }}/* * Set the cursor of the viewport. * Called from several other functions. */static void Dw_widget_update_cursor (DwWidget *widget){   GtkDwViewport *viewport = GTK_DW_VIEWPORT (widget->viewport);   DwWidget *cursor_widget;   if (GTK_WIDGET_REALIZED (viewport)) {      /* Search cursor to use, going up from last_entered (not from widget!).       */      cursor_widget = viewport->last_entered;      while (cursor_widget && cursor_widget->cursor == NULL)         cursor_widget = cursor_widget->parent;      if (cursor_widget)         gdk_window_set_cursor (GTK_LAYOUT(viewport)->bin_window,                                cursor_widget->cursor);      else         gdk_window_set_cursor (GTK_LAYOUT(viewport)->bin_window,                                NULL);   }}/* * Set the cursor for a DwWidget. cursor has to be stored elsewhere, it * is not copied (and not destroyed). If cursor is NULL, the cursor of * the parent widget is used. */void a_Dw_widget_set_cursor (DwWidget *widget,                             GdkCursor *cursor){   widget->cursor = cursor;   if (DW_WIDGET_REALIZED (widget))      Dw_widget_update_cursor (widget);}/* * If this function is called with button_sensitive == FALSE, the widget will * never receive button press/release events, instead they are sent to the * parent widgets. This attribute is inherited from the parent, if this * function is never called. * * TODO: A bit hackish, this is only needed for disabling selection * within <BUTTON>'s, and so make the button accessible at all. * It would be better to handle this problem in a way links are handled, * but this case is much more complicated, since a button is more complex * than a link. * * NOTE: This may be replaced by somehow using signals for events. */void a_Dw_widget_set_button_sensitive (DwWidget *widget,                                       gboolean button_sensitive){   widget->button_sensitive = button_sensitive;   widget->button_sensitive_set = TRUE;}/* * ... */DwWidget *a_Dw_widget_get_toplevel (DwWidget *widget){   while (widget->parent)      widget = widget->parent;   return widget;}/* * Scrolls the viewport, so that the region [x, y, width, height] (widget * coordinates) is seen, according to hpos and vpos. */void a_Dw_widget_scroll_to (DwWidget *widget,                            DwHPosition hpos,                            DwVPosition vpos,                            gint32 x,                            gint32 y,                            gint32 width,                            gint32 height){   Dw_gtk_viewport_scroll_to (GTK_DW_VIEWPORT (widget->viewport),                              hpos, vpos,                              x + widget->allocation.x,                              y + widget->allocation.y,                              width, height);}/* * Retreive an iterator pointing before the first content element * of the widget. */DwIterator* a_Dw_widget_iterator (DwWidget *widget,                                  gint mask,                                  gboolean at_end){   DwWidgetClass *klass =  DW_WIDGET_CLASS (GTK_OBJECT(widget)->klass);   if (klass->iterator)      return klass->iterator(widget, mask, at_end);   else      return NULL;}/* * This implementation of DwIterator::clone() can be used, when the * structure DwIterator is used. */DwIterator* p_Dw_iterator_clone_std (DwIterator *it){   DwIterator *it2 = g_new (DwIterator, 1);   *it2 = *it;   return it2;}/* * An implementation of DwIterator::free(), which should be sufficient for most * iterator implementations. */void p_Dw_iterator_free_std (DwIterator *it){   g_free (it);}/* * No-op implementation of DwIterator::highlight(). */void p_Dw_iterator_highlight_std (DwIterator *it,                                  gint start,                                  gint end,                                  DwHighlightLayer layer){   /* do nothing */}/* * This implementation of DwIterator::get_allocation can be used by all * widgets, whose iterators only return widgets themselves. */void p_Dw_iterator_get_allocation_std_only_widgets (DwIterator *it,                                                    gint start,                                                    gint end,                                                    DwAllocation *allocation){   g_return_if_fail (it->content.type == DW_CONTENT_WIDGET);   *allocation = it->content.data.widget->allocation;}/* * Scrolls the viewport, so that the region between it1 and it2 is * seen, according to hpos and vpos. The parameters start and end have * the same meaning as in DwIterator::get_allocation(); start refers * to it1, while end ferers to it2. * * If it1 and it2 point to the same location (see code below), only * it1 is regarded, and both start and end refer to it. */void a_Dw_iterator_scroll_to (DwIterator *it1,                              DwIterator *it2,                              gint start,                              gint end,                              DwHPosition hpos,                              DwVPosition vpos){   DwAllocation alloc1, alloc2, alloc;   gint32 x1, x2, y1, y2, vp_width, vp_height;   DwExtIterator *eit1, *eit2, *eit;   gint cur_start, cur_end, cmp;   gboolean at_start;   DBG_MSG (it1->widget->viewport, "scrolling", 0, "a_Dw_iterator_scroll_to");   DBG_MSG_START (it1->widget->viewport);   if (it1 == it2 ||       (it1->widget == it2->widget && a_Dw_iterator_compare (it1, it2) == 0)) {      a_Dw_iterator_get_allocation (it1, start, end, &alloc);

⌨️ 快捷键说明

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