changeset 8:90be8b8917d5

Add a widget that opens and closes a panel.
author Karn Kallio <kkallio@eka>
date Fri, 17 Jun 2011 10:12:05 -0430
parents 48a4180171b0
children 1e04008eaef7
files examples/togglepanel.ur examples/togglepanel.urp examples/togglepanel.urs gui.ur gui.urs lib.urp togglePanel.ur togglePanel.urs
diffstat 8 files changed, 151 insertions(+), 1 deletions(-) [+]
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/examples/togglepanel.ur	Fri Jun 17 10:12:05 2011 -0430
@@ -0,0 +1,35 @@
+open Gui
+open TogglePanel
+
+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>}
+
+fun main () =
+
+    defaultFormatPanel <- create defaultFormat defaultContent True;
+    otherFormatPanel <- create otherFormat otherContent False;
+
+    return <xml>
+      <head>
+        <title>A panel that can be shown or hidden.</title>
+      </head>
+      <body>
+        <h1>Example using the togglePanel widget.</h1>
+        <p>
+          This is a widget which has a content display panel
+          which can be shown or hidden.
+        </p>
+        <h2>Example of the default format, starting open.</h2>
+        <p>
+          {toXml defaultFormatPanel}
+        </p>
+        <h2>Example of another format, starting closed.</h2>
+        <p>
+          {toXml otherFormatPanel}
+        </p>
+      </body>
+    </xml>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/examples/togglepanel.urp	Fri Jun 17 10:12:05 2011 -0430
@@ -0,0 +1,7 @@
+path META=../../meta
+library ../
+rewrite url Togglepanel/*
+allow url http://*
+prefix http://localhost:8080/
+
+togglepanel
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/examples/togglepanel.urs	Fri Jun 17 10:12:05 2011 -0430
@@ -0,0 +1,1 @@
+val main : unit -> transaction page
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/gui.ur	Fri Jun 17 10:12:05 2011 -0430
@@ -0,0 +1,7 @@
+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
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/gui.urs	Fri Jun 17 10:12:05 2011 -0430
@@ -0,0 +1,14 @@
+(* Gui framework elements common across individual components. *)
+
+class gui
+(* Types of this class describe gui components. *)
+
+val toXml : t ::: Type -> gui t -> t -> xbody
+(* Currently the only thing a gui component can do is be
+ * pretty printed to a piece of xml. *)
+
+val gui_xbody : gui xbody
+(* Xml itself can be a gui component. *)
+
+val mkGui : t ::: Type -> (t -> xbody) -> gui t
+(* How to add components to the gui class. *)
--- a/lib.urp	Fri May 06 23:00:22 2011 -0430
+++ b/lib.urp	Fri Jun 17 10:12:05 2011 -0430
@@ -2,12 +2,13 @@
 
 $/string
 $/list
+gui
 timer
 waitbox
 select
 forms
 datebox
 navbar
+togglePanel
 popupNav
 navigation
-
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/togglePanel.ur	Fri Jun 17 10:12:05 2011 -0430
@@ -0,0 +1,51 @@
+datatype panelState = Open | Closed
+
+type formatCtl = {FormatPanel : xbody -> xbody -> xbody,
+                  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>}
+                    
+con togglePanel t = {PanelState : source panelState,
+                     FormatCtl : formatCtl,
+                     Content : t}
+
+open Gui
+
+fun create [t ::: Type] (toXml : gui t) (f : formatCtl) (content : t) (startOpen : bool) : transaction (togglePanel t) =
+    state <- source (if startOpen then Open else Closed);
+
+    return {PanelState = state,
+            FormatCtl = f,
+            Content = content}
+
+fun render [t ::: Type] (_ : gui t) (panel : togglePanel t) =
+    let
+        val openCtl = panel.FormatCtl.CloseCtl (set panel.PanelState Closed)
+        val closeCtl = panel.FormatCtl.OpenCtl (set panel.PanelState Open)
+
+        val content = toXml panel.Content
+    in
+        panel.FormatCtl.FormatPanel
+            <xml>
+              <dyn signal={c <- signal panel.PanelState;
+                           return
+                               (case c of
+                                    Open => <xml>{openCtl}</xml>
+                                  | Closed => <xml>{closeCtl}</xml>)
+                          }/>
+            </xml>
+
+            <xml>
+              <dyn signal={c <- signal panel.PanelState;
+                           return
+                               (case c of
+                                    Open => <xml>{content}</xml>
+                                  | Closed => <xml/>)
+                          }/>
+            </xml>
+    end
+
+fun gui_togglePanel [t ::: Type] (_ : gui t) = mkGui render 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/togglePanel.urs	Fri Jun 17 10:12:05 2011 -0430
@@ -0,0 +1,34 @@
+(* TogglePanel provides a panel or section of xml which appears and
+ * disappears when the user activates an associated control.  The
+ * panel may contain another gui widget as content. *)
+
+con togglePanel :: Type -> Type
+(* The type of appearing and disappearing panels.  The argument
+ * is the type of the content. *)
+
+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. *)
+
+val defaultFormat : formatCtl
+(* Some reasonable default formats for the layout and controls. *)
+
+val create : t ::: Type -> Gui.gui t -> formatCtl -> t -> bool -> transaction (togglePanel t)
+(* Given instructions for formatting the display, some content and whether to start in
+ * the open state get such a togglePanel. *)
+
+val gui_togglePanel : t ::: Type -> Gui.gui t -> Gui.gui (togglePanel t)
+(* The togglePanel is itself a widget.  It can be pretty printed to a piece
+ * of xml with a use of toXml. *)