move contrasting_text_color() into ArdourCanvas
[ardour.git] / gtk2_ardour / route_time_axis.cc
index d9b96066d3a361c86035b464bc4bd62595d705cd..e6a8f59be093fbf4299e5ae0783475d249a3a700 100644 (file)
 #include <gtkmm2ext/utils.h>
 
 #include "ardour/amp.h"
+#include "ardour/meter.h"
 #include "ardour/event_type_map.h"
 #include "ardour/processor.h"
 #include "ardour/profile.h"
 #include "ardour/route_group.h"
 #include "ardour/session.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"
@@ -76,6 +80,7 @@
 #include "i18n.h"
 
 using namespace ARDOUR;
+using namespace ARDOUR_UI_UTILS;
 using namespace PBD;
 using namespace Gtkmm2ext;
 using namespace Gtk;
@@ -103,6 +108,11 @@ RouteTimeAxisView::RouteTimeAxisView (PublicEditor& ed, Session* sess, ArdourCan
        , 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
@@ -110,9 +120,17 @@ RouteTimeAxisView::set_route (boost::shared_ptr<Route> 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");
@@ -179,11 +197,16 @@ RouteTimeAxisView::set_route (boost::shared_ptr<Route> rt)
        } 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());
+       _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);
 
@@ -191,8 +214,10 @@ RouteTimeAxisView::set_route (boost::shared_ptr<Route> 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::FILL|Gtk::EXPAND, Gtk::AttachOptions (0), 3, 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"));
@@ -204,11 +229,14 @@ RouteTimeAxisView::set_route (boost::shared_ptr<Route> rt)
                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);
        }
 
@@ -232,8 +260,7 @@ RouteTimeAxisView::set_route (boost::shared_ptr<Route> rt)
 
        } 
 
-       _editor.ZoomChanged.connect (sigc::mem_fun(*this, &RouteTimeAxisView::reset_frames_per_pixel));
-       _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();
@@ -317,12 +344,53 @@ RouteTimeAxisView::playlist_changed ()
 void
 RouteTimeAxisView::label_view ()
 {
-       string x = _route->name();
-
-       if (x != name_label.get_text()) {
+       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 (_route && _route->is_master()) {
+               show_label = false;
+       }
+
+       //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 ();
+       }
+}
+
+void
+RouteTimeAxisView::parameter_changed (string const & p)
+{
+       if (p == "track-name-number") {
+               update_track_number_visibility();
+       }
 }
 
 void
@@ -683,7 +751,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);
@@ -691,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());
@@ -710,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)) {
 
@@ -774,8 +843,8 @@ RouteTimeAxisView::show_timestretch (framepos_t start, framepos_t end, int layer
 
        if (timestretch_rect == 0) {
                timestretch_rect = new ArdourCanvas::Rectangle (canvas_display ());
-               timestretch_rect->set_fill_color (ARDOUR_UI::config()->canvasvar_TimeStretchFill.get());
-               timestretch_rect->set_outline_color (ARDOUR_UI::config()->canvasvar_TimeStretchOutline.get());
+               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 ();
@@ -821,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);
 
@@ -890,21 +964,13 @@ RouteTimeAxisView::route_color_changed ()
 }
 
 void
-RouteTimeAxisView::reset_frames_per_pixel ()
+RouteTimeAxisView::reset_samples_per_pixel ()
 {
-       set_frames_per_pixel (_editor.get_current_zoom());
-}
-
-void
-RouteTimeAxisView::horizontal_position_changed ()
-{
-       if (_view) {
-               _view->horizontal_position_changed ();
-       }
+       set_samples_per_pixel (_editor.get_current_zoom());
 }
 
 void
-RouteTimeAxisView::set_frames_per_pixel (double fpp)
+RouteTimeAxisView::set_samples_per_pixel (double fpp)
 {
        double speed = 1.0;
 
@@ -913,10 +979,10 @@ RouteTimeAxisView::set_frames_per_pixel (double fpp)
        }
 
        if (_view) {
-               _view->set_frames_per_pixel (fpp * speed);
+               _view->set_samples_per_pixel (fpp * speed);
        }
 
-       TimeAxisView::set_frames_per_pixel (fpp * speed);
+       TimeAxisView::set_samples_per_pixel (fpp * speed);
 }
 
 void
@@ -991,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;
                        }
@@ -1134,7 +1200,7 @@ RouteTimeAxisView::clear_playlist ()
 void
 RouteTimeAxisView::speed_changed ()
 {
-       Gtkmm2ext::UI::instance()->call_slot (invalidator (*this), boost::bind (&RouteTimeAxisView::reset_frames_per_pixel, this));
+       Gtkmm2ext::UI::instance()->call_slot (invalidator (*this), boost::bind (&RouteTimeAxisView::reset_samples_per_pixel, this));
 }
 
 void
@@ -1612,11 +1678,11 @@ RouteTimeAxisView::color_handler ()
 {
        //case cTimeStretchOutline:
        if (timestretch_rect) {
-               timestretch_rect->set_outline_color (ARDOUR_UI::config()->canvasvar_TimeStretchOutline.get());
+               timestretch_rect->set_outline_color (ARDOUR_UI::config()->get_canvasvar_TimeStretchOutline());
        }
        //case cTimeStretchFill:
        if (timestretch_rect) {
-               timestretch_rect->set_fill_color (ARDOUR_UI::config()->canvasvar_TimeStretchFill.get());
+               timestretch_rect->set_fill_color (ARDOUR_UI::config()->get_canvasvar_TimeStretchFill());
        }
 
        reset_meter();
@@ -2016,12 +2082,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;
 
@@ -2220,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 ();
        }
@@ -2237,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
@@ -2364,31 +2442,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"));
 }