#include "route_time_axis.h"
#include "group_tabs.h"
-#include "ardour/route.h"
-#include "ardour/event_type_map.h"
-#include "ardour/session.h"
-#include "ardour/audioengine.h"
#include "ardour/audio_track.h"
+#include "ardour/audioengine.h"
+#include "ardour/filename_extensions.h"
#include "ardour/midi_track.h"
+#include "ardour/route.h"
+#include "ardour/session.h"
#include "ardour/template_utils.h"
-#include "ardour/filename_extensions.h"
-#include "ardour/directory_names.h"
-#include "ardour/profile.h"
#include "i18n.h"
using namespace Gtk;
using namespace PBD;
uint32_t RouteUI::_max_invert_buttons = 3;
-sigc::signal<void, boost::shared_ptr<Route> > RouteUI::BusSendDisplayChanged;
+PBD::Signal1<void, boost::shared_ptr<Route> > RouteUI::BusSendDisplayChanged;
boost::weak_ptr<Route> RouteUI::_showing_sends_to;
RouteUI::RouteUI (ARDOUR::Session* sess)
: AxisView(sess)
+ , mute_menu(0)
+ , solo_menu(0)
+ , sends_menu(0)
+ , record_menu(0)
+ , _invert_menu(0)
{
- init ();
+ if (sess) init ();
}
RouteUI::~RouteUI()
rec_enable_button = manage (new ArdourButton);
rec_enable_button->set_name ("record enable button");
+ rec_enable_button->set_tweaks (ArdourButton::ImplicitUsesSolidColor);
UI::instance()->set_tip (rec_enable_button, _("Enable recording on this track"), "");
show_sends_button = manage (new ArdourButton);
monitor_disk_button->signal_button_press_event().connect (sigc::mem_fun(*this, &RouteUI::monitor_disk_press));
monitor_disk_button->signal_button_release_event().connect (sigc::mem_fun(*this, &RouteUI::monitor_disk_release));
- BusSendDisplayChanged.connect (sigc::mem_fun (*this, &RouteUI::bus_send_display_changed));
+ BusSendDisplayChanged.connect_same_thread (*this, boost::bind(&RouteUI::bus_send_display_changed, this, _1));
}
void
rec_enable_button->show();
rec_enable_button->set_controllable (t->rec_enable_control());
- update_rec_display ();
-
if (is_midi_track()) {
midi_track()->StepEditStatusChange.connect (route_connections, invalidator (*this),
boost::bind (&RouteUI::step_edit_changed, this, _1), gui_context());
}
- }
+ }
+
+ /* this will work for busses and tracks, and needs to be called to
+ set up the name entry/name label display.
+ */
+
+ update_rec_display ();
if (is_track()) {
boost::shared_ptr<Track> t = boost::dynamic_pointer_cast<Track>(_route);
mute_button->show();
- if (_route->is_monitor()) {
+ if (_route->is_monitor() || _route->is_master()) {
solo_button->hide ();
} else {
solo_button->show();
if (Keyboard::modifier_state_equals (ev->state, Keyboard::ModifierMask (Keyboard::PrimaryModifier|Keyboard::TertiaryModifier))) {
+ /* toggle mute on everything (but
+ * exclude the master and monitor)
+ *
+ * because we are going to erase
+ * elements of the list we need to work
+ * on a copy.
+ */
+
+ boost::shared_ptr<RouteList> copy (new RouteList);
+
+ *copy = *_session->get_routes ();
+
+ for (RouteList::iterator i = copy->begin(); i != copy->end(); ) {
+ if ((*i)->is_master() || (*i)->is_monitor()) {
+ i = copy->erase (i);
+ } else {
+ ++i;
+ }
+ }
+
if (_mute_release) {
- _mute_release->routes = _session->get_routes ();
+ _mute_release->routes = copy;
}
- _session->set_mute (_session->get_routes(), !_route->muted());
+ _session->set_mute (copy, !_route->muted());
} else if (Keyboard::modifier_state_equals (ev->state, Keyboard::PrimaryModifier)) {
NOTE: Primary-button2 is MIDI learn.
*/
- if (ev->button == 1 && _route->route_group()) {
- if (_mute_release) {
- _mute_release->routes = _session->get_routes ();
+ boost::shared_ptr<RouteList> rl;
+
+ if (ev->button == 1) {
+
+ if (_route->route_group()) {
+
+ rl = _route->route_group()->route_list();
+
+ if (_mute_release) {
+ _mute_release->routes = rl;
+ }
+ } else {
+ rl.reset (new RouteList);
+ rl->push_back (_route);
}
- _session->set_mute (_session->get_routes(), !_route->muted(), Session::rt_cleanup, true);
+ _session->set_mute (rl, !_route->muted(), Session::rt_cleanup, true);
}
} else {
boost::shared_ptr<RouteList> rl (new RouteList);
rl->push_back (_route);
-
+
if (_mute_release) {
_mute_release->routes = rl;
}
NOTE: Primary-button2 is MIDI learn.
*/
- if (ev->button == 1 && _route->route_group()) {
+ /* Primary-button1 applies change to the mix group even if it is not active
+ NOTE: Primary-button2 is MIDI learn.
+ */
+
+ boost::shared_ptr<RouteList> rl;
- if (_solo_release) {
- _solo_release->routes = _route->route_group()->route_list();
+ if (ev->button == 1) {
+
+ if (_route->route_group()) {
+
+ rl = _route->route_group()->route_list();
+
+ if (_solo_release) {
+ _solo_release->routes = rl;
+ }
+ } else {
+ rl.reset (new RouteList);
+ rl->push_back (_route);
}
if (Config->get_solo_control_is_listen_control()) {
- _session->set_listen (_route->route_group()->route_list(), !_route->listening_via_monitor(), Session::rt_cleanup, true);
+ _session->set_listen (rl, !_route->listening_via_monitor(), Session::rt_cleanup, true);
} else {
- _session->set_solo (_route->route_group()->route_list(), !_route->self_soloed(), Session::rt_cleanup, true);
+ _session->set_solo (rl, !_route->self_soloed(), Session::rt_cleanup, true);
}
}
/* Primary-button1 applies change to the route group (even if it is not active)
NOTE: Primary-button2 is MIDI learn.
*/
- if (ev->button == 1 && _route->route_group()) {
- _session->set_record_enabled (_route->route_group()->route_list(), !rec_enable_button->active_state(), Session::rt_cleanup, true);
+
+ if (ev->button == 1) {
+
+ boost::shared_ptr<RouteList> rl;
+
+ if (_route->route_group()) {
+
+ rl = _route->route_group()->route_list();
+
+ } else {
+ rl.reset (new RouteList);
+ rl->push_back (_route);
+ }
+
+ _session->set_record_enabled (rl, !rec_enable_button->active_state(), Session::rt_cleanup, true);
}
} else if (Keyboard::is_context_menu_event (ev)) {
void
RouteUI::set_color (const Gdk::Color & c)
{
- char buf[64];
+ /* leave _color alone in the group case so that tracks can retain their
+ * own pre-group colors.
+ */
+ char buf[64];
_color = c;
-
snprintf (buf, sizeof (buf), "%d:%d:%d", c.get_red(), c.get_green(), c.get_blue());
-
+
/* note: we use the route state ID here so that color is the same for both
the time axis view and the mixer strip
*/
void
RouteUI::adjust_latency ()
{
- LatencyDialog dialog (_route->name() + _(" latency"), *(_route->output()), _session->frame_rate(), _session->engine().frames_per_cycle());
+ LatencyDialog dialog (_route->name() + _(" latency"), *(_route->output()), _session->frame_rate(), AudioEngine::instance()->samples_per_cycle());
}
void
RouteUI::save_as_template ()
{
- sys::path path;
+ std::string path;
std::string safe_name;
string name;
path = ARDOUR::user_route_template_directory ();
- if (g_mkdir_with_parents (path.to_string().c_str(), 0755)) {
- error << string_compose (_("Cannot create route template directory %1"), path.to_string()) << endmsg;
+ if (g_mkdir_with_parents (path.c_str(), 0755)) {
+ error << string_compose (_("Cannot create route template directory %1"), path) << endmsg;
return;
}
safe_name = legalize_for_path (name);
safe_name += template_suffix;
- path /= safe_name;
+ path = Glib::build_filename (path, safe_name);
- _route->save_as_template (path.to_string(), name);
+ _route->save_as_template (path, name);
}
void
RouteUI::open_remote_control_id_dialog ()
{
ArdourDialog dialog (_("Remote Control ID"));
+ SpinButton* spin = 0;
- uint32_t const limit = _session->ntracks() + _session->nbusses () + 4;
-
- HBox* hbox = manage (new HBox);
- hbox->set_spacing (6);
- hbox->pack_start (*manage (new Label (_("Remote control ID:"))));
- SpinButton* spin = manage (new SpinButton);
- spin->set_digits (0);
- spin->set_increments (1, 10);
- spin->set_range (0, limit);
- spin->set_value (_route->remote_control_id());
- hbox->pack_start (*spin);
- dialog.get_vbox()->pack_start (*hbox);
+ dialog.get_vbox()->set_border_width (18);
- dialog.add_button (Stock::CANCEL, RESPONSE_CANCEL);
- dialog.add_button (Stock::APPLY, RESPONSE_ACCEPT);
+ if (Config->get_remote_model() == UserOrdered) {
+ uint32_t const limit = _session->ntracks() + _session->nbusses () + 4;
+
+ HBox* hbox = manage (new HBox);
+ hbox->set_spacing (6);
+ hbox->pack_start (*manage (new Label (_("Remote control ID:"))));
+ spin = manage (new SpinButton);
+ spin->set_digits (0);
+ spin->set_increments (1, 10);
+ spin->set_range (0, limit);
+ spin->set_value (_route->remote_control_id());
+ hbox->pack_start (*spin);
+ dialog.get_vbox()->pack_start (*hbox);
+
+ dialog.add_button (Stock::CANCEL, RESPONSE_CANCEL);
+ dialog.add_button (Stock::APPLY, RESPONSE_ACCEPT);
+ } else {
+ Label* l = manage (new Label());
+ if (_route->is_master() || _route->is_monitor()) {
+ l->set_markup (string_compose (_("The remote control ID of %1 is: %2\n\n\n"
+ "The remote control ID of %3 cannot be changed."),
+ Glib::Markup::escape_text (_route->name()),
+ _route->remote_control_id(),
+ (_route->is_master() ? _("the master bus") : _("the monitor bus"))));
+ } else {
+ l->set_markup (string_compose (_("The remote control ID of %6 is: %3\n\n\n"
+ "Remote Control IDs are currently determined by track/bus ordering in %1\n\n"
+ "%4Use the User Interaction tab of the Preferences window if you want to change this%5"),
+ (Config->get_remote_model() == MixerOrdered ? _("the mixer") : _("the editor")),
+ (is_track() ? _("track") : _("bus")),
+ _route->remote_control_id(),
+ "<span size=\"small\" style=\"italic\">",
+ "</span>",
+ Glib::Markup::escape_text (_route->name())));
+ }
+ dialog.get_vbox()->pack_start (*l);
+ dialog.add_button (Stock::OK, RESPONSE_CANCEL);
+ }
dialog.show_all ();
int const r = dialog.run ();
- if (r == RESPONSE_ACCEPT) {
+ if (r == RESPONSE_ACCEPT && spin) {
_route->set_remote_control_id (spin->get_value_as_int ());
}
}
for (uint32_t i = 0; i < to_add; ++i) {
ArdourButton* b = manage (new ArdourButton);
+ b->set_size_request(20,20);
b->signal_button_press_event().connect (sigc::mem_fun (*this, &RouteUI::invert_press));
b->signal_button_release_event().connect (sigc::bind (sigc::mem_fun (*this, &RouteUI::invert_release), i));
- b->set_name (X_("mixer strip button"));
+ b->set_name (X_("invert button"));
if (to_add == 1) {
if (N > 1) {
b->set_text (string_compose (X_("Ø (%1)"), N));