新しく発言する EXIT インデックスへ
哲さん、試作してみました

  哲さん、試作してみました 山中和義 2004/02/22 00:35:23 
  その1 山中和義 2004/02/22 00:36:33 
  その2 山中和義 2004/02/22 00:37:42 
  その3 山中和義 2004/02/22 00:38:17 
   ├面倒なのに良く作りましたね!2004/02/22 10:49:27 
   │└もっともこれは、自分が特定の目的のために...2004/02/22 16:38:22 
   └すごい。 青木太一 2004/02/22 19:50:38 
    └ありがとうございます。 山中和義 2004/02/22 21:52:34 

  哲さん、試作してみました 山中和義 2004/02/22 00:35:23  ツリーへ

哲さん、試作してみました 返事を書く
山中和義 2004/02/22 00:35:23
労力の割には、、、という感じです。

・説明
実はRPGのプログラムなんです。
アクティブセルを勇者、表示された表をビューポート、表全体をマップとすると
マップを徘徊する処理が利用できます。

いくつか低レベルのGUI、描画ルーチンがまとまってきました。

参考までに、、、

  その1 山中和義 2004/02/22 00:36:33  ツリーへ

Re: 哲さん、試作してみました 返事を書く
山中和義 2004/02/22 00:36:33
その1
!表形式による入力プログラム ver 0.1 十進BASIC by K. Yamanaka
SET WINDOW 0,640,0,480 !左下が原点。横がX、縦Y

!表の定義
dim cell_data$(1000,50) !セルの内容 ※最大値(1000行50桁分)

dim cell_width(30) !列幅
data 20,40,70,40,40,40,20,40,40,50, 20,30,30,40,70 !15桁 ※最大30まで

LET i = 1
LET ok = -1
do while ok<0 !定義されたボタンを表示する
READ IF MISSING THEN EXIT DO: cell_width(i)
LET i = i + 1
loop
LET MAX_COL = i-1 !最大桁数
LET MAX_ROW = 20 !最大行数 ※最大1000まで

LET NUM_COL = 10 !表示桁数、表示行数 ※左上
LET NUM_ROW = 8

LET cell_name$ = " A B C D E F G H I J K L M N O P Q R S T U V W X Y ZAAABACAD" !桁名

!--- 初期処理 ---
LET VW_X = 1 !表示する表の範囲(ビューポート)を設定する
LET VW_Y = 1
LET VW_SX = NUM_COL
LET VW_SY = NUM_ROW

LET CELL_X = 1 !アクティブセルを設定する
LET CELL_Y = 1


LET cell_data$(1,1)="成績表" !debug debug debug
LET cell_data$(2,4)="国語"
LET cell_data$(3,4)="15点"
LET cell_data$(10,8)="80点"


call DrawTABLE(1) !表を表示する ※(50,50)は図形としての左下位置
call DrawActiveCell(CELL_X,CELL_Y) !アクティブセルを表示する

LET ok = -1
do while ok<0
LET OLD_CELL_X = CELL_X
LET OLD_CELL_Y = CELL_Y

MOUSE POLL MX,MY,MLB,MRB
! print MX;MY,MLB;MRB
if MLB=1 then !マウスの左ボタンが押されたら
! LET bt = CheckCollision(MX,MY) !クリックしたセル位置を得る
! print bt !debug debug debug

else !キーボードの場合
call GetCellMOve(s$) !アクティブセルを移動する
print s$ !debug debug debug

if s$="ENTER" then !編集
input prompt "データを入力してください": cell_data$(CELL_Y,CELL_X)
end if
if s$="↑" then !スクロールアップ
if CELL_Y > 1 then
LET CELL_Y = CELL_Y - 1
end if
end if
if s$="↓" then !スクロールダウン
if CELL_Y < MAX_ROW then
LET CELL_Y = CELL_Y + 1
end if
end if
if s$="←" then !スクロールレフト
if CELL_X > 1 then
LET CELL_X = CELL_X - 1
end if
end if
if s$="→" then !スクロールライト
if CELL_X < MAX_COL then
LET CELL_X = CELL_X + 1
end if
end if
LET flg = 0
call SetViewPort(CELL_X,CELL_Y, s$, flg) !アクティブセルに追従させる

