FP8: Scribble-strip display preferences

This commit is contained in:
Robin Gareus
2017-06-30 19:55:03 +02:00
parent cd728fdd73
commit 389d2cab36
7 changed files with 279 additions and 38 deletions

View File

@@ -44,6 +44,7 @@
#include "ardour/route.h"
#include "ardour/session.h"
#include "ardour/session_configuration.h"
#include "ardour/tempo.h"
#include "ardour/vca.h"
#include "faderport8.h"
@@ -99,6 +100,9 @@ FaderPort8::FaderPort8 (Session& s)
, _shift_lock (false)
, _shift_pressed (0)
, gui (0)
, _clock_mode (1)
, _scribble_mode (2)
, _two_line_text (false)
{
boost::shared_ptr<ARDOUR::Port> inp;
boost::shared_ptr<ARDOUR::Port> outp;
@@ -217,15 +221,24 @@ FaderPort8::thread_init ()
bool
FaderPort8::periodic ()
{
/* prepare TC display -- handled by stripable Periodic () */
if (_ctrls.display_timecode ()) {
// TODO allow BBT, HHMMSS
// used in FP8Strip::periodic_update_timecode
/* prepare TC display -- handled by stripable Periodic ()
* in FP8Strip::periodic_update_timecode
*/
if (_ctrls.display_timecode () && clock_mode ()) {
Timecode::Time TC;
session->timecode_time (TC);
_timecode = Timecode::timecode_format_time(TC);
char buf[16];
Timecode::BBT_Time BBT = session->tempo_map ().bbt_at_frame (session->transport_frame ());
snprintf (buf, sizeof (buf),
" %02" PRIu32 "|%02" PRIu32 "|%02" PRIu32 "|%02" PRIu32,
BBT.bars % 100, BBT.beats %100,
(BBT.ticks/ 100) %100, BBT.ticks %100);
_musical_time = std::string (buf);
} else {
_timecode.clear ();
_musical_time.clear ();
}
/* update stripables */
@@ -688,6 +701,9 @@ FaderPort8::get_state ()
child->add_child_nocopy (boost::shared_ptr<ARDOUR::Port>(_output_port)->get_state());
node.add_child_nocopy (*child);
node.set_property (X_("clock-mode"), _clock_mode);
node.set_property (X_("scribble-mode"), _scribble_mode);
for (UserActionMap::const_iterator i = _user_action_map.begin (); i != _user_action_map.end (); ++i) {
if (i->second.empty()) {
continue;
@@ -738,6 +754,9 @@ FaderPort8::set_state (const XMLNode& node, int version)
}
}
node.get_property (X_("clock-mode"), _clock_mode);
node.get_property (X_("scribble-mode"), _scribble_mode);
_user_action_map.clear ();
// TODO: When re-loading state w/o surface re-init becomes possible,
// unset lights and reset colors of user buttons.
@@ -903,7 +922,7 @@ FaderPort8::filter_stripables (StripableList& strips) const
strips.sort (Stripable::Sorter());
}
/* Track/Pan mode: assign stripable to strips */
/* Track/Pan mode: assign stripable to strips, Send-mode: selection */
void
FaderPort8::assign_stripables (bool select_only)
{
@@ -936,6 +955,7 @@ FaderPort8::assign_stripables (bool select_only)
boost::bind (&FaderPort8::notify_stripable_property_changed, this, boost::weak_ptr<Stripable> (*s), _1), this);
if (select_only) {
/* used in send mode */
_ctrls.strip(id).set_text_line (3, (*s)->name (), true);
_ctrls.strip(id).select_button ().set_color ((*s)->presentation_info ().color());
/* update selection lights */
@@ -954,6 +974,7 @@ FaderPort8::assign_stripables (bool select_only)
}
for (; id < 8; ++id) {
_ctrls.strip(id).unset_controllables (select_only ? (FP8Strip::CTRL_SELECT | FP8Strip::CTRL_TEXT3) : FP8Strip::CTRL_ALL);
_ctrls.strip(id).set_periodic_display_mode (FP8Strip::Stripables);
}
}

View File

@@ -88,6 +88,14 @@ public:
std::string get_button_action (FP8Controls::ButtonId, bool);
FP8Controls const& control () const { return _ctrls; }
void set_clock_mode (uint32_t m) { _clock_mode = m; }
void set_scribble_mode (uint32_t m) { _scribble_mode = m; }
void set_two_line_text (bool yn) { _two_line_text = yn; }
uint32_t clock_mode () const { return _clock_mode; }
uint32_t scribble_mode () const { return _scribble_mode; }
bool twolinetext () const { return _two_line_text; }
int stop ();
void do_request (FaderPort8Request*);
void thread_init ();
@@ -210,7 +218,12 @@ private:
sigc::connection _periodic_connection;
bool periodic ();
std::string _timecode;
std::string _musical_time;
std::string const& timecode () const { return _timecode; }
std::string const& musical_time () const { return _musical_time; }
bool show_meters () const { return _scribble_mode & 1; }
bool show_panner () const { return _scribble_mode & 2; }
/* sync button blink -- the FP's blink mode does not work */
sigc::connection _blink_connection;
@@ -277,6 +290,11 @@ private:
std::vector <boost::weak_ptr<ARDOUR::AutomationControl> > _solo_state;
#endif
/* user prefs */
uint32_t _clock_mode;
uint32_t _scribble_mode;
bool _two_line_text;
/* user bound actions */
void button_user (bool, FP8Controls::ButtonId);

View File

@@ -48,7 +48,12 @@ public:
virtual size_t tx_midi (std::vector<uint8_t> const&) const = 0;
virtual std::string const& timecode () const = 0;
virtual std::string const& musical_time () const = 0;
virtual bool shift_mod () const = 0;
virtual bool show_meters () const = 0;
virtual bool show_panner () const = 0;
virtual bool twolinetext () const = 0;
virtual uint32_t clock_mode () const = 0;
size_t tx_midi2 (uint8_t sb, uint8_t d1) const
{

View File

@@ -178,6 +178,7 @@ FP8Strip::unset_controllables (int which)
{
_peak_meter = boost::shared_ptr<ARDOUR::PeakMeter>();
_redux_ctrl = boost::shared_ptr<ARDOUR::ReadOnlyControl>();
_stripable_name.clear ();
if (which & CTRL_FADER) {
set_fader_controllable (boost::shared_ptr<AutomationControl>());
@@ -201,25 +202,44 @@ FP8Strip::unset_controllables (int which)
select_button ().set_blinking (false);
}
if (which & CTRL_TEXT0) {
set_text_line (0x00, "");
set_text_line (0, "");
}
if (which & CTRL_TEXT1) {
set_text_line (0x01, "");
set_text_line (1, "");
}
if (which & CTRL_TEXT2) {
set_text_line (0x02, "");
set_text_line (2, "");
}
if (which & CTRL_TEXT3) {
set_text_line (0x03, "");
set_text_line (3, "");
}
set_bar_mode (4); // Off
}
void
FP8Strip::set_strip_name ()
{
size_t lb = _base.show_meters () ? 6 : 9;
set_text_line (0, _stripable_name.substr (0, lb));
set_text_line (1, _stripable_name.length() > lb ? _stripable_name.substr (lb) : "");
}
void
FP8Strip::set_stripable (boost::shared_ptr<Stripable> s, bool panmode)
{
assert (s);
if (_base.show_meters () && _base.show_panner ()) {
set_strip_mode (5, true);
} else if (_base.show_meters ()) {
set_strip_mode (4, true);
} else {
set_strip_mode (0, true);
}
if (!_base.show_panner ()) {
set_bar_mode (4, true); // Off
}
if (panmode) {
set_fader_controllable (s->pan_azimuth_control ());
} else {
@@ -251,11 +271,16 @@ FP8Strip::set_stripable (boost::shared_ptr<Stripable> s, bool panmode)
select_button ().set_color (s->presentation_info ().color());
//select_button ().set_blinking (false);
set_strip_mode (0x05);
set_text_line (0x00, s->name ());
set_text_line (0x01, _pan_ctrl ? _pan_ctrl->get_user_string () : "");
set_text_line (0x02, "");
set_text_line (0x03, "");
_stripable_name = s->name ();
if (_base.twolinetext ()) {
set_text_line (0, s->name ());
set_text_line (1, _pan_ctrl ? _pan_ctrl->get_user_string () : "");
} else {
set_strip_name ();
}
set_text_line (2, "");
set_text_line (3, "");
}
/* *****************************************************************************
@@ -467,10 +492,11 @@ FP8Strip::set_periodic_display_mode (DisplayMode m) {
void
FP8Strip::periodic_update_meter ()
{
bool show_meters = _base.show_meters ();
bool have_meter = false;
bool have_panner = false;
if (_peak_meter) {
if (_peak_meter && show_meters) {
have_meter = true;
float dB = _peak_meter->meter_level (0, MeterMCP);
// TODO: deflect meter
@@ -480,7 +506,7 @@ FP8Strip::periodic_update_meter ()
_last_meter = val;
}
} else {
} else if (show_meters) {
if (0 != _last_meter) {
_base.tx_midi2 (0xd0 + _id, 0);
_last_meter = 0;
@@ -488,7 +514,7 @@ FP8Strip::periodic_update_meter ()
}
// show redux only if there's a meter, too (strip display mode 5)
if (_peak_meter && _redux_ctrl) {
if (_peak_meter && _redux_ctrl && show_meters) {
float rx = (1.f - _redux_ctrl->get_parameter ()) * 127.f;
// TODO: deflect redux
int val = std::min (127.f, std::max (0.f, rx));
@@ -496,7 +522,7 @@ FP8Strip::periodic_update_meter ()
_base.tx_midi2 (0xd8 + _id, val & 0x7f);
_last_redux = val;
}
} else {
} else if (show_meters) {
if (0 != _last_redux) {
_base.tx_midi2 (0xd8 + _id, 0);
_last_redux = 0;
@@ -515,28 +541,37 @@ FP8Strip::periodic_update_meter ()
}
} else {
set_bar_mode (4); // Off
set_text_line (0x02, "");
set_text_line (2, "");
}
}
else if (_displaymode == SendDisplay) {
set_bar_mode (4); // Off
if (_fader_ctrl) {
set_text_line (0x01, value_as_string(_fader_ctrl->desc(), _fader_ctrl->get_value()));
set_text_line (1, value_as_string(_fader_ctrl->desc(), _fader_ctrl->get_value()));
} else {
set_text_line (0x01, "");
set_text_line (1, "");
}
} else if (_pan_ctrl) {
have_panner = true;
have_panner = _base.show_panner ();
float panpos = _pan_ctrl->internal_to_interface (_pan_ctrl->get_value());
int val = std::min (127.f, std::max (0.f, panpos * 128.f));
set_bar_mode (1); // Bipolar
if (val != _last_barpos) {
set_bar_mode (have_panner ? 1 : 4); // Bipolar or Off
if (val != _last_barpos && have_panner) {
_base.tx_midi3 (0xb0, 0x30 + _id, val & 0x7f);
_last_barpos = val;
}
set_text_line (0x01, _pan_ctrl->get_user_string ());
if (_base.twolinetext ()) {
set_text_line (1, _pan_ctrl->get_user_string ());
} else {
set_strip_name ();
}
} else {
set_bar_mode (4); // Off
if (_base.twolinetext ()) {
set_text_line (1, "");
} else {
set_strip_name ();
}
}
if (_displaymode == SendDisplay || _displaymode == PluginParam) {
@@ -549,9 +584,9 @@ FP8Strip::periodic_update_meter ()
set_strip_mode (4); // big meters + 3 lines of text (3rd line is large)
}
else if (have_panner) {
set_strip_mode (0); // 3 lines of text (3rd line is large) + value-bar
set_strip_mode (0); // 3 lines of text (3rd line is large + long) + value-bar
} else {
set_strip_mode (0); // 3 lines of text (3rd line is large) + value-bar
set_strip_mode (0); // 3 lines of text (3rd line is large + long) + value-bar
}
}
@@ -561,16 +596,32 @@ FP8Strip::set_strip_mode (uint8_t strip_mode, bool clear)
if (strip_mode == _strip_mode && !clear) {
return;
}
_strip_mode = strip_mode;
_base.tx_sysex (3, 0x13, _id, (_strip_mode & 0x07) | (clear ? 0x10 : 0));
if (clear) {
/* work-around, when swiching modes, the FP8 may not
* properly redraw long lines. Only update lines 0, 1
* (line 2 is timecode, line 3 may be inverted)
*/
_base.tx_text (_id, 0, 0x00, _last_line[0]);
_base.tx_text (_id, 1, 0x00, _last_line[1]);
}
}
void
FP8Strip::set_bar_mode (uint8_t bar_mode)
FP8Strip::set_bar_mode (uint8_t bar_mode, bool force)
{
if (bar_mode == _bar_mode) {
if (bar_mode == _bar_mode && !force) {
return;
}
if (bar_mode == 4) {
_base.tx_midi3 (0xb0, 0x30 + _id, 0);
_last_barpos = 0xff;
}
_bar_mode = bar_mode;
_base.tx_midi3 (0xb0, 0x38 + _id, bar_mode);
}
@@ -587,16 +638,29 @@ FP8Strip::set_text_line (uint8_t line, std::string const& txt, bool inv)
}
void
FP8Strip::periodic_update_timecode ()
FP8Strip::periodic_update_timecode (uint32_t m)
{
if (_id >= 2 && _id < 6) {
std::string const& tc = _base.timecode();
//" HH:MM:SS:FF"
if (m == 0) {
return;
}
if (m == 3) {
bool mc = _id >= 4;
std::string const& tc = mc ? _base.musical_time () : _base.timecode();
std::string t;
if (tc.size () == 12) {
t = tc.substr (1 + (_id - (mc ? 4 : 0)) * 3, 2);
}
set_text_line (2, t);
} else if (_id >= 2 && _id < 6) {
std::string const& tc = (m == 2) ? _base.musical_time () : _base.timecode();
//" HH:MM:SS:FF" or " BR|BT|TI|CK"
std::string t;
if (tc.size () == 12) {
t = tc.substr (1 + (_id - 2) * 3, 2);
}
set_text_line (0x02, t);
set_text_line (2, t);
} else {
set_text_line (2, "");
}
}
@@ -606,6 +670,6 @@ FP8Strip::periodic ()
periodic_update_fader ();
periodic_update_meter ();
if (_displaymode != PluginSelect && _displaymode != PluginParam) {
periodic_update_timecode ();
periodic_update_timecode (_base.clock_mode ());
}
}

View File

@@ -107,7 +107,7 @@ private:
PBD::ScopedConnection _base_connection; // periodic
PBD::ScopedConnectionList _button_connections;
boost::shared_ptr<ARDOUR::Stripable> _stripable;
std::string _stripable_name;
boost::shared_ptr<ARDOUR::AutomationControl> _fader_ctrl;
boost::shared_ptr<ARDOUR::AutomationControl> _mute_ctrl;
@@ -148,9 +148,10 @@ private:
void set_recarm ();
/* periodic poll, update view */
void set_strip_name ();
void periodic_update_fader ();
void periodic_update_meter ();
void periodic_update_timecode ();
void periodic_update_timecode (uint32_t);
void periodic ();
/* cache */
@@ -161,7 +162,7 @@ private:
/* display */
void set_strip_mode (uint8_t, bool clear = false);
void set_bar_mode (uint8_t);
void set_bar_mode (uint8_t, bool force = false);
uint8_t _strip_mode;
uint8_t _bar_mode;

View File

@@ -82,6 +82,7 @@ FP8GUI::FP8GUI (FaderPort8& p)
: fp (p)
, table (2, 3)
, ignore_active_change (false)
, two_line_text (_("Two Line Trackname"))
{
set_border_width (12);
@@ -106,9 +107,16 @@ FP8GUI::FP8GUI (FaderPort8& p)
input_combo.pack_start (midi_port_columns.short_name);
output_combo.pack_start (midi_port_columns.short_name);
build_prefs_combos ();
update_prefs_combos ();
input_combo.signal_changed().connect (sigc::bind (sigc::mem_fun (*this, &FP8GUI::active_port_changed), &input_combo, true));
output_combo.signal_changed().connect (sigc::bind (sigc::mem_fun (*this, &FP8GUI::active_port_changed), &output_combo, false));
clock_combo.signal_changed().connect (sigc::mem_fun (*this, &FP8GUI::clock_mode_changed));
scribble_combo.signal_changed().connect (sigc::mem_fun (*this, &FP8GUI::scribble_mode_changed));
two_line_text.signal_toggled().connect(sigc::mem_fun (*this, &FP8GUI::twolinetext_toggled));
l = manage (new Gtk::Label);
l->set_markup (string_compose ("<span weight=\"bold\">%1</span>", _("Incoming MIDI on:")));
l->set_alignment (1.0, 0.5);
@@ -161,6 +169,28 @@ FP8GUI::FP8GUI (FaderPort8& p)
table.attach (*vsep, 3 * c + 2, 3 * c + 3, row, row + 4, AttachOptions(0), AttachOptions(FILL), 6, 0);
}
row += 4;
hsep = manage(new Gtk::HSeparator);
table.attach (*hsep, 0, 8, row, row+1, AttachOptions(FILL|EXPAND), AttachOptions(0), 0, 6);
row++;
l = manage (new Gtk::Label);
l->set_markup (string_compose ("<span weight=\"bold\">%1</span>", _("Clock:")));
l->set_alignment (1.0, 0.5);
table.attach (*l, 0, 1, row, row+1, AttachOptions(FILL|EXPAND), AttachOptions(0));
table.attach (clock_combo, 1, 5, row, row+1, AttachOptions(FILL|EXPAND), AttachOptions(0), 0, 0);
table.attach (two_line_text, 5, 8, row, row+1, AttachOptions(FILL|EXPAND), AttachOptions(0), 0, 0);
row++;
l = manage (new Gtk::Label);
l->set_markup (string_compose ("<span weight=\"bold\">%1</span>", _("Display:")));
l->set_alignment (1.0, 0.5);
table.attach (*l, 0, 1, row, row+1, AttachOptions(FILL|EXPAND), AttachOptions(0));
table.attach (scribble_combo, 1, 5, row, row+1, AttachOptions(FILL|EXPAND), AttachOptions(0), 0, 0);
row++;
/* update the port connection combos */
update_port_combos ();
@@ -443,3 +473,93 @@ FP8GUI::action_changed (Gtk::ComboBox* cb, FP8Controls::ButtonId id)
string action_path = (*row)[action_columns.path];
fp.set_button_action (id, false, action_path);
}
void
FP8GUI::build_prefs_combos ()
{
vector<string> clock_strings;
vector<string> scribble_strings;
//clock_strings.push_back (_("Off"));
clock_strings.push_back (_("Timecode"));
clock_strings.push_back (_("BBT"));
clock_strings.push_back (_("Timecode + BBT"));
scribble_strings.push_back (_("Off"));
scribble_strings.push_back (_("Meter"));
scribble_strings.push_back (_("Pan"));
scribble_strings.push_back (_("Meter + Pan"));
set_popdown_strings (clock_combo, clock_strings);
set_popdown_strings (scribble_combo, scribble_strings);
}
void
FP8GUI::update_prefs_combos ()
{
switch (fp.clock_mode()) {
default:
clock_combo.set_active_text (_("Off"));
break;
case 1:
clock_combo.set_active_text (_("Timecode"));
break;
case 2:
clock_combo.set_active_text (_("BBT"));
break;
case 3:
clock_combo.set_active_text (_("Timecode + BBT"));
break;
}
switch (fp.scribble_mode()) {
default:
scribble_combo.set_active_text (_("Off"));
break;
case 1:
scribble_combo.set_active_text (_("Meter"));
break;
case 2:
scribble_combo.set_active_text (_("Pan"));
break;
case 3:
scribble_combo.set_active_text (_("Meter + Pan"));
break;
}
two_line_text.set_active (fp.twolinetext ());
}
void
FP8GUI::clock_mode_changed ()
{
string str = clock_combo.get_active_text();
if (str == _("BBT")) {
fp.set_clock_mode (2);
} else if (str == _("Timecode + BBT")) {
fp.set_clock_mode (3);
} else {
fp.set_clock_mode (1);
}
}
void
FP8GUI::scribble_mode_changed ()
{
string str = scribble_combo.get_active_text();
if (str == _("Off")) {
fp.set_scribble_mode (0);
} else if (str == _("Meter")) {
fp.set_scribble_mode (1);
} else if (str == _("Pan")) {
fp.set_scribble_mode (2);
} else {
fp.set_scribble_mode (3);
}
}
void
FP8GUI::twolinetext_toggled ()
{
fp.set_two_line_text (two_line_text.get_active ());
}

View File

@@ -25,6 +25,7 @@
#include <gtkmm/box.h>
#include <gtkmm/combobox.h>
#include <gtkmm/comboboxtext.h>
#include <gtkmm/image.h>
#include <gtkmm/table.h>
#include <gtkmm/treestore.h>
@@ -73,6 +74,17 @@ private:
Glib::RefPtr<Gtk::ListStore> build_midi_port_list (std::vector<std::string> const & ports, bool for_input);
void active_port_changed (Gtk::ComboBox*,bool for_input);
/* misc Prefs */
Gtk::ComboBoxText clock_combo;
Gtk::ComboBoxText scribble_combo;
Gtk::CheckButton two_line_text;
void build_prefs_combos ();
void update_prefs_combos ();
void clock_mode_changed ();
void scribble_mode_changed ();
void twolinetext_toggled ();
/* user actions */
void build_available_action_menu ();
void build_action_combo (Gtk::ComboBox& cb, FP8Controls::ButtonId id);