diff --git a/gtk2_ardour/audio_region_view.cc b/gtk2_ardour/audio_region_view.cc index 5f781937dc..1c52a05ea6 100644 --- a/gtk2_ardour/audio_region_view.cc +++ b/gtk2_ardour/audio_region_view.cc @@ -442,13 +442,13 @@ AudioRegionView::setup_fade_handle_positions() double const handle_height = 5; if (fade_in_handle) { - fade_in_handle->property_y1() = _y_position + handle_pos; - fade_in_handle->property_y2() = _y_position + handle_pos + handle_height; + fade_in_handle->property_y1() = handle_pos; + fade_in_handle->property_y2() = handle_pos + handle_height; } if (fade_out_handle) { - fade_out_handle->property_y1() = _y_position + handle_pos; - fade_out_handle->property_y2() = _y_position + handle_pos + handle_height; + fade_out_handle->property_y1() = handle_pos; + fade_out_handle->property_y2() = handle_pos + handle_height; } } @@ -506,7 +506,7 @@ AudioRegionView::manage_zero_line () } if (_height >= 100) { - double const wave_midpoint = _y_position + (_height - NAME_HIGHLIGHT_SIZE) / 2.0; + double const wave_midpoint = (_height - NAME_HIGHLIGHT_SIZE) / 2.0; zero_line->property_y1() = wave_midpoint; zero_line->property_y2() = wave_midpoint; zero_line->show(); @@ -587,16 +587,16 @@ AudioRegionView::reset_fade_in_shape_width (nframes_t width) for (pi = 0, pc = 0; pc < npoints; ++pc) { (*points)[pi].set_x(1 + (pc * xdelta)); - (*points)[pi++].set_y(_y_position + 2 + (h - (curve[pc] * h))); + (*points)[pi++].set_y(2 + (h - (curve[pc] * h))); } /* fold back */ (*points)[pi].set_x(pwidth); - (*points)[pi++].set_y(_y_position + 2); + (*points)[pi++].set_y(2); (*points)[pi].set_x(1); - (*points)[pi++].set_y(_y_position + 2); + (*points)[pi++].set_y(2); /* connect the dots ... */ @@ -673,16 +673,16 @@ AudioRegionView::reset_fade_out_shape_width (nframes_t width) for (pi = 0, pc = 0; pc < npoints; ++pc) { (*points)[pi].set_x(_pixel_width - 1 - pwidth + (pc*xdelta)); - (*points)[pi++].set_y(_y_position + 2 + (h - (curve[pc] * h))); + (*points)[pi++].set_y(2 + (h - (curve[pc] * h))); } /* fold back */ (*points)[pi].set_x(_pixel_width); - (*points)[pi++].set_y(_y_position + h); + (*points)[pi++].set_y(h); (*points)[pi].set_x(_pixel_width); - (*points)[pi++].set_y(_y_position + 2); + (*points)[pi++].set_y(2); /* connect the dots ... */ diff --git a/gtk2_ardour/audio_region_view.h b/gtk2_ardour/audio_region_view.h index 31c5439079..b8e3370877 100644 --- a/gtk2_ardour/audio_region_view.h +++ b/gtk2_ardour/audio_region_view.h @@ -135,7 +135,6 @@ class AudioRegionView : public RegionView AudioRegionGainLine * gain_line; double _amplitude_above_axis; - double _y_position; uint32_t _flags; uint32_t fade_color; diff --git a/gtk2_ardour/editor.cc b/gtk2_ardour/editor.cc index 778cdd73a6..dd00aabe7d 100644 --- a/gtk2_ardour/editor.cc +++ b/gtk2_ardour/editor.cc @@ -660,10 +660,10 @@ Editor::Editor () region_list_display.append_column (_("M"), region_list_columns.muted); region_list_display.append_column (_("O"), region_list_columns.opaque); region_list_display.append_column (_("Used"), region_list_columns.used); - region_list_display.append_column (_("Path to parent file"), region_list_columns.path); + region_list_display.append_column (_("Path"), region_list_columns.path); region_list_display.set_headers_visible (true); region_list_display.set_grid_lines (TREE_VIEW_GRID_LINES_BOTH); - + CellRendererText* region_name_cell = dynamic_cast(region_list_display.get_column_cell_renderer (0)); region_name_cell->property_editable() = true; region_name_cell->signal_edited().connect (mem_fun (*this, &Editor::region_name_edit)); @@ -699,7 +699,8 @@ Editor::Editor () region_list_display.get_selection()->signal_changed().connect (mem_fun(*this, &Editor::region_list_selection_changed)); // region_list_display.signal_popup_menu().connect (bind (mem_fun (*this, &Editor::show_region_list_display_context_menu), 1, 0)); - ARDOUR_UI::instance()->secondary_clock.mode_changed.connect (mem_fun(*this, &Editor::redisplay_regions)); + //ARDOUR_UI::instance()->secondary_clock.mode_changed.connect (mem_fun(*this, &Editor::redisplay_regions)); + ARDOUR_UI::instance()->secondary_clock.mode_changed.connect (mem_fun(*this, &Editor::update_all_region_rows)); ARDOUR::Region::RegionPropertyChanged.connect (mem_fun(*this, &Editor::update_region_row)); named_selection_scroller.add (named_selection_display); diff --git a/gtk2_ardour/editor.h b/gtk2_ardour/editor.h index eb51fb5beb..6a8d897d01 100644 --- a/gtk2_ardour/editor.h +++ b/gtk2_ardour/editor.h @@ -1108,6 +1108,8 @@ class Editor : public PublicEditor void populate_row (boost::shared_ptr, Gtk::TreeModel::Row const &); void update_region_row (boost::shared_ptr); bool update_region_subrows (boost::shared_ptr, Gtk::TreeModel::Row const &, int); + void update_all_region_rows (); + void update_all_region_subrows (Gtk::TreeModel::Row const &, int); bool no_region_list_redisplay; void insert_into_tmp_regionlist(boost::shared_ptr); diff --git a/gtk2_ardour/editor_region_list.cc b/gtk2_ardour/editor_region_list.cc index 767fc4ec71..a623340d36 100644 --- a/gtk2_ardour/editor_region_list.cc +++ b/gtk2_ardour/editor_region_list.cc @@ -360,6 +360,7 @@ Editor::update_region_row (boost::shared_ptr region) if (!region || !session) { return; } + TreeModel::iterator i; TreeModel::Children rows = region_list_model->children(); @@ -403,16 +404,61 @@ Editor::update_region_subrows (boost::shared_ptr region, TreeModel::Row } if (!(*i).children().empty()) { - if (update_region_subrows(region, (*i), level + 1)) { return true; } - } } return false; } +void +Editor::update_all_region_rows () +{ + if (!session) { + return; + } + + TreeModel::iterator i; + TreeModel::Children rows = region_list_model->children(); + + for (i = rows.begin(); i != rows.end(); ++i) { + + boost::shared_ptr region = (*i)[region_list_columns.region]; + + cerr << "level 1 : Updating " << region->name() << "\n"; + + if (!region->automatic()) { + populate_row(region, (*i)); + } + + if (!(*i).children().empty()) { + update_all_region_subrows((*i), 2); + } + } +} + +void +Editor::update_all_region_subrows (TreeModel::Row const &parent_row, int level) +{ + TreeModel::iterator i; + TreeModel::Children subrows = (*parent_row).children(); + + for (i = subrows.begin(); i != subrows.end(); ++i) { + + boost::shared_ptr region = (*i)[region_list_columns.region]; + + cerr << "level " << level << " : Updating " << region->name() << "\n"; + + if (!region->automatic()) { + populate_row(region, (*i)); + } + + if (!(*i).children().empty()) { + update_all_region_subrows((*i), level + 1); + } + } +} void Editor::populate_row (boost::shared_ptr region, TreeModel::Row const &row) diff --git a/gtk2_ardour/io_selector.cc b/gtk2_ardour/io_selector.cc index 94da96573c..d1ee8be31c 100644 --- a/gtk2_ardour/io_selector.cc +++ b/gtk2_ardour/io_selector.cc @@ -210,6 +210,7 @@ IOSelectorWindow::IOSelectorWindow ( : ArdourDialog ("I/O selector"), _selector (session, io, !for_input), add_button (_("Add Port")), + disconnect_button (_("Disconnect All")), ok_button (can_cancel ? _("OK"): _("Close")), cancel_button (_("Cancel")), rescan_button (_("Rescan")) @@ -218,7 +219,9 @@ IOSelectorWindow::IOSelectorWindow ( add_events (Gdk::KEY_PRESS_MASK | Gdk::KEY_RELEASE_MASK); set_name ("IOSelectorWindow2"); - // io->name_changed.connect (mem_fun(*this, &IOSelectorWindow::io_name_changed)); + disconnect_button.set_name ("IOSelectorButton"); + disconnect_button.set_image (*Gtk::manage (new Gtk::Image (Gtk::Stock::DISCONNECT, Gtk::ICON_SIZE_BUTTON))); + get_action_area()->pack_start (disconnect_button, false, false); if (_selector.maximum_rows() > _selector.n_rows()) { add_button.set_name ("IOSelectorButton"); @@ -254,6 +257,10 @@ IOSelectorWindow::IOSelectorWindow ( get_vbox()->set_spacing (8); get_vbox()->pack_start (_selector); + suggestion.set_alignment (0.5, 0.5); + suggestion_box.pack_start (suggestion, true, true); + get_vbox()->pack_start (suggestion_box); + ok_button.signal_clicked().connect (mem_fun(*this, &IOSelectorWindow::accept)); cancel_button.signal_clicked().connect (mem_fun(*this, &IOSelectorWindow::cancel)); rescan_button.signal_clicked().connect (mem_fun(*this, &IOSelectorWindow::rescan)); @@ -262,10 +269,15 @@ IOSelectorWindow::IOSelectorWindow ( io_name_changed (this); ports_changed (IOChange (0), this); - + leave_scroller ((GdkEventCrossing*) 0); + show_all (); signal_delete_event().connect (bind (sigc::ptr_fun (just_hide_it), this)); + + _selector.scrolled_window().add_events (Gdk::ENTER_NOTIFY_MASK|Gdk::LEAVE_NOTIFY_MASK); + _selector.scrolled_window().signal_enter_notify_event().connect (mem_fun (*this, &IOSelectorWindow::enter_scroller)); + _selector.scrolled_window().signal_leave_notify_event().connect (mem_fun (*this, &IOSelectorWindow::leave_scroller)); } IOSelectorWindow::~IOSelectorWindow() @@ -273,6 +285,22 @@ IOSelectorWindow::~IOSelectorWindow() } +bool +IOSelectorWindow::enter_scroller (GdkEventCrossing* ignored) +{ + cerr << "IN\n"; + suggestion.set_text (_("Click to connect. Ctrl-click to disconnect. Shift-click for cross-connect")); + return false; +} + +bool +IOSelectorWindow::leave_scroller (GdkEventCrossing* ignored) +{ + cerr << "OUT\n"; + suggestion.set_text (_("Right-click on individual port names for per-port operations")); + return false; +} + void IOSelectorWindow::ports_changed (ARDOUR::IOChange change, void *src) { diff --git a/gtk2_ardour/io_selector.h b/gtk2_ardour/io_selector.h index e720a630b3..e2c749935f 100644 --- a/gtk2_ardour/io_selector.h +++ b/gtk2_ardour/io_selector.h @@ -61,16 +61,22 @@ class IOSelectorWindow : public ArdourDialog /* overall operation buttons */ Gtk::Button add_button; + Gtk::Button disconnect_button; Gtk::Button ok_button; Gtk::Button cancel_button; Gtk::Button rescan_button; + Gtk::HBox suggestion_box; + Gtk::Label suggestion; + void rescan (); void cancel (); void accept (); void ports_changed (ARDOUR::IOChange change, void *src); void io_name_changed (void *src); + bool enter_scroller (GdkEventCrossing*); + bool leave_scroller (GdkEventCrossing*); }; diff --git a/gtk2_ardour/port_matrix.cc b/gtk2_ardour/port_matrix.cc index e8297b6193..0decce8d7a 100644 --- a/gtk2_ardour/port_matrix.cc +++ b/gtk2_ardour/port_matrix.cc @@ -171,7 +171,7 @@ PortGroupUI::port_checkbutton_toggled (CheckButton* b, int r, int c) void PortGroupUI::setup_visibility () { - if (_port_group.visible) { + if (!_port_group.ports.empty() && _port_group.visible) { _table_box.show (); } else { _table_box.hide (); @@ -374,25 +374,30 @@ PortMatrix::PortMatrix (ARDOUR::Session& session, ARDOUR::DataType type, bool of : _offer_inputs (offer_inputs), _port_group_list (session, type, offer_inputs, mask), _type (type), _column_labels (_port_group_list) { - _row_labels_vbox[0] = _row_labels_vbox[1] = 0; - _side_vbox_pad[0] = _side_vbox_pad[1] = 0; + _row_labels_vbox = 0; + _side_vbox_pad = 0; _visibility_checkbutton_box.pack_start (*(manage (new Label (_("Connections displayed: ")))), false, false, 10); pack_start (_visibility_checkbutton_box, false, false); - _side_vbox[0].pack_start (*manage (new Label (""))); - _overall_hbox.pack_start (_side_vbox[0], false, false); - _scrolled_window.set_policy (POLICY_ALWAYS, POLICY_NEVER); + _side_vbox.pack_start (*manage (new Label (""))); + _scrolled_window.set_policy (POLICY_ALWAYS, POLICY_AUTOMATIC); _scrolled_window.set_shadow_type (SHADOW_NONE); - VBox* b = new VBox; + VBox* b = manage (new VBox); b->pack_start (_column_labels, false, false); b->pack_start (_port_group_hbox, false, false); - Alignment* a = new Alignment (0, 1, 0, 0); - a->add (*manage (b)); - _scrolled_window.add (*manage (a)); - _overall_hbox.pack_start (_scrolled_window); - _side_vbox[1].pack_start (*manage (new Label (""))); - // _overall_hbox.pack_start (_side_vbox[1]); + Alignment* a = manage (new Alignment (0, 1, 0, 0)); + a->add (*b); + _scrolled_window.add (*a); + + if (offer_inputs) { + _overall_hbox.pack_start (_side_vbox, false, false, 10); + _overall_hbox.pack_start (_scrolled_window, true, true); + } else { + _overall_hbox.pack_start (_scrolled_window, true, true, 10); + _overall_hbox.pack_start (_side_vbox, false, false); + } + pack_start (_overall_hbox); _port_group_hbox.signal_size_allocate().connect (sigc::hide (sigc::mem_fun (*this, &IOSelector::setup_dimensions))); @@ -407,25 +412,22 @@ PortMatrix::~PortMatrix () void PortMatrix::clear () { - for (int i = 0; i < 2; ++i) { - - for (std::vector::iterator j = _row_labels[i].begin(); j != _row_labels[i].end(); ++j) { - delete *j; - } - _row_labels[i].clear (); - - if (_row_labels_vbox[i]) { - _side_vbox[i].remove (*_row_labels_vbox[i]); - } - delete _row_labels_vbox[i]; - _row_labels_vbox[i] = 0; - - if (_side_vbox_pad[i]) { - _side_vbox[i].remove (*_side_vbox_pad[i]); - } - delete _side_vbox_pad[i]; - _side_vbox_pad[i] = 0; + for (std::vector::iterator j = _row_labels.begin(); j != _row_labels.end(); ++j) { + delete *j; } + _row_labels.clear (); + + if (_row_labels_vbox) { + _side_vbox.remove (*_row_labels_vbox); + } + delete _row_labels_vbox; + _row_labels_vbox = 0; + + if (_side_vbox_pad) { + _side_vbox.remove (*_side_vbox_pad); + } + delete _side_vbox_pad; + _side_vbox_pad = 0; for (std::vector::iterator i = _port_group_ui.begin(); i != _port_group_ui.end(); ++i) { _port_group_hbox.remove ((*i)->get_table()); @@ -462,21 +464,24 @@ PortMatrix::setup_dimensions () /* Scrolled window */ /* XXX: really shouldn't set a minimum horizontal size here, but if we don't - the window starts up very small */ + the window starts up very small. + The constant value in the set_size_request() computation will control + how big the scrolled window will be if we fill the port matrix will a gajillion + ports. + */ + _scrolled_window.set_size_request ( - std::min (_column_labels.get_width(), 640), + std::min (_column_labels.get_width(), 400), _column_labels.get_height() + port_group_tables_height + scrollbar_height + 16 ); /* Row labels */ - for (int i = 0; i < 2; ++i) { - for (std::vector::iterator j = _row_labels[i].begin(); j != _row_labels[i].end(); ++j) { - (*j)->get_child()->set_size_request (-1, unit_size.second); - } - - if (_side_vbox_pad[i]) { - _side_vbox_pad[i]->set_size_request (-1, scrollbar_height + unit_size.second / 4); - } + for (std::vector::iterator j = _row_labels.begin(); j != _row_labels.end(); ++j) { + (*j)->get_child()->set_size_request (-1, unit_size.second); + } + + if (_side_vbox_pad) { + _side_vbox_pad->set_size_request (-1, scrollbar_height + unit_size.second / 4); } } @@ -490,35 +495,35 @@ PortMatrix::setup () int const rows = n_rows (); /* Row labels */ - for (int i = 0; i < 2; ++i) { - _row_labels_vbox[i] = new VBox; - int const run_rows = std::max (1, rows); - for (int j = 0; j < run_rows; ++j) { - /* embolden the port/channel name */ + _row_labels_vbox = new VBox; + int const run_rows = std::max (1, rows); - string s = ""; - s += row_name (j); - s += ""; - - Label* label = manage (new Label (s)); - EventBox* b = manage (new EventBox); - - label->set_use_markup (true); - - b->set_events (Gdk::BUTTON_PRESS_MASK); - b->signal_button_press_event().connect (sigc::bind (sigc::mem_fun (*this, &IOSelector::row_label_button_pressed), j)); - b->add (*label); - - _row_labels[i].push_back (b); - _row_labels_vbox[i]->pack_start (*b, false, false); - } - - _side_vbox[i].pack_start (*_row_labels_vbox[i], false, false); - _side_vbox_pad[i] = new Label (""); - _side_vbox[i].pack_start (*_side_vbox_pad[i], false, false); + for (int j = 0; j < run_rows; ++j) { + + /* embolden the port/channel name */ + + string s = ""; + s += row_name (j); + s += ""; + + Label* label = manage (new Label (s)); + EventBox* b = manage (new EventBox); + + label->set_use_markup (true); + + b->set_events (Gdk::BUTTON_PRESS_MASK); + b->signal_button_press_event().connect (sigc::bind (sigc::mem_fun (*this, &IOSelector::row_label_button_pressed), j)); + b->add (*label); + + _row_labels.push_back (b); + _row_labels_vbox->pack_start (*b, false, false); } + _side_vbox.pack_start (*_row_labels_vbox, false, false); + _side_vbox_pad = new Label (""); + _side_vbox.pack_start (*_side_vbox_pad, false, false); + /* Checkbutton tables and visibility checkbuttons */ for (PortGroupList::iterator i = _port_group_list.begin(); i != _port_group_list.end(); ++i) { diff --git a/gtk2_ardour/port_matrix.h b/gtk2_ardour/port_matrix.h index dc863ad26b..7f4eed23fb 100644 --- a/gtk2_ardour/port_matrix.h +++ b/gtk2_ardour/port_matrix.h @@ -174,6 +174,8 @@ class PortMatrix : public Gtk::VBox { virtual void remove_row (int) = 0; virtual std::string row_descriptor () const = 0; + Gtk::Widget& scrolled_window() { return _scrolled_window; } + protected: bool _offer_inputs; @@ -182,14 +184,14 @@ class PortMatrix : public Gtk::VBox { PortGroupList _port_group_list; ARDOUR::DataType _type; std::vector _port_group_ui; - std::vector _row_labels[2]; - Gtk::VBox* _row_labels_vbox[2]; + std::vector _row_labels; + Gtk::VBox* _row_labels_vbox; RotatedLabelSet _column_labels; Gtk::HBox _overall_hbox; - Gtk::VBox _side_vbox[2]; + Gtk::VBox _side_vbox; Gtk::HBox _port_group_hbox; Gtk::ScrolledWindow _scrolled_window; - Gtk::Label* _side_vbox_pad[2]; + Gtk::Label* _side_vbox_pad; Gtk::HBox _visibility_checkbutton_box; void setup ();