1 /*
2 * FIG : Facility for Interactive Generation of figures
3 * Copyright (c) 1985-1988 by Supoj Sutanthavibul
4 * Parts Copyright (c) 1989-2007 by Brian V. Smith
5 * Parts Copyright (c) 1991 by Paul King
6 *
7 * Any party obtaining a copy of these files is granted, free of charge, a
8 * full and unrestricted irrevocable, world-wide, paid up, royalty-free,
9 * nonexclusive right and license to deal in this software and documentation
10 * files (the "Software"), including without limitation the rights to use,
11 * copy, modify, merge, publish, distribute, sublicense and/or sell copies of
12 * the Software, and to permit persons who receive copies from any such
13 * party to do so, with the only requirement being that the above copyright
14 * and this permission notice remain intact.
15 *
16 */
17
18 #include "e_placelib.h"
19
20 #include <string.h>
21 #include <X11/Intrinsic.h> /* includes X11/Xlib.h, which includes X11/X.h */
22
23 #include "resources.h"
24 #include "mode.h"
25 #include "object.h"
26 #include "paintop.h"
27
28 #include "e_edit.h"
29 #include "e_flip.h"
30 #include "e_rotate.h"
31 #include "e_scale.h"
32 #include "u_create.h"
33 #include "u_elastic.h"
34 #include "u_list.h"
35 #include "u_redraw.h"
36 #include "u_translate.h"
37 #include "u_undo.h"
38 #include "w_canvas.h"
39 #include "w_cursor.h"
40 #include "w_drawprim.h" /* for max_char_height */
41 #include "w_library.h"
42 #include "w_modepanel.h"
43 #include "w_mousefun.h"
44 #include "w_msgpanel.h"
45 #include "w_util.h"
46
47
48 /* EXPORTS */
49
50 int cur_library_object = -1;
51 int old_library_object = -1;
52
53 /* LOCAL */
54
55 static Boolean draw_box = False;
56 static int off_library_x;
57 static int off_library_y;
58
59 static void init_move_object(int x, int y);
60 static void move_object(int x, int y);
61 static void change_draw_mode(int x, int y);
62 static void transform_lib_obj(XKeyEvent *kpe, unsigned char c,KeySym keysym);
63 static void place_lib_object(int x, int y, unsigned int shift);
64 static void put_draw(int paint_mode);
65 static void sel_place_lib_obj_proc(int x, int y, int shift);
66 static int orig_put_x, orig_put_y;
67
68
69 void
put_selected(void)70 put_selected(void)
71 {
72 int i, x,y;
73 char *com;
74
75 set_mousefun("place object","new object","cancel library",
76 "place and edit","change draw mode", "place at orig posn");
77 set_action_on();
78 cur_c = lib_compounds[cur_library_object]->compound;
79 new_c = copy_compound(cur_c);
80 /* add it to the depths so it is displayed */
81 add_compound_depth(new_c);
82 /* find lower-right corner for draw_box() */
83 off_library_x = new_c->secorner.x;
84 off_library_y = new_c->secorner.y;
85 /* and upper-left in case the user wants to place it at its original position */
86 /* this is saved here because the compound was shifted to 0,0 when reading in */
87 orig_put_x = lib_compounds[cur_library_object]->corner.x;
88 orig_put_y = lib_compounds[cur_library_object]->corner.y;
89
90 canvas_locmove_proc = init_move_object;
91 canvas_ref_proc = null_proc;
92 canvas_leftbut_proc = place_lib_object;
93 canvas_middlebut_proc = sel_place_lib_obj_proc;
94 canvas_rightbut_proc = cancel_place_lib_obj;
95 set_cursor(null_cursor);
96
97 /* get the pointer position */
98 get_pointer_win_xy(&x, &y);
99 /* draw the first image */
100 init_move_object(BACKX(x), BACKY(y));
101
102 /* message that we're placing object so and so */
103 com = strdup(lib_compounds[cur_library_object]->compound->comments);
104 if (strlen(com)) {
105 /* change newlines to blanks */
106 for (i=strlen(com); i>=0; i--)
107 if (com[i] == '\n')
108 com[i] = ' ';
109 put_msg("Placing library object \"%s\" (%s.fig)",
110 com, library_objects_texts[cur_library_object]);
111 } else {
112 put_msg("Placing library object %s.fig", library_objects_texts[cur_library_object]);
113 }
114 }
115
116 /* allow rotation or flipping of library object before placing on canvas */
117
118 static void
transform_lib_obj(XKeyEvent * kpe,unsigned char c,KeySym keysym)119 transform_lib_obj(XKeyEvent *kpe, unsigned char c, KeySym keysym)
120 {
121 (void)kpe;
122 (void)keysym;
123 int x,y;
124
125 x = cur_x;
126 y = cur_y;
127
128 /* first erase the existing image */
129 put_draw(ERASE);
130 if (c == 'r') {
131 rotn_dirn = 1;
132 act_rotnangle = 90;
133 rotate_compound(new_c, x, y);
134 } else if (c == 'l') {
135 rotn_dirn = -1;
136 act_rotnangle = 90;
137 rotate_compound(new_c, x, y);
138 } else if (c == 'h') {
139 flip_compound(new_c, x, y, LR_FLIP);
140 } else if (c == 'v') {
141 flip_compound(new_c, x, y, UD_FLIP);
142 } else if (c == 's') {
143 scale_compound(new_c, 0.9, 0.9, x, y);
144 } else if (c == 'S') {
145 scale_compound(new_c, 1.1, 1.1, x, y);
146 } /* if not any of the above characters, ignore it */
147 /* and draw the new image */
148 put_draw(PAINT);
149 }
150
151 static void
sel_place_lib_obj_proc(int x,int y,int shift)152 sel_place_lib_obj_proc(int x, int y, int shift)
153 {
154 /* if shift-left button, change drawing mode */
155 if (shift) {
156 change_draw_mode(x, y);
157 return;
158 }
159 /* else popup the library panel again */
160 sel_place_lib_obj();
161 }
162
163 void
sel_place_lib_obj(void)164 sel_place_lib_obj(void)
165 {
166 canvas_kbd_proc = (void (*)())transform_lib_obj;
167 canvas_locmove_proc = null_proc;
168 canvas_ref_proc = null_proc;
169 canvas_leftbut_proc = null_proc;
170 canvas_middlebut_proc = null_proc;
171 canvas_rightbut_proc = null_proc;
172
173 /* erase any object currently being dragged around the canvas */
174 if (lib_compounds && action_on && new_c)
175 put_draw(ERASE);
176 popup_library_panel();
177 }
178
179 static void
put_draw(int paint_mode)180 put_draw(int paint_mode)
181 {
182 register int x1, y1, x2, y2;
183
184 if (draw_box) {
185 x1=cur_x;
186 y1=cur_y;
187 x2=cur_x+off_library_x;
188 y2=cur_y+off_library_y;
189 elastic_box(x1, y1, x2, y2);
190 } else {
191 if (paint_mode==ERASE)
192 redisplay_compound(new_c);
193 else
194 redisplay_objects(new_c);
195 }
196 }
197
198 static void
change_draw_mode(int x,int y)199 change_draw_mode(int x, int y)
200 {
201 (void)x;
202 (void)y;
203
204 put_draw(ERASE);
205 draw_box = !draw_box;
206 translate_compound(new_c,-new_c->nwcorner.x,-new_c->nwcorner.y);
207 if (!draw_box)
208 translate_compound(new_c,cur_x,cur_y);
209
210 put_draw(PAINT);
211 }
212
213 /* place library object at original position in its file */
214
215 static void
place_lib_object_orig(int x,int y,unsigned int shift)216 place_lib_object_orig(int x, int y, unsigned int shift)
217 {
218 (void)x;
219 (void)y;
220 (void)shift;
221 int dx,dy;
222
223 canvas_ref_proc = null_proc;
224 put_draw(ERASE);
225 clean_up();
226 /* move back to original position */
227 dx = orig_put_x-x;
228 dy = orig_put_y-y;
229 translate_compound(new_c,dx,dy);
230 /* remove it from the depths because it will be added when it is put in the main list */
231 remove_compound_depth(new_c);
232 add_compound(new_c);
233 set_modifiedflag();
234 redisplay_compound(new_c);
235 put_selected();
236 }
237
238 static void
place_lib_object(int x,int y,unsigned int shift)239 place_lib_object(int x, int y, unsigned int shift)
240 {
241 (void)x;
242 (void)y;
243 F_compound *this_c;
244
245 canvas_leftbut_proc = null_proc;
246 canvas_middlebut_proc = null_proc;
247 canvas_rightbut_proc = null_proc;
248 canvas_locmove_proc = null_proc;
249 canvas_ref_proc = null_proc;
250 put_draw(ERASE);
251 clean_up();
252 if (draw_box)
253 translate_compound(new_c,cur_x,cur_y);
254 /* remove it from the depths because it will be added when it is put in the main list */
255 remove_compound_depth(new_c);
256 add_compound(new_c);
257 set_modifiedflag();
258 redisplay_compound(new_c);
259 if (shift) {
260 /* temporarily turn off library place mode so we can edit the object just placed */
261 canvas_kbd_proc = null_proc;
262 clear_mousefun();
263 set_mousefun("","","", "", "", "");
264 turn_off_current();
265 set_cursor(arrow_cursor);
266 edit_remember_lib_mode = True;
267 this_c = new_c;
268 edit_item(this_c, O_COMPOUND, 0, 0);
269 } else {
270 put_selected();
271 }
272 }
273
274
275 static void
move_object(int x,int y)276 move_object(int x, int y)
277 {
278 int dx,dy;
279 void (*save_canvas_locmove_proc) ();
280 void (*save_canvas_ref_proc) ();
281
282 save_canvas_locmove_proc = canvas_locmove_proc;
283 save_canvas_ref_proc = canvas_ref_proc;
284 /* so we don't recurse infinitely */
285 canvas_locmove_proc = null_proc;
286 canvas_ref_proc = null_proc;
287 put_draw(ERASE);
288 if (!draw_box) {
289 dx=x-cur_x;
290 dy=y-cur_y;
291 translate_compound(new_c,dx,dy);
292 }
293 cur_x=x;cur_y=y;
294 put_draw(PAINT);
295 canvas_locmove_proc = save_canvas_locmove_proc;
296 canvas_ref_proc = save_canvas_ref_proc;
297 }
298
299 static void
init_move_object(int x,int y)300 init_move_object(int x, int y)
301 {
302 cur_x=x;
303 cur_y=y;
304 if (!draw_box)
305 translate_compound(new_c,x,y);
306
307 put_draw(PAINT);
308 canvas_locmove_proc = move_object;
309 canvas_ref_proc = move_object;
310 }
311
312 /* cancel placing a library object */
313
314 void
cancel_place_lib_obj(int x,int y,int shift)315 cancel_place_lib_obj(int x, int y, int shift)
316 {
317 /* if shift right-button, actually do a place in original position */
318 if (shift) {
319 place_lib_object_orig(x, y, shift);
320 return;
321 }
322 reset_action_on();
323 canvas_leftbut_proc = null_proc;
324 canvas_middlebut_proc = null_proc;
325 canvas_rightbut_proc = null_proc;
326 canvas_locmove_proc = null_proc;
327 canvas_ref_proc = null_proc;
328 canvas_kbd_proc = null_proc;
329 clear_mousefun();
330 set_mousefun("","","", "", "", "");
331 turn_off_current();
332 set_cursor(arrow_cursor);
333 put_draw(ERASE);
334 /* remove it from the depths */
335 remove_compound_depth(new_c);
336 }
337
338