[gimp] Move the proxy text view to its own offscreen window



commit e24793a6668842e969f97d766c20c873d145c343
Author: Michael Natterer <mitch gimp org>
Date:   Tue Jun 23 21:57:59 2009 +0200

    Move the proxy text view to its own offscreen window
    
    Add the proxy text view to a toplevel window so it can pick up the
    key theme. Remove various hacks and the #ifdef TEXT_TOOL_HACK stuff.

 app/tools/gimptexttool.c |  320 ++++++++++++++++++----------------------------
 app/tools/gimptexttool.h |   22 +---
 2 files changed, 127 insertions(+), 215 deletions(-)
---
diff --git a/app/tools/gimptexttool.c b/app/tools/gimptexttool.c
index b7ca20c..765faee 100644
--- a/app/tools/gimptexttool.c
+++ b/app/tools/gimptexttool.c
@@ -70,17 +70,6 @@
 #define TEXT_UNDO_TIMEOUT 3
 
 
-#ifndef TEXT_TOOL_HACK
-enum
-{
-  MOVE_CURSOR,
-  DELETE_FROM_CURSOR,
-  BACKSPACE,
-  LAST_SIGNAL
-};
-#endif
-
-
 /*  local function prototypes  */
 
 static void gimp_text_tool_rectangle_tool_iface_init (GimpRectangleToolInterface *iface);
@@ -143,26 +132,15 @@ static void      gimp_text_tool_draw_selection  (GimpDrawTool      *draw_tool,
 static gboolean  gimp_text_tool_rectangle_change_complete
                                                 (GimpRectangleTool *rect_tool);
 
+static void      gimp_text_tool_ensure_proxy    (GimpTextTool      *text_tool);
 static void      gimp_text_tool_move_cursor     (GimpTextTool      *text_tool,
                                                  GtkMovementStep    step,
                                                  gint               count,
-                                                 gboolean           extend_selection
-#ifdef TEXT_TOOL_HACK
-                                                 , GtkTextView     *proxy
-#endif
-                                                 );
+                                                 gboolean           extend_selection);
 static void   gimp_text_tool_delete_from_cursor (GimpTextTool      *text_tool,
                                                  GtkDeleteType      type,
-                                                 gint               count
-#ifdef TEXT_TOOL_HACK
-                                                 , GtkTextView     *proxy
-#endif
-                                                 );
-static void      gimp_text_tool_backspace       (GimpTextTool      *text_tool
-#ifdef TEXT_TOOL_HACK
-                                                 , GtkTextView     *proxy
-#endif
-                                                 );
+                                                 gint               count);
+static void      gimp_text_tool_backspace       (GimpTextTool      *text_tool);
 
 static void      gimp_text_tool_connect         (GimpTextTool      *text_tool,
                                                  GimpTextLayer     *layer,
@@ -230,10 +208,6 @@ G_DEFINE_TYPE_WITH_CODE (GimpTextTool, gimp_text_tool,
 
 #define parent_class gimp_text_tool_parent_class
 
-#ifndef TEXT_TOOL_HACK
-static guint signals[LAST_SIGNAL] = { 0, };
-#endif
-
 
 void
 gimp_text_tool_register (GimpToolRegisterCallback  callback,
@@ -279,47 +253,7 @@ gimp_text_tool_class_init (GimpTextToolClass *klass)
 
   draw_tool_class->draw        = gimp_text_tool_draw;
 
-#ifndef TEXT_TOOL_HACK
-  klass->move_cursor           = gimp_text_tool_move_cursor;
-  klass->delete_from_cursor    = gimp_text_tool_delete_from_cursor;
-  klass->backspace             = gimp_text_tool_backspace;
-#endif
-
   gimp_rectangle_tool_install_properties (object_class);
-
-#ifndef TEXT_TOOL_HACK
-  signals[MOVE_CURSOR] =
-    g_signal_new ("move-cursor",
-                  G_OBJECT_CLASS_TYPE (object_class),
-                  G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
-                  G_STRUCT_OFFSET (GimpTextToolClass, move_cursor),
-                  NULL, NULL,
-                  gimp_marshal_VOID__ENUM_INT_BOOLEAN,
-		  G_TYPE_NONE, 3,
-                  GTK_TYPE_MOVEMENT_STEP,
-                  G_TYPE_INT,
-                  G_TYPE_BOOLEAN);
-
-  signals[DELETE_FROM_CURSOR] =
-    g_signal_new ("delete-from-cursor",
-		  G_OBJECT_CLASS_TYPE (object_class),
-		  G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
-		  G_STRUCT_OFFSET (GimpTextToolClass, delete_from_cursor),
-		  NULL, NULL,
-		  gimp_marshal_VOID__ENUM_INT,
-		  G_TYPE_NONE, 2,
-		  GTK_TYPE_DELETE_TYPE,
-		  G_TYPE_INT);
-
-  signals[BACKSPACE] =
-    g_signal_new ("backspace",
-		  G_OBJECT_CLASS_TYPE (object_class),
-		  G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
-		  G_STRUCT_OFFSET (GimpTextToolClass, backspace),
-		  NULL, NULL,
-		  gimp_marshal_VOID__VOID,
-		  G_TYPE_NONE, 0);
-#endif
 }
 
 static void
@@ -379,34 +313,6 @@ gimp_text_tool_init (GimpTextTool *text_tool)
   text_tool->handle_rectangle_change_complete = TRUE;
 
   text_tool->x_pos = -1;
-
-#ifdef TEXT_TOOL_HACK
-  /*  we need this crap because we need some object to call
-   *  gtk_binding_set_activate() with. It takes a GtkObject instead of
-   *  a GObject. So instead of adding the needed binding signals to
-   *  GimpTextTool, we abuse a GtkTextView, which has all the needed
-   *  signals anyway, and connect to its signals. Puke!
-   */
-  {
-    GtkTextBuffer *dummy = gtk_text_buffer_new (NULL);
-
-    text_tool->proxy_text_view = gtk_text_view_new_with_buffer (dummy);
-    g_object_unref (dummy);
-
-    g_object_ref_sink (text_tool->proxy_text_view);
-    gtk_widget_ensure_style (text_tool->proxy_text_view);
-
-    g_signal_connect_swapped (text_tool->proxy_text_view, "move-cursor",
-                              G_CALLBACK (gimp_text_tool_move_cursor),
-                              text_tool);
-    g_signal_connect_swapped (text_tool->proxy_text_view, "delete-from-cursor",
-                              G_CALLBACK (gimp_text_tool_delete_from_cursor),
-                              text_tool);
-    g_signal_connect_swapped (text_tool->proxy_text_view, "backspace",
-                              G_CALLBACK (gimp_text_tool_backspace),
-                              text_tool);
-  }
-#endif
 }
 
 static GObject *
@@ -454,13 +360,12 @@ gimp_text_tool_dispose (GObject *object)
   if (text_tool->editor)
     gtk_widget_destroy (text_tool->editor);
 
-#ifdef TEXT_TOOL_HACK
   if (text_tool->proxy_text_view)
     {
-      g_object_unref (text_tool->proxy_text_view);
+      gtk_widget_destroy (text_tool->offscreen_window);
+      text_tool->offscreen_window = NULL;
       text_tool->proxy_text_view = NULL;
     }
-#endif
 
   G_OBJECT_CLASS (parent_class)->dispose (object);
 }
