タッチ対応アプリケーションショーケース

ブログでたびたび取り上げている 「Windows 7 マルチタッチ対応アプリケーション開発者会議」。

参加者が求められたのがタッチアプリケーションの公開です。その成果が MS のサイトでまとめられています。

タッチ対応アプリケーション ショーケース

スレートPC、タッチスクリーンなどお持ちの方は、面白そうなアプリを見つけて使ってみるのがよろしいかと。

覗いてみると、皆さんきっちり作ってるんですね。誰かさんのように「4日で作りました(うち、アイコン探しで1日w)」と威張ってる場合じゃないです。
ま、一応 Silverlight で作ったということと参考情報としてソースコード公開をページ上で謳っている唯一のアプリということで、そこは大目に見てくださいな。


ところで、一つ上の階層の タッチ対応アプリケーション技術情報 を見ても、ネイティブ、MFC、.NET (WPF と思われる) というキーワードは並んでいるものの、やっぱり Silverlight は見当たらない。

ネイティブはともかくとして、スレートPC のスペックを考えると(今後、スペックが上がっていくとしても)、生産性とパフォーマンスとのバランスを考えると Silverlight はタッチアップリケーション開発には有効な技術だと思うんですけどね。
MS さんにはもっと情報提供をお願いしたいところでもあるんですが、さしあたっては この辺の情報 とか こんなソースコード とかを参考にしていただければ。

 

 


余談ですが、開発者会議には100名の方が参加したはず。私の数え方が悪いのか、公開されているアプリケーションはどうもその数には大幅に満たないような気が・・・(笑)。

[Silverlight] Tips : マルチタッチ対応の定石

Silverlight でマルチタッチな操作を実現するには Touch.FrameReported イベントを処理する必要があります。

※逆に言うと、シングルタッチの対応だけでよく、かつマウスとタッチとを区別する必要がなければ、ランタイムがタッチイベントをマウスイベントに自動的に昇格してくれるので、マウスイベントを処理するだけでいいということ。

処理の内容はもちろんアプリケーションごとに異なるわけですが、構造はかなり定型的です。
以下のコードがそれ。

01: public MainPage()
02: {
03:     InitializeComponent();
04:
05:     // マルチタッチのイベントハンドラ
06:     Touch.FrameReported += new TouchFrameEventHandler(Touch_FrameReported);
07: }
08:
09: // 前回のタッチイベントの時の座標
10: private Dictionary prevPoints = new Dictionary();
11:
12: void Touch_FrameReported(object sender, TouchFrameEventArgs e)
13: {
14:     // プライマリポイント(=1点目のタッチ)でマウスイベントへの自動昇格を止める
15:     TouchPoint primaryPoint = e.GetPrimaryTouchPoint(LayoutRoot);
16:     if (primaryPoint != null &&
17:             primaryPoint.Action == TouchAction.Down)
18:         e.SuspendMousePromotionUntilTouchUp();
19:
20:     // 今回のイベントでのすべてのタッチポイントの情報
21:     TouchPointCollection touchPoints = e.GetTouchPoints(LayoutRoot);
22:
23:     // 1点ごとに処理
24:     foreach (var touchPoint in touchPoints)
25:     {
26:         TouchDevice dev = touchPoint.TouchDevice;
27:         TouchAction action = touchPoint.Action;
28:
29:         if (action == TouchAction.Down)
30:         {
31:             // タッチ開始
32:
33:             prevPoints.Add(dev.Id, touchPoint.Position);
34:         }
35:         else if (action == TouchAction.Move)
36:         {
37:             // タッチポイントの移動
38:         }
39:         else if (action == TouchAction.Up)
40:         {
41:             // タッチ終了(指が離れた)
42:
43:             prevPoints.Remove(dev.Id);
44:         }
45:     }
46: }

 

  • 6行目 ・・・ Silverlight でタッチイベントを処理するには必ずこの行が必要。Silvelight では、タッチイベントはアプリケーションの中の1カ所で処理しなければならないので(マウスイベントはコントロールごとにイベントハンドラが存在しますよね)、MainPage のコンストラクタで FrameReported イベントにハンドラを結びつけます。

  • 10行目 ・・・ 単に「タッチされた」だけでいいのであれば不要ですが、前回のタッチポイント(座標)との差が必要になることがあるでしょう。回転や拡大、移動などでは必須ですよね。このために前回のタッチポイントを保持する変数を用意します。ここで Dictionary のキーを int にしているのは、タッチが始まってから指を離すまでの間、各ポイントは同一の ID を持っているから。この ID を見ることでどの指がどこに移動したかを追いかけることができます。

  • 12行目~ ・・・ タッチイベントハンドラの本体

  • 15~18行目 ・・・ 何もタッチされていない状態から最初のタッチが始まると、ランタイムはその点をプライマリポイントとして返してくれます。マウスイベントの自動昇格されるのはこの点の情報。 自動昇格が都合が悪い時には SuspendMousePromotionUntilTouchUp で昇格を止めます。昇格が止まるのは文字通りタッチアップまでの期間だけなので、大抵の場合はプライマリポイントに対して毎回昇格を止めることになるはず。

  • 21行目 ・・・ GetTouchPoints で今回のイベントでのすべての点(1点でも2点でもそれ以上でもまとめて)を返してくれます。

  • 24行目~ ・・・ GetTouchPoints で得られた各点について順番に必要な処理をしていきます。

  • 26, 27行目 ・・・ 後のコードを見やすくするために。ちなみに上で触れたタッチポイントの ID は TouchDevice.Id プロパティで得られます。

  • 29行目~, 35行目~, 39行目~ ・・・ 今回のイベントで、タッチポイントがタッチされ始めたか、指が移動したか、タッチが終わったかを判断しています。あとはそれぞれのブロックの中に必要な処理を入れていけばマルチタッチ対応なアプリケーションになります。33行目、43行目のように、タッチポイントのトラッキングを始めたり止めたりするのもお忘れなく。

