2024-03-10 14:27:46 -04:00
# include <string>
2024-04-21 11:53:28 -04:00
# include "applicationInternal/gui/guiMemoryOptimizer.h"
# include "applicationInternal/hardware/hardwarePresenter.h"
2024-03-10 14:27:46 -04:00
# include "applicationInternal/scenes/sceneRegistry.h"
# include "applicationInternal/commandHandler.h"
const uint8_t ROWS = 5 ; //five rows
const uint8_t COLS = 5 ; //five columns
keypad_keyStates lastKeyState [ ROWS ] [ COLS ] = {
{ IDLE , IDLE , IDLE , IDLE , IDLE } ,
{ IDLE , IDLE , IDLE , IDLE , IDLE } ,
{ IDLE , IDLE , IDLE , IDLE , IDLE } ,
{ IDLE , IDLE , IDLE , IDLE , IDLE } ,
{ IDLE , IDLE , IDLE , IDLE , IDLE } ,
} ;
unsigned long lastTimeSent [ ROWS ] [ COLS ] = {
{ 0 , 0 , 0 , 0 , 0 } ,
{ 0 , 0 , 0 , 0 , 0 } ,
{ 0 , 0 , 0 , 0 , 0 } ,
{ 0 , 0 , 0 , 0 , 0 } ,
{ 0 , 0 , 0 , 0 , 0 } ,
} ;
bool keyIsHold [ ROWS ] [ COLS ] = {
{ false , false , false , false , false } ,
{ false , false , false , false , false } ,
{ false , false , false , false , false } ,
{ false , false , false , false , false } ,
{ false , false , false , false , false }
} ;
int repeatRate = 125 ; // in milliseconds
void doShortPress ( char keyChar , int keyCode ) {
unsigned long currentMillis = millis ( ) ;
if ( ( currentMillis - lastTimeSent [ keyCode / ROWS ] [ keyCode % ROWS ] ) > repeatRate ) {
lastTimeSent [ keyCode / ROWS ] [ keyCode % ROWS ] = currentMillis ;
2024-04-21 11:53:28 -04:00
uint16_t command = get_command_short ( gui_memoryOptimizer_getActiveSceneName ( ) , keyChar ) ;
2024-03-10 14:27:46 -04:00
if ( command ! = COMMAND_UNKNOWN ) {
Serial . printf ( " key: key '%c', will use command '%u' \r \n " , keyChar , command ) ;
executeCommand ( command ) ;
} else {
Serial . printf ( " key: key '%c', but no command defined \r \n " , keyChar ) ;
}
}
}
void doLongPress ( char keyChar , int keyCode ) {
2024-04-21 11:53:28 -04:00
uint16_t command = get_command_long ( gui_memoryOptimizer_getActiveSceneName ( ) , keyChar ) ;
2024-03-10 14:27:46 -04:00
if ( command ! = COMMAND_UNKNOWN ) {
Serial . printf ( " key: key '%c' (long press), will use command '%u' \r \n " , keyChar , command ) ;
executeCommand ( command ) ;
} else {
Serial . printf ( " key: key '%c' (long press), but no command defined \r \n " , keyChar ) ;
}
}
void keypad_loop ( void ) {
// we have to ignore the result, because in case of SINGLE_REPEATED we want to send the command again and again, but the keypad would give us only one single HOLD state, not repeatedly
getKeys ( keypad_keys ) ;
for ( int i = 0 ; i < keypad_maxkeys ; i + + ) {
if ( ! keypad_keys [ i ] . stateChanged ) {
// we are not allowed to do this, because of the same reason as above
// continue;
} else {
setLastActivityTimestamp ( ) ; // Reset the sleep timer when a button is pressed
}
char keyChar = keypad_keys [ i ] . kchar ;
int keyCode = keypad_keys [ i ] . kcode ;
if ( keypad_keys [ i ] . kstate = = PRESSED ) {
// Serial.println("pressed");
2024-04-21 11:53:28 -04:00
if ( ( get_key_repeatMode ( gui_memoryOptimizer_getActiveSceneName ( ) , keyChar ) = = SHORT ) & & ( lastKeyState [ keyCode / ROWS ] [ keyCode % ROWS ] ! = PRESSED ) ) {
2024-03-10 14:27:46 -04:00
// Serial.printf("key: PRESSED of SHORT key %c (%d)\r\n", keyChar, keyCode);
doShortPress ( keyChar , keyCode ) ;
2024-04-21 11:53:28 -04:00
} else if ( ( get_key_repeatMode ( gui_memoryOptimizer_getActiveSceneName ( ) , keyChar ) = = SHORT_REPEATED ) & & ( lastKeyState [ keyCode / ROWS ] [ keyCode % ROWS ] ! = PRESSED ) ) { // here do not repeat it too early, do the repeat only in HOLD
2024-03-10 14:27:46 -04:00
// Serial.printf("key: PRESSED of SHORT_REPEATED key %c (%d)\r\n", keyChar, keyCode);
doShortPress ( keyChar , keyCode ) ;
}
lastKeyState [ keyCode / ROWS ] [ keyCode % ROWS ] = PRESSED ;
} else if ( keypad_keys [ i ] . kstate = = HOLD ) {
// Serial.println("hold");
2024-04-21 11:53:28 -04:00
if ( ( get_key_repeatMode ( gui_memoryOptimizer_getActiveSceneName ( ) , keyChar ) = = SHORTorLONG ) & & ( lastKeyState [ keyCode / ROWS ] [ keyCode % ROWS ] ! = HOLD ) ) {
2024-03-10 14:27:46 -04:00
// Serial.printf("key: HOLD of SHORTorLONG key %c (%d)\r\n", keyChar, keyCode);
// Serial.printf("will set keyIsHold to TRUE for keycode %d\r\n", keyCode);
keyIsHold [ keyCode / ROWS ] [ keyCode % ROWS ] = true ;
doLongPress ( keyChar , keyCode ) ;
2024-04-21 11:53:28 -04:00
} else if ( get_key_repeatMode ( gui_memoryOptimizer_getActiveSceneName ( ) , keyChar ) = = SHORT_REPEATED ) { // this is the only case where we do not check the lastKeyState, because here it is intended to repeat the action
2024-03-10 14:27:46 -04:00
// Serial.printf("key: HOLD of SHORT_REPEATED key %c (%d)\r\n", keyChar, keyCode);
doShortPress ( keyChar , keyCode ) ;
}
lastKeyState [ keyCode / ROWS ] [ keyCode % ROWS ] = HOLD ;
} else if ( keypad_keys [ i ] . kstate = = RELEASED ) {
// Serial.println("released");
2024-04-21 11:53:28 -04:00
if ( ( get_key_repeatMode ( gui_memoryOptimizer_getActiveSceneName ( ) , keyChar ) = = SHORTorLONG ) & & ! keyIsHold [ keyCode / ROWS ] [ keyCode % ROWS ] & & ( lastKeyState [ keyCode / ROWS ] [ keyCode % ROWS ] ! = RELEASED ) ) {
2024-03-10 14:27:46 -04:00
// Serial.printf("value of keyIsHold for keycode %d is %d\r\n", keyCode, keyIsHold[keyCode/ROWS][keyCode%ROWS]);
// Serial.printf("key: RELEASED of SHORTorLONG key %c (%d)\r\n", keyChar, keyCode);
doShortPress ( keyChar , keyCode ) ;
}
// Serial.printf("will set keyIsHold to FALSE for keycode %d\r\n", keyCode);
keyIsHold [ keyCode / ROWS ] [ keyCode % ROWS ] = false ;
// Serial.printf("key: press of key %c (%d)\r\n", keyChar, keyCode);
lastKeyState [ keyCode / ROWS ] [ keyCode % ROWS ] = RELEASED ;
} else if ( keypad_keys [ i ] . kstate = = IDLE ) {
// Serial.println("idle");
// Serial.printf("key: idle of key %c (%d)\r\n", keyChar, keyCode);
lastKeyState [ keyCode / ROWS ] [ keyCode % ROWS ] = IDLE ;
}
}
}