/* The GIMP -- an image manipulation program * Copyright (C) 1995 Spencer Kimball and Peter Mattis * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program 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 General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include "config.h" #include #include "libgimpbase/gimpbase.h" #include "libgimpcolor/gimpcolor.h" #include "libgimpwidgets/gimpwidgets.h" #include "tools-types.h" #include "config/gimpconfig.h" #include "config/gimpconfig-params.h" #include "config/gimpconfig-utils.h" #include "core/gimp.h" #include "core/gimpcontext.h" #include "core/gimpcontainer.h" #include "core/gimptoolinfo.h" #include "text/gimptext.h" #include "widgets/gimpcolorpanel.h" #include "widgets/gimpdialogfactory.h" #include "widgets/gimppropwidgets.h" #include "widgets/gimptexteditor.h" #include "widgets/gimpviewablebutton.h" #include "widgets/gimpwidgets-utils.h" #include "gimptextoptions.h" #include "gimptooloptions-gui.h" #include "gimp-intl.h" enum { PROP_0, PROP_FONT_SIZE, PROP_UNIT, PROP_HINTING, PROP_AUTOHINT, PROP_ANTIALIAS, PROP_LANGUAGE, PROP_BASE_DIR, PROP_JUSTIFICATION, PROP_INDENTATION, PROP_LINE_SPACING }; static void gimp_text_options_class_init (GimpTextOptionsClass *options_class); static void gimp_text_options_init (GimpTextOptions *options); static void gimp_text_options_set_property (GObject *object, guint property_id, const GValue *value, GParamSpec *pspec); static void gimp_text_options_get_property (GObject *object, guint property_id, GValue *value, GParamSpec *pspec); static void gimp_text_options_notify_font (GimpContext *context, GParamSpec *pspec, GimpText *text); static void gimp_text_options_notify_text_font (GimpText *text, GParamSpec *pspec, GimpContext *context); static void gimp_text_options_notify_color (GimpContext *context, GParamSpec *pspec, GimpText *text); static void gimp_text_options_notify_text_color (GimpText *text, GParamSpec *pspec, GimpContext *context); static GimpToolOptionsClass *parent_class = NULL; GType gimp_text_options_get_type (void) { static GType type = 0; if (! type) { static const GTypeInfo info = { sizeof (GimpTextOptionsClass), (GBaseInitFunc) NULL, (GBaseFinalizeFunc) NULL, (GClassInitFunc) gimp_text_options_class_init, NULL, /* class_finalize */ NULL, /* class_data */ sizeof (GimpTextOptions), 0, /* n_preallocs */ (GInstanceInitFunc) gimp_text_options_init }; type = g_type_register_static (GIMP_TYPE_TOOL_OPTIONS, "GimpTextOptions", &info, 0); } return type; } static void gimp_text_options_class_init (GimpTextOptionsClass *klass) { GObjectClass *object_class = G_OBJECT_CLASS (klass); parent_class = g_type_class_peek_parent (klass); object_class->set_property = gimp_text_options_set_property; object_class->get_property = gimp_text_options_get_property; GIMP_CONFIG_INSTALL_PROP_UNIT (object_class, PROP_UNIT, "font-size-unit", NULL, TRUE, FALSE, GIMP_UNIT_PIXEL, 0); GIMP_CONFIG_INSTALL_PROP_DOUBLE (object_class, PROP_FONT_SIZE, "font-size", NULL, 0.0, 8192.0, 18.0, 0); GIMP_CONFIG_INSTALL_PROP_BOOLEAN (object_class, PROP_HINTING, "hinting", N_("Hinting alters the font outline to " "produce a crisp bitmap at small " "sizes"), TRUE, 0); GIMP_CONFIG_INSTALL_PROP_BOOLEAN (object_class, PROP_AUTOHINT, "autohint", N_("If available, hints from the font are " "used but you may prefer to always use " "the automatic hinter"), FALSE, 0); GIMP_CONFIG_INSTALL_PROP_BOOLEAN (object_class, PROP_ANTIALIAS, "antialias", NULL, TRUE, 0); GIMP_CONFIG_INSTALL_PROP_STRING (object_class, PROP_LANGUAGE, "language", NULL, (const gchar *) gtk_get_default_language (), 0); GIMP_CONFIG_INSTALL_PROP_ENUM (object_class, PROP_BASE_DIR, "base-direction", NULL, GIMP_TYPE_TEXT_DIRECTION, GIMP_TEXT_DIRECTION_LTR, 0); GIMP_CONFIG_INSTALL_PROP_ENUM (object_class, PROP_JUSTIFICATION, "justify", NULL, GIMP_TYPE_TEXT_JUSTIFICATION, GIMP_TEXT_JUSTIFY_LEFT, 0); GIMP_CONFIG_INSTALL_PROP_DOUBLE (object_class, PROP_INDENTATION, "indent", N_("Indentation of the first line"), -8192.0, 8192.0, 0.0, GIMP_PARAM_DEFAULTS); GIMP_CONFIG_INSTALL_PROP_DOUBLE (object_class, PROP_LINE_SPACING, "line-spacing", N_("Modify line spacing"), -8192.0, 8192.0, 0.0, GIMP_PARAM_DEFAULTS); } static void gimp_text_options_init (GimpTextOptions *options) { options->size_entry = NULL; } static void gimp_text_options_get_property (GObject *object, guint property_id, GValue *value, GParamSpec *pspec) { GimpTextOptions *options = GIMP_TEXT_OPTIONS (object); switch (property_id) { case PROP_FONT_SIZE: g_value_set_double (value, options->font_size); break; case PROP_UNIT: g_value_set_int (value, options->unit); break; case PROP_HINTING: g_value_set_boolean (value, options->hinting); break; case PROP_AUTOHINT: g_value_set_boolean (value, options->autohint); break; case PROP_ANTIALIAS: g_value_set_boolean (value, options->antialias); break; case PROP_LANGUAGE: g_value_set_string (value, options->language); break; case PROP_BASE_DIR: g_value_set_enum (value, options->base_dir); break; case PROP_JUSTIFICATION: g_value_set_enum (value, options->justify); break; case PROP_INDENTATION: g_value_set_double (value, options->indent); break; case PROP_LINE_SPACING: g_value_set_double (value, options->line_spacing); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); break; } } static void gimp_text_options_set_property (GObject *object, guint property_id, const GValue *value, GParamSpec *pspec) { GimpTextOptions *options = GIMP_TEXT_OPTIONS (object); switch (property_id) { case PROP_FONT_SIZE: options->font_size = g_value_get_double (value); break; case PROP_UNIT: options->unit = g_value_get_int (value); break; case PROP_HINTING: options->hinting = g_value_get_boolean (value); break; case PROP_AUTOHINT: options->autohint = g_value_get_boolean (value); break; case PROP_ANTIALIAS: options->antialias = g_value_get_boolean (value); break; case PROP_BASE_DIR: options->base_dir = g_value_get_enum (value); break; case PROP_LANGUAGE: g_free (options->language); options->language = g_value_dup_string (value); break; case PROP_JUSTIFICATION: options->justify = g_value_get_enum (value); break; case PROP_INDENTATION: options->indent = g_value_get_double (value); break; case PROP_LINE_SPACING: options->line_spacing = g_value_get_double (value); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); break; } } static void gimp_text_options_notify_font (GimpContext *context, GParamSpec *pspec, GimpText *text) { g_signal_handlers_block_by_func (text, gimp_text_options_notify_text_font, context); g_object_set (text, "font", gimp_context_get_font_name (context), NULL); g_signal_handlers_unblock_by_func (text, gimp_text_options_notify_text_font, context); } static void gimp_text_options_notify_text_font (GimpText *text, GParamSpec *pspec, GimpContext *context) { g_signal_handlers_block_by_func (context, gimp_text_options_notify_font, text); gimp_context_set_font_name (context, text->font); g_signal_handlers_unblock_by_func (context, gimp_text_options_notify_font, text); } static void gimp_text_options_notify_color (GimpContext *context, GParamSpec *pspec, GimpText *text) { GimpRGB color; gimp_context_get_foreground (context, &color); g_signal_handlers_block_by_func (text, gimp_text_options_notify_text_color, context); g_object_set (text, "color", &color, NULL); g_signal_handlers_unblock_by_func (text, gimp_text_options_notify_text_color, context); } static void gimp_text_options_notify_text_color (GimpText *text, GParamSpec *pspec, GimpContext *context) { g_signal_handlers_block_by_func (context, gimp_text_options_notify_color, text); gimp_context_set_foreground (context, &text->color); g_signal_handlers_unblock_by_func (context, gimp_text_options_notify_color, text); } /* This function could live in gimptexttool.c also. * But it takes some bloat out of that file... */ void gimp_text_options_connect_text (GimpTextOptions *options, GimpText *text) { GimpContext *context; GimpRGB color; g_return_if_fail (GIMP_IS_TEXT_OPTIONS (options)); g_return_if_fail (GIMP_IS_TEXT (text)); context = GIMP_CONTEXT (options); gimp_context_get_foreground (context, &color); gimp_config_sync (GIMP_CONFIG (options), GIMP_CONFIG (text), 0); g_object_set (text, "color", &color, "font", gimp_context_get_font_name (context), NULL); gimp_config_connect (G_OBJECT (options), G_OBJECT (text), NULL); g_signal_connect_object (options, "notify::font", G_CALLBACK (gimp_text_options_notify_font), text, 0); g_signal_connect_object (text, "notify::font", G_CALLBACK (gimp_text_options_notify_text_font), options, 0); g_signal_connect_object (options, "notify::foreground", G_CALLBACK (gimp_text_options_notify_color), text, 0); g_signal_connect_object (text, "notify::color", G_CALLBACK (gimp_text_options_notify_text_color), options, 0); } GtkWidget * gimp_text_options_gui (GimpToolOptions *tool_options) { GimpTextOptions *options; GObject *config; GtkWidget *vbox; GtkWidget *table; GtkWidget *button; GimpDialogFactory *dialog_factory; GtkWidget *auto_button; GtkWidget *entry; GtkWidget *box; GtkWidget *spinbutton; gint row = 0; options = GIMP_TEXT_OPTIONS (tool_options); config = G_OBJECT (options); vbox = gimp_tool_options_gui (tool_options); dialog_factory = gimp_dialog_factory_from_name ("dock"); table = gtk_table_new (9, 3, FALSE); gtk_table_set_col_spacings (GTK_TABLE (table), 2); gtk_table_set_row_spacings (GTK_TABLE (table), 2); gtk_box_pack_start (GTK_BOX (vbox), table, FALSE, FALSE, 0); gtk_widget_show (table); button = gimp_viewable_button_new (GIMP_CONTEXT (options)->gimp->fonts, GIMP_CONTEXT (options), GIMP_PREVIEW_SIZE_SMALL, 1, dialog_factory, "gimp-font-list|gimp-font-grid", GIMP_STOCK_FONT, _("Open the font selection dialog")); gimp_table_attach_aligned (GTK_TABLE (table), 0, row++, _("_Font:"), 1.0, 0.5, button, 2, TRUE); entry = gimp_prop_size_entry_new (config, "font-size", "font-size-unit", "%a", GIMP_SIZE_ENTRY_UPDATE_SIZE, 72.0); gimp_table_attach_aligned (GTK_TABLE (table), 0, row, _("_Size:"), 1.0, 0.5, entry, 2, FALSE); gtk_widget_show (entry); row++; options->size_entry = GIMP_SIZE_ENTRY (entry); button = gimp_prop_check_button_new (config, "hinting", _("_Hinting")); gtk_table_attach (GTK_TABLE (table), button, 1, 3, row, row + 1, GTK_SHRINK | GTK_FILL, GTK_SHRINK | GTK_FILL, 0, 0); gtk_widget_show (button); row++; auto_button = gimp_prop_check_button_new (config, "autohint", _("Force Auto-Hinter")); gtk_table_attach (GTK_TABLE (table), auto_button, 1, 3, row, row + 1, GTK_SHRINK | GTK_FILL, GTK_SHRINK | GTK_FILL, 0, 0); gtk_widget_show (auto_button); row++; gtk_widget_set_sensitive (auto_button, options->hinting); g_object_set_data (G_OBJECT (button), "set_sensitive", auto_button); button = gimp_prop_check_button_new (config, "antialias", _("Antialiasing")); gtk_table_attach (GTK_TABLE (table), button, 1, 3, row, row + 1, GTK_SHRINK | GTK_FILL, GTK_SHRINK | GTK_FILL, 0, 0); gtk_widget_show (button); row++; button = gimp_prop_color_button_new (config, "foreground", _("Text Color"), -1, 24, GIMP_COLOR_AREA_FLAT); gimp_color_panel_set_context (GIMP_COLOR_PANEL (button), GIMP_CONTEXT (options)); gimp_table_attach_aligned (GTK_TABLE (table), 0, row++, _("Color:"), 1.0, 0.5, button, 1, FALSE); box = gimp_prop_enum_stock_box_new (config, "justify", "gtk-justify", 0, 0); gimp_table_attach_aligned (GTK_TABLE (table), 0, row++, _("Justify:"), 1.0, 0.5, box, 2, TRUE); spinbutton = gimp_prop_spin_button_new (config, "indent", 1.0, 10.0, 1); gtk_entry_set_width_chars (GTK_ENTRY (spinbutton), 5); gimp_table_attach_aligned (GTK_TABLE (table), 0, row++, _("Indent:"), 1.0, 0.5, spinbutton, 1, FALSE); spinbutton = gimp_prop_spin_button_new (config, "line-spacing", 1.0, 10.0, 1); gtk_entry_set_width_chars (GTK_ENTRY (spinbutton), 5); gimp_table_attach_stock (GTK_TABLE (table), row++, _("Line\nSpacing:"), 0.0, spinbutton, 1, GIMP_STOCK_LINE_SPACING); button = gtk_button_new_with_label (_("Create Path from Text")); gtk_box_pack_end (GTK_BOX (vbox), button, FALSE, FALSE, 0); gtk_widget_set_sensitive (button, FALSE); gtk_widget_show (button); g_object_set_data (G_OBJECT (tool_options), "gimp-text-to-vectors", button); return vbox; } static void gimp_text_options_dir_changed (GimpTextEditor *editor, GimpTextOptions *options) { g_object_set (options, "base-direction", editor->base_dir, NULL); } static void gimp_text_options_notify_dir (GimpTextOptions *options, GParamSpec *pspec, GimpTextEditor *editor) { GimpTextDirection dir; g_object_get (options, "base-direction", &dir, NULL); gimp_text_editor_set_direction (editor, dir); } GtkWidget * gimp_text_options_editor_new (GimpTextOptions *options, const gchar *title) { GtkWidget *editor; g_return_val_if_fail (GIMP_IS_TEXT_OPTIONS (options), NULL); g_return_val_if_fail (title != NULL, NULL); editor = gimp_text_editor_new (title); gimp_text_editor_set_direction (GIMP_TEXT_EDITOR (editor), options->base_dir); g_signal_connect_object (editor, "dir_changed", G_CALLBACK (gimp_text_options_dir_changed), options, 0); g_signal_connect_object (options, "notify::base-direction", G_CALLBACK (gimp_text_options_notify_dir), editor, 0); return editor; }