wxErlang: Gathering the pieces
It's been quite some time that I started rewriting some Erlang GS gui modules to use wxErlang, since the intention is that wxErlang shall replace GS soon, maybe in the next major release (R15).
Since it was not something urgent, I've been working on it every now and then, making new discoveries every time. So, I decided to write this post to gather all sources of information I came across, tutorials and existing examples and share my experiences and difficulties I found.
What is wxErlang?
wxErlang is an Erlang binding to the C++ GUI library wxWidgets, which provides support for cross platform GUI applications. This report can give you an insight of how it can be used, as well as how the library itself has been implemented. The report is quite old (2005) and several things have changed since it was written, but it's worth reading. It explains the basics in a fairly simple way and gives an interesting example on how etop (an Erlang version of the unix command top) would be re-implemented using wxErlang. However, be sure not to copy-paste the code provided and always advise the documentation because some things have changed since the report and won't work!
For example, wx:start() is used in the report instead of wx:new(), context instead of environment, etc.
Tutorials and References
I have to admit that when I fisrt started messing up with wxErlang, I was desperate. I could find almost nothing helpful online except from the reference manual, which is actually a collection of the available modules and functions with "See external documentation" links to the wxWidgets documentation.
But then this great tutorial organized a bit the things in my mind. It's fairly simple and complete and has step-by-step examples. As far as I have searched online, it is the only one available (please let me know if there are more I'm not aware of).
In a section of the same tutorial, wxFormBuilder is introduced. wxFormBuilder is a tool which allows the user to design the gui in a drag-and-drop way and generates C++ and Python code automatically. Since no IDE or other kind of framework is available for building a gui in Erlang in an easier way, I thought I'd use it. The truth is it's great but I came to find out that "translating" C++ or Python to Erlang was a bit more tricky than it sounded. I guess if someone is familiar with all three languages, ti might be very helpful.
Links
- wxErlang project: http://sourceforge.net/projects/wxerlang/
- wxErlang reference manual: http://www.erlang.org/doc/apps/wx/index.html
- wxErlang workup: http://wxerlang.dougedmunds.com/index.php
- wxFormBuilder: http://wxformbuilder.org/
Some things to note
Now to conclude this post, there are some hints I want to mention. Things that might not be obvious or in my opinion deserve your special attention:
1. Don't forget to destroy your object
Even if when using wxErlang we're writing Erlang, we're indirectly writing in C++ and we have to be aware of that. Especially when it comes to memory management. With wxErlang we need to care about destroying the objects we created and there are destroy/1 functions in every widget to do so.
2. Always read the external documentation
I know it's annoying but since the reference manual is not very enlightening and especially if you haven't worked with wxWidgets before, you might find yourself in situations where you get errors (in the usual Erlang-non-self-explanatory way) and you have no idea what is wrong.
To give you an example, here is a function I wrote:
make_window() ->
Server = wx:new(),
Frame = wxFrame:new(Server, -1, "My Window", [{size,{300, 200}}]),
Panel = wxPanel:new(Frame),
Box = wxStaticBox:new(Panel, -1, "A Static Box"),
MyText = wxStaticText:new(Box, -1, "This is static text"),
wxFrame:show(Frame),
ok.
When executing this function, the Erlang shell crashes with "Segmantation fault", no additional information, no line provided. The problem with this code is that wxStaticBox is used as the parent object for the wxStaticText. However, you will not find the reason in the wxErlang documentation, but it's pretty clear in the external one:
"Please note that a static box should not be used as the parent for the controls it contains, instead they should be siblings of each other. Although using a static box as a parent might work in some versions of wxWidgets, it results in a crash under, for example, wxGTK."
3. Concurrency
Of course what we all love in Erlang is concurrency. Why even bother making a gui in Erlang if you can't have the different components acting as independent processes that communicate with each other and the failure of one of them doesn't affect the rest of your gui?
However, there is a small detail that requires our attention when dealing with wxErlang. wxWidgets uses a process specific environment, which is created by wx:new/0. So, each process is defined within an environment. In order for other processes to be able to communicate with it, they have to share the same environment. To be able to use the environment from other processes, we can call get_env/0 to retrieve the environment and set_env/1 to assign the environment in the other process.
Looking forward to a tool that will make our life easier,
V.

