[gimp/soc-2011-gimpunitentry] Initial commit of GimpUnitEntry widget
- From: Enrico Schröder <eschroeder src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gimp/soc-2011-gimpunitentry] Initial commit of GimpUnitEntry widget
- Date: Tue, 31 May 2011 16:52:11 +0000 (UTC)
commit 0a159e3d876907692a8305f5ac589455d253c50c
Author: Enrico SchroÌ?der <enni schroeder gmail com>
Date: Tue May 31 16:03:10 2011 +0200
Initial commit of GimpUnitEntry widget
contains GimpUnitAdjustment, GimpUnitEntry and a little testapp 'test-unitentry'
.gitignore | 2 +
libgimpwidgets/Makefile.am | 21 ++-
libgimpwidgets/gimpunitadjustment.c | 200 ++++++++++++++++++++
libgimpwidgets/gimpunitadjustment.h | 85 +++++++++
libgimpwidgets/gimpunitentry.c | 349 +++++++++++++++++++++++++++++++++++
libgimpwidgets/gimpunitentry.h | 71 +++++++
libgimpwidgets/test-unitentry.c | 103 ++++++++++
7 files changed, 830 insertions(+), 1 deletions(-)
---
diff --git a/.gitignore b/.gitignore
index c5269c3..28af0de 100644
--- a/.gitignore
+++ b/.gitignore
@@ -46,3 +46,5 @@
/stamp-h
/stamp-h.in
/stamp-h1
+
+/libgimpwidgets/test-unitentry
\ No newline at end of file
diff --git a/libgimpwidgets/Makefile.am b/libgimpwidgets/Makefile.am
index a1aac9e..0cdc590 100644
--- a/libgimpwidgets/Makefile.am
+++ b/libgimpwidgets/Makefile.am
@@ -163,6 +163,10 @@ libgimpwidgets_2_0_la_sources = \
gimpstringcombobox.h \
gimpunitcombobox.c \
gimpunitcombobox.h \
+ gimpunitadjustment.c \
+ gimpunitadjustment.h \
+ gimpunitentry.c \
+ gimpunitentry.h \
gimpunitmenu.c \
gimpunitmenu.h \
gimpunitstore.c \
@@ -241,6 +245,7 @@ libgimpwidgetsinclude_HEADERS = \
gimpstock.h \
gimpstringcombobox.h \
gimpunitcombobox.h \
+ gimpunitentry.h \
gimpunitmenu.h \
gimpunitstore.h \
gimpwidgets-error.h \
@@ -332,7 +337,8 @@ gimp-wilber-pixbufs.h: $(WILBER_IMAGES) Makefile.am
EXTRA_PROGRAMS = \
test-preview-area \
- test-eevl
+ test-eevl \
+ test-unitentry
test_preview_area_SOURCES = test-preview-area.c
@@ -356,6 +362,19 @@ test_eevl_LDADD = \
$(GLIB_LIBS) \
$(test_eevl_DEPENDENCIES)
+test_unitentry_SOURCES = \
+ test-unitentry.c \
+ $(top_builddir)/devel-docs/tools/units.c
+
+test_unitentry_DEPENDENCIES = \
+ $(top_builddir)/libgimpbase/libgimpbase-$(GIMP_API_VERSION).la \
+ $(top_builddir)/libgimp/libgimp-$(GIMP_API_VERSION).la \
+ $(top_builddir)/libgimpwidgets/libgimpwidgets-$(GIMP_API_VERSION).la
+
+test_unitentry_LDADD = \
+ $(GLIB_LIBS) \
+ $(test_unitentry_DEPENDENCIES)
+
#
# test programs, not to be built by default and never installed
diff --git a/libgimpwidgets/gimpunitadjustment.c b/libgimpwidgets/gimpunitadjustment.c
new file mode 100644
index 0000000..9457f6a
--- /dev/null
+++ b/libgimpwidgets/gimpunitadjustment.c
@@ -0,0 +1,200 @@
+/* LIBGIMP - The GIMP Library
+ * Copyright (C) 1995-1997 Peter Mattis and Spencer Kimball
+ *
+ * gimpunitadjustment.c
+ * Copyright (C) 2011 Enrico Schröder <enni schroeder gmail com>
+ *
+ * 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 3 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
+ * Lesser 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, see
+ * <http://www.gnu.org/licenses/>.
+ */
+
+#include "config.h"
+
+#include <string.h>
+
+#include <gtk/gtk.h>
+#include <glib-object.h>
+#include <glib/gprintf.h>
+
+#include "libgimpbase/gimpbase.h"
+#include "gimpwidgets.h"
+#include "gimpunitadjustment.h"
+
+/* some default values */
+#define DEFAULT_UNIT GIMP_UNIT_INCH
+#define DEFAULT_RESOLUTION 300.0
+
+G_DEFINE_TYPE (GimpUnitAdjustment, gimp_unit_adjustment, GTK_TYPE_ADJUSTMENT);
+
+/**
+ * prototypes
+ **/
+/* converts from one current unit to another */
+void gimp_unit_adjustment_convert_unit (GimpUnitAdjustment *adj, GimpUnit unit);
+void unit_changed_handler (GimpUnitAdjustment *adj, GimpUnit unit, gpointer userData);
+
+
+static void
+gimp_unit_adjustment_init (GimpUnitAdjustment *unitAdjustment)
+{
+ /* set default values */
+ gtk_adjustment_set_upper (&unitAdjustment->parent_instance, 10000000.0);
+ gtk_adjustment_set_step_increment (&unitAdjustment->parent_instance, 1.0);
+ unitAdjustment->unitChanged = FALSE;
+
+ /* default unit, resolution */
+ unitAdjustment->unit = DEFAULT_UNIT;
+ unitAdjustment->resolution = DEFAULT_RESOLUTION;
+}
+
+static void
+gimp_unit_adjustment_class_init (GimpUnitAdjustmentClass *klass)
+{
+ klass->sig_unit_changed_id = g_signal_new ("unit-changed",
+ GIMP_TYPE_UNIT_ADJUSTMENT,
+ G_SIGNAL_RUN_LAST,
+ 0,
+ NULL,
+ NULL,
+ g_cclosure_marshal_VOID__INT,
+ G_TYPE_NONE,
+ 1,
+ G_TYPE_INT);
+}
+
+GObject *
+gimp_unit_adjustment_new (void)
+{
+ return g_object_new (GIMP_TYPE_UNIT_ADJUSTMENT, NULL);
+}
+
+void
+unit_changed_handler (GimpUnitAdjustment *adj, GimpUnit unit, gpointer userData)
+{
+ GimpUnitAdjustment *adjustment = GIMP_UNIT_ADJUSTMENT (userData);
+
+ adj->unitChanged = TRUE;
+
+ gimp_unit_adjustment_convert_unit (adjustment, unit);
+}
+
+/* connects adjustment to another adjustment */
+void
+gimp_unit_adjustment_connect (GimpUnitAdjustment *adj, GimpUnitAdjustment *target)
+{
+ g_signal_connect (target,
+ "unit-changed",
+ G_CALLBACK (unit_changed_handler),
+ (gpointer*) adj);
+}
+
+/* converts from one current unit to another */
+void
+gimp_unit_adjustment_convert_unit (GimpUnitAdjustment *adj, GimpUnit unit)
+{
+ gdouble newValue = 0;
+ if (adj->unit != unit)
+ {
+ g_debug ("GimpUnitAdjustment: changing unit from %s to %s\n",
+ gimp_unit_get_abbreviation (adj->unit),
+ gimp_unit_get_abbreviation (unit));
+
+ /* convert value to new unit */
+ newValue = gimp_units_to_pixels (gtk_adjustment_get_value (&(adj->parent_instance)),
+ adj->unit,
+ adj->resolution);
+ newValue = gimp_pixels_to_units (newValue,
+ unit,
+ adj->resolution);
+
+ adj->unit = unit;
+
+ gimp_unit_adjustment_set_value (adj, newValue);
+
+ /* emit "unit-changed" */
+ g_signal_emit(adj, GIMP_UNIT_ADJUSTMENT_GET_CLASS(adj)->sig_unit_changed_id, 0, unit);
+ }
+}
+
+/* sets unit of adjustment, does conversion if neccessary */
+void
+gimp_unit_adjustment_set_unit (GimpUnitAdjustment *adj, GimpUnit unit)
+{
+ gimp_unit_adjustment_convert_unit (adj, unit);
+
+ /* emit "unit-changed" */
+ g_signal_emit(adj, GIMP_UNIT_ADJUSTMENT_GET_CLASS(adj)->sig_unit_changed_id, 0, unit);
+}
+
+/* sets/gets the value of an adjustment */
+void
+gimp_unit_adjustment_set_value (GimpUnitAdjustment *adj, gdouble value)
+{
+ g_debug ("set_value: %f", value);
+
+ gtk_adjustment_set_value (GTK_ADJUSTMENT (adj), value);
+
+ //g_debug ("new value: %f\n", gimp_unit_adjustment_get_value (adj));
+}
+gdouble
+gimp_unit_adjustment_get_value (GimpUnitAdjustment *adj)
+{
+ gdouble value;
+
+ value = gtk_adjustment_get_value (GTK_ADJUSTMENT (adj));
+
+ return value;
+}
+gdouble
+gimp_unit_adjustment_get_value_in_unit (GimpUnitAdjustment *adj, GimpUnit unit)
+{
+ gdouble value = gimp_unit_adjustment_get_value (adj);
+
+ value = gimp_units_to_pixels (value, adj->unit, adj->resolution);
+ value = gimp_pixels_to_units (value, unit, adj->resolution);
+
+ return value;
+}
+void
+gimp_unit_adjustment_set_resolution (GimpUnitAdjustment *adj, gdouble res)
+{
+ adj->resolution = res;
+}
+gdouble
+gimp_unit_adjustment_get_resolution (GimpUnitAdjustment *adj)
+{
+ return adj->resolution;
+}
+
+/* get string in format "value unit" */
+gchar*
+gimp_unit_adjustment_to_string (GimpUnitAdjustment *adj)
+{
+ return gimp_unit_adjustment_to_string_in_unit (adj, adj->unit);
+}
+gchar*
+gimp_unit_adjustment_to_string_in_unit (GimpUnitAdjustment *adj, GimpUnit unit)
+{
+ gdouble value;
+ gchar *text = g_malloc (sizeof (gchar) * 12);
+
+ value = gimp_unit_adjustment_get_value_in_unit (adj, unit);
+
+ g_sprintf (text, "%.2f %s",
+ value,
+ gimp_unit_get_abbreviation (unit));
+
+ return text;
+}
+
diff --git a/libgimpwidgets/gimpunitadjustment.h b/libgimpwidgets/gimpunitadjustment.h
new file mode 100644
index 0000000..399be5f
--- /dev/null
+++ b/libgimpwidgets/gimpunitadjustment.h
@@ -0,0 +1,85 @@
+/* LIBGIMP - The GIMP Library
+ * Copyright (C) 1995-1997 Peter Mattis and Spencer Kimball
+ *
+ * gimpunitadjustment.h
+ * Copyright (C) 2011 Enrico Schröder <enni schroeder gmail com>
+ *
+ * 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 3 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
+ * Lesser 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, see
+ * <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef __GIMP_UNIT_ADJUSTMENT_H__
+#define __GIMP_UNIT_ADJUSTMENT_H__
+
+#include "libgimpbase/gimpbase.h"
+
+G_BEGIN_DECLS
+
+/**
+ * boiler-plate
+ **/
+#define GIMP_TYPE_UNIT_ADJUSTMENT (gimp_unit_adjustment_get_type ())
+#define GIMP_UNIT_ADJUSTMENT(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GIMP_TYPE_UNIT_ADJUSTMENT, GimpUnitAdjustment))
+#define GIMP_UNIT_ADJUSTMENT_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GIMP_TYPE_UNIT_ADJUSTMENT, GimpUnitAdjustmentClass))
+#define GIMP_IS_UNIT_ADJUSTMENT(obj) (G_TYPE_CHECK_INSTANCE_TYPE (obj, GIMP_TYPE_UNIT_ADJUSTMENT))
+#define GIMP_IS_UNIT_ADJUSTMENT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GIMP_TYPE_UNIT_ADJUSTMENT))
+#define GIMP_UNIT_ADJUSTMENT_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GIMP_TYPE_UNIT_ADJUSTMENT, GimpUnitAdjustmentClass))
+
+typedef struct _GimpUnitAdjustment GimpUnitAdjustment;
+typedef struct _GimpUnitAdjustmentClass GimpUnitAdjustmentClass;
+
+struct _GimpUnitAdjustment
+{
+ GtkAdjustment parent_instance;
+
+ /* flag set when unit has been changed externally */
+ gboolean unitChanged;
+
+ /* private */
+ /* TODO move private fields into own struct? */
+ GimpUnit unit; /* the unit our value is in */
+ gdouble resolution; /* resolution in dpi */
+};
+
+struct _GimpUnitAdjustmentClass
+{
+ GtkAdjustmentClass parent_class;
+
+ /* signals */
+ guint sig_unit_changed_id;
+};
+
+/**
+ * prototypes
+ **/
+GType gimp_unit_adjustment_get_type (void);
+GObject *gimp_unit_adjustment_new (void);
+
+/* sets unit of adjustment, does conversion if neccessary */
+void gimp_unit_adjustment_set_unit (GimpUnitAdjustment *adj, GimpUnit unit);
+/* sets/gets the value of an adjustment */
+void gimp_unit_adjustment_set_value (GimpUnitAdjustment *adj, gdouble value);
+gdouble gimp_unit_adjustment_get_value (GimpUnitAdjustment *adj);
+gdouble gimp_unit_adjustment_get_value_in_unit (GimpUnitAdjustment *adj, GimpUnit unit);
+void gimp_unit_adjustment_set_resolution (GimpUnitAdjustment *adj, gdouble res);
+gdouble gimp_unit_adjustment_get_resolution (GimpUnitAdjustment *adj);
+/* get string in format "value unit" */
+gchar* gimp_unit_adjustment_to_string (GimpUnitAdjustment *adj);
+gchar* gimp_unit_adjustment_to_string_in_unit (GimpUnitAdjustment *adj, GimpUnit unit);
+/* connects adjustment to another adjustment */
+void gimp_unit_adjustment_connect (GimpUnitAdjustment *adj, GimpUnitAdjustment *target);
+
+G_END_DECLS
+
+#endif /*__GIMP_UNIT_ADJUSTMENT_H__*/
\ No newline at end of file
diff --git a/libgimpwidgets/gimpunitentry.c b/libgimpwidgets/gimpunitentry.c
new file mode 100644
index 0000000..185b33d
--- /dev/null
+++ b/libgimpwidgets/gimpunitentry.c
@@ -0,0 +1,349 @@
+/* LIBGIMP - The GIMP Library
+ * Copyright (C) 1995-1997 Peter Mattis and Spencer Kimball
+ *
+ * gimpunitentry.c
+ * Copyright (C) 2011 Enrico Schröder <enni schroeder gmail com>
+ *
+ * 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 3 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
+ * Lesser 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, see
+ * <http://www.gnu.org/licenses/>.
+ */
+
+#include "config.h"
+
+#include <string.h>
+
+#include <gtk/gtk.h>
+#include <gtk/gtkadjustment.h>
+#include <gtk/gtkspinbutton.h>
+
+#include <glib/gprintf.h>
+
+#include "libgimpbase/gimpbase.h"
+
+#include "gimpwidgets.h"
+
+#include "gimpeevl.h"
+#include "gimpunitentry.h"
+#include "gimpunitadjustment.h"
+
+G_DEFINE_TYPE (GimpUnitEntry, gimp_unit_entry, GTK_TYPE_SPIN_BUTTON);
+
+/* unit resolver for GimpEevl */
+static gboolean unit_resolver (const gchar *ident,
+ GimpEevlQuantity *result,
+ gpointer data);
+
+/* read and parse entered text */
+static gboolean gimp_unit_entry_parse (GimpUnitEntry *unitEntry);
+
+/**
+ * event handlers
+ **/
+static gint gimp_unit_entry_focus_out (GtkWidget *widget,
+ GdkEventFocus *event);
+
+/**
+ * signal handlers
+ **/
+
+/* format displayed text (signal emmitted by GtkSpinButton before text is displayed) */
+static gboolean on_output (GtkSpinButton *spin,
+ gpointer data);
+/* parse and process entered text (signal emmited from GtkEntry) */
+static void on_text_changed (GtkEditable *editable,
+ gpointer user_data);
+static void on_insert_text (GtkEditable *editable,
+ gchar *new_text,
+ gint new_text_length,
+ gint *position,
+ gpointer user_data);
+static gint on_input (GtkSpinButton *spinbutton,
+ gpointer arg1,
+ gpointer user_data);
+
+static void
+gimp_unit_entry_init (GimpUnitEntry *unitEntry)
+{
+ GimpUnitEntryClass *class = GIMP_UNIT_ENTRY_GET_CLASS (unitEntry);
+
+ /* create and set our adjustment subclass */
+ GObject *adjustment = gimp_unit_adjustment_new ();
+
+ unitEntry->unitAdjustment = GIMP_UNIT_ADJUSTMENT (adjustment);
+ gtk_spin_button_set_adjustment (GTK_SPIN_BUTTON (unitEntry),
+ GTK_ADJUSTMENT (adjustment));
+
+ /* some default values */
+ gtk_spin_button_set_update_policy (&unitEntry->parent_instance, GTK_UPDATE_ALWAYS);
+
+ /* connect signals */
+ g_signal_connect (&unitEntry->parent_instance,
+ "output",
+ G_CALLBACK(on_output),
+ (gpointer) adjustment);
+ g_signal_connect (&unitEntry->parent_instance.entry,
+ "insert-text",
+ G_CALLBACK(on_insert_text),
+ (gpointer) unitEntry);
+ g_signal_connect (&unitEntry->parent_instance,
+ "input",
+ G_CALLBACK(on_input),
+ (gpointer) unitEntry);
+ g_signal_connect (&unitEntry->parent_instance.entry,
+ "changed",
+ G_CALLBACK(on_text_changed),
+ (gpointer) unitEntry);
+
+ unitEntry->id = class->id;
+ class->id++;
+}
+
+static void
+gimp_unit_entry_class_init (GimpUnitEntryClass *class)
+{
+ //GtkWidgetClass *widgetClass = GTK_WIDGET_CLASS (class);
+
+ /* some events we need to catch instead of our parent */
+ //widgetClass->focus_out_event = gimp_unit_entry_focus_out;
+
+ class->id = 0;
+}
+
+GtkWidget*
+gimp_unit_entry_new (void)
+{
+ return g_object_new (GIMP_TYPE_UNIT_ENTRY, NULL);
+}
+
+GimpUnitAdjustment*
+gimp_unit_entry_get_adjustment (GimpUnitEntry *entry)
+{
+ return entry->unitAdjustment;
+}
+
+/* connect to another entry */
+void
+gimp_unit_entry_connect (GimpUnitEntry *entry, GimpUnitEntry *target)
+{
+ gimp_unit_adjustment_connect (entry->unitAdjustment, target->unitAdjustment);
+}
+
+/* read and parse entered text */
+static gboolean
+gimp_unit_entry_parse (GimpUnitEntry *entry)
+{
+ gdouble newValue;
+ /* GimpEevl related stuff */
+ GimpEevlQuantity result;
+ GError *error = NULL;
+ const gchar *errorpos = 0;
+ /* text to parse */
+ const gchar *str = gtk_entry_get_text (GTK_ENTRY (entry));
+
+ if (strlen (str) <= 0)
+ return FALSE;
+
+ /**
+ * purpose of enteredUnit: use first unit unit_resolver will be called with
+ * as entered unit. enteredUnit is reset now to know which unit was the first one
+ **/
+ entry->enteredUnit = -1;
+
+ g_debug ("%i parsing: %s", entry->id, str);
+
+ /* parse text via GimpEevl */
+ gimp_eevl_evaluate (str,
+ unit_resolver,
+ &result,
+ (gpointer) entry,
+ &errorpos,
+ &error);
+
+ if (error || errorpos)
+ {
+ GdkColor color;
+ gdk_color_parse ("LightSalmon", &color);
+ gtk_widget_modify_base (GTK_WIDGET (entry), GTK_STATE_NORMAL, &color);
+
+ g_debug ("gimpeevl parsing error \n");
+ return FALSE;
+ }
+ else
+ {
+ gtk_widget_modify_base (GTK_WIDGET (entry), GTK_STATE_NORMAL, NULL);
+ g_debug ("%i gimpeevl parser result: %s = %lg (%d)", entry->id, str, result.value, result.dimension);
+ g_debug ("%i determined unit: %s\n", entry->id, gimp_unit_get_abbreviation (entry->enteredUnit));
+
+ /* set new unit */
+ if (entry->enteredUnit != entry->unitAdjustment->unit)
+ {
+ gimp_unit_adjustment_set_unit (entry->unitAdjustment, entry->enteredUnit);
+ }
+
+ /* set new value */
+ if (gimp_unit_adjustment_get_value (entry->unitAdjustment) != result.value)
+ {
+ /* result from parser is in inch, so convert to desired unit */
+ newValue = gimp_units_to_pixels (result.value,
+ GIMP_UNIT_INCH,
+ entry->unitAdjustment->resolution);
+ newValue = gimp_pixels_to_units (newValue,
+ entry->unitAdjustment->unit,
+ entry->unitAdjustment->resolution);
+
+ gimp_unit_adjustment_set_value (entry->unitAdjustment, newValue);
+
+ g_object_notify (G_OBJECT ( GTK_SPIN_BUTTON (entry)), "value");
+ }
+ }
+
+ return TRUE;
+}
+
+/**
+ * signal handlers
+ **/
+
+/* format displayed text, displays "[value] [unit]" (gets called by GtkSpinButton) */
+static gboolean
+on_output (GtkSpinButton *spin, gpointer data)
+{
+ gchar *text;
+ GimpUnitAdjustment *adj = GIMP_UNIT_ADJUSTMENT (data);
+
+ /* return if widget still has focus => user input must not be overwritten */
+ if (gtk_widget_has_focus (GTK_WIDGET (spin)))
+ return TRUE;
+
+ /* parse once more to prevent value from being overwritten somewhere in GtkSpinButton or
+ GtkEntry. If we don't do that, the entered text is truncated at the first space.
+ TODO: find out where and why
+ not very elegant, because we have do deactivate parsing in case the value was not
+ modified by user input but by changes that happened in a connected entry
+ */
+ if(adj->unitChanged)
+ adj->unitChanged = FALSE;
+ else
+ gimp_unit_entry_parse (GIMP_UNIT_ENTRY (spin));
+
+ text = gimp_unit_adjustment_to_string (adj);
+
+ g_debug ("on_output: %s\n", text);
+
+ gtk_entry_set_text (GTK_ENTRY (spin), text);
+
+ g_free (text);
+
+ return TRUE;
+}
+
+static
+void on_insert_text (GtkEditable *editable,
+ gchar *new_text,
+ gint new_text_length,
+ gint *position,
+ gpointer user_data)
+{
+ g_debug ("on_insert_text\n");
+}
+
+/* parse and process entered text (signal emmited from GtkEntry) */
+static
+void on_text_changed (GtkEditable *editable, gpointer user_data)
+{
+ g_debug ("on_text_changed\n");
+
+ gimp_unit_entry_parse (GIMP_UNIT_ENTRY (user_data));
+}
+
+/* unit resolver for GimpEevl */
+static gboolean
+unit_resolver (const gchar *ident,
+ GimpEevlQuantity *result,
+ gpointer user_data)
+{
+ GimpUnitEntry *entry = GIMP_UNIT_ENTRY (user_data);
+ GimpUnit *unit = &(entry->enteredUnit);
+ gboolean resolved = FALSE;
+ gboolean default_unit = (ident == NULL);
+ gint numUnits = gimp_unit_get_number_of_units ();
+ const gchar *abbr;
+ gint i = 0;
+
+ result->dimension = 1;
+
+ /* if no unit is specified, use default unit */
+ if (default_unit)
+ {
+ /* if default hasn't been set before, set to inch*/
+ if (*unit == -1)
+ *unit = GIMP_UNIT_INCH;
+
+ result->dimension = 1;
+
+ if (*unit == GIMP_UNIT_PIXEL) /* handle case that unit is px */
+ result->value = gimp_unit_entry_get_adjustment (entry)->resolution;
+ else /* otherwise use factor */
+ result->value = gimp_unit_get_factor (*unit);
+
+ resolved = TRUE;
+ return resolved;
+ }
+
+ /* find matching unit */
+ for (i = 0; i < numUnits; i++)
+ {
+ abbr = gimp_unit_get_abbreviation (i);
+
+ if (strcmp (abbr, ident) == 0)
+ {
+ /* handle case that unit is px */
+ if (i == GIMP_UNIT_PIXEL)
+ result->value = gimp_unit_entry_get_adjustment (entry)->resolution;
+ else
+ result->value = gimp_unit_get_factor (i);
+
+ if (*unit == -1)
+ *unit = i;
+
+ i = numUnits;
+ resolved = TRUE;
+ }
+ }
+
+ return resolved;
+}
+
+static
+gint on_input (GtkSpinButton *spinButton,
+ gpointer arg1,
+ gpointer user_data)
+{
+ g_debug ("on_input\n");
+
+ //gimp_unit_entry_parse (GIMP_UNIT_ENTRY (spinButton));
+
+ return 0;
+}
+
+static gint
+gimp_unit_entry_focus_out (GtkWidget *widget,
+ GdkEventFocus *event)
+{
+ GtkEntryClass *class = GTK_ENTRY_CLASS (gimp_unit_entry_parent_class);
+
+ g_debug ("focus_out\n");
+
+ return GTK_WIDGET_CLASS (class)->focus_out_event (widget, event);
+}
diff --git a/libgimpwidgets/gimpunitentry.h b/libgimpwidgets/gimpunitentry.h
new file mode 100644
index 0000000..54ed4ff
--- /dev/null
+++ b/libgimpwidgets/gimpunitentry.h
@@ -0,0 +1,71 @@
+/* LIBGIMP - The GIMP Library
+ * Copyright (C) 1995-1997 Peter Mattis and Spencer Kimball
+ *
+ * gimpunitentry.h
+ * Copyright (C) 2011 Enrico Schröder <enni schroeder gmail com>
+ *
+ * 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 3 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
+ * Lesser 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, see
+ * <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef __GIMP_UNIT_ENTRY_H__
+#define __GIMP_UNIT_ENTRY_H__
+
+#include "gimpunitadjustment.h"
+
+G_BEGIN_DECLS
+
+/**
+ * boiler-plate
+ **/
+#define GIMP_TYPE_UNIT_ENTRY (gimp_unit_entry_get_type ())
+#define GIMP_UNIT_ENTRY(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GIMP_TYPE_UNIT_ENTRY, GimpUnitEntry))
+#define GIMP_UNIT_ENTRY_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GIMP_TYPE_UNIT_ENTRY, GimpUnitEntryClass))
+#define GIMP_IS_UNIT_ENTRY(obj) (G_TYPE_CHECK_INSTANCE_TYPE (obj, GIMP_TYPE_UNIT_ENTRY))
+#define GIMP_IS_UNIT_ENTRY_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GIMP_TYPE_UNIT_ENTRY))
+#define GIMP_UNIT_ENTRY_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GIMP_TYPE_UNIT_ENTRY, GimpUnitEntryClass))
+
+typedef struct _GimpUnitEntry GimpUnitEntry;
+typedef struct _GimpUnitEntryClass GimpUnitEntryClass;
+
+struct _GimpUnitEntry
+{
+ GtkSpinButton parent_instance;
+
+ /* private */
+ GimpUnitAdjustment *unitAdjustment; /* for convinience */
+ GimpUnit enteredUnit; /* used to determine which unit was entered */
+
+ gint id; /* for debugging */
+};
+
+struct _GimpUnitEntryClass
+{
+ GtkSpinButtonClass parent_class;
+
+ gint id; /* for debugging */
+};
+
+/**
+ * prototypes
+ **/
+GType gimp_unit_entry_get_type (void);
+GtkWidget *gimp_unit_entry_new (void);
+GimpUnitAdjustment *gimp_unit_entry_get_adjustment (GimpUnitEntry *entry);
+/* connect to another entry */
+void gimp_unit_entry_connect (GimpUnitEntry *entry, GimpUnitEntry *target);
+
+G_END_DECLS
+
+#endif /*__GIMP_UNIT_ENTRY_H__*/
\ No newline at end of file
diff --git a/libgimpwidgets/test-unitentry.c b/libgimpwidgets/test-unitentry.c
new file mode 100644
index 0000000..2f62317
--- /dev/null
+++ b/libgimpwidgets/test-unitentry.c
@@ -0,0 +1,103 @@
+/* small test app for the new unit entry widget developed during Google Summer of Code 2011 */
+
+#include "config.h"
+
+#include <string.h>
+#include <glib-object.h>
+#include <glib/gprintf.h>
+#include <gtk/gtk.h>
+
+#include "devel-docs/tools/units.h"
+
+#include "gimpunitentry.h"
+
+/* global objects */
+GtkWidget *window;
+GtkWidget *vbox;
+GtkWidget *valign;
+GtkWidget *inLabel;
+GtkWidget *pxLabel;
+
+GtkWidget *entry1;
+GtkWidget *entry2;
+
+void on_value_changed (GtkAdjustment *adj, gpointer userData)
+{
+ gchar text[40];
+ gchar *val1 = gimp_unit_adjustment_to_string_in_unit (GIMP_UNIT_ENTRY (entry1)->unitAdjustment, GIMP_UNIT_INCH);
+ gchar *val2 = gimp_unit_adjustment_to_string_in_unit (GIMP_UNIT_ENTRY (entry2)->unitAdjustment, GIMP_UNIT_INCH);
+ g_sprintf (text, "%s x %s", val1, val2);
+ gtk_label_set_text (GTK_LABEL(inLabel), text);
+
+ val1 = gimp_unit_adjustment_to_string_in_unit (GIMP_UNIT_ENTRY (entry1)->unitAdjustment, GIMP_UNIT_PIXEL);
+ val2 = gimp_unit_adjustment_to_string_in_unit (GIMP_UNIT_ENTRY (entry2)->unitAdjustment, GIMP_UNIT_PIXEL);
+ g_sprintf (text, "%s x %s", val1, val2);
+ gtk_label_set_text (GTK_LABEL(pxLabel), text);
+
+ g_free (val1);
+ g_free (val2);
+}
+
+/* set up interface */
+void
+create_interface(void)
+{
+ /* main window */
+ window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
+ gtk_container_set_border_width (GTK_CONTAINER (window), 10);
+ gtk_window_set_position (GTK_WINDOW(window), GTK_WIN_POS_CENTER);
+ gtk_window_set_default_size (GTK_WINDOW(window), 200, 100);
+
+ /* vbox (used for the entries) */
+ vbox = gtk_vbox_new (TRUE, 1);
+
+ /* valign */
+ valign = gtk_alignment_new (0, 0, 1, 0);
+ gtk_container_add (GTK_CONTAINER (valign), vbox);
+ gtk_container_add (GTK_CONTAINER (window), valign);
+
+ /* the entries */
+ entry1 = gimp_unit_entry_new ();
+ entry2 = gimp_unit_entry_new ();
+
+ gtk_box_pack_start (GTK_BOX (vbox), entry1, TRUE, TRUE, 0);
+ gtk_box_pack_start (GTK_BOX (vbox), entry2, TRUE, TRUE, 0);
+
+ gimp_unit_entry_connect (GIMP_UNIT_ENTRY (entry1), GIMP_UNIT_ENTRY (entry2));
+ gimp_unit_entry_connect (GIMP_UNIT_ENTRY (entry2), GIMP_UNIT_ENTRY (entry1));
+
+ gimp_unit_adjustment_set_value (gimp_unit_entry_get_adjustment (GIMP_UNIT_ENTRY (entry1)), 20);
+ gimp_unit_adjustment_set_value (gimp_unit_entry_get_adjustment (GIMP_UNIT_ENTRY (entry2)), 20);
+
+ /* status label */
+ inLabel = gtk_label_new ("inches");
+ pxLabel = gtk_label_new ("pixels");
+ gtk_box_pack_end (GTK_BOX (vbox), pxLabel, TRUE, TRUE, 0);
+ gtk_box_pack_end (GTK_BOX (vbox), inLabel, TRUE, TRUE, 0);
+
+ on_value_changed (NULL, NULL);
+
+ /* signals */
+ g_signal_connect_swapped (G_OBJECT(window), "destroy",
+ G_CALLBACK(gtk_main_quit), NULL);
+ g_signal_connect (G_OBJECT (GIMP_UNIT_ENTRY (entry1)->unitAdjustment), "value-changed",
+ G_CALLBACK (on_value_changed), NULL);
+ g_signal_connect (G_OBJECT (GIMP_UNIT_ENTRY (entry2)->unitAdjustment), "value-changed",
+ G_CALLBACK (on_value_changed), NULL);
+
+ gtk_widget_show_all (window);
+}
+
+int main (int argc,
+ char *argv[])
+{
+ units_init();
+
+ gtk_init (&argc, &argv);
+
+ create_interface ();
+
+ gtk_main ();
+
+ return 0;
+}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]