Browse thread
Functional Reactive GUI for O'Caml
[
Home
]
[ Index:
by date
|
by threads
]
[ Message by date: previous | next ] [ Message in thread: previous | next ] [ Thread: previous | next ]
[ Message by date: previous | next ] [ Message in thread: previous | next ] [ Thread: previous | next ]
Date: | 2006-12-21 (03:36) |
From: | Chris King <colanderman@g...> |
Subject: | Re: [Caml-list] Functional Reactive GUI for O'Caml |
On 12/20/06, Gabriel Kerneis <gabriel.kerneis@enst.fr> wrote: > It might have been clearer if I had read a quick tutorial or how-to > before. But your question targeted newbies, so let me give you a > total newbie's answer : I just can't get it ;-) You have a very good point :) nothing's intuitive unless it's familiar, which I admit the syntax (especially lift) is not. I intend to post some examples as well as a tutorial in the next few weeks, but for the time being here is a quick breakdown of the above example (with a few math fixes :P): > open Fr > open FrGui Fr is the library containing funcitons to create functional reactive expressions; FrGui contains definitions of all the GUI widgets. > let float_view f = text_view (lift (string_of_float @f)) This one-liner defines the float_view widget in terms of the text_view widget. Ignoring the definition (which should make more sense later), it's simply a function which creates a widget which displays the time-varying floating-point value f. > let _ = > let temp_box, temp = spin_box 20. in spin_box is a function which creates a widget (temp_box) which allows the user to input a floating-point value (in this case, the temperature we want to convert). Here 20 is given as its initial value. The current value of temp_box is stored in temp. This value can change with time and is called a "behavior" (and has the type float behavior). > let fahrenheit = lift (@temp *. 1.8 +. 32.) Because temp is not a float but a float behavior, we must use a special construct to access it. lift (expr) allows us to access values contained in behaviors and to create new ones. Inside of expr (which is otherwise a normal O'Caml expression), we can use the form @expr to reference a behavior (think of this like dereferencing a pointer in C). Here, fahrenheit is a behavior which is always equal to the value of (temp *. 1.8 +. 32.). Whenever temp changes, so does fahrenheit. > and celsuis = lift ((@temp -. 32.) /. 1.8) in Here, we similarly define celsius as a float behavior which is dependent on the current value of temp. > let main_window = window > ~title: "Temperature converter" > (hbox [ > hbox [label "Convert "; temp_box; label " to:"]; > vbox [ > hbox [label "degrees Fahrenheit: "; float_view fahrenheit]; > hbox [label "degrees Celsius: "; float_view celsius]]]) in Here we define the main window. hbox, vbox, and label are all functions which create widgets. hbox and vbox pack lists of widgets horizontally and vertically, and label creates a text label. temp_box is the widget instance we defined above, which allows the user to enter the value of temp. We also create two instances of the float_view widget, to display the values of fahrenheit and celsius. > run_dialog (main_window, main_window#close) This incantation displays main_window and enters the GUI's main loop until the window's close button is clicked. The end result is a window with a spin box into which the user can input a temperature. That temperature is instantly converted into both Fahrenheit and Celsius and displayed in two other text boxes (the float_views) in the window. Hopefully this description helped more than it confused... if it did more of the latter then I'll try to post a proper tutorial on the O'Caml RT website as soon as possible, since one is in order anyway. Thanks for you input :) - Chris