gtk2hs - key event
キーイベントを拾った上でキーで操作できるようにした。コールバックの中でデータを変更する方法する作法がわからないMVarを使ったけどそれでいいの?命令的な書き方でいいのかどうか…。うーん、わからない。
module Main where
import Graphics.UI.Gtk
import Graphics.Rendering.Cairo
import Control.Monad.Trans(liftIO)
import Control.Concurrent.MVar
main = do
initGUI
mv <- newMVar (0,0)
window <- windowNew
widgetSetSizeRequest window 640 400
on window exposeEvent $ exposeHandler mv
on window keyPressEvent $ tryEvent $ onKeyboard window mv
on window deleteEvent (liftIO $ do
mainQuit
return True)
widgetShowAll window
mainGUI
exposeHandler mv = do
drawWin <- eventWindow
liftIO $ do
val <- readMVar mv
renderWithDrawable drawWin $ do
rectangle 50 50 100 100
fill
setSourceRGB 1 0 0
arc (200+(fst val)) (200+(snd val)) 30 0 (1 * pi)
fill
stroke
return True
onKeyboard window mv = do
keyName <- eventKeyName
[] <- eventModifier
liftIO $ case keyName of
"r" -> putStrLn "Key r pressed!"
"a" -> do
modifyMVar_ mv (\x -> return ((fst x)-1, snd x))
widgetQueueDraw window
"d" -> do
modifyMVar_ mv (\x -> return ((fst x)+1, snd x))
widgetQueueDraw window
"w" -> do
modifyMVar_ mv (\x -> return ((fst x), (snd x)-1))
widgetQueueDraw window
"s" -> do
modifyMVar_ mv (\x -> return ((fst x), (snd x)+1))
widgetQueueDraw window
_ -> putStrLn "Other key pressed!"
IOrefを使ったバージョン。今の自分のHaskellの知識ではこれが精一杯。
module Main where
import Graphics.UI.Gtk
import Graphics.Rendering.Cairo
import Control.Monad.Trans(liftIO)
import Data.IORef
main = do
initGUI
mv <- newIORef (0,0)
window <- windowNew
widgetSetSizeRequest window 640 400
on window exposeEvent $ exposeHandler mv
on window keyPressEvent $ tryEvent $ onKeyboard window mv
on window deleteEvent (liftIO $ do
mainQuit
return True)
widgetShowAll window
mainGUI
exposeHandler mv = do
drawWin <- eventWindow
liftIO $ do
val <- readIORef mv
renderWithDrawable drawWin $ do
rectangle 50 50 100 100
fill
setSourceRGB 1 0 0
arc (200+(fst val)) (200+(snd val)) 30 0 (1 * pi)
fill
stroke
return True
onKeyboard window mv = do
keyName <- eventKeyName
[] <- eventModifier
liftIO $ case keyName of
"r" -> putStrLn "Key r pressed!"
"a" -> do
modifyIORef mv (\x -> ((fst x)-1, snd x))
widgetQueueDraw window
"d" -> do
modifyIORef mv (\x -> ((fst x)+1, snd x))
widgetQueueDraw window
"w" -> do
modifyIORef mv (\x -> ((fst x), (snd x)-1))
widgetQueueDraw window
"s" -> do
modifyIORef mv (\x -> ((fst x), (snd x)+1))
widgetQueueDraw window
_ -> putStrLn "Other key pressed!"

Debian QA
Facebook (taniguchi.takaki)
Twitter (@takaki_t)