From 0cd378a53af88598262205a200c2734f8f93894f Mon Sep 17 00:00:00 2001 From: Nedko Arnaudov Date: Fri, 28 Aug 2009 21:59:45 +0300 Subject: [PATCH] gladish: studio load menu. Closes #1 --- gui/control_proxy.c | 54 +++++++++++++++++++++++++++++++--- gui/control_proxy.h | 8 +---- gui/gui.glade | 6 +++- gui/main.c | 71 +++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 127 insertions(+), 12 deletions(-) diff --git a/gui/control_proxy.c b/gui/control_proxy.c index 97a18cd6..8665943d 100644 --- a/gui/control_proxy.c +++ b/gui/control_proxy.c @@ -110,17 +110,63 @@ void control_proxy_uninit(void) dbus_unregister_object_signal_handler(g_dbus_connection, SERVICE_NAME, CONTROL_OBJECT_PATH, IFACE_CONTROL, g_signals, message_hook, NULL); } -bool control_proxy_get_studio_list(struct list_head * studio_list) +bool control_proxy_get_studio_list(void (* callback)(void * context, const char * studio_name), void * context) { - return false; + DBusMessage * reply_ptr; + const char * reply_signature; + DBusMessageIter top_iter; + DBusMessageIter struct_iter; + DBusMessageIter array_iter; + const char * studio_name; + + if (!dbus_call_simple(SERVICE_NAME, CONTROL_OBJECT_PATH, IFACE_CONTROL, "GetStudioList", "", NULL, &reply_ptr)) + { + lash_error("GetStudioList() failed."); + return false; + } + + reply_signature = dbus_message_get_signature(reply_ptr); + if (strcmp(reply_signature, "a(sa{sv})") != 0) + { + lash_error("GetStudioList() reply signature mismatch. '%s'", reply_signature); + dbus_message_unref(reply_ptr); + return false; + } + + dbus_message_iter_init(reply_ptr, &top_iter); + for (dbus_message_iter_recurse(&top_iter, &array_iter); + dbus_message_iter_get_arg_type(&array_iter) != DBUS_TYPE_INVALID; + dbus_message_iter_next(&array_iter)) + { + dbus_message_iter_recurse(&array_iter, &struct_iter); + dbus_message_iter_get_basic(&struct_iter, &studio_name); + callback(context, studio_name); + dbus_message_iter_next(&struct_iter); + dbus_message_iter_next(&struct_iter); + } + + dbus_message_unref(reply_ptr); + return true; } bool control_proxy_load_studio(const char * studio_name) { - return false; + if (!dbus_call_simple(SERVICE_NAME, CONTROL_OBJECT_PATH, IFACE_CONTROL, "LoadStudio", "s", &studio_name, "")) + { + lash_error("LoadStudio() failed."); + return false; + } + + return true; } bool control_proxy_exit(void) { - return false; + if (!dbus_call_simple(SERVICE_NAME, CONTROL_OBJECT_PATH, IFACE_CONTROL, "Exit", "", "")) + { + lash_error("Exit() failed."); + return false; + } + + return true; } diff --git a/gui/control_proxy.h b/gui/control_proxy.h index a8feff17..353add01 100644 --- a/gui/control_proxy.h +++ b/gui/control_proxy.h @@ -31,17 +31,11 @@ #include "common.h" #include "../common/klist.h" -struct loadable_studio -{ - struct list_head siblings; - char * name; -}; - bool control_proxy_init(void); void control_proxy_uninit(void); void control_proxy_on_studio_appeared(void); void control_proxy_on_studio_disappeared(void); -bool control_proxy_get_studio_list(struct list_head * studio_list); +bool control_proxy_get_studio_list(void (* callback)(void * context, const char * studio_name), void * context); bool control_proxy_load_studio(const char * studio_name); bool control_proxy_exit(void); diff --git a/gui/gui.glade b/gui/gui.glade index 39f2a919..63c545ad 100644 --- a/gui/gui.glade +++ b/gui/gui.glade @@ -23,7 +23,7 @@ True - _Load Studio... + _Load Studio True @@ -864,4 +864,8 @@ along with LADI Session Handler; if not, write to the Free Software Foundation, + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + diff --git a/gui/main.c b/gui/main.c index 77bf96ff..3f41e3d8 100644 --- a/gui/main.c +++ b/gui/main.c @@ -47,12 +47,14 @@ GtkWidget * g_clear_load_button; GtkWidget * g_xrun_progress_bar; GtkWidget * g_buffer_size_combo; +GtkWidget * g_menu_item_load_studio; GtkWidget * g_menu_item_save_studio; GtkWidget * g_menu_item_rename_studio; GtkWidget * g_menu_item_create_room; GtkWidget * g_menu_item_destroy_room; GtkWidget * g_menu_item_load_project; GtkWidget * g_menu_item_start_app; +GtkWidget * g_menu_studio_list; GtkWidget * g_rename_dialog; @@ -61,6 +63,7 @@ graph_view_handle g_studio_view = NULL; static guint g_jack_poll_source_tag; static double g_jack_max_dsp_load = 0.0; +static int g_studio_count = 0; #if 0 static void @@ -204,6 +207,69 @@ static void arrange(void) } } +static void on_load_studio(GtkWidget * item) +{ + const char * studio_name; + + studio_name = gtk_label_get_text(GTK_LABEL(gtk_bin_get_child(GTK_BIN(item)))); + lash_info("Load studio \"%s\"", studio_name); + + if (!control_proxy_load_studio(studio_name)) + { + /* TODO: display error message */ + } +} + +static void remove_studio_list_menu_entry(GtkWidget * item, GtkContainer * container) +{ + GtkWidget * label; + + label = gtk_bin_get_child(GTK_BIN(item)); + + //lash_debug("removing studio menu item \"%s\"", gtk_menu_item_get_label(GTK_MENU_ITEM(item)); + // gtk_menu_item_get_label() requries gtk 2.16 + lash_debug("removing studio menu item \"%s\"", gtk_label_get_text(GTK_LABEL(label))); + + gtk_container_remove(GTK_CONTAINER(item), label); /* destroy the label and drop the item refcount by one */ + //lash_info("refcount == %d", (unsigned int)G_OBJECT(item)->ref_count); + gtk_container_remove(container, item); /* drop the refcount of item by one and thus destroy it */ + g_studio_count--; +} + +static void menu_studio_list_clear(void) +{ + gtk_container_foreach(GTK_CONTAINER(g_menu_studio_list), (GtkCallback)remove_studio_list_menu_entry, GTK_CONTAINER(g_menu_studio_list)); + assert(g_studio_count == 0); + g_studio_count = 0; +} + +static void add_studio_list_menu_entry(void * context, const char * studio_name) +{ + GtkWidget * item; + + item = gtk_menu_item_new_with_label(studio_name); + //lash_info("refcount == %d", (unsigned int)G_OBJECT(item)->ref_count); // refcount == 2 because of the label + gtk_widget_set_sensitive(item, (bool)context); + gtk_widget_show(item); + gtk_menu_shell_append(GTK_MENU_SHELL(g_menu_studio_list), item); + g_signal_connect(G_OBJECT(item), "activate", G_CALLBACK(on_load_studio), item); + g_studio_count++; +} + +static void activate_load_studio_list(void) +{ + menu_studio_list_clear(); + if (!control_proxy_get_studio_list(add_studio_list_menu_entry, (void *)true)) + { + menu_studio_list_clear(); + add_studio_list_menu_entry((void *)false, "Error obtaining studio list"); + } + else if (g_studio_count == 0) + { + add_studio_list_menu_entry((void *)false, "Empty studio list"); + } +} + static void save_studio(void) { lash_info("save studio request"); @@ -374,15 +440,19 @@ int main(int argc, char** argv) g_clear_load_button = get_glade_widget("clear_load_button"); g_xrun_progress_bar = get_glade_widget("xrun_progress_bar"); g_buffer_size_combo = get_glade_widget("buffer_size_combo"); + g_menu_item_load_studio = get_glade_widget("menu_item_load_studio"); g_menu_item_save_studio = get_glade_widget("menu_item_save_studio"); g_menu_item_rename_studio = get_glade_widget("menu_item_rename_studio"); g_menu_item_create_room = get_glade_widget("menu_item_create_room"); g_menu_item_destroy_room = get_glade_widget("menu_item_destroy_room"); g_menu_item_load_project = get_glade_widget("menu_item_load_project"); g_menu_item_start_app = get_glade_widget("menu_item_start_app"); + g_menu_studio_list = get_glade_widget("studio_list_menu"); g_rename_dialog = get_glade_widget("rename_dialog"); + gtk_menu_item_set_submenu(GTK_MENU_ITEM(g_menu_item_load_studio), g_menu_studio_list); + world_tree_init(); view_init(); @@ -414,6 +484,7 @@ int main(int argc, char** argv) g_signal_connect(G_OBJECT(get_glade_widget("menu_item_view_arrange")), "activate", G_CALLBACK(arrange), NULL); g_signal_connect(G_OBJECT(g_menu_item_save_studio), "activate", G_CALLBACK(save_studio), NULL); g_signal_connect(G_OBJECT(g_menu_item_rename_studio), "activate", G_CALLBACK(rename_studio), NULL); + g_signal_connect(G_OBJECT(g_menu_item_load_studio), "activate", G_CALLBACK(activate_load_studio_list), NULL); gtk_widget_show(g_main_win);