Updated copyright text/header in most source files.
[geda-gaf/peter-b.git] / gschem / src / o_bus.c
blob7ef8141eb45fc589d652115174b41c69ed0222d2
1 /* gEDA - GPL Electronic Design Automation
2 * gschem - gEDA Schematic Capture
3 * Copyright (C) 1998-2010 Ales Hvezda
4 * Copyright (C) 1998-2010 gEDA Contributors (see ChangeLog for details)
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111 USA
20 #include <config.h>
21 #include <stdio.h>
22 #include <math.h>
24 #include "gschem.h"
26 #ifdef HAVE_LIBDMALLOC
27 #include <dmalloc.h>
28 #endif
30 /*! \todo Finish function documentation!!!
31 * \brief
32 * \par Function Description
35 void o_bus_draw(GSCHEM_TOPLEVEL *w_current, OBJECT *o_current)
37 TOPLEVEL *toplevel = w_current->toplevel;
38 int x1, y1, x2, y2;
39 int size = 0;
41 if (o_current == NULL) {
42 return;
45 if (o_current->line == NULL) {
46 return;
49 /* reuse line's routine */
50 if ( (toplevel->DONT_REDRAW == 1) ||
51 (!o_line_visible (w_current, o_current->line, &x1, &y1, &x2, &y2)) ) {
52 return;
55 if (toplevel->bus_style == THICK)
56 size = BUS_WIDTH;
58 gschem_cairo_line (w_current, END_SQUARE, size, x1, y1, x2, y2);
60 gschem_cairo_set_source_color (w_current,
61 o_drawing_color (w_current, o_current));
62 gschem_cairo_stroke (w_current, TYPE_SOLID, END_SQUARE, size, -1, -1);
64 if (o_current->selected && w_current->draw_grips) {
65 o_line_draw_grips (w_current, o_current);
70 /*! \todo Finish function documentation!!!
71 * \brief
72 * \par Function Description
75 void o_bus_draw_place (GSCHEM_TOPLEVEL *w_current, int dx, int dy, OBJECT *o_current)
77 int size = 0;
79 if (o_current->line == NULL) {
80 return;
83 if (w_current->toplevel->bus_style == THICK)
84 size = BUS_WIDTH;
86 gschem_cairo_line (w_current, END_NONE, size,
87 o_current->line->x[0] + dx, o_current->line->y[0] + dy,
88 o_current->line->x[1] + dx, o_current->line->y[1] + dy);
90 gschem_cairo_set_source_color (w_current,
91 x_color_lookup_dark (o_current->color));
92 gschem_cairo_stroke (w_current, TYPE_SOLID, END_NONE, size, -1, -1);
95 /*! \todo Finish function documentation!!!
96 * \brief
97 * \par Function Description
100 void o_bus_draw_stretch (GSCHEM_TOPLEVEL *w_current,
101 int dx, int dy, int whichone, OBJECT *o_current)
103 int dx1= - 1, dy1 = - 1, dx2 = -1, dy2 = -1;
105 if (o_current->line == NULL) {
106 return;
109 if (whichone == 0) {
110 dx1 = dx;
111 dy1 = dy;
112 dx2 = dy2 = 0;
113 } else if (whichone == 1) {
114 dx1 = dy1 = 0;
115 dx2 = dx;
116 dy2 = dy;
117 } else {
118 fprintf(stderr, _("Got an invalid which one in o_bus_draw_stretch\n"));
121 gschem_cairo_line (w_current, END_NONE, 0,
122 o_current->line->x[0] + dx1, o_current->line->y[0] + dy1,
123 o_current->line->x[1] + dx2, o_current->line->y[1] + dy2);
125 gschem_cairo_set_source_color (w_current,
126 x_color_lookup_dark (o_current->color));
127 gschem_cairo_stroke (w_current, TYPE_SOLID, END_NONE, 0, -1, -1);
130 /*! \brief set the start point of a new bus
131 * \par Function Description
132 * This function sets the start point (<B>w_x</B>,<B>w_y</B>) of a new bus
133 * in the <B>GSCHEM_TOPLEVEL</B> structure.
135 * The start point is stored in <B>first_wx</B>, <B>first_wy</B>.
137 * \param [in] w_current The GSCHEM_TOPLEVEL object.
138 * \param [in] w_x the x position in world coords
139 * \param [in] w_y the y position in world coords
141 void o_bus_start(GSCHEM_TOPLEVEL *w_current, int w_x, int w_y)
143 w_current->first_wx = w_current->second_wx = w_x;
144 w_current->first_wy = w_current->second_wy = w_y;
147 /*! \brief finish a bus drawing action
148 * \par Function Description
149 * This function finishes a net drawing action. The function draws
150 * a bus from the point (<B>first_wx</B>,<B>first_wy</B>) to
151 * (<B>second_wx</B>,<B>second_wy</B>). Both points are taken from
152 * the <B>GSCHEM_TOPLEVEL</B> structure.
154 * The function returns TRUE if a bus object has been created and
155 * FALSE if no bus object has been created.
157 * \param [in] w_current The GSCHEM_TOPLEVEL object.
158 * \param [in] w_x (unused)
159 * \param [in] w_y (unused)
161 int o_bus_end(GSCHEM_TOPLEVEL *w_current, int w_x, int w_y)
163 TOPLEVEL *toplevel = w_current->toplevel;
164 OBJECT *new_obj;
165 int color;
166 GList *prev_conn_objects = NULL;
168 g_assert( w_current->inside_action != 0 );
170 if (toplevel->override_bus_color == -1) {
171 color = BUS_COLOR;
172 } else {
173 color = toplevel->override_bus_color;
176 /* erase the rubberbus */
177 /* o_bus_invalidate_rubber (w_current); */
178 w_current->rubber_visible = 0;
180 /* don't allow zero length bus */
181 /* this ends the bus drawing behavior we want this? hack */
182 if ( (w_current->first_wx == w_current->second_wx) &&
183 (w_current->first_wy == w_current->second_wy) ) {
184 return FALSE;
187 new_obj = o_bus_new(toplevel, OBJ_BUS, color,
188 w_current->first_wx, w_current->first_wy,
189 w_current->second_wx, w_current->second_wy, 0);
190 s_page_append (toplevel, toplevel->page_current, new_obj);
192 o_invalidate (w_current, new_obj);
194 /* connect the new bus to the other busses */
195 prev_conn_objects = s_conn_return_others (prev_conn_objects, new_obj);
196 o_invalidate_glist (w_current, prev_conn_objects);
197 g_list_free (prev_conn_objects);
199 toplevel->page_current->CHANGED=1;
200 w_current->first_wx = w_current->second_wx;
201 w_current->first_wy = w_current->second_wy;
202 o_undo_savestate(w_current, UNDO_ALL);
203 return TRUE;
206 /*! \brief draw the bus rubber when creating a bus
207 * \par Function Description
208 * This function draws
209 * a bus rubber from the point (<B>first_wx</B>,<B>first_wy</B>) from
210 * the <B>GSCHEM_TOPLEVEL</B> structure to the input parameter
211 * (<B>w_x</B>, <B>w_y</B>).
213 * The function stores creates an non-orthogonal bus segment if the
214 * CONTROLKEY is pressed. The coordinates of the second rubberbus point
215 * is stored as (<B>second_wx</B>,<B>second_wy</B>) in the
216 * <B>GSCHEM_TOPLEVEL</B> structure.
218 * \param [in] w_current The GSCHEM_TOPLEVEL object.
219 * \param [in] w_x current x position in world units
220 * \param [in] w_y current y position in world units
222 void o_bus_motion (GSCHEM_TOPLEVEL *w_current, int w_x, int w_y)
224 int diff_x, diff_y;
226 g_assert( w_current->inside_action != 0 );
228 if (w_current->rubber_visible)
229 o_bus_invalidate_rubber (w_current);
231 w_current->second_wx = w_x;
232 w_current->second_wy = w_y;
234 /* If you press the control key then you can draw non-ortho bus */
235 if (!w_current->CONTROLKEY) {
236 diff_x = abs(w_current->second_wx - w_current->first_wx);
237 diff_y = abs(w_current->second_wy - w_current->first_wy);
239 if (diff_x >= diff_y) {
240 w_current->second_wy = w_current->first_wy;
241 } else {
242 w_current->second_wx = w_current->first_wx;
246 o_bus_invalidate_rubber (w_current);
247 w_current->rubber_visible = 1;
250 /*! \todo Finish function documentation!!!
251 * \brief
252 * \par Function Description
255 void o_bus_invalidate_rubber (GSCHEM_TOPLEVEL *w_current)
257 TOPLEVEL *toplevel = w_current->toplevel;
258 int x1, y1, x2, y2;
259 int min_x, min_y, max_x, max_y;
260 int bloat = 0;
262 WORLDtoSCREEN (w_current, w_current->first_wx, w_current->first_wy, &x1, &y1);
263 WORLDtoSCREEN (w_current, w_current->second_wx, w_current->second_wy, &x2, &y2);
265 if (toplevel->bus_style == THICK ) {
266 bloat = SCREENabs (w_current, BUS_WIDTH) / 2;
269 min_x = min (x1, x2) - bloat;
270 max_x = max (x1, x2) + bloat;
271 min_y = min (y1, y2) - bloat;
272 max_y = max (y1, y2) + bloat;
274 o_invalidate_rect (w_current, min_x, min_y, max_x, max_y);
277 /*! \brief draw a rubberbus segment
278 * \par Function Description
279 * This function draws a bus segment from the point
280 * (<B>first_wx</B>,<B>first_wy</B>) to the point
281 * (<B>second_wx</B>,<B>second_wy</B>) from the <B>GSCHEM_TOPLEVEL</B>
282 * structure.
284 * The function can be used to draw or erase the rubberbus on the screen.
286 * \param [in] w_current The GSCHEM_TOPLEVEL object
288 void o_bus_draw_rubber (GSCHEM_TOPLEVEL *w_current)
290 int size = 0;
292 if (w_current->toplevel->bus_style == THICK)
293 size = BUS_WIDTH;
295 gschem_cairo_line (w_current, END_NONE, size,
296 w_current->first_wx, w_current->first_wy,
297 w_current->second_wx, w_current->second_wy);
299 gschem_cairo_set_source_color (w_current,
300 x_color_lookup_dark (SELECT_COLOR));
301 gschem_cairo_stroke (w_current, TYPE_SOLID, END_NONE, size, -1, -1);