From 7ccbc0ca73055bafba07d8a5a785ca3bf1c8cb74 Mon Sep 17 00:00:00 2001 From: Len Ovens Date: Wed, 24 Aug 2016 10:07:21 -0700 Subject: [PATCH] OSC: Add preset loading to OSC GUI --- libs/surfaces/osc/osc_gui.cc | 494 +++++++++++++++++++++++++---------- libs/surfaces/osc/osc_gui.h | 152 +++++++++++ osc/TTC2.preset | 10 + osc/wscript | 16 ++ wscript | 1 + 5 files changed, 533 insertions(+), 140 deletions(-) create mode 100644 libs/surfaces/osc/osc_gui.h create mode 100644 osc/TTC2.preset create mode 100644 osc/wscript diff --git a/libs/surfaces/osc/osc_gui.cc b/libs/surfaces/osc/osc_gui.cc index f30c626c50..72f15a6d96 100644 --- a/libs/surfaces/osc/osc_gui.cc +++ b/libs/surfaces/osc/osc_gui.cc @@ -21,6 +21,10 @@ #include #include #include +#include +//#include + +#include "pbd/file_utils.h" #include #include @@ -34,110 +38,15 @@ #include "gtkmm2ext/gui_thread.h" #include "gtkmm2ext/utils.h" +#include "ardour/filesystem_paths.h" + #include "osc.h" +#include "osc_gui.h" #include "pbd/i18n.h" -namespace ArdourSurface { - -class OSC_GUI : public Gtk::Notebook -{ - public: - OSC_GUI (OSC&); - ~OSC_GUI (); - -private: - // settings page - Gtk::ComboBoxText debug_combo; - Gtk::ComboBoxText portmode_combo; - Gtk::SpinButton port_entry; - Gtk::SpinButton bank_entry; - Gtk::ComboBoxText gainmode_combo; - void debug_changed (); - void portmode_changed (); - void gainmode_changed (); - void clear_device (); - void factory_reset (); - void reshow_values (); - void port_changed (); - void bank_changed (); - void strips_changed (); - void feedback_changed (); - // Strip types calculator - uint32_t def_strip; - void calculate_strip_types (); - void push_strip_types (); - Gtk::Label current_strip_types; - Gtk::CheckButton audio_tracks; - Gtk::CheckButton midi_tracks; - Gtk::CheckButton audio_buses; - Gtk::CheckButton midi_buses; - Gtk::CheckButton control_masters; - Gtk::CheckButton master_type; - Gtk::CheckButton monitor_type; - Gtk::CheckButton selected_tracks; - Gtk::CheckButton hidden_tracks; - int stvalue; - // feedback calculator - uint32_t def_feedback; - void calculate_feedback (); - void push_feedback (); - Gtk::Label current_feedback; - Gtk::CheckButton strip_buttons_button; - Gtk::CheckButton strip_control_button; - Gtk::CheckButton ssid_as_path; - Gtk::CheckButton heart_beat; - Gtk::CheckButton master_fb; - Gtk::CheckButton bar_and_beat; - Gtk::CheckButton smpte; - Gtk::CheckButton meter_float; - Gtk::CheckButton meter_led; - Gtk::CheckButton signal_present; - Gtk::CheckButton hp_samples; - Gtk::CheckButton hp_min_sec; - Gtk::CheckButton hp_gui; - Gtk::CheckButton select_fb; - int fbvalue; - OSC& cp; -}; - - -void* -OSC::get_gui () const -{ - if (!gui) { - const_cast(this)->build_gui (); - } - //static_cast(gui)->show_all(); - static_cast(gui)->show_all(); - return gui; -} - -void -OSC::tear_down_gui () -{ - if (gui) { - Gtk::Widget *w = static_cast(gui)->get_parent(); - if (w) { - w->hide(); - delete w; - } - } - delete (OSC_GUI*) gui; - gui = 0; -} - -void -OSC::build_gui () -{ - gui = (void*) new OSC_GUI (*this); -} - -} // end namespace - -/////////////////////////////////////////////////////////////////////////////// - using namespace PBD; +using namespace ARDOUR; using namespace Gtk; using namespace Gtkmm2ext; using namespace ArdourSurface; @@ -149,12 +58,11 @@ OSC_GUI::OSC_GUI (OSC& p) Table* table = manage (new Table); Label* label; Button* button; - Button* frbutton; - Button* fbbutton; - Button* stbutton; table->set_row_spacings (10); table->set_col_spacings (6); table->set_border_width (12); + get_session (); + preset_busy = true; // show our url label = manage (new Gtk::Label(_("Connection:"))); @@ -229,14 +137,30 @@ OSC_GUI::OSC_GUI (OSC& p) debug_combo.set_active ((int)cp.get_debug_mode()); ++n; + // Preset loader combo + label = manage (new Gtk::Label(_("Preset:"))); + label->set_alignment(1, .5); + table->attach (*label, 0, 1, n, n+1, AttachOptions(FILL|EXPAND), AttachOptions(0)); + table->attach (preset_combo, 1, 2, n, n+1, AttachOptions(FILL|EXPAND), AttachOptions(0), 0, 0); + + preset_files.clear(); + // no files for these two + preset_options.push_back (_("Last Loaded Session")); + preset_options.push_back (_("Ardour Factory Setting")); + // user is special it appears in menu even if no file is present + preset_options.push_back ("User"); + preset_files["User"] = ""; + // scan for OSC .preset files + scan_preset_files (); + + set_popdown_strings (preset_combo, preset_options); + preset_combo.set_active (0); + preset_combo.signal_changed().connect (sigc::mem_fun (*this, &OSC_GUI::preset_changed)); + ++n; + // refresh button button = manage (new Gtk::Button(_("Clear OSC Devices"))); table->attach (*button, 0, 2, n, n+1, AttachOptions(FILL|EXPAND), AttachOptions(0), 0, 10); - ++n; - - // Factory reset - frbutton = manage (new Gtk::Button(_("Factory Reset"))); - table->attach (*frbutton, 0, 2, n, n+1, AttachOptions(FILL|EXPAND), AttachOptions(0), 0, 15); table->show_all (); append_page (*table, _("OSC Setup")); @@ -245,7 +169,6 @@ OSC_GUI::OSC_GUI (OSC& p) portmode_combo.signal_changed().connect (sigc::mem_fun (*this, &OSC_GUI::portmode_changed)); gainmode_combo.signal_changed().connect (sigc::mem_fun (*this, &OSC_GUI::gainmode_changed)); button->signal_clicked().connect (sigc::mem_fun (*this, &OSC_GUI::clear_device)); - frbutton->signal_clicked().connect (sigc::mem_fun (*this, &OSC_GUI::factory_reset)); port_entry.signal_activate().connect (sigc::mem_fun (*this, &OSC_GUI::port_changed)); bank_entry.signal_activate().connect (sigc::mem_fun (*this, &OSC_GUI::bank_changed)); @@ -273,69 +196,56 @@ OSC_GUI::OSC_GUI (OSC& p) label->set_alignment(1, .5); sttable->attach (*label, 0, 1, stn, stn+1, AttachOptions(FILL|EXPAND), AttachOptions(0)); sttable->attach (audio_tracks, 1, 2, stn, stn+1, AttachOptions(FILL|EXPAND), AttachOptions(0), 0, 0); - audio_tracks.signal_clicked().connect (sigc::mem_fun (*this, &OSC_GUI::calculate_strip_types)); ++stn; label = manage (new Gtk::Label(_("Midi Tracks:"))); label->set_alignment(1, .5); sttable->attach (*label, 0, 1, stn, stn+1, AttachOptions(FILL|EXPAND), AttachOptions(0)); sttable->attach (midi_tracks, 1, 2, stn, stn+1, AttachOptions(FILL|EXPAND), AttachOptions(0), 0, 0); - midi_tracks.signal_clicked().connect (sigc::mem_fun (*this, &OSC_GUI::calculate_strip_types)); ++stn; label = manage (new Gtk::Label(_("Audio Buses:"))); label->set_alignment(1, .5); sttable->attach (*label, 0, 1, stn, stn+1, AttachOptions(FILL|EXPAND), AttachOptions(0)); sttable->attach (audio_buses, 1, 2, stn, stn+1, AttachOptions(FILL|EXPAND), AttachOptions(0), 0, 0); - audio_buses.signal_clicked().connect (sigc::mem_fun (*this, &OSC_GUI::calculate_strip_types)); ++stn; label = manage (new Gtk::Label(_("Midi Buses:"))); label->set_alignment(1, .5); sttable->attach (*label, 0, 1, stn, stn+1, AttachOptions(FILL|EXPAND), AttachOptions(0)); sttable->attach (midi_buses, 1, 2, stn, stn+1, AttachOptions(FILL|EXPAND), AttachOptions(0), 0, 0); - midi_buses.signal_clicked().connect (sigc::mem_fun (*this, &OSC_GUI::calculate_strip_types)); ++stn; label = manage (new Gtk::Label(_("Control Masters:"))); label->set_alignment(1, .5); sttable->attach (*label, 0, 1, stn, stn+1, AttachOptions(FILL|EXPAND), AttachOptions(0)); sttable->attach (control_masters, 1, 2, stn, stn+1, AttachOptions(FILL|EXPAND), AttachOptions(0), 0, 0); - control_masters.signal_clicked().connect (sigc::mem_fun (*this, &OSC_GUI::calculate_strip_types)); ++stn; label = manage (new Gtk::Label(_("Master (use /master instead):"))); label->set_alignment(1, .5); sttable->attach (*label, 0, 1, stn, stn+1, AttachOptions(FILL|EXPAND), AttachOptions(0)); sttable->attach (master_type, 1, 2, stn, stn+1, AttachOptions(FILL|EXPAND), AttachOptions(0), 0, 0); - master_type.signal_clicked().connect (sigc::mem_fun (*this, &OSC_GUI::calculate_strip_types)); ++stn; label = manage (new Gtk::Label(_("Monitor (use /monitor instead):"))); label->set_alignment(1, .5); sttable->attach (*label, 0, 1, stn, stn+1, AttachOptions(FILL|EXPAND), AttachOptions(0)); sttable->attach (monitor_type, 1, 2, stn, stn+1, AttachOptions(FILL|EXPAND), AttachOptions(0), 0, 0); - monitor_type.signal_clicked().connect (sigc::mem_fun (*this, &OSC_GUI::calculate_strip_types)); ++stn; label = manage (new Gtk::Label(_("Selected Tracks (use for selected tracks only):"))); label->set_alignment(1, .5); sttable->attach (*label, 0, 1, stn, stn+1, AttachOptions(FILL|EXPAND), AttachOptions(0)); sttable->attach (selected_tracks, 1, 2, stn, stn+1, AttachOptions(FILL|EXPAND), AttachOptions(0), 0, 0); - selected_tracks.signal_clicked().connect (sigc::mem_fun (*this, &OSC_GUI::calculate_strip_types)); ++stn; label = manage (new Gtk::Label(_("Hidden Tracks:"))); label->set_alignment(1, .5); sttable->attach (*label, 0, 1, stn, stn+1, AttachOptions(FILL|EXPAND), AttachOptions(0)); sttable->attach (hidden_tracks, 1, 2, stn, stn+1, AttachOptions(FILL|EXPAND), AttachOptions(0), 0, 0); - hidden_tracks.signal_clicked().connect (sigc::mem_fun (*this, &OSC_GUI::calculate_strip_types)); ++stn; - stbutton = manage (new Gtk::Button(_("Set Default Strip Types"))); - sttable->attach (*stbutton, 0, 2, stn, stn+1, AttachOptions(FILL|EXPAND), AttachOptions(0), 0, 15); - stbutton->signal_clicked().connect (sigc::mem_fun (*this, &OSC_GUI::push_strip_types)); - sttable->show_all (); append_page (*sttable, _("Default Strip Types")); @@ -365,91 +275,78 @@ OSC_GUI::OSC_GUI (OSC& p) label->set_alignment(1, .5); fbtable->attach (*label, 0, 1, fn, fn+1, AttachOptions(FILL|EXPAND), AttachOptions(0)); fbtable->attach (strip_buttons_button, 1, 2, fn, fn+1, AttachOptions(FILL|EXPAND), AttachOptions(0), 0, 0); - strip_buttons_button.signal_clicked().connect (sigc::mem_fun (*this, &OSC_GUI::calculate_feedback)); ++fn; label = manage (new Gtk::Label(_("Strip Controls:"))); label->set_alignment(1, .5); fbtable->attach (*label, 0, 1, fn, fn+1, AttachOptions(FILL|EXPAND), AttachOptions(0)); fbtable->attach (strip_control_button, 1, 2, fn, fn+1, AttachOptions(FILL|EXPAND), AttachOptions(0), 0, 0); - strip_control_button.signal_clicked().connect (sigc::mem_fun (*this, &OSC_GUI::calculate_feedback)); ++fn; label = manage (new Gtk::Label(_("Use SSID as Path Extension:"))); label->set_alignment(1, .5); fbtable->attach (*label, 0, 1, fn, fn+1, AttachOptions(FILL|EXPAND), AttachOptions(0)); fbtable->attach (ssid_as_path, 1, 2, fn, fn+1, AttachOptions(FILL|EXPAND), AttachOptions(0), 0, 0); - ssid_as_path.signal_clicked().connect (sigc::mem_fun (*this, &OSC_GUI::calculate_feedback)); ++fn; label = manage (new Gtk::Label(_("Use Heart Beat:"))); label->set_alignment(1, .5); fbtable->attach (*label, 0, 1, fn, fn+1, AttachOptions(FILL|EXPAND), AttachOptions(0)); fbtable->attach (heart_beat, 1, 2, fn, fn+1, AttachOptions(FILL|EXPAND), AttachOptions(0), 0, 0); - heart_beat.signal_clicked().connect (sigc::mem_fun (*this, &OSC_GUI::calculate_feedback)); ++fn; label = manage (new Gtk::Label(_("Master Section:"))); label->set_alignment(1, .5); fbtable->attach (*label, 0, 1, fn, fn+1, AttachOptions(FILL|EXPAND), AttachOptions(0)); fbtable->attach (master_fb, 1, 2, fn, fn+1, AttachOptions(FILL|EXPAND), AttachOptions(0), 0, 0); - master_fb.signal_clicked().connect (sigc::mem_fun (*this, &OSC_GUI::calculate_feedback)); ++fn; label = manage (new Gtk::Label(_("Play Head Position as Bar and Beat:"))); label->set_alignment(1, .5); fbtable->attach (*label, 0, 1, fn, fn+1, AttachOptions(FILL|EXPAND), AttachOptions(0)); fbtable->attach (bar_and_beat, 1, 2, fn, fn+1, AttachOptions(FILL|EXPAND), AttachOptions(0), 0, 0); - bar_and_beat.signal_clicked().connect (sigc::mem_fun (*this, &OSC_GUI::calculate_feedback)); ++fn; label = manage (new Gtk::Label(_("Play Head Position as SMPTE Time:"))); label->set_alignment(1, .5); fbtable->attach (*label, 0, 1, fn, fn+1, AttachOptions(FILL|EXPAND), AttachOptions(0)); fbtable->attach (smpte, 1, 2, fn, fn+1, AttachOptions(FILL|EXPAND), AttachOptions(0), 0, 0); - smpte.signal_clicked().connect (sigc::mem_fun (*this, &OSC_GUI::calculate_feedback)); ++fn; label = manage (new Gtk::Label(_("Metering as a Float:"))); label->set_alignment(1, .5); fbtable->attach (*label, 0, 1, fn, fn+1, AttachOptions(FILL|EXPAND), AttachOptions(0)); fbtable->attach (meter_float, 1, 2, fn, fn+1, AttachOptions(FILL|EXPAND), AttachOptions(0), 0, 0); - meter_float.signal_clicked().connect (sigc::mem_fun (*this, &OSC_GUI::calculate_feedback)); ++fn; label = manage (new Gtk::Label(_("Metering as a LED Strip:"))); label->set_alignment(1, .5); fbtable->attach (*label, 0, 1, fn, fn+1, AttachOptions(FILL|EXPAND), AttachOptions(0)); fbtable->attach (meter_led, 1, 2, fn, fn+1, AttachOptions(FILL|EXPAND), AttachOptions(0), 0, 0); - meter_led.signal_clicked().connect (sigc::mem_fun (*this, &OSC_GUI::calculate_feedback)); ++fn; label = manage (new Gtk::Label(_("Signal Present:"))); label->set_alignment(1, .5); fbtable->attach (*label, 0, 1, fn, fn+1, AttachOptions(FILL|EXPAND), AttachOptions(0)); fbtable->attach (signal_present, 1, 2, fn, fn+1, AttachOptions(FILL|EXPAND), AttachOptions(0), 0, 0); - signal_present.signal_clicked().connect (sigc::mem_fun (*this, &OSC_GUI::calculate_feedback)); ++fn; label = manage (new Gtk::Label(_("Play Head Position as Samples:"))); label->set_alignment(1, .5); fbtable->attach (*label, 0, 1, fn, fn+1, AttachOptions(FILL|EXPAND), AttachOptions(0)); fbtable->attach (hp_samples, 1, 2, fn, fn+1, AttachOptions(FILL|EXPAND), AttachOptions(0), 0, 0); - hp_samples.signal_clicked().connect (sigc::mem_fun (*this, &OSC_GUI::calculate_feedback)); ++fn; label = manage (new Gtk::Label(_("Playhead Position as Minutes Seconds:"))); label->set_alignment(1, .5); fbtable->attach (*label, 0, 1, fn, fn+1, AttachOptions(FILL|EXPAND), AttachOptions(0)); fbtable->attach (hp_min_sec, 1, 2, fn, fn+1, AttachOptions(FILL|EXPAND), AttachOptions(0), 0, 0); - hp_min_sec.signal_clicked().connect (sigc::mem_fun (*this, &OSC_GUI::calculate_feedback)); ++fn; label = manage (new Gtk::Label(_("Playhead Position as per GUI Clock:"))); label->set_alignment(1, .5); fbtable->attach (*label, 0, 1, fn, fn+1, AttachOptions(FILL|EXPAND), AttachOptions(0)); fbtable->attach (hp_gui, 1, 2, fn, fn+1, AttachOptions(FILL|EXPAND), AttachOptions(0), 0, 0); - hp_gui.signal_clicked().connect (sigc::mem_fun (*this, &OSC_GUI::calculate_feedback)); hp_gui.set_sensitive (false); // we don't have this yet (Mixbus wants) ++fn; @@ -457,17 +354,37 @@ OSC_GUI::OSC_GUI (OSC& p) label->set_alignment(1, .5); fbtable->attach (*label, 0, 1, fn, fn+1, AttachOptions(FILL|EXPAND), AttachOptions(0)); fbtable->attach (select_fb, 1, 2, fn, fn+1, AttachOptions(FILL|EXPAND), AttachOptions(0), 0, 0); - select_fb.signal_clicked().connect (sigc::mem_fun (*this, &OSC_GUI::calculate_feedback)); ++fn; - fbbutton = manage (new Gtk::Button(_("Set Default Feedback"))); - fbtable->attach (*fbbutton, 0, 2, fn, fn+1, AttachOptions(FILL|EXPAND), AttachOptions(0), 0, 15); - fbbutton->signal_clicked().connect (sigc::mem_fun (*this, &OSC_GUI::push_feedback)); - - fbtable->show_all (); append_page (*fbtable, _("Default Feedback")); + // set strips and feedback from loaded default values reshow_values (); + // connect signals + audio_tracks.signal_clicked().connect (sigc::mem_fun (*this, &OSC_GUI::set_bitsets)); + midi_tracks.signal_clicked().connect (sigc::mem_fun (*this, &OSC_GUI::set_bitsets)); + audio_buses.signal_clicked().connect (sigc::mem_fun (*this, &OSC_GUI::set_bitsets)); + midi_buses.signal_clicked().connect (sigc::mem_fun (*this, &OSC_GUI::set_bitsets)); + control_masters.signal_clicked().connect (sigc::mem_fun (*this, &OSC_GUI::set_bitsets)); + master_type.signal_clicked().connect (sigc::mem_fun (*this, &OSC_GUI::set_bitsets)); + monitor_type.signal_clicked().connect (sigc::mem_fun (*this, &OSC_GUI::set_bitsets)); + selected_tracks.signal_clicked().connect (sigc::mem_fun (*this, &OSC_GUI::set_bitsets)); + hidden_tracks.signal_clicked().connect (sigc::mem_fun (*this, &OSC_GUI::set_bitsets)); + strip_buttons_button.signal_clicked().connect (sigc::mem_fun (*this, &OSC_GUI::set_bitsets)); + strip_control_button.signal_clicked().connect (sigc::mem_fun (*this, &OSC_GUI::set_bitsets)); + ssid_as_path.signal_clicked().connect (sigc::mem_fun (*this, &OSC_GUI::set_bitsets)); + heart_beat.signal_clicked().connect (sigc::mem_fun (*this, &OSC_GUI::set_bitsets)); + master_fb.signal_clicked().connect (sigc::mem_fun (*this, &OSC_GUI::set_bitsets)); + bar_and_beat.signal_clicked().connect (sigc::mem_fun (*this, &OSC_GUI::set_bitsets)); + smpte.signal_clicked().connect (sigc::mem_fun (*this, &OSC_GUI::set_bitsets)); + meter_float.signal_clicked().connect (sigc::mem_fun (*this, &OSC_GUI::set_bitsets)); + meter_led.signal_clicked().connect (sigc::mem_fun (*this, &OSC_GUI::set_bitsets)); + signal_present.signal_clicked().connect (sigc::mem_fun (*this, &OSC_GUI::set_bitsets)); + hp_samples.signal_clicked().connect (sigc::mem_fun (*this, &OSC_GUI::set_bitsets)); + hp_min_sec.signal_clicked().connect (sigc::mem_fun (*this, &OSC_GUI::set_bitsets)); + hp_gui.signal_clicked().connect (sigc::mem_fun (*this, &OSC_GUI::set_bitsets)); + select_fb.signal_clicked().connect (sigc::mem_fun (*this, &OSC_GUI::set_bitsets)); + preset_busy = false; } @@ -475,6 +392,56 @@ OSC_GUI::~OSC_GUI () { } +// static directory and file handling stuff +static Searchpath +preset_search_path () +{ + bool preset_path_defined = false; + std::string spath_env (Glib::getenv (preset_env_variable_name, preset_path_defined)); + + if (preset_path_defined) { + return spath_env; + } + + Searchpath spath (ardour_data_search_path()); + spath.add_subdirectory_to_paths(preset_dir_name); + + return spath; +} + +static std::string +user_preset_directory () +{ + return Glib::build_filename (user_config_directory(), preset_dir_name); +} + +static bool +preset_filter (const std::string &str, void* /*arg*/) +{ + return (str.length() > strlen(preset_suffix) && + str.find (preset_suffix) == (str.length() - strlen (preset_suffix))); +} + +static std::string +legalize_for_path (const std::string& str) +{ + std::string::size_type pos; + std::string illegal_chars = "/\\"; /* DOS, POSIX. Yes, we're going to ignore HFS */ + std::string legal; + + legal = str; + pos = 0; + + while ((pos = legal.find_first_of (illegal_chars, pos)) != std::string::npos) { + legal.replace (pos, 1, "_"); + pos += 1; + } + + return std::string (legal); +} + +// end of static functions + void OSC_GUI::debug_changed () { @@ -510,6 +477,7 @@ OSC_GUI::portmode_changed () std::cerr << "Invalid OSC Port Mode\n"; assert (0); } + save_user (); } void @@ -521,6 +489,7 @@ OSC_GUI::port_changed () port_entry.set_value (8000); } cp.set_remote_port (str); + save_user (); } void @@ -528,6 +497,7 @@ OSC_GUI::bank_changed () { uint32_t bsize = bank_entry.get_value (); cp.set_banksize (bsize); + save_user (); } @@ -545,6 +515,7 @@ OSC_GUI::gainmode_changed () std::cerr << "Invalid OSC Gain Mode\n"; assert (0); } + save_user (); } void @@ -553,6 +524,26 @@ OSC_GUI::clear_device () cp.clear_devices(); } +void +OSC_GUI::preset_changed () +{ + preset_busy = true; + std::string str = preset_combo.get_active_text (); + if (str == "Last Loaded Session") { + restore_sesn_values (); + } + else if (str == "Ardour Factory Setting") { + factory_reset (); + } + else if (str == "User") { + load_preset ("User"); + } + else { + load_preset (str); + } + preset_busy = false; +} + void OSC_GUI::factory_reset () { @@ -565,6 +556,8 @@ OSC_GUI::factory_reset () gainmode_combo.set_active (0); cp.set_portmode (0); portmode_combo.set_active (0); + cp.set_remote_port ("8000"); + port_entry.set_value (8000); cp.clear_devices(); } @@ -593,6 +586,7 @@ OSC_GUI::reshow_values () meter_led.set_active(def_feedback & 256); signal_present.set_active(def_feedback & 512); hp_samples.set_active(def_feedback & 1024); + hp_min_sec.set_active (def_feedback & 2048); //hp_gui.set_active (false); // we don't have this yet (Mixbus wants) select_fb.set_active(def_feedback & 8192); @@ -654,6 +648,7 @@ void OSC_GUI::push_feedback () { cp.set_defaultfeedback (fbvalue); + save_user (); } void @@ -698,4 +693,223 @@ void OSC_GUI::push_strip_types () { cp.set_defaultstrip (stvalue); + save_user (); +} + +void +OSC_GUI::set_bitsets () +{ + if (preset_busy) { + return; + } + calculate_strip_types (); + calculate_feedback (); + push_strip_types (); + push_feedback (); +} + +void +OSC_GUI::scan_preset_files () +{ + std::vector presets; + Searchpath spath (preset_search_path()); + + find_files_matching_filter (presets, spath, preset_filter, 0, false, true); + //device_profiles.clear ();preset_list.clear // first two entries already there + + if (presets.empty()) { + error << "No OSC preset files found using " << spath.to_string() << endmsg; + return; + } + + for (std::vector::iterator i = presets.begin(); i != presets.end(); ++i) { + std::string fullpath = *i; + //DeviceProfile dp; // has to be initial every loop or info from last added. + + XMLTree tree; + + if (!tree.read (fullpath.c_str())) { + continue; + } + + XMLNode* root = tree.root (); + if (!root) { + continue; + } + const XMLProperty* prop; + const XMLNode* child; + + if (root->name() != "OSCPreset") { + continue; + } + + if ((child = root->child ("Name")) == 0 || (prop = child->property ("value")) == 0) { + continue; + } else { + if (prop->value() == "User") { + // We already added user but no file name + preset_files[prop->value()] = fullpath; + } else if (preset_files.find(prop->value()) == preset_files.end()) { + preset_options.push_back (prop->value()); + preset_files[prop->value()] = fullpath; + } + } + + } +} + +void +OSC_GUI::save_user () +{ + if (preset_busy) { + return; + } + preset_combo.set_active (2); + std::string fullpath = user_preset_directory(); + + if (g_mkdir_with_parents (fullpath.c_str(), 0755) < 0) { + error << string_compose(_("Session: cannot create user MCP profile folder \"%1\" (%2)"), fullpath, strerror (errno)) << endmsg; + return; + } + + fullpath = Glib::build_filename (fullpath, string_compose ("%1%2", legalize_for_path ("user"), preset_suffix)); + + XMLNode* node = new XMLNode ("OSCPreset"); + XMLNode* child = new XMLNode ("Name"); + + child->add_property ("value", "User"); + node->add_child_nocopy (*child); + + child = new XMLNode ("PortMode"); + child->add_property ("value", cp.get_portmode()); + node->add_child_nocopy (*child); + + child = new XMLNode ("Remote-Port"); + child->add_property ("value", cp.get_remote_port()); + node->add_child_nocopy (*child); + + child = new XMLNode ("Bank-Size"); + child->add_property ("value", cp.get_banksize()); + node->add_child_nocopy (*child); + + child = new XMLNode ("Strip-Types"); + child->add_property ("value", cp.get_defaultstrip()); + node->add_child_nocopy (*child); + + child = new XMLNode ("Feedback"); + child->add_property ("value", cp.get_defaultfeedback()); + node->add_child_nocopy (*child); + + child = new XMLNode ("Gain-Mode"); + child->add_property ("value", cp.get_gainmode()); + node->add_child_nocopy (*child); + + XMLTree tree; + tree.set_root (node); + + if (!tree.write (fullpath)) { + error << string_compose ("MCP profile not saved to %1", fullpath) << endmsg; + } + +} + +void +OSC_GUI::load_preset (std::string preset) +{ + if (preset == "User" && preset_files["User"] == "") { + restore_sesn_values (); + } else if (preset_files.find(preset) != preset_files.end()) { + XMLTree tree; + + if (!tree.read (preset_files[preset])) { + std::cerr << "preset file not found " << preset_files[preset] << "\n"; + return; + } + + XMLNode* root = tree.root (); + if (!root) { + std::cerr << "invalid preset file " << preset_files[preset] << "\n"; + return; + } + const XMLProperty* prop; + const XMLNode* child; + + if (root->name() != "OSCPreset") { + std::cerr << "invalid preset file " << preset_files[preset] << "\n"; + return; + } + + if ((child = root->child ("Name")) == 0 || (prop = child->property ("value")) == 0) { + std::cerr << "preset file missing Name " << preset_files[preset] << "\n"; + return; + } + if ((child = root->child ("PortMode")) == 0 || (prop = child->property ("value")) == 0) { + cp.set_portmode (sesn_portmode); + portmode_combo.set_active (sesn_portmode); + } else { + cp.set_portmode (atoi (prop->value().c_str())); + portmode_combo.set_active (atoi (prop->value().c_str())); + } + if ((child = root->child ("Remote-Port")) == 0 || (prop = child->property ("value")) == 0) { + cp.set_remote_port (sesn_port); + port_entry.set_text (sesn_port); + } else { + cp.set_remote_port (prop->value()); + port_entry.set_text (prop->value()); + } + if ((child = root->child ("Bank-Size")) == 0 || (prop = child->property ("value")) == 0) { + cp.set_banksize (sesn_bank); + bank_entry.set_value (sesn_bank); + } else { + cp.set_banksize (atoi (prop->value().c_str())); + bank_entry.set_value (atoi (prop->value().c_str())); + } + if ((child = root->child ("Strip-Types")) == 0 || (prop = child->property ("value")) == 0) { + cp.set_defaultstrip (sesn_strips); + } else { + cp.set_defaultstrip (atoi (prop->value().c_str())); + } + if ((child = root->child ("Feedback")) == 0 || (prop = child->property ("value")) == 0) { + cp.set_defaultfeedback (sesn_feedback); + } else { + cp.set_defaultfeedback (atoi (prop->value().c_str())); + } + reshow_values (); // show strip types and feed back in GUI + + if ((child = root->child ("Gain-Mode")) == 0 || (prop = child->property ("value")) == 0) { + cp.set_gainmode (sesn_gainmode); + gainmode_combo.set_active (sesn_gainmode); + } else { + cp.set_gainmode (atoi (prop->value().c_str())); + gainmode_combo.set_active (atoi (prop->value().c_str())); + } + + } +} + +void +OSC_GUI::get_session () +{ + sesn_portmode = cp.get_portmode (); + sesn_port = cp.get_remote_port (); + sesn_bank = cp.get_banksize (); + sesn_strips = cp.get_defaultstrip (); + sesn_feedback = cp.get_defaultfeedback (); + sesn_gainmode = cp.get_gainmode (); +} + +void +OSC_GUI::restore_sesn_values () +{ + cp.set_portmode (sesn_portmode); + portmode_combo.set_active (sesn_portmode); + cp.set_remote_port (sesn_port); + port_entry.set_text (sesn_port); + cp.set_banksize (sesn_bank); + bank_entry.set_value (sesn_bank); + cp.set_defaultstrip (sesn_strips); + cp.set_defaultfeedback (sesn_feedback); + reshow_values (); + cp.set_gainmode (sesn_gainmode); + gainmode_combo.set_active (sesn_gainmode); } diff --git a/libs/surfaces/osc/osc_gui.h b/libs/surfaces/osc/osc_gui.h new file mode 100644 index 0000000000..e0c71b83d1 --- /dev/null +++ b/libs/surfaces/osc/osc_gui.h @@ -0,0 +1,152 @@ +/* + Copyright (C) 2016 Robin Gareus preset_options; + std::map preset_files; + bool preset_busy; + void get_session (); + void restore_sesn_values (); + uint32_t sesn_portmode; + std::string sesn_port; + uint32_t sesn_bank; + uint32_t sesn_strips; + uint32_t sesn_feedback; + uint32_t sesn_gainmode; + void save_user (); + void scan_preset_files (); + void load_preset (std::string preset); + + void debug_changed (); + void portmode_changed (); + void gainmode_changed (); + void clear_device (); + void factory_reset (); + void reshow_values (); + void port_changed (); + void bank_changed (); + void strips_changed (); + void feedback_changed (); + void preset_changed (); + // Strip types calculator + uint32_t def_strip; + void calculate_strip_types (); + void push_strip_types (); + Gtk::Label current_strip_types; + Gtk::CheckButton audio_tracks; + Gtk::CheckButton midi_tracks; + Gtk::CheckButton audio_buses; + Gtk::CheckButton midi_buses; + Gtk::CheckButton control_masters; + Gtk::CheckButton master_type; + Gtk::CheckButton monitor_type; + Gtk::CheckButton selected_tracks; + Gtk::CheckButton hidden_tracks; + int stvalue; + // feedback calculator + uint32_t def_feedback; + void calculate_feedback (); + void push_feedback (); + Gtk::Label current_feedback; + Gtk::CheckButton strip_buttons_button; + Gtk::CheckButton strip_control_button; + Gtk::CheckButton ssid_as_path; + Gtk::CheckButton heart_beat; + Gtk::CheckButton master_fb; + Gtk::CheckButton bar_and_beat; + Gtk::CheckButton smpte; + Gtk::CheckButton meter_float; + Gtk::CheckButton meter_led; + Gtk::CheckButton signal_present; + Gtk::CheckButton hp_samples; + Gtk::CheckButton hp_min_sec; + Gtk::CheckButton hp_gui; + Gtk::CheckButton select_fb; + int fbvalue; + void set_bitsets (); + + + + OSC& cp; +}; + + +void* +OSC::get_gui () const +{ + if (!gui) { + const_cast(this)->build_gui (); + } + //static_cast(gui)->show_all(); + static_cast(gui)->show_all(); + return gui; +} + +void +OSC::tear_down_gui () +{ + if (gui) { + Gtk::Widget *w = static_cast(gui)->get_parent(); + if (w) { + w->hide(); + delete w; + } + } + delete (OSC_GUI*) gui; + gui = 0; +} + +void +OSC::build_gui () +{ + gui = (void*) new OSC_GUI (*this); +} + +} // end namespace + +#endif // osc_gui_h diff --git a/osc/TTC2.preset b/osc/TTC2.preset new file mode 100644 index 0000000000..c431c68dd5 --- /dev/null +++ b/osc/TTC2.preset @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/osc/wscript b/osc/wscript new file mode 100644 index 0000000000..64b173af5c --- /dev/null +++ b/osc/wscript @@ -0,0 +1,16 @@ +#!/usr/bin/python + +import os + +top = '.' +out = 'build' + +def configure(conf): + pass + +def build(bld): + presets = bld.path.ant_glob ('*.preset') + bld.install_files (os.path.join(bld.env['DATADIR'], 'osc'), presets) + +def options(opt): + pass diff --git a/wscript b/wscript index 8edd38d176..ae6d35b878 100644 --- a/wscript +++ b/wscript @@ -229,6 +229,7 @@ children = [ 'export', 'midi_maps', 'mcp', + 'osc', 'patchfiles', 'scripts', 'headless', -- 2.30.2