reaper-oss / sws

The SWS extension is a collection of features that seamlessly integrate into REAPER, the Digital Audio Workstation (DAW) software by Cockos, Inc
https://www.sws-extension.org/
MIT License
455 stars 85 forks source link

FR: Exposure of keyboard-keys and modifier for multiple key-presses #1031

Open mespotine opened 6 years ago

mespotine commented 6 years ago

The gfx.getchar()-function has the problem, that it only returns one key only. But sometimes, multiple keys are pressed at once. So I would like to suggest a function, that returns the ASCII-Keycodes currently pressed as a csv-string, where the returned keypress-string could be something like "65,66,67" if the keys A,B and C were pressed altogether.

string csv_keys, bool shift_press, bool ctrlcmd_press, bool alt_press, bool altgr_press, bool win_apple_press = GetChar()

A usecase for which I need it: I want to create a live-edit-script, where I have the keys 1 to 9 associated with a certain track. When I click 1 for track 1, all items in track 2-9 are split and muted, so only the item in track 1 still runs. When I then click 5 for track 5, the item in track 5 would be split and unmuted, while the item for track 1 is split and muted, so only track 5 runs now. This is currently only possible with only one track at a time, not with multiple tracks at once, as gfx.getchar() only returns the first typed key.

With video, I would love to be able to type 1, 7 and 9 at the same time, to have these three track unmuted(e.g. for splitscreen-video-editing) and the rest muted. But gfx.getchar() only reads the first typed key, none of the other ones, so I could edit out track 1, but not 7 and 9 at the same time.

jalovatt commented 6 years ago

You can call gfx.getchar(x) with a specific ASCII value to check that key directly - it will return 1 if the key is pressed and 0 if it isn't. The number of keys allowed seems a bit fiddly, but it varies from 4 to 6 here.

gfx.init("getchar multikey", 320, 240, 0, 30, 30)

local function Main()

    local char = math.floor(gfx.getchar())
    if char == -1 or char == 27 then
        gfx.quit()
        return
    end 

    local chars = {}
    for i = 1, 200 do
        local char = math.floor(gfx.getchar(i))
        if char and char ~= 0 then
            chars[#chars+1] = string.char(i)
        end
    end

    gfx.x, gfx.y = 16, 16
    gfx.drawstr(table.concat(chars, "\n"))

    gfx.update()
    reaper.defer(Main)

end

Main()

I did, however, just find a bug - it works fine for the letter keys, but for everything else it gets stuck and continues returning 1 for the life of the gfx window. Bug report here: https://forum.cockos.com/showthread.php?p=2010727