/*! \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); }
/*! \todo Finish function documentation!!! * \brief * \par Function Description * */ void o_place_end (GSCHEM_TOPLEVEL *w_current, int w_x, int w_y, int continue_placing, GList **ret_new_objects, const char* hook_name) { TOPLEVEL *toplevel = w_current->toplevel; int w_diff_x, w_diff_y; OBJECT *o_current; PAGE *p_current; GList *temp_dest_list = NULL; GList *connected_objects = NULL; GList *iter; /* erase old image */ /* o_place_invaidate_rubber (w_current, FALSE); */ w_current->rubber_visible = 0; /* Calc final object positions */ w_current->second_wx = w_x; w_current->second_wy = w_y; w_diff_x = w_current->second_wx - w_current->first_wx; w_diff_y = w_current->second_wy - w_current->first_wy; if (continue_placing) { /* Make a copy of the place list if we want to keep it afterwards */ temp_dest_list = o_glist_copy_all (toplevel, toplevel->page_current->place_list, temp_dest_list); } else { /* Otherwise just take it */ temp_dest_list = toplevel->page_current->place_list; toplevel->page_current->place_list = NULL; } if (ret_new_objects != NULL) { *ret_new_objects = g_list_copy (temp_dest_list); } o_glist_translate_world(toplevel, w_diff_x, w_diff_y, temp_dest_list); /* Attach each item back onto the page's object list. Update object * connectivity and add the new objects to the selection list.*/ p_current = toplevel->page_current; for (iter = temp_dest_list; iter != NULL; iter = g_list_next (iter)) { o_current = iter->data; s_page_append (toplevel, p_current, o_current); /* Update object connectivity */ s_conn_update_object (toplevel, o_current); connected_objects = s_conn_return_others (connected_objects, o_current); } if (hook_name != NULL) { g_run_hook_object_list (hook_name, temp_dest_list); } o_invalidate_glist (w_current, connected_objects); g_list_free (connected_objects); connected_objects = NULL; toplevel->page_current->CHANGED = 1; o_invalidate_glist (w_current, temp_dest_list); /* only redraw new objects */ g_list_free (temp_dest_list); o_undo_savestate (w_current, UNDO_ALL); i_update_menus (w_current); }
/*! \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; }
/*! \brief End placement action * * \par Function Description * This function finishes the current placement action by adding * objects to the current page at the given new world coordinates * and redrawing them on the canvas. It also saves the current * state in the undo list and updates the menus. * * If \a continue_placing is TRUE, a copy of the placement list * is saved to start a new place action. * * \param [in] w_current GschemToplevel which we're drawing for. * \param [in] w_x The current world X coordinate. * \param [in] w_y The current world Y coordinate. * \param [in] hook_name The hook to run after adding the objects. */ void o_place_end (GschemToplevel *w_current, int w_x, int w_y, int continue_placing, const char* hook_name) { int w_diff_x, w_diff_y; OBJECT *o_current; GList *temp_dest_list = NULL; GList *connected_objects = NULL; GList *iter; g_return_if_fail (w_current != NULL); g_assert (w_current->inside_action != 0); GschemPageView *page_view = gschem_toplevel_get_current_page_view (w_current); g_return_if_fail (page_view != NULL); PAGE *page = gschem_page_view_get_page (page_view); g_return_if_fail (page != NULL); /* erase old image */ /* o_place_invalidate_rubber (w_current, FALSE); */ w_current->rubber_visible = 0; /* Calc final object positions */ w_current->second_wx = w_x; w_current->second_wy = w_y; w_diff_x = w_current->second_wx - w_current->first_wx; w_diff_y = w_current->second_wy - w_current->first_wy; if (continue_placing) { /* Make a copy of the place list if we want to keep it afterwards */ temp_dest_list = o_glist_copy_all (page->toplevel, page->place_list, temp_dest_list); } else { /* Otherwise just take it */ temp_dest_list = page->place_list; page->place_list = NULL; } o_glist_translate_world(page->toplevel, w_diff_x, w_diff_y, temp_dest_list); /* Attach each item back onto the page's object list. Update object * connectivity and add the new objects to the selection list.*/ for (iter = temp_dest_list; iter != NULL; iter = g_list_next (iter)) { o_current = iter->data; s_page_append (page->toplevel, page, o_current); /* Update object connectivity */ s_conn_update_object (page, o_current); connected_objects = s_conn_return_others (connected_objects, o_current); } if (hook_name != NULL) { g_run_hook_object_list (w_current, hook_name, temp_dest_list); } o_invalidate_glist (w_current, connected_objects); g_list_free (connected_objects); connected_objects = NULL; gschem_toplevel_page_content_changed (w_current, page); o_invalidate_glist (w_current, temp_dest_list); /* only redraw new objects */ g_list_free (temp_dest_list); o_undo_savestate_old (w_current, UNDO_ALL); i_update_menus (w_current); if (!continue_placing) { i_set_state(w_current, SELECT); i_action_stop (w_current); } }