Raspberry Pi Weighting Control System
This project serves as a simple weighting control system, that was realized as a Bachelor Thesis
Functions | Variables
event_handler Namespace Reference

Functions

template<typename Base , typename T >
bool instanceof (const T *ptr)
 
SDL_Scancode determine_scancode (uint16_t keycode, uint8_t cycle=0)
 Determines SDL_Scancode from SPI keyboard keycode and cycle. Cycle is used to cycle keys during text input. More...
 
SDL_Event create_key_event (SDL_Scancode scancode, Uint16 mod=0)
 Creates an SDL_Event simulating keyboard press from SDL_Scancode. More...
 
SDL_Event create_textinput_event (SDL_Scancode scancode)
 Creates an SDL_Event for input. More...
 
void push_event_to_sdl (SDL_Event *event, bool replace_cur_char=false)
 Pushes event to SDL queue. This event then can be propagated to ImGui. If @replace_cur_char is set, ten a BACKSPACE event is pushed first. More...
 
bool can_switch_modes ()
 Determine if keyboard can be switched to INPUT mode. More...
 
int handle_return_event ()
 Handles return event (NAVIGATION/INPUT mode switch, BUTTON/ COMBOOX... activation) More...
 
int handle_nav_event (kb_event *raw_event)
 Handle event as navigation event. More...
 
int handle_input_event (kb_event *raw_event)
 Handle event as input event. More...
 
int handle_raw_event (kb_event *raw_event)
 Offers option for cutom event handling. If not desired only created SDL event. More...
 
int handle_sdl_event (const SDL_Event *event)
 Handles SDL2 library event. More...
 
int focused_element_action (gui_element *element)
 
int rfid_action_user_logged (rfid_event *event)
 
int handle_rfid_event (rfid_event *event)
 Function handles RFID event. More...
 

Variables

std::map< uint16_t, SDL_Scancode > navigation_keymap
 Map for translating SPI keyboard scancodes keys to SDL scancodes for navigation. More...
 
std::map< uint16_t, SDL_Scancode > int_in_keymap
 int input map that is used for mapping spi keys to sdl scancodes More...
 
std::map< uint16_t, SDL_Scancode > float_in_keymap
 float input map that is used for mapping spi keys to sdl scancodes More...
 
std::map< uint16_t, std::vector< SDL_Scancode > > text_in_keymap
 Text input keymap. Holds what scancodes are cycled for corresponding key. First value should correspond to the physical key value ("picture" on keyboard). Some keys are currently disabled. Either because they are reserved or have no use. More...
 
std::map< SDL_Scancode, const char * > custom_keymap
 
std::map< SDL_Scancode, const char * > custom_shift_keymap
 

Function Documentation

◆ can_switch_modes()

bool event_handler::can_switch_modes ( )

Determine if keyboard can be switched to INPUT mode.

Definition at line 502 of file event_handler.cpp.

502  {
503  screen_manager *scr_mgr = app_workspace::get_instance()->get_scr_mgr();
504  std::unique_ptr<app_workspace_ns::kb_input_state> &kbins = app_workspace::get_instance()->kb_in_state;
505 
506  if (kbins->current_mode != app_workspace_ns::kb_input_mode::NAVIGATION)
507  return false;
508 
509  if (scr_mgr->activated)
510  return false;
511 
512  // for now only gui_input can be activated
513  if (!instanceof<gui_input>(scr_mgr->focused))
514  return false;
515 
516  return true;
517  }
static std::unique_ptr< app_workspace > & get_instance()
Get the instance app_workspace which is a singleton.
gui_element * focused
gui_element * activated

◆ create_key_event()

SDL_Event event_handler::create_key_event ( SDL_Scancode  scancode,
Uint16  mod = 0 
)

Creates an SDL_Event simulating keyboard press from SDL_Scancode.

Parameters
scancodescancode of keyboard key
mod
Returns
SDL_Event

Definition at line 418 of file event_handler.cpp.

418  {
419  SDL_Event event;
420 
421  event.type = SDL_KEYDOWN;
422  event.key.timestamp = SDL_GetTicks();
423  event.key.keysym.scancode = scancode;
424  event.key.keysym.sym = SDL_GetKeyFromScancode(scancode);
425  event.key.keysym.mod = mod;
426  event.key.state = 1;
427 
428  return event;
429  }

◆ create_textinput_event()

SDL_Event event_handler::create_textinput_event ( SDL_Scancode  scancode)

Creates an SDL_Event for input.

Parameters
scancodeinput value
Returns
SDL_Event

Definition at line 431 of file event_handler.cpp.

