/** PKPresentationBuilder PKPresentationBuilder.m Abstract Presentation class that returns concrete presentation objects (used by PKPreferencesController as layout delegates). Copyright (C) 2005 Quentin Mathe Uli Kusterer Author: Quentin Mathe Uli Kusterer Date: November 2005 This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #import #ifdef HAVE_UKTEST #import #endif #import #import #import #import #import #import "GNUstep.h" const NSString *PKNoPresentationMode = @"PKNoPresentationMode"; const NSString *PKOtherPresentationMode = @"PKOtherPresentationMode"; static NSMutableDictionary *injectedObjects = nil; /** PKPresentationBuilder Description */ @implementation PKPresentationBuilder + (void) load { injectedObjects = [[NSMutableDictionary alloc] initWithCapacity: 10]; } /**

Dependency injection relying on +load method being sent to superclass before subclasses. It means we can be sure [PKPresentationBuilder] is already loaded by runtime, when each subclass receives this message.

*/ + (BOOL) inject: (id)obj forKey: (id)key { [injectedObjects setObject: obj forKey: key]; return YES; } /**

Factory method that returns the right presentation instance when possible.

It returns nil when no presentation subclass registered against presentationMode could be found.

*/ + (id) builderForPresentationMode: (const NSString *)presentationMode { id presentationUnit = [injectedObjects objectForKey: presentationMode]; // NOTE: [myClass class] == myClass (and [myObject class] == myClass) if ([presentationUnit isEqual: [presentationUnit class]]) { presentationUnit = AUTORELEASE([[presentationUnit alloc] init]); } return presentationUnit; } - (id) init { self = [super init]; return self; } - (void) dealloc { DESTROY(controller); DESTROY(allLoadedPlugins); [super dealloc]; } /* * Preferences UI stuff (mostly abstract methods) */ - (void) setPanesController: (PKPanesController *) c { /* Cache these two objects for subclass */ ASSIGN(controller, c); ASSIGN(allLoadedPlugins, [[controller registry] loadedPlugins]); } /**

Uses this method to do preferences window related UI set up you may have to do and usually done in -awakeFromNib.

*/ - (void) loadUI { [self layoutPreferencesViewWithPaneView: [[controller selectedPane] mainView]]; [self didSelectPaneWithIdentifier: [controller selectedPaneIdentifier]]; } /**

Uses this method to remove preferences window related UI elements, previously set up in -loadUI. Usually called when presentation mode is going to change.

*/ - (void) unloadUI { // [self subclassResponsibility: _cmd]; } - (void) willSelectPaneWithIdentifier: (NSString *) identifier; { // [self subclassResponsibility: _cmd]; } - (void) didSelectPaneWithIdentifier: (NSString *)identifier { // [self subclassResponsibility: _cmd]; } /**

Computes and assigns the right size to preferences view (where paneView parameter is going to displayed), then the right frame to both presentation view and paneView. Finally adds paneView as a subview of preferences view (if it isn't already done).

By default, this method just takes care to add the paneView to preferences view.

Overrides this abstract method to layout subviews of the preferences view container (in a way specific to your presentation), it must take in account the size of preference pane view which is shown or is going to be. If paneView can be directly added to preferences view, just call this method with super. That might not always be true, to take an example, consider your presentation view is a tab view, it means paneView has to be added this time to tab view itself and not preferences view, otherwise it would be overlapped by the former.

*/ - (void) layoutPreferencesViewWithPaneView: (NSView *)paneView { NSView *prefsView = [controller view]; /* We give up here when no paneView is provided and let our subclasses finishing their custom layout. */ if (paneView == nil) return; if ([[paneView superview] isEqual: prefsView] == NO) [prefsView addSubview: paneView]; /* Presentation switches might modify pane view default position, so we reset it. */ [paneView setFrameOrigin: NSZeroPoint]; } /* * Action methods */ /**

Switches the current preference pane viewed to another one provided by sender.

Overrides this abstract method in your subclass in order to implement this behavior by calling [PKPreferencesController -selectPaneWithIdentifier:]; you have to be able to retrieve the preference pane through your custom sender.

*/ - (void) switchPaneView: (id)sender { // [self subclassResponsibility: _cmd]; } /* * Accessors */ /**

Returns the presentation mode which is used to identify the presentation.

By default, this methods returns PKNoPresentationMode.

Overrides this abstract method to return the specific presentation identifier related to your subclass.

*/ - (const NSString *) presentationMode { return (NSString *)PKNoPresentationMode; } @end