Merge remote-tracking branch 'remotes/origin/cairocanvas' into windows
[ardour.git] / gtk2_ardour / route_time_axis.cc
index 4d50a412722d114ca444a5e100c174474060e500..29794eb54f3fe52d40d23a5345713cf50dc975ec 100644 (file)
 #include <gtkmm2ext/utils.h>
 
 #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 "ardour_ui.h"
@@ -67,7 +58,6 @@
 #include "global_signals.h"
 #include "route_time_axis.h"
 #include "automation_time_axis.h"
-#include "canvas_impl.h"
 #include "enums.h"
 #include "gui_thread.h"
 #include "keyboard.h"
@@ -78,7 +68,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"
@@ -95,17 +84,7 @@ using namespace Editing;
 using namespace std;
 using std::list;
 
-Glib::RefPtr<Gdk::Pixbuf> 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,7 +101,8 @@ 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)
 {
 }
 
@@ -130,10 +110,15 @@ void
 RouteTimeAxisView::set_route (boost::shared_ptr<Route> rt)
 {
        RouteUI::set_route (rt);
-       
+
+       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 +127,7 @@ RouteTimeAxisView::set_route (boost::shared_ptr<Route> rt)
                set_height (preset_height (HeightNormal));
        }
 
-       if (!_route->is_hidden()) {
+       if (!_route->is_auditioner()) {
                if (gui_property ("visible").empty()) {
                        set_gui_property ("visible", true);
                }
@@ -184,14 +169,27 @@ RouteTimeAxisView::set_route (boost::shared_ptr<Route> rt)
 
                 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), 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());
@@ -203,12 +201,11 @@ RouteTimeAxisView::set_route (boost::shared_ptr<Route> rt)
         }
 
        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);
+       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"));
 
        if (is_midi_track()) {
                ARDOUR_UI::instance()->set_tip(automation_button, _("MIDI Controllers and Automation"));
@@ -241,27 +238,22 @@ RouteTimeAxisView::set_route (boost::shared_ptr<Route> 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,15 +327,10 @@ RouteTimeAxisView::label_view ()
 {
        string x = _route->name();
 
-       if (x != name_entry.get_text()) {
-               name_entry.set_text (x);
-       }
-
        if (x != name_label.get_text()) {
                name_label.set_text (x);
        }
 
-       ARDOUR_UI::instance()->set_tip (name_entry, x);
 }
 
 void
@@ -406,13 +393,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
@@ -484,21 +473,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<RadioMenuItem*> (&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<RadioMenuItem*> (&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));
 
@@ -655,40 +644,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<RouteTimeAxisView*> (*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<RouteTimeAxisView*> (*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;
@@ -706,7 +691,7 @@ RouteTimeAxisView::build_display_menu ()
        }
 
        items.push_back (CheckMenuElem (_("Active")));
-       CheckMenuItem* i = dynamic_cast<CheckMenuItem *> (&items.back());
+       Gtk::CheckMenuItem* i = dynamic_cast<Gtk::CheckMenuItem *> (&items.back());
        bool click_sets_active = true;
        if (active > 0 && inactive == 0) {
                i->set_active (true);
@@ -767,13 +752,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 ();
 
@@ -800,26 +781,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
@@ -855,9 +829,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);
 
@@ -924,21 +903,13 @@ RouteTimeAxisView::route_color_changed ()
 }
 
 void
-RouteTimeAxisView::reset_samples_per_unit ()
-{
-       set_samples_per_unit (_editor.get_current_zoom());
-}
-
-void
-RouteTimeAxisView::horizontal_position_changed ()
+RouteTimeAxisView::reset_samples_per_pixel ()
 {
-       if (_view) {
-               _view->horizontal_position_changed ();
-       }
+       set_samples_per_pixel (_editor.get_current_zoom());
 }
 
 void
-RouteTimeAxisView::set_samples_per_unit (double spu)
+RouteTimeAxisView::set_samples_per_pixel (double fpp)
 {
        double speed = 1.0;
 
@@ -947,10 +918,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
@@ -1025,7 +996,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;
                        }
@@ -1059,7 +1030,7 @@ RouteTimeAxisView::use_copy_playlist (bool prompt, vector<boost::shared_ptr<Play
 
        name = pl->name();
 
-       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);
        }
 
@@ -1114,7 +1085,7 @@ RouteTimeAxisView::use_new_playlist (bool prompt, vector<boost::shared_ptr<Playl
 
        name = pl->name();
 
-       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);
        }
 
