barrie-0.3.1: src/Barrie/DrawPrimitive.lhs
> 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)