Presentation is loading. Please wait.

Presentation is loading. Please wait.

Generic Graphical User Interfaces ___________

Similar presentations


Presentation on theme: "Generic Graphical User Interfaces ___________"— Presentation transcript:

1 Generic Graphical User Interfaces ___________
Peter Achten - Marko van Eekelen - Rinus Plasmeijer University of Nijmegen

2 Problem Description How to define Graphical User Interfaces ?
Visual editor : + Look: simply draw or use predefined components - Feel: connecting visual objects to handling code - Gui’s which look and feel depend on run-time data Program API: + Any functionality offered by the OS can be used - Steep learning curve Object I/O: Clean’s platform independent GUI library, (Peter Achten) partly available for Haskell programmers subset ported to Haskell by Karsimir Angelor combine Haskell and Clean programs using Peter Diviansky & Hajnalka Hegedus front end Properties of Object I/O: simple GUI’s are relatively easy to define complicated GUI’s require much more expertise and complicated code

3 Object I/O : Clean IDE (diederik van arkel)

4 Object I/O : Sparkle Theorem Prover (maarten de mol)

5 Problem Description For defining GUI’s we need better tools !
New feature in Clean: kind-indexed Generic Functions small examples : generic equality, map, foldr, : parser, pretty-printer serious stuff : parser generators, e.g. XML-parser : automatic marshalling for calling Web services : GAST automatic testing tool (Pieter Koopman) Can Generic Programming Techniques be used to generate GUI’s ?

6 Overview of the talk Architecture and use of generic Graphical Editor Components Implementation of these GECs using generic programming techniques Conclusions and Future Work

7 Generic GUI Components
Wanted: high-level, flexible, powerful, and reusable GUI components Use generics to generate a Graphical Editor Component that can display any value of any type can be used to edit and change any value of that type takes care of all communication with any (related) visual component use generic specialisation such that it can be customised in an easy way

8 Architecture of a Graphical Editor Component
:: Tree a = Node (Tree a) a (Tree a) | Leaf Location :: Location Initial Value :: t Call-back function :: t  (PSt ps)  (PSt ps) GEC Handle :: GEC_Handle t (PSt ps)

9 Architecture of a Graphical Editor Component
:: Tree a = Node (Tree a) a (Tree a) | Leaf Location :: Location Initial Value :: t Call-back function :: t  (PSt ps)  (PSt ps) GEC Handle :: GEC_Handle t (PSt ps) Demo

10 Architecture of a Graphical Editor Component
generic gGEC t :: Location t (t  *(PSt ps) * (PSt ps)) *(PSt ps)  *(GEC_Handle t *(PSt ps),*(PSt ps)) :: GEC_Handle t pSt = { .... , gecGetValue :: *pSt  *(t, *pSt) , gecSetValue :: t  *pSt  *pSt }

11 Architecture of a Graphical Editor Component
generic gGEC t :: Location t (t  *(PSt ps) * (PSt ps)) *(PSt ps)  *(GEC_Handle t *(PSt ps),*(PSt ps)) :: GEC_Handle t pSt = { .... , gecGetValue :: *pSt  *(t, *pSt) , gecSetValue :: t  *pSt  *pSt } gGEC location (Node Leaf 1 Leaf) pst

12 Examples of GEC’s apply_Two_GECs toBalancedTree [1,5,2,8,3,9] pst
where apply_Two_GECs f a pst # (fGecHndl, pst) = gGEC loc1 (f a) not_used pst # (_, pst) = gGEC loc2 a (set fGecHndl f) pst = pst set handle f na pst = handle .gecSetValue (f na) pst

13 Examples of GEC’s apply_Two_GECs toBalancedTree [1,5,2,8,3,9] pst
where apply_Two_GECs f a pst # (fGecHndl, pst) = gGEC loc1 (f a) not_used pst # (_, pst) = gGEC loc2 a (set fGecHndl f) pst = pst set handle f na pst = handle .gecSetValue (f na) pst

14 Examples of GEC’s apply_Self_GEC balanceTree (Node Leaf 1 Leaf) pst
where apply_Self_GEC f a pst = new_pst (selfGecHndl, new_pst) = gGEC loc (f a) (set selfGecHndlf) pst

15 Examples of GEC’s apply_Self_GEC balanceTree (Node Leaf 1 Leaf) pst
where apply_Self_GEC f a pst = new_pst (selfGecHndl, new_pst) = gGEC loc (f a) (set selfGecHndlf) pst

16 GEC Combinators In this way all kinds of GEC's connections can be made: e.g. application, split, join, mutual recursive, etcetera. GEC-combinators (like parser combinators): collection of high-order operators to making arbitrary circuit of editors, displays, and functions (Arjen van Weelden)

