GO BACK

NewtonScript教室 その5

「組み込まれているパッケージを探る」



■タップ時にキーボードを呼び出す

 Newtonにはさまざまなプログラムが既に組み込まれています。これらのものと連係して自分のプログラムが動かせるようになると、いろいろと面白そうなことができるようになってきますね。

 例えば、Newtonのソフトの中には、ペンでタップして文字を入力しようとすると、自動的にキーボードが現れるものがあります。あの機能を自分のプログラムにも組み込めたら便利じゃないですか。それでは、前回作成した超簡易計算機で、InputDataの部分をペンでタップしたら数字のキーボードがパッと現れるようにしてみましょう。

 では前回のプロジェクトを開いて、InputDataのブラウザを開いて下さい。ブラウザをよく見ると、中央附近に「Specific」「Methods」「Attributes」という3つのポップアップメニューがありますね。これは、選択したビューで使えるさまざまなアトリビュートやメソッド(buttonClickScriptのようにプログラムを割り付けられるものと考えて下さい)がまとめてあるのです。

 ビューには非常に多くのこうした属性が用意されているのですが、最初からそれらが全てずらーっと組み込まれていると、必要なものを探すだけでも大変だしとてもわずらわしいものです。そこで、最初は必要最小限のものだけが右上部分に表示されるようにしておき、あとは必要に応じてこれらのポップアップメニューから使いたいものを選ぶと、それが組み込まれて右上部分に表示されるようになっているのです。

 では、「Method」ポップアップメニューから、「viewClickScript」というのを選んで下さい。これは、ビューをタップした時に呼び出されるメソッドです。buttonClickScriptと違い、テキストの入力用のビューなどで、タップしてそこにカーソルを移動させる時などに呼び出されます。メニューを選ぶと、このメソッドがブラウザの右上部分に組み込まれます。

 では、このviewClickScriptに以下のようにプログラムを書いて下さい。

func(unit)
begin
	// Return true if click has been completely handled, nil otherwise
	GetRoot().numerickeyboard:open();
	return nil;
end

 beginの次に「// Return true …」というものが書いてありますが、これはコメント文です。NewtonScriptでは、このように命令の冒頭に//をつけておくと、その行は無視されます。ですから、プログラムの注釈などをこのコメント文で書いておいたりするわけです。これはあってもなくてもプログラムには全く関係ありませんから、「うるさいな」と思うようでしたら削除してかまいません。

 その次には、こんな命令がありますね。


GetRoot().numerickeyboard:open();


 これが、数字のキーボードを呼び出している部分です。これは少々説明が必要でしょう。−−普通、命令というのは「《オブジェクト》:《メソッド》」という形で呼び出すようになっていました。これは、よく見るとなんだか形が変ですね。3つの要素があります。これはどうなっているんでしょう。

 実は、これは以下のようになっているのです。


《GetRoot().numerickeyboard》:《open()》


 ここで実行している「open()」というメソッドは、プログラムを起動する働きをするものです。「《プログラム》:open()」とすることで、そのプログラムを開くことができるのです。なかなか便利ですね。

 さて問題は前半の部分です。これは、更に2つの部分からなっていますね。


《GetRoot()》.《numerickeyboard》


 わかりますか? つまりGetRoot()というもののnumerickeyboardアトリビュートをオブジェクトとして指定し、そのopen()メソッドを呼び出していた、というわけですね。ですから、もうちょっとわかりやすく書くなら、こういうことをしていたわけです。


local keyObj := GetRoot().numerickeyboard;
keyObj:open();


 これならきっとわかることでしょう。2つの命令で書くところを、書き方を工夫して1行ですませていたわけです。

 最後に「return nil;」というのがありますが、これはviewClickScript特有の命令だと思って下さい。returnというのは、何かの値を返す命令です。viewClickScriptは、プログラムの最後に必ずtrueかnilのいずれかを返さないといけない仕様になっています。trueを返すと、そこでタップした処理は止まってしまい、ビューにカーソルが表示されません。nilにしておくと、普通にタップしたのと同様に、プログラムを実行した後でカーソルが表示されます。



