Summary of Changes


Changes from version 0.5.0 to 0.5.1

Ported B to the following platforms / environments / libraries / tool sets:

  1. Mac OS X 10.4 (aka Tiger)
  2. Xcode 2.1
  3. CodeWarrior 10.0
  4. Boost 1.33.0

Changes from version 0.4.1 to 0.5.0

Completely revamped Apple Event Object Model initialization logic

Previously, supporting the Apple Event Object Model (AEOM) involved calling a bunch of functions in either AEObjectSupport or AEClassInfo during application startup.  This was necessary because:
  1. B needed to know which Apple Events an application supported, in order to install AE handlers for them.
  2. B needed to know which AE classes an application supported, in order to install AEOM callbacks for them. It also needed to know how the classes were related by inheritance.
  3. B needed to know which classes supported which Apple Events.
This tedious set-up has been almost completely eliminated.  The way it works now is that B reads a .sdef file in the application bundle. An .sdef file is an XML file having a structure defined by Apple which contains a superset of both the old 'AETE' resource and the Cocoa .scriptSuite and .scriptTerminology files. It contains almost all of the information needed by B.

Application projects need to be modified to use the new setup.  You will need to:
  1. Add an .sdef file to the project.
  2. Copy the .sdef file into the application bundle.
  3. Feed the .sdef file to the sdp command-line tool, which in turn generates a .r file containing an 'AETE' resource. This resource needs to be merged into your application's resource file.  This is because various parts of the operating system still expect an 'AETE' resource and can't read an .sdef file directly.
  4. Add an entry in your Info.plist file that points to the .sdef file in the application bundle.
Consult the sample projects, most notably PLister, for the specifics of project setup.

For more information on .sdef files, consult the sdef man page.

Window::CreateFromNib return type change

The return type of Window::CreateFromNib() and Window::CreateFromNibWithState() has changed;  it's now an std::pair.

Clients will need to modify their code.  Consult the overview article for more information.

Now Using Boost 1.32.0

B is now built using version 1.32.0 of the Boost libraries.  Some changes broke the framework, most notably the constructors of some exception classes in the format library had their signatures changed.

If you are reading this, then you most probably already have a version of Boost set up for use with B.  You will need to follow these migration steps:
  1. Change the symbolic link in /usr/local to point to the new installation.  Assuming the new installation is at /usr/local/boost_1_32_0, follow these steps:
    1. cd /usr/local
    2. sudo rm boost    # remove old symlink
    3. sudo ln -s boost_1_32_0 boost
  2. In CodeWarrior, change the global "boost" source tree to point to the new installation.
  3. In Xcode, change the global "boost" source tree to point to the new installation.
  4. Trash all build folders (Xcode "build" folder, CW "Data" folder, etc) and rebuild from scratch.

Now using Xcode 1.5

There's nothing to report here, as there haven't been any problems at all in upgrading.  All of the sample projects have been updated.

MoreIsBetter library changed

In order to support some features of the .sdef files, some small changes were made to the MoreOSL portion of the MoreIsBetter library (on which B relies for its AEOM support).

Miscellaneous Changes

Changes from version 0.4.0 to 0.4.1

Attention Xcode Users

Xcode 1.1 hangs while indexing the Tarabiscoter sample project.  The symptom is that Xcode displays the SPOD while indexing append.hpp, which is part of boost.  This bug may affect other projects as well.

I am investigating the matter.  For the moment the only workaround is to disable indexing in the projects where the problem occurs.

Xcode Configuration Changes

Building the sample Xcode projects now requires setting up some global source trees in Xcode's prefs dialog.  Consult the Read Me which has the installation details in all their glory.

The reason these source trees have been introduced is because the migration to boost 1.31.0 exposed a bug in the way the sample projects were set up.

Enhancements to Undo Classes

Undo, AutoUndo, and the various undo policy classes now have overloaded Add() functions which take a boost::function.  Because of boost::function's nice integration with boost::bind, this means it has now become very convenient to pass pointer-to-member-functions to those Add() overloads.

AutoUndo previously had support for adaptable unary and binary functors (i.e., functors deriving from std::unary_function<> or std::binary_function<>).  That support has now been deprecated.

Finally, there is a new overview article on adding undo support to an application.

Changes from version 0.3.1 to 0.4.0

Now Using Boost 1.31.0

B is now built using version 1.31.0 of the Boost libraries.  The only problem found in making the transition from 1.30.2 was that <boost/compose.hpp> is now deprecated.  I was already migrating away from that library to <boost/bind.hpp>, so it wasn't a big deal.

If you are reading this, then you most probably already have a version of Boost set up for use with B.  You will need to follow these migration steps:
  1. Change the symbolic link in /usr/local to point to the new installation.  Assuming the new installation is at /usr/local/boost_1_31_0, follow these steps:
    1. cd /usr/local
    2. sudo rm boost    # remove old symlink
    3. sudo ln -s boost_1_31_0 boost
  2. In CodeWarrior, change the global "boost" source tree to point to the new installation.
  3. Trash all build folders (Xcode "build" folder, CW "Data" folder, etc) and rebuild from scratch.

