📄 dw_widget.c
字号:
* Standard Dw function */static gint Dw_widget_real_button_press (DwWidget *widget, gint32 x, gint32 y, GdkEventButton *event){ /* not handled */ return FALSE;}/* * Standard Dw function */static gint Dw_widget_real_button_release (DwWidget *widget, gint32 x, gint32 y, GdkEventButton *event){ /* not handled */ return FALSE;}/* * Standard Dw function */static gint Dw_widget_real_motion_notify (DwWidget *widget, gint32 x, gint32 y, GdkEventMotion *event){ /* not handled */ return FALSE;}/* * Standard Dw function */static gint Dw_widget_real_enter_notify (DwWidget *widget, DwWidget *last_widget, GdkEventMotion *event){ /* not handled */ return FALSE;}/* * Standard Dw function */static gint Dw_widget_real_leave_notify (DwWidget *widget, DwWidget *next_widget, GdkEventMotion *event){ /* not handled */ return FALSE;}/* * This function is a wrapper for DwWidget::size_request; it calls * this method only when needed. */void a_Dw_widget_size_request (DwWidget *widget, DwRequisition *requisition){ if (DW_WIDGET_NEEDS_RESIZE (widget)) { /* todo: check requisition == &(widget->requisition) and do what? */ gtk_signal_emit (GTK_OBJECT (widget), widget_signals[SIZE_REQUEST], requisition); widget->requisition = *requisition; DW_WIDGET_UNSET_FLAGS (widget, DW_NEEDS_RESIZE); } else *requisition = widget->requisition;}/* * Wrapper for DwWidget::get_extremes. */void a_Dw_widget_get_extremes (DwWidget *widget, DwExtremes *extremes){ DwWidgetClass *klass; if (DW_WIDGET_EXTREMES_CHANGED (widget)) { klass = DW_WIDGET_CLASS (GTK_OBJECT(widget)->klass); (* (klass->get_extremes)) (widget, extremes); widget->extremes = *extremes; DW_WIDGET_UNSET_FLAGS (widget, DW_EXTREMES_CHANGED); } else *extremes = widget->extremes;}/* * Wrapper for DwWidget::size_allocate, only called when needed. */void a_Dw_widget_size_allocate (DwWidget *widget, DwAllocation *allocation){ if (DW_WIDGET_NEEDS_ALLOCATE (widget) || allocation->x != widget->allocation.x || allocation->y != widget->allocation.y || allocation->width != widget->allocation.width || allocation->ascent != widget->allocation.ascent || allocation->descent != widget->allocation.descent) { gtk_signal_emit (GTK_OBJECT (widget), widget_signals[SIZE_ALLOCATE], allocation); widget->allocation = *allocation; } /*DW_WIDGET_UNSET_FLAGS (widget, DW_NEEDS_RESIZE);*/}void a_Dw_widget_set_width (DwWidget *widget, gint32 width){ gtk_signal_emit (GTK_OBJECT (widget), widget_signals[SET_WIDTH], width);}void a_Dw_widget_set_ascent (DwWidget *widget, gint32 ascent){ gtk_signal_emit (GTK_OBJECT (widget), widget_signals[SET_ASCENT], ascent);}void a_Dw_widget_set_descent (DwWidget *widget, gint32 descent){ gtk_signal_emit (GTK_OBJECT (widget), widget_signals[SET_DESCENT], descent);}void a_Dw_widget_draw (DwWidget *widget, DwRectangle *area, GdkEventExpose *event){ gtk_signal_emit (GTK_OBJECT (widget), widget_signals[DRAW], area, event);}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){ /* todo: implement as signals */ gint (*function)(); DwWidgetClass *klass; GtkDwViewport *viewport = GTK_DW_VIEWPORT (viewwidget); GdkEventType event_type; DwWidget *ancestor, *w1, *w2, **track; gint track_len, i; /* simulate crossing events */ /* todo: resizing/moving widgets */ if (widget != viewport->last_entered) { /* 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 */ 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 */ for (i = 0; i < track_len; i++) { klass = DW_WIDGET_CLASS (GTK_OBJECT(track[i])->klass); if (i != 0) klass->enter_notify_event (track[i], track[i - 1], (GdkEventMotion*) event); if (i != track_len - 1) klass->leave_notify_event (track[i], track[i + 1], (GdkEventMotion*) event); } g_free (track); viewport->last_entered = widget; gdk_window_set_cursor (GTK_LAYOUT(viewport)->bin_window, NULL); } /* other events */ event_type = event ? event->type : GDK_MOTION_NOTIFY; while (widget) { klass = DW_WIDGET_CLASS (GTK_OBJECT (widget)->klass); switch (event_type) { case GDK_BUTTON_PRESS: case GDK_2BUTTON_PRESS: case GDK_3BUTTON_PRESS: function = klass->button_press_event; break; case GDK_BUTTON_RELEASE: function = klass->button_release_event; break; case GDK_MOTION_NOTIFY: function = klass->motion_notify_event; break; default: function = NULL; break; } if (function != NULL && (*function) (widget, x - widget->allocation.x, y - widget->allocation.y, event)) return TRUE; widget = widget->parent; } 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. (todo: the * latter is not implemented yet) */void a_Dw_widget_set_style (DwWidget *widget, DwStyle *style){ if (widget->style) a_Dw_style_unref (widget->style); 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);}/* * 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);}/* * ... */DwWidget *a_Dw_widget_get_toplevel (DwWidget *widget){ while (widget->parent) widget = widget->parent; return widget;}/* * Scroll viewport to pos (vertical widget coordinate). */void a_Dw_widget_scroll_to (DwWidget *widget, int pos){ Dw_gtk_viewport_scroll_to (GTK_DW_VIEWPORT (widget->viewport), pos + widget->allocation.y);}/* * ... * The function has been copied from gdktrectangle.c */gint p_Dw_rectangle_intersect (DwRectangle *src1, DwRectangle *src2, DwRectangle *dest){ DwRectangle *temp; gint src1_x2, src1_y2; gint src2_x2, src2_y2; gint return_val; g_return_val_if_fail (src1 != NULL, FALSE); g_return_val_if_fail (src2 != NULL, FALSE); g_return_val_if_fail (dest != NULL, FALSE); return_val = FALSE; if (src2->x < src1->x) { temp = src1; src1 = src2; src2 = temp; }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -