#include "midi_mapper.h"
#include "midi_mapping.pb.h"
+#include "post_to_main_thread.h"
#include "ui_midi_mapping.h"
class QObject;
QSpinBox *source_spinner = spinners[source_bus_idx][field_number].spinner;
assert(spinners[source_bus_idx][field_number].group == this_spinner_group);
- if (source_spinner->value() != 0) {
+ if (source_spinner->value() != -1) {
spinner->setValue(source_spinner->value() + offset);
}
}
void MIDIMappingDialog::save_clicked()
{
+#if HAVE_CEF
+ // The native file dialog uses GTK+, which interferes with CEF's use of the GLib main loop.
+ QFileDialog::Option options(QFileDialog::DontUseNativeDialog);
+#else
+ QFileDialog::Option options;
+#endif
unique_ptr<MIDIMappingProto> new_mapping = construct_mapping_proto_from_ui();
QString filename = QFileDialog::getSaveFileName(this,
- "Save MIDI mapping", QString(), tr("Mapping files (*.midimapping)"));
+ "Save MIDI mapping", QString(), tr("Mapping files (*.midimapping)"), /*selectedFilter=*/nullptr, options);
if (!filename.endsWith(".midimapping")) {
filename += ".midimapping";
}
void MIDIMappingDialog::load_clicked()
{
+#if HAVE_CEF
+ // The native file dialog uses GTK+, which interferes with CEF's use of the GLib main loop.
+ QFileDialog::Option options(QFileDialog::DontUseNativeDialog);
+#else
+ QFileDialog::Option options;
+#endif
QString filename = QFileDialog::getOpenFileName(this,
- "Load MIDI mapping", QString(), tr("Mapping files (*.midimapping)"));
+ "Load MIDI mapping", QString(), tr("Mapping files (*.midimapping)"), /*selectedFilter=*/nullptr, options);
MIDIMappingProto new_mapping;
if (!load_midi_mapping_from_file(filename.toStdString(), &new_mapping)) {
QMessageBox box;
unique_ptr<MIDIMappingProto> mapping_proto(new MIDIMappingProto);
for (const InstantiatedSpinner &is : controller_spinners) {
const int val = is.spinner->value();
- if (val == 0) {
+ if (val == -1) {
continue;
}
}
for (const InstantiatedSpinner &is : button_spinners) {
const int val = is.spinner->value();
- if (val == 0) {
+ if (val == -1) {
continue;
}
}
for (const InstantiatedSpinner &is : light_spinners) {
const int val = is.spinner->value();
- if (val == 0) {
+ if (val == -1) {
continue;
}
for (unsigned bus_idx = 0; bus_idx < num_buses; ++bus_idx) {
QSpinBox *spinner = new QSpinBox(this);
- spinner->setRange(0, 127);
+ spinner->setRange(-1, 127);
spinner->setAutoFillBackground(true);
spinner->setSpecialValueText("\u200d"); // Zero-width joiner (ie., empty).
spinner->installEventFilter(this); // So we know when the focus changes.
void MIDIMappingDialog::fill_controls_from_mapping(const MIDIMappingProto &mapping_proto)
{
for (const InstantiatedSpinner &is : controller_spinners) {
- is.spinner->setValue(get_controller_mapping(mapping_proto, is.bus_idx, is.field_number, 0));
+ is.spinner->setValue(get_controller_mapping(mapping_proto, is.bus_idx, is.field_number, -1));
}
for (const InstantiatedSpinner &is : button_spinners) {
- is.spinner->setValue(get_button_mapping(mapping_proto, is.bus_idx, is.field_number, 0));
+ is.spinner->setValue(get_button_mapping(mapping_proto, is.bus_idx, is.field_number, -1));
}
for (const InstantiatedSpinner &is : light_spinners) {
- is.spinner->setValue(get_light_mapping(mapping_proto, is.bus_idx, is.field_number, 0));
+ is.spinner->setValue(get_light_mapping(mapping_proto, is.bus_idx, is.field_number, -1));
}
for (const InstantiatedComboBox &ic : bank_combo_boxes) {
ic.combo_box->setCurrentIndex(get_bank(mapping_proto, ic.field_number, -1) + 1);
void MIDIMappingDialog::controller_changed(unsigned controller)
{
- for (const InstantiatedSpinner &is : controller_spinners) {
- if (is.spinner->hasFocus()) {
- is.spinner->setValue(controller);
- is.spinner->selectAll();
+ post_to_main_thread([=]{
+ for (const InstantiatedSpinner &is : controller_spinners) {
+ if (is.spinner->hasFocus()) {
+ is.spinner->setValue(controller);
+ is.spinner->selectAll();
+ }
}
- }
+ });
}
void MIDIMappingDialog::note_on(unsigned note)
{
- for (const InstantiatedSpinner &is : button_spinners) {
- if (is.spinner->hasFocus()) {
- is.spinner->setValue(note);
- is.spinner->selectAll();
+ post_to_main_thread([=]{
+ for (const InstantiatedSpinner &is : button_spinners) {
+ if (is.spinner->hasFocus()) {
+ is.spinner->setValue(note);
+ is.spinner->selectAll();
+ }
}
- }
- for (const InstantiatedSpinner &is : light_spinners) {
- if (is.spinner->hasFocus()) {
- is.spinner->setValue(note);
- is.spinner->selectAll();
+ for (const InstantiatedSpinner &is : light_spinners) {
+ if (is.spinner->hasFocus()) {
+ is.spinner->setValue(note);
+ is.spinner->selectAll();
+ }
}
- }
+ });
}
pair<int, int> MIDIMappingDialog::guess_offset(unsigned bus_idx, MIDIMappingDialog::SpinnerGroup spinner_group)
spinner_group != this_spinner_group) {
continue;
}
- if (spinner->value() == 0) {
- if (source_spinner->value() != 0) {
+ if (spinner->value() == -1) {
+ if (source_spinner->value() != -1) {
// If the source value is e.g. 3, offset can't be less than -2 or larger than 124.
// Otherwise, we'd extrapolate values outside [1..127].
minimum_allowed_offset = max(minimum_allowed_offset, 1 - source_spinner->value());
}
continue;
}
- if (source_spinner->value() == 0) {
+ if (source_spinner->value() == -1) {
// The bus has a controller set that the source bus doesn't set.
return not_found;
}
spinner_group != this_spinner_group) {
continue;
}
- if (spinner->value() != 0) {
+ if (spinner->value() != -1) {
return false;
}
}