From 1f0aff2b09eefbb16390a5643375c0dce36b31e7 Mon Sep 17 00:00:00 2001 From: Sven Neumann Date: Sun, 25 Sep 2005 17:03:03 +0000 Subject: [PATCH] libgimpwidgets/gimpwidgets.def added gimp_zoom_model_zoom() and changed 2005-09-25 Sven Neumann * 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. --- ChangeLog | 21 +++ app/actions/image-commands.c | 3 +- app/actions/view-actions.c | 24 +-- app/actions/view-commands.c | 33 ++-- app/display/gimpdisplayshell-callbacks.c | 5 +- app/display/gimpdisplayshell-scale.c | 41 +++-- app/display/gimpdisplayshell-title.c | 17 +- app/display/gimpdisplayshell.c | 42 ++--- app/display/gimpdisplayshell.h | 32 ++-- app/display/gimpnavigationeditor.c | 18 +- app/display/gimpstatusbar.c | 2 +- app/tools/gimpeditselectiontool.c | 6 +- app/tools/gimpmagnifytool.c | 10 +- libgimpwidgets/gimpwidgets.def | 1 + libgimpwidgets/gimpzoommodel.c | 207 ++++++++++++----------- libgimpwidgets/gimpzoommodel.h | 29 ++-- 16 files changed, 273 insertions(+), 218 deletions(-) diff --git a/ChangeLog b/ChangeLog index 22c007b1b6..de78aa168f 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,24 @@ +2005-09-25 Sven Neumann + + * 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 * app/tools/gimpcroptool.c: fixed assignment of local variable diff --git a/app/actions/image-commands.c b/app/actions/image-commands.c index e347eefe7c..3c1bb81cde 100644 --- a/app/actions/image-commands.c +++ b/app/actions/image-commands.c @@ -362,7 +362,8 @@ image_duplicate_cmd_callback (GtkAction *action, gimp_create_display (new_gimage->gimp, new_gimage, - shell->unit, shell->scale); + shell->unit, + gimp_zoom_model_get_factor (shell->zoom)); g_object_unref (new_gimage); } diff --git a/app/actions/view-actions.c b/app/actions/view-actions.c index 706bc111cc..2a625d845f 100644 --- a/app/actions/view-actions.c +++ b/app/actions/view-actions.c @@ -588,11 +588,15 @@ view_actions_set_zoom (GimpActionGroup *group, GimpDisplayShell *shell) { const gchar *action = NULL; - guint scale; - gchar buf[16]; + gchar *str; 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) { @@ -608,29 +612,27 @@ view_actions_set_zoom (GimpActionGroup *group, case 62: action = "view-zoom-1-16"; break; } - g_snprintf (buf, sizeof (buf), - shell->scale >= 0.15 ? "%.0f%%" : "%.2f%%", - shell->scale * 100.0); - - if (!action) + if (! action) { 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); 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); - 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); g_free (label); /* flag as dirty */ shell->other_scale = - fabs (shell->other_scale); + + g_free (str); } static void diff --git a/app/actions/view-commands.c b/app/actions/view-commands.c index 92c90ec907..e787561915 100644 --- a/app/actions/view-commands.c +++ b/app/actions/view-commands.c @@ -85,7 +85,7 @@ view_new_cmd_callback (GtkAction *action, gimp_create_display (gdisp->gimage->gimp, gdisp->gimage, - shell->unit, shell->scale); + shell->unit, gimp_zoom_model_get_factor (shell->zoom)); } void @@ -125,13 +125,10 @@ view_zoom_cmd_callback (GtkAction *action, { GimpDisplay *gdisp; GimpDisplayShell *shell; - gdouble scale; return_if_no_display (gdisp, data); shell = GIMP_DISPLAY_SHELL (gdisp->shell); - scale = shell->scale; - switch ((GimpActionSelectType) value) { case GIMP_ACTION_SELECT_FIRST: @@ -159,18 +156,22 @@ view_zoom_cmd_callback (GtkAction *action, break; default: - scale = action_select_value ((GimpActionSelectType) value, - scale, - 0.0, 512.0, - 1.0, 16.0, - FALSE); + { + gdouble scale = gimp_zoom_model_get_factor (shell->zoom); - /* min = 1.0 / 256, max = 256.0 */ - /* scale = min * (max / min)**(i/n), i = 0..n */ - scale = pow (65536.0, scale / 512.0) / 256.0; + scale = action_select_value ((GimpActionSelectType) value, + scale, + 0.0, 512.0, + 1.0, 16.0, + FALSE); - gimp_display_shell_scale (shell, GIMP_ZOOM_TO, scale); - break; + /* min = 1.0 / 256, max = 256.0 */ + /* 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 (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); } } @@ -209,7 +210,7 @@ view_zoom_other_cmd_callback (GtkAction *action, * view_actions_set_zoom() */ 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); } diff --git a/app/display/gimpdisplayshell-callbacks.c b/app/display/gimpdisplayshell-callbacks.c index fc4f03ea10..b240ebdad8 100644 --- a/app/display/gimpdisplayshell-callbacks.c +++ b/app/display/gimpdisplayshell-callbacks.c @@ -321,7 +321,7 @@ gimp_display_shell_canvas_size_allocate (GtkWidget *widget, allocation->width > 64 && allocation->height > 64) { - gdouble scale = shell->scale; + gdouble scale = gimp_zoom_model_get_factor (shell->zoom); gint offset_x; gint offset_y; @@ -336,7 +336,8 @@ gimp_display_shell_canvas_size_allocate (GtkWidget *widget, offset_x = UNSCALEX (shell, shell->offset_x); 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_y = SCALEY (shell, offset_y); } diff --git a/app/display/gimpdisplayshell-scale.c b/app/display/gimpdisplayshell-scale.c index cf4ef84103..25fa238e53 100644 --- a/app/display/gimpdisplayshell-scale.c +++ b/app/display/gimpdisplayshell-scale.c @@ -49,6 +49,7 @@ typedef struct _ScaleDialogData ScaleDialogData; struct _ScaleDialogData { GimpDisplayShell *shell; + GimpZoomModel *model; GtkObject *scale_adj; GtkObject *num_adj; GtkObject *denom_adj; @@ -280,6 +281,7 @@ gimp_display_shell_scale_to (GimpDisplayShell *shell, gdouble y) { GimpDisplayConfig *config; + gdouble current; gdouble offset_x; gdouble offset_y; @@ -288,14 +290,16 @@ gimp_display_shell_scale_to (GimpDisplayShell *shell, if (! shell->gdisp) return; + current = gimp_zoom_model_get_factor (shell->zoom); + offset_x = shell->offset_x + x; offset_y = shell->offset_y + y; - offset_x /= shell->scale; - offset_y /= shell->scale; + offset_x /= current; + offset_y /= current; 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_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 * want to inadvertently resize the window (bug #164281). */ - if (shell->scale == scale && - shell->offset_x == offset_x && + if (gimp_zoom_model_get_factor (shell->zoom) == scale && + shell->offset_x == offset_x && shell->offset_y == offset_y) return; /* freeze the active tool */ 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_y = offset_y; @@ -449,8 +454,18 @@ gimp_display_shell_scale_dialog (GimpDisplayShell *shell) 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->shell = shell; + data->model = g_object_new (GIMP_TYPE_ZOOM_MODEL, + "value", fabs (shell->other_scale), + NULL); shell->scale_dialog = 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), (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), (gpointer *) &shell->scale_dialog); @@ -499,11 +517,7 @@ gimp_display_shell_scale_dialog (GimpDisplayShell *shell) _("Zoom ratio:"), 0.0, 0.5, hbox, 1, FALSE); - if (fabs (shell->other_scale) <= 0.0001) - shell->other_scale = shell->scale; /* other_scale not yet initialized */ - - gimp_zoom_model_get_fraction (fabs (shell->other_scale), - &num, &denom); + gimp_zoom_model_get_fraction (data->model, &num, &denom); spin = gimp_spin_button_new (&data->num_adj, num, 1, 256, @@ -582,7 +596,7 @@ static void update_zoom_values (GtkAdjustment *adj, ScaleDialogData *dialog) { - gint num, denom; + gint num, denom; gdouble scale; 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)); - 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->denom_adj), denom); diff --git a/app/display/gimpdisplayshell-title.c b/app/display/gimpdisplayshell-title.c index e96ef01b92..9fbfae3d6c 100644 --- a/app/display/gimpdisplayshell-title.c +++ b/app/display/gimpdisplayshell-title.c @@ -162,7 +162,7 @@ gimp_display_shell_format_title (GimpDisplayShell *shell, image = shell->gdisp->gimage; 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) { @@ -247,9 +247,12 @@ gimp_display_shell_format_title (GimpDisplayShell *shell, break; case 'z': /* user zoom factor (percentage) */ - i += print (title, title_len, i, - shell->scale >= 0.15 ? "%.0f" : "%.2f", - 100 * shell->scale); + { + gdouble scale = gimp_zoom_model_get_factor (shell->zoom); + + i += print (title, title_len, i, + scale >= 0.15 ? "%.0f" : "%.2f", 100.0 * scale); + } break; case 'D': /* dirty flag */ @@ -278,14 +281,12 @@ gimp_display_shell_format_title (GimpDisplayShell *shell, case 'B': /* dirty flag (long) */ if (image->dirty) - i += print (title, title_len, i, "%s", - _("(modified)")); + i += print (title, title_len, i, "%s", _("(modified)")); break; case 'A': /* clean flag (long) */ if (! image->dirty) - i += print (title, title_len, i, "%s", - _("(clean)")); + i += print (title, title_len, i, "%s", _("(clean)")); break; case 'm': /* memory used by image */ diff --git a/app/display/gimpdisplayshell.c b/app/display/gimpdisplayshell.c index 594995f644..dbc6f200c8 100644 --- a/app/display/gimpdisplayshell.c +++ b/app/display/gimpdisplayshell.c @@ -74,7 +74,6 @@ enum { PROP_0, - PROP_SCALE, PROP_UNIT }; @@ -208,11 +207,6 @@ gimp_display_shell_class_init (GimpDisplayShellClass *klass) klass->scrolled = 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, gimp_param_spec_unit ("unit", NULL, NULL, TRUE, FALSE, @@ -232,7 +226,7 @@ gimp_display_shell_init (GimpDisplayShell *shell) shell->unit = GIMP_UNIT_PIXEL; - shell->scale = 1.0; + shell->zoom = gimp_zoom_model_new (); shell->other_scale = 0.0; shell->dot_for_dot = TRUE; @@ -358,6 +352,8 @@ gimp_display_shell_finalize (GObject *object) { GimpDisplayShell *shell = GIMP_DISPLAY_SHELL (object); + g_object_unref (shell->zoom); + if (shell->options) g_object_unref (shell->options); @@ -449,16 +445,10 @@ gimp_display_shell_set_property (GObject *object, 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: gimp_display_shell_set_unit (shell, g_value_get_int (value)); break; + default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); break; @@ -475,12 +465,10 @@ gimp_display_shell_get_property (GObject *object, switch (property_id) { - case PROP_SCALE: - g_value_set_double (value, shell->scale); - break; case PROP_UNIT: g_value_set_int (value, shell->unit); break; + default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); break; @@ -602,9 +590,10 @@ gimp_display_shell_new (GimpDisplay *gdisp, shell = g_object_new (GIMP_TYPE_DISPLAY_SHELL, "gravity", GDK_GRAVITY_CENTER, "unit", unit, - "scale", scale, NULL); + gimp_zoom_model_zoom (shell->zoom, GIMP_ZOOM_TO, scale); + shell->gdisp = gdisp; image_width = gdisp->gimage->width; @@ -647,18 +636,23 @@ gimp_display_shell_new (GimpDisplay *gdisp, /* Limit to the size of the screen... */ if (n_width > s_width || n_height > s_height) { - new_scale = shell->scale * MIN (((gdouble) s_height) / n_height, - ((gdouble) s_width) / n_width); + gdouble current = gimp_zoom_model_get_factor (shell->zoom); + + 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); - /* since zooming out might skip a zoom step we zoom in again - * and test if we are small enough. */ - shell->scale = gimp_zoom_model_zoom_step (GIMP_ZOOM_IN, 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) > s_width || 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_height = SCALEY (shell, image_height); diff --git a/app/display/gimpdisplayshell.h b/app/display/gimpdisplayshell.h index 3903e437a2..8359eef5f3 100644 --- a/app/display/gimpdisplayshell.h +++ b/app/display/gimpdisplayshell.h @@ -22,32 +22,34 @@ #include +#include "libgimpwidgets/gimpwidgets.h" + /* Apply to a float the same rounding mode used in the renderer */ #define PROJ_ROUND(coord) ((gint) ceil (coord)) /* finding the effective screen resolution (double) */ -#define SCREEN_XRES(s) (s->dot_for_dot ? \ - s->gdisp->gimage->xresolution : s->monitor_xres) -#define SCREEN_YRES(s) (s->dot_for_dot ? \ - s->gdisp->gimage->yresolution : s->monitor_yres) +#define SCREEN_XRES(s) ((s)->dot_for_dot ? \ + (s)->gdisp->gimage->xresolution : (s)->monitor_xres) +#define SCREEN_YRES(s) ((s)->dot_for_dot ? \ + (s)->gdisp->gimage->yresolution : (s)->monitor_yres) /* calculate scale factors (double) */ -#define SCALEFACTOR_X(s) (s->scale * SCREEN_XRES(s) / \ - s->gdisp->gimage->xresolution) -#define SCALEFACTOR_Y(s) (s->scale * SCREEN_YRES(s) / \ - s->gdisp->gimage->yresolution) +#define SCALEFACTOR_X(s) (gimp_zoom_model_get_factor ((s)->zoom) \ + * SCREEN_XRES(s) / (s)->gdisp->gimage->xresolution) +#define SCALEFACTOR_Y(s) (gimp_zoom_model_get_factor ((s)->zoom) \ + * SCREEN_YRES(s) / (s)->gdisp->gimage->yresolution) /* scale values */ -#define SCALEX(s,x) PROJ_ROUND (x * SCALEFACTOR_X(s)) -#define SCALEY(s,y) PROJ_ROUND (y * SCALEFACTOR_Y(s)) +#define SCALEX(s,x) PROJ_ROUND ((x) * SCALEFACTOR_X(s)) +#define SCALEY(s,y) PROJ_ROUND ((y) * SCALEFACTOR_Y(s)) /* unscale values */ -#define UNSCALEX(s,x) ((gint) (x / SCALEFACTOR_X(s))) -#define UNSCALEY(s,y) ((gint) (y / SCALEFACTOR_Y(s))) +#define UNSCALEX(s,x) ((gint) ((x) / SCALEFACTOR_X(s))) +#define UNSCALEY(s,y) ((gint) ((y) / SCALEFACTOR_Y(s))) /* (and float-returning versions) */ -#define FUNSCALEX(s,x) (x / SCALEFACTOR_X(s)) -#define FUNSCALEY(s,y) (y / SCALEFACTOR_Y(s)) +#define FUNSCALEX(s,x) ((x) / SCALEFACTOR_X(s)) +#define FUNSCALEY(s,y) ((y) / SCALEFACTOR_Y(s)) #define GIMP_TYPE_DISPLAY_SHELL (gimp_display_shell_get_type ()) @@ -74,7 +76,7 @@ struct _GimpDisplayShell GimpUnit unit; - gdouble scale; /* scale factor from original raw image */ + GimpZoomModel *zoom; gdouble other_scale; /* scale factor entered in Zoom->Other */ gboolean dot_for_dot; /* is monitor resolution being ignored? */ diff --git a/app/display/gimpnavigationeditor.c b/app/display/gimpnavigationeditor.c index 240c63535c..35d859a7af 100644 --- a/app/display/gimpnavigationeditor.c +++ b/app/display/gimpnavigationeditor.c @@ -605,8 +605,7 @@ static void gimp_navigation_editor_zoom_adj_changed (GtkAdjustment *adj, GimpNavigationEditor *editor) { - gimp_display_shell_scale (editor->shell, GIMP_ZOOM_TO, - pow (2.0, adj->value)); + gimp_display_shell_scale (editor->shell, GIMP_ZOOM_TO, pow (2.0, adj->value)); } static void @@ -615,21 +614,20 @@ gimp_navigation_editor_shell_scaled (GimpDisplayShell *shell, { if (editor->zoom_label) { - gchar scale_str[MAX_SCALE_BUF]; + gchar *str; - /* Update the zoom scale string */ - g_snprintf (scale_str, sizeof (scale_str), - shell->scale >= 0.15 ? "%.0f%%" : "%.2f%%", - editor->shell->scale * 100); - - gtk_label_set_text (GTK_LABEL (editor->zoom_label), scale_str); + g_object_get (shell->zoom, + "percentage", &str, + NULL); + gtk_label_set_text (GTK_LABEL (editor->zoom_label), str); + g_free (str); } if (editor->zoom_adjustment) { 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, gimp_navigation_editor_zoom_adj_changed, diff --git a/app/display/gimpstatusbar.c b/app/display/gimpstatusbar.c index 14307b0591..87234a3782 100644 --- a/app/display/gimpstatusbar.c +++ b/app/display/gimpstatusbar.c @@ -746,7 +746,7 @@ gimp_statusbar_shell_scaled (GimpDisplayShell *shell, g_signal_handlers_block_by_func (statusbar->scale_combo, gimp_statusbar_scale_changed, statusbar); 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, gimp_statusbar_scale_changed, statusbar); diff --git a/app/tools/gimpeditselectiontool.c b/app/tools/gimpeditselectiontool.c index b46df9852c..3e9e8aaf9a 100644 --- a/app/tools/gimpeditselectiontool.c +++ b/app/tools/gimpeditselectiontool.c @@ -26,6 +26,7 @@ #include "libgimpmath/gimpmath.h" #include "libgimpbase/gimpbase.h" +#include "libgimpwidgets/gimpwidgets.h" #include "tools-types.h" @@ -1048,8 +1049,9 @@ gimp_edit_selection_tool_key_press (GimpTool *tool, return FALSE; /* adapt arrow velocity to the zoom factor */ - velocity = ARROW_VELOCITY / GIMP_DISPLAY_SHELL (gdisp->shell)->scale; - velocity = MAX (1, velocity); + velocity = (ARROW_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 * modifiers match the translate_mask ones... diff --git a/app/tools/gimpmagnifytool.c b/app/tools/gimpmagnifytool.c index c7cb0bf30f..7bfc69b88d 100644 --- a/app/tools/gimpmagnifytool.c +++ b/app/tools/gimpmagnifytool.c @@ -202,6 +202,7 @@ gimp_magnify_tool_button_release (GimpTool *tool, GimpMagnifyTool *magnify = GIMP_MAGNIFY_TOOL (tool); GimpMagnifyOptions *options; GimpDisplayShell *shell; + gdouble current; 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_height = shell->disp_height; + current = gimp_zoom_model_get_factor (shell->zoom); + /* we need to compute the mouse movement in screen coordinates */ if ((SCALEX (shell, w) < options->threshold) || (SCALEY (shell, h) < options->threshold)) { - new_scale = gimp_zoom_model_zoom_step (options->zoom_type, - shell->scale); + new_scale = gimp_zoom_model_zoom_step (options->zoom_type, current); } else { @@ -256,11 +258,11 @@ gimp_magnify_tool_button_release (GimpTool *tool, ((gdouble) h / (gdouble) height)); break; - case GIMP_ZOOM_TO: + default: break; } - new_scale = shell->scale * scale; + new_scale = current * scale; } offset_x = (new_scale * ((x1 + x2) / 2) diff --git a/libgimpwidgets/gimpwidgets.def b/libgimpwidgets/gimpwidgets.def index 5ec692a0ae..5db253803c 100644 --- a/libgimpwidgets/gimpwidgets.def +++ b/libgimpwidgets/gimpwidgets.def @@ -333,5 +333,6 @@ EXPORTS gimp_zoom_model_get_type gimp_zoom_model_new gimp_zoom_model_set_range + gimp_zoom_model_zoom gimp_zoom_model_zoom_step gimp_zoom_widget_new diff --git a/libgimpwidgets/gimpzoommodel.c b/libgimpwidgets/gimpzoommodel.c index b1aa55b67f..66dcacdeff 100644 --- a/libgimpwidgets/gimpzoommodel.c +++ b/libgimpwidgets/gimpzoommodel.c @@ -79,31 +79,31 @@ gimp_zoom_model_class_init (GimpZoomModelClass *klass) g_object_class_install_property (object_class, PROP_VALUE, g_param_spec_double ("value", - "Value", NULL, + "Zoom factor", NULL, ZOOM_MIN, ZOOM_MAX, 1.0, G_PARAM_READWRITE)); g_object_class_install_property (object_class, PROP_MINIMUM, g_param_spec_double ("minimum", - "Minimum", NULL, + "Lower limit for the zoom factor", NULL, ZOOM_MIN, ZOOM_MAX, ZOOM_MIN, G_PARAM_READWRITE)); g_object_class_install_property (object_class, PROP_MAXIMUM, g_param_spec_double ("maximum", - "Maximum", NULL, + "Upper limit for the zoom factor", NULL, ZOOM_MIN, ZOOM_MAX, ZOOM_MAX, G_PARAM_READWRITE)); g_object_class_install_property (object_class, PROP_FRACTION, g_param_spec_string ("fraction", - "Fraction", NULL, + "The zoom factor expressed as a fraction", NULL, "1:1", G_PARAM_READABLE)); g_object_class_install_property (object_class, PROP_PERCENTAGE, g_param_spec_string ("percentage", - "Percentage", NULL, + "The zoom factor expressed as a percentage", NULL, "100%", G_PARAM_READABLE)); @@ -116,8 +116,8 @@ gimp_zoom_model_init (GimpZoomModel *model) GimpZoomModelPrivate *priv = GIMP_ZOOM_MODEL_GET_PRIVATE (model); priv->value = 1.0; - priv->minimum = 1.0 / 256.0; - priv->maximum = 256.0; + priv->minimum = ZOOM_MIN; + priv->maximum = ZOOM_MAX; } static void @@ -171,8 +171,6 @@ gimp_zoom_model_get_property (GObject *object, GParamSpec *pspec) { GimpZoomModelPrivate *priv = GIMP_ZOOM_MODEL_GET_PRIVATE (object); - gint numerator; - gint denominator; gchar *tmp; switch (property_id) @@ -190,15 +188,22 @@ gimp_zoom_model_get_property (GObject *object, break; case PROP_FRACTION: - gimp_zoom_model_get_fraction (priv->value, &numerator, &denominator); + { + gint numerator; + gint denominator; - tmp = g_strdup_printf ("%d:%d", numerator, denominator); - g_value_set_string (value, tmp); - g_free (tmp); + gimp_zoom_model_get_fraction (GIMP_ZOOM_MODEL (object), + &numerator, &denominator); + + tmp = g_strdup_printf ("%d:%d", numerator, denominator); + g_value_set_string (value, tmp); + g_free (tmp); + } break; 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_free (tmp); break; @@ -214,18 +219,8 @@ gimp_zoom_model_zoom_in (GimpZoomModel *model) { GimpZoomModelPrivate *priv = GIMP_ZOOM_MODEL_GET_PRIVATE (model); - g_return_if_fail (GIMP_IS_ZOOM_MODEL (model)); - - 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"); - } + if (priv->value < priv->maximum) + gimp_zoom_model_zoom (model, GIMP_ZOOM_IN, 0.0); } static void @@ -233,18 +228,8 @@ gimp_zoom_model_zoom_out (GimpZoomModel *model) { GimpZoomModelPrivate *priv = GIMP_ZOOM_MODEL_GET_PRIVATE (model); - g_return_if_fail (GIMP_IS_ZOOM_MODEL (model)); - if (priv->value > priv->minimum) - { - 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"); - } + gimp_zoom_model_zoom (model, GIMP_ZOOM_OUT, 0.0); } /** @@ -278,6 +263,7 @@ gimp_zoom_model_set_range (GimpZoomModel *model, gdouble min, gdouble max) { + g_return_if_fail (GIMP_IS_ZOOM_MODEL (model)); g_return_if_fail (min < max); g_return_if_fail (min >= ZOOM_MIN); g_return_if_fail (max <= ZOOM_MAX); @@ -288,11 +274,34 @@ gimp_zoom_model_set_range (GimpZoomModel *model, 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: * @model: a #GimpZoomModel * - * Retrieve the current zoom factor of @model. + * Retrieves the current zoom factor of @model. * * Return value: the current scale factor * @@ -301,83 +310,38 @@ gimp_zoom_model_set_range (GimpZoomModel *model, gdouble 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); - 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 - * @zoom_factor: a scale factor - * @numerator: return location for numerator + * @model: a #GimpZoomModel + * @numerator: return location for numerator * @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 **/ void -gimp_zoom_model_get_fraction (gdouble zoom_factor, - gint *numerator, - gint *denominator) +gimp_zoom_model_get_fraction (GimpZoomModel *model, + gint *numerator, + gint *denominator) { gint p0, p1, p2; gint q0, q1, q2; + gdouble zoom_factor; gdouble remainder, next_cf; gboolean swapped = FALSE; + g_return_if_fail (GIMP_IS_ZOOM_MODEL (model)); g_return_if_fail (numerator != NULL && denominator != NULL); + zoom_factor = gimp_zoom_model_get_factor (model); + /* make sure that zooming behaves symmetrically */ 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: * @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 * 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 * avoid silly jumps from 101% to 100%. + * * The factor 1.1 is chosen a bit arbitrary, but feels better * 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: 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--) new_scale = presets[i]; @@ -507,7 +519,6 @@ gimp_zoom_model_zoom_step (GimpZoomType zoom_type, scale /= ZOOM_MIN_STEP; new_scale = presets[0]; - for (i = 0; i < n_presets && presets[i] < scale; i++) new_scale = presets[i]; diff --git a/libgimpwidgets/gimpzoommodel.h b/libgimpwidgets/gimpzoommodel.h index 3700aaaa15..ccdbe1e8dd 100644 --- a/libgimpwidgets/gimpzoommodel.h +++ b/libgimpwidgets/gimpzoommodel.h @@ -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); -void gimp_zoom_model_set_range (GimpZoomModel *model, - gdouble min, - gdouble max); -gdouble gimp_zoom_model_get_factor (GimpZoomModel *model); +GimpZoomModel * gimp_zoom_model_new (void); +void gimp_zoom_model_set_range (GimpZoomModel *model, + gdouble min, + gdouble max); +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, - GimpZoomWidgetType type); +GtkWidget * gimp_zoom_widget_new (GimpZoomModel *model, + GimpZoomWidgetType type); -void gimp_zoom_model_get_fraction (gdouble zoom_factor, - gint *numerator, - gint *denominator); -gdouble gimp_zoom_model_zoom_step (GimpZoomType zoom_type, - gdouble scale); +gdouble gimp_zoom_model_zoom_step (GimpZoomType zoom_type, + gdouble scale); G_END_DECLS