Silverlight でタッチ対応しようとすると、まず例外なくこの構造になるはず。 こうして見ると、マルチタッチ対応は(コード上では)それほど難しくないことがわかると思います。

マルチタッチアプリケーション(MemoBoard)のソースコードを公開しました

先日公開した マルチタッチアプリケーション MemoBoard ですが、ソースコードもあわせて公開します。ヘボいコードなので結構恥ずかしいんですが、マルチタッチアプリケーションを開発する上での参考になれば。

 

http://www.seosoft.net/files/MemoBoard/MemoBoard_src.zip

一応、各クラスについて簡単な説明をしておくと:

App.xaml / App.xaml.cs アプリケーション アプリケーションのバージョン確認、データ保存のための MainWindow の Closing イベントのフックを行う
MainPage.xaml / MainPage.xaml.cs メインウィンドウ メモ領域の名前は “MemoArea” (Canvas)
タッチイベントはここで一元的に処理する
Memo.xaml / Memo.xaml.cs メモ用紙クラス Memo クラスのインスタンスは動的に生成して、MemoArea の Childlen に Add している
メモの移動や拡大も Memo クラス自体がイベント処理を行う
マウスイベントはこのクラスで処理している
TouchFunctionType.cs ステータス(実行中の機能) ツールバーボタンの選択状態に応じた、アプリケーションの実行中機能を表す

 

ソースを見ていただければ、コード量の少なさがわかっていただけるかと思います。マルチタッチマニピュレーションは考え方さえわかれば、コードはそれほど難しくないということです。

 

少しずつでも説明も進めないといけないな>自分

マルチタッチアプリケーションを公開してみた

去年(2010年)の12月に 「Windows 7 マルチタッチ対応アプリケーション開発者会議」というイベントがありまして、運よく参加させていただきました。その時にスレートPCをいただいたんですが、引き替えに「おらおら、タッチアプリケーション作れよ~」と言われたわけです。

そこで作ってみました。
タッチ操作用のメモアプリケーションです。付箋紙をボードにペタペタ貼り付けるイメージで使うアプリです。2本指でピンチ操作やマウスホイールでメモ用紙を拡大できるので、指でも細かいメモを取れると思います。
Out of Browser な Silverlight アプリなのでインストールして使うこともできます。
興味のある方(勇気のある方?)はちらっと覗いてみてください。

http://www.seosoft.net/files/MemoBoard/

実際に操作した結果は、こんな感じ。

mbdemo

www
※権利関係は大目に見てください

マウスでも操作できますが、こんなに上手な絵を描くことは難しいと思うのでw、ぜひスレートPCとかタッチスクリーン付きのPCでお試しください。


