Archive for 2010年6月13日|Daily archive page

GUI で midi する。。。または、キーボードを鍵盤に(解説編)

前回の “GUI で midi する。。。または、キーボードを鍵盤に” は如何だったでしょうか?

さて、解説と言っても、短いスクリプなので解説もいらないかもしれません。
今回の目玉は、gs:key-event と midi 関連関数 gs:midi-xxx だと思います。
まずは、gs:key-event から。
この関数で指定したハンドラ関数 key-action が取る引数は、4つあります。

(key-action id type code modifiers)

この内、id はおなじみ、イベント発生場所のコンポーネントID です。
type にはキーが押されたか離れたかで文字列 “pressed” か “released” が入ります。
code はキーコードで、大抵は ASCII コードですが、一部違うものがあります。前回紹介したスクリプトは日本語106用です。他のキーボードでは、動かないキーが有るかもしれません。関数key-action の一行目のコメント・アウトを外して確認して下さい。
modifiers には、SHIFT キーや CTRL キーの状態が入っています。ビット0 が SHIFTキー、ビット1 が CTR Lキーで、それぞれ押されると 1 が入り、押されていなければ、0 が入ります。
参考までに、modifiers の解析用関数を作ってみました。

(define (parse-modifiers n)
  (1 (map int (explode (bits (+ 32 n))))))
(define (translate-modifiers n)
  (let (syms '(left-click middle-click right-click ctrl shift)
        mods  (replace 0 (parse-modifiers n) nil))
    (replace nil (map and mods syms))))

実行すると、

> (parse-modifiers 17)
(1 0 0 0 1)
> (translate-modifiers 17)
(left-click shift)

こんな感じです。この引数には、SHIFT キーや CTRL キーの他にマウス・ボタンの動作も入って、マウス・イベント関数mouse-action でも使われています。
閑話休題、gs:key-event に戻りましょう。
この関数は、

(gs:key-event 'OutputArea 'key-action)

このように、ハンドラが動作するコンポーネントを指定します。
つまり、このコンポーネントがアクティブ時のみイベントが起こります。
これが曲者で、gs:listen ではうまく動かないのです。
gs:check-event でループをまわし、gs:request-focus を使って強制的にコンポーネントをアクティブにすることが必要です。

(while (gs:check-event 10000)
   (gs:request-focus 'OutputArea) ; keep focus in canvas
)

これが gs:key-event を使う時の肝でした。
さて、今回はこれくらいにして、残り midi 関連は、次回に。

以上、如何でしょうか?