@@ -899,16 +804,17 @@ gimp_text_tool_key_press (GimpTool    *tool,
                           GimpDisplay *display)
 {
   GimpTextTool     *text_tool = GIMP_TEXT_TOOL (tool);
-  GtkTextViewClass *tv_class = g_type_class_ref (GTK_TYPE_TEXT_VIEW);
-  GtkBindingSet    *binding  = gtk_binding_set_by_class (tv_class);
-
-  GtkTextMark  *cursor_mark;
-  GtkTextMark  *selection_mark;
-  GtkTextIter   cursor;
-  GtkTextIter   selection;
-  GtkTextIter  *sel_start;
-  gint          x_pos  = -1;
-  gboolean      retval = TRUE;
+  GtkTextViewClass *tv_class  = g_type_class_ref (GTK_TYPE_TEXT_VIEW);
+  GtkBindingSet    *binding   = gtk_binding_set_by_class (tv_class);
+  GtkTextMark      *cursor_mark;
+  GtkTextMark      *selection_mark;
+  GtkTextIter       cursor;
+  GtkTextIter       selection;
+  GtkTextIter      *sel_start;
+  gint              x_pos  = -1;
+  gboolean          retval = TRUE;
+
+  g_type_class_unref (tv_class);
 
   if (display != tool->display)
     return FALSE;
@@ -921,15 +827,12 @@ gimp_text_tool_key_press (GimpTool    *tool,
       return TRUE;
     }
 
+  gimp_text_tool_ensure_proxy (text_tool);
+
   if (gtk_binding_set_activate (binding,
                                 kevent->keyval,
                                 kevent->state,
-#ifdef TEXT_TOOL_HACK
-                                GTK_OBJECT (text_tool->proxy_text_view)
-#else
-                                (GtkObject *) text_tool
-#endif
-                                ))
+                                GTK_OBJECT (text_tool->proxy_text_view)))
     {
       g_printerr ("binding handled event!\n");
       return TRUE;
@@ -1429,15 +1332,106 @@ gimp_text_tool_draw_selection (GimpDrawTool *draw_tool,
   pango_layout_iter_free (line_iter);
 }
 
+static gboolean
+gimp_text_tool_rectangle_change_complete (GimpRectangleTool *rect_tool)
+{
+  GimpTextTool *text_tool = GIMP_TEXT_TOOL (rect_tool);
+
+  if (text_tool->handle_rectangle_change_complete)
+    {
+      GimpText *text = text_tool->text;
+      GimpItem *item = GIMP_ITEM (text_tool->layer);
+      gint      x1, y1;
+      gint      x2, y2;
+
+      g_object_get (rect_tool,
+                    "x1", &x1,
+                    "y1", &y1,
+                    "x2", &x2,
+                    "y2", &y2,
+                    NULL);
+
+      text_tool->text_box_fixed = TRUE;
+
+      if (! text || ! text->text || (text->text[0] == 0))
+        {
+          /* we can't set properties for the text layer, because it
+           * isn't created until some text has been inserted, so we
+           * need to make a special note that will remind us what to
+           * do when we actually create the layer
+           */
+          return TRUE;
+        }
+
+      g_object_set (text_tool->proxy,
+                    "box-mode",   GIMP_TEXT_BOX_FIXED,
+                    "box-width",  (gdouble) (x2 - x1),
+                    "box-height", (gdouble) (y2 - y1),
+                    NULL);
+
+      gimp_image_undo_group_start (text_tool->image, GIMP_UNDO_GROUP_TEXT,
+                                   _("Reshape Text Layer"));
+
+      gimp_item_translate (item,
+                           x1 - gimp_item_get_offset_x (item),
+                           y1 - gimp_item_get_offset_y (item),
+                           TRUE);
+      gimp_text_tool_apply (text_tool);
+
+      gimp_image_undo_group_end (text_tool->image);
+    }
+
+  return TRUE;
+}
+
+static void
+gimp_text_tool_ensure_proxy (GimpTextTool *text_tool)
+{
+  GimpTool *tool = GIMP_TOOL (text_tool);
+
+  if (text_tool->offscreen_window &&
+      gtk_widget_get_screen (text_tool->offscreen_window) !=
+      gtk_widget_get_screen (tool->display->shell))
+    {
+      gtk_window_set_screen (GTK_WINDOW (text_tool->offscreen_window),
+                             gtk_widget_get_screen (tool->display->shell));
+      gtk_window_move (GTK_WINDOW (text_tool->offscreen_window), -200, -200);
+    }
+  else if (! text_tool->offscreen_window)
+    {
+      GtkTextBuffer *buffer;
+
+      text_tool->offscreen_window = gtk_window_new (GTK_WINDOW_POPUP);
+      gtk_window_set_screen (GTK_WINDOW (text_tool->offscreen_window),
+                             gtk_widget_get_screen (tool->display->shell));
+      gtk_window_move (GTK_WINDOW (text_tool->offscreen_window), -200, -200);
+      gtk_widget_show (text_tool->offscreen_window);
+
+      buffer = gtk_text_buffer_new (NULL);
+      text_tool->proxy_text_view = gtk_text_view_new_with_buffer (buffer);
+      g_object_unref  (buffer);
+
+      gtk_container_add (GTK_CONTAINER (text_tool->offscreen_window),
+                         text_tool->proxy_text_view);
+      gtk_widget_show (text_tool->proxy_text_view);
+
+      g_signal_connect_swapped (text_tool->proxy_text_view, "move-cursor",
+                                G_CALLBACK (gimp_text_tool_move_cursor),
+                                text_tool);
+      g_signal_connect_swapped (text_tool->proxy_text_view, "delete-from-cursor",
+                                G_CALLBACK (gimp_text_tool_delete_from_cursor),
+                                text_tool);
+      g_signal_connect_swapped (text_tool->proxy_text_view, "backspace",
+                                G_CALLBACK (gimp_text_tool_backspace),
+                                text_tool);
+    }
+}
+
 static void
 gimp_text_tool_move_cursor (GimpTextTool    *text_tool,
                             GtkMovementStep  step,
                             gint             count,
-                            gboolean         extend_selection
-#ifdef TEXT_TOOL_HACK
-                            , GtkTextView     *proxy
-#endif
-                            )
+                            gboolean         extend_selection)
 {
   GtkTextMark  *cursor_mark;
   GtkTextMark  *selection_mark;
@@ -1619,92 +1613,26 @@ gimp_text_tool_move_cursor (GimpTextTool    *text_tool,
                                 &cursor, sel_start);
 
   gimp_draw_tool_resume (GIMP_DRAW_TOOL (text_tool));
-
-#ifdef TEXT_TOOL_HACK
-  g_signal_stop_emission_by_name (proxy, "move-cursor");
-#endif
 }
 
 static void
 gimp_text_tool_delete_from_cursor (GimpTextTool  *text_tool,
                                    GtkDeleteType  type,
-                                   gint           count
-#ifdef TEXT_TOOL_HACK
-                                   , GtkTextView *proxy
-#endif
-                            )
+                                   gint           count)
 {
-  gimp_text_tool_delete_text (text_tool, FALSE);
+  g_printerr ("%s: %s count = %d\n",
+              G_STRFUNC,
+              g_enum_get_value (g_type_class_ref (GTK_TYPE_DELETE_TYPE),
+                                type)->value_name,
+              count);
 
-#ifdef TEXT_TOOL_HACK
-  g_signal_stop_emission_by_name (proxy, "delete-from-cursor");
-#endif
+  gimp_text_tool_delete_text (text_tool, FALSE);
 }
 
 static void
