[gegl/soc-2012-editor] Completely implemented saving/loading of graphs, depended on recent fixes in master (not yet pushed)



commit cf28d1abb45d8bfaa250efcdee9792074de8ad12
Author: Isaac Wagner <isaacbw src gnome org>
Date:   Sun Jul 8 18:46:44 2012 -0400

    Completely implemented saving/loading of graphs, depended on recent fixes in master (not yet pushed). Loaded nodes are spawned in the position 0,0. Connections loaded intact

 bin/editor/.gitignore          |    3 +
 bin/editor/gegl-editor-layer.c |   97 ++++++++++++++++++++++++++++++++++++++--
 bin/editor/gegl-editor-layer.h |    1 +
 bin/editor/gegl-editor.c       |   75 ++++++++++++++++++++++++++++---
 bin/editor/gegl-node-widget.c  |   38 ++++++++++++++++
 bin/editor/gegl-node-widget.h  |    8 ++-
 6 files changed, 209 insertions(+), 13 deletions(-)
---
diff --git a/bin/editor/.gitignore b/bin/editor/.gitignore
index 3e7bab2..39c8781 100644
--- a/bin/editor/.gitignore
+++ b/bin/editor/.gitignore
@@ -1,2 +1,5 @@
 editor
 *.png
+*.xml
+*.o
+*.jpg
diff --git a/bin/editor/gegl-editor-layer.c b/bin/editor/gegl-editor-layer.c
index e4d1ad9..4da58b7 100644
--- a/bin/editor/gegl-editor-layer.c
+++ b/bin/editor/gegl-editor-layer.c
@@ -47,6 +47,21 @@ void refresh_images(GeglEditorLayer* self)
     }
 }
 
+gint get_editor_node_id(GeglEditorLayer* self, GeglNode* node)
+{
+  GSList*		pair = self->pairs;
+  for(;pair != NULL; pair = pair->next)
+    {
+      node_id_pair*	data = pair->data;
+      if(data->node == node)
+	{
+	  return data->id;
+	}
+    }
+
+  return 0;
+}
+
 gint layer_node_removed (gpointer host, GeglEditor* editor, gint node_id)
 {
   g_print("remove\n");
@@ -70,7 +85,7 @@ gint layer_node_removed (gpointer host, GeglEditor* editor, gint node_id)
   gegl_node_remove_child(self->gegl, node);
 }
 
