#include <gtkmm/stock.h>
#include <gtkmm/scale.h>
#include <gtkmm2ext/utils.h>
+#include <gtkmm2ext/slider_controller.h>
#include "pbd/fpu.h"
#include "midi++/manager.h"
#include "midi++/factory.h"
+#include "ardour/dB.h"
#include "ardour/rc_configuration.h"
#include "ardour/control_protocol_manager.h"
#include "control_protocol/control_protocol.h"
class MIDIPorts : public OptionEditorBox
{
public:
- MIDIPorts (RCConfiguration* c)
+ MIDIPorts (RCConfiguration* c, list<ComboOption<string>* > const & o)
: _rc_config (c),
- _add_port_button (Stock::ADD)
+ _add_port_button (Stock::ADD),
+ _port_combos (o)
{
_store = ListStore::create (_model);
_view.set_model (_store);
_box->pack_start (*h);
- Table* t = manage (new Table (2, 4));
- t->set_spacings (12);
-
- int n = 0;
- Label* l = manage (new Label (_("MTC:")));
- l->set_alignment (1, 0.5);
- t->attach (*l, 0, 1, n, n + 1, EXPAND | FILL, FILL);
- t->attach (_mtc_combo, 1, 2, n, n + 1, EXPAND | FILL, EXPAND | FILL);
- ++n;
-
- l = manage (new Label (_("MIDI clock:")));
- l->set_alignment (1, 0.5);
- t->attach (*l, 0, 1, n, n + 1, FILL, FILL);
- t->attach (_midi_clock_combo, 1, 2, n, n + 1, FILL, FILL);
- ++n;
-
- l = manage (new Label (_("MMC:")));
- l->set_alignment (1, 0.5);
- t->attach (*l, 0, 1, n, n + 1, FILL, FILL);
- t->attach (_mmc_combo, 1, 2, n, n + 1, FILL, FILL);
- ++n;
-
- l = manage (new Label (_("MIDI parameter control:")));
- l->set_alignment (1, 0.5);
- t->attach (*l, 0, 1, n, n + 1, FILL, FILL);
- t->attach (_mpc_combo, 1, 2, n, n + 1, FILL, FILL);
- ++n;
-
- _box->pack_start (*t, true, true);
-
ports_changed ();
_store->signal_row_changed().connect (mem_fun (*this, &MIDIPorts::model_changed));
_add_port_button.signal_clicked().connect (mem_fun (*this, &MIDIPorts::add_port_clicked));
- _mtc_combo.signal_changed().connect (mem_fun (*this, &MIDIPorts::mtc_combo_changed));
- _mmc_combo.signal_changed().connect (mem_fun (*this, &MIDIPorts::mmc_combo_changed));
- _mpc_combo.signal_changed().connect (mem_fun (*this, &MIDIPorts::mpc_combo_changed));
- _midi_clock_combo.signal_changed().connect (mem_fun (*this, &MIDIPorts::midi_clock_combo_changed));
- }
-
- void parameter_changed (string const & p)
- {
- if (p == "mtc-port-name") {
- _mtc_combo.set_active_text (_rc_config->get_mtc_port_name());
- } else if (p == "mmc-port-name") {
- _mmc_combo.set_active_text (_rc_config->get_mmc_port_name());
- } else if (p == "midi-port-name") {
- _mpc_combo.set_active_text (_rc_config->get_midi_port_name());
- } else if (p == "midi-clock-port-name") {
- _midi_clock_combo.set_active_text (_rc_config->get_midi_clock_port_name());
- }
}
- void set_state_from_config ()
- {
- parameter_changed ("mtc-port-name");
- parameter_changed ("mmc-port-name");
- parameter_changed ("midi-port-name");
- parameter_changed ("midi-clock-port-name");
- }
+ void parameter_changed (string const &) {}
+ void set_state_from_config () {}
- void mtc_combo_changed ()
- {
- _rc_config->set_mtc_port_name (_mtc_combo.get_active_text());
- }
-
- void mmc_combo_changed ()
- {
- _rc_config->set_mmc_port_name (_mmc_combo.get_active_text());
- }
-
- void mpc_combo_changed ()
- {
- _rc_config->set_midi_port_name (_mpc_combo.get_active_text());
- }
-
- void midi_clock_combo_changed ()
- {
- _rc_config->set_midi_clock_port_name (_midi_clock_combo.get_active_text());
- }
-
private:
- void model_changed (TreeModel::Path const & p, TreeModel::iterator const & i)
+ void model_changed (TreeModel::Path const &, TreeModel::iterator const & i)
{
TreeModel::Row r = *i;
}
if (port->input()) {
-
+
if (r[_model.online] == port->input()->offline()) {
port->input()->set_offline (!r[_model.online]);
}
if (r[_model.trace_output] != port->output()->tracing()) {
port->output()->trace (r[_model.trace_output], &cerr, string (port->name()) + _(" output: "));
}
-
- }
-
-
+ }
}
- void setup_ports_combo (ComboBoxText& c)
+ void setup_ports_combo (ComboOption<string>* c)
{
- c.clear_items ();
- MIDI::Manager::PortMap const & ports = MIDI::Manager::instance()->get_midi_ports ();
- for (MIDI::Manager::PortMap::const_iterator i = ports.begin(); i != ports.end(); ++i) {
- c.append_text (i->first);
+ c->clear ();
+ MIDI::Manager::PortList const & ports = MIDI::Manager::instance()->get_midi_ports ();
+ for (MIDI::Manager::PortList::const_iterator i = ports.begin(); i != ports.end(); ++i) {
+ c->add ((*i)->name(), (*i)->name());
}
- }
+ }
void ports_changed ()
{
/* XXX: why is this coming from here? */
- MIDI::Manager::PortMap const & ports = MIDI::Manager::instance()->get_midi_ports ();
+ MIDI::Manager::PortList const & ports = MIDI::Manager::instance()->get_midi_ports ();
_store->clear ();
- for (MIDI::Manager::PortMap::const_iterator i = ports.begin(); i != ports.end(); ++i) {
+ for (MIDI::Manager::PortList::const_iterator i = ports.begin(); i != ports.end(); ++i) {
TreeModel::Row r = *_store->append ();
- r[_model.name] = i->first;
+ r[_model.name] = (*i)->name();
- if (i->second->input()) {
- r[_model.online] = !i->second->input()->offline();
- i->second->input()->OfflineStatusChanged.connect (bind (mem_fun (*this, &MIDIPorts::port_offline_changed), i->second));
- r[_model.trace_input] = i->second->input()->tracing();
+ if ((*i)->input()) {
+ r[_model.online] = !(*i)->input()->offline();
+ (*i)->input()->OfflineStatusChanged.connect (bind (mem_fun (*this, &MIDIPorts::port_offline_changed), (*i)));
+ r[_model.trace_input] = (*i)->input()->tracing();
}
- if (i->second->output()) {
- r[_model.trace_output] = i->second->output()->tracing();
+ if ((*i)->output()) {
+ r[_model.trace_output] = (*i)->output()->tracing();
}
- r[_model.port] = i->second;
+ r[_model.port] = (*i);
}
- setup_ports_combo (_mtc_combo);
- setup_ports_combo (_midi_clock_combo);
- setup_ports_combo (_mmc_combo);
- setup_ports_combo (_mpc_combo);
+ for (list<ComboOption<string>* >::iterator i = _port_combos.begin(); i != _port_combos.end(); ++i) {
+ setup_ports_combo (*i);
+ }
}
void port_offline_changed (MIDI::Port* p)
dialog.set_position (WIN_POS_MOUSE);
dialog.show ();
-
+
int const r = dialog.run ();
switch (r) {
}
XMLNode node (X_("MIDI-port"));
-
+
node.add_property ("tag", dialog.port_name.get_text());
node.add_property ("device", X_("ardour")); // XXX this can't be right for all types
node.add_property ("type", MIDI::PortFactory::default_port_type());
node.add_property ("mode", smod);
-
+
if (MIDI::Manager::instance()->add_port (node) != 0) {
ports_changed ();
}
}
-
+
class MIDIModelColumns : public TreeModelColumnRecord
{
public:
ComboBoxText _midi_clock_combo;
ComboBoxText _mmc_combo;
ComboBoxText _mpc_combo;
+ list<ComboOption<string>* > _port_combos;
};
t->set_spacings (4);
Label* l = manage (new Label (_("Click audio file:")));
- l->set_alignment (1, 0.5);
+ l->set_alignment (0, 0.5);
t->attach (*l, 0, 1, 0, 1, FILL);
t->attach (_click_path_entry, 1, 2, 0, 1, FILL);
Button* b = manage (new Button (_("Browse...")));
t->attach (*b, 2, 3, 0, 1, FILL);
l = manage (new Label (_("Click emphasis audio file:")));
- l->set_alignment (1, 0.5);
+ l->set_alignment (0, 0.5);
t->attach (*l, 0, 1, 1, 2, FILL);
t->attach (_click_emphasis_path_entry, 1, 2, 1, 2, FILL);
b = manage (new Button (_("Browse...")));
_box->pack_start (*t, false, false);
}
-
+
void parameter_changed (string const & p)
{
if (p == "click-sound") {
parameter_changed ("click-emphasis-sound");
}
-private:
+private:
void click_browse_clicked ()
{
sfdb.show_all ();
sfdb.present ();
-
+
if (sfdb.run () == RESPONSE_OK) {
click_chosen (sfdb.get_filename());
}
sfdb.show_all ();
sfdb.present ();
-
+
if (sfdb.run () == RESPONSE_OK) {
click_emphasis_chosen (sfdb.get_filename());
}
{
_rc_config->set_saved_history_depth (_save_undo_spin.get_value_as_int ());
}
-
+
private:
RCConfiguration* _rc_config;
CheckButton _limit_undo_button;
guint modifier;
} modifiers[] = {
+ { "Unmodified", 0 },
+
#ifdef GTKOSX
/* Command = Meta
Option/Alt = Mod1
*/
-
{ "Shift", GDK_SHIFT_MASK },
{ "Command", GDK_META_MASK },
{ "Control", GDK_CONTROL_MASK },
{
public:
KeyboardOptions () :
- _delete_button_adjustment (3, 1, 5),
+ _delete_button_adjustment (3, 1, 12),
_delete_button_spin (_delete_button_adjustment),
_edit_button_adjustment (3, 1, 5),
_edit_button_spin (_edit_button_adjustment)
-
+
{
/* internationalize and prepare for use with combos */
Label* l = manage (new Label (_("Edit using:")));
l->set_name ("OptionsLabel");
- l->set_alignment (1.0, 0.5);
+ l->set_alignment (0, 0.5);
t->attach (*l, 0, 1, 0, 1, FILL | EXPAND, FILL);
t->attach (_edit_modifier_combo, 1, 2, 0, 1, FILL | EXPAND, FILL);
l = manage (new Label (_("Delete using:")));
l->set_name ("OptionsLabel");
- l->set_alignment (1.0, 0.5);
+ l->set_alignment (0, 0.5);
t->attach (*l, 0, 1, 1, 2, FILL | EXPAND, FILL);
t->attach (_delete_modifier_combo, 1, 2, 1, 2, FILL | EXPAND, FILL);
}
}
- l = manage (new Label (_("Ignore snap using:")));
+ l = manage (new Label (_("Toggle snap using:")));
l->set_name ("OptionsLabel");
- l->set_alignment (1.0, 0.5);
+ l->set_alignment (0, 0.5);
t->attach (*l, 0, 1, 2, 3, FILL | EXPAND, FILL);
t->attach (_snap_modifier_combo, 1, 2, 2, 3, FILL | EXPAND, FILL);
l = manage (new Label (_("Keyboard layout:")));
l->set_name ("OptionsLabel");
- l->set_alignment (1.0, 0.5);
+ l->set_alignment (0, 0.5);
t->attach (*l, 0, 1, 3, 4, FILL | EXPAND, FILL);
t->attach (_keyboard_layout_selector, 1, 2, 3, 4, FILL | EXPAND, FILL);
_box->pack_start (*t, false, false);
}
- void parameter_changed (string const & p)
+ void parameter_changed (string const &)
{
/* XXX: these aren't really config options... */
}
string const txt = _keyboard_layout_selector.get_active_text();
/* XXX: config...? for all this keyboard stuff */
-
+
for (map<string,string>::iterator i = Keyboard::binding_files.begin(); i != Keyboard::binding_files.end(); ++i) {
if (txt == i->first) {
if (Keyboard::load_keybindings (i->second)) {
void edit_modifier_chosen ()
{
string const txt = _edit_modifier_combo.get_active_text();
-
+
for (int i = 0; modifiers[i].name; ++i) {
if (txt == _(modifiers[i].name)) {
Keyboard::set_edit_modifier (modifiers[i].modifier);
void delete_modifier_chosen ()
{
string const txt = _delete_modifier_combo.get_active_text();
-
+
for (int i = 0; modifiers[i].name; ++i) {
if (txt == _(modifiers[i].name)) {
Keyboard::set_delete_modifier (modifiers[i].modifier);
}
}
}
-
+
void snap_modifier_chosen ()
{
string const txt = _snap_modifier_combo.get_active_text();
-
+
for (int i = 0; modifiers[i].name; ++i) {
if (txt == _(modifiers[i].name)) {
Keyboard::set_snap_modifier (modifiers[i].modifier);
{
Keyboard::set_edit_button (_edit_button_spin.get_value_as_int());
}
-
+
ComboBoxText _keyboard_layout_selector;
ComboBoxText _edit_modifier_combo;
ComboBoxText _delete_modifier_combo;
_dpi_adjustment (50, 50, 250, 1, 10),
_dpi_slider (_dpi_adjustment)
{
- _dpi_adjustment.set_value (_rc_config->get_font_scale ());
+ _dpi_adjustment.set_value (_rc_config->get_font_scale () / 1024);
Label* l = manage (new Label (_("Font scaling:")));
l->set_name ("OptionsLabel");
void parameter_changed (string const & p)
{
if (p == "font-scale") {
- _dpi_adjustment.set_value (_rc_config->get_font_scale() / 1024.);
+ _dpi_adjustment.set_value (_rc_config->get_font_scale() / 1024);
}
}
{
parameter_changed ("font-scale");
}
-
+
private:
-
+
void dpi_changed ()
{
_rc_config->set_font_scale ((long) floor (_dpi_adjustment.get_value() * 1024));
HScale _dpi_slider;
};
+class SoloMuteOptions : public OptionEditorBox
+{
+public:
+ SoloMuteOptions (RCConfiguration* c) :
+ _rc_config (c),
+ // 0.781787 is the value needed for gain to be set to 0.
+ _db_adjustment (0.781787, 0.0, 1.0, 0.01, 0.1)
+
+ {
+ if ((pix = ::get_icon ("fader_belt_h")) == 0) {
+ throw failed_constructor();
+ }
+
+ _db_slider = manage (new HSliderController (pix,
+ &_db_adjustment,
+ false));
+
+
+ parameter_changed ("solo-mute-gain");
+
+ Label* l = manage (new Label (_("Solo mute cut (dB):")));
+ l->set_name ("OptionsLabel");
+
+ HBox* h = manage (new HBox);
+ h->set_spacing (4);
+ h->pack_start (*l, false, false);
+ h->pack_start (*_db_slider, false, false);
+ h->pack_start (_db_display, false, false);
+
+ set_size_request_to_display_given_text (_db_display, "-99.0", 12, 12);
+
+ _box->pack_start (*h, false, false);
+
+ _db_adjustment.signal_value_changed().connect (mem_fun (*this, &SoloMuteOptions::db_changed));
+ }
+
+ void parameter_changed (string const & p)
+ {
+ if (p == "solo-mute-gain") {
+ gain_t val = _rc_config->get_solo_mute_gain();
+
+ _db_adjustment.set_value (gain_to_slider_position (val));
+
+ char buf[16];
+
+ if (val == 0.0) {
+ snprintf (buf, sizeof (buf), "-inf");
+ } else {
+ snprintf (buf, sizeof (buf), "%.2f", accurate_coefficient_to_dB (val));
+ }
+
+ _db_display.set_text (buf);
+ }
+ }
+
+ void set_state_from_config ()
+ {
+ parameter_changed ("solo-mute-gain");
+ }
+
+private:
+
+ void db_changed ()
+ {
+ _rc_config->set_solo_mute_gain (slider_position_to_gain (_db_adjustment.get_value()));
+ }
+
+ RCConfiguration* _rc_config;
+ Adjustment _db_adjustment;
+ Gtkmm2ext::HSliderController* _db_slider;
+ Glib::RefPtr<Gdk::Pixbuf> pix;
+ Entry _db_display;
+};
+
class ControlSurfacesOptions : public OptionEditorBox
{
void set_state_from_config ()
{
_store->clear ();
-
+
ControlProtocolManager& m = ControlProtocolManager::instance ();
for (list<ControlProtocolInfo*>::iterator i = m.control_protocol_info.begin(); i != m.control_protocol_info.end(); ++i) {
private:
- void model_changed (TreeModel::Path const & p, TreeModel::iterator const & i)
+ void model_changed (TreeModel::Path const &, TreeModel::iterator const & i)
{
TreeModel::Row r = *i;
class ControlSurfacesModelColumns : public TreeModelColumnRecord
{
public:
-
+
ControlSurfacesModelColumns ()
{
add (name);
/* MISC */
add_option (_("Misc"), new OptionEditorHeading (_("Metering")));
-
+
ComboOption<float>* mht = new ComboOption<float> (
"meter-hold",
_("Meter hold time"),
mht->add (MeterHoldShort, _("short"));
mht->add (MeterHoldMedium, _("medium"));
mht->add (MeterHoldLong, _("long"));
-
+
add_option (_("Misc"), mht);
ComboOption<float>* mfo = new ComboOption<float> (
add_option (_("Misc"), mfo);
add_option (_("Misc"), new OptionEditorHeading (_("Undo")));
-
+
add_option (_("Misc"), new UndoOptions (_rc_config));
add_option (_("Misc"), new OptionEditorHeading (_("Misc")));
-
+
#ifndef GTKOSX
/* font scaling does nothing with GDK/Quartz */
add_option (_("Misc"), new FontScalingOptions (_rc_config));
-#endif
+#endif
add_option (_("Misc"),
new BoolOption (
mem_fun (*_rc_config, &RCConfiguration::get_verify_remove_last_capture),
mem_fun (*_rc_config, &RCConfiguration::set_verify_remove_last_capture)
));
-
+
add_option (_("Misc"),
new BoolOption (
"periodic-safety-backups",
wfs->add (Logarithmic, _("logarithmic"));
add_option (_("Editor"), wfs);
-
+
ComboOption<WaveformShape>* wfsh = new ComboOption<WaveformShape> (
"waveform-shape",
_("Waveform shape"),
add_option (_("Audio"), new OptionEditorHeading (_("Solo")));
- ComboOption<SoloModel>* sm = new ComboOption<SoloModel> (
- "solo-model",
- _("Solo"),
- mem_fun (*_rc_config, &RCConfiguration::get_solo_model),
- mem_fun (*_rc_config, &RCConfiguration::set_solo_model)
+
+ add_option (_("Audio"),
+ new BoolOption (
+ "solo-control-is-listen-control",
+ _("Solo controls are Listen controls"),
+ mem_fun (*_rc_config, &RCConfiguration::get_solo_control_is_listen_control),
+ mem_fun (*_rc_config, &RCConfiguration::set_solo_control_is_listen_control)
+ ));
+
+ ComboOption<ListenPosition>* lp = new ComboOption<ListenPosition> (
+ "listen-position",
+ _("Listen Position"),
+ mem_fun (*_rc_config, &RCConfiguration::get_listen_position),
+ mem_fun (*_rc_config, &RCConfiguration::set_listen_position)
);
- sm->add (SoloInPlace, _("in place"));
- sm->add (SoloBus, _("via bus"));
+ lp->add (AfterFaderListen, _("after-fader listen"));
+ lp->add (PreFaderListen, _("pre-fader listen"));
- add_option (_("Audio"), sm);
+ add_option (_("Audio"), lp);
+ add_option (_("Audio"), new SoloMuteOptions (_rc_config));
add_option (_("Audio"),
new BoolOption (
mem_fun (*_rc_config, &RCConfiguration::get_denormal_model),
mem_fun (*_rc_config, &RCConfiguration::set_denormal_model)
);
-
+
dm->add (DenormalNone, _("no processor handling"));
-
+
FPU fpu;
-
+
if (fpu.has_flush_to_zero()) {
dm->add (DenormalFTZ, _("use FlushToZero"));
}
-
+
if (fpu.has_denormals_are_zero()) {
dm->add (DenormalDAZ, _("use DenormalsAreZero"));
}
-
+
if (fpu.has_flush_to_zero() && fpu.has_denormals_are_zero()) {
dm->add (DenormalFTZDAZ, _("use FlushToZero and DenormalsAreZerO"));
}
-
+
add_option (_("Audio"), dm);
add_option (_("Audio"), new OptionEditorHeading (_("Plugins")));
/* MIDI CONTROL */
- add_option (_("MIDI control"), new MIDIPorts (_rc_config));
+ list<ComboOption<string>* > midi_combos;
+
+ midi_combos.push_back (new ComboOption<string> (
+ "mtc-port-name",
+ _("Send/Receive MTC via"),
+ mem_fun (*_rc_config, &RCConfiguration::get_mtc_port_name),
+ mem_fun (*_rc_config, &RCConfiguration::set_mtc_port_name)
+ ));
+
+ midi_combos.push_back (new ComboOption<string> (
+ "midi-clock-port-name",
+ _("Send/Receive MIDI clock via"),
+ mem_fun (*_rc_config, &RCConfiguration::get_midi_clock_port_name),
+ mem_fun (*_rc_config, &RCConfiguration::set_midi_clock_port_name)
+ ));
+
+ midi_combos.push_back (new ComboOption<string> (
+ "mmc-port-name",
+ _("Send/Receive MMC via"),
+ mem_fun (*_rc_config, &RCConfiguration::get_mmc_port_name),
+ mem_fun (*_rc_config, &RCConfiguration::set_mmc_port_name)
+ ));
+
+ midi_combos.push_back (new ComboOption<string> (
+ "midi-port-name",
+ _("Send/Receive MIDI parameter control via"),
+ mem_fun (*_rc_config, &RCConfiguration::get_midi_port_name),
+ mem_fun (*_rc_config, &RCConfiguration::set_midi_port_name)
+ ));
+
+ add_option (_("MIDI control"), new MIDIPorts (_rc_config, midi_combos));
+
+ for (list<ComboOption<string>* >::iterator i = midi_combos.begin(); i != midi_combos.end(); ++i) {
+ add_option (_("MIDI control"), *i);
+ }
+
+ add_option (_("MIDI control"),
+ new BoolOption (
+ "mmc-control",
+ _("Obey MIDI Machine Control commands"),
+ mem_fun (*_rc_config, &RCConfiguration::get_mmc_control),
+ mem_fun (*_rc_config, &RCConfiguration::set_mmc_control)
+ ));
+
+
+ add_option (_("MIDI control"),
+ new BoolOption (
+ "send-mmc",
+ _("Send MIDI Machine Control commands"),
+ mem_fun (*_rc_config, &RCConfiguration::get_send_mmc),
+ mem_fun (*_rc_config, &RCConfiguration::set_send_mmc)
+ ));
+
+ add_option (_("MIDI control"),
+ new BoolOption (
+ "midi-feedback",
+ _("Send MIDI control feedback"),
+ mem_fun (*_rc_config, &RCConfiguration::get_midi_feedback),
+ mem_fun (*_rc_config, &RCConfiguration::set_midi_feedback)
+ ));
add_option (_("MIDI control"),
new SpinOption<uint8_t> (