# 01 demo.hsp

sample\ 01 demo.hsp

    ; ちょっとリッチなアニメーション付きボタンを比較的簡単に作成できます。

    #include "hsp3dish.as"

    #include "mod_layerbutton.hsp"
    #include "d3m.hsp"  ; FPS計測用

    #packopt xsize 480
    #packopt ysize 800

    	screen 0,480,800
    	title "layerbutton demo"
    	log = ""
    	// HSP3Dish.js用フォルダ設定
    	info_os = sysinfo(0)
    	if instr(info_os,0,"Emscripten")>=0 : mm_dir="" : else : mm_dir="data/"

    	// 画像読み込み
    	celload mm_dir+"03_01-btn.png", -1
    	cel_btn = stat
    	celdiv cel_btn,172,66
    	celload mm_dir+"icon.png", -1
    	cel_ico = stat
    	celdiv cel_ico,32,32, 16,16

    	// オブジェクト作成
    	gosub *create_button_hidari
    	gosub *create_button_migi
    	gosub *create_button_shita

    	// 表示ループ
    	repeat
    		redraw 0 :color 240,240,240 : boxf : color : pos 0,0 : font msgothic,14
    		mes "fps = " + d3getfps()
    		mes log
    		if laybtn_length(0) == 0 && laybtn_length(1) == 0 {
    			pos 50,650 : mes "グループが1つの場合、移動キーでフォーカスが発生します。\n(オプションで発生させないことも可能)"
    		}
    		redraw 1
    		await 16
    	loop
    	stop

    // 左側ボタン作成
    *create_button_hidari
    	if laybtn_length(0) > 0 : return  ; グループID 0 がすでに存在する場合はreturn
    	pos 30,20
    	repeat 4
    		pos ,ginfo_cy+40  ; ボタンの位置を調整
    		tien = cnt * 10  ; IDごとに表示遅延をつける(SHOW_IN:10フレーム、SHOW_OUT:5フレーム)
    		// ボタン作成 : グループID 0
    		layerbutton 172,66, cnt, 0, 30+tien,20,10, 15+tien/2,10,0 {
    			if lparam == objlayer_cmddraw {
    				mes_zurasi = 0,-5  ; テキスト表示の基準位置
    				tien = objlayer_option * 10  ; optionに代入したボタンIDに合わせて遅延時間を計算
    				// ボタンの状態に応じて描画を振り分ける
    				switch layerbtn_stat
    				case LAYBTN_SHOW_IN // 表示開始
    					pos objlayer_axis_x-laybtn_ease(200, 0, tien), objlayer_axis_y  ; 左からスライドイン(ボタンIDごとの遅延時間を考慮)
    					gmode 3,,,255 : celput cel_btn, 0  ; ボタン描画
    					mes_zurasi = -laybtn_ease(200, 0, tien),-5  ; スライドインに合わせてテキスト位置もスライド
    					swbreak
    				case LAYBTN_FOCUS_IN // フォーカス表示
    					pos objlayer_axis_x, objlayer_axis_y
    					gmode 3,,,256 : celput cel_btn, 0  ; ボタン描画 : 通常状態
    					pos objlayer_axis_x, objlayer_axis_y
    					gmode 3,,,laybtn_ease(0,256) : celput cel_btn, 1  ; ボタン描画 : フォーカス状態(透明度をイージングで徐々に変化)
    					swbreak
    				case LAYBTN_FOCUS_OUT // フォーカス解除
    					pos objlayer_axis_x, objlayer_axis_y
    					gmode 3,,,256 : celput cel_btn, 0  ; ボタン描画 : 通常状態
    					pos objlayer_axis_x, objlayer_axis_y
    					gmode 3,,,laybtn_ease(256,0) : celput cel_btn, 1  ; ボタン描画 : フォーカス状態(透明度をイージングで徐々に変化)
    					swbreak
    				case LAYBTN_PRESS_IN // 押し込み表示
    					pos objlayer_axis_x, objlayer_axis_y
    					gmode 3,,,256 : celput cel_btn, 2  ; ボタン描画 : 押し込み状態(アニメーションなしで瞬時に表示にした)
    					mes_zurasi = 0,-1  ; ボタン押し込みに合わせてテキスト位置を下げる(-5 → -1)
    					swbreak
    				case LAYBTN_SHOW_OUT // 非表示処理
    				case LAYBTN_SHOW_OUT_SELECTED
    					if layerbtn_stat == LAYBTN_SHOW_OUT_SELECTED && layerbtn_cnt == 0 {
    						// ボタンが選択された瞬間！！
    						log += "hidari - SELECTED! opt="+objlayer_option+" wparam="+wparam +"\n"
    					}
    					pos objlayer_axis_x-laybtn_ease(0, 200, tien/2), objlayer_axis_y  ; 左へスライドアウト(ボタンIDごとの遅延時間を考慮)
    					if layerbtn_stat & LAYBTN_SELECTED {  ; 選択されたボタンのスライドアウト表示
    						gmode 3,,,256 : celput cel_btn, 2  ; ボタン描画 : 押し込み状態
    						mes_zurasi = -laybtn_ease(0, 200, tien/2),-1  ; スライドインに合わせてテキスト位置もスライド + 押し込みテキスト位置
    					} else {                              ; 選択されていないボタンのスライドアウト表示
    						gmode 3,,,256 : celput cel_btn, 0  ; ボタン描画 : 通常状態
    						mes_zurasi = -laybtn_ease(0, 200, tien/2),-5  ; スライドインに合わせてテキスト位置もスライド
    					}
    					swbreak
    				case LAYBTN_COMPLETE
    				case LAYBTN_COMPLETE_SELECTED
    					if layerbtn_stat & LAYBTN_SELECTED {
    						// グループ内のすべてのボタンの非表示処理が完了したとき (選択されたボタンはLAYBTN_COMPLETE_SELECTEDで通知される)
    						log += "hidari - COMPLETE! opt="+objlayer_option+" wparam="+wparam +"\n"
    					}
    					return
    					swbreak
    				swend
    				color 0,0,0 : objcolor 255,255,255 : font msgothic, 18, 1  ; laybtn_ezboxのテキスト設定
    				laybtn_mes "ボタン0"+(objlayer_option+1),4, 1,1, mes_zurasi(0),mes_zurasi(1)  ; テキスト描画

    				// ボタンの無効表示
    				laybtn_enable 0, -1
    				if stat == 0  {
    					if objlayer_option == 3 {
    						gmode 3,,,100 : color
    						laybtn_boxfb objgroup_axis_x-5, objgroup_axis_y-10, objgroup_axis_x2+5, objgroup_axis_y2+10
    						color 0,0,0 : font msgothic, 14 : laybtn_mes "無効 : 適当に黒半透明を被せてます\n(好みの表示にして下さい)",0, 1,2, 10,52
    					}
    				}
    			}
    			return
    		}
    	loop
    	return

    // 右側ボタン作成
    *create_button_migi
    	if laybtn_length(1) >= 3 : return  ; グループID 1 がすでに存在する場合はreturn
    	repeat 4
    		switch cnt
    		case 0 : pos 220, 150 : swbreak
    		case 1 : pos 350, 150 : swbreak
    		case 2 : pos 220, 260 : swbreak
    		case 3 : pos 350, 260 : swbreak
    		swend
    		// ボタン作成 : グループID 1
    		layerbutton 120,100, cnt, 1, 30,20,5, 15,20,2 {
    			laybtn_settings 0,0,16  ; 設定変更 :  FOCUS_IN の表示が完了する前にフォーカスが外れたとき FOCUS_OUT を即座に開始させる。
    			if lparam == objlayer_cmddraw {
    				// ボタンの描画
    				color 255,255,255 : objcolor 0,0,0 : font msgothic, 18, 1  ; laybtn_ezboxのテキスト設定
    				laybtn_ezbox $AA9999FF, $AA0000FF, $AA3333AA, "ボックス0"+(objlayer_option+1)
    				laybtn_ezfrm $99FFFFFF, $99FFFFFF, $99FFFFFF, 2,,,,,,,,,,-3,-3
    				// ボタンのクリック判定
    				switch layerbtn_stat
    				case LAYBTN_SHOW_OUT_SELECTED
    					if layerbtn_cnt == 0 : log += "migi - SELECTED! opt="+objlayer_option+" wp="+wparam +"\n"
    					swbreak
    				case LAYBTN_COMPLETE_SELECTED
    					log += "migi - COMPLETE! opt="+objlayer_option+" wp="+wparam +"\n"
    					swbreak
    				swend

    				// ボタンの無効表示
    				laybtn_enable 1, -1
    				if stat == 0  {
    					if objlayer_option == 3 {
    						gmode 3,,,100 : color
    						laybtn_boxfb objgroup_axis_x-5, objgroup_axis_y-5, objgroup_axis_x2+5, objgroup_axis_y2+5  ; グループ全体を覆うように黒半透明を被せる
    						color 0,0,0 : font msgothic, 14 : laybtn_mes "無効 : 適当に黒半透明を被せてます\n(好みの表示にして下さい)",0, 2,2, -10,40
    					}
    				}
    			}
    			return
    		}
    	loop
    	return

    // 下側ボタン作成
    *create_button_shita
    	repeat 7
    		pos 65+50*cnt, 500
    		// ボタン作成 : グループID 2
    		layerbutton 50,50, cnt, 2, 0,15,20, 0,0,0 {
    			laybtn_settings 0,2,1+2+8  ; 設定変更 : 押しても消えない＋PRESSアニメ待ち＋マウスクリック即ボタン決定
    			if lparam == objlayer_cmddraw {
    				// ボタンの描画
    				color 255,255,255 : boxf objlayer_axis_x, objlayer_axis_y, objlayer_axis_x2, objlayer_axis_y2  ; ボタン下地描画
    				pos objlayer_axis_x+25, objlayer_axis_y+25  ; アイコンの基準位置をpos
    				switch layerbtn_stat
    				case LAYBTN_FOCUS_IN // フォーカスと押し込み両方で虹色カーソル描画をするのでまとめる
    				case LAYBTN_PRESS_IN
    				case LAYBTN_PRESS_IN_SELECTED
    					// グラデーション四角カーソルの描画
    					if layerbtn_stat & LAYBTN_FOCUS_IN  : fade = 0,255   ; フェードイン
    					if layerbtn_stat & LAYBTN_PRESS_IN  : fade = 255,255 ; ボタンクリック
    					grdc++  ; グラデーションカラーをくるくるさせるためにカウント(HSV形式 H値:0~191)
    					hsvcolor (grdc \ 192), laybtn_ease(fade.0, fade.1), 255  ; グラデーションパラメータ
    					x(0)=objlayer_axis_x +2 : y(0)=objlayer_axis_y +2 : col(0)=ginfo_r<<16|ginfo_g<<8|ginfo_b
    					hsvcolor (grdc+48 \ 192), laybtn_ease(fade.0, fade.1), 255
    					x(1)=objlayer_axis_x2-2 : y(1)=objlayer_axis_y +2 : col(1)=ginfo_r<<16|ginfo_g<<8|ginfo_b
    					hsvcolor (grdc+96 \ 192), laybtn_ease(fade.0, fade.1), 255
    					x(2)=objlayer_axis_x2-2 : y(2)=objlayer_axis_y2-2 : col(2)=ginfo_r<<16|ginfo_g<<8|ginfo_b
    					hsvcolor (grdc+144 \ 192), laybtn_ease(fade.0, fade.1), 255
    					x(3)=objlayer_axis_x +2 : y(3)=objlayer_axis_y2-2 : col(3)=ginfo_r<<16|ginfo_g<<8|ginfo_b
    					gmode 0,,,256 : gsquare -257, x,y,col  ; カーソル描画
    					color 255,255,255 : boxf objlayer_axis_x+4, objlayer_axis_y+4, objlayer_axis_x2-5, objlayer_axis_y2-5  ; 中抜きして枠にする
    					// アイコンが跳ねたような描画位置になるよう調整 (一度_PRESS_INに入ったら_IN→_OUTが終わるまでカウントされる)
    					if layerbtn_stat & LAYBTN_PRESS_IN {
    						if layerbtn_cnt <= 5 {
    							pos objlayer_axis_x+25, objlayer_axis_y+25-laybtn_ease(0, 13)  ; 5フレーム上にあげる
    						}else {
    							pos objlayer_axis_x+25, objlayer_axis_y+25-laybtn_ease(13, 0, 5, ease_bounce_out)  ; 残りのフレームをバウンド落下
    						}
    					}
    					swbreak
    				swend
    				// アイコン描画
    				gmode 3,,,256 : celput cel_ico, objlayer_option
    				// テキスト描画
    				if (layerbtn_stat & LAYBTN_FOCUS_IN)!=0 || (layerbtn_stat & LAYBTN_PRESS_IN)!=0 {
    					color 0,0,200 : font msgothic, 14  ; laybtn_ezboxのテキスト設定
    					switch objlayer_option
    					case 0 : laybtn_mes "左ボタン表示/非表示",0, 1,1, 0,40 : swbreak
    					case 2 : laybtn_mes "左ボタン有効/無効",0, 1,1, 0,40 : swbreak
    					case 3 : laybtn_mes "右ボタン表示/非表示",0, 1,1, 0,40 : swbreak
    					case 5 : laybtn_mes "右ボタン有効/無効",0, 1,1, 0,40 : swbreak
    					case 6 : laybtn_mes "終了",0, 1,1, 0,40 : swbreak
    					default :
    						laybtn_mes "1つ目のボタンにフォーカス",0, 1,1, 0,40
    						laybtn_mes "(キー入力でもフォーカス移動と決定が可能)",0, 1,1, 0,54
    						swbreak
    					swend
    				}

    				// ボタンのクリック判定 (設定:マウスクリック即ボタン決定)
    				if layerbtn_stat == LAYBTN_PRESS_IN_SELECTED {
    					log += "shita - SELECTED! opt="+objlayer_option+" wparam="+wparam +"\n"
    					switch objlayer_option
    					case 0 : if laybtn_length(0) != 0 { laybtn_hide 0 }else{ gosub *create_button_hidari } : swbreak
    					case 1 : laybtn_focus 0, 0 : swbreak
    					case 2 : laybtn_enable 0, -1 : laybtn_enable 0, 1 - stat : swbreak
    					case 3 : if laybtn_length(1) != 0 { laybtn_hide 1 }else{ gosub *create_button_migi } : swbreak
    					case 4 : laybtn_focus 1, 0 : swbreak
    					case 5 : laybtn_enable 1, -1 : laybtn_enable 1, 1 - stat : swbreak
    					case 6 : flg_end = 1 : swbreak
    					swend
    				}
    				if flg_end == 1 && layerbtn_stat == LAYBTN_PRESS_IN && layerbtn_cnt == 19 : dialog "終了します" : end
    			}
    			return
    		}
    	loop
    	return