レイアウト変更後の枠表示を調整する

概要

  • 画面レイアウトを変更する」でScratch 2.0風の画面レイアウトに変えましたが、無理矢理位置を変えただけなので不自然なところがいくつもあります。
  • ImageFrameMorphについて」の情報を活用し、できるだけ不自然さをなくすように変更します。


レイアウトを変えた後の画面はこんな感じでした。ステージ・ライブラリのペインと、カテゴリ・ブロックのペインの間に、画面全体の左右の枠が入ってしまっていることがわかります。

各ペインがどのように位置を変えたかを示します。

  • ステージ・ライブラリ:右側→左側
  • カテゴリ・ブロック:左側→中央
  • スクリプト:中央→右側

改造の方針としては以下のように変更していきます。要するに左右をひっくり返すわけです。

  • ステージ・ライブラリの枠は左右を反転させる。
  • カテゴリ・ブロックの枠と、スクリプトの枠を交換させ、それぞれ左右を反転させる。
  • その他の枠も左右を反転させる。必要に応じて分割線の位置を調整する。

便利メソッドの追加

この記事では多くのForm 画像を反転させるので、そのための便利メソッドを追加しましょう。例によってScratchFrameMorph のクラス側にメソッドを追加してください。

ブラウザでScratchFrameMorph を選び、class ボタンを押してからscratch skin のメソッドカテゴリを選びます。コードペインに以下をコピー&ペーストします。

flipSkinAt: aSymbol
  | form |
  form := self skinAt: aSymbol asSymbol.
  form := form flipBy: #horizontal centerAt: 0 @ 0.
  self skinAt: aSymbol asSymbol put: form

上では代入が「:=」となっていますが、コンテキストメニューでaccept をすると「←」に変わります。
Form 画像の左右を反転させるには、Form クラスの #flipBy:centerAt: というメソッドを使っています。引き数に方向(#vertical か #horizontal)と基準の位置を指定します。
ScratchFrameMorph に対して画像のキーを指定してメッセージを送れば、その画像が左右反転されます。

ステージ・ライブラリの枠を左右反転させる

ScratchFrameMorph において、ステージはstageFrame, ライブラリはlibraryPane のインスタンス変数が保持しています。stageFrame はImageFrameMorph のオブジェクトですが、libraryPane はDividedImageFrameMorph を継承したScratchLibraryMorph のオブジェクトです。
stageFrame の枠の画像は、ScratchFrameMorph の#createBasicPanes メソッドの中で指定されているように、#stagePane というキーで取得できます。

stageFrame := ImageFrameMorph new initFromForm: (ScratchFrameMorph skinAt: 'stagePane').

一方のlibraryPane の枠の画像は、ScratchLibraryMorph の#initialize メソッドの中で指定されています。こちらは、#spriteLibraryPaneFrameTransparent2 というキーで取得できます。

 self initFrontFromForm: (ScratchFrameMorph skinAt: 'spriteLibraryPaneFrameTransparent2')

先ほどの便利メソッドを用いて、stageFrame とlibraryPane で使われる枠の画像を左右反転させます。

ScratchFrameMorph flipSkinAt: #stagePane.
ScratchFrameMorph flipSkinAt: #spriteLibraryPaneFrameTransparent2.

Workspaceにコピー&ペーストし、選択してからdo itしてください。

カテゴリ・ブロックとスクリプトの枠を交換する。

カテゴリ・ブロックのペインはviewerPane が、スクリプトのペインは scriptsPane が保持しており、いずれもDividedImageFrameMorph を継承したScratchViewerMorph とScratchScriptEditorMorph のオブジェクトです。
枠の画像はどちらのクラスでもinitialize メソッドの中で設定しています。
カテゴリ・ブロックのペインの枠の画像は#blocksPaletteFrameTransparent2 が、スクリプトのペインの枠の画像は#scriptPaneFrameTransparent2 がそれぞれキーとなっています。
互いの画像を入れ替えた上で画像の左右を反転させましょう。

f1 := ScratchFrameMorph skinAt: #blocksPaletteFrameTransparent2.
f2 := ScratchFrameMorph skinAt: #scriptPaneFrameTransparent2.
ScratchFrameMorph skinAt: #blocksPaletteFrameTransparent2 put: f2.
ScratchFrameMorph skinAt: #scriptPaneFrameTransparent2 put: f1.
ScratchFrameMorph flipSkinAt: #blocksPaletteFrameTransparent2.
ScratchFrameMorph flipSkinAt: #scriptPaneFrameTransparent2.

