RealBasic University

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

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

OOP University:パート 24

レッスン099で、我々は進行状況表示ダイアログの開発という手応えのある問題について議論しました。それは簡単なようですが、とりわけユーザに動作をキャンセルさせることなど、多くの困難があります。プログレス・バーは普通は別のウィンドウですので、どのように停止する動作を伝えればよいでしょうか?

今回は、再利用可能なプログレス・バーのシステムを作成しましょう。

再利用可能なプログレス・バーのダイアログ

プログレス・バーはあらゆる種類のプログラムで目にするので、再利用できるように設計するのがよい方法です。そうすれば、コードは一度組めばすみます。REALbasicは外部項目を複数のプロジェクトにインポートすることができるので、この種のことは非常に簡単に行えます。

これはcommandとoptionキーを押しながら、項目をプロジェクト・ウィンドウにドラッグすることで行えます。これで外部項目とリンクしますが、コードは現在のプロジェクトの一部ではありません。それは外部に保存されるので、そのコードのバグを修正すれば、その外部コードにリンクしているすべてのプロジェクトは同時に更新されます!

基本ダイアログ・ボックスを作成することから始めましょう。新規プロジェクト内で、ウィンドウを追加(ファイルメニューの「新規ウィンドウ」)し、progressDialogと命名してください。それを幅300ピクセル、高さ180ピクセルにしてください。FrameプロパティはMovable Modalに設定します。次のようになります。

いま我々はこの進行状況表示ダイアログを可能な限り柔軟にしたいので(多くの異なるプログラムに使用できるように)、それを二重プログレス・バーのダイアログとして構築しましょう。しかし、お分かりのように、場合によっては一本のプログレス・バーとして使う方が簡単です。

では、progressDialogに2つのprogressBarオブジェクトと、4つのstaticTextオブジェクトを追加することから始めていきましょう。それを次のように配置します。

2番目のバーとテキスト・ラベルは左端からずれていることに注意してください。

progressBarは(上から下の順に)pBar1pBar2と命名して、staticTextsはmainLabelsubLabelstatusLabel、そしてcancelTextと命名しましょう。始めの2つのtextSizeは0、下の2つのtextSizeは10としてください。

それでは、progressDialogのコードエディタを開き(ウィンドウが選択された状態でOption-tabを押す)、新規メソッド(エディットメニューの「新規メソッド」)を追加してください。それにinitと命名し、パラメータの行には次のように入力してください。

  
title as string, singleBar as boolean, cancellable as boolean

これはダイアログの初期化ルーチンとなるものです。ウィンドウを表示する前に、始めにこのルーチンを呼び出し、ウィンドウのタイトル、プログレス・バーは1本か2本か、操作がキャンセル可能かどうかを決定します。

initのコードは次のようになります。

  
const heightDif = 40

gPleaseStopProgress = false
self.title = title
cantCancel = not cancellable
if cantCancel then
cancelText.text = "This operation cannot be cancelled."
end if

if singleBar then
// 使用されない要素を隠す
pBar2.visible = false
subLabel.visible = false

// 位置の調節
statusLabel.top = statusLabel.top - heightDif
statusLabel.left = mainLabel.left
statusLabel.width = mainLabel.width
cancelText.top = cancelText.top - heightDif

// ダイアログのサイズ変更
self.height = self.height - heightDif
end if

まだいくつかのプロパティは取り上げていませんが、上記のものは一目瞭然です。今のところは、これを入力して先に進んでください。後でこれらのプロパティを追加するときに説明しましょう。ここで起きている主なことは、プログレス・バーが1本か2本かのどちらであるかに基づいてダイアログを調節します。1本だけならば、下のテキストのラベルを押上げ(statusLabelのインデントを取り除きます)、同時に全体のウィンドウを小さくします。

我々はまた、cantCancelというローカル・プロパティを設定します。それについて考えている間に、いま追加してしまいましょう。progressDialogに新規プロパティを追加(エディットメニューの「新規プロパティ」)して、cantCancel as booleanとします。

さて、もう一つのメソッドを追加します。これはstartProgressと呼ばれ、パラメータとしてtheMessage as string, theMax as integerをとります。これは、初期メッセージと、プログレス・バーの最大サイズを設定するために呼ばれるルーチンです。

  
mainLabel.text = theMessage
statusLabel.text = ""
pBar1.value = 0
pBar1.maximum = theMax
self.refresh
self.show

