2006-12-10 05:33:38 +08:00
|
|
|
/* GIMP - The GNU Image Manipulation Program
|
1997-11-25 06:05:25 +08:00
|
|
|
* Copyright (C) 1995 Spencer Kimball and Peter Mattis
|
|
|
|
*
|
|
|
|
* This program is free software; you can redistribute it and/or modify
|
|
|
|
* it under the terms of the GNU General Public License as published by
|
|
|
|
* the Free Software Foundation; either version 2 of the License, or
|
|
|
|
* (at your option) any later version.
|
|
|
|
*
|
|
|
|
* This program is distributed in the hope that it will be useful,
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
* GNU General Public License for more details.
|
|
|
|
*
|
|
|
|
* You should have received a copy of the GNU General Public License
|
|
|
|
* along with this program; if not, write to the Free Software
|
1998-04-13 13:44:11 +08:00
|
|
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
1997-11-25 06:05:25 +08:00
|
|
|
*/
|
2000-12-17 05:37:03 +08:00
|
|
|
|
|
|
|
#include "config.h"
|
|
|
|
|
1997-11-25 06:05:25 +08:00
|
|
|
#include <stdlib.h>
|
2000-01-26 07:06:12 +08:00
|
|
|
|
2000-12-29 23:22:01 +08:00
|
|
|
#include <gtk/gtk.h>
|
2000-12-17 05:37:03 +08:00
|
|
|
|
2007-03-09 21:00:01 +08:00
|
|
|
#include "libgimpmath/gimpmath.h"
|
2003-04-04 16:32:51 +08:00
|
|
|
#include "libgimpwidgets/gimpwidgets.h"
|
2001-05-21 21:58:46 +08:00
|
|
|
|
2001-09-26 07:23:09 +08:00
|
|
|
#include "display-types.h"
|
2000-12-17 05:37:03 +08:00
|
|
|
|
2002-11-19 04:50:31 +08:00
|
|
|
#include "config/gimpdisplayconfig.h"
|
|
|
|
|
|
|
|
#include "core/gimp.h"
|
2001-05-09 10:32:03 +08:00
|
|
|
#include "core/gimpimage.h"
|
2004-06-02 06:04:20 +08:00
|
|
|
#include "core/gimpunit.h"
|
2001-05-09 10:32:03 +08:00
|
|
|
|
2003-08-24 21:52:51 +08:00
|
|
|
#include "widgets/gimphelp-ids.h"
|
2003-04-04 16:32:51 +08:00
|
|
|
#include "widgets/gimpviewabledialog.h"
|
|
|
|
|
2001-09-26 07:23:09 +08:00
|
|
|
#include "gimpdisplay.h"
|
2001-11-01 05:20:09 +08:00
|
|
|
#include "gimpdisplayshell.h"
|
2008-07-13 22:09:05 +08:00
|
|
|
#include "gimpdisplayshell-private.h"
|
2001-11-02 17:31:21 +08:00
|
|
|
#include "gimpdisplayshell-scale.h"
|
|
|
|
#include "gimpdisplayshell-scroll.h"
|
2003-02-26 03:01:10 +08:00
|
|
|
#include "gimpdisplayshell-title.h"
|
2001-09-26 07:23:09 +08:00
|
|
|
|
2003-04-04 16:32:51 +08:00
|
|
|
#include "gimp-intl.h"
|
|
|
|
|
2000-12-29 23:22:01 +08:00
|
|
|
|
2007-03-04 18:27:17 +08:00
|
|
|
#define SCALE_TIMEOUT 1
|
|
|
|
|
2007-02-07 16:13:44 +08:00
|
|
|
#define SCALE_EPSILON 0.0001
|
|
|
|
|
2007-02-07 17:12:55 +08:00
|
|
|
#define SCALE_EQUALS(a,b) (fabs ((a) - (b)) < SCALE_EPSILON)
|
|
|
|
|
|
|
|
|
2007-05-23 18:22:09 +08:00
|
|
|
typedef struct
|
2003-05-05 23:33:11 +08:00
|
|
|
{
|
|
|
|
GimpDisplayShell *shell;
|
2005-09-26 01:03:03 +08:00
|
|
|
GimpZoomModel *model;
|
2004-01-30 06:22:29 +08:00
|
|
|
GtkObject *scale_adj;
|
|
|
|
GtkObject *num_adj;
|
|
|
|
GtkObject *denom_adj;
|
2007-05-23 18:22:09 +08:00
|
|
|
} ScaleDialogData;
|
2003-05-05 23:33:11 +08:00
|
|
|
|
|
|
|
|
2001-10-13 20:52:30 +08:00
|
|
|
/* local function prototypes */
|
1997-11-25 06:05:25 +08:00
|
|
|
|
2003-11-06 23:27:05 +08:00
|
|
|
static void gimp_display_shell_scale_dialog_response (GtkWidget *widget,
|
|
|
|
gint response_id,
|
|
|
|
ScaleDialogData *dialog);
|
2007-05-23 18:22:09 +08:00
|
|
|
static void gimp_display_shell_scale_dialog_free (ScaleDialogData *dialog);
|
|
|
|
|
|
|
|
static void update_zoom_values (GtkAdjustment *adj,
|
2004-01-30 06:22:29 +08:00
|
|
|
ScaleDialogData *dialog);
|
2003-05-05 23:33:11 +08:00
|
|
|
static gdouble img2real (GimpDisplayShell *shell,
|
|
|
|
gboolean xdir,
|
|
|
|
gdouble a);
|
1997-11-25 06:05:25 +08:00
|
|
|
|
|
|
|
|
2001-10-13 20:52:30 +08:00
|
|
|
/* public functions */
|
1997-11-25 06:05:25 +08:00
|
|
|
|
2007-02-09 00:40:46 +08:00
|
|
|
/**
|
|
|
|
* gimp_display_shell_scale_setup:
|
2008-03-19 05:22:21 +08:00
|
|
|
* @shell: the #GimpDisplayShell
|
2007-02-09 00:40:46 +08:00
|
|
|
*
|
|
|
|
* Prepares the display for drawing the image at current scale and offset.
|
|
|
|
* This preparation involves, for example, setting up scrollbars and rulers.
|
|
|
|
**/
|
1997-11-25 06:05:25 +08:00
|
|
|
void
|
2001-11-01 05:20:09 +08:00
|
|
|
gimp_display_shell_scale_setup (GimpDisplayShell *shell)
|
|
|
|
{
|
2008-03-19 05:22:21 +08:00
|
|
|
GimpImage *image;
|
2008-07-12 15:14:22 +08:00
|
|
|
gfloat sw, sh;
|
2008-05-27 05:20:16 +08:00
|
|
|
gint image_width;
|
|
|
|
gint image_height;
|
2001-11-01 05:20:09 +08:00
|
|
|
|
|
|
|
g_return_if_fail (GIMP_IS_DISPLAY_SHELL (shell));
|
|
|
|
|
2006-03-29 01:55:52 +08:00
|
|
|
if (! shell->display)
|
2004-06-02 06:04:20 +08:00
|
|
|
return;
|
|
|
|
|
2008-03-19 05:22:21 +08:00
|
|
|
image = shell->display->image;
|
|
|
|
|
|
|
|
if (image)
|
|
|
|
{
|
|
|
|
image_width = gimp_image_get_width (image);
|
|
|
|
image_height = gimp_image_get_height (image);
|
|
|
|
|
2008-07-12 15:14:22 +08:00
|
|
|
sw = SCALEX (shell, image_width);
|
|
|
|
sh = SCALEY (shell, image_height);
|
2008-03-19 05:22:21 +08:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
image_width = shell->disp_width;
|
|
|
|
image_height = shell->disp_height;
|
2001-11-01 05:20:09 +08:00
|
|
|
|
2008-07-12 15:14:22 +08:00
|
|
|
sw = image_width;
|
|
|
|
sh = image_height;
|
2008-03-19 05:22:21 +08:00
|
|
|
}
|
2001-11-01 05:20:09 +08:00
|
|
|
|
2008-07-12 22:48:09 +08:00
|
|
|
|
|
|
|
/* Horizontal scrollbar */
|
|
|
|
|
2008-07-12 18:27:20 +08:00
|
|
|
shell->hsbdata->value = shell->offset_x;
|
2008-07-12 22:48:09 +08:00
|
|
|
shell->hsbdata->page_size = shell->disp_width;
|
2001-11-02 17:31:21 +08:00
|
|
|
shell->hsbdata->page_increment = shell->disp_width / 2;
|
2007-03-14 18:26:19 +08:00
|
|
|
shell->hsbdata->step_increment = shell->scale_x;
|
2001-11-01 05:20:09 +08:00
|
|
|
|
2008-07-12 22:48:09 +08:00
|
|
|
gimp_display_shell_setup_hscrollbar_with_value (shell, shell->offset_x);
|
|
|
|
|
|
|
|
gtk_adjustment_changed (shell->hsbdata);
|
|
|
|
|
|
|
|
|
|
|
|
/* Vertcal scrollbar */
|
|
|
|
|
2008-07-12 18:27:20 +08:00
|
|
|
shell->vsbdata->value = shell->offset_y;
|
2008-07-12 22:48:09 +08:00
|
|
|
shell->vsbdata->page_size = shell->disp_height;
|
2001-11-02 17:31:21 +08:00
|
|
|
shell->vsbdata->page_increment = shell->disp_height / 2;
|
2007-03-14 18:26:19 +08:00
|
|
|
shell->vsbdata->step_increment = shell->scale_y;
|
2001-11-01 05:20:09 +08:00
|
|
|
|
2008-07-12 22:48:09 +08:00
|
|
|
gimp_display_shell_setup_vscrollbar_with_value (shell, shell->offset_y);
|
|
|
|
|
2001-11-01 05:20:09 +08:00
|
|
|
gtk_adjustment_changed (shell->vsbdata);
|
|
|
|
|
2008-07-12 22:48:09 +08:00
|
|
|
|
2008-07-12 05:08:34 +08:00
|
|
|
/* Setup rulers */
|
|
|
|
{
|
|
|
|
gdouble horizontal_lower;
|
|
|
|
gdouble horizontal_upper;
|
|
|
|
gdouble horizontal_max_size;
|
|
|
|
gdouble vertical_lower;
|
|
|
|
gdouble vertical_upper;
|
|
|
|
gdouble vertical_max_size;
|
|
|
|
gint scaled_image_viewport_offset_x;
|
|
|
|
gint scaled_image_viewport_offset_y;
|
|
|
|
|
|
|
|
|
|
|
|
/* Initialize values */
|
|
|
|
|
|
|
|
horizontal_lower = 0;
|
|
|
|
vertical_lower = 0;
|
|
|
|
|
|
|
|
if (image)
|
|
|
|
{
|
|
|
|
horizontal_upper = img2real (shell, TRUE, FUNSCALEX (shell, shell->disp_width));
|
|
|
|
horizontal_max_size = img2real (shell, TRUE, MAX (image_width, image_height));
|
|
|
|
|
|
|
|
vertical_upper = img2real (shell, FALSE, FUNSCALEY (shell, shell->disp_height));
|
|
|
|
vertical_max_size = img2real (shell, FALSE, MAX (image_width, image_height));
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
horizontal_upper = image_width;
|
|
|
|
horizontal_max_size = MAX (image_width, image_height);
|
|
|
|
|
|
|
|
vertical_upper = image_height;
|
|
|
|
vertical_max_size = MAX (image_width, image_height);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/* Adjust due to scrolling */
|
|
|
|
|
|
|
|
gimp_display_shell_get_scaled_image_viewport_offset (shell,
|
|
|
|
&scaled_image_viewport_offset_x,
|
|
|
|
&scaled_image_viewport_offset_y);
|
|
|
|
|
|
|
|
horizontal_lower -= img2real (shell, TRUE,
|
|
|
|
FUNSCALEX (shell, (gdouble) scaled_image_viewport_offset_x));
|
|
|
|
horizontal_upper -= img2real (shell, TRUE,
|
|
|
|
FUNSCALEX (shell, (gdouble) scaled_image_viewport_offset_x));
|
|
|
|
|
|
|
|
vertical_lower -= img2real (shell, FALSE,
|
|
|
|
FUNSCALEY (shell, (gdouble) scaled_image_viewport_offset_y));
|
|
|
|
vertical_upper -= img2real (shell, FALSE,
|
|
|
|
FUNSCALEY (shell, (gdouble) scaled_image_viewport_offset_y));
|
|
|
|
|
|
|
|
|
|
|
|
/* Finally setup the actual rulers */
|
|
|
|
|
|
|
|
gimp_ruler_set_range (GIMP_RULER (shell->hrule),
|
|
|
|
horizontal_lower,
|
|
|
|
horizontal_upper,
|
|
|
|
horizontal_max_size);
|
|
|
|
|
|
|
|
gimp_ruler_set_unit (GIMP_RULER (shell->hrule),
|
|
|
|
shell->unit);
|
|
|
|
|
|
|
|
gimp_ruler_set_range (GIMP_RULER (shell->vrule),
|
|
|
|
vertical_lower,
|
|
|
|
vertical_upper,
|
|
|
|
vertical_max_size);
|
|
|
|
|
|
|
|
gimp_ruler_set_unit (GIMP_RULER (shell->vrule),
|
|
|
|
shell->unit);
|
|
|
|
}
|
2001-11-01 05:20:09 +08:00
|
|
|
}
|
|
|
|
|
2007-02-07 16:13:44 +08:00
|
|
|
/**
|
|
|
|
* gimp_display_shell_scale_revert:
|
|
|
|
* @shell: the #GimpDisplayShell
|
|
|
|
*
|
2008-05-27 05:20:16 +08:00
|
|
|
* Reverts the display to the previously used scale. If no previous
|
|
|
|
* scale exist, then the call does nothing.
|
2007-02-07 16:13:44 +08:00
|
|
|
*
|
|
|
|
* Return value: %TRUE if the scale was reverted, otherwise %FALSE.
|
|
|
|
**/
|
|
|
|
gboolean
|
|
|
|
gimp_display_shell_scale_revert (GimpDisplayShell *shell)
|
|
|
|
{
|
|
|
|
g_return_val_if_fail (GIMP_IS_DISPLAY_SHELL (shell), FALSE);
|
|
|
|
|
|
|
|
/* don't bother if no scale has been set */
|
|
|
|
if (shell->last_scale < SCALE_EPSILON)
|
|
|
|
return FALSE;
|
|
|
|
|
2007-03-04 18:27:17 +08:00
|
|
|
shell->last_scale_time = 0;
|
|
|
|
|
2007-02-07 16:13:44 +08:00
|
|
|
gimp_display_shell_scale_by_values (shell,
|
|
|
|
shell->last_scale,
|
|
|
|
shell->last_offset_x,
|
|
|
|
shell->last_offset_y,
|
|
|
|
FALSE); /* don't resize the window */
|
|
|
|
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* gimp_display_shell_scale_can_revert:
|
2008-03-19 05:22:21 +08:00
|
|
|
* @shell: the #GimpDisplayShell
|
2007-02-07 16:13:44 +08:00
|
|
|
*
|
|
|
|
* Return value: %TRUE if a previous display scale exists, otherwise %FALSE.
|
|
|
|
**/
|
|
|
|
gboolean
|
|
|
|
gimp_display_shell_scale_can_revert (GimpDisplayShell *shell)
|
|
|
|
{
|
|
|
|
g_return_val_if_fail (GIMP_IS_DISPLAY_SHELL (shell), FALSE);
|
|
|
|
|
|
|
|
return (shell->last_scale > SCALE_EPSILON);
|
|
|
|
}
|
|
|
|
|
2007-02-09 00:40:46 +08:00
|
|
|
/**
|
|
|
|
* gimp_display_shell_scale_set_dot_for_dot:
|
|
|
|
* @shell: the #GimpDisplayShell
|
|
|
|
* @dot_for_dot: whether "Dot for Dot" should be enabled
|
|
|
|
*
|
|
|
|
* If @dot_for_dot is set to %TRUE then the "Dot for Dot" mode (where image and
|
|
|
|
* screen pixels are of the same size) is activated. Dually, the mode is
|
|
|
|
* disabled if @dot_for_dot is %FALSE.
|
|
|
|
**/
|
2001-11-01 05:20:09 +08:00
|
|
|
void
|
|
|
|
gimp_display_shell_scale_set_dot_for_dot (GimpDisplayShell *shell,
|
|
|
|
gboolean dot_for_dot)
|
|
|
|
{
|
|
|
|
g_return_if_fail (GIMP_IS_DISPLAY_SHELL (shell));
|
|
|
|
|
2002-06-27 06:16:59 +08:00
|
|
|
if (dot_for_dot != shell->dot_for_dot)
|
2001-11-01 05:20:09 +08:00
|
|
|
{
|
2002-02-17 19:46:39 +08:00
|
|
|
/* freeze the active tool */
|
2003-09-12 06:24:30 +08:00
|
|
|
gimp_display_shell_pause (shell);
|
2002-02-17 19:46:39 +08:00
|
|
|
|
2002-06-27 06:16:59 +08:00
|
|
|
shell->dot_for_dot = dot_for_dot;
|
2001-11-01 05:20:09 +08:00
|
|
|
|
2007-03-14 18:26:19 +08:00
|
|
|
gimp_display_shell_scale_changed (shell);
|
2007-03-14 18:01:08 +08:00
|
|
|
|
2001-11-01 05:20:09 +08:00
|
|
|
gimp_display_shell_scale_resize (shell,
|
2008-03-19 05:22:21 +08:00
|
|
|
shell->display->config->resize_windows_on_zoom,
|
2008-03-23 23:16:44 +08:00
|
|
|
FALSE);
|
2002-02-17 19:46:39 +08:00
|
|
|
|
|
|
|
/* re-enable the active tool */
|
2003-09-12 06:24:30 +08:00
|
|
|
gimp_display_shell_resume (shell);
|
2001-11-01 05:20:09 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2005-04-14 19:06:49 +08:00
|
|
|
/**
|
|
|
|
* gimp_display_shell_scale:
|
|
|
|
* @shell: the #GimpDisplayShell
|
|
|
|
* @zoom_type: whether to zoom in, our or to a specific scale
|
2005-04-14 19:46:07 +08:00
|
|
|
* @scale: ignored unless @zoom_type == %GIMP_ZOOM_TO
|
2005-04-14 19:06:49 +08:00
|
|
|
*
|
2005-04-14 21:01:34 +08:00
|
|
|
* This function calls gimp_display_shell_scale_to(). It tries to be
|
|
|
|
* smart whether to use the position of the mouse pointer or the
|
2005-05-11 23:00:49 +08:00
|
|
|
* center of the display as coordinates.
|
2005-04-14 19:06:49 +08:00
|
|
|
**/
|
2005-04-14 00:34:53 +08:00
|
|
|
void
|
2005-04-14 19:06:49 +08:00
|
|
|
gimp_display_shell_scale (GimpDisplayShell *shell,
|
|
|
|
GimpZoomType zoom_type,
|
|
|
|
gdouble new_scale)
|
2005-04-14 00:34:53 +08:00
|
|
|
{
|
2005-04-14 21:01:34 +08:00
|
|
|
GdkEvent *event;
|
|
|
|
gint x, y;
|
2005-04-14 19:50:23 +08:00
|
|
|
|
2005-04-14 00:34:53 +08:00
|
|
|
g_return_if_fail (GIMP_IS_DISPLAY_SHELL (shell));
|
2005-04-14 21:01:34 +08:00
|
|
|
g_return_if_fail (shell->canvas != NULL);
|
2005-04-14 00:34:53 +08:00
|
|
|
|
2006-05-07 06:56:28 +08:00
|
|
|
if (zoom_type == GIMP_ZOOM_TO &&
|
2007-02-07 17:12:55 +08:00
|
|
|
SCALE_EQUALS (new_scale, gimp_zoom_model_get_factor (shell->zoom)))
|
2006-05-07 06:56:28 +08:00
|
|
|
return;
|
|
|
|
|
2005-04-14 20:08:01 +08:00
|
|
|
x = shell->disp_width / 2;
|
|
|
|
y = shell->disp_height / 2;
|
|
|
|
|
2005-05-11 23:00:49 +08:00
|
|
|
/* Center on the mouse position instead of the display center,
|
|
|
|
* if one of the following conditions is fulfilled:
|
|
|
|
*
|
|
|
|
* (1) there's no current event (the action was triggered by an
|
|
|
|
* input controller)
|
|
|
|
* (2) the event originates from the canvas (a scroll event)
|
|
|
|
* (3) the event originates from the shell (a key press event)
|
|
|
|
*
|
|
|
|
* Basically the only situation where we don't want to center on
|
|
|
|
* mouse position is if the action is being called from a menu.
|
|
|
|
*/
|
|
|
|
|
2005-04-14 21:01:34 +08:00
|
|
|
event = gtk_get_current_event ();
|
|
|
|
|
2005-05-11 23:00:49 +08:00
|
|
|
if (! event ||
|
|
|
|
gtk_get_event_widget (event) == shell->canvas ||
|
|
|
|
gtk_get_event_widget (event) == GTK_WIDGET (shell))
|
2005-04-14 21:01:34 +08:00
|
|
|
{
|
|
|
|
gtk_widget_get_pointer (shell->canvas, &x, &y);
|
|
|
|
}
|
2005-04-14 19:50:23 +08:00
|
|
|
|
|
|
|
gimp_display_shell_scale_to (shell, zoom_type, new_scale, x, y);
|
2005-04-14 00:34:53 +08:00
|
|
|
}
|
|
|
|
|
2005-04-14 19:06:49 +08:00
|
|
|
/**
|
2005-04-14 19:46:07 +08:00
|
|
|
* gimp_display_shell_scale_to:
|
2005-04-14 19:06:49 +08:00
|
|
|
* @shell: the #GimpDisplayShell
|
2005-04-14 19:46:07 +08:00
|
|
|
* @zoom_type: whether to zoom in, out or to a specified scale
|
|
|
|
* @scale: ignored unless @zoom_type == %GIMP_ZOOM_TO
|
2005-04-14 19:06:49 +08:00
|
|
|
* @x: x screen coordinate
|
|
|
|
* @y: y screen coordinate
|
|
|
|
*
|
2005-04-14 19:46:07 +08:00
|
|
|
* This function changes the scale (zoom ratio) of the display shell.
|
|
|
|
* It either zooms in / out one step (%GIMP_ZOOM_IN / %GIMP_ZOOM_OUT)
|
|
|
|
* or sets the scale to the zoom ratio passed as @scale (%GIMP_ZOOM_TO).
|
|
|
|
*
|
|
|
|
* The display offsets are adjusted so that the point specified by @x
|
|
|
|
* and @y doesn't change it's position on screen (if possible). You
|
|
|
|
* would typically pass either the display center or the mouse
|
|
|
|
* position here.
|
2005-04-14 19:06:49 +08:00
|
|
|
**/
|
2001-11-01 05:20:09 +08:00
|
|
|
void
|
2005-04-14 19:06:49 +08:00
|
|
|
gimp_display_shell_scale_to (GimpDisplayShell *shell,
|
|
|
|
GimpZoomType zoom_type,
|
2005-04-14 19:46:07 +08:00
|
|
|
gdouble scale,
|
2005-04-14 19:06:49 +08:00
|
|
|
gdouble x,
|
|
|
|
gdouble y)
|
1997-11-25 06:05:25 +08:00
|
|
|
{
|
2008-03-19 05:22:21 +08:00
|
|
|
gdouble current;
|
|
|
|
gdouble offset_x;
|
|
|
|
gdouble offset_y;
|
1997-11-25 06:05:25 +08:00
|
|
|
|
2001-11-01 05:20:09 +08:00
|
|
|
g_return_if_fail (GIMP_IS_DISPLAY_SHELL (shell));
|
2004-06-02 06:04:20 +08:00
|
|
|
|
2006-03-29 01:55:52 +08:00
|
|
|
if (! shell->display)
|
2004-06-02 06:04:20 +08:00
|
|
|
return;
|
|
|
|
|
2005-09-26 01:03:03 +08:00
|
|
|
current = gimp_zoom_model_get_factor (shell->zoom);
|
|
|
|
|
2005-04-14 19:46:07 +08:00
|
|
|
offset_x = shell->offset_x + x;
|
|
|
|
offset_y = shell->offset_y + y;
|
1997-11-25 06:05:25 +08:00
|
|
|
|
2005-09-26 01:03:03 +08:00
|
|
|
offset_x /= current;
|
|
|
|
offset_y /= current;
|
1997-11-25 06:05:25 +08:00
|
|
|
|
2005-04-14 19:46:07 +08:00
|
|
|
if (zoom_type != GIMP_ZOOM_TO)
|
2005-09-26 01:03:03 +08:00
|
|
|
scale = gimp_zoom_model_zoom_step (zoom_type, current);
|
2000-01-26 07:06:12 +08:00
|
|
|
|
2005-04-14 19:46:07 +08:00
|
|
|
offset_x *= scale;
|
|
|
|
offset_y *= scale;
|
2003-05-05 22:48:15 +08:00
|
|
|
|
2005-04-14 19:46:07 +08:00
|
|
|
gimp_display_shell_scale_by_values (shell, scale,
|
2005-04-14 19:06:49 +08:00
|
|
|
offset_x - x, offset_y - y,
|
2008-03-19 05:22:21 +08:00
|
|
|
shell->display->config->resize_windows_on_zoom);
|
1997-11-25 06:05:25 +08:00
|
|
|
}
|
|
|
|
|
2007-02-09 00:40:46 +08:00
|
|
|
/**
|
|
|
|
* gimp_display_shell_scale_fit_in:
|
2008-03-19 05:22:21 +08:00
|
|
|
* @shell: the #GimpDisplayShell
|
2007-02-09 00:40:46 +08:00
|
|
|
*
|
|
|
|
* Sets the scale such that the entire image precisely fits in the display
|
|
|
|
* area.
|
|
|
|
**/
|
2001-11-02 17:31:21 +08:00
|
|
|
void
|
2004-06-20 20:09:03 +08:00
|
|
|
gimp_display_shell_scale_fit_in (GimpDisplayShell *shell)
|
2001-11-02 17:31:21 +08:00
|
|
|
{
|
2006-03-29 01:08:36 +08:00
|
|
|
GimpImage *image;
|
2003-01-11 05:15:41 +08:00
|
|
|
gint image_width;
|
|
|
|
gint image_height;
|
2007-12-27 01:33:41 +08:00
|
|
|
gdouble xres;
|
|
|
|
gdouble yres;
|
2003-01-11 05:15:41 +08:00
|
|
|
gdouble zoom_factor;
|
2001-11-02 17:31:21 +08:00
|
|
|
|
|
|
|
g_return_if_fail (GIMP_IS_DISPLAY_SHELL (shell));
|
|
|
|
|
2006-03-29 01:55:52 +08:00
|
|
|
image = shell->display->image;
|
2002-11-19 04:50:31 +08:00
|
|
|
|
2007-12-26 00:21:40 +08:00
|
|
|
image_width = gimp_image_get_width (image);
|
|
|
|
image_height = gimp_image_get_height (image);
|
2002-11-19 04:50:31 +08:00
|
|
|
|
2007-12-27 01:33:41 +08:00
|
|
|
gimp_image_get_resolution (image, &xres, &yres);
|
|
|
|
|
2002-06-27 06:16:59 +08:00
|
|
|
if (! shell->dot_for_dot)
|
2001-11-02 17:31:21 +08:00
|
|
|
{
|
2007-12-27 01:33:41 +08:00
|
|
|
image_width = ROUND (image_width * shell->monitor_xres / xres);
|
|
|
|
image_height = ROUND (image_height * shell->monitor_yres / yres);
|
2001-11-02 17:31:21 +08:00
|
|
|
}
|
|
|
|
|
2003-05-05 23:33:11 +08:00
|
|
|
zoom_factor = MIN ((gdouble) shell->disp_width / (gdouble) image_width,
|
|
|
|
(gdouble) shell->disp_height / (gdouble) image_height);
|
2001-11-02 17:31:21 +08:00
|
|
|
|
2004-01-30 06:22:29 +08:00
|
|
|
gimp_display_shell_scale (shell, GIMP_ZOOM_TO, zoom_factor);
|
2008-07-14 04:23:15 +08:00
|
|
|
gimp_display_shell_center_image (shell, TRUE, TRUE);
|
2002-02-17 19:46:39 +08:00
|
|
|
}
|
|
|
|
|
2007-02-09 00:40:46 +08:00
|
|
|
/**
|
2007-12-16 10:06:15 +08:00
|
|
|
* gimp_display_shell_scale_fill:
|
2008-03-19 05:22:21 +08:00
|
|
|
* @shell: the #GimpDisplayShell
|
2007-02-09 00:40:46 +08:00
|
|
|
*
|
|
|
|
* Sets the scale such that the entire display area is precisely filled by the
|
|
|
|
* image.
|
|
|
|
**/
|
2004-06-20 20:09:03 +08:00
|
|
|
void
|
2007-12-16 10:06:15 +08:00
|
|
|
gimp_display_shell_scale_fill (GimpDisplayShell *shell)
|
2004-06-20 20:09:03 +08:00
|
|
|
{
|
2006-03-29 01:08:36 +08:00
|
|
|
GimpImage *image;
|
2004-06-20 20:09:03 +08:00
|
|
|
gint image_width;
|
|
|
|
gint image_height;
|
2007-12-27 01:33:41 +08:00
|
|
|
gdouble xres;
|
|
|
|
gdouble yres;
|
2004-06-20 20:09:03 +08:00
|
|
|
gdouble zoom_factor;
|
|
|
|
|
|
|
|
g_return_if_fail (GIMP_IS_DISPLAY_SHELL (shell));
|
|
|
|
|
2006-03-29 01:55:52 +08:00
|
|
|
image = shell->display->image;
|
2004-06-20 20:09:03 +08:00
|
|
|
|
2007-12-26 00:21:40 +08:00
|
|
|
image_width = gimp_image_get_width (image);
|
|
|
|
image_height = gimp_image_get_height (image);
|
2004-06-20 20:09:03 +08:00
|
|
|
|
2007-12-27 01:33:41 +08:00
|
|
|
gimp_image_get_resolution (image, &xres, &yres);
|
|
|
|
|
2004-06-20 20:09:03 +08:00
|
|
|
if (! shell->dot_for_dot)
|
|
|
|
{
|
2007-12-27 01:33:41 +08:00
|
|
|
image_width = ROUND (image_width * shell->monitor_xres / xres);
|
|
|
|
image_height = ROUND (image_height * shell->monitor_yres / yres);
|
2004-06-20 20:09:03 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
zoom_factor = MAX ((gdouble) shell->disp_width / (gdouble) image_width,
|
|
|
|
(gdouble) shell->disp_height / (gdouble) image_height);
|
|
|
|
|
|
|
|
gimp_display_shell_scale (shell, GIMP_ZOOM_TO, zoom_factor);
|
2008-07-14 04:23:15 +08:00
|
|
|
gimp_display_shell_center_image (shell, TRUE, TRUE);
|
2008-07-13 22:09:05 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* gimp_display_shell_center_image:
|
|
|
|
* @shell:
|
2008-07-14 04:23:15 +08:00
|
|
|
* @horizontally:
|
|
|
|
* @vertically:
|
2008-07-13 22:09:05 +08:00
|
|
|
*
|
2008-07-14 04:23:15 +08:00
|
|
|
* Centers the image in the display shell on the desired axes.
|
2008-07-13 22:09:05 +08:00
|
|
|
*
|
|
|
|
**/
|
|
|
|
void
|
2008-07-14 04:23:15 +08:00
|
|
|
gimp_display_shell_center_image (GimpDisplayShell *shell,
|
|
|
|
gboolean horizontally,
|
|
|
|
gboolean vertically)
|
2008-07-13 22:09:05 +08:00
|
|
|
{
|
|
|
|
gint sw, sh;
|
|
|
|
gint target_offset_x, target_offset_y;
|
|
|
|
|
|
|
|
g_return_if_fail (GIMP_IS_DISPLAY_SHELL (shell));
|
|
|
|
|
|
|
|
if (! shell->display)
|
|
|
|
return;
|
|
|
|
|
2008-07-14 04:23:15 +08:00
|
|
|
target_offset_x = shell->offset_x;
|
|
|
|
target_offset_y = shell->offset_y;
|
|
|
|
|
2008-07-13 22:09:05 +08:00
|
|
|
gimp_display_shell_get_scaled_image_size (shell, &sw, &sh);
|
|
|
|
|
2008-07-14 04:23:15 +08:00
|
|
|
if (horizontally)
|
2008-07-13 22:09:05 +08:00
|
|
|
{
|
2008-07-14 04:23:15 +08:00
|
|
|
if (sw < shell->disp_width)
|
|
|
|
{
|
|
|
|
target_offset_x = -(shell->disp_width - sw) / 2;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
target_offset_x = (sw - shell->disp_width) / 2;
|
|
|
|
}
|
2008-07-13 22:09:05 +08:00
|
|
|
}
|
|
|
|
|
2008-07-14 04:23:15 +08:00
|
|
|
if (vertically)
|
2008-07-13 22:09:05 +08:00
|
|
|
{
|
2008-07-14 04:23:15 +08:00
|
|
|
if (sh < shell->disp_height)
|
|
|
|
{
|
|
|
|
target_offset_y = -(shell->disp_height - sh) / 2;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
target_offset_y = (sh - shell->disp_height) / 2;
|
|
|
|
}
|
2008-07-13 22:09:05 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
/* Note that we can't use gimp_display_shell_scroll_private() here
|
|
|
|
* because that would expose the image twice, causing unwanted
|
|
|
|
* flicker.
|
|
|
|
*/
|
|
|
|
gimp_display_shell_scale_by_values (shell, gimp_zoom_model_get_factor (shell->zoom),
|
|
|
|
target_offset_x, target_offset_y,
|
|
|
|
shell->display->config->resize_windows_on_zoom);
|
2004-06-20 20:09:03 +08:00
|
|
|
}
|
|
|
|
|
2007-02-09 00:40:46 +08:00
|
|
|
/**
|
|
|
|
* gimp_display_shell_scale_by_values:
|
2008-03-19 05:22:21 +08:00
|
|
|
* @shell: the #GimpDisplayShell
|
|
|
|
* @scale: the new scale
|
|
|
|
* @offset_x: the new X offset
|
|
|
|
* @offset_y: the new Y offset
|
|
|
|
* @resize_window: whether the display window should be resized
|
2007-02-09 00:40:46 +08:00
|
|
|
*
|
|
|
|
* Directly sets the image scale and image offsets used by the display. If
|
|
|
|
* @resize_window is %TRUE then the display window is resized to better
|
|
|
|
* accomodate the image, see gimp_display_shell_shrink_wrap().
|
|
|
|
**/
|
2002-02-17 19:46:39 +08:00
|
|
|
void
|
|
|
|
gimp_display_shell_scale_by_values (GimpDisplayShell *shell,
|
2004-01-30 06:22:29 +08:00
|
|
|
gdouble scale,
|
2002-02-17 19:46:39 +08:00
|
|
|
gint offset_x,
|
|
|
|
gint offset_y,
|
|
|
|
gboolean resize_window)
|
|
|
|
{
|
2007-03-04 18:27:17 +08:00
|
|
|
guint now;
|
|
|
|
|
2002-02-17 19:46:39 +08:00
|
|
|
g_return_if_fail (GIMP_IS_DISPLAY_SHELL (shell));
|
|
|
|
|
2005-05-06 21:11:53 +08:00
|
|
|
/* Abort early if the values are all setup already. We don't
|
|
|
|
* want to inadvertently resize the window (bug #164281).
|
|
|
|
*/
|
2007-02-07 17:12:55 +08:00
|
|
|
if (SCALE_EQUALS (gimp_zoom_model_get_factor (shell->zoom), scale) &&
|
|
|
|
shell->offset_x == offset_x &&
|
2005-05-06 21:11:53 +08:00
|
|
|
shell->offset_y == offset_y)
|
|
|
|
return;
|
2003-01-11 05:15:41 +08:00
|
|
|
|
2007-02-07 16:13:44 +08:00
|
|
|
/* remember the current scale and offsets to allow reverting the scaling */
|
2007-03-04 18:27:17 +08:00
|
|
|
|
|
|
|
now = time (NULL);
|
|
|
|
|
|
|
|
if (now - shell->last_scale_time > SCALE_TIMEOUT)
|
|
|
|
{
|
|
|
|
shell->last_scale = gimp_zoom_model_get_factor (shell->zoom);
|
|
|
|
shell->last_offset_x = shell->offset_x;
|
|
|
|
shell->last_offset_y = shell->offset_y;
|
|
|
|
}
|
|
|
|
|
|
|
|
shell->last_scale_time = now;
|
2007-02-07 16:13:44 +08:00
|
|
|
|
2002-02-17 19:46:39 +08:00
|
|
|
/* freeze the active tool */
|
2003-09-12 06:24:30 +08:00
|
|
|
gimp_display_shell_pause (shell);
|
2002-02-17 19:46:39 +08:00
|
|
|
|
2005-09-26 01:03:03 +08:00
|
|
|
gimp_zoom_model_zoom (shell->zoom, GIMP_ZOOM_TO, scale);
|
|
|
|
|
2002-06-27 06:16:59 +08:00
|
|
|
shell->offset_x = offset_x;
|
|
|
|
shell->offset_y = offset_y;
|
2002-02-17 19:46:39 +08:00
|
|
|
|
2008-03-23 23:16:44 +08:00
|
|
|
gimp_display_shell_scale_resize (shell, resize_window, FALSE);
|
2002-02-17 19:46:39 +08:00
|
|
|
|
|
|
|
/* re-enable the active tool */
|
2003-09-12 06:24:30 +08:00
|
|
|
gimp_display_shell_resume (shell);
|
2002-02-17 19:46:39 +08:00
|
|
|
}
|
2001-11-02 17:31:21 +08:00
|
|
|
|
2007-02-09 00:40:46 +08:00
|
|
|
/**
|
|
|
|
* gimp_display_shell_scale_shrink_wrap:
|
2008-03-19 05:22:21 +08:00
|
|
|
* @shell: the #GimpDisplayShell
|
2007-02-09 00:40:46 +08:00
|
|
|
*
|
|
|
|
* Convenience function with the same functionality as
|
2008-03-23 23:16:44 +08:00
|
|
|
* gimp_display_shell_scale_resize(@shell, TRUE, grow_only).
|
2007-02-09 00:40:46 +08:00
|
|
|
**/
|
2002-02-17 19:46:39 +08:00
|
|
|
void
|
2008-03-23 23:16:44 +08:00
|
|
|
gimp_display_shell_scale_shrink_wrap (GimpDisplayShell *shell,
|
|
|
|
gboolean grow_only)
|
2002-02-17 19:46:39 +08:00
|
|
|
{
|
|
|
|
g_return_if_fail (GIMP_IS_DISPLAY_SHELL (shell));
|
2001-11-02 17:31:21 +08:00
|
|
|
|
2008-03-23 23:16:44 +08:00
|
|
|
gimp_display_shell_scale_resize (shell, TRUE, grow_only);
|
2001-11-02 17:31:21 +08:00
|
|
|
}
|
|
|
|
|
2007-02-09 00:40:46 +08:00
|
|
|
/**
|
|
|
|
* gimp_display_shell_scale_resize:
|
|
|
|
* @shell: the #GimpDisplayShell
|
|
|
|
* @resize_window: whether the display window should be resized
|
2008-06-05 00:09:57 +08:00
|
|
|
* @grow_only: whether shrinking of the window is allowed or not
|
2007-02-09 00:40:46 +08:00
|
|
|
*
|
|
|
|
* Function commonly called after a change in display scale to make the changes
|
|
|
|
* visible to the user. If @resize_window is %TRUE then the display window is
|
|
|
|
* resized to accomodate the display image as per
|
|
|
|
* gimp_display_shell_shrink_wrap().
|
|
|
|
**/
|
1997-11-25 06:05:25 +08:00
|
|
|
void
|
2001-11-01 05:20:09 +08:00
|
|
|
gimp_display_shell_scale_resize (GimpDisplayShell *shell,
|
|
|
|
gboolean resize_window,
|
2008-03-23 23:16:44 +08:00
|
|
|
gboolean grow_only)
|
1997-11-25 06:05:25 +08:00
|
|
|
{
|
2001-11-01 05:20:09 +08:00
|
|
|
g_return_if_fail (GIMP_IS_DISPLAY_SHELL (shell));
|
2001-10-13 20:52:30 +08:00
|
|
|
|
|
|
|
/* freeze the active tool */
|
2003-09-12 06:24:30 +08:00
|
|
|
gimp_display_shell_pause (shell);
|
2001-10-13 20:52:30 +08:00
|
|
|
|
|
|
|
if (resize_window)
|
2008-03-23 23:16:44 +08:00
|
|
|
gimp_display_shell_shrink_wrap (shell, grow_only);
|
2001-10-13 20:52:30 +08:00
|
|
|
|
2001-11-01 05:20:09 +08:00
|
|
|
gimp_display_shell_scroll_clamp_offsets (shell);
|
|
|
|
gimp_display_shell_scale_setup (shell);
|
2003-03-22 00:28:06 +08:00
|
|
|
gimp_display_shell_scaled (shell);
|
2001-10-13 20:52:30 +08:00
|
|
|
|
2008-03-23 23:37:01 +08:00
|
|
|
gimp_display_shell_expose_full (shell);
|
2001-10-13 20:52:30 +08:00
|
|
|
|
|
|
|
/* re-enable the active tool */
|
2003-09-12 06:24:30 +08:00
|
|
|
gimp_display_shell_resume (shell);
|
2001-10-13 20:52:30 +08:00
|
|
|
}
|
|
|
|
|
2008-03-19 17:57:22 +08:00
|
|
|
void
|
|
|
|
gimp_display_shell_set_initial_scale (GimpDisplayShell *shell,
|
|
|
|
gdouble scale,
|
|
|
|
gint *display_width,
|
|
|
|
gint *display_height)
|
|
|
|
{
|
|
|
|
GdkScreen *screen;
|
|
|
|
gint image_width;
|
|
|
|
gint image_height;
|
|
|
|
gint shell_width;
|
|
|
|
gint shell_height;
|
|
|
|
gint screen_width;
|
|
|
|
gint screen_height;
|
|
|
|
gdouble new_scale;
|
|
|
|
|
|
|
|
g_return_if_fail (GIMP_IS_DISPLAY_SHELL (shell));
|
|
|
|
|
|
|
|
screen = gtk_widget_get_screen (GTK_WIDGET (shell));
|
|
|
|
|
|
|
|
image_width = gimp_image_get_width (shell->display->image);
|
|
|
|
image_height = gimp_image_get_height (shell->display->image);
|
|
|
|
|
|
|
|
screen_width = gdk_screen_get_width (screen) * 0.75;
|
|
|
|
screen_height = gdk_screen_get_height (screen) * 0.75;
|
|
|
|
|
|
|
|
shell_width = SCALEX (shell, image_width);
|
|
|
|
shell_height = SCALEY (shell, image_height);
|
|
|
|
|
|
|
|
gimp_zoom_model_zoom (shell->zoom, GIMP_ZOOM_TO, scale);
|
|
|
|
|
|
|
|
if (shell->display->config->initial_zoom_to_fit)
|
|
|
|
{
|
|
|
|
/* Limit to the size of the screen... */
|
|
|
|
if (shell_width > screen_width || shell_height > screen_height)
|
|
|
|
{
|
|
|
|
gdouble current = gimp_zoom_model_get_factor (shell->zoom);
|
|
|
|
|
|
|
|
new_scale = current * MIN (((gdouble) screen_height) / shell_height,
|
|
|
|
((gdouble) screen_width) / shell_width);
|
|
|
|
|
|
|
|
new_scale = gimp_zoom_model_zoom_step (GIMP_ZOOM_OUT, new_scale);
|
|
|
|
|
|
|
|
/* Since zooming out might skip a zoom step we zoom in
|
|
|
|
* again and test if we are small enough.
|
|
|
|
*/
|
|
|
|
gimp_zoom_model_zoom (shell->zoom, GIMP_ZOOM_TO,
|
|
|
|
gimp_zoom_model_zoom_step (GIMP_ZOOM_IN,
|
|
|
|
new_scale));
|
|
|
|
|
|
|
|
if (SCALEX (shell, image_width) > screen_width ||
|
|
|
|
SCALEY (shell, image_height) > screen_height)
|
|
|
|
gimp_zoom_model_zoom (shell->zoom, GIMP_ZOOM_TO, new_scale);
|
|
|
|
|
|
|
|
shell_width = SCALEX (shell, image_width);
|
|
|
|
shell_height = SCALEY (shell, image_height);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
/* Set up size like above, but do not zoom to fit. Useful when
|
|
|
|
* working on large images.
|
|
|
|
*/
|
|
|
|
if (shell_width > screen_width)
|
|
|
|
shell_width = screen_width;
|
|
|
|
|
|
|
|
if (shell_height > screen_height)
|
|
|
|
shell_height = screen_height;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (display_width)
|
|
|
|
*display_width = shell_width;
|
|
|
|
|
|
|
|
if (display_height)
|
|
|
|
*display_height = shell_height;
|
|
|
|
}
|
|
|
|
|
2007-02-09 00:40:46 +08:00
|
|
|
/**
|
|
|
|
* gimp_display_shell_scale_dialog:
|
2008-03-19 05:22:21 +08:00
|
|
|
* @shell: the #GimpDisplayShell
|
2007-02-09 00:40:46 +08:00
|
|
|
*
|
|
|
|
* Constructs and displays a dialog allowing the user to enter a custom display
|
|
|
|
* scale.
|
|
|
|
**/
|
2003-04-04 16:32:51 +08:00
|
|
|
void
|
|
|
|
gimp_display_shell_scale_dialog (GimpDisplayShell *shell)
|
|
|
|
{
|
|
|
|
ScaleDialogData *data;
|
2006-09-01 19:26:54 +08:00
|
|
|
GimpImage *image;
|
2003-04-04 16:32:51 +08:00
|
|
|
GtkWidget *hbox;
|
2004-01-30 06:22:29 +08:00
|
|
|
GtkWidget *table;
|
2003-04-04 16:32:51 +08:00
|
|
|
GtkWidget *spin;
|
|
|
|
GtkWidget *label;
|
2004-01-30 06:22:29 +08:00
|
|
|
gint num, denom, row;
|
2003-04-04 16:32:51 +08:00
|
|
|
|
|
|
|
g_return_if_fail (GIMP_IS_DISPLAY_SHELL (shell));
|
|
|
|
|
|
|
|
if (shell->scale_dialog)
|
|
|
|
{
|
|
|
|
gtk_window_present (GTK_WINDOW (shell->scale_dialog));
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2007-02-07 17:12:55 +08:00
|
|
|
if (SCALE_EQUALS (shell->other_scale, 0.0))
|
2005-09-26 01:03:03 +08:00
|
|
|
{
|
|
|
|
/* other_scale not yet initialized */
|
|
|
|
shell->other_scale = gimp_zoom_model_get_factor (shell->zoom);
|
|
|
|
}
|
|
|
|
|
2006-09-01 19:26:54 +08:00
|
|
|
image = shell->display->image;
|
|
|
|
|
2007-05-23 18:22:09 +08:00
|
|
|
data = g_slice_new (ScaleDialogData);
|
2005-09-26 01:03:03 +08:00
|
|
|
|
2003-04-04 16:32:51 +08:00
|
|
|
data->shell = shell;
|
2005-09-26 01:03:03 +08:00
|
|
|
data->model = g_object_new (GIMP_TYPE_ZOOM_MODEL,
|
|
|
|
"value", fabs (shell->other_scale),
|
|
|
|
NULL);
|
2003-04-04 16:32:51 +08:00
|
|
|
|
|
|
|
shell->scale_dialog =
|
2006-09-01 19:26:54 +08:00
|
|
|
gimp_viewable_dialog_new (GIMP_VIEWABLE (image),
|
2008-03-19 05:22:21 +08:00
|
|
|
gimp_get_user_context (shell->display->gimp),
|
2003-04-04 16:32:51 +08:00
|
|
|
_("Zoom Ratio"), "display_scale",
|
|
|
|
GTK_STOCK_ZOOM_100,
|
|
|
|
_("Select Zoom Ratio"),
|
2003-11-08 23:29:47 +08:00
|
|
|
GTK_WIDGET (shell),
|
2003-04-04 16:32:51 +08:00
|
|
|
gimp_standard_help_func,
|
2003-08-24 21:52:51 +08:00
|
|
|
GIMP_HELP_VIEW_ZOOM_OTHER,
|
2003-05-05 23:33:11 +08:00
|
|
|
|
2003-11-06 23:27:05 +08:00
|
|
|
GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
|
|
|
|
GTK_STOCK_OK, GTK_RESPONSE_OK,
|
2003-04-04 16:32:51 +08:00
|
|
|
|
|
|
|
NULL);
|
|
|
|
|
2005-02-10 19:00:46 +08:00
|
|
|
gtk_dialog_set_alternative_button_order (GTK_DIALOG (shell->scale_dialog),
|
|
|
|
GTK_RESPONSE_OK,
|
|
|
|
GTK_RESPONSE_CANCEL,
|
|
|
|
-1);
|
|
|
|
|
2003-04-04 16:32:51 +08:00
|
|
|
g_object_weak_ref (G_OBJECT (shell->scale_dialog),
|
2007-05-23 18:22:09 +08:00
|
|
|
(GWeakNotify) gimp_display_shell_scale_dialog_free, data);
|
2005-09-26 01:03:03 +08:00
|
|
|
g_object_weak_ref (G_OBJECT (shell->scale_dialog),
|
|
|
|
(GWeakNotify) g_object_unref, data->model);
|
|
|
|
|
2003-04-04 16:32:51 +08:00
|
|
|
g_object_add_weak_pointer (G_OBJECT (shell->scale_dialog),
|
2006-06-20 01:50:40 +08:00
|
|
|
(gpointer) &shell->scale_dialog);
|
2003-04-04 16:32:51 +08:00
|
|
|
|
|
|
|
gtk_window_set_transient_for (GTK_WINDOW (shell->scale_dialog),
|
|
|
|
GTK_WINDOW (shell));
|
|
|
|
gtk_window_set_destroy_with_parent (GTK_WINDOW (shell->scale_dialog), TRUE);
|
|
|
|
|
2003-11-06 23:27:05 +08:00
|
|
|
g_signal_connect (shell->scale_dialog, "response",
|
|
|
|
G_CALLBACK (gimp_display_shell_scale_dialog_response),
|
|
|
|
data);
|
|
|
|
|
2004-01-30 06:22:29 +08:00
|
|
|
table = gtk_table_new (2, 2, FALSE);
|
2004-06-03 01:56:02 +08:00
|
|
|
gtk_container_set_border_width (GTK_CONTAINER (table), 12);
|
|
|
|
gtk_table_set_col_spacings (GTK_TABLE (table), 6);
|
|
|
|
gtk_table_set_row_spacings (GTK_TABLE (table), 6);
|
2004-01-30 06:22:29 +08:00
|
|
|
gtk_container_add (GTK_CONTAINER (GTK_DIALOG (shell->scale_dialog)->vbox),
|
|
|
|
table);
|
|
|
|
gtk_widget_show (table);
|
|
|
|
|
|
|
|
row = 0;
|
|
|
|
|
2004-06-03 01:56:02 +08:00
|
|
|
hbox = gtk_hbox_new (FALSE, 6);
|
2004-01-30 06:22:29 +08:00
|
|
|
gimp_table_attach_aligned (GTK_TABLE (table), 0, row++,
|
2005-08-23 07:39:12 +08:00
|
|
|
_("Zoom ratio:"), 0.0, 0.5,
|
2004-01-30 06:22:29 +08:00
|
|
|
hbox, 1, FALSE);
|
2003-04-04 16:32:51 +08:00
|
|
|
|
2005-09-26 01:03:03 +08:00
|
|
|
gimp_zoom_model_get_fraction (data->model, &num, &denom);
|
2003-04-04 16:32:51 +08:00
|
|
|
|
2004-01-30 06:22:29 +08:00
|
|
|
spin = gimp_spin_button_new (&data->num_adj,
|
|
|
|
num, 1, 256,
|
2003-04-04 16:32:51 +08:00
|
|
|
1, 8, 1, 1, 0);
|
2005-09-25 02:45:02 +08:00
|
|
|
gtk_entry_set_activates_default (GTK_ENTRY (spin), TRUE);
|
2003-04-04 16:32:51 +08:00
|
|
|
gtk_box_pack_start (GTK_BOX (hbox), spin, TRUE, TRUE, 0);
|
|
|
|
gtk_widget_show (spin);
|
|
|
|
|
|
|
|
label = gtk_label_new (":");
|
|
|
|
gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 0);
|
|
|
|
gtk_widget_show (label);
|
2003-05-05 23:33:11 +08:00
|
|
|
|
2004-01-30 06:22:29 +08:00
|
|
|
spin = gimp_spin_button_new (&data->denom_adj,
|
|
|
|
denom, 1, 256,
|
2003-04-04 16:32:51 +08:00
|
|
|
1, 8, 1, 1, 0);
|
2005-09-25 02:45:02 +08:00
|
|
|
gtk_entry_set_activates_default (GTK_ENTRY (spin), TRUE);
|
2003-04-04 16:32:51 +08:00
|
|
|
gtk_box_pack_start (GTK_BOX (hbox), spin, TRUE, TRUE, 0);
|
|
|
|
gtk_widget_show (spin);
|
|
|
|
|
2004-06-03 01:56:02 +08:00
|
|
|
hbox = gtk_hbox_new (FALSE, 6);
|
2004-02-03 23:51:25 +08:00
|
|
|
gimp_table_attach_aligned (GTK_TABLE (table), 0, row++,
|
2004-05-12 19:37:21 +08:00
|
|
|
_("Zoom:"), 0.0, 0.5,
|
2004-02-03 23:51:25 +08:00
|
|
|
hbox, 1, FALSE);
|
|
|
|
|
2004-01-30 06:22:29 +08:00
|
|
|
spin = gimp_spin_button_new (&data->scale_adj,
|
|
|
|
fabs (shell->other_scale) * 100,
|
|
|
|
100.0 / 256.0, 25600.0,
|
|
|
|
10, 50, 0, 1, 2);
|
2005-09-25 02:45:02 +08:00
|
|
|
gtk_entry_set_activates_default (GTK_ENTRY (spin), TRUE);
|
2004-02-03 23:51:25 +08:00
|
|
|
gtk_box_pack_start (GTK_BOX (hbox), spin, TRUE, TRUE, 0);
|
|
|
|
gtk_widget_show (spin);
|
|
|
|
|
|
|
|
label = gtk_label_new ("%");
|
|
|
|
gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 0);
|
|
|
|
gtk_widget_show (label);
|
2004-01-30 06:22:29 +08:00
|
|
|
|
|
|
|
g_signal_connect (data->scale_adj, "value-changed",
|
|
|
|
G_CALLBACK (update_zoom_values), data);
|
|
|
|
g_signal_connect (data->num_adj, "value-changed",
|
|
|
|
G_CALLBACK (update_zoom_values), data);
|
|
|
|
g_signal_connect (data->denom_adj, "value-changed",
|
|
|
|
G_CALLBACK (update_zoom_values), data);
|
|
|
|
|
2003-04-04 16:32:51 +08:00
|
|
|
gtk_widget_show (shell->scale_dialog);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2001-10-13 20:52:30 +08:00
|
|
|
/* private functions */
|
|
|
|
|
2003-04-04 16:32:51 +08:00
|
|
|
static void
|
2003-11-06 23:27:05 +08:00
|
|
|
gimp_display_shell_scale_dialog_response (GtkWidget *widget,
|
|
|
|
gint response_id,
|
|
|
|
ScaleDialogData *dialog)
|
2003-04-04 16:32:51 +08:00
|
|
|
{
|
2003-11-06 23:27:05 +08:00
|
|
|
if (response_id == GTK_RESPONSE_OK)
|
|
|
|
{
|
2004-01-30 06:22:29 +08:00
|
|
|
gdouble scale;
|
2003-04-04 16:32:51 +08:00
|
|
|
|
2004-01-30 06:22:29 +08:00
|
|
|
scale = gtk_adjustment_get_value (GTK_ADJUSTMENT (dialog->scale_adj));
|
2003-04-04 16:32:51 +08:00
|
|
|
|
2004-01-30 06:22:29 +08:00
|
|
|
gimp_display_shell_scale (dialog->shell, GIMP_ZOOM_TO, scale / 100.0);
|
2003-11-06 23:27:05 +08:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
/* need to emit "scaled" to get the menu updated */
|
|
|
|
gimp_display_shell_scaled (dialog->shell);
|
|
|
|
}
|
2003-04-04 16:32:51 +08:00
|
|
|
|
2004-01-30 06:22:29 +08:00
|
|
|
dialog->shell->other_scale = - fabs (dialog->shell->other_scale);
|
2003-04-04 16:32:51 +08:00
|
|
|
|
|
|
|
gtk_widget_destroy (dialog->shell->scale_dialog);
|
|
|
|
}
|
|
|
|
|
2007-05-23 18:22:09 +08:00
|
|
|
static void
|
|
|
|
gimp_display_shell_scale_dialog_free (ScaleDialogData *dialog)
|
|
|
|
{
|
|
|
|
g_slice_free (ScaleDialogData, dialog);
|
|
|
|
}
|
2003-04-04 16:32:51 +08:00
|
|
|
|
2004-01-30 06:22:29 +08:00
|
|
|
static void
|
|
|
|
update_zoom_values (GtkAdjustment *adj,
|
|
|
|
ScaleDialogData *dialog)
|
|
|
|
{
|
2005-09-26 01:03:03 +08:00
|
|
|
gint num, denom;
|
2004-01-30 06:22:29 +08:00
|
|
|
gdouble scale;
|
2004-02-03 23:51:25 +08:00
|
|
|
|
2004-01-30 06:22:29 +08:00
|
|
|
g_signal_handlers_block_by_func (GTK_ADJUSTMENT (dialog->scale_adj),
|
|
|
|
G_CALLBACK (update_zoom_values),
|
|
|
|
dialog);
|
2004-02-03 23:51:25 +08:00
|
|
|
|
2004-01-30 06:22:29 +08:00
|
|
|
g_signal_handlers_block_by_func (GTK_ADJUSTMENT (dialog->num_adj),
|
|
|
|
G_CALLBACK (update_zoom_values),
|
|
|
|
dialog);
|
2004-02-03 23:51:25 +08:00
|
|
|
|
2004-01-30 06:22:29 +08:00
|
|
|
g_signal_handlers_block_by_func (GTK_ADJUSTMENT (dialog->denom_adj),
|
|
|
|
G_CALLBACK (update_zoom_values),
|
|
|
|
dialog);
|
2004-02-03 23:51:25 +08:00
|
|
|
|
2004-01-30 06:22:29 +08:00
|
|
|
if (GTK_OBJECT (adj) == dialog->scale_adj)
|
|
|
|
{
|
|
|
|
scale = gtk_adjustment_get_value (GTK_ADJUSTMENT (dialog->scale_adj));
|
|
|
|
|
2005-09-26 01:03:03 +08:00
|
|
|
gimp_zoom_model_zoom (dialog->model, GIMP_ZOOM_TO, scale / 100.0);
|
|
|
|
gimp_zoom_model_get_fraction (dialog->model, &num, &denom);
|
2004-01-30 06:22:29 +08:00
|
|
|
|
|
|
|
gtk_adjustment_set_value (GTK_ADJUSTMENT (dialog->num_adj), num);
|
|
|
|
gtk_adjustment_set_value (GTK_ADJUSTMENT (dialog->denom_adj), denom);
|
|
|
|
}
|
|
|
|
else /* fraction adjustments */
|
|
|
|
{
|
|
|
|
scale = (gtk_adjustment_get_value (GTK_ADJUSTMENT (dialog->num_adj)) /
|
|
|
|
gtk_adjustment_get_value (GTK_ADJUSTMENT (dialog->denom_adj)));
|
|
|
|
gtk_adjustment_set_value (GTK_ADJUSTMENT (dialog->scale_adj),
|
|
|
|
scale * 100);
|
|
|
|
}
|
|
|
|
|
|
|
|
g_signal_handlers_unblock_by_func (GTK_ADJUSTMENT (dialog->scale_adj),
|
|
|
|
G_CALLBACK (update_zoom_values),
|
|
|
|
dialog);
|
2004-02-03 23:51:25 +08:00
|
|
|
|
2004-01-30 06:22:29 +08:00
|
|
|
g_signal_handlers_unblock_by_func (GTK_ADJUSTMENT (dialog->num_adj),
|
|
|
|
G_CALLBACK (update_zoom_values),
|
|
|
|
dialog);
|
2004-02-03 23:51:25 +08:00
|
|
|
|
2004-01-30 06:22:29 +08:00
|
|
|
g_signal_handlers_unblock_by_func (GTK_ADJUSTMENT (dialog->denom_adj),
|
|
|
|
G_CALLBACK (update_zoom_values),
|
|
|
|
dialog);
|
|
|
|
}
|
|
|
|
|
2001-10-13 20:52:30 +08:00
|
|
|
/* scale image coord to realworld units (cm, inches, pixels)
|
|
|
|
*
|
|
|
|
* 27/Feb/1999 I tried inlining this, but the result was slightly
|
|
|
|
* slower (poorer cache locality, probably) -- austin
|
|
|
|
*/
|
|
|
|
static gdouble
|
2002-06-27 06:16:59 +08:00
|
|
|
img2real (GimpDisplayShell *shell,
|
2004-10-07 18:12:26 +08:00
|
|
|
gboolean xdir,
|
|
|
|
gdouble len)
|
2001-10-13 20:52:30 +08:00
|
|
|
{
|
2008-03-19 05:22:21 +08:00
|
|
|
gdouble xres;
|
|
|
|
gdouble yres;
|
|
|
|
gdouble res;
|
2001-10-13 20:52:30 +08:00
|
|
|
|
2004-06-02 06:04:20 +08:00
|
|
|
if (shell->unit == GIMP_UNIT_PIXEL)
|
2003-10-02 01:32:14 +08:00
|
|
|
return len;
|
2001-10-13 20:52:30 +08:00
|
|
|
|
2008-03-19 05:22:21 +08:00
|
|
|
gimp_image_get_resolution (shell->display->image, &xres, &yres);
|
2007-12-27 01:33:41 +08:00
|
|
|
|
2001-10-13 20:52:30 +08:00
|
|
|
if (xdir)
|
2007-12-27 01:33:41 +08:00
|
|
|
res = xres;
|
2001-10-13 20:52:30 +08:00
|
|
|
else
|
2007-12-27 01:33:41 +08:00
|
|
|
res = yres;
|
2001-10-13 20:52:30 +08:00
|
|
|
|
2008-03-19 05:22:21 +08:00
|
|
|
return len * _gimp_unit_get_factor (shell->display->gimp, shell->unit) / res;
|
2001-10-13 20:52:30 +08:00
|
|
|
}
|