Application screenshots
+At the moment, only small to medium sized programs have been written in wxHaskell and +this page shows some of them. If you know about an interesting wxHaskell +application, write us and it may be presented here too :-)
+This year, everyone had delivered a functioning turtle language. Special credit goes to +Christof Douma for the nicest embedding of the turtle language using monads: +
++do forward 100 + right 90 + forward 100 + ... ++ +
Unfortunately, besides a good mark, there is no prize for the best embedding :-) +Although it was a close finish with the teenage ninja turtles, +this year's bag of M&M's for the best drawing goes to +Niels van der Velden and Mart Kolthof for their flower-power submission! They can pick +up their price at the office of Daan Leijen (B023). +
+ +Flower power from Niels van der Velden and Mart Kolthof
+The teenage ninja turtle of Guno Heitman en Niels Reyngoud
+The parallel turtles of Ingmar Brouns, Peter Nagel
+Christof's klavertje vier
+Recursive flowers of Robert van Herk
+At the moment, only small to medium sized programs have been written in wxHaskell and +this page shows some of them. If you know about an interesting wxHaskell +application, write us and it may be presented here too :-)
+Dazzle. +Dazzle is a Bayesian belief network editor that is developed +by the Decision Support System group of Utrecht University. +Dazzle uses the Smile C++ library, developed by +the Decision Systems Laboratory of Pittsburgh University, to leverage +standard Bayesian belief network algorithms. The interface is highly specialized, featuring custom +controls for representing multi-dimensional statistical nodes. +
+ICFP Programming Contest 2003 & 2004 – the technology behind the winners. +[www-2003 +,www-2004]. +wxHaskell 0.7 was used in the ICFP 2004 programming contest +by team Dunkosmiloolump to create an "ant" +simulator – and they won the contest! An early version of wxHaskell has been used in the ICFP 2003 contest +by Team Dom +to create a graphical editor for solving the tracks. The entry is interesting as they created the interface in +a single day, and also used C code fragments to directly program the wxWidgets repaint handler.
+
+ ![]() |
+
+ ![]() |
+
Track editor (click on image to enlarge) | +Ant simulator (click on image to enlarge) |
hsReversi [www-page]. +Lucas Torrećo, Emanoel Barreiros, Hilda Borborema, and Keldjan Alves have written a reversi game with wxHaskell. It is possible to play versus CPU or versus another human player. The window appearance can be changed at any time in game, using the "skins" feature. It is available in portugese only. +
+GeBoP [www-page]. +Maarten Löffler has written GeBoP, the General Board games Player. This application uses a generic game +engine to host 8 different games that can be played against the computer. A tree control is used to visualize +the state of the game engine, and an MDI interface is used to display several games simultaneously. Source is +available on the GeBoP website. +
Proxima +[www-page]. +The Proxima generic structure editor is written by Martijn Schrage. +Proxima is part of an ongoing research project to combine both structured editing operations with free editing +(and if you look closely at the screenshot you can see that the variables in scope, the types, and even values +are automatically computed).
+![]() |
+ ![]() |
+
MacOS X (click on image to enlarge) | Windows XP (click on image to enlarge) |
+Functional Forms [www-page].
+Sander Evers has made a library for wxHaskell to concisely create forms: dialogs that display and
+edit a set of values. All edit actions are automatically checked and converted to an appropiate Haskell form.
+
+
+
+
HCPN [www-page]. +Claus Reinke has made an experimental graphical editor for +Haskell Coloured Petri Nets (HCPN).
+HPView [www-page]. +Wei Tan has made a graphical heap profile viewer for GHC with wxHaskell, called HPView. It is intended as an interactive alternative to the hp2ps utility (included in GHC), which allows zooming and filtering of graph columns.
+Haskell on the cover of a magazine! wxHaskell was featured in a two-page article in the october 2003 version of L'informaticien, a popular French PC magazine. The article has been written by Frédéric Mazué. Here are some screenshots:
+You are going to implement an embedded domain specific language to +describe turtle graphics. The goal of this assignment is to give you a +feel for the design issues involved with an embedded language and experience +with first-class IO values and graphical user interfaces.
+The idea is that there is a turtle that carries a pencil that can draw on a +canvas. The turtle is knows just two primitive commands:
+right d +forward n+
That is, it can go forward
for n
units, or it can
+turn right
over d
degrees. For example, we can draw a
+square using the following commands:
forward 50 +right 90 +forward 50 +right 90 +forward 50 +right 90 +forward 50+ +
You can find more examples and information at the following webpage: http://el.www.media.mit.edu/groups/logo-foundation/logo/turtle.html + +
+ +It is encouraged to do this assignment with the wxHaskell 0.2 library +at http://wxhaskell.sourceforge.net. +Unfortunately, this means that you need ghc 6.01 and administrator rights. +This implies that only people with access to a computer that they own, can do +this assignment with wxHaskell. I can probably provide a few people (up +to 4) with a dedicated computer in the ST-lab in the CGN building. + +
+ +If you really need to work on a standard lab machine, you can also do the +assignment using the SOE graphics library for Hugs: http://cvs.haskell.org/Hugs/pages/downloading.htm. +See their documentation about how to open windows and do drawing. + +
+ +Implement the turtle language as an embedded language in Haskell. The +language is embedded in Haskell as a single module that exports abstract data +types and associated operations. You should consider carefully what operations +you want to expose to the user so that programming with turtles becomes +convenient. For example, you could start with an interface like this:
+data Drawing+
forward :: Double -> Drawing +right :: Double -> Drawing +...+
Of course, this is just an example and you can define another kind of
+interface, as long as it has the same basic functionality. In both cases, you
+need to be able to defend why you have chosen for a particular approach. Other
+turtle commands you should implement are penup
and pendown
,
+to either hide or show the trail of the turtle, color
that changes
+the color of the pen, and stop
to end a
+program.
Other commands are somewhat easier to add: backward
, left
,
+and repeat
. Why are these easier to add?
You should also provide an execute
function that takes a turtle
+program and runs it. Think about how general your function should be: should it
+open its own window and take of everything itself, or should it be parameterised
+by a window or drawing functions? Explain why you have chosen a particular
+approach. Think also about a coordinate system: do you use pixels as units? what
+happens on a resize of the window? Note that your turtle should start in
+the center, going upwards.
You implementation doesn't have to show a turtle: it just has to show how the +final result looks like. Check your implementation by implementing the spiral +example from the http://el.www.media.mit.edu/groups/logo-foundation/logo/turtle.html + + webpage.
++to spiral :size :angle + if :size > 100 [stop] + forward :size + right :angle + spiral :size + 2 :angle +end
Of course, you would implement your examples in a separate module than the Turtle
+module.
Instead of drawing the result of a turtle drawing, show how the drawing is
+drawn. You don't have to show a turtle itself, just showing the effect of the
+turtle moving around is good enough. You could use a timer
together
+with a mutable variable and repaint
to animate the drawing. Look at
+the wxHaskell bouncing balls example for an illustration of their usage.
+If you use SOE graphics, you can probably use sleep
(or Win32.sleep
)
+to achieve the same effect.
Once this works, you can also try to implement the forever
+operator.
Implement parallel composition to your interface. One possible interface +could be:
+(<|>) :: Drawing -> Drawing -> Drawing+
When you execute the drawing p <|> q
there will be two
+turtles, one drawing p, the other drawing q in parallel.
Think about what happens after a parallel composition finishes? Is the +operator commutative? and associative? Why would these laws be important to a +programmer?
+ +1. You could add a save construct to the language. +
save :: Program -> Program ++The meaning of the program save p is to recall the current position of +the turtle and to continue with the program as if nothing happened. But as soon +as we are done, we return to the saved state and execute the program p +from that point. When you have several save statements in your program, +all of them should be saved and later executed, but you may decide yourself in +what order. +
2. You could add a pause construct to your language. In this +case, you will add a button with the text "Continue" to the graphical +interface. This button is normally inactive, but when the turtle program +executes the pause command, it halts, and the "Continue" button +becomes active. When the user clicks on the "Continue" button, the +program continues and the continue button becomes inactive again. +
3. Similar to 2., but instead of an explicit pause, you have a +combinator called stepping. +
stepping :: Program -> Program ++The meaning of the program stepping p is: execute p as normal, but +the user is required to click the "Continue" button at every step +during the execution of p. +
4. Add the commands showturtle and hideturtle to your +language, which toggle between having a turtle picture shown when drawing the +pictures or not. A variant of this allows different turtle bitmaps and maybe +even a background image. One can then describe simple animations. Also see the +section "Up and Away" from the above mentioned turtle web page. +
5. Add a way to your language of finding out information about for +example, where the turtle currently is, or if the user clicks or drags the mouse. It +should of course be possible to then use this information in your turtle +programs. +
6. Invent your own extension to the turtle language. By extension I +mean something that cannot be implemented in terms of the existing language +constructs.
+Create a cool picture that uses some or all the extensions that you have +made. To keep up a long standing tradition, the team with the best demo, +subjectively chosen by me :-), wins a bag of M&M's.
+ +Answer and motivate the following questions:
+You should send your submission before Sunday, 28 September, 23:59h to +daan@cs.uu.nl with the subject afp submission. In the body, you should put the names of your team and +the student numbers. You should attach the following (zipped/tarred) files:
+Turtle.hs
that contains your embedding of the turtle
+ language.Main.hs
that contains your examples. If I run main
,
+ I should see the coolest example you have made.report
that contains the answers to the
+ questions and comments and motivations about your implementation.Success! +
To build wxHaskell on windows, you need the cygwin environment to provide essential unix
+tools necessary to run configure
and make
, i.e. sh
, test
, sed
, gnu make
etc. The cygwin environment provides these tools
+on windows and these notes describe how to properly install these tools. To compile wxWidgets properly
+without using Microsoft Visual C++, you also need to install the mingw compiler, as described in the
+section after installing cygwin. Please note that the compilation of wxWidgets also works without
+the mingw compiler, but all programs linked with it will fail mysteriously!
+
Download the setup program from the cygwin site. When
+prompted for the packages to install, click also on the Devel
and Archive
+node until they show install
(instead of default
).
After installation, you need to set a few environment variables. In the following description you
+should replace the variable $cygwin
with your cygwin
+installation directory (c:\cygwin
by default). Set your local environment variables
+(via start/settings/control panel/system/advanced/environment variables
) to the
+following values:
PATH
: $cygwin\bin
and
+$cygwin\usr\local\lib
. On my
+system this looks like:
++PATH = %PATH%;c:\programs\cygwin\bin;c:\programs\cygwin\usr\local\lib;... ++
SHELL
to $cygwin\bin\sh
.MAKE_MODE
to UNIX
.HOME
to your preferred home directory, for example: c:\bgates
.Next, we need to ensure that the default shell is bash. Go to the $cygwin/bin
+directory and rename sh.exe
to sh-org.exe
. Next, make a copy of bash.exe
+and name it sh.exe
.
We also set some default settings for bash. Create a file .bashrc
in your
+home directory with the following lines:
+export CVS_RSH=ssh +export PS1='\[\033[1;31m\]\w\$ \[\033[0m\]' +export PATH=$PATH:/usr/local/bin:. ++ +
Finally, you can start a bash
command prompt, either via the cygwin icon or by typing
+bash
on the windows command line. To access the c:
drive conveniently
+from the bash command prompt, you can mount the /c
directory. You only have to
+do this once:
+> mount c: /c ++ +
From now on, you can access the c:
drive via /c
, for example: cd /c/windows
In order to compile dynamic link libraries that should work with GHC, we also need the minimalist +gnu compiler, called mingw. Compiling with this compiler has the extra advantage that the +resulting executables or no longer dependent on the cygwin dll.
+ +Download the latest compiler from the mingw site. There +are a lot of packages available but you only need the +MinGW package. +
+ +After installation, you still need to adapt the cygwin environment in order to use the
+mingw compiler by default. In the following description, you should replace the $mingw
+variable with the mingw installation directory (c:\mingw
by default).
$mingw/bin
directory to the start of your PATH
environment
+variable. It is important that it comes before the $cygwin/bin
directory. On my
+system this looks like:
++PATH = %PATH%;c:\programs\mingw\bin;c:\programs\cygwin\bin;... ++
$cygwin/etc/profile
and add the $mingw/bin
directory
+to the exported PATH
. You should use a unix style directory name. On my system
+this looks like:
++export PATH="/c/programs/mingw/bin:/usr/local/bin:/usr/bin:/bin:$PATH" ++
To see if your installation was succesfull, you should retrieve the version +of the C compiler and see if the result contains the word mingw:
++~$gcc --version +gcc.exe (GCC) 3.2 (mingw special 20020817-1) +Copyright (C) 2002 Free Software Foundation, Inc. +This is free software; see the source for copying conditions. There is NO +warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. ++ +
In constrast, if you have done something wrong, you would see something like:
++~$/c/programs/cygwin/bin/gcc --version +gcc (GCC) 3.2 20020927 (prerelease) +Copyright (C) 2002 Free Software Foundation, Inc. +This is free software; see the source for copying conditions. There is NO +warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. ++
Even though graphical applications on MacOS X look great, it is a still +a developers nightmare to get them working :-). Furthermore, the MacOS X port of wxWidgets +is the least mature and still has some quirks. This page describes how to circumvent some of the pitfalls.
+ +Haskell applications need the readline
library which is not installed by
+default on the MacOS X. Arthur Baars provided
+a simple installer for the readline library.
Graphical applications generated with GHC do not work if executed directly – they need to be
+upgraded into MacOS X applications. The macosx-app
script does this for you. It
+is provided with binary releases and resides in the bin
directory of
+a source release. Creating a program now consists of the following steps:
+> cd samples/wx +> ghc -package wx -o helloworld HelloWorld.hs +> /usr/local/wxhaskell/bin/macosx-app -v helloworld +> open helloworld ++
Due to complicated MacOS X restrictions, graphical wxHaskell applications do not work directly
+when used from GHCi. Fortunately, Wolfgang Thaller has kindly provided an ingenious
+Haskell
+module that solves this problem. Just import the (compiled) module EnableGUI
+in your program and issue the following command to run main
from your GHCi prompt:
+> enableGUI >> main ++
The dynamic link libraries used by wxHaskell can not always be found. If your +application seems to start (the icon bounces) but terminates mysteriously, you need +to set the dynamic link library search path to the wxHaskell library directory. For example:
++> setenv DYLD_LIBRARY_PATH /usr/local/wxhaskell/lib ++
The advantage of using Visual C++ is that the resulting libraries are smaller and faster +than the gnu compiled ones. Furthermore, the debug version provides for automatic detection +of memory leaks in the wxWidgets libraries and you get a warning when forgetting to deallocate +wxWidgets objects. The drawback is that the configure scripts are not used and you will need +to set some options manually.
+ +We use the wxWidgets provided workspace directly:
+$wxwin/src/wxWidgets.dsw
workspace.
+Select menu "Build/Set active configuration
" and select "wxWidgets - win32 release
" to build the (static) library. After compilation, you can also select "wxWidgets - win32 debug
" to build
+the debug version.$wxwin/build/msw/wx.dsw
workspace. Select
+menu "Build/Batch build
" and select all configurations by using the mouse and the shift
key,
+when you click a marker, all configurations are deselected. Next you manually select the "Release" and "Debug" versions of all projects and press "Build". Afterwards, press "Save All" to save all your mouse clicking work :-)After building wxWidgets, you need to run configure
for the wxHaskell library.
+> cd $wxhaskell +> ./configure --with-msc ++ +
If you want to use the debug version of the library, use the --wxc-libname
option too.
+> ./configure --with-msc --wxc-libname=wxcd ++ +
After configuration, first go the $wxhaskell/wxc
directory. Here, you need to adapt the wxc-version.dsp
project to reference the correct wxWidgets directory. Open the .dsp
file in an editor and replace all occurrences of "..\..\wxWindows-2.4.2
" (or "..\..\wxWindows-2.5.1
") or by the installed wxWidgets directory, i.e. $wxwin
.
+
After adapting the project file, you can open the workspace wxc/wxc-version.dsw
+and build the release and debug versions of the C wrapper library.
And finally! – you can run make
in the $wxhaskell
directory to build the
+Haskell libraries.
+> cd $wxhaskell +> make +> make install ++ +
In principle we recommend the use of binary releases, but +wxHaskell also has a build system to compile directly from sources. The build process has +been specialized for three main platforms:
+wxHaskell has been build successfully on (at least) the following configurations:
+(Unfortunately, there are still build problems on Sun Solaris – we are looking for build volunteers :-)
+Ensure you have a recent GHC compiler – version 6.4 is recommended (but any version >= 5.04.3 will work). In principle, any Haskell98 compiler that supports the standard FFI libraries will also work.
+ +gcc
compiler, which is part of the Apple
+Developer Tools. These tools are shipped with Panther and are installed by invoking Applications/Installers/Developer Tools/Developer.mdmg
.
+Next, you should install the latest stable version (currently 2.6.0) of wxWidgets
+for your platform. We assume in this guide that the variable $wxwin
points to your
+wxWidgets installation directory, for example: ~/dev/wxGTK-2.6.0
.
If you have a source release of wxHaskell,
+just unpack it in a suitable directory. In the
+following descriptions, we assume that the variable $wxhaskell
points to your
+installation directory, for example: ~/dev/wxhaskell
.
+
If you do not have a source release of wxHaskell, you need to check it out from the cvs repository. CVS creates a
+wxhaskell
directory for you; we assume in the following example that
+your $wxhaskell
directory will be ~/dev/wxhaskell
.
+> cd ~/dev +> cvs -d:pserver:anonymous@cvs.sourceforge.net:/cvsroot/wxhaskell login +> cvs -z3 -d:pserver:anonymous@cvs.sourceforge.net:/cvsroot/wxhaskell co -P wxhaskell ++ +
You can check out a specific release version using the -r
flag:
+> cvs -z3 -d:<as above> co -P -r wxhaskell-0-4 wxhaskell ++ +
You might need to try a few times as sourceforge has a limit on the +number of people that can log in anonymously.
+windows-msc: this section describes how to build wxWidgets +using standard gnu tools -- there is a separate section on +building the library with Microsoft Visual C++ on windows.
+ +According to the wxWidgets preferred installation, create a mybuild
directory in the
+wxWidgets directory, and run configure
and make
from that directory (and take the time to get some coffee :-).
+
> cd $wxwin +> mkdir mybuild +> cd mybuild +> ../configure --disable-shared +> make +> make install ++ +Notes: +
configure
, to enable certain advanced features of wxHaskell:
+--disable-shared
to build a static library (recommended for wxHaskell version >= 0.7).--with-odbc
to enable database access.--with-opengl
to enable the openGL canvas.--enable-sound
to enable playback of wave audio files. (--enable-wave
on
+ wxWidgets 2.4.x)make install
; this installs a utility called
+wx-config
that is used by the other projects.+../configure --with-gtk --enable-gtk2 --disable-unicode +
rehash
after make install
+in order to add the wx-config
utility to the search path cache.$wxwin\include\wx\msw\popupwin.h
+is not properly copied when make install
is run, and you need to
+copy it manually to the install directory (for example /usr/local/include/wx/msw
).
+(if this file is not copied, C compilation of wxHaskell will fail).
+Now try out a few samples of wxWidgets to see if it all works correctly:
++> cd samples/controls +> make +> ./controls ++ +
Note that you build from the local samples
directory that resides
+in the mybuild
directory.
And also try if wx-config
works too:
+> wx-config --version ++
First, we configure the library for your platform.
+ ++> cd $wxhaskell +> ./configure ++ +Notes: +
configure
first with the --help
option. This also shows the values of command-line options and is an excellent check to see
+if everything is set up correctly. If the settings do not make sense, it might be that the wx-config
+utility is not found – maybe you have forgotten to run make install
on wxWindows?--with-opengl
option to configure
if you specified this
+flag when configuring wxWidgets (or you will get link errors).prefix
option of configure: ./configure --prefix=/usr/local
. Any directory that is on your library search path will do.wxcore/src/Graphics/UI/WXCore/WxcObjects.hs
you need to switch the parameters to newForeignPtr
on line 172. In the file wx/src/Graphics/UI/WX/Controls.hs
you need to replace the import of Data.Typeable
by Data.Dynamic
.After configuration, we build and install the libraries (and take some more time to drink more coffee :-).
++> make +> make install ++ +Notes: +
make install
fails when building the ghc package, you might not have administrator priviliges. Either run it as an administrator or configure in such a way that you use a local ghc package:
++./configure --package-conf=~/mypackages+
make doc
.
+make uninstall
.
+If everything succeeded, you should be able to run a test program.
++> cd samples/wx +> ghc -package wx -o helloworld HelloWorld.hs +> ./helloworld ++ +
Notes:
+You can also run the examples from GHCi – a great development environment!
++> ghci -package wx BouncingBalls.hs +> main ++ +
Notes:
+Have fun!
+ -- Daan Leijen.
"Do not ask yourself what wxHaskell can do for you, but what you can do for wxHaskell" :-)
+However, it is hard to find out which features are particularly interesting, the +hardness of certain tasks, and whether you are duplicating work done by others. +This page tries to remedy this situation by giving a list of good starting points for +contributing to wxHaskell. +
+If you feel like doing one of these items, please notify the maintainer of wxHaskell, or +send an e-mail to the wxHaskell mailing list, so that no effort is accidently duplicated. +
+wxStopWatch
or MDI windows. You only need to add code to
+the WX library and the WX.Controls
library can serve as a
+typical example of useful abstractions.ico
on windows, a mac icon on MacOS X), together
+with some generic function that searches for the most appropiate image. Another
+facet of this task could be the use of resource bundles, or ways to internationalize
+the application.
+There are more desirable features that are planned for upcoming releases. However +most of these are somewhat harder to do as they require more knowledge about the +entire wxHaskell project. However, if you feel that you really need one of these +items, feel free to try! +
There are no development releases yet. All the sources are only available +through the cvs repository. +
+wxHaskell is an open-source project, and you are invited to help developing wxHaskell! (see the +contribute page for more information.) Currently +the development team consists of:
+Furthermore, the following people have contributed to the wxHaskell project:
+wxHaskell is a project hosted on sourceforge. The sources are +available on the sourceforge cvs repository. +Currently, wxHaskell hosts four subprojects. +
+IO
monad and state is handled through mutable
+variables.(All of the following links are cheap to follow)
+You can download either a source or binary distribution. The +documentation and samples are normally included in binary distributions. After installation, you should try some of the +samples to see if everything works as expected:
++> cd samples/wx +> ghc -package wx -o helloworld HelloWorld.hs +> ./helloworld ++ +
You can also use GHCi – a great development environment for GUI's! (Unfortunately, GHCi only works well on Windows platforms at the moment)
++> ghci -package wx HelloWorld.hs +*Main> main ++ +
See the documentation for more information about wxHaskell.
+All of these files are also directly available from the +sourceforge project page.
+ +The file name of a binary release contains the version of the wxWidgets toolkit that has been used, +and the version of the Haskell compiler was used to build wxHaskell. Make sure that +you have the same version of the compiler installed, for example ghc6.4. All packages have ODBC and OpenGL support. Documentation and samples are not included with Linux rpm packages.
+ +wxhaskell-0.9.4\bin\wxhaskell-register.bat
program to register the wxHaskell package. To uninstall, you can click on wxhaskell-0.9.4\bin\wxhaskell-unregister.bat
and than remove the wxhaskell-0.9.4
directory.
+
+Note:If you have an older version of wxHaskell installed, please remove it before installing this version.
+Older releases can be uninstalled by clicking on wxhaskell-unregister.bat
.
+
/usr/local/wxhaskell
and registers them with ghc. To test the installation,
+you can run the following commands from the samples/wx
+directory:
++> ghc -package wx HelloWorld.hs -o hello +> /usr/local/wxhaskell/bin/macosx-app -v hello +> open hello ++ +
It is recommended to read the notes on using wxHaskell with MacOS X.
+
All of these files are also directly available from the +sourceforge project page.
+ +The file name of a binary release contains the version of the wxWidgets toolkit that has been used, +and the version of the Haskell compiler was used to build wxHaskell. Make sure that +you have the same version of the compiler installed, for example ghc6.2.2. All packages have ODBC and OpenGL support. Documentation and samples are not included with Linux rpm packages.
+ +wxhaskell-0.9\bin\wxhaskell-register.bat
program to register the wxHaskell package. To uninstall, you can click on wxhaskell-0.9\bin\wxhaskell-unregister.bat
and than remove the wxhaskell-0.9
directory.
+
+Note:If you have an older version of wxHaskell installed, please remove it before installing this version.
+Older releases can be uninstalled by clicking on wxhaskell-unregister.bat
.
+
/usr/local/wxhaskell
and registers them with ghc. To test the installation,
+you can run the following commands from the samples/wx
+directory:
++> ghc -package wx HelloWorld.hs -o hello +> /usr/local/wxhaskell/bin/macosx-app -v hello +> open hello ++ +
It is recommended to read the notes on using wxHaskell with MacOS X.
+
All of these files are also directly available from the +sourceforge project page.
+ +The file name of a binary release contains the version of the wxWidgets toolkit that has been used, +and the version of the Haskell compiler was used to build wxHaskell. Make sure that +you have the same version of the compiler installed, for example ghc6.2.1. All packages +have ODBC and OpenGL support. Documentation and samples are not included with Linux rpm packages.
+ +wxhaskell-0.8\bin\wxhaskell-register.bat
program to register the wxHaskell package. To uninstall, you can click on wxhaskell-0.8\bin\wxhaskell-unregister.bat
and than remove the wxhaskell-0.8
directory.
+
+Note:If you have an older version of wxHaskell installed, please remove it before installing this version.
+Older releases can be uninstalled by clicking on wxhaskell-unregister.bat
.
+
/usr/local/wxhaskell
and registers them with ghc. To test the installation,
+you can run the following commands from the samples/wx
+directory:
++> ghc -package wx HelloWorld.hs -o hello +> /usr/local/wxhaskell/bin/macosx-app -v hello +> open hello ++ +
It is recommended to read the notes on using wxHaskell with MacOS X.
+
Note: The installer for MacOS X has been build using a developer release of wxWidgets.
+All of these files are also directly available from the +sourceforge project page.
+ +The file name of a binary release contains the version of the wxWidgets toolkit that has been used,
+and the version of the haskell compiler was used to build wxHaskell. Make sure that
+you have the same version of the compiler installed, for example ghc6.2.1
. All packages
+have ODBC and OpenGL support. Documentation and samples are not included with Linux rpm packages.
wxhaskell-0.7\bin\wxhaskell-register.bat
program to register the wxHaskell package. To uninstall, you can click on wxhaskell-0.7\bin\wxhaskell-unregister.bat
and than remove the wxhaskell-0.7
directory.
+
+Note:If you have an older version of wxHaskell installed, please remove it before installing this version.
+Older releases can be uninstalled by clicking on wxhaskell-unregister.bat
.
+
/usr/local/wxhaskell
and registers them with ghc. To test the installation,
+you can run the following commands from the samples/wx
+directory:
++> ghc -package wx HelloWorld.hs -o hello +> /usr/local/wxhaskell/bin/macosx-app -v hello +> open hello ++ +
It is recommended to read the notes on using wxHaskell with MacOS X.
+
Note: The installer for MacOS X has been build using a developer version of wxWidgets and might be unstable (for example, applications are required to have a menu bar).
+All of these files are also directly available from the +sourceforge project page.
+ +The file name of a binary release contains the version of the haskell compiler that you need. Make sure that
+you have the same version of the compiler installed, for example ghc6.2
. Documentation and samples are
+included.
wxhaskell-0.6\bin\wxhaskell-register.bat
program to register the wxHaskell package. To uninstall, you can click on wxhaskell-0.6\bin\wxhaskell-unregister.bat
and than remove the wxhaskell-0.6
directory.
+
+Note:If you have an older version of wxHaskell installed, please remove it before installing this version.
+Older releases can be uninstalled by clicking on wxhaskell-unregister.bat
.
+
See below for an MacOS X installer for wxHaskell version 0.4.
+Package patched on February 19, 2004
+All of these files are also directly available from the +sourceforge project page.
+ +The file name of a binary release contains the version of the haskell compiler that you need. Make sure that
+you have the same version and compiler installed, for example ghc6.2
. Documentation and samples are
+included.
wxhaskell-0.5\bin\wxhaskell-register.bat
program to register the wxHaskell package. To uninstall, you can click on wxhaskell-0.5\bin\wxhaskell-unregister.bat
and than remove the wxhaskell-0.5
directory.
+
+Note:If you have an older version of wxHaskell installed, please remove it before installing this version.
+Older releases can be uninstalled by clicking on wxhaskell-unregister.bat
.
+
All of these files are also directly available from the +sourceforge project page.
+ +The file name of a binary release contains the version of the haskell compiler that you need. Make sure that
+you have the same version and compiler installed, for example ghc6.0.1
. You need to download the documentation and samples separately.
wxhaskell-0.4\bin\wxhaskell-register.bat
program to register the wxHaskell package. To uninstall, you can click on wxhaskell-0.4\bin\wxhaskell-unregister.bat
and than remove the wxhaskell-0.4
directory.
+
+Note:If you have an older version of wxHaskell installed, please remove it before installing this version.
+Older releases can be uninstalled by clicking on wxhaskell-uninstall.bat
in the ghc directory.
+
/usr/local/wxhaskell
and registers them with GHC.
+To test the installation, you can run the following commands from the samples/wx
+directory:
++> ghc -package wx HelloWorld.hs -o hello +> /usr/local/wxhaskell/bin/macosx-app -v hello +> ./hello ++ +
It is recommended to read the notes on using wxHaskell with MacOS X.
+
All of these files are also directly available from the +sourceforge project page.
+ +The file name of a binary release contains the version of the haskell compiler that you need. Make sure that
+you have the same version and compiler installed, for example ghc6.0.1
. You need to download the documentation and samples separately. Binary releases can be installed right over older releases.
c:\ghc\ghc-6.0.1
.
+After unzipping, click on the newly created wxhaskell-register.bat
program to register
+the wxHaskell package. To uninstall, you can click on wxhaskell-uninstall.bat
.
+/usr/local/wxhaskell
and registers them with GHC.
+To test the installation, you can run the following commands from the samples/wx
+directory:
++> ghc -package wx HelloWorld.hs -o hello +> /usr/local/wxhaskell/bin/macosx-app -v hello +> ./hello ++ +
It is recommended to read the notes on using wxHaskell with MacOS X.
+
All of these files are also directly available from the +sourceforge project page.
+Note: unfortunately, the +FileBrowse example +has accidentally not been included in the release.. but it easy to download it yourself from +cvs.
+ +The file name of a binary release contains the version of the haskell compiler that you need. Make sure that
+you have the same version and compiler installed, for example ghc6.0.1
. You need to download the documentation and samples separately. Binary releases can be installed right over older releases.
c:\ghc\ghc-6.0.1
.
+After unzipping, click on the newly created wxhaskell-register.bat
program to register
+the wxHaskell package. To uninstall, you can click on wxhaskell-uninstall.bat
.
+/usr/local/wxhaskell
and registers them with GHC.
+To test the installation, you can run the following commands from the samples/wx
+directory:
++> ghc -package wx HelloWorld.hs -o hello +> /usr/local/wxhaskell/bin/macosx-app --program=hello +> ./hello ++ +
It is recommended to read the notes on using wxHaskell with MacOS X.
+
All of these files are also directly available from the +sourceforge project page.
+The binary releases should be used with GHC 6.0. You need to download the documentation and samples separately.
+ +c:\ghc\ghc-6.0
.
+After unzipping, click on the newly created wxhaskell-register.bat
program to register
+the wxHaskell package. (It is possible to install in a different directory than the GHC installation directory
+but than you need to ensure that the wxhaskell bin
directory is in your PATH
)./usr/local/wxhaskell
and registers them with GHC.
+
+To test the installation, you can run the following commands from the samples/wx
+directory:
+> ghc --make -package wx HelloWorld.hs -o hello +> /usr/local/wxhaskell/bin/macosx-app --program=hello +> ./hello ++ +
Don't forget to read the notes on using wxHaskell with MacOS X. +To uninstall wxHaskell type:
++> rm /usr/local/wxhaskell +> ghc-pkg -r wxcore +> ghc-pkg -r wx ++
wxcApp(Safe)Yield
periodically,
+or by doing the computation in an idle event handler.
+wxHaskell does have support for event driven, asynchronous input streams; see the Process
sample
+for more details. Note that one should use the wxHaskell provided mutable variables (Var
)
+to be assured for thread safeness in the future.IO
monad and uses simple mutable variables to communicate state across
+different event handlers). Hopefully, this makes it easy for others to create new functional programming
+models on top of the basic interface. However, in our experience, the current model is already quite
+adequate and certainly much friendlier than the equivalent C++ code – having computations as first-class
+values makes Haskell the ultimate imperative language :-)
+But of course, there are also some downsides:
+ +More links: +Comparison of the FOX toolkit +against different GUI toolkits, including wxWidgets. +Comprehensive overview +of probably all GUI toolkits in existance. +
+wxHaskell is a portable and native GUI library for Haskell. The goal of the project +is to provide an industrial strength GUI library for Haskell, but without the burden of developing +(and maintaining) one ourselves.
+ +wxHaskell is therefore built on top of wxWidgets – a comprehensive C++ library that is portable across all major GUI platforms; including GTK, Windows, X11, and MacOS X. Furthermore, it is a mature library (in development since 1992) that supports a wide range of widgets with the native look-and-feel, and it has a very active community (ranked among the top 25 most active projects on sourceforge).
+Since the core interface is generated +automatically from the wxEiffel binding, about 90% of the wxWidgets functionality is already supported, excluding more "exotic" widgets like dockable windows. Most work is currently directed into writing a Haskellized version of the wxWidgets API. The library currently supports Windows, GTK (Linux) and MacOS X. +
+main
twice from ghci
.
+WXH
to the more appropiate
+name WXCore
. Also fixed type signatures in the marshalling of tree controls, list controls, toolbars and splitter windows.
+wxhaskell
directory: the other directories are
+now considered obsolete (wxc
, wxdirect
, wxh
, and wx
).
+The wxHaskell libraries are distributed under the wxWindows library license. +The documentation is subject to the wxWindows documentation license.
+ +See http://www.wxwidgets.org/newlicen.htm +for the legal description of the license.
+ +The wxWindows library licence is essentially the L-GPL (Library General Public Licence), +with an exception stating that derived works in binary form may be distributed on the +user's own terms. This means that it is possible to create commercial software with this +library without paying royalties or disclosing source code. This is a solution that satisfies +those who wish to produce GPL'ed software using wxHaskell, and also those producing proprietary software. +
+ +This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; +without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +See the wxWindows library license for more details.
+This document is written to get you started quickly with writing wxHaskell applications. +Further documentation can be found on the documentation page. +
+ +Note from the author: I have written this page to be in close correspondence with the +yahu getting started page – +first of all to make my job easier by reusing +Koen Claessen's excellent example, but also since +it makes an interesting comparison: we reuse many concepts of yahu, most notably properties +and attributes, but as yahu is based on Tcl/TK, the applications are also +typed and structured in a fundamentally different way.
+ +Daan Leijen
+Start your favorite editor and write the following program (that will show a frame with +a single button that closes the frame when pressed).
++module Main where +import Graphics.UI.WX + +main :: IO () +main + = start hello + +hello :: IO () +hello + = do f <- frame [text := "Hello!"] + quit <- button f [text := "Quit", on command := close f] + set f [layout := widget quit] ++
Now start GHCi and run the program:
++> ghci -package wx Hello.hs +[snip] +Loading package wx ... linking ... done. +Compiling Main ( Hello.hs, interpreted ) +Ok, modules loaded: Main. +*Main> main ++ +
Note: On MacOS X, you can only use the interpreter with special scripts, +as you need to build MacOS X applications. +Normally, the following commands will do the job:
++> ghc -package wx -o hello Hello.hs +> /usr/local/wxhaskell/bin/macosx-app -v hello +> ./hello ++ +
You can read the MacOS X +notes for more information on using wxHaskell on MacOS X, +and how to use it from an interpreter prompt.
+ +A typical wxHaskell program imports the Graphics.UI.WX
library. If you need to access
+specific wxWidgets functionality, you would also import the lower level Graphics.UI.WXCore
library.
+The main
function uses start
to start our GUI. The function start
+initializes the GUI framework with the provided argument and starts the window event loop until the application
+quits or when all top-level windows are closed. The GUI itself is described with the following functions:
+
+frame :: [Prop (Frame ())] -> IO (Frame ()) +button :: Window a -> [Prop (Button ())] -> IO (Button ()) + +text :: Attr (Window a) String +layout :: Attr (Frame a) Layout + +(:=) :: Attr w a -> a -> Prop w +set :: w -> [Prop w] -> IO () + +command:: Event (Control a) (IO ()) +on :: Event w a -> Attr w a + +widget :: Window a -> Layout ++ +
Actually, some of these functions have (even) more general types – you can use the :t
+command in GHCi to see them.
The types Frame ()
and Button ()
denote graphical objects. These objects can
+have properties. When an object is created we can supply an initial list of properties but we
+can also set them later using set
. The type of properties for frames are
+Prop (Frame ())
and for buttons Prop (Button ())
.
Properties are created by combining attributes with values. Examples of attributes are
+text
and layout
. An attribute of type Attr w a
applies to objects
+of type w
and values of type a
. Values can be assigned to attributes using the
+(:=)
operator. You can find out more about attributes in the haddock documentation
+for the modules WX.Attributes and
+WX.Classes.
Somewhat special attributes are events. An event of type Event w a
can be
+transformed into an attribute Attr w a
using on
. The value of an event
+attribute is normally an IO
action that is executed when the event happens.
+Find out more about events in the haddock documentation for
+WX.Events and the lower level
+WXCore.Events
Since wxHaskell is based on an object-oriented framework, we also encode inheritance. The extra
+type parameter of objects encodes the inheritance relationship. When the parameter of an object is
+unit ()
, it denotes an object of that exact class. When the parameter is a type variable
+a
, it denotes any object that is instance of that class. For example, both the frame
+and button
functions return precisely a frame or button and use a ()
type parameter.
+However, the text
attribute applies to any kind of window, including frames and buttons, and
+has a Window a
as its argument. We can now use the text
attribute for example
+for both frames and buttons. In wxHaskell, this works since a Frame ()
is actually a type synonym for
+Window (CFrame ())
and can thus be passed where a Window a
is expected.
+The same hold for a Button ()
that is a synonym for Control (CButton ())
+that is again a synonym for Window (CControl (CButton ()))
.
The layout of a window is specified through the layout
attribute. The layout of the
+current program is rather terse and we will spice it up by letting the button float in the center
+when the window is resized. This is also a good opportunity to add a small margin around the button.
+set f [layout := margin 10 (floatCentre (widget quit))] ++ +
We can also add a text label above the button that is also centered. The argument of column
+specifies the amount of space between the items.
+set f [layout := margin 10 (column 5 [floatCentre (label "Hello") + ,floatCentre (widget quit) + ] )] ++ +
You can find out more about layout in the documentation for the +WXCore.Layout module.
+It is time for a more fun program that our Hello sample. We will write a program that lets us +bounce balls on the screen!
+
+
+
+
+
+
Note that the bouncing balls window is not resizeable, with the maximize box greyed out on windows.
+First we look at the main function in our program – ballsFrame
:
+module Main where +import Graphics.UI.WX + +-- constants: radius of the ball, and the maximal x and y coordinates +radius, maxX, maxY :: Int +maxY = 300 +maxX = 300 +radius = 10 + +-- the max. height is at most max. y minus the radius of a ball. +maxH :: Int +maxH = maxY - radius + +--the main function +main = start ballsFrame + +ballsFrame + = do -- a list of balls, where each ball is represented + -- by a list of all future positions. + vballs <- varCreate [] + + -- create a non-user-resizable top-level (orphan) frame. + f <- frameFixed [text := "Bouncing balls"] + + -- create a panel to draw in. + p <- panel f [on paint := paintBalls vballs] + + -- create a timer that updates the ball positions + t <- timer f [interval := 20, on command := nextBalls vballs p] + + -- react on user input + set p [on click := dropBall vballs p -- drop ball + ,on clickRight := (\pt -> ballsFrame) -- new window + ,on (charKey 'p') := set t [enable :~ not] -- pause + ,on (charKey '-') := set t [interval :~ \i -> i*2] -- increase interval + ,on (charKey '+') := set t [interval :~ \i -> max 1 (i `div` 2)] + ] + + -- put the panel in the frame, with a minimal size + set f [layout := minsize (sz maxX maxY) $ widget p] + where + ... ++ +
Unlike more functional GUI libraries, wxHaskell does not provide a model for state management and uses
+simple mutable variables to communicate state across different event handlers. (Note: this is a concious
+design decision – as functional GUI interfaces are still very much a research area, we
+want to provide a full fledged GUI library using simple IO first, than try to build good
+functional interfaces on top of that). The state of the bouncing balls demo is a list of balls. Each ball
+is represented as a list of all its future heights. At the start of the program the list is empty
+(varCreate []
).
Next, we use fixedFrame
to create a non-resizeable window frame. A panel is created to
+paint the balls on and its paint
handler paints the current balls in the panel. (Note:
+a panel has nothing to do with a Java panel: it is a widget that is normally used to place controls in
+as it manages control navigation keys like tab).
To animate the balls, we install a timer that advances all the balls on each timer tick and
+causes the panel to repaint the balls. We also install event handlers that react on the user: a mouse
+click causes a new ball to drop, a right click opens another frame (!), a p
-key pauses the
+balls, and +/-
increase/decrease the speed of the balls. Note how the operator
+(:~)
applies a function to an attribute value instead of assigning one. Thus, the
+expression (set t [enable :~ not])
flips the enabled state of the timer.
Finally, we specify the layout of the frame, using minsize
to specifiy the minimal size
+of the panel and thus the size of the frame as it is not resizeable.
Let us look at the paint event handler of the panel:
+
+ -- paint the balls
+ paintBalls :: Var [[Point]] -> DC a -> Rect -> IO ()
+ paintBalls vballs dc viewArea
+ = do balls <- varGet vballs
+ set dc [brushColor := red, brushKind := BrushSolid]
+ mapM_ (drawBall dc) [p | (p:ps) <- balls]
+
+ drawBall dc pt
+ = circle dc pt radius []
+
+
+A paint event handler gets two arguments: a device context (DC
) to draw on and a
+rectangle that specifies the coordinates of the viewing area.
+We have supplied the first argument ourselves when setting the event handler, namely the mutable
+variable that holds the list of all balls.
As said, a single ball is represented as a list of all its future positions. When painting the current
+balls, we simple extract the head positions of all balls and draw them using drawBall
. Drawing
+combinators like circle
draw using the current pen, brush, and font
+of the device context. By default, a brush is transparent so we set it to a solid red brush before drawing
+the circles. Note that this is an optimization, we could have achieved the same effect by setting it for
+each circle individually: circle dc pt radius [brushKind := BrushSolid, brushColor := red]
.
+You can read more about drawing in the documentation of the
+WX.Draw module.
+
The timer event handler uses nextBall
to advance all the balls to their next postion.
+ -- advance all the balls to their next position
+ nextBalls :: Var [[Point]] -> Panel () -> IO ()
+ nextBalls vballs p
+ = do varUpdate vballs (filter (not.null) . map (drop 1))
+ repaint p
+
+
+Updating the positions simply consist of dropping all initial positions and filtering out all empty
+lists. The function repaint
is used to invoke the paint event handler of the panel.
When a users clicks on the panel, a new ball is created in dropBall
.
+ -- drop a new ball, gets mouse position as last argument + dropBall :: Var [[Point]] -> Panel () -> Point -> IO () + dropBall vballs p pt + = do varUpdate vballs (bouncing pt:) + repaint p + + -- calculate all future positions + bouncing (Point x y) + = map (\h -> Point x (maxH-h)) (bounce (maxH-y) 0) + + -- calculate all future heights + bounce h v + | h <= 0 && v == 0 = replicate 20 0 -- keep still for 20 frames + | h <= 0 && v < 0 = bounce 0 ((-v)-2) + | otherwise = h : bounce (h+v) (v-1) ++ +
We prepend a new list of ball positions to the existing list using the varUpdate
function
+and we repaint the panel. The new list of positions is calculated with the bouncing
function
+that takes the position of the mouse pointer as its argument. This function uses the bounce
+function to calculate all future heights given an initial height and speed. Each time the ball touches
+the ground, it loses 2 units of speed.
Hopefully this sample inspires you to write more interesting GUI's. Don't forget to look +at the samples provided with the wxHaskell documentation.
+Here are some screen shots of examples that are included in the wxHaskell library. +The screenshots are taken on various Linux, Windows, and Mac OS X systems. When the screens look differently it is normally due to differences in the native look-and-feel of a platform. Many differences are intentional – one +can normally specify the exact appearance if needed.
+Hello world +[source wx, +source wxcore]. Let's start with the infamous "Hello World" application. +Note how the status bar reflects the menu option. (Note: The "File" menu disappears on the Mac as both menu items are +moved to the standard Mac application menu.) +
+Image viewer +[source wx, +source wxcore]. This example uses a standard file open dialog to open image files in various +formats (jpg, gif, png, bmp etc.) and displays them. The windows example shows an image of a notorious Norwegian Haskell hacker skiing on mount Hood. Note the custom application icon.
+![]() |
+
+![]() |
+
Windows XP | + +MacOS X |
And an extended imageviewer with a toolbar and statusbar: +
![]() |
+![]() |
+
Windows XP | +Red Hat Linux with GTK |
Time flows +[source wx]. An old Fran demo! This sample shows how to use the idle event handler to implement a +resource aware and responsive GUI that still performs heavy animation. A nice sample to practice on: extend it +yourself with menus, status bars, and options dialogs.
+ +![]() |
+![]() |
+
Basic sample on Windows XP | Extended sample on Red Hat Linux with GTK |
Extended sample on MacOS X
+Controls +[source wx]. A sample that shows different standard controls, like buttons, listboxes, sliders, radio buttons, etc. +
+![]() |
+![]() |
+
Red Hat Linux (Fedora) | Windows XP (Classic look) |
FileBrowse +[source wx]. A (very) simple file browser that demonstrates the use of tree controls, list controls and splitter windows. +
+Grid +[source wx]. Simple demo of the wxGrid control and wxGrid events. +
+OpenGL [source contrib]. +Sean Seefried and Shelarcy have provided +these screenshots that demonstrate the wxHaskell OpenGL +canvas using the HOpenGL binding +by Sven Panne. +
+Here are some screenshots taken on various Linux, Windows, and MacOS X systems:
++
+