if flg=-1 then !スクロールされたら
clear
call DrawTABLE(1) !表を表示する
else
call DrawRestoreCell !アクティブセルをリカバリーする
end if
call DrawActiveCell(CELL_X,CELL_Y) !新しいアクティブセルを表示する

end if

wait delay 0.1 !ちょっとだけ待つ
loop

STOP

  その2 山中和義 2004/02/22 00:37:42  ツリーへ

Re: 哲さん、試作してみました 返事を書く
山中和義 2004/02/22 00:37:42
その2
SUB DrawRestoreCell
!アクティブセルの内容を再表示する
LET xx = 50
for i=VW_X to OLD_CELL_X-1
LET xx = xx + cell_width(i)
next i
LET yy = 150 + (NUM_ROW - (OLD_CELL_Y - VW_Y) - 1)*20
DRAW CELL(xx,yy, xx+cell_width(OLD_CELL_X),yy+20, 1,cell_data$(OLD_CELL_Y,OLD_CELL_X))
END SUB

SUB DrawActiveCell(x,y)
!アクティブセルの位置を算出すし、表示する
LET xx = 50
for i=VW_X to x-1
LET xx = xx + cell_width(i)
next i
LET yy = 150 + (NUM_ROW - (y - VW_Y) - 1)*20
DRAW BOXF(xx,yy, xx+cell_width(x),yy+20, 4)
END SUB

!表全体を表示する
SUB DrawTABLE(c)
LET x1 = 50
LET y1 = 150

LET j = 0 !表の大きさを算出する
for i=VW_X to VW_X+VW_SX-1
LET j = j + cell_width(i)
next i
LET x2 = x1 + j !幅
LET y2 = y1 + NUM_ROW*20 !高さ
DRAW BOXF(x1,y1, x2,y2, c) !内部を塗潰す

!行方向
SET LINE COLOR 6 !枠を表示する
for i=0 to NUM_ROW
PLOT LINES:x1,y1+i*20; x2,y1+i*20 !仕切り
next i

!桁方向
PLOT LINES:x1,y1; x1,y2 !左端
LET j = 0
for i=VW_X to VW_X+VW_SX-1 !右方向へ
LET j = j + cell_width(i)
PLOT LINES:x1+j,y1; x1+j,y2
next i

!データを表示する
for i=VW_Y to VW_Y+VW_SY-1
for j=VW_X to VW_X+VW_SX-1
LET xx = 50
for k=VW_X to j-1
LET xx = xx + cell_width(k)
next k
LET yy = 150 + (NUM_ROW - (i - VW_Y) - 1)*20
call DisplayTEXT(xx+5,yy+5,3,cell_data$(i,j))
next j
next i

!行番号
for i=1 to NUM_ROW
call DisplayDataFormat(x1-30,y2-i*20,1,str$(VW_Y+i-1),"###")
next i

!桁名
LET j = 0
for i=VW_X to VW_X+VW_SX-1
call DisplayTEXT(x1+j,y2,1,mid$(cell_name$,i*2,2))
LET j = j + cell_width(i)
next i
END SUB

!ビューポート位置を設定する
SUB SetViewPort(x,y, s$, flg)
LET flg = 0
if s$="↑" and VW_Y>y then !上方向で上端なら
LET VW_Y = VW_Y - 1
LET flg = -1
end if
if s$="↓" and VW_Y+VW_SY-1<y then !下方向で下端なら
LET VW_Y = VW_Y + 1
LET flg = -1
end if
if s$="←" and VW_X>x then !左方向で左端なら
LET VW_X = VW_X - 1
LET flg = -1
end if
if s$="→" and VW_X+VW_SX-1<x then !右方向で右端なら
LET VW_X = VW_X + 1
LET flg = -1
end if
END SUB

  その3 山中和義 2004/02/22 00:38:17  ツリーへ

Re: 哲さん、試作してみました 返事を書く
山中和義 2004/02/22 00:38:17
その3
!セルを描画する
PICTURE CELL(x1,y1, x2,y2, c, s$)
DRAW BOXF(x1,y1, x2,y2, c) !枠内を表示する
call DisplayTEXT(x1+5,y1+5,3,s$) !データを表示する
DRAW BOX(x1,y1, x2,y2, 6) !枠を表示する
END PICTURE

