RealBasic University

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

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

REALbasicの基礎 III

先週はスライダ(Slider)とべーベルボタン(BevelButton)コントロールを使用しました。今週はタブパネル(TabPanel)、グループボックス(GroupBox)、コンテキストメニュー(Contextual Menu)について勉強し、QuickTimeムービーをREALbasicプロジェクトに加える方法を学びます。

タブパネルコントロール

多くのオプションをユーザーに示す必要のあるとき(例えば、あなたのプログラムにおいての多数の初期設定が必要な場合)、あなたは関連したアイテムをグループ化し、それぞれのグループの初期設定に対して別のダイアログボックスをつくることも可能でしょう。しかし、それではユーザが変更したい項目を複数のダイアログボックスから探し出す必要があるので、ユーザーを混乱させることになるでしょう。

より良いシステムはタブパネルTabPanelコントロールを使うものです:これは、ユーザーが同一のダイアログ内の複数の項目間を飛び回るのを可能にします。良い例としてアップルのアピアランスコントロールパネルが挙げられます。

上にある対応するタブを選択することによってそのカテゴリーに関連した項目のみが表示されます。

我々のサンプルプロジェクトのRBU Demoには、それぞれのパネルに種々の項目のある3つのパネルからなるタブパネルが既に作成されています。

REALbasicのIDEではタブパネルを使うのはよく混乱します。通常はプログラムが実行されている状態と同じように動きます:タブをクリックするとそのタブの内容に切り替わります。しかし、もしあなたが他のタブのコントロールを既に選択していると、それは不可視の選択された項目として「透過して」見えます。

上の例では、最初のタブのテキスト要素が選択された状態になっています。これは現在のタブに含まれていないので、これには混乱します。私はタブを切り替える前にいつも全てのオブジェクトの選択を解除することを勧めています。これによって、あなたは間違ったアイテムを修正せずにすみます。(もし、上の例のテキスト要素がすこし下にあれば、このタブにあるテキスト要素が選択されていると思ったでしょう。)

タブパネルの別の問題点はそれが完全には信頼できないということです。あるコントロールがしみ出して、他のコントロールに影響するというバグがあります。例えば、我々の例題には3番目のタブにQuickTimeの映像が配置されています。そして、あなたが映像を再生し、他のタブへ変更した場合、その映像は間違ったタブ上で続けられます。

一般的には、タブパネルは単純なインターフェースに使用して、複雑なものには使用しない方がいいでしょう。我々の例題では表示されるタブをプログラムで設定する方法を示しています。TabPanel1のOpenイベントには次ぎの行が書かれています:

 me.value = 2 

これは単純にタブパネルを3番目のパネルに設定します(パネルが0から数えられることを忘れないようにしましょう)。

小さな矢印コントロール

我々の例題の最初のタブでは単純なテキスト要素チェックボックスがあるだけです。しかし、二つ目のタブには小さな矢印LittleArrowsと呼ばれるちょっと変わった小さなコントロールの使い方を示しています。

小さな矢印はMacOSにおいてタイプするよりも簡単に数を増減させるような多くのところで使用されています。例えば、次のような日付&時間のパネルです:

我々の例題は数値が大きいこととテキスト要素を除いて同じようなことをしようとしているのです。ユーザが下向きの矢印をクリックした時に、我々は数字を減らします。上向きの矢印をクリックすれば、数字を増やします。(もっと面白くする為に、オプションキーが押されている状態でクリックされた場合には、10単位で数を増減します。)

次はDownイベントのコードです:

   dim n as integer 

n = val(staticText1.text)
if keyboard.optionKey then
n = n - 10
else
n = n - 1
end if
staticText1.text = format(n, "-00#")
staticText1.refresh

まず、これはstaticText1の中身を数字に変換します。そして、オプションキーが押されているかどうか確認します。もし、そうであるならば、数値から10を引きます。そうでなければ1を引きます。

最後のステップではstaticText1に新しい数値を設定します。数字の前にゼロ表示したいので、strではなくformat関数を使用します(これにより数値は常に同じ文字数を持つことになります)。

私たちはまたその更新を表示させるためにstaticText1refreshします。なぜ、そうするのでしょうか? もし、我々が強制的に更新しなければ、ユーザがマウスボタンを離すまで新しい数値は表示されません。それを試した時には、マウスボタンを押しているわずかな間に、その数値は数千も増えてしまいました。このようにすればそれぞれの増加、減少のあとでテキスト要素が再描画され、ユーザに現在の値が示されます。

Upイベントのコードは、「引く」代わりに「足す」ということを除けばまったく同じです。

QuickTime ムービー

タブパネルの三つめのタブには小さなQuickTime ムービーを設置しています。私は小さな映像を作ってそれをRBU Demoに含めてあります。それをあなたのRBプロジェクトにドラッグして追加して下さい。私は属性ウィンドウでムービーコントローラがその映像"simple.mov"を自動的に再生できるように設定しました。

