gegl r2679 - in trunk: . bin



Author: ok
Date: Sat Nov  1 16:48:51 2008
New Revision: 2679
URL: http://svn.gnome.org/viewvc/gegl?rev=2679&view=rev

Log:
* bin/editor.c: refactored cairo code that shows on screen drawings
and pointer interaction code to operate with a state machine for
different modes. (menu_clear), (menu_add), (path_editor_keybinding),
(fill_press_event), (fill_release_event), (fill_motion_notify_event),
(cairo_expose), (cairo_gui_expose), (stroke_press_event),
(stroke_release_event), (stroke_motion_notify_event),
(gui_press_event), (gui_motion_event), (gui_release_event),
(editor_set_active), (editor_main).


Modified:
   trunk/ChangeLog
   trunk/bin/editor.c

Modified: trunk/bin/editor.c
==============================================================================
--- trunk/bin/editor.c	(original)
+++ trunk/bin/editor.c	Sat Nov  1 16:48:51 2008
@@ -51,6 +51,18 @@
 
 #include "gegl-path.h"
 
+enum 
+{
+  STATE_PICK = 0,
+  STATE_STROKES,
+  STATE_EDIT_NODES,
+  STATE_EDIT_LINEWIDTH,
+  STATE_EDIT_OPACITY,
+  STATE_FREE_REPLACE,
+  STATE_REDO_PART, /* redoes part of a path, starting on
+                      the first intersection */
+};
+
 
 typedef struct _Tools Tools;
 struct _Tools
@@ -58,20 +70,46 @@
 /* paint core globals */
   gint         state; /* 0: modify, 1: add strokes, 2: */
   
-  gboolean  stroke_active;
-  gboolean  path_editing_active;
-
-  GeglPath *da_vector;
+  GeglNode *node;
+  GeglPath *path;
   gint      selected_no;
   gint      drag_no; /* -1 */
   gint      drag_sub;
   gdouble   prevx;
   gdouble   prevy;
+
+  gboolean  in_stroke;
+  /* the pie menu code is written to handle only one pie menu
+   * at a time for now
+   */
+  gboolean  menu_active;
+  gdouble   menux;
+  gdouble   menuy;
+
+  gint      menu_segments;
+  gchar     menu_segment_label[10][10];
+  GCallback menu_segment_callback[10];
 };
 
-Editor editor;
 Tools  tools;
 
+static void
+menu_clear (void)
+{
+  tools.menu_segments=0;
+}
+
+static void
+menu_add (const gchar *label, GCallback callback)
+{
+  strcpy (tools.menu_segment_label[tools.menu_segments], label);
+  
+  tools.menu_segment_callback[tools.menu_segments]=callback;
+  tools.menu_segments++;
+}
+
+Editor editor;
+
 static gchar *blank_composition =
     "<gegl>"
         "<color value='white'/>"
@@ -190,33 +228,23 @@
     }
 }
 
-#if 0
-static gboolean editor.path_editing_active = FALSE;
-static GeglPath *editor.da_vector = NULL;
-static gint     editor.selected_no = 0;
-static gint     editor.drag_no = -1;
-static gint     editor.drag_sub = 0;
-static gdouble  editor.prevx = 0;
-static gdouble  editor.prevy = 0;
-#endif
-
 static gboolean
 path_editor_keybinding (GdkEventKey *event)
 {
-  if (!tools.path_editing_active)
+  if (tools.state != STATE_EDIT_NODES)
     return FALSE;
   switch (event->keyval)
     {
       case GDK_i:
         {
-          GeglPathItem knot = *gegl_path_get (tools.da_vector, tools.selected_no);
+          GeglPathItem knot = *gegl_path_get (tools.path, tools.selected_no);
           knot.point[0].x += 10;
-          gegl_path_insert (tools.da_vector, tools.selected_no, &knot);
+          gegl_path_insert (tools.path, tools.selected_no, &knot);
           tools.selected_no ++;
         }
         return TRUE;
       case GDK_BackSpace:
-        gegl_path_remove (tools.da_vector, tools.selected_no);
+        gegl_path_remove (tools.path, tools.selected_no);
         if (tools.selected_no>0)
           tools.selected_no --;
         else
@@ -224,7 +252,7 @@
         return TRUE;
       case GDK_m:
         {
-          GeglPathItem knot = *gegl_path_get (tools.da_vector, tools.selected_no);
+          GeglPathItem knot = *gegl_path_get (tools.path, tools.selected_no);
           switch (knot.type)
             {
               case 'v':
@@ -244,7 +272,7 @@
                 break;
             }
           g_print ("setting %c\n", knot.type);
-          gegl_path_replace (tools.da_vector, tools.selected_no, &knot);
+          gegl_path_replace (tools.path, tools.selected_no, &knot);
         }
         return TRUE;
       default:
@@ -253,10 +281,13 @@
   return FALSE;
 }
 
+
+
+
 static gboolean
 fill_press_event (GtkWidget      *widget,
-                    GdkEventButton *event,
-                    gpointer        data)
+                  GdkEventButton *event,
+                  gpointer        data)
 {
   gint   x, y;
   gdouble scale;
@@ -275,7 +306,7 @@
                 "y", &y,
                 "scale", &scale,
                 NULL);
