From: Chris Smith <[email protected]> > > On Fri, 2011-07-08 at 08:08 +0200, Heinrich Apfelmus wrote: > > Do you know any *small GUI programs* that you would *like* to see > > *implemented with Functional Reactive Programming?* > > This isn't really a specific application, but what I'd like to see most > from FRP is an example of something that involves moving between windows > and dialog boxes. All of the GUI-based FRP examples I've seen so far > involve interactions in a specific GUI layout. It's unclear to me how > FRP extends into a situation like: > > - There's a starting window showing several options for what to do > - When the user chooses an option, that window closes, and a new one > opens with that activity. > - In response to some actions, dialog boxes appear with their own > interactions. > > It's not clear to me if anyone in FRP has an idea of how stuff like this > fits in. Is there some FRP trick to handle this declaratively? Or > would you just say each move to a new window ends or pauses one network > of events and behaviors, and starts a new one?
I can show you how I've been handling this with reactive-banana and gtk2hs. As a small example, the "File->Open" command is meant to open a new project. The codez: > maybeEvent0 :: Typeable a => Action -> IO (Maybe a) -> NetworkDescription > (Event a) > maybeEvent0 act ops = do > (addHandler, runHandlers) <- liftIO newAddHandler > liftIO $ on act actionActivated $ ops >>= maybe (return ()) runHandlers > fromAddHandler addHandler > -- | Load a saved project file > openHandler :: ActionGroup -> Window -> NetworkDescription (Event (String, > HTree)) > openHandler actGrp _win = do > act <- liftIO openAction > liftIO $ actionGroupAddActionWithAccel actGrp act Nothing > maybeEvent0 act openProjectDialog > openProjectDialog :: IO (Maybe (String, HTree)) > openProjectDialog = do > fc <- fileChooserDialogNew (Just "Select a project file") > Nothing > FileChooserActionOpen > [] > fileChooserSetSelectMultiple fc False > dialogAddButton fc stockCancel ResponseCancel > dialogAddButton fc stockOk ResponseOk > widgetShowAll fc > resp <- dialogRun fc > case resp of > ResponseOk -> runMaybeT $ do > fp <- MaybeT $ fileChooserGetFilename fc > liftIO $ widgetDestroy fc > (fp, ) <$> liftIO (readProject fp) > _ -> widgetDestroy fc >> return Nothing The `openHandler` function connects the Gtk signal to the reactive-banana framework. This uses the helper `maybeEvent0`, which filters an IO action and triggers a reactive-banana Event when that IO action actually returns a value. I've been using this pattern for most of my modal dialogs, and I think it works very well. The one dialog I haven't used it for is the starting window, which is straight-line imperative code. I don't yet have any non-modal dialogs or alternate windows, but there shouldn't be a problem. There's nothing special about which window a widget is in; it can be connected to the FRP framework just like a widget in the main window. John L. _______________________________________________ Haskell-Cafe mailing list [email protected] http://www.haskell.org/mailman/listinfo/haskell-cafe
