2005-09-25 14:42:24 -04:00
|
|
|
/*
|
2009-10-14 12:10:01 -04:00
|
|
|
Copyright (C) 2002-2006 Paul Davis
|
2005-09-25 14:42:24 -04:00
|
|
|
|
|
|
|
This program is free software; you can redistribute it and/or modify
|
|
|
|
it under the terms of the GNU General Public License as published by
|
|
|
|
the Free Software Foundation; either version 2 of the License, or
|
|
|
|
(at your option) any later version.
|
|
|
|
|
|
|
|
This program is distributed in the hope that it will be useful,
|
|
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
GNU General Public License for more details.
|
|
|
|
|
|
|
|
You should have received a copy of the GNU General Public License
|
|
|
|
along with this program; if not, write to the Free Software
|
|
|
|
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
|
|
|
|
|
|
|
*/
|
|
|
|
|
2005-09-25 16:33:00 -04:00
|
|
|
#include <gtkmm2ext/gtk_ui.h>
|
|
|
|
#include <gtkmm2ext/choice.h>
|
|
|
|
#include <gtkmm2ext/doi.h>
|
2006-07-13 23:43:32 -04:00
|
|
|
#include <gtkmm2ext/bindable_button.h>
|
2007-06-27 18:06:35 -04:00
|
|
|
#include <gtkmm2ext/barcontroller.h>
|
2008-12-12 09:43:24 -05:00
|
|
|
#include <gtkmm2ext/gtk_ui.h>
|
2014-07-30 18:27:12 -04:00
|
|
|
#include <gtkmm2ext/utils.h>
|
2005-09-25 14:42:24 -04:00
|
|
|
|
2009-02-25 13:26:51 -05:00
|
|
|
#include "ardour/route_group.h"
|
2009-07-13 19:09:16 -04:00
|
|
|
#include "ardour/dB.h"
|
2009-02-25 13:26:51 -05:00
|
|
|
#include "pbd/memento_command.h"
|
|
|
|
#include "pbd/stacktrace.h"
|
|
|
|
#include "pbd/controllable.h"
|
2009-11-18 08:25:13 -05:00
|
|
|
#include "pbd/enumwriter.h"
|
2005-09-25 14:42:24 -04:00
|
|
|
|
2009-05-17 13:05:56 -04:00
|
|
|
#include "ardour_ui.h"
|
2009-06-17 21:48:11 -04:00
|
|
|
#include "editor.h"
|
2005-09-25 14:42:24 -04:00
|
|
|
#include "route_ui.h"
|
2011-10-26 17:01:14 -04:00
|
|
|
#include "ardour_button.h"
|
2005-09-25 14:42:24 -04:00
|
|
|
#include "keyboard.h"
|
|
|
|
#include "utils.h"
|
|
|
|
#include "prompter.h"
|
|
|
|
#include "gui_thread.h"
|
2007-06-27 18:06:35 -04:00
|
|
|
#include "ardour_dialog.h"
|
|
|
|
#include "latency_gui.h"
|
2009-05-16 22:08:13 -04:00
|
|
|
#include "mixer_strip.h"
|
2007-07-03 20:39:00 -04:00
|
|
|
#include "automation_time_axis.h"
|
2009-11-19 12:06:00 -05:00
|
|
|
#include "route_time_axis.h"
|
2011-08-31 15:14:12 -04:00
|
|
|
#include "group_tabs.h"
|
2014-12-25 10:02:00 -05:00
|
|
|
#include "timers.h"
|
2005-09-25 14:42:24 -04:00
|
|
|
|
2009-02-25 13:26:51 -05:00
|
|
|
#include "ardour/audio_track.h"
|
2012-05-24 02:09:29 -04:00
|
|
|
#include "ardour/audioengine.h"
|
|
|
|
#include "ardour/filename_extensions.h"
|
2009-02-25 13:26:51 -05:00
|
|
|
#include "ardour/midi_track.h"
|
2014-08-01 14:48:33 -04:00
|
|
|
#include "ardour/internal_send.h"
|
|
|
|
#include "ardour/send.h"
|
2012-05-24 02:09:29 -04:00
|
|
|
#include "ardour/route.h"
|
|
|
|
#include "ardour/session.h"
|
2009-03-02 13:08:15 -05:00
|
|
|
#include "ardour/template_utils.h"
|
2005-09-25 14:42:24 -04:00
|
|
|
|
|
|
|
#include "i18n.h"
|
|
|
|
using namespace Gtk;
|
2005-09-25 16:33:00 -04:00
|
|
|
using namespace Gtkmm2ext;
|
2005-09-25 14:42:24 -04:00
|
|
|
using namespace ARDOUR;
|
2014-06-25 15:27:37 -04:00
|
|
|
using namespace ARDOUR_UI_UTILS;
|
Large nasty commit in the form of a 5000 line patch chock-full of completely
unecessary changes. (Sorry, doing a "sprint" based thing, this is the end of the first one)
Achieved MIDI track and bus creation, associated Jack port and diskstream creation, and minimal GUI stuff for creating them. Should be set to start work on actually recording and playing midi to/from disk now.
Relevant (significant) changes:
- Creation of a Buffer class. Base class is type agnostic so things can point to a buffer but not care what kind it is (otherwise it'd be a template). Derived into AudioBuffer and MidiBuffer, with a type tag because checking type is necessary in parts of the code where dynamic_cast wouldn't be wise. Originally I considered this a hack, but passing around a type proved to be a very good solution to all the other problems (below). There is a 1:1 mapping between jack port data types and ardour Buffer types (with a conversion function), but that's easily removed if it ever becomes necessary. Having the type scoped in the Buffer class is maybe not the best spot for it, but whatever (this is proof of concept kinda stuff right now...)
- IO now has a "default" port type (passed to the constructor and stored as a member), used by ensure_io (and similar) to create n ports. IO::register_***_port has a type argument that defaults to the default type if not passed. Rationale: previous IO API is identical, no changes needed to existing code, but path is paved for multiple port types in one IO, which we will need for eg synth plugin inserts, among other things. This is not quite ideal (best would be to only have the two port register functions and have them take a type), but the alternative is a lot of work (namely destroying the 'ensure' functions and everything that uses them) for very little gain. (I am convinced after quite a few tries at the whiteboard that subclassing IO in any way is not a feasible option, look at it's inheritance diagram in Doxygen and you can see why)
- AudioEngine::register_audio_input_port is now register_input_port and takes a type argument. Ditto for output.
- (Most significant change) AudioDiskstream abstracted into Distream, and sibling MidiDiskstream created. Very much still a work in progress, but Diskstream is there to switch references over to (most already are), which is the important part. It is still unclear what the MIDI diskstream's relation to channels is, but I'm pretty sure they will be single channel only (so SMF Type 0) since noone can come up with a reason otherwise.
- MidiTrack creation. Same thing as AudioTrack but with a different default type basically. No big deal here.
- Random cleanups and variable renamings etc. because I have OCD and can't help myself. :)
Known broken: Loading of sessions containing MIDI tracks.
git-svn-id: svn://localhost/ardour2/branches/midi@641 d708f5d6-7413-0410-9779-e7cbd77b26cf
2006-06-26 12:01:34 -04:00
|
|
|
using namespace PBD;
|
2014-11-30 18:27:04 -05:00
|
|
|
using namespace std;
|
2005-09-25 14:42:24 -04:00
|
|
|
|
2010-09-16 16:12:30 -04:00
|
|
|
uint32_t RouteUI::_max_invert_buttons = 3;
|
2013-07-30 09:12:32 -04:00
|
|
|
PBD::Signal1<void, boost::shared_ptr<Route> > RouteUI::BusSendDisplayChanged;
|
2011-11-02 20:42:16 -04:00
|
|
|
boost::weak_ptr<Route> RouteUI::_showing_sends_to;
|
2010-08-13 17:33:01 -04:00
|
|
|
|
2009-12-17 13:24:23 -05:00
|
|
|
RouteUI::RouteUI (ARDOUR::Session* sess)
|
2008-12-08 11:07:28 -05:00
|
|
|
: AxisView(sess)
|
2013-07-23 07:30:23 -04:00
|
|
|
, mute_menu(0)
|
|
|
|
, solo_menu(0)
|
|
|
|
, sends_menu(0)
|
|
|
|
, record_menu(0)
|
2014-07-29 17:40:19 -04:00
|
|
|
, comment_window(0)
|
2014-08-27 11:49:36 -04:00
|
|
|
, comment_area(0)
|
2014-08-14 11:42:48 -04:00
|
|
|
, input_selector (0)
|
|
|
|
, output_selector (0)
|
2013-07-23 07:30:23 -04:00
|
|
|
, _invert_menu(0)
|
2008-12-08 11:07:28 -05:00
|
|
|
{
|
2013-07-02 16:56:35 -04:00
|
|
|
if (sess) init ();
|
2008-12-08 11:07:28 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
RouteUI::~RouteUI()
|
|
|
|
{
|
2015-04-01 11:58:20 -04:00
|
|
|
if (_route) {
|
|
|
|
gui_object_state().remove_node (route_state_id());
|
|
|
|
}
|
2015-03-30 15:27:18 -04:00
|
|
|
|
2009-12-25 16:06:52 -05:00
|
|
|
_route.reset (); /* drop reference to route, so that it can be cleaned up */
|
|
|
|
route_connections.drop_connections ();
|
2015-03-30 15:27:18 -04:00
|
|
|
|
2008-12-08 11:07:28 -05:00
|
|
|
delete solo_menu;
|
|
|
|
delete mute_menu;
|
2009-05-16 22:08:13 -04:00
|
|
|
delete sends_menu;
|
2010-07-24 12:40:56 -04:00
|
|
|
delete record_menu;
|
2014-07-29 17:40:19 -04:00
|
|
|
delete comment_window;
|
2014-08-01 14:48:33 -04:00
|
|
|
delete input_selector;
|
|
|
|
delete output_selector;
|
2014-08-14 11:42:48 -04:00
|
|
|
delete _invert_menu;
|
2014-08-22 12:45:34 -04:00
|
|
|
|
|
|
|
send_blink_connection.disconnect ();
|
|
|
|
rec_blink_connection.disconnect ();
|
2008-12-08 11:07:28 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
RouteUI::init ()
|
2005-09-25 14:42:24 -04:00
|
|
|
{
|
2009-04-15 14:04:23 -04:00
|
|
|
self_destruct = true;
|
2005-09-25 14:42:24 -04:00
|
|
|
mute_menu = 0;
|
|
|
|
solo_menu = 0;
|
2009-05-16 22:08:13 -04:00
|
|
|
sends_menu = 0;
|
2010-07-24 12:40:56 -04:00
|
|
|
record_menu = 0;
|
2010-08-13 17:33:01 -04:00
|
|
|
_invert_menu = 0;
|
2009-11-18 08:25:13 -05:00
|
|
|
pre_fader_mute_check = 0;
|
|
|
|
post_fader_mute_check = 0;
|
|
|
|
listen_mute_check = 0;
|
|
|
|
main_mute_check = 0;
|
2010-04-20 08:38:37 -04:00
|
|
|
solo_safe_check = 0;
|
|
|
|
solo_isolated_check = 0;
|
2010-05-05 16:29:46 -04:00
|
|
|
solo_isolated_led = 0;
|
|
|
|
solo_safe_led = 0;
|
2009-12-10 12:45:18 -05:00
|
|
|
_solo_release = 0;
|
|
|
|
_mute_release = 0;
|
2007-05-31 22:27:21 -04:00
|
|
|
denormal_menu_item = 0;
|
2010-07-24 12:40:56 -04:00
|
|
|
step_edit_item = 0;
|
2008-12-12 09:43:24 -05:00
|
|
|
multiple_mute_change = false;
|
|
|
|
multiple_solo_change = false;
|
2010-08-13 17:33:01 -04:00
|
|
|
_i_am_the_modifier = 0;
|
2005-09-25 14:42:24 -04:00
|
|
|
|
2014-08-01 14:48:33 -04:00
|
|
|
input_selector = 0;
|
|
|
|
output_selector = 0;
|
|
|
|
|
2010-08-13 17:33:01 -04:00
|
|
|
setup_invert_buttons ();
|
2010-03-30 13:44:02 -04:00
|
|
|
|
2011-11-02 12:46:49 -04:00
|
|
|
mute_button = manage (new ArdourButton);
|
|
|
|
mute_button->set_name ("mute button");
|
2008-12-12 09:43:24 -05:00
|
|
|
UI::instance()->set_tip (mute_button, _("Mute this track"), "");
|
2008-12-08 11:07:28 -05:00
|
|
|
|
2011-11-02 14:48:32 -04:00
|
|
|
solo_button = manage (new ArdourButton);
|
2011-11-02 12:46:49 -04:00
|
|
|
solo_button->set_name ("solo button");
|
2008-12-12 09:43:24 -05:00
|
|
|
UI::instance()->set_tip (solo_button, _("Mute other (non-soloed) tracks"), "");
|
2009-06-11 09:22:42 -04:00
|
|
|
solo_button->set_no_show_all (true);
|
2008-12-08 11:07:28 -05:00
|
|
|
|
2011-11-02 15:51:59 -04:00
|
|
|
rec_enable_button = manage (new ArdourButton);
|
2011-11-02 12:46:49 -04:00
|
|
|
rec_enable_button->set_name ("record enable button");
|
2015-05-24 15:45:39 -04:00
|
|
|
rec_enable_button->set_icon (ArdourIcon::RecButton);
|
2008-12-12 09:43:24 -05:00
|
|
|
UI::instance()->set_tip (rec_enable_button, _("Enable recording on this track"), "");
|
|
|
|
|
2014-09-04 22:20:15 -04:00
|
|
|
if (ARDOUR_UI::config()->get_blink_rec_arm()) {
|
2014-12-25 10:02:00 -05:00
|
|
|
rec_blink_connection = Timers::blink_connect (sigc::mem_fun (*this, &RouteUI::blink_rec_display));
|
2014-09-04 22:20:15 -04:00
|
|
|
}
|
2014-08-22 12:45:34 -04:00
|
|
|
|
2011-11-02 12:46:49 -04:00
|
|
|
show_sends_button = manage (new ArdourButton);
|
|
|
|
show_sends_button->set_name ("send alert button");
|
2009-05-16 22:08:13 -04:00
|
|
|
UI::instance()->set_tip (show_sends_button, _("make mixer strips show sends to this bus"), "");
|
|
|
|
|
2012-02-07 12:43:55 -05:00
|
|
|
monitor_input_button = manage (new ArdourButton (ArdourButton::default_elements));
|
|
|
|
monitor_input_button->set_name ("monitor button");
|
2011-10-26 17:01:14 -04:00
|
|
|
monitor_input_button->set_text (_("In"));
|
2011-10-20 14:50:29 -04:00
|
|
|
UI::instance()->set_tip (monitor_input_button, _("Monitor input"), "");
|
|
|
|
monitor_input_button->set_no_show_all (true);
|
2012-02-07 12:43:55 -05:00
|
|
|
|
|
|
|
monitor_disk_button = manage (new ArdourButton (ArdourButton::default_elements));
|
|
|
|
monitor_disk_button->set_name ("monitor button");
|
2011-10-26 17:01:14 -04:00
|
|
|
monitor_disk_button->set_text (_("Disk"));
|
2011-10-20 14:50:29 -04:00
|
|
|
UI::instance()->set_tip (monitor_disk_button, _("Monitor playback"), "");
|
|
|
|
monitor_disk_button->set_no_show_all (true);
|
|
|
|
|
2010-03-30 11:18:43 -04:00
|
|
|
_session->SoloChanged.connect (_session_connections, invalidator (*this), boost::bind (&RouteUI::solo_changed_so_update_mute, this), gui_context());
|
|
|
|
_session->TransportStateChange.connect (_session_connections, invalidator (*this), boost::bind (&RouteUI::check_rec_enable_sensitivity, this), gui_context());
|
|
|
|
_session->RecordStateChanged.connect (_session_connections, invalidator (*this), boost::bind (&RouteUI::session_rec_enable_changed, this), gui_context());
|
2009-06-14 13:56:29 -04:00
|
|
|
|
2012-04-25 08:58:19 -04:00
|
|
|
_session->config.ParameterChanged.connect (*this, invalidator (*this), boost::bind (&RouteUI::parameter_changed, this, _1), gui_context());
|
|
|
|
Config->ParameterChanged.connect (*this, invalidator (*this), boost::bind (&RouteUI::parameter_changed, this, _1), gui_context());
|
2010-01-04 09:54:08 -05:00
|
|
|
|
|
|
|
rec_enable_button->signal_button_press_event().connect (sigc::mem_fun(*this, &RouteUI::rec_enable_press), false);
|
|
|
|
rec_enable_button->signal_button_release_event().connect (sigc::mem_fun(*this, &RouteUI::rec_enable_release), false);
|
|
|
|
|
|
|
|
show_sends_button->signal_button_press_event().connect (sigc::mem_fun(*this, &RouteUI::show_sends_press), false);
|
2014-08-28 11:31:57 -04:00
|
|
|
show_sends_button->signal_button_release_event().connect (sigc::mem_fun(*this, &RouteUI::show_sends_release), false);
|
2010-01-04 09:54:08 -05:00
|
|
|
|
|
|
|
solo_button->signal_button_press_event().connect (sigc::mem_fun(*this, &RouteUI::solo_press), false);
|
|
|
|
solo_button->signal_button_release_event().connect (sigc::mem_fun(*this, &RouteUI::solo_release), false);
|
|
|
|
mute_button->signal_button_press_event().connect (sigc::mem_fun(*this, &RouteUI::mute_press), false);
|
|
|
|
mute_button->signal_button_release_event().connect (sigc::mem_fun(*this, &RouteUI::mute_release), false);
|
2011-10-26 17:01:14 -04:00
|
|
|
|
|
|
|
monitor_input_button->set_distinct_led_click (false);
|
|
|
|
monitor_disk_button->set_distinct_led_click (false);
|
2011-10-20 14:50:29 -04:00
|
|
|
|
2014-08-28 11:31:57 -04:00
|
|
|
monitor_input_button->signal_button_press_event().connect (sigc::mem_fun(*this, &RouteUI::monitor_input_press), false);
|
|
|
|
monitor_input_button->signal_button_release_event().connect (sigc::mem_fun(*this, &RouteUI::monitor_input_release), false);
|
2011-10-20 14:50:29 -04:00
|
|
|
|
2014-08-28 11:31:57 -04:00
|
|
|
monitor_disk_button->signal_button_press_event().connect (sigc::mem_fun(*this, &RouteUI::monitor_disk_press), false);
|
|
|
|
monitor_disk_button->signal_button_release_event().connect (sigc::mem_fun(*this, &RouteUI::monitor_disk_release), false);
|
2011-11-02 20:42:16 -04:00
|
|
|
|
2013-07-30 11:54:52 -04:00
|
|
|
BusSendDisplayChanged.connect_same_thread (*this, boost::bind(&RouteUI::bus_send_display_changed, this, _1));
|
2008-12-08 11:07:28 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
RouteUI::reset ()
|
|
|
|
{
|
2009-12-19 15:26:31 -05:00
|
|
|
route_connections.drop_connections ();
|
2008-12-08 11:07:28 -05:00
|
|
|
|
2008-12-18 14:31:00 -05:00
|
|
|
delete solo_menu;
|
|
|
|
solo_menu = 0;
|
2008-12-08 11:07:28 -05:00
|
|
|
|
2008-12-18 14:31:00 -05:00
|
|
|
delete mute_menu;
|
|
|
|
mute_menu = 0;
|
2009-10-14 12:10:01 -04:00
|
|
|
|
2008-12-08 11:07:28 -05:00
|
|
|
denormal_menu_item = 0;
|
|
|
|
}
|
2005-09-25 14:42:24 -04:00
|
|
|
|
2009-12-17 13:24:23 -05:00
|
|
|
void
|
|
|
|
RouteUI::self_delete ()
|
|
|
|
{
|
2011-09-08 13:48:58 -04:00
|
|
|
delete this;
|
2009-12-17 13:24:23 -05:00
|
|
|
}
|
|
|
|
|
2008-12-08 11:07:28 -05:00
|
|
|
void
|
|
|
|
RouteUI::set_route (boost::shared_ptr<Route> rp)
|
|
|
|
{
|
|
|
|
reset ();
|
2007-03-18 02:07:08 -04:00
|
|
|
|
2008-12-08 11:07:28 -05:00
|
|
|
_route = rp;
|
2006-11-19 11:45:16 -05:00
|
|
|
|
2008-12-08 11:07:28 -05:00
|
|
|
if (set_color_from_route()) {
|
|
|
|
set_color (unique_random_color());
|
|
|
|
}
|
2007-03-18 02:07:08 -04:00
|
|
|
|
2009-04-15 14:04:23 -04:00
|
|
|
if (self_destruct) {
|
2010-03-30 11:18:43 -04:00
|
|
|
rp->DropReferences.connect (route_connections, invalidator (*this), boost::bind (&RouteUI::self_delete, this), gui_context());
|
2009-04-15 14:04:23 -04:00
|
|
|
}
|
2011-06-01 13:00:29 -04:00
|
|
|
|
2014-08-01 14:48:33 -04:00
|
|
|
delete input_selector;
|
|
|
|
input_selector = 0;
|
|
|
|
|
|
|
|
delete output_selector;
|
|
|
|
output_selector = 0;
|
|
|
|
|
2008-12-08 11:07:28 -05:00
|
|
|
mute_button->set_controllable (_route->mute_control());
|
|
|
|
solo_button->set_controllable (_route->solo_control());
|
2009-10-14 12:10:01 -04:00
|
|
|
|
2010-03-30 11:18:43 -04:00
|
|
|
_route->active_changed.connect (route_connections, invalidator (*this), boost::bind (&RouteUI::route_active_changed, this), gui_context());
|
2015-03-31 12:31:06 -04:00
|
|
|
_route->mute_changed.connect (route_connections, invalidator (*this), boost::bind (&RouteUI::update_mute_display, this), gui_context());
|
2010-04-26 23:10:53 -04:00
|
|
|
|
2014-07-29 17:40:19 -04:00
|
|
|
_route->comment_changed.connect (route_connections, invalidator (*this), boost::bind (&RouteUI::comment_changed, this, _1), gui_context());
|
|
|
|
|
2010-04-26 23:10:53 -04:00
|
|
|
_route->solo_changed.connect (route_connections, invalidator (*this), boost::bind (&RouteUI::update_solo_display, this), gui_context());
|
|
|
|
_route->solo_safe_changed.connect (route_connections, invalidator (*this), boost::bind (&RouteUI::update_solo_display, this), gui_context());
|
|
|
|
_route->listen_changed.connect (route_connections, invalidator (*this), boost::bind (&RouteUI::update_solo_display, this), gui_context());
|
|
|
|
_route->solo_isolated_changed.connect (route_connections, invalidator (*this), boost::bind (&RouteUI::update_solo_display, this), gui_context());
|
2014-09-02 20:35:42 -04:00
|
|
|
if (is_track()) {
|
|
|
|
track()->TrackModeChanged.connect (route_connections, invalidator (*this), boost::bind (&RouteUI::track_mode_changed, this), gui_context());
|
|
|
|
track_mode_changed();
|
|
|
|
}
|
2010-04-26 23:10:53 -04:00
|
|
|
|
2014-09-02 20:37:10 -04:00
|
|
|
_route->phase_invert_changed.connect (route_connections, invalidator (*this), boost::bind (&RouteUI::polarity_changed, this), gui_context());
|
2012-04-25 08:58:19 -04:00
|
|
|
_route->PropertyChanged.connect (route_connections, invalidator (*this), boost::bind (&RouteUI::property_changed, this, _1), gui_context());
|
2009-10-14 12:10:01 -04:00
|
|
|
|
2012-04-25 08:58:19 -04:00
|
|
|
_route->io_changed.connect (route_connections, invalidator (*this), boost::bind (&RouteUI::setup_invert_buttons, this), gui_context ());
|
|
|
|
_route->gui_changed.connect (route_connections, invalidator (*this), boost::bind (&RouteUI::route_gui_changed, this, _1), gui_context ());
|
2010-08-13 17:33:01 -04:00
|
|
|
|
2009-12-17 13:24:23 -05:00
|
|
|
if (_session->writable() && is_track()) {
|
2006-07-27 21:08:57 -04:00
|
|
|
boost::shared_ptr<Track> t = boost::dynamic_pointer_cast<Track>(_route);
|
2005-09-25 14:42:24 -04:00
|
|
|
|
2010-04-21 16:42:22 -04:00
|
|
|
t->RecordEnableChanged.connect (route_connections, invalidator (*this), boost::bind (&RouteUI::route_rec_enable_changed, this), gui_context());
|
2011-10-20 14:50:29 -04:00
|
|
|
|
2007-07-07 01:04:34 -04:00
|
|
|
rec_enable_button->show();
|
2008-12-08 11:07:28 -05:00
|
|
|
rec_enable_button->set_controllable (t->rec_enable_control());
|
|
|
|
|
2010-07-24 12:40:56 -04:00
|
|
|
if (is_midi_track()) {
|
|
|
|
midi_track()->StepEditStatusChange.connect (route_connections, invalidator (*this),
|
2012-04-25 08:58:19 -04:00
|
|
|
boost::bind (&RouteUI::step_edit_changed, this, _1), gui_context());
|
2010-07-24 12:40:56 -04:00
|
|
|
}
|
|
|
|
|
2012-12-27 09:08:38 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
/* this will work for busses and tracks, and needs to be called to
|
|
|
|
set up the name entry/name label display.
|
|
|
|
*/
|
|
|
|
|
2011-10-20 14:50:29 -04:00
|
|
|
if (is_track()) {
|
|
|
|
boost::shared_ptr<Track> t = boost::dynamic_pointer_cast<Track>(_route);
|
|
|
|
t->MonitoringChanged.connect (route_connections, invalidator (*this), boost::bind (&RouteUI::monitoring_changed, this), gui_context());
|
2011-10-21 08:40:06 -04:00
|
|
|
|
|
|
|
update_monitoring_display ();
|
2011-10-20 14:50:29 -04:00
|
|
|
}
|
|
|
|
|
2005-09-25 16:33:00 -04:00
|
|
|
mute_button->unset_flags (Gtk::CAN_FOCUS);
|
|
|
|
solo_button->unset_flags (Gtk::CAN_FOCUS);
|
2009-10-14 12:10:01 -04:00
|
|
|
|
2007-07-07 01:04:34 -04:00
|
|
|
mute_button->show();
|
2009-06-11 09:22:42 -04:00
|
|
|
|
2013-07-09 10:36:58 -04:00
|
|
|
if (_route->is_monitor() || _route->is_master()) {
|
2009-06-11 09:22:42 -04:00
|
|
|
solo_button->hide ();
|
|
|
|
} else {
|
|
|
|
solo_button->show();
|
|
|
|
}
|
2007-07-07 01:04:34 -04:00
|
|
|
|
2005-09-25 14:42:24 -04:00
|
|
|
map_frozen ();
|
|
|
|
|
2010-08-13 17:33:01 -04:00
|
|
|
setup_invert_buttons ();
|
|
|
|
set_invert_button_state ();
|
2011-11-02 20:42:16 -04:00
|
|
|
|
|
|
|
boost::shared_ptr<Route> s = _showing_sends_to.lock ();
|
|
|
|
bus_send_display_changed (s);
|
2011-11-19 07:18:20 -05:00
|
|
|
|
|
|
|
update_mute_display ();
|
|
|
|
update_solo_display ();
|
2014-08-22 12:45:34 -04:00
|
|
|
|
2014-09-06 07:23:59 -04:00
|
|
|
if (!ARDOUR_UI::config()->get_blink_rec_arm()) {
|
|
|
|
blink_rec_display(true); // set initial rec-en button state
|
|
|
|
}
|
|
|
|
|
2014-08-22 12:45:34 -04:00
|
|
|
route_color_changed();
|
2010-03-30 13:44:02 -04:00
|
|
|
}
|
|
|
|
|
2010-03-30 20:59:09 -04:00
|
|
|
void
|
|
|
|
RouteUI::polarity_changed ()
|
2010-03-30 13:44:02 -04:00
|
|
|
{
|
2010-03-30 20:59:09 -04:00
|
|
|
if (!_route) {
|
|
|
|
return;
|
|
|
|
}
|
2010-08-13 17:33:01 -04:00
|
|
|
|
|
|
|
set_invert_button_state ();
|
2010-03-30 13:44:02 -04:00
|
|
|
}
|
|
|
|
|
2006-09-18 23:29:16 -04:00
|
|
|
bool
|
2009-12-10 12:45:18 -05:00
|
|
|
RouteUI::mute_press (GdkEventButton* ev)
|
2005-09-25 14:42:24 -04:00
|
|
|
{
|
2008-12-12 09:43:24 -05:00
|
|
|
if (ev->type == GDK_2BUTTON_PRESS || ev->type == GDK_3BUTTON_PRESS ) {
|
2008-04-11 10:06:50 -04:00
|
|
|
return true;
|
|
|
|
}
|
2009-12-10 12:45:18 -05:00
|
|
|
|
2014-08-28 11:31:57 -04:00
|
|
|
//if this is a binding action, let the ArdourButton handle it
|
|
|
|
if ( BindingProxy::is_bind_action(ev) )
|
|
|
|
return false;
|
|
|
|
|
2008-12-12 09:43:24 -05:00
|
|
|
multiple_mute_change = false;
|
2009-12-10 12:45:18 -05:00
|
|
|
|
2014-07-10 11:54:59 -04:00
|
|
|
if (Keyboard::is_context_menu_event (ev)) {
|
2005-09-25 14:42:24 -04:00
|
|
|
|
2014-07-10 11:54:59 -04:00
|
|
|
if (mute_menu == 0){
|
|
|
|
build_mute_menu();
|
|
|
|
}
|
2005-09-25 14:42:24 -04:00
|
|
|
|
2014-07-10 11:54:59 -04:00
|
|
|
mute_menu->popup(0,ev->time);
|
2014-08-22 12:45:34 -04:00
|
|
|
|
|
|
|
return true;
|
2005-09-25 14:42:24 -04:00
|
|
|
|
2014-07-10 11:54:59 -04:00
|
|
|
} else {
|
2009-10-14 12:10:01 -04:00
|
|
|
|
2014-07-10 11:54:59 -04:00
|
|
|
if (Keyboard::is_button2_event (ev)) {
|
|
|
|
// button2-click is "momentary"
|
2010-03-16 11:33:04 -04:00
|
|
|
|
2014-07-10 11:54:59 -04:00
|
|
|
_mute_release = new SoloMuteRelease (_route->muted ());
|
|
|
|
}
|
|
|
|
|
|
|
|
if (ev->button == 1 || Keyboard::is_button2_event (ev)) {
|
2005-09-25 14:42:24 -04:00
|
|
|
|
2014-07-10 11:54:59 -04:00
|
|
|
if (Keyboard::modifier_state_equals (ev->state, Keyboard::ModifierMask (Keyboard::PrimaryModifier|Keyboard::TertiaryModifier))) {
|
2005-09-25 14:42:24 -04:00
|
|
|
|
2014-07-10 11:54:59 -04:00
|
|
|
/* 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.
|
|
|
|
*/
|
2013-02-05 13:16:10 -05:00
|
|
|
|
2014-07-10 11:54:59 -04:00
|
|
|
boost::shared_ptr<RouteList> copy (new RouteList);
|
2013-02-05 13:16:10 -05:00
|
|
|
|
2014-07-10 11:54:59 -04:00
|
|
|
*copy = *_session->get_routes ();
|
2013-02-05 13:16:10 -05:00
|
|
|
|
2014-07-10 11:54:59 -04:00
|
|
|
for (RouteList::iterator i = copy->begin(); i != copy->end(); ) {
|
|
|
|
if ((*i)->is_master() || (*i)->is_monitor()) {
|
|
|
|
i = copy->erase (i);
|
|
|
|
} else {
|
|
|
|
++i;
|
2013-02-05 13:16:10 -05:00
|
|
|
}
|
2014-07-10 11:54:59 -04:00
|
|
|
}
|
2013-02-05 13:16:10 -05:00
|
|
|
|
2014-07-10 11:54:59 -04:00
|
|
|
if (_mute_release) {
|
|
|
|
_mute_release->routes = copy;
|
|
|
|
}
|
2005-09-25 14:42:24 -04:00
|
|
|
|
2014-07-10 11:54:59 -04:00
|
|
|
DisplaySuspender ds;
|
|
|
|
_session->set_mute (copy, !_route->muted());
|
2005-09-25 14:42:24 -04:00
|
|
|
|
2014-07-10 11:54:59 -04:00
|
|
|
} else if (Keyboard::modifier_state_equals (ev->state, Keyboard::PrimaryModifier)) {
|
2005-09-25 14:42:24 -04:00
|
|
|
|
2014-07-10 11:54:59 -04:00
|
|
|
/* Primary-button1 applies change to the mix group even if it is not active
|
|
|
|
NOTE: Primary-button2 is MIDI learn.
|
|
|
|
*/
|
2005-09-25 14:42:24 -04:00
|
|
|
|
2014-07-10 11:54:59 -04:00
|
|
|
boost::shared_ptr<RouteList> rl;
|
2013-02-05 13:16:10 -05:00
|
|
|
|
2014-07-10 11:54:59 -04:00
|
|
|
if (ev->button == 1) {
|
2013-02-05 13:16:10 -05:00
|
|
|
|
2014-07-10 11:54:59 -04:00
|
|
|
if (_route->route_group()) {
|
2013-02-05 16:39:38 -05:00
|
|
|
|
2014-07-10 11:54:59 -04:00
|
|
|
rl = _route->route_group()->route_list();
|
2013-02-05 16:39:38 -05:00
|
|
|
|
2014-07-10 11:54:59 -04:00
|
|
|
if (_mute_release) {
|
|
|
|
_mute_release->routes = rl;
|
2009-12-10 12:45:18 -05:00
|
|
|
}
|
2014-07-10 11:54:59 -04:00
|
|
|
} else {
|
|
|
|
rl.reset (new RouteList);
|
|
|
|
rl->push_back (_route);
|
2005-09-25 14:42:24 -04:00
|
|
|
}
|
2009-10-14 12:10:01 -04:00
|
|
|
|
2014-07-10 11:54:59 -04:00
|
|
|
DisplaySuspender ds;
|
|
|
|
_session->set_mute (rl, !_route->muted(), Session::rt_cleanup, true);
|
|
|
|
}
|
2005-09-25 14:42:24 -04:00
|
|
|
|
2014-07-10 11:54:59 -04:00
|
|
|
} else {
|
2011-06-01 13:00:29 -04:00
|
|
|
|
2014-07-10 11:54:59 -04:00
|
|
|
/* plain click applies change to this route */
|
|
|
|
|
|
|
|
boost::shared_ptr<RouteList> rl (new RouteList);
|
|
|
|
rl->push_back (_route);
|
2013-02-05 16:39:38 -05:00
|
|
|
|
2014-07-10 11:54:59 -04:00
|
|
|
if (_mute_release) {
|
|
|
|
_mute_release->routes = rl;
|
|
|
|
}
|
2009-12-10 12:45:18 -05:00
|
|
|
|
2014-07-10 11:54:59 -04:00
|
|
|
_session->set_mute (rl, !_route->muted());
|
2009-12-10 12:45:18 -05:00
|
|
|
|
2005-09-25 14:42:24 -04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-08-22 12:45:34 -04:00
|
|
|
return false;
|
2005-09-25 14:42:24 -04:00
|
|
|
}
|
|
|
|
|
2006-09-18 23:29:16 -04:00
|
|
|
bool
|
2014-09-02 20:37:10 -04:00
|
|
|
RouteUI::mute_release (GdkEventButton* /*ev*/)
|
2005-09-25 14:42:24 -04:00
|
|
|
{
|
2014-07-10 11:54:59 -04:00
|
|
|
if (_mute_release){
|
|
|
|
DisplaySuspender ds;
|
|
|
|
_session->set_mute (_mute_release->routes, _mute_release->active, Session::rt_cleanup, true);
|
|
|
|
delete _mute_release;
|
|
|
|
_mute_release = 0;
|
2005-09-25 14:42:24 -04:00
|
|
|
}
|
2009-12-10 12:45:18 -05:00
|
|
|
|
2014-08-22 12:45:34 -04:00
|
|
|
return false;
|
2005-09-25 14:42:24 -04:00
|
|
|
}
|
|
|
|
|
2014-08-01 14:48:33 -04:00
|
|
|
void
|
|
|
|
RouteUI::edit_output_configuration ()
|
|
|
|
{
|
|
|
|
if (output_selector == 0) {
|
|
|
|
|
|
|
|
boost::shared_ptr<Send> send;
|
|
|
|
boost::shared_ptr<IO> output;
|
|
|
|
|
|
|
|
if ((send = boost::dynamic_pointer_cast<Send>(_current_delivery)) != 0) {
|
|
|
|
if (!boost::dynamic_pointer_cast<InternalSend>(send)) {
|
|
|
|
output = send->output();
|
|
|
|
} else {
|
|
|
|
output = _route->output ();
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
output = _route->output ();
|
|
|
|
}
|
|
|
|
|
|
|
|
output_selector = new IOSelectorWindow (_session, output);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (output_selector->is_visible()) {
|
|
|
|
output_selector->get_toplevel()->get_window()->raise();
|
|
|
|
} else {
|
|
|
|
output_selector->present ();
|
|
|
|
}
|
|
|
|
|
2015-03-11 13:06:20 -04:00
|
|
|
//output_selector->set_keep_above (true);
|
2014-08-01 14:48:33 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
RouteUI::edit_input_configuration ()
|
|
|
|
{
|
|
|
|
if (input_selector == 0) {
|
|
|
|
input_selector = new IOSelectorWindow (_session, _route->input());
|
|
|
|
}
|
|
|
|
|
|
|
|
if (input_selector->is_visible()) {
|
|
|
|
input_selector->get_toplevel()->get_window()->raise();
|
|
|
|
} else {
|
|
|
|
input_selector->present ();
|
|
|
|
}
|
|
|
|
|
2015-03-11 13:06:20 -04:00
|
|
|
//input_selector->set_keep_above (true);
|
2014-08-01 14:48:33 -04:00
|
|
|
}
|
|
|
|
|
2006-09-18 23:29:16 -04:00
|
|
|
bool
|
2005-09-25 14:42:24 -04:00
|
|
|
RouteUI::solo_press(GdkEventButton* ev)
|
|
|
|
{
|
2008-12-12 09:43:24 -05:00
|
|
|
/* ignore double/triple clicks */
|
2008-04-11 10:06:50 -04:00
|
|
|
|
2008-12-12 09:43:24 -05:00
|
|
|
if (ev->type == GDK_2BUTTON_PRESS || ev->type == GDK_3BUTTON_PRESS ) {
|
2008-04-11 10:06:50 -04:00
|
|
|
return true;
|
|
|
|
}
|
2011-06-01 13:00:29 -04:00
|
|
|
|
2014-08-28 11:31:57 -04:00
|
|
|
//if this is a binding action, let the ArdourButton handle it
|
|
|
|
if ( BindingProxy::is_bind_action(ev) )
|
|
|
|
return false;
|
|
|
|
|
2009-12-10 12:45:18 -05:00
|
|
|
multiple_solo_change = false;
|
2005-09-25 14:42:24 -04:00
|
|
|
|
2014-07-10 11:54:59 -04:00
|
|
|
if (Keyboard::is_context_menu_event (ev)) {
|
2011-06-01 13:00:29 -04:00
|
|
|
|
2014-07-10 11:54:59 -04:00
|
|
|
if (! (solo_isolated_led && solo_isolated_led->is_visible()) ||
|
|
|
|
! (solo_safe_led && solo_safe_led->is_visible())) {
|
2010-05-05 16:29:46 -04:00
|
|
|
|
2014-07-10 11:54:59 -04:00
|
|
|
if (solo_menu == 0) {
|
|
|
|
build_solo_menu ();
|
|
|
|
}
|
2011-06-01 13:00:29 -04:00
|
|
|
|
2014-07-10 11:54:59 -04:00
|
|
|
solo_menu->popup (1, ev->time);
|
|
|
|
}
|
2011-06-01 13:00:29 -04:00
|
|
|
|
2014-07-10 11:54:59 -04:00
|
|
|
} else {
|
2011-06-01 13:00:29 -04:00
|
|
|
|
2014-07-10 11:54:59 -04:00
|
|
|
if (Keyboard::is_button2_event (ev)) {
|
2011-06-01 13:00:29 -04:00
|
|
|
|
2014-08-22 12:45:34 -04:00
|
|
|
// button2-click is "momentary"
|
2014-07-10 11:54:59 -04:00
|
|
|
_solo_release = new SoloMuteRelease (_route->self_soloed());
|
|
|
|
}
|
2011-06-01 13:00:29 -04:00
|
|
|
|
2014-07-10 11:54:59 -04:00
|
|
|
if (ev->button == 1 || Keyboard::is_button2_event (ev)) {
|
2011-06-01 13:00:29 -04:00
|
|
|
|
2014-07-10 11:54:59 -04:00
|
|
|
if (Keyboard::modifier_state_equals (ev->state, Keyboard::ModifierMask (Keyboard::PrimaryModifier|Keyboard::TertiaryModifier))) {
|
2009-10-14 12:10:01 -04:00
|
|
|
|
2014-07-10 11:54:59 -04:00
|
|
|
/* Primary-Tertiary-click applies change to all routes */
|
2011-06-01 13:00:29 -04:00
|
|
|
|
2014-07-10 11:54:59 -04:00
|
|
|
if (_solo_release) {
|
|
|
|
_solo_release->routes = _session->get_routes ();
|
|
|
|
}
|
|
|
|
|
|
|
|
DisplaySuspender ds;
|
|
|
|
if (Config->get_solo_control_is_listen_control()) {
|
|
|
|
_session->set_listen (_session->get_routes(), !_route->listening_via_monitor(), Session::rt_cleanup, true);
|
|
|
|
} else {
|
|
|
|
_session->set_solo (_session->get_routes(), !_route->self_soloed(), Session::rt_cleanup, true);
|
|
|
|
}
|
2011-06-01 13:00:29 -04:00
|
|
|
|
2014-07-10 11:54:59 -04:00
|
|
|
} else if (Keyboard::modifier_state_contains (ev->state, Keyboard::ModifierMask (Keyboard::PrimaryModifier|Keyboard::SecondaryModifier))) {
|
2011-06-01 13:00:29 -04:00
|
|
|
|
2014-07-10 11:54:59 -04:00
|
|
|
// Primary-Secondary-click: exclusively solo this track
|
2009-12-10 12:45:18 -05:00
|
|
|
|
2014-07-10 11:54:59 -04:00
|
|
|
if (_solo_release) {
|
|
|
|
_solo_release->exclusive = true;
|
2009-12-10 12:45:18 -05:00
|
|
|
|
2014-07-10 11:54:59 -04:00
|
|
|
boost::shared_ptr<RouteList> routes = _session->get_routes();
|
2009-12-10 12:45:18 -05:00
|
|
|
|
2014-07-10 11:54:59 -04:00
|
|
|
for (RouteList::iterator i = routes->begin(); i != routes->end(); ++i) {
|
|
|
|
if ((*i)->soloed ()) {
|
|
|
|
_solo_release->routes_on->push_back (*i);
|
|
|
|
} else {
|
|
|
|
_solo_release->routes_off->push_back (*i);
|
2009-07-01 09:36:50 -04:00
|
|
|
}
|
2009-12-10 12:45:18 -05:00
|
|
|
}
|
2014-07-10 11:54:59 -04:00
|
|
|
}
|
2011-06-01 13:00:29 -04:00
|
|
|
|
2014-07-10 11:54:59 -04:00
|
|
|
if (Config->get_solo_control_is_listen_control()) {
|
|
|
|
/* ??? we need a just_one_listen() method */
|
|
|
|
} else {
|
|
|
|
DisplaySuspender ds;
|
|
|
|
_session->set_just_one_solo (_route, true);
|
|
|
|
}
|
2009-12-08 22:05:14 -05:00
|
|
|
|
2014-07-10 11:54:59 -04:00
|
|
|
} else if (Keyboard::modifier_state_equals (ev->state, Keyboard::TertiaryModifier)) {
|
2011-06-01 13:00:29 -04:00
|
|
|
|
2014-07-10 11:54:59 -04:00
|
|
|
// shift-click: toggle solo isolated status
|
2011-06-01 13:00:29 -04:00
|
|
|
|
2014-07-10 11:54:59 -04:00
|
|
|
_route->set_solo_isolated (!_route->solo_isolated(), this);
|
|
|
|
delete _solo_release;
|
|
|
|
_solo_release = 0;
|
2011-06-01 13:00:29 -04:00
|
|
|
|
2014-07-10 11:54:59 -04:00
|
|
|
} else if (Keyboard::modifier_state_equals (ev->state, Keyboard::PrimaryModifier)) {
|
2011-06-01 13:00:29 -04:00
|
|
|
|
2014-07-10 11:54:59 -04:00
|
|
|
/* Primary-button1: solo mix group.
|
|
|
|
NOTE: Primary-button2 is MIDI learn.
|
|
|
|
*/
|
2011-06-01 13:00:29 -04:00
|
|
|
|
2014-07-10 11:54:59 -04:00
|
|
|
/* Primary-button1 applies change to the mix group even if it is not active
|
|
|
|
NOTE: Primary-button2 is MIDI learn.
|
|
|
|
*/
|
2013-02-05 16:39:38 -05:00
|
|
|
|
2014-07-10 11:54:59 -04:00
|
|
|
boost::shared_ptr<RouteList> rl;
|
2013-02-05 16:39:38 -05:00
|
|
|
|
2014-07-10 11:54:59 -04:00
|
|
|
if (ev->button == 1) {
|
2005-09-25 14:42:24 -04:00
|
|
|
|
2014-07-10 11:54:59 -04:00
|
|
|
if (_route->route_group()) {
|
2013-02-05 16:39:38 -05:00
|
|
|
|
2014-07-10 11:54:59 -04:00
|
|
|
rl = _route->route_group()->route_list();
|
2013-02-05 16:39:38 -05:00
|
|
|
|
2014-07-10 11:54:59 -04:00
|
|
|
if (_solo_release) {
|
|
|
|
_solo_release->routes = rl;
|
2009-07-01 09:36:50 -04:00
|
|
|
}
|
2014-07-10 11:54:59 -04:00
|
|
|
} else {
|
|
|
|
rl.reset (new RouteList);
|
|
|
|
rl->push_back (_route);
|
|
|
|
}
|
2011-06-01 13:00:29 -04:00
|
|
|
|
2014-07-10 11:54:59 -04:00
|
|
|
DisplaySuspender ds;
|
|
|
|
if (Config->get_solo_control_is_listen_control()) {
|
|
|
|
_session->set_listen (rl, !_route->listening_via_monitor(), Session::rt_cleanup, true);
|
|
|
|
} else {
|
|
|
|
_session->set_solo (rl, !_route->self_soloed(), Session::rt_cleanup, true);
|
2009-12-10 12:45:18 -05:00
|
|
|
}
|
2014-07-10 11:54:59 -04:00
|
|
|
}
|
2011-06-01 13:00:29 -04:00
|
|
|
|
2014-07-10 11:54:59 -04:00
|
|
|
} else {
|
2011-06-01 13:00:29 -04:00
|
|
|
|
2014-07-10 11:54:59 -04:00
|
|
|
/* click: solo this route */
|
2011-06-01 13:00:29 -04:00
|
|
|
|
2014-07-10 11:54:59 -04:00
|
|
|
boost::shared_ptr<RouteList> rl (new RouteList);
|
|
|
|
rl->push_back (route());
|
2009-12-10 12:45:18 -05:00
|
|
|
|
2014-07-10 11:54:59 -04:00
|
|
|
if (_solo_release) {
|
|
|
|
_solo_release->routes = rl;
|
|
|
|
}
|
2005-09-25 14:42:24 -04:00
|
|
|
|
2014-07-10 11:54:59 -04:00
|
|
|
DisplaySuspender ds;
|
|
|
|
if (Config->get_solo_control_is_listen_control()) {
|
|
|
|
_session->set_listen (rl, !_route->listening_via_monitor());
|
|
|
|
} else {
|
|
|
|
_session->set_solo (rl, !_route->self_soloed());
|
2005-09-25 14:42:24 -04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-08-22 12:45:34 -04:00
|
|
|
return false;
|
2005-09-25 14:42:24 -04:00
|
|
|
}
|
|
|
|
|
2006-09-18 23:29:16 -04:00
|
|
|
bool
|
2014-09-02 20:37:10 -04:00
|
|
|
RouteUI::solo_release (GdkEventButton* /*ev*/)
|
2005-09-25 14:42:24 -04:00
|
|
|
{
|
2014-07-10 11:54:59 -04:00
|
|
|
if (_solo_release) {
|
2009-12-10 12:45:18 -05:00
|
|
|
|
2014-07-10 11:54:59 -04:00
|
|
|
if (_solo_release->exclusive) {
|
2009-12-10 12:45:18 -05:00
|
|
|
|
2014-07-10 11:54:59 -04:00
|
|
|
} else {
|
|
|
|
DisplaySuspender ds;
|
|
|
|
if (Config->get_solo_control_is_listen_control()) {
|
|
|
|
_session->set_listen (_solo_release->routes, _solo_release->active, Session::rt_cleanup, true);
|
2008-12-12 09:43:24 -05:00
|
|
|
} else {
|
2014-07-10 11:54:59 -04:00
|
|
|
_session->set_solo (_solo_release->routes, _solo_release->active, Session::rt_cleanup, true);
|
2008-12-12 09:43:24 -05:00
|
|
|
}
|
2005-09-25 14:42:24 -04:00
|
|
|
}
|
2014-07-10 11:54:59 -04:00
|
|
|
|
|
|
|
delete _solo_release;
|
|
|
|
_solo_release = 0;
|
2005-09-25 14:42:24 -04:00
|
|
|
}
|
2006-03-29 13:52:55 -05:00
|
|
|
|
2014-08-22 12:45:34 -04:00
|
|
|
return false;
|
2005-09-25 14:42:24 -04:00
|
|
|
}
|
|
|
|
|
2006-09-18 23:29:16 -04:00
|
|
|
bool
|
2005-09-25 14:42:24 -04:00
|
|
|
RouteUI::rec_enable_press(GdkEventButton* ev)
|
|
|
|
{
|
2008-12-12 09:43:24 -05:00
|
|
|
if (ev->type == GDK_2BUTTON_PRESS || ev->type == GDK_3BUTTON_PRESS ) {
|
2008-04-11 10:06:50 -04:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2014-08-28 11:31:57 -04:00
|
|
|
//if this is a binding action, let the ArdourButton handle it
|
|
|
|
if ( BindingProxy::is_bind_action(ev) )
|
|
|
|
return false;
|
|
|
|
|
2009-12-17 13:24:23 -05:00
|
|
|
if (!_session->engine().connected()) {
|
2014-04-10 13:30:25 -04:00
|
|
|
MessageDialog msg (_("Not connected to AudioEngine - cannot engage record"));
|
2006-11-19 11:45:16 -05:00
|
|
|
msg.run ();
|
2014-08-22 12:45:34 -04:00
|
|
|
return false;
|
2006-11-19 11:45:16 -05:00
|
|
|
}
|
|
|
|
|
2015-01-07 20:12:14 -05:00
|
|
|
if (is_midi_track()) {
|
2010-07-24 12:40:56 -04:00
|
|
|
|
2015-01-07 20:12:14 -05:00
|
|
|
/* rec-enable button exits from step editing */
|
2010-07-24 12:40:56 -04:00
|
|
|
|
2015-01-07 20:12:14 -05:00
|
|
|
if (midi_track()->step_editing()) {
|
2012-02-03 16:02:18 -05:00
|
|
|
midi_track()->set_step_editing (false);
|
2014-08-22 12:45:34 -04:00
|
|
|
return false;
|
2015-01-07 20:12:14 -05:00
|
|
|
}
|
|
|
|
}
|
2010-07-24 12:40:56 -04:00
|
|
|
|
2014-07-10 11:54:59 -04:00
|
|
|
if (is_track() && rec_enable_button) {
|
2005-09-25 14:42:24 -04:00
|
|
|
|
2010-03-16 11:33:04 -04:00
|
|
|
if (Keyboard::is_button2_event (ev)) {
|
2014-08-22 12:45:34 -04:00
|
|
|
|
|
|
|
//rec arm does not have a momentary mode
|
|
|
|
return false;
|
2007-03-18 02:07:08 -04:00
|
|
|
|
2008-01-10 16:20:59 -05:00
|
|
|
} else if (Keyboard::modifier_state_equals (ev->state, Keyboard::ModifierMask (Keyboard::PrimaryModifier|Keyboard::TertiaryModifier))) {
|
2005-09-25 14:42:24 -04:00
|
|
|
|
2014-06-28 20:52:56 -04:00
|
|
|
DisplaySuspender ds;
|
2014-08-22 12:45:34 -04:00
|
|
|
_session->set_record_enabled (_session->get_routes(), !_route->record_enabled());
|
2005-09-25 14:42:24 -04:00
|
|
|
|
2008-01-10 16:20:59 -05:00
|
|
|
} else if (Keyboard::modifier_state_equals (ev->state, Keyboard::PrimaryModifier)) {
|
|
|
|
|
2009-12-07 20:52:49 -05:00
|
|
|
/* Primary-button1 applies change to the route group (even if it is not active)
|
2008-01-10 16:20:59 -05:00
|
|
|
NOTE: Primary-button2 is MIDI learn.
|
|
|
|
*/
|
2013-02-05 16:39:38 -05:00
|
|
|
|
|
|
|
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);
|
|
|
|
}
|
2014-06-28 20:52:56 -04:00
|
|
|
|
|
|
|
DisplaySuspender ds;
|
2014-08-22 12:45:34 -04:00
|
|
|
_session->set_record_enabled (rl, !_route->record_enabled(), Session::rt_cleanup, true);
|
2009-12-07 20:52:49 -05:00
|
|
|
}
|
2005-09-25 14:42:24 -04:00
|
|
|
|
2009-09-03 08:39:50 -04:00
|
|
|
} else if (Keyboard::is_context_menu_event (ev)) {
|
2009-10-14 12:10:01 -04:00
|
|
|
|
2009-09-03 08:39:50 -04:00
|
|
|
/* do this on release */
|
|
|
|
|
2005-09-25 14:42:24 -04:00
|
|
|
} else {
|
2009-12-09 22:25:32 -05:00
|
|
|
|
2009-12-07 20:52:49 -05:00
|
|
|
boost::shared_ptr<RouteList> rl (new RouteList);
|
|
|
|
rl->push_back (route());
|
2014-06-28 20:52:56 -04:00
|
|
|
DisplaySuspender ds;
|
2014-08-22 12:45:34 -04:00
|
|
|
_session->set_record_enabled (rl, !_route->record_enabled());
|
2005-09-25 14:42:24 -04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-08-22 12:45:34 -04:00
|
|
|
return false;
|
2007-03-18 02:07:08 -04:00
|
|
|
}
|
|
|
|
|
2011-10-20 14:50:29 -04:00
|
|
|
void
|
|
|
|
RouteUI::monitoring_changed ()
|
2011-10-21 08:40:06 -04:00
|
|
|
{
|
|
|
|
update_monitoring_display ();
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
RouteUI::update_monitoring_display ()
|
2011-10-20 14:50:29 -04:00
|
|
|
{
|
2011-10-21 11:05:33 -04:00
|
|
|
if (!_route) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2011-10-20 14:50:29 -04:00
|
|
|
boost::shared_ptr<Track> t = boost::dynamic_pointer_cast<Track>(_route);
|
|
|
|
|
|
|
|
if (!t) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2011-10-21 11:05:33 -04:00
|
|
|
MonitorState ms = t->monitoring_state();
|
2011-10-20 14:50:29 -04:00
|
|
|
|
2011-10-21 13:32:31 -04:00
|
|
|
if (t->monitoring_choice() & MonitorInput) {
|
2012-02-07 12:43:55 -05:00
|
|
|
monitor_input_button->set_active_state (Gtkmm2ext::ExplicitActive);
|
2011-10-21 13:32:31 -04:00
|
|
|
} else {
|
|
|
|
if (ms & MonitoringInput) {
|
2012-02-07 12:43:55 -05:00
|
|
|
monitor_input_button->set_active_state (Gtkmm2ext::ImplicitActive);
|
2011-10-21 13:32:31 -04:00
|
|
|
} else {
|
2011-10-27 07:24:43 -04:00
|
|
|
monitor_input_button->unset_active_state ();
|
2011-10-21 11:05:33 -04:00
|
|
|
}
|
2011-10-20 14:50:29 -04:00
|
|
|
}
|
|
|
|
|
2011-10-21 13:32:31 -04:00
|
|
|
if (t->monitoring_choice() & MonitorDisk) {
|
2012-02-07 12:43:55 -05:00
|
|
|
monitor_disk_button->set_active_state (Gtkmm2ext::ExplicitActive);
|
2011-10-21 13:32:31 -04:00
|
|
|
} else {
|
|
|
|
if (ms & MonitoringDisk) {
|
2012-02-07 12:43:55 -05:00
|
|
|
monitor_disk_button->set_active_state (Gtkmm2ext::ImplicitActive);
|
2011-10-21 13:32:31 -04:00
|
|
|
} else {
|
2011-10-27 07:24:43 -04:00
|
|
|
monitor_disk_button->unset_active_state ();
|
2011-10-21 11:05:33 -04:00
|
|
|
}
|
2011-10-20 14:50:29 -04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
bool
|
2012-05-02 16:29:46 -04:00
|
|
|
RouteUI::monitor_input_press(GdkEventButton*)
|
2011-10-20 14:50:29 -04:00
|
|
|
{
|
2014-08-28 11:31:57 -04:00
|
|
|
return false;
|
2011-10-20 14:50:29 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
bool
|
|
|
|
RouteUI::monitor_input_release(GdkEventButton* ev)
|
|
|
|
{
|
|
|
|
return monitor_release (ev, MonitorInput);
|
|
|
|
}
|
|
|
|
|
|
|
|
bool
|
2012-05-02 16:29:46 -04:00
|
|
|
RouteUI::monitor_disk_press (GdkEventButton*)
|
2011-10-20 14:50:29 -04:00
|
|
|
{
|
2014-08-28 11:31:57 -04:00
|
|
|
return false;
|
2011-10-20 14:50:29 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
bool
|
|
|
|
RouteUI::monitor_disk_release (GdkEventButton* ev)
|
|
|
|
{
|
2014-08-29 20:26:36 -04:00
|
|
|
return monitor_release (ev, MonitorDisk);
|
2011-10-20 14:50:29 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
bool
|
|
|
|
RouteUI::monitor_release (GdkEventButton* ev, MonitorChoice monitor_choice)
|
|
|
|
{
|
|
|
|
if (ev->button != 1) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
boost::shared_ptr<Track> t = boost::dynamic_pointer_cast<Track>(_route);
|
|
|
|
|
|
|
|
if (!t) {
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
MonitorChoice mc;
|
|
|
|
boost::shared_ptr<RouteList> rl;
|
|
|
|
|
|
|
|
/* XXX for now, monitoring choices are orthogonal. cue monitoring
|
|
|
|
will follow in 3.X but requires mixing the input and playback (disk)
|
|
|
|
signal together, which requires yet more buffers.
|
|
|
|
*/
|
|
|
|
|
2011-10-21 11:05:33 -04:00
|
|
|
if (t->monitoring_choice() & monitor_choice) {
|
|
|
|
mc = MonitorChoice (t->monitoring_choice() & ~monitor_choice);
|
2011-10-20 14:50:29 -04:00
|
|
|
} else {
|
|
|
|
/* this line will change when the options are non-orthogonal */
|
2011-10-21 11:05:33 -04:00
|
|
|
// mc = MonitorChoice (t->monitoring_choice() | monitor_choice);
|
2011-10-20 14:50:29 -04:00
|
|
|
mc = monitor_choice;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (Keyboard::modifier_state_equals (ev->state, Keyboard::ModifierMask (Keyboard::PrimaryModifier|Keyboard::TertiaryModifier))) {
|
|
|
|
rl = _session->get_routes ();
|
|
|
|
|
2011-10-21 11:47:50 -04:00
|
|
|
} else if (Keyboard::modifier_state_equals (ev->state, Keyboard::PrimaryModifier)) {
|
|
|
|
if (_route->route_group() && _route->route_group()->is_monitoring()) {
|
|
|
|
rl = _route->route_group()->route_list();
|
|
|
|
} else {
|
|
|
|
rl.reset (new RouteList);
|
|
|
|
rl->push_back (route());
|
|
|
|
}
|
2011-10-20 14:50:29 -04:00
|
|
|
} else {
|
|
|
|
rl.reset (new RouteList);
|
|
|
|
rl->push_back (route());
|
|
|
|
}
|
|
|
|
|
2014-06-28 20:52:56 -04:00
|
|
|
DisplaySuspender ds;
|
2011-10-20 14:50:29 -04:00
|
|
|
_session->set_monitoring (rl, mc, Session::rt_cleanup, true);
|
|
|
|
|
2014-08-28 11:31:57 -04:00
|
|
|
return false;
|
2011-10-20 14:50:29 -04:00
|
|
|
}
|
|
|
|
|
2010-07-24 12:40:56 -04:00
|
|
|
void
|
|
|
|
RouteUI::build_record_menu ()
|
|
|
|
{
|
2015-01-07 20:12:14 -05:00
|
|
|
if (record_menu) {
|
|
|
|
return;
|
|
|
|
}
|
2010-07-24 12:40:56 -04:00
|
|
|
|
2015-01-07 20:12:14 -05:00
|
|
|
/* no rec-button context menu for non-MIDI tracks
|
|
|
|
*/
|
2010-07-24 12:40:56 -04:00
|
|
|
|
2015-01-07 20:12:14 -05:00
|
|
|
if (is_midi_track()) {
|
|
|
|
record_menu = new Menu;
|
|
|
|
record_menu->set_name ("ArdourContextMenu");
|
2011-06-01 13:00:29 -04:00
|
|
|
|
2015-01-07 20:12:14 -05:00
|
|
|
using namespace Menu_Helpers;
|
|
|
|
MenuList& items = record_menu->items();
|
2011-06-01 13:00:29 -04:00
|
|
|
|
2015-01-07 20:12:14 -05:00
|
|
|
items.push_back (CheckMenuElem (_("Step Entry"), sigc::mem_fun (*this, &RouteUI::toggle_step_edit)));
|
|
|
|
step_edit_item = dynamic_cast<Gtk::CheckMenuItem*> (&items.back());
|
2010-08-03 17:50:15 -04:00
|
|
|
|
2015-01-07 20:12:14 -05:00
|
|
|
if (_route->record_enabled()) {
|
|
|
|
step_edit_item->set_sensitive (false);
|
|
|
|
}
|
2010-07-24 12:40:56 -04:00
|
|
|
|
2015-01-07 20:12:14 -05:00
|
|
|
step_edit_item->set_active (midi_track()->step_editing());
|
|
|
|
}
|
2010-07-24 12:40:56 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
RouteUI::toggle_step_edit ()
|
|
|
|
{
|
2015-01-07 20:12:14 -05:00
|
|
|
if (!is_midi_track() || _route->record_enabled()) {
|
|
|
|
return;
|
|
|
|
}
|
2010-08-03 17:50:15 -04:00
|
|
|
|
2015-01-07 20:12:14 -05:00
|
|
|
midi_track()->set_step_editing (step_edit_item->get_active());
|
2010-07-24 12:40:56 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
RouteUI::step_edit_changed (bool yn)
|
|
|
|
{
|
2015-01-07 20:12:14 -05:00
|
|
|
if (yn) {
|
|
|
|
if (rec_enable_button) {
|
|
|
|
rec_enable_button->set_active_state (Gtkmm2ext::ExplicitActive);
|
|
|
|
}
|
2010-08-03 17:50:15 -04:00
|
|
|
|
2015-01-07 20:12:14 -05:00
|
|
|
start_step_editing ();
|
2010-08-03 17:50:15 -04:00
|
|
|
|
2015-01-07 20:12:14 -05:00
|
|
|
if (step_edit_item) {
|
|
|
|
step_edit_item->set_active (true);
|
|
|
|
}
|
2010-08-03 17:50:15 -04:00
|
|
|
|
2015-01-07 20:12:14 -05:00
|
|
|
} else {
|
2010-08-03 17:50:15 -04:00
|
|
|
|
2015-01-07 20:12:14 -05:00
|
|
|
if (rec_enable_button) {
|
|
|
|
rec_enable_button->unset_active_state ();
|
|
|
|
}
|
2010-08-03 17:50:15 -04:00
|
|
|
|
2015-01-07 20:12:14 -05:00
|
|
|
stop_step_editing ();
|
2010-08-03 17:50:15 -04:00
|
|
|
|
2015-01-07 20:12:14 -05:00
|
|
|
if (step_edit_item) {
|
|
|
|
step_edit_item->set_active (false);
|
|
|
|
}
|
|
|
|
}
|
2010-07-24 12:40:56 -04:00
|
|
|
}
|
|
|
|
|
2007-03-18 02:07:08 -04:00
|
|
|
bool
|
2010-07-24 12:40:56 -04:00
|
|
|
RouteUI::rec_enable_release (GdkEventButton* ev)
|
2007-03-18 02:07:08 -04:00
|
|
|
{
|
2015-01-07 20:12:14 -05:00
|
|
|
if (Keyboard::is_context_menu_event (ev)) {
|
|
|
|
build_record_menu ();
|
|
|
|
if (record_menu) {
|
|
|
|
record_menu->popup (1, ev->time);
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
2010-07-24 12:40:56 -04:00
|
|
|
|
2014-08-22 12:45:34 -04:00
|
|
|
return false;
|
2005-09-25 14:42:24 -04:00
|
|
|
}
|
|
|
|
|
2009-05-16 22:08:13 -04:00
|
|
|
void
|
|
|
|
RouteUI::build_sends_menu ()
|
|
|
|
{
|
|
|
|
using namespace Menu_Helpers;
|
2009-10-14 12:10:01 -04:00
|
|
|
|
2009-05-16 22:08:13 -04:00
|
|
|
sends_menu = new Menu;
|
|
|
|
sends_menu->set_name ("ArdourContextMenu");
|
|
|
|
MenuList& items = sends_menu->items();
|
2009-10-14 12:10:01 -04:00
|
|
|
|
2010-12-29 17:07:34 -05:00
|
|
|
items.push_back (
|
|
|
|
MenuElem(_("Assign all tracks (prefader)"), sigc::bind (sigc::mem_fun (*this, &RouteUI::create_sends), PreFader, false))
|
|
|
|
);
|
2011-06-01 13:00:29 -04:00
|
|
|
|
2010-12-29 17:07:34 -05:00
|
|
|
items.push_back (
|
|
|
|
MenuElem(_("Assign all tracks and buses (prefader)"), sigc::bind (sigc::mem_fun (*this, &RouteUI::create_sends), PreFader, true))
|
|
|
|
);
|
2011-06-01 13:00:29 -04:00
|
|
|
|
2010-12-29 17:07:34 -05:00
|
|
|
items.push_back (
|
|
|
|
MenuElem(_("Assign all tracks (postfader)"), sigc::bind (sigc::mem_fun (*this, &RouteUI::create_sends), PostFader, false))
|
|
|
|
);
|
2011-06-01 13:00:29 -04:00
|
|
|
|
2010-12-29 17:07:34 -05:00
|
|
|
items.push_back (
|
|
|
|
MenuElem(_("Assign all tracks and buses (postfader)"), sigc::bind (sigc::mem_fun (*this, &RouteUI::create_sends), PostFader, true))
|
|
|
|
);
|
|
|
|
|
|
|
|
items.push_back (
|
|
|
|
MenuElem(_("Assign selected tracks (prefader)"), sigc::bind (sigc::mem_fun (*this, &RouteUI::create_selected_sends), PreFader, false))
|
|
|
|
);
|
|
|
|
|
|
|
|
items.push_back (
|
|
|
|
MenuElem(_("Assign selected tracks and buses (prefader)"), sigc::bind (sigc::mem_fun (*this, &RouteUI::create_selected_sends), PreFader, true)));
|
2011-06-01 13:00:29 -04:00
|
|
|
|
2010-12-29 17:07:34 -05:00
|
|
|
items.push_back (
|
|
|
|
MenuElem(_("Assign selected tracks (postfader)"), sigc::bind (sigc::mem_fun (*this, &RouteUI::create_selected_sends), PostFader, false))
|
|
|
|
);
|
|
|
|
|
|
|
|
items.push_back (
|
|
|
|
MenuElem(_("Assign selected tracks and buses (postfader)"), sigc::bind (sigc::mem_fun (*this, &RouteUI::create_selected_sends), PostFader, true))
|
|
|
|
);
|
2011-06-01 13:00:29 -04:00
|
|
|
|
2010-12-29 16:07:22 -05:00
|
|
|
items.push_back (MenuElem(_("Copy track/bus gains to sends"), sigc::mem_fun (*this, &RouteUI::set_sends_gain_from_track)));
|
2013-07-09 18:02:35 -04:00
|
|
|
items.push_back (MenuElem(_("Set sends gain to -inf"), sigc::mem_fun (*this, &RouteUI::set_sends_gain_to_zero)));
|
2009-12-11 18:29:48 -05:00
|
|
|
items.push_back (MenuElem(_("Set sends gain to 0dB"), sigc::mem_fun (*this, &RouteUI::set_sends_gain_to_unity)));
|
2009-06-25 16:46:39 -04:00
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
2010-12-29 17:07:34 -05:00
|
|
|
RouteUI::create_sends (Placement p, bool include_buses)
|
2009-06-25 16:46:39 -04:00
|
|
|
{
|
2010-12-29 17:07:34 -05:00
|
|
|
_session->globally_add_internal_sends (_route, p, include_buses);
|
2009-05-16 22:08:13 -04:00
|
|
|
}
|
|
|
|
|
2009-11-19 12:06:00 -05:00
|
|
|
void
|
2010-12-29 17:07:34 -05:00
|
|
|
RouteUI::create_selected_sends (Placement p, bool include_buses)
|
2009-11-19 12:06:00 -05:00
|
|
|
{
|
|
|
|
boost::shared_ptr<RouteList> rlist (new RouteList);
|
|
|
|
TrackSelection& selected_tracks (ARDOUR_UI::instance()->the_editor().get_selection().tracks);
|
|
|
|
|
|
|
|
for (TrackSelection::iterator i = selected_tracks.begin(); i != selected_tracks.end(); ++i) {
|
|
|
|
RouteTimeAxisView* rtv;
|
|
|
|
RouteUI* rui;
|
|
|
|
if ((rtv = dynamic_cast<RouteTimeAxisView*>(*i)) != 0) {
|
|
|
|
if ((rui = dynamic_cast<RouteUI*>(rtv)) != 0) {
|
2010-12-29 17:07:34 -05:00
|
|
|
if (include_buses || boost::dynamic_pointer_cast<AudioTrack>(rui->route())) {
|
2009-11-19 12:06:00 -05:00
|
|
|
rlist->push_back (rui->route());
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2011-06-01 13:00:29 -04:00
|
|
|
|
2009-12-17 13:24:23 -05:00
|
|
|
_session->add_internal_sends (_route, p, rlist);
|
2009-11-19 12:06:00 -05:00
|
|
|
}
|
|
|
|
|
2009-05-16 22:08:13 -04:00
|
|
|
void
|
|
|
|
RouteUI::set_sends_gain_from_track ()
|
|
|
|
{
|
2009-12-17 13:24:23 -05:00
|
|
|
_session->globally_set_send_gains_from_track (_route);
|
2009-05-16 22:08:13 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
RouteUI::set_sends_gain_to_zero ()
|
|
|
|
{
|
2009-12-17 13:24:23 -05:00
|
|
|
_session->globally_set_send_gains_to_zero (_route);
|
2009-05-16 22:08:13 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
RouteUI::set_sends_gain_to_unity ()
|
|
|
|
{
|
2009-12-17 13:24:23 -05:00
|
|
|
_session->globally_set_send_gains_to_unity (_route);
|
2009-05-16 22:08:13 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
bool
|
|
|
|
RouteUI::show_sends_press(GdkEventButton* ev)
|
|
|
|
{
|
|
|
|
if (ev->type == GDK_2BUTTON_PRESS || ev->type == GDK_3BUTTON_PRESS ) {
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2014-07-10 11:54:59 -04:00
|
|
|
if (!is_track() && show_sends_button) {
|
2009-05-16 22:08:13 -04:00
|
|
|
|
|
|
|
if (Keyboard::is_button2_event (ev) && Keyboard::modifier_state_equals (ev->state, Keyboard::PrimaryModifier)) {
|
|
|
|
|
2009-12-11 18:29:48 -05:00
|
|
|
// do nothing on midi sigc::bind event
|
2009-05-16 22:08:13 -04:00
|
|
|
return false;
|
|
|
|
|
|
|
|
} else if (Keyboard::is_context_menu_event (ev)) {
|
|
|
|
|
|
|
|
if (sends_menu == 0) {
|
|
|
|
build_sends_menu ();
|
|
|
|
}
|
|
|
|
|
|
|
|
sends_menu->popup (0, ev->time);
|
|
|
|
|
|
|
|
} else {
|
|
|
|
|
2011-11-02 20:42:16 -04:00
|
|
|
boost::shared_ptr<Route> s = _showing_sends_to.lock ();
|
2009-05-17 13:05:56 -04:00
|
|
|
|
2011-11-02 20:42:16 -04:00
|
|
|
if (s == _route) {
|
|
|
|
set_showing_sends_to (boost::shared_ptr<Route> ());
|
2009-05-16 22:08:13 -04:00
|
|
|
} else {
|
2011-11-02 20:42:16 -04:00
|
|
|
set_showing_sends_to (_route);
|
2009-05-16 22:08:13 -04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool
|
2009-07-21 11:55:17 -04:00
|
|
|
RouteUI::show_sends_release (GdkEventButton*)
|
2009-05-16 22:08:13 -04:00
|
|
|
{
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2009-05-17 13:05:56 -04:00
|
|
|
void
|
|
|
|
RouteUI::send_blink (bool onoff)
|
|
|
|
{
|
|
|
|
if (!show_sends_button) {
|
|
|
|
return;
|
|
|
|
}
|
2009-10-14 12:10:01 -04:00
|
|
|
|
2009-05-17 13:05:56 -04:00
|
|
|
if (onoff) {
|
2012-02-07 12:43:55 -05:00
|
|
|
show_sends_button->set_active_state (Gtkmm2ext::ExplicitActive);
|
2009-05-17 13:05:56 -04:00
|
|
|
} else {
|
2011-11-02 20:42:16 -04:00
|
|
|
show_sends_button->unset_active_state ();
|
2009-05-17 13:05:56 -04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2011-11-02 14:48:32 -04:00
|
|
|
Gtkmm2ext::ActiveState
|
|
|
|
RouteUI::solo_active_state (boost::shared_ptr<Route> r)
|
2009-11-25 22:02:16 -05:00
|
|
|
{
|
2010-03-23 08:19:21 -04:00
|
|
|
if (r->is_master() || r->is_monitor()) {
|
2012-02-07 12:43:55 -05:00
|
|
|
return Gtkmm2ext::Off;
|
2009-12-10 15:51:35 -05:00
|
|
|
}
|
2011-06-01 13:00:29 -04:00
|
|
|
|
2009-11-25 22:02:16 -05:00
|
|
|
if (Config->get_solo_control_is_listen_control()) {
|
|
|
|
|
2011-02-19 19:55:32 -05:00
|
|
|
if (r->listening_via_monitor()) {
|
2012-02-07 12:43:55 -05:00
|
|
|
return Gtkmm2ext::ExplicitActive;
|
2009-11-25 22:02:16 -05:00
|
|
|
} else {
|
2012-02-07 12:43:55 -05:00
|
|
|
return Gtkmm2ext::Off;
|
2009-11-25 22:02:16 -05:00
|
|
|
}
|
|
|
|
|
2011-06-01 13:00:29 -04:00
|
|
|
}
|
|
|
|
|
2009-12-10 15:51:35 -05:00
|
|
|
if (r->soloed()) {
|
2010-05-06 16:41:53 -04:00
|
|
|
if (!r->self_soloed()) {
|
2012-02-07 12:43:55 -05:00
|
|
|
return Gtkmm2ext::ImplicitActive;
|
2010-05-06 16:41:53 -04:00
|
|
|
} else {
|
2012-02-07 12:43:55 -05:00
|
|
|
return Gtkmm2ext::ExplicitActive;
|
2010-05-06 16:41:53 -04:00
|
|
|
}
|
2009-11-25 22:02:16 -05:00
|
|
|
} else {
|
2012-02-07 12:43:55 -05:00
|
|
|
return Gtkmm2ext::Off;
|
2009-11-25 22:02:16 -05:00
|
|
|
}
|
2009-12-10 15:51:35 -05:00
|
|
|
}
|
2009-11-25 22:02:16 -05:00
|
|
|
|
2011-11-02 14:48:32 -04:00
|
|
|
Gtkmm2ext::ActiveState
|
|
|
|
RouteUI::solo_isolate_active_state (boost::shared_ptr<Route> r)
|
2009-12-10 15:51:35 -05:00
|
|
|
{
|
2010-03-23 08:19:21 -04:00
|
|
|
if (r->is_master() || r->is_monitor()) {
|
2012-02-07 12:43:55 -05:00
|
|
|
return Gtkmm2ext::Off;
|
2009-12-10 15:51:35 -05:00
|
|
|
}
|
2011-06-01 13:00:29 -04:00
|
|
|
|
2009-12-10 15:51:35 -05:00
|
|
|
if (r->solo_isolated()) {
|
2012-02-07 12:43:55 -05:00
|
|
|
return Gtkmm2ext::ExplicitActive;
|
2010-04-05 16:08:37 -04:00
|
|
|
} else {
|
2012-02-07 12:43:55 -05:00
|
|
|
return Gtkmm2ext::Off;
|
2010-04-05 16:08:37 -04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2011-11-02 14:48:32 -04:00
|
|
|
Gtkmm2ext::ActiveState
|
|
|
|
RouteUI::solo_safe_active_state (boost::shared_ptr<Route> r)
|
2010-04-05 16:08:37 -04:00
|
|
|
{
|
|
|
|
if (r->is_master() || r->is_monitor()) {
|
2012-02-07 12:43:55 -05:00
|
|
|
return Gtkmm2ext::Off;
|
2010-04-05 16:08:37 -04:00
|
|
|
}
|
2011-06-01 13:00:29 -04:00
|
|
|
|
2010-04-05 16:08:37 -04:00
|
|
|
if (r->solo_safe()) {
|
2012-02-07 12:43:55 -05:00
|
|
|
return Gtkmm2ext::ExplicitActive;
|
2009-12-10 15:51:35 -05:00
|
|
|
} else {
|
2012-02-07 12:43:55 -05:00
|
|
|
return Gtkmm2ext::Off;
|
2009-12-10 15:51:35 -05:00
|
|
|
}
|
2009-11-25 22:02:16 -05:00
|
|
|
}
|
|
|
|
|
2005-09-25 14:42:24 -04:00
|
|
|
void
|
|
|
|
RouteUI::update_solo_display ()
|
|
|
|
{
|
2010-04-20 08:38:37 -04:00
|
|
|
bool yn = _route->solo_safe ();
|
|
|
|
|
|
|
|
if (solo_safe_check && solo_safe_check->get_active() != yn) {
|
|
|
|
solo_safe_check->set_active (yn);
|
|
|
|
}
|
|
|
|
|
|
|
|
yn = _route->solo_isolated ();
|
|
|
|
|
|
|
|
if (solo_isolated_check && solo_isolated_check->get_active() != yn) {
|
|
|
|
solo_isolated_check->set_active (yn);
|
|
|
|
}
|
|
|
|
|
|
|
|
set_button_names ();
|
|
|
|
|
2010-05-05 16:29:46 -04:00
|
|
|
if (solo_isolated_led) {
|
2011-10-27 07:24:43 -04:00
|
|
|
if (_route->solo_isolated()) {
|
2012-02-07 12:43:55 -05:00
|
|
|
solo_isolated_led->set_active_state (Gtkmm2ext::ExplicitActive);
|
2011-10-27 07:24:43 -04:00
|
|
|
} else {
|
|
|
|
solo_isolated_led->unset_active_state ();
|
|
|
|
}
|
2010-05-05 16:29:46 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
if (solo_safe_led) {
|
2011-10-27 07:24:43 -04:00
|
|
|
if (_route->solo_safe()) {
|
2012-02-07 12:43:55 -05:00
|
|
|
solo_safe_led->set_active_state (Gtkmm2ext::ExplicitActive);
|
2011-10-27 07:24:43 -04:00
|
|
|
} else {
|
|
|
|
solo_safe_led->unset_active_state ();
|
|
|
|
}
|
2010-05-05 16:29:46 -04:00
|
|
|
}
|
|
|
|
|
2011-11-02 14:48:32 -04:00
|
|
|
solo_button->set_active_state (solo_active_state (_route));
|
2011-06-01 13:00:29 -04:00
|
|
|
|
|
|
|
/* some changes to solo status can affect mute display, so catch up
|
2010-05-21 10:43:47 -04:00
|
|
|
*/
|
|
|
|
|
|
|
|
update_mute_display ();
|
2005-09-25 14:42:24 -04:00
|
|
|
}
|
|
|
|
|
2007-03-18 02:07:08 -04:00
|
|
|
void
|
|
|
|
RouteUI::solo_changed_so_update_mute ()
|
|
|
|
{
|
2010-03-10 12:31:16 -05:00
|
|
|
update_mute_display ();
|
2007-03-18 02:07:08 -04:00
|
|
|
}
|
|
|
|
|
2011-11-02 12:46:49 -04:00
|
|
|
ActiveState
|
|
|
|
RouteUI::mute_active_state (Session* s, boost::shared_ptr<Route> r)
|
2009-11-25 22:02:16 -05:00
|
|
|
{
|
2011-11-08 08:17:11 -05:00
|
|
|
if (r->is_monitor()) {
|
2011-11-02 12:46:49 -04:00
|
|
|
return ActiveState(0);
|
2009-12-10 15:51:35 -05:00
|
|
|
}
|
2010-04-27 21:29:06 -04:00
|
|
|
|
2011-06-01 13:00:29 -04:00
|
|
|
|
2011-02-22 16:14:51 -05:00
|
|
|
if (Config->get_show_solo_mutes() && !Config->get_solo_control_is_listen_control ()) {
|
2010-04-27 21:29:06 -04:00
|
|
|
|
2010-05-04 12:39:03 -04:00
|
|
|
if (r->muted ()) {
|
2009-11-25 22:02:16 -05:00
|
|
|
/* full mute */
|
2012-02-07 12:43:55 -05:00
|
|
|
return Gtkmm2ext::ExplicitActive;
|
2011-11-14 12:49:37 -05:00
|
|
|
} else if (!r->is_master() && s->soloing() && !r->soloed() && !r->solo_isolated()) {
|
|
|
|
/* master is NEVER muted by others */
|
2012-02-07 12:43:55 -05:00
|
|
|
return Gtkmm2ext::ImplicitActive;
|
2009-11-25 22:02:16 -05:00
|
|
|
} else {
|
|
|
|
/* no mute at all */
|
2012-02-07 12:43:55 -05:00
|
|
|
return Gtkmm2ext::Off;
|
2009-11-25 22:02:16 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
} else {
|
|
|
|
|
2010-05-04 12:39:03 -04:00
|
|
|
if (r->muted()) {
|
2009-11-25 22:02:16 -05:00
|
|
|
/* full mute */
|
2012-02-07 12:43:55 -05:00
|
|
|
return Gtkmm2ext::ExplicitActive;
|
2009-11-25 22:02:16 -05:00
|
|
|
} else {
|
|
|
|
/* no mute at all */
|
2012-02-07 12:43:55 -05:00
|
|
|
return Gtkmm2ext::Off;
|
2009-11-25 22:02:16 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2011-11-02 12:46:49 -04:00
|
|
|
return ActiveState(0);
|
2009-11-25 22:02:16 -05:00
|
|
|
}
|
|
|
|
|
2005-09-25 14:42:24 -04:00
|
|
|
void
|
|
|
|
RouteUI::update_mute_display ()
|
|
|
|
{
|
2010-03-10 12:31:16 -05:00
|
|
|
if (!_route) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2011-11-02 12:46:49 -04:00
|
|
|
mute_button->set_active_state (mute_active_state (_session, _route));
|
2005-09-25 14:42:24 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
2006-08-01 13:19:38 -04:00
|
|
|
RouteUI::route_rec_enable_changed ()
|
2005-09-25 14:42:24 -04:00
|
|
|
{
|
2014-08-22 12:45:34 -04:00
|
|
|
blink_rec_display(true); //this lets the button change "immediately" rather than wait for the next blink
|
2011-10-21 11:05:33 -04:00
|
|
|
update_monitoring_display ();
|
2005-09-25 14:42:24 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
RouteUI::session_rec_enable_changed ()
|
|
|
|
{
|
2014-09-07 15:03:25 -04:00
|
|
|
blink_rec_display(true); //this lets the button change "immediately" rather than wait for the next blink
|
2011-10-21 11:05:33 -04:00
|
|
|
update_monitoring_display ();
|
2005-09-25 14:42:24 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
2014-08-22 12:45:34 -04:00
|
|
|
RouteUI::blink_rec_display (bool blinkOn)
|
2005-09-25 14:42:24 -04:00
|
|
|
{
|
2010-03-10 12:31:16 -05:00
|
|
|
if (!rec_enable_button || !_route) {
|
2009-12-19 15:26:31 -05:00
|
|
|
return;
|
|
|
|
}
|
2014-09-04 22:20:15 -04:00
|
|
|
if (boost::dynamic_pointer_cast<Send>(_current_delivery)) {
|
|
|
|
return;
|
|
|
|
}
|
2011-06-01 13:00:29 -04:00
|
|
|
|
2011-11-02 15:51:59 -04:00
|
|
|
if (_route->record_enabled()) {
|
2010-07-24 12:40:56 -04:00
|
|
|
switch (_session->record_status ()) {
|
|
|
|
case Session::Recording:
|
2012-02-07 12:43:55 -05:00
|
|
|
rec_enable_button->set_active_state (Gtkmm2ext::ExplicitActive);
|
2010-07-24 12:40:56 -04:00
|
|
|
break;
|
2011-06-01 13:00:29 -04:00
|
|
|
|
2010-07-24 12:40:56 -04:00
|
|
|
case Session::Disabled:
|
|
|
|
case Session::Enabled:
|
2014-08-27 15:41:49 -04:00
|
|
|
if ( ARDOUR_UI::config()->get_blink_rec_arm() )
|
2014-08-22 12:45:34 -04:00
|
|
|
rec_enable_button->set_active_state ( blinkOn ? Gtkmm2ext::ExplicitActive : Gtkmm2ext::Off );
|
|
|
|
else
|
|
|
|
rec_enable_button->set_active_state ( ImplicitActive );
|
2010-07-24 12:40:56 -04:00
|
|
|
break;
|
2011-06-01 13:00:29 -04:00
|
|
|
|
2010-07-24 12:40:56 -04:00
|
|
|
}
|
2005-09-25 14:42:24 -04:00
|
|
|
|
2010-08-03 17:50:15 -04:00
|
|
|
if (step_edit_item) {
|
|
|
|
step_edit_item->set_sensitive (false);
|
|
|
|
}
|
|
|
|
|
2005-09-25 14:42:24 -04:00
|
|
|
} else {
|
2011-11-02 15:51:59 -04:00
|
|
|
rec_enable_button->unset_active_state ();
|
2010-08-03 17:50:15 -04:00
|
|
|
|
|
|
|
if (step_edit_item) {
|
|
|
|
step_edit_item->set_sensitive (true);
|
|
|
|
}
|
2005-09-25 14:42:24 -04:00
|
|
|
}
|
2011-06-01 13:00:29 -04:00
|
|
|
|
2009-12-07 20:52:49 -05:00
|
|
|
|
|
|
|
check_rec_enable_sensitivity ();
|
2005-09-25 14:42:24 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
RouteUI::build_solo_menu (void)
|
|
|
|
{
|
|
|
|
using namespace Menu_Helpers;
|
2009-10-14 12:10:01 -04:00
|
|
|
|
2005-09-25 14:42:24 -04:00
|
|
|
solo_menu = new Menu;
|
|
|
|
solo_menu->set_name ("ArdourContextMenu");
|
|
|
|
MenuList& items = solo_menu->items();
|
2013-07-11 15:32:31 -04:00
|
|
|
Gtk::CheckMenuItem* check;
|
2005-09-25 14:42:24 -04:00
|
|
|
|
2013-07-11 15:32:31 -04:00
|
|
|
check = new Gtk::CheckMenuItem(_("Solo Isolate"));
|
2009-06-09 16:21:19 -04:00
|
|
|
check->set_active (_route->solo_isolated());
|
2009-12-11 18:29:48 -05:00
|
|
|
check->signal_toggled().connect (sigc::bind (sigc::mem_fun (*this, &RouteUI::toggle_solo_isolated), check));
|
2005-09-25 14:42:24 -04:00
|
|
|
items.push_back (CheckMenuElem(*check));
|
2013-07-11 15:32:31 -04:00
|
|
|
solo_isolated_check = dynamic_cast<Gtk::CheckMenuItem*>(&items.back());
|
2005-09-25 14:42:24 -04:00
|
|
|
check->show_all();
|
|
|
|
|
2013-07-11 15:32:31 -04:00
|
|
|
check = new Gtk::CheckMenuItem(_("Solo Safe"));
|
2009-11-21 14:33:09 -05:00
|
|
|
check->set_active (_route->solo_safe());
|
2009-12-11 18:29:48 -05:00
|
|
|
check->signal_toggled().connect (sigc::bind (sigc::mem_fun (*this, &RouteUI::toggle_solo_safe), check));
|
2009-11-21 14:33:09 -05:00
|
|
|
items.push_back (CheckMenuElem(*check));
|
2013-07-11 15:32:31 -04:00
|
|
|
solo_safe_check = dynamic_cast<Gtk::CheckMenuItem*>(&items.back());
|
2009-11-21 14:33:09 -05:00
|
|
|
check->show_all();
|
|
|
|
|
2006-11-19 11:45:16 -05:00
|
|
|
//items.push_back (SeparatorElem());
|
2009-12-11 18:29:48 -05:00
|
|
|
// items.push_back (MenuElem (_("MIDI Bind"), sigc::mem_fun (*mute_button, &BindableToggleButton::midi_learn)));
|
2009-10-14 12:10:01 -04:00
|
|
|
|
2005-09-25 14:42:24 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
RouteUI::build_mute_menu(void)
|
|
|
|
{
|
|
|
|
using namespace Menu_Helpers;
|
2009-10-14 12:10:01 -04:00
|
|
|
|
2005-09-25 14:42:24 -04:00
|
|
|
mute_menu = new Menu;
|
|
|
|
mute_menu->set_name ("ArdourContextMenu");
|
2009-06-09 16:21:19 -04:00
|
|
|
|
2005-09-25 14:42:24 -04:00
|
|
|
MenuList& items = mute_menu->items();
|
|
|
|
|
2014-02-19 23:44:53 -05:00
|
|
|
pre_fader_mute_check = manage (new Gtk::CheckMenuItem(_("Pre Fader Sends")));
|
2009-11-18 08:25:13 -05:00
|
|
|
init_mute_menu(MuteMaster::PreFader, pre_fader_mute_check);
|
2009-12-11 18:29:48 -05:00
|
|
|
pre_fader_mute_check->signal_toggled().connect(sigc::bind (sigc::mem_fun (*this, &RouteUI::toggle_mute_menu), MuteMaster::PreFader, pre_fader_mute_check));
|
2009-11-18 08:25:13 -05:00
|
|
|
items.push_back (CheckMenuElem(*pre_fader_mute_check));
|
|
|
|
pre_fader_mute_check->show_all();
|
|
|
|
|
2014-02-19 23:44:53 -05:00
|
|
|
post_fader_mute_check = manage (new Gtk::CheckMenuItem(_("Post Fader Sends")));
|
2009-11-18 08:25:13 -05:00
|
|
|
init_mute_menu(MuteMaster::PostFader, post_fader_mute_check);
|
2009-12-11 18:29:48 -05:00
|
|
|
post_fader_mute_check->signal_toggled().connect(sigc::bind (sigc::mem_fun (*this, &RouteUI::toggle_mute_menu), MuteMaster::PostFader, post_fader_mute_check));
|
2009-11-18 08:25:13 -05:00
|
|
|
items.push_back (CheckMenuElem(*post_fader_mute_check));
|
|
|
|
post_fader_mute_check->show_all();
|
|
|
|
|
2013-07-11 15:32:31 -04:00
|
|
|
listen_mute_check = manage (new Gtk::CheckMenuItem(_("Control Outs")));
|
2009-11-18 08:25:13 -05:00
|
|
|
init_mute_menu(MuteMaster::Listen, listen_mute_check);
|
2009-12-11 18:29:48 -05:00
|
|
|
listen_mute_check->signal_toggled().connect(sigc::bind (sigc::mem_fun (*this, &RouteUI::toggle_mute_menu), MuteMaster::Listen, listen_mute_check));
|
2009-11-18 08:25:13 -05:00
|
|
|
items.push_back (CheckMenuElem(*listen_mute_check));
|
|
|
|
listen_mute_check->show_all();
|
|
|
|
|
2013-07-11 15:32:31 -04:00
|
|
|
main_mute_check = manage (new Gtk::CheckMenuItem(_("Main Outs")));
|
2009-11-18 08:25:13 -05:00
|
|
|
init_mute_menu(MuteMaster::Main, main_mute_check);
|
2009-12-11 18:29:48 -05:00
|
|
|
main_mute_check->signal_toggled().connect(sigc::bind (sigc::mem_fun (*this, &RouteUI::toggle_mute_menu), MuteMaster::Main, main_mute_check));
|
2009-11-18 08:25:13 -05:00
|
|
|
items.push_back (CheckMenuElem(*main_mute_check));
|
|
|
|
main_mute_check->show_all();
|
2005-09-25 14:42:24 -04:00
|
|
|
|
2006-11-19 11:45:16 -05:00
|
|
|
//items.push_back (SeparatorElem());
|
2009-12-11 18:29:48 -05:00
|
|
|
// items.push_back (MenuElem (_("MIDI Bind"), sigc::mem_fun (*mute_button, &BindableToggleButton::midi_learn)));
|
2009-11-18 08:25:13 -05:00
|
|
|
|
2010-03-30 11:18:43 -04:00
|
|
|
_route->mute_points_changed.connect (route_connections, invalidator (*this), boost::bind (&RouteUI::muting_change, this), gui_context());
|
2005-09-25 14:42:24 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
2013-07-11 15:32:31 -04:00
|
|
|
RouteUI::init_mute_menu(MuteMaster::MutePoint mp, Gtk::CheckMenuItem* check)
|
2005-09-25 14:42:24 -04:00
|
|
|
{
|
2009-11-18 08:25:13 -05:00
|
|
|
check->set_active (_route->mute_points() & mp);
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
RouteUI::toggle_mute_menu(MuteMaster::MutePoint mp, Gtk::CheckMenuItem* check)
|
|
|
|
{
|
|
|
|
if (check->get_active()) {
|
|
|
|
_route->set_mute_points (MuteMaster::MutePoint (_route->mute_points() | mp));
|
|
|
|
} else {
|
|
|
|
_route->set_mute_points (MuteMaster::MutePoint (_route->mute_points() & ~mp));
|
|
|
|
}
|
2005-09-25 14:42:24 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
2009-11-18 08:25:13 -05:00
|
|
|
RouteUI::muting_change ()
|
2005-09-25 14:42:24 -04:00
|
|
|
{
|
2009-12-11 18:29:48 -05:00
|
|
|
ENSURE_GUI_THREAD (*this, &RouteUI::muting_change)
|
2009-11-18 08:25:13 -05:00
|
|
|
|
|
|
|
bool yn;
|
|
|
|
MuteMaster::MutePoint current = _route->mute_points ();
|
|
|
|
|
|
|
|
yn = (current & MuteMaster::PreFader);
|
|
|
|
|
|
|
|
if (pre_fader_mute_check->get_active() != yn) {
|
|
|
|
pre_fader_mute_check->set_active (yn);
|
|
|
|
}
|
|
|
|
|
|
|
|
yn = (current & MuteMaster::PostFader);
|
|
|
|
|
|
|
|
if (post_fader_mute_check->get_active() != yn) {
|
|
|
|
post_fader_mute_check->set_active (yn);
|
|
|
|
}
|
|
|
|
|
|
|
|
yn = (current & MuteMaster::Listen);
|
|
|
|
|
|
|
|
if (listen_mute_check->get_active() != yn) {
|
|
|
|
listen_mute_check->set_active (yn);
|
|
|
|
}
|
|
|
|
|
|
|
|
yn = (current & MuteMaster::Main);
|
|
|
|
|
|
|
|
if (main_mute_check->get_active() != yn) {
|
|
|
|
main_mute_check->set_active (yn);
|
|
|
|
}
|
2005-09-25 14:42:24 -04:00
|
|
|
}
|
|
|
|
|
2010-05-05 16:29:46 -04:00
|
|
|
bool
|
|
|
|
RouteUI::solo_isolate_button_release (GdkEventButton* ev)
|
|
|
|
{
|
2014-06-28 20:52:56 -04:00
|
|
|
if (ev->type == GDK_2BUTTON_PRESS || ev->type == GDK_3BUTTON_PRESS) {
|
|
|
|
return true;
|
|
|
|
}
|
2010-05-06 14:40:37 -04:00
|
|
|
|
2014-06-28 20:52:56 -04:00
|
|
|
bool view = solo_isolated_led->active_state();
|
|
|
|
bool model = _route->solo_isolated();
|
2010-05-05 17:10:09 -04:00
|
|
|
|
2014-06-28 20:52:56 -04:00
|
|
|
/* called BEFORE the view has changed */
|
2010-05-05 17:10:09 -04:00
|
|
|
|
2014-06-28 20:52:56 -04:00
|
|
|
if (ev->button == 1) {
|
|
|
|
if (Keyboard::modifier_state_equals (ev->state, Keyboard::ModifierMask (Keyboard::PrimaryModifier|Keyboard::TertiaryModifier))) {
|
2010-05-06 14:40:37 -04:00
|
|
|
|
2014-06-28 20:52:56 -04:00
|
|
|
if (model) {
|
|
|
|
/* disable isolate for all routes */
|
|
|
|
DisplaySuspender ds;
|
|
|
|
_session->set_solo_isolated (_session->get_routes(), false, Session::rt_cleanup, true);
|
|
|
|
}
|
2010-05-06 14:40:37 -04:00
|
|
|
|
2014-06-28 20:52:56 -04:00
|
|
|
} else {
|
|
|
|
if (model == view) {
|
2010-05-06 14:40:37 -04:00
|
|
|
|
2014-06-28 20:52:56 -04:00
|
|
|
/* flip just this route */
|
2010-05-06 14:40:37 -04:00
|
|
|
|
2014-06-28 20:52:56 -04:00
|
|
|
boost::shared_ptr<RouteList> rl (new RouteList);
|
|
|
|
rl->push_back (_route);
|
|
|
|
DisplaySuspender ds;
|
|
|
|
_session->set_solo_isolated (rl, !view, Session::rt_cleanup, true);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2010-05-05 17:10:09 -04:00
|
|
|
|
2014-08-28 11:31:57 -04:00
|
|
|
return false;
|
2010-05-05 16:29:46 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
bool
|
2012-05-21 06:10:26 -04:00
|
|
|
RouteUI::solo_safe_button_release (GdkEventButton* ev)
|
2010-05-05 16:29:46 -04:00
|
|
|
{
|
2012-05-21 06:10:26 -04:00
|
|
|
if (ev->button == 1) {
|
|
|
|
_route->set_solo_safe (!solo_safe_led->active_state(), this);
|
|
|
|
}
|
|
|
|
return false;
|
2010-05-05 16:29:46 -04:00
|
|
|
}
|
|
|
|
|
2005-09-25 14:42:24 -04:00
|
|
|
void
|
2009-06-09 16:21:19 -04:00
|
|
|
RouteUI::toggle_solo_isolated (Gtk::CheckMenuItem* check)
|
2005-09-25 14:42:24 -04:00
|
|
|
{
|
2010-05-05 17:10:09 -04:00
|
|
|
bool view = check->get_active();
|
|
|
|
bool model = _route->solo_isolated();
|
|
|
|
|
|
|
|
/* called AFTER the view has changed */
|
|
|
|
|
|
|
|
if (model != view) {
|
|
|
|
_route->set_solo_isolated (view, this);
|
|
|
|
}
|
2005-09-25 14:42:24 -04:00
|
|
|
}
|
|
|
|
|
2009-11-21 14:33:09 -05:00
|
|
|
void
|
|
|
|
RouteUI::toggle_solo_safe (Gtk::CheckMenuItem* check)
|
|
|
|
{
|
|
|
|
_route->set_solo_safe (check->get_active(), this);
|
|
|
|
}
|
|
|
|
|
2014-07-29 17:40:19 -04:00
|
|
|
/** Ask the user to choose a colour, and then apply that color to my route
|
2011-02-22 20:03:51 -05:00
|
|
|
*/
|
|
|
|
void
|
2011-02-22 20:03:37 -05:00
|
|
|
RouteUI::choose_color ()
|
2005-09-25 14:42:24 -04:00
|
|
|
{
|
|
|
|
bool picked;
|
2011-02-22 20:03:37 -05:00
|
|
|
Gdk::Color const color = Gtkmm2ext::UI::instance()->get_color (_("Color Selection"), picked, &_color);
|
2005-09-25 14:42:24 -04:00
|
|
|
|
|
|
|
if (picked) {
|
2014-07-29 17:40:19 -04:00
|
|
|
set_color(color);
|
2005-09-25 14:42:24 -04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2011-08-30 11:44:00 -04:00
|
|
|
/** Set the route's own color. This may not be used for display if
|
|
|
|
* the route is in a group which shares its color with its routes.
|
|
|
|
*/
|
2005-09-25 14:42:24 -04:00
|
|
|
void
|
2005-12-18 07:02:42 -05:00
|
|
|
RouteUI::set_color (const Gdk::Color & c)
|
2005-09-25 14:42:24 -04:00
|
|
|
{
|
2012-12-26 18:35:31 -05:00
|
|
|
/* leave _color alone in the group case so that tracks can retain their
|
|
|
|
* own pre-group colors.
|
|
|
|
*/
|
2009-10-14 12:10:01 -04:00
|
|
|
|
2012-12-26 18:49:34 -05:00
|
|
|
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
|
|
|
|
*/
|
|
|
|
|
|
|
|
gui_object_state().set_property<string> (route_state_id(), X_("color"), buf);
|
|
|
|
_route->gui_changed ("color", (void *) 0); /* EMIT_SIGNAL */
|
2005-09-25 14:42:24 -04:00
|
|
|
}
|
|
|
|
|
2011-08-30 11:44:00 -04:00
|
|
|
/** @return GUI state ID for things that are common to the route in all its representations */
|
|
|
|
string
|
|
|
|
RouteUI::route_state_id () const
|
|
|
|
{
|
|
|
|
return string_compose (X_("route %1"), _route->id().to_s());
|
|
|
|
}
|
|
|
|
|
2011-07-06 20:37:13 -04:00
|
|
|
int
|
|
|
|
RouteUI::set_color_from_route ()
|
2005-09-25 14:42:24 -04:00
|
|
|
{
|
2011-08-30 11:44:00 -04:00
|
|
|
const string str = gui_object_state().get_string (route_state_id(), X_("color"));
|
2010-11-12 17:32:36 -05:00
|
|
|
|
2011-07-06 20:37:13 -04:00
|
|
|
if (str.empty()) {
|
|
|
|
return 1;
|
2005-09-25 14:42:24 -04:00
|
|
|
}
|
|
|
|
|
2011-07-06 20:37:13 -04:00
|
|
|
int r, g, b;
|
2009-10-14 12:10:01 -04:00
|
|
|
|
2011-07-06 20:37:13 -04:00
|
|
|
sscanf (str.c_str(), "%d:%d:%d", &r, &g, &b);
|
2005-09-25 14:42:24 -04:00
|
|
|
|
2011-07-06 20:37:13 -04:00
|
|
|
_color.set_red (r);
|
|
|
|
_color.set_green (g);
|
|
|
|
_color.set_blue (b);
|
|
|
|
|
|
|
|
return 0;
|
2005-09-25 14:42:24 -04:00
|
|
|
}
|
|
|
|
|
2011-08-03 09:28:36 -04:00
|
|
|
/** @return true if this name should be used for the route, otherwise false */
|
2011-07-25 22:07:59 -04:00
|
|
|
bool
|
|
|
|
RouteUI::verify_new_route_name (const std::string& name)
|
|
|
|
{
|
2011-09-16 07:39:18 -04:00
|
|
|
if (name.find (':') == string::npos) {
|
2011-08-03 09:28:36 -04:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
MessageDialog colon_msg (
|
|
|
|
_("The use of colons (':') is discouraged in track and bus names.\nDo you want to use this new name?"),
|
|
|
|
false, MESSAGE_QUESTION, BUTTONS_NONE
|
|
|
|
);
|
|
|
|
|
|
|
|
colon_msg.add_button (_("Use the new name"), Gtk::RESPONSE_ACCEPT);
|
|
|
|
colon_msg.add_button (_("Re-edit the name"), Gtk::RESPONSE_CANCEL);
|
2011-07-25 22:07:59 -04:00
|
|
|
|
2011-08-03 09:28:36 -04:00
|
|
|
return (colon_msg.run () == Gtk::RESPONSE_ACCEPT);
|
2011-07-25 22:07:59 -04:00
|
|
|
}
|
|
|
|
|
2005-09-25 14:42:24 -04:00
|
|
|
void
|
|
|
|
RouteUI::route_rename ()
|
|
|
|
{
|
|
|
|
ArdourPrompter name_prompter (true);
|
2005-10-26 21:10:36 -04:00
|
|
|
string result;
|
2011-07-25 22:07:59 -04:00
|
|
|
bool done = false;
|
|
|
|
|
2010-05-06 20:18:47 -04:00
|
|
|
if (is_track()) {
|
|
|
|
name_prompter.set_title (_("Rename Track"));
|
|
|
|
} else {
|
|
|
|
name_prompter.set_title (_("Rename Bus"));
|
|
|
|
}
|
|
|
|
name_prompter.set_prompt (_("New name:"));
|
2006-07-27 21:08:57 -04:00
|
|
|
name_prompter.set_initial_text (_route->name());
|
2006-04-19 16:42:17 -04:00
|
|
|
name_prompter.add_button (_("Rename"), Gtk::RESPONSE_ACCEPT);
|
2006-04-22 11:28:59 -04:00
|
|
|
name_prompter.set_response_sensitive (Gtk::RESPONSE_ACCEPT, false);
|
2005-09-25 14:42:24 -04:00
|
|
|
name_prompter.show_all ();
|
|
|
|
|
2011-07-25 22:07:59 -04:00
|
|
|
while (!done) {
|
|
|
|
switch (name_prompter.run ()) {
|
|
|
|
case Gtk::RESPONSE_ACCEPT:
|
|
|
|
name_prompter.get_result (result);
|
|
|
|
name_prompter.hide ();
|
|
|
|
if (result.length()) {
|
|
|
|
if (verify_new_route_name (result)) {
|
|
|
|
_route->set_name (result);
|
|
|
|
done = true;
|
|
|
|
} else {
|
|
|
|
/* back to name prompter */
|
|
|
|
}
|
|
|
|
|
|
|
|
} else {
|
|
|
|
/* nothing entered, just get out of here */
|
|
|
|
done = true;
|
|
|
|
}
|
|
|
|
break;
|
2011-12-01 14:33:28 -05:00
|
|
|
default:
|
|
|
|
done = true;
|
|
|
|
break;
|
2009-10-14 12:10:01 -04:00
|
|
|
}
|
2005-09-25 14:42:24 -04:00
|
|
|
}
|
|
|
|
|
2005-10-26 21:10:36 -04:00
|
|
|
return;
|
2009-10-14 12:10:01 -04:00
|
|
|
|
2005-09-25 14:42:24 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
2010-02-19 13:09:08 -05:00
|
|
|
RouteUI::property_changed (const PropertyChange& what_changed)
|
2005-09-25 14:42:24 -04:00
|
|
|
{
|
2010-02-19 13:09:08 -05:00
|
|
|
if (what_changed.contains (ARDOUR::Properties::name)) {
|
|
|
|
name_label.set_text (_route->name());
|
|
|
|
}
|
2005-09-25 14:42:24 -04:00
|
|
|
}
|
|
|
|
|
2014-07-29 17:40:19 -04:00
|
|
|
void
|
|
|
|
RouteUI::toggle_comment_editor ()
|
|
|
|
{
|
|
|
|
// if (ignore_toggle) {
|
|
|
|
// return;
|
|
|
|
// }
|
|
|
|
|
|
|
|
if (comment_window && comment_window->is_visible ()) {
|
|
|
|
comment_window->hide ();
|
|
|
|
} else {
|
|
|
|
open_comment_editor ();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
RouteUI::open_comment_editor ()
|
|
|
|
{
|
|
|
|
if (comment_window == 0) {
|
|
|
|
setup_comment_editor ();
|
|
|
|
}
|
|
|
|
|
|
|
|
string title;
|
|
|
|
title = _route->name();
|
|
|
|
title += _(": comment editor");
|
|
|
|
|
|
|
|
comment_window->set_title (title);
|
|
|
|
comment_window->present();
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
RouteUI::setup_comment_editor ()
|
|
|
|
{
|
|
|
|
comment_window = new ArdourWindow (""); // title will be reset to show route
|
|
|
|
comment_window->set_skip_taskbar_hint (true);
|
|
|
|
comment_window->signal_hide().connect (sigc::mem_fun(*this, &MixerStrip::comment_editor_done_editing));
|
|
|
|
comment_window->set_default_size (400, 200);
|
|
|
|
|
|
|
|
comment_area = manage (new TextView());
|
|
|
|
comment_area->set_name ("MixerTrackCommentArea");
|
|
|
|
comment_area->set_wrap_mode (WRAP_WORD);
|
|
|
|
comment_area->set_editable (true);
|
|
|
|
comment_area->get_buffer()->set_text (_route->comment());
|
|
|
|
comment_area->show ();
|
|
|
|
|
|
|
|
comment_window->add (*comment_area);
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
RouteUI::comment_changed (void *src)
|
|
|
|
{
|
|
|
|
ENSURE_GUI_THREAD (*this, &MixerStrip::comment_changed, src)
|
|
|
|
|
|
|
|
if (src != this) {
|
|
|
|
ignore_comment_edit = true;
|
|
|
|
if (comment_area) {
|
|
|
|
comment_area->get_buffer()->set_text (_route->comment());
|
|
|
|
}
|
|
|
|
ignore_comment_edit = false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
RouteUI::comment_editor_done_editing ()
|
|
|
|
{
|
2014-08-22 12:45:34 -04:00
|
|
|
ENSURE_GUI_THREAD (*this, &MixerStrip::comment_editor_done_editing, src)
|
|
|
|
|
2014-07-29 17:40:19 -04:00
|
|
|
string const str = comment_area->get_buffer()->get_text();
|
|
|
|
if (str == _route->comment ()) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
_route->set_comment (str, this);
|
|
|
|
}
|
|
|
|
|
2005-09-25 14:42:24 -04:00
|
|
|
void
|
2011-03-07 08:04:46 -05:00
|
|
|
RouteUI::set_route_active (bool a, bool apply_to_selection)
|
2005-09-25 14:42:24 -04:00
|
|
|
{
|
2011-03-07 08:04:46 -05:00
|
|
|
if (apply_to_selection) {
|
|
|
|
ARDOUR_UI::instance()->the_editor().get_selection().tracks.foreach_route_ui (boost::bind (&RouteTimeAxisView::set_route_active, _1, a, false));
|
|
|
|
} else {
|
|
|
|
_route->set_active (a, this);
|
2005-09-25 14:42:24 -04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2007-05-31 22:27:21 -04:00
|
|
|
void
|
|
|
|
RouteUI::toggle_denormal_protection ()
|
|
|
|
{
|
|
|
|
if (denormal_menu_item) {
|
|
|
|
|
|
|
|
bool x;
|
|
|
|
|
2009-12-11 18:29:48 -05:00
|
|
|
ENSURE_GUI_THREAD (*this, &RouteUI::toggle_denormal_protection)
|
2009-10-14 12:10:01 -04:00
|
|
|
|
2007-05-31 22:27:21 -04:00
|
|
|
if ((x = denormal_menu_item->get_active()) != _route->denormal_protection()) {
|
2009-06-10 14:10:07 -04:00
|
|
|
_route->set_denormal_protection (x);
|
2007-05-31 22:27:21 -04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
RouteUI::denormal_protection_changed ()
|
|
|
|
{
|
2009-06-10 14:10:07 -04:00
|
|
|
if (denormal_menu_item) {
|
|
|
|
denormal_menu_item->set_active (_route->denormal_protection());
|
|
|
|
}
|
2007-05-31 22:27:21 -04:00
|
|
|
}
|
|
|
|
|
2005-09-25 14:42:24 -04:00
|
|
|
void
|
|
|
|
RouteUI::disconnect_input ()
|
|
|
|
{
|
2009-06-09 16:21:19 -04:00
|
|
|
_route->input()->disconnect (this);
|
2005-09-25 14:42:24 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
RouteUI::disconnect_output ()
|
|
|
|
{
|
2009-06-09 16:21:19 -04:00
|
|
|
_route->output()->disconnect (this);
|
2005-09-25 14:42:24 -04:00
|
|
|
}
|
|
|
|
|
2006-07-23 08:03:19 -04:00
|
|
|
bool
|
|
|
|
RouteUI::is_track () const
|
|
|
|
{
|
2007-06-15 18:05:07 -04:00
|
|
|
return boost::dynamic_pointer_cast<Track>(_route) != 0;
|
2006-07-23 08:03:19 -04:00
|
|
|
}
|
|
|
|
|
2007-06-15 18:05:07 -04:00
|
|
|
boost::shared_ptr<Track>
|
2006-07-27 21:08:57 -04:00
|
|
|
RouteUI::track() const
|
2005-09-25 14:42:24 -04:00
|
|
|
{
|
2007-06-15 18:05:07 -04:00
|
|
|
return boost::dynamic_pointer_cast<Track>(_route);
|
2005-09-25 14:42:24 -04:00
|
|
|
}
|
|
|
|
|
2006-07-05 15:47:25 -04:00
|
|
|
bool
|
2006-07-27 21:08:57 -04:00
|
|
|
RouteUI::is_audio_track () const
|
2006-07-05 15:47:25 -04:00
|
|
|
{
|
2007-06-15 18:05:07 -04:00
|
|
|
return boost::dynamic_pointer_cast<AudioTrack>(_route) != 0;
|
2006-07-05 15:47:25 -04:00
|
|
|
}
|
|
|
|
|
2007-06-15 18:05:07 -04:00
|
|
|
boost::shared_ptr<AudioTrack>
|
2006-07-27 21:08:57 -04:00
|
|
|
RouteUI::audio_track() const
|
2005-09-25 14:42:24 -04:00
|
|
|
{
|
2007-06-15 18:05:07 -04:00
|
|
|
return boost::dynamic_pointer_cast<AudioTrack>(_route);
|
2005-09-25 14:42:24 -04:00
|
|
|
}
|
|
|
|
|
2006-07-27 21:08:57 -04:00
|
|
|
bool
|
|
|
|
RouteUI::is_midi_track () const
|
2005-09-25 14:42:24 -04:00
|
|
|
{
|
2007-06-15 18:05:07 -04:00
|
|
|
return boost::dynamic_pointer_cast<MidiTrack>(_route) != 0;
|
2005-09-25 14:42:24 -04:00
|
|
|
}
|
2006-07-05 15:47:25 -04:00
|
|
|
|
2007-06-15 18:05:07 -04:00
|
|
|
boost::shared_ptr<MidiTrack>
|
2006-07-05 15:47:25 -04:00
|
|
|
RouteUI::midi_track() const
|
|
|
|
{
|
2007-06-15 18:05:07 -04:00
|
|
|
return boost::dynamic_pointer_cast<MidiTrack>(_route);
|
2006-07-05 15:47:25 -04:00
|
|
|
}
|
|
|
|
|
2010-08-09 20:09:25 -04:00
|
|
|
bool
|
|
|
|
RouteUI::has_audio_outputs () const
|
|
|
|
{
|
|
|
|
return (_route->n_outputs().n_audio() > 0);
|
|
|
|
}
|
|
|
|
|
2005-09-25 14:42:24 -04:00
|
|
|
string
|
|
|
|
RouteUI::name() const
|
|
|
|
{
|
2006-07-27 21:08:57 -04:00
|
|
|
return _route->name();
|
2005-09-25 14:42:24 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
RouteUI::map_frozen ()
|
|
|
|
{
|
2009-12-11 18:29:48 -05:00
|
|
|
ENSURE_GUI_THREAD (*this, &RouteUI::map_frozen)
|
2005-09-25 14:42:24 -04:00
|
|
|
|
2006-07-27 21:08:57 -04:00
|
|
|
AudioTrack* at = dynamic_cast<AudioTrack*>(_route.get());
|
2005-09-25 14:42:24 -04:00
|
|
|
|
|
|
|
if (at) {
|
|
|
|
switch (at->freeze_state()) {
|
|
|
|
case AudioTrack::Frozen:
|
|
|
|
rec_enable_button->set_sensitive (false);
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
rec_enable_button->set_sensitive (true);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2006-07-27 21:08:57 -04:00
|
|
|
|
2007-06-27 18:06:35 -04:00
|
|
|
void
|
|
|
|
RouteUI::adjust_latency ()
|
|
|
|
{
|
2013-07-30 23:26:46 -04:00
|
|
|
LatencyDialog dialog (_route->name() + _(" latency"), *(_route->output()), _session->frame_rate(), AudioEngine::instance()->samples_per_cycle());
|
2007-06-27 18:06:35 -04:00
|
|
|
}
|
2009-02-27 17:52:39 -05:00
|
|
|
|
2009-03-02 13:08:15 -05:00
|
|
|
void
|
|
|
|
RouteUI::save_as_template ()
|
|
|
|
{
|
2012-06-23 01:07:05 -04:00
|
|
|
std::string path;
|
2010-09-14 12:51:02 -04:00
|
|
|
std::string safe_name;
|
2009-03-02 13:08:15 -05:00
|
|
|
string name;
|
2009-10-14 12:10:01 -04:00
|
|
|
|
2009-03-02 13:08:15 -05:00
|
|
|
path = ARDOUR::user_route_template_directory ();
|
2009-10-14 12:10:01 -04:00
|
|
|
|
2012-06-23 01:07:05 -04:00
|
|
|
if (g_mkdir_with_parents (path.c_str(), 0755)) {
|
|
|
|
error << string_compose (_("Cannot create route template directory %1"), path) << endmsg;
|
2009-03-02 13:08:15 -05:00
|
|
|
return;
|
|
|
|
}
|
2009-10-14 12:10:01 -04:00
|
|
|
|
2009-03-02 13:08:15 -05:00
|
|
|
Prompter p (true); // modal
|
2009-10-14 12:10:01 -04:00
|
|
|
|
2010-05-06 20:18:47 -04:00
|
|
|
p.set_title (_("Save As Template"));
|
2009-03-02 13:08:15 -05:00
|
|
|
p.set_prompt (_("Template name:"));
|
2010-12-29 17:27:48 -05:00
|
|
|
p.add_button (Gtk::Stock::SAVE, Gtk::RESPONSE_ACCEPT);
|
2009-03-02 13:08:15 -05:00
|
|
|
switch (p.run()) {
|
|
|
|
case RESPONSE_ACCEPT:
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
return;
|
|
|
|
}
|
2009-10-14 12:10:01 -04:00
|
|
|
|
2009-03-02 13:08:15 -05:00
|
|
|
p.hide ();
|
|
|
|
p.get_result (name, true);
|
2009-10-14 12:10:01 -04:00
|
|
|
|
2009-03-02 13:08:15 -05:00
|
|
|
safe_name = legalize_for_path (name);
|
2009-04-21 21:35:31 -04:00
|
|
|
safe_name += template_suffix;
|
2009-10-14 12:10:01 -04:00
|
|
|
|
2012-06-23 01:07:05 -04:00
|
|
|
path = Glib::build_filename (path, safe_name);
|
2009-10-14 12:10:01 -04:00
|
|
|
|
2012-06-23 01:07:05 -04:00
|
|
|
_route->save_as_template (path, name);
|
2009-03-02 13:08:15 -05:00
|
|
|
}
|
2009-06-14 09:44:26 -04:00
|
|
|
|
|
|
|
void
|
|
|
|
RouteUI::check_rec_enable_sensitivity ()
|
|
|
|
{
|
2011-11-02 15:51:59 -04:00
|
|
|
if (_session->transport_rolling() && rec_enable_button->active_state() && Config->get_disable_disarm_during_roll()) {
|
2009-06-14 09:44:26 -04:00
|
|
|
rec_enable_button->set_sensitive (false);
|
|
|
|
} else {
|
|
|
|
rec_enable_button->set_sensitive (true);
|
|
|
|
}
|
2011-10-21 11:05:33 -04:00
|
|
|
|
|
|
|
update_monitoring_display ();
|
2009-06-14 09:44:26 -04:00
|
|
|
}
|
2009-06-14 13:56:29 -04:00
|
|
|
|
|
|
|
void
|
|
|
|
RouteUI::parameter_changed (string const & p)
|
|
|
|
{
|
2011-10-21 11:05:33 -04:00
|
|
|
/* this handles RC and per-session parameter changes */
|
|
|
|
|
2009-06-14 13:56:29 -04:00
|
|
|
if (p == "disable-disarm-during-roll") {
|
|
|
|
check_rec_enable_sensitivity ();
|
2011-01-04 15:52:30 -05:00
|
|
|
} else if (p == "use-monitor-bus" || p == "solo-control-is-listen-control" || p == "listen-position") {
|
2009-06-23 16:02:15 -04:00
|
|
|
set_button_names ();
|
2011-10-21 11:05:33 -04:00
|
|
|
} else if (p == "auto-input") {
|
|
|
|
update_monitoring_display ();
|
2014-09-04 22:20:15 -04:00
|
|
|
} else if (p == "blink-rec-arm") {
|
|
|
|
if (ARDOUR_UI::config()->get_blink_rec_arm()) {
|
|
|
|
rec_blink_connection.disconnect ();
|
2014-12-25 10:02:00 -05:00
|
|
|
rec_blink_connection = Timers::blink_connect (sigc::mem_fun (*this, &RouteUI::blink_rec_display));
|
2014-09-04 22:20:15 -04:00
|
|
|
} else {
|
|
|
|
rec_blink_connection.disconnect ();
|
2014-09-05 11:26:21 -04:00
|
|
|
RouteUI::blink_rec_display(false);
|
2014-09-04 22:20:15 -04:00
|
|
|
}
|
2009-06-14 13:56:29 -04:00
|
|
|
}
|
|
|
|
}
|
2009-06-23 16:02:15 -04:00
|
|
|
|
2009-07-13 19:09:16 -04:00
|
|
|
void
|
|
|
|
RouteUI::step_gain_up ()
|
|
|
|
{
|
2009-08-22 06:21:39 -04:00
|
|
|
_route->set_gain (dB_to_coefficient (accurate_coefficient_to_dB (_route->gain_control()->get_value()) + 0.1), this);
|
2009-07-13 19:09:16 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
RouteUI::page_gain_up ()
|
|
|
|
{
|
2009-08-22 06:21:39 -04:00
|
|
|
_route->set_gain (dB_to_coefficient (accurate_coefficient_to_dB (_route->gain_control()->get_value()) + 0.5), this);
|
2009-07-13 19:09:16 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
RouteUI::step_gain_down ()
|
|
|
|
{
|
2009-08-22 06:21:39 -04:00
|
|
|
_route->set_gain (dB_to_coefficient (accurate_coefficient_to_dB (_route->gain_control()->get_value()) - 0.1), this);
|
2009-07-13 19:09:16 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
RouteUI::page_gain_down ()
|
|
|
|
{
|
2009-08-22 06:21:39 -04:00
|
|
|
_route->set_gain (dB_to_coefficient (accurate_coefficient_to_dB (_route->gain_control()->get_value()) - 0.5), this);
|
2009-07-13 19:09:16 -04:00
|
|
|
}
|
2009-08-29 19:31:59 -04:00
|
|
|
|
|
|
|
void
|
|
|
|
RouteUI::open_remote_control_id_dialog ()
|
|
|
|
{
|
|
|
|
ArdourDialog dialog (_("Remote Control ID"));
|
2012-06-25 08:46:13 -04:00
|
|
|
SpinButton* spin = 0;
|
2009-08-29 19:31:59 -04:00
|
|
|
|
2012-06-25 08:46:13 -04:00
|
|
|
dialog.get_vbox()->set_border_width (18);
|
2009-08-29 19:31:59 -04:00
|
|
|
|
2012-06-25 08:46:13 -04:00
|
|
|
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());
|
2012-11-21 14:54:52 -05:00
|
|
|
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 {
|
2013-10-20 09:19:43 -04:00
|
|
|
l->set_markup (string_compose (_("The remote control ID of %5 is: %2\n\n\n"
|
2014-02-10 10:53:01 -05:00
|
|
|
"Remote Control IDs are currently determined by track/bus ordering in %6.\n\n"
|
2013-10-20 09:19:43 -04:00
|
|
|
"%3Use the User Interaction tab of the Preferences window if you want to change this%4"),
|
2012-11-21 14:54:52 -05:00
|
|
|
(is_track() ? _("track") : _("bus")),
|
|
|
|
_route->remote_control_id(),
|
|
|
|
"<span size=\"small\" style=\"italic\">",
|
|
|
|
"</span>",
|
2014-02-10 10:53:01 -05:00
|
|
|
Glib::Markup::escape_text (_route->name()),
|
|
|
|
PROGRAM_NAME));
|
2012-11-21 14:54:52 -05:00
|
|
|
}
|
2012-06-25 08:46:13 -04:00
|
|
|
dialog.get_vbox()->pack_start (*l);
|
|
|
|
dialog.add_button (Stock::OK, RESPONSE_CANCEL);
|
|
|
|
}
|
2009-08-29 19:31:59 -04:00
|
|
|
|
|
|
|
dialog.show_all ();
|
|
|
|
int const r = dialog.run ();
|
|
|
|
|
2012-06-25 08:46:13 -04:00
|
|
|
if (r == RESPONSE_ACCEPT && spin) {
|
2009-08-29 19:31:59 -04:00
|
|
|
_route->set_remote_control_id (spin->get_value_as_int ());
|
|
|
|
}
|
|
|
|
}
|
2010-08-13 17:33:01 -04:00
|
|
|
|
|
|
|
void
|
|
|
|
RouteUI::setup_invert_buttons ()
|
|
|
|
{
|
|
|
|
/* remove old invert buttons */
|
2011-11-30 11:40:05 -05:00
|
|
|
for (vector<ArdourButton*>::iterator i = _invert_buttons.begin(); i != _invert_buttons.end(); ++i) {
|
2010-08-13 17:33:01 -04:00
|
|
|
_invert_button_box.remove (**i);
|
|
|
|
}
|
|
|
|
|
|
|
|
_invert_buttons.clear ();
|
|
|
|
|
|
|
|
if (!_route || !_route->input()) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
uint32_t const N = _route->input()->n_ports().n_audio ();
|
|
|
|
|
|
|
|
uint32_t const to_add = (N <= _max_invert_buttons) ? N : 1;
|
|
|
|
|
|
|
|
for (uint32_t i = 0; i < to_add; ++i) {
|
2011-11-28 12:58:15 -05:00
|
|
|
ArdourButton* b = manage (new ArdourButton);
|
2014-08-28 11:31:57 -04:00
|
|
|
b->signal_button_press_event().connect (sigc::mem_fun (*this, &RouteUI::invert_press), false);
|
|
|
|
b->signal_button_release_event().connect (sigc::bind (sigc::mem_fun (*this, &RouteUI::invert_release), i), false);
|
2011-06-01 13:00:29 -04:00
|
|
|
|
2012-12-06 15:48:44 -05:00
|
|
|
b->set_name (X_("invert button"));
|
2010-08-13 17:33:01 -04:00
|
|
|
if (to_add == 1) {
|
2012-03-05 17:06:16 -05:00
|
|
|
if (N > 1) {
|
|
|
|
b->set_text (string_compose (X_("Ø (%1)"), N));
|
|
|
|
} else {
|
|
|
|
b->set_text (X_("Ø"));
|
|
|
|
}
|
2010-08-13 17:33:01 -04:00
|
|
|
} else {
|
2011-11-28 12:58:15 -05:00
|
|
|
b->set_text (string_compose (X_("Ø%1"), i + 1));
|
2010-08-13 17:33:01 -04:00
|
|
|
}
|
|
|
|
|
2012-03-04 20:16:50 -05:00
|
|
|
if (N <= _max_invert_buttons) {
|
2010-08-13 17:33:01 -04:00
|
|
|
UI::instance()->set_tip (*b, string_compose (_("Left-click to invert (phase reverse) channel %1 of this track. Right-click to show menu."), i + 1));
|
|
|
|
} else {
|
2012-03-04 20:16:50 -05:00
|
|
|
UI::instance()->set_tip (*b, _("Click to show a menu of channels for inversion (phase reverse)"));
|
2010-08-13 17:33:01 -04:00
|
|
|
}
|
2011-06-01 13:00:29 -04:00
|
|
|
|
2010-08-13 17:33:01 -04:00
|
|
|
_invert_buttons.push_back (b);
|
|
|
|
_invert_button_box.pack_start (*b);
|
|
|
|
}
|
2011-06-01 13:00:29 -04:00
|
|
|
|
2011-11-30 16:07:43 -05:00
|
|
|
_invert_button_box.set_spacing (1);
|
2010-08-13 17:33:01 -04:00
|
|
|
_invert_button_box.show_all ();
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
RouteUI::set_invert_button_state ()
|
|
|
|
{
|
|
|
|
uint32_t const N = _route->input()->n_ports().n_audio();
|
|
|
|
if (N > _max_invert_buttons) {
|
|
|
|
|
2012-03-04 20:16:50 -05:00
|
|
|
/* One button for many channels; explicit active if all channels are inverted,
|
|
|
|
implicit active if some are, off if none are.
|
|
|
|
*/
|
|
|
|
|
|
|
|
ArdourButton* b = _invert_buttons.front ();
|
|
|
|
|
|
|
|
if (_route->phase_invert().count() == _route->phase_invert().size()) {
|
|
|
|
b->set_active_state (Gtkmm2ext::ExplicitActive);
|
|
|
|
} else if (_route->phase_invert().any()) {
|
|
|
|
b->set_active_state (Gtkmm2ext::ImplicitActive);
|
|
|
|
} else {
|
|
|
|
b->set_active_state (Gtkmm2ext::Off);
|
|
|
|
}
|
|
|
|
|
|
|
|
} else {
|
|
|
|
|
|
|
|
/* One button per channel; just set active */
|
|
|
|
|
|
|
|
int j = 0;
|
|
|
|
for (vector<ArdourButton*>::iterator i = _invert_buttons.begin(); i != _invert_buttons.end(); ++i, ++j) {
|
|
|
|
(*i)->set_active (_route->phase_invert (j));
|
|
|
|
}
|
|
|
|
|
2010-08-13 17:33:01 -04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2011-11-30 11:40:05 -05:00
|
|
|
bool
|
|
|
|
RouteUI::invert_release (GdkEventButton* ev, uint32_t i)
|
2010-08-13 17:33:01 -04:00
|
|
|
{
|
2011-11-30 11:40:05 -05:00
|
|
|
if (ev->button == 1 && i < _invert_buttons.size()) {
|
2012-03-04 20:16:50 -05:00
|
|
|
uint32_t const N = _route->input()->n_ports().n_audio ();
|
|
|
|
if (N <= _max_invert_buttons) {
|
|
|
|
/* left-click inverts phase so long as we have a button per channel */
|
|
|
|
_route->set_phase_invert (i, !_invert_buttons[i]->get_active());
|
2014-08-27 11:49:36 -04:00
|
|
|
return false;
|
2012-03-04 20:16:50 -05:00
|
|
|
}
|
2010-08-13 17:33:01 -04:00
|
|
|
}
|
2011-11-30 11:40:05 -05:00
|
|
|
return false;
|
2010-08-13 17:33:01 -04:00
|
|
|
}
|
|
|
|
|
2011-11-30 11:40:05 -05:00
|
|
|
|
2010-08-13 17:33:01 -04:00
|
|
|
bool
|
|
|
|
RouteUI::invert_press (GdkEventButton* ev)
|
|
|
|
{
|
|
|
|
using namespace Menu_Helpers;
|
2012-03-04 20:16:50 -05:00
|
|
|
|
|
|
|
uint32_t const N = _route->input()->n_ports().n_audio();
|
|
|
|
if (N <= _max_invert_buttons && ev->button != 3) {
|
|
|
|
/* If we have an invert button per channel, we only pop
|
|
|
|
up a menu on right-click; left click is handled
|
|
|
|
on release.
|
|
|
|
*/
|
2014-08-22 12:45:34 -04:00
|
|
|
return false;
|
2010-08-13 17:33:01 -04:00
|
|
|
}
|
2012-03-04 20:16:50 -05:00
|
|
|
|
2010-08-13 17:33:01 -04:00
|
|
|
delete _invert_menu;
|
|
|
|
_invert_menu = new Menu;
|
|
|
|
_invert_menu->set_name ("ArdourContextMenu");
|
|
|
|
MenuList& items = _invert_menu->items ();
|
|
|
|
|
|
|
|
for (uint32_t i = 0; i < N; ++i) {
|
|
|
|
items.push_back (CheckMenuElem (string_compose (X_("Ø%1"), i + 1), sigc::bind (sigc::mem_fun (*this, &RouteUI::invert_menu_toggled), i)));
|
2013-07-11 15:32:31 -04:00
|
|
|
Gtk::CheckMenuItem* e = dynamic_cast<Gtk::CheckMenuItem*> (&items.back ());
|
2010-08-13 17:33:01 -04:00
|
|
|
++_i_am_the_modifier;
|
|
|
|
e->set_active (_route->phase_invert (i));
|
|
|
|
--_i_am_the_modifier;
|
|
|
|
}
|
|
|
|
|
|
|
|
_invert_menu->popup (0, ev->time);
|
|
|
|
|
2014-08-27 11:49:36 -04:00
|
|
|
return true;
|
2010-08-13 17:33:01 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
RouteUI::invert_menu_toggled (uint32_t c)
|
|
|
|
{
|
|
|
|
if (_i_am_the_modifier) {
|
|
|
|
return;
|
|
|
|
}
|
2011-06-01 13:00:29 -04:00
|
|
|
|
2010-08-13 17:33:01 -04:00
|
|
|
_route->set_phase_invert (c, !_route->phase_invert (c));
|
|
|
|
}
|
2011-01-29 10:28:58 -05:00
|
|
|
|
|
|
|
void
|
|
|
|
RouteUI::set_invert_sensitive (bool yn)
|
|
|
|
{
|
2011-11-30 11:40:05 -05:00
|
|
|
for (vector<ArdourButton*>::iterator b = _invert_buttons.begin(); b != _invert_buttons.end(); ++b) {
|
2011-01-29 10:28:58 -05:00
|
|
|
(*b)->set_sensitive (yn);
|
|
|
|
}
|
|
|
|
}
|
2011-07-06 20:37:13 -04:00
|
|
|
|
|
|
|
void
|
|
|
|
RouteUI::request_redraw ()
|
|
|
|
{
|
|
|
|
if (_route) {
|
|
|
|
_route->gui_changed ("track_height", (void *) 0); /* EMIT_SIGNAL */
|
|
|
|
}
|
|
|
|
}
|
2011-08-30 11:44:00 -04:00
|
|
|
|
|
|
|
/** The Route's gui_changed signal has been emitted */
|
|
|
|
void
|
|
|
|
RouteUI::route_gui_changed (string what_changed)
|
|
|
|
{
|
|
|
|
if (what_changed == "color") {
|
|
|
|
if (set_color_from_route () == 0) {
|
|
|
|
route_color_changed ();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2011-08-31 15:14:12 -04:00
|
|
|
|
2014-09-02 20:35:42 -04:00
|
|
|
void
|
|
|
|
RouteUI::track_mode_changed (void)
|
|
|
|
{
|
|
|
|
assert(is_track());
|
|
|
|
switch (track()->mode()) {
|
|
|
|
case ARDOUR::NonLayered:
|
|
|
|
case ARDOUR::Normal:
|
2015-05-24 15:45:39 -04:00
|
|
|
rec_enable_button->set_icon (ArdourIcon::RecButton);
|
2014-09-02 20:35:42 -04:00
|
|
|
break;
|
|
|
|
case ARDOUR::Destructive:
|
2015-05-24 15:45:39 -04:00
|
|
|
rec_enable_button->set_icon (ArdourIcon::RecTapeMode);
|
2014-09-02 20:35:42 -04:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
rec_enable_button->queue_draw();
|
|
|
|
}
|
|
|
|
|
2011-08-31 15:14:12 -04:00
|
|
|
/** @return the color that this route should use; it maybe its own,
|
|
|
|
or it maybe that of its route group.
|
|
|
|
*/
|
|
|
|
Gdk::Color
|
|
|
|
RouteUI::color () const
|
|
|
|
{
|
|
|
|
RouteGroup* g = _route->route_group ();
|
|
|
|
|
|
|
|
if (g && g->is_color()) {
|
2014-06-09 23:28:32 -04:00
|
|
|
Gdk::Color c;
|
|
|
|
set_color_from_rgba (c, GroupTabs::group_color (g));
|
|
|
|
return c;
|
2011-08-31 15:14:12 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
return _color;
|
|
|
|
}
|
2011-11-02 20:42:16 -04:00
|
|
|
|
|
|
|
void
|
|
|
|
RouteUI::set_showing_sends_to (boost::shared_ptr<Route> send_to)
|
|
|
|
{
|
|
|
|
_showing_sends_to = send_to;
|
|
|
|
BusSendDisplayChanged (send_to); /* EMIT SIGNAL */
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
RouteUI::bus_send_display_changed (boost::shared_ptr<Route> send_to)
|
|
|
|
{
|
|
|
|
if (_route == send_to) {
|
2012-02-07 12:43:55 -05:00
|
|
|
show_sends_button->set_active (true);
|
2014-12-25 10:02:00 -05:00
|
|
|
send_blink_connection = Timers::blink_connect (sigc::mem_fun (*this, &RouteUI::send_blink));
|
2011-11-02 20:42:16 -04:00
|
|
|
} else {
|
2012-02-07 12:43:55 -05:00
|
|
|
show_sends_button->set_active (false);
|
2011-11-02 20:42:16 -04:00
|
|
|
send_blink_connection.disconnect ();
|
|
|
|
}
|
|
|
|
}
|
2011-11-04 13:53:21 -04:00
|
|
|
|
|
|
|
RouteGroup*
|
|
|
|
RouteUI::route_group() const
|
|
|
|
{
|
|
|
|
return _route->route_group();
|
|
|
|
}
|