Updated copyright text/header in most source files.
[geda-gaf/peter-b.git] / gschem / src / a_pan.c
blob04c2db94831be77057aa2395bed6103ff02f29af
1 /* gEDA - GPL Electronic Design Automation
2 * gschem - gEDA Schematic Capture
3 * Copyright (C) 1998-2010 Ales Hvezda
4 * Copyright (C) 1998-2010 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
20 #include <config.h>
22 #include <stdio.h>
23 #include <math.h>
25 #include "gschem.h"
27 #ifdef HAVE_LIBDMALLOC
28 #include <dmalloc.h>
29 #endif
32 /*! \todo Finish function documentation!!!
33 * \brief
34 * \par Function Description
37 void a_pan_general(GSCHEM_TOPLEVEL *w_current, double world_cx, double world_cy,
38 double relativ_zoom_factor,int flags)
40 TOPLEVEL *toplevel = w_current->toplevel;
41 /* see libgeda/include/defines.h for flags */
42 /*if the borders should be ignored always, remove, outcomment or changes
43 the flags in the function-calls*/
44 /* flags |= A_PAN_IGNORE_BORDERS;
45 */
46 /* think it's better that the zoomfactor is defined as pix/mills
47 this will be the same as w_current->page_current->to_screen_x/y_constant*/
48 int zoom_max = 5;
49 int diff;
50 double zx, zy, zoom_old, zoom_new, zoom_min;
52 #if DEBUG
53 printf("a_pan_general(): world_cx=%f, world_cy=%f\n",world_cx, world_cy);
54 #endif
56 /* calc minimum zoomfactors and choose the smaller one. They are equal
57 if the aspectratio of the world is the same as the screen ratio */
58 zx = (double) toplevel->width / (toplevel->init_right -
59 toplevel->init_left);
60 zy = (double) toplevel->height / (toplevel->init_bottom -
61 toplevel->init_top);
62 zoom_min = zx < zy ? zx : zy;
64 #if DEBUG
65 printf(" zx_min=%f, zy_min=%f , flags=%d\n ",zx, zy, flags);
66 #endif
68 /* to_screen_x_constant and to_screen_y_constant are almost the same.
69 lets use to_screen_y_constant */
70 zoom_old = toplevel->page_current->to_screen_y_constant;
72 /* calc new zooming factor */
73 /* check if there's a zoom_full (relativ_zoom_factor == -1) */
74 if (relativ_zoom_factor <0) {
75 zoom_new = zoom_min;
77 else {
78 zoom_new = zoom_old * relativ_zoom_factor;
79 zoom_new = zoom_new > zoom_max ? zoom_max : zoom_new;
80 if (!(flags & A_PAN_IGNORE_BORDERS)) {
81 zoom_new = zoom_new < zoom_min ? zoom_min : zoom_new;
85 /* calculate the new visible area; adding 0.5 to round */
86 toplevel->page_current->left = world_cx - (double) toplevel->width
87 / 2 / zoom_new + 0.5;
88 toplevel->page_current->right = world_cx + (double) toplevel->width
89 / 2 / zoom_new + 0.5;
90 toplevel->page_current->top = world_cy - (double) toplevel->height
91 / 2 / zoom_new + 0.5;
92 toplevel->page_current->bottom = world_cy + (double) toplevel->height
93 / 2 / zoom_new + 0.5;
95 /* and put it back to the borders */
96 if (!(flags & A_PAN_IGNORE_BORDERS)) {
97 /* check right border */
98 if (toplevel->page_current->right > toplevel->init_right) {
99 toplevel->page_current->left += toplevel->init_right -
100 toplevel->page_current->right;
101 toplevel->page_current->right = toplevel->init_right;
103 /* check left border */
104 if (toplevel->page_current->left < toplevel->init_left) {
105 toplevel->page_current->right += toplevel->init_left -
106 toplevel->page_current->left;
107 toplevel->page_current->left = toplevel->init_left;
110 /* If there is any slack, center the view */
111 diff = (toplevel->page_current->right -
112 toplevel->page_current->left) -
113 (toplevel->init_right - toplevel->init_left);
114 if (diff > 0) {
115 toplevel->page_current->left -= diff / 2;
116 toplevel->page_current->right -= diff / 2;
119 /* check bottom border */
120 if (toplevel->page_current->bottom > toplevel->init_bottom) {
121 toplevel->page_current->top += toplevel->init_bottom -
122 toplevel->page_current->bottom;
123 toplevel->page_current->bottom = toplevel->init_bottom;
125 /* check top border */
126 if (toplevel->page_current->top < toplevel->init_top) {
127 toplevel->page_current->bottom += toplevel->init_top -
128 toplevel->page_current->top;
129 toplevel->page_current->top = toplevel->init_top;
132 /* If there is any slack, center the view */
133 diff = (toplevel->page_current->bottom -
134 toplevel->page_current->top) -
135 (toplevel->init_bottom - toplevel->init_top);
136 if (diff > 0) {
137 toplevel->page_current->top -= diff / 2;
138 toplevel->page_current->bottom -= diff / 2;
143 #if DEBUG
144 printf("zoom_old: %f, zoom_new: %f \n ",zoom_old, zoom_new);
145 printf("left: %d, right: %d, top: %d, bottom: %d\n",
146 w_current->page_current->left, w_current->page_current->right,
147 w_current->page_current->top, w_current->page_current->bottom);
148 printf("aspect: %f\n",
149 (float) fabs(w_current->page_current->right
150 - w_current->page_current->left) /
151 (float) fabs(w_current->page_current->bottom
152 - w_current->page_current->top ));
153 #endif
155 /* set_window */
156 set_window(toplevel, toplevel->page_current,
157 toplevel->page_current->left ,
158 toplevel->page_current->right ,
159 toplevel->page_current->top ,
160 toplevel->page_current->bottom);
162 i_update_grid_info (w_current);
164 /* redraw */
165 if (!(flags & A_PAN_DONT_REDRAW)) {
166 x_scrollbars_update(w_current);
167 o_invalidate_all (w_current);
171 /*! \todo Finish function documentation!!!
172 * \brief
173 * \par Function Description
175 void a_pan(GSCHEM_TOPLEVEL *w_current, int w_x, int w_y)
177 /* make mouse to the new world-center;
178 attention: there are information looses because of type cast in mil_x */
180 a_pan_general(w_current, w_x, w_y, 1, 0);
182 /*! \bug FIXME? This call will trigger a motion event (x_event_motion()),
183 * even if the user doesn't move the mouse
184 * Not ready for prime time, maybe there is another way to trigger the
185 * motion event without changing the cursor position (Werner)
187 /* x_basic_warp_cursor(w_current->drawing_area, x, y); */
190 /*! \todo Finish function documentation!!!
191 * \brief
192 * \par Function Description
195 void a_pan_mouse(GSCHEM_TOPLEVEL *w_current, int diff_x, int diff_y)
197 TOPLEVEL *toplevel = w_current->toplevel;
198 double world_cx, world_cy;
199 double page_cx, page_cy;
201 #if DEBUG
202 printf("a_pan_mouse(): diff_x=%d, diff_y=%d\n", diff_x, diff_y);
203 #endif
205 page_cx = (toplevel->page_current->left + toplevel->page_current->right) / 2.0;
206 page_cy = (toplevel->page_current->top + toplevel->page_current->bottom) / 2.0;
208 world_cx = page_cx - WORLDabs (w_current, diff_x);
209 world_cy = page_cy + WORLDabs (w_current, diff_y);
211 #if DEBUG
212 printf(" world_cx=%f, world_cy=%f, world_dx=%d, world_dy=%d\n",
213 world_cx, world_cy, world_dx, world_dy);
214 #endif
216 a_pan_general(w_current, world_cx, world_cy, 1, 0);