Text samples
[dia.git] / app / magnify.c
blob26f1f40895902f43924282e153f2ae17a8b78cd3
1 /* Dia -- an diagram creation/manipulation program
2 * Copyright (C) 1998 Alexander Larsson
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
18 #include <config.h>
19 #include <stdlib.h>
20 #include <math.h>
22 #include "magnify.h"
23 #include "cursor.h"
25 static void
26 magnify_button_press(MagnifyTool *tool, GdkEventButton *event,
27 DDisplay *ddisp)
29 tool->x = tool->oldx = event->x;
30 tool->y = tool->oldy = event->y;
31 tool->box_active = TRUE;
32 tool->moved = FALSE;
33 gdk_pointer_grab (ddisp->canvas->window, FALSE,
34 GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON1_MOTION_MASK | GDK_BUTTON_RELEASE_MASK,
35 NULL, NULL, event->time);
38 static void
39 magnify_button_release(MagnifyTool *tool, GdkEventButton *event,
40 DDisplay *ddisp)
42 Rectangle *visible;
43 Point p1, p2, tl;
44 real diff;
45 int idiff;
46 real factor;
48 tool->box_active = FALSE;
50 visible = &ddisp->visible;
52 ddisplay_untransform_coords(ddisp, tool->x, tool->y, &p1.x, &p1.y);
53 ddisplay_untransform_coords(ddisp, event->x, event->y, &p2.x, &p2.y);
55 tl.x = MIN(p1.x, p2.x);
56 tl.y = MIN(p1.y, p2.y);
58 diff = MAX(fabs(p2.x - p1.x), fabs(p2.y - p1.y));
59 idiff = MAX(abs(tool->x - event->x), abs(tool->y - event->y));
61 if (tool->moved) {
62 if (idiff <= 4) {
63 ddisplay_add_update_all(ddisp);
64 ddisplay_flush(ddisp);
65 } else if (!(event->state & GDK_CONTROL_MASK)) {
66 factor = (visible->right - visible->left) / diff;
67 tl.x += (visible->right - visible->left)/(2.0*factor);
68 tl.y += (visible->bottom - visible->top)/(2.0*factor);
69 ddisplay_zoom(ddisp, &tl, factor);
70 } else {
71 factor = diff / (visible->right - visible->left);
72 tl.x = tl.x * factor + tl.x;
73 tl.y = tl.y * factor + tl.y;
74 ddisplay_zoom(ddisp, &tl, factor);
76 } else {
77 if (event->state & GDK_SHIFT_MASK)
78 ddisplay_zoom(ddisp, &tl, 0.5);
79 else
80 ddisplay_zoom(ddisp, &tl, 2.0);
83 gdk_pointer_ungrab (event->time);
86 typedef struct intPoint { int x,y; } intPoint;
88 static void
89 magnify_motion(MagnifyTool *tool, GdkEventMotion *event,
90 DDisplay *ddisp)
92 intPoint tl, br;
94 if (tool->box_active) {
95 tool->moved = TRUE;
97 if (tool->gc == NULL) {
98 tool->gc = gdk_gc_new(ddisp->canvas->window);
99 gdk_gc_set_line_attributes(tool->gc, 1, GDK_LINE_ON_OFF_DASH,
100 GDK_CAP_BUTT, GDK_JOIN_MITER);
101 gdk_gc_set_foreground(tool->gc, &color_gdk_white);
102 gdk_gc_set_function(tool->gc, GDK_XOR);
105 tl.x = MIN(tool->x, tool->oldx); tl.y = MIN(tool->y, tool->oldy);
106 br.x = MAX(tool->x, tool->oldx); br.y = MAX(tool->y, tool->oldy);
108 gdk_draw_rectangle (ddisp->canvas->window,
109 tool->gc, FALSE, tl.x, tl.y, br.x - tl.x, br.y - tl.y);
111 tl.x = MIN(tool->x, event->x); tl.y = MIN(tool->y, event->y);
112 br.x = MAX(tool->x, event->x); br.y = MAX(tool->y, event->y);
114 gdk_draw_rectangle (ddisp->canvas->window,
115 tool->gc, FALSE, tl.x, tl.y, br.x - tl.x, br.y - tl.y);
117 tool->oldx = event->x;
118 tool->oldy = event->y;
122 void
123 set_zoom_out(Tool *tool)
125 ((MagnifyTool *)tool)->zoom_out = TRUE;
126 ddisplay_set_all_cursor(get_cursor(CURSOR_ZOOM_OUT));
129 void
130 set_zoom_in(Tool *tool)
132 ((MagnifyTool *)tool)->zoom_out = FALSE;
133 ddisplay_set_all_cursor(get_cursor(CURSOR_ZOOM_IN));
136 Tool *
137 create_magnify_tool(void)
139 MagnifyTool *tool;
141 tool = g_new0(MagnifyTool, 1);
142 tool->tool.type = MAGNIFY_TOOL;
143 tool->tool.button_press_func = (ButtonPressFunc) &magnify_button_press;
144 tool->tool.button_release_func = (ButtonPressFunc) &magnify_button_release;
145 tool->tool.motion_func = (MotionFunc) &magnify_motion;
146 tool->tool.double_click_func = NULL;
148 tool->gc = NULL;
149 tool->box_active = FALSE;
150 tool->zoom_out = FALSE;
152 ddisplay_set_all_cursor(get_cursor(CURSOR_ZOOM_IN));
154 return (Tool *) tool;
157 void
158 free_magnify_tool(Tool *tool)
160 g_free(tool);
161 ddisplay_set_all_cursor(default_cursor);