This is InspectorManager.rtf in view mode; [Download] [Up]
Version 1.0 November 1991 by Kevin Brain. Released to the Public Domain. InspectorManager INHERITS FROM Object CLASS DESCRIPTION The InspectorManager class was designed to manage all of an application's inspector panels, especially for large applications with multiple nib files. Rather than requiring all inspector panels for an application to appear in a single nib file, this class allows inspector panel views created in various nib files to be managed by a single inspectorManager object. This has the advantage that connections between inspector panel controls and other objects can be made in any of the application's nib files, and the panel subsequently given to the inspectorManager object to be managed. This class is designed around the premise that selecting a certain type (or 'group') of inspector with the inspector's popUpList cannot uniquely determine the inspector that needs to be shown . The inspector that gets shown may depend on the currently selected object, if any. (For example, selecting 'Contents' in Workspace Manager may display the 'sound', 'tiff', or another inspector, depending on the currently selected file.) Therefore, the InspectorManager class lets its delegate determine which inspector should be shown when an inspector group is selected via the popUpList. This class uses compositing to and from an offscreen window to swap between inspector views quickly (code and technique to do this was borrowed from the ToolInspector example by Sharon Biocca Zakhour, NeXT Developer Support Team). The inspector panel managed by the InspectorManager class consists of three basic components: a popUpList at the top of the panel, an area where the inspector views are displayed, and a matrix of two buttons labelled "Revert" and "OK". The popUpList is referred to in this documentation as the 'group popUpList', and it selects the group (or 'type') of inspector to be viewed (as it does in Workspace Manager and Interface Builder, for example). Use of the popUpList and the Revert/OK buttons is optional; either can be hidden or displayed (using the methods showGroupPopUp, hideGroupPopUp, showRevertOK, and hideRevertOK). Initially, both are hidden. The group popUpList is automatically shown when a second group is added. The InspectorManager class maintains a list of inspector views, most of which will be given to it from other objects. (Here 'inspector views' does not refer to objects of a particular view class, but any view showing an inspector.) Inspector views are given to the InspectorManger using either the addInspector:title: or the addInspector:title:atLocation:: method. The first parameter to these methods is the view that draws the inspector (for example, a box with several controls as subviews). The second parameter (title) is the string that will be shown in the title bar of the inspector panel whenever the inspector is displayed. Both of these methods return an unsigned int that is subsequently used to indicate the particular inspector view. The showing: method returns the boolean value YES if the given inspector view is currently showing (and NO otherwise). The InspectorManager class also maintains a list of groups for the inspector. Groups are added with the method addGroup:, which takes as a parameter the name of the group as it is to be displayed in the popUpList, and returns an unsigned int that is subsequently used to indicate the group. By default, the addGroup: method assigns sequential numbers (starting at one and incrementing to nine) to the groups to act as command-key equivalents to select the group and display the inspector panel. (This can be disabled by sending setUseKeyEquivalents:NO before any groups are added.) The currently selected group is returned by the group method. The class has a delegate, which it sends messages to when the inspector panel's controls are used. When a group is selected (via the group popUpList), the delegate receives a groupChanged:to: method (if it responds to it). The second parameter of the groupChanged:to method is the number returned by the addGroup: method when this group was added. If the 'Revert' or the 'OK' button is pressed, an inspectRevert: or inspectOK: message, respectively, is sent to the delegate (again, only if the delegate responds to them). The first parameter of all these delegate methods is a pointer to the inspectorManager object. A particular inspector is displayed by sending the InspectorManager object either the switchToInspector: or showInspector: method. The switchToInspector: method will remove all currently displayed inspector views before displaying the given inspector, while showInspector: will just show the given inspector without removing any others. The hideInspector: method removes the single given inspector view from the inspector panel's subview list. The showInspector: and hideInspector: methods permit multiple inspector views to be displayed at once on the inspector panel. In the simplest case, however, all inspector views will be the same size, only one will be displayed at once, and switchToInspector: will be used to display the desired inspector view. Note that the switchToInspector: and hideInspector: methods do not erase the removed inspector views, but instead rely on other views to be drawn over the same area. This requires you to be careful when laying out your inspector views in Interface Builder, but it allows inspectors to be switched as quickly as possible. The InspectorManager class uses a nib file, Inspector.nib, which contains the single inspector panel and three default inspector views. When the InspectorManager initializes, it adds the three default inspector views to its list of inspectors. The three default inspectors, as provided, display the phrases 'No Selection', 'Multiple Selection' and 'Not Applicable', which are selectable by the manifest constants (defined in InspectorManager.h) NOSELECTIONS, MULTIPLESELECTIONS, and NOTAPPLICABLE respectively. Initially there are no groups in the popUpList. (Actually, the group 'None' is in the popUpList in Inspector.nib file because Interface Builder doesn't handle a popUpList without any elements, but 'None' is removed when the first group is added with addGroup:.) USAGE Step-by-step guide to using InspectorManager: 1) Add the class and nib file to your project. 2) Create an instance of Inspector Manager in one of the following ways: a) With Interface Builder: Drag InspectorManager.h over the class window and drop, then instantiate the class. Connect an outlet from your controlling object to the instance. b) Programmatically: use the following line. I find appDidInit: is a good place. inspectorManager = [[InspectorManager alloc] init]; 3) Add groups. For example: attributeGroup = [inspectorManager addGroup:"Attributes"]; miscellaneousGroup = [inspectorManager addGroup:"Miscellaneous"]; 4) Create the necessary inspector views, possibly in various nib files. Ensure the sizes are such that the inspectors showing at any given time together cover old inspector views. In the simplest case, where only one view is displayed in a panel at once, make all views the same size. 5) Send the inspector views to the inspectorManager with messages such as: noteInspectorNum = [inspectorManager addInspector:(id)rectangleInspectorView title:(const char *)"Rectangle Inspector" atLocation:0 :0]; 6) Set inspectorManager's delegate [inspectorManager setDelegate:self]; In is expected that many applications will change the delegate constantly as the currently selected object or window changes. 7) Implement the delegate method groupChanged:to: for all delegates. The easiest case (where each popUpList item brings up a particular inspector panel) could be implemented as follows: - groupChanged:sender to:(int)newGroup; { [inspectorManager switchToInspector:(newGroup - FIRSTADDEDINSPECTOR)] return self; } (Note: FIRSTADDEDINSPECTOR is defined in InspectorManager.h as the number that will be returned by the first addGroup: message sent.) Most implementations of the switchToInspector: method should be a lot more involved. Normally, they will involve switching to various inspector views based the currently selected object and the currently selected inspector group. One way to manage the switching between views in a more complicated case is to have an object for each window that knows (or can determine) what is (are) the currently selected object(s) within the window. If this object is set to be the window's delegate, the 'windowDidBecomeMain:' method will be invoked when the window becomes the main window. Within this method, you can querry the InspectorManager object for the currently selected group, and then send switchToInspector: and/or showInspector: messages to display the appropriate inspector(s). You would also set this object as the InspectorManager's delegate so that it will be notified when the group is changed (via the popUpList). A personal opinion about style: If your application requires an inspector panel to adjust the attributes of each of two types of objects, I think it is better 'inspector form' to have a single group 'Attributes' and to have the appropriate panel for the currently selected object automatically appear, than it is to have two groups labelled 'Object1 Attributes' and 'Object2 Attributes'. VERSION / HISTORY This is Version 1.0 of InspectorManager, distributed November, 1991. AUTHOR / SUPPORT ksbrain@zeus.waterloo.edu University of Waterloo / Department of Systems Design / Waterloo, Ontario/N2L 3G1 Compositing techniques and functions from the ToolInspector example by Sharon Biocca Zakhour, NeXT Developer Support Team. I am very interested in hearing suggestions from people who use this class. Time permitting, I will make further versions available as significant improvements or bug-fixes are made. THIS OBJECT CLASS IS DISTRIBUTED AS IS, WITH NO WARRANTY OR GUARANTEE EXPRESSED OR IMPLIED IN ANY RESPECT. THE AUTHOR IS NOT LIABLE FOR ANY DAMAGES WHATSOEVER DIRECTLY OR INDIRECTLY RELATED TO THE USAGE OF THIS WORK. INSTANCE VARIABLES Declared in InspectorManager id inspectorPanel; id layouts; id inspectorStrings; id noInspectorBox; id multiInspectorBox; id unapplicableInspectorBox; id delegate; id revertOKOut; id popupOut; id inspectorList; id groupList; id visibleInspectors; NXRect lastRect; BOOL useKeyEquivalents; inspectorPanel outlet to inspector Panel layouts outlet to offscreen window that holds default inspectors inspectorStrings outlet, stringTable object for inspector noInspectorBox outlet, view that displays "No Selection" inspector multiInspectorBox outlet, view that displays "Multiple Selections" inspector unapplicableInspectorBox outlet, view that displays "Not Applicable" inspector delegate the inspectorManager's delegate revertOKOut outlet, matrix containing 'Revert' and 'OK' button cells popupOut outlet, button that covers popUpList inspectorList Storage object containing list of inspectors groupList Storage object containing list of groups visibleInspectors List object containing list of visible inspector views lastRect rect in layout window for last inspector view added useKeyEquivalents determines whether or not key equivalents are used inspectorListEntry structure of inspectorList and groupList entries inspectorListEntry.view the view object of this inspector inspectorListEntry.title pointer to inspector title inspectorListEntry.showing YES if showing in the panel inspectorListEntry.offscreenRect rect in layout view for compositing METHOD TYPES Initializing a new instance - init Adding inspectors and groups - (unsigned int)addInspector:(id)theView title:(const char *)theTitle; - (unsigned int)addInspector:(id)theView title:(const char *)theTitle atLocation:(NXCoord)xLoc :(NXCoord)yLoc; - (unsigned int)addGroup:(const char *)theTitle; - setUseKeyEquivalents:(BOOL)use; Displaying/hiding inspectors views - switchToInspector:(unsigned int)newInspector; - showInspector:(unsigned int)newInspector; - hideInspector:(unsigned int)newInspector; Checking inspector visibility - (BOOL)showing:(unsigned int)inspectorNum; Retrieving current group - (int)group; Retrieving inspector objects - panel; - popUpListButton; - revertOKMatrix; Setting/returning delegate - setDelegate:(id)anObject; - delegate; Targets of inspector panel controls - selectGroup:sender; - revertPressed:sender; - okPressed:sender; Showing/Hiding panel controls - showRevertOK; - hideRevertOK; - showGroupPopUp; - hideGroupPopUp; INSTANCE METHODS addGroup: - (unsigned int)addGroup:(const char *)theTitle Adds the group named theTitle to the list of groups maintained by the inspector. The group is also added as an item in the group popUpList. Sequential numbers (starting at one) are assigned to the groups as command-key equivalents to select the group. If this is the first group added, the inspectorManager sends itself a showGroupPopUp message to show the group popUp button (it is hidden until the first group is added). The number returned is subsequently used to compare with numbers returned by the group method to determine the currently selected group. Numbers assigned to groups will start with 0 and increment sequentially, so it is possible to create manifests for the groups in an application and then add the groups in the appropriate order so that the manifests represent the correct number. See also: - group: addInspector: title: - (unsigned int)addInspector:(id)theView title:(const char *)theTitle Invokes addInspector: title:atLocation:: with the x and y location of the view set to the value of the manifests LOWERLEFTX and LOWERLEFTY (defined in InspectorManager.h). This is a point just above the Revert and OK buttons in the provided Inspector.nib file. See also: - switchToInspector:, - showInspector:, - hideInspector: addInspector: title:atLocation:: - (unsigned int)addInspector:(id)theView title:(const char *)theTitle atLocation:(NXCoord)xLoc :(NXCoord)yLoc Adds theView to the InspectorManager's lists. theTitle is the title as it should appear in the inspector panel's title bar when the inspector is displayed. xLoc and yLoc give the location of the origin of the view within the inspector panel. Returns a number which is subsequently used to get the inspectorManager object to display theView as an inspector view. See also: - switchToInspector:, - showInspector:, - hideInspector: delegate - delegate Returns the InspectorManager's delegate, or NULL if it doesn't have one. See also: - setDelegate: group - (int)group Returns the currenly selected group. The number returned is the number that was returned when the group was added with the addGroup:title: method. See also: - addGroup: title: hideInspector: - hideInspector:(unsigned int)inspectorNum Removes inspector number inspectorNum from the subview list of the inspector panel's content view. For efficiency, this method does not explicitly erase the old inspector view, but instead relies on subsequently shown inspectors to draw over top. If inspectorNum is not a valid inspector number the method does nothing. Returns self. See also: - switchToInspector:, - showInspector:, - showing: hideGroupPopUp - hideGroupPopUp Removes the group popUpButton from its superview (the inspector panel's content view). Note that this method does not redisplay the inspector panel's content view, so if you are not going to add an inspector view over the old group popUpButton position, you will have to erase the button's image yourself. Returns self. hideRevertOK - hideRevertOK Removes the matrix containing the Revert and OK button cells from its superview (the inspector panel's content view). Note that this method assumes that a subsequent inspector view will be drawn over the location where the Revert/OK buttons were, so it does not and sends the inspector panel's content view a display message. Returns self. init - init Overrides the default init method. After sending the init to super to do the regular initialization, this method reads in the Inspector.nib file, sets the inspector panel to be a floating panel that becomes the key window only if needed, initializes the InspectorManager's lists, adds the default inspector views, and hides the inspector panel controls. Note that it is possible to create more than one instance of the InspectorManager class. This is allowed because the inspectorManager class would also work well as a preferences panel. Returns self. okPressed: - okPressed:sender An internal method which is the target of the inspector panel's OK button. This method sends the inspectOK message to the delegate if the delegate responds to it. panel - panel Returns the inspector panel. Messages can be sent directly to the panel to move it, resize it, display it, make it non-floating, etc. popUpListButton - popUpListButton Returns the id of the button that acts as the 'cover' for the group popUpList object. You may retrieve the actual popUpList object itself by sending '[[inspectorManagerInstance popUpListButton] target]'. You could use the popUpList object to disable and enable individual items in the popUpList. (However, in keeping with the "user-is-in-control" philosophy, I believe it is better to always allow any group to be selected. Simply display the 'NOTAPPLICABLE' inspector if the selected group does not apply to the currently selected object. ) Do not add or remove objects from the popUpList, or change their names, by sending messages directly to the group popUpList object (always add groups with the addGroup: method). revertPressed: - revertPressed:sender An internal method which is the target of the inspector panel's Revert button. This method sends the inspectRevert message to the delegate if the delegate responds to it. revertOKMatrix - revertOKMatrix Returns the id of the Matrix containing the 'Revert' and 'OK' buttons. You can get at the buttons themselves through this method, if you wish to change their titles or disable/enable them. selectGroup: - selectGroup:sender An internal method which is the target of the inspector panel's group popUpList object. This method sends the groupChanged:to: message to the delegate if the delegate responds to it. setDelegate: - setDelegate:anObject Makes anObject the InspectorManager's delegate, and returns self. See ªMETHODS IMPLEMENTED BY THE DELEGATEº at the end of this class specification. See also: - delegate setUseKeyEquivalents: - setUseKeyEquivalents:(BOOL)use If use == YES, sequential numbers (starting at one and incrementing to nine) are assigned to subsequently groups as command-key equivalents to select the group and display the inspector panel. By default, key equivalents are used. If they are not desired, send a setUseKeyEquivalents:NO message before adding groups. Returns self. showing: - (BOOL)showing:(unsigned int)inspectorNum Returns YES if the inspector is currently displayed in the panel (if it exists in the subview list of the inspector panel's content view) or NO if it does not. showInspector: - showInspector:(unsigned int)newInspector Adds inspector number newInspector to the subview list, without removing any views from the subview list of the inspector panel. Sends a display message to the inspector view. If newInspector is not a valid inspector number, or if its inspector is already visible, the method does nothing. Returns self. See also: - switchToInspector:, - hideInspector:, - showing: showGroupPopUp - showGroupPopUp Adds the group popUp button to the subview list of the inspector panel's content view, and sends the button a display message. Returns self. showRevertOK - showRevertOK Adds the matrix containing the Revert and OK button cells to the subview list of the inspector panel's content view, and sends the matrix a display message. Returns self. switchToInspector: - switchToInspector:(unsigned int)newInspector Removes all views from the subview list of the inspector panel, then adds inspector number newInspector to the subview list. For efficiency, this method does not explicitly erase the removed inspector views, but instead relies on subsequently shown inspectors to draw over top. If newInspector is not a valid inspector number, or if it is already visible, the method does nothing. Returns self. See also: - showInspector:, - hideInspector:, - showing: METHODS IMPLEMENTED BY THE DELEGATE groupChanged:to: - groupChanged:sender to:(int)newGroup Sent to the delegate (if it responds to it) when a new group is selected via the group popUpList. sender is the inspectorManager object and newGroup is the number of the group (the number returned by the addGroup: method when this group was added). inspectRevert: - inspectRevert:sender Sent to the delegate (if it responds to it) when the 'Revert' button is pressed. sender is the inspectorManager object. inspectOK: - inspectOK:sender Sent to the delegate (if it responds to it) when the 'OK' button is pressed. sender is the inspectorManager object.
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.