[gimp] Implement overwrite-mode in the text tool



commit 1a2136408e1b6818888d2575b9c5640c890e1ab4
Author: Michael Natterer <mitch gimp org>
Date:   Thu Jun 25 13:22:25 2009 +0200

    Implement overwrite-mode in the text tool
    
    * app/widgets/gimptextproxy.c: also swallow the "toggle-overwrite"
    signal.
    
    * app/tools/gimpdrawtool. [ch] (gimp_draw_tool_draw_text_cursor): add
    "gboolean overwrite" which causes the cursor to be drawn as block.
    
    * app/tools/gimptexttool.[ch]: implement overwriting, toggling it,
    and changing the text cursor accordingly.

 app/tools/gimpdrawtool.c    |   71 +++++++++++++++++++++++++++++--------------
 app/tools/gimpdrawtool.h    |    1 +
 app/tools/gimptexttool.c    |   43 +++++++++++++++++++++++++-
 app/tools/gimptexttool.h    |    2 +
 app/widgets/gimptextproxy.c |    7 ++++
 5 files changed, 99 insertions(+), 25 deletions(-)
---
diff --git a/app/tools/gimpdrawtool.c b/app/tools/gimpdrawtool.c
index 5ee0029..b7427a7 100644
--- a/app/tools/gimpdrawtool.c
+++ b/app/tools/gimpdrawtool.c
@@ -1458,6 +1458,7 @@ gimp_draw_tool_draw_text_cursor (GimpDrawTool *draw_tool,
                                  gdouble       y1,
                                  gdouble       x2,
                                  gdouble       y2,
+                                 gboolean      overwrite,
                                  gboolean      use_offsets)
 {
   GimpDisplayShell *shell;
@@ -1477,29 +1478,53 @@ gimp_draw_tool_draw_text_cursor (GimpDrawTool *draw_tool,
                                      &tx2, &ty2,
                                      use_offsets);
 
-  /*  vertical line  */
-  gimp_canvas_draw_line (GIMP_CANVAS (shell->canvas), GIMP_CANVAS_STYLE_XOR,
-                         PROJ_ROUND (tx1), PROJ_ROUND (ty1) + 2,
-                         PROJ_ROUND (tx2), PROJ_ROUND (ty2) - 2);
-  gimp_canvas_draw_line (GIMP_CANVAS (shell->canvas), GIMP_CANVAS_STYLE_XOR,
-                         PROJ_ROUND (tx1) - 1, PROJ_ROUND (ty1) + 2,
-                         PROJ_ROUND (tx2) - 1, PROJ_ROUND (ty2) - 2);
-
-  /*  top serif  */
-  gimp_canvas_draw_line (GIMP_CANVAS (shell->canvas), GIMP_CANVAS_STYLE_XOR,
-                         PROJ_ROUND (tx1) - 3, PROJ_ROUND (ty1),
-                         PROJ_ROUND (tx1) + 3, PROJ_ROUND (ty1));
-  gimp_canvas_draw_line (GIMP_CANVAS (shell->canvas), GIMP_CANVAS_STYLE_XOR,
-                         PROJ_ROUND (tx1) - 3, PROJ_ROUND (ty1) + 1,
-                         PROJ_ROUND (tx1) + 3, PROJ_ROUND (ty1) + 1);
-
-  /*  bottom serif  */
-  gimp_canvas_draw_line (GIMP_CANVAS (shell->canvas), GIMP_CANVAS_STYLE_XOR,
-                         PROJ_ROUND (tx2) - 3, PROJ_ROUND (ty2) - 1,
-                         PROJ_ROUND (tx2) + 3, PROJ_ROUND (ty2) - 1);
-  gimp_canvas_draw_line (GIMP_CANVAS (shell->canvas), GIMP_CANVAS_STYLE_XOR,
-                         PROJ_ROUND (tx2) - 3, PROJ_ROUND (ty2) - 2,
-                         PROJ_ROUND (tx2) + 3, PROJ_ROUND (ty2) - 2);
+  if (overwrite)
+    {
+      gimp_canvas_draw_rectangle (GIMP_CANVAS (shell->canvas),
+                                  GIMP_CANVAS_STYLE_XOR, FALSE,
+                                  PROJ_ROUND (tx1),
+                                  PROJ_ROUND (ty1),
+                                  PROJ_ROUND (tx2 - tx1),
+                                  PROJ_ROUND (ty2 - ty1));
+      gimp_canvas_draw_rectangle (GIMP_CANVAS (shell->canvas),
+                                  GIMP_CANVAS_STYLE_XOR, FALSE,
+                                  PROJ_ROUND (tx1) + 1,
+                                  PROJ_ROUND (ty1) + 1,
+                                  PROJ_ROUND (tx2 - tx1) - 2,
+                                  PROJ_ROUND (ty2 - ty1) - 2);
+    }
+  else
+    {
+      /*  vertical line  */
+      gimp_canvas_draw_line (GIMP_CANVAS (shell->canvas),
+                             GIMP_CANVAS_STYLE_XOR,
+                             PROJ_ROUND (tx1), PROJ_ROUND (ty1) + 2,
+                             PROJ_ROUND (tx2), PROJ_ROUND (ty2) - 2);
+      gimp_canvas_draw_line (GIMP_CANVAS (shell->canvas),
+                             GIMP_CANVAS_STYLE_XOR,
+                             PROJ_ROUND (tx1) - 1, PROJ_ROUND (ty1) + 2,
+                             PROJ_ROUND (tx2) - 1, PROJ_ROUND (ty2) - 2);
+
+      /*  top serif  */
+      gimp_canvas_draw_line (GIMP_CANVAS (shell->canvas),
+                             GIMP_CANVAS_STYLE_XOR,
+                             PROJ_ROUND (tx1) - 3, PROJ_ROUND (ty1),
+                             PROJ_ROUND (tx1) + 3, PROJ_ROUND (ty1));
+      gimp_canvas_draw_line (GIMP_CANVAS (shell->canvas),
+                             GIMP_CANVAS_STYLE_XOR,
+                             PROJ_ROUND (tx1) - 3, PROJ_ROUND (ty1) + 1,
+                             PROJ_ROUND (tx1) + 3, PROJ_ROUND (ty1) + 1);
+
+      /*  bottom serif  */
+      gimp_canvas_draw_line (GIMP_CANVAS (shell->canvas),
+                             GIMP_CANVAS_STYLE_XOR,
+                             PROJ_ROUND (tx2) - 3, PROJ_ROUND (ty2) - 1,
+                             PROJ_ROUND (tx2) + 3, PROJ_ROUND (ty2) - 1);
+      gimp_canvas_draw_line (GIMP_CANVAS (shell->canvas),
+                             GIMP_CANVAS_STYLE_XOR,
+                             PROJ_ROUND (tx2) - 3, PROJ_ROUND (ty2) - 2,
+                             PROJ_ROUND (tx2) + 3, PROJ_ROUND (ty2) - 2);
+    }
 }
 
 gboolean