しかし、組込まれたムービーは常に充分とは限りません。ユーザがムービーをドラッグしてきて見られれば素晴らしいではないでしょうか? MP3の音楽ファイルはどうでしょうか? もちろんやりましょう。

最初に、二つの種類のファイルを定義します。これで、私たちのプログラムはファイルをどうやって利用するかを知ることが出来ます。Editメニューに行き、"File Types..."を選択して下さい。出てきたダイアログの"Add..."をクリックしましょう。

最初のフィールドの右にはポップアップメニューがあります。あなたは、既に定義された次のようなQuickTime ムービーのファイルタイプが選べるはずです。

これを選択すれば自動的に欄が埋まります。OKを選択して、もうひとつのMP3のファイルタイプも作りましょう。

もし、あなたが、以前のレッスンでやったことを忘れた場合には、我々が今行っていることはMacのファイルタイプに名前を付けているのだと言うことを思い出して下さい。このようにすることによりREALbasicはどのようなファイルを扱わなければならないかを知るのです。次のステップはムービーコントローラにドロップされたこの種のファイルを受け付けるよう指示します。

moviePlayer1Openイベントに移動し、次のコードを記入して下さい:

 
   me.acceptFileDrop("audio/mp3") 
me.acceptFileDrop("video/quicktime")

次にそのDropObjectイベントに移り、次のコードを記入して下さい:

   if obj.folderItemAvailable then 
me.movie = obj.folderItem.openAsMovie
me.play
me.refresh
end if

ここでは、まずコントロールにファイルがドロップされたかを調べています。もしドロップされたならば、それをムービーファイルとして開こうとし、そして再生しようとします。refresh命令はコントローラのサイズが変更された場合に、その変更を確実にするために重要です。

これによりユーザはQuickTime ムービーやMP3ファイルをコントロールにドロップして再生することが可能になります。これは洗練された手法ではありません、しかし、充分に動作します。これをもとにあなた自信のMP3プレーヤーを作ることはそれほど困難では無いでしょう。

コンテキストメニュー

近代的なコンピュータの他の素晴らしいインターフェイスはコンテキストメニューContextualMenuです。これはユーザがコントロールキーを押した状態でマウスをクリックすると現れる隠されたメニューです。それは名前どおりで、実際に文脈に依存しています:すなわち、ユーザのその時の状況に応じて内容が変化します。

REALbasicは多くの良いコンテキストメニューを実装しています、そして、それらは使いやすいものです。基本的な手順はContextualMenuアイコンをウィンドウへドラッグして、mouseDownイベントにメニューを動的に生成するコードを記述し、そしてメニューのActionイベントに、メニューがすべきことを記述します。

我々はメニューで何をしたいということが特にはありませんので、単純にコントロールの動的な性質を説明するような例を示しましょう。そこで、私が考えたのはユーザがウィンドウのどの部分をクリックしたかによって内容を変更するというものです。例えば、"Scroll Test"の領域でコントロールキーを押してクリックした場合、コンテキストメニューは"Scroll Test item"としましょう。

この為には、ユーザが今どこにいるかを追跡する手段が必要になります。これは難しくは有りませんが、いくらかの手順を必要とします。第一に、cmenuという属性を新しくWindow1に作成します。これはコンテキストメニューの内容を保持する文字列変数です。

それでは、Window1を開いて、Editメニューの"New Property"を選びます。そして、開いたダイアログに"cmenu as string"と入力して、OKをクリックします。

ここで、cmenuの初期値を決定する必要があります。そこで、Window1のOpenイベントにあるコードに次のものを書き加えます:

   // Default contextualMenu1 menu item 
cmenu = "Window item"

次に、我々はユーザがマウスを移動さたときにcmenuを変えなければなりません。我々が関心を持っているのはグループボックスコントロールだけですので、これは簡単に行えます。グループボックスは4つで、それらはコントロール配列として作られています(これは全てが同じコードを共有していることを意味しています)。

GroupBox1のMouseEnterイベントに移動し、以下のコードを打ちこみます:

 cmenu = me.caption + " item" 

me関数は常に現在のコントロールですので、これはユーザがいるどれかのGroupBox1になります。よって、cmenuはグループボックスのcaptionに" item"という文字列を追加したものに設定されます。

次に、GroupBox1のMouseExitルーチンに以下の行を入力して下さい:

 cmenu = "Window item" 

これはデフォルトの値です:もしユーザが、グループボックスの外でクリックした場合、コンテキストメニューは単に"Window item"であると答えます。

我々はこのメニューをWindow1内のすべてのところで機能させたいので、Window1のMouseDownイベントに以下のコンテキストメニューのコードを書きます:

 
   if isCMMClick then 
