技術ひろば.net の2011年3月の勉強会で話そうと思っていた内容です。
代わりというのもなんですが、5月のミニ勉強会でやりたいと思います。Developers Summit 2011 のライトニングトークで話しした内容のロングバージョンです。
Silverlight 4 (4 に特化した API は使っていないですが)でマルチタッチマニピュレーションを実現する方法の紹介です。
※マルチタッチマニピュレーション = 画面上のオブジェクトを指で移動したり、2本指で拡大/回転したりのこと
※pptx 版 はこちら(アニメーション付きなので、こちらの方がわかりやすいかも)、ソースコードはこちら
Silverlight はマルチタッチがちょっとだけ苦手
Silverlight はマルチタッチの処理がちょっとだけ苦手です。
Windows ネイティブや WPF はマルチタッチマニピュレーションの API を持っていますが、Silverlight はそれを持っていません。取れるのはタッチポイントの情報まで。
ならば自前で計算するとどうなるのか?というのがテーマです。
結論から言うと「楽勝!」とは決して言えないまでも、想像していたほどには難しくはなかったなという感想を持っています。
Touch.FrameReported イベントを使う
Silverlight では、プライマリポイント(=1点目のタッチ)をデフォルトでマウスイベントに自動的に昇格してくれます。つまり、何もしなくてもすべてのアプリケーションはタッチ対応と言えます。もちろん UX 面での使いやすさという問題はありえますが、タッチ対応であることは事実。
ただし、マウスイベントに自動昇格されては都合が悪いこともあります。マルチタッチでの操作がその一つ。
ではどうするかというと、Touch クラスを使います。これの FrameReported イベントを処理することで自動昇格に頼らずにアプリケーション固有のタッチ操作の処理を行うことができます。
Touch クラスがわかりにくい点は、マウスイベントは UIElement ごとに発生するのに対して(そして開発者はそれに慣れている)、アプリケーションのレベルでイベント処理しなければならないという点。イベントハンドラ内で「じゃあ、実際どのUIElement上で発生したのよ?」というのを判断しなければなりません。
高校時代の行列を思い出す (または勉強し直す w)
マルチタッチマニピュレーションを実現するためにもう一つ必要なのが行列演算。
高校時代に数学の時間にやったアレです。Silverlight ではタッチポイントの情報は取れると書きましたが、この座標情報からオブジェクトを移動/回転/拡大させた座標を求めるのに行列を使います。


これを Silvelight の側から見ると、Matrix 構造体 を使うということになります。
長くなってきたのでこの投稿は一旦ここで区切ります。ライトニングトークのレベルなので続きは改めて書こうかと思います。
今回は:
- Silverlight ではタッチ操作については座標が取れるのみ
- タッチイベントはアプリケーションレベルで処理する
- マニピュレーションには行列演算が必要
という3点を抑えておけばいいかと思います。
技術ひろば.net の5月の勉強会は 21日(土) の開催(予定) です。これを書いている時点ではまだ受付をしていませんが、興味のある方はぜひ情報の更新を少しだけ気にかけてもらえるとうれしいです。