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