One Line to Skip Them All - One Line to Find Them

This makes total sense but then applying the same logic, why would an EVENT_HELD_MEDIUM prevent another EVENT_HELD_LONG from ever happening if the button was held long? Or is there a different logic for “HELD” ?

This one I knew about.

This one I had seen a while back, but I couldn’t remember the file/folder names to find them again.

Unfortunately past the “#ifndef stuff”, too much is gibberish to me.

For example:

      while (DebouncedRead() && (current_modifiers & button_)) {
        if (millis() - push_millis_ > BUTTON_HELD_TIMEOUT) {
          Send(EVENT_HELD);
          while (DebouncedRead() && (current_modifiers & button_)) {
            if (millis() - push_millis_ > BUTTON_HELD_MEDIUM_TIMEOUT){
              Send(EVENT_HELD_MEDIUM);
	      while (DebouncedRead() && (current_modifiers & button_)) {
                if (millis() - push_millis_ > BUTTON_HELD_LONG_TIMEOUT) {
                  Send(EVENT_HELD_LONG);
		  while (DebouncedRead() && (current_modifiers & button_)) YIELD();

What I understand from this is that as long as the button is being held, the event will not send. So I do not see the conflict between held medium and long.

Edit: Or is it the other way around ? And a short held will be sent asap ? Which doesn’t make sense why it would be programmed like that ?

"HELD"s are not saved.

Let’s lay it out:

  • When a button is pressed, an EVENT_PRESSED event is generated.
  • If the button is held for 300ms an EVENT_HELD_SHORT event is generated
  • If the button is held for 800ms an EVENT_HELD_MEDIUM event is generated
  • If the button is held for 2000ms an EVENT_HELD_LONG event is generated
  • When a button is released, an EVENT_RELEASED event is generated.
  • If the time between EVENT_PRESSED and EVENT_RELEASED was short, an EVENT_CLICK_SHORT event is generated right after EVENT_RELEASED
  • If the time between EVENT_PRESSED and EVENT_RELEASED was long (but not too long), an EVENT_CLICK_LOCK event is generated right after EVENT_RELEASED

So far, all the events are generated immediately. That means that EVENT_HELD_SHORT is generated 300ms after EVENT_PRESSED, and we don’t know yet how long the user will keep holding the button, and we don’t care.

However, there are some events that do care:

  • If an EVENT_CLICK_SHORT or EVENT_CLICK_LONG is generated, and the button is not pressed again for 500ms, an EVENT_CLICK_SHORT_SAVED, or EVENT_CLICK_LONG_SAVED is generated.
  • If on the other hand the button is clicked again within 500ms, then the list of events above is generated again. However, in addition to those there are event prefixes that can be used to keep track of how many short clicks occured before that event. So, for every event listed above, there is an EVENT_FIRST_* EVENT_SECOND_* EVENT_THIRD_* and an EVENT_FOURTH_* that you can use. EVENT_FIRST_SHORT_CLICKED_SAVED is generated 500ms after a single click for instance. EVENT_SECOND_LONG_CLICK is generated immmediately when you release the button after a short-long combination.

Only the numbered AND saved events are compatible with having one click do one thing and two clicks do something different. (And not trigger the first event.) For sabers where the number of functions is much higher than the number of buttons, those are the only events I recommend using, even though the 500ms delay can be a problem for some things.

I suppose that EVENT_HELD_LONG is also compatible with multiple clicks, because if you hold the button for 2.5 seconds, it’s too long to count as a long click.

3 Likes

Ok, this I understand, I will save this post for future reference as I doubt I can remember all of it. But it is a lot clearer now.

Thank you.