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
figure :: Diagram Cairo R2
figure = unitCircle # scaleX 0.5 # rotateBy (1/6) # scale 50 # fc red
and it will work like a charm!
You can note that in recent versions of diagrams, you should use
import Diagrams.Backend.Gtk
instead of
import Diagrams.Backend.Cairo.Gtk
and
figure :: Diagram Cairo
instead of
figure :: Diagram Cairo R2
The result now looks like :
module Main where
import Control.Monad.Trans (liftIO)
import Graphics.UI.Gtk
import Diagrams.Backend.Cairo
import Diagrams.Backend.Gtk
import Diagrams.Prelude
main :: IO ()
main = do
initGUI
window <- windowNew
canvas <- drawingAreaNew
canvas `on` sizeRequest $ return (Requisition 256 256)
Graphics.UI.Gtk.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
figure = unitCircle # scaleX 0.5 # rotateBy (1/6) # scale 50 # fc red
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With