Skip to content

Commit

Permalink
You can use a Proc in mode_key
Browse files Browse the repository at this point in the history
  • Loading branch information
hasumikin committed Apr 4, 2021
1 parent 73f51f8 commit 9cbbd2b
Show file tree
Hide file tree
Showing 3 changed files with 89 additions and 27 deletions.
4 changes: 4 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,10 @@ add_custom_target(ruby
COMMAND ${CMAKE_CURRENT_SOURCE_DIR}/lib/picoruby/build/host-production/bin/picorbc -Bkeyboard keyboard.rb
COMMAND ${CMAKE_CURRENT_SOURCE_DIR}/lib/picoruby/build/host-production/bin/picorbc -Btud tud.rb
COMMAND ${CMAKE_CURRENT_SOURCE_DIR}/lib/picoruby/build/host-production/bin/picorbc -Bkeymap keymap.rb
#COMMAND RBENV_VERSION=mruby-2.1.1 mrbc -E -Bled led.rb
#COMMAND RBENV_VERSION=mruby-2.1.1 mrbc -E -Bkeyboard keyboard.rb
#COMMAND RBENV_VERSION=mruby-2.1.1 mrbc -E -Btud tud.rb
#COMMAND RBENV_VERSION=mruby-2.1.1 mrbc -E -Bkeymap keymap.rb
WORKING_DIRECTORY ../src/ruby
)

Expand Down
84 changes: 64 additions & 20 deletions src/ruby/keyboard.rb
Original file line number Diff line number Diff line change
Expand Up @@ -199,6 +199,7 @@ def initialize(rows, cols)
gpio_set_dir(pin, GPIO_OUT);
gpio_put(pin, HI);
end
@layer_names = Array.new
end

# Input
Expand All @@ -217,22 +218,47 @@ def add_layer(name, map)
end
end
@layers[name] = map
@first_layer_name ||= name
@locked_layer_name ||= name
@layer_names << name
end

# param[0] :release_key
# param[1] :hold_layer_name
def raise_layer
current_index = @layer_names.index(@locked_layer_name)
if current_index < @layer_names.size - 1
@locked_layer_name = @layer_names[current_index + 1]
else
@locked_layer_name = @layer_names.first
end
end

def lower_layer
current_index = @layer_names.index(@locked_layer_name)
if current_index == 0
@locked_layer_name = @layer_names.last
else
@locked_layer_name = @layer_names[current_index - 1]
end
end

