gimp/app/tools/gimptextoptions.c
Sven Neumann 21f26743c1 made gimp_config_sync() and gimp_config_connect() also work on objects of
2004-03-11  Sven Neumann  <sven@gimp.org>

	* app/config/gimpconfig-utils.c: made gimp_config_sync() and
	gimp_config_connect() also work on objects of different types.
	Properties with the same name and the same type are synced /
	connected.

	* app/core/gimpcontext.[ch]: added convenience functions to get/set
	the font by name.

	* app/tools/gimptextoptions.[ch]: don't hold a GimpText object
	that duplicates properties like font and color which are in
	GimpContext already. Instead added all text properties that are
	controlled from the text tool options.  Handling of the foreground
	color is somewhat broken and needs a GimpContext wizard (Mitch!).

	* app/text/gimptext.c: blurbs are not any longer needed now that
	the property widgets are created from the GimpTextOptions.

	* app/tools/gimptexttool.c: changed accordingly.

	* app/widgets/gimptexteditor.[ch]: use an internal GtkTextBuffer
	and emit "text-changed" when it changes.
2004-03-11 18:47:37 +00:00

549 lines
18 KiB
C

/* 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 <gtk/gtk.h>
#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,
PROP_COLOR
};
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_color (GObject *object,
GParamSpec *pspec);
static void gimp_text_options_notify_font (GimpContext *context,
GParamSpec *pspec,
GimpText *text);
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);
GimpRGB black;
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);
gimp_rgba_set (&black, 0.0, 0.0, 0.0, GIMP_OPACITY_OPAQUE);
g_object_class_install_property (object_class, PROP_COLOR,
gimp_param_spec_color ("color", NULL, NULL,
&black,
G_PARAM_READWRITE));
}
static void
gimp_text_options_init (GimpTextOptions *options)
{
gimp_context_get_foreground (GIMP_CONTEXT (options), &options->color);
g_signal_connect (options, "notify::foreground",
G_CALLBACK (gimp_text_options_notify_color),
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;
case PROP_COLOR:
g_value_set_boxed (value, &options->color);
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);
GimpRGB *color;
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;
case PROP_COLOR:
color = g_value_get_boxed (value);
options->color = *color;
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
break;
}
}
static void
gimp_text_options_notify_color (GObject *object,
GParamSpec *pspec)
{
GimpRGB color;
gimp_context_get_foreground (GIMP_CONTEXT (object), &color);
g_object_set (object, "color", &color, NULL);
}
static void
gimp_text_options_notify_font (GimpContext *context,
GParamSpec *pspec,
GimpText *text)
{
g_object_set (text, "font", gimp_context_get_font_name (context), NULL);
}
GimpText *
gimp_text_options_create_text (GimpTextOptions *options)
{
GimpText *text;
g_return_val_if_fail (GIMP_IS_TEXT_OPTIONS (options), NULL);
text = g_object_new (GIMP_TYPE_TEXT,
"font",
gimp_context_get_font_name (GIMP_CONTEXT (options)),
NULL);
gimp_config_sync (GIMP_CONFIG (options), GIMP_CONFIG (text), 0);
return text;
}
void
gimp_text_options_connect_text (GimpTextOptions *options,
GimpText *text)
{
g_return_if_fail (GIMP_IS_TEXT_OPTIONS (options));
g_return_if_fail (GIMP_IS_TEXT (text));
g_signal_handlers_block_by_func (options,
gimp_text_options_notify_color, NULL);
gimp_config_sync (GIMP_CONFIG (text), GIMP_CONFIG (options), 0);
gimp_context_set_font_name (GIMP_CONTEXT (options), text->font);
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);
}
void
gimp_text_options_disconnect_text (GimpTextOptions *options,
GimpText *text)
{
GimpRGB color;
g_return_if_fail (GIMP_IS_TEXT_OPTIONS (options));
g_return_if_fail (GIMP_IS_TEXT (text));
gimp_config_disconnect (G_OBJECT (options), G_OBJECT (text));
g_signal_handlers_disconnect_by_func (options,
gimp_text_options_notify_font, text);
gimp_context_get_foreground (GIMP_CONTEXT (options), &color);
g_object_set (options, "color", &color, NULL);
g_signal_handlers_unblock_by_func (options,
gimp_text_options_notify_color, NULL);
}
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 *menu;
GtkWidget *box;
GtkWidget *spinbutton;
gint digits;
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);
digits = gimp_unit_get_digits (options->unit);
spinbutton = gimp_prop_spin_button_new (config, "font-size",
1.0, 10.0, digits);
gimp_table_attach_aligned (GTK_TABLE (table), 0, row,
_("_Size:"), 1.0, 0.5,
spinbutton, 1, FALSE);
menu = gimp_prop_unit_menu_new (config, "font-size-unit", "%a");
g_object_set_data (G_OBJECT (menu), "set_digits", spinbutton);
gtk_table_attach (GTK_TABLE (table), menu, 2, 3, row, row + 1,
GTK_SHRINK | GTK_FILL, GTK_SHRINK | GTK_FILL, 0, 0);
gtk_widget_show (menu);
row++;
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, "color", _("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_text_changed (GimpTextEditor *editor,
GimpTextOptions *options)
{
}
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, "text_changed",
G_CALLBACK (gimp_text_options_text_changed),
options, 0);
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;
}