diff --git a/ChangeLog b/ChangeLog index 2c54eaa5e6..0ee0b84d7a 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,10 @@ +2004-03-14 Sven Neumann + + * app/tools/gimptextoptions.[ch] + * app/tools/gimptexttool.[ch]: introduced a proxy GimpText object + that is tied to the GimpTextOptions for the lifetime of the text + tool. Brings us one step closer to text undo... + 2004-03-14 Michael Natterer * app/core/gimpdrawable-offset.c (gimp_drawable_offset) diff --git a/app/tools/gimptextoptions.c b/app/tools/gimptextoptions.c index 3c95396580..043dcdd42e 100644 --- a/app/tools/gimptextoptions.c +++ b/app/tools/gimptextoptions.c @@ -66,24 +66,30 @@ enum }; -static void gimp_text_options_class_init (GimpTextOptionsClass *options_class); -static void gimp_text_options_init (GimpTextOptions *options); +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_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 (GimpContext *context, - GParamSpec *pspec, - GimpText *text); -static void gimp_text_options_notify_font (GimpContext *context, - GParamSpec *pspec, - GimpText *text); +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; @@ -278,6 +284,36 @@ gimp_text_options_set_property (GObject *object, } } +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, @@ -287,80 +323,70 @@ gimp_text_options_notify_color (GimpContext *context, 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_font (GimpContext *context, - GParamSpec *pspec, - GimpText *text) +gimp_text_options_notify_text_color (GimpText *text, + GParamSpec *pspec, + GimpContext *context) { - g_object_set (text, "font", gimp_context_get_font_name (context), NULL); + 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); } -GimpText * -gimp_text_options_create_text (GimpTextOptions *options) +/* 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; - GimpText *text; GimpRGB color; - g_return_val_if_fail (GIMP_IS_TEXT_OPTIONS (options), NULL); + 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); - text = g_object_new (GIMP_TYPE_TEXT, - "color", &color, - "font", gimp_context_get_font_name (context), - 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)); - - gimp_context_define_property (GIMP_CONTEXT (options), - GIMP_CONTEXT_PROP_FOREGROUND, TRUE); - - gimp_config_sync (GIMP_CONFIG (text), GIMP_CONFIG (options), 0); - gimp_context_set_foreground (GIMP_CONTEXT (options), &text->color); - gimp_context_set_font_name (GIMP_CONTEXT (options), text->font); + 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); -} - -void -gimp_text_options_disconnect_text (GimpTextOptions *options, - GimpText *text) -{ - 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); - g_signal_handlers_disconnect_by_func (options, - gimp_text_options_notify_color, text); - - gimp_context_define_property (GIMP_CONTEXT (options), - GIMP_CONTEXT_PROP_FOREGROUND, FALSE); + g_signal_connect_object (text, "notify::color", + G_CALLBACK (gimp_text_options_notify_text_color), + options, 0); } GtkWidget * @@ -473,13 +499,6 @@ gimp_text_options_gui (GimpToolOptions *tool_options) return vbox; } -static void -gimp_text_options_text_changed (GimpTextEditor *editor, - GimpTextOptions *options) -{ - -} - static void gimp_text_options_dir_changed (GimpTextEditor *editor, GimpTextOptions *options) @@ -517,10 +536,6 @@ gimp_text_options_editor_new (GimpTextOptions *options, 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); diff --git a/app/tools/gimptextoptions.h b/app/tools/gimptextoptions.h index e129ac0a26..900b7fdde7 100644 --- a/app/tools/gimptextoptions.h +++ b/app/tools/gimptextoptions.h @@ -53,18 +53,15 @@ struct _GimpTextOptions }; -GType gimp_text_options_get_type (void) G_GNUC_CONST; +GType gimp_text_options_get_type (void) G_GNUC_CONST; -GimpText * gimp_text_options_create_text (GimpTextOptions *options); -void gimp_text_options_connect_text (GimpTextOptions *options, - GimpText *text); -void gimp_text_options_disconnect_text (GimpTextOptions *options, - GimpText *text); +void gimp_text_options_connect_text (GimpTextOptions *options, + GimpText *text); -GtkWidget * gimp_text_options_gui (GimpToolOptions *tool_options); +GtkWidget * gimp_text_options_gui (GimpToolOptions *tool_options); -GtkWidget * gimp_text_options_editor_new (GimpTextOptions *options, - const gchar *title); +GtkWidget * gimp_text_options_editor_new (GimpTextOptions *options, + const gchar *title); #endif /* __GIMP_TEXT_OPTIONS_H__ */ diff --git a/app/tools/gimptexttool.c b/app/tools/gimptexttool.c index 6830d2b61f..84cba7b039 100644 --- a/app/tools/gimptexttool.c +++ b/app/tools/gimptexttool.c @@ -59,31 +59,36 @@ /* local function prototypes */ -static void gimp_text_tool_class_init (GimpTextToolClass *klass); -static void gimp_text_tool_init (GimpTextTool *tool); +static void gimp_text_tool_class_init (GimpTextToolClass *klass); +static void gimp_text_tool_init (GimpTextTool *tool); +static GObject * gimp_text_tool_constructor (GType type, + guint n_params, + GObjectConstructParam *params); +static void gimp_text_tool_dispose (GObject *object); +static void gimp_text_tool_finalize (GObject *object); -static void gimp_text_tool_control (GimpTool *tool, - GimpToolAction action, - GimpDisplay *gdisp); -static void gimp_text_tool_button_press (GimpTool *tool, - GimpCoords *coords, - guint32 time, - GdkModifierType state, - GimpDisplay *gdisp); -static void gimp_text_tool_cursor_update (GimpTool *tool, - GimpCoords *coords, - GdkModifierType state, - GimpDisplay *gdisp); +static void gimp_text_tool_control (GimpTool *tool, + GimpToolAction action, + GimpDisplay *gdisp); +static void gimp_text_tool_button_press (GimpTool *tool, + GimpCoords *coords, + guint32 time, + GdkModifierType state, + GimpDisplay *gdisp); +static void gimp_text_tool_cursor_update (GimpTool *tool, + GimpCoords *coords, + GdkModifierType state, + GimpDisplay *gdisp); -static void gimp_text_tool_connect (GimpTextTool *tool, - GimpText *text); +static void gimp_text_tool_connect (GimpTextTool *tool, + GimpText *text); -static void gimp_text_tool_create_vectors (GimpTextTool *text_tool); -static void gimp_text_tool_create_layer (GimpTextTool *text_tool); +static void gimp_text_tool_create_vectors (GimpTextTool *text_tool); +static void gimp_text_tool_create_layer (GimpTextTool *text_tool); -static void gimp_text_tool_editor (GimpTextTool *text_tool); -static void gimp_text_tool_text_changed (GimpTextEditor *editor, - GimpTextTool *text_tool); +static void gimp_text_tool_editor (GimpTextTool *text_tool); +static void gimp_text_tool_text_changed (GimpTextEditor *editor, + GimpTextTool *text_tool); /* local variables */ @@ -144,10 +149,15 @@ gimp_text_tool_get_type (void) static void gimp_text_tool_class_init (GimpTextToolClass *klass) { - GimpToolClass *tool_class = GIMP_TOOL_CLASS (klass); + GObjectClass *object_class = G_OBJECT_CLASS (klass); + GimpToolClass *tool_class = GIMP_TOOL_CLASS (klass); parent_class = g_type_class_peek_parent (klass); + object_class->constructor = gimp_text_tool_constructor; + object_class->dispose = gimp_text_tool_dispose; + object_class->finalize = gimp_text_tool_finalize; + tool_class->control = gimp_text_tool_control; tool_class->button_press = gimp_text_tool_button_press; tool_class->cursor_update = gimp_text_tool_cursor_update; @@ -158,14 +168,66 @@ gimp_text_tool_init (GimpTextTool *text_tool) { GimpTool *tool = GIMP_TOOL (text_tool); - text_tool->text = NULL; - text_tool->layer = NULL; + text_tool->proxy = NULL; + text_tool->idle_id = 0; + + text_tool->text = NULL; + text_tool->layer = NULL; gimp_tool_control_set_scroll_lock (tool->control, TRUE); gimp_tool_control_set_preserve (tool->control, FALSE); gimp_tool_control_set_tool_cursor (tool->control, GIMP_TEXT_TOOL_CURSOR); } +static GObject * +gimp_text_tool_constructor (GType type, + guint n_params, + GObjectConstructParam *params) +{ + GObject *object; + GimpTextTool *text_tool; + GimpTextOptions *options; + + object = G_OBJECT_CLASS (parent_class)->constructor (type, n_params, params); + + text_tool = GIMP_TEXT_TOOL (object); + options = GIMP_TEXT_OPTIONS (GIMP_TOOL (text_tool)->tool_info->tool_options); + + text_tool->proxy = g_object_new (GIMP_TYPE_TEXT, NULL); + + gimp_text_options_connect_text (options, text_tool->proxy); + + return object; +} + +static void +gimp_text_tool_dispose (GObject *object) +{ + GimpTextTool *text_tool = GIMP_TEXT_TOOL (object); + + if (text_tool->idle_id) + { + g_source_remove (text_tool->idle_id); + text_tool->idle_id = 0; + } + + G_OBJECT_CLASS (parent_class)->dispose (object); +} + +static void +gimp_text_tool_finalize (GObject *object) +{ + GimpTextTool *text_tool = GIMP_TEXT_TOOL (object); + + if (text_tool->proxy) + { + g_object_unref (text_tool->proxy); + text_tool->proxy = NULL; + } + + G_OBJECT_CLASS (parent_class)->finalize (object); +} + static void gimp_text_tool_control (GimpTool *tool, GimpToolAction action, @@ -277,31 +339,28 @@ gimp_text_tool_create_vectors (GimpTextTool *text_tool) static void gimp_text_tool_create_layer (GimpTextTool *text_tool) { - GimpTool *tool = GIMP_TOOL (text_tool); - GimpTextOptions *options; - GimpImage *image; - GimpText *text; - GimpLayer *layer; + GimpTool *tool = GIMP_TOOL (text_tool); + GimpText *text; + GimpImage *image; + GimpLayer *layer; g_return_if_fail (text_tool->text == NULL); - options = GIMP_TEXT_OPTIONS (GIMP_TOOL (text_tool)->tool_info->tool_options); - - text = gimp_text_options_create_text (options); - - g_object_set (text, + g_object_set (text_tool->proxy, "text", gimp_text_editor_get_text (GIMP_TEXT_EDITOR (text_tool->editor)), NULL); image = tool->gdisp->gimage; + text = gimp_config_duplicate (GIMP_CONFIG (text_tool->proxy)); layer = gimp_text_layer_new (image, text); + g_object_unref (text); if (! layer) return; - gimp_text_tool_connect (text_tool, text); + gimp_text_tool_connect (text_tool, GIMP_TEXT_LAYER (layer)->text); gimp_tool_control_set_preserve (tool->control, TRUE); @@ -350,7 +409,13 @@ gimp_text_tool_connect (GimpTextTool *text_tool, text_tool); } - gimp_text_options_disconnect_text (options, text_tool->text); + gimp_config_disconnect (G_OBJECT (text_tool->text), + G_OBJECT (text_tool->proxy)); + + if (text_tool->editor) + gtk_widget_destroy (text_tool->editor); + + g_object_set (G_OBJECT (text_tool->proxy), "text", NULL, NULL); g_object_unref (text_tool->text); text_tool->text = NULL; @@ -358,11 +423,15 @@ gimp_text_tool_connect (GimpTextTool *text_tool, text_tool->layer = NULL; } + gimp_context_define_property (GIMP_CONTEXT (options), + GIMP_CONTEXT_PROP_FOREGROUND, text != NULL); + if (text) { text_tool->text = g_object_ref (text); - gimp_text_options_connect_text (options, text); + gimp_config_sync (GIMP_CONFIG (text), GIMP_CONFIG (text_tool->proxy), 0); + gimp_config_connect (G_OBJECT (text), G_OBJECT (text_tool->proxy), NULL); if (button) { @@ -418,9 +487,7 @@ gimp_text_tool_text_changed (GimpTextEditor *editor, text = gimp_text_editor_get_text (GIMP_TEXT_EDITOR (text_tool->editor)); - g_object_set (text_tool->text, - "text", text, - NULL); + g_object_set (text_tool->proxy, "text", text, NULL); g_free (text); } diff --git a/app/tools/gimptexttool.h b/app/tools/gimptexttool.h index f84803b300..ba3545dce4 100644 --- a/app/tools/gimptexttool.h +++ b/app/tools/gimptexttool.h @@ -29,13 +29,16 @@ #define GIMP_TEXT_TOOL_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GIMP_TYPE_TEXT_TOOL, GimpTextToolClass)) #define GIMP_IS_TEXT_TOOL_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GIMP_TYPE_TEXT_TOOL)) -typedef struct _GimpTextTool GimpTextTool; -typedef struct _GimpTextToolClass GimpTextToolClass; +typedef struct _GimpTextTool GimpTextTool; +typedef struct _GimpTextToolClass GimpTextToolClass; struct _GimpTextTool { GimpTool parent_instance; + GimpText *proxy; + guint idle_id; + gint x1, y1; gint x2, y2;