-  gegl_node_get_translation (GEGL_NODE (data), &tx, &ty);
+  gegl_node_get_translation (GEGL_NODE (tools.node), &tx, &ty);
 
   ex = (event->x + x) / scale - tx;
   ey = (event->y + y) / scale - ty;
@@ -284,7 +315,7 @@
   cairo_scale (cr, scale, scale);
   cairo_translate (cr, tx, ty);*/
 
-  gegl_node_get (data, "path", &vector, NULL);
+  gegl_node_get (tools.node, "path", &vector, NULL);
 
   gegl_path_cairo_play (vector, cr);
 
@@ -416,13 +447,13 @@
                       gpointer        data)
 {
   tools.drag_no = -1;
-  return TRUE;
+  return FALSE;
 }
 
 static gboolean
 fill_motion_notify_event (GtkWidget      *widget,
-                     GdkEventMotion *event,
-                     gpointer        data)
+                          GdkEventMotion *event,
+                          gpointer        data)
 {
   if (tools.drag_no != -1)
     {
@@ -440,7 +471,7 @@
                     "y", &y,
                     "scale", &scale,
                     NULL);
-      gegl_node_get_translation (GEGL_NODE (data), &tx, &ty);
+      gegl_node_get_translation (tools.node, &tx, &ty);
 
       ex = (event->x + x) / scale - tx;
       ey = (event->y + y) / scale - ty;
@@ -448,7 +479,7 @@
       rx = tools.prevx - ex;
       ry = tools.prevy - ey;
 
-      gegl_node_get (data, "path", &vector, NULL);
+      gegl_node_get (tools.node, "path", &vector, NULL);
 
       if (tools.drag_sub == 0)
         {
@@ -489,19 +520,14 @@
           gegl_path_replace (vector, tools.drag_no + 1, &new_knot);
           gtk_widget_queue_draw (widget);
         }
-
-
       g_object_unref (vector);
       tools.prevx = ex;
       tools.prevy = ey;
       return TRUE;
-
     }
   return FALSE;
 }
 
-
-
 static gboolean cairo_expose (GtkWidget *widget,
                               GdkEvent  *event,
                               gpointer   user_data)
@@ -523,14 +549,15 @@
                 "y", &y,
                 "scale", &scale,
                 NULL);
-  gegl_node_get_translation (GEGL_NODE (user_data), &tx, &ty);
+  gegl_node_get_translation (GEGL_NODE (tools.node), &tx, &ty);
 
   cairo_translate (cr, -x, -y);
   cairo_scale (cr, scale, scale);
   cairo_translate (cr, tx, ty);
 
-  gegl_node_get (user_data, "path", &vector, NULL);
+  gegl_node_get (tools.node, "path", &vector, NULL);
 
+  cairo_new_path (cr);
   gegl_path_cairo_play (vector, cr);
 
   n= gegl_path_get_count (vector);
@@ -621,6 +648,97 @@
   return FALSE;
 }
 
