1 /* gEDA - GPL Electronic Design Automation
2 * gschem - gEDA Schematic Capture
3 * Copyright (C) 1998-2000 Ales V. Hvezda
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111 USA
24 #include <libgeda/libgeda.h>
26 #include "../include/globals.h"
27 #include "../include/prototype.h"
29 #ifdef HAVE_LIBDMALLOC
33 /*! \todo Finish function documentation!!!
35 * \par Function Description
38 void o_cue_redraw_all(TOPLEVEL
*w_current
, OBJECT
*head
, gboolean draw_selected
)
41 int redraw_state
= w_current
->DONT_REDRAW
;
44 while(o_current
!= NULL
) {
45 switch(o_current
->type
) {
49 if (o_current
->selected
&& !draw_selected
) {
50 w_current
->DONT_REDRAW
= 1 || redraw_state
;
53 w_current
->DONT_REDRAW
= 0 || redraw_state
;
55 o_cue_draw_single(w_current
, o_current
);
59 case(OBJ_PLACEHOLDER
):
60 if (o_current
->selected
&& !draw_selected
) {
61 w_current
->DONT_REDRAW
= 1 || redraw_state
;
64 w_current
->DONT_REDRAW
= 0 || redraw_state
;
66 o_cue_redraw_all(w_current
, o_current
->complex->prim_objs
,
72 o_current
= o_current
->next
;
74 w_current
->DONT_REDRAW
= redraw_state
;
77 /*! \todo Finish function documentation!!!
79 * \par Function Description
82 void o_cue_draw_lowlevel(TOPLEVEL
*w_current
, OBJECT
*object
, int whichone
)
84 int x
, y
, screen_x
, screen_y
;
89 int size
, x2size
, pinsize
;
91 int bus_involved
=FALSE
;
93 if (whichone
< 0 || whichone
> 1) return;
95 x
= object
->line
->x
[whichone
];
96 y
= object
->line
->y
[whichone
];
100 cl_current
= object
->conn_list
;
101 while(cl_current
!= NULL
&& !done
) {
102 conn
= (CONN
*) cl_current
->data
;
104 if (conn
->x
== x
&& conn
->y
== y
) {
106 printf("type: %d x: %d y: %d cx: %d cy: %d\n", conn
->type
, x
, y
, conn
->x
, conn
->y
);
112 if (conn
->other_object
&&
113 ((object
->type
== OBJ_NET
&&
114 conn
->other_object
->type
== OBJ_BUS
) ||
115 (object
->type
== OBJ_BUS
&&
116 conn
->other_object
->type
== OBJ_NET
))) {
122 type
= CONN_MIDPOINT
;
125 if (conn
->other_object
&&
126 ((object
->type
== OBJ_NET
&&
127 conn
->other_object
->type
== OBJ_BUS
) ||
128 (object
->type
== OBJ_BUS
&&
129 conn
->other_object
->type
== OBJ_NET
))) {
136 cl_current
= cl_current
->next
;
140 printf("type: %d count: %d\n", type
, count
);
143 size
= SCREENabs(w_current
, CUE_BOX_SIZE
);
146 if (w_current
->override_color
!= -1 ) {
147 gdk_gc_set_foreground(w_current
->gc
,
148 x_get_color(w_current
->override_color
));
150 gdk_gc_set_foreground(w_current
->gc
,
151 x_get_color(w_current
->net_endpoint_color
));
154 WORLDtoSCREEN(w_current
, x
, y
, &screen_x
, &screen_y
);
159 if (object
->type
== OBJ_NET
) { /* only nets have these cues */
160 if (count
< 1) { /* Didn't find anything connected there */
161 if (w_current
->DONT_REDRAW
== 0) {
162 gdk_draw_rectangle(w_current
->window
,
168 gdk_draw_rectangle(w_current
->backingstore
,
176 } else if (count
>= 2) {
180 size
= SCREENabs(w_current
, CUE_CIRCLE_SMALL_SIZE
);
182 size
= SCREENabs(w_current
, CUE_CIRCLE_LARGE_SIZE
);
184 if (w_current
->DONT_REDRAW
== 0) {
185 gdk_draw_arc(w_current
->window
, w_current
->gc
,
189 size
, size
, 0, FULL_CIRCLE
);
190 gdk_draw_arc(w_current
->backingstore
,
194 size
, size
, 0, FULL_CIRCLE
);
197 } else if (object
->type
== OBJ_PIN
) {
198 /* Didn't find anything connected there */
199 if (count
< 1 && object
->whichend
== whichone
) {
201 otherone
= !whichone
;
203 pinsize
= SCREENabs(w_current
, 10);
204 if (w_current
->pin_style
== THICK
) {
205 gdk_gc_set_line_attributes(w_current
->gc
, pinsize
,
211 if (w_current
->DONT_REDRAW
== 0) {
212 if (object
->line
->y
[whichone
] == object
->line
->y
[otherone
]) {
213 /* horizontal line */
214 if (object
->line
->x
[whichone
] <= object
->line
->x
[otherone
]) {
215 gdk_draw_line(w_current
->window
, w_current
->gc
,
216 screen_x
, screen_y
, screen_x
+ size
, screen_y
);
217 gdk_draw_line(w_current
->backingstore
, w_current
->gc
,
218 screen_x
, screen_y
, screen_x
+ size
, screen_y
);
220 gdk_draw_line(w_current
->window
, w_current
->gc
,
221 screen_x
, screen_y
, screen_x
- size
, screen_y
);
222 gdk_draw_line(w_current
->backingstore
, w_current
->gc
,
223 screen_x
, screen_y
, screen_x
- size
, screen_y
);
225 } else if (object
->line
->x
[0] == object
->line
->x
[1]) {
227 if (object
->line
->y
[whichone
] <= object
->line
->y
[otherone
]) {
228 gdk_draw_line(w_current
->window
, w_current
->gc
,
229 screen_x
, screen_y
, screen_x
, screen_y
- size
);
230 gdk_draw_line(w_current
->backingstore
, w_current
->gc
,
231 screen_x
, screen_y
, screen_x
, screen_y
- size
);
233 gdk_draw_line(w_current
->window
, w_current
->gc
,
234 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 que for angled pin for now. hack */
244 if (w_current
->pin_style
== THICK
) {
245 gdk_gc_set_line_attributes(w_current
->gc
, 0,
258 size
= SCREENabs(w_current
, CUE_CIRCLE_SMALL_SIZE
);
260 size
= SCREENabs(w_current
, CUE_CIRCLE_LARGE_SIZE
);
263 if (w_current
->DONT_REDRAW
== 0) {
264 gdk_draw_arc(w_current
->window
, w_current
->gc
,
268 size
, size
, 0, FULL_CIRCLE
);
269 gdk_draw_arc(w_current
->backingstore
,
273 size
, size
, 0, FULL_CIRCLE
);
277 /* here is where you draw bus rippers */
283 /*! \brief Lowlevel endpoint erase.
284 * \par Function Description
285 * This function erases OBJECT endpoints forceably.
287 * \param [in] w_current The TOPLEVEL object.
288 * \param [in] object OBJECT to forceably erase endpoint from.
289 * \param [in] whichone Which endpoint to erase from OBJECT.
291 void o_cue_erase_lowlevel(TOPLEVEL
*w_current
, OBJECT
*object
, int whichone
)
293 int x
, y
, screen_x
, screen_y
;
296 x
= object
->line
->x
[whichone
];
297 y
= object
->line
->y
[whichone
];
299 size
= SCREENabs(w_current
, CUE_BOX_SIZE
);
302 gdk_gc_set_foreground(w_current
->gc
,
303 x_get_color(w_current
->background_color
));
305 WORLDtoSCREEN(w_current
, x
, y
, &screen_x
, &screen_y
);
307 if (w_current
->DONT_REDRAW
== 0) {
308 gdk_draw_rectangle(w_current
->window
,
314 gdk_draw_rectangle(w_current
->backingstore
,
324 /*! \todo Finish function documentation!!!
326 * \par Function Description
329 void o_cue_draw_lowlevel_midpoints(TOPLEVEL
*w_current
, OBJECT
*object
)
331 int x
, y
, screen_x
, screen_y
;
336 if (w_current
->override_color
!= -1 ) {
337 gdk_gc_set_foreground(w_current
->gc
,
338 x_get_color(w_current
->override_color
));
340 gdk_gc_set_foreground(w_current
->gc
,
341 x_get_color(w_current
->net_endpoint_color
));
344 cl_current
= object
->conn_list
;
345 while(cl_current
!= NULL
) {
346 conn
= (CONN
*) cl_current
->data
;
354 WORLDtoSCREEN(w_current
, x
, y
, &screen_x
, &screen_y
);
357 if (conn
->other_object
&&
358 ( (object
->type
== OBJ_BUS
&&
359 conn
->other_object
->type
== OBJ_NET
) ||
360 (object
->type
== OBJ_NET
&&
361 conn
->other_object
->type
== OBJ_BUS
))) {
362 size
= SCREENabs(w_current
, CUE_CIRCLE_SMALL_SIZE
);
364 size
= SCREENabs(w_current
, CUE_CIRCLE_LARGE_SIZE
);
367 if (w_current
->DONT_REDRAW
== 0) {
368 gdk_draw_arc(w_current
->window
, w_current
->gc
,
372 size
, size
, 0, FULL_CIRCLE
);
373 gdk_draw_arc(w_current
->backingstore
,
377 size
, size
, 0, FULL_CIRCLE
);
383 cl_current
= cl_current
->next
;
387 /*! \todo Finish function documentation!!!
389 * \par Function Description
392 void o_cue_draw_single(TOPLEVEL
*w_current
, OBJECT
*object
)
398 if (object
->type
!= OBJ_NET
&& object
->type
!= OBJ_PIN
&&
399 object
->type
!= OBJ_BUS
) {
403 if (object
->type
!= OBJ_PIN
) {
404 o_cue_draw_lowlevel(w_current
, object
, 0);
405 o_cue_draw_lowlevel(w_current
, object
, 1);
406 o_cue_draw_lowlevel_midpoints(w_current
, object
);
408 o_cue_draw_lowlevel(w_current
, object
, object
->whichend
);
412 /*! \todo Finish function documentation!!!
414 * \par Function Description
417 void o_cue_erase_single(TOPLEVEL
*w_current
, OBJECT
*object
)
423 if (object
->type
!= OBJ_NET
&& object
->type
!= OBJ_PIN
&&
424 object
->type
!= OBJ_BUS
)
429 if (object
->type
!= OBJ_PIN
) {
430 o_cue_erase_lowlevel(w_current
, object
, 0);
431 o_cue_erase_lowlevel(w_current
, object
, 1);
432 w_current
->override_color
= w_current
->background_color
;
433 o_cue_draw_lowlevel_midpoints(w_current
, object
);
434 w_current
->override_color
= -1;
436 o_cue_erase_lowlevel(w_current
, object
, object
->whichend
);
440 /*! \todo Finish function documentation!!!
442 * \par Function Description
445 void o_cue_undraw(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
= cl_current
->next
;
463 o_redraw_single(w_current
, object
);
466 /*! \brief Undraw complex OBJECT.
467 * \par Function Description
468 * This function undraws complex objects (pass in the toplevel object)
470 * \param [in] w_current The TOPLEVEL object.
471 * \param [in] object OBJECT to undraw.
473 void o_cue_undraw_complex(TOPLEVEL
*w_current
, OBJECT
*object
)
479 if (object
->type
!= OBJ_COMPLEX
&& object
->type
!= OBJ_PLACEHOLDER
) {
483 o_current
= object
->complex->prim_objs
;
484 while(o_current
!= NULL
) {
486 if (o_current
->type
== OBJ_PIN
|| o_current
->type
== OBJ_NET
||
487 o_current
->type
== OBJ_BUS
) {
489 o_cue_erase_single(w_current
, o_current
);
491 cl_current
= o_current
->conn_list
;
492 while(cl_current
!= NULL
) {
493 conn
= (CONN
*) cl_current
->data
;
495 if (conn
->other_object
) {
496 o_redraw_single(w_current
, conn
->other_object
);
499 cl_current
= cl_current
->next
;
502 o_current
= o_current
->next
;
505 o_redraw_single(w_current
, object
);
508 /*! \todo Finish function documentation!!!
510 * \par Function Description
513 void o_cue_draw_list(TOPLEVEL
*w_current
, GList
*object_list
)
518 ol_current
= object_list
;
519 while(ol_current
!= NULL
) {
520 object
= (OBJECT
*) ol_current
->data
;
522 o_cue_draw_single(w_current
, object
);
524 ol_current
= ol_current
->next
;
528 /*! \todo Finish function documentation!!!
530 * \par Function Description
533 void o_cue_undraw_list(TOPLEVEL
*w_current
, GList
*object_list
)
538 ol_current
= object_list
;
539 while(ol_current
!= NULL
) {
540 object
= (OBJECT
*) ol_current
->data
;
542 o_cue_undraw(w_current
, object
);
544 ol_current
= ol_current
->next
;
548 /*! \todo Finish function documentation!!!
550 * \par Function Description
553 void o_cue_undraw_objects(TOPLEVEL
*w_current
, OBJECT
*list
)
558 while(o_current
!= NULL
) {
560 if (o_current
->type
== OBJ_PIN
|| o_current
->type
== OBJ_NET
||
561 o_current
->type
== OBJ_BUS
) {
562 o_cue_undraw(w_current
, o_current
);
565 o_current
= o_current
->next
;