$Id: README,v 1.5 1994/07/13 06:20:27 davis Exp $
Notes on Developing Custom Inspectors for Pastry
------------------------------------------------
Steps
-----
Developing inspectors for Pastry is simple if you are familiar
with NeXTSTEP programming. Just follow these steps:
o Use Project Builder to create a new bundle. You can name the
bundle whatever you want as long as it doesn't conflict with the
other bundles in the directory you plan to put it in -- something
related to the type of information it will inspect is good.
o If you are using NeXTSTEP 3.2 or newer, press the "Attributes"
button in PB and change the extension of the bundle to "pane". (If
you are using 3.1, you'll need to use some other method to change
the default extension "bundle" to the one Pastry expects, "pane".
You can do this in the Makefiles or by renaming it manually after
you have built it.)
o Create a class that conforms to the InspectorPane protocol. In
choosing a name for your class, try to pick something that is
unlikely to be used by someone else who may write bundles for
Pastry. I've included "InspectorPane.h" which declares the
protocol that your class must implement. It contains 3 methods --
here's a quick description of each one:
+ (const NXAtom *)types
This method should return a NULL-terminated list of all of the
pasteboard types your inspector can inspect. Pastry will send
the message when it loads your class, just before the
InspectorPanel becomes key for the first time, to find out what
it does. Pastry loads panes from directories in this order:
Pastry.app
~/Library/Pastry
/LocalLibrary/Pastry
And it can load panes when the user opens them with the Workspace
Manager.
The first pane that Pastry encounters that can inspect a certain
type will be assigned the task of inspecting that type. If your
pane can inspect both ASCII and RTF, for example, and Pastry
loads some other pane that inspects ASCII before it loads yours,
your pane will not be called upon to inspect ASCII. But your
pane will be called upon to inspect RTF if no previous class
inspects that type.
There is no way for your class to determine which panes in the
same directory will be loaded first. If you want to guarantee
that your pane will be loaded before some other pane, place it in
a directory earlier in Pastry's pane load path. To replace the
default inspectors for text (ASCII and RTF), images (any type
that can be opened by an NXImage), fonts, rulers, and files,
replace the panes in Pastry.app with your panes.
Your class should return only the native types that it can
inspect -- not all of the types that can be converted for
inspection by filter services. Pastry will handle filtering.
- updateFromStream:(NXStream *)stream withType:(NXAtom)type
When it is time for your pane to present a representation of the
pasteboard information to the user, Pastry will send this method
to your class. The stream argument is the information read from
the pasteboard that your class should inspect. (It will already
open for reading.) The type argument is the type of data in the
stream, a type that your class has claimed to inspect. Your
class can read from the stream but shouldn't close or free it.
Pastry will send this message only if the pasteboard information
has changed, so there is no need for your class to check that.
Your class should read the appropriate information from the
stream and change the appearance of its view (see below) to
reflect the information. The panel that the view is in will have
its display and flush disabled before this message is sent -- and
it will displayed and flushed after your class returns from the
message.
- (View *)view
Pastry will ask your class (at any time) for a View. It will
position that view in the Inspector Panel and display it at the
appropriate times. It is this view that your class should modify
when it receives an -updateFromStream:withType: method. If your
class is a View, it could just return self.
Pastry will eventually free your class but not the view so make
sure your class frees everything it allocates.
Your class may also implement one or both of these methods:
- didSwapIn:sender
- didSwapOut:sender
If it does, your class will receive notification immediately after
its view is moved into and out of the Inspector Panel.
o Use Project Builder to add your class, the InspectorPane.h header,
and any other source files to the bundle project. If your bundle
contains more than one class, make sure the one that conforms to
the InspectorPane protocol is the principal class.
o Add any NIB interfaces and other resources required by your class
using PB.
o Compile your bundle, make sure it has a ".pane" extension, and
place it in one of the pane search directories listed above and
restart Pastry.
Suggestions
-----------
Here are some suggestions for implementing the pane.
o If your pane will contain several views or controls, create a NIB
that contains a window. Put your views and controls in this
window. When Pastry asks for your pane's view, return the content
view of the window. You can do this with something like
view = [window setContentView:[[View alloc] init]];
where view is an instance variable of your class. The -view method
should return this variable.
Doing this will allow you to coordinate the various controls in
your pane and it will allow you to set various connections and
autosizing attributes in IB.
It would be nice for your class to load the NIB as late as
possible, at the first request for the view or the first request
for an update, for example. In your -update... method, you could
do this:
if (!window)
[self _loadNib];
and something similar in the -view method.
o Remember that the inspector panel is resizable and your view will
be sized along with it. If you use the content view suggestion
above, be sure to make the other views in the window (i.e. the
subviews of the window's content view) resizable, or anchor them
correctly to an edge of the content view. (Also if you are using
the context view suggestions, select the window in your NIB and set
all sides non-sizable in the size inspector.)
o Pastry attempts to keep the Inspector Panel from becoming the key
window. For this reason, any text fields in your pane should not
be editable or selectable, unless they must be for your pane to
work properly.
o Your class should not try to overstep its bounds -- don't try to
mess with the Inspector Panel or NXApp or any other such weirdness.
Bad things would surely result.
Sample
------
I've included the source for a sound inspector pane. It
doesn't do much, but it illustrates the stuff I've mentioned above.
To try it out, cd to the "sample" directory and type "make" to create
"SoundSample.pane", then copy SoundSample.pane to /LocalLibrary/Pastry
or wherever you want it installed. If you are using NeXTSTEP 3.1, the
final product of the make will be "SoundSample.bundle" -- rename this
to "SoundSample.pane".
Future Compatibility
--------------------
This API is fairly loose and it could very well change in the
future -- I make no claims that it will stay constant. Luckily,
inspectors are fairly easy to write and probably won't require much
change even if I do change the API. You'll probably be better off if
you stick to my suggestions, because that's how I develop panes.
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.