Sunday, December 18, 2011

Adding a New Control to wxOSX: A Walkthrough.

I've decided to write down my notes about implementing a new control for wxOSX port in the hope that it can help other OS X developers to participate in wxOSX development (but, to be honest, also because I might return to it myself when I have to do this the next time).

So, without further ado, here is the full and unabridged true story [*] of implementing wxDatePickerCtrl in wxOSX/Cocoa.

To start with, you need to set up your wxWidgets development environment. For this you need to get wxWidgets sources, ideally from svn or its git mirror. You then need to build them enabling debug support to make sure you can debug them later. The simplest way to do this is to use the command line, even if you prefer to use Xcode for editing and debugging later. It's strongly recommended to build wxWidgets in a separate directory from the one containing its sources, so, assuming you put the sources in $HOME/src/wx, you should do:

$ mkdir -p ~/build/wx/osx_cocoa-debug
$ cd $_
$ ~/src/wx/configure --with-osx_cocoa --enable-debug

If you prefer to build in 32 bits, add --enable-macosx_arch=i386 switch to configure. Another useful option is -C to make configure cache the results of its checks, this will make it run much faster the subsequent times. In any case, after doing this you just need to do make -s -j8 with "-s" added to avoid huge quantities of output you probably don't care about and "-j8" being adequate for the modern quad-core CPUs. Of course, if you use a less -- or more -- powerful machine, adjust the "8" accordingly. Depending on your machine characteristics the build can take anywhere from a couple of minutes to half an hour or more but it should eventually finish. To test that everything well, and also because we will need it later for testing anyhow, try building and running the "widgets" sample:

$ cd ~/build/wx/osx_cocoa-debug/samples/widgets
$ make -s
$ open ./

Next step is to add stubs for OS X-specific version of the control: usually, the control you want to implement will be already available under OS X but its "generic", i.e. platform-independent and hence not really Mac-looking, version would be used. We want to replace it with the native one so let's do it by modifying a few files in wxWidgets sources:

  1. Modify include/wx/datetimectrl.h to include wx/osx/datetimectrl.h if __WXOSX_COCOA__ is defined. Notice that we only implement this control for the Cocoa port version, if you were doing it for both Carbon and Cocoa, you would have tested for just __WXOSX__.

  2. Our example is actually more complicated than a typical control because there are two classes: wxDateTimePickerCtrlBase, which is the common base class for wxDatePickerCtrl and wxTimePickerCtrl and wxDatePickerCtrl itself. So we also need to update include/wx/datectrl.h in a similar way.

  3. Of course, now that we added inclusions of the new files, we actually need to create them so let's do it. Both headers should declare the corresponding classes, i.e. the same as in the common headers from where we include them but without the "Base" suffix. So let's define wxDateTimePickerCtrl, inheriting from wxDateTimePickerCtrlBase in include/wx/osx/datetimectrl.h. and, similarly, wxDatePickerCtrl inheriting from wxDatePickerCtrlBase in include/wx/osx/datectrl.h. You can copy the file structure (i.e. the standard header comment, the include guards, ...) from another OS X header or maybe from the common header that you already modified itself. Don't forget to put your name in the "Author" line!

  4. Usually, the classes we declared are concrete, so they should have the correct constructors and implement base class pure virtual methods. The "Base" classes don't define the constructors so we need to look at an existing implementation, for example the native MSW one in include/wx/datectrl.h, to see which arguments should the constructor take. You can simply copy the constructors (including the default one) and Create() function declaration from there as they must be the same for all ports, it's just their implementation that will be different.

At this stage, it might be a good idea that our new headers compile correctly (of course, nothing is going to work nor even link yet) so you could try to compile some file including them. In my case let me check if "make advdll_datavcmn.o" still works -- it does, so we didn't make any stupid mistakes (yet) and can continue.

