3

I would like to detect keyboard shortcuts like CTRL+S in Scala. It is easy if only one key is pressed, but it seems to be difficult if two or more keys are pressed. Is there any better solution than the following?

reactions += {
  case c @ KeyReleased(_, Key.S, _, _) =>
    if (c.peer.isControlDown())
      // CTRL+S pressed
}

It feels somehow semantically incorrect since it checks if the CTRL button is pressed after the S button is released (and I think it is not really better when you use KeyPressed or KeyTyped).

Here is a SSCE:

import scala.swing._
import scala.swing.event._

object SSCCE extends SimpleSwingApplication {
  def top = new MainFrame {
    val textArea = new TextArea(3, 30)
    contents = new FlowPanel {
      contents += textArea
    }
    listenTo(textArea.keys)
    reactions += {
      case c @ KeyReleased(_, Key.S, _, _) =>
        if (c.peer.isControlDown())
          Dialog.showMessage(null, "Message", "CTRL+S pressed")
    }
  }
}
Simon
  • 4,103
  • 7
  • 28
  • 53

1 Answers1

2

You can check within the pattern match by testing the modifiers:

case c @ KeyReleased(_, Key.S, mods, _) if (1 == (1 & mods>>7)) =>
  Dialog.showMessage(null, "Message", "CTRL+S pressed")

When Ctrl is down, the bit at index 7 is set.

However, I think your original code is easier to understand.

Adding a helper function would help, of course:

def ctrlDown(mods:Int) = (1 == (1 & mods>>7))
...

case c @ KeyReleased(_, Key.S, mods, _) if ctrlDown(mods) =>
  Dialog.showMessage(null, "Message", "CTRL+S pressed")
DNA
  • 42,007
  • 12
  • 107
  • 146
  • Thanks. But yeah, I also think that this is even harder to understand... I think/thought there has to be a nicer, more scalable solution (for shortcuts with X key presses)... – Simon Apr 16 '14 at 12:45