RealBasic University

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

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

SimplePaint:パート II

前回のレッスンで、私たちはペイント・プログラムの基礎部分を進めてきました。今週は、より完成に近づけるためにいくつかの機能を加えていきましょう。

色の選択機能を加える

SimplePaintは子供向けプログラムなので、移動可能なパレットやツールバーのようなインターフェース要素で混乱したくはありません。そうすると、どのように色を変える方法を導入すればよいのでしょう?それは簡単です。描画領域にカラーパレット部分を埋め込めばよいのです!

小さな子供は、フローティング・パレットと描画領域部分との間の区別がつきません。だから、私たちは描画領域の一部にカラーパレットを作成します。そうすれば、うっかり移動したり閉じたりすることができませんね。

このイメージをSimplePaintのプロジェクト・フォルダーに保存してください。

そこで、ファインダからプロジェクト・ウィンドウまでそれをドラッグして、プロジェクトにインポートしてください。それはプロジェクトのオブジェクト・リストに"パレット(palette)" と呼ばれるイタリック体の項目を加えます。(イタリック体は、オブジェクトが埋め込まれたのではなく、それがインポートされたことを示しています――要するに、ハードディスク上のオリジナルのオブジェクトにリンクされたということです。それはオリジナルを消去すれば、プロジェクトはコンパイルできないことを意味します。)

次に、カラーパレットの画像を表示するcanvasオブジェクトが必要です。canvas――それは空模様(夕焼け模様でなく)の長方形――をREALbasicのツールパレットからpaintWindowへドラッグしてください。そしてcanvasに次の属性設定を与えてください:

よいですね。次に、カラーパレットを動作させる(実際は描画ツールのカラーを変更する)ためにいくつかのコードを加える必要があります。

それはとても簡単です。コードエディタを開くためにpaletteCanvas上でダブルクリックをしてください。おそらくPaintイベントが選択されますが、mouseDownイベントが必要ですね。それに変更して、このコードを入力してください。

 changeColor(me.graphics.pixel(x, y)) 

括弧内の部分は、マウス・カーソルが指しているピクセルの色を返します。meはコードを含むオブジェクトを意味することを思い出してください――この場合はpaletteCanvasです。paletteCanvasgraphicsオブジェクトは、そこで描画されるものすべて(つまりパレット・グラフィック)を含み、pixelメソッドは通過したx, y座標のピクセルの色を返します。

したがってこのコードで行うことは、クリックされた色をchangeColorと呼ばれるメソッドへ送ることです。今まさに、そのメソッドを書かなければなりません!

Editメニューへ行き、"New Method"を選択してください。ダイアログにこのように入力してください。

次はこのメソッドのコードです。

   dim tempC as color 

tempC = newColor

if tempC <> c then
oldC = c
c = tempC
end if

このルーチンはとても簡単です。tempCと呼ばれる一時変数に新しいカラーを記憶します。それを現在の描画色のcと比べて、もしそれが一致しない場合はカラーが変更されています。したがって、oldCに現在のカラーを保存し、現在のカラーをtempC(新しいカラー)に合わせます。

しかし鋭い読者は、これがコンパイルされないことに気づくでしょう。oldCはいままでに定義されたことがないのです!

より鋭い読者は、oldCとは何か――なぜ古いカラーを保存するのか、と不思議に思うでしょう。

oldCの裏にある理由は、次のすばらしい特徴(おかしいほど単純ですが)を加えるからです。それは以前使ったカラーと、現在のカラーを切り替える方法です!

それを機能させるために、現在のカラーと以前のカラーを記憶しておかなければなりません。だからoldCが必要なのです。したがってその属性を加えましょう。Editメニューに行き、"New Property"を選択して、oldC as colorと宣言しましょう。

さてプログラムを実行してみてください。それはとてもうまく機能します。カラーパレットをクリックすれば、その色で描画し始めるでしょう。白がパレットにあるので、消しゴムとして使えますよ!

もう十分に遊んでみましたね。では今さっきお話した機能を加えることにしましょう。paintWindowのkeyDownイベントへ行って、このコードを入力してください。

 //カラーの交換 
if key = " " then
changeColor(oldC)
end if

読めば分かるとおり、これはユーザがスペースキーを押したときに、現在のカラーと以前使っていたカラーを交換します。試してみてください――それはとても便利ですよ!

しかしここで小さな問題に気がつきました。実際に描いて見なければ、現在の色が何色であるか知る方法がないのです。現在使っている色が何色であるか示してくれる機能があったほうがいいと思いませんか?

カラー表示機能を加える

paletteCanvasのすぐ下に、別のcanvasを加えましょう。そして次の設定を与えてください:

これが何であるか分かるラベルを付けましょう('Aa'を持つツールパレット項目であるstaticTextをドラッグします)。

するとpaintWindowはこのように見えるはずです。

さて、ここでいくつかのコードを入力する必要があります。colorCanvas上でダブル・クリックして、Paintイベントにこのコードを入力してください。

 g.foreColor = c 
g.fillRect(0, 0, g.width, g.height)

// 境界線を引く
g.foreColor = rgb(0, 0, 0) // 黒
g.drawRect(0, 0, g.width - 1, g.height - 1)

おそらく理解できると思いますが、これは現在のカラーで、色指標となる四角を埋め尽くします。それから黒の境界線で四角の周りを囲みます。なぜ境界線を引くのでしょうか?(ヒント:現在の描画色が白色だったら、境界線がない時にキャンバスはどのように見えるでしょうか?)

しかしプログラムを走らせて見れば、現在の描画色がぜんぜん変わらないことに気がつくでしょう!どうしたのでしょうか?もちろん私たちはすべて正しく行ってきました。

