changeset 20:554e342665fe

Add a new parameter to Gui.gui
author Adam Chlipala <adam@chlipala.net>
date Sat, 24 Sep 2011 15:47:00 -0400
parents 3a303df9ae92
children 30f9a763f5fb
files calendar.ur calendar.urs datebox.ur datebox.urs examples/datebox.ur examples/togglepanel.ur gui.ur gui.urs togglePanel.ur togglePanel.urs
diffstat 10 files changed, 95 insertions(+), 105 deletions(-) [+]
line wrap: on
line diff
--- a/calendar.ur	Fri Sep 23 13:30:01 2011 +0200
+++ b/calendar.ur	Sat Sep 24 15:47:00 2011 -0400
@@ -207,7 +207,7 @@
     SourceL.onChange ctl.Day f
 
 val gui_t = Gui.mkGui 
-                (fn ctl =>
+                (fn [body ~ []] ctl =>
                     <xml>
                       <dyn signal={render' ctl}/>
                     </xml>)
--- a/calendar.urs	Fri Sep 23 13:30:01 2011 +0200
+++ b/calendar.urs	Sat Sep 24 15:47:00 2011 -0400
@@ -20,7 +20,7 @@
 val value : t -> signal date
 (* Read the date of the calendar. *)
 
-val gui_t : Gui.gui t xbody
+val gui_t : Gui.gui t []
 (* Witness that this is a gui widget. *)
 
 val create : time -> transaction t
--- a/datebox.ur	Fri Sep 23 13:30:01 2011 +0200
+++ b/datebox.ur	Sat Sep 24 15:47:00 2011 -0400
@@ -1,5 +1,5 @@
-con t other_ctx = {Cal : Calendar.t,
-          Panel : TogglePanel.togglePanel Calendar.t other_ctx}
+type t = {Cal : Calendar.t,
+          Panel : TogglePanel.togglePanel Calendar.t []}
 
 type date = Calendar.date
 val date_eq = Calendar.date_eq
@@ -7,16 +7,15 @@
 val time = Calendar.time
 val date = Calendar.date
 
-(* : other_ctx:::{Unit} -> [other_ctx ~ body] => formatCtl other_ctx  *)
-
-val format  = TogglePanel.defaultFormat 
-                 --#OpenCtl -- #CloseCtl
-                 ++ {OpenCtl = fn behaviour => <xml><button value="Choose" onclick={behaviour}/></xml>,
-                     CloseCtl = fn behaviour => <xml><button value="Hide" onclick={behaviour}/></xml>}
+val format : TogglePanel.formatCtl [] = fn [body ~ []] =>
+    TogglePanel.defaultFormat
+        -- #OpenCtl -- #CloseCtl
+        ++ {OpenCtl = fn behaviour => <xml><button value="Choose" onclick={behaviour}/></xml>,
+            CloseCtl = fn behaviour => <xml><button value="Hide" onclick={behaviour}/></xml>}
 
 fun create tm =
     cal <- Calendar.create tm;
-    panel <- TogglePanel.create format cal False;
+    panel <- TogglePanel.create @format cal False;
 
     return {Cal = cal,
             Panel = panel}
@@ -29,9 +28,9 @@
 
 fun value db = Calendar.value db.Cal
 
-fun render db = 
+val gui_t = Gui.mkGui (fn [body ~ []] db =>
     <xml>
       <dyn signal={date <- Calendar.value db.Cal;
                    return <xml>{[date.Year]}-{[date.Month]}-{[date.Day]}</xml>}/>
       {Gui.toXml db.Panel}
-    </xml>
+    </xml>)
--- a/datebox.urs	Fri Sep 23 13:30:01 2011 +0200
+++ b/datebox.urs	Sat Sep 24 15:47:00 2011 -0400
@@ -1,8 +1,7 @@
-con t::{Unit}->Type
+type t
 
-(* The type of dateboxes, which are input elements
- * allowing the user to select a date from a popup
- * calendar. *)
+(* The type of dateboxes, which are input elements allowing the user to select a
+ * date from a popup calendar. *)
 
 type date = {Year : int, Month : int, Day : int}
 val date_eq : eq date
@@ -11,17 +10,17 @@
 val date : time -> date
 (* Type of dates and some useful utility functions. *)
 
-val create : other_ctx:::{Unit} -> [other_ctx ~ body] => time -> transaction (t other_ctx)
+val create : time -> transaction t
 (* Get a datebox initially set to the given time. *)
 
-val onChange : other_ctx:::{Unit} -> [other_ctx ~ body] => t other_ctx -> (date -> transaction {}) -> transaction {}
+val onChange : t -> (date -> transaction {}) -> transaction {}
 (* Add an action to be run when the date changes. *)
 
-val set : other_ctx:::{Unit} -> [other_ctx ~ body] => t other_ctx -> date -> transaction {}
+val set : t -> date -> transaction {}
 (* Call this to change the selected date. *)
 
-val value : other_ctx:::{Unit} -> [other_ctx ~ body] => t other_ctx -> signal date
+val value : t -> signal date
 (* Extract the current date value. *)
 
-val render : other_ctx:::{Unit} -> [other_ctx ~ body] =>  t other_ctx -> xml ([Body] ++ other_ctx) [] []
+val gui_t : Gui.gui t []
 (* Draws the datebox as a piece of xml. *)
--- a/examples/datebox.ur	Fri Sep 23 13:30:01 2011 +0200
+++ b/examples/datebox.ur	Sat Sep 24 15:47:00 2011 -0400
@@ -1,15 +1,14 @@
 fun main () =
+    tm <- now;
 
-tm <- now;
+    dayCtl <- Datebox.create tm;
 
-dayCtl <- Datebox.create tm;
+    load <- return (Datebox.onChange dayCtl (fn d => alert (show d.Day)));
 
-load <- return (Datebox.onChange dayCtl (fn d => alert (show d.Day)));
-
-return
-    <xml>
-      <head><title>Datebox Example</title></head>
-      <body onload={load}>
-        {Datebox.render dayCtl}
-      </body>
-    </xml>
+    return
+        <xml>
+          <head><title>Datebox Example</title></head>
+          <body onload={load}>
+            {Gui.toXml dayCtl}
+          </body>
+        </xml>
--- a/examples/togglepanel.ur	Fri Sep 23 13:30:01 2011 +0200
+++ b/examples/togglepanel.ur	Sat Sep 24 15:47:00 2011 -0400
@@ -4,14 +4,15 @@
 val defaultContent : xbody = <xml><p>Here I am inside the panel.<br/><b>Default format</b></p></xml>
 val otherContent : xbody = <xml><p>Here I am inside the panel.<br/><b>Other format</b></p></xml>
 
-val otherFormat = {FormatPanel = fn ctl panel => <xml><span>A Custom {ctl} Format</span>{panel}</xml>,
-                   OpenCtl = fn behaviour => <xml><a href={bless "http://#"} onclick={behaviour}>View</a></xml>,
-                   CloseCtl = fn behaviour => <xml><a href={bless "http://#"} onclick={behaviour}>Hide</a></xml>}
+val otherFormat = fn [body ~ []] =>
+                     {FormatPanel = fn ctl panel => <xml><span>A Custom {ctl} Format</span>{panel}</xml>,
+                      OpenCtl = fn behaviour => <xml><a href={bless "http://#"} onclick={behaviour}>View</a></xml>,
+                      CloseCtl = fn behaviour => <xml><a href={bless "http://#"} onclick={behaviour}>Hide</a></xml>}
 
 fun main () =
 
-    defaultFormatPanel <- create defaultFormat defaultContent True;
-    otherFormatPanel <- create otherFormat otherContent False;
+    defaultFormatPanel <- create @defaultFormat defaultContent True;
+    otherFormatPanel <- create @otherFormat otherContent False;
 
     return <xml>
       <head>
--- a/gui.ur	Fri Sep 23 13:30:01 2011 +0200
+++ b/gui.ur	Sat Sep 24 15:47:00 2011 -0400
@@ -1,16 +1,8 @@
-class gui = fn t :: Type => fn xcomponent :: Type => t -> xcomponent
+class gui = fn (t :: Type) (ctx :: {Unit}) => [body ~ ctx] => t -> xml (body ++ ctx) [] []
 
-fun gui_xbody (x:xbody) : xbody = x
-fun gui_xtable (x:xtable) : xtable = x
+fun gui_xbody [body ~ []] x = x
+fun gui_xtable [body ~ _] x = x
 
-fun mkGui [t ::: Type] [xcomponent:::Type] (toXml : t -> xcomponent) = toXml 
+fun mkGui [t ::: Type] [ctx ::: {Unit}] (toXml : [body ~ ctx] => t -> xml (body ++ ctx) [] []) = @toXml
 
-fun toXml [t:::Type] [xcomponent ::: Type] (xmlize: gui t xcomponent) = xmlize 
-
-(* class gui t = t -> xbody *)
-
-(* fun toXml [t ::: Type] (xmlize : gui t) = xmlize *)
-
-(* fun gui_xbody x = x *)
-
-(* fun mkGui [t ::: Type] (toXml : t -> xbody) = toXml *)
+fun toXml [t ::: Type] [ctx ::: {Unit}] [body ~ ctx] (toXml : gui t ctx) = toXml
--- a/gui.urs	Fri Sep 23 13:30:01 2011 +0200
+++ b/gui.urs	Sat Sep 24 15:47:00 2011 -0400
@@ -1,21 +1,17 @@
 (* Gui framework elements common across individual components. *)
 
 (* Types of this class describe gui components. *)
-class gui :: Type -> Type -> Type
- 
-
-(* class gui = fn t xcomponent => t -> xcomponent *)
-(* class gui :: Type -> Type -> Type *)
+class gui :: Type (* The type of an object to render *)
+      -> {Unit} (* The HTML context to render it for (minus [body]) *)
+      -> Type
 
 (* How to add components to the gui class. *)
-val mkGui : t ::: Type -> xcomponent:::Type -> (t -> xcomponent) -> gui t xcomponent
+val mkGui : t ::: Type -> ctx ::: {Unit} -> ([body ~ ctx] => t -> xml (body ++ ctx) [] []) -> gui t ctx
 
-(* Xml itself can be a gui component. *)
-val gui_xbody : gui xbody xbody
+(* XML itself can be a gui component. *)
+val gui_xbody : gui xbody []
+val gui_xtable : gui xtable [Table]
 
 (* Currently the only thing a gui component can do is be
  * pretty printed to a piece of xml. *)
-val toXml : t ::: Type -> xcomponent ::: Type -> gui t xcomponent -> t -> xcomponent
-
-
-
+val toXml : t ::: Type -> ctx ::: {Unit} -> [body ~ ctx] => gui t ctx -> t -> xml (body ++ ctx) [] []
--- a/togglePanel.ur	Fri Sep 23 13:30:01 2011 +0200
+++ b/togglePanel.ur	Sat Sep 24 15:47:00 2011 -0400
@@ -1,34 +1,37 @@
 datatype panelState = Open | Closed
 
-con formatCtl :: {Unit} -> Type = fn other_ctx => {FormatPanel : (xml ([Body] ++ other_ctx) [] []) -> (xml ([Body] ++ other_ctx) [] []) -> (xml ([Body] ++ other_ctx) [] []),
-                  OpenCtl : transaction unit -> xml ([Body] ++ other_ctx) [] [],
-                  CloseCtl : transaction unit -> xml ([Body] ++ other_ctx) [] []}
+con formatCtl = fn ctx :: {Unit} => [body ~ ctx] =>
+                   {FormatPanel : xbody -> xbody -> xml (body ++ ctx) [] [],
+                    OpenCtl : transaction unit -> xbody,
+                    CloseCtl : transaction unit -> xbody}
 
-val defaultFormat = {FormatPanel = fn ctl panel => <xml>{ctl}{panel}</xml>,
-                     OpenCtl = fn behaviour => <xml><button value="Open" onclick={behaviour}/></xml>,
-                     CloseCtl = fn behaviour => <xml><button value="Close" onclick={behaviour}/></xml>}
+val defaultFormat [body ~ []] =
+    {FormatPanel = fn ctl panel => <xml>{ctl}{panel}</xml>,
+     OpenCtl = fn behaviour => <xml><button value="Open" onclick={behaviour}/></xml>,
+     CloseCtl = fn behaviour => <xml><button value="Close" onclick={behaviour}/></xml>}
                     
-con togglePanel t other_ctx = {PanelState : source panelState,
-                     FormatCtl : formatCtl other_ctx,
-                     Content : t}
+con togglePanel t ctx = {PanelState : source panelState,
+                         FormatCtl : formatCtl ctx,
+                         Content : t}
 
 open Gui
 
-fun create [t ::: Type] [other_ctx:::{Unit}] [other_ctx ~ body] (toXml : gui t (xml ([Body] ++ other_ctx) [] [])) (f : formatCtl other_ctx) (content : t) (startOpen : bool) : transaction (togglePanel t other_ctx) =
+fun create [t ::: Type] [ctx ::: {Unit}] (f : formatCtl ctx) (content : t) (startOpen : bool) : transaction (togglePanel t ctx) =
     state <- source (if startOpen then Open else Closed);
 
     return {PanelState = state,
-            FormatCtl = f,
+            FormatCtl = @f,
             Content = content}
 
-fun render [t ::: Type]  [other_ctx:::{Unit}] [other_ctx ~ body] (_ : gui t (xml ([Body] ++ other_ctx) [] [])) (panel : togglePanel t other_ctx) =
+fun render [t ::: Type] [ctx ::: {Unit}] (_ : gui t ctx) [body ~ ctx] (panel : togglePanel t ctx) =
     let
-        val openCtl = panel.FormatCtl.CloseCtl (set panel.PanelState Closed)
-        val closeCtl = panel.FormatCtl.OpenCtl (set panel.PanelState Open)
+        val format = panel.FormatCtl !
+        val openCtl = format.CloseCtl (set panel.PanelState Closed)
+        val closeCtl = format.OpenCtl (set panel.PanelState Open)
 
         val content = toXml panel.Content
     in
-        panel.FormatCtl.FormatPanel
+        format.FormatPanel
             <xml>
               <dyn signal={c <- signal panel.PanelState;
                            return
@@ -48,4 +51,4 @@
             </xml>
     end
 
-fun gui_togglePanel [t ::: Type]  [other_ctx:::{Unit}] [other_ctx ~ body] (_ : gui t (xml ([Body] ++ other_ctx) [] [])) = mkGui render 
+fun gui_togglePanel [t ::: Type] [ctx ::: {Unit}] (g : gui t ctx) = mkGui (@render g)
--- a/togglePanel.urs	Fri Sep 23 13:30:01 2011 +0200
+++ b/togglePanel.urs	Sat Sep 24 15:47:00 2011 -0400
@@ -3,36 +3,37 @@
  * panel may contain another gui widget as content. *)
 
 con togglePanel :: Type -> {Unit} -> Type
-(* The type of appearing and disappearing panels.  The argument
- * is the type of the content. *)
+(* The type of appearing and disappearing panels.  The arguments
+ * are as for [Gui.gui]. *)
 
-con formatCtl :: {Unit} -> Type 
+con formatCtl = fn ctx :: {Unit} => [body ~ ctx] =>
+                   {FormatPanel : xbody -> xbody -> xml (body ++ ctx) [] [],
+                    (* Allows for formatting the panel.  The first two parameters
+                     * represent "holes" for the control and panel respectively while
+                     * the result should be the desired XML laying out the whole structure.
+                     * The controls can be formatted with the options below.
+                     * The panel part appears and disappears according to the use
+                     * of the controls. *)
+                  
+                    OpenCtl : transaction unit -> xbody,
+                    (* This should accept the transaction representing the opening of
+                     * the panel and produce an XML control having this as action. *)
 
-(* type formatCtl = {FormatPanel : xbody -> xbody -> xbody, *)
-(*                   (\* Allows for formatting the panel.  The first two parameters *)
-(*                    * represent "holes" for the control and panel respectively while *)
-(*                    * the result should be the desired xml laying out the whole structure. *)
-(*                    * The controls can be formatted with the options below. *)
-(*                    * The panel part appears and disappears according to the use  *)
-(*                    * of the controls. *\) *)
-                  
-(*                   OpenCtl : transaction unit -> xbody, *)
-(*                   (\* This should accept the transaction representing the opening of *)
-(*                    * the panel and produce an xml control having this as action. *\) *)
-
-(*                   CloseCtl : transaction unit -> xbody} *)
-(*                   (\* This should accept the transaction representing the closing of *)
-(*                    * the panel and produce an xml control having this as action. *\) *)
+                    CloseCtl : transaction unit -> xbody}
+                    (* This should accept the transaction representing the closing of
+                     * the panel and produce an xml control having this as action. *)
 
 (* Some reasonable default formats for the layout and controls. *)
-val defaultFormat :  other_ctx:::{Unit} -> [other_ctx ~ body] => formatCtl other_ctx
+val defaultFormat : formatCtl []
 
-val create : t ::: Type -> other_ctx:::{Unit} -> [other_ctx ~ body] => 
-    Gui.gui t (xml ([Body] ++ other_ctx) [] []) -> formatCtl other_ctx -> t -> bool -> transaction (togglePanel t other_ctx)
-(* Given instructions for formatting the display, some content and whether to start in
- * the open state get such a togglePanel. *)
+val create : t ::: Type -> ctx ::: {Unit} ->
+    formatCtl ctx (* Formatting instructions *)
+    -> t             (* Enclosed widget *)
+    -> bool          (* Start in open state? *)
+    -> transaction (togglePanel t ctx)
 
-val gui_togglePanel : t ::: Type ->  other_ctx:::{Unit} -> [other_ctx ~ body] => 
-    Gui.gui t (xml ([Body] ++ other_ctx) [] []) -> Gui.gui (togglePanel t other_ctx) (xml ([Body] ++ other_ctx) [] [])
+val gui_togglePanel : t ::: Type -> ctx ::: {Unit}
+                      -> Gui.gui t ctx
+                      -> Gui.gui (togglePanel t ctx) ctx
 (* The togglePanel is itself a widget.  It can be pretty printed to a piece
- * of xml with a use of toXml. *)
+ * of XML with a use of [toXml]. *)