[Replace contents of pages which have been moved to Haskell wiki. Eric Kow **20080805151503 Make these pages just a link to the WxHaskell part of the wiki. ] { hunk ./homepage/building-cygwin.html 52 -
-

Unix on Windows

-

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! -

-
- -
-

Install Cygwin

-

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:

- - -

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

- -

Cygwin make 3.81 is no more recognizing the DOS style paths. You need to install a 3.80 version that you can get from paracoda. Once your cygwin installation is working, you can install the older make with:

-
-cd /
-tar xjf /cygdrive/c/where-your-download-is/make-3.80-1.tar.bz2
-bin/make.exe --version
-
-

WARNING : It will override the 3.81 make

- -
- -
-

Installing Mingw

-

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).

- - -

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.
-
+
+

Moved!

+This page has been moved to the Haskell wiki. hunk ./homepage/building-macosx.html 52 -
- -

Using wxHaskell on MacOS X platforms

-

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
    -
    -
  • -
+
+

Moved!

+This page has been moved to the Haskell wiki. hunk ./homepage/building-msc.html 52 -
-

Building wxWidgets and wxc with Microsoft Visual C++

- -

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.

- -

If you want to use Visual C++ Express Edition, you must use Visual C++ 2008 Express Editions or higher. Because previous version requires installing Microsoft Platform SDK before building wxWidgets or wxHaskell.

- -

We use the wxWidgets provided workspace directly:

-
    -
  • wxWidgets 2.4: Open the $wxwin/src/wxWidgets.dsw workspace. -Select menu "Build/Set active configuration" and select "wxWidgets - win32 release unicode" to build the (static) library. After compilation, you can also select "wxWidgets - win32 debug unicode" to build -the debug version.
  • -
  • wxWidgets 2.6: Open the $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 "Unicode Release" and "Unicode Debug" versions of all projects and press "Build". Afterwards, press "Save All" to save all your mouse clicking work :-)
  • -
- -

If you want to use database access and openGL canvas, you must edit $wxwin/include/msw/setup.h's #define wxUSE_* (* is target feature name) from 0 to 1.

- -

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 run make command to generate stc_gen.* files.

-
-> make
-
- -

Make will stop by following error.

-
-> make: *** No rule to make target `out/wxc/wxc-msw2.6.4-0.10.1.dll', needed by `wxc'.  Stop.
-
- -

Then go $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.6.4") 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 (if you use wxWidgets 2.6.4, you must choose -"Unicode Release" or "Unicode Debug" instead of choosing just "Release" or "Debug").

- -

And finally! – you can run make in the $wxhaskell directory to build the -Haskell libraries.

-
-> cd $wxhaskell
-> make
-> make install
-> make wx
-> make wx-install
-
- +
+

Moved!

+This page has been moved to the Haskell wiki. hunk ./homepage/building.html 55 -
-

Building from sources

-

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:

-
    -
  • unix-gtk. General unix systems with GTK.
  • -
  • macosx. Mac OS X.
  • -
  • windows. General windows systems (i.e. win95 to winXP). We support both building with - the Microsoft Visual C++ compiler version 6, 7 and 8 (windows-msc) and building with the - gnu mingw32 C compiler (windows-mingw).
  • -
- -

wxHaskell has been build successfully on (at least) the following configurations:

-
    -
  • windows. Windows 98, windows 2000, and windowsXP, using wxMSW 2.4.x, 2.5.x, and 2.6.x.
  • -
  • macosx. Mac OS X 10.2 (Jaguar) and 10.3 (Panther) with ghc 6.2.x and wxMAC 2.4.2 and 2.5.x.
  • -
  • unix-gtk. Red Hat Linux 10 (Fedora), FreeBSD, and Gentoo Linux, using wxGTK 2.4.2, 2.5.x, and 2.6.x.
  • -
- -

(Unfortunately, there are still build problems on Sun Solaris – we are looking for build volunteers :-)

-
- -
-

Prerequisites

- -

Ensure you have a recent GHC compiler – version 6.8.1 is recommended (but any version >= 5.04.3 will work). In principle, any Haskell98 compiler that supports the standard FFI libraries will also work.

- -
    -
  • windows: you need the cygwin environment together -with the mingw compiler. The build process is very sensitive to the -cygwin setup and there is a separate guide for installing cygwin properly. -
  • - -
  • macosx: you need to install the 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. -
  • - -
  • ghci: the GHCi interpreter only works with wxWidgets version 2.4.2 on Windows platforms. -
  • -