// Build the menu
contextualMenu1.deleteAllRows
contextualMenu1.addRow cmenu
contextualMenu1.open
end if

これは最初にユーザがコントロールキーを押してマウスをクリックしたかを調べます:もしそうならば、我々はcmenuの内容を使用してコンテキストメニューを構築し、それからそれを開きます(表示します)。

これで終わりです。もし、いま、RBU Demoを実行すれば、コントロール+マウスクリックによってクリックした場所によって変化するコンテキストメニューが現れるでしょう。

追記

contextualMenu1内になにもコードを書かなかったことに気がつきましたか? これは、この例では、メニューでは表示する以外にはなにも行っていないからです。あなたのプログラムではユーザがメニューのどれかの項目を選んだ際、何かを実行させたいでしょう。

これをするためには、contextualMenu1のActionイベントにコードを追加します。例えば、次のようなselect caseを使うといいでしょう:

   select case item 
case "Window item"
msgBox "This is the default menu item."
case "Scroll Test item"
msgBox "You chose the Scroll Test menu!"
else
msgBox "You chose menu " + item + "."
end select

どうですか、簡単でしょう? もし、コンテキストメニューがメニューバーのコマンドと同じであれば、メニューハンドラのコードをメソッドにする必要があるでしょう。そうすれば、コンテキストメニューのActionイベントとメニューハンドラの両方からそのメソッドを呼び出すことが可能となります(そうでないと、コードを複製しなければならなくなり、それは修正を困難にします)。

今回はこれで十分でしょう。次週ではRBU Demoを終了し、その後は他のRBUの基礎、例えば、別の人が書いたクラスをあなたのプロジェクトに取り込む方法などに進みましょう。

次週

既存のクラスの使い方をふくめて、さらにREALbasicの基礎を勉強します。

RBU裏技

リストボックスのヘッダーが押されないようにするには以下の行をリストボックスのsortColumnイベントに書きましょう:

 me.headingIndex = -1 

Letters

今週の手紙はJimmy Isaacsonさんからです:

Marcさん:

まず最初に、私はREALBasicのコラムを楽しんでいるということを言わせてください。コラムのペースは私のてんてこまいのスケジュールにピッタリです。では、私の質問と提案です。

まず質問です:画像をスクロールするのはできたのですが、スクロールするときに画像を描画するあいだに気になるちらつきがあります。スクロールのそれぞれのステップで影響のある画像部分だけを再描画するように制限しようとして、drawPictureメソッドの呼出しを以下のように変更しました:

 g.drawPicture islandsunset, 0, 0, hScrollBar.maximum, vScrollBar.maximum, 
hScrollBar.value, vScrollBar.value, hScrollBar.maximum, vScrollBar.maximum

しかし、それでもまだスクロールする時にちらつきます。このちらつきをおさえるためのプログラムの変更あるいは追加にたいする提案はありませんか?

では、提案:印刷されたコラムの黄色の塗りつぶしあるいは赤の四角形の背景の部分を読んでいると、私は目が非常に疲れます、そして背景色が通常の白に変わった時に強い残像が残ります。それらの重要な部分を極端に明るい色で塗りつぶすのでは無く枠で囲むようにできないでしょうか?

REALBasic Universityであなたが行っていることに再度感謝します。

あなたが気の付いているスクロールのちらつきはREALbasicの欠点だと思います。私はそれを少なく出来ないかと少し試してみました、そして変化した領域をRBで再描画するようにしても何の改善も見られませんでした。私が気付いたのは、スクロールバーの矢印を使った時にのみ、このちらつきが起こるということです。スクロールバーのスクロールボックスをドラッグした時には、画像は全くちらつき無くスムーズにスクロールします。このことより、問題はスクロールのコードやRBの再描画速度ではなく、あなたがマウスで矢印ボタンを押している時に、RBがどれほど頻度に画像を更新するかということであると思います。

(もし、解決法をみつけた人は連絡して下さい!)

色付きのボックスに対する提案を有難うございます、Jimmyさん。どのようにできるか考えてみます。(私はCascading Style SheetでこのHTMLを作ろうとテストしています。そのときには、あなたの提案を取り入れたいと思います。)(訳註:日本語の翻訳版では最初からCSSを使っています。)

このような手紙をお寄せ下さい。私はあなたの質問に直ぐには答えないかも知れませんが、たぶん今後のコラムで取り扱うでしょう。(もし、あなたの手紙が公表されるのを望まない場合には、その旨を明記して下さい。そうでなければ、公表してもいいものとして取り扱います。)

もう一つの REALbasic コラム

読者の中でREALbasicに堪能していない人には、もう一つの REALbasic コラムがResexcellenceにあります。このコラムはErick Tejkowski (REALbasic for Dummiesの著者)によるものです。


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

INDEXに戻る