2005-09-25 14:42:24 -04:00
/*
2019-08-02 17:26:43 -04:00
* Copyright ( C ) 2005 - 2006 Taybin Rutkin < taybin @ taybin . com >
* Copyright ( C ) 2005 - 2018 Paul Davis < paul @ linuxaudiosystems . com >
* Copyright ( C ) 2006 - 2007 Doug McLain < doug @ nostar . net >
* Copyright ( C ) 2007 - 2012 Carl Hetherington < carl @ carlh . net >
* Copyright ( C ) 2007 - 2012 David Robillard < d @ drobilla . net >
* Copyright ( C ) 2007 - 2016 Tim Mayberry < mojofunk @ gmail . com >
* Copyright ( C ) 2013 - 2015 Nick Mainsbridge < mainsbridge @ gmail . com >
* Copyright ( C ) 2013 - 2019 Robin Gareus < robin @ gareus . org >
* Copyright ( C ) 2014 - 2018 Ben Loftis < ben @ harrisonconsoles . com >
* Copyright ( C ) 2016 - 2018 Len Ovens < len @ ovenwerks . net >
*
* 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 . ,
* 51 Franklin Street , Fifth Floor , Boston , MA 02110 - 1301 USA .
*/
2005-09-25 14:42:24 -04:00
2010-11-13 00:14:48 -05:00
# ifdef WAF_BUILD
# include "gtk2ardour-config.h"
# endif
2005-09-25 14:42:24 -04:00
# include <algorithm>
2009-10-22 20:05:50 -04:00
# include <map>
2005-09-25 14:42:24 -04:00
# include <sigc++/bind.h>
2016-07-06 15:20:42 -04:00
# include <boost/foreach.hpp>
2017-07-16 21:48:18 -04:00
# include <glibmm/threads.h>
2005-11-29 17:48:54 -05:00
# include <gtkmm/accelmap.h>
2022-06-01 09:48:44 -04:00
# include <gtkmm/menu.h>
2019-07-17 16:57:30 -04:00
# include <gtkmm/offscreenwindow.h>
2017-07-16 21:48:18 -04:00
# include <gtkmm/stock.h>
2005-11-29 17:48:54 -05:00
2009-02-25 13:26:51 -05:00
# include "pbd/convert.h"
2012-06-27 18:57:06 -04:00
# include "pbd/unwind.h"
2022-06-01 09:48:44 -04:00
# include "context_menu_helper.h"
2015-12-27 09:32:24 -05:00
# include "ardour/amp.h"
2012-06-27 18:57:06 -04:00
# include "ardour/debug.h"
2020-04-02 13:55:33 -04:00
# include "ardour/audio_port.h"
2016-05-16 07:30:28 -04:00
# include "ardour/audio_track.h"
2012-11-12 21:19:04 -05:00
# include "ardour/midi_track.h"
2022-05-23 10:08:30 -04:00
# include "ardour/mixer_scene.h"
2019-11-20 11:37:14 -05:00
# include "ardour/monitor_control.h"
2020-04-02 13:55:33 -04:00
# include "ardour/panner_shell.h"
2009-02-25 13:26:51 -05:00
# include "ardour/plugin_manager.h"
2024-03-20 08:49:18 -04:00
# include "ardour/profile.h"
2009-02-25 13:26:51 -05:00
# include "ardour/route_group.h"
2017-05-05 07:31:49 -04:00
# include "ardour/selection.h"
2009-02-25 13:26:51 -05:00
# include "ardour/session.h"
2016-02-27 22:16:37 -05:00
# include "ardour/vca.h"
# include "ardour/vca_manager.h"
2005-09-25 14:42:24 -04:00
2017-07-16 22:55:52 -04:00
# include "gtkmm2ext/gtk_ui.h"
# include "gtkmm2ext/keyboard.h"
# include "gtkmm2ext/utils.h"
# include "gtkmm2ext/window_title.h"
# include "gtkmm2ext/doi.h"
2022-06-01 09:48:44 -04:00
# include "widgets/prompter.h"
2017-07-16 22:55:52 -04:00
# include "widgets/tearoff.h"
2022-06-01 09:48:44 -04:00
# include "widgets/tooltips.h"
2017-07-16 22:55:52 -04:00
2019-01-18 13:22:54 -05:00
# include "foldback_strip.h"
2007-04-11 09:07:51 -04:00
# include "keyboard.h"
2005-09-25 14:42:24 -04:00
# include "mixer_ui.h"
# include "mixer_strip.h"
2010-03-10 12:31:16 -05:00
# include "monitor_section.h"
2023-11-10 12:56:03 -05:00
# include "opts.h"
2005-09-25 14:42:24 -04:00
# include "plugin_selector.h"
2011-11-15 14:33:09 -05:00
# include "public_editor.h"
2016-05-28 10:33:48 -04:00
# include "mouse_cursors.h"
2005-09-25 14:42:24 -04:00
# include "ardour_ui.h"
# include "utils.h"
2012-10-26 20:15:45 -04:00
# include "route_sorter.h"
2005-11-29 17:48:54 -05:00
# include "actions.h"
2005-09-25 14:42:24 -04:00
# include "gui_thread.h"
2022-05-24 09:18:07 -04:00
# include "ardour_message.h"
2009-06-20 13:15:33 -04:00
# include "mixer_group_tabs.h"
2020-06-25 14:46:01 -04:00
# include "plugin_utils.h"
2016-06-06 12:52:48 -04:00
# include "route_sorter.h"
2024-01-02 08:26:56 -05:00
# include "surround_strip.h"
2014-12-25 10:02:00 -05:00
# include "timers.h"
2015-01-02 09:44:54 -05:00
# include "ui_config.h"
2016-02-27 22:16:37 -05:00
# include "vca_master_strip.h"
2005-09-25 14:42:24 -04:00
2016-07-14 14:44:52 -04:00
# include "pbd/i18n.h"
2005-09-25 14:42:24 -04:00
2021-03-26 07:46:42 -04:00
# define PX_SCALE(px) std::max ((float)px, rintf ((float)px* UIConfiguration::instance ().get_ui_scale ()))
2005-09-25 14:42:24 -04:00
using namespace ARDOUR ;
2022-06-01 09:48:44 -04:00
using namespace ArdourWidgets ;
2014-06-25 15:27:37 -04:00
using namespace ARDOUR_UI_UTILS ;
2020-06-25 14:46:01 -04:00
using namespace ARDOUR_PLUGIN_UTILS ;
2006-06-21 19:01:03 -04:00
using namespace PBD ;
2005-09-25 14:42:24 -04:00
using namespace Gtk ;
2005-11-29 17:48:54 -05:00
using namespace Glib ;
2005-09-25 16:33:00 -04:00
using namespace Gtkmm2ext ;
2006-01-17 11:40:57 -05:00
using namespace std ;
2005-09-25 14:42:24 -04:00
2006-04-25 16:23:50 -04:00
using PBD : : atoi ;
2012-06-27 18:57:06 -04:00
using PBD : : Unwinder ;
2006-04-25 16:23:50 -04:00
2024-02-26 07:46:09 -05:00
static const gchar * _plugin_list_mode_strings [ ] = {
N_ ( " Favorite Plugins " ) ,
N_ ( " Recent Plugins " ) ,
N_ ( " Top-10 Plugins " ) ,
0
} ;
2011-11-15 14:33:09 -05:00
Mixer_UI * Mixer_UI : : _instance = 0 ;
Mixer_UI *
2015-10-04 14:51:05 -04:00
Mixer_UI : : instance ( )
2011-11-15 14:33:09 -05:00
{
if ( ! _instance ) {
_instance = new Mixer_UI ;
2015-10-04 14:51:05 -04:00
}
2011-11-15 14:33:09 -05:00
return _instance ;
}
2007-04-11 09:07:51 -04:00
Mixer_UI : : Mixer_UI ( )
2020-05-01 16:28:05 -04:00
: Tabbable ( _content , _ ( " Mixer " ) , X_ ( " mixer " ) )
2024-02-26 07:46:09 -05:00
, plugin_search_clear_button ( X_ ( " Clear " ) )
2022-11-10 14:52:50 -05:00
, _mixer_scene_release ( 0 )
2012-06-27 18:57:06 -04:00
, no_track_list_redisplay ( false )
, in_group_row_change ( false )
, track_menu ( 0 )
2024-03-26 12:12:18 -04:00
, _plugin_selector ( nullptr )
2024-01-02 08:26:56 -05:00
, _surround_strip ( 0 )
2019-01-18 13:22:54 -05:00
, foldback_strip ( 0 )
2019-09-11 19:36:05 -04:00
, _show_foldback_strip ( true )
2015-01-02 09:44:54 -05:00
, _strip_width ( UIConfiguration : : instance ( ) . get_default_narrow_ms ( ) ? Narrow : Wide )
2018-09-01 15:32:57 -04:00
, _spill_scroll_position ( 0 )
2020-06-24 20:26:01 -04:00
, ignore_track_reorder ( false )
2020-06-24 23:52:38 -04:00
, ignore_plugin_refill ( false )
, ignore_plugin_reorder ( false )
2017-07-01 12:42:24 -04:00
, _in_group_rebuild_or_clear ( false )
, _route_deletion_in_progress ( false )
2014-06-20 21:51:59 -04:00
, _maximised ( false )
2017-10-21 11:27:03 -04:00
, _strip_selection_change_without_scroll ( false )
2017-05-05 07:31:49 -04:00
, _selection ( * this , * this )
2005-09-25 14:42:24 -04:00
{
2024-02-26 07:46:09 -05:00
plugin_list_mode_strings = I18N ( _plugin_list_mode_strings ) ;
2016-07-06 15:20:42 -04:00
load_bindings ( ) ;
2018-12-11 05:06:26 -05:00
register_actions ( ) ;
2019-09-13 11:18:35 -04:00
Glib : : RefPtr < ToggleAction > fb_act = ActionManager : : get_toggle_action ( " Mixer " , " ToggleFoldbackStrip " ) ;
fb_act - > set_sensitive ( false ) ;
2015-08-10 14:31:59 -04:00
_content . set_data ( " ardour-bindings " , bindings ) ;
2015-10-26 14:35:06 -04:00
2017-01-27 13:18:33 -05:00
PresentationInfo : : Change . connect ( * this , invalidator ( * this ) , boost : : bind ( & Mixer_UI : : presentation_info_changed , this , _1 ) , gui_context ( ) ) ;
2020-04-02 13:55:33 -04:00
Route : : FanOut . connect ( * this , invalidator ( * this ) , boost : : bind ( & Mixer_UI : : fan_out , this , _1 , false , true ) , gui_context ( ) ) ;
2016-07-06 15:20:42 -04:00
2012-12-09 21:03:45 -05:00
scroller . set_can_default ( true ) ;
2015-04-21 15:10:49 -04:00
// set_default (scroller);
2012-12-09 21:03:45 -05:00
2022-01-26 16:29:36 -05:00
scroller_base . set_can_focus ( ) ;
2009-10-22 13:17:34 -04:00
scroller_base . add_events ( Gdk : : BUTTON_PRESS_MASK | Gdk : : BUTTON_RELEASE_MASK ) ;
scroller_base . set_name ( " MixerWindow " ) ;
2021-03-28 14:36:37 -04:00
scroller_base . signal_button_press_event ( ) . connect ( sigc : : mem_fun ( * this , & Mixer_UI : : strip_scroller_button_event ) ) ;
scroller_base . signal_button_release_event ( ) . connect ( sigc : : mem_fun ( * this , & Mixer_UI : : strip_scroller_button_event ) ) ;
2024-03-25 20:36:11 -04:00
scroller_base . signal_enter_notify_event ( ) . connect ( sigc : : mem_fun ( * this , & Mixer_UI : : scroller_enter ) , false ) ;
2016-05-06 10:04:05 -04:00
/* set up drag-n-drop */
vector < TargetEntry > target_table ;
2022-01-10 15:29:29 -05:00
target_table . push_back ( TargetEntry ( " x-ardour/plugin.favorite " , Gtk : : TARGET_SAME_APP ) ) ;
2016-05-06 10:04:05 -04:00
scroller_base . drag_dest_set ( target_table ) ;
scroller_base . signal_drag_data_received ( ) . connect ( sigc : : mem_fun ( * this , & Mixer_UI : : scroller_drag_data_received ) ) ;
2018-02-13 05:18:03 -05:00
/* add as last item of strip packer */
2005-09-25 14:42:24 -04:00
strip_packer . pack_end ( scroller_base , true , true ) ;
2021-03-26 07:46:42 -04:00
scroller_base . set_size_request ( PX_SCALE ( 20 ) , - 1 ) ;
2022-01-28 17:38:08 -05:00
scroller_base . signal_expose_event ( ) . connect ( sigc : : bind ( sigc : : ptr_fun ( & ArdourWidgets : : ArdourIcon : : expose_with_text ) , & scroller_base , ArdourWidgets : : ArdourIcon : : ShadedPlusSign ,
_ ( " Right-click or Double-click here \n to add Track, Bus, or VCA channels " ) ) ) ;
2005-09-25 14:42:24 -04:00
2018-08-09 11:10:22 -04:00
# ifdef MIXBUS
/* create a drop-shadow at the end of the mixer strips */
mb_shadow . set_size_request ( 4 , - 1 ) ;
mb_shadow . set_name ( " EditorWindow " ) ;
mb_shadow . show ( ) ;
strip_packer . pack_end ( mb_shadow , false , false ) ;
# endif
2009-06-20 13:15:33 -04:00
_group_tabs = new MixerGroupTabs ( this ) ;
2019-07-17 16:21:08 -04:00
strip_group_box . set_spacing ( 0 ) ;
strip_group_box . set_border_width ( 0 ) ;
strip_group_box . pack_start ( * _group_tabs , PACK_SHRINK ) ;
strip_group_box . pack_start ( strip_packer ) ;
strip_group_box . show_all ( ) ;
strip_group_box . signal_scroll_event ( ) . connect ( sigc : : mem_fun ( * this , & Mixer_UI : : on_scroll_event ) , false ) ;
scroller . add ( strip_group_box ) ;
2024-05-06 17:51:32 -04:00
scroller . set_policy ( Gtk : : POLICY_ALWAYS , Gtk : : POLICY_AUTOMATIC ) ;
2024-05-13 14:00:49 -04:00
Gtk : : Viewport * vp = dynamic_cast < Gtk : : Viewport * > ( scroller . get_child ( ) ) ;
vp - > set_shadow_type ( Gtk : : SHADOW_NONE ) ;
2005-09-25 14:42:24 -04:00
2011-01-09 14:09:49 -05:00
setup_track_display ( ) ;
2005-09-25 14:42:24 -04:00
2006-03-09 18:44:39 -05:00
group_model = ListStore : : create ( group_columns ) ;
group_display . set_model ( group_model ) ;
2006-11-27 14:31:33 -05:00
group_display . append_column ( _ ( " Show " ) , group_columns . visible ) ;
2016-06-29 11:26:51 -04:00
group_display . append_column ( _ ( " Group " ) , group_columns . text ) ;
2005-10-01 12:29:37 -04:00
group_display . get_column ( 0 ) - > set_data ( X_ ( " colnum " ) , GUINT_TO_POINTER ( 0 ) ) ;
group_display . get_column ( 1 ) - > set_data ( X_ ( " colnum " ) , GUINT_TO_POINTER ( 1 ) ) ;
2016-06-29 11:26:51 -04:00
group_display . get_column ( 0 ) - > set_expand ( false ) ;
group_display . get_column ( 1 ) - > set_expand ( true ) ;
group_display . get_column ( 1 ) - > set_sizing ( Gtk : : TREE_VIEW_COLUMN_FIXED ) ;
2012-12-07 17:38:49 -05:00
group_display . set_name ( " EditGroupList " ) ;
2006-03-09 18:44:39 -05:00
group_display . get_selection ( ) - > set_mode ( Gtk : : SELECTION_SINGLE ) ;
2006-02-14 14:12:35 -05:00
group_display . set_reorderable ( true ) ;
group_display . set_headers_visible ( true ) ;
2006-03-09 18:44:39 -05:00
group_display . set_rules_hint ( true ) ;
2015-09-15 15:21:01 -04:00
group_display . set_can_focus ( false ) ;
2006-03-09 18:44:39 -05:00
/* name is directly editable */
2016-06-29 11:26:51 -04:00
CellRendererText * name_cell = dynamic_cast < CellRendererText * > ( group_display . get_column_cell_renderer ( 1 ) ) ;
2006-03-09 18:44:39 -05:00
name_cell - > property_editable ( ) = true ;
2009-12-11 18:29:48 -05:00
name_cell - > signal_edited ( ) . connect ( sigc : : mem_fun ( * this , & Mixer_UI : : route_group_name_edit ) ) ;
2005-10-01 12:29:37 -04:00
/* use checkbox for the active column */
2016-06-29 11:26:51 -04:00
CellRendererToggle * active_cell = dynamic_cast < CellRendererToggle * > ( group_display . get_column_cell_renderer ( 0 ) ) ;
2005-10-01 12:29:37 -04:00
active_cell - > property_activatable ( ) = true ;
active_cell - > property_radio ( ) = false ;
2006-02-14 14:12:35 -05:00
2009-12-11 18:29:48 -05:00
group_model - > signal_row_changed ( ) . connect ( sigc : : mem_fun ( * this , & Mixer_UI : : route_group_row_change ) ) ;
2011-04-19 11:46:47 -04:00
/* We use this to notice drag-and-drop reorders of the group list */
group_model - > signal_row_deleted ( ) . connect ( sigc : : mem_fun ( * this , & Mixer_UI : : route_group_row_deleted ) ) ;
2009-12-11 18:29:48 -05:00
group_display . signal_button_press_event ( ) . connect ( sigc : : mem_fun ( * this , & Mixer_UI : : group_display_button_press ) , false ) ;
2006-02-14 14:12:35 -05:00
2005-10-01 12:29:37 -04:00
group_display_scroller . add ( group_display ) ;
2005-09-28 12:22:43 -04:00
group_display_scroller . set_policy ( Gtk : : POLICY_NEVER , Gtk : : POLICY_AUTOMATIC ) ;
2006-02-14 14:12:35 -05:00
2005-10-01 12:29:37 -04:00
group_display_vbox . pack_start ( group_display_scroller , true , true ) ;
2005-09-25 14:42:24 -04:00
2017-09-18 14:45:56 -04:00
group_display_frame . set_name ( " BaseFrame " ) ;
group_display_frame . set_shadow_type ( Gtk : : SHADOW_IN ) ;
group_display_frame . add ( group_display_vbox ) ;
2005-09-25 14:42:24 -04:00
2016-05-06 08:55:36 -04:00
list < TargetEntry > target_list ;
2022-01-10 15:29:29 -05:00
target_list . push_back ( TargetEntry ( " x-ardour/plugin.preset " , Gtk : : TARGET_SAME_APP ) ) ;
2016-05-06 08:55:36 -04:00
2015-12-25 10:10:09 -05:00
favorite_plugins_model = PluginTreeStore : : create ( favorite_plugins_columns ) ;
2015-12-21 22:43:26 -05:00
favorite_plugins_display . set_model ( favorite_plugins_model ) ;
favorite_plugins_display . append_column ( _ ( " Favorite Plugins " ) , favorite_plugins_columns . name ) ;
favorite_plugins_display . set_name ( " EditGroupList " ) ;
2015-12-26 18:37:53 -05:00
favorite_plugins_display . get_selection ( ) - > set_mode ( Gtk : : SELECTION_SINGLE ) ;
favorite_plugins_display . set_reorderable ( false ) ;
2020-06-24 23:52:38 -04:00
favorite_plugins_display . set_headers_visible ( false ) ;
2015-12-21 22:43:26 -05:00
favorite_plugins_display . set_rules_hint ( true ) ;
favorite_plugins_display . set_can_focus ( false ) ;
2022-01-10 15:29:29 -05:00
favorite_plugins_display . add_object_drag ( favorite_plugins_columns . plugin . index ( ) , " x-ardour/plugin.favorite " , Gtk : : TARGET_SAME_APP ) ;
2015-12-24 11:28:23 -05:00
favorite_plugins_display . set_drag_column ( favorite_plugins_columns . name . index ( ) ) ;
2016-05-06 08:55:36 -04:00
favorite_plugins_display . add_drop_targets ( target_list ) ;
2015-12-25 11:11:47 -05:00
favorite_plugins_display . signal_row_activated ( ) . connect ( sigc : : mem_fun ( * this , & Mixer_UI : : plugin_row_activated ) ) ;
2015-12-26 18:37:53 -05:00
favorite_plugins_display . signal_button_press_event ( ) . connect ( sigc : : mem_fun ( * this , & Mixer_UI : : plugin_row_button_press ) , false ) ;
2015-12-27 22:11:45 -05:00
favorite_plugins_display . signal_drop . connect ( sigc : : mem_fun ( * this , & Mixer_UI : : plugin_drop ) ) ;
2020-06-24 23:52:38 -04:00
favorite_plugins_display . signal_motion . connect ( sigc : : mem_fun ( * this , & Mixer_UI : : plugin_drag_motion ) ) ;
2016-01-09 18:00:07 -05:00
favorite_plugins_display . signal_row_expanded ( ) . connect ( sigc : : mem_fun ( * this , & Mixer_UI : : save_favorite_ui_state ) ) ;
favorite_plugins_display . signal_row_collapsed ( ) . connect ( sigc : : mem_fun ( * this , & Mixer_UI : : save_favorite_ui_state ) ) ;
2018-11-01 18:20:50 -04:00
if ( UIConfiguration : : instance ( ) . get_use_tooltips ( ) ) {
favorite_plugins_display . set_tooltip_column ( 0 ) ;
}
2016-01-09 18:00:07 -05:00
favorite_plugins_model - > signal_row_has_child_toggled ( ) . connect ( sigc : : mem_fun ( * this , & Mixer_UI : : sync_treeview_favorite_ui_state ) ) ;
2020-06-24 23:52:38 -04:00
favorite_plugins_model - > signal_row_deleted ( ) . connect ( sigc : : mem_fun ( * this , & Mixer_UI : : favorite_plugins_deleted ) ) ;
2024-02-26 07:46:09 -05:00
favorite_plugins_mode_combo . AddMenuElem ( Menu_Helpers : : MenuElem ( _ ( " Favorite Plugins " ) , sigc : : bind ( sigc : : mem_fun ( * this , & Mixer_UI : : set_plugin_list_mode ) , PLM_Favorite ) ) ) ;
favorite_plugins_mode_combo . AddMenuElem ( Menu_Helpers : : MenuElem ( _ ( " Recent Plugins " ) , sigc : : bind ( sigc : : mem_fun ( * this , & Mixer_UI : : set_plugin_list_mode ) , PLM_Recent ) ) ) ;
favorite_plugins_mode_combo . AddMenuElem ( Menu_Helpers : : MenuElem ( _ ( " Top-10 Plugins " ) , sigc : : bind ( sigc : : mem_fun ( * this , & Mixer_UI : : set_plugin_list_mode ) , PLM_TopHits ) ) ) ;
favorite_plugins_mode_combo . set_size_request ( - 1 , 24 ) ;
set_plugin_list_mode ( PLM_Favorite ) ;
2020-06-24 23:52:38 -04:00
plugin_search_entry . signal_changed ( ) . connect ( sigc : : mem_fun ( * this , & Mixer_UI : : plugin_search_entry_changed ) ) ;
2024-02-26 07:46:09 -05:00
plugin_search_clear_button . signal_clicked . connect ( sigc : : mem_fun ( * this , & Mixer_UI : : plugin_search_clear_button_clicked ) ) ;
2015-12-21 22:43:26 -05:00
favorite_plugins_scroller . add ( favorite_plugins_display ) ;
favorite_plugins_scroller . set_policy ( Gtk : : POLICY_NEVER , Gtk : : POLICY_AUTOMATIC ) ;
2020-06-24 23:52:38 -04:00
favorite_plugins_search_hbox . pack_start ( plugin_search_entry , true , true ) ;
2020-06-25 00:41:27 -04:00
favorite_plugins_search_hbox . pack_start ( plugin_search_clear_button , false , false ) ;
2020-06-24 23:52:38 -04:00
2017-09-18 14:45:56 -04:00
favorite_plugins_frame . set_name ( " BaseFrame " ) ;
favorite_plugins_frame . set_shadow_type ( Gtk : : SHADOW_IN ) ;
2018-01-29 18:45:42 -05:00
favorite_plugins_frame . add ( favorite_plugins_vbox ) ;
2020-06-24 23:52:38 -04:00
favorite_plugins_vbox . pack_start ( favorite_plugins_mode_combo , false , false ) ;
2018-01-29 18:45:42 -05:00
favorite_plugins_vbox . pack_start ( favorite_plugins_scroller , true , true ) ;
2020-06-24 23:52:38 -04:00
favorite_plugins_vbox . pack_start ( favorite_plugins_search_hbox , false , false ) ;
2015-12-21 22:43:26 -05:00
2022-06-01 09:48:44 -04:00
Gtk : : Label * l = manage ( new Label ( _ ( " Mixer Scenes (F1...F8 to recall) " ) ) ) ;
l - > set_alignment ( 0 , 0.5 ) ;
Gtk : : Table * padder = manage ( new Table ( ) ) ;
padder - > set_border_width ( 4 ) ;
padder - > attach ( * l , 0 , 1 , 0 , 1 , Gtk : : FILL , Gtk : : FILL ) ;
_mixer_scene_vbox . pack_start ( * padder , false , false ) ;
_mixer_scene_table . set_border_width ( 4 ) ;
_mixer_scene_table . set_spacings ( 4 ) ;
_mixer_scene_table . set_homogeneous ( false ) ;
2022-06-02 13:07:28 -04:00
for ( int column = 0 ; column < 1 ; + + column ) {
for ( int row = 0 ; row < 8 ; + + row ) {
int col = column * 2 ;
int scn_index = col * 2 + row ;
2022-06-01 09:48:44 -04:00
2022-06-02 13:07:28 -04:00
ArdourButton * b = manage ( new ArdourButton ( ArdourButton : : default_elements ) ) ;
b - > set_text ( string_compose ( " %1 " , 1 + scn_index ) ) ;
b - > signal_button_press_event ( ) . connect ( sigc : : bind ( sigc : : mem_fun ( * this , & Mixer_UI : : scene_button_press ) , scn_index ) , false ) ;
b - > signal_button_release_event ( ) . connect ( sigc : : bind ( sigc : : mem_fun ( * this , & Mixer_UI : : scene_button_release ) , scn_index ) , false ) ;
2022-06-01 09:48:44 -04:00
Gtk : : Label * l = manage ( new Gtk : : Label ( " " ) ) ;
2022-06-02 13:07:28 -04:00
Gtk : : EventBox * namebox = manage ( new Gtk : : EventBox ( ) ) ; // put label in an EventBox to capture double-click
2022-06-01 09:48:44 -04:00
namebox - > add ( * l ) ;
namebox - > add_events ( Gdk : : BUTTON_PRESS_MASK ) ;
2022-06-02 13:07:28 -04:00
namebox - > signal_button_press_event ( ) . connect ( sigc : : bind ( sigc : : mem_fun ( * this , & Mixer_UI : : scene_label_press ) , scn_index ) , false ) ;
2022-06-01 09:48:44 -04:00
2022-06-02 13:07:28 -04:00
/* Note: widgets in the vector are GTK managed, and C pointers will become invalid
* as soon as the widget are removed from the parent . */
_mixer_scene_buttons . push_back ( b ) ;
2022-06-01 09:48:44 -04:00
_mixer_scene_labels . push_back ( l ) ;
_mixer_scene_table . attach ( * b , col , col + 1 , row , row + 1 , Gtk : : FILL , Gtk : : FILL ) ; col + + ;
_mixer_scene_table . attach ( * namebox , col , col + 1 , row , row + 1 , Gtk : : FILL , Gtk : : FILL ) ; col + + ;
}
}
_mixer_scene_vbox . pack_start ( _mixer_scene_table , false , false ) ;
2024-03-20 08:49:18 -04:00
if ( ! Profile - > get_livetrax ( ) ) {
rhs_pane1 . add ( favorite_plugins_frame ) ;
rhs_pane1 . add ( track_display_frame ) ;
2016-06-13 09:53:10 -04:00
2024-03-20 08:49:18 -04:00
rhs_pane2 . add ( rhs_pane1 ) ;
rhs_pane2 . add ( group_display_frame ) ;
2015-12-21 22:43:26 -05:00
2024-03-20 08:49:18 -04:00
list_vpacker . pack_start ( rhs_pane2 , true , true ) ;
2005-09-25 14:42:24 -04:00
2022-06-01 09:48:44 -04:00
2024-03-20 08:49:18 -04:00
//add a spacer; this fills the area that is normally taken by the pane resizers
_mixer_scene_spacer . set_size_request ( - 1 , 6 ) ;
list_vpacker . pack_start ( _mixer_scene_spacer , false , false ) ;
2022-06-01 09:48:44 -04:00
2024-03-20 08:49:18 -04:00
_mixer_scene_frame . add ( _mixer_scene_vbox ) ;
list_vpacker . pack_start ( _mixer_scene_frame , false , false ) ;
2016-06-07 12:30:38 -04:00
2024-03-20 08:49:18 -04:00
vca_label_bar . set_size_request ( - 1 , 16 + 1 ) ; /* must match height in GroupTabs::set_size_request() + 1 border px*/
vca_vpacker . pack_start ( vca_label_bar , false , false ) ;
2016-05-18 22:27:25 -04:00
2024-03-20 08:49:18 -04:00
vca_scroller_base . add_events ( Gdk : : BUTTON_PRESS_MASK | Gdk : : BUTTON_RELEASE_MASK ) ;
vca_scroller_base . set_name ( X_ ( " MixerWindow " ) ) ;
vca_scroller_base . signal_button_press_event ( ) . connect ( sigc : : mem_fun ( * this , & Mixer_UI : : strip_scroller_button_event ) ) ;
vca_scroller_base . signal_button_release_event ( ) . connect ( sigc : : mem_fun ( * this , & Mixer_UI : : strip_scroller_button_event ) ) ;
2016-03-03 11:47:01 -05:00
2024-03-20 08:49:18 -04:00
vca_hpacker . signal_scroll_event ( ) . connect ( sigc : : mem_fun ( * this , & Mixer_UI : : on_vca_scroll_event ) , false ) ;
vca_scroller . add ( vca_hpacker ) ;
vca_scroller . set_policy ( Gtk : : POLICY_ALWAYS , Gtk : : POLICY_AUTOMATIC ) ;
2016-06-07 12:30:38 -04:00
2024-03-20 08:49:18 -04:00
vca_vpacker . pack_start ( vca_scroller , true , true ) ;
2016-03-03 11:47:01 -05:00
2024-03-20 08:49:18 -04:00
inner_pane . add ( scroller ) ;
inner_pane . add ( vca_vpacker ) ;
2015-12-19 18:16:42 -05:00
2024-03-20 08:49:18 -04:00
global_hpacker . pack_start ( inner_pane , true , true ) ;
global_hpacker . pack_start ( out_packer , false , false ) ;
2009-10-14 12:10:01 -04:00
2024-03-20 08:49:18 -04:00
list_hpane . set_check_divider_position ( true ) ;
list_hpane . add ( list_vpacker ) ;
list_hpane . add ( global_hpacker ) ;
list_hpane . set_child_minsize ( list_vpacker , 30 ) ;
2016-05-28 09:30:09 -04:00
2024-03-20 08:49:18 -04:00
rhs_pane1 . set_divider ( 0 , .6 ) ;
rhs_pane2 . set_divider ( 0 , .7 ) ;
list_hpane . set_divider ( 0 , .2 ) ;
inner_pane . set_divider ( 0 , .8 ) ;
2016-05-28 10:33:48 -04:00
2024-03-20 08:49:18 -04:00
rhs_pane1 . set_drag_cursor ( * PublicEditor : : instance ( ) . cursors ( ) - > expand_up_down ) ;
rhs_pane2 . set_drag_cursor ( * PublicEditor : : instance ( ) . cursors ( ) - > expand_up_down ) ;
list_hpane . set_drag_cursor ( * PublicEditor : : instance ( ) . cursors ( ) - > expand_left_right ) ;
inner_pane . set_drag_cursor ( * PublicEditor : : instance ( ) . cursors ( ) - > expand_left_right ) ;
_content . pack_start ( list_hpane , true , true ) ;
} else {
2024-05-06 17:50:33 -04:00
scroller . set_policy ( Gtk : : POLICY_ALWAYS , Gtk : : POLICY_NEVER ) ;
2024-05-06 18:07:25 -04:00
vca_label_bar . set_size_request ( - 1 , 16 + 2 ) ; /* must match height in GroupTabs::set_size_request() + 1 border px + 1 px inner shadow*/
2024-05-06 17:50:33 -04:00
VBox * mbox = manage ( new VBox ( ) ) ;
mbox - > pack_start ( vca_label_bar , false , false ) ;
mbox - > pack_start ( out_packer , true , true ) ;
2024-05-02 10:10:22 -04:00
HBox * box = manage ( new HBox ( ) ) ;
2024-05-24 09:21:46 -04:00
box - > pack_end ( * mbox , false , false ) ;
2024-05-02 10:10:22 -04:00
box - > pack_start ( scroller , true , true ) ;
2024-05-06 17:50:33 -04:00
_content . pack_start ( * box , false , false ) ;
mbox - > show ( ) ;
box - > show ( ) ;
2024-03-20 08:49:18 -04:00
}
2009-10-14 12:10:01 -04:00
2011-09-07 11:07:02 -04:00
update_title ( ) ;
2007-04-11 09:07:51 -04:00
2015-07-07 22:12:21 -04:00
_content . show ( ) ;
_content . set_name ( " MixerWindow " ) ;
2015-04-21 15:10:49 -04:00
2007-07-10 15:11:59 -04:00
global_hpacker . show ( ) ;
scroller . show ( ) ;
scroller_base . show ( ) ;
scroller_hpacker . show ( ) ;
mixer_scroller_vpacker . show ( ) ;
list_vpacker . show ( ) ;
group_display_button_label . show ( ) ;
group_display_scroller . show ( ) ;
2015-12-21 22:43:26 -05:00
favorite_plugins_scroller . show ( ) ;
2007-07-10 15:11:59 -04:00
group_display_vbox . show ( ) ;
2017-09-18 14:45:56 -04:00
group_display_frame . show ( ) ;
favorite_plugins_frame . show ( ) ;
2007-07-10 15:11:59 -04:00
rhs_pane1 . show ( ) ;
2015-12-21 22:43:26 -05:00
rhs_pane2 . show ( ) ;
2007-07-10 15:11:59 -04:00
strip_packer . show ( ) ;
2016-05-18 22:27:25 -04:00
inner_pane . show ( ) ;
2016-03-03 11:47:01 -05:00
vca_scroller . show ( ) ;
2016-06-07 12:30:38 -04:00
vca_vpacker . show ( ) ;
vca_hpacker . show ( ) ;
vca_label_bar . show ( ) ;
vca_label . show ( ) ;
2016-05-18 22:27:25 -04:00
vca_scroller_base . show ( ) ;
2007-07-10 15:11:59 -04:00
out_packer . show ( ) ;
list_hpane . show ( ) ;
group_display . show ( ) ;
2015-12-21 22:43:26 -05:00
favorite_plugins_display . show ( ) ;
2008-04-11 10:06:50 -04:00
2018-12-11 10:28:47 -05:00
XMLNode * mnode = ARDOUR_UI : : instance ( ) - > tearoff_settings ( X_ ( " monitor-section " ) ) ;
if ( mnode ) {
_monitor_section . tearoff ( ) . set_state ( * mnode ) ;
}
2012-04-25 08:58:19 -04:00
MixerStrip : : CatchDeletion . connect ( * this , invalidator ( * this ) , boost : : bind ( & Mixer_UI : : remove_strip , this , _1 ) , gui_context ( ) ) ;
2017-08-06 12:37:15 -04:00
VCAMasterStrip : : CatchDeletion . connect ( * this , invalidator ( * this ) , boost : : bind ( & Mixer_UI : : remove_master , this , _1 ) , gui_context ( ) ) ;
2019-08-28 16:22:24 -04:00
FoldbackStrip : : CatchDeletion . connect ( * this , invalidator ( * this ) , boost : : bind ( & Mixer_UI : : remove_foldback , this , _1 ) , gui_context ( ) ) ;
2024-01-02 08:26:56 -05:00
SurroundStrip : : CatchDeletion . connect ( * this , invalidator ( * this ) , boost : : bind ( & Mixer_UI : : remove_surround_master , this , _1 ) , gui_context ( ) ) ;
2009-11-15 20:06:33 -05:00
2016-05-21 08:34:09 -04:00
/* handle escape */
ARDOUR_UI : : instance ( ) - > Escape . connect ( * this , invalidator ( * this ) , boost : : bind ( & Mixer_UI : : escape , this ) , gui_context ( ) ) ;
2010-02-03 14:00:58 -05:00
# ifndef DEFER_PLUGIN_SELECTOR_LOAD
2024-03-26 12:12:18 -04:00
if ( ! Profile - > get_livetrax ( ) ) {
_plugin_selector = new PluginSelector ( PluginManager : : instance ( ) ) ;
}
2015-12-21 22:43:26 -05:00
# else
# error implement deferred Plugin-Favorite list
2010-02-03 14:00:58 -05:00
# endif
2018-01-29 18:45:42 -05:00
2020-06-24 23:52:38 -04:00
PluginManager : : instance ( ) . PluginListChanged . connect ( * this , invalidator ( * this ) , boost : : bind ( & Mixer_UI : : refill_favorite_plugins , this ) , gui_context ( ) ) ;
2018-02-02 20:25:01 -05:00
ARDOUR : : Plugin : : PresetsChanged . connect ( * this , invalidator ( * this ) , boost : : bind ( & Mixer_UI : : refill_favorite_plugins , this ) , gui_context ( ) ) ;
2020-06-24 23:52:38 -04:00
PluginManager : : instance ( ) . PluginStatusChanged . connect ( * this , invalidator ( * this ) , boost : : bind ( & Mixer_UI : : maybe_refill_favorite_plugins , this , PLM_Favorite ) , gui_context ( ) ) ;
PluginManager : : instance ( ) . PluginStatsChanged . connect ( * this , invalidator ( * this ) , boost : : bind ( & Mixer_UI : : maybe_refill_favorite_plugins , this , PLM_Recent ) , gui_context ( ) ) ;
2005-09-25 14:42:24 -04:00
}
Mixer_UI : : ~ Mixer_UI ( )
{
2018-12-11 10:28:47 -05:00
monitor_section_detached ( ) ;
2024-01-02 08:26:56 -05:00
delete _surround_strip ;
2019-11-06 11:27:21 -05:00
delete foldback_strip ;
foldback_strip = 0 ;
2015-09-12 14:05:46 -04:00
delete _plugin_selector ;
2017-03-15 21:25:53 -04:00
delete track_menu ;
2021-01-09 14:17:53 -05:00
delete _group_tabs ;
2022-11-10 14:52:50 -05:00
delete _mixer_scene_release ;
2005-09-25 14:42:24 -04:00
}
2018-08-24 10:07:55 -04:00
struct MixerStripSorter {
bool operator ( ) ( const MixerStrip * ms_a , const MixerStrip * ms_b )
{
2023-02-16 18:33:28 -05:00
std : : shared_ptr < ARDOUR : : Stripable > const & a = ms_a - > stripable ( ) ;
std : : shared_ptr < ARDOUR : : Stripable > const & b = ms_b - > stripable ( ) ;
2018-08-24 10:07:55 -04:00
return ARDOUR : : Stripable : : Sorter ( true ) ( a , b ) ;
}
} ;
2016-05-21 08:34:09 -04:00
void
Mixer_UI : : escape ( )
{
select_none ( ) ;
}
2015-07-09 12:40:51 -04:00
Gtk : : Window *
Mixer_UI : : use_own_window ( bool and_fill_it )
2015-04-21 15:10:49 -04:00
{
2015-07-09 12:40:51 -04:00
bool new_window = ! own_window ( ) ;
2015-04-21 15:10:49 -04:00
2015-07-09 12:40:51 -04:00
Gtk : : Window * win = Tabbable : : use_own_window ( and_fill_it ) ;
2015-04-21 15:10:49 -04:00
2015-07-09 12:40:51 -04:00
if ( win & & new_window ) {
win - > set_name ( " MixerWindow " ) ;
ARDOUR_UI : : instance ( ) - > setup_toplevel_window ( * win , _ ( " Mixer " ) , this ) ;
2016-02-22 14:42:40 -05:00
win - > signal_event ( ) . connect ( sigc : : bind ( sigc : : ptr_fun ( & Keyboard : : catch_user_event_for_pre_dialog_focus ) , win ) ) ;
2015-07-09 12:40:51 -04:00
win - > set_data ( " ardour-bindings " , bindings ) ;
update_title ( ) ;
2017-02-20 06:58:09 -05:00
if ( ! win - > get_focus ( ) ) {
/* set focus widget to something, anything */
win - > set_focus ( scroller ) ;
}
2015-07-09 12:40:51 -04:00
}
2015-04-21 15:10:49 -04:00
2015-07-09 12:40:51 -04:00
return win ;
2005-09-25 14:42:24 -04:00
}
2016-01-11 21:36:44 -05:00
void
2005-09-25 14:42:24 -04:00
Mixer_UI : : show_window ( )
{
2016-01-11 21:36:44 -05:00
Tabbable : : show_window ( ) ;
2011-02-21 19:11:32 -05:00
2016-01-11 21:36:44 -05:00
/* show/hide group tabs as required */
parameter_changed ( " show-group-tabs " ) ;
2009-10-14 12:10:01 -04:00
2016-01-11 21:36:44 -05:00
/* now reset each strips width so the right widgets are shown */
2009-10-14 12:10:01 -04:00
2016-01-11 21:36:44 -05:00
TreeModel : : Children rows = track_model - > children ( ) ;
TreeModel : : Children : : iterator ri ;
2015-10-05 10:17:49 -04:00
2016-01-11 21:36:44 -05:00
for ( ri = rows . begin ( ) ; ri ! = rows . end ( ) ; + + ri ) {
2016-06-05 16:29:22 -04:00
AxisView * av = ( * ri ) [ stripable_columns . strip ] ;
MixerStrip * ms = dynamic_cast < MixerStrip * > ( av ) ;
2016-02-27 22:16:37 -05:00
if ( ! ms ) {
continue ;
}
2016-01-11 21:36:44 -05:00
ms - > set_width_enum ( ms - > get_width_enum ( ) , ms - > width_owner ( ) ) ;
/* Fix visibility of mixer strip stuff */
ms - > parameter_changed ( X_ ( " mixer-element-visibility " ) ) ;
2015-04-21 15:10:49 -04:00
}
2024-03-25 20:36:11 -04:00
if ( ! Profile - > get_livetrax ( ) ) {
/* force focus into main area */
scroller_base . grab_focus ( ) ;
}
}
bool
Mixer_UI : : scroller_enter ( GdkEventCrossing * ev )
{
steal_focus ( ) ;
return false ;
2005-09-25 14:42:24 -04:00
}
2016-02-27 22:16:37 -05:00
void
Mixer_UI : : remove_master ( VCAMasterStrip * vms )
{
2016-04-23 18:25:49 -04:00
if ( _session & & _session - > deletion_in_progress ( ) ) {
/* its all being taken care of */
return ;
}
TreeModel : : Children rows = track_model - > children ( ) ;
TreeModel : : Children : : iterator ri ;
for ( ri = rows . begin ( ) ; ri ! = rows . end ( ) ; + + ri ) {
2016-06-05 16:29:22 -04:00
if ( ( * ri ) [ stripable_columns . strip ] = = vms ) {
2017-07-01 12:42:24 -04:00
PBD : : Unwinder < bool > uw ( _route_deletion_in_progress , true ) ;
2016-04-23 18:25:49 -04:00
track_model - > erase ( ri ) ;
break ;
}
}
2016-02-27 22:16:37 -05:00
}
2019-03-01 13:02:38 -05:00
void
Mixer_UI : : new_masters_created ( )
{
ActionManager : : get_toggle_action ( " Mixer " , " ToggleVCAPane " ) - > set_active ( true ) ;
}
2005-09-25 14:42:24 -04:00
void
2016-06-05 16:29:22 -04:00
Mixer_UI : : add_masters ( VCAList & vlist )
{
StripableList sl ;
for ( VCAList : : iterator v = vlist . begin ( ) ; v ! = vlist . end ( ) ; + + v ) {
2023-02-16 18:33:28 -05:00
sl . push_back ( std : : dynamic_pointer_cast < Stripable > ( * v ) ) ;
2016-06-05 16:29:22 -04:00
}
add_stripables ( sl ) ;
}
void
Mixer_UI : : add_routes ( RouteList & rlist )
{
StripableList sl ;
for ( RouteList : : iterator r = rlist . begin ( ) ; r ! = rlist . end ( ) ; + + r ) {
sl . push_back ( * r ) ;
}
add_stripables ( sl ) ;
}
void
Mixer_UI : : add_stripables ( StripableList & slist )
2005-09-25 14:42:24 -04:00
{
2013-10-23 10:27:13 -04:00
Gtk : : TreeModel : : Children : : iterator insert_iter = track_model - > children ( ) . end ( ) ;
2016-06-06 12:52:48 -04:00
bool from_scratch = ( track_model - > children ( ) . size ( ) = = 0 ) ;
2016-03-04 15:40:44 -05:00
uint32_t nroutes = 0 ;
2013-10-23 10:27:13 -04:00
2017-06-16 17:45:16 -04:00
slist . sort ( Stripable : : Sorter ( ) ) ;
2016-06-06 12:52:48 -04:00
2013-10-23 10:27:13 -04:00
for ( Gtk : : TreeModel : : Children : : iterator it = track_model - > children ( ) . begin ( ) ; it ! = track_model - > children ( ) . end ( ) ; + + it ) {
2023-02-16 18:33:28 -05:00
std : : shared_ptr < Stripable > s = ( * it ) [ stripable_columns . stripable ] ;
2013-10-23 10:27:13 -04:00
2016-06-05 16:29:22 -04:00
if ( ! s ) {
2016-02-27 22:16:37 -05:00
continue ;
}
2016-03-04 15:40:44 -05:00
nroutes + + ;
2017-06-16 17:45:16 -04:00
// XXX what does this special case do?
2024-03-02 08:51:34 -05:00
// A: it inserts the new track at the correct point in the model
// uness it's the the first (after master-bus, which is not in Mixbus track-model)
2016-06-05 16:29:22 -04:00
if ( s - > presentation_info ( ) . order ( ) = = ( slist . front ( ) - > presentation_info ( ) . order ( ) + slist . size ( ) ) ) {
2013-10-23 10:27:13 -04:00
insert_iter = it ;
break ;
}
}
2005-09-25 14:42:24 -04:00
MixerStrip * strip ;
2005-11-29 17:48:54 -05:00
2012-12-04 09:32:28 -05:00
try {
2016-06-09 20:43:11 -04:00
PBD : : Unwinder < bool > uw ( no_track_list_redisplay , true ) ;
2012-12-04 09:32:28 -05:00
track_display . set_model ( Glib : : RefPtr < ListStore > ( ) ) ;
2016-06-05 16:29:22 -04:00
for ( StripableList : : iterator s = slist . begin ( ) ; s ! = slist . end ( ) ; + + s ) {
2015-10-05 10:17:49 -04:00
2023-02-16 18:33:28 -05:00
std : : shared_ptr < Route > route ;
std : : shared_ptr < VCA > vca ;
2015-10-05 10:17:49 -04:00
2023-02-16 18:33:28 -05:00
if ( ( vca = std : : dynamic_pointer_cast < VCA > ( * s ) ) ) {
2015-10-05 10:17:49 -04:00
2016-06-05 16:29:22 -04:00
VCAMasterStrip * vms = new VCAMasterStrip ( _session , vca ) ;
2015-10-05 10:17:49 -04:00
2016-06-05 16:29:22 -04:00
TreeModel : : Row row = * ( track_model - > append ( ) ) ;
row [ stripable_columns . text ] = vca - > name ( ) ;
2016-06-09 16:03:07 -04:00
row [ stripable_columns . visible ] = vms - > marked_for_display ( ) ;
2016-06-05 16:29:22 -04:00
row [ stripable_columns . strip ] = vms ;
row [ stripable_columns . stripable ] = vca ;
2017-08-06 12:37:15 -04:00
vms - > signal_button_release_event ( ) . connect ( sigc : : bind ( sigc : : mem_fun ( * this , & Mixer_UI : : vca_button_release_event ) , vms ) ) ;
2016-06-05 16:29:22 -04:00
2023-02-16 18:33:28 -05:00
} else if ( ( route = std : : dynamic_pointer_cast < Route > ( * s ) ) ) {
2016-06-05 16:29:22 -04:00
if ( route - > is_auditioner ( ) ) {
continue ;
2015-10-04 14:51:05 -04:00
}
2015-10-05 10:17:49 -04:00
2016-06-05 16:29:22 -04:00
if ( route - > is_monitor ( ) ) {
2015-10-05 10:17:49 -04:00
2018-12-11 10:28:47 -05:00
out_packer . pack_end ( _monitor_section . tearoff ( ) , false , false ) ;
_monitor_section . set_session ( _session ) ;
_monitor_section . tearoff ( ) . show_all ( ) ;
2015-10-05 10:17:49 -04:00
2018-12-11 10:28:47 -05:00
_monitor_section . tearoff ( ) . Detach . connect ( sigc : : mem_fun ( * this , & Mixer_UI : : monitor_section_detached ) ) ;
_monitor_section . tearoff ( ) . Attach . connect ( sigc : : mem_fun ( * this , & Mixer_UI : : monitor_section_attached ) ) ;
2015-10-05 10:17:49 -04:00
2018-12-11 10:28:47 -05:00
if ( _monitor_section . tearoff ( ) . torn_off ( ) ) {
2017-05-09 12:32:04 -04:00
monitor_section_detached ( ) ;
} else {
monitor_section_attached ( ) ;
}
2015-10-05 10:17:49 -04:00
2016-06-05 16:29:22 -04:00
route - > DropReferences . connect ( * this , invalidator ( * this ) , boost : : bind ( & Mixer_UI : : monitor_section_going_away , this ) , gui_context ( ) ) ;
2012-12-04 09:32:28 -05:00
2016-06-05 16:29:22 -04:00
/* no regular strip shown for control out */
2015-10-05 10:17:49 -04:00
2016-06-05 16:29:22 -04:00
continue ;
}
2019-01-18 13:22:54 -05:00
if ( route - > is_foldbackbus ( ) ) {
if ( foldback_strip ) {
2019-09-11 19:36:05 -04:00
// last strip created is shown
2019-01-18 13:22:54 -05:00
foldback_strip - > set_route ( route ) ;
} else {
foldback_strip = new FoldbackStrip ( * this , _session , route ) ;
2019-09-04 00:44:14 -04:00
out_packer . pack_start ( * foldback_strip , false , false ) ;
// change 0 to 1 below for foldback to right of master
out_packer . reorder_child ( * foldback_strip , 0 ) ;
2019-01-18 13:22:54 -05:00
}
2019-09-11 19:36:05 -04:00
/* config from last run is set before there are any foldback strips
* this takes that setting and applies it after at least one foldback
* strip exists */
bool yn = _show_foldback_strip ;
Glib : : RefPtr < ToggleAction > act = ActionManager : : get_toggle_action ( " Mixer " , " ToggleFoldbackStrip " ) ;
2019-09-13 11:18:35 -04:00
act - > set_sensitive ( true ) ;
2019-09-11 19:36:05 -04:00
act - > set_active ( ! yn ) ;
act - > set_active ( yn ) ;
2019-01-18 13:22:54 -05:00
continue ;
}
2015-10-05 10:17:49 -04:00
2024-01-02 08:26:56 -05:00
if ( route - > is_surround_master ( ) ) {
if ( ! _surround_strip ) {
_surround_strip = new SurroundStrip ( * this , _session , route ) ;
}
out_packer . pack_start ( * _surround_strip , false , false ) ;
continue ;
}
2016-06-05 16:29:22 -04:00
strip = new MixerStrip ( * this , _session , route ) ;
2022-06-14 20:24:03 -04:00
strip - > set_selected ( route - > is_selected ( ) ) ;
2016-06-05 16:29:22 -04:00
strips . push_back ( strip ) ;
2015-10-05 10:17:49 -04:00
2016-06-05 16:29:22 -04:00
UIConfiguration : : instance ( ) . get_default_narrow_ms ( ) ? _strip_width = Narrow : _strip_width = Wide ;
2013-10-23 10:27:13 -04:00
2016-06-05 16:29:22 -04:00
if ( strip - > width_owner ( ) ! = strip ) {
strip - > set_width_enum ( _strip_width , this ) ;
}
show_strip ( strip ) ;
2015-10-05 10:17:49 -04:00
2018-03-11 15:42:00 -04:00
if ( route - > is_master ( ) ) {
2024-01-15 16:40:35 -05:00
out_packer . pack_start ( * strip , false , false ) ;
2018-03-11 15:42:00 -04:00
strip - > set_packed ( true ) ;
} else {
2016-06-10 14:44:57 -04:00
TreeModel : : Row row = * ( track_model - > insert ( insert_iter ) ) ;
2016-06-05 16:29:22 -04:00
2016-06-10 14:44:57 -04:00
row [ stripable_columns . text ] = route - > name ( ) ;
row [ stripable_columns . visible ] = strip - > marked_for_display ( ) ;
row [ stripable_columns . stripable ] = route ;
row [ stripable_columns . strip ] = strip ;
2016-06-05 16:29:22 -04:00
}
2015-10-05 10:17:49 -04:00
2016-06-05 16:29:22 -04:00
strip - > WidthChanged . connect ( sigc : : mem_fun ( * this , & Mixer_UI : : strip_width_changed ) ) ;
strip - > signal_button_release_event ( ) . connect ( sigc : : bind ( sigc : : mem_fun ( * this , & Mixer_UI : : strip_button_release_event ) , strip ) ) ;
}
2016-06-09 16:58:49 -04:00
2023-02-16 18:33:28 -05:00
( * s ) - > presentation_info ( ) . PropertyChanged . connect ( * this , invalidator ( * this ) , boost : : bind ( & Mixer_UI : : stripable_property_changed , this , _1 , std : : weak_ptr < Stripable > ( * s ) ) , gui_context ( ) ) ;
( * s ) - > PropertyChanged . connect ( * this , invalidator ( * this ) , boost : : bind ( & Mixer_UI : : stripable_property_changed , this , _1 , std : : weak_ptr < Stripable > ( * s ) ) , gui_context ( ) ) ;
2016-12-20 21:47:36 -05:00
}
2012-12-04 09:32:28 -05:00
2016-02-25 11:53:59 -05:00
} catch ( const std : : exception & e ) {
error < < string_compose ( _ ( " Error adding GUI elements for new tracks/busses %1 " ) , e . what ( ) ) < < endmsg ;
2006-08-16 22:12:20 -04:00
}
2008-12-08 13:16:12 -05:00
2012-12-04 09:32:28 -05:00
track_display . set_model ( track_model ) ;
2015-10-05 10:17:49 -04:00
2016-06-06 12:52:48 -04:00
if ( ! from_scratch ) {
2024-03-02 08:51:34 -05:00
sync_treeview_from_presentation_info ( Properties : : order ) ;
2016-06-06 12:52:48 -04:00
}
2016-06-09 20:43:11 -04:00
redisplay_track_list ( ) ;
2022-06-14 20:24:03 -04:00
if ( ! from_scratch ) {
/* Mixer_UI::move_stripable_into_view() can only correctly calculate
* the scroll offset after the layout was updated .
* We update update after the resize operation ( + 10 ) , but before drawing ( + 20 )
* https : //docs.gtk.org/glib/const.PRIORITY_HIGH_IDLE.html
*/
Glib : : signal_idle ( ) . connect ( sigc : : bind_return ( sigc : : bind ( sigc : : mem_fun ( * this , & Mixer_UI : : sync_treeview_from_presentation_info ) , PropertyChange ( Properties : : selected ) ) , false ) , G_PRIORITY_HIGH_IDLE + 15 ) ;
}
2005-09-25 14:42:24 -04:00
}
2014-07-24 23:49:33 -04:00
void
Mixer_UI : : deselect_all_strip_processors ( )
{
for ( list < MixerStrip * > : : iterator i = strips . begin ( ) ; i ! = strips . end ( ) ; + + i ) {
( * i ) - > deselect_all_processors ( ) ;
}
2021-03-26 18:50:47 -04:00
if ( foldback_strip ) {
foldback_strip - > deselect_all_processors ( ) ;
}
2014-07-24 23:49:33 -04:00
}
2014-07-28 12:35:41 -04:00
void
Mixer_UI : : select_none ( )
{
2014-07-28 16:55:20 -04:00
_selection . clear_routes ( ) ;
2014-07-28 12:35:41 -04:00
deselect_all_strip_processors ( ) ;
}
2018-08-24 14:03:34 -04:00
void
2018-08-24 10:07:55 -04:00
Mixer_UI : : select_next_strip ( )
{
deselect_all_strip_processors ( ) ;
2018-08-24 14:03:34 -04:00
_session - > selection ( ) . select_next_stripable ( true , false ) ;
2018-08-24 10:07:55 -04:00
}
void
Mixer_UI : : select_prev_strip ( )
{
deselect_all_strip_processors ( ) ;
2018-08-24 14:03:34 -04:00
_session - > selection ( ) . select_prev_stripable ( true , false ) ;
2018-08-24 10:07:55 -04:00
}
2014-07-24 23:49:33 -04:00
void
Mixer_UI : : delete_processors ( )
{
for ( list < MixerStrip * > : : iterator i = strips . begin ( ) ; i ! = strips . end ( ) ; + + i ) {
( * i ) - > delete_processors ( ) ;
}
}
2005-09-25 14:42:24 -04:00
void
Mixer_UI : : remove_strip ( MixerStrip * strip )
{
2009-12-25 16:06:52 -05:00
if ( _session & & _session - > deletion_in_progress ( ) ) {
/* its all being taken care of */
return ;
}
2006-03-09 18:44:39 -05:00
TreeModel : : Children rows = track_model - > children ( ) ;
2005-09-28 12:22:43 -04:00
TreeModel : : Children : : iterator ri ;
2005-09-25 14:42:24 -04:00
list < MixerStrip * > : : iterator i ;
2015-10-05 10:17:49 -04:00
2005-09-25 14:42:24 -04:00
if ( ( i = find ( strips . begin ( ) , strips . end ( ) , strip ) ) ! = strips . end ( ) ) {
strips . erase ( i ) ;
}
2015-10-05 10:17:49 -04:00
2020-06-24 20:26:01 -04:00
PBD : : Unwinder < bool > uwi ( ignore_track_reorder , true ) ;
2017-05-08 05:33:37 -04:00
2005-09-28 12:22:43 -04:00
for ( ri = rows . begin ( ) ; ri ! = rows . end ( ) ; + + ri ) {
2016-06-05 16:29:22 -04:00
if ( ( * ri ) [ stripable_columns . strip ] = = strip ) {
2017-07-01 12:42:24 -04:00
PBD : : Unwinder < bool > uw ( _route_deletion_in_progress , true ) ;
2006-03-09 18:44:39 -05:00
track_model - > erase ( ri ) ;
2005-09-25 14:42:24 -04:00
break ;
}
}
}
2024-01-02 08:26:56 -05:00
void
Mixer_UI : : remove_surround_master ( SurroundStrip * strip )
{
if ( _session & & _session - > deletion_in_progress ( ) ) {
/* its all being taken care of */
return ;
}
assert ( strip = = _surround_strip ) ;
out_packer . remove ( * _surround_strip ) ;
_surround_strip = 0 ;
RefPtr < ToggleAction > surround_action = ActionManager : : get_toggle_action ( X_ ( " Mixer " ) , " ToggleSurroundMaster " ) ;
surround_action - > set_active ( false ) ;
2023-12-07 11:43:26 -05:00
Glib : : RefPtr < Action > surround_export = ActionManager : : get_action ( X_ ( " Main " ) , X_ ( " SurroundExport " ) ) ;
surround_export - > set_sensitive ( false ) ;
2024-01-02 08:26:56 -05:00
}
2019-08-28 16:22:24 -04:00
void
Mixer_UI : : remove_foldback ( FoldbackStrip * strip )
{
if ( _session & & _session - > deletion_in_progress ( ) ) {
/* its all being taken care of */
return ;
}
2021-03-26 18:01:38 -04:00
assert ( strip = = foldback_strip ) ;
2019-09-13 11:18:35 -04:00
Glib : : RefPtr < ToggleAction > act = ActionManager : : get_toggle_action ( " Mixer " , " ToggleFoldbackStrip " ) ;
act - > set_sensitive ( false ) ;
2019-08-28 16:22:24 -04:00
foldback_strip = 0 ;
}
2017-01-27 13:18:33 -05:00
void
Mixer_UI : : presentation_info_changed ( PropertyChange const & what_changed )
{
2017-05-08 05:33:37 -04:00
if ( what_changed . contains ( Properties : : selected ) ) {
_selection . presentation_info_changed ( what_changed ) ;
}
2017-05-05 07:31:49 -04:00
2017-01-27 13:18:33 -05:00
PropertyChange soh ;
soh . add ( Properties : : selected ) ;
soh . add ( Properties : : order ) ;
soh . add ( Properties : : hidden ) ;
if ( what_changed . contains ( soh ) ) {
sync_treeview_from_presentation_info ( what_changed ) ;
}
}
2007-10-11 18:07:47 -04:00
void
2016-05-16 07:30:28 -04:00
Mixer_UI : : sync_presentation_info_from_treeview ( )
2012-07-19 18:35:43 -04:00
{
2020-06-24 20:26:01 -04:00
if ( ignore_track_reorder | | ! _session | | _session - > deletion_in_progress ( ) ) {
2012-06-27 18:57:06 -04:00
return ;
}
2007-10-11 18:07:47 -04:00
2012-06-27 18:57:06 -04:00
TreeModel : : Children rows = track_model - > children ( ) ;
2015-10-05 10:17:49 -04:00
2012-06-27 18:57:06 -04:00
if ( rows . empty ( ) ) {
2007-10-11 18:07:47 -04:00
return ;
}
2016-05-17 09:36:28 -04:00
DEBUG_TRACE ( DEBUG : : OrderKeys , " mixer sync presentation info from treeview \n " ) ;
2007-10-11 18:07:47 -04:00
2012-06-27 18:57:06 -04:00
TreeModel : : Children : : iterator ri ;
2008-12-08 13:16:12 -05:00
2017-06-16 17:45:16 -04:00
PresentationInfo : : order_t master_key = _session - > master_order_key ( ) ;
PresentationInfo : : order_t order = 0 ;
2016-11-04 11:39:41 -04:00
2017-01-26 13:20:40 -05:00
PresentationInfo : : ChangeSuspender cs ;
2012-07-19 18:35:43 -04:00
for ( ri = rows . begin ( ) ; ri ! = rows . end ( ) ; + + ri ) {
2016-06-05 16:29:22 -04:00
bool visible = ( * ri ) [ stripable_columns . visible ] ;
2023-02-16 18:33:28 -05:00
std : : shared_ptr < Stripable > stripable = ( * ri ) [ stripable_columns . stripable ] ;
2016-05-16 07:30:28 -04:00
2017-06-16 17:45:16 -04:00
# ifndef NDEBUG // these should not exist in the mixer's treeview
2016-06-05 16:29:22 -04:00
if ( ! stripable ) {
2017-06-16 17:45:16 -04:00
assert ( 0 ) ;
2016-02-27 22:16:37 -05:00
continue ;
}
2016-06-05 16:29:22 -04:00
if ( stripable - > is_monitor ( ) | | stripable - > is_auditioner ( ) ) {
2017-06-16 17:45:16 -04:00
assert ( 0 ) ;
2016-05-16 07:30:28 -04:00
continue ;
2008-12-08 13:16:12 -05:00
}
2024-01-02 08:26:56 -05:00
if ( stripable - > is_surround_master ( ) ) {
assert ( 0 ) ;
continue ;
}
2017-06-16 17:45:16 -04:00
if ( stripable - > is_master ( ) ) {
assert ( 0 ) ;
continue ;
}
# endif
2016-06-06 12:52:48 -04:00
2017-06-16 17:45:16 -04:00
// leave master where it is.
if ( order = = master_key ) {
+ + order ;
2016-11-04 11:39:41 -04:00
}
2022-01-25 21:18:37 -05:00
stripable - > presentation_info ( ) . set_hidden ( ! visible ) ;
stripable - > set_presentation_order ( order ) ;
2012-07-19 18:35:43 -04:00
+ + order ;
2012-06-27 18:57:06 -04:00
}
2012-07-19 18:35:43 -04:00
2012-06-27 18:57:06 -04:00
}
void
2017-01-27 13:18:33 -05:00
Mixer_UI : : sync_treeview_from_presentation_info ( PropertyChange const & what_changed )
2012-06-27 18:57:06 -04:00
{
if ( ! _session | | _session - > deletion_in_progress ( ) ) {
return ;
2007-10-11 18:07:47 -04:00
}
2009-11-16 16:07:16 -05:00
2016-05-17 09:36:28 -04:00
DEBUG_TRACE ( DEBUG : : OrderKeys , " mixer sync model from presentation info. \n " ) ;
2009-10-22 20:05:50 -04:00
2012-06-27 18:57:06 -04:00
/* we could get here after either a change in the Mixer or Editor sort
* order , but either way , the mixer order keys reflect the intended
* order for the GUI , so reorder the treeview model to match it .
*/
2022-06-14 20:24:03 -04:00
if ( what_changed . contains ( Properties : : order ) ) {
vector < int > neworder ;
TreeModel : : Children rows = track_model - > children ( ) ;
uint32_t old_order = 0 ;
bool changed = false ;
2012-06-27 18:57:06 -04:00
2022-06-14 20:24:03 -04:00
if ( rows . empty ( ) ) {
return ;
}
2007-10-11 18:07:47 -04:00
2022-06-14 20:24:03 -04:00
TreeOrderKeys sorted ;
for ( TreeModel : : Children : : iterator ri = rows . begin ( ) ; ri ! = rows . end ( ) ; + + ri , + + old_order ) {
2023-02-16 18:33:28 -05:00
std : : shared_ptr < Stripable > stripable = ( * ri ) [ stripable_columns . stripable ] ;
2022-06-14 20:24:03 -04:00
sorted . push_back ( TreeOrderKey ( old_order , stripable ) ) ;
}
2012-10-26 20:15:45 -04:00
2022-06-14 20:24:03 -04:00
TreeOrderKeySorter cmp ;
2012-10-26 20:15:45 -04:00
2022-06-14 20:24:03 -04:00
sort ( sorted . begin ( ) , sorted . end ( ) , cmp ) ;
neworder . assign ( sorted . size ( ) , 0 ) ;
2012-10-26 20:15:45 -04:00
2022-06-14 20:24:03 -04:00
uint32_t n = 0 ;
2015-10-05 10:17:49 -04:00
2022-06-14 20:24:03 -04:00
for ( TreeOrderKeys : : iterator sr = sorted . begin ( ) ; sr ! = sorted . end ( ) ; + + sr , + + n ) {
2012-06-28 18:27:37 -04:00
2022-06-14 20:24:03 -04:00
neworder [ n ] = sr - > old_display_order ;
2012-06-28 18:27:37 -04:00
2022-06-14 20:24:03 -04:00
if ( sr - > old_display_order ! = n ) {
changed = true ;
}
}
if ( changed ) {
Unwinder < bool > uw ( ignore_track_reorder , true ) ;
track_model - > reorder ( neworder ) ;
2012-06-28 18:27:37 -04:00
}
2012-06-27 18:57:06 -04:00
}
2022-06-14 20:24:03 -04:00
if ( what_changed . contains ( Properties : : order ) | | what_changed . contains ( Properties : : hidden ) ) {
redisplay_track_list ( ) ;
2008-12-08 13:16:12 -05:00
}
2012-06-27 18:57:06 -04:00
2017-01-27 13:18:33 -05:00
if ( what_changed . contains ( Properties : : selected ) ) {
PresentationInfo : : ChangeSuspender cs ;
2011-11-15 14:33:09 -05:00
2017-01-27 13:18:33 -05:00
for ( list < MixerStrip * > : : const_iterator i = strips . begin ( ) ; i ! = strips . end ( ) ; + + i ) {
2023-02-16 18:33:28 -05:00
std : : shared_ptr < Stripable > stripable = ( * i ) - > stripable ( ) ;
2017-05-05 07:31:49 -04:00
if ( stripable & & stripable - > is_selected ( ) ) {
2017-01-27 13:18:33 -05:00
_selection . add ( * i ) ;
} else {
_selection . remove ( * i ) ;
2011-11-15 14:33:09 -05:00
}
}
2017-01-28 05:46:04 -05:00
2017-10-21 11:27:03 -04:00
if ( ! _selection . axes . empty ( ) & & ! PublicEditor : : instance ( ) . track_selection_change_without_scroll ( ) & & ! _strip_selection_change_without_scroll ) {
2017-01-28 05:46:04 -05:00
move_stripable_into_view ( ( * _selection . axes . begin ( ) ) - > stripable ( ) ) ;
}
2017-08-06 12:37:15 -04:00
TreeModel : : Children rows = track_model - > children ( ) ;
for ( TreeModel : : Children : : const_iterator i = rows . begin ( ) ; i ! = rows . end ( ) ; + + i ) {
AxisView * av = ( * i ) [ stripable_columns . strip ] ;
VCAMasterStrip * vms = dynamic_cast < VCAMasterStrip * > ( av ) ;
if ( ! vms ) {
continue ;
}
if ( vms - > vca ( ) & & vms - > vca ( ) - > is_selected ( ) ) {
_selection . add ( vms ) ;
} else {
_selection . remove ( vms ) ;
}
}
2011-11-15 14:33:09 -05:00
}
}
2020-04-02 13:55:33 -04:00
void
2023-02-16 18:33:28 -05:00
Mixer_UI : : fan_out ( std : : weak_ptr < Route > wr , bool to_busses , bool group )
2020-04-02 13:55:33 -04:00
{
2023-02-16 18:33:28 -05:00
std : : shared_ptr < ARDOUR : : Route > route = wr . lock ( ) ;
2020-04-02 13:55:33 -04:00
if ( ! ARDOUR_UI_UTILS : : engine_is_running ( ) | | ! route ) {
return ;
}
DisplaySuspender ds ;
2023-02-16 18:33:28 -05:00
std : : shared_ptr < PluginInsert > pi = std : : dynamic_pointer_cast < PluginInsert > ( route - > the_instrument ( ) ) ;
2020-04-02 13:55:33 -04:00
assert ( pi ) ;
const uint32_t n_outputs = pi - > output_streams ( ) . n_audio ( ) ;
if ( route - > n_outputs ( ) . n_audio ( ) ! = n_outputs ) {
MessageDialog msg ( string_compose (
_ ( " The Plugin's number of audio outputs ports (%1) does not match the Tracks's number of audio outputs (%2). Cannot fan out. " ) ,
n_outputs , route - > n_outputs ( ) . n_audio ( ) ) ) ;
msg . run ( ) ;
return ;
}
# define BUSNAME pd.group_name + "(" + route->name () + ")"
/* count busses and channels/bus */
2023-02-16 18:33:28 -05:00
std : : shared_ptr < Plugin > plugin = pi - > plugin ( ) ;
2020-04-02 13:55:33 -04:00
std : : map < std : : string , uint32_t > busnames ;
for ( uint32_t p = 0 ; p < n_outputs ; + + p ) {
const Plugin : : IOPortDescription & pd ( plugin - > describe_io_port ( DataType : : AUDIO , false , p ) ) ;
std : : string bn = BUSNAME ;
busnames [ bn ] + + ;
}
if ( busnames . size ( ) < 2 ) {
MessageDialog msg ( _ ( " Instrument has only 1 output bus. Nothing to fan out. " ) ) ;
msg . run ( ) ;
return ;
}
uint32_t outputs = 2 ;
if ( _session - > master_out ( ) ) {
outputs = std : : max ( outputs , _session - > master_out ( ) - > n_inputs ( ) . n_audio ( ) ) ;
}
route - > output ( ) - > disconnect ( this ) ;
route - > panner_shell ( ) - > set_bypassed ( true ) ;
2023-02-16 18:33:28 -05:00
std : : shared_ptr < AutomationControl > msac = route - > master_send_enable_controllable ( ) ;
2020-04-02 13:55:33 -04:00
if ( msac ) {
2020-09-26 11:14:59 -04:00
msac - > start_touch ( timepos_t ( msac - > session ( ) . transport_sample ( ) ) ) ;
2020-04-02 13:55:33 -04:00
msac - > set_value ( 0 , PBD : : Controllable : : NoGroup ) ;
}
RouteList to_group ;
for ( uint32_t p = 0 ; p < n_outputs ; + + p ) {
const Plugin : : IOPortDescription & pd ( plugin - > describe_io_port ( DataType : : AUDIO , false , p ) ) ;
std : : string bn = BUSNAME ;
2023-02-16 18:33:28 -05:00
std : : shared_ptr < Route > r = _session - > route_by_name ( bn ) ;
2020-04-02 13:55:33 -04:00
if ( ! r ) {
try {
if ( to_busses ) {
RouteList rl = _session - > new_audio_route ( busnames [ bn ] , outputs , NULL , 1 , bn , PresentationInfo : : AudioBus , PresentationInfo : : max_order ) ;
r = rl . front ( ) ;
assert ( r ) ;
} else {
2023-02-16 18:33:28 -05:00
list < std : : shared_ptr < AudioTrack > > tl = _session - > new_audio_track ( busnames [ bn ] , outputs , NULL , 1 , bn , PresentationInfo : : max_order , Normal , false ) ;
2020-04-02 13:55:33 -04:00
r = tl . front ( ) ;
assert ( r ) ;
2023-07-19 19:24:57 -04:00
std : : shared_ptr < AutomationControlList > cl ( new AutomationControlList ) ;
2020-04-02 13:55:33 -04:00
cl - > push_back ( r - > monitoring_control ( ) ) ;
_session - > set_controls ( cl , ( double ) MonitorInput , Controllable : : NoGroup ) ;
}
} catch ( . . . ) {
if ( ! to_group . empty ( ) ) {
2023-02-16 18:33:28 -05:00
std : : shared_ptr < RouteList > rl ( & to_group ) ;
2020-04-02 13:55:33 -04:00
_session - > remove_routes ( rl ) ;
}
return ;
}
}
to_group . push_back ( r ) ;
route - > output ( ) - > audio ( p ) - > connect ( r - > input ( ) - > audio ( pd . group_channel ) . get ( ) ) ;
}
# undef BUSNAME
if ( group ) {
RouteGroup * rg = NULL ;
const std : : list < RouteGroup * > & rgs ( _session - > route_groups ( ) ) ;
for ( std : : list < RouteGroup * > : : const_iterator i = rgs . begin ( ) ; i ! = rgs . end ( ) ; + + i ) {
if ( ( * i ) - > name ( ) = = pi - > name ( ) ) {
rg = * i ;
break ;
}
}
if ( ! rg ) {
rg = new RouteGroup ( * _session , pi - > name ( ) ) ;
_session - > add_route_group ( rg ) ;
rg - > set_gain ( false ) ;
}
GroupTabs : : set_group_color ( rg , route - > presentation_info ( ) . color ( ) ) ;
for ( RouteList : : const_iterator i = to_group . begin ( ) ; i ! = to_group . end ( ) ; + + i ) {
rg - > add ( * i ) ;
}
}
}
2011-11-15 14:33:09 -05:00
2011-11-04 13:53:21 -04:00
MixerStrip *
2023-02-16 18:33:28 -05:00
Mixer_UI : : strip_by_route ( std : : shared_ptr < Route > r ) const
2005-09-25 14:42:24 -04:00
{
2016-07-06 13:37:30 -04:00
for ( list < MixerStrip * > : : const_iterator i = strips . begin ( ) ; i ! = strips . end ( ) ; + + i ) {
2011-11-04 13:53:21 -04:00
if ( ( * i ) - > route ( ) = = r ) {
return ( * i ) ;
}
2005-09-25 14:42:24 -04:00
}
2011-11-04 13:53:21 -04:00
return 0 ;
2005-09-25 14:42:24 -04:00
}
2017-01-26 08:08:58 -05:00
MixerStrip *
2023-02-16 18:33:28 -05:00
Mixer_UI : : strip_by_stripable ( std : : shared_ptr < Stripable > s ) const
2017-01-26 08:08:58 -05:00
{
for ( list < MixerStrip * > : : const_iterator i = strips . begin ( ) ; i ! = strips . end ( ) ; + + i ) {
if ( ( * i ) - > stripable ( ) = = s ) {
return ( * i ) ;
}
}
return 0 ;
}
2016-07-06 13:37:30 -04:00
AxisView *
2023-02-16 18:33:28 -05:00
Mixer_UI : : axis_view_by_stripable ( std : : shared_ptr < Stripable > s ) const
2016-07-06 13:37:30 -04:00
{
for ( list < MixerStrip * > : : const_iterator i = strips . begin ( ) ; i ! = strips . end ( ) ; + + i ) {
if ( ( * i ) - > stripable ( ) = = s ) {
return ( * i ) ;
}
}
2017-08-06 12:37:15 -04:00
TreeModel : : Children rows = track_model - > children ( ) ;
for ( TreeModel : : Children : : const_iterator i = rows . begin ( ) ; i ! = rows . end ( ) ; + + i ) {
AxisView * av = ( * i ) [ stripable_columns . strip ] ;
VCAMasterStrip * vms = dynamic_cast < VCAMasterStrip * > ( av ) ;
if ( vms & & vms - > stripable ( ) = = s ) {
return av ;
}
}
2016-07-06 13:37:30 -04:00
return 0 ;
}
2017-05-05 07:31:49 -04:00
AxisView *
2023-02-16 18:33:28 -05:00
Mixer_UI : : axis_view_by_control ( std : : shared_ptr < AutomationControl > c ) const
2017-05-05 07:31:49 -04:00
{
for ( list < MixerStrip * > : : const_iterator i = strips . begin ( ) ; i ! = strips . end ( ) ; + + i ) {
if ( ( * i ) - > control ( ) = = c ) {
return ( * i ) ;
}
}
return 0 ;
}
2006-01-04 22:18:44 -05:00
bool
2005-09-25 14:42:24 -04:00
Mixer_UI : : strip_button_release_event ( GdkEventButton * ev , MixerStrip * strip )
{
2017-10-21 11:27:03 -04:00
/* Selecting a mixer-strip may also select grouped-tracks, and
* presentation_info_changed ( ) being emitted and
* _selection . axes . begin ( ) is being moved into view . This may
* effectively move the track that was clicked - on out of view .
*
* So here only the track that is actually clicked - on is moved into
* view ( in case it ' s partially visible )
*/
PBD : : Unwinder < bool > uw ( _strip_selection_change_without_scroll , true ) ;
move_stripable_into_view ( strip - > stripable ( ) ) ;
2005-09-25 14:42:24 -04:00
if ( ev - > button = = 1 ) {
2011-11-04 13:53:21 -04:00
if ( _selection . selected ( strip ) ) {
/* primary-click: toggle selection state of strip */
if ( Keyboard : : modifier_state_equals ( ev - > state , Keyboard : : PrimaryModifier ) ) {
2023-07-28 19:13:29 -04:00
_selection . remove ( strip , false ) ;
2016-07-06 13:37:30 -04:00
} else if ( _selection . axes . size ( ) > 1 ) {
2015-05-03 15:34:17 -04:00
/* de-select others */
_selection . set ( strip ) ;
}
2017-07-20 12:57:09 -04:00
PublicEditor & pe = PublicEditor : : instance ( ) ;
TimeAxisView * tav = pe . time_axis_view_from_stripable ( strip - > stripable ( ) ) ;
if ( tav ) {
pe . set_selected_mixer_strip ( * tav ) ;
}
2005-09-25 14:42:24 -04:00
} else {
2011-11-04 13:53:21 -04:00
if ( Keyboard : : modifier_state_equals ( ev - > state , Keyboard : : PrimaryModifier ) ) {
2017-07-12 00:55:44 -04:00
_selection . add ( strip , true ) ;
2011-11-04 13:53:21 -04:00
} else if ( Keyboard : : modifier_state_equals ( ev - > state , Keyboard : : RangeSelectModifier ) ) {
2016-06-05 20:50:40 -04:00
/* extend selection */
vector < MixerStrip * > tmp ;
bool accumulate = false ;
bool found_another = false ;
2017-06-16 17:45:16 -04:00
strips . sort ( MixerStripSorter ( ) ) ;
2017-01-26 08:08:58 -05:00
2017-06-16 17:45:16 -04:00
for ( list < MixerStrip * > : : iterator i = strips . begin ( ) ; i ! = strips . end ( ) ; + + i ) {
MixerStrip * ms = * i ;
2017-01-26 08:08:58 -05:00
assert ( ms ) ;
if ( ms = = strip ) {
2016-06-05 20:50:40 -04:00
/* hit clicked strip, start accumulating till we hit the first
selected strip
*/
if ( accumulate ) {
/* done */
break ;
2011-11-04 13:53:21 -04:00
} else {
2016-06-05 20:50:40 -04:00
accumulate = true ;
2011-11-04 13:53:21 -04:00
}
2017-01-26 08:08:58 -05:00
} else if ( _selection . selected ( ms ) ) {
2016-06-05 20:50:40 -04:00
/* hit selected strip. if currently accumulating others,
we ' re done . if not accumulating others , start doing so .
*/
found_another = true ;
if ( accumulate ) {
/* done */
break ;
} else {
accumulate = true ;
2014-11-19 18:27:13 -05:00
}
2016-06-05 20:50:40 -04:00
} else {
if ( accumulate ) {
2017-01-26 08:08:58 -05:00
tmp . push_back ( ms ) ;
2016-06-05 20:50:40 -04:00
}
}
2011-11-04 13:53:21 -04:00
}
2017-02-26 12:22:39 -05:00
tmp . push_back ( strip ) ;
2016-06-05 20:50:40 -04:00
if ( found_another ) {
2017-02-26 12:22:39 -05:00
PresentationInfo : : ChangeSuspender cs ;
2016-06-05 20:50:40 -04:00
for ( vector < MixerStrip * > : : iterator i = tmp . begin ( ) ; i ! = tmp . end ( ) ; + + i ) {
2017-07-12 00:55:44 -04:00
_selection . add ( * i , true ) ;
2016-06-05 20:50:40 -04:00
}
2017-02-26 12:22:39 -05:00
} else {
2016-06-05 20:50:40 -04:00
_selection . set ( strip ) ; //user wants to start a range selection, but there aren't any others selected yet
2017-02-26 12:22:39 -05:00
}
2005-09-25 14:42:24 -04:00
} else {
2011-11-04 13:53:21 -04:00
_selection . set ( strip ) ;
2005-09-25 14:42:24 -04:00
}
}
}
2006-01-04 22:18:44 -05:00
return true ;
2005-09-25 14:42:24 -04:00
}
2017-08-06 12:37:15 -04:00
bool
Mixer_UI : : vca_button_release_event ( GdkEventButton * ev , VCAMasterStrip * strip )
{
_selection . set ( strip ) ;
return true ;
}
2005-09-25 14:42:24 -04:00
void
2009-12-17 13:24:23 -05:00
Mixer_UI : : set_session ( Session * sess )
2005-09-25 14:42:24 -04:00
{
2009-12-17 13:24:23 -05:00
SessionHandlePtr : : set_session ( sess ) ;
2018-12-11 10:28:47 -05:00
_monitor_section . set_session ( sess ) ;
2009-12-17 13:24:23 -05:00
if ( _plugin_selector ) {
_plugin_selector - > set_session ( _session ) ;
}
_group_tabs - > set_session ( sess ) ;
2022-06-01 18:52:25 -04:00
update_scene_buttons ( ) ;
2024-01-02 08:26:56 -05:00
RefPtr < ToggleAction > surround_action = ActionManager : : get_toggle_action ( X_ ( " Mixer " ) , " ToggleSurroundMaster " ) ;
2023-12-07 11:43:26 -05:00
Glib : : RefPtr < Action > surround_export = ActionManager : : get_action ( X_ ( " Main " ) , X_ ( " SurroundExport " ) ) ;
2024-01-02 08:26:56 -05:00
2009-12-17 13:24:23 -05:00
if ( ! _session ) {
2024-01-02 08:26:56 -05:00
surround_action - > set_sensitive ( false ) ;
2023-12-07 11:43:26 -05:00
surround_export - > set_sensitive ( false ) ;
2022-12-27 10:53:01 -05:00
PBD : : Unwinder < bool > uw ( ignore_plugin_reorder , true ) ;
2020-11-24 23:33:16 -05:00
favorite_plugins_model - > clear ( ) ;
2017-05-05 07:31:49 -04:00
_selection . clear ( ) ;
2009-12-17 13:24:23 -05:00
return ;
}
2005-09-25 14:42:24 -04:00
2024-03-26 12:12:18 -04:00
if ( ! Profile - > get_livetrax ( ) ) {
refill_favorite_plugins ( ) ;
}
2016-01-08 16:07:21 -05:00
2006-08-30 16:48:16 -04:00
XMLNode * node = ARDOUR_UI : : instance ( ) - > mixer_settings ( ) ;
2015-07-07 22:12:21 -04:00
set_state ( * node , 0 ) ;
2006-08-30 16:48:16 -04:00
2011-09-07 11:07:02 -04:00
update_title ( ) ;
2005-09-25 14:42:24 -04:00
2024-01-02 08:26:56 -05:00
surround_action - > set_sensitive ( _session - > vapor_barrier ( ) ) ;
surround_action - > set_active ( nullptr ! = _session - > surround_master ( ) ) ;
2023-12-07 11:43:26 -05:00
surround_export - > set_sensitive ( _session - > vapor_export_barrier ( ) & & nullptr ! = _session - > surround_master ( ) ) ;
2024-01-02 08:26:56 -05:00
2021-02-07 06:05:31 -05:00
#if 0
/* skip mapping all session-config vars, we only need one */
boost : : function < void ( string ) > pc ( boost : : bind ( & Mixer_UI : : parameter_changed , this , _1 ) ) ;
_session - > config . map_parameters ( pc ) ;
# else
parameter_changed ( " show-group-tabs " ) ;
# endif
2006-01-11 22:43:52 -05:00
initial_track_display ( ) ;
2005-09-25 14:42:24 -04:00
2016-06-05 16:29:22 -04:00
_session - > RouteAdded . connect ( _session_connections , invalidator ( * this ) , boost : : bind ( & Mixer_UI : : add_routes , this , _1 ) , gui_context ( ) ) ;
2012-04-25 08:58:19 -04:00
_session - > route_group_added . connect ( _session_connections , invalidator ( * this ) , boost : : bind ( & Mixer_UI : : add_route_group , this , _1 ) , gui_context ( ) ) ;
2010-03-30 11:18:43 -04:00
_session - > route_group_removed . connect ( _session_connections , invalidator ( * this ) , boost : : bind ( & Mixer_UI : : route_groups_changed , this ) , gui_context ( ) ) ;
2011-04-19 11:46:47 -04:00
_session - > route_groups_reordered . connect ( _session_connections , invalidator ( * this ) , boost : : bind ( & Mixer_UI : : route_groups_changed , this ) , gui_context ( ) ) ;
2012-04-25 08:58:19 -04:00
_session - > config . ParameterChanged . connect ( _session_connections , invalidator ( * this ) , boost : : bind ( & Mixer_UI : : parameter_changed , this , _1 ) , gui_context ( ) ) ;
2011-09-07 11:07:02 -04:00
_session - > DirtyChanged . connect ( _session_connections , invalidator ( * this ) , boost : : bind ( & Mixer_UI : : update_title , this ) , gui_context ( ) ) ;
2012-04-25 08:58:19 -04:00
_session - > StateSaved . connect ( _session_connections , invalidator ( * this ) , boost : : bind ( & Mixer_UI : : update_title , this ) , gui_context ( ) ) ;
2024-02-23 11:04:25 -05:00
_session - > SurroundMasterAddedOrRemoved . connect ( _session_connections , invalidator ( * this ) , boost : : bind ( & Mixer_UI : : sync_surround_action , this ) , gui_context ( ) ) ;
2005-09-25 14:42:24 -04:00
2016-02-27 22:16:37 -05:00
_session - > vca_manager ( ) . VCAAdded . connect ( _session_connections , invalidator ( * this ) , boost : : bind ( & Mixer_UI : : add_masters , this , _1 ) , gui_context ( ) ) ;
2019-03-01 13:02:38 -05:00
_session - > vca_manager ( ) . VCACreated . connect ( _session_connections , invalidator ( * this ) , boost : : bind ( & Mixer_UI : : new_masters_created , this ) , gui_context ( ) ) ;
2016-02-27 22:16:37 -05:00
2022-06-01 18:19:32 -04:00
MixerScene : : Change . connect ( _session_connections , invalidator ( * this ) , boost : : bind ( & Mixer_UI : : update_scene_buttons , this ) , gui_context ( ) ) ;
2012-04-25 08:58:19 -04:00
Config - > ParameterChanged . connect ( * this , invalidator ( * this ) , boost : : bind ( & Mixer_UI : : parameter_changed , this , _1 ) , gui_context ( ) ) ;
2010-05-02 10:28:09 -04:00
2009-06-21 15:59:56 -04:00
route_groups_changed ( ) ;
2009-10-14 12:10:01 -04:00
2006-08-30 16:48:16 -04:00
if ( _visible ) {
2010-02-03 14:00:58 -05:00
show_window ( ) ;
2006-08-30 16:48:16 -04:00
}
2017-05-05 07:31:49 -04:00
/* catch up on selection state, etc. */
PropertyChange sc ;
sc . add ( Properties : : selected ) ;
_selection . presentation_info_changed ( sc ) ;
2005-09-25 14:42:24 -04:00
start_updating ( ) ;
}
void
2009-12-17 13:24:23 -05:00
Mixer_UI : : session_going_away ( )
2005-09-25 14:42:24 -04:00
{
2011-04-19 21:24:40 -04:00
ENSURE_GUI_THREAD ( * this , & Mixer_UI : : session_going_away ) ;
2009-10-14 12:10:01 -04:00
2011-04-19 21:24:40 -04:00
_in_group_rebuild_or_clear = true ;
2006-03-09 18:44:39 -05:00
group_model - > clear ( ) ;
2011-04-19 21:24:40 -04:00
_in_group_rebuild_or_clear = false ;
2011-06-01 13:00:29 -04:00
2007-04-11 09:07:51 -04:00
_selection . clear ( ) ;
2009-12-22 15:21:43 -05:00
track_model - > clear ( ) ;
for ( list < MixerStrip * > : : iterator i = strips . begin ( ) ; i ! = strips . end ( ) ; + + i ) {
delete ( * i ) ;
}
2010-03-10 12:31:16 -05:00
2018-12-11 10:28:47 -05:00
_monitor_section . tearoff ( ) . hide_visible ( ) ;
2019-01-18 13:22:54 -05:00
StripableList fb ;
_session - > get_stripables ( fb , PresentationInfo : : FoldbackBus ) ;
if ( fb . size ( ) ) {
if ( foldback_strip ) {
delete foldback_strip ;
foldback_strip = 0 ;
}
}
2015-12-19 11:42:36 -05:00
monitor_section_detached ( ) ;
2010-03-18 22:49:01 -04:00
2009-12-23 23:04:01 -05:00
strips . clear ( ) ;
2007-04-11 09:07:51 -04:00
2005-09-25 14:42:24 -04:00
stop_updating ( ) ;
2009-12-17 13:24:23 -05:00
SessionHandlePtr : : session_going_away ( ) ;
2011-09-07 11:07:02 -04:00
_session = 0 ;
update_title ( ) ;
2005-09-25 14:42:24 -04:00
}
2012-07-19 18:35:43 -04:00
void
Mixer_UI : : track_visibility_changed ( std : : string const & path )
{
if ( _session & & _session - > deletion_in_progress ( ) ) {
return ;
}
TreeIter iter ;
if ( ( iter = track_model - > get_iter ( path ) ) ) {
2016-06-09 16:03:07 -04:00
2016-06-05 16:29:22 -04:00
AxisView * av = ( * iter ) [ stripable_columns . strip ] ;
2016-06-09 16:03:07 -04:00
bool visible = ( * iter ) [ stripable_columns . visible ] ;
2012-07-19 18:35:43 -04:00
2016-06-09 16:03:07 -04:00
if ( av - > set_marked_for_display ( ! visible ) ) {
update_track_visibility ( ) ;
2012-07-19 18:35:43 -04:00
}
}
}
void
Mixer_UI : : update_track_visibility ( )
{
TreeModel : : Children rows = track_model - > children ( ) ;
TreeModel : : Children : : iterator i ;
{
Unwinder < bool > uw ( no_track_list_redisplay , true ) ;
2015-10-05 10:17:49 -04:00
2012-07-19 18:35:43 -04:00
for ( i = rows . begin ( ) ; i ! = rows . end ( ) ; + + i ) {
2016-06-05 16:29:22 -04:00
AxisView * av = ( * i ) [ stripable_columns . strip ] ;
2016-06-09 16:03:07 -04:00
( * i ) [ stripable_columns . visible ] = av - > marked_for_display ( ) ;
2012-07-19 18:35:43 -04:00
}
2015-10-05 10:17:49 -04:00
2019-08-30 16:56:07 -04:00
/* force presentation to catch up with visibility changes */
2016-05-16 07:30:28 -04:00
sync_presentation_info_from_treeview ( ) ;
2012-07-19 18:35:43 -04:00
}
redisplay_track_list ( ) ;
}
2005-09-25 14:42:24 -04:00
void
2006-01-11 22:43:52 -05:00
Mixer_UI : : show_strip ( MixerStrip * ms )
2005-09-25 14:42:24 -04:00
{
2006-11-12 22:49:00 -05:00
TreeModel : : Children rows = track_model - > children ( ) ;
2005-09-28 12:22:43 -04:00
TreeModel : : Children : : iterator i ;
2009-10-14 12:10:01 -04:00
2005-09-28 12:22:43 -04:00
for ( i = rows . begin ( ) ; i ! = rows . end ( ) ; + + i ) {
2009-10-14 12:10:01 -04:00
2016-06-05 16:29:22 -04:00
AxisView * av = ( * i ) [ stripable_columns . strip ] ;
MixerStrip * strip = dynamic_cast < MixerStrip * > ( av ) ;
2006-01-11 22:43:52 -05:00
if ( strip = = ms ) {
2016-06-05 16:29:22 -04:00
( * i ) [ stripable_columns . visible ] = true ;
2016-07-08 14:42:49 -04:00
av - > set_marked_for_display ( true ) ;
update_track_visibility ( ) ;
2006-01-11 22:43:52 -05:00
break ;
}
2005-09-25 14:42:24 -04:00
}
}
void
2006-01-11 22:43:52 -05:00
Mixer_UI : : hide_strip ( MixerStrip * ms )
2005-09-25 14:42:24 -04:00
{
2006-11-12 22:49:00 -05:00
TreeModel : : Children rows = track_model - > children ( ) ;
2005-09-28 12:22:43 -04:00
TreeModel : : Children : : iterator i ;
2009-10-14 12:10:01 -04:00
2005-09-28 12:22:43 -04:00
for ( i = rows . begin ( ) ; i ! = rows . end ( ) ; + + i ) {
2009-10-14 12:10:01 -04:00
2016-06-05 16:29:22 -04:00
AxisView * av = ( * i ) [ stripable_columns . strip ] ;
MixerStrip * strip = dynamic_cast < MixerStrip * > ( av ) ;
2006-01-11 22:43:52 -05:00
if ( strip = = ms ) {
2016-06-05 16:29:22 -04:00
( * i ) [ stripable_columns . visible ] = false ;
2016-07-08 14:42:49 -04:00
av - > set_marked_for_display ( false ) ;
update_track_visibility ( ) ;
2006-01-11 22:43:52 -05:00
break ;
2005-09-25 14:42:24 -04:00
}
2006-11-12 22:49:00 -05:00
}
}
gint
Mixer_UI : : start_updating ( )
{
2017-07-01 12:42:24 -04:00
fast_screen_update_connection = Timers : : super_rapid_connect ( sigc : : mem_fun ( * this , & Mixer_UI : : fast_update_strips ) ) ;
return 0 ;
2006-11-12 22:49:00 -05:00
}
gint
Mixer_UI : : stop_updating ( )
{
2017-07-01 12:42:24 -04:00
fast_screen_update_connection . disconnect ( ) ;
return 0 ;
2006-11-12 22:49:00 -05:00
}
void
Mixer_UI : : fast_update_strips ( )
{
2023-11-10 17:50:44 -05:00
if ( ! UIConfiguration : : instance ( ) . get_no_strobe ( ) & & _content . get_mapped ( ) & & _session ) {
2023-11-10 12:56:03 -05:00
for ( auto & s : strips ) {
s - > fast_update ( ) ;
2006-11-12 22:49:00 -05:00
}
2020-05-07 20:12:36 -04:00
if ( foldback_strip ) {
foldback_strip - > fast_update ( ) ;
}
2024-01-02 08:26:56 -05:00
if ( _surround_strip ) {
_surround_strip - > fast_update ( ) ;
}
2006-11-12 22:49:00 -05:00
}
}
2005-11-29 17:48:54 -05:00
2006-01-11 22:43:52 -05:00
void
Mixer_UI : : set_all_strips_visibility ( bool yn )
{
2006-11-12 22:49:00 -05:00
TreeModel : : Children rows = track_model - > children ( ) ;
2006-01-11 22:43:52 -05:00
TreeModel : : Children : : iterator i ;
2005-11-29 17:48:54 -05:00
2012-06-27 18:57:06 -04:00
{
Unwinder < bool > uw ( no_track_list_redisplay , true ) ;
2015-10-05 10:17:49 -04:00
2012-06-27 18:57:06 -04:00
for ( i = rows . begin ( ) ; i ! = rows . end ( ) ; + + i ) {
2015-10-05 10:17:49 -04:00
2016-06-05 16:29:22 -04:00
AxisView * av = ( * i ) [ stripable_columns . strip ] ;
MixerStrip * strip = dynamic_cast < MixerStrip * > ( av ) ;
2015-10-05 10:17:49 -04:00
2016-02-27 22:16:37 -05:00
if ( ! strip ) {
2012-06-27 18:57:06 -04:00
continue ;
}
2015-10-05 10:17:49 -04:00
2023-11-26 22:26:46 -05:00
if ( strip - > route ( ) - > is_singleton ( ) ) {
2012-06-27 18:57:06 -04:00
continue ;
}
2015-10-05 10:17:49 -04:00
2016-06-05 16:29:22 -04:00
( * i ) [ stripable_columns . visible ] = yn ;
2006-01-11 22:43:52 -05:00
}
2019-08-30 16:56:07 -04:00
/* force presentation to catch up with visibility changes */
sync_presentation_info_from_treeview ( ) ;
2006-01-11 22:43:52 -05:00
}
2005-11-29 17:48:54 -05:00
2006-01-11 22:43:52 -05:00
redisplay_track_list ( ) ;
}
void
2015-07-10 05:11:44 -04:00
Mixer_UI : : set_all_audio_midi_visibility ( int tracks , bool yn )
2006-01-11 22:43:52 -05:00
{
2009-10-22 18:38:53 -04:00
TreeModel : : Children rows = track_model - > children ( ) ;
2006-01-11 22:43:52 -05:00
TreeModel : : Children : : iterator i ;
2012-06-27 18:57:06 -04:00
{
Unwinder < bool > uw ( no_track_list_redisplay , true ) ;
2015-10-05 10:17:49 -04:00
2012-06-27 18:57:06 -04:00
for ( i = rows . begin ( ) ; i ! = rows . end ( ) ; + + i ) {
2016-06-05 16:29:22 -04:00
AxisView * av = ( * i ) [ stripable_columns . strip ] ;
MixerStrip * strip = dynamic_cast < MixerStrip * > ( av ) ;
2015-10-05 10:17:49 -04:00
2016-02-27 22:16:37 -05:00
if ( ! strip ) {
2012-06-27 18:57:06 -04:00
continue ;
2006-01-11 22:43:52 -05:00
}
2015-10-05 10:17:49 -04:00
2023-11-26 22:26:46 -05:00
if ( strip - > route ( ) - > is_singleton ( ) ) {
2012-06-27 18:57:06 -04:00
continue ;
}
2015-10-05 10:17:49 -04:00
2023-02-16 18:33:28 -05:00
std : : shared_ptr < AudioTrack > at = strip - > audio_track ( ) ;
std : : shared_ptr < MidiTrack > mt = strip - > midi_track ( ) ;
2015-10-05 10:17:49 -04:00
2012-06-27 18:57:06 -04:00
switch ( tracks ) {
case 0 :
2016-06-05 16:29:22 -04:00
( * i ) [ stripable_columns . visible ] = yn ;
2012-06-27 18:57:06 -04:00
break ;
2015-10-05 10:17:49 -04:00
2012-06-27 18:57:06 -04:00
case 1 :
if ( at ) { /* track */
2016-06-05 16:29:22 -04:00
( * i ) [ stripable_columns . visible ] = yn ;
2012-06-27 18:57:06 -04:00
}
break ;
2015-10-05 10:17:49 -04:00
2012-06-27 18:57:06 -04:00
case 2 :
2015-07-10 05:11:44 -04:00
if ( ! at & & ! mt ) { /* bus */
2016-06-05 16:29:22 -04:00
( * i ) [ stripable_columns . visible ] = yn ;
2015-07-10 05:11:44 -04:00
}
break ;
case 3 :
if ( mt ) { /* midi-track */
2016-06-05 16:29:22 -04:00
( * i ) [ stripable_columns . visible ] = yn ;
2012-06-27 18:57:06 -04:00
}
break ;
2006-01-11 22:43:52 -05:00
}
}
2019-08-30 16:56:07 -04:00
/* force presentation to catch up with visibility changes */
sync_presentation_info_from_treeview ( ) ;
2006-01-11 22:43:52 -05:00
}
redisplay_track_list ( ) ;
}
void
Mixer_UI : : hide_all_routes ( )
{
set_all_strips_visibility ( false ) ;
}
void
Mixer_UI : : show_all_routes ( )
{
set_all_strips_visibility ( true ) ;
}
void
Mixer_UI : : show_all_audiobus ( )
{
2015-07-10 05:11:44 -04:00
set_all_audio_midi_visibility ( 2 , true ) ;
2006-01-11 22:43:52 -05:00
}
void
Mixer_UI : : hide_all_audiobus ( )
{
2015-07-10 05:11:44 -04:00
set_all_audio_midi_visibility ( 2 , false ) ;
2006-01-11 22:43:52 -05:00
}
void
Mixer_UI : : show_all_audiotracks ( )
{
2015-07-10 05:11:44 -04:00
set_all_audio_midi_visibility ( 1 , true ) ;
2006-01-11 22:43:52 -05:00
}
void
Mixer_UI : : hide_all_audiotracks ( )
{
2015-07-10 05:11:44 -04:00
set_all_audio_midi_visibility ( 1 , false ) ;
}
void
Mixer_UI : : show_all_miditracks ( )
{
set_all_audio_midi_visibility ( 3 , true ) ;
}
void
Mixer_UI : : hide_all_miditracks ( )
{
set_all_audio_midi_visibility ( 3 , false ) ;
2006-01-11 22:43:52 -05:00
}
2007-10-11 18:07:47 -04:00
void
2009-07-21 11:55:17 -04:00
Mixer_UI : : track_list_reorder ( const TreeModel : : Path & , const TreeModel : : iterator & , int * /*new_order*/ )
2007-10-11 18:07:47 -04:00
{
2012-06-27 18:57:06 -04:00
DEBUG_TRACE ( DEBUG : : OrderKeys , " mixer UI treeview reordered \n " ) ;
2016-05-16 07:30:28 -04:00
sync_presentation_info_from_treeview ( ) ;
2006-01-11 22:43:52 -05:00
}
void
2009-07-21 11:55:17 -04:00
Mixer_UI : : track_list_delete ( const Gtk : : TreeModel : : Path & )
2006-01-11 22:43:52 -05:00
{
2012-06-27 18:57:06 -04:00
/* this happens as the second step of a DnD within the treeview as well
as when a row / route is actually deleted .
2015-10-04 14:51:05 -04:00
2014-06-20 21:51:59 -04:00
if it was a deletion then we have to force a redisplay because
order keys may not have changed .
2012-06-27 18:57:06 -04:00
*/
2014-06-20 21:51:59 -04:00
2012-06-27 18:57:06 -04:00
DEBUG_TRACE ( DEBUG : : OrderKeys , " mixer UI treeview row deleted \n " ) ;
2014-06-20 21:51:59 -04:00
2017-07-01 12:42:24 -04:00
if ( _route_deletion_in_progress ) {
redisplay_track_list ( ) ;
2022-01-25 21:18:37 -05:00
} else {
sync_presentation_info_from_treeview ( ) ;
2017-07-01 12:42:24 -04:00
}
2022-01-25 21:18:37 -05:00
2006-01-11 22:43:52 -05:00
}
void
2023-02-16 18:33:28 -05:00
Mixer_UI : : spill_redisplay ( std : : shared_ptr < Stripable > s )
2006-01-11 22:43:52 -05:00
{
2020-03-23 16:13:39 -04:00
2023-02-16 18:33:28 -05:00
std : : shared_ptr < VCA > vca = std : : dynamic_pointer_cast < VCA > ( s ) ;
std : : shared_ptr < Route > r = std : : dynamic_pointer_cast < Route > ( s ) ;
2020-03-23 16:13:39 -04:00
2006-03-09 18:44:39 -05:00
TreeModel : : Children rows = track_model - > children ( ) ;
2023-02-16 18:33:28 -05:00
std : : list < std : : shared_ptr < VCA > > vcas ;
2015-10-05 10:17:49 -04:00
2020-03-23 16:13:39 -04:00
if ( vca ) {
vcas . push_back ( vca ) ;
for ( TreeModel : : Children : : const_iterator i = rows . begin ( ) ; i ! = rows . end ( ) ; + + i ) {
AxisView * av = ( * i ) [ stripable_columns . strip ] ;
VCAMasterStrip * vms = dynamic_cast < VCAMasterStrip * > ( av ) ;
if ( vms & & vms - > vca ( ) - > slaved_to ( vca ) ) {
vcas . push_back ( vms - > vca ( ) ) ;
}
2016-12-21 19:05:53 -05:00
}
}
for ( TreeModel : : Children : : const_iterator i = rows . begin ( ) ; i ! = rows . end ( ) ; + + i ) {
2016-05-18 17:36:06 -04:00
2016-06-05 16:29:22 -04:00
AxisView * av = ( * i ) [ stripable_columns . strip ] ;
MixerStrip * strip = dynamic_cast < MixerStrip * > ( av ) ;
2017-02-17 18:09:52 -05:00
bool const visible = ( * i ) [ stripable_columns . visible ] ;
2020-03-23 16:13:39 -04:00
bool slaved = false ;
bool feeds = false ;
2016-05-18 17:36:06 -04:00
if ( ! strip ) {
/* we're in the middle of changing a row, don't worry */
continue ;
}
if ( ! strip - > route ( ) ) {
/* non-route element */
continue ;
}
if ( strip - > route ( ) - > is_master ( ) | | strip - > route ( ) - > is_monitor ( ) ) {
continue ;
}
2020-03-23 16:13:39 -04:00
if ( vca ) {
2023-02-16 18:33:28 -05:00
for ( std : : list < std : : shared_ptr < VCA > > : : const_iterator m = vcas . begin ( ) ; m ! = vcas . end ( ) ; + + m ) {
2020-03-23 16:13:39 -04:00
if ( strip - > route ( ) - > slaved_to ( * m ) ) {
slaved = true ;
break ;
}
2016-12-21 19:05:53 -05:00
}
}
2021-03-27 16:29:37 -04:00
# ifdef MIXBUS
if ( r & & r - > mixbus ( ) ) {
feeds = strip - > route ( ) - > mb_feeds ( r ) ;
} else
# endif
2020-03-23 16:13:39 -04:00
if ( r ) {
2021-03-27 16:29:37 -04:00
feeds = strip - > route ( ) - > direct_feeds_according_to_graph ( r ) ;
2020-03-23 16:13:39 -04:00
}
bool should_show = visible & & ( slaved | | feeds ) ;
should_show | = ( strip - > route ( ) = = r ) ; //the spilled aux should itself be shown...
if ( should_show ) {
2016-05-18 17:36:06 -04:00
if ( strip - > packed ( ) ) {
strip_packer . reorder_child ( * strip , - 1 ) ; /* put at end */
} else {
strip_packer . pack_start ( * strip , false , false ) ;
strip - > set_packed ( true ) ;
}
} else {
if ( strip - > packed ( ) ) {
strip_packer . remove ( * strip ) ;
strip - > set_packed ( false ) ;
}
}
}
}
void
Mixer_UI : : redisplay_track_list ( )
{
2006-01-11 22:43:52 -05:00
if ( no_track_list_redisplay ) {
return ;
}
2023-02-16 18:33:28 -05:00
std : : shared_ptr < Stripable > ss = spilled_strip . lock ( ) ;
2017-01-16 16:30:26 -05:00
if ( ss ) {
2023-02-16 18:33:28 -05:00
std : : shared_ptr < VCA > sv = std : : dynamic_pointer_cast < VCA > ( ss ) ;
2017-01-16 16:30:26 -05:00
if ( sv ) {
2018-09-01 15:32:57 -04:00
if ( _spill_scroll_position < = 0 & & scroller . get_hscrollbar ( ) ) {
_spill_scroll_position = scroller . get_hscrollbar ( ) - > get_adjustment ( ) - > get_value ( ) ;
}
2017-01-16 16:30:26 -05:00
spill_redisplay ( sv ) ;
return ;
2020-03-23 16:13:39 -04:00
} else {
if ( _spill_scroll_position < = 0 & & scroller . get_hscrollbar ( ) ) {
_spill_scroll_position = scroller . get_hscrollbar ( ) - > get_adjustment ( ) - > get_value ( ) ;
}
spill_redisplay ( ss ) ;
return ;
2017-01-16 16:30:26 -05:00
}
2016-05-18 17:36:06 -04:00
}
TreeModel : : Children rows = track_model - > children ( ) ;
TreeModel : : Children : : iterator i ;
uint32_t n_masters = 0 ;
2016-06-07 12:30:38 -04:00
container_clear ( vca_hpacker ) ;
2018-02-12 16:50:35 -05:00
2016-06-07 12:30:38 -04:00
vca_hpacker . pack_end ( vca_scroller_base , true , true ) ;
2021-03-26 07:46:42 -04:00
vca_scroller_base . set_size_request ( PX_SCALE ( 20 ) , - 1 ) ;
2022-01-28 17:38:08 -05:00
vca_scroller_base . signal_expose_event ( ) . connect ( sigc : : bind ( sigc : : ptr_fun ( & ArdourWidgets : : ArdourIcon : : expose_with_text ) , & vca_scroller_base , ArdourWidgets : : ArdourIcon : : ShadedPlusSign ,
_ ( " Right-click or Double-click here \n to add Track, Bus, or VCA channels " ) ) ) ;
2018-02-12 16:50:35 -05:00
vca_scroller_base . show ( ) ;
2018-02-24 07:54:15 -05:00
2012-06-25 08:46:13 -04:00
for ( i = rows . begin ( ) ; i ! = rows . end ( ) ; + + i ) {
2016-06-05 16:29:22 -04:00
AxisView * s = ( * i ) [ stripable_columns . strip ] ;
2016-06-09 16:03:07 -04:00
bool const visible = ( * i ) [ stripable_columns . visible ] ;
2023-02-16 18:33:28 -05:00
std : : shared_ptr < Stripable > stripable = ( * i ) [ stripable_columns . stripable ] ;
2016-06-05 16:29:22 -04:00
if ( ! s ) {
/* we're in the middle of changing a row, don't worry */
continue ;
}
VCAMasterStrip * vms ;
2016-02-27 22:16:37 -05:00
2016-06-05 16:29:22 -04:00
if ( ( vms = dynamic_cast < VCAMasterStrip * > ( s ) ) ) {
2016-06-09 16:03:07 -04:00
if ( visible ) {
vca_hpacker . pack_start ( * vms , false , false ) ;
vms - > show ( ) ;
n_masters + + ;
}
2016-02-27 22:16:37 -05:00
continue ;
}
2016-06-05 16:29:22 -04:00
MixerStrip * strip = dynamic_cast < MixerStrip * > ( s ) ;
2006-01-11 22:43:52 -05:00
2016-02-27 22:16:37 -05:00
if ( ! strip ) {
2006-01-17 11:40:57 -05:00
continue ;
}
2006-01-11 22:43:52 -05:00
if ( visible ) {
2007-10-11 18:07:47 -04:00
2006-01-11 22:43:52 -05:00
if ( strip - > packed ( ) ) {
2016-06-10 14:44:57 -04:00
strip_packer . reorder_child ( * strip , - 1 ) ; /* put at end */
2006-01-11 22:43:52 -05:00
} else {
2016-06-10 14:44:57 -04:00
strip_packer . pack_start ( * strip , false , false ) ;
2006-01-11 22:43:52 -05:00
strip - > set_packed ( true ) ;
}
} else {
2023-11-26 22:26:46 -05:00
if ( stripable - > is_singleton ( ) ) {
2006-01-11 22:43:52 -05:00
/* do nothing, these cannot be hidden */
} else {
2007-04-11 09:07:51 -04:00
if ( strip - > packed ( ) ) {
strip_packer . remove ( * strip ) ;
strip - > set_packed ( false ) ;
}
2006-01-11 22:43:52 -05:00
}
2005-09-25 14:42:24 -04:00
}
}
2009-10-14 12:10:01 -04:00
2016-04-29 10:33:05 -04:00
/* update visibility of VCA assign buttons */
if ( n_masters = = 0 ) {
2018-12-03 19:55:52 -05:00
//show/hide the channelstrip VCA assign buttons on channelstrips:
2016-04-29 10:33:05 -04:00
UIConfiguration : : instance ( ) . set_mixer_strip_visibility ( VisibilityGroup : : remove_element ( UIConfiguration : : instance ( ) . get_mixer_strip_visibility ( ) , X_ ( " VCA " ) ) ) ;
2018-12-03 19:55:52 -05:00
2018-12-10 08:33:31 -05:00
Glib : : RefPtr < Action > act = ActionManager : : get_action ( " Mixer " , " ToggleVCAPane " ) ;
2018-08-09 12:52:20 -04:00
if ( act ) {
act - > set_sensitive ( false ) ;
}
2018-12-03 19:55:52 -05:00
//remove the VCA packer, but don't change our prior setting for show/hide:
vca_vpacker . hide ( ) ;
2016-04-29 10:33:05 -04:00
} else {
2018-12-03 19:55:52 -05:00
//show/hide the channelstrip VCA assign buttons on channelstrips:
2016-04-29 10:33:05 -04:00
UIConfiguration : : instance ( ) . set_mixer_strip_visibility ( VisibilityGroup : : add_element ( UIConfiguration : : instance ( ) . get_mixer_strip_visibility ( ) , X_ ( " VCA " ) ) ) ;
2018-08-09 11:28:54 -04:00
2018-12-11 23:43:22 -05:00
Glib : : RefPtr < ToggleAction > act = ActionManager : : get_toggle_action ( " Mixer " , " ToggleVCAPane " ) ;
2018-12-03 19:55:52 -05:00
act - > set_sensitive ( true ) ;
//if we were showing VCAs before, show them now:
2018-12-11 23:43:22 -05:00
showhide_vcas ( act - > get_active ( ) ) ;
2016-04-29 10:33:05 -04:00
}
2009-06-20 13:15:33 -04:00
_group_tabs - > set_dirty ( ) ;
2018-09-01 15:32:57 -04:00
if ( _spill_scroll_position > 0 & & scroller . get_hscrollbar ( ) ) {
Adjustment * adj = scroller . get_hscrollbar ( ) - > get_adjustment ( ) ;
adj - > set_value ( max ( adj - > get_lower ( ) , min ( adj - > get_upper ( ) , _spill_scroll_position ) ) ) ;
}
_spill_scroll_position = 0 ;
2024-01-15 16:40:35 -05:00
if ( _surround_strip ) {
out_packer . reorder_child ( * _surround_strip , - 1 ) ;
}
2024-01-28 15:59:14 -05:00
if ( _monitor_section . tearoff ( ) . get_parent ( ) ) {
out_packer . reorder_child ( _monitor_section . tearoff ( ) , - 1 ) ;
}
2008-04-11 10:06:50 -04:00
}
2008-12-12 09:43:24 -05:00
void
2009-06-23 19:05:14 -04:00
Mixer_UI : : strip_width_changed ( )
2008-12-12 09:43:24 -05:00
{
2009-06-23 19:05:14 -04:00
_group_tabs - > set_dirty ( ) ;
2009-10-14 12:10:01 -04:00
2015-10-27 13:43:31 -04:00
# ifdef __APPLE__
2008-12-12 09:43:24 -05:00
TreeModel : : Children rows = track_model - > children ( ) ;
TreeModel : : Children : : iterator i ;
long order ;
for ( order = 0 , i = rows . begin ( ) ; i ! = rows . end ( ) ; + + i , + + order ) {
2016-06-05 18:00:28 -04:00
AxisView * av = ( * i ) [ stripable_columns . strip ] ;
MixerStrip * strip = dynamic_cast < MixerStrip * > ( av ) ;
2008-12-12 09:43:24 -05:00
if ( strip = = 0 ) {
continue ;
}
2016-06-05 16:29:22 -04:00
bool visible = ( * i ) [ stripable_columns . visible ] ;
2009-10-14 12:10:01 -04:00
2008-12-12 09:43:24 -05:00
if ( visible ) {
strip - > queue_draw ( ) ;
}
}
# endif
2009-10-14 12:10:01 -04:00
2009-06-23 19:05:14 -04:00
}
2008-12-12 09:43:24 -05:00
2016-06-05 16:29:22 -04:00
struct PresentationInfoMixerSorter
2016-05-16 07:30:28 -04:00
{
2023-02-16 18:33:28 -05:00
bool operator ( ) ( std : : shared_ptr < Stripable > a , std : : shared_ptr < Stripable > b ) {
2016-06-05 16:29:22 -04:00
if ( a - > is_master ( ) ) {
/* master after everything else */
return false ;
} else if ( b - > is_master ( ) ) {
/* everything else before master */
return true ;
}
2016-06-03 15:15:30 -04:00
return a - > presentation_info ( ) . order ( ) < b - > presentation_info ( ) . order ( ) ;
2016-05-16 07:30:28 -04:00
}
} ;
2006-01-11 22:43:52 -05:00
void
Mixer_UI : : initial_track_display ( )
{
2016-06-05 16:29:22 -04:00
StripableList sl ;
2019-01-18 13:22:54 -05:00
StripableList fb ;
2018-11-07 16:05:05 -05:00
_session - > get_stripables ( sl ) ;
2019-01-18 13:22:54 -05:00
_session - > get_stripables ( fb , PresentationInfo : : FoldbackBus ) ;
if ( fb . size ( ) ) {
2023-02-16 18:33:28 -05:00
std : : shared_ptr < ARDOUR : : Stripable > _current_foldback = * ( fb . begin ( ) ) ;
2019-01-18 13:22:54 -05:00
sl . push_back ( _current_foldback ) ;
}
2016-06-05 16:29:22 -04:00
sl . sort ( PresentationInfoMixerSorter ( ) ) ;
2009-10-14 12:10:01 -04:00
2012-06-27 18:57:06 -04:00
{
2016-06-05 16:29:22 -04:00
/* These are also used inside ::add_stripables() but we need
* them here because we ' re going to clear the track_model also .
*/
2012-06-27 18:57:06 -04:00
Unwinder < bool > uw1 ( no_track_list_redisplay , true ) ;
2020-06-24 20:26:01 -04:00
Unwinder < bool > uw2 ( ignore_track_reorder , true ) ;
2006-01-11 22:43:52 -05:00
2012-06-27 18:57:06 -04:00
track_model - > clear ( ) ;
2016-06-05 16:29:22 -04:00
add_stripables ( sl ) ;
2012-06-27 18:57:06 -04:00
}
2015-10-05 10:17:49 -04:00
2017-01-27 13:18:33 -05:00
sync_treeview_from_presentation_info ( Properties : : order ) ;
2006-01-11 22:43:52 -05:00
}
bool
Mixer_UI : : track_display_button_press ( GdkEventButton * ev )
{
if ( Keyboard : : is_context_menu_event ( ev ) ) {
2017-03-15 21:25:53 -04:00
if ( track_menu = = 0 ) {
build_track_menu ( ) ;
}
track_menu - > popup ( ev - > button , ev - > time ) ;
2006-01-11 22:43:52 -05:00
return true ;
}
2016-10-15 17:16:09 -04:00
if ( ( ev - > type = = GDK_BUTTON_PRESS ) & & ( ev - > button = = 1 ) ) {
TreeModel : : Path path ;
TreeViewColumn * column ;
int cellx , celly ;
if ( track_display . get_path_at_pos ( ( int ) ev - > x , ( int ) ev - > y , path , column , cellx , celly ) ) {
TreeIter iter = track_model - > get_iter ( path ) ;
if ( ( * iter ) [ stripable_columns . visible ] ) {
2023-02-16 18:33:28 -05:00
std : : shared_ptr < ARDOUR : : Stripable > s = ( * iter ) [ stripable_columns . stripable ] ;
2016-10-15 17:16:09 -04:00
move_stripable_into_view ( s ) ;
}
}
}
2006-01-11 22:43:52 -05:00
return false ;
2005-09-25 14:42:24 -04:00
}
2019-03-13 20:29:10 -04:00
void
2023-02-16 18:33:28 -05:00
Mixer_UI : : move_vca_into_view ( std : : shared_ptr < ARDOUR : : Stripable > s )
2019-03-13 20:29:10 -04:00
{
if ( ! vca_scroller . get_hscrollbar ( ) ) {
return ;
}
bool found = false ;
int x0 = 0 ;
Gtk : : Allocation alloc ;
TreeModel : : Children rows = track_model - > children ( ) ;
for ( TreeModel : : Children : : const_iterator i = rows . begin ( ) ; i ! = rows . end ( ) ; + + i ) {
AxisView * av = ( * i ) [ stripable_columns . strip ] ;
VCAMasterStrip * vms = dynamic_cast < VCAMasterStrip * > ( av ) ;
if ( vms & & vms - > stripable ( ) = = s ) {
int y ;
found = true ;
vms - > translate_coordinates ( vca_hpacker , 0 , 0 , x0 , y ) ;
alloc = vms - > get_allocation ( ) ;
break ;
}
}
if ( ! found ) {
return ;
}
Adjustment * adj = vca_scroller . get_hscrollbar ( ) - > get_adjustment ( ) ;
if ( x0 < adj - > get_value ( ) ) {
adj - > set_value ( max ( adj - > get_lower ( ) , min ( adj - > get_upper ( ) , ( double ) x0 ) ) ) ;
} else if ( x0 + alloc . get_width ( ) > = adj - > get_value ( ) + adj - > get_page_size ( ) ) {
int x1 = x0 + alloc . get_width ( ) - adj - > get_page_size ( ) ;
adj - > set_value ( max ( adj - > get_lower ( ) , min ( adj - > get_upper ( ) , ( double ) x1 ) ) ) ;
}
}
2016-10-15 17:16:09 -04:00
void
2023-02-16 18:33:28 -05:00
Mixer_UI : : move_stripable_into_view ( std : : shared_ptr < ARDOUR : : Stripable > s )
2016-10-15 17:16:09 -04:00
{
if ( ! scroller . get_hscrollbar ( ) ) {
return ;
}
2019-03-13 20:29:10 -04:00
if ( s - > presentation_info ( ) . special ( ) ) {
2016-12-21 04:59:58 -05:00
return ;
}
2019-03-13 20:29:10 -04:00
if ( s - > presentation_info ( ) . flag_match ( PresentationInfo : : VCA ) ) {
move_vca_into_view ( s ) ;
}
2016-12-21 06:14:44 -05:00
# ifdef MIXBUS
if ( s - > mixbus ( ) ) {
return ;
}
# endif
2016-10-15 17:16:09 -04:00
bool found = false ;
int x0 = 0 ;
2017-01-28 11:08:40 -05:00
Gtk : : Allocation alloc ;
2016-10-15 17:16:09 -04:00
for ( list < MixerStrip * > : : const_iterator i = strips . begin ( ) ; i ! = strips . end ( ) ; + + i ) {
if ( ( * i ) - > route ( ) = = s ) {
int y ;
found = true ;
( * i ) - > translate_coordinates ( strip_packer , 0 , 0 , x0 , y ) ;
2017-01-28 11:08:40 -05:00
alloc = ( * i ) - > get_allocation ( ) ;
2016-10-15 17:16:09 -04:00
break ;
}
}
if ( ! found ) {
return ;
}
Adjustment * adj = scroller . get_hscrollbar ( ) - > get_adjustment ( ) ;
2017-01-28 10:48:20 -05:00
2017-01-30 05:46:55 -05:00
if ( x0 < adj - > get_value ( ) ) {
2017-01-28 10:48:20 -05:00
adj - > set_value ( max ( adj - > get_lower ( ) , min ( adj - > get_upper ( ) , ( double ) x0 ) ) ) ;
2017-01-30 05:46:55 -05:00
} else if ( x0 + alloc . get_width ( ) > = adj - > get_value ( ) + adj - > get_page_size ( ) ) {
int x1 = x0 + alloc . get_width ( ) - adj - > get_page_size ( ) ;
adj - > set_value ( max ( adj - > get_lower ( ) , min ( adj - > get_upper ( ) , ( double ) x1 ) ) ) ;
2017-01-28 10:48:20 -05:00
}
2016-10-15 17:16:09 -04:00
}
2005-09-25 14:42:24 -04:00
void
Mixer_UI : : build_track_menu ( )
{
using namespace Menu_Helpers ;
using namespace Gtk ;
track_menu = new Menu ;
track_menu - > set_name ( " ArdourContextMenu " ) ;
MenuList & items = track_menu - > items ( ) ;
2009-10-14 12:10:01 -04:00
2009-12-11 18:29:48 -05:00
items . push_back ( MenuElem ( _ ( " Show All " ) , sigc : : mem_fun ( * this , & Mixer_UI : : show_all_routes ) ) ) ;
items . push_back ( MenuElem ( _ ( " Hide All " ) , sigc : : mem_fun ( * this , & Mixer_UI : : hide_all_routes ) ) ) ;
items . push_back ( MenuElem ( _ ( " Show All Audio Tracks " ) , sigc : : mem_fun ( * this , & Mixer_UI : : show_all_audiotracks ) ) ) ;
items . push_back ( MenuElem ( _ ( " Hide All Audio Tracks " ) , sigc : : mem_fun ( * this , & Mixer_UI : : hide_all_audiotracks ) ) ) ;
2015-07-10 05:11:44 -04:00
items . push_back ( MenuElem ( _ ( " Show All Midi Tracks " ) , sigc : : mem_fun ( * this , & Mixer_UI : : show_all_miditracks ) ) ) ;
items . push_back ( MenuElem ( _ ( " Hide All Midi Tracks " ) , sigc : : mem_fun ( * this , & Mixer_UI : : hide_all_miditracks ) ) ) ;
2018-10-02 15:25:53 -04:00
items . push_back ( MenuElem ( _ ( " Show All Busses " ) , sigc : : mem_fun ( * this , & Mixer_UI : : show_all_audiobus ) ) ) ;
items . push_back ( MenuElem ( _ ( " Hide All Busses " ) , sigc : : mem_fun ( * this , & Mixer_UI : : hide_all_audiobus ) ) ) ;
2005-09-25 14:42:24 -04:00
}
void
2023-02-16 18:33:28 -05:00
Mixer_UI : : stripable_property_changed ( const PropertyChange & what_changed , std : : weak_ptr < Stripable > ws )
2005-09-25 14:42:24 -04:00
{
2016-06-09 16:58:49 -04:00
if ( ! what_changed . contains ( ARDOUR : : Properties : : hidden ) & & ! what_changed . contains ( ARDOUR : : Properties : : name ) ) {
2010-02-19 13:09:08 -05:00
return ;
}
2023-02-16 18:33:28 -05:00
std : : shared_ptr < Stripable > s = ws . lock ( ) ;
2016-06-09 16:58:49 -04:00
if ( ! s ) {
return ;
}
2009-10-14 12:10:01 -04:00
2006-03-09 18:44:39 -05:00
TreeModel : : Children rows = track_model - > children ( ) ;
2005-10-01 12:29:37 -04:00
TreeModel : : Children : : iterator i ;
2009-10-14 12:10:01 -04:00
2005-10-01 12:29:37 -04:00
for ( i = rows . begin ( ) ; i ! = rows . end ( ) ; + + i ) {
2023-02-16 18:33:28 -05:00
std : : shared_ptr < Stripable > ss = ( * i ) [ stripable_columns . stripable ] ;
2016-06-09 16:58:49 -04:00
if ( s = = ss ) {
if ( what_changed . contains ( ARDOUR : : Properties : : name ) ) {
( * i ) [ stripable_columns . text ] = s - > name ( ) ;
}
if ( what_changed . contains ( ARDOUR : : Properties : : hidden ) ) {
( * i ) [ stripable_columns . visible ] = ! s - > presentation_info ( ) . hidden ( ) ;
redisplay_track_list ( ) ;
}
2005-10-01 12:29:37 -04:00
return ;
}
2009-10-14 12:10:01 -04:00
}
2005-09-25 14:42:24 -04:00
2023-11-26 22:26:46 -05:00
if ( s - > is_surround_master ( ) ) {
return ;
}
2017-06-14 15:22:08 -04:00
if ( s - > is_master ( ) ) {
return ;
}
2016-01-11 21:36:44 -05:00
error < < _ ( " track display list item for renamed strip not found! " ) < < endmsg ;
2005-09-25 14:42:24 -04:00
}
2005-10-01 12:29:37 -04:00
bool
Mixer_UI : : group_display_button_press ( GdkEventButton * ev )
2005-09-25 14:42:24 -04:00
{
2005-10-01 12:29:37 -04:00
TreeModel : : Path path ;
TreeViewColumn * column ;
int cellx ;
int celly ;
if ( ! group_display . get_path_at_pos ( ( int ) ev - > x , ( int ) ev - > y , path , column , cellx , celly ) ) {
2017-03-08 10:22:17 -05:00
if ( ev - > button = = 3 ) {
_group_tabs - > get_menu ( 0 ) - > popup ( ev - > button , ev - > time ) ;
}
2015-05-03 17:33:05 -04:00
return true ;
2005-09-25 14:42:24 -04:00
}
2006-03-09 18:44:39 -05:00
2010-07-19 19:26:40 -04:00
TreeIter iter = group_model - > get_iter ( path ) ;
if ( ! iter ) {
2017-03-08 10:22:17 -05:00
if ( ev - > button = = 3 ) {
_group_tabs - > get_menu ( 0 ) - > popup ( ev - > button , ev - > time ) ;
}
2015-05-03 17:33:05 -04:00
return true ;
2010-07-19 19:26:40 -04:00
}
RouteGroup * group = ( * iter ) [ group_columns . group ] ;
if ( Keyboard : : is_context_menu_event ( ev ) ) {
2023-10-31 15:10:49 -04:00
_group_tabs - > get_menu ( group ) - > popup ( ev - > button , ev - > time ) ;
2010-07-19 19:26:40 -04:00
return true ;
}
2005-10-05 09:48:09 -04:00
switch ( GPOINTER_TO_UINT ( column - > get_data ( X_ ( " colnum " ) ) ) ) {
2016-06-29 11:26:51 -04:00
case 1 :
2006-02-14 14:12:35 -05:00
if ( Keyboard : : is_edit_event ( ev ) ) {
2010-07-19 19:26:40 -04:00
if ( group ) {
// edit_route_group (group);
2015-10-27 13:43:31 -04:00
# ifdef __APPLE__
2010-07-19 19:26:40 -04:00
group_display . queue_draw ( ) ;
2008-12-12 09:43:24 -05:00
# endif
2010-07-19 19:26:40 -04:00
return true ;
2006-03-09 18:44:39 -05:00
}
2009-10-14 12:10:01 -04:00
}
2006-02-14 14:12:35 -05:00
break ;
2016-06-29 11:26:51 -04:00
case 0 :
2010-07-19 19:26:40 -04:00
{
bool visible = ( * iter ) [ group_columns . visible ] ;
( * iter ) [ group_columns . visible ] = ! visible ;
2015-10-27 13:43:31 -04:00
# ifdef __APPLE__
2010-07-19 19:26:40 -04:00
group_display . queue_draw ( ) ;
2008-12-12 09:43:24 -05:00
# endif
2010-07-19 19:26:40 -04:00
return true ;
}
2005-09-25 14:42:24 -04:00
2006-03-09 18:44:39 -05:00
default :
break ;
}
2009-10-14 12:10:01 -04:00
2006-03-09 18:44:39 -05:00
return false ;
}
void
2009-06-21 15:59:56 -04:00
Mixer_UI : : activate_all_route_groups ( )
2006-03-09 18:44:39 -05:00
{
2009-12-17 13:24:23 -05:00
_session - > foreach_route_group ( sigc : : bind ( sigc : : mem_fun ( * this , & Mixer_UI : : set_route_group_activation ) , true ) ) ;
2005-09-25 14:42:24 -04:00
}
void
2009-06-21 15:59:56 -04:00
Mixer_UI : : disable_all_route_groups ( )
2006-03-09 18:44:39 -05:00
{
2009-12-17 13:24:23 -05:00
_session - > foreach_route_group ( sigc : : bind ( sigc : : mem_fun ( * this , & Mixer_UI : : set_route_group_activation ) , false ) ) ;
2006-03-09 18:44:39 -05:00
}
void
2009-06-21 15:59:56 -04:00
Mixer_UI : : route_groups_changed ( )
2006-03-09 18:44:39 -05:00
{
2011-04-19 11:46:47 -04:00
ENSURE_GUI_THREAD ( * this , & Mixer_UI : : route_groups_changed ) ;
2011-04-19 21:24:40 -04:00
_in_group_rebuild_or_clear = true ;
2006-03-09 18:44:39 -05:00
/* just rebuild the while thing */
group_model - > clear ( ) ;
2015-01-14 14:10:34 -05:00
#if 0
/* this is currently not used,
* Mixer_UI : : group_display_button_press ( ) has a case for it ,
* and a commented edit_route_group ( ) but that ' s n / a since 2011.
*
* This code is left as reminder that
* row [ group_columns . group ] = 0 has special meaning .
*/
2006-03-09 18:44:39 -05:00
{
TreeModel : : Row row ;
row = * ( group_model - > append ( ) ) ;
row [ group_columns . visible ] = true ;
row [ group_columns . text ] = ( _ ( " -all- " ) ) ;
row [ group_columns . group ] = 0 ;
}
2015-01-14 14:10:34 -05:00
# endif
2006-03-09 18:44:39 -05:00
2009-12-17 13:24:23 -05:00
_session - > foreach_route_group ( sigc : : mem_fun ( * this , & Mixer_UI : : add_route_group ) ) ;
2010-07-19 19:26:40 -04:00
_group_tabs - > set_dirty ( ) ;
2011-04-19 21:24:40 -04:00
_in_group_rebuild_or_clear = false ;
2006-03-09 18:44:39 -05:00
}
void
2009-06-21 15:59:56 -04:00
Mixer_UI : : new_route_group ( )
2006-03-09 18:44:39 -05:00
{
2016-06-11 15:49:18 -04:00
_group_tabs - > run_new_group_dialog ( 0 , false ) ;
2006-03-09 18:44:39 -05:00
}
void
2009-06-21 15:59:56 -04:00
Mixer_UI : : remove_selected_route_group ( )
2005-09-25 14:42:24 -04:00
{
2005-10-05 09:48:09 -04:00
Glib : : RefPtr < TreeSelection > selection = group_display . get_selection ( ) ;
2006-03-09 18:44:39 -05:00
TreeView : : Selection : : ListHandle_Path rows = selection - > get_selected_rows ( ) ;
2005-09-25 14:42:24 -04:00
2006-03-09 18:44:39 -05:00
if ( rows . empty ( ) ) {
return ;
}
2005-09-25 14:42:24 -04:00
2006-03-09 18:44:39 -05:00
TreeView : : Selection : : ListHandle_Path : : iterator i = rows . begin ( ) ;
TreeIter iter ;
2009-10-14 12:10:01 -04:00
2006-03-09 18:44:39 -05:00
/* selection mode is single, so rows.begin() is it */
2005-09-25 14:42:24 -04:00
2006-03-09 18:44:39 -05:00
if ( ( iter = group_model - > get_iter ( * i ) ) ) {
RouteGroup * rg = ( * iter ) [ group_columns . group ] ;
if ( rg ) {
2009-12-17 13:24:23 -05:00
_session - > remove_route_group ( * rg ) ;
2005-09-25 14:42:24 -04:00
}
}
}
void
2010-04-01 20:21:08 -04:00
Mixer_UI : : route_group_property_changed ( RouteGroup * group , const PropertyChange & change )
2005-09-25 14:42:24 -04:00
{
2006-03-09 18:44:39 -05:00
if ( in_group_row_change ) {
return ;
}
2007-04-11 09:07:51 -04:00
/* force an update of any mixer strips that are using this group,
2009-10-14 12:10:01 -04:00
otherwise mix group names don ' t change in mixer strips
2007-04-11 09:07:51 -04:00
*/
for ( list < MixerStrip * > : : iterator i = strips . begin ( ) ; i ! = strips . end ( ) ; + + i ) {
2009-06-21 15:59:56 -04:00
if ( ( * i ) - > route_group ( ) = = group ) {
2009-12-09 22:25:32 -05:00
( * i ) - > route_group_changed ( ) ;
2007-04-11 09:07:51 -04:00
}
}
2009-10-14 12:10:01 -04:00
2006-01-11 22:43:52 -05:00
TreeModel : : iterator i ;
2006-03-09 18:44:39 -05:00
TreeModel : : Children rows = group_model - > children ( ) ;
2006-01-11 22:43:52 -05:00
Glib : : RefPtr < TreeSelection > selection = group_display . get_selection ( ) ;
2006-03-09 18:44:39 -05:00
in_group_row_change = true ;
2009-10-14 12:10:01 -04:00
2006-01-11 22:43:52 -05:00
for ( i = rows . begin ( ) ; i ! = rows . end ( ) ; + + i ) {
2006-03-09 18:44:39 -05:00
if ( ( * i ) [ group_columns . group ] = = group ) {
( * i ) [ group_columns . visible ] = ! group - > is_hidden ( ) ;
( * i ) [ group_columns . text ] = group - > name ( ) ;
2005-10-01 12:29:37 -04:00
break ;
}
}
2006-03-09 18:44:39 -05:00
in_group_row_change = false ;
2009-06-20 13:18:41 -04:00
2010-04-01 20:21:08 -04:00
if ( change . contains ( Properties : : name ) ) {
_group_tabs - > set_dirty ( ) ;
}
2011-04-05 20:36:36 -04:00
for ( list < MixerStrip * > : : iterator j = strips . begin ( ) ; j ! = strips . end ( ) ; + + j ) {
if ( ( * j ) - > route_group ( ) = = group ) {
if ( group - > is_hidden ( ) ) {
hide_strip ( * j ) ;
} else {
show_strip ( * j ) ;
}
}
}
2006-03-09 18:44:39 -05:00
}
2015-12-10 18:21:02 -05:00
void
2018-12-03 19:55:52 -05:00
Mixer_UI : : toggle_mixer_list ( )
{
2018-12-11 23:43:22 -05:00
Glib : : RefPtr < ToggleAction > act = ActionManager : : get_toggle_action ( " Mixer " , " ToggleMixerList " ) ;
showhide_mixer_list ( act - > get_active ( ) ) ;
2018-12-03 19:55:52 -05:00
}
void
Mixer_UI : : showhide_mixer_list ( bool yn )
2015-12-10 18:21:02 -05:00
{
2024-03-20 08:49:18 -04:00
if ( ! Profile - > get_livetrax ( ) & & yn ) {
2015-12-10 18:21:02 -05:00
list_vpacker . show ( ) ;
} else {
list_vpacker . hide ( ) ;
}
2018-12-03 19:55:52 -05:00
}
2015-04-21 15:10:49 -04:00
2018-12-03 19:55:52 -05:00
void
Mixer_UI : : toggle_monitor_section ( )
{
2018-12-11 23:43:22 -05:00
Glib : : RefPtr < ToggleAction > act = ActionManager : : get_toggle_action ( " Mixer " , " ToggleMonitorSection " ) ;
showhide_monitor_section ( act - > get_active ( ) ) ;
2015-12-10 18:21:02 -05:00
}
2018-12-03 19:55:52 -05:00
2015-12-19 11:42:36 -05:00
void
2018-12-03 19:55:52 -05:00
Mixer_UI : : showhide_monitor_section ( bool yn )
2015-12-19 11:42:36 -05:00
{
2018-12-11 10:28:47 -05:00
if ( monitor_section ( ) . tearoff ( ) . torn_off ( ) ) {
2015-12-19 11:42:36 -05:00
return ;
}
if ( yn ) {
2018-12-11 10:28:47 -05:00
monitor_section ( ) . tearoff ( ) . show ( ) ;
2015-12-19 11:42:36 -05:00
} else {
2018-12-11 10:28:47 -05:00
monitor_section ( ) . tearoff ( ) . hide ( ) ;
2015-12-19 11:42:36 -05:00
}
}
2015-12-10 18:21:02 -05:00
2019-09-11 19:36:05 -04:00
void
Mixer_UI : : toggle_foldback_strip ( )
{
Glib : : RefPtr < ToggleAction > act = ActionManager : : get_toggle_action ( " Mixer " , " ToggleFoldbackStrip " ) ;
showhide_foldback_strip ( act - > get_active ( ) ) ;
}
void
Mixer_UI : : showhide_foldback_strip ( bool yn )
{
_show_foldback_strip = yn ;
if ( foldback_strip ) {
if ( yn ) {
foldback_strip - > show ( ) ;
} else {
foldback_strip - > hide ( ) ;
}
}
}
2018-12-03 19:55:52 -05:00
void
Mixer_UI : : toggle_vcas ( )
{
2018-12-11 23:43:22 -05:00
Glib : : RefPtr < ToggleAction > act = ActionManager : : get_toggle_action ( " Mixer " , " ToggleVCAPane " ) ;
showhide_vcas ( act - > get_active ( ) ) ;
2018-12-03 19:55:52 -05:00
}
void
Mixer_UI : : showhide_vcas ( bool yn )
{
if ( yn ) {
vca_vpacker . show ( ) ;
} else {
vca_vpacker . hide ( ) ;
}
}
# ifdef MIXBUS
void
Mixer_UI : : toggle_mixbuses ( )
{
2018-12-11 23:43:22 -05:00
Glib : : RefPtr < ToggleAction > act = ActionManager : : get_toggle_action ( " Mixer " , " ToggleMixbusPane " ) ;
showhide_mixbuses ( act - > get_active ( ) ) ;
2018-12-03 19:55:52 -05:00
}
void
Mixer_UI : : showhide_mixbuses ( bool on )
{
if ( on ) {
mb_vpacker . show ( ) ;
} else {
mb_vpacker . hide ( ) ;
}
}
# endif
2006-03-09 18:44:39 -05:00
void
2010-09-14 12:51:02 -04:00
Mixer_UI : : route_group_name_edit ( const std : : string & path , const std : : string & new_text )
2006-03-09 18:44:39 -05:00
{
RouteGroup * group ;
TreeIter iter ;
if ( ( iter = group_model - > get_iter ( path ) ) ) {
2009-10-14 12:10:01 -04:00
2006-03-09 18:44:39 -05:00
if ( ( group = ( * iter ) [ group_columns . group ] ) = = 0 ) {
return ;
}
2009-10-14 12:10:01 -04:00
2006-03-09 18:44:39 -05:00
if ( new_text ! = group - > name ( ) ) {
group - > set_name ( new_text ) ;
}
}
}
2009-10-14 12:10:01 -04:00
void
2009-07-21 11:55:17 -04:00
Mixer_UI : : route_group_row_change ( const Gtk : : TreeModel : : Path & , const Gtk : : TreeModel : : iterator & iter )
2006-03-09 18:44:39 -05:00
{
RouteGroup * group ;
if ( in_group_row_change ) {
return ;
}
if ( ( group = ( * iter ) [ group_columns . group ] ) = = 0 ) {
return ;
}
2010-09-14 12:51:02 -04:00
std : : string name = ( * iter ) [ group_columns . text ] ;
2006-03-09 18:44:39 -05:00
if ( name ! = group - > name ( ) ) {
group - > set_name ( name ) ;
}
2008-04-11 10:06:50 -04:00
2011-04-05 20:36:36 -04:00
bool hidden = ! ( * iter ) [ group_columns . visible ] ;
if ( hidden ! = group - > is_hidden ( ) ) {
group - > set_hidden ( hidden , this ) ;
}
2005-09-25 14:42:24 -04:00
}
2011-04-19 11:46:47 -04:00
/** Called when a group model row is deleted, but also when the model is
* reordered by a user drag - and - drop ; the latter is what we are
* interested in here .
*/
void
Mixer_UI : : route_group_row_deleted ( Gtk : : TreeModel : : Path const & )
{
2011-04-19 21:24:40 -04:00
if ( _in_group_rebuild_or_clear ) {
2011-04-19 11:46:47 -04:00
return ;
}
/* Re-write the session's route group list so that the new order is preserved */
list < RouteGroup * > new_list ;
Gtk : : TreeModel : : Children children = group_model - > children ( ) ;
for ( Gtk : : TreeModel : : Children : : iterator i = children . begin ( ) ; i ! = children . end ( ) ; + + i ) {
RouteGroup * g = ( * i ) [ group_columns . group ] ;
if ( g ) {
new_list . push_back ( g ) ;
}
}
_session - > reorder_route_groups ( new_list ) ;
}
2005-09-25 14:42:24 -04:00
void
2009-06-21 15:59:56 -04:00
Mixer_UI : : add_route_group ( RouteGroup * group )
2005-09-25 14:42:24 -04:00
{
2009-12-11 18:29:48 -05:00
ENSURE_GUI_THREAD ( * this , & Mixer_UI : : add_route_group , group )
2006-03-09 23:05:11 -05:00
bool focus = false ;
2005-09-25 14:42:24 -04:00
2006-05-18 21:54:00 -04:00
in_group_row_change = true ;
2006-03-09 18:44:39 -05:00
TreeModel : : Row row = * ( group_model - > append ( ) ) ;
2011-04-05 20:36:36 -04:00
row [ group_columns . visible ] = ! group - > is_hidden ( ) ;
2006-03-09 18:44:39 -05:00
row [ group_columns . group ] = group ;
2006-03-09 23:05:11 -05:00
if ( ! group - > name ( ) . empty ( ) ) {
row [ group_columns . text ] = group - > name ( ) ;
} else {
row [ group_columns . text ] = _ ( " unnamed " ) ;
focus = true ;
}
2005-09-25 14:42:24 -04:00
2012-04-25 08:58:19 -04:00
group - > PropertyChanged . connect ( * this , invalidator ( * this ) , boost : : bind ( & Mixer_UI : : route_group_property_changed , this , group , _1 ) , gui_context ( ) ) ;
2009-10-14 12:10:01 -04:00
2006-03-09 23:05:11 -05:00
if ( focus ) {
2006-03-10 09:35:57 -05:00
TreeViewColumn * col = group_display . get_column ( 0 ) ;
2016-06-29 11:26:51 -04:00
CellRendererText * name_cell = dynamic_cast < CellRendererText * > ( group_display . get_column_cell_renderer ( 1 ) ) ;
2006-03-10 09:35:57 -05:00
group_display . set_cursor ( group_model - > get_path ( row ) , * col , * name_cell , true ) ;
2006-03-09 23:05:11 -05:00
}
2006-05-18 21:54:00 -04:00
2010-07-19 17:47:07 -04:00
_group_tabs - > set_dirty ( ) ;
2006-05-18 21:54:00 -04:00
in_group_row_change = false ;
2005-09-25 14:42:24 -04:00
}
2006-01-04 22:18:44 -05:00
bool
2021-03-28 14:36:37 -04:00
Mixer_UI : : strip_scroller_button_event ( GdkEventButton * ev )
2005-09-25 14:42:24 -04:00
{
2021-03-28 14:36:37 -04:00
if ( ( ev - > type = = GDK_2BUTTON_PRESS & & ev - > button = = 1 ) | | ( ev - > type = = GDK_BUTTON_RELEASE & & Keyboard : : is_context_menu_event ( ev ) ) ) {
2016-05-05 21:08:46 -04:00
ARDOUR_UI : : instance ( ) - > add_route ( ) ;
2006-01-04 22:18:44 -05:00
return true ;
2005-09-25 14:42:24 -04:00
}
2006-01-04 22:18:44 -05:00
return false ;
2005-09-25 14:42:24 -04:00
}
2016-05-06 10:04:05 -04:00
void
Mixer_UI : : scroller_drag_data_received ( const Glib : : RefPtr < Gdk : : DragContext > & context , int x , int y , const Gtk : : SelectionData & data , guint info , guint time )
{
2022-01-10 15:29:29 -05:00
if ( data . get_target ( ) ! = " x-ardour/plugin.favorite " ) {
2016-05-06 10:04:05 -04:00
context - > drag_finish ( false , false , time ) ;
return ;
}
const void * d = data . get_data ( ) ;
2016-05-17 08:21:05 -04:00
const Gtkmm2ext : : DnDTreeView < ARDOUR : : PluginPresetPtr > * tv = reinterpret_cast < const Gtkmm2ext : : DnDTreeView < ARDOUR : : PluginPresetPtr > * > ( d ) ;
2016-05-06 10:04:05 -04:00
PluginPresetList nfos ;
TreeView * source ;
tv - > get_object_drag_data ( nfos , & source ) ;
Route : : ProcessorList pl ;
bool ok = false ;
for ( list < PluginPresetPtr > : : const_iterator i = nfos . begin ( ) ; i ! = nfos . end ( ) ; + + i ) {
PluginPresetPtr ppp = ( * i ) ;
PluginInfoPtr pip = ppp - > _pip ;
if ( ! pip - > is_instrument ( ) ) {
continue ;
}
2021-07-17 18:25:47 -04:00
ARDOUR_UI : : instance ( ) - > session_add_midi_route ( true , ( RouteGroup * ) 0 , 1 , _ ( " MIDI " ) , Config - > get_strict_io ( ) , pip , ppp - > _preset . valid ? & ppp - > _preset : 0 , PresentationInfo : : max_order , false ) ;
2016-05-06 10:04:05 -04:00
ok = true ;
}
context - > drag_finish ( ok , false , time ) ;
}
2005-09-25 14:42:24 -04:00
void
2013-07-10 15:40:42 -04:00
Mixer_UI : : set_strip_width ( Width w , bool save )
2005-09-25 14:42:24 -04:00
{
_strip_width = w ;
for ( list < MixerStrip * > : : iterator i = strips . begin ( ) ; i ! = strips . end ( ) ; + + i ) {
2013-07-10 15:40:42 -04:00
( * i ) - > set_width_enum ( w , save ? ( * i ) - > width_owner ( ) : this ) ;
2005-09-25 14:42:24 -04:00
}
}
int
2015-07-07 22:12:21 -04:00
Mixer_UI : : set_state ( const XMLNode & node , int version )
2005-09-25 14:42:24 -04:00
{
2016-08-27 00:15:18 -04:00
bool yn ;
2015-04-21 15:10:49 -04:00
2024-04-02 19:57:26 -04:00
if ( ! Profile - > get_livetrax ( ) ) {
Tabbable : : set_state ( node , version ) ;
}
2006-01-17 11:40:57 -05:00
2016-08-27 00:15:18 -04:00
if ( node . get_property ( " narrow-strips " , yn ) ) {
if ( yn ) {
2005-09-25 14:42:24 -04:00
set_strip_width ( Narrow ) ;
} else {
set_strip_width ( Wide ) ;
}
}
2016-08-27 00:15:18 -04:00
node . get_property ( " show-mixer " , _visible ) ;
2006-08-30 16:48:16 -04:00
2019-02-28 16:56:35 -05:00
yn = false ;
node . get_property ( " maximised " , yn ) ;
{
2018-12-11 23:43:22 -05:00
Glib : : RefPtr < ToggleAction > act = ActionManager : : get_toggle_action ( X_ ( " Common " ) , X_ ( " ToggleMaximalMixer " ) ) ;
bool fs = act & & act - > get_active ( ) ;
2014-03-21 08:45:00 -04:00
if ( yn ^ fs ) {
2015-04-21 15:10:49 -04:00
ActionManager : : do_action ( " Common " , " ToggleMaximalMixer " ) ;
2014-03-21 08:45:00 -04:00
}
}
2019-02-28 16:56:35 -05:00
yn = true ;
node . get_property ( " show-mixer-list " , yn ) ;
{
2018-12-11 23:43:22 -05:00
Glib : : RefPtr < ToggleAction > act = ActionManager : : get_toggle_action ( X_ ( " Mixer " ) , X_ ( " ToggleMixerList " ) ) ;
2015-12-10 18:21:02 -05:00
/* do it twice to force the change */
2018-12-11 23:43:22 -05:00
act - > set_active ( ! yn ) ;
act - > set_active ( yn ) ;
2015-12-10 18:21:02 -05:00
}
2019-02-28 16:56:35 -05:00
yn = true ;
node . get_property ( " monitor-section-visible " , yn ) ;
{
2018-12-11 23:43:22 -05:00
Glib : : RefPtr < ToggleAction > act = ActionManager : : get_toggle_action ( X_ ( " Mixer " ) , X_ ( " ToggleMonitorSection " ) ) ;
2018-12-03 19:55:52 -05:00
/* do it twice to force the change */
2018-12-11 23:43:22 -05:00
act - > set_active ( ! yn ) ;
act - > set_active ( yn ) ;
2018-12-03 19:55:52 -05:00
}
2019-09-11 19:36:05 -04:00
yn = true ;
node . get_property ( " foldback-strip-visible " , yn ) ;
{
Glib : : RefPtr < ToggleAction > act = ActionManager : : get_toggle_action ( X_ ( " Mixer " ) , X_ ( " ToggleFoldbackStrip " ) ) ;
/* do it twice to force the change */
act - > set_active ( ! yn ) ;
act - > set_active ( yn ) ;
}
2019-02-28 16:56:35 -05:00
yn = true ;
node . get_property ( " show-vca-pane " , yn ) ;
{
2018-12-11 23:43:22 -05:00
Glib : : RefPtr < ToggleAction > act = ActionManager : : get_toggle_action ( X_ ( " Mixer " ) , X_ ( " ToggleVCAPane " ) ) ;
2018-12-03 19:55:52 -05:00
/* do it twice to force the change */
2018-12-11 23:43:22 -05:00
act - > set_active ( ! yn ) ;
act - > set_active ( yn ) ;
2018-12-03 19:55:52 -05:00
}
# ifdef MIXBUS
2019-02-28 16:56:35 -05:00
yn = true ;
node . get_property ( " show-mixbus-pane " , yn ) ;
{
2018-12-11 23:43:22 -05:00
Glib : : RefPtr < ToggleAction > act = ActionManager : : get_toggle_action ( X_ ( " Mixer " ) , X_ ( " ToggleMixbusPane " ) ) ;
2017-05-09 12:32:04 -04:00
/* do it twice to force the change */
2018-12-11 23:43:22 -05:00
act - > set_active ( ! yn ) ;
act - > set_active ( yn ) ;
2017-05-09 12:32:04 -04:00
}
2018-12-03 19:55:52 -05:00
# endif
2020-06-24 23:52:38 -04:00
XMLNode plugin_order ( X_ ( " PO " ) ) ;
if ( PluginManager : : instance ( ) . load_plugin_order_file ( plugin_order ) ) {
favorite_ui_order . clear ( ) ;
const XMLNodeList & kids = plugin_order . children ( " PluginInfo " ) ;
2015-12-22 17:06:08 -05:00
XMLNodeConstIterator i ;
for ( i = kids . begin ( ) ; i ! = kids . end ( ) ; + + i ) {
2016-08-27 00:15:18 -04:00
std : : string unique_id ;
if ( ( * i ) - > get_property ( " unique-id " , unique_id ) ) {
2020-06-24 23:52:38 -04:00
favorite_ui_order . push_back ( unique_id ) ;
2016-08-27 00:15:18 -04:00
if ( ( * i ) - > get_property ( " expanded " , yn ) ) {
favorite_ui_state [ unique_id ] = yn ;
2015-12-25 18:43:59 -05:00
}
2015-12-22 17:06:08 -05:00
}
}
sync_treeview_from_favorite_order ( ) ;
}
2018-05-08 14:25:54 -04:00
2022-03-28 18:28:12 -04:00
float fract ;
if ( ! node . get_property ( " mixer-rhs-pane1-pos " , fract ) | | fract > 1.0 ) {
fract = 0.6f ;
}
rhs_pane1 . set_divider ( 0 , fract ) ;
if ( ! node . get_property ( " mixer-rhs-pane2-pos " , fract ) | | fract > 1.0 ) {
fract = 0.7f ;
}
rhs_pane2 . set_divider ( 0 , fract ) ;
if ( ! node . get_property ( " mixer-list-hpane-pos " , fract ) | | fract > 1.0 ) {
fract = 0.2f ;
}
list_hpane . set_divider ( 0 , fract ) ;
if ( ! node . get_property ( " mixer-inner-pane-pos " , fract ) | | fract > 1.0 ) {
fract = 0.8f ;
}
inner_pane . set_divider ( 0 , fract ) ;
2005-09-25 14:42:24 -04:00
return 0 ;
}
2018-05-08 14:25:54 -04:00
void
2020-06-24 23:52:38 -04:00
Mixer_UI : : favorite_plugins_deleted ( const TreeModel : : Path & )
2018-05-08 14:25:54 -04:00
{
2020-06-24 23:52:38 -04:00
if ( ignore_plugin_reorder ) {
return ;
}
/* re-order is implemented by insert; delete */
save_plugin_order_file ( ) ;
}
2018-05-08 14:25:54 -04:00
2020-06-24 23:52:38 -04:00
void
Mixer_UI : : save_plugin_order_file ( )
{
2018-05-08 14:25:54 -04:00
store_current_favorite_order ( ) ;
2020-06-24 23:52:38 -04:00
2018-05-08 14:25:54 -04:00
XMLNode plugin_order ( " PluginOrder " ) ;
uint32_t cnt = 0 ;
2020-06-24 23:52:38 -04:00
for ( std : : list < std : : string > : : const_iterator i = favorite_ui_order . begin ( ) ; i ! = favorite_ui_order . end ( ) ; + + i , + + cnt ) {
2018-05-08 14:25:54 -04:00
XMLNode * p = new XMLNode ( " PluginInfo " ) ;
p - > set_property ( " sort " , cnt ) ;
2020-06-24 23:52:38 -04:00
p - > set_property ( " unique-id " , * i ) ;
if ( favorite_ui_state . find ( * i ) ! = favorite_ui_state . end ( ) ) {
p - > set_property ( " expanded " , favorite_ui_state [ * i ] ) ;
2018-05-08 14:25:54 -04:00
}
plugin_order . add_child_nocopy ( * p ) ;
}
2020-06-24 23:52:38 -04:00
PluginManager : : instance ( ) . save_plugin_order_file ( plugin_order ) ;
2018-05-08 14:25:54 -04:00
}
2005-09-25 14:42:24 -04:00
XMLNode &
2022-04-06 23:56:45 -04:00
Mixer_UI : : get_state ( ) const
2005-09-25 14:42:24 -04:00
{
2015-07-09 12:40:51 -04:00
XMLNode * node = new XMLNode ( X_ ( " Mixer " ) ) ;
2005-09-25 14:42:24 -04:00
2024-04-02 19:57:26 -04:00
if ( ! Profile - > get_livetrax ( ) ) {
node - > add_child_nocopy ( Tabbable : : get_state ( ) ) ;
}
2009-10-14 12:10:01 -04:00
2016-08-27 00:15:18 -04:00
node - > set_property ( X_ ( " mixer-rhs-pane1-pos " ) , rhs_pane1 . get_divider ( ) ) ;
node - > set_property ( X_ ( " mixer-rhs_pane2-pos " ) , rhs_pane2 . get_divider ( ) ) ;
node - > set_property ( X_ ( " mixer-list-hpane-pos " ) , list_hpane . get_divider ( ) ) ;
node - > set_property ( X_ ( " mixer-inner-pane-pos " ) , inner_pane . get_divider ( ) ) ;
2005-09-25 14:42:24 -04:00
2016-08-27 00:15:18 -04:00
node - > set_property ( " narrow-strips " , ( _strip_width = = Narrow ) ) ;
node - > set_property ( " show-mixer " , _visible ) ;
node - > set_property ( " maximised " , _maximised ) ;
2014-03-21 08:45:00 -04:00
2018-12-11 23:43:22 -05:00
Glib : : RefPtr < ToggleAction > act = ActionManager : : get_toggle_action ( " Mixer " , " ToggleMixerList " ) ;
node - > set_property ( " show-mixer-list " , act - > get_active ( ) ) ;
2018-12-03 19:55:52 -05:00
2018-12-11 23:43:22 -05:00
act = ActionManager : : get_toggle_action ( " Mixer " , " ToggleMonitorSection " ) ;
node - > set_property ( " monitor-section-visible " , act - > get_active ( ) ) ;
2018-12-03 19:55:52 -05:00
2019-09-11 19:36:05 -04:00
act = ActionManager : : get_toggle_action ( " Mixer " , " ToggleFoldbackStrip " ) ;
node - > set_property ( " foldback-strip-visible " , act - > get_active ( ) ) ;
2018-12-11 23:43:22 -05:00
act = ActionManager : : get_toggle_action ( " Mixer " , " ToggleVCAPane " ) ;
node - > set_property ( " show-vca-pane " , act - > get_active ( ) ) ;
2018-12-03 19:55:52 -05:00
# ifdef MIXBUS
2018-12-11 23:43:22 -05:00
act = ActionManager : : get_toggle_action ( " Mixer " , " ToggleMixbusPane " ) ;
node - > set_property ( " show-mixbus-pane " , act - > get_active ( ) ) ;
2018-12-03 19:55:52 -05:00
# endif
2017-05-09 12:32:04 -04:00
2005-09-25 14:42:24 -04:00
return * node ;
}
2009-10-28 17:36:40 -04:00
void
2011-06-01 13:00:29 -04:00
Mixer_UI : : scroll_left ( )
2009-10-28 17:36:40 -04:00
{
2013-07-13 08:58:23 -04:00
if ( ! scroller . get_hscrollbar ( ) ) return ;
2009-10-28 17:36:40 -04:00
Adjustment * adj = scroller . get_hscrollbar ( ) - > get_adjustment ( ) ;
2016-10-14 16:58:59 -04:00
int sc_w = scroller . get_width ( ) ;
int sp_w = strip_packer . get_width ( ) ;
if ( sp_w < = sc_w ) {
return ;
}
int lp = adj - > get_value ( ) ;
int lm = 0 ;
using namespace Gtk : : Box_Helpers ;
const BoxList & strips = strip_packer . children ( ) ;
for ( BoxList : : const_iterator i = strips . begin ( ) ; i ! = strips . end ( ) ; + + i ) {
2021-03-26 07:46:42 -04:00
if ( i - > get_widget ( ) = = & scroller_base ) {
2018-02-13 05:18:03 -05:00
continue ;
}
2018-08-09 11:10:22 -04:00
# ifdef MIXBUS
if ( i - > get_widget ( ) = = & mb_shadow ) {
continue ;
}
# endif
2016-10-14 16:58:59 -04:00
lm + = i - > get_widget ( ) - > get_width ( ) ;
if ( lm > = lp ) {
lm - = i - > get_widget ( ) - > get_width ( ) ;
break ;
}
}
scroller . get_hscrollbar ( ) - > set_value ( max ( adj - > get_lower ( ) , min ( adj - > get_upper ( ) , lm - 1.0 ) ) ) ;
2009-10-28 17:36:40 -04:00
}
void
Mixer_UI : : scroll_right ( )
{
2013-07-13 08:58:23 -04:00
if ( ! scroller . get_hscrollbar ( ) ) return ;
2009-10-28 17:36:40 -04:00
Adjustment * adj = scroller . get_hscrollbar ( ) - > get_adjustment ( ) ;
2016-10-14 16:58:59 -04:00
int sc_w = scroller . get_width ( ) ;
int sp_w = strip_packer . get_width ( ) ;
if ( sp_w < = sc_w ) {
return ;
}
int lp = adj - > get_value ( ) ;
int lm = 0 ;
using namespace Gtk : : Box_Helpers ;
const BoxList & strips = strip_packer . children ( ) ;
for ( BoxList : : const_iterator i = strips . begin ( ) ; i ! = strips . end ( ) ; + + i ) {
2021-03-26 07:46:42 -04:00
if ( i - > get_widget ( ) = = & scroller_base ) {
2018-02-13 05:18:03 -05:00
continue ;
}
2018-08-09 11:10:22 -04:00
# ifdef MIXBUS
if ( i - > get_widget ( ) = = & mb_shadow ) {
continue ;
}
# endif
2016-10-14 16:58:59 -04:00
lm + = i - > get_widget ( ) - > get_width ( ) ;
if ( lm > lp + 1 ) {
break ;
}
}
scroller . get_hscrollbar ( ) - > set_value ( max ( adj - > get_lower ( ) , min ( adj - > get_upper ( ) , lm - 1.0 ) ) ) ;
2009-10-28 17:36:40 -04:00
}
2005-09-25 14:42:24 -04:00
2009-10-28 17:36:40 -04:00
bool
Mixer_UI : : on_scroll_event ( GdkEventScroll * ev )
{
switch ( ev - > direction ) {
case GDK_SCROLL_LEFT :
scroll_left ( ) ;
return true ;
case GDK_SCROLL_UP :
if ( ev - > state & Keyboard : : TertiaryModifier ) {
scroll_left ( ) ;
return true ;
}
return false ;
case GDK_SCROLL_RIGHT :
scroll_right ( ) ;
return true ;
case GDK_SCROLL_DOWN :
if ( ev - > state & Keyboard : : TertiaryModifier ) {
scroll_right ( ) ;
return true ;
}
return false ;
}
return false ;
}
2019-03-12 12:04:13 -04:00
void
Mixer_UI : : vca_scroll_left ( )
{
if ( ! vca_scroller . get_hscrollbar ( ) ) return ;
Adjustment * adj = vca_scroller . get_hscrollbar ( ) - > get_adjustment ( ) ;
int sc_w = vca_scroller . get_width ( ) ;
int sp_w = strip_packer . get_width ( ) ;
if ( sp_w < = sc_w ) {
return ;
}
int lp = adj - > get_value ( ) ;
int lm = 0 ;
using namespace Gtk : : Box_Helpers ;
const BoxList & strips = vca_hpacker . children ( ) ;
for ( BoxList : : const_iterator i = strips . begin ( ) ; i ! = strips . end ( ) ; + + i ) {
2021-03-26 07:46:42 -04:00
if ( i - > get_widget ( ) = = & vca_scroller_base ) {
2019-03-12 12:04:13 -04:00
continue ;
}
lm + = i - > get_widget ( ) - > get_width ( ) ;
if ( lm > = lp ) {
lm - = i - > get_widget ( ) - > get_width ( ) ;
break ;
}
}
vca_scroller . get_hscrollbar ( ) - > set_value ( max ( adj - > get_lower ( ) , min ( adj - > get_upper ( ) , lm - 1.0 ) ) ) ;
}
void
Mixer_UI : : vca_scroll_right ( )
{
if ( ! vca_scroller . get_hscrollbar ( ) ) return ;
Adjustment * adj = vca_scroller . get_hscrollbar ( ) - > get_adjustment ( ) ;
int sc_w = vca_scroller . get_width ( ) ;
int sp_w = strip_packer . get_width ( ) ;
if ( sp_w < = sc_w ) {
return ;
}
int lp = adj - > get_value ( ) ;
int lm = 0 ;
using namespace Gtk : : Box_Helpers ;
const BoxList & strips = vca_hpacker . children ( ) ;
for ( BoxList : : const_iterator i = strips . begin ( ) ; i ! = strips . end ( ) ; + + i ) {
2021-03-26 07:46:42 -04:00
if ( i - > get_widget ( ) = = & vca_scroller_base ) {
2019-03-12 12:04:13 -04:00
continue ;
}
lm + = i - > get_widget ( ) - > get_width ( ) ;
if ( lm > lp + 1 ) {
break ;
}
}
vca_scroller . get_hscrollbar ( ) - > set_value ( max ( adj - > get_lower ( ) , min ( adj - > get_upper ( ) , lm - 1.0 ) ) ) ;
}
bool
Mixer_UI : : on_vca_scroll_event ( GdkEventScroll * ev )
{
switch ( ev - > direction ) {
case GDK_SCROLL_LEFT :
vca_scroll_left ( ) ;
return true ;
case GDK_SCROLL_UP :
if ( ev - > state & Keyboard : : TertiaryModifier ) {
vca_scroll_left ( ) ;
return true ;
}
return false ;
case GDK_SCROLL_RIGHT :
vca_scroll_right ( ) ;
return true ;
case GDK_SCROLL_DOWN :
if ( ev - > state & Keyboard : : TertiaryModifier ) {
vca_scroll_right ( ) ;
return true ;
}
return false ;
}
return false ;
}
2009-10-28 17:36:40 -04:00
2009-06-20 13:15:33 -04:00
void
Mixer_UI : : parameter_changed ( string const & p )
{
if ( p = = " show-group-tabs " ) {
2021-02-06 18:04:36 -05:00
bool const s = _session ? _session - > config . get_show_group_tabs ( ) : true ;
2009-06-20 13:15:33 -04:00
if ( s ) {
_group_tabs - > show ( ) ;
2024-05-06 17:47:10 -04:00
vca_label_bar . show ( ) ;
Gtk : : Requisition group_size = _group_tabs - > size_request ( ) ;
2024-05-06 18:07:25 -04:00
if ( Profile - > get_livetrax ( ) ) {
vca_label_bar . set_size_request ( - 1 , group_size . height + 2 ) ;
} else {
vca_label_bar . set_size_request ( - 1 , group_size . height + 1 ) ;
}
2009-06-20 13:15:33 -04:00
} else {
_group_tabs - > hide ( ) ;
2024-05-06 17:47:10 -04:00
vca_label_bar . hide ( ) ;
2009-06-20 13:15:33 -04:00
}
2010-05-02 10:28:09 -04:00
} else if ( p = = " default-narrow_ms " ) {
2015-01-02 09:44:54 -05:00
bool const s = UIConfiguration : : instance ( ) . get_default_narrow_ms ( ) ;
2010-05-02 10:28:09 -04:00
for ( list < MixerStrip * > : : iterator i = strips . begin ( ) ; i ! = strips . end ( ) ; + + i ) {
( * i ) - > set_width_enum ( s ? Narrow : Wide , this ) ;
}
2009-06-20 13:15:33 -04:00
}
}
2009-10-14 12:10:01 -04:00
2009-06-21 15:59:56 -04:00
void
Mixer_UI : : set_route_group_activation ( RouteGroup * g , bool a )
{
g - > set_active ( a , this ) ;
}
2009-10-14 12:10:01 -04:00
2009-10-22 21:00:13 -04:00
PluginSelector *
2009-10-22 13:17:34 -04:00
Mixer_UI : : plugin_selector ( )
{
2024-03-26 12:12:18 -04:00
if ( Profile - > get_livetrax ( ) ) {
/* no plugins, no plugin selector */
return nullptr ;
}
2010-02-03 14:00:58 -05:00
# ifdef DEFER_PLUGIN_SELECTOR_LOAD
if ( ! _plugin_selector )
2011-11-14 12:41:29 -05:00
_plugin_selector = new PluginSelector ( PluginManager : : instance ( ) ) ;
2010-02-03 14:00:58 -05:00
# endif
2009-10-22 21:00:13 -04:00
return _plugin_selector ;
2009-10-22 13:17:34 -04:00
}
2011-01-09 14:09:49 -05:00
void
Mixer_UI : : setup_track_display ( )
{
2016-06-05 16:29:22 -04:00
track_model = ListStore : : create ( stripable_columns ) ;
2011-01-09 14:09:49 -05:00
track_display . set_model ( track_model ) ;
2016-06-05 16:29:22 -04:00
track_display . append_column ( _ ( " Show " ) , stripable_columns . visible ) ;
2016-06-29 11:26:51 -04:00
track_display . append_column ( _ ( " Strips " ) , stripable_columns . text ) ;
2011-01-09 14:09:49 -05:00
track_display . get_column ( 0 ) - > set_data ( X_ ( " colnum " ) , GUINT_TO_POINTER ( 0 ) ) ;
track_display . get_column ( 1 ) - > set_data ( X_ ( " colnum " ) , GUINT_TO_POINTER ( 1 ) ) ;
2016-06-29 11:26:51 -04:00
track_display . get_column ( 0 ) - > set_expand ( false ) ;
track_display . get_column ( 1 ) - > set_expand ( true ) ;
track_display . get_column ( 1 ) - > set_sizing ( Gtk : : TREE_VIEW_COLUMN_FIXED ) ;
2012-12-07 17:38:49 -05:00
track_display . set_name ( X_ ( " EditGroupList " ) ) ;
2011-01-09 14:09:49 -05:00
track_display . get_selection ( ) - > set_mode ( Gtk : : SELECTION_NONE ) ;
track_display . set_reorderable ( true ) ;
track_display . set_headers_visible ( true ) ;
2015-09-15 15:21:01 -04:00
track_display . set_can_focus ( false ) ;
2011-01-09 14:09:49 -05:00
track_model - > signal_row_deleted ( ) . connect ( sigc : : mem_fun ( * this , & Mixer_UI : : track_list_delete ) ) ;
track_model - > signal_rows_reordered ( ) . connect ( sigc : : mem_fun ( * this , & Mixer_UI : : track_list_reorder ) ) ;
2016-06-29 11:26:51 -04:00
CellRendererToggle * track_list_visible_cell = dynamic_cast < CellRendererToggle * > ( track_display . get_column_cell_renderer ( 0 ) ) ;
2011-01-09 14:09:49 -05:00
track_list_visible_cell - > property_activatable ( ) = true ;
track_list_visible_cell - > property_radio ( ) = false ;
2012-07-19 18:35:43 -04:00
track_list_visible_cell - > signal_toggled ( ) . connect ( sigc : : mem_fun ( * this , & Mixer_UI : : track_visibility_changed ) ) ;
2011-01-09 14:09:49 -05:00
track_display . signal_button_press_event ( ) . connect ( sigc : : mem_fun ( * this , & Mixer_UI : : track_display_button_press ) , false ) ;
track_display_scroller . add ( track_display ) ;
track_display_scroller . set_policy ( Gtk : : POLICY_NEVER , Gtk : : POLICY_AUTOMATIC ) ;
2017-09-18 14:45:56 -04:00
track_display_frame . set_name ( " BaseFrame " ) ;
track_display_frame . set_shadow_type ( Gtk : : SHADOW_IN ) ;
2021-04-03 16:19:33 -04:00
track_display_frame . add ( track_display_scroller ) ;
2011-01-09 14:09:49 -05:00
track_display_scroller . show ( ) ;
2017-09-18 14:45:56 -04:00
track_display_frame . show ( ) ;
2011-01-09 14:09:49 -05:00
track_display . show ( ) ;
}
2011-01-09 14:09:56 -05:00
void
Mixer_UI : : new_track_or_bus ( )
{
2016-05-05 21:08:46 -04:00
ARDOUR_UI : : instance ( ) - > add_route ( ) ;
2011-01-09 14:09:56 -05:00
}
2011-04-19 11:46:47 -04:00
2011-09-07 11:07:02 -04:00
void
Mixer_UI : : update_title ( )
{
2015-07-07 22:12:21 -04:00
if ( ! own_window ( ) ) {
return ;
}
2015-07-09 12:40:51 -04:00
2011-09-07 11:07:02 -04:00
if ( _session ) {
string n ;
2015-10-05 10:17:49 -04:00
2011-09-07 11:07:02 -04:00
if ( _session - > snap_name ( ) ! = _session - > name ( ) ) {
n = _session - > snap_name ( ) ;
} else {
n = _session - > name ( ) ;
}
if ( _session - > dirty ( ) ) {
n = " * " + n ;
}
2015-10-05 10:17:49 -04:00
2015-10-26 14:35:06 -04:00
WindowTitle title ( n ) ;
title + = S_ ( " Window|Mixer " ) ;
title + = Glib : : get_application_name ( ) ;
own_window ( ) - > set_title ( title . get_string ( ) ) ;
2011-09-07 11:07:02 -04:00
} else {
2015-10-05 10:17:49 -04:00
2015-10-26 14:35:06 -04:00
WindowTitle title ( S_ ( " Window|Mixer " ) ) ;
title + = Glib : : get_application_name ( ) ;
own_window ( ) - > set_title ( title . get_string ( ) ) ;
2011-09-07 11:07:02 -04:00
}
}
2011-11-04 13:53:21 -04:00
MixerStrip *
Mixer_UI : : strip_by_x ( int x )
{
for ( list < MixerStrip * > : : iterator i = strips . begin ( ) ; i ! = strips . end ( ) ; + + i ) {
int x1 , x2 , y ;
2015-07-07 22:12:21 -04:00
( * i ) - > translate_coordinates ( _content , 0 , 0 , x1 , y ) ;
2011-11-04 13:53:21 -04:00
x2 = x1 + ( * i ) - > get_width ( ) ;
if ( x > = x1 & & x < = x2 ) {
return ( * i ) ;
}
}
return 0 ;
}
void
2016-07-06 13:37:30 -04:00
Mixer_UI : : set_axis_targets_for_operation ( )
2011-11-04 13:53:21 -04:00
{
2016-07-06 13:37:30 -04:00
_axis_targets . clear ( ) ;
2011-11-04 13:53:21 -04:00
if ( ! _selection . empty ( ) ) {
2016-07-06 13:37:30 -04:00
_axis_targets = _selection . axes ;
2011-11-04 13:53:21 -04:00
return ;
}
2014-07-24 23:49:33 -04:00
// removed "implicit" selections of strips, after discussion on IRC
2014-07-24 13:30:11 -04:00
2011-11-04 13:53:21 -04:00
}
2012-01-17 20:30:44 -05:00
2018-12-03 19:55:52 -05:00
void
2018-12-11 10:28:47 -05:00
Mixer_UI : : monitor_section_going_away ( )
2018-12-03 19:55:52 -05:00
{
2018-12-11 10:28:47 -05:00
XMLNode * ui_node = Config - > extra_xml ( X_ ( " UI " ) ) ;
2018-12-03 19:55:52 -05:00
2018-12-11 10:28:47 -05:00
/* immediate state save.
*
* Tearoff settings are otherwise only stored during
* save_ardour_state ( ) . The mon - section may or may not
* exist at that point .
*/
2018-12-03 19:55:52 -05:00
2018-12-11 10:28:47 -05:00
if ( ui_node ) {
XMLNode * tearoff_node = ui_node - > child ( X_ ( " Tearoffs " ) ) ;
if ( tearoff_node ) {
tearoff_node - > remove_nodes_and_delete ( X_ ( " monitor-section " ) ) ;
XMLNode * t = new XMLNode ( X_ ( " monitor-section " ) ) ;
_monitor_section . tearoff ( ) . add_state ( * t ) ;
tearoff_node - > add_child_nocopy ( * t ) ;
2017-05-09 12:32:04 -04:00
}
2012-01-17 20:30:44 -05:00
}
2018-12-11 10:28:47 -05:00
monitor_section_detached ( ) ;
out_packer . remove ( _monitor_section . tearoff ( ) ) ;
2012-01-17 20:30:44 -05:00
}
2012-11-12 21:19:04 -05:00
void
Mixer_UI : : toggle_midi_input_active ( bool flip_others )
{
2023-02-16 18:33:28 -05:00
std : : shared_ptr < RouteList > rl ( new RouteList ) ;
2013-07-28 14:32:52 -04:00
bool onoff = false ;
2012-11-12 21:19:04 -05:00
2016-07-06 13:37:30 -04:00
set_axis_targets_for_operation ( ) ;
2012-11-12 21:19:04 -05:00
2016-07-06 13:37:30 -04:00
for ( AxisViewSelection : : iterator r = _axis_targets . begin ( ) ; r ! = _axis_targets . end ( ) ; + + r ) {
2023-02-16 18:33:28 -05:00
std : : shared_ptr < MidiTrack > mt = std : : dynamic_pointer_cast < MidiTrack > ( ( * r ) - > stripable ( ) ) ;
2012-11-12 21:19:04 -05:00
if ( mt ) {
2016-07-06 13:37:30 -04:00
rl - > push_back ( mt ) ;
2012-11-12 21:19:04 -05:00
onoff = ! mt - > input_active ( ) ;
}
}
2015-10-05 10:17:49 -04:00
2012-11-12 21:19:04 -05:00
_session - > set_exclusive_input_active ( rl , onoff , flip_others ) ;
}
2012-12-09 21:03:45 -05:00
2014-03-21 08:45:00 -04:00
void
Mixer_UI : : maximise_mixer_space ( )
{
2015-07-07 22:12:21 -04:00
if ( ! own_window ( ) ) {
2014-03-21 08:45:00 -04:00
return ;
}
2015-10-26 14:35:06 -04:00
if ( _maximised ) {
return ;
2015-04-21 15:10:49 -04:00
}
2015-07-07 22:12:21 -04:00
_window - > fullscreen ( ) ;
_maximised = true ;
2014-03-21 08:45:00 -04:00
}
void
Mixer_UI : : restore_mixer_space ( )
{
2015-07-07 22:12:21 -04:00
if ( ! own_window ( ) ) {
2014-03-21 08:45:00 -04:00
return ;
}
2015-10-26 14:35:06 -04:00
if ( ! _maximised ) {
return ;
2015-04-21 15:10:49 -04:00
}
2015-07-07 22:12:21 -04:00
own_window ( ) - > unfullscreen ( ) ;
_maximised = false ;
2014-03-21 08:45:00 -04:00
}
2015-12-19 11:42:36 -05:00
void
Mixer_UI : : monitor_section_attached ( )
{
2018-12-11 12:25:12 -05:00
Glib : : RefPtr < ToggleAction > act = ActionManager : : get_toggle_action ( " Mixer " , " ToggleMonitorSection " ) ;
act - > set_sensitive ( true ) ;
showhide_monitor_section ( act - > get_active ( ) ) ;
2015-12-19 11:42:36 -05:00
}
void
Mixer_UI : : monitor_section_detached ( )
{
2018-12-10 08:33:31 -05:00
Glib : : RefPtr < Action > act = ActionManager : : get_action ( " Mixer " , " ToggleMonitorSection " ) ;
2015-12-19 11:42:36 -05:00
act - > set_sensitive ( false ) ;
}
2015-12-21 22:43:26 -05:00
2015-12-22 17:06:08 -05:00
void
Mixer_UI : : store_current_favorite_order ( )
{
2024-02-26 07:46:09 -05:00
if ( plugin_list_mode ! = PLM_Favorite | | ! plugin_search_entry . get_text ( ) . empty ( ) ) {
2020-06-24 23:52:38 -04:00
return ;
}
2015-12-22 17:06:08 -05:00
typedef Gtk : : TreeModel : : Children type_children ;
type_children children = favorite_plugins_model - > children ( ) ;
2020-06-24 23:52:38 -04:00
favorite_ui_order . clear ( ) ;
2015-12-22 17:06:08 -05:00
for ( type_children : : iterator iter = children . begin ( ) ; iter ! = children . end ( ) ; + + iter )
{
Gtk : : TreeModel : : Row row = * iter ;
2015-12-25 10:10:09 -05:00
ARDOUR : : PluginPresetPtr ppp = row [ favorite_plugins_columns . plugin ] ;
2020-06-24 23:52:38 -04:00
favorite_ui_order . push_back ( ( * ppp - > _pip ) . unique_id ) ;
2015-12-25 18:43:59 -05:00
favorite_ui_state [ ( * ppp - > _pip ) . unique_id ] = favorite_plugins_display . row_expanded ( favorite_plugins_model - > get_path ( iter ) ) ;
2015-12-22 17:06:08 -05:00
}
}
2015-12-21 22:43:26 -05:00
2016-01-09 18:00:07 -05:00
void
Mixer_UI : : save_favorite_ui_state ( const TreeModel : : iterator & iter , const TreeModel : : Path & path )
{
Gtk : : TreeModel : : Row row = * iter ;
ARDOUR : : PluginPresetPtr ppp = row [ favorite_plugins_columns . plugin ] ;
assert ( ppp ) ;
favorite_ui_state [ ( * ppp - > _pip ) . unique_id ] = favorite_plugins_display . row_expanded ( favorite_plugins_model - > get_path ( iter ) ) ;
}
2020-06-24 23:52:38 -04:00
void
2024-02-26 07:46:09 -05:00
Mixer_UI : : set_plugin_list_mode ( PluginListMode plm )
2020-06-24 23:52:38 -04:00
{
2024-03-26 12:12:18 -04:00
if ( Profile - > get_livetrax ( ) ) {
return ;
}
2024-02-26 07:46:09 -05:00
plugin_list_mode = plm ;
string str = plugin_list_mode_strings [ ( int ) plm ] ;
if ( str ! = favorite_plugins_mode_combo . get_text ( ) ) {
favorite_plugins_mode_combo . set_text ( str ) ;
}
if ( plugin_list_mode = = PLM_Favorite ) {
2020-06-24 23:52:38 -04:00
PBD : : Unwinder < bool > uw ( ignore_plugin_refill , true ) ;
favorite_plugins_search_hbox . show ( ) ;
plugin_search_entry . set_text ( " " ) ;
} else {
favorite_plugins_search_hbox . hide ( ) ;
}
refill_favorite_plugins ( ) ;
}
void
Mixer_UI : : plugin_search_entry_changed ( )
{
2024-03-26 12:12:18 -04:00
if ( Profile - > get_livetrax ( ) ) {
return ;
}
2024-02-26 07:46:09 -05:00
if ( plugin_list_mode = = PLM_Favorite ) {
2020-06-24 23:52:38 -04:00
refill_favorite_plugins ( ) ;
}
}
void
Mixer_UI : : plugin_search_clear_button_clicked ( )
{
plugin_search_entry . set_text ( " " ) ;
}
2015-12-21 22:43:26 -05:00
void
2015-12-22 17:06:08 -05:00
Mixer_UI : : refiller ( PluginInfoList & result , const PluginInfoList & plugs )
2015-12-21 22:43:26 -05:00
{
2024-04-02 20:00:16 -04:00
if ( Profile - > get_livetrax ( ) ) {
return ;
}
2015-12-22 17:06:08 -05:00
PluginManager & manager ( PluginManager : : instance ( ) ) ;
2024-02-26 07:46:09 -05:00
PluginListMode plm = plugin_list_mode ;
2018-01-29 18:45:42 -05:00
2020-06-24 23:52:38 -04:00
std : : string searchstr = plugin_search_entry . get_text ( ) ;
setup_search_string ( searchstr ) ;
for ( PluginInfoList : : const_iterator i = plugs . begin ( ) ; i ! = plugs . end ( ) ; + + i ) {
bool maybe_show = true ;
2018-01-29 18:45:42 -05:00
2020-06-24 23:52:38 -04:00
if ( plm = = PLM_Favorite ) {
if ( manager . get_status ( * i ) ! = PluginManager : : Favorite ) {
maybe_show = false ;
}
2018-01-29 18:45:42 -05:00
2020-06-24 23:52:38 -04:00
if ( maybe_show & & ! searchstr . empty ( ) ) {
maybe_show = false ;
/* check name */
std : : string compstr = ( * i ) - > name ;
setup_search_string ( compstr ) ;
maybe_show | = match_search_strings ( compstr , searchstr ) ;
/* check tags */
2021-08-03 14:56:13 -04:00
std : : string tags = manager . get_tags_as_string ( * i ) ;
setup_search_string ( tags ) ;
maybe_show | = match_search_strings ( tags , searchstr ) ;
2020-06-24 23:52:38 -04:00
}
} else {
2020-06-25 14:14:57 -04:00
int64_t lru ;
2020-06-24 23:52:38 -04:00
uint64_t use_count ;
if ( ! manager . stats ( * i , lru , use_count ) ) {
maybe_show = false ;
}
if ( plm = = PLM_Recent & & lru = = 0 ) {
maybe_show = false ;
2018-01-29 18:45:42 -05:00
}
}
2020-06-24 23:52:38 -04:00
if ( ! maybe_show ) {
continue ;
}
2015-12-22 17:06:08 -05:00
result . push_back ( * i ) ;
2015-12-21 22:43:26 -05:00
}
}
void
Mixer_UI : : refill_favorite_plugins ( )
{
2024-04-02 20:00:16 -04:00
if ( Profile - > get_livetrax ( ) ) {
return ;
}
2020-06-24 23:52:38 -04:00
if ( ignore_plugin_refill ) {
return ;
}
2015-12-22 17:06:08 -05:00
PluginInfoList plugs ;
2015-12-21 22:43:26 -05:00
PluginManager & mgr ( PluginManager : : instance ( ) ) ;
# ifdef WINDOWS_VST_SUPPORT
2015-12-22 17:06:08 -05:00
refiller ( plugs , mgr . windows_vst_plugin_info ( ) ) ;
2015-12-21 22:43:26 -05:00
# endif
# ifdef LXVST_SUPPORT
2015-12-22 17:06:08 -05:00
refiller ( plugs , mgr . lxvst_plugin_info ( ) ) ;
2015-12-21 22:43:26 -05:00
# endif
2016-11-13 10:32:30 -05:00
# ifdef MACVST_SUPPORT
refiller ( plugs , mgr . mac_vst_plugin_info ( ) ) ;
# endif
2019-11-02 23:11:27 -04:00
# ifdef VST3_SUPPORT
refiller ( plugs , mgr . vst3_plugin_info ( ) ) ;
# endif
2015-12-21 22:43:26 -05:00
# ifdef AUDIOUNIT_SUPPORT
2015-12-22 17:06:08 -05:00
refiller ( plugs , mgr . au_plugin_info ( ) ) ;
2015-12-21 22:43:26 -05:00
# endif
2015-12-22 17:06:08 -05:00
refiller ( plugs , mgr . ladspa_plugin_info ( ) ) ;
2020-09-15 11:01:49 -04:00
refiller ( plugs , mgr . lv2_plugin_info ( ) ) ;
2016-04-28 19:26:46 -04:00
refiller ( plugs , mgr . lua_plugin_info ( ) ) ;
2015-12-22 17:06:08 -05:00
2024-02-26 07:46:09 -05:00
switch ( plugin_list_mode ) {
2020-06-24 23:52:38 -04:00
default :
/* use favorites as-is */
break ;
case PLM_TopHits :
{
2020-06-25 14:46:01 -04:00
PluginChartsSorter cmp ;
2020-06-24 23:52:38 -04:00
plugs . sort ( cmp ) ;
2020-06-26 06:45:39 -04:00
plugs . resize ( std : : min ( plugs . size ( ) , size_t ( UIConfiguration : : instance ( ) . get_max_plugin_chart ( ) ) ) ) ;
2020-06-24 23:52:38 -04:00
}
break ;
case PLM_Recent :
{
2020-06-25 14:46:01 -04:00
PluginRecentSorter cmp ;
2020-06-24 23:52:38 -04:00
plugs . sort ( cmp ) ;
plugs . resize ( std : : min ( plugs . size ( ) , size_t ( 10 ) ) ) ;
2020-06-26 06:45:39 -04:00
plugs . resize ( std : : min ( plugs . size ( ) , size_t ( UIConfiguration : : instance ( ) . get_max_plugin_recent ( ) ) ) ) ;
2020-06-24 23:52:38 -04:00
}
break ;
}
plugin_list = plugs ;
2015-12-22 17:06:08 -05:00
sync_treeview_from_favorite_order ( ) ;
2020-06-24 23:52:38 -04:00
//store_current_favorite_order ();
2015-12-22 17:06:08 -05:00
}
2018-01-29 18:45:42 -05:00
void
2020-06-24 23:52:38 -04:00
Mixer_UI : : maybe_refill_favorite_plugins ( PluginListMode plm )
2018-01-29 18:45:42 -05:00
{
2020-06-24 23:52:38 -04:00
switch ( plm ) {
case PLM_Favorite :
2024-02-26 07:46:09 -05:00
if ( plugin_list_mode = = PLM_Favorite ) {
2020-06-24 23:52:38 -04:00
refill_favorite_plugins ( ) ;
}
break ;
default :
2024-02-26 07:46:09 -05:00
if ( plugin_list_mode ! = PLM_Favorite ) {
2020-06-24 23:52:38 -04:00
refill_favorite_plugins ( ) ;
}
break ;
2018-01-29 18:45:42 -05:00
}
}
2016-01-09 18:00:07 -05:00
void
Mixer_UI : : sync_treeview_favorite_ui_state ( const TreeModel : : Path & path , const TreeModel : : iterator & )
{
TreeIter iter ;
if ( ! ( iter = favorite_plugins_model - > get_iter ( path ) ) ) {
return ;
}
ARDOUR : : PluginPresetPtr ppp = ( * iter ) [ favorite_plugins_columns . plugin ] ;
if ( ! ppp ) {
return ;
}
PluginInfoPtr pip = ppp - > _pip ;
if ( favorite_ui_state . find ( pip - > unique_id ) ! = favorite_ui_state . end ( ) ) {
if ( favorite_ui_state [ pip - > unique_id ] ) {
favorite_plugins_display . expand_row ( path , true ) ;
}
}
}
2015-12-22 17:06:08 -05:00
void
Mixer_UI : : sync_treeview_from_favorite_order ( )
{
2020-06-24 23:52:38 -04:00
PBD : : Unwinder < bool > uw ( ignore_plugin_reorder , true ) ;
2024-02-26 07:46:09 -05:00
switch ( plugin_list_mode ) {
2020-06-26 06:47:11 -04:00
case PLM_Favorite :
{
PluginUIOrderSorter cmp ( favorite_ui_order ) ;
plugin_list . sort ( cmp ) ;
}
break ;
case PLM_TopHits :
{
PluginABCSorter cmp ;
plugin_list . sort ( cmp ) ;
}
case PLM_Recent :
break ;
2020-06-24 23:52:38 -04:00
}
2015-12-22 17:06:08 -05:00
favorite_plugins_model - > clear ( ) ;
2020-06-24 23:52:38 -04:00
for ( PluginInfoList : : const_iterator i = plugin_list . begin ( ) ; i ! = plugin_list . end ( ) ; + + i ) {
2015-12-25 10:10:09 -05:00
PluginInfoPtr pip = ( * i ) ;
2015-12-22 17:06:08 -05:00
TreeModel : : Row newrow = * ( favorite_plugins_model - > append ( ) ) ;
newrow [ favorite_plugins_columns . name ] = ( * i ) - > name ;
2015-12-25 10:10:09 -05:00
newrow [ favorite_plugins_columns . plugin ] = PluginPresetPtr ( new PluginPreset ( pip ) ) ;
if ( ! _session ) {
continue ;
}
2016-01-09 09:22:40 -05:00
vector < ARDOUR : : Plugin : : PresetRecord > presets = ( * i ) - > get_presets ( true ) ;
2015-12-25 10:10:09 -05:00
for ( vector < ARDOUR : : Plugin : : PresetRecord > : : const_iterator j = presets . begin ( ) ; j ! = presets . end ( ) ; + + j ) {
2018-12-18 08:05:57 -05:00
if ( ! ( * j ) . user ) {
continue ;
}
2015-12-25 10:10:09 -05:00
Gtk : : TreeModel : : Row child_row = * ( favorite_plugins_model - > append ( newrow . children ( ) ) ) ;
child_row [ favorite_plugins_columns . name ] = ( * j ) . label ;
child_row [ favorite_plugins_columns . plugin ] = PluginPresetPtr ( new PluginPreset ( pip , & ( * j ) ) ) ;
}
2015-12-26 09:51:02 -05:00
if ( favorite_ui_state . find ( pip - > unique_id ) ! = favorite_ui_state . end ( ) ) {
if ( favorite_ui_state [ pip - > unique_id ] ) {
2015-12-25 18:43:59 -05:00
favorite_plugins_display . expand_row ( favorite_plugins_model - > get_path ( newrow ) , true ) ;
}
2015-12-26 09:51:02 -05:00
}
2015-12-22 17:06:08 -05:00
}
2015-12-21 22:43:26 -05:00
}
2015-12-25 10:10:09 -05:00
2015-12-25 11:11:47 -05:00
void
2015-12-26 18:37:53 -05:00
Mixer_UI : : popup_note_context_menu ( GdkEventButton * ev )
2015-12-25 11:11:47 -05:00
{
2015-12-26 18:37:53 -05:00
using namespace Gtk : : Menu_Helpers ;
2019-03-07 11:02:12 -05:00
Gtk : : Menu * m = ARDOUR_UI : : instance ( ) - > shared_popup_menu ( ) ;
2015-12-26 18:37:53 -05:00
MenuList & items = m - > items ( ) ;
2016-07-06 13:37:30 -04:00
if ( _selection . axes . empty ( ) ) {
2015-12-26 18:37:53 -05:00
items . push_back ( MenuElem ( _ ( " No Track/Bus is selected. " ) ) ) ;
2015-12-27 12:17:45 -05:00
} else {
items . push_back ( MenuElem ( _ ( " Add at the top " ) ,
sigc : : bind ( sigc : : mem_fun ( * this , & Mixer_UI : : add_selected_processor ) , AddTop ) ) ) ;
items . push_back ( MenuElem ( _ ( " Add Pre-Fader " ) ,
sigc : : bind ( sigc : : mem_fun ( * this , & Mixer_UI : : add_selected_processor ) , AddPreFader ) ) ) ;
items . push_back ( MenuElem ( _ ( " Add Post-Fader " ) ,
sigc : : bind ( sigc : : mem_fun ( * this , & Mixer_UI : : add_selected_processor ) , AddPostFader ) ) ) ;
items . push_back ( MenuElem ( _ ( " Add at the end " ) ,
sigc : : bind ( sigc : : mem_fun ( * this , & Mixer_UI : : add_selected_processor ) , AddBottom ) ) ) ;
}
2015-12-27 21:19:28 -05:00
2015-12-27 12:17:45 -05:00
items . push_back ( SeparatorElem ( ) ) ;
2015-12-27 21:19:28 -05:00
2015-12-27 12:17:45 -05:00
items . push_back ( MenuElem ( _ ( " Remove from favorites " ) , sigc : : mem_fun ( * this , & Mixer_UI : : remove_selected_from_favorites ) ) ) ;
2015-12-27 21:19:28 -05:00
ARDOUR : : PluginPresetPtr ppp = selected_plugin ( ) ;
2016-01-07 16:34:19 -05:00
if ( ppp & & ppp - > _preset . valid & & ppp - > _preset . user ) {
2016-01-13 12:01:39 -05:00
// we cannot currently delete AU presets
if ( ! ppp - > _pip | | ppp - > _pip - > type ! = AudioUnit ) {
items . push_back ( MenuElem ( _ ( " Delete Preset " ) , sigc : : mem_fun ( * this , & Mixer_UI : : delete_selected_preset ) ) ) ;
}
2015-12-27 21:19:28 -05:00
}
2015-12-26 18:37:53 -05:00
m - > popup ( ev - > button , ev - > time ) ;
}
bool
Mixer_UI : : plugin_row_button_press ( GdkEventButton * ev )
{
2018-01-29 18:45:42 -05:00
if ( ( ev - > type = = GDK_BUTTON_PRESS ) & & ( ev - > button = = 3 ) ) {
2015-12-28 11:03:40 -05:00
TreeModel : : Path path ;
TreeViewColumn * column ;
int cellx , celly ;
if ( favorite_plugins_display . get_path_at_pos ( ( int ) ev - > x , ( int ) ev - > y , path , column , cellx , celly ) ) {
Glib : : RefPtr < Gtk : : TreeView : : Selection > selection = favorite_plugins_display . get_selection ( ) ;
if ( selection ) {
selection - > unselect_all ( ) ;
selection - > select ( path ) ;
}
}
2016-01-07 08:35:10 -05:00
ARDOUR : : PluginPresetPtr ppp = selected_plugin ( ) ;
if ( ppp ) {
popup_note_context_menu ( ev ) ;
}
2015-12-26 18:37:53 -05:00
}
return false ;
}
2015-12-27 21:19:28 -05:00
PluginPresetPtr
Mixer_UI : : selected_plugin ( )
2015-12-26 18:37:53 -05:00
{
Glib : : RefPtr < Gtk : : TreeView : : Selection > selection = favorite_plugins_display . get_selection ( ) ;
if ( ! selection ) {
2015-12-27 21:19:28 -05:00
return PluginPresetPtr ( ) ;
2015-12-26 18:37:53 -05:00
}
Gtk : : TreeModel : : iterator iter = selection - > get_selected ( ) ;
if ( ! iter ) {
2015-12-27 21:19:28 -05:00
return PluginPresetPtr ( ) ;
2015-12-26 18:37:53 -05:00
}
2015-12-27 21:19:28 -05:00
return ( * iter ) [ favorite_plugins_columns . plugin ] ;
2015-12-26 18:37:53 -05:00
}
2015-12-27 12:17:45 -05:00
void
2015-12-27 21:19:28 -05:00
Mixer_UI : : add_selected_processor ( ProcessorPosition pos )
2015-12-27 12:17:45 -05:00
{
2015-12-27 21:19:28 -05:00
ARDOUR : : PluginPresetPtr ppp = selected_plugin ( ) ;
if ( ppp ) {
add_favorite_processor ( ppp , pos ) ;
}
}
void
Mixer_UI : : delete_selected_preset ( )
{
if ( ! _session ) {
2015-12-27 12:17:45 -05:00
return ;
}
2015-12-27 21:19:28 -05:00
ARDOUR : : PluginPresetPtr ppp = selected_plugin ( ) ;
2016-01-07 16:34:19 -05:00
if ( ! ppp | | ! ppp - > _preset . valid | | ! ppp - > _preset . user ) {
2015-12-27 21:19:28 -05:00
return ;
}
PluginPtr plugin = ppp - > _pip - > load ( * _session ) ;
plugin - > get_presets ( ) ;
plugin - > remove_preset ( ppp - > _preset . label ) ;
}
void
Mixer_UI : : remove_selected_from_favorites ( )
{
ARDOUR : : PluginPresetPtr ppp = selected_plugin ( ) ;
if ( ! ppp ) {
2015-12-27 12:17:45 -05:00
return ;
}
PluginManager : : PluginStatusType status = PluginManager : : Normal ;
PluginManager & manager ( PluginManager : : instance ( ) ) ;
manager . set_status ( ppp - > _pip - > type , ppp - > _pip - > unique_id , status ) ;
manager . save_statuses ( ) ;
}
2015-12-26 18:37:53 -05:00
void
Mixer_UI : : plugin_row_activated ( const TreeModel : : Path & path , TreeViewColumn * column )
{
2015-12-25 11:11:47 -05:00
TreeIter iter ;
if ( ! ( iter = favorite_plugins_model - > get_iter ( path ) ) ) {
return ;
}
ARDOUR : : PluginPresetPtr ppp = ( * iter ) [ favorite_plugins_columns . plugin ] ;
2015-12-26 18:37:53 -05:00
add_favorite_processor ( ppp , AddPreFader ) ; // TODO: preference?!
}
2015-12-25 11:11:47 -05:00
2015-12-26 18:37:53 -05:00
void
Mixer_UI : : add_favorite_processor ( ARDOUR : : PluginPresetPtr ppp , ProcessorPosition pos )
{
2016-07-06 13:37:30 -04:00
if ( ! _session | | _selection . axes . empty ( ) ) {
2015-12-26 18:37:53 -05:00
return ;
}
PluginInfoPtr pip = ppp - > _pip ;
2016-07-06 13:37:30 -04:00
for ( AxisViewSelection : : iterator i = _selection . axes . begin ( ) ; i ! = _selection . axes . end ( ) ; + + i ) {
2023-02-16 18:33:28 -05:00
std : : shared_ptr < ARDOUR : : Route > rt = std : : dynamic_pointer_cast < ARDOUR : : Route > ( ( * i ) - > stripable ( ) ) ;
2016-07-06 13:37:30 -04:00
if ( ! rt ) {
continue ;
}
2015-12-25 11:11:47 -05:00
PluginPtr p = pip - > load ( * _session ) ;
2016-07-06 13:37:30 -04:00
if ( ! p ) {
continue ;
}
2015-12-25 11:11:47 -05:00
if ( ppp - > _preset . valid ) {
p - > load_preset ( ppp - > _preset ) ;
}
Route : : ProcessorStreams err ;
2023-07-21 11:56:50 -04:00
std : : shared_ptr < Processor > processor ( new PluginInsert ( * _session , * rt , p ) ) ;
2015-12-26 18:37:53 -05:00
switch ( pos ) {
case AddTop :
rt - > add_processor_by_index ( processor , 0 , & err , Config - > get_new_plugins_active ( ) ) ;
break ;
case AddPreFader :
rt - > add_processor ( processor , PreFader , & err , Config - > get_new_plugins_active ( ) ) ;
break ;
case AddPostFader :
2015-12-27 09:32:24 -05:00
{
int idx = 0 ;
2016-05-01 07:11:43 -04:00
int pos = 0 ;
2015-12-27 09:32:24 -05:00
for ( ; ; + + idx ) {
2023-02-16 18:33:28 -05:00
std : : shared_ptr < Processor > np = rt - > nth_processor ( idx ) ;
2016-05-01 07:11:43 -04:00
if ( ! np ) {
2015-12-27 09:32:24 -05:00
break ;
}
2016-05-01 07:11:43 -04:00
if ( ! np - > display_to_user ( ) ) {
continue ;
}
2023-02-16 18:33:28 -05:00
if ( std : : dynamic_pointer_cast < Amp > ( np ) & & // Fader, not Trim
std : : dynamic_pointer_cast < Amp > ( np ) - > gain_control ( ) - > parameter ( ) . type ( ) = = GainAutomation ) {
2016-05-01 07:11:43 -04:00
break ;
}
+ + pos ;
2015-12-27 09:32:24 -05:00
}
2016-05-01 07:11:43 -04:00
rt - > add_processor_by_index ( processor , + + pos , & err , Config - > get_new_plugins_active ( ) ) ;
2015-12-27 09:32:24 -05:00
}
2015-12-26 18:37:53 -05:00
break ;
case AddBottom :
rt - > add_processor_by_index ( processor , - 1 , & err , Config - > get_new_plugins_active ( ) ) ;
break ;
}
2015-12-25 11:11:47 -05:00
}
}
2015-12-25 10:10:09 -05:00
bool
PluginTreeStore : : row_drop_possible_vfunc ( const Gtk : : TreeModel : : Path & dest , const Gtk : : SelectionData & data ) const
{
if ( data . get_target ( ) ! = " GTK_TREE_MODEL_ROW " ) {
return false ;
}
2016-01-09 18:25:04 -05:00
// only allow to re-order top-level items
TreePath src ;
if ( TreePath : : get_from_selection_data ( data , src ) ) {
if ( src . up ( ) & & src . up ( ) ) {
return false ;
}
}
// don't allow to drop as child-rows.
2015-12-25 10:10:09 -05:00
Gtk : : TreeModel : : Path _dest = dest ; // un const
const bool is_child = _dest . up ( ) ; // explicit bool for clang
if ( ! is_child | | _dest . empty ( ) ) {
return true ;
}
return false ;
}
2015-12-27 22:11:45 -05:00
2020-06-24 23:52:38 -04:00
bool
Mixer_UI : : plugin_drag_motion ( const Glib : : RefPtr < Gdk : : DragContext > & ctx , int x , int y , guint time )
{
std : : string target = favorite_plugins_display . drag_dest_find_target ( ctx , favorite_plugins_display . drag_dest_get_target_list ( ) ) ;
if ( target . empty ( ) ) {
ctx - > drag_status ( Gdk : : DragAction ( 0 ) , time ) ;
return false ;
}
if ( target = = " GTK_TREE_MODEL_ROW " ) {
2024-02-26 07:46:09 -05:00
if ( plugin_list_mode = = PLM_Favorite & & plugin_search_entry . get_text ( ) . empty ( ) ) {
2020-06-24 23:52:38 -04:00
/* re-order rows */
ctx - > drag_status ( Gdk : : ACTION_MOVE , time ) ;
return true ;
}
2022-01-10 15:29:29 -05:00
} else if ( target = = " x-ardour/plugin.preset " ) {
2020-06-24 23:52:38 -04:00
ctx - > drag_status ( Gdk : : ACTION_COPY , time ) ;
2024-02-26 07:46:09 -05:00
//favorite_plugins_mode_combo.set_text (_("Favorite Plugins"));
2020-06-24 23:52:38 -04:00
return true ;
}
ctx - > drag_status ( Gdk : : DragAction ( 0 ) , time ) ;
return false ;
}
2015-12-27 22:11:45 -05:00
void
Mixer_UI : : plugin_drop ( const Glib : : RefPtr < Gdk : : DragContext > & , const Gtk : : SelectionData & data )
{
2022-01-10 15:29:29 -05:00
if ( data . get_target ( ) ! = " x-ardour/plugin.preset " ) {
2015-12-27 22:11:45 -05:00
return ;
}
2015-12-28 10:08:35 -05:00
if ( data . get_length ( ) ! = sizeof ( PluginPresetPtr ) ) {
return ;
}
2020-06-24 23:52:38 -04:00
2015-12-27 22:11:45 -05:00
const void * d = data . get_data ( ) ;
const PluginPresetPtr ppp = * ( static_cast < const PluginPresetPtr * > ( d ) ) ;
PluginManager : : PluginStatusType status = PluginManager : : Favorite ;
PluginManager & manager ( PluginManager : : instance ( ) ) ;
manager . set_status ( ppp - > _pip - > type , ppp - > _pip - > unique_id , status ) ;
manager . save_statuses ( ) ;
}
2016-02-29 21:26:45 -05:00
void
2023-02-16 18:33:28 -05:00
Mixer_UI : : do_vca_assign ( std : : shared_ptr < VCA > vca )
2016-02-29 21:26:45 -05:00
{
/* call protected MixerActor:: method */
vca_assign ( vca ) ;
}
void
2023-02-16 18:33:28 -05:00
Mixer_UI : : do_vca_unassign ( std : : shared_ptr < VCA > vca )
2016-02-29 21:26:45 -05:00
{
/* call protected MixerActor:: method */
vca_unassign ( vca ) ;
}
2016-05-18 15:56:52 -04:00
void
2023-02-16 18:33:28 -05:00
Mixer_UI : : show_spill ( std : : shared_ptr < Stripable > s )
2016-05-18 15:56:52 -04:00
{
2023-02-16 18:33:28 -05:00
std : : shared_ptr < Stripable > ss = spilled_strip . lock ( ) ;
2020-04-15 14:21:27 -04:00
if ( ss = = s ) {
return ;
}
spilled_strip = s ;
_spill_gone_connection . disconnect ( ) ;
show_spill_change ( s ) ; /* EMIT SIGNAL */
if ( s ) {
s - > DropReferences . connect ( _spill_gone_connection , invalidator ( * this ) , boost : : bind ( & Mixer_UI : : spill_nothing , this ) , gui_context ( ) ) ;
2021-03-28 11:46:01 -04:00
_group_tabs - > set_sensitive ( false ) ;
2020-04-15 14:21:27 -04:00
} else {
2021-03-28 11:46:01 -04:00
_group_tabs - > set_sensitive ( true ) ;
2016-05-18 15:56:52 -04:00
}
2020-04-15 14:21:27 -04:00
redisplay_track_list ( ) ;
}
void
Mixer_UI : : spill_nothing ( )
{
2023-02-16 18:33:28 -05:00
show_spill ( std : : shared_ptr < Stripable > ( ) ) ;
2016-05-18 15:56:52 -04:00
}
bool
2023-02-16 18:33:28 -05:00
Mixer_UI : : showing_spill_for ( std : : shared_ptr < Stripable > s ) const
2016-05-18 15:56:52 -04:00
{
2017-01-16 16:30:26 -05:00
return s = = spilled_strip . lock ( ) ;
2016-05-18 15:56:52 -04:00
}
2016-07-06 15:20:42 -04:00
void
Mixer_UI : : register_actions ( )
{
2018-12-11 05:06:26 -05:00
Glib : : RefPtr < ActionGroup > group = ActionManager : : create_action_group ( bindings , X_ ( " Mixer " ) ) ;
2017-03-10 11:50:44 -05:00
2018-12-10 08:33:31 -05:00
ActionManager : : register_action ( group , " solo " , _ ( " Toggle Solo on Mixer-Selected Tracks/Busses " ) , sigc : : mem_fun ( * this , & Mixer_UI : : solo_action ) ) ;
ActionManager : : register_action ( group , " mute " , _ ( " Toggle Mute on Mixer-Selected Tracks/Busses " ) , sigc : : mem_fun ( * this , & Mixer_UI : : mute_action ) ) ;
ActionManager : : register_action ( group , " recenable " , _ ( " Toggle Rec-enable on Mixer-Selected Tracks/Busses " ) , sigc : : mem_fun ( * this , & Mixer_UI : : rec_enable_action ) ) ;
ActionManager : : register_action ( group , " increment-gain " , _ ( " Decrease Gain on Mixer-Selected Tracks/Busses " ) , sigc : : mem_fun ( * this , & Mixer_UI : : step_gain_up_action ) ) ;
ActionManager : : register_action ( group , " decrement-gain " , _ ( " Increase Gain on Mixer-Selected Tracks/Busses " ) , sigc : : mem_fun ( * this , & Mixer_UI : : step_gain_down_action ) ) ;
ActionManager : : register_action ( group , " unity-gain " , _ ( " Set Gain to 0dB on Mixer-Selected Tracks/Busses " ) , sigc : : mem_fun ( * this , & Mixer_UI : : unity_gain_action ) ) ;
2016-07-06 15:20:42 -04:00
2018-12-10 08:33:31 -05:00
ActionManager : : register_action ( group , " copy-processors " , _ ( " Copy Selected Processors " ) , sigc : : mem_fun ( * this , & Mixer_UI : : copy_processors ) ) ;
ActionManager : : register_action ( group , " cut-processors " , _ ( " Cut Selected Processors " ) , sigc : : mem_fun ( * this , & Mixer_UI : : cut_processors ) ) ;
ActionManager : : register_action ( group , " paste-processors " , _ ( " Paste Selected Processors " ) , sigc : : mem_fun ( * this , & Mixer_UI : : paste_processors ) ) ;
ActionManager : : register_action ( group , " delete-processors " , _ ( " Delete Selected Processors " ) , sigc : : mem_fun ( * this , & Mixer_UI : : delete_processors ) ) ;
2022-12-02 13:50:39 -05:00
ActionManager : : register_action ( group , " delete-processors-alt " , _ ( " Delete Selected Processors " ) , sigc : : mem_fun ( * this , & Mixer_UI : : delete_processors ) ) ;
2018-12-10 08:33:31 -05:00
ActionManager : : register_action ( group , " select-all-processors " , _ ( " Select All (visible) Processors " ) , sigc : : mem_fun ( * this , & Mixer_UI : : select_all_processors ) ) ;
ActionManager : : register_action ( group , " toggle-processors " , _ ( " Toggle Selected Processors " ) , sigc : : mem_fun ( * this , & Mixer_UI : : toggle_processors ) ) ;
ActionManager : : register_action ( group , " ab-plugins " , _ ( " Toggle Selected Plugins " ) , sigc : : mem_fun ( * this , & Mixer_UI : : ab_plugins ) ) ;
ActionManager : : register_action ( group , " select-none " , _ ( " Deselect all strips and processors " ) , sigc : : mem_fun ( * this , & Mixer_UI : : select_none ) ) ;
2016-07-06 15:20:42 -04:00
2018-12-10 08:33:31 -05:00
ActionManager : : register_action ( group , " select-next-stripable " , _ ( " Select Next Mixer Strip " ) , sigc : : mem_fun ( * this , & Mixer_UI : : select_next_strip ) ) ;
2020-04-13 10:09:40 -04:00
ActionManager : : register_action ( group , " select-prev-stripable " , _ ( " Select Previous Mixer Strip " ) , sigc : : mem_fun ( * this , & Mixer_UI : : select_prev_strip ) ) ;
2018-08-24 10:07:55 -04:00
2018-12-10 08:33:31 -05:00
ActionManager : : register_action ( group , " scroll-left " , _ ( " Scroll Mixer Window to the left " ) , sigc : : mem_fun ( * this , & Mixer_UI : : scroll_left ) ) ;
ActionManager : : register_action ( group , " scroll-right " , _ ( " Scroll Mixer Window to the right " ) , sigc : : mem_fun ( * this , & Mixer_UI : : scroll_right ) ) ;
2016-07-06 15:20:42 -04:00
2018-12-10 08:33:31 -05:00
ActionManager : : register_action ( group , " toggle-midi-input-active " , _ ( " Toggle MIDI Input Active for Mixer-Selected Tracks/Busses " ) ,
2016-07-06 15:20:42 -04:00
sigc : : bind ( sigc : : mem_fun ( * this , & Mixer_UI : : toggle_midi_input_active ) , false ) ) ;
2018-12-03 19:55:52 -05:00
2018-12-10 08:33:31 -05:00
ActionManager : : register_toggle_action ( group , X_ ( " ToggleMixerList " ) , _ ( " Mixer: Show Mixer List " ) , sigc : : mem_fun ( * this , & Mixer_UI : : toggle_mixer_list ) ) ;
2018-12-03 19:55:52 -05:00
2018-12-10 08:33:31 -05:00
ActionManager : : register_toggle_action ( group , X_ ( " ToggleVCAPane " ) , _ ( " Mixer: Show VCAs " ) , sigc : : mem_fun ( * this , & Mixer_UI : : toggle_vcas ) ) ;
2018-12-03 19:55:52 -05:00
# ifdef MIXBUS
2019-01-23 10:05:21 -05:00
ActionManager : : register_toggle_action ( group , X_ ( " ToggleMixbusPane " ) , _ ( " Mixer: Show Mixbusses " ) , sigc : : mem_fun ( * this , & Mixer_UI : : toggle_mixbuses ) ) ;
2018-12-03 19:55:52 -05:00
# endif
2018-12-10 08:33:31 -05:00
ActionManager : : register_toggle_action ( group , X_ ( " ToggleMonitorSection " ) , _ ( " Mixer: Show Monitor Section " ) , sigc : : mem_fun ( * this , & Mixer_UI : : toggle_monitor_section ) ) ;
2019-09-11 19:36:05 -04:00
2024-01-02 08:26:56 -05:00
# ifdef MIXBUS
ActionManager : : register_toggle_action ( group , X_ ( " ToggleSurroundMaster " ) , _ ( " Atmos Surround Master " ) , sigc : : mem_fun ( * this , & Mixer_UI : : toggle_surround_master ) ) ;
# else
ActionManager : : register_toggle_action ( group , X_ ( " ToggleSurroundMaster " ) , _ ( " Surround Master " ) , sigc : : mem_fun ( * this , & Mixer_UI : : toggle_surround_master ) ) ;
# endif
2019-09-11 19:36:05 -04:00
ActionManager : : register_toggle_action ( group , X_ ( " ToggleFoldbackStrip " ) , _ ( " Mixer: Show Foldback Strip " ) , sigc : : mem_fun ( * this , & Mixer_UI : : toggle_foldback_strip ) ) ;
2019-11-20 11:37:14 -05:00
ActionManager : : register_toggle_action ( group , X_ ( " toggle-disk-monitor " ) , _ ( " Toggle Disk Monitoring " ) , sigc : : bind ( sigc : : mem_fun ( * this , & Mixer_UI : : toggle_monitor_action ) , MonitorDisk , false , false ) ) ;
ActionManager : : register_toggle_action ( group , X_ ( " toggle-input-monitor " ) , _ ( " Toggle Input Monitoring " ) , sigc : : bind ( sigc : : mem_fun ( * this , & Mixer_UI : : toggle_monitor_action ) , MonitorInput , false , false ) ) ;
2022-05-23 10:08:30 -04:00
for ( size_t i = 0 ; i < 12 ; + + i ) {
2022-05-24 09:18:07 -04:00
std : : string a = string_compose ( X_ ( " store-mixer-scene-%1 " ) , i + 1 ) ;
std : : string n = string_compose ( _ ( " Store Mixer Scene #%1 " ) , i + 1 ) ;
2022-05-23 10:08:30 -04:00
ActionManager : : register_action ( group , a . c_str ( ) , n . c_str ( ) ,
sigc : : bind ( sigc : : mem_fun ( * this , & Mixer_UI : : store_mixer_scene ) , i ) ) ;
2022-05-24 09:18:07 -04:00
a = string_compose ( X_ ( " recall-mixer-scene-%1 " ) , i + 1 ) ;
n = string_compose ( _ ( " Recall Mixer Scene #%1 " ) , i + 1 ) ;
2022-05-23 10:08:30 -04:00
ActionManager : : register_action ( group , a . c_str ( ) , n . c_str ( ) ,
2022-10-17 17:13:40 -04:00
sigc : : bind ( sigc : : mem_fun ( * this , & Mixer_UI : : recall_mixer_scene ) , i , true , false ) ) ;
2022-05-23 10:08:30 -04:00
2022-05-24 09:18:07 -04:00
a = string_compose ( X_ ( " clear-mixer-scene-%1 " ) , i + 1 ) ;
n = string_compose ( _ ( " Clear Mixer Scene #%1 " ) , i + 1 ) ;
2022-05-23 10:08:30 -04:00
ActionManager : : register_action ( group , a . c_str ( ) , n . c_str ( ) ,
2022-06-02 13:07:28 -04:00
sigc : : bind ( sigc : : mem_fun ( * this , & Mixer_UI : : clear_mixer_scene ) , i , true ) ) ;
2022-05-23 10:08:30 -04:00
}
2016-07-06 15:20:42 -04:00
}
void
Mixer_UI : : load_bindings ( )
{
2018-12-10 08:33:31 -05:00
bindings = Bindings : : get_bindings ( X_ ( " Mixer " ) ) ;
2016-07-06 15:20:42 -04:00
}
template < class T > void
2023-02-16 18:33:28 -05:00
Mixer_UI : : control_action ( std : : shared_ptr < T > ( Stripable : : * get_control ) ( ) const )
2016-07-06 15:20:42 -04:00
{
2023-07-19 19:24:57 -04:00
std : : shared_ptr < AutomationControlList > cl ( new AutomationControlList ) ;
2023-02-16 18:33:28 -05:00
std : : shared_ptr < AutomationControl > ac ;
2016-07-06 15:20:42 -04:00
bool val = false ;
bool have_val = false ;
set_axis_targets_for_operation ( ) ;
BOOST_FOREACH ( AxisView * r , _axis_targets ) {
2023-02-16 18:33:28 -05:00
std : : shared_ptr < Stripable > s = r - > stripable ( ) ;
2016-07-06 15:20:42 -04:00
if ( s ) {
ac = ( s . get ( ) - > * get_control ) ( ) ;
if ( ac ) {
2020-09-26 11:14:59 -04:00
ac - > start_touch ( timepos_t ( _session - > audible_sample ( ) ) ) ;
2016-07-06 15:20:42 -04:00
cl - > push_back ( ac ) ;
if ( ! have_val ) {
val = ! ac - > get_value ( ) ;
have_val = true ;
}
}
}
}
_session - > set_controls ( cl , val , Controllable : : UseGroup ) ;
}
void
Mixer_UI : : solo_action ( )
{
control_action ( & Stripable : : solo_control ) ;
}
void
Mixer_UI : : mute_action ( )
{
control_action ( & Stripable : : mute_control ) ;
}
void
Mixer_UI : : rec_enable_action ( )
{
control_action ( & Stripable : : rec_enable_control ) ;
}
2022-10-17 17:24:55 -04:00
ControllableSet
2017-07-08 09:43:32 -04:00
Mixer_UI : : selected_gaincontrols ( )
2016-07-06 15:20:42 -04:00
{
set_axis_targets_for_operation ( ) ;
2022-10-17 17:24:55 -04:00
ControllableSet rv ;
2016-07-06 15:20:42 -04:00
BOOST_FOREACH ( AxisView * r , _axis_targets ) {
MixerStrip * ms = dynamic_cast < MixerStrip * > ( r ) ;
if ( ms ) {
2023-02-16 18:33:28 -05:00
std : : shared_ptr < GainControl > ac ( ms - > route ( ) - > gain_control ( ) ) ;
2023-07-19 19:24:57 -04:00
AutomationControlList cl ( ac - > grouped_controls ( ) ) ;
for ( AutomationControlList : : const_iterator c = cl . begin ( ) ; c ! = cl . end ( ) ; + + c ) {
2017-07-08 09:43:32 -04:00
rv . insert ( * c ) ;
}
rv . insert ( ac ) ;
2016-07-06 15:20:42 -04:00
}
}
2017-07-08 09:43:32 -04:00
return rv ;
2016-07-06 15:20:42 -04:00
}
void
2017-07-08 09:43:32 -04:00
Mixer_UI : : step_gain_up_action ( )
2016-07-06 15:20:42 -04:00
{
2022-10-17 17:24:55 -04:00
ControllableSet acs = selected_gaincontrols ( ) ;
for ( ControllableSet : : const_iterator i = acs . begin ( ) ; i ! = acs . end ( ) ; + + i ) {
2023-02-16 18:33:28 -05:00
std : : shared_ptr < GainControl > ac = std : : dynamic_pointer_cast < GainControl > ( * i ) ;
2017-07-08 09:43:32 -04:00
assert ( ac ) ;
ac - > set_value ( dB_to_coefficient ( accurate_coefficient_to_dB ( ac - > get_value ( ) ) + 0.1 ) , Controllable : : NoGroup ) ;
}
}
2016-07-06 15:20:42 -04:00
2017-07-08 09:43:32 -04:00
void
Mixer_UI : : step_gain_down_action ( )
{
2022-10-17 17:24:55 -04:00
ControllableSet acs = selected_gaincontrols ( ) ;
for ( ControllableSet : : const_iterator i = acs . begin ( ) ; i ! = acs . end ( ) ; + + i ) {
2023-02-16 18:33:28 -05:00
std : : shared_ptr < GainControl > ac = std : : dynamic_pointer_cast < GainControl > ( * i ) ;
2017-07-08 09:43:32 -04:00
assert ( ac ) ;
ac - > set_value ( dB_to_coefficient ( accurate_coefficient_to_dB ( ac - > get_value ( ) ) - 0.1 ) , Controllable : : NoGroup ) ;
2016-07-06 15:20:42 -04:00
}
}
void
Mixer_UI : : unity_gain_action ( )
{
set_axis_targets_for_operation ( ) ;
BOOST_FOREACH ( AxisView * r , _axis_targets ) {
2023-02-16 18:33:28 -05:00
std : : shared_ptr < Stripable > s = r - > stripable ( ) ;
2016-07-06 15:20:42 -04:00
if ( s ) {
2023-02-16 18:33:28 -05:00
std : : shared_ptr < AutomationControl > ac = s - > gain_control ( ) ;
2016-07-06 15:20:42 -04:00
if ( ac ) {
ac - > set_value ( 1.0 , Controllable : : UseGroup ) ;
}
}
}
}
void
Mixer_UI : : copy_processors ( )
{
set_axis_targets_for_operation ( ) ;
BOOST_FOREACH ( AxisView * r , _axis_targets ) {
MixerStrip * ms = dynamic_cast < MixerStrip * > ( r ) ;
if ( ms ) {
ms - > copy_processors ( ) ;
}
}
}
void
Mixer_UI : : cut_processors ( )
{
set_axis_targets_for_operation ( ) ;
BOOST_FOREACH ( AxisView * r , _axis_targets ) {
MixerStrip * ms = dynamic_cast < MixerStrip * > ( r ) ;
if ( ms ) {
ms - > cut_processors ( ) ;
}
}
}
void
Mixer_UI : : paste_processors ( )
{
set_axis_targets_for_operation ( ) ;
BOOST_FOREACH ( AxisView * r , _axis_targets ) {
MixerStrip * ms = dynamic_cast < MixerStrip * > ( r ) ;
if ( ms ) {
ms - > paste_processors ( ) ;
}
}
}
void
Mixer_UI : : select_all_processors ( )
{
set_axis_targets_for_operation ( ) ;
BOOST_FOREACH ( AxisView * r , _axis_targets ) {
MixerStrip * ms = dynamic_cast < MixerStrip * > ( r ) ;
if ( ms ) {
ms - > select_all_processors ( ) ;
}
}
}
void
Mixer_UI : : toggle_processors ( )
{
set_axis_targets_for_operation ( ) ;
BOOST_FOREACH ( AxisView * r , _axis_targets ) {
MixerStrip * ms = dynamic_cast < MixerStrip * > ( r ) ;
if ( ms ) {
ms - > toggle_processors ( ) ;
}
}
}
void
Mixer_UI : : ab_plugins ( )
{
set_axis_targets_for_operation ( ) ;
BOOST_FOREACH ( AxisView * r , _axis_targets ) {
MixerStrip * ms = dynamic_cast < MixerStrip * > ( r ) ;
if ( ms ) {
ms - > ab_plugins ( ) ;
}
}
}
void
2023-02-16 18:33:28 -05:00
Mixer_UI : : vca_assign ( std : : shared_ptr < VCA > vca )
2016-07-06 15:20:42 -04:00
{
set_axis_targets_for_operation ( ) ;
BOOST_FOREACH ( AxisView * r , _axis_targets ) {
MixerStrip * ms = dynamic_cast < MixerStrip * > ( r ) ;
if ( ms ) {
ms - > vca_assign ( vca ) ;
}
}
}
void
2023-02-16 18:33:28 -05:00
Mixer_UI : : vca_unassign ( std : : shared_ptr < VCA > vca )
2016-07-06 15:20:42 -04:00
{
set_axis_targets_for_operation ( ) ;
BOOST_FOREACH ( AxisView * r , _axis_targets ) {
MixerStrip * ms = dynamic_cast < MixerStrip * > ( r ) ;
if ( ms ) {
ms - > vca_unassign ( vca ) ;
}
}
}
2019-07-17 16:57:30 -04:00
2022-05-23 10:08:30 -04:00
void
Mixer_UI : : store_mixer_scene ( size_t n )
{
2022-06-01 09:48:44 -04:00
if ( ! _session ) {
return ;
}
std : : string str ;
/* if it already exists, prompt the user to overwrite an existing scene */
2023-02-16 18:33:28 -05:00
std : : shared_ptr < MixerScene > ms = _session - > nth_mixer_scene ( n , false ) ;
2022-06-01 09:48:44 -04:00
if ( ms & & ! ms - > empty ( ) ) {
ArdourMessageDialog md ( _ ( " Scene is already set. Overwrite it? " ) , false , MESSAGE_QUESTION , BUTTONS_YES_NO ) ;
if ( md . run ( ) ! = RESPONSE_YES ) {
return ;
}
str = ms - > name ( ) ;
} else {
time_t now ;
time ( & now ) ;
Glib : : DateTime tm ( Glib : : DateTime : : create_now_local ( now ) ) ;
str = Glib : : DateTime : : create_now_local ( ) . format ( " %FT%H.%M.%S " ) ;
}
/* prompt the user for a scene name */
ArdourWidgets : : Prompter name_prompter ( true ) ;
string result ;
bool done = false ;
name_prompter . set_title ( _ ( " Store Scene " ) ) ;
name_prompter . set_prompt ( _ ( " Scene name: " ) ) ;
name_prompter . set_initial_text ( str ) ;
name_prompter . add_button ( _ ( " Store " ) , Gtk : : RESPONSE_ACCEPT ) ;
name_prompter . show_all ( ) ;
while ( ! done ) {
switch ( name_prompter . run ( ) ) {
case Gtk : : RESPONSE_ACCEPT :
name_prompter . get_result ( result ) ;
name_prompter . hide ( ) ;
if ( result . length ( ) ) {
_session - > store_nth_mixer_scene ( n ) ;
2023-02-16 18:33:28 -05:00
std : : shared_ptr < MixerScene > ms = _session - > nth_mixer_scene ( n , false ) ;
2022-06-01 09:48:44 -04:00
ms - > set_name ( result ) ;
done = true ;
} else {
/* nothing entered, just get out of here */
done = true ;
2022-05-24 09:18:07 -04:00
}
2022-06-01 09:48:44 -04:00
break ;
default :
done = true ;
break ;
2022-05-24 09:18:07 -04:00
}
2022-05-23 10:08:30 -04:00
}
}
void
2022-10-17 17:13:40 -04:00
Mixer_UI : : recall_mixer_scene ( size_t n , bool interactive , bool for_selection )
2022-05-23 10:08:30 -04:00
{
2022-06-01 09:48:44 -04:00
if ( ! _session ) {
return ;
}
2023-02-16 18:33:28 -05:00
std : : shared_ptr < MixerScene > ms = _session - > nth_mixer_scene ( n , false ) ;
2022-06-02 13:07:28 -04:00
if ( ! ms | | ms - > empty ( ) ) {
2022-06-01 09:48:44 -04:00
return ;
}
2022-06-02 13:07:28 -04:00
// XXX this is really bad UX. Ardour should not have any "don't show this again" options.
if ( interactive & & 0 = = Config - > instant_xml ( X_ ( " no-scene-recall-warning " ) ) ) {
ArdourMessageDialog msg ( string_compose ( _ ( " Recall mixer scene \" %1 \" ? \n "
" This will overwrite your mixer settings! \n "
2022-07-07 11:07:46 -04:00
" This operation cannot be undone. " ) , ms - > name ( ) ) ,
false , MESSAGE_QUESTION , BUTTONS_YES_NO ) ;
2022-06-01 09:48:44 -04:00
2022-07-07 11:07:46 -04:00
msg . set_default_response ( RESPONSE_YES ) ;
2022-06-01 09:48:44 -04:00
VBox * vbox = msg . get_vbox ( ) ;
HBox hbox ;
CheckButton cb ( _ ( " Do not show this window again " ) ) ;
hbox . pack_start ( cb , true , false ) ;
vbox - > pack_start ( hbox ) ;
cb . show ( ) ;
vbox - > show ( ) ;
hbox . show ( ) ;
2022-07-07 11:07:46 -04:00
if ( msg . run ( ) ! = RESPONSE_YES ) {
2022-06-02 13:07:28 -04:00
return ;
2022-06-01 09:48:44 -04:00
}
if ( cb . get_active ( ) ) {
2022-06-02 13:07:28 -04:00
XMLNode node ( X_ ( " no-scene-recall-warning " ) ) ;
2022-06-01 09:48:44 -04:00
Config - > add_instant_xml ( node ) ;
}
}
2022-10-17 17:13:40 -04:00
if ( for_selection ) {
_session - > apply_nth_mixer_scene ( n , PublicEditor : : instance ( ) . get_selection ( ) . tracks . routelist ( ) ) ;
} else {
_session - > apply_nth_mixer_scene ( n ) ;
}
2022-05-23 10:08:30 -04:00
}
void
2022-06-02 13:07:28 -04:00
Mixer_UI : : clear_mixer_scene ( size_t n , bool interactive )
2022-05-23 10:08:30 -04:00
{
2022-06-01 09:48:44 -04:00
if ( ! _session ) {
return ;
}
2023-02-16 18:33:28 -05:00
std : : shared_ptr < MixerScene > ms = _session - > nth_mixer_scene ( n , false ) ;
2022-06-01 09:48:44 -04:00
if ( ! ms ) {
return ;
}
2022-06-02 13:07:28 -04:00
// XXX this is really bad UX. Ardour should not have any "don't show this again" options.
if ( interactive & & 0 = = Config - > instant_xml ( X_ ( " no-scene-clear-warning " ) ) ) {
ArdourMessageDialog msg ( string_compose ( _ ( " Clear mixer scene \" %1 \" ? \n "
2022-07-07 11:07:46 -04:00
" This operation cannot be undone. " ) , ms - > name ( ) ) ,
false , MESSAGE_QUESTION , BUTTONS_YES_NO ) ;
2022-06-01 09:48:44 -04:00
2022-07-07 11:07:46 -04:00
msg . set_default_response ( RESPONSE_YES ) ;
2022-06-01 09:48:44 -04:00
VBox * vbox = msg . get_vbox ( ) ;
HBox hbox ;
CheckButton cb ( _ ( " Do not show this window again " ) ) ;
hbox . pack_start ( cb , true , false ) ;
vbox - > pack_start ( hbox ) ;
cb . show ( ) ;
vbox - > show ( ) ;
hbox . show ( ) ;
2022-07-07 11:07:46 -04:00
if ( msg . run ( ) ! = RESPONSE_YES ) {
2022-06-02 13:07:28 -04:00
return ;
2022-06-01 09:48:44 -04:00
}
if ( cb . get_active ( ) ) {
2022-06-02 13:07:28 -04:00
XMLNode node ( X_ ( " no-scene-clear-warning " ) ) ;
2022-06-01 09:48:44 -04:00
Config - > add_instant_xml ( node ) ;
}
}
2022-06-02 13:07:28 -04:00
ms - > clear ( ) ;
2022-06-01 09:48:44 -04:00
}
void
Mixer_UI : : rename_mixer_scene ( size_t n )
{
if ( ! _session ) {
return ;
}
2023-02-16 18:33:28 -05:00
std : : shared_ptr < MixerScene > ms = _session - > nth_mixer_scene ( n , false ) ;
2022-06-01 09:48:44 -04:00
if ( ! ms ) {
return ;
}
/* prompt the user for a scene name */
ArdourWidgets : : Prompter name_prompter ( true ) ;
string result ;
bool done = false ;
name_prompter . set_title ( _ ( " Rename Scene " ) ) ;
name_prompter . set_prompt ( _ ( " Scene name: " ) ) ;
name_prompter . set_initial_text ( ms - > name ( ) ) ;
name_prompter . add_button ( _ ( " Rename " ) , Gtk : : RESPONSE_ACCEPT ) ;
name_prompter . show_all ( ) ;
while ( ! done ) {
switch ( name_prompter . run ( ) ) {
case Gtk : : RESPONSE_ACCEPT :
name_prompter . get_result ( result ) ;
name_prompter . hide ( ) ;
if ( result . length ( ) ) {
2023-02-16 18:33:28 -05:00
std : : shared_ptr < MixerScene > ms = _session - > nth_mixer_scene ( n , false ) ;
2022-06-01 09:48:44 -04:00
ms - > set_name ( result ) ;
done = true ;
} else {
/* nothing entered, just get out of here */
done = true ;
}
break ;
default :
done = true ;
break ;
}
}
}
void
Mixer_UI : : popup_scene_menu ( GdkEventButton * ev , int scn_idx )
{
Gtk : : Menu * menu = ARDOUR_UI_UTILS : : shared_popup_menu ( ) ;
Gtk : : Menu_Helpers : : MenuList & items = menu - > items ( ) ;
items . push_back ( Gtk : : Menu_Helpers : : MenuElem ( _ ( " Store " ) , sigc : : bind ( sigc : : mem_fun ( * this , & Mixer_UI : : store_mixer_scene ) , scn_idx ) ) ) ;
2023-02-16 18:33:28 -05:00
std : : shared_ptr < MixerScene > ms = _session - > nth_mixer_scene ( scn_idx ) ;
2022-06-01 09:48:44 -04:00
if ( ms & & ! ms - > empty ( ) ) {
2022-06-02 13:07:28 -04:00
items . push_back ( Gtk : : Menu_Helpers : : MenuElem ( _ ( " Clear " ) , sigc : : bind ( sigc : : mem_fun ( * this , & Mixer_UI : : clear_mixer_scene ) , scn_idx , true ) ) ) ;
2022-06-01 09:48:44 -04:00
items . push_back ( Gtk : : Menu_Helpers : : MenuElem ( _ ( " Rename " ) , sigc : : bind ( sigc : : mem_fun ( * this , & Mixer_UI : : rename_mixer_scene ) , scn_idx ) ) ) ;
2022-10-17 17:13:40 -04:00
items . push_back ( Gtk : : Menu_Helpers : : MenuElem ( _ ( " Restore for selected tracks " ) , sigc : : bind ( sigc : : mem_fun ( * this , & Mixer_UI : : recall_mixer_scene ) , scn_idx , false , true ) ) ) ;
items . back ( ) . set_sensitive ( ! PublicEditor : : instance ( ) . get_selection ( ) . tracks . routelist ( ) . empty ( ) ) ;
2022-06-01 09:48:44 -04:00
}
2023-10-31 15:10:49 -04:00
menu - > popup ( ev - > button , ev - > time ) ;
2022-06-01 09:48:44 -04:00
}
bool
2022-06-02 13:07:28 -04:00
Mixer_UI : : scene_button_press ( GdkEventButton * ev , int idx )
2022-06-01 09:48:44 -04:00
{
2022-06-08 20:25:02 -04:00
if ( ! _session | | ev - > type = = GDK_2BUTTON_PRESS | | ev - > type = = GDK_3BUTTON_PRESS ) {
2022-06-01 09:48:44 -04:00
return false ;
}
2022-06-02 13:07:28 -04:00
if ( Keyboard : : is_context_menu_event ( ev ) ) {
2022-06-01 09:48:44 -04:00
popup_scene_menu ( ev , idx ) ;
2022-06-02 13:07:28 -04:00
} else if ( Keyboard : : is_delete_event ( ev ) ) {
clear_mixer_scene ( idx , true ) ;
2022-06-14 17:44:48 -04:00
} else if ( Keyboard : : is_momentary_push_event ( ev ) ) {
2022-06-02 13:07:28 -04:00
/* momentary */
2022-11-10 14:52:50 -05:00
delete _mixer_scene_release ; // .. or keep existing?
_mixer_scene_release = new MixerScene ( * _session ) ;
_mixer_scene_release - > snapshot ( ) ; // TODO; prevent changed signal
recall_mixer_scene ( idx , false ) ;
2022-06-02 14:53:45 -04:00
return false ;
2022-06-02 13:07:28 -04:00
} else if ( ev - > button = = 1 ) {
2022-06-02 14:53:45 -04:00
return false ;
2022-06-01 09:48:44 -04:00
}
return true ;
}
bool
2022-06-02 13:07:28 -04:00
Mixer_UI : : scene_button_release ( GdkEventButton * ev , int idx )
{
2022-11-10 14:52:50 -05:00
if ( _mixer_scene_release ) {
_mixer_scene_release - > apply ( ) ;
delete _mixer_scene_release ;
_mixer_scene_release = 0 ;
2022-06-02 14:53:45 -04:00
} else if ( ev - > button = = 1 ) {
2022-10-17 17:13:40 -04:00
recall_mixer_scene ( idx ) ;
2022-06-02 13:07:28 -04:00
}
return false ;
}
bool
Mixer_UI : : scene_label_press ( GdkEventButton * ev , int idx )
2022-06-01 09:48:44 -04:00
{
2023-02-16 18:33:28 -05:00
std : : shared_ptr < MixerScene > scn = _session - > nth_mixer_scene ( idx ) ;
2022-06-01 09:48:44 -04:00
if ( ! scn | | scn - > empty ( ) ) {
return false ;
}
if ( ( ev - > button = = 1 & & ev - > type = = GDK_2BUTTON_PRESS ) | | Keyboard : : is_edit_event ( ev ) ) {
rename_mixer_scene ( idx ) ;
return true ;
}
return false ;
}
void
Mixer_UI : : update_scene_buttons ( )
{
2022-11-10 14:58:45 -05:00
if ( _mixer_scene_release ) {
/* do not change highlight for momentary scene */
return ;
}
2022-06-01 10:56:20 -04:00
bool all_unset = true ;
for ( size_t idx = 0 ; idx < _mixer_scene_buttons . size ( ) ; + + idx ) {
2023-02-16 18:33:28 -05:00
std : : shared_ptr < MixerScene > scn ;
2022-06-01 18:52:25 -04:00
2022-11-08 18:30:07 -05:00
bool last = false ;
2022-06-01 18:52:25 -04:00
if ( _session ) {
scn = _session - > nth_mixer_scene ( idx ) ;
2022-11-08 18:30:07 -05:00
last = ( idx = = _session - > last_touched_mixer_scene_idx ( ) ) ;
2022-06-01 18:52:25 -04:00
}
2022-06-01 10:56:20 -04:00
Gtk : : Label * l = _mixer_scene_labels [ idx ] ;
l - > set_alignment ( 0 , 0.5 ) ;
if ( scn & & ! scn - > empty ( ) ) {
ArdourButton * b = _mixer_scene_buttons [ idx ] ;
2022-06-17 09:04:47 -04:00
ArdourWidgets : : set_tooltip ( b , string_compose (
_ ( " Click to recall this mixer scene \n "
" %1 for Momentary Restore \n "
" Right-Click for Context menu " )
2022-07-29 12:13:21 -04:00
, Keyboard : : momentary_push_name ( ) ) ) ;
2022-11-08 18:30:07 -05:00
if ( last ) {
l - > set_markup ( string_compose ( " <b>>%1</b> " , scn - > name ( ) ) ) ;
} else {
l - > set_text ( scn - > name ( ) ) ;
}
2022-06-01 10:56:20 -04:00
all_unset = false ;
} else {
l - > set_text ( ( " " ) ) ;
2022-05-23 10:08:30 -04:00
}
}
2022-06-01 10:56:20 -04:00
2022-06-01 18:52:25 -04:00
if ( ! _session ) {
return ;
}
2022-06-01 10:56:20 -04:00
if ( _mixer_scene_buttons . size ( ) > 0 & & all_unset ) {
Gtk : : Label * l = _mixer_scene_labels [ 0 ] ;
l - > set_markup ( string_compose ( " <i>%1</i> " , _ ( " (Right-Click to Store) " ) ) ) ;
}
2022-05-23 10:08:30 -04:00
}
2019-07-17 18:05:32 -04:00
bool
2019-07-17 16:57:30 -04:00
Mixer_UI : : screenshot ( std : : string const & filename )
{
2019-07-17 18:05:32 -04:00
if ( ! _session ) {
return false ;
}
2024-05-06 17:49:05 -04:00
if ( Profile - > get_livetrax ( ) ) {
return false ;
}
2019-07-17 18:05:32 -04:00
2019-07-17 16:57:30 -04:00
int height = strip_packer . get_height ( ) ;
2022-01-26 15:21:06 -05:00
bool with_vca = vca_vpacker . get_visible ( ) ;
2019-07-17 18:05:32 -04:00
MixerStrip * master = strip_by_route ( _session - > master_out ( ) ) ;
Gtk : : OffscreenWindow osw ;
Gtk : : HBox b ;
osw . add ( b ) ;
b . show ( ) ;
/* unpack widgets, add to OffscreenWindow */
2019-07-17 16:57:30 -04:00
strip_group_box . remove ( strip_packer ) ;
2019-07-17 18:05:32 -04:00
b . pack_start ( strip_packer , false , false ) ;
/* hide extra elements inside strip_packer */
scroller_base . hide ( ) ;
# ifdef MIXBUS
mb_shadow . hide ( ) ;
# endif
if ( with_vca ) {
/* work around Gtk::ScrolledWindow */
Gtk : : Viewport * viewport = ( Gtk : : Viewport * ) vca_scroller . get_child ( ) ;
viewport - > remove ( ) ; // << vca_hpacker
b . pack_start ( vca_hpacker , false , false ) ;
/* hide some growing widgets */
vca_scroller_base . hide ( ) ;
}
2024-01-02 08:26:56 -05:00
if ( _surround_strip ) {
out_packer . remove ( * _surround_strip ) ;
b . pack_start ( * _surround_strip , false , false ) ;
_surround_strip - > hide_spacer ( true ) ;
}
2019-07-17 18:05:32 -04:00
if ( master ) {
out_packer . remove ( * master ) ;
2024-01-02 08:26:56 -05:00
b . pack_end ( * master , false , false ) ;
2019-07-17 18:05:32 -04:00
master - > hide_master_spacer ( true ) ;
}
/* prepare the OffscreenWindow for rendering */
2019-07-17 16:57:30 -04:00
osw . set_size_request ( - 1 , height ) ;
2019-07-17 18:05:32 -04:00
osw . show ( ) ;
osw . queue_resize ( ) ;
osw . queue_draw ( ) ;
2019-07-17 16:57:30 -04:00
osw . get_window ( ) - > process_updates ( true ) ;
2019-07-17 18:05:32 -04:00
/* create screenshot */
2019-07-17 16:57:30 -04:00
Glib : : RefPtr < Gdk : : Pixbuf > pb = osw . get_pixbuf ( ) ;
pb - > save ( filename , " png " ) ;
2019-07-17 18:05:32 -04:00
Fix typos in gtk2_ardour/ directory
Found via `codespell -q 3 -S *.po,./share/patchfiles,./libs -L ba,buss,busses,doubleclick,hsi,ontop,ro,seh,siz,sur,te,trough,ue`
2022-01-26 12:35:38 -05:00
/* unpack elements before destroying the Box & OffscreenWindow */
2019-07-17 18:05:32 -04:00
list < Gtk : : Widget * > children = b . get_children ( ) ;
for ( list < Gtk : : Widget * > : : iterator child = children . begin ( ) ; child ! = children . end ( ) ; + + child ) {
b . remove ( * * child ) ;
}
2019-07-17 16:57:30 -04:00
osw . remove ( ) ;
2019-07-17 18:05:32 -04:00
/* now re-pack the widgets into the main mixer window */
scroller_base . show ( ) ;
# ifdef MIXBUS
mb_shadow . show ( ) ;
# endif
2019-07-17 16:57:30 -04:00
strip_group_box . pack_start ( strip_packer ) ;
2019-07-17 18:05:32 -04:00
if ( with_vca ) {
vca_scroller_base . show ( ) ;
vca_scroller . add ( vca_hpacker ) ;
}
2024-01-02 08:26:56 -05:00
if ( _surround_strip ) {
_surround_strip - > hide_spacer ( false ) ;
2024-01-15 16:40:35 -05:00
out_packer . pack_end ( * _surround_strip , false , false ) ;
2024-01-02 08:26:56 -05:00
}
2019-07-17 18:05:32 -04:00
if ( master ) {
master - > hide_master_spacer ( false ) ;
2024-01-15 16:40:35 -05:00
out_packer . pack_start ( * master , false , false ) ;
2019-07-17 18:05:32 -04:00
}
return true ;
2019-07-17 16:57:30 -04:00
}
2019-11-20 11:37:14 -05:00
void
Mixer_UI : : toggle_monitor_action ( MonitorChoice monitor_choice , bool group_override , bool all )
{
MonitorChoice mc ;
for ( AxisViewSelection : : iterator i = _selection . axes . begin ( ) ; i ! = _selection . axes . end ( ) ; + + i ) {
2023-02-16 18:33:28 -05:00
std : : shared_ptr < ARDOUR : : Route > rt = std : : dynamic_pointer_cast < ARDOUR : : Route > ( ( * i ) - > stripable ( ) ) ;
2019-11-20 11:37:14 -05:00
2021-01-05 17:35:30 -05:00
if ( ! rt - > monitoring_control ( ) ) {
/* skip busses */
continue ;
}
2019-11-20 11:37:14 -05:00
if ( rt - > monitoring_control ( ) - > monitoring_choice ( ) & monitor_choice ) {
mc = MonitorChoice ( rt - > monitoring_control ( ) - > monitoring_choice ( ) & ~ monitor_choice ) ;
} else {
mc = MonitorChoice ( rt - > monitoring_control ( ) - > monitoring_choice ( ) | monitor_choice ) ;
}
if ( all ) {
/* Primary-Tertiary-click applies change to all routes */
2023-04-07 17:33:13 -04:00
std : : shared_ptr < RouteList const > rl = _session - > get_routes ( ) ;
2019-11-20 11:37:14 -05:00
_session - > set_controls ( route_list_to_control_list ( rl , & Stripable : : monitoring_control ) , ( double ) mc , Controllable : : NoGroup ) ;
} else if ( group_override ) {
2023-04-07 17:33:13 -04:00
std : : shared_ptr < RouteList > rl ( new RouteList ) ;
2019-11-20 11:37:14 -05:00
rl - > push_back ( rt ) ;
_session - > set_controls ( route_list_to_control_list ( rl , & Stripable : : monitoring_control ) , ( double ) mc , Controllable : : InverseGroup ) ;
} else {
2023-04-07 17:33:13 -04:00
std : : shared_ptr < RouteList > rl ( new RouteList ) ;
2019-11-20 11:37:14 -05:00
rl - > push_back ( rt ) ;
_session - > set_controls ( route_list_to_control_list ( rl , & Stripable : : monitoring_control ) , ( double ) mc , Controllable : : UseGroup ) ;
}
}
}
2024-01-02 08:26:56 -05:00
void
Mixer_UI : : toggle_surround_master ( )
{
if ( ! _session | | ! _session - > vapor_barrier ( ) ) {
return ;
}
RefPtr < ToggleAction > act = ActionManager : : get_toggle_action ( X_ ( " Mixer " ) , " ToggleSurroundMaster " ) ;
bool want_sm = act - > get_active ( ) ;
bool have_sm = _session - > surround_master ( ) ! = nullptr ;
if ( want_sm = = have_sm ) {
return ;
}
if ( want_sm ) {
_session - > config . set_use_surround_master ( true ) ;
} else {
ArdourMessageDialog md ( _ ( " Disabling surround master will delete all existing surround panner state. \n This cannot be undonoe. Proceed anyway? " ) , false , MESSAGE_QUESTION , BUTTONS_YES_NO ) ;
if ( md . run ( ) = = RESPONSE_YES ) {
_session - > config . set_use_surround_master ( false ) ;
}
}
have_sm = _session - > surround_master ( ) ! = nullptr ;
act - > set_active ( have_sm ) ;
2023-12-07 11:43:26 -05:00
Glib : : RefPtr < Action > surround_export = ActionManager : : get_action ( X_ ( " Main " ) , X_ ( " SurroundExport " ) ) ;
surround_export - > set_sensitive ( have_sm & & _session - > vapor_export_barrier ( ) ) ;
2024-01-02 08:26:56 -05:00
}
2024-02-23 11:04:25 -05:00
void
Mixer_UI : : sync_surround_action ( )
{
RefPtr < ToggleAction > act = ActionManager : : get_toggle_action ( X_ ( " Mixer " ) , " ToggleSurroundMaster " ) ;
if ( _session - > config . get_use_surround_master ( ) = = act - > get_active ( ) ) {
return ;
}
bool have_sm = _session - > surround_master ( ) ! = nullptr ;
act - > set_active ( have_sm ) ;
Glib : : RefPtr < Action > surround_export = ActionManager : : get_action ( X_ ( " Main " ) , X_ ( " SurroundExport " ) ) ;
surround_export - > set_sensitive ( have_sm & & _session - > vapor_export_barrier ( ) ) ;
}
2024-03-25 20:36:11 -04:00
void
Mixer_UI : : steal_focus ( )
{
if ( Profile - > get_livetrax ( ) ) {
scroller_base . grab_focus ( ) ;
}
}