- - -

Next, you should install the previous stable version (2.6.4) of wxWidgets -for your platform. (wxHaskell doesn't support latest stable version (currently 2.8.4) now.) We assume in this guide that the variable $wxwin points to your -wxWidgets installation directory, for example: ~/dev/wxGTK-2.6.4.

- -
    -
  • windows: ghci only works with wxWidgets 2.4.2. Since this wxWidgets version is very stable, it is recommended on windows platforms. -
  • - -
  • macosx: MacOS X works best with wxWidgets 2.5.4. The previous stable release (wxMAC-2.6.4) does not display menus properly. -
  • -
- - -

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. -

- -

(Note: GHC 6.6.x or higher can't build old source releases. So you must get source from darcs by below command.)

- -

If you do not have a source release of wxHaskell, you need to check it out from the darcs repository. Darcs creates a -wxhaskell directory for you; we assume in the following example that -your $wxhaskell directory will be ~/dev/wxhaskell.

-
-> cd ~/dev
-> darcs get --partial --set-scripts-executable http://darcs.haskell.org/wxhaskell/
-
- -
- -
-

Building wxWidgets

-

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 --enable-unicode
-> make
-> make install
-> cd contrib/src
-> make
-> make install
-
- -Notes: -
    -
  • Add the following flags to configure, to enable certain advanced features of wxHaskell: -
    • --enable-unicode to build a unicode library (required for 0.10 and up).
    • -
    • --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. And this option is diffrent with below option. You can play sound without no-control by this feature. - But ... if you use below media control, it requires to make Control on your Window.)
    • -
    • --enable-mediactrl to enable the media control. (recommended for wxWidgets version >= 2.6.x)
    • -
    -
  • -
  • Do not forget to run make install; this installs a utility called -wx-config that is used by the other projects.
  • -
  • Do not forget to install 'contib' hierarchy libraries. Now latest darcs' source depends on -'contib' hierarchy libraries.
  • -
  • unix-gtk: if you want to use the GTK-2 toolkit, you need to configure with -unicode support since current wxHaskell can handle only unicode library. Try for example: -
    -../configure --with-gtk --enable-gtk2 --enable-unicode
    -
  • -
  • macosx: you might need to run rehash after make install -in order to add the wx-config utility to the search path cache.
  • -
  • windows: sometimes the header file $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
-
- -
- -
-

Building wxHaskell

- -

First, we configure the library for your platform.

- -
-> cd $wxhaskell
-> ./configure --enable-split-objs --hcprof
-
- -Notes: -
    -
  • You can run 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?
  • -
  • You should pass the --with-opengl option to configure if you specified this -flag when configuring wxWidgets (or you will get link errors).
  • -
  • You should pass the --with-contrib option to configure if you also installed contrib libraries after building -wxWidgets (or you will get link errors).
  • -
  • By default, the library is installed in the wxWidgets install directory. You can specify another directory with the -prefix option of configure: ./configure --prefix=/usr/local. Any directory that is on your library search path will do.
  • -
  • windows-msc. Read the notes on building wxHaskell with Visual C++.
  • -
  • ghc 6.0.1, wxhaskell 0.8: In the file 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
-> make wx
-> make wx-install
-
- -Notes: -
    -
  • If 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
    -
  • -
  • You can generate documentation with make doc. -
  • -
  • The libraries can be uninstalled with make uninstall. -
  • -
-
- -
-

Test wxHaskell

-

If everything succeeded, you should be able to run a test program.

-
-> cd samples/wx
-> ghc -package wx -o helloworld HelloWorld.hs
-> ./helloworld
-
- -

Notes:

-
    -
  • macosx: Unfortunately, wxHaskell programs do not work directly as generated by -GHC. Look at the MacOS X notes for more information.
  • - -
- -

You can also run the examples from GHCi – a great development environment!

-
-> ghci -package wx BouncingBalls.hs
-> main
-
- -

Notes:

-
    -
  • wxHaskell programs are not always properly reïnitialized when started -the second time from a GHCi prompt. This is due static variables in the wxWidgets C++ code, and -we are working with wxWidgets developers to remove those bugs. Currently, GHCi only works well -with wxWidgets 2.4.2. -
  • gtk: Unfortunately, one can only start a wxWidgets program once with GHCi on GTK (rendering it -useless).
  • -
  • macosx. You need to use a special command to run wxHaskell applications, see the -Mac OS X notes from more information.
  • - -
- -

Have fun!
-   -- Daan Leijen.

+
+

Moved!

+This page has been moved to the Haskell wiki. hunk ./homepage/contribute.html 52 -
-

Contribute to wxHaskell!

-

"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. -

-
-
-

- -
XRC support
-
From the wxWidgets homepage: -
-The XML-based resource system, known as XRC, allows user interface -elements such as dialogs, menu bars and toolbars, to be stored in text -files and loaded into the application at run-time. -
-It would certainly be useful if people could use tools like wxGlade -to build interfaces and use them for Haskell programming. -gtk2hs seems to support -an equivalent feature, so perhaps you could get some tips from them. - -
- -
-

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! -

    -
  • Drag and drop.
  • -
  • Clipboard, copy and past.
  • -
  • Grid control support.
  • -
  • Better internet support.
  • -
  • ...
  • -
-

+
+

Moved!

+This page has been moved to the Haskell wiki. hunk ./homepage/development.html 51 -
-

Development

-

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:

-
-
Jeremy O'Donoghue
-
Team leader
-
Mads Lindstrøm
-
Linux support (Debian)
-
Kido Takahiro (shelarcy)
-
Windows support
-
Eric Kow
-
MacOS X support
-
Daan Leijen
-
The main developer and designer of wxHaskell
-
- -

Furthermore, the following people have contributed to the wxHaskell project:

-
-
Wolfgang Thaller
-
Contributed a nifty MacOS X module that enables the use of GHCi on MacOS X.
-
Martijn Schrage
-
Helped to design the library interface and tested the library by using wxHaskell -as a backend to Proxima – a sophisticated generic structure editor.
-
Arjan van IJzendoorn
-
Developer of NetEdit and provides a lot -feedback for improving the library.
-
Maarten Loffler, Sean Seefried, and Luc Taesch
-
Contributed samples to the library. Maarten also helped creating a proper windows98 -installer.
-
Andres Löh
-
Testing on Gentoo Linux with GTK (and has written the graphical editor -used by team DOM in the ICFP contest).
-
Arthur Baars
-
Testing on MacOS X, and creating MacOS X installers.
-
Wijnand Suijlen
-
Has written the Helium interpreter in wxHaskell and initiated the design of the -layout combinators.
-
Eelco Dolstra and Armijn Hemel
-
Kindly provided their linux computers and unix wisdom :-) to test wxHaskell on -Linux/GTK systems. Special thanks goes to Armijn Hemel for maintaining a Red Hat Linux -and MacOS X system for testing in the student laboratories.
-
Jens Petersen
-
Created the initial rpm specification files and released a few rpm distributions of wxHaskell
-
-
- -
-

