I'm trying to learn how to draw diagrams using the diagrams library and the Cairo / GTK backend. I've got a blank window to appear, but my drawing won't render. What am I doing wrong?
module Main where
import Control.Monad.Trans (liftIO)
import Graphics.UI.Gtk
import Diagrams.Backend.Cairo
import Diagrams.Backend.Cairo.Gtk
import Diagrams.Prelude
main :: IO ()
main = do
initGUI
window <- windowNew
canvas <- drawingAreaNew
canvas `on` sizeRequest $ return (Requisition 1000 1000)
set window [ containerBorderWidth := 10,
containerChild := canvas ]
canvas `on` exposeEvent $ renderFigure
onDestroy window mainQuit
widgetShowAll window
mainGUI
renderFigure :: EventM EExpose Bool
renderFigure = do
win <- eventWindow
liftIO $ renderToGtk win $ toGtkCoords figure
-- liftIO $ defaultRender win figure
return True
figure :: Diagram Cairo R2
figure = unitCircle # scaleX 0.5 # rotateBy (1/6) # scale 50
I've tried using "defaultRender" (as commented out above), but that gives a type error: apparently "win" is not the right type.
I've read the tutorial and user manual for diagram, but it doesn't actually tell you how to use the Cairo backend.
Update: I've got the ellipse to render. The "renderFigure" function now says:
renderFigure :: DrawingArea -> EventM EExpose Bool
renderFigure canvas = do
-- win <- eventWindow
liftIO $ do
-- diagramArea <- widgetGetDrawWindow canvas
-- renderToGtk diagramArea $ toGtkCoords figure
defaultRender canvas figure
return True
and the DrawingArea passed in is the "canvas" referenced in the "canvas on
exposeEvent..." setting.
But I still can't get it to render a fixed size diagram using "renderToGtk".
Update 2: Thanks to Joachim Breitner's answer, I've now got the minimal diagram-on-GTK program looking like this, ready for your cut-and-paste pleasure.
module Main where
import Control.Monad.Trans (liftIO)
import Graphics.UI.Gtk
import Diagrams.Backend.Cairo
import Diagrams.Backend.Cairo.Gtk
import Diagrams.Prelude
main :: IO ()
main = do
initGUI
window <- windowNew
canvas <- drawingAreaNew
canvas `on` sizeRequest $ return (Requisition 256 256)
set window [ containerBorderWidth := 10,
containerChild := canvas ]
canvas `on` exposeEvent $ renderFigure
onDestroy window mainQuit
widgetShowAll window
mainGUI
renderFigure :: EventM EExpose Bool
renderFigure = do
win <- eventWindow
liftIO $ renderToGtk win $ toGtkCoords figure
return True
figure :: Diagram Cairo R2
figure = unitCircle # scaleX 0.5 # rotateBy (1/6) # scale 50 # fc red
Your initial code actually works. But renderToGtk does not scale the image, so it appears rather small, too small to be visible at that line width. But try
and it will work like a charm!