[gegl-edit] Work towards meta-op property proxies
- From: Isaac Wagner <isaacbw src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gegl-edit] Work towards meta-op property proxies
- Date: Wed, 8 Aug 2012 19:36:01 +0000 (UTC)
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]