summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLen Ovens <len@ovenwerks.net>2016-08-24 10:07:21 -0700
committerLen Ovens <len@ovenwerks.net>2016-08-24 10:07:21 -0700
commit7ccbc0ca73055bafba07d8a5a785ca3bf1c8cb74 (patch)
tree771ea9ffc5004953478d575034e158d61ac503ff
parent427d9f888ade60c20d57e6f3ccd8a62eab6fc426 (diff)
OSC: Add preset loading to OSC GUI
-rw-r--r--libs/surfaces/osc/osc_gui.cc494
-rw-r--r--libs/surfaces/osc/osc_gui.h152
-rw-r--r--osc/TTC2.preset10
-rw-r--r--osc/wscript16
-rw-r--r--wscript1
5 files changed, 533 insertions, 140 deletions
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 <iostream>
#include <list>
#include <string>
+#include <vector>
+//#include <glibmm/miscutils.h>
+
+#include "pbd/file_utils.h"
#include <gtkmm/box.h>
#include <gtkmm/notebook.h>
@@ -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<OSC*>(this)->build_gui ();
- }
- //static_cast<Gtk::VBox*>(gui)->show_all();
- static_cast<Gtk::Notebook*>(gui)->show_all();
- return gui;
-}
-
-void
-OSC::tear_down_gui ()
-{
- if (gui) {
- Gtk::Widget *w = static_cast<Gtk::Notebook*>(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
@@ -554,6 +525,26 @@ OSC_GUI::clear_device ()
}
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 ()
{
cp.set_banksize (0);
@@ -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<std::string> 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<std::string>::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 <robin@gareus.org
+ Copyright (C) 2009-2012 Paul Davis
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+*/
+#ifndef osc_gui_h
+#define osc_gui_h
+
+
+#include "osc.h"
+
+#include "pbd/i18n.h"
+
+// preset stuff
+static const char* const preset_dir_name = "osc";
+static const char* const preset_suffix = ".preset";
+static const char * const preset_env_variable_name = "ARDOUR_OSC_PATH";
+
+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;
+ Gtk::ComboBoxText preset_combo;
+ std::vector<std::string> preset_options;
+ std::map<std::string,std::string> 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<OSC*>(this)->build_gui ();
+ }
+ //static_cast<Gtk::VBox*>(gui)->show_all();
+ static_cast<Gtk::Notebook*>(gui)->show_all();
+ return gui;
+}
+
+void
+OSC::tear_down_gui ()
+{
+ if (gui) {
+ Gtk::Widget *w = static_cast<Gtk::Notebook*>(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 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<OSCPreset>
+ <Name value="TTC2"/>
+ <PortMode value="1"/>
+ <Remote-Port value="8000"/>
+ <Bank-Size value="0"/>
+ <Strip-Types value="3"/>
+ <Feedback value="605"/>
+ <Gain-Mode value="1"/>
+</OSCPreset>
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',