!当り判定(枠内にいるか?)- ボタンが押されたか確認する
FUNCTION CheckCollision(x,y)
LET CheckCollision = -99 !まずは外!
END FUNCTION

!枠を描画する
PICTURE BOX(x1,y1, x2,y2, c)
SET LINE COLOR c
PLOT LINES:x1,y1; x2,y1 !反時計まわりに
PLOT LINES:x2,y1; x2,y2
PLOT LINES:x2,y2; x1,y2
PLOT LINES:x1,y2; x1,y1
END PICTURE

!枠内を描画する(塗潰し)
PICTURE BOXF(x1,y1, x2,y2, c)
SET AREA COLOR c
PLOT AREA: x1,y1; x2,y1; x2,y2; x1,y2
END PICTURE

!指定位置に書式付きで文字を表示する
SUB DisplayDataFormat(x,y,c,s$,f$)
SET TEXT COLOR c
PLOT TEXT, AT x,y, USING f$: val(s$)
END SUB

!指定の位置に文字を表示する
SUB DisplayTEXT(x,y,c,s$)
SET TEXT COLOR c
PLOT TEXT, AT x,y: s$
END SUB

!セル移動、編集用のキーを得る
SUB GetCellMove(s$)
LET s$=""

if getkeystate(37)<0 then
LET s$ = "←"
end if
if getkeystate(38)<0 then
LET s$ = "↑"
end if
if getkeystate(39)<0 then
LET s$ = "→"
end if
if getkeystate(40)<0 then
LET s$ = "↓"
end if
if getkeystate(13)<0 then
LET s$ = "ENTER"
end if
if getkeystate(27)<0 then
LET s$ = "ESC"
end if
END SUB

END

   ├面倒なのに良く作りましたね!2004/02/22 10:49:27  ツリーへ

Re: その3 返事を書く
2004/02/22 10:49:27
面倒なのに良く作りましたね!
表計算の場合は再描画が必要になるのでどんな状態になるか疑問に思っていまして、
私もそのうちに暇を見て作りたいとは思っていましたがなかなかやる気が起きなかったのですが。
近いうちにセルの大きさも文字数によって変わるように、またプログラム終了時にグラフィックウィンドウを大きくして描画し、ファイル保存してそのままプリンタで印刷できるようにしようなどと考えているところです。
十進BASICの機能で十分良いものが出来るとは思いますが、処理速度がどの程度か心配です。

   │└もっともこれは、自分が特定の目的のために...2004/02/22 16:38:22  ツリーへ

Re: 面倒なのに良く作りましたね! 返事を書く
2004/02/22 16:38:22
もっともこれは、自分が特定の目的のために作るので公開するつもりはありません。

   └すごい。 青木太一 2004/02/22 19:50:38  ツリーへ

Re: その3 返事を書く
青木太一 2004/02/22 19:50:38
すごい。
哲さんと同じような感想ですが、作っちゃう人は作っちゃうのですね。
shinさんの秤にも感動しました。

ところで、アクティブセルが赤の塗り潰しだと、そこに書いてあったものが見えなくなってしまいますよね。
別に塗りつぶさずに枠を使えばいいだけの話だけど、
set draw mode notxorを使って反転表示っぽくしてみました。

この副プログラムを入れ替えるだけでうまく動くようです。
SUB DrawActiveCell(x,y)
!アクティブセルの位置を算出すし、表示する
LET xx = 50
for i=VW_X to x-1
LET xx = xx + cell_width(i)
next i
LET yy = 150 + (NUM_ROW - (y - VW_Y) - 1)*20
set draw mode notxor !---
DRAW BOXF(xx,yy, xx+cell_width(x),yy+20, 4)
set draw mode overwrite !---
END SUB

まあ山中さんには釈迦に説法のような提案ですが...

    └ありがとうございます。 山中和義 2004/02/22 21:52:34  ツリーへ

Re: すごい。 返事を書く
山中和義 2004/02/22 21:52:34
ありがとうございます。
まとまりのないプログラムですので、恥ずかしいですが、、、
いくつか改良したいと思っています。
GUI系のライブラリができればいいなと考えています。


インデックスへ EXIT
新規発言を反映させるにはブラウザの更新ボタンを押してください。