fadeport: restructure button info actions to allow modifiers (shift, rewind, stop) and set up undo and shift-undo (redo)
This commit is contained in:
parent
7c8cc3cfa9
commit
3a86b386fa
|
@ -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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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 ();
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -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"' ]
|
||||||
|
|
Loading…
Reference in New Issue
Block a user