About CTM The following Alice ML code is derived from the examples provided in the book:
      "Concepts, Techniques, and Models of Computer Programming" by Peter Van Roy and Seif Haridi.
      http://www2.info.ucl.ac.be/people/PVR/book.html

(* CTM Chapter #10 Examples in Alice ML *)
import structure Gtk            from "x-alice:/lib/gtk/Gtk"
import structure Canvas         from "x-alice:/lib/gtk/Canvas"

(* syntactic sugar for solutions using promises/futures *)
open Promise
open Future
infix 3 ?=
val op?= = fulfill
val ? = future

(* Functions defined in previous chapters *)
datatype gtkglue = NOGLUE | N | S | W | E | NS | NW | NE | SW | SE | WE | NSW | NWE | SWE | NSWE
datatype gtk = GtkTD of gtk list
             | GtkLR of gtk list
             | GtkTitle of {text:string}
             | GtkLabel of {text:string}
             | GtkText of {object:(Gtk.object promise), tdscrollbar:bool, glue:gtkglue}
             | GtkButton of {text:string, action:(Gtk.callback_function), glue:gtkglue}
             | GtkGlue of gtkglue

fun gtkBuild d =
   let
      val window = Gtk.Window.new Gtk.WindowType.TOPLEVEL
      val destroyEvent = fn _ => OS.Process.exit OS.Process.success
      fun gtkPack (box, widget) =
         if (widget <> Gtk.NULL)
            then Gtk.Box.packStart(box, widget, false, false, 0)
            else ()
      fun build (GtkTD xs) =
            let
               val vBox = Gtk.VBox.new(false, 0)
            in
               map (fn x => let val widget = build x in gtkPack(vBox, widget) end) xs;
               vBox
            end
        | build (GtkLR xs) =
            let
               val hBox = Gtk.HBox.new(false, 0)
            in
               map (fn x => let val widget = build x in gtkPack(hBox, widget) end) xs;
               hBox
            end
        | build (GtkTitle {text}) =
            let
               val _ = Gtk.Window.setTitle(window, text)
            in
               Gtk.NULL
            end
        | build (GtkLabel {text}) =
            let
               val label = Gtk.Label.new text
            in
               label
            end
        | build (GtkText {object, tdscrollbar, glue}) =
            let
               val _ = fulfill(object, Gtk.TextView.new())
            in
               future object
            end
        | build (GtkButton {text, action, glue}) =
            let
               val button = Gtk.Button.newWithLabel text
            in
               Gtk.signalConnect(button, "clicked", action);
               button
            end
        | build (GtkGlue x) = Gtk.NULL
   in
      Gtk.signalConnect(window, "destroy-event", destroyEvent);
      Gtk.Container.setBorderWidth(window, 4);
      Gtk.Container.add(window, build d);
      window
   end

(* 10.2.2 Using the declarative/procedural approach - Build the GUI *)
fun gtkTextOutput field =
   let
      val textBuffer    = Gtk.TextView.getBuffer(future field)
      val textIterStart = Gtk.TextIter.new()
      val textIterEnd   = Gtk.TextIter.new()
   in
      Gtk.TextBuffer.getBounds(textBuffer, textIterStart, textIterEnd);
      Gtk.TextBuffer.getText(textBuffer, textIterStart, textIterEnd, false)
   end


fun getText a =
   let
      val h = promise()
      val t = promise()
      val pWindow = promise()
      fun a1 _ =
         let
         in
            t ?= gtkTextOutput(h);
            Gtk.Widget.destroy(future pWindow)
         end
      val d = GtkTD[
                 GtkLR[
                    GtkLabel {text="Input:"},
                    GtkText {object=h, tdscrollbar=true, glue=NSWE}],
                 GtkButton {text="Ok", action=a1, glue=NSWE}
              ]
      val window = gtkBuild(d)
   in
      fulfill(pWindow, window);
      Gtk.Widget.showAll window;
      await (future t);
      future t
   end;

inspect (getText "Type your name:");

(* 10.2.3 Using the declarative/procedural approach - Declarative geometry *)
val d = GtkLR[
           GtkLabel {text="left"},
           GtkLabel {text="center"},
           GtkLabel {text="right"}
        ]
val w1 = gtkBuild(d);
Gtk.Widget.showAll w1;

val e = GtkTD[
           GtkLabel {text="top"},
           GtkLabel {text="center"},
           GtkLabel {text="down"}
        ]
val w2 = gtkBuild(e);
Gtk.Widget.showAll w2;




Chris Rathman / Chris.Rathman@tx.rr.com