gimp/libgimpwidgets/gimpresolutionentry.c

1344 lines
41 KiB
C

/* LIBGIMP - The GIMP Library
* Copyright (C) 1995-2005 Peter Mattis and Spencer Kimball
*
* gimpresolutionentry.c
* Copyright (C) 1999-2005 Sven Neumann <sven@gimp.org>
* Michael Natterer <mitch@gimp.org>
* Nathan Summers <rock@gimp.org>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*/
#include "config.h"
#include <gtk/gtk.h>
#include "libgimpbase/gimpbase.h"
#include "gimpwidgets.h"
#include "gimpresolutionentry.h"
#include "libgimp/libgimp-intl.h"
#define SIZE_MAX_VALUE 500000.0
#define GIMP_RESOLUTION_ENTRY_DIGITS(unit) \
(MIN (gimp_unit_get_digits (unit), 5) + 1)
enum
{
WIDTH_CHANGED,
HEIGHT_CHANGED,
X_CHANGED,
Y_CHANGED,
UNIT_CHANGED,
LAST_SIGNAL
};
static void gimp_resolution_entry_class_init (GimpResolutionEntryClass *class);
static void gimp_resolution_entry_init (GimpResolutionEntry *gre);
static void gimp_resolution_entry_finalize (GObject *object);
static void gimp_resolution_entry_update_value (GimpResolutionEntryField *gref,
gdouble value);
static void gimp_resolution_entry_value_callback (GtkWidget *widget,
gpointer data);
static void gimp_resolution_entry_update_unit (GimpResolutionEntry *gre,
GimpUnit unit);
static void gimp_resolution_entry_unit_callback (GtkWidget *widget,
GimpResolutionEntry *gre);
static void gimp_resolution_entry_field_init (GimpResolutionEntry *gre,
GimpResolutionEntryField *gref,
GimpResolutionEntryField *corresponding,
guint changed_signal,
gdouble initial_val,
GimpUnit initial_unit,
gboolean size,
gint spinbutton_width);
static void gimp_resolution_entry_field_set_boundaries
(GimpResolutionEntryField *gref,
gdouble lower,
gdouble upper);
static void gimp_resolution_entry_field_set_value
(GimpResolutionEntryField *gref,
gdouble value);
static void gimp_resolution_entry_format_label (GimpResolutionEntry *gre,
GtkWidget *label,
gdouble size);
static guint gimp_resolution_entry_signals[LAST_SIGNAL] = { 0 };
static GtkTableClass *parent_class = NULL;
GType
gimp_resolution_entry_get_type (void)
{
static GType gre_type = 0;
if (! gre_type)
{
const GTypeInfo gre_info =
{
sizeof (GimpResolutionEntryClass),
(GBaseInitFunc) NULL,
(GBaseFinalizeFunc) NULL,
(GClassInitFunc) gimp_resolution_entry_class_init,
NULL, /* class_finalize */
NULL, /* class_data */
sizeof (GimpResolutionEntry),
0, /* n_preallocs */
(GInstanceInitFunc) gimp_resolution_entry_init,
};
gre_type = g_type_register_static (GTK_TYPE_TABLE,
"GimpResolutionEntry",
&gre_info, 0);
}
return gre_type;
}
static void
gimp_resolution_entry_class_init (GimpResolutionEntryClass *klass)
{
GObjectClass *object_class;
object_class = G_OBJECT_CLASS (klass);
parent_class = g_type_class_peek_parent (klass);
gimp_resolution_entry_signals[HEIGHT_CHANGED] =
g_signal_new ("height-changed",
G_TYPE_FROM_CLASS (klass),
G_SIGNAL_RUN_FIRST,
G_STRUCT_OFFSET (GimpResolutionEntryClass, value_changed),
NULL, NULL,
g_cclosure_marshal_VOID__VOID,
G_TYPE_NONE, 0);
gimp_resolution_entry_signals[WIDTH_CHANGED] =
g_signal_new ("width-changed",
G_TYPE_FROM_CLASS (klass),
G_SIGNAL_RUN_FIRST,
G_STRUCT_OFFSET (GimpResolutionEntryClass, value_changed),
NULL, NULL,
g_cclosure_marshal_VOID__VOID,
G_TYPE_NONE, 0);
gimp_resolution_entry_signals[X_CHANGED] =
g_signal_new ("x-changed",
G_TYPE_FROM_CLASS (klass),
G_SIGNAL_RUN_FIRST,
G_STRUCT_OFFSET (GimpResolutionEntryClass, value_changed),
NULL, NULL,
g_cclosure_marshal_VOID__VOID,
G_TYPE_NONE, 0);
gimp_resolution_entry_signals[Y_CHANGED] =
g_signal_new ("y-changed",
G_TYPE_FROM_CLASS (klass),
G_SIGNAL_RUN_FIRST,
G_STRUCT_OFFSET (GimpResolutionEntryClass, refval_changed),
NULL, NULL,
g_cclosure_marshal_VOID__VOID,
G_TYPE_NONE, 0);
gimp_resolution_entry_signals[UNIT_CHANGED] =
g_signal_new ("unit-changed",
G_TYPE_FROM_CLASS (klass),
G_SIGNAL_RUN_FIRST,
G_STRUCT_OFFSET (GimpResolutionEntryClass, unit_changed),
NULL, NULL,
g_cclosure_marshal_VOID__VOID,
G_TYPE_NONE, 0);
object_class->finalize = gimp_resolution_entry_finalize;
klass->value_changed = NULL;
klass->refval_changed = NULL;
klass->unit_changed = NULL;
}
static void
gimp_resolution_entry_init (GimpResolutionEntry *gre)
{
gre->unitmenu = NULL;
gre->unit = GIMP_UNIT_INCH;
gre->independent = FALSE;
gtk_table_set_col_spacings (GTK_TABLE (gre), 4);
gtk_table_set_row_spacings (GTK_TABLE (gre), 2);
}
static void
gimp_resolution_entry_finalize (GObject *object)
{
GimpResolutionEntry *gre;
g_return_if_fail (GIMP_IS_RESOLUTION_ENTRY (object));
gre = GIMP_RESOLUTION_ENTRY (object);
G_OBJECT_CLASS (parent_class)->finalize (object);
}
static void
gimp_resolution_entry_field_init (GimpResolutionEntry *gre,
GimpResolutionEntryField *gref,
GimpResolutionEntryField *corresponding,
guint changed_signal,
gdouble initial_val,
GimpUnit initial_unit,
gboolean size,
gint spinbutton_width)
{
gint digits;
g_return_if_fail (GIMP_IS_RESOLUTION_ENTRY (gre));
gref->gre = gre;
gref->corresponding = corresponding;
gref->changed_signal = gimp_resolution_entry_signals[changed_signal];
if (size)
{
gref->value = initial_val /
gimp_unit_get_factor (initial_unit) *
corresponding->value *
gimp_unit_get_factor (gre->unit);
gref->phy_size = initial_val /
gimp_unit_get_factor (initial_unit);
}
else
gref->value = initial_val;
gref->min_value = GIMP_MIN_RESOLUTION;
gref->max_value = GIMP_MAX_RESOLUTION;
gref->adjustment = NULL;
gref->stop_recursion = 0;
gref->size = size;
if (size)
{
gref->label = g_object_new (GTK_TYPE_LABEL,
"xalign", 0.0,
"yalign", 0.5,
NULL);
gimp_label_set_attributes (GTK_LABEL (gref->label),
PANGO_ATTR_STYLE, PANGO_STYLE_ITALIC,
-1);
gimp_resolution_entry_format_label (gre, gref->label, gref->phy_size);
}
digits = size ? 0 : GIMP_RESOLUTION_ENTRY_DIGITS (initial_unit);
gref->spinbutton = gimp_spin_button_new (&gref->adjustment,
gref->value,
gref->min_value,
gref->max_value,
1.0, 10.0, 0.0,
1.0,
digits);
if (spinbutton_width > 0)
{
if (spinbutton_width < 17)
gtk_entry_set_width_chars (GTK_ENTRY (gref->spinbutton),
spinbutton_width);
else
gtk_widget_set_size_request (gref->spinbutton,
spinbutton_width, -1);
}
}
/**
* gimp_resolution_entry_new:
* @width_label: Optional label for the width control.
* @width: Width of the item, specified in terms of @size_unit.
* @height_label: Optional label for the height control.
* @height: Height of the item, specified in terms of @size_unit.
* @size_unit: Unit used to specify the width and height.
* @x_label: Optional label for the X resolution entry.
* @initial_x: The initial X resolution.
* @y_label: Optional label for the Y resolution entry. Ignored if
* @independent is %FALSE.
* @initial_y: The initial Y resolution. Ignored if @independent is
* %FALSE.
* @initial_unit: The initial unit.
* @independent: Whether the X and Y resolutions can be different values.
* @spinbutton_width: The minimal horizontal size of the #GtkSpinButton s.
*
* Creates a new #GimpResolutionEntry widget.
*
* The #GimpResolutionEntry is derived from #GtkTable and will have
* an empty border of one cell width on each side plus an empty column left
* of the #GimpUnitMenu to allow the caller to add labels or other widgets.
*
* A #GimpChainButton is displayed if independent is set to %TRUE.
*
* Returns: A pointer to the new #GimpResolutionEntry widget.
*
* Since: GIMP 2.4
**/
GtkWidget *
gimp_resolution_entry_new (const gchar *width_label,
gdouble width,
const gchar *height_label,
gdouble height,
GimpUnit size_unit,
const gchar *x_label,
gdouble initial_x,
const gchar *y_label,
gdouble initial_y,
GimpUnit initial_unit,
gboolean independent,
gint spinbutton_width)
{
GimpResolutionEntry *gre;
gre = g_object_new (GIMP_TYPE_RESOLUTION_ENTRY, NULL);
gre->unit = initial_unit;
gre->independent = independent;
gtk_table_resize (GTK_TABLE (gre),
independent ? 5 : 4,
4);
gimp_resolution_entry_field_init (gre, &gre->x,
&gre->width,
X_CHANGED,
initial_x, initial_unit,
FALSE,
spinbutton_width);
gtk_table_attach_defaults (GTK_TABLE (gre), gre->x.spinbutton,
1, 2,
3, 4);
g_signal_connect (gre->x.adjustment, "value-changed",
G_CALLBACK (gimp_resolution_entry_value_callback),
&gre->x);
gtk_widget_show (gre->x.spinbutton);
if (independent)
{
gre->chainbutton = gimp_chain_button_new (GIMP_CHAIN_RIGHT);
gtk_table_attach (GTK_TABLE (gre), gre->chainbutton,
2, 3,
3, 5,
GTK_SHRINK, GTK_SHRINK | GTK_FILL,
0, 0);
gtk_widget_show (gre->chainbutton);
gimp_resolution_entry_field_init (gre, &gre->y,
&gre->height,
Y_CHANGED,
initial_y, initial_unit,
FALSE,
spinbutton_width);
gtk_table_attach_defaults (GTK_TABLE (gre), gre->y.spinbutton,
1, 2,
4, 5);
g_signal_connect (gre->y.adjustment, "value-changed",
G_CALLBACK (gimp_resolution_entry_value_callback),
&gre->y);
gtk_widget_show (gre->y.spinbutton);
}
gre->unitmenu = gimp_unit_menu_new (_("pixels/%s"), initial_unit,
FALSE, FALSE,
TRUE);
gtk_table_attach (GTK_TABLE (gre), gre->unitmenu,
3, 4,
independent ? 4 : 3, independent ? 5 : 4,
GTK_SHRINK | GTK_FILL, GTK_SHRINK | GTK_FILL, 0, 0);
g_signal_connect (gre->unitmenu, "unit-changed",
G_CALLBACK (gimp_resolution_entry_unit_callback),
gre);
gtk_widget_show (gre->unitmenu);
gimp_resolution_entry_field_init (gre, &gre->width,
&gre->x,
WIDTH_CHANGED,
width, size_unit,
TRUE,
spinbutton_width);
gtk_table_attach_defaults (GTK_TABLE (gre), gre->width.spinbutton,
1, 2,
1, 2);
gtk_table_attach_defaults (GTK_TABLE (gre), gre->width.label,
3, 4,
1, 2);
g_signal_connect (gre->width.adjustment, "value-changed",
G_CALLBACK (gimp_resolution_entry_value_callback),
&gre->width);
gtk_widget_show (gre->width.spinbutton);
gtk_widget_show (gre->width.label);
gimp_resolution_entry_field_init (gre, &gre->height,
independent ? &gre->y : &gre->x,
HEIGHT_CHANGED,
height, size_unit,
TRUE,
spinbutton_width);
gtk_table_attach_defaults (GTK_TABLE (gre), gre->height.spinbutton,
1, 2,
2, 3);
gtk_table_attach_defaults (GTK_TABLE (gre), gre->height.label,
3, 4,
2, 3);
g_signal_connect (gre->height.adjustment, "value-changed",
G_CALLBACK (gimp_resolution_entry_value_callback),
&gre->height);
gtk_widget_show (gre->height.spinbutton);
gtk_widget_show (gre->height.label);
if (width_label)
gimp_resolution_entry_attach_label (gre, width_label, 1, 0, 0.0);
if (height_label)
gimp_resolution_entry_attach_label (gre, height_label, 2, 0, 0.0);
if (x_label)
gimp_resolution_entry_attach_label (gre, x_label, 3, 0, 0.0);
if (independent && y_label)
gimp_resolution_entry_attach_label (gre, y_label, 4, 0, 0.0);
return GTK_WIDGET (gre);
}
/**
* gimp_resolution_entry_attach_label:
* @gre: The #GimpResolutionEntry you want to add a label to.
* @text: The text of the label.
* @row: The row where the label will be attached.
* @column: The column where the label will be attached.
* @alignment: The horizontal alignment of the label.
*
* Attaches a #GtkLabel to the #GimpResolutionEntry (which is a #GtkTable).
*
* Returns: A pointer to the new #GtkLabel widget.
*
* Since: GIMP 2.4
**/
GtkWidget *
gimp_resolution_entry_attach_label (GimpResolutionEntry *gre,
const gchar *text,
gint row,
gint column,
gfloat alignment)
{
GtkWidget *label;
g_return_val_if_fail (GIMP_IS_RESOLUTION_ENTRY (gre), NULL);
g_return_val_if_fail (text != NULL, NULL);
label = gtk_label_new_with_mnemonic (text);
if (column == 0)
{
GtkTableChild *child;
GList *list;
for (list = GTK_TABLE (gre)->children; list; list = g_list_next (list))
{
child = list->data;
if (child->left_attach == 1 && child->top_attach == row)
{
gtk_label_set_mnemonic_widget (GTK_LABEL (label),
child->widget);
break;
}
}
}
gtk_misc_set_alignment (GTK_MISC (label), alignment, 0.5);
gtk_table_attach (GTK_TABLE (gre), label, column, column+1, row, row+1,
GTK_SHRINK | GTK_FILL, GTK_SHRINK | GTK_FILL, 0, 0);
gtk_widget_show (label);
return label;
}
/**
* gimp_resolution_entry_set_width_boundaries:
* @gre: The #GimpResolutionEntry you want to set value boundaries for.
* @lower: The new lower boundary of the value of the field in pixels.
* @upper: The new upper boundary of the value of the field in pixels.
*
* Limits the range of possible values which can be entered in the width field
* of the #GimpResolutionEntry.
*
* The current value of the field will be clamped to fit in its
* new boundaries.
*
* Since: GIMP 2.4
**/
void
gimp_resolution_entry_set_width_boundaries (GimpResolutionEntry *gre,
gdouble lower,
gdouble upper)
{
g_return_if_fail (GIMP_IS_RESOLUTION_ENTRY (gre));
gimp_resolution_entry_field_set_boundaries (&gre->width,
lower,
upper);
}
/**
* gimp_resolution_entry_set_height_boundaries:
* @gre: The #GimpResolutionEntry you want to set value boundaries for.
* @lower: The new lower boundary of the value of the field in pixels.
* @upper: The new upper boundary of the value of the field in pixels.
*
* Limits the range of possible values which can be entered in the height field
* of the #GimpResolutionEntry.
*
* The current value of the field will be clamped to fit in its
* new boundaries.
*
* Since: GIMP 2.4
**/
void
gimp_resolution_entry_set_height_boundaries (GimpResolutionEntry *gre,
gdouble lower,
gdouble upper)
{
g_return_if_fail (GIMP_IS_RESOLUTION_ENTRY (gre));
gimp_resolution_entry_field_set_boundaries (&gre->height,
lower,
upper);
}
/**
* gimp_resolution_entry_set_x_boundaries:
* @gre: The #GimpResolutionEntry you want to set value boundaries for.
* @lower: The new lower boundary of the value of the field, in the current unit.
* @upper: The new upper boundary of the value of the field, in the current unit.
*
* Limits the range of possible values which can be entered in the x field
* of the #GimpResolutionEntry.
*
* The current value of the field will be clamped to fit in its
* new boundaries.
*
* Since: GIMP 2.4
**/
void
gimp_resolution_entry_set_x_boundaries (GimpResolutionEntry *gre,
gdouble lower,
gdouble upper)
{
g_return_if_fail (GIMP_IS_RESOLUTION_ENTRY (gre));
gimp_resolution_entry_field_set_boundaries (&gre->x,
lower,
upper);
}
/**
* gimp_resolution_entry_set_y_boundaries:
* @gre: The #GimpResolutionEntry you want to set value boundaries for.
* @lower: The new lower boundary of the value of the field, in the current unit.
* @upper: The new upper boundary of the value of the field, in the current unit.
*
* Limits the range of possible values which can be entered in the y field
* of the #GimpResolutionEntry.
*
* The current value of the field will be clamped to fit in its
* new boundaries.
*
*
* Since: GIMP 2.4
**/
void
gimp_resolution_entry_set_y_boundaries (GimpResolutionEntry *gre,
gdouble lower,
gdouble upper)
{
g_return_if_fail (GIMP_IS_RESOLUTION_ENTRY (gre));
g_return_if_fail (gre->independent);
gimp_resolution_entry_field_set_boundaries (&gre->y,
lower,
upper);
}
static void
gimp_resolution_entry_field_set_boundaries (GimpResolutionEntryField *gref,
gdouble lower,
gdouble upper)
{
g_return_if_fail (lower <= upper);
gref->min_value = lower;
gref->max_value = upper;
GTK_ADJUSTMENT (gref->adjustment)->lower = gref->min_value;
GTK_ADJUSTMENT (gref->adjustment)->upper = gref->max_value;
if (gref->value > upper || gref->value < lower)
gimp_resolution_entry_field_set_value (gref, gref->value);
}
/**
* gimp_resolution_entry_get_width;
* @gre: The #GimpResolutionEntry you want to know the width of.
*
* Returns the width of the #GimpResolutionEntry in pixels.
*
* SeeAlso: gimp_resolution_get_x
*
* Since: GIMP 2.4
**/
gdouble
gimp_resolution_entry_get_width (GimpResolutionEntry *gre)
{
g_return_val_if_fail (GIMP_IS_RESOLUTION_ENTRY (gre), 0);
return gre->width.value;
}
/**
* gimp_resolution_entry_get_height;
* @gre: The #GimpResolutionEntry you want to know the height of.
*
* Returns the height of the #GimpResolutionEntry in pixels.
*
* SeeAlso: gimp_resolution_get_y
*
* Since: GIMP 2.4
**/
gdouble
gimp_resolution_entry_get_height (GimpResolutionEntry *gre)
{
g_return_val_if_fail (GIMP_IS_RESOLUTION_ENTRY (gre), 0);
return gre->height.value;
}
/**
* gimp_resolution_entry_get_x;
* @gre: The #GimpResolutionEntry you want to know the resolution of.
*
* Returns the X resolution of the #GimpResolutionEntry in the current unit.
*
* SeeAlso: gimp_resolution_get_x_in_dpi
*
* Since: GIMP 2.4
**/
gdouble
gimp_resolution_entry_get_x (GimpResolutionEntry *gre)
{
g_return_val_if_fail (GIMP_IS_RESOLUTION_ENTRY (gre), 0);
return gre->x.value;
}
/**
* gimp_resolution_entry_get_x_in_dpi;
* @gre: The #GimpResolutionEntry you want to know the resolution of.
*
* Returns the X resolution of the #GimpResolutionEntry in pixels per inch.
*
* SeeAlso: gimp_resolution_get_x
*
* Since: GIMP 2.4
**/
gdouble
gimp_resolution_entry_get_x_in_dpi (GimpResolutionEntry *gre)
{
g_return_val_if_fail (GIMP_IS_RESOLUTION_ENTRY (gre), 0);
return gre->x.value / gimp_unit_get_factor (gre->unit);
}
/**
* gimp_resolution_entry_get_y;
* @gre: The #GimpResolutionEntry you want to know the resolution of.
*
* Returns the Y resolution of the #GimpResolutionEntry in the current unit.
*
* SeeAlso: gimp_resolution_get_y_in_dpi
*
* Since: GIMP 2.4
**/
gdouble
gimp_resolution_entry_get_y (GimpResolutionEntry *gre)
{
g_return_val_if_fail (GIMP_IS_RESOLUTION_ENTRY (gre), 0);
return gre->y.value;
}
/**
* gimp_resolution_entry_get_y_in_dpi;
* @gre: The #GimpResolutionEntry you want to know the resolution of.
*
* Returns the Y resolution of the #GimpResolutionEntry in pixels per inch.
*
* SeeAlso: gimp_resolution_get_y
*
* Since: GIMP 2.4
**/
gdouble
gimp_resolution_entry_get_y_in_dpi (GimpResolutionEntry *gre)
{
g_return_val_if_fail (GIMP_IS_RESOLUTION_ENTRY (gre), 0);
return gre->y.value / gimp_unit_get_factor (gre->unit);
}
static void
gimp_resolution_entry_update_value (GimpResolutionEntryField *gref,
gdouble value)
{
if (gref->stop_recursion > 0)
return;
gref->value = value;
gref->stop_recursion++;
if (gref->gre->independent &&
!gref->size &&
gimp_chain_button_get_active (GIMP_CHAIN_BUTTON (gref->gre->chainbutton)))
{
gimp_resolution_entry_update_value (&gref->gre->x, value);
gimp_resolution_entry_update_value (&gref->gre->y, value);
}
if (gref->size)
gimp_resolution_entry_update_value (gref->corresponding,
gref->value /
gref->phy_size /
gimp_unit_get_factor (gref->gre->unit));
else
{
gdouble factor = gimp_unit_get_factor (gref->gre->unit);
if (gref->gre->independent)
gimp_resolution_entry_update_value (gref->corresponding,
gref->value *
gref->corresponding->phy_size *
factor);
else
{
gimp_resolution_entry_update_value (&gref->gre->width,
gref->value *
gref->gre->width.phy_size *
factor);
gimp_resolution_entry_update_value (&gref->gre->height,
gref->value *
gref->gre->height.phy_size *
factor);
}
}
gtk_adjustment_set_value (GTK_ADJUSTMENT (gref->adjustment), value);
gref->stop_recursion--;
g_signal_emit (gref->gre, gref->changed_signal, 0);
}
/**
* gimp_resolution_entry_set_width:
* @gre: The #GimpResolutionEntry you want to set a value for.
* @value: The new value for the width entry.
*
* Sets the value for the width control of the #GimpResolutionEntry.
*
* Since: GIMP 2.4
**/
void
gimp_resolution_entry_set_width (GimpResolutionEntry *gre,
gdouble value)
{
g_return_if_fail (GIMP_IS_RESOLUTION_ENTRY (gre));
gimp_resolution_entry_field_set_value (&gre->width,
value);
}
/**
* gimp_resolution_entry_set_height:
* @gre: The #GimpResolutionEntry you want to set a value for.
* @value: The new value for the height entry.
*
* Sets the value for the height control of the #GimpResolutionEntry.
*
* Since: GIMP 2.4
**/
void
gimp_resolution_entry_set_height (GimpResolutionEntry *gre,
gdouble value)
{
g_return_if_fail (GIMP_IS_RESOLUTION_ENTRY (gre));
gimp_resolution_entry_field_set_value (&gre->height,
value);
}
/**
* gimp_resolution_entry_set_x:
* @gre: The #GimpResolutionEntry you want to set a value for.
* @value: The new value for the X resolution in the current unit.
*
* Sets the value for the x resolution of the #GimpResolutionEntry.
*
* Since: GIMP 2.4
**/
void
gimp_resolution_entry_set_x (GimpResolutionEntry *gre,
gdouble value)
{
g_return_if_fail (GIMP_IS_RESOLUTION_ENTRY (gre));
gimp_resolution_entry_field_set_value (&gre->x,
value);
}
/**
* gimp_resolution_entry_set_y:
* @gre: The #GimpResolutionEntry you want to set a value for.
* @value: The new value for the Y resolution in the current unit.
*
* Sets the value for the y resolution of the #GimpResolutionEntry.
*
* Since: GIMP 2.4
**/
void
gimp_resolution_entry_set_y (GimpResolutionEntry *gre,
gdouble value)
{
g_return_if_fail (GIMP_IS_RESOLUTION_ENTRY (gre));
gimp_resolution_entry_field_set_value (&gre->y,
value);
}
static void
gimp_resolution_entry_field_set_value (GimpResolutionEntryField *gref,
gdouble value)
{
value = CLAMP (value, gref->min_value, gref->max_value);
gtk_adjustment_set_value (GTK_ADJUSTMENT (gref->adjustment), value);
gimp_resolution_entry_update_value (gref, value);
}
static void
gimp_resolution_entry_value_callback (GtkWidget *widget,
gpointer data)
{
GimpResolutionEntryField *gref;
gdouble new_value;
gref = (GimpResolutionEntryField *) data;
new_value = GTK_ADJUSTMENT (widget)->value;
if (gref->value != new_value)
gimp_resolution_entry_update_value (gref, new_value);
}
/**
* gimp_resolution_entry_get_unit:
* @gre: The #GimpResolutionEntry you want to know the unit of.
*
* Returns the #GimpUnit the user has selected in the #GimpResolutionEntry's
* #GimpUnitMenu.
*
* Returns: The #GimpResolutionEntry's unit.
*
* Since: GIMP 2.4
**/
GimpUnit
gimp_resolution_entry_get_unit (GimpResolutionEntry *gre)
{
g_return_val_if_fail (GIMP_IS_RESOLUTION_ENTRY (gre), GIMP_UNIT_INCH);
return gre->unit;
}
static void
gimp_resolution_entry_update_unit (GimpResolutionEntry *gre,
GimpUnit unit)
{
GimpUnit old_unit;
gint digits;
gdouble factor;
old_unit = gre->unit;
gre->unit = unit;
digits = (gimp_unit_get_digits (GIMP_UNIT_INCH) -
gimp_unit_get_digits (unit));
gtk_spin_button_set_digits (GTK_SPIN_BUTTON (gre->x.spinbutton),
MAX (3 + digits, 3));
factor = gimp_unit_get_factor (old_unit) / gimp_unit_get_factor (unit);
gre->x.min_value *= factor;
gre->x.max_value *= factor;
gre->x.value *= factor;
gtk_adjustment_set_value (GTK_ADJUSTMENT (gre->x.adjustment),
gre->x.value);
if (gre->independent)
{
gtk_spin_button_set_digits (GTK_SPIN_BUTTON (gre->y.spinbutton),
MAX (3 + digits, 3));
gre->y.min_value *= factor;
gre->y.max_value *= factor;
gre->y.value *= factor;
gtk_adjustment_set_value (GTK_ADJUSTMENT (gre->y.adjustment),
gre->y.value);
}
gimp_resolution_entry_format_label (gre,
gre->width.label, gre->width.phy_size);
gimp_resolution_entry_format_label (gre,
gre->height.label, gre->height.phy_size);
g_signal_emit (gre, gimp_resolution_entry_signals[UNIT_CHANGED], 0);
}
/**
* gimp_resolution_entry_set_unit:
* @gre: The #GimpResolutionEntry you want to change the unit for.
* @unit: The new unit.
*
* Sets the #GimpResolutionEntry's unit. The resolution will
* stay the same but the value in pixels per unit will change
* accordingly.
*
* Since: Gimp 2.4
**/
void
gimp_resolution_entry_set_unit (GimpResolutionEntry *gre,
GimpUnit unit)
{
g_return_if_fail (GIMP_IS_RESOLUTION_ENTRY (gre));
g_return_if_fail (unit != GIMP_UNIT_PIXEL);
g_return_if_fail (unit != GIMP_UNIT_PERCENT);
gimp_unit_menu_set_unit (GIMP_UNIT_MENU (gre->unitmenu), unit);
gimp_resolution_entry_update_unit (gre, unit);
}
static void
gimp_resolution_entry_unit_callback (GtkWidget *widget,
GimpResolutionEntry *gre)
{
GimpUnit new_unit;
new_unit = gimp_unit_menu_get_unit (GIMP_UNIT_MENU (widget));
if (gre->unit != new_unit)
gimp_resolution_entry_update_unit (gre, new_unit);
}
/**
* gimp_resolution_entry_show_unit_menu:
* @gre: a #GimpResolutionEntry
* @show: Boolean
*
* Controls whether a unit menu is shown in the size entry. If
* @show is #TRUE, the menu is shown; otherwise it is hidden.
*
* Since: GIMP 2.4
**/
void
gimp_resolution_entry_show_unit_menu (GimpResolutionEntry *gre,
gboolean show)
{
g_return_if_fail (GIMP_IS_RESOLUTION_ENTRY (gre));
if (show)
gtk_widget_show (gre->unitmenu);
else
gtk_widget_hide (gre->unitmenu);
}
/**
* gimp_resolution_entry_set_pixel_digits:
* @gre: a #GimpResolutionEntry
* @digits: the number of digits to display for a pixel size
*
* Similar to gimp_unit_menu_set_pixel_digits(), this function allows
* you set up a #GimpResolutionEntry so that sub-pixel sizes can be entered.
*
* Since: GIMP 2.4
**/
void
gimp_resolution_entry_set_pixel_digits (GimpResolutionEntry *gre,
gint digits)
{
GimpUnitMenu *menu;
g_return_if_fail (GIMP_IS_RESOLUTION_ENTRY (gre));
menu = GIMP_UNIT_MENU (gre->unitmenu);
gimp_unit_menu_set_pixel_digits (menu, digits);
gimp_resolution_entry_update_unit (gre, gimp_unit_menu_get_unit (menu));
}
/**
* gimp_resolution_entry_grab_focus:
* @gre: The #GimpResolutionEntry you want to grab the keyboard focus.
*
* This function is rather ugly and just a workaround for the fact that
* it's impossible to implement gtk_widget_grab_focus() for a #GtkTable.
*
* Since: GIMP 2.4
**/
void
gimp_resolution_entry_grab_focus (GimpResolutionEntry *gre)
{
g_return_if_fail (GIMP_IS_RESOLUTION_ENTRY (gre));
gtk_widget_grab_focus (gre->x.spinbutton);
}
/**
* gimp_resolution_entry_set_activates_default:
* @gre: A #GimpResolutionEntry
* @setting: %TRUE to activate window's default widget on Enter keypress
*
* Iterates over all entries in the #GimpResolutionEntry and calls
* gtk_entry_set_activates_default() on them.
*
* Since: GIMP 2.4
**/
void
gimp_resolution_entry_set_activates_default (GimpResolutionEntry *gre,
gboolean setting)
{
g_return_if_fail (GIMP_IS_RESOLUTION_ENTRY (gre));
gtk_entry_set_activates_default (GTK_ENTRY (gre->width.spinbutton),
setting);
gtk_entry_set_activates_default (GTK_ENTRY (gre->height.spinbutton),
setting);
gtk_entry_set_activates_default (GTK_ENTRY (gre->x.spinbutton),
setting);
if (gre->independent)
gtk_entry_set_activates_default (GTK_ENTRY (gre->y.spinbutton),
setting);
}
/**
* gimp_resolution_entry_get_width_help_widget:
* @gre: a #GimpResolutionEntry
*
* You shouldn't fiddle with the internals of a #GimpResolutionEntry but
* if you want to set tooltips using gimp_help_set_help_data() you
* can use this function to get a pointer to the spinbuttons.
*
* Return value: a #GtkWidget pointer that you can attach a tooltip to.
**/
GtkWidget *
gimp_resolution_entry_get_width_help_widget (GimpResolutionEntry *gre)
{
g_return_val_if_fail (GIMP_IS_RESOLUTION_ENTRY (gre), NULL);
return gre->width.spinbutton;
}
/**
* gimp_resolution_entry_get_height_help_widget:
* @gre: a #GimpResolutionEntry
*
* You shouldn't fiddle with the internals of a #GimpResolutionEntry but
* if you want to set tooltips using gimp_help_set_help_data() you
* can use this function to get a pointer to the spinbuttons.
*
* Return value: a #GtkWidget pointer that you can attach a tooltip to.
**/
GtkWidget *
gimp_resolution_entry_get_height_help_widget (GimpResolutionEntry *gre)
{
g_return_val_if_fail (GIMP_IS_RESOLUTION_ENTRY (gre), NULL);
return gre->height.spinbutton;
}
/**
* gimp_resolution_entry_get_x_help_widget:
* @gre: a #GimpResolutionEntry
*
* You shouldn't fiddle with the internals of a #GimpResolutionEntry but
* if you want to set tooltips using gimp_help_set_help_data() you
* can use this function to get a pointer to the spinbuttons.
*
* Return value: a #GtkWidget pointer that you can attach a tooltip to.
**/
GtkWidget *
gimp_resolution_entry_get_x_help_widget (GimpResolutionEntry *gre)
{
g_return_val_if_fail (GIMP_IS_RESOLUTION_ENTRY (gre), NULL);
return gre->x.spinbutton;
}
/**
* gimp_resolution_entry_get_x_help_widget:
* @gre: a #GimpResolutionEntry
*
* You shouldn't fiddle with the internals of a #GimpResolutionEntry but
* if you want to set tooltips using gimp_help_set_help_data() you
* can use this function to get a pointer to the spinbuttons.
*
* Return value: a #GtkWidget pointer that you can attach a tooltip to.
**/
GtkWidget *
gimp_resolution_entry_get_y_help_widget (GimpResolutionEntry *gre)
{
g_return_val_if_fail (GIMP_IS_RESOLUTION_ENTRY (gre), NULL);
g_return_val_if_fail (gre->independent, NULL);
return gre->x.spinbutton;
}
/**
* gimp_resolution_entry_update_width:
* @gre: the #GimpResolutionEntry
* @data: a pointer to a gdouble
*
* Convenience function to set a double to the width, suitable
* for use as a signal callback.
*
* Since: GIMP 2.4
*/
void
gimp_resolution_entry_update_width (GimpResolutionEntry *gre,
gpointer data)
{
gdouble *val;
g_return_if_fail (gre != NULL);
g_return_if_fail (data != NULL);
g_return_if_fail (GIMP_IS_RESOLUTION_ENTRY (gre));
val = (gdouble *) data;
*val = gimp_resolution_entry_get_width (gre);
}
/**
* gimp_resolution_entry_update_height:
* @gre: the #GimpResolutionEntry
* @data: a pointer to a gdouble
*
* Convenience function to set a double to the height, suitable
* for use as a signal callback.
*
* Since: GIMP 2.4
*/
void
gimp_resolution_entry_update_height (GimpResolutionEntry *gre,
gpointer data)
{
gdouble *val;
g_return_if_fail (gre != NULL);
g_return_if_fail (data != NULL);
g_return_if_fail (GIMP_IS_RESOLUTION_ENTRY (gre));
val = (gdouble *) data;
*val = gimp_resolution_entry_get_height (gre);
}
/**
* gimp_resolution_entry_update_x:
* @gre: the #GimpResolutionEntry
* @data: a pointer to a gdouble
*
* Convenience function to set a double to the X resolution, suitable
* for use as a signal callback.
*
* Since: GIMP 2.4
*/
void
gimp_resolution_entry_update_x (GimpResolutionEntry *gre,
gpointer data)
{
gdouble *val;
g_return_if_fail (gre != NULL);
g_return_if_fail (data != NULL);
g_return_if_fail (GIMP_IS_RESOLUTION_ENTRY (gre));
val = (gdouble *) data;
*val = gimp_resolution_entry_get_x (gre);
}
/**
* gimp_resolution_entry_update_x_in_dpi:
* @gre: the #GimpResolutionEntry
* @data: a pointer to a gdouble
*
* Convenience function to set a double to the X resolution, suitable
* for use as a signal callback.
*
* Since: GIMP 2.4
*/
void
gimp_resolution_entry_update_x_in_dpi (GimpResolutionEntry *gre,
gpointer data)
{
gdouble *val;
g_return_if_fail (gre != NULL);
g_return_if_fail (data != NULL);
g_return_if_fail (GIMP_IS_RESOLUTION_ENTRY (gre));
val = (gdouble *) data;
*val = gimp_resolution_entry_get_x_in_dpi (gre);
}
/**
* gimp_resolution_entry_update_y:
* @gre: the #GimpResolutionEntry
* @data: a pointer to a gdouble
*
* Convenience function to set a double to the Y resolution, suitable
* for use as a signal callback.
*
* Since: GIMP 2.4
*/
void
gimp_resolution_entry_update_y (GimpResolutionEntry *gre,
gpointer data)
{
gdouble *val;
g_return_if_fail (gre != NULL);
g_return_if_fail (data != NULL);
g_return_if_fail (GIMP_IS_RESOLUTION_ENTRY (gre));
val = (gdouble *) data;
*val = gimp_resolution_entry_get_y (gre);
}
/**
* gimp_resolution_entry_update_y_in_dpi:
* @gre: the #GimpResolutionEntry
* @data: a pointer to a gdouble
*
* Convenience function to set a double to the Y resolution, suitable
* for use as a signal callback.
*
* Since: GIMP 2.4
*/
void
gimp_resolution_entry_update_y_in_dpi (GimpResolutionEntry *gre,
gpointer data)
{
gdouble *val;
g_return_if_fail (gre != NULL);
g_return_if_fail (data != NULL);
g_return_if_fail (GIMP_IS_RESOLUTION_ENTRY (gre));
val = (gdouble *) data;
*val = gimp_resolution_entry_get_y_in_dpi (gre);
}
static void
gimp_resolution_entry_format_label (GimpResolutionEntry *gre,
GtkWidget *label,
gdouble size)
{
gchar *format = g_strdup_printf ("%%.%df %%s",
gimp_unit_get_digits (gre->unit));
gchar *text = g_strdup_printf (format,
size * gimp_unit_get_factor (gre->unit),
gimp_unit_get_plural (gre->unit));
g_free (format);
gtk_label_set_text (GTK_LABEL (label), text);
g_free (text);
}