1 / 96

Generic Graphical User Interfaces for the WEB ___________

Generic Graphical User Interfaces for the WEB ___________. Rinus Plasmeijer - Peter Achten University of Nijmegen www.cs.kun.nl/~clean. Snapshot from Clean's CD shop. Overview of the talk. Clean’s generic G raphical E ditor C omponents

aoife
Download Presentation

Generic Graphical User Interfaces for the WEB ___________

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. GenericGraphical User Interfacesfor the WEB___________ Rinus Plasmeijer - Peter Achten University of Nijmegen www.cs.kun.nl/~clean

  2. Snapshot from Clean's CD shop

  3. Overview of the talk • Clean’s generic Graphical Editor Components • Architecture Web applications <–> Architecture normal Clean application • Generation of Html code • Automatic Generation of Html code for any Clean type • Automatic Generation of simple interactive forms for any Clean type • Separating Data from Views allowing to make any kind of form • Implementation • Arrows • Conclusion & Future Research

  4. Overview of the talk • Clean’s generic Graphical Editor Components • Architecture Web applications <–> Architecture normal Clean application • Generation of Html code • Automatic Generation of Html code for any Clean type • Automatic Generation of simple interactive forms for any Clean type • Separating Data from Views allowing to make any kind of form • Implementation • Arrows • Conclusion & Future Research

  5. Graphical Editor Components in Clean • Start :: *World  *World • Start world = startFormCircuit myEditor [1,5,2] world • myEditor= edit "List" >>> arr toBalancedTree >>> display "Balanced Tree"

  6. mutual dependent arrows • myEditor = feedback ( arr toPounds >>> • edit “Pounds” >>> • arr toEuros >>> • edit“Euros” )

  7. Graphical Editor Components • Given any type, an editor can be generated for it automatically • Editors can be connected: the output of one can be used as input for another • Editors even may be mutual dependent • One can make "circuits" of editors using special combinators (arrows) • Even editors for higher order types can be generated (editing of functions) • You can easily define your favourite "look" for any type (buttons, menu's) • Great for rapid prototyping: no low level IO programming needed

  8. Overview of the talk • Clean’s generic Graphical Editor Components • Architecture Web applications <–> Architecture normal Clean application • Generation of Html code • Automatic Generation of Html code for any Clean type • Automatic Generation of simple interactive forms for any Clean type • Separating Data from Views allowing to make any kind of form • Implementation • Arrows • Conclusion & Future Research

  9. Architecture "normal" Clean Application OS Clean Application

  10. Architecture Clean application for the Web Browser MyPage + info Web Server MyPage.exe + info htmlcode htmlcode Clean Application

  11. Architecture Clean application for the Web Browser Web Server

  12. How to achieve Graphical Editor Components for the Web ? • We need to be able to generate Html code • For any Clean type, an Html Form has to be generatedautomatically • Deal with interaction: a change made in a Form has to be handled automatically • We need to be able to connect Forms • We have to be able to make sophisticated Forms with any look we like • Clean application is a pure function: it "just" need its previous state

  13. Overview of the talk • Clean’s generic Graphical Editor Components • Architecture Web applications <–> Architecture normal Clean application • Generation of Html code • Automatic Generation of Html code for any Clean type • Automatic Generation of simple interactive forms for any Clean type • Separating Data from Views allowing to make any kind of form • Implementation • Arrows • Conclusion & Future Research

  14. Generating Html Code • An Algebraic Data Type has been defined isomorphic with Html, Style sheets • :: Html = Html Head Rest • :: Head = Head [HeadAttr] [HeadTag] • :: Rest = Body [BodyAttr] [BodyTag] • :: BodyTag = A [A_Attr] [BodyTag] • … • | Var [Std_Attr] String • | Stable [Table_Attr] [[BodyTag]] • | BodyTag [BodyTag] | EmptyBody • any value of Html ADT can be converted to real Html-code, using a generic function • generic gHpra :: *File a  *File

  15. Playing with the world of web pages • An interactive Clean program has type: • Start:: *World  *World • An interactive Clean Web program has type: • myPage:: *HSt  (Html,*HSt) • So, a wrapper function is defined: • doHtml:: (*HSt  (Html,*HSt))  *World  *World

  16. General Structure of a Clean Web application • module example • import StdEnv, StdHtml • Start world = doHtmlhelloWorldPage world • helloWorldPage hst • = mkHtml "Hello World Example" • [Txt "Hello World"] hst • mkHtml title tags hst = (Html (Head [`Hd_Std [Std_Title s]] []) • (Body [] tags) • ,hst)

  17. General Structure of a Clean Web application • helloWorldPage hst • = mkHtml "Hello World Example" • [Txt "Hello World"] hst

  18. What did we gain with our ADT definition ? • Disadvantage • Slightly more verbose than plain Html, caused by restrictions of an ADT • Advantage • We have at least the expressive power of Html • Everything is typed, so many html errors cannot be made anymore • ADT is a handy Html grammar for beginners • Full power of Clean, let's use it….

  19. Overview of the talk • Clean’s generic Graphical Editor Components • Architecture Web applications <–> Architecture normal Clean application • Generation of Html code • Automatic Generation of Html code for any Clean type • Automatic Generation of simple interactive forms for any Clean type • Separating Data from Views allowing to make any kind of form • Implementation • Arrows • Conclusion & Future Research

  20. Add ability to show any type • toHtml:: a  BodyTag | gForm {|*|} a • toHtml converts any Clean type to Html code using the generic function gForm

  21. Add ability to show any type showBalancedTreePage hst = mkHtml "Balanced Tree" [ H1 [] "Balanced Tree" , toHtml (fromListToBalTree [1..5]) ] hst :: Tree a = Node (Tree a) a (Tree a) | Leaf derive gFormTree

  22. Overview of the talk • Clean’s generic Graphical Editor Components • Architecture Web applications <–> Architecture normal Clean application • Generation of Html code • Automatic Generation of Html code for any Clean type • Automatic Generation of simple interactive forms for any Clean type • Separating Data from Views allowing to make any kind of form • Implementation • Arrows • Conclusion & Future Research

  23. Automatic creation of Interactive Forms • mkEditForm :: FormId d *HSt  *(Form d, *HSt) | gHTML d • :: FormId • = { id :: String // id *uniquely* identifying the form • , lifespan :: Lifespan // lifespan of form • , mode :: Mode // editable or not • } • :: Lifespan • = Persistent // form will live "forever" in a file • | Session // form will live a session long • | Page // form will live a page long • :: Mode • = Edit // an editable form • | Display // a non-editable form • :: Form d • = { changed :: Bool // the user has edited the form • , value :: d // current value in data domain (the feel) • , form :: [BodyTag] // html code to create the form (the look) • }

  24. Example: an editable record • :: Person = { name :: String • , address :: String • , city :: String • } • initPerson = { name = "", address = "" , city = "" } • personPage hst • # (person,hst) = mkEditForm (nFormId "person") initPerson hst • = mkHtml "Person" • [ H1 [] "Person" • , BodyTag person.form • ] hst • nFormId s = {id = s, lifespan = Page, mode = Edit} • ndFormId s = {id = s, lifespan = Page, mode = Display}

  25. Example: an editable tree • treePage hst • # (tree,hst) = mkEditForm (nFormId "tree") (Node Leaf 1 Leaf) hst • = mkHtml "Simple Tree" • [ H1 [] "Simple Tree" • , BodyTag tree.form • ] hst

  26. Example: an editable list converted to a balanced tree • listToBalancedTreePage hst • # (list,hst) = mkEditForm (nFormId "list") [1] hst • = mkHtml "List to Balanced Tree" • [ H1 [] "List to Balanced Tree" • , BodyTag list.form • , Br • , toHtml (fromListToBalTree list.value) • ] hst

  27. Example: showing a list as an vertical table • vertlistForm:: FormId [a] *HSt  (Form [a],*HSt) | gHTML a • vertlistForm_ [] hst = ({changed = False,value = [] ,form = [] },hst) • vertlistFormformid [x:xs] hst • # (nxs,hst) = vertlistFormformid xs hst • # (nx, hst) = mkEditForm nformid x hst • = ( {changed = nxs.changed || nx.changed • ,value = [nx.value : nxs.value] • ,form = [nx.form <||> nxs.form] • } ,hst ) • where • nformid = {formid & id = formid.id +++ toString (length xs)}

  28. Example: taken the sum of a table • vertTablePage hst • # (vtable,hst) = vertlistForm (nFormId "vertlist") [1..5] hst • = mkHtml "Vertical Table" • [ H1 [] "Vertical Table" • , BodyTag vtable.form • , toHtml (sum vtable.value) • ] hst

  29. Simple Spreadsheet • spreadsheet hst • # (tablef, hst) = table_hv_Form (nFormId "table") (inittable 8 10) hst • # (rowsumf,hst) = vertlistForm (ndFormId "rsum") (rowsum tablef.value) hst • # (colsumf,hst) = horlistForm (ndFormId "csum") (colsum tablef.value) hst • # (totsumf,hst) = mkEditForm (ndFormId "tsum") (sum (rowsum tablef.value)) hst • = mkHtml "Spreadsheet" • [ H1 [] "Simple Spreadsheet Example: " • , tablef.form <=> rowsumf.form • , colsumf.form <=> totsumf.form • ] hst • rowsum table = map sum table • colsum table = map sum (transpose table) • transpose table = [[table!!i!!j \\ i <- [0..(length table) - 1]] • \\ j <- [0..length (table!!0) - 1] • ] • inittable n m = [ [i..i+n] \\ i <- [0,n+1 .. n*m+1]]

  30. Simple Spreadsheet

  31. Spreadsheet using toHtml(Form) • spreadsheet hst • # (table, hst) = table_hv_Form (nFormId "table") (inittable 8 10) hst • = mkHtml "Spreadsheet" • [ H1 [] "Simple Spreadsheet Example: " • , table.form <=> rowsumF table.value • , colsumF table.value <=> totsumF table.value • ] hst • rowsumF table = toHtmlForm (vertlistForm (ndFormId "rsum") (rowsum table)) • colsumF table = toHtmlForm (horlistForm (ndFormId "csum") (colsum table)) • totsumF table = toHtmlForm (mkEditForm (ndFormId "tsum") (sum (rowsum table))) • toHtmlForm :: (*HSt  *(Form a,*HSt))  [BodyTag] | gHTML a

  32. Spreadsheet defined in Monadic Style • spreadsheet • = table_hv_Form (nFormId "table") (inittable 8 10) >>= \table • vertlistForm (ndFormId "rsum") (rowsum table.value) >>= \rowsum • horlistForm (ndFormId "csum") (colsum table.value) >>= \colsum • mkEditForm (ndFormId "tsum") (sum (rowsum table.value)) >>= \totsum • mkHtmlM "Spreadsheet" • [ H1 [] "Spreadsheet Example: " • , table.form <=> rowsum.form • , colsum.form <=> totsum.form • ] • :: *HStM a :== *HSt -> *(a, *HSt) • (>>=) infixr 5 :: (HStM .a) (.a -> HStM .b) -> HStM .b • mkHtmlM:: String [BodyTag] -> HStM Html

  33. What did we gain so far ? • Advantage • We obtain an editor for free for (almost) any Clean type • No low level Html form handling required • We want to do more • Editable forms which contents depend on value of other forms • Make a complete separation between "data" and "view" • One function that can fulfil all wishes

  34. Overview of the talk • Clean’s generic Graphical Editor Components • Architecture Web applications <–> Architecture normal Clean application • Generation of Html code • Automatic Generation of Html code for any Clean type • Automatic Generation of simple interactive forms for any Clean type • Separating Data from Views allowing to make any kind of form • Implementation • Arrows • Conclusion & Future Research

  35. Separation of Data Model and View Model • Instead of • mkEditForm:: FormId d *HSt  *(Form d, *HSt) | gHTML d • We define the more general function • mkViewForm :: FormId d (ViewBimap d v) *HSt  *(Form d, *HSt) | gHTML v • :: ViewBimap d v • = { toForm :: d (Maybe v)  v // converts data to view domain • , updForm :: Bool v  v // update, True when form edited • , fromForm :: Bool v  d // back to data domain • , resetForm :: Maybe (v  v) // reset view option • }

  36. mkEditForm is just a simple variant of mkViewForm • mkEditForm:: FormId d *HSt  (Form d,*HSt) | gHtml d • mkEditForm formid data hst = mkViewForm formid data • { toForm = toFormid • , updForm = \_ d  d • , fromForm = \_ d  d • , resetForm = Nothing} hst • toFormid d Nothing = d • toFormid d (Just old_d) = old_d

  37. Counter example • counterForm:: FormId a *HSt  (Form a,*HSt) | +, -, one, gHtml a • counterForm name i hst = mkViewForm name i counterView hst • counterView = { toForm = \n  toFormid (n,down,up) • , updForm = updCounter • , fromForm = \_ (n,_,_)  n • , resetForm = Nothing • } • where • updCounter _ (n,Pressed,_) = (n - one,down,up) • updCounter _ (n,_,Pressed) = (n + one,down,up) • updCounter _ else = else • down = LButton (defpixel / 6) "-" • up = LButton (defpixel / 6) "+"

  38. Counter Example • counterExamplePage hst • # (counter1,hst) = counterForm (nFormId "counter1") 0 hst • # (counter2,hst) = counterForm (nFormId "counter2") 0 hst • = mkHtml "Counter Example" • [ H1 [] "Counter Example" • , BodyTag counter1.form • , BodyTag counter2.form • , toHtml (counter1.value + counter2.value) • ] hst

  39. mkViewForm variants: mkSelfForm for self correcting forms • mkSelfForm:: FormId d (d  d) *HSt  (Form d,*HSt) | gHtml d • mkSelfForm formid initdata cbf hst = mkViewForm formid data • { toForm = toFormid • , updForm = update • , fromForm = \_ d  d • , resetForm = Nothing} hst • where • update True newval = cbf newval • update _ val = val

  40. Self Balancing Tree • selfBalancingTreePage hst • # (balancedtree,hst) = mkSelfForm (nFormId "BalancedTree") • (fromListToBalTree [0]) balanceTree hst • = mkHtml "Balanced Tree" • [ H1 [] "Balanced Tree" • , BodyTag balancedtree.form • ] hst

  41. mkViewForm variants: a Store • mkStoreForm:: FormId d (d  d) *HSt  (Form d,*HSt) | gHtml d • mkStoreForm formid data cbf hst • = mkViewForm formid data { toForm = toFormid • , updForm = \_ d  cbf d • , fromForm = \_ d  d • , resetForm = Nothing} hst

  42. Page Visitors Counter • pageCount hst • # (pagecount,hst) = mkStoreForm (pFormId "pageCount") 0 (\n  inc n) hst • = mkHtml "Balanced Tree" • [ H1 [] "Page Count" • , Txt ("You are visitor nr: " +++ toString pagecount.value) • ] hst • pdFormId s = {id = s, lifespan = Persistent, mode = Display}

  43. Types with special views • :: Button • = Pressed // button pressed • | LButton Int String // label button, size in pixels, label of button • | PButton (Int,Int) String // picture button, (height,width), ref to picture • :: CheckBox • = CBChecked String // checkbox checked • | CBNotChecked String // checkbox not checked • :: RadioButton • = RBChecked String // radiobutton checked • | RBNotChecked String // radiobutton not checked • :: PullDownMenu • = PullDown (Int,Int) (Int,[String]) // pulldownmenu (number visible,width) • (item chosen,menulist)

  44. Calculator • TableFuncBut:: FormId [[(Button, a  a)]] *HSt  (Form (a  a) ,*HSt) • calcbuttons :: [[(Button, (Int,Int)  (Int,Int)]] • calcbuttons = [ [(but "7",set 7), (but "8",set 8), (but "9",set 9) ] • , [(but "4",set 4), (but "5",set 5), (but "6",set 6) ] • , [(but "1",set 1), (but "2",set 2), (but "3",set 3) ] • , [(but "0",set 0), (but "C",clear) ] • , [(but "+",app (+)), (but "-",app (-)), (but "*",app (*))] • ] • where • set ni (mem,i) = (mem, i*10 + ni) • clear (mem,i) = (mem,0) • app fun (mem,i) = (fun mem i , 0) • but i = LButton (defpixel / 3) i

  45. Calculator • calculator hst • # (calcfun,hst) = TableFuncBut (nFormId "calcbut") calcbuttons hst • # (display,hst) = mkStoreForm (ndFormId "display") (0,0) calcfun.value hst = mkHtml "Calculator" • [ H1 [] "Calculator Example: " • , mem display <.||.> input display • , toBody calcfun • ] hst • where • mem display = toHtml (fst (display.value)) • input display = toHtml (snd (display.value))

  46. Simple Login Administration (I) • :: Login • = { loginName :: String • , password :: String • } • loginHandler hst • # (login,hst) = mkEditForm (sFormId "login") (mklogin "" "") hst • # (loginDatabase,hst) = loginStore id hst • # (page,hst) = if (isMember login.value loginDatabase.value) • (memberPage login hst) • (loginPage login hst) • = mkHtml "login test" • [BodyTag page] hst • where • loginStore upd hst = mkStoreForm (pFormId "logindatabase") [] upd hst • mklogin name password = { loginName = name, password = password}

  47. Simple Login Administration (II) • loginPagelogin hst • # (addlogin,hst) = addLoginButton login.value hst • # (loginDatabase,hst) = loginStore (addLoginlogin.valueaddlogin.changed) hst • | isMember login.value loginDatabase.value = memberPage login hst • = ( [ Txt "Please log in ..." • , Br, Br • , BodyTag login.form • , Br • , BodyTag addlogin.form • ], hst) • addLoginButton value hst = ListFuncBut False (formid "addlogin") addbutton hst • addbutton = [ (LButton defpixel "addLogin", id)] • formid = if (value.loginName <> "" && value.password <> "") nFormId ndFormId

  48. Simple Login Administration (III) • memberPagelogin hst • = ( [ Txt ("Welcome " +++ login.value.loginName) • ], hst)

  49. Overview of the talk • Clean’s generic Graphical Editor Components • Architecture Web applications <–> Architecture normal Clean application • Generation of Html code • Automatic Generation of Html code for any Clean type • Automatic Generation of simple interactive forms for any Clean type • Separating Data from Views allowing to make any kind of form • Implementation • Arrows • Conclusion & Future Research

  50. Architecture Clean application for the Web Browser Web Server File Server Clean Application Html Code + Serialized State of Forms Serialized State of Forms + Changed input Serialized State of Forms

More Related