Let's add the stubs for the implementation of the new classes too now:

  1. Create src/osx/datetimectrl_osx.cpp and src/osx/cocoa/ The latter is an "Objective-C++" source file, hence the relatively unusual extension. Again, as we actually are implementing two new classes and not one, we also need to create src/osx/datectrl_osx.cpp. But as we suspect that we won't need any Cocoa-specific implementation for this class (as everything will be done in the base one), we don't need any other Objective-C++ files.

  2. We need to update wxWidgets build system to take the new files into account. For this, we need to edit build/bakefiles/files.bkl, locate ADVANCED_OSX_COCOA_SRC definition in it and add the new files paths to it. Also do the same for ADVANCED_OSX_COCOA_HDR.

  3. If you don't have it yet, you need to install bakefile for the next step. Just grab the DMG from download page and install it as usual.

  4. Go to build/bakefiles subdirectory and run bakefile_gen -b wx.bkl to update all make and project files for wxWidgets.

  5. Finally, re-run configure or just recreate the makefile using the command ~/src/wx/regen Makefile from the build directory.

  6. And redo make again as a sanity check. I got undefined symbol error from the linker about wxDatePickerCtrl::GetClassInfo() when doing this, which made me realize that I forgot to put wxIMPLEMENT_DYNAMIC_CLASS() in src/osx/datectrl_osx.cpp. After adding it, everything linked correctly. Of course, nothing works yet but we're going to change this soon.

So, finally, here is the interesting part: actually implementing the control using Cocoa API. The details of doing this depend on the exact control used, of course, e.g. we are going to base it on NSDatePicker in this case but another subclass of NSControl would need to be used for another control. But some things need to be done for all of them in more or less the same way because all wxOSX classes are similar and use pImpl-idiom: the wxControl-derived class itself just forwards all of its methods to its "peer", which is a pointer to an internal object of a class deriving from wxWidgetImpl implemented differently for Carbon and Cocoa ports. In more details:

  1. As we need some additional methods in our "impl", we're going to define a new class for it. Notice that sometimes this can be avoided as wxWidgetImpl already has quite a few standard methods which are enough for many common controls. In our case, however, they are not. So we add a new include/wx/osx/core/private/datetimectrl.h header and define wxDateTimeWidgetImpl class with the Set/GetDate() and Set/GetDateRange() methods corresponding to wxDatePickerCtrl methods we need to implement in it. Notice that this is a private header, not installed when wxWidgets is installed, so there is no need to add it to build/bakefiles/files.bkl unlike the public headers we had created before.

  2. We also a static CreateDateTimePicker() method that we'll use for creating the native Cocoa control to this class as well.

  3. The implementation will be the same as for the other Cocoa widgets, i.e. it will first create a subclassed NSDatePicker which is only necessary in order to call wxOSXCocoaClassAddWXMethods() (it would definitely be nice to have some way to avoid duplicating this code, even if it's quite trivial for all classes, but I don't know how to do it -- contributions from Cocoa/Objective-C experts would be welcome) and associate it with the peer object mentioned above.

  4. We also need to implement wxDateTimeWidgetImpl implementing all its pure virtual methods we added above and implement them using the corresponding NSDatePicker methods in the straightforward way. We'll call our derived class wxDateTimeWidgetCocoaImpl for consistency with the similar classes.

  5. Finally we also need to add code for generating events for our control. In this case it is very simple as there is only one event and it's the main/default action of the Cocoa control so it's enough to just override controlAction() method in wxDateTimeWidgetCocoaImpl.

By now we have a minimally working implementation of the control! It's definitely not perfect as we don't handle almost any styles of wxDatePickerCtrl, notably wxDP_ALLOWNONE, but as there doesn't seem to be any simple way to implement it with the native Cocoa control we're just going to leave it unimplemented for now. We do need to mention this to warn the users so let's update interface/wx/datectrl.h to add a note about this.
Otherwise no new documentation needs to be written as it already existed so we are almost done.

The last thing is to submit the changes for the inclusion to wxWidgets. This is normally done by submitting a patch to our Trac but as this patch is rather extensive, it's a good idea to request a review for it first. Remember to clean up your patch before submitting for the review, just as I did before submitting this patch.

While this post turned out to be quite long, it's mostly because I tried to describe all the steps, including the very first ones, in details. It also involved a rather atypical case with 2 different classes being involved when usually only one of them is. Adding new controls to wxOSX is really not that difficult and I hope this walk-through will encourage more people to do it. And if you do follow it and find any inexactitudes (this word sounds so much better than "stupid errors"), please let me know and I'll correct them here.

Happy hacking!

* For some values of "unabridged" and "true". I did simplify a few things, mainly because I implemented both wxDatePickerCtrl and wxTimePickerCtrl at the same time.

Wednesday, December 14, 2011

2.9.3 release in details

wxWidgets 2.9.3 has been officially released today. In spite of our efforts to speed up the release process, it still took us 5 months to do it after 2.9.2. However it's significantly better than a year that both 2.9.1 and 2.9.2 had taken. And we plan to make 2.9.4 sooner than in 5 months too as explained in the updated roadmap.

