はじめてのMorphicチュートリアル(第14回)「文字の表示」

モーフに文字を表示する方法について学ぶ。
モーフに文字を表示するには、おおまかに2通りの方法がある。1つはStringMorphを使う方法、もう1つはdrawOn:で直接描画する方法である。

StringMorphを使う

StringMorphは文字を表示するためのモーフである。

(StringMorph contents: 'aiueo') openInWorld.

上のコードをPlaygroundに入力してDo itすれば、画面の左上に小さく aiueo と表示されるのがわかる。
StringMorph
これは文字を表示するモーフであり、マウスでドラッグして好きな場所に移動することができる。
表示するフォント名やポイント数を指定したい場合には、contents:の代わりにcontents:fonts:メッセージを送る。

(StringMorph contents: 'あいうえお'
                  font: (LogicalFont familyName: 'Osaka' pointSize: 30)) openInWorld.

StringMorphをサブモーフにすることもできる。MyMorph2でメッセージを表示するようにするなら、initializeメソッドを以下のように変更する。

initialize
    super initialize.
    ActiveHand keyboardFocus: self.
    keys := Set new.
    (StringMorph contents: 'Hello!'
                 font: (LogicalFont familyName: 'Apple Chancery' pointSize: 30))
        in: [ :morph |
            morph topLeft: self topRight.
            morph color: Color red.
            self addMorphBack: morph ]

後半の4行がStringMorphを追加している部分である。簡単に説明しておくと、まず指定した文字列とフォントでStringMorphを生成しておき、得られたモーフに対して位置を設定(StringMorphの左上がMyMorph2の右上の座標になるように)して赤色にし、サブモーフとして追加するという流れになっている。
Screen Shot 2015-06-18 at 7.26.01
残念ながらStringMorphでは背景色を設定できないので、背景色が必要な場合にはStringMorphを、色を付けた素のモーフのサブモーフにして同じ位置に設定する。

drawOn:で表示する

drawOn:はモーフを描画する際に送られるメッセージで、第12回ではそのことを利用して画像を表示した。これと同様にモーフ描画の一部として文字を書く方法がある。
モーフを描画する必要が生じると、各モーフに対してdrawOn:というメッセージが送られる。メッセージには描画先としてのCanvasオブジェクトが引数として添えられているので、このCanvasオブジェクトに描画メッセージを送ってモーフを描く。
文字を描くためにCanvasオブジェクトに送ることのできるメッセージはいくつかあり、Canvasクラスのdrawing-textプロトコルを見ればわかるが、実際にはdrawString:at:メッセージか、drawString:at:font:color:メッセージだけで事足りるだろう。前者は指定された文字列を指定された位置にデフォルトフォントを用いて黒色で描画するというものであり、後者は更にフォントと色を指定できるというものである。
応用例として、押下中の文字を表示する機能をMyMorph2に付けてみよう。

drawOn: aCanvas
    super drawOn: aCanvas.
    aCanvas drawString: keys asString at: self topLeft

2行目は本来のモーフの描画を、親クラスであるMyMorphに行わせるためのものである。3行目では、押下中のキーを保持しているインスタンス変数keysの内容を文字列に変換し、モーフの左上に描画している。
drawOn:を用いる際の注意点として、特定のタイミングで明示的に表示内容を更新したい場合には、自分自身に対してchangedメッセージを送る必要があることである。MyMorph/MyMorph2では、画像を表示させる際に大きさや位置を変更しているため暗黙的な描画が行われるのでchangedメッセージを送る必要はないが、文字列内容だけを変更した場合などは、変更後に描画を行わせるためにself changed.というメッセージ式を実行する必要がある。
(第14回おわり)