|
概要 |
GUIシリーズ第4弾の「減法混色」。先週の「加法混色」と似ていますが、今回は「モデル1つに対して複数のビューが対応」しているアプリケーションを構築します。 ちなみにテキストはこちら(http://www.cc.kyoto-su.ac.jp/~atsushi/Programs/ColorCMY/index-j.html)
|
概要 |
GUIシリーズ第4弾の「減法混色」。先週の「加法混色」と似ていますが、今回は「モデル1つに対して複数のビューが対応」しているアプリケーションを構築します。 ちなみにテキストはこちら(http://www.cc.kyoto-su.ac.jp/~atsushi/Programs/ColorCMY/index-j.html)
|
準備 |
マシンメンテナンス
息をするように...とは言いませんが、マシンメンテナンスを行いましょう。(日々のマシンメンテナンス)
今日の目標
まずは目標物をご覧に入れましょう。
先週のRGBに引き続き、今週拵えるのはCMY(Cyan、Magenta、Yellow:色材の三原色)の強さをスピンボタンで調整することで、色を作り出すアプリケーションです。
準備プログラムの実行
以下のプログラムを実行して、準備を整えましょう。
| aCollection | (aCollection := OrderedCollection new) add: #url: -> 'http://www.cc.kyoto-su.ac.jp/~atsushi/Programs/ColorCMY/ColorCMY.st'; add: #comment: -> 'Copyright 2008-2011 KSU (Kyoto Sangyo University). All Right Reserved.'; add: #bundle: -> #KSU; add: #package: -> 'KSU-Template'; add: #nameSpace: -> #KSU; add: #category: -> 'KSU-Template'; add: #class: -> #{KSU.ColorCMY}; add: #protocol: -> #examples; add: #selector: -> #example1; add: #execute: -> [#{KSU.ColorCMY} value example1]; yourself. JunSystem perform: ((aCollection collect: [:each | each key]) inject: String new into: [:selector :key | selector , key]) asSymbol withArguments: (aCollection collect: [:each | each value]) asArray
|
今回のGUI部品:Label, Spin Button, Percent Done Bar |
|
コードリーディング |
color
先週にも同じ構造を見ましたよね。では、このプログラムを説明してみてください。
regGauge, greenGauge, blueGauge
先週にも同じ構造を見ましたよね。では、このプログラムを...(同
updateColor, postOpenWith:
先週にも同じ構造を見ましたよね。では...(同
updateColorCyan:, updateColorMagenta:, updateColorYellow:
(同
先週との違い
ことごとく先週と似通った構造のようですが、違う点もあります。実はここが結構重要なのです。
先週は「フィールド」と「スライダー」が登場し、それぞれ別々のモデル(ValueHolder)を持っていました。 ところが、今週の「スピンボタン」と「プログレスバー」は、実は1つのモデルを共有しているのです。
では、今回のモデルはどのような仕事を受け持っているのでしょうか。値が変わった際に、何をするのでしょうか。調べてみましょう。 どんな仕事を頼まれたのかは、ValueHolder自身が知っていますから、ValueHolderに尋ねてみましょう。(ここではcyanGaugeのValueHolderを調べます。)
example1をインスペクト(Inspect)したら、cyanGaugeにダイブ(Dive)します。さらにdependentsにダイブすると、以下のように3つの項目が表示されるはずです。
(※実行環境により結果は異なります。)
どうやら3つの仕事を受け持っているようです。1つ目の仕事は、cyanGaugeメソッドの中で依頼した「色変更の仕事」です。 2つ目は「InputFieldView」とあるので、スピンボタンに付随するテキストフィールドを指していて、 3つ目は「ProgressWidgetView」とあるので、プログレスバーを指しているのでしょう。 それぞれ、値が変更された時に「色を変更する」「欄内の数値を変更する」「進行度の割合を増減する」といった仕事が行われるのです。
2つ目と3つ目は、どちらもビューです。1つのモデル(cyanGauge)が同時に複数のビューに情報を提供しているのです。 「MVC」と一言に言えば、モデルとビューとコントローラが、それぞれ1つずつ連携している様子を思い浮かべるかもしれませんが、 決してそうではなく、ビューやコントローラさえも、1つのモデルに対して複数対応していて良いのです。
何かしらの出来事(情報、モデル)があれば、それに対して幾つものマスメディア(ビューたち)が取り上げるではありませんか。 MVCという構造は現実世界に存在する構造であって、特別なものでも難しいことでもないのです。さて、これで少しは「MVC」に親近感が湧いたでしょうか。
|
コードライティング |
今日も今日とてプログラミング。今回は、ちょっとしたTipsの紹介を兼ねてプログラミングを行いましょう。
「検査」メニューの設置
ちょうど前節で、example1をインスペクトする機会がありました。最初からオブジェクトと対話したいのなら「Inspect it」すると思いますが、 「Do it」した後から「あぁ、Inspect itしておけばよかった」...なんて思うことは多々あります。 その際に便利なのが「検査」メニュー。メニューバーに「検査」という項目を入れて、選択すればインスペクタが開くのです。便利ですよ。
詳細は説明しませんが、ヒントとして画像を掲載しておきます。おきばりやしとくれやす!
|
余談 |
ObjectMemory allObjects
Smalltalk上で生きている全てのオブジェクトに会えるということを知っていますか。以下をインスペクトすれば、全てのオブジェクトをつかまえることができます。
ObjectMemory allObjects
前節で「インスペクトし忘れた」などということが起きても問題ありません。この全オブジェクトの一覧があれば、そこから探し出せば良いのです。 例えば、ColorCMYのexample1を動かしておいて、全オブジェクトのリストからColorCMYクラスのオブジェクトだけを探し出します。
ObjectMemory allObjects select: [:anObject | anObject class = KSU.ColorCMY]
すると、見事にオブジェクトが見つかりました。試しに、シアンの値を「0.1」にするようメッセージを投げてみたところ、確かにシアンの値が変更されて、背景色が赤っぽくなりました。
こんなことができるということは、今、動いている「トランスクリプト」も「ワークスペース」も「ブラウザ」も、ひっつかまえてメッセージを送ることができるのです。 なんて自由な世界!!(その分、非常に危ないのですが。。。)
とても断片的ですが、以上が余談でした。
|
さいごに |
さて、先週と似たようなテーマでしたが、いかがでしたか。 コードリーディングをほとんど割愛してしまいましたが、それほど先週と似たプログラムだったのです。 さて、そのプログラムを見て、共通の構造を見出だせたでしょうか。そして、それを括り出せるでしょうか...。 再来週の「リファクタリング」が楽しみですね!(
保存を忘れずに
今日取り組んだ内容を保存しておいて、また来年に活かしてくださいね。