コミュニティー活動をしているということから参加させていただけたイベントなので、売り物を作ろうということではなくて、話のネタ(=セッション、ブログ) になるような利用をしようと考えました。それでデブサミで5分間いただいてマルチタッチマニピュレーションの話をしたり、勉強会の資料を作ったり(都合によりセッションはまだ実現してないけど)しました。

開発者会議の宿題のアプリケーションも同じ目的で作ったので、アプリでやってること、苦労したことなどを共有していきたいなと思います。恥を忍んでソースコードも公開します(って、まだソースの整理してないことに今気づいた orz)。
ちなみに諸々の事情によりアプリ開発の時間が満足に取れなかったので、4日ほどででっち上げたw アプリです。そのあたりで作りは甘いかもしれませんが、幸いデブサミ LT の準備でざっとマルチタッチの要点は見ていたので、マルチタッチのコーディング自体はそれほど苦労しませんでした(ウソです)。

Silverlight のマルチタッチなネタについて、As Is の状態ですがひとまず出すことができました。これからテクニックや Tips として整理していきたいと思います。

 

技術ひろば.net の5月の勉強会は 21日(土) の開催(予定) です。Silverlight やらマルチタッチやらについて直接情報共有することもできると思います。これを書いている時点ではまだ受付をしていませんが、興味のある方はぜひ情報の更新を少しだけ気にかけてもらえるとうれしいです。

Silverlightで作るマルチタッチアプリケーション (技術ひろば.net 版)

技術ひろば.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 ではタッチポイントの情報は取れると書きましたが、この座標情報からオブジェクトを移動/回転/拡大させた座標を求めるのに行列を使います。

image

image

これを Silvelight の側から見ると、Matrix 構造体 を使うということになります。

長くなってきたのでこの投稿は一旦ここで区切ります。ライトニングトークのレベルなので続きは改めて書こうかと思います。
今回は:

  • Silverlight ではタッチ操作については座標が取れるのみ
  • タッチイベントはアプリケーションレベルで処理する
  • マニピュレーションには行列演算が必要

という3点を抑えておけばいいかと思います。

技術ひろば.net の5月の勉強会は 21日(土) の開催(予定) です。これを書いている時点ではまだ受付をしていませんが、興味のある方はぜひ情報の更新を少しだけ気にかけてもらえるとうれしいです。

[Silverlight] Tips : 境界線なしの Out of Browser アプリケーションを終了する方法

Silverlight の Out of Browser についての Tips をいくつか書いてます(時間かかりすぎだが・・・)。


前回 の続きとして、Silverlight の境界線なし Out of Browser アプリを終了する方法です。
紹介しますと言って、メチャメチャ簡単なんですが。
コードは2行です。

境界線なしの OOB アプリを終了する方法を用意しなければならないのは、実行中のアプリの画面を見ればすぐわかります。

image

タイトルバーがないために [閉じる] ボタンもありません。これじゃアプリを終われません。


結論から言うと、MainWindow を Close するだけです。
ただし In Browser でこれを実行しても意味がないので、IsRunningOutOfBrowser の確認をします。
これだけです。

例えば、Button の Click イベントハンドラであればこうなります。

private void CloseButton_Click(object sender, RoutedEventArgs e) { if (Application.Current.IsRunningOutOfBrowser) Application.Current.MainWindow.Close(); }

 


一応、 前の投稿 の「見た目がわかりやすいアプリ」にボタンを一つ追加してみます。

せっかくの Silverlight アプリですから、当然本来であればもっと見栄えのするボタンを貼るべきでしょうが、とりあえず地味な Button だと、こんな風にするのはどうでしょう。

image

念のため、ソースコード(XAML)も載せておきます。

<UserControl x:Class="OobWinStyle.MainPage"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    mc:Ignorable="d"
    d:DesignHeight="300" d:DesignWidth="400">

    <Grid x:Name="LayoutRoot" Background="Wheat">
        <Rectangle Name="DragArea" Width="400" Height="51" Stroke="Black" StrokeThickness="1" HorizontalAlignment="Left" VerticalAlignment="Top"
                   Fill="MidnightBlue" MouseLeftButtonDown="DragArea_MouseLeftButtonDown" />
        <Button Name="CloseButton" Content="×" Width="33" Height="30" Margin="0,12,8,0" HorizontalAlignment="Right" VerticalAlignment="Top"
                FontSize="16" Click="CloseButton_Click" />
    </Grid>
</UserControl>

