GO BACK

AppleScript Studio教室 その7

「より本格的なアプリへ」



■ドロワーを使ってみよう!

 さて、AppleScript Studioを使ってごく簡単なアプリが作れることはわかってきました。今回は、もうちょっと難しそうなアプリを作ってみましょう。そのためには、もう少し複雑なインターフェイスの使い方を覚えておく必要もあります。

 まずは、「ドロワー」の利用から考えていきましょう。ドロワーというのはMac OS Xからサポートされたインターフェイスで、ウィンドウの横に引き出しのようにくっついて出てくる、アレのことです。Mailやその他さまざまなアプリで使われていますね。せっかくアプリ作りに挑戦するなら、「いかにもMac OS X用」といったものを作りたいものです。ドロワーは、「これぞXのためのもの」という感じがしますね。

 このドロワーは、Cocoaでは「NSDrawer」という名前の部品として用意されています。これはInterface Builderのパレットの左から4番目のアイコン(Cocoa Windows)の中にあります。「Drawer」とでっかく表示されているのがNSDrawerの部品です。この他、ウィンドウとセットになった部品もその上に用意されています。

 ドロワーは、ウィンドウにくっついて動くというかなり変わったインターフェイスですので、いろいろと使い方に決まりがあります。それをよく頭に入れておかないと、ドロワーを利用することはできません。特に、「NSDrawerでは、内部に表示する部品が必要だ」ということはよく理解しておく必要があります。これには通常、「NSView」と呼ばれる部品が用いられます。これは、パレットの右から3番目(Cocoa Container Views)のアイコン内にあります。「Custom View」と表示されている部品です。

 では、実際にドロワーを作ってみましょう。作成の手順を以下に示しますので順番にやってみて下さい。

  1. まずInterface Builderでnibファイル(MainMenu.nib)を開き、パレットのCocoa Windowsアイコンを選択します。
  2. そこにあるNSDrawer部品(右下のDrawerと書いてるやつ)を、Nibファイルウィンドウの「Instances」タブのエリア内にドラッグ&ドロップします。(デザインウィンドウではないよ!)すると、「NSDrawer」と表示されたアイコンが追加されます。
  3. 次に、ドロワーの中に表示する部品として「NSView」を用意します。Cocoa Container Viewsアイコンを選択し、その中にあるNSView部品(Custom Viewと書いてあるやつ)を、やっぱりNibファイルウィンドウの「Instances」タブのエリア内にドラッグ&ドロップします。これで、「View」と表示されたアイコンが追加されます。
  4. 作成したNSDrawerに、「Parent Window」というものを設定します。これは、ドロワーが取り付けられるウィンドウを示すものです。作業の手順は以下のようになります。
    1. Nibファイルウィンドウの「Instances」タブ内にあるNSDrawerアイコンから、Ctrlキーを押したまま、同じ「Instances」タブ内にあるWindowアイコンまでドラッグ&ドロップしましょう。
    2. 薄紫色の線が延びて2つのアイコンがつながり、Infoウィンドウの「Connections」という表示に切り替わります。
    3. ここで「Outletes」という部分にある「parentWindow」という項目を選択して、下の「Connect」ボタンを押して下さい。これで、つなげたWindowアイコンの部品が、NSDrawerのParent windowに接続されます。
  5. 続いて、NSDrawerに「Current View」というものを設定します。これは、ドロワーに表示する部品を示すものです。——やはりNibファイルウィンドウの「Instances」タブ内にあるNSDrawerアイコンから、Ctrlキーを押したままViewアイコン(先ほど作ったNSViewね)までドラッグ&ドロップします。そしてInfoウィンドウの「Connections」にある「currentView」項目を選択して「Connect」ボタンを押せば、接続完了です。
NSDrawerの設定


 ちょっとややこしいですが、だいたいの流れはわかりましたか? NSDrawerは、このように「ドロワー本体」「組み込むウィンドウ」「中に表示する部品」の3つがセットになっていないとうまく機能しません。また、ドロワーも、その中に表示する部品(NSView)も、ウィンドウの中に組み込むわけではありませんから、今までのボタンなどのようにデザインウィンドウの中に配置してはいけません。こうした「ウィンドウ内に組み込むのではなく、独立した部品」というのは、Nibファイルウィンドウの「Instances」タブの中に追加します。


