PDP-8-E-Simulator/Panels/PreferencesController.m

229 lines
7.0 KiB
Objective-C

/*
* PDP-8/E Simulator
*
* Copyright © 1994-2015 Bernhard Baehr
*
* PreferencesController.m - Controller for the preferences panel
*
* This file is part of PDP-8/E Simulator.
*
* PDP-8/E Simulator is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#import <Cocoa/Cocoa.h>
#import <PreferencePanes/NSPreferencePane.h>
#import "PreferencesController.h"
#import "NSMutableArray+BinarySearch.h"
#define PREFS_PANEL_TOPLEFT_KEY @"PrefsPanel TopLeft"
@implementation NSBundle (OrderInPreferencesPanelToolbar)
- (NSComparisonResult) compareOrderInPreferencesPanelToolbarInfoPlistKey:(NSBundle *)bundle
{
return [[self objectForInfoDictionaryKey:@"OrderInPreferencesPanelToolbar"]
compare:[bundle objectForInfoDictionaryKey:@"OrderInPreferencesPanelToolbar"]];
}
@end
@implementation PreferencesController
#pragma mark Toolbar
- (void) setupToolbar
{
NSToolbar *toolbar = [[[NSToolbar alloc] initWithIdentifier:@"PrefsPanelToolbar"] autorelease];
[toolbar setAllowsUserCustomization:NO];
[toolbar setAutosavesConfiguration:YES];
[toolbar setDelegate:self];
[prefPanel setToolbar:toolbar];
[prefPanel setShowsToolbarButton:YES];
[toolbar setSelectedItemIdentifier:[prefPaneIdentifiers objectAtIndex:0]];
}
- (NSToolbarItem *) toolbar:(NSToolbar *)toolbar itemForItemIdentifier:(NSString *)identifier
willBeInsertedIntoToolbar:(BOOL)willBeInserted
{
NSToolbarItem *toolbarItem =
[[[NSToolbarItem alloc] initWithItemIdentifier:identifier] autorelease];
NSBundle *bundle = [NSBundle bundleWithIdentifier:identifier];
[toolbarItem setLabel:[bundle objectForInfoDictionaryKey:@"NSPrefPaneIconLabel"]];
[toolbarItem setImage:[[[NSImage alloc] initWithContentsOfFile:[bundle pathForResource:
[bundle objectForInfoDictionaryKey:@"NSPrefPaneIconFile"] ofType:nil]] autorelease]];
[toolbarItem setTarget:self];
[toolbarItem setAction:@selector(selectPreferencePane:)];
return toolbarItem;
}
- (NSArray *) toolbarDefaultItemIdentifiers:(NSToolbar *)toolbar
{
return prefPaneIdentifiers;
}
- (NSArray *) toolbarAllowedItemIdentifiers:(NSToolbar *)toolbar
{
return prefPaneIdentifiers;
}
- (NSArray *) toolbarSelectableItemIdentifiers:(NSToolbar *)toolbar
{
return prefPaneIdentifiers;
}
#pragma mark Initialization
- (void) findPrefPanesAtPath:(NSString *)path addToArray:(NSMutableArray *)array
{
NSString *bundleName;
NSBundle *bundle;
NSDirectoryEnumerator *bundlePathEnum = [[NSFileManager defaultManager] enumeratorAtPath:path];
while ((bundleName = [bundlePathEnum nextObject])) {
if ([[bundleName pathExtension] isEqualToString:PREF_PANE_EXTENSION]) {
[bundlePathEnum skipDescendents];
bundle = [NSBundle bundleWithPath:[path stringByAppendingPathComponent:bundleName]];
if (bundle)
[array addObject:bundle toArraySortedBy:
@selector(compareOrderInPreferencesPanelToolbarInfoPlistKey:)
replaceExistingObject:YES];
}
}
}
- (NSArray *) findPrefPanes
{
NSEnumerator *enumerator;
NSBundle *bundle;
NSMutableArray *prefPaneBundles = [NSMutableArray array];
[self findPrefPanesAtPath:[[NSBundle mainBundle] sharedSupportPath] addToArray:prefPaneBundles];
[self findPrefPanesAtPath:[[NSBundle mainBundle] builtInPlugInsPath] addToArray:prefPaneBundles];
NSMutableArray *prefPaneIdents = [NSMutableArray array];
enumerator = [prefPaneBundles objectEnumerator];
while ((bundle = [enumerator nextObject]))
[prefPaneIdents addObject:[bundle bundleIdentifier]];
return prefPaneIdents;
}
#pragma mark Pane Handling
- (void) resizeWindowForContentView:(NSView *)view
{
NSRect windowFrame =
[NSPanel contentRectForFrameRect:[prefPanel frame] styleMask:[prefPanel styleMask]];
float newWindowHeight = NSHeight([view frame]);
if ([[prefPanel toolbar] isVisible])
newWindowHeight += NSHeight(windowFrame) - NSHeight([[prefPanel contentView] frame]);
NSRect newWindowFrame = [NSPanel frameRectForContentRect:
NSMakeRect(NSMinX(windowFrame), NSMaxY(windowFrame) - newWindowHeight,
NSWidth(windowFrame), newWindowHeight) styleMask:[prefPanel styleMask]];
[prefPanel setFrame:newWindowFrame display:YES animate:[prefPanel isVisible]];
}
- (void) selectPreferencePaneWithIdentifier:(NSString *)identifier
{
if (currentPrefPane) {
if ([currentPrefPane shouldUnselect] != NSUnselectNow) {
NSLog (@"Handle pref pane unwilling to unselect");
return;
}
[currentPrefPane willUnselect];
[[currentPrefPane mainView] removeFromSuperview];
[currentPrefPane didUnselect];
[currentPrefPane release];
currentPrefPane = nil;
}
NSBundle *prefBundle = [NSBundle bundleWithIdentifier:identifier];
currentPrefPane = [[[prefBundle principalClass] alloc] initWithBundle:prefBundle];
if ([currentPrefPane loadMainView]) {
[currentPrefPane willSelect];
[self resizeWindowForContentView:[currentPrefPane mainView]];
[prefPanel setContentView:[currentPrefPane mainView]];
[prefPanel setTitle:[prefBundle objectForInfoDictionaryKey:@"PrefPaneWindowTitle"]];
[currentPrefPane didSelect];
[prefPanel setInitialFirstResponder:[currentPrefPane initialKeyView]];
} else
NSLog (@"Pref pane loadMainView failed");
}
- (IBAction) selectPreferencePane:(id)sender
{
[[prefPanel toolbar] setSelectedItemIdentifier:[sender itemIdentifier]];
[self selectPreferencePaneWithIdentifier:[sender itemIdentifier]];
}
- (void) windowWillClose:(NSNotification *)notification
{
[currentPrefPane willUnselect];
[currentPrefPane didUnselect];
}
- (void) windowDidMove:(NSNotification *)notificatin
{
/* because of the panel resizing, we can't use the auto frame save feature */
NSRect frame = [prefPanel frame];
NSPoint topLeft = frame.origin; // bottom left
topLeft.y += NSHeight(frame); // top left
[[NSUserDefaults standardUserDefaults] setObject:
[NSString stringWithFormat:@"%f %f", topLeft.x, topLeft.y] forKey:PREFS_PANEL_TOPLEFT_KEY];
}
- (void) windowDidBecomeKey:(NSNotification *)notification
{
if (prefPaneIdentifiers == nil) { // initialization
prefPaneIdentifiers = [[self findPrefPanes] retain];
[self setupToolbar];
}
if (currentPrefPane == nil) {
[self selectPreferencePaneWithIdentifier:[prefPaneIdentifiers objectAtIndex:0]];
NSString *str = [[NSUserDefaults standardUserDefaults] objectForKey:PREFS_PANEL_TOPLEFT_KEY];
if (str) { // restore old panel position
NSScanner *scanner = [NSScanner scannerWithString:str];
NSPoint topLeft;
if ([scanner scanFloat:&topLeft.x] && [scanner scanFloat:&topLeft.y])
[prefPanel setFrameTopLeftPoint:topLeft];
else
[prefPanel center];
} else
[prefPanel center];
}
}
@end