Workspaceにコピー&ペーストし、選択してからdo itしてください。

途中経過と微調整

ここまでの変更によって画面の不自然さもある程度解消されてきました。

目立つ不自然さは、topPane の部分の接続部分、ステージの表示位置、そしてDividedImageFrameMorph 関係の分割線の位置です。
topPane の接続部分の問題は、topPane の枠の画像(#topPane)を左右反転すれば解消されます。titlePane の画像も合わせて反転しておきます。

ScratchFrameMorph flipSkinAt: #topPane.
ScratchFrameMorph flipSkinAt: #titlePane.

実はstageFrame の枠の画像は左右のマージンがかなり違います。そのため、titlePane やworkPane は位置調整する必要があります。

ScratchFrameMorph の#fixLayout メソッドで、titlePane やworkPane の位置を設定している部分を変更します。

workPane position: stageFrame topLeft + (4@37).

まず、workPane を右に6ピクセル右に移動させます。赤字部分だけ変更します。

workPane position: stageFrame topLeft + (10@37).

次は titlePane です。

titlePane
  position: stageFrame topLeft + (0@1);
  width: stageFrame width - 6;
  height: 36.

こちらも6ピクセル右に移動させます。赤字部分を変更したら、コンテキストメニューでaccept を選んでください。

titlePane
  position: stageFrame topLeft + (6@1);

DividedImageFrameMorph の枠のマージン調整

残った大きな修正点は、DividedImageFrameMorph の枠のズレを直すことです。
該当するのは、ScratchLibraryMorph, ScratchViewerMorph, ScratchScriptEditorMorph の3つです。いずれも initialize で枠の左右マージンを設定しています。
ScratchLibraryMorph の#initialize メソッドでは以下のようになっています。

self middleBarLeftMargin: 0 rightMargin: 6.

左右のマージン量を逆転させます。赤字部分を変更したらaccept してください。

self middleBarLeftMargin: 6 rightMargin: 0.

次は、ScratchViewerMorph の#initialize メソッドです。

 self middleBarLeftMargin: 5 rightMargin: 0.

こちらは左右とも0に設定します。赤字部分を変更したらaccept してください。

 self middleBarLeftMargin: 0 rightMargin: 0.

最後に、ScratchScriptEditorMorph の#initialize メソッドです。このメソッドではもともと左右マージンが設定されていません。そこで、新たにメッセージ式を追加します。赤字の行をコピー&ペーストして、accept してください。

self
  initFrontFromForm: (ScratchFrameMorph skinAt: #scriptPaneFrameTransparent2)
  topSectionHeight: 90.
self middleBarLeftMargin: 0 rightMargin: 5.
self color: (Color r: (149/255) g: (154/255) b: (159/255)).

左右マージンの調整は以上ですが、分割線の画像も左右反転させます。こちらはWorkspace にコピー&ペーストして、do itしてください。

ScratchFrameMorph flipSkinAt: #dividedImageFrameBar.

最後の微調整

修正はほぼ完了ですが、readoutPane の位置が若干ずれています。再度、ScratchFrameMorph の#fixLayout メソッドを修正します。最後の方で設定されています。

 readoutPane
 width: xyReadout width + 23;
 height: xyReadout height + 15;
 position: stageFrame bottomRight - ((readoutPane width + 6)@3).

上を下のように修正して、6ピクセル右に移動させます。赤字部分だけ変更してaccept してください。

 readoutPane
 width: xyReadout width + 23;
 height: xyReadout height + 15;
 position: stageFrame bottomRight - ((readoutPane width + 0)@3).

完成

以上でレイアウトの変更は完了しました。

readoutPane の影の部分が数ピクセルおかしいのと、左右のマージンが調整できていない部分がありますが、これはいずれ対応しましょう。

追記

公開した後で右上のviewModeButtonsPanel のイメージが異なっているのに気づきました。新しいレイアウトに対応するように左右反転させましょう。

ScratchFrameMorph flipSkinAt: #quarterViewModeOn.
ScratchFrameMorph flipSkinAt: #quarterViewMode.
ScratchFrameMorph flipSkinAt: #quarterViewModeOver.
ScratchFrameMorph flipSkinAt: #normalViewModeOn.
ScratchFrameMorph flipSkinAt: #normalViewMode.
ScratchFrameMorph flipSkinAt: #normalViewModeOver.