そのとおりです。私たちはすべて正確に行ってきました。しかしひとつだけ細部を見逃していました。ColorCanvasPaintイベントが発生したときにだけ描画します。しかしPaintイベントはダイアログ・ボックスあるいは他のプログラムからのウィンドウがコントロールを覆い隠した直後にだけ発生するので、全スクリーンを占め、単独で実行させるようデザインされている私たちのプログラムでは、決して自動的に再描画されません!

したがって解決方法は無理矢理にコントロールに再描画させなければなりません。それはcolorCanvas.refreshコマンドを使用すれば簡単です。よってchangeColorメソッドに戻って、このように作成してください。

 dim tempC as color 

tempC = newColor

if tempC <> c then
oldC = c
c = tempC
colorCanvas.refresh
end if 

素晴らしい!これで描画色が変更されたときに、colorCanvasは強制的に再描画させられるようになりました。ここでSimplePaintを立ち上げれば、現在のカラーはカラー指示ボックスに反映されます。

もう一つの問題

しかしながら、すでに気づいているかもしれませんが、このプログラムは、ユーザにコントロール・ボックス上にも描画させます。それはこのようにやや不完全に見えます。

私は解決法をすでに持っているのですが、来週までにあなた自身の解決法を見つけ出すように挑戦状を出しましょう。

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

次週

SimplePaintのコントロール上の描画問題を解決し、さらに機能を追加します。

News

REALbasic Developerマガジンは、現在、案内広告が利用できることを発表いたします。案内広告は商品やサービスの提供、あるいは求人など様々なカテゴリーからなるテキスト広告です。

REALbasic Developerの案内広告は、夢のようなお値段です。たった12ドルで、何千人ものリアルベーシック開発者へ届くのです!広告は複数刊を通じて出すとさらにお得になります。それはあなたのビジネス、ウェブサイト、商品、プラグ・イン、"REALbasic製"ソフトウェア、求人、その他を促進するすぐれた方法です。

案内広告を申し込むためには、オンライン・フォームに記入するだけです。正確な広告の価格を教えてくれ、クレジットカードによる支払い手続きもできます。

REALbasic Developer創刊号の広告締め切りは2002年3月22日です。あなたの広告を今すぐに!

Letters

今週の最初の手紙はRBUピラミッドのウィンドウ版で問題を見つけたCharlesさんからです。

Marcさん、

RB 4を用いて、私はインストラクション・ヘルプ・メニューにスクロール・コードを追加しました。それは動作します。しかしここで質問ですが、ウィンドウズ用にプロジェクトをコンパイルし、そのコードのポップアップメニューを使用した時、テキストが黒で強調表示されるのです。エディット・フィールドをクリックすると黒は消えます。私の質問は次の通りです。見苦しい黒の強調表示をコントロールする方法はあるでしょうか。

ところで、それはMacでは淡黄色になります。

Charles

おかしなバグですね、Charlesさん。私はWindowsのコンパイルについてはほとんど知りません。だからこれについての"正しい" 解決策はよく分かりません。Macでは、強調表示の色は、アピアランスコントロールパネル(the Appearance control panel)の設定で制御され、REALbasicはその設定を使用しています――おそらくPCにも同様の設定があるでしょう(しかしRBはそれを使用しないか、それが黒に設定されているかです)。

しかし実のところ、RBUピラミッドはもともと、RBがプログラム的にエディット・フィールドのスクロールをサポートする前のREALbasic 3で書かれました。そのときのスクロール方法は、いくつかのテキストを選択することによってカーソルを移動させることでした。すると、エディットフィールドは自動的にスクロールし、選択部分が見えました。現在RBはスクロールをサポートし、ヘルプ・トピックが強調表示される必要がありません。

editField1.selLength = 0コマンド、あるいは適当な行へスクロールするeditField1.scrollPositionメソッドを使用して、強調表示をオフにすることができます。(おそらく後者の方法がベストでしょう。なぜならeditFieldの上端までヘルプ・トピックの見出しをスクロールできるからです。実際、RBU 047のバグ修正セッションではその方法を採りました。)

次に、Ersinさんからです。

わたしは、ユーザが2つの数を与えて、プログラムがそれを足し算して、数の合計を書いてくれるプログラムが作りたいのです。

どうやってこれを作ったらいいか分かりません。

どうぞよろしく。

こんにちは、Ersinさん!

以前にこのような問題を簡潔にカバーしましたが、要約すると、取り扱う問題はeditFieldでは文字列(テキスト)を含み、数値変数(整数あるいは倍精度実数)は数値だけを含んでいるということです。テキストで数学的操作を行うことはできないし、数値で文字列を扱う操作はできません。

幸いにも、REALbasicはある型から別の型へコンバートするメソッドを提供します。val()関数は文字列を数値に返します。str()関数はその逆(数値から文字列)を行います。

したがって2つのeditFieldをともに加え、3番目のeditFieldに結果を入力するために、次のようなことをするでしょう。

 editField3.text = str(val(editField1.text) + val(editField2.text)) 

2つのval() 関数はeditField1editField2の内容を数値で返すので、それを加えることができます。足した結果は、数値を文字列へ変換した結果を返すstr()関数で囲まれ、それはeditField3に代入されます。

下の始めの2つの方法は、おそらく分かるとは思いますが、うまく働きません

 // 文字列は加えることができないので、それらを
// 連結(結合)させます。例えば
// "1" + "3" = "13"
editField3.text = editField1.text + editField2.text

// 次は数値の足し算をしていますが、まず始めに
// str()関数で数値を文字列に変換することなしに、それを
// 文字列に入れることはできません。
editField3.text = val(editField1.text) + val(editField2.text)

// これで動きます!
editField3.text = str(val(editField1.text) + val(editField2.text))


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

INDEXに戻る