431  {
432  SDL_Event txt_in;
433  txt_in.type = SDL_TEXTINPUT;
434 
435  try {
436  const char* txt;
437 
438  if (app_workspace::get_instance()->lshift_flag) {
439  try {
440  txt = custom_shift_keymap.at(scancode);
441  strcpy(txt_in.text.text, txt);
442  return txt_in;
443  } catch (std::out_of_range &ex) {
444  // no action, maybe log debug - if scancode isn't in shift_keymap, try looking in normal keymap
445  }
446  }
447 
448  txt = custom_keymap.at(scancode);
449 
450  // if the code is in cutom keymaps, use that instead of general SDL
451  strcpy(txt_in.text.text, txt);
452  return txt_in;
453  } catch (std::out_of_range &ex) {
454  spdlog::debug("event_handler.cpp - Custom keymaps are missing request scancode ({0})", scancode);
455  }
456 
457  strcpy(txt_in.text.text, SDL_GetScancodeName(scancode));
458  // if scancode is a letter between A-Z and capslock is off, make lower case
459  if (scancode >= SDL_SCANCODE_A && scancode <= SDL_SCANCODE_Z && !app_workspace::get_instance()->capslock_flag) {
460  for (size_t i = 0; i < strlen(txt_in.text.text); i++) {
461  txt_in.text.text[i] = std::tolower(txt_in.text.text[i]);
462  }
463  }
464 
465  return txt_in;
466  }
std::map< SDL_Scancode, const char * > custom_shift_keymap
std::map< SDL_Scancode, const char * > custom_keymap

◆ determine_scancode()

SDL_Scancode event_handler::determine_scancode ( uint16_t  keycode,
uint8_t  cycle = 0 
)

Determines SDL_Scancode from SPI keyboard keycode and cycle. Cycle is used to cycle keys during text input.

Parameters
keycodeSPI keyboard
cyclerepeted pressed withnin a time limit
Returns
SDL_Scancode

Definition at line 381 of file event_handler.cpp.

381  {
382  std::unique_ptr<app_workspace_ns::kb_input_state> &kbins = app_workspace::get_instance()->kb_in_state;
383 
384  try {
385  if (kbins->current_mode == app_workspace_ns::kb_input_mode::NAVIGATION) {
386  return navigation_keymap.at(keycode);
387  } else if (kbins->current_mode == app_workspace_ns::kb_input_mode::INPUT) {
388  switch (kbins->current_type) {
390  return float_in_keymap.at(keycode);
391  } break;
393  return int_in_keymap.at(keycode);
394  } break;
396  std::vector<SDL_Scancode> opts = text_in_keymap.at(keycode);
397  return opts[cycle % opts.size()];
398  } break;
400  default:
401  spdlog::error("keyboard.cpp - This kb_input_type has no keymap");
402  }
403  } else {
404  spdlog::error("keyboard.cpp - Unknown kb_input_mode");
405  }
406  } catch (const std::out_of_range& ex) {
407  /* logging disabled, because of many key options, that are not specified in maps
408  spdlog::error("keyboard.cpp - Failed to find event for pressed key.");
409  spdlog::error("\t\t\t - 1) Key doesn't have event in selected input mode and type");
410  spdlog::error("\t\t\t - 2) Multiple keys pressed at once (unrecognized key value)");
411  */
412  return SDL_SCANCODE_CLEAR;
413  }
414 
415  return SDL_SCANCODE_CLEAR;
416  }
std::map< uint16_t, SDL_Scancode > navigation_keymap
Map for translating SPI keyboard scancodes keys to SDL scancodes for navigation.
std::map< uint16_t, SDL_Scancode > int_in_keymap
int input map that is used for mapping spi keys to sdl scancodes
std::map< uint16_t, SDL_Scancode > float_in_keymap
float input map that is used for mapping spi keys to sdl scancodes
std::map< uint16_t, std::vector< SDL_Scancode > > text_in_keymap
Text input keymap. Holds what scancodes are cycled for corresponding key. First value should correspo...

◆ focused_element_action()

int event_handler::focused_element_action ( gui_element element)
Parameters
element
Returns
int - temp: 1 when action is taken, 0 when function reaches end without any action

Definition at line 525 of file event_handler.cpp.

