Difference between revisions of "Extending Phooey"

From HaskellWiki
Jump to navigation Jump to search
(Created)
 
m
 
(One intermediate revision by the same user not shown)
Line 1: Line 1:
A note on how [[Phooey]] is being extended and utilised to develop a non-trivial application [[HGene]]. The key problem being addressed is the 'wiring problem' - How to wire up all the buttons, menus and display widgets so that it all works smoothly and is obvious?
+
A note on how [[Phooey]] is being extended and utilised to develop a non-trivial application [[HGene]]. The key problem being addressed is the 'wiring problem' - How to wire up all the buttons, menus and display widgets so that it all works smoothly and is obvious?
   
 
First a screen shot:
 
First a screen shot:
Line 15: Line 15:
 
</haskell>
 
</haskell>
   
All of these are dynamic and take a source which provides updates on the information that they display.
+
All of these are dynamic and take a source which provides updates on the information that they display. Sourceable is a new class that provides a number of utility functions that are used by recordEditor primarily.
   
 
ListSources and TreeSources are a way of grouping sources.
 
ListSources and TreeSources are a way of grouping sources.
Line 23: Line 23:
 
</haskell>
 
</haskell>
   
The select source is for selections in the widget, and the copy source is hooked into a popup menu action on the widget. This is wired to copy the current item into the clip board.
+
The select source is for selections in the widget, and the copy source is hooked into a popup menu action on the widget. This is wired to copy the current item into the clipboard.
   
An additional 'non visible widget was created to provide persistence. The input source is updated 'a' values.
+
An additional non-visible 'widget' was created to provide persistence. The input source is updated 'a' values.
 
<haskell>
 
<haskell>
 
database :: Sourceable a => (Map Int a) -> Source (Maybe a) -> UI (Source (Map Int a))
 
database :: Sourceable a => (Map Int a) -> Source (Maybe a) -> UI (Source (Map Int a))
Line 32: Line 32:
 
The following is wired together as follows:
 
The following is wired together as follows:
 
<haskell>
 
<haskell>
  +
hgene :: Map Int Person -> UI (Source ())
 
hgene pd = mdo
 
hgene pd = mdo
 
db <- database pd pers
 
db <- database pd pers
Line 44: Line 45:
 
return clipboard
 
return clipboard
 
</haskell>
 
</haskell>
  +
The input map is a map of Person records read from a file.
  +
 
The above could be neater except that mdo and the fromLeft/fromTop functions don't play together nicely. The '!' construct was borrowed from [[PropLang]]. 'orSource' is a function to OR two sources together.
 
The above could be neater except that mdo and the fromLeft/fromTop functions don't play together nicely. The '!' construct was borrowed from [[PropLang]]. 'orSource' is a function to OR two sources together.
   
Line 50: Line 53:
 
Next steps are:
 
Next steps are:
 
* Add more editing actions - add delete and insert buttons to the recordEditor
 
* Add more editing actions - add delete and insert buttons to the recordEditor
* Add a 'write protect' check box which if checked will prevent changes to the data but also grey out the menu buttons which trigger updates.
+
* Add a 'write protect' check box which if checked will prevent changes to the data but also grey out the menu buttons which lead to updates. Similarly grey out 'Paste' button if there is nothing in the clipboard.
 
* Add a way of allowing users of listDisplay and treeDisplay to specify additional buttons for the popup menu.
 
* Add a way of allowing users of listDisplay and treeDisplay to specify additional buttons for the popup menu.
 
* How might undo/redo be handled?
 
* How might undo/redo be handled?

Latest revision as of 12:31, 18 August 2007

A note on how Phooey is being extended and utilised to develop a non-trivial application HGene. The key problem being addressed is the 'wiring problem' - How to wire up all the buttons, menus and display widgets so that it all works smoothly and is obvious?

First a screen shot:

PhooeyHGene1.png

To achieve this the following was done.

A number of widgets were added:

recordEditor :: Sourceable a => Source (Maybe a)  -> UI (Source (Maybe a))
listDisplay :: Sourceable a => Source [a] -> UI (ListSources a)
treeDisplay :: Sourceable a => Source (Tree a) -> UI (TreeSources a)

All of these are dynamic and take a source which provides updates on the information that they display. Sourceable is a new class that provides a number of utility functions that are used by recordEditor primarily.

ListSources and TreeSources are a way of grouping sources.

data TreeSources a = TreeSources { treeSelect :: Source (Maybe a), treeCopy :: Source (Maybe a) }
data ListSources a = ListSources { listSelect :: Source (Maybe a), listCopy :: Source (Maybe a) }

The select source is for selections in the widget, and the copy source is hooked into a popup menu action on the widget. This is wired to copy the current item into the clipboard.

An additional non-visible 'widget' was created to provide persistence. The input source is updated 'a' values.

database :: Sourceable a => (Map Int a) -> Source (Maybe a) -> UI (Source (Map Int a))

The following is wired together as follows:

hgene :: Map Int Person -> UI (Source ())
hgene pd = mdo 
            db <- database pd pers
            (pers,clipboard) <- fromLeft $ do 
                aTree  <- title "Family Tree" $ treeDisplay (liftA asTree db)
                fromTop $ do 
                     pers <- title "Person"  $ recordEditor  (aTree!treeSelect) 
                     aList <- title "Children" $ listDisplay ( liftA2 (\d p -> maybe [] (childrenOf d) p) db (aTree!treeSelect) )
                     pasted <- liftIO ( (aTree!treeCopy) `orSource` (aList!listCopy))
                     clipboard <- title "Clipboard" $ showDisplay pasted
                     return (pers,clipboard)
            return clipboard

The input map is a map of Person records read from a file.

The above could be neater except that mdo and the fromLeft/fromTop functions don't play together nicely. The '!' construct was borrowed from PropLang. 'orSource' is a function to OR two sources together.

I hope it is clear from the above code what the wiring is. If it isn't let me know about this and other suggestions on the talk page

Next steps are:

  • Add more editing actions - add delete and insert buttons to the recordEditor
  • Add a 'write protect' check box which if checked will prevent changes to the data but also grey out the menu buttons which lead to updates. Similarly grey out 'Paste' button if there is nothing in the clipboard.
  • Add a way of allowing users of listDisplay and treeDisplay to specify additional buttons for the popup menu.
  • How might undo/redo be handled?