gschem: cleanup o_cue_draw_lowlevel
[geda-gaf.git] / gschem / src / o_cue.c
blob648f044ed03bbce300a92f2b5ede948afa7d8373
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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20 #include <config.h>
22 #include <stdio.h>
23 #include <string.h>
24 #include <math.h> /* For M_PI */
26 #include "gschem.h"
28 #ifdef HAVE_LIBDMALLOC
29 #include <dmalloc.h>
30 #endif
32 /*! \todo Finish function documentation!!!
33 * \brief
34 * \par Function Description
37 void o_cue_redraw_all (GSCHEM_TOPLEVEL *w_current, GList *list, gboolean draw_selected)
39 OBJECT *o_current;
40 GList *iter;
42 iter = list;
43 while (iter != NULL) {
44 o_current = (OBJECT *)iter->data;
45 switch(o_current->type) {
46 case(OBJ_NET):
47 case(OBJ_BUS):
48 case(OBJ_PIN):
49 if (!(o_current->dont_redraw ||
50 (o_current->selected && !draw_selected))) {
51 o_cue_draw_single(w_current, o_current);
52 if (o_current->selected && w_current->draw_grips) {
53 o_line_draw_grips (w_current, o_current);
56 break;
58 case(OBJ_COMPLEX):
59 case(OBJ_PLACEHOLDER):
60 if (!(o_current->dont_redraw ||
61 (o_current->selected && !draw_selected))) {
62 o_cue_redraw_all(w_current, o_current->complex->prim_objs,
63 draw_selected);
65 break;
68 iter = g_list_next (iter);
73 /*!
74 * \brief Set the color on the gc depending on the passed in color id
76 static void o_cue_set_color(GSCHEM_TOPLEVEL *w_current, int color)
78 if (w_current->toplevel->override_color != -1 ) {
79 gschem_cairo_set_source_color (w_current, x_color_lookup (w_current->toplevel->override_color));
80 } else {
81 gschem_cairo_set_source_color (w_current, x_color_lookup (color));
86 /*! \brief Draws a circular junction cue
88 * \par Function Description
89 * Draws a cue at the given world coordinate, picking the size based
90 * on whether a bus forms a part of the connection.
92 * The cue's drawn position is hinted to align with the widht a net or
93 * bus would be drawn on screen. This helps to keep the cue looking
94 * central when lines being hinted onto the pixel grid.
96 * \param [in] w_current The GSCHEM_TOPLEVEL object
97 * \param [in] x The X coordinate of the cue (world units)
98 * \param [in] y The Y coordinate of the cue (world units)
99 * \param [in] bus_involved If a bus forms part of the connection (TRUE/FALSE)
101 static void draw_junction_cue (GSCHEM_TOPLEVEL *w_current,
102 int x, int y, int bus_involved)
104 int size;
105 int line_width;
107 if (bus_involved) {
108 size = JUNCTION_CUE_SIZE_BUS / 2;
109 line_width = BUS_WIDTH;
110 } else {
111 size = JUNCTION_CUE_SIZE_NET / 2;
112 line_width = NET_WIDTH;
115 gschem_cairo_center_arc (w_current, line_width, -1, x, y, size, 0, 360);
116 o_cue_set_color (w_current, JUNCTION_COLOR);
117 cairo_fill (w_current->cr);
121 /*! \todo Finish function documentation!!!
122 * \brief
123 * \par Function Description
126 void o_cue_draw_lowlevel(GSCHEM_TOPLEVEL *w_current, OBJECT *object, int whichone)
128 int x, y;
129 GList *cl_current;
130 CONN *conn;
131 int type, count = 0;
132 int done = FALSE;
133 int size;
134 int bus_involved = FALSE;
136 g_return_if_fail (whichone == 0 || whichone == 1);
138 x = object->line->x[whichone];
139 y = object->line->y[whichone];
141 type = CONN_ENDPOINT;
143 if (object->type == OBJ_BUS ||
144 (object->type == OBJ_PIN && object->pin_type == PIN_TYPE_BUS))
145 bus_involved = TRUE;
147 cl_current = object->conn_list;
148 while (cl_current != NULL && !done) {
149 conn = (CONN *) cl_current->data;
151 if (conn->x == x && conn->y == y) {
153 if (conn->other_object &&
154 (conn->other_object->type == OBJ_BUS ||
155 (conn->other_object->type == OBJ_PIN &&
156 conn->other_object->pin_type == PIN_TYPE_BUS)))
157 bus_involved=TRUE;
159 switch(conn->type) {
161 case(CONN_ENDPOINT):
162 count++;
163 break;
165 case(CONN_MIDPOINT):
166 type = CONN_MIDPOINT;
167 done = TRUE;
168 count = 0;
169 break;
173 cl_current = g_list_next(cl_current);
176 #if DEBUG
177 printf("type: %d count: %d\n", type, count);
178 #endif
180 switch(type) {
182 case(CONN_ENDPOINT):
183 if (object->type == OBJ_NET || object->type == OBJ_PIN) {
184 if (count < 1) { /* Didn't find anything connected there */
185 size = CUE_BOX_SIZE;
186 gschem_cairo_center_box (w_current, -1, -1, x, y, size, size);
187 o_cue_set_color (w_current, NET_ENDPOINT_COLOR);
188 cairo_fill (w_current->cr);
189 } else if (count >= 2) {
190 draw_junction_cue (w_current, x, y, bus_involved);
193 break;
195 case(CONN_MIDPOINT):
196 draw_junction_cue (w_current, x, y, bus_involved);
197 break;
199 /* here is where you draw bus rippers */
206 /*! \todo Finish function documentation!!!
207 * \brief
208 * \par Function Description
211 void o_cue_draw_lowlevel_midpoints(GSCHEM_TOPLEVEL *w_current, OBJECT *object)
213 GList *iter;
214 int bus_involved;
216 for (iter = object->conn_list; iter != NULL; iter = g_list_next (iter)) {
217 CONN *conn = iter->data;
219 if (conn->type == CONN_MIDPOINT) {
220 bus_involved = (object->type == OBJ_BUS ||
221 (conn->other_object &&
222 conn->other_object->type == OBJ_BUS));
223 draw_junction_cue (w_current, conn->x, conn->y, bus_involved);
229 /*! \brief Draw cues for a single object
231 * \par Function Description
232 * Cues are drawn on pins, nets and buses.
233 * Two types of cues are drawn:
234 * - endpoint cues (identifying unconnected ends of objects)
235 * - junction cues (identifying net/pin/bus junctions)
237 * \param [in] w_current The GSCHEM_TOPLEVEL object
238 * \param [in] object The OBJECT to draw cues for
240 void o_cue_draw_single(GSCHEM_TOPLEVEL *w_current, OBJECT *object)
242 g_return_if_fail (object != NULL);
244 switch (object->type) {
245 case(OBJ_NET):
247 * o_cue_draw_lowlevel handles both endpoints and junctions.
248 * The intention of the check is to skip drawing endpoint cues on nets
249 * that are not "fully connected".
250 * Junctions will be drawn correctly, as:
251 * - net-net junctions are handled by o_cue_draw_lowlevel_midpoints
252 * - net-pin and pin-pin junctions are handled by case OBJ_PIN below
254 if (!o_net_is_fully_connected (w_current->toplevel, object)) {
255 o_cue_draw_lowlevel (w_current, object, 0);
256 o_cue_draw_lowlevel (w_current, object, 1);
258 o_cue_draw_lowlevel_midpoints (w_current, object);
259 break;
260 case(OBJ_BUS):
261 o_cue_draw_lowlevel (w_current, object, 0);
262 o_cue_draw_lowlevel (w_current, object, 1);
263 o_cue_draw_lowlevel_midpoints (w_current, object);
264 break;
265 case(OBJ_PIN):
266 o_cue_draw_lowlevel (w_current, object, object->whichend);
267 break;
268 default:
269 return;
274 /*! \todo Finish function documentation!!!
275 * \brief
276 * \par Function Description
279 void o_cue_draw_list(GSCHEM_TOPLEVEL *w_current, GList *object_list)
281 OBJECT *object;
282 GList *ol_current;
284 ol_current = object_list;
285 while(ol_current != NULL) {
286 object = (OBJECT *) ol_current->data;
288 o_cue_draw_single(w_current, object);
290 ol_current = g_list_next(ol_current);