-gimp_text_tool_backspace (GimpTextTool  *text_tool
-#ifdef TEXT_TOOL_HACK
-                          , GtkTextView *proxy
-#endif
-                          )
+gimp_text_tool_backspace (GimpTextTool  *text_tool)
 {
   gimp_text_tool_delete_text (text_tool, TRUE);
-
-#ifdef TEXT_TOOL_HACK
-  g_signal_stop_emission_by_name (proxy, "backspace");
-#endif
-}
-
-static gboolean
-gimp_text_tool_rectangle_change_complete (GimpRectangleTool *rect_tool)
-{
-  GimpTextTool *text_tool = GIMP_TEXT_TOOL (rect_tool);
-
-  if (text_tool->handle_rectangle_change_complete)
-    {
-      GimpText *text = text_tool->text;
-      GimpItem *item = GIMP_ITEM (text_tool->layer);
-      gint      x1, y1;
-      gint      x2, y2;
-
-      g_object_get (rect_tool,
-                    "x1", &x1,
-                    "y1", &y1,
-                    "x2", &x2,
-                    "y2", &y2,
-                    NULL);
-
-      text_tool->text_box_fixed = TRUE;
-
-      if (! text || ! text->text || (text->text[0] == 0))
-        {
-          /* we can't set properties for the text layer, because it
-           * isn't created until some text has been inserted, so we
-           * need to make a special note that will remind us what to
-           * do when we actually create the layer
-           */
-          return TRUE;
-        }
-
-      g_object_set (text_tool->proxy,
-                    "box-mode",   GIMP_TEXT_BOX_FIXED,
-                    "box-width",  (gdouble) (x2 - x1),
-                    "box-height", (gdouble) (y2 - y1),
-                    NULL);
-
-      gimp_image_undo_group_start (text_tool->image, GIMP_UNDO_GROUP_TEXT,
-                                   _("Reshape Text Layer"));
-
-      gimp_item_translate (item,
-                           x1 - gimp_item_get_offset_x (item),
-                           y1 - gimp_item_get_offset_y (item),
-                           TRUE);
-      gimp_text_tool_apply (text_tool);
-
-      gimp_image_undo_group_end (text_tool->image);
-    }
-
-  return TRUE;
 }
 
 
