Woopsi progress, at last! I’m neglecting my exam revision to bring you more Woopsi changes.
First up, the ListData class (that forms the data container for the ListBox-derived classes) now raises events when its data or selected items are changed. That means the ListBox classes no longer need their own wrappers around functionality that the ListData class provides (adding items, removing items, etc) - the ListData class notifies the ListBox when anything changes, rather than the other way around.
There are a number of classes involved in providing this functionality. A new “EventArgs” template class is the base class for all events within Woopsi. A “ListDataEventArgs” class contains data pertaining to all ListData events. Lastly, a “ListDataEventHandler” class listens for, and handles, all ListData events.
Related to this, I have refactored the existing gadget event system. Note that these are breaking changes and will definitely require you to change your code to match. Gadgets can now have multiple event handlers. Handlers are added with the “Gadget::addGadgetEventHandler()” method, and removed with the “Gadget::removeGadgetEventHandler()” method. Events are raised to all registered event handlers. The “EventHandler” class is now called “GadgetEventHandler”, and the “EventArgs” struct has been replaced with a “GadgetEventArgs” class.
In addition to this, I have replaced the “handleEvent()” method from the old “EventHandler” class with a suite of event handler functions, such as “handleClickEvent()”, handleDragEvent()“, etc. I originally followed this pattern, as described back in September 2007, but swapped to the single method on Jeff’s advice. As Woopsi has grown, though, this approach has led to some fantastically bloated and unintuitive handleEvent() methods. Switching back to the old system makes the code considerably tidier. Note that the new methods return void, not bool, which was always rather redundant.
These changes make the event system more extensible, in that developers can implement their own EventArgs-based classes for their own set of events.
I still need to remove the “EventType” enum from the “GadgetEventArgs” class. I’ll get around to that at some point.
Most of these changes have been inspired by my recent work with Swing. Swing gets a lot of things wrong - such as being horribly slow and featuring the worst layout system I’ve ever tried to use - but it also gets a lot of things right. It’s pleasing to see that an awful lot of the design decisions made for Woopsi are mirrored in the design of Swing (Gadget vs. Component, ListData vs. ListModel, EventHandler vs. Listener, Decoration vs… um… Decoration, etc). Though they have been developed entirely separately, Swing and Woopsi have both managed to re-implement a more-or-less round wheel. In some areas the Swing wheel is slightly rounder than the Woopsi wheel, so I’m just shaving Woopsi down to match.