libgimpwidgets/gimpwidgets.def added gimp_zoom_model_zoom() and changed

2005-09-25  Sven Neumann  <sven@gimp.org>

	* libgimpwidgets/gimpwidgets.def
	* libgimpwidgets/gimpzoommodel.[ch]: added gimp_zoom_model_zoom()
	and changed gimp_zoom_model_get_fraction() to take a model instead
	of the zoom factor.

	* app/display/gimpdisplayshell.[ch]: use a GimpZoomModel for the
	display scale factor.

	* app/actions/image-commands.c
	* app/actions/view-actions.c
	* app/actions/view-commands.c
	* app/display/gimpdisplayshell-callbacks.c
	* app/display/gimpdisplayshell-scale.c
	* app/display/gimpdisplayshell-title.c
	* app/display/gimpnavigationeditor.c
	* app/display/gimpstatusbar.c
	* app/tools/gimpeditselectiontool.c
	* app/tools/gimpmagnifytool.c: changed accordingly.
This commit is contained in:
Sven Neumann 2005-09-25 17:03:03 +00:00 committed by Sven Neumann
parent 13041a7ebd
commit 1f0aff2b09
16 changed files with 273 additions and 218 deletions

View File

@ -1,3 +1,24 @@
2005-09-25 Sven Neumann <sven@gimp.org>
* libgimpwidgets/gimpwidgets.def
* libgimpwidgets/gimpzoommodel.[ch]: added gimp_zoom_model_zoom()
and changed gimp_zoom_model_get_fraction() to take a model instead
of the zoom factor.
* app/display/gimpdisplayshell.[ch]: use a GimpZoomModel for the
display scale factor.
* app/actions/image-commands.c
* app/actions/view-actions.c
* app/actions/view-commands.c
* app/display/gimpdisplayshell-callbacks.c
* app/display/gimpdisplayshell-scale.c
* app/display/gimpdisplayshell-title.c
* app/display/gimpnavigationeditor.c
* app/display/gimpstatusbar.c
* app/tools/gimpeditselectiontool.c
* app/tools/gimpmagnifytool.c: changed accordingly.
2005-09-25 Karine Delvare <kdelvare@nerim.net> 2005-09-25 Karine Delvare <kdelvare@nerim.net>
* app/tools/gimpcroptool.c: fixed assignment of local variable * app/tools/gimpcroptool.c: fixed assignment of local variable

View File

@ -362,7 +362,8 @@ image_duplicate_cmd_callback (GtkAction *action,
gimp_create_display (new_gimage->gimp, gimp_create_display (new_gimage->gimp,
new_gimage, new_gimage,
shell->unit, shell->scale); shell->unit,
gimp_zoom_model_get_factor (shell->zoom));
g_object_unref (new_gimage); g_object_unref (new_gimage);
} }

View File

@ -588,11 +588,15 @@ view_actions_set_zoom (GimpActionGroup *group,
GimpDisplayShell *shell) GimpDisplayShell *shell)
{ {
const gchar *action = NULL; const gchar *action = NULL;
guint scale; gchar *str;
gchar buf[16];
gchar *label; gchar *label;
guint scale;
scale = ROUND (shell->scale * 1000); g_object_get (shell->zoom,
"percentage", &str,
NULL);
scale = ROUND (gimp_zoom_model_get_factor (shell->zoom) * 1000);
switch (scale) switch (scale)
{ {
@ -608,29 +612,27 @@ view_actions_set_zoom (GimpActionGroup *group,
case 62: action = "view-zoom-1-16"; break; case 62: action = "view-zoom-1-16"; break;
} }
g_snprintf (buf, sizeof (buf), if (! action)
shell->scale >= 0.15 ? "%.0f%%" : "%.2f%%",
shell->scale * 100.0);
if (!action)
{ {
action = "view-zoom-other"; action = "view-zoom-other";
label = g_strdup_printf (_("Othe_r (%s) ..."), buf); label = g_strdup_printf (_("Othe_r (%s) ..."), str);
gimp_action_group_set_action_label (group, action, label); gimp_action_group_set_action_label (group, action, label);
g_free (label); g_free (label);
shell->other_scale = shell->scale; shell->other_scale = gimp_zoom_model_get_factor (shell->zoom);
} }
gimp_action_group_set_action_active (group, action, TRUE); gimp_action_group_set_action_active (group, action, TRUE);
label = g_strdup_printf (_("_Zoom (%s)"), buf); label = g_strdup_printf (_("_Zoom (%s)"), str);
gimp_action_group_set_action_label (group, "view-zoom-menu", label); gimp_action_group_set_action_label (group, "view-zoom-menu", label);
g_free (label); g_free (label);
/* flag as dirty */ /* flag as dirty */
shell->other_scale = - fabs (shell->other_scale); shell->other_scale = - fabs (shell->other_scale);
g_free (str);
} }
static void static void

View File

@ -85,7 +85,7 @@ view_new_cmd_callback (GtkAction *action,
gimp_create_display (gdisp->gimage->gimp, gimp_create_display (gdisp->gimage->gimp,
gdisp->gimage, gdisp->gimage,
shell->unit, shell->scale); shell->unit, gimp_zoom_model_get_factor (shell->zoom));
} }
void void
@ -125,13 +125,10 @@ view_zoom_cmd_callback (GtkAction *action,
{ {
GimpDisplay *gdisp; GimpDisplay *gdisp;
GimpDisplayShell *shell; GimpDisplayShell *shell;
gdouble scale;
return_if_no_display (gdisp, data); return_if_no_display (gdisp, data);
shell = GIMP_DISPLAY_SHELL (gdisp->shell); shell = GIMP_DISPLAY_SHELL (gdisp->shell);
scale = shell->scale;
switch ((GimpActionSelectType) value) switch ((GimpActionSelectType) value)
{ {
case GIMP_ACTION_SELECT_FIRST: case GIMP_ACTION_SELECT_FIRST:
@ -159,18 +156,22 @@ view_zoom_cmd_callback (GtkAction *action,
break; break;
default: default:
scale = action_select_value ((GimpActionSelectType) value, {
scale, gdouble scale = gimp_zoom_model_get_factor (shell->zoom);
0.0, 512.0,
1.0, 16.0,
FALSE);
/* min = 1.0 / 256, max = 256.0 */ scale = action_select_value ((GimpActionSelectType) value,
/* scale = min * (max / min)**(i/n), i = 0..n */ scale,
scale = pow (65536.0, scale / 512.0) / 256.0; 0.0, 512.0,
1.0, 16.0,
FALSE);
gimp_display_shell_scale (shell, GIMP_ZOOM_TO, scale); /* min = 1.0 / 256, max = 256.0 */
break; /* scale = min * (max / min)**(i/n), i = 0..n */
scale = pow (65536.0, scale / 512.0) / 256.0;
gimp_display_shell_scale (shell, GIMP_ZOOM_TO, scale);
break;
}
} }
} }
@ -190,7 +191,7 @@ view_zoom_explicit_cmd_callback (GtkAction *action,
if (value != 0 /* not Other... */) if (value != 0 /* not Other... */)
{ {
if (fabs (value - shell->scale) > 0.0001) if (fabs (value - gimp_zoom_model_get_factor (shell->zoom)) > 0.0001)
gimp_display_shell_scale (shell, GIMP_ZOOM_TO, (gdouble) value / 10000); gimp_display_shell_scale (shell, GIMP_ZOOM_TO, (gdouble) value / 10000);
} }
} }
@ -209,7 +210,7 @@ view_zoom_other_cmd_callback (GtkAction *action,
* view_actions_set_zoom() * view_actions_set_zoom()
*/ */
if (gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action)) && if (gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action)) &&
shell->scale != shell->other_scale) shell->other_scale != gimp_zoom_model_get_factor (shell->zoom))
{ {
gimp_display_shell_scale_dialog (shell); gimp_display_shell_scale_dialog (shell);
} }

