Recreate text prim_objs only when drawing them.
[geda-gaf/berndj.git] / gschem / src / o_attrib.c
blob49ee0af90f4858c98a62828a17ddc9d84d49456e
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
20 #include <config.h>
22 #include <stdio.h>
23 #ifdef HAVE_STRING_H
24 #include <string.h>
25 #endif
26 #include <math.h>
28 #include "gschem.h"
30 #ifdef HAVE_LIBDMALLOC
31 #include <dmalloc.h>
32 #endif
34 /* No special type for attributes */
35 /* You can only edit text attributes */
37 /* be sure in o_copy o_move o_delete you maintain the attributes */
38 /* delete is a bare, because you will have to unattach the other end */
39 /* and in o_save o_read as well */
40 /* and in o_select when selecting objects, select the attributes */
42 /* there needs to be a modifier (in struct.h, such as a flag) which
43 * signifies that this is an attribute */
45 /*! \todo Finish function documentation!!!
46 * \brief
47 * \par Function Description
48 * Copy all attributes select to the selection list.
50 * \todo get a better name
52 void o_attrib_add_selected(GSCHEM_TOPLEVEL *w_current, SELECTION *selection,
53 OBJECT *selected)
55 OBJECT *a_current;
56 GList *a_iter;
58 g_assert( selection != NULL );
60 /* deal with attributes here? */
61 if (selected->attribs != NULL) {
62 /* first node is head */
63 a_iter = selected->attribs;
65 while (a_iter != NULL) {
66 a_current = a_iter->data;
68 /* make sure object isn't selected already */
69 if (a_current->saved_color == -1) {
70 o_selection_add(selection, a_current);
71 o_redraw_single(w_current, a_current);
74 a_iter = g_list_next (a_iter);
78 return;
81 /*! \brief Change visibility status of attribute object.
82 * \par Function Description
83 * This function toggles the visibility status of the attribute \a
84 * object and updates it. The object is erased or redrawn if
85 * necessary.
87 * \param [in] w_current The GSCHEM_TOPLEVEL object.
88 * \param [in] object The attribute object.
90 void o_attrib_toggle_visibility(GSCHEM_TOPLEVEL *w_current, OBJECT *object)
92 TOPLEVEL *toplevel = w_current->toplevel;
94 g_return_if_fail (object != NULL && object->type == OBJ_TEXT);
96 if (o_text_printing_p(object)) {
97 o_erase_single(w_current, object);
99 o_text_change(object, NULL, INVISIBLE, LEAVE_NAME_VALUE_ALONE);
101 if (o_text_display_p(object)) {
102 /* draw text so that little I is drawn */
103 o_text_draw(w_current, object);
105 } else {
106 /* if we are in the special show hidden mode, then erase text first */
107 /* to get rid of the little I */
108 if (o_text_display_p(object)) {
109 o_erase_single(w_current, object);
112 o_text_change(object, NULL, VISIBLE, LEAVE_NAME_VALUE_ALONE);
113 o_text_draw(w_current, object);
116 toplevel->page_current->CHANGED = 1;
119 /*! \brief Set what part of an attribute is shown.
120 * \par Function Description
121 * This function changes what part (name, value or both) of an
122 * attribute is shown by its attribute object. The attribute object
123 * is erased, updated and finally redrawn.
125 * \param [in] w_current The GSCHEM_TOPLEVEL object.
126 * \param [in] object The attribute object.
127 * \param [in] show_name_value The new display flag for attribute.
129 void o_attrib_toggle_show_name_value(GSCHEM_TOPLEVEL *w_current,
130 OBJECT *object, int show_name_value)
132 TOPLEVEL *toplevel = w_current->toplevel;
134 g_return_if_fail (object != NULL && object->type == OBJ_TEXT);
136 o_erase_single(w_current, object);
137 o_text_change(object, NULL, LEAVE_VISIBILITY_ALONE, show_name_value);
138 o_text_draw(w_current, object);
140 toplevel->page_current->CHANGED = 1;
144 /*! \todo Finish function documentation!!!
145 * \brief
146 * \par Function Description
149 /* This function no longer returns NULL, but will always return the new */
150 /* text item */
151 OBJECT *o_attrib_add_attrib(GSCHEM_TOPLEVEL *w_current,
152 const char *text_string, int visibility,
153 int show_name_value, OBJECT *object)
155 TOPLEVEL *toplevel = w_current->toplevel;
156 OBJECT *new_obj;
157 int world_x = - 1, world_y = -1;
158 int color;
159 int left, right, top, bottom;
160 OBJECT *o_current;
162 color = toplevel->detachedattr_color;
164 o_current = object;
166 /* creating a toplevel or unattached attribute */
167 if (o_current) {
168 /* get coordinates of where to place the text object */
169 switch(o_current->type) {
170 int w_x1, w_y1, w_x2, w_y2;
172 case(OBJ_COMPLEX):
173 case(OBJ_PLACEHOLDER):
174 world_x = o_current->complex->x;
175 world_y = o_current->complex->y;
176 color = toplevel->attribute_color;
177 break;
179 case(OBJ_ARC):
180 s_basic_get_grip(o_current, GRIP_ARC_CENTER, &world_x, &world_y);
181 color = toplevel->attribute_color;
182 break;
184 case(OBJ_CIRCLE):
185 s_basic_get_grip(o_current, GRIP_CIRCLE_CENTER, &world_x, &world_y);
186 color = toplevel->attribute_color;
187 break;
189 case(OBJ_BOX):
190 s_basic_get_grip(o_current, GRIP_UPPER_LEFT, &w_x1, &w_y1);
191 s_basic_get_grip(o_current, GRIP_LOWER_RIGHT, &w_x2, &w_y2);
192 world_x = min(w_x1, w_x2);
193 world_y = max(w_y1, w_y2);
194 color = toplevel->attribute_color;
195 break;
197 case(OBJ_LINE):
198 case(OBJ_NET):
199 case(OBJ_PIN):
200 case(OBJ_BUS):
201 s_basic_get_grip(o_current, GRIP_1, &world_x, &world_y);
202 color = toplevel->attribute_color;
203 break;
205 case(OBJ_TEXT):
206 o_text_get_xy(o_current, &world_x, &world_y);
208 color = toplevel->detachedattr_color;
210 o_current = NULL;
211 break;
213 } else {
214 world_get_object_list_bounds(toplevel->page_current->object_head, LIST_KIND_HEAD,
215 &left, &top, &right, &bottom);
217 /* this really is the lower left hand corner */
218 world_x = left;
219 world_y = top;
221 /* printf("%d %d\n", world_x, world_y); */
222 color = toplevel->detachedattr_color;
225 /* first create text item */
226 new_obj = o_text_new(toplevel, OBJ_TEXT, color, world_x, world_y,
227 LOWER_LEFT, 0, /* zero is angle */
228 text_string, w_current->text_size, /* current text size */
229 visibility, show_name_value);
230 s_page_append(toplevel->page_current, new_obj);
232 /* now toplevel->page_current->object_tail contains new text item */
234 /* now attach the attribute to the object (if o_current is not NULL) */
235 /* remember that o_current contains the object to get the attribute */
236 if (o_current) {
237 o_attrib_attach (toplevel, toplevel->page_current->object_tail, o_current);
240 o_selection_add( toplevel->page_current->selection_list,
241 toplevel->page_current->object_tail );
243 o_erase_single(w_current, toplevel->page_current->object_tail);
244 o_text_draw(w_current, toplevel->page_current->object_tail);
246 /* handle slot= attribute, it's a special case */
247 if (g_ascii_strncasecmp (text_string, "slot=", 5) == 0) {
248 o_slot_end (w_current, text_string, strlen (text_string));
251 /* Run the add attribute hook */
252 if (scm_hook_empty_p(add_attribute_hook) == SCM_BOOL_F &&
253 o_current != NULL) {
254 scm_run_hook(add_attribute_hook,
255 scm_cons(g_make_object_smob(toplevel,
256 o_current),
257 SCM_EOL));
260 toplevel->page_current->CHANGED = 1;
262 return(toplevel->page_current->object_tail);