X-Git-Url: https://main.carlh.net/gitweb/?a=blobdiff_plain;f=gtk2_ardour%2Froute_time_axis.cc;h=e6a8f59be093fbf4299e5ae0783475d249a3a700;hb=471570705d58ee88f852009fee18f51562c34292;hp=11c0893a62c5957ec23d9bb980f107106e727148;hpb=592bfa3616678838bb80b925d66fbadae2d20d7e;p=ardour.git diff --git a/gtk2_ardour/route_time_axis.cc b/gtk2_ardour/route_time_axis.cc index 11c0893a62..e6a8f59be0 100644 --- a/gtk2_ardour/route_time_axis.cc +++ b/gtk2_ardour/route_time_axis.cc @@ -43,32 +43,24 @@ #include #include "ardour/amp.h" -#include "ardour/audioplaylist.h" -#include "ardour/diskstream.h" +#include "ardour/meter.h" #include "ardour/event_type_map.h" -#include "ardour/ladspa_plugin.h" -#include "ardour/location.h" -#include "ardour/panner.h" -#include "ardour/playlist.h" -#include "ardour/playlist.h" #include "ardour/processor.h" #include "ardour/profile.h" -#include "ardour/region_factory.h" #include "ardour/route_group.h" #include "ardour/session.h" -#include "ardour/session_playlist.h" -#include "ardour/debug.h" -#include "ardour/utils.h" +#include "ardour/session_playlists.h" + #include "evoral/Parameter.hpp" +#include "canvas/debug.h" + #include "ardour_ui.h" #include "ardour_button.h" #include "debug.h" #include "global_signals.h" #include "route_time_axis.h" #include "automation_time_axis.h" -#include "canvas_impl.h" -#include "crossfade_view.h" #include "enums.h" #include "gui_thread.h" #include "keyboard.h" @@ -79,7 +71,6 @@ #include "region_view.h" #include "rgb_macros.h" #include "selection.h" -#include "simplerect.h" #include "streamview.h" #include "utils.h" #include "route_group_menu.h" @@ -89,23 +80,15 @@ #include "i18n.h" using namespace ARDOUR; +using namespace ARDOUR_UI_UTILS; using namespace PBD; using namespace Gtkmm2ext; using namespace Gtk; using namespace Editing; using namespace std; +using std::list; -Glib::RefPtr RouteTimeAxisView::slider; - -void -RouteTimeAxisView::setup_slider_pix () -{ - if ((slider = ::get_icon ("fader_belt_h")) == 0) { - throw failed_constructor (); - } -} - -RouteTimeAxisView::RouteTimeAxisView (PublicEditor& ed, Session* sess, Canvas& canvas) +RouteTimeAxisView::RouteTimeAxisView (PublicEditor& ed, Session* sess, ArdourCanvas::Canvas& canvas) : AxisView(sess) , RouteUI(sess) , TimeAxisView(sess,ed,(TimeAxisView*) 0, canvas) @@ -122,18 +105,33 @@ RouteTimeAxisView::RouteTimeAxisView (PublicEditor& ed, Session* sess, Canvas& c , playlist_action_menu (0) , mode_menu (0) , color_mode_menu (0) - , gm (sess, slider, true, 115) + , gm (sess, true, 125, 18) + , _ignore_set_layer_display (false) { + number_label.set_corner_radius(2); + number_label.set_name("tracknumber label"); + number_label.set_alignment(.5, .5); + + sess->config.ParameterChanged.connect (*this, invalidator (*this), boost::bind (&RouteTimeAxisView::parameter_changed, this, _1), gui_context()); } void RouteTimeAxisView::set_route (boost::shared_ptr rt) { RouteUI::set_route (rt); - + + CANVAS_DEBUG_NAME (_canvas_display, string_compose ("main for %1", rt->name())); + CANVAS_DEBUG_NAME (selection_group, string_compose ("selections for %1", rt->name())); + CANVAS_DEBUG_NAME (_ghost_group, string_compose ("ghosts for %1", rt->name())); + + int meter_width = 3; + if (_route && _route->shared_peak_meter()->input_streams().n_total() == 1) { + meter_width = 6; + } gm.set_controls (_route, _route->shared_peak_meter(), _route->amp()); gm.get_level_meter().set_no_show_all(); - gm.get_level_meter().setup_meters(50); + gm.get_level_meter().setup_meters(50, meter_width); + gm.update_gain_sensitive (); string str = gui_property ("height"); if (!str.empty()) { @@ -142,7 +140,7 @@ RouteTimeAxisView::set_route (boost::shared_ptr rt) set_height (preset_height (HeightNormal)); } - if (!_route->is_hidden()) { + if (!_route->is_auditioner()) { if (gui_property ("visible").empty()) { set_gui_property ("visible", true); } @@ -158,50 +156,57 @@ RouteTimeAxisView::set_route (boost::shared_ptr rt) ignore_toggle = false; - route_group_button.set_name ("TrackGroupButton"); - playlist_button.set_name ("TrackPlaylistButton"); - automation_button.set_name ("TrackAutomationButton"); - - route_group_button.unset_flags (Gtk::CAN_FOCUS); - playlist_button.unset_flags (Gtk::CAN_FOCUS); - automation_button.unset_flags (Gtk::CAN_FOCUS); + route_group_button.set_name ("route button"); + playlist_button.set_name ("route button"); + automation_button.set_name ("route button"); route_group_button.signal_button_release_event().connect (sigc::mem_fun(*this, &RouteTimeAxisView::route_group_click), false); - playlist_button.signal_clicked().connect (sigc::mem_fun(*this, &RouteTimeAxisView::playlist_click)); - automation_button.signal_clicked().connect (sigc::mem_fun(*this, &RouteTimeAxisView::automation_click)); + playlist_button.signal_clicked.connect (sigc::mem_fun(*this, &RouteTimeAxisView::playlist_click)); + automation_button.signal_clicked.connect (sigc::mem_fun(*this, &RouteTimeAxisView::automation_click)); if (is_track()) { /* use icon */ - - rec_enable_button->remove (); - + switch (track()->mode()) { case ARDOUR::Normal: case ARDOUR::NonLayered: - rec_enable_button->add (*(manage (new Image (::get_icon (X_("record_normal_red")))))); + rec_enable_button->set_image (::get_icon (X_("record_normal_red"))); break; case ARDOUR::Destructive: - rec_enable_button->add (*(manage (new Image (::get_icon (X_("record_tape_red")))))); + rec_enable_button->set_image (::get_icon (X_("record_tape_red"))); break; } - rec_enable_button->show_all (); controls_table.attach (*rec_enable_button, 5, 6, 0, 1, Gtk::FILL|Gtk::EXPAND, Gtk::FILL|Gtk::EXPAND, 0, 0); if (is_midi_track()) { ARDOUR_UI::instance()->set_tip(*rec_enable_button, _("Record (Right-click for Step Edit)")); + gm.set_fader_name ("MidiTrackFader"); } else { ARDOUR_UI::instance()->set_tip(*rec_enable_button, _("Record")); + gm.set_fader_name ("AudioTrackFader"); } rec_enable_button->set_sensitive (_session->writable()); + + /* set playlist button tip to the current playlist, and make it update when it changes */ + update_playlist_tip (); + track()->PlaylistChanged.connect (*this, invalidator (*this), ui_bind(&RouteTimeAxisView::update_playlist_tip, this), gui_context()); + + } else { + gm.set_fader_name ("AudioBusFader"); } - - controls_hbox.pack_start(gm.get_level_meter(), false, false); + + Gtk::VBox *mtrbox = manage(new Gtk::VBox()); + mtrbox->pack_start(gm.get_level_meter(), false, false, 2); + controls_hbox.pack_start(*mtrbox, false, false, 4); + mtrbox->show(); + _route->meter_change.connect (*this, invalidator (*this), bind (&RouteTimeAxisView::meter_changed, this), gui_context()); - _route->input()->changed.connect (*this, invalidator (*this), ui_bind (&RouteTimeAxisView::io_changed, this, _1, _2), gui_context()); - _route->output()->changed.connect (*this, invalidator (*this), ui_bind (&RouteTimeAxisView::io_changed, this, _1, _2), gui_context()); + _route->input()->changed.connect (*this, invalidator (*this), boost::bind (&RouteTimeAxisView::io_changed, this, _1, _2), gui_context()); + _route->output()->changed.connect (*this, invalidator (*this), boost::bind (&RouteTimeAxisView::io_changed, this, _1, _2), gui_context()); + _route->track_number_changed.connect (*this, invalidator (*this), boost::bind (&RouteTimeAxisView::label_view, this), gui_context()); controls_table.attach (*mute_button, 6, 7, 0, 1, Gtk::FILL|Gtk::EXPAND, Gtk::FILL|Gtk::EXPAND, 0, 0); @@ -209,27 +214,36 @@ RouteTimeAxisView::set_route (boost::shared_ptr rt) controls_table.attach (*solo_button, 7, 8, 0, 1, Gtk::FILL|Gtk::EXPAND, Gtk::FILL|Gtk::EXPAND, 0, 0); } - controls_table.attach (route_group_button, 7, 8, 1, 2, Gtk::FILL|Gtk::EXPAND, Gtk::FILL|Gtk::EXPAND, 0, 0); - controls_table.attach (gm.get_gain_slider(), 0, 5, 1, 2, Gtk::SHRINK, Gtk::SHRINK, 0, 0); + if (!ARDOUR::Profile->get_trx()) { + controls_table.attach (route_group_button, 7, 8, 1, 2, Gtk::FILL|Gtk::EXPAND, Gtk::FILL|Gtk::EXPAND, 0, 0); + controls_table.attach (gm.get_gain_slider(), 0, 5, 1, 2, Gtk::FILL|Gtk::EXPAND, Gtk::AttachOptions (0), 3, 0); + } ARDOUR_UI::instance()->set_tip(*solo_button,_("Solo")); ARDOUR_UI::instance()->set_tip(*mute_button,_("Mute")); ARDOUR_UI::instance()->set_tip(route_group_button, _("Route Group")); - ARDOUR_UI::instance()->set_tip(playlist_button,_("Playlist")); - ARDOUR_UI::instance()->set_tip(automation_button, _("Automation")); + if (is_midi_track()) { + ARDOUR_UI::instance()->set_tip(automation_button, _("MIDI Controllers and Automation")); + } else { + ARDOUR_UI::instance()->set_tip(automation_button, _("Automation")); + } + + update_track_number_visibility(); label_view (); - controls_table.attach (automation_button, 6, 7, 1, 2, Gtk::FILL|Gtk::EXPAND, Gtk::FILL|Gtk::EXPAND); + if (!ARDOUR::Profile->get_trx()) { + controls_table.attach (automation_button, 6, 7, 1, 2, Gtk::FILL|Gtk::EXPAND, Gtk::FILL|Gtk::EXPAND); + } - if (is_track() && track()->mode() == ARDOUR::Normal) { + if (!ARDOUR::Profile->get_trx() && is_track() && track()->mode() == ARDOUR::Normal) { controls_table.attach (playlist_button, 5, 6, 1, 2, Gtk::FILL|Gtk::EXPAND, Gtk::FILL|Gtk::EXPAND); } _y_position = -1; - _route->processors_changed.connect (*this, invalidator (*this), ui_bind (&RouteTimeAxisView::processors_changed, this, _1), gui_context()); - _route->PropertyChanged.connect (*this, invalidator (*this), ui_bind (&RouteTimeAxisView::route_property_changed, this, _1), gui_context()); + _route->processors_changed.connect (*this, invalidator (*this), boost::bind (&RouteTimeAxisView::processors_changed, this, _1), gui_context()); + _route->PropertyChanged.connect (*this, invalidator (*this), boost::bind (&RouteTimeAxisView::route_property_changed, this, _1), gui_context()); if (is_track()) { @@ -243,27 +257,22 @@ RouteTimeAxisView::set_route (boost::shared_ptr rt) /* pick up the correct freeze state */ map_frozen (); - } - _editor.ZoomChanged.connect (sigc::mem_fun(*this, &RouteTimeAxisView::reset_samples_per_unit)); - _editor.HorizontalPositionChanged.connect (sigc::mem_fun (*this, &RouteTimeAxisView::horizontal_position_changed)); + } + + _editor.ZoomChanged.connect (sigc::mem_fun(*this, &RouteTimeAxisView::reset_samples_per_pixel)); ColorsChanged.connect (sigc::mem_fun (*this, &RouteTimeAxisView::color_handler)); PropertyList* plist = new PropertyList(); - plist->add (ARDOUR::Properties::edit, true); plist->add (ARDOUR::Properties::mute, true); plist->add (ARDOUR::Properties::solo, true); route_group_menu = new RouteGroupMenu (_session, plist); gm.get_gain_slider().signal_scroll_event().connect(sigc::mem_fun(*this, &RouteTimeAxisView::controls_ebox_scroll), false); - gm.get_gain_slider().set_name ("TrackGainFader"); gm.get_level_meter().signal_scroll_event().connect (sigc::mem_fun (*this, &RouteTimeAxisView::controls_ebox_scroll), false); - - show_name_entry (); - hide_name_label (); } RouteTimeAxisView::~RouteTimeAxisView () @@ -335,17 +344,53 @@ RouteTimeAxisView::playlist_changed () void RouteTimeAxisView::label_view () { - string x = _route->name(); + string x = _route->name (); + if (x != name_label.get_text ()) { + name_label.set_text (x); + } + const int64_t track_number = _route->track_number (); + if (track_number == 0) { + number_label.set_text (""); + } else { + number_label.set_text (PBD::to_string (abs(_route->track_number ()), std::dec)); + } +} + +void +RouteTimeAxisView::update_track_number_visibility () +{ + bool show_label = _session->config.get_track_name_number(); - if (x != name_entry.get_text()) { - name_entry.set_text (x); + if (_route && _route->is_master()) { + show_label = false; } - if (x != name_label.get_text()) { - name_label.set_text (x); + //if (show_label == number_label.is_visible()) { return; } + if (number_label.get_parent()) { + controls_table.remove (number_label); + } + if (name_hbox.get_parent()) { + controls_table.remove (name_hbox); + } + if (show_label) { + controls_table.attach (number_label, 0, 1, 0, 1, Gtk::SHRINK, Gtk::FILL|Gtk::EXPAND, 3, 0); + controls_table.attach (name_hbox, 1, 5, 0, 1, Gtk::FILL|Gtk::EXPAND, Gtk::FILL|Gtk::EXPAND, 3, 0); + number_label.set_size_request(3 + _session->track_number_decimals() * 8, -1); + name_hbox.show (); + number_label.show (); + } else { + controls_table.attach (name_hbox, 0, 5, 0, 1, Gtk::FILL|Gtk::EXPAND, Gtk::FILL|Gtk::EXPAND, 3, 0); + name_hbox.show (); + number_label.hide (); } +} - ARDOUR_UI::instance()->set_tip (name_entry, x); +void +RouteTimeAxisView::parameter_changed (string const & p) +{ + if (p == "track-name-number") { + update_track_number_visibility(); + } } void @@ -408,13 +453,15 @@ RouteTimeAxisView::build_automation_action_menu (bool for_selection) items.push_back (MenuElem (_("Hide All Automation"), sigc::bind (sigc::mem_fun (*this, &RouteTimeAxisView::hide_all_automation), for_selection))); - items.push_back (SeparatorElem ()); - /* Attach the plugin submenu. It may have previously been used elsewhere, - so it was detached above */ - - items.push_back (MenuElem (_("Plugins"), subplugin_menu)); - items.back().set_sensitive (!subplugin_menu.items().empty() && (!for_selection || _editor.get_selection().tracks.size() == 1));; + so it was detached above + */ + + if (!subplugin_menu.items().empty()) { + items.push_back (SeparatorElem ()); + items.push_back (MenuElem (_("Processor automation"), subplugin_menu)); + items.back().set_sensitive (!for_selection || _editor.get_selection().tracks.size() == 1);; + } } void @@ -474,6 +521,7 @@ RouteTimeAxisView::build_display_menu () ++overlaid; break; case Stacked: + case Expanded: ++stacked; break; } @@ -485,21 +533,21 @@ RouteTimeAxisView::build_display_menu () select the active one, no toggled signal is emitted so nothing happens. */ + _ignore_set_layer_display = true; + layers_items.push_back (RadioMenuElem (layers_group, _("Overlaid"))); RadioMenuItem* i = dynamic_cast (&layers_items.back ()); i->set_active (overlaid != 0 && stacked == 0); i->set_inconsistent (overlaid != 0 && stacked != 0); i->signal_activate().connect (sigc::bind (sigc::mem_fun (*this, &RouteTimeAxisView::set_layer_display), Overlaid, true)); - layers_items.push_back ( - RadioMenuElem (layers_group, _("Stacked"), - sigc::bind (sigc::mem_fun (*this, &RouteTimeAxisView::set_layer_display), Stacked, true)) - ); - + layers_items.push_back (RadioMenuElem (layers_group, _("Stacked"))); i = dynamic_cast (&layers_items.back ()); - i->signal_activate().connect (sigc::bind (sigc::mem_fun (*this, &RouteTimeAxisView::set_layer_display), Stacked, true)); i->set_active (overlaid == 0 && stacked != 0); i->set_inconsistent (overlaid != 0 && stacked != 0); + i->signal_activate().connect (sigc::bind (sigc::mem_fun (*this, &RouteTimeAxisView::set_layer_display), Stacked, true)); + + _ignore_set_layer_display = false; items.push_back (MenuElem (_("Layers"), *layers_menu)); @@ -656,40 +704,36 @@ RouteTimeAxisView::build_display_menu () items.push_back (MenuElem (_("Mode"), *mode_menu)); } - color_mode_menu = build_color_mode_menu(); - if (color_mode_menu) { - items.push_back (MenuElem (_("Color Mode"), *color_mode_menu)); - } items.push_back (SeparatorElem()); build_playlist_menu (); items.push_back (MenuElem (_("Playlist"), *playlist_action_menu)); items.back().set_sensitive (_editor.get_selection().tracks.size() <= 1); + } - route_group_menu->detach (); - - WeakRouteList r; - for (TrackSelection::iterator i = _editor.get_selection().tracks.begin(); i != _editor.get_selection().tracks.end(); ++i) { - RouteTimeAxisView* rtv = dynamic_cast (*i); - if (rtv) { - r.push_back (rtv->route ()); - } - } - - if (r.empty ()) { - r.push_back (route ()); + route_group_menu->detach (); + + WeakRouteList r; + for (TrackSelection::iterator i = _editor.get_selection().tracks.begin(); i != _editor.get_selection().tracks.end(); ++i) { + RouteTimeAxisView* rtv = dynamic_cast (*i); + if (rtv) { + r.push_back (rtv->route ()); } - - route_group_menu->build (r); - items.push_back (MenuElem (_("Route Group"), *route_group_menu->menu ())); - - build_automation_action_menu (true); - items.push_back (MenuElem (_("Automation"), *automation_action_menu)); - - items.push_back (SeparatorElem()); + } + + if (r.empty ()) { + r.push_back (route ()); } + route_group_menu->build (r); + items.push_back (MenuElem (_("Group"), *route_group_menu->menu ())); + + build_automation_action_menu (true); + items.push_back (MenuElem (_("Automation"), *automation_action_menu)); + + items.push_back (SeparatorElem()); + int active = 0; int inactive = 0; TrackSelection const & s = _editor.get_selection().tracks; @@ -707,7 +751,7 @@ RouteTimeAxisView::build_display_menu () } items.push_back (CheckMenuElem (_("Active"))); - CheckMenuItem* i = dynamic_cast (&items.back()); + Gtk::CheckMenuItem* i = dynamic_cast (&items.back()); bool click_sets_active = true; if (active > 0 && inactive == 0) { i->set_active (true); @@ -715,6 +759,7 @@ RouteTimeAxisView::build_display_menu () } else if (active > 0 && inactive > 0) { i->set_inconsistent (true); } + i->set_sensitive(! _session->transport_rolling()); i->signal_activate().connect (sigc::bind (sigc::mem_fun (*this, &RouteUI::set_route_active), click_sets_active, true)); items.push_back (SeparatorElem()); @@ -734,7 +779,7 @@ RouteTimeAxisView::set_track_mode (TrackMode mode, bool apply_to_selection) _editor.get_selection().tracks.foreach_route_time_axis (boost::bind (&RouteTimeAxisView::set_track_mode, _1, mode, false)); } else { - bool needs_bounce; + bool needs_bounce = false; if (!track()->can_use_mode (mode, needs_bounce)) { @@ -754,10 +799,12 @@ RouteTimeAxisView::set_track_mode (TrackMode mode, bool apply_to_selection) switch (mode) { case ARDOUR::NonLayered: case ARDOUR::Normal: - rec_enable_button->add (*(manage (new Image (::get_icon (X_("record_normal_red")))))); + rec_enable_button->set_image (::get_icon (X_("record_normal_red"))); + rec_enable_button->set_text (string()); break; case ARDOUR::Destructive: - rec_enable_button->add (*(manage (new Image (::get_icon (X_("record_tape_red")))))); + rec_enable_button->set_image (::get_icon (X_("record_tape_red"))); + rec_enable_button->set_text (string()); break; } @@ -766,13 +813,9 @@ RouteTimeAxisView::set_track_mode (TrackMode mode, bool apply_to_selection) } void -RouteTimeAxisView::show_timestretch (framepos_t start, framepos_t end) +RouteTimeAxisView::show_timestretch (framepos_t start, framepos_t end, int layers, int layer) { - double x1; - double x2; - double y2; - - TimeAxisView::show_timestretch (start, end); + TimeAxisView::show_timestretch (start, end, layers, layer); hide_timestretch (); @@ -799,26 +842,19 @@ RouteTimeAxisView::show_timestretch (framepos_t start, framepos_t end) #endif if (timestretch_rect == 0) { - timestretch_rect = new SimpleRect (*canvas_display ()); - timestretch_rect->property_x1() = 0.0; - timestretch_rect->property_y1() = 0.0; - timestretch_rect->property_x2() = 0.0; - timestretch_rect->property_y2() = 0.0; - timestretch_rect->property_fill_color_rgba() = ARDOUR_UI::config()->canvasvar_TimeStretchFill.get(); - timestretch_rect->property_outline_color_rgba() = ARDOUR_UI::config()->canvasvar_TimeStretchOutline.get(); + timestretch_rect = new ArdourCanvas::Rectangle (canvas_display ()); + timestretch_rect->set_fill_color (ARDOUR_UI::config()->get_canvasvar_TimeStretchFill()); + timestretch_rect->set_outline_color (ARDOUR_UI::config()->get_canvasvar_TimeStretchOutline()); } timestretch_rect->show (); timestretch_rect->raise_to_top (); - x1 = start / _editor.get_current_zoom(); - x2 = (end - 1) / _editor.get_current_zoom(); - y2 = current_height() - 2; + double const x1 = start / _editor.get_current_zoom(); + double const x2 = (end - 1) / _editor.get_current_zoom(); - timestretch_rect->property_x1() = x1; - timestretch_rect->property_y1() = 1.0; - timestretch_rect->property_x2() = x2; - timestretch_rect->property_y2() = y2; + timestretch_rect->set (ArdourCanvas::Rect (x1, current_height() * (layers - layer - 1) / layers, + x2, current_height() * (layers - layer) / layers)); } void @@ -854,9 +890,14 @@ RouteTimeAxisView::show_selection (TimeSelection& ts) void RouteTimeAxisView::set_height (uint32_t h) { - int gmlen = h - 5; + int gmlen = h - 9; bool height_changed = (height == 0) || (h != height); - gm.get_level_meter().setup_meters (gmlen); + + int meter_width = 3; + if (_route && _route->shared_peak_meter()->input_streams().n_total() == 1) { + meter_width = 6; + } + gm.get_level_meter().setup_meters (gmlen, meter_width); TimeAxisView::set_height (h); @@ -923,21 +964,13 @@ RouteTimeAxisView::route_color_changed () } void -RouteTimeAxisView::reset_samples_per_unit () +RouteTimeAxisView::reset_samples_per_pixel () { - set_samples_per_unit (_editor.get_current_zoom()); + set_samples_per_pixel (_editor.get_current_zoom()); } void -RouteTimeAxisView::horizontal_position_changed () -{ - if (_view) { - _view->horizontal_position_changed (); - } -} - -void -RouteTimeAxisView::set_samples_per_unit (double spu) +RouteTimeAxisView::set_samples_per_pixel (double fpp) { double speed = 1.0; @@ -946,10 +979,10 @@ RouteTimeAxisView::set_samples_per_unit (double spu) } if (_view) { - _view->set_samples_per_unit (spu * speed); + _view->set_samples_per_pixel (fpp * speed); } - TimeAxisView::set_samples_per_unit (spu * speed); + TimeAxisView::set_samples_per_pixel (fpp * speed); } void @@ -1024,7 +1057,7 @@ RouteTimeAxisView::resolve_new_group_playlist_name(std::string &basename, vector tmp = tmp.substr(idx + group_string.length()); // and find the largest current number - int x = atoi(tmp.c_str()); + int x = atoi(tmp); if (x > maxnumber) { maxnumber = x; } @@ -1058,7 +1091,7 @@ RouteTimeAxisView::use_copy_playlist (bool prompt, vectorname(); - if (route_group() && route_group()->is_active() && route_group()->enabled_property (ARDOUR::Properties::edit.property_id)) { + if (route_group() && route_group()->is_active() && route_group()->enabled_property (ARDOUR::Properties::select.property_id)) { name = resolve_new_group_playlist_name(name, playlists_before_op); } @@ -1113,7 +1146,7 @@ RouteTimeAxisView::use_new_playlist (bool prompt, vectorname(); - if (route_group() && route_group()->is_active() && route_group()->enabled_property (ARDOUR::Properties::edit.property_id)) { + if (route_group() && route_group()->is_active() && route_group()->enabled_property (ARDOUR::Properties::select.property_id)) { name = resolve_new_group_playlist_name(name,playlists_before_op); } @@ -1167,7 +1200,7 @@ RouteTimeAxisView::clear_playlist () void RouteTimeAxisView::speed_changed () { - Gtkmm2ext::UI::instance()->call_slot (invalidator (*this), boost::bind (&RouteTimeAxisView::reset_samples_per_unit, this)); + Gtkmm2ext::UI::instance()->call_slot (invalidator (*this), boost::bind (&RouteTimeAxisView::reset_samples_per_pixel, this)); } void @@ -1301,7 +1334,9 @@ RouteTimeAxisView::playlist () const void RouteTimeAxisView::name_entry_changed () { - string x = name_entry.get_text (); + TimeAxisView::name_entry_changed (); + + string x = name_entry->get_text (); if (x == _route->name()) { return; @@ -1310,18 +1345,18 @@ RouteTimeAxisView::name_entry_changed () strip_whitespace_edges (x); if (x.length() == 0) { - name_entry.set_text (_route->name()); + name_entry->set_text (_route->name()); return; } if (_session->route_name_internal (x)) { ARDOUR_UI::instance()->popup_error (string_compose (_("You cannot create a track with that name as it is reserved for %1"), PROGRAM_NAME)); - name_entry.grab_focus (); + name_entry->grab_focus (); } else if (RouteUI::verify_new_route_name (x)) { _route->set_name (x); } else { - name_entry.grab_focus (); + name_entry->grab_focus (); } } @@ -1494,7 +1529,7 @@ RouteTimeAxisView::build_playlist_menu () playlist_items.push_back (MenuElem (_("Rename..."), sigc::mem_fun(*this, &RouteTimeAxisView::rename_current_playlist))); playlist_items.push_back (SeparatorElem()); - if (!route_group() || !route_group()->is_active() || !route_group()->enabled_property (ARDOUR::Properties::edit.property_id)) { + if (!route_group() || !route_group()->is_active() || !route_group()->enabled_property (ARDOUR::Properties::select.property_id)) { playlist_items.push_back (MenuElem (_("New..."), sigc::bind(sigc::mem_fun(_editor, &PublicEditor::new_playlists), this))); playlist_items.push_back (MenuElem (_("New Copy..."), sigc::bind(sigc::mem_fun(_editor, &PublicEditor::copy_playlists), this))); @@ -1538,7 +1573,7 @@ RouteTimeAxisView::use_playlist (RadioMenuItem *item, boost::weak_ptr RouteGroup* rg = route_group(); - if (rg && rg->is_active() && rg->enabled_property (ARDOUR::Properties::edit.property_id)) { + if (rg && rg->is_active() && rg->enabled_property (ARDOUR::Properties::select.property_id)) { std::string group_string = "." + rg->name() + "."; std::string take_name = pl->name(); @@ -1552,16 +1587,21 @@ RouteTimeAxisView::use_playlist (RadioMenuItem *item, boost::weak_ptr boost::shared_ptr rl (rg->route_list()); for (RouteList::const_iterator i = rl->begin(); i != rl->end(); ++i) { - if ( (*i) == this->route()) { + if ((*i) == this->route()) { continue; } - + std::string playlist_name = (*i)->name()+group_string+take_name; boost::shared_ptr track = boost::dynamic_pointer_cast(*i); if (!track) { continue; } + + if (track->freeze_state() == Track::Frozen) { + /* Don't change playlists of frozen tracks */ + continue; + } boost::shared_ptr ipl = session()->playlists->by_name(playlist_name); if (!ipl) { @@ -1575,6 +1615,37 @@ RouteTimeAxisView::use_playlist (RadioMenuItem *item, boost::weak_ptr } } +void +RouteTimeAxisView::update_playlist_tip () +{ + RouteGroup* rg = route_group (); + if (rg && rg->is_active() && rg->enabled_property (ARDOUR::Properties::select.property_id)) { + string group_string = "." + rg->name() + "."; + + string take_name = track()->playlist()->name(); + string::size_type idx = take_name.find(group_string); + + if (idx != string::npos) { + /* find the bit containing the take number / name */ + take_name = take_name.substr (idx + group_string.length()); + + /* set the playlist button tooltip to the take name */ + ARDOUR_UI::instance()->set_tip ( + playlist_button, + string_compose(_("Take: %1.%2"), + Glib::Markup::escape_text(rg->name()), + Glib::Markup::escape_text(take_name)) + ); + + return; + } + } + + /* set the playlist button tooltip to the playlist name */ + ARDOUR_UI::instance()->set_tip (playlist_button, _("Playlist") + std::string(": ") + Glib::Markup::escape_text(track()->playlist()->name())); +} + + void RouteTimeAxisView::show_playlist_selector () { @@ -1607,11 +1678,11 @@ RouteTimeAxisView::color_handler () { //case cTimeStretchOutline: if (timestretch_rect) { - timestretch_rect->property_outline_color_rgba() = ARDOUR_UI::config()->canvasvar_TimeStretchOutline.get(); + timestretch_rect->set_outline_color (ARDOUR_UI::config()->get_canvasvar_TimeStretchOutline()); } //case cTimeStretchFill: if (timestretch_rect) { - timestretch_rect->property_fill_color_rgba() = ARDOUR_UI::config()->canvasvar_TimeStretchFill.get(); + timestretch_rect->set_fill_color (ARDOUR_UI::config()->get_canvasvar_TimeStretchFill()); } reset_meter(); @@ -2011,12 +2082,12 @@ RouteTimeAxisView::add_processor_to_subplugin_menu (boost::weak_ptr p for (std::set::const_iterator i = automatable.begin(); i != automatable.end(); ++i) { ProcessorAutomationNode* pan; - CheckMenuItem* mitem; + Gtk::CheckMenuItem* mitem; string name = processor->describe_parameter (*i); items.push_back (CheckMenuElem (name)); - mitem = dynamic_cast (&items.back()); + mitem = dynamic_cast (&items.back()); _subplugin_menu_map[*i] = mitem; @@ -2135,16 +2206,27 @@ RouteTimeAxisView::reset_processor_automation_curves () } } +bool +RouteTimeAxisView::can_edit_name () const +{ + /* we do not allow track name changes if it is record enabled + */ + return !_route->record_enabled(); +} + void RouteTimeAxisView::update_rec_display () { RouteUI::update_rec_display (); - name_entry.set_sensitive (!_route->record_enabled()); } void RouteTimeAxisView::set_layer_display (LayerDisplay d, bool apply_to_selection) { + if (_ignore_set_layer_display) { + return; + } + if (apply_to_selection) { _editor.get_selection().tracks.foreach_route_time_axis (boost::bind (&RouteTimeAxisView::set_layer_display, _1, d, false)); } else { @@ -2204,7 +2286,11 @@ void RouteTimeAxisView::reset_meter () { if (Config->get_show_track_meters()) { - gm.get_level_meter().setup_meters (height-5); + int meter_width = 3; + if (_route && _route->shared_peak_meter()->input_streams().n_total() == 1) { + meter_width = 6; + } + gm.get_level_meter().setup_meters (height - 9, meter_width); } else { hide_meter (); } @@ -2221,12 +2307,20 @@ RouteTimeAxisView::meter_changed () { ENSURE_GUI_THREAD (*this, &RouteTimeAxisView::meter_changed) reset_meter(); + if (_route && !no_redraw) { + request_redraw (); + } + // reset peak when meter point changes + gm.reset_peak_display(); } void RouteTimeAxisView::io_changed (IOChange /*change*/, void */*src*/) { reset_meter (); + if (_route && !no_redraw) { + request_redraw (); + } } void @@ -2348,32 +2442,26 @@ RouteTimeAxisView::remove_underlay (StreamView* v) void RouteTimeAxisView::set_button_names () { - rec_enable_button_label.set_text (_("r")); - - if (_route && _route->solo_safe()) { - solo_button->remove (); - if (solo_safe_image == 0) { - solo_safe_image = new Gtk::Image (::get_icon("solo-safe-enabled")); - solo_safe_image->show (); + if (_route && _route->solo_safe()) { + solo_button->set_visual_state (Gtkmm2ext::VisualState (solo_button->visual_state() | Gtkmm2ext::Insensitive)); + } else { + solo_button->set_visual_state (Gtkmm2ext::VisualState (solo_button->visual_state() & ~Gtkmm2ext::Insensitive)); + } + if (Config->get_solo_control_is_listen_control()) { + switch (Config->get_listen_position()) { + case AfterFaderListen: + solo_button->set_text (_("A")); + ARDOUR_UI::instance()->set_tip (*solo_button, _("After-fade listen (AFL)")); + break; + case PreFaderListen: + solo_button->set_text (_("P")); + ARDOUR_UI::instance()->set_tip (*solo_button, _("Pre-fade listen (PFL)")); + break; } - solo_button->add (*solo_safe_image); - } else { - solo_button->remove (); - solo_button->add (solo_button_label); - solo_button_label.show (); - if (Config->get_solo_control_is_listen_control()) { - switch (Config->get_listen_position()) { - case AfterFaderListen: - solo_button_label.set_text (_("A")); - break; - case PreFaderListen: - solo_button_label.set_text (_("P")); - break; - } - } else { - solo_button_label.set_text (_("s")); - } - } + } else { + solo_button->set_text (_("s")); + ARDOUR_UI::instance()->set_tip (*solo_button, _("Solo")); + } mute_button->set_text (_("m")); } @@ -2418,7 +2506,7 @@ RouteTimeAxisView::create_gain_automation_child (const Evoral::Parameter& param, } static -void add_region_to_list (RegionView* rv, Playlist::RegionList* l) +void add_region_to_list (RegionView* rv, RegionList* l) { l->push_back (rv->region()); } @@ -2437,7 +2525,7 @@ RouteTimeAxisView::combine_regions () return 0; } - Playlist::RegionList selected_regions; + RegionList selected_regions; boost::shared_ptr playlist = track()->playlist(); _view->foreach_selected_regionview (sigc::bind (sigc::ptr_fun (add_region_to_list), &selected_regions)); @@ -2468,7 +2556,7 @@ RouteTimeAxisView::uncombine_regions () return; } - Playlist::RegionList selected_regions; + RegionList selected_regions; boost::shared_ptr playlist = track()->playlist(); /* have to grab selected regions first because the uncombine is going @@ -2479,7 +2567,7 @@ RouteTimeAxisView::uncombine_regions () playlist->clear_changes (); - for (Playlist::RegionList::iterator i = selected_regions.begin(); i != selected_regions.end(); ++i) { + for (RegionList::iterator i = selected_regions.begin(); i != selected_regions.end(); ++i) { playlist->uncombine (*i); } @@ -2492,3 +2580,19 @@ RouteTimeAxisView::state_id() const return string_compose ("rtav %1", _route->id().to_s()); } + +void +RouteTimeAxisView::remove_child (boost::shared_ptr c) +{ + TimeAxisView::remove_child (c); + + boost::shared_ptr a = boost::dynamic_pointer_cast (c); + if (a) { + for (AutomationTracks::iterator i = _automation_tracks.begin(); i != _automation_tracks.end(); ++i) { + if (i->second == a) { + _automation_tracks.erase (i); + return; + } + } + } +}