/* PKTableViewPresentation.m Preferences controller subclass with preference panes listed in a table bview Copyright (C) 2005 Quentin Mathe Author: Quentin Mathe Date: June 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 #import #import #import #import #import "GNUstep.h" const NSString *PKTablePresentationMode = @"PKTablePresentationMode"; @implementation PKTableViewPresentation /* 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. */ + (void) load { [super inject: self forKey: PKTablePresentationMode]; } /* * Overriden methods */ - (id) init { self = [super init]; /* We build the table here and reuse it */ NSRect rect = NSMakeRect(0, 0, 180, 100); prebuiltTableView = [[NSScrollView alloc] initWithFrame: rect]; [prebuiltTableView setAutoresizingMask: NSViewHeightSizable]; NSTableColumn *column = [[NSTableColumn alloc] initWithIdentifier: @"name"]; [column setWidth: 180]; [column setEditable: NO]; rect = [[prebuiltTableView documentView] bounds]; preferencesTableView = [[NSTableView alloc] initWithFrame: rect]; [preferencesTableView setAutoresizingMask: NSViewHeightSizable]; [preferencesTableView addTableColumn: column]; [prebuiltTableView setDocumentView: preferencesTableView]; DESTROY(column); RELEASE(preferencesTableView); AUTORELEASE(prebuiltTableView); [preferencesTableView setCornerView: nil]; [preferencesTableView setHeaderView: nil]; [preferencesTableView setDataSource: self]; [preferencesTableView setDelegate: self]; return self; } - (void) loadUI { NSView *mainViewContainer = [controller view]; [prebuiltTableView setFrame: NSMakeRect(0, 0, 180, [mainViewContainer frame].size.height)]; [mainViewContainer addSubview: prebuiltTableView]; [preferencesTableView reloadData]; [super loadUI]; } - (void) unloadUI { [prebuiltTableView removeFromSuperview]; } - (NSString *) presentationMode { return (NSString *)PKTablePresentationMode; } /* It is too complicated to call super because each presentation has different architecture. So we need to add paneView ourselves. And over-use -setFrame causes view to flick. */ - (void) layoutPreferencesViewWithPaneView: (NSView *)paneView { if (paneView == nil) return; NSView *mainView = [controller view]; NSRect paneFrame = [paneView frame]; NSRect tableFrame = [prebuiltTableView frame]; NSRect windowFrame = [[mainView window] frame]; NSRect contentFrame = NSZeroRect; int previousHeight = windowFrame.size.height; int heightDelta; /* Resize window so content area is large enough for prefs. */ tableFrame.size.height = paneFrame.size.height; paneFrame.origin.x = tableFrame.size.width; paneFrame.origin.y = 0; contentFrame.size.width = tableFrame.size.width + paneFrame.size.width; contentFrame.size.height = paneFrame.size.height; // FIXME: Implement -frameRectForContentRect: in GNUstep windowFrame.size = [NSWindow frameRectForContentRect: contentFrame styleMask: [[mainView window] styleMask]].size; // NOTE: We have to check carefully the view is not undersized to avoid // limiting switch possibilities in listed panes. if (windowFrame.size.height < 100) windowFrame.size.height = 100; if (windowFrame.size.width < 200) windowFrame.size.width = 200; /* We take in account the fact the origin is located at bottom left corner. */ heightDelta = previousHeight - windowFrame.size.height; windowFrame.origin.y += heightDelta; // FIXME: Animated resizing is buggy on GNUstep (exception thrown about // periodic events already generated for the current thread) #ifndef GNUSTEP [[mainView window] setFrame: windowFrame display: YES animate: YES]; #else [[mainView window] setFrame: windowFrame display: YES animate: NO]; #endif /* Do not resize table view because it is autoresizable. * Resize paneView before adding it into window to reduce flick. * It is also the reason that adding it after window is resized. */ [paneView setFrame: paneFrame]; if ([[paneView superview] isEqual: mainView] == NO) [mainView addSubview: paneView]; } - (void) switchPaneView: (id)sender { int row = [preferencesTableView selectedRow]; NSString *path = [[allLoadedPlugins objectAtIndex: row] identifier]; [controller selectPaneWithIdentifier: path]; } /* * Preferences controller delegate methods */ - (void) didSelectPaneWithIdentifier: (NSString *)identifier { NSDictionary *info = [allLoadedPlugins objectWithValue: identifier forKey: @"identifier"]; int row = [allLoadedPlugins indexOfObject: info]; [preferencesTableView selectRow: row byExtendingSelection: NO]; } /* * Table view delegate methods */ - (int) numberOfRowsInTableView: (NSTableView *)tableView { return [allLoadedPlugins count]; } - (id) tableView: (NSTableView*)tableView objectValueForTableColumn: (NSTableColumn *) tableColumn row: (int)row { NSDictionary *info = [allLoadedPlugins objectAtIndex: row]; return [info objectForKey: @"name"]; } - (void) tableViewSelectionDidChange: (NSNotification *)notification { int row = [preferencesTableView selectedRow]; NSString *path = (NSString *)[[allLoadedPlugins objectAtIndex: row] objectForKey: @"path"]; [controller updateUIForPane: [[controller registry] paneAtPath: path]]; } @end