implementation module basicAGEC import StdAGEC, modeGEC, buttonGEC, layoutGEC import StdEnv // Identity nopred n = (DontTest,n) noupdate b ps = (False,b,ps) idxAGEC :: (TgGEC a *(PSt .ps)) a -> AGEC a idxAGEC gGEC j = mkxAGEC gGEC (idBimapGEC j) "idGEC" idAGEC :: a -> AGEC a | gGEC {|*|} a idAGEC j = mkAGEC (idBimapGEC j) "idGEC" idBimapGEC j = { toGEC = \i _ ->i , fromGEC = id , value = j , updGEC = noupdate , pred = nopred } hidAGEC :: a -> AGEC a // Just a store, does not require any GEC ! hidAGEC j = mkAGEC` { toGEC = \i _ -> Hide i , fromGEC = \(Hide i) -> i , value = j , updGEC = noupdate , pred = nopred } "hidGEC" predAGEC :: (a -> (Bool,a)) a -> AGEC a | gGEC {|*|} a predAGEC pred a = mkAGEC { toGEC = toPred , fromGEC = id , value = a , updGEC = noupdate , pred = \a -> case pred a of (True,na) = (TestStoreUpd,na) (False,na) = (TestStore,na) } "predGEC" where toPred nv Undefined = nv toPred nv (Defined oi) = nv // apply GEC applyAGEC :: (b -> a) (AGEC b) -> AGEC a | gGEC {|*|} a & gGEC {|*|} b applyAGEC fba gecb = mkAGEC { toGEC = initgec , fromGEC = \(gecb <|> Display olda) -> fba (^^ gecb) , value = inita , updGEC = \(gecb <|> Display olda) ps -> (True,(gecb <|> Display (fba (^^ gecb))),ps) , pred = nopred } "applyAGEC" where inita = fba (^^ gecb) initgec _ Undefined = gecb <|> Display inita initgec _ (Defined b) = b // convert mode to agec modeAGEC :: (Mode a) -> AGEC a | gGEC {|*|} a modeAGEC mode = mkAGEC { toGEC = mkmode mode , fromGEC = demode , updGEC = noupdate , value = demode mode , pred = nopred } "modeGEC" where demode (Display a) = a demode (Edit a) = a demode (Hide a) = a demode EmptyMode = abort "EmptyMode inspected" mkmode (Display om) nm Undefined = Display nm mkmode (Edit om) nm Undefined = Edit nm mkmode (Hide om) nm Undefined = Hide nm mkmode mode nm (Defined om) = mkmode mode nm Undefined // Integer with up down counter counterAGEC :: a -> AGEC a | gGEC {|*|} a & IncDec a counterAGEC j = mkAGEC { toGEC = \i _ ->(i,Neutral) , fromGEC = fst , value = j , updGEC = \j ps -> (True, updateCounter j,ps) , pred = nopred } "counterGEC" where updateCounter (n,UpPressed) = (n+one,Neutral) updateCounter (n,DownPressed) = (n-one,Neutral) updateCounter any = any // All elements of a list shown in a row horlistAGEC :: [a] -> AGEC [a] | gGEC {|*|} a horlistAGEC list = mkAGEC { toGEC = tohorlist , fromGEC = fromhorlist , value = list , updGEC = noupdate , pred = nopred } ("horlistGEC" +++ len) where tohorlist [] _ = EmptyMode <-> hidAGEC [] tohorlist [x:xs] _ = Edit x <-> horlistAGEC xs fromhorlist (EmptyMode <-> xs) = [] fromhorlist (Edit x <-> xs) = [x: ^^ xs] len = (toString (length list)) // All elements of a list shown in a column vertlistAGEC :: [a] -> AGEC [a] | gGEC {|*|} a vertlistAGEC list = vertlistGEC` True list vertlistGEC` update list = mkAGEC { toGEC = tovertlist , fromGEC = fromvertlist , value = list , updGEC = noupdate , pred = nopred } ("vertlistGEC" +++ len) where tovertlist [] _ = EmptyMode <|> hidAGEC [] tovertlist [x:xs] _ = Edit x <|> vertlistGEC` False xs fromvertlist (EmptyMode <|> xs) = [] fromvertlist (Edit x <|> xs) = [x: ^^ xs] len = (toString (length list)) hor2listAGEC :: a [a] -> AGEC [a] | gGEC {|*|} a hor2listAGEC defaultval list = mkAGEC { toGEC = mkdisplay , fromGEC = fetchlist , value = list , updGEC = \list ps -> (False,adjustdisplay list,ps) , pred = nopred } "list2AGEC" where mkdisplay list Undefined = display list mkdisplay list (Defined _) = display list display list = mlbuttons <|*|> horlistAGEC list where mlbuttons = (Button width "-", Button width "+") width = defCellWidth / 10 adjustdisplay ((_,Pressed) <|*|> alist) = display (^^ alist ++ [defaultval]) adjustdisplay ((Pressed,_) <|*|> alist) = display (init (^^ alist)) adjustdisplay ( _ <|*|> alist) = display (^^ alist) fetchlist (_ <|*|> alist ) = ^^ alist vert2listAGEC :: a [a] -> AGEC [a] | gGEC {|*|} a vert2listAGEC defaultval list = mkAGEC { toGEC = mkdisplay , fromGEC = fetchlist , value = list , updGEC = (\list ps -> (False,adjustdisplay list,ps)) , pred = nopred } "list2AGEC" where mkdisplay list Undefined = display list mkdisplay list (Defined _) = display list display list = mlbuttons <|> vertlistAGEC list where mlbuttons = (Button width "-", Button width "+") width = defCellWidth / 10 adjustdisplay ((_,Pressed) <|> alist) = display (^^ alist ++ [defaultval]) adjustdisplay ((Pressed,_) <|> alist) = display (init (^^ alist)) adjustdisplay ( _ <|> alist) = display (^^ alist) fetchlist (_ <|> alist ) = ^^ alist // list components derive gGEC Actions,Action :: Action = { element_nr :: AGEC Int , goto :: (Button,Button) , actions :: Actions } :: Actions = Append | Insert | Delete | Copy | Paste | Choose listAGEC :: Bool [a] -> AGEC [a] | gGEC {|*|} a listAGEC finite list = mkAGEC { toGEC = mkdisplay , fromGEC = \(_,Hide (_,(list,_))) -> list , value = list , updGEC = \b ps -> (True,edit (parseListEditor b),ps) , pred = nopred } "listGEC" where mkdisplay list Undefined = display 0 list (list!!0) mkdisplay list (Defined(_,Hide (clipboard,(_,i)))) = display i list clipboard display i list clipboard = (mklistEditor list i,Hide (clipboard,(list,i))) mklistEditor list i = list!!ni <|> mkaction ni where mkaction nr = { element_nr = counterAGEC nr , goto = (Button (defCellWidth/2) "0",Button (defCellWidth/2) (toString next)) , actions = Choose } ni | finite = if (i >= 0 && i <= (length list - 1)) i (if (i<0) (length list - 1) 0) | otherwise = if (i >= 0) i 0 next | finite = length list - 1 | otherwise = i + 100 parseListEditor ( listelement <|> {element_nr,goto,actions}, Hide (clipboard,(list,j))) = ((fst goto,snd goto),actions,^^ element_nr,listelement,clipboard,list,j) edit ((first,last),_,i,_,clipboard,list,j) | isPressed first = display 0 list clipboard | isPressed last = display (if finite (length list - 1) (i + 100)) list clipboard | i <> j = display i list clipboard edit (_,Insert,i,_,clipboard,list,_) = display i (insertAt i clipboard list) clipboard edit (_,Append,i,_,clipboard,list,_) = display (i+1) (insertAt (i+1) clipboard list) clipboard edit (_,Delete,i,_,clipboard,list,_) = display i (removeAt i list) clipboard edit (_,Copy,i,listelement,_,list,_) = display i list listelement edit (_,Paste,i,_,clipboard,list,_) = display i (updateAt i clipboard list) clipboard edit (_,_,i,listelement,clipboard,list,_) = display i (updateAt i listelement list) clipboard isPressed Pressed = True isPressed _ = False // All elements of a list shown in a column table_hv_AGEC :: [[a]] -> AGEC [[a]] | gGEC {|*|} a table_hv_AGEC list = mkAGEC { toGEC = \newlist -> mktable newlist , fromGEC = \table -> mklist (^^ table) , value = list , updGEC = noupdate , pred = nopred } "tableGEC" where mktable list _ = vertlistAGEC [(horlistAGEC xs) \\ xs <- list] mklist [] = [] mklist [hor:hors] = [^^ hor: mklist hors] table_vh_AGEC :: [[a]] -> AGEC [[a]] | gGEC {|*|} a table_vh_AGEC list = mkAGEC { toGEC = \newlist -> mktable newlist , fromGEC = \table -> mklist (^^ table) , value = list , updGEC = noupdate , pred = nopred } "tableGEC" where mktable list _ = horlistAGEC [(vertlistAGEC xs) \\ xs <- list] mklist [] = [] mklist [hor:hors] = [^^ hor: mklist hors] // buttons with functions attached calcAGEC :: a [[(Button,a->a)]] -> AGEC a | gGEC {|*|} a calcAGEC a butfun = mkAGEC { toGEC = \a _ -> a <|> table_hv_AGEC buts , fromGEC = \(na <|> _) -> na , value = a , updGEC = \c ps -> (True,calcnewa c,ps) , pred = nopred } "calcGEC" where (buts,funs) = ([map fst list \\ list <- butfun],[map snd list \\ list <- butfun]) calcnewa (na <|> nbuts) = case [f \\ (f,Pressed) <- zip2 (flatten funs) (flatten (^^nbuts))] of [] -> na <|> nbuts [f:_] -> f na <|> table_hv_AGEC buts // Integer with calculator buttons intcalcAGEC :: Int -> AGEC Int intcalcAGEC i = mkAGEC { toGEC = \ni _ -> calcAGEC ni buttons , fromGEC = \b -> ^^ b , value = i , updGEC = noupdate , pred = nopred } "intcalcGEC" where buttons = [ map mkBut [7..9] , map mkBut [4..6] , map mkBut [1..3] , [mkBut 0, (Button (defCellWidth/3) "C",\_->0), (Button (defCellWidth/3) "N", \v -> 0 - v)] ] mkBut i = (Button (defCellWidth/3) (toString i),\v -> v*10 + i) realcalcAGEC :: Real -> AGEC Real realcalcAGEC i = mkAGEC { toGEC = newGEC , fromGEC = \b -> fst (^^ b) , value = i , updGEC = noupdate , pred = nopred } "realcalcGEC" where newGEC ni Undefined = calcAGEC (ni ,Hide (True,1.0)) buttons newGEC 0.0 (Defined oval)= calcAGEC (0.0,Hide (True,1.0)) buttons newGEC ni (Defined oval)= calcAGEC (ni,snd (^^ oval)) buttons buttons = [ map mkBut [7..9] , map mkBut [4..6] , map mkBut [1..3] , [mkBut 0] , [ (Button (defCellWidth/3) ".", \(v,Hide (_,_)) -> (v, Hide (False,1.0))) , (Button (defCellWidth/3) "C", \(_,hide) -> (0.0,Hide (True,1.0))) , (Button (defCellWidth/3) "N", \(v,hide) -> (0.0 - v,hide)) ] ] mkBut i = ( Button (defCellWidth/3) (toString i) , \(v,Hide (cond,base)) -> if cond (v*10.0 + toReal i,Hide (cond,base)) (v+(toReal i/(base*10.0)),Hide(cond,(base*10.0))) ) textAGEC :: a -> AGEC a | gGEC {|*|} a & toString a textAGEC v = mkAGEC (textBimapGEC v) "textGEC" textBimapGEC v = { toGEC = \v _ -> Text (toString v) , fromGEC = \_ -> v , value = v , updGEC = \v pst -> (True,v,pst) , pred = nopred }