■システムのルートとスロットについて

 ところで、このGetRoot()というのは一体なんでしょう? 関数のようですが、なぜ関数がオブジェクトなのでしょうね?

 このGetRoot()は、実をいえばNewtonのシステムが管理している「ルート」というところを示す関数なのです。−−Windowsユーザーであれば、ハードディスクを開いてすぐの階層を「ルートディレクトリ」と呼ぶことを御存じだと思います。ハードディスクの一番元になる階層、という意味でこう呼ぶのでしょう。

 Newtonのルートも、それと似たようなものです。−−Newtonにはさまざまなプログラムが組み込まれていますが、それらはインストールされると、この「ルート」と呼ばれるところから「見える」ように設定されます。Newtonはソフトを起動する時など、このルートから指定のプログラムを見つけて起動しているのです。

 ここでは「numerickeyboard」というものを指定しています。これは数字キーボードのプログラムの正式な名称です。つまり「GetRoot().numerickeyboard」とすることで、ルートのnumerickeyboardを指定していたのです。

 Newtonでは、あるオブジェクトから「見える」オブジェクトを指定する場合も、アトリビュートと同じように「《オブジェクト》.《オブジェクト》」という感じで指定することができます。まるで、オブジェクトもアトリビュートも同じ感覚で使えるのです。これには秘密があります。

 Newtonでは、そのオブジェクトからアクセスできるさまざまなオブジェクトや値などを「スロット」というもので接続しています。アトリビュートもオブジェクトも、元のオブジェクトから見れば単にスロットを指定しているに過ぎないのです。−−え、よくわからないって?

 例えば、InputDataにはtextというアトリビュートがありましたね。あれは、「InputDataというオブジェクトにtextというスロットが組み込まれている」のです。同様に、numerickeyboardはルートに「numerickeyboard」というスロットを組み込んであるのです。

 更にいえば、作成しているプロジェクトにはAppというベースのビューの上にInputDataやOutputData、ClickMeというビューが組み込まれていましたが、これらもAppにそれぞれのスロットを組み込んでいたというわけなのです。

 要するに、Newtonでは、全ての要素は、そのオブジェクトに組み込まれているスロットとして認識されているのです。アトリビュートも、その上に配置されたビューも、全て同じ「スロット」なのです。従って、プログラム内からはアトリビュートだろうとオブジェクトだろうとみんな同じようにアクセスができる、ということなのです。

 まあ、このスロットという概念は非常に抽象的なものですから、よくわからなくても今は問題はありません。いろいろとプログラムを作っていくと、次第に「全てはスロットで繋がっている」ということが、感覚的にわかってくるようになりますから心配はいりませんよ。

 さて、説明が長くなってしまいましたが、できあがったプログラムをコンパイルしてNewtonで動かしてみましょう。InputData部分をタップすると、数字キーボードが自動的に表示され、すぐに数字の入力ができるようになります。



■さまざまなものを開いてみる

 さて、Newtonに入っているプログラムの起動方法がわかったところで、数字キーボード以外のプログラムも開いてみることにしましょう。とりあえず、主だったプログラムの起動方法をざっとまとめて紹介しましょう。


●タイプライターのキーボードを開く
英語のキーボードのデフォルトに設定されているのがこれですね。キーボードアイコンをクリックすると最初に現れるものです。これは「alphakeyboard」という名前のプログラムです。ですから起動する場合は以下のようにします。

 GetRoot().alphakeyboard:open()


●電話用のキーボードを開く
電話をかけるときの専用キーボードは「phonekeyboard」といいます。これを起動するのは以下のようになりますね。

 GetRoot().phonekeyboard:open()


●日本語のローマ字インラインキーボードを開く
日本語を入力する時、もっとも多用するのはローマ字インラインキーボードではないでしょうか。これは「|romajiIn:ENFOUR|」という名前で指定します。一番最初にちょっと触れましたが、純正以外のプログラムは、プログラムの名前と一緒にシグネーチャというものを指定するようになっていました。Newtonの内部では、こうしたサードパーティが開発したプログラムは、 |《プログラム名》:《シグネーチャ》| という形で示されます。両脇を|記号でくくるのを忘れないで下さい。これを忘れると、Newtonは、《プログラム名》オブジェクトの《シグネーチャ》メソッドを実行しようとしているのだと勘違いしてしまいエラーを起こしてしまうのです。従って、インラインキーボードを起動する時は、こんな感じの命令になります。

 GetRoot().|romajiIn:ENFOUR|:open()


●日本語のHWCR手書き認識キーボードを開く
これは筆者の個人的な趣味です(笑)。エヌフォーからは、日本語の手書き認識入力を可能にする「HWCR」というソフトが市販されており、この手書き認識キーボードがなかなか快適なので、筆者は愛用しているのです。この手書き認識用のキーボードは、 |HWCR:ENFOUR| という名前になります。

 GetRoot().|HWCR:ENFOUR|:open()


●組み込みの計算機を開く
Newtonに最初から組み込まれている計算機は「calculator」という名前です。これもぱっと呼び出せると便利ですね。

 GetRoot().calculator:open()


●アラーム時計を開く
Newtonには世界時計と、時計の針がアナログっぽく表示されるアラーム時計があります。このアラーム時計は「alarm」という名前になります。

 GetRoot().alarm:open()


●Extrasを開く
「Extras」アイコンをタップすると現れる、さまざまなプログラムが整理してあるドロワーも、実はプログラムなのです。「extrasDrawer」といいます。これも、open()で開くことができるのですよ。

 GetRoot().extrasDrawer:open()


