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