mirror of https://github.com/GNOME/gimp.git
New files implementing a widget for entering ratios. Will be improved over
2006-12-30 Simon Budig <simon@gimp.org> * libgimpwidgets/gimpratioentry.[ch]: New files implementing a widget for entering ratios. Will be improved over time... * libgimpwidgets/gimpwidgetstypes.h * libgimpwidgets/gimpwidgets.h * libgimpwidgets/Makefile.am: changed accordingly. * app/widgets/gimppropwidgets.c: use it for the crop/rectangle select tools. svn path=/trunk/; revision=21613
This commit is contained in:
parent
930d6149da
commit
7a3eb8dcd3
12
ChangeLog
12
ChangeLog
|
@ -1,3 +1,15 @@
|
||||||
|
2006-12-30 Simon Budig <simon@gimp.org>
|
||||||
|
|
||||||
|
* libgimpwidgets/gimpratioentry.[ch]: New files implementing a widget
|
||||||
|
for entering ratios. Will be improved over time...
|
||||||
|
|
||||||
|
* libgimpwidgets/gimpwidgetstypes.h
|
||||||
|
* libgimpwidgets/gimpwidgets.h
|
||||||
|
* libgimpwidgets/Makefile.am: changed accordingly.
|
||||||
|
|
||||||
|
* app/widgets/gimppropwidgets.c: use it for the crop/rectangle
|
||||||
|
select tools.
|
||||||
|
|
||||||
2006-12-30 Sven Neumann <sven@gimp.org>
|
2006-12-30 Sven Neumann <sven@gimp.org>
|
||||||
|
|
||||||
* plug-ins/print/print.c: use a GtkMessageDialog to display errors.
|
* plug-ins/print/print.c: use a GtkMessageDialog to display errors.
|
||||||
|
|
|
@ -558,20 +558,16 @@ typedef struct
|
||||||
const gchar *height_property;
|
const gchar *height_property;
|
||||||
} AspectData;
|
} AspectData;
|
||||||
|
|
||||||
static void gimp_prop_numeric_entry_notify (GObject *config,
|
static void gimp_prop_ratio_entry_notify (GObject *config,
|
||||||
GParamSpec *param_spec,
|
GParamSpec *param_spec,
|
||||||
GtkEntry *entry);
|
GtkEntry *entry);
|
||||||
|
|
||||||
static void gimp_prop_numeric_entry_callback (GtkWidget *widget,
|
|
||||||
GObject *config);
|
|
||||||
|
|
||||||
static gboolean gimp_prop_numeric_entry_focus_out (GtkWidget *widget,
|
|
||||||
GdkEventFocus *event,
|
|
||||||
GObject *config);
|
|
||||||
static void gimp_prop_aspect_ratio_flip (GtkWidget *widget,
|
static void gimp_prop_aspect_ratio_flip (GtkWidget *widget,
|
||||||
gpointer data);
|
gpointer data);
|
||||||
static void gimp_prop_aspect_ratio_square (GtkWidget *widget,
|
static void gimp_prop_aspect_ratio_square (GtkWidget *widget,
|
||||||
gpointer data);
|
gpointer data);
|
||||||
|
static void gimp_prop_aspect_ratio_ratio (GtkWidget *widget,
|
||||||
|
gpointer data);
|
||||||
static void gimp_prop_aspect_ratio_set (GtkWidget *widget,
|
static void gimp_prop_aspect_ratio_set (GtkWidget *widget,
|
||||||
gpointer data);
|
gpointer data);
|
||||||
|
|
||||||
|
@ -614,14 +610,11 @@ gimp_prop_aspect_ratio_new (GObject *config,
|
||||||
gint col0)
|
gint col0)
|
||||||
{
|
{
|
||||||
AspectData *aspect_data;
|
AspectData *aspect_data;
|
||||||
GParamSpec *param_spec;
|
|
||||||
GtkWidget *label;
|
|
||||||
GtkWidget *entry;
|
GtkWidget *entry;
|
||||||
GtkWidget *hbox;
|
GtkWidget *hbox;
|
||||||
GtkWidget *button;
|
GtkWidget *button;
|
||||||
gdouble numerator;
|
gdouble numerator;
|
||||||
gdouble denominator;
|
gdouble denominator;
|
||||||
gchar num_string[20];
|
|
||||||
|
|
||||||
g_object_get (config,
|
g_object_get (config,
|
||||||
numerator_property, &numerator,
|
numerator_property, &numerator,
|
||||||
|
@ -636,53 +629,23 @@ gimp_prop_aspect_ratio_new (GObject *config,
|
||||||
aspect_data->width_property = width_property;
|
aspect_data->width_property = width_property;
|
||||||
aspect_data->height_property = height_property;
|
aspect_data->height_property = height_property;
|
||||||
|
|
||||||
/* numerator entry */
|
entry = gimp_ratio_entry_new ();
|
||||||
param_spec = find_param_spec (config, numerator_property, G_STRFUNC);
|
g_object_set_data (G_OBJECT (entry),
|
||||||
if (! param_spec)
|
"gimp-ratio-entry-aspect-data",
|
||||||
return;
|
aspect_data);
|
||||||
entry = gtk_entry_new ();
|
gtk_entry_set_width_chars (GTK_ENTRY (entry), 9);
|
||||||
gtk_entry_set_width_chars (GTK_ENTRY (entry), 5);
|
gimp_ratio_entry_set_fraction (GIMP_RATIO_ENTRY (entry),
|
||||||
sprintf (num_string, "%lg", numerator);
|
numerator, denominator);
|
||||||
gtk_entry_set_text (GTK_ENTRY (entry), num_string);
|
|
||||||
gtk_table_attach_defaults (GTK_TABLE (table), entry,
|
gtk_table_attach_defaults (GTK_TABLE (table), entry,
|
||||||
col0, col0 + 1, row0, row0 + 1);
|
col0, col0 + 3, row0, row0 + 1);
|
||||||
set_param_spec (G_OBJECT (entry), entry, param_spec);
|
g_signal_connect (entry, "ratio-changed",
|
||||||
g_signal_connect (entry, "activate",
|
G_CALLBACK (gimp_prop_aspect_ratio_ratio),
|
||||||
G_CALLBACK (gimp_prop_numeric_entry_callback),
|
aspect_data);
|
||||||
config);
|
|
||||||
g_signal_connect (entry, "focus-out-event",
|
|
||||||
G_CALLBACK (gimp_prop_numeric_entry_focus_out),
|
|
||||||
config);
|
|
||||||
connect_notify (config, numerator_property,
|
connect_notify (config, numerator_property,
|
||||||
G_CALLBACK (gimp_prop_numeric_entry_notify),
|
G_CALLBACK (gimp_prop_ratio_entry_notify),
|
||||||
entry);
|
entry);
|
||||||
gtk_widget_show (entry);
|
|
||||||
|
|
||||||
/* ":" label */
|
|
||||||
label = gtk_label_new (":");
|
|
||||||
gtk_table_attach_defaults (GTK_TABLE (table), label,
|
|
||||||
col0 + 1, col0 + 2, row0, row0 + 1);
|
|
||||||
gtk_widget_show (label);
|
|
||||||
|
|
||||||
/* denominator entry */
|
|
||||||
param_spec = find_param_spec (config, denominator_property, G_STRFUNC);
|
|
||||||
if (! param_spec)
|
|
||||||
return;
|
|
||||||
entry = gtk_entry_new ();
|
|
||||||
gtk_entry_set_width_chars (GTK_ENTRY (entry), 5);
|
|
||||||
sprintf (num_string, "%lg", denominator);
|
|
||||||
gtk_entry_set_text (GTK_ENTRY (entry), num_string);
|
|
||||||
gtk_table_attach_defaults (GTK_TABLE (table), entry,
|
|
||||||
col0 + 2, col0 + 3, row0, row0 + 1);
|
|
||||||
set_param_spec (G_OBJECT (entry), entry, param_spec);
|
|
||||||
g_signal_connect (entry, "activate",
|
|
||||||
G_CALLBACK (gimp_prop_numeric_entry_callback),
|
|
||||||
config);
|
|
||||||
g_signal_connect (entry, "focus-out-event",
|
|
||||||
G_CALLBACK (gimp_prop_numeric_entry_focus_out),
|
|
||||||
config);
|
|
||||||
connect_notify (config, denominator_property,
|
connect_notify (config, denominator_property,
|
||||||
G_CALLBACK (gimp_prop_numeric_entry_notify),
|
G_CALLBACK (gimp_prop_ratio_entry_notify),
|
||||||
entry);
|
entry);
|
||||||
gtk_widget_show (entry);
|
gtk_widget_show (entry);
|
||||||
|
|
||||||
|
@ -717,53 +680,23 @@ gimp_prop_aspect_ratio_new (GObject *config,
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
gimp_prop_numeric_entry_notify (GObject *config,
|
gimp_prop_ratio_entry_notify (GObject *config,
|
||||||
GParamSpec *param_spec,
|
GParamSpec *param_spec,
|
||||||
GtkEntry *entry)
|
GtkEntry *entry)
|
||||||
{
|
{
|
||||||
gdouble value;
|
AspectData *aspect_data = g_object_get_data (G_OBJECT (entry),
|
||||||
gchar text[20];
|
"gimp-ratio-entry-aspect-data");
|
||||||
|
|
||||||
g_object_get (config, param_spec->name, &value, NULL);
|
gdouble num, denom;
|
||||||
|
|
||||||
sprintf (text, "%3lg", value);
|
g_return_if_fail (aspect_data != NULL);
|
||||||
|
|
||||||
gtk_entry_set_text (entry, text);
|
g_object_get (config,
|
||||||
}
|
aspect_data->numerator_property, &num,
|
||||||
|
aspect_data->denominator_property, &denom,
|
||||||
|
NULL);
|
||||||
|
|
||||||
static gboolean
|
gimp_ratio_entry_set_fraction (GTK_RATIO_ENTRY (entry), num, denom);
|
||||||
gimp_prop_numeric_entry_focus_out (GtkWidget *widget,
|
|
||||||
GdkEventFocus *event,
|
|
||||||
GObject *config)
|
|
||||||
{
|
|
||||||
gimp_prop_numeric_entry_callback (widget, config);
|
|
||||||
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
gimp_prop_numeric_entry_callback (GtkWidget *widget,
|
|
||||||
GObject *config)
|
|
||||||
{
|
|
||||||
GParamSpec *param_spec;
|
|
||||||
gdouble value;
|
|
||||||
|
|
||||||
g_return_if_fail (GTK_IS_ENTRY (widget));
|
|
||||||
|
|
||||||
param_spec = get_param_spec (G_OBJECT (widget));
|
|
||||||
if (! param_spec)
|
|
||||||
return;
|
|
||||||
|
|
||||||
/* we use strtod instead of g_ascii_strtod because it uses the locale,
|
|
||||||
which is what we want here */
|
|
||||||
value = strtod (gtk_entry_get_text (GTK_ENTRY (widget)), NULL);
|
|
||||||
|
|
||||||
if (value != 0)
|
|
||||||
g_object_set (config,
|
|
||||||
param_spec->name, value,
|
|
||||||
NULL);
|
|
||||||
else
|
|
||||||
g_message ("Invalid value entered for aspect ratio.");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -830,6 +763,22 @@ gimp_prop_aspect_ratio_square (GtkWidget *widget,
|
||||||
NULL);
|
NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
gimp_prop_aspect_ratio_ratio (GtkWidget *widget,
|
||||||
|
gpointer data)
|
||||||
|
{
|
||||||
|
AspectData *aspect_data = data;
|
||||||
|
gdouble num, denom;
|
||||||
|
|
||||||
|
gimp_ratio_entry_get_fraction (GIMP_RATIO_ENTRY (widget), &num, &denom);
|
||||||
|
|
||||||
|
g_object_set (aspect_data->config,
|
||||||
|
aspect_data->numerator_property, num,
|
||||||
|
aspect_data->denominator_property, denom,
|
||||||
|
aspect_data->fixed_aspect_property, TRUE,
|
||||||
|
NULL);
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
gimp_prop_aspect_ratio_set (GtkWidget *widget,
|
gimp_prop_aspect_ratio_set (GtkWidget *widget,
|
||||||
gpointer data)
|
gpointer data)
|
||||||
|
|
|
@ -142,6 +142,8 @@ libgimpwidgets_2_0_la_sources = \
|
||||||
gimppropwidgets.h \
|
gimppropwidgets.h \
|
||||||
gimpquerybox.c \
|
gimpquerybox.c \
|
||||||
gimpquerybox.h \
|
gimpquerybox.h \
|
||||||
|
gimpratioentry.c \
|
||||||
|
gimpratioentry.h \
|
||||||
gimpresolutionentry.c \
|
gimpresolutionentry.c \
|
||||||
gimpresolutionentry.h \
|
gimpresolutionentry.h \
|
||||||
gimpscrolledpreview.c \
|
gimpscrolledpreview.c \
|
||||||
|
|
|
@ -0,0 +1,424 @@
|
||||||
|
/* LIBGIMP - The GIMP Library
|
||||||
|
* Copyright (C) 1995-1997 Peter Mattis and Spencer Kimball
|
||||||
|
*
|
||||||
|
* gimpratioentry.c
|
||||||
|
* Copyright (C) 2006 Simon Budig <simon@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 <math.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#include <gtk/gtk.h>
|
||||||
|
#include <gdk/gdkkeysyms.h>
|
||||||
|
|
||||||
|
#include "gimpwidgetstypes.h"
|
||||||
|
|
||||||
|
#include "gimpratioentry.h"
|
||||||
|
|
||||||
|
#define EPSILON 0.000001
|
||||||
|
|
||||||
|
enum
|
||||||
|
{
|
||||||
|
RATIO_CHANGED,
|
||||||
|
LAST_SIGNAL
|
||||||
|
};
|
||||||
|
|
||||||
|
enum
|
||||||
|
{
|
||||||
|
PROP_0,
|
||||||
|
PROP_RATIO,
|
||||||
|
PROP_NUMERATOR,
|
||||||
|
PROP_DENOMINATOR,
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
static void gimp_ratio_entry_set_property (GObject *object,
|
||||||
|
guint property_id,
|
||||||
|
const GValue *value,
|
||||||
|
GParamSpec *pspec);
|
||||||
|
static void gimp_ratio_entry_get_property (GObject *object,
|
||||||
|
guint property_id,
|
||||||
|
GValue *value,
|
||||||
|
GParamSpec *pspec);
|
||||||
|
static gboolean gimp_ratio_entry_events (GtkWidget *widget,
|
||||||
|
GdkEvent *event);
|
||||||
|
static void gimp_ratio_entry_format_text (GimpRatioEntry *entry);
|
||||||
|
static void gimp_ratio_entry_parse_text (GimpRatioEntry *entry,
|
||||||
|
const gchar *text);
|
||||||
|
|
||||||
|
G_DEFINE_TYPE (GimpRatioEntry, gimp_ratio_entry, GTK_TYPE_ENTRY)
|
||||||
|
|
||||||
|
#define parent_class gimp_ratio_entry_parent_class
|
||||||
|
|
||||||
|
static guint entry_signals[LAST_SIGNAL] = { 0 };
|
||||||
|
|
||||||
|
|
||||||
|
static void
|
||||||
|
gimp_ratio_entry_class_init (GimpRatioEntryClass *klass)
|
||||||
|
{
|
||||||
|
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
||||||
|
|
||||||
|
entry_signals[RATIO_CHANGED] =
|
||||||
|
g_signal_new ("ratio-changed",
|
||||||
|
G_TYPE_FROM_CLASS (klass),
|
||||||
|
G_SIGNAL_RUN_FIRST,
|
||||||
|
G_STRUCT_OFFSET (GimpRatioEntryClass, ratio_changed),
|
||||||
|
NULL, NULL,
|
||||||
|
g_cclosure_marshal_VOID__VOID,
|
||||||
|
G_TYPE_NONE, 0);
|
||||||
|
|
||||||
|
klass->ratio_changed = NULL;
|
||||||
|
|
||||||
|
object_class->set_property = gimp_ratio_entry_set_property;
|
||||||
|
object_class->get_property = gimp_ratio_entry_get_property;
|
||||||
|
|
||||||
|
g_object_class_install_property (object_class, PROP_RATIO,
|
||||||
|
g_param_spec_double ("ratio",
|
||||||
|
"Ratio", NULL,
|
||||||
|
G_MINDOUBLE, G_MAXDOUBLE,
|
||||||
|
1.0,
|
||||||
|
GIMP_PARAM_READWRITE));
|
||||||
|
g_object_class_install_property (object_class, PROP_NUMERATOR,
|
||||||
|
g_param_spec_double ("numerator",
|
||||||
|
"Numerator of the ratio", NULL,
|
||||||
|
G_MINDOUBLE, G_MAXDOUBLE,
|
||||||
|
1.0,
|
||||||
|
GIMP_PARAM_READWRITE));
|
||||||
|
g_object_class_install_property (object_class, PROP_DENOMINATOR,
|
||||||
|
g_param_spec_double ("denominator",
|
||||||
|
"Denominator of the ratio", NULL,
|
||||||
|
G_MINDOUBLE, G_MAXDOUBLE,
|
||||||
|
1.0,
|
||||||
|
GIMP_PARAM_READWRITE));
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
gimp_ratio_entry_set_property (GObject *object,
|
||||||
|
guint property_id,
|
||||||
|
const GValue *value,
|
||||||
|
GParamSpec *pspec)
|
||||||
|
{
|
||||||
|
GimpRatioEntry *entry = GIMP_RATIO_ENTRY (object);
|
||||||
|
|
||||||
|
switch (property_id)
|
||||||
|
{
|
||||||
|
case PROP_RATIO:
|
||||||
|
gimp_ratio_entry_set_ratio (entry, g_value_get_double (value));
|
||||||
|
break;
|
||||||
|
case PROP_NUMERATOR:
|
||||||
|
gimp_ratio_entry_set_fraction (entry,
|
||||||
|
g_value_get_double (value),
|
||||||
|
entry->denominator);
|
||||||
|
break;
|
||||||
|
case PROP_DENOMINATOR:
|
||||||
|
gimp_ratio_entry_set_fraction (entry,
|
||||||
|
entry->numerator,
|
||||||
|
g_value_get_double (value));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
gimp_ratio_entry_get_property (GObject *object,
|
||||||
|
guint property_id,
|
||||||
|
GValue *value,
|
||||||
|
GParamSpec *pspec)
|
||||||
|
{
|
||||||
|
GimpRatioEntry *entry = GIMP_RATIO_ENTRY (object);
|
||||||
|
|
||||||
|
switch (property_id)
|
||||||
|
{
|
||||||
|
case PROP_RATIO:
|
||||||
|
g_value_set_double (value, gimp_ratio_entry_get_ratio (entry));
|
||||||
|
break;
|
||||||
|
case PROP_NUMERATOR:
|
||||||
|
g_value_set_double (value, entry->numerator);
|
||||||
|
break;
|
||||||
|
case PROP_DENOMINATOR:
|
||||||
|
g_value_set_double (value, entry->denominator);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void
|
||||||
|
gimp_ratio_entry_init (GimpRatioEntry *entry)
|
||||||
|
{
|
||||||
|
entry->numerator = 1;
|
||||||
|
entry->denominator = 1;
|
||||||
|
|
||||||
|
gtk_entry_set_text (GTK_ENTRY (entry), "1:1");
|
||||||
|
|
||||||
|
g_signal_connect (entry, "focus-out-event",
|
||||||
|
G_CALLBACK (gimp_ratio_entry_events),
|
||||||
|
NULL);
|
||||||
|
g_signal_connect (entry, "key-press-event",
|
||||||
|
G_CALLBACK (gimp_ratio_entry_events),
|
||||||
|
NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* gimp_ratio_entry_new:
|
||||||
|
*
|
||||||
|
* Return value: a new #GimpRatioEntry widget
|
||||||
|
*
|
||||||
|
* Since: GIMP 2.4
|
||||||
|
**/
|
||||||
|
GtkWidget *
|
||||||
|
gimp_ratio_entry_new (void)
|
||||||
|
{
|
||||||
|
return g_object_new (GIMP_TYPE_RATIO_ENTRY, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* gimp_ratio_entry_set_ratio:
|
||||||
|
* @entry: a #GimpRatioEntry widget
|
||||||
|
* @ratio: ratio to set in the widget
|
||||||
|
* @calc_fraction: convert into a fraction?
|
||||||
|
*
|
||||||
|
* Sets the ratio displayed by a #GimpRatioEntry. If the new ratio is
|
||||||
|
* different than the previous ratio, the "ratio-changed" signal is
|
||||||
|
* emitted.
|
||||||
|
*
|
||||||
|
* An attempt is made to convert the decimal number into a fraction with
|
||||||
|
* numerator and denominator < 1000.
|
||||||
|
*
|
||||||
|
* Since: GIMP 2.4
|
||||||
|
**/
|
||||||
|
void
|
||||||
|
gimp_ratio_entry_set_ratio (GimpRatioEntry *entry,
|
||||||
|
gdouble ratio)
|
||||||
|
{
|
||||||
|
gdouble remainder, next_cf;
|
||||||
|
gint p0, p1, p2;
|
||||||
|
gint q0, q1, q2;
|
||||||
|
|
||||||
|
/* calculate the continued fraction to approximate the desired ratio */
|
||||||
|
|
||||||
|
p0 = 1;
|
||||||
|
q0 = 0;
|
||||||
|
p1 = floor (ratio);
|
||||||
|
q1 = 1;
|
||||||
|
|
||||||
|
remainder = ratio - p1;
|
||||||
|
|
||||||
|
while (fabs (remainder) >= 0.0001 &&
|
||||||
|
fabs (((gdouble) p1 / q1) - ratio) > 0.0001)
|
||||||
|
{
|
||||||
|
remainder = 1.0 / remainder;
|
||||||
|
|
||||||
|
next_cf = floor (remainder);
|
||||||
|
|
||||||
|
p2 = next_cf * p1 + p0;
|
||||||
|
q2 = next_cf * q1 + q0;
|
||||||
|
|
||||||
|
/* remember the last two fractions */
|
||||||
|
p0 = p1;
|
||||||
|
q0 = q1;
|
||||||
|
p1 = p2;
|
||||||
|
q1 = q2;
|
||||||
|
|
||||||
|
remainder = remainder - next_cf;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* only use the calculated fraction if it is "reasonable" */
|
||||||
|
if (p1 < 1000 && q1 < 1000)
|
||||||
|
gimp_ratio_entry_set_fraction (entry, p1, q1);
|
||||||
|
else
|
||||||
|
gimp_ratio_entry_set_fraction (entry, ratio, 1.0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* gimp_ratio_entry_get_ratio:
|
||||||
|
* @entry: a #GimpRatioEntry widget
|
||||||
|
*
|
||||||
|
* Retrieves the ratio value displayed by a #GimpRatioEntry.
|
||||||
|
*
|
||||||
|
* Since: GIMP 2.4
|
||||||
|
**/
|
||||||
|
gdouble
|
||||||
|
gimp_ratio_entry_get_ratio (GimpRatioEntry *entry)
|
||||||
|
{
|
||||||
|
return entry->denominator == 0.0 ? entry->numerator :
|
||||||
|
entry->numerator / entry->denominator;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* gimp_ratio_entry_set_fraction:
|
||||||
|
* @entry: a #GimpRatioEntry widget
|
||||||
|
* @numerator: numerator of the fraction to set in the widget
|
||||||
|
* @denominator: denominator of the fraction to set in the widget
|
||||||
|
*
|
||||||
|
* Sets the fraction displayed by a #GimpRatioEntry. If the resulting
|
||||||
|
* ratio is different to the previously set ratio, the "ratio-changed"
|
||||||
|
* signal is emitted.
|
||||||
|
*
|
||||||
|
* If the denominator is zero, the #GimpRatioEntry will silently
|
||||||
|
* convert it to 1.0.
|
||||||
|
*
|
||||||
|
* Since: GIMP 2.4
|
||||||
|
**/
|
||||||
|
void
|
||||||
|
gimp_ratio_entry_set_fraction (GimpRatioEntry *entry,
|
||||||
|
const gdouble numerator,
|
||||||
|
const gdouble denominator)
|
||||||
|
{
|
||||||
|
gdouble old_ratio;
|
||||||
|
g_return_if_fail (GIMP_IS_RATIO_ENTRY (entry));
|
||||||
|
|
||||||
|
old_ratio = entry->numerator / entry->denominator;
|
||||||
|
|
||||||
|
entry->numerator = numerator;
|
||||||
|
entry->denominator = denominator;
|
||||||
|
|
||||||
|
if (entry->denominator < 0)
|
||||||
|
{
|
||||||
|
entry->numerator *= -1;
|
||||||
|
entry->denominator *= -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (entry->denominator < EPSILON)
|
||||||
|
entry->denominator = 1.0;
|
||||||
|
|
||||||
|
gimp_ratio_entry_format_text (entry);
|
||||||
|
|
||||||
|
if (fabs (old_ratio - entry->numerator / entry->denominator) > EPSILON)
|
||||||
|
g_signal_emit (entry, entry_signals[RATIO_CHANGED], 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* gimp_ratio_entry_get_fraction:
|
||||||
|
* @entry: a #GimpRatioEntry widget
|
||||||
|
* @numerator: pointer to store the numerator of the fraction
|
||||||
|
* @denominator: pointer to store the denominator of the fraction
|
||||||
|
*
|
||||||
|
* Gets the fraction displayed by a #GimpRatioEntry.
|
||||||
|
*
|
||||||
|
* The denominator may be zero if the #GimpRatioEntry shows just a single
|
||||||
|
* value. You can use #gimp_ratio_entry_get_ratio to retrieve the ratio
|
||||||
|
* as a single decimal value.
|
||||||
|
*
|
||||||
|
* Since: GIMP 2.4
|
||||||
|
**/
|
||||||
|
void
|
||||||
|
gimp_ratio_entry_get_fraction (GimpRatioEntry *entry,
|
||||||
|
gdouble *numerator,
|
||||||
|
gdouble *denominator)
|
||||||
|
{
|
||||||
|
g_return_if_fail (GIMP_IS_RATIO_ENTRY (entry));
|
||||||
|
g_return_if_fail (numerator != NULL);
|
||||||
|
g_return_if_fail (denominator != NULL);
|
||||||
|
|
||||||
|
*numerator = entry->numerator;
|
||||||
|
*denominator = entry->denominator;
|
||||||
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
gimp_ratio_entry_events (GtkWidget *widget,
|
||||||
|
GdkEvent *event)
|
||||||
|
{
|
||||||
|
GimpRatioEntry *entry = GIMP_RATIO_ENTRY (widget);
|
||||||
|
const gchar *text;
|
||||||
|
|
||||||
|
switch (event->type)
|
||||||
|
{
|
||||||
|
case GDK_KEY_PRESS:
|
||||||
|
if (((GdkEventKey *) event)->keyval != GDK_Return)
|
||||||
|
break;
|
||||||
|
/* else fall through */
|
||||||
|
|
||||||
|
case GDK_FOCUS_CHANGE:
|
||||||
|
text = gtk_entry_get_text (GTK_ENTRY (entry));
|
||||||
|
gimp_ratio_entry_parse_text (entry, text);
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
/* do nothing */
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
gimp_ratio_entry_format_text (GimpRatioEntry *entry)
|
||||||
|
{
|
||||||
|
gchar *buffer;
|
||||||
|
|
||||||
|
buffer = g_strdup_printf ("%g:%g", entry->numerator, entry->denominator);
|
||||||
|
|
||||||
|
gtk_entry_set_text (GTK_ENTRY (entry), buffer);
|
||||||
|
g_free (buffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
gimp_ratio_entry_parse_text (GimpRatioEntry *entry,
|
||||||
|
const gchar *text)
|
||||||
|
{
|
||||||
|
gint count;
|
||||||
|
gchar op1, op2, dummy;
|
||||||
|
gdouble num = 1.0, denom = 0.0;
|
||||||
|
|
||||||
|
count = sscanf (text, " %lf %c %lf %c %c ", &num, &op1, &denom, &op2, &dummy);
|
||||||
|
|
||||||
|
switch (count)
|
||||||
|
{
|
||||||
|
case EOF:
|
||||||
|
case 0:
|
||||||
|
gimp_ratio_entry_set_fraction (entry, 1.0, 1.0);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 1:
|
||||||
|
gimp_ratio_entry_set_fraction (entry, num, 1.0);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 2:
|
||||||
|
if (op1 == '=')
|
||||||
|
gimp_ratio_entry_set_ratio (entry, num);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 3:
|
||||||
|
if (op1 == ':' || op1 == '/')
|
||||||
|
gimp_ratio_entry_set_fraction (entry, num, denom);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 4:
|
||||||
|
if ((op1 == ':' || op1 == '/') && denom != 0 && op2 == '=')
|
||||||
|
{
|
||||||
|
if (fabs (denom - 1.0) < EPSILON)
|
||||||
|
gimp_ratio_entry_set_ratio (entry, num / denom);
|
||||||
|
else
|
||||||
|
gimp_ratio_entry_set_fraction (entry, num / denom, 1.0);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 5:
|
||||||
|
/* we have additional stuff at the end - malformed input. */
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* sanitize text */
|
||||||
|
gimp_ratio_entry_format_text (entry);
|
||||||
|
|
||||||
|
gtk_editable_set_position (GTK_EDITABLE (entry), -1);
|
||||||
|
}
|
|
@ -0,0 +1,79 @@
|
||||||
|
/* LIBGIMP - The GIMP Library
|
||||||
|
* Copyright (C) 1995-1997 Peter Mattis and Spencer Kimball
|
||||||
|
*
|
||||||
|
* gimpratioentry.h
|
||||||
|
* Copyright (C) 2006 Simon Budig <simon@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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __GIMP_RATIO_ENTRY_H__
|
||||||
|
#define __GIMP_RATIO_ENTRY_H__
|
||||||
|
|
||||||
|
G_BEGIN_DECLS
|
||||||
|
|
||||||
|
|
||||||
|
#define GIMP_TYPE_RATIO_ENTRY (gimp_ratio_entry_get_type ())
|
||||||
|
#define GIMP_RATIO_ENTRY(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GIMP_TYPE_RATIO_ENTRY, GimpRatioEntry))
|
||||||
|
#define GIMP_RATIO_ENTRY_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GIMP_TYPE_RATIO_ENTRY, GimpRatioEntryClass))
|
||||||
|
#define GIMP_IS_RATIO_ENTRY(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GIMP_TYPE_RATIO_ENTRY))
|
||||||
|
#define GIMP_IS_RATIO_ENTRY_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GIMP_TYPE_RATIO_ENTRY))
|
||||||
|
#define GIMP_RATIO_ENTRY_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GIMP_TYPE_RATIO_AREA, GimpRatioEntryClass))
|
||||||
|
|
||||||
|
|
||||||
|
typedef struct _GimpRatioEntryClass GimpRatioEntryClass;
|
||||||
|
|
||||||
|
struct _GimpRatioEntry
|
||||||
|
{
|
||||||
|
GtkEntry parent_instance;
|
||||||
|
|
||||||
|
gdouble numerator;
|
||||||
|
gdouble denominator;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct _GimpRatioEntryClass
|
||||||
|
{
|
||||||
|
GtkEntryClass parent_class;
|
||||||
|
|
||||||
|
void (* ratio_changed) (GimpRatioEntry *entry);
|
||||||
|
|
||||||
|
/* Padding for future expansion */
|
||||||
|
void (* _gimp_reserved1) (void);
|
||||||
|
void (* _gimp_reserved2) (void);
|
||||||
|
void (* _gimp_reserved3) (void);
|
||||||
|
void (* _gimp_reserved4) (void);
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
GType gimp_ratio_entry_get_type (void) G_GNUC_CONST;
|
||||||
|
|
||||||
|
GtkWidget * gimp_ratio_entry_new (void);
|
||||||
|
|
||||||
|
void gimp_ratio_entry_set_fraction (GimpRatioEntry *entry,
|
||||||
|
gdouble numerator,
|
||||||
|
gdouble denominator);
|
||||||
|
void gimp_ratio_entry_get_fraction (GimpRatioEntry *entry,
|
||||||
|
gdouble *numerator,
|
||||||
|
gdouble *denominator);
|
||||||
|
|
||||||
|
void gimp_ratio_entry_set_ratio (GimpRatioEntry *entry,
|
||||||
|
gdouble ratio);
|
||||||
|
gdouble gimp_ratio_entry_get_ratio (GimpRatioEntry *entry);
|
||||||
|
|
||||||
|
|
||||||
|
G_END_DECLS
|
||||||
|
|
||||||
|
#endif /* __GIMP_RATIO_ENTRY_H__ */
|
|
@ -63,6 +63,7 @@
|
||||||
#include <libgimpwidgets/gimppreviewarea.h>
|
#include <libgimpwidgets/gimppreviewarea.h>
|
||||||
#include <libgimpwidgets/gimppropwidgets.h>
|
#include <libgimpwidgets/gimppropwidgets.h>
|
||||||
#include <libgimpwidgets/gimpquerybox.h>
|
#include <libgimpwidgets/gimpquerybox.h>
|
||||||
|
#include <libgimpwidgets/gimpratioentry.h>
|
||||||
#include <libgimpwidgets/gimpresolutionentry.h>
|
#include <libgimpwidgets/gimpresolutionentry.h>
|
||||||
#include <libgimpwidgets/gimpscrolledpreview.h>
|
#include <libgimpwidgets/gimpscrolledpreview.h>
|
||||||
#include <libgimpwidgets/gimpsizeentry.h>
|
#include <libgimpwidgets/gimpsizeentry.h>
|
||||||
|
|
|
@ -64,6 +64,7 @@ typedef struct _GimpPickButton GimpPickButton;
|
||||||
typedef struct _GimpPreview GimpPreview;
|
typedef struct _GimpPreview GimpPreview;
|
||||||
typedef struct _GimpPreviewArea GimpPreviewArea;
|
typedef struct _GimpPreviewArea GimpPreviewArea;
|
||||||
typedef struct _GimpPixmap GimpPixmap;
|
typedef struct _GimpPixmap GimpPixmap;
|
||||||
|
typedef struct _GimpRatioEntry GimpRatioEntry;
|
||||||
typedef struct _GimpResolutionEntry GimpResolutionEntry;
|
typedef struct _GimpResolutionEntry GimpResolutionEntry;
|
||||||
typedef struct _GimpScrolledPreview GimpScrolledPreview;
|
typedef struct _GimpScrolledPreview GimpScrolledPreview;
|
||||||
typedef struct _GimpSizeEntry GimpSizeEntry;
|
typedef struct _GimpSizeEntry GimpSizeEntry;
|
||||||
|
|
Loading…
Reference in New Issue