From beef6e7d445a82994b640387057dbeb53865993c Mon Sep 17 00:00:00 2001 From: Nedko Arnaudov Date: Wed, 1 Jun 2011 05:37:02 +0300 Subject: [PATCH] join vclients functionality --- daemon/virtualizer.c | 28 ++++++++++++++++++++ gui/canvas.cpp | 63 +++++++++++++++++++++++++++++++++++++++++--- gui/canvas.h | 13 ++++++++- gui/graph_canvas.c | 42 ++++++++++++++++++++++++++++- 4 files changed, 140 insertions(+), 6 deletions(-) diff --git a/daemon/virtualizer.c b/daemon/virtualizer.c index f0060b53..803a111d 100644 --- a/daemon/virtualizer.c +++ b/daemon/virtualizer.c @@ -1562,6 +1562,24 @@ bool ladish_virtualizer_split_client(ladish_graph_handle vgraph, uint64_t client return ladish_graph_interate_client_ports(vgraph, vclient1, vclient2, move_capture_port_callback); } +static +bool +move_port_callback( + void * context, + ladish_graph_handle graph_handle, + bool hidden, + ladish_client_handle client_handle, + const char * client_name, + ladish_port_handle port_handle, + const char * port_name, + uint32_t port_type, + uint32_t port_flags) +{ + ASSERT(client_handle != context); /* source and destination clients must be differ */ + ladish_graph_move_port(graph_handle, port_handle, context); + return true; +} + bool ladish_virtualizer_join_clients( ladish_graph_handle vgraph, @@ -1571,6 +1589,12 @@ ladish_virtualizer_join_clients( ladish_client_handle vclient1; ladish_client_handle vclient2; + if (client1_id == client2_id) + { + log_error("Cannot join same client"); + return false; + } + vclient1 = ladish_graph_find_client_by_id(vgraph, client1_id); if (vclient1 == NULL) { @@ -1585,5 +1609,9 @@ ladish_virtualizer_join_clients( return false; } + ladish_graph_interate_client_ports(vgraph, vclient2, vclient1, move_port_callback); + + ladish_graph_remove_client(vgraph, vclient2); + return true; } diff --git a/gui/canvas.cpp b/gui/canvas.cpp index 36058979..0c51f2f5 100644 --- a/gui/canvas.cpp +++ b/gui/canvas.cpp @@ -37,13 +37,15 @@ public: canvas_cls( double width, double height, + void * context, void (* connect_request)(void * port1_context, void * port2_context), void (* disconnect_request)(void * port1_context, void * port2_context), void (* module_location_changed)(void * module_context, double x, double y), - void (* fill_canvas_menu)(GtkMenu * menu), + void (* fill_canvas_menu)(GtkMenu * menu, void * canvas_context), void (* fill_module_menu)(GtkMenu * menu, void * module_context), void (* fill_port_menu)(GtkMenu * menu, void * port_context)) : FlowCanvas::Canvas(width, height) + , m_context(context) , m_connect_request(connect_request) , m_disconnect_request(disconnect_request) , m_module_location_changed(module_location_changed) @@ -77,10 +79,11 @@ public: virtual void connect(boost::shared_ptr port1, boost::shared_ptr port2); virtual void disconnect(boost::shared_ptr port1, boost::shared_ptr port2); + void * m_context; void (* m_connect_request)(void * port1_context, void * port2_context); void (* m_disconnect_request)(void * port1_context, void * port2_context); void (* m_module_location_changed)(void * module_context, double x, double y); - void (* m_fill_canvas_menu)(GtkMenu * menu); + void (* m_fill_canvas_menu)(GtkMenu * menu, void * canvas_context); void (* m_fill_module_menu)(GtkMenu * menu, void * module_context); void (* m_fill_port_menu)(GtkMenu * menu, void * port_context); }; @@ -197,10 +200,11 @@ bool canvas_create( double width, double height, + void * canvas_context, void (* connect_request)(void * port1_context, void * port2_context), void (* disconnect_request)(void * port1_context, void * port2_context), void (* module_location_changed)(void * module_context, double x, double y), - void (* fill_canvas_menu)(GtkMenu * menu), + void (* fill_canvas_menu)(GtkMenu * menu, void * canvas_context), void (* fill_module_menu)(GtkMenu * menu, void * module_context), void (* fill_port_menu)(GtkMenu * menu, void * port_context), canvas_handle * canvas_handle_ptr) @@ -209,6 +213,7 @@ canvas_create( canvas = new boost::shared_ptr(new canvas_cls(width, height, + canvas_context, connect_request, disconnect_request, module_location_changed, @@ -320,6 +325,56 @@ canvas_arrange( } } +size_t +canvas_get_selected_modules_count( + canvas_handle canvas) +{ + return canvas_ptr->get()->selected_items().size(); +} + +bool +canvas_get_two_selected_modules( + canvas_handle canvas, + void ** module1_context_ptr, + void ** module2_context_ptr) +{ + int i; + + std::list > modules = canvas_ptr->get()->selected_items(); + if (modules.size() != 2) + { + return false; + } + + i = 0; + for (std::list >::iterator m = modules.begin(); m != modules.end(); ++m) + { + boost::shared_ptr module = boost::dynamic_pointer_cast(*m); + if (module == NULL) + { + ASSERT_NO_PASS; + return false; + } + + switch (i) + { + case 0: + *module1_context_ptr = module->m_context; + i++; + break; + case 1: + *module2_context_ptr = module->m_context; + i++; + break; + default: + ASSERT_NO_PASS; + return false; + } + } + + return true; +} + bool canvas_create_module( canvas_handle canvas, @@ -466,7 +521,7 @@ bool canvas_cls::canvas_event(GdkEvent * event) { Gtk::Menu * menu_ptr; menu_ptr = new Gtk::Menu(); - m_fill_canvas_menu(menu_ptr->gobj()); + m_fill_canvas_menu(menu_ptr->gobj(), m_context); menu_ptr->show_all(); menu_ptr->popup(event->button.button, event->button.time); return true; diff --git a/gui/canvas.h b/gui/canvas.h index 3b665e6b..aeeb833a 100644 --- a/gui/canvas.h +++ b/gui/canvas.h @@ -48,10 +48,11 @@ bool canvas_create( double width, double height, + void * canvas_context, void (* connect_request)(void * port1_context, void * port2_context), void (* disconnect_request)(void * port1_context, void * port2_context), void (* module_location_changed)(void * module_context, double x, double y), - void (* fill_canvas_menu)(GtkMenu * menu), + void (* fill_canvas_menu)(GtkMenu * menu, void * canvas_context), void (* fill_module_menu)(GtkMenu * menu, void * module_context), void (* fill_port_menu)(GtkMenu * menu, void * port_context), canvas_handle * canvas_handle_ptr); @@ -95,6 +96,16 @@ void canvas_arrange( canvas_handle canvas); +size_t +canvas_get_selected_modules_count( + canvas_handle canvas); + +bool +canvas_get_two_selected_modules( + canvas_handle canvas, + void ** module1_context_ptr, + void ** module2_context_ptr); + bool canvas_create_module( canvas_handle canvas, diff --git a/gui/graph_canvas.c b/gui/graph_canvas.c index 823ec1dc..c9b93118 100644 --- a/gui/graph_canvas.c +++ b/gui/graph_canvas.c @@ -35,6 +35,7 @@ struct graph_canvas { graph_proxy_handle graph; canvas_handle canvas; + void (* fill_menu)(GtkMenu * menu); struct list_head clients; }; @@ -249,11 +250,47 @@ static void fill_port_menu(GtkMenu * menu, void * port_context) #undef port_ptr +#define canvas_ptr ((struct graph_canvas *)canvas_context) + +static void on_popup_menu_action_join_clients(GtkWidget * menuitem, gpointer canvas_context) +{ + struct client * client1_ptr; + struct client * client2_ptr; + + if (!canvas_get_two_selected_modules(canvas_ptr->canvas, (void **)&client1_ptr, (void **)&client2_ptr)) + { + return; + } + + if (!graph_proxy_join(canvas_ptr->graph, client1_ptr->id, client2_ptr->id)) + { + error_message_box("Join failed"); + } +} + +static void fill_canvas_menu(GtkMenu * menu, void * canvas_context) +{ + GtkWidget * menuitem; + + log_info("fill_canvas_menu"); + + if (canvas_get_selected_modules_count(canvas_ptr->canvas) == 2) + { + menuitem = gtk_menu_item_new_with_label(_("Join clients")); + g_signal_connect(menuitem, "activate", (GCallback)on_popup_menu_action_join_clients, canvas_ptr); + gtk_menu_shell_append(GTK_MENU_SHELL(menu), menuitem); + } + + canvas_ptr->fill_menu(menu); +} + +#undef canvas_ptr + bool graph_canvas_create( int width, int height, - void (* fill_canvas_menu)(GtkMenu * menu), + void (* fill_canvas_menu_callback)(GtkMenu * menu), graph_canvas_handle * graph_canvas_handle_ptr) { struct graph_canvas * graph_canvas_ptr; @@ -264,9 +301,12 @@ graph_canvas_create( return false; } + graph_canvas_ptr->fill_menu = fill_canvas_menu_callback; + if (!canvas_create( width, height, + graph_canvas_ptr, connect_request, disconnect_request, module_location_changed,