新しく発言する  EXIT  インデックスへ

マウスの操作5種類をまとめました


  マウスの操作5種類をまとめました 荒田浩二 2008/03/20 11:49:53 
  !<続き> 荒田浩二 2008/03/20 11:51:29 
   └!マウスのイベント・ドリブンによる処理※左... 山中和義 2008/03/22 10:48:03 
    └ダブルクリックの判別が悩むところです。 荒田浩二 2008/03/25 18:33:39 

  マウスの操作5種類をまとめました 荒田浩二 2008/03/20 11:49:53   ツリーへ
マウスの操作5種類をまとめました  返事を書く  ノートメニュー
荒田浩二 <knrztrhoel> 2008/03/20 11:49:53
十進BASICの独自の拡張機能であるMOUSE POLLを利用して、よく使う次の5種類の操作をモジュールにまとめました。
 ・長押し(press)
 ・右クリック(right click)
 ・Wクリック(w click)
 ・左クリック(single click)
 ・ドラッグ(drag)

MOUSE POLLの「マウスの操作を待たない」という特徴をできる限り引き継ぐようにしました。
マウス操作と他の命令を並行的に処理できます。
グラフィックス画面内で上の5種類の操作を試してみて下さい。

DECLARE EXTERNAL SUB mouse.operation ! マウス操作
SET TEXT BACKGROUND "OPAQUE"
DIM tail_p(2,200) ! しっぽの長さ;200
SET POINT STYLE 2 ! ドラッグの軌跡;+
SET POINT COLOR 4 ! ドラッグの軌跡;赤
LET n=6 ! 操作の回数
FOR i=1 TO n
PLOT TEXT ,AT 0.1,0.95 ,USING "あと ># 回操作":STR$(n+1-i)
DO
PLOT TEXT ,AT 0.4,0.95 ,USING "TIME = <####.##":STR$(TIME) !マウス操作と並行処理可
CALL mouse.operation(action,clickx,clicky,pointerx,pointery) !マウス操作
!CALL tail(clickx,clicky,tail_p,4,3) ! ポインタのしっぽ;o,緑
!IF action=0.1 AND (clickx<>pointerx OR clicky<>pointery) THEN PLOT POINTS : pointerx,pointery !ドラッグの軌跡
LOOP UNTIL action>=1
SELECT CASE action
CASE 1 ! 長押し
PLOT TEXT ,AT clickx,clicky :"press"
CASE 2 ! 右クリック
PLOT TEXT ,AT clickx,clicky :"right click"
CASE 3 ! Wクリック
PLOT TEXT ,AT clickx,clicky :"w click"
CASE 4 ! 左クリック
PLOT TEXT ,AT clickx,clicky :"single click"
CASE 5 ! ドラッグ
PLOT TEXT ,AT clickx,clicky :"drag"
PLOT LINES : clickx,clicky ; pointerx,pointery
! PLOT TEXT ,AT pointerx,pointery :"release"
END SELECT
NEXT i
PLOT TEXT ,AT 0.1,0.95 : "プログラム終了 !!"
SUB tail(x9,y9,t(,),ps,pc) ! ポインタのしっぽ
ASK POINT STYLE aps
ASK POINT COLOR apc
LET tn=SIZE(t,2)
SET POINT STYLE ps
SET POINT COLOR 0
PLOT POINTS : t(1,1),t(2,1)
IF x9<>t(1,tn) OR y9<>t(2,tn) THEN
SET POINT COLOR pc
PLOT POINTS : x9,y9
END IF
FOR j=1 TO tn-1
LET t(1,j)=t(1,j+1)
LET t(2,j)=t(2,j+1)
NEXT j
LET t(1,tn)=x9
LET t(2,tn)=y9
SET POINT STYLE aps
SET POINT COLOR apc
END SUB
END
!<続く>
  !<続き> 荒田浩二 2008/03/20 11:51:29   ツリーへ