diff --git a/app/tools/gimpdrawtool.h b/app/tools/gimpdrawtool.h
index 0e9e920..508a99c 100644
--- a/app/tools/gimpdrawtool.h
+++ b/app/tools/gimpdrawtool.h
@@ -207,6 +207,7 @@ void       gimp_draw_tool_draw_text_cursor         (GimpDrawTool     *draw_tool,
                                                     gdouble           y1,
                                                     gdouble           x2,
                                                     gdouble           y2,
+                                                    gboolean          overwrite,
                                                     gboolean          use_offsets);
 
 gboolean   gimp_draw_tool_on_handle                (GimpDrawTool     *draw_tool,
diff --git a/app/tools/gimptexttool.c b/app/tools/gimptexttool.c
index 4340556..5616bd1 100644
--- a/app/tools/gimptexttool.c
+++ b/app/tools/gimptexttool.c
@@ -144,6 +144,7 @@ static void      gimp_text_tool_backspace       (GimpTextTool      *text_tool);
 static void      gimp_text_tool_cut_clipboard   (GimpTextTool      *text_tool);
 static void      gimp_text_tool_copy_clipboard  (GimpTextTool      *text_tool);
 static void      gimp_text_tool_paste_clipboard (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);
 
@@ -316,6 +317,8 @@ gimp_text_tool_init (GimpTextTool *text_tool)
 
   text_tool->handle_rectangle_change_complete = TRUE;
 
+  text_tool->overwrite_mode = FALSE;
+
   text_tool->x_pos = -1;
 }
 
@@ -1036,6 +1039,7 @@ gimp_text_tool_draw (GimpDrawTool *draw_tool)
       GtkTextIter     cursor;
       PangoRectangle  crect;
       gchar          *string;
+      gboolean        overwrite_cursor;
 
       gtk_text_buffer_get_iter_at_mark (text_tool->text_buffer, &cursor,
                                         gtk_text_buffer_get_insert (text_tool->text_buffer));
@@ -1057,11 +1061,17 @@ gimp_text_tool_draw (GimpDrawTool *draw_tool)
 
       crect.x      = PANGO_PIXELS (crect.x) + logical_off_x;
       crect.y      = PANGO_PIXELS (crect.y) + logical_off_y;
+      crect.width  = PANGO_PIXELS (crect.width);
       crect.height = PANGO_PIXELS (crect.height);
 
