X-Git-Url: https://main.carlh.net/gitweb/?a=blobdiff_plain;f=gtk2_ardour%2Feditor_routes.cc;h=714c5faad92a2da2363ef3507259fb47fc81006a;hb=80972784e348aa51522e562b3d6b250745c489f0;hp=1368979e5896ef313775fb2f61437db3011747e5;hpb=13232d03f3e5f8a5d7d19392c26c27ce0327250c;p=ardour.git diff --git a/gtk2_ardour/editor_routes.cc b/gtk2_ardour/editor_routes.cc index 1368979e58..714c5faad9 100644 --- a/gtk2_ardour/editor_routes.cc +++ b/gtk2_ardour/editor_routes.cc @@ -68,6 +68,8 @@ EditorRoutes::EditorRoutes (Editor* e) , selection_countdown (0) , name_editable (0) { + static const int column_width = 22; + _scroller.add (_display); _scroller.set_policy (POLICY_NEVER, POLICY_AUTOMATIC); @@ -77,25 +79,43 @@ EditorRoutes::EditorRoutes (Editor* e) // Record enable toggle CellRendererPixbufMulti* rec_col_renderer = manage (new CellRendererPixbufMulti()); - rec_col_renderer->set_pixbuf (0, ::get_icon("act-disabled")); - rec_col_renderer->set_pixbuf (1, ::get_icon("rec-in-progress")); - rec_col_renderer->set_pixbuf (2, ::get_icon("rec-enabled")); - rec_col_renderer->set_pixbuf (3, ::get_icon("step-editing")); + rec_col_renderer->set_pixbuf (0, ::get_icon("record-normal-disabled")); + rec_col_renderer->set_pixbuf (1, ::get_icon("record-normal-in-progress")); + rec_col_renderer->set_pixbuf (2, ::get_icon("record-normal-enabled")); + rec_col_renderer->set_pixbuf (3, ::get_icon("record-step")); rec_col_renderer->signal_changed().connect (sigc::mem_fun (*this, &EditorRoutes::on_tv_rec_enable_changed)); TreeViewColumn* rec_state_column = manage (new TreeViewColumn("R", *rec_col_renderer)); rec_state_column->add_attribute(rec_col_renderer->property_state(), _columns.rec_state); rec_state_column->add_attribute(rec_col_renderer->property_visible(), _columns.is_track); + rec_state_column->set_sizing(TREE_VIEW_COLUMN_FIXED); rec_state_column->set_alignment(ALIGN_CENTER); rec_state_column->set_expand(false); - rec_state_column->set_fixed_width(15); + rec_state_column->set_fixed_width(column_width); + + // MIDI Input Active + + CellRendererPixbufMulti* input_active_col_renderer = manage (new CellRendererPixbufMulti()); + input_active_col_renderer->set_pixbuf (0, ::get_icon("midi-input-inactive")); + input_active_col_renderer->set_pixbuf (1, ::get_icon("midi-input-active")); + input_active_col_renderer->signal_changed().connect (sigc::mem_fun (*this, &EditorRoutes::on_input_active_changed)); + + TreeViewColumn* input_active_column = manage (new TreeViewColumn ("I", *input_active_col_renderer)); + + input_active_column->add_attribute(input_active_col_renderer->property_state(), _columns.is_input_active); + input_active_column->add_attribute (input_active_col_renderer->property_visible(), _columns.is_midi); + + input_active_column->set_sizing(TREE_VIEW_COLUMN_FIXED); + input_active_column->set_alignment(ALIGN_CENTER); + input_active_column->set_expand(false); + input_active_column->set_fixed_width(column_width); // Mute enable toggle CellRendererPixbufMulti* mute_col_renderer = manage (new CellRendererPixbufMulti()); - mute_col_renderer->set_pixbuf (0, ::get_icon("act-disabled")); + mute_col_renderer->set_pixbuf (0, ::get_icon("mute-disabled")); mute_col_renderer->set_pixbuf (1, ::get_icon("muted-by-others")); mute_col_renderer->set_pixbuf (2, ::get_icon("mute-enabled")); mute_col_renderer->signal_changed().connect (sigc::mem_fun (*this, &EditorRoutes::on_tv_mute_enable_toggled)); @@ -111,7 +131,7 @@ EditorRoutes::EditorRoutes (Editor* e) // Solo enable toggle CellRendererPixbufMulti* solo_col_renderer = manage (new CellRendererPixbufMulti()); - solo_col_renderer->set_pixbuf (0, ::get_icon("act-disabled")); + solo_col_renderer->set_pixbuf (0, ::get_icon("solo-disabled")); solo_col_renderer->set_pixbuf (1, ::get_icon("solo-enabled")); solo_col_renderer->set_pixbuf (3, ::get_icon("soloed-by-others")); solo_col_renderer->signal_changed().connect (sigc::mem_fun (*this, &EditorRoutes::on_tv_solo_enable_toggled)); @@ -122,13 +142,13 @@ EditorRoutes::EditorRoutes (Editor* e) solo_state_column->set_sizing(TREE_VIEW_COLUMN_FIXED); solo_state_column->set_alignment(ALIGN_CENTER); solo_state_column->set_expand(false); - solo_state_column->set_fixed_width(15); + solo_state_column->set_fixed_width(column_width); // Solo isolate toggle CellRendererPixbufMulti* solo_iso_renderer = manage (new CellRendererPixbufMulti()); - solo_iso_renderer->set_pixbuf (0, ::get_icon("act-disabled")); - solo_iso_renderer->set_pixbuf (1, ::get_icon("solo-isolated")); + solo_iso_renderer->set_pixbuf (0, ::get_icon("solo-isolate-disabled")); + solo_iso_renderer->set_pixbuf (1, ::get_icon("solo-isolate-enabled")); solo_iso_renderer->signal_changed().connect (sigc::mem_fun (*this, &EditorRoutes::on_tv_solo_isolate_toggled)); TreeViewColumn* solo_isolate_state_column = manage (new TreeViewColumn("SI", *solo_iso_renderer)); @@ -137,13 +157,13 @@ EditorRoutes::EditorRoutes (Editor* e) solo_isolate_state_column->set_sizing(TREE_VIEW_COLUMN_FIXED); solo_isolate_state_column->set_alignment(ALIGN_CENTER); solo_isolate_state_column->set_expand(false); - solo_isolate_state_column->set_fixed_width(22); + solo_isolate_state_column->set_fixed_width(column_width); // Solo safe toggle CellRendererPixbufMulti* solo_safe_renderer = manage (new CellRendererPixbufMulti ()); - solo_safe_renderer->set_pixbuf (0, ::get_icon("act-disabled")); - solo_safe_renderer->set_pixbuf (1, ::get_icon("solo-enabled")); + solo_safe_renderer->set_pixbuf (0, ::get_icon("solo-safe-disabled")); + solo_safe_renderer->set_pixbuf (1, ::get_icon("solo-safe-enabled")); solo_safe_renderer->signal_changed().connect (sigc::mem_fun (*this, &EditorRoutes::on_tv_solo_safe_toggled)); TreeViewColumn* solo_safe_state_column = manage (new TreeViewColumn(_("SS"), *solo_safe_renderer)); @@ -151,19 +171,18 @@ EditorRoutes::EditorRoutes (Editor* e) solo_safe_state_column->set_sizing(TREE_VIEW_COLUMN_FIXED); solo_safe_state_column->set_alignment(ALIGN_CENTER); solo_safe_state_column->set_expand(false); - solo_safe_state_column->set_fixed_width(22); + solo_safe_state_column->set_fixed_width(column_width); + _display.append_column (*input_active_column); _display.append_column (*rec_state_column); _display.append_column (*mute_state_column); _display.append_column (*solo_state_column); _display.append_column (*solo_isolate_state_column); _display.append_column (*solo_safe_state_column); - - int colnum = _display.append_column (_("Name"), _columns.text); - TreeViewColumn* c = _display.get_column (colnum-1); - c->set_data ("i_am_the_tab_column", (void*) 0xfeedface); - _display.append_column (_("V"), _columns.visible); - + + _name_column = _display.append_column (_("Name"), _columns.text) - 1; + _visible_column = _display.append_column (_("V"), _columns.visible) - 1; + _display.set_headers_visible (true); _display.set_name ("TrackListDisplay"); _display.get_selection()->set_mode (SELECTION_SINGLE); @@ -173,12 +192,12 @@ EditorRoutes::EditorRoutes (Editor* e) _display.set_size_request (100, -1); _display.add_object_drag (_columns.route.index(), "routes"); - CellRendererText* name_cell = dynamic_cast (_display.get_column_cell_renderer (5)); + CellRendererText* name_cell = dynamic_cast (_display.get_column_cell_renderer (_name_column)); assert (name_cell); name_cell->signal_editing_started().connect (sigc::mem_fun (*this, &EditorRoutes::name_edit_started)); - TreeViewColumn* name_column = _display.get_column (5); + TreeViewColumn* name_column = _display.get_column (_name_column); assert (name_column); @@ -191,21 +210,21 @@ EditorRoutes::EditorRoutes (Editor* e) name_cell->signal_edited().connect (sigc::mem_fun (*this, &EditorRoutes::name_edit)); // Set the visible column cell renderer to radio toggle - CellRendererToggle* visible_cell = dynamic_cast (_display.get_column_cell_renderer (6)); + CellRendererToggle* visible_cell = dynamic_cast (_display.get_column_cell_renderer (_visible_column)); visible_cell->property_activatable() = true; visible_cell->property_radio() = false; visible_cell->signal_toggled().connect (sigc::mem_fun (*this, &EditorRoutes::visible_changed)); - - TreeViewColumn* visible_col = dynamic_cast (_display.get_column (6)); + + TreeViewColumn* visible_col = dynamic_cast (_display.get_column (_visible_column)); visible_col->set_expand(false); visible_col->set_sizing(TREE_VIEW_COLUMN_FIXED); visible_col->set_fixed_width(30); visible_col->set_alignment(ALIGN_CENTER); - + _model->signal_row_deleted().connect (sigc::mem_fun (*this, &EditorRoutes::route_deleted)); _model->signal_rows_reordered().connect (sigc::mem_fun (*this, &EditorRoutes::reordered)); - + _display.signal_button_press_event().connect (sigc::mem_fun (*this, &EditorRoutes::button_press), false); _scroller.signal_key_press_event().connect (sigc::mem_fun(*this, &EditorRoutes::key_press), false); @@ -254,8 +273,8 @@ EditorRoutes::enter_notify (GdkEventCrossing*) if (name_editable) { return true; } - - /* arm counter so that ::selection_filter() will deny selecting anything for the + + /* arm counter so that ::selection_filter() will deny selecting anything for the next two attempts to change selection status. */ selection_countdown = 2; @@ -291,6 +310,24 @@ EditorRoutes::set_session (Session* s) } } +void +EditorRoutes::on_input_active_changed (std::string const & path_string) +{ + // Get the model row that has been toggled. + Gtk::TreeModel::Row row = *_model->get_iter (Gtk::TreeModel::Path (path_string)); + + TimeAxisView* tv = row[_columns.tv]; + RouteTimeAxisView *rtv = dynamic_cast (tv); + + if (rtv) { + boost::shared_ptr mt; + mt = rtv->midi_track(); + if (mt) { + mt->set_input_active (!mt->input_active()); + } + } +} + void EditorRoutes::on_tv_rec_enable_changed (std::string const & path_string) { @@ -315,7 +352,7 @@ EditorRoutes::on_tv_mute_enable_toggled (std::string const & path_string) TimeAxisView *tv = row[_columns.tv]; RouteTimeAxisView *rtv = dynamic_cast (tv); - + if (rtv != 0) { boost::shared_ptr rl (new RouteList); rl->push_back (rtv->route()); @@ -431,22 +468,19 @@ EditorRoutes::redisplay () route->set_order_key (N_ ("editor"), n); } - bool visible = (*i)[_columns.visible]; + bool visible = tv->marked_for_display (); /* show or hide the TimeAxisView */ if (visible) { - tv->set_marked_for_display (true); position += tv->show_at (position, n, &_editor->edit_controls_vbox); tv->clip_to_viewport (); } else { - tv->set_marked_for_display (false); tv->hide (); } n++; } - /* whenever we go idle, update the track view list to reflect the new order. we can't do this here, because we could mess up something that is traversing the track order and has caused a redisplay of the list. @@ -477,7 +511,7 @@ EditorRoutes::route_deleted (Gtk::TreeModel::Path const &) if (!_session || _session->deletion_in_progress()) { return; } - + /* this could require an order reset & sync */ _session->set_remote_control_ids(); _ignore_reorder = true; @@ -498,14 +532,16 @@ EditorRoutes::visible_changed (std::string const & path) TimeAxisView* tv = (*iter)[_columns.tv]; if (tv) { bool visible = (*iter)[_columns.visible]; - (*iter)[_columns.visible] = !visible; + + if (tv->set_marked_for_display (!visible)) { + _redisplay_does_not_reset_order_keys = true; + _session->set_remote_control_ids(); + update_visibility (); + redisplay (); + _redisplay_does_not_reset_order_keys = false; + } } } - - _redisplay_does_not_reset_order_keys = true; - _session->set_remote_control_ids(); - redisplay (); - _redisplay_does_not_reset_order_keys = false; } void @@ -518,6 +554,8 @@ EditorRoutes::routes_added (list routes) for (list::iterator x = routes.begin(); x != routes.end(); ++x) { + boost::shared_ptr midi_trk = boost::dynamic_pointer_cast ((*x)->route()); + row = *(_model->append ()); row[_columns.text] = (*x)->route()->name(); @@ -525,6 +563,15 @@ EditorRoutes::routes_added (list routes) row[_columns.tv] = *x; row[_columns.route] = (*x)->route (); row[_columns.is_track] = (boost::dynamic_pointer_cast ((*x)->route()) != 0); + + if (midi_trk) { + row[_columns.is_input_active] = midi_trk->input_active (); + row[_columns.is_midi] = true; + } else { + row[_columns.is_input_active] = false; + row[_columns.is_midi] = false; + } + row[_columns.mute_state] = (*x)->route()->muted(); row[_columns.solo_state] = RouteUI::solo_visual_state ((*x)->route()); row[_columns.solo_isolate_state] = (*x)->route()->solo_isolated(); @@ -553,6 +600,7 @@ EditorRoutes::routes_added (list routes) if ((*x)->is_midi_track()) { boost::shared_ptr t = boost::dynamic_pointer_cast ((*x)->route()); t->StepEditStatusChange.connect (*this, MISSING_INVALIDATOR, boost::bind (&EditorRoutes::update_rec_display, this), gui_context()); + t->InputActiveChanged.connect (*this, MISSING_INVALIDATOR, boost::bind (&EditorRoutes::update_input_active_display, this), gui_context()); } (*x)->route()->mute_changed.connect (*this, MISSING_INVALIDATOR, boost::bind (&EditorRoutes::update_mute_display, this), gui_context()); @@ -567,6 +615,7 @@ EditorRoutes::routes_added (list routes) update_solo_display (true); update_solo_isolate_display (); update_solo_safe_display (); + update_input_active_display (); resume_redisplay (); _redisplay_does_not_sync_order_keys = false; } @@ -651,7 +700,6 @@ EditorRoutes::update_visibility () for (i = rows.begin(); i != rows.end(); ++i) { TimeAxisView *tv = (*i)[_columns.tv]; (*i)[_columns.visible] = tv->marked_for_display (); - cerr << "marked " << tv->name() << " for display = " << tv->marked_for_display() << endl; } resume_redisplay (); @@ -665,12 +713,12 @@ EditorRoutes::hide_track_in_display (TimeAxisView& tv) for (i = rows.begin(); i != rows.end(); ++i) { if ((*i)[_columns.tv] == &tv) { + tv.set_marked_for_display (false); (*i)[_columns.visible] = false; + redisplay (); break; } } - - redisplay (); } void @@ -679,14 +727,15 @@ EditorRoutes::show_track_in_display (TimeAxisView& tv) TreeModel::Children rows = _model->children(); TreeModel::Children::iterator i; + for (i = rows.begin(); i != rows.end(); ++i) { if ((*i)[_columns.tv] == &tv) { + tv.set_marked_for_display (true); (*i)[_columns.visible] = true; + redisplay (); break; } } - - redisplay (); } void @@ -701,7 +750,7 @@ EditorRoutes::reordered (TreeModel::Path const &, TreeModel::iterator const &, i void EditorRoutes::sync_order_keys (string const & src) { - vector neworder; + map new_order; TreeModel::Children rows = _model->children(); TreeModel::Children::iterator ri; @@ -709,20 +758,16 @@ EditorRoutes::sync_order_keys (string const & src) return; } - for (ri = rows.begin(); ri != rows.end(); ++ri) { - neworder.push_back (0); - } - bool changed = false; int order; for (order = 0, ri = rows.begin(); ri != rows.end(); ++ri, ++order) { boost::shared_ptr route = (*ri)[_columns.route]; - int old_key = order; - int new_key = route->order_key (N_ ("editor")); + int const old_key = order; + int const new_key = route->order_key (N_ ("editor")); - neworder[new_key] = old_key; + new_order[new_key] = old_key; if (new_key != old_key) { changed = true; @@ -731,7 +776,16 @@ EditorRoutes::sync_order_keys (string const & src) if (changed) { _redisplay_does_not_reset_order_keys = true; - _model->reorder (neworder); + + /* `compact' new_order into a vector */ + vector co; + for (map::const_iterator i = new_order.begin(); i != new_order.end(); ++i) { + co.push_back (i->second); + } + + assert (co.size() == _model->children().size ()); + + _model->reorder (co); _redisplay_does_not_reset_order_keys = false; } } @@ -798,13 +852,13 @@ EditorRoutes::set_all_audio_midi_visibility (int tracks, bool yn) suspend_redisplay (); for (i = rows.begin(); i != rows.end(); ++i) { - + TreeModel::Row row = (*i); TimeAxisView* tv = row[_columns.tv]; - + AudioTimeAxisView* atv; MidiTimeAxisView* mtv; - + if (tv == 0) { continue; } @@ -907,9 +961,9 @@ EditorRoutes::key_press (GdkEventKey* ev) if (name_editable) { name_editable->editing_done (); name_editable = 0; - } + } - col = _display.get_column (5); // select&focus on name column + col = _display.get_column (_name_column); // select&focus on name column if (Keyboard::modifier_state_equals (ev->state, Keyboard::TertiaryModifier)) { treeview_select_previous (_display, _model, col); @@ -999,35 +1053,35 @@ EditorRoutes::button_press (GdkEventButton* ev) show_menu (); return true; } - + //Scroll editor canvas to selected track if (Keyboard::modifier_state_equals (ev->state, Keyboard::PrimaryModifier)) { - + TreeModel::Path path; TreeViewColumn *tvc; int cell_x; int cell_y; - + _display.get_path_at_pos ((int) ev->x, (int) ev->y, path, tvc, cell_x, cell_y); // Get the model row. Gtk::TreeModel::Row row = *_model->get_iter (path); - + TimeAxisView *tv = row[_columns.tv]; - + int y_pos = tv->y_position(); - + //Clamp the y pos so that we do not extend beyond the canvas full height. if (_editor->full_canvas_height - y_pos < _editor->_canvas_height){ y_pos = _editor->full_canvas_height - _editor->_canvas_height; } - + //Only scroll to if the track is visible if(y_pos != -1){ _editor->reset_y_origin (y_pos); } } - + return false; } @@ -1233,6 +1287,25 @@ EditorRoutes::move_selected_tracks (bool up) _session->sync_order_keys (N_ ("editor")); } +void +EditorRoutes::update_input_active_display () +{ + TreeModel::Children rows = _model->children(); + TreeModel::Children::iterator i; + + for (i = rows.begin(); i != rows.end(); ++i) { + boost::shared_ptr route = (*i)[_columns.route]; + + if (boost::dynamic_pointer_cast (route)) { + boost::shared_ptr mt = boost::dynamic_pointer_cast (route); + + if (mt) { + (*i)[_columns.is_input_active] = mt->input_active(); + } + } + } +} + void EditorRoutes::update_rec_display () { @@ -1256,7 +1329,7 @@ EditorRoutes::update_rec_display () } else { (*i)[_columns.rec_state] = 0; } - + (*i)[_columns.name_editable] = !route->record_enabled (); } } @@ -1381,7 +1454,7 @@ EditorRoutes::show_tracks_with_regions_at_playhead () } suspend_redisplay (); - + TreeModel::Children rows = _model->children (); for (TreeModel::Children::iterator i = rows.begin(); i != rows.end(); ++i) { TimeAxisView* tv = (*i)[_columns.tv];