Completely Revamped Support for Sheets

The way in which sheets are implemented has been redone completely.  Previously, sheets were supported for Alerts and Navigation Services dialogs via dedicated classes.  For example, you would instantiate one class to get an application-modal alert, and another class to get an alert sheet.  This made the classes harder to use, and more than doubled the number of classes relating to alerts & nav dialogs.  Also, there wasn't any support for developer-created sheets.

All this has changed.  Alert now directly supports both app-modal alerts and alert sheets.  NavDialog and its derivatives also support both app-modal dialogs and sheets.  Finally, Dialog now supports sheets as well as modeless and app-modal dialogs.  Furthermore, all three classes support a unified interface for displaying themselves regardless of whether they are modeless, app-modal, or sheet.  See the "Dialogs, Alerts and Navigation Services" overview article for an explanation of how things work now.

Because sheet functionality has been subsumed in other classes, the following files are now gone:
If you get errors in Xcode or CodeWarrior relating to one of these deleted files, you can safely remove them from your project.  While you are at it, you can also remove any Sheet groups in your projects, since that directory is now gone also.

Changes to Dialog

Dialog has been enhanced to support sheets.  There have been many additions to the class, but by and large existing code should be unaffected by them.  See the "Dialogs, Alerts and Navigation Services" overview article for more information.  Note that the EnterAppModalLoop() function has been deprecated;  see the Dialog class documentation for more information.

Changes to NavDialog and its derivatives

The most important change is that NavDialog now supports sheets directly.  See the "Dialogs, Alerts and Navigation Services" overview article for more information.  Other changes include:

Changes to Alert

The most important change is that Alert now supports sheets directly.  See the "Dialogs, Alerts and Navigation Services" overview article for more information.  Other changes include:

Miscellaneous Changes

Changes from version 0.3.0 to 0.3.1

Changes to View Create() functions.

The Create() functions for the various Toolbox views (ie PlacardView::Create() etc.) have changed. They now end up creating a View object in a manner much closer to when views are loaded from a nib file.  The functions now take identical initial arguments:
  1. The view's ID.  If non-zero, the view is given an HIViewID with the given value and the main bundle's creator as the signature.  If zero is passed in, the view doesn't get a view ID.
  2. The view's superview.  This is more convenient than a WindowRef, because it allows the caller to set up the view hierarchy in fewer steps.  If NULL is passed in, the view is created "standalone".  To place the new view at the top level of a window, pass in the return value of Window::GetContentView() or WindowUtils::GetContentView().
  3. A pointer to the view's frame.  If non-NULL, it specifies the location of the view in its superview's coordinates.  If NULL is passed in, the view doesn't get any specific size or location.  This is actually convenient, especially when you are adding the new view to a superview that automatically places and resizes its child views (eg ScrollView).
  4. A pointer to a Nib.  If non-NULL, it's assumed that the new view can load auxiliary resources from it.
  5. A pointer to a ViewFactory.  If non-NULL, it's used to instantiate the View object;  else, the default view factory is used instead.
The view-awakening logic has been modified a bit to accomodate this change.

Refactoring of Exception and Error Handling Classes

There have been many changes to the exception and error handling classes.  Fortunately, for the most part the changes should have minimal impact on clients.
An overview article covering error handling in B has been added to the main documentation page.

B now uses Boost.Threads

In order to make certain parts of B easier to use in the presence of threads, it now relies on the boost thread library.  For the moment, said support is limited to the following:
All sample projects have been updated to contain the boost thread sources.

Bug uncovered in gdb

If you are using Project Builder or Xcode, you need to be aware of a problem with gdb.  Namely, the debugging information recorded in an executable doesn't properly handle namespaces.  The result is that gdb thinks that classes Window and B::Window are the same, which is really bad.  It can cause gdb to crash.  The workaround is to ensure your class names don't conflict with B's class names.  It rather defeats the purpose of namespaces, but there is not much of an alternative until Apple fixes the problem.  The sample projects have had their classes renamed to it.

Thanks to David Dunham for this important information!

Miscellaneous Changes

Changes from version 0.2.3 to 0.3.0

ObservationCenter Replaced by Boost.Signals

ObservationCenter, B's clone of Cocoa's NSNotificationCenter, has been replaced throughout by boost::signal.   Boost's signal class offers complete and efficient type-safety.  It is trivial to implement the Observer design pattern with it.

For examples of B's own use of boost.signal, take a look at classes MultipleDocumentPolicy, AbstractDocument, and DocumentWindow.  For more information about Boost.Signals, click here.

Dialogs

The new Dialog class allows one to create modal and modeless dialogs.  See the "Windows and Dialogs" overview article for more information.

Drawers