525  {
526  // for debug purposes
527  if (instanceof<gui_button>(element)) {
528  spdlog::debug("event_handler.cpp - action of focused element BUTTON");
529  } else if (instanceof<gui_combobox>(element)) {
530  spdlog::debug("event_handler.cpp - action of focused element COMBOBOX");
531  } else if (instanceof<gui_direct>(element)) {
532  spdlog::debug("event_handler.cpp - action of focused element DIRECT");
533  } else if (instanceof<gui_label>(element)) {
534  spdlog::debug("event_handler.cpp - action of focused element LABEL");
535  } else if (instanceof<gui_observer>(element)) {
536  spdlog::debug("event_handler.cpp - action of focused element OBSERVER");
537  } else if (instanceof<gui_selectable>(element)) {
538  spdlog::debug("event_handler.cpp - action of focused element SELECTABLE");
539  }else {
540  spdlog::debug("event_handler.cpp - action of focused element UNKNOWN");
541  }
542 
543  // handling button action - it needs to send TEXT_INPUT event as well
544  if (instanceof<gui_button>(element) || instanceof<gui_combobox>(element) ||
545  instanceof<gui_selectable>(element) || combo_expanded)
546  {
547  // on normal keyboard button callback is activated with "spacebar"
548  // events are: KEYDOWN - SPACE, TEXTINPUT - SPACE, KEYUP - SPACE
549  // only TEXTINPUT - SPACE might be enough to invoke callback (not tested!!!)
550 
551  spdlog::debug("event_handler.cpp - creating action event");
552 
553  SDL_Event ret = create_key_event(SDL_SCANCODE_SPACE, 0);
554  SDL_PushEvent(&ret);
555 
556  SDL_Event txt_input = create_textinput_event(ret.key.keysym.scancode);
557  SDL_PushEvent(&txt_input); // pushes TEXTINPUT_EVENT of pressed key
558 
559  ret.type = SDL_KEYUP;
560  ret.key.state = 0;
561  SDL_PushEvent(&ret); // pushes KEY_UP event
562 
563  if (instanceof<gui_combobox>(element) || combo_expanded) {
564  combo_expanded = !combo_expanded; // if activating/ deactivating combo set this flag
565  spdlog::debug("event_handler.cpp - setting combo_expanded flag to {0}", combo_expanded);
566  }
567 
568  return 1;
569  }
570 
571  return 0;
572  }
SDL_Event create_key_event(SDL_Scancode scancode, Uint16 mod=0)
Creates an SDL_Event simulating keyboard press from SDL_Scancode.
SDL_Event create_textinput_event(SDL_Scancode scancode)
Creates an SDL_Event for input.

◆ handle_input_event()

int event_handler::handle_input_event ( kb_event raw_event)

Handle event as input event.

Definition at line 666 of file event_handler.cpp.

666  {
667  std::unique_ptr<app_workspace_ns::kb_input_state> &kbins = app_workspace::get_instance()->kb_in_state;
668  SDL_Event event;
669  SDL_Scancode sc;
670 
671  // custom event handling here, doesn't need to be sent tro SDL
672 
673  // if input is text, determine if the key_should be cycled (e.g.: 2 = A/B/C)
674  if (kbins->current_type == app_workspace_ns::kb_input_type::TEXT) {
675  uint32_t delta_t = UINT32_MAX;
676  // time since last event in us
677  if (last_raw_event != nullptr) {
678  delta_t = (raw_event->timestamp.tv_sec - last_raw_event->timestamp.tv_sec) * 1000000 +
679  (raw_event->timestamp.tv_usec - last_raw_event->timestamp.tv_usec);
680  if (last_raw_event->scancode == raw_event->scancode && delta_t < 2000000) //
681  key_cycle++;
682  else
683  key_cycle = 0;
684  } else {
685  key_cycle = 0;
686  }
687 
688  last_raw_event = raw_event;
689  }
690 
691  sc = determine_scancode(raw_event->scancode, key_cycle);
692  if (sc == SDL_SCANCODE_CLEAR)
693  return 0;
694 
695  // those flags could be handled in key_cycle branch which would be a bit more efficient, but this is more readable
696  // DO NOT create event for mod keys
697  if (sc == SDL_SCANCODE_LSHIFT) {
698  app_workspace::get_instance()->lshift_flag = !app_workspace::get_instance()->lshift_flag;
699  return 1;
700  }
701  if (sc == SDL_SCANCODE_CAPSLOCK) {
702  app_workspace::get_instance()->capslock_flag = !app_workspace::get_instance()->capslock_flag;
703  return 1;
704  }
705 
706  // doesn't do anything
707  Uint16 mod = 0;
708  if (app_workspace::get_instance()->lshift_flag) mod |= KMOD_LSHIFT;
709  if (app_workspace::get_instance()->capslock_flag) mod |= KMOD_CAPS;
710 
711  event = create_key_event(sc, mod);
712  push_event_to_sdl(&event, key_cycle > 0);
713 
714  return 1;
715  }
void push_event_to_sdl(SDL_Event *event, bool replace_cur_char=false)
Pushes event to SDL queue. This event then can be propagated to ImGui. If @replace_cur_char is set,...
SDL_Scancode determine_scancode(uint16_t keycode, uint8_t cycle=0)
Determines SDL_Scancode from SPI keyboard keycode and cycle. Cycle is used to cycle keys during text ...
struct timeval timestamp
Definition: keyboard.h:26
uint16_t scancode
Definition: keyboard.h:24

◆ handle_nav_event()

int event_handler::handle_nav_event ( kb_event raw_event)

Handle event as navigation event.

Definition at line 635 of file event_handler.cpp.

