1 /*
2 * FIG : Facility for Interactive Generation of figures
3 * Copyright (c) 1985-1988 by Supoj Sutanthavibul
4 * Parts Copyright (c) 1989-2015 by Brian V. Smith
5 * Parts Copyright (c) 1991 by Paul King
6 * Parts Copyright (c) 2016-2020 by Thomas Loimer
7 *
8 * Any party obtaining a copy of these files is granted, free of charge, a
9 * full and unrestricted irrevocable, world-wide, paid up, royalty-free,
10 * nonexclusive right and license to deal in this software and documentation
11 * files (the "Software"), including without limitation the rights to use,
12 * copy, modify, merge, publish, distribute, sublicense and/or sell copies of
13 * the Software, and to permit persons who receive copies from any such
14 * party to do so, with the only requirement being that the above copyright
15 * and this permission notice remain intact.
16 *
17 */
18
19 #include "e_arrow.h"
20
21 #include <stdlib.h>
22
23 #include "resources.h"
24 #include "mode.h"
25 #include "object.h"
26 #include "paintop.h"
27 #include "u_create.h"
28 #include "u_draw.h"
29 #include "u_redraw.h"
30 #include "u_search.h"
31 #include "u_undo.h"
32 #include "w_canvas.h"
33 #include "w_cursor.h"
34 #include "w_mousefun.h"
35
36
37 static void add_arrow_head(F_line *obj, int type, int x, int y,
38 F_point *p, F_point *q, int pnum);
39 static void delete_arrow_head(F_line *obj, int type, int x, int y,
40 F_point *p, F_point *q, int pnum);
41 static void add_linearrow(F_line *line, F_point *prev_point,
42 F_point *selected_point);
43 static void add_arcarrow(F_arc *arc, int point_num);
44 static void add_splinearrow(F_spline *spline, F_point *prev_point,
45 F_point *selected_point);
46
47
48
49 void
arrow_head_selected(void)50 arrow_head_selected(void)
51 {
52 set_mousefun("add arrow", "delete arrow", "", LOC_OBJ, LOC_OBJ, LOC_OBJ);
53 canvas_kbd_proc = null_proc;
54 canvas_locmove_proc = null_proc;
55 canvas_ref_proc = null_proc;
56 init_searchproc_left(add_arrow_head);
57 init_searchproc_middle(delete_arrow_head);
58 canvas_leftbut_proc = point_search_left;
59 canvas_middlebut_proc = point_search_middle;
60 canvas_rightbut_proc = null_proc;
61 set_cursor(pick9_cursor);
62 reset_action_on();
63 }
64
65 static void
add_arrow_head(F_line * obj,int type,int x,int y,F_point * p,F_point * q,int pnum)66 add_arrow_head(F_line *obj, int type, int x, int y, F_point *p, F_point *q,
67 int pnum)
68 {
69 (void)x;
70 (void)y;
71
72 switch (type) {
73 case O_POLYLINE:
74 cur_l = (F_line *) obj;
75 add_linearrow(cur_l, p, q);
76 break;
77 case O_SPLINE:
78 cur_s = (F_spline *) obj;
79 add_splinearrow(cur_s, p, q);
80 break;
81 case O_ARC:
82 cur_a = (F_arc *) obj;
83 add_arcarrow(cur_a, pnum);
84 break;
85 }
86 }
87
88 static void
delete_arrow_head(F_line * obj,int type,int x,int y,F_point * p,F_point * q,int pnum)89 delete_arrow_head(F_line *obj, int type, int x, int y, F_point *p, F_point *q,
90 int pnum)
91 {
92 (void)x;
93 (void)y;
94
95 switch (type) {
96 case O_POLYLINE:
97 cur_l = (F_line *) obj;
98 delete_linearrow(cur_l, p, q);
99 break;
100 case O_SPLINE:
101 cur_s = (F_spline *) obj;
102 delete_splinearrow(cur_s, p, q);
103 break;
104 case O_ARC:
105 cur_a = (F_arc *) obj;
106 delete_arcarrow(cur_a, pnum);
107 break;
108 }
109 }
110
111 static void
add_linearrow(F_line * line,F_point * prev_point,F_point * selected_point)112 add_linearrow(F_line *line, F_point *prev_point, F_point *selected_point)
113 {
114 if (line->points->next == NULL)
115 return; /* A single point line */
116
117 if (prev_point == NULL) { /* selected_point is the first point */
118 if (line->back_arrow)
119 return;
120 line->back_arrow = backward_arrow();
121 redisplay_line(line);
122 } else if (selected_point->next == NULL) { /* forward arrow */
123 if (line->for_arrow)
124 return;
125 line->for_arrow = forward_arrow();
126 redisplay_line(line);
127 } else
128 return;
129 clean_up();
130 set_last_prevpoint(prev_point);
131 set_last_selectedpoint(selected_point);
132 set_latestline(line);
133 set_action_object(F_ADD_ARROW_HEAD, O_POLYLINE);
134 set_modifiedflag();
135 }
136
137 static void
add_arcarrow(F_arc * arc,int point_num)138 add_arcarrow(F_arc *arc, int point_num)
139 {
140
141 /* only allow arrowheads on open arc */
142 if (arc->type == T_PIE_WEDGE_ARC)
143 return;
144 if (point_num == 0) { /* backward arrow */
145 if (arc->back_arrow)
146 return;
147 arc->back_arrow = backward_arrow();
148 redisplay_arc(arc);
149 } else if (point_num == 2) {/* for_arrow */
150 if (arc->for_arrow)
151 return;
152 arc->for_arrow = forward_arrow();
153 redisplay_arc(arc);
154 } else
155 return;
156 clean_up();
157 set_last_arcpointnum(point_num);
158 set_latestarc(arc);
159 set_action_object(F_ADD_ARROW_HEAD, O_ARC);
160 set_modifiedflag();
161 }
162
163 static void
add_splinearrow(F_spline * spline,F_point * prev_point,F_point * selected_point)164 add_splinearrow(F_spline *spline, F_point *prev_point, F_point *selected_point)
165 {
166 if (prev_point == NULL) { /* add backward arrow */
167 if (spline->back_arrow)
168 return;
169 spline->back_arrow = backward_arrow();
170 redisplay_spline(spline);
171 } else if (selected_point->next == NULL) { /* add forward arrow */
172 if (spline->for_arrow)
173 return;
174 spline->for_arrow = forward_arrow();
175 redisplay_spline(spline);
176 }
177 clean_up();
178 set_last_prevpoint(prev_point);
179 set_last_selectedpoint(selected_point);
180 set_latestspline(spline);
181 set_action_object(F_ADD_ARROW_HEAD, O_SPLINE);
182 set_modifiedflag();
183 }
184
185 void
delete_linearrow(F_line * line,F_point * prev_point,F_point * selected_point)186 delete_linearrow(F_line *line, F_point *prev_point, F_point *selected_point)
187 {
188 if (line->points->next == NULL)
189 return; /* A single point line */
190
191 if (prev_point == NULL) { /* selected_point is the first point */
192 if (!line->back_arrow)
193 return;
194 draw_line(line, ERASE);
195 saved_back_arrow=line->back_arrow;
196 if (saved_for_arrow && saved_for_arrow != line->for_arrow)
197 free((char *) saved_for_arrow);
198 saved_for_arrow = NULL;
199 line->back_arrow = NULL;
200 redisplay_line(line);
201 } else if (selected_point->next == NULL) { /* forward arrow */
202 if (!line->for_arrow)
203 return;
204 draw_line(line, ERASE);
205 saved_for_arrow=line->for_arrow;
206 if (saved_back_arrow && saved_back_arrow != line->back_arrow)
207 free((char *) saved_back_arrow);
208 saved_back_arrow = NULL;
209 line->for_arrow = NULL;
210 redisplay_line(line);
211 } else
212 return;
213 clean_up();
214 set_last_prevpoint(prev_point);
215 set_last_selectedpoint(selected_point);
216 set_latestline(line);
217 set_action_object(F_DELETE_ARROW_HEAD, O_POLYLINE);
218 set_modifiedflag();
219 }
220
221 void
delete_arcarrow(F_arc * arc,int point_num)222 delete_arcarrow(F_arc *arc, int point_num)
223 {
224 if (arc->type == T_PIE_WEDGE_ARC)
225 return;;
226 if (point_num == 0) { /* backward arrow */
227 if (!arc->back_arrow)
228 return;
229 draw_arc(arc, ERASE);
230 saved_back_arrow=arc->back_arrow;
231 if (saved_for_arrow && saved_for_arrow != arc->for_arrow)
232 free((char *) saved_for_arrow);
233 saved_for_arrow = NULL;
234 arc->back_arrow = NULL;
235 redisplay_arc(arc);
236 } else if (point_num == 2) {/* for_arrow */
237 if (!arc->for_arrow)
238 return;
239 draw_arc(arc, ERASE);
240 saved_for_arrow=arc->for_arrow;
241 if (saved_back_arrow && saved_back_arrow != arc->back_arrow)
242 free((char *) saved_back_arrow);
243 saved_back_arrow = NULL;
244 arc->for_arrow = NULL;
245 redisplay_arc(arc);
246 } else
247 return;
248 clean_up();
249 set_last_arcpointnum(point_num);
250 set_latestarc(arc);
251 set_action_object(F_DELETE_ARROW_HEAD, O_ARC);
252 set_modifiedflag();
253 }
254
255 void
delete_splinearrow(F_spline * spline,F_point * prev_point,F_point * selected_point)256 delete_splinearrow(F_spline *spline, F_point *prev_point, F_point *selected_point)
257 {
258 if (closed_spline(spline))
259 return;
260 if (prev_point == NULL) { /* selected_point is the first point */
261 if (!spline->back_arrow)
262 return;
263 draw_spline(spline, ERASE);
264 saved_back_arrow=spline->back_arrow;
265 if (saved_for_arrow && saved_for_arrow != spline->for_arrow)
266 free((char *) saved_for_arrow);
267 saved_for_arrow = NULL;
268 spline->back_arrow = NULL;
269 redisplay_spline(spline);
270 } else if (selected_point->next == NULL) { /* forward arrow */
271 if (!spline->for_arrow)
272 return;
273 draw_spline(spline, ERASE);
274 saved_for_arrow=spline->for_arrow;
275 if (saved_back_arrow && saved_back_arrow != spline->back_arrow)
276 free((char *) saved_back_arrow);
277 saved_back_arrow = NULL;
278 spline->for_arrow = NULL;
279 redisplay_spline(spline);
280 } else
281 return;
282 clean_up();
283 set_last_prevpoint(prev_point);
284 set_last_selectedpoint(selected_point);
285 set_latestspline(spline);
286 set_action_object(F_DELETE_ARROW_HEAD, O_SPLINE);
287 set_modifiedflag();
288 }
289
290
291
292
293
294