summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--SConstruct2
-rw-r--r--gtk2_ardour/add_route_dialog.cc12
-rw-r--r--gtk2_ardour/ardour_ui2.cc46
-rw-r--r--gtk2_ardour/editor.cc38
-rw-r--r--gtk2_ardour/editor.h16
-rw-r--r--gtk2_ardour/editor_actions.cc20
-rw-r--r--gtk2_ardour/editor_mixer.cc16
-rw-r--r--gtk2_ardour/editor_ops.cc97
-rw-r--r--gtk2_ardour/editor_region_list.cc20
-rw-r--r--gtk2_ardour/editor_route_list.cc51
-rw-r--r--gtk2_ardour/editor_selection.cc10
-rw-r--r--gtk2_ardour/generic_pluginui.cc33
-rw-r--r--gtk2_ardour/keyboard.cc18
-rw-r--r--gtk2_ardour/mixer_strip.cc18
-rw-r--r--gtk2_ardour/option_editor.cc29
-rw-r--r--gtk2_ardour/option_editor.h2
-rw-r--r--gtk2_ardour/plugin_selector.cc24
-rw-r--r--gtk2_ardour/plugin_ui.cc7
-rw-r--r--gtk2_ardour/plugin_ui.h1
-rw-r--r--gtk2_ardour/processor_box.cc10
-rw-r--r--gtk2_ardour/route_time_axis.cc8
-rw-r--r--gtk2_ardour/route_ui.cc13
-rw-r--r--gtk2_ardour/route_ui.h2
-rw-r--r--gtk2_ardour/startup.cc41
-rw-r--r--gtk2_ardour/startup.h8
-rw-r--r--gtk2_ardour/tempo_dialog.cc17
-rw-r--r--libs/ardour/ardour/configuration_vars.h2
-rw-r--r--libs/ardour/audioengine.cc4
-rw-r--r--libs/ardour/audioregion.cc8
-rw-r--r--libs/ardour/playlist.cc3
-rw-r--r--libs/ardour/route.cc12
-rw-r--r--libs/ardour/session.cc64
-rw-r--r--libs/gtkmm2ext/gtkmm2ext/utils.h13
-rw-r--r--libs/gtkmm2ext/sync-menu.c15
-rw-r--r--libs/gtkmm2ext/utils.cc42
-rw-r--r--libs/surfaces/mackie/mackie_control_protocol.cc42
-rw-r--r--libs/surfaces/mackie/route_signal.cc41
-rw-r--r--libs/surfaces/mackie/route_signal.h7
38 files changed, 509 insertions, 303 deletions
diff --git a/SConstruct b/SConstruct
index 9cd866745a..615cd9014d 100644
--- a/SConstruct
+++ b/SConstruct
@@ -32,7 +32,7 @@ subst_dict = { }
opts = Options('scache.conf')
opts.AddOptions(
('ARCH', 'Set architecture-specific compilation flags by hand (all flags as 1 argument)',''),
- ('WINDOWS_KEY', 'Set X Modifier (Mod1,Mod2,Mod3,Mod4,Mod5) for "Windows" key', 'Mod4'),
+ ('WINDOWS_KEY', 'Set X Modifier (Mod1,Mod2,Mod3,Mod4,Mod5) for "Windows" key', 'Mod4><Super'),
BoolOption('AUDIOUNITS', 'Compile with Apple\'s AudioUnit library. (experimental)', 0),
BoolOption('COREAUDIO', 'Compile with Apple\'s CoreAudio library', 0),
BoolOption('GTKOSX', 'Compile for use with GTK-OSX, not GTK-X11', 0),
diff --git a/gtk2_ardour/add_route_dialog.cc b/gtk2_ardour/add_route_dialog.cc
index 855ce5d248..d5856fa4e6 100644
--- a/gtk2_ardour/add_route_dialog.cc
+++ b/gtk2_ardour/add_route_dialog.cc
@@ -160,17 +160,19 @@ AddRouteDialog::AddRouteDialog ()
hbox5->pack_start (track_button, PACK_EXPAND_PADDING);
hbox5->pack_start (bus_button, PACK_EXPAND_PADDING);
- set_popdown_strings (channel_combo, channel_combo_strings);
- set_popdown_strings (track_mode_combo, track_mode_strings);
- channel_combo.set_active_text (channel_combo_strings.front());
channel_combo.set_name (X_("ChannelCountSelector"));
+ track_mode_combo.set_name (X_("ChannelCountSelector"));
+
+ set_popdown_strings (channel_combo, channel_combo_strings, true);
+ set_popdown_strings (track_mode_combo, track_mode_strings, true);
+
+ channel_combo.set_active_text (channel_combo_strings.front());
+ track_mode_combo.set_active_text (track_mode_strings.front());
track_button.signal_clicked().connect (mem_fun (*this, &AddRouteDialog::track_type_chosen));
bus_button.signal_clicked().connect (mem_fun (*this, &AddRouteDialog::track_type_chosen));
template_button.signal_clicked().connect (mem_fun (*this, &AddRouteDialog::track_type_chosen));
- track_mode_combo.set_active_text (track_mode_strings.front());
- track_mode_combo.set_name (X_("ChannelCountSelector"));
VBox* vbox1 = manage (new VBox);
vbox1->set_spacing (6);
diff --git a/gtk2_ardour/ardour_ui2.cc b/gtk2_ardour/ardour_ui2.cc
index abc4163d5e..f2fb31ddbf 100644
--- a/gtk2_ardour/ardour_ui2.cc
+++ b/gtk2_ardour/ardour_ui2.cc
@@ -189,11 +189,6 @@ ARDOUR_UI::transport_forwarding ()
void
ARDOUR_UI::setup_transport ()
{
-#ifdef GTKOSX
- const guint32 FUDGE = 38; // Combo's are stupid - they steal space from the entry for the button
-#else
- const guint32 FUDGE = 24; // Combo's are stupid - they steal space from the entry for the button
-#endif
transport_tearoff = manage (new TearOff (transport_tearoff_hbox));
transport_tearoff->set_name ("TransportBase");
@@ -376,6 +371,7 @@ ARDOUR_UI::setup_transport ()
speed_display_box.add (speed_display_label);
speed_display_box.set_name (X_("ShuttleDisplay"));
+ set_size_request_to_display_given_text (speed_display_label, X_("> 24.0"), 2, 2);
shuttle_units_button.set_name (X_("ShuttleButton"));
shuttle_units_button.signal_clicked().connect (mem_fun(*this, &ARDOUR_UI::shuttle_unit_clicked));
@@ -385,8 +381,7 @@ ARDOUR_UI::setup_transport ()
vector<string> shuttle_strings;
shuttle_strings.push_back (_("sprung"));
shuttle_strings.push_back (_("wheel"));
- set_size_request_to_display_given_text (shuttle_style_button, shuttle_strings, 6+FUDGE, 10);
- set_popdown_strings (shuttle_style_button, shuttle_strings);
+ set_popdown_strings (shuttle_style_button, shuttle_strings, true);
shuttle_style_button.signal_changed().connect (mem_fun (*this, &ARDOUR_UI::shuttle_style_changed));
Frame* sdframe = manage (new Frame);
@@ -396,7 +391,9 @@ ARDOUR_UI::setup_transport ()
mtc_port_changed ();
sync_option_combo.signal_changed().connect (mem_fun (*this, &ARDOUR_UI::sync_option_changed));
- set_size_request_to_display_given_text (sync_option_combo, X_("Igternal"), 4+FUDGE, 10);
+ // XXX HOW TO USE set_popdown_strings() and combo_fudge with this when we don't know
+ // the real strings till later?
+ set_size_request_to_display_given_text (sync_option_combo, X_("Igternal"), 4+COMBO_FUDGE, 10);
shbox->pack_start (*sdframe, false, false);
shbox->pack_start (shuttle_units_button, true, true);
@@ -777,15 +774,33 @@ ARDOUR_UI::use_shuttle_fract (bool force)
last_shuttle_request = now;
- bool neg = (shuttle_fract < 0.0);
+ if (Config->get_shuttle_units() == Semitones) {
+
+ const double step = 1.0 / 24.0; // range is 24 semitones up & down
+ double semitones;
+ double speed;
+
+ semitones = round (shuttle_fract / step);
+ speed = pow (2.0, (semitones / 12.0));
+
+ session->request_transport_speed (speed);
+
+ } else {
+
+ bool neg;
+ double fract;
+
+ neg = (shuttle_fract < 0.0);
- double fract = 1 - sqrt (1 - (shuttle_fract * shuttle_fract)); // Formula A1
+ fract = 1 - sqrt (1 - (shuttle_fract * shuttle_fract)); // Formula A1
- if (neg) {
- fract = -fract;
+ if (neg) {
+ fract = -fract;
+ }
+
+ session->request_transport_speed (shuttle_max_speed * fract);
}
- session->request_transport_speed (shuttle_max_speed * fract); // Formula A2
shuttle_box.queue_draw ();
}
@@ -856,10 +871,11 @@ ARDOUR_UI::update_speed_display ()
if (Config->get_shuttle_units() == Percentage) {
snprintf (buf, sizeof (buf), "%.2f", x);
} else {
+
if (x < 0) {
- snprintf (buf, sizeof (buf), "< %.1f", 12.0 * fast_log2 (-x));
+ snprintf (buf, sizeof (buf), "< %d", (int) round (12.0 * fast_log2 (-x)));
} else {
- snprintf (buf, sizeof (buf), "> %.1f", 12.0 * fast_log2 (x));
+ snprintf (buf, sizeof (buf), "> %d", (int) round (12.0 * fast_log2 (x)));
}
}
speed_display_label.set_text (buf);
diff --git a/gtk2_ardour/editor.cc b/gtk2_ardour/editor.cc
index db77a0b003..b129009a9c 100644
--- a/gtk2_ardour/editor.cc
+++ b/gtk2_ardour/editor.cc
@@ -3017,12 +3017,6 @@ Editor::setup_toolbar ()
{
string pixmap_path;
-#ifdef GTKOSX
- const guint32 FUDGE = 38; // Combo's are stupid - they steal space from the entry for the button
-#else
- const guint32 FUDGE = 24; // Combo's are stupid - they steal space from the entry for the button
-#endif
-
/* Mode Buttons (tool selection) */
vector<ToggleButton *> mouse_mode_buttons;
@@ -3081,8 +3075,7 @@ Editor::setup_toolbar ()
edit_mode_strings.push_back (edit_mode_to_string (Lock));
edit_mode_selector.set_name ("EditModeSelector");
- Gtkmm2ext::set_size_request_to_display_given_text (edit_mode_selector, edit_mode_strings, 7+FUDGE, 10);
- set_popdown_strings (edit_mode_selector, edit_mode_strings);
+ set_popdown_strings (edit_mode_selector, edit_mode_strings, true);
edit_mode_selector.signal_changed().connect (mem_fun(*this, &Editor::edit_mode_selection_done));
mode_box->pack_start(edit_mode_selector);
@@ -3165,8 +3158,7 @@ Editor::setup_toolbar ()
ARDOUR_UI::instance()->tooltips().set_tip (zoom_out_full_button, _("Zoom to Session"));
zoom_focus_selector.set_name ("ZoomFocusSelector");
- Gtkmm2ext::set_size_request_to_display_given_text (zoom_focus_selector, zoom_focus_strings, 2+FUDGE, 10);
- set_popdown_strings (zoom_focus_selector, zoom_focus_strings);
+ set_popdown_strings (zoom_focus_selector, zoom_focus_strings, true);
zoom_focus_selector.signal_changed().connect (mem_fun(*this, &Editor::zoom_focus_selection_done));
ARDOUR_UI::instance()->tooltips().set_tip (zoom_focus_selector, _("Zoom focus"));
@@ -3179,20 +3171,17 @@ Editor::setup_toolbar ()
snap_box.set_border_width (2);
snap_type_selector.set_name ("SnapTypeSelector");
- Gtkmm2ext::set_size_request_to_display_given_text (snap_type_selector, snap_type_strings, 7+FUDGE, 10);
- set_popdown_strings (snap_type_selector, snap_type_strings);
+ set_popdown_strings (snap_type_selector, snap_type_strings, true);
snap_type_selector.signal_changed().connect (mem_fun(*this, &Editor::snap_type_selection_done));
ARDOUR_UI::instance()->tooltips().set_tip (snap_type_selector, _("Snap/Grid Units"));
snap_mode_selector.set_name ("SnapModeSelector");
- Gtkmm2ext::set_size_request_to_display_given_text (snap_mode_selector, snap_mode_strings, 7+FUDGE, 10);
- set_popdown_strings (snap_mode_selector, snap_mode_strings);
+ set_popdown_strings (snap_mode_selector, snap_mode_strings, true);
snap_mode_selector.signal_changed().connect (mem_fun(*this, &Editor::snap_mode_selection_done));
ARDOUR_UI::instance()->tooltips().set_tip (snap_mode_selector, _("Snap/Grid Mode"));
edit_point_selector.set_name ("EditPointSelector");
- Gtkmm2ext::set_size_request_to_display_given_text (edit_point_selector, edit_point_strings, 7+FUDGE, 10);
- set_popdown_strings (edit_point_selector, edit_point_strings);
+ set_popdown_strings (edit_point_selector, edit_point_strings, true);
edit_point_selector.signal_changed().connect (mem_fun(*this, &Editor::edit_point_selection_done));
ARDOUR_UI::instance()->tooltips().set_tip (edit_point_selector, _("Edit point"));
@@ -4749,12 +4738,19 @@ Editor::post_zoom ()
void
Editor::queue_visual_change (nframes64_t where)
{
-// pending_visual_change.pending = VisualChange::Type (pending_visual_change.pending | VisualChange::TimeOrigin);
-// pending_visual_change.time_origin = where;
-
+ pending_visual_change.pending = VisualChange::Type (pending_visual_change.pending | VisualChange::TimeOrigin);
+
+ /* if we're moving beyond the end, make sure the upper limit of the horizontal adjustment
+ can reach.
+ */
+
+ if (where > session->current_end_frame()) {
+ horizontal_adjustment.set_upper ((where + current_page_frames()) / frames_per_unit);
+ }
+
+ pending_visual_change.time_origin = where;
+
if (pending_visual_change.idle_handler_id < 0) {
- pending_visual_change.pending = VisualChange::Type (pending_visual_change.pending | VisualChange::TimeOrigin);
- pending_visual_change.time_origin = where;
pending_visual_change.idle_handler_id = g_idle_add (_idle_visual_changer, this);
}
}
diff --git a/gtk2_ardour/editor.h b/gtk2_ardour/editor.h
index f41d031730..1c04c76504 100644
--- a/gtk2_ardour/editor.h
+++ b/gtk2_ardour/editor.h
@@ -296,6 +296,7 @@ class Editor : public PublicEditor
void clear_playlists (TimeAxisView* v);
TrackViewList* get_valid_views (TimeAxisView*, ARDOUR::RouteGroup* grp = 0);
+ void get_onscreen_tracks (TrackViewList&);
Width editor_mixer_strip_width;
void maybe_add_mixer_strip_width (XMLNode&);
@@ -837,18 +838,20 @@ class Editor : public PublicEditor
Cursor* playhead_cursor;
ArdourCanvas::Group* cursor_group;
- void cursor_to_region_boundary (Cursor*, int32_t dir);
- void cursor_to_next_region_boundary (Cursor*);
- void cursor_to_previous_region_boundary (Cursor*);
+ nframes64_t get_region_boundary (nframes64_t pos, int32_t dir, bool with_selection, bool only_onscreen);
+
+ void cursor_to_region_boundary (bool with_selection, int32_t dir);
+ void cursor_to_next_region_boundary (bool with_selection);
+ void cursor_to_previous_region_boundary (bool with_selection);
void cursor_to_next_region_point (Cursor*, ARDOUR::RegionPoint);
void cursor_to_previous_region_point (Cursor*, ARDOUR::RegionPoint);
void cursor_to_region_point (Cursor*, ARDOUR::RegionPoint, int32_t dir);
void cursor_to_selection_start (Cursor *);
void cursor_to_selection_end (Cursor *);
- void selected_marker_to_region_boundary (int32_t dir);
- void selected_marker_to_next_region_boundary ();
- void selected_marker_to_previous_region_boundary ();
+ void selected_marker_to_region_boundary (bool with_selection, int32_t dir);
+ void selected_marker_to_next_region_boundary (bool with_selection);
+ void selected_marker_to_previous_region_boundary (bool with_selection);
void selected_marker_to_next_region_point (ARDOUR::RegionPoint);
void selected_marker_to_previous_region_point (ARDOUR::RegionPoint);
void selected_marker_to_region_point (ARDOUR::RegionPoint, int32_t dir);
@@ -1908,6 +1911,7 @@ public:
void route_list_reordered (const Gtk::TreeModel::Path& path, const Gtk::TreeModel::iterator& iter, int* what);
bool ignore_route_list_reorder;
bool no_route_list_redisplay;
+ bool sync_track_view_list_and_route_list ();
void build_route_list_menu ();
void show_route_list_menu ();
diff --git a/gtk2_ardour/editor_actions.cc b/gtk2_ardour/editor_actions.cc
index 63c0b79bc0..9606540b6e 100644
--- a/gtk2_ardour/editor_actions.cc
+++ b/gtk2_ardour/editor_actions.cc
@@ -134,9 +134,13 @@ Editor::register_actions ()
act = ActionManager::register_action (editor_actions, "toggle-selected-region-fades", _("Toggle Region Fades"), bind (mem_fun(*this, &Editor::toggle_selected_region_fades), 0));
ActionManager::session_sensitive_actions.push_back (act);
- act = ActionManager::register_action (editor_actions, "playhead-to-next-region-boundary", _("Playhead to Next Region Boundary"), bind (mem_fun(*this, &Editor::cursor_to_next_region_boundary), playhead_cursor));
+ act = ActionManager::register_action (editor_actions, "playhead-to-next-region-boundary", _("Playhead to Next Region Boundary"), bind (mem_fun(*this, &Editor::cursor_to_next_region_boundary), true ));
ActionManager::session_sensitive_actions.push_back (act);
- act = ActionManager::register_action (editor_actions, "playhead-to-previous-region-boundary", _("Playhead to Previous Region Boundary"), bind (mem_fun(*this, &Editor::cursor_to_previous_region_boundary), playhead_cursor));
+ act = ActionManager::register_action (editor_actions, "playhead-to-next-region-boundary-noselection", _("Playhead to Next Region Boundary (No Track Selection)"), bind (mem_fun(*this, &Editor::cursor_to_next_region_boundary), false ));
+ ActionManager::session_sensitive_actions.push_back (act);
+ act = ActionManager::register_action (editor_actions, "playhead-to-previous-region-boundary", _("Playhead to Previous Region Boundary"), bind (mem_fun(*this, &Editor::cursor_to_previous_region_boundary), true));
+ ActionManager::session_sensitive_actions.push_back (act);
+ act = ActionManager::register_action (editor_actions, "playhead-to-previous-region-boundary-noselection", _("Playhead to Previous Region Boundary (No Track Selection"), bind (mem_fun(*this, &Editor::cursor_to_previous_region_boundary), false));
ActionManager::session_sensitive_actions.push_back (act);
act = ActionManager::register_action (editor_actions, "playhead-to-next-region-start", _("Playhead to Next Region Start"), bind (mem_fun(*this, &Editor::cursor_to_next_region_point), playhead_cursor, RegionPoint (Start)));
@@ -153,10 +157,14 @@ Editor::register_actions ()
act = ActionManager::register_action (editor_actions, "playhead-to-previous-region-sync", _("Playhead to Previous Region Sync"), bind (mem_fun(*this, &Editor::cursor_to_previous_region_point), playhead_cursor, RegionPoint (SyncPoint)));
ActionManager::session_sensitive_actions.push_back (act);
- act = ActionManager::register_action (editor_actions, "selected-marker-to-next-region-boundary", _("To Next Region Boundary"), mem_fun(*this, &Editor::selected_marker_to_next_region_boundary));
- ActionManager::session_sensitive_actions.push_back (act);
- act = ActionManager::register_action (editor_actions, "selected-marker-to-previous-region-boundary", _("To Previous Region Boundary"), mem_fun(*this, &Editor::selected_marker_to_previous_region_boundary));
- ActionManager::session_sensitive_actions.push_back (act);
+ act = ActionManager::register_action (editor_actions, "selected-marker-to-next-region-boundary", _("to Next Region Boundary"), bind (mem_fun(*this, &Editor::selected_marker_to_next_region_boundary), true));
+ ActionManager::session_sensitive_actions.push_back (act);
+ act = ActionManager::register_action (editor_actions, "selected-marker-to-next-region-boundary-noselection", _("to Next Region Boundary (No Track Selection)"), bind (mem_fun(*this, &Editor::selected_marker_to_next_region_boundary), false));
+ ActionManager::session_sensitive_actions.push_back (act);
+ act = ActionManager::register_action (editor_actions, "selected-marker-to-previous-region-boundary", _("to Previous Region Boundary"), bind (mem_fun(*this, &Editor::selected_marker_to_previous_region_boundary), true));
+ ActionManager::session_sensitive_actions.push_back (act);
+ act = ActionManager::register_action (editor_actions, "selected-marker-to-previous-region-boundary-noselection", _("to Previous Region Boundary (No Track Selection)"), bind (mem_fun(*this, &Editor::selected_marker_to_previous_region_boundary), false));
+ ActionManager::session_sensitive_actions.push_back (act);
act = ActionManager::register_action (editor_actions, "edit-cursor-to-next-region-start", _("To Next Region Start"), bind (mem_fun(*this, &Editor::selected_marker_to_next_region_point), RegionPoint (Start)));
ActionManager::session_sensitive_actions.push_back (act);
diff --git a/gtk2_ardour/editor_mixer.cc b/gtk2_ardour/editor_mixer.cc
index add7213400..2f858f99a0 100644
--- a/gtk2_ardour/editor_mixer.cc
+++ b/gtk2_ardour/editor_mixer.cc
@@ -408,12 +408,16 @@ Editor::session_going_away ()
delete current_bbt_points;
current_bbt_points = 0;
-
- /* mixer strip will be deleted all by itself
- when its route is deleted.
- */
-
- current_mixer_strip = 0;
+
+ /* get rid of any existing editor mixer strip */
+
+ if (current_mixer_strip) {
+ if (current_mixer_strip->get_parent() != 0) {
+ global_hpacker.remove (*current_mixer_strip);
+ }
+ delete current_mixer_strip;
+ current_mixer_strip = 0;
+ }
WindowTitle title(Glib::get_application_name());
title += _("Editor");
diff --git a/gtk2_ardour/editor_ops.cc b/gtk2_ardour/editor_ops.cc
index cbda900255..2706a44669 100644
--- a/gtk2_ardour/editor_ops.cc
+++ b/gtk2_ardour/editor_ops.cc
@@ -710,7 +710,8 @@ Editor::build_region_boundary_cache ()
break;
case SyncPoint:
- rpos = r->adjust_to_sync (r->first_frame());
+ rpos = r->sync_position ();
+ //r->adjust_to_sync (r->first_frame());
break;
default:
@@ -796,7 +797,8 @@ Editor::find_next_region (nframes64_t frame, RegionPoint point, int32_t dir, Tra
break;
case SyncPoint:
- rpos = r->adjust_to_sync (r->first_frame());
+ rpos = r->sync_position ();
+ // r->adjust_to_sync (r->first_frame());
break;
}
@@ -826,6 +828,7 @@ Editor::find_next_region_boundary (nframes64_t pos, int32_t dir, const TrackView
nframes64_t distance = max_frames;
nframes64_t current_nearest = -1;
+
for (TrackViewList::const_iterator i = tracks.begin(); i != tracks.end(); ++i) {
nframes64_t contender;
nframes64_t d;
@@ -851,10 +854,45 @@ Editor::find_next_region_boundary (nframes64_t pos, int32_t dir, const TrackView
return current_nearest;
}
+nframes64_t
+Editor::get_region_boundary (nframes64_t pos, int32_t dir, bool with_selection, bool only_onscreen)
+{
+ nframes64_t target;
+ TrackViewList tvl;
+
+ if (with_selection && Config->get_region_boundaries_from_selected_tracks()) {
+
+ if (!selection->tracks.empty()) {
+
+ target = find_next_region_boundary (pos, dir, selection->tracks);
+
+ } else {
+
+ if (only_onscreen || Config->get_region_boundaries_from_onscreen_tracks()) {
+ get_onscreen_tracks (tvl);
+ target = find_next_region_boundary (pos, dir, tvl);
+ } else {
+ target = find_next_region_boundary (pos, dir, track_views);
+ }
+ }
+
+ } else {
+
+ if (only_onscreen || Config->get_region_boundaries_from_onscreen_tracks()) {
+ get_onscreen_tracks (tvl);
+ target = find_next_region_boundary (pos, dir, tvl);
+ } else {
+ target = find_next_region_boundary (pos, dir, track_views);
+ }
+ }
+
+ return target;
+}
+
void
-Editor::cursor_to_region_boundary (Cursor* cursor, int32_t dir)
+Editor::cursor_to_region_boundary (bool with_selection, int32_t dir)
{
- nframes64_t pos = cursor->current_frame;
+ nframes64_t pos = playhead_cursor->current_frame;
nframes64_t target;
if (!session) {
@@ -866,37 +904,24 @@ Editor::cursor_to_region_boundary (Cursor* cursor, int32_t dir)
pos += dir;
}
- if (!selection->tracks.empty()) {
-
- target = find_next_region_boundary (pos, dir, selection->tracks);
-
- } else {
-
- target = find_next_region_boundary (pos, dir, track_views);
- }
-
- if (target < 0) {
+ if ((target = get_region_boundary (pos, dir, with_selection, false)) < 0) {
return;
}
- if (cursor == playhead_cursor) {
- session->request_locate (target);
- } else {
- cursor->set_position (target);
- }
+ session->request_locate (target);
}
void
-Editor::cursor_to_next_region_boundary (Cursor* cursor)
+Editor::cursor_to_next_region_boundary (bool with_selection)
{
- cursor_to_region_boundary (cursor, 1);
+ cursor_to_region_boundary (with_selection, 1);
}
void
-Editor::cursor_to_previous_region_boundary (Cursor* cursor)
+Editor::cursor_to_previous_region_boundary (bool with_selection)
{
- cursor_to_region_boundary (cursor, -1);
+ cursor_to_region_boundary (with_selection, -1);
}
void
@@ -945,7 +970,8 @@ Editor::cursor_to_region_point (Cursor* cursor, RegionPoint point, int32_t dir)
break;
case SyncPoint:
- pos = r->adjust_to_sync (r->first_frame());
+ pos = r->sync_position ();
+ // r->adjust_to_sync (r->first_frame());
break;
}
@@ -1044,7 +1070,7 @@ Editor::cursor_to_selection_end (Cursor *cursor)
}
void
-Editor::selected_marker_to_region_boundary (int32_t dir)
+Editor::selected_marker_to_region_boundary (bool with_selection, int32_t dir)
{
nframes64_t target;
Location* loc;
@@ -1076,16 +1102,7 @@ Editor::selected_marker_to_region_boundary (int32_t dir)
pos += dir;
}
- if (!selection->tracks.empty()) {
-
- target = find_next_region_boundary (pos, dir, selection->tracks);
-
- } else {
-
- target = find_next_region_boundary (pos, dir, track_views);
- }
-
- if (target < 0) {
+ if ((target = get_region_boundary (pos, dir, with_selection, false)) < 0) {
return;
}
@@ -1093,15 +1110,15 @@ Editor::selected_marker_to_region_boundary (int32_t dir)
}
void
-Editor::selected_marker_to_next_region_boundary ()
+Editor::selected_marker_to_next_region_boundary (bool with_selection)
{
- selected_marker_to_region_boundary (1);
+ selected_marker_to_region_boundary (with_selection, 1);
}
void
-Editor::selected_marker_to_previous_region_boundary ()
+Editor::selected_marker_to_previous_region_boundary (bool with_selection)
{
- selected_marker_to_region_boundary (-1);
+ selected_marker_to_region_boundary (with_selection, -1);
}
void
@@ -3633,7 +3650,7 @@ Editor::freeze_thread ()
gint
Editor::freeze_progress_timeout (void *arg)
{
- interthread_progress_bar.set_fraction (current_interthread_info->progress/100);
+ interthread_progress_bar.set_fraction (current_interthread_info->progress);
return !(current_interthread_info->done || current_interthread_info->cancel);
}
diff --git a/gtk2_ardour/editor_region_list.cc b/gtk2_ardour/editor_region_list.cc
index 7e9fb810d8..9d7aa86e5d 100644
--- a/gtk2_ardour/editor_region_list.cc
+++ b/gtk2_ardour/editor_region_list.cc
@@ -855,28 +855,14 @@ Editor::region_list_display_button_press (GdkEventButton *ev)
return true;
}
- if (region == 0) {
- region_list_display.get_selection()->unselect_all();
- deselect_all();
- return false;
- }
-
- switch (ev->button) {
- case 1:
- break;
-
- case 2:
- // audition on middle click (stop audition too)
+ if (region != 0 && Keyboard::is_button2_event (ev)) {
+ // start/stop audition
if (!Keyboard::modifier_state_equals (ev->state, Keyboard::PrimaryModifier)) {
consider_auditioning (region);
}
return true;
- break;
-
- default:
- break;
}
-
+
return false;
}
diff --git a/gtk2_ardour/editor_route_list.cc b/gtk2_ardour/editor_route_list.cc
index ef6bbde471..8ab6d5fe59 100644
--- a/gtk2_ardour/editor_route_list.cc
+++ b/gtk2_ardour/editor_route_list.cc
@@ -169,6 +169,8 @@ Editor::remove_route (TimeAxisView *tv)
TrackViewList::iterator i;
TreeModel::Children rows = route_display_model->children();
TreeModel::Children::iterator ri;
+ boost::shared_ptr<Route> route;
+ TimeAxisView* next_tv;
if (tv == entered_track) {
entered_track = 0;
@@ -182,6 +184,7 @@ Editor::remove_route (TimeAxisView *tv)
for (ri = rows.begin(); ri != rows.end(); ++ri) {
if ((*ri)[route_display_columns.tv] == tv) {
+ route = (*ri)[route_display_columns.route];
route_display_model->erase (ri);
break;
}
@@ -190,14 +193,29 @@ Editor::remove_route (TimeAxisView *tv)
route_redisplay_does_not_sync_order_keys = false;
if ((i = find (track_views.begin(), track_views.end(), tv)) != track_views.end()) {
- track_views.erase (i);
+
+ i = track_views.erase (i);
+
+ if (track_views.empty()) {
+ next_tv = 0;
+ } else if (i == track_views.end()) {
+ next_tv = track_views.front();
+ } else {
+ next_tv = (*i);
+ }
}
+ if (current_mixer_strip && current_mixer_strip->route() == route) {
- /* since the editor mixer goes away when you remove a route, set the
- * button to inactive and untick the menu option
- */
+ if (next_tv) {
+ set_selected_mixer_strip (*next_tv);
+ } else {
+ /* make the editor mixer strip go away setting the
+ * button to inactive (which also unticks the menu option)
+ */
- ActionManager::uncheck_toggleaction ("<Actions>/Editor/show-editor-mixer");
+ ActionManager::uncheck_toggleaction ("<Actions>/Editor/show-editor-mixer");
+ }
+ }
}
void
@@ -361,6 +379,13 @@ Editor::redisplay_route_list ()
}
+ /* whenever we go idle, update the track view list to reflect the new order.
+ we can't do this here, because we could mess up something that is traversing
+ the track order and has caused a redisplay of the list.
+ */
+
+ Glib::signal_idle().connect (mem_fun (*this, &Editor::sync_track_view_list_and_route_list));
+
full_canvas_height = position + canvas_timebars_vsize;
vertical_adjustment.set_upper (full_canvas_height);
if ((vertical_adjustment.get_value() + canvas_height) > vertical_adjustment.get_upper()) {
@@ -376,6 +401,22 @@ Editor::redisplay_route_list ()
}
}
+bool
+Editor::sync_track_view_list_and_route_list ()
+{
+ TreeModel::Children rows = route_display_model->children();
+ TreeModel::Children::iterator i;
+
+ track_views.clear ();
+
+ for (i = rows.begin(); i != rows.end(); ++i) {
+ TimeAxisView *tv = (*i)[route_display_columns.tv];
+ track_views.push_back (tv);
+ }
+
+ return false; // do not call again (until needed)
+}
+
void
Editor::hide_all_tracks (bool with_select)
{
diff --git a/gtk2_ardour/editor_selection.cc b/gtk2_ardour/editor_selection.cc
index 05b1296075..730bd0b20d 100644
--- a/gtk2_ardour/editor_selection.cc
+++ b/gtk2_ardour/editor_selection.cc
@@ -252,6 +252,16 @@ Editor::set_selected_control_point_from_click (Selection::Operation op, bool no_
}
void
+Editor::get_onscreen_tracks (TrackViewList& tvl)
+{
+ for (TrackViewList::iterator i = track_views.begin(); i != track_views.end(); ++i) {
+ if ((*i)->y_position() < canvas_height) {
+ tvl.push_back (*i);
+ }
+ }
+}
+
+void
Editor::get_relevant_tracks (set<RouteTimeAxisView*>& relevant_tracks)
{
/* step one: get all selected tracks and all tracks in the relevant edit groups */
diff --git a/gtk2_ardour/generic_pluginui.cc b/gtk2_ardour/generic_pluginui.cc
index d276b294ed..842fc15cdb 100644
--- a/gtk2_ardour/generic_pluginui.cc
+++ b/gtk2_ardour/generic_pluginui.cc
@@ -462,14 +462,15 @@ GenericPluginUI::build_control_ui (guint32 port_index, boost::shared_ptr<Automat
control_ui->pack_start (control_ui->label, true, true);
control_ui->pack_start (*control_ui->button, false, true);
- control_ui->pack_start (control_ui->automate_button, false, false);
+ // control_ui->pack_start (control_ui->automate_button, false, false);
control_ui->button->signal_clicked().connect (bind (mem_fun(*this, &GenericPluginUI::control_port_toggled), control_ui));
-
- if(plugin->get_parameter (port_index) == 1){
+ mcontrol->Changed.connect (bind (mem_fun (*this, &GenericPluginUI::toggle_parameter_changed), control_ui));
+
+ if (plugin->get_parameter (port_index) > 0.5){
control_ui->button->set_active(true);
}
-
+
return control_ui;
}
@@ -496,9 +497,6 @@ GenericPluginUI::build_control_ui (guint32 port_index, boost::shared_ptr<Automat
}*/
- float delta = desc.upper - desc.lower;
-
- control_ui->controller->adjustment()->set_page_size (delta/100.0);
control_ui->controller->adjustment()->set_step_increment (desc.step);
control_ui->controller->adjustment()->set_page_increment (desc.largestep);
//#endif
@@ -643,6 +641,20 @@ GenericPluginUI::set_automation_state (AutoState state, ControlUI* cui)
}
void
+GenericPluginUI::toggle_parameter_changed (ControlUI* cui)
+{
+ float val = cui->control->get_value();
+
+ if (!cui->ignore_change) {
+ if (val > 0.5) {
+ cui->button->set_active (true);
+ } else {
+ cui->button->set_active (false);
+ }
+ }
+}
+
+void
GenericPluginUI::parameter_changed (ControlUI* cui)
{
if (!cui->update_pending) {
@@ -661,6 +673,7 @@ GenericPluginUI::update_control_display (ControlUI* cui)
float val = cui->control->get_value();
cui->ignore_change++;
+
if (cui->combo) {
std::map<string,float>::iterator it;
for (it = cui->combo_map->begin(); it != cui->combo_map->end(); ++it) {
@@ -697,9 +710,9 @@ GenericPluginUI::update_control_display (ControlUI* cui)
void
GenericPluginUI::control_port_toggled (ControlUI* cui)
{
- if (!cui->ignore_change) {
- insert->automation_control(cui->parameter())->set_value(cui->button->get_active());
- }
+ cui->ignore_change++;
+ insert->automation_control (cui->parameter())->set_value (cui->button->get_active());
+ cui->ignore_change--;
}
void
diff --git a/gtk2_ardour/keyboard.cc b/gtk2_ardour/keyboard.cc
index cd9d51c164..ad8b02ab53 100644
--- a/gtk2_ardour/keyboard.cc
+++ b/gtk2_ardour/keyboard.cc
@@ -651,6 +651,24 @@ Keyboard::load_keybindings (string path)
release_keys.clear ();
+ bool show_bindings = (getenv ("ARDOUR_SHOW_BINDINGS") != 0);
+
+ for (n = names.begin(), b = bindings.begin(), g = groups.begin(); n != names.end(); ++n, ++b, ++g) {
+
+ if (show_bindings) {
+
+ cerr << "Action: " << (*n) << " Group: " << (*g) << " binding = ";
+
+ if ((*b).get_key() != GDK_VoidSymbol) {
+ cerr << (*b).get_key() << " w/mod = " << hex << (*b).get_mod() << dec << " = " << (*b).get_abbrev();
+ } else {
+ cerr << "unbound";
+ }
+
+ cerr << endl;
+ }
+ }
+
for (n = names.begin(), b = bindings.begin(), g = groups.begin(); n != names.end(); ++n, ++b, ++g) {
if ((*b).get_mod() & Gdk::RELEASE_MASK) {
release_keys.insert (pair<AccelKey,two_strings> (*b, two_strings (*g, *n)));
diff --git a/gtk2_ardour/mixer_strip.cc b/gtk2_ardour/mixer_strip.cc
index 52af1c09a6..8823e2810e 100644
--- a/gtk2_ardour/mixer_strip.cc
+++ b/gtk2_ardour/mixer_strip.cc
@@ -102,6 +102,14 @@ MixerStrip::MixerStrip (Mixer_UI& mx, Session& sess, bool in_mixer)
{
init ();
+
+ if (!_mixer_owned) {
+ /* the editor mixer strip: don't destroy it every time
+ the underlying route goes away.
+ */
+
+ self_destruct = false;
+ }
}
MixerStrip::MixerStrip (Mixer_UI& mx, Session& sess, boost::shared_ptr<Route> rt, bool in_mixer)
@@ -1280,16 +1288,16 @@ MixerStrip::width_clicked ()
void
MixerStrip::hide_clicked ()
{
- // LAME fix to reset the button status for when it is redisplayed (part 1)
- hide_button.set_sensitive(false);
-
+ // LAME fix to reset the button status for when it is redisplayed (part 1)
+ hide_button.set_sensitive(false);
+
if (_embedded) {
- Hiding(); /* EMIT_SIGNAL */
+ Hiding(); /* EMIT_SIGNAL */
} else {
_mixer.hide_strip (this);
}
- // (part 2)
+ // (part 2)
hide_button.set_sensitive(true);
}
diff --git a/gtk2_ardour/option_editor.cc b/gtk2_ardour/option_editor.cc
index 960f8065bc..b1bff9c5ff 100644
--- a/gtk2_ardour/option_editor.cc
+++ b/gtk2_ardour/option_editor.cc
@@ -1396,35 +1396,6 @@ OptionEditor::edit_button_changed ()
}
void
-OptionEditor::fixup_combo_size (Gtk::ComboBoxText& combo, vector<string>& strings)
-{
- /* find the widest string */
-
- string::size_type maxlen = 0;
- string maxstring;
-
- for (vector<string>::iterator i = strings.begin(); i != strings.end(); ++i) {
- string::size_type l;
-
- if ((l = (*i).length()) > maxlen) {
- maxlen = l;
- maxstring = *i;
- }
- }
-
- /* try to include ascenders and descenders */
-
- if (maxstring.length() > 2) {
- maxstring[0] = 'g';
- maxstring[1] = 'l';
- }
-
- const guint32 FUDGE = 10; // Combo's are stupid - they steal space from the entry for the button
-
- set_size_request_to_display_given_text (combo, maxstring.c_str(), 10 + FUDGE, 10);
-}
-
-void
OptionEditor::parameter_changed (const char* parameter_name)
{
ENSURE_GUI_THREAD (bind (mem_fun (*this, &OptionEditor::parameter_changed), parameter_name));
diff --git a/gtk2_ardour/option_editor.h b/gtk2_ardour/option_editor.h
index a6b1a74e5c..5fc0dd02b0 100644
--- a/gtk2_ardour/option_editor.h
+++ b/gtk2_ardour/option_editor.h
@@ -232,8 +232,6 @@ class OptionEditor : public ArdourDialog
void edit_button_changed ();
void delete_button_changed ();
void bindings_changed ();
-
- void fixup_combo_size (Gtk::ComboBoxText&, std::vector<std::string>& strings);
};
#endif /* __gtk_ardour_option_editor_h__ */
diff --git a/gtk2_ardour/plugin_selector.cc b/gtk2_ardour/plugin_selector.cc
index 9398661d70..5f5930c41c 100644
--- a/gtk2_ardour/plugin_selector.cc
+++ b/gtk2_ardour/plugin_selector.cc
@@ -50,6 +50,7 @@ using namespace std;
static const char* _filter_mode_strings[] = {
N_("Name contains"),
N_("Type contains"),
+ N_("Category contains"),
N_("Author contains"),
N_("Library contains"),
N_("Favorites only"),
@@ -210,14 +211,35 @@ PluginSelector::show_this_plugin (const PluginInfoPtr& info, const std::string&
if (mode == _("Name contains")) {
compstr = info->name;
- } else if (mode == _("Type contains")) {
+ } else if (mode == _("Category contains")) {
compstr = info->category;
+ } else if (mode == _("Type contains")) {
+
+ switch (info->type) {
+ case LADSPA:
+ compstr = X_("LADSPA");
+ break;
+ case AudioUnit:
+ compstr = X_("AudioUnit");
+ break;
+ case LV2:
+ compstr = X_("LV2");
+ break;
+ case VST:
+ compstr = X_("VST");
+ break;
+ }
+
} else if (mode == _("Author contains")) {
compstr = info->creator;
} else if (mode == _("Library contains")) {
compstr = info->path;
}
+ if (compstr.empty()) {
+ return false;
+ }
+
transform (compstr.begin(), compstr.end(), compstr.begin(), ::toupper);
if (compstr.find (filterstr) != string::npos) {
diff --git a/gtk2_ardour/plugin_ui.cc b/gtk2_ardour/plugin_ui.cc
index bfac04aa9b..36c5001816 100644
--- a/gtk2_ardour/plugin_ui.cc
+++ b/gtk2_ardour/plugin_ui.cc
@@ -377,7 +377,7 @@ PlugUIBase::PlugUIBase (boost::shared_ptr<PluginInsert> pi)
focus_button.add (*focus_out_image);
- ARDOUR_UI::instance()->set_tip (&focus_button, _("Click to focus all keyboard events on this plugin window"), "");
+ ARDOUR_UI::instance()->set_tip (&focus_button, _("Click to allow the plugin to receive keyboard events that Ardour would normally use as a shortcut"), "");
ARDOUR_UI::instance()->set_tip (&bypass_button, _("Click to enable/disable this plugin"), "");
plugin_eq_bin.set_expanded(true);
@@ -417,6 +417,7 @@ PlugUIBase::save_plugin_setting ()
prompter.set_type_hint (Gdk::WINDOW_TYPE_HINT_UTILITY);
prompter.show_all();
+ prompter.present ();
switch (prompter.run ()) {
case Gtk::RESPONSE_ACCEPT:
@@ -454,13 +455,13 @@ PlugUIBase::focus_toggled (GdkEventButton* ev)
focus_button.remove ();
focus_button.add (*focus_out_image);
focus_out_image->show ();
- ARDOUR_UI::instance()->set_tip (&focus_button, _("Click to focus all keyboard events on this plugin window"), "");
+ ARDOUR_UI::instance()->set_tip (&focus_button, _("Click to allow the plugin to receive keyboard events that Ardour would normally use as a shortcut"), "");
} else {
Keyboard::the_keyboard().magic_widget_grab_focus();
focus_button.remove ();
focus_button.add (*focus_in_image);
focus_in_image->show ();
- ARDOUR_UI::instance()->set_tip (&focus_button, _("Click to remove keyboard focus from this plugin window"), "");
+ ARDOUR_UI::instance()->set_tip (&focus_button, _("Click to allow normal use of Ardour keyboard shortcuts"), "");
}
return true;
diff --git a/gtk2_ardour/plugin_ui.h b/gtk2_ardour/plugin_ui.h
index 8f00ef8201..a920bfb07e 100644
--- a/gtk2_ardour/plugin_ui.h
+++ b/gtk2_ardour/plugin_ui.h
@@ -202,6 +202,7 @@ class GenericPluginUI : public PlugUIBase, public Gtk::HPaned
ControlUI* build_control_ui (guint32 port_index, boost::shared_ptr<ARDOUR::AutomationControl>);
std::vector<string> setup_scale_values(guint32 port_index, ControlUI* cui);
void parameter_changed (ControlUI* cui);
+ void toggle_parameter_changed (ControlUI* cui);
void update_control_display (ControlUI* cui);
void control_port_toggled (ControlUI* cui);
void control_combo_changed (ControlUI* cui);
diff --git a/gtk2_ardour/processor_box.cc b/gtk2_ardour/processor_box.cc
index 886f594ad4..627bada571 100644
--- a/gtk2_ardour/processor_box.cc
+++ b/gtk2_ardour/processor_box.cc
@@ -346,9 +346,13 @@ ProcessorBox::processor_button_release_event (GdkEventButton *ev)
show_processor_menu(ev->time);
ret = true;
- } else if (processor && Keyboard::is_button2_event (ev) && (Keyboard::no_modifier_keys_pressed (ev) && ((ev->state & Gdk::BUTTON2_MASK) == Gdk::BUTTON2_MASK))) {
-
- /* button2-click with no modifiers */
+ } else if (processor && Keyboard::is_button2_event (ev)
+#ifndef GTKOSX
+ && (Keyboard::no_modifier_keys_pressed (ev) && ((ev->state & Gdk::BUTTON2_MASK) == Gdk::BUTTON2_MASK))
+#endif
+ ) {
+
+ /* button2-click with no/appropriate modifiers */
if (processor->active()) {
processor->deactivate ();
diff --git a/gtk2_ardour/route_time_axis.cc b/gtk2_ardour/route_time_axis.cc
index b5b8a25d1f..a1f41adf6e 100644
--- a/gtk2_ardour/route_time_axis.cc
+++ b/gtk2_ardour/route_time_axis.cc
@@ -405,13 +405,8 @@ RouteTimeAxisView::playlist_click ()
void
RouteTimeAxisView::automation_click ()
{
- if (automation_action_menu == 0) {
- /* this seems odd, but the automation action
- menu is built as part of the display menu.
- */
- build_display_menu ();
- }
conditionally_add_to_selection ();
+ build_automation_action_menu ();
automation_action_menu->popup (1, gtk_get_current_event_time());
}
@@ -506,6 +501,7 @@ RouteTimeAxisView::build_display_menu ()
if (!Profile->get_sae()) {
build_remote_control_menu ();
items.push_back (MenuElem (_("Remote Control ID"), *remote_control_menu));
+ /* rebuild this every time */
build_automation_action_menu ();
items.push_back (MenuElem (_("Automation"), *automation_action_menu));
items.push_back (SeparatorElem());
diff --git a/gtk2_ardour/route_ui.cc b/gtk2_ardour/route_ui.cc
index 3107679df7..e0812e9036 100644
--- a/gtk2_ardour/route_ui.cc
+++ b/gtk2_ardour/route_ui.cc
@@ -77,8 +77,10 @@ RouteUI::RouteUI (boost::shared_ptr<ARDOUR::Route> rt,
RouteUI::~RouteUI()
{
- GoingAway (); /* EMIT SIGNAL */
-
+ /* derived classes should emit GoingAway so that they receive the signal
+ when the object is still a legal derived instance.
+ */
+
delete solo_menu;
delete mute_menu;
delete remote_control_menu;
@@ -87,6 +89,7 @@ RouteUI::~RouteUI()
void
RouteUI::init ()
{
+ self_destruct = true;
xml_node = 0;
mute_menu = 0;
solo_menu = 0;
@@ -162,8 +165,10 @@ RouteUI::set_route (boost::shared_ptr<Route> rp)
up when the route is destroyed.
*/
- new PairedShiva<Route,RouteUI> (*_route, *this);
-
+ if (self_destruct) {
+ new PairedShiva<Route,RouteUI> (*_route, *this);
+ }
+
mute_button->set_controllable (_route->mute_control());
mute_button->set_label (m_name);
diff --git a/gtk2_ardour/route_ui.h b/gtk2_ardour/route_ui.h
index 1287b49946..320dab9dae 100644
--- a/gtk2_ardour/route_ui.h
+++ b/gtk2_ardour/route_ui.h
@@ -176,6 +176,8 @@ class RouteUI : public virtual AxisView
std::string m_name;
std::string r_name;
+ bool self_destruct;
+
void init ();
void reset ();
};
diff --git a/gtk2_ardour/startup.cc b/gtk2_ardour/startup.cc
index 0675bb2f93..fe2bbe03c1 100644
--- a/gtk2_ardour/startup.cc
+++ b/gtk2_ardour/startup.cc
@@ -30,6 +30,9 @@ ArdourStartup::ArdourStartup ()
, ic_new_session_button (_("Open a new session"))
, ic_existing_session_button (_("Open an existing session"))
, more_new_session_options_button (_("I'd like more options for this session"))
+ , monitor_via_hardware_button (_("Use an external mixer or the hardware mixer of your audio interface.\n\
+Ardour will play NO role in monitoring"))
+ , monitor_via_ardour_button (_("Ask Ardour to playback material as it is being recorded"))
, new_folder_chooser (FILE_CHOOSER_ACTION_SELECT_FOLDER)
{
set_keep_above (true);
@@ -56,6 +59,7 @@ ArdourStartup::ArdourStartup ()
// XXX touch been_here_before;
setup_new_user_page ();
setup_first_time_config_page ();
+ setup_monitoring_choice_page ();
} else {
setup_initial_choice_page ();
}
@@ -142,6 +146,43 @@ Where would you like new Ardour sessions to be stored by default?\n\
}
void
+ArdourStartup::setup_monitoring_choice_page ()
+{
+ mon_vbox.set_spacing (6);
+ mon_vbox.set_border_width (6);
+
+ RadioButton::Group g (monitor_via_hardware_button.get_group());
+ monitor_via_ardour_button.set_group (g);
+
+ monitor_label.set_markup("\
+While recording instruments or vocals, you probably want to listen to the\n\
+signal as well as record it. This is called \"monitoring\". There are\n\
+different ways to do this depending on the equipment you have and the\n\
+configuration of that equipment. The two most common are presented here.\n\
+Please choose whichever one is right for your setup.\n\n\
+<i>You can change this preference at any time, via the Options menu</i>");
+
+ mon_vbox.pack_start (monitor_label);
+ mon_vbox.pack_start (monitor_via_hardware_button);
+ mon_vbox.pack_start (monitor_via_ardour_button);
+
+ mon_vbox.show ();
+ monitor_label.show ();
+ monitor_via_ardour_button.show ();
+ monitor_via_hardware_button.show ();
+
+ append_page (mon_vbox);
+ set_page_title (mon_vbox, _("Monitoring Choices"));
+ set_page_header_image (mon_vbox, icon_pixbuf);
+
+ /* user could just click on "Forward" if default
+ * choice is correct.
+ */
+
+ set_page_complete (mon_vbox, true);
+}
+
+void
ArdourStartup::setup_initial_choice_page ()
{
ic_vbox.set_spacing (6);
diff --git a/gtk2_ardour/startup.h b/gtk2_ardour/startup.h
index 1657d4fcd0..96adf954ba 100644
--- a/gtk2_ardour/startup.h
+++ b/gtk2_ardour/startup.h
@@ -49,6 +49,14 @@ class ArdourStartup : public Gtk::Assistant {
Gtk::RadioButton ic_new_session_button;
Gtk::RadioButton ic_existing_session_button;
+ /* monitoring choices */
+
+ Gtk::VBox mon_vbox;
+ Gtk::Label monitor_label;
+ Gtk::RadioButton monitor_via_hardware_button;
+ Gtk::RadioButton monitor_via_ardour_button;
+ void setup_monitoring_choice_page ();
+
/* session page (could be new or existing) */
void setup_session_page ();
diff --git a/gtk2_ardour/tempo_dialog.cc b/gtk2_ardour/tempo_dialog.cc
index 622045579c..7a59fe9ab0 100644
--- a/gtk2_ardour/tempo_dialog.cc
+++ b/gtk2_ardour/tempo_dialog.cc
@@ -82,13 +82,7 @@ TempoDialog::init (const BBT_Time& when, double bpm, double note_type, bool mova
strings.push_back (_("sixteenth (16)"));
strings.push_back (_("thirty-second (32)"));
- /* the string here needs to be the longest one to display */
- const guint32 FUDGE = 20; // Combo's are stupid - they steal space from the entry for the button
- // TRANSLATORS: this is not a mis-spelling of "thirty", we're including a vertical
- // descender to make sure the height gets computed properly.
- Gtkmm2ext::set_size_request_to_display_given_text (note_types, "thirtq-second (32)", 7+FUDGE, 15);
-
- set_popdown_strings (note_types, strings);
+ set_popdown_strings (note_types, strings, true);
if (note_type==1.0f)
note_types.set_active_text (_("whole (1)"));
@@ -309,14 +303,7 @@ MeterDialog::init (const BBT_Time& when, double bpb, double note_type, bool mova
strings.push_back (_("sixteenth (16)"));
strings.push_back (_("thirty-second (32)"));
- /* the string here needs to be the longest one to display */
- const guint32 FUDGE = 20; // Combo's are stupid - they steal space from the entry for the button
-
- // TRANSLATORS: this is not a mis-spelling of "thirty", we're including a vertical
- // descender to make sure the height gets computed properly.
- Gtkmm2ext::set_size_request_to_display_given_text (note_types, _("thirtq-second (32)"), 7+FUDGE, 15);
-
- set_popdown_strings (note_types, strings);
+ set_popdown_strings (note_types, strings, true);
if (note_type==1.0f)
note_types.set_active_text (_("whole (1)"));
diff --git a/libs/ardour/ardour/configuration_vars.h b/libs/ardour/ardour/configuration_vars.h
index 208fcbb0f0..81985ff77a 100644
--- a/libs/ardour/ardour/configuration_vars.h
+++ b/libs/ardour/ardour/configuration_vars.h
@@ -83,6 +83,8 @@ CONFIG_VARIABLE (LayerModel, layer_model, "layer-model", MoveAddHigher)
CONFIG_VARIABLE (bool, link_region_and_track_selection, "link-region-and-track-selection", false)
CONFIG_VARIABLE (std::string, keyboard_layout_name, "keyboard-layout-name", "ansi")
CONFIG_VARIABLE (bool, automation_follows_regions, "automation-follows-regions", false)
+CONFIG_VARIABLE (bool, region_boundaries_from_selected_tracks, "region-boundaries-from-selected-tracks", true)
+CONFIG_VARIABLE (bool, region_boundaries_from_onscreen_tracks, "region-boundaries-from-onscreen_tracks", true)
/* monitoring, mute, solo etc */
diff --git a/libs/ardour/audioengine.cc b/libs/ardour/audioengine.cc
index 19e6c27ba4..e0be9af6d9 100644
--- a/libs/ardour/audioengine.cc
+++ b/libs/ardour/audioengine.cc
@@ -558,9 +558,9 @@ AudioEngine::port_registration_failure (const std::string& portname)
string reason;
if (p) {
- reason = _("a port with this name already exists: check for duplicated track/bus names");
+ reason = string_compose (_("a port with the name \"%1\" already exists: check for duplicated track/bus names"), portname);
} else {
- reason = _("unknown error");
+ reason = _("No more JACK ports are available. You will need to stop Ardour and restart JACK with ports if you need this many tracks.");
}
throw PortRegistrationFailure (string_compose (_("AudioEngine: cannot register port \"%1\": %2"), portname, reason).c_str());
diff --git a/libs/ardour/audioregion.cc b/libs/ardour/audioregion.cc
index b5d733aea1..085296281c 100644
--- a/libs/ardour/audioregion.cc
+++ b/libs/ardour/audioregion.cc
@@ -356,10 +356,10 @@ nframes_t
AudioRegion::master_read_at (Sample *buf, Sample *mixdown_buffer, float *gain_buffer,
sframes_t position, nframes_t cnt, uint32_t chan_n) const
{
- return _read_at (_master_sources,
- _master_sources.front()->length(_master_sources.front()->timeline_position()),
- buf, mixdown_buffer, gain_buffer,
- position, cnt, chan_n, 0, 0);
+ /* do not read gain/scaling/fades and do not count this disk i/o in statistics */
+
+ return _read_at (_master_sources, _master_sources.front()->length(_master_sources.front()->timeline_position()),
+ buf, mixdown_buffer, gain_buffer, position, cnt, chan_n, 0, 0, ReadOps (0));
}
nframes_t
diff --git a/libs/ardour/playlist.cc b/libs/ardour/playlist.cc
index 3f8785cf37..f34e47b9da 100644
--- a/libs/ardour/playlist.cc
+++ b/libs/ardour/playlist.cc
@@ -1606,7 +1606,8 @@ Playlist::find_next_region (nframes_t frame, RegionPoint point, int dir)
pos = r->last_frame ();
break;
case SyncPoint:
- pos = r->adjust_to_sync (r->first_frame());
+ pos = r->sync_position ();
+ // r->adjust_to_sync (r->first_frame());
break;
}
diff --git a/libs/ardour/route.cc b/libs/ardour/route.cc
index 107603c176..04b4974ceb 100644
--- a/libs/ardour/route.cc
+++ b/libs/ardour/route.cc
@@ -2261,6 +2261,18 @@ Route::_set_state (const XMLNode& node, bool call_base)
delete _control_outs;
_control_outs = new IO (_session, coutname);
+
+ /* fix up the control out name in the XML before setting it.
+ Otherwise track templates don't work because the control
+ outs end up with the stored template name, rather than
+ the new name of the track based on the template.
+ */
+
+ XMLProperty* prop = (*child->children().begin())->property ("name");
+ if (prop) {
+ prop->set_value (coutname);
+ }
+
_control_outs->set_state (**(child->children().begin()));
} else if (child->name() == X_("Comment")) {
diff --git a/libs/ardour/session.cc b/libs/ardour/session.cc
index 25cf610189..e62d672984 100644
--- a/libs/ardour/session.cc
+++ b/libs/ardour/session.cc
@@ -565,17 +565,21 @@ Session::when_engine_running ()
} else {
- /* default state for Click */
+ /* default state for Click: dual-mono to first 2 physical outputs */
- first_physical_output = _engine.get_nth_physical_output (DataType::AUDIO, 0);
+ for (int physport = 0; physport < 2; ++physport) {
+ string physical_output = _engine.get_nth_physical_output (DataType::AUDIO, physport);
- if (first_physical_output.length()) {
- if (_click_io->add_output_port (first_physical_output, this)) {
- // relax, even though its an error
- } else {
- _clicking = Config->get_clicking ();
- }
- }
+ if (physical_output.length()) {
+ if (_click_io->add_output_port (physical_output, this)) {
+ // relax, even though its an error
+ }
+ }
+ }
+
+ if (_click_io->n_outputs () > ChanCount::ZERO) {
+ _clicking = Config->get_clicking ();
+ }
}
}
@@ -1529,7 +1533,7 @@ Session::new_midi_track (TrackMode mode, uint32_t how_many)
shared_ptr<RouteList> r = routes.reader ();
for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
- if (dynamic_cast<MidiTrack*>((*i).get()) != 0) {
+ if (boost::dynamic_pointer_cast<MidiTrack>(*i) != 0) {
if (!(*i)->is_hidden()) {
n++;
//channels_used += (*i)->n_inputs().n_midi();
@@ -1687,7 +1691,7 @@ Session::new_audio_track (int input_channels, int output_channels, TrackMode mod
shared_ptr<RouteList> r = routes.reader ();
for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
- if (dynamic_cast<AudioTrack*>((*i).get()) != 0) {
+ if (boost::dynamic_pointer_cast<AudioTrack>(*i) != 0) {
if (!(*i)->is_hidden()) {
n++;
channels_used += (*i)->n_inputs().n_audio();
@@ -1805,7 +1809,7 @@ Session::new_audio_track (int input_channels, int output_channels, TrackMode mod
catch (AudioEngine::PortRegistrationFailure& pfe) {
- error << _("No more JACK ports are available. You will need to stop Ardour and restart JACK with ports if you need this many tracks.") << endmsg;
+ error << pfe.what() << endmsg;
if (track) {
/* we need to get rid of this, since the track failed to be created */
@@ -1963,7 +1967,7 @@ Session::new_audio_route (int input_channels, int output_channels, uint32_t how_
}
catch (AudioEngine::PortRegistrationFailure& pfe) {
- error << _("No more JACK ports are available. You will need to stop Ardour and restart JACK with ports if you need this many tracks.") << endmsg;
+ error << pfe.what() << endmsg;
goto failure;
}
@@ -2058,7 +2062,7 @@ Session::new_route_from_template (uint32_t how_many, const std::string& template
}
catch (AudioEngine::PortRegistrationFailure& pfe) {
- error << _("No more JACK ports are available. You will need to stop Ardour and restart JACK with ports if you need this many tracks.") << endmsg;
+ error << pfe.what() << endmsg;
goto out;
}
@@ -2182,10 +2186,10 @@ Session::remove_route (shared_ptr<Route> route)
/* writer goes out of scope, forces route list update */
}
- Track* t;
+ boost::shared_ptr<Track> t;
boost::shared_ptr<Diskstream> ds;
- if ((t = dynamic_cast<Track*>(route.get())) != 0) {
+ if ((t = boost::dynamic_pointer_cast<Track>(route)) != 0) {
ds = t->diskstream();
}
@@ -2262,7 +2266,7 @@ Session::route_solo_changed (void* src, boost::weak_ptr<Route> wpr)
/* don't mess with busses */
- if (dynamic_cast<Track*>((*i).get()) == 0) {
+ if (boost::dynamic_pointer_cast<Track>(*i) == 0) {
continue;
}
@@ -2270,7 +2274,7 @@ Session::route_solo_changed (void* src, boost::weak_ptr<Route> wpr)
/* don't mess with tracks */
- if (dynamic_cast<Track*>((*i).get()) != 0) {
+ if (boost::dynamic_pointer_cast<Track>(*i) != 0) {
continue;
}
}
@@ -2306,7 +2310,7 @@ Session::route_solo_changed (void* src, boost::weak_ptr<Route> wpr)
for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
if ((*i)->soloed()) {
something_soloed = true;
- if (dynamic_cast<Track*>((*i).get())) {
+ if (boost::dynamic_pointer_cast<Track>(*i)) {
if (is_track) {
same_thing_soloed = true;
break;
@@ -2353,7 +2357,7 @@ Session::update_route_solo_state ()
for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
if ((*i)->soloed()) {
mute = true;
- if (dynamic_cast<Track*>((*i).get())) {
+ if (boost::dynamic_pointer_cast<Track>(*i)) {
is_track = true;
}
break;
@@ -2398,7 +2402,7 @@ Session::modify_solo_mute (bool is_track, bool mute)
/* only alter track solo mute */
- if (dynamic_cast<Track*>((*i).get())) {
+ if (boost::dynamic_pointer_cast<Track>(*i)) {
if ((*i)->soloed()) {
(*i)->set_solo_mute (!mute);
} else {
@@ -2410,7 +2414,7 @@ Session::modify_solo_mute (bool is_track, bool mute)
/* only alter bus solo mute */
- if (!dynamic_cast<Track*>((*i).get())) {
+ if (!boost::dynamic_pointer_cast<Track>(*i)) {
if ((*i)->soloed()) {
@@ -3673,10 +3677,10 @@ Session::record_enable_change_all (bool yn)
shared_ptr<RouteList> r = routes.reader ();
for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
- Track* at;
+ boost::shared_ptr<Track> t;
- if ((at = dynamic_cast<Track*>((*i).get())) != 0) {
- at->set_record_enable (yn, this);
+ if ((t = boost::dynamic_pointer_cast<Track>(*i)) != 0) {
+ t->set_record_enable (yn, this);
}
}
@@ -4040,13 +4044,13 @@ Session::freeze (InterThreadInfo& itt)
for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
- Track *at;
+ boost::shared_ptr<Track> t;
- if ((at = dynamic_cast<Track*>((*i).get())) != 0) {
+ if ((t = boost::dynamic_pointer_cast<Track>(*i)) != 0) {
/* XXX this is wrong because itt.progress will keep returning to zero at the start
of every track.
*/
- at->freeze (itt);
+ t->freeze (itt);
}
}
@@ -4255,7 +4259,7 @@ Session::ntracks () const
shared_ptr<RouteList> r = routes.reader ();
for (RouteList::const_iterator i = r->begin(); i != r->end(); ++i) {
- if (dynamic_cast<Track*> ((*i).get())) {
+ if (boost::dynamic_pointer_cast<Track> (*i)) {
++n;
}
}
@@ -4270,7 +4274,7 @@ Session::nbusses () const
shared_ptr<RouteList> r = routes.reader ();
for (RouteList::const_iterator i = r->begin(); i != r->end(); ++i) {
- if (dynamic_cast<Track*> ((*i).get()) == 0) {
+ if (boost::dynamic_pointer_cast<Track>(*i) == 0) {
++n;
}
}
diff --git a/libs/gtkmm2ext/gtkmm2ext/utils.h b/libs/gtkmm2ext/gtkmm2ext/utils.h
index e664f2420d..7f986e738c 100644
--- a/libs/gtkmm2ext/gtkmm2ext/utils.h
+++ b/libs/gtkmm2ext/gtkmm2ext/utils.h
@@ -45,12 +45,21 @@ namespace Gtkmm2ext {
gint vpadding);
void set_size_request_to_display_given_text (Gtk::Widget &w,
- const std::vector<std::string>&,
+ const std::vector<std::string>&,
gint hpadding,
gint vpadding);
void set_popdown_strings (Gtk::ComboBoxText&,
- const std::vector<std::string>&);
+ const std::vector<std::string>&,
+ bool set_size = false,
+ gint hpadding = 0, gint vpadding = 0);
+
+ // Combo's are stupid - they steal space from the entry for the button
+#ifdef GTKOSX
+ static const guint32 COMBO_FUDGE = 38;
+#else
+ static const guint32 COMBO_FUDGE = 24;
+#endif
template<class T> void deferred_delete (void *ptr) {
delete static_cast<T *> (ptr);
diff --git a/libs/gtkmm2ext/sync-menu.c b/libs/gtkmm2ext/sync-menu.c
index 894446c424..a16babce54 100644
--- a/libs/gtkmm2ext/sync-menu.c
+++ b/libs/gtkmm2ext/sync-menu.c
@@ -313,6 +313,7 @@ carbon_menu_item_update_accelerator (CarbonMenuItem *carbon_item,
gint n_keys;
gint use_command;
gboolean add_modifiers = FALSE;
+ UInt8 modifiers = 0; /* implies Command key */
if (gdk_keymap_get_entries_for_keyval (keymap, key->accel_key,
&keys, &n_keys) == 0)
@@ -347,10 +348,14 @@ carbon_menu_item_update_accelerator (CarbonMenuItem *carbon_item,
}
} else {
- SetMenuItemCommandKey (carbon_item->menu, carbon_item->index,
- true, keys[0].keycode);
- g_free (keys);
- add_modifiers = TRUE;
+ SetMenuItemCommandKey (carbon_item->menu, carbon_item->index, true, keys[0].keycode);
+ if (keys[0].level == 1) {
+ /* regular key, but it needs shift to make it work */
+ modifiers |= kMenuShiftModifier;
+ }
+
+ g_free (keys);
+ add_modifiers = TRUE;
}
if (add_modifiers)
@@ -589,7 +594,7 @@ menu_event_handler_func (EventHandlerCallRef event_handler_call_ref,
sizeof (widget), 0, &widget);
if (err == noErr && GTK_IS_WIDGET (widget))
{
- g_idle_add (dummy_gtk_menu_item_activate, widget);
+ g_idle_add ((GSourceFunc) dummy_gtk_menu_item_activate, widget);
// gtk_menu_item_activate (GTK_MENU_ITEM (widget));
_in_carbon_menu_event_handler = 0;
return noErr;
diff --git a/libs/gtkmm2ext/utils.cc b/libs/gtkmm2ext/utils.cc
index adcaaaaeb5..3a021bbe7b 100644
--- a/libs/gtkmm2ext/utils.cc
+++ b/libs/gtkmm2ext/utils.cc
@@ -59,8 +59,8 @@ Gtkmm2ext::set_size_request_to_display_given_text (Gtk::Widget &w, const gchar *
void
Gtkmm2ext::set_size_request_to_display_given_text (Gtk::Widget &w,
- const std::vector<std::string>& strings,
- gint hpadding, gint vpadding)
+ const std::vector<std::string>& strings,
+ gint hpadding, gint vpadding)
{
int width, height;
@@ -68,11 +68,10 @@ Gtkmm2ext::set_size_request_to_display_given_text (Gtk::Widget &w,
int height_max = 0;
w.ensure_style ();
- for (vector<string>::const_iterator i = strings.begin();
- i != strings.end(); ++i) {
- get_ink_pixel_size (w.create_pango_layout (*i), width, height);
- width_max = max(width_max,width);
- height_max = max(height_max, height);
+ for (vector<string>::const_iterator i = strings.begin(); i != strings.end(); ++i) {
+ get_ink_pixel_size (w.create_pango_layout (*i), width, height);
+ width_max = max(width_max,width);
+ height_max = max(height_max, height);
}
w.set_size_request(width_max + hpadding, height_max + vpadding);
}
@@ -85,11 +84,36 @@ Gtkmm2ext::init ()
}
void
-Gtkmm2ext::set_popdown_strings (Gtk::ComboBoxText& cr, const vector<string>& strings)
+Gtkmm2ext::set_popdown_strings (Gtk::ComboBoxText& cr, const vector<string>& strings, bool set_size, gint hpadding, gint vpadding)
{
+ vector<string>::const_iterator i;
+
cr.clear ();
- for (vector<string>::const_iterator i = strings.begin(); i != strings.end(); ++i) {
+ if (set_size) {
+ vector<string> copy;
+
+ for (i = strings.begin(); i != strings.end(); ++i) {
+ if ((*i).find_first_of ("gy") != string::npos) {
+ /* contains a descender */
+ break;
+ }
+ }
+
+ if (i == strings.end()) {
+
+ /* make a copy of the strings then add one that has a descener */
+
+ copy = strings;
+ copy.push_back ("g");
+ set_size_request_to_display_given_text (cr, copy, COMBO_FUDGE+10+hpadding, 15+vpadding);
+
+ } else {
+ set_size_request_to_display_given_text (cr, strings, COMBO_FUDGE+10+hpadding, 15+vpadding);
+ }
+ }
+
+ for (i = strings.begin(); i != strings.end(); ++i) {
cr.append_text (*i);
}
}
diff --git a/libs/surfaces/mackie/mackie_control_protocol.cc b/libs/surfaces/mackie/mackie_control_protocol.cc
index 18dbd28c0e..c9f67a6bef 100644
--- a/libs/surfaces/mackie/mackie_control_protocol.cc
+++ b/libs/surfaces/mackie/mackie_control_protocol.cc
@@ -293,7 +293,7 @@ void MackieControlProtocol::switch_banks( int initial )
cout << "remote id " << route->remote_control_id() << " connecting " << route->name() << " to " << strip.name() << " with port " << port_for_id(i) << endl;
#endif
route_table[i] = route;
- RouteSignal * rs = new RouteSignal( *route, *this, strip, port_for_id(i) );
+ RouteSignal * rs = new RouteSignal (route, *this, strip, port_for_id(i) );
route_signals.push_back( rs );
// update strip from route
rs->notify_all();
@@ -543,11 +543,14 @@ void MackieControlProtocol::update_surface()
switch_banks( _current_initial_bank );
// create a RouteSignal for the master route
- // but only the first time around
- master_route_signal = shared_ptr<RouteSignal>( new RouteSignal( *master_route(), *this, master_strip(), mcu_port() ) );
- // update strip from route
- master_route_signal->notify_all();
-
+
+ boost::shared_ptr<Route> mr = master_route ();
+ if (mr) {
+ master_route_signal = shared_ptr<RouteSignal> (new RouteSignal (mr, *this, master_strip(), mcu_port()) );
+ // update strip from route
+ master_route_signal->notify_all();
+ }
+
// sometimes the jog wheel is a pot
surface().blank_jog_ring( mcu_port(), builder );
@@ -656,13 +659,8 @@ void MackieControlProtocol::create_ports()
shared_ptr<Route> MackieControlProtocol::master_route()
{
- shared_ptr<Route> retval;
- retval = session->route_by_name( "master" );
- if ( retval == 0 )
- {
- // TODO search through all routes for one with the master attribute set
- }
- return retval;
+ boost::shared_ptr<IO> mo = session->master_out ();
+ return boost::dynamic_pointer_cast<Route>(mo);
}
Strip & MackieControlProtocol::master_strip()
@@ -966,7 +964,7 @@ void MackieControlProtocol::notify_solo_changed( RouteSignal * route_signal )
try
{
Button & button = route_signal->strip().solo();
- route_signal->port().write( builder.build_led( button, route_signal->route().soloed() ) );
+ route_signal->port().write( builder.build_led( button, route_signal->route()->soloed() ) );
}
catch( exception & e )
{
@@ -979,7 +977,7 @@ void MackieControlProtocol::notify_mute_changed( RouteSignal * route_signal )
try
{
Button & button = route_signal->strip().mute();
- route_signal->port().write( builder.build_led( button, route_signal->route().muted() ) );
+ route_signal->port().write( builder.build_led( button, route_signal->route()->muted() ) );
}
catch( exception & e )
{
@@ -992,7 +990,7 @@ void MackieControlProtocol::notify_record_enable_changed( RouteSignal * route_si
try
{
Button & button = route_signal->strip().recenable();
- route_signal->port().write( builder.build_led( button, route_signal->route().record_enabled() ) );
+ route_signal->port().write( builder.build_led( button, route_signal->route()->record_enabled() ) );
}
catch( exception & e )
{
@@ -1022,7 +1020,7 @@ void MackieControlProtocol::notify_gain_changed( RouteSignal * route_signal, boo
Fader & fader = route_signal->strip().gain();
if ( !fader.in_use() )
{
- float gain_value = route_signal->route().gain_control()->get_value();
+ float gain_value = route_signal->route()->gain_control()->get_value();
// check that something has actually changed
if ( force_update || gain_value != route_signal->last_gain_written() )
{
@@ -1045,7 +1043,7 @@ void MackieControlProtocol::notify_name_changed( RouteSignal * route_signal )
if ( !strip.is_master() )
{
string line1;
- string fullname = route_signal->route().name();
+ string fullname = route_signal->route()->name();
if ( fullname.length() <= 6 )
{
@@ -1072,11 +1070,11 @@ void MackieControlProtocol::notify_panner_changed( RouteSignal * route_signal, b
try
{
Pot & pot = route_signal->strip().vpot();
- const Panner & panner = route_signal->route().panner();
+ const Panner & panner = route_signal->route()->panner();
if ( panner.npanners() == 1 || ( panner.npanners() == 2 && panner.linked() ) )
{
float pos;
- route_signal->route().panner().streampanner(0).get_effective_position( pos );
+ route_signal->route()->panner().streampanner(0).get_effective_position( pos );
// cache the MidiByteArray here, because the mackie led control is much lower
// resolution than the panner control. So we save lots of byte
@@ -1103,13 +1101,13 @@ void MackieControlProtocol::notify_panner_changed( RouteSignal * route_signal, b
// TODO handle plugin automation polling
void MackieControlProtocol::update_automation( RouteSignal & rs )
{
- ARDOUR::AutoState gain_state = rs.route().gain_control()->automation_state();
+ ARDOUR::AutoState gain_state = rs.route()->gain_control()->automation_state();
if ( gain_state == Touch || gain_state == Play )
{
notify_gain_changed( &rs, false );
}
- ARDOUR::AutoState panner_state = rs.route().panner().automation_state();
+ ARDOUR::AutoState panner_state = rs.route()->panner().automation_state();
if ( panner_state == Touch || panner_state == Play )
{
notify_panner_changed( &rs, false );
diff --git a/libs/surfaces/mackie/route_signal.cc b/libs/surfaces/mackie/route_signal.cc
index 33a8908dde..b2139e1cbe 100644
--- a/libs/surfaces/mackie/route_signal.cc
+++ b/libs/surfaces/mackie/route_signal.cc
@@ -25,48 +25,39 @@
#include <stdexcept>
+using namespace ARDOUR;
using namespace Mackie;
using namespace std;
void RouteSignal::connect()
{
back_insert_iterator<Connections> cins = back_inserter( _connections );
-
+
if ( _strip.has_solo() )
- cins = _route.solo_control()->Changed.connect( sigc::bind ( mem_fun ( _mcp, &MackieControlProtocol::notify_solo_changed ), this ) );
+ cins = _route->solo_control()->Changed.connect( sigc::bind ( mem_fun ( _mcp, &MackieControlProtocol::notify_solo_changed ), this ) );
if ( _strip.has_mute() )
- cins = _route.mute_control()->Changed.connect( sigc::bind ( mem_fun ( _mcp, &MackieControlProtocol::notify_mute_changed ), this ) );
+ cins = _route->mute_control()->Changed.connect( sigc::bind ( mem_fun ( _mcp, &MackieControlProtocol::notify_mute_changed ), this ) );
if ( _strip.has_gain() )
- cins = _route.gain_control()->Changed.connect( sigc::bind ( mem_fun ( _mcp, &MackieControlProtocol::notify_gain_changed ), this, true ) );
+ cins = _route->gain_control()->Changed.connect( sigc::bind ( mem_fun ( _mcp, &MackieControlProtocol::notify_gain_changed ), this, true ) );
- cins = _route.NameChanged.connect( sigc::bind ( mem_fun ( _mcp, &MackieControlProtocol::notify_name_changed ), this ) );
+ cins = _route->NameChanged.connect( sigc::bind ( mem_fun ( _mcp, &MackieControlProtocol::notify_name_changed ), this ) );
- cins = _route.panner().Changed.connect( sigc::bind ( mem_fun ( _mcp, &MackieControlProtocol::notify_panner_changed ), this, true ) );
- for ( unsigned int i = 0; i < _route.panner().npanners(); ++i )
- {
- cins = _route.panner().streampanner (i).Changed.connect( sigc::bind ( mem_fun ( _mcp, &MackieControlProtocol::notify_panner_changed ), this, true ) );
- }
+ cins = _route->panner().Changed.connect( sigc::bind ( mem_fun ( _mcp, &MackieControlProtocol::notify_panner_changed ), this, true ) );
+ for ( unsigned int i = 0; i < _route->panner().npanners(); ++i ) {
+ cins = _route->panner().streampanner (i).Changed.connect( sigc::bind ( mem_fun ( _mcp, &MackieControlProtocol::notify_panner_changed ), this, true ) );
+ }
- try
- {
- cins = dynamic_cast<ARDOUR::Track&>( _route )
- .rec_enable_control()
- ->Changed
- .connect( sigc::bind ( mem_fun ( _mcp, &MackieControlProtocol::notify_record_enable_changed ), this ) )
- ;
+ boost::shared_ptr<Track> trk = boost::dynamic_pointer_cast<ARDOUR::Track>(_route);
+ if (trk) {
+ cins = trk->rec_enable_control()->Changed .connect( sigc::bind ( mem_fun ( _mcp, &MackieControlProtocol::notify_record_enable_changed ), this));
}
- catch ( std::bad_cast & )
- {
- // this should catch the dynamic_cast to Track, if what we're working
- // with can't be record-enabled
- }
-
+
// TODO this works when a currently-banked route is made inactive, but not
// when a route is activated which should be currently banked.
- cins = _route.active_changed.connect( sigc::bind ( mem_fun ( _mcp, &MackieControlProtocol::notify_active_changed ), this ) );
-
+ cins = _route->active_changed.connect( sigc::bind ( mem_fun ( _mcp, &MackieControlProtocol::notify_active_changed ), this ) );
+
// TODO
// SelectedChanged
// RemoteControlIDChanged. Better handled at Session level.
diff --git a/libs/surfaces/mackie/route_signal.h b/libs/surfaces/mackie/route_signal.h
index 01b3c97c16..a272449e52 100644
--- a/libs/surfaces/mackie/route_signal.h
+++ b/libs/surfaces/mackie/route_signal.h
@@ -19,6 +19,7 @@
#define route_signal_h
#include <sigc++/sigc++.h>
+#include <boost/shared_ptr.hpp>
#include <vector>
@@ -45,7 +46,7 @@ class SurfacePort;
class RouteSignal
{
public:
- RouteSignal( ARDOUR::Route & route, MackieControlProtocol & mcp, Strip & strip, SurfacePort & port )
+ RouteSignal(boost::shared_ptr<ARDOUR::Route> route, MackieControlProtocol & mcp, Strip & strip, SurfacePort & port )
: _route( route ), _mcp( mcp ), _strip( strip ), _port( port ), _last_gain_written(0.0)
{
connect();
@@ -62,7 +63,7 @@ public:
// call all signal handlers manually
void notify_all();
- const ARDOUR::Route & route() const { return _route; }
+ boost::shared_ptr<const ARDOUR::Route> route() const { return _route; }
Strip & strip() { return _strip; }
SurfacePort & port() { return _port; }
@@ -73,7 +74,7 @@ public:
void last_pan_written( const MidiByteArray & other ) { _last_pan_written = other; }
private:
- ARDOUR::Route & _route;
+ boost::shared_ptr<ARDOUR::Route> _route;
MackieControlProtocol & _mcp;
Strip & _strip;
SurfacePort & _port;