#include <glibmm/threads.h>
#include <gtkmm2ext/gtk_ui.h>
+#include <gtkmm2ext/keyboard.h>
#include <gtkmm2ext/utils.h>
#include <gtkmm2ext/tearoff.h>
#include <gtkmm2ext/window_title.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"
/* bindings was already set in MixerActor constructor */
_content.set_data ("ardour-bindings", bindings);
-
+
scroller.set_can_default (true);
// set_default (scroller);
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);
- global_hpacker.pack_start (out_packer, false, false, 0);
+ global_hpacker.pack_start (vca_packer, false, false);
+ global_hpacker.pack_start (out_packer, false, false);
list_hpane.pack1(list_vpacker, false, true);
list_hpane.pack2(global_hpacker, true, false);
rhs_pane1.show();
rhs_pane2.show();
strip_packer.show();
+ vca_packer.show();
out_packer.show();
list_hpane.show();
group_display.show();
PublicEditor::instance().get_selection().TracksChanged.connect (sigc::mem_fun (*this, &Mixer_UI::follow_editor_selection));
}
-void
Gtk::Window*
Mixer_UI::use_own_window (bool and_fill_it)
{
win->set_name ("MixerWindow");
ARDOUR_UI::instance()->setup_toplevel_window (*win, _("Mixer"), this);
win->signal_scroll_event().connect (sigc::mem_fun (*this, &Mixer_UI::on_scroll_event), false);
+ win->signal_event().connect (sigc::bind (sigc::ptr_fun (&Keyboard::catch_user_event_for_pre_dialog_focus), win));
win->set_data ("ardour-bindings", bindings);
update_title ();
}
return win;
}
+void
Mixer_UI::show_window ()
{
- if (_parent_window) {
- _parent_window->present ();
- }
-
- if (!_visible) { /* was hidden, update status */
-
- set_window_pos_and_size ();
+ Tabbable::show_window ();
- /* show/hide group tabs as required */
- parameter_changed ("show-group-tabs");
+ /* show/hide group tabs as required */
+ parameter_changed ("show-group-tabs");
- /* now reset each strips width so the right widgets are shown */
- MixerStrip* ms;
+ /* now reset each strips width so the right widgets are shown */
+ MixerStrip* ms;
- TreeModel::Children rows = track_model->children();
- TreeModel::Children::iterator ri;
+ TreeModel::Children rows = track_model->children();
+ TreeModel::Children::iterator ri;
- for (ri = rows.begin(); ri != rows.end(); ++ri) {
- ms = (*ri)[track_columns.strip];
- ms->set_width_enum (ms->get_width_enum (), ms->width_owner());
- /* Fix visibility of mixer strip stuff */
- ms->parameter_changed (X_("mixer-element-visibility"));
+ for (ri = rows.begin(); ri != rows.end(); ++ri) {
+ ms = (*ri)[track_columns.strip];
+ if (!ms) {
+ continue;
}
- }
-
- if (!_parent_window) {
- /* not in its own window, just switch main tabs to show mixer */
- int pagenum = ARDOUR_UI::instance()->tabs().page_num (*this);
- ARDOUR_UI::instance()->tabs().set_current_page (pagenum);
+ ms->set_width_enum (ms->get_width_enum (), ms->width_owner());
+ /* Fix visibility of mixer strip stuff */
+ ms->parameter_changed (X_("mixer-element-visibility"));
}
/* force focus into main area */
scroller_base.grab_focus ();
- _visible = true;
}
-bool
-Mixer_UI::hide_window (GdkEventAny *ev)
+void
+Mixer_UI::add_masters (VCAList& vcas)
{
- if (_parent_window) {
- /* unpack Mixer_UI from parent, put it back in the main tabbed
- * notebook
- */
-
- get_window_pos_and_size ();
+ cerr << "VCA added\n";
- get_parent()->remove (*this);
- ARDOUR_UI::instance()->tabs().insert_page (*this, _("Mixer"), 1);
- ARDOUR_UI::instance()->tabs().set_tab_detachable (*this);
- ARDOUR_UI::instance()->tabs().set_current_page (0);
+ for (VCAList::iterator v = vcas.begin(); v != vcas.end(); ++v) {
- show_all ();
+ VCAMasterStrip* vms = new VCAMasterStrip (_session, *v);
- delete_when_idle (_parent_window);
- _parent_window = 0;
+ TreeModel::Row row = *(track_model->append());
+ row[track_columns.text] = (*v)->name();
+ row[track_columns.visible] = true;
+ row[track_columns.vca] = vms;
}
- ARDOUR_UI::instance()->tabs().set_current_page (0);
-
- _visible = false;
+ redisplay_track_list ();
+}
- return true;
+void
+Mixer_UI::remove_master (VCAMasterStrip* vms)
+{
}
void
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) {
+ continue;
+ }
+
if (r->order_key() == (routes.front()->order_key() + routes.size())) {
insert_iter = it;
break;
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) {
_selection.add (strip);
strip->signal_button_release_event().connect (sigc::bind (sigc::mem_fun(*this, &Mixer_UI::strip_button_release_event), strip));
}
- } catch (...) {
+ } catch (const std::exception& e) {
+ error << string_compose (_("Error adding GUI elements for new tracks/busses %1"), e.what()) << endmsg;
}
no_track_list_redisplay = false;
boost::shared_ptr<Route> route = (*ri)[track_columns.route];
bool visible = (*ri)[track_columns.visible];
+ if (!route) {
+ continue;
+ }
+
if (!route->is_master() && !route->is_monitor()) {
uint32_t new_rid = (visible ? rid : invisible_key--);
boost::shared_ptr<Route> route = (*ri)[track_columns.route];
bool visible = (*ri)[track_columns.visible];
+ if (!route) {
+ continue;
+ }
+
uint32_t old_key = route->order_key ();
if (order != old_key) {
for (TreeModel::Children::iterator ri = rows.begin(); ri != rows.end(); ++ri, ++old_order) {
boost::shared_ptr<Route> route = (*ri)[track_columns.route];
+ if (!route) {
+ continue;
+ }
sorted_routes.push_back (RoutePlusOrderKey (route, old_order, route->order_key ()));
}
_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
}
}
-void
-Mixer_UI::show_window ()
-{
- Tabbable::show_window ();
-
- /* show/hide group tabs as required */
- parameter_changed ("show-group-tabs");
-
- /* now reset each strips width so the right widgets are shown */
- MixerStrip* ms;
-
- TreeModel::Children rows = track_model->children();
- TreeModel::Children::iterator ri;
-
- for (ri = rows.begin(); ri != rows.end(); ++ri) {
- ms = (*ri)[track_columns.strip];
- ms->set_width_enum (ms->get_width_enum (), ms->width_owner());
- /* Fix visibility of mixer strip stuff */
- ms->parameter_changed (X_("mixer-element-visibility"));
- }
-
- /* force focus into main area */
- scroller_base.grab_focus ();
-}
-
void
Mixer_UI::set_all_strips_visibility (bool yn)
{
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;
}
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 ();
+ cerr << "Packed vca into vca_packer\n";
+ 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;
}
{
_group_tabs->set_dirty ();
-#ifdef GTKOSX
+#ifdef __APPLE__
TreeModel::Children rows = track_model->children();
TreeModel::Children::iterator i;
long order;
if (Keyboard::is_edit_event (ev)) {
if (group) {
// edit_route_group (group);
-#ifdef GTKOSX
+#ifdef __APPLE__
group_display.queue_draw();
#endif
return true;
{
bool visible = (*iter)[group_columns.visible];
(*iter)[group_columns.visible] = !visible;
-#ifdef GTKOSX
+#ifdef __APPLE__
group_display.queue_draw();
#endif
return true;
using namespace Menu_Helpers;
if (Keyboard::is_context_menu_event (ev)) {
- // ARDOUR_UI::instance()->add_route (this);
+ ARDOUR_UI::instance()->add_route ();
return true;
}
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)
{
int
Mixer_UI::set_state (const XMLNode& node, int version)
{
- const XMLProperty* prop;
- XMLNode* geometry;
-
- m_width = default_width;
- m_height = default_height;
- m_root_x = 1;
- m_root_y = 1;
-
- if ((geometry = find_named_node (node, "geometry")) != 0) {
-
- /* if there's a geometry node, we have our own window */
+ XMLProperty const * prop;
- create_own_window ();
- Gtk::Notebook* notebook = (Gtk::Notebook*) _parent_window->get_child();
- Gtk::Widget* parent = get_parent();
- if (parent) {
- ((Gtk::Container*)parent)->remove (*this);
- }
- notebook->append_page (*this, _("Mixer"));
-
- XMLProperty* prop;
-
- if ((prop = geometry->property("x_size")) == 0) {
- prop = geometry->property ("x-size");
- }
- if (prop) {
- m_width = atoi(prop->value());
- }
- if ((prop = geometry->property("y_size")) == 0) {
- prop = geometry->property ("y-size");
- }
- if (prop) {
- m_height = atoi(prop->value());
- }
-
- if ((prop = geometry->property ("x_pos")) == 0) {
- prop = geometry->property ("x-pos");
- }
- if (prop) {
- m_root_x = atoi (prop->value());
-
- }
- if ((prop = geometry->property ("y_pos")) == 0) {
- prop = geometry->property ("y-pos");
- }
- if (prop) {
- m_root_y = atoi (prop->value());
- }
- }
+ Tabbable::set_state (node, version);
if ((prop = node.property ("narrow-strips"))) {
if (string_is_affirmative (prop->value())) {
node->add_property ("show-mixer-list", _show_mixer_list ? "yes" : "no");
node->add_property ("maximised", _maximised ? "yes" : "no");
+ store_current_favorite_order ();
+ XMLNode* plugin_order = new XMLNode ("PluginOrder");
+ int cnt = 0;
+ for (PluginInfoList::const_iterator i = favorite_order.begin(); i != favorite_order.end(); ++i, ++cnt) {
+ XMLNode* p = new XMLNode ("PluginInfo");
+ p->add_property ("sort", cnt);
+ p->add_property ("unique-id", (*i)->unique_id);
+ if (favorite_ui_state.find ((*i)->unique_id) != favorite_ui_state.end ()) {
+ p->add_property ("expanded", favorite_ui_state[(*i)->unique_id]);
+ }
+ plugin_order->add_child_nocopy (*p);
+ }
+ node->add_child_nocopy (*plugin_order);
+
return *node;
}
Mixer_UI::pane_allocation_handler (Allocation&, Gtk::Paned* which)
{
int pos;
- XMLProperty* prop = 0;
+ XMLProperty const * prop = 0;
XMLNode* node = ARDOUR_UI::instance()->mixer_settings();
XMLNode* geometry;
int height;
void
Mixer_UI::new_track_or_bus ()
{
- // ARDOUR_UI::instance()->add_route (this);
+ ARDOUR_UI::instance()->add_route ();
}
n = "*" + n;
}
- if (own_window()) {
- WindowTitle title (n);
- title += S_("Window|Mixer");
- title += Glib::get_application_name ();
- own_window()->set_title (title.get_string());
- }
+ WindowTitle title (n);
+ title += S_("Window|Mixer");
+ title += Glib::get_application_name ();
+ own_window()->set_title (title.get_string());
} else {
- if (own_window()) {
- WindowTitle title (S_("Window|Mixer"));
- title += Glib::get_application_name ();
- own_window()->set_title (title.get_string());
- }
+ WindowTitle title (S_("Window|Mixer"));
+ title += Glib::get_application_name ();
+ own_window()->set_title (title.get_string());
}
}
return;
}
- Gtk::Window* win = (Gtk::Window*) get_toplevel();
-
- if (win) {
- win->fullscreen ();
- _maximised = true;
+ if (_maximised) {
+ return;
}
_window->fullscreen ();
return;
}
- Gtk::Window* win = (Gtk::Window*) get_toplevel();
-
- if (win) {
- win->unfullscreen();
- _maximised = false;
+ if (!_maximised) {
+ return;
}
own_window()->unfullscreen();
refiller (plugs, mgr.au_plugin_info ());
#endif
refiller (plugs, mgr.ladspa_plugin_info ());
+ refiller (plugs, mgr.lua_plugin_info ());
store_current_favorite_order ();
case AddPostFader:
{
int idx = 0;
+ int pos = 0;
for (;;++idx) {
boost::shared_ptr<Processor> np = rt->nth_processor (idx);
- if (!np || boost::dynamic_pointer_cast<Amp> (np)) {
+ if (!np) {
+ break;
+ }
+ if (!np->display_to_user()) {
+ continue;
+ }
+ if (boost::dynamic_pointer_cast<Amp> (np) && // Fader, not Trim
+ boost::dynamic_pointer_cast<Amp> (np)->gain_control()->parameter().type() == GainAutomation) {
break;
}
+ ++pos;
}
- rt->add_processor_by_index (processor, ++idx, &err, Config->get_new_plugins_active ());
+ rt->add_processor_by_index (processor, ++pos, &err, Config->get_new_plugins_active ());
}
break;
case AddBottom: