📄 dw_widget.c
字号:
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;}/* * Override the "desired" size of a widget. Further calls of * a_Dw_widget_request_size will return these values, except those specified * as -1. */void a_Dw_widget_set_usize(DwWidget * widget, gint32 width, gint32 ascent, gint32 descent){ widget->user_requisition.width = width; widget->user_requisition.ascent = ascent; widget->user_requisition.descent = descent; Dw_widget_queue_resize(widget);}/* * 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;}/* * Set the background color of a widget. *//* * Currently this work only for the top-level widget, by setting the * window background color of the viewport, the code was copied from the * old Dw. */void a_Dw_widget_set_bg_color(DwWidget * widget, gint32 color){ const gint COLOR_MASK = 0xff; const gint COLOR_ELEMENT_WIDTH = 8; GdkColormap *colormap; GdkColor gdk_color; if (widget->parent != NULL) { g_warning("background colors for non-top-level widgets not " "supported yet"); return; } gdk_color.pixel = color; /* Split gint into rgb components */ gdk_color.red = (gdk_color.pixel >> 2 * COLOR_ELEMENT_WIDTH) & COLOR_MASK; gdk_color.green = (gdk_color.pixel >> COLOR_ELEMENT_WIDTH) & COLOR_MASK; gdk_color.blue = gdk_color.pixel & COLOR_MASK; /* Now approximately scale the components from 8 bit values to 16 bit values */ gdk_color.red |= gdk_color.red << 8; gdk_color.green |= gdk_color.green << 8; gdk_color.blue |= gdk_color.blue << 8;#ifdef VERBOSE g_print("color:\tred %d\tgreen %d\tblue %d\n", gdk_color.red, gdk_color.green, gdk_color.blue);#endif if (widget->window) { /* Get drawingarea colormap */ colormap = gdk_window_get_colormap(widget->window); /* Allocate color */ gdk_color_alloc(colormap, &gdk_color); gdk_window_set_background(widget->window, &gdk_color); /*gdk_window_clear(widget->window); */ }}/* * 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 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; } 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 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 (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 Dw_widget_set_parent(DwWidget * widget, DwWidget * parent){ widget->parent = parent; widget->viewport = parent->viewport; widget->window = parent->window; if (DW_WIDGET_REALIZED(parent)) { a_Dw_widget_realize(widget); Dw_widget_queue_resize(parent); }}/* * Converting between coordinates. */gint32 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 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 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 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;}/* * This function is used by the Dw_widget_queue_... functions below. */static void Dw_widget_queue_func_area(DwWidget * widget, gint32 x, gint32 y, gint32 width, gint32 height, void (*func) (GtkWidget *, gint, gint, gint, gint)){ /* * In this function, the intersection of the passed area and the * viewport area is calculated, to prevent errors caused by * converting 32 to 16 bit values. */ GtkLayout *layout; DwRectangle widget_area, viewport_area, intersection; g_return_if_fail(widget && widget->viewport); 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 (Dw_rectangle_intersect(&widget_area, &viewport_area, &intersection)) func(widget->viewport, intersection.x - layout->xoffset, intersection.y - layout->yoffset, intersection.width, intersection.height);}/* * ... */void Dw_widget_queue_draw(DwWidget * widget){ Dw_widget_queue_draw_area(widget, 0, 0, widget->allocation.width, widget->allocation.ascent + widget->allocation.descent);}/* * ... */void Dw_widget_queue_draw_area(DwWidget * widget, gint32 x, gint32 y, gint32 width, gint32 height){ Dw_widget_queue_func_area(widget, x, y, width, height, gtk_widget_queue_draw_area);}/* * ... */void Dw_widget_queue_clear(DwWidget * widget){ Dw_widget_queue_clear_area(widget, 0, 0, widget->allocation.width, widget->allocation.ascent + widget->allocation.descent);}/* * ... */void Dw_widget_queue_clear_area(DwWidget * widget, gint32 x, gint32 y, gint32 width, gint32 height){ Dw_widget_queue_func_area(widget, x, y, width, height, gtk_widget_queue_clear_area);}/* * 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 Dw_widget_queue_resize(DwWidget * widget){ DwWidget *widget2, *toplevel; GtkDwViewport *viewport; gboolean must_queue; toplevel = a_Dw_widget_get_toplevel(widget); must_queue = !DW_WIDGET_NEEDS_RESIZE(toplevel); DW_WIDGET_SET_FLAGS(widget, DW_NEEDS_RESIZE); for (widget2 = widget->parent; widget2; widget2 = widget2->parent) { DW_WIDGET_SET_FLAGS(widget2, DW_NEEDS_RESIZE); DW_WIDGET_SET_FLAGS(widget2, DW_NEEDS_ALLOCATE); } if (must_queue) { 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 Dw_widget_set_anchor(DwWidget * widget, gchar * name, int pos){ gint *val = g_new(gint, 1); if (widget->anchors_table == NULL) widget->anchors_table = g_hash_table_new(g_str_hash, g_str_equal); *val = pos; g_hash_table_insert(widget->anchors_table, name, (gpointer) val); Dw_gtk_viewport_update_anchor(GTK_DW_VIEWPORT(widget->viewport));}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -