From 91cce1c81bdc0e11a4f7be02f40d7e0af4b4e550 Mon Sep 17 00:00:00 2001 From: Michael Natterer Date: Sun, 28 Mar 2010 21:38:31 +0200 Subject: [PATCH] app: add size control for text spans, does not work as expected yet --- app/tools/gimptexttool-editor.c | 23 ++++ app/widgets/gimptextbuffer.c | 198 +++++++++++++++++++++++++++++- app/widgets/gimptextbuffer.h | 13 ++ app/widgets/gimptextstyleeditor.c | 95 ++++++++++++-- app/widgets/gimptextstyleeditor.h | 4 +- 5 files changed, 321 insertions(+), 12 deletions(-) diff --git a/app/tools/gimptexttool-editor.c b/app/tools/gimptexttool-editor.c index ad7ab2ab90..6982ee0301 100644 --- a/app/tools/gimptexttool-editor.c +++ b/app/tools/gimptexttool-editor.c @@ -71,6 +71,8 @@ static void gimp_text_tool_backspace (GimpTextTool *text_tool); static void gimp_text_tool_toggle_overwrite (GimpTextTool *text_tool); static void gimp_text_tool_select_all (GimpTextTool *text_tool, gboolean select); +static void gimp_text_tool_change_size (GimpTextTool *text_tool, + gdouble amount); static void gimp_text_tool_change_baseline (GimpTextTool *text_tool, gdouble amount); static void gimp_text_tool_change_kerning (GimpTextTool *text_tool, @@ -595,6 +597,9 @@ gimp_text_tool_ensure_proxy (GimpTextTool *text_tool) g_signal_connect_swapped (text_tool->proxy_text_view, "select-all", G_CALLBACK (gimp_text_tool_select_all), text_tool); + g_signal_connect_swapped (text_tool->proxy_text_view, "change-size", + G_CALLBACK (gimp_text_tool_change_size), + text_tool); g_signal_connect_swapped (text_tool->proxy_text_view, "change-baseline", G_CALLBACK (gimp_text_tool_change_baseline), text_tool); @@ -996,6 +1001,24 @@ gimp_text_tool_select_all (GimpTextTool *text_tool, gimp_draw_tool_resume (GIMP_DRAW_TOOL (text_tool)); } +static void +gimp_text_tool_change_size (GimpTextTool *text_tool, + gdouble amount) +{ + GtkTextBuffer *buffer = GTK_TEXT_BUFFER (text_tool->buffer); + GtkTextIter start; + GtkTextIter end; + + if (! gtk_text_buffer_get_selection_bounds (buffer, &start, &end)) + { + return; + } + + gtk_text_iter_order (&start, &end); + gimp_text_buffer_change_size (text_tool->buffer, &start, &end, + amount * PANGO_SCALE); +} + static void gimp_text_tool_change_baseline (GimpTextTool *text_tool, gdouble amount) diff --git a/app/widgets/gimptextbuffer.c b/app/widgets/gimptextbuffer.c index 7dd1a8eb70..09d62c678f 100644 --- a/app/widgets/gimptextbuffer.c +++ b/app/widgets/gimptextbuffer.c @@ -147,6 +147,12 @@ gimp_text_buffer_finalize (GObject *object) { GimpTextBuffer *buffer = GIMP_TEXT_BUFFER (object); + if (buffer->size_tags) + { + g_list_free (buffer->size_tags); + buffer->size_tags = NULL; + } + if (buffer->baseline_tags) { g_list_free (buffer->baseline_tags); @@ -324,6 +330,174 @@ gimp_text_buffer_has_markup (GimpTextBuffer *buffer) return FALSE; } +GtkTextTag * +gimp_text_buffer_get_iter_size (GimpTextBuffer *buffer, + const GtkTextIter *iter, + gint *size) +{ + GList *list; + + for (list = buffer->size_tags; list; list = g_list_next (list)) + { + GtkTextTag *tag = list->data; + + if (gtk_text_iter_has_tag (iter, tag)) + { + if (size) + g_object_get (tag, + "size", size, + NULL); + + return tag; + } + } + + if (size) + *size = 0; + + return NULL; +} + +static GtkTextTag * +gimp_text_buffer_get_size_tag (GimpTextBuffer *buffer, + gint size) +{ + GList *list; + GtkTextTag *tag; + gchar name[32]; + + for (list = buffer->size_tags; list; list = g_list_next (list)) + { + gint tag_size; + + tag = list->data; + + g_object_get (tag, + "size", &tag_size, + NULL); + + if (tag_size == size) + return tag; + } + + g_snprintf (name, sizeof (name), "size-%d", size); + + tag = gtk_text_buffer_create_tag (GTK_TEXT_BUFFER (buffer), + name, + "size", size, + NULL); + + buffer->size_tags = g_list_prepend (buffer->size_tags, tag); + + return tag; +} + +void +gimp_text_buffer_set_size (GimpTextBuffer *buffer, + const GtkTextIter *start, + const GtkTextIter *end, + gint size) +{ + GList *list; + + g_return_if_fail (GIMP_IS_TEXT_BUFFER (buffer)); + g_return_if_fail (start != NULL); + g_return_if_fail (end != NULL); + + if (gtk_text_iter_equal (start, end)) + return; + + gtk_text_buffer_begin_user_action (GTK_TEXT_BUFFER (buffer)); + + for (list = buffer->size_tags; list; list = g_list_next (list)) + { + gtk_text_buffer_remove_tag (GTK_TEXT_BUFFER (buffer), list->data, + start, end); + } + + if (size != 0) + { + GtkTextTag *tag; + + tag = gimp_text_buffer_get_size_tag (buffer, size); + + gtk_text_buffer_apply_tag (GTK_TEXT_BUFFER (buffer), tag, + start, end); + } + + gtk_text_buffer_end_user_action (GTK_TEXT_BUFFER (buffer)); +} + +void +gimp_text_buffer_change_size (GimpTextBuffer *buffer, + const GtkTextIter *start, + const GtkTextIter *end, + gint count) +{ + GtkTextIter iter; + GtkTextIter span_start; + GtkTextIter span_end; + GtkTextTag *span_tag; + gint span_size; + + g_return_if_fail (GIMP_IS_TEXT_BUFFER (buffer)); + g_return_if_fail (start != NULL); + g_return_if_fail (end != NULL); + + if (gtk_text_iter_equal (start, end)) + return; + + iter = *start; + span_start = *start; + span_tag = gimp_text_buffer_get_iter_size (buffer, &iter, + &span_size); + + gtk_text_buffer_begin_user_action (GTK_TEXT_BUFFER (buffer)); + + do + { + GtkTextTag *iter_tag; + gint iter_size; + + gtk_text_iter_forward_char (&iter); + + iter_tag = gimp_text_buffer_get_iter_size (buffer, &iter, + &iter_size); + + span_end = iter; + + if (iter_size != span_size || + gtk_text_iter_compare (&iter, end) >= 0) + { + if (span_size != 0) + { + gtk_text_buffer_remove_tag (GTK_TEXT_BUFFER (buffer), span_tag, + &span_start, &span_end); + } + + if ((span_size + count) > 0) + { + span_tag = gimp_text_buffer_get_size_tag (buffer, + span_size + count); + + gtk_text_buffer_apply_tag (GTK_TEXT_BUFFER (buffer), span_tag, + &span_start, &span_end); + } + + span_start = iter; + span_size = iter_size; + span_tag = iter_tag; + } + + /* We might have moved too far */ + if (gtk_text_iter_compare (&iter, end) > 0) + iter = *end; + } + while (! gtk_text_iter_equal (&iter, end)); + + gtk_text_buffer_end_user_action (GTK_TEXT_BUFFER (buffer)); +} + GtkTextTag * gimp_text_buffer_get_iter_baseline (GimpTextBuffer *buffer, const GtkTextIter *iter, @@ -792,6 +966,24 @@ gimp_text_buffer_tag_to_name (GimpTextBuffer *buffer, { return "s"; } + else if (g_list_find (buffer->size_tags, tag)) + { + if (attribute) + *attribute = "size"; + + if (value) + { + gint size; + + g_object_get (tag, + "size", &size, + NULL); + + *value = g_strdup_printf ("%d", size); + } + + return "span"; + } else if (g_list_find (buffer->baseline_tags, tag)) { if (attribute) @@ -875,7 +1067,11 @@ gimp_text_buffer_name_to_tag (GimpTextBuffer *buffer, attribute != NULL && value != NULL) { - if (! strcmp (attribute, "rise")) + if (! strcmp (attribute, "size")) + { + return gimp_text_buffer_get_size_tag (buffer, atoi (value)); + } + else if (! strcmp (attribute, "rise")) { return gimp_text_buffer_get_baseline_tag (buffer, atoi (value)); } diff --git a/app/widgets/gimptextbuffer.h b/app/widgets/gimptextbuffer.h index 97425cca0b..1e4659857c 100644 --- a/app/widgets/gimptextbuffer.h +++ b/app/widgets/gimptextbuffer.h @@ -40,6 +40,7 @@ struct _GimpTextBuffer GtkTextTag *underline_tag; GtkTextTag *strikethrough_tag; + GList *size_tags; GList *baseline_tags; GList *kerning_tags; GList *font_tags; @@ -71,6 +72,18 @@ gchar * gimp_text_buffer_get_markup (GimpTextBuffer *buffer); gboolean gimp_text_buffer_has_markup (GimpTextBuffer *buffer); +GtkTextTag * gimp_text_buffer_get_iter_size (GimpTextBuffer *buffer, + const GtkTextIter *iter, + gint *size); +void gimp_text_buffer_set_size (GimpTextBuffer *buffer, + const GtkTextIter *start, + const GtkTextIter *end, + gint size); +void gimp_text_buffer_change_size (GimpTextBuffer *buffer, + const GtkTextIter *start, + const GtkTextIter *end, + gint amount); + GtkTextTag * gimp_text_buffer_get_iter_baseline (GimpTextBuffer *buffer, const GtkTextIter *iter, gint *baseline); diff --git a/app/widgets/gimptextstyleeditor.c b/app/widgets/gimptextstyleeditor.c index 424105eff0..2381a301b8 100644 --- a/app/widgets/gimptextstyleeditor.c +++ b/app/widgets/gimptextstyleeditor.c @@ -85,6 +85,11 @@ static void gimp_text_style_editor_set_toggle (GimpTextStyleEditor *e GtkToggleButton *toggle, gboolean active); +static void gimp_text_style_editor_size_changed (GtkAdjustment *adjustment, + GimpTextStyleEditor *editor); +static void gimp_text_style_editor_set_size (GimpTextStyleEditor *editor, + gint size); + static void gimp_text_style_editor_baseline_changed (GtkAdjustment *adjustment, GimpTextStyleEditor *editor); static void gimp_text_style_editor_set_baseline (GimpTextStyleEditor *editor, @@ -181,11 +186,21 @@ gimp_text_style_editor_init (GimpTextStyleEditor *editor) FALSE, FALSE, 0); gtk_widget_show (editor->font_entry); - editor->size_label = gtk_label_new ("0.0"); - gtk_misc_set_padding (GTK_MISC (editor->size_label), 2, 0); - gtk_box_pack_start (GTK_BOX (editor->upper_hbox), editor->size_label, + editor->size_adjustment = + GTK_ADJUSTMENT (gtk_adjustment_new (0.0, 0.0, 1000.0, 1.0, 10.0, 0.0)); + editor->size_spinbutton = gtk_spin_button_new (editor->size_adjustment, + 1.0, 1); + gtk_entry_set_width_chars (GTK_ENTRY (editor->size_spinbutton), 5); + gtk_box_pack_start (GTK_BOX (editor->upper_hbox), editor->size_spinbutton, FALSE, FALSE, 0); - gtk_widget_show (editor->size_label); + gtk_widget_show (editor->size_spinbutton); + + gimp_help_set_help_data (editor->size_spinbutton, + _("Change size of selected text"), NULL); + + g_signal_connect (editor->size_adjustment, "value-changed", + G_CALLBACK (gimp_text_style_editor_size_changed), + editor); /* lower row */ @@ -219,6 +234,9 @@ gimp_text_style_editor_init (GimpTextStyleEditor *editor) FALSE, FALSE, 0); gtk_widget_show (editor->kerning_spinbutton); + gimp_help_set_help_data (editor->kerning_spinbutton, + _("Change kerning of selected text"), NULL); + g_signal_connect (editor->kerning_adjustment, "value-changed", G_CALLBACK (gimp_text_style_editor_kerning_changed), editor); @@ -232,6 +250,9 @@ gimp_text_style_editor_init (GimpTextStyleEditor *editor) FALSE, FALSE, 0); gtk_widget_show (editor->baseline_spinbutton); + gimp_help_set_help_data (editor->baseline_spinbutton, + _("Change baseline of selected text"), NULL); + g_signal_connect (editor->baseline_adjustment, "value-changed", G_CALLBACK (gimp_text_style_editor_baseline_changed), editor); @@ -604,6 +625,41 @@ gimp_text_style_editor_set_toggle (GimpTextStyleEditor *editor, editor); } +static void +gimp_text_style_editor_size_changed (GtkAdjustment *adjustment, + GimpTextStyleEditor *editor) +{ + GtkTextBuffer *buffer = GTK_TEXT_BUFFER (editor->buffer); + GtkTextIter start, end; + + if (! gtk_text_buffer_get_selection_bounds (buffer, &start, &end)) + { + return; + } + + gimp_text_buffer_set_size (editor->buffer, &start, &end, + gtk_adjustment_get_value (adjustment) * + PANGO_SCALE); +} + +static void +gimp_text_style_editor_set_size (GimpTextStyleEditor *editor, + gint size) +{ + g_signal_handlers_block_by_func (editor->size_adjustment, + gimp_text_style_editor_size_changed, + editor); + + gtk_adjustment_set_value (editor->size_adjustment, + (gdouble) size / PANGO_SCALE); + /* make sure the "" really gets replaced */ + gtk_adjustment_value_changed (editor->size_adjustment); + + g_signal_handlers_unblock_by_func (editor->size_adjustment, + gimp_text_style_editor_size_changed, + editor); +} + static void gimp_text_style_editor_baseline_changed (GtkAdjustment *adjustment, GimpTextStyleEditor *editor) @@ -708,9 +764,11 @@ gimp_text_style_editor_update_idle (GimpTextStyleEditor *editor) GList *list; gboolean any_toggle_active = TRUE; gboolean font_differs = FALSE; + gboolean size_differs = FALSE; gboolean baseline_differs = FALSE; gboolean kerning_differs = FALSE; GtkTextTag *font_tag = NULL; + gint size; gint baseline; gint kerning; @@ -727,6 +785,7 @@ gimp_text_style_editor_update_idle (GimpTextStyleEditor *editor) /* and get some initial values */ font_tag = gimp_text_buffer_get_iter_font (editor->buffer, &start, NULL); + gimp_text_buffer_get_iter_size (editor->buffer, &start, &size); gimp_text_buffer_get_iter_baseline (editor->buffer, &start, &baseline); gimp_text_buffer_get_iter_kerning (editor->buffer, &start, &kerning); @@ -766,6 +825,17 @@ gimp_text_style_editor_update_idle (GimpTextStyleEditor *editor) font_differs = TRUE; } + if (! size_differs) + { + gint tag_size; + + gimp_text_buffer_get_iter_size (editor->buffer, &iter, + &tag_size); + + if (size != tag_size) + size_differs = TRUE; + } + if (! baseline_differs) { gint tag_baseline; @@ -790,6 +860,7 @@ gimp_text_style_editor_update_idle (GimpTextStyleEditor *editor) if (! any_toggle_active && font_differs && + size_differs && baseline_differs && kerning_differs) break; @@ -800,7 +871,10 @@ gimp_text_style_editor_update_idle (GimpTextStyleEditor *editor) gimp_text_style_editor_set_font (editor, font_tag); - gtk_label_set_text (GTK_LABEL (editor->size_label), "---"); + if (size_differs) + gtk_entry_set_text (GTK_ENTRY (editor->size_spinbutton), ""); + else + gimp_text_style_editor_set_size (editor, size); if (baseline_differs) gtk_entry_set_text (GTK_ENTRY (editor->baseline_spinbutton), ""); @@ -819,7 +893,6 @@ gimp_text_style_editor_update_idle (GimpTextStyleEditor *editor) GSList *tags_on; GSList *tags_off; GList *list; - gchar *str; gint value; gtk_text_buffer_get_iter_at_mark (buffer, &cursor, @@ -845,10 +918,6 @@ gimp_text_style_editor_update_idle (GimpTextStyleEditor *editor) if (! list) gimp_text_style_editor_set_font (editor, NULL); - str = g_strdup_printf ("%0.2f", editor->resolution_y); - gtk_label_set_text (GTK_LABEL (editor->size_label), str); - g_free (str); - for (list = editor->toggles; list; list = g_list_next (list)) { GtkToggleButton *toggle = list->data; @@ -861,6 +930,12 @@ gimp_text_style_editor_update_idle (GimpTextStyleEditor *editor) g_slist_find (tags_off, tag)); } + gimp_text_buffer_get_iter_size (editor->buffer, &cursor, &value); + if (value == 0) + gtk_entry_set_text (GTK_ENTRY (editor->size_spinbutton), ""); + else + gimp_text_style_editor_set_size (editor, value); + gimp_text_buffer_get_iter_baseline (editor->buffer, &cursor, &value); gimp_text_style_editor_set_baseline (editor, value); diff --git a/app/widgets/gimptextstyleeditor.h b/app/widgets/gimptextstyleeditor.h index d92efcc14a..7ce3fd89bb 100644 --- a/app/widgets/gimptextstyleeditor.h +++ b/app/widgets/gimptextstyleeditor.h @@ -49,10 +49,12 @@ struct _GimpTextStyleEditor GtkWidget *lower_hbox; GtkWidget *font_entry; - GtkWidget *size_label; GtkWidget *clear_button; + GtkWidget *size_spinbutton; + GtkAdjustment *size_adjustment; + GtkWidget *baseline_spinbutton; GtkAdjustment *baseline_adjustment;