About The ABox
This is the home of the TopSoft AboutBox ("ABox") project, perhaps the most overfeatured single purpose piece of software you are ever likely to lay your mouse upon...
The ABox (as we like to call it) grew out of TopSoft, Inc.'s FilterTop software project. We wanted to come up with something that no-one had ever really seen or done before, much like our guiding principle for the FilterTop software. I volunteered to undertake the development of the World's Greatest About Box. Eventually, it took on a life of its own, achieved sentience, and is now demanding that I get a PowerMac because it's embarassed to have been born on a hot-rodded Mac II, but that's another story...
The ABox supports nearly all of the way-cool-nifty-gee-i-gotta-have features that Apple has been cranking out for System 7 and beyond. It supports QuickTime, the Text-to-Speech Manager, the Drag-and-Drop Manager, the Asynchronous Sound Manager, the old Threads Package, the new Threads Manager...you get the idea.
The ABox is really a set of C++ classes that have a rather simple interface for the client software. Based mainly upon the API for the Speech Recognition Manager, the ABox has an object-oriented "properties" interface, where instead of providing lots of methods (functions) to do lots of things, there are a handful of methods to do lots of things. Most importantly, all client-adjustable features of the ABox are driven through a pair of methods--GetProperty and SetProperty--that use an OSType selector code to indicate the property to be operated on. Pretty simple.
Most importantly, the ABox can be used to display a set of Topics and Slides. These things are really just a folder-tree of files (topics), where each file contains a 'TSAb' resource that instructs the ABox which resources should be grouped together as Slides within the Topic (much like icon families...a group of resources that share the same ID). By pointing the ABox at the root of some folder tree containing files with 'TSAb' resources, you can make the ABox display a hierarchical list of topics that the user can then browse.
Oh, by the way...adding the ABox to your projects will add about 49K (even less when compiled and built with the latest Metrowerks CodeWarrior compiler!) to your project file. Not too bad for all that gee-whiz feature-itis!
Version history
- 1.9.6 ABox will compile under CW/8 without a fuss. Cool. Fixed an oddball case where someone had a slide that contained a wide PICT and no text or title, and the picture was repositioned and scaled such that it drew over the list scroll bar. Naughty, bad developer, bad!
- 1.9.5 Fixes for the new CW/7 release of CodeWarrior; CW6 let some non-standard uses of the "const" keyword slip thru as legal syntax. Building v1.9 under CW/7 would work, but you would get TONS of warning messages from the compiler. Successfully tested and built on my new 7500/100 (!)
- 1.9 Fixed a problem with the detection of the DragManager on some PowerPC Macs that may have the shared library for the DragMgr installed. The code used is now identical to that used by Apple in their official examples.
- 1.8 Changes for compatibility with CodeWarrior CW6 release and the new Universal Headers. Mainly, the changes involved renaming lots of methods that returned references to object members so the names of the methods now end in "Ref" This had to be done for cases where the name of the method was the same name as a datatype or class; older versions of CW didn't complain about this, but now it does.
- 1.7 Addition of better checks for the Drag Manager since Simon Dufour found a problem running on his PowerBook under System 7.1 French-Canadian (!)
- 1.6 addition of support for the TeachText/SimpleText read-only ('ttro') documents as text files.
- 1.5 addressed ColorQuickDraw issues on 68000 machines such as the SE when using DeviceLoop
- 1.4 addition of BalloonHelp for the test app and the ABox resources, just to do it up right...also fixed a logic problem in performing update events via the event filter which would cause some application's use of the ABox to show an incomplete dialog, where some controls were drawn and some omitted.
- 1.3 fixed a bug in the public release that incorrectly detected the SpeechMgr on PowerMacs (well, on my 8100/80 at work at least), but worked fine on 680x0 macs.
- 1.2 public release; fixed the 3d effects to be intelligent across multiple monitors a-la DeviceLoop; fixed a pair of memory leaks in two of the classes. There _is_ a cosmetic bug wherein the 3d bezel effect will sometimes draw on top of the top line of the vertical scrollbars, but it's only cosmetic and will be fixed shortly.
- 1.1 final dressing for public release; mainly includes the documentation that was really needed, and adjustment of the 3d frame effect
- 1.0.8 internal stuff, never released on time due to loss of full internet access (sigh...)
- 1.0.7 fixed and improved the list update code to better handle list drawing when shoved to the background. Also, added some DragMgr code to improve things.
- 1.0.6 added some sanity checks when dealing with RgnHandles for the Drag Manager to prevent the ABox++ from eventually blowing up. Changed the cursor switching between arrow and watch during setup time. Also added support for the host program to turn support for the Drag Mgr, Speech to Text Mgr, and the Sound Mgr on and off via the kABoxUseDragMgr, kABoxUseSpeechMgr, and KABoxUseSoundMgr properties of the ABox class.
- 1.0.5 reduced the package size (thanks again dan!) due to a bad resource file being included via a QuicKeys macro during packaging. Sigh.
- 1.0.4 reduced redundant updates, finally fixed click-to-foreground movement/updating (thanks dan!)
- 1.0.3 edits for true modeless dialog window proc, better click-to-foreground handling
- 1.0.2 internal modifications; never released
- 1.0.1 first version released
What is, and how does one use, the ABox?
The ABox is a multi-purpose dialog box that can be used to provide a user with a list of topics, where each list contains one or more "slides" on that topic. The ABox is depicted below:
![[About Box]](images/tsabout.gif)
Topics (and their respective slides within the topics) are just loose files within a predetermined folder, possibly organized with with subfolders. This folder (specified by the application programmer) is recursively walked to gather up a topic list, which is simply a list of files that contain TSAb resources (more on this later), and is then displayed in the left area of the dialog box. This way we can create a poor-person's outline just by organizing the topic/slide files into folders and subfolders. Subtopics (and subfolders) are appropriately indented in the topic list. If a folder contains a file of the same name, the file is substituted for the folder name and displayed in the list where the folder would be.
When the user clicks either the "<<prev<<" or ">>next>>" buttons the previous or next slide in the current slide list is displayed. The buttons are appropriately disabled when at the start or end of a slide list. The left/right arrow keys are keyboard shortcuts for the
previous and next buttons.
Additionally, the "play" button (or the spacebar, as a shortcut) will cause the slide's sound or controller-less movie to replay (movies that have a controller already provide their own play button).
The up/down arrow keys will traverse the topic list.
Special Features
- Speech Synthesis: If the user has the Speech Manager installed, clicking on the slide title (if there is one) will cause the system to speak the title out loud, in the system-default voice.
- Drag-And-Drop: If the user has the Drag-And-Drop Manager installed, he/she can drag any
TEXT or PICT object from the ABox to any droppable location, such as another application that can accept the TEXT or PICT, or to the Finder to create clipping-files. This is a really useful way for the user to extract information contained within the ABox.
- QuickTime: Any QuickTime movie file placed within the topic folder tree will show up in the Topic List as its very own topic. Normal Macintosh (resource) format movies and flattened (data-only) format movies are supported. Keep in mind, however, that flattened movies in the topic folder tree will cause the ABox to take a little extra time during the initial set-up phase because it must ask QuickTime to open each file and verify its movie status; resource-format movies are just checked for the
'moov' resource.
- Threads Package/Manager: The ABox is multi-thread-friendly if the host application supports either of these threads subsystems, allowing concurrent paths of execution. Programmers, take note!
- Asynchronous Sound: The ABox attempts to play all sounds asynchronously via the asynchronous portion of the Sound Manager. As a fallback, the ABox will play sounds synchronously, but only if it absolutely must.
Making Topics: Creating Topic/Slide Files
Slide Building Instructions:
Anyone wishing to place something in the ABox need only create a RESOURCE file (via ResEdit, Resorcerer, or some other application of that ilk) with one or more of the following items grouped by resource ID:
'PICT'
'TEXT' (you can also include a 'styl' resource for stylized text)
'STR ' (not STR#)
'snd '
or a QuickTime movie file (flattened or regular)
You can stuff several slides into one topic (file) by grouping them according to ID number. For example, the "TopSoft Inc." topic file has 2 slides in it. The first slide is a world relief map pict, a short text item, and a 'STR ' resource. These all have the same resource ID
(let's call it resID = 3). The next slide in the file consists of a TEXT and 'styl' resource combination (for stylized text; the 'styl' is optional), both of another resource ID (let's call it resID = 4).
Next, once you've got all of the resources you want in the topic file, you need to create a TSAb resource (which stands for TopSoft ABox, if you're curious). The ResEdit file "TopicSlideResource TMPL", which you should have received with this distribution, contains a sample resource and a ResEdit template (TMPL resource) to make the process a little easier. Create a TSAb resource in your topic file, then add the resource-group ID#'s one at a time to the TSAb list. The ABox will only use the first TSAb resource it finds in a file (including the application's own resource fork), so don't bother creating more than one or even worry about what ID you've given the TSAb. The important information is the numbers you've entered inside the TSAb.
Making Topics: An Example
For example, say you've created a file with the slide information described in the paragraphs above. You've got the following information in the file named "TopSoft Inc.":
resource ID#
------------------
PICT 3
TEXT 4
styl 4
So you've got 2 slides for this topic: slide ID#3 and ID#4. Now create a TSAb resource in your file and edit it so you have the following information:
TSAb #128
numItems 2
*****
slide ID number: 3
*****
slide ID number: 4
*****
I can't draw the actual ResEdit screen here, but you get the idea. Close and save the file and you're done!
As a note, I've decided NOT to use compressed PICTs, as it would require QuickTime. And all PICTs should be kept to 8-bit or under to allow for the lowest common denominator in terms of machine performance.
That's all there is to it. Perhaps you should name the file something
meaningful; your name is a good start. Remember: the name of the file
will appear in the Topic List on the left side of the ABox, and if it
is placed inside a folder with the same name, the file's contents will
appear as if they were the folder's contents, providing a means to
display slides for folder-names in the list.
Making Topics: The "you" file feature
Kitsch Alert: Special Personalized End-User Feature!
There is a special feature in naming topic files. The ABox supports a special reserved filename --"you"--that will be renamed in the Topic List at runtime, substituting the name of the user (from the Sharing Setup control panel) in the topic list for "you". This feature allows the programmer to provide a personalized greeting. Here at TopSoft we use it to extend an opportunity to join our programming family. 'Nuff said.
"Folder" Topics
Because the topic list is based upon a file/folder tree on a volume, folders will appear in the list and the user can indeed click on one to select it, like any other topic.
The ABox does, however, have the ability to substitute files for folders of the same name. To utilize this feature a topic resource file with exactly the same name as the enclosing folder must be created and placed with the folder in question. When the ABox is generating the topic list, it will see both the folder and the file, each with the same name, and place the file in the list where the folder would be. When this happens you won't get this silly message, but will instead see whatever slide or slides were created by the designer.
'TEXT' Files
Since not everyone on the planet is ResEdit-savvy, the ABox also has the ability to display TEXT files, so you don't have to use a resource editor to create a TSAb resource, fill in the slide number fields, and then paste your text into a TEXT resource.
Of course, stylized text is much nicer to see and read, and really shows off your design skills, but plain TEXT files are _much_ easier to deal with.
I find that an ABox displaying 9 point Geneva is pretty readable, and a text file of 66 columns can fit into the ABox at this size.
'PICT' Files
The ABox can now support the display of PICT files, such as those created by screen captures or typical graphics applications (be sure to "Save As..." and specify PICT format).
Programming Info
Background
First, however, a little background...
The ABox was originally a large C project, developed under the Symantec C++ v6.0 environment. Later, when more features were added to the ABox, development was switched to the then-newly-released Metrowerks CodeWarrior (gotta love that name!) environment. As the project grew larger, I decided to take the plunge, re-evaluate the work, and move it to C++ (where it now stands). It became easier to maintain, easier to develop, and easier for the application programmer to integrate into his/her work. However, because of its current manifestation, it also requires that the developer use a C++ compiler that uses the Apple Universal Headers. The ABox Project does not actively support the Symantec compiler, but it does not use anything that is CodeWarrior specific either, so the source should work (though don't hold a gun to my head or bet the farm on it either).
Things You Need to Do:
To integrate the ABox into your software project, you'll basically need to do these things:
- Include the ABox source into your project file, either as ordinary source code or as a library.
- Include the ABox resources into your project resource file; a simple copy and past will suffice or include the resource file directly into your project window.
- Create one or more Topic/Slide resource files in a folder tree. You can also store Topic/Slide information (via the
TSAb resource) in your application's resource fork.
- Obviously there is some programming that needs to go on within your application, but it really is minimal.
Modifying Your Source
Incorporating the ABox into your source really couldn't be much easier...
#include "ABox.h"
You will need to #include the file "ABox.h" into your source--do this in the usual fashion. This file provides all of the necessary #defines, enums, prototypes, and class definitions that you will need to use the ABox.
Instantiate an ABox object
When you are ready (well, when your application is ready) to create an ABox instance, you can do it in the normal C++ manner via the new operator.
ABox *myABox = NULL;
//...your code does some stuff
//...your code does more stuff
//...your code wants to create an ABox
myABox = new ABox;
if (!myABox)
return MemError();
//...do what you have to
This is fairly elementary. The ABox constructor will initialize all of the default values for you.
Setting ABox Properties
The ABox class provides a pair of methods to get and set various characteristics or properties of the ABox. These properties allow you, the application programmer, to specify the root of the topic/slide folder tree, if the ABox should be modal, moveable modal, or modeless, if it should behave as a splash screen that waits for a click, shows for a brief time then vanishes, or vanishes under application control (useful for initialization time), etc.
A really crude and only semi-enlightening example snippet is also available; a real world example is contained in the ABox distribution, as well as within the FilterTop distribution.
Making it work
Once you've got the ABox all built and ready to go, you need to tell it to draw itself on the screen...
OSErr ABox::Draw(WindowPtr window);
You can pass nearly anything in the "window" argument; it is currently unused, and a "NULL" which will work very nicely right now.
Now that the ABox is up and on the screen, you've got to allow it to receive events. You do this by using the method below in one of two ways
Boolean ABox::Event(EventRecord *event);
(1) Send it a NULL for the event; this will prime the ABox, and if you have instructed it to operate as a Modal Dialog, it will block until the Modal Dialog version of the ABox is dismissed by the user.
Below is a sample:
gABox = new ABox;
if (gABox)
{
// PrepareABox is from the
// earlier example on setting properties
error = PrepareABox (gABox,
splashTime,
modality,
&homeSpec);
error = gABox->Draw(NULL);
error = gABox->Event(NULL);
}
OR
(2) Incorporate the ABox's Event method into your application's main event loop. This is generally the preferred method, as it allows the ABox to operate in any fashion--even as a splash screen. Below is a sample:
do
{
// Get an event...
WaitNextEvent(everyEvent,
&eRecord,
mySleep,
nil);
// if we have an ABox up and running,
// allow it first shot at the event
if (gABox)
{
Boolean aboxFinished = false;
aboxHandled = gABox->Event(&eRecord);
// is the ABox now finished?
error = gABox->GetProperty (kABoxIsFinished,
&aboxFinished,
NULL);
if (aboxFinished)
{
// yes, the ABox is done and over with
delete gABox;
gABox = NULL;
} else if (aboxHandled) {
// did the ABox handle the event? Should
// we further process it? Yes, if we
// are here...
continue;
} // end if block
} // end if block
// normal event processing here since either
// we don't have an ABox, the ABox is finished,
// or the ABox didn't want the event.
switch (eRecord.what)
{
// blah blah blah...
// general event handling here
} // end switch block
} while (gQuit != true);
That's about it...
...just remember to delete the ABox via the standard C++ delete mechanism
if (gABox)
delete gABox;
This is also shown in the above code fragment as part of the event loop.