view popupNav.ur @ 18:16447dc6a68c

Introduction of multi-parameter type class for gui components
author Ron de Bruijn <rmbruijn@gmail.com>
date Thu, 22 Sep 2011 19:24:01 +0200
parents 48a4180171b0
children b5432d74841a
line wrap: on
line source
datatype menuState = Open | Closed

type formatCtl = {FormatMenu : xbody -> xbody -> xbody,
                  WrapMenu : xbody -> xbody,
                  OpenCtl : transaction unit -> xbody,
                  CloseCtl : transaction unit -> xbody}

val defaultFormat = {FormatMenu = fn ctl menu => <xml>{ctl}{menu}</xml>,
                     WrapMenu = fn menu => <xml><ul>{menu}</ul></xml>,
                     OpenCtl = fn behaviour => <xml><button value="Open" onclick={behaviour}/></xml>,
                     CloseCtl = fn behaviour => <xml><button value="Close" onclick={behaviour}/></xml>}

open Navbar

con popupNav t = {MenuState : source menuState,
                  FormatCtl : formatCtl,
                  NavBar : navBar t}

fun create [t ::: Type] (f : formatCtl) (m : mode t) (bar : navBar t) : transaction (popupNav t) =
    state <- source Closed;

    return {MenuState = state,
            FormatCtl = f,
            NavBar = bar}

fun render [t ::: Type] (m : mode t) (popup : popupNav t) =
    popup.FormatCtl.FormatMenu
        <xml>
          <dyn signal={c <- signal popup.MenuState;
                       return
                           (case c of
                                Open => <xml>{popup.FormatCtl.CloseCtl (set popup.MenuState Closed)}</xml>
                              | Closed => <xml>{popup.FormatCtl.OpenCtl (set popup.MenuState Open)}</xml>)
                      }/>
        </xml>

        <xml>
          <dyn signal={c <- signal popup.MenuState;
                       return
                           (case c of
                                Open => <xml>{popup.FormatCtl.WrapMenu (navBarToXml popup.NavBar)}</xml>
                              | Closed => <xml/>)
                      }/>
        </xml>