lots of fixes and changes:

2007-03-12  Michael Natterer  <mitch@gimp.org>

	* app/tools/gimpmagnifytool.[ch]: lots of fixes and changes:

	- Request click events and use them instead of looking at the
	  distance the mouse travelled ourselves.
	- Also zoom when the user draws a very thin rectangle or just a
	  line, there is no reason to treat that as click.
	- Changed all calculations and stored values to double so the tool
	  continues to work smoothly at high zoom levels.
	- Fix scale calculation when zooming out (was totally b0rk).
	- Changed offset calculation when zooming out so that the current
	  viewport ends up within the drawn rectangle (which is the
	  opposite of what zooming in does).


svn path=/trunk/; revision=22105
This commit is contained in:
Michael Natterer
2007-03-12 14:36:49 +00:00
committed by Michael Natterer
parent 4d44bacd74
commit ef30d0079c
3 changed files with 110 additions and 44 deletions

View File

@ -1,3 +1,18 @@
2007-03-12 Michael Natterer <mitch@gimp.org>
* app/tools/gimpmagnifytool.[ch]: lots of fixes and changes:
- Request click events and use them instead of looking at the
distance the mouse travelled ourselves.
- Also zoom when the user draws a very thin rectangle or just a
line, there is no reason to treat that as click.
- Changed all calculations and stored values to double so the tool
continues to work smoothly at high zoom levels.
- Fix scale calculation when zooming out (was totally b0rk).
- Changed offset calculation when zooming out so that the current
viewport ends up within the drawn rectangle (which is the
opposite of what zooming in does).
2007-03-12 Sven Neumann <sven@gimp.org> 2007-03-12 Sven Neumann <sven@gimp.org>
* app/plug-in/gimpplugin.[ch]: gimp_plug_in_get_undo_desc() uses * app/plug-in/gimpplugin.[ch]: gimp_plug_in_get_undo_desc() uses

View File