実は、ほとんど同じ別のメソッドがあります。二つ目のものは、startSubProgressで、同じパラメータをとります。そのコードは次のようになります。

  
subLabel.text = theMessage
statusLabel.text = ""
pBar2.value = 0
pBar2.maximum = theMax

お分かりのように、これらのルーチンはとても簡単です。プログレス・バーの最大サイズを設定し、テキスト・メッセージの初期表示を確定します。唯一の違いといえば、startProgresspBar1に、startSubProgresspBar2に作用することです。

次に、プログレス・バーに調整が必要になったときに呼ばれるメソッドを追加していきましょう。これは、メッセージを表示するためのテキストと、プログレス・バーのvalueプロパティに追加する値を引数とする簡単なメソッドです。

  
sub updateProgress(theMessage as string, addAmount as integer)
mainLabel.text = theMessage
pBar1.value = pBar1.value + addAmount
self.refresh
if not cantCancel and userCancelled then
cancel
end if
end sub

ここでも、メソッドは簡単です。表示されるテキストとしてtheMessageを渡し、プログレス・バーの値に引数の値を加算します。

このメソッドはpBar1だけを更新しますので、pBar2のために次の第二のメソッドが必要になるでしょう。

  
sub updateSubProgress(theMessage as string, addAmount as integer)
subLabel.text = theMessage
pBar2.value = pBar2.value + addAmount
self.refresh
if not cantCancel and userCancelled then
cancel
end if
end sub

この2つのメソッドには、共にself.refreshコマンドがあることに気がついたでしょうか。このコマンドは、何か設定を変更したあとに、ウィンドウを強制的に再描画するものです。REALbasicは実際のタスクを実行しているのに忙しいとき(たとえばループに入っているとき)、あなたの望むように頻繁にプログレス・バーを更新しないことがあるので、このコマンドは重要です。

この2つのルーチンには、共にとても重要なコードがあることに注意してください。それは、更新するときにユーザが操作をキャンセルしたかを確認することです。すべての操作はキャンセル可能ではありませんので、まず始めにcantCanceltrueではないことを確認します(trueであれば、ユーザがキャンセルしたかを確認する必要はありません)。

ユーザがキャンセルをした場合、コントロールを次のcancelというメソッドに渡します。

  
gPleaseStopProgress = true

これはユーザが操作をキャンセルしたいかを我々に伝える、グローバル・プロパティを設定するとても簡単なメソッドです。重要事項:このグローバル・プロパティは、このダイアログを使用するあなたの書くアプリケーションすべてで使用可能にしておかなければなりません。これについては、後ほどさらに詳しく説明します。

最後に、進行を停止するためのメソッドを追加しなければなりません。これは操作が完了したとき、あるいはユーザがキャンセルしたときのどちらの場合にも呼ばれます。stopProgressという新しいメソッドを追加し、次のコードを入力してください。

  
// これは、ルーチンを呼ぶことでダイアログが
// 閉じられるときに呼ばれます。
pBar1.value = pBar1.maximum
pBar2.value = pBar2.maximum
self.refresh
self.close

これは2本のバーを最大値に設定して(ユーザはバーが最大値をとることを一瞬みることになります)、ウィンドウを閉じます。

驚くことに、これで再利用可能なプログレス・バーのダイアログはほとんど完成しました。あと2、3追加することがあるだけです。

ウィンドウのopenイベントで、次を入力してください。

  
#if targetWin32 then
cancelText.text = "Press ESC key to cancel."
#endif

これは、Windowsユーザ(Commandキーはありません)のために、cancelTextに表示されるテキストを変更します。

最後に、keyDownイベントに次を追加してください。

  
if not cantCancel and userCancelled then
cancel
end if

これは、ユーザがキャンセル・キー(MacユーザはCommand-Period、WindowsユーザはESC)を押すかどうかを監視します。ユーザがキャンセルをしようとした場合には、我々はcancelメソッドを呼びます。

これで終わりです!再利用可能なプログレス・バーのダイアログは完成しました。progressDialogウィンドウを、あなたのプロジェクト・ウィンドウからハードディスクにドラッグしておいて、どのようなプロジェクトにもそれをドラッグしてコピーすることができます。理想的には、それを他のプログラムにリンク(Command-Optionでドラッグ)することで、1つの再利用可能なプログレス・バーのダイアログだけで、あなたのプログラムすべてに使用できます。

