[GUI] fruit demo

Daan Leijen daanleijen@xs4all.nl
Sat, 1 Feb 2003 00:08:41 +0100


Hi Anthony,

Very interesting to see your program -- it is neat how one
can separate the model from the interface! (allthough the wiring
still seems a bit convoluted.)

I don't know if you have seen Koen Claessens bouncing balls
demo, but I would be quite interested to see how that would look in
Fruit (I  think that especially the behaviour of the balls can be modelled nicer
in Fruit). See http://www.cs.chalmers.se/Cs/Grundutb/Kurser/afp/yahu.html
for the demo.

Anyway, I  am off re-reading your papers :-)
-- Daan.


----- Original Message ----- 
From: "Antony Courtney" <antony@apocalypse.org>
To: "John Meacham" <john@repetae.net>
Cc: "Haskell GUI API Task Force" <gui@haskell.org>
Sent: Friday, January 31, 2003 10:08 PM
Subject: Re: Terminology (Re: [GUI] Re: Know you backends)


> John Meacham wrote:
> >
> > I propose a simple program which pops up a window saying
> > 
> > 'Hello World' with a button saying 'Bye' which you click and it changes
> > the message to 'Goodbye'. if you click the button again the program
> > exits.
> 
> Although (as I have said repeatedly) Fruit is far too experimental to be 
> suitable as a standardized, portable production GUI toolkit, I have, 
> just for fun, implemented this little excercise in Fruit.  Code is attached.
> 
> -antony
> 
> -- 
> Antony Courtney
> Grad. Student, Dept. of Computer Science, Yale University
> antony@apocalypse.org          http://www.apocalypse.org/pub/u/antony
> 


--------------------------------------------------------------------------------


> --
> -- HelloGoodbye -- simple "Hello/Goodbye" example for GUI API comparison
> -- proposed by John Meacham
> --
> -- Author: Antony Courtney, 1/31/03
> 
> module HelloGoodbye where
> 
> import GUI
> import Arrow
> import AFRP
> import Haven
> import GAUtils
> 
> -- The code here is short, but heavily commented.  I've chosen to err
> -- on the side of verbosity with comments to try and describe a little
> -- of the design methodology and clarify many of the combinators that are
> -- relatively newer than published papers on Fruit or AFRP/Yampa.
> 
> -- First, let's try to seperate the "model" from the interface:
> 
> -- Our application model is a signal function that accepts button
> -- press events as input, and produces a String to display paired with
> -- an event that occurs when the application is done executing:
>  
> appModel :: SF (Event ()) (String, Event ())
> 
> -- Our model is a simple state machine.  We'll use kSwitch to switch
> -- from the "hello" state to the "goodbye" state on a button press:
> appModel = kSwitch helloSF -- initial signal function
>            (arr fst) -- switch when input event occurs
>            (\_ _ -> goodbyeSF)  -- SF to switch in to
> 
> -- The "hello" state just outputs "hello" and does not cause
> -- a program termination event:
> helloSF :: SF (Event ()) (String,Event ())
> helloSF = (constant ("Hello World", noEvent))
> 
> -- The "goodbye" state outputs "Goodbye", and produces a program termination
> -- event when the input event occurs:
> goodbyeSF :: SF (Event ()) (String,Event ())
> goodbyeSF = (constant "Goodbye") &&& identity
> 
> 
> -- Now for the GUI itself:
> 
> -- The window content (or view) consists of a button and label.  The
> -- String to display in the label is taken as an external signal (from
> -- the model), and the button press events are an output signal (to be
> -- fed to the model)
> -- Some notes:
> --   - "GA" is the type of a GUI Arrow, which uses the order in which GUIs
> --     appear in the Arrow notation to determine the order in which the
> --     GUI components will be layed out.
> --   - We use "hbox" to create a horizontal layout of GUI components.
> --   - The use of "id" as the input signal to the button specifies default
> --     configuration options for the button.
> --   - Since there is no returnA at the end of the proc, the output signal
> --     from the button is the output signal of the entire GUI
> viewGA :: GA (String) (Event ())
> viewGA = hbox $ proc s -> do
>   ltext s >- label -> _
>   id >- button (btext "Bye")
> 
> -- Use feedback to wire the view to the model.  The one subtlety here
> -- is that we must use 'iPre' to introduce an infinitesimal delay between
> -- the output signal of the view and the input signal of the model to ensure
> -- that the feedback loop is well-formed.
> appGUI :: GUI () (Event ())
> appGUI = proc (gin,_) -> do
>   rec (gin,s) >- unGA viewGA -> (pic,clickE)
>       clickE >- iPre noEvent -> dClickE
>       dClickE >- appModel -> (s,termE)
>   (pic,termE) >- returnA
> 
> -- Full Disclosure:  The above code assumes that 'runGUI' observes the
> -- output event of the GUI, and exits the program when the event occurs.
> -- The current implementation doesn't actually support this, but adding
> -- it would be trivial.
> --
> -- Main :: IO ()
> -- main = runGUI appGUI
> 
> 
>