diff --git a/app/tools/gimptexttool.h b/app/tools/gimptexttool.h
index 232856f..b87a48a 100644
--- a/app/tools/gimptexttool.h
+++ b/app/tools/gimptexttool.h
@@ -19,9 +19,6 @@
 #define __GIMP_TEXT_TOOL_H__
 
 
-#define TEXT_TOOL_HACK 1
-
-
 #include "gimpdrawtool.h"
 
 
@@ -76,27 +73,14 @@ struct _GimpTextTool
 
   GimpTextLayout *layout;
 
-#ifdef TEXT_TOOL_HACK
-  GtkWidget      *proxy_text_view; /* this sucks so much */
-#endif
+  /* this sucks so much */
+  GtkWidget      *offscreen_window;
+  GtkWidget      *proxy_text_view;
 };
 
 struct _GimpTextToolClass
 {
   GimpDrawToolClass parent_class;
-
-#ifndef TEXT_TOOL_HACK
-  void (* move_cursor)        (GimpTextTool    *text_tool,
-                               GtkMovementStep  step,
-                               gint             count,
-                               gboolean         extend_selection);
-
-  void (* delete_from_cursor) (GimpTextTool    *text_tool,
-                               GtkDeleteType    type,
-                               gint             count);
-
-  void (* backspace)          (GimpTextTool    *text_tool);
-#endif
 };
 
 



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