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>
* 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,
new_gimage,
shell->unit, shell->scale);
shell->unit,
gimp_zoom_model_get_factor (shell->zoom));
g_object_unref (new_gimage);
}

View File

@ -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

View File

@ -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);
}

View File

@ -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);
}

View File

@ -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);

View File

@ -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 */

View File

@ -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);

View File

@ -22,32 +22,34 @@
#include <gtk/gtkwindow.h>
#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? */

View File

@ -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,

View File

@ -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);

View File

@ -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...

View File

@ -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)

View File

@ -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

View File

@ -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];

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);
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