13
0

fadeport: restructure button info actions to allow modifiers (shift, rewind, stop) and set up undo and shift-undo (redo)

This commit is contained in:
Paul Davis 2015-11-24 22:32:40 -05:00
parent 7c8cc3cfa9
commit 3a86b386fa
3 changed files with 79 additions and 29 deletions

View File

@ -1,5 +1,5 @@
/* /*
Copyright (C) 2006 Paul Davis Copyright (C) 2015 Paul Davis
This program is free software; you can redistribute it and/or modify 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 it under the terms of the GNU General Public License as published by
@ -68,6 +68,7 @@ FaderPort::FaderPort (Session& s)
, _device_active (false) , _device_active (false)
, fader_msb (0) , fader_msb (0)
, fader_lsb (0) , fader_lsb (0)
, button_state (ButtonState (0))
{ {
boost::shared_ptr<ARDOUR::Port> inp; boost::shared_ptr<ARDOUR::Port> inp;
boost::shared_ptr<ARDOUR::Port> outp; boost::shared_ptr<ARDOUR::Port> outp;
@ -122,7 +123,8 @@ FaderPort::FaderPort (Session& s)
buttons.insert (std::make_pair (RecEnable, ButtonInfo (*this, _("RecEnable"), RecEnable, 0))); buttons.insert (std::make_pair (RecEnable, ButtonInfo (*this, _("RecEnable"), RecEnable, 0)));
buttons.insert (std::make_pair (FaderTouch, ButtonInfo (*this, _("Fader (touch)"), FaderTouch, -1))); buttons.insert (std::make_pair (FaderTouch, ButtonInfo (*this, _("Fader (touch)"), FaderTouch, -1)));
button_info (Undo).set_action (boost::bind (&BasicUI::undo, this), true); button_info (Undo).set_action (boost::bind (&FaderPort::undo, this), true);
button_info (Undo).set_action (boost::bind (&FaderPort::redo, this), true, ButtonState (ShiftDown));
button_info (Undo).set_flash (true); button_info (Undo).set_flash (true);
button_info (Play).set_action (boost::bind (&BasicUI::transport_play, this, false), true); button_info (Play).set_action (boost::bind (&BasicUI::transport_play, this, false), true);
@ -255,11 +257,29 @@ FaderPort::button_info (ButtonID id) const
void void
FaderPort::switch_handler (MIDI::Parser &, MIDI::EventTwoBytes* tb) FaderPort::switch_handler (MIDI::Parser &, MIDI::EventTwoBytes* tb)
{ {
ButtonInfo& bi (button_info ((ButtonID) tb->controller_number)); ButtonID id (ButtonID (tb->controller_number));
switch (id) {
case Shift:
button_state = (tb->value ? ButtonState (button_state|ShiftDown) : ButtonState (button_state&~ShiftDown));
break;
case Stop:
button_state = (tb->value ? ButtonState (button_state|StopDown) : ButtonState (button_state&~StopDown));
break;
case Rewind:
button_state = (tb->value ? ButtonState (button_state|RewindDown) : ButtonState (button_state&~RewindDown));
break;
default:
break;
}
ButtonInfo& bi (button_info (id));
if (bi.uses_flash()) { if (bi.uses_flash()) {
bi.set_led_state (_output_port, (int)tb->value); bi.set_led_state (_output_port, (int)tb->value);
} }
bi.invoke (ButtonState (0), tb->value ? true : false);
bi.invoke (button_state, tb->value ? true : false);
} }
void void
@ -613,23 +633,35 @@ FaderPort::ButtonInfo::invoke (FaderPort::ButtonState bs, bool press)
switch (type) { switch (type) {
case NamedAction: case NamedAction:
if (press) { if (press) {
if (!on_press.action_name.empty()) { ToDoMap::iterator x = on_press.find (bs);
fp.access_action (on_press.action_name); if (x != on_press.end()) {
if (!x->second.action_name.empty()) {
fp.access_action (x->second.action_name);
}
} }
} else { } else {
if (!on_release.action_name.empty()) { ToDoMap::iterator x = on_release.find (bs);
fp.access_action (on_press.action_name); if (x != on_release.end()) {
if (!x->second.action_name.empty()) {
fp.access_action (x->second.action_name);
}
} }
} }
break; break;
case InternalFunction: case InternalFunction:
if (press) { if (press) {
if (on_press.function) { ToDoMap::iterator x = on_press.find (bs);
on_press.function (); if (x != on_press.end()) {
if (x->second.function) {
x->second.function ();
}
} }
} else { } else {
if (on_release.function) { ToDoMap::iterator x = on_release.find (bs);
on_release.function (); if (x != on_release.end()) {
if (x->second.function) {
x->second.function ();
}
} }
} }
break; break;
@ -637,24 +669,34 @@ FaderPort::ButtonInfo::invoke (FaderPort::ButtonState bs, bool press)
} }
void void
FaderPort::ButtonInfo::set_action (string const& name, bool when_pressed) FaderPort::ButtonInfo::set_action (string const& name, bool when_pressed, FaderPort::ButtonState bs)
{ {
ToDo todo;
type = NamedAction; type = NamedAction;
if (when_pressed) { if (when_pressed) {
on_press.action_name = name; todo.action_name = name;
on_press[bs] = todo;
} else { } else {
on_release.action_name = name; todo.action_name = name;
on_release[bs] = todo;
} }
} }
void void
FaderPort::ButtonInfo::set_action (boost::function<void()> f, bool when_pressed) FaderPort::ButtonInfo::set_action (boost::function<void()> f, bool when_pressed, FaderPort::ButtonState bs)
{ {
ToDo todo;
type = InternalFunction; type = InternalFunction;
if (when_pressed) { if (when_pressed) {
on_press.function = f; todo.function = f;
on_press[bs] = todo;
} else { } else {
on_release.function = f; todo.function = f;
on_release[bs] = todo;
} }
} }

View File

@ -201,9 +201,9 @@ class FaderPort : public ARDOUR::ControlProtocol, public AbstractUI<FaderPortReq
}; };
enum ButtonState { enum ButtonState {
ShiftDown, ShiftDown = 0x1,
RewindDown, RewindDown = 0x2,
StopDown, StopDown = 0x4,
}; };
ButtonState button_state; ButtonState button_state;
@ -228,8 +228,8 @@ class FaderPort : public ARDOUR::ControlProtocol, public AbstractUI<FaderPortReq
, flash (false) , flash (false)
{} {}
void set_action (std::string const& action_name, bool on_press); void set_action (std::string const& action_name, bool on_press, FaderPort::ButtonState = ButtonState (0));
void set_action (boost::function<void()> function, bool on_press); void set_action (boost::function<void()> function, bool on_press, FaderPort::ButtonState = ButtonState (0));
void set_led_state (boost::shared_ptr<MIDI::Port>, int onoff); void set_led_state (boost::shared_ptr<MIDI::Port>, int onoff);
void invoke (ButtonState bs, bool press); void invoke (ButtonState bs, bool press);
bool uses_flash () const { return flash; } bool uses_flash () const { return flash; }
@ -244,15 +244,17 @@ class FaderPort : public ARDOUR::ControlProtocol, public AbstractUI<FaderPortReq
bool led_on; bool led_on;
bool flash; bool flash;
struct { /* could be a union if boost::function didn't require a
* constructor
*/
struct ToDo {
std::string action_name; std::string action_name;
boost::function<void()> function; boost::function<void()> function;
} on_press; };
struct { typedef std::map<FaderPort::ButtonState,ToDo> ToDoMap;
std::string action_name; ToDoMap on_press;
boost::function<void()> function; ToDoMap on_release;
} on_release;
}; };
typedef std::map<ButtonID,ButtonInfo> ButtonMap; typedef std::map<ButtonID,ButtonInfo> ButtonMap;
@ -266,6 +268,11 @@ class FaderPort : public ARDOUR::ControlProtocol, public AbstractUI<FaderPortReq
void close (); void close ();
void start_midi_handling (); void start_midi_handling ();
void stop_midi_handling (); void stop_midi_handling ();
/* operations (defined in operations.cc) */
void undo ();
void redo ();
}; };
} }

View File

@ -18,6 +18,7 @@ def build(bld):
faderport.cc faderport.cc
gui.cc gui.cc
faderport_interface.cc faderport_interface.cc
operations.cc
''' '''
obj.export_includes = ['.'] obj.export_includes = ['.']
obj.defines = [ 'PACKAGE="ardour_faderport"' ] obj.defines = [ 'PACKAGE="ardour_faderport"' ]