Friday, July 26, 2013

Continuous Integration with Travis

Travis is a continuous integration system which works nicely with GitHub, so while we've been using Buildbot since a long time and will continue to do it, we thought it could be nice to also try Travis and so now we have a minimal configuration file for it and it builds wxGTK after each commit.

You can check the latest Travis build status by just looking at this blog post: and you can click the button for more details. For the other ports and also to check if the tests pass (as Travis currently only checks the compilation and doesn't run the tests yet), see our Buildbot status page.

Tuesday, July 09, 2013

Help with pre-2.9.5 testing

We plan to release 2.9.5 next Monday, so any testing right now would be even more welcome than usual -- as 2.9.5 is supposed to be the last release before 3.0, it would be great to avoid having to do any big changes after it is done and for this we need to avoid having the kind of bugs requiring such changes in the release in the first place.

So if you can grab the latest sources from SVN or Git and test them with your application, it would be really helpful. Especially if you discover any news bugs while doing it. And even more so if you don't ;-)

Thanks in advance!


P.S. Currently wxX11 and wxMotif are known to be broken (and will be fixed before 2.9.5) so testing these ports is not worth doing, but all the rest of the ports are supposed to work.

Tuesday, July 02, 2013

The fastest image format to load is...

... surprisingly, at least to me, TIFF. I have recently added a simple benchmark for wxImage methods, mostly to be able to test the optimizations to wxImage::Scale() done by @Hsilgos, but it also looked like a good opportunity to test the speed of loading the same image in different formats. And it turns out that loading the image from TIFF is consistently faster than loading it from JPEG, BMP or PNG even though the JPEG file is much smaller and I'd expect this to play a role. Actually, either the TIFF library under Linux is particularly optimized or the other ones are not optimized at all because using the system libraries for all formats (except BMP which is always loaded using our own code), loading TIFF image is more than twice faster than loading the JPEG one, 8 times faster and 10 times faster than loading the PNG one. Under Windows, where our builds of the libraries, compiled without any particular optimizations, are used, TIFF is relatively twice slower as it's only 10% faster than JPEG, 4 times faster than BMP and 5 times faster than PNG but the differences are still quite big.

The fact that using libpng turns out to be slower (albeit not by a large margin) than our own naive BMP loading code is rather surprising too but perhaps it's due to the code in wxPNGHandler which tries to determine the alpha format in a not very clever way. It would be interesting to profile this further and also test with other images (currently I have a huge sample of 1) and at least determine whether TIFF is consistently faster or just for some images (and, if so, for which ones) and whether this is specific to the code in wxWidgets or if the TIFF protocol or library is just really more efficient.

Wednesday, May 01, 2013

Simpler way to create fonts

Just a quick note about the new and simpler way to create fonts in wxWidgets 2.9: in addition to a multitude of wxFont constructors taking various font attributes, such as size, style, weight, face name and so on, there is now another constructor, taking a single wxFontInfo object that combines all of them together and allows to use the named parameter idiom for the font creation.

It may seem non-obvious how can adding another constructor help with the problem of having too many constructors, so here is a quick example to show how it does: suppose you want to create an underlined, 12 point version of "Courier" font. Here is how you'd do it currently:

wxFont f(12, wxFONTFAMILY_DEFAULT, wxFONTSTYLE_NORMAL, wxFONTWEIGHT_NORMAL, true, "Courier");
And here is how you'd do it with the new constructor:
wxFont f(wxFontInfo(12).Underlined().FaceName("Courier"));

Hopefully the advantages from the point of view of the library user are clear:

  • You don't need to specify the default parameters such as wxFONTFAMILY_DEFAULT, that you don't care about.
  • Each font attribute is clearly written out, while the meaning of true (which meant that the font should be underlined, by the way) was hardly obvious in the first form.
  • You can specify the parameters in any order instead of having to check the documentation every time.
  • Last and really least but still: you can create strike-through fonts (notice that they are only supported under MSW and GTK currently) using the new constructor using the natural Strikethrough() syntax, while this wasn't supported at all with the old constructor.
From our, i.e. developers, point of view, there is one extra important advantage, related to the last point: if support for a new wxFont attribute is added later, this way of creating fonts will be easy to extend to support it.

So my advice is to use wxFontInfo in all the new code using wxWidgets 2.9. The old constructors are not going anywhere and can still be used (except for the one taking int flags which was added for 2.9.4 and now removed to avoid ambiguities with the other existing constructors), but there is no reason to prefer them to the new one.

Sunday, January 20, 2013

About the benefits of procrastination

And no, I'm not going to speak about why postponing 2.9.5 release for so long after its initially scheduled October 2012 release date is a good thing. Instead, I'd like to explain how can the recently added CallAfter() function make your life simpler.

CallAfter() is a method of wxEvtHandler, which means that it's available in the code of any classes deriving from it, including wxWindow but also wxApp and several others. And it basically allows to call another method of the class in which it is used asynchronously later. Notice that no threads are involved, the call to that other method still happens on the same main GUI thread but at a slightly later time. To be precise, the control first must return to the event loop and only then (i.e. "after") the specified method will be called.

Using it is quite simple: if you want to call some method Foo() taking 0, 1 or 2 arguments (this is the current maximum but it could be extended in the future if really needed), you can just write

void SomeWindow::OnSomeEvent(wxEvent& event) { // If the method doesn't take any arguments: CallAfter(&SomeWindow::Foo); // If the method takes an argument: CallAfter(&SomeWindow::Foo, arg1); // Or if it takes two: CallAfter(&SomeWindow::Foo, arg1, arg2); }
Notice that Foo() must be a method of the same class. But other than that, this is pretty straightforward.

The above explains how to use CallAfter() but doesn't answer the really interesting question which is, of course, why would you ever want to do this instead of just calling Foo() directly? The answer is that some things often just can't be done immediately in a GUI program, either because doing them would interfere with its normal flow of control and generate extra events, potentially resulting in unexpectedly re-entering the same event handler and infinite recursion. Or because the current state of the program simply doesn't allow them. An example of the first case is showing a message box from a window activation event handler: doing this would immediately deactivate the window back again which is probably unexpected. An example of the second case is showing a message box from event handlers for all events generated by mouse click, e.g. button press event: as the mouse is captured by the button when the click happens, its mouse grab is released unexpectedly and the standard control itself can get confused by it, e.g. the button could appear to be stuck in pressed state.

The message box example is actually a poor one because wxWidgets already provides an easy way to prevent such problems from happening by using wxLogMessage() function which already postpones showing the message box until the next event loop iteration. What CallAfter() does is to provide you with a generic way to do the same thing very simply.

As a more realistic example, let's consider a common GUI layout with a tree control on the left and some window displaying the items in the tree on the right. Suppose you'd like to update the display when a tree item is double-clicked. There is a wxEVT_COMMAND_TREE_ITEM_ACTIVATED event corresponding to this action so typically you'd do something like this:

TreeViewFrame::TreeViewFrame() { wxTreeCtrl* tree = new wxTreeCtrl(this, ...); tree->Bind(wxEVT_COMMAND_TREE_ITEM_ACTIVATED, &TreeViewFrame::OnActivated, this); // This is the window showing the current item. m_view = new ViewWindow(this); DisplayItem(initial); } void TreeViewFrame::OnActivated(wxTreeEvent& event) { ... retrieve the item to show from the event (typically using client data) ... DisplayItem(item); } void TreeViewFrame::DisplayItem(ItemType item) { m_view->ShowItem(item); // Give the focus to the view to allow the user to easily use the keyboard. m_view->SetFocus(); }
And this works perfectly well except that the view doesn't get the focus after double clicking an item in the tree under Windows. The reason for this is that the native tree control there sends the activation event first and then processes the (second) mouse click which resulted in it itself, and as part of this processing it sets the focus to the control itself (as it's normal for the control to become focused when clicked). So while the view does get focus during the activation event handler execution, it loses it almost immediately afterwards.

In a perfect world, wxWidgets would somehow isolate you from this peculiarity of Windows tree control implementation. But doing this is rather not trivial and, remember, this is just one of several examples. So in the imperfect world we live in, you need to deal with this problem at your application level. CallAfter() reduces the imperfectness of having to do it to acceptably low level as all you need to change in the snippet above to make it work is to replace the last line of the event handler with the call to it:

void TreeViewFrame::OnActivated(wxTreeEvent& event) { ... retrieve the item to show from the event (typically using client data) ... CallAfter(&TreeViewFrame::DisplayItem, item); }
All we did was to delay the item display until the next event loop iteration after the one which dispatched the activated event itself and this is enough to get rid of the focus problem.

So if you have any capture, focus or other global state problems (and notice that they can stem from your own code as well, and not just behaviour of the native controls or wxWidgets itself), you can often use CallAfter() to easily solve them by just postponing whatever you need to do until slightly later. Remember that laziness is a cardinal virtue for a programmer -- and now wxWidgets helps you to cultivate it!


P.S. But we'll still try to release 2.9.5 soon...

Sunday, October 21, 2012

Preparing for 2.9.5

As (unfortunately) not unusual, it looks like 2.9.5 won't be released before the end of October as I planned hoped. But the good news is that we're still relatively close to it, so even though the release is going to be late, at least it won't be late by much. This optimistic assessment is based on the fact that a lot of long-standing important tasks are finally getting closer to the completion:

First, we will finally (after 3 years) soon apply the XRC reorganization patch by Steven Lamerton that will allow us to have XRC handlers for the classes not in the "core" or "adv" libraries, e.g. wxRichTextCtrl, wxRibbonControl or various AUI classes. This was unfortunately impossible so far because of annoying inter-library dependencies issues, but will be fixed by this patch in a classic computer science manner -- that is, by introducing another level of indirection. The changes here are relatively straightforward but there are still quite a few of them, so it would be great to get more testing for them, even before 2.9.5 release, so if you're interested, please get the patch from the Trac or, soon, from the svn or its git mirror and let us know about your experience.

Second, an almost as long-lived branch containing several important changes to wxAUI by Malcolm MacLeod is also planned for a merge. The main user-visible effect of these changes is that it will now be possible to drag notebook pages not only between different wxAuiNotebooks but also form notebooks dynamically by simply piling up pages on top of each other. There are other notebook-related improvements, such as support for horizontal (i.e. on the left or right) tabs by Jens Lody. But here there are also a lot of changes and, to make matters more interesting, they're hardly straightforward so testing this patch would be very welcome as well.

The final relatively big feature planned for 2.9.5 is wxMaskedEdit by Manuel Martin and, again, unsurprisingly, feedback about it would be very welcome.

In addition to the not-yet-quite-merged patches above, several other long-postponed changes have been already done in the svn:

  • Scintilla, used by wxStyledTextCtrl, was upgraded to almost the latest version. This brings a number of new features but also, possibly, some bugs which it would be great to find before the release.
  • Much better support for symbolic links in wxFileName (see DontFollowLink() and the new flags argument of Exists()) and wxFileSystemWatcher (work done by David Hart).
  • New wxSimplebook class.
  • Support for embedding PNG into the program sources, XPM-like.
  • wxPython CallAfter() equivalent for C++.

Please test your programs with the latest svn and, better yet, try using the new features in them and let us know about any regressions or things that could be improved in the new stuff.

Thanks in advance for helping us to make wxWidgets 3.0 better!

Friday, August 31, 2012

Spin news

I've recently needed to add a small new feature to wxSpinCtrl: possibility to display and enter the numbers in hexadecimal format. This is done now with the addition of SetBase() method, so now you can either call SetBase(16) explicitly in the code or use "base" XRC property by adding <base>16</base> to your XRC files (this needs to be done manually as dialog editors don't have support for it yet). Just in case you're curious, here is how the new control looks in the updated widgets sample under OS X:
But as a side effect of working on this, I've also fixed a few other bugs in wxSpinCtrl, hence this progress report:
  • First, I've simply removed wxOSX version of this control. Strangely enough, we had a generic implementation of it for wxOSX which was different from another generic implementation used for all other platforms. They were not identical but pretty similar and at least now we only have one version to maintain.
  • Next I fixed the funny bug with contents of the control being shown as password field if wxALIGN_CENTRE was used. Even though it's more correct to use wxTE_CENtRE, it's more user-friendly to support both versions, especially as the documentation was rather confusing on this subject until recently.
  • I also added the generation of wxEVT_COMMAND_TEXT_ENTER to the generic wxSpinCtrl which didn't send them at all before. This fixed another bug as generic wxSpinCtrl was also used for wxSpinCtrlDouble under wxMSW, and so this event wasn't sent when using real-valued spin controls under Windows, even though it was sent with integer-valued ones.
  • But integer-valued Windows wxSpinCtrl was not without problems neither: the value carried by its events wrapped over when it was greater than SHRT_MAX, i.e. 32767. So I fixed this as well.
There are still some bugs left in wxSpinCtrl, e.g. settings colours doesn't work correctly in the generic version but it's in a much better shape now than only a few days ago.

Tuesday, August 14, 2012

Did you know that Intel VTune used wxWidgets?

Well, I didn't know this but reading the release notes for a new update I've just downloaded I noticed the following at the end of the document:
wxWindows Library
This tool includes wxWindows software which can be downloaded from
http://www.wxwidgets.org/downloads.
wxWindows Library Licence, Version 3.1
======================================
Copyright (C) 1998-2005 Julian Smart, Robert Roebling et al
...
And, indeed, Ctrl-Alt-middle-clicking on VTune window gives:

Sometimes I forget that only a very small proportion of all wxWidgets users reads mailing lists (let alone posts to them), the forums and so on and that there are plenty of companies that use wxWidgets that we have no idea about at all. So it's not really surprising to find that Intel uses wx but it's still nice to have them in our users list!

How to use 2.9.4 wxMSW binaries

We have decided to experiment with providing binaries for wxWidgets releases. So, for the first time ever, 2.9.4 release includes binaries for a few different versions of Microsoft Visual C++ compiler.
However we might not have done a very good job of explaining how to actually use them, the README at the link above is relatively brief and omits some steps, so let me try to explain in more details how to build your wxWidgets applications using the files provided and without building wxWidgets yourself.
First, you need to get the correct files. You will always need the headers one but the rest depends on your compiler version and architecture: as different versions of MSVC compiler are not binary compatible, you should select the files with the correct vc80, vc90 or vc100 suffix depending on whether you use Visual Studio 2005, 2008 or 2010 respectively. You also need to decide whether you use the x64 files for 64-bit development or the ones without this suffix for the still more common 32-bit builds. After determining the combination of suffixes you need, you should download the "Dev" and the "ReleaseDLL" files in addition to the "Headers" one above, e.g. for 32-bit MSVS 2010 development you need wxMSW-2.9.4_vc100_Dev.7z and wxMSW-2.9.4_vc100_ReleaseDLL.7z.

Once you have the files you need, unzip all of them into the same directory, for example c:\wx\2.9.4. You should have only include and lib subdirectories under it, nothing else. To avoid hard-coding this path into your projects, define wxwin environment variable containing it: although it's a little known fact, all versions of MSVC support environment variable expansion in the C++ projects (but not, unfortunately, in the solution files).
Next step is to set up your project to use these files. You need to do the following:
  • In the compiler options, i.e. "C/C++" properties:
    • Add $(wxwin)/include/msvc;$(wxwin)/include to the "Additional Include Directories". Notice that the order is important here, putting the MSVC-specific directory first ensures that you use wx/setup.h automatically linking in wxWidgets libraries.
    • Add WXUSINGDLL and wxMSVC_VERSION_AUTO to the list of defined symbols in "Preprocessor Definitions". The first should be self-explanatory (we only provide DLLs, not static libraries) while the second one is necessary to use the libraries from e.g. lib\vc100_dll directory and not the default lib\vc_dll.
    • Also check that _UNICODE and UNICODE symbols are defined in the same "Preprocessor Definitions" section. This should already be the case for the newly created projects but it might be necessary to add them if you're upgrading an existing one.
      [added at 2013-02-08 in response to comments]
    • Check that you use "Multi-threaded [Debug] DLL" in the "Run-time library" option under "Code Generation" to ensure that your build uses the same CRT version as our binaries.
  • In the linker options you only need to add $(wxwin)\lib\vc100_dll (with the compiler-version-dependent suffix, of course) to "Additional Library Directories" under "Linker\General" in the options. Thanks to the use of MSVC-specific setup.h you don't need to list wxWidgets libraries manually, i.e. you do not need to put anything in the list of "Additional Dependencies".

Now you should be able to build your project successfully, both in "Debug" and "Release" configurations. With MSVC 10 it can also be done from the command line using msbuild.exe. Of course, to run the generated executable you will need to either add the directory containing wxWidgets DLLs to your PATH or copy the DLL files to a directory already on it. Finally, if you want to distribute the binaries created using these options, you will need to install Microsoft Visual C++ run-time DLLs. Again, MSVC 10 has an advantage here as you can simply copy msvcp100.dll and msvcr100.dll as any other DLL, while you need to install specially for the previous compiler versions that use WinSxS ("side-by-side") for them.
Let us know if you run into any problems using these binaries or, on the contrary, if you didn't but were glad to have them. If enough people find them useful, we'll try to provide them again for 2.9.5 and, most importantly, for 3.0.


Updated on 2012-08-23T12:55:10: Corrected linker options instructions.

Friday, July 27, 2012

Nicer Notifications

This is something really not that important in the grand scheme of things but notifications produced by wxNotificationMessage used to look relatively ugly under Unix as they appeared just as a normal window:
And this wasn't especially nicely looking and, even worse, inconsistent with all the other notifications shown by the system.

As I'm currently on vacation and don't feel bound to work on "important" things, I've finally decided to take time to change this. Switching to libnotify to show the notifications as everybody else does was very simple and the end result is much nicer:

or, to show an example of multiple active notifications:

Unfortunately fixing the rest of the problems due to lack of integration with Linux desktop turned out to be less trivial, for example I totally failed in my attempts to get notifications about the system going to sleep and waking up that I'd really like to implement for wxGTK. The only other thing I managed to do during this vacation was a couple of minor wxWebView enhancements but more about this in a future post.

Sunday, July 01, 2012

MSVS 2012 RC Installation Experience

As an update to my previous post about building wxWidgets with VC11 beta, I'd like to say a few words about my experience with installing the RC version of the same compiler -- now known as MSVS 2012.

First of all, the installer doesn't tell you anything about having to uninstall the beta yourself before running it but you really must do it. Otherwise the installation will succeed but the IDE won't open afterwards with an "invalid licence" error (see this known issue, apparently beta has a higher version number than the RC).

Second, and much more annoyingly, the installer also doesn't warn you that it's going to break your existing VC 10 installation. This is also an apparently known problem and can be fixed by installing SP1 for VC 10 but if you're unaware of it it may not be completely obvious that the mysterious LNK1123: failure during conversion to COFF: file invalid or corrupt errors you now get when building any MSVS 2010 C++ projects in debug build are due to VS 2012 installation.

Hopefully knowing this in advance will make testing MSVS 2012 less aggravating to the other wxWidgets users than it was for me. Unfortunately you will still need to reboot your machine a couple of times to install it but then clearly not having to reboot for a compiler installation would have been too much to expect.

Ah, and as for building wxWidgets with VC 11 RC -- nothing to say here, it still works, just as it did with beta and I didn't notice any real changes affecting wxWidgets. The new IDE look is pretty ugly but all the features are there and the profiler is rather nice. Pity it's only included in Premium edition and later.

Wednesday, February 29, 2012

Building wxWidgets with Microsoft Visual C++ 11

This is practically a non-post as building wxWidgets with the recently released Visual Studio 11 Beta turned out to be completely uneventful. After installing the Visual Studio itself -- which was also perfectly straightforward albeit still a typically Microsoft experience as, obviously, installing a compiler should require you to reboot your machine -- I could build the current wxWidgets with the new compiler from command line using nmake /f makefile.vc without any problems. I did fix a harmless warning about an unrecognized Visual C++ version but no other changes were needed.

So far I don't have any experience with the new compiler yet, i.e. there are no obvious differences compared with VC10. It seems to produce slightly larger binaries (~70MiB instead of ~68 for VC10 for wxmsw29u_core.lib) but this is perhaps a consequence of its beta nature. I do look forward to testing the improved support for C++11 in the new version and, if I have some time, I'd like to play with the new WinRT stuff and, in particular, WRL library to see if it's realistic to write Metro applications in C++ without using Microsoft-specific compiler extensions and, if so, whether we can support Metro in wxWidgets.

Sunday, January 15, 2012

Panta rhei

I've just done something that I hadn't done during the entire time I was working on wxWidgets: removed an entire port. And not even just one of them but two at once: wxPalmOS and wxMGL. The latter wasn't used since many years and I don't think the former has been ever really used at all. Moreover, the platforms targeted by these ports don't themselves exist any more. So removing them was a pretty straightforward decision as there were no benefits at all in keeping these ports while maintaining them took small but non zero amount of work.

The decision is less clear cut for them but there are other ports which might be dropped soon too. wxGTK1 will probably disappear when GTK+ 3 support is merged into trunk. The old Cocoa port should be removed too, if only to avoid confusion with the new wxOSX/Cocoa. wxMotif is definitely not very relevant any more so it will probably go as well. I'm not sure if anybody is interested in wxPM (OS/2 port) but it could be a candidate for removal in the near future as well.

The one port which we, or at least I, had high hopes for was the DirectFB-based wxUniversal, a.k.a. wxDFB. Unfortunately it hasn't attracted any interest from the community so it has never developed into a fully-fledged port. This is really a pity as I'd like to see wxWidgets used more on low-powered embedded devices where DirectFB is pretty popular and I still hope that we can find somebody interested in working on it. And while there is hope, we're not going to remove it, even if it's really not very useful in its current state.

With all these ports gone or going, what is remaining? The three major ports are, as always, wxMSW, wxGTK(2) and wxOSX. wxDFB, wxX11 and wxWinCE are not used much but still exist in a more or less reasonable shape. We also hope to have wxGTK3 soon and, more excitingly, the new wxiOS port. Other than that, wxQt port was started but seems to have stalled and, in any case, it was never clear if it made much sense. wxAndroid would be the port I personally would most love to see but it requires a big effort and in spite of having been discussed several times nothing much has happened.

I think writing new ports -- or maintaining and improving the existing ones -- is much simpler now than it used to be because of the clear definitions of the classes API (for the most part anyhow), more clear documentation and the unit tests allowing to automatically check the code correctness. And working on your own port is very rewarding and (at least in my, perhaps atypical, opinion) a lot of fun so if you're looking for a fun open source project for 2012, you could do worse than choose working on wxSomethingOrOther!

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 ./widgets.app


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/datetimectrl.mm. 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 trac.wxwidgets.org 2011-07-04 today
Ticket statistics for http://trac.wxwidgets.org/timeline 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 '*Makefile.in' -x setup.h.in \
-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
instead.

If you add any new files, any new wxUSE_XXX constants or modify configure.in, 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 trac.wxwidgets.org $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.