@@ -1168,7 +1139,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
@@ -1302,7 +1273,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;
@@ -1311,18 +1284,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 ();
        }
 }
 
@@ -1495,7 +1468,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)));
 
@@ -1539,7 +1512,7 @@ RouteTimeAxisView::use_playlist (RadioMenuItem *item, boost::weak_ptr<Playlist>
        
        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();
@@ -1553,16 +1526,21 @@ RouteTimeAxisView::use_playlist (RadioMenuItem *item, boost::weak_ptr<Playlist>
                boost::shared_ptr<RouteList> 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> track = boost::dynamic_pointer_cast<Track>(*i);
                        if (!track) {
                                continue;
                        }
+
+                       if (track->freeze_state() == Track::Frozen) {
+                               /* Don't change playlists of frozen tracks */
+                               continue;
+                       }
                        
                        boost::shared_ptr<Playlist> ipl = session()->playlists->by_name(playlist_name);
                        if (!ipl) {
@@ -1576,6 +1554,37 @@ RouteTimeAxisView::use_playlist (RadioMenuItem *item, boost::weak_ptr<Playlist>
        }
 }
 
+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 ()
 {
@@ -1608,11 +1617,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();
@@ -2012,12 +2021,12 @@ RouteTimeAxisView::add_processor_to_subplugin_menu (boost::weak_ptr<Processor> p
        for (std::set<Evoral::Parameter>::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<CheckMenuItem*> (&items.back());
+               mitem = dynamic_cast<Gtk::CheckMenuItem*> (&items.back());
                
                _subplugin_menu_map[*i] = mitem;
 
@@ -2136,16 +2145,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 {
@@ -2205,7 +2225,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 ();
        }
@@ -2222,12 +2246,18 @@ RouteTimeAxisView::meter_changed ()
 {
        ENSURE_GUI_THREAD (*this, &RouteTimeAxisView::meter_changed)
        reset_meter();
+       if (_route && !no_redraw) {
+               request_redraw ();
+       }
 }
 
 void
 RouteTimeAxisView::io_changed (IOChange /*change*/, void */*src*/)
 {
        reset_meter ();
+       if (_route && !no_redraw) {
+               request_redraw ();
+       }
 }
 
 void
@@ -2349,31 +2379,26 @@ RouteTimeAxisView::remove_underlay (StreamView* v)
 void
 RouteTimeAxisView::set_button_names ()
 {
-        if (_route && _route->solo_safe()) {
-               solo_button->remove ();
-               if (solo_safe_pixbuf == 0) {
-                       solo_safe_pixbuf = ::get_icon("solo-safe-icon");
-               }
-               solo_button->set_image (solo_safe_pixbuf);
-               solo_button->set_text (string());
-        } else {
-               solo_button->set_image (Glib::RefPtr<Gdk::Pixbuf>());
-                if (Config->get_solo_control_is_listen_control()) {
-                        switch (Config->get_listen_position()) {
-                        case AfterFaderListen:
-                                solo_button->set_text (_("A"));
+       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"));
+                               break;
+                       case PreFaderListen:
+                               solo_button->set_text (_("P"));
                                ARDOUR_UI::instance()->set_tip (*solo_button, _("Pre-fade listen (PFL)"));
-                                break;
-                        }
-                } else {
-                        solo_button->set_text (_("s"));
-                       ARDOUR_UI::instance()->set_tip (*solo_button, _("Solo"));
-                }
-        }
+                       break;
+               }
+       } else {
+               solo_button->set_text (_("s"));
+               ARDOUR_UI::instance()->set_tip (*solo_button, _("Solo"));
+       }
        mute_button->set_text (_("m"));
 }