635  {
636  screen_manager *scr_mgr = app_workspace::get_instance()->get_scr_mgr();
637  SDL_Event event;
638  SDL_Scancode sc;
639 
640  // custom event handling here, doesn't need to be sent tro SDL
641 
642  sc = determine_scancode(raw_event->scancode);
643  if (sc == SDL_SCANCODE_CLEAR)
644  return 0;
645 
646  // 1-9 isn't send to SDL
647  if (sc >= SDL_SCANCODE_1 && sc < SDL_SCANCODE_0) {
648  uint8_t screen_no = strtol(SDL_GetScancodeName(sc), NULL, 10);
649  scr_mgr->set_selected_screen(screen_no);
650  return 1;
651  }
652 
653  // 0 sends backspace - serves to go to previous screen
654  if (sc == SDL_SCANCODE_BACKSPACE) {
655  scr_mgr->pop_screen_from_previous();
656  return 1; // not needed to send backspace during navigation to sdl (would be handled twice)
657  }
658 
659  // create SDL event for keys other than 1-9: eg.: "arrow" UP, DOWN for nav
660  event = create_key_event(sc);
661  push_event_to_sdl(&event);
662 
663  return 1;
664  }
void pop_screen_from_previous()
void set_selected_screen(uint8_t screen)

◆ handle_raw_event()

int event_handler::handle_raw_event ( kb_event raw_event)

Offers option for cutom event handling. If not desired only created SDL event.

Function that handles SPI keyboard event.

Parameters
raw_eventSPI keyboard event
Returns
int - currently not used anywhere
Parameters
raw_eventSPI kb event
Returns
int

Definition at line 242 of file event_handler.cpp.

242  {
243  if (app_workspace::get_instance()->hx_measuring || app_workspace::get_instance()->get_kb_testing()) {
244  if (raw_event->scancode == 0x2000 &&
245  !(raw_event->flags & KB_FLAGS_REPEATING) && (raw_event->flags & KB_FLAGS_KEY_DOWN))
246  {
247  if (app_workspace::get_instance()->hx_measuring) {
248  app_workspace::get_instance()->hx711_controller->stop_reading();
249  app_workspace::get_instance()->hx_continuous = false;
250  app_workspace::get_instance()->hx_not_finished_yet = true;
251  app_workspace::get_instance()->refresh_current_screen = true;
252  spdlog::info("event_handler.cpp - Recieved event to stop continuous measuring. Stopping...");
253  } else {
254  app_workspace::get_instance()->set_kb_testing(false);
255  app_workspace::get_instance()->get_scr_mgr()->set_selected_screen(ADMIN_SELECT_SCREEN);
256  app_workspace::get_instance()->get_scr_mgr()->refresh_screen_elements(ADMIN_SELECT_SCREEN);
257  }
258  return 0;
259  }
260 
261  spdlog::debug("event_handler.cpp - Not handling keyboard events because a hx measuring is ongoing.");
262  return 0;
263  }
264 
265  if (raw_event->flags & KB_FLAGS_TEST) {
266  return 0;
267  }
268 
269  std::unique_ptr<app_workspace_ns::kb_input_state> &kbins = app_workspace::get_instance()->kb_in_state;
270 
271  spdlog::debug("Handling raw event: {0}", raw_event->scancode);
272 
273  // handling '#' used as return - always the same action (considered key exception, doesn't go to lookup maps)
274  // only handle on first event KEY DOWN
275  if (raw_event->scancode == 0x2000 &&
276  !(raw_event->flags & KB_FLAGS_REPEATING) &&
277  (raw_event->flags & KB_FLAGS_KEY_DOWN))
278  {
279  return handle_return_event();
280  }
281 
282  if (raw_event->flags & KB_FLAGS_KEY_DOWN) { // handling KEY_DOWN events
283  if (!(raw_event->flags & KB_FLAGS_REPEATING)) { // only first event (not continous hold events)
284  if (kbins->current_mode == app_workspace_ns::kb_input_mode::NAVIGATION)
285  return handle_nav_event(raw_event);
286 
287  if (kbins->current_mode == app_workspace_ns::kb_input_mode::INPUT)
288  return handle_input_event(raw_event);
289  }
290  }
291 
292  return 1;
293  }
@ KB_FLAGS_REPEATING
Definition: keyboard.h:14
@ KB_FLAGS_TEST
Definition: keyboard.h:15
@ KB_FLAGS_KEY_DOWN
Definition: keyboard.h:13
int handle_return_event()
Handles return event (NAVIGATION/INPUT mode switch, BUTTON/ COMBOOX... activation)
int handle_nav_event(kb_event *raw_event)
Handle event as navigation event.
int handle_input_event(kb_event *raw_event)
Handle event as input event.
#define ADMIN_SELECT_SCREEN
uint8_t flags
Definition: keyboard.h:25

◆ handle_return_event()

int event_handler::handle_return_event ( )

Handles return event (NAVIGATION/INPUT mode switch, BUTTON/ COMBOOX... activation)

Returns
int - temp: 1 when action is performed, 0 when function reachec end without action

Definition at line 579 of file event_handler.cpp.

