summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaul Davis <paul@linuxaudiosystems.com>2012-06-25 12:46:13 +0000
committerPaul Davis <paul@linuxaudiosystems.com>2012-06-25 12:46:13 +0000
commit97d920593ffc796986107e16d7bbf88cc3184043 (patch)
treecc68f13ec1c9be69f98d30bd734e809fea30a0d1
parentf2f35e50a0e2d6e0b2c7f02b5e6c76e82643c80a (diff)
drastic rethink of the relationship between remote control ID and route order keys. unless the user explicitly switches to UserOrdered, Route::_remote_control_id is an unallocated pointer, and Route::remote_control_id() simply returns a value based on the relevant order_key() value. Also, change the key used in the Route::order_keys std::map<> from a string to an enum, since there is no evidence that we are benefitting from the theoretical benefit of using a string. Generally tidy up allocation of order keys so that the master and monitor busses always get a "special" MixerSort key value, based on the MMC ID for master (already defined within Ardour), and all other tracks/busses start at zero. Syncing keys between editor and mixer will leave the MixerSort key for the master and monitor bus alone, reflecting the fact that we display these in their own distinct parts of the GUI and they are not orderable like other tracks or busses within the mixer window
git-svn-id: svn://localhost/ardour2/branches/3.0@12923 d708f5d6-7413-0410-9779-e7cbd77b26cf
-rw-r--r--gtk2_ardour/editor_drag.cc2
-rw-r--r--gtk2_ardour/editor_group_tabs.cc6
-rw-r--r--gtk2_ardour/editor_group_tabs.h2
-rw-r--r--gtk2_ardour/editor_ops.cc3
-rw-r--r--gtk2_ardour/editor_routes.cc36
-rw-r--r--gtk2_ardour/editor_routes.h2
-rw-r--r--gtk2_ardour/editor_selection.cc8
-rw-r--r--gtk2_ardour/group_tabs.cc9
-rw-r--r--gtk2_ardour/group_tabs.h2
-rw-r--r--gtk2_ardour/mixer_group_tabs.cc6
-rw-r--r--gtk2_ardour/mixer_group_tabs.h2
-rw-r--r--gtk2_ardour/mixer_ui.cc63
-rw-r--r--gtk2_ardour/mixer_ui.h3
-rw-r--r--gtk2_ardour/port_group.cc2
-rw-r--r--gtk2_ardour/route_ui.cc42
-rw-r--r--libs/ardour/ardour/route.h18
-rw-r--r--libs/ardour/ardour/session.h5
-rw-r--r--libs/ardour/ardour/types.h6
-rw-r--r--libs/ardour/enums.cc5
-rw-r--r--libs/ardour/route.cc131
-rw-r--r--libs/ardour/route_graph.cc4
-rw-r--r--libs/ardour/session.cc90
-rw-r--r--libs/ardour/session_state.cc10
23 files changed, 268 insertions, 189 deletions
diff --git a/gtk2_ardour/editor_drag.cc b/gtk2_ardour/editor_drag.cc
index ae3795f7fa..8ae618b37f 100644
--- a/gtk2_ardour/editor_drag.cc
+++ b/gtk2_ardour/editor_drag.cc
@@ -420,7 +420,7 @@ struct EditorOrderTimeAxisViewSorter {
RouteTimeAxisView* ra = dynamic_cast<RouteTimeAxisView*> (a);
RouteTimeAxisView* rb = dynamic_cast<RouteTimeAxisView*> (b);
assert (ra && rb);
- return ra->route()->order_key (N_ ("editor")) < rb->route()->order_key (N_ ("editor"));
+ return ra->route()->order_key (EditorSort) < rb->route()->order_key (EditorSort);
}
};
diff --git a/gtk2_ardour/editor_group_tabs.cc b/gtk2_ardour/editor_group_tabs.cc
index 352eec88cc..5a1e9c8aaa 100644
--- a/gtk2_ardour/editor_group_tabs.cc
+++ b/gtk2_ardour/editor_group_tabs.cc
@@ -177,10 +177,10 @@ EditorGroupTabs::default_properties () const
return plist;
}
-string
+RouteSortOrderKey
EditorGroupTabs::order_key () const
{
- return X_("editor");
+ return EditorSort;
}
RouteList
@@ -201,5 +201,5 @@ EditorGroupTabs::selected_routes () const
void
EditorGroupTabs::sync_order_keys ()
{
- _editor->_routes->sync_order_keys ("");
+ _editor->_routes->sync_order_keys (UndefinedSort);
}
diff --git a/gtk2_ardour/editor_group_tabs.h b/gtk2_ardour/editor_group_tabs.h
index e2ed6055aa..a0021e4833 100644
--- a/gtk2_ardour/editor_group_tabs.h
+++ b/gtk2_ardour/editor_group_tabs.h
@@ -37,7 +37,7 @@ private:
}
void add_menu_items (Gtk::Menu *, ARDOUR::RouteGroup *);
PBD::PropertyList default_properties () const;
- std::string order_key () const;
+ ARDOUR::RouteSortOrderKey order_key () const;
ARDOUR::RouteList selected_routes () const;
void sync_order_keys ();
};
diff --git a/gtk2_ardour/editor_ops.cc b/gtk2_ardour/editor_ops.cc
index 46a69ce6af..d891db6651 100644
--- a/gtk2_ardour/editor_ops.cc
+++ b/gtk2_ardour/editor_ops.cc
@@ -5411,8 +5411,7 @@ Editor::split_region ()
struct EditorOrderRouteSorter {
bool operator() (boost::shared_ptr<Route> a, boost::shared_ptr<Route> b) {
- /* use of ">" forces the correct sort order */
- return a->order_key ("editor") < b->order_key ("editor");
+ return a->order_key (EditorSort) < b->order_key (EditorSort);
}
};
diff --git a/gtk2_ardour/editor_routes.cc b/gtk2_ardour/editor_routes.cc
index c4443cbed0..3faeba183f 100644
--- a/gtk2_ardour/editor_routes.cc
+++ b/gtk2_ardour/editor_routes.cc
@@ -520,7 +520,14 @@ EditorRoutes::redisplay ()
/* this reorder is caused by user action, so reassign sort order keys
to tracks.
*/
- route->set_order_key (N_ ("editor"), order_key);
+
+ if (route->is_master()) {
+ route->set_order_key (EditorSort, Route::MasterBusRemoteControlID);
+ } else if (route->is_monitor()) {
+ route->set_order_key (EditorSort, Route::MonitorBusRemoteControlID);
+ } else {
+ route->set_order_key (EditorSort, order_key++);
+ }
}
bool visible = tv->marked_for_display ();
@@ -534,7 +541,6 @@ EditorRoutes::redisplay ()
}
n++;
- order_key++;
}
/* whenever we go idle, update the track view list to reflect the new order.
@@ -557,7 +563,7 @@ EditorRoutes::redisplay ()
}
if (!_redisplay_does_not_reset_order_keys && !_redisplay_does_not_sync_order_keys) {
- _session->sync_order_keys (N_ ("editor"));
+ _session->sync_order_keys (EditorSort);
}
}
@@ -569,7 +575,6 @@ EditorRoutes::route_deleted (Gtk::TreeModel::Path const &)
}
/* this could require an order reset & sync */
- _session->set_remote_control_ids();
_ignore_reorder = true;
redisplay ();
_ignore_reorder = false;
@@ -591,7 +596,6 @@ EditorRoutes::visible_changed (std::string const & path)
if (tv->set_marked_for_display (!visible)) {
_redisplay_does_not_reset_order_keys = true;
- _session->set_remote_control_ids();
update_visibility ();
redisplay ();
_redisplay_does_not_reset_order_keys = false;
@@ -649,15 +653,6 @@ EditorRoutes::routes_added (list<RouteTimeAxisView*> routes)
row[_columns.solo_safe_state] = (*x)->route()->solo_safe();
row[_columns.name_editable] = true;
- _ignore_reorder = true;
-
- /* added a new fresh one at the end */
- if ((*x)->route()->order_key (N_ ("editor")) == -1) {
- (*x)->route()->set_order_key (N_ ("editor"), _model->children().size()-1);
- }
-
- _ignore_reorder = false;
-
boost::weak_ptr<Route> wr ((*x)->route());
(*x)->route()->gui_changed.connect (*this, MISSING_INVALIDATOR, boost::bind (&EditorRoutes::handle_gui_changes, this, _1, _2), gui_context());
@@ -833,13 +828,13 @@ EditorRoutes::reordered (TreeModel::Path const &, TreeModel::iterator const &, i
* route list so that the visual arrangement of routes matches the order keys from the routes.
*/
void
-EditorRoutes::sync_order_keys (string const & src)
+EditorRoutes::sync_order_keys (RouteSortOrderKey src)
{
map<int, int> new_order;
TreeModel::Children rows = _model->children();
TreeModel::Children::iterator ri;
- if (src == N_ ("editor") || !_session || (_session->state_of_the_state() & (Session::Loading|Session::Deletion)) || rows.empty()) {
+ if (src == EditorSort || !_session || (_session->state_of_the_state() & (Session::Loading|Session::Deletion)) || rows.empty()) {
return;
}
@@ -850,7 +845,7 @@ EditorRoutes::sync_order_keys (string const & src)
boost::shared_ptr<Route> route = (*ri)[_columns.route];
int const old_key = order;
- int const new_key = route->order_key (N_ ("editor"));
+ int const new_key = route->order_key (EditorSort);
new_order[new_key] = old_key;
@@ -1193,7 +1188,7 @@ EditorRoutes::selection_filter (Glib::RefPtr<TreeModel> const &, TreeModel::Path
struct EditorOrderRouteSorter {
bool operator() (boost::shared_ptr<Route> a, boost::shared_ptr<Route> b) {
/* use of ">" forces the correct sort order */
- return a->order_key (N_ ("editor")) < b->order_key (N_ ("editor"));
+ return a->order_key (EditorSort) < b->order_key (EditorSort);
}
};
@@ -1247,7 +1242,6 @@ void
EditorRoutes::track_list_reorder (Gtk::TreeModel::Path const &, Gtk::TreeModel::iterator const &, int* /*new_order*/)
{
_redisplay_does_not_sync_order_keys = true;
- _session->set_remote_control_ids();
redisplay ();
_redisplay_does_not_sync_order_keys = false;
}
@@ -1370,7 +1364,7 @@ EditorRoutes::move_selected_tracks (bool up)
}
for (leading = view_routes.begin(); leading != view_routes.end(); ++leading) {
- neworder.push_back (leading->second->order_key (N_ ("editor")));
+ neworder.push_back (leading->second->order_key (EditorSort));
}
#ifndef NDEBUG
@@ -1381,7 +1375,7 @@ EditorRoutes::move_selected_tracks (bool up)
_model->reorder (neworder);
- _session->sync_order_keys (N_ ("editor"));
+ _session->sync_order_keys (EditorSort);
}
void
diff --git a/gtk2_ardour/editor_routes.h b/gtk2_ardour/editor_routes.h
index 5fad890faf..00631d914a 100644
--- a/gtk2_ardour/editor_routes.h
+++ b/gtk2_ardour/editor_routes.h
@@ -55,7 +55,7 @@ public:
std::list<TimeAxisView*> views () const;
void hide_all_tracks (bool);
void clear ();
- void sync_order_keys (std::string const &);
+ void sync_order_keys (ARDOUR::RouteSortOrderKey);
private:
diff --git a/gtk2_ardour/editor_selection.cc b/gtk2_ardour/editor_selection.cc
index eb9ea5c721..7b08eaeaa6 100644
--- a/gtk2_ardour/editor_selection.cc
+++ b/gtk2_ardour/editor_selection.cc
@@ -779,7 +779,7 @@ Editor::set_selected_regionview_from_click (bool press, Selection::Operation op)
RouteTimeAxisView* closest = 0;
int distance = INT_MAX;
- int key = rtv->route()->order_key ("editor");
+ int key = rtv->route()->order_key (EditorSort);
for (RegionSelection::iterator x = selection->regions.begin(); x != selection->regions.end(); ++x) {
@@ -794,7 +794,7 @@ Editor::set_selected_regionview_from_click (bool press, Selection::Operation op)
if (result.second) {
/* newly added to already_in_selection */
- int d = artv->route()->order_key ("editor");
+ int d = artv->route()->order_key (EditorSort);
d -= key;
@@ -810,7 +810,7 @@ Editor::set_selected_regionview_from_click (bool press, Selection::Operation op)
/* now add all tracks between that one and this one */
- int okey = closest->route()->order_key ("editor");
+ int okey = closest->route()->order_key (EditorSort);
if (okey > key) {
swap (okey, key);
@@ -820,7 +820,7 @@ Editor::set_selected_regionview_from_click (bool press, Selection::Operation op)
RouteTimeAxisView* artv = dynamic_cast<RouteTimeAxisView*>(*x);
if (artv && artv != rtv) {
- int k = artv->route()->order_key ("editor");
+ int k = artv->route()->order_key (EditorSort);
if (k >= okey && k <= key) {
diff --git a/gtk2_ardour/group_tabs.cc b/gtk2_ardour/group_tabs.cc
index 9ce3b15046..d53b905846 100644
--- a/gtk2_ardour/group_tabs.cc
+++ b/gtk2_ardour/group_tabs.cc
@@ -435,24 +435,23 @@ GroupTabs::subgroup (RouteGroup* g, bool aux, Placement placement)
}
struct CollectSorter {
- CollectSorter (string const & key) : _key (key) {}
+ CollectSorter (RouteSortOrderKey key) : _key (key) {}
bool operator () (boost::shared_ptr<Route> a, boost::shared_ptr<Route> b) {
return a->order_key (_key) < b->order_key (_key);
}
- string _key;
+ RouteSortOrderKey _key;
};
struct OrderSorter {
- OrderSorter (string const & key) : _key (key) {}
+ OrderSorter (RouteSortOrderKey key) : _key (key) {}
bool operator() (boost::shared_ptr<Route> a, boost::shared_ptr<Route> b) {
- /* use of ">" forces the correct sort order */
return a->order_key (_key) < b->order_key (_key);
}
- string _key;
+ RouteSortOrderKey _key;
};
/** Collect all members of a RouteGroup so that they are together in the Editor or Mixer.
diff --git a/gtk2_ardour/group_tabs.h b/gtk2_ardour/group_tabs.h
index d8c488c70f..fa6a7bac53 100644
--- a/gtk2_ardour/group_tabs.h
+++ b/gtk2_ardour/group_tabs.h
@@ -92,7 +92,7 @@ private:
virtual void add_menu_items (Gtk::Menu *, ARDOUR::RouteGroup *) {}
virtual PBD::PropertyList default_properties () const = 0;
- virtual std::string order_key () const = 0;
+ virtual ARDOUR::RouteSortOrderKey order_key () const = 0;
virtual ARDOUR::RouteList selected_routes () const = 0;
virtual void sync_order_keys () = 0;
diff --git a/gtk2_ardour/mixer_group_tabs.cc b/gtk2_ardour/mixer_group_tabs.cc
index db586eed7e..60a625c96d 100644
--- a/gtk2_ardour/mixer_group_tabs.cc
+++ b/gtk2_ardour/mixer_group_tabs.cc
@@ -170,10 +170,10 @@ MixerGroupTabs::default_properties () const
return plist;
}
-string
+RouteSortOrderKey
MixerGroupTabs::order_key () const
{
- return X_("signal");
+ return MixerSort;
}
RouteList
@@ -192,5 +192,5 @@ MixerGroupTabs::selected_routes () const
void
MixerGroupTabs::sync_order_keys ()
{
- _mixer->sync_order_keys ("");
+ _mixer->sync_order_keys (UndefinedSort);
}
diff --git a/gtk2_ardour/mixer_group_tabs.h b/gtk2_ardour/mixer_group_tabs.h
index d8dd062280..0999dd9808 100644
--- a/gtk2_ardour/mixer_group_tabs.h
+++ b/gtk2_ardour/mixer_group_tabs.h
@@ -36,7 +36,7 @@ private:
}
PBD::PropertyList default_properties () const;
- std::string order_key () const;
+ ARDOUR::RouteSortOrderKey order_key () const;
ARDOUR::RouteList selected_routes () const;
void sync_order_keys ();
diff --git a/gtk2_ardour/mixer_ui.cc b/gtk2_ardour/mixer_ui.cc
index 8dd83ad771..a29717211e 100644
--- a/gtk2_ardour/mixer_ui.cc
+++ b/gtk2_ardour/mixer_ui.cc
@@ -307,13 +307,11 @@ Mixer_UI::hide_window (GdkEventAny *ev)
void
Mixer_UI::add_strip (RouteList& routes)
{
- ENSURE_GUI_THREAD (*this, &Mixer_UI::add_strip, routes)
-
MixerStrip* strip;
no_track_list_redisplay = true;
strip_redisplay_does_not_sync_order_keys = true;
-
+
for (RouteList::iterator x = routes.begin(); x != routes.end(); ++x) {
boost::shared_ptr<Route> route = (*x);
@@ -360,10 +358,6 @@ Mixer_UI::add_strip (RouteList& routes)
row[track_columns.route] = route;
row[track_columns.strip] = strip;
- if (route->order_key (N_("signal")) == -1) {
- route->set_order_key (N_("signal"), track_model->children().size()-1);
- }
-
route->PropertyChanged.connect (*this, invalidator (*this), boost::bind (&Mixer_UI::strip_property_changed, this, _1, strip), gui_context());
strip->WidthChanged.connect (sigc::mem_fun(*this, &Mixer_UI::strip_width_changed));
@@ -406,12 +400,12 @@ Mixer_UI::remove_strip (MixerStrip* strip)
}
void
-Mixer_UI::sync_order_keys (string const & src)
+Mixer_UI::sync_order_keys (RouteSortOrderKey src)
{
TreeModel::Children rows = track_model->children();
TreeModel::Children::iterator ri;
- if (src == N_("signal") || !_session || (_session->state_of_the_state() & (Session::Loading|Session::Deletion)) || rows.empty()) {
+ if (src == MixerSort || !_session || (_session->state_of_the_state() & (Session::Loading|Session::Deletion)) || rows.empty()) {
return;
}
@@ -423,7 +417,7 @@ Mixer_UI::sync_order_keys (string const & src)
for (ri = rows.begin(); ri != rows.end(); ++ri, ++order) {
boost::shared_ptr<Route> route = (*ri)[track_columns.route];
unsigned int old_key = order;
- unsigned int new_key = route->order_key (N_("signal"));
+ unsigned int new_key = route->order_key (MixerSort);
keys[new_key] = old_key;
@@ -802,7 +796,6 @@ void
Mixer_UI::track_list_reorder (const TreeModel::Path&, const TreeModel::iterator&, int* /*new_order*/)
{
strip_redisplay_does_not_sync_order_keys = true;
- _session->set_remote_control_ids();
redisplay_track_list ();
strip_redisplay_does_not_sync_order_keys = false;
}
@@ -812,7 +805,6 @@ Mixer_UI::track_list_change (const Gtk::TreeModel::Path&, const Gtk::TreeModel::
{
// never reset order keys because of a property change
strip_redisplay_does_not_reset_order_keys = true;
- _session->set_remote_control_ids();
redisplay_track_list ();
strip_redisplay_does_not_reset_order_keys = false;
}
@@ -822,7 +814,6 @@ Mixer_UI::track_list_delete (const Gtk::TreeModel::Path&)
{
/* this could require an order sync */
if (_session && !_session->deletion_in_progress()) {
- _session->set_remote_control_ids();
redisplay_track_list ();
}
}
@@ -832,13 +823,15 @@ Mixer_UI::redisplay_track_list ()
{
TreeModel::Children rows = track_model->children();
TreeModel::Children::iterator i;
- long order;
-
+ long regular_order = 0;
+ long hidden_order = 999999; // arbitary high number
+
if (no_track_list_redisplay) {
return;
}
- for (order = 0, i = rows.begin(); i != rows.end(); ++i, ++order) {
+ for (i = rows.begin(); i != rows.end(); ++i) {
+
MixerStrip* strip = (*i)[track_columns.strip];
if (strip == 0) {
@@ -846,10 +839,6 @@ Mixer_UI::redisplay_track_list ()
continue;
}
- if (!strip_redisplay_does_not_reset_order_keys) {
- strip->route()->set_order_key (N_("signal"), order);
- }
-
bool const visible = (*i)[track_columns.visible];
if (visible) {
@@ -859,16 +848,41 @@ Mixer_UI::redisplay_track_list ()
if (strip->route()->is_master() || strip->route()->is_monitor()) {
out_packer.reorder_child (*strip, -1);
+
+ if (!strip_redisplay_does_not_reset_order_keys) {
+ if (strip->route()->is_master()) {
+ strip->route()->set_order_key (MixerSort, Route::MasterBusRemoteControlID);
+ } else {
+ strip->route()->set_order_key (MixerSort, Route::MonitorBusRemoteControlID);
+ }
+ }
+
} else {
strip_packer.reorder_child (*strip, -1); /* put at end */
+
+ if (!strip_redisplay_does_not_reset_order_keys) {
+ strip->route()->set_order_key (MixerSort, regular_order++);
+ }
+
}
} else {
if (strip->route()->is_master() || strip->route()->is_monitor()) {
out_packer.pack_start (*strip, false, false);
+ if (!strip_redisplay_does_not_reset_order_keys) {
+ if (strip->route()->is_master()) {
+ strip->route()->set_order_key (MixerSort, Route::MasterBusRemoteControlID);
+ } else {
+ strip->route()->set_order_key (MixerSort, Route::MonitorBusRemoteControlID);
+ }
+ }
} else {
strip_packer.pack_start (*strip, false, false);
+
+ if (!strip_redisplay_does_not_reset_order_keys) {
+ strip->route()->set_order_key (MixerSort, regular_order++);
+ }
}
strip->set_packed (true);
}
@@ -884,12 +898,16 @@ Mixer_UI::redisplay_track_list ()
strip_packer.remove (*strip);
strip->set_packed (false);
}
+
+ if (!strip_redisplay_does_not_reset_order_keys) {
+ strip->route()->set_order_key (MixerSort, hidden_order++);
+ }
}
}
}
if (!strip_redisplay_does_not_reset_order_keys && !strip_redisplay_does_not_sync_order_keys) {
- _session->sync_order_keys (N_("signal"));
+ _session->sync_order_keys (MixerSort);
}
_group_tabs->set_dirty ();
@@ -924,8 +942,7 @@ Mixer_UI::strip_width_changed ()
struct SignalOrderRouteSorter {
bool operator() (boost::shared_ptr<Route> a, boost::shared_ptr<Route> b) {
- /* use of ">" forces the correct sort order */
- return a->order_key (N_("signal")) < b->order_key (N_("signal"));
+ return a->order_key (MixerSort) < b->order_key (MixerSort);
}
};
diff --git a/gtk2_ardour/mixer_ui.h b/gtk2_ardour/mixer_ui.h
index 08d7b6e487..f3d7845461 100644
--- a/gtk2_ardour/mixer_ui.h
+++ b/gtk2_ardour/mixer_ui.h
@@ -37,6 +37,7 @@
#include "pbd/signals.h"
#include "ardour/ardour.h"
+#include "ardour/types.h"
#include "ardour/session_handle.h"
#include "enums.h"
@@ -244,7 +245,7 @@ class Mixer_UI : public Gtk::Window, public PBD::ScopedConnectionList, public AR
Width _strip_width;
- void sync_order_keys (std::string const &);
+ void sync_order_keys (ARDOUR::RouteSortOrderKey);
bool strip_redisplay_does_not_reset_order_keys;
bool strip_redisplay_does_not_sync_order_keys;
bool ignore_sync;
diff --git a/gtk2_ardour/port_group.cc b/gtk2_ardour/port_group.cc
index 36b9ea1187..f313b2973f 100644
--- a/gtk2_ardour/port_group.cc
+++ b/gtk2_ardour/port_group.cc
@@ -312,7 +312,7 @@ struct RouteIOs {
class RouteIOsComparator {
public:
bool operator() (RouteIOs const & a, RouteIOs const & b) {
- return a.route->order_key (X_("editor")) < b.route->order_key (X_("editor"));
+ return a.route->order_key (EditorSort) < b.route->order_key (EditorSort);
}
};
diff --git a/gtk2_ardour/route_ui.cc b/gtk2_ardour/route_ui.cc
index 0da6bde4f0..b6c81717a2 100644
--- a/gtk2_ardour/route_ui.cc
+++ b/gtk2_ardour/route_ui.cc
@@ -1716,27 +1716,39 @@ void
RouteUI::open_remote_control_id_dialog ()
{
ArdourDialog dialog (_("Remote Control ID"));
+ SpinButton* spin = 0;
- uint32_t const limit = _session->ntracks() + _session->nbusses () + 4;
+ dialog.get_vbox()->set_border_width (18);
- HBox* hbox = manage (new HBox);
- hbox->set_spacing (6);
- hbox->pack_start (*manage (new Label (_("Remote control ID:"))));
- SpinButton* spin = manage (new SpinButton);
- spin->set_digits (0);
- spin->set_increments (1, 10);
- spin->set_range (0, limit);
- spin->set_value (_route->remote_control_id());
- hbox->pack_start (*spin);
- dialog.get_vbox()->pack_start (*hbox);
-
- dialog.add_button (Stock::CANCEL, RESPONSE_CANCEL);
- dialog.add_button (Stock::APPLY, RESPONSE_ACCEPT);
+ if (Config->get_remote_model() == UserOrdered) {
+ uint32_t const limit = _session->ntracks() + _session->nbusses () + 4;
+
+ HBox* hbox = manage (new HBox);
+ hbox->set_spacing (6);
+ hbox->pack_start (*manage (new Label (_("Remote control ID:"))));
+ spin = manage (new SpinButton);
+ spin->set_digits (0);
+ spin->set_increments (1, 10);
+ spin->set_range (0, limit);
+ spin->set_value (_route->remote_control_id());
+ hbox->pack_start (*spin);
+ dialog.get_vbox()->pack_start (*hbox);
+
+ dialog.add_button (Stock::CANCEL, RESPONSE_CANCEL);
+ dialog.add_button (Stock::APPLY, RESPONSE_ACCEPT);
+ } else {
+ Label* l = manage (new Label());
+ l->set_markup (string_compose (_("Remote Control IDs are currently determined by track/bus ordering in %1\n\n\n"
+ "<span size=\"small\" style=\"italic\">Use the User Interaction tab of the Preferences window if you want to change this</span>"),
+ (Config->get_remote_model() == MixerOrdered ? _("the mixer") : ("the editor"))));
+ dialog.get_vbox()->pack_start (*l);
+ dialog.add_button (Stock::OK, RESPONSE_CANCEL);
+ }
dialog.show_all ();
int const r = dialog.run ();
- if (r == RESPONSE_ACCEPT) {
+ if (r == RESPONSE_ACCEPT && spin) {
_route->set_remote_control_id (spin->get_value_as_int ());
}
}
diff --git a/libs/ardour/ardour/route.h b/libs/ardour/ardour/route.h
index d1248d8b03..a15937377e 100644
--- a/libs/ardour/ardour/route.h
+++ b/libs/ardour/ardour/route.h
@@ -101,8 +101,8 @@ class Route : public SessionObject, public Automatable, public RouteGroupMember,
bool set_name (const std::string& str);
static void set_name_in_state (XMLNode &, const std::string &);
- int32_t order_key (std::string const &) const;
- void set_order_key (std::string const &, int32_t);
+ int32_t order_key (RouteSortOrderKey) const;
+ void set_order_key (RouteSortOrderKey, int32_t);
bool is_hidden() const { return _flags & Hidden; }
bool is_master() const { return _flags & MasterOut; }
@@ -420,19 +420,19 @@ class Route : public SessionObject, public Automatable, public RouteGroupMember,
MonitorBusRemoteControlID = 319,
};
- void set_remote_control_id (uint32_t id, bool notify_class_listeners = true);
+ void set_remote_control_id (uint32_t id, bool notify_class_listeners = true);
uint32_t remote_control_id () const;
/* for things concerned about *this* route's RID */
PBD::Signal0<void> RemoteControlIDChanged;
- /* for things concerned about any route's RID changes */
+ /* for things concerned about *any* route's RID changes */
static PBD::Signal0<void> RemoteControlIDChange;
- void sync_order_keys (std::string const &);
- static PBD::Signal1<void,std::string const &> SyncOrderKeys;
+ void sync_order_keys (RouteSortOrderKey);
+ static PBD::Signal1<void,RouteSortOrderKey> SyncOrderKeys;
bool has_external_redirects() const;
@@ -518,7 +518,6 @@ class Route : public SessionObject, public Automatable, public RouteGroupMember,
void silence_unlocked (framecnt_t);
ChanCount processor_max_streams;
- uint32_t _remote_control_id;
uint32_t pans_required() const;
ChanCount n_process_buffers ();
@@ -534,8 +533,9 @@ class Route : public SessionObject, public Automatable, public RouteGroupMember,
static uint32_t order_key_cnt;
- typedef std::map<std::string, long> OrderKeys;
- OrderKeys order_keys;
+ typedef std::map<RouteSortOrderKey,int32_t> OrderKeys;
+ OrderKeys order_keys;
+ uint32_t* _remote_control_id;
void input_change_handler (IOChange, void *src);
void output_change_handler (IOChange, void *src);
diff --git a/libs/ardour/ardour/session.h b/libs/ardour/ardour/session.h
index 7f73d3ae77..eb84c0685e 100644
--- a/libs/ardour/ardour/session.h
+++ b/libs/ardour/ardour/session.h
@@ -235,7 +235,7 @@ class Session : public PBD::StatefulDestructible, public PBD::ScopedConnectionLi
bool operator() (boost::shared_ptr<Route>, boost::shared_ptr<Route> b);
};
- void sync_order_keys (std::string const &);
+ void sync_order_keys (RouteSortOrderKey);
template<class T> void foreach_route (T *obj, void (T::*func)(Route&));
template<class T> void foreach_route (T *obj, void (T::*func)(boost::shared_ptr<Route>));
@@ -464,8 +464,6 @@ class Session : public PBD::StatefulDestructible, public PBD::ScopedConnectionLi
void resort_routes ();
void resort_routes_using (boost::shared_ptr<RouteList>);
- void set_remote_control_ids();
-
AudioEngine & engine() { return _engine; }
AudioEngine const & engine () const { return _engine; }
@@ -1488,7 +1486,6 @@ class Session : public PBD::StatefulDestructible, public PBD::ScopedConnectionLi
XMLNode& get_control_protocol_state ();
void set_history_depth (uint32_t depth);
- void sync_order_keys ();
static bool _disable_all_loaded_plugins;
diff --git a/libs/ardour/ardour/types.h b/libs/ardour/ardour/types.h
index 6d05bdbbd8..713e35ebab 100644
--- a/libs/ardour/ardour/types.h
+++ b/libs/ardour/ardour/types.h
@@ -351,6 +351,12 @@ namespace ARDOUR {
PostFader
};
+ enum RouteSortOrderKey {
+ UndefinedSort,
+ EditorSort,
+ MixerSort
+ };
+
enum MonitorModel {
HardwareMonitoring, ///< JACK does monitoring
SoftwareMonitoring, ///< Ardour does monitoring
diff --git a/libs/ardour/enums.cc b/libs/ardour/enums.cc
index afe92ed5f7..1ef9047f57 100644
--- a/libs/ardour/enums.cc
+++ b/libs/ardour/enums.cc
@@ -89,6 +89,7 @@ setup_enum_writer ()
AutoState _AutoState;
AutoStyle _AutoStyle;
AutoConnectOption _AutoConnectOption;
+ RouteSortOrderKey _RouteSortOrderKey;
Session::StateOfTheState _Session_StateOfTheState;
Route::Flag _Route_Flag;
Source::Flag _Source_Flag;
@@ -397,6 +398,10 @@ setup_enum_writer ()
REGISTER_CLASS_ENUM (Route, MonitorOut);
REGISTER_BITS (_Route_Flag);
+ REGISTER_ENUM (MixerSort);
+ REGISTER_ENUM (EditorSort);
+ REGISTER_BITS (_RouteSortOrderKey);
+
REGISTER_CLASS_ENUM (Source, Writable);
REGISTER_CLASS_ENUM (Source, CanRename);
REGISTER_CLASS_ENUM (Source, Broadcast);
diff --git a/libs/ardour/route.cc b/libs/ardour/route.cc
index 83b1efce76..af30a112db 100644
--- a/libs/ardour/route.cc
+++ b/libs/ardour/route.cc
@@ -67,7 +67,7 @@ using namespace ARDOUR;
using namespace PBD;
uint32_t Route::order_key_cnt = 0;
-PBD::Signal1<void,string const&> Route::SyncOrderKeys;
+PBD::Signal1<void,RouteSortOrderKey> Route::SyncOrderKeys;
PBD::Signal0<void> Route::RemoteControlIDChange;
Route::Route (Session& sess, string name, Flag flg, DataType default_type)
@@ -99,14 +99,6 @@ Route::Route (Session& sess, string name, Flag flg, DataType default_type)
, _last_custom_meter_was_at_end (false)
{
processor_max_streams.reset();
- order_keys[N_("signal")] = order_key_cnt++;
-
- if (is_master()) {
- set_remote_control_id (MasterBusRemoteControlID);
- } else if (is_monitor()) {
- set_remote_control_id (MonitorBusRemoteControlID);
- }
-
}
int
@@ -203,11 +195,22 @@ Route::~Route ()
}
_processors.clear ();
+
+ delete _remote_control_id;
}
void
Route::set_remote_control_id (uint32_t id, bool notify_class_listeners)
{
+ if (Config->get_remote_model() != UserOrdered) {
+ return;
+ }
+
+ if (id < 1) {
+ error << _("Remote Control ID's start at one, not zero") << endmsg;
+ return;
+ }
+
/* force IDs for master/monitor busses and prevent
any other route from accidentally getting these IDs
(i.e. legacy sessions)
@@ -228,8 +231,11 @@ Route::set_remote_control_id (uint32_t id, bool notify_class_listeners)
id += MonitorBusRemoteControlID;
}
- if (id != _remote_control_id) {
- _remote_control_id = id;
+ if (id != remote_control_id()) {
+ if (!_remote_control_id) {
+ _remote_control_id = new uint32_t;
+ }
+ *_remote_control_id = id;
RemoteControlIDChanged ();
if (notify_class_listeners) {
RemoteControlIDChange ();
@@ -240,13 +246,27 @@ Route::set_remote_control_id (uint32_t id, bool notify_class_listeners)
uint32_t
Route::remote_control_id() const
{
- return _remote_control_id;
+ switch (Config->get_remote_model()) {
+ case MixerOrdered:
+ return order_key (MixerSort) + 1;
+ case EditorOrdered:
+ return order_key (EditorSort) + 1;
+ case UserOrdered:
+ if (_remote_control_id) {
+ return *_remote_control_id;
+ }
+ }
+
+ /* fall back to MixerSort as the default */
+
+ return order_key (MixerSort) + 1;
}
int32_t
-Route::order_key (std::string const & name) const
+Route::order_key (RouteSortOrderKey key) const
{
- OrderKeys::const_iterator i = order_keys.find (name);
+ OrderKeys::const_iterator i = order_keys.find (key);
+
if (i == order_keys.end()) {
return -1;
}
@@ -255,7 +275,7 @@ Route::order_key (std::string const & name) const
}
void
-Route::set_order_key (std::string const & name, int32_t n)
+Route::set_order_key (RouteSortOrderKey key, int32_t n)
{
bool changed = false;
@@ -265,16 +285,24 @@ Route::set_order_key (std::string const & name, int32_t n)
signal.
*/
- if (order_keys.find(name) == order_keys.end() || order_keys[name] != n) {
- order_keys[name] = n;
+ if (order_keys.find (key) == order_keys.end() || order_keys[key] != n) {
+ order_keys[key] = n;
changed = true;
}
if (Config->get_sync_all_route_ordering()) {
for (OrderKeys::iterator x = order_keys.begin(); x != order_keys.end(); ++x) {
- if (x->second != n) {
- x->second = n;
- changed = true;
+
+ /* we do not sync the signal order keys for mixer +
+ * monitor because they are considered "external" to
+ * the ordering of other routes.
+ */
+
+ if ((!is_master() && !is_monitor()) || x->first != MixerSort) {
+ if (x->second != n) {
+ x->second = n;
+ changed = true;
+ }
}
}
}
@@ -290,7 +318,7 @@ Route::set_order_key (std::string const & name, int32_t n)
* @param base Base key.
*/
void
-Route::sync_order_keys (std::string const & base)
+Route::sync_order_keys (RouteSortOrderKey base)
{
if (order_keys.empty()) {
return;
@@ -313,9 +341,17 @@ Route::sync_order_keys (std::string const & base)
bool changed = false;
for (; i != order_keys.end(); ++i) {
- if (i->second != key) {
- i->second = key;
- changed = true;
+
+ /* we do not sync the signal order keys for mixer +
+ * monitor because they are considered "external" to
+ * the ordering of other routes.
+ */
+
+ if ((!is_master() && !is_monitor()) || i->first != MixerSort) {
+ if (i->second != key) {
+ i->second = key;
+ changed = true;
+ }
}
}
@@ -1421,12 +1457,7 @@ Route::remove_processor (boost::shared_ptr<Processor> processor, ProcessorStream
boost::shared_ptr<IOProcessor> iop;
if ((iop = boost::dynamic_pointer_cast<IOProcessor> (*i)) != 0) {
- if (iop->input()) {
- iop->input()->disconnect (this);
- }
- if (iop->output()) {
- iop->output()->disconnect (this);
- }
+ iop->disconnect ();
}
i = _processors.erase (i);
@@ -1867,9 +1898,9 @@ Route::state(bool full_state)
OrderKeys::iterator x = order_keys.begin();
while (x != order_keys.end()) {
- order_string += string ((*x).first);
+ order_string += enum_2_string ((*x).first);
order_string += '=';
- snprintf (buf, sizeof(buf), "%ld", (*x).second);
+ snprintf (buf, sizeof(buf), "%" PRId32, (*x).second);
order_string += buf;
++x;
@@ -1895,10 +1926,12 @@ Route::state(bool full_state)
node->add_child_nocopy (_mute_control->get_state ());
node->add_child_nocopy (_mute_master->get_state ());
- XMLNode* remote_control_node = new XMLNode (X_("RemoteControl"));
- snprintf (buf, sizeof (buf), "%d", _remote_control_id);
- remote_control_node->add_property (X_("id"), buf);
- node->add_child_nocopy (*remote_control_node);
+ if (_remote_control_id) {
+ XMLNode* remote_control_node = new XMLNode (X_("RemoteControl"));
+ snprintf (buf, sizeof (buf), "%d", *_remote_control_id);
+ remote_control_node->add_property (X_("id"), buf);
+ node->add_child_nocopy (*remote_control_node);
+ }
if (_comment.length()) {
XMLNode *cmt = node->add_child ("Comment");
@@ -2089,7 +2122,18 @@ Route::set_state (const XMLNode& node, int version)
error << string_compose (_("badly formed order key string in state file! [%1] ... ignored."), remaining)
<< endmsg;
} else {
- set_order_key (remaining.substr (0, equal), n);
+ string keyname = remaining.substr (0, equal);
+ RouteSortOrderKey sk;
+
+ if (keyname == "signal") {
+ sk = MixerSort;
+ } else if (keyname == "editor") {
+ sk = EditorSort;
+ } else {
+ RouteSortOrderKey sk = (RouteSortOrderKey) string_2_enum (remaining.substr (0, equal), sk);
+ }
+
+ set_order_key (sk, n);
}
}
@@ -2285,7 +2329,18 @@ Route::set_state_2X (const XMLNode& node, int version)
error << string_compose (_("badly formed order key string in state file! [%1] ... ignored."), remaining)
<< endmsg;
} else {
- set_order_key (remaining.substr (0, equal), n);
+ string keyname = remaining.substr (0, equal);
+ RouteSortOrderKey sk;
+
+ if (keyname == "signal") {
+ sk = MixerSort;
+ } else if (keyname == "editor") {
+ sk = EditorSort;
+ } else {
+ RouteSortOrderKey sk = (RouteSortOrderKey) string_2_enum (remaining.substr (0, equal), sk);
+ }
+
+ set_order_key (sk, n);
}
}
diff --git a/libs/ardour/route_graph.cc b/libs/ardour/route_graph.cc
index fbf406fd92..13264ff9fa 100644
--- a/libs/ardour/route_graph.cc
+++ b/libs/ardour/route_graph.cc
@@ -170,7 +170,7 @@ struct RouteRecEnabledComparator
if (r1->record_enabled()) {
if (r2->record_enabled()) {
/* both rec-enabled, just use signal order */
- return r1->order_key(N_("signal")) < r2->order_key(N_("signal"));
+ return r1->order_key (MixerSort) < r2->order_key (MixerSort);
} else {
/* r1 rec-enabled, r2 not rec-enabled, run r2 early */
return false;
@@ -181,7 +181,7 @@ struct RouteRecEnabledComparator
return true;
} else {
/* neither rec-enabled, use signal order */
- return r1->order_key(N_("signal")) < r2->order_key(N_("signal"));
+ return r1->order_key (MixerSort) < r2->order_key (MixerSort);
}
}
}
diff --git a/libs/ardour/session.cc b/libs/ardour/session.cc
index f6d5b2bbd1..a38f6a129a 100644
--- a/libs/ardour/session.cc
+++ b/libs/ardour/session.cc
@@ -1515,7 +1515,7 @@ Session::resort_routes_using (boost::shared_ptr<RouteList> r)
DEBUG_TRACE (DEBUG::Graph, "Routes resorted, order follows:\n");
for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
DEBUG_TRACE (DEBUG::Graph, string_compose ("\t%1 signal order %2\n",
- (*i)->name(), (*i)->order_key ("signal")));
+ (*i)->name(), (*i)->order_key (MixerSort)));
}
#endif
@@ -1602,12 +1602,9 @@ Session::new_midi_track (const ChanCount& input, const ChanCount& output, boost:
string port;
RouteList new_routes;
list<boost::shared_ptr<MidiTrack> > ret;
- uint32_t control_id;
cerr << "Adding MIDI track with in = " << input << " out = " << output << endl;
- control_id = next_control_id ();
-
bool const use_number = (how_many != 1) || name_template.empty () || name_template == _("MIDI");
while (how_many) {
@@ -1650,7 +1647,10 @@ Session::new_midi_track (const ChanCount& input, const ChanCount& output, boost:
}
track->DiskstreamChanged.connect_same_thread (*this, boost::bind (&Session::resort_routes, this));
- track->set_remote_control_id (control_id);
+
+ if (Config->get_remote_model() == UserOrdered) {
+ track->set_remote_control_id (next_control_id());
+ }
new_routes.push_back (track);
ret.push_back (track);
@@ -1839,9 +1839,6 @@ Session::new_audio_track (int input_channels, int output_channels, TrackMode mod
string port;
RouteList new_routes;
list<boost::shared_ptr<AudioTrack> > ret;
- uint32_t control_id;
-
- control_id = next_control_id ();
bool const use_number = (how_many != 1) || name_template.empty () || name_template == _("Audio");
@@ -1892,8 +1889,9 @@ Session::new_audio_track (int input_channels, int output_channels, TrackMode mod
track->non_realtime_input_change();
track->DiskstreamChanged.connect_same_thread (*this, boost::bind (&Session::resort_routes, this));
- track->set_remote_control_id (control_id);
- ++control_id;
+ if (Config->get_remote_model() == UserOrdered) {
+ track->set_remote_control_id (next_control_id());
+ }
new_routes.push_back (track);
ret.push_back (track);
@@ -1921,33 +1919,6 @@ Session::new_audio_track (int input_channels, int output_channels, TrackMode mod
return ret;
}
-void
-Session::set_remote_control_ids ()
-{
- RemoteModel m = Config->get_remote_model();
- bool emit_signal = false;
-
- boost::shared_ptr<RouteList> r = routes.reader ();
-
- for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
- if (MixerOrdered == m) {
- int32_t order = (*i)->order_key(N_("signal"));
- (*i)->set_remote_control_id (order+1, false);
- emit_signal = true;
- } else if (EditorOrdered == m) {
- int32_t order = (*i)->order_key(N_("editor"));
- (*i)->set_remote_control_id (order+1, false);
- emit_signal = true;
- } else if (UserOrdered == m) {
- //do nothing ... only changes to remote id's are initiated by user
- }
- }
-
- if (emit_signal) {
- Route::RemoteControlIDChange();
- }
-}
-
/** Caller must not hold process lock.
* @param name_template string to use for the start of the name, or "" to use "Bus".
*/
@@ -1958,9 +1929,6 @@ Session::new_audio_route (int input_channels, int output_channels, RouteGroup* r
uint32_t bus_id = 0;
string port;
RouteList ret;
- uint32_t control_id;
-
- control_id = next_control_id ();
bool const use_number = (how_many != 1) || name_template.empty () || name_template == _("Bus");
@@ -2002,8 +1970,9 @@ Session::new_audio_route (int input_channels, int output_channels, RouteGroup* r
if (route_group) {
route_group->add (bus);
}
- bus->set_remote_control_id (control_id);
- ++control_id;
+ if (Config->get_remote_model() == UserOrdered) {
+ bus->set_remote_control_id (next_control_id());
+ }
bus->add_internal_return ();
@@ -2390,7 +2359,7 @@ Session::remove_route (boost::shared_ptr<Route> route)
route->drop_references ();
- sync_order_keys (N_("session"));
+ sync_order_keys (UndefinedSort);
Route::RemoteControlIDChange(); /* EMIT SIGNAL */
@@ -3481,7 +3450,7 @@ Session::RoutePublicOrderSorter::operator() (boost::shared_ptr<Route> a, boost::
if (b->is_monitor()) {
return false;
}
- return a->order_key(N_("signal")) < b->order_key(N_("signal"));
+ return a->order_key (MixerSort) < b->order_key (MixerSort);
}
bool
@@ -4182,7 +4151,7 @@ Session::add_automation_list(AutomationList *al)
}
void
-Session::sync_order_keys (std::string const & base)
+Session::sync_order_keys (RouteSortOrderKey base)
{
if (deletion_in_progress()) {
return;
@@ -4200,10 +4169,6 @@ Session::sync_order_keys (std::string const & base)
}
Route::SyncOrderKeys (base); // EMIT SIGNAL
-
- /* this might not do anything */
-
- set_remote_control_ids ();
}
/** @return true if there is at least one record-enabled track, otherwise false */
@@ -4781,7 +4746,32 @@ Session::session_name_is_legal (const string& path)
uint32_t
Session::next_control_id () const
{
- return ntracks() + nbusses() + 1;
+ int subtract = 0;
+
+ /* the master and monitor bus remote ID's occupy a different
+ * "namespace" than regular routes. their existence doesn't
+ * affect normal (low) numbered routes.
+ */
+
+ if (_master_out) {
+ subtract++;
+ }
+
+ if (_monitor_out) {
+ subtract++;
+ }
+
+ /* remote control IDs are based either on this
+ value, or signal order, which is zero-based. so we have
+ to ensure consistency of zero-based-ness for both
+ sources of the number.
+
+ we actually add 1 to the value to form an actual
+ remote control ID, which is 1-based.
+ */
+
+ cerr << "Next control ID will be " << ntracks() + (nbusses() - subtract) << endl;
+ return ntracks() + (nbusses() - subtract);
}
bool
diff --git a/libs/ardour/session_state.cc b/libs/ardour/session_state.cc
index 9ea202ee67..1509a757eb 100644
--- a/libs/ardour/session_state.cc
+++ b/libs/ardour/session_state.cc
@@ -3109,11 +3109,13 @@ Session::controllable_by_descriptor (const ControllableDescriptor& desc)
}
case ControllableDescriptor::RemoteControlID:
+ cerr << "RID " << desc.rid() << endl;
r = route_by_remote_id (desc.rid());
break;
}
if (!r) {
+ cerr << "no controllable with no route\n";
return c;
}
@@ -3196,11 +3198,15 @@ Session::controllable_by_descriptor (const ControllableDescriptor& desc)
--send;
}
+ cerr << "Look for send " << send << endl;
+
boost::shared_ptr<Processor> p = r->nth_send (send);
if (p) {
boost::shared_ptr<Send> s = boost::dynamic_pointer_cast<Send>(p);
boost::shared_ptr<Amp> a = s->amp();
+
+ cerr << " looked for send " << send << " got " << s << " amp = " << a << endl;
if (a) {
c = s->amp()->gain_control();
@@ -3551,14 +3557,12 @@ Session::config_changed (std::string p, bool ours)
} else {
switch_to_sync_source (config.get_sync_source());
}
- } else if (p == "remote-model") {
- set_remote_control_ids ();
} else if (p == "denormal-model") {
setup_fpu ();
} else if (p == "history-depth") {
set_history_depth (Config->get_history_depth());
} else if (p == "sync-all-route-ordering") {
- sync_order_keys ("session");
+ sync_order_keys (UndefinedSort);
} else if (p == "initial-program-change") {
if (MIDI::Manager::instance()->mmc()->output_port() && Config->get_initial_program_change() >= 0) {