#include "ardour/amp.h"
#include "ardour/debug.h"
+#include "ardour/audio_track.h"
#include "ardour/midi_track.h"
#include "ardour/plugin_manager.h"
#include "ardour/route_group.h"
-#include "ardour/route_sorters.h"
#include "ardour/session.h"
+#include "ardour/vca.h"
+#include "ardour/vca_manager.h"
#include "keyboard.h"
#include "mixer_ui.h"
#include "mixer_group_tabs.h"
#include "timers.h"
#include "ui_config.h"
+#include "vca_master_strip.h"
#include "i18n.h"
, _maximised (false)
, _show_mixer_list (true)
{
- Route::SyncOrderKeys.connect (*this, invalidator (*this), boost::bind (&Mixer_UI::sync_treeview_from_order_keys, this), gui_context());
+ Stripable::PresentationInfoChange.connect (*this, invalidator (*this), boost::bind (&Mixer_UI::sync_treeview_from_presentation_info, this), gui_context());
/* bindings was already set in MixerActor constructor */
scroller_base.add_events (Gdk::BUTTON_PRESS_MASK|Gdk::BUTTON_RELEASE_MASK);
scroller_base.set_name ("MixerWindow");
scroller_base.signal_button_release_event().connect (sigc::mem_fun(*this, &Mixer_UI::strip_scroller_button_release));
+
+ /* set up drag-n-drop */
+ vector<TargetEntry> target_table;
+ target_table.push_back (TargetEntry ("PluginFavoritePtr"));
+ scroller_base.drag_dest_set (target_table);
+ scroller_base.signal_drag_data_received().connect (sigc::mem_fun(*this, &Mixer_UI::scroller_drag_data_received));
+
// add as last item of strip packer
strip_packer.pack_end (scroller_base, true, true);
group_display_frame.set_shadow_type (Gtk::SHADOW_IN);
group_display_frame.add (group_display_vbox);
+
+ list<TargetEntry> target_list;
+ target_list.push_back (TargetEntry ("PluginPresetPtr"));
+
favorite_plugins_model = PluginTreeStore::create (favorite_plugins_columns);
favorite_plugins_display.set_model (favorite_plugins_model);
favorite_plugins_display.append_column (_("Favorite Plugins"), favorite_plugins_columns.name);
favorite_plugins_display.set_headers_visible (true);
favorite_plugins_display.set_rules_hint (true);
favorite_plugins_display.set_can_focus (false);
- favorite_plugins_display.add_object_drag (favorite_plugins_columns.plugin.index(), "PluginPresetPtr");
+ favorite_plugins_display.add_object_drag (favorite_plugins_columns.plugin.index(), "PluginFavoritePtr");
favorite_plugins_display.set_drag_column (favorite_plugins_columns.name.index());
+ favorite_plugins_display.add_drop_targets (target_list);
favorite_plugins_display.signal_row_activated().connect (sigc::mem_fun (*this, &Mixer_UI::plugin_row_activated));
favorite_plugins_display.signal_button_press_event().connect (sigc::mem_fun (*this, &Mixer_UI::plugin_row_button_press), false);
favorite_plugins_display.signal_drop.connect (sigc::mem_fun (*this, &Mixer_UI::plugin_drop));
list_vpacker.pack_start (rhs_pane2, true, true);
- global_hpacker.pack_start (scroller, true, true);
+ vca_scroller.add (vca_packer);
+ vca_scroller.set_policy (Gtk::POLICY_ALWAYS, Gtk::POLICY_AUTOMATIC);
+
+ inner_pane.pack1 (scroller);
+ inner_pane.pack2 (vca_scroller);
+
+ global_hpacker.pack_start (inner_pane, true, true);
global_hpacker.pack_start (out_packer, false, false);
list_hpane.pack1(list_vpacker, false, true);
static_cast<Gtk::Paned*> (&rhs_pane2)));
list_hpane.signal_size_allocate().connect (sigc::bind (sigc::mem_fun(*this, &Mixer_UI::pane_allocation_handler),
static_cast<Gtk::Paned*> (&list_hpane)));
+ inner_pane.signal_size_allocate().connect (sigc::bind (sigc::mem_fun(*this, &Mixer_UI::pane_allocation_handler),
+ static_cast<Gtk::Paned*> (&inner_pane)));
_content.pack_start (list_hpane, true, true);
rhs_pane1.show();
rhs_pane2.show();
strip_packer.show();
+ inner_pane.show ();
+ vca_scroller.show();
+ vca_packer.show();
out_packer.show();
list_hpane.show();
group_display.show();
for (ri = rows.begin(); ri != rows.end(); ++ri) {
ms = (*ri)[track_columns.strip];
+ if (!ms) {
+ continue;
+ }
ms->set_width_enum (ms->get_width_enum (), ms->width_owner());
/* Fix visibility of mixer strip stuff */
ms->parameter_changed (X_("mixer-element-visibility"));
scroller_base.grab_focus ();
}
+void
+Mixer_UI::add_masters (VCAList& vcas)
+{
+ for (VCAList::iterator v = vcas.begin(); v != vcas.end(); ++v) {
+
+ VCAMasterStrip* vms = new VCAMasterStrip (_session, *v);
+
+ TreeModel::Row row = *(track_model->append());
+ row[track_columns.text] = (*v)->name();
+ row[track_columns.visible] = true;
+ row[track_columns.vca] = vms;
+
+ vms->CatchDeletion.connect (*this, invalidator (*this), boost::bind (&Mixer_UI::remove_master, this, _1), gui_context());
+ }
+
+ redisplay_track_list ();
+}
+
+void
+Mixer_UI::remove_master (VCAMasterStrip* vms)
+{
+ if (_session && _session->deletion_in_progress()) {
+ /* its all being taken care of */
+ return;
+ }
+
+ TreeModel::Children rows = track_model->children();
+ TreeModel::Children::iterator ri;
+
+ for (ri = rows.begin(); ri != rows.end(); ++ri) {
+ if ((*ri)[track_columns.vca] == vms) {
+ PBD::Unwinder<bool> uw (_route_deletion_in_progress, true);
+ track_model->erase (ri);
+ break;
+ }
+ }
+}
+
void
Mixer_UI::add_strips (RouteList& routes)
{
- bool from_scratch = track_model->children().size() == 0;
Gtk::TreeModel::Children::iterator insert_iter = track_model->children().end();
+ uint32_t nroutes = 0;
for (Gtk::TreeModel::Children::iterator it = track_model->children().begin(); it != track_model->children().end(); ++it) {
boost::shared_ptr<Route> r = (*it)[track_columns.route];
- if (r->order_key() == (routes.front()->order_key() + routes.size())) {
+ if (!r) {
+ continue;
+ }
+
+ nroutes++;
+
+ if (r->presentation_info().group_order() == (routes.front()->presentation_info().group_order() + routes.size())) {
insert_iter = it;
break;
}
}
- if(!from_scratch) {
+ if (nroutes) {
_selection.clear_routes ();
}
row[track_columns.visible] = strip->route()->is_master() ? true : strip->marked_for_display();
row[track_columns.route] = route;
row[track_columns.strip] = strip;
+ row[track_columns.vca] = 0;
- if (!from_scratch) {
+ if (nroutes != 0) {
_selection.add (strip);
}
no_track_list_redisplay = false;
track_display.set_model (track_model);
- sync_order_keys_from_treeview ();
+ sync_presentation_info_from_treeview ();
redisplay_track_list ();
}
}
}
+void
+Mixer_UI::select_strip (MixerStrip& ms, bool add)
+{
+ if (add) {
+ _selection.add (&ms);
+ } else {
+ _selection.set (&ms);
+ }
+}
+
void
Mixer_UI::select_none ()
{
}
void
-Mixer_UI::reset_remote_control_ids ()
+Mixer_UI::sync_presentation_info_from_treeview ()
{
- if (Config->get_remote_model() == UserOrdered || !_session || _session->deletion_in_progress()) {
- return;
- }
-
- TreeModel::Children rows = track_model->children();
-
- if (rows.empty()) {
- return;
- }
-
- DEBUG_TRACE (DEBUG::OrderKeys, "mixer resets remote control ids after remote model change\n");
-
- TreeModel::Children::iterator ri;
- bool rid_change = false;
- uint32_t rid = 1;
- uint32_t invisible_key = UINT32_MAX;
-
- for (ri = rows.begin(); ri != rows.end(); ++ri) {
-
- /* skip two special values */
-
- if (rid == Route::MasterBusRemoteControlID) {
- rid++;
- }
-
- if (rid == Route::MonitorBusRemoteControlID) {
- rid++;
- }
-
- boost::shared_ptr<Route> route = (*ri)[track_columns.route];
- bool visible = (*ri)[track_columns.visible];
-
- if (!route->is_master() && !route->is_monitor()) {
-
- uint32_t new_rid = (visible ? rid : invisible_key--);
-
- if (new_rid != route->remote_control_id()) {
- route->set_remote_control_id_explicit (new_rid);
- rid_change = true;
- }
-
- if (visible) {
- rid++;
- }
- }
- }
-
- if (rid_change) {
- /* tell the world that we changed the remote control IDs */
- _session->notify_remote_id_change ();
- }
-}
-
-void
-Mixer_UI::sync_order_keys_from_treeview ()
-{
- if (ignore_reorder || !_session || _session->deletion_in_progress()) {
+ if (ignore_reorder || !_session || _session->deletion_in_progress() || (Config->get_remote_model() != MixerOrdered)) {
return;
}
DEBUG_TRACE (DEBUG::OrderKeys, "mixer sync order keys from model\n");
TreeModel::Children::iterator ri;
- bool changed = false;
- bool rid_change = false;
+ bool change = false;
uint32_t order = 0;
- uint32_t rid = 1;
- uint32_t invisible_key = UINT32_MAX;
for (ri = rows.begin(); ri != rows.end(); ++ri) {
boost::shared_ptr<Route> route = (*ri)[track_columns.route];
bool visible = (*ri)[track_columns.visible];
- uint32_t old_key = route->order_key ();
- if (order != old_key) {
- route->set_order_key (order);
- changed = true;
+ if (!route) {
+ continue;
}
- if ((Config->get_remote_model() == MixerOrdered) && !route->is_master() && !route->is_monitor()) {
-
- uint32_t new_rid = (visible ? rid : invisible_key--);
+ if (route->presentation_info().special()) {
+ continue;
+ }
- if (new_rid != route->remote_control_id()) {
- route->set_remote_control_id_explicit (new_rid);
- rid_change = true;
- }
+ if (!visible) {
+ route->presentation_info().set_flag (PresentationInfo::Hidden);
+ } else {
+ route->presentation_info().unset_flag (PresentationInfo::Hidden);
+ }
- if (visible) {
- rid++;
- }
+ DEBUG_TRACE (DEBUG::OrderKeys, string_compose ("route %1 old order %2 new order %3\n", route->name(), route->presentation_info().group_order(), order));
+ if (order != route->presentation_info().group_order()) {
+ route->set_presentation_group_order_explicit (order);
+ change = true;
}
++order;
}
- if (changed) {
- /* tell everyone that we changed the mixer sort keys */
- _session->sync_order_keys ();
- }
-
- if (rid_change) {
- /* tell the world that we changed the remote control IDs */
- _session->notify_remote_id_change ();
+ if (change) {
+ DEBUG_TRACE (DEBUG::OrderKeys, "... notify PI change from mixer GUI\n");
+ _session->notify_presentation_info_change ();
}
}
void
-Mixer_UI::sync_treeview_from_order_keys ()
+Mixer_UI::sync_treeview_from_presentation_info ()
{
if (!_session || _session->deletion_in_progress()) {
return;
return;
}
- OrderKeySortedRoutes sorted_routes;
+ OrderingKeys sorted;
+ uint32_t vca_cnt = 0;
+ uint32_t max_route_order_key = 0;
+
+ /* count number of Routes in track_model (there may be some odd reason
+ why this is not the same as the number in the session, but here we
+ care about the track model.
+ */
+
+ for (TreeModel::Children::iterator ri = rows.begin(); ri != rows.end(); ++ri) {
+ boost::shared_ptr<Route> route = (*ri)[track_columns.route];
+ if (route) {
+ max_route_order_key = max (route->presentation_info().group_order(), max_route_order_key);
+ }
+ }
for (TreeModel::Children::iterator ri = rows.begin(); ri != rows.end(); ++ri, ++old_order) {
boost::shared_ptr<Route> route = (*ri)[track_columns.route];
- sorted_routes.push_back (RoutePlusOrderKey (route, old_order, route->order_key ()));
+ if (!route) {
+ /* VCAs need to sort after all routes. We don't display
+ * them in the same place (March 2016), but we don't
+ * want them intermixed in the track_model
+ */
+ sorted.push_back (OrderKeys (old_order, max_route_order_key + ++vca_cnt));
+ } else {
+ sorted.push_back (OrderKeys (old_order, route->presentation_info().group_order()));
+ }
}
SortByNewDisplayOrder cmp;
- sort (sorted_routes.begin(), sorted_routes.end(), cmp);
- neworder.assign (sorted_routes.size(), 0);
+ sort (sorted.begin(), sorted.end(), cmp);
+ neworder.assign (sorted.size(), 0);
uint32_t n = 0;
- for (OrderKeySortedRoutes::iterator sr = sorted_routes.begin(); sr != sorted_routes.end(); ++sr, ++n) {
+ for (OrderingKeys::iterator sr = sorted.begin(); sr != sorted.end(); ++sr, ++n) {
neworder[n] = sr->old_display_order;
changed = true;
}
- DEBUG_TRACE (DEBUG::OrderKeys, string_compose ("MIXER change order for %1 from %2 to %3\n",
- sr->route->name(), sr->old_display_order, n));
+ DEBUG_TRACE (DEBUG::OrderKeys, string_compose ("MIXER change order from %1 to %2\n",
+ sr->old_display_order, n));
}
if (changed) {
_session->DirtyChanged.connect (_session_connections, invalidator (*this), boost::bind (&Mixer_UI::update_title, this), gui_context());
_session->StateSaved.connect (_session_connections, invalidator (*this), boost::bind (&Mixer_UI::update_title, this), gui_context());
+ _session->vca_manager().VCAAdded.connect (_session_connections, invalidator (*this), boost::bind (&Mixer_UI::add_masters, this, _1), gui_context());
+
Config->ParameterChanged.connect (*this, invalidator (*this), boost::bind (&Mixer_UI::parameter_changed, this, _1), gui_context ());
route_groups_changed ();
for (i = rows.begin(); i != rows.end(); ++i) {
MixerStrip *strip = (*i)[track_columns.strip];
- (*i)[track_columns.visible] = strip->marked_for_display ();
+ if (strip) {
+ (*i)[track_columns.visible] = strip->marked_for_display ();
+ }
}
- /* force route order keys catch up with visibility changes
+ /* force presentation catch up with visibility changes
*/
- sync_order_keys_from_treeview ();
+ sync_presentation_info_from_treeview ();
}
redisplay_track_list ();
TreeModel::Row row = (*i);
MixerStrip* strip = row[track_columns.strip];
- if (strip == 0) {
+ if (!strip) {
continue;
}
TreeModel::Row row = (*i);
MixerStrip* strip = row[track_columns.strip];
- if (strip == 0) {
+ if (!strip) {
continue;
}
Mixer_UI::track_list_reorder (const TreeModel::Path&, const TreeModel::iterator&, int* /*new_order*/)
{
DEBUG_TRACE (DEBUG::OrderKeys, "mixer UI treeview reordered\n");
- sync_order_keys_from_treeview ();
+ sync_presentation_info_from_treeview ();
}
void
*/
DEBUG_TRACE (DEBUG::OrderKeys, "mixer UI treeview row deleted\n");
- sync_order_keys_from_treeview ();
+ sync_presentation_info_from_treeview ();
if (_route_deletion_in_progress) {
redisplay_track_list ();
{
TreeModel::Children rows = track_model->children();
TreeModel::Children::iterator i;
+ uint32_t n_masters = 0;
if (no_track_list_redisplay) {
return;
}
+ container_clear (vca_packer);
+
for (i = rows.begin(); i != rows.end(); ++i) {
+ VCAMasterStrip* vms = (*i)[track_columns.vca];
+
+ if (vms) {
+ vca_packer.pack_start (*vms, false, false);
+ vms->show ();
+ n_masters++;
+ continue;
+ }
+
MixerStrip* strip = (*i)[track_columns.strip];
- if (strip == 0) {
+ if (!strip) {
/* we're in the middle of changing a row, don't worry */
continue;
}
}
}
+ /* update visibility of VCA assign buttons */
+
+ if (n_masters == 0) {
+ UIConfiguration::instance().set_mixer_strip_visibility (VisibilityGroup::remove_element (UIConfiguration::instance().get_mixer_strip_visibility(), X_("VCA")));
+ vca_scroller.hide ();
+ } else {
+ UIConfiguration::instance().set_mixer_strip_visibility (VisibilityGroup::add_element (UIConfiguration::instance().get_mixer_strip_visibility(), X_("VCA")));
+ vca_scroller.show ();
+ }
+
_group_tabs->set_dirty ();
}
}
+struct PresentationInfoRouteSorter
+{
+ bool operator() (boost::shared_ptr<Route> a, boost::shared_ptr<Route> b) {
+ return a->presentation_info().global_order () < b->presentation_info().global_order ();
+ }
+};
+
void
Mixer_UI::initial_track_display ()
{
boost::shared_ptr<RouteList> routes = _session->get_routes();
RouteList copy (*routes);
- ARDOUR::SignalOrderRouteSorter sorter;
+ PresentationInfoRouteSorter sorter;
copy.sort (sorter);
Unwinder<bool> uw2 (ignore_reorder, true);
track_model->clear ();
+ VCAList vcas = _session->vca_manager().vcas();
+ add_masters (vcas);
add_strips (copy);
}
- _session->sync_order_keys ();
-
redisplay_track_list ();
}
//if user wants to show the pane, we should make sure that it is wide enough to be visible
int width = list_hpane.get_position();
- if (width < 40)
+ if (width < 40) {
list_hpane.set_position(40);
+ }
} else {
list_vpacker.hide ();
}
return false;
}
+void
+Mixer_UI::scroller_drag_data_received (const Glib::RefPtr<Gdk::DragContext>& context, int x, int y, const Gtk::SelectionData& data, guint info, guint time)
+{
+ printf ("Mixer_UI::scroller_drag_data_received\n");
+ if (data.get_target() != "PluginFavoritePtr") {
+ context->drag_finish (false, false, time);
+ return;
+ }
+
+ const void * d = data.get_data();
+ const Gtkmm2ext::DnDTreeView<ARDOUR::PluginPresetPtr>* tv = reinterpret_cast<const Gtkmm2ext::DnDTreeView<ARDOUR::PluginPresetPtr>*>(d);
+
+ PluginPresetList nfos;
+ TreeView* source;
+ tv->get_object_drag_data (nfos, &source);
+
+ Route::ProcessorList pl;
+ bool ok = false;
+
+ for (list<PluginPresetPtr>::const_iterator i = nfos.begin(); i != nfos.end(); ++i) {
+ PluginPresetPtr ppp = (*i);
+ PluginInfoPtr pip = ppp->_pip;
+ if (!pip->is_instrument ()) {
+ continue;
+ }
+ ARDOUR_UI::instance()->session_add_midi_track (NULL, 1, _("MIDI"), Config->get_strict_io (), pip, ppp->_preset.valid ? &ppp->_preset : 0);
+ ok = true;
+ }
+
+ context->drag_finish (ok, false, time);
+}
+
void
Mixer_UI::set_strip_width (Width w, bool save)
{
node->add_child_nocopy (Tabbable::get_state());
- snprintf(buf,sizeof(buf), "%d",gtk_paned_get_position (const_cast<GtkPaned*>(static_cast<const Paned*>(&rhs_pane1)->gobj())));
- node->add_property(X_("mixer_rhs_pane1_pos"), string(buf));
- snprintf(buf,sizeof(buf), "%d",gtk_paned_get_position (const_cast<GtkPaned*>(static_cast<const Paned*>(&list_hpane)->gobj())));
- node->add_property(X_("mixer_list_hpane_pos"), string(buf));
+ snprintf(buf,sizeof(buf), "%f", paned_position_as_fraction (rhs_pane1, true));
+ node->add_property(X_("mixer-rhs-pane1-pos"), string(buf));
+ snprintf(buf,sizeof(buf), "%f", paned_position_as_fraction (rhs_pane2, true));
+ node->add_property(X_("mixer-rhs_pane2-pos"), string(buf));
+ snprintf(buf,sizeof(buf), "%f", paned_position_as_fraction (list_hpane, false));
+ node->add_property(X_("mixer-list-hpane-pos"), string(buf));
+ snprintf(buf,sizeof(buf), "%f", paned_position_as_fraction (inner_pane, false));
+ node->add_property(X_("mixer-inner-pane-pos"), string(buf));
node->add_property ("narrow-strips", _strip_width == Narrow ? "yes" : "no");
node->add_property ("show-mixer", _visible ? "yes" : "no");
}
void
-Mixer_UI::pane_allocation_handler (Allocation&, Gtk::Paned* which)
+Mixer_UI::pane_allocation_handler (Allocation& allocation, Gtk::Paned* which)
{
- int pos;
- XMLProperty const * prop = 0;
- XMLNode* node = ARDOUR_UI::instance()->mixer_settings();
- XMLNode* geometry;
- int height;
- static int32_t done[3] = { 0, 0, 0 };
-
- height = default_height;
-
- if ((geometry = find_named_node (*node, "geometry")) != 0) {
+ float pos;
+ XMLProperty* prop = 0;
+ XMLNode* geometry = ARDOUR_UI::instance()->mixer_settings();
+ int height = default_height;
+ static bool done[4] = { false, false, false, false };
- if ((prop = geometry->property ("y_size")) == 0) {
- prop = geometry->property ("y-size");
- }
- if (prop) {
- height = atoi (prop->value());
- }
- }
+ /* Gtk::Paned behaves very oddly and rather undesirably. Setting the
+ * position is a crapshoot if you time it incorrectly with the overall
+ * sizing of the Paned. For example, if you might retrieve the size with
+ * ::get_position() and then later call ::set_position() on a Paned at
+ * a time when its allocation is different than it was when you retrieved
+ * the position. The position will be interpreted as the size of the
+ * first (top or left) child widget. If packing/size allocation later
+ * resizes the Paned to a (final) smaller size, the position will be
+ * used in ways that mean that the Paned ends up NOT in the same state
+ * that it was in when you originally saved the position.
+ *
+ * Concrete example: Paned is 800 pixels wide, position is 400
+ * (halfway). Save position as 400. During program restart, set
+ * position to 400, before Paned has been allocated any space. Paned
+ * ends up initially sized to 1200 pixels. Position is now 1/3 of the
+ * way across/down. Subsequent resizes will leave the position 1/3 of
+ * the way across, rather than leaving it as a fixed pixel
+ * position. Eventually, the Paned ends up 800 pixels wide/high again,
+ * but the position is now 267, not 400.
+ *
+ * So ...
+ *
+ * We deal with this by using two strategies:
+ *
+ * 1) only set the position if the allocated size of the Paned is at
+ * least as big as it needs to be for the position to make sense.
+ *
+ * 2) in recent versions of Ardour, save the position as a fraction,
+ * and restore it using that fraction.
+ *
+ * So, we will only call ::set_position() AFTER the Paned is of a
+ * sensible size, and then in addition, we will set the position in a
+ * way that will be maintained as/when/if the Paned is resized.
+ *
+ * Once we've called ::set_position() on a Paned, we don't do it
+ * again.
+ */
if (which == static_cast<Gtk::Paned*> (&rhs_pane1)) {
if (!geometry || (prop = geometry->property("mixer-rhs-pane1-pos")) == 0) {
pos = height / 3;
} else {
- pos = atoi (prop->value());
+ pos = atof (prop->value());
}
- if ((done[0] = GTK_WIDGET(rhs_pane1.gobj())->allocation.height > pos)) {
- rhs_pane1.set_position (pos);
+ if (pos > 1.0f) {
+ /* older versions of Ardour stored absolute position */
+ if ((done[0] = (allocation.get_height() > pos))) {
+ rhs_pane1.set_position (pos);
+ }
+ } else {
+ if ((done[0] = (allocation.get_height() > 1.0/pos))) {
+ paned_set_position_as_fraction (rhs_pane1, pos, true);
+ }
}
+ }
+
+ if (which == static_cast<Gtk::Paned*> (&rhs_pane2)) {
- } else if (which == static_cast<Gtk::Paned*> (&rhs_pane2)) {
if (done[1]) {
return;
}
if (!geometry || (prop = geometry->property("mixer-rhs-pane2-pos")) == 0) {
pos = 2 * height / 3;
} else {
- pos = atoi (prop->value());
+ pos = atof (prop->value());
}
- if ((done[1] = GTK_WIDGET(rhs_pane2.gobj())->allocation.height > pos)) {
- rhs_pane2.set_position (pos);
+ if (pos > 1.0f) {
+ /* older versions of Ardour stored absolute position */
+ if ((done[1] = (allocation.get_height() > pos))) {
+ rhs_pane2.set_position (pos);
+ }
+ } else {
+ if ((done[1] = (allocation.get_height() > 1.0/pos))) {
+ paned_set_position_as_fraction (rhs_pane2, pos, true);
+ }
}
- } else if (which == static_cast<Gtk::Paned*> (&list_hpane)) {
+ }
+
+ if (which == static_cast<Gtk::Paned*> (&list_hpane)) {
if (done[2]) {
return;
if (!geometry || (prop = geometry->property("mixer-list-hpane-pos")) == 0) {
pos = std::max ((float)100, rintf ((float) 125 * UIConfiguration::instance().get_ui_scale()));
} else {
- pos = max (36, atoi (prop->value ()));
+ pos = max (0.1, atof (prop->value ()));
+ }
+
+ if (pos > 1.0f) {
+ if ((done[2] = (allocation.get_width() > pos))) {
+ list_hpane.set_position (pos);
+ }
+ } else {
+ if ((done[2] = (allocation.get_width() > 1.0/pos))) {
+ paned_set_position_as_fraction (list_hpane, pos, false);
+ }
+ }
+ }
+
+ if (which == static_cast<Gtk::Paned*> (&inner_pane)) {
+
+ if (done[3]) {
+ return;
+ }
+
+ if (!geometry || (prop = geometry->property("mixer-inner-pane-pos")) == 0) {
+ pos = std::max ((float)100, rintf ((float) 125 * UIConfiguration::instance().get_ui_scale()));
+ } else {
+ pos = max (0.1, atof (prop->value ()));
}
- if ((done[2] = GTK_WIDGET(list_hpane.gobj())->allocation.width > pos)) {
- list_hpane.set_position (pos);
+ if (pos > 1.0f) {
+ /* older versions of Ardour stored absolute position */
+ if ((done[3] = (allocation.get_width() > pos))) {
+ inner_pane.set_position (pos);
+ }
+ } else {
+ if ((done[3] = (allocation.get_width() > 1.0/pos))) {
+ paned_set_position_as_fraction (inner_pane, pos, false);
+ }
}
}
}
+
void
Mixer_UI::scroll_left ()
{
for (list<MixerStrip*>::iterator i = strips.begin(); i != strips.end(); ++i) {
(*i)->set_width_enum (s ? Narrow : Wide, this);
}
- } else if (p == "remote-model") {
- reset_remote_control_ids ();
} else if (p == "use-monitor-bus") {
if (_session && !_session->monitor_out()) {
monitor_section_detached ();
ARDOUR_UI::instance()->add_route ();
}
-
void
Mixer_UI::update_title ()
{
manager.set_status (ppp->_pip->type, ppp->_pip->unique_id, status);
manager.save_statuses ();
}
+
+void
+Mixer_UI::do_vca_assign (boost::shared_ptr<VCA> vca)
+{
+ /* call protected MixerActor:: method */
+ vca_assign (vca);
+}
+
+void
+Mixer_UI::do_vca_unassign (boost::shared_ptr<VCA> vca)
+{
+ /* call protected MixerActor:: method */
+ vca_unassign (vca);
+}