As a remainder, here is a summary of the most important new features that appeared in wxWidgets since 2.9.2:

  • The star addition of this release is the wxWebView library by Steven Lamerton and Auria, developed during Google Summer of Code 2011. It is by far the biggest and most important new feature. Thanks to it it is finally possible to embed a fully functional native web rendering engine (with JavaScript and CSS support) in wxWidgets applications.

  • wxTimePickerCtrl logically complements wxDatePickerCtrl. Currently it uses a native control under MSW and a generic implementation elsewhere but we have plans to also provide a native implementation for OS X in the next version (and for wxDatePickerCtrl as well).

  • wxTreeListCtrl: this is much less revolutionary but is a convenient and, most importantly, simple to use multi-column hierarchical control.

  • wxRichToolTip and wxBannerWindow are also not exactly earth shattering but provide a simple way to enhance your application UI by presenting more information in a nice and not distracting way to the user.

  • Time functions now can return time with microsecond, rather than millisecond, precision and wxStopWatch is more precise thanks to this.

  • The generation of wxEVT_CHAR_HOOK event was made consistent for all the major platforms and DoAllowNextEvent() was added to make it possible to handle this event in more flexible way.

  • wxMessageDialog gained support for wxHELP button and, consequently, it is now possible to easily show message boxes with up to 4 (instead of 3 before) custom buttons. We are sure that wxWidgets users won't abuse this feature but, just in case, we officially announce that 4 is as high as the number of message box buttons will ever go.

  • You can now try to enter a critical section, without blocking.

  • wxTextCtrl has gained support for auto-completing the directories (unfortunately, as with the files, this is only implemented in wxMSW currently).

  • And it is now also possible to find the pixel coordinates of a text position in wxTextCtrl which is helpful for e.g. showing a context menu or a popup window for the given character or word.

  • Support for wxSplitterWindow persistency was added, meaning that you can now simply call wxPersistentRegisterAndRestore(splitter) to automatically save the splitter position and restore it the next time your program is executed. Additionally, the location and the format of saved persistent options can now be customized by providing a custom wxPersistenceManager and overriding its GetKey() method.

  • Keyboard navigation in generic wxDataViewCtrl has been significantly enhanced to make it really practical to use it for editing and not just browsing data.

There were many more minor additions and plenty of bug fixes as well, of course, see the change log for even more details.

Finally some combined statistics about the changes since the last release:
% git shortlog -sn remotes/tags/WX_2_9_2..
465 Vadim Zeitlin
232 Steven Lamerton
74 Stefan Csomor
71 Vaclav Slavik
47 Dimitri Schoolwerth
47 Robin Dunn
41 Paul Cornett
26 Julian Smart
21 Jouk Jansen
6 Francesco Montorsi
5 Chris Elliott
1 Bryan Petty
1 John Chain
1 Mike Wetherell
for 1038 commits. Notice that my own check ins include committing many patches from other people (which git would have kept track of but svn is unfortunately incapable of this). In particular, I'd like to thank Catalin Raceanu, Kinaou Hervé, David Hart, troelsk, Armel Asselin, wsu, joostn, Navaneeth, Allonii, ivan_14_32, Marcin Wojdyr, John Roberts and others for their contributions to this release (sorry in advance if I forgot anybody in this list, please contact me if you should have been included into it). To keep an idea of the amount of code changed by these commits here is another statistics:
% git diff --shortstat remotes/tags/WX_2_9_2
1202 files changed, 231492 insertions(+), 149751 deletions(-)
So around 80000 lines have been added which seems enormous but more than 60000 of them were actually changes to the (automatically generated) make and project files and message catalogs so "only" approximatively 18000 new lines of code have been added. Remarkably, almost 6000 of them were added to the documentation and another 1500 or so to the unit tests. On the other hand, we actually lost 20000 lines in an upgrade of libpng so the actual amount of the new lines in our own code is close to 15000 which is still pretty impressive.

On a less bright note we also have:
% ./trac-ticket-stats 2011-07-04 today
Ticket statistics for from 2011-07-04 to 2011-12-14:
New 454
Closed 397
Reopened 59
Delta 116
so while almost 400 bugs were fixed since 2.9.2, net effect is unfortunately that today we have 116 more bugs than 5 months ago.

Friday, December 02, 2011

Please help with testing 2.9.3 RC

Release candidate for the next 2.9.3 is available from SourceForge and soon will also be at FTP mirror.

