研究開発

ブロックを積む(9)

第9章 ダイアログによる数値入力

スクリプト実行中にユーザとインタラクティブなやり取りをするためにダイアログというユーザインタフェースがあります。

例えば、スクリプトの終了を知らせるために、

手続きAlrtDialog(message : STRING);

を使うことで、ユーザに注意を促せます。

PROCEDURE sample;
VAR
ii, jj : INTEGER;

BEGIN
FOR jj := 0 TO 4 DO
BEGIN
FOR ii := jj TO 8 DO
BEGIN
BeginXtrd( jj*30, 30+jj*30 );
Rect( ii*50, 0, 50+ii*50, 30 );
IF ( jj MOD 2 = 0 ) AND ( ii MOD 2 <> 0 ) THEN
BEGIN
SetFillBack( LNewObj, 39321, 26214, 13107 );
END
ELSE IF ( jj MOD 2 <> 0 ) AND ( ii MOD 2 = 0 ) THEN
BEGIN
SetFillBack( LNewObj, 39321, 26214, 13107 );
END;
EndXtrd;
END;
END;

AlrtDialog( '計算が終了しました。' );
END;
Run( sample );

ほかにも、ユーザに質問を投げかける、

関数YNDialog(s : STRING):BOOLEAN;

を使ってユーザの選択によりスクリプトの流れを操作することができます。
最初のIF文で「スクリプトを実行しますか?」という質問に対しての回答が「いいえ」の場合、GOTO文でスクリプトの最後(9999:)まで飛びます。このGOTO文の飛び先をラベルといって、スクリプトの最初の部分で宣言します。

LABEL
xxxx;{1~9999}

PROCEDURE sample;
LABEL
9999;
VAR
ii, jj : INTEGER;

BEGIN
IF NOT YNDialog( 'スクリプトを実行しますか?' ) THEN
BEGIN
GOTO 9999;
END;

FOR jj := 0 TO 4 DO
BEGIN
FOR ii := jj TO 8 DO
BEGIN
BeginXtrd( jj*30, 30+jj*30 );
Rect( ii*50, 0, 50+ii*50, 30 );
IF ( jj MOD 2 = 0 ) AND ( ii MOD 2 <> 0 ) THEN
BEGIN
SetFillBack( LNewObj, 39321, 26214, 13107 );
END
ELSE IF ( jj MOD 2 <> 0 ) AND ( ii MOD 2 = 0 ) THEN
BEGIN
SetFillBack( LNewObj, 39321, 26214, 13107 );
END;
EndXtrd;
END;
END;

AlrtDialog( '計算が終了しました。' );
9999:
END;
Run( sample );

つぎに、数値を入力させることによって、図形に変化を持たせてみましょう。
整数を扱うには、

関数IntDialog(request, default : STRING):INTEGER;
を使います。

ブロックの数を横方向と縦方向それぞれいくつづつにするかを問います。それぞれのIntDialogの次のIF文で、

関数DidCancel:BOOLEAN;

を使っています。これは直前のダイアログでキャンセルボタンが押されたかどうかを判断する関数です。
それと同時に、それぞれの個数が0のときもスクリプトは実行されないようにIF文で処理されます。

PROCEDURE sample;
LABEL
9999;
VAR
iX, iY : INTEGER;
ii, jj : INTEGER;

BEGIN
IF NOT YNDialog( 'スクリプトを実行しますか?' ) THEN
BEGIN
GOTO 9999;
END;

iX := IntDialog( '横方向のブロック数?', '9' );
IF DidCancel OR ( ix = 0 ) THEN
BEGIN
GOTO 9999;
END;

iY := IntDialog( '縦方向のブロック数?', '5' );
IF DidCancel OR ( iy = 0 ) THEN
BEGIN
GOTO 9999;
END;

FOR jj := 0 TO iy-1 DO
BEGIN
FOR ii := jj TO iX-1 DO
BEGIN
BeginXtrd( jj*30, 30+jj*30 );
Rect( ii*50, 0, 50+ii*50, 30 );
IF ( jj MOD 2 = 0 ) AND ( ii MOD 2 <> 0 ) THEN
BEGIN
SetFillBack( LNewObj, 39321, 26214, 13107 );
END
ELSE IF ( jj MOD 2 <> 0 ) AND ( ii MOD 2 = 0 ) THEN
BEGIN
SetFillBack( LNewObj, 39321, 26214, 13107 );
END;
EndXtrd;
END;
END;

AlrtDialog( '計算が終了しました。' );
9999:
END;
Run( sample );

さらに、ブロックの大きさも変更可能にしてみましょう。
実数を扱うには、

関数RealDialog(request, default : STRING):REAL;

を使います。

PROCEDURE sample;
LABEL
9999;
VAR
iX, iY : INTEGER;
rX, rY, rZ : REAL;
ii, jj : INTEGER;

BEGIN
IF NOT YNDialog( 'スクリプトを実行しますか?' ) THEN
BEGIN
GOTO 9999;
END;

iX := IntDialog( '横方向のブロック数?', '9' );
IF DidCancel OR ( ix = 0 ) THEN
BEGIN
GOTO 9999;
END;

iY := IntDialog( '縦方向のブロック数?', '5' );
IF DidCancel OR ( iy = 0 ) THEN
BEGIN
GOTO 9999;
END;

rX := RealDialog( 'ブロックのx方向の長さは?', '50' );
IF DidCancel OR ( rX = 0 ) THEN
BEGIN
GOTO 9999;
END;

rY := RealDialog( 'ブロックのy方向の長さは?', '30' );
IF DidCancel OR ( rY = 0 ) THEN
BEGIN
GOTO 9999;
END;

rZ := RealDialog( 'ブロックのz方向の長さは?', '30' );
IF DidCancel OR ( rZ = 0 ) THEN
BEGIN
GOTO 9999;
END;

FOR jj := 0 TO iy-1 DO
BEGIN
FOR ii := jj TO iX-1 DO
BEGIN
BeginXtrd( 0+jj*rZ, rZ+jj*rZ );
Rect( ii*rX, 0, rX+ii*rX, rY );
IF ( jj MOD 2 = 0 ) AND ( ii MOD 2 <> 0 ) THEN
BEGIN
SetFillBack( LNewObj, 39321, 26214, 13107 );
END
ELSE IF ( jj MOD 2 <> 0 ) AND ( ii MOD 2 = 0 ) THEN
BEGIN
SetFillBack( LNewObj, 39321, 26214, 13107 );
END;
EndXtrd;
END;
END;

AlrtDialog( '計算が終了しました。' );
9999:
END;
Run( sample );