faderport: switch long-press mechanism to a timeout

This makes the long press action fire after the timeout even if the user is still holding the button,
which feels more satisfactory
This commit is contained in:
Paul Davis
2015-12-01 13:15:38 -05:00
parent 03a4926790
commit 37961a6bbe
2 changed files with 43 additions and 31 deletions

View File

@@ -120,6 +120,12 @@ FaderPort::FaderPort (Session& s)
buttons.insert (std::make_pair (RecEnable, Button (*this, _("RecEnable"), RecEnable, 0)));
buttons.insert (std::make_pair (FaderTouch, Button (*this, _("Fader (touch)"), FaderTouch, -1)));
get_button (Shift).set_flash (true);
get_button (Mix).set_flash (true);
get_button (Proj).set_flash (true);
get_button (Trns).set_flash (true);
get_button (User).set_flash (true);
get_button (Left).set_action ( boost::bind (&FaderPort::left, this), true);
get_button (Right).set_action ( boost::bind (&FaderPort::right, this), true);
@@ -269,13 +275,38 @@ FaderPort::get_button (ButtonID id) const
return const_cast<Button&>(b->second);
}
bool
FaderPort::button_long_press_timeout (ButtonID id)
{
if (buttons_down.find (id) != buttons_down.end()) {
get_button (id).invoke (ButtonState (LongPress|button_state), false);
} else {
/* release happened and somehow we were not cancelled */
}
return false; /* don't get called again */
}
void
FaderPort::start_press_timeout (Button& button, ButtonID id)
{
Glib::RefPtr<Glib::TimeoutSource> timeout = Glib::TimeoutSource::create (500); // milliseconds
button.timeout_connection = timeout->connect (sigc::bind (sigc::mem_fun (*this, &FaderPort::button_long_press_timeout), id));
timeout->attach (main_loop()->get_context());
}
void
FaderPort::button_handler (MIDI::Parser &, MIDI::EventTwoBytes* tb)
{
ButtonID id (ButtonID (tb->controller_number));
Button& button (get_button (id));
button.do_timing (tb->value ? true : false);
if (tb->value) {
buttons_down.insert (id);
} else {
buttons_down.erase (id);
button.timeout_connection.disconnect ();
}
switch (id) {
case Shift:
@@ -305,6 +336,9 @@ FaderPort::button_handler (MIDI::Parser &, MIDI::EventTwoBytes* tb)
}
break;
default:
if (tb->value) {
start_press_timeout (button, id);
}
break;
}
@@ -717,12 +751,6 @@ FaderPort::Button::invoke (FaderPort::ButtonState bs, bool press)
{
DEBUG_TRACE (DEBUG::FaderPort, string_compose ("invoke button %1 for %2 state %3%4%5\n", id, (press ? "press":"release"), hex, bs, dec));
if (!press) {
if (long_press) {
bs = FaderPort::ButtonState (bs | LongPress);
}
}
ToDoMap::iterator x;
if (press) {
@@ -750,25 +778,6 @@ FaderPort::Button::invoke (FaderPort::ButtonState bs, bool press)
}
}
void
FaderPort::Button::do_timing (bool press)
{
if (press) {
pressed_at = get_microseconds ();
long_press = false;
} else {
if (pressed_at > 0) {
const ARDOUR::microseconds_t delta = ARDOUR::get_microseconds () - pressed_at;
if (delta < 1000000) {
long_press = false;
} else {
long_press = true;
}
pressed_at = 0;
}
}
}
void
FaderPort::Button::set_action (string const& name, bool when_pressed, FaderPort::ButtonState bs)
{

View File

@@ -22,6 +22,7 @@
#include <list>
#include <map>
#include <set>
#include <glibmm/threads.h>
#define ABSTRACT_UI_EXPORTS
@@ -215,8 +216,6 @@ class FaderPort : public ARDOUR::ControlProtocol, public AbstractUI<FaderPortReq
, out (o)
, led_on (false)
, flash (false)
, pressed_at (0)
, long_press (false)
{}
void set_action (std::string const& action_name, bool on_press, FaderPort::ButtonState = ButtonState (0));
@@ -227,11 +226,12 @@ class FaderPort : public ARDOUR::ControlProtocol, public AbstractUI<FaderPortReq
void invoke (ButtonState bs, bool press);
bool uses_flash () const { return flash; }
void set_flash (bool yn) { flash = yn; }
void do_timing (bool press);
XMLNode& get_state () const;
int set_state (XMLNode const&);
sigc::connection timeout_connection;
private:
FaderPort& fp;
std::string name;
@@ -239,8 +239,6 @@ class FaderPort : public ARDOUR::ControlProtocol, public AbstractUI<FaderPortReq
int out;
bool led_on;
bool flash;
ARDOUR::microseconds_t pressed_at;
bool long_press;
struct ToDo {
ActionType type;
@@ -261,6 +259,11 @@ class FaderPort : public ARDOUR::ControlProtocol, public AbstractUI<FaderPortReq
ButtonMap buttons;
Button& get_button (ButtonID) const;
std::set<ButtonID> buttons_down;
bool button_long_press_timeout (ButtonID id);
void start_press_timeout (Button&, ButtonID);
void all_lights_out ();
void close ();
void start_midi_handling ();