●スケジューラを開く
「Dates」アイコンをタップすると現れるスケジューラも、やっぱりプログラムですから開くことができます。これは「calendar」という名前になります。

 GetRoot().calendar:open()


●住所録を開く
「Names」アイコンをタップして表示される住所録カードは「cardFile」という名前になります。

 GetRoot().cardFile:open()


 主だったプログラムをざっと紹介しました。これらが自由に呼び出せるようになると、かなりプログラムも面白くなってきますね。作成中のプロジェクトを修正して、これらのプログラムが起動するようなサンプルを作ってみてると、使い方もすぐに飲み込めますよ。



■インスペクターを使う

 では、ここに紹介したもの以外のプログラムを起動したい時はどうすればいいんだろう? Newtonに組み込んだプログラムの正式な名前はどうやって調べればいいんだろうか?−−そう疑問に思う人も多いことでしょう。

 このような場合は、Newtonの内部を自分で調べる必要があります。なーんていうと、なんかめちゃめちゃすごいことをするように思うかも知れませんが、そういうわけじゃありません。NTKには、ちゃんとそういう機能が用意されており、これを使うだけでNewtonの内側を探ることができるんです。それは「インスペクター」というものです。

 インスペクターというのは、Newtonにさまざまな命令を送り、その結果を出力するツールです。つまり、NewtonにNewtonScriptの命令を直接送りつけることで、その内部を調べることができるというわけです。

 このインスペクターを使うためには、ちょっと手順がいります。以下のようにしてください。


1.まずNewtonとマシンを接続します。
2.NewtonでToolkitを起動します。そして「Connect Inspector」ボタンをクリックします。
3.NTKで、「Window」メニューから「Connect Inspector」を選びます。
4.暫く待っていると接続が開始され、インスペクターのウィンドウが現れます。


 これでちゃんとNewtonとNTKのインスペクターがつながりました。インスペクターで命令を実行すれば、ちゃんとその結果が返ってくるはずです。−−手始めに、「GetRoot():SysBeep()」と入力し、enterキーを押してみて下さい。リターンキーではなく、enterキーです。これを押すと、選択行の命令がNewtonに送られ、実行されるのです。

 この「SysBeep()」というのは、ビープ音を鳴らす命令です。これを実行すると、ニュートン側で音が鳴るでしょう?−−そしてその後で、インスペクターになんだかよくわからないテキストが書き出されます。「#1A TRUE」といったものが表示されるはずです。これは、まあ「ちゃんと命令は実行できたよ」という意味だと思って下さい。

 では、今度は「GetRoot()」と実行してみましょう。−−どうです? 何かがずらずらと表示されてきたでしょう?

 なんだか非常に難しそうな感じがしますが、これは、そこに組み込まれている「スロット」を延々と書き出していたのです。書き出されたものをよーく見てみると、例えばこんな部分が発見できるでしょう。

           downButton: {_parent: {#4406479}, 
                        _proto: {#57A921}, 
                        viewCObject: 0x110FC33, 
                        viewJustify: 1536, 
                        viewBounds: {#3C7F71}, 
                        viewFlags: 515}, 

 これは、ルート上にある「downButton」というものと、それに用意されているスロットの一覧なのです。よく見ると、なんだか見覚えあるものがあるでしょう?「viewBounds」は確か今まで作ったビューにもありました。ビューの領域を示すアトリビュートでしたね。設定されている値は、Newtonが理解できるようにしてあるものなのでほとんど暗号ですが、しかしスロットの名前だけはこうしてちゃんと表示されるのです。

 このように、インスペクターからオブジェクト名を実行すると、そのオブジェクトに用意されている全スロットがずらりと表示されます。そこで、ルート上からスロットを探していけば、どこかにスロットの名前としてプログラムが組み込まれているのを発見できるはずです。

 ただし、注意しておかないといけない点がひとつ。インスペクターでは、スロットの数が16以上になると、「...」というように「以下略」となってしまうのです。これでは表示し切れない場合があります。

 この「一度に表示するスロットの数」は、「printLength」という変数で決まります。ですから、この変数の値を変えれば、表示されるスロットの数は変わるのです。例えば、以下のように実行してみて下さい。


printLength:=128


 こうすると、スロットは最大128項目まで律儀に書き出されるようになります。これでGetRoot()を実行すれば、まずたいていのものは書き出されることでしょう。−−ただし、数をあまり多くすると、反応が返ってくるまで相当の時間待たされることになりますので、適当に数は調整して下さい。

 これで、Newtonの内部にあるプログラムを調べる方法もちょっとだけわかりました。インスペクターは他にもさまざまな使い方ができます。ある程度慣れてきたら、インスペクターでどんなことができるか勉強してみるのもいいでしょう。


GO NEXT


GO HOME