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
35 #ifdef HAVE_LIBDMALLOC
40 /*! \todo Finish function documentation!!!
42 * \par Function Description
45 void o_text_draw_lowlevel(GSCHEM_TOPLEVEL
*w_current
, OBJECT
*o_current
)
47 int left
, right
, top
, bottom
;
49 g_return_if_fail (o_current
!= NULL
);
50 g_return_if_fail (o_current
->text
!= NULL
);
52 if (o_current
->visibility
== INVISIBLE
&& o_current
->show_hidden
&&
53 o_current
->text
->prim_objs
== NULL
) {
54 o_text_recreate(o_current
);
57 o_redraw(w_current
, o_current
->text
->prim_objs
, TRUE
);
59 world_get_object_list_bounds(o_current
->text
->prim_objs
,
60 &left
, &top
, &right
, &bottom
);
61 o_current
->w_left
= left
;
62 o_current
->w_top
= top
;
63 o_current
->w_right
= right
;
64 o_current
->w_bottom
= bottom
;
68 /*! \todo Finish function documentation!!!
70 * \par Function Description
73 void o_text_draw_rectangle(GSCHEM_TOPLEVEL
*w_current
, OBJECT
*o_current
)
75 TOPLEVEL
*toplevel
= w_current
->toplevel
;
76 PAGE
*page
= toplevel
->page_current
;
77 int left
=0, right
=0, top
=0, bottom
=0;
80 if (o_current
->visibility
== INVISIBLE
&& o_current
->show_hidden
&&
81 o_current
->text
->prim_objs
== NULL
) {
82 o_text_recreate(o_current
);
85 /* text is too small so go through and draw a rectangle in
88 /* NOTE THAT THE TOP AND BOTTOM ARE REVERSED THROUGHOUT THE WHOLE OF GEDA FOR WORLD COORDS */
89 WORLDtoSCREEN(page
, o_current
->w_left
, o_current
->w_bottom
, &left
, &top
);
90 WORLDtoSCREEN(page
, o_current
->w_right
, o_current
->w_top
, &right
, &bottom
);
92 if (toplevel
->override_color
!= -1 ) { /* Override */
93 color
= x_get_color(toplevel
->override_color
);
95 color
= x_get_color(o_current
->color
);
97 gdk_gc_set_foreground(w_current
->gc
, color
);
99 if (toplevel
->DONT_REDRAW
== 0) {
100 gdk_draw_rectangle( w_current
->backingstore
,
110 /*! \todo Finish function documentation!!!
112 * \par Function Description
115 void o_text_draw(GSCHEM_TOPLEVEL
*w_current
, OBJECT
*o_current
)
117 TOPLEVEL
*toplevel
= w_current
->toplevel
;
118 PAGE
*page
= toplevel
->page_current
;
119 int screen_x1
, screen_y1
;
120 int small_dist
, offset
;
122 g_return_if_fail (o_current
!= NULL
);
123 g_return_if_fail (o_current
->type
== OBJ_TEXT
);
124 g_return_if_fail (o_current
->text
!= NULL
);
126 if (o_current
->text
->x
== -1 && o_current
->text
->y
-- -1) {
127 /* Off-schematic text has its own dialog. */
131 if (toplevel
->DONT_REDRAW
== 1 ||
132 (o_current
->visibility
== INVISIBLE
&& !o_current
->show_hidden
)) {
136 if (!w_current
->fast_mousepan
|| !w_current
->doing_pan
) {
137 o_text_draw_lowlevel(w_current
, o_current
);
139 /* Indicate on the schematic that the text is invisible by */
140 /* drawing a little I on the screen at the origin */
141 if (o_current
->visibility
== INVISIBLE
&& o_current
->show_hidden
) {
142 if (toplevel
->override_color
!= -1 ) {
143 gdk_gc_set_foreground(w_current
->gc
,
144 x_get_color(toplevel
->override_color
));
147 gdk_gc_set_foreground(w_current
->gc
,
148 x_get_color(w_current
->lock_color
));
151 offset
= SCREENabs(page
, 10);
152 small_dist
= SCREENabs(page
, 20);
153 WORLDtoSCREEN(page
, o_current
->text
->x
, o_current
->text
->y
, &screen_x1
, &screen_y1
);
156 if (toplevel
->DONT_REDRAW
== 0) {
157 /* Top part of the I */
158 gdk_draw_line(w_current
->backingstore
, w_current
->gc
,
161 screen_x1
+small_dist
,
163 /* Middle part of the I */
164 gdk_draw_line(w_current
->backingstore
, w_current
->gc
,
165 screen_x1
+small_dist
/2,
167 screen_x1
+small_dist
/2,
168 screen_y1
+small_dist
);
169 /* Bottom part of the I */
170 gdk_draw_line(w_current
->backingstore
, w_current
->gc
,
172 screen_y1
+small_dist
,
173 screen_x1
+small_dist
,
174 screen_y1
+small_dist
);
179 if (w_current
->doing_pan
) {
180 o_text_draw_rectangle(w_current
, o_current
);
185 /* return if text origin marker displaying is disabled */
186 if (w_current
->text_origin_marker
== FALSE
) {
190 small_dist
= SCREENabs(page
, 10);
192 WORLDtoSCREEN(page
, o_current
->text
->x
, o_current
->text
->y
, &screen_x1
, &screen_y1
);
194 /* this is not really a fix, but a lame patch */
195 /* not having this will cause a bad draw of things when coords */
196 /* get close to the 2^15 limit of X */
197 if (screen_x1
+small_dist
> 32767 || screen_y1
+small_dist
> 32767) {
201 if (toplevel
->override_color
!= -1 ) {
202 gdk_gc_set_foreground(w_current
->gc
,
203 x_get_color(toplevel
->override_color
));
206 gdk_gc_set_foreground(w_current
->gc
,
207 x_get_color(w_current
->lock_color
));
210 if (toplevel
->DONT_REDRAW
== 0) {
211 gdk_draw_line(w_current
->backingstore
, w_current
->gc
,
212 screen_x1
-small_dist
,
213 screen_y1
+small_dist
,
214 screen_x1
+small_dist
,
215 screen_y1
-small_dist
);
217 gdk_draw_line(w_current
->backingstore
, w_current
->gc
,
218 screen_x1
+small_dist
,
219 screen_y1
+small_dist
,
220 screen_x1
-small_dist
,
221 screen_y1
-small_dist
);
226 /*! \todo Finish function documentation!!!
228 * \par Function Description
231 void o_text_draw_xor(GSCHEM_TOPLEVEL
*w_current
, int dx
, int dy
, OBJECT
*o_current
)
233 TOPLEVEL
*toplevel
= w_current
->toplevel
;
234 PAGE
*page
= toplevel
->page_current
;
235 int top
, bottom
, left
, right
;
238 if (o_current
->visibility
== INVISIBLE
&& !o_current
->show_hidden
) {
242 /* always display text which is 12 or larger */
243 factor
= (int) page
->to_world_x_constant
;
244 if ((factor
< w_current
->text_display_zoomfactor
) ||
245 o_current
->text
->size
>= 12 ||
246 w_current
->text_feedback
== ALWAYS
) {
247 o_list_draw_xor(w_current
, dx
, dy
, o_current
->text
->prim_objs
);
249 /* text is too small so go through and draw a line in
251 WORLDtoSCREEN(page
, o_current
->w_left
+ dx
, o_current
->w_bottom
+ dy
, &left
, &top
);
252 WORLDtoSCREEN(page
, o_current
->w_right
+ dx
, o_current
->w_top
+ dy
, &right
, &bottom
);
254 if (o_current
->saved_color
!= -1) {
255 color
= o_current
->saved_color
;
257 color
= o_current
->color
;
260 gdk_gc_set_foreground(w_current
->outline_xor_gc
,
261 x_get_darkcolor(color
));
263 gdk_draw_rectangle( w_current
->backingstore
,
264 w_current
->outline_xor_gc
,
273 void o_text_notice_changed(OBJECT
*subject
, GSCHEM_TOPLEVEL
*w_current
)
275 TOPLEVEL
*toplevel
= w_current
->toplevel
;
276 char const *string
= o_text_get_string(subject
);
278 /* erase old object */
279 o_erase_single(w_current
, subject
);
281 o_text_recreate(subject
);
282 o_text_draw(w_current
, subject
);
284 /* handle slot= attribute, it's a special case */
285 if (string
&& g_ascii_strncasecmp (string
, "slot=", 5) == 0) {
286 o_slot_end (w_current
, string
, strlen (string
));
289 if (subject
->attached_to
) {
292 owner
= subject
->attached_to
;
294 /* Another slotting special case. */
295 if (g_ascii_strncasecmp(string
, "slotname=", 9) == 0 ||
296 g_ascii_strncasecmp(string
, "slotowner=", 10) == 0) {
297 s_slot_reparent_from_attribs(toplevel
, owner
);
300 /* Rewrite symbols in slots, to pick up new values. */
301 if (owner
->type
== OBJ_COMPLEX
) {
302 s_slot_rewrite_symbols(owner
);
305 if (owner
->type
== OBJ_SLOT
&& owner
->slot
->owner
) {
306 s_slot_rewrite_symbols(owner
->slot
->owner
);
310 toplevel
->page_current
->CHANGED
= 1;
313 /*! \todo Finish function documentation!!!
315 * \par Function Description
318 void o_text_prepare_place(GSCHEM_TOPLEVEL
*w_current
, char *text
)
320 TOPLEVEL
*toplevel
= w_current
->toplevel
;
323 /* Insert the new object into the buffer at world coordinates (0,0).
324 * It will be translated to the mouse coordinates during placement. */
326 w_current
->first_wx
= 0;
327 w_current
->first_wy
= 0;
329 w_current
->last_drawb_mode
= LAST_DRAWB_MODE_NONE
;
331 new_text
= o_text_new(toplevel
, OBJ_TEXT
, w_current
->text_color
,
332 0, 0, LOWER_LEFT
, 0, /* zero is angle */
334 w_current
->text_size
,
335 /* has to be visible so you can place it */
336 /* visibility is set when you create the object */
337 VISIBLE
, SHOW_NAME_VALUE
);
339 s_page_replace_place_list(toplevel
, toplevel
->page_current
,
340 g_list_prepend(NULL
, new_text
));
342 w_current
->inside_action
= 1;
343 i_set_state(w_current
, DRAWTEXT
);
347 /*! \todo Finish function documentation!!!
349 * \par Function Description
352 void o_text_start (GSCHEM_TOPLEVEL
*w_current
, int w_x
, int w_y
)
354 o_place_start (w_current
, w_x
, w_y
);
358 /*! \todo Finish function documentation!!!
360 * \par Function Description
363 void o_text_edit(GSCHEM_TOPLEVEL
*w_current
, OBJECT
*o_current
)
365 /* you need to check to make sure only one object is selected */
366 /* no actually this is okay... not here in o_edit */
367 text_edit_dialog(w_current
, o_text_get_string(o_current
),
368 o_current
->text
->size
, o_current
->text
->alignment
);
371 /*! \todo Finish function documentation!!!
373 * \par Function Description
376 void o_text_edit_end(GSCHEM_TOPLEVEL
*w_current
, char *string
, int len
, int text_size
,
379 TOPLEVEL
*toplevel
= w_current
->toplevel
;
385 s_current
= geda_list_get_glist( toplevel
->page_current
->selection_list
);
386 numselect
= g_list_length( geda_list_get_glist( toplevel
->page_current
->selection_list
));
388 while(s_current
!= NULL
) {
389 object
= s_current
->data
;
392 if (object
->type
== OBJ_TEXT
) {
393 o_erase_single(w_current
, object
);
395 object
->text
->size
= text_size
;
396 object
->text
->alignment
= text_alignment
;
398 /* probably the text object should be extended to carry a color */
399 /* and we should pass it here with a function parameter (?) */
400 object
->saved_color
= w_current
->edit_color
;
402 /* only change text string if there is only ONE text object selected */
403 if (numselect
== 1 && string
) {
404 o_text_set_string(object
, string
);
405 /* handle slot= attribute, it's a special case */
406 if (g_ascii_strncasecmp (string
, "slot=", 5) == 0) {
407 o_slot_end (w_current
, string
, strlen (string
));
411 g_signal_emit_by_name(G_OBJECT(object
), "changed");
415 s_current
= g_list_next(s_current
);
418 toplevel
->page_current
->CHANGED
= 1;
419 o_undo_savestate(w_current
, UNDO_ALL
);
422 void o_text_notice_create(GSCHEM_TOPLEVEL
*w_current
, OBJECT
*o
)
424 g_signal_connect(o
, "changed", G_CALLBACK(o_text_notice_changed
), w_current
);