■NSTableViewについて

 では、ドロワーを使ったアプリケーションを作ってみましょう。今まで、UNIXコマンドを使ったアプリをいくつか作りました。UNIXコマンドはなかなか強力ですが、使い方がわからないと使うこともできません。そこで、UNIXコマンドのマニュアルを表示するアプリを作ってみましょう。

 ここでは、更に新しいインターフェイスとして「NSTableView」というものを使おうと思いますので、先にそちらについて簡単に説明をしておきましょう。これは、パレットの左から5番目(Cocoa Data View)のアイコンを選択すると現れます。左下の一覧表のような部品がNSTableViewです。

NSTableView

 このNSTableViewは、表計算のシートのようなインターフェイスです。縦の列を「カラム(列)」、横の行を「ロウ(行)」と呼びます。また最上列には「ヘッダー」と呼ばれる、列名を表示する部分があります。そして各セルに値を書き込んだりして表のような表示を作れるわけです。

 前に、NSTextViewという長文テキストを扱う部品を使った時に、「これはNSScrollViewという部品の中にNSTextViewが組み込まれた二重構造になっている」という話をしました。このNSTableViewも似たような構造になっています。ただし! こちらはなんと「三重構造」になっているのです。

 まず、一番外側にNSScrollViewがあります。そして、それをダブルクリックすると、中のNSTableView本体が選択されるようになります。更に、その中の各ヘッダー部分をクリックして選択すると、その「列」を示す「NSTableColumn」というものが選択されるようになります。NSTableViewは、このように列単位でデータ管理されているのですね。

 また、NSTableViewを使う場合には、「データの管理をどうするか」についても考えなければいけません。単にNSTableViewを配置しても、それだけでは何もセルに書き込めないのです。表示するデータを管理する仕組みを自分で用意してやらないといけません。

 これはけっこう面倒なのですが、AppleScript Studioの場合には「データ管理用の部品」というのが用意されているので、それを使えば比較的簡単に管理が行なえます。これは「ASKDataSource」というもので、パレットの一番右のアイコン(AppleScript)にある青い立方体のアイコンをした部品です。

 これをNibファイルウィンドウの「Instances」タブのエリア内にドラッグ&ドロップすると、ASKDataSourceというアイコンが作成されます。そうしたら、この部品をNSTableViewのデータ(Data Source)として設定します。これは、以下のように行ないます。

  1. まず、デザインウィンドウに配置したNSTableViewを選択します。注意したいのは、外側のNSScrollViewではなく、内部のNSTableViewを選択する、ということです。すなわち、配置してある部品をクリックした後、ダブルクリックして内側の部品を選択しておきます。
  2. このNSTableViewから、Nibファイルウィンドウの「Instances」タブ内にある「ASKDataSource」アイコンまで、Ctrlキーを押したままドラッグ&ドロップをします。
  3. Infoウィンドウの表示が「Connections」に切り替わるので、その「Outlets」内にある「dataSource」という項目を選択し、「Connect」ボタンを押します。これで、NSTableViewのデータとしてASKDataSourceが設定されます。

ASKDataSouceの設定


 後は、スクリプトを使ってデータ利用のためのさまざまな処理を行なえばいいわけです。それらは実際にサンプルを作りながら説明しますので、ここではNSTableViewとNSKDataSourceの基本だけ頭に入れておきましょう。

■マニュアルブラウザを作る

 では、先ほどいった「UNIXコマンドのマニュアルを表示するアプリ」を作ってみましょう。以下の手順どおりに作業して下さい。

1.まず、新規にプロジェクトを作成したら、先ほどの説明に従ってNSDrawerとNSViewを作成し、接続などの設定を行なって下さい。

2.ではインターフェイスの設計を行ないます。最初にウィンドウからです。ウィンドウを選択し、Infoウィンドウの「AppleScript」で、Nameを「win1」と設定してください。

3.ウィンドウ内に、NSTextField、NSButton、NSTextViewの3つを作成します。これらは、Infoウィンドウでそれぞれ以下のようにアトリビュートとAppleScriptの設定を行なって下さい。

NSTextField
・Send Actionアトリビュート:Only On Enterを選択
・「AppleScript」のName:text1
・「AppleScript」のAction/actionイベントをON
・「AppleScript」のスクリプトファイル(○○.applescript)をON

NSButton
・Nameアトリビュート:List
・「AppleScript」のName:listbtn
・「AppleScript」のAction/clickedイベントをON
・「AppleScript」のスクリプトファイルをON

NSScrollView(NSTextViewの外側のやつ)
・「AppleScript」のName:scroll1

