static void show_line(PcbItem *item, int layer) { item->canvas_item[layer] = goo_canvas_polyline_new_line(pcb.layer[layer].olay, item->l.point[0]->p.x, item->l.point[0]->p.y, item->l.point[1]->p.x, item->l.point[1]->p.y, "stroke-color", item->flags & PCB_SELECTED ? "green" : "black", NULL); }
/* * Compute the anchor shapes to link field1 to field2 from ent1 to ent2 * * if @shapes is not NULL, then the shapes in the list are reused, and the ones which don't need * to exist anymore are removed * * Returns a list of BrowserCanvasCanvasShapes structures */ GSList * browser_canvas_util_compute_connect_shapes (GooCanvasItem *parent, GSList *shapes, BrowserCanvasTable *ent1, GdaMetaTableColumn *field1, BrowserCanvasTable *ent2, GdaMetaTableColumn *field2, guint nb_connect, guint ext) { GSList *retval = shapes; GooCanvasItem *item; GooCanvasPoints *points; gdouble xl1, xr1, xl2, xr2, yt1, yt2; /* X boundings and Y top of ent1 and ent2 */ gdouble x1, x2; /* X positions of the lines extremities close to ent1 and ent2 */ gdouble x1offset, x2offset; /* offsets for the horizontal part of the lines */ double sq = 5.; double eps = 0.5; GooCanvasBounds bounds; BrowserCanvasCanvasShape *shape; gchar *id; if (!field1 || !field2) return browser_canvas_util_compute_anchor_shapes (parent, shapes, ent1, ent2, 1, ext, FALSE); /* line made of 4 points */ points = goo_canvas_points_new (4); browser_canvas_table_get_anchor_bounds (ent1, &bounds); xl1 = bounds.x1; yt1 = bounds.y1; xr1 = bounds.x2; browser_canvas_table_get_anchor_bounds (ent2, &bounds); xl2 = bounds.x1; yt2 = bounds.y1; xr2 = bounds.x2; if (xl2 > xr1) { x1 = xr1 + eps; x2 = xl2 - eps; x1offset = 2 * sq; x2offset = -2 * sq; } else { if (xl1 >= xr2) { x1 = xl1 - eps; x2 = xr2 + eps; x1offset = - 2 * sq; x2offset = 2 * sq; } else { if ((xl1 + xr1) < (xl2 + xr2)) { x1 = xl1 - eps; x2 = xl2 - eps; x1offset = -2 * sq; x2offset = -2 * sq; } else { x1 = xr1 + eps; x2 = xr2 + eps; x1offset = 2 * sq; x2offset = 2 * sq; } } } points->coords[0] = x1; points->coords[1] = browser_canvas_table_get_column_ypos (ent1, field1) + yt1; points->coords[2] = x1 + x1offset; points->coords[3] = points->coords[1]; points->coords[4] = x2 + x2offset; points->coords[5] = browser_canvas_table_get_column_ypos (ent2, field2) + yt2; points->coords[6] = x2; points->coords[7] = points->coords[5]; id = g_strdup_printf ("c%d", nb_connect); shape = browser_canvas_canvas_shape_find (retval, id); if (shape) { g_object_set (shape->item, "points", points, NULL); shape->_used = TRUE; g_free (id); } else { item = goo_canvas_polyline_new_line (parent, points->coords[0], points->coords [1], points->coords[2], points->coords [3], "close-path", FALSE, "points", points, NULL); retval = browser_canvas_canvas_shape_add_to_list (retval, id, item); } /* extension marks as text */ if (ext & CANVAS_SHAPE_EXT_JOIN_OUTER_1) { gdouble mxoff = 0., myoff = 0.; GooCanvasAnchorType atype; compute_text_marks_offsets (points->coords[4], points->coords[5], points->coords[2], points->coords[3], &mxoff, &myoff, &atype); id = g_strdup_printf ("ce%d1", nb_connect); shape = browser_canvas_canvas_shape_find (retval, id); if (shape) { g_object_set (shape->item, "x", points->coords[2] + mxoff, "y", points->coords[3] + myoff, "anchor", atype, NULL); shape->_used = TRUE; g_free (id); } else { item = goo_canvas_text_new (parent, "*", points->coords[2] + mxoff, points->coords[3] + myoff, -1, atype, NULL); retval = browser_canvas_canvas_shape_add_to_list (retval, id, item); } } if (ext & CANVAS_SHAPE_EXT_JOIN_OUTER_2) { gdouble mxoff, myoff; GooCanvasAnchorType atype; compute_text_marks_offsets (points->coords[2], points->coords[3], points->coords[4], points->coords[5], &mxoff, &myoff, &atype); id = g_strdup_printf ("ce%d2", nb_connect); shape = browser_canvas_canvas_shape_find (retval, id); if (shape) { g_object_set (shape->item, "x", points->coords[2] + mxoff, "y", points->coords[3] + myoff, "anchor", atype, NULL); shape->_used = TRUE; g_free (id); } else { item = goo_canvas_text_new (parent, "*", points->coords[2] + mxoff, points->coords[3] + myoff, -1, atype, NULL); retval = browser_canvas_canvas_shape_add_to_list (retval, id, item); } } goo_canvas_points_unref (points); return retval; }
/* * Computes the points' coordinates of the line going from * @ref_pk_ent to @fk_ent (which are themselves rectangles) * * if @shapes is not NULL, then the shapes in the list are reused, and the ones which don't need * to exist anymore are removed * * Returns a list of BrowserCanvasCanvasShapes structures */ GSList * browser_canvas_util_compute_anchor_shapes (GooCanvasItem *parent, GSList *shapes, BrowserCanvasTable *fk_ent, BrowserCanvasTable *ref_pk_ent, guint nb_anchors, guint ext, gboolean with_handle) { GSList *retval = shapes; guint i; gdouble fx1, fy1, fx2, fy2; /* FK entity item (bounds) */ gdouble rx1, ry1, rx2, ry2; /* REF PK entity item (bounds) */ BrowserCanvasCanvasShape *shape; gchar *id; gdouble rcx, rcy; /* center of ref_pk entity item */ gdouble cx, cy; gdouble rux, ruy; /* current ref_pk point for the arrow line */ gdouble dx, dy; /* increments to compute the new ref_pk point for the arrow line */ GooCanvasBounds bounds; g_return_val_if_fail (nb_anchors > 0, NULL); browser_canvas_table_get_anchor_bounds (fk_ent, &bounds); fx1 = bounds.x1; fy1 = bounds.y1; fx2 = bounds.x2; fy2 = bounds.y2; browser_canvas_table_get_anchor_bounds (ref_pk_ent, &bounds); rx1 = bounds.x1; ry1 = bounds.y1; rx2 = bounds.x2; ry2 = bounds.y2; /* compute the cx, cy, dx and dy values */ rcx = (rx1 + rx2) / 2.; rcy = (ry1 + ry2) / 2.; cx = (fx1 + fx2) / 2.; cy = (fy1 + fy2) / 2.; rux = rcx; ruy = rcy; dx = 0; dy = 0; for (i = 0; i < nb_anchors; i++) { /* TODO: - detect tables overlapping */ if ((rcx == cx) && (rcy == cy)) { /* tables have the same center (includes case when they are equal) */ gdouble Dy, Dx; GooCanvasPoints *ap, *points; GooCanvasItem *item; points = goo_canvas_points_new (4); ap = goo_canvas_points_new (4); Dy = (ry2 - ry1) / 2. / (gdouble ) (nb_anchors + 1) * (gdouble) (i + 1); Dx = (rx2 - rx1) * (0.8 + 0.1 * i); if (! compute_intersect_rect_line (rx1, ry1, rx2, ry2, cx, cy, cx + Dx, cy - Dy, &(ap->coords[0]), &(ap->coords[1]), &(ap->coords[2]), &(ap->coords[3]))) return retval; if (ap->coords[0] > ap->coords[2]) { points->coords[0] = ap->coords[0]; points->coords[1] = ap->coords[1]; } else { points->coords[0] = ap->coords[2]; points->coords[1] = ap->coords[3]; } points->coords[2] = cx + Dx; points->coords[3] = cy - Dy; Dy = (fy2 - fy1) / 2. / (gdouble ) (nb_anchors + 1) * (gdouble) (i + 1); Dx = (fx2 - fx1) * (0.8 + 0.1 * i); points->coords[4] = cx + Dx; points->coords[5] = cy + Dy; if (! compute_intersect_rect_line (fx1, fy1, fx2, fy2, cx, cy, cx + Dx, cy + Dy, &(ap->coords[0]), &(ap->coords[1]), &(ap->coords[2]), &(ap->coords[3]))) return retval; if (ap->coords[0] > ap->coords[2]) { points->coords[6] = ap->coords[0]; points->coords[7] = ap->coords[1]; } else { points->coords[6] = ap->coords[2]; points->coords[7] = ap->coords[3]; } id = g_strdup_printf ("a%d", i); shape = browser_canvas_canvas_shape_find (retval, id); if (shape) { g_object_set (shape->item, "points", points, NULL); shape->_used = TRUE; g_free (id); } else { item = goo_canvas_polyline_new_line (parent, points->coords[0], points->coords [1], points->coords[2], points->coords [3], "close-path", FALSE, "points", points, NULL); retval = browser_canvas_canvas_shape_add_to_list (retval, id, item); } goo_canvas_points_unref (ap); /* extension marks as text */ if (ext & CANVAS_SHAPE_EXT_JOIN_OUTER_1) { id = g_strdup_printf ("a%de1", i); shape = browser_canvas_canvas_shape_find (retval, id); if (shape) { g_object_set (shape->item, "x", points->coords[2] + 5., "y", points->coords[3] - 5., NULL); shape->_used = TRUE; g_free (id); } else { item = goo_canvas_text_new (parent, "*", points->coords[2] + 5., points->coords[3] - 5., -1, GOO_CANVAS_ANCHOR_SOUTH, NULL); retval = browser_canvas_canvas_shape_add_to_list (retval, id, item); } } if (ext & CANVAS_SHAPE_EXT_JOIN_OUTER_2) { id = g_strdup_printf ("a%de2", i); if (shape) { g_object_set (shape->item, "x", points->coords[4] + 5., "y", points->coords[5] + 5., NULL); shape->_used = TRUE; g_free (id); } else { item = goo_canvas_text_new (parent, "*", points->coords[4] + 5., points->coords[5] + 5., -1, GOO_CANVAS_ANCHOR_NORTH, NULL); retval = browser_canvas_canvas_shape_add_to_list (retval, id, item); } } goo_canvas_points_unref (points); } else { GooCanvasPoints *ap, *points; GooCanvasItem *item; points = goo_canvas_points_new (2); ap = goo_canvas_points_new (4); if (nb_anchors > 1) { if ((dx == 0) && (dy == 0)) { /* compute perpendicular to D={(rcx, rcy), (cx, cy)} */ gdouble vx = (rcx - cx), vy = (rcy - cy); gdouble tmp; tmp = vx; vx = vy; vy = - tmp; /* compute intersect of ref_pkey rectangle and D=[vx, vy] passing at (rcx, rcy) */ if (! compute_intersect_rect_line (rx1, ry1, rx2, ry2, rcx, rcy, rcx + vx, rcy + vy, &(ap->coords[0]), &(ap->coords[1]), &(ap->coords[2]), &(ap->coords[3]))) return retval; dx = (ap->coords[2] - ap->coords[0]) / (gdouble) (nb_anchors + 1); dy = (ap->coords[3] - ap->coords[1]) / (gdouble) (nb_anchors + 1); rux = ap->coords[0]; ruy = ap->coords[1]; } rux += dx; ruy += dy; } /* compute the 4 intersection points */ if (! compute_intersect_rect_line (rx1, ry1, rx2, ry2, rux, ruy, cx, cy, &(ap->coords[0]), &(ap->coords[1]), &(ap->coords[2]), &(ap->coords[3]))) return retval; if (! compute_intersect_rect_line (fx1, fy1, fx2, fy2, rux, ruy, cx, cy, &(ap->coords[4]), &(ap->coords[5]), &(ap->coords[6]), &(ap->coords[7]))) return retval; /* choosing between point coords(0,1) and coords(2,3) */ if (((ap->coords[0] - ap->coords[4]) * (ap->coords[0] - ap->coords[4]) + (ap->coords[1] - ap->coords[5]) * (ap->coords[1] - ap->coords[5])) < ((ap->coords[2] - ap->coords[4]) * (ap->coords[2] - ap->coords[4]) + (ap->coords[3] - ap->coords[5]) * (ap->coords[3] - ap->coords[5]))) { points->coords[0] = ap->coords[0]; points->coords[1] = ap->coords[1]; } else { points->coords[0] = ap->coords[2]; points->coords[1] = ap->coords[3]; } /* choosing between point coords(4,5) and coords(6,7) */ if (((points->coords[0] - ap->coords[4]) * (points->coords[0] - ap->coords[4]) + (points->coords[1] - ap->coords[5]) * (points->coords[1] - ap->coords[5])) < ((points->coords[0] - ap->coords[6]) * (points->coords[0] - ap->coords[6]) + (points->coords[1] - ap->coords[7]) * (points->coords[1] - ap->coords[7]))) { points->coords[2] = ap->coords[4]; points->coords[3] = ap->coords[5]; } else { points->coords[2] = ap->coords[6]; points->coords[3] = ap->coords[7]; } id = g_strdup_printf ("a%d", i); shape = browser_canvas_canvas_shape_find (retval, id); if (shape) { g_object_set (shape->item, "points", points, NULL); shape->_used = TRUE; g_free (id); } else { item = goo_canvas_polyline_new_line (parent, points->coords[0], points->coords [1], points->coords[2], points->coords [3], "close-path", FALSE, "points", points, NULL); retval = browser_canvas_canvas_shape_add_to_list (retval, id, item); } goo_canvas_points_unref (ap); /* extension marks as text */ if (ext & CANVAS_SHAPE_EXT_JOIN_OUTER_1) { gdouble mxoff = 0., myoff = 0.; GooCanvasAnchorType atype; compute_text_marks_offsets (points->coords[0], points->coords[1], points->coords[2], points->coords[3], &mxoff, &myoff, &atype); id = g_strdup_printf ("a%de1", i); shape = browser_canvas_canvas_shape_find (retval, id); if (shape) { g_object_set (shape->item, "x", points->coords[2] + mxoff, "y", points->coords[3] + myoff, "anchor", atype, NULL); shape->_used = TRUE; g_free (id); } else { item = goo_canvas_text_new (parent, "*", points->coords[2] + mxoff, points->coords[3] + myoff, -1, atype, NULL); retval = browser_canvas_canvas_shape_add_to_list (retval, id, item); } } if (ext & CANVAS_SHAPE_EXT_JOIN_OUTER_2) { gdouble mxoff, myoff; GooCanvasAnchorType atype; compute_text_marks_offsets (points->coords[2], points->coords[3], points->coords[0], points->coords[1], &mxoff, &myoff, &atype); id = g_strdup_printf ("a%de2", i); if (shape) { g_object_set (shape->item, "x", points->coords[0] + mxoff, "y", points->coords[1] + myoff, "anchor", atype, NULL); shape->_used = TRUE; g_free (id); } else { item = goo_canvas_text_new (parent, "*", points->coords[0] + mxoff, points->coords[1] + myoff, -1, atype, NULL); retval = browser_canvas_canvas_shape_add_to_list (retval, id, item); } } goo_canvas_points_unref (points); } } return retval; }
/** * \brief defines the drawing widget on which the actual schematic will be drawn * * @param height height of the content area * @param width width of the content area */ GtkWidget * sheet_new (gdouble height, gdouble width) { GooCanvas *sheet_canvas; GooCanvasGroup *sheet_group; GooCanvasPoints *points; Sheet *sheet; GtkWidget *sheet_widget; GooCanvasItem *root; // Creation of the Canvas sheet = SHEET (g_object_new (TYPE_SHEET, NULL)); sheet_canvas = GOO_CANVAS (sheet); g_object_set (G_OBJECT (sheet_canvas), "bounds-from-origin", FALSE, "bounds-padding", 4.0, "background-color-rgb", 0xFFFFFF, NULL); root = goo_canvas_get_root_item (sheet_canvas); sheet_group = GOO_CANVAS_GROUP (goo_canvas_group_new ( root, NULL)); sheet_widget = GTK_WIDGET (sheet); goo_canvas_set_bounds (GOO_CANVAS (sheet_canvas), 0., 0., width + 20., height + 20.); // Define vicinity around GooCanvasItem //sheet_canvas->close_enough = 6.0; sheet->priv->width = width; sheet->priv->height = height; // Create the dot grid. sheet->grid = grid_new (GOO_CANVAS_ITEM (sheet_group), height, width); // Everything outside the sheet should be gray. // top // goo_canvas_rect_new (GOO_CANVAS_ITEM (sheet_group), 0.0, 0.0, width + 20.0, 20.0, "fill_color", "gray", "line-width", 0.0, NULL); goo_canvas_rect_new (GOO_CANVAS_ITEM (sheet_group), 0.0, height, width + 20.0, height + 20.0, "fill_color", "gray", "line-width", 0.0, NULL); // right // goo_canvas_rect_new (GOO_CANVAS_ITEM (sheet_group), 0.0, 0.0, 20.0, height + 20.0, "fill_color", "gray", "line-width", 0.0, NULL); goo_canvas_rect_new (GOO_CANVAS_ITEM (sheet_group), width, 0.0, width + 20.0, height + 20.0, "fill_color", "gray", "line-width", 0.0, NULL); if (oregano_options_debug_directions()) { goo_canvas_polyline_new_line (GOO_CANVAS_ITEM (sheet_group), 10.0, 10.0, 50.0, 10.0, "stroke-color", "green", "line-width", 2.0, "end-arrow", TRUE, NULL); goo_canvas_text_new (GOO_CANVAS_ITEM (sheet_group), "x", 90.0, 10.0, -1.0, GOO_CANVAS_ANCHOR_WEST, "fill-color", "green", NULL); goo_canvas_polyline_new_line (GOO_CANVAS_ITEM (sheet_group), 10.0, 10.0, 10.0, 50.0, "stroke-color", "red", "line-width", 2.0, "end-arrow", TRUE, NULL); goo_canvas_text_new (GOO_CANVAS_ITEM (sheet_group), "y", 10.0, 90.0, -1.0, GOO_CANVAS_ANCHOR_CENTER, "fill-color", "red", NULL); } // Draw a thin black border around the sheet. points = goo_canvas_points_new (5); points->coords[0] = 20.0; points->coords[1] = 20.0; points->coords[2] = width; points->coords[3] = 20.0; points->coords[4] = width; points->coords[5] = height; points->coords[6] = 20.0; points->coords[7] = height; points->coords[8] = 20.0; points->coords[9] = 20.0; goo_canvas_polyline_new (GOO_CANVAS_ITEM (sheet_group), FALSE, 0, "line-width", 1.0, "points", points, NULL); goo_canvas_points_unref (points); // Finally, create the object group that holds all objects. sheet->object_group = GOO_CANVAS_GROUP (goo_canvas_group_new ( root, "x", 0.0, "y", 0.0, NULL)); NG_DEBUG ("root group %p", sheet->object_group); sheet->priv->selected_group = GOO_CANVAS_GROUP (goo_canvas_group_new ( GOO_CANVAS_ITEM (sheet->object_group), "x", 0.0, "y", 0.0, NULL)); NG_DEBUG ("selected group %p", sheet->priv->selected_group); sheet->priv->floating_group = GOO_CANVAS_GROUP (goo_canvas_group_new ( GOO_CANVAS_ITEM (sheet->object_group), "x", 0.0, "y", 0.0, NULL)); NG_DEBUG ("floating group %p", sheet->priv->floating_group); // Hash table that maps coordinates to a specific dot. sheet->priv->node_dots = g_hash_table_new_full (dot_hash, dot_equal, g_free, NULL); //this requires object_group to be setup properly sheet->priv->rubberband_info = rubberband_info_new (sheet); sheet->priv->create_wire_info = create_wire_info_new (sheet); return sheet_widget; }
int main (int argc, char *argv[]) { GtkWidget *window, *scrolled_win, *canvas; GooCanvasItem *root, *rect_item, *text_item, *image_item; GdkPixbuf *pb; /* Initialize GTK+. */ gtk_set_locale (); gtk_init (&argc, &argv); pb=gdk_pixbuf_new_from_file("test-screenshot.png", NULL); if(!pb) { printf("error: gdk_pixbuf_new_from_file"); exit(1); } /* Create the window and widgets. */ window = gtk_window_new (GTK_WINDOW_TOPLEVEL); gtk_window_set_default_size (GTK_WINDOW (window), 740, 700); gtk_widget_show (window); g_signal_connect (window, "delete_event", (GtkSignalFunc) on_delete_event, NULL); scrolled_win = gtk_scrolled_window_new (NULL, NULL); gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (scrolled_win), GTK_SHADOW_IN); gtk_widget_show (scrolled_win); gtk_container_add (GTK_CONTAINER (window), scrolled_win); canvas = goo_canvas_new (); gtk_widget_set_size_request (canvas, 640, 600); goo_canvas_set_bounds (GOO_CANVAS (canvas), 0, 0, 1000, 1000); gtk_widget_show (canvas); gtk_container_add (GTK_CONTAINER (scrolled_win), canvas); root = goo_canvas_get_root_item (GOO_CANVAS (canvas)); image_item = goo_canvas_image_new (root, pb, 0, 0, NULL); /* Add a few simple items. */ rect_item = goo_canvas_rect_new (root, 20, 20, 200, 200, "line-width", 5.0, "radius-x", 10.0, "radius-y", 5.0, "stroke-color", "red", NULL); GooCanvasItem *polyline0 = goo_canvas_polyline_new_line (root, 100.0, 100.0, 500.0, 500.0, "stroke-color", "red", "line-width", 5.0, "start-arrow", TRUE, NULL); //text_item = goo_canvas_text_new (root, PACKAGE_STRING, 300, 300, -1, //GTK_ANCHOR_CENTER, //"font", "Sans 24px", //NULL); //goo_canvas_item_rotate (text_item, 45, 300, 300); /* Connect a signal handler for the rectangle item. */ g_signal_connect (rect_item, "button_press_event", (GtkSignalFunc) on_rect_button_press, NULL); /* Pass control to the GTK+ main event loop. */ gtk_main (); return 0; }