this is a major update which adds a tree view of the pipeline and lets you set individual element args through a dyna...

Original commit message from CVS:
this is a major update which adds a tree view of the pipeline and lets you set individual element args through a dynamically generated gui.  If you haven't tried this tool yet then try it now. The next step will be to add gui generation for dynamic params as well. Please email feedback and bug reports to the list
This commit is contained in:
Steve Baker 2001-10-23 17:43:49 +00:00
parent 5e85a8eb03
commit 799b712338

View file

@ -13,6 +13,7 @@
GtkWidget *start_but, *pause_but, *parse_but, *status;
GtkWidget *window;
GtkWidget *prop_box, *dparam_box;
GstElement *pipeline;
typedef void (*found_handler) (GstElement *element, gint xid, void *priv);
@ -33,7 +34,7 @@ load_history(GtkWidget *pipe_combo)
int history_fd;
struct stat statbuf;
gchar *map, *current, *next, *entry;
gchar *map, *current, *next, *entry, *last_entry = "";
gchar *history_filename;
gint num_entries = 0, entries_limit = 50;
GList *history = NULL;
@ -62,10 +63,17 @@ load_history(GtkWidget *pipe_combo)
while (current){
if ((next = strstr(current, "\n"))){
// show entries_limit of the newest entries
if (num_entries-- < entries_limit){
entry = g_strndup(current, next - current);
history = g_list_prepend(history, entry);
entry = g_strndup(current, next - current);
if ((strlen(entry) == strlen(last_entry)) && strstr(entry, last_entry)){
g_free(entry);
}
else{
// show entries_limit of the newest entries
if (num_entries-- < entries_limit){
entry = g_strndup(current, next - current);
last_entry = entry;
history = g_list_prepend(history, entry);
}
}
current = next + 1;
}
@ -121,7 +129,7 @@ build_debug_page(GtkWidget *notebook)
debug_box = gtk_vbox_new(TRUE, 0);
debug_buts = gtk_hbox_new(TRUE, 0);
gtk_box_pack_start(GTK_BOX(debug_box),debug_buts,TRUE,TRUE,0);
gtk_box_pack_start(GTK_BOX(debug_box),debug_buts,FALSE,FALSE,0);
gtk_scrolled_window_add_with_viewport(GTK_SCROLLED_WINDOW(scrolled), debug_box);
gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrolled), GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC);
@ -221,19 +229,294 @@ xid_handler (GstElement *element, gint xid, void *priv)
gtk_object_set_data(GTK_OBJECT(element), "gtk_socket", gtk_socket);
}
void
prop_change_callback(GtkWidget *widget, GstElement *element)
{
gchar *prop_name = gtk_object_get_data(GTK_OBJECT(widget), "prop_name");
GType prop_type = GPOINTER_TO_INT(gtk_object_get_data(GTK_OBJECT(widget), "prop_type"));
GValue *value = g_new0(GValue,1);
g_value_init (value, prop_type);
g_print("prop %s changed in %s\n", prop_name, gst_element_get_name(element));
switch (prop_type) {
case G_TYPE_STRING:
g_print("setting string\n");
g_object_set(G_OBJECT(element),prop_name,gtk_entry_get_text(GTK_ENTRY(widget)), NULL);
g_object_get_property(G_OBJECT(element),prop_name,value);
gtk_entry_set_text(GTK_ENTRY(widget), g_value_get_string(value));
break;
case G_TYPE_BOOLEAN:
g_print("setting bool\n");
g_object_set(G_OBJECT(element),prop_name,gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON(widget)), NULL);
g_object_get_property(G_OBJECT(element),prop_name,value);
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON(widget), g_value_get_boolean(value));
break;
case G_TYPE_ULONG:
g_print("setting ulong\n");
g_object_set(G_OBJECT(element),prop_name,(gulong)(GTK_ADJUSTMENT(widget)->value), NULL);
g_object_get_property(G_OBJECT(element),prop_name,value);
gtk_adjustment_set_value(GTK_ADJUSTMENT(widget), (gfloat)g_value_get_ulong(value));
break;
case G_TYPE_LONG:
g_print("setting long\n");
g_object_set(G_OBJECT(element),prop_name,(glong)(GTK_ADJUSTMENT(widget)->value), NULL);
g_object_get_property(G_OBJECT(element),prop_name,value);
gtk_adjustment_set_value(GTK_ADJUSTMENT(widget), (gfloat)g_value_get_long(value));
break;
case G_TYPE_UINT:
g_print("setting uint\n");
g_object_set(G_OBJECT(element),prop_name,(guint)(GTK_ADJUSTMENT(widget)->value), NULL);
g_object_get_property(G_OBJECT(element),prop_name,value);
gtk_adjustment_set_value(GTK_ADJUSTMENT(widget), (gfloat)g_value_get_uint(value));
break;
case G_TYPE_INT:
g_print("setting int\n");
g_object_set(G_OBJECT(element),prop_name,(gint)(GTK_ADJUSTMENT(widget)->value), NULL);
g_object_get_property(G_OBJECT(element),prop_name,value);
gtk_adjustment_set_value(GTK_ADJUSTMENT(widget), (gfloat)g_value_get_int(value));
break;
case G_TYPE_FLOAT:
g_print("setting float\n");
g_object_set(G_OBJECT(element),prop_name,(GTK_ADJUSTMENT(widget)->value), NULL);
g_object_get_property(G_OBJECT(element),prop_name,value);
gtk_adjustment_set_value(GTK_ADJUSTMENT(widget), g_value_get_float(value));
break;
case G_TYPE_DOUBLE:
g_print("setting double\n");
g_object_set(G_OBJECT(element),prop_name,(gdouble)(GTK_ADJUSTMENT(widget)->value), NULL);
g_object_get_property(G_OBJECT(element),prop_name,value);
gtk_adjustment_set_value(GTK_ADJUSTMENT(widget), (gfloat)g_value_get_double(value));
break;
case G_TYPE_ENUM:{
GtkWidget *menu_item = gtk_menu_get_active(GTK_MENU(widget));
g_print("setting enum\n");
g_object_set(G_OBJECT(element),prop_name,
GPOINTER_TO_INT(gtk_object_get_data(GTK_OBJECT(menu_item), "enum_val")),
NULL);
}
break;
default:
break;
}
g_free(value);
}
void
build_props_box(GstElement *element)
{
GParamSpec **property_specs;
GValue *value;
gint num_properties,i;
GtkWidget *prop_table;
GtkWidget *prop_label, *prop_align;
GtkWidget *prop_attach_widget;
GtkObject *prop_object;
const gchar *element_name, *prop_name, *short_name;
element_name = gst_element_get_name(element);
property_specs = g_object_class_list_properties(G_OBJECT_GET_CLASS (element), &num_properties);
prop_table = gtk_table_new(num_properties, 2, FALSE);
gtk_box_pack_start(GTK_BOX(prop_box),prop_table,FALSE,FALSE,0);
for (i=0;i<num_properties;i++) {
gchar *signal_name = "";
value = g_new0(GValue,1);
g_value_init (value, property_specs[i]->value_type);
prop_name = property_specs[i]->name;
if (strstr(prop_name, "::")){
short_name = strstr(prop_name, "::") + 2;
}
else {
short_name = prop_name;
}
prop_label = gtk_label_new(short_name);
g_object_get_property(G_OBJECT(element),prop_name,value);
prop_align = gtk_alignment_new(1, 0, 0, 0);
gtk_container_add(GTK_CONTAINER(prop_align), prop_label);
gtk_table_attach(GTK_TABLE(prop_table), prop_align, 0, 1, i, i+1, GTK_FILL, GTK_SHRINK, 5, 3);
prop_object = NULL;
prop_attach_widget = NULL;
switch (G_VALUE_TYPE (value)) {
case G_TYPE_STRING:
g_print("got string %s for %s\n", prop_name, element_name);
prop_object = GTK_OBJECT(gtk_entry_new());
if (g_value_get_string(value)){
gtk_entry_set_text(GTK_ENTRY(prop_object), g_value_get_string(value));
}
signal_name = "activate";
prop_attach_widget = GTK_WIDGET(prop_object);
break;
case G_TYPE_BOOLEAN:
g_print("got bool %s for %s\n", prop_name, element_name);
prop_object = GTK_OBJECT(gtk_check_button_new());
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON(prop_object), g_value_get_boolean(value));
signal_name = "toggled";
prop_attach_widget = GTK_WIDGET(prop_object);
break;
case G_TYPE_ULONG:
g_print("got ulong %s for %s\n", prop_name, element_name);
prop_object = gtk_adjustment_new(g_value_get_ulong(value), 0, (gfloat)G_MAXLONG * 2.0, 1, 10, 10);
signal_name = "value-changed";
prop_attach_widget = gtk_spin_button_new(GTK_ADJUSTMENT(prop_object), 1, 0);
break;
case G_TYPE_LONG:
g_print("got long %s for %s\n", prop_name, element_name);
prop_object = gtk_adjustment_new(g_value_get_long(value), G_MINLONG, G_MAXLONG, 1, 10, 10);
signal_name = "value-changed";
prop_attach_widget = gtk_spin_button_new(GTK_ADJUSTMENT(prop_object), 1, 0);
break;
case G_TYPE_UINT:
g_print("got uint %s for %s\n", prop_name, element_name);
prop_object = gtk_adjustment_new(g_value_get_uint(value), 0, (gfloat)G_MAXINT * 2.0, 1, 10, 10);
prop_attach_widget = gtk_spin_button_new(GTK_ADJUSTMENT(prop_object), 1, 0);
signal_name = "value-changed";
break;
case G_TYPE_INT:
g_print("got int %s for %s\n", prop_name, element_name);
prop_object = gtk_adjustment_new(g_value_get_int(value), G_MININT, G_MAXINT, 1, 10, 10);
prop_attach_widget = gtk_spin_button_new(GTK_ADJUSTMENT(prop_object), 1, 0);
signal_name = "value-changed";
break;
case G_TYPE_FLOAT:
g_print("got float %s for %s\n", prop_name, element_name);
prop_object = gtk_adjustment_new(g_value_get_float(value), G_MINFLOAT, G_MAXFLOAT, 1, 10, 10);
prop_attach_widget = gtk_spin_button_new(GTK_ADJUSTMENT(prop_object), 1, 3);
signal_name = "value-changed";
break;
case G_TYPE_DOUBLE:
g_print("got double %s for %s\n", prop_name, element_name);
prop_object = gtk_adjustment_new(g_value_get_double(value), G_MINDOUBLE, G_MAXDOUBLE, 1, 10, 10);
prop_attach_widget = gtk_spin_button_new(GTK_ADJUSTMENT(prop_object), 1, 3);
signal_name = "value-changed";
break;
default:
if (G_IS_PARAM_SPEC_ENUM (property_specs[i])) {
GEnumValue *values;
guint j = 0;
g_print("got enum %s for %s\n", prop_name, element_name);
g_value_init (value, G_TYPE_ENUM);
prop_attach_widget = gtk_option_menu_new();
prop_object = GTK_OBJECT(gtk_menu_new());
gtk_option_menu_set_menu(GTK_OPTION_MENU(prop_attach_widget), GTK_WIDGET(prop_object));
signal_name = "selection-done";
//FIXME when the shim is dead
values = gtk_type_enum_get_values (property_specs[i]->value_type);
while (values[j].value_name) {
GtkWidget *menu_item;
menu_item = gtk_menu_item_new_with_label(values[j].value_nick);
gtk_menu_append(GTK_MENU(prop_object), menu_item);
gtk_object_set_data(GTK_OBJECT(menu_item), "enum_val", GINT_TO_POINTER(values[j].value));
if (values[j].value == g_value_get_enum(value)){
gtk_menu_shell_select_item(GTK_MENU_SHELL(prop_object), menu_item);
gtk_menu_shell_activate_item(GTK_MENU_SHELL(prop_object), menu_item, FALSE);
}
j++;
}
}
break;
}
if (prop_attach_widget){
gtk_table_attach_defaults(GTK_TABLE(prop_table), prop_attach_widget, 1, 2, i, i+1);
gtk_widget_show(prop_attach_widget);
}
if (property_specs[i]->flags & G_PARAM_WRITABLE){
if (prop_object){
gtk_signal_connect (prop_object, signal_name,
GTK_SIGNAL_FUNC (prop_change_callback), element);
gtk_object_set_data(prop_object, "prop_name", g_strdup(short_name));
gtk_object_set_data(prop_object, "prop_type", GINT_TO_POINTER(G_VALUE_TYPE (value)));
}
}
else {
gtk_widget_set_sensitive(GTK_WIDGET(prop_attach_widget), FALSE);
}
g_free(value);
gtk_widget_show_all(prop_table);
}
}
void
select_child_callback(GtkWidget *tree_item, GstElement *element)
{
build_props_box(element);
}
void
clear_edit_panes(GtkWidget *widget, gpointer *data)
{
GList *children;
children = gtk_container_children(GTK_CONTAINER(prop_box));
while (children){
gtk_container_remove(GTK_CONTAINER(prop_box), GTK_WIDGET(children->data));
children = g_list_next (children);
}
/*
children = gtk_container_children(GTK_CONTAINER(dparam_box));
while (children){
gtk_container_remove(GTK_CONTAINER(prop_box), GTK_WIDGET(children->data));
children = g_list_next (children);
}
*/
}
void
build_tree(GtkWidget *tree_item, GstBin *bin){
GList *children;
GtkWidget *tree, *item;
if (GTK_TREE_ITEM_SUBTREE(tree_item) != NULL){
gtk_tree_item_remove_subtree(GTK_TREE_ITEM(tree_item));
}
tree = gtk_tree_new();
gtk_tree_item_set_subtree(GTK_TREE_ITEM(tree_item), tree);
gtk_widget_show(tree);
children = gst_bin_get_list(bin);
while (children) {
GstElement *child;
child = GST_ELEMENT (children->data);
children = g_list_next (children);
item = gtk_tree_item_new_with_label(gst_element_get_name(child));
gtk_object_set_data(GTK_OBJECT(item), "tree", tree);
gtk_signal_connect (GTK_OBJECT (item), "select",
GTK_SIGNAL_FUNC (select_child_callback), child);
gtk_signal_connect (GTK_OBJECT (item), "deselect",
GTK_SIGNAL_FUNC (clear_edit_panes), child);
gtk_tree_append(GTK_TREE(tree), item);
gtk_widget_show(item);
if (GST_IS_BIN (child)){
build_tree(item, GST_BIN(child));
gtk_tree_item_expand(GTK_TREE_ITEM(item));
}
}
}
void
parse_callback( GtkWidget *widget,
GtkWidget *pipe_combo)
{
GList *history = (GList*)gtk_object_get_data(GTK_OBJECT(pipe_combo), "history");
FILE *history_file = (FILE*)gtk_object_get_data(GTK_OBJECT(pipe_combo), "history_file");
GtkWidget *tree_item = (GtkWidget*)gtk_object_get_data(GTK_OBJECT(widget), "tree_item");
gchar *last_pipe = (gchar*)gtk_object_get_data(GTK_OBJECT(widget), "last_pipe");
gchar *try_pipe = gtk_entry_get_text(GTK_ENTRY(GTK_COMBO(pipe_combo)->entry));
gchar *write_pipe = g_strdup_printf("%s\n", try_pipe);
fwrite(write_pipe, sizeof(gchar), strlen(write_pipe), history_file);
fflush(history_file);
if (pipeline){
g_print("unreffing\n");
gst_object_unref (GST_OBJECT (pipeline));
@ -244,9 +527,19 @@ parse_callback( GtkWidget *widget,
gst_parse_launch (try_pipe, GST_BIN (pipeline));
gtk_widget_set_sensitive(GTK_WIDGET(start_but), TRUE);
history = g_list_prepend(history, try_pipe);
gtk_combo_set_popdown_strings(GTK_COMBO(pipe_combo), history);
g_free(write_pipe);
build_tree(tree_item, GST_BIN(pipeline));
if (last_pipe==NULL || !((strlen(try_pipe) == strlen(last_pipe)) && strstr(try_pipe, last_pipe))){
gchar *write_pipe = g_strdup_printf("%s\n", try_pipe);
gtk_object_set_data(GTK_OBJECT(widget), "last_pipe", try_pipe);
fwrite(write_pipe, sizeof(gchar), strlen(write_pipe), history_file);
fflush(history_file);
history = g_list_prepend(history, try_pipe);
gtk_combo_set_popdown_strings(GTK_COMBO(pipe_combo), history);
g_free(write_pipe);
g_free(last_pipe);
}
}
void
@ -254,7 +547,6 @@ start_callback( GtkWidget *widget,
gpointer data )
{
GtkWidget *pipe_combo = gtk_object_get_data(GTK_OBJECT(widget), "pipe_combo");
gchar *try_pipe = gtk_entry_get_text(GTK_ENTRY(GTK_COMBO(pipe_combo)->entry));
if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget))){
gtk_widget_set_sensitive(GTK_WIDGET(pause_but), TRUE);
@ -296,7 +588,8 @@ pause_callback( GtkWidget *widget,
int main(int argc,char *argv[]) {
GtkWidget *window;
GtkWidget *vbox;
GtkWidget *parse_line, *pipe_combo, *notebook;
GtkWidget *parse_line, *pipe_combo, *notebook, *pane;
GtkWidget *tree_root, *tree_root_item, *page_scroll;
gst_init(&argc,&argv);
@ -332,13 +625,45 @@ int main(int argc,char *argv[]) {
GTK_SIGNAL_FUNC (pause_callback), NULL);
gtk_signal_connect (GTK_OBJECT (parse_but), "clicked",
GTK_SIGNAL_FUNC (parse_callback), pipe_combo);
gtk_signal_connect (GTK_OBJECT (parse_but), "clicked",
GTK_SIGNAL_FUNC (clear_edit_panes), NULL);
gtk_object_set_data(GTK_OBJECT(start_but), "pipe_combo", pipe_combo);
notebook = gtk_notebook_new();
gtk_box_pack_start(GTK_BOX(vbox),notebook,TRUE,TRUE,0);
tree_root = gtk_tree_new();
tree_root_item = gtk_tree_item_new_with_label("pipe");
gtk_tree_append(GTK_TREE(tree_root), tree_root_item);
gtk_object_set_data(GTK_OBJECT(parse_but), "tree_item", tree_root_item);
gtk_tree_item_expand(GTK_TREE_ITEM(tree_root_item));
prop_box = gtk_vbox_new(FALSE, 0);
//dparam_box = gtk_vbox_new(FALSE, 0);
notebook = gtk_notebook_new();
page_scroll = gtk_scrolled_window_new(NULL,NULL);
gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(page_scroll), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
gtk_scrolled_window_add_with_viewport(GTK_SCROLLED_WINDOW(page_scroll), prop_box);
gtk_notebook_append_page(GTK_NOTEBOOK(notebook), page_scroll, gtk_label_new("Properties"));
/*
page_scroll = gtk_scrolled_window_new(NULL,NULL);
gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(page_scroll), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
gtk_scrolled_window_add_with_viewport(GTK_SCROLLED_WINDOW(page_scroll), dparam_box);
gtk_notebook_append_page(GTK_NOTEBOOK(notebook), page_scroll, gtk_label_new("Dynamic Params"));
*/
build_debug_page(notebook);
page_scroll = gtk_scrolled_window_new(NULL,NULL);
gtk_scrolled_window_add_with_viewport(GTK_SCROLLED_WINDOW(page_scroll), tree_root);
gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(page_scroll), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
pane = gtk_hpaned_new();
gtk_paned_pack1 (GTK_PANED (pane), page_scroll, TRUE, TRUE);
gtk_paned_pack2 (GTK_PANED (pane), notebook, TRUE, TRUE);
gtk_box_pack_start(GTK_BOX(vbox),pane,TRUE,TRUE,0);
status = gtk_label_new("stopped");
gtk_box_pack_start(GTK_BOX(vbox),status,FALSE,FALSE,0);