[gegl-edit] Can now edit subgraphs
- From: Isaac Wagner <isaacbw src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gegl-edit] Can now edit subgraphs
- Date: Sat, 4 Aug 2012 17:13:23 +0000 (UTC)
commit 57edaefeadc66b3b9dd6aa2c866b98e7b281df3b
Author: Isaac Wagner <isaacbw src gnome org>
Date: Sat Aug 4 13:13:12 2012 -0400
Can now edit subgraphs
gegl-edit/contextmenu.ui | 27 +++
gegl-edit/contextmenu_canvas.ui | 19 ++
gegl-edit/gegl-edit.c | 440 +++++++++++++++++++++++++++---------
gegl-edit/gegl-gtk-property-view.c | 2 +-
gegl-edit/gresource.xml | 2 +
gegl-edit/menubar.ui | 37 +++-
6 files changed, 414 insertions(+), 113 deletions(-)
---
diff --git a/gegl-edit/contextmenu.ui b/gegl-edit/contextmenu.ui
new file mode 100644
index 0000000..6067eda
--- /dev/null
+++ b/gegl-edit/contextmenu.ui
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<interface>
+ <!-- interface-requires gtk+ 3.0 -->
+ <object class="GtkMenu" id="context">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <child>
+ <object class="GtkMenuItem" id="edit">
+ <property name="use_action_appearance">False</property>
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes">Edit</property>
+ <property name="use_underline">True</property>
+ <signal name="activate" handler="activated_context_edit" swapped="no"/>
+ </object>
+ </child>
+ <child>
+ <object class="GtkMenuItem" id="delete">
+ <property name="use_action_appearance">False</property>
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes">Delete</property>
+ <property name="use_underline">True</property>
+ </object>
+ </child>
+ </object>
+</interface>
diff --git a/gegl-edit/contextmenu_canvas.ui b/gegl-edit/contextmenu_canvas.ui
new file mode 100644
index 0000000..3f80ea0
--- /dev/null
+++ b/gegl-edit/contextmenu_canvas.ui
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<interface>
+ <!-- interface-requires gtk+ 3.0 -->
+ <object class="GtkMenu" id="context_canvas">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <child>
+ <object class="GtkMenuItem" id="return">
+ <property name="use_action_appearance">False</property>
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="tooltip_text" translatable="yes">Return to the parent graph</property>
+ <property name="label" translatable="yes">Return</property>
+ <property name="use_underline">True</property>
+ <signal name="activate" handler="activated_context_return" swapped="no"/>
+ </object>
+ </child>
+ </object>
+</interface>
diff --git a/gegl-edit/gegl-edit.c b/gegl-edit/gegl-edit.c
index 7ff77ef..4b94ba5 100644
--- a/gegl-edit/gegl-edit.c
+++ b/gegl-edit/gegl-edit.c
@@ -7,28 +7,36 @@
#include "resources.h"
+static void canvas_rightclicked(GraphGtkView *view, gpointer data);
static void node_selected(GraphGtkView *view, GraphGtkNode *node, gpointer data);
static void node_deselected(GraphGtkView *view, GraphGtkNode *node, gpointer data);
static void node_doubleclicked(GraphGtkView *view, GraphGtkNode *node, gpointer data);
+static void node_rightclicked(GraphGtkView *view, GraphGtkNode *node, gpointer data);
static void nodes_connected(GraphGtkView *view, GraphGtkNode *from, const gchar* output, GraphGtkNode *to, const gchar* input, gpointer data);
static void nodes_disconnected(GraphGtkView *view, GraphGtkNode *from, const gchar* output, GraphGtkNode *to, const gchar* input, gpointer data);
static GraphGtkNode* add_gegl_node_to_view(GraphGtkView *view, GeglNode *node);
+static void load_graph(GraphGtkView *view, GeglNode *node);
static void update_images(GraphGtkView *view);
static void update_bg_image(GraphGtkView *view);
//Undocumented gegl functions
GSList *gegl_node_get_input_pads(GeglNode*);
+GSList *gegl_node_get_pads(GeglNode *self);
const gchar *gegl_pad_get_name(gpointer);
GeglNode *gegl_node_get_nth_child (GeglNode*,gint);
typedef struct CallbackData
{
GtkWidget *window;
- GraphGtkView *view;
- GeglNode *gegl;
+ GraphGtkNode *context;
+ GQueue *graph_stack;
+ GQueue *view_stack;
+ GtkWidget *view_box;
GtkWidget *property_view;
+ GtkMenu *popup;
+ GtkMenu *popup2;
} CallbackData;
static void
@@ -63,15 +71,19 @@ main (gint argc,
CallbackData *data = g_new(CallbackData, 1);
data->window = window;
- data->view = GRAPH_GTK_VIEW(view);
- data->gegl = gegl;
+ data->view_stack = g_queue_new();
+ g_queue_push_head(data->view_stack, GRAPH_GTK_VIEW(view));
+ data->graph_stack = g_queue_new();
+ g_queue_push_head(data->graph_stack, gegl);
data->property_view = GTK_WIDGET(props);
g_signal_connect(props, "property-changed", G_CALLBACK(property_changed), view);
+ g_signal_connect(view, "canvas-rightclicked", G_CALLBACK(canvas_rightclicked), data);
g_signal_connect(view, "node-selected", G_CALLBACK(node_selected), data);
g_signal_connect(view, "node-deselected", G_CALLBACK(node_deselected), data);
g_signal_connect(view, "node-doubleclicked", G_CALLBACK(node_doubleclicked), data);
+ g_signal_connect(view, "node-rightclicked", G_CALLBACK(node_rightclicked), data);
g_signal_connect(view, "nodes-connected", G_CALLBACK(nodes_connected), data);
g_signal_connect(view, "nodes-disconnected", G_CALLBACK(nodes_disconnected), data);
@@ -84,6 +96,14 @@ main (gint argc,
//Build the menubar from misc/menubar.glade
GtkBuilder *builder = gtk_builder_new();
+ add_ui_to_builder(resource, builder, "/gegl-edit/contextmenu.ui", data);
+ GtkMenu *popup = GTK_MENU(gtk_builder_get_object(builder, "context"));
+ data->popup = popup;
+
+ add_ui_to_builder(resource, builder, "/gegl-edit/contextmenu_canvas.ui", data);
+ GtkMenu *popup2 = GTK_MENU(gtk_builder_get_object(builder, "context_canvas"));
+ data->popup2 = popup2;
+
add_ui_to_builder(resource, builder, "/gegl-edit/menubar.ui", data);
GtkWidget *menubar = GTK_WIDGET(gtk_builder_get_object(builder, "menu_bar"));
@@ -93,7 +113,11 @@ main (gint argc,
GtkWidget* pane = gtk_hpaned_new();
gtk_paned_set_position(GTK_PANED(pane), 450);
- gtk_paned_pack1(GTK_PANED(pane), view, TRUE, TRUE);
+ GtkWidget *box = gtk_vbox_new(TRUE, 0);
+ gtk_box_pack_start(GTK_BOX(box), view, TRUE, TRUE, 0);
+ data->view_box = box;
+
+ gtk_paned_pack1(GTK_PANED(pane), GTK_WIDGET(box), TRUE, TRUE);
gtk_paned_pack2(GTK_PANED(pane), props, TRUE, TRUE);
gtk_box_pack_start(GTK_BOX(vbox), pane, TRUE, TRUE, 0);
@@ -105,6 +129,17 @@ main (gint argc,
////////GraphGtk callbacks////////
static void
+canvas_rightclicked(GraphGtkView *view, gpointer user_data)
+{
+ g_print("canvas_rightclicked\n");
+ CallbackData *data = (CallbackData*)user_data;
+ if(g_queue_get_length(data->graph_stack) > 1)
+ {
+ gtk_menu_popup(data->popup2, NULL, NULL, NULL, NULL, 3, gtk_get_current_event_time());
+ }
+}
+
+static void
node_selected(GraphGtkView *view, GraphGtkNode *view_node, gpointer user_data)
{
CallbackData *data = (CallbackData*)user_data;
@@ -119,22 +154,38 @@ node_deselected(GraphGtkView *view, GraphGtkNode *node, gpointer user_data)
CallbackData *data = (CallbackData*)user_data;
GtkWidget *props = data->property_view;
gegl_gtk_property_view_set_node(GEGL_GTK_PROPERTY_VIEW(data->property_view), NULL);
- graph_gtk_view_set_bg(data->view, NULL);
+ graph_gtk_view_set_bg(g_queue_peek_head(data->view_stack), NULL);
}
static void
-node_doubleclicked(GraphGtkView *view, GraphGtkNode *view_node, gpointer data)
+node_rightclicked(GraphGtkView *view, GraphGtkNode *view_node, gpointer user_data)
{
- GeglNode *node = GEGL_NODE(view_node->user_data);
+ CallbackData *data = (CallbackData*)user_data;
- if(!view_node->show_image)
+ if(GEGL_IS_NODE(view_node->user_data))
{
- graph_gtk_node_show_image(view_node, TRUE);
- update_images(view);
+ data->context = view_node;
+ gtk_menu_popup(data->popup, NULL, NULL, NULL, NULL, 3, gtk_get_current_event_time());
+ //open menu
}
- else
+}
+
+static void
+node_doubleclicked(GraphGtkView *view, GraphGtkNode *view_node, gpointer data)
+{
+ if(GEGL_IS_NODE(view_node->user_data))
{
- graph_gtk_node_show_image(view_node, FALSE);
+ GeglNode *node = GEGL_NODE(view_node->user_data);
+
+ if(!view_node->show_image)
+ {
+ graph_gtk_node_show_image(view_node, TRUE);
+ update_images(view);
+ }
+ else
+ {
+ graph_gtk_node_show_image(view_node, FALSE);
+ }
}
}
@@ -143,24 +194,206 @@ nodes_connected(GraphGtkView *view, GraphGtkNode *from, const gchar* output, Gra
{
CallbackData *data = (CallbackData*)user_data;
- gegl_node_connect_to(from->user_data, output, to->user_data, input);
+ if(GEGL_IS_NODE(from->user_data) && GEGL_IS_NODE(to->user_data))
+ {
+ gegl_node_connect_to(from->user_data, output, to->user_data, input);
- update_images(view);
+ update_images(view);
+ }
}
static void
nodes_disconnected(GraphGtkView *view, GraphGtkNode *from, const gchar* output, GraphGtkNode *to, const gchar* input, gpointer user_data)
{
- gegl_node_disconnect(to->user_data, input);
- update_images(view);
+ if(GEGL_IS_NODE(to->user_data))
+ {
+ gegl_node_disconnect(to->user_data, input);
+ update_images(view);
+ }
}
//////////Gtk+ callbacks//////////
+G_MODULE_EXPORT void activated_context_return(GtkMenuItem *menuitem, gpointer user_data)
+{
+ CallbackData *data = user_data;
+ GtkWidget *view = GTK_WIDGET(g_queue_pop_head(data->view_stack));
+ gtk_container_remove(GTK_CONTAINER(data->view_box), view);
+ gtk_box_pack_start(GTK_BOX(data->view_box), GTK_WIDGET(g_queue_peek_head(data->view_stack)), TRUE, TRUE, 0);
+ gtk_widget_destroy(view);
+
+ GeglNode *node = g_queue_pop_head(data->graph_stack);
+
+ GraphGtkNode *view_node = NULL;
+ GList *list;
+ for(list = GRAPH_GTK_VIEW(g_queue_peek_head(data->view_stack))->nodes; list != NULL; list = list->next)
+ {
+ GraphGtkNode *n = list->data;
+ g_print("checking %s\n", n->name);
+ if(n->user_data == node)
+ view_node = n;
+ }
+
+ g_assert(view_node);
+
+ graph_gtk_node_remove_pads(view_node);
+
+ GSList *pads;
+ for(pads = gegl_node_get_pads(node); pads != NULL; pads = pads->next)
+ {
+ graph_gtk_node_add_pad(view_node, gegl_pad_get_name(pads->data), gegl_pad_is_output(pads->data));
+ }
+}
+
+G_MODULE_EXPORT void activated_context_edit(GtkMenuItem *menuitem, gpointer user_data)
+{
+ CallbackData *data = user_data;
+ if(data->context)
+ {
+ GtkWidget *view = graph_gtk_view_new();
+ load_graph(GRAPH_GTK_VIEW(view), data->context->user_data);
+
+ g_object_ref(g_queue_peek_head(data->view_stack));
+ gtk_container_remove(GTK_CONTAINER(data->view_box), g_queue_peek_head(data->view_stack));
+ gtk_box_pack_start(GTK_BOX(data->view_box), view, TRUE, TRUE, 0);
+ gtk_widget_show(view);
+
+ g_queue_push_head(data->view_stack, view);
+ g_queue_push_head(data->graph_stack, data->context->user_data);
+ g_print("views: %d, graphs: %d\n", g_queue_get_length(data->view_stack), g_queue_get_length(data->graph_stack));
+
+ g_signal_connect(view, "canvas-rightclicked", G_CALLBACK(canvas_rightclicked), data);
+ g_signal_connect(view, "node-selected", G_CALLBACK(node_selected), data);
+ g_signal_connect(view, "node-deselected", G_CALLBACK(node_deselected), data);
+ g_signal_connect(view, "node-doubleclicked", G_CALLBACK(node_doubleclicked), data);
+ g_signal_connect(view, "node-rightclicked", G_CALLBACK(node_rightclicked), data);
+ g_signal_connect(view, "nodes-connected", G_CALLBACK(nodes_connected), data);
+ g_signal_connect(view, "nodes-disconnected", G_CALLBACK(nodes_disconnected), data);
+ }
+}
+
+G_MODULE_EXPORT void activated_context_delete(GtkMenuItem *menuitem, gpointer user_data)
+{
+ CallbackData *data = user_data;
+ graph_gtk_view_remove_node(g_queue_peek_head(data->view_stack), data->context);
+}
+
+G_MODULE_EXPORT void activated_add_subgraph(GtkMenuItem *menuitem, gpointer user_data)
+{
+ CallbackData *data = user_data;
+ GtkWidget* dialog = gtk_dialog_new_with_buttons ("Add Subgraph",
+ GTK_WINDOW(data->window),
+ GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT,
+ GTK_STOCK_OK, GTK_RESPONSE_ACCEPT,
+ GTK_STOCK_CANCEL, GTK_RESPONSE_REJECT,
+ NULL);
+
+ //gtk_window_set_default_size(GTK_WINDOW(dialog), 350, 80);
+
+ GtkWidget* vbox = gtk_dialog_get_content_area(GTK_DIALOG(dialog));
+
+ GtkWidget* name_label = gtk_label_new("Name");
+ GtkWidget* name_entry = gtk_entry_new();
+ gtk_box_pack_start(GTK_BOX(vbox), name_label, FALSE, FALSE, 0);
+ gtk_box_pack_start(GTK_BOX(vbox), name_entry, FALSE, FALSE, 0);
+
+ gtk_widget_show_all(vbox);
+
+ gint result = gtk_dialog_run(GTK_DIALOG(dialog));
+
+ if(result == GTK_RESPONSE_ACCEPT)
+ {
+ const gchar *name = gtk_entry_get_text(GTK_ENTRY(name_entry));
+ GraphGtkNode *node = graph_gtk_node_new();
+ graph_gtk_node_set_name(node, name);
+ GeglNode *subgraph = gegl_node_new();
+ node->user_data = subgraph;
+ graph_gtk_view_add_node(g_queue_peek_head(data->view_stack), node);
+ }
+
+ gtk_widget_destroy(dialog);
+}
+
+G_MODULE_EXPORT void activated_add_input(GtkMenuItem *menuitem, gpointer user_data)
+{
+ CallbackData *data = user_data;
+
+ GtkWidget* dialog = gtk_dialog_new_with_buttons ("Add Input",
+ GTK_WINDOW(data->window),
+ GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT,
+ GTK_STOCK_OK, GTK_RESPONSE_ACCEPT,
+ GTK_STOCK_CANCEL, GTK_RESPONSE_REJECT,
+ NULL);
+
+ //gtk_window_set_default_size(GTK_WINDOW(dialog), 350, 80);
+
+ GtkWidget* vbox = gtk_dialog_get_content_area(GTK_DIALOG(dialog));
+
+ GtkWidget* name_label = gtk_label_new("Name");
+ GtkWidget* name_entry = gtk_entry_new();
+ gtk_box_pack_start(GTK_BOX(vbox), name_label, FALSE, FALSE, 0);
+ gtk_box_pack_start(GTK_BOX(vbox), name_entry, FALSE, FALSE, 0);
+
+ gtk_widget_show_all(vbox);
+
+ gint result = gtk_dialog_run(GTK_DIALOG(dialog));
+
+ if(result == GTK_RESPONSE_ACCEPT)
+ {
+ const gchar *name = gtk_entry_get_text(GTK_ENTRY(name_entry));
+ GraphGtkNode *node = graph_gtk_node_new();
+ graph_gtk_node_set_name(node, name);
+ graph_gtk_node_add_pad(node, "output", TRUE);
+ graph_gtk_view_add_node(g_queue_peek_head(data->view_stack), node);
+ GeglNode *proxy = gegl_node_get_input_proxy(g_queue_peek_head(data->graph_stack), name);
+ node->user_data = proxy;
+ }
+
+ gtk_widget_destroy(dialog);
+}
+
+G_MODULE_EXPORT void activated_add_output(GtkMenuItem *menuitem, gpointer user_data)
+{
+ CallbackData *data = user_data;
+
+ GtkWidget* dialog = gtk_dialog_new_with_buttons ("Add Output",
+ GTK_WINDOW(data->window),
+ GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT,
+ GTK_STOCK_OK, GTK_RESPONSE_ACCEPT,
+ GTK_STOCK_CANCEL, GTK_RESPONSE_REJECT,
+ NULL);
+
+ //gtk_window_set_default_size(GTK_WINDOW(dialog), 350, 80);
+
+ GtkWidget* vbox = gtk_dialog_get_content_area(GTK_DIALOG(dialog));
+
+ GtkWidget* name_label = gtk_label_new("Name");
+ GtkWidget* name_entry = gtk_entry_new();
+ gtk_box_pack_start(GTK_BOX(vbox), name_label, FALSE, FALSE, 0);
+ gtk_box_pack_start(GTK_BOX(vbox), name_entry, FALSE, FALSE, 0);
+
+ gtk_widget_show_all(vbox);
+
+ gint result = gtk_dialog_run(GTK_DIALOG(dialog));
+
+ if(result == GTK_RESPONSE_ACCEPT)
+ {
+ const gchar *name = gtk_entry_get_text(GTK_ENTRY(name_entry));
+ GraphGtkNode *node = graph_gtk_node_new();
+ graph_gtk_node_set_name(node, name);
+ graph_gtk_node_add_pad(node, "input", FALSE);
+ graph_gtk_view_add_node(g_queue_peek_head(data->view_stack), node);
+ GeglNode *proxy = gegl_node_get_output_proxy(g_queue_peek_head(data->graph_stack), name);
+ node->user_data = proxy;
+ }
+
+ gtk_widget_destroy(dialog);
+}
+
G_MODULE_EXPORT void activated_open(GtkMenuItem *menuitem, gpointer user_data)
{
CallbackData *data = user_data;
- GraphGtkView *view = data->view;
+ GraphGtkView *view = g_queue_peek_head(data->view_stack);
GtkFileChooserDialog *file_select = GTK_FILE_CHOOSER_DIALOG(gtk_file_chooser_dialog_new("Save As", GTK_WINDOW(data->window),
GTK_FILE_CHOOSER_ACTION_OPEN,
@@ -173,52 +406,7 @@ G_MODULE_EXPORT void activated_open(GtkMenuItem *menuitem, gpointer user_data)
const gchar *filename = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(file_select));
GeglNode* gegl = gegl_node_new_from_file(filename);
- GHashTable *hash_table = g_hash_table_new(g_direct_hash, g_direct_equal);
-
- 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));
- GraphGtkNode *view_node = add_gegl_node_to_view(data->view, node);
- g_hash_table_insert(hash_table, node, view_node);
- }
-
- for(list = gegl_node_get_children(gegl); list != NULL; list = list->next)
- {
- GeglNode* node = GEGL_NODE(list->data);
-
- GraphGtkNode *from = g_hash_table_lookup(hash_table, node);
- if(!from)
- break;
-
- g_print("from: %s\n", from->name);
-
- if(!gegl_node_has_pad(node, "output"))
- {
- g_print("No output\n");
- break;
- }
-
- 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++)
- {
- GraphGtkNode *to = g_hash_table_lookup(hash_table, nodes[i]);
- if(!to)
- break;
-
- g_print("to: %s\n", to->name);
- g_print("Connecting to consumer (%s to %s): output->%s\n", gegl_node_get_operation(node), gegl_node_get_operation(nodes[i]), pads[i]);
- graph_gtk_node_connect_to(from, "output", to, pads[i]);
- }
- }
-
- g_hash_table_destroy(hash_table);
+ load_graph(view, gegl);
}
gtk_widget_destroy(GTK_WIDGET(file_select));
@@ -253,7 +441,7 @@ G_MODULE_EXPORT void activated_save_as(GtkMenuItem *menuitem, gpointer user_data
const gchar *filename = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(file_select));
//Try to guess at an output
- GeglNode* first = gegl_node_get_nth_child(data->gegl, 0);
+ GeglNode* first = gegl_node_get_nth_child(g_queue_peek_head(data->graph_stack), 0);
GeglNode* last = getFinalNode(first);
g_print("Final node: %s\n", gegl_node_get_operation(last));
@@ -275,14 +463,14 @@ G_MODULE_EXPORT void activated_save(GtkMenuItem *menuitem, gpointer user_data)
G_MODULE_EXPORT void activated_delete(GtkMenuItem *menuitem, gpointer user_data)
{
CallbackData *data = user_data;
- graph_gtk_view_remove_selected_nodes(data->view);
+ graph_gtk_view_remove_selected_nodes(g_queue_peek_head(data->view_stack));
}
G_MODULE_EXPORT void activated_process_selected(GtkMenuItem *menuitem, gpointer user_data)
{
CallbackData *data = user_data;
- GeglNode *gegl = data->gegl;
- GraphGtkView *view = data->view;
+ GeglNode *gegl = g_queue_peek_head(data->graph_stack);
+ GraphGtkView *view = g_queue_peek_head(data->view_stack);
GList *nodes;
for(nodes = view->selected_nodes; nodes != NULL; nodes = nodes->next)
@@ -298,7 +486,7 @@ G_MODULE_EXPORT void activated_process_selected(GtkMenuItem *menuitem, gpointer
G_MODULE_EXPORT void activated_process_all(GtkMenuItem *menuitem, gpointer user_data)
{
CallbackData *data = user_data;
- GeglNode *gegl = data->gegl;
+ GeglNode *gegl = g_queue_peek_head(data->graph_stack);
GSList *nodes;
for(nodes = gegl_node_get_children(gegl); nodes != NULL; nodes = nodes->next)
@@ -367,9 +555,9 @@ G_MODULE_EXPORT void activated_add(GtkMenuItem *menuitem, gpointer user_data)
{
gchar* operation;
gtk_tree_model_get(model, &itr, 0, &operation, -1);
- GeglNode *node = gegl_node_create_child(data->gegl, operation);
+ GeglNode *node = gegl_node_create_child(g_queue_peek_head(data->graph_stack), operation);
- add_gegl_node_to_view(data->view, node);
+ add_gegl_node_to_view(g_queue_peek_head(data->view_stack), node);
}
}
@@ -380,38 +568,41 @@ static void update_bg_image(GraphGtkView *view)
{
if(view->selected_nodes)
{
- GeglNode *node = GEGL_NODE(GRAPH_GTK_NODE(view->selected_nodes->data)->user_data);
- g_print("%s\n", gegl_node_get_operation(node));
- const GeglRectangle roi = gegl_node_get_bounding_box(node);
- if(!gegl_rectangle_is_infinite_plane(&roi))
+ if(GEGL_IS_NODE(GRAPH_GTK_NODE(view->selected_nodes->data)->user_data))
{
- const Babl *cairo_argb32 = babl_format("cairo-ARGB32");
-
- gdouble scale = 1.0;//150.0/roi.width;
- GeglRectangle scaled;
- scaled.x = 0;
- scaled.y = 0;
- scaled.width = roi.width*scale;
- scaled.height = roi.height*scale;
-
- gint stride = cairo_format_stride_for_width(CAIRO_FORMAT_ARGB32, scaled.width);
- guchar* buf = (guchar*)malloc(stride*scaled.height);
-
- //make buffer in memory
- gegl_node_blit(node,
- scale,
- &scaled,
- cairo_argb32,
- buf,
- GEGL_AUTO_ROWSTRIDE,
- GEGL_BLIT_CACHE);
-
- cairo_surface_t* image =
- cairo_image_surface_create_for_data(buf, CAIRO_FORMAT_ARGB32,
- scaled.width, scaled.height,
- stride);
-
- graph_gtk_view_set_bg(view, image);
+ GeglNode *node = GEGL_NODE(GRAPH_GTK_NODE(view->selected_nodes->data)->user_data);
+ g_print("%s\n", gegl_node_get_operation(node));
+ const GeglRectangle roi = gegl_node_get_bounding_box(node);
+ if(!gegl_rectangle_is_infinite_plane(&roi))
+ {
+ const Babl *cairo_argb32 = babl_format("cairo-ARGB32");
+
+ gdouble scale = 1.0;//150.0/roi.width;
+ GeglRectangle scaled;
+ scaled.x = 0;
+ scaled.y = 0;
+ scaled.width = roi.width*scale;
+ scaled.height = roi.height*scale;
+
+ gint stride = cairo_format_stride_for_width(CAIRO_FORMAT_ARGB32, scaled.width);
+ guchar* buf = (guchar*)malloc(stride*scaled.height);
+
+ //make buffer in memory
+ gegl_node_blit(node,
+ scale,
+ &scaled,
+ cairo_argb32,
+ buf,
+ GEGL_AUTO_ROWSTRIDE,
+ GEGL_BLIT_CACHE);
+
+ cairo_surface_t* image =
+ cairo_image_surface_create_for_data(buf, CAIRO_FORMAT_ARGB32,
+ scaled.width, scaled.height,
+ stride);
+
+ graph_gtk_view_set_bg(view, image);
+ }
}
}
}
@@ -425,7 +616,7 @@ static void update_images(GraphGtkView *view)
{
view_node = GRAPH_GTK_NODE(list->data);
- if(view_node->show_image)
+ if(view_node->show_image && GEGL_IS_NODE(view_node->user_data))
{
if(view_node->image)
cairo_surface_destroy(view_node->image);
@@ -492,3 +683,46 @@ add_gegl_node_to_view(GraphGtkView *view, GeglNode *node)
return view_node;
}
+
+static void load_graph(GraphGtkView *view, GeglNode *gegl)
+{
+ GHashTable *hash_table = g_hash_table_new(g_direct_hash, g_direct_equal);
+
+ 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));
+ GraphGtkNode *view_node = add_gegl_node_to_view(view, node);
+ g_hash_table_insert(hash_table, node, view_node);
+ }
+
+ for(list = gegl_node_get_children(gegl); list != NULL; list = list->next)
+ {
+ GeglNode* node = GEGL_NODE(list->data);
+
+ GraphGtkNode *from = g_hash_table_lookup(hash_table, node);
+
+ if(!from)
+ break;
+
+ if(!gegl_node_has_pad(node, "output"))
+ break;
+
+ GeglNode** nodes;
+ const gchar** pads;
+ gint num = gegl_node_get_consumers(node, "output", &nodes, &pads);
+
+ int i;
+ for(i = 0; i < num; i++)
+ {
+ GraphGtkNode *to = g_hash_table_lookup(hash_table, nodes[i]);
+ if(!to)
+ break;
+
+ graph_gtk_node_connect_to(from, "output", to, pads[i]);
+ }
+ }
+
+ g_hash_table_destroy(hash_table);
+}
diff --git a/gegl-edit/gegl-gtk-property-view.c b/gegl-edit/gegl-gtk-property-view.c
index a7fc3b4..a019a3b 100644
--- a/gegl-edit/gegl-gtk-property-view.c
+++ b/gegl-edit/gegl-gtk-property-view.c
@@ -201,7 +201,7 @@ rebuild_contents(GeglGtkPropertyView *self)
gtk_container_remove(GTK_CONTAINER(self), GTK_WIDGET(child->data));
}
- if(node)
+ if(node && gegl_node_get_operation(node))
{
guint n_props;
GParamSpec** properties = gegl_operation_list_properties(gegl_node_get_operation(node), &n_props);
diff --git a/gegl-edit/gresource.xml b/gegl-edit/gresource.xml
index 6bcaef6..5e7e45e 100644
--- a/gegl-edit/gresource.xml
+++ b/gegl-edit/gresource.xml
@@ -2,5 +2,7 @@
<gresources>
<gresource prefix="/gegl-edit/">
<file preprocess="xml-stripblanks">menubar.ui</file>
+ <file preprocess="xml-stripblanks">contextmenu.ui</file>
+ <file preprocess="xml-stripblanks">contextmenu_canvas.ui</file>
</gresource>
</gresources>
diff --git a/gegl-edit/menubar.ui b/gegl-edit/menubar.ui
index 14853ed..8976574 100644
--- a/gegl-edit/menubar.ui
+++ b/gegl-edit/menubar.ui
@@ -1,17 +1,17 @@
<?xml version="1.0" encoding="UTF-8"?>
<interface>
<!-- interface-requires gtk+ 3.0 -->
- <object class="GtkImage" id="image1">
+ <object class="GtkImage" id="image2">
<property name="visible">True</property>
<property name="can_focus">False</property>
- <property name="xalign">0.4699999988079071</property>
+ <property name="xalign">0.49000000953674316</property>
+ <property name="yalign">0.41999998688697815</property>
<property name="stock">gtk-add</property>
</object>
- <object class="GtkImage" id="image2">
+ <object class="GtkImage" id="image1">
<property name="visible">True</property>
<property name="can_focus">False</property>
- <property name="xalign">0.49000000953674316</property>
- <property name="yalign">0.41999998688697815</property>
+ <property name="xalign">0.4699999988079071</property>
<property name="stock">gtk-add</property>
</object>
<object class="GtkImage" id="image3">
@@ -42,6 +42,11 @@
<property name="yalign">0.49000000953674316</property>
<property name="stock">gtk-yes</property>
</object>
+ <object class="GtkImage" id="image8">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="stock">gtk-add</property>
+ </object>
<object class="GtkMenuBar" id="menu_bar">
<property name="visible">True</property>
<property name="can_focus">False</property>
@@ -146,6 +151,17 @@
</object>
</child>
<child>
+ <object class="GtkImageMenuItem" id="add subgraph">
+ <property name="label" translatable="yes">Add Subgraph</property>
+ <property name="use_action_appearance">False</property>
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="image">image8</property>
+ <property name="use_stock">False</property>
+ <signal name="activate" handler="activated_add_subgraph" swapped="no"/>
+ </object>
+ </child>
+ <child>
<object class="GtkImageMenuItem" id="delete">
<property name="label" translatable="yes">Delete</property>
<property name="use_action_appearance">False</property>
@@ -170,30 +186,32 @@
<property name="use_action_appearance">False</property>
<property name="visible">True</property>
<property name="can_focus">False</property>
- <property name="label" translatable="yes">Meta-op</property>
+ <property name="label" translatable="yes">Graph</property>
<property name="use_underline">True</property>
<child type="submenu">
<object class="GtkMenu" id="menu3">
<property name="visible">True</property>
<property name="can_focus">False</property>
<child>
- <object class="GtkImageMenuItem" id="imagemenuitem3">
+ <object class="GtkImageMenuItem" id="add input">
<property name="label" translatable="yes">Add Input</property>
<property name="use_action_appearance">False</property>
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="image">image1</property>
<property name="use_stock">False</property>
+ <signal name="activate" handler="activated_add_input" swapped="no"/>
</object>
</child>
<child>
- <object class="GtkImageMenuItem" id="imagemenuitem4">
+ <object class="GtkImageMenuItem" id="add output">
<property name="label" translatable="yes">Add Output</property>
<property name="use_action_appearance">False</property>
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="image">image2</property>
<property name="use_stock">False</property>
+ <signal name="activate" handler="activated_add_output" swapped="no"/>
</object>
</child>
<child>
@@ -204,6 +222,7 @@
<property name="can_focus">False</property>
<property name="image">image3</property>
<property name="use_stock">False</property>
+ <signal name="activate" handler="activated_metaop_properties" swapped="no"/>
</object>
</child>
</object>
@@ -219,7 +238,7 @@
<property name="use_action_appearance">False</property>
<property name="visible">True</property>
<property name="can_focus">False</property>
- <property name="label" translatable="yes">_Graph</property>
+ <property name="label" translatable="yes">_Gegl</property>
<property name="use_underline">True</property>
<child type="submenu">
<object class="GtkMenu" id="menu4">
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]