GraphicWindows

 さて、予告通り、今回はGraphicWindowsモジュールを解説することにしましょう。
 今回紹介するプログラムは、Windowを一つ作成し、そのWindow内に星を描く、というものです。

ソース

 まずは、サンプルコード全体を以下に示します。
DrawStar.mod
MODULE DrawStar;

FROM
	GraphicWindows
IMPORT
	Window,
	OpenGraphicWindow,
	CloseGraphicWindow,
	SetPen,
	TurnTo,
	Move;

FROM
	EventBase
IMPORT
	mouseDown,
	Point,
	EventRecord,
	PushTask,
	PopTask,
	PollEventTasks;

VAR
	wndStar		:Window;
	blnDone		:BOOLEAN;
	tskMouse	:INTEGER;

PROCEDURE TrackMouse(VAR recEvent :EventRecord) :BOOLEAN;
BEGIN
	IF recEvent.what = mouseDown THEN
		blnDone := TRUE;
		RETURN TRUE
	ELSE
		RETURN FALSE
	END
END TrackMouse;

PROCEDURE DrawStar(wndArg :Window);
VAR
	intLoop	:INTEGER;
	intDig	:INTEGER;
BEGIN
	SetPen(wndArg,10,50);
	TurnTo(wndArg,0);
	intDig := 0;
	FOR intLoop := 0 TO 4 DO
		TurnTo(wndArg,intDig);
		Move(wndArg,80);
		intDig := intDig + 216;
		IF intDig > 360 THEN
			intDig := intDig - 360
		END
	END
END DrawStar;

BEGIN
	OpenGraphicWindow(wndStar,50,50,100,100,"DrawStar",DrawStar);
	tskMouse := PushTask(TrackMouse);
	REPEAT
		PollEventTasks
	UNTIL blnDone;
	PopTask(tskMouse);
	CloseGraphicWindow(wndStar)
END DrawStar.

解説

 今回紹介するDrawStarプログラムは、前回紹介したHelloWorldプログラムとほとんど変わらないことが判るかと思います。言ってしまえば、「Hello,World!」と表示されていたものを星に換えただけのプログラムです。そこで、前回さらっと紹介した事柄は省いて、今回の肝であるところのGraphicWindowsモジュールを中心に説明して行きます。
FROM
	GraphicWindows
IMPORT
	Window,
	OpenGraphicWindow,
	CloseGraphicWindow,
	SetPen,
	TurnTo,
	Move;
 この部分は、前回紹介した様に、GraphicWindowsモジュールから、Window、 OpenGraphicWindow, CloseGraphicWindow, SetPen, TurnTo, Moveを取り込みます。Mac上に実現しようとする大抵のApplicationでは、キャラクタベースのインターフェースでは無しに、グラフィカルなインターフェースとグラフィカルな結果出力を用意したいだろうかと思います。つまり、画像を展開できるWindowを開き、画像を描き、という作業が大抵の場合必要となるでしょう。これを実現するのが今回簡単に紹介するGraphicWindowsモジュールです。
 上で紹介したWindow、 OpenGraphicWindow, CloseGraphicWindow, SetPen, TurnTo, Moveは、今回利用するものだけを取り込んだのであって、GraphicWindowsモジュールには、下のような型・関数等が用意されています。
TYPE
	Window
	RestoreProc
	Mode

PROCEDURE
	OpenGraphicWindow
	RedefGraphicWindow
	Clear
	CloseGraphicWindow
	SetMode

	Dot
	SetPen
	TurnTo
	Turn
	Move
	MoveTo
	Circle
	Area
	CopyArea

	Write
	WriteString
	IdentifyPos
こられの説明はDocumentにありますから、ここですべてに関して詳細を紹介するのは止しまして、前回のHelloWorldプログラムと、今回のDrawStarプログラムで用いられているものについての詳しく紹介します。

Window

 Windowデータを納める変数型。
 Windowsモジュール内で定義されている。

PROCEDURE OpenGraphicWindow(VAR u :Window; x,y,w,h :INTEGER; name :ARRAY OF CHAR; Repaint :RestoreProc);

 新規にWindowを作成する。
 各引数は、
VAR u :Window
作成されたWindowデータが納められる。
x,y,w,h :INTEGER
それぞれ作成するWindowの、左下の画面左下端からの水平方向位置、同垂直方向位置、Window幅、高さ。
name :ARRAY OF CHAR
WindowTitle。
Repaint :RestoreProc
Window描画関数。
である。

PROCEDURE CloseGraphicWindow(u :Window);

 Windowを閉じる。
 引数uは、閉じる対象のWindowデータ変数。

PROCEDURE SetPen(u :Window; x,y :INTEGER);

 ペンの現在位置をWindow座標水平方向x、垂直方向yへ移動する。
 uはペンを移動する対象Window。

PROCEDURE TurnTo(u :Window; d :INTEGER);

 ペンの移動方向をd度に設定する。d=0で水平右方向、d=90で垂直上方向、反時計周りに度数で設定する。
 uはペンの移動方向を設定する対象Window。

PROCEDURE Move(u :Window; n :INTEGER);

 設定されている方向へ線を描画しつつn移動する。
 uは描画・移動対象Window。

PROCEDURE WriteString(u :Window; s :ARRAY OF CHAR);

 sは描画文字列。
 uは描画対象Window。

プログラム本体

 GraphicWindowsモジュールを紹介したところで、実際にDrawStarプログラム内で、どのようにこれを用いているのか、実際のソースを見ながら説明して行きましょう。
 まずは、星型を描画する関数DrawStarから。
PROCEDURE DrawStar(wndArg :Window);
 wndArgは描画対象Window。
VAR
	intLoop	:INTEGER;
	intDig	:INTEGER;
 intLoopは、星型を描画するために繰り返す処理に用いる変数。
 intDigは、描画する方向を保持する変数。
BEGIN
	SetPen(wndArg,10,50);
	TurnTo(wndArg,0);
	intDig := 0;
 関数の実際の処理。
 SetPenでペン位置を、TurnToでペンの初期方向を、intDig:=0で描画する方向に初期値を、設定する。
	FOR intLoop := 0 TO 4 DO
		TurnTo(wndArg,intDig);
		Move(wndArg,80);
		intDig := intDig + 216;
		IF intDig > 360 THEN
			intDig := intDig - 360
		END
	END
END DrawStar;
 星は五回線を描画することによって描かれる。その都度描画する方向をTurnTo関数で設定する。
 各描画時には、設定されている方向へ80の長さを持つ線を描画し、描画後、描画方向を反時計周りに216度移動させ、もし360度を越えた場合には360度分角度を引く。

 続いて、DrawStarプログラムのメイン処理。
BEGIN
	OpenGraphicWindow(wndStar,50,50,100,100,"DrawStar",DrawStar);
 Windowを作成する。
 描画関数としてはDrawStarを指定。(描画関数に指定するため、起動時に起こるUpdateEventにより星型が描画される。)
	tskMouse := PushTask(TrackMouse);
	REPEAT
		PollEventTasks
	UNTIL blnDone;
	PopTask(tskMouse);
 イベント処理。
  CloseGraphicWindow(wndStar)
END DrawStar.
 Windowを閉じる。

お試し

 さて、今回はGraphicWindowsモジュールを紹介してみました。実行するとこんな感じになります。

GraphicWindowsモジュールは、今ひとつパワーに欠ける感がしないでもありませんが、簡単なプログラムであればこれで十分書けることでしょう。
 今回はここまで。次回はEvent処理を紹介します。