-- Draws nested squares. Solution to SA-3, with input added. -- Demonstrates how to read and use numbers. -- by Scot Drysdale on 10/1/07, modified 2/9/09 module Main where import Graphics.SOE.Gtk type Radius = Int -- Creates a colored square centered at (x,y) with "radius" r -- (where radius is half the side length) makeSquare :: Color -> Point -> Radius -> Graphic makeSquare clr (x, y) r = withColor clr (polyline [(x-r, y-r), (x+r, y-r), (x+r, y+r), (x-r, y+r), (x-r, y-r)]) squareDraw = runGraphics ( do w <- openWindow "One Square" (300, 300) drawInWindow w (makeSquare Blue (100,100) 50) spaceClose w) -- Creates a group of nested squares, all centered at ctr, with -- smallest radius sm, largest radius lg, step size step, and color clr. makeNestedSquares :: Point -> Radius -> Radius -> Int -> Color -> [Graphic] makeNestedSquares ctr sm lg step clr = map makeSq [sm, (sm+step) .. lg] where makeSq r = (makeSquare clr ctr r) -- Creates a list of draw commands from a list of Graphics graphicsToIO :: Window -> [Graphic] -> [IO ()] graphicsToIO w list = map drawGraphic list where drawGraphic g = drawInWindow w g main = runGraphics ( do w <- openWindow "Nested Squares" (300, 300) putStr "Smallest radius = " small <- getLine let sm = read small putStr "Largest radius = " large <- getLine let lg = read large putStr "Increment = " incr <- getLine let inc = read incr let nest1 = makeNestedSquares (150, 150) sm lg inc Red sequence_ (graphicsToIO w nest1) spaceClose w) -- This version uses readInt main2 = runGraphics ( do w <- openWindow "Nested Squares" (300, 300) sm <- readInt "Smallest radius = " lg <- readInt "Largest radius = " inc <- readInt "Increment = " let nest1 = makeNestedSquares (150, 150) sm lg inc Red sequence_ (graphicsToIO w nest1) spaceClose w) -- A function to read an Int from the keyboard, using given prompt. -- Note that it returns IO Int, not Int. readInt :: String -> IO Int readInt prompt = do putStr prompt numStr <- getLine let num = read numStr return num -- From SOE spaceClose :: Window -> IO () spaceClose w = do k <- getKey w if k==' ' || k == '\x0' then closeWindow w else spaceClose w