<div>Hi Andy,</div><div><br></div>Your program didn't compile as given, so I cut out some of the event handling fanciness you were doing. Also, my modified version restarts whenever the 'r' key is pressed. I figure those changes aren't important to the problem at hand.<div>
<br></div><div>Anyway, I don't think it's ever going to be possible to define a Binary instance for a TextView, since all of the functions which can yield information about it are impure. I would recommend extracting the relevant data beforehand, and then persisting it in a tuple. You could use some 'marshal<WIDGET>' and 'recreate<WIDGET>' functions if you need to persist many different widget types. Saving just the text can be done as follows:</div>
<div><br></div><div><code></div><div>module DyreExample where</div><div><br></div><div>import Graphics.UI.Gtk hiding (get)</div><div>import qualified Graphics.UI.Gtk.Gdk.Events as E</div><div><br></div><div>import qualified Config.Dyre as Dyre</div>
<div>import Config.Dyre.Relaunch</div><div><br></div><div>import System.IO</div><div>import Data.Binary</div><div><br></div><div>data Config = Config { message :: String, errorMsg :: Maybe String }</div><div><br></div><div>
defaultConfig :: Config</div><div>defaultConfig = Config "Dyre Example v0.1" Nothing</div><div><br></div><div>showError :: Config -> String -> Config</div><div>showError cfg msg = cfg { errorMsg = Just msg }</div>
<div><br></div><div>realMain Config{message = message, errorMsg = errorMsg } = do</div><div> initGUI</div><div><br></div><div> textView <- textViewNew</div><div> textBuffer <- textViewGetBuffer textView</div><div>
text <- restoreBinaryState ""</div><div> putStrLn $ "Restored state: " ++ text</div><div> textBufferSetText textBuffer text</div><div><br></div><div> rootWindow <- windowNew</div><div> rootWindow `onDestroy` mainQuit</div>
<div> windowFullscreen rootWindow</div><div><br></div><div> rootWindow `containerAdd` textView</div><div><br></div><div> widgetShowAll rootWindow</div><div><br></div><div> rootWindow `onKeyPress` (\event -> dyreKeyTest event textView)</div>
<div><br></div><div> mainGUI</div><div><br></div><div>dyreExample = Dyre.wrapMain $ Dyre.defaultParams</div><div> { Dyre.projectName = "Main"</div><div> , Dyre.realMain = realMain</div><div> , Dyre.showError = showError</div>
<div> }</div><div><br></div><div>dyreKeyTest :: E.Event -> TextView -> IO Bool</div><div>dyreKeyTest ev textView = do</div><div> case E.eventKeyName ev of</div><div> "r" -> do textBuffer <- textViewGetBuffer textView</div>
<div> sI <- textBufferGetStartIter textBuffer</div><div> eI <- textBufferGetEndIter textBuffer</div><div> text <- textBufferGetText textBuffer sI eI True</div>
<div> putStrLn $ "Relaunching with state: " ++ text</div><div> relaunchWithBinaryState text Nothing</div><div> return True</div><div> _ -> return False</div>
<div></code></div><div><br></div><div>Other comments:</div><div> 1. It isn't necessary to explicitly tell Dyre to do a custom compile. It will take care of figuring that out once you restart it.</div><div> 2. Instead of manually setting paths in the code, you can use the '--dyre-debug' command-line flag, which will cause Dyre to look for configurations in the current directory, and store temporary files in a 'cache' subdirectory.</div>
<div> 3. Giving a project name of 'Main' causes Dyre to see the file 'Main.hs' as a custom configuration. I'm not sure if that's what you intended, but it will make testing custom configurations harder than it needs to be.</div>
<div> 4. Good luck with the rest of your project!</div><div><br></div><div>- Will Donnelly</div>