Summary of Changes
Changes from version 0.5.0 to 0.5.1
Ported B to the following platforms / environments / libraries / tool sets:
- Mac OS X 10.4 (aka Tiger)
- Xcode 2.1
- CodeWarrior 10.0
- 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:
- B needed to know which Apple Events an application supported, in
order to install AE handlers for them.
- 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.
- 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:
- Add an .sdef file
to the project.
- Copy the .sdef file
into the application bundle.
- 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.
- 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:
- 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:
- cd /usr/local
- sudo rm boost
# remove old symlink
- sudo ln -s boost_1_32_0
boost
- In CodeWarrior, change the global "boost" source tree to point to
the new installation.
- In Xcode, change the global "boost" source tree to point to
the new installation.
- 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
- The "parent" property of the Apple Event class "document window"
has been renamed to "document". Previously, if you had an
Applescript that accessed this property, you would say
"parent of document window foo". Now you say "document of
document window foo".
- AEObject::GetProperty()
and AEObject::SetProperty()
have been replaced by AEObject::ReadProperty()
and AEObject::ReadProperty(),
respectively. The latter take AEReader and AEWriter objects as arguments
instead of an AEDesc.
- The singletons managed by ErrorHandler
and ExceptionStreamer are
now wrapped inside a boost::intrusive_ptr
instead of boost::shared_ptr.
This will affect clients that directly access these singletons.
- Changed the internals of Cursor
to use boost::intrusive_ptr
instead of boost::shared_ptr.
This shouldn't have any impact on clients.
- Ditto for EventHandler
and UndoAction.
- Added AutoMacResourceHandle
to BMemoryUtilities.h.
- Removed BCOM.cpp/.h, which wasn't used and was
marked as "not
ready for prime time".
- EventHandler::Add() now has an overload
that takes a boost::function.
This probably won't affect clients. This means greater
flexibility for clients, because
of boost::function's nice
integration with boost::bind.
- Internally, EventHandler's
functor map now uses boost::intrusive_ptr
instead of boost::shared_ptr.
The former is a lot less resource-hungry than the latter. This
change won't affect clients.
- Don't forget to re-run the install.command
shell script (under b/prog).
This will set up some symlinks under /usr/local to point to the B
installation.
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:
- 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:
- cd /usr/local
- sudo rm boost
# remove old symlink
- sudo ln -s boost_1_31_0
boost
- In CodeWarrior, change the global "boost" source tree to point to
the new installation.
- 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:
- Documents/BDocumentSheets.h
- Documents/BDocumentSheets.tpl.h
- Sheets/BAlertSheets.cpp
- Sheets/BAlertSheets.h
- Sheets/BNavSheet.h
- Sheets/BSheetParentState.cpp
- Sheets/BSheetParentState.h
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:
- The Run() function
is gone. Actually, it's gone from NavDialog
and has now become a template member function in the derived classes
such as AskSaveChangesDialog.
Attempting to call the old Run()
function will almost certainly lead to compilation errors. There
is no one function that does the same thing, but NavDialog::Enter() (the
non-static variant) is good as a first approximation. The
overview article may help you decide the best way to migrate your
code; the Doxygen documentation can also be of help here.
- The Display()
function is also gone. Again, the overview article will be of
help here.
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:
- The files BAlerts.cpp/.h
were renamed to BAlert.cpp/.h,
since there is now one Alert
class instead of many.
- SetError() and SetExplanation() have been
renamed to SetMessageText()
and SetInformativeText(),
respectively. The new names better reflect their purpose, and
match the nomenclature in the Aqua HIG.
- Likewise SetConfirmButton()
and SetInfirmButton()
have been renamed to SetDefaultButton()
and SetCancelButton().
Miscellaneous Changes
- Since SheetParentState is
gone, a new mechanism was required to allow a sheet's parent's state to
be saved when the sheet is displayed and restored when it is
hidden. This is now accomplished by sending custom Carbon Events
to the
parent window. That way, if the parent needs to save/restore
stuff, it can do so itself. Window
includes built-in handlers for these events that save & restore the
state of the close button. This isn't actually required on
Panther but it is on Jaguar.
- When running on Panther or later, SplitView will draw the
splitter image via HIThemeDrawPaneSplitter(),
if no custom image has been specified.
- Changed the global constants in BEventCustomParams.h so they
all begin with "B". This may affect clients, especially if they
have nibs containing command IDs defined in this file. For
example, the PLister sample was affected by this because it has an
"Open Recent" item in its menus.
- Changed the definition of some of B's custom Carbon Events to use
lower-level parameter types (WindowRef
instead of B::Window*, EventTargetRef instead of B::AbstractDocument*).
Clients of B are unlikely to be affected by this change.
- The Dialogs test window in the Tarabiscoter sample has been
revamped to also show off alerts.
- Added a Navigation Services test window to the Tarabiscoter
sample; it demonstrates the use of the various Nav dialogs with all
supported window modalities.
- Added WindowUtils::WindowIterator,
an iterator class similar to ViewUtils::SubviewIterator,
but for iterating over windows instead. The iterator's
constructor takes a WindowClass
and a return-only-visible-windows flag, which helps when iterating over
a subset of the windows.
- Added WindowUtils::begin()
and WindowUtils::end()
which return iterators pointing to the beginning and end of a sequence
of WindowRefs,
respectively.
- Added WindowUtils::IsMetal(),
WindowUtils::GetClass(),
WindowUtils::GetAttributes() and WindowUtils::GetModality().
- Removed Window::GetModality(),
since it's really too low-level for this class. WindowUtils::GetModality() can
be used instead.
- InteractWithUserDialog::Run()
doesn't return a bool
anymore. If a timeout occurs, an InteractionTimeoutException is
thrown instead.
- TaggedTypeTrait<typeQDPoint>
is now
mapped to Point instead
of ::Point (aka Quickdraw
point); likewise TaggedTypeTrait<typeQDRectangle>
is mapped to Rect.
- The throwing variants of the AEReader::ReadXXX() member
functions now return a reference to their output argument as the
function result. This makes it easier to chain function calls.
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:
- 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.
- 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().
- 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).
- A pointer to a Nib.
If non-NULL, it's assumed
that the new view can load auxiliary resources from it.
- 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.
- Class Exception is
gone. B's exception classes now form small trees rooted in std::exception.
- There is now an IOException
class deriving from std::exception
and the file-I/O related exceptions derive from it: EOFException, FileNotFoundException, OpenException, ReadException, WriteException. These are
meant to be more generic and higher-level than throwing OSStatusException.
- OSStatusException is
now an abstract base class. There are two principal derived
classes: RuntimeOSStatusException
which fills the role that OSStatusException
used to have, and ConstantOSStatusException<>,
which is class template containing a constant OSStatus value.
- The classes derived from Exception
that need to mantain an internal string have been refactored to use a
common class, called ExceptionStringHolder.
- A more sophisticated mechanism for determined how to serialise an
exception object has been introduced. It uses a "traits" class
called (unsurprisingly) ExceptionTraits.
- A portion of the functionality that used to be in ErrorHandler has been spun off
to a new class, ExceptionStreamer.
This class takes care of serialising and deserialising exception
objects, and takes full advantage of ExceptionTraits.
- ErrorHandler is now
a real object instead of a collection of static functions. The
functions that display alerts are virtual, so it's possible to change
that behaviour, eg to log the information to a file or system log
instead. Furthermore, ErrorHandler
is now a per-thread singleton. That is, every distinct thread
gets a new instance of ErrorHandler.
It's possible to change the instance of ErrorHandler for the current
thread.
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:
- AEObjectSupport uses
a helper object (ExInfo)
to put exception information into Apple Event replies. This
object is in thread-specific storage and is now managed by boost::thread_specific_ptr<>.
- ErrorHandler is a
per-thread singleton managed by boost::thread_specific_ptr<>.
Its truly global state is initialised via boost::call_once, so even its
initialisation sequence is thread-safe.
- ExceptionStreamer's
singleton object is also initialised via boost::call_once.
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
- Tidied up some code having to do with the interrelationships
between View, CustomView, and HybridView.
- Fixed bugs in the view layout code. Replaced MoveControl()/SizeControl() with HIViewSetFrame() in
non-compositing windows.
- Added specialisations of Event
for kEventWindowUpdate
and kEventWindowDrawContent.
- Added WindowRef
constructors to the specialisations of Event kEventWindowUpdate,kEventWindowDrawContent,
kEventWindowActivated,
kEventWindowDeactivated,
kEventWindowShowing, kEventWindowHiding, kEventWindowShown and kEventWindowHidden.
- Member functions of AEWriter
and AEEvent<XXX, YYY>
that create & send AppleEvents have been modified to take an
additional template parameter: TARGET. This parameter is
an object that specifies which process will receive the event. A
number of predefined target classes have been added: AESelfTarget, AEPsnTarget, AEPidTarget, AEUrlTarget. Developers
using AEObject to send
events won't be affected, since that class uses AESelfTarget behind the scenes.
- String and Mutable string will now throw CharacterEncodingException in
most cases if an encoding error occurs (eg, when asked to return a C
string in an encoding to which the string can't be converted).
Previously, this was mis-diagnosed as an out-of-memory condition.
- Added a second templated CustomView::Create()
function. The new one takes an EventRef instead of a Collection, and instantiates
the view via HIObjectCreate()
instead of CreateCustomControl().
- HybridView now has
templated Create() helper
functions.
- Added DataBrowser::Create().
- Added Window::GetContentView().
- Added a new helper class, ViewUtils::ImageContent,
which allows implementers of custom views to add support for image
content (icons, PICTs, CGImages, etc) without too much fuss. This
new class allows SplitView
to support drawing an image in the middle of the splitter area.
- All unique strings (bundle identifiers, HIObject class IDs, etc.)
have been changed from "enrg.paullallonde.*" to "ca.paullalonde.*".
- Added relational operators for HIViewID and ControlKind to ViewUtils.
- Renamed View::GetControlKind()
and CustomView::GetControlKind() to GetKind(). In both cases
the kind is now returned as the function result instead of an output
argument.
- Added View::GetViewID(),
View::GetID(), View::SetViewID(), View::SetID(), and CustomView::GetViewID() to get
& set a view's HIViewID.
The "ID" variants only
deal with the HIViewID::id
field, where the "ViewID"
variants handle the whole structure.
- Fixed a performance problem where one of the overloads of ToolboxObjectProperty<>::Get()
was using exceptions as a return mechanism. Because this function
is called quite often, it was generating a lot of spurious
throws.
Note that in the unlikely case where a developer was specialising the ToolboxObjectPropertyTypeTrait<>
class template, they will need to add a non-throwing version of the Get() function.
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:
- Determining if a window is composited.
- Retrieving a window's content view.
- Retrieving the bounds of a window's content view.
- Retrieving the global bounds, origin & size of a window's
structure region.
- Retrieving the global bounds, origin & size of a window's
content region.
ViewUtils contains
functions operating on HIViewRef
and covers these areas:
- Coordinate conversions. One can convert between two views,
or between a view and local, window or global coordinates. The
conversions operate on Point,
or on any type that implements operator
+= (B::Point) (that includes Rect and MutableShape).
- Retrieving the content view of a view's owning window.
- Retrieving the bounds of the content view of a view's owning
window.
- Finding a subview of a given view.
- Two iterator classes for iterating over the subviews of a
view. One class iterates forward, the other backward. Both
classes fall into the "forward iterator" category of STL iterators.
- Performs view layout.
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:
- In composited windows on Panther, the layout is performed by the
HIView system.
- On Jaguar and in non-composited windows on Panther, the layout is
performed by B. Only a subset of the layout facility is currently
available, but it's more than adequate for simple needs.
You can specify a view's layout information either through Interface
Builder or programatically. The method you choose depends on a
number of criterion:
- If your application needs to run on Jaguar, specify it
programatically. This is because the Interface Builder runtime
only supports layout
information on Panther. You will be limited to a subset of the
layout facility as noted above.
- If your application needs sophisticated view layout (ie anything
beyond what Interface Builder supports), specify it
programatically. You may be limited to a subset of the
layout facility as noted above, depending on the type of window and OS
version.
- If your application runs only on Panther or later, and it needs
only simple layout support, specify it with Interface
Builder. You can enjoy the
benefits of not having to write any code!
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
- Added Window::GetModality(),
which returns a window's WindowModality.
- Added virtual functions to Window
that allow derived classes to know when a window is being shown or
hidden: HandleShowing(),
HandleHiding(), HandleShown(), HandleHidden().
- Added a new sample application, Tarabiscoter.
- Added support for more Boost exceptions to ErrorHandler's exception
serialisation mechanism.
- Reorganised the precompiled headers in the sample projects.
They now #include a common header, "B.pch++", which contains common
stuff.
- Window's constructor
arguments have been swapped. Now the WindowRef
is first, and the AEObject*
second. This makes the argument sequence
more sensical when one adds extra arguments (such as when calling Window::CreateFromNibWithState).
- Window::CreateFromNib now takes
only one template parameter, the window class. A second function,
Window::CreateFromNibWithState,
has been added which can be used to pass state information to the
window object's constructor.
- Added missing specialisations of Event for Carbon Events of
class kEventClassMouse.
- Added overview article for Carbon Events.
- Revamped the "Using Windows" overview article. It now has
handy links to Doxygen-generated documentation.
- Removed the overloads of EventBase::Send()
for classes Window, View and Menu. They were
superfluous and introduced needless coupling between the Carbon Event
code and those classes.
- Added some member functions to Window, View, Menu, EventTarget, and Toolbar to give clients more
consistent access to their underlying (ie HIToolbox) data structures:
- Each class now has a conversion operator to the underlying OS
data structure (eg WindowRef).
- Each has a member function which also returns the OS data
structure. For example Menu
has a GetMenu() function
returning its MenuRef.
- Each has a GetObjectRef()
function which returns the OS data structure typecast as an HIObjectRef.
- Each has a GetEventTarget()
function which returns the OS data structure's EventTargetRef.
- View now has member
functions for returning iterators over its subviews.
- Added template FindSubview()
member functions to View.
They are similar to the FindView()
functions in Window,
except they can start finding at an arbitrary location in the view tree.
- Added support in SplitView
for orientation and content tags.
- Fixed bugs in HelpButton
and SplitView where we
weren't expecting a null Collection.
- Added operator WindowRef ()
to Window.
- EventBase::Send()
now takes an optional argument that specifies sending options (eg kEventTargetDontPropagate).
The implementation now uses SendEventToEventTargetWithOptions().
- Added a Bundle
member variable to Nib,
and a function to access it. This is handy for Awaken() functions that want to
load resource from the same bundle as the one they themselves were
loaded from.
- Removed the IBNibRef
constructor from Nib.
It was only used by the old Loaded()
implementation.
- Propagation of the Awaken()
(née Loaded()) functions has been
redone. The previous implementation was prone to conflicts
between View and CustomView.
- The "loaded" functions (View::Loaded(),
CustomView::Loaded(), Window::Loaded()) have been
renamed to Awaken(),
which I think is more poetic. Its Nib argument is now
optional, in order to allow the function to be called when a View/CustomView/Window is created
programatically.
- Well, I've finally determined that B's use of C++ is a bit too
advanced for lame old ZeroLink. The option has been turned off in
all of the Xcode projects.
- Changed AEObject::PrintObject
and AEEvent<kCoreEventClass,
kAEPrint> to support the extended print options in Panther.
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
- In order to make the sample projects independent of the exact
location of the B installation, the way that the projects refer to the
B sources has changed. The exact method is depends on whether you
use CodeWarrior or Xcode/PB. For CW you need to define a new
global source tree; for Xcode/PB, you need to create symlinks
under /usr/local.
Refer to the ReadMe for more
information.
- Changed the layout of the html documentation files on disk.
- Documented ViewFactory.
- Doxygen docs.
- Member functions of AEObject
that contained "Model" were renamed to use "Object" instead. For
example, CloneModel()
became CloneObject().
The term "Model" was a holdover from an earlier nomenclature.
- Made it easier to build the CodeWarrior projects on Jaguar.
- Fixed lingering problems in building Project Builder projects on
Jaguar.
- Upgraded the sample projects to Xcode 1.1.
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.
- B_BUILDING_ON_10_3_OR_LATER.
This is non-zero if the current project is being built on
Panther. Note that the default value is 1. If you are not
building on Panther, you should set this to zero in your prefix file.
- B_BUILDING_CAN_USE_10_3_APIS.
This is non-zero if you are allowed to access declarations (including
function declarations) that were introduced in Panther. It's
non-zero if B_BUILDING_ON_10_3_OR_LATER
is non-zero and MAC_OS_X_VERSION_MAX_ALLOWED
is greater than or equal to MAC_OS_X_VERSION_10_3.
Note that even if this macro is non-zero, you may still need to check
for API availability at runtime.
- B_BUILDING_CAN_USE_10_3_APIS_ONLY.
This is non-zero if you are allowed to access declarations (including
function declarations) that were introduced in Panther. It's
non-zero if B_BUILDING_ON_10_3_OR_LATER
is non-zero and MAC_OS_X_VERSION_MIN_REQUIRED
is greater than or equal to MAC_OS_X_VERSION_10_3.
Note that unlike B_BUILDING_CAN_USE_10_3_APIS,
this doesn't require any runtime checks for API availability, because
in effect in sets the app's minimum required system to Panther.
Miscellaneous Changes
- Several changes to the PLister sample:
- The undo support had suffered quite a bit of bitrot over time.
- The tree of ModelItems
is now stored using boost::shared_ptr,
which helps with lifetime management, especially when items are being
deleted.
- Added the "duplicate" event to the terminology resource (aka 'aete').
- Made the Duplicate menu command work more like in the Finder
(the duplicates of all selected items end up in the same container as
their original item, instead of having all of the duplicates end up in
the same container).
- Added supported for the optional "with properties" parameter to
the "duplicate" Apple Event.
- AEObject::CountElements()
now handles the case where the requested element type is cObject. It iterates over
all of the container's declared element types, and counts each in turn.
- Added AEClassInfo::AddElement(),
which allows derivatives of AEObject
to declare their element class IDs.
- References to typeCString
and typePString have been
removed,
since those descriptor types are now deprecated by Apple.
- Changed the "exception-thrown" alert so that displays inException.what().
- Added ErrnoException,
which is an exception class that represents a UNIX errno value. Matching
exception-throwing macros have been added to BErrorHandler.h (ThrowIfErrno(errn), ThrowErrnoIf(c)).
- The throw and assert handlers in ErrorHandler are now kept in
thread-specific storage.
- Added concept checks to the Apple Event and Carbon Event classes.
- Added Window::ClearProxy().
- Added a new view flag to CustomView:
kViewClickActivation.
When it's turned on, the view gets called for the kEventClassControl / kEventControlGetClickActivation
event.
- Added Bundle::FindDocumentTypeForMIMEType()
and Bundle::DoesMIMETypeMatchDocumentType().
- Bundle::DocumentType
now contains the document type's list of MIME types (if any), as well
as flag indicating if the document is a package.
- Added Document::GetIcon().
- Added support in Icon
for icons that don't have an associated file.
- A window belonging to a never-before-saved document doesn't get a
proxy icon any more, as per the Panther HIG.
- Fixed a bug where the About Box was appearing in the Window menu.
- Replaced uses of MAC_OS_X_VERSION_MIN_REQUIRED
and MAC_OS_X_VERSION_MIN_REQUIRED
with B_BUILDING_ON_10_3_OR_LATER,
B_BUILDING_CAN_USE_10_3_APIS
or B_BUILDING_CAN_USE_10_3_APIS_ONLY
as appropriate.
- Ensured the source as well as the sample projects can compile
under Jaguar. Their deployment targets were set to 10.2 as well.
- Added 'CURS'
resources for the up, down, and up-down cursors. These cursors
weren't available via SetThemeCursor()
until Panther, and SplitView
needed them. They are only used when running on Jaguar.
- Fixed a bug in the definition of the ThrowIfNULLRsrc() macro.
Changes from version 0.2.0 to 0.2.1
- Fixed bug in CustomView::ControlDraw
where sometimes the Draw()
function wouldn't be given a GrafPtr
even if it requested one in the view flags.
- The PLister and DragPeeker Xcode projects (still) contained a few
absolute paths, which caused builds to break on every machine except
the author's! It's altogether too easy to mistakenly attribute an
absolute path to a file in Xcode...
- Changed the release-building process to work around a bug in
libtool where linking against a library archive (aka .a file) whose mod
date had been changed would fail.
- Added a Project Builder project for the PLister sample.
- Removed COM constructs from PlugIn.
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... CustomView! CustomView 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:
- NullUndoPolicy, for applications that don't need to
support Undo.
- MultipleUndoPolicy, for applications that need separate
Undo and Redo
stacks of arbitrary size.
- SingleUndoPolicy, for applications that only need a
simple 1-level-deep
Undo.
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
- Added Array<>
and MutableArray<>.
- Region has been
replaced by Shape, MutableShape and AutoRegion.
- Added ViewProperties<>,
MenuItemProperties<>,
MenuCommandProperties<>,
and WindowProperties<>.
These classes allow type-safe access to client-defined properties of
toolbox objects. They share a common templated implementation,
which
is now also shared by CollectionItem<>.
- Added more Doxygen
comments.
- Fixed problems in the Xcode projects
- The localisation aspect of the PLister sample was quite
broken. Some of its .plist files weren't in the correct encoding.
- Changed the Apple Event functor to be true functors, i.e. they
implement operator ().
- Toolbar has been
enhanced quite a bit. It's possible now to initialise it with the
contents of a property list. This makes it very easy to whip up
simple toolbars, without having to subclass anything.
- Added some boost-style concept checking. This work is
ongoing.
- Simplified the EventHandler
classes. EventHandler
is no longer a template class. EventHandlerBase is gone, as
are the EventFunctorMap
classes.
- Changed Application::ShowAboutBox()
so it gets the app description from a pre-defined key in InfoPlist.strings instead of Localizable.strings.
- Renamed CustomObject
to EventTarget, which
better explains what it does.
- Exceptions are now serialised when leaving a Carbon Event
handler, and deserialised after sending a Carbon Event.
- Added more template specialisations of Event<>.
- Fixed bugs in HelpButton
where the focus ring was leaving artifacts behind.
- Changed HelpButton
so that if it's running under Panther and it's been given a
CGContextRef, it will draw using the new HITheme APIs.
- CustomView wasn't
correctly invalidating the view when in a non-composited window.