Overview

-

wxHaskell is a project hosted on sourceforge. The sources are -available via darcs on darcs.haskell.org. -

-
    -
  • wx [documentation]. The main middle-level library. This library is written in Haskell and only depends on the wxcore package. It uses overloading and attributes to expose a nice functional -interface to the wxcore library. However, it does not try to create a new model -for programming GUI interfaces: everything is still in the IO monad and state is handled through mutable -variables.
  • -
  • wxcore [documentation]. The Haskell binding to the core wxWidgets library. This is just like programming the wxWidgets library directly, you can see some - examples - in the cvs. All the method definitions and marshaling code is generated automatically -- about 500 classes with 2500 methods and 1000 constant definitions. -wxcore uses the following two sub-projects: -
      -
    • wxc. A C project that puts a C wrapper around the C++ interface to wxWidgets. This makes it -much easier to access the wxWidgets library from Haskell. The C wrapper consists of the C sources of the Eiffel ewxw library for wxWidgets. We also added a few files to make the project suitable for Haskell, but we made no changes to the original Eiffel sources. This way, we are able to automatically update the sources from their cvs server. A big thank-you to the people that worked on the Eiffel library! -
    • wxdirect. A Haskell program that reads the C header files of the Eiffel wxWidgets C library and automatically generates Haskell marshaling code and class definitions. -
    -
  • -
+
+

Moved!

+This page has been moved to the Haskell wiki. hunk ./homepage/documentation.html 52 -
-

Documentation

-

(All of the following links are cheap to follow)

- +
+

Moved!

+This page has been moved to the Haskell wiki. hunk ./homepage/faq.html 52 -
-

Frequently Asked Questions

-

Technical

