[gimp] app: add size control for text spans, does not work as expected yet



commit 91cce1c81bdc0e11a4f7be02f40d7e0af4b4e550
Author: Michael Natterer <mitch gimp org>
Date:   Sun Mar 28 21:38:31 2010 +0200

    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 ad7ab2a..6982ee0 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);
@@ -997,6 +1002,24 @@ gimp_text_tool_select_all (GimpTextTool *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 7dd1a8e..09d62c6 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);
@@ -325,6 +331,174 @@ gimp_text_buffer_has_markup (GimpTextBuffer *buffer)
 }
 
 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,
                                     gint              *baseline)
@@ -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 97425cc..1e46598 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 424105e..2381a30 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);
@@ -605,6 +626,41 @@ gimp_text_style_editor_set_toggle (GimpTextStyleEditor *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 d92efcc..7ce3fd8 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;
 



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]