境界線なしの Out of Browser アプリでも、ウィンドウ移動もアプリ終了も非常に簡単です。

これで見栄えのするアプリケーションが作り放題です(そこの紹介はできません、あしからず)。

[Silverlight] Tips : 境界線なしの Out of Browser アプリケーションでウィンドウ移動する方法

Out of Browser 昇格時のウィンドウスタイル について前のブログで紹介しました。

境界線なしのウィンドウスタイルにすると、アプリケーションのウィンドウ全体でデザインを考えることができると思います。
が、一つ(二つ?)だけちょっとした落とし穴があります。

そのままでは、ウィンドウを移動する手段がないことと、アプリケーションを終了する手段がないことです。
タイトルバーがないんだから当然です。
まずは、ウィンドウを移動する方法を紹介します。と言ってもすごく簡単、定型的。


なにはともあれ、ユーザーがウィンドウを移動するためにドラッグする領域が必要ですね。
UserControl 全体でももちろん制限なく実現できますが、今回はとってもわかりやすく UserControl の上部にそれらしい領域を付けましょうか。

image

こんな感じ。わかりやすすぎ(笑)。

XAML だと、

<UserControl x:Class="OobWinStyle.MainPage"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    mc:Ignorable="d"
    d:DesignHeight="300" d:DesignWidth="400">

    <Grid x:Name="LayoutRoot" Background="Wheat">
        <Rectangle Name="DragArea" Width="400" Height="51" Stroke="Black" StrokeThickness="1" HorizontalAlignment="Left" VerticalAlignment="Top"
                   Fill="MidnightBlue" MouseLeftButtonDown="DragArea_MouseLeftButtonDown" />
    </Grid>
</UserControl>

大体こうなります。もちろん、色やサイズはお好みで。名前もコードとの対応が自分でわかるようならご自由に。


ここでポイントになるのは、ドラッグするための領域とする要素 (今回の場合は Rectangle) のMouseLeftButtonDown イベントハンドラを用意することです。

「あれっ?MouseMove とか MouseLeftButtonUp はいらないの?」と思うかもしれませんが、はい、いりません。

では肝心の MouseLeftButtonDown イベントハンドラの中身はどうなるかというと、以下の通り。

private void DragArea_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
    if (Application.Current.IsRunningOutOfBrowser)
        Application.Current.MainWindow.DragMove();
}

「MainWindow の DragMove を始めます」というだけなんですね、簡単、簡単。

もう一つ注意が必要なのは、当然、ブラウザ内実行では、この領域のドラッグで移動するわけではないので、Application.Current.IsRunningOutOfBrowser プロパティの値を確認すること。

これをブラウザ外で実行してみてください。ちゃんとウィンドウ移動できるはずです。

次回の Tips は(もしかするとウィンドウ移動よりももっと大事な) 境界線なし Out of Browser なアプリケーションを終了する方法です。

[Silverlight] Tips : Out of Browser 昇格時のウィンドウスタイル

すっかり間が空いてしまってますが、Silverlight の Tips (本当に Tips レベル !!)を、自分のための覚え書きの意味を含めてポツポツと整理しようと思っています。
(が、なかなか手がつかない・・・)
スタートの方向性としては若干間違っている気もしますが、Out of Browser 周りから進めてみます。

に続いて、Out of Browser で権限昇格時に指定可能なウィンドウスタイルについて。


 

昇格した Out of Browser では3通りのウィンドウスタイルから選択できます。

デフォルトでは標準的な、タイトルバーと境界線を持ったスタイルになりますが、せっかくブラウザの外に出たんだし、フレームまで含めてちょっと見た目のことも考えてみたいということもあるでしょう。

ウィンドウスタイルとしては3通りから選択して指定できます。それぞれ以下のような違いがあります(比較しやすいようにクライアント領域の背景色を変えてあります)。

image タイトルバーと境界線を表示する(標準的なウィンドウスタイル)
image タイトルバーと境界線を表示しない
image さらに、ウィンドウの四隅を丸くする

 

境界線なしの2つの違いがちょっとわかりにくいかもしれないので、ウィンドウの角を拡大表示するとこんな感じ。

image 境界線なしだけ
image 四隅を丸くしたもの

 


これらの指定はプロジェクトのプロパティで選択できます。

image