Re: マウスの操作5種類をまとめました  返事を書く  ノートメニュー
荒田浩二 <knrztrhoel> 2008/03/20 11:51:29
!<続き>
REM ** マウス操作 **
MODULE mouse
PUBLIC SUB operation
SHARE NUMERIC p,w,s,check,t0,t1
LET p=0.9 ! 長押し時間(p秒以上押し続ける)
LET w=0.4 ! Wクリックの間隔(押してからw秒以内に2度目を押す)
LET s=0.3 ! ドラッグ無効時間(押してからs秒以内に放すと左クリック扱い)
EXTERNAL SUB operation(a,x0,y0,x,y)
MOUSE POLL x,y,l,r
SELECT CASE check
CASE 0 ! 操作開始のチェック
LET x0=x
LET y0=y
IF l=0 AND r=0 THEN ! ボタン解放の確認
LET a=0
ELSEIF a<>0 THEN
LET a=-1 ! 前回の操作を無効化
ELSE ! 操作の開始
LET t0=TIME
LET check=1
END IF
CASE 1 ! ボタンのチェック
LET t1=TIME
IF l=1 THEN
LET a=0.1 ! 左ボタンが押された状態
CALL press(a,x0,y0,x,y) ! 長押しの判定
ELSEIF r=1 THEN
LET a=0.2 ! 右ボタンが押された状態
LET check=3
! CALL complete(a,x0,y0,x,y) ! ボタンを押して右クリック完了
ELSE
LET a=0 ! 左ボタンが放された状態
LET check=2
! CALL complete(a,x0,y0,x,y) ! Wクリックを無効化
END IF
CASE 2 ! Wクリックの有無のチェック
IF l=1 THEN
LET a=0.3 ! 左ボタンが2度押された状態
LET check=3
! CALL complete(a,x0,y0,x,y) ! ボタンを押してWクリック完了
ELSEIF TIME-t0>w THEN
CALL complete(a,x0,y0,x,y)
END IF
CASE 3 ! ボタン解放のチェック
IF l=0 AND r=0 THEN CALL complete(a,x0,y0,x,y)
END SELECT
END SUB
EXTERNAL SUB complete(a,x0,y0,x,y) ! 操作の完了
LET check=0
IF a=0.2 THEN
LET a=2 ! 右クリック
ELSEIF a=0.3 THEN
LET a=3 ! Wクリック
ELSEIF t1-t0<=s OR (x=x0 AND y=y0 AND t1-t0<p) THEN
LET a=4 ! 左クリック
ELSEIF x<>x0 OR y<>y0 THEN
LET a=5 ! ドラッグ(移動先は x,y)
ELSE
LET a=1 ! 長押し(ボタンを放して完了,副プログラムpressを無効にした時)
END IF
END SUB
EXTERNAL SUB press(a,x0,y0,x,y) ! 長押しの判定
IF x=x0 AND y=y0 AND t1-t0>=p THEN
LET check=0 ! 操作の完了
LET a=1 ! 長押し(ボタンを押し続けて完了)
END IF
END SUB
END MODULE

   └!マウスのイベント・ドリブンによる処理※左... 山中和義 2008/03/22 10:48:03   ツリーへ
Re: !<続き>  返事を書く  ノートメニュー
山中和義 <drdlxujciw> 2008/03/22 10:48:03
!マウスのイベント・ドリブンによる処理 ※左ボタンのみ

!イベント・ハンドラ ※手短に処理すること

SUB mouseDown(x,y) !ボタンが押された
LET c=2
PRINT "left down"
END SUB
SUB mouseUp(x,y) !ボタンが離された
LET c=1
PRINT "left up"
END SUB
SUB mouseClick(x,y) !クリック
LET sc=0.1
PRINT "left click"
END SUB
SUB mouseDblClick(x,y) !ダブルクリック
LET sc=0.05
PRINT "left double click"
END SUB
SUB mouseDrag(x,y) !ドラグ(押したまま移動)
LET c=4
END SUB
SUB mouseMove(x,y) !移動
SET DRAW mode hidden !描画開始
CLEAR
SET AREA COLOR c
DRAW disk WITH SCALE(sc)*SHIFT(x,y) !図形を表示する
SET DRAW mode explicit !描画終了
END SUB



!main

LET c=1 !色
LET sc=0.05 !大きさ


!イベント・ループ

LET mevt=0 !マウスの状態
DO
mouse poll x,y,left,right !マウスの状態を得る

IF left=1 THEN !左ボタンが押下されたら
SELECT CASE mevt !状態遷移
CASE 0
LET x0=x !位置を記録する
LET y0=y
LET t0=TIME !時刻を記録する

LET mevt=1
CALL mouseDown(x,y)
CASE 1 !押下中
IF x0<>x OR y0<>y THEN !移動すれば
LET mevt=2
PRINT "left drag start" !debug
END IF
CASE 2 !ドラグ中
CALL mouseDrag(x,y)
CASE ELSE
END SELECT

ELSE !離されたら
IF mevt>0 THEN !以前が押下中なら
IF mevt=1 THEN !クリック系
IF TIME-t9<0.3 THEN !ダブルクリックなら ※0.3は調整要
CALL mouseDblClick(x,y)
LET t9=t0
ELSE
LET t9=TIME
IF t9-t0<0.3 THEN CALL mouseClick(x,y) !クリックなら ※0.3は調整要
END IF
ELSE
PRINT "left drag end" !debug
END IF

LET mevt=0
CALL mouseUp(x,y)
END IF

END IF

CALL mouseMove(x,y) !移動なら ※常時


LOOP


END
    └ダブルクリックの判別が悩むところです。 荒田浩二 2008/03/25 18:33:39   ツリーへ
Re: !マウスのイベント・ドリブンによる処理※左...  返事を書く  ノートメニュー
荒田浩二 <knrztrhoel> 2008/03/25 18:33:39
ダブルクリックの判別が悩むところです。

山中さんのプログラムではダブルクリックを操作すると、まずシングルクリックと認識されます。

私のプログラムではダブルクリック(a=3)とシングルクリック(a=4)は区別されますが、ボタンの2度目の押し下げを待つためシングルクリックの反応時間が遅いです。
w=0などとしてダブルクリックを無効にすればシングルクリックの反応も速くなるのですが……。

やはり、あれもこれもと詰め込むにはどこかを犠牲にしなければいけないのでしょうね。


ところでこのプログラムは、以前の山中さんのマウスに応じて目玉が動くプログラムに触発されて作ったものです。
MOUSE POLLの機能をもっと活かせるのではないかと考え作りました。
ご本人からレスをいただき感激です。


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