Sencha Desktop PackagerでネイティブAPIを使う
こんにちは、ゼノフィnakamuraです。
Sencha Desktop Packagerを使用すると、既存のWebアプリケーションをデスクトップアプリケーションとして使えるようになります。メニューの作成やファイルダイアログの表示やファイルシステムのアクセスなどの追加APIを利用することによって、ネイティブプラットフォームを統合できます。このブログ記事では、ネイティブAPIの利用方法を示すために単純なテキストエディタを紹介します。
もしSencha Desktop Packagerをあまりご存知でなかったら、この3分間のチュートリアルビデオをご覧になって下さい。まだDesktop Packagerをお持ちでない場合は、30日の体験版をダウンロードして下さい。こちらはWindows、OS X、およびLinuxで利用可能です。いつでもオンラインのドキュメントが参照できます。
基本構造
シンプルなテキストエディタの主な構成要素はテキストフィールドです。これは次のシンプルなindex.htmlを用いています:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | <html> <head> <style> body { margin: 0 } textarea { height: 100%; width: 100%; border: none; outline: none; font-family: Menlo, 'Courier New', monospace; } </style> </head> <body> <textarea id="text"> </textarea> </body></html> |
パッケージするには、次のような対応するマニフェストファイルが必要です:
1 2 3 4 5 6 7 8 9 10 11 12 | { "organizationName": "Sencha", "applicationName": "Text Editor", "versionString": "1.0", "outputPath": "TextEditor", "webAppPath": "src/", "settings": { "mainWindow": { "autoShow": true } } } |
マニフェストファイルはtexteditor.jsonという名前だとすると、index.htmlをsrc/
サブディレクトリの下に置くと、デスクトップアプリケーションの構築は、次のように簡単に実行できます。
1 | ionpackage texteditor.json |
アプリケーションはTextEditor/ サブディレクトリの下に作成されます。それを起動すると、テキストエディタに期待する通り、空のテキストフィールドを持つウインドウが表示されます。
ネイティブメニューの追加
言うまでもなく、ユーザーが既存のファイルを開くことがでければ、テキストエディタはあまり役に立ちません。これへの第一歩はユーザーがいくつかのアクションを実行できるように、インターフェイスを作成することです。最初はメニューバーとファイルメニューの作成です。この追加のロジックはui.js
のJavaScriptファイルに実装され、同じ src/
サブディレクトリに設置する必要があります。ここでは(メインウインドウにある)Ion.ui.MenuBar を利用し、メニューバーを作成してデータを読み込みます。
1 2 3 4 5 6 | function createUI() { var fileMenu = Ion.ui.mainWindow.menuBar.addMenu('&File'); fileMenu.addMenuItem('Open', function(){}, 'Ctrl+O'); fileMenu.addSeparator(); fileMenu.addMenuItem('Save', function(){}, 'Ctrl+S'); } |
メインのindex.html
からこの関数createUI
を呼び出す必要があります。この例では、それをドキュメントのonLoad
ハンドラーから呼び出します。もちろん、ui.js
を含むために新しいスクリプトタグを追加することを忘れないで下さい。
またionpackage texteditor.json
を実行して、アプリケーションを再びパッケージすると、メインウィンドウにメニューバーが出てきます。ファイルメニューをクリックすると全ての項目が表示され、それぞれの項目にはcreateUI()
関数で指定された対応するショートカットが付いています。とても簡単だと思いませんか?
ファイルダイアログの利用
残念なことに、新しいメニューの項目はまだ意味のある働きはしないので、役に立ちません。両方のメニュー項目に実際のハンドラーを与えると変更することができます。次のように私達のJavaScriptのロジックを微調整する必要があります:
1 2 3 4 5 6 7 8 | var filename; function createUI() { var fileMenu = Ion.ui.mainWindow.menuBar.addMenu('&File'); fileMenu.addMenuItem('Open', handleOpen, 'Ctrl+O'); fileMenu.addSeparator(); fileMenu.addMenuItem('Save', handleSave, 'Ctrl+S'); } |
空の関数の代わりに、handleOpen
と handleSave
をOpenとSaveのメニュー項目にそれぞれ渡して下さい。最初の段階として、ユーザーがファイルを開きたい時にネイティブファイルダイアログを呼び出すことができます。これは次のようにIon.ui.browseFilesを通して実装されます。(同じことはSaveメニューでも行えますが、そこは読者への宿題にしておきます。)。
1 2 3 4 5 6 7 8 | function handleOpen() { Ion.io.browseFiles({ caption: 'Load Text File', path: filename, filters: [['Text Files', '*.txt']], type: 'open' }); } |
Openメニューがクリックされたら、次のスクリーンショットで表示されているように、ユーザーがファイルを選択できるようにファイルダイアログボックスがポップアップします。
ファイルのアクセス
ファイルダイアログそれ自体は動作しません。アプリケーションはユーザーが選択したファイルを知っていますが、まだそれで何か行う必要があります。Desktop PackagerファイルシステムAPIのお陰で、ファイル内容を読み込むための追加のロジックを加えます。この場合はIon.io.readFileを利用します。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | function handleOpen() { var result, content; result = Ion.io.browseFiles({ caption: 'Load Text File', path: filename, filters: [['Text Files', '*.txt']], type: 'open' }); if (result.success) { content = Ion.io.readFile(result.value); if (content.success) { document.getElementById('text').value = content.data; filename = result.value; } } } |
上記のhandleOpen
の新しい実装で私達の小さなテキストエディタがついにオープンファイルダイアログを介してユーザーが選択したテキストファイルから内容をロードするための完全に機能するユーザーインターフェイスをやっと取得しました。
最後に、もしパッケージしたアプリケーションをテストする必要がある場合は、Desktop Packagerのremote debugging featureを利用して下さい。デバッガーにコンソールがありますので、ネイティブAPIと遊びながら、アプリケーションロジックを分析もできます。
パッケージングを楽しんで下さい!