+      overwrite_cursor = text_tool->overwrite_mode && crect.width > 0;
+
       gimp_draw_tool_draw_text_cursor (draw_tool,
                                        crect.x, crect.y,
-                                       crect.x, crect.y + crect.height,
+                                       overwrite_cursor ?
+                                       crect.x + crect.width : crect.x,
+                                       crect.y + crect.height,
+                                       overwrite_cursor,
                                        TRUE);
 
       if (text_tool->preedit_string && text_tool->preedit_len > 0)
@@ -1388,6 +1398,9 @@ gimp_text_tool_ensure_proxy (GimpTextTool *text_tool)
       g_signal_connect_swapped (text_tool->proxy_text_view, "paste-clipboard",
                                 G_CALLBACK (gimp_text_tool_paste_clipboard),
                                 text_tool);
+      g_signal_connect_swapped (text_tool->proxy_text_view, "toggle-overwrite",
+                                G_CALLBACK (gimp_text_tool_toggle_overwrite),
+                                text_tool);
       g_signal_connect_swapped (text_tool->proxy_text_view, "select-all",
                                 G_CALLBACK (gimp_text_tool_select_all),
                                 text_tool);
@@ -1757,6 +1770,16 @@ gimp_text_tool_paste_clipboard (GimpTextTool *text_tool)
 }
 
 static void
+gimp_text_tool_toggle_overwrite (GimpTextTool *text_tool)
+{
+  gimp_draw_tool_pause (GIMP_DRAW_TOOL (text_tool));
+
+  text_tool->overwrite_mode = ! text_tool->overwrite_mode;
+
+  gimp_draw_tool_resume (GIMP_DRAW_TOOL (text_tool));
+}
+
+static void
 gimp_text_tool_select_all (GimpTextTool *text_tool,
                            gboolean      select)
 {
@@ -2588,9 +2611,25 @@ static void
 gimp_text_tool_enter_text (GimpTextTool *text_tool,
                            const gchar  *str)
 {
+  GtkTextBuffer *buffer = text_tool->text_buffer;
+  gboolean       had_selection;
+
+  had_selection = gtk_text_buffer_get_has_selection (buffer);
+
   gimp_text_tool_delete_selection (text_tool);
 
-  gtk_text_buffer_insert_at_cursor (text_tool->text_buffer, str, -1);
+  if (! had_selection && text_tool->overwrite_mode && strcmp (str, "\n"))
+    {
+      GtkTextIter cursor;
+
+      gtk_text_buffer_get_iter_at_mark (buffer, &cursor,
+                                        gtk_text_buffer_get_insert (buffer));
+
+      if (! gtk_text_iter_ends_line (&cursor))
+        gimp_text_tool_delete_from_cursor (text_tool, GTK_DELETE_CHARS, 1);
+    }
+
+  gtk_text_buffer_insert_at_cursor (buffer, str, -1);
 }
 
 static void
diff --git a/app/tools/gimptexttool.h b/app/tools/gimptexttool.h
index 746de54..7ee36bd 100644
--- a/app/tools/gimptexttool.h
+++ b/app/tools/gimptexttool.h
@@ -69,6 +69,8 @@ struct _GimpTextTool
   gboolean        select_words;
   gboolean        select_lines;
 
+  gboolean        overwrite_mode;
+
   gint            x_pos;
 
   GimpTextLayout *layout;
diff --git a/app/widgets/gimptextproxy.c b/app/widgets/gimptextproxy.c
index 8965bdc..1d3fe55 100644
--- a/app/widgets/gimptextproxy.c
+++ b/app/widgets/gimptextproxy.c
@@ -38,6 +38,7 @@ static void   gimp_text_proxy_backspace          (GtkTextView     *text_view);
 static void   gimp_text_proxy_cut_clipboard      (GtkTextView     *text_view);
 static void   gimp_text_proxy_copy_clipboard     (GtkTextView     *text_view);
 static void   gimp_text_proxy_paste_clipboard    (GtkTextView     *text_view);
+static void   gimp_text_proxy_toggle_overwrite   (GtkTextView     *text_view);
 
 
 G_DEFINE_TYPE (GimpTextProxy, gimp_text_proxy, GTK_TYPE_TEXT_VIEW)
@@ -55,6 +56,7 @@ gimp_text_proxy_class_init (GimpTextProxyClass *klass)
   tv_class->cut_clipboard      = gimp_text_proxy_cut_clipboard;
   tv_class->copy_clipboard     = gimp_text_proxy_copy_clipboard;
   tv_class->paste_clipboard    = gimp_text_proxy_paste_clipboard;
+  tv_class->toggle_overwrite   = gimp_text_proxy_toggle_overwrite;
 }
 
 static void
@@ -103,6 +105,11 @@ gimp_text_proxy_paste_clipboard (GtkTextView *text_view)
 {
 }
 
+static void
+gimp_text_proxy_toggle_overwrite (GtkTextView *text_view)
+{
+}
+
 
 /*  public functions  */
 



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