From: Andre P. <at...@us...> - 2004-05-16 16:20:26
|
Update of /cvsroot/hoc/www In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv31552 Modified Files: examples.html hoc.css index.html screenshots.html tab-download-selected.png Added Files: download.html Log Message: Miscellaneous webpage updates Added Downloads page Completed Examples page Fix "Selected Downloads" graphic --- NEW FILE: download.html --- <!--#set var="title" value="Download" --> <!--#set var="active-tab" value="Download" --> <!--#include virtual="/templates.hoc/header.shtml" --> <h1>Requirements</h1> <p>As with most Haskell libraries & tools, we currently provide HOC as a build-it-yourself source distribution tarball. To build HOC, you will need:</p> <ul> <li><p>Mac OS X "Panther" 10.3.x. HOC may also work with Mac OS X 10.2 "Jaguar", but has not been tested with it.</p></li> <li><p>The Mac OS X Developer Tools installed.</p> <li><p><a href="http://www.haskell.org/ghc/">GHC</a> (the Glasgow Haskell Compiler) 6.2, or 6.2.1.</p></li> </ul> <p>HOC has also been very lightly tested with Linux and GNUstep, but this is not the main development platform, so please do not expect much to work. :-)</p> <h1>Releases</h1> All HOC releases are made available via Sourceforge, and may also be downloaded from its <a href="http://sourceforge.net/project/showfiles.php?group_id=93369">project releases</a> page. <div class="inner-box"> <table align="center" width="100%" border="0"> <tr valign="top"> <th align="left">Version</th> <th> </th> <th align="left">Brief description</th> </tr> <tr valign="top"> <td nowrap>1.0 RC1 (release notes)</td> <td></td> <td>Major changes: <em>typed interface</em>, memory management, update to GHC and GHCi 6.2 support, documentation (gasp!), and lots more …</td> </tr> <tr valign="top"> <td nowrap><a href="http://prdownloads.sourceforge.net/hoc/HOC020103.tar.bz2?download">0.1</a> (<a href="http://sourceforge.net/project/shownotes.php?release_id=238704">release notes</a>)</td> <td></td> <td>First development snapshot; more an experiment into Template Haskell than anything else (for historical interest only).</td> </tr> </table> </div> <!--#include virtual="/templates.hoc/footer.shtml" --> Index: index.html =================================================================== RCS file: /cvsroot/hoc/www/index.html,v retrieving revision 1.4 retrieving revision 1.5 diff -u -d -r1.4 -r1.5 --- index.html 16 May 2004 08:49:29 -0000 1.4 +++ index.html 16 May 2004 16:20:16 -0000 1.5 @@ -1,61 +1,54 @@ -<!--#set var="title" value="- A Haskell to Objective-C Binding" --> +<!--#set var="title" value="A Haskell to Objective-C Binding" --> <!--#set var="active-tab" value="Home" --> <!--#set var="big-logo" value="yes" --> <!--#include virtual="/templates.hoc/header.shtml" --> - <h1>About</h1> +<h1>About</h1> - <p>HOC is a <strong>H</strong>askell to - <strong>O</strong>bjective-<strong>C</strong> - binding. In a nutshell, it enables you to use - Objective-C objects and frameworks from Haskell, and - also enables you to write Objective-C objects in - Haskell.</p> +<p>HOC is a <strong>H</strong>askell to +<strong>O</strong>bjective-<strong>C</strong> binding. In a nutshell, it +enables you to use Objective-C objects and frameworks from Haskell, and also +enables you to write Objective-C objects in Haskell.</p> - <p>The Haskell interfaces produced by HOC are:</p> +<p>The Haskell interfaces produced by HOC are:</p> - <ul> +<ul> - <li><strong>Strongly Typed</strong>: Take advantage - of Haskell's sound type inference to help you - develop robust, correct Cocoa/GNUstep applications - on your first compile.</li> + <li><strong>Typed</strong>: Take advantage of Haskell's sound type inference + to help you develop robust, correct Cocoa/GNUstep applications on your first + compile.</li> - <li><strong>Automatically Generated</strong>: HOC - comes with an <em>interface generator</em> to - generate Haskell bindings to Objective-C's objects; - use it even with your own custom Objective-C - frameworks!</li> + <li><strong>Automatically Generated</strong>: HOC comes with an <em>interface + generator</em> to generate Haskell bindings to Objective-C's objects; use it +even with your own custom Objective-C frameworks!</li> - <li><strong>Haskell-Friendly</strong>: We make - heavy use of key Haskell features such as type - classes and partial evaluation, to ensure that the - HOC API is as 'Haskell-like' as possible.</li> + <li><strong>Haskell-Friendly</strong>: We make heavy use of key Haskell + features such as type classes and partial application, to ensure that the HOC + API is as 'Haskell-like' as possible.</li> - </ul> +</ul> - <p>You can use HOC to write full-blown GUI - applications using Mac OS X's advanced Cocoa - framework.</p> +<p>You can use HOC to write full-blown GUI applications using Mac OS X's +advanced Cocoa framework.</p> - <h1>News</h1> +<h1>News</h1> - <p><strong>Friday, 14 May 2004</strong>:<br/> HOC - 0.2 released.</p> +<p>Friday, 14 May 2004: <strong>HOC 0.2 released</strong>.</p> - <p><strong>Thursday, 2 Jan 2003</strong>:<br/> HOC - 0.1 released. See the <a - href="http://www.haskell.org/pipermail/glasgow-haskell-users/2003-January/004602.html">full - release announcement</a>, or download it - here.</p> +<p>Thursday, 2 Jan 2003: <strong>HOC 0.1 released</strong>. See the <a + href="http://www.haskell.org/pipermail/glasgow-haskell-users/2003-January/004602.html">full + release announcement</a>, or <a + href="http://prdownloads.sourceforge.net/hoc/HOC020103.tar.bz2?download">download + it</a> here.</p> - </ul> - <h1>License</h1> +</p> - <p>In the spirit of the Haskell and Mac OS X open-source - communities, HOC is provided under the liberal BSD license.</p> +<h1>License</h1> + +<p>In the spirit of the Haskell and Mac OS X open-source communities, HOC is +provided under the liberal BSD license.</p> <!--#include virtual="/templates.hoc/footer.shtml" --> Index: tab-download-selected.png =================================================================== RCS file: /cvsroot/hoc/www/tab-download-selected.png,v retrieving revision 1.1.1.1 retrieving revision 1.2 diff -u -d -r1.1.1.1 -r1.2 Binary files /tmp/cvsFAh8F3 and /tmp/cvsgzWiaV differ Index: hoc.css =================================================================== RCS file: /cvsroot/hoc/www/hoc.css,v retrieving revision 1.2 retrieving revision 1.3 diff -u -d -r1.2 -r1.3 --- hoc.css 16 May 2004 08:42:15 -0000 1.2 +++ hoc.css 16 May 2004 16:20:16 -0000 1.3 @@ -29,6 +29,15 @@ align: center; } +ul { + /* same as inner-box */ + margin: 12px 12px; + padding: 12px 35px 12px 35px; + border: 1px solid #BDBDBD; + background-image: url("bg-stripes-dark.png"); + background-repeat: repeat; +} + li { margin: 8px 0; } Index: screenshots.html =================================================================== RCS file: /cvsroot/hoc/www/screenshots.html,v retrieving revision 1.1 retrieving revision 1.2 diff -u -d -r1.1 -r1.2 --- screenshots.html 16 May 2004 08:42:15 -0000 1.1 +++ screenshots.html 16 May 2004 16:20:16 -0000 1.2 @@ -8,8 +8,7 @@ <h2>A Text Editor</h2> <p>Here's the canonical GUI text editor application, implemented in about 50 -lines of Haskell code. The code for this is distributed in HOC's -<code>Samples/</code> source distribution.</p> +lines of Haskell code.</p> <p class="center"> <a href="screenshots/Editor.png" class="plain"> @@ -51,7 +50,7 @@ lines for the expression parsing code, and ~50 lines for the GUI.</p> <p> -<table align="center" border="0"> +<table align="center" border="0" cellpadding="4"> <tr> <td> <img src="screenshots/ExpressionParser.png" class="bordered"> Index: examples.html =================================================================== RCS file: /cvsroot/hoc/www/examples.html,v retrieving revision 1.1 retrieving revision 1.2 diff -u -d -r1.1 -r1.2 --- examples.html 16 May 2004 08:42:15 -0000 1.1 +++ examples.html 16 May 2004 16:20:16 -0000 1.2 @@ -3,32 +3,74 @@ <!--#include virtual="/templates.hoc/header.shtml" --> -<h1>Cocoa Examples</h1> +<h1>Adding a GUI to an Expression Parser</h1> -<h2>Adding a GUI to an Expression Parser</h2> +<p>You've probably seen many examples of Haskell GUI libraries which show you +how to create a simple graphical application that has a cute little button +which prints "Hello, world!" when you click on it. Well, we'd show you that, +but the truth is it's so easy to do with Cocoa that it'd just be boring (as +well as being useless). So, let's do something a bit more practical with our +first example: our mission is to put a simple GUI around a basic Haskell +program, which is something you're more likely to be interested in.</p> -<p>You've probably seen many examples of Haskell GUI libraries -which show you how to create a simple graphical application with -menus, and a cute little button that prints "Hello, world!" when -you click on it:</p> +<p>For this quick tour, let's write a GUI program that allows a user to type in +arithmetic expressions (e.g. <code>2+5</code> or <code>69*33/3+15</code>), and +print its result. Something like this will do:</p> -TODO: Insert picture +<p> +<table align="center" border="0" cellpadding="4"> + <tr> + <td> + <img src="screenshots/ExpressionParser.png" class="bordered"> + </td> -<p>Well, we'd show you that, but the truth is it's so easy to do -with Cocoa that it'd just be boring. (Really!) So, let's do -something a bit more practical with our first example: put a simple -GUI around a basic Haskell program, which is something you're more -likely to be interested in.</p> + <td> + <img src="screenshots/ExpressionParser_error.png" class="bordered"> + </td> + </tr> +</table> +</p> -<p>Let's assume that you've written a useful Haskell module: say -a simple calculator (or <em>expression parser</em>). To do this, -we could use Daan Leijen's most excellent <a - href="http://www.cs.uu.nl/~daan/parsec.html">Parsec</a> parser -combinator library. In fact, Parsec comes with such excellent -documentation that it even gives <a +<h2>Preface</h2> + +<p>In comparison to other GUI toolkits available for Haskell, there's a bit +more of a learning curve to use HOC for writing GUIs, because Cocoa enforces +good design by separating your application logic cleanly using design patterns +such as <a + href="http://developer.apple.com/documentation/Cocoa/Conceptual/ObjCTutorial/chapter02/chapter_2_section_3.html">Model-View-Controller</a> +(which we will use in this example). So, while this quick tour may seem a bit +longer than you expect, the really good news is that Cocoa's design patterns +<em>scale</em> very well: writing a small GUI may take 50-100 lines of code, +but writing a much bigger, fancy GUI with lots of widgets and controls may only +take 100-200 lines rather than 500-1000, because much of the GUI code is +handled for you by Interface Builder's target-action/outlet design. In Mac OS +X Panther, you can even use <a + href="http://developer.apple.com/documentation/Cocoa/Conceptual/CocoaBindings/CocoaBindings.html">Cocoa + Bindings</a> with your Haskell application, and cut down your code size even +further.</p> + +<p>Note that HOC is also a lower-level binding than higher-level GUI toolkits +such as <a + href="http://www.cs.chalmers.se/ComputingScience/Research/Functional/Fudgets/">Fudgets</a> +or even <a href="http://wxhaskell.sourceforge.net/">wxHaskell</a>: it is really +a bridge which enables you to use Objective-C objects from Haskell (and thus +gives you much more functionality than simply being able to write GUIs!). In +the future, we hope to layer a higher-level interface on top of HOC to provide +a more functional API, so you're not forced into imperative style of coding as +you would write Objective-C code. Even so, the Cocoa framework is so well +designed that the resulting imperative code is still far shorter than it would +be compared to most other frameworks .</p> + +<h2>The Model: an Arithmetic Expression Parser</h2> + +<p>Our first step is to write the arithmetic expression parser. To do this, we +could use Daan Leijen's most excellent <a + href="http://www.cs.uu.nl/~daan/parsec.html">Parsec</a> parser combinator +library. In fact, Parsec comes with such excellent documentation that it even +gives <a href="http://www.cs.uu.nl/~daan/download/parsec/parsec.html#Expressions">example - code</a> which shows how to do this. So, imagine the following -code is in an <code>ExpressionParser.hs</code> Haskell module:</a> + code</a> which shows how to do this. So, imagine the following code is in an +<code>ExpressionParser.hs</code> Haskell module:</a> <div class="inner-box"> <pre>module ExpressionParser @@ -67,8 +109,160 @@ </div> <p>So, you have a working expression parser. Unfortunately, you have to to run -this from GHCI. Wouldn't it be nicer if you could run it from a Haskell GUI -instead?</p> +this from GHCi to use it. You could write a command-line interface to it, but +wouldn't it be nicer if you could run it from a Haskell GUI instead?</p> + +<h2>The View: a GUI for the Expression Parser</h2> + +<p>Now that you've written the model, it's time to write the <em>view</em>, +which lets the user interact with the model by clicking on buttons, selecting +menu items, and all that fancy GUI stuff. Luckily, the Cocoa framework on Mac +OS X makes this quite trivial: instead of writing tedious layout code to draw +the view, set up the menus, etc., we use <a + href="http://developer.apple.com/tools/interfacebuilder/">Interface + Builder</a>, a GUI design tool. Briefly, the steps involved with Interface +Builder are:</p> + +<ul> + + <li>Drag the text fields and buttons from the Cocoa Controls palette into + your window.</li> + + <li>Tell Interface Builder that you'll be writing a class called + <code>EPController</code> to handle events such as the user clicking on + buttons. To do this, you simply subclass and instantiate the + <code>NSObject</code> class (the root of all of Cocoa's classes) in Interface + Builder's Classes window.</li> + + <li>Add two <em>outlets</em> to the <code>EPController</code> class, which + are pointers to the two text fields in the window. This enables your + controller class to read the user's typed-in expression from the first text + field, and write its output to the second text field.</li> + + <li>Add an <em>action</em> to the <code>EPController</code> class, which + contains the expression-evaluation code that will run when the user clicks on + the "Evaluate" button (or presses the <em>Enter</em> key in the input text + field).</li> + + <li><em>Connect</em> the text fields to <code>EPController</code>'s outlets + by Ctrl-dragging from the instantiated <code>EPController</code> object to + the text field, and setting the outlet appropriately. You also want to + connect the Evaluate button and text field entry to + <code>EPController</code>'s, again by Ctrl-dragging from them to the + instantiated <code>EPController</code> object icon.</li> + +</ul> + +<p>That's it: your view's done. You could write all this code programmatically +of course, but why bother? Interface Builder allows you to add GUIs to your +code very rapidly, and also handles issues such as window re-sizing elegantly. +(This is often quoted as a reason to manually write code—so you can use +a geometry manager—rather than using a GUI designer tool. Truth is, +Cocoa and Interface Builder's re-sizing controls are so easy and powerful that +you'll very rarely have to write any geometry management code—I've +<em>never</em> had to, even when writing a full-fledged media player +application!) Here's a screenshot of what Interface Builder will look like as +you're designing your view with it:</p> + +<p class="center" align="center"> +<a href="screenshots/ExpressionParser_view.png" class="plain"> + <img src="screenshots/ExpressionParser_view.png" width="90%"> +</a> +</p> + +<p class="center" align="center"> +<a href="screenshots/ExpressionParser_view.png"> + (Click to enlarge.) +</a> +<p> + +<h2>The Controller: Handling User Interaction</h2> + +<p>Now that you've written the model and the view, it's time to write the +<em>controller</em>, which the view sends messages to in response to user +interactions. The controller is responsible for calling the appopriate +functions in the model, and delivering the model's outputs to the view. In +this case, that means delivering the expression the user typed in to the +<code>ExpressionParser</code> module's parsing code, taking the parser's +output, and displaying that back in the view.</p> + +<p>HOC enables you to write the controller's code in pure Haskell: first, you +need to write a <code>Selectors.hs</code> file which declares all the +<em>selectors</em> (method names) that you will be using:</p> + +<div class="inner-box"> +<pre>{-# OPTIONS -fglasgow-exts #-} + +module Selectors where + +import AppKit.NSButton + +$(declareSelector "evaluateExpression:" [t| forall a. NSButton a -> IO () |]) +</pre> +</div> + +<p>This enables better static checking of method names, and prevents scenarios +such as pondering why your method wasn't being called when you actually +misspelled it (which can happen with Objective-C). After this, it's time to +write the controller code:</p> + +<div class="inner-box"> +<pre>{-# OPTIONS -fglasgow-exts #-} + +module EPController where + +import Cocoa hiding (parse) +import ExpressionParser +import Selectors +import Text.ParserCombinators.Parsec (parse) + +$(declareClass "EPController" "NSObject") + +$(exportClass "EPController" "ep_" + [ Outlet "expressionEntry" [t| NSTextField () |] + , Outlet "evaluation" [t| NSTextField () |] + , InstanceMethod Selectors.info_evaluateExpression ]) + +obj #. var = obj # getIVar var + +ep_evaluateExpression _ self = do + -- Get the expressionEntry outlet text field from this object, and get + -- what the user typed as a Haskell string + expression <- self #. _expressionEntry >>= stringValue >>= haskellString + -- Parse the expression + case (parse expr "" expression) of + Left err -> + -- Parsing returned an error: display it in the output text field + self #. _evaluation >>= setStringValue (toNSString $ "Error " ++ show err) + Right answer -> + -- Parsing was successful: display the answer + self #. _evaluation >>= setStringValue (toNSString $ show answer) +</pre> +</div> + +<p>That's it: you've just added a pretty GUI to your expression parser. Once +again, here's what the result looks like:</p> + +<p> +<table align="center" border="0" cellpadding="4"> + <tr> + <td> + <img src="screenshots/ExpressionParser.png" class="bordered"> + </td> + + <td> + <img src="screenshots/ExpressionParser_error.png" class="bordered"> + </td> + </tr> +</table> +</p> + +<p>Of course, this is only a quick overview on how to use HOC: this brief look +at HOC is expanded upon in the HOC <a + href="documentation.html">documentation</a>, where we describe the exact +steps involved in building this arithmetic expression parser. We hope that +this example gives you an idea of how you can use HOC to easily implement a GUI +for your existing Haskell applications!</p> <!--#include virtual="/templates.hoc/footer.shtml" --> |