cga/Gtk.hs

204 lines
6.3 KiB
Haskell
Raw Normal View History

2014-10-01 18:26:57 +00:00
module Gtk where
import Control.Monad.IO.Class
2014-10-05 01:12:58 +00:00
import Control.Monad
import Defaults
2014-10-01 18:26:57 +00:00
import Diagram
import Diagrams.Prelude
import Diagrams.Backend.Cairo
import Diagrams.Backend.Cairo.Internal
import Graphics.UI.Gtk
2014-10-02 12:29:56 +00:00
import Graphics.UI.Gtk.Glade
2014-10-01 18:26:57 +00:00
import System.Directory
import Util
2014-10-01 18:26:57 +00:00
2014-10-02 12:29:56 +00:00
gladeFile :: FilePath
gladeFile = "gtk2.glade"
2014-10-01 21:02:43 +00:00
-- |Handle the whole GTK gui.
2014-10-02 11:14:16 +00:00
makeGUI :: FilePath -> IO ()
makeGUI startFile = do
2014-10-01 18:26:57 +00:00
homedir <- getHomeDirectory
-- init gui
_ <- initGUI
2014-10-02 12:29:56 +00:00
-- load glade file
Just xml <- xmlNew gladeFile
window <- xmlGetWidget xml castToWindow "window1"
drawButton <- xmlGetWidget xml castToButton "drawButton"
saveButton <- xmlGetWidget xml castToButton "saveButton"
quitButton <- xmlGetWidget xml castToButton "quitButton"
fileButton <- xmlGetWidget xml castToFileChooserButton
"filechooserButton"
da <- xmlGetWidget xml castToDrawingArea "drawingarea"
hscale <- xmlGetWidget xml castToHScale "hscale"
xlDE <- xmlGetWidget xml castToEntry "xlD"
xlUE <- xmlGetWidget xml castToEntry "xlU"
ylDE <- xmlGetWidget xml castToEntry "ylD"
ylUE <- xmlGetWidget xml castToEntry "ylU"
2014-10-01 18:26:57 +00:00
-- adjust properties
2014-10-05 01:12:58 +00:00
if startFile == ""
then do
_ <- fileChooserSetCurrentFolder fileButton homedir
return ()
else do
_ <- fileChooserSetFilename fileButton startFile
return ()
2014-10-01 18:26:57 +00:00
-- callbacks
_ <- onDestroy window mainQuit
_ <- onClicked drawButton $ onClickedDrawButton fileButton
da hscale (xlDE, xlUE) (ylDE, ylUE)
2014-10-01 18:26:57 +00:00
_ <- onClicked saveButton $ onClickedSaveButton fileButton
hscale (xlDE, xlUE) (ylDE, ylUE)
2014-10-01 18:26:57 +00:00
_ <- onClicked quitButton mainQuit
-- hotkeys
_ <- window `on` keyPressEvent $ tryEvent $ do
[Control] <- eventModifier
"q" <- eventKeyName
2014-10-05 01:12:58 +00:00
liftIO mainQuit
2014-10-01 18:26:57 +00:00
_ <- window `on` keyPressEvent $ tryEvent $ do
[Control] <- eventModifier
"s" <- eventKeyName
liftIO $ onClickedSaveButton fileButton
hscale (xlDE, xlUE) (ylDE, ylUE)
2014-10-01 18:26:57 +00:00
_ <- window `on` keyPressEvent $ tryEvent $ do
[Control] <- eventModifier
"d" <- eventKeyName
liftIO $ onClickedDrawButton fileButton da hscale
(xlDE, xlUE) (ylDE, ylUE)
2014-10-01 18:26:57 +00:00
-- draw widgets and start main loop
widgetShowAll window
mainGUI
2014-10-01 21:02:43 +00:00
-- |Callback when the "Draw" Button is clicked.
onClickedDrawButton :: (WidgetClass widget, RangeClass scale)
2014-10-01 18:26:57 +00:00
=> FileChooserButton
-> widget
-> scale
-> (Entry, Entry)
-> (Entry, Entry)
2014-10-01 18:26:57 +00:00
-> IO ()
onClickedDrawButton fcb da scale' dXE dYE = do
2014-10-01 18:26:57 +00:00
filename <- fileChooserGetFilename fcb
case filename of
Just x -> do
cId <- onExpose da (\_ -> drawDiag' x da scale' dXE dYE)
_ <- on fcb fileActivated (signalDisconnect cId)
ret <- drawDiag' x da scale' dXE dYE
2014-10-05 01:12:58 +00:00
unless ret $ showErrorDialog "No valid Mesh file!"
Nothing -> showErrorDialog "No valid Mesh file!"
2014-10-01 18:26:57 +00:00
2014-10-01 21:02:43 +00:00
-- |Callback when the "Save" Button is clicked.
onClickedSaveButton :: RangeClass scale
=> FileChooserButton
-> scale
-> (Entry, Entry)
-> (Entry, Entry)
2014-10-01 18:26:57 +00:00
-> IO ()
onClickedSaveButton fcb scale' dXE dYE = do
2014-10-01 18:26:57 +00:00
filename <- fileChooserGetFilename fcb
case filename of
Just x -> do
ret <- saveDiag' x scale' dXE dYE
2014-10-05 01:12:58 +00:00
unless ret $ showErrorDialog "No valid Mesh file!"
Nothing -> showErrorDialog "No valid Mesh file!"
2014-10-01 18:26:57 +00:00
2014-10-01 21:02:43 +00:00
-- |Pops up an error Dialog with the given String.
2014-10-01 18:26:57 +00:00
showErrorDialog :: String -> IO ()
showErrorDialog str = do
errorDialog <- messageDialogNew Nothing
[DialogDestroyWithParent]
MessageError
ButtonsClose
str
_ <- dialogRun errorDialog
widgetDestroy errorDialog
2014-10-01 21:02:43 +00:00
-- |Draws a Diagram which is built from a given file to
-- the gtk DrawingArea.
drawDiag' :: (WidgetClass widget, RangeClass scale)
=> FilePath
-> widget
-> scale
-> (Entry, Entry)
-> (Entry, Entry)
2014-10-05 01:12:58 +00:00
-> IO Bool
drawDiag' fp da scale' dXE dYE =
2014-10-05 01:12:58 +00:00
if cmpExt "obj" fp
then do
mesh <- readFile fp
dw <- widgetGetDrawWindow da
adjustment <- rangeGetAdjustment scale'
scaleVal <- adjustmentGetValue adjustment
xlD <- entryGetText $ fst dXE
xlU <- entryGetText $ snd dXE
ylD <- entryGetText $ fst dYE
ylU <- entryGetText $ snd dYE
-- clear drawing area
clearDiag da
let xD = (read xlD, read xlU) :: (Double, Double)
yD = (read ylD, read ylU) :: (Double, Double)
(_, r) = renderDia Cairo
(CairoOptions "" (Width 600) SVG False)
(diagFromString (def{t = scaleVal,
dX = xD,
dY = yD})
mesh)
renderWithDrawable dw r
2014-10-02 18:59:27 +00:00
return True
2014-10-05 01:12:58 +00:00
else return False
2014-10-01 21:02:43 +00:00
-- |Saves a Diagram which is built from a given file as an SVG.
saveDiag' :: RangeClass scale
=> FilePath
-> scale
-> (Entry, Entry)
-> (Entry, Entry)
-> IO Bool
saveDiag' fp scale' dXE dYE =
2014-10-05 01:12:58 +00:00
if cmpExt "obj" fp
then do
mesh <- readFile fp
adjustment <- rangeGetAdjustment scale'
scaleVal <- adjustmentGetValue adjustment
xlD <- entryGetText $ fst dXE
xlU <- entryGetText $ snd dXE
ylD <- entryGetText $ fst dYE
ylU <- entryGetText $ snd dYE
let xD = (read xlD, read xlU) :: (Double, Double)
yD = (read ylD, read ylU) :: (Double, Double)
renderCairo "out.svg" (Width 600)
(diagFromString (def{t = scaleVal,
dX = xD,
dY = yD})
mesh)
2014-10-02 18:59:27 +00:00
return True
2014-10-05 01:12:58 +00:00
else return False
-- |Clears the drawing area by painting a white rectangle.
clearDiag :: WidgetClass widget
=> widget
-> IO ()
clearDiag da = do
dw <- widgetGetDrawWindow da
let (_, r) = renderDia Cairo
(CairoOptions "" (Width 600) SVG False)
(emptyRect 600 600)
renderWithDrawable dw r