+
+static gboolean cairo_gui_expose (GtkWidget *widget,
+                                  GdkEvent  *event,
+                                  gpointer   user_data)
+{
+  switch (tools.state)
+    {
+      case STATE_PICK:
+        break;
+      case STATE_EDIT_NODES:
+        cairo_expose (widget, event, user_data);
+        break;
+      case STATE_STROKES:
+        break;
+      case STATE_EDIT_LINEWIDTH:
+      case STATE_EDIT_OPACITY:
+      case STATE_FREE_REPLACE:
+      default:
+        g_warning ("not handling expose of state %i\n", tools.state);
+        break;
+    }
+
+  if (tools.menu_active)
+    {
+      gint x, y;
+      gdouble scale;
+      cairo_t *cr = gdk_cairo_create (widget->window);
+      g_object_get (G_OBJECT (widget),
+                    "x", &x,
+                    "y", &y,
+                    "scale", &scale,
+                    NULL);
+
+      cairo_translate (cr, -x, -y);
+
+      cairo_set_source_rgba (cr, 1.0, 0.0, 1.0, 1.0);
+
+      x = tools.menux;
+      y = tools.menuy;
+#if 0
+      cairo_move_to (cr, x, y);
+      cairo_arc (cr, x, y, 100, 0.0, 3.1415*2);
+      cairo_fill (cr);
+#endif
+
+      {
+        gint segment;
+        gint segments = tools.menu_segments;
+
+        gint inner = 35;
+        gint outher = 100;
+        gint middle = (inner+outher)/2;
+        gdouble adjustment = 3.0; /* adjustments to make the margin produce
+                                     a straight line from the centre
+                                     (set by trial and error) */
+
+
+        for (segment=0;segment<segments;segment++)
+          {
+            cairo_text_extents_t text_extents;
+            gdouble margin = 0.05 * (3.1415*2)/segments;
+            cairo_new_path (cr);
+            cairo_arc (cr, x, y, outher, segment*(3.1415*2)/segments + margin, (segment+1)*(3.1415*2)/segments -margin);
+            margin *= adjustment;
+            cairo_arc_negative (cr, x, y, inner, (segment+1)*(3.1415*2)/segments - margin, (segment)*(3.1415*2)/segments + margin);
+            cairo_set_source_rgba (cr, 1.0, 1.0, 1.0, 1.0);
+            cairo_stroke_preserve (cr);
+            cairo_set_source_rgba (cr, 0.0, 1.0, 1.0, 1.0);
+            cairo_fill (cr);
+
+            cairo_new_path (cr);
+            cairo_arc (cr, x, y, middle, (segment+0.5)*(3.1415*2)/segments,
+                                         (segment+0.5)*(3.1415*2)/segments);
+            cairo_set_source_rgba (cr, 1.0, 1.0, 1.0, 1.0);
+
+            cairo_select_font_face (cr, "Sans", CAIRO_FONT_SLANT_NORMAL,
+                                                CAIRO_FONT_WEIGHT_NORMAL);
+            cairo_set_font_size (cr, 20);
+            cairo_text_extents (cr, tools.menu_segment_label[segment], &text_extents);
+            cairo_rel_move_to (cr, -text_extents.width/2, +text_extents.height/2);
+            cairo_show_text (cr, tools.menu_segment_label[segment]);
+          }
+      }
+
+
+      cairo_destroy (cr);
+    }
+
+  return FALSE;
+}
+
 static gboolean
 stroke_press_event (GtkWidget      *widget,
                     GdkEventButton *event,
@@ -638,16 +756,16 @@
                 "y", &y,
                 "scale", &scale,
                 NULL);
-  gegl_node_get_translation (GEGL_NODE (data), &tx, &ty);
+  gegl_node_get_translation (GEGL_NODE (tools.node), &tx, &ty);
 
   ex = (event->x + x) / scale - tx;
   ey = (event->y + y) / scale - ty;
 
-  gegl_node_get (GEGL_NODE (data), "path", &vector, NULL);
+  gegl_node_get (GEGL_NODE (tools.node), "path", &vector, NULL);
 
   gegl_path_clear (vector);
   gegl_path_append (vector, 'M', ex, ey);
-  tools.stroke_active = TRUE;
+  tools.in_stroke = TRUE;
   g_object_unref (vector);
   return TRUE;
 }
@@ -655,7 +773,7 @@
 static gboolean
 stroke_release_event (GtkWidget      *widget,
                       GdkEventButton *event,
-                      gpointer        data)
+                      gpointer        dataa)
 {
   GeglNode *stroke;
   GeglColor *color = gegl_color_new ("red");
@@ -686,11 +804,12 @@
 
       gegl_color_get_rgba (color2, &r, &g, &b, &a);
       gegl_color_set_rgba (color, r,g,b,a);
-      gegl_node_set (stroke, "path", gegl_path_new (), "color", color, "linewidth", linewidth, NULL);
+      gegl_node_set (stroke, "path", tools.path=gegl_path_new (), "color", color, "linewidth", linewidth, NULL);
+      tools.node = stroke;
     }
 