17 Costomizing the look of GEC’s
:: UpDown = UpPressed | DownPressed | Neutral :: Counter a :== (a,UpDown) updateCounter:: (Counter a)  (Counter a) | IncDec a updateCounter (n,UpPressed) = (n+one,Neutral) updateCounter (n,DownPressed) = (n-one,Neutral) updateCounter any = any apply_Self_GEC updateCounter (0,Neutral)

18 Costomizing the look of GEC’s
:: UpDown = UpPressed | DownPressed | Neutral :: Counter a :== (a,UpDown) updateCounter:: (Counter a)  (Counter a) | IncDec a updateCounter (n,UpPressed) = (n+one,Neutral) updateCounter (n,DownPressed) = (n-one,Neutral) updateCounter any = any apply_Self_GEC updateCounter (0,Neutral) gGEC {| (,) |} = …. // just redefine graphical representation for tuples gGEC {| UpDown |} = …. // just redefine graphical representation for UpDown

19 Costomizing the look of GEC’s
:: UpDown = UpPressed | DownPressed | Neutral :: Counter a :== (a,UpDown) updateCounter:: (Counter a)  (Counter a) | IncDec a updateCounter (n,UpPressed) = (n+one,Neutral) updateCounter (n,DownPressed) = (n-one,Neutral) updateCounter any = any apply_Self_GEC updateCounter (0,Neutral) gGEC {| (,) |} = …. // just redefine graphical representation for tuples gGEC {| UpDown |} = …. // just redefine graphical representation for UpDown

20 Composing GEC’s - part 1 Solution: create a “b”-editor that is used as an “a”-value ! :: BimapGEC a b = { toGEC :: a  b , updGEC :: b  b , fromGEC :: b  a , value :: a }

21 Composing GEC’s - part 1 Solution: create a “b”-editor that is used as an “a”-value ! :: BimapGEC a b = { toGEC :: a  b , updGEC :: b  b , fromGEC :: b  a , value :: a } gGEC {| BimapGEC |} = … // convert initial “a”-value to “b”-domain // apply updGEC to any change in “b”-domain // and convert result back to “a”-domain // and store it in value field

