X-Git-Url: https://main.carlh.net/gitweb/?a=blobdiff_plain;f=gtk2_ardour%2Fio_selector.cc;h=7ff12612e60c30dee554a382f311fa766ef8c6e8;hb=767984b486086e3682e521179c2fb8364b3bba76;hp=1f7c7dc0450847f898eaab96b60b4904a7a4186c;hpb=b62c348c88f4c34286a759898e7148561c3de35e;p=ardour.git diff --git a/gtk2_ardour/io_selector.cc b/gtk2_ardour/io_selector.cc index 1f7c7dc045..7ff12612e6 100644 --- a/gtk2_ardour/io_selector.cc +++ b/gtk2_ardour/io_selector.cc @@ -15,13 +15,16 @@ along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - $Id$ */ #include #include -#include +#include + +#include + +#include #include #include @@ -29,14 +32,13 @@ #include #include #include -#include +#include #include #include #include #include "utils.h" -#include "ardour_message.h" #include "io_selector.h" #include "keyboard.h" #include "gui_thread.h" @@ -48,9 +50,10 @@ using namespace Gtk; using namespace Glib; using namespace sigc; using namespace ARDOUR; +using namespace PBD; using namespace Gtkmm2ext; -IOSelectorWindow::IOSelectorWindow (Session& sess, IO& ior, bool input, bool can_cancel) +IOSelectorWindow::IOSelectorWindow (Session& sess, boost::shared_ptr ior, bool input, bool can_cancel) : ArdourDialog ("i/o selector"), _selector (sess, ior, input), ok_button (can_cancel ? _("OK"): _("Close")), @@ -63,9 +66,9 @@ IOSelectorWindow::IOSelectorWindow (Session& sess, IO& ior, bool input, bool can string title; if (input) { - title = string_compose(_("%1 input"), ior.name()); + title = string_compose(_("%1 input"), ior->name()); } else { - title = string_compose(_("%1 output"), ior.name()); + title = string_compose(_("%1 output"), ior->name()); } ok_button.set_name ("IOSelectorButton"); @@ -133,7 +136,7 @@ IOSelectorWindow::on_map () The IO Selector "widget" *************************/ -IOSelector::IOSelector (Session& sess, IO& ior, bool input) +IOSelector::IOSelector (Session& sess, boost::shared_ptr ior, bool input) : session (sess), io (ior), for_input (input), @@ -180,40 +183,7 @@ IOSelector::IOSelector (Session& sess, IO& ior, bool input) port_button_box.set_border_width (5); port_button_box.pack_start (add_port_button, false, false); - - if (for_input) { - if (io.input_maximum() < 0 || io.input_maximum() > (int) io.n_inputs()) { - add_port_button.set_sensitive (true); - } else { - add_port_button.set_sensitive (false); - } - - } else { - if (io.output_maximum() < 0 || io.output_maximum() > (int) io.n_outputs()) { - add_port_button.set_sensitive (true); - } else { - add_port_button.set_sensitive (false); - } - - } - port_button_box.pack_start (remove_port_button, false, false); - - if (for_input) { - if (io.input_minimum() < 0 || io.input_minimum() < (int) io.n_inputs()) { - remove_port_button.set_sensitive (true); - } else { - remove_port_button.set_sensitive (false); - } - - } else { - if (io.output_minimum() < 0 || io.output_minimum() < (int) io.n_outputs()) { - remove_port_button.set_sensitive (true); - } else { - remove_port_button.set_sensitive (false); - } - } - port_button_box.pack_start (clear_connections_button, false, false); port_and_button_box.set_border_width (5); @@ -239,18 +209,56 @@ IOSelector::IOSelector (Session& sess, IO& ior, bool input) remove_port_button.signal_clicked().connect (mem_fun(*this, &IOSelector::remove_port)); if (for_input) { - io.input_changed.connect (mem_fun(*this, &IOSelector::ports_changed)); + io->input_changed.connect (mem_fun(*this, &IOSelector::ports_changed)); } else { - io.output_changed.connect (mem_fun(*this, &IOSelector::ports_changed)); + io->output_changed.connect (mem_fun(*this, &IOSelector::ports_changed)); } - io.name_changed.connect (mem_fun(*this, &IOSelector::name_changed)); + io->name_changed.connect (mem_fun(*this, &IOSelector::name_changed)); } IOSelector::~IOSelector () { } +void +IOSelector::set_button_sensitivity () +{ + if (for_input) { + + if (io->input_maximum() < 0 || io->input_maximum() > (int) io->n_inputs()) { + add_port_button.set_sensitive (true); + } else { + add_port_button.set_sensitive (false); + } + + } else { + + if (io->output_maximum() < 0 || io->output_maximum() > (int) io->n_outputs()) { + add_port_button.set_sensitive (true); + } else { + add_port_button.set_sensitive (false); + } + + } + + if (for_input) { + if (io->n_inputs() && (io->input_minimum() < 0 || io->input_minimum() < (int) io->n_inputs())) { + remove_port_button.set_sensitive (true); + } else { + remove_port_button.set_sensitive (false); + } + + } else { + if (io->n_outputs() && (io->output_minimum() < 0 || io->output_minimum() < (int) io->n_outputs())) { + remove_port_button.set_sensitive (true); + } else { + remove_port_button.set_sensitive (false); + } + } +} + + void IOSelector::name_changed (void* src) { @@ -263,9 +271,9 @@ void IOSelector::clear_connections () { if (for_input) { - io.disconnect_inputs (this); + io->disconnect_inputs (this); } else { - io.disconnect_outputs (this); + io->disconnect_outputs (this); } } @@ -281,7 +289,10 @@ IOSelector::rescan () gint current_page; vector rowdata; + page_selection_connection.disconnect (); + current_page = notebook.get_current_page (); + pages.clear (); /* get relevant current JACK ports */ @@ -340,9 +351,7 @@ IOSelector::rescan () row[port_display_columns.full_name] = s->second; } - display->get_selection()->signal_changed().connect - (bind (mem_fun(*this, &IOSelector::port_selection_changed), display)); - + display->signal_button_release_event().connect (bind (mem_fun(*this, &IOSelector::port_selection_changed), display)); Label *tab_label = manage (new Label); tab_label->set_name ("IOSelectorNotebookTab"); @@ -357,7 +366,7 @@ IOSelector::rescan () } notebook.set_current_page (current_page); - notebook.signal_show().connect (bind (mem_fun (notebook, &Notebook::set_current_page), current_page)); + page_selection_connection = notebook.signal_show().connect (bind (mem_fun (notebook, &Notebook::set_current_page), current_page)); selector_box.show_all (); } @@ -366,33 +375,31 @@ IOSelector::display_ports () { TreeView *firsttview = 0; TreeView *selected_port_tview = 0; - { - LockMonitor lm (port_display_lock, __LINE__, __FILE__); + Glib::Mutex::Lock lm (port_display_lock); Port *port; uint32_t limit; - + if (for_input) { - limit = io.n_inputs(); + limit = io->n_inputs(); } else { - limit = io.n_outputs(); + limit = io->n_outputs(); } - - for (slist::iterator i = port_displays.begin(); i != port_displays.end(); ) { + for (slist::iterator i = port_displays.begin(); i != port_displays.end(); ) { + slist::iterator tmp; - + tmp = i; ++tmp; - + port_box.remove (**i); delete *i; port_displays.erase (i); - + i = tmp; } - - + for (uint32_t n = 0; n < limit; ++n) { TreeView* tview; @@ -400,19 +407,19 @@ IOSelector::display_ports () string really_short_name; if (for_input) { - port = io.input (n); + port = io->input (n); } else { - port = io.output (n); + port = io->output (n); } /* we know there is '/' because we put it there */ - + really_short_name = port->short_name(); really_short_name = really_short_name.substr (really_short_name.find ('/') + 1); tview = manage (new TreeView()); RefPtr port_model = ListStore::create (port_display_columns); - + if (!firsttview) { firsttview = tview; } @@ -420,37 +427,28 @@ IOSelector::display_ports () tview->set_model (port_model); tview->append_column (really_short_name, port_display_columns.displayed_name); tview->get_selection()->set_mode (SELECTION_SINGLE); - tview->set_data ("port", port); + tview->set_data (X_("port"), port); tview->set_headers_visible (true); - tview->set_name ("IOSelectorPortList"); + tview->set_name (X_("IOSelectorPortList")); port_box.pack_start (*tview); - //scroller = manage (new ScrolledWindow); - - //scroller->add (*tview); - //scroller->set_policy (POLICY_NEVER, POLICY_NEVER); - port_displays.insert (port_displays.end(), tview); - //port_box.pack_start (*scroller); - - //scroller->set_size_request (-1, 75); /* now fill the clist with the current connections */ - const char **connections = port->get_connections (); - + if (connections) { for (uint32_t c = 0; connections[c]; ++c) { TreeModel::Row row = *(port_model->append()); row[port_display_columns.displayed_name] = connections[c]; row[port_display_columns.full_name] = connections[c]; } - } + } if (for_input) { - if (io.input_maximum() == 1) { + if (io->input_maximum() == 1) { selected_port = port; selected_port_tview = tview; } else { @@ -458,10 +456,10 @@ IOSelector::display_ports () selected_port_tview = tview; } } - + } else { - - if (io.output_maximum() == 1) { + + if (io->output_maximum() == 1) { selected_port = port; selected_port_tview = tview; } else { @@ -470,71 +468,61 @@ IOSelector::display_ports () } } } - + TreeViewColumn* col = tview->get_column (0); col->set_clickable (true); - //set_treeview_header_as_default_label(col); - /* handle button events on the column header and within the treeview itself */ + + /* handle button events on the column header ... */ + col->signal_clicked().connect (bind (mem_fun(*this, &IOSelector::select_treeview), tview)); - //col->signal_button_release_event().connect (bind (mem_fun(*this, &IOSelector::port_column_button_release), tview)); + /* ... and within the treeview itself */ tview->signal_button_release_event().connect (bind (mem_fun(*this, &IOSelector::connection_button_release), tview)); } - + port_box.show_all (); - - if (selected_port_tview) { - // GTK2FIX - // selected_port_tview->click_column(0); - selected_port_tview->set_name ("IOSelectorPortListSelected"); - for (slist::iterator i = port_displays.begin(); i != port_displays.end(); ++i) { - if (*i != selected_port_tview) { - (*i)->set_name ("IOSelectorPortList"); - (*i)->queue_draw (); - } - } - } else { - selected_port = 0; - selector_box.hide_all (); - } } + if (!selected_port_tview) { + selected_port_tview = firsttview; + } + if (selected_port_tview) { select_treeview (selected_port_tview); - } else if (firsttview) { - // select first - select_treeview (firsttview); } } -void -IOSelector::port_selection_changed (TreeView* treeview) +bool +IOSelector::port_selection_changed (GdkEventButton *ev, TreeView* treeview) { TreeModel::iterator i = treeview->get_selection()->get_selected(); int status; if (!i) { - return; + return 0; } if (selected_port == 0) { - return; + return 0; } ustring other_port_name = (*i)[port_display_columns.full_name]; if (for_input) { - if ((status = io.connect_input (selected_port, other_port_name, this)) == 0) { + if ((status = io->connect_input (selected_port, other_port_name, this)) == 0) { Port *p = session.engine().get_port_by_name (other_port_name); p->enable_metering(); } } else { - status = io.connect_output (selected_port, other_port_name, this); + status = io->connect_output (selected_port, other_port_name, this); } if (status == 0) { select_next_treeview (); } + + treeview->get_selection()->unselect_all(); + return 0; } void @@ -553,36 +541,27 @@ IOSelector::add_port () if (for_input) { try { - io.add_input_port ("", this); + io->add_input_port ("", this); } catch (AudioEngine::PortRegistrationFailure& err) { - ArdourMessage msg (0, X_("noport dialog"), _("There are no more JACK ports available.")); - } - - if (io.input_maximum() >= 0 && io.input_maximum() <= (int) io.n_inputs()) { - add_port_button.set_sensitive (false); - } - - if (io.input_minimum() < (int) io.n_inputs()) { - remove_port_button.set_sensitive (true); + MessageDialog msg (0, _("There are no more JACK ports available.")); + msg.run (); } } else { try { - io.add_output_port ("", this); + io->add_output_port ("", this); } catch (AudioEngine::PortRegistrationFailure& err) { - ArdourMessage msg (0, X_("noport dialog"), - _("There are no more JACK ports available.")); - } - - if (io.output_maximum() >= 0 && io.output_maximum() <= (int) io.n_outputs()) { - add_port_button.set_sensitive (false); + MessageDialog msg (0, _("There are no more JACK ports available.")); + msg.run (); } } + + set_button_sensitivity (); } void @@ -593,29 +572,17 @@ IOSelector::remove_port () // always remove last port if (for_input) { - if ((nports = io.n_inputs()) > 0) { - io.remove_input_port (io.input(nports-1), this); - } - if (io.input_minimum() == (int) io.n_inputs()) { - remove_port_button.set_sensitive (false); - } - } else { - if ((nports = io.n_outputs()) > 0) { - io.remove_output_port (io.output(nports-1), this); + if ((nports = io->n_inputs()) > 0) { + io->remove_input_port (io->input(nports-1), this); } - } -} -gint -IOSelector::remove_port_when_idle (Port *port) -{ - if (for_input) { - io.remove_input_port (port, this); } else { - io.remove_output_port (port, this); + if ((nports = io->n_outputs()) > 0) { + io->remove_output_port (io->output(nports-1), this); + } } - - return FALSE; + + set_button_sensitivity (); } gint @@ -637,75 +604,37 @@ IOSelector::connection_button_release (GdkEventButton *ev, TreeView *treeview) return false; } - if (!(Keyboard::is_delete_event (ev))) { - //return false; - } - if (!treeview->get_path_at_pos ((int)ev->x, (int)ev->y, path, column, cellx, celly)) { return false; } - cerr << "path = " << path.to_string() << endl; - + if ((iter = treeview->get_model()->get_iter (path.to_string()))) { /* path is valid */ ustring connected_port_name = (*iter)[port_display_columns.full_name]; - cerr << "selected row displayed_name: " << (*iter)[port_display_columns.displayed_name] << endl; - cerr << "selected row string was " << connected_port_name << endl; - Port *port = reinterpret_cast (treeview->get_data (_("port"))); + Port *port = reinterpret_cast (treeview->get_data (X_("port"))); if (for_input) { Port *p = session.engine().get_port_by_name (connected_port_name); p->disable_metering(); - io.disconnect_input (port, connected_port_name, this); + io->disconnect_input (port, connected_port_name, this); } else { - io.disconnect_output (port, connected_port_name, this); + io->disconnect_output (port, connected_port_name, this); } } return true; } -gint -IOSelector::port_column_button_release (GdkEventButton* event, TreeView* treeview) -{ - /* this handles button release on the button at the top of a single-column - treeview (representing a port) - */ - cerr << "IOSelector::port_column_button_release() called" << endl; - - if (Keyboard::is_delete_event (event)) { - Port* port; - { - LockMonitor lm (port_display_lock, __LINE__, __FILE__); - - port = static_cast (treeview->get_data (_("port"))); - - if (port == selected_port) { - selected_port = 0; - treeview->set_name ("IOSelectorPortList"); - treeview->queue_draw(); - } - } - - /* remove the port when idle - if we do it here, we will destroy the widget - for whom we are handling an event. not good. - */ - - signal_idle().connect (bind (mem_fun(*this, &IOSelector::remove_port_when_idle), port)); - - } else { - select_treeview (treeview); - } - - return TRUE; -} - void IOSelector::select_next_treeview () { slist::iterator next; + if (port_displays.empty() || port_displays.size() == 1) { + return; + } + for (slist::iterator i = port_displays.begin(); i != port_displays.end(); ++i) { if ((*i)->get_name() == "IOSelectorPortListSelected") { @@ -731,22 +660,42 @@ IOSelector::select_treeview (TreeView* tview) switch. */ - LockMonitor lm (port_display_lock, __LINE__, __FILE__); - Port* port = reinterpret_cast (tview->get_data (_("port"))); + Glib::Mutex::Lock lm (port_display_lock); + Port* port = reinterpret_cast (tview->get_data (X_("port"))); + + selected_port = port; + + tview->set_name ("IOSelectorPortListSelected"); + tview->queue_draw (); + + /* ugly hack to force the column header button to change as well */ + + TreeViewColumn* col = tview->get_column (0); + GtkTreeViewColumn* ccol = col->gobj(); - if (port != selected_port) { - selected_port = port; + if (ccol->button) { + gtk_widget_set_name (ccol->button, "IOSelectorPortListSelected"); + gtk_widget_queue_draw (ccol->button); + } + + for (slist::iterator i = port_displays.begin(); i != port_displays.end(); ++i) { + if (*i == tview) { + continue; + } - tview->set_name ("IOSelectorPortListSelected"); + col = (*i)->get_column (0); + ccol = col->gobj(); - for (slist::iterator i = port_displays.begin(); i != port_displays.end(); ++i) { - if (*i != tview) { - (*i)->set_name ("IOSelectorPortList"); - (*i)->queue_draw (); - } + if (ccol->button) { + gtk_widget_set_name (ccol->button, "IOSelectorPortList"); + gtk_widget_queue_draw (ccol->button); } - selector_box.show_all (); + + (*i)->set_name ("IOSelectorPortList"); + (*i)->queue_draw (); } + + selector_box.show_all (); } void @@ -755,17 +704,17 @@ IOSelector::redisplay () display_ports (); if (for_input) { - if (io.input_maximum() != 0) { + if (io->input_maximum() != 0) { rescan (); } } else { - if (io.output_maximum() != 0) { + if (io->output_maximum() != 0) { rescan(); } } } -PortInsertUI::PortInsertUI (Session& sess, PortInsert& pi) +PortInsertUI::PortInsertUI (Session& sess, boost::shared_ptr pi) : input_selector (sess, pi, true), output_selector (sess, pi, false) { @@ -792,9 +741,9 @@ PortInsertUI::finished(IOSelector::Result r) } -PortInsertWindow::PortInsertWindow (Session& sess, PortInsert& pi, bool can_cancel) +PortInsertWindow::PortInsertWindow (Session& sess, boost::shared_ptr pi, bool can_cancel) : ArdourDialog ("port insert dialog"), - _portinsertui(sess, pi), + _portinsertui (sess, pi), ok_button (can_cancel ? _("OK"): _("Close")), cancel_button (_("Cancel")), rescan_button (_("Rescan")) @@ -802,7 +751,7 @@ PortInsertWindow::PortInsertWindow (Session& sess, PortInsert& pi, bool can_canc set_name ("IOSelectorWindow"); string title = _("ardour: "); - title += pi.name(); + title += pi->name(); set_title (title); ok_button.set_name ("IOSelectorButton"); @@ -829,13 +778,13 @@ PortInsertWindow::PortInsertWindow (Session& sess, PortInsert& pi, bool can_canc rescan_button.signal_clicked().connect (mem_fun(*this, &PortInsertWindow::rescan)); signal_delete_event().connect (bind (sigc::ptr_fun (just_hide_it), reinterpret_cast (this))); - pi.GoingAway.connect (mem_fun(*this, &PortInsertWindow::plugin_going_away)); + pi->GoingAway.connect (mem_fun(*this, &PortInsertWindow::plugin_going_away)); } void -PortInsertWindow::plugin_going_away (ARDOUR::Redirect* ignored) +PortInsertWindow::plugin_going_away () { - ENSURE_GUI_THREAD(bind (mem_fun(*this, &PortInsertWindow::plugin_going_away), ignored)); + ENSURE_GUI_THREAD(mem_fun(*this, &PortInsertWindow::plugin_going_away)); delete_when_idle (this); }