Simple Scheme で電卓をつくってみる(3)
Simple Schemeで電卓を作っています。前回までで、ボタンを押したら反応するようになりました。
今度はボタンごとに異なる反応を返すようにしてみましょう。
押したボタンの上に、ボタンの文字と同じ色の円盤を重ね、その上に白抜きでボタンの文字を拡大表示します。
そのためには、どのボタンが押されたかを、タップされた位置の座標から求めなければなりません。
ボタンの文字については、文字のリストがすでにあるので、画面上の座標をキーボード上の座標に変換して、さらに添字に変換すれば求められます。
(define button-labels '("%" "7" "8" "9" "÷" "MR" "√" "4" "5" "6" "×" "M-" "C" "1" "2" "3" "-" "M+" "AC" "0" "." "=" "+")) (list-ref button-labels (+ (iconv-x x) (* 6 (iconv-y y))) ;(x,y)の位置にあるボタンのラベルをこれで取得できる
文字以外の情報(サイズと色)を含めたレコード型を定義してそのリストを作りましょう。
(define-struct button (label size color)) (define buttons (letrec ((find (lambda (lis b) (let ((bc (car lis))) (if (ormap (lambda (l) (string=? b l)) (button-category-labels bc)) (make-button b (button-category-size bc) (button-category-color bc)) (find (cdr lis) b)))))) (map (lambda (l) (find button-categories l)) button-labels)))
これでタップされた位置のボタンの、文字以外の情報も取得できるようになりました。
(big-bang keyboard (on-draw (lambda (b) b)) (on-mouse (lambda (_ x y what) (if (string=? what "button-down") (let ((x (iconv-x x)) (y (iconv-y y))) (let ((i (+ x (* 6 y)))) (if (and (<= 0 x) (< x 6) (<= 0 i) (< i 23)) (let ((b (list-ref buttons i)) (x (conv-x x)) (y (conv-y y))) (place-image (text (button-label b) (/ (* 4 (button-size b)) 3) "white") x y (place-image (circle 100 "solid" (button-color b)) x y keyboard))) keyboard))) keyboard))))
— brv00 (@brv00) 2019年10月29日
続きます。