Please test the distribution files and let us know about any problems you encounter with downloading, compiling or installing from them. If all goes well the final 2.9.3 should be done next week.

Thanks in advance for your help!

Saturday, September 03, 2011

August Augmentations

August has been a busy month this year, with a couple of new classes being
added and several minor enhancements to the existing ones as well. Even though none of these changes is particularly major, they should hopefully be useful to wxWidgets users, just as they were useful for me when working on my projects.

The first of the new classes is wxBannerWindow. As you can see from the screenshot at that link, it is a particularly simple class as it is static in appearance and basically doesn't do anything except providing some information about the current window to the user and, mostly, just looking nice. Of course, it was always pretty simple to do something like this with wxWidgets and personally I had already done it a few times but having a standard class for this makes using it even easier, especially as it can also be defined in the XRC resources and so added to your existing dialogs very easily.

The second new class is actually not really a new class at all but a wrapper for an existing one: wxTreeListCtrl is a façade for wxDataViewCtrl which is not nearly as flexible as the full wxDataViewCtrl class but is much easier to use in a special yet common case when you just want to have a multi-column tree control, optionally with icons and, also optionally, check boxes, in the first column, like this:
wxTreeListCtrl screenshot

What you can't see on the screenshot is that the source code of the new treelist sample is much simpler than that of the dataview sample. Of course, this simplicity comes at a price: you can't have "infinitely" many items in this control because it stores all of them internally. However if you have a control with relatively few (not more than a couple of thousands) items, then this is probably not a big problem and this control can be a simple alternative to wxDataViewCtrl. And, of course, wxTreeListCtrl features are a union of those of wxTreeCtrl and wxListCtrl and so it may also provide a simple solution if you're currently using one of those controls but need the extra features (multiple columns or hierarchical items) not available in it.

And then there were several enhancements to the existing classes:

  • Navaneeth has contributed a useful wxTextCtrl::PositionToCoords() method allowing to find the pixel coordinates of the given character in wxTextCtrl. This allows to show auto-completion window at the right position, for example.

  • wxMessageDialog and, hence, wxMessageBox(), have gained support for wxHELP button. Beyond the ability to provide help in your message boxes this is significant because you can now have up to 4, instead of 3, as before, buttons in your message boxes. And as using SetHelpLabel() you can set arbitrary text for this button, it means you can now propose more choices to the user if really necessary (an advance warning: 4 is as high as it will go).

  • A new wxTextEntry::AutoCompleteDirectories() was added. Unfortunately, just as AutoCompleteFileNames(), it is currently MSW-only. But at least on this platform it makes using controls used for entering directory names in them more convenient for the user. Moreover, wxFilePickerCtrl and wxDirPickerCtrl now call the appropriate completion function automatically for their integrated text control and so you don't even need to worry about not forgetting to do it yourself if you use one of those handy controls.

  • Another MSW-specific change is the addition of wxTopLevelWindow::MSWGetSystemMenu(). This function can be used to add items to the "system" window of Windows programs. Using it is inherently not portable but can still be useful even in cross-platform applications: for example, you could use it to add an "About" item to the system menu under MSW if your application doesn't have any normal menu bar. This is actually consistent with OS X where all applications have the standard "About" item in their "Apple" menu, whether they have a menu bar or not. Maybe in the future we will provide a higher level interface for this but for now this function can be helpful.

  • Some cleanup was done as well: SetImageList() and AssignImageList() now work consistently for all controls, as discussed in this thread. And wxDataViewCtrl::GetSelection() now works consistently in all ports, after the changes proposed here were implemented. New, more clear, wxComboBox::IsTextEmpty() and IsListEmpty() were added to replace IsEmpty() whose behaviour was inconsistent in different port. Finally, Stefan fixed long-standing issue with Ctrl vs Cmd keys confusion in wxOSX after this discussion.

More new features are planned for September too, notably I'm personally planning to add a new wxTimePickerCtrl class and also wxBalloonTooltip. Any help with their development or participation in discussion of the API of the new classes is always welcome on wx-dev.

Saturday, August 20, 2011

Cleaning patches for the review

Unfortunately (and, as usual, for historical reasons) we keep quite a few auto-generated files in wxWidgets sources repository, for example configure (created by autoconf), a lot of setup.h files all generated from the master setup_inc.h template using a simple sed script and also tons of makefiles (created by bakefile).