579  {
580  screen_manager *scr_mgr = app_workspace::get_instance()->get_scr_mgr();
582  SDL_Event event;
583 
584  /* how this works: if in navigation - enter on input enters input mode
585  - enter on combobox/ button "activate event"
586  if in input mode - enter exits input mode
587  */
588 
589 
590  spdlog::debug("event_handler.cpp - handling RETURN raw event");
591 
593  spdlog::debug("event_handler.cpp - switching input mode from INPUT to NAVIGATION");
594 
595  event = create_key_event(SDL_SCANCODE_RETURN, 0);
596  push_event_to_sdl(&event, false);
598 
599  // disable flags when exiting input mode (not necessary, does the same on input)
600  app_workspace::get_instance()->lshift_flag = false;
601  app_workspace::get_instance()->capslock_flag = false;
602 
603  return 1;
604  }
605 
606  // see can_switch_modes for condition to enter INPUT mode
607  if (can_switch_modes()) {
608  spdlog::debug("event_handler.cpp - switching input mode from NAVIGATION to INPUT");
609 
610  // disable flags when entering input mode
611  app_workspace::get_instance()->lshift_flag = false;
612  app_workspace::get_instance()->capslock_flag = false;
613 
614  event = create_key_event(SDL_SCANCODE_RETURN, 0);
615  push_event_to_sdl(&event, false);
616 
618  // can_switch_modes() checks that focused is instanceof gui_input
619  kbins->current_type = ((gui_input*) scr_mgr->focused)->get_in_type();
620  spdlog::debug("event_handler.cpp - input type: {0}", kbins->current_type);
621 
622  return 1;
623  }
624 
625  // when combo is expanded, an element IS focused, but it ISN'T any element from screen definition
626  if (scr_mgr->focused || combo_expanded) {
627  spdlog::debug("event_handler.cpp - calling focused element action");
628  return focused_element_action(scr_mgr->focused);
629  }
630 
631  spdlog::debug("event_handler.cpp - handling RETURN raw event with no action");
632  return 0;
633  }
This is a wrapper for various ImGui input types.
Definition: gui_input.h:24
bool can_switch_modes()
Determine if keyboard can be switched to INPUT mode.
int focused_element_action(gui_element *element)
Structure holding the values of keyboard input mode and input type.
Definition: app_workspace.h:96

◆ handle_rfid_event()

int event_handler::handle_rfid_event ( rfid_event event)

Function handles RFID event.

Parameters
eventRFID event, contains rfid_tag structure
Returns
int

Definition at line 762 of file event_handler.cpp.

762  {
763  if (app_workspace::get_instance()->hx_measuring) {
764  spdlog::debug("event_handler.cpp - Not handling keyboard events, because a hx measuring is ongoing.");
765  return 1;
766  }
767 
768  spdlog::info("event_handler.cpp - handling RFID event");
769  app_workspace *app_wrk = app_workspace::get_instance().get();
770 
771  printf("RFID serial: ");
772  for (int i = 0; i < event->tag.serial_size; i++) {
773  printf("%02x(%d) ", event->tag.serial[i], event->tag.serial[i]);
774  }
775  printf("\n");
776 
777  if (!(event->flags & RFID_FLAGS_REPEATING)) {
778  if (app_wrk->has_user()) {
779  return rfid_action_user_logged(event);
780  } else {
781  if (app_wrk->get_scr_mgr()->get_selected_screen() == 1) {
782  app_wrk->log_in_user_rfid(&(event->tag), false);
783  } else {
784  spdlog::error("event_handler.cpp - No user logged in. RFID login only possible from screen 1.");
785  }
786  }
787  }
788 
789  return 0;
790  }
One of the most importat classes in the whole project. Holds variables that define the state of the a...
int log_in_user_rfid(rfid_reader::rfid_tag *tag, bool loading_sub=false)
Logs in user through scanned RFID tag. Initializes user_workspace if loading_sub is false.
bool has_user()
Checks if user is logged in. This is determined by user_space being initialized and having the user_l...
screen_manager * get_scr_mgr()
Get the screen manager instance. This instance is kind of singleton. Is initalized only once on start...
uint8_t get_selected_screen()
int rfid_action_user_logged(rfid_event *event)
@ RFID_FLAGS_REPEATING
Definition: rfid_reader.h:93
uint8_t flags
Definition: rfid_reader.h:102
rfid_reader::rfid_tag tag
Definition: rfid_reader.h:101
uint8_t serial[10]
Definition: rfid_reader.h:14

◆ handle_sdl_event()

int event_handler::handle_sdl_event ( const SDL_Event *  event)

Handles SDL2 library event.

Parameters
eventSDL event
Returns
int

Definition at line 298 of file event_handler.cpp.

