[gegl/soc-2012-editor] Completely implemented saving/loading of graphs, depended on recent fixes in master (not yet pushed)
- From: Isaac Wagner <isaacbw src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gegl/soc-2012-editor] Completely implemented saving/loading of graphs, depended on recent fixes in master (not yet pushed)
- Date: Sun, 8 Jul 2012 23:11:43 +0000 (UTC)
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]