📄 dw_widget.c
字号:
dest->x = src2->x; src1_x2 = src1->x + src1->width; src2_x2 = src2->x + src2->width; if (src2->x < src1_x2) { if (src1_x2 < src2_x2) dest->width = src1_x2 - dest->x; else dest->width = src2_x2 - dest->x; if (src2->y < src1->y) { temp = src1; src1 = src2; src2 = temp; } dest->y = src2->y; src1_y2 = src1->y + src1->height; src2_y2 = src2->y + src2->height; if (src2->y < src1_y2) { return_val = TRUE; if (src1_y2 < src2_y2) dest->height = src1_y2 - dest->y; else dest->height = src2_y2 - dest->y; if (dest->height == 0) return_val = FALSE; if (dest->width == 0) return_val = FALSE; } } return return_val;}/* * 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; child_area.x = widget->allocation.x; child_area.y = widget->allocation.y; child_area.width = widget->allocation.width; child_area.height = widget->allocation.ascent + widget->allocation.descent; 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 = (widget->allocation.ascent + widget->allocation.descent); 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 (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, widget->allocation.ascent + widget->allocation.descent);}/* * ... */void p_Dw_widget_queue_draw_area (DwWidget *widget, gint32 x, gint32 y, gint32 width, gint32 height){ GdkRectangle gdk_area; if (Dw_widget_intersect_viewport (widget, x, y, width, height, &gdk_area)) gtk_widget_queue_draw_area (widget->viewport, gdk_area.x, gdk_area.y, gdk_area.width, gdk_area.height);}/* * ... */void p_Dw_widget_queue_clear (DwWidget *widget){ p_Dw_widget_queue_clear_area ( widget, 0, 0, widget->allocation.width, widget->allocation.ascent + widget->allocation.descent);}/* * ... */void p_Dw_widget_queue_clear_area (DwWidget *widget, gint32 x, gint32 y, gint32 width, gint32 height){ GdkRectangle gdk_area; if (Dw_widget_intersect_viewport (widget, x, y, width, height, &gdk_area)) gtk_widget_queue_clear_area (widget->viewport, gdk_area.x, gdk_area.y, gdk_area.width, gdk_area.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. *//* * Used by Dw_widget_queue_resize. */static int Dw_widget_queue_resize_idle (gpointer data){ GtkDwViewport *viewport = GTK_DW_VIEWPORT (data); Dw_gtk_viewport_calc_size (viewport); viewport->resize_idle_id = -1; return FALSE;}/* * 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; GtkDwViewport *viewport; DwWidgetClass *klass; 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); 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) { viewport = GTK_DW_VIEWPORT (widget->viewport); if (viewport->resize_idle_id == -1) viewport->resize_idle_id = gtk_idle_add (Dw_widget_queue_resize_idle, viewport); }}/* * Add or change an anchor. * The widget is responsible for storing a copy of name. */void p_Dw_widget_set_anchor (DwWidget *widget, gchar *name, int pos){ if (widget->anchors_table == NULL) widget->anchors_table = g_hash_table_new(g_str_hash, g_str_equal); g_hash_table_insert(widget->anchors_table, name, GINT_TO_POINTER(pos)); Dw_gtk_viewport_update_anchor(GTK_DW_VIEWPORT (widget->viewport));}/* * 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){ 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); 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); }}/* * Draw borders and background of a widget. */void p_Dw_widget_draw_widget_box (DwWidget *widget, DwRectangle *area){ 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, widget->allocation.ascent + widget->allocation.descent, widget->style); /* - 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, widget->allocation.ascent + widget->allocation.descent, widget->style); }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -