RealBasic University

このコラムはStone Table Softwareのオーナーであり、またREALbasic Developerの編集者でもあるMarc Zeedar氏により書かれたものを、著者の許可を得て翻訳したものです。この翻訳はHREM Researchにより提供されています。この日本語版へのご意見はRBU-Jまでご連絡下さい。

URL: http://www.applelinks.com/rbu/021/
INDEXに戻る

REALbasic の基礎

私は今までのコラムの中でREALbasicのインターフェースについてほんの少し説明をしましたが、すぐに初めてのプロジェクト、GenderChangerにのめり込みました。私は初心者のユーザーを無視するつもりではなく、ただ全ての基礎的なことをカバーしたかったのです。次の幾つかのレッスンでは、私はREALbasicに組み込まれている様々なインターフェイスの使い方を示しながら、RBの最も基礎的な側面の幾つかを重点的に取り扱いたいと思います。

REALbasic Version 3.2

REALbasicは定期的に改良されているプログラムです:REAL Software社は数日毎のように頻繁にベータとアルファバージョンをリリースしています。それは最前線で活躍している専業の開発者にとっては素晴らしいことです。しかし、それ以外の我々のような者は正規のリリースを利用したほうがいいでしょう。(リリース前の機能は完成したものではなく、最終版では変更されたり、あるいはサポートされないこともあります。)

このコラムや今後のコラムの中で、これを書いているときの最近リリースであるREALbasic 3.2を使用するでしょう。今までは、私は古いバージョンを使用していました。その違いの多くはIDE(統合開発環境)の概観が変わったというようなほとんどうわべだけのものですが、幾つかの新しいコマンドや機能が追加されています(スプライトの解説の中で説明したようなスプライト関係の変化など)。最新のリリースを使用することの問題の一つはREALbasicの古いバージョンではRB 3.2のプロジェクトファイルを開くことのができないということです -- これは、あなたは少なくとも今からはREALbasic Universityのプロジェクトを開くためには3.2を必要とするということです。

(これはまたアップグレードを行なうときは注意が必要であるということを意味します:一度、古いプロジェクトを新しいREALbasicのバージョンに変換した場合には、それを元に戻すことは困難です。RB 3.2にはコマンド"Save as RB 2.1"があります。しかし、もしあなたが新しいバージョンのどれかの機能を使うならば、そのプロジェクトは古いバージョンではコンパイルされないでしょう。)

基本的なインターフェース要素

REALbasicは我々がRBUプロジェクトの中で今まで使用する機会のなかった多くのインターフェイスオブジェクトを含んでいます。例えば、我々はリストボックス や文字入力欄を使用しましたが、タブパネル(tab panel)や スライダ(slider)、 プログレスバー(progress bar)を使用しませんでした。これから、それらの要素の幾つかを概観し、そしてそれらをどのように使うのかを学びましょう。

私はあなたがダウンロードして、このシリーズで説明するデモの全てを試すのに使うことのできるREALbasicプロジェクト、 RBU Demo、を用意しました。このプロジェクトはIDEで次のように見えるでしょう:

見てお解りのように、ここには沢山のコントロールが含まれています。しかし、このプロジェクトは色んなRBのインターフェイス要素をどのように使うかを示すこと以外には何もしていません。

我々のインターフェイスのツアーをガイドするために、まずREALbasicのツールパレットのスクリーンショットを示します:

初めの六つはとても簡単で、多くの説明を必要としないでしょう:直線、円、四角そしてラベルです。それらは表示のためのインターフェイス要素で、通常はユーザーが作用することはありません。(これはそれらが相互作用をできないと言っているのではありません:例えば、それらの要素を使って簡単な描画プログラムを書くことができます。しかし、あなたはREALbasicが描くことのできるオブジェクトに制約されます。あなたが思いのものを自由に描画できるキャンバスを使用する方がもっと合理的でしょう。)

次の3つ、プラカード placard、額縁 imagewellそしてキャンバス canvasの中では後者が最も重要です。私は正直なところ初めの2つが何のためなのかよく知りません:プラカードは押し込まれるか飛び出た状態をあらわす単なる立体的な四角形です、そして額縁は画像を単に表示できるだけです。どちらの機能もより柔軟性のあるキャンバスを使って代用することが可能です。

キャンバスができることの幾つかを示すために、我々は画像を表示しましょう(今後のコラムの中でキャンバスをより深く勉強するでしょう)。しかし、これを行なう間に、この機会に別の1対のスクロールバー scrollbarコントロールを同時に説明しましょう。

スクロールバーコントロールは大きすぎてディスプレイの領域に収まらない内容の一部を表示する時に使います。我々の例では、非常に小さなキャンバスにこの前のコラムの射撃場プロジェクトで使った島の日の出の大きな画像を表示します。これを行なうために、1つは垂直方向で、他方は水平方向の2つのスクロールバーを必要とします。私はそれらをvScrollBarhScrollBarと名前を付けました。

私はそれらをcanvasオブジェクトの下と右に置きました。プログラムが実行されると、それは以下のように見えるでしょう:

スクロールバーはかなり簡単なコントロールです。大きさと位置以外には、あなたが設定する必要がある重要な属性はminimummaximum、そして valueのたった3つだけです。それらはスクロールバーが制御する範囲を設定します。valueはスクロールボックス(thumb)の現在の位置です。もし、valueminimumと等しいときは、スクロールボックスは最も左(垂直なスクロールバーでは最も上)にあります。もし、valueがスクロールバーのmaximumと一致したときには、それは最も右(もしくは底)にあります。

画像をスクロールするには、スクロールボックスの水平と垂直の値 (value)を設定し、画像をキャンバスに描画します。ユーザーが画像をスクロールするたびに新しい座標を用いてそれを描き直します。単純です。

この処理には3つの部分があります。まず最初に、我々はスクロールバーを初期化する必要があります。いくつかのアプリケーションでは、プログラムが動いている間に画像の大きさが変化することもありますので(もし、ユーザーが新しい画像を開くことを許されるならば)、これはメソッドにすると最もうまくいくでしょう。我々のデモの場合には、我々はwindow1のOpenイベントでは初期化の処理をしているだけです:

Window1の Openイベントのためのコード

   // 画像のスクロールバーの大きさを画像の
// 大きさにあわせる
hScrollBar.maximum = islandsunset.width - hScrollBar.width
vScrollBar.maximum = islandsunset.height - vScrollBar.height

// 画像を中心にもってくる
hScrollBar.value = hScrollBar.maximum \ 2
vScrollBar.value = vScrollBar.maximum \ 2

我々のプロジェクトにはドラッグされてきたislandsunsetと呼ばれる画像があります:我々はそのサイズを取得して、それをスクロールバーの最大のスクロール量を設定するために使っています。

追記

画像のサイズからスクロールバーのサイズを引くことに注意して下さい:なぜ、そのようなことをするのでしょうか?

例えば、次のようにしてはいけないのでしょうか:

 
   hScrollBar.maximum = islandsunset.width 
vScrollBar.maximum = islandsunset.height

これでいいように思いませんか? しかし、もし我々がこのようにすると、おかしなことが起るでしょう。このコードではユーザに次のようなことを許します:

ユーザーが画像の最後を越えてスクロールして白い部分を表示するのが判りましたか? それは奇妙で見栄えがよくありません。

maximumは我々が画像をスクロールできる最大のピクセルを現しているということを覚えておきましょう。もし、我々が画像の全幅(例えば1000ピクセル)に設定し、そしてユーザーが全域をスクロールするならば、その画像は1000ピクセル移動するでしょう。しかし、画像は左上の端から描かれます -- それは我々がキャンバスの左の1000ピクセルから画像を描くことを意味します:キャンバスには何にも表示されないでしょう!

これは重要であり、そして、しばしば混乱する点です。おそらく、次の図はそれをより明確に説明するでしょう。

見て判るように、我々のスクロール領域は画像の大きさではなく、画像の大きさからキャンバスの大きさを引いた範囲です。これによりユーザーは画像を越えないで、画像全体をスクロールすることができます。

我々はスクロールバーを初期化した後、スクロールバー自身に少しのコードを付け足さなければなりません。ここで我々がしたいこのと全ては、スクロールバーが動いたときに、画像を再描画することを知らせることです。スクロールバーコントロールはvalueChangedイベントを持っています。ですから我々がしなければならないことはそのサブルーチンに次のコードを書くことです:

 canvas1.refresh 

(2つのスクロールバーのそれぞれに対してこれをしなければならないということを覚えておきましょう。)

このcanvas1.refreshは何をするのでしょうか? 簡単です:refreshコマンドはキャンバスにそれ自身を再描画するように命令します。それだけです!

追記

あなたはダイアログボックスが出てきて、あなたが使っていた領域を覆うってしまった経験がありますか? ダイアログボックスが消えたときに、ダイアログの後ろのものが再描画されることに気が付いたでしょうか? Macのプログラミングでは以前からリフレッシュイベントを使っています。リフレッシュとはウィンドウの全てまたは一部が再描画される必要があるということのプログラミング的な言い方です。

REALbasicは通常あなたのプログラムの内容の再描画を自動的に処理します。(RBに組み込まれた全てのコントロールは必要な時に自動的にリフレッシュします。あなたは普通はそのことについて心配する必要はありません。)

上の場合、あなたは単にcanvas1にそれがリフレッシュされる必要があることを知らせているのです。

しかし、canvas1はそれ自身を再描画する時に何をするのでしょうか? では、Paintイベントの中のコードを見てみましょう。

 g.drawPicture islandsunset, -hScrollBar.value, -vScrollBar.value 

信じられないほどに簡単ですね?しかし、それらの数行のコードで我々は画像をフレームの中でスクロールすることができるのです。

上のコードはどのように働くのでしょうか?そうですね、gはcanvas1の グラフィックオブジェスト、すなわち何かが描かれる場所です。グラフィックオブジェクトは線や長方形や円などを描くためのルーチンのような数多くのコマンドを持っています。それらのうちの1つはdrawPictureメソッドです。

drawPictureメソッドは強力(そして複雑)ですが、ここでは最も単純な使い方をしています。(例えば、あなたは描いている画像の大きさを変えるためにdrawPictureに対して追加のパラメータを使うこともできます。)我々の場合には、3つのパラメーターがあります:画像オブジェクトと画像を描く水平と垂直の座標です。

我々の絵はプロジェクトにドラッグされたいる画像islandsunsetです。描画座標としては、我々はスクロール位置の負数を使っています。座標(0, 0)canvas1の左上のコーナーを表わしているということを覚えておきましょう。ですから、負の値は画像をさらに左あるいは上に描いて、画像のより右側と下側を表示します。スクロールすればするほど、スクロール値は大きくなります。ですから、描画はより左(もしくは上)からはじめられ、画像もより右(または下)が表示されます。単純です!

詳細表示三角形(Disclosure Triangle)

これで、我々はキャンバスの例を終了しましたので、次に移りましょう。我々は今までのコラムで文字入力欄を説明していますので、ここでそれを議論しません。その代わり、ツールパレットの2つの三角形のオブジェクト調べましょう。それらは何なのでしょうか?

最初のものは黒い三角形て、popupArrowとして知られています。それは極めて簡単なコントロールです:あなたが設定することのできるものはそれ自身の位置と三角形が示している方位です。それは何に使えるのでしょうか? そうですね、あなたはそれを幾つかの目的のために使うことができます。例えば、浮かんでいるパレット(floating palette)があるときに、その三角形は以下のようにポップアップメニューを示すことができます:

(これはZ-Writeからのものですが、このようなメニューはAdobe Photoshopのような多くのプログラムの中も見つけられます。)

もっとよく使われるコントロールは詳細表示三角形disclosure triangleです。多くののプログラムが高度なオプションを表示したり、隠したりするためにこれを使っています。高度なオプションを隠すことにより混乱をより少なくすることができます。

Appleのリモートアクセスコントロールパネルは簡易と詳細モードの間を切り替えるのにこの詳細表示三角形コントロールを使っています。

しかし、プログラムはどのようにしてインターフェイスの一部を隠したり、現したりするのでしょう?もし、あなたがプログラミングに慣れていなければ、その答えは明白ではありませんが、しかしそれは驚くほどに簡単です。

我々のデモプロジェクトでは、"music"の一部を隠したり、現したりする詳細表示三角形があります。

インターフェイスの一部が表示または隠されているRBU Demo

詳細表示三角形はどのように動作するのでしょうか?そうですね、実際にはそれ自身の中には何もありません。しかし、我々は三角形が上を向いているのか、下を向いているのかを知ることができますので、それに応じてインターフェイスの状態を変えることができます。ウィンドウの底の一部を隠すためには、我々のすることはウィンドウの高さを短くするだけです!コントロールはまだそこにありますが、それらはウィンドウの底にあるので、見えなくなったのです!

disclosureTriangle1の Actionイベントのコード

   if window1.height = 300 then 
window1.height = 255
musicLabel.text = "Show Music Player"
else
window1.height = 300
musicLabel.text = "Hide Music Player"
end if

ここでは現在のウィンドウの高さを調べて、それを切り替えているだけです。そして、我々はstaticTextの名前を"show"もしくは"hide"に適切に変更します。簡単ですが、それはうまく機能します!

今週はこれで充分でしょう。来週、我々はBevelButtons、 ContextualMenus、QuickTime のmovieplayer、そしてその他のホットなコントロールについて勉強します。

次週

REALbasic の基礎 II

RBU裏技

もし、あなたがリストボックスの中へ何千ものアイテムを読み込んでいるならば、それを満たすためにはかなりの時間がかかります。この処理を大きくスピードアップするためには、読み込んでいる間はリストボックスを不可視(invisible)にしましょう。

次のことを試してみましょう:新しいプロジェクトをつくり、リストボックス、チェックボックスそしてプッシュボタンをドラッグしてきます。プッシュボタンのActionイベントの中に次のものを置きます:

 dim i, tt as integer 

if checkBox1.value then
listBox1.visible = false
end if

tt = ticks
listBox1.deleteAllRows
for i = 1 to 3000
listBox1.addRow "Line " + format(i, "000#")
next

listBox1.visible = true
msgBox "That took " + str(ticks - tt) + " ticks!"

では、プログラムを走らせて、チェックボックスがチェックされた状態とチェックされていない状態でプッシュボタンをクリックしましょう。時間の違いがわかりますか?(1tickは一分の60分の1であることを憶えておきましょう。)チェックボックスがチェックされた状態では、リストボックスはそれが設定される間は不可視にされます。そうで無い場合は、リストボックスは目に見えた状態で、かなり 遅くなるでしょう。

可視(上)と不可視(下)の時のリストボックスを満たすための時間(tick数)

Letters

今週の我々の手紙はRBUのスプライトの例の 射撃場ゲームの中で表示される時計カーソルが嫌いなBenさんから届きました。

私はspriteworldが動作している時には、カーソルはwaitwatchであることに気が付きました。それは多少エレガントでは無いよううに見えます。スプライトがマウスによってコントロールされているゲームのように、カーソルを消し去る方法はありますか?それでは。

そうですね、Ben さん、REALbasicはカーソルを直接的に隠すための方法を持っていません。(普通、それはRBによってに自動的に処理されます。)しかし、あなたは以下のことを試みることができます:ResEditで空白のカーソルをつくり、そしてあなたのプロジェクトにそれをドラッグしてきます。あなたがこれを簡単に行えるように、私はblankCursorと呼ばれているものを作りました。あなたはそれをここからダウンロードすることができます。

あなたがカーソルを隠したいところに(spriteSurfaceオブジェクトの中などに)、me.mouseCursor = blankcursorという行を書きましょう。これはうまくいくはずです!(終わったあとで、カーソルをarrowCursorへ戻す事を忘れてはいけません。)

(ついでに、うまくいくと思われる他の方法はDisableAutoWaitCursor というpragma directiveを使って待機中カーソル(wait cursor)を不能(disable)にすることです。さらに詳しくはRBのオンラインヘルプを参照して下さい。)


RBU-Jの通知サービス!コラムが発表されるたびに日本語版REALbasic Universityのお知らせの emailがあなたに届きます。登録・削除は ここ から。

INDEXに戻る