[gegl-edit] Work towards meta-op property proxies



commit 6ad0126488c0608ca96f235b6fc0c3ee6951d5fe
Author: Isaac Wagner <isaacbw src gnome org>
Date:   Wed Aug 8 15:35:53 2012 -0400

    Work towards meta-op property proxies

 gegl-edit/gegl-edit.c              |   47 +++++---
 gegl-edit/gegl-gtk-property-view.c |  247 ++++++++++++++++++++++++++---------
 2 files changed, 214 insertions(+), 80 deletions(-)
---
diff --git a/gegl-edit/gegl-edit.c b/gegl-edit/gegl-edit.c
index 96e8a1b..50accf7 100644
--- a/gegl-edit/gegl-edit.c
+++ b/gegl-edit/gegl-edit.c
@@ -8,6 +8,19 @@
 
 #include "resources.h"
 
+typedef struct CallbackData
+{
+  GtkWidget	*window;
+  GraphGtkNode	*context;
+  GQueue	*graph_stack;
+  GQueue	*view_stack;
+  GtkWidget	*view_box;
+  GtkWidget	*property_view;
+  GtkMenu       *popup;
+  GtkMenu       *popup2;
+} CallbackData;
+
+static const gchar* query_proxy(GeglGtkPropertyView *view, GeglNode *node, const gchar *property, CallbackData* data);
 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);
@@ -23,22 +36,11 @@ 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);
+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;
-  GraphGtkNode	*context;
-  GQueue	*graph_stack;
-  GQueue	*view_stack;
-  GtkWidget	*view_box;
-  GtkWidget	*property_view;
-  GtkMenu       *popup;
-  GtkMenu       *popup2;
-} CallbackData;
 
 static void
 add_ui_to_builder(GResource *resource, GtkBuilder *builder, const gchar* resource_name, CallbackData *data)
@@ -79,6 +81,7 @@ main (gint	  argc,
   data->property_view = GTK_WIDGET(props);
 
   g_signal_connect(props, "property-changed", G_CALLBACK(property_changed), view);
+  g_signal_connect(props, "query-proxy", G_CALLBACK(query_proxy), data);
 
   g_signal_connect(view, "canvas-rightclicked", G_CALLBACK(canvas_rightclicked), data);
   g_signal_connect(view, "node-selected", G_CALLBACK(node_selected), data);
@@ -129,6 +132,17 @@ main (gint	  argc,
 }
 
 ////////GraphGtk callbacks////////
+static const gchar* query_proxy(GeglGtkPropertyView *view, GeglNode *node, const gchar *property, CallbackData* data)
+{
+  /*  GeglNode *graph = g_queue_peek_head(data->graph_stack);
+  if(GEGL_IS_OPERATION_META(node->operation))
+    {
+      return "meta";
+      }*/
+  //return "property1";
+  return NULL;
+}
+
 static void
 canvas_rightclicked(GraphGtkView *view, gpointer user_data)
 {
@@ -616,7 +630,8 @@ static void update_bg_image(GraphGtkView *view)
 	  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))
+	  gegl_rectangle_dump(&roi);
+	  if(!gegl_rectangle_is_infinite_plane(&roi) && roi.width > 0 && roi.height > 0)
 	    {
 	      const Babl *cairo_argb32 = babl_format("cairo-ARGB32");
 
diff --git a/gegl-edit/gegl-gtk-property-view.c b/gegl-edit/gegl-gtk-property-view.c
index a019a3b..8b5806a 100644
--- a/gegl-edit/gegl-gtk-property-view.c
+++ b/gegl-edit/gegl-gtk-property-view.c
@@ -83,6 +83,34 @@ gegl_gtk_property_view_class_init (GeglGtkPropertyViewClass *klass)
 	       NULL,
 	       G_TYPE_NONE,
 	       0);
+
+  g_signal_new("proxy-changed",
+	       GEGL_GTK_TYPE_PROPERTY_VIEW,
+	       G_SIGNAL_RUN_FIRST,
+	       0, //no class method
+	       NULL, //no accumulator,
+	       NULL,
+	       NULL,
+	       G_TYPE_NONE,
+	       3,
+	       GEGL_TYPE_NODE,
+	       G_TYPE_STRING,
+	       G_TYPE_STRING,
+	       G_TYPE_BOOLEAN); //node, property name, proxy text
+
+  g_signal_new("query-proxy",
+	       GEGL_GTK_TYPE_PROPERTY_VIEW,
+	       G_SIGNAL_RUN_LAST,
+	       0, //no class method
+	       NULL, //no accumulator,
+	       NULL,
+	       NULL,
+	       G_TYPE_STRING,
+	       2,
+	       GEGL_TYPE_NODE,
+	       G_TYPE_STRING);
+  //should connect to this and return a) the name of the parent property to which this property is connected
+  //or b) NULL which means the property is not a connected to by a proxy
 }
 
 static void
