(77) ボタンを押してみた 2
本エントリは (75) ボタンを押してみた の続きです。
ボタンを押すと光って離すと消える、という動作ができたところで。
次は、一度押したら光ってもう一度押したら消える、というように動作を変えてみます。
一度押したら光って、もう一度押すまで光りっぱなしになるわけですから、複数のボタンが光っている状態があり得ます。
ということは、どのボタンが光っている状態でどのボタンが光っていない状態なのかを記録しておく必要があるということになります。
この「光っているかどうか」の状態を、light[x][y] という 2 次元の配列に持たせることにします。各変数の中身は、"on" が光っている状態、"off" が光っていない状態とします。
まず、各ボタンの描画と同時に、初期値 "off" を 配列 light に格納していきます。
'初期画像を背景に描画
GraphicsWindow.BackgroundColor=GraphicsWindow.GetColorFromRGB(192,192,192)
GraphicsWindow.Clear()
For x=0 To 2
btnLeft=margin["left"]+(button["size"]["normal"]+margin["grid"])*x
For y=0 To 2
btnTop=margin["top"]+(button["size"]["normal"]+margin["grid"])*y
GraphicsWindow.DrawImage(button["off"],btnLeft,btnTop)
light[x][y] = "off"
EndFor
EndFor
配列 light に与える添字 x と y は、ボタン描画の左上座標を算出する時にいっしょに算出します。
ついでに、ボタン領域外をクリックされた時に -1 を返す変数を、座標用の btnLeft ・ btnTop ではなく、x ・ y に変更します。
'マウスクリックの x 座標から、ボタンのインデックスと描画座標を算出
x=-1
If GraphicsWindow.MouseX>=margin["left"] And GraphicsWindow.MouseX<button["size"]["normal"] Then
x=0
btnLeft=margin["left"]
ElseIf GraphicsWindow.MouseX>=margin["left"]+mgn And GraphicsWindow.MouseX<mgn+button["size"]["normal"] Then
x=1
btnLeft=margin["left"]+mgn
ElseIf GraphicsWindow.MouseX>=margin["left"]+mgn*2 And GraphicsWindow.MouseX<mgn*2+button["size"]["normal"] Then
x=2
btnLeft=margin["left"]+mgn*2
EndIf
'マウスクリックの y 座標から、ボタンのインデックスと描画座標を算出
y=-1
If GraphicsWindow.MouseY>=margin["top"] And GraphicsWindow.MouseY<button["size"]["normal"] Then
y=0
btnTop=margin["top"]
ElseIf GraphicsWindow.MouseY>=margin["top"]+mgn And GraphicsWindow.MouseY<mgn+button["size"]["normal"] Then
y=1
btnTop=margin["top"]+mgn
ElseIf GraphicsWindow.MouseY>=margin["top"]+mgn*2 And GraphicsWindow.MouseY<mgn*2+button["size"]["normal"] Then
y=2
btnTop=margin["top"]+mgn*2
EndIf
これを受けて、MouseUpEvent イベント用サブルーチンを
- ボタン領域外かどうかの判断をしている If 文の参照変数を btnLeft ・ btnTop → x ・ y に変更。
- light[x][y] の保持内容に応じて「On」画像・「Off」画像のどちらを描画するかを振り分け。
というように記述を変更・追加します。
'マウスボタンを離された時の処理
Sub MouseUpEvent
'「On」画像と「Off」画像を切り替える
If x<>-1 and y<>-1 Then
If light[x][y]="off" Then
GraphicsWindow.DrawImage(button["on"],btnLeft,btnTop)
Else
GraphicsWindow.DrawImage(button["off"],btnLeft,btnTop)
EndIf
EndIf
EndSub
この操作方法だと、マウスクリックに対する動作は、MouseDown と MouseUp のどちらか一方で充分です。というわけで、今回は MouseUp で再描画することにします。
ただしマウスボタンを押し込んだ瞬間の座標が基準なのは変えたくないので、MouseDown イベント用サブルーチンでは GetButtonLocation サブルーチンの呼び出し機能だけを残し、GraphicsWindow.DrawImage とそれを振り分ける If 文はコメントアウトします。
'マウスボタンを押された時の処理
Sub MouseDownEvent
'クリック座標から、ボタンのインデックスと描画位置を算出
GetButtonLocation()
'算出結果がボタン上であれば、「On」画像を表示
' If btnLeft<>-1 And btnTop<>-1 Then
' GraphicsWindow.DrawImage(button["on"],btnLeft,btnTop)
' EndIf
EndSub
以上で修正は完了です。
修正したソース全体を見たい場合は、下記画像下のリンクから smallbasic.com の Web ページへジャンプしてください。
( XDG488 )
せっかくですから、押した瞬間に押したことがわかるような工夫もしてみます。
押した瞬間に、周囲にはみ出してぼやっと光らせることなんかできたらいいなーとか思います。
ので、こんな画像を用意してみました。

この画像は、ある程度透明な白色で周囲を囲ってあります。
で、まずはこの画像を読み込みます。
'画像の取り込み
button["off"]=ImageList.LoadImage("http://bit.ly/dygOB7")
button["on"]=ImageList.LoadImage("http://bit.ly/beStHm")
button["mdown"]=ImageList.LoadImage("http://bit.ly/c8epcx")
button["mdown"] に読み込んだ画像を AddImage でウィンドウ上に配置し、Shapes.HideShape で隠しておきます。
'マウスダウン時の画像を表示し、隠しておく
imgMDown=Shapes.AddImage(button["mdown"])
Shapes.HideShape(imgMDown)
あとは、MouseDownEvent イベント用サブルーチンで位置を合わせて表示、MouseUpEvent イベント用サブルーチンで再度隠す、という処理を追加します。
この画像は周囲まで光る分、ボタン画像より大きめにできています。ので、ボタン画像と同じ左上座標に表示させると大きい分右下にずれます。
ですから、ボタン画像とぴったり重なるずらしドット数を、初期処理で設定しておきます。
'座標パラメータの設定
button["size"]["normal"]=41
button["size"]["shine"]=63
margin["grid"]=3 'ボタン間のマージン
margin["left"]=95 'パネル左上の横位置
margin["top"]=30 'パネル左上の縦位置
margin["mdown"]=-10 'マウスダウン時画像のズレ
'マウスボタンを押された時の処理 Sub MouseDownEvent 'クリック座標から、ボタンのインデックスと描画位置を算出 GetButtonLocation() '算出結果がボタン上であれば、マウスダウン時画像を表示 If x<>-1 And y<>-1 Then Shapes.Move(imgMDown,btnLeft+margin["mdown"],btnTop+margin["mdown"]) Shapes.ShowShape(imgMDown) EndIf EndSub 'マウスボタンを離された時の処理 Sub MouseUpEvent 'マウスダウン時画像を隠す Shapes.HideShape(imgMDown) '「On」画像と「Off」画像を切り替える If x<>-1 and y<>-1 Then If light[x][y]="off" Then light[x][y]="on" Else light[x][y]="off" EndIf GraphicsWindow.DrawImage(button[light[x][y]],btnLeft,btnTop) EndIf EndSub
これで、「押した瞬間だけ白く光る」ギミックの完成です。
( ZBR010 )
