Libraries, Upgrades and Fixes

Version 0.40 of Woopsi is well underway. There are a number of significant changes coming in this release.

Folder Structure

Woopsi was initially set up to be easy to edit using Visual Studio Express. I used its default folder structure. However, this is at odds with how a library should be organised. So, the Woopsi root directory no longer includes a “woopsi” folder with all sourcecode. It has a “libwoopsi” folder instead, which contains “include”, “src” and “lib” folders containing .h, .cpp and pre-built .a files respectively. It also contains a makefile that will create the library.

For the first time, Woopsi can now easily be used as a proper library. Projects can link against the existing library binary. Installation instructions are included in the archive, but it boils down to this:

  1. Copy the “libwoopsi” folder to the devkitPro directory.
  2. Include $(DEVKITPRO)/libwoopsi/include in your makefile’s include path.
  3. Include $(DEVKITPRO)/libwoopsi/lib in your makefile’s library path.
  4. Link with woopsi.

Version 0.40 includes a template program with the makefile ready-made.

Visual Studio Upgrade

The Woopsi VC++ project has been upgraded to use VC++ 2008 Express. After having performed a number of VS2003 to VS2005 upgrades for ASP.NET web projects, I was expecting the upgrade to be far more onerous than it eventually turned out to be. The upgrade did nothing more than change a couple of version strings in the VS project files.

PALib Support

As mentioned in the last post, PALib support has been dropped. This makes Woopsi slightly tidier and easier to maintain.

Alpha Release

Version 0.40 will be the first alpha version of Woopsi. I have already updated the SourceForge page. From this point on, I am mainly fixing bugs in the existing code.

Testing and Bugfixes

I’ve added three new gadget test projects to the Woopsi distribution - calendar, multiline textbox and standard textbox tests. These have illuminated yet more bugs.

The Calendar gadget’s getPreferredSize() method now returns correct values. Its layout code is now far more intelligent. Previously, the calendar only really looked right when created at certain sizes; at most sizes, the calendar left gaps on the right of the day selection buttons and between those buttons and the labels above them. This has now been addressed, and the calendar’s gadgets use all of the available space. Additionally, its resize() routine is magnitudes faster.

If a day in the calendar was selected and the month changed, if the same day was selected in the new month, the selection wasn’t remembered. For example, selecting “01/01/2009” and then choosing “01/02/2009” (dd/mm/yyyy) would result in the calendar ignoring the second selection.

The last calendar bug is a small one. The day labels are greyed out when the calendar is disabled. This fix has also been applied to the multiline and standard textboxes. The MultiLineTextBox::removeText() method correctly repositions the cursor.

There are a couple of fixes to more fundamental gadgets. The Gadget and ScrollingPanel classes only fire their drag and scrolled events if the stylus actually moves. Previously, just clicking and holding a gadget would cause the drag event to be fired continually.

Finally, the “scrolltest” example now compiles properly.


Chase-san on 2009-10-30 at 07:49 said:

Very very nice. I do not suppose you can just use Woopsi widgets as a way to keep track of UI data and do the rendering yourself (for a custom UI with all the power that woopsi provides). I only ask as all I personally only need scrollbar/scroll list, and buttons with a usable event system, and perhaps a way to make custom widgets. So to replace my yards and yards of custom code.

Ant on 2009-10-30 at 09:59 said:

This is actually possible. You need to subclass the gadgets that you want and override their draw() methods. For example, this would create a button with a green background:

// Use the WoopsiUI namespace
namespace WoopsiUI {

    // Subclass Button
    class MyButton : Button {

        // Override draw method
        void draw(Rect clipRect) {

            // Get a graphics port to draw to
            GraphicsPort* port = newInternalGraphicsPort(clipRect);

            // Draw the green background
            port->drawFilledRect(0, 0, _width, _height, woopsiRGB(0, 31, 0));

            // Draw the button text
            port->drawText(_textX, _textY, _font, _text->getCharArray());

            // Draw the button outline
            port->drawBevelledRect(0, 0, _width, _height);

You may find you need to add a few other overrides (constructor/destructor) in order to get the code to compile, but this is the basic idea:

  • Find the gadgets you want to use
  • Subclass them
  • Copy their draw() methods into the subclass
  • Edit the new draw() methods as you need to.