2005-09-25 14:42:24 -04:00
/*
2006-08-03 22:18:45 -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 0213 9 , USA .
$ Id $
*/
2005-09-25 16:33:00 -04:00
# include <gtkmm2ext/gtk_ui.h>
# include <gtkmm2ext/stop_signal.h>
# include <gtkmm2ext/choice.h>
# include <gtkmm2ext/doi.h>
2006-08-03 22:18:45 -04:00
# include <gtkmm2ext/bindable_button.h>
2005-09-25 14:42:24 -04:00
# include <ardour/route_group.h>
2006-07-28 23:17:11 -04:00
# include <pbd/memento_command.h>
2006-10-18 13:42:59 -04:00
# include <pbd/stacktrace.h>
# include <pbd/shiva.h>
2005-09-25 14:42:24 -04:00
# include "route_ui.h"
# include "keyboard.h"
# include "utils.h"
# include "prompter.h"
# include "gui_thread.h"
# include <ardour/route.h>
# include <ardour/audio_track.h>
2006-06-22 19:40:55 -04:00
# include <ardour/audio_diskstream.h>
2005-09-25 14:42:24 -04:00
# include "i18n.h"
2005-10-10 16:38:53 -04:00
using namespace sigc ;
2005-09-25 14:42:24 -04:00
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 ;
2006-06-22 19:40:55 -04:00
using namespace PBD ;
2005-09-25 14:42:24 -04:00
2006-08-03 22:18:45 -04:00
RouteUI : : RouteUI ( boost : : shared_ptr < ARDOUR : : Route > rt , ARDOUR : : Session & sess , const char * m_name ,
2005-09-25 14:42:24 -04:00
const char * s_name , const char * r_name )
2006-08-03 22:18:45 -04:00
: AxisView ( sess ) ,
2005-09-25 14:42:24 -04:00
_route ( rt ) ,
mute_button ( 0 ) ,
solo_button ( 0 ) ,
rec_enable_button ( 0 )
{
xml_node = 0 ;
mute_menu = 0 ;
solo_menu = 0 ;
2006-01-07 21:56:49 -05:00
remote_control_menu = 0 ;
2005-09-25 14:42:24 -04:00
ignore_toggle = false ;
wait_for_release = false ;
route_active_menu_item = 0 ;
if ( set_color_from_route ( ) ) {
set_color ( unique_random_color ( ) ) ;
}
2006-10-25 16:11:42 -04:00
new PairedShiva < Route , RouteUI > ( * _route , * this ) ;
2006-10-18 13:42:59 -04:00
2006-08-03 22:18:45 -04:00
_route - > active_changed . connect ( mem_fun ( * this , & RouteUI : : route_active_changed ) ) ;
2005-09-25 14:42:24 -04:00
2006-08-03 22:18:45 -04:00
mute_button = manage ( new BindableToggleButton ( _route - > mute_control ( ) , m_name ) ) ;
solo_button = manage ( new BindableToggleButton ( _route - > solo_control ( ) , s_name ) ) ;
if ( is_track ( ) ) {
boost : : shared_ptr < Track > t = boost : : dynamic_pointer_cast < Track > ( _route ) ;
2005-09-25 14:42:24 -04:00
2006-08-15 21:19:06 -04:00
t - > diskstream ( ) - > RecordEnableChanged . connect ( mem_fun ( * this , & RouteUI : : route_rec_enable_changed ) ) ;
2005-09-25 14:42:24 -04:00
2006-01-18 19:03:55 -05:00
_session . RecordStateChanged . connect ( mem_fun ( * this , & RouteUI : : session_rec_enable_changed ) ) ;
2005-09-25 14:42:24 -04:00
2006-08-03 22:18:45 -04:00
rec_enable_button = manage ( new BindableToggleButton ( t - > rec_enable_control ( ) , r_name ) ) ;
2005-09-25 14:42:24 -04:00
2006-08-03 22:18:45 -04:00
rec_enable_button - > unset_flags ( Gtk : : CAN_FOCUS ) ;
update_rec_display ( ) ;
}
2006-09-04 12:04:09 -04:00
2005-09-25 16:33:00 -04:00
mute_button - > unset_flags ( Gtk : : CAN_FOCUS ) ;
solo_button - > unset_flags ( Gtk : : CAN_FOCUS ) ;
2006-09-04 12:04:09 -04:00
2005-09-25 14:42:24 -04:00
/* map the current state */
map_frozen ( ) ;
}
RouteUI : : ~ RouteUI ( )
{
2006-10-18 13:42:59 -04:00
GoingAway ( ) ; /* EMIT SIGNAL */
2005-09-25 14:42:24 -04:00
delete mute_menu ;
}
2006-09-01 22:54:04 -04:00
bool
2005-09-25 14:42:24 -04:00
RouteUI : : mute_press ( GdkEventButton * ev )
{
if ( ! ignore_toggle ) {
if ( Keyboard : : is_context_menu_event ( ev ) ) {
if ( mute_menu = = 0 ) {
build_mute_menu ( ) ;
}
mute_menu - > popup ( 0 , 0 ) ;
} else {
if ( ev - > button = = 2 ) {
// ctrl-button2 click is the midi binding click
// button2-click is "momentary"
if ( ! Keyboard : : modifier_state_equals ( ev - > state , Keyboard : : ModifierMask ( Keyboard : : Control ) ) ) {
wait_for_release = true ;
}
}
if ( ev - > button = = 1 | | ev - > button = = 2 ) {
if ( Keyboard : : modifier_state_equals ( ev - > state , Keyboard : : ModifierMask ( Keyboard : : Control | Keyboard : : Shift ) ) ) {
/* ctrl-shift-click applies change to all routes */
_session . begin_reversible_command ( _ ( " mute change " ) ) ;
2006-08-03 17:54:14 -04:00
Session : : GlobalMuteStateCommand * cmd = new Session : : GlobalMuteStateCommand ( _session , this ) ;
2006-08-03 23:42:34 -04:00
_session . set_all_mute ( ! _route - > muted ( ) ) ;
2006-07-28 23:17:11 -04:00
cmd - > mark ( ) ;
2006-07-28 19:38:30 -04:00
_session . add_command ( cmd ) ;
2005-09-25 14:42:24 -04:00
_session . commit_reversible_command ( ) ;
} else if ( Keyboard : : modifier_state_equals ( ev - > state , Keyboard : : Control ) ) {
/* ctrl-click applies change to the mix group.
ctrl - button2 is MIDI learn .
*/
if ( ev - > button = = 1 ) {
2006-08-03 22:18:45 -04:00
set_mix_group_mute ( _route , ! _route - > muted ( ) ) ;
2005-09-25 14:42:24 -04:00
}
} else {
/* plain click applies change to this route */
2006-08-03 22:18:45 -04:00
reversibly_apply_route_boolean ( " mute change " , & Route : : set_mute , ! _route - > muted ( ) , this ) ;
2005-09-25 14:42:24 -04:00
}
}
}
}
2005-12-06 11:21:06 -05:00
return true ;
2005-09-25 14:42:24 -04:00
}
2006-09-01 22:54:04 -04:00
bool
2005-09-25 14:42:24 -04:00
RouteUI : : mute_release ( GdkEventButton * ev )
{
if ( ! ignore_toggle ) {
if ( wait_for_release ) {
wait_for_release = false ;
// undo the last op
// because the press was the last undoable thing we did
_session . undo ( 1U ) ;
}
}
2005-12-06 11:21:06 -05:00
return true ;
2005-09-25 14:42:24 -04:00
}
2006-09-01 22:54:04 -04:00
bool
2005-09-25 14:42:24 -04:00
RouteUI : : solo_press ( GdkEventButton * ev )
{
if ( ! ignore_toggle ) {
if ( Keyboard : : is_context_menu_event ( ev ) ) {
if ( solo_menu = = 0 ) {
build_solo_menu ( ) ;
}
solo_menu - > popup ( 1 , 0 ) ;
} else {
if ( ev - > button = = 2 ) {
// ctrl-button2 click is the midi binding click
// button2-click is "momentary"
if ( ! Keyboard : : modifier_state_equals ( ev - > state , Keyboard : : ModifierMask ( Keyboard : : Control ) ) ) {
wait_for_release = true ;
}
}
if ( ev - > button = = 1 | | ev - > button = = 2 ) {
if ( Keyboard : : modifier_state_equals ( ev - > state , Keyboard : : ModifierMask ( Keyboard : : Control | Keyboard : : Shift ) ) ) {
/* ctrl-shift-click applies change to all routes */
_session . begin_reversible_command ( _ ( " solo change " ) ) ;
2006-08-03 17:54:14 -04:00
Session : : GlobalSoloStateCommand * cmd = new Session : : GlobalSoloStateCommand ( _session , this ) ;
2006-08-03 23:42:34 -04:00
_session . set_all_solo ( ! _route - > soloed ( ) ) ;
2006-07-28 23:17:11 -04:00
cmd - > mark ( ) ;
2006-07-28 19:38:30 -04:00
_session . add_command ( cmd ) ;
2005-09-25 14:42:24 -04:00
_session . commit_reversible_command ( ) ;
} else if ( Keyboard : : modifier_state_contains ( ev - > state , Keyboard : : ModifierMask ( Keyboard : : Control | Keyboard : : Alt ) ) ) {
// ctrl-alt-click: exclusively solo this track, not a toggle */
_session . begin_reversible_command ( _ ( " solo change " ) ) ;
2006-08-03 17:54:14 -04:00
Session : : GlobalSoloStateCommand * cmd = new Session : : GlobalSoloStateCommand ( _session , this ) ;
2005-09-25 14:42:24 -04:00
_session . set_all_solo ( false ) ;
2006-08-03 23:42:34 -04:00
_route - > set_solo ( true , this ) ;
2006-07-28 23:17:11 -04:00
cmd - > mark ( ) ;
2006-07-28 19:38:30 -04:00
_session . add_command ( cmd ) ;
2005-09-25 14:42:24 -04:00
_session . commit_reversible_command ( ) ;
} else if ( Keyboard : : modifier_state_equals ( ev - > state , Keyboard : : Shift ) ) {
// shift-click: set this route to solo safe
2006-08-03 22:18:45 -04:00
_route - > set_solo_safe ( ! _route - > solo_safe ( ) , this ) ;
2005-09-25 14:42:24 -04:00
wait_for_release = false ;
} else if ( Keyboard : : modifier_state_equals ( ev - > state , Keyboard : : Control ) ) {
/* ctrl-click: solo mix group.
ctrl - button2 is MIDI learn .
*/
if ( ev - > button = = 1 ) {
2006-08-03 22:18:45 -04:00
set_mix_group_solo ( _route , ! _route - > soloed ( ) ) ;
2005-09-25 14:42:24 -04:00
}
} else {
/* click: solo this route */
2006-08-03 22:18:45 -04:00
reversibly_apply_route_boolean ( " solo change " , & Route : : set_solo , ! _route - > soloed ( ) , this ) ;
2005-09-25 14:42:24 -04:00
}
}
}
}
2006-03-29 13:52:55 -05:00
return true ;
2005-09-25 14:42:24 -04:00
}
2006-09-01 22:54:04 -04:00
bool
2005-09-25 14:42:24 -04:00
RouteUI : : solo_release ( GdkEventButton * ev )
{
2006-03-29 13:52:55 -05:00
if ( ! ignore_toggle ) {
if ( wait_for_release ) {
2005-09-25 14:42:24 -04:00
wait_for_release = false ;
// undo the last op
// because the press was the last undoable thing we did
_session . undo ( 1U ) ;
}
}
2006-03-29 13:52:55 -05:00
return true ;
2005-09-25 14:42:24 -04:00
}
2006-09-01 22:54:04 -04:00
bool
2005-09-25 14:42:24 -04:00
RouteUI : : rec_enable_press ( GdkEventButton * ev )
{
2006-08-03 22:18:45 -04:00
if ( ! ignore_toggle & & is_track ( ) & & rec_enable_button ) {
2005-09-25 14:42:24 -04:00
if ( ev - > button = = 2 & & Keyboard : : modifier_state_equals ( ev - > state , Keyboard : : Control ) ) {
// do nothing on midi bind event
}
else if ( Keyboard : : modifier_state_equals ( ev - > state , Keyboard : : ModifierMask ( Keyboard : : Control | Keyboard : : Shift ) ) ) {
_session . begin_reversible_command ( _ ( " rec-enable change " ) ) ;
2006-08-03 17:54:14 -04:00
Session : : GlobalRecordEnableStateCommand * cmd = new Session : : GlobalRecordEnableStateCommand ( _session , this ) ;
2005-09-25 14:42:24 -04:00
if ( rec_enable_button - > get_active ( ) ) {
_session . record_disenable_all ( ) ;
} else {
_session . record_enable_all ( ) ;
}
2006-07-28 23:17:11 -04:00
cmd - > mark ( ) ;
2006-07-28 19:38:30 -04:00
_session . add_command ( cmd ) ;
2005-09-25 14:42:24 -04:00
_session . commit_reversible_command ( ) ;
} else if ( Keyboard : : modifier_state_equals ( ev - > state , Keyboard : : Control ) ) {
2006-08-03 22:18:45 -04:00
set_mix_group_rec_enable ( _route , ! _route - > record_enabled ( ) ) ;
2005-09-25 14:42:24 -04:00
} else {
reversibly_apply_audio_track_boolean ( " rec-enable change " , & AudioTrack : : set_record_enable , ! audio_track ( ) - > record_enabled ( ) , this ) ;
ignore_toggle = true ;
rec_enable_button - > set_active ( audio_track ( ) - > record_enabled ( ) ) ;
ignore_toggle = false ;
}
stop_signal ( * rec_enable_button , " button-press-event " ) ;
}
return TRUE ;
}
void
RouteUI : : solo_changed ( void * src )
{
2005-09-25 17:19:23 -04:00
Gtkmm2ext : : UI : : instance ( ) - > call_slot ( mem_fun ( * this , & RouteUI : : update_solo_display ) ) ;
2005-09-25 14:42:24 -04:00
}
void
RouteUI : : update_solo_display ( )
{
bool x ;
2006-08-03 22:18:45 -04:00
if ( solo_button - > get_active ( ) ! = ( x = _route - > soloed ( ) ) ) {
2005-09-25 14:42:24 -04:00
ignore_toggle = true ;
solo_button - > set_active ( x ) ;
ignore_toggle = false ;
}
/* show solo safe */
2006-08-03 22:18:45 -04:00
if ( _route - > solo_safe ( ) ) {
2005-09-25 14:42:24 -04:00
solo_button - > set_name ( safe_solo_button_name ( ) ) ;
} else {
solo_button - > set_name ( solo_button_name ( ) ) ;
}
}
void
RouteUI : : mute_changed ( void * src )
{
2005-09-25 17:19:23 -04:00
Gtkmm2ext : : UI : : instance ( ) - > call_slot ( mem_fun ( * this , & RouteUI : : update_mute_display ) ) ;
2005-09-25 14:42:24 -04:00
}
void
RouteUI : : update_mute_display ( )
{
bool x ;
2006-08-03 22:18:45 -04:00
if ( mute_button - > get_active ( ) ! = ( x = _route - > muted ( ) ) ) {
2005-09-25 14:42:24 -04:00
ignore_toggle = true ;
mute_button - > set_active ( x ) ;
ignore_toggle = false ;
}
}
void
2006-08-03 22:18:45 -04:00
RouteUI : : route_rec_enable_changed ( )
2005-09-25 14:42:24 -04:00
{
2005-09-25 17:19:23 -04:00
Gtkmm2ext : : UI : : instance ( ) - > call_slot ( mem_fun ( * this , & RouteUI : : update_rec_display ) ) ;
2005-09-25 14:42:24 -04:00
}
void
RouteUI : : session_rec_enable_changed ( )
{
2005-09-25 17:19:23 -04:00
Gtkmm2ext : : UI : : instance ( ) - > call_slot ( mem_fun ( * this , & RouteUI : : update_rec_display ) ) ;
2005-09-25 14:42:24 -04:00
}
void
RouteUI : : update_rec_display ( )
{
2006-08-03 22:18:45 -04:00
bool model = _route - > record_enabled ( ) ;
2005-09-25 14:42:24 -04:00
bool view = rec_enable_button - > get_active ( ) ;
/* first make sure the button's "depressed" visual
is correct .
*/
if ( model ! = view ) {
ignore_toggle = true ;
rec_enable_button - > set_active ( model ) ;
ignore_toggle = false ;
}
/* now make sure its color state is correct */
if ( model ) {
switch ( _session . record_status ( ) ) {
case Session : : Disabled :
case Session : : Enabled :
2005-10-06 14:24:23 -04:00
if ( rec_enable_button - > get_state ( ) ! = Gtk : : STATE_ACTIVE ) {
rec_enable_button - > set_state ( Gtk : : STATE_ACTIVE ) ;
2005-09-25 14:42:24 -04:00
}
break ;
case Session : : Recording :
2005-10-06 14:24:23 -04:00
if ( rec_enable_button - > get_state ( ) ! = Gtk : : STATE_SELECTED ) {
rec_enable_button - > set_state ( Gtk : : STATE_SELECTED ) ;
2005-09-25 14:42:24 -04:00
}
break ;
}
} else {
2005-09-25 16:33:00 -04:00
if ( rec_enable_button - > get_state ( ) ! = Gtk : : STATE_NORMAL ) {
rec_enable_button - > set_state ( Gtk : : STATE_NORMAL ) ;
2005-09-25 14:42:24 -04:00
}
}
}
2006-01-07 21:56:49 -05:00
void
RouteUI : : build_remote_control_menu ( )
{
remote_control_menu = manage ( new Menu ) ;
refresh_remote_control_menu ( ) ;
}
void
RouteUI : : refresh_remote_control_menu ( )
{
using namespace Menu_Helpers ;
RadioMenuItem : : Group rc_group ;
CheckMenuItem * rc_active ;
uint32_t limit = _session . ntracks ( ) ;
char buf [ 32 ] ;
MenuList & rc_items = remote_control_menu - > items ( ) ;
rc_items . clear ( ) ;
/* note that this menu list starts at zero, not 1, because zero
is a valid , if useless , ID .
*/
limit + = 4 ; /* leave some breathing room */
2006-06-22 19:40:55 -04:00
rc_items . push_back ( RadioMenuElem ( rc_group , _ ( " None " ) ) ) ;
2006-08-03 22:18:45 -04:00
if ( _route - > remote_control_id ( ) = = 0 ) {
2006-06-22 19:40:55 -04:00
rc_active = dynamic_cast < CheckMenuItem * > ( & rc_items . back ( ) ) ;
rc_active - > set_active ( ) ;
}
for ( uint32_t i = 1 ; i < limit ; + + i ) {
2006-01-07 21:56:49 -05:00
snprintf ( buf , sizeof ( buf ) , " %u " , i ) ;
rc_items . push_back ( RadioMenuElem ( rc_group , buf ) ) ;
rc_active = dynamic_cast < RadioMenuItem * > ( & rc_items . back ( ) ) ;
2006-08-03 22:18:45 -04:00
if ( _route - > remote_control_id ( ) = = i ) {
2006-01-07 21:56:49 -05:00
rc_active = dynamic_cast < CheckMenuItem * > ( & rc_items . back ( ) ) ;
rc_active - > set_active ( ) ;
}
rc_active - > signal_activate ( ) . connect ( bind ( mem_fun ( * this , & RouteUI : : set_remote_control_id ) , i , rc_active ) ) ;
}
}
void
RouteUI : : set_remote_control_id ( uint32_t id , CheckMenuItem * item )
{
/* this is called when the radio menu item is toggled, and so
is actually invoked twice per menu selection . we only
care about the invocation for the item that was being
marked active .
*/
if ( item - > get_active ( ) ) {
2006-08-03 22:18:45 -04:00
_route - > set_remote_control_id ( id ) ;
2006-01-07 21:56:49 -05:00
}
}
2005-09-25 14:42:24 -04:00
void
RouteUI : : build_solo_menu ( void )
{
using namespace Menu_Helpers ;
solo_menu = new Menu ;
solo_menu - > set_name ( " ArdourContextMenu " ) ;
MenuList & items = solo_menu - > items ( ) ;
CheckMenuItem * check ;
check = new CheckMenuItem ( _ ( " Solo-safe " ) ) ;
2006-08-03 22:18:45 -04:00
check - > set_active ( _route - > solo_safe ( ) ) ;
2005-10-06 14:24:23 -04:00
check - > signal_toggled ( ) . connect ( bind ( mem_fun ( * this , & RouteUI : : toggle_solo_safe ) , check ) ) ;
2006-08-03 22:18:45 -04:00
_route - > solo_safe_changed . connect ( bind ( mem_fun ( * this , & RouteUI : : solo_safe_toggle ) , check ) ) ;
2005-09-25 14:42:24 -04:00
items . push_back ( CheckMenuElem ( * check ) ) ;
check - > show_all ( ) ;
items . push_back ( SeparatorElem ( ) ) ;
2006-08-03 22:18:45 -04:00
// items.push_back (MenuElem (_("MIDI Bind"), mem_fun (*mute_button, &BindableToggleButton::midi_learn)));
2005-09-25 14:42:24 -04:00
}
void
RouteUI : : build_mute_menu ( void )
{
using namespace Menu_Helpers ;
mute_menu = new Menu ;
mute_menu - > set_name ( " ArdourContextMenu " ) ;
MenuList & items = mute_menu - > items ( ) ;
CheckMenuItem * check ;
check = new CheckMenuItem ( _ ( " Pre Fader " ) ) ;
init_mute_menu ( PRE_FADER , check ) ;
2005-10-06 14:24:23 -04:00
check - > signal_toggled ( ) . connect ( bind ( mem_fun ( * this , & RouteUI : : toggle_mute_menu ) , PRE_FADER , check ) ) ;
2006-08-03 22:18:45 -04:00
_route - > pre_fader_changed . connect ( bind ( mem_fun ( * this , & RouteUI : : pre_fader_toggle ) , check ) ) ;
2005-09-25 14:42:24 -04:00
items . push_back ( CheckMenuElem ( * check ) ) ;
check - > show_all ( ) ;
check = new CheckMenuItem ( _ ( " Post Fader " ) ) ;
init_mute_menu ( POST_FADER , check ) ;
2005-10-06 14:24:23 -04:00
check - > signal_toggled ( ) . connect ( bind ( mem_fun ( * this , & RouteUI : : toggle_mute_menu ) , POST_FADER , check ) ) ;
2006-08-03 22:18:45 -04:00
_route - > post_fader_changed . connect ( bind ( mem_fun ( * this , & RouteUI : : post_fader_toggle ) , check ) ) ;
2005-09-25 14:42:24 -04:00
items . push_back ( CheckMenuElem ( * check ) ) ;
check - > show_all ( ) ;
check = new CheckMenuItem ( _ ( " Control Outs " ) ) ;
init_mute_menu ( CONTROL_OUTS , check ) ;
2005-10-06 14:24:23 -04:00
check - > signal_toggled ( ) . connect ( bind ( mem_fun ( * this , & RouteUI : : toggle_mute_menu ) , CONTROL_OUTS , check ) ) ;
2006-08-03 22:18:45 -04:00
_route - > control_outs_changed . connect ( bind ( mem_fun ( * this , & RouteUI : : control_outs_toggle ) , check ) ) ;
2005-09-25 14:42:24 -04:00
items . push_back ( CheckMenuElem ( * check ) ) ;
check - > show_all ( ) ;
check = new CheckMenuItem ( _ ( " Main Outs " ) ) ;
init_mute_menu ( MAIN_OUTS , check ) ;
2005-10-06 14:24:23 -04:00
check - > signal_toggled ( ) . connect ( bind ( mem_fun ( * this , & RouteUI : : toggle_mute_menu ) , MAIN_OUTS , check ) ) ;
2006-08-03 22:18:45 -04:00
_route - > main_outs_changed . connect ( bind ( mem_fun ( * this , & RouteUI : : main_outs_toggle ) , check ) ) ;
2005-09-25 14:42:24 -04:00
items . push_back ( CheckMenuElem ( * check ) ) ;
check - > show_all ( ) ;
items . push_back ( SeparatorElem ( ) ) ;
2006-08-03 22:18:45 -04:00
// items.push_back (MenuElem (_("MIDI Bind"), mem_fun (*mute_button, &BindableToggleButton::midi_learn)));
2005-09-25 14:42:24 -04:00
}
void
RouteUI : : init_mute_menu ( mute_type type , CheckMenuItem * check )
{
2006-08-03 22:18:45 -04:00
if ( _route - > get_mute_config ( type ) ) {
2005-09-25 14:42:24 -04:00
check - > set_active ( true ) ;
}
}
void
RouteUI : : toggle_mute_menu ( mute_type type , Gtk : : CheckMenuItem * check )
{
2006-08-03 22:18:45 -04:00
_route - > set_mute_config ( type , check - > get_active ( ) , this ) ;
2005-09-25 14:42:24 -04:00
}
void
RouteUI : : toggle_solo_safe ( Gtk : : CheckMenuItem * check )
{
2006-08-03 22:18:45 -04:00
_route - > set_solo_safe ( check - > get_active ( ) , this ) ;
2005-09-25 14:42:24 -04:00
}
void
2006-08-03 22:18:45 -04:00
RouteUI : : set_mix_group_solo ( boost : : shared_ptr < Route > route , bool yn )
2005-09-25 14:42:24 -04:00
{
RouteGroup * mix_group ;
2006-08-03 22:18:45 -04:00
if ( ( mix_group = route - > mix_group ( ) ) ! = 0 ) {
2005-09-25 14:42:24 -04:00
_session . begin_reversible_command ( _ ( " mix group solo change " ) ) ;
2006-08-03 17:54:14 -04:00
Session : : GlobalSoloStateCommand * cmd = new Session : : GlobalSoloStateCommand ( _session , this ) ;
2005-09-25 14:42:24 -04:00
mix_group - > apply ( & Route : : set_solo , yn , this ) ;
2006-07-28 23:17:11 -04:00
cmd - > mark ( ) ;
2006-07-28 19:38:30 -04:00
_session . add_command ( cmd ) ;
2005-09-25 14:42:24 -04:00
_session . commit_reversible_command ( ) ;
} else {
2006-08-03 22:18:45 -04:00
reversibly_apply_route_boolean ( " solo change " , & Route : : set_solo , ! route - > soloed ( ) , this ) ;
2005-09-25 14:42:24 -04:00
}
}
void
RouteUI : : reversibly_apply_route_boolean ( string name , void ( Route : : * func ) ( bool , void * ) , bool yn , void * arg )
{
_session . begin_reversible_command ( name ) ;
2006-08-03 23:42:34 -04:00
XMLNode & before = _route - > get_state ( ) ;
bind ( mem_fun ( * _route , func ) , yn , arg ) ( ) ;
XMLNode & after = _route - > get_state ( ) ;
2006-08-12 17:49:20 -04:00
_session . add_command ( new MementoCommand < Route > ( * _route , & before , & after ) ) ;
2005-09-25 14:42:24 -04:00
_session . commit_reversible_command ( ) ;
}
void
RouteUI : : reversibly_apply_audio_track_boolean ( string name , void ( AudioTrack : : * func ) ( bool , void * ) , bool yn , void * arg )
{
_session . begin_reversible_command ( name ) ;
2006-07-26 20:19:12 -04:00
XMLNode & before = audio_track ( ) - > get_state ( ) ;
bind ( mem_fun ( * audio_track ( ) , func ) , yn , arg ) ( ) ;
XMLNode & after = audio_track ( ) - > get_state ( ) ;
2006-08-12 17:49:20 -04:00
_session . add_command ( new MementoCommand < AudioTrack > ( * audio_track ( ) , & before , & after ) ) ;
2005-09-25 14:42:24 -04:00
_session . commit_reversible_command ( ) ;
}
void
2006-08-03 22:18:45 -04:00
RouteUI : : set_mix_group_mute ( boost : : shared_ptr < Route > route , bool yn )
2005-09-25 14:42:24 -04:00
{
RouteGroup * mix_group ;
2006-08-03 22:18:45 -04:00
if ( ( mix_group = route - > mix_group ( ) ) ! = 0 ) {
2005-09-25 14:42:24 -04:00
_session . begin_reversible_command ( _ ( " mix group mute change " ) ) ;
2006-08-03 17:54:14 -04:00
Session : : GlobalMuteStateCommand * cmd = new Session : : GlobalMuteStateCommand ( _session , this ) ;
2005-09-25 14:42:24 -04:00
mix_group - > apply ( & Route : : set_mute , yn , this ) ;
2006-07-28 23:17:11 -04:00
cmd - > mark ( ) ;
2006-07-28 19:38:30 -04:00
_session . add_command ( cmd ) ;
2005-09-25 14:42:24 -04:00
_session . commit_reversible_command ( ) ;
} else {
2006-08-03 22:18:45 -04:00
reversibly_apply_route_boolean ( " mute change " , & Route : : set_mute , ! route - > muted ( ) , this ) ;
2005-09-25 14:42:24 -04:00
}
}
void
2006-08-03 22:18:45 -04:00
RouteUI : : set_mix_group_rec_enable ( boost : : shared_ptr < Route > route , bool yn )
2005-09-25 14:42:24 -04:00
{
RouteGroup * mix_group ;
2006-08-03 22:18:45 -04:00
if ( ( mix_group = route - > mix_group ( ) ) ! = 0 ) {
2005-09-25 14:42:24 -04:00
_session . begin_reversible_command ( _ ( " mix group rec-enable change " ) ) ;
2006-08-03 17:54:14 -04:00
Session : : GlobalRecordEnableStateCommand * cmd = new Session : : GlobalRecordEnableStateCommand ( _session , this ) ;
2005-09-25 14:42:24 -04:00
mix_group - > apply ( & Route : : set_record_enable , yn , this ) ;
2006-07-28 23:17:11 -04:00
cmd - > mark ( ) ;
2006-07-28 19:38:30 -04:00
_session . add_command ( cmd ) ;
2005-09-25 14:42:24 -04:00
_session . commit_reversible_command ( ) ;
} else {
2006-08-03 22:18:45 -04:00
reversibly_apply_route_boolean ( " rec-enable change " , & Route : : set_record_enable , ! _route - > record_enabled ( ) , this ) ;
2005-09-25 14:42:24 -04:00
}
}
bool
RouteUI : : choose_color ( )
{
bool picked ;
2005-10-06 14:24:23 -04:00
Gdk : : Color color ;
2005-09-25 14:42:24 -04:00
2005-12-18 07:02:42 -05:00
color = Gtkmm2ext : : UI : : instance ( ) - > get_color ( _ ( " ardour: color selection " ) , picked , & _color ) ;
2005-09-25 14:42:24 -04:00
if ( picked ) {
set_color ( color ) ;
}
return picked ;
}
void
2005-12-18 07:02:42 -05:00
RouteUI : : set_color ( const Gdk : : Color & c )
2005-09-25 14:42:24 -04:00
{
char buf [ 64 ] ;
_color = c ;
ensure_xml_node ( ) ;
2005-10-06 14:24:23 -04:00
snprintf ( buf , sizeof ( buf ) , " %d:%d:%d " , c . get_red ( ) , c . get_green ( ) , c . get_blue ( ) ) ;
2005-09-25 14:42:24 -04:00
xml_node - > add_property ( " color " , buf ) ;
2006-08-03 22:18:45 -04:00
_route - > gui_changed ( " color " , ( void * ) 0 ) ; /* EMIT_SIGNAL */
2005-09-25 14:42:24 -04:00
}
void
RouteUI : : ensure_xml_node ( )
{
if ( xml_node = = 0 ) {
2006-08-03 22:18:45 -04:00
if ( ( xml_node = _route - > extra_xml ( " GUI " ) ) = = 0 ) {
2005-09-25 14:42:24 -04:00
xml_node = new XMLNode ( " GUI " ) ;
2006-08-03 22:18:45 -04:00
_route - > add_extra_xml ( * xml_node ) ;
2005-09-25 14:42:24 -04:00
}
}
}
XMLNode *
2005-12-22 07:23:54 -05:00
RouteUI : : get_child_xml_node ( const string & childname )
2005-09-25 14:42:24 -04:00
{
XMLNode * child ;
ensure_xml_node ( ) ;
if ( ( child = find_named_node ( * xml_node , childname ) ) = = 0 ) {
child = new XMLNode ( childname ) ;
xml_node - > add_child_nocopy ( * child ) ;
}
return child ;
}
int
RouteUI : : set_color_from_route ( )
{
XMLProperty * prop ;
RouteUI : : ensure_xml_node ( ) ;
if ( ( prop = xml_node - > property ( " color " ) ) ! = 0 ) {
int r , g , b ;
sscanf ( prop - > value ( ) . c_str ( ) , " %d:%d:%d " , & r , & g , & b ) ;
2005-10-06 14:24:23 -04:00
_color . set_red ( r ) ;
_color . set_green ( g ) ;
_color . set_blue ( b ) ;
2005-09-25 14:42:24 -04:00
return 0 ;
}
return 1 ;
}
void
RouteUI : : remove_this_route ( )
{
vector < string > choices ;
string prompt ;
2006-08-03 22:18:45 -04:00
if ( is_track ( ) ) {
prompt = string_compose ( _ ( " Do you really want to remove track \" %1 \" ? \n \n You may also lose the playlist used by this track. \n (cannot be undone) " ) , _route - > name ( ) ) ;
2005-09-25 14:42:24 -04:00
} else {
2006-08-03 22:18:45 -04:00
prompt = string_compose ( _ ( " Do you really want to remove bus \" %1 \" ? \n (cannot be undone) " ) , _route - > name ( ) ) ;
2005-09-25 14:42:24 -04:00
}
choices . push_back ( _ ( " No, do nothing. " ) ) ;
2006-04-20 07:41:45 -04:00
choices . push_back ( _ ( " Yes, remove it. " ) ) ;
2005-09-25 14:42:24 -04:00
Choice prompter ( prompt , choices ) ;
2006-04-20 07:41:45 -04:00
if ( prompter . run ( ) = = 1 ) {
2006-03-22 12:03:00 -05:00
Glib : : signal_idle ( ) . connect ( bind ( sigc : : ptr_fun ( & RouteUI : : idle_remove_this_route ) , this ) ) ;
2005-09-25 14:42:24 -04:00
}
}
gint
RouteUI : : idle_remove_this_route ( RouteUI * rui )
{
rui - > _session . remove_route ( rui - > _route ) ;
return FALSE ;
}
void
RouteUI : : route_rename ( )
{
ArdourPrompter name_prompter ( true ) ;
2005-10-26 21:10:36 -04:00
string result ;
2006-04-22 11:28:59 -04:00
name_prompter . set_prompt ( _ ( " New Name: " ) ) ;
2006-08-03 22:18:45 -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 ( ) ;
2005-10-26 21:10:36 -04:00
switch ( name_prompter . run ( ) ) {
2005-09-25 14:42:24 -04:00
2006-01-13 14:48:55 -05:00
case Gtk : : RESPONSE_ACCEPT :
name_prompter . get_result ( result ) ;
if ( result . length ( ) ) {
2006-08-03 22:18:45 -04:00
_route - > set_name ( result , this ) ;
2005-10-26 21:10:36 -04:00
}
break ;
2005-09-25 14:42:24 -04:00
}
2005-10-26 21:10:36 -04:00
return ;
2005-09-25 14:42:24 -04:00
}
void
RouteUI : : name_changed ( void * src )
{
2005-09-25 17:19:23 -04:00
ENSURE_GUI_THREAD ( bind ( mem_fun ( * this , & RouteUI : : name_changed ) , src ) ) ;
2006-05-17 08:07:16 -04:00
2006-08-03 22:18:45 -04:00
name_label . set_text ( _route - > name ( ) ) ;
2005-09-25 14:42:24 -04:00
}
void
RouteUI : : toggle_route_active ( )
{
bool yn ;
if ( route_active_menu_item ) {
2006-08-03 22:18:45 -04:00
if ( route_active_menu_item - > get_active ( ) ! = ( yn = _route - > active ( ) ) ) {
_route - > set_active ( ! yn ) ;
2005-09-25 14:42:24 -04:00
}
}
}
void
RouteUI : : route_active_changed ( )
{
if ( route_active_menu_item ) {
2006-08-03 22:18:45 -04:00
Gtkmm2ext : : UI : : instance ( ) - > call_slot ( bind ( mem_fun ( * route_active_menu_item , & CheckMenuItem : : set_active ) , _route - > active ( ) ) ) ;
2005-09-25 14:42:24 -04:00
}
}
2006-03-30 10:50:08 -05:00
void
RouteUI : : toggle_polarity ( )
{
if ( polarity_menu_item ) {
bool x ;
ENSURE_GUI_THREAD ( mem_fun ( * this , & RouteUI : : toggle_polarity ) ) ;
2006-08-03 22:18:45 -04:00
if ( ( x = polarity_menu_item - > get_active ( ) ) ! = _route - > phase_invert ( ) ) {
_route - > set_phase_invert ( x , this ) ;
2006-05-17 08:07:16 -04:00
if ( x ) {
name_label . set_text ( X_ ( " Ø " ) + name_label . get_text ( ) ) ;
} else {
2006-08-03 22:18:45 -04:00
name_label . set_text ( _route - > name ( ) ) ;
2006-05-17 08:07:16 -04:00
}
2006-03-30 10:50:08 -05:00
}
}
}
void
RouteUI : : polarity_changed ( )
{
/* no signal for this yet */
}
2005-09-25 14:42:24 -04:00
void
RouteUI : : solo_safe_toggle ( void * src , Gtk : : CheckMenuItem * check )
{
2006-08-03 22:18:45 -04:00
bool yn = _route - > solo_safe ( ) ;
2005-09-25 14:42:24 -04:00
if ( check - > get_active ( ) ! = yn ) {
check - > set_active ( yn ) ;
}
}
void
RouteUI : : pre_fader_toggle ( void * src , Gtk : : CheckMenuItem * check )
{
2005-09-25 17:19:23 -04:00
ENSURE_GUI_THREAD ( bind ( mem_fun ( * this , & RouteUI : : pre_fader_toggle ) , src , check ) ) ;
2005-09-25 14:42:24 -04:00
2006-08-03 22:18:45 -04:00
bool yn = _route - > get_mute_config ( PRE_FADER ) ;
2005-09-25 14:42:24 -04:00
if ( check - > get_active ( ) ! = yn ) {
check - > set_active ( yn ) ;
}
}
void
RouteUI : : post_fader_toggle ( void * src , Gtk : : CheckMenuItem * check )
{
2005-09-25 17:19:23 -04:00
ENSURE_GUI_THREAD ( bind ( mem_fun ( * this , & RouteUI : : post_fader_toggle ) , src , check ) ) ;
2005-09-25 14:42:24 -04:00
2006-08-03 22:18:45 -04:00
bool yn = _route - > get_mute_config ( POST_FADER ) ;
2005-09-25 14:42:24 -04:00
if ( check - > get_active ( ) ! = yn ) {
check - > set_active ( yn ) ;
}
}
void
RouteUI : : control_outs_toggle ( void * src , Gtk : : CheckMenuItem * check )
{
2005-09-25 17:19:23 -04:00
ENSURE_GUI_THREAD ( bind ( mem_fun ( * this , & RouteUI : : control_outs_toggle ) , src , check ) ) ;
2005-09-25 14:42:24 -04:00
2006-08-03 22:18:45 -04:00
bool yn = _route - > get_mute_config ( CONTROL_OUTS ) ;
2005-09-25 14:42:24 -04:00
if ( check - > get_active ( ) ! = yn ) {
check - > set_active ( yn ) ;
}
}
void
RouteUI : : main_outs_toggle ( void * src , Gtk : : CheckMenuItem * check )
{
2005-09-25 17:19:23 -04:00
ENSURE_GUI_THREAD ( bind ( mem_fun ( * this , & RouteUI : : main_outs_toggle ) , src , check ) ) ;
2005-09-25 14:42:24 -04:00
2006-08-03 22:18:45 -04:00
bool yn = _route - > get_mute_config ( MAIN_OUTS ) ;
2005-09-25 14:42:24 -04:00
if ( check - > get_active ( ) ! = yn ) {
check - > set_active ( yn ) ;
}
}
void
RouteUI : : disconnect_input ( )
{
2006-08-03 22:18:45 -04:00
_route - > disconnect_inputs ( this ) ;
2005-09-25 14:42:24 -04:00
}
void
RouteUI : : disconnect_output ( )
{
2006-08-03 22:18:45 -04:00
_route - > disconnect_outputs ( this ) ;
}
bool
RouteUI : : is_track ( ) const
{
return dynamic_cast < Track * > ( _route . get ( ) ) ! = 0 ;
}
Track *
RouteUI : : track ( ) const
{
return dynamic_cast < Track * > ( _route . get ( ) ) ;
2005-09-25 14:42:24 -04:00
}
bool
RouteUI : : is_audio_track ( ) const
{
2006-08-03 22:18:45 -04:00
return dynamic_cast < AudioTrack * > ( _route . get ( ) ) ! = 0 ;
}
AudioTrack *
RouteUI : : audio_track ( ) const
{
return dynamic_cast < AudioTrack * > ( _route . get ( ) ) ;
2005-09-25 14:42:24 -04:00
}
2006-08-15 21:19:06 -04:00
boost : : shared_ptr < Diskstream >
2005-09-25 14:42:24 -04:00
RouteUI : : get_diskstream ( ) const
{
2006-08-03 22:18:45 -04:00
boost : : shared_ptr < Track > t ;
2005-09-25 14:42:24 -04:00
2006-08-03 22:18:45 -04:00
if ( ( t = boost : : dynamic_pointer_cast < Track > ( _route ) ) ! = 0 ) {
2006-08-15 21:19:06 -04:00
return t - > diskstream ( ) ;
2005-09-25 14:42:24 -04:00
} else {
2006-08-15 21:19:06 -04:00
return boost : : shared_ptr < Diskstream > ( ( Diskstream * ) 0 ) ;
2005-09-25 14:42:24 -04:00
}
}
string
RouteUI : : name ( ) const
{
2006-08-03 22:18:45 -04:00
return _route - > name ( ) ;
2005-09-25 14:42:24 -04:00
}
void
RouteUI : : map_frozen ( )
{
2005-09-25 17:19:23 -04:00
ENSURE_GUI_THREAD ( mem_fun ( * this , & RouteUI : : map_frozen ) ) ;
2005-09-25 14:42:24 -04:00
2006-08-03 22:18:45 -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-08-03 22:18:45 -04:00