@ -18,8 +18,6 @@
#include "config.h" #include "config.h"
#include <stdlib.h>
#include <gtk/gtk.h> #include <gtk/gtk.h>
#include "libgimpmath/gimpmath.h" #include "libgimpmath/gimpmath.h"
@ -29,12 +27,12 @@
#include "core/gimpimage.h" #include "core/gimpimage.h"
#include "widgets/gimphelp-ids.h"
#include "display/gimpdisplay.h" #include "display/gimpdisplay.h"
#include "display/gimpdisplayshell.h" #include "display/gimpdisplayshell.h"
#include "display/gimpdisplayshell-scale.h" #include "display/gimpdisplayshell-scale.h"
#include "widgets/gimphelp-ids.h"
#include "gimpmagnifyoptions.h" #include "gimpmagnifyoptions.h"
#include "gimpmagnifytool.h" #include "gimpmagnifytool.h"
#include "gimptoolcontrol.h" #include "gimptoolcontrol.h"
@ -120,6 +118,7 @@ gimp_magnify_tool_init (GimpMagnifyTool *magnify_tool)
gimp_tool_control_set_scroll_lock (tool->control, TRUE); gimp_tool_control_set_scroll_lock (tool->control, TRUE);
gimp_tool_control_set_handle_empty_image (tool->control, TRUE); gimp_tool_control_set_handle_empty_image (tool->control, TRUE);
gimp_tool_control_set_wants_click (tool->control, TRUE);
gimp_tool_control_set_snap_to (tool->control, FALSE); gimp_tool_control_set_snap_to (tool->control, FALSE);
gimp_tool_control_set_cursor (tool->control, gimp_tool_control_set_cursor (tool->control,
@ -163,7 +162,6 @@ gimp_magnify_tool_button_release (GimpTool *tool,
GimpMagnifyTool *magnify = GIMP_MAGNIFY_TOOL (tool); GimpMagnifyTool *magnify = GIMP_MAGNIFY_TOOL (tool);
GimpMagnifyOptions *options = GIMP_MAGNIFY_TOOL_GET_OPTIONS (tool); GimpMagnifyOptions *options = GIMP_MAGNIFY_TOOL_GET_OPTIONS (tool);
GimpDisplayShell *shell = GIMP_DISPLAY_SHELL (tool->display->shell); GimpDisplayShell *shell = GIMP_DISPLAY_SHELL (tool->display->shell);
gdouble current;
gimp_draw_tool_stop (GIMP_DRAW_TOOL (tool)); gimp_draw_tool_stop (GIMP_DRAW_TOOL (tool));
@ -171,68 +169,121 @@ gimp_magnify_tool_button_release (GimpTool *tool,
if (release_type != GIMP_BUTTON_RELEASE_CANCEL) if (release_type != GIMP_BUTTON_RELEASE_CANCEL)
{ {
gint x1, y1, x2, y2, w, h; gdouble x1, y1, x2, y2;
gint win_width, win_height; gdouble width, height;
gint offset_x, offset_y; gdouble current_scale;
gdouble new_scale; gdouble new_scale;
x1 = (magnify->w < 0) ? magnify->x + magnify->w : magnify->x; x1 = (magnify->w < 0) ? magnify->x + magnify->w : magnify->x;
y1 = (magnify->h < 0) ? magnify->y + magnify->h : magnify->y; y1 = (magnify->h < 0) ? magnify->y + magnify->h : magnify->y;
w = (magnify->w < 0) ? -magnify->w : magnify->w; width = (magnify->w < 0) ? -magnify->w : magnify->w;
h = (magnify->h < 0) ? -magnify->h : magnify->h; height = (magnify->h < 0) ? -magnify->h : magnify->h;
x2 = x1 + w; x2 = x1 + width;
y2 = y1 + h; y2 = y1 + height;
win_width = shell->disp_width; width = MAX (1.0, width);
win_height = shell->disp_height; height = MAX (1.0, height);
current = gimp_zoom_model_get_factor (shell->zoom); current_scale = gimp_zoom_model_get_factor (shell->zoom);
/* we need to compute the mouse movement in screen coordinates */ if (release_type == GIMP_BUTTON_RELEASE_CLICK ||
if ((SCALEX (shell, w) < options->threshold) || release_type == GIMP_BUTTON_RELEASE_NO_MOTION)
(SCALEY (shell, h) < options->threshold))
{ {
new_scale = gimp_zoom_model_zoom_step (options->zoom_type, current); new_scale = gimp_zoom_model_zoom_step (options->zoom_type,
current_scale);
} }
else else
{ {
gint width, height; gdouble display_width;
gdouble scale = 1.0; gdouble display_height;
gdouble factor = 1.0;
width = UNSCALEX (shell, win_width); display_width = FUNSCALEX (shell, shell->disp_width);
height = UNSCALEY (shell, win_height); display_height = FUNSCALEY (shell, shell->disp_height);
switch (options->zoom_type) switch (options->zoom_type)
{ {
case GIMP_ZOOM_IN: case GIMP_ZOOM_IN:
scale = MIN (((gdouble) width / (gdouble) w), factor = MIN ((display_width / width),
((gdouble) height / (gdouble) h)); (display_height / height));
break; break;
case GIMP_ZOOM_OUT: case GIMP_ZOOM_OUT:
scale = MIN (((gdouble) w / (gdouble) width), factor = MAX ((width / display_width),
((gdouble) h / (gdouble) height)); (height / display_height));
break; break;
default: default:
break; break;
} }
new_scale = current * scale; new_scale = current_scale * factor;
} }
offset_x = (new_scale * ((x1 + x2) / 2) if (new_scale != current_scale)
* SCREEN_XRES (shell) / display->image->xresolution {
- (win_width / 2)); gint offset_x = 0;
gint offset_y = 0;
offset_y = (new_scale * ((y1 + y2) / 2) switch (options->zoom_type)
* SCREEN_YRES (shell) / display->image->yresolution {
- (win_height / 2)); case GIMP_ZOOM_IN:
/* move the center of the rectangle to the center of the
* viewport:
*
* new_offset = center of rectangle in new scale screen coords
* including offset
* -
* center of viewport in screen coords without
* offset
*/
offset_x = RINT (new_scale * ((x1 + x2) / 2.0) *
SCREEN_XRES (shell) / display->image->xresolution
-
(shell->disp_width / 2.0));
gimp_display_shell_scale_by_values (shell, offset_y = RINT (new_scale * ((y1 + y2) / 2.0) *
new_scale, SCREEN_YRES (shell) / display->image->yresolution
offset_x, offset_y, -
options->auto_resize); (shell->disp_height / 2.0));
break;
case GIMP_ZOOM_OUT:
/* move the center of the viewport to the center of the
* rectangle:
*
* new_offset = center of viewport in new scale screen coords
* including offset
* -
* center of rectangle in screen coords without
* offset
*/
offset_x = RINT (new_scale * UNSCALEX (shell,
shell->offset_x +
shell->disp_width / 2.0) *
SCREEN_XRES (shell) / display->image->xresolution
-
(SCALEX (shell, (x1 + x2) / 2.0) -
shell->offset_x));
offset_y = RINT (new_scale * UNSCALEY (shell,
shell->offset_y +
shell->disp_height / 2.0) *
SCREEN_YRES (shell) / display->image->yresolution
-
(SCALEY (shell, (y1 + y2) / 2.0) -
shell->offset_y));
break;
default:
break;
}
gimp_display_shell_scale_by_values (shell,
new_scale,
offset_x, offset_y,
options->auto_resize);
}
} }
} }
@ -247,8 +298,8 @@ gimp_magnify_tool_motion (GimpTool *tool,
gimp_draw_tool_pause (GIMP_DRAW_TOOL (tool)); gimp_draw_tool_pause (GIMP_DRAW_TOOL (tool));
magnify->w = (coords->x - magnify->x); magnify->w = coords->x - magnify->x;
magnify->h = (coords->y - magnify->y); magnify->h = coords->y - magnify->y;
gimp_draw_tool_resume (GIMP_DRAW_TOOL (tool)); gimp_draw_tool_resume (GIMP_DRAW_TOOL (tool));
} }

View File

@ -40,8 +40,8 @@ struct _GimpMagnifyTool
{ {
GimpDrawTool parent_instance; GimpDrawTool parent_instance;
gint x, y; /* upper left hand coordinate */ gdouble x, y; /* upper left hand coordinate */
gint w, h; /* width and height */ gdouble w, h; /* width and height */
}; };
struct _GimpMagnifyToolClass struct _GimpMagnifyToolClass