NSTextView(NSTextView本体)
・「AppleScript」のName:textview1
ウィンドウの設計


4.次に、ドロワーに表示するNSViewを設計しましょう。Nibファイルウィンドウの「Instances」にあるViewアイコンをダブルクリックして開いて下さい。NSViewの設計をするためのデザインウィンドウが表示されます。ここに、「NSTableView」を1つ配置して下さい。そして、ASKDataSourceを1つNibファイルウィンドウ内に配置し、先の説明に従ってNSTableViewのdataSourceに設定します。

5.NSViewと、配置したNSTableViewを、以下のようにアトリビュートとAppleScriptの設定します。
NSView
・「AppleScript」のName:view1

NSScrollView(NSTableViewの外側)
・「AppleScript」のName:listscroll

NSTableView
・Allows Empty SelectionアトリビュートをON
・Allows Multiple SelectionアトリビュートをOFF
・Allows Column SelectionアトリビュートをOFF
・OptionエリアのColmsを「1」にする(これで1列の表示になる)
・「AppleScriptのName:listtable
・「AppleScript」のAction/clickedをON
・「AppleScript」のスクリプトファイルをON

NSTableColumn(NSTableViewの1列目のカラム)
・Column titleアトリビュート:command list
・OptionsエリアのEditableとResizableをそれぞれOFF
・Identifierアトリビュート:listcolumn
NSViewの設定


6.最後に、アプリケーションのイベントを1つ設定します。Nibファイルウィンドウで「File's Owner」アイコンを選択し、Infoウィンドウの「AppleScript」で、Application/will finish launchingをONにします(スクリプトファイルももちろんONにしておきます)。これは、アプリケーションの起動処理が完了する時に呼び出されるもので、起動した際に何かの処理を行なう時に多用されます。

 さて、けっこう複雑になってきましたが、これでインターフェイスは完成です。最後にProject Builderに戻り、スクリプトファイルを以下のように記述すれば完成です。かなり長い行があるので、あまり長すぎるものは〜記号をつけて改行して表示してあります。記述の際には、〜で終る行は次行と続けて記述して1行にして書いて下さい。

property flg : false

on clicked theObject
if name of theObject is "listbtn" then
tggleDrawer()
else if name of theObject is "listtable" then
putList()
end if
end clicked

on tggleDrawer()
tell drawer "drawer1" of window "win1"
if flg is false then
open drawer
else
close drawer
end if
set flg to not flg
end tell
end tggleDrawer

on putList()
tell table view "listtable" of scroll view "listscroll" of content view of
drawer "drawer1" of window "win1"
set n to clicked row
end tell
if n = 0 then
set str1 to ""
else
tell data source of table view "listtable" of scroll view "listscroll" of
content view of drawer "drawer1" of window "win1"
set str1 to contents of data cell "listcolumn" of data row n
end tell
end if
set contents of text field "text1" of window "win1" to str1
doMan()
end putList

on action theObject
if name of theObject is "text1" then
doMan()
end if
end action

on will finish launching theObject
tell data source of table view "listtable" of scroll view "listscroll" of
content view of drawer "drawer1" of window "win1"
make new data column at the end of the data columns 〜
with properties {name:"listcolumn"}
end tell
end will finish launching

on doMan()
tell window "win1"
set str1 to string value of text field "text1"
try
do shell script "man" & space & str1
set ans to result
on error
set ans to "not found manual."
end try
set contents of text view "textview1" of scroll view "scroll1" to ans
end tell
tell data source of table view "listtable" of scroll view "listscroll" of
content view of drawer "drawer1" of window "win1"
make new data row at the end of the data rows
set n to data rows count
set contents of data cell "listcolumn" of data row n to str1
end tell
tell table view "listtable" of scroll view "listscroll" of content view of
drawer "drawer1" of window "win1"
update
end tell
end doMan



 完成したらビルドして実行してみましょう。これは、NSTextFieldに入力したコマンドの説明を表示するアプリです。例えば、「ls」と入力してリターンしてみましょう。lsコマンドの説明がNSTextViewに表示されます。

 実行したコマンド名はNSTableViewに記録されるようになっています。「List」ボタンを押すと、ドロワーが開かれ、そこに実行したコマンドの一覧が現れます。一覧からコマンド名をクリックすると、そのコマンドがNSTextFieldに書き出されマニュアル表示されます。

アプリの実行画面


