Пример #1
0
// Cancel the placement of floating items and remove them.
void sheet_item_cancel_floating (Sheet *sheet)
{
	GooCanvasGroup *group;
	GList *list;

	g_return_if_fail (sheet != NULL);
	g_return_if_fail (IS_SHEET (sheet));

	group = GOO_CANVAS_GROUP (sheet->priv->floating_group);
	if (group == NULL)
		return;

	if (sheet->state != SHEET_STATE_FLOAT && sheet->state != SHEET_STATE_FLOAT_START)
		return;

	if (g_signal_handler_is_connected (sheet, sheet->priv->float_handler_id))
		g_signal_handler_disconnect (sheet, sheet->priv->float_handler_id);

	// TODO verfiy that the following has no nasty sideffects
	for (list = sheet->priv->floating_objects; list; list = list->next) {
		goo_canvas_item_remove (list->data); // remove from canvas and free
	}
	g_list_free (sheet->priv->floating_objects);
	sheet->priv->floating_objects = NULL;
	goo_canvas_item_remove (GOO_CANVAS_ITEM (group));

	// Create a new empty group to prepare next floating 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));

	// sheet_clear_ghosts (sheet);
	sheet->priv->float_handler_id = 0;
	sheet->state = SHEET_STATE_NONE;
}
Пример #2
0
static int
select_idle_callback (PartItem *item)
{
	GooCanvasItem *canvas_item = NULL;
	int index;
	
	g_return_val_if_fail (item != NULL, FALSE);

	for (index = 0; index < GOO_CANVAS_GROUP (item)->items->len; index++) {	
		canvas_item = GOO_CANVAS_ITEM (GOO_CANVAS_GROUP (item)->items->pdata[index]);
		g_object_set (canvas_item, 
		              "stroke-color", SELECTED_COLOR, 
		              NULL);
	}
	g_object_unref (G_OBJECT (item));
	return FALSE;
}
Пример #3
0
static int
deselect_idle_callback (PartItem *item)
{
	GooCanvasItem *canvas_item = NULL;
	int index;

	for (index = 0; index < GOO_CANVAS_GROUP (item)->items->len; index++) {
		canvas_item = GOO_CANVAS_ITEM (GOO_CANVAS_GROUP (item)->items->pdata[index]);
		
		if (GOO_IS_CANVAS_TEXT (canvas_item)) {
			g_object_set (canvas_item, 
			              "stroke-color", LABEL_COLOR, 
			              NULL);
		}
		else {
			g_object_set (canvas_item, 
			              "stroke-color", NORMAL_COLOR, 
			              NULL);
		}
	}
	g_object_unref (G_OBJECT (item));
	return FALSE;
}
Пример #4
0
PartItem *
part_item_new (Sheet *sheet, Part *part)
{
	Library *library;
	LibraryPart *library_part;
	PartPriv *priv;
	PartItem *item;

	priv = part->priv;

	library = priv->library;
	library_part = library_get_part (library, priv->name);

	// Create the PartItem canvas item
	item = part_item_canvas_new (sheet, part);
	create_canvas_items (GOO_CANVAS_GROUP (item), library_part);
	create_canvas_labels (item, part);
	create_canvas_label_nodes (item, part);
	goo_canvas_item_ensure_updated (GOO_CANVAS_ITEM (item));
	return item;
}
Пример #5
0
static void
create_canvas_labels (PartItem *item, Part *part)
{
	GooCanvasItem *canvas_item;
	GSList *list, *item_list;
	GooCanvasGroup *group;

	g_return_if_fail (item != NULL);
	g_return_if_fail (IS_PART_ITEM (item));
	g_return_if_fail (part != NULL);
	g_return_if_fail (IS_PART (part));

	group = GOO_CANVAS_GROUP (item->priv->label_group);
	item_list = NULL;

	for (list = part_get_labels (part); list; list = list->next) {
		PartLabel *label = list->data;
		char *text;

		text = part_property_expand_macros (part, label->text);

		canvas_item = goo_canvas_text_new (GOO_CANVAS_ITEM (group),
		                text,
		                (double) label->pos.x,
		                (double) label->pos.y,
		                0,
		                GOO_CANVAS_ANCHOR_SOUTH_WEST,
		                "fill_color", LABEL_COLOR,
		                "font", "Sans 8",
		                NULL);

		item_list = g_slist_prepend (item_list, canvas_item);
		g_free (text);
	}
	g_slist_free_full (list, g_object_unref);

	item_list = g_slist_reverse (item_list);
	part_item_set_label_items (item, item_list);
}
Пример #6
0
static void
update_preview (Browser *br)
{
	LibraryPart *library_part;
	gdouble new_x, new_y, x1, y1, x2, y2;
	gdouble text_width;
	gdouble width, height;
	GooCanvasBounds bounds;
	gdouble scale; 
	cairo_matrix_t transf, affine;
	gchar *part_name;
	char *description;
	GtkTreeModel *model;
	GtkTreeIter iter;
	GtkTreeSelection *selection;

	// Get the current selected row
	selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (br->list));
	model = gtk_tree_view_get_model (GTK_TREE_VIEW (br->list));

	if (!GTK_IS_TREE_SELECTION (selection)) return;
	
	if (!gtk_tree_selection_get_selected (selection, NULL, &iter)) {
		return;
	}

	gtk_tree_model_get (model, &iter, 0, &part_name, -1);

	library_part = library_get_part (br->library, part_name);
	
	// If there is already a preview part-item, destroy its group and create a
	// new one.
	if (br->preview != NULL) {
		goo_canvas_item_remove (GOO_CANVAS_ITEM (br->preview));
	}
	
	br->preview = GOO_CANVAS_GROUP (goo_canvas_group_new (
	    goo_canvas_get_root_item (GOO_CANVAS (br->canvas)),
	    NULL));

	goo_canvas_set_bounds (GOO_CANVAS (br->canvas), 0.0, 0.0, 250.0, 110.0);

	g_object_get (br->preview, 
	              "width", &width, 
	              "height", &height, 
	              NULL);
	
	if (!library_part)
		return;

	part_item_create_canvas_items_for_preview (br->preview, library_part);

	// Unconstraint the canvas width & height to adjust for the part description
	g_object_set (br->preview,
	              "width", -1.0,
	              "height", -1.0,
	              NULL);
	
	// Get the coordonates */
	goo_canvas_item_get_bounds (GOO_CANVAS_ITEM (br->preview), &bounds);
	x1 = bounds.x1;
	x2 = bounds.x2;
	y1 = bounds.y1;
	y2 = bounds.y2;

	// Translate in such a way that the canvas centre remains in (0, 0) 
	cairo_matrix_init_translate (&transf, -(x2 + x1) / 2.0f + PREVIEW_WIDTH / 2,
	                             -(y2 + y1) / 2.0f + PREVIEW_HEIGHT / 2);

	// Compute the scale of the widget 
	if ((x2 - x1 != 0) || (y2 - y1 != 0)) {
		if ((x2 - x1) < (y2 - y1))
			scale = 0.60f * PREVIEW_HEIGHT / (y2 - y1);
		else
			scale = 0.60f * PREVIEW_WIDTH / (x2 - x1);
	} 
	else
		scale = 5;

	cairo_matrix_init_scale (&affine, scale, scale);
	cairo_matrix_multiply (&transf, &transf, &affine);

	// Apply the transformation 
	goo_canvas_item_set_transform (GOO_CANVAS_ITEM (br->preview), &transf);
	
	// Compute the motion to centre the Preview widget 
	new_x = 100 + (PREVIEW_WIDTH - x1 - x2) / 2;
	new_y = (PREVIEW_HEIGHT - y1 - y2) / 2 - 10;

	// Apply the transformation 
	if (scale > 5.0) scale = 3.0;
	goo_canvas_item_set_simple_transform (GOO_CANVAS_ITEM (br->preview), 
	                                      new_x,
	                                      new_y,
	                                      scale,
	                                      0.0);
    	
	description = g_strdup (library_part->description);
	wrap_string (description, 20);
	g_object_set (br->description,
	              "text", description, 
	              NULL);
	g_free (description);

	g_object_get (G_OBJECT (br->description),
	              "width", &text_width, 
	              NULL);
	
	goo_canvas_item_set_simple_transform (GOO_CANVAS_ITEM (br->description), 
	                                      50.0, 
	                                      -20.0,
	                                      1.0,
	                                      0.0);
	g_free (part_name);
}
Пример #7
0
// This function defines the drawing sheet on which schematic will be drawn 
GtkWidget *
sheet_new (int width, int height)
{
	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_create (GOO_CANVAS_ITEM (sheet_group),
	                           width,
	                           height);

	// Everything outside the sheet should be gray.
	// top //
	goo_canvas_rect_new (GOO_CANVAS_ITEM (sheet_group), 
	                     0.0, 
	                     0.0, 
	                     (double) width + 20.0, 
	                     20.0, 
	                     "fill_color", "gray", 
	                     "line-width", 0.0, 
	                     NULL);

	goo_canvas_rect_new (GOO_CANVAS_ITEM (sheet_group), 
	                     0.0, 
	                     (double) height, 
	                     (double) width + 20.0, 
	                     (double) 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, 
	                     (double) height + 20.0, 
	                     "fill_color", "gray", 
	                     "line-width", 0.0, 
	                     NULL);

	goo_canvas_rect_new (GOO_CANVAS_ITEM (sheet_group), 
	                     (double) width, 
	                     0.0, 
	                     (double) width + 20.0, 
	                     (double) height + 20.0, 
	                     "fill_color", "gray", 
	                     "line-width", 0.0, 
	                     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 keeps maps coordinate 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;
}
Пример #8
0
/**
 * whenever the model changes, this one gets called to update the view representation
 * @attention this recalculates the matrix every time, this makes sure no errors stack up
 * @attention further reading on matrix manipulations
 * @attention http://www.cairographics.org/matrix_transform/
 * @param data the model item, a bare C struct derived from ItemData
 * @param sheet_item the view item, derived from goo_canvas_group/item
 */
static void
part_changed_callback (ItemData *data, SheetItem *sheet_item)
{
	//TODO add static vars in order to skip the redraw if nothing changed
	//TODO may happen once in a while and the check is really cheap
	GSList *iter;
	GooCanvasAnchorType anchor;
	GooCanvasGroup *group;
	GooCanvasItem *canvas_item;
	PartItem *item;
	PartItemPriv *priv;
	Part *part;
	int index = 0;
	Coords pos;
	double scale_h, scale_v;


	// states
	int rotation;
	IDFlip flip;

	g_return_if_fail (sheet_item != NULL);
	g_return_if_fail (IS_PART_ITEM (sheet_item));

	item = PART_ITEM (sheet_item);
	group = GOO_CANVAS_GROUP (item);
	part = PART (data);

	priv = item->priv;

	// init the states

	flip = part_get_flip (part);
	rotation = part_get_rotation (part);

	DEGSANITY (rotation);

	scale_h = (flip & ID_FLIP_HORIZ) ? -1. : 1.;
	scale_v = (flip & ID_FLIP_VERT) ? -1. : 1.;


	item_data_get_pos (data, &pos);
	// Move the canvas item and invalidate the bbox cache.
	goo_canvas_item_set_simple_transform (GOO_CANVAS_ITEM (sheet_item),
	                                      pos.x,
	                                      pos.y,
	                                      1.0,
	                                      0.0);

	cairo_matrix_t morph, inv;
	cairo_status_t done;

	cairo_matrix_init_rotate (&morph, DEG2RAD (rotation));
	cairo_matrix_scale (&morph, scale_h, scale_v);

	inv = morph;
	done = cairo_matrix_invert (&inv);
	if (done != CAIRO_STATUS_SUCCESS) {
		g_warning ("Failed to invert matrix. This should never happen. Never!");
		return;
	}

	// rotate all items in the canvas group
	for (index = 0; index < group->items->len; index++) {
		canvas_item = GOO_CANVAS_ITEM (group->items->pdata[index]);
		goo_canvas_item_set_transform (GOO_CANVAS_ITEM (canvas_item), &morph);
	}

	// revert the rotation of all labels and change their anchor to not overlap too badly
	// this assures that the text is always horizontal and properly aligned
	anchor = angle_to_anchor (rotation);

	for (iter = priv->label_items; iter; iter = iter->next) {
		g_object_set (iter->data,
		              "anchor", anchor,
		              NULL);

		goo_canvas_item_set_transform (iter->data, &inv);

	}
	// same for label nodes
	for (iter = priv->label_nodes; iter; iter = iter->next) {
		g_object_set (iter->data,
		              "anchor", anchor, 
		              NULL);

		goo_canvas_item_set_transform (iter->data, &inv);
	}


	// Invalidate the bounding box cache.
	priv->cache_valid = FALSE;
}