@@ -134,6 +162,7 @@ typedef struct _propertycallbackdata
   GType prop_gtype;
   const gchar* prop_name;
   GeglGtkPropertyView *props;
+  GtkWidget *value_box;
 } PropertyCallbackData;
 
 static
@@ -190,6 +219,133 @@ void property_changed(GtkWidget *widget, gpointer user_data)
 }
 
 static
+void proxy_changed(GtkWidget *widget, gpointer user_data)
+{
+  PropertyCallbackData *data = user_data;
+
+  const gchar *text = gtk_entry_get_text(GTK_ENTRY(widget));
+
+  g_signal_emit_by_name(data->props, "proxy-changed", data->node, data->prop_name, text);
+}
+
+static gboolean
+make_value_entry(GtkWidget *value_box, GType type, const gchar *name, GeglNode *node, int *d, PropertyCallbackData *data);
+
+static void
+proxy_checkbox_toggled (GtkToggleButton *togglebutton, PropertyCallbackData *data)
+{
+  gboolean active = gtk_toggle_button_get_active(togglebutton);
+  if(active) {
+    /*GtkWidget *combo = gtk_combo_new();
+      GList *choices = NULL;
+      choices = g_list_append(choices, "property1");
+      choices = g_list_append(choices, "property2");
+      choices = g_list_append(choices, "property3");
+
+      gtk_combo_set_popdown_strings(GTK_COMBO(combo), choices);
+      
+      GList *list;
+      if(list = gtk_container_get_children(GTK_CONTAINER(data->value_box)))
+	gtk_container_remove(GTK_CONTAINER(data->value_box), GTK_WIDGET(list->data));
+
+      gtk_box_pack_start(GTK_BOX(data->value_box), combo, TRUE, TRUE, 0);
+      gtk_widget_show(combo);*/
+
+    GList *list;
+    if(list = gtk_container_get_children(GTK_CONTAINER(data->value_box)))
+      gtk_container_remove(GTK_CONTAINER(data->value_box), GTK_WIDGET(list->data));
+
+    GtkWidget*	value_entry = gtk_entry_new();
+    gtk_entry_set_width_chars(GTK_ENTRY(value_entry), 2);
+    g_signal_connect(value_entry, "activate", G_CALLBACK(proxy_changed), data);
+    gtk_box_pack_start(GTK_BOX(data->value_box), value_entry, TRUE, TRUE, 0);
+    gtk_widget_show(value_entry);
+  }
+  else {
+    GList *list;
+    if(list = gtk_container_get_children(GTK_CONTAINER(data->value_box)))
+      gtk_container_remove(GTK_CONTAINER(data->value_box), GTK_WIDGET(list->data));
+    make_value_entry(data->value_box, data->prop_gtype, data->prop_name, data->node, NULL, data);
+    gtk_widget_show_all(data->value_box);
+  }
+}
+
+static gboolean
+make_value_entry(GtkWidget *value_box, GType type, const gchar *name, GeglNode *node, int *d, PropertyCallbackData *data)
+{
+  GtkWidget*	value_entry = gtk_entry_new();
+
+  gchar buf[256] = "*";	//can probably be smaller; In fact, can probably do this without sprintf and a buffer. TODO: look at g_string
+
+  gint		i_value;
+  gdouble	d_value;
+  gchar*	str_value;
+  gboolean	skip = FALSE; //skip adding a generic text box in the case of special buttons for things like colors and filepaths
+
+  switch(type)
+    {
+    case G_TYPE_INT:
+      gegl_node_get(node, name, &i_value, NULL);
+      sprintf(buf, "%d", i_value);
+      break;
+    case G_TYPE_DOUBLE:
+      gegl_node_get(node, name, &d_value, NULL);
+      sprintf(buf, "%.3f", d_value);
+      break;
+    case G_TYPE_STRING:
+      gegl_node_get(node, name, &str_value, NULL);
+      sprintf(buf, "%s", str_value);
+      break;
+    }
+
+  if(type == GEGL_TYPE_BUFFER) {
+    if(d)
+      *d--;
+    return FALSE;
+  } else if( type == GEGL_TYPE_COLOR) {
+    skip = TRUE;
+    GtkWidget *color_button = gtk_color_button_new();//..._with_color(...);
+
+    GeglColor* color;// = gegl_color_new(NULL);
+
+    gegl_node_get(node, name, &color, NULL);
+
+    gdouble r, g, b, a;
+    gegl_color_get_rgba(color, &r, &g, &b, &a);
+
+    GdkColor gdk_color;
+    gdk_color.red = r*65535;
+    gdk_color.green = g*65535;
+    gdk_color.blue = b*65535;
+
+    gtk_color_button_set_color(GTK_COLOR_BUTTON(color_button), &gdk_color);
+
+    g_signal_connect(color_button, "color-set", (GCallback)property_changed, data);
+    gtk_box_pack_start(GTK_BOX(value_box), color_button, TRUE, TRUE, 0);
+	    
+  } else if (!strcmp(name, "path")) { //create a special file browser for this property
+    skip = TRUE;
+    GtkWidget *file_button = gtk_file_chooser_button_new("Select File", GTK_FILE_CHOOSER_ACTION_OPEN);
+
+    g_signal_connect(file_button, "file-set", (GCallback)property_changed, data);
+    gtk_box_pack_start(GTK_BOX(value_box), file_button, TRUE, TRUE, 0);
+  }
+
+  if(!skip)
+    {
+      gtk_entry_set_text(GTK_ENTRY(value_entry), buf);
+
+      gtk_entry_set_width_chars(GTK_ENTRY(value_entry), 2);
+
+      g_signal_connect(value_entry, "activate", G_CALLBACK(property_changed), data);
+
+      gtk_box_pack_start(GTK_BOX(value_box), value_entry, TRUE, TRUE, 0);
+    }
+
+  return TRUE;
+}
+
+static
 rebuild_contents(GeglGtkPropertyView *self)
 {
   GeglNode *node = self->node;
@@ -207,7 +363,7 @@ rebuild_contents(GeglGtkPropertyView *self)
       GParamSpec**	properties = gegl_operation_list_properties(gegl_node_get_operation(node), &n_props);
 
       //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));
+      GtkTable	*prop_table = GTK_TABLE(gtk_table_new(3, n_props, FALSE));
       gtk_box_pack_start(GTK_BOX(self), GTK_WIDGET(prop_table), TRUE, TRUE, 0);
 
       int d, i;
@@ -220,81 +376,44 @@ rebuild_contents(GeglGtkPropertyView *self)
 	  GtkWidget* name_label = gtk_label_new(name);
 	  gtk_misc_set_alignment(GTK_MISC(name_label), 0, 0.5);
 
+	  GtkWidget *value_box = gtk_vbox_new(TRUE, 0);
+
 	  PropertyCallbackData *data = g_new(PropertyCallbackData, 1);
 	  data->node = node;
 	  data->prop_name = name;
 	  data->prop_gtype = type;
 	  data->props = self;
+	  data->value_box = value_box;
 
-	  GtkWidget*	value_entry = gtk_entry_new();
+	  const gchar *proxy = NULL;
+	  g_signal_emit_by_name(self, "query-proxy", node, name, &proxy);
 
-	  gchar buf[256] = "*";	//can probably be smaller; In fact, can probably do this without sprintf and a buffer. TODO: look at g_string
-
-	  gint	i_value;
-	  gdouble	d_value;
-	  gchar*	str_value;
-	  gboolean skip = FALSE;
-
-	  switch(type)
-	    {
-	    case G_TYPE_INT:
-	      gegl_node_get(node, name, &i_value, NULL);
-	      sprintf(buf, "%d", i_value);
-	      break;
-	    case G_TYPE_DOUBLE:
-	      gegl_node_get(node, name, &d_value, NULL);
-	      sprintf(buf, "%.3f", d_value);
-	      break;
-	    case G_TYPE_STRING:
-	      gegl_node_get(node, name, &str_value, NULL);
-	      sprintf(buf, "%s", str_value);
-	      break;
-	    }
-
-	  if(type == GEGL_TYPE_BUFFER) {
-	    skip = TRUE;
-	    d--;
-	  } else if( type == GEGL_TYPE_COLOR) {
-	    skip = TRUE;
-	    GtkWidget *color_button = gtk_color_button_new();//..._with_color(...);
-
-	    GeglColor* color;// = gegl_color_new(NULL);
-
-	    gegl_node_get(node, name, &color, NULL);
-
-	    gdouble r, g, b, a;
-	    gegl_color_get_rgba(color, &r, &g, &b, &a);
-
-	    GdkColor gdk_color;
-	    gdk_color.red = r*65535;
-	    gdk_color.green = g*65535;
-	    gdk_color.blue = b*65535;
-
-	    gtk_color_button_set_color(GTK_COLOR_BUTTON(color_button), &gdk_color);
-
-	    g_signal_connect(color_button, "color-set", (GCallback)property_changed, data);
-
-	    gtk_table_attach(prop_table, name_label, 0, 1, d, d+1, GTK_FILL, GTK_FILL, 1, 1);
-	    gtk_table_attach(prop_table, color_button, 1, 2, d, d+1, GTK_EXPAND | GTK_FILL | GTK_SHRINK, GTK_FILL, 1, 1);
-	  } else if (!strcmp(name, "path")) { //create a special file browser for this property
-	    skip = TRUE;
-	    GtkWidget *file_button = gtk_file_chooser_button_new("Select File", GTK_FILE_CHOOSER_ACTION_OPEN);
-
-	    g_signal_connect(file_button, "file-set", (GCallback)property_changed, data);
-	    gtk_table_attach(prop_table, name_label, 0, 1, d, d+1, GTK_FILL, GTK_FILL, 1, 1);
-	    gtk_table_attach(prop_table, file_button, 1, 2, d, d+1, GTK_EXPAND | GTK_FILL | GTK_SHRINK, GTK_FILL, 1, 1);
-	  }
-
-	  if(!skip)
+	  if(proxy)
 	    {
-	      gtk_entry_set_text(GTK_ENTRY(value_entry), buf);
-
+	      GtkWidget* value_entry = gtk_entry_new();
+	      GString *str = g_string_new("<");
+	      str = g_string_append(str, proxy);
+	      str = g_string_append(str, ">");
+	      gtk_entry_set_text(GTK_ENTRY(value_entry), str->str);
 	      gtk_entry_set_width_chars(GTK_ENTRY(value_entry), 2);
+	      g_signal_connect(value_entry, "activate", G_CALLBACK(proxy_changed), data);
+	      gtk_box_pack_start(GTK_BOX(value_box), value_entry, TRUE, TRUE, 0);
 
-	      g_signal_connect(value_entry, "activate", G_CALLBACK(property_changed), data);
+	      gtk_table_attach(prop_table, name_label, 0, 1, d, d+1, GTK_FILL, GTK_FILL, 1, 1);
+	      gtk_table_attach(prop_table, value_box, 1, 2, d, d+1, GTK_EXPAND | GTK_FILL | GTK_SHRINK, GTK_FILL, 1, 1);
 
+	      /*GtkWidget *check = gtk_check_button_new();
+	      gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(check), TRUE);
+	      gtk_table_attach(prop_table, check, 2, 3, d, d+1, GTK_FILL, GTK_FILL, 1, 1);
+	      g_signal_connect(check, "toggled", (GCallback)proxy_checkbox_toggled, data);*/
+	    }
+	  else if(make_value_entry(value_box, type, name, node, &d, data))
+	    {
 	      gtk_table_attach(prop_table, name_label, 0, 1, d, d+1, GTK_FILL, GTK_FILL, 1, 1);
-	      gtk_table_attach(prop_table, value_entry, 1, 2, d, d+1, GTK_EXPAND | GTK_FILL | GTK_SHRINK, GTK_FILL, 1, 1);
+	      gtk_table_attach(prop_table, value_box, 1, 2, d, d+1, GTK_EXPAND | GTK_FILL | GTK_SHRINK, GTK_FILL, 1, 1);
+	      /*GtkWidget *check = gtk_check_button_new();
+	      gtk_table_attach(prop_table, check, 2, 3, d, d+1, GTK_FILL, GTK_FILL, 1, 1);
+	      g_signal_connect(check, "toggled", (GCallback)proxy_checkbox_toggled, data);*/
 	    }
 	}
   



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