-gint layer_connected_pads (gpointer host, GeglEditor* editor, gint from, gchar* output, gint to, gchar* input)
+gint layer_connected_pads (gpointer host, GeglEditor* editor, gint from, const gchar* output, gint to, const gchar* input)
 {
   GeglEditorLayer*	self = (GeglEditorLayer*)host;
 
@@ -91,12 +106,12 @@ gint layer_connected_pads (gpointer host, GeglEditor* editor, gint from, gchar*
   g_assert(from_node != NULL && to_node != NULL);
   g_assert(from_node != to_node);
   gboolean	success = gegl_node_connect_to(from_node, output, to_node, input);
-  g_print("connected: %s(%s) to %s(%s), %i\n", gegl_node_get_operation(from_node), output,
+  g_print("connected (%d): %s(%s) to %s(%s), %i\n", success, gegl_node_get_operation(from_node), output,
 	  gegl_node_get_operation(to_node), input, success);  
   refresh_images(self);
 }
 
-gint layer_disconnected_pads (gpointer host, GeglEditor* editor, gint from, gchar* output, gint to, gchar* input)
+gint layer_disconnected_pads (gpointer host, GeglEditor* editor, gint from, const gchar* output, gint to, const gchar* input)
 {
   GeglEditorLayer*	layer = (GeglEditorLayer*)host;
   g_print("disconnected: %s to %s\n", output, input);
@@ -205,6 +220,18 @@ gint layer_node_selected (gpointer host, GeglEditor* editor, gint node_id)
 
   g_assert(node != NULL);
 
+  GeglNode** nodes;
+  const gchar** pads;
+  gint num = gegl_node_get_consumers(node, "output", &nodes, &pads);
+
+  int i;
+  g_print("%s: %d consumer(s)\n", gegl_node_get_operation(node), num);
+  for(i = 0; i < num; i++)
+    {
+      g_print("Connection: (%s to %s)\n", gegl_node_get_operation(node), gegl_node_get_operation(nodes[0]), pads[0]);
+    }
+  g_print("Input from: %s\n", gegl_node_get_operation(gegl_node_get_producer(node, "input", NULL)));
+
   //  g_print("selected: %s\n", gegl_node_get_operation(node));
 
   guint		n_props;
@@ -213,7 +240,6 @@ gint layer_node_selected (gpointer host, GeglEditor* editor, gint node_id)
   //TODO: only create enough columns for the properties which will actually be included (i.e. ignoring GeglBuffer props)
   GtkTable	*prop_table = GTK_TABLE(gtk_table_new(2, n_props, FALSE));
 
-  int i;
   int d;
   for(d = 0, i = 0; i < n_props; i++, d++)
     {
@@ -348,6 +374,69 @@ const gchar*	gegl_pad_get_name(gpointer pad);
 GSList*	gegl_node_get_pads(GeglNode *self);
 GSList*	gegl_node_get_input_pads(GeglNode *self);
 
+gpointer gegl_node_get_pad (GeglNode      *self, const gchar   *name);
+
+static void print_info(GeglNode* gegl)
+{
+  GSList *list = gegl_node_get_children(gegl);
+  for(;list != NULL; list = list->next)
+    {
+      GeglNode* node = GEGL_NODE(list->data);
+      g_print("Node %s\n", gegl_node_get_operation(node));
+
+      if(gegl_node_get_pad(node, "output") == NULL) {
+	g_print("Output pad is NULL\n");
+      }
+
+      /*      GeglNode** nodes;
+      const gchar** pads;
+      gint num = gegl_node_get_consumers(node, "output", &nodes, &pads);
+      g_print("%s: %d consumer(s)\n", gegl_node_get_operation(node), num);
+
+      int i;
+      for(i = 0; i < num; i++)
+	{
+	  g_print("Connection: (%s to %s)\n", gegl_node_get_operation(node), gegl_node_get_operation(nodes[0]), pads[0]);
+	}
+	g_print("\n");*/
+    }
+}
+
+void layer_set_graph(GeglEditorLayer* self, GeglNode* gegl)
+{
+  //properly dispose of old gegl graph
+  self->gegl = gegl;
+  gegl_editor_remove_all_nodes(self->editor);
+  GSList *list = gegl_node_get_children(gegl);
+  for(;list != NULL; list = list->next)
+    {
+      GeglNode* node = GEGL_NODE(list->data);
+      g_print("Loading %s\n", gegl_node_get_operation(node));
+      layer_add_gegl_node(self, node);
+    }
+
+  for(list = gegl_node_get_children(gegl); list != NULL; list = list->next)
+    {
+      GeglNode* node = GEGL_NODE(list->data);
+      gint from = get_editor_node_id(self, node);
+
+      GeglNode** nodes;
+      const gchar** pads;
+     
+      if(!gegl_node_find_property(node, "output")) break;
+      gint num = gegl_node_get_consumers(node, "output", &nodes, &pads);
+
+      int i;
+      g_print("%s: %d consumer(s)\n", gegl_node_get_operation(node), num);
+      for(i = 0; i < num; i++)
+	{
+	  gint to = get_editor_node_id(self, nodes[i]);
+	  g_print("Connecting to consumer (%s to %s): output->%s\n", gegl_node_get_operation(node), gegl_node_get_operation(nodes[0]), pads[0]);
+	  gegl_editor_add_connection(self->editor, from, to, "output", pads[0]);
+	}
+    }
+}
+
 void
 layer_add_gegl_node(GeglEditorLayer* layer, GeglNode* node)
 {
diff --git a/bin/editor/gegl-editor-layer.h b/bin/editor/gegl-editor-layer.h
index 682c89f..800fafc 100644
--- a/bin/editor/gegl-editor-layer.h
+++ b/bin/editor/gegl-editor-layer.h
@@ -33,6 +33,7 @@ Editor and gegl graph should both be empty, but properly initialized
 */
 GeglEditorLayer*	layer_create(GeglEditor* editor, GeglNode* gegl, GtkWidget* property_editor_container);
 void			layer_add_gegl_node(GeglEditorLayer* layer, GeglNode* node);
+void layer_set_graph(GeglEditorLayer* layer, GeglNode* gegl); //will clear the current graph and load in the new one
 //void layer_remove_gegl_node(GeglNode* node);
 //link, unlink
 
diff --git a/bin/editor/gegl-editor.c b/bin/editor/gegl-editor.c
index cc7f960..d6ba9ed 100644
--- a/bin/editor/gegl-editor.c
+++ b/bin/editor/gegl-editor.c
@@ -8,19 +8,57 @@
 
 GtkWidget	*window;
 
+static void print_info(GeglNode* gegl)
+{
+  GSList *list = gegl_node_get_children(gegl);
+  for(;list != NULL; list = list->next)
+    {
+      GeglNode* node = GEGL_NODE(list->data);
+      g_print("Node %s\n", gegl_node_get_operation(node));
+
+      GeglNode** nodes;
+      const gchar** pads;
+      gint num = gegl_node_get_consumers(node, "output", &nodes, &pads);
+
+      int i;
+      g_print("%s: %d consumer(s)\n", gegl_node_get_operation(node), num);
+      for(i = 0; i < num; i++)
+	{
+	  g_print("Connection: (%s to %s)\n", gegl_node_get_operation(node), gegl_node_get_operation(nodes[0]), pads[0]);
+	}
+    }
+}
+
 GeglNode* getFinalNode(GeglNode* node)
 {
+  if(gegl_node_find_property(node, "output") == NULL)
+    return node;
+
   GeglNode**	nodes;
   const gchar** pads;
   gint		num_consumers = gegl_node_get_consumers(node, "output", &nodes, &pads);
-  if(0 == num_consumers)
+  
+  if(num_consumers == 0)
     return node;
   else
     return getFinalNode(nodes[0]);
 }
 
+
+GeglNode* getFirstNode(GeglNode* node)
+{
+  GeglNode* prev_node = gegl_node_get_producer(node, "input", NULL);
+  if(prev_node == NULL)
+    return node;
+  else
+    return getFirstNode(prev_node);
+}
+
+GeglNode* gegl_node_get_nth_child(GeglNode*, gint);
+
 void SaveAs(GeglEditorLayer* layer)
 {
+  print_info(layer->gegl);
   GtkFileChooserDialog	*file_select = GTK_FILE_CHOOSER_DIALOG(gtk_file_chooser_dialog_new("Save As", GTK_WINDOW(window), 
 											   GTK_FILE_CHOOSER_ACTION_SAVE, 
 											   GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
@@ -33,14 +71,33 @@ void SaveAs(GeglEditorLayer* layer)
 
       //Try to guess at an output
       GeglNode* first = gegl_node_get_nth_child(layer->gegl, 0);
+      GeglNode* last = getFinalNode(first);
 
-      const gchar	*xml = gegl_node_to_xml(getFinalNode(first), "");
+      g_print("Final node: %s\n", gegl_node_get_operation(last));
+      const gchar	*xml = gegl_node_to_xml(last, "/");
 
       g_print("%s\n", filename);
 
       g_file_set_contents(filename, xml, -1, NULL);	//TODO: check for error
+    }
 
-      //g_free(filename);
+  gtk_widget_destroy(GTK_WIDGET(file_select));
+}
+
+void Open(GeglEditorLayer* layer)
+{
+  GtkFileChooserDialog	*file_select = GTK_FILE_CHOOSER_DIALOG(gtk_file_chooser_dialog_new("Save As", GTK_WINDOW(window), 
+											   GTK_FILE_CHOOSER_ACTION_OPEN, 
+											   GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
+											   GTK_STOCK_OPEN, GTK_RESPONSE_ACCEPT,
+											   NULL));
+  gint			 result	     = gtk_dialog_run(GTK_DIALOG(file_select));
+  if(result == GTK_RESPONSE_ACCEPT)
+    {
+      const gchar	*filename = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(file_select));
+      GeglNode* gegl = gegl_node_new_from_file(filename);
+      layer_set_graph(layer, gegl);
+      //clear the current project, load in a new gegl object
     }
 
   gtk_widget_destroy(GTK_WIDGET(file_select));
@@ -56,9 +113,11 @@ void file_menu_item_activated(GtkMenuItem* item, gpointer data)
   else if(0 == g_strcmp0( label, "Save"))
     {
       //Check to see if open graph is associated with a file. If it is save to that	file, otherwise, save as
+      SaveAs((GeglEditorLayer*)data);
     }
   else if(0 == g_strcmp0(label, "Open"))
     {
+      Open((GeglEditorLayer*)data);
     }
   else if(0 == g_strcmp0(label, "New Graph"))
     {
@@ -167,7 +226,7 @@ main (gint	  argc,
   
   //add some samples nodes
   GeglNode		*gegl  = gegl_node_new();
-  GeglEditorLayer*	 layer = layer_create(node_editor, gegl, property_box);
+  GeglEditorLayer*	 layer = layer_create(node_editor, NULL, property_box);
 
   window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
   gtk_window_set_default_size(GTK_WINDOW(window), 800, 600);
@@ -263,10 +322,14 @@ main (gint	  argc,
   GeglNode	*text	 = gegl_node_new_child(gegl, "operation", "gegl:text", "size", 10.0, "color", 
 					       gegl_color_new("rgb(1.0,1.0,1.0)"), "text", "Hello world!", NULL);
 
+  gegl_node_link(load, over);
+
   //layer_add_gegl_node(layer, display);
-  layer_add_gegl_node(layer, over);
+  /*  layer_add_gegl_node(layer, over);
   layer_add_gegl_node(layer, load);
-  layer_add_gegl_node(layer, text);
+  layer_add_gegl_node(layer, text);*/
+
+  layer_set_graph(layer, gegl);
 
 
   ///////////////////////////////////////////////////////////////////////////////////////////////////////////////
diff --git a/bin/editor/gegl-node-widget.c b/bin/editor/gegl-node-widget.c
index 3b8d37c..1a28880 100644
--- a/bin/editor/gegl-node-widget.c
+++ b/bin/editor/gegl-node-widget.c
@@ -10,6 +10,27 @@ enum {
 
 static GParamSpec *obj_properties[N_PROPERTIES] = { NULL, };
 
+NodePad* editorNodeGetPad(EditorNode* node, const gchar* pad_name)
+{
+  int i;
+  NodePad*	pad = node->inputs;
+  for(i = 0;pad!=NULL;pad = pad->next, i++)
+    {
+      if(0 == g_strcmp0(pad->name, pad_name))
+	return pad;
+    }
+
+  i = 0;
+  pad = node->outputs;
+  for(i = 0;pad!=NULL;pad = pad->next, i++)
+    {
+      if(0 == g_strcmp0(pad->name, pad_name))
+	return pad;
+    }
+}
+
+EditorNode* gegl_editor_get_node(GeglEditor* self, gint id);
+
 static void
 gegl_editor_set_property (GObject		*object,
 			       guint		 property_id,
@@ -684,6 +705,16 @@ gegl_editor_add_node(GeglEditor* self, const gchar* title, gint ninputs, gchar**
   return node->id;
 }
 
+void gegl_editor_add_connection(GeglEditor* self, gint from, gint to, const gchar* output, const gchar* input)
+{
+  if(from == 0 || to == 0)
+    return;
+
+  NodePad* f = editorNodeGetPad(gegl_editor_get_node(self, from), output);
+  NodePad* t = editorNodeGetPad(gegl_editor_get_node(self, to), input);
+  connect_pads(f, t);
+}
+
 void gegl_editor_set_node_position(GeglEditor* self, gint id, gint x, gint y)
 {
   EditorNode*	node = gegl_editor_get_node(self, id);
@@ -713,6 +744,13 @@ EditorNode* gegl_editor_get_node(GeglEditor* self, gint id)
   return NULL;
 }
 
+void gegl_editor_remove_all_nodes(GeglEditor* self)
+{
+  //TODO: super obvious and stupid memory leak
+  self->first_node = NULL;
+  self->selected_node = NULL;
+}
+
 void gegl_editor_show_node_image(GeglEditor* self, gint node)
 {
   gegl_editor_get_node(self, node)->show_image = TRUE;
diff --git a/bin/editor/gegl-node-widget.h b/bin/editor/gegl-node-widget.h
index 8ec778a..94bce31 100644
--- a/bin/editor/gegl-node-widget.h
+++ b/bin/editor/gegl-node-widget.h
@@ -23,7 +23,7 @@ typedef struct _PadConnection   PadConnection;
 
 struct _NodePad
 {
-  gchar*	 name;
+  const gchar*	 name;
   NodePad	*connected;	//the pad that this is connected to. NULL if none
   NodePad	*next;		//the next pad in the linked list
   EditorNode*	 node;
@@ -55,8 +55,8 @@ struct _GeglEditor
   GtkDrawingArea	parent;
 
   /* public */
-  gint (*connectedPads) (gpointer host, GeglEditor* editor, gint from, gchar* output, gint to, gchar* input);
-  gint (*disconnectedPads) (gpointer host, GeglEditor* editor, gint from, gchar* output, gint to, gchar* input);
+  gint (*connectedPads) (gpointer host, GeglEditor* editor, gint from, const gchar* output, gint to, const gchar* input);
+  gint (*disconnectedPads) (gpointer host, GeglEditor* editor, gint from, const gchar* output, gint to, const gchar* input);
   gint (*nodeSelected) (gpointer host, GeglEditor* editor, gint node);
   gint (*nodeDeselected) (gpointer host, GeglEditor* editor, gint node);
   gint (*nodeRemoved) (gpointer host, GeglEditor* editor, gint node);
@@ -84,9 +84,11 @@ GtkWidget*	gegl_editor_new(void);
 
 //public methods
 gint	gegl_editor_add_node(GeglEditor* self, const gchar* title, gint ninputs, gchar** inputs, gint noutputs, gchar** outputs);
+void	gegl_editor_add_connection(GeglEditor*	self, gint from, gint to, const gchar* output, const gchar* input);
 void	gegl_editor_set_node_position(GeglEditor* self, gint node, gint x, gint y);
 void	gegl_editor_show_node_image(GeglEditor* self, gint node);
 void	gegl_editor_hide_node_image(GeglEditor* self, gint node);
 void	gegl_editor_set_node_image(GeglEditor* self, gint node, cairo_surface_t* image);
+void gegl_editor_remove_all_nodes(GeglEditor* self);
 
 #endif



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