■NSTableViewのデータ利用

 では、リストをチェックしてみましょう。まず、起動時の処理を行なっているwill finish launchingからです。ここでは、以下のようにして1列分のデータをASKDataSouceに作成しています。

tell data source of table view "listtable" of scroll view "listscroll" of 〜
content view of drawer "drawer1" of window "win1"
make new data column at the end of the data columns with properties {name:"listcolumn"}
end tell

 NSTableViewに設定したASKDataSourceは、「data source of table view ○○」という形で指定できます。このdata sourceの中にデータを追加したり、そこから必要なデータを取り出したりするわけです。

 問題は、「NSTableViewの指定の仕方」と、「ドロワー内の部品の指定の仕方」でしょう。NSTableViewは、NSScrollViewの中にありますから、指定する際には「table view ○○ of scroll view ××」というように指定しなければいけません。またドロワー内の部品の場合、NSDrawerの「content view」というものの中に配置されていると考えられます。content viewというのはその部品に設定されている表示用部品(NSView)を示すものです。

 また、NSDrawerは、Interface Builderでは「ウィンドウとは別の独立したもの」として作成しましたが、スクリプト的には表示するウィンドウ(Parent window)の中に組み込まれているものとして指定されます。従って、ドロワー内にある部品は、「《部品》 of content view of drawer ○○ of window ××」というような書き方をしないといけないのです。

 こうしたややこしい指定の仕方のため、ドロワー内に組み込まれたNSTableViewのdata sourceを指定する場合には、「data source of table view ○○ of scroll view ○○ of content view of drawer ○○ of window ○○」という、落語の寿限無のような長ったらしい書き方をしなければいけません。

 そしてデータの作成ですが、ASKDataSourceというのは、「まず、必要な列の数だけdata columnオブジェクトが用意されており、そこに更に必要な行だけdata rowオブジェクトを作成する」という仕組みになっています。要するに、「列データ=data column」「行データ=data row」をそれぞれ必要な数だけ作らないといけないのです。

 そこで今回の例では、起動時に列データをあらかじめ作っておき、コマンドのヘルプ呼び出しを行なったら、その際に行データを作って追加する、というようにしました。まず列データですが、これは以下のようにして作成します。

make new data column at the end of the data columns of 《data source》[with properties { 属性 } ]

 これは、「こう書くのだ」と覚えてしまって下さい。ここでは、tell data sourceというようにしてdata sourceにtellするようにしてあります。こうすることで、makeの書き方を簡略化しているわけですね。またwith propertiesでname属性を「listcolumn」としてあります。data columnは、nameと同じIdentifierのNSTableColumnにデータが表示されるようになっているのです。このため、作成の際には表示するNSTableColumnと同じnameを設定しておく必要があります。

 では、data rowの作成はどうやっているのでしょうか。これは、NSTextFieldでリターンキーを押した時に呼び出されるdoManハンドラ内で行なっている、次のような部分を見ればわかります。

tell data source of table view "listtable" of scroll view "listscroll" of 〜
content view of drawer "drawer1" of window "win1"
make new data row at the end of the data rows
set n to data rows count
set contents of data cell "listcolumn" of data row n to str1
end tell

 見ればわかるように、「make new data row at the end of the data rows」というものでdata rowを作成していることがわかります。「data column」が「data row」になっただけで、基本的な書き方は同じですね。

 data rowを作成したら、「data rows count」というものでdata rowの数を調べています。そして「contents of data cell "listcolumn" of data row n」という形で、作成した最後の行の1列目のセルの値を設定しています。セルの値というのは、この例でわかる通り、以下のようにして指定します。
contents of data cell 名前/番号 of data row 名前/番号 of 《data source》
 要するに「データソースのdata rowの中のdata cell」という形でデータは組み込まれているわけです。このように指定することで、特定のセルの値を取り出したり変更したりできるというわけです。

 また、データを変更したら、最後にNSTableViewに向けて「update」という命令を送ることを忘れないようにしましょう。これで表示が更新されます。実は自動的に表示を更新することもできるのですが、とりあえず「updateすると更新される」ということは忘れないでおきましょう。

 NSTableViewは、データを使いこなそうとするといろいろと難しいのですが、とりあえず「data sourceにdata columnとdata rowを組み込んで操作する」という基本さえわかれば、一応簡単な操作ぐらいはできるようになります。これは複雑なコントロールなので、焦らず基本からじっくりとマスターしていきましょう。


GO NEXT


GO HOME