> module Barrie.DrawPrimitive > (DrawFunction, Picture, Colour, > background, > setForeground, > lineTo, moveTo, line, lineWidth, move, rectangle, polygon, > multiLine, circle, > image, showText, > black, white, fromRGB, > doDraw) > where > import qualified Graphics.UI.Gtk as Gtk > type Picture = Gtk.Pixmap > data Colour = RGB Int Int Int deriving (Eq) > black, white :: Colour > black = fromRGB 0 0 0 > white = fromRGB 65535 65535 65535 > data DrawPrimitive = Background Colour > | SetForeground Colour > | SetLineThickness Int > | Line Int Int > | LineTo Int Int > | LineWidth Int > | Move Int Int > | MoveTo Int Int > | Polygon Bool [(Int, Int)] > | Circle Bool Int > | Rectangle Bool Int Int > | ShowText String > | Image String > deriving (Eq) > type DrawFunction = [DrawPrimitive] -> [DrawPrimitive] > background :: Colour -> DrawFunction > lineTo, moveTo, line, move :: Int -> Int -> DrawFunction > lineWidth :: Int -> DrawFunction > rectangle :: Bool -> Int -> Int -> DrawFunction > polygon :: Bool -> [(Int, Int)] -> DrawFunction > circle :: Bool -> Int -> DrawFunction > showText :: String -> DrawFunction > image :: String -> DrawFunction > multiLine :: [(Int,Int)] -> DrawFunction > setForeground :: Colour -> DrawFunction > background colour xs = Background colour : xs > lineTo x y xs = LineTo x y : xs > moveTo x y xs = MoveTo x y : xs > line x y xs = Line x y : xs > lineWidth w xs = LineWidth w : xs > move x y xs = Move x y : xs > rectangle filled width height xs = Rectangle filled width height : xs > polygon filled pts xs = Polygon filled pts : xs > circle filled r xs = Circle filled r : xs > showText text xs = ShowText text : xs > image pic = (:) (Image pic) > multiLine [] = id > multiLine ((x, y):pts) = moveTo x y . foldl (.) id (map (uncurry lineTo) pts) > setForeground col xs = SetForeground col : xs > fromRGB :: Int -> Int -> Int -> Colour > fromRGB = RGB > toGtkColour :: Colour -> IO Gtk.Color > toGtkColour (RGB r g b) = return $ Gtk.Color (cvt r) (cvt g) (cvt b) > where cvt = fromInteger . toInteger > doDraw :: Gtk.Pixmap > -> Gtk.GC > -> Gtk.PangoContext > -> (Int,Int) > -> [DrawPrimitive] > -> IO () > doDraw _ _ _ _ [] = return () > doDraw win gc context (x,y) (p:ps) = do (newP,newGC) <- drawPrimitive p > doDraw win newGC context newP ps > where noChange = return ((x,y),gc) > drawPrimitive (MoveTo x' y') = return ((x', y'), gc) > drawPrimitive (Move dx dy) = return ((x + dx, y + dy), gc) > drawPrimitive (LineTo x' y') = do > Gtk.drawLine win gc (x,y) (x',y') > return ((x',y'), gc) > drawPrimitive (Line dx dy) = do > let (x',y') = (x + dx, y + dy) > Gtk.drawLine win gc (x,y) (x', y') > return ((x',y'), gc) > drawPrimitive (LineWidth w) = do > Gtk.gcSetValues gc Gtk.newGCValues { Gtk.lineWidth = w } > return ((x,y), gc) > drawPrimitive (Rectangle filled width height) = do > Gtk.drawRectangle win gc filled x y width height > noChange > drawPrimitive (Polygon _ []) = noChange > drawPrimitive (Polygon filled pts) = do > Gtk.drawPolygon win gc filled pts > return (last pts, gc) > drawPrimitive (Circle filled r) = do > Gtk.drawArc win gc filled (x - r) (y - r) > (r * 2) (r * 2) 0 (360 * 64) > return ((x,y),gc) > drawPrimitive (ShowText text) = do > layout <- Gtk.layoutText context text > layoutLine <- Gtk.layoutGetLine layout 0 > Gtk.drawLayoutLine win gc x y layoutLine > return ((x,y),gc) > drawPrimitive (SetForeground colour) = do > col <- toGtkColour colour > Gtk.gcSetValues gc $ Gtk.newGCValues { > Gtk.foreground = col > } > return ((x,y),gc) > drawPrimitive (Background colour) = do > backgc <- Gtk.gcNew win > gtkColour <- toGtkColour colour > Gtk.gcSetValues backgc Gtk.newGCValues { > Gtk.foreground = gtkColour > } > (width, height) <- Gtk.drawableGetSize win > Gtk.drawRectangle win backgc True 0 0 width height > Gtk.drawRectangle win backgc False 0 0 width height > return ((x,y),gc) > drawPrimitive (Image pic) = do > pb <- Gtk.pixbufNewFromFile pic > Gtk.drawPixbuf win gc pb 0 0 x y (-1) (-1) Gtk.RgbDitherNormal 0 0 > return ((x,y),gc)