gschem
|
00001 /* gEDA - GPL Electronic Design Automation 00002 * gschem - gEDA Schematic Capture 00003 * Copyright (C) 1998-2010 Ales Hvezda 00004 * Copyright (C) 1998-2011 gEDA Contributors (see ChangeLog for details) 00005 * 00006 * This program is free software; you can redistribute it and/or modify 00007 * it under the terms of the GNU General Public License as published by 00008 * the Free Software Foundation; either version 2 of the License, or 00009 * (at your option) any later version. 00010 * 00011 * This program is distributed in the hope that it will be useful, 00012 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00013 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00014 * GNU General Public License for more details. 00015 * 00016 * You should have received a copy of the GNU General Public License 00017 * along with this program; if not, write to the Free Software 00018 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 00019 */ 00020 #include <config.h> 00021 #include <stdio.h> 00022 #include <math.h> 00023 00024 #include "gschem.h" 00025 00026 #ifdef HAVE_LIBDMALLOC 00027 #include <dmalloc.h> 00028 #endif 00029 00035 void o_bus_draw(GSCHEM_TOPLEVEL *w_current, OBJECT *o_current) 00036 { 00037 TOPLEVEL *toplevel = w_current->toplevel; 00038 int x1, y1, x2, y2; 00039 int size = 0; 00040 00041 if (o_current == NULL) { 00042 return; 00043 } 00044 00045 if (o_current->line == NULL) { 00046 return; 00047 } 00048 00049 /* reuse line's routine */ 00050 if (!o_line_visible (w_current, o_current->line, &x1, &y1, &x2, &y2)) { 00051 return; 00052 } 00053 00054 if (toplevel->bus_style == THICK) 00055 size = BUS_WIDTH; 00056 00057 gschem_cairo_line (w_current, END_SQUARE, size, x1, y1, x2, y2); 00058 00059 gschem_cairo_set_source_color (w_current, 00060 o_drawing_color (w_current, o_current)); 00061 gschem_cairo_stroke (w_current, TYPE_SOLID, END_SQUARE, size, -1, -1); 00062 00063 if (o_current->selected && w_current->draw_grips) { 00064 o_line_draw_grips (w_current, o_current); 00065 } 00066 } 00067 00068 00074 void o_bus_draw_place (GSCHEM_TOPLEVEL *w_current, int dx, int dy, OBJECT *o_current) 00075 { 00076 int size = 0; 00077 00078 if (o_current->line == NULL) { 00079 return; 00080 } 00081 00082 if (w_current->toplevel->bus_style == THICK) 00083 size = BUS_WIDTH; 00084 00085 gschem_cairo_line (w_current, END_NONE, size, 00086 o_current->line->x[0] + dx, o_current->line->y[0] + dy, 00087 o_current->line->x[1] + dx, o_current->line->y[1] + dy); 00088 00089 gschem_cairo_set_source_color (w_current, 00090 x_color_lookup_dark (o_current->color)); 00091 gschem_cairo_stroke (w_current, TYPE_SOLID, END_NONE, size, -1, -1); 00092 } 00093 00099 void o_bus_draw_stretch (GSCHEM_TOPLEVEL *w_current, 00100 int dx, int dy, int whichone, OBJECT *o_current) 00101 { 00102 int dx1= - 1, dy1 = - 1, dx2 = -1, dy2 = -1; 00103 00104 if (o_current->line == NULL) { 00105 return; 00106 } 00107 00108 if (whichone == 0) { 00109 dx1 = dx; 00110 dy1 = dy; 00111 dx2 = dy2 = 0; 00112 } else if (whichone == 1) { 00113 dx1 = dy1 = 0; 00114 dx2 = dx; 00115 dy2 = dy; 00116 } else { 00117 fprintf(stderr, _("Got an invalid which one in o_bus_draw_stretch\n")); 00118 } 00119 00120 gschem_cairo_line (w_current, END_NONE, 0, 00121 o_current->line->x[0] + dx1, o_current->line->y[0] + dy1, 00122 o_current->line->x[1] + dx2, o_current->line->y[1] + dy2); 00123 00124 gschem_cairo_set_source_color (w_current, 00125 x_color_lookup_dark (o_current->color)); 00126 gschem_cairo_stroke (w_current, TYPE_SOLID, END_NONE, 0, -1, -1); 00127 } 00128 00140 void o_bus_start(GSCHEM_TOPLEVEL *w_current, int w_x, int w_y) 00141 { 00142 w_current->first_wx = w_current->second_wx = w_x; 00143 w_current->first_wy = w_current->second_wy = w_y; 00144 } 00145 00160 int o_bus_end(GSCHEM_TOPLEVEL *w_current, int w_x, int w_y) 00161 { 00162 TOPLEVEL *toplevel = w_current->toplevel; 00163 OBJECT *new_obj; 00164 int color; 00165 GList *prev_conn_objects = NULL; 00166 00167 g_assert( w_current->inside_action != 0 ); 00168 00169 if (toplevel->override_bus_color == -1) { 00170 color = BUS_COLOR; 00171 } else { 00172 color = toplevel->override_bus_color; 00173 } 00174 00175 /* erase the rubberbus */ 00176 /* o_bus_invalidate_rubber (w_current); */ 00177 w_current->rubber_visible = 0; 00178 00179 /* don't allow zero length bus */ 00180 /* this ends the bus drawing behavior we want this? hack */ 00181 if ( (w_current->first_wx == w_current->second_wx) && 00182 (w_current->first_wy == w_current->second_wy) ) { 00183 return FALSE; 00184 } 00185 00186 new_obj = o_bus_new(toplevel, OBJ_BUS, color, 00187 w_current->first_wx, w_current->first_wy, 00188 w_current->second_wx, w_current->second_wy, 0); 00189 s_page_append (toplevel, toplevel->page_current, new_obj); 00190 00191 /* connect the new bus to the other busses */ 00192 prev_conn_objects = s_conn_return_others (prev_conn_objects, new_obj); 00193 o_invalidate_glist (w_current, prev_conn_objects); 00194 g_list_free (prev_conn_objects); 00195 00196 /* Call add-objects-hook */ 00197 g_run_hook_object (w_current, "%add-objects-hook", new_obj); 00198 00199 toplevel->page_current->CHANGED=1; 00200 w_current->first_wx = w_current->second_wx; 00201 w_current->first_wy = w_current->second_wy; 00202 o_undo_savestate(w_current, UNDO_ALL); 00203 return TRUE; 00204 } 00205 00222 void o_bus_motion (GSCHEM_TOPLEVEL *w_current, int w_x, int w_y) 00223 { 00224 int diff_x, diff_y; 00225 00226 g_assert( w_current->inside_action != 0 ); 00227 00228 if (w_current->rubber_visible) 00229 o_bus_invalidate_rubber (w_current); 00230 00231 w_current->second_wx = w_x; 00232 w_current->second_wy = w_y; 00233 00234 /* If you press the control key then you can draw non-ortho bus */ 00235 if (!w_current->CONTROLKEY) { 00236 diff_x = abs(w_current->second_wx - w_current->first_wx); 00237 diff_y = abs(w_current->second_wy - w_current->first_wy); 00238 00239 if (diff_x >= diff_y) { 00240 w_current->second_wy = w_current->first_wy; 00241 } else { 00242 w_current->second_wx = w_current->first_wx; 00243 } 00244 } 00245 00246 o_bus_invalidate_rubber (w_current); 00247 w_current->rubber_visible = 1; 00248 } 00249 00255 void o_bus_invalidate_rubber (GSCHEM_TOPLEVEL *w_current) 00256 { 00257 TOPLEVEL *toplevel = w_current->toplevel; 00258 int x1, y1, x2, y2; 00259 int min_x, min_y, max_x, max_y; 00260 int bloat = 0; 00261 00262 WORLDtoSCREEN (w_current, w_current->first_wx, w_current->first_wy, &x1, &y1); 00263 WORLDtoSCREEN (w_current, w_current->second_wx, w_current->second_wy, &x2, &y2); 00264 00265 if (toplevel->bus_style == THICK ) { 00266 bloat = SCREENabs (w_current, BUS_WIDTH) / 2; 00267 } 00268 00269 min_x = min (x1, x2) - bloat; 00270 max_x = max (x1, x2) + bloat; 00271 min_y = min (y1, y2) - bloat; 00272 max_y = max (y1, y2) + bloat; 00273 00274 o_invalidate_rect (w_current, min_x, min_y, max_x, max_y); 00275 } 00276 00288 void o_bus_draw_rubber (GSCHEM_TOPLEVEL *w_current) 00289 { 00290 int size = 0; 00291 00292 if (w_current->toplevel->bus_style == THICK) 00293 size = BUS_WIDTH; 00294 00295 gschem_cairo_line (w_current, END_NONE, size, 00296 w_current->first_wx, w_current->first_wy, 00297 w_current->second_wx, w_current->second_wy); 00298 00299 gschem_cairo_set_source_color (w_current, 00300 x_color_lookup_dark (SELECT_COLOR)); 00301 gschem_cairo_stroke (w_current, TYPE_SOLID, END_NONE, size, -1, -1); 00302 }