Added grid and some basic keyboard handling
Getty Ritter
8 years ago
1 | {-# LANGUAGE LambdaCase #-} | |
2 | ||
1 | 3 | module Main where |
2 | 4 | |
3 | 5 | import qualified Data.ByteString.Lazy as BS |
4 | 6 | import Data.IORef |
5 | 7 | import Graphics.UI.Gtk.Cairo |
6 | import Graphics.UI.Gtk hiding (eventButton) | |
7 | import Graphics.UI.Gtk.Gdk.Events(eventX,eventY,eventButton) | |
8 | import Graphics.UI.Gtk hiding (eventButton, eventKeyVal) | |
9 | import Graphics.UI.Gtk.Gdk.Events(Event(..),eventX,eventY,eventButton) | |
8 | 10 | import qualified Graphics.Rendering.Cairo as C |
9 | 11 | import qualified Image.VK as VK |
10 | 12 | |
42 | 44 | render d state = do |
43 | 45 | dw <- widgetGetDrawWindow d |
44 | 46 | (w, h) <- drawableGetSize dw |
47 | region <- regionRectangle (Rectangle 0 0 w h) | |
48 | drawWindowBeginPaintRegion dw region | |
45 | 49 | renderWithDrawable dw $ do |
46 | 50 | C.setSourceRGB 1.0 1.0 1.0 |
47 | 51 | C.rectangle 0 0 (fromIntegral w) (fromIntegral h) |
48 | 52 | C.fill |
53 | case apGrid state of | |
54 | Nothing -> return () | |
55 | Just (xW, yW) -> do | |
56 | C.setSourceRGB 0.8 0.8 0.8 | |
57 | C.setLineWidth 2 | |
58 | C.setLineCap C.LineCapRound | |
59 | sequence_ [ dot (fromIntegral (x * xW)) (fromIntegral (y * yW)) | |
60 | | x <- [0..(w `div` xW)] | |
61 | , y <- [0..(h `div` yW)] | |
62 | ] | |
49 | 63 | C.setSourceRGB 0.0 0.0 0.0 |
50 | 64 | mapM_ dLine (apLines state) |
51 | 65 | case apLines state of |
60 | 74 | Just (x, y) -> do |
61 | 75 | C.arc (fromIntegral x) (fromIntegral y) 5.0 0.0 (2 * pi) |
62 | 76 | C.stroke |
63 |
|
|
77 | drawWindowEndPaint dw | |
78 | ||
79 | dot :: Double -> Double -> C.Render () | |
80 | dot x y = do | |
81 | C.moveTo x y | |
82 | C.lineTo x y | |
83 | C.stroke | |
64 | 84 | |
65 | 85 | main :: IO () |
66 | 86 | main = do |
67 | 87 | _ <- initGUI |
68 | 88 | window <- windowNew |
89 | vbox <- vBoxNew False 10 | |
69 | 90 | da <- drawingAreaNew |
70 |
|
|
91 | minibuf <- labelNew (Just ":" :: Maybe String) | |
92 | stRef <- newIORef (ApplicationState [[]] Nothing (800, 800) (Just (10, 10))) | |
71 | 93 | set window [ windowDefaultWidth := 800 |
72 | 94 | , windowDefaultHeight := 800 |
73 |
, containerChild := |
|
95 | , containerChild := vbox | |
74 | 96 | , containerBorderWidth := 10 |
75 | 97 | ] |
98 | boxPackStart vbox da PackGrow 0 | |
99 | boxPackStart vbox minibuf PackRepel 0 | |
76 | 100 | _ <- onMotionNotify da True $ \ event -> do |
77 | 101 | st <- readIORef stRef |
78 | 102 | let (x, y) = (rnd (eventX event), rnd (eventY event)) |
94 | 118 | writeIORef stRef st' |
95 | 119 | render da st' |
96 | 120 | return True |
121 | _ <- onKeyPress window $ \ case | |
122 | Key { eventKeyChar = Just 'c' } -> do | |
123 | modifyIORef stRef (\ st -> st { apLines = [[]] }) | |
124 | readIORef stRef >>= render da | |
125 | return True | |
126 | Key { eventKeyChar = Just ':' } -> do | |
127 | labelSetText minibuf ("command" :: String) | |
128 | return True | |
129 | _ -> return True | |
97 | 130 | _ <- window `onDestroy` (saveFile stRef >> mainQuit) |
98 | 131 | widgetShowAll window |
99 | 132 | mainGUI |