22 Composing GEC’s - part 1 :: BimapGEC a b = { toGEC :: a  b
Solution: create a “b”-editor that is used as an “a”-value ! :: BimapGEC a b = { toGEC :: a  b , updGEC :: b  b , fromGEC :: b  a , value :: a } gGEC {| BimapGEC |} = … // convert initial “a”-value to “b”-domain // apply updGEC to any change in “b”-domain // and convert result back to “a”-domain // and store it in value field cntrGEC :: a  BimapGEC a (Counter a) | IncDec a cntrGEC i = { toGEC = \i  (i,Neutral) , updGEC = updateCounter , fromGEC = fst , value = i }

23 Composing GEC’s - part 2 Abstract: Hide the "b"-editor type in an abstract type AGEC But: type needed to generate an editor => hide the editor in type :: AGEC a = E. b : Hidden (BimapGEC a b) (A. ps: GEC_Handle (BimapGEC a b) (PSt ps)) gGEC {| AGEC |} = … // same as BimapGEC, but with hidden editor included

24 Composing GEC’s - part 2 Solution: Hide the "b"-editor type in an abstract type AGEC But: type needed to generate an editor => hide the editor in type :: AGEC a = E. b : Hidden (BimapGEC a b) (A. ps: GEC_Handle (BimapGEC a b) (PSt ps)) gGEC {| AGEC |} = … // same as BimapGEC, but store the editor inside mkAGEC :: (BimapGEC a b)  AGEC a | gGEC{|*|} a & gGEC{|*|} b ^^ :: (AGEC a)  a (^=) infixl :: (AGEC a) a  (AGEC a)

25 Composing GEC’s - part 2 Solution: Hide the "b"-editor type an abstract type AGEC But: type needed to generate an editor => hide the editor in type :: AGEC a = E. b : Hidden (BimapGEC a b) (A. ps: GEC_Handle (BimapGEC a b) (PSt ps)) gGEC {| AGEC |} = … // same as BimapGEC, but store the editor inside mkAGEC :: (BimapGEC a b)  AGEC a | gGEC{|*|} a & gGEC{|*|} b ^^ :: (AGEC a)  a (^=) infixl :: (AGEC a) a  (AGEC a) counterGEC :: a  AGEC a | gGEC{|*|} a & IncDec a calcGEC :: a [[(Button,a a)]]  AGEC a | gGEC{|*|} a idGEC :: a  AGEC a | gGEC{|*|} a hidGEC :: a  AGEC a | gGEC{|*|} a horlistGEC :: [a]  AGEC [a] | gGEC{|*|} a vertlistGEC :: [a]  AGEC [a] | gGEC{|*|} a tableGEC :: [[a]]  AGEC [[a]] | gGEC{|*|} a

26 Composing GEC’s - part 3 :: DoubleCounter a = { cntr1 :: AGEC a, cntr2 :: AGEC a, sum :: AGEC a } doubleCntr:: (DoubleCounter a)  DoubleCounter a | + a doubleCntr cntr = { cntr & sum = cntr.sum ^= ^^ cntr.cntr1 + ^^ cntr.cntr2 } apply_Self_GEC doubleCntr { cntr1 = idGEC 0 , cntr2 = idGEC 0, sum = idGEC 0 }

27 Composing GEC’s - part 5 :: DoubleCounter a = { cntr1 :: AGEC a, cntr2 :: AGEC a, sum :: AGEC a } doubleCntr:: (DoubleCounter a)  DoubleCounter a | + a doubleCntr cntr = { cntr & sum = cntr.sum ^= ^^ cntr.cnt1 + ^^ cntr.cnt2 } apply_Self_GEC doubleCntr { cntr1 = idGEC 0 , cntr2 = idGEC 0, sum = idGEC 0 } apply_Self_GEC doubleCntr { cntr1 = cntrGEC 0, cntr2 = cntrGEC 0, sum = idGEC 0 }

28 Composing GEC’s - part 5 :: DoubleCounter a = { cntr1 :: AGEC a, cntr2 :: AGEC a, sum :: AGEC a } doubleCntr:: (DoubleCounter a)  DoubleCounter a | + a doubleCntr cntr = { cntr & sum = cntr.sum ^= ^^ cntr.cnt1 + ^^ cntr.cnt2 } apply_Self_GEC doubleCntr { cntr1 = idGEC 0 , cntr2 = idGEC 0, sum = idGEC 0 } apply_Self_GEC doubleCntr { cntr1 = cntrGEC 0, cntr2 = cntrGEC 0, sum = idGEC 0 } apply_Self_GEC doubleCntr { cntr1 = cntrGEC 0, cntr2 = calcGEC 0, sum = idGEC 0 }

29 Generic function definitions (Hinze, Jeuring, Alimarine)
One function definition for all thinkable (future) data structures: List a gGEC :: … (List a) … Handle (List a) from List to List Generic Type generic gGEC :: … t … Handle (Generic Type) from Tree to Tree Tree a gGEC :: … (Tree a) … Handle (Tree a)

30 Bimaps between User Type Generic Types
:: List a = Cons a (List a) | Nil Family of Generic types :: UNIT = UNIT :: EITHER a b = LEFT a | RIGHT b :: PAIR a b = PAIR a b :: Type a = Type InfoT a :: Cons a = Constr InfoC a Unit Left Right Pair :: List Cons :: Nil ::

31 Converting User Data Generic Representation
:: List a = Cons a (List a) | Nil Cons 1 Nil Left 1 Unit Pair Right :: List Cons :: Nil ::

32 Converting User Data Generic Representation
:: List a = Cons a (List a) | Nil Cons 1 (Cons 2 Nil) :: List Left Cons :: Pair 1 :: List Left Cons :: Pair 2 :: List Right Nil :: Unit

33 Implementation issues
Problems There is no “type of types” that we can use to represent any type Generic types are actually a family of types A user defined type is converted to a generic type in a lazy way We want to be able to change any data interactively in any order New implementation technique required for interactive applications: For each generic element an Object I/O object (a receiver) is created Objects communicate in Object I/O via message passing primitives All objects offer methods like: GetValue, SetValue t, OpenGUI, CloseGUI, Switch. Communication infrastructure separated from graphical representation

34 Objects that Represent a Generic Value
:: List a = Cons a (List a) | Nil Cons 1 Nil Objects Infrastructure Graphical Representation :: List Left Cons :: Nil :: Pair 1 :: List Right Cons :: Nil :: Unit

35 Objects that Represent a Generic Value
:: List a = Cons a (List a) | Nil Nil Objects Infrastructure Graphical Representation :: List Right Left Cons :: Nil :: Pair Unit 1 :: List Right Cons :: Nil :: Unit

36 Objects that Represent a Generic Value
:: List a = Cons a (List a) | Nil Cons 1 Nil Objects Infrastructure Graphical Representation Graphical Representation :: List Left Cons :: Nil :: Pair Unit 1 :: List Right Cons :: Nil :: Unit

37 Objects that Represent a Generic Value
:: List a = Cons a (List a) | Nil Cons 1 (Cons 2 Nil) Objects Infrastructure Graphical Representation :: List Left Cons :: Nil :: Pair Unit 1 :: List Right Cons :: Nil :: Pair Unit 2 :: List Right Cons :: Nil :: Unit

38 Conclusions & Future Work
Generic functions are very suited for generating interactive applications GEC’s are easy to use building blocks: rapid prototyping, education, debugging Composition of GEC's possible to display/edit any type in a customized way GEC Combinators are available to create any thinkable circuit of editors Circuits can be used as (abstract) editor Future work Include functions in editors using Arjen van Weelden’s OS Shell Use editors in shell to visualize values, directories (browser), anything


Download ppt "Generic Graphical User Interfaces ___________"

Similar presentations


Ads by Google