[Silverlight] タブの [アプリケーションのブラウザー外実行を有効にする] をチェックします。
さらに [ブラウザ外実行の設定] ボタンで詳細設定のダイアログボックスを開きます。

SNAGHTMLab207e

デフォルト以外のスタイルに変更するには、[ブラウザー外での実行時に昇格された信頼を要求する] チェックする必要があります。これをチェックすることでウィンドウスタイルは3通りから指定できます。

 


これらの指定は、OutOfBrowserSettings.xml に保存されます。

SNAGHTMLb0600d

WindowsSettings 要素の中に WindowStyle 属性があります。
(当然、テキストエディタで直接編集することも可能だということです)

属性値はそれぞれ以下の値です。

SingleBorderWindow タイトルバーと境界線を表示する
None タイトルバーと境界線を表示しない
BorderlessRoundCornersWindow タイトルバーと境界線を表示せず、ウィンドウの隅の角を丸める

 


タイトルバーと境界線を非表示にすることで、アプリケーション全体でトータルに画面のデザインをすることができます。今どきのアプリケーションでは考慮する価値のあるものなので、(要求や工数によりますが)

積極的に利用を検討してみてもいいと思います。

・・・が、タイトルバー非表示にすると考慮点が増えるので注意。
ウィンドウの移動とアプリケーションの終了が、そのままではできなくなります。(そりゃそうだ、タイトルバーがないんだから)

ということで、次回はタイトルバーなしの Out of Browser アプリケーションでウィンドウの移動と終了に対応する Tips を紹介します。

Silverlight で作るマルチタッチアプリケーション (Developers Summit 2011 17-D-3 LT セッション)

Developers Summit 2011 の MVP & .NET Community Members Lightning Talks に登壇させていただきました。

テーマは「Silverlight で作るマルチタッチアプリケーション」です。
Silverlight でマルチタッチマニピュレーション(2点タッチで拡大とか回転)をする方法の紹介です。

スマートフォンでも iPad でも普通にできて、Windows ネイティブでも WFP でも普通にできて、Windows Phone 7 でも風通にできる、マルチタッチマニピュレーションですが、デスクトップ用 Silverlight ではちょっとだけ苦労します。
というのも、タッチポイントの情報は取れるもののマニピューレーション対応の API を持っていないから。

それではと言うことで、Matrix クラスを使って座標変換してしまいます。

その際に必要になるのが、高校時代の数学でやった行列の計算。
覚えてます?行列?
私はすっかり忘れてましたw
今回のネタのために久しぶりに勉強しました。

思ったよりはコードもシンプルで、サクサク動いてくれますが、さすがに5分でちゃんと説明するのは難しい。
ということで、ブログと 技術ひろばの勉強会(多分?) でフォローしたいと思ってます。興味のある方はチェックを。

[Silverlight] Tips : Out of Browser 実行を有効にする方法

Out of Browser の Tips シリーズです。

前の投稿で 「そもそも In Browser か Out of Browser かが判別できないとお話にならない」 と書きました。
が、そもそもで言うと、もしかして Out of Browser 実行を有効にする方法自体を説明する必要があるのかも、と思い立ち、順番としては逆になりますが、書いておきます。
(それとも、これを知らずに Out of Browser しようとするっていうのは、さすがにないのかな・・・)


Silverlight プロジェクトのプロパティーを開くと、最初のタブは [Silverlight] になっているはず。
その中に [アプリケーションのブラウザー外実行を有効にする] というチェックボックスがあるので、これをチェックします。
これで、Out of Browser 実行できるようになります。

SNAGHTML1f2220

これでプロジェクト内に “OutOfBrowserSettings.xml” という設定ファイルができます。この内容がビルド時に “AppManifest.xaml” に埋め込まれて、アプリケーションの実際の実行時に Out of Browser の挙動が決まります。

SNAGHTML279369


“OutOfBrowserSettings.xml” にはあらかじめデフォルト値が埋め込まれていますが、プロジェクトのプロパティーの [ブラウザー外実行の設定] ボタンで、アプリケーションのタイトルや、サイズ・位置、アイコンなどの指定ができます。
(もちろん、OutOfBrowserSettings.xml を直接編集してもいいですが)

SNAGHTML237d88

 

ダイアログボックスの中では Trusted Permission の指定やウィンドウスタイルの選択も可能なんですが、これらについてはまた改めて。

フォロー

Get every new post delivered to your Inbox.

現在513人フォロワーがいます。