Mercurial > gui
view navbar.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 | f17b869fbb71 |
children | d314d2ec3300 |
line wrap: on
line source
style active style last datatype navItem = NavItem of string * url datatype navBar m = NavBar of (list navItem) * (list navItem) (* First list is items before the active item, second list is items at and after the active one. * If the second list is non-empty its head is the active item. Parameter mode is to avoid * double reverses coming from calling printingNavBar. *) type build = unit type print = unit class mode t = navBar t -> xbody (* The case of special treatment for the last one seems common in themes. *) fun mapXLast [a ::: Type] [ctx ::: {Unit}] (f : a -> bool -> xml ctx [] []) (ls : list a) : (xml ctx [] []) = let fun mapXLast' ls = case ls of [] => <xml/> | x :: [] => <xml>{f x True}</xml> | x :: ls => <xml>{f x False}{mapXLast' ls}</xml> in mapXLast' ls end fun navItemToXml css (NavItem (text, url)) = case css of None => <xml><a href={url} title={text}>{[text]}</a></xml> | Some cl => <xml><a class={cl} href={url} title={text}>{[text]}</a></xml> fun navBarToXml' (NavBar (before, after)) = let fun navListToXml checkForLast = mapXLast (fn navItem lst => let val linkXml = navItemToXml None navItem in if checkForLast && lst then <xml><li class={last}>{linkXml}</li></xml> else <xml><li>{linkXml}</li></xml> end) in case after of [] => <xml>{navListToXml True before}</xml> | act :: tl => <xml> {navListToXml False before} {case tl of [] => <xml><li class={last}>{navItemToXml (Some active) act}</li></xml> | _ => <xml> <li>{navItemToXml (Some active) act}</li> {navListToXml True tl} </xml>} </xml> end fun printingNavBar (NavBar (before, after)) = NavBar (List.rev before, List.rev after) fun navBarToXml [t ::: Type] (m : mode t) = m fun navToXml_build (n : navBar build) : xbody = navBarToXml' (printingNavBar n) fun navToXml_print (n: navBar print) : xbody = navBarToXml' n val emptyNavBar = NavBar ([], []) fun mkNavItem text url = NavItem (text, url) fun navAdd navItem navBar = case navBar of NavBar (before, []) => NavBar (navItem :: before, []) | NavBar (before, after) => NavBar (before, navItem :: after) fun navAddActive navItem navBar = case navBar of NavBar (before, []) => NavBar (before, navItem :: []) | NavBar (before, after) => NavBar (List.append after before, navItem :: [])