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
26 #ifdef HAVE_LIBDMALLOC
30 /*! \todo Finish function documentation!!!
32 * \par Function Description
35 void o_bus_draw(GSCHEM_TOPLEVEL
*w_current
, OBJECT
*o_current
)
37 TOPLEVEL
*toplevel
= w_current
->toplevel
;
41 if (o_current
== NULL
) {
45 if (o_current
->line
== NULL
) {
49 /* reuse line's routine */
50 if ( (toplevel
->DONT_REDRAW
== 1) ||
51 (!o_line_visible (w_current
, o_current
->line
, &x1
, &y1
, &x2
, &y2
)) ) {
55 if (toplevel
->bus_style
== THICK
)
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!!!
72 * \par Function Description
75 void o_bus_draw_place (GSCHEM_TOPLEVEL
*w_current
, int dx
, int dy
, OBJECT
*o_current
)
79 if (o_current
->line
== NULL
) {
83 if (w_current
->toplevel
->bus_style
== THICK
)
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!!!
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
) {
113 } else if (whichone
== 1) {
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
;
166 GList
*prev_conn_objects
= NULL
;
168 g_assert( w_current
->inside_action
!= 0 );
170 if (toplevel
->override_bus_color
== -1) {
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
) ) {
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
);
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
)
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
;
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!!!
252 * \par Function Description
255 void o_bus_invalidate_rubber (GSCHEM_TOPLEVEL
*w_current
)
257 TOPLEVEL
*toplevel
= w_current
->toplevel
;
259 int min_x
, min_y
, max_x
, max_y
;
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>
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
)
292 if (w_current
->toplevel
->bus_style
== THICK
)
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);