more refactoring; adds dynamic key coloring
This commit is contained in:
parent
203513ec0e
commit
9756bacaea
|
@ -55,12 +55,17 @@ shift.KEY_SHIFT = shift.KEY_SHIFT or 11
|
||||||
shift.KEY_LAYOUT = shift.KEY_LAYOUT or 8
|
shift.KEY_LAYOUT = shift.KEY_LAYOUT or 8
|
||||||
shift.KEY_BRIGHTNESS = shift.KEY_BRIGHTNESS or 5
|
shift.KEY_BRIGHTNESS = shift.KEY_BRIGHTNESS or 5
|
||||||
|
|
||||||
|
shift.BRIGHTNESS_LEVELS = shift.BRIGHTNESS_LEVELS or { 70, 100, 40 }
|
||||||
|
|
||||||
|
|
||||||
-- Internal flag for detecting SHIFT press-release sequences without any SHIFTed
|
-- Internal flag for detecting SHIFT press-release sequences without any SHIFTed
|
||||||
-- function.
|
-- function.
|
||||||
local shift_only = false
|
local shift_only = false
|
||||||
local grabbed_key_count = 0
|
local grabbed_key_count = 0
|
||||||
|
|
||||||
|
-- Activates the first brightness level...
|
||||||
|
shift.brightnesses = table.pack(table.unpack(shift.BRIGHTNESS_LEVELS))
|
||||||
|
mb.cycle_brightness(shift.brightnesses)
|
||||||
|
|
||||||
-- Switches to the next SHIFT layer within the currently active keyboard layout.
|
-- Switches to the next SHIFT layer within the currently active keyboard layout.
|
||||||
-- SHIFT layer(s) are wired up as a circular list of keymaps, linked using their
|
-- SHIFT layer(s) are wired up as a circular list of keymaps, linked using their
|
||||||
|
@ -72,7 +77,6 @@ function shift.shift_secondary_keymap()
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
-- Remember how many grabbed keys are pressed, so we won't ungrab later until
|
-- Remember how many grabbed keys are pressed, so we won't ungrab later until
|
||||||
-- all keys have been released.
|
-- all keys have been released.
|
||||||
function shift.any_press(keyno)
|
function shift.any_press(keyno)
|
||||||
|
@ -94,7 +98,6 @@ function shift.any_release(keyno)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
-- SHIFT press: switches into grabbed SHIFT mode, activating the in-SHIFT keys
|
-- SHIFT press: switches into grabbed SHIFT mode, activating the in-SHIFT keys
|
||||||
-- for brightness change, keymap cycling, et cetera.
|
-- for brightness change, keymap cycling, et cetera.
|
||||||
function shift.shift(key)
|
function shift.shift(key)
|
||||||
|
@ -106,23 +109,27 @@ function shift.shift(key)
|
||||||
mb.grab(shift.keymap_shifted.name)
|
mb.grab(shift.keymap_shifted.name)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
-- Cycles to the next primary keyboard layout (keymap)
|
-- Cycles to the next primary keyboard layout (keymap)
|
||||||
function shift.cycle(key)
|
function shift.cycle(key)
|
||||||
shift_only = false
|
shift_only = false
|
||||||
mb.cycle_primary_keymaps()
|
mb.cycle_primary_keymaps()
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
-- Changes the Keybow LED brightness, by cycling through different brightness
|
-- Changes the Keybow LED brightness, by cycling through different brightness
|
||||||
-- levels
|
-- levels
|
||||||
function shift.brightness(key)
|
function shift.brightness(key)
|
||||||
shift_only = false
|
shift_only = false
|
||||||
local b = mb.brightness + 0.3
|
mb.cycle_brightness(shift.brightnesses)
|
||||||
if b > 1 then; b = 0.4; end
|
mb.led(key, shift.next_brightness_color())
|
||||||
mb.set_brightness(b)
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
-- Returns the color for the BRIGHTNESS key LED: this is the next brightness
|
||||||
|
-- level in the sequence of brightness levels as a color of gray/white.
|
||||||
|
function shift.next_brightness_color()
|
||||||
|
local br = shift.brightnesses[1]
|
||||||
|
br = br > 1.0 and br / 100 or br
|
||||||
|
return { r=br, g=br, b=br }
|
||||||
|
end
|
||||||
|
|
||||||
-- define and register our keymaps: the permanent SHIFT key-only keymap, as well
|
-- define and register our keymaps: the permanent SHIFT key-only keymap, as well
|
||||||
-- as a temporary grabbing keymap while the SHIFT key is being pressed and held.
|
-- as a temporary grabbing keymap while the SHIFT key is being pressed and held.
|
||||||
|
@ -138,7 +145,7 @@ shift.keymap_shifted = {
|
||||||
[shift.KEY_SHIFT] = {c={r=1, g=1, b=1}},
|
[shift.KEY_SHIFT] = {c={r=1, g=1, b=1}},
|
||||||
|
|
||||||
[shift.KEY_LAYOUT] = {c={r=0, g=1, b=1}, press=shift.cycle, release=shift.release_other},
|
[shift.KEY_LAYOUT] = {c={r=0, g=1, b=1}, press=shift.cycle, release=shift.release_other},
|
||||||
[shift.KEY_BRIGHTNESS] = {c={r=0.5, g=0.5, b=0.5}, press=shift.brightness, release=shift.release_other}
|
[shift.KEY_BRIGHTNESS] = {c=shift.next_brightness_color, press=shift.brightness, release=shift.release_other}
|
||||||
}
|
}
|
||||||
mb.register_keymap(shift.keymap)
|
mb.register_keymap(shift.keymap)
|
||||||
mb.register_keymap(shift.keymap_shifted)
|
mb.register_keymap(shift.keymap_shifted)
|
||||||
|
|
|
@ -23,13 +23,74 @@ SOFTWARE.
|
||||||
]]--
|
]]--
|
||||||
|
|
||||||
|
|
||||||
|
mb.MIN_BRIGHTNESS = mb.MIN_BRIGHTNESS or 0.1
|
||||||
|
|
||||||
-- Default LED brightness in the [0.1..1] range.
|
-- Default LED brightness in the [0.1..1] range.
|
||||||
mb.brightness = 1
|
mb.brightness = 1
|
||||||
|
|
||||||
-- Sets the Keybow key LEDs maximum brightness, in the range [0.1..1].
|
-- Sets the Keybow key LEDs maximum brightness, in the range [0.1..1] or
|
||||||
|
-- [10..100] (percent). The minim brightness is clamped on purpose to avoid
|
||||||
|
-- unlit LEDs. The lower clamp defaults to mb.MIN_BRIGHTNESS.
|
||||||
function mb.set_brightness(brightness)
|
function mb.set_brightness(brightness)
|
||||||
if brightness < 0.1 then brightness = 0.1 end
|
brightness = brightness > 1.0 and brightness / 100 or brightness
|
||||||
|
if brightness < mb.MIN_BRIGHTNESS then brightness = mb.MIN_BRIGHTNESS end
|
||||||
if brightness > 1 then brightness = 1 end
|
if brightness > 1 then brightness = 1 end
|
||||||
mb.brightness = brightness
|
mb.brightness = brightness
|
||||||
mb.activate_leds()
|
mb.activate_leds()
|
||||||
end
|
end
|
||||||
|
|
||||||
|
-- Cycles through a list of brightness values, always taking the first
|
||||||
|
-- value and modifying the list by cycling it. Brightness values can be
|
||||||
|
-- either [0..1] or [0..100] (that is, percent)
|
||||||
|
function mb.cycle_brightness(brightnesses)
|
||||||
|
local brightness = table.remove(brightnesses, 1)
|
||||||
|
table.insert(brightnesses, brightness)
|
||||||
|
mb.set_brightness(brightness)
|
||||||
|
return brightnesses
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Sets key LED to specific color, taking brightness into consideration.
|
||||||
|
-- The color is a triple (table) with the elements r, g, and b. Each color
|
||||||
|
-- component is in the range [0..1].
|
||||||
|
function mb.led(keyno, color)
|
||||||
|
if color then
|
||||||
|
local b = mb.brightness * 255
|
||||||
|
keybow.set_pixel(keyno, color.r * b, color.g * b, color.b * b)
|
||||||
|
else
|
||||||
|
keybow.set_pixel(keyno, 0, 0, 0)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Restores Keybow LEDs according to current keymap and the permanent keymaps.
|
||||||
|
function mb.activate_leds()
|
||||||
|
keybow.clear_lights()
|
||||||
|
-- if a grab is in place then it takes absolute priority
|
||||||
|
if mb.grab_keymap then
|
||||||
|
mb.activate_keymap_leds(mb.grab_keymap)
|
||||||
|
else
|
||||||
|
-- first update LEDs for the current keymap...
|
||||||
|
if mb.current_keymap ~= nil then
|
||||||
|
mb.activate_keymap_leds(mb.current_keymap)
|
||||||
|
end
|
||||||
|
-- ...then update LEDs from permanent keymap(s), as this ensures that
|
||||||
|
-- the permanent keymaps take precedence.
|
||||||
|
for name, keymap in pairs(mb.keymaps) do
|
||||||
|
if keymap.permanent then
|
||||||
|
mb.activate_keymap_leds(keymap)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Helper function that iterates over all keymap elements but skipping non-key
|
||||||
|
-- bindings.
|
||||||
|
function mb.activate_keymap_leds(keymap)
|
||||||
|
for keyno, keydef in pairs(keymap) do
|
||||||
|
-- Only iterates over keys, skipping any other keymap definitions.
|
||||||
|
if type(keyno) == "number" and keydef.c then
|
||||||
|
local color = type(keydef.c) == "function" and keydef.c() or keydef.c
|
||||||
|
mb.led(keyno, color)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
|
|
@ -160,50 +160,6 @@ function mb.ungrab()
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
-- Sets key LED to specific color, taking brightness into consideration.
|
|
||||||
-- The color is a triple (table) with the elements r, g, and b. Each color
|
|
||||||
-- component is in the range [0..1].
|
|
||||||
function mb.led(keyno, color)
|
|
||||||
if color then
|
|
||||||
local b = mb.brightness * 255
|
|
||||||
keybow.set_pixel(keyno, color.r * b, color.g * b, color.b * b)
|
|
||||||
else
|
|
||||||
keybow.set_pixel(keyno, 0, 0, 0)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
-- Restores Keybow LEDs according to current keymap and the permanent keymaps.
|
|
||||||
function mb.activate_leds()
|
|
||||||
keybow.clear_lights()
|
|
||||||
-- if a grab is in place then it takes absolute priority
|
|
||||||
if mb.grab_keymap then
|
|
||||||
mb.activate_keymap_leds(mb.grab_keymap)
|
|
||||||
else
|
|
||||||
-- first update LEDs for the current keymap...
|
|
||||||
if mb.current_keymap ~= nil then
|
|
||||||
mb.activate_keymap_leds(mb.current_keymap)
|
|
||||||
end
|
|
||||||
-- ...then update LEDs from permanent keymap(s), as this ensures that
|
|
||||||
-- the permanent keymaps take precedence.
|
|
||||||
for name, keymap in pairs(mb.keymaps) do
|
|
||||||
if keymap.permanent then
|
|
||||||
mb.activate_keymap_leds(keymap)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
-- Helper function that iterates over all keymap elements but skipping non-key
|
|
||||||
-- bindings.
|
|
||||||
function mb.activate_keymap_leds(keymap)
|
|
||||||
for keyno, keydef in pairs(keymap) do
|
|
||||||
if type(keyno) == "number" and keydef.c then
|
|
||||||
-- print((keymap.permanent and "permanent LED" or "LED") .. " " .. keyno)
|
|
||||||
mb.led(keyno, keydef.c)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
-- Disables the automatic Keybow lightshow and sets the key LED colors. This
|
-- Disables the automatic Keybow lightshow and sets the key LED colors. This
|
||||||
-- is a well-known (hook) function that gets called by the Keybow firmware
|
-- is a well-known (hook) function that gets called by the Keybow firmware
|
||||||
-- after initialization immediately before waiting for key events.
|
-- after initialization immediately before waiting for key events.
|
||||||
|
|
|
@ -46,7 +46,7 @@ describe("Kdenlive keymap", function()
|
||||||
_G.setup()
|
_G.setup()
|
||||||
end)
|
end)
|
||||||
|
|
||||||
it("colors its keys", function()
|
inslit("colors its keys", function()
|
||||||
for _, keymap in pairs(mb.registered_keymaps()) do
|
for _, keymap in pairs(mb.registered_keymaps()) do
|
||||||
if string.sub(keymap.name, 1, #"kdenlive") == "kdenlive" then
|
if string.sub(keymap.name, 1, #"kdenlive") == "kdenlive" then
|
||||||
for keyno = 0, 11 do
|
for keyno = 0, 11 do
|
||||||
|
|
|
@ -179,6 +179,25 @@ describe("SHIFT multibow keymap", function()
|
||||||
end)
|
end)
|
||||||
end)
|
end)
|
||||||
|
|
||||||
|
inslit("cycles brightness", function()
|
||||||
|
local s = spy.on(mb, "led")
|
||||||
|
|
||||||
|
local len = #shift.BRIGHTNESS_LEVELS
|
||||||
|
for i = 1, len do
|
||||||
|
assert.equals(mb.brightness * 100, shift.BRIGHTNESS_LEVELS[i])
|
||||||
|
-- enters SHIFT and check the brightness of brightness key...
|
||||||
|
s:clear()
|
||||||
|
hwk.press(shift.KEY_SHIFT)
|
||||||
|
assert.spy(s).was.called_with(
|
||||||
|
shift.KEY_BRIGHTNESS,
|
||||||
|
shift.next_brightness_color())
|
||||||
|
-- cycles to next brightness
|
||||||
|
hwk.tap(shift.KEY_BRIGHTNESS)
|
||||||
|
hwk.release(shift.KEY_SHIFT)
|
||||||
|
end
|
||||||
|
assert.equals(mb.brightness * 100, shift.BRIGHTNESS_LEVELS[1])
|
||||||
|
end)
|
||||||
|
|
||||||
end)
|
end)
|
||||||
|
|
||||||
end)
|
end)
|
||||||
|
|
|
@ -29,11 +29,42 @@ describe("multibow LEDs", function()
|
||||||
mb.set_brightness(0.5)
|
mb.set_brightness(0.5)
|
||||||
assert.equals(0.5, mb.brightness)
|
assert.equals(0.5, mb.brightness)
|
||||||
|
|
||||||
mb.set_brightness(1.1)
|
mb.set_brightness(1.0)
|
||||||
assert.equals(1.0, mb.brightness)
|
assert.equals(1.0, mb.brightness)
|
||||||
|
|
||||||
mb.set_brightness(0)
|
mb.set_brightness(0)
|
||||||
assert.equals(0.1, mb.brightness)
|
assert.equals(mb.MIN_BRIGHTNESS, mb.brightness)
|
||||||
|
|
||||||
|
mb.set_brightness(20)
|
||||||
|
assert.equals(0.2, mb.brightness)
|
||||||
|
end)
|
||||||
|
|
||||||
|
it("cycles brightness", function()
|
||||||
|
function f(b, scale)
|
||||||
|
local copy = table.pack(table.unpack(b))
|
||||||
|
local len = #b
|
||||||
|
for i = 1, len do
|
||||||
|
mb.cycle_brightness(copy)
|
||||||
|
assert.equals(b[i], mb.brightness * scale)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
f({ 0.7, 1.0, 0.4 }, 1)
|
||||||
|
f({ 70, 100, 40 }, 100)
|
||||||
|
end)
|
||||||
|
|
||||||
|
inslit("accepts LED color functions in keymaps", function()
|
||||||
|
local s = spy.on(mb, "led")
|
||||||
|
local km = {
|
||||||
|
name="test",
|
||||||
|
[0]={c={r=0, g=1, b=0}},
|
||||||
|
[1]={c=function() return {r=1, g=1, b=1} end}
|
||||||
|
}
|
||||||
|
|
||||||
|
mb.activate_keymap_leds(km)
|
||||||
|
assert.spy(s).was.called(2)
|
||||||
|
assert.spy(s).was.called_with(0, {r=0, g=1, b=0})
|
||||||
|
assert.spy(s).was.called_with(1, {r=1, g=1, b=1})
|
||||||
end)
|
end)
|
||||||
|
|
||||||
end)
|
end)
|
||||||
|
|
Loading…
Reference in New Issue