module Graphics.Rendering.Chart.Gtk(
renderableToWindow,
createRenderableWindow,
updateCanvas
) where
import qualified Graphics.UI.Gtk as G
import qualified Graphics.UI.Gtk.Gdk.Events as GE
import qualified Graphics.Rendering.Cairo as C
import Graphics.Rendering.Chart
import Graphics.Rendering.Chart.Renderable
import Graphics.Rendering.Chart.Types
import Data.List (isPrefixOf)
import Data.IORef
import Control.Monad(when)
import System.IO.Unsafe(unsafePerformIO)
anyKey :: (Monad m) => m a -> GE.Event -> m Bool
anyKey m (GE.Key {GE.eventKeyName=key})
| any (`isPrefixOf` key) ignores = return True
| otherwise = m >> return True
where ignores = ["Shift","Control","Alt",
"Super","Meta","Hyper"]
guiInitVar :: IORef Bool
guiInitVar = unsafePerformIO (newIORef False)
initGuiOnce :: IO ()
initGuiOnce = do
v <- readIORef guiInitVar
when (not v) $ do
G.unsafeInitGUIForThreadedRTS
writeIORef guiInitVar True
renderableToWindow :: Renderable a -> Int -> Int -> IO ()
renderableToWindow chart windowWidth windowHeight = do
initGuiOnce
window <- createRenderableWindow chart windowWidth windowHeight
G.onKeyPress window $ anyKey (G.widgetDestroy window)
G.onDestroy window G.mainQuit
G.widgetShowAll window
G.mainGUI
createRenderableWindow :: Renderable a -> Int -> Int -> IO G.Window
createRenderableWindow chart windowWidth windowHeight = do
window <- G.windowNew
canvas <- G.drawingAreaNew
G.widgetSetSizeRequest window windowWidth windowHeight
G.onExpose canvas $ const (updateCanvas chart canvas)
G.set window [G.containerChild G.:= canvas]
return window
updateCanvas :: Renderable a -> G.DrawingArea -> IO Bool
updateCanvas chart canvas = do
win <- G.widgetGetDrawWindow canvas
(width, height) <- G.widgetGetSize canvas
let sz = (fromIntegral width,fromIntegral height)
G.renderWithDrawable win $ runCRender (render chart sz) bitmapEnv
return True