@ -26,14 +26,10 @@ uint32_t OneShot::start_time_ = 0;
uint16_t OneShot : : time_out = 2500 ;
uint16_t OneShot : : hold_time_out = 250 ;
int16_t OneShot : : double_tap_time_out = - 1 ;
OneShot : : state_t OneShot : : state_ = { 0 , 0 } ;
OneShot : : state_t OneShot : : sticky_state_ = { 0 , 0 } ;
OneShot : : state_t OneShot : : stickable_state_ = { 0xFF , 0xFF } ;
OneShot : : state_t OneShot : : pressed_state_ = { 0 , 0 } ;
OneShot : : key_state_t OneShot : : state_ [ 16 ] ;
Key OneShot : : prev_key_ ;
bool OneShot : : should_cancel_ = false ;
bool OneShot : : should_cancel_stickies_ = false ;
uint8_t OneShot : : positions_ [ 16 ] ;
// --- helper macros ------
@ -41,25 +37,41 @@ uint8_t OneShot::positions_[16];
# define isModifier(key) (key.raw >= Key_LeftControl.raw && key.raw <= Key_RightGui.raw)
# define isLayerKey(key) (key.flags == (KEY_FLAGS | SYNTHETIC | SWITCH_TO_KEYMAP))
# define isOneShot(idx) ( bitRead (state_.all, (idx)) )
# define setOneShot(idx) ( bitWrite (state_.all, idx, 1) )
# define clearOneShot(idx) ( bitWrite (state_.all, idx, 0) )
# define isOneShot(idx) ( state_[idx].active )
# define setOneShot(idx) ( state_[idx].active = true )
# define clearOneShot(idx) ( state_[idx].active = false )
# define isSticky_(idx) ( bitRead (sticky_state_.all, idx) )
# define setSticky(idx) ( bitWrite (sticky_state_.all, idx, 1) )
# define clearSticky(idx) bitWrite (sticky_state_.all, idx, 0 )
# define isSticky_(idx) ( state_[idx].sticky )
# define setSticky(idx) ( state_[idx].sticky = true )
# define clearSticky(idx) (state_[idx].sticky = false )
# define setPressed(idx) bitWrite(pressed_state_.all, idx, 1 )
# define clearPressed(idx) bitWrite(pressed_state_.all, idx, 0 )
# define isPressed (idx) bitRead (pressed_state_.all, idx )
# define setPressed(idx) (state_[idx].pressed = true )
# define clearPressed(idx) (state_[idx].pressed = false )
# define isPressed _(idx) (state_[idx].pressed )
# define isSameAsPrevious(key) (key.raw == prev_key_.raw)
# define saveAsPrevious(key) prev_key_.raw = key.raw
# define hasTimedOut() (millis () - start_time_ >= time_out)
bool OneShot : : isPressed ( ) {
for ( uint8_t i = 0 ; i < sizeof ( state_ ) ; i + + ) {
if ( state_ [ i ] . pressed )
return true ;
}
return false ;
}
bool OneShot : : isSticky ( ) {
for ( uint8_t i = 0 ; i < sizeof ( state_ ) ; i + + ) {
if ( state_ [ i ] . sticky )
return true ;
}
return false ;
}
bool OneShot : : isStickable ( Key key ) {
return bitRead ( stickable_state_ . all , key . raw - ranges : : OS_FIRST ) ;
return state_ [ key . raw - ranges : : OS_FIRST ] . stickable ;
}
void OneShot : : positionToCoords ( uint8_t pos , byte * row , byte * col ) {
@ -80,7 +92,7 @@ void OneShot::injectNormalKey(uint8_t idx, uint8_t key_state) {
key . keyCode = LAYER_SHIFT_OFFSET + idx - 8 ;
}
positionToCoords ( positions_[ idx ] , & row , & col ) ;
positionToCoords ( state_[ idx ] . position , & row , & col ) ;
handleKeyswitchEvent ( key , row , col , key_state | INJECTED ) ;
}
@ -99,7 +111,7 @@ EventHandlerResult OneShot::onKeyswitchEvent(Key &mapped_key, byte row, byte col
if ( keyState & INJECTED )
return EventHandlerResult : : OK ;
if ( ! state_. all ) {
if ( ! isActive( ) ) {
if ( ! isOneShotKey ( mapped_key ) ) {
return EventHandlerResult : : OK ;
}
@ -108,7 +120,7 @@ EventHandlerResult OneShot::onKeyswitchEvent(Key &mapped_key, byte row, byte col
clearPressed ( idx ) ;
} else if ( keyToggledOn ( keyState ) ) {
start_time_ = millis ( ) ;
positions_[ idx ] = row * COLS + col ;
state_[ idx ] . position = row * COLS + col ;
setPressed ( idx ) ;
setOneShot ( idx ) ;
saveAsPrevious ( mapped_key ) ;
@ -148,7 +160,7 @@ EventHandlerResult OneShot::onKeyswitchEvent(Key &mapped_key, byte row, byte col
} else {
start_time_ = millis ( ) ;
positions_[ idx ] = row * COLS + col ;
state_[ idx ] . position = row * COLS + col ;
setOneShot ( idx ) ;
saveAsPrevious ( mapped_key ) ;
@ -173,7 +185,7 @@ EventHandlerResult OneShot::onKeyswitchEvent(Key &mapped_key, byte row, byte col
}
EventHandlerResult OneShot : : beforeReportingState ( ) {
if ( ! state_. all )
if ( ! isActive( ) )
return EventHandlerResult : : OK ;
for ( uint8_t i = 0 ; i < 8 ; i + + ) {
@ -186,7 +198,7 @@ EventHandlerResult OneShot::beforeReportingState() {
}
EventHandlerResult OneShot : : afterEachCycle ( ) {
if ( ! state_. all )
if ( ! isActive( ) )
return EventHandlerResult : : OK ;
if ( hasTimedOut ( ) )
@ -203,7 +215,7 @@ EventHandlerResult OneShot::afterEachCycle() {
cancelOneShot ( i ) ;
clearPressed ( i ) ;
}
} else if ( isOneShot ( i ) & & ! isPressed ( i ) ) {
} else if ( isOneShot ( i ) & & ! isPressed _ ( i ) ) {
is_cancelled = true ;
cancelOneShot ( i ) ;
}
@ -225,13 +237,21 @@ void OneShot::inject(Key mapped_key, uint8_t key_state) {
// --- glue code ---
bool OneShot : : isActive ( void ) {
return ( state_ . all & & ! hasTimedOut ( ) ) | | ( pressed_state_ . all ) | | ( sticky_state_ . all ) ;
for ( uint8_t i = 0 ; i < 16 ; i + + ) {
if ( ( state_ [ i ] . active & & ! hasTimedOut ( ) ) | |
state_ [ i ] . pressed | |
state_ [ i ] . sticky )
return true ;
}
return false ;
}
bool OneShot : : isActive ( Key key ) {
uint8_t idx = key . raw - ranges : : OS_FIRST ;
return ( bitRead ( state_ . all , idx ) & & ! hasTimedOut ( ) ) | | ( isPressed ( idx ) ) | | ( isSticky_ ( idx ) ) ;
return ( state_ [ idx ] . active & & ! hasTimedOut ( ) ) | |
state_ [ idx ] . pressed | |
state_ [ idx ] . sticky ;
}
bool OneShot : : isSticky ( Key key ) {
@ -254,28 +274,36 @@ void OneShot::cancel(bool with_stickies) {
void OneShot : : enableStickability ( Key key ) {
if ( key > = ranges : : OS_FIRST & & key < = ranges : : OS_LAST )
bitSet( stickable_state_ . all , ( key . raw - ranges : : OS_FIRST ) ) ;
state_[ key . raw - ranges : : OS_FIRST ] . stickable = true ;
}
void OneShot : : disableStickability ( Key key ) {
if ( key > = ranges : : OS_FIRST & & key < = ranges : : OS_LAST )
bitClear( stickable_state_ . all , ( key . raw - ranges : : OS_FIRST ) ) ;
state_[ key . raw - ranges : : OS_FIRST ] . stickable = false ;
}
void OneShot : : enableStickabilityForModifiers ( ) {
stickable_state_ . mods = 0xFF ;
for ( uint8_t i = 0 ; i < 8 ; i + + ) {
state_ [ i ] . stickable = true ;
}
}
void OneShot : : enableStickabilityForLayers ( ) {
stickable_state_ . layers = 0xFF ;
for ( uint8_t i = 8 ; i < 16 ; i + + ) {
state_ [ i ] . stickable = true ;
}
}
void OneShot : : disableStickabilityForModifiers ( ) {
stickable_state_ . mods = 0 ;
for ( uint8_t i = 0 ; i < 8 ; i + + ) {
state_ [ i ] . stickable = false ;
}
}
void OneShot : : disableStickabilityForLayers ( ) {
stickable_state_ . layers = 0 ;
for ( uint8_t i = 8 ; i < 16 ; i + + ) {
state_ [ i ] . stickable = false ;
}
}
}