298  {
299  screen_manager *scr_mgr = app_workspace::get_instance()->get_scr_mgr();
300  // reference to KeyBoardINputState (kbins)
301  std::unique_ptr<app_workspace_ns::kb_input_state> &kbins = app_workspace::get_instance()->kb_in_state;
302 
303  // if no item is focused, arrow down focuses "second" element and arrow up focuses "first" element
304  // this masks arrow down to arrow up in case when no item is focused resulting in first element being focused
305  // FIXME - potential bug: arrow down KEYUP event is still processed, this triggers on KEYDOWN and
306  // doesn't trigger again on KEYUP - event seq: UP - KEYDOWN, UP - KEYUP, DOWN - KEYUP
307  if ((event->type == SDL_KEYDOWN || event->type == SDL_KEYUP) &&
308  (event->key.keysym.scancode == SDL_SCANCODE_DOWN || event->key.keysym.scancode == SDL_SCANCODE_UP) &&
309  (!ImGui::IsAnyItemFocused() || (!scr_mgr->focused && !combo_expanded)))
310  {
311  // need to consume event and reque new one, only changing current event doesn't work
312  spdlog::debug("event_handler.cpp - masking arrow key DOWN as UP {0}", combo_expanded);
313  //SDL_Event e = create_key_event(SDL_SCANCODE_UP);
314  // "fix" - after changing screens focus is lost, but focused item count is remembered and incorrect item is selected
315  // PAGE_UP selects first item
316  SDL_Event e = create_key_event(SDL_SCANCODE_PAGEUP);
317  push_event_to_sdl(&e, false);
318 
319  return 0;
320  }
321 
322  // handling only KEYDOWN events
323  if (event->type == SDL_KEYDOWN) {
324  spdlog::debug("event_handler.cpp - KEYDOWN scancode: {0}", event->key.keysym.scancode);
325 
326 // raspbian should be defined on rpi through cmake option
327 #ifndef __RASPBIAN__
328  if (event->key.keysym.scancode == SDL_SCANCODE_RALT) {
330  return 0;
331  }
332 
333  if (kbins->current_mode == app_workspace_ns::kb_input_mode::NAVIGATION &&
334  event->key.keysym.scancode == SDL_SCANCODE_BACKSPACE)
335  {
336  scr_mgr->pop_screen_from_previous();
337  return 0;
338  }
339 #endif
340 
341  // handle 1-9 while kb_input_mode is NAVIGATION (0 isn't included)
342  // need this for navigation on desktop, but for rpi moved to handle_nav_event() and never comes here
343  if (kbins->current_mode == app_workspace_ns::kb_input_mode::NAVIGATION &&
344  event->key.keysym.scancode >= SDL_SCANCODE_1 &&
345  event->key.keysym.scancode < SDL_SCANCODE_0) {
346  // screen number is only allowed in range 1-9 (0 reserved for error)
347  uint8_t screen_no = strtol(SDL_GetKeyName(event->key.keysym.sym), NULL, 10);
348 
349  if (screen_no > scr_mgr->get_screen_count()) {
350  spdlog::debug("event_handler.cpp - Requested screen ({0}) doesn't exist", screen_no);
351  return 0;
352  }
353 
354  scr_mgr->set_selected_screen(screen_no);
355 
356  return 0;
357  }
358 
359  // handle other keys (than 1-9) while in NAVIGATION mode
360  if (kbins->current_mode == app_workspace_ns::kb_input_mode::NAVIGATION) {
361  return 1;
362  }
363 
364  // handle any keypress (exc. #) while kb_input_mode is INPUT
365  if (kbins->current_mode == app_workspace_ns::kb_input_mode::INPUT) {
366  }
367  }
368 
369  if (event->type == SDL_KEYUP) {
370  spdlog::debug("event_handler.cpp - KEYUP scancode: {0}", event->key.keysym.scancode);
371  return 1; // DO NOT SEND KEYUP TO IMGUI - this is to prevent unwanted actions on desktop (spi keyboard only sends keydown events)
372  }
373 
374  return 1;
375  }
uint8_t get_screen_count()

◆ instanceof()

template<typename Base , typename T >
bool event_handler::instanceof ( const T *  ptr)
inline

Definition at line 19 of file event_handler.cpp.

19  {
20  return dynamic_cast<const Base*>(ptr) != nullptr;
21 }

◆ push_event_to_sdl()

void event_handler::push_event_to_sdl ( SDL_Event *  event,
bool  replace_cur_char = false 
)

Pushes event to SDL queue. This event then can be propagated to ImGui. If @replace_cur_char is set, ten a BACKSPACE event is pushed first.

Parameters
event
replace_cur_char

Definition at line 468 of file event_handler.cpp.