One of the many reasons this is inconvenient is that changes to these files get in the way when reviewing patches. But luckily, it's simple enough to fix this, at least if you're using a Unix system with patchutils on it. It's enough to execute this command:

filterdiff -x '*/*.vcproj' -x '*/*.dsp' -x configure -x \
'*/makefile.*' -x '*' -x \
-x include/wx/msw/wince/setup.h -x '*/setup0.h' \
some-wx-patch.diff > some-wx-patch-clean.diff

The command is actually not difficult to write but it is long and it's easy to forget something (as I just did for not the first time when retyping it) so I recorded it in a one-line script called clean_patch and now you (and I) can simply do

./misc/scripts/clean_patch some-wx-patch.diff > some-wx-patch-clean.diff

If you add any new files, any new wxUSE_XXX constants or modify, please remember to clean your patches up. The clean patches are much more pleasant to review and easier to merge, even if there were other changes to the auto-generated files in the meanwhile.

Thursday, July 28, 2011

Another Victory in the War Against Macros

wxWidgets is notorious for using many macros. While evils of macros in C++ are well-known, sometimes they are really necessary, e.g. wxIMPLEMENT_APP hides the difference between using main() or WinMain() as entry point and sometimes, even if there are alternative approaches not involving macros, e.g. using a base class instead of wxDECLARE_NO_COPY_CLASS macro, their use is still not particularly offending. In still other cases macros are used to provide a kind of a DSL, such as event table macros that allow to describe event handler connections statically and less flexibly but more concisely than Connect().

However in some cases there is really nothing that can be said in defense of
using the macros and they are present in the code just for "historical
reasons", i.e. because nobody thought about doing it better back when the code was first written, often enough almost 20 years ago. We try to deprecate (which is a polite term for "get rid of") such macros progressively and there are not that many of them left, at least on the interface side.

A couple of days ago I finally managed to ditch a particularly aggravating set of them: the so-called "control container" macros. They must be used in the classes that represent windows containing other windows ("controls") in order to allow TAB navigation inside them. While wxPanel and wxDialog, which are two of the usual control containers, already do it, you had to explicitly use macros such as WX_DECLARE_CONTROL_CONTAINER() and WX_DELEGATE_TO_CONTROL_CONTAINER() if you wanted to write your own composite controls. Luckily few people did this because these macros were not even documented but even just using them in wxWidgets itself causes much teeth gnashing. And particularly so from my part, almost surely because I wrote these macros myself (and only 10 years ago so even the "explanation for using macros here is forever lost in the mists of time" excuse is at most half-valid).

So when I had to add correct keyboard navigation to wxSearchCtrl to fix another bug, I finally decided to atone for my mistake. The solution turned out to be surprisingly simple and nice: instead of all these macros I added a new wxNavigationEnabled class which uses CRTP to inject the TAB-handling logic into the derived class. So, as the example in the documentation shows, you now simply have to inherit your custom composite control from wxNavigationEnabled<wxWindow> instead of directly deriving from wxWindow to get correct keyboard handling, e.g.:
class MyCompositeControl : wxNavigationEnabled {

Using wxNavigationEnabled is definitely much simpler than using macros -- in fact, it's so simple that it could even finally be documented quite painlessly, which is a good criteria -- so I'm quite happy with it (as you can see, even happy enough to write a blog post about this). Even though not having to do anything at all and have TAB-navigation just work would certainly be even better, this can't be done without moving all the TAB navigation logic down into wxWindow itself and there are many, many windows which don't contain any other controls this doesn't look like a good idea.

Anyhow, this battle against macros was won but the war is not over yet. Getting rid of (or at least providing non preprocessor-based alternatives to) all macros in wxWidgets is not the highest priority issue but it's still nice to make some progress on it. And if you have any candidates for irritating macros to be dealt with next, please let us know!

Sunday, July 24, 2011

Less flattering statistics

I've stopped counting the number of opened and fixed Trac bugs quite some time ago because it was too much trouble to do it semi-manually. But one of the side effects of the recrudescence of my love affair with Perl is that I'm looking for excuses to write more Perl code and so I spent half an hour today on writing a small script allowing to gather ticket statistics automatically. This is probably not the best way to do it (it would be better to install some Trac statistics plugin server-side) and the script itself is pretty trivial so it didn't quench my quest for more Perl neither but at least it does quickly give the statistics I wanted.

The bad part is that I didn't want the statistics I got because it in spite of all our efforts the number of opened bugs in wxWidgets keeps increasing. The only good news is that the rate of increase seems to have decreased or at least stabilized: if in 2009 we had 271 new bugs (computed as the difference between 1270 opened and 145 reopened ones and 1144 closed ones), in 2010 we had "only" 275 new bugs and so far in 2011 we have only 20 news ones (and it's not as people got simply tired of reporting them, there were still 521 newly opened bugs since the beginning of the year). But in all, we still have 544 more bugs today than in May 2008 when Trac statistics begin so the journey towards bug-free future remains long...

