1 /* gEDA - GPL Electronic Design Automation
2 * gschem - gEDA Schematic Capture
3 * Copyright (C) 1998-2007 Ales Hvezda
4 * Copyright (C) 1998-2007 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
27 #ifdef HAVE_LIBDMALLOC
32 /*! \todo Finish function documentation!!!
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 PAGE
*page
= toplevel
->page_current
;
42 /* see libgeda/include/defines.h for flags */
43 /*if the borders should be ignored always, remove, outcomment or changes
44 the flags in the function-calls*/
45 /* flags |= A_PAN_IGNORE_BORDERS;
47 /* think it's better that the zoomfactor is defined as pix/mills
48 this will be the same as page->to_screen_x/y_constant */
51 double zx
, zy
, zoom_old
, zoom_new
, zoom_min
;
54 printf("a_pan_general(): world_cx=%f, world_cy=%f\n",world_cx
, world_cy
);
57 /* calc minimum zoomfactors and choose the smaller one. They are equal
58 if the aspectratio of the world is the same as the screen ratio */
59 zx
= (double) page
->width
/ (toplevel
->init_right
- toplevel
->init_left
);
60 zy
= (double) page
->height
/ (toplevel
->init_bottom
- toplevel
->init_top
);
61 zoom_min
= zx
< zy
? zx
: zy
;
64 printf(" zx_min=%f, zy_min=%f , flags=%d\n ",zx
, zy
, flags
);
67 /* to_screen_x_constant and to_screen_y_constant are almost the same.
68 lets use to_screen_y_constant */
69 zoom_old
= page
->to_screen_y_constant
;
71 /* calc new zooming factor */
72 /* check if there's a zoom_full (relativ_zoom_factor == -1) */
73 if (relativ_zoom_factor
<0) {
77 zoom_new
= zoom_old
* relativ_zoom_factor
;
78 zoom_new
= zoom_new
> zoom_max
? zoom_max
: zoom_new
;
79 if (!(flags
& A_PAN_IGNORE_BORDERS
)) {
80 zoom_new
= zoom_new
< zoom_min
? zoom_min
: zoom_new
;
84 /* calculate the new visible area; adding 0.5 to round */
85 page
->left
= world_cx
- (double) page
->width
/ 2 / zoom_new
+ 0.5;
86 page
->right
= world_cx
+ (double) page
->width
/ 2 / zoom_new
+ 0.5;
87 page
->top
= world_cy
- (double) page
->height
/ 2 / zoom_new
+ 0.5;
88 page
->bottom
= world_cy
+ (double) page
->height
/ 2 / zoom_new
+ 0.5;
90 /* and put it back to the borders */
91 if (!(flags
& A_PAN_IGNORE_BORDERS
)) {
92 /* check right border */
93 if (page
->right
> toplevel
->init_right
) {
94 page
->left
+= toplevel
->init_right
- page
->right
;
95 page
->right
= toplevel
->init_right
;
97 /* check left border */
98 if (page
->left
< toplevel
->init_left
) {
99 page
->right
+= toplevel
->init_left
- page
->left
;
100 page
->left
= toplevel
->init_left
;
103 /* If there is any slack, center the view */
104 diff
= (page
->right
- page
->left
) -
105 (toplevel
->init_right
- toplevel
->init_left
);
107 page
->left
-= diff
/ 2;
108 page
->right
-= diff
/ 2;
111 /* check bottom border */
112 if (page
->bottom
> toplevel
->init_bottom
) {
113 page
->top
+= toplevel
->init_bottom
- page
->bottom
;
114 page
->bottom
= toplevel
->init_bottom
;
116 /* check top border */
117 if (page
->top
< toplevel
->init_top
) {
118 page
->bottom
+= toplevel
->init_top
- page
->top
;
119 page
->top
= toplevel
->init_top
;
122 /* If there is any slack, center the view */
123 diff
= (page
->bottom
- page
->top
) -
124 (toplevel
->init_bottom
- toplevel
->init_top
);
126 page
->top
-= diff
/ 2;
127 page
->bottom
-= diff
/ 2;
132 printf("zoom_old: %f, zoom_new: %f \n ",zoom_old
, zoom_new
);
133 printf("left: %d, right: %d, top: %d, bottom: %d\n",
134 page
->left
, page
->right
, page
->top
, page
->bottom
);
135 printf("aspect: %f\n",
136 (float) fabs(page
->right
- page
->left
) /
137 (float) fabs(page
->bottom
- page
->top
));
141 set_window(toplevel
, page
,
148 if (!(flags
& A_PAN_DONT_REDRAW
)) {
149 x_scrollbars_update(w_current
);
150 o_redraw_all(w_current
);
154 /*! \todo Finish function documentation!!!
156 * \par Function Description
158 void a_pan(GSCHEM_TOPLEVEL
*w_current
, int w_x
, int w_y
)
160 /* make mouse to the new world-center;
161 attention: there are information looses because of type cast in mil_x */
163 a_pan_general(w_current
, w_x
, w_y
, 1, 0);
165 /*! \bug FIXME? This call will trigger a motion event (x_event_motion()),
166 * even if the user doesn't move the mouse
167 * Not ready for prime time, maybe there is another way to trigger the
168 * motion event without changing the cursor position (Werner)
170 /* x_basic_warp_cursor(w_current->drawing_area, x, y); */
173 /*! \todo Finish function documentation!!!
175 * \par Function Description
178 void a_pan_mouse(GSCHEM_TOPLEVEL
*w_current
, int diff_x
, int diff_y
)
180 TOPLEVEL
*toplevel
= w_current
->toplevel
;
181 PAGE
*page
= toplevel
->page_current
;
182 double world_cx
, world_cy
;
183 double page_cx
, page_cy
;
186 printf("a_pan_mouse(): diff_x=%d, diff_y=%d\n", diff_x
, diff_y
);
189 page_cx
= (page
->left
+ page
->right
) / 2.0;
190 page_cy
= (page
->top
+ page
->bottom
) / 2.0;
192 world_cx
= page_cx
- WORLDabs(page
, diff_x
);
193 world_cy
= page_cy
+ WORLDabs(page
, diff_y
);
196 printf(" world_cx=%f, world_cy=%f, world_dx=%d, world_dy=%d\n",
197 world_cx
, world_cy
, world_dx
, world_dy
);
200 a_pan_general(w_current
, world_cx
, world_cy
, 1, 0);