Reputation: 8722
How do I build keyboard combinations into my Elm app, eg. "shift + alt + enter"? You would do something like this to react to a single key pressed (for example the enter key):
import Keyboard
type Msg
= KeyDown Keyboard.KeyCode
type alias Model =
...
update msg model =
case msg of
KeyDown key ->
handleKeyDown key model
subscriptions model =
Sub.batch
[
Keyboard.downs KeyDown
]
handleKeyDown key model =
case key of
13 -> -- Enter key
Debug.log "Other key"
model
_ -> -- Any other key
Debug.log "Other key"
model
view model =
...
But how can you do the same for multiple keys pressed?
Upvotes: 4
Views: 738
Reputation: 3081
From the documentation:
Longer-term, it makes sense to help track key combinations and a couple other common scenarios. If you have a particular problem you think this library could address more directly, please describe it as a SSCCE in an issue. Please do not suggest the solution. Just describe the scenario. Once it becomes clearer what folks are up to, it will be time to add support for those cases in a coherent way.
So, at least it means that it is not supported right now. I'm not fully sure whether it also means that you should open an issue to encourage this later addition or not.
Now, Chad's answer looks like a good temporary solution to me. It looks even better with swelet's suggestion of tracking only a few modifier keys. Note how if you take this approach you don't need to rely on any List
or Set
but you can instead have a little record with 4 booleans.
Finally, if you want for some reasons to track all the keys (if for instance you would like the user being able to link [F1] to some action, then performance-wise it would make sense to use a more efficient representation of sets. Any subset of a finite set for instance can be defined as a single number, each bit being a boolean meaning absence or presence of one particular element. You can do such things with the Bitwise library.
Upvotes: 1
Reputation: 36375
You could use Keyboard.downs
as pdoherty926 mentioned as well as a Set
to keep track of which keys are pressed. You'll need to look at Keyboard.ups
as well to know when a key is released.
Here is a working example:
import Html exposing (..)
import Html.App exposing (program)
import Keyboard exposing (..)
import Set exposing (Set)
import Char
main =
program { init = (initialModel, Cmd.none), view = view, update = update, subscriptions = subscriptions }
initialModel =
{ keysDown = Set.empty
}
view : Model -> Html Msg
view model =
text <| toString <| Set.map Char.fromCode model.keysDown
type Msg
= KeyDown KeyCode
| KeyUp KeyCode
type alias Model =
{ keysDown : Set KeyCode
}
update msg model =
case msg of
KeyDown key ->
({ model | keysDown = Set.insert key model.keysDown }, Cmd.none)
KeyUp key ->
({ model | keysDown = Set.remove key model.keysDown }, Cmd.none)
subscriptions _ =
Sub.batch
[ Keyboard.downs KeyDown
, Keyboard.ups KeyUp
]
Upvotes: 5