View File

@ -321,7 +321,7 @@ gimp_display_shell_canvas_size_allocate (GtkWidget *widget,
allocation->width > 64 && allocation->width > 64 &&
allocation->height > 64) allocation->height > 64)
{ {
gdouble scale = shell->scale; gdouble scale = gimp_zoom_model_get_factor (shell->zoom);
gint offset_x; gint offset_x;
gint offset_y; gint offset_y;
@ -336,7 +336,8 @@ gimp_display_shell_canvas_size_allocate (GtkWidget *widget,
offset_x = UNSCALEX (shell, shell->offset_x); offset_x = UNSCALEX (shell, shell->offset_x);
offset_y = UNSCALEX (shell, shell->offset_y); offset_y = UNSCALEX (shell, shell->offset_y);
shell->scale = scale; gimp_zoom_model_zoom (shell->zoom, GIMP_ZOOM_TO, scale);
shell->offset_x = SCALEX (shell, offset_x); shell->offset_x = SCALEX (shell, offset_x);
shell->offset_y = SCALEY (shell, offset_y); shell->offset_y = SCALEY (shell, offset_y);
} }

View File

@ -49,6 +49,7 @@ typedef struct _ScaleDialogData ScaleDialogData;
struct _ScaleDialogData struct _ScaleDialogData
{ {
GimpDisplayShell *shell; GimpDisplayShell *shell;
GimpZoomModel *model;
GtkObject *scale_adj; GtkObject *scale_adj;
GtkObject *num_adj; GtkObject *num_adj;
GtkObject *denom_adj; GtkObject *denom_adj;
@ -280,6 +281,7 @@ gimp_display_shell_scale_to (GimpDisplayShell *shell,
gdouble y) gdouble y)
{ {
GimpDisplayConfig *config; GimpDisplayConfig *config;
gdouble current;
gdouble offset_x; gdouble offset_x;
gdouble offset_y; gdouble offset_y;
@ -288,14 +290,16 @@ gimp_display_shell_scale_to (GimpDisplayShell *shell,
if (! shell->gdisp) if (! shell->gdisp)
return; return;
current = gimp_zoom_model_get_factor (shell->zoom);
offset_x = shell->offset_x + x; offset_x = shell->offset_x + x;
offset_y = shell->offset_y + y; offset_y = shell->offset_y + y;
offset_x /= shell->scale; offset_x /= current;
offset_y /= shell->scale; offset_y /= current;
if (zoom_type != GIMP_ZOOM_TO) if (zoom_type != GIMP_ZOOM_TO)
scale = gimp_zoom_model_zoom_step (zoom_type, shell->scale); scale = gimp_zoom_model_zoom_step (zoom_type, current);
offset_x *= scale; offset_x *= scale;
offset_y *= scale; offset_y *= scale;
@ -377,15 +381,16 @@ gimp_display_shell_scale_by_values (GimpDisplayShell *shell,
/* Abort early if the values are all setup already. We don't /* Abort early if the values are all setup already. We don't
* want to inadvertently resize the window (bug #164281). * want to inadvertently resize the window (bug #164281).
*/ */
if (shell->scale == scale && if (gimp_zoom_model_get_factor (shell->zoom) == scale &&
shell->offset_x == offset_x && shell->offset_x == offset_x &&
shell->offset_y == offset_y) shell->offset_y == offset_y)
return; return;
/* freeze the active tool */ /* freeze the active tool */
gimp_display_shell_pause (shell); gimp_display_shell_pause (shell);
shell->scale = scale; gimp_zoom_model_zoom (shell->zoom, GIMP_ZOOM_TO, scale);
shell->offset_x = offset_x; shell->offset_x = offset_x;
shell->offset_y = offset_y; shell->offset_y = offset_y;
@ -449,8 +454,18 @@ gimp_display_shell_scale_dialog (GimpDisplayShell *shell)
return; return;
} }
if (fabs (shell->other_scale) <= 0.0001)
{
/* other_scale not yet initialized */
shell->other_scale = gimp_zoom_model_get_factor (shell->zoom);
}
data = g_new (ScaleDialogData, 1); data = g_new (ScaleDialogData, 1);
data->shell = shell; data->shell = shell;
data->model = g_object_new (GIMP_TYPE_ZOOM_MODEL,
"value", fabs (shell->other_scale),
NULL);
shell->scale_dialog = shell->scale_dialog =
gimp_viewable_dialog_new (GIMP_VIEWABLE (shell->gdisp->gimage), gimp_viewable_dialog_new (GIMP_VIEWABLE (shell->gdisp->gimage),
@ -473,6 +488,9 @@ gimp_display_shell_scale_dialog (GimpDisplayShell *shell)
g_object_weak_ref (G_OBJECT (shell->scale_dialog), g_object_weak_ref (G_OBJECT (shell->scale_dialog),
(GWeakNotify) g_free, data); (GWeakNotify) g_free, data);
g_object_weak_ref (G_OBJECT (shell->scale_dialog),
(GWeakNotify) g_object_unref, data->model);
g_object_add_weak_pointer (G_OBJECT (shell->scale_dialog), g_object_add_weak_pointer (G_OBJECT (shell->scale_dialog),
(gpointer *) &shell->scale_dialog); (gpointer *) &shell->scale_dialog);
@ -499,11 +517,7 @@ gimp_display_shell_scale_dialog (GimpDisplayShell *shell)
_("Zoom ratio:"), 0.0, 0.5, _("Zoom ratio:"), 0.0, 0.5,
hbox, 1, FALSE); hbox, 1, FALSE);
if (fabs (shell->other_scale) <= 0.0001) gimp_zoom_model_get_fraction (data->model, &num, &denom);
shell->other_scale = shell->scale; /* other_scale not yet initialized */
gimp_zoom_model_get_fraction (fabs (shell->other_scale),
&num, &denom);
spin = gimp_spin_button_new (&data->num_adj, spin = gimp_spin_button_new (&data->num_adj,
num, 1, 256, num, 1, 256,
@ -582,7 +596,7 @@ static void
update_zoom_values (GtkAdjustment *adj, update_zoom_values (GtkAdjustment *adj,
ScaleDialogData *dialog) ScaleDialogData *dialog)
{ {
gint num, denom; gint num, denom;
gdouble scale; gdouble scale;
g_signal_handlers_block_by_func (GTK_ADJUSTMENT (dialog->scale_adj), g_signal_handlers_block_by_func (GTK_ADJUSTMENT (dialog->scale_adj),
@ -601,7 +615,8 @@ update_zoom_values (GtkAdjustment *adj,
{ {
scale = gtk_adjustment_get_value (GTK_ADJUSTMENT (dialog->scale_adj)); scale = gtk_adjustment_get_value (GTK_ADJUSTMENT (dialog->scale_adj));
gimp_zoom_model_get_fraction (scale / 100.0, &num, &denom); gimp_zoom_model_zoom (dialog->model, GIMP_ZOOM_TO, scale / 100.0);
gimp_zoom_model_get_fraction (dialog->model, &num, &denom);
gtk_adjustment_set_value (GTK_ADJUSTMENT (dialog->num_adj), num); gtk_adjustment_set_value (GTK_ADJUSTMENT (dialog->num_adj), num);
gtk_adjustment_set_value (GTK_ADJUSTMENT (dialog->denom_adj), denom); gtk_adjustment_set_value (GTK_ADJUSTMENT (dialog->denom_adj), denom);

View File

@ -162,7 +162,7 @@ gimp_display_shell_format_title (GimpDisplayShell *shell,
image = shell->gdisp->gimage; image = shell->gdisp->gimage;
gimp = image->gimp; gimp = image->gimp;
gimp_zoom_model_get_fraction (shell->scale, &num, &denom); gimp_zoom_model_get_fraction (shell->zoom, &num, &denom);
while (i < title_len && *format) while (i < title_len && *format)
{ {
@ -247,9 +247,12 @@ gimp_display_shell_format_title (GimpDisplayShell *shell,
break; break;
case 'z': /* user zoom factor (percentage) */ case 'z': /* user zoom factor (percentage) */
i += print (title, title_len, i, {
shell->scale >= 0.15 ? "%.0f" : "%.2f", gdouble scale = gimp_zoom_model_get_factor (shell->zoom);
100 * shell->scale);
i += print (title, title_len, i,
scale >= 0.15 ? "%.0f" : "%.2f", 100.0 * scale);
}
break; break;
case 'D': /* dirty flag */ case 'D': /* dirty flag */
@ -278,14 +281,12 @@ gimp_display_shell_format_title (GimpDisplayShell *shell,
case 'B': /* dirty flag (long) */ case 'B': /* dirty flag (long) */
if (image->dirty) if (image->dirty)
i += print (title, title_len, i, "%s", i += print (title, title_len, i, "%s", _("(modified)"));
_("(modified)"));
break; break;
case 'A': /* clean flag (long) */ case 'A': /* clean flag (long) */
if (! image->dirty) if (! image->dirty)
i += print (title, title_len, i, "%s", i += print (title, title_len, i, "%s", _("(clean)"));
_("(clean)"));
break; break;
case 'm': /* memory used by image */ case 'm': /* memory used by image */

View File

@ -74,7 +74,6 @@
enum enum
{ {
PROP_0, PROP_0,
PROP_SCALE,
PROP_UNIT PROP_UNIT
}; };
@ -208,11 +207,6 @@ gimp_display_shell_class_init (GimpDisplayShellClass *klass)
klass->scrolled = NULL; klass->scrolled = NULL;
klass->reconnect = NULL; klass->reconnect = NULL;
g_object_class_install_property (object_class, PROP_SCALE,
g_param_spec_double ("scale", NULL, NULL,
1.0 / 256, 256, 1.0,
G_PARAM_READWRITE));
g_object_class_install_property (object_class, PROP_UNIT, g_object_class_install_property (object_class, PROP_UNIT,
gimp_param_spec_unit ("unit", NULL, NULL, gimp_param_spec_unit ("unit", NULL, NULL,
TRUE, FALSE, TRUE, FALSE,
@ -232,7 +226,7 @@ gimp_display_shell_init (GimpDisplayShell *shell)
shell->unit = GIMP_UNIT_PIXEL; shell->unit = GIMP_UNIT_PIXEL;
shell->scale = 1.0; shell->zoom = gimp_zoom_model_new ();
shell->other_scale = 0.0; shell->other_scale = 0.0;
shell->dot_for_dot = TRUE; shell->dot_for_dot = TRUE;
@ -358,6 +352,8 @@ gimp_display_shell_finalize (GObject *object)
{ {
GimpDisplayShell *shell = GIMP_DISPLAY_SHELL (object); GimpDisplayShell *shell = GIMP_DISPLAY_SHELL (object);
g_object_unref (shell->zoom);
if (shell->options) if (shell->options)
g_object_unref (shell->options); g_object_unref (shell->options);
@ -449,16 +445,10 @@ gimp_display_shell_set_property (GObject *object,
switch (property_id) switch (property_id)
{ {
case PROP_SCALE:
if (shell->canvas)
gimp_display_shell_scale (shell,
GIMP_ZOOM_TO, g_value_get_double (value));
else
shell->scale = g_value_get_double (value);
break;
case PROP_UNIT: case PROP_UNIT:
gimp_display_shell_set_unit (shell, g_value_get_int (value)); gimp_display_shell_set_unit (shell, g_value_get_int (value));
break; break;
default: default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
break; break;
@ -475,12 +465,10 @@ gimp_display_shell_get_property (GObject *object,
switch (property_id) switch (property_id)
{ {
case PROP_SCALE:
g_value_set_double (value, shell->scale);
break;
case PROP_UNIT: case PROP_UNIT:
g_value_set_int (value, shell->unit); g_value_set_int (value, shell->unit);
break; break;
default: default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
break; break;
@ -602,9 +590,10 @@ gimp_display_shell_new (GimpDisplay *gdisp,
shell = g_object_new (GIMP_TYPE_DISPLAY_SHELL, shell = g_object_new (GIMP_TYPE_DISPLAY_SHELL,
"gravity", GDK_GRAVITY_CENTER, "gravity", GDK_GRAVITY_CENTER,
"unit", unit, "unit", unit,
"scale", scale,
NULL); NULL);
gimp_zoom_model_zoom (shell->zoom, GIMP_ZOOM_TO, scale);
shell->gdisp = gdisp; shell->gdisp = gdisp;
image_width = gdisp->gimage->width; image_width = gdisp->gimage->width;
@ -647,18 +636,23 @@ gimp_display_shell_new (GimpDisplay *gdisp,
/* Limit to the size of the screen... */ /* Limit to the size of the screen... */
if (n_width > s_width || n_height > s_height) if (n_width > s_width || n_height > s_height)
{ {
new_scale = shell->scale * MIN (((gdouble) s_height) / n_height, gdouble current = gimp_zoom_model_get_factor (shell->zoom);
((gdouble) s_width) / n_width);
new_scale = current * MIN (((gdouble) s_height) / n_height,
((gdouble) s_width) / n_width);
new_scale = gimp_zoom_model_zoom_step (GIMP_ZOOM_OUT, new_scale); new_scale = gimp_zoom_model_zoom_step (GIMP_ZOOM_OUT, new_scale);
/* since zooming out might skip a zoom step we zoom in again /* Since zooming out might skip a zoom step we zoom in again
* and test if we are small enough. */ * and test if we are small enough.
shell->scale = gimp_zoom_model_zoom_step (GIMP_ZOOM_IN, new_scale); */
gimp_zoom_model_zoom (shell->zoom, GIMP_ZOOM_TO,
gimp_zoom_model_zoom_step (GIMP_ZOOM_IN,
new_scale));
if (SCALEX (shell, image_width) > s_width || if (SCALEX (shell, image_width) > s_width ||
SCALEY (shell, image_height) > s_height) SCALEY (shell, image_height) > s_height)
shell->scale = new_scale; gimp_zoom_model_zoom (shell->zoom, GIMP_ZOOM_TO, new_scale);
n_width = SCALEX (shell, image_width); n_width = SCALEX (shell, image_width);
n_height = SCALEY (shell, image_height); n_height = SCALEY (shell, image_height);

View File

@ -22,32 +22,34 @@
#include <gtk/gtkwindow.h> #include <gtk/gtkwindow.h>
#include "libgimpwidgets/gimpwidgets.h"
/* Apply to a float the same rounding mode used in the renderer */ /* Apply to a float the same rounding mode used in the renderer */
#define PROJ_ROUND(coord) ((gint) ceil (coord)) #define PROJ_ROUND(coord) ((gint) ceil (coord))
/* finding the effective screen resolution (double) */ /* finding the effective screen resolution (double) */
#define SCREEN_XRES(s) (s->dot_for_dot ? \ #define SCREEN_XRES(s) ((s)->dot_for_dot ? \
s->gdisp->gimage->xresolution : s->monitor_xres) (s)->gdisp->gimage->xresolution : (s)->monitor_xres)
#define SCREEN_YRES(s) (s->dot_for_dot ? \ #define SCREEN_YRES(s) ((s)->dot_for_dot ? \
s->gdisp->gimage->yresolution : s->monitor_yres) (s)->gdisp->gimage->yresolution : (s)->monitor_yres)
/* calculate scale factors (double) */ /* calculate scale factors (double) */
#define SCALEFACTOR_X(s) (s->scale * SCREEN_XRES(s) / \ #define SCALEFACTOR_X(s) (gimp_zoom_model_get_factor ((s)->zoom) \
s->gdisp->gimage->xresolution) * SCREEN_XRES(s) / (s)->gdisp->gimage->xresolution)
#define SCALEFACTOR_Y(s) (s->scale * SCREEN_YRES(s) / \ #define SCALEFACTOR_Y(s) (gimp_zoom_model_get_factor ((s)->zoom) \
s->gdisp->gimage->yresolution) * SCREEN_YRES(s) / (s)->gdisp->gimage->yresolution)
/* scale values */ /* scale values */
#define SCALEX(s,x) PROJ_ROUND (x * SCALEFACTOR_X(s)) #define SCALEX(s,x) PROJ_ROUND ((x) * SCALEFACTOR_X(s))
#define SCALEY(s,y) PROJ_ROUND (y * SCALEFACTOR_Y(s)) #define SCALEY(s,y) PROJ_ROUND ((y) * SCALEFACTOR_Y(s))
/* unscale values */ /* unscale values */
#define UNSCALEX(s,x) ((gint) (x / SCALEFACTOR_X(s))) #define UNSCALEX(s,x) ((gint) ((x) / SCALEFACTOR_X(s)))
#define UNSCALEY(s,y) ((gint) (y / SCALEFACTOR_Y(s))) #define UNSCALEY(s,y) ((gint) ((y) / SCALEFACTOR_Y(s)))
/* (and float-returning versions) */ /* (and float-returning versions) */
#define FUNSCALEX(s,x) (x / SCALEFACTOR_X(s)) #define FUNSCALEX(s,x) ((x) / SCALEFACTOR_X(s))
#define FUNSCALEY(s,y) (y / SCALEFACTOR_Y(s)) #define FUNSCALEY(s,y) ((y) / SCALEFACTOR_Y(s))
#define GIMP_TYPE_DISPLAY_SHELL (gimp_display_shell_get_type ()) #define GIMP_TYPE_DISPLAY_SHELL (gimp_display_shell_get_type ())
@ -74,7 +76,7 @@ struct _GimpDisplayShell
GimpUnit unit; GimpUnit unit;
gdouble scale; /* scale factor from original raw image */ GimpZoomModel *zoom;
gdouble other_scale; /* scale factor entered in Zoom->Other */ gdouble other_scale; /* scale factor entered in Zoom->Other */
gboolean dot_for_dot; /* is monitor resolution being ignored? */ gboolean dot_for_dot; /* is monitor resolution being ignored? */

View File

@ -605,8 +605,7 @@ static void
gimp_navigation_editor_zoom_adj_changed (GtkAdjustment *adj, gimp_navigation_editor_zoom_adj_changed (GtkAdjustment *adj,
GimpNavigationEditor *editor) GimpNavigationEditor *editor)
{ {
gimp_display_shell_scale (editor->shell, GIMP_ZOOM_TO, gimp_display_shell_scale (editor->shell, GIMP_ZOOM_TO, pow (2.0, adj->value));
pow (2.0, adj->value));
} }
static void static void
@ -615,21 +614,20 @@ gimp_navigation_editor_shell_scaled (GimpDisplayShell *shell,
{ {
if (editor->zoom_label) if (editor->zoom_label)
{ {
gchar scale_str[MAX_SCALE_BUF]; gchar *str;
/* Update the zoom scale string */ g_object_get (shell->zoom,
g_snprintf (scale_str, sizeof (scale_str), "percentage", &str,
shell->scale >= 0.15 ? "%.0f%%" : "%.2f%%", NULL);
editor->shell->scale * 100); gtk_label_set_text (GTK_LABEL (editor->zoom_label), str);
g_free (str);
gtk_label_set_text (GTK_LABEL (editor->zoom_label), scale_str);
} }
if (editor->zoom_adjustment) if (editor->zoom_adjustment)
{ {
gdouble val; gdouble val;
val = log (CLAMP (editor->shell->scale, 1.0 / 256, 256.0) ) / G_LN2; val = log (gimp_zoom_model_get_factor (shell->zoom)) / G_LN2;
g_signal_handlers_block_by_func (editor->zoom_adjustment, g_signal_handlers_block_by_func (editor->zoom_adjustment,
gimp_navigation_editor_zoom_adj_changed, gimp_navigation_editor_zoom_adj_changed,

View File

@ -746,7 +746,7 @@ gimp_statusbar_shell_scaled (GimpDisplayShell *shell,
g_signal_handlers_block_by_func (statusbar->scale_combo, g_signal_handlers_block_by_func (statusbar->scale_combo,
gimp_statusbar_scale_changed, statusbar); gimp_statusbar_scale_changed, statusbar);
gimp_scale_combo_box_set_scale (GIMP_SCALE_COMBO_BOX (statusbar->scale_combo), gimp_scale_combo_box_set_scale (GIMP_SCALE_COMBO_BOX (statusbar->scale_combo),
shell->scale); gimp_zoom_model_get_factor (shell->zoom));
g_signal_handlers_unblock_by_func (statusbar->scale_combo, g_signal_handlers_unblock_by_func (statusbar->scale_combo,
gimp_statusbar_scale_changed, statusbar); gimp_statusbar_scale_changed, statusbar);

View File

@ -26,6 +26,7 @@
#include "libgimpmath/gimpmath.h" #include "libgimpmath/gimpmath.h"
#include "libgimpbase/gimpbase.h" #include "libgimpbase/gimpbase.h"
#include "libgimpwidgets/gimpwidgets.h"
#include "tools-types.h" #include "tools-types.h"
@ -1048,8 +1049,9 @@ gimp_edit_selection_tool_key_press (GimpTool *tool,
return FALSE; return FALSE;
/* adapt arrow velocity to the zoom factor */ /* adapt arrow velocity to the zoom factor */
velocity = ARROW_VELOCITY / GIMP_DISPLAY_SHELL (gdisp->shell)->scale; velocity = (ARROW_VELOCITY /
velocity = MAX (1, velocity); gimp_zoom_model_get_factor (GIMP_DISPLAY_SHELL (gdisp->shell)->zoom));
velocity = MAX (1.0, velocity);
/* check for mask translation first because the translate_layer /* check for mask translation first because the translate_layer
* modifiers match the translate_mask ones... * modifiers match the translate_mask ones...

View File

@ -202,6 +202,7 @@ gimp_magnify_tool_button_release (GimpTool *tool,
GimpMagnifyTool *magnify = GIMP_MAGNIFY_TOOL (tool); GimpMagnifyTool *magnify = GIMP_MAGNIFY_TOOL (tool);
GimpMagnifyOptions *options; GimpMagnifyOptions *options;
GimpDisplayShell *shell; GimpDisplayShell *shell;
gdouble current;
options = GIMP_MAGNIFY_OPTIONS (tool->tool_info->tool_options); options = GIMP_MAGNIFY_OPTIONS (tool->tool_info->tool_options);
@ -229,12 +230,13 @@ gimp_magnify_tool_button_release (GimpTool *tool,
win_width = shell->disp_width; win_width = shell->disp_width;
win_height = shell->disp_height; win_height = shell->disp_height;
current = gimp_zoom_model_get_factor (shell->zoom);
/* we need to compute the mouse movement in screen coordinates */ /* we need to compute the mouse movement in screen coordinates */
if ((SCALEX (shell, w) < options->threshold) || if ((SCALEX (shell, w) < options->threshold) ||
(SCALEY (shell, h) < options->threshold)) (SCALEY (shell, h) < options->threshold))
{ {
new_scale = gimp_zoom_model_zoom_step (options->zoom_type, new_scale = gimp_zoom_model_zoom_step (options->zoom_type, current);
shell->scale);
} }
else else
{ {
@ -256,11 +258,11 @@ gimp_magnify_tool_button_release (GimpTool *tool,
((gdouble) h / (gdouble) height)); ((gdouble) h / (gdouble) height));
break; break;
case GIMP_ZOOM_TO: default:
break; break;
} }
new_scale = shell->scale * scale; new_scale = current * scale;
} }
offset_x = (new_scale * ((x1 + x2) / 2) offset_x = (new_scale * ((x1 + x2) / 2)

View File

@ -333,5 +333,6 @@ EXPORTS
gimp_zoom_model_get_type gimp_zoom_model_get_type
gimp_zoom_model_new gimp_zoom_model_new
gimp_zoom_model_set_range gimp_zoom_model_set_range
gimp_zoom_model_zoom
gimp_zoom_model_zoom_step gimp_zoom_model_zoom_step
gimp_zoom_widget_new gimp_zoom_widget_new

View File

@ -79,31 +79,31 @@ gimp_zoom_model_class_init (GimpZoomModelClass *klass)
g_object_class_install_property (object_class, PROP_VALUE, g_object_class_install_property (object_class, PROP_VALUE,
g_param_spec_double ("value", g_param_spec_double ("value",
"Value", NULL, "Zoom factor", NULL,
ZOOM_MIN, ZOOM_MAX, ZOOM_MIN, ZOOM_MAX,
1.0, 1.0,
G_PARAM_READWRITE)); G_PARAM_READWRITE));
g_object_class_install_property (object_class, PROP_MINIMUM, g_object_class_install_property (object_class, PROP_MINIMUM,
g_param_spec_double ("minimum", g_param_spec_double ("minimum",
"Minimum", NULL, "Lower limit for the zoom factor", NULL,
ZOOM_MIN, ZOOM_MAX, ZOOM_MIN, ZOOM_MAX,
ZOOM_MIN, ZOOM_MIN,
G_PARAM_READWRITE)); G_PARAM_READWRITE));
g_object_class_install_property (object_class, PROP_MAXIMUM, g_object_class_install_property (object_class, PROP_MAXIMUM,
g_param_spec_double ("maximum", g_param_spec_double ("maximum",
"Maximum", NULL, "Upper limit for the zoom factor", NULL,
ZOOM_MIN, ZOOM_MAX, ZOOM_MIN, ZOOM_MAX,
ZOOM_MAX, ZOOM_MAX,
G_PARAM_READWRITE)); G_PARAM_READWRITE));
g_object_class_install_property (object_class, PROP_FRACTION, g_object_class_install_property (object_class, PROP_FRACTION,
g_param_spec_string ("fraction", g_param_spec_string ("fraction",
"Fraction", NULL, "The zoom factor expressed as a fraction", NULL,
"1:1", "1:1",
G_PARAM_READABLE)); G_PARAM_READABLE));
g_object_class_install_property (object_class, PROP_PERCENTAGE, g_object_class_install_property (object_class, PROP_PERCENTAGE,
g_param_spec_string ("percentage", g_param_spec_string ("percentage",
"Percentage", NULL, "The zoom factor expressed as a percentage", NULL,
"100%", "100%",
G_PARAM_READABLE)); G_PARAM_READABLE));
@ -116,8 +116,8 @@ gimp_zoom_model_init (GimpZoomModel *model)
GimpZoomModelPrivate *priv = GIMP_ZOOM_MODEL_GET_PRIVATE (model); GimpZoomModelPrivate *priv = GIMP_ZOOM_MODEL_GET_PRIVATE (model);
priv->value = 1.0; priv->value = 1.0;
priv->minimum = 1.0 / 256.0; priv->minimum = ZOOM_MIN;
priv->maximum = 256.0; priv->maximum = ZOOM_MAX;
} }
static void static void
@ -171,8 +171,6 @@ gimp_zoom_model_get_property (GObject *object,
GParamSpec *pspec) GParamSpec *pspec)
{ {
GimpZoomModelPrivate *priv = GIMP_ZOOM_MODEL_GET_PRIVATE (object); GimpZoomModelPrivate *priv = GIMP_ZOOM_MODEL_GET_PRIVATE (object);
gint numerator;
gint denominator;
gchar *tmp; gchar *tmp;
switch (property_id) switch (property_id)
@ -190,15 +188,22 @@ gimp_zoom_model_get_property (GObject *object,
break; break;
case PROP_FRACTION: case PROP_FRACTION:
gimp_zoom_model_get_fraction (priv->value, &numerator, &denominator); {
gint numerator;
gint denominator;
tmp = g_strdup_printf ("%d:%d", numerator, denominator); gimp_zoom_model_get_fraction (GIMP_ZOOM_MODEL (object),
g_value_set_string (value, tmp); &numerator, &denominator);
g_free (tmp);
tmp = g_strdup_printf ("%d:%d", numerator, denominator);
g_value_set_string (value, tmp);
g_free (tmp);
}
break; break;
case PROP_PERCENTAGE: case PROP_PERCENTAGE:
tmp = g_strdup_printf ("%d%%", (gint) (priv->value * 100.0)); tmp = g_strdup_printf (priv->value >= 0.15 ? "%.0f%%" : "%.2f%%",
priv->value * 100.0);
g_value_set_string (value, tmp); g_value_set_string (value, tmp);
g_free (tmp); g_free (tmp);
break; break;
@ -214,18 +219,8 @@ gimp_zoom_model_zoom_in (GimpZoomModel *model)
{ {
GimpZoomModelPrivate *priv = GIMP_ZOOM_MODEL_GET_PRIVATE (model); GimpZoomModelPrivate *priv = GIMP_ZOOM_MODEL_GET_PRIVATE (model);
g_return_if_fail (GIMP_IS_ZOOM_MODEL (model)); if (priv->value < priv->maximum)
gimp_zoom_model_zoom (model, GIMP_ZOOM_IN, 0.0);
if (priv->value < priv->maximum);
{
gdouble scale = gimp_zoom_model_zoom_step (GIMP_ZOOM_IN, priv->value);
priv->value = CLAMP (scale, priv->minimum, priv->maximum);
g_object_notify (G_OBJECT (model), "value");
g_object_notify (G_OBJECT (model), "fraction");
g_object_notify (G_OBJECT (model), "percentage");
}
} }
static void static void
@ -233,18 +228,8 @@ gimp_zoom_model_zoom_out (GimpZoomModel *model)
{ {
GimpZoomModelPrivate *priv = GIMP_ZOOM_MODEL_GET_PRIVATE (model); GimpZoomModelPrivate *priv = GIMP_ZOOM_MODEL_GET_PRIVATE (model);
g_return_if_fail (GIMP_IS_ZOOM_MODEL (model));
if (priv->value > priv->minimum) if (priv->value > priv->minimum)
{ gimp_zoom_model_zoom (model, GIMP_ZOOM_OUT, 0.0);
gdouble scale = gimp_zoom_model_zoom_step (GIMP_ZOOM_OUT, priv->value);
priv->value = CLAMP (scale, priv->minimum, priv->maximum);
g_object_notify (G_OBJECT (model), "value");
g_object_notify (G_OBJECT (model), "fraction");
g_object_notify (G_OBJECT (model), "percentage");
}
} }
/** /**
@ -278,6 +263,7 @@ gimp_zoom_model_set_range (GimpZoomModel *model,
gdouble min, gdouble min,
gdouble max) gdouble max)
{ {
g_return_if_fail (GIMP_IS_ZOOM_MODEL (model));
g_return_if_fail (min < max); g_return_if_fail (min < max);
g_return_if_fail (min >= ZOOM_MIN); g_return_if_fail (min >= ZOOM_MIN);
g_return_if_fail (max <= ZOOM_MAX); g_return_if_fail (max <= ZOOM_MAX);
@ -288,11 +274,34 @@ gimp_zoom_model_set_range (GimpZoomModel *model,
NULL); NULL);
} }
/**
* gimp_zoom_model_zoom:
* @model: a #GimpZoomModel
* @zoom_type: the #GimpZoomType
* @scale: ignored unless @zoom_type == %GIMP_ZOOM_TO
*
* Since GIMP 2.4
**/
void
gimp_zoom_model_zoom (GimpZoomModel *model,
GimpZoomType zoom_type,
gdouble scale)
{
g_return_if_fail (GIMP_IS_ZOOM_MODEL (model));
if (zoom_type != GIMP_ZOOM_TO)
scale = gimp_zoom_model_get_factor (model);
g_object_set (model,
"value", gimp_zoom_model_zoom_step (zoom_type, scale),
NULL);
}
/** /**
* gimp_zoom_model_get_factor: * gimp_zoom_model_get_factor:
* @model: a #GimpZoomModel * @model: a #GimpZoomModel
* *
* Retrieve the current zoom factor of @model. * Retrieves the current zoom factor of @model.
* *
* Return value: the current scale factor * Return value: the current scale factor
* *
@ -301,83 +310,38 @@ gimp_zoom_model_set_range (GimpZoomModel *model,
gdouble gdouble
gimp_zoom_model_get_factor (GimpZoomModel *model) gimp_zoom_model_get_factor (GimpZoomModel *model)
{ {
GimpZoomModelPrivate *priv = GIMP_ZOOM_MODEL_GET_PRIVATE (model);
g_return_val_if_fail (GIMP_IS_ZOOM_MODEL (model), 1.0); g_return_val_if_fail (GIMP_IS_ZOOM_MODEL (model), 1.0);
return priv->value; return GIMP_ZOOM_MODEL_GET_PRIVATE (model)->value;
} }
/**
* gimp_zoom_widget_new:
* @model: a #GimpZoomModel
* @type: the type of widget to create
*
* Creates a new widget to interact with the #GimpZoomModel.
*
* Return value: a new #GtkWidget.
*
* Since GIMP 2.4
**/
GtkWidget *
gimp_zoom_widget_new (GimpZoomModel *model,
GimpZoomWidgetType type)
{
GtkWidget *button;
GtkWidget *image;
g_return_val_if_fail (GIMP_IS_ZOOM_MODEL (model), NULL);
switch (type)
{
case GIMP_ZOOM_IN_BUTTON:
button = gtk_button_new ();
image = gtk_image_new_from_stock (GTK_STOCK_ZOOM_IN,
GTK_ICON_SIZE_SMALL_TOOLBAR);
gtk_container_add (GTK_CONTAINER (button), image);
gtk_widget_show (image);
g_signal_connect_swapped (button, "clicked",
G_CALLBACK (gimp_zoom_model_zoom_in),
model);
return button;
case GIMP_ZOOM_OUT_BUTTON:
button = gtk_button_new ();
image = gtk_image_new_from_stock (GTK_STOCK_ZOOM_OUT,
GTK_ICON_SIZE_SMALL_TOOLBAR);
gtk_container_add (GTK_CONTAINER (button), image);
gtk_widget_show (image);
g_signal_connect_swapped (button, "clicked",
G_CALLBACK (gimp_zoom_model_zoom_out),
model);
return button;
}
return NULL;
}
/** /**
* gimp_zoom_model_get_fraction * gimp_zoom_model_get_fraction
* @zoom_factor: a scale factor * @model: a #GimpZoomModel
* @numerator: return location for numerator * @numerator: return location for numerator
* @denominator: return location for denominator * @denominator: return location for denominator
* *
* Utility function that expresses @zoom_factor as a fraction. * Retrieves the current zoom factor of @model as a fraction.
* *
* Since GIMP 2.4 * Since GIMP 2.4
**/ **/
void void
gimp_zoom_model_get_fraction (gdouble zoom_factor, gimp_zoom_model_get_fraction (GimpZoomModel *model,
gint *numerator, gint *numerator,
gint *denominator) gint *denominator)
{ {
gint p0, p1, p2; gint p0, p1, p2;
gint q0, q1, q2; gint q0, q1, q2;
gdouble zoom_factor;
gdouble remainder, next_cf; gdouble remainder, next_cf;
gboolean swapped = FALSE; gboolean swapped = FALSE;
g_return_if_fail (GIMP_IS_ZOOM_MODEL (model));
g_return_if_fail (numerator != NULL && denominator != NULL); g_return_if_fail (numerator != NULL && denominator != NULL);
zoom_factor = gimp_zoom_model_get_factor (model);
/* make sure that zooming behaves symmetrically */ /* make sure that zooming behaves symmetrically */
if (zoom_factor < 1.0) if (zoom_factor < 1.0)
{ {
@ -445,6 +409,54 @@ gimp_zoom_model_get_fraction (gdouble zoom_factor,
} }
} }
/**
* gimp_zoom_widget_new:
* @model: a #GimpZoomModel
* @type: the type of widget to create
*
* Creates a new widget to interact with the #GimpZoomModel.
*
* Return value: a new #GtkWidget.
*
* Since GIMP 2.4
**/
GtkWidget *
gimp_zoom_widget_new (GimpZoomModel *model,
GimpZoomWidgetType type)
{
GtkWidget *button;
GtkWidget *image;
g_return_val_if_fail (GIMP_IS_ZOOM_MODEL (model), NULL);
switch (type)
{
case GIMP_ZOOM_IN_BUTTON:
button = gtk_button_new ();
image = gtk_image_new_from_stock (GTK_STOCK_ZOOM_IN,
GTK_ICON_SIZE_SMALL_TOOLBAR);
gtk_container_add (GTK_CONTAINER (button), image);
gtk_widget_show (image);
g_signal_connect_swapped (button, "clicked",
G_CALLBACK (gimp_zoom_model_zoom_in),
model);
return button;
case GIMP_ZOOM_OUT_BUTTON:
button = gtk_button_new ();
image = gtk_image_new_from_stock (GTK_STOCK_ZOOM_OUT,
GTK_ICON_SIZE_SMALL_TOOLBAR);
gtk_container_add (GTK_CONTAINER (button), image);
gtk_widget_show (image);
g_signal_connect_swapped (button, "clicked",
G_CALLBACK (gimp_zoom_model_zoom_out),
model);
return button;
}
return NULL;
}
/** /**
* gimp_zoom_model_zoom_step: * gimp_zoom_model_zoom_step:
* @zoom_type: * @zoom_type:
@ -467,9 +479,10 @@ gimp_zoom_model_zoom_step (GimpZoomType zoom_type,
* sqrt(2)^k. This gives a smooth feeling regardless of the starting * sqrt(2)^k. This gives a smooth feeling regardless of the starting
* zoom level. * zoom level.
* *
* Zooming in/out always jumps to a zoom step from the list above. * Zooming in/out always jumps to a zoom step from the list below.
* However, we try to guarantee a certain size of the step, to * However, we try to guarantee a certain size of the step, to
* avoid silly jumps from 101% to 100%. * avoid silly jumps from 101% to 100%.
*
* The factor 1.1 is chosen a bit arbitrary, but feels better * The factor 1.1 is chosen a bit arbitrary, but feels better
* than the geometric median of the zoom steps (2^(1/4)). * than the geometric median of the zoom steps (2^(1/4)).
*/ */
@ -496,8 +509,7 @@ gimp_zoom_model_zoom_step (GimpZoomType zoom_type,
case GIMP_ZOOM_IN: case GIMP_ZOOM_IN:
scale *= ZOOM_MIN_STEP; scale *= ZOOM_MIN_STEP;
new_scale = presets[n_presets-1]; new_scale = presets[n_presets - 1];
for (i = n_presets - 1; i >= 0 && presets[i] > scale; i--) for (i = n_presets - 1; i >= 0 && presets[i] > scale; i--)
new_scale = presets[i]; new_scale = presets[i];
@ -507,7 +519,6 @@ gimp_zoom_model_zoom_step (GimpZoomType zoom_type,
scale /= ZOOM_MIN_STEP; scale /= ZOOM_MIN_STEP;
new_scale = presets[0]; new_scale = presets[0];
for (i = 0; i < n_presets && presets[i] < scale; i++) for (i = 0; i < n_presets && presets[i] < scale; i++)
new_scale = presets[i]; new_scale = presets[i];

View File

@ -53,22 +53,25 @@ struct _GimpZoomModelClass
}; };
GType gimp_zoom_model_get_type (void) G_GNUC_CONST; GType gimp_zoom_model_get_type (void) G_GNUC_CONST;
GimpZoomModel *gimp_zoom_model_new (void); GimpZoomModel * gimp_zoom_model_new (void);
void gimp_zoom_model_set_range (GimpZoomModel *model, void gimp_zoom_model_set_range (GimpZoomModel *model,
gdouble min, gdouble min,
gdouble max); gdouble max);
gdouble gimp_zoom_model_get_factor (GimpZoomModel *model); void gimp_zoom_model_zoom (GimpZoomModel *model,
GimpZoomType zoom_type,
gdouble scale);
gdouble gimp_zoom_model_get_factor (GimpZoomModel *model);
void gimp_zoom_model_get_fraction (GimpZoomModel *model,
gint *numerator,
gint *denominator);
GtkWidget *gimp_zoom_widget_new (GimpZoomModel *model, GtkWidget * gimp_zoom_widget_new (GimpZoomModel *model,
GimpZoomWidgetType type); GimpZoomWidgetType type);
void gimp_zoom_model_get_fraction (gdouble zoom_factor, gdouble gimp_zoom_model_zoom_step (GimpZoomType zoom_type,
gint *numerator, gdouble scale);
gint *denominator);
gdouble gimp_zoom_model_zoom_step (GimpZoomType zoom_type,
gdouble scale);
G_END_DECLS G_END_DECLS