1 /* gEDA - GPL Electronic Design Automation
2 * gschem - gEDA Schematic Capture
3 * Copyright (C) 1998-2007 Ales Hvezda
4 * Copyright (C) 1998-2007 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
27 #ifdef HAVE_LIBDMALLOC
31 /*! \todo Finish function documentation!!!
33 * \par Function Description
36 void o_cue_redraw_all(GSCHEM_TOPLEVEL
*w_current
, OBJECT
*head
, gboolean draw_selected
)
38 TOPLEVEL
*toplevel
= w_current
->toplevel
;
40 int redraw_state
= w_current
->toplevel
->DONT_REDRAW
;
43 while(o_current
!= NULL
) {
44 switch(o_current
->type
) {
48 if (o_current
->dont_redraw
||
49 (o_current
->selected
&& !draw_selected
)) {
50 w_current
->toplevel
->DONT_REDRAW
= 1 || redraw_state
;
53 w_current
->toplevel
->DONT_REDRAW
= 0 || redraw_state
;
55 o_cue_draw_single(w_current
, o_current
);
59 case(OBJ_PLACEHOLDER
):
60 if (o_current
->dont_redraw
||
61 (o_current
->selected
&& !draw_selected
)) {
62 toplevel
->DONT_REDRAW
= 1 || redraw_state
;
65 toplevel
->DONT_REDRAW
= 0 || redraw_state
;
67 o_cue_redraw_all(w_current
, o_current
->complex->prim_objs
,
73 o_current
= o_current
->next
;
75 toplevel
->DONT_REDRAW
= redraw_state
;
80 * \brief Set the color on the gc depending on the passed in color id
82 static void o_cue_set_color(GSCHEM_TOPLEVEL
*w_current
, int color
)
84 if (w_current
->toplevel
->override_color
!= -1 ) {
85 gdk_gc_set_foreground(w_current
->gc
,
86 x_get_color(w_current
->toplevel
->override_color
));
88 gdk_gc_set_foreground(w_current
->gc
, x_get_color(color
));
93 /*! \todo Finish function documentation!!!
95 * \par Function Description
98 void o_cue_draw_lowlevel(GSCHEM_TOPLEVEL
*w_current
, OBJECT
*object
, int whichone
)
100 TOPLEVEL
*toplevel
= w_current
->toplevel
;
101 PAGE
*page
= toplevel
->page_current
;
102 int x
[2], y
[2], screen_x
, screen_y
;
107 int size
, x2size
, pinsize
;
109 int bus_involved
=FALSE
;
111 if (whichone
!= GRIP_1
&& whichone
!= GRIP_2
) return;
113 s_basic_get_grip(object
, whichone
, &x
[0], &y
[0]);
115 type
= CONN_ENDPOINT
;
117 cl_current
= object
->conn_list
;
118 while(cl_current
!= NULL
&& !done
) {
119 conn
= (CONN
*) cl_current
->data
;
121 if (conn
->x
== x
[0] && conn
->y
== y
[0]) {
126 if (conn
->other_object
&&
127 ((object
->type
== OBJ_NET
&&
128 conn
->other_object
->type
== OBJ_BUS
) ||
129 (object
->type
== OBJ_BUS
&&
130 conn
->other_object
->type
== OBJ_NET
))) {
136 type
= CONN_MIDPOINT
;
139 if (conn
->other_object
&&
140 ((object
->type
== OBJ_NET
&&
141 conn
->other_object
->type
== OBJ_BUS
) ||
142 (object
->type
== OBJ_BUS
&&
143 conn
->other_object
->type
== OBJ_NET
))) {
150 cl_current
= g_list_next(cl_current
);
154 printf("type: %d count: %d\n", type
, count
);
157 size
= SCREENabs(page
, CUE_BOX_SIZE
);
160 WORLDtoSCREEN(page
, x
[0], y
[0], &screen_x
, &screen_y
);
165 if (object
->type
== OBJ_NET
) { /* only nets have these cues */
166 if (count
< 1) { /* Didn't find anything connected there */
167 if (toplevel
->DONT_REDRAW
== 0) {
168 o_cue_set_color(w_current
, toplevel
->net_endpoint_color
);
169 gdk_draw_rectangle(w_current
->backingstore
,
175 o_invalidate_rect(w_current
, screen_x
- size
, screen_y
- size
,
176 screen_x
+ size
, screen_y
+ size
);
179 } else if (count
>= 2) {
183 size
= SCREENabs(page
, CUE_CIRCLE_SMALL_SIZE
) / 2;
185 size
= SCREENabs(page
, CUE_CIRCLE_LARGE_SIZE
) / 2;
188 if (toplevel
->DONT_REDRAW
== 0) {
189 o_cue_set_color(w_current
, toplevel
->junction_color
);
190 gdk_draw_arc(w_current
->backingstore
,
194 x2size
, x2size
, 0, FULL_CIRCLE
);
195 o_invalidate_rect(w_current
, screen_x
- size
, screen_y
- size
,
196 screen_x
+ size
, screen_y
+ size
);
199 } else if (object
->type
== OBJ_PIN
) {
200 /* Didn't find anything connected there */
201 if (count
< 1 && object
->whichend
== whichone
) {
203 otherone
= (whichone
== GRIP_1
? GRIP_2
: GRIP_1
);
205 pinsize
= SCREENabs(page
, 10);
206 if (toplevel
->pin_style
== THICK
) {
207 gdk_gc_set_line_attributes(w_current
->gc
, pinsize
,
213 /* No need to invalidate the PIN end CUE, as the
214 * whole pin region is already invalidated. */
215 if (toplevel
->DONT_REDRAW
== 0) {
216 s_basic_get_grip(object
, otherone
, &x
[1], &y
[1]);
218 o_cue_set_color(w_current
, toplevel
->net_endpoint_color
);
221 /* horizontal line */
223 gdk_draw_line(w_current
->backingstore
, w_current
->gc
,
224 screen_x
, screen_y
, screen_x
+ size
, screen_y
);
226 gdk_draw_line(w_current
->backingstore
, w_current
->gc
,
227 screen_x
, screen_y
, screen_x
- size
, screen_y
);
229 } else if (x
[0] == x
[1]) {
232 gdk_draw_line(w_current
->backingstore
, w_current
->gc
,
233 screen_x
, screen_y
, screen_x
, screen_y
- size
);
235 gdk_draw_line(w_current
->backingstore
, w_current
->gc
,
236 screen_x
, screen_y
, screen_x
, screen_y
+ size
);
240 /* not supporting rendering of cue for angled pin for now. hack */
244 if (toplevel
->pin_style
== THICK
) {
245 gdk_gc_set_line_attributes(w_current
->gc
, 0,
258 size
= SCREENabs(page
, CUE_CIRCLE_SMALL_SIZE
) / 2;
260 size
= SCREENabs(page
, CUE_CIRCLE_LARGE_SIZE
) / 2;
264 if (toplevel
->DONT_REDRAW
== 0) {
265 o_cue_set_color(w_current
, toplevel
->junction_color
);
266 gdk_draw_arc(w_current
->backingstore
,
270 x2size
, x2size
, 0, FULL_CIRCLE
);
271 o_invalidate_rect(w_current
, screen_x
- size
, screen_y
- size
,
272 screen_x
+ size
, screen_y
+ size
);
276 /* here is where you draw bus rippers */
282 /*! \brief Lowlevel endpoint erase.
283 * \par Function Description
284 * This function erases OBJECT endpoints forcibly.
286 * \param [in] w_current The GSCHEM_TOPLEVEL object.
287 * \param [in] object OBJECT to forcibly erase endpoint from.
288 * \param [in] whichone Which endpoint to erase from OBJECT.
290 void o_cue_erase_lowlevel(GSCHEM_TOPLEVEL
*w_current
, OBJECT
*object
, int whichone
)
292 TOPLEVEL
*toplevel
= w_current
->toplevel
;
293 PAGE
*page
= toplevel
->page_current
;
294 int x
, y
, screen_x
, screen_y
;
297 s_basic_get_grip(object
, whichone
, &x
, &y
);
299 size
= SCREENabs(page
, CUE_BOX_SIZE
);
302 gdk_gc_set_foreground(w_current
->gc
,
303 x_get_color(toplevel
->background_color
));
305 WORLDtoSCREEN(page
, x
, y
, &screen_x
, &screen_y
);
307 if (toplevel
->DONT_REDRAW
== 0) {
308 gdk_draw_rectangle(w_current
->backingstore
,
314 o_invalidate_rect(w_current
, screen_x
- size
, screen_y
- size
,
315 screen_x
+ size
, screen_y
+ size
);
320 /*! \todo Finish function documentation!!!
322 * \par Function Description
325 void o_cue_draw_lowlevel_midpoints(GSCHEM_TOPLEVEL
*w_current
, OBJECT
*object
)
327 TOPLEVEL
*toplevel
= w_current
->toplevel
;
328 PAGE
*page
= toplevel
->page_current
;
329 int x
, y
, screen_x
, screen_y
;
334 if (toplevel
->override_color
!= -1 ) {
335 gdk_gc_set_foreground(w_current
->gc
,
336 x_get_color(toplevel
->override_color
));
338 gdk_gc_set_foreground(w_current
->gc
,
339 x_get_color(toplevel
->junction_color
));
342 cl_current
= object
->conn_list
;
343 while(cl_current
!= NULL
) {
344 conn
= (CONN
*) cl_current
->data
;
352 WORLDtoSCREEN(page
, x
, y
, &screen_x
, &screen_y
);
355 if (conn
->other_object
&&
356 ( (object
->type
== OBJ_BUS
&&
357 conn
->other_object
->type
== OBJ_NET
) ||
358 (object
->type
== OBJ_NET
&&
359 conn
->other_object
->type
== OBJ_BUS
))) {
360 size
= SCREENabs(page
, CUE_CIRCLE_SMALL_SIZE
) / 2;
362 size
= SCREENabs(page
, CUE_CIRCLE_LARGE_SIZE
) / 2;
366 if (toplevel
->DONT_REDRAW
== 0) {
367 gdk_draw_arc(w_current
->backingstore
,
371 x2size
, x2size
, 0, FULL_CIRCLE
);
372 o_invalidate_rect(w_current
, screen_x
- size
, screen_y
- size
,
373 screen_x
+ size
, screen_y
+ size
);
379 cl_current
= g_list_next(cl_current
);
383 /*! \todo Finish function documentation!!!
385 * \par Function Description
388 void o_cue_draw_single(GSCHEM_TOPLEVEL
*w_current
, OBJECT
*object
)
394 if (object
->type
!= OBJ_NET
&& object
->type
!= OBJ_PIN
&&
395 object
->type
!= OBJ_BUS
) {
399 if (object
->type
!= OBJ_PIN
) {
400 o_cue_draw_lowlevel(w_current
, object
, GRIP_1
);
401 o_cue_draw_lowlevel(w_current
, object
, GRIP_2
);
402 o_cue_draw_lowlevel_midpoints(w_current
, object
);
404 o_cue_draw_lowlevel(w_current
, object
, object
->whichend
);
408 /*! \todo Finish function documentation!!!
410 * \par Function Description
413 void o_cue_erase_single(GSCHEM_TOPLEVEL
*w_current
, OBJECT
*object
)
415 TOPLEVEL
*toplevel
= w_current
->toplevel
;
420 if (object
->type
!= OBJ_NET
&& object
->type
!= OBJ_PIN
&&
421 object
->type
!= OBJ_BUS
)
426 if (object
->type
!= OBJ_PIN
) {
427 o_cue_erase_lowlevel(w_current
, object
, GRIP_1
);
428 o_cue_erase_lowlevel(w_current
, object
, GRIP_2
);
429 toplevel
->override_color
= toplevel
->background_color
;
430 o_cue_draw_lowlevel_midpoints(w_current
, object
);
431 toplevel
->override_color
= -1;
433 o_cue_erase_lowlevel(w_current
, object
, object
->whichend
);
437 /*! \brief Erase the cues of an object and redraw connected objects.
438 * \par Function Description
439 * This function erases the cues on object \a object. It then redraws
440 * the cues of its connected objects.
442 * \param [in] w_current The GSCHEM_TOPLEVEL object.
443 * \param [in] object The object to redraw with no cue.
445 static void o_cue_undraw_lowlevel(GSCHEM_TOPLEVEL
*w_current
, OBJECT
*object
)
450 o_cue_erase_single(w_current
, object
);
452 cl_current
= object
->conn_list
;
453 while(cl_current
!= NULL
) {
454 conn
= (CONN
*) cl_current
->data
;
456 if (conn
->other_object
) {
457 o_redraw_single(w_current
, conn
->other_object
);
460 cl_current
= g_list_next(cl_current
);
464 /*! \brief Hide the cues of an object.
465 * \par Function Description
466 * This function takes an object and redraws it without its cues. It
467 * also manages the redraw of connected objects.
470 * The connections of the object are unchanged by this function.
472 * \param [in] w_current The GSCHEM_TOPLEVEL object.
473 * \param [in] object The object to redraw with no cue.
475 void o_cue_undraw(GSCHEM_TOPLEVEL
*w_current
, OBJECT
*object
)
477 switch (object
->type
) {
481 o_cue_undraw_lowlevel (w_current
, object
);
484 case OBJ_PLACEHOLDER
:
487 for (o_current
= object
->complex->prim_objs
;
489 o_current
= o_current
->next
) {
490 if (o_current
->type
== OBJ_PIN
||
491 o_current
->type
== OBJ_NET
||
492 o_current
->type
== OBJ_BUS
) {
493 o_cue_undraw_lowlevel (w_current
, o_current
);
499 o_redraw_single(w_current
, object
);
502 /*! \todo Finish function documentation!!!
504 * \par Function Description
507 void o_cue_draw_list(GSCHEM_TOPLEVEL
*w_current
, GList
const *object_list
)
510 GList
const *ol_current
;
512 ol_current
= object_list
;
513 while(ol_current
!= NULL
) {
514 object
= ol_current
->data
;
516 o_cue_draw_single(w_current
, object
);
518 ol_current
= g_list_next(ol_current
);
522 /*! \todo Finish function documentation!!!
524 * \par Function Description
527 void o_cue_undraw_list(GSCHEM_TOPLEVEL
*w_current
, GList
const *object_list
)
530 GList
const *ol_current
;
532 ol_current
= object_list
;
533 while(ol_current
!= NULL
) {
534 object
= ol_current
->data
;
536 o_cue_undraw(w_current
, object
);
538 ol_current
= g_list_next(ol_current
);