1 /*
2 * FIG : Facility for Interactive Generation of figures
3 * Copyright (c) 1991 by Henning Spruth
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 <X11/keysym.h>
19 #include "fig.h"
20 #include "resources.h"
21 #include "mode.h"
22 #include "object.h"
23 #include "paintop.h"
24 #include "u_create.h"
25 #include "u_elastic.h"
26 #include "u_pan.h"
27 #include "w_canvas.h"
28 #include "w_file.h"
29 #include "w_indpanel.h"
30 #include "w_msgpanel.h"
31 #include "w_setup.h"
32 #include "w_util.h"
33 #include "w_zoom.h"
34
35 #include "w_cursor.h"
36
37 /* global for w_canvas.c */
38
39 Boolean zoom_in_progress = False;
40
41 static void do_zoom(int x, int y), cancel_zoom(void);
42 static void init_zoombox_drawing(int x, int y);
43
44 static void (*save_kbd_proc) ();
45 static void (*save_locmove_proc) ();
46 static void (*save_ref_proc) ();
47 static void (*save_leftbut_proc) ();
48 static void (*save_middlebut_proc) ();
49 static void (*save_rightbut_proc) ();
50 static int save_cur_mode;
51
52 float display_zoomscale; /* both zoomscales initialized in main() */
53 float zoomscale;
54 int zoomxoff = 0;
55 int zoomyoff = 0;
56 Boolean integral_zoom = False; /* integral zoom flag for area zoom (mouse) */
57
58 /* used for private box drawing functions */
59 static int my_fix_x, my_fix_y;
60 static int my_cur_x, my_cur_y;
61
62
63
64 void
zoom_selected(int x,int y,unsigned int button)65 zoom_selected(int x, int y, unsigned int button)
66 {
67 /* if trying to zoom while drawing an object, don't allow it */
68 if ((button != Button2) && check_action_on()) /* panning is ok */
69 return;
70 /* don't allow zooming while previewing */
71 if (preview_in_progress)
72 return;
73
74 if (!zoom_in_progress) {
75 switch (button) {
76 case Button1:
77 set_temp_cursor(magnify_cursor);
78 init_zoombox_drawing(x, y);
79 break;
80 case Button2:
81 pan_origin();
82 break;
83 case Button3:
84 unzoom();
85 break;
86 case Button4:
87 wheel_inc_zoom();
88 break;
89 case Button5:
90 wheel_dec_zoom();
91 break;
92 }
93 } else if (button == Button1) {
94 reset_cursor();
95 do_zoom(x, y);
96 }
97 }
98
99 void
unzoom(void)100 unzoom(void)
101 {
102 display_zoomscale = 1.0;
103 show_zoom(&ind_switches[ZOOM_SWITCH_INDEX]);
104 }
105
106 static void
my_box(int x,int y)107 my_box(int x, int y)
108 {
109 elastic_box(my_fix_x, my_fix_y, my_cur_x, my_cur_y);
110 my_cur_x = x;
111 my_cur_y = y;
112 elastic_box(my_fix_x, my_fix_y, my_cur_x, my_cur_y);
113 }
114
115 static void
elastic_mybox(void)116 elastic_mybox(void)
117 {
118 elastic_box(my_fix_x, my_fix_y, my_cur_x, my_cur_y);
119 }
120
121 static void
init_zoombox_drawing(int x,int y)122 init_zoombox_drawing(int x, int y)
123 {
124 if (check_action_on())
125 return;
126 save_kbd_proc = canvas_kbd_proc;
127 save_locmove_proc = canvas_locmove_proc;
128 save_ref_proc = canvas_ref_proc;
129 save_leftbut_proc = canvas_leftbut_proc;
130 save_middlebut_proc = canvas_middlebut_proc;
131 save_rightbut_proc = canvas_rightbut_proc;
132
133 my_cur_x = my_fix_x = x;
134 my_cur_y = my_fix_y = y;
135
136 canvas_locmove_proc = my_box;
137 canvas_ref_proc = elastic_mybox;
138 canvas_leftbut_proc = do_zoom;
139 canvas_middlebut_proc = canvas_rightbut_proc = null_proc;
140 canvas_rightbut_proc = cancel_zoom;
141 elastic_box(my_fix_x, my_fix_y, my_cur_x, my_cur_y);
142 set_action_on();
143 save_cur_mode=cur_mode;
144 cur_mode = F_ZOOM;
145 zoom_in_progress = True;
146 }
147
148 static void
do_zoom(int x,int y)149 do_zoom(int x, int y)
150 {
151 int dimx, dimy;
152 float scalex, scaley;
153
154 /* don't allow zooming while previewing */
155 if (preview_in_progress)
156 return;
157 elastic_box(my_fix_x, my_fix_y, my_cur_x, my_cur_y);
158 zoomxoff = my_fix_x < x ? my_fix_x : x;
159 zoomyoff = my_fix_y < y ? my_fix_y : y;
160 dimx = abs(x - my_fix_x);
161 dimy = abs(y - my_fix_y);
162 if (!appres.allownegcoords) {
163 if (zoomxoff < 0)
164 zoomxoff = 0;
165 if (zoomyoff < 0)
166 zoomyoff = 0;
167 }
168 if (dimx && dimy) {
169 scalex = ZOOM_FACTOR * CANVAS_WD / (float) dimx;
170 scaley = ZOOM_FACTOR * CANVAS_HT / (float) dimy;
171
172 display_zoomscale = (scalex > scaley ? scaley : scalex);
173 if (display_zoomscale <= 1.0) /* keep to 0.1 increments */
174 display_zoomscale = (int)((display_zoomscale+0.09)*10.0)/10.0 - 0.1;
175
176 /* round if integral zoom is on (indicator panel in zoom popup) */
177 if (integral_zoom && display_zoomscale > 1.0)
178 display_zoomscale = round(display_zoomscale);
179 show_zoom(&ind_switches[ZOOM_SWITCH_INDEX]);
180 }
181 /* restore state */
182 canvas_kbd_proc = save_kbd_proc;
183 canvas_locmove_proc = save_locmove_proc;
184 canvas_ref_proc = save_ref_proc;
185 canvas_leftbut_proc = save_leftbut_proc;
186 canvas_middlebut_proc = save_middlebut_proc;
187 canvas_rightbut_proc = save_rightbut_proc;
188 cur_mode=save_cur_mode;
189 reset_action_on();
190 zoom_in_progress = False;
191 }
192
193 static void
cancel_zoom(void)194 cancel_zoom(void)
195 {
196 elastic_box(my_fix_x, my_fix_y, my_cur_x, my_cur_y);
197 /* restore state */
198 canvas_kbd_proc = save_kbd_proc;
199 canvas_locmove_proc = save_locmove_proc;
200 canvas_ref_proc = save_ref_proc;
201 canvas_leftbut_proc = save_leftbut_proc;
202 canvas_middlebut_proc = save_middlebut_proc;
203 canvas_rightbut_proc = save_rightbut_proc;
204 cur_mode=save_cur_mode;
205 reset_cursor();
206 reset_action_on();
207 zoom_in_progress = False;
208 }
209