-  tools.stroke_active = FALSE;
-  return TRUE;
+  tools.in_stroke = FALSE;
+  return FALSE;
 }
 
 
@@ -699,7 +818,7 @@
                             GdkEventMotion *event,
                             gpointer        data)
 {
-  if (tools.stroke_active)
+  if (tools.in_stroke)
     {
       gint   x, y;
       gdouble scale;
@@ -707,14 +826,12 @@
       gdouble ex, ey;
       gdouble rx, ry;
 
-      GeglPath *vector;
-
       g_object_get (G_OBJECT (widget),
                     "x", &x,
-                    "y", &y,
-                    "scale", &scale,
-                    NULL);
-      gegl_node_get_translation (GEGL_NODE (data), &tx, &ty);
+                      "y", &y,
+                      "scale", &scale,
+                      NULL);
+      gegl_node_get_translation (tools.node, &tx, &ty);
 
       ex = (event->x + x) / scale - tx;
       ey = (event->y + y) / scale - ty;
@@ -722,11 +839,8 @@
       rx = tools.prevx - ex;
       ry = tools.prevy - ey;
 
-      gegl_node_get (data, "path", &vector, NULL);
+      gegl_path_append (tools.path, 'L', ex, ey);
 
-      gegl_path_append (vector, 'L', ex, ey);
-
-      g_object_unref (vector);
       tools.prevx = ex;
       tools.prevy = ey;
       return TRUE;
@@ -735,39 +849,115 @@
   return FALSE;
 }
 