Out of curiosity I also collected the month statistics using the following intimidating command combining the wonders of zsh short loop syntax and GNU date relative dates support:

% for ((year=2008;$year<=2011;year++)); \
for ((i=1;$i<=12;i++)); \
./trac-ticket-stats --csv $year-$i-01 \
`date --date="1 day ago 1 month $year-$i-01" +%F`

and discovered somewhat surprising variations between the months: on average, we get 60 net new tickets per month but there are some outliers. In Januaries there are almost no new bugs (2) while in October there are 112 of them. Looking at the number of bugs created, more bugs are created in March, October and July (which are very close) while wxWidgets users seem to be on vacation in June when almost twice less bugs are opened. As for us, the developers, we seem to start every new year with good resolutions as January is the month with by far the most bug fixes while by June working on them really loses its appeal and two times fewer of them are resolved.

Friday, July 15, 2011

Self flattering statistics

After receiving the latest monthly Source Forge newsletter with their list of top 25 projects I became curious because at first glance it had seemed like most of them were Web-based applications and I wondered if it really was so. So I spent 10 minutes clicking on all the 25 links and quickly looking at the programming languages/environments/frameworks these projects used and here is what I found (please bear in mind that I could easily make some errors, all this is very quick and rough):

  1. Web/PHP

  2. Java

  3. Java

  4. Java

  5. Perl(?)

  6. Python

  7. C++/wx (and Qt?)

  8. Java

  9. C

  10. C++

  11. Python/wx

  12. Web/PHP

  13. Web/PHP

  14. C++/Qt

  15. Java

  16. C

  17. C

  18. C++/wx

  19. C#

  20. Java

  21. C/SDL

  22. C++/wx

  23. C++/MFC

  24. C++ (?)

  25. C++

As you can see, actually my initial impression was totally wrong and there are only 3 web-based applications (incidentally, all written in PHP) whereas there are twice as many written in Java. What really surprised me, however, was that 4 of them used wxWidgets (although I'm not sure if it's the main UI used by MediaInfo as it also seems to use Qt). I knew about DVDStyler but not the other ones so it was a pleasant surprise.