468  {
469  std::unique_ptr<app_workspace_ns::kb_input_state> &kbins = app_workspace::get_instance()->kb_in_state;
470 
471  spdlog::debug("event_handler.cpp - Pushing key event with scancode: {0} - {1}", event->key.keysym.scancode,
472  SDL_GetKeyName(SDL_GetKeyFromScancode(event->key.keysym.scancode)));
473 
474  // remove character so new one replaces it
475  if (replace_cur_char &&
476  kbins->current_mode == app_workspace_ns::kb_input_mode::INPUT &&
477  kbins->current_type == app_workspace_ns::kb_input_type::TEXT &&
478  event->key.keysym.scancode != SDL_SCANCODE_RETURN)
479  {
480  SDL_Event backspace = create_key_event(SDL_SCANCODE_BACKSPACE, 0);
481  SDL_PushEvent(&backspace);
482 
483  backspace.type = SDL_KEYUP;
484  SDL_PushEvent(&backspace);
485  }
486 
487  SDL_PushEvent(event); // pushes KEY_DOWN event
488 
489  if (kbins->current_mode == app_workspace_ns::kb_input_mode::INPUT &&
490  event->key.keysym.scancode != SDL_SCANCODE_RETURN &&
491  event->key.keysym.scancode != SDL_SCANCODE_BACKSPACE) // backspace during input MUSTN'T send textinput event
492  {
493  SDL_Event txt_input = create_textinput_event(event->key.keysym.scancode);
494  SDL_PushEvent(&txt_input); // pushes TEXTINPUT_EVENT of pressed key
495  }
496 
497  event->type = SDL_KEYUP;
498  event->key.state = 0;
499  SDL_PushEvent(event); // pushes KEY_UP event
500  }

◆ rfid_action_user_logged()

int event_handler::rfid_action_user_logged ( rfid_event event)

Definition at line 717 of file event_handler.cpp.

717  {
718  app_workspace *app_wrk = app_workspace::get_instance().get();
719  user_workspace *usr_wrk = app_wrk->get_userspace();
720 
721  // if the rfid is the same as logged in user
722  if (usr_wrk->compare_rfid_serials(&(event->tag)) == 0) { // 0 means equal
723  spdlog::info("event_handler.cpp - RFID event handler: user with this RFID is already logged");
724  // dont go to err screen (other than log, no action)
725  return 1;
726  }
727 
728  // currently logged user is pacient (0) and rfid doesnt match -> new user is trying to log in (regardless of new user role)
729  if (usr_wrk->get_role() == 0) {
730  spdlog::error("event_handler.cpp - RFID event handler: ");
731  // TODO/ FIXME - maybe instead of error and manual log in, automatically log over
732  app_wrk->set_err_screen_and_activate(get_localized_text("ERR_USER_LOGIN"),
733  get_localized_text("ERR_USER_ALREADY_LOGGED"));
734  return 1;
735  }
736 
737  if (usr_wrk->get_role() == 2 && app_wrk->get_scr_mgr()->get_selected_screen() == 6 &&
738  app_wrk->s5_screen_6_indicator == 1) // if user is admin, active screen is 6 and content on screen is user addition
739  {
740  app_wrk->s6_rfid_indicator = true;
741  app_wrk->refresh_current_screen = true;
742  rfid_reader::rfid_tag* tag_tmp = (rfid_reader::rfid_tag*) calloc(1, sizeof(rfid_reader::rfid_tag));
743  memcpy(tag_tmp, &(event->tag), sizeof(rfid_reader::rfid_tag));
744  app_wrk->s6_rfid_tag.reset(tag_tmp);
745  return 0;
746  }
747 
748  // this is reached only if role > 0 (employee/ admin). assuming the login is for subuser. subuser already exists, no place to log in new user
749  if (usr_wrk->has_subuser()) {
750  spdlog::error("event_handler.cpp - RFID event handler: already have user and subuser.");
751  // can move to error screen with this, but rfid is usually loaded several times with one "press" on the reader
752  // app_wrk->set_err_screen_and_activate(get_localized_text("ERR_USERS_FULL"),
753  // get_localized_text("ERR_USERS_FULL_DESC"));
754  return 1;
755  }
756 
757  app_wrk->log_in_user_rfid(&(event->tag), true);
758 
759  return 0;
760  }
user_workspace * get_userspace()
void set_err_screen_and_activate(const char *title, const char *label)
Set the err screen and activate the screen on next frame.
bool s6_rfid_indicator
int s5_screen_6_indicator
std::unique_ptr< rfid_reader::rfid_tag > s6_rfid_tag
bool refresh_current_screen
When this is set to true, elements of current screen will be reinitialized for next frame.
Container that servers for storing users data and manipulating them.
int compare_rfid_serials(rfid_reader::rfid_tag *tag)
const char * get_localized_text(const char *key)
Get the localized text object.
RFID tag structure. Stores data read from SPI.
Definition: rfid_reader.h:12

Variable Documentation

◆ custom_keymap

std::map<SDL_Scancode, const char*> event_handler::custom_keymap
Initial value:
{
{SDL_SCANCODE_KP_MULTIPLY, "*"},
{SDL_SCANCODE_DECIMALSEPARATOR, "."},
{SDL_SCANCODE_MINUS, "-"}
}

This map is used to create a character input for SDL scancode

Definition at line 161 of file event_handler.cpp.

◆ custom_shift_keymap

std::map<SDL_Scancode, const char*> event_handler::custom_shift_keymap
Initial value:
{
{SDL_SCANCODE_MINUS, "_"}
}

This map is used when the SHIFT keymoad is toggled (true)

Definition at line 168 of file event_handler.cpp.

◆ float_in_keymap

