Added a new parameter to o_redraw and o_cue_redraw_all,
[geda-gaf/whiteaudio.git] / gschem / src / o_cue.c
blob4f2861542fbd07b278c7756e0bc8d88ff3471d68
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
19 #include <config.h>
21 #include <stdio.h>
22 #include <string.h>
24 #include <libgeda/libgeda.h>
26 #include "../include/globals.h"
27 #include "../include/prototype.h"
29 #ifdef HAVE_LIBDMALLOC
30 #include <dmalloc.h>
31 #endif
33 /*! \todo Finish function documentation!!!
34 * \brief
35 * \par Function Description
38 void o_cue_redraw_all(TOPLEVEL *w_current, OBJECT *head, gboolean draw_selected)
40 OBJECT *o_current;
41 int redraw_state = w_current->DONT_REDRAW;
43 o_current = head;
44 while(o_current != NULL) {
45 switch(o_current->type) {
46 case(OBJ_NET):
47 case(OBJ_BUS):
48 case(OBJ_PIN):
49 if (o_current->selected && !draw_selected) {
50 w_current->DONT_REDRAW = 1 || redraw_state;
52 else {
53 w_current->DONT_REDRAW = 0 || redraw_state;
55 o_cue_draw_single(w_current, o_current);
56 break;
58 case(OBJ_COMPLEX):
59 case(OBJ_PLACEHOLDER):
60 if (o_current->selected && !draw_selected) {
61 w_current->DONT_REDRAW = 1 || redraw_state;
63 else {
64 w_current->DONT_REDRAW = 0 || redraw_state;
66 o_cue_redraw_all(w_current, o_current->complex->prim_objs,
67 draw_selected);
68 break;
72 o_current = o_current->next;
74 w_current->DONT_REDRAW = redraw_state;
77 /*! \todo Finish function documentation!!!
78 * \brief
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;
85 GList *cl_current;
86 CONN *conn;
87 int type, count = 0;
88 int done = FALSE;
89 int size, x2size, pinsize;
90 int otherone;
91 int bus_involved=FALSE;
93 if (whichone < 0 || whichone > 1) return;
95 x = object->line->x[whichone];
96 y = object->line->y[whichone];
98 type = CONN_ENDPOINT;
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) {
105 #if 0
106 printf("type: %d x: %d y: %d cx: %d cy: %d\n", conn->type, x, y, conn->x, conn->y);
107 #endif
108 switch(conn->type) {
110 case(CONN_ENDPOINT):
111 count++;
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))) {
117 bus_involved=TRUE;
119 break;
121 case(CONN_MIDPOINT):
122 type = CONN_MIDPOINT;
123 done = TRUE;
124 count = 0;
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))) {
130 bus_involved=TRUE;
132 break;
136 cl_current = cl_current->next;
139 #if DEBUG
140 printf("type: %d count: %d\n", type, count);
141 #endif
143 size = SCREENabs(w_current, CUE_BOX_SIZE);
144 x2size = 2 * size;
146 if (w_current->override_color != -1 ) {
147 gdk_gc_set_foreground(w_current->gc,
148 x_get_color(w_current->override_color));
149 } else {
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);
156 switch(type) {
158 case(CONN_ENDPOINT):
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,
163 w_current->gc, TRUE,
164 screen_x - size,
165 screen_y - size,
166 x2size,
167 x2size);
168 gdk_draw_rectangle(w_current->backingstore,
169 w_current->gc, TRUE,
170 screen_x - size,
171 screen_y - size,
172 x2size,
173 x2size);
176 } else if (count >= 2) {
177 /* draw circle */
179 if (bus_involved) {
180 size = SCREENabs(w_current, CUE_CIRCLE_SMALL_SIZE);
181 } else {
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,
186 TRUE,
187 screen_x - size / 2,
188 screen_y - size / 2,
189 size, size, 0, FULL_CIRCLE);
190 gdk_draw_arc(w_current->backingstore,
191 w_current->gc, TRUE,
192 screen_x - size / 2,
193 screen_y - size / 2,
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,
206 GDK_LINE_SOLID,
207 GDK_CAP_NOT_LAST,
208 GDK_JOIN_MITER);
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);
219 } else {
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]) {
226 /* vertical line */
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);
232 } else {
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);
238 } else {
239 /* angled line */
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,
246 GDK_LINE_SOLID,
247 GDK_CAP_NOT_LAST,
248 GDK_JOIN_MITER);
252 break;
254 case(CONN_MIDPOINT):
256 /* draw circle */
257 if (bus_involved) {
258 size = SCREENabs(w_current, CUE_CIRCLE_SMALL_SIZE);
259 } else {
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,
265 TRUE,
266 screen_x - size / 2,
267 screen_y - size / 2,
268 size, size, 0, FULL_CIRCLE);
269 gdk_draw_arc(w_current->backingstore,
270 w_current->gc, TRUE,
271 screen_x - size / 2,
272 screen_y - size / 2,
273 size, size, 0, FULL_CIRCLE);
275 break;
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;
294 int size, x2size;
296 x = object->line->x[whichone];
297 y = object->line->y[whichone];
299 size = SCREENabs(w_current, CUE_BOX_SIZE);
300 x2size = 2 * 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,
309 w_current->gc, TRUE,
310 screen_x - size,
311 screen_y - size,
312 x2size,
313 x2size);
314 gdk_draw_rectangle(w_current->backingstore,
315 w_current->gc, TRUE,
316 screen_x - size,
317 screen_y - size,
318 x2size,
319 x2size);
324 /*! \todo Finish function documentation!!!
325 * \brief
326 * \par Function Description
329 void o_cue_draw_lowlevel_midpoints(TOPLEVEL *w_current, OBJECT *object)
331 int x, y, screen_x, screen_y;
332 GList *cl_current;
333 CONN *conn;
334 int size;
336 if (w_current->override_color != -1 ) {
337 gdk_gc_set_foreground(w_current->gc,
338 x_get_color(w_current->override_color));
339 } else {
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;
348 switch(conn->type) {
349 case(CONN_MIDPOINT):
351 x = conn->x;
352 y = conn->y;
354 WORLDtoSCREEN(w_current, x, y, &screen_x, &screen_y);
356 /* draw circle */
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);
363 } else {
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,
369 TRUE,
370 screen_x - size / 2,
371 screen_y - size / 2,
372 size, size, 0, FULL_CIRCLE);
373 gdk_draw_arc(w_current->backingstore,
374 w_current->gc, TRUE,
375 screen_x - size / 2,
376 screen_y - size / 2,
377 size, size, 0, FULL_CIRCLE);
379 break;
383 cl_current = cl_current->next;
387 /*! \todo Finish function documentation!!!
388 * \brief
389 * \par Function Description
392 void o_cue_draw_single(TOPLEVEL *w_current, OBJECT *object)
394 if (!object) {
395 return;
398 if (object->type != OBJ_NET && object->type != OBJ_PIN &&
399 object->type != OBJ_BUS) {
400 return;
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);
407 } else {
408 o_cue_draw_lowlevel(w_current, object, object->whichend);
412 /*! \todo Finish function documentation!!!
413 * \brief
414 * \par Function Description
417 void o_cue_erase_single(TOPLEVEL *w_current, OBJECT *object)
419 if (!object) {
420 return;
423 if (object->type != OBJ_NET && object->type != OBJ_PIN &&
424 object->type != OBJ_BUS)
426 return;
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;
435 } else {
436 o_cue_erase_lowlevel(w_current, object, object->whichend);
440 /*! \todo Finish function documentation!!!
441 * \brief
442 * \par Function Description
445 void o_cue_undraw(TOPLEVEL *w_current, OBJECT *object)
447 GList *cl_current;
448 CONN *conn;
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)
475 GList *cl_current;
476 CONN *conn;
477 OBJECT *o_current;
479 if (object->type != OBJ_COMPLEX && object->type != OBJ_PLACEHOLDER) {
480 return;
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!!!
509 * \brief
510 * \par Function Description
513 void o_cue_draw_list(TOPLEVEL *w_current, GList *object_list)
515 OBJECT *object;
516 GList *ol_current;
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!!!
529 * \brief
530 * \par Function Description
533 void o_cue_undraw_list(TOPLEVEL *w_current, GList *object_list)
535 OBJECT *object;
536 GList *ol_current;
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!!!
549 * \brief
550 * \par Function Description
553 void o_cue_undraw_objects(TOPLEVEL *w_current, OBJECT *list)
555 OBJECT *o_current;
557 o_current = 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;