-void editor_set_active (gpointer view, gpointer node);
-void editor_set_active (gpointer view, gpointer node)
-{
-  static guint paint_handler = 0;
-  static guint press_handler = 0;
-  static guint motion_handler = 0;
-  static guint release_handler = 0;
-  const gchar *opname;
-
-  if (!view || ! node)
-    return;
 
-  if (paint_handler)
+static gboolean
+gui_press_event (GtkWidget      *widget,
+                    GdkEventButton *event,
+                    gpointer        data)
+{
+  if (event->button == 3)
     {
-      g_signal_handler_disconnect (view, paint_handler);
-      paint_handler = 0;
+      if (tools.menu_active)
+        {
+          tools.menu_active = FALSE;
+        }
+      else
+        {
+          gint   x, y;
+          gdouble scale;
+
+          tools.menu_active = TRUE;
+          g_object_get (G_OBJECT (widget),
+                        "x", &x,
+                        "y", &y,
+                        "scale", &scale,
+                      NULL);
+  
+            tools.menux = (event->x + x);
+            tools.menuy = (event->y + y);
+            menu_clear ();
+            menu_add ("foo", NULL);
+            menu_add ("bar", NULL);
+            menu_add ("baz", NULL);
+          }
+      gtk_widget_queue_draw (widget);
+      return TRUE;
     }
 
-  if (motion_handler)
+  switch (tools.state)
     {
-      g_signal_handler_disconnect (view, motion_handler);
-      motion_handler = 0;
+      case STATE_PICK:
+        break;
+      case STATE_EDIT_NODES:
+        return fill_press_event (widget, event, data);
+      case STATE_STROKES:
+        return stroke_press_event (widget, event, data);
+      case STATE_EDIT_LINEWIDTH:
+      case STATE_EDIT_OPACITY:
+      case STATE_FREE_REPLACE:
+      default:
+        g_warning ("not handling top release of state %i\n", tools.state);
+        break;
     }
-  if (release_handler)
+
+  return FALSE;
+}
+
+
+static gboolean
+gui_motion_event (GtkWidget      *widget,
+                  GdkEventMotion *event,
+                  gpointer        data)
+{
+  switch (tools.state)
     {
-      g_signal_handler_disconnect (view, release_handler);
-      release_handler = 0;
+      case STATE_PICK:
+        break;
+      case STATE_STROKES:
+        return stroke_motion_notify_event (widget, event, data);
+      case STATE_EDIT_NODES:
+        return fill_motion_notify_event (widget, event, data);
+      case STATE_EDIT_LINEWIDTH:
+      case STATE_EDIT_OPACITY:
+      case STATE_FREE_REPLACE:
+      default:
+        g_warning ("not handling top motion of state %i\n", tools.state);
+        break;
     }
-  if (press_handler)
+  return FALSE;
+}
+
+
+static gboolean
+gui_release_event (GtkWidget      *widget,
+                   GdkEventButton *event,
+                   gpointer        data)
+{
+  switch (tools.state)
     {
-      g_signal_handler_disconnect (view, press_handler);
-      press_handler = 0;
+      case STATE_PICK:
+        break;
+      case STATE_EDIT_NODES:
+        return fill_release_event (widget, event, data);
+      case STATE_STROKES:
+        return stroke_release_event (widget, event, data);
+      case STATE_EDIT_LINEWIDTH:
+      case STATE_EDIT_OPACITY:
+      case STATE_FREE_REPLACE:
+      default:
+        g_warning ("not handling top release of state %i\n", tools.state);
+        break;
     }
+  return FALSE;
+}
+
+void editor_set_active (gpointer view, gpointer node);
+void editor_set_active (gpointer view, gpointer node)
+{
+  const gchar *opname;
+
+  if (!view || ! node)
+    return;
 
   opname = gegl_node_get_operation (node);
 
@@ -776,46 +966,36 @@
       GeglPath *vector;
       gegl_node_get (node, "path", &vector, NULL);
 
-      tools.da_vector = vector;
+      tools.path = vector;
+      tools.node = node;
+
       g_object_unref (vector);
-      paint_handler = g_signal_connect_after (view, "expose-event",
-                              G_CALLBACK (cairo_expose), node);
-      press_handler = g_signal_connect (view, "button-press-event",
-                              G_CALLBACK (fill_press_event), node);
-      release_handler = g_signal_connect (view, "button-release-event",
-                              G_CALLBACK (fill_release_event), node);
-      motion_handler = g_signal_connect (view, "motion-notify-event",
-                              G_CALLBACK (fill_motion_notify_event), node);
-      tools.path_editing_active = TRUE;
+      tools.state = STATE_EDIT_NODES;
     }
    else if(g_str_equal (opname, "gegl:stroke"))
     {
       GeglPath *vector;
       gegl_node_get (node, "path", &vector, NULL);
-
-      tools.da_vector = vector;
+      if (!vector)
+        {
+          vector = gegl_path_new ();
+          gegl_node_set (node, "path", vector, NULL);
+        }
+      tools.path = vector;
+      tools.node = node;
       g_object_unref (vector);
-#if 0
-      paint_handler = g_signal_connect_after (view, "expose-event",
-                              G_CALLBACK (cairo_expose), node);
-#endif
-      press_handler = g_signal_connect (view, "button-press-event",
-                              G_CALLBACK (stroke_press_event), node);
-      release_handler = g_signal_connect (view, "button-release-event",
-                              G_CALLBACK (stroke_release_event), node);
-      motion_handler = g_signal_connect (view, "motion-notify-event",
-                              G_CALLBACK (stroke_motion_notify_event), node);
-      tools.path_editing_active = TRUE;
+      tools.state = STATE_STROKES;
     }
   else
     {
-      tools.path_editing_active = FALSE;
-      tools.da_vector = NULL;
+      tools.state = STATE_PICK;
+      tools.path = NULL;
     }
   gtk_widget_queue_draw (GTK_WIDGET (view));
 }
 
 
+
 static void cb_detected_event (GeglView *view,
                                GeglNode *node,
                                gpointer  userdata)
@@ -1007,7 +1187,15 @@
   gtk_widget_show (editor.window);
   gtk_container_set_border_width (GTK_CONTAINER (editor.property_editor), 6);
 
+  g_signal_connect_after (editor.view, "expose-event",
+                          G_CALLBACK (cairo_gui_expose), NULL);
 
+  g_signal_connect (editor.view, "button-press-event",
+                          G_CALLBACK (gui_press_event), NULL);
+  g_signal_connect (editor.view, "button-release-event",
+                          G_CALLBACK (gui_release_event), NULL);
+  g_signal_connect (editor.view, "motion-notify-event",
+                          G_CALLBACK (gui_motion_event), NULL);
 
   editor_set_gegl (gegl);
 



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