Of course, I have no idea what are the exact criteria for choosing these 25 "top" projects and there are plenty of Open Source projects not hosted on SourceForge, without even speaking about all the other ones, and so on but, still, it seems like wxWidgets is more popular than I thought (and otherwise I wouldn't have written this post, would I?).

Friday, July 08, 2011

2.9.2 and plans for the future

As you've probably noticed at, the new 2.9.2 release was finally officially released this Tuesday. I won't detail its new features in details here as most important of them were already covered before but just wanted to say a few words about our future plans.

The next release -- incredibly enough -- will be 2.9.3 and we plan to do it at the end of September, after merging the work of GSoC 2011 students in the trunk. So ideally this release will have GTK+ 3 support, a new wxiOS port, wxWebViewCtrl for embedding a "true" HTML rendering engine (such as Trident under MSW or Webkit elsewhere) and a new UI animation library. Being realistic (although I'd certainly like to be proven wrong!), at least some of these things will probably be delayed but the release itself should still happen.

Depending on the things included in or omitted from 2.9.3 we may need to do 2.9.4 with all the big features we want in 3.0 next, although I'd like to avoid it and, again, ideally, 2.9.3 would already have all of them. If 2.9.3 does have everything and if no huge problems are discovered in it, we'd like to release 3.0 before the end of the year (meaning not later than mi-December). But then again, you have to be realistic about these things, so 3.0 will probably happen in the beginning of the next year rather than in this one. Still, planning it for 2011 at least gives us a target to miss.

As usual, let me end any roadmap discussion with a plea for help: we need your help. Most obviously with testing the huge amounts of the new code that will hopefully be in 2.9.3. But also with wxOS port as Stefan is almost alone working on it and with GTK+ 3 stuff as few people know it (yet). Please help us make 3.0 available sooner and, most importantly, better -- thanks in advance!

Saturday, June 18, 2011

Choosing gcc for building wxWidgets under Windows

There are a lot of possibilities for building wxWidgets under Windows using gcc. First of all, you can choose to use traditional makefile in build/msw/makefile.gcc. This binds you to using a MinGW version of the compiler in Windows command prompt (i.e. cmd.exe as hopefully nobody uses systems with any more) as the makefiles use DOS/Windows style paths and commands. Second, you can use the traditional Unix configure-and-make approach. Then you have a subchoice between using MSYS which is a minimalistic environment developed by MinGW project or a full-blown Cygwin one. In the former case you would use MinGW compilers too, of course, and in the latter one the natural idea is to use Cygwin compilers. This however means that the generated programs would depend on Cygwin DLL and would require installing it for them to run. As this can be undesirable, there is also a possibility of using a MinGW cross-compiler from Cygwin environment which combines the advantages of being able to use Cygwin on the build machine while not requiring anything special for the deployment.

Let's summarize the choices in a concise list:
  1. Use makefiles: implies the use of MinGW compiler in DOS prompt.
  2. Use configure+make; then choose between
    1. Using MSYS and MinGW compiler
    2. Using Cygwin and Cygwin compiler
    3. Using Cygwin and MinGW cross-compiler

The choice (1a) is probably the simplest one if you want to install as few things as possible. However, it doesn't allow you to easily specify many compilation options (you need to edit setup.h file instead of just passing options to configure on command line) and, worse, it doesn't produce a wx-config script as part of the build -- and even if it did, there would be no way to use it without some kind of Unix-like shell.

Because of this, I always recommended using the second approach to building wxWidgets. Moreover, personally I've always favoured using Cygwin because I use zsh all day long anyhow. However traditionally you had to use Cygwin compiler which was the worst of the lot. Not only did it always lag a version or two (and sometimes more) behind the latest available MinGW one, but it also was significantly slower than MinGW version. And, of course, the binaries created by it depended on cygwin1.dll. Because of this, people fond of Cygwin (or, alternatively, not fond of many MSYS problems), also tried to use native MinGW compilers under Cygwin and this could be made to work but was so painful because you had to painstakingly ensure that both MinGW compiler and Cygwin tools could understand the paths you used (which basically meant that only relative paths could be really used as absolute paths take different forms for Windows-based MinGW compiler and Cygwin-based tools) that I could never wholeheartedly recommend it.

So I was very pleasantly surprised when I learnt that Cygwin now provides recent versions of MinGW cross-compiler or, rather, several of them. As Charles Wilson explains here, there is a cross-compiler for Win64 from MinGW64 project, another cross-compiler for Win32 from the same project and also a Win32 cross-compiler from "traditional" MinGW. Hence now you have yet another choice to make in case (2c).

Obviously, if you need to target Win64 the choice is easy to make, as there is only one of them. I recommend using MinGW64 version of Win32 cross-compiler as well for two reasons: first, it seems quite likely that you will need to target Win64 later even if you don't need it now, so why not use the same compiler that would allow you to build for Win64 later. And second, MinGW64 uses the so-called SJLJ exceptions which can propagate through the code not compiled with gcc, e.g. all Windows system DLLs. And in practice this is needed to be able to catch any exceptions thrown by your wxWidgets event handlers. So while DW2 exceptions used by MinGW version do have their advantages (in particular they are much more speed-efficient), SJLJ ones are preferable for wxWidgets GUI applications.

To summarize, my recommendation for building wxWidgets under Windows using gcc is now straightforward and unambiguous: use MinGW64 compiler under Cygwin. To be more precise, you need to install Cygwin (if you don't have it yet) and its mingw64-i686-gcc-g++ package (you shouldn't download this file directly though, use Cygwin setup program to install it with all its dependencies). Then you simply need to run wxWidgets configure with the following options:

$ /path/to/wx/configure --host=i686-w64-mingw32 --build=i686-pc-cygwin ...

and run make as usual. You can also use wx-config script and, in general, things are almost as nice as under Unix. Just don't forget to use i686-w64-mingw32-g++ compiler instead of plain g++ if you write it manually instead of using `wx-config --cxx` output.

Another good news is that the speed of the compiler seems to have improved dramatically since the bad old gcc3 days: building the entire wxWidgets takes less than 4 minutes here with make -j8 in default shared library build. Running configure itself is still painfully slow the first time but reasonably fast afterwards if you use -C option to cache the tests results.

Good luck building your applications using wxWidgets using Cygwin cross-compilers and thanks for Cygwin and MinGW(64) folks for making it faster and easier than ever!

Monday, April 18, 2011

Using dynamic auto-completion in text controls

wxTextEntry supports auto-completion of a fixed of strings in wxWidgets 2.9 since quite some time however so far you had to specify the full of set of strings to complete and, incidentally, this didn't work under OS X meaning that one of three major platforms didn't support auto-completion at all.

Lack of support of OS X aside, this is a useful feature which helps the users a lot with the data entry. For example, it is typically used to keep the history of previous entries in a text control and auto-complete the entries used in the past automatically. And for this the existing AutoComplete() worked fine. Sometimes, however, using a fixed set of strings is impractical. A typical example is trying to complete the results of some database queries: there can be a lot of them and it can be wasteful to get all the results from the database. It would be much better to be able to dynamically retrieve just the completions for the prefix already entered by user.

And this is exactly what the newly added wxTextCompleter class and wxTextEntry::AutoComplete() overload taking it allows to do. A text completer object can dynamically generate the completions using the prefix already by the user, either by overriding Start() and GetNext() methods of wxTextCompleter itself or by overriding the single GetCompletions() method of wxTextCompleterSimple class. The widgets sample was updated to show how to do it and the documentation of wxTextCompleterSimple also contains a simple example and hopefully the new API should be clear enough to be used without problems.

As usual, things could be improved further: for one, even though the new dynamic auto-completion is implemented under MSW and OS X, it is not implemented under GTK yet. It shouldn't be difficult to do it by defining a GtkTreeModel forwarding to wxTextCompleter and using it with GtkEntryCompletion but this still remains to be done. Also, under OS X the completion currently needs to be triggered manually by pressing F5 and doesn't appear automatically. This is the native behaviour but it doesn't seem to be particularly useful so we'd need to make it appear automatically. As usual, any contributions implementing either of those improvements would be gratefully received by wxWidgets project so don't hesitate to help if you'd like to use the missing features in your programs.

But even in the current state, you can easily define custom dynamic text completers and also use fixed lists of completion strings under all of the major platforms now.

Wednesday, April 06, 2011

Help with attracting students for GSoC 2011

This year we have surprisingly few proposals from the students willing to work on wxWidgets during this year Google Summer of Code. All the previous times when we participated in the GSoC we had more proposals than the slots allocated to wxWidgets but this year it looks like the reverse might happen for the very first time as two days before the proposal submission deadline we only have two worthy proposals and a couple more of more or less junk ones while, for comparison, the last year we had 7 or 8 interesting proposals and 5-6 or more of lesser quality but still not quite worthless.

And as we always had enough good proposals to take all the slots we were assigned, we never really did much advertisement for it. However this year it looks like it was a bad mistake to not do it so, considering that later is still better than never (even if it's really very late -- again, there are only 2 days left before the deadline), I'd like to ask for the help of the readers of this blog with spreading the word about SGoC in general and wxWidgets participation in it in particular among any students (and maybe also professors) you might know.

Personally I'm convinced that for any student interested in working on a real life yet fun and interesting project during the summer vacation, learning both more about the technical subject and also about how to work in an open source community in general and, moreover, be paid on successful completion of the project, participating in GSoC is really a great opportunity -- so please let know anybody who might be concerned about it.

Thanks in advance!

Tuesday, February 22, 2011

Markup in control labels

As I'm hopelessly out of date with my planned updates anyhow, I've decided to write a brief post about a nice new feature that was recently added to wx instead:

This feature is the possibility to use Pango-like markup in some wxWidgets controls, notably wxButton and wxStaticText. This means that it is now possible to write
wxButton *b = new wxButton(parent, wxID_ANY, "");
b->SetLabelMarkup("<span size='x-large' color='blue'>Big</span> <b>bold</b> button");
and it will indeed behave as expected:
MSW button with markup OS X button with markup GTK+ button with markup

Currently this works for wxButton in all major ports and for the wxGTK and the generic versions of wxStaticText (that can be used under all platforms if this feature is important). The plan is to extend this to more controls later, e.g. wxCheckBox, wxRadioButton or wxStaticBox and maybe even allow using markup for the items of controls with multiple items such as wxListBox or wxComboBox. There is however no definite schedule for this so if anybody is interested in using markup with these controls, please consider helping with implementing it, it should be pretty simple to do by simply copying wxButton behaviour.