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:
@@ -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)
|
||||
{
|
||||
|
||||
@@ -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 ();
|
||||
|
||||
Reference in New Issue
Block a user