カテゴリの追加方法

概要

新しいカテゴリの作成

ここでは例として、eventsとmore blocksの2つのカテゴリを追加することにします。
実際に何のカテゴリを作るかは自由に決めることができますが、適宜読み替えて作業する必要があります。

カテゴリ一覧への登録

新しいカテゴリを追加するには、ScratchViewerMorph の rebuildCategorySelectors を修正します。ブラウザで、Scratch UI Panes ⇒ Scratch Viewer Morph ⇒ initialization ⇒ rebuildCategorySelectors と選びます。
catList 配列を注意深く変更して、eventsとmore blocksを追加します。

catList := #(
  motion    events
  looks     control
  sound     sensing
  pen       operators
  variables 'more blocks').

間違いなく入力したらコンテキストメニューでacceptを選びます。

more blocksは2単語で間にスペースがあり、そのままだとmoreとblocksのカテゴリが作られてしまうため、両端をシングルクオートで囲む必要があります。

カテゴリ画像の作成

次にカテゴリ一覧に表示するための画像を作らなければなりません。新たな色で作り直すのは面倒なので、今回は既存のものを流用します。
つまり、eventsカテゴリはvariablesカテゴリと同じ色、more blocksカテゴリはsoundカテゴリと同じ色となります。
今回も便利メソッドを使ってカテゴリ一覧の画像を作ります。
ワークスペースを開いて、以下の内容をコピー&ペーストし、全体を選択してからコンテキストメニューでdo itを選んでください。

ScratchFrameMorph skinAt: #events put: (ScratchFrameMorph skinAt: #variables).
ScratchFrameMorph skinAt: #eventsPressed put: (ScratchFrameMorph skinAt: #variablesPressed).
ScratchFrameMorph skinAt: #eventsOver put: (ScratchFrameMorph skinAt: #variablesOver).
ScratchFrameMorph skinAt: #'more blocks' put: (ScratchFrameMorph skinAt: #sound).
ScratchFrameMorph skinAt: #'more blocksPressed' put: (ScratchFrameMorph skinAt: #soundPressed).
ScratchFrameMorph skinAt: #'more blocksOver' put: (ScratchFrameMorph skinAt: #soundOver).

カテゴリ毎に3種類の画像が必要なので、計6つのメッセージ式を使ってdataカテゴリとmore blocksカテゴリの画像を生成(流用)しています。
これで、デスクトップメニューからスクラッチを起動すれば以下のようにカテゴリ一覧が表示されるはずです。

カテゴリにブロックを加える

Scratch 2.0では、Scratch 1.4の制御(Control)カテゴリにあったブロックの一部がイベント(Events)カテゴリに移りました。
そこで、似た感じになるように control カテゴリのブロックを events カテゴリに移すことにします。
controlカテゴリのブロックは、ScriptableScratchMorph のクラス側にある blockSpecs メソッドで定義されています。
配列から ‘control’ 以下の要素を抜き出してみましょう。

'control'
    ('when %m clicked' S -)
    ('when %k key pressed' K -)
    ('when %m clicked' M -)
    -
    ('wait %n secs' t wait:elapsed:from: 1)
    -
    ('forever' c doForever)
    ('repeat %n' c doRepeat 10)
    -
    ('broadcast %e' - broadcast:)
    ('broadcast %e and wait' s doBroadcastAndWait)
    ('when I receive %e' E -)
    -
    ('forever if %b' c doForeverIf)
    ('if %b' c doIf)
    ('if %b' c doIfElse)
    ('wait until %b' s doWaitUntil)
    ('repeat until %b' c doUntil)
    -
    ('stop script' s doReturn)
    ('stop all' - stopAll)

これを適当にコピペして、controlとeventsの二つのカテゴリに分けます。

'control'
    ('wait %n secs' t wait:elapsed:from: 1)
    -
    ('forever' c doForever)
    ('repeat %n' c doRepeat 10)
    -
    ('forever if %b' c doForeverIf)
    ('if %b' c doIf)
    ('if %b' c doIfElse)
    ('wait until %b' s doWaitUntil)
    ('repeat until %b' c doUntil)
    -
    ('stop script' s doReturn)
    ('stop all' - stopAll)
'events'
    ('when %m clicked' S -)
    ('when %k key pressed' K -)
    ('when %m clicked' M -)
    -
    ('broadcast %e' - broadcast:)
    ('broadcast %e and wait' s doBroadcastAndWait)
    ('when I receive %e' E -)

問題なく変更できたら、コンテキストメニューからacceptを選びます。

カテゴリ内のブロックの色を設定する

今までの変更を行うと、controlカテゴリの一部のブロックがeventsカテゴリに表示されることがわかりますが、ちょっとおかしくなっています。

これは、カテゴリ内のブロックの色が適切に設定されていないためです。これを適切に行うには、ScriptableScratchMorph のクラス側にある blockColorFor: メソッドを修正する必要があります。
このメソッドは、引き数として渡されたカテゴリ名に対して、色の値を返すというものです。未定義であれば「赤」が返されるので上のような不自然なブロックとなってしまいます。
eventsカテゴリはvariablesカテゴリと同じ色、more blocksカテゴリはsoundカテゴリと同じ色としましたので、メソッドに以下の2行を加えます。

'events' = aCategory ifTrue: [^ (Color h: 25 s: 0.88 v: 0.95)].
'more blocks' = aCategory ifTrue: [^ (Color h: 296 s: 0.66 v: 0.85)].

実際はこんな感じです。

変更後にコンテキストメニューからacceptを選べば、カテゴリ内のブロックの色が変わります。

これでも不自然な感じがしますが、これはHatBlockMorphの表示方法に原因があります。この対応については別の記事で説明します。