/*! \brief Recalculate position of the given object. * \par Function Description * This function will take an object and recalculate its * position on the screen. * * \param [in] toplevel The TOPLEVEL object. * \param [in,out] o_current OBJECT to recalculate. * */ void o_recalc_single_object(TOPLEVEL *toplevel, OBJECT *o_current) { if (o_current != NULL) { switch(o_current->type) { case(OBJ_LINE): o_line_recalc(toplevel, o_current); break; case(OBJ_NET): o_net_recalc(toplevel, o_current); break; case(OBJ_BUS): o_bus_recalc(toplevel, o_current); break; case(OBJ_BOX): o_box_recalc(toplevel, o_current); break; case(OBJ_PATH): o_path_recalc(toplevel, o_current); break; case(OBJ_PICTURE): o_picture_recalc(toplevel, o_current); break; case(OBJ_CIRCLE): o_circle_recalc(toplevel, o_current); break; case(OBJ_COMPLEX): case(OBJ_PLACEHOLDER): o_complex_recalc(toplevel, o_current); break; case(OBJ_PIN): o_pin_recalc(toplevel, o_current); break; case(OBJ_ARC): o_arc_recalc(toplevel, o_current); break; case(OBJ_TEXT): o_text_recalc(toplevel, o_current); break; } } }
/*! \brief move a complex object * \par Function Description * This function changes the position of a complex \a object. * * \param [in] toplevel The TOPLEVEL object * \param [in] dx The x-distance to move the object * \param [in] dy The y-distance to move the object * \param [in] object The complex OBJECT to be moved */ void o_complex_translate_world(TOPLEVEL *toplevel, int dx, int dy, OBJECT *object) { g_return_if_fail (object != NULL && (object->type == OBJ_COMPLEX || object->type == OBJ_PLACEHOLDER)); object->complex->x = object->complex->x + dx; object->complex->y = object->complex->y + dy; o_glist_translate_world (toplevel, dx, dy, object->complex->prim_objs); o_complex_recalc (toplevel, object); }
/*! \brief Create a copy of a COMPLEX object * \par Function Description * This function creates a copy of the complex object \a o_current. * * \param [in] toplevel The TOPLEVEL object * \param [in] o_current The object that is copied * \return a new COMPLEX object */ OBJECT *o_complex_copy(TOPLEVEL *toplevel, OBJECT *o_current) { OBJECT *o_new; GList *iter; g_return_val_if_fail(o_current != NULL, NULL); o_new = s_basic_new_object(o_current->type, "complex"); o_new->color = o_current->color; o_new->selectable = o_current->selectable; o_new->complex_basename = g_strdup(o_current->complex_basename); o_new->complex_embedded = o_current->complex_embedded; o_new->complex = g_malloc0(sizeof(COMPLEX)); o_new->complex->x = o_current->complex->x; o_new->complex->y = o_current->complex->y; o_new->complex->angle = o_current->complex->angle; o_new->complex->mirror = o_current->complex->mirror; /* Copy contents and set the parent pointers on the copied objects. */ o_new->complex->prim_objs = o_glist_copy_all (toplevel, o_current->complex->prim_objs, NULL); for (iter = o_new->complex->prim_objs; iter != NULL; iter = g_list_next (iter)) { ((OBJECT*) iter->data)->parent = o_new; } /* Recalculate bounds */ o_complex_recalc(toplevel, o_new); /* Delete or hide attributes eligible for promotion inside the complex */ o_complex_remove_promotable_attribs (toplevel, o_new); s_slot_update_object (toplevel, o_new); /* deal with stuff that has changed */ /* here you need to create a list of attributes which need to be * connected to the new list, probably make an attribute list and * fill it with sid's of the attributes */ return o_new; }
/*! \brief * \par Function Description * */ OBJECT *o_complex_new(TOPLEVEL *toplevel, char type, int color, int x, int y, int angle, int mirror, const CLibSymbol *clib, const gchar *basename, int selectable) { OBJECT *new_node=NULL; OBJECT *new_prim_obj; GList *prim_objs; GList *iter; int loaded_normally = FALSE; gchar *buffer = NULL; new_node = s_basic_new_object(type, "complex"); if (clib != NULL) { new_node->complex_basename = g_strdup (s_clib_symbol_get_name (clib)); } else { new_node->complex_basename = g_strdup (basename); } new_node->complex_embedded = FALSE; new_node->color = color; new_node->selectable = selectable; new_node->complex = (COMPLEX *) g_malloc(sizeof(COMPLEX)); new_node->complex->angle = angle; new_node->complex->mirror = mirror; new_node->complex->x = x; new_node->complex->y = y; prim_objs = NULL; /* get the symbol data */ if (clib != NULL) { buffer = s_clib_symbol_get_data (clib); } if (clib == NULL || buffer == NULL) { char *not_found_text = NULL; int left, right, top, bottom; int x_offset, y_offset; /* filename was NOT found */ loaded_normally = FALSE; /* Put placeholder into object list. Changed by SDB on * 1.19.2005 to fix problem that symbols were silently * deleted by gattrib when RC files were messed up. */ new_node->type = OBJ_PLACEHOLDER; /* Mark the origin of the missing component */ new_prim_obj = o_line_new(toplevel, OBJ_LINE, DETACHED_ATTRIBUTE_COLOR, x - 50, y, x + 50, y); prim_objs = g_list_append (prim_objs, new_prim_obj); new_prim_obj = o_line_new(toplevel, OBJ_LINE, DETACHED_ATTRIBUTE_COLOR, x, y + 50, x, y - 50); prim_objs = g_list_append (prim_objs, new_prim_obj); /* Add some useful text */ not_found_text = g_strdup_printf (_("Component not found:\n %s"), new_node->complex_basename); new_prim_obj = o_text_new(toplevel, OBJ_TEXT, DETACHED_ATTRIBUTE_COLOR, x + NOT_FOUND_TEXT_X, y + NOT_FOUND_TEXT_Y, LOWER_LEFT, 0, not_found_text, 8, VISIBLE, SHOW_NAME_VALUE); prim_objs = g_list_append (prim_objs, new_prim_obj); g_free(not_found_text); /* figure out where to put the hazard triangle */ world_get_text_bounds (toplevel, new_prim_obj, &left, &top, &right, &bottom); x_offset = (right - left) / 4; y_offset = bottom - top + 100; /* 100 is just an additional offset */ /* add hazard triangle */ new_prim_obj = o_line_new(toplevel, OBJ_LINE, DETACHED_ATTRIBUTE_COLOR, x + NOT_FOUND_TEXT_X + x_offset, y + NOT_FOUND_TEXT_Y + y_offset, x + NOT_FOUND_TEXT_X + x_offset + 600, y + NOT_FOUND_TEXT_Y + y_offset); o_set_line_options(toplevel, new_prim_obj, END_ROUND, TYPE_SOLID, 50, -1, -1); prim_objs = g_list_append (prim_objs, new_prim_obj); new_prim_obj = o_line_new(toplevel, OBJ_LINE, DETACHED_ATTRIBUTE_COLOR, x + NOT_FOUND_TEXT_X + x_offset, y + NOT_FOUND_TEXT_Y + y_offset, x + NOT_FOUND_TEXT_X + x_offset + 300, y + NOT_FOUND_TEXT_Y + y_offset + 500); o_set_line_options(toplevel, new_prim_obj, END_ROUND, TYPE_SOLID, 50, -1, -1); prim_objs = g_list_append (prim_objs, new_prim_obj); new_prim_obj = o_line_new(toplevel, OBJ_LINE, DETACHED_ATTRIBUTE_COLOR, x + NOT_FOUND_TEXT_X + x_offset + 300, y + NOT_FOUND_TEXT_Y + y_offset + 500, x + NOT_FOUND_TEXT_X + x_offset + 600, y + NOT_FOUND_TEXT_Y + y_offset); o_set_line_options(toplevel, new_prim_obj, END_ROUND, TYPE_SOLID, 50, -1, -1); prim_objs = g_list_append (prim_objs, new_prim_obj); new_prim_obj = o_text_new(toplevel, OBJ_TEXT, DETACHED_ATTRIBUTE_COLOR, x + NOT_FOUND_TEXT_X + x_offset + 270, y + NOT_FOUND_TEXT_Y + y_offset + 90, LOWER_LEFT, 0, "!", 18, VISIBLE, SHOW_NAME_VALUE); prim_objs = g_list_append (prim_objs, new_prim_obj); } else { /* filename was found */ loaded_normally = TRUE; /* add connections till translated */ prim_objs = o_read_buffer (toplevel, prim_objs, buffer, -1, new_node->complex_basename); g_free (buffer); } /* do not mirror/rotate/translate/connect the primitive objects if the * component was not loaded via o_read */ if (loaded_normally == TRUE) { if (mirror) { o_glist_mirror_world (toplevel, 0, 0, prim_objs); } o_glist_rotate_world (toplevel, 0, 0, angle, prim_objs); o_glist_translate_world (toplevel, x, y, prim_objs); } new_node->complex->prim_objs = prim_objs; /* set the parent field now */ for (iter = prim_objs; iter != NULL; iter = g_list_next (iter)) { OBJECT *tmp = iter->data; tmp->parent = new_node; } o_complex_recalc(toplevel, new_node); return new_node; }