std::map<uint16_t, SDL_Scancode> event_handler::float_in_keymap
Initial value:
{
{0x0008, SDL_SCANCODE_1},
{0x0004, SDL_SCANCODE_2},
{0x0002, SDL_SCANCODE_3},
{0x0001, SDL_SCANCODE_BACKSPACE},
{0x0080, SDL_SCANCODE_4},
{0x0040, SDL_SCANCODE_5},
{0x0020, SDL_SCANCODE_6},
{0x0010, SDL_SCANCODE_MINUS},
{0x0800, SDL_SCANCODE_7},
{0x0400, SDL_SCANCODE_8},
{0x0200, SDL_SCANCODE_9},
{0x8000, SDL_SCANCODE_DECIMALSEPARATOR},
{0x4000, SDL_SCANCODE_0},
}

float input map that is used for mapping spi keys to sdl scancodes

Definition at line 110 of file event_handler.cpp.

◆ int_in_keymap

std::map<uint16_t, SDL_Scancode> event_handler::int_in_keymap
Initial value:
{
{0x0008, SDL_SCANCODE_1},
{0x0004, SDL_SCANCODE_2},
{0x0002, SDL_SCANCODE_3},
{0x0001, SDL_SCANCODE_BACKSPACE},
{0x0080, SDL_SCANCODE_4},
{0x0040, SDL_SCANCODE_5},
{0x0020, SDL_SCANCODE_6},
{0x0010, SDL_SCANCODE_MINUS},
{0x0800, SDL_SCANCODE_7},
{0x0400, SDL_SCANCODE_8},
{0x0200, SDL_SCANCODE_9},
{0x4000, SDL_SCANCODE_0},
}

int input map that is used for mapping spi keys to sdl scancodes

Definition at line 84 of file event_handler.cpp.

◆ navigation_keymap

std::map<uint16_t, SDL_Scancode> event_handler::navigation_keymap
Initial value:
{
{0x0008, SDL_SCANCODE_1},
{0x0004, SDL_SCANCODE_2},
{0x0002, SDL_SCANCODE_3},
{0x0001, SDL_SCANCODE_UP},
{0x0080, SDL_SCANCODE_4},
{0x0040, SDL_SCANCODE_5},
{0x0020, SDL_SCANCODE_6},
{0x0010, SDL_SCANCODE_LEFT},
{0x0800, SDL_SCANCODE_7},
{0x0400, SDL_SCANCODE_8},
{0x0200, SDL_SCANCODE_9},
{0x0100, SDL_SCANCODE_RIGHT},
{0x4000, SDL_SCANCODE_BACKSPACE},
{0x1000, SDL_SCANCODE_DOWN}
}

Map for translating SPI keyboard scancodes keys to SDL scancodes for navigation.

Definition at line 58 of file event_handler.cpp.

◆ text_in_keymap

std::map<uint16_t, std::vector<SDL_Scancode> > event_handler::text_in_keymap
Initial value:
{
{0x0008, {SDL_SCANCODE_1}},
{0x0004, {SDL_SCANCODE_2, SDL_SCANCODE_A, SDL_SCANCODE_B, SDL_SCANCODE_C}},
{0x0002, {SDL_SCANCODE_3, SDL_SCANCODE_D, SDL_SCANCODE_E, SDL_SCANCODE_F}},
{0x0001, {SDL_SCANCODE_BACKSPACE}},
{0x0080, {SDL_SCANCODE_4, SDL_SCANCODE_G, SDL_SCANCODE_H, SDL_SCANCODE_I}},
{0x0040, {SDL_SCANCODE_5, SDL_SCANCODE_J, SDL_SCANCODE_K, SDL_SCANCODE_L}},
{0x0020, {SDL_SCANCODE_6, SDL_SCANCODE_M, SDL_SCANCODE_N, SDL_SCANCODE_O}},
{0x0010, {SDL_SCANCODE_LSHIFT}},
{0x0800, {SDL_SCANCODE_7, SDL_SCANCODE_P, SDL_SCANCODE_Q, SDL_SCANCODE_R, SDL_SCANCODE_S}},
{0x0400, {SDL_SCANCODE_8, SDL_SCANCODE_T, SDL_SCANCODE_U, SDL_SCANCODE_V}},
{0x0200, {SDL_SCANCODE_9, SDL_SCANCODE_W, SDL_SCANCODE_X, SDL_SCANCODE_Y, SDL_SCANCODE_Z}},
{0x0100, {SDL_SCANCODE_CAPSLOCK}},
{0x8000, {SDL_SCANCODE_KP_MULTIPLY, SDL_SCANCODE_DECIMALSEPARATOR, SDL_SCANCODE_MINUS}},
{0x4000, {SDL_SCANCODE_0}},
}

Text input keymap. Holds what scancodes are cycled for corresponding key. First value should correspond to the physical key value ("picture" on keyboard). Some keys are currently disabled. Either because they are reserved or have no use.

Definition at line 138 of file event_handler.cpp.