The new Drawer class is a very simple derivative of Window that makes it easy to implement drawers.

Cursors

The new Cursor class is a very simple concrete class that allows one to load a variety of different cursor types (theme, Quickdraw black & white, Quickdraw color, named pixmap).  Of course once loaded you can make a cursor current (ie change the shape of the pointer on the screen).  Note that this class only manages the storage of a cursor's bits; it doesn't provide screen management for cursor-tracking purposes.

New View & Window Utilities

The are two new namespaces called ViewUtils and WindowUtils, contained in similarly named files.  The namespaces contain a number of utility functions that used to be in View or Window, which led to code being inappropriately coupled to those classes.

WindowUtils contains functions operating on WindowRef and covers these areas:
ViewUtils contains functions operating on HIViewRef and covers these areas:
All of the B classes have been changed where appropriate to take advantage of the new utilities.

Revamped View Layout

Previous releases had a Cocoa-style view layout system which was written for Jaguar.  Panther of course introduced the HIViewLayout APIs, and Interface Builder 2.4 incorporates a rudimentary UI to support them.  So the layout support in View has been rewritten to be compatible with the one in Panther.  Here's how it works:
You can specify a view's layout information either through Interface Builder or programatically.  The method you choose depends on a number of criterion:
To use the layout facility programatically, call one of a number of View's member functions:
    HILayoutInfo layout;
B::View* myView;

// This gives you complete control over the layout
myView->SetLayout(layout);
// This is shorthand for binding one side of the view to its parent.
myView->SetRightBinding(kHILayoutBindRight);

Miscellaneous Changes


Changes from version 0.2.2 to 0.2.3

Finding Views Made Easier

Window::FindViewByID() has been renamed to FindView() and is now a template member function with a number of overloads.  The template parameter, VIEW, indicates the function's return type and should be View or a class derived from View.  The advantages to the new approach are (1) it's type-safe and (2) it relieves the programmer from the burden of checking for a NULL return value.  Here are the new functions:

template <class VIEW> VIEW*
FindView(int inID) const;

Returns the view matching the main bundle's signature and inID.

template <class VIEW> VIEW*
FindView(int inID, const std::nothrow_t&) const;

Returns the view matching the main bundle's signature and inID, or NULL.

template <class VIEW> VIEW*
FindView(OSType inSignature, int inID) const;

Returns the view matching inSignature and inID.

template <class VIEW> VIEW*
FindView(OSType inSignature, int inID, const std::nothrow_t&) const;

Returns the view matching inSignature and inID, or NULL.

Calling FindView() is now done by explicitly specifying the type of the view as a template parameter:
StaticTextView* myView;
myView = myWindow->FindView<StaticTextView>(kMyViewID);

Miscellaneous Changes


Changes from version 0.2.1 to 0.2.2

New Build Macros

A number of macros have been introduced which make it easier to track which system APIs may be called.  They simplify conditional compilation tests from the somewhat awkward tests against MAC_OS_X_VERSION_MIN_REQUIRED or MAC_OS_X_VERSION_MAX_ALLOWED as defined by Apple.  For more information on the Apple-defined macros, click here.

Miscellaneous Changes


Changes from version 0.2.0 to 0.2.1


Changes from version 0.1.0 to 0.2.0

Major changes to the custom view classes

First, some classes have been renamed.  CustomView became HybridView and CustomViewBase became... CustomViewCustomView has quite a bit more functionality so deriving from it will hopefully be simpler now.

CustomView now installs many Carbon Event handlers by default, and installs even more depending on flags passed to its constructor.  So for example, passing kViewDragAndDrop to the constructor will turn on drag&drop for the view and install pertinent handlers.

There are a few examples of custom views.  One is HelpButton, which displays a round button with the system help icon in it;  it's an example of a simple button-type view supporting keyboard focus.  Another is SplitView, which show how to make a container view, as well as how to track the mouse and change the cursor via a mouse tracking region.  Finally, the DragPeekerX sample contains a DragPeekerView class that is scrollable and supports drag & drop.

Major changes to the Undo system

The Undo architecture has been substantially reworked. Instead of a class hierarchy rooted in UndoManager, we now have a policy "class" called UNDO_POLICY with three concrete implementations:

UNDO_POLICY also specifies transaction-like semantics.  An "action group" (the UNDO_POLICY's term for transaction) may be opened, after which any number of undoable actions may be added to the policy object.  To close the action group, one either commits the group or aborts it.  Committing records the group's actions for later Undo, whereas aborting discards the actions.  One may have nested open action groups.

The Application and Document classes now have an UNDO_POLICY template parameter.  Undo-related functionality that used to be in AbstractDocument has been moved to Document.

A new class, Undo, allow clients to record undoable actions as well as open action groups without being coupled to a particular implementation of UNDO_POLICY.

A few convenience classes derived from UndoAction have been added:  UnaryUndoAction, BinaryUndoAction, and AEUndoAction.

Miscellaneous changes