次回は、このダイアログを実際にどのように使用するかについてデモを行いましょう。

今週のチュートリアルの完全なREALbasicプロジェクト(リソースを含む)をダウンロードしたい場合は、こちらからダウンロードしてください。

次週

再利用可能なプログレス・バーのダイアログを使用します。

ニュース

REALbasic Developer 2.1 2003年8/9月号発行

REALbasic Developerマガジンの最新号が発行されました!8/9月号は、数多くのすばらしい記事を特集しています。

はじめに、次期バージョンのREALbasicは、Linuxへのコンパイルをサポートするというわくわくするようなニュースをご存じでしたでしょうか?RBDはREAL Software社の仲間へ独占インタビューすることに成功し、特ダネを手に入れました。

REAL Software社について言うと、おそらく多くの人はDavid Grogono氏の名前を聞いたことがあるか、彼とEメールを交わしたことがあると思います。しかし、彼は一体誰なのでしょうか?REALbasicプロダクト・マネージャーであるDavid Grogono氏へのインタビューが、そのすべてを明らかにします。彼はREALbasicを指揮するため、ヨットの船長としてどのような人生を過ごしてきたをみてください。

3Dの達人、Joe Strout氏が今回非常におもしろいリアルタイムのメッシュ・デフォーメーションを携えて戻ってきました。例題プロジェクトでは、風にはためいている布をどのようにシミュレーションするかをお見せします。感動的です。

それから、Charles Yeomans氏から二本立ての記事が届いています。はじめに、REALbasic 5の新しい拡張(Extend)と割り当て(Assign)キーワードについて知っておくべきことを説明し、それから、すてきな「最近の項目」メニューをプログラムに追加する方法について、すばらしい記事を提供してくれました。

そしてもちろん、これらの記事に加えて、ニュース、レビュー、そしてすべての定期コラムの記事も掲載しています!

定期購読者は、今週にも今号が届くでしょう。もし定期購読していない場合は、定期購読しましょう!既刊号を見逃したくない場合は、すべてのバックナンバーを注文することもできます。

Letters

今週は、匿名希望の方からお手紙を頂きました。彼の質問は、リソース(Macにおけるファイルのリソース・フォーク)についてです。

私はID129のリソースの画像があります。そのリソースのファイル名は、Picturesです。どのようにその画像を呼び出し、それを変数に設定すればよいでしょうか?そしてそれができたら、その画像はどのように表示すればよいでしょうか。もし以前のRBUのレッスンですでに述べられていたら申し訳ありません。私はすべてに目を通すのがとても億劫なもので。

このプロジェクトファイルを見てください。まだテストされていませんが、うまく機能するはずです。私はファイルから画像を返すメソッドを作成しました。画像が見つからなければ、それはnilを返します。次はそのメソッドです。

  
function loadPicture() as picture
dim f as folderItem
dim rf as resourceFork

f = getFolderItem("").child("Pictures")
if f = nil then
return nil
end if

rf = f.openResourceFork
if rf = nil then
return nil
end if

return rf.GetPicture(129)
end function

現在のところこの例題はcanvasbackdropプロパティに、返された画像を置きますが、別のプロパティに簡単に画像を保存する、あるいはそれに何か操作することも簡単にできます。

たとえば、ウィンドウが次のような名前のプロパティを持つとすれば:

  
thePicture as picture

次のようにに書くことができます:

  
thePicture = loadPicture

これによって、その変数にリソース129の画像を保存することができます。しかし、まずはじめにnewPictureコマンドで変数を初期化する必要があります。それについては、RBのドキュメントに目を通してください。

画像を変数に入力できれば、次のようにしてcanvasオブジェクト内部、あるいはウィンドウ内部にそれを表示することができます。

  
canvas1.graphics.drawPicture thePicture, 100, 200

または

  
window1.graphics.drawPicture thePicture, 100, 200

最後の2つの数値は、画像の左上の部分が表示されるオブジェクトの水平方向と垂直方向の座標です。

また、このメソッドを整数のパラメータを受け付けるメソッドに修正し、あなたの指定した画像番号の画像を返させることができるでしょう。したがって、loadPicture(129)はID129の画像を返すでしょう。現在のところ、このルーチンはこの画像のみに対するものです。


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

INDEXに戻る