-
-
What is the difference between the wx and wxcore libraries?
-
The wxcore library provides the core interface to the wxWidgets API (in -WxcClasses). Furthermore, it provides some useful abstractions -for the Haskell programmer. However, the library just uses functional abstraction: no overloading, new monads, or other -fanciness. The wx library is build on top of the wxcore -library and uses more advanced abstraction mechanisms, like overloading, to provide useful features like -properties and attributes.
- - -
Does wxHaskell support multiple threads?
-
Not currently. GHC 6.0 does not support process threads by default, and Haskell -concurrency does not work correctly (yet) with a GUI event loop. However, as the -wxWidgets manual says, multiple threads are not always a good solution. For example, -doing a long computation in a separate thread in order to show a progress bar, is -normally better solved by calling 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.
-
- -

Design

-
-
Why haven't you created a purely functional interface (Fudgets, Fran, ..)
-
Since the design of high-level GUI libraries (like -Fruit or -Fudgets) is still -much of a research issue, we opted for creating a "medium level" interface: an interface that does -create useful functional abstractions but does not provide a new programming model (i.e. everything -is in the 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 :-) -
- -
Why wxWidgets?
-
-Well, there are many good reasons for using wxWidgets: -
    -
  • wxWidgets is free software but you can still write commercial applications with it.
  • -
  • It is a thin wrapper around native UI elements giving native look-and-feel.
  • -
  • It is a comprehensive library that is portable across many GUI platforms.
  • -
  • There even exists a wxUniversal port that just uses a screen -buffer (and giving up on native look-and-feel!) that can be used on embedded devices.
  • -
  • The development community is very active (ranked among the top 25 of most active projects on sourceforge).
  • -
  • The library is mature (in development since 1992).
  • -
  • The library not only provides GUI abstractions but also an API for databases, sockets, editors, etc.
  • -
  • We could generate a Haskell marshalling layer automatically from the wxEiffel binding.
  • -
  • There exist many more language bindings, with wxPython as the most widely known (and used?).
  • -
- -

But of course, there are also some downsides:

- -
    -
  • wxWidgets is free software :-). In itself not bad but it also means that we are -dependent on the time and effort of volunteers. For example, the MacOS X port lags somewhat -behind and the documentation of the Qt toolkit is in general better -(although the wxWidgets documentation is pretty good too).
  • -
  • It is a huge library. Not a problem in itself but it can be somewhat intimidating.
  • -
  • The wxEiffel binding is only partially type checked and manually written; it is -better when the marshalling code can be generated from the real wxWidgets type signatures -(but alas, this involves writing either a C++ parser or writing bindings with SWIG). -We might someday start to use the wx.NET wrapper as it seems better structured for use -with an automatic marshalling program. -
  • -
-
-
Why don't you use Qt (or FLTK, or ..) ?
-
Of course there exist some other good GUI libraries and maybe they would be good -choices too (here is a nice overview). -However, many libraries have important drawbacks. For example, we do not use -the Qt toolkit since one has to pay for an expensive license to create commercial or -Windows applications; The programming model of Swing is inconvenient to use -from Haskell, etc. - -

More links: -Comparison of the FOX toolkit -against different GUI toolkits, including wxWidgets. -Comprehensive overview -of probably all GUI toolkits in existance. -

-
-
+
+

Moved!

+This page has been moved to the Haskell wiki. hunk ./homepage/license.html 51 -
-

License

-

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.

+
+

Moved!

+This page has been moved to the Haskell wiki. hunk ./homepage/quickstart.html 54 -
-

A quick start with wxHaskell

- -

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

+
+

Moved!

+This page has been moved to the Haskell wiki. hunk ./homepage/quickstart.html 59 -
-

Hello world in wxHaskell

-

Start your favorite editor and write the following program (that will show a frame with -a single button that closes the frame when pressed).

-Hello world on Windows XP -
-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]
-
-Hello world on Red Hat Linux - -

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:

-Hello world sample -
-> 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.

- -

Types

-

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 ())).

- -

Layout

- -

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.

-Hello world sample -
-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.

-Hello world sample -
-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.

-
- -
-

Bouncing balls

- -

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!

-

-Bouncing balls on Windows 2000 -Bouncing balls on Gentoo Linux with GTK and KDE -Bouncing balls on MacOS X (Panther) -Bouncing balls on Red Hat Linux (Fedora) -

- -

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 [enabled   :~ 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 [enabled :~ 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.

- -

Painting

- -

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. -

- -

Bouncing

- -

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.

-
- - - }