# param[0] :on_release
# param[1] :on_hold
# param[2] :release_threshold
# param[3] :repush_threshold
def define_mode_key(key_name, param)
@layers.each do |layer_name, map|
map.each_with_index do |row, row_index|
row.each_with_index do |key_symbol, col_index|
if key_name == key_symbol
on_release = nil
if KEYCODE[param[0]]
on_release = KEYCODE[param[0]] * -1
else
on_release = param[0]
end
@mode_keys << {
layer_name: layer_name,
release_key: ( (KEYCODE[param[0]] || 0) * -1),
hold_layer_name: param[1],
on_release: on_release,
on_hold: param[1],
release_threshold: (param[2] || 0),
repush_threshold: (param[3] || 0),
switch: [row_index, col_index],
Expand Down Expand Up @@ -273,12 +299,29 @@ def before_report(&block)
@before_filters << block
end

def action_on_release(mode_key)
case mode_key.class
when Fixnum
@keycodes << (mode_key * -1).chr
when Proc
mode_key.call
end
end

def action_on_hold(mode_key)
if MOD_KEYCODE[mode_key]
@modifier |= MOD_KEYCODE[mode_key]
else # assumes layer key
@layer_name = mode_key
end
end

def start!
@keycodes = Array.new
while true
now = board_millis
keycode_pos = 0
@keycodes = "\000\000\000\000\000\000"
layer_name = @first_layer_name
@keycodes.clear
@layer_name = @locked_layer_name

@switches.clear
@modifier = 0
Expand All @@ -293,32 +336,30 @@ def start!
end

@mode_keys.each do |mode_key|
next if mode_key[:layer_name] != layer_name
next if mode_key[:layer_name] != @layer_name
if @switches.include?(mode_key[:switch])
@led.on
case mode_key[:prev_state]
when :released
mode_key[:pushed_at] = now
mode_key[:prev_state] = :pushed
layer_name = mode_key[:hold_layer_name]
action_on_hold(mode_key[:on_hold])
when :pushed
layer_name = mode_key[:hold_layer_name]
action_on_hold(mode_key[:on_hold])
when :pushed_then_released
if now - mode_key[:released_at] <= mode_key[:repush_threshold]
mode_key[:prev_state] = :pushed_then_released_then_pushed
end
when :pushed_then_released_then_pushed
@keycodes[keycode_pos] = (mode_key[:release_key] * -1).chr
keycode_pos += 1
action_on_release(mode_key[:on_release])
break
end
else
@led.off
case mode_key[:prev_state]
when :pushed
if now - mode_key[:pushed_at] <= mode_key[:release_threshold]
@keycodes[keycode_pos] = (mode_key[:release_key] * -1).chr
keycode_pos += 1
action_on_release(mode_key[:on_release])
mode_key[:prev_state] = :pushed_then_released
mode_key[:released_at] = now
break
Expand All @@ -335,24 +376,27 @@ def start!
end
end

layer = @layers[layer_name]
layer = @layers[@layer_name]
@switches.each do |switch|
key = layer[switch[0]][switch[1]]
next unless key.is_a?(Fixnum)
if key < 0 # Normal keys
@keycodes[keycode_pos] = (key * -1).chr
keycode_pos += 1
@keycodes << (key * -1).chr
else # Modifier keys
@modifier |= key
end
break if keycode_pos > 5
break if @keycodes.size > 5
end

(6 - @keycodes.size).times do
@keycodes << "\000"
end

@before_filters.each do |block|
block.call
end

report_hid(@modifier, @keycodes)
report_hid(@modifier, @keycodes.join)
time = board_millis - now
sleep_ms(time) if time > 0
end
Expand Down
28 changes: 21 additions & 7 deletions src/ruby/keymap.rb
Original file line number Diff line number Diff line change
Expand Up @@ -33,22 +33,36 @@
]
kbd.add_layer :raise, [
%i(KC_C RAISE_ENTER),
%i(KC_D ADJUST),
#%i(KC_D ADJUST),
%i(KC_D LOWER_SPACE),
]
kbd.add_layer :lower, [
%i(KC_E RAISE_ENTER),
%i(KC_F LOWER_SPACE),
]
kbd.add_layer :adjust, [
%i(KC_SCOLON RAISE_ENTER),
%i(KC_LSFT ADJUST),
#%i(KC_LSFT ADJUST),
%i(KC_LSFT LOWER_SPACE),
]

# Your custom Keycode when Layer when Release time threshold(ms) Re-push time threshold(ms)
# key name you click you keep press to consider as `click the key` to consider as `hold the key`
kbd.define_mode_key :RAISE_ENTER, [ :KC_ENTER, :raise, 200, 150 ]
kbd.define_mode_key :LOWER_SPACE, [ :KC_SPACE, :lower, 300, 400 ]
kbd.define_mode_key :ADJUST, [ nil, :adjust, nil, nil ]
# Your custom Keycode when Layer when Release time Re-push time
# key name you click you keep threshold(ms) threshold(ms)
# press to consider as to consider as
# `click the key` `hold the key`
#kbd.define_mode_key :RAISE_ENTER, [ :KC_ENTER, :raise, 200, 150 ]
#kbd.define_mode_key :LOWER_SPACE, [ :KC_SPACE, :lower, 300, 400 ]
#kbd.define_mode_key :ADJUST, [ nil, :adjust, nil, nil ]


raise_proc = Proc.new do
kbd.raise_layer
end
lower_proc = Proc.new do
kbd.lower_layer
end
kbd.define_mode_key :RAISE_ENTER, [ raise_proc, :KC_LSFT, 200, 200 ]
kbd.define_mode_key :LOWER_SPACE, [ lower_proc, :KC_LCTL, 200, 200 ]

# ex) Use Keyboard#before_report filter if you want to input `":" w/o shift` and `";" w/ shift`
#
Expand Down

0 comments on commit 9cbbd2b

Please sign in to comment.